Browse Source

feat(mt8188): add IOMMU enable control in SiP service

Add SiP service for multimedia & infra master to enable/disable
MM & INFRA IOMMU in secure world

TEST=build pass
BUG=b:236339614

Signed-off-by: Chengci Xu <chengci.xu@mediatek.corp-partner.google.com>
Change-Id: I4eb1fda6044cf2cb6c22c005cb2fa550906b71e9
pull/1988/head
Chengci Xu 2 years ago
committed by Bo-Chen Chen
parent
commit
be457248c6
  1. 99
      plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c
  2. 24
      plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h
  3. 44
      plat/mediatek/drivers/iommu/mtk_iommu_priv.h
  4. 125
      plat/mediatek/drivers/iommu/mtk_iommu_smc.c
  5. 17
      plat/mediatek/drivers/iommu/rules.mk
  6. 37
      plat/mediatek/include/mt8188/platform_def.h
  7. 1
      plat/mediatek/include/mtk_sip_def.h
  8. 1
      plat/mediatek/mt8188/platform.mk

99
plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c

@ -0,0 +1,99 @@
/*
* Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mtk_iommu_plat.h>
#include <mtk_mmap_pool.h>
#include <platform_def.h>
/* mm iommu */
#define SMI_L0_ID (0)
#define SMI_L1_ID (1)
#define SMI_L2_ID (2)
#define SMI_L3_ID (3)
#define SMI_L4_ID (4)
#define SMI_L5_ID (5)
#define SMI_L6_ID (6)
#define SMI_L7_ID (7)
#define SMI_L9_ID (8)
#define SMI_L10_ID (9)
#define SMI_L11A_ID (10)
#define SMI_L11B_ID (11)
#define SMI_L11C_ID (12)
#define SMI_L12_ID (13)
#define SMI_L13_ID (14)
#define SMI_L14_ID (15)
#define SMI_L15_ID (16)
#define SMI_L16A_ID (17)
#define SMI_L16B_ID (18)
#define SMI_L17A_ID (19)
#define SMI_L17B_ID (20)
#define SMI_L19_ID (21)
#define SMI_L21_ID (22)
#define SMI_L23_ID (23)
#define SMI_L27_ID (24)
#define SMI_L28_ID (25)
/* infra iommu */
#define PERI_MST_PROT (0x710)
#define PERICFG_AO_IOMMU_1 (0x714)
#define MMU_DEV_PCIE_0 (0)
#define IFR_CFG_GROUP_NUM (1)
static struct mtk_smi_larb_config mt8188_larb_cfg[SMI_LARB_NUM] = {
[SMI_L0_ID] = LARB_CFG_ENTRY(SMI_LARB_0_BASE, 7, 0),
[SMI_L1_ID] = LARB_CFG_ENTRY(SMI_LARB_1_BASE, 7, 0),
[SMI_L2_ID] = LARB_CFG_ENTRY(SMI_LARB_2_BASE, 5, 0),
[SMI_L3_ID] = LARB_CFG_ENTRY(SMI_LARB_3_BASE, 7, 0),
[SMI_L4_ID] = LARB_CFG_ENTRY(SMI_LARB_4_BASE, 7, 0),
[SMI_L5_ID] = LARB_CFG_ENTRY(SMI_LARB_5_BASE, 8, 0),
[SMI_L6_ID] = LARB_CFG_ENTRY(SMI_LARB_6_BASE, 4, 0),
[SMI_L7_ID] = LARB_CFG_ENTRY(SMI_LARB_7_BASE, 3, 0),
[SMI_L9_ID] = LARB_CFG_ENTRY(SMI_LARB_9_BASE, 25, 0),
[SMI_L10_ID] = LARB_CFG_ENTRY(SMI_LARB_10_BASE, 20, 0),
[SMI_L11A_ID] = LARB_CFG_ENTRY(SMI_LARB_11A_BASE, 30, 0),
[SMI_L11B_ID] = LARB_CFG_ENTRY(SMI_LARB_11B_BASE, 30, 0),
[SMI_L11C_ID] = LARB_CFG_ENTRY(SMI_LARB_11C_BASE, 30, 0),
[SMI_L12_ID] = LARB_CFG_ENTRY(SMI_LARB_12_BASE, 16, 0),
[SMI_L13_ID] = LARB_CFG_ENTRY(SMI_LARB_13_BASE, 24, 0),
[SMI_L14_ID] = LARB_CFG_ENTRY(SMI_LARB_14_BASE, 23, 0),
[SMI_L15_ID] = LARB_CFG_ENTRY(SMI_LARB_15_BASE, 19, 0),
[SMI_L16A_ID] = LARB_CFG_ENTRY(SMI_LARB_16A_BASE, 17, 0),
[SMI_L16B_ID] = LARB_CFG_ENTRY(SMI_LARB_16B_BASE, 17, 0),
[SMI_L17A_ID] = LARB_CFG_ENTRY(SMI_LARB_17A_BASE, 7, 0),
[SMI_L17B_ID] = LARB_CFG_ENTRY(SMI_LARB_17B_BASE, 7, 0),
/* venc nbm ports (5/6/11/15/16/17) to sram */
[SMI_L19_ID] = LARB_CFG_ENTRY_WITH_PATH(SMI_LARB_19_BASE, 27, 0, 0x38860),
[SMI_L21_ID] = LARB_CFG_ENTRY(SMI_LARB_21_BASE, 11, 0),
[SMI_L23_ID] = LARB_CFG_ENTRY(SMI_LARB_23_BASE, 9, 0),
[SMI_L27_ID] = LARB_CFG_ENTRY(SMI_LARB_27_BASE, 4, 0),
[SMI_L28_ID] = LARB_CFG_ENTRY(SMI_LARB_28_BASE, 0, 0),
};
static bool is_protected;
static uint32_t mt8188_ifr_mst_cfg_base[IFR_CFG_GROUP_NUM] = {
PERICFG_AO_BASE,
};
static uint32_t mt8188_ifr_mst_cfg_offs[IFR_CFG_GROUP_NUM] = {
PERICFG_AO_IOMMU_1,
};
static struct mtk_ifr_mst_config mt8188_ifr_mst_cfg[MMU_DEV_NUM] = {
[MMU_DEV_PCIE_0] = IFR_MST_CFG_ENTRY(0, 18),
};
struct mtk_smi_larb_config *g_larb_cfg = &mt8188_larb_cfg[0];
struct mtk_ifr_mst_config *g_ifr_mst_cfg = &mt8188_ifr_mst_cfg[0];
uint32_t *g_ifr_mst_cfg_base = &mt8188_ifr_mst_cfg_base[0];
uint32_t *g_ifr_mst_cfg_offs = &mt8188_ifr_mst_cfg_offs[0];
/* Protect infra iommu enable setting registers as secure access. */
void mtk_infra_iommu_enable_protect(void)
{
if (!is_protected) {
mmio_write_32(PERICFG_AO_BASE + PERI_MST_PROT, 0xffffffff);
is_protected = true;
}
}

