mirror of https://github.com/parazyd/arm-sdk.git
125 lines
3.4 KiB
Diff
125 lines
3.4 KiB
Diff
From 328a31aeb9e4cb56f312be7722010ede59ef96be Mon Sep 17 00:00:00 2001
|
|
From: Tony Lindgren <tony@atomide.com>
|
|
Date: Mon, 24 Jul 2017 19:33:05 +0200
|
|
Subject: [PATCH 08/17] drm/omap: panel-dsi-cm: fix driver
|
|
|
|
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>
|
|
---
|
|
drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 56 ++++++++++++++++++++++---
|
|
1 file changed, 51 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
|
|
index 92c556a..905b717 100644
|
|
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
|
|
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
|
|
@@ -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;
|
|
--
|
|
2.1.4
|
|
|