tegra186-emc.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2019 NVIDIA CORPORATION. All rights reserved.
  4. */
  5. #include <linux/clk.h>
  6. #include <linux/debugfs.h>
  7. #include <linux/module.h>
  8. #include <linux/mod_devicetable.h>
  9. #include <linux/platform_device.h>
  10. #include <soc/tegra/bpmp.h>
  11. struct tegra186_emc_dvfs {
  12. unsigned long latency;
  13. unsigned long rate;
  14. };
  15. struct tegra186_emc {
  16. struct tegra_bpmp *bpmp;
  17. struct device *dev;
  18. struct clk *clk;
  19. struct tegra186_emc_dvfs *dvfs;
  20. unsigned int num_dvfs;
  21. struct {
  22. struct dentry *root;
  23. unsigned long min_rate;
  24. unsigned long max_rate;
  25. } debugfs;
  26. };
  27. /*
  28. * debugfs interface
  29. *
  30. * The memory controller driver exposes some files in debugfs that can be used
  31. * to control the EMC frequency. The top-level directory can be found here:
  32. *
  33. * /sys/kernel/debug/emc
  34. *
  35. * It contains the following files:
  36. *
  37. * - available_rates: This file contains a list of valid, space-separated
  38. * EMC frequencies.
  39. *
  40. * - min_rate: Writing a value to this file sets the given frequency as the
  41. * floor of the permitted range. If this is higher than the currently
  42. * configured EMC frequency, this will cause the frequency to be
  43. * increased so that it stays within the valid range.
  44. *
  45. * - max_rate: Similarily to the min_rate file, writing a value to this file
  46. * sets the given frequency as the ceiling of the permitted range. If
  47. * the value is lower than the currently configured EMC frequency, this
  48. * will cause the frequency to be decreased so that it stays within the
  49. * valid range.
  50. */
  51. static bool tegra186_emc_validate_rate(struct tegra186_emc *emc,
  52. unsigned long rate)
  53. {
  54. unsigned int i;
  55. for (i = 0; i < emc->num_dvfs; i++)
  56. if (rate == emc->dvfs[i].rate)
  57. return true;
  58. return false;
  59. }
  60. static int tegra186_emc_debug_available_rates_show(struct seq_file *s,
  61. void *data)
  62. {
  63. struct tegra186_emc *emc = s->private;
  64. const char *prefix = "";
  65. unsigned int i;
  66. for (i = 0; i < emc->num_dvfs; i++) {
  67. seq_printf(s, "%s%lu", prefix, emc->dvfs[i].rate);
  68. prefix = " ";
  69. }
  70. seq_puts(s, "\n");
  71. return 0;
  72. }
  73. static int tegra186_emc_debug_available_rates_open(struct inode *inode,
  74. struct file *file)
  75. {
  76. return single_open(file, tegra186_emc_debug_available_rates_show,
  77. inode->i_private);
  78. }
  79. static const struct file_operations tegra186_emc_debug_available_rates_fops = {
  80. .open = tegra186_emc_debug_available_rates_open,
  81. .read = seq_read,
  82. .llseek = seq_lseek,
  83. .release = single_release,
  84. };
  85. static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate)
  86. {
  87. struct tegra186_emc *emc = data;
  88. *rate = emc->debugfs.min_rate;
  89. return 0;
  90. }
  91. static int tegra186_emc_debug_min_rate_set(void *data, u64 rate)
  92. {
  93. struct tegra186_emc *emc = data;
  94. int err;
  95. if (!tegra186_emc_validate_rate(emc, rate))
  96. return -EINVAL;
  97. err = clk_set_min_rate(emc->clk, rate);
  98. if (err < 0)
  99. return err;
  100. emc->debugfs.min_rate = rate;
  101. return 0;
  102. }
  103. DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_min_rate_fops,
  104. tegra186_emc_debug_min_rate_get,
  105. tegra186_emc_debug_min_rate_set, "%llu\n");
  106. static int tegra186_emc_debug_max_rate_get(void *data, u64 *rate)
  107. {
  108. struct tegra186_emc *emc = data;
  109. *rate = emc->debugfs.max_rate;
  110. return 0;
  111. }
  112. static int tegra186_emc_debug_max_rate_set(void *data, u64 rate)
  113. {
  114. struct tegra186_emc *emc = data;
  115. int err;
  116. if (!tegra186_emc_validate_rate(emc, rate))
  117. return -EINVAL;
  118. err = clk_set_max_rate(emc->clk, rate);
  119. if (err < 0)
  120. return err;
  121. emc->debugfs.max_rate = rate;
  122. return 0;
  123. }
  124. DEFINE_DEBUGFS_ATTRIBUTE(tegra186_emc_debug_max_rate_fops,
  125. tegra186_emc_debug_max_rate_get,
  126. tegra186_emc_debug_max_rate_set, "%llu\n");
  127. static int tegra186_emc_probe(struct platform_device *pdev)
  128. {
  129. struct mrq_emc_dvfs_latency_response response;
  130. struct tegra_bpmp_message msg;
  131. struct tegra186_emc *emc;
  132. unsigned int i;
  133. int err;
  134. emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
  135. if (!emc)
  136. return -ENOMEM;
  137. emc->bpmp = tegra_bpmp_get(&pdev->dev);
  138. if (IS_ERR(emc->bpmp))
  139. return dev_err_probe(&pdev->dev, PTR_ERR(emc->bpmp), "failed to get BPMP\n");
  140. emc->clk = devm_clk_get(&pdev->dev, "emc");
  141. if (IS_ERR(emc->clk)) {
  142. err = PTR_ERR(emc->clk);
  143. dev_err(&pdev->dev, "failed to get EMC clock: %d\n", err);
  144. goto put_bpmp;
  145. }
  146. platform_set_drvdata(pdev, emc);
  147. emc->dev = &pdev->dev;
  148. memset(&msg, 0, sizeof(msg));
  149. msg.mrq = MRQ_EMC_DVFS_LATENCY;
  150. msg.tx.data = NULL;
  151. msg.tx.size = 0;
  152. msg.rx.data = &response;
  153. msg.rx.size = sizeof(response);
  154. err = tegra_bpmp_transfer(emc->bpmp, &msg);
  155. if (err < 0) {
  156. dev_err(&pdev->dev, "failed to EMC DVFS pairs: %d\n", err);
  157. goto put_bpmp;
  158. }
  159. if (msg.rx.ret < 0) {
  160. err = -EINVAL;
  161. dev_err(&pdev->dev, "EMC DVFS MRQ failed: %d (BPMP error code)\n", msg.rx.ret);
  162. goto put_bpmp;
  163. }
  164. emc->debugfs.min_rate = ULONG_MAX;
  165. emc->debugfs.max_rate = 0;
  166. emc->num_dvfs = response.num_pairs;
  167. emc->dvfs = devm_kmalloc_array(&pdev->dev, emc->num_dvfs,
  168. sizeof(*emc->dvfs), GFP_KERNEL);
  169. if (!emc->dvfs) {
  170. err = -ENOMEM;
  171. goto put_bpmp;
  172. }
  173. dev_dbg(&pdev->dev, "%u DVFS pairs:\n", emc->num_dvfs);
  174. for (i = 0; i < emc->num_dvfs; i++) {
  175. emc->dvfs[i].rate = response.pairs[i].freq * 1000;
  176. emc->dvfs[i].latency = response.pairs[i].latency;
  177. if (emc->dvfs[i].rate < emc->debugfs.min_rate)
  178. emc->debugfs.min_rate = emc->dvfs[i].rate;
  179. if (emc->dvfs[i].rate > emc->debugfs.max_rate)
  180. emc->debugfs.max_rate = emc->dvfs[i].rate;
  181. dev_dbg(&pdev->dev, " %2u: %lu Hz -> %lu us\n", i,
  182. emc->dvfs[i].rate, emc->dvfs[i].latency);
  183. }
  184. err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
  185. emc->debugfs.max_rate);
  186. if (err < 0) {
  187. dev_err(&pdev->dev,
  188. "failed to set rate range [%lu-%lu] for %pC\n",
  189. emc->debugfs.min_rate, emc->debugfs.max_rate,
  190. emc->clk);
  191. goto put_bpmp;
  192. }
  193. emc->debugfs.root = debugfs_create_dir("emc", NULL);
  194. debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root,
  195. emc, &tegra186_emc_debug_available_rates_fops);
  196. debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
  197. emc, &tegra186_emc_debug_min_rate_fops);
  198. debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
  199. emc, &tegra186_emc_debug_max_rate_fops);
  200. return 0;
  201. put_bpmp:
  202. tegra_bpmp_put(emc->bpmp);
  203. return err;
  204. }
  205. static int tegra186_emc_remove(struct platform_device *pdev)
  206. {
  207. struct tegra186_emc *emc = platform_get_drvdata(pdev);
  208. debugfs_remove_recursive(emc->debugfs.root);
  209. tegra_bpmp_put(emc->bpmp);
  210. return 0;
  211. }
  212. static const struct of_device_id tegra186_emc_of_match[] = {
  213. #if defined(CONFIG_ARCH_TEGRA_186_SOC)
  214. { .compatible = "nvidia,tegra186-emc" },
  215. #endif
  216. #if defined(CONFIG_ARCH_TEGRA_194_SOC)
  217. { .compatible = "nvidia,tegra194-emc" },
  218. #endif
  219. #if defined(CONFIG_ARCH_TEGRA_234_SOC)
  220. { .compatible = "nvidia,tegra234-emc" },
  221. #endif
  222. { /* sentinel */ }
  223. };
  224. MODULE_DEVICE_TABLE(of, tegra186_emc_of_match);
  225. static struct platform_driver tegra186_emc_driver = {
  226. .driver = {
  227. .name = "tegra186-emc",
  228. .of_match_table = tegra186_emc_of_match,
  229. .suppress_bind_attrs = true,
  230. },
  231. .probe = tegra186_emc_probe,
  232. .remove = tegra186_emc_remove,
  233. };
  234. module_platform_driver(tegra186_emc_driver);
  235. MODULE_AUTHOR("Thierry Reding <[email protected]>");
  236. MODULE_DESCRIPTION("NVIDIA Tegra186 External Memory Controller driver");
  237. MODULE_LICENSE("GPL v2");