From bae72cb900640f7c56f6bb3fa3854474ed863e73 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 16 Dec 2020 15:42:34 -0800 Subject: [PATCH] video: driver: add scale clocks and buses functions Add clocks and buses scaling functionality. Change-Id: Ifa61043a938bc5c1990f6baf1777a3f2270fc77d Signed-off-by: Maheshwar Ajja --- Kbuild | 2 + .../variant/iris2/inc/msm_vidc_power_iris2.h | 14 +++++++ driver/variant/iris2/src/msm_vidc_iris2.c | 1 + .../variant/iris2/src/msm_vidc_power_iris2.c | 30 +++++++++++++ driver/vidc/inc/msm_vidc_inst.h | 4 +- driver/vidc/inc/msm_vidc_power.h | 13 ++++++ driver/vidc/inc/venus_hfi.h | 3 ++ driver/vidc/src/msm_vidc_power.c | 36 ++++++++++++++++ driver/vidc/src/venus_hfi.c | 42 +++++++++++++++++++ 9 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 driver/variant/iris2/inc/msm_vidc_power_iris2.h create mode 100644 driver/variant/iris2/src/msm_vidc_power_iris2.c create mode 100644 driver/vidc/inc/msm_vidc_power.h create mode 100644 driver/vidc/src/msm_vidc_power.c diff --git a/Kbuild b/Kbuild index 158a09d315..a37c9cf097 100644 --- a/Kbuild +++ b/Kbuild @@ -22,6 +22,7 @@ msm_video-objs += driver/vidc/src/msm_vidc_v4l2.o \ driver/vidc/src/msm_vidc_driver.o \ driver/vidc/src/msm_vidc_control.o \ driver/vidc/src/msm_vidc_buffer.o \ + driver/vidc/src/msm_vidc_power.o \ driver/vidc/src/msm_vidc_probe.o \ driver/vidc/src/msm_vidc_dt.o \ driver/vidc/src/msm_vidc_platform.o \ @@ -31,5 +32,6 @@ msm_video-objs += driver/vidc/src/msm_vidc_v4l2.o \ driver/vidc/src/hfi_packet.o \ driver/vidc/src/venus_hfi_response.o \ driver/variant/iris2/src/msm_vidc_buffer_iris2.o \ + driver/variant/iris2/src/msm_vidc_power_iris2.o \ driver/variant/iris2/src/msm_vidc_iris2.o \ driver/platform/waipio/src/msm_vidc_waipio.o diff --git a/driver/variant/iris2/inc/msm_vidc_power_iris2.h b/driver/variant/iris2/inc/msm_vidc_power_iris2.h new file mode 100644 index 0000000000..886b724e60 --- /dev/null +++ b/driver/variant/iris2/inc/msm_vidc_power_iris2.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_MSM_VIDC_POWER_IRIS2_H__ +#define __H_MSM_VIDC_POWER_IRIS2_H__ + +#include "msm_vidc_inst.h" + +u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst* inst); +u64 msm_vidc_calc_bw_iris2(struct msm_vidc_inst* inst); + +#endif diff --git a/driver/variant/iris2/src/msm_vidc_iris2.c b/driver/variant/iris2/src/msm_vidc_iris2.c index 3a348d8b7e..0423004092 100644 --- a/driver/variant/iris2/src/msm_vidc_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_iris2.c @@ -7,6 +7,7 @@ #include "msm_vidc_iris2.h" #include "msm_vidc_buffer_iris2.h" +#include "msm_vidc_power_iris2.h" #include "venus_hfi.h" #include "msm_vidc_inst.h" #include "msm_vidc_core.h" diff --git a/driver/variant/iris2/src/msm_vidc_power_iris2.c b/driver/variant/iris2/src/msm_vidc_power_iris2.c new file mode 100644 index 0000000000..b9779a0b1f --- /dev/null +++ b/driver/variant/iris2/src/msm_vidc_power_iris2.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_power_iris2.h" +#include "msm_vidc_inst.h" +#include "msm_vidc_debug.h" + +u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst) +{ + u64 freq = 0; + + /* 240 Mhz for iris2 based video hw */ + freq = 240 * 1000 * 1000; + s_vpr_h(inst->sid, "%s: freq %lu\n", __func__, freq); + + return freq; +} + +u64 msm_vidc_calc_bw_iris2(struct msm_vidc_inst *inst) +{ + u64 freq = 0; + + /* 600 Mhz for iris2 based video hw */ + freq = 600 * 1000 * 1000; + s_vpr_h(inst->sid, "%s: freq %lu\n", __func__, freq); + + return freq; +} diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index 6210328f25..9c75dda62c 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -15,8 +15,8 @@ struct msm_vidc_inst; ((c)->session_ops->op(__VA_ARGS__)) : 0) struct msm_vidc_session_ops { - int (*calc_freq)(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); - int (*calc_bw)(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); + u64 (*calc_freq)(struct msm_vidc_inst *inst); + u64 (*calc_bw)(struct msm_vidc_inst *inst); int (*decide_work_route)(struct msm_vidc_inst *inst); int (*decide_work_mode)(struct msm_vidc_inst *inst); int (*decide_core_and_power_mode)(struct msm_vidc_inst *inst); diff --git a/driver/vidc/inc/msm_vidc_power.h b/driver/vidc/inc/msm_vidc_power.h new file mode 100644 index 0000000000..62e08c4f81 --- /dev/null +++ b/driver/vidc/inc/msm_vidc_power.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_VIDC_POWER_H_ +#define _MSM_VIDC_POWER_H_ + +#include "msm_vidc_inst.h" + +int msm_vidc_scale_power(struct msm_vidc_inst *inst); + +#endif diff --git a/driver/vidc/inc/venus_hfi.h b/driver/vidc/inc/venus_hfi.h index 686f12e275..be9dc8d34b 100644 --- a/driver/vidc/inc/venus_hfi.h +++ b/driver/vidc/inc/venus_hfi.h @@ -66,6 +66,9 @@ int venus_hfi_session_set_codec(struct msm_vidc_inst *inst); int venus_hfi_core_init(struct msm_vidc_core *core); int venus_hfi_core_release(struct msm_vidc_core *core); int venus_hfi_suspend(struct msm_vidc_core *core); +int venus_hfi_scale_clocks(struct msm_vidc_inst* inst, u64 freq); +int venus_hfi_scale_buses(struct msm_vidc_inst* inst, u64 freq); + void venus_hfi_work_handler(struct work_struct *work); void venus_hfi_pm_work_handler(struct work_struct *work); irqreturn_t venus_hfi_isr(int irq, void *data); diff --git a/driver/vidc/src/msm_vidc_power.c b/driver/vidc/src/msm_vidc_power.c new file mode 100644 index 0000000000..3c6499f4c9 --- /dev/null +++ b/driver/vidc/src/msm_vidc_power.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_power.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_internal.h" +#include "msm_vidc_inst.h" +#include "msm_vidc_core.h" +#include "venus_hfi.h" + +int msm_vidc_scale_power(struct msm_vidc_inst *inst) +{ + int rc = 0; + u64 freq; + struct msm_vidc_core* core; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + core = inst->core; + + freq = call_session_op(core, calc_freq, inst); + rc = venus_hfi_scale_clocks(inst, freq); + if (rc) + return rc; + + freq = call_session_op(core, calc_bw, inst); + rc = venus_hfi_scale_buses(inst, freq); + if (rc) + return rc; + + return 0; +} diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index a7f6a716e6..3c018355da 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -2970,3 +2970,45 @@ int venus_hfi_release_buffer(struct msm_vidc_inst *inst, return rc; } + +int venus_hfi_scale_clocks(struct msm_vidc_inst* inst, u64 freq) +{ + int rc = 0; + struct msm_vidc_core* core; + + if (!inst || inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + + mutex_lock(&core->lock); + if (__resume(core)) { + s_vpr_e(inst->sid, "Resume from power collapse failed\n"); + rc = -EINVAL; + goto exit; + } + rc = __set_clocks(core, freq); +exit: + mutex_unlock(&core->lock); + + return rc; +} + +int venus_hfi_scale_buses(struct msm_vidc_inst *inst, u64 freq) +{ + int rc = 0; + struct msm_vidc_core* core; + + if (!inst || inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + + mutex_lock(&core->lock); + rc = __vote_buses(core, freq, freq); + mutex_unlock(&core->lock); + + return rc; +}