示例#1
0
void rk616_set_colorbar(int enable)
{
        static int display_mask = 0;
        int reg_value;
        if (enable) {
                if (!display_mask) {
                        if (hdmi->tmdsclk <= (HDMI_SYS_FREG_CLK << 2)) {
	                        hdmi_readl(SYS_CTRL, &reg_value);
                                hdmi_msk_reg(SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);  
        	                hdmi_writel(HDMI_COLORBAR, 0x00);
                                hdmi_writel(SYS_CTRL, reg_value);
                        } else {
        	                hdmi_writel(HDMI_COLORBAR, 0x00);
                        }

                        display_mask = 1;
                }
        } else {
                if (display_mask) {

                        if (hdmi->tmdsclk <= (HDMI_SYS_FREG_CLK << 2)) {
	                        hdmi_readl(SYS_CTRL, &reg_value);
                                hdmi_msk_reg(SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);  
                                hdmi_writel(HDMI_COLORBAR, 0x10);
                                hdmi_writel(SYS_CTRL, reg_value);
                        } else {
                                hdmi_writel(HDMI_COLORBAR, 0x10);
                        }

                        display_mask = 0;
                }
        }
}
int rk3036_hdcp_start_authentication(void)
{
	int temp;
	int retry = 0;
	int tmds_clk;

	tmds_clk = hdmi_dev->driver.tmdsclk;
	if (hdcp->keys == NULL) {
		HDCP_WARN("HDCP: key is not loaded\n");
		return HDCP_KEY_ERR;
	}
	if (rk3036_hdcp_key_check(hdcp->keys) == HDCP_KEY_INVALID) {
		HDCP_WARN("loaded HDCP key is incorrect\n");
		return HDCP_KEY_ERR;
	}
	if (tmds_clk > (HDMI_SYS_FREG_CLK << 2)) {
		/*Select TMDS CLK to configure regs*/
		hdmi_msk_reg(hdmi_dev, SYS_CTRL,
			     m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
	} else {
		hdmi_msk_reg(hdmi_dev, SYS_CTRL,
			     m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
	}
	hdmi_writel(hdmi_dev, HDCP_TIMER_100MS, 0x28);
	hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp);
	while ((temp & m_KEY_READY) == 0) {
		if (retry > 1000) {
			HDCP_WARN("HDCP: loaded key error\n");
			return HDCP_KEY_ERR;
		}
		rk3036_hdcp_load_key2mem(hdcp->keys);
		msleep(1);
		hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp);
		retry++;
	}
	/*Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)*/
	retry = hdmi_dev->hclk_rate/(HDCP_DDC_CLK << 2);
	hdmi_writel(hdmi_dev, DDC_CLK_L, retry & 0xFF);
	hdmi_writel(hdmi_dev, DDC_CLK_H, (retry >> 8) & 0xFF);
	hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x67);
	/*Enable interrupt*/
	hdmi_writel(hdmi_dev, HDCP_INT_MASK1,
		    m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE |
		    m_INT_AUTH_SUCCESS | m_INT_AUTH_READY);
	hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x00);
	/*Start authentication*/
	hdmi_msk_reg(hdmi_dev, HDCP_CTRL1,
		     m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE |
		     m_AUTH_STOP | m_HDCP_RESET,
		     v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) |
		     v_ADVANED_ENABLE(0) | v_AUTH_STOP(0) | v_HDCP_RESET(0));

	if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
		hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE,
			     v_REG_CLK_SOURCE_TMDS);
	}
	return HDCP_OK;
}
static void rk3288_hdmi_av_mute(struct hdmi *hdmi_drv, int enable)
{
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);

	hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE, v_FC_SET_AVMUTE(enable));
#if 0
	/* audio mute priority: AVMUTE, sample flat, validity */
	/* AVMUTE also mutes video */
	value = enable ? 0xF : 0;
	hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, m_AUD_PACK_SAMPFIT, v_AUD_PACK_SAMPFIT(value));
