msm: vidc: Do not unhalt CVP Core Clock

Configure CVP_VPU_WRAPPER_CORE_CLOCK_CONFIG register to unhalt AXI & VPU
core clocks but not unhalt CVP core clock. Add a function to write a
masked value to register.

Change-Id: I8cb80b1823d091ac4eb705fd207afbd35bde86de
Signed-off-by: Akshay Chandrashekhar Kalghatgi <akalghat@codeaurora.org>
This commit is contained in:
Akshay Chandrashekhar Kalghatgi 2020-01-10 10:23:14 -08:00
parent 8f0d93768a
commit 167523e9ff
4 changed files with 58 additions and 9 deletions

View File

@ -787,6 +787,51 @@ void __write_register(struct venus_hfi_device *device,
wmb();
}
/*
* 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.
*/
void __write_register_masked(struct venus_hfi_device *device,
u32 reg, u32 value, u32 mask, u32 sid)
{
u32 prev_val, new_val;
u8 *base_addr;
if (!device) {
s_vpr_e(sid, "%s: invalid params\n", __func__);
return;
}
__strict_check(device);
if (!device->power_enabled) {
s_vpr_e(sid, "%s: register write failed, power is off\n",
__func__);
msm_vidc_res_handle_fatal_hw_error(device->res, true);
return;
}
base_addr = device->hal_data->register_base;
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);
s_vpr_l(sid,
"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();
}
int __read_register(struct venus_hfi_device *device, u32 reg, u32 sid)
{
int rc = 0;
@ -831,8 +876,9 @@ static void __set_registers(struct venus_hfi_device *device, u32 sid)
reg_set = &device->res->reg_set;
for (i = 0; i < reg_set->count; i++) {
__write_register(device, reg_set->reg_tbl[i].reg,
reg_set->reg_tbl[i].value, sid);
__write_register_masked(device, reg_set->reg_tbl[i].reg,
reg_set->reg_tbl[i].value,
reg_set->reg_tbl[i].mask, sid);
}
}

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __HFI_COMMON_H__
@ -296,6 +296,8 @@ void __dump(struct dump dump[], int len, u32 sid);
void __write_register(struct venus_hfi_device *device,
u32 reg, u32 value, u32 sid);
void __write_register_masked(struct venus_hfi_device *device,
u32 reg, u32 value, u32 mask, u32 sid);
int __read_register(struct venus_hfi_device *device, u32 reg, u32 sid);
void __disable_unprepare_clks(struct venus_hfi_device *device);
int __disable_regulators(struct venus_hfi_device *device);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/iommu.h>
@ -151,15 +151,15 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res)
}
if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets",
(u32 *)reg_set->reg_tbl, reg_set->count * 2)) {
(u32 *)reg_set->reg_tbl, reg_set->count * 3)) {
d_vpr_e("Failed to read register table\n");
msm_vidc_free_reg_table(res);
return -EINVAL;
}
for (i = 0; i < reg_set->count; i++) {
d_vpr_h("reg = %x, value = %x\n",
reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value
);
d_vpr_h("reg = %#x, value = %#x, mask = %#x\n",
reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value,
reg_set->reg_tbl[i].mask);
}
return rc;
}

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __MSM_VIDC_RESOURCES_H__
@ -15,6 +15,7 @@
struct reg_value_pair {
u32 reg;
u32 value;
u32 mask;
};
struct reg_set {