rk3288 lcdc: add dsp_lut adjust support
authoryxj <yxj@rock-chips.com>
Wed, 3 Sep 2014 10:10:30 +0000 (18:10 +0800)
committeryxj <yxj@rock-chips.com>
Wed, 3 Sep 2014 10:16:40 +0000 (18:16 +0800)
arch/arm/boot/dts/lcd-F402.dtsi
drivers/video/of_display_timing.c
drivers/video/rockchip/lcdc/rk3288_lcdc.c
drivers/video/rockchip/rk_fb.c
include/video/display_timing.h

index 55035ed82838b86819f27672bdf669421803f337..7a83aedeac566fcea5f6391381800ad8c187ba9d 100644 (file)
                                swap-rb = <0>;
                                swap-rg = <0>;
                                swap-gb = <0>;
+                               dsp-lut = <0x00000000 0x00010101 0x00020202 0x00030303 0x00040404 0x00050505 0x00060606 0x00070707 0x00080808 0x00090909 
+                                               0x000a0a0a 0x000b0b0b 0x000c0c0c 0x000d0d0d 0x000e0e0e 0x000f0f0f 0x00101010 0x00111111 0x00121212 0x00131313 
+                                               0x00141414 0x00151515 0x00161616 0x00171717 0x00181818 0x00191919 0x001a1a1a 0x001b1b1b 0x001c1c1c 0x001d1d1d 
+                                               0x001e1e1e 0x001f1f1f 0x00202020 0x00212121 0x00222222 0x00232323 0x00242424 0x00252525 0x00262626 0x00272727 
+                                               0x00282828 0x00292929 0x002a2a2a 0x002b2b2b 0x002c2c2c 0x002d2d2d 0x002e2e2e 0x002f2f2f 0x00303030 0x00313131 
+                                               0x00323232 0x00333333 0x00343434 0x00353535 0x00363636 0x00373737 0x00383838 0x00393939 0x003a3a3a 0x003b3b3b 
+                                               0x003c3c3c 0x003d3d3d 0x003e3e3e 0x003f3f3f 0x00404040 0x00414141 0x00424242 0x00434343 0x00444444 0x00454545 
+                                               0x00464646 0x00474747 0x00484848 0x00494949 0x004a4a4a 0x004b4b4b 0x004c4c4c 0x004d4d4d 0x004e4e4e 0x004f4f4f 
+                                               0x00505050 0x00515151 0x00525252 0x00535353 0x00545454 0x00555555 0x00565656 0x00575757 0x00585858 0x00595959 
+                                               0x005a5a5a 0x005b5b5b 0x005c5c5c 0x005d5d5d 0x005e5e5e 0x005f5f5f 0x00606060 0x00616161 0x00626262 0x00636363 
+                                               0x00646464 0x00656565 0x00666666 0x00676767 0x00686868 0x00696969 0x006a6a6a 0x006b6b6b 0x006c6c6c 0x006d6d6d 
+                                               0x006e6e6e 0x006f6f6f 0x00707070 0x00717171 0x00727272 0x00737373 0x00747474 0x00757575 0x00767676 0x00777777 
+                                               0x00787878 0x00797979 0x007a7a7a 0x007b7b7b 0x007c7c7c 0x007d7d7d 0x007e7e7e 0x007f7f7f 0x00808080 0x00818181 
+                                               0x00828282 0x00838383 0x00848484 0x00858585 0x00868686 0x00878787 0x00888888 0x00898989 0x008a8a8a 0x008b8b8b 
+                                               0x008c8c8c 0x008d8d8d 0x008e8e8e 0x008f8f8f 0x00909090 0x00919191 0x00929292 0x00939393 0x00949494 0x00959595 
+                                               0x00969696 0x00979797 0x00989898 0x00999999 0x009a9a9a 0x009b9b9b 0x009c9c9c 0x009d9d9d 0x009e9e9e 0x009f9f9f 
+                                               0x00a0a0a0 0x00a1a1a1 0x00a2a2a2 0x00a3a3a3 0x00a4a4a4 0x00a5a5a5 0x00a6a6a6 0x00a7a7a7 0x00a8a8a8 0x00a9a9a9 
+                                               0x00aaaaaa 0x00ababab 0x00acacac 0x00adadad 0x00aeaeae 0x00afafaf 0x00b0b0b0 0x00b1b1b1 0x00b2b2b2 0x00b3b3b3 
+                                               0x00b4b4b4 0x00b5b5b5 0x00b6b6b6 0x00b7b7b7 0x00b8b8b8 0x00b9b9b9 0x00bababa 0x00bbbbbb 0x00bcbcbc 0x00bdbdbd 
+                                               0x00bebebe 0x00bfbfbf 0x00c0c0c0 0x00c1c1c1 0x00c2c2c2 0x00c3c3c3 0x00c4c4c4 0x00c5c5c5 0x00c6c6c6 0x00c7c7c7 
+                                               0x00c8c8c8 0x00c9c9c9 0x00cacaca 0x00cbcbcb 0x00cccccc 0x00cdcdcd 0x00cecece 0x00cfcfcf 0x00d0d0d0 0x00d1d1d1 
+                                               0x00d2d2d2 0x00d3d3d3 0x00d4d4d4 0x00d5d5d5 0x00d6d6d6 0x00d7d7d7 0x00d8d8d8 0x00d9d9d9 0x00dadada 0x00dbdbdb 
+                                               0x00dcdcdc 0x00dddddd 0x00dedede 0x00dfdfdf 0x00e0e0e0 0x00e1e1e1 0x00e2e2e2 0x00e3e3e3 0x00e4e4e4 0x00e5e5e5 
+                                               0x00e6e6e6 0x00e7e7e7 0x00e8e8e8 0x00e9e9e9 0x00eaeaea 0x00ebebeb 0x00ececec 0x00ededed 0x00eeeeee 0x00efefef 
+                                               0x00f0f0f0 0x00f1f1f1 0x00f2f2f2 0x00f3f3f3 0x00f4f4f4 0x00f5f5f5 0x00f6f6f6 0x00f7f7f7 0x00f8f8f8 0x00f9f9f9 
+                                               0x00fafafa 0x00fbfbfb 0x00fcfcfc 0x00fdfdfd 0x00fefefe 0x00ffffff>; 
                        };
                };
 };
