st_remoteproc.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. * ST's Remote Processor Control Driver
  3. *
  4. * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
  5. *
  6. * Author: Ludovic Barre <ludovic.barre@st.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/clk.h>
  13. #include <linux/dma-mapping.h>
  14. #include <linux/err.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/kernel.h>
  17. #include <linux/mfd/syscon.h>
  18. #include <linux/module.h>
  19. #include <linux/of.h>
  20. #include <linux/of_device.h>
  21. #include <linux/of_reserved_mem.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/regmap.h>
  24. #include <linux/remoteproc.h>
  25. #include <linux/reset.h>
  26. struct st_rproc_config {
  27. bool sw_reset;
  28. bool pwr_reset;
  29. unsigned long bootaddr_mask;
  30. };
  31. struct st_rproc {
  32. struct st_rproc_config *config;
  33. struct reset_control *sw_reset;
  34. struct reset_control *pwr_reset;
  35. struct clk *clk;
  36. u32 clk_rate;
  37. struct regmap *boot_base;
  38. u32 boot_offset;
  39. };
  40. static int st_rproc_start(struct rproc *rproc)
  41. {
  42. struct st_rproc *ddata = rproc->priv;
  43. int err;
  44. regmap_update_bits(ddata->boot_base, ddata->boot_offset,
  45. ddata->config->bootaddr_mask, rproc->bootaddr);
  46. err = clk_enable(ddata->clk);
  47. if (err) {
  48. dev_err(&rproc->dev, "Failed to enable clock\n");
  49. return err;
  50. }
  51. if (ddata->config->sw_reset) {
  52. err = reset_control_deassert(ddata->sw_reset);
  53. if (err) {
  54. dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
  55. goto sw_reset_fail;
  56. }
  57. }
  58. if (ddata->config->pwr_reset) {
  59. err = reset_control_deassert(ddata->pwr_reset);
  60. if (err) {
  61. dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
  62. goto pwr_reset_fail;
  63. }
  64. }
  65. dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
  66. return 0;
  67. pwr_reset_fail:
  68. if (ddata->config->pwr_reset)
  69. reset_control_assert(ddata->sw_reset);
  70. sw_reset_fail:
  71. clk_disable(ddata->clk);
  72. return err;
  73. }
  74. static int st_rproc_stop(struct rproc *rproc)
  75. {
  76. struct st_rproc *ddata = rproc->priv;
  77. int sw_err = 0, pwr_err = 0;
  78. if (ddata->config->sw_reset) {
  79. sw_err = reset_control_assert(ddata->sw_reset);
  80. if (sw_err)
  81. dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
  82. }
  83. if (ddata->config->pwr_reset) {
  84. pwr_err = reset_control_assert(ddata->pwr_reset);
  85. if (pwr_err)
  86. dev_err(&rproc->dev, "Failed to assert Power Reset\n");
  87. }
  88. clk_disable(ddata->clk);
  89. return sw_err ?: pwr_err;
  90. }
  91. static struct rproc_ops st_rproc_ops = {
  92. .start = st_rproc_start,
  93. .stop = st_rproc_stop,
  94. };
  95. /*
  96. * Fetch state of the processor: 0 is off, 1 is on.
  97. */
  98. static int st_rproc_state(struct platform_device *pdev)
  99. {
  100. struct rproc *rproc = platform_get_drvdata(pdev);
  101. struct st_rproc *ddata = rproc->priv;
  102. int reset_sw = 0, reset_pwr = 0;
  103. if (ddata->config->sw_reset)
  104. reset_sw = reset_control_status(ddata->sw_reset);
  105. if (ddata->config->pwr_reset)
  106. reset_pwr = reset_control_status(ddata->pwr_reset);
  107. if (reset_sw < 0 || reset_pwr < 0)
  108. return -EINVAL;
  109. return !reset_sw && !reset_pwr;
  110. }
  111. static const struct st_rproc_config st40_rproc_cfg = {
  112. .sw_reset = true,
  113. .pwr_reset = true,
  114. .bootaddr_mask = GENMASK(28, 1),
  115. };
  116. static const struct st_rproc_config st231_rproc_cfg = {
  117. .sw_reset = true,
  118. .pwr_reset = false,
  119. .bootaddr_mask = GENMASK(31, 6),
  120. };
  121. static const struct of_device_id st_rproc_match[] = {
  122. { .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
  123. { .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
  124. {},
  125. };
  126. MODULE_DEVICE_TABLE(of, st_rproc_match);
  127. static int st_rproc_parse_dt(struct platform_device *pdev)
  128. {
  129. struct device *dev = &pdev->dev;
  130. struct rproc *rproc = platform_get_drvdata(pdev);
  131. struct st_rproc *ddata = rproc->priv;
  132. struct device_node *np = dev->of_node;
  133. int err;
  134. if (ddata->config->sw_reset) {
  135. ddata->sw_reset = devm_reset_control_get(dev, "sw_reset");
  136. if (IS_ERR(ddata->sw_reset)) {
  137. dev_err(dev, "Failed to get S/W Reset\n");
  138. return PTR_ERR(ddata->sw_reset);
  139. }
  140. }
  141. if (ddata->config->pwr_reset) {
  142. ddata->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
  143. if (IS_ERR(ddata->pwr_reset)) {
  144. dev_err(dev, "Failed to get Power Reset\n");
  145. return PTR_ERR(ddata->pwr_reset);
  146. }
  147. }
  148. ddata->clk = devm_clk_get(dev, NULL);
  149. if (IS_ERR(ddata->clk)) {
  150. dev_err(dev, "Failed to get clock\n");
  151. return PTR_ERR(ddata->clk);
  152. }
  153. err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
  154. if (err) {
  155. dev_err(dev, "failed to get clock frequency\n");
  156. return err;
  157. }
  158. ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
  159. if (IS_ERR(ddata->boot_base)) {
  160. dev_err(dev, "Boot base not found\n");
  161. return PTR_ERR(ddata->boot_base);
  162. }
  163. err = of_property_read_u32_index(np, "st,syscfg", 1,
  164. &ddata->boot_offset);
  165. if (err) {
  166. dev_err(dev, "Boot offset not found\n");
  167. return -EINVAL;
  168. }
  169. err = of_reserved_mem_device_init(dev);
  170. if (err) {
  171. dev_err(dev, "Failed to obtain shared memory\n");
  172. return err;
  173. }
  174. err = clk_prepare(ddata->clk);
  175. if (err)
  176. dev_err(dev, "failed to get clock\n");
  177. return err;
  178. }
  179. static int st_rproc_probe(struct platform_device *pdev)
  180. {
  181. struct device *dev = &pdev->dev;
  182. const struct of_device_id *match;
  183. struct st_rproc *ddata;
  184. struct device_node *np = dev->of_node;
  185. struct rproc *rproc;
  186. int enabled;
  187. int ret;
  188. match = of_match_device(st_rproc_match, dev);
  189. if (!match || !match->data) {
  190. dev_err(dev, "No device match found\n");
  191. return -ENODEV;
  192. }
  193. rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
  194. if (!rproc)
  195. return -ENOMEM;
  196. rproc->has_iommu = false;
  197. ddata = rproc->priv;
  198. ddata->config = (struct st_rproc_config *)match->data;
  199. platform_set_drvdata(pdev, rproc);
  200. ret = st_rproc_parse_dt(pdev);
  201. if (ret)
  202. goto free_rproc;
  203. enabled = st_rproc_state(pdev);
  204. if (enabled < 0) {
  205. ret = enabled;
  206. goto free_rproc;
  207. }
  208. if (enabled) {
  209. atomic_inc(&rproc->power);
  210. rproc->state = RPROC_RUNNING;
  211. } else {
  212. clk_set_rate(ddata->clk, ddata->clk_rate);
  213. }
  214. ret = rproc_add(rproc);
  215. if (ret)
  216. goto free_rproc;
  217. return 0;
  218. free_rproc:
  219. rproc_free(rproc);
  220. return ret;
  221. }
  222. static int st_rproc_remove(struct platform_device *pdev)
  223. {
  224. struct rproc *rproc = platform_get_drvdata(pdev);
  225. struct st_rproc *ddata = rproc->priv;
  226. rproc_del(rproc);
  227. clk_disable_unprepare(ddata->clk);
  228. of_reserved_mem_device_release(&pdev->dev);
  229. rproc_free(rproc);
  230. return 0;
  231. }
  232. static struct platform_driver st_rproc_driver = {
  233. .probe = st_rproc_probe,
  234. .remove = st_rproc_remove,
  235. .driver = {
  236. .name = "st-rproc",
  237. .of_match_table = of_match_ptr(st_rproc_match),
  238. },
  239. };
  240. module_platform_driver(st_rproc_driver);
  241. MODULE_DESCRIPTION("ST Remote Processor Control Driver");
  242. MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
  243. MODULE_LICENSE("GPL v2");