msm_gfx_ldo.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674
  1. /*
  2. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #define pr_fmt(fmt) "GFX_LDO: %s: " fmt, __func__
  14. #include <linux/bitops.h>
  15. #include <linux/debugfs.h>
  16. #include <linux/delay.h>
  17. #include <linux/io.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/of.h>
  21. #include <linux/of_device.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/regulator/driver.h>
  24. #include <linux/regulator/machine.h>
  25. #include <linux/regulator/of_regulator.h>
  26. #include <linux/slab.h>
  27. #include <linux/uaccess.h>
  28. #include <linux/regulator/msm-ldo-regulator.h>
  29. #define LDO_ATEST_REG 0x0
  30. #define LDO_CFG0_REG 0x4
  31. #define LDO_CFG1_REG 0x8
  32. #define LDO_CFG2_REG 0xC
  33. #define LDO_LD_DATA_REG 0x10
  34. #define LDO_VREF_TEST_CFG 0x14
  35. #define ENABLE_LDO_STATUS_BIT (BIT(8) | BIT(12))
  36. #define LDO_AUTOBYPASS_BIT BIT(20)
  37. #define LDO_VREF_SET_REG 0x18
  38. #define UPDATE_VREF_BIT BIT(31)
  39. #define SEL_RST_BIT BIT(16)
  40. #define VREF_VAL_MASK GENMASK(6, 0)
  41. #define PWRSWITCH_CTRL_REG 0x1C
  42. #define LDO_CLAMP_IO_BIT BIT(31)
  43. #define CPR_BYPASS_IN_LDO_MODE_BIT BIT(30)
  44. #define EN_LDOAP_CTRL_CPR_BIT BIT(29)
  45. #define CX_CPR_BYPASS_IN_LDO_MODE_BIT BIT(10)
  46. #define PWR_SRC_SEL_BIT BIT(9)
  47. #define ACK_SW_OVR_BIT BIT(8)
  48. #define LDO_PREON_SW_OVR_BIT BIT(7)
  49. #define LDO_BYPASS_BIT BIT(6)
  50. #define LDO_PDN_BIT BIT(5)
  51. #define LDO_UNDER_SW_CTRL_BIT BIT(4)
  52. #define BHS_EN_REST_BIT BIT(2)
  53. #define BHS_EN_FEW_BIT BIT(1)
  54. #define BHS_UNDER_SW_CTL BIT(0)
  55. #define LDO_STATUS1_REG 0x24
  56. #define PWRSWITCH_STATUS_REG 0x28
  57. #define LDO_VREF_SETTLED_BIT BIT(4)
  58. #define LDO_READY_BIT BIT(2)
  59. #define BHS_EN_REST_ACK_BIT BIT(1)
  60. #define REF_CURRENT_X1_REG 0x2C
  61. #define REF_CURRENT_X2_REG 0x30
  62. #define ADC_CTL_REG 0x34
  63. #define MIN_LDO_VOLTAGE 375000
  64. #define MAX_LDO_VOLTAGE 980000
  65. #define LDO_STEP_VOLATGE 5000
  66. #define MAX_LDO_REGS 11
  67. #define BYTES_PER_FUSE_ROW 8
  68. #define MAX_FUSE_ROW_BIT 63
  69. #define MIN_CORNER_OFFSET 1
  70. #define GFX_LDO_FUSE_STEP_VOLT 10000
  71. #define GFX_LDO_FUSE_SIZE 5
  72. enum direction {
  73. NO_CHANGE,
  74. UP,
  75. DOWN,
  76. };
  77. enum voltage_handling {
  78. VOLTAGE,
  79. CORNER,
  80. };
  81. struct fuse_param {
  82. unsigned int row;
  83. unsigned int bit_start;
  84. unsigned int bit_end;
  85. };
  86. struct ldo_config {
  87. u32 offset;
  88. u32 value;
  89. };
  90. struct msm_gfx_ldo {
  91. struct device *dev;
  92. struct regulator_desc rdesc;
  93. struct regulator_dev *rdev;
  94. struct regulator *vdd_cx;
  95. struct regulator *mem_acc_vreg;
  96. struct dentry *debugfs;
  97. u32 num_corners;
  98. u32 num_ldo_corners;
  99. u32 *open_loop_volt;
  100. u32 *ceiling_volt;
  101. u32 *floor_volt;
  102. u32 *ldo_corner_en_map;
  103. u32 *vdd_cx_corner_map;
  104. u32 *mem_acc_corner_map;
  105. const int *ref_volt;
  106. const struct fuse_param *ldo_enable_param;
  107. const struct fuse_param **init_volt_param;
  108. bool ldo_fuse_enable;
  109. bool ldo_mode_disable;
  110. struct ldo_config *ldo_init_config;
  111. void __iomem *efuse_base;
  112. phys_addr_t efuse_addr;
  113. void __iomem *ldo_base;
  114. phys_addr_t ldo_addr;
  115. bool vreg_enabled;
  116. enum msm_ldo_supply_mode mode;
  117. u32 corner;
  118. int ldo_voltage_uv;
  119. struct mutex ldo_mutex;
  120. enum voltage_handling ops_type;
  121. };
  122. #define MSM8953_LDO_FUSE_CORNERS 3
  123. #define LDO_MAX_OFFSET 0xFFFF
  124. static struct ldo_config msm8953_ldo_config[] = {
  125. {LDO_ATEST_REG, 0x00000203},
  126. {LDO_CFG0_REG, 0x05008600},
  127. {LDO_CFG1_REG, 0x0},
  128. {LDO_CFG2_REG, 0x0000C3FC},
  129. {LDO_VREF_TEST_CFG, 0x004B1102},
  130. {LDO_MAX_OFFSET, LDO_MAX_OFFSET},
  131. };
  132. static struct ldo_config sdm660_ldo_config[] = {
  133. {LDO_ATEST_REG, 0x00000080},
  134. {LDO_CFG0_REG, 0x0100A600},
  135. {LDO_CFG1_REG, 0x000000A0},
  136. {LDO_CFG2_REG, 0x0000C3FE},
  137. {LDO_LD_DATA_REG, 0x00000000},
  138. {LDO_VREF_TEST_CFG, 0x00401100},
  139. {REF_CURRENT_X1_REG, 0x00000230},
  140. {REF_CURRENT_X2_REG, 0x00000048},
  141. {ADC_CTL_REG, 0x00000000},
  142. {LDO_MAX_OFFSET, LDO_MAX_OFFSET},
  143. };
  144. static struct fuse_param msm8953_ldo_enable_param[] = {
  145. {65, 11, 11},
  146. {},
  147. };
  148. static const struct fuse_param
  149. msm8953_init_voltage_param[MSM8953_LDO_FUSE_CORNERS][2] = {
  150. { {73, 42, 46}, {} },
  151. { {73, 37, 41}, {} },
  152. { {73, 32, 36}, {} },
  153. };
  154. static const int msm8953_fuse_ref_volt[MSM8953_LDO_FUSE_CORNERS] = {
  155. 580000,
  156. 650000,
  157. 720000,
  158. };
  159. enum {
  160. MSM8953_SOC_ID,
  161. SDM660_SOC_ID,
  162. };
  163. static int convert_open_loop_voltage_fuse(int ref_volt, int step_volt,
  164. u32 fuse, int fuse_len)
  165. {
  166. int sign, steps;
  167. sign = (fuse & (1 << (fuse_len - 1))) ? -1 : 1;
  168. steps = fuse & ((1 << (fuse_len - 1)) - 1);
  169. return ref_volt + sign * steps * step_volt;
  170. }
  171. static int read_fuse_param(void __iomem *fuse_base_addr,
  172. const struct fuse_param *param, u64 *param_value)
  173. {
  174. u64 fuse_val, val;
  175. int bits;
  176. int bits_total = 0;
  177. *param_value = 0;
  178. while (param->row || param->bit_start || param->bit_end) {
  179. if (param->bit_start > param->bit_end
  180. || param->bit_end > MAX_FUSE_ROW_BIT) {
  181. pr_err("Invalid fuse parameter segment: row=%u, start=%u, end=%u\n",
  182. param->row, param->bit_start, param->bit_end);
  183. return -EINVAL;
  184. }
  185. bits = param->bit_end - param->bit_start + 1;
  186. if (bits_total + bits > 64) {
  187. pr_err("Invalid fuse parameter segments; total bits = %d\n",
  188. bits_total + bits);
  189. return -EINVAL;
  190. }
  191. fuse_val = readq_relaxed(fuse_base_addr
  192. + param->row * BYTES_PER_FUSE_ROW);
  193. val = (fuse_val >> param->bit_start) & ((1ULL << bits) - 1);
  194. *param_value |= val << bits_total;
  195. bits_total += bits;
  196. param++;
  197. }
  198. return 0;
  199. }
  200. static enum msm_ldo_supply_mode get_operating_mode(struct msm_gfx_ldo *ldo_vreg,
  201. int corner)
  202. {
  203. if (!ldo_vreg->ldo_mode_disable && ldo_vreg->ldo_fuse_enable
  204. && ldo_vreg->ldo_corner_en_map[corner])
  205. return LDO_MODE;
  206. return BHS_MODE;
  207. }
  208. static char *register_str[] = {
  209. "LDO_ATEST",
  210. "LDO_CFG0",
  211. "LDO_CFG1",
  212. "LDO_CFG2",
  213. "LDO_LD_DATA",
  214. "LDO_VREF_TEST_CFG",
  215. "LDO_VREF_SET",
  216. "PWRSWITCH_CTL",
  217. "LDO_STATUS0",
  218. "LDO_STATUS1",
  219. "PWRSWITCH_STATUS",
  220. };
  221. static void dump_registers(struct msm_gfx_ldo *ldo_vreg, char *func)
  222. {
  223. u32 reg[MAX_LDO_REGS];
  224. int i;
  225. for (i = 0; i < MAX_LDO_REGS; i++) {
  226. reg[i] = 0;
  227. reg[i] = readl_relaxed(ldo_vreg->ldo_base + (i * 4));
  228. pr_debug("%s -- %s = 0x%x\n", func, register_str[i], reg[i]);
  229. }
  230. }
  231. #define GET_VREF(a) DIV_ROUND_UP(a - MIN_LDO_VOLTAGE, LDO_STEP_VOLATGE)
  232. static void configure_ldo_voltage(struct msm_gfx_ldo *ldo_vreg, int new_uv)
  233. {
  234. int val = 0;
  235. u32 reg = 0;
  236. val = GET_VREF(new_uv);
  237. reg = readl_relaxed(ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  238. /* set the new voltage */
  239. reg &= ~VREF_VAL_MASK;
  240. reg |= val & VREF_VAL_MASK;
  241. writel_relaxed(reg, ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  242. /* Initiate VREF update */
  243. reg |= UPDATE_VREF_BIT;
  244. writel_relaxed(reg, ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  245. /* complete the writes */
  246. mb();
  247. reg &= ~UPDATE_VREF_BIT;
  248. writel_relaxed(reg, ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  249. ldo_vreg->ldo_voltage_uv = new_uv;
  250. /* complete the write sequence */
  251. mb();
  252. }
  253. static int ldo_update_voltage(struct msm_gfx_ldo *ldo_vreg, int new_uv)
  254. {
  255. int timeout = 50;
  256. u32 reg = 0;
  257. configure_ldo_voltage(ldo_vreg, new_uv);
  258. while (--timeout) {
  259. reg = readl_relaxed(ldo_vreg->ldo_base +
  260. PWRSWITCH_STATUS_REG);
  261. if (reg & (LDO_VREF_SETTLED_BIT | LDO_READY_BIT))
  262. break;
  263. udelay(10);
  264. }
  265. if (!timeout) {
  266. pr_err("LDO_VREF_SETTLED not set PWRSWITCH_STATUS = 0x%x\n",
  267. reg);
  268. return -EBUSY;
  269. }
  270. pr_debug("LDO voltage set to=%d uV VREF_REG=%x\n",
  271. ldo_vreg->ldo_voltage_uv,
  272. readl_relaxed(ldo_vreg->ldo_base + LDO_VREF_SET_REG));
  273. return 0;
  274. }
  275. static int enable_ldo_mode(struct msm_gfx_ldo *ldo_vreg, int new_uv)
  276. {
  277. u32 ctl = 0;
  278. /* set the ldo-vref */
  279. configure_ldo_voltage(ldo_vreg, new_uv);
  280. /* configure the LDO for power-up */
  281. ctl = readl_relaxed(ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  282. /* Move BHS under SW control */
  283. ctl |= BHS_UNDER_SW_CTL;
  284. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  285. /* Set LDO under gdsc control */
  286. ctl &= ~LDO_UNDER_SW_CTRL_BIT;
  287. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  288. /* enable hw_pre-on to gdsc */
  289. ctl |= LDO_PREON_SW_OVR_BIT;
  290. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  291. /* remove LDO bypass */
  292. ctl &= ~LDO_BYPASS_BIT;
  293. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  294. /* set power-source as LDO */
  295. ctl |= PWR_SRC_SEL_BIT;
  296. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  297. /* clear fake-sw ack to gdsc */
  298. ctl &= ~ACK_SW_OVR_BIT;
  299. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  300. /* put CPR in bypass mode */
  301. if (ldo_vreg->ops_type == CORNER) {
  302. ctl |= CPR_BYPASS_IN_LDO_MODE_BIT;
  303. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  304. }
  305. /* complete all writes */
  306. mb();
  307. dump_registers(ldo_vreg, "enable_ldo_mode");
  308. return 0;
  309. }
  310. static int enable_bhs_mode(struct msm_gfx_ldo *ldo_vreg)
  311. {
  312. u32 ctl = 0;
  313. ctl = readl_relaxed(ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  314. /* Put LDO under SW control */
  315. ctl |= LDO_UNDER_SW_CTRL_BIT;
  316. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  317. /* set power-source as BHS */
  318. ctl &= ~PWR_SRC_SEL_BIT;
  319. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  320. if (ldo_vreg->ops_type == CORNER) {
  321. /* clear GFX CPR in by-pass mode */
  322. ctl &= ~CPR_BYPASS_IN_LDO_MODE_BIT;
  323. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  324. }
  325. /* Enable the BHS control signals to gdsc */
  326. ctl &= ~BHS_EN_FEW_BIT;
  327. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  328. ctl &= ~BHS_EN_REST_BIT;
  329. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  330. /* Put BHS under GDSC control */
  331. ctl &= ~BHS_UNDER_SW_CTL;
  332. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  333. dump_registers(ldo_vreg, "enable_bhs_mode");
  334. return 0;
  335. }
  336. static int msm_gfx_ldo_corner_enable(struct regulator_dev *rdev)
  337. {
  338. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  339. int rc = 0, new_uv;
  340. enum msm_ldo_supply_mode enable_mode;
  341. mutex_lock(&ldo_vreg->ldo_mutex);
  342. pr_debug("regulator_enable requested. corner=%d\n",
  343. ldo_vreg->corner + MIN_CORNER_OFFSET);
  344. if (ldo_vreg->vdd_cx) {
  345. rc = regulator_set_voltage(ldo_vreg->vdd_cx,
  346. ldo_vreg->vdd_cx_corner_map[ldo_vreg->corner],
  347. INT_MAX);
  348. if (rc) {
  349. pr_err("Unable to set CX for corner %d rc=%d\n",
  350. ldo_vreg->corner + MIN_CORNER_OFFSET, rc);
  351. goto fail;
  352. }
  353. rc = regulator_enable(ldo_vreg->vdd_cx);
  354. if (rc) {
  355. pr_err("regulator_enable: vdd_cx: failed rc=%d\n", rc);
  356. goto fail;
  357. }
  358. }
  359. enable_mode = get_operating_mode(ldo_vreg, ldo_vreg->corner);
  360. if (enable_mode == LDO_MODE) {
  361. new_uv = ldo_vreg->open_loop_volt[ldo_vreg->corner];
  362. rc = enable_ldo_mode(ldo_vreg, new_uv);
  363. pr_debug("LDO voltage configured =%d uV corner=%d\n",
  364. ldo_vreg->ldo_voltage_uv,
  365. ldo_vreg->corner + MIN_CORNER_OFFSET);
  366. } else {
  367. rc = enable_bhs_mode(ldo_vreg);
  368. }
  369. if (rc) {
  370. pr_err("Failed to enable regulator in %s mode rc=%d\n",
  371. (enable_mode == LDO_MODE) ? "LDO" : "BHS", rc);
  372. goto disable_cx;
  373. }
  374. pr_debug("regulator_enable complete. mode=%s, corner=%d\n",
  375. (enable_mode == LDO_MODE) ? "LDO" : "BHS",
  376. ldo_vreg->corner + MIN_CORNER_OFFSET);
  377. ldo_vreg->mode = enable_mode;
  378. ldo_vreg->vreg_enabled = true;
  379. disable_cx:
  380. if (rc && ldo_vreg->vdd_cx) {
  381. rc = regulator_disable(ldo_vreg->vdd_cx);
  382. if (rc)
  383. pr_err("regulator_enable: vdd_cx: failed rc=%d\n", rc);
  384. }
  385. fail:
  386. mutex_unlock(&ldo_vreg->ldo_mutex);
  387. return rc;
  388. }
  389. static int msm_gfx_ldo_disable(struct regulator_dev *rdev)
  390. {
  391. int rc = 0;
  392. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  393. mutex_lock(&ldo_vreg->ldo_mutex);
  394. if (ldo_vreg->vdd_cx) {
  395. rc = regulator_disable(ldo_vreg->vdd_cx);
  396. if (rc) {
  397. pr_err("regulator_disable: vdd_cx: failed rc=%d\n", rc);
  398. goto done;
  399. }
  400. rc = regulator_set_voltage(ldo_vreg->vdd_cx, 0, INT_MAX);
  401. if (rc)
  402. pr_err("failed to set voltage on CX rc=%d\n", rc);
  403. }
  404. /* No additional configuration for LDO/BHS - taken care by gsdc */
  405. ldo_vreg->vreg_enabled = false;
  406. pr_debug("regulator_disabled complete\n");
  407. done:
  408. mutex_unlock(&ldo_vreg->ldo_mutex);
  409. return rc;
  410. }
  411. static int switch_mode_to_ldo(struct msm_gfx_ldo *ldo_vreg, int new_uv)
  412. {
  413. u32 ctl = 0, status = 0, timeout = 50;
  414. ctl = readl_relaxed(ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  415. if (ldo_vreg->ops_type == CORNER) {
  416. /* enable CPR bypass mode for LDO */
  417. ctl |= CPR_BYPASS_IN_LDO_MODE_BIT;
  418. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  419. }
  420. /* fake ack to GDSC */
  421. ctl |= ACK_SW_OVR_BIT;
  422. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  423. /* set power-source as LDO */
  424. ctl |= PWR_SRC_SEL_BIT;
  425. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  426. /* Make sure BHS continues to power the rail */
  427. ctl |= BHS_EN_FEW_BIT;
  428. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  429. ctl |= BHS_EN_REST_BIT;
  430. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  431. /* move BHS to SW control */
  432. ctl |= BHS_UNDER_SW_CTL;
  433. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  434. /* set LDO under SW control */
  435. ctl |= LDO_UNDER_SW_CTRL_BIT;
  436. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  437. /* bypass LDO */
  438. ctl |= LDO_BYPASS_BIT;
  439. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  440. /* power-on LDO */
  441. ctl &= ~LDO_PDN_BIT;
  442. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  443. /* set the new LDO voltage */
  444. ldo_update_voltage(ldo_vreg, new_uv);
  445. pr_debug("LDO voltage =%d uV\n", ldo_vreg->ldo_voltage_uv);
  446. /* make sure that the configuration is complete */
  447. mb();
  448. /* power down BHS */
  449. ctl &= ~BHS_EN_FEW_BIT;
  450. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  451. ctl &= ~BHS_EN_REST_BIT;
  452. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  453. /* make sure that the configuration is complete */
  454. mb();
  455. /* wait for BHS to turn-off */
  456. while (--timeout) {
  457. status = readl_relaxed(ldo_vreg->ldo_base +
  458. PWRSWITCH_STATUS_REG);
  459. if (!(status & BHS_EN_REST_ACK_BIT))
  460. break;
  461. udelay(10);
  462. }
  463. if (!timeout)
  464. pr_err("BHS_EN_RESET_ACK not clear PWRSWITCH_STATUS = 0x%x\n",
  465. status);
  466. /* remove LDO bypass */
  467. ctl &= ~LDO_BYPASS_BIT;
  468. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  469. /* expose LDO to gdsc */
  470. ctl &= ~ACK_SW_OVR_BIT;
  471. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  472. ctl &= ~LDO_UNDER_SW_CTRL_BIT;
  473. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  474. dump_registers(ldo_vreg, "switch_mode_to_ldo");
  475. return 0;
  476. }
  477. static int switch_mode_to_bhs(struct msm_gfx_ldo *ldo_vreg)
  478. {
  479. u32 ctl = 0, status = 0, timeout = 50;
  480. ctl = readl_relaxed(ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  481. /* fake ack to gdsc */
  482. ctl |= ACK_SW_OVR_BIT;
  483. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  484. /* select BHS as power source */
  485. ctl &= ~PWR_SRC_SEL_BIT;
  486. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  487. /* LDO stays ON */
  488. ctl &= ~LDO_PDN_BIT;
  489. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  490. /* Move LDO to SW control */
  491. ctl |= LDO_UNDER_SW_CTRL_BIT;
  492. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  493. /* Power-up BHS */
  494. ctl |= BHS_EN_FEW_BIT;
  495. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  496. ctl |= BHS_EN_REST_BIT;
  497. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  498. /* make sure that the configuration is complete */
  499. mb();
  500. /* wait for BHS to power-up */
  501. while (--timeout) {
  502. status = readl_relaxed(ldo_vreg->ldo_base +
  503. PWRSWITCH_STATUS_REG);
  504. if (status & BHS_EN_REST_ACK_BIT)
  505. break;
  506. udelay(10);
  507. }
  508. if (!timeout)
  509. pr_err("BHS_EN_RESET_ACK not set PWRSWITCH_STATUS = 0x%x\n",
  510. status);
  511. /* bypass LDO */
  512. ctl |= LDO_BYPASS_BIT;
  513. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  514. /* pull-down LDO */
  515. ctl |= LDO_PDN_BIT;
  516. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  517. /* Expose BHS to gdsc */
  518. ctl &= ~ACK_SW_OVR_BIT;
  519. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  520. ctl &= ~BHS_UNDER_SW_CTL;
  521. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  522. if (ldo_vreg->ops_type == CORNER) {
  523. /* Enable CPR in BHS mode */
  524. ctl &= ~CPR_BYPASS_IN_LDO_MODE_BIT;
  525. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  526. }
  527. /* make sure that all configuration is complete */
  528. mb();
  529. dump_registers(ldo_vreg, "switch_mode_to_bhs");
  530. return 0;
  531. }
  532. static int msm_gfx_ldo_set_corner(struct regulator_dev *rdev,
  533. int corner, int corner_max, unsigned int *selector)
  534. {
  535. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  536. int rc = 0, mem_acc_corner, new_uv;
  537. enum msm_ldo_supply_mode new_mode;
  538. enum direction dir = NO_CHANGE;
  539. corner -= MIN_CORNER_OFFSET;
  540. corner_max -= MIN_CORNER_OFFSET;
  541. mutex_lock(&ldo_vreg->ldo_mutex);
  542. if (corner == ldo_vreg->corner)
  543. goto done;
  544. pr_debug("set-voltage requested: old_mode=%s old_corner=%d new_corner=%d vreg_enabled=%d\n",
  545. ldo_vreg->mode == BHS_MODE ? "BHS" : "LDO",
  546. ldo_vreg->corner + MIN_CORNER_OFFSET,
  547. corner + MIN_CORNER_OFFSET,
  548. ldo_vreg->vreg_enabled);
  549. if (corner > ldo_vreg->corner)
  550. dir = UP;
  551. else if (corner < ldo_vreg->corner)
  552. dir = DOWN;
  553. if (ldo_vreg->mem_acc_vreg && dir == DOWN) {
  554. mem_acc_corner = ldo_vreg->mem_acc_corner_map[corner];
  555. rc = regulator_set_voltage(ldo_vreg->mem_acc_vreg,
  556. mem_acc_corner, mem_acc_corner);
  557. }
  558. if (!ldo_vreg->vreg_enabled) {
  559. ldo_vreg->corner = corner;
  560. goto done;
  561. }
  562. if (ldo_vreg->vdd_cx) {
  563. rc = regulator_set_voltage(ldo_vreg->vdd_cx,
  564. ldo_vreg->vdd_cx_corner_map[corner],
  565. INT_MAX);
  566. if (rc) {
  567. pr_err("Unable to set CX for corner %d rc=%d\n",
  568. corner + MIN_CORNER_OFFSET, rc);
  569. goto done;
  570. }
  571. }
  572. new_mode = get_operating_mode(ldo_vreg, corner);
  573. if (new_mode == BHS_MODE) {
  574. if (ldo_vreg->mode == LDO_MODE) {
  575. rc = switch_mode_to_bhs(ldo_vreg);
  576. if (rc)
  577. pr_err("Switch to BHS corner=%d failed rc=%d\n",
  578. corner + MIN_CORNER_OFFSET, rc);
  579. }
  580. } else { /* new mode - LDO */
  581. new_uv = ldo_vreg->open_loop_volt[ldo_vreg->corner];
  582. if (ldo_vreg->mode == BHS_MODE) {
  583. rc = switch_mode_to_ldo(ldo_vreg, new_uv);
  584. if (rc)
  585. pr_err("Switch to LDO failed corner=%d rc=%d\n",
  586. corner + MIN_CORNER_OFFSET, rc);
  587. } else {
  588. rc = ldo_update_voltage(ldo_vreg, new_uv);
  589. if (rc)
  590. pr_err("Update voltage failed corner=%d rc=%d\n",
  591. corner + MIN_CORNER_OFFSET, rc);
  592. }
  593. }
  594. if (!rc) {
  595. pr_debug("set-voltage complete. old_mode=%s new_mode=%s old_corner=%d new_corner=%d\n",
  596. ldo_vreg->mode == BHS_MODE ? "BHS" : "LDO",
  597. new_mode == BHS_MODE ? "BHS" : "LDO",
  598. ldo_vreg->corner + MIN_CORNER_OFFSET,
  599. corner + MIN_CORNER_OFFSET);
  600. ldo_vreg->mode = new_mode;
  601. ldo_vreg->corner = corner;
  602. }
  603. done:
  604. if (!rc && ldo_vreg->mem_acc_vreg && dir == UP) {
  605. mem_acc_corner = ldo_vreg->mem_acc_corner_map[corner];
  606. rc = regulator_set_voltage(ldo_vreg->mem_acc_vreg,
  607. mem_acc_corner, mem_acc_corner);
  608. }
  609. mutex_unlock(&ldo_vreg->ldo_mutex);
  610. return rc;
  611. }
  612. static int msm_gfx_ldo_get_corner(struct regulator_dev *rdev)
  613. {
  614. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  615. return ldo_vreg->corner + MIN_CORNER_OFFSET;
  616. }
  617. static int msm_gfx_ldo_is_enabled(struct regulator_dev *rdev)
  618. {
  619. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  620. return ldo_vreg->vreg_enabled;
  621. }
  622. /**
  623. * msm_gfx_ldo_list_corner_voltage() - return the ldo voltage mapped to
  624. * the specified voltage corner
  625. * @rdev: Regulator device pointer for the msm_gfx_ldo
  626. * @corner: Voltage corner
  627. *
  628. * Return: voltage value in microvolts or -EINVAL if the corner is out of range
  629. */
  630. static int msm_gfx_ldo_list_corner_voltage(struct regulator_dev *rdev,
  631. int corner)
  632. {
  633. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  634. corner -= MIN_CORNER_OFFSET;
  635. if (corner >= 0 && corner < ldo_vreg->num_corners)
  636. return ldo_vreg->open_loop_volt[corner];
  637. else
  638. return -EINVAL;
  639. }
  640. static struct regulator_ops msm_gfx_ldo_corner_ops = {
  641. .enable = msm_gfx_ldo_corner_enable,
  642. .disable = msm_gfx_ldo_disable,
  643. .is_enabled = msm_gfx_ldo_is_enabled,
  644. .set_voltage = msm_gfx_ldo_set_corner,
  645. .get_voltage = msm_gfx_ldo_get_corner,
  646. .list_corner_voltage = msm_gfx_ldo_list_corner_voltage,
  647. };
  648. static int msm_gfx_ldo_get_bypass(struct regulator_dev *rdev,
  649. bool *enable)
  650. {
  651. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  652. *enable = ldo_vreg->mode;
  653. return 0;
  654. }
  655. static int msm_gfx_ldo_set_bypass(struct regulator_dev *rdev,
  656. bool mode)
  657. {
  658. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  659. int rc = 0;
  660. mutex_lock(&ldo_vreg->ldo_mutex);
  661. if (ldo_vreg->mode == mode || !ldo_vreg->vreg_enabled)
  662. goto done;
  663. if (mode == LDO_MODE)
  664. rc = switch_mode_to_ldo(ldo_vreg, ldo_vreg->ldo_voltage_uv);
  665. else
  666. rc = switch_mode_to_bhs(ldo_vreg);
  667. if (rc) {
  668. pr_err("Failed to configure regulator in %s mode rc=%d\n",
  669. (mode == LDO_MODE) ? "LDO" : "BHS", rc);
  670. goto done;
  671. }
  672. pr_debug("regulator_set_bypass complete. mode=%s, voltage = %d uV\n",
  673. (mode == LDO_MODE) ? "LDO" : "BHS",
  674. (mode == LDO_MODE) ? ldo_vreg->ldo_voltage_uv : 0);
  675. ldo_vreg->mode = mode;
  676. done:
  677. mutex_unlock(&ldo_vreg->ldo_mutex);
  678. return rc;
  679. }
  680. static int msm_gfx_ldo_voltage_enable(struct regulator_dev *rdev)
  681. {
  682. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  683. int rc = 0;
  684. enum msm_ldo_supply_mode enable_mode;
  685. mutex_lock(&ldo_vreg->ldo_mutex);
  686. pr_debug("regulator_enable requested. voltage=%d\n",
  687. ldo_vreg->ldo_voltage_uv);
  688. enable_mode = ldo_vreg->mode;
  689. if (enable_mode == LDO_MODE)
  690. rc = enable_ldo_mode(ldo_vreg, ldo_vreg->ldo_voltage_uv);
  691. else
  692. rc = enable_bhs_mode(ldo_vreg);
  693. if (rc) {
  694. pr_err("Failed to enable regulator in %s mode rc=%d\n",
  695. (enable_mode == LDO_MODE) ? "LDO" : "BHS", rc);
  696. goto fail;
  697. }
  698. pr_debug("regulator_enable complete. mode=%s, voltage = %d uV\n",
  699. (enable_mode == LDO_MODE) ? "LDO" : "BHS",
  700. (enable_mode == LDO_MODE) ? ldo_vreg->ldo_voltage_uv : 0);
  701. ldo_vreg->vreg_enabled = true;
  702. fail:
  703. mutex_unlock(&ldo_vreg->ldo_mutex);
  704. return rc;
  705. }
  706. static int msm_gfx_ldo_set_voltage(struct regulator_dev *rdev,
  707. int new_uv, int max_uv, unsigned int *selector)
  708. {
  709. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  710. int rc = 0;
  711. mutex_lock(&ldo_vreg->ldo_mutex);
  712. if (new_uv == ldo_vreg->ldo_voltage_uv)
  713. goto done;
  714. if (!ldo_vreg->vreg_enabled || ldo_vreg->mode != LDO_MODE) {
  715. ldo_vreg->ldo_voltage_uv = new_uv;
  716. goto done;
  717. }
  718. /* update LDO voltage */
  719. rc = ldo_update_voltage(ldo_vreg, new_uv);
  720. if (rc)
  721. pr_err("Update voltage failed for [%d, %d], rc=%d\n",
  722. new_uv, max_uv, rc);
  723. done:
  724. mutex_unlock(&ldo_vreg->ldo_mutex);
  725. return rc;
  726. }
  727. static int msm_gfx_ldo_get_voltage(struct regulator_dev *rdev)
  728. {
  729. struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
  730. return ldo_vreg->ldo_voltage_uv;
  731. }
  732. static struct regulator_ops msm_gfx_ldo_voltage_ops = {
  733. .enable = msm_gfx_ldo_voltage_enable,
  734. .disable = msm_gfx_ldo_disable,
  735. .is_enabled = msm_gfx_ldo_is_enabled,
  736. .set_voltage = msm_gfx_ldo_set_voltage,
  737. .get_voltage = msm_gfx_ldo_get_voltage,
  738. .set_bypass = msm_gfx_ldo_set_bypass,
  739. .get_bypass = msm_gfx_ldo_get_bypass,
  740. };
  741. static int msm_gfx_ldo_adjust_init_voltage(struct msm_gfx_ldo *ldo_vreg)
  742. {
  743. int rc, len, size, i;
  744. u32 *volt_adjust;
  745. struct device_node *of_node = ldo_vreg->dev->of_node;
  746. char *prop_name = "qcom,ldo-init-voltage-adjustment";
  747. if (!of_find_property(of_node, prop_name, &len)) {
  748. /* No initial voltage adjustment needed. */
  749. return 0;
  750. }
  751. size = len / sizeof(u32);
  752. if (size != ldo_vreg->num_ldo_corners) {
  753. pr_err("%s length=%d is invalid: required:%d\n",
  754. prop_name, size, ldo_vreg->num_ldo_corners);
  755. return -EINVAL;
  756. }
  757. volt_adjust = devm_kcalloc(ldo_vreg->dev, size, sizeof(*volt_adjust),
  758. GFP_KERNEL);
  759. if (!volt_adjust)
  760. return -ENOMEM;
  761. rc = of_property_read_u32_array(of_node, prop_name, volt_adjust, size);
  762. if (rc) {
  763. pr_err("failed to read %s property rc=%d\n", prop_name, rc);
  764. return rc;
  765. }
  766. for (i = 0; i < ldo_vreg->num_corners; i++) {
  767. if (volt_adjust[i]) {
  768. ldo_vreg->open_loop_volt[i] += volt_adjust[i];
  769. pr_info("adjusted the open-loop voltage[%d] %d -> %d\n",
  770. i + MIN_CORNER_OFFSET,
  771. ldo_vreg->open_loop_volt[i] - volt_adjust[i],
  772. ldo_vreg->open_loop_volt[i]);
  773. }
  774. }
  775. return 0;
  776. }
  777. static int msm_gfx_ldo_voltage_init(struct msm_gfx_ldo *ldo_vreg)
  778. {
  779. struct device_node *of_node = ldo_vreg->dev->of_node;
  780. int i, rc, len;
  781. u64 efuse_bits;
  782. len = ldo_vreg->num_ldo_corners;
  783. ldo_vreg->open_loop_volt = devm_kcalloc(ldo_vreg->dev,
  784. len, sizeof(*ldo_vreg->open_loop_volt),
  785. GFP_KERNEL);
  786. ldo_vreg->ceiling_volt = devm_kcalloc(ldo_vreg->dev,
  787. len, sizeof(*ldo_vreg->ceiling_volt),
  788. GFP_KERNEL);
  789. ldo_vreg->floor_volt = devm_kcalloc(ldo_vreg->dev,
  790. len, sizeof(*ldo_vreg->floor_volt),
  791. GFP_KERNEL);
  792. if (!ldo_vreg->open_loop_volt || !ldo_vreg->ceiling_volt
  793. || !ldo_vreg->floor_volt)
  794. return -ENOMEM;
  795. rc = of_property_read_u32_array(of_node, "qcom,ldo-voltage-ceiling",
  796. ldo_vreg->ceiling_volt, len);
  797. if (rc) {
  798. pr_err("Unable to read qcom,ldo-voltage-ceiling rc=%d\n", rc);
  799. return rc;
  800. }
  801. rc = of_property_read_u32_array(of_node, "qcom,ldo-voltage-floor",
  802. ldo_vreg->floor_volt, len);
  803. if (rc) {
  804. pr_err("Unable to read qcom,ldo-voltage-floor rc=%d\n", rc);
  805. return rc;
  806. }
  807. for (i = 0; i < ldo_vreg->num_ldo_corners; i++) {
  808. rc = read_fuse_param(ldo_vreg->efuse_base,
  809. ldo_vreg->init_volt_param[i],
  810. &efuse_bits);
  811. if (rc) {
  812. pr_err("Unable to read init-voltage rc=%d\n", rc);
  813. return rc;
  814. }
  815. ldo_vreg->open_loop_volt[i] = convert_open_loop_voltage_fuse(
  816. ldo_vreg->ref_volt[i],
  817. GFX_LDO_FUSE_STEP_VOLT,
  818. efuse_bits,
  819. GFX_LDO_FUSE_SIZE);
  820. pr_info("LDO corner %d: target-volt = %d uV\n",
  821. i + MIN_CORNER_OFFSET, ldo_vreg->open_loop_volt[i]);
  822. }
  823. rc = msm_gfx_ldo_adjust_init_voltage(ldo_vreg);
  824. if (rc) {
  825. pr_err("Unable to adjust init voltages rc=%d\n", rc);
  826. return rc;
  827. }
  828. for (i = 0; i < ldo_vreg->num_ldo_corners; i++) {
  829. if (ldo_vreg->open_loop_volt[i] > ldo_vreg->ceiling_volt[i]) {
  830. pr_info("Warning: initial voltage[%d] %d above ceiling %d\n",
  831. i + MIN_CORNER_OFFSET,
  832. ldo_vreg->open_loop_volt[i],
  833. ldo_vreg->ceiling_volt[i]);
  834. ldo_vreg->open_loop_volt[i] = ldo_vreg->ceiling_volt[i];
  835. } else if (ldo_vreg->open_loop_volt[i] <
  836. ldo_vreg->floor_volt[i]) {
  837. pr_info("Warning: initial voltage[%d] %d below floor %d\n",
  838. i + MIN_CORNER_OFFSET,
  839. ldo_vreg->open_loop_volt[i],
  840. ldo_vreg->floor_volt[i]);
  841. ldo_vreg->open_loop_volt[i] = ldo_vreg->floor_volt[i];
  842. }
  843. }
  844. efuse_bits = 0;
  845. rc = read_fuse_param(ldo_vreg->efuse_base, ldo_vreg->ldo_enable_param,
  846. &efuse_bits);
  847. if (rc) {
  848. pr_err("Unable to read ldo_enable_param rc=%d\n", rc);
  849. return rc;
  850. }
  851. ldo_vreg->ldo_fuse_enable = !!efuse_bits;
  852. pr_info("LDO-mode fuse %s by default\n", ldo_vreg->ldo_fuse_enable ?
  853. "enabled" : "disabled");
  854. return rc;
  855. }
  856. static int msm_gfx_ldo_efuse_init(struct platform_device *pdev,
  857. struct msm_gfx_ldo *ldo_vreg)
  858. {
  859. struct resource *res;
  860. u32 len;
  861. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse_addr");
  862. if (!res || !res->start) {
  863. pr_err("efuse_addr missing: res=%p\n", res);
  864. return -EINVAL;
  865. }
  866. ldo_vreg->efuse_addr = res->start;
  867. len = res->end - res->start + 1;
  868. ldo_vreg->efuse_base = devm_ioremap(&pdev->dev,
  869. ldo_vreg->efuse_addr, len);
  870. if (!ldo_vreg->efuse_base) {
  871. pr_err("Unable to map efuse_addr %pa\n",
  872. &ldo_vreg->efuse_addr);
  873. return -EINVAL;
  874. }
  875. return 0;
  876. }
  877. static int msm_gfx_ldo_mem_acc_init(struct msm_gfx_ldo *ldo_vreg)
  878. {
  879. int rc;
  880. u32 len, size;
  881. struct device_node *of_node = ldo_vreg->dev->of_node;
  882. if (of_find_property(ldo_vreg->dev->of_node, "mem-acc-supply", NULL)) {
  883. ldo_vreg->mem_acc_vreg = devm_regulator_get(ldo_vreg->dev,
  884. "mem-acc");
  885. if (IS_ERR_OR_NULL(ldo_vreg->mem_acc_vreg)) {
  886. rc = PTR_RET(ldo_vreg->mem_acc_vreg);
  887. if (rc != -EPROBE_DEFER)
  888. pr_err("devm_regulator_get: mem-acc: rc=%d\n",
  889. rc);
  890. return rc;
  891. }
  892. } else {
  893. pr_debug("mem-acc-supply not specified\n");
  894. return 0;
  895. }
  896. if (!of_find_property(of_node, "qcom,mem-acc-corner-map", &len)) {
  897. pr_err("qcom,mem-acc-corner-map missing");
  898. return -EINVAL;
  899. }
  900. size = len / sizeof(u32);
  901. if (size != ldo_vreg->num_corners) {
  902. pr_err("qcom,mem-acc-corner-map length=%d is invalid: required:%u\n",
  903. size, ldo_vreg->num_corners);
  904. return -EINVAL;
  905. }
  906. ldo_vreg->mem_acc_corner_map = devm_kcalloc(ldo_vreg->dev, size,
  907. sizeof(*ldo_vreg->mem_acc_corner_map), GFP_KERNEL);
  908. if (!ldo_vreg->mem_acc_corner_map)
  909. return -ENOMEM;
  910. rc = of_property_read_u32_array(of_node, "qcom,mem-acc-corner-map",
  911. ldo_vreg->mem_acc_corner_map, size);
  912. if (rc)
  913. pr_err("Unable to read qcom,mem-acc-corner-map rc=%d\n", rc);
  914. return rc;
  915. }
  916. static int msm_gfx_ldo_init(struct platform_device *pdev,
  917. struct msm_gfx_ldo *ldo_vreg)
  918. {
  919. struct resource *res;
  920. u32 len, ctl;
  921. int i = 0;
  922. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ldo_addr");
  923. if (!res || !res->start) {
  924. pr_err("ldo_addr missing: res=%p\n", res);
  925. return -EINVAL;
  926. }
  927. ldo_vreg->ldo_addr = res->start;
  928. len = res->end - res->start + 1;
  929. ldo_vreg->ldo_base = devm_ioremap(ldo_vreg->dev,
  930. ldo_vreg->ldo_addr, len);
  931. if (!ldo_vreg->ldo_base) {
  932. pr_err("Unable to map efuse_addr %pa\n",
  933. &ldo_vreg->ldo_addr);
  934. return -EINVAL;
  935. }
  936. /* HW initialization */
  937. /* clear clamp_io, enable CPR in auto-bypass*/
  938. ctl = readl_relaxed(ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  939. ctl &= ~LDO_CLAMP_IO_BIT;
  940. ctl |= EN_LDOAP_CTRL_CPR_BIT;
  941. writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG);
  942. i = 0;
  943. while (ldo_vreg->ldo_init_config &&
  944. ldo_vreg->ldo_init_config[i].offset != LDO_MAX_OFFSET) {
  945. writel_relaxed(ldo_vreg->ldo_init_config[i].value,
  946. ldo_vreg->ldo_base +
  947. ldo_vreg->ldo_init_config[i].offset);
  948. i++;
  949. }
  950. /* complete the writes */
  951. mb();
  952. return 0;
  953. }
  954. static int ldo_parse_cx_parameters(struct msm_gfx_ldo *ldo_vreg)
  955. {
  956. struct device_node *of_node = ldo_vreg->dev->of_node;
  957. int rc, len, size;
  958. if (of_find_property(of_node, "vdd-cx-supply", NULL)) {
  959. ldo_vreg->vdd_cx = devm_regulator_get(ldo_vreg->dev, "vdd-cx");
  960. if (IS_ERR_OR_NULL(ldo_vreg->vdd_cx)) {
  961. rc = PTR_RET(ldo_vreg->vdd_cx);
  962. if (rc != -EPROBE_DEFER)
  963. pr_err("devm_regulator_get: vdd-cx: rc=%d\n",
  964. rc);
  965. return rc;
  966. }
  967. } else {
  968. pr_debug("vdd-cx-supply not specified\n");
  969. return 0;
  970. }
  971. if (!of_find_property(of_node, "qcom,vdd-cx-corner-map", &len)) {
  972. pr_err("qcom,vdd-cx-corner-map missing");
  973. return -EINVAL;
  974. }
  975. size = len / sizeof(u32);
  976. if (size != ldo_vreg->num_corners) {
  977. pr_err("qcom,vdd-cx-corner-map length=%d is invalid: required:%u\n",
  978. size, ldo_vreg->num_corners);
  979. return -EINVAL;
  980. }
  981. ldo_vreg->vdd_cx_corner_map = devm_kcalloc(ldo_vreg->dev, size,
  982. sizeof(*ldo_vreg->vdd_cx_corner_map), GFP_KERNEL);
  983. if (!ldo_vreg->vdd_cx_corner_map)
  984. return -ENOMEM;
  985. rc = of_property_read_u32_array(of_node, "qcom,vdd-cx-corner-map",
  986. ldo_vreg->vdd_cx_corner_map, size);
  987. if (rc)
  988. pr_err("Unable to read qcom,vdd-cx-corner-map rc=%d\n", rc);
  989. return rc;
  990. }
  991. static int msm_gfx_ldo_parse_dt(struct msm_gfx_ldo *ldo_vreg)
  992. {
  993. struct device_node *of_node = ldo_vreg->dev->of_node;
  994. int rc, size, len;
  995. rc = of_property_read_u32(of_node, "qcom,num-corners",
  996. &ldo_vreg->num_corners);
  997. if (rc < 0) {
  998. pr_err("Unable to read qcom,num-corners rc=%d\n", rc);
  999. return rc;
  1000. }
  1001. rc = of_property_read_u32(of_node, "qcom,num-ldo-corners",
  1002. &ldo_vreg->num_ldo_corners);
  1003. if (rc) {
  1004. pr_err("Unable to read qcom,num-ldo-corners rc=%d\n", rc);
  1005. return rc;
  1006. }
  1007. rc = of_property_read_u32(of_node, "qcom,init-corner",
  1008. &ldo_vreg->corner);
  1009. if (rc) {
  1010. pr_err("Unable to read qcom,init-corner rc=%d\n", rc);
  1011. return rc;
  1012. }
  1013. if (!of_find_property(of_node, "qcom,ldo-enable-corner-map", &len)) {
  1014. pr_err("qcom,ldo-enable-corner-map missing\n");
  1015. return -EINVAL;
  1016. }
  1017. size = len / sizeof(u32);
  1018. if (size != ldo_vreg->num_corners) {
  1019. pr_err("qcom,ldo-enable-corner-map length=%d is invalid: required:%u\n",
  1020. size, ldo_vreg->num_corners);
  1021. return -EINVAL;
  1022. }
  1023. ldo_vreg->ldo_corner_en_map = devm_kcalloc(ldo_vreg->dev, size,
  1024. sizeof(*ldo_vreg->ldo_corner_en_map), GFP_KERNEL);
  1025. if (!ldo_vreg->ldo_corner_en_map)
  1026. return -ENOMEM;
  1027. rc = of_property_read_u32_array(of_node, "qcom,ldo-enable-corner-map",
  1028. ldo_vreg->ldo_corner_en_map, size);
  1029. if (rc) {
  1030. pr_err("Unable to read qcom,ldo-enable-corner-map rc=%d\n",
  1031. rc);
  1032. return rc;
  1033. }
  1034. rc = ldo_parse_cx_parameters(ldo_vreg);
  1035. if (rc) {
  1036. pr_err("Unable to parse CX parameters rc=%d\n", rc);
  1037. return rc;
  1038. }
  1039. return 0;
  1040. }
  1041. static int msm_gfx_ldo_target_init(struct msm_gfx_ldo *ldo_vreg)
  1042. {
  1043. int i;
  1044. /* MSM8953 */
  1045. ldo_vreg->init_volt_param = devm_kzalloc(ldo_vreg->dev,
  1046. (MSM8953_LDO_FUSE_CORNERS *
  1047. sizeof(struct fuse_param *)), GFP_KERNEL);
  1048. if (!ldo_vreg->init_volt_param)
  1049. return -ENOMEM;
  1050. for (i = 0; i < MSM8953_LDO_FUSE_CORNERS; i++)
  1051. ldo_vreg->init_volt_param[i] =
  1052. msm8953_init_voltage_param[i];
  1053. ldo_vreg->ref_volt = msm8953_fuse_ref_volt;
  1054. ldo_vreg->ldo_enable_param = msm8953_ldo_enable_param;
  1055. return 0;
  1056. }
  1057. static int debugfs_ldo_mode_disable_set(void *data, u64 val)
  1058. {
  1059. struct msm_gfx_ldo *ldo_vreg = data;
  1060. ldo_vreg->ldo_mode_disable = !!val;
  1061. pr_debug("LDO-mode %s\n", ldo_vreg->ldo_mode_disable ?
  1062. "disabled" : "enabled");
  1063. return 0;
  1064. }
  1065. static int debugfs_ldo_mode_disable_get(void *data, u64 *val)
  1066. {
  1067. struct msm_gfx_ldo *ldo_vreg = data;
  1068. *val = ldo_vreg->ldo_mode_disable;
  1069. return 0;
  1070. }
  1071. DEFINE_SIMPLE_ATTRIBUTE(ldo_mode_disable_fops, debugfs_ldo_mode_disable_get,
  1072. debugfs_ldo_mode_disable_set, "%llu\n");
  1073. static int debugfs_ldo_set_voltage(void *data, u64 val)
  1074. {
  1075. struct msm_gfx_ldo *ldo_vreg = data;
  1076. int rc = 0, timeout = 50;
  1077. u32 reg = 0, voltage = 0;
  1078. mutex_lock(&ldo_vreg->ldo_mutex);
  1079. if (ldo_vreg->mode == BHS_MODE || !ldo_vreg->vreg_enabled ||
  1080. val > MAX_LDO_VOLTAGE || val < MIN_LDO_VOLTAGE) {
  1081. rc = -EINVAL;
  1082. goto done;
  1083. }
  1084. voltage = GET_VREF((u32)val);
  1085. reg = readl_relaxed(ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  1086. /* set the new voltage */
  1087. reg &= ~VREF_VAL_MASK;
  1088. reg |= voltage & VREF_VAL_MASK;
  1089. writel_relaxed(reg, ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  1090. /* Initiate VREF update */
  1091. reg |= UPDATE_VREF_BIT;
  1092. writel_relaxed(reg, ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  1093. /* complete the writes */
  1094. mb();
  1095. reg &= ~UPDATE_VREF_BIT;
  1096. writel_relaxed(reg, ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  1097. /* complete the writes */
  1098. mb();
  1099. while (--timeout) {
  1100. reg = readl_relaxed(ldo_vreg->ldo_base +
  1101. PWRSWITCH_STATUS_REG);
  1102. if (reg & (LDO_VREF_SETTLED_BIT | LDO_READY_BIT))
  1103. break;
  1104. udelay(10);
  1105. }
  1106. if (!timeout) {
  1107. pr_err("LDO_VREF_SETTLED not set PWRSWITCH_STATUS = 0x%x\n",
  1108. reg);
  1109. rc = -EBUSY;
  1110. } else {
  1111. ldo_vreg->ldo_voltage_uv = val;
  1112. pr_debug("LDO voltage set to %d uV\n",
  1113. ldo_vreg->ldo_voltage_uv);
  1114. }
  1115. done:
  1116. mutex_unlock(&ldo_vreg->ldo_mutex);
  1117. return rc;
  1118. }
  1119. static int debugfs_ldo_get_voltage(void *data, u64 *val)
  1120. {
  1121. struct msm_gfx_ldo *ldo_vreg = data;
  1122. int rc = 0;
  1123. u32 reg;
  1124. mutex_lock(&ldo_vreg->ldo_mutex);
  1125. if (ldo_vreg->mode == BHS_MODE || !ldo_vreg->vreg_enabled) {
  1126. rc = -EINVAL;
  1127. goto done;
  1128. }
  1129. reg = readl_relaxed(ldo_vreg->ldo_base + LDO_VREF_SET_REG);
  1130. reg &= VREF_VAL_MASK;
  1131. *val = (reg * LDO_STEP_VOLATGE) + MIN_LDO_VOLTAGE;
  1132. done:
  1133. mutex_unlock(&ldo_vreg->ldo_mutex);
  1134. return rc;
  1135. }
  1136. DEFINE_SIMPLE_ATTRIBUTE(ldo_voltage_fops, debugfs_ldo_get_voltage,
  1137. debugfs_ldo_set_voltage, "%llu\n");
  1138. static int msm_gfx_ldo_debug_info_open(struct inode *inode, struct file *file)
  1139. {
  1140. file->private_data = inode->i_private;
  1141. return 0;
  1142. }
  1143. static ssize_t msm_gfx_ldo_debug_info_read(struct file *file, char __user *buff,
  1144. size_t count, loff_t *ppos)
  1145. {
  1146. struct msm_gfx_ldo *ldo_vreg = file->private_data;
  1147. char *debugfs_buf;
  1148. ssize_t len, ret = 0;
  1149. u32 i = 0, reg[MAX_LDO_REGS];
  1150. debugfs_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
  1151. if (!debugfs_buf)
  1152. return -ENOMEM;
  1153. mutex_lock(&ldo_vreg->ldo_mutex);
  1154. len = snprintf(debugfs_buf + ret, PAGE_SIZE - ret,
  1155. "Regulator_enable = %d Regulator mode = %s Corner = %d LDO-voltage = %d uV\n",
  1156. ldo_vreg->vreg_enabled,
  1157. ldo_vreg->mode == BHS_MODE ? "BHS" : "LDO",
  1158. ldo_vreg->corner + MIN_CORNER_OFFSET,
  1159. ldo_vreg->ldo_voltage_uv);
  1160. ret += len;
  1161. for (i = 0; i < MAX_LDO_REGS; i++) {
  1162. reg[i] = 0;
  1163. reg[i] = readl_relaxed(ldo_vreg->ldo_base + (i * 4));
  1164. len = snprintf(debugfs_buf + ret, PAGE_SIZE - ret,
  1165. "%s = 0x%x\n", register_str[i], reg[i]);
  1166. ret += len;
  1167. }
  1168. mutex_unlock(&ldo_vreg->ldo_mutex);
  1169. ret = simple_read_from_buffer(buff, count, ppos, debugfs_buf, ret);
  1170. kfree(debugfs_buf);
  1171. return ret;
  1172. }
  1173. static const struct file_operations msm_gfx_ldo_debug_info_fops = {
  1174. .open = msm_gfx_ldo_debug_info_open,
  1175. .read = msm_gfx_ldo_debug_info_read,
  1176. };
  1177. static void msm_gfx_ldo_debugfs_init(struct msm_gfx_ldo *ldo_vreg)
  1178. {
  1179. struct dentry *temp;
  1180. ldo_vreg->debugfs = debugfs_create_dir("msm_gfx_ldo", NULL);
  1181. if (!ldo_vreg->debugfs) {
  1182. pr_err("Couldn't create debug dir\n");
  1183. return;
  1184. }
  1185. temp = debugfs_create_file("debug_info", 0444, ldo_vreg->debugfs,
  1186. ldo_vreg, &msm_gfx_ldo_debug_info_fops);
  1187. if (IS_ERR_OR_NULL(temp)) {
  1188. pr_err("debug_info node creation failed\n");
  1189. return;
  1190. }
  1191. temp = debugfs_create_file("ldo_voltage", 0644, ldo_vreg->debugfs,
  1192. ldo_vreg, &ldo_voltage_fops);
  1193. if (IS_ERR_OR_NULL(temp)) {
  1194. pr_err("ldo_voltage node creation failed\n");
  1195. return;
  1196. }
  1197. temp = debugfs_create_file("ldo_mode_disable", 0644, ldo_vreg->debugfs,
  1198. ldo_vreg, &ldo_mode_disable_fops);
  1199. if (IS_ERR_OR_NULL(temp)) {
  1200. pr_err("ldo_mode_disable node creation failed\n");
  1201. return;
  1202. }
  1203. }
  1204. static void msm_gfx_ldo_debugfs_remove(struct msm_gfx_ldo *ldo_vreg)
  1205. {
  1206. debugfs_remove_recursive(ldo_vreg->debugfs);
  1207. }
  1208. static int msm_gfx_ldo_corner_config_init(struct msm_gfx_ldo *ldo_vreg,
  1209. struct platform_device *pdev)
  1210. {
  1211. int rc;
  1212. rc = msm_gfx_ldo_target_init(ldo_vreg);
  1213. if (rc) {
  1214. pr_err("Unable to initialize target specific data rc=%d", rc);
  1215. return rc;
  1216. }
  1217. rc = msm_gfx_ldo_parse_dt(ldo_vreg);
  1218. if (rc) {
  1219. pr_err("Unable to pasrse dt rc=%d\n", rc);
  1220. return rc;
  1221. }
  1222. rc = msm_gfx_ldo_efuse_init(pdev, ldo_vreg);
  1223. if (rc) {
  1224. pr_err("efuse_init failed rc=%d\n", rc);
  1225. return rc;
  1226. }
  1227. rc = msm_gfx_ldo_voltage_init(ldo_vreg);
  1228. if (rc) {
  1229. pr_err("ldo_voltage_init failed rc=%d\n", rc);
  1230. return rc;
  1231. }
  1232. rc = msm_gfx_ldo_mem_acc_init(ldo_vreg);
  1233. if (rc) {
  1234. pr_err("Unable to initialize mem_acc rc=%d\n", rc);
  1235. return rc;
  1236. }
  1237. return rc;
  1238. };
  1239. /* Data corresponds to the SoC revision */
  1240. static const struct of_device_id msm_gfx_ldo_match_table[] = {
  1241. {
  1242. .compatible = "qcom,msm8953-gfx-ldo",
  1243. .data = (void *)(uintptr_t)MSM8953_SOC_ID,
  1244. },
  1245. {
  1246. .compatible = "qcom,sdm660-gfx-ldo",
  1247. .data = (void *)(uintptr_t)SDM660_SOC_ID,
  1248. },
  1249. {}
  1250. };
  1251. static int msm_gfx_ldo_probe(struct platform_device *pdev)
  1252. {
  1253. struct msm_gfx_ldo *ldo_vreg;
  1254. struct regulator_config reg_config = {};
  1255. struct regulator_desc *rdesc;
  1256. struct regulator_init_data *init_data = pdev->dev.platform_data;
  1257. struct device *dev = &pdev->dev;
  1258. const struct of_device_id *match;
  1259. int soc_id, rc;
  1260. match = of_match_device(msm_gfx_ldo_match_table, dev);
  1261. if (!match)
  1262. return -ENODEV;
  1263. ldo_vreg = devm_kzalloc(dev, sizeof(*ldo_vreg), GFP_KERNEL);
  1264. if (!ldo_vreg)
  1265. return -ENOMEM;
  1266. init_data = of_get_regulator_init_data(dev, dev->of_node, NULL);
  1267. if (!init_data) {
  1268. pr_err("regulator init data is missing\n");
  1269. return -EINVAL;
  1270. }
  1271. init_data->constraints.input_uV = init_data->constraints.max_uV;
  1272. init_data->constraints.valid_ops_mask
  1273. |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS;
  1274. ldo_vreg->rdesc.name = init_data->constraints.name;
  1275. if (ldo_vreg->rdesc.name == NULL) {
  1276. dev_err(dev, "regulator-name missing\n");
  1277. return -EINVAL;
  1278. }
  1279. soc_id = (uintptr_t)match->data;
  1280. ldo_vreg->dev = &pdev->dev;
  1281. mutex_init(&ldo_vreg->ldo_mutex);
  1282. platform_set_drvdata(pdev, ldo_vreg);
  1283. switch (soc_id) {
  1284. case MSM8953_SOC_ID:
  1285. ldo_vreg->ldo_init_config = msm8953_ldo_config;
  1286. ldo_vreg->ops_type = CORNER;
  1287. rc = msm_gfx_ldo_corner_config_init(ldo_vreg, pdev);
  1288. if (rc) {
  1289. pr_err("ldo corner handling initialization failed, rc=%d\n",
  1290. rc);
  1291. return rc;
  1292. }
  1293. break;
  1294. case SDM660_SOC_ID:
  1295. ldo_vreg->ldo_init_config = sdm660_ldo_config;
  1296. ldo_vreg->ops_type = VOLTAGE;
  1297. init_data->constraints.valid_ops_mask
  1298. |= REGULATOR_CHANGE_BYPASS;
  1299. break;
  1300. default:
  1301. pr_err("invalid SOC ID = %d\n", soc_id);
  1302. return -EINVAL;
  1303. }
  1304. /* HW initialization */
  1305. rc = msm_gfx_ldo_init(pdev, ldo_vreg);
  1306. if (rc) {
  1307. pr_err("ldo_init failed rc=%d\n", rc);
  1308. return rc;
  1309. }
  1310. rdesc = &ldo_vreg->rdesc;
  1311. rdesc->owner = THIS_MODULE;
  1312. rdesc->type = REGULATOR_VOLTAGE;
  1313. if (ldo_vreg->ops_type == CORNER)
  1314. rdesc->ops = &msm_gfx_ldo_corner_ops;
  1315. else
  1316. rdesc->ops = &msm_gfx_ldo_voltage_ops;
  1317. reg_config.dev = &pdev->dev;
  1318. reg_config.init_data = init_data;
  1319. reg_config.driver_data = ldo_vreg;
  1320. reg_config.of_node = pdev->dev.of_node;
  1321. ldo_vreg->rdev = regulator_register(rdesc, &reg_config);
  1322. if (IS_ERR(ldo_vreg->rdev)) {
  1323. rc = PTR_ERR(ldo_vreg->rdev);
  1324. pr_err("regulator_register failed: rc=%d\n", rc);
  1325. return rc;
  1326. }
  1327. msm_gfx_ldo_debugfs_init(ldo_vreg);
  1328. return 0;
  1329. }
  1330. static int msm_gfx_ldo_remove(struct platform_device *pdev)
  1331. {
  1332. struct msm_gfx_ldo *ldo_vreg = platform_get_drvdata(pdev);
  1333. regulator_unregister(ldo_vreg->rdev);
  1334. msm_gfx_ldo_debugfs_remove(ldo_vreg);
  1335. return 0;
  1336. }
  1337. static struct platform_driver msm_gfx_ldo_driver = {
  1338. .driver = {
  1339. .name = "qcom,msm-gfx-ldo",
  1340. .of_match_table = msm_gfx_ldo_match_table,
  1341. .owner = THIS_MODULE,
  1342. },
  1343. .probe = msm_gfx_ldo_probe,
  1344. .remove = msm_gfx_ldo_remove,
  1345. };
  1346. static int msm_gfx_ldo_platform_init(void)
  1347. {
  1348. return platform_driver_register(&msm_gfx_ldo_driver);
  1349. }
  1350. arch_initcall(msm_gfx_ldo_platform_init);
  1351. static void msm_gfx_ldo_platform_exit(void)
  1352. {
  1353. platform_driver_unregister(&msm_gfx_ldo_driver);
  1354. }
  1355. module_exit(msm_gfx_ldo_platform_exit);
  1356. MODULE_DESCRIPTION("MSM GFX LDO driver");
  1357. MODULE_LICENSE("GPL v2");