static char* ddp_signal_0(int bit) { switch(bit) { case 31: return "dpi0_sel_mm_dpi0 "; case 30: return "dis0_sel_mm_dsi0 "; case 29: return "rdma1_sout1_mm_dpi0_sin2 "; case 28: return "rdma1_sout0_mm_dsi0_sin2 "; case 27: return "rdma1_mm_rdma1_sout "; case 26: return "ovl1_mout2_mm_ovl0 "; case 25: return "ovl1_mout1_mm_wdma1 "; case 24: return "ovl1_mout0_mm_rdma1 "; case 23: return "ovl1_mm_ovl1_mout "; case 22: return "wdma0_sel_mm_wdma0 "; case 21: return "ufoe_mout2_mm_wdma0_sin2 "; case 20: return "ufoe_mout1_mm_dpi0_sin0 "; case 19: return "ufoe_mout0_mm_dsi0_sin0 "; case 18: return "ufoe_mm_ufoe_mout "; case 17: return "ufoe_sel_mm_ufoe "; case 16: return "rdma0_sout3_mm_dpi0_sin1 "; case 15: return "rdma0_sout2_mm_dsi0_sin1 "; case 14: return "rdma0_sout1_mm_color_sin0 "; case 13: return "rdma0_sout0_mm_ufoe_sin0 "; case 12: return "rdma0_mm_rdma0_sout "; case 11: return "dither_mout2_mm_wdma0_sin1"; case 10: return "dither_mout1_mm_ufoe_sin1 "; case 9: return "dither_mout0_mm_rdma0 "; case 8: return "dither_mm_dither_mout "; case 7: return "gamma_mm_dither "; case 6: return "aal_mm_gamma "; case 5: return "ccorr_mm_aal "; case 4: return "color_mm_ccorr "; case 3: return "color_sel_mm_color "; case 2: return "ovl0_mout1_mm_wdma0_sin0 "; case 1: return "ovl0_mout0_mm_color_sin1 "; case 0: return "ovl0_mm_ovl0_mout "; default: DDPERR("ddp_signal_0, unknown bit=%d \n", bit); return "unknown"; } }
unsigned int ddp_module_to_idx(int module) { unsigned int id=0; switch(module) { case DISP_MODULE_UFOE: case DISP_MODULE_AAL: case DISP_MODULE_COLOR0: case DISP_MODULE_RDMA0: case DISP_MODULE_WDMA0: case DISP_MODULE_OVL0: case DISP_MODULE_GAMMA: case DISP_MODULE_PWM0: case DISP_MODULE_OD: case DISP_MODULE_SPLIT0: case DISP_MODULE_DSI0: case DISP_MODULE_DPI: case DISP_MODULE_DITHER: case DISP_MODULE_CCORR: id = 0; break; case DISP_MODULE_COLOR1: case DISP_MODULE_RDMA1: case DISP_MODULE_WDMA1: case DISP_MODULE_OVL1: case DISP_MODULE_PWM1: case DISP_MODULE_SPLIT1: case DISP_MODULE_DSI1: id = 1; break; case DISP_MODULE_RDMA2: case DISP_MODULE_DSIDUAL: id = 2; break; default: DDPERR("ddp_module_to_idx, module=0x%x \n", module); } return id; }
static int wdma_reset(DISP_MODULE_ENUM module,void * handle) { unsigned int delay_cnt = 0; unsigned int idx = wdma_index(module); DISP_REG_SET(handle,idx*DISP_WDMA_INDEX_OFFSET+DISP_REG_WDMA_RST, 0x01); // trigger soft reset if (!handle) { while ((DISP_REG_GET(idx*DISP_WDMA_INDEX_OFFSET+DISP_REG_WDMA_FLOW_CTRL_DBG)&0x1)==0) { delay_cnt++; udelay(10); if (delay_cnt>2000) { DDPERR("wdma%d reset timeout!\n", idx); break; } } }else{ //add comdq polling } DISP_REG_SET(handle,idx*DISP_WDMA_INDEX_OFFSET+DISP_REG_WDMA_RST , 0x0); // trigger soft reset return 0; }
static unsigned int is_reg_addr_valid(unsigned int isVa, unsigned long addr) { unsigned int i = 0; for (i = 0; i < DISP_REG_NUM; i++) { if ((isVa == 1) && (addr >= dispsys_reg[i]) && (addr <= dispsys_reg[i] + 0x1000)) break; if ((isVa == 0) && (addr >= ddp_reg_pa_base[i]) && (addr <= ddp_reg_pa_base[i] + 0x1000)) break; } if (i < DISP_REG_NUM) { DDPMSG("addr valid, isVa=0x%x, addr=0x%lx, module=%s!\n", isVa, addr, ddp_get_reg_module_name(i)); return 1; } else { DDPERR("is_reg_addr_valid return fail, isVa=0x%x, addr=0x%lx!\n", isVa, addr); return 0; } }
static DpColorFormat ovl_input_fmt(enum OVL_INPUT_FORMAT fmt, int swap) { switch (fmt) { case OVL_INPUT_FORMAT_BGR565: return swap ? eBGR565 : eRGB565; case OVL_INPUT_FORMAT_RGB888: return swap ? eRGB888 : eBGR888; case OVL_INPUT_FORMAT_RGBA8888: return swap ? eRGBA8888 : eBGRA8888; case OVL_INPUT_FORMAT_ARGB8888: return swap ? eARGB8888 : eABGR8888; case OVL_INPUT_FORMAT_VYUY: return swap ? eVYUY : eUYVY; case OVL_INPUT_FORMAT_YVYU: return swap ? eYVYU : eYUY2; default: DDPERR("ovl_input_fmt fmt=%d, swap=%d\n", fmt, swap); break; } return eRGB888; }
// id: mutex ID, 0~5 static int ddp_mutex_set_l(int mutex_id, int* module_list, DDP_MODE ddp_mode, void * handle) { int i=0; kal_uint32 value = 0; int module_num = ddp_get_module_num_l(module_list); MUTEX_SOF mode = ddp_get_mutex_sof(module_list[module_num-1],ddp_mode); if(mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) { DDPERR("exceed mutex max (0 ~ %d)\n",DISP_MUTEX_DDP_LAST); return -1; } for(i = 0 ; i < module_num ; i++) { if(module_mutex_map[module_list[i]].bit != -1) DDPDBG("module %s added to mutex %d\n",ddp_get_module_name(module_list[i]),mutex_id); value |= (1 << module_mutex_map[module_list[i]].bit); } DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),value); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(mutex_id),mode); DDPDBG("mutex %d value=0x%x, sof=%s\n",mutex_id, value, ddp_get_mutex_sof_name(mode)); return 0; }
int disp_register_irq_callback(DDP_IRQ_CALLBACK cb) { int i = 0; for (i = 0; i < DISP_MAX_IRQ_CALLBACK; i++) { if (irq_callback_table[i] == cb) break; } if (i < DISP_MAX_IRQ_CALLBACK) return 0; for (i = 0; i < DISP_MAX_IRQ_CALLBACK; i++) { if (irq_callback_table[i] == NULL) break; } if (i == DISP_MAX_IRQ_CALLBACK) { DDPERR("not enough irq callback entries for module\n"); return -1; } DDPMSG("register callback on %d\n", i); irq_callback_table[i] = cb; return 0; }
static enum mc_result late_open_mobicore_device(void) { enum mc_result mcRet = MC_DRV_OK; if (0 == opened_device) { DDPDBG("=============== open mobicore device ===============\n"); /* Open MobiCore device */ mcRet = mc_open_device(mc_deviceId); if (MC_DRV_ERR_INVALID_OPERATION == mcRet) { // skip false alarm when the mc_open_device(mc_deviceId) is called more than once DDPDBG("mc_open_device already done\n"); } else if (MC_DRV_OK != mcRet) { DDPERR("mc_open_device failed: %d @%s line %d\n", mcRet, __func__, __LINE__); return mcRet; } opened_device = 1; } return MC_DRV_OK; }
int ovl_clock_off(DISP_MODULE_ENUM module, void *handle) { int idx = ovl_index(module); DDPMSG("ovl%d_clock_off\n", idx); #ifdef ENABLE_CLK_MGR if (ovl_clock_cnt[idx] == 0) { DDPERR("ovl_deinit, clock off OVL%d, but it's already off!\n", idx); return 0; } if (idx == 0) { #ifdef CONFIG_MTK_CLKMGR disable_clock(MT_CG_DISP0_DISP_OVL0, "OVL0"); #else disp_clk_disable(DISP0_DISP_OVL0); #endif } ovl_clock_cnt[idx]--; #endif return 0; }
int ovl_reset(DISP_MODULE_ENUM module, void *handle) { #define OVL_IDLE (0x3) int ret = 0; unsigned int delay_cnt = 0; int idx = ovl_index(module); int idx_offset = idx*DISP_OVL_INDEX_OFFSET; DISP_CPU_REG_SET(idx_offset+DISP_REG_OVL_RST, 0x1); DISP_CPU_REG_SET(idx_offset+DISP_REG_OVL_RST, 0x0); /*only wait if not cmdq*/ if (handle == NULL) { while (!(DISP_REG_GET(idx_offset+DISP_REG_OVL_FLOW_CTRL_DBG) & OVL_IDLE)) { delay_cnt++; udelay(10); if (delay_cnt > 2000) { DDPERR("ovl%d_reset timeout!\n", idx); ret = -1; break; } } } return ret; }
static MUTEX_SOF ddp_get_mutex_sof(DISP_MODULE_ENUM dest_module, DDP_MODE ddp_mode) { MUTEX_SOF mode = SOF_SINGLE; switch(dest_module) { case DISP_MODULE_DSI0: { mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI0 : SOF_SINGLE); break; } case DISP_MODULE_DSI1: { mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI1 : SOF_SINGLE); break; } case DISP_MODULE_DSIDUAL: { mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI0 : SOF_SINGLE); break; } case DISP_MODULE_DPI: { mode = SOF_DSI1;//SOF_DPI0; has one DSI, so the DPI should use 1 for mutex_sof break; } case DISP_MODULE_WDMA0: case DISP_MODULE_WDMA1: mode = SOF_SINGLE; break; default: DDPERR("get mutex sof, invalid param dst module = %s(%d), dis mode %s\n", ddp_get_module_name(dest_module), dest_module,ddp_get_mode_name(ddp_mode)); } DDPDBG("mutex sof: %s dst module %s:%s\n", ddp_get_mutex_sof_name(mode), ddp_get_module_name(dest_module),ddp_get_mode_name(ddp_mode)); return mode; }
int disp_init_irq(void) { if(irq_init) return 0; irq_init = 1; DDPMSG("disp_init_irq\n"); #if 0 // irq mapped in DT probe() static char * device_name="mtk_disp"; // Register IRQ disp_register_dev_irq(DISP_OVL0_IRQ_BIT_ID ,"DISP_OVL0"); disp_register_dev_irq(DISP_OVL1_IRQ_BIT_ID ,"DISP_OVL1"); disp_register_dev_irq(DISP_RDMA0_IRQ_BIT_ID ,"DISP_RDMA0"); disp_register_dev_irq(DISP_RDMA1_IRQ_BIT_ID ,"DISP_RDMA1"); disp_register_dev_irq(DISP_RDMA2_IRQ_BIT_ID ,"DISP_RDMA2"); disp_register_dev_irq(DISP_WDMA0_IRQ_BIT_ID ,"DISP_WDMA0"); disp_register_dev_irq(DISP_WDMA1_IRQ_BIT_ID ,"DISP_WDMA1"); disp_register_dev_irq(DSI0_IRQ_BIT_ID ,"DISP_DSI0"); //disp_register_dev_irq(DISP_COLOR0_IRQ_BIT_ID ,device_name); //disp_register_dev_irq(DISP_COLOR1_IRQ_BIT_ID ,device_name); //disp_register_dev_irq(DISP_GAMMA_IRQ_BIT_ID ,device_name ); //disp_register_dev_irq(DISP_UFOE_IRQ_BIT_ID ,device_name); disp_register_dev_irq(MM_MUTEX_IRQ_BIT_ID ,"DISP_MUTEX"); disp_register_dev_irq(DISP_AAL_IRQ_BIT_ID ,"DISP_AAL"); #endif //create irq log thread init_waitqueue_head(&disp_irq_log_wq); disp_irq_log_task = kthread_create(disp_irq_log_kthread_func, NULL, "ddp_irq_log_kthread"); if (IS_ERR(disp_irq_log_task)) { DDPERR(" can not create disp_irq_log_task kthread\n"); } wake_up_process(disp_irq_log_task); return 0; }
int rdma_build_cmdq(DISP_MODULE_ENUM module,void *cmdq_trigger_handle, CMDQ_STATE state) { int ret = 0; unsigned int idx = rdma_index(module); if(cmdq_trigger_handle == NULL) { DDPERR("cmdq_trigger_handle is NULL\n"); return -1; } if(disp_helper_get_option(DISP_HELPER_OPTION_DYNAMIC_SWITCH_UNDERFLOW_EN)) { if(state == CMDQ_AFTER_STREAM_EOF) { DISP_REG_SET_FIELD(cmdq_trigger_handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 0); } else if(state == CMDQ_AFTER_STREAM_SOF) { DISP_REG_SET_FIELD(cmdq_trigger_handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); } } return 0; }
static void process_dbg_opt(const char *opt) { char *buf = dbg_buf + strlen(dbg_buf); if (0 == strncmp(opt, "regr:", 5)) { unsigned long addr; int ret; ret = sscanf(opt, "regr: 0x%lx\n", &addr); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } if (is_reg_addr_valid(1, addr) == 1) { unsigned int regVal = DISP_REG_GET(addr); DDPMSG(" regr : 0x%lx = 0x%08x\n ", addr, regVal); sprintf(buf, " regr : 0x%lx = 0x%08x\n ", addr, regVal); } else { sprintf(buf, " regr, invalid address 0x%lx\n ", addr); goto Error; } } else if (0 == strncmp(opt, "regw:", 5)) { unsigned long addr; unsigned int val; unsigned int ret; ret = sscanf(opt, "regw: 0x%lx,0x%08x\n", &addr, &val); if (ret != 2) { pr_err("error to parse cmd %s\n", opt); return; } if (is_reg_addr_valid(1, addr) == 1) { unsigned int regVal; DISP_CPU_REG_SET(addr, val); regVal = DISP_REG_GET(addr); DDPMSG(" regw : 0x%lx, 0x%08x = 0x%08x\n ", addr, val, regVal); sprintf(buf, " regw : 0x%lx, 0x%08x = 0x%08x\n ", addr, val, regVal); } else { sprintf(buf, " regw, invalid address 0x%lx\n ", addr); goto Error; } } else if (0 == strncmp(opt, "rdma_ultra:", 11)) { int ret; ret = sscanf(opt, "rdma_ultra: 0x%x\n", &gRDMAUltraSetting); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } DISP_CPU_REG_SET(DISP_REG_RDMA_MEM_GMC_SETTING_0, gRDMAUltraSetting); sprintf(buf, " rdma_ultra, gRDMAUltraSetting = 0x%x, reg = 0x%x\n ", gRDMAUltraSetting, DISP_REG_GET(DISP_REG_RDMA_MEM_GMC_SETTING_0)); } else if (0 == strncmp(opt, "rdma_fifo:", 10)) { int ret; ret = sscanf(opt, "rdma_fifo: 0x%x\n", &gRDMAFIFOLen); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } DISP_CPU_REG_SET_FIELD(FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, DISP_REG_RDMA_FIFO_CON, gRDMAFIFOLen); sprintf(buf, " rdma_fifo, gRDMAFIFOLen = 0x%x, reg = 0x%x\n ", gRDMAFIFOLen, DISP_REG_GET(DISP_REG_RDMA_FIFO_CON)); } else if (0 == strncmp(opt, "g_regr:", 7)) { unsigned int reg_va_before; unsigned long reg_va; unsigned long reg_pa; int ret; ret = sscanf(opt, "g_regr: 0x%lx\n", ®_pa); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } if (reg_pa < 0x10000000 || reg_pa > 0x18000000) { sprintf(buf, " g_regr, invalid pa = 0x%lx\n ", reg_pa); } else { reg_va = (unsigned long)ioremap_nocache(reg_pa, sizeof(unsigned long)); reg_va_before = DISP_REG_GET(reg_va); pr_debug(" g_regr, pa = 0x%lx, va = 0x%lx, reg_val = 0x%x\n ", reg_pa, reg_va, reg_va_before); sprintf(buf, " g_regr, pa = 0x%lx, va = 0x%lx, reg_val = 0x%x\n ", reg_pa, reg_va, reg_va_before); iounmap((void *)reg_va); } } else if (0 == strncmp(opt, "g_regw:", 7)) { unsigned int reg_va_before; unsigned int reg_va_after; unsigned int val; unsigned long reg_va; unsigned long reg_pa; int ret; ret = sscanf(opt, "g_regw: 0x%lx\n", ®_pa); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } if (reg_pa < 0x10000000 || reg_pa > 0x18000000) { sprintf(buf, " g_regw, invalid pa = 0x%lx\n ", reg_pa); } else { ret = sscanf(opt, "g_regw,val: 0x%x\n", &val); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } reg_va = (unsigned long)ioremap_nocache(reg_pa, sizeof(unsigned long)); reg_va_before = DISP_REG_GET(reg_va); DISP_CPU_REG_SET(reg_va, val); reg_va_after = DISP_REG_GET(reg_va); pr_debug ("g_regw, pa = 0x%lx, va = 0x%lx, value = 0x%x, reg_val_before = 0x%x, reg_val_after = 0x%x\n ", reg_pa, reg_va, val, reg_va_before, reg_va_after); sprintf(buf, " g_regw, pa = 0x%lx, va = 0x%lx, value = 0x%x, reg_val_before = 0x%x, reg_val_after = 0x%x\n ", reg_pa, reg_va, val, reg_va_before, reg_va_after); iounmap((void *)reg_va); } } else if (0 == strncmp(opt, "dbg_log:", 8)) { unsigned int enable; int ret; ret = sscanf(opt, "dbg_log: %d\n", &enable); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } if (enable) dbg_log_level = 1; else dbg_log_level = 0; sprintf(buf, " dbg_log : %d\n ", dbg_log_level); } else if (0 == strncmp(opt, "irq_log:", 8)) { unsigned int enable; int ret; ret = sscanf(opt, "irq_log: %d\n", &enable); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } if (enable) irq_log_level = 1; else irq_log_level = 0; sprintf(buf, " irq_log : %d\n ", irq_log_level); } else if (0 == strncmp(opt, "met_on:", 7)) { int met_on; int rdma0_mode; int rdma1_mode; int ret; ret = sscanf(opt, "met_on : %d,%d,%d\n", &met_on, &rdma0_mode, &rdma1_mode); if (ret != 3) { pr_err("error to parse cmd %s\n", opt); return; } ddp_init_met_tag(met_on, rdma0_mode, rdma1_mode); DDPMSG(" process_dbg_opt, met_on = %d, rdma0_mode %d, rdma1 %d\n ", met_on, rdma0_mode, rdma1_mode); sprintf(buf, " met_on : %d, rdma0_mode : %d, rdma1_mode : %d\n ", met_on, rdma0_mode, rdma1_mode); } else if (0 == strncmp(opt, "backlight:", 10)) { unsigned int level; int ret; ret = sscanf(opt, "backlight: %d\n", &level); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } if (level) { disp_bls_set_backlight(level); sprintf(buf, " backlight : %d\n ", level); } else { goto Error; } } else if (0 == strncmp(opt, "pwm0:", 5) || 0 == strncmp(opt, "pwm1:", 5)) { unsigned int level; int ret; ret = sscanf(opt, "pwm: %d\n", &level); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } if (level) { disp_pwm_id_t pwm_id = DISP_PWM0; if (opt[3] == '1') pwm_id = DISP_PWM1; disp_pwm_set_backlight(pwm_id, level); sprintf(buf, " PWM 0x%x : %d\n ", pwm_id, level); } else { goto Error; } } else if (0 == strncmp(opt, "aal_dbg:", 8)) { int ret; ret = sscanf(opt, "aal_dbg: %d\n", &aal_dbg_en); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } sprintf(buf, " aal_dbg_en = 0x%x\n ", aal_dbg_en); } else if (0 == strncmp(opt, "dump_reg:", 9)) { unsigned int module; int ret; ret = sscanf(opt, "dump_reg: %d\n", &module); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } DDPMSG(" process_dbg_opt, module = %d\n ", module); if (module < DISP_MODULE_NUM) { ddp_dump_reg(module); sprintf(buf, " dump_reg : %d\n ", module); } else { DDPMSG(" process_dbg_opt2, module = %d\n ", module); goto Error; } } else if (0 == strncmp(opt, "dump_path:", 10)) { unsigned int mutex_idx; int ret; ret = sscanf(opt, "dump_path: %d\n", &mutex_idx); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } DDPMSG(" process_dbg_opt, path mutex = %d\n ", mutex_idx); dpmgr_debug_path_status(mutex_idx); sprintf(buf, " dump_path : %d\n ", mutex_idx); } else if (0 == strncmp(opt, "debug:", 6)) { unsigned int enable; int ret; ret = sscanf(opt, "debug: %d\n", &enable); if (ret != 1) { pr_err("error to parse cmd %s\n", opt); return; } disp_debug_api(enable, buf); } else if (0 == strncmp(opt, "mmp", 3)) { init_ddp_mmp_events(); } else { dbg_buf[0] = '\0'; goto Error; } return; Error: DDPERR(" parse command error !\n%s\n\n%s", opt, STR_HELP); }
void ddp_mmp_wdma_layer(WDMA_CONFIG_STRUCT *wdma_layer,unsigned int wdma_num, unsigned int down_sample_x,unsigned int down_sample_y) { if(wdma_num > 1) { DDPERR("dprec_mmp_dump_wdma_layer is error %d\n",wdma_num); return; } MMP_MetaDataBitmap_t Bitmap; MMP_MetaData_t meta; int raw = 0; Bitmap.data1 = wdma_layer->dstAddress; Bitmap.width = wdma_layer->srcWidth; Bitmap.height = wdma_layer->srcHeight; switch (wdma_layer->outputFormat) { case eRGB565: case eBGR565: Bitmap.format = MMProfileBitmapRGB565; Bitmap.bpp = 16; break; case eRGB888: Bitmap.format = MMProfileBitmapRGB888; Bitmap.bpp = 24; break; case eBGRA8888: Bitmap.format = MMProfileBitmapBGRA8888; Bitmap.bpp = 32; break; case eBGR888: Bitmap.format = MMProfileBitmapBGR888; Bitmap.bpp = 24; break; case eRGBA8888: Bitmap.format = MMProfileBitmapRGBA8888; Bitmap.bpp = 32; break; default: DDPERR("dprec_mmp_dump_wdma_layer(), unknow fmt=%d, dump raw\n", wdma_layer->outputFormat); raw = 1; } if(!raw) { Bitmap.start_pos =0; Bitmap.pitch = wdma_layer->dstPitch; Bitmap.data_size = Bitmap.pitch * Bitmap.height; Bitmap.down_sample_x = down_sample_x; Bitmap.down_sample_y = down_sample_y; if (m4u_mva_map_kernel(wdma_layer->dstAddress, Bitmap.data_size,(unsigned long*)&Bitmap.pData, &Bitmap.data_size)==0) { MMProfileLogMetaBitmap(DDP_MMP_Events.wdma_dump[wdma_num], MMProfileFlagPulse, &Bitmap); m4u_mva_unmap_kernel(wdma_layer->dstAddress, Bitmap.data_size, (unsigned long)Bitmap.pData); } else { DDPERR("dprec_mmp_dump_wdma_layer(),fail to dump rgb(0x%x)\n", wdma_layer->outputFormat); } } else { meta.data_type = MMProfileMetaRaw; meta.size = wdma_layer->dstPitch * wdma_layer->srcHeight; if(m4u_mva_map_kernel(wdma_layer->dstAddress, meta.size, (unsigned long*)&meta.pData, &meta.size)==0) { MMProfileLogMeta(DDP_MMP_Events.wdma_dump[wdma_num], MMProfileFlagPulse, &meta); } else { DDPERR("dprec_mmp_dump_wdma_layer(),fail to dump raw(0x%x)\n", wdma_layer->outputFormat); } } return 0; }
int OVLLayerConfig(DISP_MODULE_ENUM module, unsigned int layer, unsigned int source, DpColorFormat format, unsigned int addr, unsigned int src_x, // ROI x offset unsigned int src_y, // ROI y offset unsigned int src_pitch, unsigned int dst_x, // ROI x offset unsigned int dst_y, // ROI y offset unsigned int dst_w, // ROT width unsigned int dst_h, // ROI height unsigned int keyEn, unsigned int key, // color key unsigned int aen, // alpha enable unsigned char alpha, void * handle) { int idx = ovl_index(module); unsigned int value = 0; enum OVL_INPUT_FORMAT fmt = ovl_input_fmt_convert(format); unsigned int bpp = ovl_input_fmt_bpp(fmt); unsigned int input_swap = ovl_input_fmt_byte_swap(fmt); unsigned int input_fmt = ovl_input_fmt_reg_value(fmt); enum OVL_COLOR_SPACE space = ovl_input_fmt_color_space(fmt); /*0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB)*/ int color_matrix = 0x4; unsigned int idx_offset = idx*DISP_INDEX_OFFSET; unsigned int layer_offset = idx_offset + layer * 0x20; ASSERT((dst_w <= OVL_MAX_WIDTH) && (dst_h <= OVL_MAX_HEIGHT) && (layer <= 3)); if (addr == 0) { DDPERR("source from memory, but addr is 0!\n"); ASSERT(0); } DDPDBG("ovl%d, layer=%d, source=%s, off(x=%d, y=%d), dst(%d, %d, %d, %d),pitch=%d," "fmt=%s, addr=%lx, keyEn=%d, key=%d, aen=%d, alpha=%d \n", idx, layer, (source==0)?"memory":"constant_color", src_x, src_y, dst_x, dst_y, dst_w, dst_h, src_pitch, ovl_intput_format_name(fmt, input_swap), addr, keyEn, key, aen, alpha); if(source==OVL_LAYER_SOURCE_RESERVED) //==1, means constant color { if(aen==0) { DDPERR("dim layer ahpha enable should be 1!\n"); } if(fmt!=OVL_INPUT_FORMAT_RGB565) { DDPERR("dim layer format should be RGB565"); fmt = OVL_INPUT_FORMAT_RGB565; } } DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_CTRL+layer_offset, 0x1); value = (REG_FLD_VAL((L_CON_FLD_LARC), (source)) | REG_FLD_VAL((L_CON_FLD_CFMT), (input_fmt)) | REG_FLD_VAL((L_CON_FLD_AEN), (aen)) | REG_FLD_VAL((L_CON_FLD_APHA), (alpha)) | REG_FLD_VAL((L_CON_FLD_SKEN), (keyEn)) | REG_FLD_VAL((L_CON_FLD_BTSW), (input_swap))); if (space == OVL_COLOR_SPACE_YUV) value = value | REG_FLD_VAL((L_CON_FLD_MTX), (color_matrix)); DISP_REG_SET(handle, DISP_REG_OVL_L0_CON+layer_offset, value); DISP_REG_SET(handle, DISP_REG_OVL_L0_SRC_SIZE+layer_offset, dst_h<<16 | dst_w); DISP_REG_SET(handle, DISP_REG_OVL_L0_OFFSET+layer_offset, dst_y<<16 | dst_x); DISP_REG_SET(handle, DISP_REG_OVL_L0_ADDR+layer_offset, addr+src_x*bpp+src_y*src_pitch); DISP_REG_SET(handle, DISP_REG_OVL_L0_SRCKEY+layer_offset, key); value = (REG_FLD_VAL((L_PITCH_FLD_SUR_ALFA), (value)) | REG_FLD_VAL((L_PITCH_FLD_LSP), (src_pitch))); DISP_REG_SET(handle, DISP_REG_OVL_L0_PITCH+layer_offset, value); DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x6070); }
static int ovl_layer_config(DISP_MODULE_ENUM module, unsigned int layer, unsigned int source, DpColorFormat format, unsigned long addr, unsigned int src_x, /* ROI x offset*/ unsigned int src_y, /* ROI y offset*/ unsigned int src_pitch, unsigned int dst_x, /* ROI x offset*/ unsigned int dst_y, /* ROI y offset*/ unsigned int dst_w, /* ROT width*/ unsigned int dst_h, /* ROI height*/ unsigned int key_en, unsigned int key, /*color key*/ unsigned int aen, /* alpha enable*/ unsigned char alpha, unsigned int sur_aen, unsigned int src_alpha, unsigned int dst_alpha, unsigned int constant_color, unsigned int yuv_range, DISP_BUFFER_TYPE sec, unsigned int is_engine_sec, void *handle) { int idx = ovl_index(module); unsigned int value = 0; enum OVL_INPUT_FORMAT fmt = ovl_input_fmt_convert(format); unsigned int bpp = ovl_input_fmt_bpp(fmt); unsigned int input_swap = ovl_input_fmt_byte_swap(fmt); unsigned int input_fmt = ovl_input_fmt_reg_value(fmt); enum OVL_COLOR_SPACE space = ovl_input_fmt_color_space(fmt); unsigned int offset = 0; /*0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB)*/ int color_matrix = 0x4; unsigned int idx_offset = idx*DISP_OVL_INDEX_OFFSET; unsigned int layer_offset = idx_offset + layer * OVL_LAYER_OFFSET; #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW unsigned int bg_h, bg_w; #endif switch(yuv_range) { case 0: color_matrix = 4; break; //BT601_full case 1: color_matrix = 6; break; //BT601 case 2: color_matrix = 7; break; //BT709 default: DDPERR("un-recognized yuv_range=%d! \n", yuv_range); color_matrix = 4; } // DDPMSG("color matrix=%d. \n", color_matrix); ASSERT((dst_w <= OVL_MAX_WIDTH) && (dst_h <= OVL_MAX_HEIGHT) && (layer <= 3)); if (addr == 0) { DDPERR("source from memory, but addr is 0!\n"); ASSERT(0); } #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) && defined(CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT) DDPMSG("ovl%d, layer=%d, source=%s, off(x=%d, y=%d), dst(%d, %d, %d, %d),pitch=%d," "fmt=%s, addr=%lx, keyEn=%d, key=%d, aen=%d, alpha=%d," "sur_aen=%d,sur_alpha=0x%x, constant_color=0x%x, yuv_range=%d, sec=%d,ovlsec=%d\n", idx, layer, (source==0)?"memory":"dim", src_x, src_y,dst_x, dst_y, dst_w, dst_h, src_pitch, ovl_intput_format_name(fmt, input_swap), addr, key_en, key, aen, alpha, sur_aen, dst_alpha<<2 | src_alpha, constant_color, yuv_range, sec, is_engine_sec); #endif if(source==OVL_LAYER_SOURCE_RESERVED) //==1, means constant color { if(aen==0) { DDPERR("dim layer ahpha enable should be 1!\n"); } if(fmt!=OVL_INPUT_FORMAT_RGB565 && fmt!=OVL_INPUT_FORMAT_RGB888) { //DDPERR("dim layer format should be RGB565"); fmt = OVL_INPUT_FORMAT_RGB888; input_fmt = ovl_input_fmt_reg_value(fmt); } } // DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_RDMA0_CTRL+layer_offset, 0x1); value = (REG_FLD_VAL((L_CON_FLD_LARC), (source)) | REG_FLD_VAL((L_CON_FLD_CFMT), (input_fmt)) | REG_FLD_VAL((L_CON_FLD_AEN), (aen)) | REG_FLD_VAL((L_CON_FLD_APHA), (alpha)) | REG_FLD_VAL((L_CON_FLD_SKEN), (key_en)) | REG_FLD_VAL((L_CON_FLD_BTSW), (input_swap))); if (space == OVL_COLOR_SPACE_YUV) value = value | REG_FLD_VAL((L_CON_FLD_MTX), (color_matrix)); #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW value |= 0x600; #endif DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_CON+layer_offset, value); DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_CLR+idx_offset+layer*4, constant_color); DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_SRC_SIZE+layer_offset, dst_h<<16 | dst_w); #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW bg_h = DISP_REG_GET(idx_offset + DISP_REG_OVL_ROI_SIZE); bg_w = bg_h & 0xFFFF; bg_h = bg_h >> 16; DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_OFFSET+layer_offset, ((bg_h-dst_h-dst_y)<<16)|(bg_w-dst_w-dst_x)); #else DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_OFFSET+layer_offset, dst_y<<16 | dst_x); #endif #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION_HW offset = src_pitch*(dst_h+src_y-1)+(src_x+dst_w)*bpp-1; #else offset = src_x*bpp+src_y*src_pitch; #endif if(!is_engine_sec) { DISP_REG_SET(handle, DISP_REG_OVL_L0_ADDR+layer_offset, addr+offset); } else { unsigned int size; int m4u_port; size = (dst_h-1)*src_pitch + dst_w*bpp; #if defined(MTK_FB_OVL1_SUPPORT) m4u_port = idx==0 ? M4U_PORT_DISP_OVL0 : M4U_PORT_DISP_OVL1; #else m4u_port = M4U_PORT_DISP_OVL0; #endif if(sec != DISP_SECURE_BUFFER) { /* ovl is sec but this layer is non-sec */ /* we need to tell cmdq to help map non-sec mva to sec mva */ cmdqRecWriteSecure(handle, disp_addr_convert(DISP_REG_OVL_L0_ADDR+layer_offset), CMDQ_SAM_NMVA_2_MVA, addr+offset, 0, size, m4u_port); } else { /* for sec layer, addr variable stores sec handle*/ /* we need to pass this handle and offset to cmdq driver */ /* cmdq sec driver will help to convert handle to correct address */ offset = src_x*bpp+src_y*src_pitch; cmdqRecWriteSecure(handle, disp_addr_convert(DISP_REG_OVL_L0_ADDR+layer_offset), CMDQ_SAM_H_2_MVA, addr, offset, size, m4u_port); } } if(key_en==1) { DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_SRCKEY+layer_offset, key); } value = (((sur_aen & 0x1) << 15) | ((dst_alpha & 0x3) << 6) | ((dst_alpha & 0x3) << 4) | ((src_alpha & 0x3)<<2) | (src_alpha & 0x3)); value = (REG_FLD_VAL((L_PITCH_FLD_SUR_ALFA), (value)) | REG_FLD_VAL((L_PITCH_FLD_LSP), (src_pitch))); DISP_REG_SET_DIRTY(handle, DISP_REG_OVL_L0_PITCH+layer_offset, value); if(idx==0) { if(primary_display_is_decouple_mode()==0) { if(DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset)!=0x6070) DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x6070); } else { if(DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset)!=0x50FF) DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x50FF); } } if(idx==1) { if(primary_display_is_decouple_mode()==0 && ovl_get_status()!=DDP_OVL1_STATUS_SUB) { if(DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset)!=0x6070) DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x6070); } else { if(DISP_REG_GET(DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset)!=0x50FF) DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x50FF); } } return 0; }
void ddp_mmp_ovl_layer(OVL_CONFIG_STRUCT* pLayer,unsigned int down_sample_x,unsigned int down_sample_y,unsigned int session/*1:primary, 2:external, 3:memory*/) { MMP_MetaDataBitmap_t Bitmap; MMP_MetaData_t meta; int raw = 0; if(session == 1) MMProfileLogEx(DDP_MMP_Events.layer_dump_parent,MMProfileFlagStart, pLayer->layer, pLayer->layer_en); else if(session == 2) MMProfileLogEx(DDP_MMP_Events.Extd_layer_dump_parent,MMProfileFlagStart, pLayer->layer, pLayer->layer_en); if (pLayer->layer_en) { Bitmap.data1 = pLayer->vaddr; Bitmap.width = pLayer->dst_w; Bitmap.height = pLayer->dst_h; switch (pLayer->fmt) { case eRGB565: case eBGR565: Bitmap.format = MMProfileBitmapRGB565; Bitmap.bpp = 16; break; case eRGB888: Bitmap.format = MMProfileBitmapRGB888; Bitmap.bpp = 24; break; case eBGRA8888: Bitmap.format = MMProfileBitmapBGRA8888; Bitmap.bpp = 32; break; case eBGR888: Bitmap.format = MMProfileBitmapBGR888; Bitmap.bpp = 24; break; case eRGBA8888: Bitmap.format = MMProfileBitmapRGBA8888; Bitmap.bpp = 32; break; default: DDPERR("ddp_mmp_ovl_layer(), unknow fmt=%d, dump raw\n", pLayer->fmt); raw = 1; } if(!raw) { Bitmap.start_pos =0; Bitmap.pitch = pLayer->src_pitch; Bitmap.data_size = Bitmap.pitch * Bitmap.height; Bitmap.down_sample_x = down_sample_x; Bitmap.down_sample_y = down_sample_y; if (m4u_mva_map_kernel(pLayer->addr, Bitmap.data_size,(unsigned long*)&Bitmap.pData, &Bitmap.data_size)==0) { if(session == 1) MMProfileLogMetaBitmap(DDP_MMP_Events.layer_dump[pLayer->layer], MMProfileFlagPulse, &Bitmap); else if(session == 2) MMProfileLogMetaBitmap(DDP_MMP_Events.ovl1layer_dump[pLayer->layer], MMProfileFlagPulse, &Bitmap); m4u_mva_unmap_kernel(pLayer->addr, Bitmap.data_size, (unsigned long)Bitmap.pData); } else { DDPERR("ddp_mmp_ovl_layer(),fail to dump rgb(0x%x)\n", pLayer->fmt); } } else { meta.data_type = MMProfileMetaRaw; meta.size = pLayer->src_pitch * pLayer->src_h; if(m4u_mva_map_kernel(pLayer->addr, meta.size, (unsigned long*)&meta.pData, &meta.size)==0) { if(session == 1) MMProfileLogMeta(DDP_MMP_Events.layer_dump[pLayer->layer], MMProfileFlagPulse, &meta); else if(session == 2) MMProfileLogMeta(DDP_MMP_Events.ovl1layer_dump[pLayer->layer], MMProfileFlagPulse, &meta); m4u_mva_unmap_kernel(pLayer->addr, meta.size, (unsigned long)meta.pData); } else { DDPERR("ddp_mmp_ovl_layer(),fail to dump raw(0x%x)\n", pLayer->fmt); } } } if(session == 1) MMProfileLogEx(DDP_MMP_Events.layer_dump_parent,MMProfileFlagEnd, pLayer->fmt, pLayer->addr); else if(session == 2) MMProfileLogEx(DDP_MMP_Events.Extd_layer_dump_parent,MMProfileFlagEnd, pLayer->fmt, pLayer->addr); return ; }
static void process_dbg_opt(const char *opt) { char *buf = dbg_buf + strlen(dbg_buf); static disp_session_config config; if (0 == strncmp(opt, "regr:", 5)) { char *p = (char *)opt + 5; unsigned long addr = (unsigned long) simple_strtoul(p, &p, 16); if(is_reg_addr_valid(1, addr)==1)// (addr >= 0xf0000000U && addr <= 0xff000000U) { unsigned int regVal = DISP_REG_GET(addr); DDPMSG("regr: 0x%lx = 0x%08X\n", addr, regVal); sprintf(buf, "regr: 0x%lx = 0x%08X\n", addr, regVal); } else { sprintf(buf, "regr, invalid address 0x%lx\n", addr); goto Error; } } else if (0 == strncmp(opt, "regw:", 5)) { char *p = (char *)opt + 5; unsigned long addr = (unsigned long) simple_strtoul(p, &p, 16); unsigned int val = (unsigned int) simple_strtoul(p + 1, &p, 16); if(is_reg_addr_valid(1, addr)==1)// (addr >= 0xf0000000U && addr <= 0xff000000U) { unsigned int regVal; DISP_CPU_REG_SET(addr, val); regVal = DISP_REG_GET(addr); DDPMSG("regw: 0x%lx, 0x%08X = 0x%08X\n", addr, val, regVal); sprintf(buf, "regw: 0x%lx, 0x%08X = 0x%08X\n", addr, val, regVal); } else { sprintf(buf, "regw, invalid address 0x%lx \n", addr); goto Error; } } else if (0 == strncmp(opt, "dbg_log:", 8)) { char *p = (char *)opt + 8; unsigned int enable = (unsigned int) simple_strtoul(p, &p, 10); if (enable) dbg_log_level = 1; else dbg_log_level = 0; sprintf(buf, "dbg_log: %d\n", dbg_log_level); } else if (0 == strncmp(opt, "irq_log:", 8)) { char *p = (char *)opt + 8; unsigned int enable = (unsigned int) simple_strtoul(p, &p, 10); if (enable) irq_log_level = 1; else irq_log_level = 0; sprintf(buf, "irq_log: %d\n", irq_log_level); } else if (0 == strncmp(opt, "met_on:", 7)) { char *p = (char *)opt + 7; int met_on = (int) simple_strtoul(p, &p, 10); int rdma0_mode = (int) simple_strtoul(p + 1, &p, 10); int rdma1_mode = (int) simple_strtoul(p + 1, &p, 10); // ddp_init_met_tag(met_on,rdma0_mode,rdma1_mode); DDPMSG("process_dbg_opt, met_on=%d,rdma0_mode %d, rdma1 %d \n", met_on,rdma0_mode,rdma1_mode); sprintf(buf, "met_on:%d,rdma0_mode:%d,rdma1_mode:%d\n", met_on,rdma0_mode,rdma1_mode); } else if (0 == strncmp(opt, "backlight:", 10)) { char *p = (char *)opt + 10; unsigned int level = (unsigned int) simple_strtoul(p, &p, 10); if (level) { disp_bls_set_backlight(level); sprintf(buf, "backlight: %d\n", level); } else { goto Error; } } else if (0 == strncmp(opt, "pwm0:", 5) || 0 == strncmp(opt, "pwm1:", 5)) { char *p = (char *)opt + 5; unsigned int level = (unsigned int)simple_strtoul(p, &p, 10); if (level) { disp_pwm_id_t pwm_id = DISP_PWM0; if (opt[3] == '1') pwm_id = DISP_PWM1; disp_pwm_set_backlight(pwm_id, level); sprintf(buf, "PWM 0x%x : %d\n", pwm_id, level); } else { goto Error; } } else if (0 == strncmp(opt, "aal_dbg:", 8)) { aal_dbg_en = (int)simple_strtoul(opt + 8, NULL, 10); sprintf(buf, "aal_dbg_en = 0x%x\n", aal_dbg_en); } else if (0 == strncmp(opt, "dump_reg:", 9)) { char *p = (char *)opt + 9; unsigned int module = (unsigned int) simple_strtoul(p, &p, 10); DDPMSG("process_dbg_opt, module=%d \n", module); if (module<DISP_MODULE_NUM) { ddp_dump_reg(module); sprintf(buf, "dump_reg: %d\n", module); } else { DDPMSG("process_dbg_opt2, module=%d \n", module); goto Error; } } else if (0 == strncmp(opt, "dump_path:", 10)) { char *p = (char *)opt + 10; unsigned int mutex_idx = (unsigned int) simple_strtoul(p, &p, 10); DDPMSG("process_dbg_opt, path mutex=%d \n", mutex_idx); dpmgr_debug_path_status(mutex_idx); sprintf(buf, "dump_path: %d\n", mutex_idx); } else if (0 == strncmp(opt, "debug:", 6)) { char *p = (char *)opt + 6; unsigned int enable = (unsigned int) simple_strtoul(p, &p, 10); if(enable==1) { DDPMSG("[DDP] debug=1, trigger AEE\n"); //aee_kernel_exception("DDP-TEST-ASSERT", "[DDP] DDP-TEST-ASSERT"); } else if(enable==2) { ddp_mem_test(); } else if(enable==3) { ddp_lcd_test(); } else if(enable==4) { //DDPAEE("test 4"); } else if(enable==5) { extern unsigned int gDDPError; if(gDDPError==0) gDDPError = 1; else gDDPError = 0; sprintf(buf, "bypass PQ: %d\n", gDDPError); DDPMSG("bypass PQ: %d\n", gDDPError); } else if(enable==6) { unsigned int i = 0; int * modules = ddp_get_scenario_list(DDP_SCENARIO_PRIMARY_DISP); int module_num = ddp_get_module_num(DDP_SCENARIO_PRIMARY_DISP); printk("dump path status:"); for(i=0;i<module_num;i++) { printk("%s-", ddp_get_module_name(modules[i])); } printk("\n"); ddp_dump_analysis(DISP_MODULE_CONFIG); ddp_dump_analysis(DISP_MODULE_MUTEX); for( i=0; i< module_num;i++) { ddp_dump_analysis(modules[i]); } ddp_dump_reg(DISP_MODULE_CONFIG); ddp_dump_reg(DISP_MODULE_MUTEX); for( i=0; i< module_num;i++) { ddp_dump_reg(modules[i]); } } else if(enable==7) { if(dbg_log_level<3) dbg_log_level++; else dbg_log_level=0; printk("DDP: dbg_log_level=%d\n", dbg_log_level); sprintf(buf, "dbg_log_level: %d\n", dbg_log_level); } #if 0 else if(enable==8) { DDPDUMP("clock_mm setting:%u \n", DISP_REG_GET(DISP_REG_CONFIG_C11)); if(DISP_REG_GET(DISP_REG_CONFIG_C11)&0xff000000!=0xff000000) { DDPDUMP("error, MM clock bit 24~bit31 should be 1, but real value=0x%x", DISP_REG_GET(DISP_REG_CONFIG_C11)); } } #endif else if(enable==9) { gOVLBackground = 0xFF0000FF; printk("DDP: gOVLBackground=%d\n", gOVLBackground); sprintf(buf, "gOVLBackground: %d\n", gOVLBackground); } else if(enable==10) { gOVLBackground = 0xFF000000; printk("DDP: gOVLBackground=%d\n", gOVLBackground); sprintf(buf, "gOVLBackground: %d\n", gOVLBackground); } else if(enable==11) { unsigned int i=0; for(i=0;i<DISP_REG_NUM;i++) { DDPDUMP("i=%d, module=%s, reg_va=0x%lx\n", i, ddp_get_reg_module_name(i), dispsys_reg[i]); } } else if(enable==12) { if(gUltraEnable==0) gUltraEnable = 1; else gUltraEnable = 0; printk("DDP: gUltraEnable=%d\n", gUltraEnable); sprintf(buf, "gUltraEnable: %d\n", gUltraEnable); } } else if (0 == strncmp(opt, "mmp", 3)) { init_ddp_mmp_events(); } else { dbg_buf[0]='\0'; goto Error; } return; Error: DDPERR("parse command error!\n%s\n\n%s", opt, STR_HELP); }
///TODO: move each irq to module driver irqreturn_t disp_irq_handler(int irq, void *dev_id) { DISP_MODULE_ENUM module = DISP_MODULE_UNKNOWN; unsigned int reg_val = 0; unsigned int index = 0; unsigned int mutexID = 0; //MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagStart, irq, 0); if(irq==dispsys_irq[DISP_REG_DSI0] || irq==dispsys_irq[DISP_REG_DSI1]) { index = (irq == dispsys_irq[DISP_REG_DSI0]) ? 0 : 1; module = (irq == dispsys_irq[DISP_REG_DSI0]) ? DISP_MODULE_DSI0 : DISP_MODULE_DSI1; reg_val = DISP_REG_GET(DDP_REG_BASE_DSI0+0xC + index * DISP_DSI_INDEX_OFFSET) & 0xff; DISP_CPU_REG_SET(DDP_REG_BASE_DSI0+0xC + index * DISP_DSI_INDEX_OFFSET, ~reg_val); DDPIRQ("IRQ: DSI%d 0x%x!\n", index, reg_val); //MMProfileLogEx(ddp_mmp_get_events()->DSI_IRQ[index], MMProfileFlagPulse, reg_val, 0); } else if(irq==dispsys_irq[DISP_REG_OVL0] || irq==dispsys_irq[DISP_REG_OVL1]) { index = (irq == dispsys_irq[DISP_REG_OVL0]) ? 0 : 1; module = (irq == dispsys_irq[DISP_REG_OVL0]) ? DISP_MODULE_OVL0 : DISP_MODULE_OVL1; reg_val = DISP_REG_GET(DISP_REG_OVL_INTSTA + index * DISP_OVL_INDEX_OFFSET); if(reg_val&(1<<1)) DDPIRQ("IRQ: OVL%d frame done!\n", index); if (reg_val & (1 << 2)) { DDPERR("IRQ: OVL%d frame underrun! cnt=%d\n", index, cnt_ovl_underflow[index]++); disp_irq_log_module |= 1<<module; } if (reg_val & (1 << 3)) { DDPIRQ("IRQ: OVL%d sw reset done\n", index); } if (reg_val & (1 << 4)) { DDPIRQ("IRQ: OVL%d hw reset done\n", index); } if (reg_val & (1 << 5)) { DDPERR("IRQ: OVL%d-RDMA0 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 6)) { DDPERR("IRQ: OVL%d-RDMA1 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 7)) { DDPERR("IRQ: OVL%d-RDMA2 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 8)) { DDPERR("IRQ: OVL%d-RDMA3 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 9)) { DDPERR("IRQ: OVL%d-RDMA0 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 10)) { DDPERR("IRQ: OVL%d-RDMA1 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 11)) { DDPERR("IRQ: OVL%d-RDMA2 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 12)) { DDPERR("IRQ: OVL%d-RDMA3 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } DISP_CPU_REG_SET(DISP_REG_OVL_INTSTA + index * DISP_OVL_INDEX_OFFSET, ~reg_val); MMProfileLogEx(ddp_mmp_get_events()->OVL_IRQ[index], MMProfileFlagPulse, reg_val, DISP_REG_GET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET)); } else if(irq==dispsys_irq[DISP_REG_WDMA0] || irq==dispsys_irq[DISP_REG_WDMA1]) { index = (irq==dispsys_irq[DISP_REG_WDMA0]) ? 0 : 1; module =(irq==dispsys_irq[DISP_REG_WDMA0]) ? DISP_MODULE_WDMA0 : DISP_MODULE_WDMA1; reg_val = DISP_REG_GET(DISP_REG_WDMA_INTSTA+index*DISP_WDMA_INDEX_OFFSET); if (reg_val & (1 << 0)) { DDPIRQ("IRQ: WDMA%d frame done!\n", index); } if (reg_val & (1 << 1)) { DDPERR("IRQ: WDMA%d underrun! cnt=%d\n", index, cnt_wdma_underflow[index]++); disp_irq_log_module |= 1 << module; } DISP_CPU_REG_SET(DISP_REG_WDMA_INTSTA + index * DISP_WDMA_INDEX_OFFSET, ~reg_val); MMProfileLogEx(ddp_mmp_get_events()->WDMA_IRQ[index], MMProfileFlagPulse, reg_val, DISP_REG_GET(DISP_REG_WDMA_CLIP_SIZE)); } else if(irq==dispsys_irq[DISP_REG_RDMA0] || irq==dispsys_irq[DISP_REG_RDMA1] || irq==dispsys_irq[DISP_REG_RDMA2] ) { if(dispsys_irq[DISP_REG_RDMA0]==irq) { index = 0; module = DISP_MODULE_RDMA0; } else if(dispsys_irq[DISP_REG_RDMA1]==irq) { index = 1; module = DISP_MODULE_RDMA1; } else if (dispsys_irq[DISP_REG_RDMA2] == irq) { index = 2; module = DISP_MODULE_RDMA2; } reg_val = DISP_REG_GET(DISP_REG_RDMA_INT_STATUS+index*DISP_RDMA_INDEX_OFFSET); if (reg_val & (1 << 0)) { DDPIRQ("IRQ: RDMA%d reg update done!\n", index); } /* deal with end first */ if (reg_val & (1 << 2)) { MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagEnd, reg_val, 0); rdma_end_time[index] = sched_clock(); DDPIRQ("IRQ: RDMA%d frame done!\n", index); } if (reg_val & (1 << 1)) { MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagStart, reg_val, 0); MMProfileLogEx(ddp_mmp_get_events()->layer[0], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x1); MMProfileLogEx(ddp_mmp_get_events()->layer[1], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L1_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x2); MMProfileLogEx(ddp_mmp_get_events()->layer[2], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L2_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x4); MMProfileLogEx(ddp_mmp_get_events()->layer[3], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L3_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x8); rdma_start_time[index] = sched_clock(); DDPIRQ("IRQ: RDMA%d frame start!\n", index); } if (reg_val & (1 << 3)) { DDPERR("IRQ: RDMA%d abnormal! cnt=%d\n", index, cnt_rdma_abnormal[index]++); disp_irq_log_module |= 1 << module; MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagPulse, reg_val, 0); } if (reg_val & (1 << 4)) { MMProfileLogEx(ddp_mmp_get_events()->rdma_underflow, MMProfileFlagPulse,cnt_rdma_underflow, 0); MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagPulse, reg_val, 0); DDPERR("IRQ: RDMA%d underflow! cnt=%d dsi0_cur(%d,%d)\n", index, cnt_rdma_underflow[index]++, DISP_REG_GET(DDP_REG_BASE_DSI0+0x168), DISP_REG_GET(DDP_REG_BASE_DSI0+0x16C)); disp_irq_log_module |= module; } if (reg_val & (1 << 5)) { DDPIRQ("IRQ: RDMA%d target line!\n", index); } /* clear intr */ DISP_CPU_REG_SET(DISP_REG_RDMA_INT_STATUS + index * DISP_RDMA_INDEX_OFFSET, ~reg_val); } else if(irq==dispsys_irq[DISP_REG_COLOR0] || irq==dispsys_irq[DISP_REG_COLOR1]) { index = (irq == dispsys_irq[DISP_REG_COLOR0]) ? 0 : 1; module = (irq == dispsys_irq[DISP_REG_COLOR0]) ? DISP_MODULE_COLOR0 : DISP_MODULE_COLOR1; reg_val = 0; } else if(irq==dispsys_irq[DISP_REG_MM_MUTEX]) { module = DISP_MODULE_MUTEX; reg_val = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_INTSTA) & 0x7C1F; for (mutexID = 0; mutexID < 5; mutexID++) { if (reg_val & (0x1 << mutexID)) { DDPIRQ("IRQ: mutex%d sof!\n", mutexID); MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 0); } } if (reg_val & (0x1 << (mutexID + DISP_MUTEX_TOTAL))) { DDPIRQ("IRQ: mutex%d eof!\n", mutexID); MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 1); } DISP_CPU_REG_SET(DISP_REG_CONFIG_MUTEX_INTSTA, ~reg_val); } else if(irq==dispsys_irq[DISP_REG_AAL]) { module = DISP_MODULE_AAL; reg_val = DISP_REG_GET(DISP_AAL_INTSTA); disp_aal_on_end_of_frame(); } else { module = DISP_MODULE_UNKNOWN; reg_val = 0; DDPERR("invalid irq=%d\n ", irq); } disp_invoke_irq_callbacks(module, reg_val); if (disp_irq_log_module != 0) { wake_up_interruptible(&disp_irq_log_wq); } //MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagEnd, irq, reg_val); return IRQ_HANDLED; }
static int disp_probe(struct platform_device *pdev) { struct class_device; int ret; int i; int new_count; static unsigned int disp_probe_cnt = 0; if(disp_probe_cnt!=0) { return 0; } #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) && (CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT) disp_misc_dev.minor = MISC_DYNAMIC_MINOR; disp_misc_dev.name = "mtk_disp"; disp_misc_dev.fops = &disp_fops; disp_misc_dev.parent = NULL; ret = misc_register(&disp_misc_dev); if (ret) { pr_err("disp: fail to create mtk_disp node\n"); return ERR_PTR(ret); } // secure video path implementation: a physical address is allocated to place a handle for decryption buffer. init_tplay_handle(&(pdev->dev)); // non-zero value for valid VA #endif new_count = nr_dispsys_dev + 1; dispsys_dev = krealloc(dispsys_dev, sizeof(struct dispsys_device) * new_count, GFP_KERNEL); if (!dispsys_dev) { DDPERR("Unable to allocate dispsys_dev\n"); return -ENOMEM; } dispsys_dev = &(dispsys_dev[nr_dispsys_dev]); dispsys_dev->dev = &pdev->dev; /* iomap registers and irq*/ for(i=0;i<DISP_REG_NUM;i++) { dispsys_dev->regs[i] = of_iomap(pdev->dev.of_node, i); if (!dispsys_dev->regs[i]) { continue; // skip } dispsys_reg[i] = dispsys_dev->regs[i]; /* get IRQ ID and request IRQ */ dispsys_dev->irq[i] = irq_of_parse_and_map(pdev->dev.of_node, i); dispsys_irq[i] = dispsys_dev->irq[i]; if (!dispsys_dev->irq[i]) { continue; // skip } if(disp_is_intr_enable(i)==1) { ret = request_irq(dispsys_dev->irq[i], (irq_handler_t)disp_irq_handler, IRQF_TRIGGER_NONE, DISP_DEVNAME, NULL); // IRQF_TRIGGER_NONE dose not take effect here, real trigger mode set in dts file if (ret) { DDPERR("Unable to request IRQ, request_irq fail, i=%d, irq=%d \n", i, dispsys_dev->irq[i]); return ret; } } DDPMSG("DT, i=%d, module=%s, map_addr=%p, map_irq=%d, reg_pa=0x%x, irq=%d \n", i, ddp_get_reg_module_name(i), dispsys_dev->regs[i], dispsys_dev->irq[i], ddp_reg_pa_base[i], ddp_irq_num[i]); } nr_dispsys_dev = new_count; //mipi tx reg map here dsi_reg_va = dispsys_reg[DISP_REG_DSI0]; mipi_tx_reg = dispsys_reg[DISP_REG_MIPI]; DPI_REG = (PDPI_REGS)dispsys_reg[DISP_REG_DPI0]; ////// power on MMSYS for early porting #ifdef CONFIG_FPGA_EARLY_PORTING printk("[DISP Probe] power MMSYS:0x%lx,0x%lx\n",DISP_REG_CONFIG_MMSYS_CG_CLR0,DISP_REG_CONFIG_MMSYS_CG_CLR1); DISP_REG_SET(0,DISP_REG_CONFIG_MMSYS_CG_CLR0,0xFFFFFFFF); DISP_REG_SET(0,DISP_REG_CONFIG_MMSYS_CG_CLR1,0xFFFFFFFF); DISP_REG_SET(0,DISPSYS_CONFIG_BASE + 0xC00,0x0);//fpga should set this register #endif ////// #ifdef MTKFB_NO_M4U DISP_REG_SET(0,DISP_REG_SMI_LARB_MMU_EN,0x0);//m4u disable #endif // init arrays ddp_path_init(); // init M4U callback DDPMSG("register m4u callback\n"); m4u_register_fault_callback(M4U_PORT_DISP_OVL0, disp_m4u_callback, 0); m4u_register_fault_callback(M4U_PORT_DISP_RDMA0, disp_m4u_callback, 0); m4u_register_fault_callback(M4U_PORT_DISP_WDMA0, disp_m4u_callback, 0); #if defined(MTK_FB_OVL1_SUPPORT) m4u_register_fault_callback(M4U_PORT_DISP_OVL1, disp_m4u_callback, 0); #endif #if defined(MTK_FB_RDMA1_SUPPORT) m4u_register_fault_callback(M4U_PORT_DISP_RDMA1, disp_m4u_callback, 0); #endif DDPMSG("dispsys probe done.\n"); //NOT_REFERENCED(class_dev); // bus hang issue error intr enable // when MMSYS clock off but GPU/MJC/PWM clock on, avoid display hang and trigger error intr { DISP_REG_SET_FIELD(0, MMSYS_TO_MFG_TX_ERROR, DISP_REG_CONFIG_MMSYS_INTEN, 1); DISP_REG_SET_FIELD(0, MMSYS_TO_MJC_TX_ERROR, DISP_REG_CONFIG_MMSYS_INTEN, 1); DISP_REG_SET_FIELD(0, PWM0_APB_TX_ERROR, DISP_REG_CONFIG_MMSYS_INTEN, 1); } /* sysfs */ DDPMSG("sysfs disp +"); //add kobject if(kobject_init_and_add(&kdispobj, &disp_kobj_ktype, NULL, "disp") <0){ DDPERR("fail to add disp\n"); return -ENOMEM; } return 0; }
static int rdma_config(DISP_MODULE_ENUM module, enum RDMA_MODE mode, unsigned long address, DpColorFormat inFormat, unsigned pitch, unsigned width, unsigned height, unsigned ufoe_enable, DISP_BUFFER_TYPE sec, void * handle) { unsigned int output_is_yuv = 0; enum RDMA_INPUT_FORMAT inputFormat = rdma_input_format_convert(inFormat); unsigned int bpp = rdma_input_format_bpp(inputFormat); unsigned int input_is_yuv = rdma_input_format_color_space(inputFormat); unsigned int input_swap = rdma_input_format_byte_swap(inputFormat); unsigned int input_format_reg = rdma_input_format_reg_value(inputFormat); unsigned int color_matrix = 0x4; //0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB) unsigned int idx = rdma_index(module); #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) && defined(CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT) DDPMSG("RDMAConfig idx %d, mode %d, address 0x%lx, inputformat %s, pitch %u, width %u, height %u,sec%d\n", idx, mode, address, rdma_intput_format_name(inputFormat,input_swap), pitch,width, height, sec); #else DDPDBG("RDMAConfig idx %d, mode %d, address 0x%lx, inputformat %s, pitch %u, width %u, height %u,sec%d\n", idx, mode, address, rdma_intput_format_name(inputFormat,input_swap), pitch,width, height, sec); #endif ASSERT(idx <= 2); if((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT)) { DDPERR("RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n", width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT); } if(input_is_yuv==1 && output_is_yuv==0) { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else if(input_is_yuv==0 && output_is_yuv==1) { color_matrix = 0x2; //0x0010, RGB_TO_BT601 DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); } DISP_REG_SET_FIELD(handle,GLOBAL_CON_FLD_MODE_SEL, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON, mode); // FORMAT & SWAP only works when RDMA memory mode, set both to 0 when RDMA direct link mode. DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_format_reg&0xf)); DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_SWAP, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_swap)); if(sec != DISP_SECURE_BUFFER) { DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_START_ADDR, address); } else { int m4u_port; unsigned int size = pitch * height; m4u_port = idx==0 ? M4U_PORT_DISP_RDMA0 : M4U_PORT_DISP_RDMA1; /* for sec layer, addr variable stores sec handle*/ /* we need to pass this handle and offset to cmdq driver */ /* cmdq sec driver will help to convert handle to correct address */ cmdqRecWriteSecure(handle, disp_addr_convert(idx*DISP_RDMA_INDEX_OFFSET+DISP_REG_RDMA_MEM_START_ADDR), CMDQ_SAM_H_2_MVA, address, 0, size, m4u_port); //DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+DISP_REG_RDMA_MEM_START_ADDR, address-0xbc000000+0x8c00000); } DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_SRC_PITCH, pitch); //DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_INT_ENABLE, 0x3F); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, width); DISP_REG_SET_FIELD(handle,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, height); rdma_set_ultra(idx, width, height, bpp, rdma_fps[idx], handle); #if 1 if(0) //UFOE bypassed, enable RDMA underflow intr, else disable RDMA underflow intr { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, gRDMAFIFOLen); } else { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, width*3*3/16/2); //FHD:304, HD:203, QHD:151 } #endif return 0; }
irqreturn_t disp_irq_handler(int irq, void *dev_id) { DISP_MODULE_ENUM module = DISP_MODULE_UNKNOWN; unsigned long reg_val = 0; unsigned int index = 0; unsigned int mutexID = 0; unsigned long reg_temp_val = 0; DDPDBG("disp_irq_handler, irq=%d, module=%s \n", irq, disp_irq_module(irq)); MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagStart, irq, 0); //switch(irq) { if(irq==dispsys_irq[DISP_REG_DSI0]) { module = DISP_MODULE_DSI0; reg_val = (DISP_REG_GET(dsi_reg_va + 0xC) & 0xff); if(atomic_read(&ESDCheck_byCPU) == 0) { reg_temp_val=reg_val&0xfffe;//rd_rdy don't clear and wait for ESD & Read LCM will clear the bit. DISP_CPU_REG_SET(dsi_reg_va + 0xC, ~reg_temp_val); } else { DISP_CPU_REG_SET(dsi_reg_va + 0xC, ~reg_val); } MMProfileLogEx(ddp_mmp_get_events()->DSI_IRQ[0], MMProfileFlagPulse, reg_val, 0); } else if(irq==dispsys_irq[DISP_REG_OVL0] || irq==dispsys_irq[DISP_REG_OVL1]) { index = (irq==dispsys_irq[DISP_REG_OVL0]) ? 0 : 1; module= (irq==dispsys_irq[DISP_REG_OVL0]) ? DISP_MODULE_OVL0 : DISP_MODULE_OVL1; reg_val = DISP_REG_GET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET); if(reg_val&(1<<1)) { DDPIRQ("IRQ: OVL%d frame done! \n",index); ovl_complete_irq_cnt[index]++; // update OVL addr { unsigned int i = 0; if(index==0) { for(i=0;i<4;i++) { if(DISP_REG_GET(DISP_REG_OVL_SRC_CON)&(0x1<<i)) MMProfileLogEx(ddp_mmp_get_events()->layer[i], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR+i*0x20), 0); } } if(index==1) { for(i=0;i<4;i++) { if(DISP_REG_GET(DISP_REG_OVL_SRC_CON+DISP_OVL_INDEX_OFFSET)&(0x1<<i)) MMProfileLogEx(ddp_mmp_get_events()->ovl1_layer[i], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR+DISP_OVL_INDEX_OFFSET+i*0x20), 0); } } } } if(reg_val&(1<<2)) { //DDPERR("IRQ: OVL%d frame underrun! cnt=%d \n",index, cnt_ovl_underflow[index]++); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<3)) { DDPIRQ("IRQ: OVL%d sw reset done\n",index); } if(reg_val&(1<<4)) { DDPIRQ("IRQ: OVL%d hw reset done\n",index); } if(reg_val&(1<<5)) { DDPERR("IRQ: OVL%d-L0 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<6)) { DDPERR("IRQ: OVL%d-L1 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<7)) { DDPERR("IRQ: OVL%d-L2 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<8)) { DDPERR("IRQ: OVL%d-L3 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<9)) { //DDPERR("IRQ: OVL%d-L0 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<10)) { //DDPERR("IRQ: OVL%d-L1 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<11)) { //DDPERR("IRQ: OVL%d-L2 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<12)) { //DDPERR("IRQ: OVL%d-L3 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } //clear intr if(reg_val&(0xf<<5)) { ddp_dump_analysis(DISP_MODULE_CONFIG); if(index==0) { ddp_dump_analysis(DISP_MODULE_OVL1); ddp_dump_analysis(DISP_MODULE_OVL0); ddp_dump_analysis(DISP_MODULE_COLOR0); ddp_dump_analysis(DISP_MODULE_AAL); ddp_dump_analysis(DISP_MODULE_RDMA0); } else { ddp_dump_analysis(DISP_MODULE_OVL1); ddp_dump_analysis(DISP_MODULE_RDMA1); ddp_dump_reg(DISP_MODULE_CONFIG); } } DISP_CPU_REG_SET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET, ~reg_val); MMProfileLogEx(ddp_mmp_get_events()->OVL_IRQ[index], MMProfileFlagPulse, reg_val, 0); if(reg_val&0x1e0) { MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, module<<24); } } else if(irq==dispsys_irq[DISP_REG_WDMA0] || irq==dispsys_irq[DISP_REG_WDMA1]) { index = (irq==dispsys_irq[DISP_REG_WDMA0]) ? 0 : 1; module =(irq==dispsys_irq[DISP_REG_WDMA0]) ? DISP_MODULE_WDMA0 : DISP_MODULE_WDMA1; reg_val = DISP_REG_GET(DISP_REG_WDMA_INTSTA+index*DISP_WDMA_INDEX_OFFSET); if(reg_val&(1<<0)) { DDPIRQ("IRQ: WDMA%d frame done!\n",index); } if(reg_val&(1<<1)) { DDPERR("IRQ: WDMA%d underrun! cnt=%d\n",index,cnt_wdma_underflow[index]++); disp_irq_log_module |= 1<<module; } //clear intr DISP_CPU_REG_SET(DISP_REG_WDMA_INTSTA+index*DISP_WDMA_INDEX_OFFSET,~reg_val); MMProfileLogEx(ddp_mmp_get_events()->WDMA_IRQ[index], MMProfileFlagPulse, reg_val, DISP_REG_GET(DISP_REG_WDMA_CLIP_SIZE)); if(reg_val&0x2) { MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, cnt_wdma_underflow[index]|(module<<24)); } } else if(irq==dispsys_irq[DISP_REG_RDMA0] || irq==dispsys_irq[DISP_REG_RDMA1]) { if(dispsys_irq[DISP_REG_RDMA0]==irq) { index = 0; module = DISP_MODULE_RDMA0; } else if(dispsys_irq[DISP_REG_RDMA1]==irq) { index = 1; module = DISP_MODULE_RDMA1; } reg_val = DISP_REG_GET(DISP_REG_RDMA_INT_STATUS+index*DISP_RDMA_INDEX_OFFSET); if(reg_val&(1<<0)) { DDPIRQ("IRQ: RDMA%d reg update done! \n",index); } if(reg_val&(1<<1)) { MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagStart, reg_val, DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR)); rdma_start_time[index]= sched_clock(); DDPIRQ("IRQ: RDMA%d frame start! \n",index); rdma_start_irq_cnt[index]++; // rdma start/end irq should equal, else need reset ovl if(gResetRDMAEnable == 1 && is_hwc_enabled == 1 && index ==0 && primary_display_is_video_mode()==1 && rdma_start_irq_cnt[0] > rdma_done_irq_cnt[0]+3) { ovl_reset(DISP_MODULE_OVL0, NULL); if(ovl_get_status()!=DDP_OVL1_STATUS_SUB) { ovl_reset(DISP_MODULE_OVL1, NULL); } rdma_done_irq_cnt[0] = rdma_start_irq_cnt[0]; DDPERR("warning: reset ovl!\n"); } #ifdef CONFIG_MTK_SEGMENT_TEST if(record_rdma_end_interval == 1) { if(rdma_end_begin_time == 0) { rdma_end_begin_time = sched_clock(); //printk("[display_test]====RDMA frame end time1:%lld\n",rdma_end_begin_time); } else { unsigned long long time_now = sched_clock(); //printk("[display_test]====RDMA frame end time2:%lld\n",time_now); //printk("[display_test]====RDMA frame end time3:this=%lld,max=%lld,min=%lld\n",time_now - rdma_end_begin_time,rdma_end_max_interval,rdma_end_min_interval); if((time_now - rdma_end_begin_time) > rdma_end_max_interval) { rdma_end_max_interval = time_now - rdma_end_begin_time; } if((time_now - rdma_end_begin_time) < rdma_end_min_interval) { rdma_end_min_interval = time_now - rdma_end_begin_time; } rdma_end_begin_time = time_now; } } #endif } if(reg_val&(1<<2)) { MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagEnd, reg_val, 0); rdma_end_time[index]= sched_clock(); DDPIRQ("IRQ: RDMA%d frame done! \n",index); //rdma_done_irq_cnt[index] ++; rdma_done_irq_cnt[index] = rdma_start_irq_cnt[index]; } if(reg_val&(1<<3)) { DDPERR("IRQ: RDMA%d abnormal! cnt=%d \n",index, cnt_rdma_abnormal[index]++); disp_irq_log_module |= 1<<module; } if(reg_val&(1<<4)) { DDPERR("IRQ: RDMA%d underflow! cnt=%d \n",index, cnt_rdma_underflow[index]++); disp_irq_log_module |= 1<<module; rdma_underflow_irq_cnt[index]++; } if(reg_val&(1<<5)) { DDPIRQ("IRQ: RDMA%d target line! \n",index); rdma_targetline_irq_cnt[index]++; } //clear intr DISP_CPU_REG_SET(DISP_REG_RDMA_INT_STATUS+index*DISP_RDMA_INDEX_OFFSET,~reg_val); MMProfileLogEx(ddp_mmp_get_events()->RDMA_IRQ[index], MMProfileFlagPulse, reg_val, 0); if(reg_val&0x18) { MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, rdma_underflow_irq_cnt[index]|(cnt_rdma_abnormal[index]<<8)||(module<<24)); } } else if(irq==dispsys_irq[DISP_REG_COLOR]) { } else if(irq==dispsys_irq[DISP_REG_MUTEX]) { // mutex0: perimary disp // mutex1: sub disp // mutex2: aal module = DISP_MODULE_MUTEX; reg_val = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_INTSTA) & 0x7C1F; for(mutexID = 0; mutexID<5; mutexID++) { if(reg_val & (0x1<<mutexID)) { DDPIRQ("IRQ: mutex%d sof!\n",mutexID); MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 0); } if(reg_val & (0x1<<(mutexID+DISP_MUTEX_TOTAL))) { DDPIRQ("IRQ: mutex%d eof!\n",mutexID); MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 1); } } DISP_CPU_REG_SET(DISP_REG_CONFIG_MUTEX_INTSTA, ~reg_val); } else if(irq==dispsys_irq[DISP_REG_AAL]) { module = DISP_MODULE_AAL; reg_val = DISP_REG_GET(DISP_AAL_INTSTA); disp_aal_on_end_of_frame(); } else if(irq==dispsys_irq[DISP_REG_CONFIG]) // MMSYS error intr { reg_val = DISP_REG_GET(DISP_REG_CONFIG_MMSYS_INTSTA) & 0x7; if(reg_val&(1<<0)) { DDPERR("MMSYS to MFG APB TX Error, MMSYS clock off but MFG clock on! \n"); } if(reg_val&(1<<1)) { DDPERR("MMSYS to MJC APB TX Error, MMSYS clock off but MJC clock on! \n"); } if(reg_val&(1<<2)) { DDPERR("PWM APB TX Error! \n"); } DISP_CPU_REG_SET(DISP_REG_CONFIG_MMSYS_INTSTA, ~reg_val); } else { module = DISP_MODULE_UNKNOWN; reg_val = 0; DDPERR("invalid irq=%d \n ", irq); } } disp_invoke_irq_callbacks(module, reg_val); if(disp_irq_log_module!=0) { wake_up_interruptible(&disp_irq_log_wq); } MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagEnd, irq, reg_val); return IRQ_HANDLED; }
// fixme: spec has no RDMA format, fix enum definition here int rdma_config(DISP_MODULE_ENUM module, enum RDMA_MODE mode, unsigned long address, DpColorFormat inFormat, unsigned pitch, unsigned width, unsigned height, unsigned ufoe_enable, void * handle) // ourput setting { unsigned int output_is_yuv = 0; enum RDMA_INPUT_FORMAT inputFormat = rdma_input_format_convert(inFormat); unsigned int bpp = rdma_input_format_bpp(inputFormat); unsigned int input_is_yuv = rdma_input_format_color_space(inputFormat); unsigned int input_swap = rdma_input_format_byte_swap(inputFormat); unsigned int input_format_reg = rdma_input_format_reg_value(inputFormat); unsigned int color_matrix = 0x4; //0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB) unsigned int idx = rdma_index(module); DDPDBG("RDMAConfig idx %d, mode %d, address 0x%x, inputformat %s, pitch %u, width %u, height %u\n", idx, mode, address, rdma_intput_format_name(inputFormat,input_swap), pitch,width, height); ASSERT(idx <= 2); if((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT)) { DDPERR("RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n", width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT); } if(input_is_yuv==1 && output_is_yuv==0) { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else if(input_is_yuv==0 && output_is_yuv==1) { color_matrix = 0x2; //0x0010, RGB_TO_BT601 DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); } DISP_REG_SET_FIELD(handle,GLOBAL_CON_FLD_MODE_SEL, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON, mode); // FORMAT & SWAP only works when RDMA memory mode, set both to 0 when RDMA direct link mode. DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_format_reg&0xf)); DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_SWAP, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_swap)); DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_START_ADDR, address); DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_SRC_PITCH, pitch); DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_INT_ENABLE, 0x3F); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, width); DISP_REG_SET_FIELD(handle,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, height); rdma_set_ultra(idx, width, height, bpp, rdma_fps[idx], handle); #if 1 if(ufoe_enable==0) //UFOE bypassed, enable RDMA underflow intr, else disable RDMA underflow intr { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 16); } else { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, width*3*3/16/2); //FHD:304, HD:203, QHD:151 } #endif return 0; }
static int disp_probe(struct platform_device *pdev) { struct class_device; int ret; int i; int new_count; static unsigned int disp_probe_cnt = 0; if(disp_probe_cnt!=0) { return 0; } new_count = nr_dispsys_dev + 1; dispsys_dev = krealloc(dispsys_dev, sizeof(struct dispsys_device) * new_count, GFP_KERNEL); if (!dispsys_dev) { DDPERR("Unable to allocate dispsys_dev\n"); return -ENOMEM; } dispsys_dev = &(dispsys_dev[nr_dispsys_dev]); dispsys_dev->dev = &pdev->dev; /* iomap registers and irq*/ for(i=0;i<DISP_REG_NUM;i++) { struct resource res; dispsys_dev->regs[i] = of_iomap(pdev->dev.of_node, i); if (!dispsys_dev->regs[i]) { DDPERR("Unable to ioremap registers, of_iomap fail, i=%d \n", i); return -ENOMEM; } dispsys_reg[i] = dispsys_dev->regs[i]; /* check physical register */ of_address_to_resource(pdev->dev.of_node, i, &res); if(ddp_reg_pa_base[i] != res.start) DDPERR("DT err, i=%d, module=%s, map_addr=%p, reg_pa=0x%x!=0x%pa\n", i, ddp_get_reg_module_name(i), dispsys_dev->regs[i], ddp_reg_pa_base[i], &res.start); /* get IRQ ID and request IRQ */ { dispsys_dev->irq[i] = irq_of_parse_and_map(pdev->dev.of_node, i); dispsys_irq[i] = dispsys_dev->irq[i]; if(disp_is_intr_enable(i)==1) { ret = request_irq(dispsys_dev->irq[i], (irq_handler_t)disp_irq_handler, IRQF_TRIGGER_NONE, ddp_get_reg_module_name(i), NULL); // IRQF_TRIGGER_NONE dose not take effect here, real trigger mode set in dts file if (ret) { DDPERR("Unable to request IRQ, request_irq fail, i=%d, irq=%d \n", i, dispsys_dev->irq[i]); return ret; } DDPMSG("irq enabled, module=%s, irq=%d \n", ddp_get_reg_module_name(i), dispsys_dev->irq[i]); } } DDPMSG("DT, i=%d, module=%s, map_addr=%p, map_irq=%d, reg_pa=0x%x\n", i, ddp_get_reg_module_name(i), dispsys_dev->regs[i], dispsys_dev->irq[i], ddp_reg_pa_base[i]); } nr_dispsys_dev = new_count; //mipi tx reg map here ////// power on MMSYS for early porting #ifdef CONFIG_FPGA_EARLY_PORTING printk("[DISP Probe] power MMSYS:0x%lx,0x%lx\n",DISP_REG_CONFIG_MMSYS_CG_CLR0,DISP_REG_CONFIG_MMSYS_CG_CLR1); DISP_REG_SET(0,DISP_REG_CONFIG_MMSYS_CG_CLR0,0xFFFFFFFF); DISP_REG_SET(0,DISP_REG_CONFIG_MMSYS_CG_CLR1,0xFFFFFFFF); DISP_REG_SET(0,DISPSYS_CONFIG_BASE + 0xC04,0x1C000);//fpga should set this register #endif ////// // init arrays ddp_path_init(); // init M4U callback #ifdef early_porting_by_k DDPMSG("register m4u callback\n"); m4u_register_fault_callback(M4U_PORT_DISP_OVL0, disp_m4u_callback, 0); m4u_register_fault_callback(M4U_PORT_DISP_RDMA0, disp_m4u_callback, 0); m4u_register_fault_callback(M4U_PORT_DISP_WDMA0, disp_m4u_callback, 0); m4u_register_fault_callback(M4U_PORT_DISP_OVL1, disp_m4u_callback, 0); m4u_register_fault_callback(M4U_PORT_DISP_RDMA1, disp_m4u_callback, 0); m4u_register_fault_callback(M4U_PORT_DISP_WDMA1, disp_m4u_callback, 0); #endif DDPMSG("dispsys probe done.\n"); //NOT_REFERENCED(class_dev); return 0; }
// fixme: spec has no RDMA format, fix enum definition here int RDMAConfig(DISP_MODULE_ENUM module, enum RDMA_MODE mode, unsigned address, DpColorFormat inFormat, unsigned pitch, unsigned width, unsigned height, unsigned ufoe_enable, void * handle) // ourput setting { unsigned int output_is_yuv = 0; enum RDMA_INPUT_FORMAT inputFormat = rdma_input_format_convert(inFormat); unsigned int bpp = rdma_input_format_bpp(inputFormat); unsigned int input_is_yuv = rdma_input_format_color_space(inputFormat); unsigned int input_swap = rdma_input_format_byte_swap(inputFormat); unsigned int input_format_reg = rdma_input_format_reg_value(inputFormat); unsigned int idx = rdma_index(module); //DDPDBG("RDMAConfig idx %d, mode %d, address 0x%x, inputformat %d, input_swap %u, pitch %u, width %u, height %u\n", // idx, mode, address, inputFormat,input_swap, pitch,width, height); ASSERT(idx <= 2); if((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT)) { DDPERR("RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n", width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT); } if(input_is_yuv==1 && output_is_yuv==0) { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0x6); // set color conversion matrix DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C00, coef_rdma_601_y2r[0][0] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C01, coef_rdma_601_y2r[0][1] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C02, coef_rdma_601_y2r[0][2] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C10, coef_rdma_601_y2r[1][0] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C11, coef_rdma_601_y2r[1][1] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C12, coef_rdma_601_y2r[1][2] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C20, coef_rdma_601_y2r[2][0] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C21, coef_rdma_601_y2r[2][1] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C22, coef_rdma_601_y2r[2][2] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_PRE_ADD_0, coef_rdma_601_y2r[3][0]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_PRE_ADD_1, coef_rdma_601_y2r[3][1]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_PRE_ADD_2, coef_rdma_601_y2r[3][2]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_POST_ADD_0, coef_rdma_601_y2r[4][0]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_POST_ADD_1, coef_rdma_601_y2r[4][1]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_POST_ADD_2, coef_rdma_601_y2r[4][2]); } else if(input_is_yuv==0 && output_is_yuv==1) { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0x2); // set color conversion matrix DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C00, coef_rdma_601_r2y[0][0] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C01, coef_rdma_601_r2y[0][1] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C02, coef_rdma_601_r2y[0][2] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C10, coef_rdma_601_r2y[1][0] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C11, coef_rdma_601_r2y[1][1] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C12, coef_rdma_601_r2y[1][2] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C20, coef_rdma_601_r2y[2][0] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C21, coef_rdma_601_r2y[2][1] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_C22, coef_rdma_601_r2y[2][2] ); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_PRE_ADD_0, coef_rdma_601_r2y[3][0]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_PRE_ADD_1, coef_rdma_601_r2y[3][1]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_PRE_ADD_2, coef_rdma_601_r2y[3][2]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_POST_ADD_0, coef_rdma_601_r2y[4][0]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_POST_ADD_1, coef_rdma_601_r2y[4][1]); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_POST_ADD_2, coef_rdma_601_r2y[4][2]); } else { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); } DISP_REG_SET_FIELD(handle,GLOBAL_CON_FLD_MODE_SEL, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON, mode); // FORMAT & SWAP only works when RDMA memory mode, set both to 0 when RDMA direct link mode. DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_format_reg&0xf)); DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_SWAP, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_swap)); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_MEM_START_ADDR, address); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_MEM_SRC_PITCH, pitch); DISP_REG_SET(handle,idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_INT_ENABLE, 0x1F); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, width); DISP_REG_SET_FIELD(handle,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, height); rdma_set_ultra(idx, width, height, bpp, 60, handle); #if 1 if(ufoe_enable==0) //UFOE bypassed, enable RDMA underflow intr, else disable RDMA underflow intr { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 16); } else { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, width*3*3/16/2); //FHD:304, HD:203, QHD:151 } #endif return 0; }
int disp_draw_num(unsigned long va, /* dst buf va */ unsigned int x, /* x offset (pixel) */ unsigned int y, /* y offset */ unsigned int pitch, /* dst pitch */ DpColorFormat fmt, /* dst buf format */ unsigned int number, /* data_digit number */ unsigned int alpha_en, /* transparent */ unsigned int color_argb) /* background oqupa or not */ { unsigned int h = 0; unsigned int w = 0; unsigned int bpp = 0; unsigned int num_offset = 0; unsigned int len = 0; unsigned int i = 0; unsigned int num[20] = { 0 }; unsigned int value; if (DP_COLOR_BITS_PER_PIXEL(fmt) != 32 && DP_COLOR_BITS_PER_PIXEL(fmt) != 24) { DDPERR(" only support ARGB / RGB888 now !\n "); return -1; } bpp = DP_COLOR_BITS_PER_PIXEL(fmt) / 8; do { if (len >= 20 || DISP_DIGIT_W * (len + 1) > pitch / bpp - x) { /* len to long or buf width too short */ DDPERR(" number too big for dst buf !\n "); break; } num[len++] = number % 10; number = number / 10; } while (number > 0); for (i = 0; i < len; i++) { num_offset = DISP_DIGIT_W * DISP_DIGIT_H / 8 * num[len - i - 1]; for (h = 0; h < DISP_DIGIT_H; h++) { /* DDPMSG(" h = %d, value = 0x%x.\n ", h, value); */ for (w = 0; w < DISP_DIGIT_W; w++) { value = (unsigned int)data_digit[num_offset + (h * DISP_DIGIT_W + w) / 8]; if (bpp == 4) { if ((value & 0xff & (1 << (7 - (w % 8)))) == 0) *(unsigned int *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp) = color_argb; else if (alpha_en == 0) *(unsigned int *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp) = 0xffffffff; /* DDPMSG(" w = %d, of = %d.\n ", w, h*pitch+w*bpp+y*pitch+x*bpp+i*DISP_DIGIT_W*bpp); */ } else if (bpp == 3) { if ((value & 0xff & (1 << (7 - (w % 8)))) == 0) { *(unsigned char *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp) = (unsigned char)(color_argb & 0xff); *(unsigned char *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp + 1) = (unsigned char)((color_argb >> 8) & 0xff); *(unsigned char *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp + 2) = (unsigned char)((color_argb >> 16) & 0xff); } else if (alpha_en == 0) { *(unsigned int *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp) = 0xff; *(unsigned int *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp + 1) = 0xff; *(unsigned int *)(va + h * pitch + w * bpp + y * pitch + x * bpp + i * DISP_DIGIT_W * bpp + 2) = 0xff; } } } }