1*257aa94fSZhigang Qin /*
2*257aa94fSZhigang Qin * Copyright (c) 2025, MediaTek Inc. All rights reserved.
3*257aa94fSZhigang Qin *
4*257aa94fSZhigang Qin * SPDX-License-Identifier: BSD-3-Clause
5*257aa94fSZhigang Qin */
6*257aa94fSZhigang Qin
7*257aa94fSZhigang Qin #include <lib/mmio.h>
8*257aa94fSZhigang Qin #include <lib/utils_def.h>
9*257aa94fSZhigang Qin
10*257aa94fSZhigang Qin #include <drivers/spmi/pmif_common.h>
11*257aa94fSZhigang Qin #include <drivers/spmi/pmif_v1/pmif.h>
12*257aa94fSZhigang Qin #include <drivers/spmi/spmi_common.h>
13*257aa94fSZhigang Qin #include <drivers/spmi/spmi_sw.h>
14*257aa94fSZhigang Qin #include <drivers/spmi_api.h>
15*257aa94fSZhigang Qin #include <lib/mtk_init/mtk_init.h>
16*257aa94fSZhigang Qin #include <mtk_mmap_pool.h>
17*257aa94fSZhigang Qin
18*257aa94fSZhigang Qin #define SPMI_GROUP_ID 0xB
19*257aa94fSZhigang Qin #define SPMI_DEBUG 0
20*257aa94fSZhigang Qin
21*257aa94fSZhigang Qin static uint16_t mt6xxx_regs[] = {
22*257aa94fSZhigang Qin [PMIF_INIT_DONE] = 0x0000,
23*257aa94fSZhigang Qin [PMIF_INF_EN] = 0x0024,
24*257aa94fSZhigang Qin [PMIF_ARB_EN] = 0x0150,
25*257aa94fSZhigang Qin [PMIF_IRQ_EVENT_EN_0] = 0x0420,
26*257aa94fSZhigang Qin [PMIF_IRQ_FLAG_0] = 0x0428,
27*257aa94fSZhigang Qin [PMIF_IRQ_CLR_0] = 0x042C,
28*257aa94fSZhigang Qin [PMIF_IRQ_EVENT_EN_2] = 0x0440,
29*257aa94fSZhigang Qin [PMIF_IRQ_FLAG_2] = 0x0448,
30*257aa94fSZhigang Qin [PMIF_IRQ_CLR_2] = 0x044C,
31*257aa94fSZhigang Qin [PMIF_WDT_CTRL] = 0x0470,
32*257aa94fSZhigang Qin [PMIF_WDT_EVENT_EN_1] = 0x047C,
33*257aa94fSZhigang Qin [PMIF_WDT_FLAG_1] = 0x0480,
34*257aa94fSZhigang Qin [PMIF_SWINF_2_ACC] = 0x0880,
35*257aa94fSZhigang Qin [PMIF_SWINF_2_WDATA_31_0] = 0x0884,
36*257aa94fSZhigang Qin [PMIF_SWINF_2_WDATA_63_32] = 0x0888,
37*257aa94fSZhigang Qin [PMIF_SWINF_2_RDATA_31_0] = 0x0894,
38*257aa94fSZhigang Qin [PMIF_SWINF_2_RDATA_63_32] = 0x0898,
39*257aa94fSZhigang Qin [PMIF_SWINF_2_VLD_CLR] = 0x08A4,
40*257aa94fSZhigang Qin [PMIF_SWINF_2_STA] = 0x08A8,
41*257aa94fSZhigang Qin [PMIF_SWINF_3_ACC] = 0x08C0,
42*257aa94fSZhigang Qin [PMIF_SWINF_3_WDATA_31_0] = 0x08C4,
43*257aa94fSZhigang Qin [PMIF_SWINF_3_WDATA_63_32] = 0x08C8,
44*257aa94fSZhigang Qin [PMIF_SWINF_3_RDATA_31_0] = 0x08D4,
45*257aa94fSZhigang Qin [PMIF_SWINF_3_RDATA_63_32] = 0x08D8,
46*257aa94fSZhigang Qin [PMIF_SWINF_3_VLD_CLR] = 0x08E4,
47*257aa94fSZhigang Qin [PMIF_SWINF_3_STA] = 0x08E8,
48*257aa94fSZhigang Qin /* hw mpu */
49*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_EN_1] = 0x09B0,
50*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_EN_2] = 0x0D30,
51*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_0_START] = 0x09B4,
52*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_0_END] = 0x09B8,
53*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_1_START] = 0x09BC,
54*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_1_END] = 0x09C0,
55*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_2_START] = 0x09C4,
56*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_2_END] = 0x09C8,
57*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_3_START] = 0x09CC,
58*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_3_END] = 0x09D0,
59*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_31_START] = 0x0D34,
60*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_31_END] = 0x0D38,
61*257aa94fSZhigang Qin [PMIF_PMIC_ALL_INVLD_SLVID] = 0x0AAC,
62*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_0_PER0] = 0x0AB0,
63*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_0_PER1] = 0x0AB4,
64*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_1_PER0] = 0x0AB8,
65*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_2_PER0] = 0x0AC0,
66*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_3_PER0] = 0x0AC8,
67*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_31_PER0] = 0x0E34,
68*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_31_PER1] = 0x0E38,
69*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_OTHERS_PER0] = 0x0BA8,
70*257aa94fSZhigang Qin [PMIF_PMIC_ALL_RGN_OTHERS_PER1] = 0x0BAC,
71*257aa94fSZhigang Qin };
72*257aa94fSZhigang Qin
73*257aa94fSZhigang Qin static uint16_t mt6xxx_spmi_regs[] = {
74*257aa94fSZhigang Qin [SPMI_OP_ST_CTRL] = 0x0000,
75*257aa94fSZhigang Qin [SPMI_GRP_ID_EN] = 0x0004,
76*257aa94fSZhigang Qin [SPMI_OP_ST_STA] = 0x0008,
77*257aa94fSZhigang Qin [SPMI_MST_SAMPL] = 0x000c,
78*257aa94fSZhigang Qin [SPMI_MST_REQ_EN] = 0x0010,
79*257aa94fSZhigang Qin [SPMI_RCS_CTRL] = 0x0014,
80*257aa94fSZhigang Qin [SPMI_SLV_3_0_EINT] = 0x0020,
81*257aa94fSZhigang Qin [SPMI_SLV_7_4_EINT] = 0x0024,
82*257aa94fSZhigang Qin [SPMI_SLV_B_8_EINT] = 0x0028,
83*257aa94fSZhigang Qin [SPMI_SLV_F_C_EINT] = 0x002c,
84*257aa94fSZhigang Qin [SPMI_REC_CTRL] = 0x0040,
85*257aa94fSZhigang Qin [SPMI_REC0] = 0x0044,
86*257aa94fSZhigang Qin [SPMI_REC1] = 0x0048,
87*257aa94fSZhigang Qin [SPMI_REC2] = 0x004c,
88*257aa94fSZhigang Qin [SPMI_REC3] = 0x0050,
89*257aa94fSZhigang Qin [SPMI_REC4] = 0x0054,
90*257aa94fSZhigang Qin [SPMI_REC_CMD_DEC] = 0x005c,
91*257aa94fSZhigang Qin [SPMI_DEC_DBG] = 0x00f8,
92*257aa94fSZhigang Qin [SPMI_MST_DBG] = 0x00fc,
93*257aa94fSZhigang Qin };
94*257aa94fSZhigang Qin
95*257aa94fSZhigang Qin struct pmif pmif_spmi_arb[] = {
96*257aa94fSZhigang Qin {
97*257aa94fSZhigang Qin .regs = mt6xxx_regs,
98*257aa94fSZhigang Qin .spmimst_regs = mt6xxx_spmi_regs,
99*257aa94fSZhigang Qin .mstid = SPMI_MASTER_0,
100*257aa94fSZhigang Qin .read_cmd = pmif_spmi_read_cmd,
101*257aa94fSZhigang Qin .write_cmd = pmif_spmi_write_cmd,
102*257aa94fSZhigang Qin },
103*257aa94fSZhigang Qin {
104*257aa94fSZhigang Qin .regs = mt6xxx_regs,
105*257aa94fSZhigang Qin .spmimst_regs = mt6xxx_spmi_regs,
106*257aa94fSZhigang Qin .mstid = SPMI_MASTER_1,
107*257aa94fSZhigang Qin .read_cmd = pmif_spmi_read_cmd,
108*257aa94fSZhigang Qin .write_cmd = pmif_spmi_write_cmd,
109*257aa94fSZhigang Qin },
110*257aa94fSZhigang Qin {
111*257aa94fSZhigang Qin .base = (unsigned int *)PMIF_SPMI_P_BASE,
112*257aa94fSZhigang Qin .regs = mt6xxx_regs,
113*257aa94fSZhigang Qin .spmimst_base = (unsigned int *)SPMI_MST_P_BASE,
114*257aa94fSZhigang Qin .spmimst_regs = mt6xxx_spmi_regs,
115*257aa94fSZhigang Qin .mstid = SPMI_MASTER_P_1,
116*257aa94fSZhigang Qin .read_cmd = pmif_spmi_read_cmd,
117*257aa94fSZhigang Qin .write_cmd = pmif_spmi_write_cmd,
118*257aa94fSZhigang Qin },
119*257aa94fSZhigang Qin };
120*257aa94fSZhigang Qin
121*257aa94fSZhigang Qin static struct spmi_device spmi_dev[] = {
122*257aa94fSZhigang Qin {
123*257aa94fSZhigang Qin .slvid = SPMI_SLAVE_7, /* MT6319 */
124*257aa94fSZhigang Qin .grpiden = 0x800,
125*257aa94fSZhigang Qin .type = BUCK_CPU,
126*257aa94fSZhigang Qin .type_id = BUCK_CPU_ID,
127*257aa94fSZhigang Qin .mstid = SPMI_MASTER_P_1,/* spmi-p */
128*257aa94fSZhigang Qin .hwcid_addr = 0x09,
129*257aa94fSZhigang Qin .hwcid_val = 0x15,
130*257aa94fSZhigang Qin .swcid_addr = 0x0B,
131*257aa94fSZhigang Qin .swcid_val = 0x15,
132*257aa94fSZhigang Qin .wpk_key_addr = 0x3A8,
133*257aa94fSZhigang Qin .wpk_key_val = 0x6315,
134*257aa94fSZhigang Qin .tma_key_addr = 0x39F,
135*257aa94fSZhigang Qin .tma_key_val = 0x9CEA,
136*257aa94fSZhigang Qin .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
137*257aa94fSZhigang Qin },
138*257aa94fSZhigang Qin {
139*257aa94fSZhigang Qin .slvid = SPMI_SLAVE_8, /* MT6319 */
140*257aa94fSZhigang Qin .grpiden = 0x800,
141*257aa94fSZhigang Qin .type = BUCK_CPU,
142*257aa94fSZhigang Qin .type_id = BUCK_CPU_ID,
143*257aa94fSZhigang Qin .mstid = SPMI_MASTER_P_1,/* spmi-p */
144*257aa94fSZhigang Qin .hwcid_addr = 0x09,
145*257aa94fSZhigang Qin .hwcid_val = 0x15,
146*257aa94fSZhigang Qin .swcid_addr = 0x0B,
147*257aa94fSZhigang Qin .swcid_val = 0x15,
148*257aa94fSZhigang Qin .wpk_key_addr = 0x3A8,
149*257aa94fSZhigang Qin .wpk_key_val = 0x6315,
150*257aa94fSZhigang Qin .tma_key_addr = 0x39F,
151*257aa94fSZhigang Qin .tma_key_val = 0x9CEA,
152*257aa94fSZhigang Qin .pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
153*257aa94fSZhigang Qin },
154*257aa94fSZhigang Qin };
155*257aa94fSZhigang Qin
platform_pmif_spmi_init(void)156*257aa94fSZhigang Qin int platform_pmif_spmi_init(void)
157*257aa94fSZhigang Qin {
158*257aa94fSZhigang Qin /*
159*257aa94fSZhigang Qin * The MT8189 chipset comes in two variants: MT8189G and MT8189H. The
160*257aa94fSZhigang Qin * MT8189G variant uses a single PMIC IC (MT6319), whereas the MT8189H
161*257aa94fSZhigang Qin * variant uses two PMIC ICs. To ensure driver compatibility, we utilize
162*257aa94fSZhigang Qin * the CPU ID and segment ID to accurately determine the required number
163*257aa94fSZhigang Qin * of SPMIF instances.
164*257aa94fSZhigang Qin */
165*257aa94fSZhigang Qin if (mmio_read_32((uintptr_t)CHIP_ID_REG) == MTK_CPU_ID_MT8189 &&
166*257aa94fSZhigang Qin mmio_read_32((uintptr_t)CPU_SEG_ID_REG) == MTK_CPU_SEG_ID_MT8189G)
167*257aa94fSZhigang Qin spmi_device_register(spmi_dev, 1);
168*257aa94fSZhigang Qin else
169*257aa94fSZhigang Qin spmi_device_register(spmi_dev, ARRAY_SIZE(spmi_dev));
170*257aa94fSZhigang Qin
171*257aa94fSZhigang Qin return 0;
172*257aa94fSZhigang Qin }
173*257aa94fSZhigang Qin MTK_ARCH_INIT(platform_pmif_spmi_init);
174