blob: e99872544b588730a8081df953254cda866d3053 [file] [log] [blame]
Chengci Xudb1e75b2022-07-20 16:20:15 +08001/*
developerca791f82022-12-30 13:33:04 +08002 * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
Chengci Xudb1e75b2022-07-20 16:20:15 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stddef.h>
8#include <mtk_iommu_plat.h>
9
10/* defination */
11/* smi larb */
12#define SMI_LARB_NON_SEC_CON(port) (0x380 + ((port) << 2))
13#define PATH_SEL_MASK (0xf0000) /* to sram (INT) */
14#define SMI_LARB_SEC_CON_INT(port) (0xf00 + ((port) << 2))
15#define SMI_LARB_SEC_CON(port) (0xf80 + ((port) << 2))
16#define MMU_MASK BIT(0)
17#define MMU_EN(en) ((!!(en)) << 0)
18#define SEC_MASK BIT(1)
19#define SEC_EN(en) ((!!(en)) << 1)
20#define DOMAIN_MASK (0x1f << 4)
21#define SMI_MMU_EN(port) (0x1 << (port))
22
23/* infra master */
24#define IFR_CFG_MMU_EN_MSK(r_bit) (0x3 << (r_bit))
25
26/* smi larb configure */
27/*
28 * If multimedia security config is enabled, the SMI config register must be
29 * configurated in security world.
30 * And the SRAM path is also configurated here to enhance security.
31 */
32static void mtk_smi_larb_port_config_to_sram(
33 const struct mtk_smi_larb_config *larb,
34 uint32_t port_id)
35{
36 mmio_clrbits_32(larb->base + SMI_LARB_SEC_CON_INT(port_id),
37 MMU_MASK | SEC_MASK | DOMAIN_MASK);
38
39 mmio_setbits_32(larb->base + SMI_LARB_NON_SEC_CON(port_id),
40 PATH_SEL_MASK);
41}
42
43static void mtk_smi_port_config(const struct mtk_smi_larb_config *larb,
44 uint32_t port_id, uint8_t mmu_en, uint8_t sec_en)
45{
46 mmio_clrsetbits_32(larb->base + SMI_LARB_SEC_CON(port_id),
47 MMU_MASK | SEC_MASK | DOMAIN_MASK,
48 MMU_EN(mmu_en) | SEC_EN(sec_en));
49}
50
51static int mtk_smi_larb_port_config_sec(uint32_t larb_id, uint32_t mmu_en_msk)
52{
53 uint32_t port_id, port_nr;
54 const struct mtk_smi_larb_config *larb;
55 uint32_t to_sram;
56 uint8_t mmu_en;
57
58 if (larb_id >= SMI_LARB_NUM) {
59 return MTK_SIP_E_INVALID_PARAM;
60 }
61
62 larb = &g_larb_cfg[larb_id];
63 port_nr = larb->port_nr;
64 to_sram = larb->to_sram;
65
66 for (port_id = 0; port_id < port_nr; port_id++) {
67 if ((to_sram & BIT(port_id)) > 0U) {
68 mtk_smi_larb_port_config_to_sram(larb, port_id);
69 continue;
70 }
71 mmu_en = !!(mmu_en_msk & SMI_MMU_EN(port_id));
72 mtk_smi_port_config(larb, port_id, mmu_en, 0);
73 }
74
75 return MTK_SIP_E_SUCCESS;
76}
77
developerca791f82022-12-30 13:33:04 +080078static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable)
Chengci Xudb1e75b2022-07-20 16:20:15 +080079{
80 const struct mtk_ifr_mst_config *ifr_cfg;
developerca791f82022-12-30 13:33:04 +080081 uint32_t dev_id, reg_addr, reg_mask;
Chengci Xudb1e75b2022-07-20 16:20:15 +080082
83 mtk_infra_iommu_enable_protect();
84
developerca791f82022-12-30 13:33:04 +080085 if (dev_id_msk >= BIT(MMU_DEV_NUM)) {
86 return MTK_SIP_E_INVALID_PARAM;
Chengci Xudb1e75b2022-07-20 16:20:15 +080087 }
88
developerca791f82022-12-30 13:33:04 +080089 for (dev_id = 0U; dev_id < MMU_DEV_NUM; dev_id++) {
90 if ((dev_id_msk & BIT(dev_id)) == 0U) {
91 continue;
92 }
Chengci Xudb1e75b2022-07-20 16:20:15 +080093
developerca791f82022-12-30 13:33:04 +080094 ifr_cfg = &g_ifr_mst_cfg[dev_id];
95 reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
96 g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
97 reg_mask = IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit);
98
99 if (enable > 0U) {
100 mmio_setbits_32(reg_addr, reg_mask);
101 } else {
102 mmio_clrbits_32(reg_addr, reg_mask);
103 }
Chengci Xudb1e75b2022-07-20 16:20:15 +0800104 }
105
106 return MTK_SIP_E_SUCCESS;
107}
108
109static u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
110 u_register_t x3, u_register_t x4,
111 void *handle, struct smccc_res *smccc_ret)
112{
113 uint32_t cmd_id = x1, mdl_id = x2, val = x3;
114 int ret = MTK_SIP_E_NOT_SUPPORTED;
115
116 (void)x4;
117 (void)handle;
118
119 switch (cmd_id) {
120 case IOMMU_ATF_CMD_CONFIG_SMI_LARB:
121 ret = mtk_smi_larb_port_config_sec(mdl_id, val);
122 break;
123 case IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU:
124 ret = mtk_infra_master_config_sec(mdl_id, val);
125 break;
126 default:
127 break;
128 }
129
130 return ret;
131}
132DECLARE_SMC_HANDLER(MTK_SIP_IOMMU_CONTROL, mtk_iommu_handler);