index bcc28c6a6099802e19a44edca865897cfc8c6f0b..405dbd68a0d45b8c0f5c960f0496e6b432f1d00b 100644 (file)
@@ -61,7 +61,10 @@ static struct display_timing *of_get_display_timing(struct device_node *np)
        struct display_timing *dt;
        u32 val = 0;
        int ret = 0;
-
+#if defined(CONFIG_FB_ROCKCHIP) || defined(CONFIG_DRM_ROCKCHIP)
+       struct property *prop;
+       int length;
+#endif
        dt = kzalloc(sizeof(*dt), GFP_KERNEL);
        if (!dt) {
                pr_err("%s: could not allocate display_timing struct\n",
@@ -113,6 +116,13 @@ static struct display_timing *of_get_display_timing(struct device_node *np)
                dt->face = val;
        if (!of_property_read_u32(np, "color-mode", &val))
                 dt->color_mode = val;
+       prop = of_find_property(np, "dsp-lut", &length);
+       if (prop) {
+               dt->dsp_lut = kzalloc(length, GFP_KERNEL);
+               if (dt->dsp_lut)
+                       ret = of_property_read_u32_array(np,
+                               "dsp-lut",dt->dsp_lut, length >> 2);
+       }
 #endif
 
        if (ret) {
index 827ed304b3e98e5dd8b38bcb97d199b30836aeb8..a794a0d50c27f9c866f1b5c49892d9ce51ec2812 100755 (executable)
@@ -70,21 +70,26 @@ static int rk3288_lcdc_get_id(u32 phy_base)
 
 static int rk3288_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
 {
-       int i = 0;
+       int i,j;
        int __iomem *c;
-       int v;
+       u32 v,r,g,b;
        struct lcdc_device *lcdc_dev = container_of(dev_drv,
-                                                          struct
-                                                          lcdc_device,
-                                                          driver);
+                                       struct lcdc_device,driver);
        lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
        lcdc_cfg_done(lcdc_dev);
        mdelay(25);
        for (i = 0; i < 256; i++) {
                v = dev_drv->cur_screen->dsp_lut[i];
-               c = lcdc_dev->dsp_lut_addr_base + i;
-               writel_relaxed(v, c);
-
+               c = lcdc_dev->dsp_lut_addr_base + (i << 2);
+               b = (v & 0xff) << 2;
+               g = (v & 0xff00) << 4;
+               r = (v & 0xff0000) << 6;
+               v = r + g + b;
+               for (j = 0; j < 4; j++) {
+                       writel_relaxed(v, c);
+                       v += (1 + (1 << 10) + (1 << 20)) ;
+                       c++;
+               }
        }
        lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
 
@@ -2329,9 +2334,9 @@ static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
-       int i = 0;
+       int i, j;
        int __iomem *c;
-       int v;
+       int v, r, g, b;
 
        if (!dev_drv->suspend_flag)
                return 0;
@@ -2350,8 +2355,16 @@ static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
                        mdelay(25);
                        for (i = 0; i < 256; i++) {
                                v = dev_drv->cur_screen->dsp_lut[i];
-                               c = lcdc_dev->dsp_lut_addr_base + i;
-                               writel_relaxed(v, c);
+                               c = lcdc_dev->dsp_lut_addr_base + (i << 2);
+                               b = (v & 0xff) << 2;
+                               g = (v & 0xff00) << 4;
+                               r = (v & 0xff0000) << 6;
+                               v = r + g + b;
+                               for (j = 0; j < 4; j++) {
+                                       writel_relaxed(v, c);
+                                       v += (1 + (1 << 10) + (1 << 20)) ;
+                                       c++;
+                               }
                        }
                        lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
                                     v_DSP_LUT_EN(1));
@@ -2997,30 +3010,39 @@ static int rk3288_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
 
 static int rk3288_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
 {
-       int i = 0;
+       int i,j;
        int __iomem *c;
-       int v;
+       int v, r, g, b;
        int ret = 0;
 
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
        lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
        lcdc_cfg_done(lcdc_dev);
-       msleep(25);
+       mdelay(25);
        if (dev_drv->cur_screen->dsp_lut) {
                for (i = 0; i < 256; i++) {
                        v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
-                       c = lcdc_dev->dsp_lut_addr_base + i;
-                       writel_relaxed(v, c);
-
+                       c = lcdc_dev->dsp_lut_addr_base + (i << 2);
+                       b = (v & 0xff) << 2;
+                       g = (v & 0xff00) << 4;
+                       r = (v & 0xff0000) << 6;
+                       v = r + g + b;
+                       for (j = 0; j < 4; j++) {
+                               writel_relaxed(v, c);
+                               v += (1 + (1 << 10) + (1 << 20)) ;
+                               c++;
+                       }
                }
        } else {
                dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
                ret = -1;
        }
-       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
-       lcdc_cfg_done(lcdc_dev);
-
+       
+       do{
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
+               lcdc_cfg_done(lcdc_dev);
+       }while(!lcdc_read_bit(lcdc_dev,DSP_CTRL1,m_DSP_LUT_EN));
        return ret;
 }
 
@@ -3728,7 +3750,6 @@ static int rk3288_lcdc_probe(struct platform_device *pdev)
                return ret;
        }
        lcdc_dev->screen = dev_drv->screen0;
-       
        dev_info(dev, "lcdc%d probe ok, iommu %s\n",
                lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
 
index 76c81f321d5f5f5d1b61e9e11f49b72050144912..5388c1a92655b4dc53f0a4f8d1ed8b1245346a72 100755 (executable)
@@ -348,6 +348,7 @@ int rk_fb_video_mode_from_timing(const struct display_timing *dt,
        screen->lvds_format = dt->lvds_format;
        screen->face = dt->face;
        screen->color_mode = dt->color_mode;
+       screen->dsp_lut = dt->dsp_lut;
 
        if (dt->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
                screen->pin_dclk = 1;
index 365067d27cd4b8527b3ffe9f847aab1955e62405..6c5585a6316c6b8e6219dd7151b402c0df02ebc4 100644 (file)
@@ -80,6 +80,7 @@ struct display_timing {
        u16 lvds_format;                        /*lvds data format for lvds screen*/
        u16 face;                               /*display output  interface format:24bit 18bit 16bit*/
        u16 color_mode;                         /* input color mode: RGB or YUV */
+       u32 *dsp_lut;
 #endif
 };