msm8974.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2019 Brian Masney <masneyb@onstation.org>
  4. *
  5. * Based on MSM bus code from downstream MSM kernel sources.
  6. * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
  7. *
  8. * Based on qcs404.c
  9. * Copyright (C) 2019 Linaro Ltd
  10. *
  11. * Here's a rough representation that shows the various buses that form the
  12. * Network On Chip (NOC) for the msm8974:
  13. *
  14. * Multimedia Subsystem (MMSS)
  15. * |----------+-----------------------------------+-----------|
  16. * | |
  17. * | |
  18. * Config | Bus Interface | Memory Controller
  19. * |------------+-+-----------| |------------+-+-----------|
  20. * | |
  21. * | |
  22. * | System |
  23. * |--------------+-+---------------------------------+-+-------------|
  24. * | |
  25. * | |
  26. * Peripheral | On Chip | Memory (OCMEM)
  27. * |------------+-------------| |------------+-------------|
  28. */
  29. #include <dt-bindings/interconnect/qcom,msm8974.h>
  30. #include <linux/clk.h>
  31. #include <linux/device.h>
  32. #include <linux/interconnect-provider.h>
  33. #include <linux/io.h>
  34. #include <linux/module.h>
  35. #include <linux/of_device.h>
  36. #include <linux/of_platform.h>
  37. #include <linux/platform_device.h>
  38. #include <linux/slab.h>
  39. #include "smd-rpm.h"
  40. enum {
  41. MSM8974_BIMC_MAS_AMPSS_M0 = 1,
  42. MSM8974_BIMC_MAS_AMPSS_M1,
  43. MSM8974_BIMC_MAS_MSS_PROC,
  44. MSM8974_BIMC_TO_MNOC,
  45. MSM8974_BIMC_TO_SNOC,
  46. MSM8974_BIMC_SLV_EBI_CH0,
  47. MSM8974_BIMC_SLV_AMPSS_L2,
  48. MSM8974_CNOC_MAS_RPM_INST,
  49. MSM8974_CNOC_MAS_RPM_DATA,
  50. MSM8974_CNOC_MAS_RPM_SYS,
  51. MSM8974_CNOC_MAS_DEHR,
  52. MSM8974_CNOC_MAS_QDSS_DAP,
  53. MSM8974_CNOC_MAS_SPDM,
  54. MSM8974_CNOC_MAS_TIC,
  55. MSM8974_CNOC_SLV_CLK_CTL,
  56. MSM8974_CNOC_SLV_CNOC_MSS,
  57. MSM8974_CNOC_SLV_SECURITY,
  58. MSM8974_CNOC_SLV_TCSR,
  59. MSM8974_CNOC_SLV_TLMM,
  60. MSM8974_CNOC_SLV_CRYPTO_0_CFG,
  61. MSM8974_CNOC_SLV_CRYPTO_1_CFG,
  62. MSM8974_CNOC_SLV_IMEM_CFG,
  63. MSM8974_CNOC_SLV_MESSAGE_RAM,
  64. MSM8974_CNOC_SLV_BIMC_CFG,
  65. MSM8974_CNOC_SLV_BOOT_ROM,
  66. MSM8974_CNOC_SLV_PMIC_ARB,
  67. MSM8974_CNOC_SLV_SPDM_WRAPPER,
  68. MSM8974_CNOC_SLV_DEHR_CFG,
  69. MSM8974_CNOC_SLV_MPM,
  70. MSM8974_CNOC_SLV_QDSS_CFG,
  71. MSM8974_CNOC_SLV_RBCPR_CFG,
  72. MSM8974_CNOC_SLV_RBCPR_QDSS_APU_CFG,
  73. MSM8974_CNOC_TO_SNOC,
  74. MSM8974_CNOC_SLV_CNOC_ONOC_CFG,
  75. MSM8974_CNOC_SLV_CNOC_MNOC_MMSS_CFG,
  76. MSM8974_CNOC_SLV_CNOC_MNOC_CFG,
  77. MSM8974_CNOC_SLV_PNOC_CFG,
  78. MSM8974_CNOC_SLV_SNOC_MPU_CFG,
  79. MSM8974_CNOC_SLV_SNOC_CFG,
  80. MSM8974_CNOC_SLV_EBI1_DLL_CFG,
  81. MSM8974_CNOC_SLV_PHY_APU_CFG,
  82. MSM8974_CNOC_SLV_EBI1_PHY_CFG,
  83. MSM8974_CNOC_SLV_RPM,
  84. MSM8974_CNOC_SLV_SERVICE_CNOC,
  85. MSM8974_MNOC_MAS_GRAPHICS_3D,
  86. MSM8974_MNOC_MAS_JPEG,
  87. MSM8974_MNOC_MAS_MDP_PORT0,
  88. MSM8974_MNOC_MAS_VIDEO_P0,
  89. MSM8974_MNOC_MAS_VIDEO_P1,
  90. MSM8974_MNOC_MAS_VFE,
  91. MSM8974_MNOC_TO_CNOC,
  92. MSM8974_MNOC_TO_BIMC,
  93. MSM8974_MNOC_SLV_CAMERA_CFG,
  94. MSM8974_MNOC_SLV_DISPLAY_CFG,
  95. MSM8974_MNOC_SLV_OCMEM_CFG,
  96. MSM8974_MNOC_SLV_CPR_CFG,
  97. MSM8974_MNOC_SLV_CPR_XPU_CFG,
  98. MSM8974_MNOC_SLV_MISC_CFG,
  99. MSM8974_MNOC_SLV_MISC_XPU_CFG,
  100. MSM8974_MNOC_SLV_VENUS_CFG,
  101. MSM8974_MNOC_SLV_GRAPHICS_3D_CFG,
  102. MSM8974_MNOC_SLV_MMSS_CLK_CFG,
  103. MSM8974_MNOC_SLV_MMSS_CLK_XPU_CFG,
  104. MSM8974_MNOC_SLV_MNOC_MPU_CFG,
  105. MSM8974_MNOC_SLV_ONOC_MPU_CFG,
  106. MSM8974_MNOC_SLV_SERVICE_MNOC,
  107. MSM8974_OCMEM_NOC_TO_OCMEM_VNOC,
  108. MSM8974_OCMEM_MAS_JPEG_OCMEM,
  109. MSM8974_OCMEM_MAS_MDP_OCMEM,
  110. MSM8974_OCMEM_MAS_VIDEO_P0_OCMEM,
  111. MSM8974_OCMEM_MAS_VIDEO_P1_OCMEM,
  112. MSM8974_OCMEM_MAS_VFE_OCMEM,
  113. MSM8974_OCMEM_MAS_CNOC_ONOC_CFG,
  114. MSM8974_OCMEM_SLV_SERVICE_ONOC,
  115. MSM8974_OCMEM_VNOC_TO_SNOC,
  116. MSM8974_OCMEM_VNOC_TO_OCMEM_NOC,
  117. MSM8974_OCMEM_VNOC_MAS_GFX3D,
  118. MSM8974_OCMEM_SLV_OCMEM,
  119. MSM8974_PNOC_MAS_PNOC_CFG,
  120. MSM8974_PNOC_MAS_SDCC_1,
  121. MSM8974_PNOC_MAS_SDCC_3,
  122. MSM8974_PNOC_MAS_SDCC_4,
  123. MSM8974_PNOC_MAS_SDCC_2,
  124. MSM8974_PNOC_MAS_TSIF,
  125. MSM8974_PNOC_MAS_BAM_DMA,
  126. MSM8974_PNOC_MAS_BLSP_2,
  127. MSM8974_PNOC_MAS_USB_HSIC,
  128. MSM8974_PNOC_MAS_BLSP_1,
  129. MSM8974_PNOC_MAS_USB_HS,
  130. MSM8974_PNOC_TO_SNOC,
  131. MSM8974_PNOC_SLV_SDCC_1,
  132. MSM8974_PNOC_SLV_SDCC_3,
  133. MSM8974_PNOC_SLV_SDCC_2,
  134. MSM8974_PNOC_SLV_SDCC_4,
  135. MSM8974_PNOC_SLV_TSIF,
  136. MSM8974_PNOC_SLV_BAM_DMA,
  137. MSM8974_PNOC_SLV_BLSP_2,
  138. MSM8974_PNOC_SLV_USB_HSIC,
  139. MSM8974_PNOC_SLV_BLSP_1,
  140. MSM8974_PNOC_SLV_USB_HS,
  141. MSM8974_PNOC_SLV_PDM,
  142. MSM8974_PNOC_SLV_PERIPH_APU_CFG,
  143. MSM8974_PNOC_SLV_PNOC_MPU_CFG,
  144. MSM8974_PNOC_SLV_PRNG,
  145. MSM8974_PNOC_SLV_SERVICE_PNOC,
  146. MSM8974_SNOC_MAS_LPASS_AHB,
  147. MSM8974_SNOC_MAS_QDSS_BAM,
  148. MSM8974_SNOC_MAS_SNOC_CFG,
  149. MSM8974_SNOC_TO_BIMC,
  150. MSM8974_SNOC_TO_CNOC,
  151. MSM8974_SNOC_TO_PNOC,
  152. MSM8974_SNOC_TO_OCMEM_VNOC,
  153. MSM8974_SNOC_MAS_CRYPTO_CORE0,
  154. MSM8974_SNOC_MAS_CRYPTO_CORE1,
  155. MSM8974_SNOC_MAS_LPASS_PROC,
  156. MSM8974_SNOC_MAS_MSS,
  157. MSM8974_SNOC_MAS_MSS_NAV,
  158. MSM8974_SNOC_MAS_OCMEM_DMA,
  159. MSM8974_SNOC_MAS_WCSS,
  160. MSM8974_SNOC_MAS_QDSS_ETR,
  161. MSM8974_SNOC_MAS_USB3,
  162. MSM8974_SNOC_SLV_AMPSS,
  163. MSM8974_SNOC_SLV_LPASS,
  164. MSM8974_SNOC_SLV_USB3,
  165. MSM8974_SNOC_SLV_WCSS,
  166. MSM8974_SNOC_SLV_OCIMEM,
  167. MSM8974_SNOC_SLV_SNOC_OCMEM,
  168. MSM8974_SNOC_SLV_SERVICE_SNOC,
  169. MSM8974_SNOC_SLV_QDSS_STM,
  170. };
  171. #define RPM_BUS_MASTER_REQ 0x73616d62
  172. #define RPM_BUS_SLAVE_REQ 0x766c7362
  173. #define to_msm8974_icc_provider(_provider) \
  174. container_of(_provider, struct msm8974_icc_provider, provider)
  175. static const struct clk_bulk_data msm8974_icc_bus_clocks[] = {
  176. { .id = "bus" },
  177. { .id = "bus_a" },
  178. };
  179. /**
  180. * struct msm8974_icc_provider - Qualcomm specific interconnect provider
  181. * @provider: generic interconnect provider
  182. * @bus_clks: the clk_bulk_data table of bus clocks
  183. * @num_clks: the total number of clk_bulk_data entries
  184. */
  185. struct msm8974_icc_provider {
  186. struct icc_provider provider;
  187. struct clk_bulk_data *bus_clks;
  188. int num_clks;
  189. };
  190. #define MSM8974_ICC_MAX_LINKS 3
  191. /**
  192. * struct msm8974_icc_node - Qualcomm specific interconnect nodes
  193. * @name: the node name used in debugfs
  194. * @id: a unique node identifier
  195. * @links: an array of nodes where we can go next while traversing
  196. * @num_links: the total number of @links
  197. * @buswidth: width of the interconnect between a node and the bus (bytes)
  198. * @mas_rpm_id: RPM ID for devices that are bus masters
  199. * @slv_rpm_id: RPM ID for devices that are bus slaves
  200. * @rate: current bus clock rate in Hz
  201. */
  202. struct msm8974_icc_node {
  203. unsigned char *name;
  204. u16 id;
  205. u16 links[MSM8974_ICC_MAX_LINKS];
  206. u16 num_links;
  207. u16 buswidth;
  208. int mas_rpm_id;
  209. int slv_rpm_id;
  210. u64 rate;
  211. };
  212. struct msm8974_icc_desc {
  213. struct msm8974_icc_node **nodes;
  214. size_t num_nodes;
  215. };
  216. #define DEFINE_QNODE(_name, _id, _buswidth, _mas_rpm_id, _slv_rpm_id, \
  217. ...) \
  218. static struct msm8974_icc_node _name = { \
  219. .name = #_name, \
  220. .id = _id, \
  221. .buswidth = _buswidth, \
  222. .mas_rpm_id = _mas_rpm_id, \
  223. .slv_rpm_id = _slv_rpm_id, \
  224. .num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })), \
  225. .links = { __VA_ARGS__ }, \
  226. }
  227. DEFINE_QNODE(mas_ampss_m0, MSM8974_BIMC_MAS_AMPSS_M0, 8, 0, -1);
  228. DEFINE_QNODE(mas_ampss_m1, MSM8974_BIMC_MAS_AMPSS_M1, 8, 0, -1);
  229. DEFINE_QNODE(mas_mss_proc, MSM8974_BIMC_MAS_MSS_PROC, 8, 1, -1);
  230. DEFINE_QNODE(bimc_to_mnoc, MSM8974_BIMC_TO_MNOC, 8, 2, -1, MSM8974_BIMC_SLV_EBI_CH0);
  231. DEFINE_QNODE(bimc_to_snoc, MSM8974_BIMC_TO_SNOC, 8, 3, 2, MSM8974_SNOC_TO_BIMC, MSM8974_BIMC_SLV_EBI_CH0, MSM8974_BIMC_MAS_AMPSS_M0);
  232. DEFINE_QNODE(slv_ebi_ch0, MSM8974_BIMC_SLV_EBI_CH0, 8, -1, 0);
  233. DEFINE_QNODE(slv_ampss_l2, MSM8974_BIMC_SLV_AMPSS_L2, 8, -1, 1);
  234. static struct msm8974_icc_node *msm8974_bimc_nodes[] = {
  235. [BIMC_MAS_AMPSS_M0] = &mas_ampss_m0,
  236. [BIMC_MAS_AMPSS_M1] = &mas_ampss_m1,
  237. [BIMC_MAS_MSS_PROC] = &mas_mss_proc,
  238. [BIMC_TO_MNOC] = &bimc_to_mnoc,
  239. [BIMC_TO_SNOC] = &bimc_to_snoc,
  240. [BIMC_SLV_EBI_CH0] = &slv_ebi_ch0,
  241. [BIMC_SLV_AMPSS_L2] = &slv_ampss_l2,
  242. };
  243. static struct msm8974_icc_desc msm8974_bimc = {
  244. .nodes = msm8974_bimc_nodes,
  245. .num_nodes = ARRAY_SIZE(msm8974_bimc_nodes),
  246. };
  247. DEFINE_QNODE(mas_rpm_inst, MSM8974_CNOC_MAS_RPM_INST, 8, 45, -1);
  248. DEFINE_QNODE(mas_rpm_data, MSM8974_CNOC_MAS_RPM_DATA, 8, 46, -1);
  249. DEFINE_QNODE(mas_rpm_sys, MSM8974_CNOC_MAS_RPM_SYS, 8, 47, -1);
  250. DEFINE_QNODE(mas_dehr, MSM8974_CNOC_MAS_DEHR, 8, 48, -1);
  251. DEFINE_QNODE(mas_qdss_dap, MSM8974_CNOC_MAS_QDSS_DAP, 8, 49, -1);
  252. DEFINE_QNODE(mas_spdm, MSM8974_CNOC_MAS_SPDM, 8, 50, -1);
  253. DEFINE_QNODE(mas_tic, MSM8974_CNOC_MAS_TIC, 8, 51, -1);
  254. DEFINE_QNODE(slv_clk_ctl, MSM8974_CNOC_SLV_CLK_CTL, 8, -1, 47);
  255. DEFINE_QNODE(slv_cnoc_mss, MSM8974_CNOC_SLV_CNOC_MSS, 8, -1, 48);
  256. DEFINE_QNODE(slv_security, MSM8974_CNOC_SLV_SECURITY, 8, -1, 49);
  257. DEFINE_QNODE(slv_tcsr, MSM8974_CNOC_SLV_TCSR, 8, -1, 50);
  258. DEFINE_QNODE(slv_tlmm, MSM8974_CNOC_SLV_TLMM, 8, -1, 51);
  259. DEFINE_QNODE(slv_crypto_0_cfg, MSM8974_CNOC_SLV_CRYPTO_0_CFG, 8, -1, 52);
  260. DEFINE_QNODE(slv_crypto_1_cfg, MSM8974_CNOC_SLV_CRYPTO_1_CFG, 8, -1, 53);
  261. DEFINE_QNODE(slv_imem_cfg, MSM8974_CNOC_SLV_IMEM_CFG, 8, -1, 54);
  262. DEFINE_QNODE(slv_message_ram, MSM8974_CNOC_SLV_MESSAGE_RAM, 8, -1, 55);
  263. DEFINE_QNODE(slv_bimc_cfg, MSM8974_CNOC_SLV_BIMC_CFG, 8, -1, 56);
  264. DEFINE_QNODE(slv_boot_rom, MSM8974_CNOC_SLV_BOOT_ROM, 8, -1, 57);
  265. DEFINE_QNODE(slv_pmic_arb, MSM8974_CNOC_SLV_PMIC_ARB, 8, -1, 59);
  266. DEFINE_QNODE(slv_spdm_wrapper, MSM8974_CNOC_SLV_SPDM_WRAPPER, 8, -1, 60);
  267. DEFINE_QNODE(slv_dehr_cfg, MSM8974_CNOC_SLV_DEHR_CFG, 8, -1, 61);
  268. DEFINE_QNODE(slv_mpm, MSM8974_CNOC_SLV_MPM, 8, -1, 62);
  269. DEFINE_QNODE(slv_qdss_cfg, MSM8974_CNOC_SLV_QDSS_CFG, 8, -1, 63);
  270. DEFINE_QNODE(slv_rbcpr_cfg, MSM8974_CNOC_SLV_RBCPR_CFG, 8, -1, 64);
  271. DEFINE_QNODE(slv_rbcpr_qdss_apu_cfg, MSM8974_CNOC_SLV_RBCPR_QDSS_APU_CFG, 8, -1, 65);
  272. DEFINE_QNODE(cnoc_to_snoc, MSM8974_CNOC_TO_SNOC, 8, 52, 75);
  273. DEFINE_QNODE(slv_cnoc_onoc_cfg, MSM8974_CNOC_SLV_CNOC_ONOC_CFG, 8, -1, 68);
  274. DEFINE_QNODE(slv_cnoc_mnoc_mmss_cfg, MSM8974_CNOC_SLV_CNOC_MNOC_MMSS_CFG, 8, -1, 58);
  275. DEFINE_QNODE(slv_cnoc_mnoc_cfg, MSM8974_CNOC_SLV_CNOC_MNOC_CFG, 8, -1, 66);
  276. DEFINE_QNODE(slv_pnoc_cfg, MSM8974_CNOC_SLV_PNOC_CFG, 8, -1, 69);
  277. DEFINE_QNODE(slv_snoc_mpu_cfg, MSM8974_CNOC_SLV_SNOC_MPU_CFG, 8, -1, 67);
  278. DEFINE_QNODE(slv_snoc_cfg, MSM8974_CNOC_SLV_SNOC_CFG, 8, -1, 70);
  279. DEFINE_QNODE(slv_ebi1_dll_cfg, MSM8974_CNOC_SLV_EBI1_DLL_CFG, 8, -1, 71);
  280. DEFINE_QNODE(slv_phy_apu_cfg, MSM8974_CNOC_SLV_PHY_APU_CFG, 8, -1, 72);
  281. DEFINE_QNODE(slv_ebi1_phy_cfg, MSM8974_CNOC_SLV_EBI1_PHY_CFG, 8, -1, 73);
  282. DEFINE_QNODE(slv_rpm, MSM8974_CNOC_SLV_RPM, 8, -1, 74);
  283. DEFINE_QNODE(slv_service_cnoc, MSM8974_CNOC_SLV_SERVICE_CNOC, 8, -1, 76);
  284. static struct msm8974_icc_node *msm8974_cnoc_nodes[] = {
  285. [CNOC_MAS_RPM_INST] = &mas_rpm_inst,
  286. [CNOC_MAS_RPM_DATA] = &mas_rpm_data,
  287. [CNOC_MAS_RPM_SYS] = &mas_rpm_sys,
  288. [CNOC_MAS_DEHR] = &mas_dehr,
  289. [CNOC_MAS_QDSS_DAP] = &mas_qdss_dap,
  290. [CNOC_MAS_SPDM] = &mas_spdm,
  291. [CNOC_MAS_TIC] = &mas_tic,
  292. [CNOC_SLV_CLK_CTL] = &slv_clk_ctl,
  293. [CNOC_SLV_CNOC_MSS] = &slv_cnoc_mss,
  294. [CNOC_SLV_SECURITY] = &slv_security,
  295. [CNOC_SLV_TCSR] = &slv_tcsr,
  296. [CNOC_SLV_TLMM] = &slv_tlmm,
  297. [CNOC_SLV_CRYPTO_0_CFG] = &slv_crypto_0_cfg,
  298. [CNOC_SLV_CRYPTO_1_CFG] = &slv_crypto_1_cfg,
  299. [CNOC_SLV_IMEM_CFG] = &slv_imem_cfg,
  300. [CNOC_SLV_MESSAGE_RAM] = &slv_message_ram,
  301. [CNOC_SLV_BIMC_CFG] = &slv_bimc_cfg,
  302. [CNOC_SLV_BOOT_ROM] = &slv_boot_rom,
  303. [CNOC_SLV_PMIC_ARB] = &slv_pmic_arb,
  304. [CNOC_SLV_SPDM_WRAPPER] = &slv_spdm_wrapper,
  305. [CNOC_SLV_DEHR_CFG] = &slv_dehr_cfg,
  306. [CNOC_SLV_MPM] = &slv_mpm,
  307. [CNOC_SLV_QDSS_CFG] = &slv_qdss_cfg,
  308. [CNOC_SLV_RBCPR_CFG] = &slv_rbcpr_cfg,
  309. [CNOC_SLV_RBCPR_QDSS_APU_CFG] = &slv_rbcpr_qdss_apu_cfg,
  310. [CNOC_TO_SNOC] = &cnoc_to_snoc,
  311. [CNOC_SLV_CNOC_ONOC_CFG] = &slv_cnoc_onoc_cfg,
  312. [CNOC_SLV_CNOC_MNOC_MMSS_CFG] = &slv_cnoc_mnoc_mmss_cfg,
  313. [CNOC_SLV_CNOC_MNOC_CFG] = &slv_cnoc_mnoc_cfg,
  314. [CNOC_SLV_PNOC_CFG] = &slv_pnoc_cfg,
  315. [CNOC_SLV_SNOC_MPU_CFG] = &slv_snoc_mpu_cfg,
  316. [CNOC_SLV_SNOC_CFG] = &slv_snoc_cfg,
  317. [CNOC_SLV_EBI1_DLL_CFG] = &slv_ebi1_dll_cfg,
  318. [CNOC_SLV_PHY_APU_CFG] = &slv_phy_apu_cfg,
  319. [CNOC_SLV_EBI1_PHY_CFG] = &slv_ebi1_phy_cfg,
  320. [CNOC_SLV_RPM] = &slv_rpm,
  321. [CNOC_SLV_SERVICE_CNOC] = &slv_service_cnoc,
  322. };
  323. static struct msm8974_icc_desc msm8974_cnoc = {
  324. .nodes = msm8974_cnoc_nodes,
  325. .num_nodes = ARRAY_SIZE(msm8974_cnoc_nodes),
  326. };
  327. DEFINE_QNODE(mas_graphics_3d, MSM8974_MNOC_MAS_GRAPHICS_3D, 16, 6, -1, MSM8974_MNOC_TO_BIMC);
  328. DEFINE_QNODE(mas_jpeg, MSM8974_MNOC_MAS_JPEG, 16, 7, -1, MSM8974_MNOC_TO_BIMC);
  329. DEFINE_QNODE(mas_mdp_port0, MSM8974_MNOC_MAS_MDP_PORT0, 16, 8, -1, MSM8974_MNOC_TO_BIMC);
  330. DEFINE_QNODE(mas_video_p0, MSM8974_MNOC_MAS_VIDEO_P0, 16, 9, -1);
  331. DEFINE_QNODE(mas_video_p1, MSM8974_MNOC_MAS_VIDEO_P1, 16, 10, -1);
  332. DEFINE_QNODE(mas_vfe, MSM8974_MNOC_MAS_VFE, 16, 11, -1, MSM8974_MNOC_TO_BIMC);
  333. DEFINE_QNODE(mnoc_to_cnoc, MSM8974_MNOC_TO_CNOC, 16, 4, -1);
  334. DEFINE_QNODE(mnoc_to_bimc, MSM8974_MNOC_TO_BIMC, 16, -1, 16, MSM8974_BIMC_TO_MNOC);
  335. DEFINE_QNODE(slv_camera_cfg, MSM8974_MNOC_SLV_CAMERA_CFG, 16, -1, 3);
  336. DEFINE_QNODE(slv_display_cfg, MSM8974_MNOC_SLV_DISPLAY_CFG, 16, -1, 4);
  337. DEFINE_QNODE(slv_ocmem_cfg, MSM8974_MNOC_SLV_OCMEM_CFG, 16, -1, 5);
  338. DEFINE_QNODE(slv_cpr_cfg, MSM8974_MNOC_SLV_CPR_CFG, 16, -1, 6);
  339. DEFINE_QNODE(slv_cpr_xpu_cfg, MSM8974_MNOC_SLV_CPR_XPU_CFG, 16, -1, 7);
  340. DEFINE_QNODE(slv_misc_cfg, MSM8974_MNOC_SLV_MISC_CFG, 16, -1, 8);
  341. DEFINE_QNODE(slv_misc_xpu_cfg, MSM8974_MNOC_SLV_MISC_XPU_CFG, 16, -1, 9);
  342. DEFINE_QNODE(slv_venus_cfg, MSM8974_MNOC_SLV_VENUS_CFG, 16, -1, 10);
  343. DEFINE_QNODE(slv_graphics_3d_cfg, MSM8974_MNOC_SLV_GRAPHICS_3D_CFG, 16, -1, 11);
  344. DEFINE_QNODE(slv_mmss_clk_cfg, MSM8974_MNOC_SLV_MMSS_CLK_CFG, 16, -1, 12);
  345. DEFINE_QNODE(slv_mmss_clk_xpu_cfg, MSM8974_MNOC_SLV_MMSS_CLK_XPU_CFG, 16, -1, 13);
  346. DEFINE_QNODE(slv_mnoc_mpu_cfg, MSM8974_MNOC_SLV_MNOC_MPU_CFG, 16, -1, 14);
  347. DEFINE_QNODE(slv_onoc_mpu_cfg, MSM8974_MNOC_SLV_ONOC_MPU_CFG, 16, -1, 15);
  348. DEFINE_QNODE(slv_service_mnoc, MSM8974_MNOC_SLV_SERVICE_MNOC, 16, -1, 17);
  349. static struct msm8974_icc_node *msm8974_mnoc_nodes[] = {
  350. [MNOC_MAS_GRAPHICS_3D] = &mas_graphics_3d,
  351. [MNOC_MAS_JPEG] = &mas_jpeg,
  352. [MNOC_MAS_MDP_PORT0] = &mas_mdp_port0,
  353. [MNOC_MAS_VIDEO_P0] = &mas_video_p0,
  354. [MNOC_MAS_VIDEO_P1] = &mas_video_p1,
  355. [MNOC_MAS_VFE] = &mas_vfe,
  356. [MNOC_TO_CNOC] = &mnoc_to_cnoc,
  357. [MNOC_TO_BIMC] = &mnoc_to_bimc,
  358. [MNOC_SLV_CAMERA_CFG] = &slv_camera_cfg,
  359. [MNOC_SLV_DISPLAY_CFG] = &slv_display_cfg,
  360. [MNOC_SLV_OCMEM_CFG] = &slv_ocmem_cfg,
  361. [MNOC_SLV_CPR_CFG] = &slv_cpr_cfg,
  362. [MNOC_SLV_CPR_XPU_CFG] = &slv_cpr_xpu_cfg,
  363. [MNOC_SLV_MISC_CFG] = &slv_misc_cfg,
  364. [MNOC_SLV_MISC_XPU_CFG] = &slv_misc_xpu_cfg,
  365. [MNOC_SLV_VENUS_CFG] = &slv_venus_cfg,
  366. [MNOC_SLV_GRAPHICS_3D_CFG] = &slv_graphics_3d_cfg,
  367. [MNOC_SLV_MMSS_CLK_CFG] = &slv_mmss_clk_cfg,
  368. [MNOC_SLV_MMSS_CLK_XPU_CFG] = &slv_mmss_clk_xpu_cfg,
  369. [MNOC_SLV_MNOC_MPU_CFG] = &slv_mnoc_mpu_cfg,
  370. [MNOC_SLV_ONOC_MPU_CFG] = &slv_onoc_mpu_cfg,
  371. [MNOC_SLV_SERVICE_MNOC] = &slv_service_mnoc,
  372. };
  373. static struct msm8974_icc_desc msm8974_mnoc = {
  374. .nodes = msm8974_mnoc_nodes,
  375. .num_nodes = ARRAY_SIZE(msm8974_mnoc_nodes),
  376. };
  377. DEFINE_QNODE(ocmem_noc_to_ocmem_vnoc, MSM8974_OCMEM_NOC_TO_OCMEM_VNOC, 16, 54, 78, MSM8974_OCMEM_SLV_OCMEM);
  378. DEFINE_QNODE(mas_jpeg_ocmem, MSM8974_OCMEM_MAS_JPEG_OCMEM, 16, 13, -1);
  379. DEFINE_QNODE(mas_mdp_ocmem, MSM8974_OCMEM_MAS_MDP_OCMEM, 16, 14, -1);
  380. DEFINE_QNODE(mas_video_p0_ocmem, MSM8974_OCMEM_MAS_VIDEO_P0_OCMEM, 16, 15, -1);
  381. DEFINE_QNODE(mas_video_p1_ocmem, MSM8974_OCMEM_MAS_VIDEO_P1_OCMEM, 16, 16, -1);
  382. DEFINE_QNODE(mas_vfe_ocmem, MSM8974_OCMEM_MAS_VFE_OCMEM, 16, 17, -1);
  383. DEFINE_QNODE(mas_cnoc_onoc_cfg, MSM8974_OCMEM_MAS_CNOC_ONOC_CFG, 16, 12, -1);
  384. DEFINE_QNODE(slv_service_onoc, MSM8974_OCMEM_SLV_SERVICE_ONOC, 16, -1, 19);
  385. DEFINE_QNODE(slv_ocmem, MSM8974_OCMEM_SLV_OCMEM, 16, -1, 18);
  386. /* Virtual NoC is needed for connection to OCMEM */
  387. DEFINE_QNODE(ocmem_vnoc_to_onoc, MSM8974_OCMEM_VNOC_TO_OCMEM_NOC, 16, 56, 79, MSM8974_OCMEM_NOC_TO_OCMEM_VNOC);
  388. DEFINE_QNODE(ocmem_vnoc_to_snoc, MSM8974_OCMEM_VNOC_TO_SNOC, 8, 57, 80);
  389. DEFINE_QNODE(mas_v_ocmem_gfx3d, MSM8974_OCMEM_VNOC_MAS_GFX3D, 8, 55, -1, MSM8974_OCMEM_VNOC_TO_OCMEM_NOC);
  390. static struct msm8974_icc_node *msm8974_onoc_nodes[] = {
  391. [OCMEM_NOC_TO_OCMEM_VNOC] = &ocmem_noc_to_ocmem_vnoc,
  392. [OCMEM_MAS_JPEG_OCMEM] = &mas_jpeg_ocmem,
  393. [OCMEM_MAS_MDP_OCMEM] = &mas_mdp_ocmem,
  394. [OCMEM_MAS_VIDEO_P0_OCMEM] = &mas_video_p0_ocmem,
  395. [OCMEM_MAS_VIDEO_P1_OCMEM] = &mas_video_p1_ocmem,
  396. [OCMEM_MAS_VFE_OCMEM] = &mas_vfe_ocmem,
  397. [OCMEM_MAS_CNOC_ONOC_CFG] = &mas_cnoc_onoc_cfg,
  398. [OCMEM_SLV_SERVICE_ONOC] = &slv_service_onoc,
  399. [OCMEM_VNOC_TO_SNOC] = &ocmem_vnoc_to_snoc,
  400. [OCMEM_VNOC_TO_OCMEM_NOC] = &ocmem_vnoc_to_onoc,
  401. [OCMEM_VNOC_MAS_GFX3D] = &mas_v_ocmem_gfx3d,
  402. [OCMEM_SLV_OCMEM] = &slv_ocmem,
  403. };
  404. static struct msm8974_icc_desc msm8974_onoc = {
  405. .nodes = msm8974_onoc_nodes,
  406. .num_nodes = ARRAY_SIZE(msm8974_onoc_nodes),
  407. };
  408. DEFINE_QNODE(mas_pnoc_cfg, MSM8974_PNOC_MAS_PNOC_CFG, 8, 43, -1);
  409. DEFINE_QNODE(mas_sdcc_1, MSM8974_PNOC_MAS_SDCC_1, 8, 33, -1, MSM8974_PNOC_TO_SNOC);
  410. DEFINE_QNODE(mas_sdcc_3, MSM8974_PNOC_MAS_SDCC_3, 8, 34, -1, MSM8974_PNOC_TO_SNOC);
  411. DEFINE_QNODE(mas_sdcc_4, MSM8974_PNOC_MAS_SDCC_4, 8, 36, -1, MSM8974_PNOC_TO_SNOC);
  412. DEFINE_QNODE(mas_sdcc_2, MSM8974_PNOC_MAS_SDCC_2, 8, 35, -1, MSM8974_PNOC_TO_SNOC);
  413. DEFINE_QNODE(mas_tsif, MSM8974_PNOC_MAS_TSIF, 8, 37, -1, MSM8974_PNOC_TO_SNOC);
  414. DEFINE_QNODE(mas_bam_dma, MSM8974_PNOC_MAS_BAM_DMA, 8, 38, -1);
  415. DEFINE_QNODE(mas_blsp_2, MSM8974_PNOC_MAS_BLSP_2, 8, 39, -1, MSM8974_PNOC_TO_SNOC);
  416. DEFINE_QNODE(mas_usb_hsic, MSM8974_PNOC_MAS_USB_HSIC, 8, 40, -1, MSM8974_PNOC_TO_SNOC);
  417. DEFINE_QNODE(mas_blsp_1, MSM8974_PNOC_MAS_BLSP_1, 8, 41, -1, MSM8974_PNOC_TO_SNOC);
  418. DEFINE_QNODE(mas_usb_hs, MSM8974_PNOC_MAS_USB_HS, 8, 42, -1, MSM8974_PNOC_TO_SNOC);
  419. DEFINE_QNODE(pnoc_to_snoc, MSM8974_PNOC_TO_SNOC, 8, 44, 45, MSM8974_SNOC_TO_PNOC, MSM8974_PNOC_SLV_PRNG);
  420. DEFINE_QNODE(slv_sdcc_1, MSM8974_PNOC_SLV_SDCC_1, 8, -1, 31);
  421. DEFINE_QNODE(slv_sdcc_3, MSM8974_PNOC_SLV_SDCC_3, 8, -1, 32);
  422. DEFINE_QNODE(slv_sdcc_2, MSM8974_PNOC_SLV_SDCC_2, 8, -1, 33);
  423. DEFINE_QNODE(slv_sdcc_4, MSM8974_PNOC_SLV_SDCC_4, 8, -1, 34);
  424. DEFINE_QNODE(slv_tsif, MSM8974_PNOC_SLV_TSIF, 8, -1, 35);
  425. DEFINE_QNODE(slv_bam_dma, MSM8974_PNOC_SLV_BAM_DMA, 8, -1, 36);
  426. DEFINE_QNODE(slv_blsp_2, MSM8974_PNOC_SLV_BLSP_2, 8, -1, 37);
  427. DEFINE_QNODE(slv_usb_hsic, MSM8974_PNOC_SLV_USB_HSIC, 8, -1, 38);
  428. DEFINE_QNODE(slv_blsp_1, MSM8974_PNOC_SLV_BLSP_1, 8, -1, 39);
  429. DEFINE_QNODE(slv_usb_hs, MSM8974_PNOC_SLV_USB_HS, 8, -1, 40);
  430. DEFINE_QNODE(slv_pdm, MSM8974_PNOC_SLV_PDM, 8, -1, 41);
  431. DEFINE_QNODE(slv_periph_apu_cfg, MSM8974_PNOC_SLV_PERIPH_APU_CFG, 8, -1, 42);
  432. DEFINE_QNODE(slv_pnoc_mpu_cfg, MSM8974_PNOC_SLV_PNOC_MPU_CFG, 8, -1, 43);
  433. DEFINE_QNODE(slv_prng, MSM8974_PNOC_SLV_PRNG, 8, -1, 44, MSM8974_PNOC_TO_SNOC);
  434. DEFINE_QNODE(slv_service_pnoc, MSM8974_PNOC_SLV_SERVICE_PNOC, 8, -1, 46);
  435. static struct msm8974_icc_node *msm8974_pnoc_nodes[] = {
  436. [PNOC_MAS_PNOC_CFG] = &mas_pnoc_cfg,
  437. [PNOC_MAS_SDCC_1] = &mas_sdcc_1,
  438. [PNOC_MAS_SDCC_3] = &mas_sdcc_3,
  439. [PNOC_MAS_SDCC_4] = &mas_sdcc_4,
  440. [PNOC_MAS_SDCC_2] = &mas_sdcc_2,
  441. [PNOC_MAS_TSIF] = &mas_tsif,
  442. [PNOC_MAS_BAM_DMA] = &mas_bam_dma,
  443. [PNOC_MAS_BLSP_2] = &mas_blsp_2,
  444. [PNOC_MAS_USB_HSIC] = &mas_usb_hsic,
  445. [PNOC_MAS_BLSP_1] = &mas_blsp_1,
  446. [PNOC_MAS_USB_HS] = &mas_usb_hs,
  447. [PNOC_TO_SNOC] = &pnoc_to_snoc,
  448. [PNOC_SLV_SDCC_1] = &slv_sdcc_1,
  449. [PNOC_SLV_SDCC_3] = &slv_sdcc_3,
  450. [PNOC_SLV_SDCC_2] = &slv_sdcc_2,
  451. [PNOC_SLV_SDCC_4] = &slv_sdcc_4,
  452. [PNOC_SLV_TSIF] = &slv_tsif,
  453. [PNOC_SLV_BAM_DMA] = &slv_bam_dma,
  454. [PNOC_SLV_BLSP_2] = &slv_blsp_2,
  455. [PNOC_SLV_USB_HSIC] = &slv_usb_hsic,
  456. [PNOC_SLV_BLSP_1] = &slv_blsp_1,
  457. [PNOC_SLV_USB_HS] = &slv_usb_hs,
  458. [PNOC_SLV_PDM] = &slv_pdm,
  459. [PNOC_SLV_PERIPH_APU_CFG] = &slv_periph_apu_cfg,
  460. [PNOC_SLV_PNOC_MPU_CFG] = &slv_pnoc_mpu_cfg,
  461. [PNOC_SLV_PRNG] = &slv_prng,
  462. [PNOC_SLV_SERVICE_PNOC] = &slv_service_pnoc,
  463. };
  464. static struct msm8974_icc_desc msm8974_pnoc = {
  465. .nodes = msm8974_pnoc_nodes,
  466. .num_nodes = ARRAY_SIZE(msm8974_pnoc_nodes),
  467. };
  468. DEFINE_QNODE(mas_lpass_ahb, MSM8974_SNOC_MAS_LPASS_AHB, 8, 18, -1);
  469. DEFINE_QNODE(mas_qdss_bam, MSM8974_SNOC_MAS_QDSS_BAM, 8, 19, -1);
  470. DEFINE_QNODE(mas_snoc_cfg, MSM8974_SNOC_MAS_SNOC_CFG, 8, 20, -1);
  471. DEFINE_QNODE(snoc_to_bimc, MSM8974_SNOC_TO_BIMC, 8, 21, 24, MSM8974_BIMC_TO_SNOC);
  472. DEFINE_QNODE(snoc_to_cnoc, MSM8974_SNOC_TO_CNOC, 8, 22, 25);
  473. DEFINE_QNODE(snoc_to_pnoc, MSM8974_SNOC_TO_PNOC, 8, 29, 28, MSM8974_PNOC_TO_SNOC);
  474. DEFINE_QNODE(snoc_to_ocmem_vnoc, MSM8974_SNOC_TO_OCMEM_VNOC, 8, 53, 77, MSM8974_OCMEM_VNOC_TO_OCMEM_NOC);
  475. DEFINE_QNODE(mas_crypto_core0, MSM8974_SNOC_MAS_CRYPTO_CORE0, 8, 23, -1, MSM8974_SNOC_TO_BIMC);
  476. DEFINE_QNODE(mas_crypto_core1, MSM8974_SNOC_MAS_CRYPTO_CORE1, 8, 24, -1);
  477. DEFINE_QNODE(mas_lpass_proc, MSM8974_SNOC_MAS_LPASS_PROC, 8, 25, -1, MSM8974_SNOC_TO_OCMEM_VNOC);
  478. DEFINE_QNODE(mas_mss, MSM8974_SNOC_MAS_MSS, 8, 26, -1);
  479. DEFINE_QNODE(mas_mss_nav, MSM8974_SNOC_MAS_MSS_NAV, 8, 27, -1);
  480. DEFINE_QNODE(mas_ocmem_dma, MSM8974_SNOC_MAS_OCMEM_DMA, 8, 28, -1);
  481. DEFINE_QNODE(mas_wcss, MSM8974_SNOC_MAS_WCSS, 8, 30, -1);
  482. DEFINE_QNODE(mas_qdss_etr, MSM8974_SNOC_MAS_QDSS_ETR, 8, 31, -1);
  483. DEFINE_QNODE(mas_usb3, MSM8974_SNOC_MAS_USB3, 8, 32, -1, MSM8974_SNOC_TO_BIMC);
  484. DEFINE_QNODE(slv_ampss, MSM8974_SNOC_SLV_AMPSS, 8, -1, 20);
  485. DEFINE_QNODE(slv_lpass, MSM8974_SNOC_SLV_LPASS, 8, -1, 21);
  486. DEFINE_QNODE(slv_usb3, MSM8974_SNOC_SLV_USB3, 8, -1, 22);
  487. DEFINE_QNODE(slv_wcss, MSM8974_SNOC_SLV_WCSS, 8, -1, 23);
  488. DEFINE_QNODE(slv_ocimem, MSM8974_SNOC_SLV_OCIMEM, 8, -1, 26);
  489. DEFINE_QNODE(slv_snoc_ocmem, MSM8974_SNOC_SLV_SNOC_OCMEM, 8, -1, 27);
  490. DEFINE_QNODE(slv_service_snoc, MSM8974_SNOC_SLV_SERVICE_SNOC, 8, -1, 29);
  491. DEFINE_QNODE(slv_qdss_stm, MSM8974_SNOC_SLV_QDSS_STM, 8, -1, 30);
  492. static struct msm8974_icc_node *msm8974_snoc_nodes[] = {
  493. [SNOC_MAS_LPASS_AHB] = &mas_lpass_ahb,
  494. [SNOC_MAS_QDSS_BAM] = &mas_qdss_bam,
  495. [SNOC_MAS_SNOC_CFG] = &mas_snoc_cfg,
  496. [SNOC_TO_BIMC] = &snoc_to_bimc,
  497. [SNOC_TO_CNOC] = &snoc_to_cnoc,
  498. [SNOC_TO_PNOC] = &snoc_to_pnoc,
  499. [SNOC_TO_OCMEM_VNOC] = &snoc_to_ocmem_vnoc,
  500. [SNOC_MAS_CRYPTO_CORE0] = &mas_crypto_core0,
  501. [SNOC_MAS_CRYPTO_CORE1] = &mas_crypto_core1,
  502. [SNOC_MAS_LPASS_PROC] = &mas_lpass_proc,
  503. [SNOC_MAS_MSS] = &mas_mss,
  504. [SNOC_MAS_MSS_NAV] = &mas_mss_nav,
  505. [SNOC_MAS_OCMEM_DMA] = &mas_ocmem_dma,
  506. [SNOC_MAS_WCSS] = &mas_wcss,
  507. [SNOC_MAS_QDSS_ETR] = &mas_qdss_etr,
  508. [SNOC_MAS_USB3] = &mas_usb3,
  509. [SNOC_SLV_AMPSS] = &slv_ampss,
  510. [SNOC_SLV_LPASS] = &slv_lpass,
  511. [SNOC_SLV_USB3] = &slv_usb3,
  512. [SNOC_SLV_WCSS] = &slv_wcss,
  513. [SNOC_SLV_OCIMEM] = &slv_ocimem,
  514. [SNOC_SLV_SNOC_OCMEM] = &slv_snoc_ocmem,
  515. [SNOC_SLV_SERVICE_SNOC] = &slv_service_snoc,
  516. [SNOC_SLV_QDSS_STM] = &slv_qdss_stm,
  517. };
  518. static struct msm8974_icc_desc msm8974_snoc = {
  519. .nodes = msm8974_snoc_nodes,
  520. .num_nodes = ARRAY_SIZE(msm8974_snoc_nodes),
  521. };
  522. static void msm8974_icc_rpm_smd_send(struct device *dev, int rsc_type,
  523. char *name, int id, u64 val)
  524. {
  525. int ret;
  526. if (id == -1)
  527. return;
  528. /*
  529. * Setting the bandwidth requests for some nodes fails and this same
  530. * behavior occurs on the downstream MSM 3.4 kernel sources based on
  531. * errors like this in that kernel:
  532. *
  533. * msm_rpm_get_error_from_ack(): RPM NACK Unsupported resource
  534. * AXI: msm_bus_rpm_req(): RPM: Ack failed
  535. * AXI: msm_bus_rpm_commit_arb(): RPM: Req fail: mas:32, bw:240000000
  536. *
  537. * Since there's no publicly available documentation for this hardware,
  538. * and the bandwidth for some nodes in the path can be set properly,
  539. * let's not return an error.
  540. */
  541. ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE, rsc_type, id,
  542. val);
  543. if (ret)
  544. dev_dbg(dev, "Cannot set bandwidth for node %s (%d): %d\n",
  545. name, id, ret);
  546. }
  547. static int msm8974_icc_set(struct icc_node *src, struct icc_node *dst)
  548. {
  549. struct msm8974_icc_node *src_qn, *dst_qn;
  550. struct msm8974_icc_provider *qp;
  551. u64 sum_bw, max_peak_bw, rate;
  552. u32 agg_avg = 0, agg_peak = 0;
  553. struct icc_provider *provider;
  554. struct icc_node *n;
  555. int ret, i;
  556. src_qn = src->data;
  557. dst_qn = dst->data;
  558. provider = src->provider;
  559. qp = to_msm8974_icc_provider(provider);
  560. list_for_each_entry(n, &provider->nodes, node_list)
  561. provider->aggregate(n, 0, n->avg_bw, n->peak_bw,
  562. &agg_avg, &agg_peak);
  563. sum_bw = icc_units_to_bps(agg_avg);
  564. max_peak_bw = icc_units_to_bps(agg_peak);
  565. /* Set bandwidth on source node */
  566. msm8974_icc_rpm_smd_send(provider->dev, RPM_BUS_MASTER_REQ,
  567. src_qn->name, src_qn->mas_rpm_id, sum_bw);
  568. msm8974_icc_rpm_smd_send(provider->dev, RPM_BUS_SLAVE_REQ,
  569. src_qn->name, src_qn->slv_rpm_id, sum_bw);
  570. /* Set bandwidth on destination node */
  571. msm8974_icc_rpm_smd_send(provider->dev, RPM_BUS_MASTER_REQ,
  572. dst_qn->name, dst_qn->mas_rpm_id, sum_bw);
  573. msm8974_icc_rpm_smd_send(provider->dev, RPM_BUS_SLAVE_REQ,
  574. dst_qn->name, dst_qn->slv_rpm_id, sum_bw);
  575. rate = max(sum_bw, max_peak_bw);
  576. do_div(rate, src_qn->buswidth);
  577. rate = min_t(u32, rate, INT_MAX);
  578. if (src_qn->rate == rate)
  579. return 0;
  580. for (i = 0; i < qp->num_clks; i++) {
  581. ret = clk_set_rate(qp->bus_clks[i].clk, rate);
  582. if (ret) {
  583. dev_err(provider->dev, "%s clk_set_rate error: %d\n",
  584. qp->bus_clks[i].id, ret);
  585. ret = 0;
  586. }
  587. }
  588. src_qn->rate = rate;
  589. return 0;
  590. }
  591. static int msm8974_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
  592. {
  593. *avg = 0;
  594. *peak = 0;
  595. return 0;
  596. }
  597. static int msm8974_icc_probe(struct platform_device *pdev)
  598. {
  599. const struct msm8974_icc_desc *desc;
  600. struct msm8974_icc_node **qnodes;
  601. struct msm8974_icc_provider *qp;
  602. struct device *dev = &pdev->dev;
  603. struct icc_onecell_data *data;
  604. struct icc_provider *provider;
  605. struct icc_node *node;
  606. size_t num_nodes, i;
  607. int ret;
  608. /* wait for the RPM proxy */
  609. if (!qcom_icc_rpm_smd_available())
  610. return -EPROBE_DEFER;
  611. desc = of_device_get_match_data(dev);
  612. if (!desc)
  613. return -EINVAL;
  614. qnodes = desc->nodes;
  615. num_nodes = desc->num_nodes;
  616. qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL);
  617. if (!qp)
  618. return -ENOMEM;
  619. data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
  620. GFP_KERNEL);
  621. if (!data)
  622. return -ENOMEM;
  623. qp->bus_clks = devm_kmemdup(dev, msm8974_icc_bus_clocks,
  624. sizeof(msm8974_icc_bus_clocks), GFP_KERNEL);
  625. if (!qp->bus_clks)
  626. return -ENOMEM;
  627. qp->num_clks = ARRAY_SIZE(msm8974_icc_bus_clocks);
  628. ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
  629. if (ret)
  630. return ret;
  631. ret = clk_bulk_prepare_enable(qp->num_clks, qp->bus_clks);
  632. if (ret)
  633. return ret;
  634. provider = &qp->provider;
  635. INIT_LIST_HEAD(&provider->nodes);
  636. provider->dev = dev;
  637. provider->set = msm8974_icc_set;
  638. provider->aggregate = icc_std_aggregate;
  639. provider->xlate = of_icc_xlate_onecell;
  640. provider->data = data;
  641. provider->get_bw = msm8974_get_bw;
  642. ret = icc_provider_add(provider);
  643. if (ret) {
  644. dev_err(dev, "error adding interconnect provider: %d\n", ret);
  645. goto err_disable_clks;
  646. }
  647. for (i = 0; i < num_nodes; i++) {
  648. size_t j;
  649. node = icc_node_create(qnodes[i]->id);
  650. if (IS_ERR(node)) {
  651. ret = PTR_ERR(node);
  652. goto err_del_icc;
  653. }
  654. node->name = qnodes[i]->name;
  655. node->data = qnodes[i];
  656. icc_node_add(node, provider);
  657. dev_dbg(dev, "registered node %s\n", node->name);
  658. /* populate links */
  659. for (j = 0; j < qnodes[i]->num_links; j++)
  660. icc_link_create(node, qnodes[i]->links[j]);
  661. data->nodes[i] = node;
  662. }
  663. data->num_nodes = num_nodes;
  664. platform_set_drvdata(pdev, qp);
  665. return 0;
  666. err_del_icc:
  667. icc_nodes_remove(provider);
  668. icc_provider_del(provider);
  669. err_disable_clks:
  670. clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
  671. return ret;
  672. }
  673. static int msm8974_icc_remove(struct platform_device *pdev)
  674. {
  675. struct msm8974_icc_provider *qp = platform_get_drvdata(pdev);
  676. icc_nodes_remove(&qp->provider);
  677. clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
  678. return icc_provider_del(&qp->provider);
  679. }
  680. static const struct of_device_id msm8974_noc_of_match[] = {
  681. { .compatible = "qcom,msm8974-bimc", .data = &msm8974_bimc},
  682. { .compatible = "qcom,msm8974-cnoc", .data = &msm8974_cnoc},
  683. { .compatible = "qcom,msm8974-mmssnoc", .data = &msm8974_mnoc},
  684. { .compatible = "qcom,msm8974-ocmemnoc", .data = &msm8974_onoc},
  685. { .compatible = "qcom,msm8974-pnoc", .data = &msm8974_pnoc},
  686. { .compatible = "qcom,msm8974-snoc", .data = &msm8974_snoc},
  687. { },
  688. };
  689. MODULE_DEVICE_TABLE(of, msm8974_noc_of_match);
  690. static struct platform_driver msm8974_noc_driver = {
  691. .probe = msm8974_icc_probe,
  692. .remove = msm8974_icc_remove,
  693. .driver = {
  694. .name = "qnoc-msm8974",
  695. .of_match_table = msm8974_noc_of_match,
  696. .sync_state = icc_sync_state,
  697. },
  698. };
  699. module_platform_driver(msm8974_noc_driver);
  700. MODULE_DESCRIPTION("Qualcomm MSM8974 NoC driver");
  701. MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
  702. MODULE_LICENSE("GPL v2");