xref: /linux/arch/arm/mach-omap2/omap_twl.c (revision 4e95bc268b915c3a19ec8b9110f61e4ea41a1ed0)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /**
3  * OMAP and TWL PMIC specific initializations.
4  *
5  * Copyright (C) 2010 Texas Instruments Incorporated.
6  * Thara Gopinath
7  * Copyright (C) 2009 Texas Instruments Incorporated.
8  * Nishanth Menon
9  * Copyright (C) 2009 Nokia Corporation
10  * Paul Walmsley
11  */
12 
13 #include <linux/err.h>
14 #include <linux/io.h>
15 #include <linux/kernel.h>
16 #include <linux/mfd/twl.h>
17 
18 #include "soc.h"
19 #include "voltage.h"
20 
21 #include "pm.h"
22 
23 #define OMAP3_SRI2C_SLAVE_ADDR		0x12
24 #define OMAP3_VDD_MPU_SR_CONTROL_REG	0x00
25 #define OMAP3_VDD_CORE_SR_CONTROL_REG	0x01
26 #define OMAP3_VP_CONFIG_ERROROFFSET	0x00
27 #define OMAP3_VP_VSTEPMIN_VSTEPMIN	0x1
28 #define OMAP3_VP_VSTEPMAX_VSTEPMAX	0x04
29 #define OMAP3_VP_VLIMITTO_TIMEOUT_US	200
30 
31 #define OMAP4_SRI2C_SLAVE_ADDR		0x12
32 #define OMAP4_VDD_MPU_SR_VOLT_REG	0x55
33 #define OMAP4_VDD_MPU_SR_CMD_REG	0x56
34 #define OMAP4_VDD_IVA_SR_VOLT_REG	0x5B
35 #define OMAP4_VDD_IVA_SR_CMD_REG	0x5C
36 #define OMAP4_VDD_CORE_SR_VOLT_REG	0x61
37 #define OMAP4_VDD_CORE_SR_CMD_REG	0x62
38 
39 #define OMAP4_VP_CONFIG_ERROROFFSET	0x00
40 #define OMAP4_VP_VSTEPMIN_VSTEPMIN	0x01
41 #define OMAP4_VP_VSTEPMAX_VSTEPMAX	0x04
42 #define OMAP4_VP_VLIMITTO_TIMEOUT_US	200
43 
44 static bool is_offset_valid;
45 static u8 smps_offset;
46 
47 #define REG_SMPS_OFFSET         0xE0
48 
49 static unsigned long twl4030_vsel_to_uv(const u8 vsel)
50 {
51 	return (((vsel * 125) + 6000)) * 100;
52 }
53 
54 static u8 twl4030_uv_to_vsel(unsigned long uv)
55 {
56 	return DIV_ROUND_UP(uv - 600000, 12500);
57 }
58 
59 static unsigned long twl6030_vsel_to_uv(const u8 vsel)
60 {
61 	/*
62 	 * In TWL6030 depending on the value of SMPS_OFFSET
63 	 * efuse register the voltage range supported in
64 	 * standard mode can be either between 0.6V - 1.3V or
65 	 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
66 	 * is programmed to all 0's where as starting from
67 	 * TWL6030 ES1.1 the efuse is programmed to 1
68 	 */
69 	if (!is_offset_valid) {
70 		twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
71 				REG_SMPS_OFFSET);
72 		is_offset_valid = true;
73 	}
74 
75 	if (!vsel)
76 		return 0;
77 	/*
78 	 * There is no specific formula for voltage to vsel
79 	 * conversion above 1.3V. There are special hardcoded
80 	 * values for voltages above 1.3V. Currently we are
81 	 * hardcoding only for 1.35 V which is used for 1GH OPP for
82 	 * OMAP4430.
83 	 */
84 	if (vsel == 0x3A)
85 		return 1350000;
86 
87 	if (smps_offset & 0x8)
88 		return ((((vsel - 1) * 1266) + 70900)) * 10;
89 	else
90 		return ((((vsel - 1) * 1266) + 60770)) * 10;
91 }
92 
93 static u8 twl6030_uv_to_vsel(unsigned long uv)
94 {
95 	/*
96 	 * In TWL6030 depending on the value of SMPS_OFFSET
97 	 * efuse register the voltage range supported in
98 	 * standard mode can be either between 0.6V - 1.3V or
99 	 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
100 	 * is programmed to all 0's where as starting from
101 	 * TWL6030 ES1.1 the efuse is programmed to 1
102 	 */
103 	if (!is_offset_valid) {
104 		twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
105 				REG_SMPS_OFFSET);
106 		is_offset_valid = true;
107 	}
108 
109 	if (!uv)
110 		return 0x00;
111 	/*
112 	 * There is no specific formula for voltage to vsel
113 	 * conversion above 1.3V. There are special hardcoded
114 	 * values for voltages above 1.3V. Currently we are
115 	 * hardcoding only for 1.35 V which is used for 1GH OPP for
116 	 * OMAP4430.
117 	 */
118 	if (uv > twl6030_vsel_to_uv(0x39)) {
119 		if (uv == 1350000)
120 			return 0x3A;
121 		pr_err("%s:OUT OF RANGE! non mapped vsel for %ld Vs max %ld\n",
122 			__func__, uv, twl6030_vsel_to_uv(0x39));
123 		return 0x3A;
124 	}
125 
126 	if (smps_offset & 0x8)
127 		return DIV_ROUND_UP(uv - 709000, 12660) + 1;
128 	else
129 		return DIV_ROUND_UP(uv - 607700, 12660) + 1;
130 }
131 
132 static struct omap_voltdm_pmic omap3_mpu_pmic = {
133 	.slew_rate		= 4000,
134 	.step_size		= 12500,
135 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
136 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
137 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
138 	.vddmin			= 600000,
139 	.vddmax			= 1450000,
140 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
141 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
142 	.volt_reg_addr		= OMAP3_VDD_MPU_SR_CONTROL_REG,
143 	.i2c_high_speed		= true,
144 	.vsel_to_uv		= twl4030_vsel_to_uv,
145 	.uv_to_vsel		= twl4030_uv_to_vsel,
146 };
147 
148 static struct omap_voltdm_pmic omap3_core_pmic = {
149 	.slew_rate		= 4000,
150 	.step_size		= 12500,
151 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
152 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
153 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
154 	.vddmin			= 600000,
155 	.vddmax			= 1450000,
156 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
157 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
158 	.volt_reg_addr		= OMAP3_VDD_CORE_SR_CONTROL_REG,
159 	.i2c_high_speed		= true,
160 	.vsel_to_uv		= twl4030_vsel_to_uv,
161 	.uv_to_vsel		= twl4030_uv_to_vsel,
162 };
163 
164 static struct omap_voltdm_pmic omap4_mpu_pmic = {
165 	.slew_rate		= 4000,
166 	.step_size		= 12660,
167 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
168 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
169 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
170 	.vddmin			= 0,
171 	.vddmax			= 2100000,
172 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
173 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
174 	.volt_reg_addr		= OMAP4_VDD_MPU_SR_VOLT_REG,
175 	.cmd_reg_addr		= OMAP4_VDD_MPU_SR_CMD_REG,
176 	.i2c_high_speed		= true,
177 	.i2c_pad_load		= 3,
178 	.vsel_to_uv		= twl6030_vsel_to_uv,
179 	.uv_to_vsel		= twl6030_uv_to_vsel,
180 };
181 
182 static struct omap_voltdm_pmic omap4_iva_pmic = {
183 	.slew_rate		= 4000,
184 	.step_size		= 12660,
185 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
186 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
187 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
188 	.vddmin			= 0,
189 	.vddmax			= 2100000,
190 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
191 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
192 	.volt_reg_addr		= OMAP4_VDD_IVA_SR_VOLT_REG,
193 	.cmd_reg_addr		= OMAP4_VDD_IVA_SR_CMD_REG,
194 	.i2c_high_speed		= true,
195 	.i2c_pad_load		= 3,
196 	.vsel_to_uv		= twl6030_vsel_to_uv,
197 	.uv_to_vsel		= twl6030_uv_to_vsel,
198 };
199 
200 static struct omap_voltdm_pmic omap4_core_pmic = {
201 	.slew_rate		= 4000,
202 	.step_size		= 12660,
203 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
204 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
205 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
206 	.vddmin			= 0,
207 	.vddmax			= 2100000,
208 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
209 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
210 	.volt_reg_addr		= OMAP4_VDD_CORE_SR_VOLT_REG,
211 	.cmd_reg_addr		= OMAP4_VDD_CORE_SR_CMD_REG,
212 	.i2c_high_speed		= true,
213 	.i2c_pad_load		= 3,
214 	.vsel_to_uv		= twl6030_vsel_to_uv,
215 	.uv_to_vsel		= twl6030_uv_to_vsel,
216 };
217 
218 int __init omap4_twl_init(void)
219 {
220 	struct voltagedomain *voltdm;
221 
222 	if (!cpu_is_omap44xx())
223 		return -ENODEV;
224 
225 	voltdm = voltdm_lookup("mpu");
226 	omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);
227 
228 	voltdm = voltdm_lookup("iva");
229 	omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
230 
231 	voltdm = voltdm_lookup("core");
232 	omap_voltage_register_pmic(voltdm, &omap4_core_pmic);
233 
234 	return 0;
235 }
236 
237 int __init omap3_twl_init(void)
238 {
239 	struct voltagedomain *voltdm;
240 
241 	if (!cpu_is_omap34xx())
242 		return -ENODEV;
243 
244 	voltdm = voltdm_lookup("mpu_iva");
245 	omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
246 
247 	voltdm = voltdm_lookup("core");
248 	omap_voltage_register_pmic(voltdm, &omap3_core_pmic);
249 
250 	return 0;
251 }
252