From 1f32450911dfa243b8ff79cef62d2ddaeeb3e033 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 8 May 2014 22:16:50 +0200 Subject: omapdss: panel-tpo-td028ec1: Add DT support. Signed-off-by: Marek Belisko Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 16d33d831287..66a2ee030b21 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -566,6 +566,7 @@ static const char * const dss_compat_conv_list[] __initconst = { "svideo-connector", "ti,tfp410", "ti,tpd12s015", + "toppoly,td028ttec1", }; /* prepend compatible string with "omapdss," */ -- cgit v1.2.3 From d6279d4ae18d4248c90dfcf02fa8c579b81ce43b Mon Sep 17 00:00:00 2001 From: Sathya Prakash M R Date: Mon, 24 Mar 2014 16:31:51 +0530 Subject: OMAPDSS: Add DSS features for AM43xx Add DSS features for AM43xx. Signed-off-by: Sathya Prakash M R Acked-by: Tony Lindgren Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 2 + drivers/video/fbdev/omap2/dss/dispc.c | 1 + drivers/video/fbdev/omap2/dss/dpi.c | 2 + drivers/video/fbdev/omap2/dss/dsi.c | 1 + drivers/video/fbdev/omap2/dss/dss.c | 11 +++++ drivers/video/fbdev/omap2/dss/dss_features.c | 67 ++++++++++++++++++++++++++++ include/video/omapdss.h | 1 + 7 files changed, 85 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 66a2ee030b21..c3f2c66e61f3 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -279,6 +279,8 @@ static enum omapdss_version __init omap_display_get_version(void) return OMAPDSS_VER_OMAP4; else if (soc_is_omap54xx()) return OMAPDSS_VER_OMAP5; + else if (soc_is_am43xx()) + return OMAPDSS_VER_AM43xx; else return OMAPDSS_VER_UNKNOWN; } diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c index 4fe143166b74..3f612a0895d3 100644 --- a/drivers/video/fbdev/omap2/dss/dispc.c +++ b/drivers/video/fbdev/omap2/dss/dispc.c @@ -3656,6 +3656,7 @@ static int __init dispc_init_features(struct platform_device *pdev) case OMAPDSS_VER_OMAP34xx_ES3: case OMAPDSS_VER_OMAP3630: case OMAPDSS_VER_AM35xx: + case OMAPDSS_VER_AM43xx: src = &omap34xx_rev3_0_dispc_feats; break; diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index 157921db447a..10745261be52 100644 --- a/drivers/video/fbdev/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -67,6 +67,7 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel) case OMAPDSS_VER_OMAP34xx_ES3: case OMAPDSS_VER_OMAP3630: case OMAPDSS_VER_AM35xx: + case OMAPDSS_VER_AM43xx: return NULL; case OMAPDSS_VER_OMAP4430_ES1: @@ -595,6 +596,7 @@ static enum omap_channel dpi_get_channel(void) case OMAPDSS_VER_OMAP34xx_ES3: case OMAPDSS_VER_OMAP3630: case OMAPDSS_VER_AM35xx: + case OMAPDSS_VER_AM43xx: return OMAP_DSS_CHANNEL_LCD; case OMAPDSS_VER_OMAP4430_ES1: diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c index 57f120896b43..90e0eff84867 100644 --- a/drivers/video/fbdev/omap2/dss/dsi.c +++ b/drivers/video/fbdev/omap2/dss/dsi.c @@ -5132,6 +5132,7 @@ static enum omap_channel dsi_get_channel(int module_id) { switch (omapdss_get_version()) { case OMAPDSS_VER_OMAP24xx: + case OMAPDSS_VER_AM43xx: DSSWARN("DSI not supported\n"); return OMAP_DSS_CHANNEL_LCD; diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 71524cb1b423..a6ef4c424ffa 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -728,6 +728,13 @@ static const struct dss_features omap54xx_dss_feats __initconst = { .dpi_select_source = &dss_dpi_select_source_omap5, }; +static const struct dss_features am43xx_dss_feats __initconst = { + .fck_div_max = 0, + .dss_fck_multiplier = 0, + .parent_clk_name = NULL, + .dpi_select_source = &dss_dpi_select_source_omap2_omap3, +}; + static int __init dss_init_features(struct platform_device *pdev) { const struct dss_features *src; @@ -764,6 +771,10 @@ static int __init dss_init_features(struct platform_device *pdev) src = &omap54xx_dss_feats; break; + case OMAPDSS_VER_AM43xx: + src = &am43xx_dss_feats; + break; + default: return -ENODEV; } diff --git a/drivers/video/fbdev/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c index 7f8969191dc6..46542f82faef 100644 --- a/drivers/video/fbdev/omap2/dss/dss_features.c +++ b/drivers/video/fbdev/omap2/dss/dss_features.c @@ -93,6 +93,17 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = { [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 }, }; +static const struct dss_reg_field am43xx_dss_reg_fields[] = { + [FEAT_REG_FIRHINC] = { 12, 0 }, + [FEAT_REG_FIRVINC] = { 28, 16 }, + [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 }, + [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 }, + [FEAT_REG_FIFOSIZE] = { 10, 0 }, + [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, + [FEAT_REG_VERTICALACCU] = { 25, 16 }, + [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, +}; + static const struct dss_reg_field omap4_dss_reg_fields[] = { [FEAT_REG_FIRHINC] = { 12, 0 }, [FEAT_REG_FIRVINC] = { 28, 16 }, @@ -149,6 +160,11 @@ static const enum omap_display_type omap3630_dss_supported_displays[] = { OMAP_DISPLAY_TYPE_VENC, }; +static const enum omap_display_type am43xx_dss_supported_displays[] = { + /* OMAP_DSS_CHANNEL_LCD */ + OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, +}; + static const enum omap_display_type omap4_dss_supported_displays[] = { /* OMAP_DSS_CHANNEL_LCD */ OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, @@ -200,6 +216,11 @@ static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = { OMAP_DSS_OUTPUT_VENC, }; +static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = { + /* OMAP_DSS_CHANNEL_LCD */ + OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, +}; + static const enum omap_dss_output_id omap4_dss_supported_outputs[] = { /* OMAP_DSS_CHANNEL_LCD */ OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1, @@ -444,6 +465,13 @@ static const struct dss_param_range omap3_dss_param_range[] = { [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, }; +static const struct dss_param_range am43xx_dss_param_range[] = { + [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, + [FEAT_PARAM_DSS_PCD] = { 2, 255 }, + [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, + [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, +}; + static const struct dss_param_range omap4_dss_param_range[] = { [FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, [FEAT_PARAM_DSS_PCD] = { 1, 255 }, @@ -520,6 +548,21 @@ static const enum dss_feat_id am35xx_dss_feat_list[] = { FEAT_OMAP3_DSI_FIFO_BUG, }; +static const enum dss_feat_id am43xx_dss_feat_list[] = { + FEAT_LCDENABLEPOL, + FEAT_LCDENABLESIGNAL, + FEAT_PCKFREEENABLE, + FEAT_FUNCGATED, + FEAT_LINEBUFFERSPLIT, + FEAT_ROWREPEATENABLE, + FEAT_RESIZECONF, + FEAT_CPR, + FEAT_PRELOAD, + FEAT_FIR_COEF_V, + FEAT_ALPHA_FIXED_ZORDER, + FEAT_FIFO_MERGE, +}; + static const enum dss_feat_id omap3630_dss_feat_list[] = { FEAT_LCDENABLEPOL, FEAT_LCDENABLESIGNAL, @@ -682,6 +725,26 @@ static const struct omap_dss_features am35xx_dss_features = { .burst_size_unit = 8, }; +static const struct omap_dss_features am43xx_dss_features = { + .reg_fields = am43xx_dss_reg_fields, + .num_reg_fields = ARRAY_SIZE(am43xx_dss_reg_fields), + + .features = am43xx_dss_feat_list, + .num_features = ARRAY_SIZE(am43xx_dss_feat_list), + + .num_mgrs = 1, + .num_ovls = 3, + .supported_displays = am43xx_dss_supported_displays, + .supported_outputs = am43xx_dss_supported_outputs, + .supported_color_modes = omap3_dss_supported_color_modes, + .overlay_caps = omap3430_dss_overlay_caps, + .clksrc_names = omap2_dss_clk_source_names, + .dss_params = am43xx_dss_param_range, + .supported_rotation_types = OMAP_DSS_ROT_DMA, + .buffer_size_unit = 1, + .burst_size_unit = 8, +}; + static const struct omap_dss_features omap3630_dss_features = { .reg_fields = omap3_dss_reg_fields, .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), @@ -928,6 +991,10 @@ void dss_features_init(enum omapdss_version version) omap_current_dss_features = &am35xx_dss_features; break; + case OMAPDSS_VER_AM43xx: + omap_current_dss_features = &am43xx_dss_features; + break; + default: DSSWARN("Unsupported OMAP version"); break; diff --git a/include/video/omapdss.h b/include/video/omapdss.h index f7b9903ee154..fc06c5b5f12a 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -319,6 +319,7 @@ enum omapdss_version { OMAPDSS_VER_OMAP4430_ES2, /* OMAP4430 ES2.0, 2.1, 2.2 */ OMAPDSS_VER_OMAP4, /* All other OMAP4s */ OMAPDSS_VER_OMAP5, + OMAPDSS_VER_AM43xx, }; /* Board specific data */ -- cgit v1.2.3 From 9a3089481a2ed87517f71e00e8fc0182c604f255 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Apr 2014 13:16:27 +0300 Subject: ARM: OMAP: add detection of omap5-dss Add detection of omap5-dss nodes so that the related devices get initialized. Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index c3f2c66e61f3..98e3c59deeab 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -635,6 +635,10 @@ struct device_node * __init omapdss_find_dss_of_node(void) if (node) return node; + node = of_find_compatible_node(NULL, NULL, "ti,omap5-dss"); + if (node) + return node; + return NULL; } -- cgit v1.2.3 From f2dd36ac9974cc2353bcbb8e6b643fb96030564c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 15 May 2014 10:41:34 +0300 Subject: OMAPDSS: move 'compatible' converter to omapdss driver Move the panel/encoder driver compatible-string converter from arch/arm/mach-omap2/display.c to omapdss driver. That is a more logical place for it, as it's really an omapdss internal hack. The code is rewritten to follow the video node graph, starting from omapdss. This removes the need to have the device compatible-string database. Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 57 ------ drivers/video/fbdev/omap2/Makefile | 2 +- drivers/video/fbdev/omap2/dss/Kconfig | 4 + drivers/video/fbdev/omap2/dss/Makefile | 1 + drivers/video/fbdev/omap2/dss/omapdss-boot-init.c | 229 ++++++++++++++++++++++ 5 files changed, 235 insertions(+), 58 deletions(-) create mode 100644 drivers/video/fbdev/omap2/dss/omapdss-boot-init.c (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 98e3c59deeab..bf852d7ae951 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -557,66 +557,9 @@ int omap_dss_reset(struct omap_hwmod *oh) return r; } -/* list of 'compatible' nodes to convert to omapdss specific */ -static const char * const dss_compat_conv_list[] __initconst = { - "composite-connector", - "dvi-connector", - "hdmi-connector", - "panel-dpi", - "panel-dsi-cm", - "sony,acx565akm", - "svideo-connector", - "ti,tfp410", - "ti,tpd12s015", - "toppoly,td028ttec1", -}; - -/* prepend compatible string with "omapdss," */ -static __init void omapdss_omapify_node(struct device_node *node, - const char *compat) -{ - char *new_compat; - struct property *prop; - - new_compat = kasprintf(GFP_KERNEL, "omapdss,%s", compat); - - prop = kzalloc(sizeof(*prop), GFP_KERNEL); - - if (!prop) { - pr_err("omapdss_omapify_node: kzalloc failed\n"); - return; - } - - prop->name = "compatible"; - prop->value = new_compat; - prop->length = strlen(new_compat) + 1; - - of_update_property(node, prop); -} - -/* - * As omapdss panel drivers are omapdss specific, but we want to define the - * DT-data in generic manner, we convert the compatible strings of the panel - * nodes from "panel-foo" to "omapdss,panel-foo". This way we can have both - * correct DT data and omapdss specific drivers. - * - * When we get generic panel drivers to the kernel, this will be removed. - */ void __init omapdss_early_init_of(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(dss_compat_conv_list); ++i) { - const char *compat = dss_compat_conv_list[i]; - struct device_node *node = NULL; - - while ((node = of_find_compatible_node(node, NULL, compat))) { - if (!of_device_is_available(node)) - continue; - omapdss_omapify_node(node, compat); - } - } } struct device_node * __init omapdss_find_dss_of_node(void) diff --git a/drivers/video/fbdev/omap2/Makefile b/drivers/video/fbdev/omap2/Makefile index bf8127df8c71..f8745ec369cc 100644 --- a/drivers/video/fbdev/omap2/Makefile +++ b/drivers/video/fbdev/omap2/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_OMAP2_VRFB) += vrfb.o -obj-$(CONFIG_OMAP2_DSS) += dss/ +obj-y += dss/ obj-y += displays-new/ obj-$(CONFIG_FB_OMAP2) += omapfb/ diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig index 8921a7a76a15..285bcd103dce 100644 --- a/drivers/video/fbdev/omap2/dss/Kconfig +++ b/drivers/video/fbdev/omap2/dss/Kconfig @@ -1,6 +1,10 @@ +config OMAP2_DSS_INIT + bool + menuconfig OMAP2_DSS tristate "OMAP2+ Display Subsystem support" select VIDEOMODE_HELPERS + select OMAP2_DSS_INIT help OMAP2+ Display Subsystem support. diff --git a/drivers/video/fbdev/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile index 390ab746bdc0..245f933060ee 100644 --- a/drivers/video/fbdev/omap2/dss/Makefile +++ b/drivers/video/fbdev/omap2/dss/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o obj-$(CONFIG_OMAP2_DSS) += omapdss.o # Core DSS files omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ diff --git a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c new file mode 100644 index 000000000000..99af9e88b2d8 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2014 Texas Instruments + * Author: Tomi Valkeinen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +/* + * As omapdss panel drivers are omapdss specific, but we want to define the + * DT-data in generic manner, we convert the compatible strings of the panel and + * encoder nodes from "panel-foo" to "omapdss,panel-foo". This way we can have + * both correct DT data and omapdss specific drivers. + * + * When we get generic panel drivers to the kernel, this file will be removed. + */ + +#include +#include +#include +#include +#include + +static struct list_head dss_conv_list __initdata; + +static const char prefix[] __initconst = "omapdss,"; + +struct dss_conv_node { + struct list_head list; + struct device_node *node; + bool root; +}; + +static int __init omapdss_count_strings(const struct property *prop) +{ + const char *p = prop->value; + int l = 0, total = 0; + int i; + + for (i = 0; total < prop->length; total += l, p += l, i++) + l = strlen(p) + 1; + + return i; +} + +static void __init omapdss_update_prop(struct device_node *node, char *compat, + int len) +{ + struct property *prop; + + prop = kzalloc(sizeof(*prop), GFP_KERNEL); + if (!prop) + return; + + prop->name = "compatible"; + prop->value = compat; + prop->length = len; + + of_update_property(node, prop); +} + +static void __init omapdss_prefix_strcpy(char *dst, int dst_len, + const char *src, int src_len) +{ + size_t total = 0; + + while (total < src_len) { + size_t l = strlen(src) + 1; + + strcpy(dst, prefix); + dst += strlen(prefix); + + strcpy(dst, src); + dst += l; + + src += l; + total += l; + } +} + +/* prepend compatible property strings with "omapdss," */ +static void __init omapdss_omapify_node(struct device_node *node) +{ + struct property *prop; + char *new_compat; + int num_strs; + int new_len; + + prop = of_find_property(node, "compatible", NULL); + + if (!prop || !prop->value) + return; + + if (strnlen(prop->value, prop->length) >= prop->length) + return; + + /* is it already prefixed? */ + if (strncmp(prefix, prop->value, strlen(prefix)) == 0) + return; + + num_strs = omapdss_count_strings(prop); + + new_len = prop->length + strlen(prefix) * num_strs; + new_compat = kmalloc(new_len, GFP_KERNEL); + + omapdss_prefix_strcpy(new_compat, new_len, prop->value, prop->length); + + omapdss_update_prop(node, new_compat, new_len); +} + +static void __init omapdss_add_to_list(struct device_node *node, bool root) +{ + struct dss_conv_node *n = kmalloc(sizeof(struct dss_conv_node), + GFP_KERNEL); + n->node = node; + n->root = root; + list_add(&n->list, &dss_conv_list); +} + +static bool __init omapdss_list_contains(const struct device_node *node) +{ + struct dss_conv_node *n; + + list_for_each_entry(n, &dss_conv_list, list) { + if (n->node == node) + return true; + } + + return false; +} + +static void __init omapdss_walk_device(struct device_node *node, bool root) +{ + struct device_node *n; + + omapdss_add_to_list(node, root); + + /* + * of_graph_get_remote_port_parent() prints an error if there is no + * port/ports node. To avoid that, check first that there's the node. + */ + n = of_get_child_by_name(node, "ports"); + if (!n) + n = of_get_child_by_name(node, "port"); + if (!n) + return; + + of_node_put(n); + + n = NULL; + while ((n = of_graph_get_next_endpoint(node, n)) != NULL) { + struct device_node *pn; + + pn = of_graph_get_remote_port_parent(n); + + if (!pn) { + of_node_put(n); + continue; + } + + if (!of_device_is_available(pn) || omapdss_list_contains(pn)) { + of_node_put(pn); + of_node_put(n); + continue; + } + + omapdss_walk_device(pn, false); + + of_node_put(n); + } +} + +static const struct of_device_id omapdss_of_match[] __initconst = { + { .compatible = "ti,omap2-dss", }, + { .compatible = "ti,omap3-dss", }, + { .compatible = "ti,omap4-dss", }, + { .compatible = "ti,omap5-dss", }, + {}, +}; + +static int __init omapdss_boot_init(void) +{ + struct device_node *dss, *child; + + INIT_LIST_HEAD(&dss_conv_list); + + dss = of_find_matching_node(NULL, omapdss_of_match); + + if (dss == NULL || !of_device_is_available(dss)) + return 0; + + omapdss_walk_device(dss, true); + + for_each_available_child_of_node(dss, child) { + if (!of_find_property(child, "compatible", NULL)) { + of_node_put(child); + continue; + } + + omapdss_walk_device(child, true); + } + + while (!list_empty(&dss_conv_list)) { + struct dss_conv_node *n; + + n = list_first_entry(&dss_conv_list, struct dss_conv_node, + list); + + if (!n->root) + omapdss_omapify_node(n->node); + + list_del(&n->list); + of_node_put(n->node); + kfree(n); + } + + return 0; +} + +subsys_initcall(omapdss_boot_init); -- cgit v1.2.3