mem-acc-regulator.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /* Copyright (c) 2014, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #define pr_fmt(fmt) "ACC: %s: " fmt, __func__
  13. #include <linux/module.h>
  14. #include <linux/types.h>
  15. #include <linux/init.h>
  16. #include <linux/slab.h>
  17. #include <linux/err.h>
  18. #include <linux/of.h>
  19. #include <linux/of_device.h>
  20. #include <linux/io.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/regulator/driver.h>
  23. #include <linux/regulator/machine.h>
  24. #include <linux/regulator/of_regulator.h>
  25. #define MEM_ACC_SEL_MASK 0x3
  26. enum {
  27. MEMORY_L1,
  28. MEMORY_L2,
  29. MEMORY_MAX,
  30. };
  31. struct mem_acc_regulator {
  32. struct device *dev;
  33. struct regulator_desc rdesc;
  34. struct regulator_dev *rdev;
  35. int corner;
  36. bool mem_acc_supported[MEMORY_MAX];
  37. u32 acc_sel_reg[MEMORY_MAX];
  38. u32 *acc_sel_mask[MEMORY_MAX];
  39. u32 *acc_sel_bit_pos[MEMORY_MAX];
  40. u32 num_acc_sel[MEMORY_MAX];
  41. u32 *acc_en_bit_pos;
  42. u32 num_acc_en;
  43. u32 *corner_acc_map;
  44. u32 num_corners;
  45. void __iomem *acc_sel_base[MEMORY_MAX];
  46. void __iomem *acc_en_base;
  47. phys_addr_t acc_sel_addr[MEMORY_MAX];
  48. phys_addr_t acc_en_addr;
  49. };
  50. static inline u32 apc_to_acc_corner(struct mem_acc_regulator *mem_acc_vreg,
  51. int corner)
  52. {
  53. /*
  54. * corner_acc_map maps the corner from index 0 and APC corner value
  55. * starts from the value 1
  56. */
  57. return mem_acc_vreg->corner_acc_map[corner - 1];
  58. }
  59. static void __update_acc_sel(struct mem_acc_regulator *mem_acc_vreg,
  60. int corner, int mem_type)
  61. {
  62. u32 acc_data, i, bit, acc_corner;
  63. acc_data = mem_acc_vreg->acc_sel_reg[mem_type];
  64. for (i = 0; i < mem_acc_vreg->num_acc_sel[mem_type]; i++) {
  65. bit = mem_acc_vreg->acc_sel_bit_pos[mem_type][i];
  66. acc_data &= ~mem_acc_vreg->acc_sel_mask[mem_type][i];
  67. acc_corner = apc_to_acc_corner(mem_acc_vreg, corner);
  68. acc_data |= (acc_corner << bit) &
  69. mem_acc_vreg->acc_sel_mask[mem_type][i];
  70. }
  71. pr_debug("corner=%d old_acc_sel=0x%02x new_acc_sel=0x%02x mem_type=%d\n",
  72. corner, mem_acc_vreg->acc_sel_reg[mem_type],
  73. acc_data, mem_type);
  74. writel_relaxed(acc_data, mem_acc_vreg->acc_sel_base[mem_type]);
  75. mem_acc_vreg->acc_sel_reg[mem_type] = acc_data;
  76. }
  77. static void update_acc_sel(struct mem_acc_regulator *mem_acc_vreg, int corner)
  78. {
  79. int i;
  80. for (i = 0; i < MEMORY_MAX; i++) {
  81. if (mem_acc_vreg->mem_acc_supported[i])
  82. __update_acc_sel(mem_acc_vreg, corner, i);
  83. }
  84. }
  85. static int mem_acc_regulator_set_voltage(struct regulator_dev *rdev,
  86. int corner, int corner_max, unsigned *selector)
  87. {
  88. struct mem_acc_regulator *mem_acc_vreg = rdev_get_drvdata(rdev);
  89. int i;
  90. if (corner > mem_acc_vreg->num_corners) {
  91. pr_err("Invalid corner=%d requested\n", corner);
  92. return -EINVAL;
  93. }
  94. pr_debug("old corner=%d, new corner=%d\n",
  95. mem_acc_vreg->corner, corner);
  96. if (corner == mem_acc_vreg->corner)
  97. return 0;
  98. /* go up or down one level at a time */
  99. if (corner > mem_acc_vreg->corner) {
  100. for (i = mem_acc_vreg->corner + 1; i <= corner; i++) {
  101. pr_debug("UP: to corner %d\n", i);
  102. update_acc_sel(mem_acc_vreg, i);
  103. }
  104. } else {
  105. for (i = mem_acc_vreg->corner - 1; i >= corner; i--) {
  106. pr_debug("DOWN: to corner %d\n", i);
  107. update_acc_sel(mem_acc_vreg, i);
  108. }
  109. }
  110. pr_debug("new voltage corner set %d\n", corner);
  111. mem_acc_vreg->corner = corner;
  112. return 0;
  113. }
  114. static int mem_acc_regulator_get_voltage(struct regulator_dev *rdev)
  115. {
  116. struct mem_acc_regulator *mem_acc_vreg = rdev_get_drvdata(rdev);
  117. return mem_acc_vreg->corner;
  118. }
  119. static struct regulator_ops mem_acc_corner_ops = {
  120. .set_voltage = mem_acc_regulator_set_voltage,
  121. .get_voltage = mem_acc_regulator_get_voltage,
  122. };
  123. static int __mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg,
  124. int mem_type)
  125. {
  126. int i;
  127. u32 bit;
  128. mem_acc_vreg->acc_sel_mask[mem_type] = devm_kzalloc(mem_acc_vreg->dev,
  129. mem_acc_vreg->num_acc_sel[mem_type] * sizeof(u32), GFP_KERNEL);
  130. if (!mem_acc_vreg->acc_sel_mask[mem_type]) {
  131. pr_err("Unable to allocate memory for mem_type=%d\n", mem_type);
  132. return -ENOMEM;
  133. }
  134. for (i = 0; i < mem_acc_vreg->num_acc_sel[mem_type]; i++) {
  135. bit = mem_acc_vreg->acc_sel_bit_pos[mem_type][i];
  136. mem_acc_vreg->acc_sel_mask[mem_type][i] =
  137. MEM_ACC_SEL_MASK << bit;
  138. }
  139. mem_acc_vreg->acc_sel_reg[mem_type] =
  140. readl_relaxed(mem_acc_vreg->acc_sel_base[mem_type]);
  141. return 0;
  142. }
  143. static int mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg)
  144. {
  145. int i, rc;
  146. for (i = 0; i < MEMORY_MAX; i++) {
  147. if (mem_acc_vreg->mem_acc_supported[i]) {
  148. rc = __mem_acc_sel_init(mem_acc_vreg, i);
  149. if (rc) {
  150. pr_err("Unable to intialize mem_type=%d rc=%d\n",
  151. i, rc);
  152. return rc;
  153. }
  154. }
  155. }
  156. return 0;
  157. }
  158. static void mem_acc_en_init(struct mem_acc_regulator *mem_acc_vreg)
  159. {
  160. int i, bit;
  161. u32 acc_data;
  162. acc_data = readl_relaxed(mem_acc_vreg->acc_en_base);
  163. pr_debug("init: acc_en_register=%x\n", acc_data);
  164. for (i = 0; i < mem_acc_vreg->num_acc_en; i++) {
  165. bit = mem_acc_vreg->acc_en_bit_pos[i];
  166. acc_data |= BIT(bit);
  167. }
  168. pr_debug("final: acc_en_register=%x\n", acc_data);
  169. writel_relaxed(acc_data, mem_acc_vreg->acc_en_base);
  170. }
  171. static int populate_acc_data(struct mem_acc_regulator *mem_acc_vreg,
  172. const char *prop_name, u32 **value, u32 *len)
  173. {
  174. int rc;
  175. if (!of_get_property(mem_acc_vreg->dev->of_node, prop_name, len)) {
  176. pr_err("Unable to find %s property\n", prop_name);
  177. return -EINVAL;
  178. }
  179. *len /= sizeof(u32);
  180. if (!(*len)) {
  181. pr_err("Incorrect entries in %s\n", prop_name);
  182. return -EINVAL;
  183. }
  184. *value = devm_kzalloc(mem_acc_vreg->dev, (*len) * sizeof(u32),
  185. GFP_KERNEL);
  186. if (!(*value)) {
  187. pr_err("Unable to allocate memory for %s\n", prop_name);
  188. return -ENOMEM;
  189. }
  190. pr_debug("Found %s, data-length = %d\n", prop_name, *len);
  191. rc = of_property_read_u32_array(mem_acc_vreg->dev->of_node,
  192. prop_name, *value, *len);
  193. if (rc) {
  194. pr_err("Unable to populate %s rc=%d\n", prop_name, rc);
  195. return rc;
  196. }
  197. return 0;
  198. }
  199. static int mem_acc_sel_setup(struct mem_acc_regulator *mem_acc_vreg,
  200. struct resource *res, int mem_type)
  201. {
  202. int len, rc;
  203. char *mem_select_str;
  204. mem_acc_vreg->acc_sel_addr[mem_type] = res->start;
  205. len = res->end - res->start + 1;
  206. pr_debug("'acc_sel_addr' = %pa mem_type=%d (len=%d)\n",
  207. &res->start, mem_type, len);
  208. mem_acc_vreg->acc_sel_base[mem_type] = devm_ioremap(mem_acc_vreg->dev,
  209. mem_acc_vreg->acc_sel_addr[mem_type], len);
  210. if (!mem_acc_vreg->acc_sel_base[mem_type]) {
  211. pr_err("Unable to map 'acc_sel_addr' %pa for mem_type=%d\n",
  212. &mem_acc_vreg->acc_sel_addr[mem_type], mem_type);
  213. return -EINVAL;
  214. }
  215. switch (mem_type) {
  216. case MEMORY_L1:
  217. mem_select_str = "qcom,acc-sel-l1-bit-pos";
  218. break;
  219. case MEMORY_L2:
  220. mem_select_str = "qcom,acc-sel-l2-bit-pos";
  221. break;
  222. }
  223. rc = populate_acc_data(mem_acc_vreg, mem_select_str,
  224. &mem_acc_vreg->acc_sel_bit_pos[mem_type],
  225. &mem_acc_vreg->num_acc_sel[mem_type]);
  226. if (rc)
  227. pr_err("Unable to populate '%s' rc=%d\n", mem_select_str, rc);
  228. return rc;
  229. }
  230. static int mem_acc_init(struct platform_device *pdev,
  231. struct mem_acc_regulator *mem_acc_vreg)
  232. {
  233. struct resource *res;
  234. int len, rc, i;
  235. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-en");
  236. if (!res || !res->start) {
  237. pr_debug("'acc-en' resource missing or not used.\n");
  238. } else {
  239. mem_acc_vreg->acc_en_addr = res->start;
  240. len = res->end - res->start + 1;
  241. pr_debug("'acc_en_addr' = %pa (len=0x%x)\n", &res->start, len);
  242. mem_acc_vreg->acc_en_base = devm_ioremap(mem_acc_vreg->dev,
  243. mem_acc_vreg->acc_en_addr, len);
  244. if (!mem_acc_vreg->acc_en_base) {
  245. pr_err("Unable to map 'acc_en_addr' %pa\n",
  246. &mem_acc_vreg->acc_en_addr);
  247. return -EINVAL;
  248. }
  249. rc = populate_acc_data(mem_acc_vreg, "qcom,acc-en-bit-pos",
  250. &mem_acc_vreg->acc_en_bit_pos,
  251. &mem_acc_vreg->num_acc_en);
  252. if (rc) {
  253. pr_err("Unable to populate 'qcom,acc-en-bit-pos' rc=%d\n",
  254. rc);
  255. return rc;
  256. }
  257. }
  258. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-sel-l1");
  259. if (!res || !res->start) {
  260. pr_debug("'acc-sel-l1' resource missing or not used.\n");
  261. } else {
  262. rc = mem_acc_sel_setup(mem_acc_vreg, res, MEMORY_L1);
  263. if (rc) {
  264. pr_err("Unable to setup mem-acc for mem_type=%d rc=%d\n",
  265. MEMORY_L1, rc);
  266. return rc;
  267. }
  268. mem_acc_vreg->mem_acc_supported[MEMORY_L1] = true;
  269. }
  270. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-sel-l2");
  271. if (!res || !res->start) {
  272. pr_debug("'acc-sel-l2' resource missing or not used.\n");
  273. } else {
  274. rc = mem_acc_sel_setup(mem_acc_vreg, res, MEMORY_L2);
  275. if (rc) {
  276. pr_err("Unable to setup mem-acc for mem_type=%d rc=%d\n",
  277. MEMORY_L2, rc);
  278. return rc;
  279. }
  280. mem_acc_vreg->mem_acc_supported[MEMORY_L2] = true;
  281. }
  282. rc = populate_acc_data(mem_acc_vreg, "qcom,corner-acc-map",
  283. &mem_acc_vreg->corner_acc_map,
  284. &mem_acc_vreg->num_corners);
  285. if (rc) {
  286. pr_err("Unable to find 'qcom,corner-acc-map' rc=%d\n", rc);
  287. return rc;
  288. }
  289. pr_debug("num_corners = %d\n", mem_acc_vreg->num_corners);
  290. /* Check if at least one valid mem-acc config. is specified */
  291. for (i = 0; i < MEMORY_MAX; i++) {
  292. if (mem_acc_vreg->mem_acc_supported[i])
  293. break;
  294. }
  295. if (i == MEMORY_MAX) {
  296. pr_err("No mem-acc configuration specified\n");
  297. return -EINVAL;
  298. }
  299. if (mem_acc_vreg->num_acc_en)
  300. mem_acc_en_init(mem_acc_vreg);
  301. rc = mem_acc_sel_init(mem_acc_vreg);
  302. if (rc) {
  303. pr_err("Unable to intialize mem_acc_sel reg rc=%d\n", rc);
  304. return rc;
  305. }
  306. return 0;
  307. }
  308. static int mem_acc_regulator_probe(struct platform_device *pdev)
  309. {
  310. struct mem_acc_regulator *mem_acc_vreg;
  311. struct regulator_desc *rdesc;
  312. struct regulator_init_data *init_data;
  313. int rc;
  314. if (!pdev->dev.of_node) {
  315. pr_err("Device tree node is missing\n");
  316. return -EINVAL;
  317. }
  318. init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
  319. if (!init_data) {
  320. pr_err("regulator init data is missing\n");
  321. return -EINVAL;
  322. } else {
  323. init_data->constraints.input_uV
  324. = init_data->constraints.max_uV;
  325. init_data->constraints.valid_ops_mask
  326. |= REGULATOR_CHANGE_VOLTAGE;
  327. }
  328. mem_acc_vreg = devm_kzalloc(&pdev->dev, sizeof(*mem_acc_vreg),
  329. GFP_KERNEL);
  330. if (!mem_acc_vreg) {
  331. pr_err("Can't allocate mem_acc_vreg memory\n");
  332. return -ENOMEM;
  333. }
  334. mem_acc_vreg->dev = &pdev->dev;
  335. rc = mem_acc_init(pdev, mem_acc_vreg);
  336. if (rc) {
  337. pr_err("Unable to initialize mem_acc configuration rc=%d\n",
  338. rc);
  339. return rc;
  340. }
  341. rdesc = &mem_acc_vreg->rdesc;
  342. rdesc->owner = THIS_MODULE;
  343. rdesc->type = REGULATOR_VOLTAGE;
  344. rdesc->ops = &mem_acc_corner_ops;
  345. rdesc->name = init_data->constraints.name;
  346. mem_acc_vreg->rdev = regulator_register(rdesc, &pdev->dev,
  347. init_data, mem_acc_vreg, pdev->dev.of_node);
  348. if (IS_ERR(mem_acc_vreg->rdev)) {
  349. rc = PTR_ERR(mem_acc_vreg->rdev);
  350. if (rc != -EPROBE_DEFER)
  351. pr_err("regulator_register failed: rc=%d\n", rc);
  352. return rc;
  353. }
  354. platform_set_drvdata(pdev, mem_acc_vreg);
  355. return 0;
  356. }
  357. static int mem_acc_regulator_remove(struct platform_device *pdev)
  358. {
  359. struct mem_acc_regulator *mem_acc_vreg = platform_get_drvdata(pdev);
  360. regulator_unregister(mem_acc_vreg->rdev);
  361. return 0;
  362. }
  363. static struct of_device_id mem_acc_regulator_match_table[] = {
  364. { .compatible = "qcom,mem-acc-regulator", },
  365. {}
  366. };
  367. static struct platform_driver mem_acc_regulator_driver = {
  368. .probe = mem_acc_regulator_probe,
  369. .remove = mem_acc_regulator_remove,
  370. .driver = {
  371. .name = "qcom,mem-acc-regulator",
  372. .of_match_table = mem_acc_regulator_match_table,
  373. .owner = THIS_MODULE,
  374. },
  375. };
  376. int __init mem_acc_regulator_init(void)
  377. {
  378. return platform_driver_register(&mem_acc_regulator_driver);
  379. }
  380. postcore_initcall(mem_acc_regulator_init);
  381. static void __exit mem_acc_regulator_exit(void)
  382. {
  383. platform_driver_unregister(&mem_acc_regulator_driver);
  384. }
  385. module_exit(mem_acc_regulator_exit);
  386. MODULE_DESCRIPTION("MEM-ACC-SEL regulator driver");
  387. MODULE_LICENSE("GPL v2");