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

Commit 2ecef246 authored by Tomi Valkeinen's avatar Tomi Valkeinen
Browse files

OMAPDSS: Add DT support to DSS



Add DT support for DSS. Contrary to the non-DT version, the DSS in DT
mode contains DPI and SDI outputs, which better reflects the hardware.
The non-DT code will be removed after all boards have been converted to
DT, so there's no need to change the non-DT code to act the same way.

The code for DPI and SDI needs to be refined later to make it possible
to add multiple DPI ports. For now, handling just a single DPI port is
enough for all the boards.

Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: default avatarArchit Taneja <archit@ti.com>
parent e6fa68ba
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/string.h>
#include <linux/of.h>

#include <video/omapdss.h>

@@ -49,6 +50,8 @@ static struct {
	int data_lines;

	struct omap_dss_device output;

	bool port_initialized;
} dpi;

static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
@@ -726,3 +729,47 @@ void __exit dpi_uninit_platform_driver(void)
{
	platform_driver_unregister(&omap_dpi_driver);
}

int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
{
	struct device_node *ep;
	u32 datalines;
	int r;

	ep = omapdss_of_get_next_endpoint(port, NULL);
	if (!ep)
		return 0;

	r = of_property_read_u32(ep, "data-lines", &datalines);
	if (r) {
		DSSERR("failed to parse datalines\n");
		goto err_datalines;
	}

	dpi.data_lines = datalines;

	of_node_put(ep);

	dpi.pdev = pdev;

	mutex_init(&dpi.lock);

	dpi_init_output(pdev);

	dpi.port_initialized = true;

	return 0;

err_datalines:
	of_node_put(ep);

	return r;
}

void __exit dpi_uninit_port(void)
{
	if (!dpi.port_initialized)
		return;

	dpi_uninit_output(dpi.pdev);
}
+66 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#define DSS_SUBSYS_NAME "DSS"

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/err.h>
@@ -33,6 +34,7 @@
#include <linux/pm_runtime.h>
#include <linux/gfp.h>
#include <linux/sizes.h>
#include <linux/of.h>

#include <video/omapdss.h>

@@ -788,6 +790,56 @@ static int __init dss_init_features(struct platform_device *pdev)
	return 0;
}

static int dss_init_ports(struct platform_device *pdev)
{
	struct device_node *parent = pdev->dev.of_node;
	struct device_node *port;
	int r;

	if (parent == NULL)
		return 0;

	port = omapdss_of_get_next_port(parent, NULL);
	if (!port) {
#ifdef CONFIG_OMAP2_DSS_DPI
		dpi_init_port(pdev, parent);
#endif
		return 0;
	}

	do {
		u32 reg;

		r = of_property_read_u32(port, "reg", &reg);
		if (r)
			reg = 0;

#ifdef CONFIG_OMAP2_DSS_DPI
		if (reg == 0)
			dpi_init_port(pdev, port);
#endif

#ifdef CONFIG_OMAP2_DSS_SDI
		if (reg == 1)
			sdi_init_port(pdev, port);
#endif

	} while ((port = omapdss_of_get_next_port(parent, port)) != NULL);

	return 0;
}

static void dss_uninit_ports(void)
{
#ifdef CONFIG_OMAP2_DSS_DPI
	dpi_uninit_port();
#endif

#ifdef CONFIG_OMAP2_DSS_SDI
	sdi_uninit_port();
#endif
}

/* DSS HW IP initialisation */
static int __init omap_dsshw_probe(struct platform_device *pdev)
{
@@ -846,6 +898,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;

	dss_init_ports(pdev);

	rev = dss_read_reg(DSS_REVISION);
	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -865,6 +919,8 @@ err_setup_clocks:

static int __exit omap_dsshw_remove(struct platform_device *pdev)
{
	dss_uninit_ports();

	pm_runtime_disable(&pdev->dev);

	dss_put_clocks();
@@ -902,12 +958,22 @@ static const struct dev_pm_ops dss_pm_ops = {
	.runtime_resume = dss_runtime_resume,
};

static const struct of_device_id dss_of_match[] = {
	{ .compatible = "ti,omap2-dss", },
	{ .compatible = "ti,omap3-dss", },
	{ .compatible = "ti,omap4-dss", },
	{},
};

MODULE_DEVICE_TABLE(of, dss_of_match);

static struct platform_driver omap_dsshw_driver = {
	.remove         = __exit_p(omap_dsshw_remove),
	.driver         = {
		.name   = "omapdss_dss",
		.owner  = THIS_MODULE,
		.pm	= &dss_pm_ops,
		.of_match_table = dss_of_match,
	},
};

+6 −0
Original line number Diff line number Diff line
@@ -252,6 +252,9 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
int sdi_init_platform_driver(void) __init;
void sdi_uninit_platform_driver(void) __exit;

int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init;
void sdi_uninit_port(void) __exit;

/* DSI */

typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint,
@@ -363,6 +366,9 @@ static inline bool dsi_pll_calc(struct platform_device *dsidev,
int dpi_init_platform_driver(void) __init;
void dpi_uninit_platform_driver(void) __exit;

int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init;
void dpi_uninit_port(void) __exit;

/* DISPC */
int dispc_init_platform_driver(void) __init;
void dispc_uninit_platform_driver(void) __exit;
+45 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/of.h>

#include <video/omapdss.h>
#include "dss.h"
@@ -41,6 +42,8 @@ static struct {
	int datapairs;

	struct omap_dss_device output;

	bool port_initialized;
} sdi;

struct sdi_clk_calc_ctx {
@@ -387,3 +390,45 @@ void __exit sdi_uninit_platform_driver(void)
{
	platform_driver_unregister(&omap_sdi_driver);
}

int __init sdi_init_port(struct platform_device *pdev, struct device_node *port)
{
	struct device_node *ep;
	u32 datapairs;
	int r;

	ep = omapdss_of_get_next_endpoint(port, NULL);
	if (!ep)
		return 0;

	r = of_property_read_u32(ep, "datapairs", &datapairs);
	if (r) {
		DSSERR("failed to parse datapairs\n");
		goto err_datapairs;
	}

	sdi.datapairs = datapairs;

	of_node_put(ep);

	sdi.pdev = pdev;

	sdi_init_output(pdev);

	sdi.port_initialized = true;

	return 0;

err_datapairs:
	of_node_put(ep);

	return r;
}

void __exit sdi_uninit_port(void)
{
	if (!sdi.port_initialized)
		return;

	sdi_uninit_output(sdi.pdev);
}