diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 3e4e5d40c760..4995f45a5376 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include "hfi_common.h" @@ -1105,8 +1105,21 @@ static int __set_clk_rate(struct venus_hfi_device *device, struct clock_info *cl, u64 rate, u32 sid) { 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 (ipeak && device->clk_freq < threshold_freq && rate >= threshold_freq) { + rc = cx_ipeak_update(ipeak, true); + if (rc) { + s_vpr_e(sid, "%s: cx_ipeak_update failed!\n", __func__); + return rc; + } + s_vpr_p(sid, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); + } + rc = clk_set_rate(clk, rate); if (rc) { s_vpr_e(sid, @@ -1115,6 +1128,19 @@ static int __set_clk_rate(struct venus_hfi_device *device, return rc; } + if (ipeak && device->clk_freq >= threshold_freq && rate < threshold_freq) { + rc = cx_ipeak_update(ipeak, false); + if (rc) { + s_vpr_e(sid, + "cx_ipeak_update failed! ipeak %pK\n", ipeak); + device->clk_freq = rate; + return rc; + } + s_vpr_p(sid, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); + } + device->clk_freq = rate; return rc; diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 412fd52e9679..b9dc0d4b6450 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -115,6 +115,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) { @@ -125,6 +132,7 @@ void msm_vidc_free_platform_resources( msm_vidc_free_qdss_addr_table(res); msm_vidc_free_bus_table(res); msm_vidc_free_buffer_usage_table(res); + msm_vidc_free_cx_ipeak_context(res); } static int msm_vidc_load_fw_name(struct msm_vidc_platform_resources *res) @@ -828,6 +836,44 @@ 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"); + else + return rc; + + if (IS_ERR(res->cx_ipeak_context)) { + rc = PTR_ERR(res->cx_ipeak_context); + if (rc == -EPROBE_DEFER) + d_vpr_h("cx-ipeak register failed. Deferring probe!"); + else + d_vpr_e("cx-ipeak register failed. rc: %d", rc); + + res->cx_ipeak_context = NULL; + return rc; + } + + if (res->cx_ipeak_context) + d_vpr_h("cx-ipeak register successful"); + else + d_vpr_h("cx-ipeak register not implemented"); + + of_property_read_u32(pdev->dev.of_node, + "qcom,clock-freq-threshold", + &res->clk_freq_threshold); + d_vpr_h("cx ipeak threshold frequency = %u\n", + res->clk_freq_threshold); + + return rc; +} + int read_platform_resources_from_dt( struct msm_vidc_platform_resources *res) { @@ -913,9 +959,16 @@ int read_platform_resources_from_dt( goto err_setup_legacy_cb; } + rc = msm_vidc_populate_cx_ipeak_context(res); + if (rc) { + d_vpr_e("Failed to setup cx-ipeak %d\n", rc); + goto err_register_cx_ipeak; + } return rc; +err_register_cx_ipeak: + msm_vidc_free_cx_ipeak_context(res); err_setup_legacy_cb: err_load_reset_table: msm_vidc_free_allowed_clocks_table(res); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 7a2916cd62ac..ac6dd6eca9ec 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. */ #ifndef __MSM_VIDC_RESOURCES_H__ @@ -9,6 +9,7 @@ #include #include "msm_vidc.h" #include +#include #define MAX_BUFFER_TYPES 32