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: Tomi Valkeinen <tomi.valkeinen@ti.com> Reviewed-by: Archit Taneja <archit@ti.com>
This commit is contained in:
parent
e6fa68ba82
commit
2ecef24630
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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", ®);
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue