Loading drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +58 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,13 @@ static inline void msm_vidc_free_clock_table( res->clock_set.count = 0; } static inline void msm_vidc_free_cx_ipeak_context( struct msm_vidc_platform_resources *res) { cx_ipeak_unregister(res->cx_ipeak_context); res->cx_ipeak_context = NULL; } void msm_vidc_free_platform_resources( struct msm_vidc_platform_resources *res) { Loading @@ -132,6 +139,7 @@ void msm_vidc_free_platform_resources( msm_vidc_free_qdss_addr_table(res); msm_vidc_free_bus_vectors(res); msm_vidc_free_buffer_usage_table(res); msm_vidc_free_cx_ipeak_context(res); } static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) Loading Loading @@ -804,6 +812,48 @@ int read_platform_resources_from_drv_data( } static int msm_vidc_populate_cx_ipeak_context( struct msm_vidc_platform_resources *res) { struct platform_device *pdev = res->pdev; int rc = 0; if (of_find_property(pdev->dev.of_node, "qcom,cx-ipeak-data", NULL)) { res->cx_ipeak_context = cx_ipeak_register( pdev->dev.of_node, "qcom,cx-ipeak-data"); } if (IS_ERR(res->cx_ipeak_context)) { rc = PTR_ERR(res->cx_ipeak_context); if (rc == -EPROBE_DEFER) dprintk(VIDC_INFO, "cx-ipeak register failed. Deferring probe!"); else dprintk(VIDC_ERR, "cx-ipeak register failed. rc: %d", rc); res->cx_ipeak_context = NULL; goto err_cx_ipeak; } if (res->cx_ipeak_context) dprintk(VIDC_INFO, "cx-ipeak register successful"); else dprintk(VIDC_INFO, "cx-ipeak register not implemented"); of_property_read_u32(pdev->dev.of_node, "qcom,clock-freq-threshold", &res->clk_freq_threshold); dprintk(VIDC_DBG, "cx ipeak threshold frequency = %u\n", res->clk_freq_threshold); return rc; err_cx_ipeak: return rc; } int read_platform_resources_from_dt( struct msm_vidc_platform_resources *res) { Loading Loading @@ -892,8 +942,16 @@ int read_platform_resources_from_dt( "Using fw-bias : %pa", &res->firmware_base); } rc = msm_vidc_populate_cx_ipeak_context(res); if (rc) { dprintk(VIDC_ERR, "Failed to setup cx-ipeak %d\n", rc); goto err_register_cx_ipeak; } return rc; err_register_cx_ipeak: err_setup_legacy_cb: msm_vidc_free_allowed_clocks_table(res); err_load_allowed_clocks_table: Loading drivers/media/platform/msm/vidc/msm_vidc_resources.h +3 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include "msm_vidc.h" #include <linux/soc/qcom/llcc-qcom.h> #include "soc/qcom/cx_ipeak.h" #define MAX_BUFFER_TYPES 32 Loading Loading @@ -200,6 +201,8 @@ struct msm_vidc_platform_resources { struct msm_vidc_mem_cdsp mem_cdsp; uint32_t vpu_ver; uint32_t fw_cycles; uint32_t clk_freq_threshold; struct cx_ipeak_client *cx_ipeak_context; }; static inline bool is_iommu_present(struct msm_vidc_platform_resources *res) Loading drivers/media/platform/msm/vidc/venus_hfi.c +48 −8 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <linux/workqueue.h> #include <linux/platform_device.h> #include <linux/soc/qcom/llcc-qcom.h> #include <soc/qcom/cx_ipeak.h> #include <soc/qcom/scm.h> #include <soc/qcom/socinfo.h> #include <linux/soc/qcom/smem.h> Loading Loading @@ -1383,6 +1384,49 @@ static enum hal_default_properties venus_hfi_get_default_properties(void *dev) return prop; } static int __set_clk_rate(struct venus_hfi_device *device, struct clock_info *cl, u64 rate) { int rc = 0; u64 threshold_freq = device->res->clk_freq_threshold; struct cx_ipeak_client *ipeak = device->res->cx_ipeak_context; struct clk *clk = cl->clk; if (device->clk_freq < threshold_freq && rate >= threshold_freq) { rc = cx_ipeak_update(ipeak, true); if (rc) { dprintk(VIDC_ERR, "cx_ipeak_update failed! ipeak %pK\n", ipeak); return rc; } dprintk(VIDC_PROF, "cx_ipeak_update: up, clk freq = %lu\n", device->clk_freq); } rc = clk_set_rate(clk, rate); if (rc) { dprintk(VIDC_ERR, "%s: Failed to set clock rate %llu %s: %d\n", __func__, rate, cl->name, rc); return rc; } device->clk_freq = rate; if (device->clk_freq >= threshold_freq && rate < threshold_freq) { rc = cx_ipeak_update(ipeak, false); if (rc) { dprintk(VIDC_ERR, "cx_ipeak_update failed! ipeak %pK\n", ipeak); return rc; } dprintk(VIDC_PROF, "cx_ipeak_update: down, clk freq = %lu\n", device->clk_freq); } return rc; } static int __set_clocks(struct venus_hfi_device *device, u32 freq) { struct clock_info *cl; Loading @@ -1390,14 +1434,9 @@ static int __set_clocks(struct venus_hfi_device *device, u32 freq) venus_hfi_for_each_clock(device, cl) { if (cl->has_scaling) {/* has_scaling */ device->clk_freq = freq; rc = clk_set_rate(cl->clk, freq); if (rc) { dprintk(VIDC_ERR, "Failed to set clock rate %u %s: %d %s\n", freq, cl->name, rc, __func__); rc = __set_clk_rate(device, cl, freq); if (rc) return rc; } trace_msm_vidc_perf_clock_scale(cl->name, freq); dprintk(VIDC_PROF, "Scaling clock %s to %u\n", Loading Loading @@ -3956,7 +3995,8 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) * it to the lowest frequency possible */ if (cl->has_scaling) clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); __set_clk_rate(device, cl, clk_round_rate(cl->clk, 0)); rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); if (rc) { Loading Loading
drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +58 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,13 @@ static inline void msm_vidc_free_clock_table( res->clock_set.count = 0; } static inline void msm_vidc_free_cx_ipeak_context( struct msm_vidc_platform_resources *res) { cx_ipeak_unregister(res->cx_ipeak_context); res->cx_ipeak_context = NULL; } void msm_vidc_free_platform_resources( struct msm_vidc_platform_resources *res) { Loading @@ -132,6 +139,7 @@ void msm_vidc_free_platform_resources( msm_vidc_free_qdss_addr_table(res); msm_vidc_free_bus_vectors(res); msm_vidc_free_buffer_usage_table(res); msm_vidc_free_cx_ipeak_context(res); } static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) Loading Loading @@ -804,6 +812,48 @@ int read_platform_resources_from_drv_data( } static int msm_vidc_populate_cx_ipeak_context( struct msm_vidc_platform_resources *res) { struct platform_device *pdev = res->pdev; int rc = 0; if (of_find_property(pdev->dev.of_node, "qcom,cx-ipeak-data", NULL)) { res->cx_ipeak_context = cx_ipeak_register( pdev->dev.of_node, "qcom,cx-ipeak-data"); } if (IS_ERR(res->cx_ipeak_context)) { rc = PTR_ERR(res->cx_ipeak_context); if (rc == -EPROBE_DEFER) dprintk(VIDC_INFO, "cx-ipeak register failed. Deferring probe!"); else dprintk(VIDC_ERR, "cx-ipeak register failed. rc: %d", rc); res->cx_ipeak_context = NULL; goto err_cx_ipeak; } if (res->cx_ipeak_context) dprintk(VIDC_INFO, "cx-ipeak register successful"); else dprintk(VIDC_INFO, "cx-ipeak register not implemented"); of_property_read_u32(pdev->dev.of_node, "qcom,clock-freq-threshold", &res->clk_freq_threshold); dprintk(VIDC_DBG, "cx ipeak threshold frequency = %u\n", res->clk_freq_threshold); return rc; err_cx_ipeak: return rc; } int read_platform_resources_from_dt( struct msm_vidc_platform_resources *res) { Loading Loading @@ -892,8 +942,16 @@ int read_platform_resources_from_dt( "Using fw-bias : %pa", &res->firmware_base); } rc = msm_vidc_populate_cx_ipeak_context(res); if (rc) { dprintk(VIDC_ERR, "Failed to setup cx-ipeak %d\n", rc); goto err_register_cx_ipeak; } return rc; err_register_cx_ipeak: err_setup_legacy_cb: msm_vidc_free_allowed_clocks_table(res); err_load_allowed_clocks_table: Loading
drivers/media/platform/msm/vidc/msm_vidc_resources.h +3 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include "msm_vidc.h" #include <linux/soc/qcom/llcc-qcom.h> #include "soc/qcom/cx_ipeak.h" #define MAX_BUFFER_TYPES 32 Loading Loading @@ -200,6 +201,8 @@ struct msm_vidc_platform_resources { struct msm_vidc_mem_cdsp mem_cdsp; uint32_t vpu_ver; uint32_t fw_cycles; uint32_t clk_freq_threshold; struct cx_ipeak_client *cx_ipeak_context; }; static inline bool is_iommu_present(struct msm_vidc_platform_resources *res) Loading
drivers/media/platform/msm/vidc/venus_hfi.c +48 −8 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <linux/workqueue.h> #include <linux/platform_device.h> #include <linux/soc/qcom/llcc-qcom.h> #include <soc/qcom/cx_ipeak.h> #include <soc/qcom/scm.h> #include <soc/qcom/socinfo.h> #include <linux/soc/qcom/smem.h> Loading Loading @@ -1383,6 +1384,49 @@ static enum hal_default_properties venus_hfi_get_default_properties(void *dev) return prop; } static int __set_clk_rate(struct venus_hfi_device *device, struct clock_info *cl, u64 rate) { int rc = 0; u64 threshold_freq = device->res->clk_freq_threshold; struct cx_ipeak_client *ipeak = device->res->cx_ipeak_context; struct clk *clk = cl->clk; if (device->clk_freq < threshold_freq && rate >= threshold_freq) { rc = cx_ipeak_update(ipeak, true); if (rc) { dprintk(VIDC_ERR, "cx_ipeak_update failed! ipeak %pK\n", ipeak); return rc; } dprintk(VIDC_PROF, "cx_ipeak_update: up, clk freq = %lu\n", device->clk_freq); } rc = clk_set_rate(clk, rate); if (rc) { dprintk(VIDC_ERR, "%s: Failed to set clock rate %llu %s: %d\n", __func__, rate, cl->name, rc); return rc; } device->clk_freq = rate; if (device->clk_freq >= threshold_freq && rate < threshold_freq) { rc = cx_ipeak_update(ipeak, false); if (rc) { dprintk(VIDC_ERR, "cx_ipeak_update failed! ipeak %pK\n", ipeak); return rc; } dprintk(VIDC_PROF, "cx_ipeak_update: down, clk freq = %lu\n", device->clk_freq); } return rc; } static int __set_clocks(struct venus_hfi_device *device, u32 freq) { struct clock_info *cl; Loading @@ -1390,14 +1434,9 @@ static int __set_clocks(struct venus_hfi_device *device, u32 freq) venus_hfi_for_each_clock(device, cl) { if (cl->has_scaling) {/* has_scaling */ device->clk_freq = freq; rc = clk_set_rate(cl->clk, freq); if (rc) { dprintk(VIDC_ERR, "Failed to set clock rate %u %s: %d %s\n", freq, cl->name, rc, __func__); rc = __set_clk_rate(device, cl, freq); if (rc) return rc; } trace_msm_vidc_perf_clock_scale(cl->name, freq); dprintk(VIDC_PROF, "Scaling clock %s to %u\n", Loading Loading @@ -3956,7 +3995,8 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) * it to the lowest frequency possible */ if (cl->has_scaling) clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); __set_clk_rate(device, cl, clk_round_rate(cl->clk, 0)); rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); if (rc) { Loading