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;
}
Example #2
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;
}