techpack: video: Updating video kernel snapshot

Video kernel snapshot before disabling msm/vidc compilation
from base kernel.

Change-Id: Id1178c3aca00706ad4822537f7f9a28141478771
Signed-off-by: Shivendra Kakrania <shiven@codeaurora.org>
This commit is contained in:
Shivendra Kakrania 2019-05-02 23:07:45 -07:00
parent 4ae4cb1749
commit ae78fd954b
12 changed files with 846 additions and 593 deletions

View File

@ -14,7 +14,10 @@ msm-vidc-objs := vidc/msm_v4l2_vidc.o \
vidc/msm_smem.o \
vidc/msm_vidc_debug.o \
vidc/msm_vidc_res_parse.o \
vidc/venus_hfi.o \
vidc/hfi_common.o \
vidc/hfi_ar50.o \
vidc/hfi_iris1.o \
vidc/hfi_iris2.o \
vidc/hfi_response_handler.o \
vidc/hfi_packetization.o \
vidc/vidc_hfi.o \

13
msm/vidc/hfi_ar50.c Normal file
View File

@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#include "hfi_common.h"
#include "hfi_io_common.h"
void __interrupt_init_ar50(struct venus_hfi_device *device)
{
__write_register(device, WRAPPER_INTR_MASK,
WRAPPER_INTR_MASK_A2HVCODEC_BMSK);
}

View File

