]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/video/mxc/mxc_lcdif.c
video: mxc: use of_get_videomode() to set up the video timing
[karo-tx-linux.git] / drivers / video / mxc / mxc_lcdif.c
index 7235f922aa2254a9d25ce47f42782a15260f9bdd..e18731e238d91dd6cffefeac02a54171c0085e73 100644 (file)
@@ -19,6 +19,9 @@
 #include <linux/of_device.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
+#include <video/of_display_timing.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
 
 #include "mxc_dispdrv.h"
 
@@ -26,10 +29,11 @@ struct mxc_lcd_platform_data {
        u32 default_ifmt;
        u32 ipu_id;
        u32 disp_id;
+       enum display_flags disp_flags;
 };
 
 struct mxc_lcdif_data {
-       struct platform_device *pdev;
+       struct device *dev;
        struct mxc_dispdrv_handle *disp_lcdif;
 };
 
@@ -37,17 +41,104 @@ struct mxc_lcdif_data {
 
 static struct fb_videomode lcdif_modedb[] = {
        {
-       /* 800x480 @ 57 Hz , pixel clk @ 27MHz */
-       "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
-       FB_SYNC_CLK_LAT_FALL,
-       FB_VMODE_NONINTERLACED,
-       0,},
+               /* 800x480 @ 57 Hz , pixel clk @ 27MHz */
+               "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
+               FB_SYNC_CLK_LAT_FALL,
+               FB_VMODE_NONINTERLACED,
+               0,
+       },
+       {
+               /* 800x480 @ 60 Hz , pixel clk @ 32MHz */
+               "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
+               FB_SYNC_CLK_LAT_FALL,
+               FB_VMODE_NONINTERLACED,
+               0,
+       },
+       {
+               .name = "VGA",
+               .pixclock = KHZ2PICOS(25200),
+               .xres = 640,
+               .yres = 480,
+               .left_margin = 48,
+               .hsync_len = 96,
+               .right_margin = 16,
+               .upper_margin = 31,
+               .vsync_len = 2,
+               .lower_margin = 12,
+       },
+       {
+               .name = "ETV570",
+               .pixclock = KHZ2PICOS(25200),
+               .xres = 640,
+               .yres = 480,
+               .left_margin = 114,
+               .hsync_len = 30,
+               .right_margin = 16,
+               .upper_margin = 32,
+               .vsync_len = 3,
+               .lower_margin = 10,
+       },
+       {
+               .name = "ET0350",
+               .pixclock = KHZ2PICOS(6413760 / 1000),
+               .xres = 320,
+               .yres = 240,
+               .left_margin = 34,
+               .hsync_len = 34,
+               .right_margin = 20,
+               .upper_margin = 15,
+               .vsync_len = 3,
+               .lower_margin = 4,
+       },
+       {
+               .name = "ET0430",
+               .pixclock = KHZ2PICOS(9009),
+               .xres = 480,
+               .yres = 272,
+               .left_margin = 2,
+               .hsync_len = 41,
+               .right_margin = 2,
+               .upper_margin = 2,
+               .vsync_len = 10,
+               .lower_margin = 2,
+               .sync = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               .name = "ET0500",
+               .pixclock = KHZ2PICOS(33264),
+               .xres = 800,
+               .yres = 480,
+               .left_margin = 88,
+               .hsync_len = 128,
+               .right_margin = 40,
+               .upper_margin = 33,
+               .vsync_len = 2,
+               .lower_margin = 10,
+       },
+       {
+               .name = "ET0700", /* same as ET0500 */
+               .pixclock = KHZ2PICOS(33264),
+               .xres = 800,
+               .yres = 480,
+               .left_margin = 88,
+               .hsync_len = 128,
+               .right_margin = 40,
+               .upper_margin = 33,
+               .vsync_len = 2,
+               .lower_margin = 10,
+       },
        {
-       /* 800x480 @ 60 Hz , pixel clk @ 32MHz */
-       "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
-       FB_SYNC_CLK_LAT_FALL,
-       FB_VMODE_NONINTERLACED,
-       0,},
+               .name = "ETQ570",
+               .pixclock = KHZ2PICOS(6596040 / 1000),
+               .xres = 320,
+               .yres = 240,
+               .left_margin = 38,
+               .hsync_len = 30,
+               .right_margin = 30,
+               .upper_margin = 16,
+               .vsync_len = 3,
+               .lower_margin = 4,
+       },
 };
 static int lcdif_modedb_sz = ARRAY_SIZE(lcdif_modedb);
 
