Skip to contentSkip to conversation

drm/tilcdc: Address LCDC rev 2 color errata

PATCH Superseded Jyri Sarha 3 participants 7 messages Aug 16, 2016 – Aug 19, 2016

Subsystems (4)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Jyri Sarha

author
#0 lore raw

cover drm/tilcdc: Address LCDC rev 2 color errata

The first patch ("drm/tilcdc: Remove drm_helper_disable_unused_functions() call") is completely independent fix.

The red and blue components are reversed between 24 and 16 bit modes on am335x LCDC output pins. To get 24 RGB format the wires red and blue wires has to be crossed and this in turn causes 16 colors output to be in BGR format. With straight wiring the 16 color is RGB and 24 bit is BGR. These patches try to deal with the issue in reasonable manner.

For more details see section 3.1.1 in AM335x Silicon Errata:
http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360

Jyri Sarha (4):
drm/tilcdc: Remove drm_helper_disable_unused_functions() call drm/tilcdc: Add blue-and-red-wiring -device tree property drm/tilcdc: Choose console BPP that supports RGB
ARM: dts: am335x-boneblack: Convert BGR from LCDC to RGB in tda19988

 .../devicetree/bindings/display/tilcdc/tilcdc.txt  | 12 +++++
 arch/arm/boot/dts/am335x-boneblack.dts             | 11 ++++
 drivers/gpu/drm/tilcdc/tilcdc_drv.c                | 59 ++++++++++++++++++----
 drivers/gpu/drm/tilcdc/tilcdc_drv.h                |  5 +-
 drivers/gpu/drm/tilcdc/tilcdc_external.c           |  7 ++-
 drivers/gpu/drm/tilcdc/tilcdc_external.h           |  2 +-
 drivers/gpu/drm/tilcdc/tilcdc_panel.c              |  2 -
 drivers/gpu/drm/tilcdc/tilcdc_plane.c              |  9 ++--
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c             |  2 -
 9 files changed, 82 insertions(+), 27 deletions(-)
Signature · 6 lines
1.9.1

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#1 lore raw

PATCH 1/4 drm/tilcdc: Remove drm_helper_disable_unused_functions() call

drm_helper_disable_unused_functions() should not be called by atomic drivers.

---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 --
 1 file changed, 2 deletions(-)
drivers/gpu/drm/tilcdc/tilcdc_drv.c +0 -2
index 3404d24..e45c268 100644
@@ -361,8 +361,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 			break;
 	}
 
