int pe_driver_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { VPP_DMA_INFO user_dma_info; int irqstat, bcmbuf_info[2]; pe_debug("pe_driver_ioctl cmd = %d\n", cmd); switch(cmd) { case VPP_IOCTL_VBI_DMA_CFGQ: if (copy_from_user(&user_dma_info, (void __user *)arg, sizeof(VPP_DMA_INFO))) return -EFAULT; dma_info[user_dma_info.cpcbID].DmaAddr = (UINT32)MV_SHM_GetNonCacheVirtAddr(user_dma_info.DmaAddr); dma_info[user_dma_info.cpcbID].DmaLen = user_dma_info.DmaLen; break; case VPP_IOCTL_VBI_BCM_CFGQ: if (copy_from_user(&user_dma_info, (void __user *)arg, sizeof(VPP_DMA_INFO))) return -EFAULT; vbi_bcm_info[user_dma_info.cpcbID].DmaAddr = (UINT32)MV_SHM_GetNonCacheVirtAddr(user_dma_info.DmaAddr); vbi_bcm_info[user_dma_info.cpcbID].DmaLen = user_dma_info.DmaLen; break; case VPP_IOCTL_VDE_BCM_CFGQ: if (copy_from_user(&user_dma_info, (void __user *)arg, sizeof(VPP_DMA_INFO))) return -EFAULT; vde_bcm_info[user_dma_info.cpcbID].DmaAddr = (UINT32)MV_SHM_GetNonCacheVirtAddr(user_dma_info.DmaAddr); vde_bcm_info[user_dma_info.cpcbID].DmaLen = user_dma_info.DmaLen; break; case VPP_IOCTL_TIMING: down(&vpp_sem); break; case VPP_IOCTL_START_BCM_TRANSACTION: if (copy_from_user(bcmbuf_info, (void __user *)arg, 2*sizeof(int))) return -EFAULT; spin_lock_irqsave(&bcm_spinlock, irqstat); dhub_channel_write_cmd(&(VPP_dhubHandle.dhub), avioDhubChMap_vpp_BCM_R, bcmbuf_info[0], bcmbuf_info[1], 0, 0, 0, 1, 0, 0); spin_unlock_irqrestore(&bcm_spinlock, irqstat); break; default: break; } return 0; }
static int __init fastlogo_device_init(unsigned int cpu_id) { int err; logo_time_0 = cpu_clock(0); // init context fastlogo_ctx.bcm_cmd_0 = bcm_cmd_0; fastlogo_ctx.bcm_cmd_0_len = bcm_cmd_0_len; fastlogo_ctx.bcm_cmd_a = bcm_cmd_a; fastlogo_ctx.bcm_cmd_a_len = bcm_cmd_a_len; fastlogo_ctx.bcm_cmd_n = bcm_cmd_n; fastlogo_ctx.bcm_cmd_n_len = bcm_cmd_n_len; fastlogo_ctx.bcm_cmd_z = bcm_cmd_z; fastlogo_ctx.bcm_cmd_z_len = bcm_cmd_z_len; fastlogo_ctx.bcmQ_len = bcmQ_len; fastlogo_ctx.dmaQ_len = 8*8; fastlogo_ctx.cfgQ_len = 8*8; /* set up logo frame */ fastlogo_ctx.length = yuv_logo_stride*yuv_logo_height; #ifndef YUV_LOGO_ALPHA vbuf.alpha = 255; #else vbuf.alpha = YUV_LOGO_ALPHA; #endif #ifndef YUV_LOGO_BGCOLOR vbuf.bgcolor = yuv_logo[0]; if ((vbuf.bgcolor & 0xff00ff) != 0x800080) vbuf.bgcolor = 0x00800080; // black #else vbuf.bgcolor = YUV_LOGO_BGCOLOR; #endif vbuf.m_disp_offset = 0; vbuf.m_active_left = ((720 - yuv_logo_width)/8)*4; // at center vbuf.m_active_top = ((480 - yuv_logo_height)/8)*4; // at center vbuf.m_buf_stride = yuv_logo_stride; vbuf.m_active_width = yuv_logo_width; vbuf.m_active_height = yuv_logo_height; #if LOGO_USE_SHM // use MV_SHM for logo buffer and 3 dhub queues to have contiguous memory fastlogo_ctx.mSHMSize = fastlogo_ctx.length + fastlogo_ctx.bcmQ_len + fastlogo_ctx.dmaQ_len + fastlogo_ctx.cfgQ_len; fastlogo_ctx.mSHMOffset = MV_SHM_NONCACHE_Malloc(fastlogo_ctx.mSHMSize, 4096); if (fastlogo_ctx.mSHMOffset == ERROR_SHM_MALLOC_FAILED) { return -1; } // put logo image in logo buffer fastlogo_ctx.logoBuf = (int *) MV_SHM_GetNonCacheVirtAddr(fastlogo_ctx.mSHMOffset); fastlogo_ctx.mapaddr = (unsigned int *) MV_SHM_GetNonCachePhysAddr(fastlogo_ctx.mSHMOffset); memcpy(fastlogo_ctx.logoBuf, yuv_logo, fastlogo_ctx.length); // arrange dhub queues and commands { char *shm = (char *) fastlogo_ctx.logoBuf; unsigned shm_phys = (unsigned) fastlogo_ctx.mapaddr; fastlogo_ctx.bcmQ = shm + fastlogo_ctx.length; fastlogo_ctx.dmaQ = fastlogo_ctx.bcmQ + fastlogo_ctx.bcmQ_len; fastlogo_ctx.cfgQ = fastlogo_ctx.dmaQ + fastlogo_ctx.dmaQ_len; fastlogo_ctx.bcmQ_phys = shm_phys + fastlogo_ctx.length; fastlogo_ctx.dmaQ_phys = fastlogo_ctx.bcmQ_phys + fastlogo_ctx.bcmQ_len; fastlogo_ctx.cfgQ_phys = fastlogo_ctx.dmaQ_phys + fastlogo_ctx.dmaQ_len; // pre-load vpp commands memcpy(fastlogo_ctx.bcmQ, bcm_cmd_0, bcm_cmd_0_len); // pre-load logo frame dma commands fastlogo_ctx.logo_dma_cmd_len = logo_dma_cmd_len; fastlogo_ctx.logo_frame_dma_cmd = logo_frame_dma_cmd; logo_frame_dma_cmd[2] = shm_phys; vbuf.m_pbuf_start = (void *) shm_phys; memcpy(fastlogo_ctx.dmaQ, logo_frame_dma_cmd, logo_dma_cmd_len); } #else fastlogo_ctx.logoBuf = kmalloc(fastlogo_ctx.length, GFP_KERNEL); if (!fastlogo_ctx.logoBuf) { gs_trace("kmalloc error\n"); return err; } memcpy(fastlogo_ctx.logoBuf, yuv_logo, fastlogo_ctx.length); fastlogo_ctx.mapaddr = (unsigned int *)dma_map_single(NULL, fastlogo_ctx.logoBuf, fastlogo_ctx.length, DMA_TO_DEVICE); err = dma_mapping_error(NULL, (dma_addr_t)fastlogo_ctx.logoBuf); if (err) { gs_trace("dma_mapping_error\n"); kfree(fastlogo_ctx.logoBuf); fastlogo_ctx.logoBuf = NULL; return err; } outer_cache.flush_range(virt_to_phys(fastlogo_ctx.logoBuf), virt_to_phys(fastlogo_ctx.logoBuf)+fastlogo_ctx.length); logo_frame_dma_cmd[2] = virt_to_phys(fastlogo_ctx.logoBuf); vbuf.m_pbuf_start = (void *) logo_frame_dma_cmd[2]; #endif fastlogo_ctx.logoBuf_2 = fastlogo_ctx.logoBuf; /* initialize dhub */ DhubInitialization(cpu_id, VPP_DHUB_BASE, VPP_HBO_SRAM_BASE, &VPP_dhubHandle, VPP_config, VPP_NUM_OF_CHANNELS); DhubInitialization(cpu_id, AG_DHUB_BASE, AG_HBO_SRAM_BASE, &AG_dhubHandle, AG_config, AG_NUM_OF_CHANNELS); MV_THINVPP_Create(MEMMAP_VPP_REG_BASE); MV_THINVPP_Reset(); MV_THINVPP_Config(); /* set output resolution */ MV_THINVPP_SetCPCBOutputResolution(CPCB_1, RES_525P5994, OUTPUT_BIT_DEPTH_8BIT); // use MAIN plane fastlogo_ctx.planes = 1; fastlogo_ctx.win.x = 0; fastlogo_ctx.win.y = 0; fastlogo_ctx.win.width = 720; fastlogo_ctx.win.height = 480; MV_THINVPP_SetMainDisplayFrame(&vbuf); MV_THINVPP_OpenDispWindow(PLANE_MAIN, &fastlogo_ctx.win, NULL); /* register ISR */ err = request_irq(IRQ_DHUBINTRAVIO0, fastlogo_devices_vpp_isr, IRQF_DISABLED, "fastlogo_module_vpp", NULL); if (unlikely(err < 0)) { gs_trace("vec_num:%5d, err:%8x\n", IRQ_DHUBINTRAVIO0, err); return err; } /* * using 3 for debugging legacy; should change to a more reasonable * number after clean-up */ cpcb_start_flag = 3; /* clean up and enable ISR */ VPP_dhub_sem_clear(); semaphore_pop(thinvpp_obj->pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr, 1); semaphore_clr_full(thinvpp_obj->pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr); THINVPP_Enable_ISR_Interrupt(thinvpp_obj, CPCB_1, 1); return 0; }