예제 #1
0
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";
    }
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
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;
	}

}
예제 #5
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;
}
예제 #6
0
파일: ddp_path.c 프로젝트: djun/m463
// 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;
}
예제 #7
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;
}
예제 #8
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;
}
예제 #9
0
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;
}
예제 #10
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;
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
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;
}
예제 #14
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", &reg_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", &reg_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);
}
예제 #15
0
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;

}
예제 #16
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);
}
예제 #17
0
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;
}
예제 #18
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 ;
}
예제 #19
0
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);
}
예제 #20
0
///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;
}
예제 #21
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;
    }

#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;
}
예제 #22
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;
}
예제 #23
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;
}
예제 #24
0
// 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;
}
예제 #25
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;
}
예제 #26
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;
}
예제 #27
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;
					}
				}
			}
		}