#endif
}
示例#4
0
int	rk616_hdcp_start_authentication(void)
{
	int temp;
	int retry = 0;

	if(hdcp->keys == NULL) {
		printk(KERN_ERR "HDCP: key is not loaded\n");
		return HDCP_KEY_ERR;
	}
	
	if(rk616_hdcp_key_check(hdcp->keys) == HDCP_KEY_INVALID){
		printk(KERN_ERR "loaded HDCP key is incorrect\n");
		return HDCP_KEY_ERR;
	}	

        if (hdmi->tmdsclk > (HDMI_SYS_FREG_CLK << 2)) {
        	// Select TMDS CLK to configure regs
	        hdmi_msk_reg(SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
        }

	hdmi_readl(HDCP_KEY_STATUS,&temp);
	while( ( temp & m_KEY_READY) == 0 ) {
		if(retry > 1000) {
			printk(KERN_ERR "HDCP: loaded key error\n");
			return HDCP_KEY_ERR;
		}
		rk616_hdcp_load_key2mem(hdcp->keys);
		msleep(1);
		hdmi_readl(HDCP_KEY_STATUS,&temp);
                retry++;
	}
        
        // Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)
        retry = hdmi->tmdsclk/(HDCP_DDC_CLK << 2);
        hdmi_writel(DDC_CLK_L, retry & 0xFF);
        hdmi_writel(DDC_CLK_H, (retry >> 8) & 0xFF);
 
	hdmi_writel(HDCP_CTRL2, 0x77);
	
	//Enable interrupt
	hdmi_writel(HDCP_INT_MASK1, m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE | m_INT_AUTH_SUCCESS | m_INT_AUTH_READY);
	 hdmi_writel(HDCP_INT_MASK2, 0x00);

	//Start authentication
	hdmi_msk_reg(HDCP_CTRL1, m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE, v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) | v_ADVANED_ENABLE(0));
	

        if (hdmi->tmdsclk <= (HDMI_SYS_FREG_CLK << 2)) {
                hdmi_msk_reg(SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
        }
	return HDCP_OK;
}
示例#5
0
void rk616_hdcp_disable(void)
{
	// Diable HDCP Interrupt
	hdmi_writel(HDCP_INT_MASK1, 0x00);
	// Stop and Reset HDCP
	hdmi_msk_reg(HDCP_CTRL1, m_ENCRYPT_ENABLE | m_AUTH_STOP | m_HDCP_RESET, 
		v_ENCRYPT_ENABLE(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1) );
}
示例#6
0
int	rk616_hdcp_stop_authentication(void)
{
        hdmi_msk_reg(SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);  
        hdmi_writel(DDC_CLK_L, 0x1c);
	hdmi_writel(DDC_CLK_H, 0x00);
	hdmi_writel(HDCP_CTRL2, 0x08);
	hdmi_writel(HDCP_INT_MASK2, 0x06);
	hdmi_writel(HDCP_CTRL1, 0x02);
        return 0;
	//hdmi_writel(HDCP_CTRL1, 0x0a);
}
static int rk3288_hdmi_video_forceOutput(struct hdmi *hdmi_drv, char enable)
{
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);

	hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEAUDIO, v_FC_FORCEAUDIO(0));

	if(enable) {	/*Force output Blue*/
		hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00);	/*R*/
		hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00);	/*G*/
		hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0xff);	/*B*/
		hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
	}
	else {
		hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(0));
		hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00);	/*R*/
		hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00);	/*G*/
		hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00);	/*B*/
	}

	return 0;
}
示例#8
0
int	rk616_hdcp_check_bksv(void)
{
	int i, j;
	int temp = 0, bksv[5];
	char *invalidkey;
	
	for(i = 0; i < 5; i++) {
		hdmi_readl(HDCP_KSV_BYTE0 + (4 - i), &temp);
		bksv[i] = temp & 0xFF;
	}
	DBG("bksv is 0x%02x%02x%02x%02x%02x", bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]);
	
	temp = 0; 	
	for (i = 0; i < 5; i++)
	{
    	for (j = 0; j < 8; j++)
    	{
    		if (bksv[i] & 0x01)
    		{
        		temp++;
    		}
    		bksv[i] >>= 1;
    	}
 	}
 	if (temp != 20)
    	return HDCP_KSV_ERR;
	
	for(i = 0; i < hdcp->invalidkey; i++)
	{
		invalidkey = hdcp->invalidkeys + i *5;
		if(memcmp(bksv, invalidkey, 5) == 0) {
			printk(KERN_ERR "HDCP: BKSV was revocated!!!\n");
			hdmi_msk_reg(HDCP_CTRL1, m_BKSV_INVALID | m_ENCRYPT_ENABLE, v_BKSV_INVALID(1) | v_ENCRYPT_ENABLE(1));
			return HDCP_KSV_ERR;
		}
	}
	hdmi_msk_reg(HDCP_CTRL1, m_BKSV_VALID | m_ENCRYPT_ENABLE, v_BKSV_VALID(1) | v_ENCRYPT_ENABLE(1));
	return HDCP_OK;
}
void rk3036_hdcp_disable(void)
{
	int reg_value;
	int tmds_clk;

	tmds_clk = hdmi_dev->driver.tmdsclk;
	if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
		hdmi_readl(hdmi_dev, SYS_CTRL, &reg_value);
		hdmi_msk_reg(hdmi_dev, SYS_CTRL,
			     m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
	}

	/* Diable HDCP Interrupt*/
	hdmi_writel(hdmi_dev, HDCP_INT_MASK1, 0x00);
	/* Stop and Reset HDCP*/
	hdmi_msk_reg(hdmi_dev, HDCP_CTRL1,
		     m_AUTH_START | m_AUTH_STOP | m_HDCP_RESET,
		     v_AUTH_START(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1));

	if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
		hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
}
void rk3036_hdcp_interrupt(char *status1, char *status2)
{
	int interrupt1 = 0;
	int interrupt2 = 0;
	int temp = 0;
	int tmds_clk;

	tmds_clk = hdmi_dev->driver.tmdsclk;
	hdmi_readl(hdmi_dev, HDCP_INT_STATUS1, &interrupt1);
	hdmi_readl(hdmi_dev, HDCP_INT_STATUS2, &interrupt2);

	if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
		hdmi_msk_reg(hdmi_dev, SYS_CTRL,
			     m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);

	if (interrupt1) {
		hdmi_writel(hdmi_dev, HDCP_INT_STATUS1, interrupt1);
		if (interrupt1 & m_INT_HDCP_ERR) {
			hdmi_readl(hdmi_dev, HDCP_ERROR, &temp);
			HDCP_WARN("HDCP: Error reg 0x65 = 0x%02x\n", temp);
			rk3036_hdcp_error(temp);
			hdmi_writel(hdmi_dev, HDCP_ERROR, temp);
		}
	}
	if (interrupt2)
		hdmi_writel(hdmi_dev, HDCP_INT_STATUS2, interrupt2);

	*status1 = interrupt1;
	*status2 = interrupt2;

	if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
		hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE,
			     v_REG_CLK_SOURCE_TMDS);