@ -29,8 +29,8 @@
#include <linux/reset.h>
#include "hfi_packetization.h"
#include "msm_vidc_debug.h"
#include "venus_hfi.h"
#include "vidc_hfi_io.h"
#include "hfi_common.h"
#include "hfi_io_common.h"
#define FIRMWARE_SIZE 0X00A00000
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
@ -77,10 +77,8 @@ static void venus_hfi_pm_handler(struct work_struct *work);
static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler);
static inline int __resume(struct venus_hfi_device *device);
static inline int __suspend(struct venus_hfi_device *device);
static int __disable_regulators(struct venus_hfi_device *device);
static int __enable_regulators(struct venus_hfi_device *device);
static inline int __prepare_enable_clks(struct venus_hfi_device *device);
static inline void __disable_unprepare_clks(struct venus_hfi_device *device);
static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet);
static int __initialize_packetization(struct venus_hfi_device *device);
static struct hal_session *__get_session(struct venus_hfi_device *device,
@ -99,43 +97,56 @@ static int __release_subcaches(struct venus_hfi_device *device);
static int __disable_subcaches(struct venus_hfi_device *device);
static int __power_collapse(struct venus_hfi_device *device, bool force);
static int venus_hfi_noc_error_info(void *dev);
static void interrupt_init_vpu4(struct venus_hfi_device *device);
static void interrupt_init_iris1(struct venus_hfi_device *device);
static void setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device);
static void clock_config_on_enable_iris1(struct venus_hfi_device *device);
static int reset_ahb2axi_bridge(struct venus_hfi_device *device);
static int __set_ubwc_config(struct venus_hfi_device *device);
static void power_off_common(struct venus_hfi_device *device);
static void power_off_iris2(struct venus_hfi_device *device);
static void noc_error_info_common(struct venus_hfi_device *device);
static void noc_error_info_iris2(struct venus_hfi_device *device);
static void __power_off_common(struct venus_hfi_device *device);
static int __prepare_pc_common(struct venus_hfi_device *device);
static void __raise_interrupt_common(struct venus_hfi_device *device);
static bool __watchdog_common(u32 intr_status);
static void __noc_error_info_common(struct venus_hfi_device *device);
static void __core_clear_interrupt_common(struct venus_hfi_device *device);
static inline int __boot_firmware_common(struct venus_hfi_device *device);
static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device);
struct venus_hfi_vpu_ops vpu4_ops = {
.interrupt_init = interrupt_init_vpu4,
.setup_dsp_uc_memmap = NULL,
.interrupt_init = __interrupt_init_ar50,
.setup_ucregion_memmap = __setup_ucregion_memory_map_common,
.clock_config_on_enable = NULL,
.reset_ahb2axi_bridge = NULL,
.power_off = power_off_common,
.noc_error_info = noc_error_info_common,
.power_off = __power_off_common,
.prepare_pc = __prepare_pc_common,
.raise_interrupt = __raise_interrupt_common,
.watchdog = __watchdog_common,
.noc_error_info = __noc_error_info_common,
.core_clear_interrupt = __core_clear_interrupt_common,
.boot_firmware = __boot_firmware_common,
};
struct venus_hfi_vpu_ops iris1_ops = {
.interrupt_init = interrupt_init_iris1,
.setup_dsp_uc_memmap = setup_dsp_uc_memmap_iris1,
.clock_config_on_enable = clock_config_on_enable_iris1,
.reset_ahb2axi_bridge = reset_ahb2axi_bridge,
.power_off = power_off_common,
.noc_error_info = noc_error_info_common,
.interrupt_init = __interrupt_init_iris1,
.setup_ucregion_memmap = __setup_ucregion_memory_map_iris1,
.clock_config_on_enable = __clock_config_on_enable_iris1,
.reset_ahb2axi_bridge = __reset_ahb2axi_bridge_common,
.power_off = __power_off_common,
.prepare_pc = __prepare_pc_common,
.raise_interrupt = __raise_interrupt_common,
.watchdog = __watchdog_common,
.noc_error_info = __noc_error_info_common,
.core_clear_interrupt = __core_clear_interrupt_common,
.boot_firmware = __boot_firmware_common,
};
struct venus_hfi_vpu_ops iris2_ops = {
.interrupt_init = interrupt_init_iris1,
.setup_dsp_uc_memmap = NULL,
.interrupt_init = __interrupt_init_iris2,
.setup_ucregion_memmap = __setup_ucregion_memory_map_iris2,
.clock_config_on_enable = NULL,
.reset_ahb2axi_bridge = reset_ahb2axi_bridge,
.power_off = power_off_iris2,
.noc_error_info = noc_error_info_iris2,
.reset_ahb2axi_bridge = __reset_ahb2axi_bridge_common,
.power_off = __power_off_iris2,
.prepare_pc = __prepare_pc_iris2,
.raise_interrupt = __raise_interrupt_iris2,
.watchdog = __watchdog_iris2,
.noc_error_info = __noc_error_info_iris2,
.core_clear_interrupt = __core_clear_interrupt_iris2,
.boot_firmware = __boot_firmware_iris2,
};
/**
@ -881,7 +892,7 @@ static void __smem_free(struct venus_hfi_device *dev, struct msm_smem *mem)
msm_smem_free(mem);
}
static void __write_register(struct venus_hfi_device *device,
void __write_register(struct venus_hfi_device *device,
u32 reg, u32 value)
{
u32 hwiosymaddr = reg;
@ -913,7 +924,7 @@ static void __write_register(struct venus_hfi_device *device,
wmb();
}
static int __read_register(struct venus_hfi_device *device, u32 reg)
int __read_register(struct venus_hfi_device *device, u32 reg)
{
int rc = 0;
u8 *base_addr;
@ -964,37 +975,13 @@ static void __set_registers(struct venus_hfi_device *device)
}
}
/*
* The existence of this function is a hack for 8996 (or certain Venus versions)
* to overcome a hardware bug. Whenever the GDSCs momentarily power collapse
* (after calling __hand_off_regulators()), the values of the threshold
* registers (typically programmed by TZ) are incorrectly reset. As a result
* reprogram these registers at certain agreed upon points.
*/
static void __set_threshold_registers(struct venus_hfi_device *device)
{
u32 version = __read_register(device, VIDC_WRAPPER_HW_VERSION);
version &= ~GENMASK(15, 0);
if (version != (0x3 << 28 | 0x43 << 16))
return;
if (__tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESTORE_THRESHOLD))
dprintk(VIDC_ERR, "Failed to restore threshold values\n");
}
static int __vote_bandwidth(struct bus_info *bus,
unsigned long *freq)
static int __vote_bandwidth(struct bus_info *bus, unsigned long freq)
{
int rc = 0;
uint64_t ab = 0;
if (*freq)
*freq = clamp_t(typeof(*freq), *freq, bus->range[0],
bus->range[1]);
/* Bus Driver expects values in Bps */
ab = *freq * 1000;
ab = freq * 1000;
dprintk(VIDC_PROF, "Voting bus %s to ab %llu\n", bus->name, ab);
rc = msm_bus_scale_update_bw(bus->client, ab, 0);
if (rc)
@ -1004,24 +991,17 @@ static int __vote_bandwidth(struct bus_info *bus,
return rc;
}
static int __unvote_buses(struct venus_hfi_device *device)
int __unvote_buses(struct venus_hfi_device *device)
{
int rc = 0;
struct bus_info *bus = NULL;
unsigned long freq = 0, zero = 0;
kfree(device->bus_vote.data);
device->bus_vote.data = NULL;
device->bus_vote.data_count = 0;
venus_hfi_for_each_bus(device, bus) {
if (!bus->is_prfm_mode) {
freq = device->bus_vote.calc_bw(bus, &device->bus_vote);
rc = __vote_bandwidth(bus, &freq);
}
else
rc = __vote_bandwidth(bus, &zero);
rc = __vote_bandwidth(bus, 0);
if (rc)
goto err_unknown_device;
}
@ -1066,7 +1046,11 @@ no_data_count:
else
freq = bus->range[1];
rc = __vote_bandwidth(bus, &freq);
/* ensure freq is within limits */
freq = clamp_t(typeof(freq), freq,
bus->range[0], bus->range[1]);
rc = __vote_bandwidth(bus, freq);
} else {
dprintk(VIDC_ERR, "No BUS to Vote\n");
}
@ -1181,7 +1165,7 @@ static int __tzbsp_set_video_state(enum tzbsp_video_state state)
return 0;
}
static inline int __boot_firmware(struct venus_hfi_device *device)
static inline int __boot_firmware_common(struct venus_hfi_device *device)
{
int rc = 0;
u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000;
@ -1190,10 +1174,10 @@ static inline int __boot_firmware(struct venus_hfi_device *device)
if (device->res->domain_cvp)
ctrl_init_val |= BIT(1);
__write_register(device, VIDC_CTRL_INIT, ctrl_init_val);
__write_register(device, CTRL_INIT, ctrl_init_val);
while (!ctrl_status && count < max_tries) {
ctrl_status = __read_register(device, VIDC_CTRL_STATUS);
if ((ctrl_status & VIDC_CTRL_ERROR_STATUS__M) == 0x4) {
ctrl_status = __read_register(device, CTRL_STATUS);
if ((ctrl_status & CTRL_ERROR_STATUS__M) == 0x4) {
dprintk(VIDC_ERR, "invalid setting for UC_REGION\n");
break;
}
@ -1207,10 +1191,6 @@ static inline int __boot_firmware(struct venus_hfi_device *device)
rc = -ETIME;
}
/* Enable interrupt before sending commands to venus */
__write_register(device, VIDC_CPU_CS_H2XSOFTINTEN, 0x1);
__write_register(device, VIDC_CPU_CS_X2RPMh, 0x0);
return rc;
}
@ -1413,17 +1393,19 @@ err_q_null:
return result;
}
static void __raise_interrupt_common(struct venus_hfi_device *device)
{
__write_register(device, CPU_IC_SOFTINT,
1 << CPU_IC_SOFTINT_H2A_SHFT);
}
static int __iface_cmdq_write(struct venus_hfi_device *device, void *pkt)
{
bool needs_interrupt = false;
int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt);
if (!rc && needs_interrupt) {
/* Consumer of cmdq prefers that we raise an interrupt */
rc = 0;
__write_register(device, VIDC_CPU_IC_SOFTINT,
1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT);
}
if (!rc && needs_interrupt)
call_venus_op(device, raise_interrupt, device);
return rc;
}
@ -1457,8 +1439,7 @@ static int __iface_msgq_read(struct venus_hfi_device *device, void *pkt)
if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
__hal_sim_modify_msg_packet((u8 *)pkt, device);
if (tx_req_is_set)
__write_register(device, VIDC_CPU_IC_SOFTINT,
1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT);
call_venus_op(device, raise_interrupt, device);
rc = 0;
} else
rc = -ENODATA;
@ -1489,8 +1470,7 @@ static int __iface_dbgq_read(struct venus_hfi_device *device, void *pkt)
if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
if (tx_req_is_set)
__write_register(device, VIDC_CPU_IC_SOFTINT,
1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT);
call_venus_op(device, raise_interrupt, device);
rc = 0;
} else
rc = -ENODATA;
@ -1764,21 +1744,20 @@ static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev,
return rc;
}
static void __setup_ucregion_memory_map(struct venus_hfi_device *device)
static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device)
{
__write_register(device, VIDC_UC_REGION_ADDR,
__write_register(device, UC_REGION_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, VIDC_UC_REGION_SIZE, SHARED_QSIZE);
__write_register(device, VIDC_QTBL_ADDR,
__write_register(device, UC_REGION_SIZE, SHARED_QSIZE);
__write_register(device, QTBL_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, VIDC_QTBL_INFO, 0x01);
__write_register(device, QTBL_INFO, 0x01);
if (device->sfr.align_device_addr)
__write_register(device, VIDC_SFR_ADDR,
__write_register(device, SFR_ADDR,
(u32)device->sfr.align_device_addr);
if (device->qdss.align_device_addr)
__write_register(device, VIDC_MMAP_ADDR,
__write_register(device, MMAP_ADDR,
(u32)device->qdss.align_device_addr);
call_venus_op(device, setup_dsp_uc_memmap, device);
}
static int __interface_queues_init(struct venus_hfi_device *dev)
@ -1930,7 +1909,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev)
}
}
__setup_ucregion_memory_map(dev);
call_venus_op(dev, setup_ucregion_memmap, dev);
return 0;
fail_alloc_queue:
return -ENOMEM;
@ -2052,7 +2031,7 @@ static int venus_hfi_core_init(void *device)
goto err_core_init;
}
rc = __boot_firmware(dev);
rc = call_venus_op(dev, boot_firmware, dev);
if (rc) {
dprintk(VIDC_ERR, "Failed to start core\n");
rc = -ENODEV;
@ -2164,7 +2143,7 @@ static int __get_q_size(struct venus_hfi_device *dev, unsigned int q_index)
return read_ptr - write_ptr;
}
static void __core_clear_interrupt(struct venus_hfi_device *device)
static void __core_clear_interrupt_common(struct venus_hfi_device *device)
{
u32 intr_status = 0, mask = 0;
@ -2173,10 +2152,10 @@ static void __core_clear_interrupt(struct venus_hfi_device *device)
return;
}
intr_status = __read_register(device, VIDC_WRAPPER_INTR_STATUS);
mask = (VIDC_WRAPPER_INTR_STATUS_A2H_BMSK |
VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK |
VIDC_CTRL_INIT_IDLE_MSG_BMSK);
intr_status = __read_register(device, WRAPPER_INTR_STATUS);
mask = (WRAPPER_INTR_STATUS_A2H_BMSK |
WRAPPER_INTR_STATUS_A2HWD_BMSK |
CTRL_INIT_IDLE_MSG_BMSK);
if (intr_status & mask) {
device->intr_status |= intr_status;
@ -2188,7 +2167,8 @@ static void __core_clear_interrupt(struct venus_hfi_device *device)
device->spur_count++;
}
__write_register(device, VIDC_CPU_CS_A2HSOFTINTCLR, 1);
__write_register(device, CPU_CS_A2HSOFTINTCLR, 1);
__write_register(device, WRAPPER_INTR_CLEAR, intr_status);
}
static int venus_hfi_core_trigger_ssr(void *device,
@ -2984,7 +2964,7 @@ static int __check_core_registered(struct hal_device_data core,
device = list_entry(curr,
struct venus_hfi_device, list);
hal_data = device->hal_data;
if (device && hal_data->irq == irq &&
if (hal_data && hal_data->irq == irq &&
(CONTAINS(hal_data->firmware_base,
FIRMWARE_SIZE, fw_addr) ||
CONTAINS(fw_addr, FIRMWARE_SIZE,
@ -3022,7 +3002,7 @@ static void __process_fatal_error(
device->callback(HAL_SYS_ERROR, &cmd_done);
}
static int __prepare_pc(struct venus_hfi_device *device)
int __prepare_pc(struct venus_hfi_device *device)
{
int rc = 0;
struct hfi_cmd_sys_pc_prep_packet pkt;
@ -3098,15 +3078,64 @@ static void venus_hfi_pm_handler(struct work_struct *work)
}
}
static int __power_collapse(struct venus_hfi_device *device, bool force)
static int __prepare_pc_common(struct venus_hfi_device *device)
{
int rc = 0;
u32 wfi_status = 0, idle_status = 0, pc_ready = 0;
u32 ctrl_status = 0;
u32 flags = 0;
int count = 0;
const int max_tries = 10;
ctrl_status = __read_register(device, CTRL_STATUS);
pc_ready = ctrl_status & CTRL_STATUS_PC_READY;
idle_status = ctrl_status & BIT(30);
if (pc_ready) {
dprintk(VIDC_DBG, "Already in pc_ready state\n");
return 0;
}
wfi_status = BIT(0) & __read_register(device,
WRAPPER_CPU_STATUS);
if (!wfi_status || !idle_status) {
dprintk(VIDC_WARN, "Skipping PC, wfi status not set\n");
goto skip_power_off;
}
rc = __prepare_pc(device);
if (rc) {
dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc);
goto skip_power_off;
}
while (count < max_tries) {
wfi_status = BIT(0) & __read_register(device,
WRAPPER_CPU_STATUS);
ctrl_status = __read_register(device, CTRL_STATUS);
if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY))
break;
usleep_range(150, 250);
count++;
}
if (count == max_tries) {
dprintk(VIDC_ERR, "Skip PC. Core is not in right state\n");
goto skip_power_off;
}
return rc;
skip_power_off:
dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
wfi_status, idle_status, pc_ready, ctrl_status);
return -EAGAIN;
}
static int __power_collapse(struct venus_hfi_device *device, bool force)
{
int rc = 0;
u32 flags = 0;
if (!device) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
@ -3128,45 +3157,9 @@ static int __power_collapse(struct venus_hfi_device *device, bool force)
else if (rc)
goto skip_power_off;
ctrl_status = __read_register(device, VIDC_CTRL_STATUS);
pc_ready = ctrl_status & VIDC_CTRL_STATUS_PC_READY;
idle_status = ctrl_status & BIT(30);
if (!pc_ready) {
wfi_status = BIT(0) &
__read_register(device,
VIDC_WRAPPER_TZ_CPU_STATUS);
if (!wfi_status || !idle_status) {
dprintk(VIDC_WARN,
"Skipping PC, wfi or idle status not set.\n");
goto skip_power_off;
}
rc = __prepare_pc(device);
if (rc) {
dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc);
goto skip_power_off;
}
while (count < max_tries) {
wfi_status = BIT(0) &
__read_register(device,
VIDC_WRAPPER_TZ_CPU_STATUS);
ctrl_status = __read_register(device,
VIDC_CTRL_STATUS);
if (wfi_status &&
(ctrl_status & VIDC_CTRL_STATUS_PC_READY))
break;
usleep_range(150, 250);
count++;
}
if (count == max_tries) {
dprintk(VIDC_ERR,
"Skip PC. Core is not in right state.\n");
goto skip_power_off;
}
}
rc = call_venus_op(device, prepare_pc, device);
if (rc)
goto skip_power_off;
__flush_debug_queue(device, device->raw_packet);
@ -3178,9 +3171,6 @@ exit:
return rc;
skip_power_off:
dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
wfi_status, idle_status, pc_ready, ctrl_status);
return -EAGAIN;
}
@ -3294,6 +3284,16 @@ static struct hal_session *__get_session(struct venus_hfi_device *device,
return NULL;
}
static bool __watchdog_common(u32 intr_status)
{
bool rc = false;
if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK)
rc = true;
return rc;
}
static int __response_handler(struct venus_hfi_device *device)
{
struct msm_vidc_cb_info *packets;
@ -3310,12 +3310,12 @@ static int __response_handler(struct venus_hfi_device *device)
if (!raw_packet || !packets) {
dprintk(VIDC_ERR,
"%s: Invalid args : Res packet = %p, Raw packet = %p\n",
"%s: Invalid args : Res packet = %pK, Raw packet = %pK\n",
__func__, packets, raw_packet);
return 0;
}
if (device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK) {
if (call_venus_op(device, watchdog, device->intr_status)) {
struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *)
device->sfr.align_virtual_addr;
struct msm_vidc_cb_info info = {
@ -3361,14 +3361,6 @@ static int __response_handler(struct venus_hfi_device *device)
dprintk(VIDC_DBG, "Received SYS_INIT_DONE\n");
break;
case HAL_SESSION_LOAD_RESOURCE_DONE:
/*
* Work around for H/W bug, need to re-program these
* registers as part of a handshake agreement with the
* firmware. This strictly only needs to be done for
* decoder secure sessions, but there's no harm in doing
* so for all sessions as it's at worst a NO-OP.
*/
__set_threshold_registers(device);
break;
default:
break;
@ -3491,7 +3483,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work)
goto err_no_work;
}
__core_clear_interrupt(device);
call_venus_op(device, core_clear_interrupt, device);
num_responses = __response_handler(device);
err_no_work:
@ -3521,7 +3513,7 @@ err_no_work:
}
/* We need re-enable the irq which was disabled in ISR handler */
if (!(intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
if (!call_venus_op(device, watchdog, intr_status))
enable_irq(device->hal_data->irq);
/*
@ -3703,7 +3695,7 @@ failed_to_reset:
return rc;
}
static inline void __disable_unprepare_clks(struct venus_hfi_device *device)
void __disable_unprepare_clks(struct venus_hfi_device *device)
{
struct clock_info *cl;
int rc = 0;
@ -3732,7 +3724,7 @@ static inline void __disable_unprepare_clks(struct venus_hfi_device *device)
}
}
static int reset_ahb2axi_bridge(struct venus_hfi_device *device)
int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device)
{
int rc, i;
@ -4179,7 +4171,7 @@ err_reg_enable_failed:
return rc;
}
static int __disable_regulators(struct venus_hfi_device *device)
int __disable_regulators(struct venus_hfi_device *device)
{
struct regulator_info *rinfo;
@ -4355,50 +4347,6 @@ static int __disable_subcaches(struct venus_hfi_device *device)
return 0;
}
static void interrupt_init_iris1(struct venus_hfi_device *device)
{
u32 mask_val = 0;
/* All interrupts should be disabled initially 0x1F6 : Reset value */
mask_val = __read_register(device, VIDC_WRAPPER_INTR_MASK);
/* Write 0 to unmask CPU and WD interrupts */
mask_val &= ~(VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK |
VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK);
__write_register(device, VIDC_WRAPPER_INTR_MASK, mask_val);
}
static void interrupt_init_vpu4(struct venus_hfi_device *device)
{
__write_register(device, VIDC_WRAPPER_INTR_MASK,
VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK);
}
static void setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device)
{
/* initialize DSP QTBL & UCREGION with CPU queues */
__write_register(device, HFI_DSP_QTBL_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE);
if (device->res->domain_cvp) {
__write_register(device, HFI_DSP_QTBL_ADDR,
(u32)device->dsp_iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_ADDR,
(u32)device->dsp_iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_SIZE,
device->dsp_iface_q_table.mem_data.size);
}
}
static void clock_config_on_enable_iris1(struct venus_hfi_device *device)
{
__write_register(device, VIDC_WRAPPER_CPU_CGC_DIS, 0);
__write_register(device, VIDC_WRAPPER_CPU_CLOCK_CONFIG, 0);
}
static int __set_ubwc_config(struct venus_hfi_device *device)
{
u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE];
@ -4503,12 +4451,12 @@ fail_vote_buses:
return rc;
}
static void power_off_common(struct venus_hfi_device *device)
static void __power_off_common(struct venus_hfi_device *device)
{
if (!device->power_enabled)
return;
if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
if (!(device->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK))
disable_irq_nosync(device->hal_data->irq);
device->intr_status = 0;
@ -4524,93 +4472,6 @@ static void power_off_common(struct venus_hfi_device *device)
device->power_enabled = false;
}
static void power_off_iris2(struct venus_hfi_device *device)
{
u32 lpi_status, reg_status = 0, count = 0, max_count = 10;
if (!device->power_enabled)
return;
if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
disable_irq_nosync(device->hal_data->irq);
device->intr_status = 0;
/* HPG 6.1.2 Step 1 */
__write_register(device, VIDC_CPU_CS_X2RPMh, 0x3);
/* HPG 6.1.2 Step 2, noc to low power */
__write_register(device, VIDC_AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1);
while (!reg_status && count < max_count) {
lpi_status =
__read_register(device,
VIDC_AON_WRAPPER_MVP_NOC_LPI_STATUS);
reg_status = lpi_status & BIT(0);
dprintk(VIDC_DBG,
"Noc: lpi_status %d noc_status %d (count %d)\n",
lpi_status, reg_status, count);
usleep_range(50, 100);
count++;
}
if (count == max_count) {
dprintk(VIDC_ERR,
"NOC not in qaccept status %d\n", reg_status);
}
/* HPG 6.1.2 Step 3, debug bridge to low power */
__write_register(device,
VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7);
reg_status = 0;
count = 0;
while ((reg_status != 0x7) && count < max_count) {
lpi_status = __read_register(device,
VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS);
reg_status = lpi_status & 0x7;
dprintk(VIDC_DBG,
"DBLP Set : lpi_status %d reg_status %d (count %d)\n",
lpi_status, reg_status, count);
usleep_range(50, 100);
count++;
}
if (count == max_count) {
dprintk(VIDC_ERR,
"DBLP Set: status %d\n", reg_status);
}
/* HPG 6.1.2 Step 4, debug bridge to lpi release */
__write_register(device,
VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x0);
lpi_status = 0x1;
count = 0;
while (lpi_status && count < max_count) {
lpi_status = __read_register(device,
VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS);
dprintk(VIDC_DBG,
"DBLP Release: lpi_status %d(count %d)\n",
lpi_status, count);
usleep_range(50, 100);
count++;
}
if (count == max_count) {
dprintk(VIDC_ERR,
"DBLP Release: lpi_status %d\n", lpi_status);
}
/* HPG 6.1.2 Step 6 */
__disable_unprepare_clks(device);
/* HPG 6.1.2 Step 7 & 8 */
if (call_venus_op(device, reset_ahb2axi_bridge, device))
dprintk(VIDC_ERR, "Failed to reset ahb2axi\n");
/* HPG 6.1.2 Step 5 */
if (__disable_regulators(device))
dprintk(VIDC_WARN, "Failed to disable regulators\n");
if (__unvote_buses(device))
dprintk(VIDC_WARN, "Failed to unvote for buses\n");
device->power_enabled = false;
}
static inline int __suspend(struct venus_hfi_device *device)
{
int rc = 0;
@ -4674,20 +4535,15 @@ static inline int __resume(struct venus_hfi_device *device)
goto err_set_video_state;
}
__setup_ucregion_memory_map(device);
call_venus_op(device, setup_ucregion_memmap, device);
/* Wait for boot completion */
rc = __boot_firmware(device);
rc = call_venus_op(device, boot_firmware, device);
if (rc) {
dprintk(VIDC_ERR, "Failed to reset venus core\n");
goto err_reset_core;
}
/*
* Work around for H/W bug, need to reprogram these registers once
* firmware is out reset
*/
__set_threshold_registers(device);
if (device->res->pm_qos_latency_us) {
#ifdef CONFIG_SMP
device->qos.type = PM_QOS_REQ_AFFINE_IRQ;
@ -4926,7 +4782,7 @@ static void __noc_error_info(struct venus_hfi_device *device, u32 core_num)
dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_num, val);
}
static void noc_error_info_common(struct venus_hfi_device *device)
static void __noc_error_info_common(struct venus_hfi_device *device)
{
const u32 core0 = 0, core1 = 1;
@ -4939,38 +4795,6 @@ static void noc_error_info_common(struct venus_hfi_device *device)
__noc_error_info(device, core1);
}
static void noc_error_info_iris2(struct venus_hfi_device *device)
{
u32 val = 0;
val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val);
}
static int venus_hfi_noc_error_info(void *dev)
{
struct venus_hfi_device *device;

View File

@ -3,8 +3,8 @@
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __H_VENUS_HFI_H__
#define __H_VENUS_HFI_H__
#ifndef __HFI_COMMON_H__
#define __HFI_COMMON_H__
#include <linux/clk.h>
#include <linux/mutex.h>
@ -234,12 +234,17 @@ enum reset_state {
struct venus_hfi_device;
struct venus_hfi_vpu_ops {
void (*interrupt_init)(struct venus_hfi_device *ptr);
void (*setup_dsp_uc_memmap)(struct venus_hfi_device *device);
void (*interrupt_init)(struct venus_hfi_device *device);
void (*setup_ucregion_memmap)(struct venus_hfi_device *device);
void (*clock_config_on_enable)(struct venus_hfi_device *device);
int (*reset_ahb2axi_bridge)(struct venus_hfi_device *device);
void (*power_off)(struct venus_hfi_device *device);
int (*prepare_pc)(struct venus_hfi_device *device);
void (*raise_interrupt)(struct venus_hfi_device *device);
bool (*watchdog)(u32 intr_status);
void (*noc_error_info)(struct venus_hfi_device *device);
void (*core_clear_interrupt)(struct venus_hfi_device *device);
int (*boot_firmware)(struct venus_hfi_device *device);
};
struct venus_hfi_device {
@ -286,4 +291,30 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id,
struct msm_vidc_platform_resources *res,
hfi_cmd_response_callback callback);
void __write_register(struct venus_hfi_device *device, u32 reg, u32 value);
int __read_register(struct venus_hfi_device *device, u32 reg);
void __disable_unprepare_clks(struct venus_hfi_device *device);
int __disable_regulators(struct venus_hfi_device *device);
int __unvote_buses(struct venus_hfi_device *device);
int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device);
int __prepare_pc(struct venus_hfi_device *device);
/* AR50 specific */
void __interrupt_init_ar50(struct venus_hfi_device *device);
/* IRIS1 specific */
void __interrupt_init_iris1(struct venus_hfi_device *device);
void __setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device);
void __clock_config_on_enable_iris1(struct venus_hfi_device *device);
void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device);
/* IRIS2 specific */
void __interrupt_init_iris2(struct venus_hfi_device *device);
void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device);
void __power_off_iris2(struct venus_hfi_device *device);
int __prepare_pc_iris2(struct venus_hfi_device *device);
void __raise_interrupt_iris2(struct venus_hfi_device *device);
bool __watchdog_iris2(u32 intr_status);
void __noc_error_info_iris2(struct venus_hfi_device *device);
void __core_clear_interrupt_iris2(struct venus_hfi_device *device);
int __boot_firmware_iris2(struct venus_hfi_device *device);
#endif

