From da37a31d45c83a4dc307f94a568553797afdd869 Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Wed, 20 May 2020 11:01:16 +0800 Subject: [PATCH] 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 --- drivers/mxc/vpu_malone/vpu_b0.c | 86 ++++++++++++++++++-------------- drivers/mxc/vpu_malone/vpu_rpc.c | 50 +++++++++++++++++++ drivers/mxc/vpu_malone/vpu_rpc.h | 3 ++ 3 files changed, 102 insertions(+), 37 deletions(-) diff --git a/drivers/mxc/vpu_malone/vpu_b0.c b/drivers/mxc/vpu_malone/vpu_b0.c index dc9d4d5727f7..387f8da03d06 100644 --- a/drivers/mxc/vpu_malone/vpu_b0.c +++ b/drivers/mxc/vpu_malone/vpu_b0.c @@ -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); diff --git a/drivers/mxc/vpu_malone/vpu_rpc.c b/drivers/mxc/vpu_malone/vpu_rpc.c index 6b0c41f338f2..7057b12b0cb8 100644 --- a/drivers/mxc/vpu_malone/vpu_rpc.c +++ b/drivers/mxc/vpu_malone/vpu_rpc.c @@ -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; diff --git a/drivers/mxc/vpu_malone/vpu_rpc.h b/drivers/mxc/vpu_malone/vpu_rpc.h index cbbfa6a4b62f..661746fb7acd 100644 --- a/drivers/mxc/vpu_malone/vpu_rpc.h +++ b/drivers/mxc/vpu_malone/vpu_rpc.h @@ -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,