简介

tiny4412 lcd屏使用的液晶屏型号是S702,它通过RGB888跟4412进行数据通信。LCD驱动的实现方式有两种,一种是单独写驱动模块,另一种是基于源码s3c-fb.c去修改。
第一种方式可以参考
【TINY4412】LINUX移植笔记:(27)设备树LCD驱动
Exynos4412——LCD驱动
另外一种方式是参考fire brother的github去修改的。
第二种方式的思路是基于友善之臂的linux3.5源码移植过来,然后改成设备树的形式。我这里仅仅是做了移植操作,没有去仔细分析代码,所以我这里仅提供diff。

diff

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 6085e92..7cf499e 100755
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -722,8 +722,8 @@reg = <0x11c00000 0x20000>;interrupt-names = "fifo", "vsync", "lcd_sys";interrupts = <11 0>, <11 1>, <11 2>;
-            clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
-            clock-names = "sclk_fimd", "fimd";
+            clocks = <&clock CLK_FIMD0>, <&clock CLK_SCLK_FIMD0>;
+            clock-names = "fimd", "sclk_fimd";power-domains = <&pd_lcd0>;iommus = <&sysmmu_fimd0>;samsung,sysreg = <&sys_reg>;
diff --git a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
old mode 100644
new mode 100755
index d7d5fdc..8bbb3a8
--- a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
@@ -363,7 +363,7 @@samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";samsung,pin-function = <EXYNOS_PIN_FUNC_2>;samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-        samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+        samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;};lcd_data16: lcd-data-width16 {@@ -396,7 +396,7 @@"gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";samsung,pin-function = <EXYNOS_PIN_FUNC_2>;samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-        samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+        samsung,pin-drv = <EXYNOS4_PIN_DRV_LV3>;};lcd_ldi: lcd-ldi {diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
index f6b00a7..92aa0f0 100755
--- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@ -11,6 +11,8 @@
/dts-v1/;
#include "exynos4412.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/video/samsung_fimd.h>
+
/ {model = "FriendlyARM TINY4412 board based on Exynos4412";
@@ -92,6 +94,147 @@clock-frequency = <24000000>;};};
+    tiny4412_lcd {+        status = "okay";
+
+        s702{+            width = <800>;
+            height = <480>;
+            p_width = <155>;
+            p_height = <93>;
+            bpp = <24>;
+            freq = <63>;
+
+            timing {+                h_fp = <80>;
+                h_bp = <36>;
+                h_sw = <10>;
+                v_fp = <22>;
+                v_fpe = <1>;
+                v_bp = <15>;
+                v_bpe = <1>;
+                v_sw = <8>;
+            };
+
+            polarity {+                rise_vclk;
+                inv_hsync;
+                inv_vsync;
+            };
+        };
+    };
+
+&fimd {+    compatible = "samsung,exynos4-fb";
+    sclk-fimd-rate = <800000000>;
+    pinctrl-0 = <&lcd_clk &lcd_data24>;
+    pinctrl-names = "lcd0_pin_cfg";
+    sysreg_lcd_blk_cfg_offset = /bits/ 32 <0x0210>;
+    status = "okay";
+    lcd_name = "s702";
+
+    lcd_default_config {+        vidcon0 = <VIDCON0_VIDOUT_RGB VIDCON0_PNRMODE_RGB>;
+        vidcon1 = <VIDCON1_INV_HSYNC VIDCON1_INV_VSYNC>;
+        setup_gpio = "exynos4_fimd0_gpio_setup_24bpp";
+
+        vtiming {+            left_margin = <9>;
+            right_margin = <9>;
+            upper_margin = <5>;
+            lower_margin = <5>;
+            hsync_len = <2>;
+            vsync_len = <2>;
+            xres = <480>;
+            yres = <800>;
+        };
+        wins_array {+            win0 {+                xres = /bits/ 16 <480>;
+                yres = /bits/ 16 <800>;
+                virtual_x = /bits/ 16 <480>;
+                virtual_y = /bits/ 16 <800>;
+                max_bpp     = /bits/ 16 <32>;
+                default_bpp    = /bits/ 16 <24>;
+                width = /bits/ 16 <66>;
+                height = /bits/ 16 <109>;
+            };
+
+            win1 {+                xres = /bits/ 16 <480>;
+                yres = /bits/ 16 <800>;
+                virtual_x = /bits/ 16 <480>;
+                virtual_y = /bits/ 16 <800>;
+                max_bpp     = /bits/ 16 <32>;
+                default_bpp    = /bits/ 16 <24>;
+                width = /bits/ 16 <66>;
+                height = /bits/ 16 <109>;
+            };
+
+            win2 {+                xres = /bits/ 16 <480>;
+                yres = /bits/ 16 <800>;
+                virtual_x = /bits/ 16 <480>;
+                virtual_y = /bits/ 16 <800>;
+                max_bpp     = /bits/ 16 <32>;
+                default_bpp    = /bits/ 16 <24>;
+                width = /bits/ 16 <66>;
+                height = /bits/ 16 <109>;
+            };
+
+            win3 {+                xres = /bits/ 16 <480>;
+                yres = /bits/ 16 <800>;
+                virtual_x = /bits/ 16 <480>;
+                virtual_y = /bits/ 16 <800>;
+                max_bpp     = /bits/ 16 <32>;
+                default_bpp    = /bits/ 16 <24>;
+                width = /bits/ 16 <66>;
+                height = /bits/ 16 <109>;
+            };
+
+            win4 {+                xres = /bits/ 16 <480>;
+                yres = /bits/ 16 <800>;
+                virtual_x = /bits/ 16 <480>;
+                virtual_y = /bits/ 16 <800>;
+                max_bpp     = /bits/ 16 <32>;
+                default_bpp    = /bits/ 16 <24>;
+                width = /bits/ 16 <66>;
+                height = /bits/ 16 <109>;
+            };
+        };
+
+    };
+
+
};
&i2c_0 {diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 846b0c9..bf66a1d 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -102,7 +102,7 @@ obj-$(CONFIG_FB_BROADSHEET)       += broadsheetfb.o
obj-$(CONFIG_FB_S1D13XXX)      += s1d13xxxfb.o
obj-$(CONFIG_FB_SH7760)          += sh7760fb.o
obj-$(CONFIG_FB_IMX)              += imxfb.o
-obj-$(CONFIG_FB_S3C)          += s3c-fb.o
+obj-y          += s3c-fb.o
obj-$(CONFIG_FB_S3C2410)      += s3c2410fb.o
obj-$(CONFIG_FB_FSL_DIU)      += fsl-diu-fb.o
obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c
old mode 100644
new mode 100755
index 9ec85cc..a343636
--- a/drivers/video/fbdev/s3c-fb.c
+++ b/drivers/video/fbdev/s3c-fb.c
@@ -24,10 +24,17 @@
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
+#include <linux/dma-buf.h>
+
#include <linux/platform_data/video_s3c.h>
#include <video/samsung_fimd.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/gpio.h>
+#include <linux/byteorder/generic.h>
+
/* This driver will export a number of framebuffer interfaces depending* on the configuration passed in via the platform data. Each fb instance* maps to a hardware window. Currently there is no support for runtime
@@ -54,7 +61,7 @@
/* irq_flags bits */
#define S3C_FB_VSYNC_IRQ_EN    0
-#define VSYNC_TIMEOUT_MSEC 50
+#define VSYNC_TIMEOUT_MSEC 60
struct s3c_fb;
@@ -153,6 +160,13 @@ struct s3c_fb_palette {struct fb_bitfield    a;
};
+struct s3c_dma_buf_data {+    struct dma_buf *dma_buf;
+    struct dma_buf_attachment *attachment;
+    struct sg_table *sg_table;
+    dma_addr_t dma_addr;
+};
+
/*** struct s3c_fb_win - per window private data for each framebuffer.* @windata: The platform data supplied for the window configuration.
@@ -174,6 +188,13 @@ struct s3c_fb_win {u32            *palette_buffer;u32             pseudo_palette[16];unsigned int         index;
+
+    struct s3c_dma_buf_data dma_buf_data;
+    struct fb_var_screeninfo prev_var;
+    struct fb_fix_screeninfo prev_fix;
+
+    int         fps;
+
};
/**
@@ -221,6 +242,90 @@ struct s3c_fb {struct s3c_fb_vsync     vsync_info;
};
+#ifdef CONFIG_OF
+
+typedef struct lcd_io_reg_cfg{
+    struct pinctrl *pctrl;
+    struct pinctrl_state *pin_lcd_cfg;
+    void __iomem *lcd_blk_cfg_reg;
+} lcd_io_reg_cfg;
+
+static struct lcd_io_reg_cfg lcd_io_cfg = {
+    .lcd_blk_cfg_reg = NULL,
+    .pctrl = NULL,
+    .pin_lcd_cfg = NULL,
+};
+
+static const struct of_device_id s3c_fb_of_match[];
+static struct s3c_fb_platdata * of_get_s3_fb_lcd(const struct device_node *node,
+    const char *name);
+static int of_parse_lcd_io_reg_cfg(struct platform_device *pdev,
+    struct lcd_io_reg_cfg *pcfg);
+
+#endif
+
+
+/*
+ * struct s3cfb_lcd_polarity
+ * @rise_vclk:    if 1, video data is fetched at rising edge
+ * @inv_hsync:    if HSYNC polarity is inversed
+ * @inv_vsync:    if VSYNC polarity is inversed
+ * @inv_vden:    if VDEN polarity is inversed
+ */
+struct s3cfb_lcd_polarity {+    int    rise_vclk;
+    int    inv_hsync;
+    int    inv_vsync;
+    int    inv_vden;
+};
+
+/*
+ * struct s3cfb_lcd_timing
+ * @h_fp:    horizontal front porch
+ * @h_bp:    horizontal back porch
+ * @h_sw:    horizontal sync width
+ * @v_fp:    vertical front porch
+ * @v_fpe:    vertical front porch for even field
+ * @v_bp:    vertical back porch
+ * @v_bpe:    vertical back porch for even field
+ */
+struct s3cfb_lcd_timing {+    int    h_fp;
+    int    h_bp;
+    int    h_sw;
+    int    v_fp;
+    int    v_fpe;
+    int    v_bp;
+    int    v_bpe;
+    int    v_sw;
+};
+
+
+/*
+ * struct s3cfb_lcd
+ * @width:        horizontal resolution
+ * @height:        vertical resolution
+ * @p_width:    width of lcd in mm
+ * @p_height:    height of lcd in mm
+ * @bpp:        bits per pixel
+ * @freq:        vframe frequency
+ * @timing:        timing values
+ * @polarity:    polarity settings
+ * @init_ldi:    pointer to LDI init function
+ *
+ */
+struct s3cfb_lcd {+    int    width;
+    int    height;
+    int    p_width;
+    int    p_height;
+    int    bpp;
+    int    freq;
+    struct    s3cfb_lcd_timing timing;
+    struct    s3cfb_lcd_polarity polarity;
+};
+
+
/*** s3c_fb_validate_win_bpp - validate the bits-per-pixel for this mode.* @win: The device window.
@@ -962,7 +1067,7 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id)struct s3c_fb *sfb = dev_id;void __iomem  *regs = sfb->regs;u32 irq_sts_reg;
-
+    printk(KERN_WARNING"s3c_fb_irq do irq!\n");spin_lock(&sfb->slock);irq_sts_reg = readl(regs + VIDINTCON1);
@@ -1098,21 +1203,25 @@ static int s3c_fb_alloc_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)size = (real_size > virt_size) ? real_size : virt_size;size *= (windata->max_bpp > 16) ? 32 : windata->max_bpp;
-    size /= 8;
+    size >>= 3;fbi->fix.smem_len = size;size = PAGE_ALIGN(size);dev_dbg(sfb->dev, "want %u bytes for window\n", size);
-    fbi->screen_base = dma_alloc_wc(sfb->dev, size, &map_dma, GFP_KERNEL);
-    if (!fbi->screen_base)
+    fbi->screen_base = dma_alloc_writecombine(sfb->dev, size, &map_dma, GFP_KERNEL);
+    printk(KERN_WARNING"s3c_fb_alloc_memory dma addr 0x%08X\n", map_dma);
+    if (!fbi->screen_base){
+        dev_err(sfb->dev, "dma_alloc_writecombine err\n");return -ENOMEM;
+    }
+dev_dbg(sfb->dev, "mapped %x to %p\n",(unsigned int)map_dma, fbi->screen_base);
-    memset(fbi->screen_base, 0x0, size);
+    memset(fbi->screen_base, 0x00, size);fbi->fix.smem_start = map_dma;return 0;
@@ -1130,7 +1239,7 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)struct fb_info *fbi = win->fbinfo;if (fbi->screen_base)
-        dma_free_wc(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),
+        dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),fbi->screen_base, fbi->fix.smem_start);
}
@@ -1242,6 +1351,8 @@ static int s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,initmode.yres = windata->yres;fb_videomode_to_var(&fbinfo->var, &initmode);
+    fbinfo->var.width    = windata->width;
+    fbinfo->var.height    = windata->height;fbinfo->fix.type    = FB_TYPE_PACKED_PIXELS;fbinfo->fix.accel    = FB_ACCEL_NONE;fbinfo->var.activate    = FB_ACTIVATE_NOW;
@@ -1314,6 +1425,13 @@ static void s3c_fb_set_rgb_timing(struct s3c_fb *sfb)data |= (1 << 5);writel(data, regs + VIDCON0);
+    if (sfb->variant.has_blendcon) {
+        data = readl(sfb->regs + BLENDCON);
+        data &= ~BLENDCON_NEW_MASK;
+        data |= BLENDCON_NEW_8BIT_ALPHA_VALUE;
+        writel(data, sfb->regs + BLENDCON);
+    }
+data = VIDTCON0_VBPD(vmode->upper_margin - 1) |VIDTCON0_VFPD(vmode->lower_margin - 1) |VIDTCON0_VSPW(vmode->vsync_len - 1);
@@ -1356,29 +1474,182 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)writel(reg, sfb->regs + SHADOWCON);}
}
+static int of_parse_tiny4412_lcd(const char *lcd_name, struct s3cfb_lcd *lcd)
+{
+    struct device_node *lcd_np = NULL;
+    struct device_node *spec_lcd_np = NULL;
+    struct device_node *timing_np = NULL;
+    struct device_node *polar_np = NULL;
+
+    if((NULL == lcd_name) || (NULL == lcd))
+        return -1;
+
+    lcd_np = of_find_node_by_name(NULL, "tiny4412_lcd");
+
+    if(NULL == lcd_np)
+        return -1;
+
+    spec_lcd_np = of_get_child_by_name(lcd_np, lcd_name);
+
+    if(NULL == spec_lcd_np)
+        return -1;
+
+    of_property_read_u32(spec_lcd_np, "width", &lcd->width);
+    of_property_read_u32(spec_lcd_np, "height", &lcd->height);
+    of_property_read_u32(spec_lcd_np, "p_width", &lcd->p_width);
+    of_property_read_u32(spec_lcd_np, "p_height", &lcd->p_height);
+    of_property_read_u32(spec_lcd_np, "bpp", &lcd->bpp);
+    of_property_read_u32(spec_lcd_np, "freq", &lcd->freq);
+
+    timing_np = of_get_child_by_name(spec_lcd_np, "timing");
+    of_property_read_u32(timing_np, "h_fp", &lcd->timing.h_fp);
+    of_property_read_u32(timing_np, "h_bp", &lcd->timing.h_bp);
+    of_property_read_u32(timing_np, "h_sw", &lcd->timing.h_sw);
+    of_property_read_u32(timing_np, "v_fp", &lcd->timing.v_fp);
+    of_property_read_u32(timing_np, "v_fpe", &lcd->timing.v_fpe);
+    of_property_read_u32(timing_np, "v_bp", &lcd->timing.v_bp);
+    of_property_read_u32(timing_np, "v_bpe", &lcd->timing.v_bpe);
+    of_property_read_u32(timing_np, "v_sw", &lcd->timing.v_sw);
+
+    polar_np = of_get_child_by_name(spec_lcd_np, "polarity");
+    memset(&lcd->polarity, 0x00, sizeof(lcd->polarity));
+    if(of_property_read_bool(polar_np, "rise_vclk"))
+        lcd->polarity.rise_vclk = 1;
+
+    if(of_property_read_bool(polar_np, "inv_hsync"))
+        lcd->polarity.inv_hsync = 1;
+
+    if(of_property_read_bool(polar_np, "inv_vsync"))
+        lcd->polarity.inv_vsync = 1;
+
+    if(of_property_read_bool(polar_np, "inv_vden"))
+        lcd->polarity.inv_vden = 1;
+
+
+    return 0;
+
+}
+
+static void tiny4412_fb_init_pdata(const char *lcd_name, struct s3c_fb_platdata *pd) {
+    struct s3cfb_lcd *lcd = NULL;
+    struct s3c_fb_pd_win *win;
+    struct fb_videomode *mode = pd->vtiming;
+    unsigned long val = 0;
+    u64 pixclk = 1000000000000ULL;
+    u32 div;
+    int i, err;
+
+    if(NULL == lcd_name)
+        return;
+    printk(KERN_WARNING"lcd_name %s\n", lcd_name);
+
+    lcd = kzalloc(sizeof(struct s3cfb_lcd), GFP_KERNEL);
+    err = of_parse_tiny4412_lcd(lcd_name, lcd);
+    if(err < 0){
+        printk(KERN_WARNING"%s of_parse_tiny4412_lcd fail!!\n", lcd_name);
+        goto out;
+    }
+
+    for (i = 0; i < S3C_FB_MAX_WIN; i++) {
+        if (pd->win[i] == NULL)
+            continue;
+
+        win = pd->win[i];
+        win->xres        = lcd->width;
+        win->yres        = lcd->height;
+        win->default_bpp= lcd->bpp ? : 24;
+        win->virtual_x    = win->xres;
+        win->virtual_y    = win->yres * 3;
+        win->width        = lcd->p_width;
+        win->height        = lcd->p_height;
+    }
+
+    mode->left_margin    = lcd->timing.h_bp;
+    mode->right_margin    = lcd->timing.h_fp;
+    mode->upper_margin    = lcd->timing.v_bp;
+    mode->lower_margin    = lcd->timing.v_fp;
+    mode->hsync_len        = lcd->timing.h_sw;
+    mode->vsync_len        = lcd->timing.v_sw;
+    mode->xres            = lcd->width;
+    mode->yres            = lcd->height;
+
+    /* calculates pixel clock */
+    div  = mode->left_margin + mode->hsync_len + mode->right_margin +
+        mode->xres;
+    div *= mode->upper_margin + mode->vsync_len + mode->lower_margin +
+        mode->yres;
+    div *= lcd->freq ? : 60;
+
+    do_div(pixclk, div);
+
+    mode->pixclock        = pixclk + 386;
+
+    /* initialize signal polarity of RGB interface */
+    if (lcd->polarity.rise_vclk)
+        val |= VIDCON1_INV_VCLK;
+    if (lcd->polarity.inv_hsync)
+        val |= VIDCON1_INV_HSYNC;
+    if (lcd->polarity.inv_vsync)
+        val |= VIDCON1_INV_VSYNC;
+    if (lcd->polarity.inv_vden)
+        val |= VIDCON1_INV_VDEN;
+
+    pd->vidcon1 = val;
+
+out:
+    if(NULL != lcd){+        kfree(lcd);
+        lcd = NULL;
+    }
+
+}
+
static int s3c_fb_probe(struct platform_device *pdev)
{const struct platform_device_id *platid;
+    struct of_device_id *of_id = NULL;
+    struct device_node *fimd_root_dn = NULL;
+struct s3c_fb_driverdata *fbdrv;struct device *dev = &pdev->dev;struct s3c_fb_platdata *pd;struct s3c_fb *sfb;
+    struct s3c_fb_win *fbwin;struct resource *res;
+    const char *lcd_name = NULL;int win;int ret = 0;
-    u32 reg;
+    u32 reg, clk_rate = 0;
+    printk("s3c_fb_probe\n");
+
+    of_id = of_match_device(s3c_fb_of_match, &pdev->dev);
+    if(NULL != of_id){+        printk(KERN_WARNING"s3c_fb_probe: of_match_device OK \n");
+        fbdrv = (struct s3c_fb_driverdata *)of_id->data;
+        fimd_root_dn = dev->of_node;
+    }
+    else{+        platid = platform_get_device_id(pdev);
+        fbdrv = (struct s3c_fb_driverdata *)platid->driver_data;
+    }
-    platid = platform_get_device_id(pdev);
-    fbdrv = (struct s3c_fb_driverdata *)platid->driver_data;if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) {dev_err(dev, "too many windows, cannot attach\n");return -EINVAL;}
-    pd = dev_get_platdata(&pdev->dev);
-    if (!pd) {+    if(NULL != fimd_root_dn)
+    {+        of_parse_lcd_io_reg_cfg(pdev, &lcd_io_cfg);
+        pd = of_get_s3_fb_lcd(fimd_root_dn, "lcd_default_config");
+    }
+    else
+        pd = dev_get_platdata(&pdev->dev);
+
+    if(!pd){+dev_err(dev, "no platform data specified\n");return -EINVAL;}
@@ -1388,6 +1659,8 @@ static int s3c_fb_probe(struct platform_device *pdev)return -ENOMEM;dev_dbg(dev, "allocate new framebuffer %p\n", sfb);
+    of_property_read_string(fimd_root_dn, "lcd_name", &lcd_name);
+    tiny4412_fb_init_pdata(lcd_name, pd);sfb->dev = dev;sfb->pdata = pd;
@@ -1395,7 +1668,7 @@ static int s3c_fb_probe(struct platform_device *pdev)spin_lock_init(&sfb->slock);
-    sfb->bus_clk = devm_clk_get(dev, "lcd");
+    sfb->bus_clk = devm_clk_get(dev, "fimd");if (IS_ERR(sfb->bus_clk)) {dev_err(dev, "failed to get bus clock\n");return PTR_ERR(sfb->bus_clk);
@@ -1410,6 +1683,8 @@ static int s3c_fb_probe(struct platform_device *pdev)ret = PTR_ERR(sfb->lcd_clk);goto err_bus_clk;}
+        of_property_read_u32(fimd_root_dn, "sclk-fimd-rate", &clk_rate);
+        clk_set_rate(sfb->lcd_clk, clk_rate);clk_prepare_enable(sfb->lcd_clk);}
@@ -1423,13 +1698,12 @@ static int s3c_fb_probe(struct platform_device *pdev)goto err_lcd_clk;}
-    res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-    if (!res) {+    sfb->irq_no = platform_get_irq_byname(pdev, "vsync");
+    if (sfb->irq_no < 0) {dev_err(dev, "failed to acquire irq resource\n");ret = -ENOENT;goto err_lcd_clk;}
-    sfb->irq_no = res->start;ret = devm_request_irq(dev, sfb->irq_no, s3c_fb_irq,0, "s3c_fb", sfb);if (ret) {@@ -1478,8 +1752,8 @@ static int s3c_fb_probe(struct platform_device *pdev)if (!pd->win[win])continue;
-        ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win],
-                       &sfb->windows[win]);
+        ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win],
+            &sfb->windows[win]);if (ret < 0) {dev_err(dev, "failed to create window %d\n", win);for (; win >= 0; win--)
@@ -1487,9 +1761,17 @@ static int s3c_fb_probe(struct platform_device *pdev)goto err_pm_runtime;}}
+    fbwin = sfb->windows[0];
+
+    if (fb_prepare_logo(fbwin->fbinfo, FB_ROTATE_UR)) {+        printk("Start display and show logo\n");
+        fb_set_cmap(&fbwin->fbinfo->cmap, fbwin->fbinfo);
+        fb_show_logo(fbwin->fbinfo, FB_ROTATE_UR);
+
+    }platform_set_drvdata(pdev, sfb);
-    pm_runtime_put_sync(sfb->dev);
+return 0;
@@ -1658,6 +1940,152 @@ static int s3c_fb_runtime_resume(struct device *dev)
}
#endif
+#ifdef CONFIG_OF
+
+
+static int of_parse_lcd_io_reg_cfg(struct platform_device *pdev,
+    struct lcd_io_reg_cfg *pcfg)
+{+    struct device *dev = NULL;
+    struct device_node *sysreg_node = NULL;
+    u32 sysreg, offset, addr_cells_nr, size_cells_nr;
+    phandle sysreg_ph;
+
+    if((NULL == pdev) || (NULL == pcfg))
+        return -EINVAL;
+
+    dev = &pdev->dev;
+    of_property_read_u32_index(dev->of_node, "samsung,sysreg", 0, &sysreg_ph);
+    of_property_read_u32(dev->of_node, "sysreg_lcd_blk_cfg_offset", &offset);
+    sysreg_node = of_find_node_by_phandle(sysreg_ph);
+    addr_cells_nr = of_n_addr_cells(sysreg_node);
+    of_property_read_u32_index(sysreg_node, "reg", 0, &sysreg);
+    size_cells_nr = of_n_size_cells(sysreg_node);
+    pcfg->lcd_blk_cfg_reg =  ioremap(sysreg + offset, 4);
+
+    pcfg->pctrl = devm_pinctrl_get(dev);
+    pcfg->pin_lcd_cfg = pinctrl_lookup_state(pcfg->pctrl, "lcd0_pin_cfg");
+    if((NULL != pcfg->pctrl) && (NULL != pcfg->pin_lcd_cfg))
+        printk(KERN_WARNING"of_parse_lcd_io_reg_cfg pctrl setup OK!\n");
+
+    return 0;
+}
+static void setup_lcd_pin_cfg(void)
+{+    u32 reg;
+
+    pinctrl_select_state(lcd_io_cfg.pctrl, lcd_io_cfg.pin_lcd_cfg);
+    /*
+     * Set DISPLAY_CONTROL register for Display path selection.
+     *
+     * DISPLAY_CONTROL[1:0]
+     * ---------------------
+     *  00 | MIE
+     *  01 | MDINE
+     *  10 | FIMD : selected
+     *  11 | FIMD
+     */
+    reg = readl(lcd_io_cfg.lcd_blk_cfg_reg);
+    reg |= (1 << 1);
+    writel(reg, lcd_io_cfg.lcd_blk_cfg_reg);
+
+}
+
+
+static int of_parse_fimd_def_lcd(const struct device_node * np, struct s3c_fb_platdata *pdata)
+{+    struct device_node *vt_node;
+    struct device_node *wins_arr_node;
+
+    int i ,cnt;
+    u32 val;
+
+    if((NULL == np) || (NULL == pdata))
+        return -EINVAL;
+
+    cnt = of_property_count_elems_of_size(np, "vidcon0", sizeof(u32));
+    for(i = 0; i < cnt; i++)
+    {+        of_property_read_u32_index(np, "vidcon0", i, &val);
+        pdata->vidcon0 |= val;
+    }
+
+    cnt = of_property_count_elems_of_size(np, "vidcon1", sizeof(u32));
+    for(i = 0; i < cnt; i++)
+    {+        of_property_read_u32_index(np, "vidcon1", i, &val);
+        pdata->vidcon1 |= val;
+    }
+    vt_node = of_get_child_by_name(np, "vtiming");
+    if(NULL != vt_node)
+    {+        pdata->vtiming = kzalloc(sizeof(struct fb_videomode), GFP_KERNEL);
+        of_property_read_u32(vt_node, "left_margin", &pdata->vtiming->left_margin);
+        of_property_read_u32(vt_node, "right_margin", &pdata->vtiming->right_margin);
+        of_property_read_u32(vt_node, "upper_margin", &pdata->vtiming->upper_margin);
+        of_property_read_u32(vt_node, "lower_margin", &pdata->vtiming->lower_margin);
+        of_property_read_u32(vt_node, "hsync_len", &pdata->vtiming->hsync_len);
+        of_property_read_u32(vt_node, "vsync_len", &pdata->vtiming->vsync_len);
+        of_property_read_u32(vt_node, "xres", &pdata->vtiming->xres);
+        of_property_read_u32(vt_node, "yres", &pdata->vtiming->yres);
+    }
+    wins_arr_node = of_get_child_by_name(np, "wins_array");
+    if(NULL != wins_arr_node)
+    {+        struct device_node *child;
+        int j = 0;
+        for_each_child_of_node(wins_arr_node, child)
+        {+            pdata->win[j] = kzalloc(sizeof(struct s3c_fb_pd_win), GFP_KERNEL);
+            of_property_read_u16(child, "xres", &pdata->win[j]->xres);
+            of_property_read_u16(child, "yres", &pdata->win[j]->yres);
+            of_property_read_u16(child, "virtual_x", &pdata->win[j]->virtual_x);
+            of_property_read_u16(child, "virtual_y", &pdata->win[j]->virtual_y);
+            of_property_read_u16(child, "max_bpp", &pdata->win[j]->max_bpp);
+            of_property_read_u16(child, "default_bpp", &pdata->win[j]->default_bpp);
+            j++;
+        }
+    }
+
+    pdata->setup_gpio = setup_lcd_pin_cfg;
+
+    return 0;
+}
+
+static struct s3c_fb_platdata * of_get_s3_fb_lcd(const struct device_node *node,
+        const char *name)
+{+    struct device_node *def_lcd_node = NULL;
+    struct s3c_fb_platdata *pdata = NULL;
+    int err = 0;
+
+    def_lcd_node = of_get_child_by_name(node, name);
+    if(NULL != def_lcd_node)
+    {+        pdata = kzalloc(sizeof(struct s3c_fb_platdata), GFP_KERNEL);
+        if(!pdata)
+            goto err_out;
+
+        err = of_parse_fimd_def_lcd(def_lcd_node, pdata);
+        if(err)
+        {+            goto err_out;
+        }
+
+        return pdata;
+    }
+
+err_out:
+    if(pdata)
+    {+        kfree(pdata);
+        pdata = NULL;
+    }
+    return NULL;
+}
+
+
+
#define VALID_BPP124 (VALID_BPP(1) | VALID_BPP(2) | VALID_BPP(4))
#define VALID_BPP1248 (VALID_BPP124 | VALID_BPP(8))
@@ -1714,6 +2142,64 @@ static int s3c_fb_runtime_resume(struct device *dev)},
};
+static struct s3c_fb_win_variant s3c_fb_data_s5p_wins[] = {+    [0] = {+        .has_osd_c    = 1,
+        .osd_size_off    = 0x8,
+        .palette_sz    = 256,
+        .valid_bpp    = (VALID_BPP1248 | VALID_BPP(13) |
+                   VALID_BPP(15) | VALID_BPP(16) |
+                   VALID_BPP(18) | VALID_BPP(19) |
+                   VALID_BPP(24) | VALID_BPP(25) |
+                   VALID_BPP(32)),
+    },
+    [1] = {+        .has_osd_c    = 1,
+        .has_osd_d    = 1,
+        .osd_size_off    = 0xc,
+        .has_osd_alpha    = 1,
+        .palette_sz    = 256,
+        .valid_bpp    = (VALID_BPP1248 | VALID_BPP(13) |
+                   VALID_BPP(15) | VALID_BPP(16) |
+                   VALID_BPP(18) | VALID_BPP(19) |
+                   VALID_BPP(24) | VALID_BPP(25) |
+                   VALID_BPP(32)),
+    },
+    [2] = {+        .has_osd_c    = 1,
+        .has_osd_d    = 1,
+        .osd_size_off    = 0xc,
+        .has_osd_alpha    = 1,
+        .palette_sz    = 256,
+        .valid_bpp    = (VALID_BPP1248 | VALID_BPP(13) |
+                   VALID_BPP(15) | VALID_BPP(16) |
+                   VALID_BPP(18) | VALID_BPP(19) |
+                   VALID_BPP(24) | VALID_BPP(25) |
+                   VALID_BPP(32)),
+    },
+    [3] = {+        .has_osd_c    = 1,
+        .has_osd_alpha    = 1,
+        .palette_sz    = 256,
+        .valid_bpp    = (VALID_BPP1248 | VALID_BPP(13) |
+                   VALID_BPP(15) | VALID_BPP(16) |
+                   VALID_BPP(18) | VALID_BPP(19) |
+                   VALID_BPP(24) | VALID_BPP(25) |
+                   VALID_BPP(32)),
+    },
+    [4] = {+        .has_osd_c    = 1,
+        .has_osd_alpha    = 1,
+        .palette_sz    = 256,
+        .valid_bpp    = (VALID_BPP1248 | VALID_BPP(13) |
+                   VALID_BPP(15) | VALID_BPP(16) |
+                   VALID_BPP(18) | VALID_BPP(19) |
+                   VALID_BPP(24) | VALID_BPP(25) |
+                   VALID_BPP(32)),
+    },
+};
+
+
static struct s3c_fb_driverdata s3c_fb_data_64xx = {.variant = {.nr_windows    = 5,
@@ -1781,6 +2267,46 @@ static int s3c_fb_runtime_resume(struct device *dev)VALID_BPP(28)),},
};
+static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {+    .variant = {+        .nr_windows = 5,
+        .vidtcon    = VIDTCON0,
+        .wincon     = WINCON(0),
+        .winmap     = WINxMAP(0),
+        .keycon     = WKEYCON,
+        .osd        = VIDOSD_BASE,
+        .osd_stride = 16,
+        .buf_start    = VIDW_BUF_START(0),
+        .buf_size    = VIDW_BUF_SIZE(0),
+        .buf_end    = VIDW_BUF_END(0),
+
+        .palette = {+            [0] = 0x2400,
+            [1] = 0x2800,
+            [2] = 0x2c00,
+            [3] = 0x3000,
+            [4] = 0x3400,
+        },
+
+        .has_shadowcon    = 1,
+        .has_blendcon    = 1,
+        .has_fixvclk    = 1,
+    },
+    .win[0] = &s3c_fb_data_s5p_wins[0],
+    .win[1] = &s3c_fb_data_s5p_wins[1],
+    .win[2] = &s3c_fb_data_s5p_wins[2],
+    .win[3] = &s3c_fb_data_s5p_wins[3],
+    .win[4] = &s3c_fb_data_s5p_wins[4],
+};
+
+
+static const struct of_device_id s3c_fb_of_match[] = {+    { .compatible = "samsung,exynos4-fb",
+      .data = &s3c_fb_data_exynos4 },
+    {},
+};
+MODULE_DEVICE_TABLE(of, s3c_fb_of_match);
+#endif
static const struct platform_device_id s3c_fb_driver_ids[] = {{@@ -1789,6 +2315,9 @@ static int s3c_fb_runtime_resume(struct device *dev)}, {.name        = "s3c2443-fb",.driver_data    = (unsigned long)&s3c_fb_data_s3c2443,
+    },{+        .name        = "exynos4-fb",
+        .driver_data    = (unsigned long)&s3c_fb_data_exynos4,},{},
};
@@ -1807,6 +2336,7 @@ static int s3c_fb_runtime_resume(struct device *dev).driver        = {.name    = "s3c-fb",.pm    = &s3cfb_pm_ops,
+        .of_match_table = s3c_fb_of_match,},
};
diff --git a/include/dt-bindings/video/samsung_fimd.h b/include/dt-bindings/video/samsung_fimd.h
new file mode 100644
index 0000000..d8fc96e
--- /dev/null
+++ b/include/dt-bindings/video/samsung_fimd.h
@@ -0,0 +1,477 @@
+/* include/video/samsung_fimd.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - new-style fimd and framebuffer register definitions
+ *
+ * This is the register set for the fimd and new style framebuffer interface
+ * found from the S3C2443 onwards into the S3C2416, S3C2450, the
+ * S3C64XX series such as the S3C6400 and S3C6410, and EXYNOS series.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* VIDCON0 */
+
+#define VIDCON0                    0x00
+#define VIDCON0_DSI_EN                (1 << 30)
+#define VIDCON0_INTERLACE            (1 << 29)
+#define VIDCON0_VIDOUT_MASK            (0x7 << 26)
+#define VIDCON0_VIDOUT_SHIFT            26
+#define VIDCON0_VIDOUT_RGB            (0x0 << 26)
+#define VIDCON0_VIDOUT_TV            (0x1 << 26)
+#define VIDCON0_VIDOUT_I80_LDI0            (0x2 << 26)
+#define VIDCON0_VIDOUT_I80_LDI1            (0x3 << 26)
+#define VIDCON0_VIDOUT_WB_RGB            (0x4 << 26)
+#define VIDCON0_VIDOUT_WB_I80_LDI0        (0x6 << 26)
+#define VIDCON0_VIDOUT_WB_I80_LDI1        (0x7 << 26)
+
+#define VIDCON0_L1_DATA_MASK            (0x7 << 23)
+#define VIDCON0_L1_DATA_SHIFT            23
+#define VIDCON0_L1_DATA_16BPP            (0x0 << 23)
+#define VIDCON0_L1_DATA_18BPP16            (0x1 << 23)
+#define VIDCON0_L1_DATA_18BPP9            (0x2 << 23)
+#define VIDCON0_L1_DATA_24BPP            (0x3 << 23)
+#define VIDCON0_L1_DATA_18BPP            (0x4 << 23)
+#define VIDCON0_L1_DATA_16BPP8            (0x5 << 23)
+
+#define VIDCON0_L0_DATA_MASK            (0x7 << 20)
+#define VIDCON0_L0_DATA_SHIFT            20
+#define VIDCON0_L0_DATA_16BPP            (0x0 << 20)
+#define VIDCON0_L0_DATA_18BPP16            (0x1 << 20)
+#define VIDCON0_L0_DATA_18BPP9            (0x2 << 20)
+#define VIDCON0_L0_DATA_24BPP            (0x3 << 20)
+#define VIDCON0_L0_DATA_18BPP            (0x4 << 20)
+#define VIDCON0_L0_DATA_16BPP8            (0x5 << 20)
+
+#define VIDCON0_PNRMODE_MASK            (0x3 << 17)
+#define VIDCON0_PNRMODE_SHIFT            17
+#define VIDCON0_PNRMODE_RGB            (0x0 << 17)
+#define VIDCON0_PNRMODE_BGR            (0x1 << 17)
+#define VIDCON0_PNRMODE_SERIAL_RGB        (0x2 << 17)
+#define VIDCON0_PNRMODE_SERIAL_BGR        (0x3 << 17)
+
+#define VIDCON0_CLKVALUP            (1 << 16)
+#define VIDCON0_CLKVAL_F_MASK            (0xff << 6)
+#define VIDCON0_CLKVAL_F_SHIFT            6
+#define VIDCON0_CLKVAL_F_LIMIT            0xff
+#define VIDCON0_CLKVAL_F(_x)            ((_x) << 6)
+#define VIDCON0_VLCKFREE            (1 << 5)
+#define VIDCON0_CLKDIR                (1 << 4)
+
+#define VIDCON0_CLKSEL_MASK            (0x3 << 2)
+#define VIDCON0_CLKSEL_SHIFT            2
+#define VIDCON0_CLKSEL_HCLK            (0x0 << 2)
+#define VIDCON0_CLKSEL_LCD            (0x1 << 2)
+#define VIDCON0_CLKSEL_27M            (0x3 << 2)
+
+#define VIDCON0_ENVID                (1 << 1)
+#define VIDCON0_ENVID_F                (1 << 0)
+
+#define VIDCON1                    0x04
+#define VIDCON1_LINECNT_MASK            (0x7ff << 16)
+#define VIDCON1_LINECNT_SHIFT            16
+#define VIDCON1_LINECNT_GET(_v)            (((_v) >> 16) & 0x7ff)
+#define VIDCON1_FSTATUS_EVEN            (1 << 15)
+#define VIDCON1_VSTATUS_MASK            (0x3 << 13)
+#define VIDCON1_VSTATUS_SHIFT            13
+#define VIDCON1_VSTATUS_VSYNC            (0x0 << 13)
+#define VIDCON1_VSTATUS_BACKPORCH        (0x1 << 13)
+#define VIDCON1_VSTATUS_ACTIVE            (0x2 << 13)
+#define VIDCON1_VSTATUS_FRONTPORCH        (0x3 << 13)
+#define VIDCON1_VCLK_MASK            (0x3 << 9)
+#define VIDCON1_VCLK_HOLD            (0x0 << 9)
+#define VIDCON1_VCLK_RUN            (0x1 << 9)
+
+#define VIDCON1_INV_VCLK            (1 << 7)
+#define VIDCON1_INV_HSYNC            (1 << 6)
+#define VIDCON1_INV_VSYNC            (1 << 5)
+#define VIDCON1_INV_VDEN            (1 << 4)
+
+/* VIDCON2 */
+
+#define VIDCON2                    0x08
+#define VIDCON2_EN601                (1 << 23)
+#define VIDCON2_TVFMTSEL_SW            (1 << 14)
+
+#define VIDCON2_TVFMTSEL1_MASK            (0x3 << 12)
+#define VIDCON2_TVFMTSEL1_SHIFT            12
+#define VIDCON2_TVFMTSEL1_RGB            (0x0 << 12)
+#define VIDCON2_TVFMTSEL1_YUV422        (0x1 << 12)
+#define VIDCON2_TVFMTSEL1_YUV444        (0x2 << 12)
+
+#define VIDCON2_ORGYCbCr            (1 << 8)
+#define VIDCON2_YUVORDCrCb            (1 << 7)
+
+/* PRTCON (S3C6410)
+ * Might not be present in the S3C6410 documentation,
+ * but tests prove it's there almost for sure; shouldn't hurt in any case.
+ */
+#define PRTCON                    0x0c
+#define PRTCON_PROTECT                (1 << 11)
+
+/* VIDTCON0 */
+
+#define VIDTCON0                0x10
+#define VIDTCON0_VBPDE_MASK            (0xff << 24)
+#define VIDTCON0_VBPDE_SHIFT            24
+#define VIDTCON0_VBPDE_LIMIT            0xff
+#define VIDTCON0_VBPDE(_x)            ((_x) << 24)
+
+#define VIDTCON0_VBPD_MASK            (0xff << 16)
+#define VIDTCON0_VBPD_SHIFT            16
+#define VIDTCON0_VBPD_LIMIT            0xff
+#define VIDTCON0_VBPD(_x)            ((_x) << 16)
+
+#define VIDTCON0_VFPD_MASK            (0xff << 8)
+#define VIDTCON0_VFPD_SHIFT            8
+#define VIDTCON0_VFPD_LIMIT            0xff
+#define VIDTCON0_VFPD(_x)            ((_x) << 8)
+
+#define VIDTCON0_VSPW_MASK            (0xff << 0)
+#define VIDTCON0_VSPW_SHIFT            0
+#define VIDTCON0_VSPW_LIMIT            0xff
+#define VIDTCON0_VSPW(_x)            ((_x) << 0)
+
+/* VIDTCON1 */
+
+#define VIDTCON1                0x14
+#define VIDTCON1_VFPDE_MASK            (0xff << 24)
+#define VIDTCON1_VFPDE_SHIFT            24
+#define VIDTCON1_VFPDE_LIMIT            0xff
+#define VIDTCON1_VFPDE(_x)            ((_x) << 24)
+
+#define VIDTCON1_HBPD_MASK            (0xff << 16)
+#define VIDTCON1_HBPD_SHIFT            16
+#define VIDTCON1_HBPD_LIMIT            0xff
+#define VIDTCON1_HBPD(_x)            ((_x) << 16)
+
+#define VIDTCON1_HFPD_MASK            (0xff << 8)
+#define VIDTCON1_HFPD_SHIFT            8
+#define VIDTCON1_HFPD_LIMIT            0xff
+#define VIDTCON1_HFPD(_x)            ((_x) << 8)
+
+#define VIDTCON1_HSPW_MASK            (0xff << 0)
+#define VIDTCON1_HSPW_SHIFT            0
+#define VIDTCON1_HSPW_LIMIT            0xff
+#define VIDTCON1_HSPW(_x)            ((_x) << 0)
+
+#define VIDTCON2                0x18
+#define VIDTCON2_LINEVAL_E(_x)            ((((_x) & 0x800) >> 11) << 23)
+#define VIDTCON2_LINEVAL_MASK            (0x7ff << 11)
+#define VIDTCON2_LINEVAL_SHIFT            11
+#define VIDTCON2_LINEVAL_LIMIT            0x7ff
+#define VIDTCON2_LINEVAL(_x)            (((_x) & 0x7ff) << 11)
+
+#define VIDTCON2_HOZVAL_E(_x)            ((((_x) & 0x800) >> 11) << 22)
+#define VIDTCON2_HOZVAL_MASK            (0x7ff << 0)
+#define VIDTCON2_HOZVAL_SHIFT            0
+#define VIDTCON2_HOZVAL_LIMIT            0x7ff
+#define VIDTCON2_HOZVAL(_x)            (((_x) & 0x7ff) << 0)
+
+/* WINCONx */
+
+#define WINCON(_win)                (0x20 + ((_win) * 4))
+#define WINCONx_CSCCON_EQ601            (0x0 << 28)
+#define WINCONx_CSCCON_EQ709            (0x1 << 28)
+#define WINCONx_CSCWIDTH_MASK            (0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT            26
+#define WINCONx_CSCWIDTH_WIDE            (0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW            (0x3 << 26)
+#define WINCONx_ENLOCAL                (1 << 22)
+#define WINCONx_BUFSTATUS            (1 << 21)
+#define WINCONx_BUFSEL                (1 << 20)
+#define WINCONx_BUFAUTOEN            (1 << 19)
+#define WINCONx_BITSWP                (1 << 18)
+#define WINCONx_BYTSWP                (1 << 17)
+#define WINCONx_HAWSWP                (1 << 16)
+#define WINCONx_WSWP                (1 << 15)
+#define WINCONx_YCbCr                (1 << 13)
+#define WINCONx_BURSTLEN_MASK            (0x3 << 9)
+#define WINCONx_BURSTLEN_SHIFT            9
+#define WINCONx_BURSTLEN_16WORD            (0x0 << 9)
+#define WINCONx_BURSTLEN_8WORD            (0x1 << 9)
+#define WINCONx_BURSTLEN_4WORD            (0x2 << 9)
+#define WINCONx_ENWIN                (1 << 0)
+
+#define WINCON0_BPPMODE_MASK            (0xf << 2)
+#define WINCON0_BPPMODE_SHIFT            2
+#define WINCON0_BPPMODE_1BPP            (0x0 << 2)
+#define WINCON0_BPPMODE_2BPP            (0x1 << 2)
+#define WINCON0_BPPMODE_4BPP            (0x2 << 2)
+#define WINCON0_BPPMODE_8BPP_PALETTE        (0x3 << 2)
+#define WINCON0_BPPMODE_16BPP_565        (0x5 << 2)
+#define WINCON0_BPPMODE_16BPP_1555        (0x7 << 2)
+#define WINCON0_BPPMODE_18BPP_666        (0x8 << 2)
+#define WINCON0_BPPMODE_24BPP_888        (0xb << 2)
+
+#define WINCON1_LOCALSEL_CAMIF            (1 << 23)
+#define WINCON1_BLD_PIX                (1 << 6)
+#define WINCON1_BPPMODE_MASK            (0xf << 2)
+#define WINCON1_BPPMODE_SHIFT            2
+#define WINCON1_BPPMODE_1BPP            (0x0 << 2)
+#define WINCON1_BPPMODE_2BPP            (0x1 << 2)
+#define WINCON1_BPPMODE_4BPP            (0x2 << 2)
+#define WINCON1_BPPMODE_8BPP_PALETTE        (0x3 << 2)
+#define WINCON1_BPPMODE_8BPP_1232        (0x4 << 2)
+#define WINCON1_BPPMODE_16BPP_565        (0x5 << 2)
+#define WINCON1_BPPMODE_16BPP_A1555        (0x6 << 2)
+#define WINCON1_BPPMODE_16BPP_I1555        (0x7 << 2)
+#define WINCON1_BPPMODE_18BPP_666        (0x8 << 2)
+#define WINCON1_BPPMODE_18BPP_A1665        (0x9 << 2)
+#define WINCON1_BPPMODE_19BPP_A1666        (0xa << 2)
+#define WINCON1_BPPMODE_24BPP_888        (0xb << 2)
+#define WINCON1_BPPMODE_24BPP_A1887        (0xc << 2)
+#define WINCON1_BPPMODE_25BPP_A1888        (0xd << 2)
+#define WINCON1_BPPMODE_28BPP_A4888        (0xd << 2)
+#define WINCON1_ALPHA_SEL            (1 << 1)
+
+/* S5PV210 */
+#define SHADOWCON                0x34
+#define SHADOWCON_WINx_PROTECT(_win)        (1 << (10 + (_win)))
+/* DMA channels (all windows) */
+#define SHADOWCON_CHx_ENABLE(_win)        (1 << (_win))
+/* Local input channels (windows 0-2) */
+#define SHADOWCON_CHx_LOCAL_ENABLE(_win)    (1 << (5 + (_win)))
+
+/* VIDOSDx */
+
+#define VIDOSD_BASE                0x40
+#define VIDOSDxA_TOPLEFT_X_E(_x)        ((((_x) & 0x800) >> 11) << 23)
+#define VIDOSDxA_TOPLEFT_X_MASK            (0x7ff << 11)
+#define VIDOSDxA_TOPLEFT_X_SHIFT        11
+#define VIDOSDxA_TOPLEFT_X_LIMIT        0x7ff
+#define VIDOSDxA_TOPLEFT_X(_x)            (((_x) & 0x7ff) << 11)
+
+#define VIDOSDxA_TOPLEFT_Y_E(_x)        ((((_x) & 0x800) >> 11) << 22)
+#define VIDOSDxA_TOPLEFT_Y_MASK            (0x7ff << 0)
+#define VIDOSDxA_TOPLEFT_Y_SHIFT        0
+#define VIDOSDxA_TOPLEFT_Y_LIMIT        0x7ff
+#define VIDOSDxA_TOPLEFT_Y(_x)            (((_x) & 0x7ff) << 0)
+
+#define VIDOSDxB_BOTRIGHT_X_E(_x)        ((((_x) & 0x800) >> 11) << 23)
+#define VIDOSDxB_BOTRIGHT_X_MASK        (0x7ff << 11)
+#define VIDOSDxB_BOTRIGHT_X_SHIFT        11
+#define VIDOSDxB_BOTRIGHT_X_LIMIT        0x7ff
+#define VIDOSDxB_BOTRIGHT_X(_x)            (((_x) & 0x7ff) << 11)
+
+#define VIDOSDxB_BOTRIGHT_Y_E(_x)        ((((_x) & 0x800) >> 11) << 22)
+#define VIDOSDxB_BOTRIGHT_Y_MASK        (0x7ff << 0)
+#define VIDOSDxB_BOTRIGHT_Y_SHIFT        0
+#define VIDOSDxB_BOTRIGHT_Y_LIMIT        0x7ff
+#define VIDOSDxB_BOTRIGHT_Y(_x)            (((_x) & 0x7ff) << 0)
+
+/* For VIDOSD[1..4]C */
+#define VIDISD14C_ALPHA0_R(_x)            ((_x) << 20)
+#define VIDISD14C_ALPHA0_G_MASK            (0xf << 16)
+#define VIDISD14C_ALPHA0_G_SHIFT        16
+#define VIDISD14C_ALPHA0_G_LIMIT        0xf
+#define VIDISD14C_ALPHA0_G(_x)            ((_x) << 16)
+#define VIDISD14C_ALPHA0_B_MASK            (0xf << 12)
+#define VIDISD14C_ALPHA0_B_SHIFT        12
+#define VIDISD14C_ALPHA0_B_LIMIT        0xf
+#define VIDISD14C_ALPHA0_B(_x)            ((_x) << 12)
+#define VIDISD14C_ALPHA1_R_MASK            (0xf << 8)
+#define VIDISD14C_ALPHA1_R_SHIFT        8
+#define VIDISD14C_ALPHA1_R_LIMIT        0xf
+#define VIDISD14C_ALPHA1_R(_x)            ((_x) << 8)
+#define VIDISD14C_ALPHA1_G_MASK            (0xf << 4)
+#define VIDISD14C_ALPHA1_G_SHIFT        4
+#define VIDISD14C_ALPHA1_G_LIMIT        0xf
+#define VIDISD14C_ALPHA1_G(_x)            ((_x) << 4)
+#define VIDISD14C_ALPHA1_B_MASK            (0xf << 0)
+#define VIDISD14C_ALPHA1_B_SHIFT        0
+#define VIDISD14C_ALPHA1_B_LIMIT        0xf
+#define VIDISD14C_ALPHA1_B(_x)            ((_x) << 0)
+
+#define VIDW_ALPHA                0x021c
+#define VIDW_ALPHA_R(_x)            ((_x) << 16)
+#define VIDW_ALPHA_G(_x)            ((_x) << 8)
+#define VIDW_ALPHA_B(_x)            ((_x) << 0)
+
+/* Video buffer addresses */
+#define VIDW_BUF_START(_buff)            (0xA0 + ((_buff) * 8))
+#define VIDW_BUF_START_S(_buff)            (0x40A0 + ((_buff) * 8))
+#define VIDW_BUF_START1(_buff)            (0xA4 + ((_buff) * 8))
+#define VIDW_BUF_END(_buff)            (0xD0 + ((_buff) * 8))
+#define VIDW_BUF_END1(_buff)            (0xD4 + ((_buff) * 8))
+#define VIDW_BUF_SIZE(_buff)            (0x100 + ((_buff) * 4))
+
+#define VIDW_BUF_SIZE_OFFSET_E(_x)        ((((_x) & 0x2000) >> 13) << 27)
+#define VIDW_BUF_SIZE_OFFSET_MASK        (0x1fff << 13)
+#define VIDW_BUF_SIZE_OFFSET_SHIFT        13
+#define VIDW_BUF_SIZE_OFFSET_LIMIT        0x1fff
+#define VIDW_BUF_SIZE_OFFSET(_x)        (((_x) & 0x1fff) << 13)
+
+#define VIDW_BUF_SIZE_PAGEWIDTH_E(_x)        ((((_x) & 0x2000) >> 13) << 26)
+#define VIDW_BUF_SIZE_PAGEWIDTH_MASK        (0x1fff << 0)
+#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT        0
+#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT        0x1fff
+#define VIDW_BUF_SIZE_PAGEWIDTH(_x)        (((_x) & 0x1fff) << 0)
+
+/* Interrupt controls and status */
+
+#define VIDINTCON0                0x130
+#define VIDINTCON0_FIFOINTERVAL_MASK        (0x3f << 20)
+#define VIDINTCON0_FIFOINTERVAL_SHIFT        20
+#define VIDINTCON0_FIFOINTERVAL_LIMIT        0x3f
+#define VIDINTCON0_FIFOINTERVAL(_x)        ((_x) << 20)
+
+#define VIDINTCON0_INT_SYSMAINCON        (1 << 19)
+#define VIDINTCON0_INT_SYSSUBCON        (1 << 18)
+#define VIDINTCON0_INT_I80IFDONE        (1 << 17)
+
+#define VIDINTCON0_FRAMESEL0_MASK        (0x3 << 15)
+#define VIDINTCON0_FRAMESEL0_SHIFT        15
+#define VIDINTCON0_FRAMESEL0_BACKPORCH        (0x0 << 15)
+#define VIDINTCON0_FRAMESEL0_VSYNC        (0x1 << 15)
+#define VIDINTCON0_FRAMESEL0_ACTIVE        (0x2 << 15)
+#define VIDINTCON0_FRAMESEL0_FRONTPORCH        (0x3 << 15)
+
+#define VIDINTCON0_FRAMESEL1            (1 << 13)
+#define VIDINTCON0_FRAMESEL1_MASK        (0x3 << 13)
+#define VIDINTCON0_FRAMESEL1_NONE        (0x0 << 13)
+#define VIDINTCON0_FRAMESEL1_BACKPORCH        (0x1 << 13)
+#define VIDINTCON0_FRAMESEL1_VSYNC        (0x2 << 13)
+#define VIDINTCON0_FRAMESEL1_FRONTPORCH        (0x3 << 13)
+
+#define VIDINTCON0_INT_FRAME            (1 << 12)
+#define VIDINTCON0_FIFIOSEL_MASK        (0x7f << 5)
+#define VIDINTCON0_FIFIOSEL_SHIFT        5
+#define VIDINTCON0_FIFIOSEL_WINDOW0        (0x1 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW1        (0x2 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW2        (0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3        (0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4        (0x40 << 5)
+
+#define VIDINTCON0_FIFOLEVEL_MASK        (0x7 << 2)
+#define VIDINTCON0_FIFOLEVEL_SHIFT        2
+#define VIDINTCON0_FIFOLEVEL_TO25PC        (0x0 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO50PC        (0x1 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO75PC        (0x2 << 2)
+#define VIDINTCON0_FIFOLEVEL_EMPTY        (0x3 << 2)
+#define VIDINTCON0_FIFOLEVEL_FULL        (0x4 << 2)
+
+#define VIDINTCON0_INT_FIFO_MASK        (0x3 << 0)
+#define VIDINTCON0_INT_FIFO_SHIFT        0
+#define VIDINTCON0_INT_ENABLE            (1 << 0)
+
+#define VIDINTCON1                0x134
+#define VIDINTCON1_INT_I80            (1 << 2)
+#define VIDINTCON1_INT_FRAME            (1 << 1)
+#define VIDINTCON1_INT_FIFO            (1 << 0)
+
+/* Window colour-key control registers */
+#define WKEYCON                    0x140
+
+#define WKEYCON0                0x00
+#define WKEYCON1                0x04
+
+#define WxKEYCON0_KEYBL_EN            (1 << 26)
+#define WxKEYCON0_KEYEN_F            (1 << 25)
+#define WxKEYCON0_DIRCON            (1 << 24)
+#define WxKEYCON0_COMPKEY_MASK            (0xffffff << 0)
+#define WxKEYCON0_COMPKEY_SHIFT            0
+#define WxKEYCON0_COMPKEY_LIMIT            0xffffff
+#define WxKEYCON0_COMPKEY(_x)            ((_x) << 0)
+#define WxKEYCON1_COLVAL_MASK            (0xffffff << 0)
+#define WxKEYCON1_COLVAL_SHIFT            0
+#define WxKEYCON1_COLVAL_LIMIT            0xffffff
+#define WxKEYCON1_COLVAL(_x)            ((_x) << 0)
+
+/* Dithering control */
+#define DITHMODE                0x170
+#define DITHMODE_R_POS_MASK            (0x3 << 5)
+#define DITHMODE_R_POS_SHIFT            5
+#define DITHMODE_R_POS_8BIT            (0x0 << 5)
+#define DITHMODE_R_POS_6BIT            (0x1 << 5)
+#define DITHMODE_R_POS_5BIT            (0x2 << 5)
+#define DITHMODE_G_POS_MASK            (0x3 << 3)
+#define DITHMODE_G_POS_SHIFT            3
+#define DITHMODE_G_POS_8BIT            (0x0 << 3)
+#define DITHMODE_G_POS_6BIT            (0x1 << 3)
+#define DITHMODE_G_POS_5BIT            (0x2 << 3)
+#define DITHMODE_B_POS_MASK            (0x3 << 1)
+#define DITHMODE_B_POS_SHIFT            1
+#define DITHMODE_B_POS_8BIT            (0x0 << 1)
+#define DITHMODE_B_POS_6BIT            (0x1 << 1)
+#define DITHMODE_B_POS_5BIT            (0x2 << 1)
+#define DITHMODE_DITH_EN            (1 << 0)
+
+/* Window blanking (MAP) */
+#define WINxMAP(_win)                (0x180 + ((_win) * 4))
+#define WINxMAP_MAP                (1 << 24)
+#define WINxMAP_MAP_COLOUR_MASK            (0xffffff << 0)
+#define WINxMAP_MAP_COLOUR_SHIFT        0
+#define WINxMAP_MAP_COLOUR_LIMIT        0xffffff
+#define WINxMAP_MAP_COLOUR(_x)            ((_x) << 0)
+
+/* Winodw palette control */
+#define WPALCON                    0x1A0
+#define WPALCON_PAL_UPDATE            (1 << 9)
+#define WPALCON_W4PAL_16BPP_A555        (1 << 8)
+#define WPALCON_W3PAL_16BPP_A555        (1 << 7)
+#define WPALCON_W2PAL_16BPP_A555        (1 << 6)
+#define WPALCON_W1PAL_MASK            (0x7 << 3)
+#define WPALCON_W1PAL_SHIFT            3
+#define WPALCON_W1PAL_25BPP_A888        (0x0 << 3)
+#define WPALCON_W1PAL_24BPP            (0x1 << 3)
+#define WPALCON_W1PAL_19BPP_A666        (0x2 << 3)
+#define WPALCON_W1PAL_18BPP_A665        (0x3 << 3)
+#define WPALCON_W1PAL_18BPP            (0x4 << 3)
+#define WPALCON_W1PAL_16BPP_A555        (0x5 << 3)
+#define WPALCON_W1PAL_16BPP_565            (0x6 << 3)
+#define WPALCON_W0PAL_MASK            (0x7 << 0)
+#define WPALCON_W0PAL_SHIFT            0
+#define WPALCON_W0PAL_25BPP_A888        (0x0 << 0)
+#define WPALCON_W0PAL_24BPP            (0x1 << 0)
+#define WPALCON_W0PAL_19BPP_A666        (0x2 << 0)
+#define WPALCON_W0PAL_18BPP_A665        (0x3 << 0)
+#define WPALCON_W0PAL_18BPP            (0x4 << 0)
+#define WPALCON_W0PAL_16BPP_A555        (0x5 << 0)
+#define WPALCON_W0PAL_16BPP_565            (0x6 << 0)
+
+/* Blending equation control */
+#define BLENDCON                0x260
+#define BLENDCON_NEW_MASK            (1 << 0)
+#define BLENDCON_NEW_8BIT_ALPHA_VALUE        (1 << 0)
+#define BLENDCON_NEW_4BIT_ALPHA_VALUE        (0 << 0)
+
+/* Display port clock control */
+#define DP_MIE_CLKCON                0x27c
+#define DP_MIE_CLK_DISABLE            0x0
+#define DP_MIE_CLK_DP_ENABLE            0x2
+#define DP_MIE_CLK_MIE_ENABLE            0x3
+
+/* Notes on per-window bpp settings
+ *
+ * Value    Win0     Win1      Win2       Win3        Win 4
+ * 0000        1(P)     1(P)      1(P)       1(P)        1(P)
+ * 0001        2(P)     2(P)     2(P)       2(P)        2(P)
+ * 0010        4(P)     4(P)     4(P)       4(P)     -none-
+ * 0011        8(P)     8(P)     -none-   -none-   -none-
+ * 0100        -none-     8(A232)  8(A232)  -none-   -none-
+ * 0101        16(565)     16(565)  16(565)  16(565)   16(565)
+ * 0110        -none-     16(A555) 16(A555) 16(A555)  16(A555)
+ * 0111        16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
+ * 1000        18(666)     18(666)  18(666)  18(666)   18(666)
+ * 1001        -none-     18(A665) 18(A665) 18(A665)  16(A665)
+ * 1010        -none-     19(A666) 19(A666) 19(A666)  19(A666)
+ * 1011        24(888)     24(888)  24(888)  24(888)   24(888)
+ * 1100        -none-     24(A887) 24(A887) 24(A887)  24(A887)
+ * 1101        -none-     25(A888) 25(A888) 25(A888)  25(A888)
+ * 1110        -none-     -none-      -none-   -none-    -none-
+ * 1111        -none-     -none-   -none-   -none-    -none-
+*/
+
+/* FIMD Version 8 register offset definitions */
+#define FIMD_V8_VIDTCON0    0x20010
+#define FIMD_V8_VIDTCON1    0x20014
+#define FIMD_V8_VIDTCON2    0x20018
+#define FIMD_V8_VIDTCON3    0x2001C
+#define FIMD_V8_VIDCON1        0x20004
diff --git a/include/linux/platform_data/video_s3c.h b/include/linux/platform_data/video_s3c.h
old mode 100644
new mode 100755
index dd7747b..48f8687
--- a/include/linux/platform_data/video_s3c.h
+++ b/include/linux/platform_data/video_s3c.h
@@ -23,6 +23,9 @@ struct s3c_fb_pd_win {unsigned short        yres;unsigned short        virtual_x;unsigned short        virtual_y;
+    unsigned short        width;
+    unsigned short        height;
+
};

