bus.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include "bus.h"
  7. #include "debug.h"
  8. #include "pci.h"
  9. enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
  10. {
  11. if (!dev)
  12. return CNSS_BUS_NONE;
  13. if (!dev->bus)
  14. return CNSS_BUS_NONE;
  15. if (memcmp(dev->bus->name, "pci", 3) == 0)
  16. return CNSS_BUS_PCI;
  17. else
  18. return CNSS_BUS_NONE;
  19. }
  20. enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
  21. {
  22. switch (device_id) {
  23. case QCA6174_DEVICE_ID:
  24. case QCA6290_DEVICE_ID:
  25. case QCA6390_DEVICE_ID:
  26. case QCA6490_DEVICE_ID:
  27. case KIWI_DEVICE_ID:
  28. case MANGO_DEVICE_ID:
  29. return CNSS_BUS_PCI;
  30. default:
  31. cnss_pr_err("Unknown device_id: 0x%lx\n", device_id);
  32. return CNSS_BUS_NONE;
  33. }
  34. }
  35. void *cnss_bus_dev_to_bus_priv(struct device *dev)
  36. {
  37. if (!dev)
  38. return NULL;
  39. switch (cnss_get_dev_bus_type(dev)) {
  40. case CNSS_BUS_PCI:
  41. return cnss_get_pci_priv(to_pci_dev(dev));
  42. default:
  43. return NULL;
  44. }
  45. }
  46. struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev)
  47. {
  48. void *bus_priv;
  49. if (!dev)
  50. return cnss_get_plat_priv(NULL);
  51. bus_priv = cnss_bus_dev_to_bus_priv(dev);
  52. if (!bus_priv)
  53. return NULL;
  54. switch (cnss_get_dev_bus_type(dev)) {
  55. case CNSS_BUS_PCI:
  56. return cnss_pci_priv_to_plat_priv(bus_priv);
  57. default:
  58. return NULL;
  59. }
  60. }
  61. int cnss_bus_init(struct cnss_plat_data *plat_priv)
  62. {
  63. if (!plat_priv)
  64. return -ENODEV;
  65. switch (plat_priv->bus_type) {
  66. case CNSS_BUS_PCI:
  67. return cnss_pci_init(plat_priv);
  68. default:
  69. cnss_pr_err("Unsupported bus type: %d\n",
  70. plat_priv->bus_type);
  71. return -EINVAL;
  72. }
  73. }
  74. void cnss_bus_deinit(struct cnss_plat_data *plat_priv)
  75. {
  76. if (!plat_priv)
  77. return;
  78. switch (plat_priv->bus_type) {
  79. case CNSS_BUS_PCI:
  80. return cnss_pci_deinit(plat_priv);
  81. default:
  82. cnss_pr_err("Unsupported bus type: %d\n",
  83. plat_priv->bus_type);
  84. return;
  85. }
  86. }
  87. void cnss_bus_add_fw_prefix_name(struct cnss_plat_data *plat_priv,
  88. char *prefix_name, char *name)
  89. {
  90. if (!plat_priv)
  91. return;
  92. switch (plat_priv->bus_type) {
  93. case CNSS_BUS_PCI:
  94. return cnss_pci_add_fw_prefix_name(plat_priv->bus_priv,
  95. prefix_name, name);
  96. default:
  97. cnss_pr_err("Unsupported bus type: %d\n",
  98. plat_priv->bus_type);
  99. return;
  100. }
  101. }
  102. int cnss_bus_load_m3(struct cnss_plat_data *plat_priv)
  103. {
  104. if (!plat_priv)
  105. return -ENODEV;
  106. switch (plat_priv->bus_type) {
  107. case CNSS_BUS_PCI:
  108. return cnss_pci_load_m3(plat_priv->bus_priv);
  109. default:
  110. cnss_pr_err("Unsupported bus type: %d\n",
  111. plat_priv->bus_type);
  112. return -EINVAL;
  113. }
  114. }
  115. int cnss_bus_handle_dev_sol_irq(struct cnss_plat_data *plat_priv)
  116. {
  117. if (!plat_priv)
  118. return -ENODEV;
  119. switch (plat_priv->bus_type) {
  120. case CNSS_BUS_PCI:
  121. return cnss_pci_handle_dev_sol_irq(plat_priv->bus_priv);
  122. default:
  123. cnss_pr_err("Unsupported bus type: %d\n",
  124. plat_priv->bus_type);
  125. return -EINVAL;
  126. }
  127. }
  128. int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv)
  129. {
  130. if (!plat_priv)
  131. return -ENODEV;
  132. switch (plat_priv->bus_type) {
  133. case CNSS_BUS_PCI:
  134. return cnss_pci_alloc_fw_mem(plat_priv->bus_priv);
  135. default:
  136. cnss_pr_err("Unsupported bus type: %d\n",
  137. plat_priv->bus_type);
  138. return -EINVAL;
  139. }
  140. }
  141. int cnss_bus_alloc_qdss_mem(struct cnss_plat_data *plat_priv)
  142. {
  143. if (!plat_priv)
  144. return -ENODEV;
  145. switch (plat_priv->bus_type) {
  146. case CNSS_BUS_PCI:
  147. return cnss_pci_alloc_qdss_mem(plat_priv->bus_priv);
  148. default:
  149. cnss_pr_err("Unsupported bus type: %d\n",
  150. plat_priv->bus_type);
  151. return -EINVAL;
  152. }
  153. }
  154. void cnss_bus_free_qdss_mem(struct cnss_plat_data *plat_priv)
  155. {
  156. if (!plat_priv)
  157. return;
  158. switch (plat_priv->bus_type) {
  159. case CNSS_BUS_PCI:
  160. cnss_pci_free_qdss_mem(plat_priv->bus_priv);
  161. return;
  162. default:
  163. cnss_pr_err("Unsupported bus type: %d\n",
  164. plat_priv->bus_type);
  165. return;
  166. }
  167. }
  168. u32 cnss_bus_get_wake_irq(struct cnss_plat_data *plat_priv)
  169. {
  170. if (!plat_priv)
  171. return -ENODEV;
  172. switch (plat_priv->bus_type) {
  173. case CNSS_BUS_PCI:
  174. return cnss_pci_get_wake_msi(plat_priv->bus_priv);
  175. default:
  176. cnss_pr_err("Unsupported bus type: %d\n",
  177. plat_priv->bus_type);
  178. return -EINVAL;
  179. }
  180. }
  181. int cnss_bus_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv)
  182. {
  183. if (!plat_priv)
  184. return -ENODEV;
  185. switch (plat_priv->bus_type) {
  186. case CNSS_BUS_PCI:
  187. return cnss_pci_force_fw_assert_hdlr(plat_priv->bus_priv);
  188. default:
  189. cnss_pr_err("Unsupported bus type: %d\n",
  190. plat_priv->bus_type);
  191. return -EINVAL;
  192. }
  193. }
  194. int cnss_bus_qmi_send_get(struct cnss_plat_data *plat_priv)
  195. {
  196. if (!plat_priv)
  197. return -ENODEV;
  198. switch (plat_priv->bus_type) {
  199. case CNSS_BUS_PCI:
  200. return cnss_pci_qmi_send_get(plat_priv->bus_priv);
  201. default:
  202. cnss_pr_err("Unsupported bus type: %d\n",
  203. plat_priv->bus_type);
  204. return -EINVAL;
  205. }
  206. }
  207. int cnss_bus_qmi_send_put(struct cnss_plat_data *plat_priv)
  208. {
  209. if (!plat_priv)
  210. return -ENODEV;
  211. switch (plat_priv->bus_type) {
  212. case CNSS_BUS_PCI:
  213. return cnss_pci_qmi_send_put(plat_priv->bus_priv);
  214. default:
  215. cnss_pr_err("Unsupported bus type: %d\n",
  216. plat_priv->bus_type);
  217. return -EINVAL;
  218. }
  219. }
  220. void cnss_bus_fw_boot_timeout_hdlr(struct timer_list *t)
  221. {
  222. struct cnss_plat_data *plat_priv =
  223. from_timer(plat_priv, t, fw_boot_timer);
  224. if (!plat_priv)
  225. return;
  226. switch (plat_priv->bus_type) {
  227. case CNSS_BUS_PCI:
  228. return cnss_pci_fw_boot_timeout_hdlr(plat_priv->bus_priv);
  229. default:
  230. cnss_pr_err("Unsupported bus type: %d\n",
  231. plat_priv->bus_type);
  232. return;
  233. }
  234. }
  235. void cnss_bus_collect_dump_info(struct cnss_plat_data *plat_priv, bool in_panic)
  236. {
  237. if (!plat_priv)
  238. return;
  239. switch (plat_priv->bus_type) {
  240. case CNSS_BUS_PCI:
  241. return cnss_pci_collect_dump_info(plat_priv->bus_priv,
  242. in_panic);
  243. default:
  244. cnss_pr_err("Unsupported bus type: %d\n",
  245. plat_priv->bus_type);
  246. return;
  247. }
  248. }
  249. void cnss_bus_device_crashed(struct cnss_plat_data *plat_priv)
  250. {
  251. if (!plat_priv)
  252. return;
  253. switch (plat_priv->bus_type) {
  254. case CNSS_BUS_PCI:
  255. return cnss_pci_device_crashed(plat_priv->bus_priv);
  256. default:
  257. cnss_pr_err("Unsupported bus type: %d\n",
  258. plat_priv->bus_type);
  259. return;
  260. }
  261. }
  262. int cnss_bus_call_driver_probe(struct cnss_plat_data *plat_priv)
  263. {
  264. if (!plat_priv)
  265. return -ENODEV;
  266. switch (plat_priv->bus_type) {
  267. case CNSS_BUS_PCI:
  268. return cnss_pci_call_driver_probe(plat_priv->bus_priv);
  269. default:
  270. cnss_pr_err("Unsupported bus type: %d\n",
  271. plat_priv->bus_type);
  272. return -EINVAL;
  273. }
  274. }
  275. int cnss_bus_call_driver_remove(struct cnss_plat_data *plat_priv)
  276. {
  277. if (!plat_priv)
  278. return -ENODEV;
  279. switch (plat_priv->bus_type) {
  280. case CNSS_BUS_PCI:
  281. return cnss_pci_call_driver_remove(plat_priv->bus_priv);
  282. default:
  283. cnss_pr_err("Unsupported bus type: %d\n",
  284. plat_priv->bus_type);
  285. return -EINVAL;
  286. }
  287. }
  288. int cnss_bus_dev_powerup(struct cnss_plat_data *plat_priv)
  289. {
  290. if (!plat_priv)
  291. return -ENODEV;
  292. switch (plat_priv->bus_type) {
  293. case CNSS_BUS_PCI:
  294. return cnss_pci_dev_powerup(plat_priv->bus_priv);
  295. default:
  296. cnss_pr_err("Unsupported bus type: %d\n",
  297. plat_priv->bus_type);
  298. return -EINVAL;
  299. }
  300. }
  301. int cnss_bus_dev_shutdown(struct cnss_plat_data *plat_priv)
  302. {
  303. if (!plat_priv)
  304. return -ENODEV;
  305. switch (plat_priv->bus_type) {
  306. case CNSS_BUS_PCI:
  307. return cnss_pci_dev_shutdown(plat_priv->bus_priv);
  308. default:
  309. cnss_pr_err("Unsupported bus type: %d\n",
  310. plat_priv->bus_type);
  311. return -EINVAL;
  312. }
  313. }
  314. int cnss_bus_dev_crash_shutdown(struct cnss_plat_data *plat_priv)
  315. {
  316. if (!plat_priv)
  317. return -ENODEV;
  318. switch (plat_priv->bus_type) {
  319. case CNSS_BUS_PCI:
  320. return cnss_pci_dev_crash_shutdown(plat_priv->bus_priv);
  321. default:
  322. cnss_pr_err("Unsupported bus type: %d\n",
  323. plat_priv->bus_type);
  324. return -EINVAL;
  325. }
  326. }
  327. int cnss_bus_dev_ramdump(struct cnss_plat_data *plat_priv)
  328. {
  329. if (!plat_priv)
  330. return -ENODEV;
  331. switch (plat_priv->bus_type) {
  332. case CNSS_BUS_PCI:
  333. return cnss_pci_dev_ramdump(plat_priv->bus_priv);
  334. default:
  335. cnss_pr_err("Unsupported bus type: %d\n",
  336. plat_priv->bus_type);
  337. return -EINVAL;
  338. }
  339. }
  340. int cnss_bus_register_driver_hdlr(struct cnss_plat_data *plat_priv, void *data)
  341. {
  342. if (!plat_priv)
  343. return -ENODEV;
  344. switch (plat_priv->bus_type) {
  345. case CNSS_BUS_PCI:
  346. return cnss_pci_register_driver_hdlr(plat_priv->bus_priv, data);
  347. default:
  348. cnss_pr_err("Unsupported bus type: %d\n",
  349. plat_priv->bus_type);
  350. return -EINVAL;
  351. }
  352. }
  353. int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv)
  354. {
  355. if (!plat_priv)
  356. return -ENODEV;
  357. switch (plat_priv->bus_type) {
  358. case CNSS_BUS_PCI:
  359. return cnss_pci_unregister_driver_hdlr(plat_priv->bus_priv);
  360. default:
  361. cnss_pr_err("Unsupported bus type: %d\n",
  362. plat_priv->bus_type);
  363. return -EINVAL;
  364. }
  365. }
  366. int cnss_bus_call_driver_modem_status(struct cnss_plat_data *plat_priv,
  367. int modem_current_status)
  368. {
  369. if (!plat_priv)
  370. return -ENODEV;
  371. switch (plat_priv->bus_type) {
  372. case CNSS_BUS_PCI:
  373. return cnss_pci_call_driver_modem_status(plat_priv->bus_priv,
  374. modem_current_status);
  375. default:
  376. cnss_pr_err("Unsupported bus type: %d\n",
  377. plat_priv->bus_type);
  378. return -EINVAL;
  379. }
  380. }
  381. int cnss_bus_update_status(struct cnss_plat_data *plat_priv,
  382. enum cnss_driver_status status)
  383. {
  384. if (!plat_priv)
  385. return -ENODEV;
  386. switch (plat_priv->bus_type) {
  387. case CNSS_BUS_PCI:
  388. return cnss_pci_update_status(plat_priv->bus_priv, status);
  389. default:
  390. cnss_pr_err("Unsupported bus type: %d\n",
  391. plat_priv->bus_type);
  392. return -EINVAL;
  393. }
  394. }
  395. int cnss_bus_update_uevent(struct cnss_plat_data *plat_priv,
  396. enum cnss_driver_status status, void *data)
  397. {
  398. if (!plat_priv)
  399. return -ENODEV;
  400. switch (plat_priv->bus_type) {
  401. case CNSS_BUS_PCI:
  402. return cnss_pci_call_driver_uevent(plat_priv->bus_priv,
  403. status, data);
  404. default:
  405. cnss_pr_err("Unsupported bus type: %d\n",
  406. plat_priv->bus_type);
  407. return -EINVAL;
  408. }
  409. }
  410. int cnss_bus_is_device_down(struct cnss_plat_data *plat_priv)
  411. {
  412. if (!plat_priv)
  413. return -ENODEV;
  414. switch (plat_priv->bus_type) {
  415. case CNSS_BUS_PCI:
  416. return cnss_pcie_is_device_down(plat_priv->bus_priv);
  417. default:
  418. cnss_pr_dbg("Unsupported bus type: %d\n",
  419. plat_priv->bus_type);
  420. return 0;
  421. }
  422. }
  423. int cnss_bus_check_link_status(struct cnss_plat_data *plat_priv)
  424. {
  425. if (!plat_priv)
  426. return -ENODEV;
  427. switch (plat_priv->bus_type) {
  428. case CNSS_BUS_PCI:
  429. return cnss_pci_check_link_status(plat_priv->bus_priv);
  430. default:
  431. cnss_pr_dbg("Unsupported bus type: %d\n",
  432. plat_priv->bus_type);
  433. return 0;
  434. }
  435. }
  436. int cnss_bus_recover_link_down(struct cnss_plat_data *plat_priv)
  437. {
  438. if (!plat_priv)
  439. return -ENODEV;
  440. switch (plat_priv->bus_type) {
  441. case CNSS_BUS_PCI:
  442. return cnss_pci_recover_link_down(plat_priv->bus_priv);
  443. default:
  444. cnss_pr_dbg("Unsupported bus type: %d\n",
  445. plat_priv->bus_type);
  446. return -EINVAL;
  447. }
  448. }
  449. int cnss_bus_debug_reg_read(struct cnss_plat_data *plat_priv, u32 offset,
  450. u32 *val, bool raw_access)
  451. {
  452. if (!plat_priv)
  453. return -ENODEV;
  454. switch (plat_priv->bus_type) {
  455. case CNSS_BUS_PCI:
  456. return cnss_pci_debug_reg_read(plat_priv->bus_priv, offset,
  457. val, raw_access);
  458. default:
  459. cnss_pr_dbg("Unsupported bus type: %d\n",
  460. plat_priv->bus_type);
  461. return 0;
  462. }
  463. }
  464. int cnss_bus_debug_reg_write(struct cnss_plat_data *plat_priv, u32 offset,
  465. u32 val, bool raw_access)
  466. {
  467. if (!plat_priv)
  468. return -ENODEV;
  469. switch (plat_priv->bus_type) {
  470. case CNSS_BUS_PCI:
  471. return cnss_pci_debug_reg_write(plat_priv->bus_priv, offset,
  472. val, raw_access);
  473. default:
  474. cnss_pr_dbg("Unsupported bus type: %d\n",
  475. plat_priv->bus_type);
  476. return 0;
  477. }
  478. }
  479. int cnss_bus_get_iova(struct cnss_plat_data *plat_priv, u64 *addr, u64 *size)
  480. {
  481. if (!plat_priv)
  482. return -ENODEV;
  483. switch (plat_priv->bus_type) {
  484. case CNSS_BUS_PCI:
  485. return cnss_pci_get_iova(plat_priv->bus_priv, addr, size);
  486. default:
  487. cnss_pr_err("Unsupported bus type: %d\n",
  488. plat_priv->bus_type);
  489. return -EINVAL;
  490. }
  491. }
  492. int cnss_bus_get_iova_ipa(struct cnss_plat_data *plat_priv, u64 *addr,
  493. u64 *size)
  494. {
  495. if (!plat_priv)
  496. return -ENODEV;
  497. switch (plat_priv->bus_type) {
  498. case CNSS_BUS_PCI:
  499. return cnss_pci_get_iova_ipa(plat_priv->bus_priv, addr, size);
  500. default:
  501. cnss_pr_err("Unsupported bus type: %d\n",
  502. plat_priv->bus_type);
  503. return -EINVAL;
  504. }
  505. }
  506. int cnss_bus_update_time_sync_period(struct cnss_plat_data *plat_priv,
  507. unsigned int time_sync_period)
  508. {
  509. if (!plat_priv)
  510. return -ENODEV;
  511. switch (plat_priv->bus_type) {
  512. case CNSS_BUS_PCI:
  513. return cnss_pci_update_time_sync_period(plat_priv->bus_priv,
  514. time_sync_period);
  515. default:
  516. cnss_pr_err("Unsupported bus type: %d\n",
  517. plat_priv->bus_type);
  518. return -EINVAL;
  519. }
  520. }
  521. #if IS_ENABLED(CONFIG_MHI_BUS_MISC)
  522. void cnss_bus_disable_mhi_satellite_cfg(struct cnss_plat_data *plat_priv)
  523. {
  524. struct cnss_pci_data *pci_priv;
  525. pci_priv = plat_priv->bus_priv;
  526. if (!pci_priv) {
  527. cnss_pr_err("mhi satellite could not be disabled since pci_priv is NULL\n");
  528. return;
  529. }
  530. switch (plat_priv->bus_type) {
  531. case CNSS_BUS_PCI:
  532. /* MHI satellite configuration is only for KIWI V2 and
  533. * that too only in DRV mode.
  534. */
  535. if (plat_priv->device_id == KIWI_DEVICE_ID &&
  536. plat_priv->device_version.major_version == FW_V2_NUMBER) {
  537. cnss_pr_dbg("Remove MHI satellite configuration\n");
  538. return cnss_mhi_controller_set_base(pci_priv, 0);
  539. }
  540. break;
  541. default:
  542. cnss_pr_dbg("Unsupported bus type: %d, ignore disable mhi satellite cfg\n",
  543. plat_priv->bus_type);
  544. return;
  545. }
  546. return;
  547. }
  548. #else
  549. void cnss_bus_disable_mhi_satellite_cfg(struct cnss_plat_data *pci_priv)
  550. {
  551. }
  552. #endif