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/platform_device.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <video/omapdss.h>
|
#include <video/omapdss.h>
|
||||||
|
|
||||||
@ -49,6 +50,8 @@ static struct {
|
|||||||
int data_lines;
|
int data_lines;
|
||||||
|
|
||||||
struct omap_dss_device output;
|
struct omap_dss_device output;
|
||||||
|
|
||||||
|
bool port_initialized;
|
||||||
} dpi;
|
} dpi;
|
||||||
|
|
||||||
static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
|
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);
|
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"
|
#define DSS_SUBSYS_NAME "DSS"
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
@ -33,6 +34,7 @@
|
|||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <video/omapdss.h>
|
#include <video/omapdss.h>
|
||||||
|
|
||||||
@ -788,6 +790,56 @@ static int __init dss_init_features(struct platform_device *pdev)
|
|||||||
return 0;
|
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 */
|
/* DSS HW IP initialisation */
|
||||||
static int __init omap_dsshw_probe(struct platform_device *pdev)
|
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[0] = OMAP_DSS_CLK_SRC_FCK;
|
||||||
dss.lcd_clk_source[1] = 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);
|
rev = dss_read_reg(DSS_REVISION);
|
||||||
printk(KERN_INFO "OMAP DSS rev %d.%d\n",
|
printk(KERN_INFO "OMAP DSS rev %d.%d\n",
|
||||||
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
|
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)
|
static int __exit omap_dsshw_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
dss_uninit_ports();
|
||||||
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
dss_put_clocks();
|
dss_put_clocks();
|
||||||
@ -902,12 +958,22 @@ static const struct dev_pm_ops dss_pm_ops = {
|
|||||||
.runtime_resume = dss_runtime_resume,
|
.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 = {
|
static struct platform_driver omap_dsshw_driver = {
|
||||||
.remove = __exit_p(omap_dsshw_remove),
|
.remove = __exit_p(omap_dsshw_remove),
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "omapdss_dss",
|
.name = "omapdss_dss",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &dss_pm_ops,
|
.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;
|
int sdi_init_platform_driver(void) __init;
|
||||||
void sdi_uninit_platform_driver(void) __exit;
|
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 */
|
/* DSI */
|
||||||
|
|
||||||
typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint,
|
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;
|
int dpi_init_platform_driver(void) __init;
|
||||||
void dpi_uninit_platform_driver(void) __exit;
|
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 */
|
/* DISPC */
|
||||||
int dispc_init_platform_driver(void) __init;
|
int dispc_init_platform_driver(void) __init;
|
||||||
void dispc_uninit_platform_driver(void) __exit;
|
void dispc_uninit_platform_driver(void) __exit;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <video/omapdss.h>
|
#include <video/omapdss.h>
|
||||||
#include "dss.h"
|
#include "dss.h"
|
||||||
@ -41,6 +42,8 @@ static struct {
|
|||||||
int datapairs;
|
int datapairs;
|
||||||
|
|
||||||
struct omap_dss_device output;
|
struct omap_dss_device output;
|
||||||
|
|
||||||
|
bool port_initialized;
|
||||||
} sdi;
|
} sdi;
|
||||||
|
|
||||||
struct sdi_clk_calc_ctx {
|
struct sdi_clk_calc_ctx {
|
||||||
@ -387,3 +390,45 @@ void __exit sdi_uninit_platform_driver(void)
|
|||||||
{
|
{
|
||||||
platform_driver_unregister(&omap_sdi_driver);
|
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
Block a user