From: zwl Date: Wed, 12 Mar 2014 13:27:17 +0000 (+0800) Subject: HDMI: modify code about reading EDID and add HDCP register define at rk3288 hdmi... X-Git-Tag: firefly_0821_release~6119 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=eafd5f9be3552bec28157705e2af5acd5146b776;p=firefly-linux-kernel-4.4.55.git HDMI: modify code about reading EDID and add HDCP register define at rk3288 hdmi driver --- diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/Makefile b/drivers/video/rockchip/hdmi/chips/rk3288/Makefile index d93b6f036c22..4216e35e66f6 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/Makefile +++ b/drivers/video/rockchip/hdmi/chips/rk3288/Makefile @@ -5,4 +5,4 @@ ccflags-$(CONFIG_RK_HDMI_DEBUG) = -DDEBUG -DHDMI_DEBUG obj-y += rk3288_hdmi_hw.o rk3288_hdmi.o -obj-$(CONFIG_HDCP_RK3288) += hdcp/ +#obj-$(CONFIG_HDCP_RK3288) += hdcp/ diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c index 30f843829368..9a06d51e625f 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.c @@ -120,6 +120,27 @@ static const struct file_operations rk3288_hdmi_reg_fops = { }; #endif + +struct hdmi* rk3288_hdmi_register_hdcp_callbacks( + void (*hdcp_cb)(void), + void (*hdcp_irq_cb)(int status), + int (*hdcp_power_on_cb)(void), + void (*hdcp_power_off_cb)(void)) +{ + struct hdmi *hdmi_drv = NULL; + + if(hdmi_dev == NULL) + return NULL; + + hdmi_drv = &hdmi_dev->driver; + hdmi_drv->hdcp_cb = hdcp_cb; + hdmi_drv->hdcp_irq_cb = hdcp_irq_cb; + hdmi_drv->hdcp_power_on_cb = hdcp_power_on_cb; + hdmi_drv->hdcp_power_off_cb = hdcp_power_off_cb; + + return hdmi_drv; +} + static int rk3288_hdmi_drv_init(struct hdmi *hdmi_drv) { int ret = 0; diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.h index 1ba67a2136fe..9b332f8cdacb 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.h +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi.h @@ -7,5 +7,11 @@ #define ENABLE 16 #define HDMI_SEL_LCDC(x) ((((x)&1)<<4)|(1<<(4+ENABLE))) +extern struct hdmi* rk3288_hdmi_register_hdcp_callbacks( + void (*hdcp_cb)(void), + void (*hdcp_irq_cb)(int status), + int (*hdcp_power_on_cb)(void), + void (*hdcp_power_off_cb)(void)); + #endif /* __RK3288_HDMI_H__ */ diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c index 5d2aabaa3657..0ed901065522 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c @@ -79,7 +79,8 @@ int rk3288_hdmi_detect_hotplug(struct hdmi *hdmi_drv) int rk3288_hdmi_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff) { - int i = 0,index = 0,interrupt = 0,ret = -1,trytime = 2; + int i = 0, n = 0, index = 0, interrupt = 0, ret = -1, trytime = 2; + int offset = (block%2)*0x80; unsigned long flags; struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver); @@ -94,57 +95,65 @@ int rk3288_hdmi_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff) hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE, v_I2CM_FAST_STD_MODE(STANDARD_MODE)); //Set Standard Mode //Enable edid interrupt - hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, v_SCDC_READREQ_MUTE(0) | v_I2CM_DONE_MUTE(0) | v_I2CM_ERR_MUTE(0)); + //hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, v_SCDC_READREQ_MUTE(0) | v_I2CM_DONE_MUTE(0) | v_I2CM_ERR_MUTE(0)); - //hdmi_writel(hdmi_dev, I2CM_SLAVE,); //TODO Daisen wait to add!! + hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR); + hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR); while(trytime--) { - // Config EDID block and segment addr - hdmi_writel(hdmi_dev, I2CM_SEGADDR, (block%2) * 0x80); - hdmi_writel(hdmi_dev, I2CM_SEGPTR, block/2); - //enable Extended sequential read operation - hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD8_EXT, v_I2CM_RD8_EXT(1)); + for(n = 0; n < HDMI_EDID_BLOCK_SIZE/8; n++) { + // Config EDID block and segment addr + hdmi_writel(hdmi_dev, I2CM_SEGPTR, block/2); + hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8*n); + //enable extend sequential read operation + hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD8_EXT, v_I2CM_RD8_EXT(1)); + + i = 200; + while(i--) + { + spin_lock_irqsave(&hdmi_drv->irq_lock, flags); + interrupt = hdmi_dev->edid_status; + hdmi_dev->edid_status = 0; + spin_unlock_irqrestore(&hdmi_drv->irq_lock, flags); + if(interrupt & (m_SCDC_READREQ | m_I2CM_DONE | m_I2CM_ERROR)) + break; + msleep(5); + } - i = 100; - while(i--) - { - spin_lock_irqsave(&hdmi_drv->irq_lock, flags); - interrupt = hdmi_dev->edid_status; - hdmi_dev->edid_status = 0; - spin_unlock_irqrestore(&hdmi_drv->irq_lock, flags); - if(interrupt & (m_SCDC_READREQ | m_I2CM_DONE | m_I2CM_ERROR)) + 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; - msleep(10); - } - - if(interrupt & (m_SCDC_READREQ | m_I2CM_DONE)) { - for(i = 0; i < HDMI_EDID_BLOCK_SIZE/8; i++) { - for(index = 0; index < 8; index++) - buff[i] = hdmi_readl(hdmi_dev, I2CM_READ_BUFF0 + index); } - 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"); + if(interrupt & (m_SCDC_READREQ | m_I2CM_DONE)) { + for(index = 0; index < 8; index++) { + buff[8*n + index] = hdmi_readl(hdmi_dev, I2CM_READ_BUFF0 + index); + } + continue; + + 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; + } } -#endif - break; - } - - if(interrupt & m_I2CM_ERROR) { - hdmi_err(hdmi_drv->dev, "[%s] edid read error\n", __FUNCTION__); - rk3288_hdmi_i2cm_reset(hdmi_dev); } hdmi_dbg(hdmi_drv->dev, "[%s] edid try times %d\n", __FUNCTION__, trytime); msleep(100); } +exit: // Disable edid interrupt - hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, v_SCDC_READREQ_MUTE(1) | v_I2CM_DONE_MUTE(1) | v_I2CM_ERR_MUTE(1)); //TODO Daisen HDCP enable it?? + //hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, v_SCDC_READREQ_MUTE(1) | v_I2CM_DONE_MUTE(1) | v_I2CM_ERR_MUTE(1)); return ret; } diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h index c1b38c2623fc..4742d1ec61dd 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h @@ -10,9 +10,25 @@ enum { OUTPUT_DVI = 0, OUTPUT_HDMI, }; +enum{ + INPUT_IIS, + INPUT_SPDIF +}; + +/* Color Space Convertion Mode */ +enum { + CSC_RGB_0_255_TO_ITU601_16_235 = 0, //RGB 0-255 input to YCbCr 16-235 output according BT601 + CSC_RGB_0_255_TO_ITU709_16_235, //RGB 0-255 input to YCbCr 16-235 output accroding BT709 + CSC_ITU601_16_235_TO_RGB_16_235, //YCbCr 16-235 input to RGB 16-235 output according BT601 + CSC_ITU709_16_235_TO_RGB_16_235, //YCbCr 16-235 input to RGB 16-235 output according BT709 + CSC_ITU601_16_235_TO_RGB_0_255, //YCbCr 16-235 input to RGB 0-255 output according BT601 + CSC_ITU709_16_235_TO_RGB_0_255 //YCbCr 16-235 input to RGB 0-255 output according BT709 +}; -#define HDMI_SCL_RATE (100*1000) +#define HDMI_SCL_RATE (100*1000) +#define DDC_I2C_EDID_ADDR 0x50 // 0xA0/2 = 0x50 +#define DDC_I2C_SEG_ADDR 0x30 // 0x60/2 = 0x30 /*Register and Field Descriptions*/ /*Identification Registers*/ @@ -994,19 +1010,96 @@ enum { #define HDCP_ENCRYPTION_ENGINE_BASE 0x5000 #define A_HDCPCFG0 0x5000 +#define m_HDCP_ENHANCE_LIKE (1 << 7) +#define v_HDCP_ENHANCE_LIKE(n) (((n)&0x01) << 7) +#define m_I2C_FAST_MODE (1 << 6) +#define v_I2C_FAST_MODE(n) (((n)&0x01) << 6) +#define m_ENCRYPT_BYPASS (1 << 5) +#define v_ENCRYPT_BYPASS(n) (((n)&0x01) << 5) +#define m_SYNC_RI_CHECK (1 << 4) +#define v_SYNC_RI_CHECK(n) (((n)&0x01) << 4) +#define m_AVMUTE (1 << 3) +#define m_RX_DETECT (1 << 2) +#define v_RX_DETECT(n) (((n)&0x01) << 2) +#define m_FEATURE11_EN (1 << 1) +#define v_FEATURE11_EN(n) (((n)&0x01) << 1) +#define m_HDMI_DVI (1 << 0) +#define v_HDMI_DVI(n) (((n)&0x01) << 0) + #define A_HDCPCFG1 0x5001 +#define m_HDCP_LOCK (1 << 4) +#define v_HDCP_LOCK(n) (((n)&0x01) << 4) +#define m_SHA1_CHECK_DISABLE (1 << 3) +#define v_SHA1_CHECK_DISBALE(n) (((n)&0x01) << 3) +#define m_PH2UPSHFTENC (1 << 2) +#define v_PH2UPSHFTENC(n) (((n)&0x01) << 2) +#define m_ENCRYPT_DISBALE (1 << 1) +#define v_ENCRYPT_DISBALE(n) (((n)&0x01) << 1) +#define m_HDCP_SW_RST (1 << 0) +#define v_HDCP_SW_RST(n) (((n)&0x01) << 0) + #define A_HDCPOBS0 0x5002 +#define m_STATE_AUTH (0x0f << 4) +#define m_SUB_STATE_AUTH (0x07 << 1) +#define m_STATE_HDCP_ENGAGED (1 << 0) + #define A_HDCPOBS1 0x5003 +#define m_STATE_OESS (0x07 << 3) +#define m_STATE_REVO (0x07 << 0) + #define A_HDCPOBS2 0x5004 +#define m_STATE_CIPHER (0x07 << 3) +#define m_STATE_EESS (0x07 << 0) + #define A_HDCPOBS3 0x5005 +#define m_BCAP_REPEATER (1 << 6) +#define m_BCAP_KSVFIFO_READY (1 << 5) +#define m_BCAP_FAST_I2C (1 << 4) +#define m_BCAP_HDMI_MODE (1 << 2) +#define m_BCAP_FEATURES11 (1 << 1) +#define m_BCAP_FAST_REAUTH (1 << 0) + #define A_APIINTCLR 0x5006 #define A_APIINTSTAT 0x5007 #define A_APIINTMSK 0x5008 +#define m_HDCP_ENGAGED (1 << 7) +#define m_HDCP_FAILED (1 << 6) +#define m_HDCP_I2C_NOACK (1 << 4) +#define m_HDCP_LOST_ARBI (1 << 3) +#define m_KEEP_ERR_INT (1 << 2) +#define m_KSVSHA1_CALC_INT (1 << 1) +#define m_KSV_ACCESS_INT (1 << 0) +#define v_HDCP_ENGAGED(n) (((n)&0x01) << 7) +#define v_HDCP_FAILED(n) (((n)&0x01) << 6) +#define v_HDCP_I2C_NOACK(n) (((n)&0x01) << 4) +#define v_HDCP_LOST_ARBI(n) (((n)&0x01) << 3) +#define v_KEEP_ERR_INT(n) (((n)&0x01) << 1) +#define v_KSVSHA1_CALC_INT(n) (((n)&0x01) << 1) +#define v_KSV_ACCESS_INT(n) (((n)&0x01) << 0) + #define A_VIDPOLCFG 0x5009 +#define m_UNENCRYT_CONF (0x03 << 5) +#define v_UNENCRYT_CONF(n) (((n)&0x03) << 5) +#define m_DATAEN_POL (1 << 4) +#define v_DATAEN_POL(n) (((n)&0x01) << 4) +#define m_VSYNC_POL (1 << 3) +#define v_VSYNC_POL(n) (((n)&0x01) << 3) +#define m_HSYNC_POL (1 << 1) +#define v_HSYNC_POL(n) (((n)&0x01) << 1) + #define A_OESSWCFG 0x500a #define A_COREVERLSB 0x5014 #define A_COREVERMSB 0x5015 + #define A_KSVMEMCTRL 0x5016 +#define m_SHA1_FAIL (1 << 3) +#define v_SHA1_FAIL(n) (((n)&0x01) << 3) +#define m_KSV_UPDATE (1 << 2) +#define v_KSV_UPDATE(n) (((n)&0x01) << 2) +#define m_KSV_MEM_ACCESS (1 << 1) +#define m_KSV_MEM_REQ (1 << 0) +#define v_KSV_MEM_REQ(n) (((n)&0x01) << 0) + #define HDCP_BSTATUS_0 0x5020 #define HDCP_BSTATUS_1 0x5021 #define HDCP_M0_0 0x5022 @@ -1038,6 +1131,9 @@ enum { #define HDCP_AN_BASE 0x7805 #define HDCPREG_ANCONF 0x7805 +#define m_OAN_BYPASS (1 << 0) +#define v_OAN_BYPASS(n) (((n)&0x01) << 0) + #define HDCPREG_AN0 0x7806 #define HDCPREG_AN1 0x7807 #define HDCPREG_AN2 0x7808 @@ -1052,7 +1148,13 @@ enum { #define ENCRYPTED_DPK_EMBEDDED_BASE 0x780e #define HDCPREG_RMCTL 0x780e +#define m_DPK_DECRYPT_EN (1 << 0) +#define v_DPK_DECRYPT_EN(n) (((n)&0x01) <<0) + #define HDCPREG_RMSTS 0x780f +#define m_DPK_WR_OK_STS (1 << 6) +#define m_DPK_DATA_INDEX (0x3f << 6) + #define HDCPREG_SEED0 0x7810 #define HDCPREG_SEED1 0x7811 #define HDCPREG_DPK0 0x7812 @@ -1235,21 +1337,6 @@ struct phy_mpll_config_tab { -enum{ - INPUT_IIS, - INPUT_SPDIF -}; - -/* Color Space Convertion Mode */ -enum { - CSC_RGB_0_255_TO_ITU601_16_235 = 0, //RGB 0-255 input to YCbCr 16-235 output according BT601 - CSC_RGB_0_255_TO_ITU709_16_235, //RGB 0-255 input to YCbCr 16-235 output accroding BT709 - CSC_ITU601_16_235_TO_RGB_16_235, //YCbCr 16-235 input to RGB 16-235 output according BT601 - CSC_ITU709_16_235_TO_RGB_16_235, //YCbCr 16-235 input to RGB 16-235 output according BT709 - CSC_ITU601_16_235_TO_RGB_0_255, //YCbCr 16-235 input to RGB 0-255 output according BT601 - CSC_ITU709_16_235_TO_RGB_0_255 //YCbCr 16-235 input to RGB 0-255 output according BT709 -}; - struct rk3288_hdmi_reg_table { int reg_base; int reg_end;