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>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
Tony Lindgren 2017-07-24 19:33:05 +02:00 committed by Tomi Valkeinen
parent b070d6e84a
commit e128310ddd
1 changed files with 51 additions and 5 deletions

View 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;