tiny4412 linux-4.2 移植(十一)LCD驱动移植相关推荐

  1. STM32MP157 Linux系统移植开发篇14:Linux内核RGB LCD驱动移植

    本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...

  2. [lcm] Qualcomm平台的显示屏lcd驱动移植步骤

    1lk部分 1-1 target_displayc 1-2 oem_panelc 1-3 panel_innont51021b_1200p_videoh 2Kernel 2-1 dsi-panel-b ...

  3. linux在开发板LCD上显,W35型LCD驱动移植 - linux-2.6.32在mini2440开发板上移植_Linux编程_Linux公社-Linux系统门户网站...

    编者注:本移植主要步骤还是按照手册来,里面讲解了一些有用的基础知识.但书册上提供了集中屏幕的方案,我们这里主要就用一种,也就是开发板自带的W35型号.液晶驱动的源程序在src/drivers/vide ...

  4. Barebox for Tiny6410(LCD驱动移植)

    一.目的 熟悉Barebox的Frame buffer框架.LCD驱动的移植和测试命令的编写. 二.主要内容 1.1 为Barebox移植基于Tiny6410的LCD驱动. 1.2 编写lcd命令测试 ...

  5. linux-2.6.32在mini2440开发板上移植 ---W35型LCD驱动移植

    转载:http://blog.csdn.net/viewsky11/article/details/11846359 编者注:本移植主要步骤还是按照手册来,里面讲解了一些有用的基础知识.但书册上提供了 ...

  6. LCD驱动移植之开机logo

    移植环境 BootLoader:u-boot-1.1.6 kernel:linux-2.6.30.4 CPU:s3c2440 开发板:TQ2440 LCD:TFT480*272 参考资料:<天嵌 ...

  7. rtthread工业使用_RT-Thread三探--LCD驱动移植(使用GUI Engine)

    既网络之后又一个比较重要的功能--GUI 对于RT-Thread使用的GUI我还没有什么概念,本文只是针对LCD驱动部分的移植,并使用GUI运行本身提供的demo样例. 当然还是和ETH一样,在STM ...

  8. 基于正点原子F103精英板和CubeIDE的Hal库LCD驱动移植(从零开始)

    最近在学习王维波老师的<STM32Cube高效开发教程>,王老师移植的是普中科技的驱动,而我手动移植了一下正点原子的lcd驱动,看了网上的诸多教程,有的博客存在一些bug,于是乎手动整理了 ...

  9. LCD驱动移植(二)

    LCD驱动的话会在MINI2440里是向Plaform注册的一个驱动 Plaform的话可以在网上查查这方面的资料,主要要注意这两个函数,如下: (1)platform_device_register ...

  10. mtk平台lcd驱动移植

    mtk平台lcd驱动分为两个部分:lk和kernel.两部分基本流程相同,除了GPIO操作及头文件. 1. lk:需要修改的目录 vendor/mediatek/proprietary/bootabl ...

最新文章

  1. 【linux】Valgrind工具集详解(二):入门
  2. 三星15TB固态硬盘开卖 售价高达10000美元
  3. 大一java实训报告1500字_从800字小作文,到3000字小论文你用了多久? | 校媒FM
  4. JAVA String 相加编译器发生了什么?
  5. 【云计算 Hadoop】Hadoop 版本 生态圈 MapReduce模型
  6. 《快乐编程大本营》java语言训练班-第4课:java流程控制
  7. MTK:oemlock介绍
  8. nodejs实现的高性能服务器编程,使用NodeJS搭建自己的接口服务器,提交APP的开发效率...
  9. linux lib64被改名,问题解决:Centos误将/lib64更改为lib64.bak
  10. centos5.5中安装mysql5.5.3
  11. 第五十五期:MongoDB数据库误删后的恢复
  12. chrome扩展之3:一步步跟我学开发一个表单填写扩展
  13. 克拉克拉(KilaKila):大规模实时计算平台架构实战 1
  14. 发布了!2020 年 AI 人才发展报告,最高补助 1000 万!
  15. LeetCode 135. 分发糖果(贪心算法)
  16. 数据库面试题之PL/SQL面试题
  17. Apache+tomcat配置集群(1)
  18. 怎么在Linux上抓包分析
  19. 高校校园网络设计与实现
  20. Android 百度地图--定位、周边搜索

热门文章

  1. CNC加工中心程序代码大全,你还不收藏吗?
  2. 用亿图软件怎么画数据模型图?
  3. Python代码整洁之道勘误
  4. Mqtt 客户端 java API 教程
  5. python老男孩scrapy视频刷课记录
  6. Hive 窗口函数lead、lag
  7. 关于ftp 服务器搭建的200错误与527错误
  8. instantclient使用步骤
  9. linux系统双显示器怎么设置复制,Redhat 5.6 双显示器 xorg.conf 设置
  10. Skyline软件二次开发初级——11如何在WEB页面中的三维地图上加载和保存工程文件...