/*
	hdmi_readl(HDCP_ERROR, &temp);
	DBG("HDCP: Error reg 0x65 = 0x%02x\n", temp);
*/
}
void rk3036_set_colorbar(int enable)
{
	static int display_mask;
	int reg_value;
	int tmds_clk;

	tmds_clk = hdmi_dev->driver.tmdsclk;
	if (enable) {
		if (!display_mask) {
			if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
				hdmi_readl(hdmi_dev, SYS_CTRL, &reg_value);
				hdmi_msk_reg(hdmi_dev, SYS_CTRL,
					     m_REG_CLK_SOURCE,
					     v_REG_CLK_SOURCE_SYS);
				hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
				hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
			} else {
				hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
			}
			display_mask = 1;
		}
	} else {
		if (display_mask) {
			if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
				hdmi_readl(hdmi_dev, SYS_CTRL, &reg_value);
				hdmi_msk_reg(hdmi_dev, SYS_CTRL,
					     m_REG_CLK_SOURCE,
					     v_REG_CLK_SOURCE_SYS);
				hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
				hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
			} else {
				hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
			}
			display_mask = 0;
		}
	}
}
示例#12
0
static void rk3288_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
{
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
	if(hdmi_drv->pwr_mode == mode)
		return;

	dev_printk(KERN_INFO, hdmi_drv->dev, "%s change pwr_mode %d --> %d\n", __FUNCTION__, hdmi_drv->pwr_mode, mode);

	switch(mode)
	{
		case NORMAL:
			hdmi_writel(hdmi_dev, MC_CLKDIS, 0x00);
			break;
		case LOWER_PWR:
			//hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE | m_PREPCLK_DISABLE | m_TMDSCLK_DISABLE | m_PIXELCLK_DISABLE,
				//v_AUDCLK_DISABLE(1) | v_PREPCLK_DISABLE(1) | v_TMDSCLK_DISABLE(1) | v_PIXELCLK_DISABLE(1));
			hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_TMDS_EN | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
				v_TMDS_EN(0) | v_TXPWRON_SIG(0) | v_ENHPD_RXSENSE_SIG(1));
			break;
		default:
			hdmi_dbg(hdmi_drv->dev, "unkown hdmi pwr mode %d\n",mode);
	}
	hdmi_drv->pwr_mode = mode;
}
示例#13
0
//i2c master reset
void rk3288_hdmi_i2cm_reset(struct rk3288_hdmi_device *hdmi_dev)
{
	hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ, m_I2CM_SOFTRST, v_I2CM_SOFTRST(0));
	udelay(100);
}
示例#14
0
int rk3288_hdmi_video_sampler(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara)
{
	int map_code = 0;
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);

	if (vpara->input_color == VIDEO_INPUT_COLOR_RGB || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444
							|| vpara->input_color == VIDEO_INPUT_COLOR_YCBCR420) {

		switch (vpara->color_depth) {
		case HDMI_COLOR_DEPTH_8BIT:
			map_code = VIDEO_RGB444_8BIT;
			break;
		case HDMI_COLOR_DEPTH_10BIT:
			map_code = VIDEO_RGB444_10BIT;
			break;
		case HDMI_COLOR_DEPTH_12BIT:
			map_code = VIDEO_RGB444_12BIT;
			break;
		case HDMI_COLOR_DEPTH_16BIT:
			map_code = VIDEO_RGB444_16BIT;
			break;
		default:
			map_code = VIDEO_RGB444_8BIT;
			break;
		}
		map_code += (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) ? 8 : 0;
	} else if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR422) {
		/* YCC422 mapping is discontinued - only map 1 is supported */
		switch (vpara->color_depth) {
		case HDMI_COLOR_DEPTH_8BIT:
			map_code = VIDEO_YCBCR422_8BIT;
			break;
		case HDMI_COLOR_DEPTH_10BIT:
			map_code = VIDEO_YCBCR422_10BIT;
			break;
		case HDMI_COLOR_DEPTH_12BIT:
			map_code = VIDEO_YCBCR422_12BIT;
			break;
		default:
			map_code = VIDEO_YCBCR422_8BIT;
			break;
		}
	} else {
		hdmi_err(hdmi_drv->dev, "invalid input color type: %d", vpara->input_color);
		return -1;
	}

	//Set Data enable signal from external and set video sample input mapping
	hdmi_msk_reg(hdmi_dev, TX_INVID0, m_INTERNAL_DE_GEN | m_VIDEO_MAPPING, v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code));

