rk3036 hdmi: add basic version
authorhjc <hjc@rock-chips.com>
Thu, 3 Jul 2014 11:40:26 +0000 (19:40 +0800)
committerhjc <hjc@rock-chips.com>
Fri, 4 Jul 2014 07:33:12 +0000 (15:33 +0800)
arch/arm/boot/dts/rk3036.dtsi
drivers/video/rockchip/hdmi/chips/Kconfig
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.h
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h
drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c

index c8616f020bbc61cd3fb4390cffa66cadd4cf25b6..bbb300c454a4cdfe0257d9ea4f304c98069dae97 100755 (executable)
                clocks = <&clk_gates1 6>, <&clk_gates7 3>;
                clock-names = "clk_usbphy1", "hclk_usb1";
        };
+         
+       hdmi: hdmi@20034000 {
+               compatible = "rockchip,rk3036-hdmi";
+               reg = <0x20034000 0x4000>;
+               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+               rockchip,hdmi_lcdc_source = <0>;
+               //pinctrl-names = "default", "gpio";
+               //pinctrl-0 = <&i2c5_sda &i2c5_scl>;
+               //pinctrl-1 = <&i2c5_gpio>;
+               clocks = <&clk_gates3 8>;
+               clock-names = "pclk_hdmi";      
+               status = "disabled";
+       };
 
         vpu: vpu_service@10108000 {
                compatible = "vpu_service";
index b8797ffdeab8f842346026dfeb6f312a6296385b..8f72dfed7b94c70bcc6afcd810fe8fbb69c6e648 100755 (executable)
@@ -39,7 +39,7 @@ endif
 
 config  HDMI_RK616
         bool "RK616 HDMI support"
-        depends on MFD_RK616 || ARCH_RK3026
+#depends on MFD_RK616 || ARCH_RK3026
                default y
         help
            Support rk616 hdmi if you say y here
index 1262dd579c9cbc3c738e1762928811585d2042dd..83bd233b8ac7f00541a49e627161706d0e801dd8 100755 (executable)
@@ -92,7 +92,7 @@ static const struct file_operations rk616_hdmi_reg_fops = {
 };
 #endif
 
-#if defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
 static int rk616_hdmi_clk_enable(struct rk_hdmi_device *hdmi_dev)
 {
        if (!hdmi_dev->clk_on) {
@@ -261,7 +261,7 @@ static irqreturn_t rk616_hdmi_irq(int irq, void *dev_id)
                disable_irq_nosync(hdmi_drv->irq);
                queue_work(hdmi_drv->workqueue, rk616_irq_work_struct);
        } else {
-               /* 3028a hdmi */
+               /* 3028a/3036 hdmi */
                if ((hdmi_drv->suspend == 0) && (hdmi_drv->enable == 1)) {
                        hdmi_dbg(hdmi_drv->dev,
                                 "line = %d, rk616_hdmi_irq irq triggered.\n",
@@ -284,7 +284,7 @@ static int rk616_hdmi_drv_init(struct hdmi *hdmi_drv)
        lcdc_id = (screen.lcdc_id == 0) ? 1 : 0;
        /* lcdc source select */
        /* wait to modify!!
-#if defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
        grf_writel(HDMI_SEL_LCDC(lcdc_id), RK3036_GRF_SOC_CON6);
 #endif
        */
@@ -310,10 +310,20 @@ static int rk616_hdmi_drv_init(struct hdmi *hdmi_drv)
        return ret;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id rk616_hdmi_of_match[] = {
+       {.compatible = "rockchip,rk616-hdmi",},
+       {.compatible = "rockchip,rk3036-hdmi",},
+       {}
+};
+
+MODULE_DEVICE_TABLE(of, rk616_hdmi_of_match);
+#endif
+
 static int rk616_hdmi_probe(struct platform_device *pdev)
 {
        int ret;
-       struct rk_hdmi_device *hdmi_dev;
+       //struct rk_hdmi_device *hdmi_dev;
        struct hdmi *hdmi_drv;
        struct resource __maybe_unused *mem;
        struct resource __maybe_unused *res;
@@ -330,7 +340,7 @@ static int rk616_hdmi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, hdmi_dev);
        spin_lock_init(&hdmi_dev->reg_lock);
 
-#ifdef CONFIG_ARCH_RK3026
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
        hdmi_dev->rk616_drv = NULL;
 #else
        hdmi_dev->rk616_drv = dev_get_drvdata(pdev->dev.parent);
@@ -354,7 +364,7 @@ static int rk616_hdmi_probe(struct platform_device *pdev)
        INIT_DELAYED_WORK(&(hdmi_drv->delay_work), hdmi_work);
        INIT_DELAYED_WORK(&hdmi_dev->rk616_delay_work, rk616_delay_work_func);
 
-#ifdef CONFIG_ARCH_RK3026
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
        /* enable clk */
        hdmi_dev->hclk = devm_clk_get(hdmi_drv->dev, "pclk_hdmi");
        if (IS_ERR(hdmi_dev->hclk)) {
@@ -362,12 +372,12 @@ static int rk616_hdmi_probe(struct platform_device *pdev)
                ret = -ENXIO;
                goto err1;
        }
-       rk616_hdmi_clk_enable();        /* enable clk may move to irq func */
+       rk616_hdmi_clk_enable(hdmi_dev);        /* enable clk may move to irq func */
 
        /* request and remap iomem */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
-               dev_err(hdmi_dev->dev, "Unable to get register resource\n");
+               dev_err(hdmi_drv->dev, "Unable to get register resource\n");
                ret = -ENXIO;
                goto err2;
        }
@@ -384,8 +394,8 @@ static int rk616_hdmi_probe(struct platform_device *pdev)
        /* get the IRQ */
        hdmi_drv->irq = platform_get_irq(pdev, 0);
        if (hdmi_drv->irq <= 0) {
-               dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n",
-                       hdmi->irq);
+               dev_err(hdmi_drv->dev, "failed to get hdmi irq resource (%d).\n",
+                       hdmi_drv->irq);
                hdmi_drv->irq = 0;
        } else {
                /* request the IRQ */
@@ -459,7 +469,7 @@ static int rk616_hdmi_probe(struct platform_device *pdev)
        dev_info(hdmi_drv->dev, "rk616 hdmi probe success.\n");
        return 0;
 
-#if defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_ARCH_RK3026) || defined(SOC_CONFIG_RK3036)
 err2:
        rk616_hdmi_clk_disable(hdmi_dev);
 #endif
@@ -520,7 +530,8 @@ static int rk616_hdmi_remove(struct platform_device *pdev)
 
 static void rk616_hdmi_shutdown(struct platform_device *pdev)
 {
-       struct hdmi *hdmi_drv;
+       struct rk_hdmi_device *hdmi_dev = platform_get_drvdata(pdev);
+       struct hdmi *hdmi_drv = NULL;
 
        if (hdmi_dev) {
                hdmi_drv = &hdmi_dev->driver;
@@ -541,26 +552,14 @@ static void rk616_hdmi_shutdown(struct platform_device *pdev)
        hdmi_dbg(hdmi_drv->dev, "rk616 hdmi shut down.\n");
 }
 
-#if defined(CONFIG_OF)
-static const struct of_device_id rk616_hdmi_of_match[] = {
-       {.compatible = "rockchip,rk616-hdmi",},
-       {}
-};
-
-MODULE_DEVICE_TABLE(of, rk616_hdmi_of_match);
-#endif
 
 static struct platform_driver rk616_hdmi_driver = {
        .probe = rk616_hdmi_probe,
        .remove = rk616_hdmi_remove,
        .driver = {
-#ifdef CONFIG_ARCH_RK3026
-                  .name = "rk3026-hdmi",
-#else
                   .name = "rk616-hdmi",
-#endif
                   .owner = THIS_MODULE,
-                  .of_match_table = of_match_ptr(rk616_hdmi_of_match),
+                  .of_match_table = of_match_ptr(rk616_hdmi_of_match),            
                   },
        .shutdown = rk616_hdmi_shutdown,
 };
index 35ff0927a75e5a2c1609f2967ac0491cb6326ce2..b104ee1878689e883376f619154ef614b30a81dc 100755 (executable)
@@ -30,6 +30,7 @@ struct rk_hdmi_device {
        int regsize_phy;
        struct clk *pd;
        struct clk *hclk;       /* HDMI AHP clk */
+       struct clk *pclk;       /* HDMI APB clk */
        struct delayed_work rk616_delay_work;
        struct work_struct rk616_irq_work_struct;
        struct mfd_rk616 *rk616_drv;
index 4b51345b6a3fb327a077ed07a7f02db75c13e601..26d91496d974cdb6c5b0edf9af1ec30c9599b381 100755 (executable)
@@ -5,7 +5,8 @@
 #include "rk616_hdmi.h"
 #include "rk616_hdmi_hw.h"
 
-#ifndef CONFIG_ARCH_RK3026
+#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
+
 static int rk616_set_polarity(struct mfd_rk616 *rk616_drv, int vic)
 {
        u32 val;
@@ -129,11 +130,16 @@ static void rk616_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
                        hdmi_writel(hdmi_dev, PHY_DRIVER, 0x99);
                        hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x0f);
                }
-
-               hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2d);
-               hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2c);
-               hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x28);
-               hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x20);
+#ifndef SOC_CONFIG_RK3036
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x2d);
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x2c);
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x28);
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x20);
+#else
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x15);
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x14);
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x10);
+#endif
                hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f);
                hdmi_writel(hdmi_dev, 0xce, 0x00);
                hdmi_writel(hdmi_dev, 0xce, 0x01);