139
msm/vidc/hfi_io_common.h Normal file
View File

@ -0,0 +1,139 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef __HFI_IO_COMMON_H__
#define __HFI_IO_COMMON_H__
#include <linux/io.h>
#define VBIF_BASE_OFFS 0x00080000
#define CPU_BASE_OFFS 0x000C0000
#define CPU_CS_BASE_OFFS (CPU_BASE_OFFS + 0x00012000)
#define CPU_IC_BASE_OFFS (CPU_BASE_OFFS + 0x0001F000)
#define CPU_CS_A2HSOFTINT (CPU_CS_BASE_OFFS + 0x18)
#define CPU_CS_A2HSOFTINTCLR (CPU_CS_BASE_OFFS + 0x1C)
#define CPU_CS_VMIMSG (CPU_CS_BASE_OFFS + 0x34)
#define CPU_CS_VMIMSGAG0 (CPU_CS_BASE_OFFS + 0x38)
#define CPU_CS_VMIMSGAG1 (CPU_CS_BASE_OFFS + 0x3C)
#define CPU_CS_SCIACMD (CPU_CS_BASE_OFFS + 0x48)
/* HFI_CTRL_STATUS */
#define CPU_CS_SCIACMDARG0 (CPU_CS_BASE_OFFS + 0x4C)
#define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe
#define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100
#define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK 0x40000000
/* HFI_QTBL_INFO */
#define CPU_CS_SCIACMDARG1 (CPU_CS_BASE_OFFS + 0x50)
/* HFI_QTBL_ADDR */
#define CPU_CS_SCIACMDARG2 (CPU_CS_BASE_OFFS + 0x54)
/* HFI_VERSION_INFO */
#define CPU_CS_SCIACMDARG3 (CPU_CS_BASE_OFFS + 0x58)
/* SFR_ADDR */
#define CPU_CS_SCIBCMD (CPU_CS_BASE_OFFS + 0x5C)
/* MMAP_ADDR */
#define CPU_CS_SCIBCMDARG0 (CPU_CS_BASE_OFFS + 0x60)
/* UC_REGION_ADDR */
#define CPU_CS_SCIBARG1 (CPU_CS_BASE_OFFS + 0x64)
/* UC_REGION_ADDR */
#define CPU_CS_SCIBARG2 (CPU_CS_BASE_OFFS + 0x68)
#define CPU_IC_SOFTINT (CPU_IC_BASE_OFFS + 0x18)
#define CPU_IC_SOFTINT_H2A_SHFT 0xF
/*
* --------------------------------------------------------------------------
* MODULE: wrapper
* --------------------------------------------------------------------------
*/
#define WRAPPER_BASE_OFFS 0x000E0000
#define WRAPPER_INTR_STATUS (WRAPPER_BASE_OFFS + 0x0C)
#define WRAPPER_INTR_STATUS_A2HWD_BMSK 0x10
#define WRAPPER_INTR_STATUS_A2H_BMSK 0x4
#define WRAPPER_INTR_MASK (WRAPPER_BASE_OFFS + 0x10)
#define WRAPPER_INTR_MASK_A2HWD_BMSK 0x10
#define WRAPPER_INTR_MASK_A2HVCODEC_BMSK 0x8
#define WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4
#define WRAPPER_INTR_CLEAR (WRAPPER_BASE_OFFS + 0x14)
#define WRAPPER_CPU_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x2000)
#define WRAPPER_CPU_CGC_DIS (WRAPPER_BASE_OFFS + 0x2010)
#define WRAPPER_CPU_STATUS (WRAPPER_BASE_OFFS + 0x2014)
#define CTRL_INIT CPU_CS_SCIACMD
#define CTRL_STATUS CPU_CS_SCIACMDARG0
#define CTRL_ERROR_STATUS__M \
CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK
#define CTRL_INIT_IDLE_MSG_BMSK \
CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK
#define CTRL_STATUS_PC_READY \
CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY
#define QTBL_INFO CPU_CS_SCIACMDARG1
#define QTBL_ADDR CPU_CS_SCIACMDARG2
#define VERSION_INFO CPU_CS_SCIACMDARG3
#define SFR_ADDR CPU_CS_SCIBCMD
#define MMAP_ADDR CPU_CS_SCIBCMDARG0
#define UC_REGION_ADDR CPU_CS_SCIBARG1
#define UC_REGION_SIZE CPU_CS_SCIBARG2
/* HFI_DSP_QTBL_ADDR
* 31:3 - HFI_DSP_QTBL_ADDR
* 4-byte aligned Address
*/
#define HFI_DSP_QTBL_ADDR CPU_CS_VMIMSG
/* HFI_DSP_UC_REGION_ADDR
* 31:20 - HFI_DSP_UC_REGION_ADDR
* 1MB aligned address.
* Uncached Region start Address. This region covers
* HFI DSP QTable,
* HFI DSP Queue Headers,
* HFI DSP Queues,
*/
#define HFI_DSP_UC_REGION_ADDR CPU_CS_VMIMSGAG0
/* HFI_DSP_UC_REGION_SIZE
* 31:20 - HFI_DSP_UC_REGION_SIZE
* Multiples of 1MB.
* Size of the DSP_UC_REGION Uncached Region
*/
#define HFI_DSP_UC_REGION_SIZE CPU_CS_VMIMSGAG1
/*
* --------------------------------------------------------------------------
* MODULE: vcodec noc error log registers
* --------------------------------------------------------------------------
*/
#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000
#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000
#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500
#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504
#define VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C
#endif

