xref: /rk3399_ARM-atf/plat/mediatek/drivers/spmi/mt8196/platform_pmif_spmi.c (revision cf2df874cd09305ac7282fadb0fef6be597dfffb)
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