[PATCH v4 3/8] drm/tilcdc: Add blue-and-red-crossed devicetree property
Rob Herring
robh at kernel.org
Mon Sep 12 05:58:38 PDT 2016
On Thu, Sep 01, 2016 at 12:09:07PM +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. If the property is not present or its value is not recognized
> the legacy mode is assumed. The legacy configuration supports RGB565,
> RGB888 and XRGB8888 formats. However, depending on wiring, the red and
> blue colors are swapped in either 16 or 24-bit color modes.
>
> 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 at ti.com>
> ---
> .../devicetree/bindings/display/tilcdc/tilcdc.txt | 22 ++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_drv.c | 41 ++++++++++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_drv.h | 4 +++
> drivers/gpu/drm/tilcdc/tilcdc_plane.c | 9 ++---
> 4 files changed, 70 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> index 6efa4c5..a5007aa 100644
> --- a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> +++ b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> @@ -17,6 +17,18 @@ 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: Recognized values "default", "straight" or
Need to drop default from here. With that,
Acked-by: Rob Herring <robh at kernel.org>
> + "crossed". This property deals with the LCDC revision 2 (found on
> + AM335x) color errata [1].
> + - "straight" indicates normal wiring that supports RGB565,
> + BGR888, and XBGR8888 color formats.
> + - "crossed" indicates wiring that has blue and red wires
> + crossed. This setup supports BGR565, RGB888 and XRGB8888
> + formats.
> + - If the property is not present or its value is not recognized
> + the legacy mode is assumed. This configuration supports RGB565,
> + RGB888 and XRGB8888 formats. However, depending on wiring, the red
> + and blue colors are swapped in either 16 or 24-bit color modes.
>
> Optional nodes:
>
> @@ -28,6 +40,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 at 4830e000 {
> @@ -37,6 +57,8 @@ Example:
> interrupts = <36>;
> ti,hwmods = "lcdc";
>
> + blue-and-red-wiring = "crossed";
> +
> port {
> lcdc_0: endpoint at 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..ed4dc5c 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -33,6 +33,20 @@
>
> 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 };
> +
> +static const u32 tilcdc_legacy_formats[] = { DRM_FORMAT_RGB565,
> + DRM_FORMAT_RGB888,
> + DRM_FORMAT_XRGB8888 };
> +
> void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
> const struct tilcdc_module_ops *funcs)
> {
> @@ -318,6 +332,33 @@ 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 {
> + const char *str = "\0";
> +
> + of_property_read_string(node, "blue-and-red-wiring", &str);
> + if (0 == strcmp(str, "crossed")) {
> + DBG("Configured for crossed blue and red wires");
> + priv->pixelformats = tilcdc_crossed_formats;
> + priv->num_pixelformats =
> + ARRAY_SIZE(tilcdc_crossed_formats);
> + } else if (0 == strcmp(str, "straight")) {
> + DBG("Configured for straight blue and red wires");
> + priv->pixelformats = tilcdc_straight_formats;
> + priv->num_pixelformats =
> + ARRAY_SIZE(tilcdc_straight_formats);
> + } else {
> + DBG("Blue and red wiring '%s' unknown, use legacy mode",
> + str);
> + priv->pixelformats = tilcdc_legacy_formats;
> + priv->num_pixelformats =
> + ARRAY_SIZE(tilcdc_legacy_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);
> --
> 1.9.1
>
More information about the linux-arm-kernel
mailing list