@@ -149,7 +155,11 @@ static void rk616_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
                hdmi_writel(hdmi_dev, PHY_DRIVER, 0x00);
                hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x00);
                hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x00);
-               hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2f);
+#ifndef SOC_CONFIG_RK3036
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x2f);
+#else
+               hdmi_writel(hdmi_dev, PHY_SYS_CTL,0x17);
+#endif
                break;
        default:
                hdmi_dbg(hdmi_drv->dev, "unkown rk616 hdmi pwr mode %d\n",
@@ -259,8 +269,12 @@ int rk616_hdmi_read_edid(struct hdmi *hdmi_drv, int block, u8 *buf)
                        }
                }
        }
-
-       hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+       //close edid irq
+#ifndef SOC_CONFIG_RK3036
+        hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+#else
+       hdmi_writel(hdmi_dev, INTERRUPT_MASK1, 0);
+#endif
        enable_irq(hdmi_drv->irq);
 
        return ret;
@@ -570,10 +584,17 @@ void rk616_hdmi_work(struct hdmi *hdmi_drv)
                                                       struct rk_hdmi_device,
                                                       driver);
 
-       hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &interrupt);
-       if (interrupt)
-               hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt);
-
+#ifndef SOC_CONFIG_RK3036
+        hdmi_readl(hdmi_dev, INTERRUPT_STATUS1,&interrupt);
+        if(interrupt){
+                hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt);
+        }
+#else
+       hdmi_readl(hdmi_dev, HDMI_STATUS,&interrupt);
+       if(interrupt){
+               hdmi_writel(hdmi_dev, HDMI_STATUS, interrupt);
+       }
+#endif
        if (interrupt & m_HOTPLUG) {
                if (hdmi_drv->state == HDMI_SLEEP)
                        hdmi_drv->state = WAIT_HOTPLUG;
@@ -602,14 +623,20 @@ static void rk616_hdmi_reset(struct hdmi *hdmi_drv)
        msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
        val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
        hdmi_msk_reg(hdmi_dev, SYS_CTRL, msk, val);
+#ifndef SOC_CONFIG_RK3036
        hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+#else
+       hdmi_readl(hdmi_dev, HDMI_STATUS,&val);//enable hpg
+       val |= m_MASK_INT_HOTPLUG;
+       hdmi_writel(hdmi_dev, HDMI_STATUS,val);
+#endif
        rk616_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
 }
 
 int rk616_hdmi_initial(struct hdmi *hdmi_drv)
 {
        int rc = HDMI_ERROR_SUCESS;
-#ifndef CONFIG_ARCH_RK3026
+#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
        struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
                                                       struct rk_hdmi_device,
                                                       driver);