60
msm/vidc/hfi_iris1.c Normal file
View File

@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#include "hfi_common.h"
#include "hfi_io_common.h"
void __interrupt_init_iris1(struct venus_hfi_device *device)
{
u32 mask_val = 0;
/* All interrupts should be disabled initially 0x1F6 : Reset value */
mask_val = __read_register(device, WRAPPER_INTR_MASK);
/* Write 0 to unmask CPU and WD interrupts */
mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK |
WRAPPER_INTR_MASK_A2HCPU_BMSK);
__write_register(device, WRAPPER_INTR_MASK, mask_val);
}
void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device)
{
/* initialize CPU QTBL & UCREGION */
__write_register(device, UC_REGION_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, UC_REGION_SIZE, SHARED_QSIZE);
__write_register(device, QTBL_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, QTBL_INFO, 0x01);
if (device->sfr.align_device_addr)
__write_register(device, SFR_ADDR,
(u32)device->sfr.align_device_addr);
if (device->qdss.align_device_addr)
__write_register(device, MMAP_ADDR,
(u32)device->qdss.align_device_addr);
/* initialize DSP QTBL & UCREGION with CPU queues by default */
__write_register(device, HFI_DSP_QTBL_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE);
if (device->res->domain_cvp) {
/* initialize DSP QTBL & UCREGION with DSP queues */
__write_register(device, HFI_DSP_QTBL_ADDR,
(u32)device->dsp_iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_ADDR,
(u32)device->dsp_iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_SIZE,
device->dsp_iface_q_table.mem_data.size);
}
}
void __clock_config_on_enable_iris1(struct venus_hfi_device *device)
{
__write_register(device, WRAPPER_CPU_CGC_DIS, 0);
__write_register(device, WRAPPER_CPU_CLOCK_CONFIG, 0);
}

