exynos5_bus.c 11 KB

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