exynos5_bus.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /*
  2. * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  3. * http://www.samsung.com/
  4. *
  5. * EXYNOS5 INT clock frequency scaling support using DEVFREQ framework
  6. * Based on work done by Jonghwan Choi <jhbird.choi@samsung.com>
  7. * Support for only EXYNOS5250 is present.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. *
  13. */
  14. #include <linux/module.h>
  15. #include <linux/devfreq.h>
  16. #include <linux/io.h>
  17. #include <linux/pm_opp.h>
  18. #include <linux/slab.h>
  19. #include <linux/suspend.h>
  20. #include <linux/clk.h>
  21. #include <linux/delay.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/pm_qos.h>
  24. #include <linux/regulator/consumer.h>
  25. #include <linux/of_address.h>
  26. #include <linux/of_platform.h>
  27. #include "exynos_ppmu.h"
  28. #define MAX_SAFEVOLT 1100000 /* 1.10V */
  29. /* Assume that the bus is saturated if the utilization is 25% */
  30. #define INT_BUS_SATURATION_RATIO 25
  31. enum int_level_idx {
  32. LV_0,
  33. LV_1,
  34. LV_2,
  35. LV_3,
  36. LV_4,
  37. _LV_END
  38. };
  39. enum exynos_ppmu_list {
  40. PPMU_RIGHT,
  41. PPMU_END,
  42. };
  43. struct busfreq_data_int {
  44. struct device *dev;
  45. struct devfreq *devfreq;
  46. struct regulator *vdd_int;
  47. struct exynos_ppmu ppmu[PPMU_END];
  48. unsigned long curr_freq;
  49. bool disabled;
  50. struct notifier_block pm_notifier;
  51. struct mutex lock;
  52. struct pm_qos_request int_req;
  53. struct clk *int_clk;
  54. };
  55. struct int_bus_opp_table {
  56. unsigned int idx;
  57. unsigned long clk;
  58. unsigned long volt;
  59. };
  60. static struct int_bus_opp_table exynos5_int_opp_table[] = {
  61. {LV_0, 266000, 1025000},
  62. {LV_1, 200000, 1025000},
  63. {LV_2, 160000, 1025000},
  64. {LV_3, 133000, 1025000},
  65. {LV_4, 100000, 1025000},
  66. {0, 0, 0},
  67. };
  68. static void busfreq_mon_reset(struct busfreq_data_int *data)
  69. {
  70. unsigned int i;
  71. for (i = PPMU_RIGHT; i < PPMU_END; i++) {
  72. void __iomem *ppmu_base = data->ppmu[i].hw_base;
  73. /* Reset the performance and cycle counters */
  74. exynos_ppmu_reset(ppmu_base);
  75. /* Setup count registers to monitor read/write transactions */
  76. data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
  77. exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
  78. data->ppmu[i].event[PPMU_PMNCNT3]);
  79. exynos_ppmu_start(ppmu_base);
  80. }
  81. }
  82. static void exynos5_read_ppmu(struct busfreq_data_int *data)
  83. {
  84. int i, j;
  85. for (i = PPMU_RIGHT; i < PPMU_END; i++) {
  86. void __iomem *ppmu_base = data->ppmu[i].hw_base;
  87. exynos_ppmu_stop(ppmu_base);
  88. /* Update local data from PPMU */
  89. data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
  90. for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
  91. if (data->ppmu[i].event[j] == 0)
  92. data->ppmu[i].count[j] = 0;
  93. else
  94. data->ppmu[i].count[j] =
  95. exynos_ppmu_read(ppmu_base, j);
  96. }
  97. }
  98. busfreq_mon_reset(data);
  99. }
  100. static int exynos5_int_setvolt(struct busfreq_data_int *data,
  101. unsigned long volt)
  102. {
  103. return regulator_set_voltage(data->vdd_int, volt, MAX_SAFEVOLT);
  104. }
  105. static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq,
  106. u32 flags)
  107. {
  108. int err = 0;
  109. struct platform_device *pdev = container_of(dev, struct platform_device,
  110. dev);
  111. struct busfreq_data_int *data = platform_get_drvdata(pdev);
  112. struct dev_pm_opp *opp;
  113. unsigned long old_freq, freq;
  114. unsigned long volt;
  115. rcu_read_lock();
  116. opp = devfreq_recommended_opp(dev, _freq, flags);
  117. if (IS_ERR(opp)) {
  118. rcu_read_unlock();
  119. dev_err(dev, "%s: Invalid OPP.\n", __func__);
  120. return PTR_ERR(opp);
  121. }
  122. freq = dev_pm_opp_get_freq(opp);
  123. volt = dev_pm_opp_get_voltage(opp);
  124. rcu_read_unlock();
  125. old_freq = data->curr_freq;
  126. if (old_freq == freq)
  127. return 0;
  128. dev_dbg(dev, "targetting %lukHz %luuV\n", freq, volt);
  129. mutex_lock(&data->lock);
  130. if (data->disabled)
  131. goto out;
  132. if (freq > exynos5_int_opp_table[0].clk)
  133. pm_qos_update_request(&data->int_req, freq * 16 / 1000);
  134. else
  135. pm_qos_update_request(&data->int_req, -1);
  136. if (old_freq < freq)
  137. err = exynos5_int_setvolt(data, volt);
  138. if (err)
  139. goto out;
  140. err = clk_set_rate(data->int_clk, freq * 1000);
  141. if (err)
  142. goto out;
  143. if (old_freq > freq)
  144. err = exynos5_int_setvolt(data, volt);
  145. if (err)
  146. goto out;
  147. data->curr_freq = freq;
  148. out:
  149. mutex_unlock(&data->lock);
  150. return err;
  151. }
  152. static int exynos5_get_busier_dmc(struct busfreq_data_int *data)
  153. {
  154. int i, j;
  155. int busy = 0;
  156. unsigned int temp = 0;
  157. for (i = PPMU_RIGHT; i < PPMU_END; i++) {
  158. for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
  159. if (data->ppmu[i].count[j] > temp) {
  160. temp = data->ppmu[i].count[j];
  161. busy = i;
  162. }
  163. }
  164. }
  165. return busy;
  166. }
  167. static int exynos5_int_get_dev_status(struct device *dev,
  168. struct devfreq_dev_status *stat)
  169. {
  170. struct platform_device *pdev = container_of(dev, struct platform_device,
  171. dev);
  172. struct busfreq_data_int *data = platform_get_drvdata(pdev);
  173. int busier_dmc;
  174. exynos5_read_ppmu(data);
  175. busier_dmc = exynos5_get_busier_dmc(data);
  176. stat->current_frequency = data->curr_freq;
  177. /* Number of cycles spent on memory access */
  178. stat->busy_time = data->ppmu[busier_dmc].count[PPMU_PMNCNT3];
  179. stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO;
  180. stat->total_time = data->ppmu[busier_dmc].ccnt;
  181. return 0;
  182. }
  183. static void exynos5_int_exit(struct device *dev)
  184. {
  185. struct platform_device *pdev = container_of(dev, struct platform_device,
  186. dev);
  187. struct busfreq_data_int *data = platform_get_drvdata(pdev);
  188. devfreq_unregister_opp_notifier(dev, data->devfreq);
  189. }
  190. static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
  191. .initial_freq = 160000,
  192. .polling_ms = 100,
  193. .target = exynos5_busfreq_int_target,
  194. .get_dev_status = exynos5_int_get_dev_status,
  195. .exit = exynos5_int_exit,
  196. };
  197. static int exynos5250_init_int_tables(struct busfreq_data_int *data)
  198. {
  199. int i, err = 0;
  200. for (i = LV_0; i < _LV_END; i++) {
  201. err = dev_pm_opp_add(data->dev, exynos5_int_opp_table[i].clk,
  202. exynos5_int_opp_table[i].volt);
  203. if (err) {
  204. dev_err(data->dev, "Cannot add opp entries.\n");
  205. return err;
  206. }
  207. }
  208. return 0;
  209. }
  210. static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this,
  211. unsigned long event, void *ptr)
  212. {
  213. struct busfreq_data_int *data = container_of(this,
  214. struct busfreq_data_int, pm_notifier);
  215. struct dev_pm_opp *opp;
  216. unsigned long maxfreq = ULONG_MAX;
  217. unsigned long freq;
  218. unsigned long volt;
  219. int err = 0;
  220. switch (event) {
  221. case PM_SUSPEND_PREPARE:
  222. /* Set Fastest and Deactivate DVFS */
  223. mutex_lock(&data->lock);
  224. data->disabled = true;
  225. rcu_read_lock();
  226. opp = dev_pm_opp_find_freq_floor(data->dev, &maxfreq);
  227. if (IS_ERR(opp)) {
  228. rcu_read_unlock();
  229. err = PTR_ERR(opp);
  230. goto unlock;
  231. }
  232. freq = dev_pm_opp_get_freq(opp);
  233. volt = dev_pm_opp_get_voltage(opp);
  234. rcu_read_unlock();
  235. err = exynos5_int_setvolt(data, volt);
  236. if (err)
  237. goto unlock;
  238. err = clk_set_rate(data->int_clk, freq * 1000);
  239. if (err)
  240. goto unlock;
  241. data->curr_freq = freq;
  242. unlock:
  243. mutex_unlock(&data->lock);
  244. if (err)
  245. return NOTIFY_BAD;
  246. return NOTIFY_OK;
  247. case PM_POST_RESTORE:
  248. case PM_POST_SUSPEND:
  249. /* Reactivate */
  250. mutex_lock(&data->lock);
  251. data->disabled = false;
  252. mutex_unlock(&data->lock);
  253. return NOTIFY_OK;
  254. }
  255. return NOTIFY_DONE;
  256. }
  257. static int exynos5_busfreq_int_probe(struct platform_device *pdev)
  258. {
  259. struct busfreq_data_int *data;
  260. struct dev_pm_opp *opp;
  261. struct device *dev = &pdev->dev;
  262. struct device_node *np;
  263. unsigned long initial_freq;
  264. unsigned long initial_volt;
  265. int err = 0;
  266. int i;
  267. data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data_int),
  268. GFP_KERNEL);
  269. if (data == NULL) {
  270. dev_err(dev, "Cannot allocate memory.\n");
  271. return -ENOMEM;
  272. }
  273. np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu");
  274. if (np == NULL) {
  275. pr_err("Unable to find PPMU node\n");
  276. return -ENOENT;
  277. }
  278. for (i = PPMU_RIGHT; i < PPMU_END; i++) {
  279. /* map PPMU memory region */
  280. data->ppmu[i].hw_base = of_iomap(np, i);
  281. if (data->ppmu[i].hw_base == NULL) {
  282. dev_err(&pdev->dev, "failed to map memory region\n");
  283. return -ENOMEM;
  284. }
  285. }
  286. data->pm_notifier.notifier_call = exynos5_busfreq_int_pm_notifier_event;
  287. data->dev = dev;
  288. mutex_init(&data->lock);
  289. err = exynos5250_init_int_tables(data);
  290. if (err)
  291. goto err_regulator;
  292. data->vdd_int = regulator_get(dev, "vdd_int");
  293. if (IS_ERR(data->vdd_int)) {
  294. dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
  295. err = PTR_ERR(data->vdd_int);
  296. goto err_regulator;
  297. }
  298. data->int_clk = clk_get(dev, "int_clk");
  299. if (IS_ERR(data->int_clk)) {
  300. dev_err(dev, "Cannot get clock \"int_clk\"\n");
  301. err = PTR_ERR(data->int_clk);
  302. goto err_clock;
  303. }
  304. rcu_read_lock();
  305. opp = dev_pm_opp_find_freq_floor(dev,
  306. &exynos5_devfreq_int_profile.initial_freq);
  307. if (IS_ERR(opp)) {
  308. rcu_read_unlock();
  309. dev_err(dev, "Invalid initial frequency %lu kHz.\n",
  310. exynos5_devfreq_int_profile.initial_freq);
  311. err = PTR_ERR(opp);
  312. goto err_opp_add;
  313. }
  314. initial_freq = dev_pm_opp_get_freq(opp);
  315. initial_volt = dev_pm_opp_get_voltage(opp);
  316. rcu_read_unlock();
  317. data->curr_freq = initial_freq;
  318. err = clk_set_rate(data->int_clk, initial_freq * 1000);
  319. if (err) {
  320. dev_err(dev, "Failed to set initial frequency\n");
  321. goto err_opp_add;
  322. }
  323. err = exynos5_int_setvolt(data, initial_volt);
  324. if (err)
  325. goto err_opp_add;
  326. platform_set_drvdata(pdev, data);
  327. busfreq_mon_reset(data);
  328. data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
  329. "simple_ondemand", NULL);
  330. if (IS_ERR(data->devfreq)) {
  331. err = PTR_ERR(data->devfreq);
  332. goto err_devfreq_add;
  333. }
  334. devfreq_register_opp_notifier(dev, data->devfreq);
  335. err = register_pm_notifier(&data->pm_notifier);
  336. if (err) {
  337. dev_err(dev, "Failed to setup pm notifier\n");
  338. goto err_devfreq_add;
  339. }
  340. /* TODO: Add a new QOS class for int/mif bus */
  341. pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);
  342. return 0;
  343. err_devfreq_add:
  344. devfreq_remove_device(data->devfreq);
  345. platform_set_drvdata(pdev, NULL);
  346. err_opp_add:
  347. clk_put(data->int_clk);
  348. err_clock:
  349. regulator_put(data->vdd_int);
  350. err_regulator:
  351. return err;
  352. }
  353. static int exynos5_busfreq_int_remove(struct platform_device *pdev)
  354. {
  355. struct busfreq_data_int *data = platform_get_drvdata(pdev);
  356. pm_qos_remove_request(&data->int_req);
  357. unregister_pm_notifier(&data->pm_notifier);
  358. devfreq_remove_device(data->devfreq);
  359. regulator_put(data->vdd_int);
  360. clk_put(data->int_clk);
  361. platform_set_drvdata(pdev, NULL);
  362. return 0;
  363. }
  364. static int exynos5_busfreq_int_resume(struct device *dev)
  365. {
  366. struct platform_device *pdev = container_of(dev, struct platform_device,
  367. dev);
  368. struct busfreq_data_int *data = platform_get_drvdata(pdev);
  369. busfreq_mon_reset(data);
  370. return 0;
  371. }
  372. static const struct dev_pm_ops exynos5_busfreq_int_pm = {
  373. .resume = exynos5_busfreq_int_resume,
  374. };
  375. /* platform device pointer for exynos5 devfreq device. */
  376. static struct platform_device *exynos5_devfreq_pdev;
  377. static struct platform_driver exynos5_busfreq_int_driver = {
  378. .probe = exynos5_busfreq_int_probe,
  379. .remove = exynos5_busfreq_int_remove,
  380. .driver = {
  381. .name = "exynos5-bus-int",
  382. .owner = THIS_MODULE,
  383. .pm = &exynos5_busfreq_int_pm,
  384. },
  385. };
  386. static int __init exynos5_busfreq_int_init(void)
  387. {
  388. int ret;
  389. ret = platform_driver_register(&exynos5_busfreq_int_driver);
  390. if (ret < 0)
  391. goto out;
  392. exynos5_devfreq_pdev =
  393. platform_device_register_simple("exynos5-bus-int", -1, NULL, 0);
  394. if (IS_ERR_OR_NULL(exynos5_devfreq_pdev)) {
  395. ret = PTR_ERR(exynos5_devfreq_pdev);
  396. goto out1;
  397. }
  398. return 0;
  399. out1:
  400. platform_driver_unregister(&exynos5_busfreq_int_driver);
  401. out:
  402. return ret;
  403. }
  404. late_initcall(exynos5_busfreq_int_init);
  405. static void __exit exynos5_busfreq_int_exit(void)
  406. {
  407. platform_device_unregister(exynos5_devfreq_pdev);
  408. platform_driver_unregister(&exynos5_busfreq_int_driver);
  409. }
  410. module_exit(exynos5_busfreq_int_exit);
  411. MODULE_LICENSE("GPL");
  412. MODULE_DESCRIPTION("EXYNOS5 busfreq driver with devfreq framework");