1
0
Fork 0

LF-1405-2:[8QM_MEK/8QXP_MEK]mxc:vpu_malone: support insmod repeatly

1. the mu won't be really power off,
so we need restore the mu but not initialize it
2. the vpu is shared with vpu windsor,
so we don't do vpu reset when remove module.

Signed-off-by: Ming Qian <ming.qian@nxp.com>
5.4-rM2-2.2.x-imx-squashed
Ming Qian 2020-05-20 11:01:16 +08:00
parent 8ebff584ef
commit da37a31d45
3 changed files with 102 additions and 37 deletions

View File

@ -95,6 +95,7 @@ static void vpu_dec_event_decode_error(struct vpu_ctx *ctx);
static void vpu_calculate_performance(struct vpu_ctx *ctx, u_int32 uEvent, const char *str);
static void vpu_dec_cancel_work(struct vpu_dev *vpudev);
static void vpu_dec_alloc_mbi_dcp(struct vpu_ctx *ctx);
static bool is_vpu_poweroff(struct vpu_dev *vpudev);
#define CHECK_BIT(var, pos) (((var) >> (pos)) & 1)
@ -2688,6 +2689,18 @@ TB_API_DEC_FMT vpu_format_remap(uint32_t vdec_std)
return malone_format;
}
static void vpu_dec_send_cmd(struct vpu_dev *dev, u32 idx, u32 cmdid,
u32 cmdnum, u32 *local_cmddata)
{
WARN_ON(!dev || idx >= VPU_MAX_NUM_STREAMS);
mutex_lock(&dev->cmd_mutex);
rpc_send_cmd_buf(&dev->shared_mem, idx, cmdid, cmdnum, local_cmddata);
mb();
vpu_mu_send_msg(dev, COMMAND, 0xffff);
mutex_unlock(&dev->cmd_mutex);
}
static void do_send_cmd_to_firmware(struct vpu_ctx *ctx,
uint32_t idx, uint32_t cmdid,
uint32_t cmdnum, uint32_t *local_cmddata)
@ -2696,12 +2709,7 @@ static void do_send_cmd_to_firmware(struct vpu_ctx *ctx,
count_cmd(&ctx->statistic, cmdid);
record_log_info(ctx, LOG_COMMAND, cmdid, 0);
mutex_lock(&ctx->dev->cmd_mutex);
rpc_send_cmd_buf(&ctx->dev->shared_mem, idx, cmdid, cmdnum,
local_cmddata);
mb();
vpu_mu_send_msg(ctx->dev, COMMAND, 0xffff);
mutex_unlock(&ctx->dev->cmd_mutex);
vpu_dec_send_cmd(ctx->dev, idx, cmdid, cmdnum, local_cmddata);
}
static struct vpu_dec_cmd_request vpu_dec_cmds[] = {
@ -4808,14 +4816,6 @@ static void vpu_receive_msg_event(struct vpu_dev *dev)
static void vpu_handle_msg_data(struct vpu_dev *dev, u32 data)
{
if (data == 0xaa) {
rpc_init_shared_memory(&dev->shared_mem,
vpu_dec_cpu_phy_to_mu(dev, dev->m0_rpc_phy),
dev->m0_rpc_virt,
dev->m0_rpc_size);
dev->print_buf = dev->m0_rpc_virt + M0_PRINT_OFFSET;
rpc_set_system_cfg_value(dev->shared_mem.pSharedInterface,
VPU_REG_BASE);
mutex_lock(&dev->cmd_mutex);
vpu_mu_send_msg(dev, RPC_BUF_OFFSET,
vpu_dec_cpu_phy_to_mu(dev, dev->m0_rpc_phy));
@ -6136,9 +6136,9 @@ static int v4l2_open(struct file *filp)
}
}
dev->fw_is_ready = true;
create_fwlog_file(ctx->dev);
create_dbglog_file(ctx->dev);
}
create_fwlog_file(ctx->dev);
create_dbglog_file(ctx->dev);
mutex_unlock(&dev->dev_mutex);
rpc_set_stream_cfg_value(dev->shared_mem.pSharedInterface, ctx->str_index, vpu_dbe_num);
init_vpu_buffer(ctx);
@ -6370,13 +6370,6 @@ static void vpu_setup(struct vpu_dev *This)
vpu_dbg(LVL_INFO, "%s read_data=%x\n", __func__, read_data);
}
static void vpu_reset(struct vpu_dev *This)
{
vpu_dbg(LVL_BIT_FUNC, "enter %s\n", __func__);
writel(0x7, This->regs_base + SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL + SCB_BLK_CTRL_CACHE_RESET_CLR);
writel(0xffffffff, This->regs_base + DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL + MFD_BLK_CTRL_MFD_SYS_RESET_CLR);
}
static int vpu_enable_hw(struct vpu_dev *This)
{
vpu_dbg(LVL_BIT_FUNC, "%s()\n", __func__);
@ -6385,24 +6378,21 @@ static int vpu_enable_hw(struct vpu_dev *This)
}
static void vpu_disable_hw(struct vpu_dev *This)
{
vpu_reset(This);
}
static int swreset_vpu_firmware(struct vpu_dev *dev, u_int32 idx)
{
int ret = 0;
struct vpu_ctx *ctx;
if (!dev || !dev->ctx[idx])
if (!dev)
return 0;
ctx = dev->ctx[idx];
vpu_dbg(LVL_WARN, "SWRESET: swreset_vpu_firmware\n");
dev->firmware_started = false;
kfifo_reset(&dev->mu_msg_fifo);
reinit_completion(&dev->start_cmp);
do_send_cmd_to_firmware(ctx, 0, VID_API_CMD_FIRM_RESET, 0, NULL);
vpu_dec_send_cmd(dev, 0, VID_API_CMD_FIRM_RESET, 0, NULL);
if (!wait_for_completion_timeout(&dev->start_cmp, msecs_to_jiffies(10000))) {
vpu_err("error: %s() fail\n", __func__);
return -1;
@ -6518,8 +6508,6 @@ static int init_vpudev_parameters(struct vpu_dev *dev)
dev->hang_mask = 0;
dev->instance_mask = 0;
dev->fw_is_ready = false;
//firmware space for M0
dev->m0_p_fw_space_vir = ioremap_wc(dev->m0_p_fw_space_phy,
dev->m0_boot_size
@ -6529,8 +6517,6 @@ static int init_vpudev_parameters(struct vpu_dev *dev)
return -ENOMEM;
}
cleanup_firmware_memory(dev);
dev->m0_rpc_virt = ioremap_wc(dev->m0_rpc_phy,
dev->m0_rpc_size
);
@ -6539,11 +6525,34 @@ static int init_vpudev_parameters(struct vpu_dev *dev)
return -ENOMEM;
}
memset_io(dev->m0_rpc_virt, 0, dev->m0_rpc_size);
return 0;
}
static void vpu_dec_init_rpc(struct vpu_dev *dev)
{
cleanup_firmware_memory(dev);
memset_io(dev->m0_rpc_virt, 0, dev->m0_rpc_size);
rpc_init_shared_memory(&dev->shared_mem,
vpu_dec_cpu_phy_to_mu(dev, dev->m0_rpc_phy),
dev->m0_rpc_virt,
dev->m0_rpc_size);
dev->print_buf = dev->m0_rpc_virt + M0_PRINT_OFFSET;
rpc_set_system_cfg_value(dev->shared_mem.pSharedInterface,
VPU_REG_BASE);
dev->fw_is_ready = false;
}
static void vpu_dec_restore_rpc(struct vpu_dev *dev)
{
vpu_dbg(LVL_WARN, "restore vpu decoder\n");
rpc_restore_shared_memory(&dev->shared_mem,
vpu_dec_cpu_phy_to_mu(dev, dev->m0_rpc_phy),
dev->m0_rpc_virt);
dev->print_buf = dev->m0_rpc_virt + M0_PRINT_OFFSET;
swreset_vpu_firmware(dev, 0);
dev->fw_is_ready = true;
}
static void vpu_dec_init_ctx_work(struct vpu_dev *dev)
{
int i;
@ -6630,15 +6639,18 @@ static int vpu_probe(struct platform_device *pdev)
goto err_pm_runtime_get_sync;
}
vpu_enable_hw(dev);
ret = init_vpudev_parameters(dev);
if (ret) {
vpu_err("error: failed to init parameters for vpudev\n");
goto err_poweroff;
}
vpu_enable_hw(dev);
if (is_vpu_poweroff(dev))
vpu_dec_init_rpc(dev);
else
vpu_dec_restore_rpc(dev);
pm_runtime_put_sync(&pdev->dev);
device_create_file(&pdev->dev, &dev_attr_precheck_pattern);
vpu_dec_init_ctx_work(dev);

