video: rockchip: tve: code sync from kernel-3.10
authorShen Zhenyi <szy@rock-chips.com>
Thu, 3 Mar 2016 07:43:47 +0000 (15:43 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 3 Mar 2016 11:08:02 +0000 (19:08 +0800)
Change-Id: I677105f02c1be03a062cbe80b3883000b107ca91
Signed-off-by: Shen Zhenyi <szy@rock-chips.com>
drivers/video/rockchip/tve/rk3036/rk3036_tve.c
drivers/video/rockchip/tve/rk3036/rk3036_tve.h

index ee30ae6d20b2a72dd666e40de57b9238ee09057d..b8415412dd1b5c1e2b0213634ba2edf21531bc36 100755 (executable)
@@ -21,9 +21,9 @@
 #include <linux/rk_fb.h>
 #include <linux/rockchip/grf.h>
 #include <linux/rockchip/iomap.h>
+#include "../../hdmi/rockchip-hdmiv2/rockchip_hdmiv2.h"
 #include "rk3036_tve.h"
 
-
 static const struct fb_videomode rk3036_cvbs_mode[] = {
        /*name          refresh xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw                    polariry                                PorI            flag*/
 /*     {"NTSC",        60,     720,    480,    27000000,       57,     19,     19,     0,      62,     3,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   FB_VMODE_INTERLACED,    0},
@@ -60,13 +60,15 @@ static void dac_enable(bool enable)
        if (enable) {
                mask = m_VBG_EN | m_DAC_EN | m_DAC_GAIN;
                if (rk3036_tve->soctype == SOC_RK312X) {
-                       val = m_VBG_EN | m_DAC_EN | v_DAC_GAIN(0x3a);
+                       val = m_VBG_EN | m_DAC_EN |
+                             v_DAC_GAIN(rk3036_tve->daclevel);
                        grfreg = RK312X_GRF_TVE_CON;
                } else if (rk3036_tve->soctype == SOC_RK3036) {
-                       val = m_VBG_EN | m_DAC_EN | v_DAC_GAIN(0x3e);
+                       val = m_VBG_EN | m_DAC_EN |
+                             v_DAC_GAIN(rk3036_tve->daclevel);
                        grfreg = RK3036_GRF_SOC_CON3;
-               } else if (rk3036_tve->soctype == SOC_RK3228) {
-                       val = 0xb0;
+               } else if (rk3036_tve->soctype == SOC_RK322X) {
+                       val = 0x70;
                }
        } else {
                mask = m_VBG_EN | m_DAC_EN;
@@ -75,8 +77,8 @@ static void dac_enable(bool enable)
                        grfreg = RK312X_GRF_TVE_CON;
                else if (rk3036_tve->soctype == SOC_RK3036)
                        grfreg = RK3036_GRF_SOC_CON3;
-               else if (rk3036_tve->soctype == SOC_RK3228)
-                       val = v_CUR_REG(0xb) | m_DR_PWR_DOWN | m_BG_PWR_DOWN;
+               else if (rk3036_tve->soctype == SOC_RK322X)
+                       val = v_CUR_REG(0x7) | m_DR_PWR_DOWN | m_BG_PWR_DOWN;
        }
        if (grfreg)
                grf_writel(grfreg, (mask << 16) | val);
@@ -84,12 +86,12 @@ static void dac_enable(bool enable)
                tve_dac_writel(VDAC_VDAC1, val);
 }
 
-static void rk3228_dac_init(void)
+static void rk322x_dac_init(void)
 {
        /*tve_dac_writel(VDAC_VDAC0, 0x0);*/
-       tve_dac_writel(VDAC_VDAC1, v_CUR_REG(0xb) |
+       tve_dac_writel(VDAC_VDAC1, v_CUR_REG(0x7) |
                                   m_DR_PWR_DOWN | m_BG_PWR_DOWN);
-       tve_dac_writel(VDAC_VDAC2, v_CUR_CTR(0x39));
+       tve_dac_writel(VDAC_VDAC2, v_CUR_CTR(rk3036_tve->daclevel));
        tve_dac_writel(VDAC_VDAC3, v_CAB_EN(0));
 }
 
@@ -98,7 +100,7 @@ static void tve_set_mode(int mode)
        TVEDBG("%s mode %d\n", __func__, mode);
        if (cvbsformat >= 0)
                return;
-       if (rk3036_tve->soctype != SOC_RK3228) {
+       if (rk3036_tve->soctype != SOC_RK322X) {
                tve_writel(TV_RESET, v_RESET(1));
                usleep_range(100, 110);
                tve_writel(TV_RESET, v_RESET(0));
@@ -111,15 +113,10 @@ static void tve_set_mode(int mode)
                tve_writel(TV_CTRL, v_CVBS_MODE(mode) | v_CLK_UPSTREAM_EN(2) |
                           v_TIMING_EN(2) | v_LUMA_FILTER_GAIN(0) |
                           v_LUMA_FILTER_UPSAMPLE(1) | v_CSC_PATH(3));
-       if (rk3036_tve->soctype == SOC_RK3228) {
-               tve_writel(TV_LUMA_FILTER0, 0x02ff0001);
-               tve_writel(TV_LUMA_FILTER1, 0xF40202fe);
-               tve_writel(TV_LUMA_FILTER2, 0xF332d910);
-       } else {
-               tve_writel(TV_LUMA_FILTER0, 0x02ff0000);
-               tve_writel(TV_LUMA_FILTER1, 0xF40202fd);
-               tve_writel(TV_LUMA_FILTER2, 0xF332d919);
-       }
+
+       tve_writel(TV_LUMA_FILTER0, rk3036_tve->lumafilter0);
+       tve_writel(TV_LUMA_FILTER1, rk3036_tve->lumafilter1);
+       tve_writel(TV_LUMA_FILTER2, rk3036_tve->lumafilter2);
 
        if (mode == TVOUT_CVBS_NTSC) {
                tve_writel(TV_ROUTING, v_DAC_SENSE_EN(0) | v_Y_IRE_7_5(1) |
@@ -145,37 +142,19 @@ static void tve_set_mode(int mode)
                        v_YPP_MODE(1) | v_Y_SYNC_ON(1) | v_PIC_MODE(mode));
                tve_writel(TV_BW_CTRL, v_CHROMA_BW(BP_FILTER_PAL) |
                        v_COLOR_DIFF_BW(COLOR_DIFF_FILTER_BW_1_3));
-               if (rk3036_tve->soctype == SOC_RK312X) {
-                       tve_writel(TV_SATURATION, /*0x00325c40*/ 0x002b4d3c);
-                       if (rk3036_tve->test_mode)
-                               tve_writel(TV_BRIGHTNESS_CONTRAST, 0x00008a0a);
-                       else
-                               tve_writel(TV_BRIGHTNESS_CONTRAST, 0x0000770a);
-               } else if (rk3036_tve->soctype == SOC_RK3228) {
-                       tve_writel(TV_SATURATION, 0x00386346);
-                       tve_writel(TV_BRIGHTNESS_CONTRAST, 0x00009000);
-               } else {
-                       tve_writel(TV_SATURATION, /*0x00325c40*/ 0x00386346);
-                       tve_writel(TV_BRIGHTNESS_CONTRAST, 0x00008b00);
-               }
+
+               tve_writel(TV_SATURATION, rk3036_tve->saturation);
+               tve_writel(TV_BRIGHTNESS_CONTRAST, rk3036_tve->brightcontrast);
 
                tve_writel(TV_FREQ_SC,  0x2A098ACB);
                tve_writel(TV_SYNC_TIMING, 0x00C28381);
                tve_writel(TV_ADJ_TIMING, (0xc << 28) | 0x06c00800 | 0x80);
                tve_writel(TV_ACT_ST,   0x001500F6);
                tve_writel(TV_ACT_TIMING, 0x0694011D | (1 << 12) | (2 << 28));
-               if (rk3036_tve->soctype == SOC_RK312X) {
-                       tve_writel(TV_ADJ_TIMING, (0xa << 28) |
-                                       0x06c00800 | 0x80);
-                       usleep_range(100, 150);
-                       tve_writel(TV_ADJ_TIMING, (0xa << 28) |
-                                       0x06c00800 | 0x80);
-                       tve_writel(TV_ACT_TIMING, 0x0694011D |
-                                       (1 << 12) | (2 << 28));
-               } else {
-                       tve_writel(TV_ADJ_TIMING, (0xa << 28) |
-                                       0x06c00800 | 0x80);
-               }
+
+               tve_writel(TV_ADJ_TIMING, rk3036_tve->adjtiming);
+               tve_writel(TV_ACT_TIMING, 0x0694011D |
+                               (1 << 12) | (2 << 28));
        }
 }
 
@@ -183,7 +162,7 @@ static int tve_switch_fb(const struct fb_videomode *modedb, int enable)
 {
        struct rk_screen *screen = &rk3036_tve->screen;
 
-       if (modedb == NULL)
+       if (!modedb)
                return -1;
 
        memset(screen, 0, sizeof(struct rk_screen));
@@ -223,6 +202,8 @@ static int tve_switch_fb(const struct fb_videomode *modedb, int enable)
        rk_fb_switch_screen(screen, enable, 0);
 
        if (enable) {
+               if (rk3036_tve->soctype == SOC_RK322X)
+                       ext_pll_set_27m_out();
                if (screen->mode.yres == 480)
                        tve_set_mode(TVOUT_CVBS_NTSC);
                else
@@ -234,10 +215,13 @@ static int tve_switch_fb(const struct fb_videomode *modedb, int enable)
 static int cvbs_set_enable(struct rk_display_device *device, int enable)
 {
        TVEDBG("%s enable %d\n", __func__, enable);
+       mutex_lock(&rk3036_tve->tve_lock);
        if (rk3036_tve->enable != enable) {
                rk3036_tve->enable = enable;
-               if (rk3036_tve->suspend)
+               if (rk3036_tve->suspend) {
+                       mutex_unlock(&rk3036_tve->tve_lock);
                        return 0;
+               }
 
                if (enable == 0) {
                        dac_enable(false);
@@ -248,6 +232,7 @@ static int cvbs_set_enable(struct rk_display_device *device, int enable)
                        dac_enable(true);
                }
        }
+       mutex_unlock(&rk3036_tve->tve_lock);
        return 0;
 }
 
@@ -265,7 +250,7 @@ static int cvbs_get_status(struct rk_display_device *device)
 static int
 cvbs_get_modelist(struct rk_display_device *device, struct list_head **modelist)
 {
-       *modelist = &(rk3036_tve->modelist);
+       *modelist = &rk3036_tve->modelist;
        return 0;
 }
 
@@ -279,10 +264,12 @@ cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
                        if (rk3036_tve->mode != &rk3036_cvbs_mode[i]) {
                                rk3036_tve->mode =
                                (struct fb_videomode *)&rk3036_cvbs_mode[i];
-                               if (rk3036_tve->enable && !rk3036_tve->suspend)
+                               if (rk3036_tve->enable && !rk3036_tve->suspend) {
                                        dac_enable(false);
+                                       msleep(200);
                                        tve_switch_fb(rk3036_tve->mode, 1);
                                        dac_enable(true);
+                               }
                        }
                        return 0;
                }
@@ -294,7 +281,7 @@ cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
 static int
 cvbs_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
 {
-       *mode = *(rk3036_tve->mode);
+       *mode = *rk3036_tve->mode;
        return 0;
 }
 
@@ -316,7 +303,7 @@ tve_fb_event_notify(struct notifier_block *self,
                                if (rk3036_tve->enable) {
                                        tve_switch_fb(rk3036_tve->mode, 0);
                                        dac_enable(false);
-                                       if (rk3036_tve->soctype == SOC_RK3228)
+                                       if (rk3036_tve->soctype == SOC_RK322X)
                                                clk_disable_unprepare(rk3036_tve->dac_clk);
                                }
                        }
@@ -326,10 +313,11 @@ tve_fb_event_notify(struct notifier_block *self,
                switch (blank_mode) {
                case FB_BLANK_UNBLANK:
                        TVEDBG("resume tve\n");
+                       mutex_lock(&rk3036_tve->tve_lock);
                        if (rk3036_tve->suspend) {
-                               if (rk3036_tve->soctype == SOC_RK3228) {
+                               if (rk3036_tve->soctype == SOC_RK322X) {
                                        clk_prepare_enable(rk3036_tve->dac_clk);
-                                       rk3228_dac_init();
+                                       rk322x_dac_init();
                                }
                                rk3036_tve->suspend = 0;
                                if (rk3036_tve->enable) {
@@ -337,6 +325,7 @@ tve_fb_event_notify(struct notifier_block *self,
                                        dac_enable(true);
                                }
                        }
+                       mutex_unlock(&rk3036_tve->tve_lock);
                        break;
                default:
                        break;
@@ -378,7 +367,7 @@ static struct rk_display_driver display_cvbs = {
 static const struct of_device_id rk3036_tve_dt_ids[] = {
        {.compatible = "rockchip,rk3036-tve",},
        {.compatible = "rockchip,rk312x-tve",},
-       {.compatible = "rockchip,rk3228-tve",},
+       {.compatible = "rockchip,rk322x-tve",},
        {}
 };
 #endif
@@ -397,13 +386,74 @@ static int __init bootloader_tve_setup(char *str)
 
 early_param("tve.format", bootloader_tve_setup);
 
+static int rk3036_tve_parse_dt(struct device_node *np,
+                              struct rk3036_tve *rk3036_tve)
+{
+       int ret;
+       u32 val;
+
+       if (rk3036_tve->soctype == SOC_RK312X) {
+               ret = of_property_read_u32(np, "test_mode", &val);
+               if (ret < 0)
+                       goto errer;
+               else
+                       rk3036_tve->test_mode = val;
+       }
+
+       ret = of_property_read_u32(np, "saturation", &val);
+       if ((val == 0) || (ret < 0))
+               goto errer;
+       else
+               rk3036_tve->saturation = val;
+
+       ret = of_property_read_u32(np, "brightcontrast", &val);
+       if ((val == 0) || (ret < 0))
+               goto errer;
+       else
+               rk3036_tve->brightcontrast = val;
+
+       ret = of_property_read_u32(np, "adjtiming", &val);
+       if ((val == 0) || (ret < 0))
+               goto errer;
+       else
+               rk3036_tve->adjtiming = val;
+
+       ret = of_property_read_u32(np, "lumafilter0", &val);
+       if ((val == 0) || (ret < 0))
+               goto errer;
+       else
+               rk3036_tve->lumafilter0 = val;
+
+       ret = of_property_read_u32(np, "lumafilter1", &val);
+       if ((val == 0) || (ret < 0))
+               goto errer;
+       else
+               rk3036_tve->lumafilter1 = val;
+
+       ret = of_property_read_u32(np, "lumafilter2", &val);
+       if ((val == 0) || (ret < 0))
+               goto errer;
+       else
+               rk3036_tve->lumafilter2 = val;
+
+       ret = of_property_read_u32(np, "daclevel", &val);
+       if ((val == 0) || (ret < 0))
+               goto errer;
+       else
+               rk3036_tve->daclevel = val;
+
+       return 0;
+errer:
+       return -1;
+}
+
 static int rk3036_tve_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct resource *res;
        const struct of_device_id *match;
        int i;
-       int val = 0;
+       int ret;
 
        match = of_match_node(rk3036_tve_dt_ids, np);
        if (!match)
@@ -416,30 +466,26 @@ static int rk3036_tve_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       if (of_property_read_u32(np, "test_mode", &val))
-               rk3036_tve->test_mode = 0;
-       else
-               rk3036_tve->test_mode = val;
-       val = 0;
-       if (of_property_read_u32(np, "saturation", &val))
-               rk3036_tve->saturation = 0x002b4d3c;
-       else
-               rk3036_tve->saturation = val;
-
        if (!strcmp(match->compatible, "rockchip,rk3036-tve")) {
                rk3036_tve->soctype = SOC_RK3036;
                rk3036_tve->inputformat = INPUT_FORMAT_RGB;
        } else if (!strcmp(match->compatible, "rockchip,rk312x-tve")) {
                rk3036_tve->soctype = SOC_RK312X;
                rk3036_tve->inputformat = INPUT_FORMAT_YUV;
-       } else if (!strcmp(match->compatible, "rockchip,rk3228-tve")) {
-               rk3036_tve->soctype = SOC_RK3228;
+       } else if (!strcmp(match->compatible, "rockchip,rk322x-tve")) {
+               rk3036_tve->soctype = SOC_RK322X;
                rk3036_tve->inputformat = INPUT_FORMAT_YUV;
        } else {
                dev_err(&pdev->dev, "It is not a valid tv encoder!");
                return -ENOMEM;
        }
 
+       ret = rk3036_tve_parse_dt(np, rk3036_tve);
+       if (ret) {
+               dev_err(&pdev->dev, "TVE parse dts error!");
+               return -EINVAL;
+       }
+
        platform_set_drvdata(pdev, rk3036_tve);
        rk3036_tve->dev = &pdev->dev;
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -451,7 +497,7 @@ static int rk3036_tve_probe(struct platform_device *pdev)
                        "rk3036 tv encoder device map registers failed!");
                return PTR_ERR(rk3036_tve->regbase);
        }
-       if (rk3036_tve->soctype == SOC_RK3228) {
+       if (rk3036_tve->soctype == SOC_RK322X) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
                rk3036_tve->len = resource_size(res);
                rk3036_tve->vdacbase = devm_ioremap(rk3036_tve->dev,
@@ -470,11 +516,13 @@ static int rk3036_tve_probe(struct platform_device *pdev)
                        return PTR_ERR(rk3036_tve->dac_clk);
                }
                clk_prepare_enable(rk3036_tve->dac_clk);
-               rk3228_dac_init();
+               if (cvbsformat < 0)
+                       rk322x_dac_init();
        }
-       INIT_LIST_HEAD(&(rk3036_tve->modelist));
+       mutex_init(&rk3036_tve->tve_lock);
+       INIT_LIST_HEAD(&rk3036_tve->modelist);
        for (i = 0; i < ARRAY_SIZE(rk3036_cvbs_mode); i++)
-               fb_add_videomode(&rk3036_cvbs_mode[i], &(rk3036_tve->modelist));
+               fb_add_videomode(&rk3036_cvbs_mode[i], &rk3036_tve->modelist);
         if (cvbsformat >= 0) {
                rk3036_tve->mode =
                        (struct fb_videomode *)&rk3036_cvbs_mode[cvbsformat];
index 8194a0543fc8c78fe3b0a01211e71bdeb3d8a0f6..b0c2a24d3e0622d00f74ca5bd07b81db1529b271 100644 (file)
@@ -118,7 +118,7 @@ enum {
 enum {
        SOC_RK3036 = 0,
        SOC_RK312X,
-       SOC_RK3228
+       SOC_RK322X
 };
 
 #define TVOUT_DEAULT TVOUT_CVBS_PAL
@@ -143,8 +143,15 @@ struct rk3036_tve {
        struct fb_videomode             *mode;
        struct list_head                modelist;
        struct rk_screen                screen;
-       int test_mode;
-       int saturation;
+       u32 test_mode;
+       u32 saturation;
+       u32 brightcontrast;
+       u32 adjtiming;
+       u32 lumafilter0;
+       u32 lumafilter1;
+       u32 lumafilter2;
+       u32 daclevel;
+       struct mutex tve_lock;  /* mutex for tve resume operation*/
 };
 
 #endif