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,