24
plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h

@ -0,0 +1,24 @@
/*
* Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IOMMU_PLAT_H
#define IOMMU_PLAT_H
#include <mtk_iommu_priv.h>
/* mm iommu */
#define SMI_LARB_NUM (26)
extern struct mtk_smi_larb_config *g_larb_cfg;
/* infra iommu */
#define MMU_DEV_NUM (1)
extern struct mtk_ifr_mst_config *g_ifr_mst_cfg;
extern uint32_t *g_ifr_mst_cfg_base;
extern uint32_t *g_ifr_mst_cfg_offs;
extern void mtk_infra_iommu_enable_protect(void);
#endif /* IOMMU_PLAT_H */

44
plat/mediatek/drivers/iommu/mtk_iommu_priv.h

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IOMMU_PRIV_H
#define IOMMU_PRIV_H
#include <common/debug.h>
#include <lib/mmio.h>
#include <mtk_sip_svc.h>
#define LARB_CFG_ENTRY(bs, p_nr, dom) \
{ .base = (bs), .port_nr = (p_nr), \
.dom_id = (dom), .to_sram = 0, }
#define LARB_CFG_ENTRY_WITH_PATH(bs, p_nr, dom, sram) \
{ .base = (bs), .port_nr = (p_nr), \
.dom_id = (dom), .to_sram = (sram), }
#define IFR_MST_CFG_ENTRY(idx, bit) \
{ .cfg_addr_idx = (idx), .r_mmu_en_bit = (bit), }
enum IOMMU_ATF_CMD {
IOMMU_ATF_CMD_CONFIG_SMI_LARB, /* For mm master to enable iommu */
IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU, /* For infra master to enable iommu */
IOMMU_ATF_CMD_COUNT,
};
struct mtk_smi_larb_config {
uint32_t base;
uint32_t port_nr;
uint32_t dom_id;
uint32_t to_sram;
uint32_t sec_en_msk;
};
struct mtk_ifr_mst_config {
uint8_t cfg_addr_idx;
uint8_t r_mmu_en_bit;
};
#endif /* IOMMU_PRIV_H */