-	drm_helper_disable_unused_functions(dev);
-
 	drm_mode_config_reset(dev);
 
 	priv->fbdev = drm_fbdev_cma_init(dev, bpp,
Signature · 6 lines
1.9.1

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#2 lore raw

PATCH 2/4 drm/tilcdc: Add blue-and-red-wiring -device tree property

In reply to Jyri Sarha

Add "blue-and-red-wiring"-device tree property and update devicetree binding document. The red and blue components are reversed between 24 and 16 bit modes on am335x LCDC output pins. To get 24 RGB format the red and blue wires has to be crossed and this in turn causes 16 colors output to be in BGR format. With straight wiring the 16 color is RGB and 24 bit is BGR. The new property describes whether the red and blue wires are crossed or not. The am335x-evm has the wires going to LCD crossed and that is chosen to be the default mode if "blue-and-red-wiring"-property is not found.

For more details see section 3.1.1 in AM335x Silicon Errata:
http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360

---
 .../devicetree/bindings/display/tilcdc/tilcdc.txt  | 12 ++++++
 drivers/gpu/drm/tilcdc/tilcdc_drv.c                | 44 ++++++++++++++++++++++
 drivers/gpu/drm/tilcdc/tilcdc_drv.h                |  4 ++
 drivers/gpu/drm/tilcdc/tilcdc_plane.c              |  9 ++---
 4 files changed, 63 insertions(+), 6 deletions(-)
Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt +12 -0
index 6efa4c5..992803b 100644
@@ -17,6 +17,8 @@ Optional properties:
    the lcd controller.
  - max-pixelclock: The maximum pixel clock that can be supported
    by the lcd controller in KHz.
+ - blue-and-red-wiring: Either "crossed" or "straight", if not present
+   crossed wiring is assumed for dtb backward compatibility. [1]
 
 Optional nodes:
 
@@ -28,6 +30,14 @@ Optional nodes:
    Documentation/devicetree/bindings/display/tilcdc/tfp410.txt for connecting
    tfp410 DVI encoder or lcd panel to lcdc
 
+[1] There is an errata about AM335x color wiring. For 16-bit color mode
+    the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]),
+    but for 24 bit color modes the wiring of blue and red components is
+    crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is
+    for Blue[3-7]. For more details see section 3.1.1 in AM335x
+    Silicon Errata:
+    http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360
+
 Example:
 
 	fb: fb@4830e000 {
@@ -37,6 +47,8 @@ Example:
 		interrupts = <36>;
 		ti,hwmods = "lcdc";
 
+		blue-and-red-wiring = "crossed";
+
 		port {
 			lcdc_0: endpoint@0 {
 				remote-endpoint = <&hdmi_0>;
drivers/gpu/drm/tilcdc/tilcdc_drv.c +44 -0

62 lines not on this page · raw message

drivers/gpu/drm/tilcdc/tilcdc_drv.h +4 -0
index 13001df..0e19c14 100644
@@ -65,6 +65,10 @@ struct tilcdc_drm_private {
 	 */
 	uint32_t max_width;
 
+	/* Supported pixel formats */
+	const uint32_t *pixelformats;
+	uint32_t num_pixelformats;
+
 	/* The context for pm susped/resume cycle is stored here */
 	struct drm_atomic_state *saved_state;
 
drivers/gpu/drm/tilcdc/tilcdc_plane.c +3 -6
index 41911e3..74c65fa 100644
@@ -24,10 +24,6 @@
 
 #include "tilcdc_drv.h"
 
-static const u32 tilcdc_formats[] = { DRM_FORMAT_RGB565,
-				      DRM_FORMAT_RGB888,
-				      DRM_FORMAT_XRGB8888 };
-
 static struct drm_plane_funcs tilcdc_plane_funcs = {
 	.update_plane	= drm_atomic_helper_update_plane,
 	.disable_plane	= drm_atomic_helper_disable_plane,
@@ -114,12 +110,13 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
 int tilcdc_plane_init(struct drm_device *dev,
 		      struct drm_plane *plane)
 {
+	struct tilcdc_drm_private *priv = dev->dev_private;
 	int ret;
 
 	ret = drm_plane_init(dev, plane, 1,
 			     &tilcdc_plane_funcs,
-			     tilcdc_formats,
-			     ARRAY_SIZE(tilcdc_formats),
+			     priv->pixelformats,
+			     priv->num_pixelformats,
 			     true);
 	if (ret) {
 		dev_err(dev->dev, "Failed to initialize plane: %d\n", ret);
Signature · 6 lines
1.9.1

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
maintainer
#3 lore raw

Re: [PATCH 2/4] drm/tilcdc: Add blue-and-red-wiring -device tree property

Quoted 26 lines · Jyri Sarha

Add "blue-and-red-wiring"-device tree property and update devicetree binding document. The red and blue components are reversed between 24 and 16 bit modes on am335x LCDC output pins. To get 24 RGB format the red and blue wires has to be crossed and this in turn causes 16 colors output to be in BGR format. With straight wiring the 16 color is RGB and 24 bit is BGR. The new property describes whether the red and blue wires are crossed or not. The am335x-evm has the wires going to LCD crossed and that is chosen to be the default mode if "blue-and-red-wiring"-property is not found.

For more details see section 3.1.1 in AM335x Silicon Errata:
http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360

---
 .../devicetree/bindings/display/tilcdc/tilcdc.txt  | 12 ++++++
 drivers/gpu/drm/tilcdc/tilcdc_drv.c                | 44 ++++++++++++++++++++++
 drivers/gpu/drm/tilcdc/tilcdc_drv.h                |  4 ++
 drivers/gpu/drm/tilcdc/tilcdc_plane.c              |  9 ++---
 4 files changed, 63 insertions(+), 6 deletions(-)
Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt +0 -0
index 6efa4c5..992803b 100644

Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt Optional properties: · line 21

Quoted 5 lines
Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt +2 -0
@@ -17,6 +17,8 @@ Optional properties:
    the lcd controller.
  - max-pixelclock: The maximum pixel clock that can be supported
    by the lcd controller in KHz.
+ - blue-and-red-wiring: Either "crossed" or "straight", if not present
+   crossed wiring is assumed for dtb backward compatibility. [1]

Just do a boolean and restrict it to a particular compatible string so we don't have to carry it forever on new parts.

Rob
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#4 lore raw

Re: [PATCH 2/4] drm/tilcdc: Add blue-and-red-wiring -device tree property

Quoted 22 lines · Rob Herring
Quoted 21 lines · Jyri Sarha

Add "blue-and-red-wiring"-device tree property and update devicetree binding document. The red and blue components are reversed between 24 and 16 bit modes on am335x LCDC output pins. To get 24 RGB format the red and blue wires has to be crossed and this in turn causes 16 colors output to be in BGR format. With straight wiring the 16 color is RGB and 24 bit is BGR. The new property describes whether the red and blue wires are crossed or not. The am335x-evm has the wires going to LCD crossed and that is chosen to be the default mode if "blue-and-red-wiring"-property is not found.

For more details see section 3.1.1 in AM335x Silicon Errata:
http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360

---
 .../devicetree/bindings/display/tilcdc/tilcdc.txt  | 12 ++++++
 drivers/gpu/drm/tilcdc/tilcdc_drv.c                | 44 ++++++++++++++++++++++
 drivers/gpu/drm/tilcdc/tilcdc_drv.h                |  4 ++
 drivers/gpu/drm/tilcdc/tilcdc_plane.c              |  9 ++---
 4 files changed, 63 insertions(+), 6 deletions(-)
Quoted 14 lines

Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt Optional properties: · line 21

Quoted 10 lines
Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt +2 -0
index 6efa4c5..992803b 100644
@@ -17,6 +17,8 @@ Optional properties:
    the lcd controller.
  - max-pixelclock: The maximum pixel clock that can be supported
    by the lcd controller in KHz.
+ - blue-and-red-wiring: Either "crossed" or "straight", if not present
+   crossed wiring is assumed for dtb backward compatibility. [1]

Just do a boolean and restrict it to a particular compatible string so we don't have to carry it forever on new parts.

Do you mean having "blue-and-red-straight" boolean property to keep old dtbs compatible, or coming up with a new compatible string (I actually hate ti,tilcdc tautology) and having "blue-and-red-crossed" boolean there?

BTW, I find it unlikely that there will be new versions of LCDC coming any more, so the errata will remain "forever" on LCDC and will only fade out when the am3 fades out. I base my assumption only on the fact that am4 does not have LCDC any more.

Best regards,
Jyri

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#5 lore raw

PATCH 3/4 drm/tilcdc: Choose console BPP that supports RGB

In reply to Jyri Sarha

Choose console BPP that supports RGB and remove the old fbdev bpp selection code. LCDC on AM335x has red and blue wires switched between 24 bit and 16 bit colors. If 24 format is wired for RGB colors, the 16 bit format is wired for BGR. drm_fbdev_cma_init() does not currently like anything else but RGB formats, so we must choose such bytes per pixel value that supports RGB.

---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c      | 13 ++++---------
 drivers/gpu/drm/tilcdc/tilcdc_drv.h      |  1 -
 drivers/gpu/drm/tilcdc/tilcdc_external.c |  7 +++----
 drivers/gpu/drm/tilcdc/tilcdc_external.h |  2 +-
 drivers/gpu/drm/tilcdc/tilcdc_panel.c    |  2 --
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c   |  2 --
 6 files changed, 8 insertions(+), 19 deletions(-)
drivers/gpu/drm/tilcdc/tilcdc_drv.c +4 -9
index 7f9c19d..bb7af14 100644
@@ -256,7 +256,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 	struct platform_device *pdev = dev->platformdev;
 	struct device_node *node = pdev->dev.of_node;
 	struct tilcdc_drm_private *priv;
-	struct tilcdc_module *mod;
 	struct resource *res;
 	u32 bpp = 0;
 	int ret;
@@ -352,14 +351,17 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 		DBG("Revision 1 LCDC supports only RGB565 format");
 		priv->pixelformats = tilcdc_rev1_formats;
 		priv->num_pixelformats = ARRAY_SIZE(tilcdc_rev1_formats);
+		bpp = 16;
 	} else if (tilcdc_of_blue_and_red_crossed(node)) {
 		DBG("Configured for crossed blue and red wires");
 		priv->pixelformats = tilcdc_crossed_formats;
 		priv->num_pixelformats = ARRAY_SIZE(tilcdc_crossed_formats);
+		bpp = 32; /* Choose bpp with RGB support for fbdef */
 	} else {
 		DBG("Configured for straight blue and red wires");
 		priv->pixelformats = tilcdc_straight_formats;
 		priv->num_pixelformats = ARRAY_SIZE(tilcdc_straight_formats);
+		bpp = 16; /* Choose bpp with RGB support for fbdef */
 	}
 
 	ret = modeset_init(dev);
@@ -375,7 +377,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 		if (ret < 0)
 			goto fail_mode_config_cleanup;
 
-		ret = tilcdc_add_external_encoders(dev, &bpp);
+		ret = tilcdc_add_external_encoders(dev);
 		if (ret < 0)
 			goto fail_component_cleanup;
 	}
@@ -398,13 +400,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 		goto fail_vblank_cleanup;
 	}
 
-	list_for_each_entry(mod, &module_list, list) {
-		DBG("%s: preferred_bpp: %d", mod->name, mod->preferred_bpp);
-		bpp = mod->preferred_bpp;
-		if (bpp > 0)
-			break;
-	}
-
 	drm_mode_config_reset(dev);
 
 	priv->fbdev = drm_fbdev_cma_init(dev, bpp,
drivers/gpu/drm/tilcdc/tilcdc_drv.h +0 -1
index 0e19c14..a6e5e6d 100644
@@ -116,7 +116,6 @@ struct tilcdc_module {
 	const char *name;
 	struct list_head list;
 	const struct tilcdc_module_ops *funcs;
-	unsigned int preferred_bpp;
 };
 
 void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
drivers/gpu/drm/tilcdc/tilcdc_external.c +3 -4
index 849b23e..68e8950 100644
@@ -52,7 +52,7 @@ static int tilcdc_external_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-static int tilcdc_add_external_encoder(struct drm_device *dev, int *bpp,
+static int tilcdc_add_external_encoder(struct drm_device *dev,
 				       struct drm_connector *connector)
 {
 	struct tilcdc_drm_private *priv = dev->dev_private;
@@ -64,7 +64,6 @@ static int tilcdc_add_external_encoder(struct drm_device *dev, int *bpp,
 	/* Only tda998x is supported at the moment. */
 	tilcdc_crtc_set_simulate_vesa_sync(priv->crtc, true);
 	tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_tda998x);
-	*bpp = panel_info_tda998x.bpp;
 
 	connector_funcs = devm_kzalloc(dev->dev, sizeof(*connector_funcs),
 				       GFP_KERNEL);
@@ -94,7 +93,7 @@ static int tilcdc_add_external_encoder(struct drm_device *dev, int *bpp,
 	return 0;
 }
 
-int tilcdc_add_external_encoders(struct drm_device *dev, int *bpp)
+int tilcdc_add_external_encoders(struct drm_device *dev)
 {
 	struct tilcdc_drm_private *priv = dev->dev_private;
 	struct drm_connector *connector;
@@ -108,7 +107,7 @@ int tilcdc_add_external_encoders(struct drm_device *dev, int *bpp)
 			if (connector == priv->connectors[i])
 				found = true;
 		if (!found) {
-			ret = tilcdc_add_external_encoder(dev, bpp, connector);
+			ret = tilcdc_add_external_encoder(dev, connector);
 			if (ret)
 				return ret;
 		}
drivers/gpu/drm/tilcdc/tilcdc_external.h +1 -1
index 6aabe27..c700e0c 100644
@@ -18,7 +18,7 @@
 #ifndef __TILCDC_EXTERNAL_H__
 #define __TILCDC_EXTERNAL_H__
 
-int tilcdc_add_external_encoders(struct drm_device *dev, int *bpp);
+int tilcdc_add_external_encoders(struct drm_device *dev);
 void tilcdc_remove_external_encoders(struct drm_device *dev);
 int tilcdc_get_external_components(struct device *dev,
 				   struct component_match **match);
drivers/gpu/drm/tilcdc/tilcdc_panel.c +0 -2
index 4ac1d25..7b36509 100644
@@ -397,8 +397,6 @@ static int panel_probe(struct platform_device *pdev)
 		goto fail_timings;
 	}
 
-	mod->preferred_bpp = panel_mod->info->bpp;
-
 	return 0;
 
 fail_timings:
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c +0 -2
index 741c7b5..c6a70da 100644
@@ -327,8 +327,6 @@ static int tfp410_probe(struct platform_device *pdev)
 		goto fail;
 	}
 
-	mod->preferred_bpp = dvi_info.bpp;
-
 	i2c_node = of_find_node_by_phandle(i2c_phandle);
 	if (!i2c_node) {
 		dev_err(&pdev->dev, "could not get i2c bus node\n");
Signature · 6 lines
1.9.1

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#6 lore raw

PATCH 4/4 ARM: dts: am335x-boneblack: Convert BGR from LCDC to RGB in tda19988

In reply to Jyri Sarha

Convert BGR from LCDC to RGB in tda19988 with video-ports property. The red and blue components are reversed between 24 and 16 bit modes on color output of am335x LCDC. On BBB the 16 bit video output is by default RGB and 24 is BGR. This patch reverts that using tda19988 so we have a 24 bit RGB mode and 16 BGR mode.

The commit also adds blue-and-red-wiring = "crossed" -property to LCDC node. This change is functionally redundant as "crossed" is the default mode if the property does not exist, but it makes the reason for tda19988 video-port property mode explicit.

If you want to get 16 RGB mode (and 24 BGR mode), set tda19988 video-ports -property to 0x230145 and tilcdc blue-and-red-wiring -property to "straight".

---
 arch/arm/boot/dts/am335x-boneblack.dts | 11 +++++++++++
 1 file changed, 11 insertions(+)
arch/arm/boot/dts/am335x-boneblack.dts +11 -0
index 528559b..a745962 100644
@@ -90,6 +90,14 @@
 
 &lcdc {
 	status = "okay";
+
+	/* If you want to get 16 RGB and 24 BGR mode instead of
+	 * current 24 bit RGB and 16 BGR modes, set this property to
+	 * "straight" and the tda19988 video-ports -property bellow
+	 * to 0x230145 (or remove the property).
+	 */
+	blue-and-red-wiring = "crossed";
+
 	port {
 		lcdc_0: endpoint@0 {
 			remote-endpoint = <&hdmi_0>;
@@ -106,6 +114,9 @@
 		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
 		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
 
+		/* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
+		video-ports = <0x234501>;
+
 		#sound-dai-cells = <0>;
 		audio-ports = <	TDA998x_I2S	0x03>;
 
Signature · 6 lines
1.9.1

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel