diff mbox

[4/9] drm/panel: simple: add support for overriding the pixel clock polarity

Message ID 1507721021-28174-5-git-send-email-LW@KARO-electronics.de (mailing list archive)
State New, archived
Headers show

Commit Message

Lothar Waßmann Oct. 11, 2017, 11:23 a.m. UTC
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.

Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 .../bindings/display/panel/simple-panel.txt        |  3 +++
 drivers/gpu/drm/panel/panel-simple.c               | 30 ++++++++++++++++++++++
 2 files changed, 33 insertions(+)

Comments

Rob Herring Oct. 16, 2017, 10:13 p.m. UTC | #1
On Wed, Oct 11, 2017 at 6:23 AM, Lothar Waßmann <LW@karo-electronics.de> wrote:
> 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.

Wouldn't you know the polarity required based on the type of LVDS
converter chip in front of the panel? Or is that not being described
because it is "transparent".

Rob
Lothar Waßmann Oct. 17, 2017, 6:51 a.m. UTC | #2
Hi,

On Mon, 16 Oct 2017 17:13:29 -0500 Rob Herring wrote:
> On Wed, Oct 11, 2017 at 6:23 AM, Lothar Waßmann <LW@karo-electronics.de> wrote:
> > 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.
> 
> Wouldn't you know the polarity required based on the type of LVDS
> converter chip in front of the panel? Or is that not being described
> because it is "transparent".
> 
Exactly the latter.


Lothar Waßmann
Thierry Reding Oct. 17, 2017, 12:14 p.m. UTC | #3
On Wed, Oct 11, 2017 at 01:23:36PM +0200, Lothar Waßmann wrote:
> 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.

I'd argue that the LCD->LVDS converter should be modelled specifically
in DT to handle this case. It could be a implemented as a DRM bridge
driver, for example.

Thierry
Lothar Waßmann Oct. 17, 2017, 12:25 p.m. UTC | #4
Hi,

On Tue, 17 Oct 2017 14:14:22 +0200 Thierry Reding wrote:
> On Wed, Oct 11, 2017 at 01:23:36PM +0200, Lothar Waßmann wrote:
> > 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.
> 
> I'd argue that the LCD->LVDS converter should be modelled specifically
> in DT to handle this case. It could be a implemented as a DRM bridge
> driver, for example.
> 
IMO that's just overkill for a simple chip that is in no way
configurable nor detectable by software.


Lothar Waßmann
Thierry Reding Oct. 17, 2017, 12:45 p.m. UTC | #5
On Tue, Oct 17, 2017 at 02:25:07PM +0200, Lothar Waßmann wrote:
> Hi,
> 
> On Tue, 17 Oct 2017 14:14:22 +0200 Thierry Reding wrote:
> > On Wed, Oct 11, 2017 at 01:23:36PM +0200, Lothar Waßmann wrote:
> > > 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.
> > 
> > I'd argue that the LCD->LVDS converter should be modelled specifically
> > in DT to handle this case. It could be a implemented as a DRM bridge
> > driver, for example.
> > 
> IMO that's just overkill for a simple chip that is in no way
> configurable nor detectable by software.

I suspect that you're not the only one who runs a board that has this
kind of quirk. If we solve this in a generic way we can point people in
that direction when they come asking for such a quirk.

So this could be something very simple that's instantiated using maybe a
couple of lines of code.

Thierry
Lothar Waßmann Oct. 25, 2017, 9:56 a.m. UTC | #6
Hi,

On Tue, 17 Oct 2017 14:45:04 +0200 Thierry Reding wrote:
> On Tue, Oct 17, 2017 at 02:25:07PM +0200, Lothar Waßmann wrote:
> > Hi,
> > 
> > On Tue, 17 Oct 2017 14:14:22 +0200 Thierry Reding wrote:
> > > On Wed, Oct 11, 2017 at 01:23:36PM +0200, Lothar Waßmann wrote:
> > > > 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.
> > > 
> > > I'd argue that the LCD->LVDS converter should be modelled specifically
> > > in DT to handle this case. It could be a implemented as a DRM bridge
> > > driver, for example.
> > > 
> > IMO that's just overkill for a simple chip that is in no way
> > configurable nor detectable by software.
> 
> I suspect that you're not the only one who runs a board that has this
> kind of quirk. If we solve this in a generic way we can point people in
> that direction when they come asking for such a quirk.
> 
> So this could be something very simple that's instantiated using maybe a
> couple of lines of code.
> 
I found the drivers/gpu/drm/bridge/lvds-encoder.c driver which on first
glance is more or less what I would need. But the driver is currently
dysfunctional due to:
|commit 13dfc0540a575b47b2d640b093ac16e9e09474f6
|Author: Eric Anholt <eric@anholt.net>
|Date:   Fri Jun 2 13:25:14 2017 -0700
|
|    drm/bridge: Refactor out the panel wrapper from the lvds-encoder bridge.

Also there is no in-kernel user of this driver, so that it obviously
doesn't get tested in any way.
There is only one dts file (r8a7779-marzen.dts) that instantiate this
driver, but it has an incomplete OF graph. The missing link for the
OF graph is provided by either r8a77xx-aa104xd12-panel.dtsi or
r8a77xx-aa121td01-panel.dtsi, but those files are referenced nowhere in
the kernel source.

Reverting the part of the above mentioned patch that touches
lvds-encoder.c makes the driver functional, but I see no way to use
this driver to enforce specific bus_flags for the interface, since the
code is run prior to the simple-panel's initialization, which would
override whatever settings might have been provided by the lvds-encoder
driver.

Can someone enligthen me, how to enforce specific bus_flags/bus_format
settings for an LCD interface driven by the simple-panel driver apart
from doing it in the simple-panel driver itself?


Lothar Waßmann
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/display/panel/simple-panel.txt b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
index e2308c3..dcaf9a7 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 f356a7b..7bbb752 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;
 }