Loading drivers/media/platform/msm/cvp/cvp_hfi.c +34 −29 Original line number Original line Diff line number Diff line Loading @@ -3213,18 +3213,21 @@ static inline int __init_clocks(struct iris_hfi_device *device) } } static int __handle_reset_clk(struct msm_cvp_platform_resources *res, static int __handle_reset_clk(struct msm_cvp_platform_resources *res, int reset_index, enum reset_state state) int reset_index, enum reset_state state, enum power_state pwr_state) { { int rc = 0; int rc = 0; struct reset_control *rst; struct reset_control *rst; struct reset_info rst_info; struct reset_set *rst_set = &res->reset_set; struct reset_set *rst_set = &res->reset_set; if (!rst_set->reset_tbl) if (!rst_set->reset_tbl) return 0; return 0; rst = rst_set->reset_tbl[reset_index].rst; rst_info = rst_set->reset_tbl[reset_index]; dprintk(CVP_DBG, "reset_clk: name %s reset_state %d rst %pK\n", rst = rst_info.rst; rst_set->reset_tbl[reset_index].name, state, rst); dprintk(CVP_DBG, "reset_clk: name %s reset_state %d rst %pK ps=%d\n", rst_set->reset_tbl[reset_index].name, state, rst, pwr_state); switch (state) { switch (state) { case INIT: case INIT: Loading @@ -3244,6 +3247,9 @@ static int __handle_reset_clk(struct msm_cvp_platform_resources *res, goto failed_to_reset; goto failed_to_reset; } } if (pwr_state != rst_info.required_state) break; rc = reset_control_assert(rst); rc = reset_control_assert(rst); break; break; case DEASSERT: case DEASSERT: Loading @@ -3251,6 +3257,10 @@ static int __handle_reset_clk(struct msm_cvp_platform_resources *res, rc = PTR_ERR(rst); rc = PTR_ERR(rst); goto failed_to_reset; goto failed_to_reset; } } if (pwr_state != rst_info.required_state) break; rc = reset_control_deassert(rst); rc = reset_control_deassert(rst); break; break; default: default: Loading Loading @@ -3285,6 +3295,7 @@ static inline void __disable_unprepare_clks(struct iris_hfi_device *device) static int reset_ahb2axi_bridge(struct iris_hfi_device *device) static int reset_ahb2axi_bridge(struct iris_hfi_device *device) { { int rc, i; int rc, i; enum power_state s; if (!device) { if (!device) { dprintk(CVP_ERR, "NULL device\n"); dprintk(CVP_ERR, "NULL device\n"); Loading @@ -3292,8 +3303,13 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) goto failed_to_reset; goto failed_to_reset; } } if (device->power_enabled) s = CVP_POWER_ON; else s = CVP_POWER_OFF; for (i = 0; i < device->res->reset_set.count; i++) { for (i = 0; i < device->res->reset_set.count; i++) { rc = __handle_reset_clk(device->res, i, ASSERT); rc = __handle_reset_clk(device->res, i, ASSERT, s); if (rc) { if (rc) { dprintk(CVP_ERR, dprintk(CVP_ERR, "failed to assert reset clocks\n"); "failed to assert reset clocks\n"); Loading @@ -3303,7 +3319,7 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) /* wait for deassert */ /* wait for deassert */ usleep_range(150, 250); usleep_range(150, 250); rc = __handle_reset_clk(device->res, i, DEASSERT); rc = __handle_reset_clk(device->res, i, DEASSERT, s); if (rc) { if (rc) { dprintk(CVP_ERR, dprintk(CVP_ERR, "failed to deassert reset clocks\n"); "failed to deassert reset clocks\n"); Loading Loading @@ -3534,7 +3550,7 @@ static int __init_resources(struct iris_hfi_device *device, } } for (i = 0; i < device->res->reset_set.count; i++) { for (i = 0; i < device->res->reset_set.count; i++) { rc = __handle_reset_clk(res, i, INIT); rc = __handle_reset_clk(res, i, INIT, 0); if (rc) { if (rc) { dprintk(CVP_ERR, "Failed to init reset clocks\n"); dprintk(CVP_ERR, "Failed to init reset clocks\n"); rc = -ENODEV; rc = -ENODEV; Loading Loading @@ -3916,7 +3932,6 @@ static int __iris_power_on(struct iris_hfi_device *device) if (device->power_enabled) if (device->power_enabled) return 0; return 0; device->power_enabled = true; /* Vote for all hardware resources */ /* Vote for all hardware resources */ rc = __vote_buses(device, device->bus_vote.data, rc = __vote_buses(device, device->bus_vote.data, device->bus_vote.data_count); device->bus_vote.data_count); Loading Loading @@ -3950,6 +3965,9 @@ static int __iris_power_on(struct iris_hfi_device *device) rc = 0; rc = 0; } } /*Do not access registers before this point!*/ device->power_enabled = true; dprintk(CVP_DBG, "Done with scaling\n"); dprintk(CVP_DBG, "Done with scaling\n"); /* /* * Re-program all of the registers that get reset as a result of * Re-program all of the registers that get reset as a result of Loading Loading @@ -4083,23 +4101,8 @@ static void power_off_iris2(struct iris_hfi_device *device) /* HPG 6.1.2 Step 3, debug bridge to low power */ /* HPG 6.1.2 Step 3, debug bridge to low power */ __write_register(device, __write_register(device, CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); reg_status = 0; count = 0; while ((reg_status != 0x7) && count < max_count) { lpi_status = __read_register(device, CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); reg_status = lpi_status & 0x7; /* Wait for debug bridge lpi status to be set */ usleep_range(50, 100); usleep_range(50, 100); count++; } dprintk(CVP_DBG, "DBLP Set : lpi_status %d reg_status %d (count %d)\n", lpi_status, reg_status, count); if (count == max_count) { dprintk(CVP_WARN, "DBLP Set: status %x %x\n", reg_status, lpi_status); } /* HPG 6.1.2 Step 4, debug bridge to lpi release */ /* HPG 6.1.2 Step 4, debug bridge to lpi release */ __write_register(device, __write_register(device, Loading @@ -4119,6 +4122,10 @@ static void power_off_iris2(struct iris_hfi_device *device) dprintk(CVP_WARN, dprintk(CVP_WARN, "DBLP Release: lpi_status %x\n", lpi_status); "DBLP Release: lpi_status %x\n", lpi_status); } } /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) dprintk(CVP_WARN, "Failed to disable regulators\n"); /* HPG 6.1.2 Step 6 */ /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); __disable_unprepare_clks(device); Loading @@ -4127,12 +4134,10 @@ static void power_off_iris2(struct iris_hfi_device *device) if (call_iris_op(device, reset_ahb2axi_bridge, device)) if (call_iris_op(device, reset_ahb2axi_bridge, device)) dprintk(CVP_ERR, "Failed to reset ahb2axi\n"); dprintk(CVP_ERR, "Failed to reset ahb2axi\n"); /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) dprintk(CVP_WARN, "Failed to disable regulators\n"); if (__unvote_buses(device)) if (__unvote_buses(device)) dprintk(CVP_WARN, "Failed to unvote for buses\n"); dprintk(CVP_WARN, "Failed to unvote for buses\n"); /*Do not access registers after this point!*/ device->power_enabled = false; device->power_enabled = false; } } Loading drivers/media/platform/msm/cvp/msm_cvp_common.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -38,4 +38,5 @@ void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct cvp_kmd_buffer *cbuf); struct msm_cvp_inst *inst, struct cvp_kmd_buffer *cbuf); void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem); struct msm_cvp_smem *smem); int msm_cvp_noc_error_info(struct msm_cvp_core *core); #endif #endif drivers/media/platform/msm/cvp/msm_cvp_platform.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -108,7 +108,7 @@ static struct msm_cvp_common_data sm8350_common_data[] = { }, }, { { .key = "qcom,sw-power-collapse", .key = "qcom,sw-power-collapse", .value = 0, .value = 1, }, }, { { .key = "qcom,domain-attr-non-fatal-faults", .key = "qcom,domain-attr-non-fatal-faults", Loading drivers/media/platform/msm/cvp/msm_cvp_res_parse.c +16 −3 Original line number Original line Diff line number Diff line Loading @@ -626,17 +626,20 @@ static int msm_cvp_load_clock_table( return rc; return rc; } } #define MAX_CLK_RESETS 5 static int msm_cvp_load_reset_table( static int msm_cvp_load_reset_table( struct msm_cvp_platform_resources *res) struct msm_cvp_platform_resources *res) { { struct platform_device *pdev = res->pdev; struct platform_device *pdev = res->pdev; struct reset_set *rst = &res->reset_set; struct reset_set *rst = &res->reset_set; int num_clocks = 0, c = 0; int num_clocks = 0, c = 0, ret = 0; int pwr_stats[MAX_CLK_RESETS]; num_clocks = of_property_count_strings(pdev->dev.of_node, num_clocks = of_property_count_strings(pdev->dev.of_node, "reset-names"); "reset-names"); if (num_clocks <= 0) { if (num_clocks <= 0 || num_clocks > MAX_CLK_RESETS) { dprintk(CVP_DBG, "No reset clocks found\n"); dprintk(CVP_ERR, "Num reset clocks out of range\n"); rst->count = 0; rst->count = 0; return 0; return 0; } } Loading @@ -648,12 +651,21 @@ static int msm_cvp_load_reset_table( rst->count = num_clocks; rst->count = num_clocks; dprintk(CVP_DBG, "Found %d reset clocks\n", num_clocks); dprintk(CVP_DBG, "Found %d reset clocks\n", num_clocks); ret = of_property_read_u32_array(pdev->dev.of_node, "reset-power-status", pwr_stats, num_clocks); if (ret) { dprintk(CVP_ERR, "Failed to read reset pwr state: %d\n", ret); devm_kfree(&pdev->dev, rst->reset_tbl); return ret; } for (c = 0; c < num_clocks; ++c) { for (c = 0; c < num_clocks; ++c) { struct reset_info *rc = &res->reset_set.reset_tbl[c]; struct reset_info *rc = &res->reset_set.reset_tbl[c]; of_property_read_string_index(pdev->dev.of_node, of_property_read_string_index(pdev->dev.of_node, "reset-names", c, &rc->name); "reset-names", c, &rc->name); rc->required_state = pwr_stats[c]; } } return 0; return 0; Loading Loading @@ -895,6 +907,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, msm_cvp_comm_print_inst_info(inst); msm_cvp_comm_print_inst_info(inst); } } core->smmu_fault_handled = true; core->smmu_fault_handled = true; msm_cvp_noc_error_info(core); mutex_unlock(&core->lock); mutex_unlock(&core->lock); /* /* * Return -EINVAL to elicit the default behaviour of smmu driver. * Return -EINVAL to elicit the default behaviour of smmu driver. Loading drivers/media/platform/msm/cvp/msm_cvp_resources.h +8 −0 Original line number Original line Diff line number Diff line Loading @@ -83,8 +83,16 @@ struct bus_set { u32 count; u32 count; }; }; enum power_state { CVP_POWER_INIT, CVP_POWER_ON, CVP_POWER_OFF, CVP_POWER_INVALID, }; struct reset_info { struct reset_info { struct reset_control *rst; struct reset_control *rst; enum power_state required_state; const char *name; const char *name; }; }; Loading Loading
drivers/media/platform/msm/cvp/cvp_hfi.c +34 −29 Original line number Original line Diff line number Diff line Loading @@ -3213,18 +3213,21 @@ static inline int __init_clocks(struct iris_hfi_device *device) } } static int __handle_reset_clk(struct msm_cvp_platform_resources *res, static int __handle_reset_clk(struct msm_cvp_platform_resources *res, int reset_index, enum reset_state state) int reset_index, enum reset_state state, enum power_state pwr_state) { { int rc = 0; int rc = 0; struct reset_control *rst; struct reset_control *rst; struct reset_info rst_info; struct reset_set *rst_set = &res->reset_set; struct reset_set *rst_set = &res->reset_set; if (!rst_set->reset_tbl) if (!rst_set->reset_tbl) return 0; return 0; rst = rst_set->reset_tbl[reset_index].rst; rst_info = rst_set->reset_tbl[reset_index]; dprintk(CVP_DBG, "reset_clk: name %s reset_state %d rst %pK\n", rst = rst_info.rst; rst_set->reset_tbl[reset_index].name, state, rst); dprintk(CVP_DBG, "reset_clk: name %s reset_state %d rst %pK ps=%d\n", rst_set->reset_tbl[reset_index].name, state, rst, pwr_state); switch (state) { switch (state) { case INIT: case INIT: Loading @@ -3244,6 +3247,9 @@ static int __handle_reset_clk(struct msm_cvp_platform_resources *res, goto failed_to_reset; goto failed_to_reset; } } if (pwr_state != rst_info.required_state) break; rc = reset_control_assert(rst); rc = reset_control_assert(rst); break; break; case DEASSERT: case DEASSERT: Loading @@ -3251,6 +3257,10 @@ static int __handle_reset_clk(struct msm_cvp_platform_resources *res, rc = PTR_ERR(rst); rc = PTR_ERR(rst); goto failed_to_reset; goto failed_to_reset; } } if (pwr_state != rst_info.required_state) break; rc = reset_control_deassert(rst); rc = reset_control_deassert(rst); break; break; default: default: Loading Loading @@ -3285,6 +3295,7 @@ static inline void __disable_unprepare_clks(struct iris_hfi_device *device) static int reset_ahb2axi_bridge(struct iris_hfi_device *device) static int reset_ahb2axi_bridge(struct iris_hfi_device *device) { { int rc, i; int rc, i; enum power_state s; if (!device) { if (!device) { dprintk(CVP_ERR, "NULL device\n"); dprintk(CVP_ERR, "NULL device\n"); Loading @@ -3292,8 +3303,13 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) goto failed_to_reset; goto failed_to_reset; } } if (device->power_enabled) s = CVP_POWER_ON; else s = CVP_POWER_OFF; for (i = 0; i < device->res->reset_set.count; i++) { for (i = 0; i < device->res->reset_set.count; i++) { rc = __handle_reset_clk(device->res, i, ASSERT); rc = __handle_reset_clk(device->res, i, ASSERT, s); if (rc) { if (rc) { dprintk(CVP_ERR, dprintk(CVP_ERR, "failed to assert reset clocks\n"); "failed to assert reset clocks\n"); Loading @@ -3303,7 +3319,7 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) /* wait for deassert */ /* wait for deassert */ usleep_range(150, 250); usleep_range(150, 250); rc = __handle_reset_clk(device->res, i, DEASSERT); rc = __handle_reset_clk(device->res, i, DEASSERT, s); if (rc) { if (rc) { dprintk(CVP_ERR, dprintk(CVP_ERR, "failed to deassert reset clocks\n"); "failed to deassert reset clocks\n"); Loading Loading @@ -3534,7 +3550,7 @@ static int __init_resources(struct iris_hfi_device *device, } } for (i = 0; i < device->res->reset_set.count; i++) { for (i = 0; i < device->res->reset_set.count; i++) { rc = __handle_reset_clk(res, i, INIT); rc = __handle_reset_clk(res, i, INIT, 0); if (rc) { if (rc) { dprintk(CVP_ERR, "Failed to init reset clocks\n"); dprintk(CVP_ERR, "Failed to init reset clocks\n"); rc = -ENODEV; rc = -ENODEV; Loading Loading @@ -3916,7 +3932,6 @@ static int __iris_power_on(struct iris_hfi_device *device) if (device->power_enabled) if (device->power_enabled) return 0; return 0; device->power_enabled = true; /* Vote for all hardware resources */ /* Vote for all hardware resources */ rc = __vote_buses(device, device->bus_vote.data, rc = __vote_buses(device, device->bus_vote.data, device->bus_vote.data_count); device->bus_vote.data_count); Loading Loading @@ -3950,6 +3965,9 @@ static int __iris_power_on(struct iris_hfi_device *device) rc = 0; rc = 0; } } /*Do not access registers before this point!*/ device->power_enabled = true; dprintk(CVP_DBG, "Done with scaling\n"); dprintk(CVP_DBG, "Done with scaling\n"); /* /* * Re-program all of the registers that get reset as a result of * Re-program all of the registers that get reset as a result of Loading Loading @@ -4083,23 +4101,8 @@ static void power_off_iris2(struct iris_hfi_device *device) /* HPG 6.1.2 Step 3, debug bridge to low power */ /* HPG 6.1.2 Step 3, debug bridge to low power */ __write_register(device, __write_register(device, CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); reg_status = 0; count = 0; while ((reg_status != 0x7) && count < max_count) { lpi_status = __read_register(device, CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); reg_status = lpi_status & 0x7; /* Wait for debug bridge lpi status to be set */ usleep_range(50, 100); usleep_range(50, 100); count++; } dprintk(CVP_DBG, "DBLP Set : lpi_status %d reg_status %d (count %d)\n", lpi_status, reg_status, count); if (count == max_count) { dprintk(CVP_WARN, "DBLP Set: status %x %x\n", reg_status, lpi_status); } /* HPG 6.1.2 Step 4, debug bridge to lpi release */ /* HPG 6.1.2 Step 4, debug bridge to lpi release */ __write_register(device, __write_register(device, Loading @@ -4119,6 +4122,10 @@ static void power_off_iris2(struct iris_hfi_device *device) dprintk(CVP_WARN, dprintk(CVP_WARN, "DBLP Release: lpi_status %x\n", lpi_status); "DBLP Release: lpi_status %x\n", lpi_status); } } /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) dprintk(CVP_WARN, "Failed to disable regulators\n"); /* HPG 6.1.2 Step 6 */ /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); __disable_unprepare_clks(device); Loading @@ -4127,12 +4134,10 @@ static void power_off_iris2(struct iris_hfi_device *device) if (call_iris_op(device, reset_ahb2axi_bridge, device)) if (call_iris_op(device, reset_ahb2axi_bridge, device)) dprintk(CVP_ERR, "Failed to reset ahb2axi\n"); dprintk(CVP_ERR, "Failed to reset ahb2axi\n"); /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) dprintk(CVP_WARN, "Failed to disable regulators\n"); if (__unvote_buses(device)) if (__unvote_buses(device)) dprintk(CVP_WARN, "Failed to unvote for buses\n"); dprintk(CVP_WARN, "Failed to unvote for buses\n"); /*Do not access registers after this point!*/ device->power_enabled = false; device->power_enabled = false; } } Loading
drivers/media/platform/msm/cvp/msm_cvp_common.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -38,4 +38,5 @@ void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct cvp_kmd_buffer *cbuf); struct msm_cvp_inst *inst, struct cvp_kmd_buffer *cbuf); void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem); struct msm_cvp_smem *smem); int msm_cvp_noc_error_info(struct msm_cvp_core *core); #endif #endif
drivers/media/platform/msm/cvp/msm_cvp_platform.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -108,7 +108,7 @@ static struct msm_cvp_common_data sm8350_common_data[] = { }, }, { { .key = "qcom,sw-power-collapse", .key = "qcom,sw-power-collapse", .value = 0, .value = 1, }, }, { { .key = "qcom,domain-attr-non-fatal-faults", .key = "qcom,domain-attr-non-fatal-faults", Loading
drivers/media/platform/msm/cvp/msm_cvp_res_parse.c +16 −3 Original line number Original line Diff line number Diff line Loading @@ -626,17 +626,20 @@ static int msm_cvp_load_clock_table( return rc; return rc; } } #define MAX_CLK_RESETS 5 static int msm_cvp_load_reset_table( static int msm_cvp_load_reset_table( struct msm_cvp_platform_resources *res) struct msm_cvp_platform_resources *res) { { struct platform_device *pdev = res->pdev; struct platform_device *pdev = res->pdev; struct reset_set *rst = &res->reset_set; struct reset_set *rst = &res->reset_set; int num_clocks = 0, c = 0; int num_clocks = 0, c = 0, ret = 0; int pwr_stats[MAX_CLK_RESETS]; num_clocks = of_property_count_strings(pdev->dev.of_node, num_clocks = of_property_count_strings(pdev->dev.of_node, "reset-names"); "reset-names"); if (num_clocks <= 0) { if (num_clocks <= 0 || num_clocks > MAX_CLK_RESETS) { dprintk(CVP_DBG, "No reset clocks found\n"); dprintk(CVP_ERR, "Num reset clocks out of range\n"); rst->count = 0; rst->count = 0; return 0; return 0; } } Loading @@ -648,12 +651,21 @@ static int msm_cvp_load_reset_table( rst->count = num_clocks; rst->count = num_clocks; dprintk(CVP_DBG, "Found %d reset clocks\n", num_clocks); dprintk(CVP_DBG, "Found %d reset clocks\n", num_clocks); ret = of_property_read_u32_array(pdev->dev.of_node, "reset-power-status", pwr_stats, num_clocks); if (ret) { dprintk(CVP_ERR, "Failed to read reset pwr state: %d\n", ret); devm_kfree(&pdev->dev, rst->reset_tbl); return ret; } for (c = 0; c < num_clocks; ++c) { for (c = 0; c < num_clocks; ++c) { struct reset_info *rc = &res->reset_set.reset_tbl[c]; struct reset_info *rc = &res->reset_set.reset_tbl[c]; of_property_read_string_index(pdev->dev.of_node, of_property_read_string_index(pdev->dev.of_node, "reset-names", c, &rc->name); "reset-names", c, &rc->name); rc->required_state = pwr_stats[c]; } } return 0; return 0; Loading Loading @@ -895,6 +907,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, msm_cvp_comm_print_inst_info(inst); msm_cvp_comm_print_inst_info(inst); } } core->smmu_fault_handled = true; core->smmu_fault_handled = true; msm_cvp_noc_error_info(core); mutex_unlock(&core->lock); mutex_unlock(&core->lock); /* /* * Return -EINVAL to elicit the default behaviour of smmu driver. * Return -EINVAL to elicit the default behaviour of smmu driver. Loading
drivers/media/platform/msm/cvp/msm_cvp_resources.h +8 −0 Original line number Original line Diff line number Diff line Loading @@ -83,8 +83,16 @@ struct bus_set { u32 count; u32 count; }; }; enum power_state { CVP_POWER_INIT, CVP_POWER_ON, CVP_POWER_OFF, CVP_POWER_INVALID, }; struct reset_info { struct reset_info { struct reset_control *rst; struct reset_control *rst; enum power_state required_state; const char *name; const char *name; }; }; Loading