From e7a609b031d251c81433ea99d7c5c716a85fff96 Mon Sep 17 00:00:00 2001 From: Surajit Podder Date: Tue, 18 Jul 2017 13:07:50 +0530 Subject: [PATCH] msm: vidc: retain clock rate across power suspend/resume Power collapse should be transparent to vidc layer, so clock rate should be retained across suspend resume. Add change to save clock rate during suspend, and restore clock rate during resume. Change-Id: I7e01ddcfc5b2f7d02f76512e1cbaf1a75bacdb03 Signed-off-by: Surajit Podder --- .../platform/msm/vidc/msm_vidc_resources.h | 1 + drivers/media/platform/msm/vidc/venus_hfi.c | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h index 3a329d989918..a1b4ad48b054 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h @@ -106,6 +106,7 @@ struct clock_info { u32 count; bool has_scaling; bool has_mem_retention; + unsigned long rate_on_enable; }; struct clock_set { diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 52b56f615da9..20f02ce46029 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1574,6 +1574,7 @@ static int __scale_clocks(struct venus_hfi_device *device, return rc; } + static int venus_hfi_scale_clocks(void *dev, int load, struct vidc_clk_scale_data *data, unsigned long instant_bitrate) @@ -1600,6 +1601,41 @@ exit: return rc; } +static void __save_clock_rate(struct venus_hfi_device *device, bool reset) +{ + struct clock_info *cl; + + venus_hfi_for_each_clock(device, cl) { + if (cl->has_scaling) { + cl->rate_on_enable = + reset ? 0 : clk_get_rate(cl->clk); + dprintk(VIDC_PROF, "Saved clock %s rate %lu\n", + cl->name, cl->rate_on_enable); + } + } +} + +static void __restore_clock_rate(struct venus_hfi_device *device) +{ + struct clock_info *cl; + + venus_hfi_for_each_clock(device, cl) { + if (cl->has_scaling && cl->rate_on_enable) { + int rc; + + rc = __set_clk_rate(device, cl, cl->rate_on_enable); + if (rc) + dprintk(VIDC_ERR, + "Failed to restore clock %s rate %lu\n", + cl->name, cl->rate_on_enable); + else + dprintk(VIDC_DBG, + "Restored clock %s rate %lu\n", + cl->name, cl->rate_on_enable); + } + } +} + /* Writes into cmdq without raising an interrupt */ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, void *pkt, bool *requires_interrupt) @@ -4316,6 +4352,7 @@ static inline int __suspend(struct venus_hfi_device *device) goto err_tzbsp_suspend; } + __save_clock_rate(device, false); __venus_power_off(device, true); dprintk(VIDC_PROF, "Venus power collapsed\n"); return rc; @@ -4345,6 +4382,7 @@ static inline int __resume(struct venus_hfi_device *device) dprintk(VIDC_ERR, "Failed to power on venus\n"); goto err_venus_power_on; } + __restore_clock_rate(device); /* Reboot the firmware */ rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME); @@ -4382,6 +4420,7 @@ exit: err_reset_core: __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND); err_set_video_state: + __save_clock_rate(device, true); __venus_power_off(device, true); err_venus_power_on: dprintk(VIDC_ERR, "Failed to resume from power collapse\n"); @@ -4440,6 +4479,7 @@ fail_protect_mem: subsystem_put(device->resources.fw.cookie); device->resources.fw.cookie = NULL; fail_load_fw: + __save_clock_rate(device, true); __venus_power_off(device, true); fail_venus_power_on: fail_init_pkt: @@ -4461,6 +4501,7 @@ static void __unload_fw(struct venus_hfi_device *device) __vote_buses(device, NULL, 0); subsystem_put(device->resources.fw.cookie); __interface_queues_release(device); + __save_clock_rate(device, true); __venus_power_off(device, false); device->resources.fw.cookie = NULL; __deinit_resources(device);