qcom_spss.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. * Qualcomm Technologies, Inc. SPSS Peripheral Image Loader
  6. *
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/firmware.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/of_address.h>
  14. #include <linux/of_device.h>
  15. #include <linux/io.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/qcom_scm.h>
  18. #include <linux/regulator/consumer.h>
  19. #include <linux/remoteproc.h>
  20. #include <linux/remoteproc/qcom_spss.h>
  21. #include <linux/rpmsg/qcom_glink.h>
  22. #include <linux/soc/qcom/mdt_loader.h>
  23. #include "qcom_common.h"
  24. #include "remoteproc_internal.h"
  25. #define ERR_READY 0
  26. #define PBL_DONE 1
  27. #define SPSS_WDOG_ERR 0x44554d50
  28. #define SPSS_TIMEOUT 5000
  29. /* err_status definitions */
  30. #define PBL_LOG_VALUE (0xef000000)
  31. #define PBL_LOG_MASK (0xff000000)
  32. #define to_glink_subdev(d) container_of(d, struct qcom_rproc_glink, subdev)
  33. #define SP_SCSR_MB0_SP2CL_GP0_ADDR 0x1886020
  34. #define SP_SCSR_MB1_SP2CL_GP0_ADDR 0x1888020
  35. #define SP_SCSR_MB3_SP2CL_GP0_ADDR 0x188C020
  36. #define NUM_OF_DEBUG_REGISTERS_READ 0x3
  37. struct spss_data {
  38. const char *firmware_name;
  39. int pas_id;
  40. const char *ssr_name;
  41. bool auto_boot;
  42. const char *qmp_name;
  43. };
  44. struct qcom_spss {
  45. struct device *dev;
  46. struct rproc *rproc;
  47. struct clk *xo;
  48. struct reg_info cx;
  49. int pas_id;
  50. struct completion start_done;
  51. phys_addr_t mem_phys;
  52. phys_addr_t mem_reloc;
  53. void *mem_region;
  54. size_t mem_size;
  55. int generic_irq;
  56. const char *qmp_name;
  57. struct qmp *qmp;
  58. struct qcom_rproc_glink glink_subdev;
  59. struct qcom_rproc_ssr ssr_subdev;
  60. struct qcom_sysmon *sysmon_subdev;
  61. void __iomem *irq_status;
  62. void __iomem *irq_clr;
  63. void __iomem *irq_mask;
  64. void __iomem *err_status;
  65. void __iomem *err_status_spare;
  66. void __iomem *rmb_gpm;
  67. u32 bits_arr[2];
  68. };
  69. static void read_sp2cl_debug_registers(struct qcom_spss *spss);
  70. static void read_sp2cl_debug_registers(struct qcom_spss *spss)
  71. {
  72. uint32_t iter;
  73. void __iomem *addr = NULL;
  74. uint32_t debug_register_addr[NUM_OF_DEBUG_REGISTERS_READ] = {SP_SCSR_MB0_SP2CL_GP0_ADDR,
  75. SP_SCSR_MB1_SP2CL_GP0_ADDR, SP_SCSR_MB3_SP2CL_GP0_ADDR};
  76. for (iter = 0; iter < NUM_OF_DEBUG_REGISTERS_READ; iter++) {
  77. addr = ioremap(debug_register_addr[iter], sizeof(uint32_t)*2);
  78. if (!addr) {
  79. dev_err(spss->dev, "Iteration: [0x%x], addr: [0x%x]\n", iter, addr);
  80. continue;
  81. }
  82. dev_info(spss->dev, "Iteration: [0x%x], Debug Data1: [0x%x], Debug Data2: [0x%x]\n",
  83. iter, readl_relaxed(addr), readl_relaxed(((char *) addr) + sizeof(uint32_t)));
  84. iounmap(addr);
  85. }
  86. }
  87. static int glink_spss_subdev_start(struct rproc_subdev *subdev)
  88. {
  89. struct qcom_rproc_glink *glink = to_glink_subdev(subdev);
  90. glink->edge = qcom_glink_spss_register(glink->dev, glink->node);
  91. return PTR_ERR_OR_ZERO(glink->edge);
  92. }
  93. static void glink_spss_subdev_stop(struct rproc_subdev *subdev, bool crashed)
  94. {
  95. struct qcom_rproc_glink *glink = to_glink_subdev(subdev);
  96. qcom_glink_spss_unregister(glink->edge);
  97. glink->edge = NULL;
  98. }
  99. static void glink_spss_subdev_unprepare(struct rproc_subdev *subdev)
  100. {
  101. struct qcom_rproc_glink *glink = to_glink_subdev(subdev);
  102. qcom_glink_ssr_notify(glink->ssr_name);
  103. }
  104. /**
  105. * qcom_add_glink_spss_subdev() - try to add a GLINK SPSS subdevice to rproc
  106. * @rproc: rproc handle to parent the subdevice
  107. * @glink: reference to a GLINK subdev context
  108. * @ssr_name: identifier of the associated remoteproc for ssr notifications
  109. */
  110. static void qcom_add_glink_spss_subdev(struct rproc *rproc,
  111. struct qcom_rproc_glink *glink,
  112. const char *ssr_name)
  113. {
  114. struct device *dev = &rproc->dev;
  115. glink->node = of_get_child_by_name(dev->parent->of_node, "glink-edge");
  116. if (!glink->node)
  117. return;
  118. glink->ssr_name = kstrdup_const(ssr_name, GFP_KERNEL);
  119. if (!glink->ssr_name)
  120. return;
  121. glink->dev = dev;
  122. glink->subdev.start = glink_spss_subdev_start;
  123. glink->subdev.stop = glink_spss_subdev_stop;
  124. glink->subdev.unprepare = glink_spss_subdev_unprepare;
  125. rproc_add_subdev(rproc, &glink->subdev);
  126. }
  127. /**
  128. * qcom_remove_glink_spss_subdev() - remove a GLINK SPSS subdevice from rproc
  129. * @rproc: rproc handle
  130. * @glink: reference to a GLINK subdev context
  131. */
  132. static void qcom_remove_glink_spss_subdev(struct rproc *rproc,
  133. struct qcom_rproc_glink *glink)
  134. {
  135. if (!glink->node)
  136. return;
  137. rproc_remove_subdev(rproc, &glink->subdev);
  138. kfree_const(glink->ssr_name);
  139. of_node_put(glink->node);
  140. }
  141. static void clear_pbl_done(struct qcom_spss *spss)
  142. {
  143. uint32_t err_value, rmb_err_spare0, rmb_err_spare1, rmb_err_spare2;
  144. err_value = __raw_readl(spss->err_status);
  145. rmb_err_spare2 = __raw_readl(spss->err_status_spare);
  146. rmb_err_spare1 = __raw_readl(spss->err_status_spare-4);
  147. rmb_err_spare0 = __raw_readl(spss->err_status_spare-8);
  148. if (err_value) {
  149. dev_err(spss->dev, "PBL error status register: 0x%08x, spare0 register: 0x%08x, spare1 register: 0x%08x, spare2 register: 0x%08x\n",
  150. err_value, rmb_err_spare0, rmb_err_spare1, rmb_err_spare2);
  151. } else
  152. dev_info(spss->dev, "PBL_DONE - 1st phase loading [%s] completed ok\n",
  153. spss->rproc->name);
  154. __raw_writel(BIT(spss->bits_arr[PBL_DONE]), spss->irq_clr);
  155. }
  156. static void clear_err_ready(struct qcom_spss *spss)
  157. {
  158. dev_info(spss->dev, "SW_INIT_DONE - 2nd phase loading [%s] completed ok\n",
  159. spss->rproc->name);
  160. __raw_writel(BIT(spss->bits_arr[ERR_READY]), spss->irq_clr);
  161. complete(&spss->start_done);
  162. }
  163. static void clear_sw_init_done_error(struct qcom_spss *spss, int err)
  164. {
  165. uint32_t rmb_err_spare0;
  166. uint32_t rmb_err_spare1;
  167. uint32_t rmb_err_spare2;
  168. dev_info(spss->dev, "SW_INIT_DONE - ERROR [%s] [0x%x].\n", spss->rproc->name, err);
  169. rmb_err_spare2 = __raw_readl(spss->err_status_spare);
  170. rmb_err_spare1 = __raw_readl(spss->err_status_spare-4);
  171. rmb_err_spare0 = __raw_readl(spss->err_status_spare-8);
  172. dev_err(spss->dev, "spare0 register: 0x%08x, spare1 register: 0x%08x, spare2 register: 0x%08x\n",
  173. rmb_err_spare0, rmb_err_spare1, rmb_err_spare2);
  174. /* Clear the interrupt source */
  175. __raw_writel(BIT(spss->bits_arr[ERR_READY]), spss->irq_clr);
  176. }
  177. static void clear_wdog(struct qcom_spss *spss)
  178. {
  179. dev_err(spss->dev, "wdog bite received from %s!\n", spss->rproc->name);
  180. dev_err(spss->dev, "rproc recovery state: %s\n", spss->rproc->recovery_disabled ?
  181. "disabled and lead to device crash" : "enabled and kick reovery process");
  182. if (spss->rproc->recovery_disabled) {
  183. spss->rproc->state = RPROC_CRASHED;
  184. panic("Panicking, remoterpoc %s crashed\n", spss->rproc->name);
  185. }
  186. __raw_writel(BIT(spss->bits_arr[ERR_READY]), spss->irq_clr);
  187. rproc_report_crash(spss->rproc, RPROC_WATCHDOG);
  188. }
  189. static irqreturn_t spss_generic_handler(int irq, void *dev_id)
  190. {
  191. struct qcom_spss *spss = dev_id;
  192. uint32_t status_val, err_value;
  193. err_value = __raw_readl(spss->err_status_spare);
  194. status_val = __raw_readl(spss->irq_status);
  195. if (status_val & BIT(spss->bits_arr[ERR_READY])) {
  196. if (!err_value)
  197. clear_err_ready(spss);
  198. else if (err_value == SPSS_WDOG_ERR)
  199. clear_wdog(spss);
  200. else
  201. clear_sw_init_done_error(spss, err_value);
  202. }
  203. if (status_val & BIT(spss->bits_arr[PBL_DONE]))
  204. clear_pbl_done(spss);
  205. return IRQ_HANDLED;
  206. }
  207. static void mask_scsr_irqs(struct qcom_spss *spss)
  208. {
  209. uint32_t mask_val;
  210. /* Masking all interrupts */
  211. mask_val = ~0;
  212. __raw_writel(mask_val, spss->irq_mask);
  213. }
  214. static void unmask_scsr_irqs(struct qcom_spss *spss)
  215. {
  216. uint32_t mask_val;
  217. /* unmasking interrupts handled by HLOS */
  218. mask_val = ~0;
  219. __raw_writel(mask_val & ~BIT(spss->bits_arr[ERR_READY]) &
  220. ~BIT(spss->bits_arr[PBL_DONE]), spss->irq_mask);
  221. }
  222. static bool check_status(struct qcom_spss *spss, int *ret_error)
  223. {
  224. uint32_t status_val, err_value, rmb_err;
  225. err_value = __raw_readl(spss->err_status_spare);
  226. status_val = __raw_readl(spss->irq_status);
  227. rmb_err = __raw_readl(spss->err_status);
  228. if ((rmb_err & PBL_LOG_MASK) == PBL_LOG_VALUE) {
  229. dev_err(spss->dev, "PBL error detected\n");
  230. *ret_error = rmb_err;
  231. return true;
  232. }
  233. if ((status_val & BIT(spss->bits_arr[ERR_READY])) && err_value == SPSS_WDOG_ERR) {
  234. dev_err(spss->dev, "wdog bite is pending\n");
  235. __raw_writel(BIT(spss->bits_arr[ERR_READY]), spss->irq_clr);
  236. return true;
  237. }
  238. return false;
  239. }
  240. static int spss_load(struct rproc *rproc, const struct firmware *fw)
  241. {
  242. struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
  243. return qcom_mdt_load(spss->dev, fw, rproc->firmware, spss->pas_id,
  244. spss->mem_region, spss->mem_phys, spss->mem_size,
  245. &spss->mem_reloc);
  246. }
  247. static int spss_stop(struct rproc *rproc)
  248. {
  249. struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
  250. int ret;
  251. ret = qcom_scm_pas_shutdown(spss->pas_id);
  252. if (ret)
  253. panic("Panicking, remoteproc %s failed to shutdown.\n", rproc->name);
  254. mask_scsr_irqs(spss);
  255. if (spss->qmp)
  256. qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, false);
  257. /* Set state as OFFLINE */
  258. rproc->state = RPROC_OFFLINE;
  259. reinit_completion(&spss->start_done);
  260. return ret;
  261. }
  262. static int spss_attach(struct rproc *rproc)
  263. {
  264. struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
  265. int ret = 0;
  266. /* If rproc already crashed stop it and propagate error */
  267. if (check_status(spss, &ret)) {
  268. dev_err(spss->dev, "Failed to attach SPSS remote proc and shutdown\n");
  269. spss_stop(rproc);
  270. return ret;
  271. }
  272. /* signal AOP about spss status.*/
  273. if (spss->qmp) {
  274. ret = qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, true);
  275. if (ret) {
  276. dev_err(spss->dev, "Failed to signal AOP about spss status [%d]\n", ret);
  277. spss_stop(rproc);
  278. return ret;
  279. }
  280. }
  281. /* If booted successfully then wait for init_done*/
  282. unmask_scsr_irqs(spss);
  283. ret = wait_for_completion_timeout(&spss->start_done, msecs_to_jiffies(SPSS_TIMEOUT));
  284. read_sp2cl_debug_registers(spss);
  285. if (rproc->recovery_disabled && !ret) {
  286. dev_err(spss->dev, "%d ms timeout poked\n", SPSS_TIMEOUT);
  287. panic("Panicking, %s attach timed out\n", rproc->name);
  288. } else if (!ret) {
  289. dev_err(spss->dev, "recovery disabled (after timeout)\n");
  290. }
  291. ret = ret ? 0 : -ETIMEDOUT;
  292. /* if attach fails, signal AOP about spss status.*/
  293. if (ret && spss->qmp)
  294. qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, false);
  295. return ret;
  296. }
  297. static inline void disable_regulator(struct reg_info *regulator)
  298. {
  299. regulator_set_voltage(regulator->reg, 0, INT_MAX);
  300. regulator_set_load(regulator->reg, 0);
  301. regulator_disable(regulator->reg);
  302. }
  303. static inline int enable_regulator(struct reg_info *regulator)
  304. {
  305. regulator_set_voltage(regulator->reg, regulator->uV, INT_MAX);
  306. regulator_set_load(regulator->reg, regulator->uA);
  307. return regulator_enable(regulator->reg);
  308. }
  309. static int spss_start(struct rproc *rproc)
  310. {
  311. struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
  312. int ret = 0;
  313. int status = 0;
  314. ret = clk_prepare_enable(spss->xo);
  315. if (ret)
  316. return ret;
  317. ret = enable_regulator(&spss->cx);
  318. if (ret)
  319. goto disable_xo_clk;
  320. /* Signal AOP about spss status. */
  321. if (spss->qmp) {
  322. status = qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, true);
  323. if (status) {
  324. dev_err(spss->dev,
  325. "Failed to signal AOP about spss status [%d]\n", status);
  326. goto disable_xo_clk;
  327. }
  328. }
  329. ret = qcom_scm_pas_auth_and_reset(spss->pas_id);
  330. if (ret)
  331. panic("Panicking, auth and reset failed for remoteproc %s\n", rproc->name);
  332. unmask_scsr_irqs(spss);
  333. dev_err(spss->dev, "trying to read spss registers\n");
  334. ret = wait_for_completion_timeout(&spss->start_done, msecs_to_jiffies(SPSS_TIMEOUT));
  335. read_sp2cl_debug_registers(spss);
  336. if (rproc->recovery_disabled && !ret)
  337. panic("Panicking, %s start timed out\n", rproc->name);
  338. else if (!ret)
  339. dev_err(spss->dev, "start timed out\n");
  340. ret = ret ? 0 : -ETIMEDOUT;
  341. /* if SPSS fails to start, signal AOP about spss status. */
  342. if (ret && spss->qmp) {
  343. status = qcom_rproc_toggle_load_state(spss->qmp, spss->qmp_name, false);
  344. if (status)
  345. dev_err(spss->dev,
  346. "Failed to signal AOP about spss status [%d]\n", status);
  347. }
  348. disable_regulator(&spss->cx);
  349. disable_xo_clk:
  350. clk_disable_unprepare(spss->xo);
  351. return ret;
  352. }
  353. static void *spss_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
  354. {
  355. struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
  356. int offset;
  357. offset = da - spss->mem_reloc;
  358. if (offset < 0 || offset + len > spss->mem_size) {
  359. dev_err(&rproc->dev, "offset: %llx, da: %llx, len: %llx\n", offset, da, len);
  360. return NULL;
  361. }
  362. return spss->mem_region + offset;
  363. }
  364. static const struct rproc_ops spss_ops = {
  365. .stop = spss_stop,
  366. .da_to_va = spss_da_to_va,
  367. .load = spss_load,
  368. .attach = spss_attach,
  369. .parse_fw = qcom_register_dump_segments,
  370. .start = spss_start,
  371. };
  372. static int spss_init_clock(struct qcom_spss *spss)
  373. {
  374. int ret;
  375. spss->xo = devm_clk_get(spss->dev, "xo");
  376. if (IS_ERR(spss->xo)) {
  377. ret = PTR_ERR(spss->xo);
  378. if (ret != -EPROBE_DEFER)
  379. dev_err(spss->dev, "failed to get xo clock\n");
  380. return ret;
  381. }
  382. return 0;
  383. }
  384. static int init_regulator(struct device *dev, struct reg_info *regulator, const char *reg_name)
  385. {
  386. int len, rc;
  387. char uv_ua[50];
  388. u32 uv_ua_vals[2];
  389. regulator->reg = devm_regulator_get(dev, reg_name);
  390. if (IS_ERR(regulator->reg))
  391. return PTR_ERR(regulator->reg);
  392. snprintf(uv_ua, sizeof(uv_ua), "%s-uV-uA", reg_name);
  393. if (!of_find_property(dev->of_node, uv_ua, &len))
  394. return -EINVAL;
  395. rc = of_property_read_u32_array(dev->of_node, uv_ua,
  396. uv_ua_vals,
  397. ARRAY_SIZE(uv_ua_vals));
  398. if (rc) {
  399. dev_err(dev, "Failed to read uV-uA value(rc:%d)\n", rc);
  400. return rc;
  401. }
  402. if (uv_ua_vals[0] > 0)
  403. regulator->uV = uv_ua_vals[0];
  404. if (uv_ua_vals[1] > 0)
  405. regulator->uA = uv_ua_vals[1];
  406. return 0;
  407. }
  408. static int spss_alloc_memory_region(struct qcom_spss *spss)
  409. {
  410. struct device_node *node;
  411. struct resource r;
  412. int ret, extra_size = 0;
  413. node = of_parse_phandle(spss->dev->of_node, "memory-region", 0);
  414. if (!node) {
  415. dev_err(spss->dev, "no memory-region specified\n");
  416. return -EINVAL;
  417. }
  418. ret = of_address_to_resource(node, 0, &r);
  419. if (ret)
  420. return ret;
  421. ret = of_property_read_u32(spss->dev->of_node, "qcom,extra-size", &extra_size);
  422. spss->mem_phys = spss->mem_reloc = r.start;
  423. spss->mem_size = resource_size(&r) + extra_size;
  424. spss->mem_region = devm_ioremap_wc(spss->dev, spss->mem_phys, spss->mem_size);
  425. if (!spss->mem_region) {
  426. dev_err(spss->dev, "unable to map memory region: %pa+%zx\n",
  427. &r.start, spss->mem_size);
  428. return -EBUSY;
  429. }
  430. return 0;
  431. }
  432. static int qcom_spss_init_mmio(struct platform_device *pdev, struct qcom_spss *spss)
  433. {
  434. struct resource *res;
  435. int ret;
  436. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb_general_purpose");
  437. spss->rmb_gpm = devm_ioremap_resource(&pdev->dev, res);
  438. if (IS_ERR(spss->rmb_gpm))
  439. return PTR_ERR(spss->rmb_gpm);
  440. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sp2soc_irq_status");
  441. spss->irq_status = devm_ioremap_resource(&pdev->dev, res);
  442. if (IS_ERR(spss->irq_status))
  443. return PTR_ERR(spss->irq_status);
  444. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sp2soc_irq_clr");
  445. spss->irq_clr = devm_ioremap_resource(&pdev->dev, res);
  446. if (IS_ERR(spss->irq_clr))
  447. return PTR_ERR(spss->irq_clr);
  448. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sp2soc_irq_mask");
  449. spss->irq_mask = devm_ioremap_resource(&pdev->dev, res);
  450. if (IS_ERR(spss->irq_mask))
  451. return PTR_ERR(spss->irq_mask);
  452. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb_err");
  453. spss->err_status = devm_ioremap_resource(&pdev->dev, res);
  454. if (IS_ERR(spss->err_status))
  455. return PTR_ERR(spss->err_status);
  456. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb_err_spare2");
  457. spss->err_status_spare = devm_ioremap_resource(&pdev->dev, res);
  458. if (IS_ERR(spss->err_status_spare))
  459. return PTR_ERR(spss->err_status_spare);
  460. ret = of_property_read_u32_array(pdev->dev.of_node, "qcom,spss-scsr-bits", spss->bits_arr,
  461. ARRAY_SIZE(spss->bits_arr));
  462. if (ret)
  463. return ret;
  464. return 0;
  465. }
  466. int qcom_spss_set_fw_name(struct rproc *rproc, const char *fw_name)
  467. {
  468. const char *p;
  469. p = kstrdup_const(fw_name, GFP_KERNEL);
  470. if (!p)
  471. return -ENOMEM;
  472. mutex_lock(&rproc->lock);
  473. kfree(rproc->firmware);
  474. rproc->firmware = p;
  475. mutex_unlock(&rproc->lock);
  476. return 0;
  477. }
  478. EXPORT_SYMBOL(qcom_spss_set_fw_name);
  479. static int qcom_spss_probe(struct platform_device *pdev)
  480. {
  481. const struct spss_data *desc;
  482. struct qcom_spss *spss;
  483. struct rproc *rproc;
  484. const char *fw_name;
  485. int ret;
  486. bool signal_aop;
  487. desc = of_device_get_match_data(&pdev->dev);
  488. if (!desc)
  489. return -EINVAL;
  490. if (!qcom_scm_is_available())
  491. return -EPROBE_DEFER;
  492. fw_name = desc->firmware_name;
  493. rproc = rproc_alloc(&pdev->dev, pdev->name, &spss_ops, fw_name, sizeof(*spss));
  494. if (!rproc) {
  495. dev_err(&pdev->dev, "unable to allocate remoteproc\n");
  496. return -ENOMEM;
  497. }
  498. spss = (struct qcom_spss *)rproc->priv;
  499. spss->dev = &pdev->dev;
  500. spss->rproc = rproc;
  501. spss->pas_id = desc->pas_id;
  502. init_completion(&spss->start_done);
  503. platform_set_drvdata(pdev, spss);
  504. rproc->auto_boot = desc->auto_boot;
  505. spss->qmp_name = desc->qmp_name;
  506. rproc->recovery_disabled = true;
  507. rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
  508. ret = device_init_wakeup(spss->dev, true);
  509. if (ret)
  510. goto free_rproc;
  511. ret = qcom_spss_init_mmio(pdev, spss);
  512. if (ret)
  513. goto deinit_wakeup_source;
  514. if (!(__raw_readl(spss->rmb_gpm) & BIT(0)))
  515. rproc->state = RPROC_DETACHED;
  516. else
  517. rproc->state = RPROC_OFFLINE;
  518. ret = spss_alloc_memory_region(spss);
  519. if (ret)
  520. goto deinit_wakeup_source;
  521. ret = spss_init_clock(spss);
  522. if (ret)
  523. goto deinit_wakeup_source;
  524. ret = init_regulator(spss->dev, &spss->cx, "cx");
  525. if (ret)
  526. goto deinit_wakeup_source;
  527. signal_aop = of_property_read_bool(pdev->dev.of_node,
  528. "qcom,signal-aop");
  529. if (signal_aop) {
  530. spss->qmp = qmp_get(spss->dev);
  531. if (IS_ERR_OR_NULL(spss->qmp))
  532. goto deinit_wakeup_source;
  533. }
  534. qcom_add_glink_spss_subdev(rproc, &spss->glink_subdev, "spss");
  535. qcom_add_ssr_subdev(rproc, &spss->ssr_subdev, desc->ssr_name);
  536. spss->sysmon_subdev = qcom_add_sysmon_subdev(rproc, desc->ssr_name, -EINVAL);
  537. if (IS_ERR(spss->sysmon_subdev)) {
  538. dev_err(spss->dev, "failed to add sysmon subdevice\n");
  539. goto deinit_wakeup_source;
  540. }
  541. mask_scsr_irqs(spss);
  542. spss->generic_irq = platform_get_irq(pdev, 0);
  543. ret = devm_request_threaded_irq(&pdev->dev, spss->generic_irq, NULL, spss_generic_handler,
  544. IRQF_TRIGGER_RISING | IRQF_ONESHOT, "generic-irq", spss);
  545. if (ret) {
  546. dev_err(&pdev->dev, "failed to acquire generic IRQ\n");
  547. goto remove_subdev;
  548. }
  549. ret = rproc_add(rproc);
  550. if (ret)
  551. goto remove_subdev;
  552. return 0;
  553. remove_subdev:
  554. qcom_remove_sysmon_subdev(spss->sysmon_subdev);
  555. deinit_wakeup_source:
  556. device_init_wakeup(spss->dev, false);
  557. free_rproc:
  558. rproc_free(rproc);
  559. return ret;
  560. }
  561. static int qcom_spss_remove(struct platform_device *pdev)
  562. {
  563. struct qcom_spss *spss = platform_get_drvdata(pdev);
  564. rproc_del(spss->rproc);
  565. qcom_remove_glink_spss_subdev(spss->rproc, &spss->glink_subdev);
  566. qcom_remove_ssr_subdev(spss->rproc, &spss->ssr_subdev);
  567. qcom_remove_sysmon_subdev(spss->sysmon_subdev);
  568. device_init_wakeup(spss->dev, false);
  569. rproc_free(spss->rproc);
  570. return 0;
  571. }
  572. static const struct spss_data spss_resource_init = {
  573. .firmware_name = "spss.mdt",
  574. .pas_id = 14,
  575. .ssr_name = "spss",
  576. .auto_boot = false,
  577. .qmp_name = "spss",
  578. };
  579. static const struct of_device_id spss_of_match[] = {
  580. { .compatible = "qcom,waipio-spss-pas", .data = &spss_resource_init},
  581. { .compatible = "qcom,kalama-spss-pas", .data = &spss_resource_init},
  582. { .compatible = "qcom,pineapple-spss-pas", .data = &spss_resource_init},
  583. { .compatible = "qcom,niobe-spss-pas", .data = &spss_resource_init},
  584. { },
  585. };
  586. MODULE_DEVICE_TABLE(of, spss_of_match);
  587. static struct platform_driver spss_driver = {
  588. .probe = qcom_spss_probe,
  589. .remove = qcom_spss_remove,
  590. .driver = {
  591. .name = "qcom_spss",
  592. .of_match_table = spss_of_match,
  593. },
  594. };
  595. module_platform_driver(spss_driver);
  596. MODULE_DESCRIPTION("QTI Peripheral Image Loader for Secure Subsystem");
  597. MODULE_LICENSE("GPL");