411
msm/vidc/hfi_iris2.c Normal file
View File

@ -0,0 +1,411 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#include "msm_vidc_debug.h"
#include "hfi_common.h"
#define VBIF_BASE_OFFS_IRIS2 0x00080000
#define CPU_BASE_OFFS_IRIS2 0x000A0000
#define AON_BASE_OFFS 0x000E0000
#define CPU_CS_BASE_OFFS_IRIS2 (CPU_BASE_OFFS_IRIS2)
#define CPU_IC_BASE_OFFS_IRIS2 (CPU_BASE_OFFS_IRIS2)
#define CPU_CS_A2HSOFTINTCLR_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x1C)
#define CPU_CS_VMIMSG_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x34)
#define CPU_CS_VMIMSGAG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x38)
#define CPU_CS_VMIMSGAG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x3C)
#define CPU_CS_SCIACMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x48)
#define CPU_CS_H2XSOFTINTEN_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x148)
/* HFI_CTRL_STATUS */
#define CPU_CS_SCIACMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x4C)
#define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2 0xfe
#define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2 0x100
#define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2 0x40000000
/* HFI_QTBL_INFO */
#define CPU_CS_SCIACMDARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x50)
/* HFI_QTBL_ADDR */
#define CPU_CS_SCIACMDARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x54)
/* HFI_VERSION_INFO */
#define CPU_CS_SCIACMDARG3_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x58)
/* SFR_ADDR */
#define CPU_CS_SCIBCMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x5C)
/* MMAP_ADDR */
#define CPU_CS_SCIBCMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x60)
/* UC_REGION_ADDR */
#define CPU_CS_SCIBARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x64)
/* UC_REGION_ADDR */
#define CPU_CS_SCIBARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x68)
/* FAL10 Feature Control */
#define CPU_CS_X2RPMh_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x168)
#define CPU_CS_X2RPMh_MASK0_BMSK_IRIS2 0x1
#define CPU_CS_X2RPMh_MASK0_SHFT_IRIS2 0x0
#define CPU_CS_X2RPMh_MASK1_BMSK_IRIS2 0x2
#define CPU_CS_X2RPMh_MASK1_SHFT_IRIS2 0x1
#define CPU_CS_X2RPMh_SWOVERRIDE_BMSK_IRIS2 0x4
#define CPU_CS_X2RPMh_SWOVERRIDE_SHFT_IRIS2 0x3
#define CPU_IC_SOFTINT_IRIS2 (CPU_IC_BASE_OFFS_IRIS2 + 0x150)
#define CPU_IC_SOFTINT_H2A_SHFT_IRIS2 0x0
/*
* --------------------------------------------------------------------------
* MODULE: wrapper
* --------------------------------------------------------------------------
*/
#define WRAPPER_BASE_OFFS_IRIS2 0x000B0000
#define WRAPPER_INTR_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x0C)
#define WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2 0x8
#define WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2 0x4
#define WRAPPER_INTR_MASK_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x10)
#define WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2 0x8
#define WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2 0x4
#define WRAPPER_CPU_CLOCK_CONFIG_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2000)
#define WRAPPER_CPU_CGC_DIS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2010)
#define WRAPPER_CPU_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2014)
#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x54)
#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x58)
/*
* --------------------------------------------------------------------------
* MODULE: tz_wrapper
* --------------------------------------------------------------------------
*/
#define WRAPPER_TZ_BASE_OFFS 0x000C0000
#define WRAPPER_TZ_CPU_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS)
#define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10)
#define CTRL_INIT_IRIS2 CPU_CS_SCIACMD_IRIS2
#define CTRL_STATUS_IRIS2 CPU_CS_SCIACMDARG0_IRIS2
#define CTRL_ERROR_STATUS__M_IRIS2 \
CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2
#define CTRL_INIT_IDLE_MSG_BMSK_IRIS2 \
CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2
#define CTRL_STATUS_PC_READY_IRIS2 \
CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2
#define QTBL_INFO_IRIS2 CPU_CS_SCIACMDARG1_IRIS2
#define QTBL_ADDR_IRIS2 CPU_CS_SCIACMDARG2_IRIS2
#define VERSION_INFO_IRIS2 CPU_CS_SCIACMDARG3_IRIS2
#define SFR_ADDR_IRIS2 CPU_CS_SCIBCMD_IRIS2
#define MMAP_ADDR_IRIS2 CPU_CS_SCIBCMDARG0_IRIS2
#define UC_REGION_ADDR_IRIS2 CPU_CS_SCIBARG1_IRIS2
#define UC_REGION_SIZE_IRIS2 CPU_CS_SCIBARG2_IRIS2
#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
/*
* --------------------------------------------------------------------------
* MODULE: vcodec noc error log registers (iris2)
* --------------------------------------------------------------------------
*/
#define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000
#define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200
#define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204
#define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208
#define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210
#define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218
#define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220
#define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224
#define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228
#define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C
#define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230
#define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
void __interrupt_init_iris2(struct venus_hfi_device *device)
{
u32 mask_val = 0;
/* All interrupts should be disabled initially 0x1F6 : Reset value */
mask_val = __read_register(device, WRAPPER_INTR_MASK_IRIS2);
/* Write 0 to unmask CPU and WD interrupts */
mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2|
WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2);
__write_register(device, WRAPPER_INTR_MASK_IRIS2, mask_val);
}
void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device)
{
__write_register(device, UC_REGION_ADDR_IRIS2,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, UC_REGION_SIZE_IRIS2, SHARED_QSIZE);
__write_register(device, QTBL_ADDR_IRIS2,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, QTBL_INFO_IRIS2, 0x01);
if (device->sfr.align_device_addr)
__write_register(device, SFR_ADDR_IRIS2,
(u32)device->sfr.align_device_addr);
if (device->qdss.align_device_addr)
__write_register(device, MMAP_ADDR_IRIS2,
(u32)device->qdss.align_device_addr);
}
void __power_off_iris2(struct venus_hfi_device *device)
{
u32 lpi_status, reg_status = 0, count = 0, max_count = 10;
if (!device->power_enabled)
return;
if (!(device->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2))
disable_irq_nosync(device->hal_data->irq);
device->intr_status = 0;
/* HPG 6.1.2 Step 1 */
__write_register(device, CPU_CS_X2RPMh_IRIS2, 0x3);
/* HPG 6.1.2 Step 2, noc to low power */
__write_register(device, AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1);
while (!reg_status && count < max_count) {
lpi_status =
__read_register(device,
AON_WRAPPER_MVP_NOC_LPI_STATUS);
reg_status = lpi_status & BIT(0);
dprintk(VIDC_DBG,
"Noc: lpi_status %d noc_status %d (count %d)\n",
lpi_status, reg_status, count);
usleep_range(50, 100);
count++;
}
if (count == max_count) {
dprintk(VIDC_ERR,
"NOC not in qaccept status %d\n", reg_status);
}
/* HPG 6.1.2 Step 3, debug bridge to low power */
__write_register(device,
WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7);
reg_status = 0;
count = 0;
while ((reg_status != 0x7) && count < max_count) {
lpi_status = __read_register(device,
WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2);
reg_status = lpi_status & 0x7;
dprintk(VIDC_DBG,
"DBLP Set : lpi_status %d reg_status %d (count %d)\n",
lpi_status, reg_status, count);
usleep_range(50, 100);
count++;
}
if (count == max_count) {
dprintk(VIDC_ERR,
"DBLP Set: status %d\n", reg_status);
}
/* HPG 6.1.2 Step 4, debug bridge to lpi release */
__write_register(device,
WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x0);
lpi_status = 0x1;
count = 0;
while (lpi_status && count < max_count) {
lpi_status = __read_register(device,
WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2);
dprintk(VIDC_DBG,
"DBLP Release: lpi_status %d(count %d)\n",
lpi_status, count);
usleep_range(50, 100);
count++;
}
if (count == max_count) {
dprintk(VIDC_ERR,
"DBLP Release: lpi_status %d\n", lpi_status);
}
/* HPG 6.1.2 Step 6 */
__disable_unprepare_clks(device);
/* HPG 6.1.2 Step 7 & 8 */
if (call_venus_op(device, reset_ahb2axi_bridge, device))
dprintk(VIDC_ERR, "Failed to reset ahb2axi\n");
/* HPG 6.1.2 Step 5 */
if (__disable_regulators(device))
dprintk(VIDC_WARN, "Failed to disable regulators\n");
if (__unvote_buses(device))
dprintk(VIDC_WARN, "Failed to unvote for buses\n");
device->power_enabled = false;
}
int __prepare_pc_iris2(struct venus_hfi_device *device)
{
int rc = 0;
u32 wfi_status = 0, idle_status = 0, pc_ready = 0;
u32 ctrl_status = 0;
int count = 0;
const int max_tries = 10;
ctrl_status = __read_register(device, CTRL_STATUS_IRIS2);
pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS2;
idle_status = ctrl_status & BIT(30);
if (pc_ready) {
dprintk(VIDC_DBG, "Already in pc_ready state\n");
return 0;
}
wfi_status = BIT(0) & __read_register(device,
WRAPPER_TZ_CPU_STATUS);
if (!wfi_status || !idle_status) {
dprintk(VIDC_WARN, "Skipping PC, wfi status not set\n");
goto skip_power_off;
}
rc = __prepare_pc(device);
if (rc) {
dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc);
goto skip_power_off;
}
while (count < max_tries) {
wfi_status = BIT(0) & __read_register(device,
WRAPPER_TZ_CPU_STATUS);
ctrl_status = __read_register(device, CTRL_STATUS_IRIS2);
if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY_IRIS2))
break;
usleep_range(150, 250);
count++;
}
if (count == max_tries) {
dprintk(VIDC_ERR, "Skip PC. Core is not in right state\n");
goto skip_power_off;
}
return rc;
skip_power_off:
dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
wfi_status, idle_status, pc_ready, ctrl_status);
return -EAGAIN;
}
void __raise_interrupt_iris2(struct venus_hfi_device *device)
{
__write_register(device, CPU_IC_SOFTINT_IRIS2,
1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS2);
}
bool __watchdog_iris2(u32 intr_status)
{
bool rc = false;
if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2)
rc = true;
return rc;
}
void __noc_error_info_iris2(struct venus_hfi_device *device)
{
u32 val = 0;
val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val);
val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH);
dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val);
}
void __core_clear_interrupt_iris2(struct venus_hfi_device *device)
{
u32 intr_status = 0, mask = 0;
if (!device) {
dprintk(VIDC_ERR, "%s: NULL device\n", __func__);
return;
}
intr_status = __read_register(device, WRAPPER_INTR_STATUS_IRIS2);
mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2|
WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2|
CTRL_INIT_IDLE_MSG_BMSK_IRIS2);
if (intr_status & mask) {
device->intr_status |= intr_status;
device->reg_count++;
dprintk(VIDC_DBG,
"INTERRUPT for device: %pK: times: %d interrupt_status: %d\n",
device, device->reg_count, intr_status);
} else {
device->spur_count++;
}
__write_register(device, CPU_CS_A2HSOFTINTCLR_IRIS2, 1);
}
int __boot_firmware_iris2(struct venus_hfi_device *device)
{
int rc = 0;
u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000;
ctrl_init_val = BIT(0);
if (device->res->domain_cvp)
ctrl_init_val |= BIT(1);
__write_register(device, CTRL_INIT_IRIS2, ctrl_init_val);
while (!ctrl_status && count < max_tries) {
ctrl_status = __read_register(device, CTRL_STATUS_IRIS2);
if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS2) == 0x4) {
dprintk(VIDC_ERR, "invalid setting for UC_REGION\n");
break;
}
usleep_range(50, 100);
count++;
}
if (count >= max_tries) {
dprintk(VIDC_ERR, "Error booting up vidc firmware\n");
rc = -ETIME;
}
/* Enable interrupt before sending commands to venus */
__write_register(device, CPU_CS_H2XSOFTINTEN_IRIS2, 0x1);
__write_register(device, CPU_CS_X2RPMh_IRIS2, 0x0);
return rc;
}

