int ovl2mem_trigger(int blocking, void *callback, unsigned int userdata) { int ret = -1; DISPFUNC(); if(pgc->need_trigger_path == 0) { DISPMSG("ovl2mem_trigger do not trigger\n"); return ret; } _ovl2mem_path_lock(__func__); dpmgr_path_start(pgc->dpmgr_handle, ovl2mem_cmdq_enabled()); dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_config, ovl2mem_cmdq_enabled()); cmdqRecWait(pgc->cmdq_handle_config, CMDQ_EVENT_DISP_WDMA1_EOF); dpmgr_path_stop(pgc->dpmgr_handle, ovl2mem_cmdq_enabled()); ///cmdqRecDumpCommand(pgc->cmdq_handle_config); cmdqRecFlushAsyncCallback(pgc->cmdq_handle_config, ovl2mem_callback, atomic_read(&g_trigger_ticket)); cmdqRecReset(pgc->cmdq_handle_config); pgc->need_trigger_path = 0; atomic_add(1, &g_trigger_ticket ); _ovl2mem_path_unlock(__func__); DISPMSG("ovl2mem_trigger done %d\n", get_ovl2mem_ticket()); return ret; }
int ovl2mem_trigger(int blocking, void *callback, unsigned int userdata) { int ret = -1; int fence_idx = 0; int layid = 0; DISPFUNC(); if(pgc->need_trigger_path == 0) { DISPMSG("ovl2mem_trigger do not trigger\n"); if ((atomic_read(&g_trigger_ticket) - atomic_read(&g_release_ticket)) == 1) { DISPMSG("ovl2mem_trigger(%x), configue input, but does not config output!!\n", pgc->session); for(layid = 0; layid < (HW_OVERLAY_COUNT + 1); layid++) { fence_idx = mtkfb_query_idx_by_ticket(pgc->session, layid, atomic_read(&g_trigger_ticket)); if(fence_idx >=0) { mtkfb_release_fence(pgc->session, layid, fence_idx); } } } return ret; } _ovl2mem_path_lock(__func__); dpmgr_path_start(pgc->dpmgr_handle, ovl2mem_cmdq_enabled()); dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_config, ovl2mem_cmdq_enabled()); cmdqRecWait(pgc->cmdq_handle_config, CMDQ_EVENT_DISP_WDMA1_EOF); dpmgr_path_stop(pgc->dpmgr_handle, ovl2mem_cmdq_enabled()); ///cmdqRecDumpCommand(pgc->cmdq_handle_config); cmdqRecFlushAsyncCallback(pgc->cmdq_handle_config, ovl2mem_callback, atomic_read(&g_trigger_ticket)); cmdqRecReset(pgc->cmdq_handle_config); pgc->need_trigger_path = 0; atomic_add(1, &g_trigger_ticket ); _ovl2mem_path_unlock(__func__); dprec_logger_frame_seq_begin(pgc->session, mtkfb_query_frm_seq_by_addr(pgc->session, 0, 0)); DISPMSG("ovl2mem_trigger ovl2mem_seq %d-seq %d\n", get_ovl2mem_ticket(), mtkfb_query_frm_seq_by_addr(pgc->session, 0, 0)); return ret; }
int32_t cmdqRecBackupUpdateSlot(cmdqRecHandle handle, cmdqBackupSlotHandle hBackupSlot, uint32_t slotIndex, uint32_t value) { #ifdef CMDQ_GPR_SUPPORT const CMDQ_DATA_REGISTER_ENUM valueRegId = CMDQ_DATA_REG_DEBUG; const CMDQ_DATA_REGISTER_ENUM destRegId = CMDQ_DATA_REG_DEBUG_DST; const CMDQ_EVENT_ENUM regAccessToken = CMDQ_SYNC_TOKEN_GPR_SET_4; const dma_addr_t dramAddr = hBackupSlot + slotIndex * sizeof(uint32_t); /* lock GPR because we may access it in multiple CMDQ HW threads */ cmdqRecWait(handle, regAccessToken); /* Assign 32-bit GRP with value */ cmdq_append_command( handle, CMDQ_CODE_RAW, (CMDQ_CODE_MOVE << 24) | (valueRegId << 16) | (4 << 21), /* argA is GPR */ value); /* Note that <MOVE> argB is 48-bit */ /* so writeAddress is split into 2 parts */ /* and we store address in 64-bit GPR (P0-P7) */ cmdq_append_command(handle, CMDQ_CODE_MOVE, #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT ((dramAddr >> 32) & 0xffff) | #endif ((destRegId & 0x1f) << 16) | (4 << 21), (uint32_t) dramAddr); /* write value in GPR to memory pointed by GPR */ cmdq_append_command( handle, CMDQ_CODE_RAW, (CMDQ_CODE_WRITE << 24) | (0 & 0xffff) | ((destRegId & 0x1f) << 16) | (6 << 21), valueRegId); /* release the GPR lock */ cmdqRecSetEventToken(handle, regAccessToken); return 0; #else CMDQ_ERR("func:%s failed since CMDQ dosen't support GPR\n", __func__); return -EFAULT; #endif /* CMDQ_GPR_SUPPORT */ }
int32_t cmdqRecBackupWriteRegisterFromSlot(cmdqRecHandle handle, cmdqBackupSlotHandle hBackupSlot, uint32_t slotIndex, uint32_t addr) { #ifdef CMDQ_GPR_SUPPORT const CMDQ_DATA_REGISTER_ENUM valueRegId = CMDQ_DATA_REG_DEBUG; const CMDQ_DATA_REGISTER_ENUM addrRegId = CMDQ_DATA_REG_DEBUG_DST; const CMDQ_EVENT_ENUM regAccessToken = CMDQ_SYNC_TOKEN_GPR_SET_4; const dma_addr_t dramAddr = hBackupSlot + slotIndex * sizeof(uint32_t); /* lock GPR because we may access it in multiple CMDQ HW threads */ cmdqRecWait(handle, regAccessToken); /* 1. MOVE slot address to addr GPR */ /* Note that <MOVE> argB is 48-bit */ /* so writeAddress is split into 2 parts */ /* and we store address in 64-bit GPR (P0-P7) */ cmdq_append_command(handle, CMDQ_CODE_MOVE, #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT ((dramAddr >> 32) & 0xffff) | #endif ((addrRegId & 0x1f) << 16) | (4 << 21), (uint32_t) dramAddr); /* argA is GPR */ /* 2. read value from src address, which is stroed in GPR, to valueRegId */ cmdq_append_command(handle, CMDQ_CODE_RAW, (CMDQ_CODE_READ << 24) | (0 & 0xffff) | ((addrRegId & 0x1f) << 16) | (6 << 21), valueRegId); /* 3. write from data register */ cmdqRecWriteFromDataRegister(handle, valueRegId, addr); /* release the GPR lock */ cmdqRecSetEventToken(handle, regAccessToken); return 0; #else CMDQ_ERR("func:%s failed since CMDQ dosen't support GPR\n", __func__); return -EFAULT; #endif /* CMDQ_GPR_SUPPORT */ }
static void _cmdq_build_trigger_loop(void) { int ret = 0; cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &(pgc->cmdq_handle_trigger)); EXT_DISP_LOG("ext_disp path trigger thread cmd handle=%p\n", pgc->cmdq_handle_trigger); cmdqRecReset(pgc->cmdq_handle_trigger); if(ext_disp_is_video_mode()) { // wait and clear stream_done, HW will assert mutex enable automatically in frame done reset. // todo: should let dpmanager to decide wait which mutex's eof. ret = cmdqRecWait(pgc->cmdq_handle_trigger, dpmgr_path_get_mutex(pgc->dpmgr_handle) + CMDQ_EVENT_MUTEX0_STREAM_EOF); ///dpmgr_path_get_mutex(pgc->dpmgr_handle) // for some module(like COLOR) to read hw register to GPR after frame done dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_AFTER_STREAM_EOF); } else { // DSI command mode doesn't have mutex_stream_eof, need use CMDQ token instead ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_CONFIG_DIRTY); //ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_MDP_DSI0_TE_SOF); // for operations before frame transfer, such as waiting for DSI TE dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_BEFORE_STREAM_SOF); // cleat frame done token, now the config thread will not allowed to config registers. // remember that config thread's priority is higher than trigger thread, so all the config queued before will be applied then STREAM_EOF token be cleared // this is what CMDQ did as "Merge" ret = cmdqRecClearEventToken(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_STREAM_EOF); // enable mutex, only cmd mode need this // this is what CMDQ did as "Trigger" dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_trigger, CMDQ_ENABLE); //ret = cmdqRecWrite(pgc->cmdq_handle_trigger, (unsigned int)(DISP_REG_CONFIG_MUTEX_EN(0))&0x1fffffff, 1, ~0); // waiting for frame done, because we can't use mutex stream eof here, so need to let dpmanager help to decide which event to wait // most time we wait rdmax frame done event. ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_DISP_RDMA1_EOF); dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_WAIT_STREAM_EOF_EVENT); // dsi is not idle rightly after rdma frame done, so we need to polling about 1us for dsi returns to idle // do not polling dsi idle directly which will decrease CMDQ performance dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_CHECK_IDLE_AFTER_STREAM_EOF); // for some module(like COLOR) to read hw register to GPR after frame done dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_AFTER_STREAM_EOF); // polling DSI idle //ret = cmdqRecPoll(pgc->cmdq_handle_trigger, 0x1401b00c, 0, 0x80000000); // polling wdma frame done //ret = cmdqRecPoll(pgc->cmdq_handle_trigger, 0x140060A0, 1, 0x1); // now frame done, config thread is allowed to config register now ret = cmdqRecSetEventToken(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_STREAM_EOF); // RUN forever!!!! BUG_ON(ret < 0); } // dump trigger loop instructions to check whether dpmgr_path_build_cmdq works correctly cmdqRecDumpCommand(pgc->cmdq_handle_trigger); EXT_DISP_LOG("ext display BUILD cmdq trigger loop finished\n"); return; }
static int jpeg_dec_ioctl(unsigned int cmd, unsigned long arg, struct file *file) { unsigned int* pStatus; unsigned int decResult; long timeout_jiff; JPEG_DEC_DRV_IN dec_params; JPEG_DEC_CONFIG_ROW dec_row_params ; JPEG_DEC_CONFIG_CMDQ cfg_cmdq_params ; unsigned int irq_st = 0; unsigned int i = 0; //unsigned int timeout = 0x1FFFFF; JPEG_DEC_DRV_OUT outParams; pStatus = (unsigned int*)file->private_data; if (NULL == pStatus) { JPEG_MSG("[JPEGDRV]JPEG Decoder: Private data is null in flush operation. SOME THING WRONG??\n"); return -EFAULT; } switch(cmd) { // initial and reset JPEG encoder case JPEG_DEC_IOCTL_INIT: /* OT:OK */ JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Init!!\n"); if(jpeg_drv_dec_init() == 0) { *pStatus = JPEG_DEC_PROCESS; } break; case JPEG_DEC_IOCTL_RESET: /* OT:OK */ JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Reset!!\n"); jpeg_drv_dec_reset(); break; case JPEG_DEC_IOCTL_CONFIG: JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Configration!!\n"); if(*pStatus != JPEG_DEC_PROCESS) { JPEG_MSG("[JPEGDRV]Permission Denied! This process can not access decoder\n"); return -EFAULT; } if(dec_status == 0) { JPEG_MSG("[JPEGDRV]JPEG Decoder is unlocked!!"); *pStatus = 0; return -EFAULT; } if(copy_from_user(&dec_params, (void *)arg, sizeof(JPEG_DEC_DRV_IN))) { JPEG_MSG("[JPEGDRV]JPEG Decoder : Copy from user error\n"); return -EFAULT; } //_jpeg_dec_dump_reg_en = dec_params.regDecDumpEn; if(dec_params.decodeMode == JPEG_DEC_MODE_MCU_ROW) _jpeg_dec_mode = 1; else _jpeg_dec_mode = 0; if (jpeg_drv_dec_set_config_data(&dec_params) < 0) return -EFAULT; break; case JPEG_DEC_IOCTL_FLUSH_CMDQ : JPEG_MSG("[JPEGDRV]enter JPEG BUILD CMDQ !!\n"); if(*pStatus != JPEG_DEC_PROCESS) { JPEG_MSG("[JPEGDRV]Permission Denied! This process can not access decoder\n"); return -EFAULT; } if(dec_status == 0) { JPEG_MSG("[JPEGDRV]JPEG Decoder is unlocked!!"); *pStatus = 0; return -EFAULT; } if(copy_from_user(&cfg_cmdq_params, (void *)arg, sizeof(JPEG_DEC_CONFIG_CMDQ))) { JPEG_MSG("[JPEGDRV]JPEG Decoder : Copy from user error\n"); return -EFAULT; } JPEG_MSG("[JPEGDRV]JPEG CREATE CMDQ !!\n"); cmdqRecCreate(CMDQ_SCENARIO_JPEG_DEC, &jpegCMDQ_handle) ; cmdqRecWait(jpegCMDQ_handle, CMDQ_EVENT_JPEG_DEC_EOF) ; for( i = 0 ; i < cfg_cmdq_params.goNum ; i++ ){ JPEG_MSG("[JPEGDRV]JPEG gen CMDQ %x %x %x %x !!\n", cfg_cmdq_params.pauseMCUidx[i], cfg_cmdq_params.decRowBuf0[i], cfg_cmdq_params.decRowBuf1[i], cfg_cmdq_params.decRowBuf2[i]); cmdqRecWrite(jpegCMDQ_handle, 0x18004170 /*REG_ADDR_JPGDEC_PAUSE_MCU_NUM*/, cfg_cmdq_params.pauseMCUidx[i]-1 , 0xFFFFFFFF) ; cmdqRecWrite(jpegCMDQ_handle, 0x18004140 /*REG_ADDR_JPGDEC_DEST_ADDR0_Y */, cfg_cmdq_params.decRowBuf0[i] , 0xFFFFFFFF) ; cmdqRecWrite(jpegCMDQ_handle, 0x18004144 /*REG_ADDR_JPGDEC_DEST_ADDR0_U */, cfg_cmdq_params.decRowBuf1[i] , 0xFFFFFFFF) ; cmdqRecWrite(jpegCMDQ_handle, 0x18004148 /*REG_ADDR_JPGDEC_DEST_ADDR0_V */, cfg_cmdq_params.decRowBuf2[i] , 0xFFFFFFFF) ; JPEG_MSG("[JPEGDRV]JPEG gen CMDQ go!!\n"); //trigger cmdqRecWrite(jpegCMDQ_handle, 0x18004274 /*REG_ADDR_JPGDEC_INTERRUPT_STATUS*/ , BIT_INQST_MASK_PAUSE , 0xFFFFFFFF) ; JPEG_MSG("[JPEGDRV]JPEG gen CMDQ wait!!\n"); //wait frame done cmdqRecWait(jpegCMDQ_handle, CMDQ_EVENT_JPEG_DEC_EOF) ; //cmdqRecPoll(jpegCMDQ_handle, 0x18004274 /*REG_ADDR_JPGDEC_INTERRUPT_STATUS*/ , BIT_INQST_MASK_PAUSE , 0x0010) ; } JPEG_MSG("[JPEGDRV]JPEG flush CMDQ start!!\n"); cmdqRecFlush(jpegCMDQ_handle) ; JPEG_MSG("[JPEGDRV]JPEG flush CMDQ end!!\n"); cmdqRecDestroy(jpegCMDQ_handle) ; JPEG_MSG("[JPEGDRV]JPEG destroy CMDQ end!!\n"); break; case JPEG_DEC_IOCTL_RESUME: if(*pStatus != JPEG_DEC_PROCESS) { JPEG_MSG("[JPEGDRV]Permission Denied! This process can not access decoder\n"); return -EFAULT; } if(dec_status == 0) { JPEG_MSG("[JPEGDRV]JPEG Decoder is unlocked!!"); *pStatus = 0; return -EFAULT; } if(copy_from_user(&dec_row_params, (void *)arg, sizeof(JPEG_DEC_CONFIG_ROW))) { JPEG_MSG("[JPEGDRV]JPEG Decoder : Copy from user error\n"); return -EFAULT; } JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Resume, [%d] %x %x %x !!\n", dec_row_params.pauseMCU -1,dec_row_params.decRowBuf[0], dec_row_params.decRowBuf[1], dec_row_params.decRowBuf[2]); jpeg_drv_dec_set_dst_bank0( dec_row_params.decRowBuf[0], dec_row_params.decRowBuf[1], dec_row_params.decRowBuf[2]); jpeg_drv_dec_set_pause_mcu_idx(dec_row_params.pauseMCU -1) ; // lock CPU to ensure irq is enabled after trigger HW spin_lock(&jpeg_dec_lock); jpeg_drv_dec_resume(BIT_INQST_MASK_PAUSE); spin_unlock(&jpeg_dec_lock); break; case JPEG_DEC_IOCTL_START: /* OT:OK */ JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Start!!\n"); //Debug: printk("0xF0: 0x%08x\n", *(volatile unsigned int*)(JPEG_DEC_BASE + 0xF0)); jpeg_drv_dec_start(); break; case JPEG_DEC_IOCTL_WAIT: if(*pStatus != JPEG_DEC_PROCESS) { JPEG_WRN("Permission Denied! This process can not access decoder"); return -EFAULT; } if(dec_status == 0) { JPEG_WRN("Decoder status is available, HOW COULD THIS HAPPEN ??"); *pStatus = 0; return -EFAULT; } if(copy_from_user(&outParams, (void *)arg, sizeof(JPEG_DEC_DRV_OUT))) { JPEG_WRN("JPEG Decoder : Copy from user error\n"); return -EFAULT; } //set timeout timeout_jiff = outParams.timeout* HZ / 1000; //JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Wait Resume Time Jiffies : %ld\n", timeout_jiff); #ifdef FPGA_VERSION //#if 1 JPEG_MSG("[JPEGDRV]Polling JPEG Status"); do { _jpeg_dec_int_status = REG_JPGDEC_INTERRUPT_STATUS; } while(_jpeg_dec_int_status == 0); #else //if(outParams.timeout >= 5000){ // // JPEG_MSG("Polling JPEG Status"); // do // { // _jpeg_dec_int_status = REG_JPGDEC_INTERRUPT_STATUS; // timeout--; // } while(_jpeg_dec_int_status == 0 && timeout != 0); // if(timeout == 0) JPEG_MSG("Polling JPEG Status TIMEOUT!!\n"); //}else if(jpeg_isr_dec_lisr()<0){ //JPEG_MSG("wait JPEG irq\n"); wait_event_interruptible_timeout(dec_wait_queue, _jpeg_dec_int_status, timeout_jiff); JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Enter IRQ Wait Done!!\n"); //printk("[JPEGDRV]wait JPEG irq done\n"); }else{ JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Enter IRQ Wait Already Done!!\n"); //printk("[JPEGDRV]JPEG decoder already done\n"); } #endif decResult = jpeg_drv_dec_get_result(); //jpeg_drv_dec_dump_key_reg(); if(decResult >= 2) { JPEG_MSG("[JPEGDRV]Decode Result : %d, status %x!\n", decResult, _jpeg_dec_int_status ); jpeg_drv_dec_dump_key_reg(); //jpeg_drv_dec_dump_reg(); jpeg_drv_dec_reset(); } irq_st = _jpeg_dec_int_status ; decResult = decResult | (irq_st<<8) ; _jpeg_dec_int_status = 0; if(copy_to_user(outParams.result, &decResult, sizeof(unsigned int))) { JPEG_WRN("JPEG Decoder : Copy to user error (result)\n"); return -EFAULT; } break; case JPEG_DEC_IOCTL_BREAK: if (jpeg_drv_dec_break() < 0) return -EFAULT; break; case JPEG_DEC_IOCTL_DUMP_REG: JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder DUMP REGISTER !!\n"); jpeg_drv_dec_dump_reg(); break; case JPEG_DEC_IOCTL_DEINIT: JPEG_MSG("[JPEGDRV][IOCTL] JPEG Decoder Deinit !!\n"); // copy input parameters if(*pStatus != JPEG_DEC_PROCESS) { JPEG_ERR("Permission Denied! This process can not access encoder"); return -EFAULT; } if(dec_status == 0) { JPEG_ERR("Encoder status is available, HOW COULD THIS HAPPEN ??"); *pStatus = 0; return -EFAULT; } jpeg_drv_dec_deinit(); *pStatus = 0; break; #ifdef FOR_COMPILE case JPEG_DEC_IOCTL_RW_REG: /* OT:OK */ jpeg_drv_dec_rw_reg(); break; #endif default: JPEG_ERR("JPEG DEC IOCTL NO THIS COMMAND\n"); break; } return 0; }