@@ -624,9 +651,11 @@ int rk616_hdmi_initial(struct hdmi *hdmi_drv)
        hdmi_drv->detect_hotplug = rk616_hdmi_detect_hotplug;
        hdmi_drv->read_edid = rk616_hdmi_read_edid;
 
-#ifdef CONFIG_ARCH_RK3026
+#if defined(CONFIG_ARCH_RK3026)
        rk3028_hdmi_reset_pclk();
        rk616_hdmi_reset(hdmi_drv);
+#elif defined(SOC_CONFIG_RK3036)
+       rk616_hdmi_reset(hdmi_drv);
 #else
        hdmi_drv->set_vif = rk616_hdmi_set_vif;
        rk616_hdmi_reset(hdmi_drv);
index 1d3c24417d751eba87f44d7fbd6026d28c91972c..41c88e6b07206822fc32ea3dc57202281915526f 100755 (executable)
@@ -1,6 +1,8 @@
 #ifndef _RK616_HDMI_HW_H
 #define _RK616_HDMI_HW_H
 
+#define SOC_CONFIG_RK3036
+
 #define RK616_HDMI_BASE 0x400
 enum PWR_MODE {
        NORMAL,
@@ -223,7 +225,9 @@ enum {
 
 #define INTERRUPT_MASK1                        0xc0
 #define INTERRUPT_STATUS1              0xc1
+       #ifndef SOC_CONFIG_RK3036
 #define m_INT_HOTPLUG          (1 << 7)
+       #endif
 #define        m_INT_ACTIVE_VSYNC      (1 << 5)
 #define m_INT_EDID_READY       (1 << 2)
 
@@ -234,9 +238,15 @@ enum {
 #define m_INT_HDCP_OK          (1 << 4)
 
 #define HDMI_STATUS                    0xc8
-#define m_HOTPLUG              (1 << 7)
-#define m_DDC_SDA              (1 << 5)
-#define m_DDC_SDC              (1 << 4)
+       #define m_HOTPLUG       (1 << 7)
+       #ifndef SOC_CONFIG_RK3036
+       #define m_DDC_SDA       (1 << 5)
+       #define m_DDC_SDC       (1 << 4)
+       #else
+       #define m_MASK_INT_HOTPLUG      (1 << 5)
+       #define m_INT_HOTPLUG           (1 << 1)
+       #endif
+
 
 #define HDMI_COLORBAR                   0xc9
 
@@ -282,7 +292,7 @@ enum {
 #define PHY_PRE_DIV_RATIO              0xed
 #define v_PRE_DIV_RATIO(n)     (n & 0x1f)
 
-#ifndef CONFIG_ARCH_RK3026
+#if !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
 static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev,
                             u16 offset, u32 *val)
 {
@@ -342,11 +352,11 @@ static inline int hdmi_msk_reg(struct rk_hdmi_device *hdmi_dev, u16 offset,
        int ret = 0;
        u32 temp;
 
-       temp = readl_relaxed(hdmi->regbase + (offset) * 0x04) & (0xFF - (msk));
-       writel_relaxed(temp | ((val) & (msk)), hdmi->regbase + (offset) * 0x04);
+       temp = readl_relaxed(hdmi_dev->regbase + (offset) * 0x04) & (0xFF - (msk));
+       writel_relaxed(temp | ((val) & (msk)), hdmi_dev->regbase + (offset) * 0x04);
        return ret;
 }
-
+#if defined(CONFIG_ARCH_RK3026)
 static inline void rk3028_hdmi_reset_pclk(void)
 {
        writel_relaxed(0x00010001, RK2928_CRU_BASE + 0x128);
@@ -354,6 +364,7 @@ static inline void rk3028_hdmi_reset_pclk(void)
        writel_relaxed(0x00010000, RK2928_CRU_BASE + 0x128);
 }
 #endif
+#endif
 
 extern int rk616_hdmi_initial(struct hdmi *hdmi);
 extern void rk616_hdmi_work(struct hdmi *hdmi);
index fe65b3760f7696972e795e7c15e68ea8ae725dc8..cb61763ac68cc0c508668999ad2417299b0fed42 100755 (executable)
@@ -124,7 +124,7 @@ int hdmi_set_info(struct rk_screen *screen, unsigned int vic)
        screen->hdmi_resolution = hdmi_mode[i].flag;
 
        /* Pin polarity */
-#if defined(CONFIG_HDMI_RK616) && !defined(CONFIG_ARCH_RK3026)
+#if defined(CONFIG_HDMI_RK616) && !defined(CONFIG_ARCH_RK3026) && !defined(SOC_CONFIG_RK3036)
        screen->pin_hsync = 0;
        screen->pin_vsync = 0;
 #else