125
plat/mediatek/drivers/iommu/mtk_iommu_smc.c

@ -0,0 +1,125 @@
/*
* Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stddef.h>
#include <mtk_iommu_plat.h>
/* defination */
/* smi larb */
#define SMI_LARB_NON_SEC_CON(port) (0x380 + ((port) << 2))
#define PATH_SEL_MASK (0xf0000) /* to sram (INT) */
#define SMI_LARB_SEC_CON_INT(port) (0xf00 + ((port) << 2))
#define SMI_LARB_SEC_CON(port) (0xf80 + ((port) << 2))
#define MMU_MASK BIT(0)
#define MMU_EN(en) ((!!(en)) << 0)
#define SEC_MASK BIT(1)
#define SEC_EN(en) ((!!(en)) << 1)
#define DOMAIN_MASK (0x1f << 4)
#define SMI_MMU_EN(port) (0x1 << (port))
/* infra master */
#define IFR_CFG_MMU_EN_MSK(r_bit) (0x3 << (r_bit))
/* smi larb configure */
/*
* If multimedia security config is enabled, the SMI config register must be
* configurated in security world.
* And the SRAM path is also configurated here to enhance security.
*/
static void mtk_smi_larb_port_config_to_sram(
const struct mtk_smi_larb_config *larb,
uint32_t port_id)
{
mmio_clrbits_32(larb->base + SMI_LARB_SEC_CON_INT(port_id),
MMU_MASK | SEC_MASK | DOMAIN_MASK);
mmio_setbits_32(larb->base + SMI_LARB_NON_SEC_CON(port_id),
PATH_SEL_MASK);
}
static void mtk_smi_port_config(const struct mtk_smi_larb_config *larb,
uint32_t port_id, uint8_t mmu_en, uint8_t sec_en)
{
mmio_clrsetbits_32(larb->base + SMI_LARB_SEC_CON(port_id),
MMU_MASK | SEC_MASK | DOMAIN_MASK,
MMU_EN(mmu_en) | SEC_EN(sec_en));
}
static int mtk_smi_larb_port_config_sec(uint32_t larb_id, uint32_t mmu_en_msk)
{
uint32_t port_id, port_nr;
const struct mtk_smi_larb_config *larb;
uint32_t to_sram;
uint8_t mmu_en;
if (larb_id >= SMI_LARB_NUM) {
return MTK_SIP_E_INVALID_PARAM;
}
larb = &g_larb_cfg[larb_id];
port_nr = larb->port_nr;
to_sram = larb->to_sram;
for (port_id = 0; port_id < port_nr; port_id++) {
if ((to_sram & BIT(port_id)) > 0U) {
mtk_smi_larb_port_config_to_sram(larb, port_id);
continue;
}
mmu_en = !!(mmu_en_msk & SMI_MMU_EN(port_id));
mtk_smi_port_config(larb, port_id, mmu_en, 0);
}
return MTK_SIP_E_SUCCESS;
}
static int mtk_infra_master_config_sec(uint32_t dev_id, uint32_t enable)
{
const struct mtk_ifr_mst_config *ifr_cfg;
uint32_t reg_addr;
mtk_infra_iommu_enable_protect();
if (dev_id >= MMU_DEV_NUM) {
return MTK_SIP_E_NOT_SUPPORTED;
}
ifr_cfg = &g_ifr_mst_cfg[dev_id];
reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
if (enable > 0U) {
mmio_setbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
} else {
mmio_clrbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
}
return MTK_SIP_E_SUCCESS;
}
static u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
u_register_t x3, u_register_t x4,
void *handle, struct smccc_res *smccc_ret)
{
uint32_t cmd_id = x1, mdl_id = x2, val = x3;
int ret = MTK_SIP_E_NOT_SUPPORTED;
(void)x4;
(void)handle;
switch (cmd_id) {
case IOMMU_ATF_CMD_CONFIG_SMI_LARB:
ret = mtk_smi_larb_port_config_sec(mdl_id, val);
break;
case IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU:
ret = mtk_infra_master_config_sec(mdl_id, val);
break;
default:
break;
}
return ret;
}
DECLARE_SMC_HANDLER(MTK_SIP_IOMMU_CONTROL, mtk_iommu_handler);

17
plat/mediatek/drivers/iommu/rules.mk