View File

@ -11,7 +11,6 @@
#include <linux/soc/qcom/smem.h>
#include <soc/qcom/socinfo.h>
#include "vidc_hfi_helper.h"
#include "vidc_hfi_io.h"
#include "msm_vidc_debug.h"
#include "vidc_hfi.h"

View File

@ -1391,16 +1391,13 @@ static int msm_venc_resolve_rc_enable(struct msm_vidc_inst *inst,
static int msm_venc_resolve_rate_control(struct msm_vidc_inst *inst,
struct v4l2_ctrl *ctrl)
{
struct v4l2_ctrl *rc_enable;
if (inst->rc_type == RATE_CONTROL_LOSSLESS) {
dprintk(VIDC_DBG,
"Skip RC mode when enabling lossless encoding\n");
return 0;
}
rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE);
if (!rc_enable->val) {
if (inst->rc_type == RATE_CONTROL_OFF) {
dprintk(VIDC_ERR,
"RC is not enabled.\n");
return -EINVAL;
@ -2617,7 +2614,6 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst)
struct v4l2_ctrl *i_qp = NULL;
struct v4l2_ctrl *p_qp = NULL;
struct v4l2_ctrl *b_qp = NULL;
struct v4l2_ctrl *rc_enable = NULL;
struct hfi_quantization qp;
if (!inst || !inst->core) {
@ -2633,7 +2629,6 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst)
i_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP);
p_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP);
b_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP);
rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE);
/*
* When RC is ON:
@ -2642,7 +2637,7 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst)
* I_QP value must be set by client.
* If other QP value is invalid, then, assign I_QP value to it.
*/
if (rc_enable->val) {
if (inst->rc_type != RATE_CONTROL_OFF) {
if (!(inst->client_set_ctrls & CLIENT_SET_I_QP))
qp.enable &= ~QP_ENABLE_I;
if (!(inst->client_set_ctrls & CLIENT_SET_P_QP))
@ -2829,7 +2824,6 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst)
u32 mb_per_frame, fps, mbps, bitrate, max_slices;
u32 slice_val, slice_mode, max_avg_slicesize;
u32 rc_mode, output_width, output_height;
struct v4l2_ctrl *rc_enable;
u32 codec;
if (!inst || !inst->core) {
@ -2845,13 +2839,11 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst)
slice_val = 0;
bitrate = inst->clk_data.bitrate;
fps = inst->clk_data.frame_rate;
fps = inst->clk_data.frame_rate >> 16;
rc_mode = inst->rc_type;
rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE);
if (fps > 60 ||
(rc_enable->val &&
rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR &&
rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) {
if (fps > 60 || (!(rc_mode == RATE_CONTROL_OFF ||
rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR ||
rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))) {
goto set_and_exit;
}
@ -2896,8 +2888,11 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst)
mbps <= NUM_MBS_PER_SEC(1088, 1920, 60)) {
max_slices = inst->capability.cap[CAP_SLICE_BYTE].max ?
inst->capability.cap[CAP_SLICE_BYTE].max : 1;
max_avg_slicesize = ((bitrate / fps) / 8) / max_slices;
slice_val = max(slice_val, max_avg_slicesize);
if (rc_mode != RATE_CONTROL_OFF) {
max_avg_slicesize =
((bitrate / fps) / 8) / max_slices;
slice_val = max(slice_val, max_avg_slicesize);
}
}
}
@ -2928,7 +2923,6 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst)
int rc = 0;
struct hfi_device *hdev;
struct v4l2_ctrl *ctrl = NULL;
struct v4l2_ctrl *rc_mode = NULL;
struct hfi_intra_refresh intra_refresh;
struct v4l2_format *f;
@ -2938,9 +2932,8 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst)
}
hdev = inst->core->device;
rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE);
if (!(rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR ||
rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
if (!(inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR ||
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
return 0;
/* Firmware supports only random mode */
@ -3616,6 +3609,11 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst)
if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264))
return 0;
if (!(inst->rc_type == RATE_CONTROL_OFF ||
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR))
return 0;
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT);
if (!ctrl->val)
return 0;
@ -3706,7 +3704,6 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
int rc = 0;
struct hfi_device *hdev;
struct hfi_quantization qp;
struct v4l2_ctrl *rc_enable;
if (!inst || !inst->core) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
@ -3714,8 +3711,7 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
}
hdev = inst->core->device;
rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE);
if (rc_enable->val) {
if (inst->rc_type != RATE_CONTROL_OFF) {
dprintk(VIDC_ERR, "%s: Dyn qp is set only when RC is OFF\n",
__func__);
return -EINVAL;
@ -3958,6 +3954,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst)
if (rc)
goto exit;
rc = msm_venc_set_rate_control(inst);
if (rc)
goto exit;
rc = msm_venc_set_vbv_delay(inst);
if (rc)
goto exit;
rc = msm_venc_set_bitrate_savings_mode(inst);

View File

@ -1432,12 +1432,6 @@ static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst)
return;
msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE,
&inst->capability.cap[CAP_BITRATE]);
msm_vidc_comm_update_ctrl(inst,
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
&inst->capability.cap[CAP_SLICE_BYTE]);
msm_vidc_comm_update_ctrl(inst,
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
&inst->capability.cap[CAP_SLICE_MB]);
msm_vidc_comm_update_ctrl(inst,
V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT,
&inst->capability.cap[CAP_LTR_COUNT]);