#if defined(HDMI_VIDEO_STUFFING)
	hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00);
	hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00);
	hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_GYDATA_STUFF, v_GYDATA_STUFF(1));
	hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00);
	hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00);
	hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_RCRDATA_STUFF, v_RCRDATA_STUFF(1));
	hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00);
	hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00);
	hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_BCBDATA_STUFF, v_BCBDATA_STUFF(1));
#endif
	return 0;
}
示例#15
0
static int rk3288_hdmi_video_packetizer(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara)
{
	unsigned char color_depth = 0;
	unsigned char output_select = 0;
	unsigned char remap_size = 0;
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);

	if (vpara->output_color == VIDEO_OUTPUT_RGB444 || vpara->output_color == VIDEO_OUTPUT_YCBCR444
							|| vpara->output_color == VIDEO_OUTPUT_YCBCR420) {

		switch (vpara->color_depth) {
		case HDMI_COLOR_DEPTH_8BIT:
			color_depth = COLOR_DEPTH_24BIT;
			output_select = OUT_FROM_8BIT_BYPASS;
			break;
		case HDMI_COLOR_DEPTH_10BIT:
			color_depth = COLOR_DEPTH_30BIT;
			output_select = OUT_FROM_PIXEL_PACKING;
			break;
		case HDMI_COLOR_DEPTH_12BIT:
			color_depth = COLOR_DEPTH_36BIT;
			output_select = OUT_FROM_PIXEL_PACKING;
			break;
		case HDMI_COLOR_DEPTH_16BIT:
			color_depth = COLOR_DEPTH_48BIT;
			output_select = OUT_FROM_PIXEL_PACKING;
			break;
		default:
			color_depth = COLOR_DEPTH_24BIT;
			output_select = OUT_FROM_8BIT_BYPASS;
			break;
		}

		/*Config Color Depth*/
		hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth));
	} else if (vpara->output_color == VIDEO_OUTPUT_YCBCR422) {

		switch (vpara->color_depth) {
		case HDMI_COLOR_DEPTH_8BIT:
			remap_size = YCC422_16BIT;
			break;
		case HDMI_COLOR_DEPTH_10BIT:
			remap_size = YCC422_20BIT;
			break;
		case HDMI_COLOR_DEPTH_12BIT:
			remap_size = YCC422_24BIT;
			break;
		default:
			remap_size = YCC422_16BIT;
			break;
		}

		output_select = OUT_FROM_YCC422_REMAP;
		/*Config remap size for the different color Depth*/
		hdmi_msk_reg(hdmi_dev, VP_REMAP, m_YCC422_SIZE, v_YCC422_SIZE(remap_size));
	} else {
		hdmi_err(hdmi_drv->dev, "invalid output color type: %d", vpara->output_color);
		return -1;
	}

	/*Config pixel repettion*/
	hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR, v_DESIRED_PR_FACTOR(vpara->pixel_repet));
	if (vpara->pixel_repet > 0)
		hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL, v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0));
	else
		hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL, v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1));

	/*config output select*/
	if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */
		hdmi_msk_reg(hdmi_dev, VP_CONF, m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | m_OUTPUT_SEL,
			v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) | v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
	} else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */
		hdmi_msk_reg(hdmi_dev, VP_CONF, m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | m_OUTPUT_SEL,
			v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) | v_YCC422_EN(1) | v_OUTPUT_SEL(output_select));
	} else if (output_select == OUT_FROM_8BIT_BYPASS || output_select == 3) { /* bypass */
		hdmi_msk_reg(hdmi_dev, VP_CONF, m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN | m_OUTPUT_SEL,
			v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) | v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
	}

