From: Lothar Waßmann Date: Thu, 14 Sep 2017 09:54:55 +0000 (+0200) Subject: drm/panel: simple: add support for overriding the pixel clock polarity X-Git-Tag: KARO-TX6-2017-10-26~2^2~5 X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-linux.git;a=commitdiff_plain;h=15eac9d803414dd670a4e99970b895c6f16ed92b drm/panel: simple: add support for overriding the pixel clock polarity The Ka-Ro electronics MB7 baseboard has an on-board LCD->LVDS converter that requires a fixed pixelclk polarity, no matter what the panel's display_mode specifies. Add an option to override the pixelclk polarity defined in the panel's display_mode via DTB. --- diff --git a/Documentation/devicetree/bindings/display/panel/simple-panel.txt b/Documentation/devicetree/bindings/display/panel/simple-panel.txt index e2308c3414d9..dcaf9a78f1e3 100644 --- a/Documentation/devicetree/bindings/display/panel/simple-panel.txt +++ b/Documentation/devicetree/bindings/display/panel/simple-panel.txt @@ -9,6 +9,9 @@ Optional properties: - backlight: phandle of the backlight device attached to the panel - bus-format-override: override the bus_format setting of the panel's display_mode settings +- pixelclk-active: override the pixelclock polarity defined in the + panel's display_mode settings + Example: diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index f356a7b32f08..7bbb752332ff 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -89,6 +89,12 @@ struct panel_simple { struct gpio_desc *enable_gpio; u32 bus_fmt_override; + u32 quirks; +}; + +enum { + PANEL_QUIRK_PIXDATA_NEGEDGE = BIT(0), + PANEL_QUIRK_PIXDATA_POSEDGE = BIT(1), }; #define SP_DISPLAY_MODE(freq, ha, hfp, hs, hbp, va, vfp, vs, vbp, vr, flgs) { \ @@ -110,6 +116,15 @@ static inline struct panel_simple *to_panel_simple(struct drm_panel *panel) return container_of(panel, struct panel_simple, base); } +static inline void panel_simple_apply_quirks(struct panel_simple *panel, + struct drm_display_info *info) +{ + if (panel->quirks & PANEL_QUIRK_PIXDATA_NEGEDGE) + info->bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE; + if (panel->quirks & PANEL_QUIRK_PIXDATA_POSEDGE) + info->bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE; +} + static int panel_simple_get_fixed_modes(struct panel_simple *panel) { struct drm_connector *connector = panel->base.connector; @@ -175,6 +190,8 @@ static int panel_simple_get_fixed_modes(struct panel_simple *panel) drm_display_info_set_bus_formats(&connector->display_info, &panel->desc->bus_format, 1); connector->display_info.bus_flags = panel->desc->bus_flags; + if (panel->quirks) + panel_simple_apply_quirks(panel, &connector->display_info); return num; } @@ -308,6 +325,7 @@ static inline int panel_simple_check_quirks(struct device *dev, struct panel_simple *p) { const char *bus_fmt; + u32 clkpol; if (of_property_read_string(dev->of_node, "bus-format-override", &bus_fmt) == 0) { @@ -329,6 +347,18 @@ static inline int panel_simple_check_quirks(struct device *dev, bus_fmt); return p->bus_fmt_override ? 0 : -EINVAL; } + + if (of_property_read_u32(dev->of_node, "pixelclk-active", + &clkpol) == 0) { + if (clkpol & ~1) { + dev_err(dev, + "Invalid value for pixelclk-active: '%u' (should be <0> or <1>)\n", + clkpol); + return -EINVAL; + } + p->quirks |= clkpol ? PANEL_QUIRK_PIXDATA_POSEDGE : + PANEL_QUIRK_PIXDATA_NEGEDGE; + } return 0; }