View File

@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include "msm_vidc_debug.h"
#include "vidc_hfi_api.h"
#include "venus_hfi.h"
#include "hfi_common.h"
struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type,
u32 device_id, struct msm_vidc_platform_resources *res,

View File

@ -1,220 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __VIDC_HFI_IO_H__
#define __VIDC_HFI_IO_H__
#include <linux/io.h>
#define VIDC_VBIF_BASE_OFFS 0x00080000
#define VIDC_CPU_BASE_OFFS 0x000A0000
#define VIDEO_CC_BASE_OFFS 0x000F0000
#define VIDC_AON_BASE_OFFS 0x000E0000
#define VIDC_CPU_CS_BASE_OFFS (VIDC_CPU_BASE_OFFS)
#define VIDC_CPU_IC_BASE_OFFS (VIDC_CPU_BASE_OFFS)
#define VIDC_CPU_CS_A2HSOFTINTEN (VIDC_CPU_CS_BASE_OFFS + 0x10)
#define VIDC_CPU_CS_A2HSOFTINTENCLR (VIDC_CPU_CS_BASE_OFFS + 0x14)
#define VIDC_CPU_CS_A2HSOFTINT (VIDC_CPU_CS_BASE_OFFS + 0x18)
#define VIDC_CPU_CS_A2HSOFTINTCLR (VIDC_CPU_CS_BASE_OFFS + 0x1C)
#define VIDC_CPU_CS_VMIMSG (VIDC_CPU_CS_BASE_OFFS + 0x34)
#define VIDC_CPU_CS_VMIMSGAG0 (VIDC_CPU_CS_BASE_OFFS + 0x38)
#define VIDC_CPU_CS_VMIMSGAG1 (VIDC_CPU_CS_BASE_OFFS + 0x3C)
#define VIDC_CPU_CS_VMIMSGAG2 (VIDC_CPU_CS_BASE_OFFS + 0x40)
#define VIDC_CPU_CS_VMIMSGAG3 (VIDC_CPU_CS_BASE_OFFS + 0x44)
#define VIDC_CPU_CS_SCIACMD (VIDC_CPU_CS_BASE_OFFS + 0x48)
#define VIDC_CPU_CS_H2XSOFTINTEN (VIDC_CPU_CS_BASE_OFFS + 0x148)
/* HFI_CTRL_STATUS */
#define VIDC_CPU_CS_SCIACMDARG0 (VIDC_CPU_CS_BASE_OFFS + 0x4C)
#define VIDC_CPU_CS_SCIACMDARG0_BMSK 0xff
#define VIDC_CPU_CS_SCIACMDARG0_SHFT 0x0
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT 0x1
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK 0x1
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT 0x0
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK 0x40000000
/* HFI_QTBL_INFO */
#define VIDC_CPU_CS_SCIACMDARG1 (VIDC_CPU_CS_BASE_OFFS + 0x50)
/* HFI_QTBL_ADDR */
#define VIDC_CPU_CS_SCIACMDARG2 (VIDC_CPU_CS_BASE_OFFS + 0x54)
/* HFI_VERSION_INFO */
#define VIDC_CPU_CS_SCIACMDARG3 (VIDC_CPU_CS_BASE_OFFS + 0x58)
/* VIDC_SFR_ADDR */
#define VIDC_CPU_CS_SCIBCMD (VIDC_CPU_CS_BASE_OFFS + 0x5C)
/* VIDC_MMAP_ADDR */
#define VIDC_CPU_CS_SCIBCMDARG0 (VIDC_CPU_CS_BASE_OFFS + 0x60)
/* VIDC_UC_REGION_ADDR */
#define VIDC_CPU_CS_SCIBARG1 (VIDC_CPU_CS_BASE_OFFS + 0x64)
/* VIDC_UC_REGION_ADDR */
#define VIDC_CPU_CS_SCIBARG2 (VIDC_CPU_CS_BASE_OFFS + 0x68)
#define VIDC_CPU_CS_SCIBARG3 (VIDC_CPU_CS_BASE_OFFS + 0x6C)
/* FAL10 Feature Control */
#define VIDC_CPU_CS_X2RPMh (VIDC_CPU_CS_BASE_OFFS + 0x168)
#define VIDC_CPU_CS_X2RPMh_MASK0_BMSK 0x1
#define VIDC_CPU_CS_X2RPMh_MASK0_SHFT 0x0
#define VIDC_CPU_CS_X2RPMh_MASK1_BMSK 0x2
#define VIDC_CPU_CS_X2RPMh_MASK1_SHFT 0x1
#define VIDC_CPU_CS_X2RPMh_SWOVERRIDE_BMSK 0x4
#define VIDC_CPU_CS_X2RPMh_SWOVERRIDE_SHFT 0x3
#define VIDC_CPU_IC_SOFTINT (VIDC_CPU_IC_BASE_OFFS + 0x150)
#define VIDC_CPU_IC_SOFTINT_H2A_BMSK 0x1
#define VIDC_CPU_IC_SOFTINT_H2A_SHFT 0x0
#define VIDC_CPU_IC_SOFTINTCLEAR (VIDC_CPU_IC_BASE_OFFS + 0x154)
/*
* --------------------------------------------------------------------------
* MODULE: vidc_wrapper
* --------------------------------------------------------------------------
*/
#define VIDC_WRAPPER_BASE_OFFS 0x000B0000
#define VIDC_WRAPPER_HW_VERSION (VIDC_WRAPPER_BASE_OFFS + 0x00)
#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_MASK 0x78000000
#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT 28
#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_MASK 0xFFF0000
#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT 16
#define VIDC_WRAPPER_HW_VERSION_STEP_VERSION_MASK 0xFFFF
#define VIDC_WRAPPER_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x04)
#define VIDC_WRAPPER_INTR_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x0C)
#define VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK 0x8
#define VIDC_WRAPPER_INTR_STATUS_A2HWD_SHFT 0x3
#define VIDC_WRAPPER_INTR_STATUS_A2H_BMSK 0x4
#define VIDC_WRAPPER_INTR_STATUS_A2H_SHFT 0x2
#define VIDC_WRAPPER_INTR_MASK (VIDC_WRAPPER_BASE_OFFS + 0x10)
#define VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK 0x8
#define VIDC_WRAPPER_INTR_MASK_A2HWD_SHFT 0x3
#define VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK 0x8
#define VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4
#define VIDC_WRAPPER_INTR_MASK_A2HCPU_SHFT 0x2
#define VIDC_WRAPPER_CPU_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x2000)
#define VIDC_WRAPPER_CPU_CGC_DIS (VIDC_WRAPPER_BASE_OFFS + 0x2010)
#define VIDC_WRAPPER_CPU_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x2014)
#define VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (VIDC_WRAPPER_BASE_OFFS + 0x54)
#define VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x58)
/*
* --------------------------------------------------------------------------
* MODULE: vidc_tz_wrapper
* --------------------------------------------------------------------------
*/
#define VIDC_WRAPPER_TZ_BASE_OFFS 0x000C0000
#define VIDC_WRAPPER_TZ_CPU_CLOCK_CONFIG (VIDC_WRAPPER_TZ_BASE_OFFS)
#define VIDC_WRAPPER_TZ_CPU_STATUS (VIDC_WRAPPER_TZ_BASE_OFFS + 0x10)
#define VIDC_VENUS_VBIF_CLK_ON (VIDC_VBIF_BASE_OFFS + 0x4)
#define VENUS_VBIF_AXI_HALT_CTRL0 (VIDC_VBIF_BASE_OFFS + 0x208)
#define VENUS_VBIF_AXI_HALT_CTRL1 (VIDC_VBIF_BASE_OFFS + 0x20C)
#define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ BIT(0)
#define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK BIT(0)
#define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US 500000
#define VIDC_CTRL_INIT VIDC_CPU_CS_SCIACMD
#define VIDC_CTRL_STATUS VIDC_CPU_CS_SCIACMDARG0
#define VIDC_CTRL_ERROR_STATUS__M \
VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK
#define VIDC_CTRL_INIT_IDLE_MSG_BMSK \
VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK
#define VIDC_CTRL_STATUS_PC_READY \
VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY
#define VIDC_QTBL_INFO VIDC_CPU_CS_SCIACMDARG1
#define VIDC_QTBL_ADDR VIDC_CPU_CS_SCIACMDARG2
#define VIDC_VERSION_INFO VIDC_CPU_CS_SCIACMDARG3
#define VIDC_SFR_ADDR VIDC_CPU_CS_SCIBCMD
#define VIDC_MMAP_ADDR VIDC_CPU_CS_SCIBCMDARG0
#define VIDC_UC_REGION_ADDR VIDC_CPU_CS_SCIBARG1
#define VIDC_UC_REGION_SIZE VIDC_CPU_CS_SCIBARG2
/* HFI_DSP_QTBL_ADDR
* 31:3 - HFI_DSP_QTBL_ADDR
* 4-byte aligned Address
*/
#define HFI_DSP_QTBL_ADDR VIDC_CPU_CS_VMIMSG
/* HFI_DSP_UC_REGION_ADDR
* 31:20 - HFI_DSP_UC_REGION_ADDR
* 1MB aligned address.
* Uncached Region start Address. This region covers
* HFI DSP QTable,
* HFI DSP Queue Headers,
* HFI DSP Queues,
*/
#define HFI_DSP_UC_REGION_ADDR VIDC_CPU_CS_VMIMSGAG0
/* HFI_DSP_UC_REGION_SIZE
* 31:20 - HFI_DSP_UC_REGION_SIZE
* Multiples of 1MB.
* Size of the DSP_UC_REGION Uncached Region
*/
#define HFI_DSP_UC_REGION_SIZE VIDC_CPU_CS_VMIMSGAG1
/*
* --------------------------------------------------------------------------
* MODULE: vcodec noc error log registers (iris1)
* --------------------------------------------------------------------------
*/
#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000
#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000
#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500
#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504
#define VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538
#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C
#define VIDC_AON_WRAPPER_MVP_NOC_LPI_CONTROL (VIDC_AON_BASE_OFFS)
#define VIDC_AON_WRAPPER_MVP_NOC_LPI_STATUS (VIDC_AON_BASE_OFFS + 0x4)
/*
* --------------------------------------------------------------------------
* MODULE: vcodec noc error log registers (iris2)
* --------------------------------------------------------------------------
*/
#define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000
#define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200
#define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204
#define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208
#define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210
#define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218
#define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220
#define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224
#define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228
#define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C
#define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230
#define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
#
#endif