xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.c (revision 79c262327aa8ccc1ae5a0ee7f7ead3bf5ce8e022)
1*45d50759SJames Liao /*
2*45d50759SJames Liao  * Copyright (c) 2023, MediaTek Inc. All rights reserved.
3*45d50759SJames Liao  *
4*45d50759SJames Liao  * SPDX-License-Identifier: BSD-3-Clause
5*45d50759SJames Liao  */
6*45d50759SJames Liao 
7*45d50759SJames Liao #include <stddef.h>
8*45d50759SJames Liao #include <stdio.h>
9*45d50759SJames Liao #include <string.h>
10*45d50759SJames Liao 
11*45d50759SJames Liao #include <common/debug.h>
12*45d50759SJames Liao #include <lib/mmio.h>
13*45d50759SJames Liao #include <plat/common/platform.h>
14*45d50759SJames Liao 
15*45d50759SJames Liao #include <lib/pm/mtk_pm.h>
16*45d50759SJames Liao #include "mt_spm.h"
17*45d50759SJames Liao #include "mt_spm_internal.h"
18*45d50759SJames Liao #include "mt_spm_pmic_wrap.h"
19*45d50759SJames Liao #include "mt_spm_reg.h"
20*45d50759SJames Liao #include <platform_def.h>
21*45d50759SJames Liao 
22*45d50759SJames Liao /* BIT operation */
23*45d50759SJames Liao #define _BITS_(h, l, v) ((GENMASK(h, l) & ((v) << (l))))
24*45d50759SJames Liao 
25*45d50759SJames Liao /* PMIC_WRAP */
26*45d50759SJames Liao #define VCORE_BASE_UV			(40000) /* PMIC MT6359 */
27*45d50759SJames Liao #define VOLT_TO_PMIC_VAL(volt)		(((volt) - VCORE_BASE_UV + 625 - 1) / 625)
28*45d50759SJames Liao 
29*45d50759SJames Liao #define NR_PMIC_WRAP_CMD		(NR_IDX_ALL)
30*45d50759SJames Liao #define SPM_DATA_SHIFT			(16)
31*45d50759SJames Liao 
32*45d50759SJames Liao #define BUCK_VGPU11_ELR0		(0x15B4)
33*45d50759SJames Liao #define TOP_SPI_CON0			(0x0456)
34*45d50759SJames Liao #define BUCK_TOP_CON1			(0x1443) /* PMIC MT6315 */
35*45d50759SJames Liao #define TOP_CON				(0x0013) /* PMIC MT6315 */
36*45d50759SJames Liao #define TOP_DIG_WPK			(0x03a9)
37*45d50759SJames Liao #define TOP_CON_LOCK			(0x03a8)
38*45d50759SJames Liao #define TOP_CLK_CON0			(0x0134) /* PMIC MT6359*/
39*45d50759SJames Liao 
40*45d50759SJames Liao struct pmic_wrap_cmd {
41*45d50759SJames Liao 	uint32_t cmd_addr;
42*45d50759SJames Liao 	uint32_t cmd_wdata;
43*45d50759SJames Liao };
44*45d50759SJames Liao 
45*45d50759SJames Liao struct pmic_wrap_setting {
46*45d50759SJames Liao 	enum pmic_wrap_phase_id phase;
47*45d50759SJames Liao 	struct pmic_wrap_cmd addr[NR_PMIC_WRAP_CMD];
48*45d50759SJames Liao 	struct {
49*45d50759SJames Liao 		struct {
50*45d50759SJames Liao 			uint32_t cmd_addr;
51*45d50759SJames Liao 			uint32_t cmd_wdata;
52*45d50759SJames Liao 		} _[NR_PMIC_WRAP_CMD];
53*45d50759SJames Liao 		const int nr_idx;
54*45d50759SJames Liao 	} set[NR_PMIC_WRAP_PHASE];
55*45d50759SJames Liao };
56*45d50759SJames Liao 
57*45d50759SJames Liao static struct pmic_wrap_setting pw = {
58*45d50759SJames Liao 	.phase = NR_PMIC_WRAP_PHASE,	/* invalid setting for init */
59*45d50759SJames Liao 	.addr = {{0, 0} },
60*45d50759SJames Liao 	.set[PMIC_WRAP_PHASE_ALLINONE] = {
61*45d50759SJames Liao 		._[CMD_0]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(75000)),},
62*45d50759SJames Liao 		._[CMD_1]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(65000)),},
63*45d50759SJames Liao 		._[CMD_2]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(60000)),},
64*45d50759SJames Liao 		._[CMD_3]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(55000)),},
65*45d50759SJames Liao 		._[CMD_4]	= {TOP_SPI_CON0, _BITS_(0, 0, 1),},
66*45d50759SJames Liao 		._[CMD_5]	= {TOP_SPI_CON0, _BITS_(0, 0, 0),},
67*45d50759SJames Liao 		._[CMD_6]	= {BUCK_TOP_CON1, 0x0,},	/* MT6315-3: VMD NO LP */
68*45d50759SJames Liao 		._[CMD_7]	= {BUCK_TOP_CON1, 0xF,},	/* MT6315-3: VMD LP */
69*45d50759SJames Liao 		._[CMD_8]	= {TOP_CON, 0x3,},		/* MT6315-3: PMIC NO LP */
70*45d50759SJames Liao 		._[CMD_9]	= {TOP_CON, 0x0,},		/* MT6315-3: PMIC LP */
71*45d50759SJames Liao 		._[CMD_10]	= {TOP_DIG_WPK, 0x63,},		/* MT6315-2: PMIC_CON_DIG_WPK */
72*45d50759SJames Liao 		._[CMD_11]	= {TOP_CON_LOCK, 0x15,},	/* MT6315-2: PMIC_CON_UNLOCK */
73*45d50759SJames Liao 		._[CMD_12]	= {TOP_DIG_WPK, 0x0,},		/* MT6315-2: PMIC_CON_DIG_WPK */
74*45d50759SJames Liao 		._[CMD_13]	= {TOP_CON_LOCK, 0x0,},		/* MT6315-2: PMIC_CON_LOCK */
75*45d50759SJames Liao 		._[CMD_14]	= {TOP_CLK_CON0, 0x0040,},	/* MT6359: 6359_LDO_SW_SEL_H */
76*45d50759SJames Liao 		._[CMD_15]	= {TOP_CLK_CON0, 0x0000,},	/* MT6359: 6359_LDO_SW_SEL_L */
77*45d50759SJames Liao 		.nr_idx = NR_IDX_ALL,
78*45d50759SJames Liao 	},
79*45d50759SJames Liao };
80*45d50759SJames Liao 
_mt_spm_pmic_table_init(void)81*45d50759SJames Liao void _mt_spm_pmic_table_init(void)
82*45d50759SJames Liao {
83*45d50759SJames Liao 	struct pmic_wrap_cmd pwrap_cmd_default[NR_PMIC_WRAP_CMD] = {
84*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD0, (uint32_t)SPM_DVFS_CMD0, },
85*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD1, (uint32_t)SPM_DVFS_CMD1, },
86*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD2, (uint32_t)SPM_DVFS_CMD2, },
87*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD3, (uint32_t)SPM_DVFS_CMD3, },
88*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD4, (uint32_t)SPM_DVFS_CMD4, },
89*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD5, (uint32_t)SPM_DVFS_CMD5, },
90*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD6, (uint32_t)SPM_DVFS_CMD6, },
91*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD7, (uint32_t)SPM_DVFS_CMD7, },
92*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD8, (uint32_t)SPM_DVFS_CMD8, },
93*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD9, (uint32_t)SPM_DVFS_CMD9, },
94*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD10, (uint32_t)SPM_DVFS_CMD10, },
95*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD11, (uint32_t)SPM_DVFS_CMD11, },
96*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD12, (uint32_t)SPM_DVFS_CMD12, },
97*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD13, (uint32_t)SPM_DVFS_CMD13, },
98*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD14, (uint32_t)SPM_DVFS_CMD14, },
99*45d50759SJames Liao 		{ (uint32_t)SPM_DVFS_CMD15, (uint32_t)SPM_DVFS_CMD15, },
100*45d50759SJames Liao 	};
101*45d50759SJames Liao 
102*45d50759SJames Liao 	memcpy(pw.addr, pwrap_cmd_default, sizeof(pwrap_cmd_default));
103*45d50759SJames Liao }
104*45d50759SJames Liao 
mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase)105*45d50759SJames Liao void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase)
106*45d50759SJames Liao {
107*45d50759SJames Liao 	int idx;
108*45d50759SJames Liao 
109*45d50759SJames Liao 	if ((phase >= NR_PMIC_WRAP_PHASE) || (pw.phase == phase)) {
110*45d50759SJames Liao 		return;
111*45d50759SJames Liao 	}
112*45d50759SJames Liao 
113*45d50759SJames Liao 	if (pw.addr[0].cmd_addr == 0) {
114*45d50759SJames Liao 		_mt_spm_pmic_table_init();
115*45d50759SJames Liao 	}
116*45d50759SJames Liao 
117*45d50759SJames Liao 	pw.phase = phase;
118*45d50759SJames Liao 
119*45d50759SJames Liao 	mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB);
120*45d50759SJames Liao 	for (idx = 0; idx < pw.set[phase].nr_idx; idx++) {
121*45d50759SJames Liao 		mmio_write_32(pw.addr[idx].cmd_addr,
122*45d50759SJames Liao 			      (pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT) |
123*45d50759SJames Liao 			      (pw.set[phase]._[idx].cmd_wdata));
124*45d50759SJames Liao 	}
125*45d50759SJames Liao }
126*45d50759SJames Liao 
mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase,unsigned int idx,unsigned int cmd_wdata)127*45d50759SJames Liao void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, unsigned int idx,
128*45d50759SJames Liao 			      unsigned int cmd_wdata)
129*45d50759SJames Liao {
130*45d50759SJames Liao 	/* just set wdata value */
131*45d50759SJames Liao 	if ((phase >= NR_PMIC_WRAP_PHASE) || (idx >= pw.set[phase].nr_idx)) {
132*45d50759SJames Liao 		return;
133*45d50759SJames Liao 	}
134*45d50759SJames Liao 
135*45d50759SJames Liao 	pw.set[phase]._[idx].cmd_wdata = cmd_wdata;
136*45d50759SJames Liao 
137*45d50759SJames Liao 	mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB);
138*45d50759SJames Liao 	if (pw.phase == phase) {
139*45d50759SJames Liao 		mmio_write_32(pw.addr[idx].cmd_addr,
140*45d50759SJames Liao 			      (pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT) | cmd_wdata);
141*45d50759SJames Liao 	}
142*45d50759SJames Liao }
143*45d50759SJames Liao 
mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase,unsigned int idx)144*45d50759SJames Liao uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, unsigned int idx)
145*45d50759SJames Liao {
146*45d50759SJames Liao 	/* just get wdata value */
147*45d50759SJames Liao 	if ((phase >= NR_PMIC_WRAP_PHASE) || (idx >= pw.set[phase].nr_idx)) {
148*45d50759SJames Liao 		return 0;
149*45d50759SJames Liao 	}
150*45d50759SJames Liao 
151*45d50759SJames Liao 	return pw.set[phase]._[idx].cmd_wdata;
152*45d50759SJames Liao }
153