cam_cpas_soc.c 47 KB

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