From 21974f4a608f3306c5f16d1bd7833d3c311f04dc Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Thu, 16 Jun 2022 06:54:07 -0700 Subject: [PATCH] video-driver: Move register manipulation functions Move register manipulation functions in a common variant file (msm_vidc_variant). Change-Id: Ic92a264b47b4d90efcfb4389e30d2749a23f792b Signed-off-by: Stanimir Varbanov --- Kbuild | 4 +- driver/variant/common/inc/msm_vidc_variant.h | 22 +++ driver/variant/common/src/msm_vidc_variant.c | 196 +++++++++++++++++++ driver/variant/iris2/src/msm_vidc_iris2.c | 3 +- driver/variant/iris3/src/msm_vidc_iris3.c | 3 +- driver/vidc/inc/resources.h | 2 - driver/vidc/inc/venus_hfi.h | 7 - driver/vidc/src/resources.c | 23 --- driver/vidc/src/venus_hfi.c | 144 -------------- 9 files changed, 225 insertions(+), 179 deletions(-) create mode 100644 driver/variant/common/inc/msm_vidc_variant.h create mode 100644 driver/variant/common/src/msm_vidc_variant.c diff --git a/Kbuild b/Kbuild index 968a7ee391..e70c93c257 100644 --- a/Kbuild +++ b/Kbuild @@ -22,6 +22,7 @@ endif LINUXINCLUDE += -I$(VIDEO_ROOT)/driver/vidc/inc \ -I$(VIDEO_ROOT)/driver/platform/common/inc \ + -I$(VIDEO_ROOT)/driver/variant/common/inc \ -I$(VIDEO_ROOT)/include/uapi/vidc USERINCLUDE += -I$(VIDEO_ROOT)/include/uapi/vidc/media \ @@ -76,4 +77,5 @@ msm_video-objs += driver/vidc/src/msm_vidc_v4l2.o \ driver/vidc/src/venus_hfi_queue.o \ driver/vidc/src/hfi_packet.o \ driver/vidc/src/venus_hfi_response.o \ - driver/platform/common/src/msm_vidc_platform.o + driver/platform/common/src/msm_vidc_platform.o \ + driver/variant/common/src/msm_vidc_variant.o diff --git a/driver/variant/common/inc/msm_vidc_variant.h b/driver/variant/common/inc/msm_vidc_variant.h new file mode 100644 index 0000000000..1c09f48e79 --- /dev/null +++ b/driver/variant/common/inc/msm_vidc_variant.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_VIDC_VARIANT_H_ +#define _MSM_VIDC_VARIANT_H_ + +#include + +struct msm_vidc_core; + +int __write_register_masked(struct msm_vidc_core *core, u32 reg, u32 value, + u32 mask); +int __write_register(struct msm_vidc_core *core, u32 reg, u32 value); +int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value); +int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg, + u32 mask, u32 exp_val, u32 sleep_us, + u32 timeout_us); +int __set_registers(struct msm_vidc_core *core); + +#endif diff --git a/driver/variant/common/src/msm_vidc_variant.c b/driver/variant/common/src/msm_vidc_variant.c new file mode 100644 index 0000000000..fafdbaafcc --- /dev/null +++ b/driver/variant/common/src/msm_vidc_variant.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include + +#include "msm_vidc_core.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_dt.h" +#include "msm_vidc_variant.h" + +static void __fatal_error(bool fatal) +{ + WARN_ON(fatal); +} + +static int __strict_check(struct msm_vidc_core *core, const char *function) +{ + bool fatal = !mutex_is_locked(&core->lock); + + __fatal_error(fatal); + + if (fatal) + d_vpr_e("%s: strict check failed\n", function); + + return fatal ? -EINVAL : 0; +} + +int __write_register(struct msm_vidc_core *core, u32 reg, u32 value) +{ + u32 hwiosymaddr = reg; + u8 *base_addr; + int rc = 0; + + if (!core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + rc = __strict_check(core, __func__); + if (rc) + return rc; + + if (!core->power_enabled) { + d_vpr_e("HFI Write register failed : Power is OFF\n"); + return -EINVAL; + } + + base_addr = core->register_base_addr; + d_vpr_l("regwrite(%pK + %#x) = %#x\n", base_addr, hwiosymaddr, value); + base_addr += hwiosymaddr; + writel_relaxed(value, base_addr); + + /* + * Memory barrier to make sure value is written into the register. + */ + wmb(); + + return rc; +} + +/* + * Argument mask is used to specify which bits to update. In case mask is 0x11, + * only bits 0 & 4 will be updated with corresponding bits from value. To update + * entire register with value, set mask = 0xFFFFFFFF. + */ +int __write_register_masked(struct msm_vidc_core *core, u32 reg, u32 value, + u32 mask) +{ + u32 prev_val, new_val; + u8 *base_addr; + int rc = 0; + + if (!core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + rc = __strict_check(core, __func__); + if (rc) + return rc; + + if (!core->power_enabled) { + d_vpr_e("%s: register write failed, power is off\n", + __func__); + return -EINVAL; + } + + base_addr = core->register_base_addr; + base_addr += reg; + + prev_val = readl_relaxed(base_addr); + /* + * Memory barrier to ensure register read is correct + */ + rmb(); + + new_val = (prev_val & ~mask) | (value & mask); + d_vpr_l( + "Base addr: %pK, writing to: %#x, previous-value: %#x, value: %#x, mask: %#x, new-value: %#x...\n", + base_addr, reg, prev_val, value, mask, new_val); + writel_relaxed(new_val, base_addr); + /* + * Memory barrier to make sure value is written into the register. + */ + wmb(); + + return rc; +} + +int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value) +{ + int rc = 0; + u8 *base_addr; + + if (!core || !value) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!core->power_enabled) { + d_vpr_e("HFI Read register failed : Power is OFF\n"); + return -EINVAL; + } + + base_addr = core->register_base_addr; + + *value = readl_relaxed(base_addr + reg); + /* + * Memory barrier to make sure value is read correctly from the + * register. + */ + rmb(); + d_vpr_l("regread(%pK + %#x) = %#x\n", base_addr, reg, *value); + + return rc; +} + +int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg, + u32 mask, u32 exp_val, u32 sleep_us, + u32 timeout_us) +{ + int rc = 0; + u32 val = 0; + u8 *addr; + + if (!core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!core->power_enabled) { + d_vpr_e("%s failed: Power is OFF\n", __func__); + return -EINVAL; + } + + addr = (u8 *)core->register_base_addr + reg; + + rc = readl_relaxed_poll_timeout(addr, val, ((val & mask) == exp_val), sleep_us, timeout_us); + /* + * Memory barrier to make sure value is read correctly from the + * register. + */ + rmb(); + d_vpr_l( + "regread(%pK + %#x) = %#x. rc %d, mask %#x, exp_val %#x, cond %u, sleep %u, timeout %u\n", + core->register_base_addr, reg, val, rc, mask, exp_val, + ((val & mask) == exp_val), sleep_us, timeout_us); + + return rc; +} + +int __set_registers(struct msm_vidc_core *core) +{ + struct reg_set *reg_set; + int i, rc = 0; + + if (!core || !core->dt) { + d_vpr_e("core resources null, cannot set registers\n"); + return -EINVAL; + } + + reg_set = &core->dt->reg_set; + for (i = 0; i < reg_set->count; i++) { + rc = __write_register_masked(core, reg_set->reg_tbl[i].reg, + reg_set->reg_tbl[i].value, + reg_set->reg_tbl[i].mask); + if (rc) + return rc; + } + + return rc; +} diff --git a/driver/variant/iris2/src/msm_vidc_iris2.c b/driver/variant/iris2/src/msm_vidc_iris2.c index 9085f939e2..51434d9d85 100644 --- a/driver/variant/iris2/src/msm_vidc_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_iris2.c @@ -15,6 +15,7 @@ #include "msm_vidc_buffer.h" #include "msm_vidc_debug.h" #include "msm_vidc_control.h" +#include "msm_vidc_variant.h" #define VIDEO_ARCH_LX 1 @@ -549,7 +550,7 @@ static int __power_on_iris2(struct msm_vidc_core *core) * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() */ - res_ops->set_regs(core); + __set_registers(core); __interrupt_init_iris2(core); core->intr_status = 0; diff --git a/driver/variant/iris3/src/msm_vidc_iris3.c b/driver/variant/iris3/src/msm_vidc_iris3.c index ae121df296..0758d6cfe6 100644 --- a/driver/variant/iris3/src/msm_vidc_iris3.c +++ b/driver/variant/iris3/src/msm_vidc_iris3.c @@ -16,6 +16,7 @@ #include "msm_vidc_internal.h" #include "msm_vidc_buffer.h" #include "msm_vidc_debug.h" +#include "msm_vidc_variant.h" #define VIDEO_ARCH_LX 1 @@ -591,7 +592,7 @@ static int __power_on_iris3(struct msm_vidc_core *core) * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() */ - res_ops->set_regs(core); + __set_registers(core); __interrupt_init_iris3(core); core->intr_status = 0; diff --git a/driver/vidc/inc/resources.h b/driver/vidc/inc/resources.h index b4a18a7432..d32d457182 100644 --- a/driver/vidc/inc/resources.h +++ b/driver/vidc/inc/resources.h @@ -26,8 +26,6 @@ struct msm_vidc_resources_ops { int (*clk_disable)(struct msm_vidc_core *core, const char *name); int (*clk_enable)(struct msm_vidc_core *core, const char *name); - - int (*set_regs)(struct msm_vidc_core *core); }; const struct msm_vidc_resources_ops *get_resources_ops(void); diff --git a/driver/vidc/inc/venus_hfi.h b/driver/vidc/inc/venus_hfi.h index a270b506a1..99058da742 100644 --- a/driver/vidc/inc/venus_hfi.h +++ b/driver/vidc/inc/venus_hfi.h @@ -73,13 +73,6 @@ void venus_hfi_pm_work_handler(struct work_struct *work); irqreturn_t venus_hfi_isr(int irq, void *data); irqreturn_t venus_hfi_isr_handler(int irq, void *data); -int __write_register_masked(struct msm_vidc_core *core, - u32 reg, u32 value, u32 mask); -int __write_register(struct msm_vidc_core *core, - u32 reg, u32 value); -int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value); -int __read_register_with_poll_timeout(struct msm_vidc_core *core, - u32 reg, u32 mask, u32 exp_val, u32 sleep_us, u32 timeout_us); int __prepare_pc(struct msm_vidc_core *core); bool __core_in_valid_state(struct msm_vidc_core *core); diff --git a/driver/vidc/src/resources.c b/driver/vidc/src/resources.c index f758e1c246..99d5db2abb 100644 --- a/driver/vidc/src/resources.c +++ b/driver/vidc/src/resources.c @@ -443,28 +443,6 @@ static int __enable_regulator(struct msm_vidc_core *core, const char *reg_name) return rc; } -static int __set_registers(struct msm_vidc_core *core) -{ - struct reg_set *reg_set; - int i, rc = 0; - - if (!core || !core->dt) { - d_vpr_e("core resources null, cannot set registers\n"); - return -EINVAL; - } - - reg_set = &core->dt->reg_set; - for (i = 0; i < reg_set->count; i++) { - rc = __write_register_masked(core, reg_set->reg_tbl[i].reg, - reg_set->reg_tbl[i].value, - reg_set->reg_tbl[i].mask); - if (rc) - return rc; - } - - return rc; -} - #ifdef CONFIG_MSM_MMRM static void __deregister_mmrm(struct msm_vidc_core *core) { @@ -1139,7 +1117,6 @@ static const struct msm_vidc_resources_ops res_ops = { .set_clks = __set_clocks, .clk_enable = __prepare_enable_clock, .clk_disable = __disable_unprepare_clock, - .set_regs = __set_registers, }; const struct msm_vidc_resources_ops *get_resources_ops(void) diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index 1fe5423a9b..b1d2862a8a 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -161,150 +161,6 @@ static bool __valdiate_session(struct msm_vidc_core *core, return valid; } -int __write_register(struct msm_vidc_core *core, - u32 reg, u32 value) -{ - u32 hwiosymaddr = reg; - u8 *base_addr; - int rc = 0; - - if (!core) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - rc = __strict_check(core, __func__); - if (rc) - return rc; - - if (!core->power_enabled) { - d_vpr_e("HFI Write register failed : Power is OFF\n"); - return -EINVAL; - } - - base_addr = core->register_base_addr; - d_vpr_l("regwrite(%pK + %#x) = %#x\n", base_addr, hwiosymaddr, value); - base_addr += hwiosymaddr; - writel_relaxed(value, base_addr); - - /* - * Memory barrier to make sure value is written into the register. - */ - wmb(); - - return rc; -} - -/* - * Argument mask is used to specify which bits to update. In case mask is 0x11, - * only bits 0 & 4 will be updated with corresponding bits from value. To update - * entire register with value, set mask = 0xFFFFFFFF. - */ -int __write_register_masked(struct msm_vidc_core *core, - u32 reg, u32 value, u32 mask) -{ - u32 prev_val, new_val; - u8 *base_addr; - int rc = 0; - - if (!core) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - rc = __strict_check(core, __func__); - if (rc) - return rc; - - if (!core->power_enabled) { - d_vpr_e("%s: register write failed, power is off\n", - __func__); - return -EINVAL; - } - - base_addr = core->register_base_addr; - base_addr += reg; - - prev_val = readl_relaxed(base_addr); - /* - * Memory barrier to ensure register read is correct - */ - rmb(); - - new_val = (prev_val & ~mask) | (value & mask); - d_vpr_l( - "Base addr: %pK, writing to: %#x, previous-value: %#x, value: %#x, mask: %#x, new-value: %#x...\n", - base_addr, reg, prev_val, value, mask, new_val); - writel_relaxed(new_val, base_addr); - /* - * Memory barrier to make sure value is written into the register. - */ - wmb(); - - return rc; -} - -int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value) -{ - int rc = 0; - u8 *base_addr; - - if (!core || !value) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!core->power_enabled) { - d_vpr_e("HFI Read register failed : Power is OFF\n"); - return -EINVAL; - } - - base_addr = core->register_base_addr; - - *value = readl_relaxed(base_addr + reg); - /* - * Memory barrier to make sure value is read correctly from the - * register. - */ - rmb(); - d_vpr_l("regread(%pK + %#x) = %#x\n", base_addr, reg, *value); - - return rc; -} - -int __read_register_with_poll_timeout(struct msm_vidc_core *core, - u32 reg, u32 mask, u32 exp_val, u32 sleep_us, u32 timeout_us) -{ - int rc = 0; - u32 val = 0; - u8 *addr; - - if (!core) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!core->power_enabled) { - d_vpr_e("%s failed: Power is OFF\n", __func__); - return -EINVAL; - } - - addr = (u8 *)core->register_base_addr + reg; - - rc = readl_relaxed_poll_timeout(addr, val, ((val & mask) == exp_val), sleep_us, timeout_us); - /* - * Memory barrier to make sure value is read correctly from the - * register. - */ - rmb(); - d_vpr_l( - "regread(%pK + %#x) = %#x. rc %d, mask %#x, exp_val %#x, cond %u, sleep %u, timeout %u\n", - core->register_base_addr, reg, val, rc, mask, exp_val, - ((val & mask) == exp_val), sleep_us, timeout_us); - - return rc; -} - static void __schedule_power_collapse_work(struct msm_vidc_core *core) { if (!core || !core->capabilities) {