drm/omap: panel-dsi-cm: fix driver
authorTony Lindgren <tony@atomide.com>
Mon, 24 Jul 2017 17:33:05 +0000 (19:33 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Tue, 19 Dec 2017 08:32:00 +0000 (10:32 +0200)
This adds support for get_timings() and check_timings()
to get the driver working and properly initializes the
timing information from DT.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c

index 92c556a..905b717 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/of_gpio.h>
 
 #include <video/mipi_display.h>
+#include <video/of_display_timing.h>
 
 #include "../dss/omapdss.h"
 
@@ -1099,6 +1100,36 @@ static void dsicm_ulps_work(struct work_struct *work)
        mutex_unlock(&ddata->lock);
 }
 
+static void dsicm_get_timings(struct omap_dss_device *dssdev,
+                             struct videomode *vm)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+       *vm = ddata->vm;
+}
+
+static int dsicm_check_timings(struct omap_dss_device *dssdev,
+                              struct videomode *vm)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
+       int ret = 0;
+
+       if (vm->hactive != ddata->vm.hactive)
+               ret = -EINVAL;
+
+       if (vm->vactive != ddata->vm.vactive)
+               ret = -EINVAL;
+
+       if (ret) {
+               dev_warn(dssdev->dev, "wrong resolution: %d x %d",
+                        vm->hactive, vm->vactive);
+               dev_warn(dssdev->dev, "panel resolution: %d x %d",
+                        ddata->vm.hactive, ddata->vm.vactive);
+       }
+
+       return ret;
+}
+
 static struct omap_dss_driver dsicm_ops = {
        .connect        = dsicm_connect,
        .disconnect     = dsicm_disconnect,
@@ -1109,6 +1140,9 @@ static struct omap_dss_driver dsicm_ops = {
        .update         = dsicm_update,
        .sync           = dsicm_sync,
 
+       .get_timings    = dsicm_get_timings,
+       .check_timings  = dsicm_check_timings,
+
        .enable_te      = dsicm_enable_te,
        .get_te         = dsicm_get_te,
 
@@ -1120,7 +1154,8 @@ static int dsicm_probe_of(struct platform_device *pdev)
        struct device_node *node = pdev->dev.of_node;
        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
        struct omap_dss_device *in;
-       int gpio;
+       struct display_timing timing;
+       int gpio, err;
 
        gpio = of_get_named_gpio(node, "reset-gpios", 0);
        if (!gpio_is_valid(gpio)) {
@@ -1137,6 +1172,17 @@ static int dsicm_probe_of(struct platform_device *pdev)
                return gpio;
        }
 
+       err = of_get_display_timing(node, "panel-timing", &timing);
+       if (!err) {
+               videomode_from_timing(&timing, &ddata->vm);
+               if (!ddata->vm.pixelclock)
+                       ddata->vm.pixelclock =
+                               ddata->vm.hactive * ddata->vm.vactive * 60;
+       } else {
+               dev_warn(&pdev->dev,
+                        "failed to get video timing, using defaults\n");
+       }
+
        in = omapdss_of_find_source_for_first_ep(node);
        if (IS_ERR(in)) {
                dev_err(&pdev->dev, "failed to find video source\n");
@@ -1171,14 +1217,14 @@ static int dsicm_probe(struct platform_device *pdev)
        if (!pdev->dev.of_node)
                return -ENODEV;
 
-       r = dsicm_probe_of(pdev);
-       if (r)
-               return r;
-
        ddata->vm.hactive = 864;
        ddata->vm.vactive = 480;
        ddata->vm.pixelclock = 864 * 480 * 60;
 
+       r = dsicm_probe_of(pdev);
+       if (r)
+               return r;
+
        dssdev = &ddata->dssdev;
        dssdev->dev = dev;
        dssdev->driver = &dsicm_ops;