#if defined(HDMI_VIDEO_STUFFING)
	/* YCC422 and pixel packing stuffing*/
	hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1));
	hdmi_msk_reg(hdmi_dev, VP_STUFF, m_YCC422_STUFFING | m_PP_STUFFING, v_YCC422_STUFFING(1) | v_PP_STUFFING(1));
#endif
	return 0;
}
示例#16
0
static int rk3288_hdmi_video_frameComposer(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara)	//TODO Daisen wait to add support 3D
{
	int h_act = 0, v_act = 0;
	int h_syncdelay = 0, v_syncdelay = 0;
	int h_sync = 0, v_sync = 0;
	int h_blank = 0, v_blank = 0;
	int vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync;
	int hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync;
	int de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0;
	struct fb_videomode *mode = NULL;
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);

	mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
	if(mode == NULL) {
		hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic);
		return -ENOENT;
	}

	hdmi_drv->pixclock = mode->pixclock;
	switch(vpara->color_depth) {
	case HDMI_COLOR_DEPTH_8BIT:
		hdmi_drv->tmdsclk = mode->pixclock;
		break;
	case HDMI_COLOR_DEPTH_10BIT:
		hdmi_drv->tmdsclk = mode->pixclock * 10 / 8;
		break;
	case HDMI_COLOR_DEPTH_12BIT:
		hdmi_drv->tmdsclk = mode->pixclock * 12 / 8;
		break;
	case HDMI_COLOR_DEPTH_16BIT:
		hdmi_drv->tmdsclk = mode->pixclock * 2;
		break;
	default:
		hdmi_drv->tmdsclk = mode->pixclock;
		break;
	}
	rk3288_hdmi_config_phy(hdmi_drv, vpara->pixel_repet, vpara->color_depth);

	hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_ENCRYPT_BYPASS | m_HDMI_DVI,
		v_ENCRYPT_BYPASS(1) | v_HDMI_DVI(vpara->output_mode));	//cfg to bypass hdcp data encrypt
	hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL | m_FC_HDMI_DVI | m_FC_INTERLACE_MODE,
		v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) | v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->output_mode) | v_FC_INTERLACE_MODE(mode->vmode));
	hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VBLANK, v_FC_VBLANK(mode->vmode));

	h_act = mode->xres;
	hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(h_act >> 8));
	hdmi_writel(hdmi_dev, FC_INHACTIV0, (h_act & 0xff));

	v_act = mode->yres;
	hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(v_act >> 8));
	hdmi_writel(hdmi_dev, FC_INVACTIV0, (v_act & 0xff));

	h_blank = mode->hsync_len + mode->left_margin + mode->right_margin;
	hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(h_blank >> 8));
	hdmi_writel(hdmi_dev, FC_INHBLANK0, (h_blank & 0xff));

	v_blank = mode->vsync_len + mode->upper_margin + mode->lower_margin;
	hdmi_writel(hdmi_dev, FC_INVBLANK, (v_blank & 0xff));

	h_syncdelay = mode->right_margin;
	hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(h_syncdelay >> 8));
	hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (h_syncdelay & 0xff));

	v_syncdelay = mode->lower_margin;
	hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (v_syncdelay & 0xff));

	h_sync = mode->hsync_len;
	hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(h_sync >> 8));
	hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (h_sync & 0xff));

	v_sync = mode->vsync_len;
	hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (v_sync & 0xff));

	/*Set the control period minimum duration(min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)*/
	hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
	hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