@@ -56,8 +147,7 @@ static int lcdif_init(struct mxc_dispdrv_handle *disp,
 {
        int ret, i;
        struct mxc_lcdif_data *lcdif = mxc_dispdrv_getdata(disp);
-       struct mxc_lcd_platform_data *plat_data
-                       = lcdif->pdev->dev.platform_data;
+       struct mxc_lcd_platform_data *plat_data = lcdif->dev->platform_data;
        struct fb_videomode *modedb = lcdif_modedb;
        int modedb_sz = lcdif_modedb_sz;
 
@@ -92,35 +182,47 @@ void lcdif_deinit(struct mxc_dispdrv_handle *disp)
 }
 
 static struct mxc_dispdrv_driver lcdif_drv = {
-       .name   = DISPDRV_LCD,
-       .init   = lcdif_init,
+       .name   = DISPDRV_LCD,
+       .init   = lcdif_init,
        .deinit = lcdif_deinit,
 };
 
-static int lcd_get_of_property(struct platform_device *pdev,
+static int lcd_get_of_property(struct device *dev,
                                struct mxc_lcd_platform_data *plat_data)
 {
-       struct device_node *np = pdev->dev.of_node;
+       struct device_node *np = dev->of_node;
        int err;
        u32 ipu_id, disp_id;
        const char *default_ifmt;
 
        err = of_property_read_string(np, "default_ifmt", &default_ifmt);
        if (err) {
-               dev_err(&pdev->dev, "get of property default_ifmt fail\n");
+               dev_err(dev, "get of property default_ifmt fail\n");
                return err;
        }
        err = of_property_read_u32(np, "ipu_id", &ipu_id);
        if (err) {
-               dev_err(&pdev->dev, "get of property ipu_id fail\n");
+               dev_err(dev, "get of property ipu_id fail\n");
                return err;
        }
        err = of_property_read_u32(np, "disp_id", &disp_id);
        if (err) {
-               dev_err(&pdev->dev, "get of property disp_id fail\n");
+               dev_err(dev, "get of property disp_id fail\n");
                return err;
        }
 
+       {
+               struct videomode vm = { };
+
+               err = of_get_videomode(np, &vm, OF_USE_NATIVE_MODE);
+               if (err == 0) {
+                       dev_dbg(dev, "Copying videomode from display-timings\n");
+                       fb_videomode_from_videomode(&vm, &lcdif_modedb[0]);
+                       plat_data->disp_flags = vm.flags;
+                       lcdif_modedb_sz = 1;
+               }
+       }
+
        plat_data->ipu_id = ipu_id;
        plat_data->disp_id = disp_id;
        if (!strncmp(default_ifmt, "RGB24", 5))
@@ -146,7 +248,7 @@ static int lcd_get_of_property(struct platform_device *pdev,
        else if (!strncmp(default_ifmt, "VYUY16", 6))
                                plat_data->default_ifmt = IPU_PIX_FMT_VYUY;
        else {
-               dev_err(&pdev->dev, "err default_ifmt!\n");
+               dev_err(dev, "err default_ifmt!\n");
                return -ENOENT;
        }
 
@@ -172,7 +274,7 @@ static int mxc_lcdif_probe(struct platform_device *pdev)
                return -ENOMEM;
        pdev->dev.platform_data = plat_data;
 
-       ret = lcd_get_of_property(pdev, plat_data);
+       ret = lcd_get_of_property(&pdev->dev, plat_data);
        if (ret < 0) {
                dev_err(&pdev->dev, "get lcd of property fail\n");
                return ret;
@@ -184,7 +286,7 @@ static int mxc_lcdif_probe(struct platform_device *pdev)
                return PTR_ERR(pinctrl);
        }
 
-       lcdif->pdev = pdev;
+       lcdif->dev = &pdev->dev;
        lcdif->disp_lcdif = mxc_dispdrv_register(&lcdif_drv);
        mxc_dispdrv_setdata(lcdif->disp_lcdif, lcdif);
 
@@ -196,7 +298,7 @@ static int mxc_lcdif_probe(struct platform_device *pdev)
 
 static int mxc_lcdif_remove(struct platform_device *pdev)
 {
-       struct mxc_lcdif_data *lcdif = dev_get_drvdata(&pdev->dev);
+       struct mxc_lcdif_data *lcdif = platform_get_drvdata(pdev);
 
        mxc_dispdrv_puthandle(lcdif->disp_lcdif);
        mxc_dispdrv_unregister(lcdif->disp_lcdif);