1*fb57af70SWenzhen Yu /*
2*fb57af70SWenzhen Yu * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3*fb57af70SWenzhen Yu *
4*fb57af70SWenzhen Yu * SPDX-License-Identifier: BSD-3-Clause
5*fb57af70SWenzhen Yu */
6*fb57af70SWenzhen Yu
7*fb57af70SWenzhen Yu #include <common/debug.h>
8*fb57af70SWenzhen Yu #include <lib/mmio.h>
9*fb57af70SWenzhen Yu #include <platform_def.h>
10*fb57af70SWenzhen Yu
11*fb57af70SWenzhen Yu #include <mt_spm_hwreq.h>
12*fb57af70SWenzhen Yu #include <mt_spm_reg.h>
13*fb57af70SWenzhen Yu
spm_hwcg_index2res(uint32_t idx)14*fb57af70SWenzhen Yu static uint32_t spm_hwcg_index2res(uint32_t idx)
15*fb57af70SWenzhen Yu {
16*fb57af70SWenzhen Yu uint32_t res;
17*fb57af70SWenzhen Yu
18*fb57af70SWenzhen Yu if (idx >= HWCG_MAX)
19*fb57af70SWenzhen Yu return 0;
20*fb57af70SWenzhen Yu
21*fb57af70SWenzhen Yu switch (idx) {
22*fb57af70SWenzhen Yu case HWCG_DDREN:
23*fb57af70SWenzhen Yu res = (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI);
24*fb57af70SWenzhen Yu break;
25*fb57af70SWenzhen Yu case HWCG_VRF18:
26*fb57af70SWenzhen Yu res = MT_SPM_SYSPLL;
27*fb57af70SWenzhen Yu break;
28*fb57af70SWenzhen Yu case HWCG_INFRA:
29*fb57af70SWenzhen Yu res = MT_SPM_INFRA;
30*fb57af70SWenzhen Yu break;
31*fb57af70SWenzhen Yu case HWCG_PMIC:
32*fb57af70SWenzhen Yu res = MT_SPM_PMIC;
33*fb57af70SWenzhen Yu break;
34*fb57af70SWenzhen Yu case HWCG_F26M:
35*fb57af70SWenzhen Yu res = MT_SPM_26M;
36*fb57af70SWenzhen Yu break;
37*fb57af70SWenzhen Yu case HWCG_VCORE:
38*fb57af70SWenzhen Yu res = MT_SPM_VCORE;
39*fb57af70SWenzhen Yu break;
40*fb57af70SWenzhen Yu default:
41*fb57af70SWenzhen Yu res = 0;
42*fb57af70SWenzhen Yu }
43*fb57af70SWenzhen Yu return res;
44*fb57af70SWenzhen Yu }
45*fb57af70SWenzhen Yu
spm_hwcg_ctrl_get(struct spm_hwcg_info * info,enum spm_hwcg_setting type)46*fb57af70SWenzhen Yu static uint32_t spm_hwcg_ctrl_get(struct spm_hwcg_info *info,
47*fb57af70SWenzhen Yu enum spm_hwcg_setting type)
48*fb57af70SWenzhen Yu {
49*fb57af70SWenzhen Yu uint32_t reg = 0;
50*fb57af70SWenzhen Yu
51*fb57af70SWenzhen Yu if (!info)
52*fb57af70SWenzhen Yu return 0;
53*fb57af70SWenzhen Yu
54*fb57af70SWenzhen Yu switch (type) {
55*fb57af70SWenzhen Yu case HWCG_PWR:
56*fb57af70SWenzhen Yu reg = info->pwr;
57*fb57af70SWenzhen Yu break;
58*fb57af70SWenzhen Yu case HWCG_PWR_MSB:
59*fb57af70SWenzhen Yu reg = info->pwr_msb;
60*fb57af70SWenzhen Yu break;
61*fb57af70SWenzhen Yu default:
62*fb57af70SWenzhen Yu reg = info->module_busy;
63*fb57af70SWenzhen Yu break;
64*fb57af70SWenzhen Yu }
65*fb57af70SWenzhen Yu return reg;
66*fb57af70SWenzhen Yu }
67*fb57af70SWenzhen Yu
__spm_hwcg_ctrl(struct spm_hwcg_info * info,enum spm_hwcg_setting type,uint32_t is_set,uint32_t val)68*fb57af70SWenzhen Yu static void __spm_hwcg_ctrl(struct spm_hwcg_info *info,
69*fb57af70SWenzhen Yu enum spm_hwcg_setting type,
70*fb57af70SWenzhen Yu uint32_t is_set, uint32_t val)
71*fb57af70SWenzhen Yu {
72*fb57af70SWenzhen Yu uint32_t reg;
73*fb57af70SWenzhen Yu
74*fb57af70SWenzhen Yu reg = spm_hwcg_ctrl_get(info, type);
75*fb57af70SWenzhen Yu
76*fb57af70SWenzhen Yu if (!reg)
77*fb57af70SWenzhen Yu return;
78*fb57af70SWenzhen Yu
79*fb57af70SWenzhen Yu if (is_set)
80*fb57af70SWenzhen Yu mmio_setbits_32(reg, val);
81*fb57af70SWenzhen Yu else
82*fb57af70SWenzhen Yu mmio_clrbits_32(reg, val);
83*fb57af70SWenzhen Yu }
84*fb57af70SWenzhen Yu
spm_hwcg_ctrl(uint32_t res,enum spm_hwcg_setting type,uint32_t is_set,uint32_t val)85*fb57af70SWenzhen Yu void spm_hwcg_ctrl(uint32_t res, enum spm_hwcg_setting type,
86*fb57af70SWenzhen Yu uint32_t is_set, uint32_t val)
87*fb57af70SWenzhen Yu {
88*fb57af70SWenzhen Yu struct spm_hwcg_info info;
89*fb57af70SWenzhen Yu
90*fb57af70SWenzhen Yu if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
91*fb57af70SWenzhen Yu DECLARE_HWCG_REG(DDREN, info);
92*fb57af70SWenzhen Yu else if (res & MT_SPM_SYSPLL)
93*fb57af70SWenzhen Yu DECLARE_HWCG_REG(VRF18, info);
94*fb57af70SWenzhen Yu else if (res & MT_SPM_INFRA)
95*fb57af70SWenzhen Yu DECLARE_HWCG_REG(INFRA, info);
96*fb57af70SWenzhen Yu else if (res & MT_SPM_PMIC)
97*fb57af70SWenzhen Yu DECLARE_HWCG_REG(PMIC, info);
98*fb57af70SWenzhen Yu else if (res & MT_SPM_26M)
99*fb57af70SWenzhen Yu DECLARE_HWCG_REG(F26M, info);
100*fb57af70SWenzhen Yu else if (res & MT_SPM_VCORE)
101*fb57af70SWenzhen Yu DECLARE_HWCG_REG(VCORE, info);
102*fb57af70SWenzhen Yu else
103*fb57af70SWenzhen Yu HWCG_INFO_INIT(info);
104*fb57af70SWenzhen Yu
105*fb57af70SWenzhen Yu if (info.pwr)
106*fb57af70SWenzhen Yu __spm_hwcg_ctrl(&info, type, is_set, val);
107*fb57af70SWenzhen Yu }
108*fb57af70SWenzhen Yu
spm_hwcg_ctrl_by_index(uint32_t idx,enum spm_hwcg_setting type,uint32_t is_set,uint32_t val)109*fb57af70SWenzhen Yu void spm_hwcg_ctrl_by_index(uint32_t idx, enum spm_hwcg_setting type,
110*fb57af70SWenzhen Yu uint32_t is_set, uint32_t val)
111*fb57af70SWenzhen Yu {
112*fb57af70SWenzhen Yu uint32_t res = spm_hwcg_index2res(idx);
113*fb57af70SWenzhen Yu
114*fb57af70SWenzhen Yu if (res)
115*fb57af70SWenzhen Yu spm_hwcg_ctrl(res, type, is_set, val);
116*fb57af70SWenzhen Yu }
117*fb57af70SWenzhen Yu
spm_hwcg_mask_get(uint32_t res,enum spm_hwcg_setting type)118*fb57af70SWenzhen Yu static uint32_t spm_hwcg_mask_get(uint32_t res, enum spm_hwcg_setting type)
119*fb57af70SWenzhen Yu {
120*fb57af70SWenzhen Yu struct spm_hwcg_info info;
121*fb57af70SWenzhen Yu uint32_t raw_val = 0, reg = 0;
122*fb57af70SWenzhen Yu
123*fb57af70SWenzhen Yu if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
124*fb57af70SWenzhen Yu DECLARE_HWCG_REG(DDREN, info);
125*fb57af70SWenzhen Yu else if (res & MT_SPM_SYSPLL)
126*fb57af70SWenzhen Yu DECLARE_HWCG_REG(VRF18, info);
127*fb57af70SWenzhen Yu else if (res & MT_SPM_INFRA)
128*fb57af70SWenzhen Yu DECLARE_HWCG_REG(INFRA, info);
129*fb57af70SWenzhen Yu else if (res & MT_SPM_PMIC)
130*fb57af70SWenzhen Yu DECLARE_HWCG_REG(PMIC, info);
131*fb57af70SWenzhen Yu else if (res & MT_SPM_26M)
132*fb57af70SWenzhen Yu DECLARE_HWCG_REG(F26M, info);
133*fb57af70SWenzhen Yu else if (res & MT_SPM_VCORE)
134*fb57af70SWenzhen Yu DECLARE_HWCG_REG(VCORE, info);
135*fb57af70SWenzhen Yu else
136*fb57af70SWenzhen Yu HWCG_INFO_INIT(info);
137*fb57af70SWenzhen Yu
138*fb57af70SWenzhen Yu if (!info.pwr)
139*fb57af70SWenzhen Yu return 0;
140*fb57af70SWenzhen Yu
141*fb57af70SWenzhen Yu reg = spm_hwcg_ctrl_get(&info, type);
142*fb57af70SWenzhen Yu
143*fb57af70SWenzhen Yu if (!reg)
144*fb57af70SWenzhen Yu return 0;
145*fb57af70SWenzhen Yu
146*fb57af70SWenzhen Yu raw_val = ~mmio_read_32(reg);
147*fb57af70SWenzhen Yu
148*fb57af70SWenzhen Yu return raw_val;
149*fb57af70SWenzhen Yu }
150*fb57af70SWenzhen Yu
spm_hwcg_get_default(uint32_t res,enum spm_hwcg_setting type)151*fb57af70SWenzhen Yu static uint32_t spm_hwcg_get_default(uint32_t res, enum spm_hwcg_setting type)
152*fb57af70SWenzhen Yu {
153*fb57af70SWenzhen Yu struct spm_hwcg_info info;
154*fb57af70SWenzhen Yu
155*fb57af70SWenzhen Yu if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI))
156*fb57af70SWenzhen Yu DECLARE_HWCG_DEFAULT(DDREN, info);
157*fb57af70SWenzhen Yu else if (res & MT_SPM_SYSPLL)
158*fb57af70SWenzhen Yu DECLARE_HWCG_DEFAULT(VRF18, info);
159*fb57af70SWenzhen Yu else if (res & MT_SPM_INFRA)
160*fb57af70SWenzhen Yu DECLARE_HWCG_DEFAULT(INFRA, info);
161*fb57af70SWenzhen Yu else if (res & MT_SPM_PMIC)
162*fb57af70SWenzhen Yu DECLARE_HWCG_DEFAULT(PMIC, info);
163*fb57af70SWenzhen Yu else if (res & MT_SPM_26M)
164*fb57af70SWenzhen Yu DECLARE_HWCG_DEFAULT(F26M, info);
165*fb57af70SWenzhen Yu else if (res & MT_SPM_VCORE)
166*fb57af70SWenzhen Yu DECLARE_HWCG_DEFAULT(VCORE, info);
167*fb57af70SWenzhen Yu else
168*fb57af70SWenzhen Yu HWCG_INFO_INIT(info);
169*fb57af70SWenzhen Yu
170*fb57af70SWenzhen Yu if (!info.pwr)
171*fb57af70SWenzhen Yu return 0;
172*fb57af70SWenzhen Yu
173*fb57af70SWenzhen Yu return spm_hwcg_ctrl_get(&info, type);
174*fb57af70SWenzhen Yu }
175*fb57af70SWenzhen Yu
spm_hwcg_get_status(uint32_t idx,enum spm_hwcg_setting type)176*fb57af70SWenzhen Yu uint32_t spm_hwcg_get_status(uint32_t idx, enum spm_hwcg_setting type)
177*fb57af70SWenzhen Yu {
178*fb57af70SWenzhen Yu uint32_t val = 0;
179*fb57af70SWenzhen Yu
180*fb57af70SWenzhen Yu switch (type) {
181*fb57af70SWenzhen Yu case HWCG_PWR:
182*fb57af70SWenzhen Yu val = mmio_read_32(PWR_STATUS);
183*fb57af70SWenzhen Yu break;
184*fb57af70SWenzhen Yu case HWCG_PWR_MSB:
185*fb57af70SWenzhen Yu val = mmio_read_32(PWR_STATUS_MSB);
186*fb57af70SWenzhen Yu break;
187*fb57af70SWenzhen Yu default:
188*fb57af70SWenzhen Yu break;
189*fb57af70SWenzhen Yu }
190*fb57af70SWenzhen Yu return val;
191*fb57af70SWenzhen Yu }
192*fb57af70SWenzhen Yu
spm_hwcg_get_setting(uint32_t res,enum spm_hwcg_sta_type sta_type,enum spm_hwcg_setting type,struct spm_hwcg_sta * sta)193*fb57af70SWenzhen Yu int spm_hwcg_get_setting(uint32_t res, enum spm_hwcg_sta_type sta_type,
194*fb57af70SWenzhen Yu enum spm_hwcg_setting type,
195*fb57af70SWenzhen Yu struct spm_hwcg_sta *sta)
196*fb57af70SWenzhen Yu {
197*fb57af70SWenzhen Yu int ret = 0;
198*fb57af70SWenzhen Yu
199*fb57af70SWenzhen Yu if (!sta)
200*fb57af70SWenzhen Yu return -1;
201*fb57af70SWenzhen Yu
202*fb57af70SWenzhen Yu switch (sta_type) {
203*fb57af70SWenzhen Yu case HWCG_STA_DEFAULT_MASK:
204*fb57af70SWenzhen Yu sta->sta = spm_hwcg_get_default(res, type);
205*fb57af70SWenzhen Yu break;
206*fb57af70SWenzhen Yu case HWCG_STA_MASK:
207*fb57af70SWenzhen Yu sta->sta = spm_hwcg_mask_get(res, type);
208*fb57af70SWenzhen Yu break;
209*fb57af70SWenzhen Yu default:
210*fb57af70SWenzhen Yu ret = -1;
211*fb57af70SWenzhen Yu MT_SPM_HW_CG_STA_INIT(sta);
212*fb57af70SWenzhen Yu break;
213*fb57af70SWenzhen Yu }
214*fb57af70SWenzhen Yu return ret;
215*fb57af70SWenzhen Yu }
216*fb57af70SWenzhen Yu
spm_hwcg_get_setting_by_index(uint32_t idx,enum spm_hwcg_sta_type sta_type,enum spm_hwcg_setting type,struct spm_hwcg_sta * sta)217*fb57af70SWenzhen Yu int spm_hwcg_get_setting_by_index(uint32_t idx,
218*fb57af70SWenzhen Yu enum spm_hwcg_sta_type sta_type,
219*fb57af70SWenzhen Yu enum spm_hwcg_setting type,
220*fb57af70SWenzhen Yu struct spm_hwcg_sta *sta)
221*fb57af70SWenzhen Yu {
222*fb57af70SWenzhen Yu uint32_t res = spm_hwcg_index2res(idx);
223*fb57af70SWenzhen Yu
224*fb57af70SWenzhen Yu return spm_hwcg_get_setting(res, sta_type, type, sta);
225*fb57af70SWenzhen Yu }
226*fb57af70SWenzhen Yu
spm_infra_swcg_init(void)227*fb57af70SWenzhen Yu static void spm_infra_swcg_init(void)
228*fb57af70SWenzhen Yu {
229*fb57af70SWenzhen Yu mmio_write_32(INFRA_SW_CG_MASK, ~INFRA_SW_CG_MB);
230*fb57af70SWenzhen Yu }
231*fb57af70SWenzhen Yu
spm_hwcg_init(void)232*fb57af70SWenzhen Yu static void spm_hwcg_init(void)
233*fb57af70SWenzhen Yu {
234*fb57af70SWenzhen Yu /* HW CG for ddren, apsrc, emi resource req */
235*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_DDREN_REQ_MASK,
236*fb57af70SWenzhen Yu ~SPM_HWCG_DDREN_PWR_MB);
237*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_MSB_DDREN_REQ_MASK,
238*fb57af70SWenzhen Yu ~SPM_HWCG_DDREN_PWR_MSB_MB);
239*fb57af70SWenzhen Yu mmio_write_32(REG_MODULE_BUSY_DDREN_REQ_MASK,
240*fb57af70SWenzhen Yu ~SPM_HWCG_DDREN_MODULE_BUSY_MB);
241*fb57af70SWenzhen Yu
242*fb57af70SWenzhen Yu /* HW CG for vrf18 resource req */
243*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_VRF18_REQ_MASK,
244*fb57af70SWenzhen Yu ~SPM_HWCG_VRF18_PWR_MB);
245*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_MSB_VRF18_REQ_MASK,
246*fb57af70SWenzhen Yu ~SPM_HWCG_VRF18_PWR_MSB_MB);
247*fb57af70SWenzhen Yu mmio_write_32(REG_MODULE_BUSY_VRF18_REQ_MASK,
248*fb57af70SWenzhen Yu ~SPM_HWCG_VRF18_MODULE_BUSY_MB);
249*fb57af70SWenzhen Yu
250*fb57af70SWenzhen Yu /* HW CG for infra resource req */
251*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_INFRA_REQ_MASK,
252*fb57af70SWenzhen Yu ~SPM_HWCG_INFRA_PWR_MB);
253*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_MSB_INFRA_REQ_MASK,
254*fb57af70SWenzhen Yu ~SPM_HWCG_INFRA_PWR_MSB_MB);
255*fb57af70SWenzhen Yu mmio_write_32(REG_MODULE_BUSY_INFRA_REQ_MASK,
256*fb57af70SWenzhen Yu ~SPM_HWCG_INFRA_MODULE_BUSY_MB);
257*fb57af70SWenzhen Yu
258*fb57af70SWenzhen Yu /* HW CG for pmic resource req */
259*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_PMIC_REQ_MASK,
260*fb57af70SWenzhen Yu ~SPM_HWCG_PMIC_PWR_MB);
261*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_MSB_PMIC_REQ_MASK,
262*fb57af70SWenzhen Yu ~SPM_HWCG_PMIC_PWR_MSB_MB);
263*fb57af70SWenzhen Yu mmio_write_32(REG_MODULE_BUSY_PMIC_REQ_MASK,
264*fb57af70SWenzhen Yu ~SPM_HWCG_PMIC_MODULE_BUSY_MB);
265*fb57af70SWenzhen Yu
266*fb57af70SWenzhen Yu /* HW CG for f26m resource req */
267*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_F26M_REQ_MASK,
268*fb57af70SWenzhen Yu ~SPM_HWCG_F26M_PWR_MB);
269*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_MSB_F26M_REQ_MASK,
270*fb57af70SWenzhen Yu ~SPM_HWCG_F26M_PWR_MSB_MB);
271*fb57af70SWenzhen Yu mmio_write_32(REG_MODULE_BUSY_F26M_REQ_MASK,
272*fb57af70SWenzhen Yu ~SPM_HWCG_F26M_MODULE_BUSY_MB);
273*fb57af70SWenzhen Yu
274*fb57af70SWenzhen Yu /* HW CG for vcore resource req */
275*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_VCORE_REQ_MASK,
276*fb57af70SWenzhen Yu ~SPM_HWCG_VCORE_PWR_MB);
277*fb57af70SWenzhen Yu mmio_write_32(REG_PWR_STATUS_MSB_VCORE_REQ_MASK,
278*fb57af70SWenzhen Yu ~SPM_HWCG_VCORE_PWR_MSB_MB);
279*fb57af70SWenzhen Yu mmio_write_32(REG_MODULE_BUSY_VCORE_REQ_MASK,
280*fb57af70SWenzhen Yu ~SPM_HWCG_VCORE_MODULE_BUSY_MB);
281*fb57af70SWenzhen Yu }
282*fb57af70SWenzhen Yu
283*fb57af70SWenzhen Yu #define PERI_CG(ofs) (PERICFG_AO_BASE + 0x10 + (0x4 * (ofs)))
284*fb57af70SWenzhen Yu #define PERI_REQ_DEFAULT_MB (BIT(PERI_REQ_EN_FLASHIF) | \
285*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_AP_DMA) | \
286*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_UART1) | \
287*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_UART2) | \
288*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_UART4) | \
289*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_UART5) | \
290*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_PWM) | \
291*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI0) | \
292*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI0_INCR16) | \
293*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI1) | \
294*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI2) | \
295*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI3) | \
296*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI4) | \
297*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI5) | \
298*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI6) | \
299*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_SPI7) | \
300*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_IMP_IIC))
301*fb57af70SWenzhen Yu
302*fb57af70SWenzhen Yu /* For MSDC reqesut WA: PERI_REQ_EN_RSV_FOR_MSDC */
303*fb57af70SWenzhen Yu #define PERI_REQ_APSRC_MB (PERI_REQ_DEFAULT_MB | \
304*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_RSV_FOR_MSDC))
305*fb57af70SWenzhen Yu
306*fb57af70SWenzhen Yu #define PERI_REQ_DDREN_MB (PERI_REQ_DEFAULT_MB | \
307*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_USB) | \
308*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_UFS0) | \
309*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_PEXTP1) | \
310*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_PEXTP0) | \
311*fb57af70SWenzhen Yu BIT(PERI_REQ_EN_PERI_BUS_TRAFFIC))
312*fb57af70SWenzhen Yu #define PERI_REQ_EMI_MB (PERI_REQ_DEFAULT_MB)
313*fb57af70SWenzhen Yu #define PERI_REQ_INFRA_MB (PERI_REQ_DEFAULT_MB)
314*fb57af70SWenzhen Yu #define PERI_REQ_SYSPLL_MB (PERI_REQ_DEFAULT_MB)
315*fb57af70SWenzhen Yu #define PERI_REQ_F26M_MB (PERI_REQ_DEFAULT_MB)
316*fb57af70SWenzhen Yu
spm_peri_req_get_status(uint32_t idx,enum spm_peri_req_status type)317*fb57af70SWenzhen Yu uint32_t spm_peri_req_get_status(uint32_t idx, enum spm_peri_req_status type)
318*fb57af70SWenzhen Yu {
319*fb57af70SWenzhen Yu uint32_t val = 0, reg = 0;
320*fb57af70SWenzhen Yu struct spm_peri_req_info info;
321*fb57af70SWenzhen Yu
322*fb57af70SWenzhen Yu switch (type) {
323*fb57af70SWenzhen Yu case PERI_RES_REQ_EN:
324*fb57af70SWenzhen Yu
325*fb57af70SWenzhen Yu switch (idx) {
326*fb57af70SWenzhen Yu case PERI_REQ_DDREN:
327*fb57af70SWenzhen Yu DECLARE_PERI_REQ_STA_REG(PERI_REQ_DDREN, info);
328*fb57af70SWenzhen Yu
329*fb57af70SWenzhen Yu break;
330*fb57af70SWenzhen Yu case PERI_REQ_EMI:
331*fb57af70SWenzhen Yu DECLARE_PERI_REQ_STA_REG(PERI_REQ_EMI, info);
332*fb57af70SWenzhen Yu
333*fb57af70SWenzhen Yu break;
334*fb57af70SWenzhen Yu case PERI_REQ_APSRC:
335*fb57af70SWenzhen Yu DECLARE_PERI_REQ_STA_REG(PERI_REQ_APSRC, info);
336*fb57af70SWenzhen Yu
337*fb57af70SWenzhen Yu break;
338*fb57af70SWenzhen Yu case PERI_REQ_SYSPLL:
339*fb57af70SWenzhen Yu DECLARE_PERI_REQ_STA_REG(PERI_REQ_SYSPLL, info);
340*fb57af70SWenzhen Yu
341*fb57af70SWenzhen Yu break;
342*fb57af70SWenzhen Yu case PERI_REQ_INFRA:
343*fb57af70SWenzhen Yu DECLARE_PERI_REQ_STA_REG(PERI_REQ_INFRA, info);
344*fb57af70SWenzhen Yu
345*fb57af70SWenzhen Yu break;
346*fb57af70SWenzhen Yu case PERI_REQ_F26M:
347*fb57af70SWenzhen Yu DECLARE_PERI_REQ_STA_REG(PERI_REQ_F26M, info);
348*fb57af70SWenzhen Yu
349*fb57af70SWenzhen Yu break;
350*fb57af70SWenzhen Yu default:
351*fb57af70SWenzhen Yu PERI_REQ_STA_INFO_INIT(info);
352*fb57af70SWenzhen Yu break;
353*fb57af70SWenzhen Yu }
354*fb57af70SWenzhen Yu
355*fb57af70SWenzhen Yu if (!info.req_sta)
356*fb57af70SWenzhen Yu return 0;
357*fb57af70SWenzhen Yu
358*fb57af70SWenzhen Yu reg = info.req_sta;
359*fb57af70SWenzhen Yu val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
360*fb57af70SWenzhen Yu
361*fb57af70SWenzhen Yu break;
362*fb57af70SWenzhen Yu default:
363*fb57af70SWenzhen Yu break;
364*fb57af70SWenzhen Yu }
365*fb57af70SWenzhen Yu return val;
366*fb57af70SWenzhen Yu }
367*fb57af70SWenzhen Yu
spm_peri_req_name(uint32_t idex,char * name,size_t sz)368*fb57af70SWenzhen Yu int spm_peri_req_name(uint32_t idex, char *name, size_t sz)
369*fb57af70SWenzhen Yu {
370*fb57af70SWenzhen Yu int ret = 0;
371*fb57af70SWenzhen Yu
372*fb57af70SWenzhen Yu if (!name)
373*fb57af70SWenzhen Yu return -1;
374*fb57af70SWenzhen Yu
375*fb57af70SWenzhen Yu switch (idex) {
376*fb57af70SWenzhen Yu case PERI_REQ_DDREN:
377*fb57af70SWenzhen Yu ret = snprintf(name, sz - 1, "ddren");
378*fb57af70SWenzhen Yu break;
379*fb57af70SWenzhen Yu case PERI_REQ_EMI:
380*fb57af70SWenzhen Yu ret = snprintf(name, sz - 1, "emi");
381*fb57af70SWenzhen Yu break;
382*fb57af70SWenzhen Yu case PERI_REQ_APSRC:
383*fb57af70SWenzhen Yu ret = snprintf(name, sz - 1, "apsrc");
384*fb57af70SWenzhen Yu break;
385*fb57af70SWenzhen Yu case PERI_REQ_SYSPLL:
386*fb57af70SWenzhen Yu ret = snprintf(name, sz - 1, "syspll");
387*fb57af70SWenzhen Yu break;
388*fb57af70SWenzhen Yu case PERI_REQ_INFRA:
389*fb57af70SWenzhen Yu ret = snprintf(name, sz - 1, "infra");
390*fb57af70SWenzhen Yu break;
391*fb57af70SWenzhen Yu case PERI_REQ_F26M:
392*fb57af70SWenzhen Yu ret = snprintf(name, sz - 1, "26m_pmic_vcore");
393*fb57af70SWenzhen Yu break;
394*fb57af70SWenzhen Yu default:
395*fb57af70SWenzhen Yu ret = -1;
396*fb57af70SWenzhen Yu break;
397*fb57af70SWenzhen Yu }
398*fb57af70SWenzhen Yu
399*fb57af70SWenzhen Yu if (ret < 0)
400*fb57af70SWenzhen Yu ret = -1;
401*fb57af70SWenzhen Yu
402*fb57af70SWenzhen Yu name[sz-1] = '\0';
403*fb57af70SWenzhen Yu
404*fb57af70SWenzhen Yu return ret;
405*fb57af70SWenzhen Yu }
406*fb57af70SWenzhen Yu
spm_peri_req_get_status_raw(enum spm_peri_req_status_raw type,uint32_t idx,char * name,size_t sz)407*fb57af70SWenzhen Yu uint32_t spm_peri_req_get_status_raw(enum spm_peri_req_status_raw type,
408*fb57af70SWenzhen Yu uint32_t idx,
409*fb57af70SWenzhen Yu char *name, size_t sz)
410*fb57af70SWenzhen Yu {
411*fb57af70SWenzhen Yu return 0;
412*fb57af70SWenzhen Yu }
413*fb57af70SWenzhen Yu
spm_peri_req_get_default(uint32_t res)414*fb57af70SWenzhen Yu static uint32_t spm_peri_req_get_default(uint32_t res)
415*fb57af70SWenzhen Yu {
416*fb57af70SWenzhen Yu struct spm_peri_req_info info;
417*fb57af70SWenzhen Yu
418*fb57af70SWenzhen Yu if (res & MT_SPM_DRAM_S1)
419*fb57af70SWenzhen Yu DECLARE_PERI_REQ_DEFAULT(DDREN, info);
420*fb57af70SWenzhen Yu else if (res & MT_SPM_EMI)
421*fb57af70SWenzhen Yu DECLARE_PERI_REQ_DEFAULT(EMI, info);
422*fb57af70SWenzhen Yu else if (res & MT_SPM_DRAM_S0)
423*fb57af70SWenzhen Yu DECLARE_PERI_REQ_DEFAULT(APSRC, info);
424*fb57af70SWenzhen Yu else if (res & MT_SPM_SYSPLL)
425*fb57af70SWenzhen Yu DECLARE_PERI_REQ_DEFAULT(SYSPLL, info);
426*fb57af70SWenzhen Yu else if (res & MT_SPM_INFRA)
427*fb57af70SWenzhen Yu DECLARE_PERI_REQ_DEFAULT(INFRA, info);
428*fb57af70SWenzhen Yu else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
429*fb57af70SWenzhen Yu DECLARE_PERI_REQ_DEFAULT(F26M, info);
430*fb57af70SWenzhen Yu else
431*fb57af70SWenzhen Yu PERI_REQ_EN_INFO_INIT(info);
432*fb57af70SWenzhen Yu
433*fb57af70SWenzhen Yu return info.req_en;
434*fb57af70SWenzhen Yu }
435*fb57af70SWenzhen Yu
spm_peri_req_mask_get(uint32_t res)436*fb57af70SWenzhen Yu static uint32_t spm_peri_req_mask_get(uint32_t res)
437*fb57af70SWenzhen Yu {
438*fb57af70SWenzhen Yu struct spm_peri_req_info info;
439*fb57af70SWenzhen Yu uint32_t raw_val = 0, reg = 0;
440*fb57af70SWenzhen Yu
441*fb57af70SWenzhen Yu if (res & MT_SPM_DRAM_S1)
442*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info);
443*fb57af70SWenzhen Yu else if (res & MT_SPM_EMI)
444*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info);
445*fb57af70SWenzhen Yu else if (res & MT_SPM_DRAM_S0)
446*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info);
447*fb57af70SWenzhen Yu else if (res & MT_SPM_SYSPLL)
448*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info);
449*fb57af70SWenzhen Yu else if (res & MT_SPM_INFRA)
450*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info);
451*fb57af70SWenzhen Yu else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
452*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info);
453*fb57af70SWenzhen Yu else
454*fb57af70SWenzhen Yu PERI_REQ_EN_INFO_INIT(info);
455*fb57af70SWenzhen Yu
456*fb57af70SWenzhen Yu if (!info.req_en)
457*fb57af70SWenzhen Yu return 0;
458*fb57af70SWenzhen Yu
459*fb57af70SWenzhen Yu reg = info.req_en;
460*fb57af70SWenzhen Yu
461*fb57af70SWenzhen Yu raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
462*fb57af70SWenzhen Yu
463*fb57af70SWenzhen Yu return raw_val;
464*fb57af70SWenzhen Yu }
465*fb57af70SWenzhen Yu
spm_peri_req_get_setting(uint32_t res,enum spm_peri_req_sta_type sta_type,struct spm_peri_req_sta * sta)466*fb57af70SWenzhen Yu int spm_peri_req_get_setting(uint32_t res,
467*fb57af70SWenzhen Yu enum spm_peri_req_sta_type sta_type,
468*fb57af70SWenzhen Yu struct spm_peri_req_sta *sta)
469*fb57af70SWenzhen Yu {
470*fb57af70SWenzhen Yu int ret = 0;
471*fb57af70SWenzhen Yu
472*fb57af70SWenzhen Yu if (!sta)
473*fb57af70SWenzhen Yu return -1;
474*fb57af70SWenzhen Yu
475*fb57af70SWenzhen Yu switch (sta_type) {
476*fb57af70SWenzhen Yu case PERI_REQ_STA_DEFAULT_MASK:
477*fb57af70SWenzhen Yu sta->sta = spm_peri_req_get_default(res);
478*fb57af70SWenzhen Yu break;
479*fb57af70SWenzhen Yu case PERI_REQ_STA_MASK:
480*fb57af70SWenzhen Yu sta->sta = spm_peri_req_mask_get(res);
481*fb57af70SWenzhen Yu break;
482*fb57af70SWenzhen Yu default:
483*fb57af70SWenzhen Yu ret = -1;
484*fb57af70SWenzhen Yu MT_SPM_HW_CG_STA_INIT(sta);
485*fb57af70SWenzhen Yu break;
486*fb57af70SWenzhen Yu }
487*fb57af70SWenzhen Yu return ret;
488*fb57af70SWenzhen Yu }
489*fb57af70SWenzhen Yu
spm_peri_req_index2res(uint32_t idx)490*fb57af70SWenzhen Yu static uint32_t spm_peri_req_index2res(uint32_t idx)
491*fb57af70SWenzhen Yu {
492*fb57af70SWenzhen Yu uint32_t res;
493*fb57af70SWenzhen Yu
494*fb57af70SWenzhen Yu if (idx >= PERI_REQ_MAX)
495*fb57af70SWenzhen Yu return 0;
496*fb57af70SWenzhen Yu
497*fb57af70SWenzhen Yu switch (idx) {
498*fb57af70SWenzhen Yu case PERI_REQ_DDREN:
499*fb57af70SWenzhen Yu res = MT_SPM_DRAM_S1;
500*fb57af70SWenzhen Yu break;
501*fb57af70SWenzhen Yu case PERI_REQ_EMI:
502*fb57af70SWenzhen Yu res = MT_SPM_EMI;
503*fb57af70SWenzhen Yu break;
504*fb57af70SWenzhen Yu case PERI_REQ_APSRC:
505*fb57af70SWenzhen Yu res = MT_SPM_DRAM_S0;
506*fb57af70SWenzhen Yu break;
507*fb57af70SWenzhen Yu case PERI_REQ_SYSPLL:
508*fb57af70SWenzhen Yu res = MT_SPM_SYSPLL;
509*fb57af70SWenzhen Yu break;
510*fb57af70SWenzhen Yu case PERI_REQ_INFRA:
511*fb57af70SWenzhen Yu res = MT_SPM_INFRA;
512*fb57af70SWenzhen Yu break;
513*fb57af70SWenzhen Yu case PERI_REQ_F26M:
514*fb57af70SWenzhen Yu res = (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE);
515*fb57af70SWenzhen Yu break;
516*fb57af70SWenzhen Yu default:
517*fb57af70SWenzhen Yu res = 0;
518*fb57af70SWenzhen Yu }
519*fb57af70SWenzhen Yu return res;
520*fb57af70SWenzhen Yu
521*fb57af70SWenzhen Yu }
522*fb57af70SWenzhen Yu
spm_peri_req_get_setting_by_index(uint32_t idx,enum spm_peri_req_sta_type sta_type,struct spm_peri_req_sta * sta)523*fb57af70SWenzhen Yu int spm_peri_req_get_setting_by_index(uint32_t idx,
524*fb57af70SWenzhen Yu enum spm_peri_req_sta_type sta_type,
525*fb57af70SWenzhen Yu struct spm_peri_req_sta *sta)
526*fb57af70SWenzhen Yu {
527*fb57af70SWenzhen Yu uint32_t res = spm_peri_req_index2res(idx);
528*fb57af70SWenzhen Yu
529*fb57af70SWenzhen Yu return spm_peri_req_get_setting(res, sta_type, sta);
530*fb57af70SWenzhen Yu }
531*fb57af70SWenzhen Yu
__spm_peri_req_ctrl(struct spm_peri_req_info * info,uint32_t is_set,uint32_t val)532*fb57af70SWenzhen Yu static void __spm_peri_req_ctrl(struct spm_peri_req_info *info,
533*fb57af70SWenzhen Yu uint32_t is_set, uint32_t val)
534*fb57af70SWenzhen Yu {
535*fb57af70SWenzhen Yu uint32_t raw_val, reg;
536*fb57af70SWenzhen Yu
537*fb57af70SWenzhen Yu reg = info->req_en;
538*fb57af70SWenzhen Yu
539*fb57af70SWenzhen Yu if (!reg)
540*fb57af70SWenzhen Yu return;
541*fb57af70SWenzhen Yu
542*fb57af70SWenzhen Yu raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK);
543*fb57af70SWenzhen Yu
544*fb57af70SWenzhen Yu if (is_set)
545*fb57af70SWenzhen Yu raw_val |= val;
546*fb57af70SWenzhen Yu else
547*fb57af70SWenzhen Yu raw_val &= ~val;
548*fb57af70SWenzhen Yu
549*fb57af70SWenzhen Yu mmio_write_32(reg, raw_val);
550*fb57af70SWenzhen Yu }
551*fb57af70SWenzhen Yu
spm_peri_req_ctrl(uint32_t res,uint32_t is_set,uint32_t val)552*fb57af70SWenzhen Yu void spm_peri_req_ctrl(uint32_t res,
553*fb57af70SWenzhen Yu uint32_t is_set, uint32_t val)
554*fb57af70SWenzhen Yu {
555*fb57af70SWenzhen Yu struct spm_peri_req_info info;
556*fb57af70SWenzhen Yu
557*fb57af70SWenzhen Yu if (res & MT_SPM_DRAM_S1)
558*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info);
559*fb57af70SWenzhen Yu else if (res & MT_SPM_EMI)
560*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info);
561*fb57af70SWenzhen Yu else if (res & MT_SPM_DRAM_S0)
562*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info);
563*fb57af70SWenzhen Yu else if (res & MT_SPM_SYSPLL)
564*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info);
565*fb57af70SWenzhen Yu else if (res & MT_SPM_INFRA)
566*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info);
567*fb57af70SWenzhen Yu else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE))
568*fb57af70SWenzhen Yu DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info);
569*fb57af70SWenzhen Yu else
570*fb57af70SWenzhen Yu PERI_REQ_EN_INFO_INIT(info);
571*fb57af70SWenzhen Yu
572*fb57af70SWenzhen Yu if (info.req_en)
573*fb57af70SWenzhen Yu __spm_peri_req_ctrl(&info, is_set, val);
574*fb57af70SWenzhen Yu }
575*fb57af70SWenzhen Yu
spm_peri_req_ctrl_by_index(uint32_t idx,uint32_t is_set,uint32_t val)576*fb57af70SWenzhen Yu void spm_peri_req_ctrl_by_index(uint32_t idx,
577*fb57af70SWenzhen Yu uint32_t is_set, uint32_t val)
578*fb57af70SWenzhen Yu {
579*fb57af70SWenzhen Yu uint32_t res = spm_peri_req_index2res(idx);
580*fb57af70SWenzhen Yu
581*fb57af70SWenzhen Yu if (res)
582*fb57af70SWenzhen Yu spm_peri_req_ctrl(res, is_set, val);
583*fb57af70SWenzhen Yu }
584*fb57af70SWenzhen Yu
spm_peri_req_init(void)585*fb57af70SWenzhen Yu static void spm_peri_req_init(void)
586*fb57af70SWenzhen Yu {
587*fb57af70SWenzhen Yu mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_DDREN), PERI_REQ_DDREN_MB);
588*fb57af70SWenzhen Yu mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_EMI), PERI_REQ_EMI_MB);
589*fb57af70SWenzhen Yu mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_APSRC), PERI_REQ_APSRC_MB);
590*fb57af70SWenzhen Yu mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_INFRA), PERI_REQ_INFRA_MB);
591*fb57af70SWenzhen Yu mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_SYSPLL), PERI_REQ_SYSPLL_MB);
592*fb57af70SWenzhen Yu mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_F26M), PERI_REQ_F26M_MB);
593*fb57af70SWenzhen Yu }
594*fb57af70SWenzhen Yu
spm_hwreq_init(void)595*fb57af70SWenzhen Yu void spm_hwreq_init(void)
596*fb57af70SWenzhen Yu {
597*fb57af70SWenzhen Yu spm_infra_swcg_init();
598*fb57af70SWenzhen Yu spm_hwcg_init();
599*fb57af70SWenzhen Yu spm_peri_req_init();
600*fb57af70SWenzhen Yu }
601