From c50b37eee0209858cfa963919f41dc5dadd65c62 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@ti.com> Date: Tue, 21 Aug 2012 15:35:42 +0300 Subject: [PATCH 09/23] OMAPDSS: Add DT support to DSI Add the code to make the DSI driver work with device tree on OMAP3 and OMAP4. A minor hack is needed at the moment in the DSI driver: the DSS driver needs to know the ID number of a DSI device, as clocks are routed in different ways to the DSI devices. At the moment we don't have any proper way to manage this, so this patchs adds a simple lookup table that is used to deduce the ID from the DSI device's base address. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> --- drivers/video/omap2/dss/dsi.c | 53 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) @ drivers/video/omap2/dss/dsi.c:41 @ #include <linux/slab.h> #include <linux/debugfs.h> #include <linux/pm_runtime.h> +#include <linux/of.h> #include <video/omapdss.h> #include <video/mipi_display.h> @ drivers/video/omap2/dss/dsi.c:377 @ struct dsi_packet_sent_handler_data { struct completion *completion; }; +struct dsi_module_id_data { + u32 address; + int id; +}; + +static const struct of_device_id dsi_of_match[]; + #ifdef DEBUG static bool dsi_perf; module_param(dsi_perf, bool, 0644); @ drivers/video/omap2/dss/dsi.c:5358 @ static int omap_dsihw_probe(struct platform_device *dsidev) if (!dsi) return -ENOMEM; - dsi->module_id = dsidev->id; dsi->pdev = dsidev; dev_set_drvdata(&dsidev->dev, dsi); @ drivers/video/omap2/dss/dsi.c:5407 @ static int omap_dsihw_probe(struct platform_device *dsidev) return r; } + if (dsidev->dev.of_node) { + const struct of_device_id *match; + const struct dsi_module_id_data *d; + + match = of_match_node(dsi_of_match, dsidev->dev.of_node); + if (!match) { + DSSERR("unsupported DSI module\n"); + return -ENODEV; + } + + d = match->data; + + while (d->address != 0 && d->address != dsi_mem->start) + d++; + + if (d->address == 0) { + DSSERR("unsupported DSI module\n"); + return -ENODEV; + } + + dsi->module_id = d->id; + } else { + dsi->module_id = dsidev->id; + } + /* DSI VCs initialization */ for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) { dsi->vc[i].source = DSI_VC_SOURCE_L4; @ drivers/video/omap2/dss/dsi.c:5480 @ static int omap_dsihw_probe(struct platform_device *dsidev) else if (dsi->module_id == 1) dss_debugfs_create_file("dsi2_irqs", dsi2_dump_irqs); #endif + return 0; err_runtime_get: @ drivers/video/omap2/dss/dsi.c:5529 @ static const struct dev_pm_ops dsi_pm_ops = { .runtime_resume = dsi_runtime_resume, }; +static const struct dsi_module_id_data dsi_of_data_omap3[] = { + { .address = 0x4804fc00, .id = 0, }, + { }, +}; + +static const struct dsi_module_id_data dsi_of_data_omap4[] = { + { .address = 0x58004000, .id = 0, }, + { .address = 0x58005000, .id = 1, }, + { }, +}; + +static const struct of_device_id dsi_of_match[] = { + { .compatible = "ti,omap3-dsi", .data = dsi_of_data_omap3, }, + { .compatible = "ti,omap4-dsi", .data = dsi_of_data_omap4, }, + {}, +}; + static struct platform_driver omap_dsihw_driver = { .probe = omap_dsihw_probe, .remove = __exit_p(omap_dsihw_remove), @ drivers/video/omap2/dss/dsi.c:5553 @ static struct platform_driver omap_dsihw_driver = { .name = "omapdss_dsi", .owner = THIS_MODULE, .pm = &dsi_pm_ops, + .of_match_table = dsi_of_match, }, }; -- 1.8.4.rc3