#if 0
	if(hdmi_drv->tmdsclk > 340000000) {	//used for HDMI 2.0 TX	//TODO Daisen wait to modify HDCP KEEPOUT
		hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1));
		hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL, m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1));
	}

	/* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
	 * worst case: tmdsClock == 25MHz => config <= 19
	 */
	hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1);

	/*Set PreambleFilter*/
	for (i = 0; i < 3; i++) {
		value = (i + 1) * 11;
		if (i == 0)		/*channel 0*/
			hdmi_writel(hdmi_dev, FC_CH0PREAM, value);
		else if (i == 1)	/*channel 1*/
			hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f);
		else if (i == 2)	/*channel 2*/
			hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f);
	}
#endif
	/*Set PixelRepetition:No pixel repetition*/
	hdmi_writel(hdmi_dev, FC_PRCONF, v_FC_PR_FACTOR(vpara->pixel_repet + 1));

	return 0;
}
示例#17
0
int rk3288_hdmi_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff)
{
	int i = 0, n = 0, index = 0, ret = -1, trytime = 2;
	int offset = (block % 2) * 0x80;
	//int interrupt = 0;
	//unsigned long flags;
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);

	hdmi_dbg(hdmi_drv->dev, "[%s] block %d\n", __FUNCTION__, block);
	//spin_lock_irqsave(&hdmi_drv->irq_lock, flags);
	hdmi_dev->i2cm_int = 0;
	//spin_unlock_irqrestore(&hdmi_drv->irq_lock, flags);

	//Set DDC I2C CLK which devided from DDC_CLK to 100KHz.
	hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR, 0x7a);
	hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR, 0x8d);
	hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE, v_I2CM_FAST_STD_MODE(STANDARD_MODE));	//Set Standard Mode

	//Enable I2C interrupt for reading edid
	hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, v_SCDC_READREQ_MUTE(0) | v_I2CM_DONE_MUTE(0) | v_I2CM_ERR_MUTE(0));
	hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0));
	hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0));

	hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR);
	hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR);
	hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2);
	while(trytime--) {
		for(n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
			hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n);
			//enable extend sequential read operation
			if(block == 0)
				hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD8, v_I2CM_RD8(1));
			else
				hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD8_EXT, v_I2CM_RD8_EXT(1));
#if 0
			i = 200;
			while(i--)
			{
				//spin_lock_irqsave(&hdmi_drv->irq_lock, flags);
				interrupt = hdmi_dev->i2cm_int;
				hdmi_dev->i2cm_int = 0;
				//spin_unlock_irqrestore(&hdmi_drv->irq_lock, flags);
				if(interrupt & (m_SCDC_READREQ | m_I2CM_DONE | m_I2CM_ERROR))
					break;
				msleep(5);
			}

			if((i == 0) || (interrupt & m_I2CM_ERROR)) {
				hdmi_err(hdmi_drv->dev, "[%s] edid read error\n", __FUNCTION__);
				rk3288_hdmi_i2cm_reset(hdmi_dev);
				break;
			}
#endif
			//if(interrupt & m_I2CM_DONE)
			{
				msleep(1);
				for(index = 0; index < 8; index++) {
					buff[8 * n + index] = hdmi_readl(hdmi_dev, I2CM_READ_BUFF0 + index);
				}

				if(n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
					ret = 0;
					hdmi_dbg(hdmi_drv->dev, "[%s] edid read sucess\n", __FUNCTION__);

				#ifdef HDMI_DEBUG
					for(i = 0; i < 128; i++) {
						printk("%02x ,", buff[i]);
						if( (i + 1) % 16 == 0)
							printk("\n");
					}
				#endif
					goto exit;
				}
			}
		}

		hdmi_err(hdmi_drv->dev, "[%s] edid try times %d\n", __FUNCTION__, trytime);
		msleep(100);
	}

exit:
	//Disable I2C interrupt
	hdmi_msk_reg(hdmi_dev, IH_MUTE_I2CM_STAT0, m_I2CM_DONE_MUTE | m_I2CM_ERR_MUTE, v_I2CM_DONE_MUTE(1) | v_I2CM_ERR_MUTE(1));
	hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1));
	hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK, v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1));
	return ret;
}