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 <quic_c_svarba@quicinc.com>
Bu işleme şunda yer alıyor:
Stanimir Varbanov
2022-06-16 06:54:07 -07:00
işlemeyi yapan: Gerrit - the friendly Code Review server
ebeveyn cf7b4f85c9
işleme 21974f4a60
9 değiştirilmiş dosya ile 225 ekleme ve 179 silme

Dosyayı Görüntüle

@@ -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 <linux/types.h>
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

Dosyayı Görüntüle

@@ -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 <linux/errno.h>
#include <linux/iopoll.h>
#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;
}

Dosyayı Görüntüle

@@ -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;

Dosyayı Görüntüle

@@ -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;