gecko-core.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/slab.h>
  13. #include <linux/wait.h>
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/delay.h>
  17. #include <linux/sched.h>
  18. #include <linux/of.h>
  19. #include <linux/of_platform.h>
  20. #include <linux/jiffies.h>
  21. #include <ipc/gpr-lite.h>
  22. #include <dsp/gecko-core.h>
  23. #define APM_STATE_READY_TIMEOUT_MS 10000
  24. #define Q6_READY_TIMEOUT_MS 1000
  25. #define APM_CMD_GET_GECKO_STATE 0x01001021
  26. #define APM_CMD_RSP_GET_GECKO_STATE 0x02001007
  27. #define APM_MODULE_INSTANCE_ID 0x00000001
  28. #define GPR_SVC_ADSP_CORE 0x3
  29. struct gecko_core {
  30. struct gpr_device *adev;
  31. wait_queue_head_t wait;
  32. struct mutex lock;
  33. bool resp_received;
  34. bool is_ready;
  35. };
  36. struct gecko_core_private {
  37. struct device *dev;
  38. struct mutex lock;
  39. struct gecko_core *gecko_core_drv;
  40. bool is_initial_boot;
  41. struct work_struct add_chld_dev_work;
  42. };
  43. static struct gecko_core_private *gecko_core_priv;
  44. struct apm_cmd_rsp_get_gecko_status_t
  45. {
  46. /* Gecko status
  47. * @values
  48. * 0 -> Not ready
  49. * 1 -> Ready
  50. */
  51. uint32_t status;
  52. };
  53. static int gecko_core_callback(struct gpr_device *adev, void *data)
  54. {
  55. struct gecko_core *core = dev_get_drvdata(&adev->dev);
  56. struct apm_cmd_rsp_get_gecko_status_t *result;
  57. struct gpr_hdr *hdr = data;
  58. result = GPR_PKT_GET_PAYLOAD(struct apm_cmd_rsp_get_gecko_status_t, data);
  59. dev_err(&adev->dev ,"%s: Payload %x",__func__, hdr->opcode);
  60. switch (hdr->opcode) {
  61. case GPR_IBASIC_RSP_RESULT:
  62. dev_err(&adev->dev ,"%s: Failed response received",__func__);
  63. core->resp_received = true;
  64. break;
  65. case APM_CMD_RSP_GET_GECKO_STATE:
  66. dev_err(&adev->dev ,"%s: sucess response received",__func__);
  67. core->is_ready = result->status;
  68. core->resp_received = true;
  69. break;
  70. default:
  71. dev_err(&adev->dev, "Message ID from apm: 0x%x\n",
  72. hdr->opcode);
  73. break;
  74. }
  75. if (core->resp_received)
  76. wake_up(&core->wait);
  77. return 0;
  78. }
  79. static bool __gecko_core_is_apm_ready(struct gecko_core *core)
  80. {
  81. struct gpr_device *adev = core->adev;
  82. struct gpr_pkt pkt;
  83. int rc;
  84. pkt.hdr.header = GPR_SET_FIELD(GPR_PKT_VERSION, GPR_PKT_VER) |
  85. GPR_SET_FIELD(GPR_PKT_HEADER_SIZE, GPR_PKT_HEADER_WORD_SIZE_V) |
  86. GPR_SET_FIELD(GPR_PKT_PACKET_SIZE, GPR_PKT_HEADER_BYTE_SIZE_V);
  87. pkt.hdr.opcode = APM_CMD_GET_GECKO_STATE;
  88. pkt.hdr.dst_port = APM_MODULE_INSTANCE_ID;
  89. pkt.hdr.src_port = GPR_SVC_ADSP_CORE;
  90. pkt.hdr.dst_domain_id = GPR_IDS_DOMAIN_ID_ADSP_V;
  91. pkt.hdr.src_domain_id = GPR_IDS_DOMAIN_ID_APPS_V;
  92. pkt.hdr.opcode = APM_CMD_GET_GECKO_STATE;
  93. dev_err(gecko_core_priv->dev, "%s: send_command ret\n", __func__);
  94. rc = gpr_send_pkt(adev, &pkt);
  95. if (rc < 0)
  96. return false;
  97. rc = wait_event_timeout(core->wait, (core->resp_received),
  98. msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
  99. dev_err(gecko_core_priv->dev, "%s: wait event unblocked \n", __func__);
  100. // core->resp_received = true;
  101. // core->is_ready = true;
  102. if (rc > 0 && core->resp_received) {
  103. core->resp_received = false;
  104. if (core->is_ready)
  105. return true;
  106. } else {
  107. dev_err(gecko_core_priv->dev, "%s: command timedout, ret\n",
  108. __func__);
  109. }
  110. return false;
  111. }
  112. /**
  113. * gecko_core_is_apm_ready() - Get status of adsp
  114. *
  115. * Return: Will be an true if apm is ready and false if not.
  116. */
  117. bool gecko_core_is_apm_ready(void)
  118. {
  119. unsigned long timeout;
  120. bool ret = false;
  121. struct gecko_core *core;
  122. if (!gecko_core_priv)
  123. return 0;
  124. core = gecko_core_priv->gecko_core_drv;
  125. if (!core)
  126. return 0;
  127. mutex_lock(&core->lock);
  128. timeout = jiffies + msecs_to_jiffies(APM_STATE_READY_TIMEOUT_MS);
  129. for (;;) {
  130. if (__gecko_core_is_apm_ready(core)) {
  131. ret = true;
  132. break;
  133. }
  134. usleep_range(300000, 300050);
  135. if (!time_after(timeout, jiffies)) {
  136. ret = false;
  137. break;
  138. }
  139. }
  140. mutex_unlock(&core->lock);
  141. return ret;
  142. }
  143. EXPORT_SYMBOL_GPL(gecko_core_is_apm_ready);
  144. static int gecko_core_probe(struct gpr_device *adev)
  145. {
  146. struct gecko_core *core;
  147. pr_err("%s",__func__);
  148. if (!gecko_core_priv) {
  149. pr_err("%s: gecko_core platform probe not yet done\n", __func__);
  150. return -EPROBE_DEFER;
  151. }
  152. mutex_lock(&gecko_core_priv->lock);
  153. core = kzalloc(sizeof(*core), GFP_KERNEL);
  154. if (!core)
  155. return -ENOMEM;
  156. dev_set_drvdata(&adev->dev, core);
  157. mutex_init(&core->lock);
  158. core->adev = adev;
  159. init_waitqueue_head(&core->wait);
  160. gecko_core_priv->gecko_core_drv = core;
  161. if (gecko_core_priv->is_initial_boot)
  162. schedule_work(&gecko_core_priv->add_chld_dev_work);
  163. mutex_unlock(&gecko_core_priv->lock);
  164. return 0;
  165. }
  166. static int gecko_core_exit(struct gpr_device *adev)
  167. {
  168. struct gecko_core *core = dev_get_drvdata(&adev->dev);
  169. if (!gecko_core_priv) {
  170. pr_err("%s: gecko_core platform probe not yet done\n", __func__);
  171. return -1;
  172. }
  173. mutex_lock(&gecko_core_priv->lock);
  174. gecko_core_priv->gecko_core_drv = NULL;
  175. kfree(core);
  176. mutex_unlock(&gecko_core_priv->lock);
  177. return 0;
  178. }
  179. static const struct of_device_id gecko_core_device_id[] = {
  180. { .compatible = "qcom,gecko_core" },
  181. {},
  182. };
  183. MODULE_DEVICE_TABLE(of, gecko_core_device_id);
  184. static struct gpr_driver qcom_gecko_core_driver = {
  185. .probe = gecko_core_probe,
  186. .remove = gecko_core_exit,
  187. .callback = gecko_core_callback,
  188. .driver = {
  189. .name = "qcom-gecko_core",
  190. .of_match_table = of_match_ptr(gecko_core_device_id),
  191. },
  192. };
  193. static void gecko_core_add_child_devices(struct work_struct *work)
  194. {
  195. int ret;
  196. pr_err("%s:enumarate machine driver\n", __func__);
  197. if(gecko_core_is_apm_ready()) {
  198. dev_err(gecko_core_priv->dev, "%s: apm is up\n",
  199. __func__);
  200. } else {
  201. dev_err(gecko_core_priv->dev, "%s: apm is not up\n",
  202. __func__);
  203. return;
  204. }
  205. ret = of_platform_populate(gecko_core_priv->dev->of_node,
  206. NULL, NULL, gecko_core_priv->dev);
  207. if (ret)
  208. dev_err(gecko_core_priv->dev, "%s: failed to add child nodes, ret=%d\n",
  209. __func__, ret);
  210. gecko_core_priv->is_initial_boot = false;
  211. }
  212. static int gecko_core_platform_driver_probe(struct platform_device *pdev)
  213. {
  214. int ret = 0;
  215. pr_err("%s",__func__);
  216. gecko_core_priv = devm_kzalloc(&pdev->dev, sizeof(struct gecko_core_private), GFP_KERNEL);
  217. if (!gecko_core_priv)
  218. return -ENOMEM;
  219. gecko_core_priv->dev = &pdev->dev;
  220. mutex_init(&gecko_core_priv->lock);
  221. INIT_WORK(&gecko_core_priv->add_chld_dev_work, gecko_core_add_child_devices);
  222. ret = gpr_driver_register(&qcom_gecko_core_driver);
  223. if (ret) {
  224. pr_err("%s: gpr driver register failed = %d\n",
  225. __func__, ret);
  226. ret = 0;
  227. }
  228. gecko_core_priv->is_initial_boot = true;
  229. #if 0
  230. ret = snd_event_client_register(&pdev->dev, &gpr_ssr_ops, NULL);
  231. if (ret) {
  232. pr_err("%s: Registration with SND event fwk failed ret = %d\n",
  233. __func__, ret);
  234. ret = 0;
  235. }
  236. #endif
  237. return ret;
  238. }
  239. static int gecko_core_platform_driver_remove(struct platform_device *pdev)
  240. {
  241. //snd_event_client_deregister(&pdev->dev);
  242. gpr_driver_unregister(&qcom_gecko_core_driver);
  243. gecko_core_priv = NULL;
  244. return 0;
  245. }
  246. static const struct of_device_id gecko_core_of_match[] = {
  247. { .compatible = "qcom,gecko-core-platform", },
  248. {},
  249. };
  250. static struct platform_driver gecko_core_driver = {
  251. .probe = gecko_core_platform_driver_probe,
  252. .remove = gecko_core_platform_driver_remove,
  253. .driver = {
  254. .name = "gecko-core-platform",
  255. .owner = THIS_MODULE,
  256. .of_match_table = gecko_core_of_match,
  257. }
  258. };
  259. module_platform_driver(gecko_core_driver);
  260. MODULE_DESCRIPTION("q6 core");
  261. MODULE_LICENSE("GPL v2");