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