Loading Documentation/devicetree/bindings/media/video/msm-cam-cpas.txt +5 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,11 @@ First Level Node - CAM CPAS device Value type: <u32> Definition: CAM HW Version information. - camnoc-axi-min-ib-bw Usage: optional Value type: <u64> Definition: Min camnoc axi bw for the given target. - regulator-names Usage: required Value type: <string> Loading arch/arm64/boot/dts/qcom/sm8150-camera.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -499,6 +499,7 @@ interrupt-names = "cpas_camnoc"; interrupts = <0 459 0>; qcom,cpas-hw-ver = <0x175100>; /* Titan v175 v1.0.0 */ camnoc-axi-min-ib-bw = <3000000000>; regulator-names = "camss-vdd"; camss-vdd-supply = <&titan_top_gdsc>; clock-names = Loading drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c +81 −48 Original line number Diff line number Diff line Loading @@ -22,11 +22,6 @@ #include "cam_cpas_hw_intf.h" #include "cam_cpas_soc.h" #define CAM_CPAS_AXI_MIN_MNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_MNOC_IB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_IB_BW (3000000000L) static uint cam_min_camnoc_ib_bw; module_param(cam_min_camnoc_ib_bw, uint, 0644); Loading Loading @@ -82,8 +77,8 @@ static int cam_cpas_util_vote_bus_client_level( if (level == bus_client->curr_vote_level) return 0; CAM_DBG(CAM_CPAS, "Bus client[%d] index[%d]", bus_client->client_id, level); CAM_DBG(CAM_CPAS, "Bus client=[%d][%s] index[%d]", bus_client->client_id, bus_client->name, level); msm_bus_scale_client_update_request(bus_client->client_id, level); bus_client->curr_vote_level = level; Loading Loading @@ -152,8 +147,8 @@ static int cam_cpas_util_vote_bus_client_bw( path->vectors[0].ab = ab; path->vectors[0].ib = ib; CAM_DBG(CAM_CPAS, "Bus client[%d] :ab[%llu] ib[%llu], index[%d]", bus_client->client_id, ab, ib, idx); CAM_DBG(CAM_CPAS, "Bus client=[%d][%s] :ab[%llu] ib[%llu], index[%d]", bus_client->client_id, bus_client->name, ab, ib, idx); msm_bus_scale_client_update_request(bus_client->client_id, idx); return 0; Loading Loading @@ -208,10 +203,12 @@ static int cam_cpas_util_register_bus_client( bus_client->num_paths = pdata->usecase[0].num_paths; bus_client->curr_vote_level = 0; bus_client->valid = true; bus_client->name = pdata->name; mutex_init(&bus_client->lock); CAM_DBG(CAM_CPAS, "Bus Client : src=%d, dst=%d, bus_client=%d", bus_client->src, bus_client->dst, bus_client->client_id); CAM_DBG(CAM_CPAS, "Bus Client=[%d][%s] : src=%d, dst=%d", bus_client->client_id, bus_client->name, bus_client->src, bus_client->dst); return 0; fail_unregister_client: Loading Loading @@ -463,6 +460,7 @@ static int cam_cpas_hw_reg_write(struct cam_hw_info *cpas_hw, { struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; int reg_base_index = cpas_core->regbase_index[reg_base]; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -478,9 +476,12 @@ static int cam_cpas_hw_reg_write(struct cam_hw_info *cpas_hw, return -EINVAL; mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started%d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } Loading @@ -503,6 +504,7 @@ static int cam_cpas_hw_reg_read(struct cam_hw_info *cpas_hw, { struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; int reg_base_index = cpas_core->regbase_index[reg_base]; uint32_t reg_value; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); Loading @@ -523,9 +525,12 @@ static int cam_cpas_hw_reg_read(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started%d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } Loading Loading @@ -584,8 +589,9 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate( soc_private->camnoc_axi_clk_bw_margin) / 100; if ((required_camnoc_bw > 0) && (required_camnoc_bw < CAM_CPAS_AXI_MIN_CAMNOC_IB_BW)) required_camnoc_bw = CAM_CPAS_AXI_MIN_CAMNOC_IB_BW; (required_camnoc_bw < soc_private->camnoc_axi_min_ib_bw)) required_camnoc_bw = soc_private->camnoc_axi_min_ib_bw; clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width; Loading Loading @@ -710,6 +716,7 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw, { struct cam_axi_vote axi_vote; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -734,16 +741,20 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started %d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } CAM_DBG(CAM_CPAS, "Client[%d] Requested compressed[%llu], uncompressed[%llu]", client_indx, axi_vote.compressed_bw, "Client=[%d][%s][%d] Requested compressed[%llu], uncompressed[%llu]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, axi_vote.compressed_bw, axi_vote.uncompressed_bw); rc = cam_cpas_util_apply_client_axi_vote(cpas_hw, Loading Loading @@ -824,7 +835,8 @@ static int cam_cpas_util_apply_client_ahb_vote(struct cam_hw_info *cpas_hw, mutex_lock(&ahb_bus_client->lock); cpas_client->ahb_level = required_level; CAM_DBG(CAM_CPAS, "Clients required level[%d], curr_level[%d]", CAM_DBG(CAM_CPAS, "Client=[%d][%s] required level[%d], curr_level[%d]", ahb_bus_client->client_id, ahb_bus_client->name, required_level, ahb_bus_client->curr_vote_level); if (required_level == ahb_bus_client->curr_vote_level) Loading Loading @@ -868,6 +880,7 @@ static int cam_cpas_hw_update_ahb_vote(struct cam_hw_info *cpas_hw, { struct cam_ahb_vote ahb_vote; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -890,17 +903,21 @@ static int cam_cpas_hw_update_ahb_vote(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started %d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } CAM_DBG(CAM_CPAS, "client[%d] : type[%d], level[%d], freq[%ld], applied[%d]", client_indx, ahb_vote.type, ahb_vote.vote.level, ahb_vote.vote.freq, "client=[%d][%s][%d] : type[%d], level[%d], freq[%ld], applied[%d]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, ahb_vote.type, ahb_vote.vote.level, ahb_vote.vote.freq, cpas_core->cpas_client[client_indx]->ahb_level); rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, Loading Loading @@ -962,32 +979,37 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_REGISTERED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client is not registered %d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d] is not registered", client_indx); rc = -EPERM; goto done; } if (CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "Client %d is in start state", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] is in start state", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } cpas_client = cpas_core->cpas_client[client_indx]; CAM_DBG(CAM_CPAS, "AHB :client[%d] type[%d], level[%d], applied[%d]", client_indx, ahb_vote->type, ahb_vote->vote.level, cpas_client->ahb_level); CAM_DBG(CAM_CPAS, "AHB :client=[%d][%s][%d] type[%d], level[%d], applied[%d]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, ahb_vote->type, ahb_vote->vote.level, cpas_client->ahb_level); rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client, ahb_vote, &applied_level); if (rc) goto done; CAM_DBG(CAM_CPAS, "AXI client[%d] compressed_bw[%llu], uncompressed_bw[%llu]", client_indx, axi_vote->compressed_bw, "AXI client=[%d][%s][%d] compressed_bw[%llu], uncompressed_bw[%llu]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, axi_vote->compressed_bw, axi_vote->uncompressed_bw); rc = cam_cpas_util_apply_client_axi_vote(cpas_hw, cpas_client, axi_vote); Loading Loading @@ -1024,9 +1046,9 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args, cpas_client->started = true; cpas_core->streamon_clients++; CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d", soc_private->client_name[client_indx], cpas_core->streamon_clients); CAM_DBG(CAM_CPAS, "client=[%d][%s][%d] streamon_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->streamon_clients); done: mutex_unlock(&cpas_core->client_mutex[client_indx]); mutex_unlock(&cpas_hw->hw_mutex); Loading Loading @@ -1076,18 +1098,20 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d", soc_private->client_name[client_indx], cpas_core->streamon_clients); CAM_DBG(CAM_CPAS, "Client=[%d][%s][%d] streamon_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->streamon_clients); if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "Client %d is not started", client_indx); CAM_ERR(CAM_CPAS, "Client=[%d][%s][%d] is not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } cpas_client = cpas_core->cpas_client[client_indx]; cpas_client->started = false; cpas_core->streamon_clients--; Loading Loading @@ -1221,8 +1245,9 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw, cpas_client, client_indx); if (rc) { CAM_ERR(CAM_CPAS, "axi_port_insert failed client_indx=%d, rc=%d", client_indx, rc); "axi_port_insert failed Client=[%d][%s][%d], rc=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, rc); kfree(cpas_client); mutex_unlock(&cpas_hw->hw_mutex); return -EINVAL; Loading @@ -1237,8 +1262,9 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw, mutex_unlock(&cpas_hw->hw_mutex); CAM_DBG(CAM_CPAS, "client_indx=%d, registered_clients=%d", client_indx, cpas_core->registered_clients); CAM_DBG(CAM_CPAS, "client=[%d][%s][%d], registered_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->registered_clients); return 0; } Loading @@ -1247,6 +1273,7 @@ static int cam_cpas_hw_unregister_client(struct cam_hw_info *cpas_hw, uint32_t client_handle) { struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -1255,15 +1282,20 @@ static int cam_cpas_hw_unregister_client(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_REGISTERED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client not registered %d", client_indx); CAM_ERR(CAM_CPAS, "Client=[%d][%s][%d] not registered", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } if (CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "Client %d is not stopped", client_indx); CAM_ERR(CAM_CPAS, "Client=[%d][%s][%d] is not stopped", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } Loading @@ -1271,8 +1303,9 @@ static int cam_cpas_hw_unregister_client(struct cam_hw_info *cpas_hw, cam_cpas_util_remove_client_from_axi_port( cpas_core->cpas_client[client_indx]); CAM_DBG(CAM_CPAS, "client_indx=%d, registered_clients=%d", client_indx, cpas_core->registered_clients); CAM_DBG(CAM_CPAS, "client=[%d][%s][%d], registered_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->registered_clients); kfree(cpas_core->cpas_client[client_indx]); cpas_core->cpas_client[client_indx] = NULL; Loading drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.h +7 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #define CAM_CPAS_MAX_CLIENTS 30 #define CAM_CPAS_INFLIGHT_WORKS 5 #define CAM_CPAS_AXI_MIN_MNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_MNOC_IB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_IB_BW (3000000000L) #define CAM_CPAS_GET_CLIENT_IDX(handle) (handle) #define CAM_CPAS_GET_CLIENT_HANDLE(indx) (indx) Loading Loading @@ -118,6 +123,7 @@ struct cam_cpas_client { * @dyn_vote: Whether dynamic voting enabled * @lock: Mutex lock used while voting on this client * @valid: Whether bus client is valid * @name: Name of the bus client * */ struct cam_cpas_bus_client { Loading @@ -131,6 +137,7 @@ struct cam_cpas_bus_client { bool dyn_vote; struct mutex lock; bool valid; const char *name; }; /** Loading drivers/media/platform/msm/camera/cam_cpas/cam_cpas_soc.c +21 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,27 @@ int cam_cpas_get_custom_dt_info(struct platform_device *pdev, CAM_DBG(CAM_CPAS, "CPAS HW VERSION %x", soc_private->hw_version); 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"); Loading Loading
Documentation/devicetree/bindings/media/video/msm-cam-cpas.txt +5 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,11 @@ First Level Node - CAM CPAS device Value type: <u32> Definition: CAM HW Version information. - camnoc-axi-min-ib-bw Usage: optional Value type: <u64> Definition: Min camnoc axi bw for the given target. - regulator-names Usage: required Value type: <string> Loading
arch/arm64/boot/dts/qcom/sm8150-camera.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -499,6 +499,7 @@ interrupt-names = "cpas_camnoc"; interrupts = <0 459 0>; qcom,cpas-hw-ver = <0x175100>; /* Titan v175 v1.0.0 */ camnoc-axi-min-ib-bw = <3000000000>; regulator-names = "camss-vdd"; camss-vdd-supply = <&titan_top_gdsc>; clock-names = Loading
drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c +81 −48 Original line number Diff line number Diff line Loading @@ -22,11 +22,6 @@ #include "cam_cpas_hw_intf.h" #include "cam_cpas_soc.h" #define CAM_CPAS_AXI_MIN_MNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_MNOC_IB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_IB_BW (3000000000L) static uint cam_min_camnoc_ib_bw; module_param(cam_min_camnoc_ib_bw, uint, 0644); Loading Loading @@ -82,8 +77,8 @@ static int cam_cpas_util_vote_bus_client_level( if (level == bus_client->curr_vote_level) return 0; CAM_DBG(CAM_CPAS, "Bus client[%d] index[%d]", bus_client->client_id, level); CAM_DBG(CAM_CPAS, "Bus client=[%d][%s] index[%d]", bus_client->client_id, bus_client->name, level); msm_bus_scale_client_update_request(bus_client->client_id, level); bus_client->curr_vote_level = level; Loading Loading @@ -152,8 +147,8 @@ static int cam_cpas_util_vote_bus_client_bw( path->vectors[0].ab = ab; path->vectors[0].ib = ib; CAM_DBG(CAM_CPAS, "Bus client[%d] :ab[%llu] ib[%llu], index[%d]", bus_client->client_id, ab, ib, idx); CAM_DBG(CAM_CPAS, "Bus client=[%d][%s] :ab[%llu] ib[%llu], index[%d]", bus_client->client_id, bus_client->name, ab, ib, idx); msm_bus_scale_client_update_request(bus_client->client_id, idx); return 0; Loading Loading @@ -208,10 +203,12 @@ static int cam_cpas_util_register_bus_client( bus_client->num_paths = pdata->usecase[0].num_paths; bus_client->curr_vote_level = 0; bus_client->valid = true; bus_client->name = pdata->name; mutex_init(&bus_client->lock); CAM_DBG(CAM_CPAS, "Bus Client : src=%d, dst=%d, bus_client=%d", bus_client->src, bus_client->dst, bus_client->client_id); CAM_DBG(CAM_CPAS, "Bus Client=[%d][%s] : src=%d, dst=%d", bus_client->client_id, bus_client->name, bus_client->src, bus_client->dst); return 0; fail_unregister_client: Loading Loading @@ -463,6 +460,7 @@ static int cam_cpas_hw_reg_write(struct cam_hw_info *cpas_hw, { struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; int reg_base_index = cpas_core->regbase_index[reg_base]; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -478,9 +476,12 @@ static int cam_cpas_hw_reg_write(struct cam_hw_info *cpas_hw, return -EINVAL; mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started%d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } Loading @@ -503,6 +504,7 @@ static int cam_cpas_hw_reg_read(struct cam_hw_info *cpas_hw, { struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; int reg_base_index = cpas_core->regbase_index[reg_base]; uint32_t reg_value; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); Loading @@ -523,9 +525,12 @@ static int cam_cpas_hw_reg_read(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started%d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } Loading Loading @@ -584,8 +589,9 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate( soc_private->camnoc_axi_clk_bw_margin) / 100; if ((required_camnoc_bw > 0) && (required_camnoc_bw < CAM_CPAS_AXI_MIN_CAMNOC_IB_BW)) required_camnoc_bw = CAM_CPAS_AXI_MIN_CAMNOC_IB_BW; (required_camnoc_bw < soc_private->camnoc_axi_min_ib_bw)) required_camnoc_bw = soc_private->camnoc_axi_min_ib_bw; clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width; Loading Loading @@ -710,6 +716,7 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw, { struct cam_axi_vote axi_vote; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -734,16 +741,20 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started %d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } CAM_DBG(CAM_CPAS, "Client[%d] Requested compressed[%llu], uncompressed[%llu]", client_indx, axi_vote.compressed_bw, "Client=[%d][%s][%d] Requested compressed[%llu], uncompressed[%llu]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, axi_vote.compressed_bw, axi_vote.uncompressed_bw); rc = cam_cpas_util_apply_client_axi_vote(cpas_hw, Loading Loading @@ -824,7 +835,8 @@ static int cam_cpas_util_apply_client_ahb_vote(struct cam_hw_info *cpas_hw, mutex_lock(&ahb_bus_client->lock); cpas_client->ahb_level = required_level; CAM_DBG(CAM_CPAS, "Clients required level[%d], curr_level[%d]", CAM_DBG(CAM_CPAS, "Client=[%d][%s] required level[%d], curr_level[%d]", ahb_bus_client->client_id, ahb_bus_client->name, required_level, ahb_bus_client->curr_vote_level); if (required_level == ahb_bus_client->curr_vote_level) Loading Loading @@ -868,6 +880,7 @@ static int cam_cpas_hw_update_ahb_vote(struct cam_hw_info *cpas_hw, { struct cam_ahb_vote ahb_vote; struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -890,17 +903,21 @@ static int cam_cpas_hw_update_ahb_vote(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client has not started %d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] has not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto unlock_client; } CAM_DBG(CAM_CPAS, "client[%d] : type[%d], level[%d], freq[%ld], applied[%d]", client_indx, ahb_vote.type, ahb_vote.vote.level, ahb_vote.vote.freq, "client=[%d][%s][%d] : type[%d], level[%d], freq[%ld], applied[%d]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, ahb_vote.type, ahb_vote.vote.level, ahb_vote.vote.freq, cpas_core->cpas_client[client_indx]->ahb_level); rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, Loading Loading @@ -962,32 +979,37 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_REGISTERED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client is not registered %d", client_indx); CAM_ERR(CAM_CPAS, "client=[%d] is not registered", client_indx); rc = -EPERM; goto done; } if (CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "Client %d is in start state", client_indx); CAM_ERR(CAM_CPAS, "client=[%d][%s][%d] is in start state", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } cpas_client = cpas_core->cpas_client[client_indx]; CAM_DBG(CAM_CPAS, "AHB :client[%d] type[%d], level[%d], applied[%d]", client_indx, ahb_vote->type, ahb_vote->vote.level, cpas_client->ahb_level); CAM_DBG(CAM_CPAS, "AHB :client=[%d][%s][%d] type[%d], level[%d], applied[%d]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, ahb_vote->type, ahb_vote->vote.level, cpas_client->ahb_level); rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client, ahb_vote, &applied_level); if (rc) goto done; CAM_DBG(CAM_CPAS, "AXI client[%d] compressed_bw[%llu], uncompressed_bw[%llu]", client_indx, axi_vote->compressed_bw, "AXI client=[%d][%s][%d] compressed_bw[%llu], uncompressed_bw[%llu]", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, axi_vote->compressed_bw, axi_vote->uncompressed_bw); rc = cam_cpas_util_apply_client_axi_vote(cpas_hw, cpas_client, axi_vote); Loading Loading @@ -1024,9 +1046,9 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args, cpas_client->started = true; cpas_core->streamon_clients++; CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d", soc_private->client_name[client_indx], cpas_core->streamon_clients); CAM_DBG(CAM_CPAS, "client=[%d][%s][%d] streamon_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->streamon_clients); done: mutex_unlock(&cpas_core->client_mutex[client_indx]); mutex_unlock(&cpas_hw->hw_mutex); Loading Loading @@ -1076,18 +1098,20 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d", soc_private->client_name[client_indx], cpas_core->streamon_clients); CAM_DBG(CAM_CPAS, "Client=[%d][%s][%d] streamon_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->streamon_clients); if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "Client %d is not started", client_indx); CAM_ERR(CAM_CPAS, "Client=[%d][%s][%d] is not started", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } cpas_client = cpas_core->cpas_client[client_indx]; cpas_client->started = false; cpas_core->streamon_clients--; Loading Loading @@ -1221,8 +1245,9 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw, cpas_client, client_indx); if (rc) { CAM_ERR(CAM_CPAS, "axi_port_insert failed client_indx=%d, rc=%d", client_indx, rc); "axi_port_insert failed Client=[%d][%s][%d], rc=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, rc); kfree(cpas_client); mutex_unlock(&cpas_hw->hw_mutex); return -EINVAL; Loading @@ -1237,8 +1262,9 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw, mutex_unlock(&cpas_hw->hw_mutex); CAM_DBG(CAM_CPAS, "client_indx=%d, registered_clients=%d", client_indx, cpas_core->registered_clients); CAM_DBG(CAM_CPAS, "client=[%d][%s][%d], registered_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->registered_clients); return 0; } Loading @@ -1247,6 +1273,7 @@ static int cam_cpas_hw_unregister_client(struct cam_hw_info *cpas_hw, uint32_t client_handle) { struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_client *cpas_client = NULL; uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle); int rc = 0; Loading @@ -1255,15 +1282,20 @@ static int cam_cpas_hw_unregister_client(struct cam_hw_info *cpas_hw, mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); cpas_client = cpas_core->cpas_client[client_indx]; if (!CAM_CPAS_CLIENT_REGISTERED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "client not registered %d", client_indx); CAM_ERR(CAM_CPAS, "Client=[%d][%s][%d] not registered", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } if (CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) { CAM_ERR(CAM_CPAS, "Client %d is not stopped", client_indx); CAM_ERR(CAM_CPAS, "Client=[%d][%s][%d] is not stopped", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index); rc = -EPERM; goto done; } Loading @@ -1271,8 +1303,9 @@ static int cam_cpas_hw_unregister_client(struct cam_hw_info *cpas_hw, cam_cpas_util_remove_client_from_axi_port( cpas_core->cpas_client[client_indx]); CAM_DBG(CAM_CPAS, "client_indx=%d, registered_clients=%d", client_indx, cpas_core->registered_clients); CAM_DBG(CAM_CPAS, "client=[%d][%s][%d], registered_clients=%d", client_indx, cpas_client->data.identifier, cpas_client->data.cell_index, cpas_core->registered_clients); kfree(cpas_core->cpas_client[client_indx]); cpas_core->cpas_client[client_indx] = NULL; Loading
drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.h +7 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #define CAM_CPAS_MAX_CLIENTS 30 #define CAM_CPAS_INFLIGHT_WORKS 5 #define CAM_CPAS_AXI_MIN_MNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_MNOC_IB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_AB_BW (2048 * 1024) #define CAM_CPAS_AXI_MIN_CAMNOC_IB_BW (3000000000L) #define CAM_CPAS_GET_CLIENT_IDX(handle) (handle) #define CAM_CPAS_GET_CLIENT_HANDLE(indx) (indx) Loading Loading @@ -118,6 +123,7 @@ struct cam_cpas_client { * @dyn_vote: Whether dynamic voting enabled * @lock: Mutex lock used while voting on this client * @valid: Whether bus client is valid * @name: Name of the bus client * */ struct cam_cpas_bus_client { Loading @@ -131,6 +137,7 @@ struct cam_cpas_bus_client { bool dyn_vote; struct mutex lock; bool valid; const char *name; }; /** Loading
drivers/media/platform/msm/camera/cam_cpas/cam_cpas_soc.c +21 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,27 @@ int cam_cpas_get_custom_dt_info(struct platform_device *pdev, CAM_DBG(CAM_CPAS, "CPAS HW VERSION %x", soc_private->hw_version); 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"); Loading