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