int disp_bls_set_backlight(unsigned int level) { printf("[DDP] disp_bls_set_backlight: %d, CG = 0x%x, BLS_EN = 0x%x, PWM_DUTY = %d\n", level, DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0), DISP_REG_GET(DISP_REG_BLS_EN), DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); if (level && (!(DISP_REG_GET(DISP_REG_BLS_EN) & 0x10000))) { disp_bls_config(); } #ifdef USE_DISP_BLS_MUTEX disp_bls_get_mutex(); #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x3); #endif DISP_REG_SET(DISP_REG_BLS_PWM_DUTY, brightness_mapping(level)); printf("[DDP] PWM_DUTY: %x\n", DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); #ifdef USE_DISP_BLS_MUTEX disp_bls_release_mutex(); #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x0); #endif return 0; }
static void ddp_check_mutex_l(int mutex_id, int* module_list, DDP_MODE ddp_mode) { int i=0; kal_uint32 real_value = 0; kal_uint32 expect_value = 0; kal_uint32 real_sof = 0; MUTEX_SOF expect_sof = SOF_SINGLE; int module_num = ddp_get_module_num_l(module_list); if(mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) { DDPDUMP("error:check mutex fail:exceed mutex max (0 ~ %d)\n",DISP_MUTEX_DDP_LAST); return; } real_value = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_MOD(mutex_id)); for(i = 0 ; i < module_num ; i++) { if(module_mutex_map[module_list[i]].bit != -1) expect_value |= (1 << module_mutex_map[module_list[i]].bit); } if( expect_value != real_value ) { DDPDUMP("error:mutex %d error: expect 0x%x, real 0x%x\n",mutex_id,expect_value,real_value); } real_sof = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_SOF(mutex_id)); expect_sof = ddp_get_mutex_sof(module_list[module_num-1],ddp_mode); if((kal_uint32)expect_sof != real_sof) { DDPDUMP("error:mutex %d sof error: expect %s, real %s\n", mutex_id, ddp_get_mutex_sof_name(expect_sof), ddp_get_mutex_sof_name((MUTEX_SOF)real_sof)); } }
void disp_bls_init(unsigned int srcWidth, unsigned int srcHeight) { struct cust_mt65xx_led *cust_led_list = get_cust_led_list(); struct cust_mt65xx_led *cust = NULL; struct PWM_config *config_data = NULL; if(cust_led_list) { cust = &cust_led_list[MT65XX_LED_TYPE_LCD]; if((strcmp(cust->name,"lcd-backlight") == 0) && (cust->mode == MT65XX_LED_MODE_CUST_BLS_PWM)) { config_data = &cust->config_data; if (config_data->clock_source >= 0 && config_data->clock_source <= 3) { unsigned int regVal = DISP_REG_GET(CLK_CFG_1); DISP_REG_SET(CLK_CFG_1, (regVal & ~0x3) | config_data->clock_source); printf("disp_bls_init : CLK_CFG_1 0x%x => 0x%x\n", regVal, DISP_REG_GET(CLK_CFG_1)); } gPWMDiv = (config_data->div == 0) ? PWM_DEFAULT_DIV_VALUE : config_data->div; gPWMDiv &= 0x3FF; printf("disp_bls_init : PWM config data (%d,%d)\n", config_data->clock_source, config_data->div); } } printf("[DDP] disp_bls_init : srcWidth = %d, srcHeight = %d\n", srcWidth, srcHeight); printf("[DDP] disp_bls_init : CG = 0x%x, BLS_EN = 0x%x, PWM_DUTY = %d\n", DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0), DISP_REG_GET(DISP_REG_BLS_EN), DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); DISP_REG_SET(DISP_REG_BLS_SRC_SIZE, (srcHeight << 16) | srcWidth); DISP_REG_SET(DISP_REG_BLS_PWM_DUTY, 0); DISP_REG_SET(DISP_REG_BLS_PWM_CON, 0x0 | (gPWMDiv << 16)); DISP_REG_SET(DISP_REG_BLS_EN, 0x00010000); }
unsigned int ddp_dump_reg_to_buf(unsigned int start_module, unsigned long *addr) { unsigned int cnt = 0; unsigned long reg_addr; switch (start_module) { case 0: /* DISP_MODULE_WDMA0: */ reg_addr = DISP_REG_WDMA_INTEN; while (reg_addr <= DISP_REG_WDMA_PRE_ADD2) { addr[cnt++] = DISP_REG_GET(reg_addr); reg_addr += 4; } case 1: /* DISP_MODULE_OVL: */ reg_addr = DISP_REG_OVL_STA; while (reg_addr <= DISP_REG_OVL_L3_PITCH) { addr[cnt++] = DISP_REG_GET(reg_addr); reg_addr += 4; } case 2: /* DISP_MODULE_RDMA: */ reg_addr = DISP_REG_RDMA_INT_ENABLE; while (reg_addr <= DISP_REG_RDMA_PRE_ADD_1) { addr[cnt++] = DISP_REG_GET(reg_addr); reg_addr += 4; } break; } return cnt * sizeof(unsigned long); }
void rdma_dump_analysis(DISP_MODULE_ENUM module) { unsigned int idx = rdma_index(module); DDPDUMP("==DISP RDMA%d ANALYSIS==\n", idx); DDPDUMP("rdma%d: en=%d, memory mode=%d, w=%d, h=%d, pitch=%d, addr=0x%x, fmt=%s, fifo_min=%d, \ in_p_cnt=%d, in_l_cnt=%d, out_p_cnt=%d, out_l_cnt=%d, rdma_start_time=%lld ns,rdma_end_time=%lld ns\n", idx, DISP_REG_GET(DISP_REG_RDMA_GLOBAL_CON+DISP_RDMA_INDEX_OFFSET*idx)&0x1, (DISP_REG_GET(DISP_REG_RDMA_GLOBAL_CON+DISP_RDMA_INDEX_OFFSET*idx)&0x2)?1:0, DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0+DISP_RDMA_INDEX_OFFSET*idx)&0xfff, DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1+DISP_RDMA_INDEX_OFFSET*idx)&0xfffff, DISP_REG_GET(DISP_REG_RDMA_MEM_SRC_PITCH+DISP_RDMA_INDEX_OFFSET*idx), DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR+DISP_RDMA_INDEX_OFFSET*idx), rdma_intput_format_name( (DISP_REG_GET(DISP_REG_RDMA_MEM_CON+DISP_RDMA_INDEX_OFFSET*idx)>>4)&0xf, (DISP_REG_GET(DISP_REG_RDMA_MEM_CON+DISP_RDMA_INDEX_OFFSET*idx)>>8)&0x1 ), DISP_REG_GET(DISP_REG_RDMA_FIFO_LOG+DISP_RDMA_INDEX_OFFSET*idx), DISP_REG_GET(DISP_REG_RDMA_IN_P_CNT+DISP_RDMA_INDEX_OFFSET*idx), DISP_REG_GET(DISP_REG_RDMA_IN_LINE_CNT+DISP_RDMA_INDEX_OFFSET*idx), DISP_REG_GET(DISP_REG_RDMA_OUT_P_CNT+DISP_RDMA_INDEX_OFFSET*idx), DISP_REG_GET(DISP_REG_RDMA_OUT_LINE_CNT+DISP_RDMA_INDEX_OFFSET*idx), rdma_start_time[idx], rdma_end_time[idx] ); DDPDUMP("irq cnt: start=%d, end=%d, underflow=%d, targetline=%d \n", rdma_start_irq_cnt[idx], rdma_done_irq_cnt[idx], rdma_underflow_irq_cnt[idx], rdma_targetline_irq_cnt[idx]); return ; }
int rdma_resolution_test(DISP_MODULE_ENUM module,unsigned int fw,unsigned fh) { int ret=0; unsigned int idx = rdma_index(module); int pw = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0+DISP_RDMA_INDEX_OFFSET*idx)&0xfff; int ph = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1+DISP_RDMA_INDEX_OFFSET*idx)&0xfffff; //reset rdma ret=rdma_reset(module,NULL); if(ret!=0) { printk("reset fail\n"); return -1; } DISP_REG_SET_FIELD(NULL,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, pw); DISP_REG_SET_FIELD(NULL,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, ph); DISP_REG_SET_FIELD(NULL,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, fw); DISP_REG_SET_FIELD(NULL,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, fh); int w = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0+DISP_RDMA_INDEX_OFFSET*idx)&0xfff; int h = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1+DISP_RDMA_INDEX_OFFSET*idx)&0xfffff; if((w!=pw) && (h!=ph)) { printk("w=%d,h=%d,pw=%d,ph=%d,fw=%d,fh=%d\n",w,h,pw,ph,fw,fh); DISP_REG_SET_FIELD(NULL,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, pw); DISP_REG_SET_FIELD(NULL,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, ph); ret =-1; } return ret; }
int rdma_reset(DISP_MODULE_ENUM module,void * handle) { unsigned int delay_cnt=0; int ret =0; unsigned int idx = rdma_index(module); ASSERT(idx <= 2); DISP_REG_SET_FIELD(handle,GLOBAL_CON_FLD_SOFT_RESET, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON, 1); while((DISP_REG_GET(idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON)&0x700)==0x100) { delay_cnt++; udelay(10); if(delay_cnt>10000) { ret = -1; DDPERR("rdma%d_reset timeout, stage 1! DISP_REG_RDMA_GLOBAL_CON=0x%x \n", idx, DISP_REG_GET(idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON)); break; } } DISP_REG_SET_FIELD(handle,GLOBAL_CON_FLD_SOFT_RESET, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON, 0); delay_cnt =0; while((DISP_REG_GET(idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON)&0x700)!=0x100) { delay_cnt++; udelay(10); if(delay_cnt>10000) { ret = -1; DDPERR("rdma%d_reset timeout, stage 2! DISP_REG_RDMA_GLOBAL_CON=0x%x \n", idx, DISP_REG_GET(idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON)); break; } } return ret; }
void ovl_get_info(int idx, void *data) { int i = 0; OVL_BASIC_STRUCT *pdata = (OVL_BASIC_STRUCT *)data; unsigned int idx_offset = 0; unsigned int layer_off = 0; unsigned int src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset); OVL_BASIC_STRUCT *p = NULL; memset(pdata, 0, sizeof(OVL_BASIC_STRUCT)*OVL_LAYER_NUM); idx_offset = 0; src_on = DISP_REG_GET(DISP_REG_OVL_SRC_CON + idx_offset); for (i = 0; i < OVL_LAYER_NUM_PER_OVL; i++) { layer_off = (i%4)*OVL_LAYER_OFFSET + idx_offset; p = &pdata[i]; p->layer = i; p->layer_en = src_on & (0x1<<i); if (p->layer_en) { p->fmt = (DISP_REG_GET(layer_off+DISP_REG_OVL_L0_CON)>>12)&0xf; p->addr = DISP_REG_GET(layer_off+DISP_REG_OVL_L0_ADDR); p->src_w = DISP_REG_GET(layer_off+DISP_REG_OVL_L0_SRC_SIZE)&0xfff; p->src_h = (DISP_REG_GET(layer_off+DISP_REG_OVL_L0_SRC_SIZE)>>16)&0xfff; p->src_pitch = DISP_REG_GET(layer_off+DISP_REG_OVL_L0_PITCH)&0xffff; p->bpp = ddp_get_bpp(DISP_MODULE_OVL, (DISP_REG_GET(layer_off+DISP_REG_OVL_L0_CON)>>12)&0xf); } DISP_DBG("ovl_get_info:layer%d,en %d,w %d,h %d, bpp %d,addr %lx\n", i, p->layer_en, p->src_w, p->src_h, p->bpp, p->addr); }
int OVLReset() { unsigned int delay_cnt = 0; static unsigned int cnt=0; printk("[DDP] OVLReset called %d \n", cnt++); DISP_REG_SET(DISP_REG_OVL_RST, 0x1); // soft reset DISP_REG_SET(DISP_REG_OVL_RST, 0x0); while (((DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG)&0x3ff) != 0x1) && ((DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG)&0x3ff) != 0x2)) { delay_cnt++; if(delay_cnt>10000) { printk("[DDP] error, OVLReset() timeout! \n"); ddp_dump_info(DISP_MODULE_CONFIG); ddp_dump_info(DISP_MODULE_MUTEX); ddp_dump_info(DISP_MODULE_OVL); ddp_dump_info(DISP_MODULE_RDMA); disp_dump_reg(DISP_MODULE_OVL); smi_dumpDebugMsg(); break; } } #if 0 DISP_REG_SET(DISP_REG_OVL_ROI_SIZE , 0x00); // clear regs DISP_REG_SET(DISP_REG_OVL_ROI_BGCLR , 0x00); DISP_REG_SET(DISP_REG_OVL_SRC_CON , 0x00); DISP_REG_SET(DISP_REG_OVL_L0_CON , 0x00); DISP_REG_SET(DISP_REG_OVL_L0_SRCKEY , 0x00); DISP_REG_SET(DISP_REG_OVL_L0_SRC_SIZE , 0x00); DISP_REG_SET(DISP_REG_OVL_L0_OFFSET , 0x00); DISP_REG_SET(DISP_REG_OVL_L0_ADDR , 0x00); DISP_REG_SET(DISP_REG_OVL_L0_PITCH , 0x00); DISP_REG_SET(DISP_REG_OVL_L1_CON , 0x00); DISP_REG_SET(DISP_REG_OVL_L1_SRCKEY , 0x00); DISP_REG_SET(DISP_REG_OVL_L1_SRC_SIZE , 0x00); DISP_REG_SET(DISP_REG_OVL_L1_OFFSET , 0x00); DISP_REG_SET(DISP_REG_OVL_L1_ADDR , 0x00); DISP_REG_SET(DISP_REG_OVL_L1_PITCH , 0x00); DISP_REG_SET(DISP_REG_OVL_L2_CON , 0x00); DISP_REG_SET(DISP_REG_OVL_L2_SRCKEY , 0x00); DISP_REG_SET(DISP_REG_OVL_L2_SRC_SIZE , 0x00); DISP_REG_SET(DISP_REG_OVL_L2_OFFSET , 0x00); DISP_REG_SET(DISP_REG_OVL_L2_ADDR , 0x00); DISP_REG_SET(DISP_REG_OVL_L2_PITCH , 0x00); DISP_REG_SET(DISP_REG_OVL_L3_CON , 0x00); DISP_REG_SET(DISP_REG_OVL_L3_SRCKEY , 0x00); DISP_REG_SET(DISP_REG_OVL_L3_SRC_SIZE , 0x00); DISP_REG_SET(DISP_REG_OVL_L3_OFFSET , 0x00); DISP_REG_SET(DISP_REG_OVL_L3_ADDR , 0x00); DISP_REG_SET(DISP_REG_OVL_L3_PITCH , 0x00); #endif return 0; }
static int RDMAPollingInterrupt(DISP_MODULE_ENUM module, int bit, int timeout) { unsigned int idx = rdma_index(module); unsigned int cnt = 0; unsigned int regval = 0; if( timeout <= 0) { while((DISP_REG_GET(idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_INT_STATUS) & bit)==0); cnt = 1; } else { // time need to update cnt = timeout*1000/100; while(cnt > 0) { cnt--; regval = DISP_REG_GET(idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_INT_STATUS); if(regval & bit ) { DISP_CPU_REG_SET(idx*DISP_INDEX_OFFSET+ DISP_REG_RDMA_INT_STATUS, ~regval); break; } udelay(100); } } //should clear? DDPMSG(" RDMA%d polling interrupt ret =%d \n", idx, cnt); return cnt; }
int WDMAReset(unsigned idx) { unsigned int delay_cnt = 0; static unsigned int wdma_timeout_cnt = 0; //WDMA_RST = 0x00; DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_RST , 0x01); // soft reset while(((DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG)&0x3ff) != 0x1) && ((DISP_REG_GET(DISP_REG_OVL_FLOW_CTRL_DBG)&0x3ff) != 0x2)) { delay_cnt++; if(delay_cnt>10000) { printk("[DDP] error, WDMAReset(%d) timeout! wdma_timeout_cnt=%d \n", idx, wdma_timeout_cnt++); WDMADumpHidenReg(idx); disp_dump_reg(DISP_MODULE_WDMA0); smi_dumpDebugMsg(); break; } } DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_RST , 0x00); DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_CFG , 0x00); DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_SRC_SIZE , 0x00); DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_CLIP_SIZE , 0x00); DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_CLIP_COORD , 0x00); DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_DST_ADDR , 0x00); DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_DST_W_IN_BYTE , 0x00); DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_WDMA_ALPHA , 0x00); // clear regs return 0; }
static int aal_config(DISP_MODULE_ENUM module, disp_ddp_path_config *pConfig, void *cmdq) { if (pConfig->dst_dirty) { int width, height; width = pConfig->dst_w; height = pConfig->dst_h; DISP_REG_SET(cmdq, DISP_AAL_SIZE, (width << 16) | height); DISP_REG_MASK(cmdq, DISP_AAL_CFG, 0x0, 0x1); /* Disable relay mode */ disp_aal_init(module, width, height, cmdq); DISP_REG_MASK(cmdq, DISP_AAL_EN, 0x1, 0x1); AAL_DBG("AAL_CFG = 0x%x, AAL_SIZE = 0x%x(%d, %d)", DISP_REG_GET(DISP_AAL_CFG), DISP_REG_GET(DISP_AAL_SIZE), width, height); } if (pConfig->ovl_dirty || pConfig->rdma_dirty) { disp_aal_notify_frame_dirty(); } return 0; }
static void mutex_dump_analysis(void) { int i=0; int j=0; char mutex_module[512]={'\0'}; char * p = NULL; int len = 0; DDPDUMP("==DISP Mutex Analysis==\n"); for (i = 0; i < 5; i++) { p = mutex_module; len = 0; if( DISP_REG_GET(DISP_REG_CONFIG_MUTEX_MOD(i))!=0 && ((DISP_REG_GET(DISP_REG_CONFIG_MUTEX_EN(i)+0x20*i)==1 && DISP_REG_GET(DISP_REG_CONFIG_MUTEX_SOF(i)+0x20*i)!=SOF_SINGLE ) || DISP_REG_GET(DISP_REG_CONFIG_MUTEX_SOF(i)+0x20*i)==SOF_SINGLE)) { len = sprintf(p,"MUTEX%d :mode=%s,module=(", i, ddp_mutex_sof_to_string( DISP_REG_GET(DISP_REG_CONFIG_MUTEX_SOF(i)))); p += len; for(j=11;j<=25;j++) { if((DISP_REG_GET(DISP_REG_CONFIG_MUTEX_MOD(i))>>j)&0x1) { len = sprintf(p,"%s,", ddp_get_mutex_module_name(j)); p += len; } } DDPDUMP("%s)\n",mutex_module); } }
void disp_aal_on_end_of_frame(void) { unsigned int intsta; int i; unsigned long flags; intsta = DISP_REG_GET(DISP_AAL_INTSTA); AAL_DBG("disp_aal_on_end_of_frame: intsta: 0x%x", intsta); if (intsta & 0x2) { /* End of frame */ if (spin_trylock_irqsave(&g_aal_hist_lock, flags)) { DISP_CPU_REG_SET(DISP_AAL_INTSTA, (intsta & ~0x3)); for (i = 0; i < AAL_HIST_BIN; i++) { g_aal_hist.maxHist[i] = DISP_REG_GET(DISP_AAL_STATUS_00 + (i << 2)); } g_aal_hist_available = 1; /* Allow to disable interrupt */ g_aal_dirty_frame_retrieved = 1; spin_unlock_irqrestore(&g_aal_hist_lock, flags); wake_up_interruptible(&g_aal_hist_wq); } else { /* * Histogram was not be retrieved, but it's OK. * Another interrupt will come until histogram available * See: disp_aal_set_interrupt() */ } } }
int disp_bls_config(void) { #if !defined(MTK_AAL_SUPPORT) struct cust_mt65xx_led *cust_led_list = get_cust_led_list(); struct cust_mt65xx_led *cust = NULL; struct PWM_config *config_data = NULL; if(cust_led_list) { cust = &cust_led_list[MT65XX_LED_TYPE_LCD]; if((strcmp(cust->name,"lcd-backlight") == 0) && (cust->mode == MT65XX_LED_MODE_CUST_BLS_PWM)) { config_data = &cust->config_data; if (config_data->clock_source >= 0 && config_data->clock_source <= 3) { unsigned int regVal = DISP_REG_GET(CLK_CFG_1); DISP_REG_SET(CLK_CFG_1, (regVal & ~0x3) | config_data->clock_source); printf("disp_bls_config : CLK_CFG_1 0x%x => 0x%x\n", regVal, DISP_REG_GET(CLK_CFG_1)); } gPWMDiv = (config_data->div == 0) ? PWM_DEFAULT_DIV_VALUE : config_data->div; gPWMDiv &= 0x3FF; printf("disp_bls_config : PWM config data (%d,%d)\n", config_data->clock_source, config_data->div); } } printf("[DDP] disp_bls_config : CG = 0x%x, BLS_EN = 0x%x, PWM_DUTY = %d\n", DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0), DISP_REG_GET(DISP_REG_BLS_EN), DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); #ifdef USE_DISP_BLS_MUTEX printf("[DDP] disp_bls_config : gBLSMutexID = %d\n", gBLSMutexID); DISP_REG_SET(DISP_REG_CONFIG_MUTEX_RST(gBLSMutexID), 1); DISP_REG_SET(DISP_REG_CONFIG_MUTEX_RST(gBLSMutexID), 0); DISP_REG_SET(DISP_REG_CONFIG_MUTEX_MOD(gBLSMutexID), 0x200); // BLS DISP_REG_SET(DISP_REG_CONFIG_MUTEX_SOF(gBLSMutexID), 0); // single mode DISP_REG_SET(DISP_REG_CONFIG_MUTEX_EN(gBLSMutexID), 1); if (disp_bls_get_mutex() == 0) { #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x3); #endif DISP_REG_SET(DISP_REG_BLS_PWM_DUTY, 0); DISP_REG_SET(DISP_REG_BLS_PWM_CON, 0x0 | (gPWMDiv << 16)); DISP_REG_SET(DISP_REG_BLS_EN, 0x00010000); #ifdef USE_DISP_BLS_MUTEX if (disp_bls_release_mutex() == 0) return 0; } return -1; #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x0); #endif #endif return 0; }
int disp_bls_set_backlight(unsigned int level) { unsigned int mapped_level; DISP_MSG("disp_bls_set_backlight: %d, gBLSPowerOn = %d\n", level, gBLSPowerOn); mutex_lock(&backlight_mutex); if(level && !clock_is_on(MT_CG_PWM_MM_SW_CG)) enable_clock(MT_CG_PWM_MM_SW_CG, "DDP"); if (level && !clock_is_on(MT_CG_MDP_BLS_26M_SW_CG)) { // remove CG control to DDP path ASSERT(0); if (!gBLSPowerOn) { // config BLS parameter disp_bls_config(); } } #ifdef USE_DISP_BLS_MUTEX disp_bls_get_mutex(); #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x3); #endif mapped_level = brightness_mapping(level); DISP_MSG("after mapping, mapped_level: %d\n", mapped_level); DISP_REG_SET(DISP_REG_BLS_PWM_DUTY, mapped_level); if (mapped_level) // enable PWM generator DISP_REG_SET(DISP_REG_BLS_EN, DISP_REG_GET(DISP_REG_BLS_EN) | 0x10000); else // disable PWM generator DISP_REG_SET(DISP_REG_BLS_EN, DISP_REG_GET(DISP_REG_BLS_EN) & 0xFFFEFFFF); DISP_MSG("after SET, PWM_DUTY: %d\n", DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); #ifdef USE_DISP_BLS_MUTEX disp_bls_release_mutex(); #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x0); #endif if(!level && clock_is_on(MT_CG_PWM_MM_SW_CG)) disable_clock(MT_CG_PWM_MM_SW_CG, "DDP"); if (!level && gBLSPowerOn) { DISP_MSG("disp_bls_set_backlight: disable clock\n"); // disable_clock(MT_CG_DISP0_SMI_LARB0 , "DDP"); gBLSPowerOn = 0; } mutex_unlock(&backlight_mutex); return 0; }
void rdma_get_info(int idx, RDMA_BASIC_STRUCT * info) { RDMA_BASIC_STRUCT *p = info; p->addr = DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR+DISP_RDMA_INDEX_OFFSET*idx); p->src_w = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0+DISP_RDMA_INDEX_OFFSET*idx)&0xfff; p->src_h = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1+DISP_RDMA_INDEX_OFFSET*idx)&0xfffff, p->bpp = rdma_input_format_bpp((DISP_REG_GET(DISP_REG_RDMA_MEM_CON+DISP_RDMA_INDEX_OFFSET*idx)>>4)&0xf); return ; }
int ovl_is_idle(DISP_MODULE_ENUM module) { int idx = ovl_index(module); int idx_offset = idx*DISP_OVL_INDEX_OFFSET; if(((DISP_REG_GET(idx_offset+DISP_REG_OVL_FLOW_CTRL_DBG)&0x3ff)!=0x1) && ((DISP_REG_GET(idx_offset+DISP_REG_OVL_FLOW_CTRL_DBG)&0x3ff)!=0x2)) {return 0;} else {return 1;} }
void disp_bls_update_gamma_lut(void) { int index, i; unsigned long regValue; unsigned long CurVal, Count; #ifndef NEW_GAMMA_ARRAY_ARRANGEMENT // make it build fail for EPC rule after MP DISP_MSG("disp_bls_update_gamma_lut!\n"); #endif DISP_MSG("disp_bls_update_gamma_lut!\n"); // init gamma table for(index = 0; index < 3; index++) { for(Count = 0; Count < 257 ; Count++) { g_gamma_lut.entry[index][Count] = g_gamma_index.entry[index][Count]; } } // disable BLS_EN first DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x00000003); regValue = DISP_REG_GET(DISP_REG_BLS_EN); DISP_REG_SET(DISP_REG_BLS_EN, regValue & 0x00010000); DISP_MSG("ready to modify gamma lut, set BLS_EN=%x\n", DISP_REG_GET(DISP_REG_BLS_EN)); DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x00000000); DISP_REG_SET(DISP_REG_BLS_LUT_UPDATE, 0x1); for (i = 0; i < 256 ; i++) { CurVal = (((g_gamma_lut.entry[0][i]&0x3FF)<<20) | ((g_gamma_lut.entry[1][i]&0x3FF)<<10) | (g_gamma_lut.entry[2][i]&0x3FF)); DISP_REG_SET(DISP_REG_BLS_GAMMA_LUT(i), CurVal); DISP_DBG("[%d] GAMMA LUT = 0x%x, (%lu, %lu, %lu)\n", i, DISP_REG_GET(DISP_REG_BLS_GAMMA_LUT(i)), g_gamma_lut.entry[0][i], g_gamma_lut.entry[1][i], g_gamma_lut.entry[2][i]); } /* Set Gamma Last point*/ DISP_REG_SET(DISP_REG_BLS_GAMMA_SETTING, 0x00000001); // set gamma last index CurVal = (((g_gamma_lut.entry[0][256]&0x3FF)<<20) | ((g_gamma_lut.entry[1][256]&0x3FF)<<10) | (g_gamma_lut.entry[2][256]&0x3FF)); DISP_REG_SET(DISP_REG_BLS_GAMMA_BOUNDARY, CurVal); DISP_REG_SET(DISP_REG_BLS_LUT_UPDATE, 0); //DISP_REG_SET(DISP_REG_BLS_EN, regValue); //set BLS_EN to oringinal value DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x00000003); DISP_REG_SET(DISP_REG_BLS_EN, regValue); DISP_MSG("end modifying gamma lut, set BLS_EN=%x\n", DISP_REG_GET(DISP_REG_BLS_EN)); DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x00000000); }
void disp_bls_init(unsigned int srcWidth, unsigned int srcHeight) { DDP_DRV_DBG("disp_bls_init : srcWidth = %d, srcHeight = %d\n", srcWidth, srcHeight); struct cust_mt65xx_led *cust_led_list = get_cust_led_list(); struct cust_mt65xx_led *cust = NULL; struct PWM_config *config_data = NULL; if(cust_led_list) { cust = &cust_led_list[MT65XX_LED_TYPE_LCD]; if((strcmp(cust->name,"lcd-backlight") == 0) && (cust->mode == MT65XX_LED_MODE_CUST_BLS_PWM)) { config_data = &cust->config_data; if (config_data->clock_source >= 0 && config_data->clock_source <= 1) { unsigned int regVal = DISP_REG_GET(0xF0000000); if(config_data->clock_source == 0) clkmux_sel(MT_CLKMUX_PWM_MM_MUX_SEL, MT_CG_SYS_26M, "DISP_PWM"); else clkmux_sel(MT_CLKMUX_PWM_MM_MUX_SEL, MT_CG_UPLL_D12, "DISP_PWM"); DISP_DBG("disp_bls_init : 0xF0000000: 0x%x => 0x%x\n", regVal, DISP_REG_GET(0xF0000000)); } } } // TODO: fix register setting DISP_REG_SET(DISP_REG_BLS_SRC_SIZE, (srcHeight << 16) | srcWidth); DISP_REG_SET(DISP_REG_BLS_PWM_DUTY, DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); DISP_REG_SET(DISP_REG_BLS_PWM_CON, 0x0); DISP_REG_SET(DISP_REG_BLS_INTEN, 0xF); disp_bls_update_gamma_lut(); //disp_bls_update_pwm_lut(); // not used in 6572 #if 0 // TODO: fix Dither setting // Dithering DISP_REG_SET(DISP_REG_BLS_DITHER(0), 0x00000001); DISP_REG_SET(DISP_REG_BLS_DITHER(6), 0x00000000); DISP_REG_SET(DISP_REG_BLS_DITHER(13), 0x00000222); DISP_REG_SET(DISP_REG_BLS_DITHER(14), 0x00000000); DISP_REG_SET(DISP_REG_BLS_DITHER(15), 0x22220001); DISP_REG_SET(DISP_REG_BLS_DITHER(16), 0x22222222); DISP_REG_SET(DISP_REG_BLS_DITHER(17), 0x00000000); #endif DISP_REG_SET(DISP_REG_BLS_EN, 0x00010001); // enable BLS_EN disp_bls_config_full(srcWidth, srcHeight); #if 0 disp_dump_reg(DISP_MODULE_BLS); #endif }
void disp_set_pll(unsigned int freq) { unsigned long reg_va_con0 = 0; unsigned long reg_va_con1 = 0; static unsigned int freq_last = 364; static unsigned int pll_cnt; if (freq == freq_last) return; freq_last = freq; reg_va_con0 = (unsigned long)ioremap_nocache(REG_PA_VENC_PLL_CON0, sizeof(unsigned long)); reg_va_con1 = (unsigned long)ioremap_nocache(REG_PA_VENC_PLL_CON1, sizeof(unsigned long)); pr_debug ("disp_set_pll(%d), before set, con0=0x%x, con1=0x%x, 0x%lx, 0x%lx\n", freq, DISP_REG_GET(reg_va_con0), DISP_REG_GET(reg_va_con1), reg_va_con0, reg_va_con1); if (freq == 156) { enable_pll(VENCPLL, DISP_CLOCK_USER_NAME); DISP_CPU_REG_SET(reg_va_con0, DISP_MMCLK_156MHZ_CON0); DISP_CPU_REG_SET(reg_va_con1, DISP_MMCLK_156MHZ_CON1); clkmux_sel(MT_MUX_MM, 3, DISP_CLOCK_USER_NAME); pll_cnt++; } else if (freq == 182) { enable_pll(VENCPLL, DISP_CLOCK_USER_NAME); DISP_CPU_REG_SET(reg_va_con0, DISP_MMCLK_182MHZ_CON0); DISP_CPU_REG_SET(reg_va_con1, DISP_MMCLK_182MHZ_CON1); clkmux_sel(MT_MUX_MM, 3, DISP_CLOCK_USER_NAME); pll_cnt++; } else if (freq == 364) { clkmux_sel(MT_MUX_MM, 1, DISP_CLOCK_USER_NAME); if (pll_cnt != 0) { disable_pll(VENCPLL, DISP_CLOCK_USER_NAME); pll_cnt--; } } else { pr_debug("disp_set_pll, error, invalid freq=%d\n", freq); } pr_debug("disp_set_pll(%d), after set, con0=0x%x, con1=0x%x\n", freq, DISP_REG_GET(reg_va_con0), DISP_REG_GET(reg_va_con1)); iounmap((void *)reg_va_con0); iounmap((void *)reg_va_con1); }
void rdma_get_info(int idx, RDMA_BASIC_STRUCT * info) { RDMA_BASIC_STRUCT *p = info; p->addr = DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR); p->src_w = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0)&0xfff; p->src_h = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1)&0xfffff, p->bpp = ddp_get_bpp(DISP_MODULE_RDMA, (DISP_REG_GET(DISP_REG_RDMA_MEM_CON)>>4)&0x3f); DISP_DBG("rdma_get_info:w %d,h %d, bpp %d,addr %lx\n", p->src_w, p->src_h, p->bpp, p->addr); return ; }
int RDMAConfig(unsigned idx, enum RDMA_MODE mode, enum RDMA_INPUT_FORMAT inputFormat, unsigned address, enum RDMA_OUTPUT_FORMAT outputFormat, unsigned pitch, unsigned width, unsigned height, BOOL isByteSwap, // input setting BOOL isRGBSwap) // ourput setting { ASSERT(idx <= 2); ASSERT((width <= RDMA_MAX_WIDTH) && (height <= RDMA_MAX_HEIGHT)); unsigned bpp; switch(inputFormat) { case RDMA_INPUT_FORMAT_YUYV: case RDMA_INPUT_FORMAT_UYVY: case RDMA_INPUT_FORMAT_YVYU: case RDMA_INPUT_FORMAT_VYUY: case RDMA_INPUT_FORMAT_RGB565: bpp = 2; break; case RDMA_INPUT_FORMAT_RGB888: bpp = 3; break; case RDMA_INPUT_FORMAT_ARGB: bpp = 4; break; default: ASSERT(0); } printf("RDMA: w=%d, h=%d, pitch=%d, mode=%d \n", width, height, width*bpp, mode); DISP_REG_SET_FIELD(GLOBAL_CON_FLD_MODE_SEL, DISP_REG_RDMA_GLOBAL_CON, mode); DISP_REG_SET_FIELD(MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, DISP_REG_RDMA_MEM_CON, inputFormat); DISP_REG_SET(DISP_REG_RDMA_MEM_START_ADDR, address); DISP_REG_SET(DISP_REG_RDMA_MEM_SRC_PITCH, pitch); DISP_REG_SET_FIELD(SIZE_CON_0_FLD_INPUT_BYTE_SWAP, DISP_REG_RDMA_SIZE_CON_0, isByteSwap); DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, DISP_REG_RDMA_SIZE_CON_0, width); DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_RGB_SWAP, DISP_REG_RDMA_SIZE_CON_0, isRGBSwap); DISP_REG_SET_FIELD(SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, DISP_REG_RDMA_SIZE_CON_1, height); printf("RDMA Config = 0x%08X, 0x%08X\n", DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0), DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1)); return 0; }
int disp_bls_set_backlight(unsigned int level) { unsigned int regVal; unsigned int mapped_level; BLS_MSG("disp_bls_set_backlight: %d, gBLSPowerOn = %d\n", level, gBLSPowerOn); mutex_lock(&backlight_mutex); // if (level && (!clock_is_on(MT_CG_DISP0_MDP_BLS_26M) || !gBLSPowerOn)) // { // disp_bls_config(); // } #ifdef USE_DISP_BLS_MUTEX disp_bls_get_mutex(); #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x3); #endif mapped_level = brightness_mapping(level); BLS_MSG("after mapping, mapped_level: %d\n", mapped_level); DISP_REG_SET(DISP_REG_BLS_PWM_DUTY, mapped_level); if(level != 0) { regVal = DISP_REG_GET(DISP_REG_BLS_EN); if (!(regVal & 0x10000)) DISP_REG_SET(DISP_REG_BLS_EN, regVal | 0x10000); } else { regVal = DISP_REG_GET(DISP_REG_BLS_EN); if (regVal & 0x10000) DISP_REG_SET(DISP_REG_BLS_EN, regVal & 0xFFFEFFFF); } BLS_MSG("after SET, PWM_DUTY: %d\n", DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); #ifdef USE_DISP_BLS_MUTEX disp_bls_release_mutex(); #else DISP_REG_SET(DISP_REG_BLS_DEBUG, 0x0); #endif // if (!level && (clock_is_on(MT_CG_DISP0_MDP_BLS_26M) && gBLSPowerOn)) // { // BLS_MSG("disp_bls_set_backlight: disable clock\n"); // disable_clock(MT_CG_DISP0_MDP_BLS_26M , "DDP"); // disable_clock(MT_CG_DISP0_SMI_LARB0 , "DDP"); // gBLSPowerOn = 0; // } mutex_unlock(&backlight_mutex); return 0; }
void disp_aal_on_end_of_frame(void) { #ifdef CONFIG_MTK_AAL_SUPPORT unsigned int intsta; int i; unsigned long flags; intsta = DISP_REG_GET(DISP_AAL_INTSTA); AAL_DBG("disp_aal_on_end_of_frame: intsta: 0x%x", intsta); if (intsta & 0x2) { /* End of frame */ if (spin_trylock_irqsave(&g_aal_hist_lock, flags)) { DISP_CPU_REG_SET(DISP_AAL_INTSTA, (intsta & ~0x3)); for (i = 0; i < AAL_HIST_BIN; i++) { g_aal_hist.maxHist[i] = DISP_REG_GET(DISP_AAL_STATUS_00 + (i << 2)); } g_aal_hist_available = 1; /* Allow to disable interrupt */ g_aal_dirty_frame_retrieved = 1; spin_unlock_irqrestore(&g_aal_hist_lock, flags); if (!g_aal_is_init_regs_valid) { /* * AAL service is not running, not need per-frame wakeup. * We stop interrupt until next frame dirty. */ disp_aal_set_interrupt(0); } wake_up_interruptible(&g_aal_hist_wq); } else { /* * Histogram was not be retrieved, but it's OK. * Another interrupt will come until histogram available * See: disp_aal_set_interrupt() */ } } #else /* * We will not wake up AAL unless signals */ #endif }
void OVLClockOn(DISP_MODULE_ENUM module,void * handle) { int idx = ovl_index(module); ddp_enable_module_clock(module); DDPMSG("OVL%dClockOn CG 0x%x \n",idx, DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0)); return; }
void WDMAWait(unsigned idx) { // polling interrupt status while((DISP_REG_GET(DISP_REG_WDMA_INTSTA) & 0x1) != 0x1) ; DISP_REG_SET(DISP_REG_WDMA_INTSTA , 0x0); }
static void ovl_store_regs(DISP_MODULE_ENUM module) { int i = 0; int idx = ovl_index(module); unsigned int idx_offset = idx*DISP_OVL_INDEX_OFFSET; #if 0 static const unsigned long regs[] = { DISP_REG_OVL_ROI_SIZE, DISP_REG_OVL_ROI_BGCLR, }; #else static unsigned long regs[3]; regs[0] = DISP_REG_OVL_ROI_SIZE + idx_offset; regs[1] = DISP_REG_OVL_ROI_BGCLR + idx_offset; regs[2] = DISP_REG_OVL_DATAPATH_CON + idx_offset; #endif reg_back_cnt[idx] = sizeof(regs)/sizeof(unsigned long); ASSERT(reg_back_cnt[idx] <= OVL_REG_BACK_MAX); for (i = 0; i < reg_back_cnt[idx]; i++) { reg_back[idx][i].address = regs[i]; reg_back[idx][i].value = DISP_REG_GET(regs[i]); } DDPMSG("store %d cnt registers on ovl %d\n", reg_back_cnt[idx], idx); }
int disp_path_config_layer_addr(unsigned int layer, unsigned int addr) { unsigned int reg_addr; printf("[DDP]disp_path_config_layer_addr(), layer=%d, addr=0x%x\n ", layer, addr); // disp_path_get_mutex(); switch(layer) { case 0: DISP_REG_SET(DISP_REG_OVL_L0_ADDR, addr); reg_addr = DISP_REG_OVL_L0_ADDR; break; case 1: DISP_REG_SET(DISP_REG_OVL_L1_ADDR, addr); reg_addr = DISP_REG_OVL_L1_ADDR; break; case 2: DISP_REG_SET(DISP_REG_OVL_L2_ADDR, addr); reg_addr = DISP_REG_OVL_L2_ADDR; break; case 3: DISP_REG_SET(DISP_REG_OVL_L3_ADDR, addr); reg_addr = DISP_REG_OVL_L3_ADDR; break; default: printf("[DDP] error! error: unknow layer=%d \n", layer); } printf("[DDP]disp_path_config_layer_addr() done, addr=0x%x \n", DISP_REG_GET(reg_addr)); // disp_path_release_mutex(); return 0; }
void disp_bls_init(unsigned int srcWidth, unsigned int srcHeight) { DISP_MSG("disp_bls_init : srcWidth = %d, srcHeight = %d\n", srcWidth, srcHeight); // TODO: fix register setting DISP_REG_SET(DISP_REG_BLS_SRC_SIZE, (srcHeight << 16) | srcWidth); DISP_REG_SET(DISP_REG_BLS_PWM_DUTY, DISP_REG_GET(DISP_REG_BLS_PWM_DUTY)); DISP_REG_SET(DISP_REG_BLS_PWM_CON, 0x0); DISP_REG_SET(DISP_REG_BLS_INTEN, 0xF); disp_bls_update_gamma_lut(); //disp_bls_update_pwm_lut(); // not used in 6572 #if 0 // TODO: fix Dither setting // Dithering DISP_REG_SET(DISP_REG_BLS_DITHER(0), 0x00000001); DISP_REG_SET(DISP_REG_BLS_DITHER(6), 0x00000000); DISP_REG_SET(DISP_REG_BLS_DITHER(13), 0x00000222); DISP_REG_SET(DISP_REG_BLS_DITHER(14), 0x00000000); DISP_REG_SET(DISP_REG_BLS_DITHER(15), 0x22220001); DISP_REG_SET(DISP_REG_BLS_DITHER(16), 0x22222222); DISP_REG_SET(DISP_REG_BLS_DITHER(17), 0x00000000); #endif DISP_REG_SET(DISP_REG_BLS_EN, 0x00010001); // enable BLS_EN disp_bls_config_full(srcWidth, srcHeight); #if 0 disp_dump_reg(DISP_MODULE_BLS); #endif }