pci_qcom.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */
  3. #include "pci_platform.h"
  4. #include "debug.h"
  5. static struct cnss_msi_config msi_config = {
  6. .total_vectors = 32,
  7. .total_users = MSI_USERS,
  8. .users = (struct cnss_msi_user[]) {
  9. { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
  10. { .name = "CE", .num_vectors = 10, .base_vector = 3 },
  11. { .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
  12. { .name = "DP", .num_vectors = 18, .base_vector = 14 },
  13. },
  14. };
  15. #ifdef CONFIG_ONE_MSI_VECTOR
  16. /**
  17. * All the user share the same vector and msi data
  18. * For MHI user, we need pass IRQ array information to MHI component
  19. * MHI_IRQ_NUMBER is defined to specify this MHI IRQ array size
  20. */
  21. #define MHI_IRQ_NUMBER 3
  22. static struct cnss_msi_config msi_config_one_msi = {
  23. .total_vectors = 1,
  24. .total_users = 4,
  25. .users = (struct cnss_msi_user[]) {
  26. { .name = "MHI", .num_vectors = 1, .base_vector = 0 },
  27. { .name = "CE", .num_vectors = 1, .base_vector = 0 },
  28. { .name = "WAKE", .num_vectors = 1, .base_vector = 0 },
  29. { .name = "DP", .num_vectors = 1, .base_vector = 0 },
  30. },
  31. };
  32. #endif
  33. int _cnss_pci_enumerate(struct cnss_plat_data *plat_priv, u32 rc_num)
  34. {
  35. return msm_pcie_enumerate(rc_num);
  36. }
  37. int cnss_pci_assert_perst(struct cnss_pci_data *pci_priv)
  38. {
  39. struct pci_dev *pci_dev = pci_priv->pci_dev;
  40. return msm_pcie_pm_control(MSM_PCIE_HANDLE_LINKDOWN,
  41. pci_dev->bus->number, pci_dev, NULL,
  42. PM_OPTIONS_DEFAULT);
  43. }
  44. int cnss_pci_disable_pc(struct cnss_pci_data *pci_priv, bool vote)
  45. {
  46. struct pci_dev *pci_dev = pci_priv->pci_dev;
  47. return msm_pcie_pm_control(vote ? MSM_PCIE_DISABLE_PC :
  48. MSM_PCIE_ENABLE_PC,
  49. pci_dev->bus->number, pci_dev, NULL,
  50. PM_OPTIONS_DEFAULT);
  51. }
  52. int cnss_pci_set_link_bandwidth(struct cnss_pci_data *pci_priv,
  53. u16 link_speed, u16 link_width)
  54. {
  55. return msm_pcie_set_link_bandwidth(pci_priv->pci_dev,
  56. link_speed, link_width);
  57. }
  58. int cnss_pci_set_max_link_speed(struct cnss_pci_data *pci_priv,
  59. u32 rc_num, u16 link_speed)
  60. {
  61. return msm_pcie_set_target_link_speed(rc_num, link_speed, false);
  62. }
  63. /**
  64. * _cnss_pci_prevent_l1() - Prevent PCIe L1 and L1 sub-states
  65. * @pci_priv: driver PCI bus context pointer
  66. *
  67. * This function shall call corresponding PCIe root complex driver APIs
  68. * to prevent PCIe link enter L1 and L1 sub-states. The APIs should also
  69. * bring link out of L1 or L1 sub-states if any and avoid synchronization
  70. * issues if any.
  71. *
  72. * Return: 0 for success, negative value for error
  73. */
  74. static int _cnss_pci_prevent_l1(struct cnss_pci_data *pci_priv)
  75. {
  76. return msm_pcie_prevent_l1(pci_priv->pci_dev);
  77. }
  78. /**
  79. * _cnss_pci_allow_l1() - Allow PCIe L1 and L1 sub-states
  80. * @pci_priv: driver PCI bus context pointer
  81. *
  82. * This function shall call corresponding PCIe root complex driver APIs
  83. * to allow PCIe link enter L1 and L1 sub-states. The APIs should avoid
  84. * synchronization issues if any.
  85. *
  86. * Return: 0 for success, negative value for error
  87. */
  88. static void _cnss_pci_allow_l1(struct cnss_pci_data *pci_priv)
  89. {
  90. msm_pcie_allow_l1(pci_priv->pci_dev);
  91. }
  92. /**
  93. * cnss_pci_set_link_up() - Power on or resume PCIe link
  94. * @pci_priv: driver PCI bus context pointer
  95. *
  96. * This function shall call corresponding PCIe root complex driver APIs
  97. * to Power on or resume PCIe link.
  98. *
  99. * Return: 0 for success, negative value for error
  100. */
  101. static int cnss_pci_set_link_up(struct cnss_pci_data *pci_priv)
  102. {
  103. struct pci_dev *pci_dev = pci_priv->pci_dev;
  104. enum msm_pcie_pm_opt pm_ops = MSM_PCIE_RESUME;
  105. u32 pm_options = PM_OPTIONS_DEFAULT;
  106. int ret;
  107. ret = msm_pcie_pm_control(pm_ops, pci_dev->bus->number, pci_dev,
  108. NULL, pm_options);
  109. if (ret)
  110. cnss_pr_err("Failed to resume PCI link with default option, err = %d\n",
  111. ret);
  112. return ret;
  113. }
  114. /**
  115. * cnss_pci_set_link_down() - Power off or suspend PCIe link
  116. * @pci_priv: driver PCI bus context pointer
  117. *
  118. * This function shall call corresponding PCIe root complex driver APIs
  119. * to power off or suspend PCIe link.
  120. *
  121. * Return: 0 for success, negative value for error
  122. */
  123. static int cnss_pci_set_link_down(struct cnss_pci_data *pci_priv)
  124. {
  125. struct pci_dev *pci_dev = pci_priv->pci_dev;
  126. enum msm_pcie_pm_opt pm_ops;
  127. u32 pm_options = PM_OPTIONS_DEFAULT;
  128. int ret;
  129. if (pci_priv->drv_connected_last) {
  130. cnss_pr_vdbg("Use PCIe DRV suspend\n");
  131. pm_ops = MSM_PCIE_DRV_SUSPEND;
  132. } else {
  133. pm_ops = MSM_PCIE_SUSPEND;
  134. }
  135. ret = msm_pcie_pm_control(pm_ops, pci_dev->bus->number, pci_dev,
  136. NULL, pm_options);
  137. if (ret)
  138. cnss_pr_err("Failed to suspend PCI link with default option, err = %d\n",
  139. ret);
  140. return ret;
  141. }
  142. void cnss_pci_update_drv_supported(struct cnss_pci_data *pci_priv)
  143. {
  144. struct pci_dev *root_port = pcie_find_root_port(pci_priv->pci_dev);
  145. struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
  146. struct device_node *root_of_node;
  147. bool drv_supported = false;
  148. if (!root_port) {
  149. cnss_pr_err("PCIe DRV is not supported as root port is null\n");
  150. pci_priv->drv_supported = false;
  151. return;
  152. }
  153. root_of_node = root_port->dev.of_node;
  154. if (root_of_node->parent) {
  155. drv_supported = of_property_read_bool(root_of_node->parent,
  156. "qcom,drv-supported") ||
  157. of_property_read_bool(root_of_node->parent,
  158. "qcom,drv-name");
  159. }
  160. cnss_pr_dbg("PCIe DRV is %s\n",
  161. drv_supported ? "supported" : "not supported");
  162. pci_priv->drv_supported = drv_supported;
  163. if (drv_supported) {
  164. plat_priv->cap.cap_flag |= CNSS_HAS_DRV_SUPPORT;
  165. cnss_set_feature_list(plat_priv, CNSS_DRV_SUPPORT_V01);
  166. }
  167. }
  168. static void cnss_pci_event_cb(struct msm_pcie_notify *notify)
  169. {
  170. struct pci_dev *pci_dev;
  171. struct cnss_pci_data *pci_priv;
  172. struct device *dev;
  173. struct cnss_plat_data *plat_priv = NULL;
  174. int ret = 0;
  175. if (!notify)
  176. return;
  177. pci_dev = notify->user;
  178. if (!pci_dev)
  179. return;
  180. pci_priv = cnss_get_pci_priv(pci_dev);
  181. if (!pci_priv)
  182. return;
  183. dev = &pci_priv->pci_dev->dev;
  184. switch (notify->event) {
  185. case MSM_PCIE_EVENT_LINK_RECOVER:
  186. cnss_pr_dbg("PCI link recover callback\n");
  187. plat_priv = pci_priv->plat_priv;
  188. if (!plat_priv) {
  189. cnss_pr_err("plat_priv is NULL\n");
  190. return;
  191. }
  192. plat_priv->ctrl_params.quirks |= BIT(LINK_DOWN_SELF_RECOVERY);
  193. ret = msm_pcie_pm_control(MSM_PCIE_HANDLE_LINKDOWN,
  194. pci_dev->bus->number, pci_dev, NULL,
  195. PM_OPTIONS_DEFAULT);
  196. if (ret)
  197. cnss_pci_handle_linkdown(pci_priv);
  198. break;
  199. case MSM_PCIE_EVENT_LINKDOWN:
  200. cnss_pr_dbg("PCI link down event callback\n");
  201. cnss_pci_handle_linkdown(pci_priv);
  202. break;
  203. case MSM_PCIE_EVENT_WAKEUP:
  204. cnss_pr_dbg("PCI Wake up event callback\n");
  205. if ((cnss_pci_get_monitor_wake_intr(pci_priv) &&
  206. cnss_pci_get_auto_suspended(pci_priv)) ||
  207. dev->power.runtime_status == RPM_SUSPENDING) {
  208. cnss_pci_set_monitor_wake_intr(pci_priv, false);
  209. cnss_pci_pm_request_resume(pci_priv);
  210. }
  211. complete(&pci_priv->wake_event_complete);
  212. break;
  213. case MSM_PCIE_EVENT_DRV_CONNECT:
  214. cnss_pr_dbg("DRV subsystem is connected\n");
  215. cnss_pci_set_drv_connected(pci_priv, 1);
  216. break;
  217. case MSM_PCIE_EVENT_DRV_DISCONNECT:
  218. cnss_pr_dbg("DRV subsystem is disconnected\n");
  219. if (cnss_pci_get_auto_suspended(pci_priv))
  220. cnss_pci_pm_request_resume(pci_priv);
  221. cnss_pci_set_drv_connected(pci_priv, 0);
  222. break;
  223. default:
  224. cnss_pr_err("Received invalid PCI event: %d\n", notify->event);
  225. }
  226. }
  227. int cnss_reg_pci_event(struct cnss_pci_data *pci_priv)
  228. {
  229. int ret = 0;
  230. struct msm_pcie_register_event *pci_event;
  231. pci_event = &pci_priv->msm_pci_event;
  232. pci_event->events = MSM_PCIE_EVENT_LINK_RECOVER |
  233. MSM_PCIE_EVENT_LINKDOWN |
  234. MSM_PCIE_EVENT_WAKEUP;
  235. if (cnss_pci_get_drv_supported(pci_priv))
  236. pci_event->events = pci_event->events |
  237. MSM_PCIE_EVENT_DRV_CONNECT |
  238. MSM_PCIE_EVENT_DRV_DISCONNECT;
  239. pci_event->user = pci_priv->pci_dev;
  240. pci_event->mode = MSM_PCIE_TRIGGER_CALLBACK;
  241. pci_event->callback = cnss_pci_event_cb;
  242. pci_event->options = MSM_PCIE_CONFIG_NO_RECOVERY;
  243. ret = msm_pcie_register_event(pci_event);
  244. if (ret)
  245. cnss_pr_err("Failed to register MSM PCI event, err = %d\n",
  246. ret);
  247. return ret;
  248. }
  249. void cnss_dereg_pci_event(struct cnss_pci_data *pci_priv)
  250. {
  251. msm_pcie_deregister_event(&pci_priv->msm_pci_event);
  252. }
  253. int cnss_wlan_adsp_pc_enable(struct cnss_pci_data *pci_priv,
  254. bool control)
  255. {
  256. struct pci_dev *pci_dev = pci_priv->pci_dev;
  257. int ret = 0;
  258. u32 pm_options = PM_OPTIONS_DEFAULT;
  259. struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
  260. if (!cnss_pci_get_drv_supported(pci_priv))
  261. return 0;
  262. if (plat_priv->adsp_pc_enabled == control) {
  263. cnss_pr_dbg("ADSP power collapse already %s\n",
  264. control ? "Enabled" : "Disabled");
  265. return 0;
  266. }
  267. if (control)
  268. pm_options &= ~MSM_PCIE_CONFIG_NO_DRV_PC;
  269. else
  270. pm_options |= MSM_PCIE_CONFIG_NO_DRV_PC;
  271. ret = msm_pcie_pm_control(MSM_PCIE_DRV_PC_CTRL, pci_dev->bus->number,
  272. pci_dev, NULL, pm_options);
  273. if (ret)
  274. return ret;
  275. cnss_pr_dbg("%s ADSP power collapse\n", control ? "Enable" : "Disable");
  276. plat_priv->adsp_pc_enabled = control;
  277. return 0;
  278. }
  279. static int cnss_set_pci_link_status(struct cnss_pci_data *pci_priv,
  280. enum pci_link_status status)
  281. {
  282. u16 link_speed, link_width = pci_priv->def_link_width;
  283. u16 one_lane = PCI_EXP_LNKSTA_NLW_X1 >> PCI_EXP_LNKSTA_NLW_SHIFT;
  284. int ret;
  285. cnss_pr_vdbg("Set PCI link status to: %u\n", status);
  286. switch (status) {
  287. case PCI_GEN1:
  288. link_speed = PCI_EXP_LNKSTA_CLS_2_5GB;
  289. if (!link_width)
  290. link_width = one_lane;
  291. break;
  292. case PCI_GEN2:
  293. link_speed = PCI_EXP_LNKSTA_CLS_5_0GB;
  294. if (!link_width)
  295. link_width = one_lane;
  296. break;
  297. case PCI_DEF:
  298. link_speed = pci_priv->def_link_speed;
  299. if (!link_speed || !link_width) {
  300. cnss_pr_err("PCI link speed or width is not valid\n");
  301. return -EINVAL;
  302. }
  303. break;
  304. default:
  305. cnss_pr_err("Unknown PCI link status config: %u\n", status);
  306. return -EINVAL;
  307. }
  308. ret = cnss_pci_set_link_bandwidth(pci_priv, link_speed, link_width);
  309. if (!ret)
  310. pci_priv->cur_link_speed = link_speed;
  311. return ret;
  312. }
  313. int cnss_set_pci_link(struct cnss_pci_data *pci_priv, bool link_up)
  314. {
  315. int ret = 0, retry = 0;
  316. cnss_pr_vdbg("%s PCI link\n", link_up ? "Resuming" : "Suspending");
  317. if (link_up) {
  318. retry:
  319. ret = cnss_pci_set_link_up(pci_priv);
  320. if (ret && retry++ < LINK_TRAINING_RETRY_MAX_TIMES) {
  321. cnss_pr_dbg("Retry PCI link training #%d\n", retry);
  322. if (pci_priv->pci_link_down_ind)
  323. msleep(LINK_TRAINING_RETRY_DELAY_MS * retry);
  324. goto retry;
  325. }
  326. } else {
  327. /* Since DRV suspend cannot be done in Gen 3, set it to
  328. * Gen 2 if current link speed is larger than Gen 2.
  329. */
  330. if (pci_priv->drv_connected_last &&
  331. pci_priv->cur_link_speed > PCI_EXP_LNKSTA_CLS_5_0GB)
  332. cnss_set_pci_link_status(pci_priv, PCI_GEN2);
  333. ret = cnss_pci_set_link_down(pci_priv);
  334. }
  335. if (pci_priv->drv_connected_last) {
  336. if ((link_up && !ret) || (!link_up && ret))
  337. cnss_set_pci_link_status(pci_priv, PCI_DEF);
  338. }
  339. return ret;
  340. }
  341. int cnss_pci_prevent_l1(struct device *dev)
  342. {
  343. struct pci_dev *pci_dev = to_pci_dev(dev);
  344. struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
  345. int ret;
  346. if (!pci_priv) {
  347. cnss_pr_err("pci_priv is NULL\n");
  348. return -ENODEV;
  349. }
  350. if (pci_priv->pci_link_state == PCI_LINK_DOWN) {
  351. cnss_pr_dbg("PCIe link is in suspend state\n");
  352. return -EIO;
  353. }
  354. if (pci_priv->pci_link_down_ind) {
  355. cnss_pr_err("PCIe link is down\n");
  356. return -EIO;
  357. }
  358. ret = _cnss_pci_prevent_l1(pci_priv);
  359. if (ret == -EIO) {
  360. cnss_pr_err("Failed to prevent PCIe L1, considered as link down\n");
  361. cnss_pci_link_down(dev);
  362. }
  363. return ret;
  364. }
  365. EXPORT_SYMBOL(cnss_pci_prevent_l1);
  366. void cnss_pci_allow_l1(struct device *dev)
  367. {
  368. struct pci_dev *pci_dev = to_pci_dev(dev);
  369. struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
  370. if (!pci_priv) {
  371. cnss_pr_err("pci_priv is NULL\n");
  372. return;
  373. }
  374. if (pci_priv->pci_link_state == PCI_LINK_DOWN) {
  375. cnss_pr_dbg("PCIe link is in suspend state\n");
  376. return;
  377. }
  378. if (pci_priv->pci_link_down_ind) {
  379. cnss_pr_err("PCIe link is down\n");
  380. return;
  381. }
  382. _cnss_pci_allow_l1(pci_priv);
  383. }
  384. EXPORT_SYMBOL(cnss_pci_allow_l1);
  385. int cnss_pci_get_msi_assignment(struct cnss_pci_data *pci_priv)
  386. {
  387. pci_priv->msi_config = &msi_config;
  388. return 0;
  389. }
  390. #ifdef CONFIG_ONE_MSI_VECTOR
  391. int cnss_pci_get_one_msi_assignment(struct cnss_pci_data *pci_priv)
  392. {
  393. pci_priv->msi_config = &msi_config_one_msi;
  394. return 0;
  395. }
  396. bool cnss_pci_fallback_one_msi(struct cnss_pci_data *pci_priv,
  397. int *num_vectors)
  398. {
  399. struct pci_dev *pci_dev = pci_priv->pci_dev;
  400. struct cnss_msi_config *msi_config;
  401. cnss_pci_get_one_msi_assignment(pci_priv);
  402. msi_config = pci_priv->msi_config;
  403. if (!msi_config) {
  404. cnss_pr_err("one msi_config is NULL!\n");
  405. return false;
  406. }
  407. *num_vectors = pci_alloc_irq_vectors(pci_dev,
  408. msi_config->total_vectors,
  409. msi_config->total_vectors,
  410. PCI_IRQ_MSI);
  411. if (*num_vectors < 0) {
  412. cnss_pr_err("Failed to get one MSI vector!\n");
  413. return false;
  414. }
  415. cnss_pr_dbg("request MSI one vector\n");
  416. return true;
  417. }
  418. bool cnss_pci_is_one_msi(struct cnss_pci_data *pci_priv)
  419. {
  420. return pci_priv && pci_priv->msi_config &&
  421. (pci_priv->msi_config->total_vectors == 1);
  422. }
  423. int cnss_pci_get_one_msi_mhi_irq_array_size(struct cnss_pci_data *pci_priv)
  424. {
  425. return MHI_IRQ_NUMBER;
  426. }
  427. bool cnss_pci_is_force_one_msi(struct cnss_pci_data *pci_priv)
  428. {
  429. struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
  430. return test_bit(FORCE_ONE_MSI, &plat_priv->ctrl_params.quirks);
  431. }
  432. #else
  433. int cnss_pci_get_one_msi_assignment(struct cnss_pci_data *pci_priv)
  434. {
  435. return 0;
  436. }
  437. bool cnss_pci_fallback_one_msi(struct cnss_pci_data *pci_priv,
  438. int *num_vectors)
  439. {
  440. return false;
  441. }
  442. bool cnss_pci_is_one_msi(struct cnss_pci_data *pci_priv)
  443. {
  444. return false;
  445. }
  446. int cnss_pci_get_one_msi_mhi_irq_array_size(struct cnss_pci_data *pci_priv)
  447. {
  448. return 0;
  449. }
  450. bool cnss_pci_is_force_one_msi(struct cnss_pci_data *pci_priv)
  451. {
  452. return false;
  453. }
  454. #endif
  455. static int cnss_pci_smmu_fault_handler(struct iommu_domain *domain,
  456. struct device *dev, unsigned long iova,
  457. int flags, void *handler_token)
  458. {
  459. struct cnss_pci_data *pci_priv = handler_token;
  460. cnss_fatal_err("SMMU fault happened with IOVA 0x%lx\n", iova);
  461. if (!pci_priv) {
  462. cnss_pr_err("pci_priv is NULL\n");
  463. return -ENODEV;
  464. }
  465. pci_priv->is_smmu_fault = true;
  466. cnss_pci_update_status(pci_priv, CNSS_FW_DOWN);
  467. cnss_force_fw_assert(&pci_priv->pci_dev->dev);
  468. /* IOMMU driver requires -ENOSYS to print debug info. */
  469. return -ENOSYS;
  470. }
  471. int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
  472. {
  473. struct pci_dev *pci_dev = pci_priv->pci_dev;
  474. struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
  475. struct device_node *of_node;
  476. struct resource *res;
  477. const char *iommu_dma_type;
  478. u32 addr_win[2];
  479. int ret = 0;
  480. of_node = of_parse_phandle(pci_dev->dev.of_node, "qcom,iommu-group", 0);
  481. if (!of_node)
  482. return ret;
  483. cnss_pr_dbg("Initializing SMMU\n");
  484. pci_priv->iommu_domain = iommu_get_domain_for_dev(&pci_dev->dev);
  485. ret = of_property_read_string(of_node, "qcom,iommu-dma",
  486. &iommu_dma_type);
  487. if (!ret && !strcmp("fastmap", iommu_dma_type)) {
  488. cnss_pr_dbg("Enabling SMMU S1 stage\n");
  489. pci_priv->smmu_s1_enable = true;
  490. iommu_set_fault_handler(pci_priv->iommu_domain,
  491. cnss_pci_smmu_fault_handler, pci_priv);
  492. cnss_register_iommu_fault_handler_irq(pci_priv);
  493. }
  494. ret = of_property_read_u32_array(of_node, "qcom,iommu-dma-addr-pool",
  495. addr_win, ARRAY_SIZE(addr_win));
  496. if (ret) {
  497. cnss_pr_err("Invalid SMMU size window, err = %d\n", ret);
  498. of_node_put(of_node);
  499. return ret;
  500. }
  501. pci_priv->smmu_iova_start = addr_win[0];
  502. pci_priv->smmu_iova_len = addr_win[1];
  503. cnss_pr_dbg("smmu_iova_start: %pa, smmu_iova_len: 0x%zx\n",
  504. &pci_priv->smmu_iova_start,
  505. pci_priv->smmu_iova_len);
  506. res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM,
  507. "smmu_iova_ipa");
  508. if (res) {
  509. pci_priv->smmu_iova_ipa_start = res->start;
  510. pci_priv->smmu_iova_ipa_current = res->start;
  511. pci_priv->smmu_iova_ipa_len = resource_size(res);
  512. cnss_pr_dbg("smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: 0x%zx\n",
  513. &pci_priv->smmu_iova_ipa_start,
  514. pci_priv->smmu_iova_ipa_len);
  515. }
  516. pci_priv->iommu_geometry = of_property_read_bool(of_node,
  517. "qcom,iommu-geometry");
  518. cnss_pr_dbg("iommu_geometry: %d\n", pci_priv->iommu_geometry);
  519. of_node_put(of_node);
  520. return 0;
  521. }
  522. int _cnss_pci_get_reg_dump(struct cnss_pci_data *pci_priv,
  523. u8 *buf, u32 len)
  524. {
  525. return msm_pcie_reg_dump(pci_priv->pci_dev, buf, len);
  526. }
  527. #if IS_ENABLED(CONFIG_ARCH_QCOM)
  528. /**
  529. * cnss_pci_of_reserved_mem_device_init() - Assign reserved memory region
  530. * to given PCI device
  531. * @pci_priv: driver PCI bus context pointer
  532. *
  533. * This function shall call corresponding of_reserved_mem_device* API to
  534. * assign reserved memory region to PCI device based on where the memory is
  535. * defined and attached to (platform device of_node or PCI device of_node)
  536. * in device tree.
  537. *
  538. * Return: 0 for success, negative value for error
  539. */
  540. int cnss_pci_of_reserved_mem_device_init(struct cnss_pci_data *pci_priv)
  541. {
  542. struct device *dev_pci = &pci_priv->pci_dev->dev;
  543. int ret;
  544. /* Use of_reserved_mem_device_init_by_idx() if reserved memory is
  545. * attached to platform device of_node.
  546. */
  547. ret = of_reserved_mem_device_init(dev_pci);
  548. if (ret) {
  549. if (ret == -EINVAL)
  550. cnss_pr_vdbg("Ignore, no specific reserved-memory assigned\n");
  551. else
  552. cnss_pr_err("Failed to init reserved mem device, err = %d\n",
  553. ret);
  554. }
  555. if (dev_pci->cma_area)
  556. cnss_pr_dbg("CMA area is %s\n",
  557. cma_get_name(dev_pci->cma_area));
  558. return ret;
  559. }
  560. int cnss_pci_wake_gpio_init(struct cnss_pci_data *pci_priv)
  561. {
  562. return 0;
  563. }
  564. void cnss_pci_wake_gpio_deinit(struct cnss_pci_data *pci_priv)
  565. {
  566. }
  567. #endif