void VPP_dhub_sem_clear(void) { int instat; HDL_dhub2d *pDhubHandle; int dhubID; int status; HDL_semaphore *pSemHandle = thinvpp_obj->pSemHandle; instat = semaphore_chk_full(pSemHandle, -1); if (bTST(instat, avioDhubSemMap_vpp_vppCPCB0_intr)){ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr); } else if (bTST(instat, avioDhubSemMap_vpp_vppCPCB2_intr)){ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB2_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB2_intr); } dhubID = avioDhubChMap_vpp_BCM_R; pDhubHandle = &VPP_dhubHandle; /* clear BCM interrupt */ pSemHandle = dhub_semaphore(&(pDhubHandle->dhub)); status = semaphore_chk_full(pSemHandle, dhubID); while (status) { semaphore_pop(pSemHandle, dhubID, 1); semaphore_clr_full(pSemHandle, dhubID); status = semaphore_chk_full(pSemHandle, dhubID); } return; }
/********************************************************************* * FUNCTION: do the hardware transaction * PARAMS: *buf - pointer to the buffer descriptor ********************************************************************/ void THINVPP_BCMBUF_HardwareTrans(BCMBUF *pbcmbuf, int block) { HDL_semaphore *pSemHandle; HDL_dhub2d *pDhubHandle; unsigned int bcm_sched_cmd[2]; int dhubID; unsigned int *start; int status; int size; if (pbcmbuf->subID == CPCB_1) start = pbcmbuf->dv1_head; else if (pbcmbuf->subID == CPCB_3) start = pbcmbuf->dv3_head; else start = pbcmbuf->head; size = (int)pbcmbuf->writer-(int)start; if (size <= 0) return; /* flush data in D$ */ FLUSH_DCACHE_RANGE(start, size); #if __LINUX_KERNEL__ start = (unsigned int *)virt_to_phys(start); #endif /* start BCM engine */ dhubID = avioDhubChMap_vpp_BCM_R; pDhubHandle = &VPP_dhubHandle; /* clear BCM interrupt */ pSemHandle = dhub_semaphore(&(pDhubHandle->dhub)); status = semaphore_chk_full(pSemHandle, dhubID); while (status) { semaphore_pop(pSemHandle, dhubID, 1); semaphore_clr_full(pSemHandle, dhubID); status = semaphore_chk_full(pSemHandle, dhubID); } dhub_channel_generate_cmd(&(pDhubHandle->dhub), dhubID, (int)start, (int)size, 0, 0, 0, 1, bcm_sched_cmd); while( !BCM_SCHED_PushCmd(BCM_SCHED_Q12, bcm_sched_cmd, NULL)); if (block){ /* check BCM interrupt */ pSemHandle = dhub_semaphore(&(pDhubHandle->dhub)); status = semaphore_chk_full(pSemHandle, dhubID); while (!status) { status = semaphore_chk_full(pSemHandle, dhubID); } /* clear BCM interrupt */ semaphore_pop(pSemHandle, dhubID, 1); semaphore_clr_full(pSemHandle, dhubID); } return; }
static irqreturn_t fastlogo_devices_vpp_isr(int irq, void *dev_id) { int instat; HDL_semaphore *pSemHandle; u64 cpcb0_isr_time_current; ++fastlogo_ctx.count; logo_isr_count++; cpcb0_isr_time_current = cpu_clock(smp_processor_id()); last_isr_interval = (unsigned) (cpcb0_isr_time_current - last_isr_time); last_isr_time = cpcb0_isr_time_current; #if LOGO_TIME_PROFILE { u64 curr_interval; if (cpcb0_isr_time_previous) { curr_interval = cpcb0_isr_time_current - cpcb0_isr_time_previous; if (logo_tp_count < LOGO_TP_MAX_COUNT) lat[logo_tp_count++] = curr_interval; } cpcb0_isr_time_previous = cpcb0_isr_time_current; } #endif /* VPP interrupt handling */ pSemHandle = dhub_semaphore(&VPP_dhubHandle.dhub); instat = semaphore_chk_full(pSemHandle, -1); if (bTST(instat, avioDhubSemMap_vpp_vppCPCB0_intr)) { /* our CPCB interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr); if(logo_isr_count > 1) { THINVPP_CPCB_ISR_service(thinvpp_obj, CPCB_1); } } #if LOGO_TIME_PROFILE if (logo_tp_count) { u64 curr_interval = cpu_clock(0) - cpcb0_isr_time_current; if ((logo_tp_count-1) < LOGO_TP_MAX_COUNT) lat2[logo_tp_count-1] = curr_interval; } #endif return IRQ_HANDLED; }
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; }
static irqreturn_t pe_devices_aout_isr(int irq, void *dev_id) { int instat; UNSG32 chanId; HDL_semaphore *pSemHandle; PIC_SetPerPIC_PerVector(CPUINDEX, irq, PIC_INT_DISABLE, PIC_INT_DISABLE); pSemHandle = dhub_semaphore(&AG_dhubHandle.dhub); instat = semaphore_chk_full(pSemHandle, -1); for (chanId = avioDhubChMap_ag_MA0_R; chanId <= avioDhubChMap_ag_MA3_R; chanId++) { if (bTST(instat, chanId)) { semaphore_pop(pSemHandle, chanId, 1); semaphore_clr_full(pSemHandle, chanId); // clear source if(chanId == avioDhubChMap_ag_MA0_R) { tasklet_hi_schedule(&pe_ma_tasklet); } } } chanId = avioDhubChMap_ag_SA_R; { if (bTST(instat, chanId)) { semaphore_pop(pSemHandle, chanId, 1); semaphore_clr_full(pSemHandle, chanId); tasklet_hi_schedule(&pe_st_tasklet); } } chanId = avioDhubChMap_ag_SPDIF_R; { if (bTST(instat, chanId)) { semaphore_pop(pSemHandle, chanId, 1); semaphore_clr_full(pSemHandle, chanId); tasklet_hi_schedule(&pe_spdif_tasklet); } } chanId = avioDhubChMap_ag_APPDAT_W; if (bTST(instat, chanId)) { semaphore_pop(pSemHandle, chanId, 1); semaphore_clr_full(pSemHandle, chanId); tasklet_hi_schedule(&pe_app_tasklet); } chanId = avioDhubChMap_ag_PG_ENG_W; if (bTST(instat, chanId)) { semaphore_pop(pSemHandle, chanId, 1); semaphore_clr_full(pSemHandle, chanId); tasklet_hi_schedule(&pe_pg_done_tasklet); } chanId = avioDhubSemMap_ag_spu_intr0; if (bTST(instat, chanId)) { semaphore_pop(pSemHandle, chanId, 1); semaphore_clr_full(pSemHandle, chanId); tasklet_hi_schedule(&pe_rle_err_tasklet); } chanId = avioDhubSemMap_ag_spu_intr1; if (bTST(instat, chanId)) { semaphore_pop(pSemHandle, chanId, 1); semaphore_clr_full(pSemHandle, chanId); tasklet_hi_schedule(&pe_rle_done_tasklet); } PIC_SetPerPIC_PerVector(CPUINDEX, irq, PIC_INT_ENABLE, PIC_INT_ENABLE); return IRQ_HANDLED; }
static irqreturn_t pe_devices_vpp_isr(int irq, void *dev_id) { INT instat; HDL_semaphore *pSemHandle; #if 0 GA_REG_WORD32_READ(0xf7e82C00+0x04 + 7*0x14, &val); vpp_int_time = DEBUG_TIMER_VALUE - val; #endif /* disable interrupt */ PIC_SetPerPIC_PerVector(CPUINDEX, irq, PIC_INT_DISABLE, PIC_INT_DISABLE); /* VPP interrupt handling */ pSemHandle = dhub_semaphore(&VPP_dhubHandle.dhub); instat = semaphore_chk_full(pSemHandle, -1); if (bTST(instat, avioDhubSemMap_vpp_vppCPCB0_intr)) { /* CPCB-0 interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB0_intr); /* Clear the bits for CPCB0 VDE interrupt */ if (bTST(instat, avioDhubSemMap_vpp_vppOUT4_intr)){ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT4_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT4_intr); bCLR(instat, avioDhubSemMap_vpp_vppOUT4_intr); } start_vbi_dma_transaction(0); start_vbi_bcm_transaction(0); } if (bTST(instat, avioDhubSemMap_vpp_vppCPCB1_intr)){ /* CPCB-1 interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB1_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB1_intr); /* Clear the bits for CPCB1 VDE interrupt */ if (bTST(instat, avioDhubSemMap_vpp_vppOUT5_intr)){ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT5_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT5_intr); bCLR(instat, avioDhubSemMap_vpp_vppOUT5_intr); } start_vbi_dma_transaction(1); start_vbi_bcm_transaction(1); } if (bTST(instat, avioDhubSemMap_vpp_vppCPCB2_intr)){ /* CPCB-2 interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppCPCB2_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppCPCB2_intr); /* Clear the bits for CPCB2 VDE interrupt */ if (bTST(instat, avioDhubSemMap_vpp_vppOUT6_intr)){ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT6_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT6_intr); bCLR(instat, avioDhubSemMap_vpp_vppOUT6_intr); } start_vbi_dma_transaction(2); start_vbi_bcm_transaction(2); } if (bTST(instat, avioDhubSemMap_vpp_vppOUT4_intr)){ /* CPCB-0 VDE interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT4_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT4_intr); start_vde_bcm_transaction(0); } if (bTST(instat, avioDhubSemMap_vpp_vppOUT5_intr)){ /* CPCB-1 VDE interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT5_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT5_intr); start_vde_bcm_transaction(1); } if (bTST(instat, avioDhubSemMap_vpp_vppOUT6_intr)){ /* CPCB-2 VDE interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT6_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT6_intr); start_vde_bcm_transaction(2); } if (bTST(instat, avioDhubSemMap_vpp_vppOUT3_intr)){ /* VOUT3 interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT3_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT3_intr); } if (bTST(instat, avioDhubSemMap_vpp_CH10_intr)){ /* HDMI audio interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_CH10_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_CH10_intr); } if (bTST(instat, avioDhubSemMap_vpp_vppOUT0_intr)){ /* VOUT0 interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT0_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT0_intr); } if (bTST(instat, avioDhubSemMap_vpp_vppOUT1_intr)){ /* VOUT1 interrupt */ /* clear interrupt */ semaphore_pop(pSemHandle, avioDhubSemMap_vpp_vppOUT1_intr, 1); semaphore_clr_full(pSemHandle, avioDhubSemMap_vpp_vppOUT1_intr); } #ifdef VPP_DBG pe_trace("ISR instat:%x\n", instat); #endif pe_vpp_tasklet.data = instat; tasklet_hi_schedule(&pe_vpp_tasklet); // enable ICC RX Soft IRQ // raise_softirq(VPP_SOFTIRQ); // up(&vpp_sem); /* enable again */ PIC_SetPerPIC_PerVector(CPUINDEX, irq, PIC_INT_ENABLE, PIC_INT_ENABLE); return IRQ_HANDLED; }