cam_cpas_soc.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/device.h>
  7. #include <linux/of.h>
  8. #include <linux/module.h>
  9. #include <linux/kernel.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/slab.h>
  12. #include <dt-bindings/msm-camera.h>
  13. #include "cam_cpas_api.h"
  14. #include "cam_cpas_hw_intf.h"
  15. #include "cam_cpas_hw.h"
  16. #include "cam_cpas_soc.h"
  17. #include "cam_compat.h"
  18. static uint cpas_dump;
  19. module_param(cpas_dump, uint, 0644);
  20. #define CAM_ICP_CLK_NAME "cam_icp_clk"
  21. void cam_cpas_dump_tree_vote_info(struct cam_hw_info *cpas_hw,
  22. const struct cam_cpas_tree_node *tree_node,
  23. const char *identifier, int ddr_drv_idx, int cesta_drv_idx)
  24. {
  25. struct cam_cpas_private_soc *soc_private =
  26. (struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
  27. if ((cpas_dump & BIT(0)) == 0)
  28. return;
  29. if (cesta_drv_idx > CAM_CPAS_PORT_HLOS_DRV)
  30. CAM_INFO(CAM_PERF,
  31. "%s node:%s lvl:%d cesta_drv_idx:%d DRV BW camnoc[%llu %llu]",
  32. identifier, tree_node->node_name, tree_node->level_idx, cesta_drv_idx,
  33. tree_node->bw_info[cesta_drv_idx].drv_vote.high.camnoc,
  34. tree_node->bw_info[cesta_drv_idx].drv_vote.low.camnoc);
  35. else
  36. CAM_INFO(CAM_PERF,
  37. "%s node:%s lvl:%d cesta_drv_idx:%d HLOS BW camnoc[%llu]",
  38. identifier, tree_node->node_name, tree_node->level_idx, cesta_drv_idx,
  39. tree_node->bw_info[cesta_drv_idx].hlos_vote.camnoc);
  40. if (ddr_drv_idx > CAM_CPAS_PORT_HLOS_DRV)
  41. CAM_INFO(CAM_PERF,
  42. "%s node:%s lvl:%d ddr_drv_idx:%d DRV BW ab[%llu %llu] ib[%llu %llu]",
  43. identifier, tree_node->node_name, tree_node->level_idx, ddr_drv_idx,
  44. tree_node->bw_info[ddr_drv_idx].drv_vote.high.ab,
  45. tree_node->bw_info[ddr_drv_idx].drv_vote.low.ab,
  46. tree_node->bw_info[ddr_drv_idx].drv_vote.high.ib,
  47. tree_node->bw_info[ddr_drv_idx].drv_vote.low.ib);
  48. else
  49. CAM_INFO(CAM_PERF,
  50. "%s node:%s lvl:%d ddr_drv_idx:%d HLOS BW ab[%llu] ib[%llu]",
  51. identifier, tree_node->node_name, tree_node->level_idx, ddr_drv_idx,
  52. tree_node->bw_info[ddr_drv_idx].hlos_vote.ab,
  53. tree_node->bw_info[ddr_drv_idx].hlos_vote.ib);
  54. if (soc_private->enable_cam_ddr_drv) {
  55. int i;
  56. CAM_INFO(CAM_PERF,
  57. "%s node:%s lvl:%d drv_idx:%d cesta_drv_idx:%d ==== printing full node state",
  58. identifier, tree_node->node_name, tree_node->level_idx,
  59. ddr_drv_idx, cesta_drv_idx);
  60. for (i = 0; i < CAM_CPAS_MAX_DRV_PORTS; i++) {
  61. if (i == CAM_CPAS_PORT_HLOS_DRV)
  62. CAM_INFO(CAM_PERF,
  63. "idx[%d] HLOS camnoc[%llu], DDR ab[%llu] ib[%llu]",
  64. i,
  65. tree_node->bw_info[i].hlos_vote.camnoc,
  66. tree_node->bw_info[i].hlos_vote.ab,
  67. tree_node->bw_info[i].hlos_vote.ib);
  68. else
  69. CAM_INFO(CAM_PERF,
  70. "idx[%d] DRV camnoc[%llu %llu], DDR ab[%llu %llu] ib[%llu %llu]",
  71. i,
  72. tree_node->bw_info[i].drv_vote.high.camnoc,
  73. tree_node->bw_info[i].drv_vote.low.camnoc,
  74. tree_node->bw_info[i].drv_vote.high.ab,
  75. tree_node->bw_info[i].drv_vote.low.ab,
  76. tree_node->bw_info[i].drv_vote.high.ib,
  77. tree_node->bw_info[i].drv_vote.low.ib);
  78. }
  79. }
  80. }
  81. void cam_cpas_dump_full_tree_state(struct cam_hw_info *cpas_hw, const char *identifier)
  82. {
  83. int j;
  84. struct cam_cpas_private_soc *soc_private =
  85. (struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
  86. struct cam_cpas_tree_node *curr_node;
  87. if ((cpas_dump & BIT(1)) == 0)
  88. return;
  89. CAM_INFO(CAM_CPAS, "Dumping cpas tree full state start ============== %s", identifier);
  90. /* This will traverse through all nodes in the tree and print stats*/
  91. for (j = 0; j < CAM_CPAS_MAX_TREE_NODES; j++) {
  92. if (!soc_private->tree_node[j])
  93. continue;
  94. curr_node = soc_private->tree_node[j];
  95. if (soc_private->enable_cam_ddr_drv) {
  96. int i;
  97. CAM_INFO(CAM_PERF,
  98. "Identifier[%s] node:[%s] cell:%d lvl:%d PortIdx mnoc[%d %d %d %d] camnoc[%d] camnoc_max %d, bus_width:%d, drv_idx:%d",
  99. identifier, curr_node->node_name, curr_node->cell_idx,
  100. curr_node->level_idx,
  101. curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
  102. curr_node->axi_port_idx_arr[CAM_CPAS_PORT_DRV_0],
  103. curr_node->axi_port_idx_arr[CAM_CPAS_PORT_DRV_1],
  104. curr_node->axi_port_idx_arr[CAM_CPAS_PORT_DRV_2],
  105. curr_node->camnoc_axi_port_idx,
  106. curr_node->camnoc_max_needed,
  107. curr_node->bus_width_factor,
  108. curr_node->drv_voting_idx);
  109. for (i = 0; i < CAM_CPAS_MAX_DRV_PORTS; i++) {
  110. if (i == CAM_CPAS_PORT_HLOS_DRV)
  111. CAM_INFO(CAM_PERF,
  112. " idx[%d] HLOS camnoc[%llu], DDR ab[%llu] ib[%llu]",
  113. i,
  114. curr_node->bw_info[i].hlos_vote.camnoc,
  115. curr_node->bw_info[i].hlos_vote.ab,
  116. curr_node->bw_info[i].hlos_vote.ib);
  117. else
  118. CAM_INFO(CAM_PERF,
  119. " idx[%d] DRV camnoc[%llu %llu], DDR ab[%llu %llu] ib[%llu %llu]",
  120. i,
  121. curr_node->bw_info[i].drv_vote.high.camnoc,
  122. curr_node->bw_info[i].drv_vote.low.camnoc,
  123. curr_node->bw_info[i].drv_vote.high.ab,
  124. curr_node->bw_info[i].drv_vote.low.ab,
  125. curr_node->bw_info[i].drv_vote.high.ib,
  126. curr_node->bw_info[i].drv_vote.low.ib);
  127. }
  128. } else {
  129. CAM_INFO(CAM_CPAS,
  130. "[%s] Cell[%d] level[%d] PortIdx[%d][%d] camnoc_bw[%d %d %lld %lld] mnoc_bw[%lld %lld]",
  131. curr_node->node_name, curr_node->cell_idx,
  132. curr_node->level_idx,
  133. curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
  134. curr_node->camnoc_axi_port_idx,
  135. curr_node->camnoc_max_needed,
  136. curr_node->bus_width_factor,
  137. curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.camnoc,
  138. curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.camnoc *
  139. curr_node->bus_width_factor,
  140. curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.ab,
  141. curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.ib);
  142. }
  143. }
  144. CAM_INFO(CAM_CPAS, "Dumping cpas tree full state end ============== %s", identifier);
  145. }
  146. void cam_cpas_dump_axi_vote_info(
  147. const struct cam_cpas_client *cpas_client,
  148. const char *identifier,
  149. struct cam_axi_vote *axi_vote)
  150. {
  151. int i;
  152. if ((cpas_dump & BIT(0)) == 0)
  153. return;
  154. if (!axi_vote || (axi_vote->num_paths >
  155. CAM_CPAS_MAX_PATHS_PER_CLIENT)) {
  156. CAM_ERR(CAM_PERF, "Invalid num_paths %d",
  157. axi_vote ? axi_vote->num_paths : -1);
  158. return;
  159. }
  160. for (i = 0; i < axi_vote->num_paths; i++) {
  161. CAM_INFO(CAM_PERF,
  162. "Client [%s][%d] : [%s], Path=[%d] [%d], [%s], camnoc[%llu], mnoc_ab[%llu], mnoc_ib[%llu]",
  163. cpas_client->data.identifier, cpas_client->data.cell_index,
  164. identifier,
  165. axi_vote->axi_path[i].path_data_type,
  166. axi_vote->axi_path[i].transac_type,
  167. cam_cpas_axi_util_drv_vote_lvl_to_string(axi_vote->axi_path[i].vote_level),
  168. axi_vote->axi_path[i].camnoc_bw,
  169. axi_vote->axi_path[i].mnoc_ab_bw,
  170. axi_vote->axi_path[i].mnoc_ib_bw);
  171. }
  172. }
  173. void cam_cpas_util_debug_parse_data(
  174. struct cam_cpas_private_soc *soc_private)
  175. {
  176. int i, j;
  177. struct cam_cpas_tree_node *curr_node = NULL;
  178. if ((cpas_dump & BIT(0)) == 0)
  179. return;
  180. for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
  181. if (!soc_private->tree_node[i])
  182. break;
  183. curr_node = soc_private->tree_node[i];
  184. CAM_INFO(CAM_CPAS,
  185. "NODE cell_idx: %d, level: %d, name: %s, axi_port_idx: %d, merge_type: %d, parent_name: %s camnoc_max_needed: %d",
  186. curr_node->cell_idx, curr_node->level_idx,
  187. curr_node->node_name, curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
  188. curr_node->merge_type, curr_node->parent_node ?
  189. curr_node->parent_node->node_name : "no parent",
  190. curr_node->camnoc_max_needed);
  191. if (curr_node->level_idx)
  192. continue;
  193. CAM_INFO(CAM_CPAS, "path_type: %d, transac_type: %s drv_voting_idx:%d",
  194. curr_node->path_data_type,
  195. cam_cpas_axi_util_trans_type_to_string(
  196. curr_node->path_trans_type), curr_node->drv_voting_idx);
  197. for (j = 0; j < CAM_CPAS_PATH_DATA_MAX; j++) {
  198. if (curr_node->constituent_paths[j])
  199. CAM_INFO(CAM_CPAS, "Constituent path: %d", j);
  200. }
  201. }
  202. CAM_INFO(CAM_CPAS, "NUMBER OF NODES PARSED: %d", i);
  203. }
  204. int cam_cpas_node_tree_cleanup(struct cam_cpas *cpas_core,
  205. struct cam_cpas_private_soc *soc_private)
  206. {
  207. int i = 0;
  208. for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
  209. if (soc_private->tree_node[i]) {
  210. kfree(soc_private->tree_node[i]->bw_info);
  211. kfree(soc_private->tree_node[i]->axi_port_idx_arr);
  212. soc_private->tree_node[i]->bw_info = NULL;
  213. soc_private->tree_node[i]->axi_port_idx_arr = NULL;
  214. of_node_put(soc_private->tree_node[i]->tree_dev_node);
  215. kfree(soc_private->tree_node[i]);
  216. soc_private->tree_node[i] = NULL;
  217. }
  218. }
  219. for (i = 0; i < CAM_CPAS_MAX_TREE_LEVELS; i++) {
  220. if (soc_private->level_node[i]) {
  221. of_node_put(soc_private->level_node[i]);
  222. soc_private->level_node[i] = NULL;
  223. }
  224. }
  225. if (soc_private->camera_bus_node) {
  226. of_node_put(soc_private->camera_bus_node);
  227. soc_private->camera_bus_node = NULL;
  228. }
  229. mutex_destroy(&cpas_core->tree_lock);
  230. return 0;
  231. }
  232. static int cam_cpas_util_path_type_to_idx(uint32_t *path_data_type)
  233. {
  234. if (*path_data_type >= CAM_CPAS_PATH_DATA_CONSO_OFFSET) {
  235. *path_data_type = CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT +
  236. (*path_data_type % CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT);
  237. }
  238. else {
  239. *path_data_type %= CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT;
  240. }
  241. if (*path_data_type >= CAM_CPAS_PATH_DATA_MAX) {
  242. CAM_ERR(CAM_CPAS, "index Invalid: %u", *path_data_type);
  243. return -EINVAL;
  244. }
  245. return 0;
  246. }
  247. static int cam_cpas_update_camnoc_node(struct cam_cpas *cpas_core,
  248. struct device_node *curr_node,
  249. struct cam_cpas_tree_node *cpas_node_ptr,
  250. int *camnoc_idx)
  251. {
  252. struct device_node *camnoc_node;
  253. int rc;
  254. camnoc_node = of_find_node_by_name(curr_node,
  255. "qcom,axi-port-camnoc");
  256. if (camnoc_node) {
  257. if (*camnoc_idx >=
  258. CAM_CPAS_MAX_AXI_PORTS) {
  259. CAM_ERR(CAM_CPAS, "CAMNOC axi index overshoot %d",
  260. *camnoc_idx);
  261. return -EINVAL;
  262. }
  263. cpas_core->camnoc_axi_port[*camnoc_idx]
  264. .axi_port_node = camnoc_node;
  265. rc = of_property_read_string(
  266. curr_node,
  267. "qcom,axi-port-name",
  268. &cpas_core->camnoc_axi_port[*camnoc_idx]
  269. .axi_port_name);
  270. if (rc) {
  271. CAM_ERR(CAM_CPAS,
  272. "fail to read camnoc-port-name rc=%d",
  273. rc);
  274. return rc;
  275. }
  276. cpas_node_ptr->camnoc_axi_port_idx = *camnoc_idx;
  277. cpas_core->num_camnoc_axi_ports++;
  278. (*camnoc_idx)++;
  279. }
  280. return 0;
  281. }
  282. static int cam_cpas_parse_mnoc_node(struct cam_cpas *cpas_core,
  283. struct cam_cpas_private_soc *soc_private, struct cam_cpas_tree_node *curr_node_ptr,
  284. struct device_node *mnoc_node, int *mnoc_idx)
  285. {
  286. int rc = 0, count, i;
  287. bool ib_voting_needed = false, is_rt_port = false;
  288. struct of_phandle_args src_args = {0}, dst_args = {0};
  289. ib_voting_needed = of_property_read_bool(curr_node_ptr->tree_dev_node,
  290. "ib-bw-voting-needed");
  291. is_rt_port = of_property_read_bool(curr_node_ptr->tree_dev_node, "rt-axi-port");
  292. if (soc_private->bus_icc_based) {
  293. count = of_property_count_strings(mnoc_node, "interconnect-names");
  294. if (count <= 0) {
  295. CAM_ERR(CAM_CPAS, "no interconnect-names found");
  296. return -EINVAL;
  297. } else if (count > CAM_CPAS_MAX_DRV_PORTS) {
  298. CAM_ERR(CAM_CPAS, "Number of interconnects %d greater than max ports %d",
  299. count, CAM_CPAS_MAX_DRV_PORTS);
  300. return -EINVAL;
  301. }
  302. for (i = 0; i < count; i++) {
  303. if ((i > 0) && !soc_private->enable_cam_ddr_drv)
  304. break;
  305. if (*mnoc_idx >= CAM_CPAS_MAX_AXI_PORTS) {
  306. CAM_ERR(CAM_CPAS, "Invalid mnoc index: %d", *mnoc_idx);
  307. return -EINVAL;
  308. }
  309. cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
  310. rc = of_property_read_string_index(mnoc_node, "interconnect-names", i,
  311. &cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
  312. if (rc) {
  313. CAM_ERR(CAM_CPAS, "failed to read interconnect-names rc=%d", rc);
  314. return rc;
  315. }
  316. rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
  317. "#interconnect-cells", (2 * i), &src_args);
  318. if (rc) {
  319. CAM_ERR(CAM_CPAS,
  320. "failed to read axi bus src info rc=%d",
  321. rc);
  322. return -EINVAL;
  323. }
  324. of_node_put(src_args.np);
  325. if (src_args.args_count != 1) {
  326. CAM_ERR(CAM_CPAS, "Invalid number of axi src args: %d",
  327. src_args.args_count);
  328. return -EINVAL;
  329. }
  330. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id =
  331. src_args.args[0];
  332. rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
  333. "#interconnect-cells", ((2 * i) + 1), &dst_args);
  334. if (rc) {
  335. CAM_ERR(CAM_CPAS, "failed to read axi bus dst info rc=%d", rc);
  336. return -EINVAL;
  337. }
  338. of_node_put(dst_args.np);
  339. if (dst_args.args_count != 1) {
  340. CAM_ERR(CAM_CPAS, "Invalid number of axi dst args: %d",
  341. dst_args.args_count);
  342. return -EINVAL;
  343. }
  344. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id =
  345. dst_args.args[0];
  346. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.num_usecases = 2;
  347. cpas_core->axi_port[*mnoc_idx].axi_port_name =
  348. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
  349. cpas_core->axi_port[*mnoc_idx].drv_idx = i;
  350. if (i > CAM_CPAS_PORT_HLOS_DRV) {
  351. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.is_drv_port =
  352. true;
  353. cpas_core->axi_port[*mnoc_idx].curr_bw.vote_type =
  354. CAM_CPAS_VOTE_TYPE_DRV;
  355. cpas_core->axi_port[*mnoc_idx].applied_bw.vote_type =
  356. CAM_CPAS_VOTE_TYPE_DRV;
  357. cpas_core->axi_port[*mnoc_idx].cam_rsc_dev =
  358. cam_cpas_get_rsc_dev_for_drv(i - CAM_CPAS_PORT_DRV_0);
  359. if (!cpas_core->axi_port[*mnoc_idx].cam_rsc_dev) {
  360. CAM_ERR(CAM_CPAS,
  361. "Port[%s][%d] Failed to get rsc device drv_idx:%d",
  362. cpas_core->axi_port[*mnoc_idx].axi_port_name,
  363. *mnoc_idx, i);
  364. rc = -ENODEV;
  365. goto err;
  366. }
  367. }
  368. /*
  369. * The indexes of axi_port_idx_arr map to drv_voting_idx,
  370. * with 0 pointing to hlos drv bus ID
  371. */
  372. curr_node_ptr->axi_port_idx_arr[i] = *mnoc_idx;
  373. cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
  374. cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
  375. CAM_DBG(CAM_PERF, "Adding Bus Client=[%s] : src=%d, dst=%d mnoc_idx:%d",
  376. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name,
  377. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id,
  378. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id,
  379. *mnoc_idx);
  380. (*mnoc_idx)++;
  381. cpas_core->num_axi_ports++;
  382. }
  383. } else {
  384. if (soc_private->enable_cam_ddr_drv) {
  385. CAM_ERR(CAM_CPAS, "DRV not supported for old bus scaling clients");
  386. return -EPERM;
  387. }
  388. cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
  389. rc = of_property_read_string(curr_node_ptr->tree_dev_node, "qcom,axi-port-name",
  390. &cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
  391. if (rc) {
  392. CAM_ERR(CAM_CPAS,
  393. "failed to read mnoc-port-name rc=%d",
  394. rc);
  395. return rc;
  396. }
  397. cpas_core->axi_port[*mnoc_idx].axi_port_name =
  398. cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
  399. curr_node_ptr->axi_port_idx_arr[0] = *mnoc_idx;
  400. cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
  401. cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
  402. (*mnoc_idx)++;
  403. cpas_core->num_axi_ports++;
  404. }
  405. err:
  406. return rc;
  407. }
  408. static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
  409. struct device_node *of_node, struct cam_cpas_private_soc *soc_private)
  410. {
  411. struct device_node *camera_bus_node;
  412. struct device_node *level_node;
  413. struct device_node *curr_node;
  414. struct device_node *parent_node;
  415. struct device_node *mnoc_node;
  416. int mnoc_idx = 0, camnoc_idx = 0, level_idx = 0;
  417. uint32_t path_idx;
  418. bool camnoc_max_needed = false;
  419. struct cam_cpas_tree_node *curr_node_ptr = NULL;
  420. struct cam_cpas_client *curr_client = NULL;
  421. const char *client_name = NULL;
  422. uint32_t client_idx = 0, cell_idx = 0;
  423. uint8_t niu_idx = 0;
  424. int rc = 0, count = 0, i, j, num_drv_ports;
  425. camera_bus_node = of_get_child_by_name(of_node, "camera-bus-nodes");
  426. if (!camera_bus_node) {
  427. CAM_ERR(CAM_CPAS, "Camera Bus node not found in cpas DT node");
  428. return -EINVAL;
  429. }
  430. soc_private->camera_bus_node = camera_bus_node;
  431. for_each_available_child_of_node(camera_bus_node, level_node) {
  432. rc = of_property_read_u32(level_node, "level-index", &level_idx);
  433. if (rc) {
  434. CAM_ERR(CAM_CPAS, "Error reading level idx rc: %d", rc);
  435. return rc;
  436. }
  437. if (level_idx >= CAM_CPAS_MAX_TREE_LEVELS) {
  438. CAM_ERR(CAM_CPAS, "Invalid level idx: %d", level_idx);
  439. return -EINVAL;
  440. }
  441. soc_private->level_node[level_idx] = level_node;
  442. }
  443. if (soc_private->enable_smart_qos)
  444. soc_private->smart_qos_info->num_rt_wr_nius = 0;
  445. if (soc_private->enable_cam_ddr_drv)
  446. num_drv_ports = CAM_CPAS_MAX_DRV_PORTS;
  447. else
  448. num_drv_ports = 1;
  449. for (level_idx = (CAM_CPAS_MAX_TREE_LEVELS - 1); level_idx >= 0;
  450. level_idx--) {
  451. level_node = soc_private->level_node[level_idx];
  452. if (!level_node)
  453. continue;
  454. CAM_DBG(CAM_CPAS, "Parsing level %d nodes", level_idx);
  455. camnoc_max_needed = of_property_read_bool(level_node, "camnoc-max-needed");
  456. for_each_available_child_of_node(level_node, curr_node) {
  457. curr_node_ptr = kzalloc(sizeof(struct cam_cpas_tree_node), GFP_KERNEL);
  458. if (!curr_node_ptr)
  459. return -ENOMEM;
  460. curr_node_ptr->tree_dev_node = curr_node;
  461. rc = of_property_read_u32(curr_node, "cell-index",
  462. &curr_node_ptr->cell_idx);
  463. if (rc) {
  464. CAM_ERR(CAM_CPAS, "Node index not found");
  465. return rc;
  466. }
  467. CAM_DBG(CAM_CPAS, "Parsing Node with cell index %d",
  468. curr_node_ptr->cell_idx);
  469. if (curr_node_ptr->cell_idx >=
  470. CAM_CPAS_MAX_TREE_NODES) {
  471. CAM_ERR(CAM_CPAS, "Invalid cell idx: %d", curr_node_ptr->cell_idx);
  472. return -EINVAL;
  473. }
  474. soc_private->tree_node[curr_node_ptr->cell_idx] = curr_node_ptr;
  475. curr_node_ptr->level_idx = level_idx;
  476. rc = of_property_read_string(curr_node, "node-name",
  477. &curr_node_ptr->node_name);
  478. if (rc) {
  479. CAM_ERR(CAM_CPAS, "failed to read node-name rc=%d", rc);
  480. return rc;
  481. }
  482. curr_node_ptr->bw_info = kzalloc((sizeof(struct cam_cpas_axi_bw_info) *
  483. num_drv_ports), GFP_KERNEL);
  484. if (!curr_node_ptr->bw_info) {
  485. CAM_ERR(CAM_CPAS, "Failed in allocating memory for bw info");
  486. return -ENOMEM;
  487. }
  488. curr_node_ptr->axi_port_idx_arr = kzalloc((sizeof(int) * num_drv_ports),
  489. GFP_KERNEL);
  490. if (!curr_node_ptr->axi_port_idx_arr) {
  491. CAM_ERR(CAM_CPAS, "Failed in allocating memory for port indices");
  492. return -ENOMEM;
  493. }
  494. if (soc_private->enable_smart_qos && (level_idx == 1) &&
  495. of_property_read_bool(curr_node, "rt-wr-niu")) {
  496. rc = of_property_read_u32(curr_node, "priority-lut-low-offset",
  497. &curr_node_ptr->pri_lut_low_offset);
  498. if (rc) {
  499. CAM_ERR(CAM_CPAS, "Invalid priority low offset rc %d", rc);
  500. return rc;
  501. }
  502. rc = of_property_read_u32(curr_node, "priority-lut-high-offset",
  503. &curr_node_ptr->pri_lut_high_offset);
  504. if (rc) {
  505. CAM_ERR(CAM_CPAS, "Invalid priority high offset rc %d", rc);
  506. return rc;
  507. }
  508. rc = of_property_read_u32(curr_node, "niu-size",
  509. &curr_node_ptr->niu_size);
  510. if (rc || !curr_node_ptr->niu_size) {
  511. CAM_ERR(CAM_CPAS, "Invalid niu size rc %d", rc);
  512. return rc;
  513. }
  514. niu_idx = soc_private->smart_qos_info->num_rt_wr_nius;
  515. if (niu_idx >= CAM_CPAS_MAX_RT_WR_NIU_NODES) {
  516. CAM_ERR(CAM_CPAS, "Invalid number of level1 nodes %d",
  517. soc_private->smart_qos_info->num_rt_wr_nius);
  518. return -EINVAL;
  519. }
  520. soc_private->smart_qos_info->rt_wr_niu_node[niu_idx] =
  521. curr_node_ptr;
  522. soc_private->smart_qos_info->num_rt_wr_nius++;
  523. CAM_DBG(CAM_CPAS,
  524. "level1[%d] : Node %s idx %d priority offset 0x%x, NIU size %dKB",
  525. niu_idx, curr_node_ptr->node_name, curr_node_ptr->cell_idx,
  526. curr_node_ptr->pri_lut_low_offset, curr_node_ptr->niu_size);
  527. }
  528. curr_node_ptr->camnoc_max_needed = camnoc_max_needed;
  529. rc = of_property_read_u32(curr_node, "bus-width-factor",
  530. &curr_node_ptr->bus_width_factor);
  531. if (rc)
  532. curr_node_ptr->bus_width_factor = 1;
  533. rc = of_property_read_u32(curr_node, "traffic-merge-type",
  534. &curr_node_ptr->merge_type);
  535. if (rc)
  536. curr_node_ptr->merge_type = CAM_CPAS_TRAFFIC_MERGE_SUM;
  537. for (j = 0; j < num_drv_ports; j++)
  538. curr_node_ptr->axi_port_idx_arr[j] = -1;
  539. mnoc_node = of_get_child_by_name(curr_node, "qcom,axi-port-mnoc");
  540. if (mnoc_node) {
  541. rc = cam_cpas_parse_mnoc_node(cpas_core, soc_private, curr_node_ptr,
  542. mnoc_node, &mnoc_idx);
  543. if (rc) {
  544. CAM_ERR(CAM_CPAS, "failed to parse mnoc node info rc=%d",
  545. rc);
  546. return rc;
  547. }
  548. }
  549. if (!soc_private->control_camnoc_axi_clk) {
  550. rc = cam_cpas_update_camnoc_node(cpas_core, curr_node,
  551. curr_node_ptr, &camnoc_idx);
  552. if (rc) {
  553. CAM_ERR(CAM_CPAS, "failed to parse camnoc node info rc=%d",
  554. rc);
  555. return rc;
  556. }
  557. }
  558. rc = of_property_read_string(curr_node, "client-name", &client_name);
  559. if (!rc) {
  560. rc = of_property_read_u32(curr_node, "traffic-data",
  561. &curr_node_ptr->path_data_type);
  562. if (rc) {
  563. CAM_ERR(CAM_CPAS,
  564. "Path Data type not found");
  565. return rc;
  566. }
  567. rc = cam_cpas_util_path_type_to_idx(&curr_node_ptr->path_data_type);
  568. if (rc) {
  569. CAM_ERR(CAM_CPAS, "Incorrect path type for client: %s",
  570. client_name);
  571. return rc;
  572. }
  573. rc = of_property_read_u32(curr_node, "traffic-transaction-type",
  574. &curr_node_ptr->path_trans_type);
  575. if (rc) {
  576. CAM_ERR(CAM_CPAS, "Path Transac type not found");
  577. return rc;
  578. }
  579. if (curr_node_ptr->path_trans_type >= CAM_CPAS_TRANSACTION_MAX) {
  580. CAM_ERR(CAM_CPAS, "Invalid transac type: %d",
  581. curr_node_ptr->path_trans_type);
  582. return -EINVAL;
  583. }
  584. count = of_property_count_u32_elems(curr_node, "constituent-paths");
  585. for (i = 0; i < count; i++) {
  586. rc = of_property_read_u32_index(curr_node,
  587. "constituent-paths", i, &path_idx);
  588. if (rc) {
  589. CAM_ERR(CAM_CPAS, "No constituent path at %d", i);
  590. return rc;
  591. }
  592. rc = cam_cpas_util_path_type_to_idx(&path_idx);
  593. if (rc)
  594. return rc;
  595. curr_node_ptr->constituent_paths[path_idx] = true;
  596. }
  597. rc = cam_common_util_get_string_index(soc_private->client_name,
  598. soc_private->num_clients, client_name, &client_idx);
  599. if (rc) {
  600. CAM_ERR(CAM_CPAS, "client name not found in list: %s",
  601. client_name);
  602. return rc;
  603. }
  604. if (client_idx >= CAM_CPAS_MAX_CLIENTS)
  605. return -EINVAL;
  606. curr_client = cpas_core->cpas_client[client_idx];
  607. curr_client->tree_node_valid = true;
  608. curr_client->tree_node[curr_node_ptr->path_data_type]
  609. [curr_node_ptr->path_trans_type] = curr_node_ptr;
  610. if (soc_private->enable_cam_ddr_drv) {
  611. rc = of_property_read_u32(curr_node, "drv-voting-index",
  612. &curr_node_ptr->drv_voting_idx);
  613. if (rc)
  614. curr_node_ptr->merge_type = CAM_CPAS_PORT_HLOS_DRV;
  615. if (curr_node_ptr->drv_voting_idx == CAM_CPAS_PORT_DRV_DYN)
  616. curr_client->is_drv_dyn = true;
  617. if (curr_client->is_drv_dyn &&
  618. (curr_node_ptr->drv_voting_idx !=
  619. CAM_CPAS_PORT_DRV_DYN))
  620. CAM_ERR(CAM_CPAS,
  621. "Invalid config for drv dyn client: %s drv_idx: %d",
  622. client_name, curr_node_ptr->drv_voting_idx);
  623. }
  624. CAM_DBG(CAM_CPAS,
  625. "Node Added: Client[%s] DataType[%d] TransType[%d] DRV idx[%d]",
  626. client_name,
  627. curr_node_ptr->path_data_type,
  628. curr_node_ptr->path_trans_type,
  629. curr_node_ptr->drv_voting_idx);
  630. }
  631. if (soc_private->enable_cam_ddr_drv)
  632. for (j = CAM_CPAS_PORT_DRV_0; j < num_drv_ports; j++)
  633. curr_node_ptr->bw_info[j].vote_type =
  634. CAM_CPAS_VOTE_TYPE_DRV;
  635. parent_node = of_parse_phandle(curr_node, "parent-node", 0);
  636. if (parent_node) {
  637. of_property_read_u32(parent_node, "cell-index", &cell_idx);
  638. curr_node_ptr->parent_node = soc_private->tree_node[cell_idx];
  639. } else {
  640. CAM_DBG(CAM_CPAS, "no parent node at this level");
  641. }
  642. }
  643. }
  644. mutex_init(&cpas_core->tree_lock);
  645. cam_cpas_util_debug_parse_data(soc_private);
  646. return 0;
  647. }
  648. int cam_cpas_get_hw_features(struct platform_device *pdev,
  649. struct cam_cpas_private_soc *soc_private)
  650. {
  651. struct device_node *of_node;
  652. void *fuse;
  653. uint32_t fuse_addr, fuse_mask, fuse_shift;
  654. uint32_t val = 0, fuse_val = 0, feature;
  655. uint32_t enable_type = 0, hw_map = 0;
  656. int count = 0, i = 0, j = 0, num_feature = 0, num_fuse = 0;
  657. struct cam_cpas_feature_info *feature_info;
  658. of_node = pdev->dev.of_node;
  659. count = of_property_count_u32_elems(of_node, "cam_hw_fuse");
  660. CAM_DBG(CAM_CPAS, "fuse info elements count %d", count);
  661. if (count <= 0) {
  662. goto end;
  663. } else if (count%5 != 0) {
  664. CAM_INFO(CAM_CPAS, "fuse entries should be multiple of 5 %d",
  665. count);
  666. goto end;
  667. }
  668. for (i = 0; (i + 5) <= count; i = i + 5) {
  669. of_property_read_u32_index(of_node, "cam_hw_fuse", i,
  670. &feature);
  671. of_property_read_u32_index(of_node, "cam_hw_fuse", i + 1,
  672. &fuse_addr);
  673. of_property_read_u32_index(of_node, "cam_hw_fuse", i + 2,
  674. &fuse_mask);
  675. of_property_read_u32_index(of_node, "cam_hw_fuse", i + 3,
  676. &enable_type);
  677. of_property_read_u32_index(of_node, "cam_hw_fuse", i + 4,
  678. &hw_map);
  679. val = ffs(fuse_mask);
  680. if (val == 0) {
  681. CAM_ERR(CAM_CPAS, "fuse_mask not valid 0x%x",
  682. fuse_mask);
  683. fuse_shift = 0;
  684. } else {
  685. fuse_shift = val - 1;
  686. }
  687. CAM_INFO(CAM_CPAS,
  688. "feature 0x%x addr 0x%x, mask 0x%x, shift 0x%x type 0x%x hw_map 0x%x",
  689. feature, fuse_addr, fuse_mask, fuse_shift, enable_type,
  690. hw_map);
  691. fuse = ioremap(fuse_addr, 4);
  692. if (fuse) {
  693. fuse_val = cam_io_r(fuse);
  694. for (j = 0; (j < num_fuse) && (j < CAM_CPAS_FUSES_MAX);
  695. j++) {
  696. if (soc_private->fuse_info.fuse_val[j].fuse_id
  697. == fuse_addr)
  698. break;
  699. }
  700. if (j >= CAM_CPAS_FUSES_MAX) {
  701. CAM_ERR(CAM_CPAS,
  702. "fuse_info array overflow! %d", j);
  703. goto end;
  704. }
  705. if (j == num_fuse) {
  706. soc_private->fuse_info.fuse_val[j].fuse_id =
  707. fuse_addr;
  708. soc_private->fuse_info.fuse_val[j].fuse_val =
  709. fuse_val;
  710. CAM_INFO(CAM_CPAS,
  711. "fuse_addr 0x%x, fuse_val %x",
  712. fuse_addr, fuse_val);
  713. num_fuse++;
  714. }
  715. } else {
  716. /* if fuse ioremap is failed, disable the feature */
  717. CAM_ERR(CAM_CPAS,
  718. "fuse register io remap failed fuse_addr:0x%x feature0x%x ",
  719. fuse_addr, feature);
  720. if (enable_type == CAM_CPAS_FEATURE_TYPE_ENABLE ||
  721. enable_type == CAM_CPAS_FEATURE_TYPE_DISABLE)
  722. fuse_val = (enable_type) ? ~fuse_mask :
  723. fuse_mask;
  724. else
  725. fuse_val = 0;
  726. }
  727. if (num_feature >= CAM_CPAS_MAX_FUSE_FEATURE) {
  728. CAM_ERR(CAM_CPAS, "feature_info array overflow %d",
  729. num_feature);
  730. goto end;
  731. }
  732. soc_private->feature_info[num_feature].feature =
  733. feature;
  734. soc_private->feature_info[num_feature].hw_map = hw_map;
  735. soc_private->feature_info[num_feature].type = enable_type;
  736. feature_info = &soc_private->feature_info[num_feature];
  737. if (enable_type != CAM_CPAS_FEATURE_TYPE_VALUE) {
  738. if (enable_type == CAM_CPAS_FEATURE_TYPE_ENABLE) {
  739. /*
  740. * fuse is for enable feature
  741. * if fust bit is set means feature is enabled
  742. * or HW is enabled
  743. */
  744. if (fuse_val & fuse_mask)
  745. feature_info->enable = true;
  746. else
  747. feature_info->enable = false;
  748. } else if (enable_type ==
  749. CAM_CPAS_FEATURE_TYPE_DISABLE){
  750. /*
  751. * fuse is for disable feature
  752. * if fust bit is set means feature is disabled
  753. * or HW is disabled
  754. */
  755. if (fuse_val & fuse_mask)
  756. feature_info->enable = false;
  757. else
  758. feature_info->enable = true;
  759. } else {
  760. CAM_ERR(CAM_CPAS,
  761. "Feature type not valid, type: %d",
  762. enable_type);
  763. goto end;
  764. }
  765. CAM_INFO(CAM_CPAS,
  766. "feature 0x%x enable=%d hw_map=0x%x",
  767. feature_info->feature, feature_info->enable,
  768. feature_info->hw_map);
  769. } else {
  770. feature_info->value =
  771. (fuse_val & fuse_mask) >> fuse_shift;
  772. CAM_INFO(CAM_CPAS,
  773. "feature 0x%x value=0x%x hw_map=0x%x",
  774. feature_info->feature, feature_info->value,
  775. feature_info->hw_map);
  776. }
  777. num_feature++;
  778. iounmap(fuse);
  779. }
  780. end:
  781. soc_private->fuse_info.num_fuses = num_fuse;
  782. soc_private->num_feature_info = num_feature;
  783. return 0;
  784. }
  785. static inline enum cam_sys_cache_config_types cam_cpas_find_type_from_string(
  786. const char *cache_name)
  787. {
  788. if (strcmp(cache_name, "small-1") == 0)
  789. return CAM_LLCC_SMALL_1;
  790. else if (strcmp(cache_name, "small-2") == 0)
  791. return CAM_LLCC_SMALL_2;
  792. else if (strcmp(cache_name, "large-1") == 0)
  793. return CAM_LLCC_LARGE_1;
  794. else if (strcmp(cache_name, "large-2") == 0)
  795. return CAM_LLCC_LARGE_2;
  796. else if (strcmp(cache_name, "large-3") == 0)
  797. return CAM_LLCC_LARGE_3;
  798. else if (strcmp(cache_name, "large-4") == 0)
  799. return CAM_LLCC_LARGE_4;
  800. else
  801. return CAM_LLCC_MAX;
  802. }
  803. static int cam_cpas_parse_sys_cache_uids(
  804. struct device_node *of_node,
  805. struct cam_cpas_private_soc *soc_private)
  806. {
  807. enum cam_sys_cache_config_types type = CAM_LLCC_MAX;
  808. int num_caches, i, rc;
  809. uint32_t scid;
  810. soc_private->llcc_info = NULL;
  811. soc_private->num_caches = 0;
  812. num_caches = of_property_count_strings(of_node, "sys-cache-names");
  813. if (num_caches <= 0) {
  814. CAM_DBG(CAM_CPAS, "no cache-names found");
  815. return 0;
  816. }
  817. if (num_caches > CAM_LLCC_MAX) {
  818. CAM_ERR(CAM_CPAS,
  819. "invalid number of cache-names found: 0x%x",
  820. num_caches);
  821. return -EINVAL;
  822. }
  823. soc_private->llcc_info = kcalloc(num_caches,
  824. sizeof(struct cam_sys_cache_info), GFP_KERNEL);
  825. if (!soc_private->llcc_info)
  826. return -ENOMEM;
  827. for (i = 0; i < num_caches; i++) {
  828. rc = of_property_read_string_index(of_node, "sys-cache-names", i,
  829. &soc_private->llcc_info[i].name);
  830. if (rc) {
  831. CAM_ERR(CAM_CPAS, "failed to read cache-names at %d", i);
  832. goto end;
  833. }
  834. type = cam_cpas_find_type_from_string(
  835. soc_private->llcc_info[i].name);
  836. if (type == CAM_LLCC_MAX) {
  837. CAM_ERR(CAM_CPAS, "Unsupported cache found: %s",
  838. soc_private->llcc_info[i].name);
  839. rc = -EINVAL;
  840. goto end;
  841. }
  842. soc_private->llcc_info[i].type = type;
  843. rc = of_property_read_u32_index(of_node,
  844. "sys-cache-uids", i,
  845. &soc_private->llcc_info[i].uid);
  846. if (rc < 0) {
  847. CAM_ERR(CAM_CPAS,
  848. "unable to read sys cache uid at index %d", i);
  849. goto end;
  850. }
  851. soc_private->llcc_info[i].slic_desc =
  852. llcc_slice_getd(soc_private->llcc_info[i].uid);
  853. if (IS_ERR_OR_NULL(soc_private->llcc_info[i].slic_desc)) {
  854. CAM_ERR(CAM_CPAS,
  855. "Failed to get slice desc for uid %u",
  856. soc_private->llcc_info[i].uid);
  857. rc = -EINVAL;
  858. goto end;
  859. }
  860. scid = llcc_get_slice_id(soc_private->llcc_info[i].slic_desc);
  861. soc_private->llcc_info[i].scid = scid;
  862. soc_private->llcc_info[i].size =
  863. llcc_get_slice_size(soc_private->llcc_info[i].slic_desc);
  864. soc_private->llcc_info[i].staling_distance = 0;
  865. soc_private->llcc_info[i].mode = CAM_LLCC_STALING_MODE_CAPACITY;
  866. soc_private->llcc_info[i].op_type = CAM_LLCC_NOTIFY_STALING_EVICT;
  867. soc_private->num_caches++;
  868. CAM_DBG(CAM_CPAS,
  869. "Cache: %s uid: %u scid: %d size: %zukb",
  870. soc_private->llcc_info[i].name,
  871. soc_private->llcc_info[i].uid, scid,
  872. soc_private->llcc_info[i].size);
  873. }
  874. return 0;
  875. end:
  876. kfree(soc_private->llcc_info);
  877. soc_private->llcc_info = NULL;
  878. return rc;
  879. }
  880. #ifdef CONFIG_DOMAIN_ID_SECURE_CAMERA
  881. static int cam_cpas_parse_domain_id_mapping(struct device_node *of_node,
  882. struct cam_cpas_private_soc *soc_private)
  883. {
  884. int count, i, rc = 0;
  885. soc_private->domain_id_info.num_domain_ids = 0;
  886. soc_private->domain_id_info.domain_id_supported = false;
  887. soc_private->domain_id_info.domain_id_entries = NULL;
  888. count = of_property_count_u32_elems(of_node, "domain-id");
  889. if (count <= 0) {
  890. CAM_DBG(CAM_CPAS, "No domain-id mapping found, count: %d", count);
  891. return rc;
  892. }
  893. /* This property will always be specified in pairs */
  894. if (count % 2) {
  895. CAM_ERR(CAM_CPAS,
  896. "Mismatch in domain-id mapping, found %d number of entries", count);
  897. rc = -EINVAL;
  898. goto err;
  899. }
  900. soc_private->domain_id_info.num_domain_ids = count / 2;
  901. if (soc_private->domain_id_info.num_domain_ids > CAM_CPAS_DOMAIN_ID_MAX) {
  902. CAM_ERR(CAM_CPAS,
  903. "Number of domain id types: %u more than supported: %d",
  904. soc_private->domain_id_info.num_domain_ids, CAM_CPAS_DOMAIN_ID_MAX);
  905. rc = -EINVAL;
  906. goto err;
  907. }
  908. soc_private->domain_id_info.domain_id_entries =
  909. kcalloc(soc_private->domain_id_info.num_domain_ids,
  910. sizeof(struct cam_cpas_domain_id_mapping), GFP_KERNEL);
  911. if (!soc_private->domain_id_info.domain_id_entries) {
  912. CAM_ERR(CAM_CPAS,
  913. "Error allocating memory for %u domain-id mapping(s)",
  914. soc_private->domain_id_info.num_domain_ids);
  915. rc = -ENOMEM;
  916. goto err;
  917. }
  918. for (i = 0; i < soc_private->domain_id_info.num_domain_ids; i++) {
  919. struct cam_cpas_domain_id_mapping *domain_id_entry =
  920. &soc_private->domain_id_info.domain_id_entries[i];
  921. rc = of_property_read_u32_index(of_node, "domain-id",
  922. (i * 2), &domain_id_entry->domain_type);
  923. if (rc) {
  924. CAM_ERR(CAM_CPAS, "Error reading domain-id type entry at pos %d", i);
  925. rc = -EINVAL;
  926. goto err;
  927. }
  928. if (domain_id_entry->domain_type > CAM_CPAS_SECURE_DOMAIN) {
  929. CAM_ERR(CAM_CPAS, "Unexpected domain id type: %u",
  930. domain_id_entry->domain_type);
  931. rc = -EINVAL;
  932. goto err;
  933. }
  934. rc = of_property_read_u32_index(of_node, "domain-id",
  935. ((i * 2) + 1), &domain_id_entry->mapping_id);
  936. if (rc) {
  937. CAM_ERR(CAM_CPAS, "Error reading domain-id mapping id at pos %d", i);
  938. rc = -EINVAL;
  939. goto err;
  940. }
  941. CAM_DBG(CAM_CPAS, "Domain-id type: %u, mapping: %u at pos: %d",
  942. domain_id_entry->domain_type, domain_id_entry->mapping_id, i);
  943. }
  944. soc_private->domain_id_info.domain_id_supported = true;
  945. return rc;
  946. err:
  947. soc_private->domain_id_info.num_domain_ids = 0;
  948. kfree(soc_private->domain_id_info.domain_id_entries);
  949. soc_private->domain_id_info.domain_id_entries = NULL;
  950. return rc;
  951. }
  952. #endif
  953. static int cam_cpas_get_domain_id_support_clks(struct device_node *of_node,
  954. struct cam_hw_soc_info *soc_info, struct cam_cpas_private_soc *soc_private)
  955. {
  956. int rc = 0, count, i;
  957. struct cam_cpas_domain_id_support_clks *domain_id_clks;
  958. soc_private->domain_id_clks = kzalloc(sizeof(struct cam_cpas_domain_id_support_clks),
  959. GFP_KERNEL);
  960. if (!soc_private->domain_id_clks) {
  961. CAM_ERR(CAM_CPAS, "Failed in allocating memory for domain_id_clk");
  962. return -ENOMEM;
  963. }
  964. domain_id_clks = soc_private->domain_id_clks;
  965. count = of_property_count_strings(of_node, "domain-id-support-clks");
  966. CAM_DBG(CAM_CPAS, "Domain-id clk count: %d", count);
  967. if (count > CAM_SOC_MAX_OPT_CLK) {
  968. CAM_ERR(CAM_CPAS, "Invalid cnt of clocks, count: %d", count);
  969. rc = -EINVAL;
  970. goto err;
  971. }
  972. if (count <= 0) {
  973. CAM_ERR(CAM_CPAS, "No domain-id clk found");
  974. rc = -EINVAL;
  975. goto err;
  976. }
  977. domain_id_clks->number_clks = count;
  978. for (i = 0; i < count; i++) {
  979. rc = of_property_read_string_index(of_node, "domain-id-support-clks",
  980. i, &domain_id_clks->clk_names[i]);
  981. if (rc) {
  982. CAM_ERR(CAM_CPAS,
  983. "Failed reading domain-id clk name at i: %d, total clks: %d",
  984. i, count);
  985. rc = -EINVAL;
  986. goto err;
  987. }
  988. rc = cam_soc_util_get_option_clk_by_name(soc_info, domain_id_clks->clk_names[i],
  989. &domain_id_clks->clk_idx[i]);
  990. if (rc) {
  991. CAM_ERR(CAM_CPAS,
  992. "Failed reading domain-id clk %s at i: %d, total clks; %d",
  993. domain_id_clks->clk_names[i], i, count);
  994. rc = -EINVAL;
  995. goto err;
  996. }
  997. CAM_DBG(CAM_CPAS, "Domain-id-clk %s with clk index %d",
  998. domain_id_clks->clk_names[i], domain_id_clks->clk_idx[i]);
  999. }
  1000. return rc;
  1001. err:
  1002. kfree(domain_id_clks);
  1003. return rc;
  1004. }
  1005. int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
  1006. struct platform_device *pdev, struct cam_cpas_private_soc *soc_private)
  1007. {
  1008. struct device_node *of_node;
  1009. struct of_phandle_args src_args = {0}, dst_args = {0};
  1010. int count = 0, i = 0, rc = 0, num_bw_values = 0, num_levels = 0;
  1011. uint32_t cam_drv_en_mask_val = 0;
  1012. struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
  1013. uint32_t ahb_bus_client_ab = 0, ahb_bus_client_ib = 0;
  1014. if (!soc_private || !pdev) {
  1015. CAM_ERR(CAM_CPAS, "invalid input arg %pK %pK",
  1016. soc_private, pdev);
  1017. return -EINVAL;
  1018. }
  1019. of_node = pdev->dev.of_node;
  1020. rc = of_property_read_string(of_node, "arch-compat",
  1021. &soc_private->arch_compat);
  1022. if (rc) {
  1023. CAM_ERR(CAM_CPAS, "device %s failed to read arch-compat",
  1024. pdev->name);
  1025. return rc;
  1026. }
  1027. cam_cpas_get_hw_features(pdev, soc_private);
  1028. #ifdef CONFIG_DOMAIN_ID_SECURE_CAMERA
  1029. /* get domain id mapping info */
  1030. rc = cam_cpas_parse_domain_id_mapping(of_node, soc_private);
  1031. if (rc)
  1032. return rc;
  1033. /* check if the domain ID configuration is available in the DTSI */
  1034. if (soc_private->domain_id_info.domain_id_supported == false) {
  1035. CAM_ERR(CAM_CPAS, "Domain ID configuration is expected for this target");
  1036. return -EINVAL;
  1037. }
  1038. #endif
  1039. soc_private->camnoc_axi_min_ib_bw = 0;
  1040. rc = of_property_read_u64(of_node,
  1041. "camnoc-axi-min-ib-bw",
  1042. &soc_private->camnoc_axi_min_ib_bw);
  1043. if (rc == -EOVERFLOW) {
  1044. soc_private->camnoc_axi_min_ib_bw = 0;
  1045. rc = of_property_read_u32(of_node,
  1046. "camnoc-axi-min-ib-bw",
  1047. (u32 *)&soc_private->camnoc_axi_min_ib_bw);
  1048. }
  1049. if (rc) {
  1050. CAM_DBG(CAM_CPAS,
  1051. "failed to read camnoc-axi-min-ib-bw rc:%d", rc);
  1052. soc_private->camnoc_axi_min_ib_bw =
  1053. CAM_CPAS_AXI_MIN_CAMNOC_IB_BW;
  1054. }
  1055. CAM_DBG(CAM_CPAS, "camnoc-axi-min-ib-bw = %llu",
  1056. soc_private->camnoc_axi_min_ib_bw);
  1057. soc_private->client_id_based = of_property_read_bool(of_node,
  1058. "client-id-based");
  1059. soc_private->bus_icc_based = of_property_read_bool(of_node,
  1060. "interconnects");
  1061. if (soc_private->bus_icc_based) {
  1062. rc = of_property_read_string(of_node, "interconnect-names",
  1063. &cpas_core->ahb_bus_client.common_data.name);
  1064. if (rc) {
  1065. CAM_ERR(CAM_CPAS,
  1066. "device %s failed to read interconnect-names",
  1067. pdev->name);
  1068. return rc;
  1069. }
  1070. rc = of_parse_phandle_with_args(of_node, "interconnects",
  1071. "#interconnect-cells", 0, &src_args);
  1072. if (rc) {
  1073. CAM_ERR(CAM_CPAS,
  1074. "device %s failed to read ahb bus src info",
  1075. pdev->name);
  1076. return rc;
  1077. }
  1078. of_node_put(src_args.np);
  1079. if (src_args.args_count != 1) {
  1080. CAM_ERR(CAM_CPAS,
  1081. "Invalid number of ahb src args: %d",
  1082. src_args.args_count);
  1083. return -EINVAL;
  1084. }
  1085. cpas_core->ahb_bus_client.common_data.src_id = src_args.args[0];
  1086. rc = of_parse_phandle_with_args(of_node, "interconnects",
  1087. "#interconnect-cells", 1, &dst_args);
  1088. if (rc) {
  1089. CAM_ERR(CAM_CPAS,
  1090. "device %s failed to read ahb bus dst info",
  1091. pdev->name);
  1092. return rc;
  1093. }
  1094. of_node_put(dst_args.np);
  1095. if (dst_args.args_count != 1) {
  1096. CAM_ERR(CAM_CPAS,
  1097. "Invalid number of ahb dst args: %d",
  1098. dst_args.args_count);
  1099. return -EINVAL;
  1100. }
  1101. cpas_core->ahb_bus_client.common_data.dst_id = dst_args.args[0];
  1102. rc = of_property_read_u32(of_node, "cam-ahb-num-cases",
  1103. &cpas_core->ahb_bus_client.common_data.num_usecases);
  1104. if (rc) {
  1105. CAM_ERR(CAM_CPAS,
  1106. "device %s failed to read ahb num usecases",
  1107. pdev->name);
  1108. return rc;
  1109. }
  1110. if (cpas_core->ahb_bus_client.common_data.num_usecases >
  1111. CAM_SOC_BUS_MAX_NUM_USECASES) {
  1112. CAM_ERR(CAM_UTIL, "Invalid number of usecases: %d",
  1113. cpas_core->ahb_bus_client.common_data
  1114. .num_usecases);
  1115. return -EINVAL;
  1116. }
  1117. num_bw_values = of_property_count_u32_elems(of_node,
  1118. "cam-ahb-bw-KBps");
  1119. if (num_bw_values <= 0) {
  1120. CAM_ERR(CAM_UTIL, "Error counting ahb bw values");
  1121. return -EINVAL;
  1122. }
  1123. CAM_DBG(CAM_CPAS, "AHB: num bw values %d", num_bw_values);
  1124. num_levels = (num_bw_values / 2);
  1125. if (num_levels !=
  1126. cpas_core->ahb_bus_client.common_data.num_usecases) {
  1127. CAM_ERR(CAM_UTIL, "Invalid number of levels: %d",
  1128. num_bw_values/2);
  1129. return -EINVAL;
  1130. }
  1131. for (i = 0; i < num_levels; i++) {
  1132. rc = of_property_read_u32_index(of_node,
  1133. "cam-ahb-bw-KBps",
  1134. (i * 2),
  1135. &ahb_bus_client_ab);
  1136. if (rc) {
  1137. CAM_ERR(CAM_UTIL,
  1138. "Error reading ab bw value, rc=%d",
  1139. rc);
  1140. return rc;
  1141. }
  1142. cpas_core->ahb_bus_client.common_data.bw_pair[i].ab = ahb_bus_client_ab;
  1143. rc = of_property_read_u32_index(of_node,
  1144. "cam-ahb-bw-KBps",
  1145. ((i * 2) + 1),
  1146. &ahb_bus_client_ib);
  1147. if (rc) {
  1148. CAM_ERR(CAM_UTIL,
  1149. "Error reading ib bw value, rc=%d",
  1150. rc);
  1151. return rc;
  1152. }
  1153. cpas_core->ahb_bus_client.common_data.bw_pair[i].ib = ahb_bus_client_ib;
  1154. CAM_DBG(CAM_CPAS,
  1155. "AHB: Level: %d, ab_value %llu, ib_value: %llu",
  1156. i, cpas_core->ahb_bus_client.common_data
  1157. .bw_pair[i].ab, cpas_core->ahb_bus_client
  1158. .common_data.bw_pair[i].ib);
  1159. }
  1160. }
  1161. count = of_property_count_strings(of_node, "client-names");
  1162. if (count <= 0) {
  1163. CAM_ERR(CAM_CPAS, "no client-names found");
  1164. return -EINVAL;
  1165. } else if (count > CAM_CPAS_MAX_CLIENTS) {
  1166. CAM_ERR(CAM_CPAS, "Number of clients %d greater than max %d",
  1167. count, CAM_CPAS_MAX_CLIENTS);
  1168. return -EINVAL;
  1169. }
  1170. soc_private->num_clients = count;
  1171. CAM_DBG(CAM_CPAS,
  1172. "arch-compat=%s, client_id_based = %d, num_clients=%d",
  1173. soc_private->arch_compat, soc_private->client_id_based,
  1174. soc_private->num_clients);
  1175. for (i = 0; i < soc_private->num_clients; i++) {
  1176. rc = of_property_read_string_index(of_node,
  1177. "client-names", i, &soc_private->client_name[i]);
  1178. if (rc) {
  1179. CAM_ERR(CAM_CPAS, "no client-name at cnt=%d", i);
  1180. return -EINVAL;
  1181. }
  1182. cpas_core->cpas_client[i] =
  1183. kzalloc(sizeof(struct cam_cpas_client), GFP_KERNEL);
  1184. if (!cpas_core->cpas_client[i]) {
  1185. rc = -ENOMEM;
  1186. goto cleanup_clients;
  1187. }
  1188. CAM_DBG(CAM_CPAS, "Client[%d] : %s", i,
  1189. soc_private->client_name[i]);
  1190. }
  1191. soc_private->control_camnoc_axi_clk = of_property_read_bool(of_node,
  1192. "control-camnoc-axi-clk");
  1193. if (soc_private->control_camnoc_axi_clk == true) {
  1194. rc = of_property_read_u32(of_node, "camnoc-bus-width",
  1195. &soc_private->camnoc_bus_width);
  1196. if (rc || (soc_private->camnoc_bus_width == 0)) {
  1197. CAM_ERR(CAM_CPAS, "Bus width not found rc=%d, %d",
  1198. rc, soc_private->camnoc_bus_width);
  1199. goto cleanup_clients;
  1200. }
  1201. if (of_property_read_u32(of_node,
  1202. "camnoc-axi-clk-bw-margin-perc",
  1203. &soc_private->camnoc_axi_clk_bw_margin)) {
  1204. /* this is not fatal, overwrite to 0 */
  1205. soc_private->camnoc_axi_clk_bw_margin = 0;
  1206. }
  1207. }
  1208. CAM_DBG(CAM_CPAS,
  1209. "control_camnoc_axi_clk=%d, width=%d, margin=%d",
  1210. soc_private->control_camnoc_axi_clk,
  1211. soc_private->camnoc_bus_width,
  1212. soc_private->camnoc_axi_clk_bw_margin);
  1213. count = of_property_count_u32_elems(of_node, "vdd-corners");
  1214. if ((count > 0) && (count <= CAM_REGULATOR_LEVEL_MAX) &&
  1215. (of_property_count_strings(of_node, "vdd-corner-ahb-mapping") ==
  1216. count)) {
  1217. const char *ahb_string;
  1218. for (i = 0; i < count; i++) {
  1219. rc = of_property_read_u32_index(of_node, "vdd-corners",
  1220. i, &soc_private->vdd_ahb[i].vdd_corner);
  1221. if (rc) {
  1222. CAM_ERR(CAM_CPAS,
  1223. "vdd-corners failed at index=%d", i);
  1224. rc = -ENODEV;
  1225. goto cleanup_clients;
  1226. }
  1227. rc = of_property_read_string_index(of_node,
  1228. "vdd-corner-ahb-mapping", i, &ahb_string);
  1229. if (rc) {
  1230. CAM_ERR(CAM_CPAS,
  1231. "no ahb-mapping at index=%d", i);
  1232. rc = -ENODEV;
  1233. goto cleanup_clients;
  1234. }
  1235. rc = cam_soc_util_get_level_from_string(ahb_string,
  1236. &soc_private->vdd_ahb[i].ahb_level);
  1237. if (rc) {
  1238. CAM_ERR(CAM_CPAS,
  1239. "invalid ahb-string at index=%d", i);
  1240. rc = -EINVAL;
  1241. goto cleanup_clients;
  1242. }
  1243. CAM_DBG(CAM_CPAS,
  1244. "Vdd-AHB mapping [%d] : [%d] [%s] [%d]", i,
  1245. soc_private->vdd_ahb[i].vdd_corner,
  1246. ahb_string, soc_private->vdd_ahb[i].ahb_level);
  1247. }
  1248. soc_private->num_vdd_ahb_mapping = count;
  1249. }
  1250. soc_private->enable_secure_qos_update = of_property_read_bool(of_node,
  1251. "enable-secure-qos-update");
  1252. soc_private->enable_smart_qos = of_property_read_bool(of_node,
  1253. "enable-smart-qos");
  1254. if (soc_private->enable_smart_qos) {
  1255. uint32_t value;
  1256. soc_private->smart_qos_info = kzalloc(sizeof(struct cam_cpas_smart_qos_info),
  1257. GFP_KERNEL);
  1258. if (!soc_private->smart_qos_info) {
  1259. rc = -ENOMEM;
  1260. goto cleanup_clients;
  1261. }
  1262. /*
  1263. * If enabled, we expect min and max priority values,
  1264. * clamp priority value, slope factor, least and most
  1265. * stressed clamp threshold values, high and low stress
  1266. * indicator threshold values, bw ratio scale factor value,
  1267. * so treat as fatal error if not available.
  1268. */
  1269. rc = of_property_read_u32(of_node, "rt-wr-priority-min",
  1270. &value);
  1271. if (rc) {
  1272. CAM_ERR(CAM_CPAS, "Invalid min Qos priority rc %d", rc);
  1273. goto cleanup_clients;
  1274. }
  1275. soc_private->smart_qos_info->rt_wr_priority_min = (uint8_t)value;
  1276. rc = of_property_read_u32(of_node, "rt-wr-priority-max",
  1277. &value);
  1278. if (rc) {
  1279. CAM_ERR(CAM_CPAS, "Invalid max Qos priority rc %d", rc);
  1280. goto cleanup_clients;
  1281. }
  1282. soc_private->smart_qos_info->rt_wr_priority_max = (uint8_t)value;
  1283. rc = of_property_read_u32(of_node, "rt-wr-priority-clamp",
  1284. &value);
  1285. if (rc) {
  1286. CAM_ERR(CAM_CPAS, "Invalid clamp Qos priority rc %d", rc);
  1287. goto cleanup_clients;
  1288. }
  1289. soc_private->smart_qos_info->rt_wr_priority_clamp = (uint8_t)value;
  1290. rc = of_property_read_u32(of_node, "rt-wr-slope-factor",
  1291. &value);
  1292. if (rc) {
  1293. CAM_ERR(CAM_CPAS, "Invalid slope factor rc %d", rc);
  1294. goto cleanup_clients;
  1295. }
  1296. if (value > CAM_CPAS_MAX_SLOPE_FACTOR) {
  1297. CAM_ERR(CAM_UTIL, "Invalid slope factor value %d", value);
  1298. rc = -EINVAL;
  1299. goto cleanup_clients;
  1300. } else
  1301. soc_private->smart_qos_info->rt_wr_slope_factor = (uint8_t)value;
  1302. CAM_DBG(CAM_CPAS,
  1303. "SmartQoS enabled, priority min=%u, max=%u, clamp=%u, slope factor=%u",
  1304. (uint32_t)soc_private->smart_qos_info->rt_wr_priority_min,
  1305. (uint32_t)soc_private->smart_qos_info->rt_wr_priority_max,
  1306. (uint32_t)soc_private->smart_qos_info->rt_wr_priority_clamp,
  1307. (uint32_t)soc_private->smart_qos_info->rt_wr_slope_factor);
  1308. rc = of_property_read_u32(of_node, "rt-wr-leaststressed-clamp-threshold",
  1309. &value);
  1310. if (rc) {
  1311. CAM_ERR(CAM_CPAS, "Invalid leaststressed clamp threshold rc %d", rc);
  1312. goto cleanup_clients;
  1313. }
  1314. soc_private->smart_qos_info->leaststressed_clamp_th = (uint8_t)value;
  1315. rc = of_property_read_u32(of_node, "rt-wr-moststressed-clamp-threshold",
  1316. &value);
  1317. if (rc) {
  1318. CAM_ERR(CAM_CPAS, "Invalid moststressed clamp threshold rc %d", rc);
  1319. goto cleanup_clients;
  1320. }
  1321. soc_private->smart_qos_info->moststressed_clamp_th = (uint8_t)value;
  1322. CAM_DBG(CAM_CPAS,
  1323. "leaststressed_clamp_th=%u, moststressed_clamp_th=%u",
  1324. (uint32_t)soc_private->smart_qos_info->leaststressed_clamp_th,
  1325. (uint32_t)soc_private->smart_qos_info->moststressed_clamp_th);
  1326. rc = of_property_read_u32(of_node, "rt-wr-highstress-indicator-threshold",
  1327. &value);
  1328. if (rc) {
  1329. CAM_ERR(CAM_CPAS, "Invalid highstress indicator threshold rc %d", rc);
  1330. goto cleanup_clients;
  1331. }
  1332. if (value > CAM_CPAS_MAX_STRESS_INDICATOR) {
  1333. CAM_ERR(CAM_UTIL, "Invalid highstress indicator threshold value %d", value);
  1334. rc = -EINVAL;
  1335. goto cleanup_clients;
  1336. } else
  1337. soc_private->smart_qos_info->highstress_indicator_th = (uint8_t)value;
  1338. rc = of_property_read_u32(of_node, "rt-wr-lowstress-indicator-threshold",
  1339. &value);
  1340. if (rc) {
  1341. CAM_ERR(CAM_CPAS, "Invalid lowstress indicator threshold rc %d", rc);
  1342. goto cleanup_clients;
  1343. }
  1344. if (value > CAM_CPAS_MAX_STRESS_INDICATOR) {
  1345. CAM_ERR(CAM_UTIL, "Invalid lowstress indicator threshold value %d", value);
  1346. rc = -EINVAL;
  1347. goto cleanup_clients;
  1348. } else
  1349. soc_private->smart_qos_info->lowstress_indicator_th = (uint8_t)value;
  1350. rc = of_property_read_u32(of_node, "rt-wr-bw-ratio-scale-factor",
  1351. &value);
  1352. if (rc) {
  1353. CAM_ERR(CAM_CPAS, "Invalid bw ratio scale factor rc %d", rc);
  1354. goto cleanup_clients;
  1355. }
  1356. soc_private->smart_qos_info->bw_ratio_scale_factor = (uint8_t)value;
  1357. CAM_DBG(CAM_CPAS,
  1358. "highstress_indicator_th=%u, lowstress_indicator_th=%u, scale factor=%u",
  1359. (uint32_t)soc_private->smart_qos_info->highstress_indicator_th,
  1360. (uint32_t)soc_private->smart_qos_info->lowstress_indicator_th,
  1361. (uint32_t)soc_private->smart_qos_info->bw_ratio_scale_factor);
  1362. } else {
  1363. CAM_DBG(CAM_CPAS, "SmartQoS not enabled, use static settings");
  1364. soc_private->smart_qos_info = NULL;
  1365. }
  1366. rc = of_property_read_u32(of_node, "enable-cam-drv", &cam_drv_en_mask_val);
  1367. if (!rc) {
  1368. if (cam_drv_en_mask_val & CAM_DDR_DRV)
  1369. soc_private->enable_cam_ddr_drv = true;
  1370. if (cam_drv_en_mask_val & CAM_CLK_DRV) {
  1371. if (!soc_private->enable_cam_ddr_drv) {
  1372. CAM_ERR(CAM_CPAS, "DDR DRV needs to be enabled for Clock DRV");
  1373. rc = -EPERM;
  1374. goto cleanup_clients;
  1375. }
  1376. soc_private->enable_cam_clk_drv = true;
  1377. rc = cam_soc_util_cesta_populate_crm_device();
  1378. if (rc) {
  1379. CAM_ERR(CAM_CPAS, "Failed to populate cam cesta crm device rc %d",
  1380. rc);
  1381. goto cleanup_clients;
  1382. }
  1383. }
  1384. }
  1385. CAM_DBG(CAM_CPAS, "enable_cam_ddr_drv %d enable_cam_clk_drv %d cam_drv_en_mask_val %d",
  1386. soc_private->enable_cam_ddr_drv, soc_private->enable_cam_clk_drv,
  1387. cam_drv_en_mask_val);
  1388. rc = cam_cpas_parse_node_tree(cpas_core, of_node, soc_private);
  1389. if (rc) {
  1390. CAM_ERR(CAM_CPAS, "Node tree parsing failed rc: %d", rc);
  1391. goto cleanup_tree;
  1392. }
  1393. /* If SmartQoS is enabled, we expect few tags in dtsi, validate */
  1394. if (soc_private->enable_smart_qos) {
  1395. int port_idx;
  1396. bool rt_port_exists = false;
  1397. if ((soc_private->smart_qos_info->num_rt_wr_nius == 0) ||
  1398. (soc_private->smart_qos_info->num_rt_wr_nius >
  1399. CAM_CPAS_MAX_RT_WR_NIU_NODES)) {
  1400. CAM_ERR(CAM_CPAS, "Invalid number of level1 nodes %d",
  1401. soc_private->smart_qos_info->num_rt_wr_nius);
  1402. rc = -EINVAL;
  1403. goto cleanup_tree;
  1404. }
  1405. for (port_idx = 0; port_idx < cpas_core->num_axi_ports;
  1406. port_idx++) {
  1407. CAM_DBG(CAM_CPAS, "[%d] : Port[%s] is_rt=%d",
  1408. port_idx, cpas_core->axi_port[port_idx].axi_port_name,
  1409. cpas_core->axi_port[port_idx].is_rt);
  1410. if (cpas_core->axi_port[port_idx].is_rt) {
  1411. rt_port_exists = true;
  1412. break;
  1413. }
  1414. }
  1415. if (!rt_port_exists) {
  1416. CAM_ERR(CAM_CPAS,
  1417. "RT AXI port not tagged, num ports %d",
  1418. cpas_core->num_axi_ports);
  1419. rc = -EINVAL;
  1420. goto cleanup_tree;
  1421. }
  1422. }
  1423. /* Optional rpmh bcm info */
  1424. count = of_property_count_u32_elems(of_node, "rpmh-bcm-info");
  1425. /*
  1426. * We expect count=5(CAM_RPMH_BCM_INFO_MAX) if valid rpmh bcm info
  1427. * is available.
  1428. * 0 - Total number of BCMs
  1429. * 1 - First BCM FE (front-end) register offset.
  1430. * These represent requested clk plan by sw
  1431. * 2 - First BCM BE (back-end) register offset.
  1432. * These represent actual clk plan at hw
  1433. * 3 - DDR BCM index
  1434. * 4 - MMNOC BCM index
  1435. */
  1436. if (count == CAM_RPMH_BCM_INFO_MAX) {
  1437. for (i = 0; i < count; i++) {
  1438. rc = of_property_read_u32_index(of_node,
  1439. "rpmh-bcm-info", i, &soc_private->rpmh_info[i]);
  1440. if (rc) {
  1441. CAM_ERR(CAM_CPAS,
  1442. "Incorrect rpmh info at %d, count=%d",
  1443. i, count);
  1444. break;
  1445. }
  1446. CAM_DBG(CAM_CPAS, "RPMH BCM Info [%d]=0x%x",
  1447. i, soc_private->rpmh_info[i]);
  1448. }
  1449. if (rc)
  1450. soc_private->rpmh_info[CAM_RPMH_NUMBER_OF_BCMS] = 0;
  1451. } else {
  1452. CAM_DBG(CAM_CPAS, "RPMH BCM info not available in DT, count=%d",
  1453. count);
  1454. }
  1455. /* check cache info */
  1456. rc = cam_cpas_parse_sys_cache_uids(of_node, soc_private);
  1457. if (rc)
  1458. goto cache_parse_fail;
  1459. return 0;
  1460. cache_parse_fail:
  1461. soc_private->rpmh_info[CAM_RPMH_NUMBER_OF_BCMS] = 0;
  1462. cleanup_tree:
  1463. cam_cpas_node_tree_cleanup(cpas_core, soc_private);
  1464. cleanup_clients:
  1465. cam_cpas_util_client_cleanup(cpas_hw);
  1466. return rc;
  1467. }
  1468. static int cam_cpas_soc_fill_irq_data(struct cam_hw_info *cpas_hw,
  1469. struct cam_hw_soc_info *soc_info, void **irq_data)
  1470. {
  1471. struct cam_cpas_private_soc *soc_private = soc_info->soc_private;
  1472. int i;
  1473. for (i = 0; i < soc_info->irq_count; i++) {
  1474. soc_private->irq_data[i].cpas_hw = cpas_hw;
  1475. if (!strcmp(soc_info->irq_name[i], "cpas_camnoc"))
  1476. soc_private->irq_data[i].camnoc_type = CAM_CAMNOC_HW_COMBINED;
  1477. else if (!strcmp(soc_info->irq_name[i], "cpas_camnoc_rt"))
  1478. soc_private->irq_data[i].camnoc_type = CAM_CAMNOC_HW_RT;
  1479. else if (!strcmp(soc_info->irq_name[i], "cpas_camnoc_nrt"))
  1480. soc_private->irq_data[i].camnoc_type = CAM_CAMNOC_HW_NRT;
  1481. else {
  1482. CAM_ERR(CAM_CPAS, "Unable to identify interrupt name: %s",
  1483. soc_info->irq_name[i]);
  1484. return -EINVAL;
  1485. }
  1486. irq_data[i] = &soc_private->irq_data[i];
  1487. }
  1488. return 0;
  1489. }
  1490. int cam_cpas_soc_init_resources(struct cam_hw_soc_info *soc_info,
  1491. irq_handler_t irq_handler, struct cam_hw_info *cpas_hw)
  1492. {
  1493. int rc = 0;
  1494. struct cam_cpas_private_soc *soc_private;
  1495. void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
  1496. rc = cam_soc_util_get_dt_properties(soc_info);
  1497. if (rc) {
  1498. CAM_ERR(CAM_CPAS, "failed in get_dt_properties, rc=%d", rc);
  1499. return rc;
  1500. }
  1501. if (soc_info->irq_count > 0 && !irq_handler) {
  1502. CAM_ERR(CAM_CPAS, "Invalid IRQ handler");
  1503. return -EINVAL;
  1504. }
  1505. soc_info->soc_private = kzalloc(sizeof(struct cam_cpas_private_soc),
  1506. GFP_KERNEL);
  1507. if (!soc_info->soc_private) {
  1508. CAM_ERR(CAM_CPAS, "Failed to allocate soc private");
  1509. return -ENOMEM;
  1510. }
  1511. soc_private = (struct cam_cpas_private_soc *)soc_info->soc_private;
  1512. rc = cam_cpas_get_custom_dt_info(cpas_hw, soc_info->pdev, soc_private);
  1513. if (rc) {
  1514. CAM_ERR(CAM_CPAS, "failed in get_custom_info, rc=%d", rc);
  1515. goto free_soc_private;
  1516. }
  1517. soc_private->irq_data = kcalloc(soc_info->irq_count, sizeof(struct cam_cpas_soc_irq_data),
  1518. GFP_KERNEL);
  1519. if (!soc_private->irq_data) {
  1520. CAM_ERR(CAM_CPAS, "Failed to allocate irq data");
  1521. rc = -ENOMEM;
  1522. goto free_soc_private;
  1523. }
  1524. rc = cam_cpas_soc_fill_irq_data(cpas_hw, soc_info, &(irq_data[0]));
  1525. if (rc) {
  1526. CAM_ERR(CAM_CPAS, "Failed to fill irq data rc=%d", rc);
  1527. goto free_irq_data;
  1528. }
  1529. soc_info->is_clk_drv_en = soc_private->enable_cam_clk_drv;
  1530. rc = cam_soc_util_request_platform_resource(soc_info, irq_handler, &(irq_data[0]));
  1531. if (rc) {
  1532. CAM_ERR(CAM_CPAS, "failed in request_platform_resource, rc=%d", rc);
  1533. goto free_irq_data;
  1534. }
  1535. rc = cam_soc_util_get_option_clk_by_name(soc_info, CAM_ICP_CLK_NAME,
  1536. &soc_private->icp_clk_index);
  1537. if (rc) {
  1538. CAM_DBG(CAM_CPAS, "ICP option clk get failed with rc %d", rc);
  1539. soc_private->icp_clk_index = -1;
  1540. rc = 0;
  1541. } else {
  1542. CAM_DBG(CAM_CPAS, "ICP option clk get success index %d",
  1543. soc_private->icp_clk_index);
  1544. }
  1545. if (soc_private->domain_id_info.domain_id_supported) {
  1546. rc = cam_cpas_get_domain_id_support_clks(soc_info->pdev->dev.of_node,
  1547. soc_info, soc_private);
  1548. if (rc)
  1549. goto release_res;
  1550. }
  1551. return rc;
  1552. release_res:
  1553. cam_soc_util_release_platform_resource(soc_info);
  1554. free_irq_data:
  1555. kfree(soc_private->irq_data);
  1556. free_soc_private:
  1557. kfree(soc_private->llcc_info);
  1558. kfree(soc_private->smart_qos_info);
  1559. kfree(soc_info->soc_private);
  1560. soc_info->soc_private = NULL;
  1561. return rc;
  1562. }
  1563. int cam_cpas_soc_deinit_resources(struct cam_hw_soc_info *soc_info)
  1564. {
  1565. int rc, i;
  1566. struct cam_cpas_private_soc *soc_private = soc_info->soc_private;
  1567. for (i = 0; i < soc_private->num_caches; i++)
  1568. llcc_slice_putd(soc_private->llcc_info[i].slic_desc);
  1569. if (soc_private->icp_clk_index != -1) {
  1570. rc = cam_soc_util_put_optional_clk(soc_info, soc_private->icp_clk_index);
  1571. if (rc)
  1572. CAM_ERR(CAM_CPAS, "Error Put optional clk failed rc=%d", rc);
  1573. }
  1574. kfree(soc_private->domain_id_info.domain_id_entries);
  1575. kfree(soc_private->domain_id_clks);
  1576. rc = cam_soc_util_release_platform_resource(soc_info);
  1577. if (rc)
  1578. CAM_ERR(CAM_CPAS, "release platform failed, rc=%d", rc);
  1579. kfree(soc_private->irq_data);
  1580. kfree(soc_private->llcc_info);
  1581. kfree(soc_private->smart_qos_info);
  1582. kfree(soc_info->soc_private);
  1583. soc_info->soc_private = NULL;
  1584. return rc;
  1585. }
  1586. int cam_cpas_soc_enable_resources(struct cam_hw_soc_info *soc_info,
  1587. enum cam_vote_level default_level)
  1588. {
  1589. struct cam_cpas_private_soc *soc_private = soc_info->soc_private;
  1590. int rc = 0;
  1591. /* set this everytime in order to support debugfs to disable clk drv between runs */
  1592. soc_info->is_clk_drv_en = soc_private->enable_cam_clk_drv;
  1593. rc = cam_soc_util_enable_platform_resource(soc_info, CAM_CLK_SW_CLIENT_IDX, true,
  1594. default_level, true);
  1595. if (rc)
  1596. CAM_ERR(CAM_CPAS, "enable platform resource failed, rc=%d", rc);
  1597. return rc;
  1598. }
  1599. int cam_cpas_soc_disable_resources(struct cam_hw_soc_info *soc_info,
  1600. bool disable_clocks, bool disable_irq)
  1601. {
  1602. int rc = 0;
  1603. rc = cam_soc_util_disable_platform_resource(soc_info, CAM_CLK_SW_CLIENT_IDX,
  1604. disable_clocks, disable_irq);
  1605. if (rc)
  1606. CAM_ERR(CAM_CPAS, "disable platform failed, rc=%d", rc);
  1607. return rc;
  1608. }
  1609. int cam_cpas_soc_disable_irq(struct cam_hw_soc_info *soc_info)
  1610. {
  1611. int rc = 0;
  1612. rc = cam_soc_util_irq_disable(soc_info);
  1613. if (rc)
  1614. CAM_ERR(CAM_CPAS, "disable irq failed, rc=%d", rc);
  1615. return rc;
  1616. }