Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e128310d authored by Tony Lindgren's avatar Tony Lindgren Committed by Tomi Valkeinen
Browse files

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: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent b070d6e8
Loading
Loading
Loading
Loading
+51 −5
Original line number Diff line number Diff line
@@ -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;