rk30 hdmi:
authorZheng Yang <zhengyang@rock-chips.com>
Tue, 12 Jun 2012 10:10:13 +0000 (18:10 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Tue, 12 Jun 2012 10:10:13 +0000 (18:10 +0800)
1. io mux ddc channel to GPIO mode when suspend, and mux again when resume.
2. fix ddc clock frequency error when hdcp is enabled.

drivers/video/rockchip/hdmi/hdcp/rk30_hdcp.c
drivers/video/rockchip/hdmi/hdcp/rk30_hdmi_hdcp.c
drivers/video/rockchip/hdmi/hdcp/rk30_hdmi_hdcp.h
drivers/video/rockchip/hdmi/rk30_hdmi.c
drivers/video/rockchip/hdmi/rk30_hdmi.h
drivers/video/rockchip/hdmi/rk30_hdmi_hw.c
drivers/video/rockchip/hdmi/rk30_hdmi_hw.h

index dbc6b5227b77e085d178aad46c31f8131d1a878b..68d0ac841a67dc6b34fd42f95d6cc85eb0afce8b 100755 (executable)
@@ -304,9 +304,14 @@ static void hdcp_start_frame_cb(void)
  */
 static void hdcp_irq_cb(int interrupt)
 {
+       int value;
        DBG("%s 0x%x", __FUNCTION__, interrupt);
        if(interrupt & m_INT_HDCP_ERR)
        {
+               value = HDMIRdReg(HDCP_ERROR);
+               HDMIWrReg(HDCP_ERROR, value);
+               printk(KERN_INFO "HDCP: Error 0x%02x\n", value);
+               
                if( (hdcp->hdcp_state != HDCP_DISABLED) &&
                        (hdcp->hdcp_state != HDCP_ENABLE_PENDING) )
                {       
index 82ccff1bcb7dd88418525a811d25419d28f18b65..1184989a57b256481cb00088fabfc79483c3e5cb 100755 (executable)
@@ -103,8 +103,10 @@ int rk30_hdcp_start_authentication(void)
                        HDMIWrReg(HDCP_TIMER_5S, 0x2c);
                        break;
        }
-       
-       
+       // Config DDC Clock
+       temp = (hdmi->tmdsclk/HDCP_DDC_CLK)/4;
+       HDMIWrReg(DDC_BUS_FREQ_L, temp & 0xFF);
+       HDMIWrReg(DDC_BUS_FREQ_H, (temp >> 8) & 0xFF);
        // Enable HDCP Interrupt
        HDMIWrReg(INTR_MASK2, m_INT_HDCP_ERR | m_INT_BKSV_RPRDY | m_INT_BKSV_RCRDY | m_INT_AUTH_DONE | m_INT_AUTH_READY);
        // Start HDCP
index 3c085720360b3f23eb5c4ca0f81952bce43df037..0224d88ab134003a904f43f6584e65e538cbfedb 100755 (executable)
@@ -52,6 +52,7 @@ enum hdmi_states {
 
 #define HDCP_PRIVATE_KEY_SIZE  280
 #define HDCP_KEY_SHA_SIZE              20
+#define HDCP_DDC_CLK                   100000
 
 struct hdcp_keys{
        u8 KSV[8];
index 40421c799fd1c15a5c4d1d3df8183a4a2fe75549..0aae519acc9e1edaea91ec3616fa36456944213d 100755 (executable)
@@ -63,6 +63,10 @@ static void hdmi_early_suspend(struct early_suspend *h)
        wait_for_completion_interruptible_timeout(&hdmi->complete,\r
                                                        msecs_to_jiffies(5000));\r
        flush_delayed_work(&hdmi->delay_work);\r
+       // When HDMI 1.1V and 2.5V power off, DDC channel will be pull down, current is produced\r
+       // from VCC_IO which is pull up outside soc. We need to switch DDC IO to GPIO.\r
+       rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_GPIO0A2);\r
+       rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_GPIO0A1);\r
        return;\r
 }\r
 \r
@@ -70,6 +74,10 @@ static void hdmi_early_resume(struct early_suspend *h)
 {\r
        hdmi_dbg(hdmi->dev, "hdmi exit early resume\n");\r
        mutex_lock(&hdmi->enable_mutex);\r
+       \r
+       rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_HDMI_I2C_SDA);\r
+       rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_HDMI_I2C_SCL);\r
+       \r
        hdmi->suspend = 0;\r
        rk30_hdmi_initial();\r
        if(hdmi->enable) {\r
index 45275f39f9a117bd09381412b778cc219d961549..54f5a5c0a6763863287c7e10d455e9671d61be2e 100755 (executable)
@@ -80,7 +80,7 @@ struct hdmi {
        int display;                            // HDMI display status
        int xscale;                                     // x direction scale value
        int yscale;                                     // y directoon scale value
-       
+       int tmdsclk;                            // TDMS Clock frequency
        // call back for hdcp operatoion
        void (*hdcp_cb)(void);
        void (*hdcp_irq_cb)(int);
index 5727174863304d0e78adf3c996d0961261e00ac1..1e4aabcfefa27806360617f8c198cab77d5f3961 100755 (executable)
@@ -81,9 +81,9 @@ int rk30_hdmi_read_edid(int block, unsigned char *buff)
        spin_lock_irqsave(&hdmi->irq_lock, flags);
        edid_result = 0;
        spin_unlock_irqrestore(&hdmi->irq_lock, flags);
-       //Before Phy parameter was set, DDC_CLK is equal to PLLA freq which is 24MHz.
+       //Before Phy parameter was set, DDC_CLK is equal to PLLA freq which is 30MHz.
        //Set DDC I2C CLK which devided from DDC_CLK to 100KHz.
-       ddc_bus_freq = (24000000/HDMI_EDID_DDC_CLK)/4;
+       ddc_bus_freq = (30000000/HDMI_EDID_DDC_CLK)/4;
        HDMIWrReg(DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
        HDMIWrReg(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
        
@@ -375,6 +375,7 @@ int rk30_hdmi_config_video(struct rk30_hdmi_video_para *vpara)
                hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic);
                return -ENOENT;
        }
+       hdmi->tmdsclk = mode->pixclock;
        value = v_EXT_VIDEO_ENABLE(1) | v_INTERLACE(mode->vmode);
        if(mode->sync & FB_SYNC_HOR_HIGH_ACT)
                value |= v_HSYNC_POLARITY(1);
index 45f986bf6f2ee3609518d28a9b8fd061950ed378..6a5fc3368a62e51e9bfd18ac1b273cd67eaf81c2 100755 (executable)
@@ -392,6 +392,9 @@ enum {
 #define HDCP_KSV_BYTE3                 0x308
 #define HDCP_KSV_BYTE4                 0x30c
 
+/* HDCP error status */
+#define HDCP_ERROR                             0x320
+
 /* HDCP 100 ms timer */
 #define HDCP_TIMER_100MS               0x324
 /* HDCP 5s timer */