diff mbox

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

Message ID 9c5bd87d77527aa7a88ab0c006387ed565606c8e.1471334845.git.jsarha@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jyri Sarha Aug. 16, 2016, 9:24 a.m. UTC
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

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 .../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(-)

Comments

Rob Herring Aug. 18, 2016, 7:17 p.m. UTC | #1
On Tue, Aug 16, 2016 at 12:24:28PM +0300, Jyri Sarha wrote:
> 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
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  .../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(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> index 6efa4c5..992803b 100644
> --- a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> +++ b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> @@ -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
Jyri Sarha Aug. 19, 2016, 11:48 a.m. UTC | #2
On 08/18/16 22:17, Rob Herring wrote:
> On Tue, Aug 16, 2016 at 12:24:28PM +0300, Jyri Sarha wrote:
>> 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
>>
>> Signed-off-by: Jyri Sarha <jsarha@ti.com>
>> ---
>>  .../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(-)
>>
>> diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
>> index 6efa4c5..992803b 100644
>> --- a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
>> +++ b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
>> @@ -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
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
index 6efa4c5..992803b 100644
--- a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
+++ b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
@@ -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>;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index e45c268..7f9c19d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -33,6 +33,16 @@ 
 
 static LIST_HEAD(module_list);
 
+static const u32 tilcdc_rev1_formats[] = { DRM_FORMAT_RGB565 };
+
+static const u32 tilcdc_straight_formats[] = { DRM_FORMAT_RGB565,
+					       DRM_FORMAT_BGR888,
+					       DRM_FORMAT_XBGR8888 };
+
+static const u32 tilcdc_crossed_formats[] = { DRM_FORMAT_BGR565,
+					      DRM_FORMAT_RGB888,
+					      DRM_FORMAT_XRGB8888 };
+
 void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
 		const struct tilcdc_module_ops *funcs)
 {
@@ -221,6 +231,26 @@  static int tilcdc_unload(struct drm_device *dev)
 	return 0;
 }
 
+static bool tilcdc_of_blue_and_red_crossed(struct device_node *node)
+{
+	const char *str;
+	int ret;
+
+	ret = of_property_read_string(node, "blue-and-red-wiring", &str);
+
+	/* If no property is present, assume that wires are crossed */
+	if (ret != 0)
+		return true;
+
+	DBG("blue-and-red-wiring = \"%s\"", str);
+
+	/* Unless property is "crossed", assume the wires are straight */
+	if (0 == strcmp(str, "crossed"))
+		return true;
+
+	return false;
+}
+
 static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 {
 	struct platform_device *pdev = dev->platformdev;
@@ -318,6 +348,20 @@  static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 
 	pm_runtime_put_sync(dev->dev);
 
+	if (priv->rev == 1) {
+		DBG("Revision 1 LCDC supports only RGB565 format");
+		priv->pixelformats = tilcdc_rev1_formats;
+		priv->num_pixelformats = ARRAY_SIZE(tilcdc_rev1_formats);
+	} 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);
+	} else {
+		DBG("Configured for straight blue and red wires");
+		priv->pixelformats = tilcdc_straight_formats;
+		priv->num_pixelformats = ARRAY_SIZE(tilcdc_straight_formats);
+	}
+
 	ret = modeset_init(dev);
 	if (ret < 0) {
 		dev_err(dev->dev, "failed to initialize mode setting\n");
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 13001df..0e19c14 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -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;
 
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
index 41911e3..74c65fa 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
@@ -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);