123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #include <linux/device.h>
- #include <linux/of.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/platform_device.h>
- #include <linux/slab.h>
- #include <dt-bindings/msm-camera.h>
- #include "cam_cpas_api.h"
- #include "cam_cpas_hw_intf.h"
- #include "cam_cpas_hw.h"
- #include "cam_cpas_soc.h"
- #include "cam_compat.h"
- static uint cpas_dump;
- module_param(cpas_dump, uint, 0644);
- #define CAM_ICP_CLK_NAME "cam_icp_clk"
- void cam_cpas_dump_tree_vote_info(struct cam_hw_info *cpas_hw,
- const struct cam_cpas_tree_node *tree_node,
- const char *identifier, int ddr_drv_idx, int cesta_drv_idx)
- {
- struct cam_cpas_private_soc *soc_private =
- (struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
- if ((cpas_dump & BIT(0)) == 0)
- return;
- if (cesta_drv_idx > CAM_CPAS_PORT_HLOS_DRV)
- CAM_INFO(CAM_PERF,
- "%s node:%s lvl:%d cesta_drv_idx:%d DRV BW camnoc[%llu %llu]",
- identifier, tree_node->node_name, tree_node->level_idx, cesta_drv_idx,
- tree_node->bw_info[cesta_drv_idx].drv_vote.high.camnoc,
- tree_node->bw_info[cesta_drv_idx].drv_vote.low.camnoc);
- else
- CAM_INFO(CAM_PERF,
- "%s node:%s lvl:%d cesta_drv_idx:%d HLOS BW camnoc[%llu]",
- identifier, tree_node->node_name, tree_node->level_idx, cesta_drv_idx,
- tree_node->bw_info[cesta_drv_idx].hlos_vote.camnoc);
- if (ddr_drv_idx > CAM_CPAS_PORT_HLOS_DRV)
- CAM_INFO(CAM_PERF,
- "%s node:%s lvl:%d ddr_drv_idx:%d DRV BW ab[%llu %llu] ib[%llu %llu]",
- identifier, tree_node->node_name, tree_node->level_idx, ddr_drv_idx,
- tree_node->bw_info[ddr_drv_idx].drv_vote.high.ab,
- tree_node->bw_info[ddr_drv_idx].drv_vote.low.ab,
- tree_node->bw_info[ddr_drv_idx].drv_vote.high.ib,
- tree_node->bw_info[ddr_drv_idx].drv_vote.low.ib);
- else
- CAM_INFO(CAM_PERF,
- "%s node:%s lvl:%d ddr_drv_idx:%d HLOS BW ab[%llu] ib[%llu]",
- identifier, tree_node->node_name, tree_node->level_idx, ddr_drv_idx,
- tree_node->bw_info[ddr_drv_idx].hlos_vote.ab,
- tree_node->bw_info[ddr_drv_idx].hlos_vote.ib);
- if (soc_private->enable_cam_ddr_drv) {
- int i;
- CAM_INFO(CAM_PERF,
- "%s node:%s lvl:%d drv_idx:%d cesta_drv_idx:%d ==== printing full node state",
- identifier, tree_node->node_name, tree_node->level_idx,
- ddr_drv_idx, cesta_drv_idx);
- for (i = 0; i < CAM_CPAS_MAX_DRV_PORTS; i++) {
- if (i == CAM_CPAS_PORT_HLOS_DRV)
- CAM_INFO(CAM_PERF,
- "idx[%d] HLOS camnoc[%llu], DDR ab[%llu] ib[%llu]",
- i,
- tree_node->bw_info[i].hlos_vote.camnoc,
- tree_node->bw_info[i].hlos_vote.ab,
- tree_node->bw_info[i].hlos_vote.ib);
- else
- CAM_INFO(CAM_PERF,
- "idx[%d] DRV camnoc[%llu %llu], DDR ab[%llu %llu] ib[%llu %llu]",
- i,
- tree_node->bw_info[i].drv_vote.high.camnoc,
- tree_node->bw_info[i].drv_vote.low.camnoc,
- tree_node->bw_info[i].drv_vote.high.ab,
- tree_node->bw_info[i].drv_vote.low.ab,
- tree_node->bw_info[i].drv_vote.high.ib,
- tree_node->bw_info[i].drv_vote.low.ib);
- }
- }
- }
- void cam_cpas_dump_full_tree_state(struct cam_hw_info *cpas_hw, const char *identifier)
- {
- int j;
- struct cam_cpas_private_soc *soc_private =
- (struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
- struct cam_cpas_tree_node *curr_node;
- if ((cpas_dump & BIT(1)) == 0)
- return;
- CAM_INFO(CAM_CPAS, "Dumping cpas tree full state start ============== %s", identifier);
- /* This will traverse through all nodes in the tree and print stats*/
- for (j = 0; j < CAM_CPAS_MAX_TREE_NODES; j++) {
- if (!soc_private->tree_node[j])
- continue;
- curr_node = soc_private->tree_node[j];
- if (soc_private->enable_cam_ddr_drv) {
- int i;
- CAM_INFO(CAM_PERF,
- "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",
- identifier, curr_node->node_name, curr_node->cell_idx,
- curr_node->level_idx,
- curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
- curr_node->axi_port_idx_arr[CAM_CPAS_PORT_DRV_0],
- curr_node->axi_port_idx_arr[CAM_CPAS_PORT_DRV_1],
- curr_node->axi_port_idx_arr[CAM_CPAS_PORT_DRV_2],
- curr_node->camnoc_axi_port_idx,
- curr_node->camnoc_max_needed,
- curr_node->bus_width_factor,
- curr_node->drv_voting_idx);
- for (i = 0; i < CAM_CPAS_MAX_DRV_PORTS; i++) {
- if (i == CAM_CPAS_PORT_HLOS_DRV)
- CAM_INFO(CAM_PERF,
- " idx[%d] HLOS camnoc[%llu], DDR ab[%llu] ib[%llu]",
- i,
- curr_node->bw_info[i].hlos_vote.camnoc,
- curr_node->bw_info[i].hlos_vote.ab,
- curr_node->bw_info[i].hlos_vote.ib);
- else
- CAM_INFO(CAM_PERF,
- " idx[%d] DRV camnoc[%llu %llu], DDR ab[%llu %llu] ib[%llu %llu]",
- i,
- curr_node->bw_info[i].drv_vote.high.camnoc,
- curr_node->bw_info[i].drv_vote.low.camnoc,
- curr_node->bw_info[i].drv_vote.high.ab,
- curr_node->bw_info[i].drv_vote.low.ab,
- curr_node->bw_info[i].drv_vote.high.ib,
- curr_node->bw_info[i].drv_vote.low.ib);
- }
- } else {
- CAM_INFO(CAM_CPAS,
- "[%s] Cell[%d] level[%d] PortIdx[%d][%d] camnoc_bw[%d %d %lld %lld] mnoc_bw[%lld %lld]",
- curr_node->node_name, curr_node->cell_idx,
- curr_node->level_idx,
- curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
- curr_node->camnoc_axi_port_idx,
- curr_node->camnoc_max_needed,
- curr_node->bus_width_factor,
- curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.camnoc,
- curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.camnoc *
- curr_node->bus_width_factor,
- curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.ab,
- curr_node->bw_info[CAM_CPAS_PORT_HLOS_DRV].hlos_vote.ib);
- }
- }
- CAM_INFO(CAM_CPAS, "Dumping cpas tree full state end ============== %s", identifier);
- }
- void cam_cpas_dump_axi_vote_info(
- const struct cam_cpas_client *cpas_client,
- const char *identifier,
- struct cam_axi_vote *axi_vote)
- {
- int i;
- if ((cpas_dump & BIT(0)) == 0)
- return;
- if (!axi_vote || (axi_vote->num_paths >
- CAM_CPAS_MAX_PATHS_PER_CLIENT)) {
- CAM_ERR(CAM_PERF, "Invalid num_paths %d",
- axi_vote ? axi_vote->num_paths : -1);
- return;
- }
- for (i = 0; i < axi_vote->num_paths; i++) {
- CAM_INFO(CAM_PERF,
- "Client [%s][%d] : [%s], Path=[%d] [%d], [%s], camnoc[%llu], mnoc_ab[%llu], mnoc_ib[%llu]",
- cpas_client->data.identifier, cpas_client->data.cell_index,
- identifier,
- axi_vote->axi_path[i].path_data_type,
- axi_vote->axi_path[i].transac_type,
- cam_cpas_axi_util_drv_vote_lvl_to_string(axi_vote->axi_path[i].vote_level),
- axi_vote->axi_path[i].camnoc_bw,
- axi_vote->axi_path[i].mnoc_ab_bw,
- axi_vote->axi_path[i].mnoc_ib_bw);
- }
- }
- void cam_cpas_util_debug_parse_data(
- struct cam_cpas_private_soc *soc_private)
- {
- int i, j;
- struct cam_cpas_tree_node *curr_node = NULL;
- if ((cpas_dump & BIT(0)) == 0)
- return;
- for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
- if (!soc_private->tree_node[i])
- break;
- curr_node = soc_private->tree_node[i];
- CAM_INFO(CAM_CPAS,
- "NODE cell_idx: %d, level: %d, name: %s, axi_port_idx: %d, merge_type: %d, parent_name: %s camnoc_max_needed: %d",
- curr_node->cell_idx, curr_node->level_idx,
- curr_node->node_name, curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
- curr_node->merge_type, curr_node->parent_node ?
- curr_node->parent_node->node_name : "no parent",
- curr_node->camnoc_max_needed);
- if (curr_node->level_idx)
- continue;
- CAM_INFO(CAM_CPAS, "path_type: %d, transac_type: %s drv_voting_idx:%d",
- curr_node->path_data_type,
- cam_cpas_axi_util_trans_type_to_string(
- curr_node->path_trans_type), curr_node->drv_voting_idx);
- for (j = 0; j < CAM_CPAS_PATH_DATA_MAX; j++) {
- if (curr_node->constituent_paths[j])
- CAM_INFO(CAM_CPAS, "Constituent path: %d", j);
- }
- }
- CAM_INFO(CAM_CPAS, "NUMBER OF NODES PARSED: %d", i);
- }
- int cam_cpas_node_tree_cleanup(struct cam_cpas *cpas_core,
- struct cam_cpas_private_soc *soc_private)
- {
- int i = 0;
- for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
- if (soc_private->tree_node[i]) {
- kfree(soc_private->tree_node[i]->bw_info);
- kfree(soc_private->tree_node[i]->axi_port_idx_arr);
- soc_private->tree_node[i]->bw_info = NULL;
- soc_private->tree_node[i]->axi_port_idx_arr = NULL;
- of_node_put(soc_private->tree_node[i]->tree_dev_node);
- kfree(soc_private->tree_node[i]);
- soc_private->tree_node[i] = NULL;
- }
- }
- for (i = 0; i < CAM_CPAS_MAX_TREE_LEVELS; i++) {
- if (soc_private->level_node[i]) {
- of_node_put(soc_private->level_node[i]);
- soc_private->level_node[i] = NULL;
- }
- }
- if (soc_private->camera_bus_node) {
- of_node_put(soc_private->camera_bus_node);
- soc_private->camera_bus_node = NULL;
- }
- mutex_destroy(&cpas_core->tree_lock);
- return 0;
- }
- static int cam_cpas_util_path_type_to_idx(uint32_t *path_data_type)
- {
- if (*path_data_type >= CAM_CPAS_PATH_DATA_CONSO_OFFSET) {
- *path_data_type = CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT +
- (*path_data_type % CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT);
- }
- else {
- *path_data_type %= CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT;
- }
- if (*path_data_type >= CAM_CPAS_PATH_DATA_MAX) {
- CAM_ERR(CAM_CPAS, "index Invalid: %u", *path_data_type);
- return -EINVAL;
- }
- return 0;
- }
- static int cam_cpas_update_camnoc_node(struct cam_cpas *cpas_core,
- struct device_node *curr_node,
- struct cam_cpas_tree_node *cpas_node_ptr,
- int *camnoc_idx)
- {
- struct device_node *camnoc_node;
- int rc;
- camnoc_node = of_find_node_by_name(curr_node,
- "qcom,axi-port-camnoc");
- if (camnoc_node) {
- if (*camnoc_idx >=
- CAM_CPAS_MAX_AXI_PORTS) {
- CAM_ERR(CAM_CPAS, "CAMNOC axi index overshoot %d",
- *camnoc_idx);
- return -EINVAL;
- }
- cpas_core->camnoc_axi_port[*camnoc_idx]
- .axi_port_node = camnoc_node;
- rc = of_property_read_string(
- curr_node,
- "qcom,axi-port-name",
- &cpas_core->camnoc_axi_port[*camnoc_idx]
- .axi_port_name);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "fail to read camnoc-port-name rc=%d",
- rc);
- return rc;
- }
- cpas_node_ptr->camnoc_axi_port_idx = *camnoc_idx;
- cpas_core->num_camnoc_axi_ports++;
- (*camnoc_idx)++;
- }
- return 0;
- }
- static int cam_cpas_parse_mnoc_node(struct cam_cpas *cpas_core,
- struct cam_cpas_private_soc *soc_private, struct cam_cpas_tree_node *curr_node_ptr,
- struct device_node *mnoc_node, int *mnoc_idx)
- {
- int rc = 0, count, i;
- bool ib_voting_needed = false, is_rt_port = false;
- struct of_phandle_args src_args = {0}, dst_args = {0};
- ib_voting_needed = of_property_read_bool(curr_node_ptr->tree_dev_node,
- "ib-bw-voting-needed");
- is_rt_port = of_property_read_bool(curr_node_ptr->tree_dev_node, "rt-axi-port");
- if (soc_private->bus_icc_based) {
- count = of_property_count_strings(mnoc_node, "interconnect-names");
- if (count <= 0) {
- CAM_ERR(CAM_CPAS, "no interconnect-names found");
- return -EINVAL;
- } else if (count > CAM_CPAS_MAX_DRV_PORTS) {
- CAM_ERR(CAM_CPAS, "Number of interconnects %d greater than max ports %d",
- count, CAM_CPAS_MAX_DRV_PORTS);
- return -EINVAL;
- }
- for (i = 0; i < count; i++) {
- if ((i > 0) && !soc_private->enable_cam_ddr_drv)
- break;
- if (*mnoc_idx >= CAM_CPAS_MAX_AXI_PORTS) {
- CAM_ERR(CAM_CPAS, "Invalid mnoc index: %d", *mnoc_idx);
- return -EINVAL;
- }
- cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
- rc = of_property_read_string_index(mnoc_node, "interconnect-names", i,
- &cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed to read interconnect-names rc=%d", rc);
- return rc;
- }
- rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
- "#interconnect-cells", (2 * i), &src_args);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "failed to read axi bus src info rc=%d",
- rc);
- return -EINVAL;
- }
- of_node_put(src_args.np);
- if (src_args.args_count != 1) {
- CAM_ERR(CAM_CPAS, "Invalid number of axi src args: %d",
- src_args.args_count);
- return -EINVAL;
- }
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id =
- src_args.args[0];
- rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
- "#interconnect-cells", ((2 * i) + 1), &dst_args);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed to read axi bus dst info rc=%d", rc);
- return -EINVAL;
- }
- of_node_put(dst_args.np);
- if (dst_args.args_count != 1) {
- CAM_ERR(CAM_CPAS, "Invalid number of axi dst args: %d",
- dst_args.args_count);
- return -EINVAL;
- }
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id =
- dst_args.args[0];
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.num_usecases = 2;
- cpas_core->axi_port[*mnoc_idx].axi_port_name =
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
- cpas_core->axi_port[*mnoc_idx].drv_idx = i;
- if (i > CAM_CPAS_PORT_HLOS_DRV) {
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.is_drv_port =
- true;
- cpas_core->axi_port[*mnoc_idx].curr_bw.vote_type =
- CAM_CPAS_VOTE_TYPE_DRV;
- cpas_core->axi_port[*mnoc_idx].applied_bw.vote_type =
- CAM_CPAS_VOTE_TYPE_DRV;
- cpas_core->axi_port[*mnoc_idx].cam_rsc_dev =
- cam_cpas_get_rsc_dev_for_drv(i - CAM_CPAS_PORT_DRV_0);
- if (!cpas_core->axi_port[*mnoc_idx].cam_rsc_dev) {
- CAM_ERR(CAM_CPAS,
- "Port[%s][%d] Failed to get rsc device drv_idx:%d",
- cpas_core->axi_port[*mnoc_idx].axi_port_name,
- *mnoc_idx, i);
- rc = -ENODEV;
- goto err;
- }
- }
- /*
- * The indexes of axi_port_idx_arr map to drv_voting_idx,
- * with 0 pointing to hlos drv bus ID
- */
- curr_node_ptr->axi_port_idx_arr[i] = *mnoc_idx;
- cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
- cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
- CAM_DBG(CAM_PERF, "Adding Bus Client=[%s] : src=%d, dst=%d mnoc_idx:%d",
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name,
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id,
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id,
- *mnoc_idx);
- (*mnoc_idx)++;
- cpas_core->num_axi_ports++;
- }
- } else {
- if (soc_private->enable_cam_ddr_drv) {
- CAM_ERR(CAM_CPAS, "DRV not supported for old bus scaling clients");
- return -EPERM;
- }
- cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
- rc = of_property_read_string(curr_node_ptr->tree_dev_node, "qcom,axi-port-name",
- &cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "failed to read mnoc-port-name rc=%d",
- rc);
- return rc;
- }
- cpas_core->axi_port[*mnoc_idx].axi_port_name =
- cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
- curr_node_ptr->axi_port_idx_arr[0] = *mnoc_idx;
- cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
- cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
- (*mnoc_idx)++;
- cpas_core->num_axi_ports++;
- }
- err:
- return rc;
- }
- static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
- struct device_node *of_node, struct cam_cpas_private_soc *soc_private)
- {
- struct device_node *camera_bus_node;
- struct device_node *level_node;
- struct device_node *curr_node;
- struct device_node *parent_node;
- struct device_node *mnoc_node;
- int mnoc_idx = 0, camnoc_idx = 0, level_idx = 0;
- uint32_t path_idx;
- bool camnoc_max_needed = false;
- struct cam_cpas_tree_node *curr_node_ptr = NULL;
- struct cam_cpas_client *curr_client = NULL;
- const char *client_name = NULL;
- uint32_t client_idx = 0, cell_idx = 0;
- uint8_t niu_idx = 0;
- int rc = 0, count = 0, i, j, num_drv_ports;
- camera_bus_node = of_get_child_by_name(of_node, "camera-bus-nodes");
- if (!camera_bus_node) {
- CAM_ERR(CAM_CPAS, "Camera Bus node not found in cpas DT node");
- return -EINVAL;
- }
- soc_private->camera_bus_node = camera_bus_node;
- for_each_available_child_of_node(camera_bus_node, level_node) {
- rc = of_property_read_u32(level_node, "level-index", &level_idx);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Error reading level idx rc: %d", rc);
- return rc;
- }
- if (level_idx >= CAM_CPAS_MAX_TREE_LEVELS) {
- CAM_ERR(CAM_CPAS, "Invalid level idx: %d", level_idx);
- return -EINVAL;
- }
- soc_private->level_node[level_idx] = level_node;
- }
- if (soc_private->enable_smart_qos)
- soc_private->smart_qos_info->num_rt_wr_nius = 0;
- if (soc_private->enable_cam_ddr_drv)
- num_drv_ports = CAM_CPAS_MAX_DRV_PORTS;
- else
- num_drv_ports = 1;
- for (level_idx = (CAM_CPAS_MAX_TREE_LEVELS - 1); level_idx >= 0;
- level_idx--) {
- level_node = soc_private->level_node[level_idx];
- if (!level_node)
- continue;
- CAM_DBG(CAM_CPAS, "Parsing level %d nodes", level_idx);
- camnoc_max_needed = of_property_read_bool(level_node, "camnoc-max-needed");
- for_each_available_child_of_node(level_node, curr_node) {
- curr_node_ptr = kzalloc(sizeof(struct cam_cpas_tree_node), GFP_KERNEL);
- if (!curr_node_ptr)
- return -ENOMEM;
- curr_node_ptr->tree_dev_node = curr_node;
- rc = of_property_read_u32(curr_node, "cell-index",
- &curr_node_ptr->cell_idx);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Node index not found");
- return rc;
- }
- CAM_DBG(CAM_CPAS, "Parsing Node with cell index %d",
- curr_node_ptr->cell_idx);
- if (curr_node_ptr->cell_idx >=
- CAM_CPAS_MAX_TREE_NODES) {
- CAM_ERR(CAM_CPAS, "Invalid cell idx: %d", curr_node_ptr->cell_idx);
- return -EINVAL;
- }
- soc_private->tree_node[curr_node_ptr->cell_idx] = curr_node_ptr;
- curr_node_ptr->level_idx = level_idx;
- rc = of_property_read_string(curr_node, "node-name",
- &curr_node_ptr->node_name);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed to read node-name rc=%d", rc);
- return rc;
- }
- curr_node_ptr->bw_info = kzalloc((sizeof(struct cam_cpas_axi_bw_info) *
- num_drv_ports), GFP_KERNEL);
- if (!curr_node_ptr->bw_info) {
- CAM_ERR(CAM_CPAS, "Failed in allocating memory for bw info");
- return -ENOMEM;
- }
- curr_node_ptr->axi_port_idx_arr = kzalloc((sizeof(int) * num_drv_ports),
- GFP_KERNEL);
- if (!curr_node_ptr->axi_port_idx_arr) {
- CAM_ERR(CAM_CPAS, "Failed in allocating memory for port indices");
- return -ENOMEM;
- }
- if (soc_private->enable_smart_qos && (level_idx == 1) &&
- of_property_read_bool(curr_node, "rt-wr-niu")) {
- rc = of_property_read_u32(curr_node, "priority-lut-low-offset",
- &curr_node_ptr->pri_lut_low_offset);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid priority low offset rc %d", rc);
- return rc;
- }
- rc = of_property_read_u32(curr_node, "priority-lut-high-offset",
- &curr_node_ptr->pri_lut_high_offset);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid priority high offset rc %d", rc);
- return rc;
- }
- rc = of_property_read_u32(curr_node, "niu-size",
- &curr_node_ptr->niu_size);
- if (rc || !curr_node_ptr->niu_size) {
- CAM_ERR(CAM_CPAS, "Invalid niu size rc %d", rc);
- return rc;
- }
- niu_idx = soc_private->smart_qos_info->num_rt_wr_nius;
- if (niu_idx >= CAM_CPAS_MAX_RT_WR_NIU_NODES) {
- CAM_ERR(CAM_CPAS, "Invalid number of level1 nodes %d",
- soc_private->smart_qos_info->num_rt_wr_nius);
- return -EINVAL;
- }
- soc_private->smart_qos_info->rt_wr_niu_node[niu_idx] =
- curr_node_ptr;
- soc_private->smart_qos_info->num_rt_wr_nius++;
- CAM_DBG(CAM_CPAS,
- "level1[%d] : Node %s idx %d priority offset 0x%x, NIU size %dKB",
- niu_idx, curr_node_ptr->node_name, curr_node_ptr->cell_idx,
- curr_node_ptr->pri_lut_low_offset, curr_node_ptr->niu_size);
- }
- curr_node_ptr->camnoc_max_needed = camnoc_max_needed;
- rc = of_property_read_u32(curr_node, "bus-width-factor",
- &curr_node_ptr->bus_width_factor);
- if (rc)
- curr_node_ptr->bus_width_factor = 1;
- rc = of_property_read_u32(curr_node, "traffic-merge-type",
- &curr_node_ptr->merge_type);
- if (rc)
- curr_node_ptr->merge_type = CAM_CPAS_TRAFFIC_MERGE_SUM;
- for (j = 0; j < num_drv_ports; j++)
- curr_node_ptr->axi_port_idx_arr[j] = -1;
- mnoc_node = of_get_child_by_name(curr_node, "qcom,axi-port-mnoc");
- if (mnoc_node) {
- rc = cam_cpas_parse_mnoc_node(cpas_core, soc_private, curr_node_ptr,
- mnoc_node, &mnoc_idx);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed to parse mnoc node info rc=%d",
- rc);
- return rc;
- }
- }
- if (!soc_private->control_camnoc_axi_clk) {
- rc = cam_cpas_update_camnoc_node(cpas_core, curr_node,
- curr_node_ptr, &camnoc_idx);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed to parse camnoc node info rc=%d",
- rc);
- return rc;
- }
- }
- rc = of_property_read_string(curr_node, "client-name", &client_name);
- if (!rc) {
- rc = of_property_read_u32(curr_node, "traffic-data",
- &curr_node_ptr->path_data_type);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "Path Data type not found");
- return rc;
- }
- rc = cam_cpas_util_path_type_to_idx(&curr_node_ptr->path_data_type);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Incorrect path type for client: %s",
- client_name);
- return rc;
- }
- rc = of_property_read_u32(curr_node, "traffic-transaction-type",
- &curr_node_ptr->path_trans_type);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Path Transac type not found");
- return rc;
- }
- if (curr_node_ptr->path_trans_type >= CAM_CPAS_TRANSACTION_MAX) {
- CAM_ERR(CAM_CPAS, "Invalid transac type: %d",
- curr_node_ptr->path_trans_type);
- return -EINVAL;
- }
- count = of_property_count_u32_elems(curr_node, "constituent-paths");
- for (i = 0; i < count; i++) {
- rc = of_property_read_u32_index(curr_node,
- "constituent-paths", i, &path_idx);
- if (rc) {
- CAM_ERR(CAM_CPAS, "No constituent path at %d", i);
- return rc;
- }
- rc = cam_cpas_util_path_type_to_idx(&path_idx);
- if (rc)
- return rc;
- curr_node_ptr->constituent_paths[path_idx] = true;
- }
- rc = cam_common_util_get_string_index(soc_private->client_name,
- soc_private->num_clients, client_name, &client_idx);
- if (rc) {
- CAM_ERR(CAM_CPAS, "client name not found in list: %s",
- client_name);
- return rc;
- }
- if (client_idx >= CAM_CPAS_MAX_CLIENTS)
- return -EINVAL;
- curr_client = cpas_core->cpas_client[client_idx];
- curr_client->tree_node_valid = true;
- curr_client->tree_node[curr_node_ptr->path_data_type]
- [curr_node_ptr->path_trans_type] = curr_node_ptr;
- if (soc_private->enable_cam_ddr_drv) {
- rc = of_property_read_u32(curr_node, "drv-voting-index",
- &curr_node_ptr->drv_voting_idx);
- if (rc)
- curr_node_ptr->merge_type = CAM_CPAS_PORT_HLOS_DRV;
- if (curr_node_ptr->drv_voting_idx == CAM_CPAS_PORT_DRV_DYN)
- curr_client->is_drv_dyn = true;
- if (curr_client->is_drv_dyn &&
- (curr_node_ptr->drv_voting_idx !=
- CAM_CPAS_PORT_DRV_DYN))
- CAM_ERR(CAM_CPAS,
- "Invalid config for drv dyn client: %s drv_idx: %d",
- client_name, curr_node_ptr->drv_voting_idx);
- }
- CAM_DBG(CAM_CPAS,
- "Node Added: Client[%s] DataType[%d] TransType[%d] DRV idx[%d]",
- client_name,
- curr_node_ptr->path_data_type,
- curr_node_ptr->path_trans_type,
- curr_node_ptr->drv_voting_idx);
- }
- if (soc_private->enable_cam_ddr_drv)
- for (j = CAM_CPAS_PORT_DRV_0; j < num_drv_ports; j++)
- curr_node_ptr->bw_info[j].vote_type =
- CAM_CPAS_VOTE_TYPE_DRV;
- parent_node = of_parse_phandle(curr_node, "parent-node", 0);
- if (parent_node) {
- of_property_read_u32(parent_node, "cell-index", &cell_idx);
- curr_node_ptr->parent_node = soc_private->tree_node[cell_idx];
- } else {
- CAM_DBG(CAM_CPAS, "no parent node at this level");
- }
- }
- }
- mutex_init(&cpas_core->tree_lock);
- cam_cpas_util_debug_parse_data(soc_private);
- return 0;
- }
- int cam_cpas_get_hw_features(struct platform_device *pdev,
- struct cam_cpas_private_soc *soc_private)
- {
- struct device_node *of_node;
- void *fuse;
- uint32_t fuse_addr, fuse_mask, fuse_shift;
- uint32_t val = 0, fuse_val = 0, feature;
- uint32_t enable_type = 0, hw_map = 0;
- int count = 0, i = 0, j = 0, num_feature = 0, num_fuse = 0;
- struct cam_cpas_feature_info *feature_info;
- of_node = pdev->dev.of_node;
- count = of_property_count_u32_elems(of_node, "cam_hw_fuse");
- CAM_DBG(CAM_CPAS, "fuse info elements count %d", count);
- if (count <= 0) {
- goto end;
- } else if (count%5 != 0) {
- CAM_INFO(CAM_CPAS, "fuse entries should be multiple of 5 %d",
- count);
- goto end;
- }
- for (i = 0; (i + 5) <= count; i = i + 5) {
- of_property_read_u32_index(of_node, "cam_hw_fuse", i,
- &feature);
- of_property_read_u32_index(of_node, "cam_hw_fuse", i + 1,
- &fuse_addr);
- of_property_read_u32_index(of_node, "cam_hw_fuse", i + 2,
- &fuse_mask);
- of_property_read_u32_index(of_node, "cam_hw_fuse", i + 3,
- &enable_type);
- of_property_read_u32_index(of_node, "cam_hw_fuse", i + 4,
- &hw_map);
- val = ffs(fuse_mask);
- if (val == 0) {
- CAM_ERR(CAM_CPAS, "fuse_mask not valid 0x%x",
- fuse_mask);
- fuse_shift = 0;
- } else {
- fuse_shift = val - 1;
- }
- CAM_INFO(CAM_CPAS,
- "feature 0x%x addr 0x%x, mask 0x%x, shift 0x%x type 0x%x hw_map 0x%x",
- feature, fuse_addr, fuse_mask, fuse_shift, enable_type,
- hw_map);
- fuse = ioremap(fuse_addr, 4);
- if (fuse) {
- fuse_val = cam_io_r(fuse);
- for (j = 0; (j < num_fuse) && (j < CAM_CPAS_FUSES_MAX);
- j++) {
- if (soc_private->fuse_info.fuse_val[j].fuse_id
- == fuse_addr)
- break;
- }
- if (j >= CAM_CPAS_FUSES_MAX) {
- CAM_ERR(CAM_CPAS,
- "fuse_info array overflow! %d", j);
- goto end;
- }
- if (j == num_fuse) {
- soc_private->fuse_info.fuse_val[j].fuse_id =
- fuse_addr;
- soc_private->fuse_info.fuse_val[j].fuse_val =
- fuse_val;
- CAM_INFO(CAM_CPAS,
- "fuse_addr 0x%x, fuse_val %x",
- fuse_addr, fuse_val);
- num_fuse++;
- }
- } else {
- /* if fuse ioremap is failed, disable the feature */
- CAM_ERR(CAM_CPAS,
- "fuse register io remap failed fuse_addr:0x%x feature0x%x ",
- fuse_addr, feature);
- if (enable_type == CAM_CPAS_FEATURE_TYPE_ENABLE ||
- enable_type == CAM_CPAS_FEATURE_TYPE_DISABLE)
- fuse_val = (enable_type) ? ~fuse_mask :
- fuse_mask;
- else
- fuse_val = 0;
- }
- if (num_feature >= CAM_CPAS_MAX_FUSE_FEATURE) {
- CAM_ERR(CAM_CPAS, "feature_info array overflow %d",
- num_feature);
- goto end;
- }
- soc_private->feature_info[num_feature].feature =
- feature;
- soc_private->feature_info[num_feature].hw_map = hw_map;
- soc_private->feature_info[num_feature].type = enable_type;
- feature_info = &soc_private->feature_info[num_feature];
- if (enable_type != CAM_CPAS_FEATURE_TYPE_VALUE) {
- if (enable_type == CAM_CPAS_FEATURE_TYPE_ENABLE) {
- /*
- * fuse is for enable feature
- * if fust bit is set means feature is enabled
- * or HW is enabled
- */
- if (fuse_val & fuse_mask)
- feature_info->enable = true;
- else
- feature_info->enable = false;
- } else if (enable_type ==
- CAM_CPAS_FEATURE_TYPE_DISABLE){
- /*
- * fuse is for disable feature
- * if fust bit is set means feature is disabled
- * or HW is disabled
- */
- if (fuse_val & fuse_mask)
- feature_info->enable = false;
- else
- feature_info->enable = true;
- } else {
- CAM_ERR(CAM_CPAS,
- "Feature type not valid, type: %d",
- enable_type);
- goto end;
- }
- CAM_INFO(CAM_CPAS,
- "feature 0x%x enable=%d hw_map=0x%x",
- feature_info->feature, feature_info->enable,
- feature_info->hw_map);
- } else {
- feature_info->value =
- (fuse_val & fuse_mask) >> fuse_shift;
- CAM_INFO(CAM_CPAS,
- "feature 0x%x value=0x%x hw_map=0x%x",
- feature_info->feature, feature_info->value,
- feature_info->hw_map);
- }
- num_feature++;
- iounmap(fuse);
- }
- end:
- soc_private->fuse_info.num_fuses = num_fuse;
- soc_private->num_feature_info = num_feature;
- return 0;
- }
- static inline enum cam_sys_cache_config_types cam_cpas_find_type_from_string(
- const char *cache_name)
- {
- if (strcmp(cache_name, "small-1") == 0)
- return CAM_LLCC_SMALL_1;
- else if (strcmp(cache_name, "small-2") == 0)
- return CAM_LLCC_SMALL_2;
- else if (strcmp(cache_name, "large-1") == 0)
- return CAM_LLCC_LARGE_1;
- else if (strcmp(cache_name, "large-2") == 0)
- return CAM_LLCC_LARGE_2;
- else if (strcmp(cache_name, "large-3") == 0)
- return CAM_LLCC_LARGE_3;
- else if (strcmp(cache_name, "large-4") == 0)
- return CAM_LLCC_LARGE_4;
- else
- return CAM_LLCC_MAX;
- }
- static int cam_cpas_parse_sys_cache_uids(
- struct device_node *of_node,
- struct cam_cpas_private_soc *soc_private)
- {
- enum cam_sys_cache_config_types type = CAM_LLCC_MAX;
- int num_caches, i, rc;
- uint32_t scid;
- soc_private->llcc_info = NULL;
- soc_private->num_caches = 0;
- num_caches = of_property_count_strings(of_node, "sys-cache-names");
- if (num_caches <= 0) {
- CAM_DBG(CAM_CPAS, "no cache-names found");
- return 0;
- }
- if (num_caches > CAM_LLCC_MAX) {
- CAM_ERR(CAM_CPAS,
- "invalid number of cache-names found: 0x%x",
- num_caches);
- return -EINVAL;
- }
- soc_private->llcc_info = kcalloc(num_caches,
- sizeof(struct cam_sys_cache_info), GFP_KERNEL);
- if (!soc_private->llcc_info)
- return -ENOMEM;
- for (i = 0; i < num_caches; i++) {
- rc = of_property_read_string_index(of_node, "sys-cache-names", i,
- &soc_private->llcc_info[i].name);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed to read cache-names at %d", i);
- goto end;
- }
- type = cam_cpas_find_type_from_string(
- soc_private->llcc_info[i].name);
- if (type == CAM_LLCC_MAX) {
- CAM_ERR(CAM_CPAS, "Unsupported cache found: %s",
- soc_private->llcc_info[i].name);
- rc = -EINVAL;
- goto end;
- }
- soc_private->llcc_info[i].type = type;
- rc = of_property_read_u32_index(of_node,
- "sys-cache-uids", i,
- &soc_private->llcc_info[i].uid);
- if (rc < 0) {
- CAM_ERR(CAM_CPAS,
- "unable to read sys cache uid at index %d", i);
- goto end;
- }
- soc_private->llcc_info[i].slic_desc =
- llcc_slice_getd(soc_private->llcc_info[i].uid);
- if (IS_ERR_OR_NULL(soc_private->llcc_info[i].slic_desc)) {
- CAM_ERR(CAM_CPAS,
- "Failed to get slice desc for uid %u",
- soc_private->llcc_info[i].uid);
- rc = -EINVAL;
- goto end;
- }
- scid = llcc_get_slice_id(soc_private->llcc_info[i].slic_desc);
- soc_private->llcc_info[i].scid = scid;
- soc_private->llcc_info[i].size =
- llcc_get_slice_size(soc_private->llcc_info[i].slic_desc);
- soc_private->llcc_info[i].staling_distance = 0;
- soc_private->llcc_info[i].mode = CAM_LLCC_STALING_MODE_CAPACITY;
- soc_private->llcc_info[i].op_type = CAM_LLCC_NOTIFY_STALING_EVICT;
- soc_private->num_caches++;
- CAM_DBG(CAM_CPAS,
- "Cache: %s uid: %u scid: %d size: %zukb",
- soc_private->llcc_info[i].name,
- soc_private->llcc_info[i].uid, scid,
- soc_private->llcc_info[i].size);
- }
- return 0;
- end:
- kfree(soc_private->llcc_info);
- soc_private->llcc_info = NULL;
- return rc;
- }
- #ifdef CONFIG_DOMAIN_ID_SECURE_CAMERA
- static int cam_cpas_parse_domain_id_mapping(struct device_node *of_node,
- struct cam_cpas_private_soc *soc_private)
- {
- int count, i, rc = 0;
- soc_private->domain_id_info.num_domain_ids = 0;
- soc_private->domain_id_info.domain_id_supported = false;
- soc_private->domain_id_info.domain_id_entries = NULL;
- count = of_property_count_u32_elems(of_node, "domain-id");
- if (count <= 0) {
- CAM_DBG(CAM_CPAS, "No domain-id mapping found, count: %d", count);
- return rc;
- }
- /* This property will always be specified in pairs */
- if (count % 2) {
- CAM_ERR(CAM_CPAS,
- "Mismatch in domain-id mapping, found %d number of entries", count);
- rc = -EINVAL;
- goto err;
- }
- soc_private->domain_id_info.num_domain_ids = count / 2;
- if (soc_private->domain_id_info.num_domain_ids > CAM_CPAS_DOMAIN_ID_MAX) {
- CAM_ERR(CAM_CPAS,
- "Number of domain id types: %u more than supported: %d",
- soc_private->domain_id_info.num_domain_ids, CAM_CPAS_DOMAIN_ID_MAX);
- rc = -EINVAL;
- goto err;
- }
- soc_private->domain_id_info.domain_id_entries =
- kcalloc(soc_private->domain_id_info.num_domain_ids,
- sizeof(struct cam_cpas_domain_id_mapping), GFP_KERNEL);
- if (!soc_private->domain_id_info.domain_id_entries) {
- CAM_ERR(CAM_CPAS,
- "Error allocating memory for %u domain-id mapping(s)",
- soc_private->domain_id_info.num_domain_ids);
- rc = -ENOMEM;
- goto err;
- }
- for (i = 0; i < soc_private->domain_id_info.num_domain_ids; i++) {
- struct cam_cpas_domain_id_mapping *domain_id_entry =
- &soc_private->domain_id_info.domain_id_entries[i];
- rc = of_property_read_u32_index(of_node, "domain-id",
- (i * 2), &domain_id_entry->domain_type);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Error reading domain-id type entry at pos %d", i);
- rc = -EINVAL;
- goto err;
- }
- if (domain_id_entry->domain_type > CAM_CPAS_SECURE_DOMAIN) {
- CAM_ERR(CAM_CPAS, "Unexpected domain id type: %u",
- domain_id_entry->domain_type);
- rc = -EINVAL;
- goto err;
- }
- rc = of_property_read_u32_index(of_node, "domain-id",
- ((i * 2) + 1), &domain_id_entry->mapping_id);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Error reading domain-id mapping id at pos %d", i);
- rc = -EINVAL;
- goto err;
- }
- CAM_DBG(CAM_CPAS, "Domain-id type: %u, mapping: %u at pos: %d",
- domain_id_entry->domain_type, domain_id_entry->mapping_id, i);
- }
- soc_private->domain_id_info.domain_id_supported = true;
- return rc;
- err:
- soc_private->domain_id_info.num_domain_ids = 0;
- kfree(soc_private->domain_id_info.domain_id_entries);
- soc_private->domain_id_info.domain_id_entries = NULL;
- return rc;
- }
- #endif
- static int cam_cpas_get_domain_id_support_clks(struct device_node *of_node,
- struct cam_hw_soc_info *soc_info, struct cam_cpas_private_soc *soc_private)
- {
- int rc = 0, count, i;
- struct cam_cpas_domain_id_support_clks *domain_id_clks;
- soc_private->domain_id_clks = kzalloc(sizeof(struct cam_cpas_domain_id_support_clks),
- GFP_KERNEL);
- if (!soc_private->domain_id_clks) {
- CAM_ERR(CAM_CPAS, "Failed in allocating memory for domain_id_clk");
- return -ENOMEM;
- }
- domain_id_clks = soc_private->domain_id_clks;
- count = of_property_count_strings(of_node, "domain-id-support-clks");
- CAM_DBG(CAM_CPAS, "Domain-id clk count: %d", count);
- if (count > CAM_SOC_MAX_OPT_CLK) {
- CAM_ERR(CAM_CPAS, "Invalid cnt of clocks, count: %d", count);
- rc = -EINVAL;
- goto err;
- }
- if (count <= 0) {
- CAM_ERR(CAM_CPAS, "No domain-id clk found");
- rc = -EINVAL;
- goto err;
- }
- domain_id_clks->number_clks = count;
- for (i = 0; i < count; i++) {
- rc = of_property_read_string_index(of_node, "domain-id-support-clks",
- i, &domain_id_clks->clk_names[i]);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "Failed reading domain-id clk name at i: %d, total clks: %d",
- i, count);
- rc = -EINVAL;
- goto err;
- }
- rc = cam_soc_util_get_option_clk_by_name(soc_info, domain_id_clks->clk_names[i],
- &domain_id_clks->clk_idx[i]);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "Failed reading domain-id clk %s at i: %d, total clks; %d",
- domain_id_clks->clk_names[i], i, count);
- rc = -EINVAL;
- goto err;
- }
- CAM_DBG(CAM_CPAS, "Domain-id-clk %s with clk index %d",
- domain_id_clks->clk_names[i], domain_id_clks->clk_idx[i]);
- }
- return rc;
- err:
- kfree(domain_id_clks);
- return rc;
- }
- int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
- struct platform_device *pdev, struct cam_cpas_private_soc *soc_private)
- {
- struct device_node *of_node;
- struct of_phandle_args src_args = {0}, dst_args = {0};
- int count = 0, i = 0, rc = 0, num_bw_values = 0, num_levels = 0;
- uint32_t cam_drv_en_mask_val = 0;
- struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
- uint32_t ahb_bus_client_ab = 0, ahb_bus_client_ib = 0;
- if (!soc_private || !pdev) {
- CAM_ERR(CAM_CPAS, "invalid input arg %pK %pK",
- soc_private, pdev);
- return -EINVAL;
- }
- of_node = pdev->dev.of_node;
- rc = of_property_read_string(of_node, "arch-compat",
- &soc_private->arch_compat);
- if (rc) {
- CAM_ERR(CAM_CPAS, "device %s failed to read arch-compat",
- pdev->name);
- return rc;
- }
- cam_cpas_get_hw_features(pdev, soc_private);
- #ifdef CONFIG_DOMAIN_ID_SECURE_CAMERA
- /* get domain id mapping info */
- rc = cam_cpas_parse_domain_id_mapping(of_node, soc_private);
- if (rc)
- return rc;
- /* check if the domain ID configuration is available in the DTSI */
- if (soc_private->domain_id_info.domain_id_supported == false) {
- CAM_ERR(CAM_CPAS, "Domain ID configuration is expected for this target");
- return -EINVAL;
- }
- #endif
- soc_private->camnoc_axi_min_ib_bw = 0;
- rc = of_property_read_u64(of_node,
- "camnoc-axi-min-ib-bw",
- &soc_private->camnoc_axi_min_ib_bw);
- if (rc == -EOVERFLOW) {
- soc_private->camnoc_axi_min_ib_bw = 0;
- rc = of_property_read_u32(of_node,
- "camnoc-axi-min-ib-bw",
- (u32 *)&soc_private->camnoc_axi_min_ib_bw);
- }
- if (rc) {
- CAM_DBG(CAM_CPAS,
- "failed to read camnoc-axi-min-ib-bw rc:%d", rc);
- soc_private->camnoc_axi_min_ib_bw =
- CAM_CPAS_AXI_MIN_CAMNOC_IB_BW;
- }
- CAM_DBG(CAM_CPAS, "camnoc-axi-min-ib-bw = %llu",
- soc_private->camnoc_axi_min_ib_bw);
- soc_private->client_id_based = of_property_read_bool(of_node,
- "client-id-based");
- soc_private->bus_icc_based = of_property_read_bool(of_node,
- "interconnects");
- if (soc_private->bus_icc_based) {
- rc = of_property_read_string(of_node, "interconnect-names",
- &cpas_core->ahb_bus_client.common_data.name);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "device %s failed to read interconnect-names",
- pdev->name);
- return rc;
- }
- rc = of_parse_phandle_with_args(of_node, "interconnects",
- "#interconnect-cells", 0, &src_args);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "device %s failed to read ahb bus src info",
- pdev->name);
- return rc;
- }
- of_node_put(src_args.np);
- if (src_args.args_count != 1) {
- CAM_ERR(CAM_CPAS,
- "Invalid number of ahb src args: %d",
- src_args.args_count);
- return -EINVAL;
- }
- cpas_core->ahb_bus_client.common_data.src_id = src_args.args[0];
- rc = of_parse_phandle_with_args(of_node, "interconnects",
- "#interconnect-cells", 1, &dst_args);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "device %s failed to read ahb bus dst info",
- pdev->name);
- return rc;
- }
- of_node_put(dst_args.np);
- if (dst_args.args_count != 1) {
- CAM_ERR(CAM_CPAS,
- "Invalid number of ahb dst args: %d",
- dst_args.args_count);
- return -EINVAL;
- }
- cpas_core->ahb_bus_client.common_data.dst_id = dst_args.args[0];
- rc = of_property_read_u32(of_node, "cam-ahb-num-cases",
- &cpas_core->ahb_bus_client.common_data.num_usecases);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "device %s failed to read ahb num usecases",
- pdev->name);
- return rc;
- }
- if (cpas_core->ahb_bus_client.common_data.num_usecases >
- CAM_SOC_BUS_MAX_NUM_USECASES) {
- CAM_ERR(CAM_UTIL, "Invalid number of usecases: %d",
- cpas_core->ahb_bus_client.common_data
- .num_usecases);
- return -EINVAL;
- }
- num_bw_values = of_property_count_u32_elems(of_node,
- "cam-ahb-bw-KBps");
- if (num_bw_values <= 0) {
- CAM_ERR(CAM_UTIL, "Error counting ahb bw values");
- return -EINVAL;
- }
- CAM_DBG(CAM_CPAS, "AHB: num bw values %d", num_bw_values);
- num_levels = (num_bw_values / 2);
- if (num_levels !=
- cpas_core->ahb_bus_client.common_data.num_usecases) {
- CAM_ERR(CAM_UTIL, "Invalid number of levels: %d",
- num_bw_values/2);
- return -EINVAL;
- }
- for (i = 0; i < num_levels; i++) {
- rc = of_property_read_u32_index(of_node,
- "cam-ahb-bw-KBps",
- (i * 2),
- &ahb_bus_client_ab);
- if (rc) {
- CAM_ERR(CAM_UTIL,
- "Error reading ab bw value, rc=%d",
- rc);
- return rc;
- }
- cpas_core->ahb_bus_client.common_data.bw_pair[i].ab = ahb_bus_client_ab;
- rc = of_property_read_u32_index(of_node,
- "cam-ahb-bw-KBps",
- ((i * 2) + 1),
- &ahb_bus_client_ib);
- if (rc) {
- CAM_ERR(CAM_UTIL,
- "Error reading ib bw value, rc=%d",
- rc);
- return rc;
- }
- cpas_core->ahb_bus_client.common_data.bw_pair[i].ib = ahb_bus_client_ib;
- CAM_DBG(CAM_CPAS,
- "AHB: Level: %d, ab_value %llu, ib_value: %llu",
- i, cpas_core->ahb_bus_client.common_data
- .bw_pair[i].ab, cpas_core->ahb_bus_client
- .common_data.bw_pair[i].ib);
- }
- }
- count = of_property_count_strings(of_node, "client-names");
- if (count <= 0) {
- CAM_ERR(CAM_CPAS, "no client-names found");
- return -EINVAL;
- } else if (count > CAM_CPAS_MAX_CLIENTS) {
- CAM_ERR(CAM_CPAS, "Number of clients %d greater than max %d",
- count, CAM_CPAS_MAX_CLIENTS);
- return -EINVAL;
- }
- soc_private->num_clients = count;
- CAM_DBG(CAM_CPAS,
- "arch-compat=%s, client_id_based = %d, num_clients=%d",
- soc_private->arch_compat, soc_private->client_id_based,
- soc_private->num_clients);
- for (i = 0; i < soc_private->num_clients; i++) {
- rc = of_property_read_string_index(of_node,
- "client-names", i, &soc_private->client_name[i]);
- if (rc) {
- CAM_ERR(CAM_CPAS, "no client-name at cnt=%d", i);
- return -EINVAL;
- }
- cpas_core->cpas_client[i] =
- kzalloc(sizeof(struct cam_cpas_client), GFP_KERNEL);
- if (!cpas_core->cpas_client[i]) {
- rc = -ENOMEM;
- goto cleanup_clients;
- }
- CAM_DBG(CAM_CPAS, "Client[%d] : %s", i,
- soc_private->client_name[i]);
- }
- soc_private->control_camnoc_axi_clk = of_property_read_bool(of_node,
- "control-camnoc-axi-clk");
- if (soc_private->control_camnoc_axi_clk == true) {
- rc = of_property_read_u32(of_node, "camnoc-bus-width",
- &soc_private->camnoc_bus_width);
- if (rc || (soc_private->camnoc_bus_width == 0)) {
- CAM_ERR(CAM_CPAS, "Bus width not found rc=%d, %d",
- rc, soc_private->camnoc_bus_width);
- goto cleanup_clients;
- }
- if (of_property_read_u32(of_node,
- "camnoc-axi-clk-bw-margin-perc",
- &soc_private->camnoc_axi_clk_bw_margin)) {
- /* this is not fatal, overwrite to 0 */
- soc_private->camnoc_axi_clk_bw_margin = 0;
- }
- }
- CAM_DBG(CAM_CPAS,
- "control_camnoc_axi_clk=%d, width=%d, margin=%d",
- soc_private->control_camnoc_axi_clk,
- soc_private->camnoc_bus_width,
- soc_private->camnoc_axi_clk_bw_margin);
- count = of_property_count_u32_elems(of_node, "vdd-corners");
- if ((count > 0) && (count <= CAM_REGULATOR_LEVEL_MAX) &&
- (of_property_count_strings(of_node, "vdd-corner-ahb-mapping") ==
- count)) {
- const char *ahb_string;
- for (i = 0; i < count; i++) {
- rc = of_property_read_u32_index(of_node, "vdd-corners",
- i, &soc_private->vdd_ahb[i].vdd_corner);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "vdd-corners failed at index=%d", i);
- rc = -ENODEV;
- goto cleanup_clients;
- }
- rc = of_property_read_string_index(of_node,
- "vdd-corner-ahb-mapping", i, &ahb_string);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "no ahb-mapping at index=%d", i);
- rc = -ENODEV;
- goto cleanup_clients;
- }
- rc = cam_soc_util_get_level_from_string(ahb_string,
- &soc_private->vdd_ahb[i].ahb_level);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "invalid ahb-string at index=%d", i);
- rc = -EINVAL;
- goto cleanup_clients;
- }
- CAM_DBG(CAM_CPAS,
- "Vdd-AHB mapping [%d] : [%d] [%s] [%d]", i,
- soc_private->vdd_ahb[i].vdd_corner,
- ahb_string, soc_private->vdd_ahb[i].ahb_level);
- }
- soc_private->num_vdd_ahb_mapping = count;
- }
- soc_private->enable_secure_qos_update = of_property_read_bool(of_node,
- "enable-secure-qos-update");
- soc_private->enable_smart_qos = of_property_read_bool(of_node,
- "enable-smart-qos");
- if (soc_private->enable_smart_qos) {
- uint32_t value;
- soc_private->smart_qos_info = kzalloc(sizeof(struct cam_cpas_smart_qos_info),
- GFP_KERNEL);
- if (!soc_private->smart_qos_info) {
- rc = -ENOMEM;
- goto cleanup_clients;
- }
- /*
- * If enabled, we expect min and max priority values,
- * clamp priority value, slope factor, least and most
- * stressed clamp threshold values, high and low stress
- * indicator threshold values, bw ratio scale factor value,
- * so treat as fatal error if not available.
- */
- rc = of_property_read_u32(of_node, "rt-wr-priority-min",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid min Qos priority rc %d", rc);
- goto cleanup_clients;
- }
- soc_private->smart_qos_info->rt_wr_priority_min = (uint8_t)value;
- rc = of_property_read_u32(of_node, "rt-wr-priority-max",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid max Qos priority rc %d", rc);
- goto cleanup_clients;
- }
- soc_private->smart_qos_info->rt_wr_priority_max = (uint8_t)value;
- rc = of_property_read_u32(of_node, "rt-wr-priority-clamp",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid clamp Qos priority rc %d", rc);
- goto cleanup_clients;
- }
- soc_private->smart_qos_info->rt_wr_priority_clamp = (uint8_t)value;
- rc = of_property_read_u32(of_node, "rt-wr-slope-factor",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid slope factor rc %d", rc);
- goto cleanup_clients;
- }
- if (value > CAM_CPAS_MAX_SLOPE_FACTOR) {
- CAM_ERR(CAM_UTIL, "Invalid slope factor value %d", value);
- rc = -EINVAL;
- goto cleanup_clients;
- } else
- soc_private->smart_qos_info->rt_wr_slope_factor = (uint8_t)value;
- CAM_DBG(CAM_CPAS,
- "SmartQoS enabled, priority min=%u, max=%u, clamp=%u, slope factor=%u",
- (uint32_t)soc_private->smart_qos_info->rt_wr_priority_min,
- (uint32_t)soc_private->smart_qos_info->rt_wr_priority_max,
- (uint32_t)soc_private->smart_qos_info->rt_wr_priority_clamp,
- (uint32_t)soc_private->smart_qos_info->rt_wr_slope_factor);
- rc = of_property_read_u32(of_node, "rt-wr-leaststressed-clamp-threshold",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid leaststressed clamp threshold rc %d", rc);
- goto cleanup_clients;
- }
- soc_private->smart_qos_info->leaststressed_clamp_th = (uint8_t)value;
- rc = of_property_read_u32(of_node, "rt-wr-moststressed-clamp-threshold",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid moststressed clamp threshold rc %d", rc);
- goto cleanup_clients;
- }
- soc_private->smart_qos_info->moststressed_clamp_th = (uint8_t)value;
- CAM_DBG(CAM_CPAS,
- "leaststressed_clamp_th=%u, moststressed_clamp_th=%u",
- (uint32_t)soc_private->smart_qos_info->leaststressed_clamp_th,
- (uint32_t)soc_private->smart_qos_info->moststressed_clamp_th);
- rc = of_property_read_u32(of_node, "rt-wr-highstress-indicator-threshold",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid highstress indicator threshold rc %d", rc);
- goto cleanup_clients;
- }
- if (value > CAM_CPAS_MAX_STRESS_INDICATOR) {
- CAM_ERR(CAM_UTIL, "Invalid highstress indicator threshold value %d", value);
- rc = -EINVAL;
- goto cleanup_clients;
- } else
- soc_private->smart_qos_info->highstress_indicator_th = (uint8_t)value;
- rc = of_property_read_u32(of_node, "rt-wr-lowstress-indicator-threshold",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid lowstress indicator threshold rc %d", rc);
- goto cleanup_clients;
- }
- if (value > CAM_CPAS_MAX_STRESS_INDICATOR) {
- CAM_ERR(CAM_UTIL, "Invalid lowstress indicator threshold value %d", value);
- rc = -EINVAL;
- goto cleanup_clients;
- } else
- soc_private->smart_qos_info->lowstress_indicator_th = (uint8_t)value;
- rc = of_property_read_u32(of_node, "rt-wr-bw-ratio-scale-factor",
- &value);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Invalid bw ratio scale factor rc %d", rc);
- goto cleanup_clients;
- }
- soc_private->smart_qos_info->bw_ratio_scale_factor = (uint8_t)value;
- CAM_DBG(CAM_CPAS,
- "highstress_indicator_th=%u, lowstress_indicator_th=%u, scale factor=%u",
- (uint32_t)soc_private->smart_qos_info->highstress_indicator_th,
- (uint32_t)soc_private->smart_qos_info->lowstress_indicator_th,
- (uint32_t)soc_private->smart_qos_info->bw_ratio_scale_factor);
- } else {
- CAM_DBG(CAM_CPAS, "SmartQoS not enabled, use static settings");
- soc_private->smart_qos_info = NULL;
- }
- rc = of_property_read_u32(of_node, "enable-cam-drv", &cam_drv_en_mask_val);
- if (!rc) {
- if (cam_drv_en_mask_val & CAM_DDR_DRV)
- soc_private->enable_cam_ddr_drv = true;
- if (cam_drv_en_mask_val & CAM_CLK_DRV) {
- if (!soc_private->enable_cam_ddr_drv) {
- CAM_ERR(CAM_CPAS, "DDR DRV needs to be enabled for Clock DRV");
- rc = -EPERM;
- goto cleanup_clients;
- }
- soc_private->enable_cam_clk_drv = true;
- rc = cam_soc_util_cesta_populate_crm_device();
- if (rc) {
- CAM_ERR(CAM_CPAS, "Failed to populate cam cesta crm device rc %d",
- rc);
- goto cleanup_clients;
- }
- }
- }
- CAM_DBG(CAM_CPAS, "enable_cam_ddr_drv %d enable_cam_clk_drv %d cam_drv_en_mask_val %d",
- soc_private->enable_cam_ddr_drv, soc_private->enable_cam_clk_drv,
- cam_drv_en_mask_val);
- rc = cam_cpas_parse_node_tree(cpas_core, of_node, soc_private);
- if (rc) {
- CAM_ERR(CAM_CPAS, "Node tree parsing failed rc: %d", rc);
- goto cleanup_tree;
- }
- /* If SmartQoS is enabled, we expect few tags in dtsi, validate */
- if (soc_private->enable_smart_qos) {
- int port_idx;
- bool rt_port_exists = false;
- if ((soc_private->smart_qos_info->num_rt_wr_nius == 0) ||
- (soc_private->smart_qos_info->num_rt_wr_nius >
- CAM_CPAS_MAX_RT_WR_NIU_NODES)) {
- CAM_ERR(CAM_CPAS, "Invalid number of level1 nodes %d",
- soc_private->smart_qos_info->num_rt_wr_nius);
- rc = -EINVAL;
- goto cleanup_tree;
- }
- for (port_idx = 0; port_idx < cpas_core->num_axi_ports;
- port_idx++) {
- CAM_DBG(CAM_CPAS, "[%d] : Port[%s] is_rt=%d",
- port_idx, cpas_core->axi_port[port_idx].axi_port_name,
- cpas_core->axi_port[port_idx].is_rt);
- if (cpas_core->axi_port[port_idx].is_rt) {
- rt_port_exists = true;
- break;
- }
- }
- if (!rt_port_exists) {
- CAM_ERR(CAM_CPAS,
- "RT AXI port not tagged, num ports %d",
- cpas_core->num_axi_ports);
- rc = -EINVAL;
- goto cleanup_tree;
- }
- }
- /* Optional rpmh bcm info */
- count = of_property_count_u32_elems(of_node, "rpmh-bcm-info");
- /*
- * We expect count=5(CAM_RPMH_BCM_INFO_MAX) if valid rpmh bcm info
- * is available.
- * 0 - Total number of BCMs
- * 1 - First BCM FE (front-end) register offset.
- * These represent requested clk plan by sw
- * 2 - First BCM BE (back-end) register offset.
- * These represent actual clk plan at hw
- * 3 - DDR BCM index
- * 4 - MMNOC BCM index
- */
- if (count == CAM_RPMH_BCM_INFO_MAX) {
- for (i = 0; i < count; i++) {
- rc = of_property_read_u32_index(of_node,
- "rpmh-bcm-info", i, &soc_private->rpmh_info[i]);
- if (rc) {
- CAM_ERR(CAM_CPAS,
- "Incorrect rpmh info at %d, count=%d",
- i, count);
- break;
- }
- CAM_DBG(CAM_CPAS, "RPMH BCM Info [%d]=0x%x",
- i, soc_private->rpmh_info[i]);
- }
- if (rc)
- soc_private->rpmh_info[CAM_RPMH_NUMBER_OF_BCMS] = 0;
- } else {
- CAM_DBG(CAM_CPAS, "RPMH BCM info not available in DT, count=%d",
- count);
- }
- /* check cache info */
- rc = cam_cpas_parse_sys_cache_uids(of_node, soc_private);
- if (rc)
- goto cache_parse_fail;
- return 0;
- cache_parse_fail:
- soc_private->rpmh_info[CAM_RPMH_NUMBER_OF_BCMS] = 0;
- cleanup_tree:
- cam_cpas_node_tree_cleanup(cpas_core, soc_private);
- cleanup_clients:
- cam_cpas_util_client_cleanup(cpas_hw);
- return rc;
- }
- static int cam_cpas_soc_fill_irq_data(struct cam_hw_info *cpas_hw,
- struct cam_hw_soc_info *soc_info, void **irq_data)
- {
- struct cam_cpas_private_soc *soc_private = soc_info->soc_private;
- int i;
- for (i = 0; i < soc_info->irq_count; i++) {
- soc_private->irq_data[i].cpas_hw = cpas_hw;
- if (!strcmp(soc_info->irq_name[i], "cpas_camnoc"))
- soc_private->irq_data[i].camnoc_type = CAM_CAMNOC_HW_COMBINED;
- else if (!strcmp(soc_info->irq_name[i], "cpas_camnoc_rt"))
- soc_private->irq_data[i].camnoc_type = CAM_CAMNOC_HW_RT;
- else if (!strcmp(soc_info->irq_name[i], "cpas_camnoc_nrt"))
- soc_private->irq_data[i].camnoc_type = CAM_CAMNOC_HW_NRT;
- else {
- CAM_ERR(CAM_CPAS, "Unable to identify interrupt name: %s",
- soc_info->irq_name[i]);
- return -EINVAL;
- }
- irq_data[i] = &soc_private->irq_data[i];
- }
- return 0;
- }
- int cam_cpas_soc_init_resources(struct cam_hw_soc_info *soc_info,
- irq_handler_t irq_handler, struct cam_hw_info *cpas_hw)
- {
- int rc = 0;
- struct cam_cpas_private_soc *soc_private;
- void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
- rc = cam_soc_util_get_dt_properties(soc_info);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed in get_dt_properties, rc=%d", rc);
- return rc;
- }
- if (soc_info->irq_count > 0 && !irq_handler) {
- CAM_ERR(CAM_CPAS, "Invalid IRQ handler");
- return -EINVAL;
- }
- soc_info->soc_private = kzalloc(sizeof(struct cam_cpas_private_soc),
- GFP_KERNEL);
- if (!soc_info->soc_private) {
- CAM_ERR(CAM_CPAS, "Failed to allocate soc private");
- return -ENOMEM;
- }
- soc_private = (struct cam_cpas_private_soc *)soc_info->soc_private;
- rc = cam_cpas_get_custom_dt_info(cpas_hw, soc_info->pdev, soc_private);
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed in get_custom_info, rc=%d", rc);
- goto free_soc_private;
- }
- soc_private->irq_data = kcalloc(soc_info->irq_count, sizeof(struct cam_cpas_soc_irq_data),
- GFP_KERNEL);
- if (!soc_private->irq_data) {
- CAM_ERR(CAM_CPAS, "Failed to allocate irq data");
- rc = -ENOMEM;
- goto free_soc_private;
- }
- rc = cam_cpas_soc_fill_irq_data(cpas_hw, soc_info, &(irq_data[0]));
- if (rc) {
- CAM_ERR(CAM_CPAS, "Failed to fill irq data rc=%d", rc);
- goto free_irq_data;
- }
- soc_info->is_clk_drv_en = soc_private->enable_cam_clk_drv;
- rc = cam_soc_util_request_platform_resource(soc_info, irq_handler, &(irq_data[0]));
- if (rc) {
- CAM_ERR(CAM_CPAS, "failed in request_platform_resource, rc=%d", rc);
- goto free_irq_data;
- }
- rc = cam_soc_util_get_option_clk_by_name(soc_info, CAM_ICP_CLK_NAME,
- &soc_private->icp_clk_index);
- if (rc) {
- CAM_DBG(CAM_CPAS, "ICP option clk get failed with rc %d", rc);
- soc_private->icp_clk_index = -1;
- rc = 0;
- } else {
- CAM_DBG(CAM_CPAS, "ICP option clk get success index %d",
- soc_private->icp_clk_index);
- }
- if (soc_private->domain_id_info.domain_id_supported) {
- rc = cam_cpas_get_domain_id_support_clks(soc_info->pdev->dev.of_node,
- soc_info, soc_private);
- if (rc)
- goto release_res;
- }
- return rc;
- release_res:
- cam_soc_util_release_platform_resource(soc_info);
- free_irq_data:
- kfree(soc_private->irq_data);
- free_soc_private:
- kfree(soc_private->llcc_info);
- kfree(soc_private->smart_qos_info);
- kfree(soc_info->soc_private);
- soc_info->soc_private = NULL;
- return rc;
- }
- int cam_cpas_soc_deinit_resources(struct cam_hw_soc_info *soc_info)
- {
- int rc, i;
- struct cam_cpas_private_soc *soc_private = soc_info->soc_private;
- for (i = 0; i < soc_private->num_caches; i++)
- llcc_slice_putd(soc_private->llcc_info[i].slic_desc);
- if (soc_private->icp_clk_index != -1) {
- rc = cam_soc_util_put_optional_clk(soc_info, soc_private->icp_clk_index);
- if (rc)
- CAM_ERR(CAM_CPAS, "Error Put optional clk failed rc=%d", rc);
- }
- kfree(soc_private->domain_id_info.domain_id_entries);
- kfree(soc_private->domain_id_clks);
- rc = cam_soc_util_release_platform_resource(soc_info);
- if (rc)
- CAM_ERR(CAM_CPAS, "release platform failed, rc=%d", rc);
- kfree(soc_private->irq_data);
- kfree(soc_private->llcc_info);
- kfree(soc_private->smart_qos_info);
- kfree(soc_info->soc_private);
- soc_info->soc_private = NULL;
- return rc;
- }
- int cam_cpas_soc_enable_resources(struct cam_hw_soc_info *soc_info,
- enum cam_vote_level default_level)
- {
- struct cam_cpas_private_soc *soc_private = soc_info->soc_private;
- int rc = 0;
- /* set this everytime in order to support debugfs to disable clk drv between runs */
- soc_info->is_clk_drv_en = soc_private->enable_cam_clk_drv;
- rc = cam_soc_util_enable_platform_resource(soc_info, CAM_CLK_SW_CLIENT_IDX, true,
- default_level, true);
- if (rc)
- CAM_ERR(CAM_CPAS, "enable platform resource failed, rc=%d", rc);
- return rc;
- }
- int cam_cpas_soc_disable_resources(struct cam_hw_soc_info *soc_info,
- bool disable_clocks, bool disable_irq)
- {
- int rc = 0;
- rc = cam_soc_util_disable_platform_resource(soc_info, CAM_CLK_SW_CLIENT_IDX,
- disable_clocks, disable_irq);
- if (rc)
- CAM_ERR(CAM_CPAS, "disable platform failed, rc=%d", rc);
- return rc;
- }
- int cam_cpas_soc_disable_irq(struct cam_hw_soc_info *soc_info)
- {
- int rc = 0;
- rc = cam_soc_util_irq_disable(soc_info);
- if (rc)
- CAM_ERR(CAM_CPAS, "disable irq failed, rc=%d", rc);
- return rc;
- }
|