Loading Documentation/devicetree/bindings/media/video/msm-vidc.txt +7 −1 Original line number Diff line number Diff line Loading @@ -135,6 +135,12 @@ value is typically max(latencies of every cluster at all power levels) + 1 - qcom,power-conf = Indicates the value at which or beyond, a video session is configured in low power mode to have power benefits. Value is defined interms of HxW of the video session beyond which power benefit is desired. - qcom,cx-ipeak-data : phandle of cx_ipeak device node and bit position on the cx register where venus is supposed to vote - qcom,clock-freq-threshold : Operating threshold frequency of venus which video driver uses to check against the frequency voted. Whenever venus clock frequency crosses this mark, driver intimates cx ipeak driver on supported targets. [Second level nodes] Context Banks Loading drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +31 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "msm_vidc_res_parse.h" #include "venus_boot.h" #include "soc/qcom/secure_buffer.h" #include "soc/qcom/cx_ipeak.h" enum clock_properties { CLOCK_PROP_HAS_SCALING = 1 << 0, Loading Loading @@ -171,6 +172,8 @@ 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); cx_ipeak_unregister(res->cx_ipeak_context); res->cx_ipeak_context = NULL; } static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) Loading Loading @@ -1133,8 +1136,36 @@ int read_platform_resources_from_dt( of_property_read_u32(pdev->dev.of_node, "qcom,max-secure-instances", &res->max_secure_inst_count); 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_register_cx_ipeak; } else 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_register_cx_ipeak: err_setup_legacy_cb: err_load_max_hw_load: msm_vidc_free_allowed_clocks_table(res); Loading drivers/media/platform/msm/vidc/msm_vidc_resources.h +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/devfreq.h> #include <linux/platform_device.h> #include <media/msm_vidc.h> #include "soc/qcom/cx_ipeak.h" #define MAX_BUFFER_TYPES 32 struct platform_version_table { Loading Loading @@ -191,6 +192,8 @@ struct msm_vidc_platform_resources { uint32_t pm_qos_latency_us; uint32_t max_inst_count; uint32_t max_secure_inst_count; 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 +43 −15 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/workqueue.h> #include <soc/qcom/cx_ipeak.h> #include <soc/qcom/scm.h> #include <soc/qcom/smem.h> #include <soc/qcom/subsystem_restart.h> Loading Loading @@ -1385,6 +1386,39 @@ static int __halt_axi(struct venus_hfi_device *device) return rc; } static int __set_clk_rate(struct venus_hfi_device *device, struct clock_info *cl, u64 rate) { int rc = 0, rc1 = 0; u64 toggle_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 < toggle_freq && rate >= toggle_freq) { rc1 = cx_ipeak_update(ipeak, true); dprintk(VIDC_PROF, "Voting up: %d\n", rc); } 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); if (device->clk_freq >= toggle_freq && rate < toggle_freq) { rc1 = cx_ipeak_update(ipeak, false); dprintk(VIDC_PROF, "Voting down: %d\n", rc); } if (rc1) dprintk(VIDC_ERR, "cx_ipeak_update failed! ipeak %pK\n", ipeak); if (!rc) device->clk_freq = rate; return rc; } static int __scale_clocks_cycles_per_mb(struct venus_hfi_device *device, struct vidc_clk_scale_data *data, unsigned long instant_bitrate) { Loading Loading @@ -1458,14 +1492,10 @@ get_clock_freq: if (!cl->has_scaling) continue; device->clk_freq = rate; rc = clk_set_rate(cl->clk, rate); if (rc) { dprintk(VIDC_ERR, "%s: Failed to set clock rate %llu %s: %d\n", __func__, rate, cl->name, rc); rc = __set_clk_rate(device, cl, rate); if (rc) return rc; } if (!strcmp(cl->name, "core_clk")) device->scaled_rate = rate; Loading Loading @@ -1506,14 +1536,11 @@ static int __scale_clocks_load(struct venus_hfi_device *device, int load, load, data, instant_bitrate); } device->clk_freq = rate; rc = clk_set_rate(cl->clk, rate); if (rc) { dprintk(VIDC_ERR, "Failed to set clock rate %lu %s: %d\n", rate, cl->name, rc); rc = __set_clk_rate(device, cl, rate); if (rc) return rc; } if (!strcmp(cl->name, "core_clk")) device->scaled_rate = rate; Loading Loading @@ -3794,7 +3821,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)); if (cl->has_mem_retention) { rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_PERIPH); Loading Loading
Documentation/devicetree/bindings/media/video/msm-vidc.txt +7 −1 Original line number Diff line number Diff line Loading @@ -135,6 +135,12 @@ value is typically max(latencies of every cluster at all power levels) + 1 - qcom,power-conf = Indicates the value at which or beyond, a video session is configured in low power mode to have power benefits. Value is defined interms of HxW of the video session beyond which power benefit is desired. - qcom,cx-ipeak-data : phandle of cx_ipeak device node and bit position on the cx register where venus is supposed to vote - qcom,clock-freq-threshold : Operating threshold frequency of venus which video driver uses to check against the frequency voted. Whenever venus clock frequency crosses this mark, driver intimates cx ipeak driver on supported targets. [Second level nodes] Context Banks Loading
drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +31 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "msm_vidc_res_parse.h" #include "venus_boot.h" #include "soc/qcom/secure_buffer.h" #include "soc/qcom/cx_ipeak.h" enum clock_properties { CLOCK_PROP_HAS_SCALING = 1 << 0, Loading Loading @@ -171,6 +172,8 @@ 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); cx_ipeak_unregister(res->cx_ipeak_context); res->cx_ipeak_context = NULL; } static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) Loading Loading @@ -1133,8 +1136,36 @@ int read_platform_resources_from_dt( of_property_read_u32(pdev->dev.of_node, "qcom,max-secure-instances", &res->max_secure_inst_count); 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_register_cx_ipeak; } else 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_register_cx_ipeak: err_setup_legacy_cb: err_load_max_hw_load: msm_vidc_free_allowed_clocks_table(res); Loading
drivers/media/platform/msm/vidc/msm_vidc_resources.h +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/devfreq.h> #include <linux/platform_device.h> #include <media/msm_vidc.h> #include "soc/qcom/cx_ipeak.h" #define MAX_BUFFER_TYPES 32 struct platform_version_table { Loading Loading @@ -191,6 +192,8 @@ struct msm_vidc_platform_resources { uint32_t pm_qos_latency_us; uint32_t max_inst_count; uint32_t max_secure_inst_count; 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 +43 −15 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/workqueue.h> #include <soc/qcom/cx_ipeak.h> #include <soc/qcom/scm.h> #include <soc/qcom/smem.h> #include <soc/qcom/subsystem_restart.h> Loading Loading @@ -1385,6 +1386,39 @@ static int __halt_axi(struct venus_hfi_device *device) return rc; } static int __set_clk_rate(struct venus_hfi_device *device, struct clock_info *cl, u64 rate) { int rc = 0, rc1 = 0; u64 toggle_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 < toggle_freq && rate >= toggle_freq) { rc1 = cx_ipeak_update(ipeak, true); dprintk(VIDC_PROF, "Voting up: %d\n", rc); } 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); if (device->clk_freq >= toggle_freq && rate < toggle_freq) { rc1 = cx_ipeak_update(ipeak, false); dprintk(VIDC_PROF, "Voting down: %d\n", rc); } if (rc1) dprintk(VIDC_ERR, "cx_ipeak_update failed! ipeak %pK\n", ipeak); if (!rc) device->clk_freq = rate; return rc; } static int __scale_clocks_cycles_per_mb(struct venus_hfi_device *device, struct vidc_clk_scale_data *data, unsigned long instant_bitrate) { Loading Loading @@ -1458,14 +1492,10 @@ get_clock_freq: if (!cl->has_scaling) continue; device->clk_freq = rate; rc = clk_set_rate(cl->clk, rate); if (rc) { dprintk(VIDC_ERR, "%s: Failed to set clock rate %llu %s: %d\n", __func__, rate, cl->name, rc); rc = __set_clk_rate(device, cl, rate); if (rc) return rc; } if (!strcmp(cl->name, "core_clk")) device->scaled_rate = rate; Loading Loading @@ -1506,14 +1536,11 @@ static int __scale_clocks_load(struct venus_hfi_device *device, int load, load, data, instant_bitrate); } device->clk_freq = rate; rc = clk_set_rate(cl->clk, rate); if (rc) { dprintk(VIDC_ERR, "Failed to set clock rate %lu %s: %d\n", rate, cl->name, rc); rc = __set_clk_rate(device, cl, rate); if (rc) return rc; } if (!strcmp(cl->name, "core_clk")) device->scaled_rate = rate; Loading Loading @@ -3794,7 +3821,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)); if (cl->has_mem_retention) { rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_PERIPH); Loading