View File

@ -163,6 +163,56 @@ void rpc_init_shared_memory(struct shared_addr *This,
}
}
void rpc_restore_shared_memory(struct shared_addr *This,
unsigned long long base_phy_addr,
void *base_virt_addr)
{
pDEC_RPC_HOST_IFACE pSharedInterface;
unsigned int phy_addr;
This->shared_mem_phy = base_phy_addr;
This->shared_mem_vir = base_virt_addr;
pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
This->pSharedInterface = pSharedInterface;
phy_addr = base_phy_addr + sizeof(DEC_RPC_HOST_IFACE);
This->cmd_mem_phy = phy_addr;
This->cmd_mem_vir = This->shared_mem_vir + sizeof(DEC_RPC_HOST_IFACE);
phy_addr += CMD_SIZE;
This->msg_mem_phy = phy_addr;
This->msg_mem_vir = This->cmd_mem_vir + CMD_SIZE;
phy_addr += MSG_SIZE;
This->codec_mem_phy = phy_addr;
This->codec_mem_vir = This->msg_mem_vir + MSG_SIZE;
phy_addr += CODEC_SIZE;
This->jpeg_mem_phy = phy_addr;
This->jpeg_mem_vir = This->codec_mem_vir + CODEC_SIZE;
phy_addr += JPEG_SIZE;
This->seq_mem_phy = phy_addr;
This->seq_mem_vir = This->jpeg_mem_vir + JPEG_SIZE;
phy_addr += SEQ_SIZE;
This->pic_mem_phy = phy_addr;
This->pic_mem_vir = This->seq_mem_vir + SEQ_SIZE;
phy_addr += PIC_SIZE;
This->gop_mem_phy = phy_addr;
This->gop_mem_vir = This->pic_mem_vir + PIC_SIZE;
phy_addr += GOP_SIZE;
This->qmeter_mem_phy = phy_addr;
This->qmeter_mem_vir = This->gop_mem_vir + GOP_SIZE;
phy_addr += QMETER_SIZE;
This->dbglog_mem_phy = phy_addr;
This->dbglog_mem_vir = This->qmeter_mem_vir + QMETER_SIZE;
}
void rpc_set_stream_cfg_value(void *Interface, u_int32 str_idx, u_int32 vpu_dbe_num)
{
pDEC_RPC_HOST_IFACE pSharedInterface;

View File

@ -106,6 +106,9 @@ void rpc_init_shared_memory(struct shared_addr *This,
unsigned long long base_phy_addr,
void *base_virt_addr,
u_int32 total_size);
void rpc_restore_shared_memory(struct shared_addr *This,
unsigned long long base_phy_addr,
void *base_virt_addr);
void rpc_set_system_cfg_value(void *Interface, u_int32 regs_base);
void rpc_set_stream_cfg_value(void *Interface, u_int32 str_idx, u_int32 vpu_dbe_num);
void rpc_send_cmd_buf(struct shared_addr *This,