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