@ -0,0 +1,17 @@
#
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
LOCAL_DIR := $(call GET_LOCAL_DIR)
MODULE := mtk_iommu
LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_iommu_smc.c
LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtk_iommu_plat.c
PLAT_INCLUDES += -I${LOCAL_DIR}
PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))

37
plat/mediatek/include/mt8188/platform_def.h

@ -25,6 +25,12 @@
#define UART0_BASE (IO_PHYS + 0x01002000)
#define UART_BAUDRATE (115200)
/*******************************************************************************
* Infra IOMMU related constants
******************************************************************************/
#define PERICFG_AO_BASE (IO_PHYS + 0x01003000)
#define PERICFG_AO_REG_SIZE (0x1000)
/*******************************************************************************
* GIC-600 & interrupt handling related constants
******************************************************************************/
@ -41,6 +47,37 @@
#define CIRQ_REG_NUM (23)
#define CIRQ_SPI_START (96)
/*******************************************************************************
* MM IOMMU & SMI related constants
******************************************************************************/
#define SMI_LARB_0_BASE (IO_PHYS + 0x0c022000)
#define SMI_LARB_1_BASE (IO_PHYS + 0x0c023000)
#define SMI_LARB_2_BASE (IO_PHYS + 0x0c102000)
#define SMI_LARB_3_BASE (IO_PHYS + 0x0c103000)
#define SMI_LARB_4_BASE (IO_PHYS + 0x04013000)
#define SMI_LARB_5_BASE (IO_PHYS + 0x04f02000)
#define SMI_LARB_6_BASE (IO_PHYS + 0x04f03000)
#define SMI_LARB_7_BASE (IO_PHYS + 0x04e04000)
#define SMI_LARB_9_BASE (IO_PHYS + 0x05001000)
#define SMI_LARB_10_BASE (IO_PHYS + 0x05120000)
#define SMI_LARB_11A_BASE (IO_PHYS + 0x05230000)
#define SMI_LARB_11B_BASE (IO_PHYS + 0x05530000)
#define SMI_LARB_11C_BASE (IO_PHYS + 0x05630000)
#define SMI_LARB_12_BASE (IO_PHYS + 0x05340000)
#define SMI_LARB_13_BASE (IO_PHYS + 0x06001000)
#define SMI_LARB_14_BASE (IO_PHYS + 0x06002000)
#define SMI_LARB_15_BASE (IO_PHYS + 0x05140000)
#define SMI_LARB_16A_BASE (IO_PHYS + 0x06008000)
#define SMI_LARB_16B_BASE (IO_PHYS + 0x0600a000)
#define SMI_LARB_17A_BASE (IO_PHYS + 0x06009000)
#define SMI_LARB_17B_BASE (IO_PHYS + 0x0600b000)
#define SMI_LARB_19_BASE (IO_PHYS + 0x0a010000)
#define SMI_LARB_21_BASE (IO_PHYS + 0x0802e000)
#define SMI_LARB_23_BASE (IO_PHYS + 0x0800d000)
#define SMI_LARB_27_BASE (IO_PHYS + 0x07201000)
#define SMI_LARB_28_BASE (IO_PHYS + 0x00000000)
#define SMI_LARB_REG_RNG_SIZE (0x1000)
/*******************************************************************************
* DP related constants
******************************************************************************/

1
plat/mediatek/include/mtk_sip_def.h

@ -11,6 +11,7 @@
#define MTK_SIP_SMC_FROM_NS_EL1_TABLE(_func) \
_func(MTK_SIP_KERNEL_TIME_SYNC, 0x202) \
_func(MTK_SIP_VCORE_CONTROL, 0x506) \
_func(MTK_SIP_IOMMU_CONTROL, 0x514) \
_func(MTK_SIP_APUSYS_CONTROL, 0x51E) \
_func(MTK_SIP_DP_CONTROL, 0x523) \
_func(MTK_SIP_KERNEL_GIC_OP, 0x526)

1
plat/mediatek/mt8188/platform.mk

@ -25,6 +25,7 @@ MODULES-y += $(MTK_PLAT)/lib/pm
MODULES-y += $(MTK_PLAT)/drivers/cirq
MODULES-y += $(MTK_PLAT)/drivers/dp
MODULES-y += $(MTK_PLAT)/drivers/gic600
MODULES-y += $(MTK_PLAT)/drivers/iommu
MODULES-y += $(MTK_PLAT)/drivers/timer
PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \

Loading…
Cancel
Save