omap_twl.c 6.7 KB

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