1 /*
2 * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <lib/utils_def.h>
8
9 #include <drivers/spmi/pmif_common.h>
10 #include <drivers/spmi/pmif_v1/pmif.h>
11 #include <drivers/spmi/spmi_common.h>
12 #include <drivers/spmi/spmi_sw.h>
13 #include <drivers/spmi_api.h>
14 #include <lib/mtk_init/mtk_init.h>
15 #include <mtk_mmap_pool.h>
16
17 #define SPMI_GROUP_ID 0xB
18 #define SPMI_DEBUG 0
19
20 static const mmap_region_t pmif_spmi_mmap[] MTK_MMAP_SECTION = {
21 MAP_REGION_FLAT(PMIF_SPMI_M_BASE, PMIF_SPMI_SIZE,
22 MT_DEVICE | MT_RW | MT_NS),
23 MAP_REGION_FLAT(SPMI_MST_M_BASE, SPMI_MST_SIZE,
24 MT_DEVICE | MT_RW | MT_SECURE),
25 MAP_REGION_FLAT(PMIF_SPMI_P_BASE, PMIF_SPMI_SIZE,
26 MT_DEVICE | MT_RW | MT_NS),
27 {0}
28 };
29 DECLARE_MTK_MMAP_REGIONS(pmif_spmi_mmap);
30
31 static uint16_t mt6xxx_spmi_regs[] = {
32 [SPMI_OP_ST_CTRL] = 0x0000,
33 [SPMI_GRP_ID_EN] = 0x0004,
34 [SPMI_OP_ST_STA] = 0x0008,
35 [SPMI_MST_SAMPL] = 0x000C,
36 [SPMI_MST_REQ_EN] = 0x0010,
37 [SPMI_RCS_CTRL] = 0x0014,
38 [SPMI_SLV_3_0_EINT] = 0x0020,
39 [SPMI_SLV_7_4_EINT] = 0x0024,
40 [SPMI_SLV_B_8_EINT] = 0x0028,
41 [SPMI_SLV_F_C_EINT] = 0x002C,
42 [SPMI_REC_CTRL] = 0x0040,
43 [SPMI_REC0] = 0x0044,
44 [SPMI_REC1] = 0x0048,
45 [SPMI_REC2] = 0x004C,
46 [SPMI_REC3] = 0x0050,
47 [SPMI_REC4] = 0x0054,
48 [SPMI_REC_CMD_DEC] = 0x005C,
49 [SPMI_DEC_DBG] = 0x00F8,
50 [SPMI_MST_DBG] = 0x00FC,
51 };
52
53 static uint16_t mt6xxx_regs[] = {
54 [PMIF_INIT_DONE] = 0x0000,
55 [PMIF_INF_EN] = 0x0024,
56 [PMIF_ARB_EN] = 0x0150,
57 [PMIF_IRQ_EVENT_EN_0] = 0x0420,
58 [PMIF_IRQ_FLAG_0] = 0x0428,
59 [PMIF_IRQ_CLR_0] = 0x042C,
60 [PMIF_IRQ_EVENT_EN_2] = 0x0440,
61 [PMIF_IRQ_FLAG_2] = 0x0448,
62 [PMIF_IRQ_CLR_2] = 0x044C,
63 [PMIF_WDT_CTRL] = 0x0470,
64 [PMIF_WDT_EVENT_EN_1] = 0x047C,
65 [PMIF_WDT_FLAG_1] = 0x0480,
66 [PMIF_SWINF_2_ACC] = 0x0880,
67 [PMIF_SWINF_2_WDATA_31_0] = 0x0884,
68 [PMIF_SWINF_2_WDATA_63_32] = 0x0888,
69 [PMIF_SWINF_2_RDATA_31_0] = 0x0894,
70 [PMIF_SWINF_2_RDATA_63_32] = 0x0898,
71 [PMIF_SWINF_2_VLD_CLR] = 0x08A4,
72 [PMIF_SWINF_2_STA] = 0x08A8,
73 [PMIF_SWINF_3_ACC] = 0x08C0,
74 [PMIF_SWINF_3_WDATA_31_0] = 0x08C4,
75 [PMIF_SWINF_3_WDATA_63_32] = 0x08C8,
76 [PMIF_SWINF_3_RDATA_31_0] = 0x08D4,
77 [PMIF_SWINF_3_RDATA_63_32] = 0x08D8,
78 [PMIF_SWINF_3_VLD_CLR] = 0x08E4,
79 [PMIF_SWINF_3_STA] = 0x08E8,
80 /* hw mpu */
81 [PMIF_PMIC_ALL_RGN_EN_1] = 0x09B0,
82 [PMIF_PMIC_ALL_RGN_EN_2] = 0x0D30,
83 [PMIF_PMIC_ALL_RGN_0_START] = 0x09B4,
84 [PMIF_PMIC_ALL_RGN_0_END] = 0x09B8,
85 [PMIF_PMIC_ALL_RGN_1_START] = 0x09BC,
86 [PMIF_PMIC_ALL_RGN_1_END] = 0x09C0,
87 [PMIF_PMIC_ALL_RGN_2_START] = 0x09C4,
88 [PMIF_PMIC_ALL_RGN_2_END] = 0x09C8,
89 [PMIF_PMIC_ALL_RGN_3_START] = 0x09CC,
90 [PMIF_PMIC_ALL_RGN_3_END] = 0x09D0,
91 [PMIF_PMIC_ALL_RGN_31_START] = 0x0D34,
92 [PMIF_PMIC_ALL_RGN_31_END] = 0x0D38,
93 [PMIF_PMIC_ALL_INVLD_SLVID] = 0x0AAC,
94 [PMIF_PMIC_ALL_RGN_0_PER0] = 0x0AB0,
95 [PMIF_PMIC_ALL_RGN_0_PER1] = 0x0AB4,
96 [PMIF_PMIC_ALL_RGN_1_PER0] = 0x0AB8,
97 [PMIF_PMIC_ALL_RGN_2_PER0] = 0x0AC0,
98 [PMIF_PMIC_ALL_RGN_3_PER0] = 0x0AC8,
99 [PMIF_PMIC_ALL_RGN_31_PER0] = 0x0DB4,
100 [PMIF_PMIC_ALL_RGN_31_PER1] = 0x0DB8,
101 [PMIF_PMIC_ALL_RGN_OTHERS_PER0] = 0x0BA8,
102 [PMIF_PMIC_ALL_RGN_OTHERS_PER1] = 0x0BAC,
103 };
104
105 struct pmif pmif_spmi_arb[] = {
106 {
107 .base = (void *)PMIF_SPMI_M_BASE,
108 .regs = mt6xxx_regs,
109 .spmimst_base = (void *)SPMI_MST_M_BASE,
110 .spmimst_regs = mt6xxx_spmi_regs,
111 .mstid = SPMI_MASTER_0,
112 .read_cmd = pmif_spmi_read_cmd,
113 .write_cmd = pmif_spmi_write_cmd,
114 }, {
115 .base = (void *)PMIF_SPMI_M_BASE,
116 .regs = mt6xxx_regs,
117 .spmimst_base = (void *)SPMI_MST_M_BASE,
118 .spmimst_regs = mt6xxx_spmi_regs,
119 .mstid = SPMI_MASTER_1,
120 .read_cmd = pmif_spmi_read_cmd,
121 .write_cmd = pmif_spmi_write_cmd,
122 }, {
123 .base = (void *)PMIF_SPMI_P_BASE,
124 .regs = mt6xxx_regs,
125 .spmimst_base = (void *)SPMI_MST_P_BASE,
126 .spmimst_regs = mt6xxx_spmi_regs,
127 .mstid = SPMI_MASTER_P_1,
128 .read_cmd = pmif_spmi_read_cmd,
129 .write_cmd = pmif_spmi_write_cmd,
130 },
131 };
132
133 static struct spmi_device spmi_dev[] = {
134 {
135 .slvid = SPMI_SLAVE_4,
136 .grpiden = 0x1 << SPMI_GROUP_ID,
137 .mstid = SPMI_MASTER_1,
138 .hwcid_addr = 0x09,
139 .hwcid_val = 0x63,
140 .swcid_addr = 0x0B,
141 .swcid_val = 0x63,
142 .wpk_key_addr = 0x3A7,
143 .wpk_key_val = 0x9C,
144 .wpk_key_h_val = 0x9C,
145 .tma_key_addr = 0x39E,
146 .tma_key_val = 0x9C,
147 .tma_key_h_val = 0x9C,
148 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
149 }, {
150 .slvid = SPMI_SLAVE_9,
151 .grpiden = 0x1 << SPMI_GROUP_ID,
152 .mstid = SPMI_MASTER_1,
153 .hwcid_addr = 0x09,
154 .hwcid_val = 0x85,
155 .swcid_addr = 0x0B,
156 .swcid_val = 0x85,
157 .wpk_key_addr = 0x3AA,
158 .wpk_key_val = 0x30,
159 .wpk_key_h_val = 0x63,
160 .tma_key_addr = 0x39E,
161 .tma_key_val = 0x7A,
162 .tma_key_h_val = 0x99,
163 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
164 }, {
165 .slvid = SPMI_SLAVE_5,
166 .grpiden = 0x800,
167 .mstid = SPMI_MASTER_1,/* spmi-m */
168 .hwcid_addr = 0x09,
169 .hwcid_val = 0x73,
170 .swcid_addr = 0x0B,
171 .swcid_val = 0x73,
172 .wpk_key_addr = 0x3A7,
173 .wpk_key_val = 0x8C,
174 .wpk_key_h_val = 0x9C,
175 .tma_key_addr = 0x39E,
176 .tma_key_val = 0x8C,
177 .tma_key_h_val = 0x9C,
178 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
179 }, {
180 .slvid = SPMI_SLAVE_14, /* MT6379 */
181 .grpiden = 0x800,
182 .mstid = SPMI_MASTER_1,/* spmi-m */
183 .hwcid_addr = 0x00,
184 .hwcid_val = 0x70,
185 .hwcid_mask = 0xF0,
186 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
187 }, {
188 .slvid = SPMI_SLAVE_6, /* MT6316 */
189 .grpiden = 0x800,
190 .mstid = SPMI_MASTER_P_1,/* spmi-m */
191 .hwcid_addr = 0x209,
192 .hwcid_val = 0x16,
193 .swcid_addr = 0x20B,
194 .swcid_val = 0x16,
195 .wpk_key_addr = 0x3B1,
196 .wpk_key_val = 0xE9,
197 .wpk_key_h_val = 0xE6,
198 .tma_key_addr = 0x3A8,
199 .tma_key_val = 0xE9,
200 .tma_key_h_val = 0xE6,
201 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
202 }, {
203 .slvid = SPMI_SLAVE_7,
204 .grpiden = 0x800,
205 .mstid = SPMI_MASTER_P_1,/* spmi-m */
206 .hwcid_addr = 0x209,
207 .hwcid_val = 0x16,
208 .swcid_addr = 0x20B,
209 .swcid_val = 0x16,
210 .wpk_key_addr = 0x3B1,
211 .wpk_key_val = 0xE9,
212 .wpk_key_h_val = 0xE6,
213 .tma_key_addr = 0x3A8,
214 .tma_key_val = 0xE9,
215 .tma_key_h_val = 0xE6,
216 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
217 }, {
218 .slvid = SPMI_SLAVE_8,
219 .grpiden = 0x800,
220 .mstid = SPMI_MASTER_P_1,/* spmi-m */
221 .hwcid_addr = 0x209,
222 .hwcid_val = 0x16,
223 .swcid_addr = 0x20B,
224 .swcid_val = 0x16,
225 .wpk_key_addr = 0x3B1,
226 .wpk_key_val = 0xE9,
227 .wpk_key_h_val = 0xE6,
228 .tma_key_addr = 0x3A8,
229 .tma_key_val = 0xE9,
230 .tma_key_h_val = 0xE6,
231 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
232 }, {
233 .slvid = SPMI_SLAVE_15,
234 .grpiden = 0x800,
235 .mstid = SPMI_MASTER_P_1,/* spmi-m */
236 .hwcid_addr = 0x209,
237 .hwcid_val = 0x16,
238 .swcid_addr = 0x20B,
239 .swcid_val = 0x16,
240 .wpk_key_addr = 0x3B1,
241 .wpk_key_val = 0xE9,
242 .wpk_key_h_val = 0xE6,
243 .tma_key_addr = 0x3A8,
244 .tma_key_val = 0xE9,
245 .tma_key_h_val = 0xE6,
246 .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
247 },
248 };
249
250 #if SPMI_DEBUG
spmi_read_check(struct spmi_device * dev)251 static void spmi_read_check(struct spmi_device *dev)
252 {
253 uint8_t rdata = 0;
254
255 spmi_ext_register_readl(dev, dev->hwcid_addr, &rdata, 1);
256
257 if (dev->hwcid_mask) {
258 if ((rdata & dev->hwcid_mask) == (dev->hwcid_val & dev->hwcid_mask))
259 SPMI_INFO("%s pass, slvid:%d rdata = 0x%x\n", __func__,
260 dev->slvid, rdata);
261 else
262 SPMI_ERR("%s fail, slvid:%d rdata = 0x%x\n", __func__,
263 dev->slvid, rdata);
264 } else {
265 if (rdata == dev->hwcid_val)
266 SPMI_INFO("%s pass, slvid:%d rdata = 0x%x\n", __func__,
267 dev->slvid, rdata);
268 else
269 SPMI_ERR("%s fail, slvid:%d rdata = 0x%x\n", __func__,
270 dev->slvid, rdata);
271 }
272 }
273
spmi_test(void)274 void spmi_test(void)
275 {
276 for (int k = 0; k < ARRAY_SIZE(spmi_dev); k++)
277 spmi_read_check(&spmi_dev[k]);
278 }
279 #endif
280
platform_pmif_spmi_init(void)281 int platform_pmif_spmi_init(void)
282 {
283 spmi_device_register(spmi_dev, ARRAY_SIZE(spmi_dev));
284
285 #if SPMI_DEBUG
286 spmi_test();
287 #endif
288 return 0;
289 }
290 MTK_ARCH_INIT(platform_pmif_spmi_init);
291