dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Sam Ravnborg <sam@ravnborg.org>
To: Ahmad Fatoum <a.fatoum@pengutronix.de>
Cc: Marek Vasut <marex@denx.de>, David Airlie <airlied@linux.ie>,
	dri-devel@lists.freedesktop.org, kernel@pengutronix.de,
	Peter Rosin <peda@axentia.se>
Subject: Re: [PATCH 0/3] drm/mxsfb: support swapped RGB lanes
Date: Mon, 7 Jan 2019 19:04:25 +0100	[thread overview]
Message-ID: <20190107180425.GA28018@ravnborg.org> (raw)
In-Reply-To: <2088ee21-ec2a-933a-5c28-6b1d23f8b54d@pengutronix.de>

Hi Ahmad.

> On 2/1/19 22:37, Sam Ravnborg wrote:
> > The problem with the RED/BLUE lines swapped is something I
> > have encountered while working with DRM support for Atmel at91sam9263 too.
> > 
> > The solution selected is to extend the endpoint with
> > a new optional property:
> > 
> > - wiring: Wiring of data lines to display.
> >   "straight" - normal wiring.
> >   "red-blue-reversed" - red and blue lines reversed.
> > 
> > (media/video-interfaces.txt)
> > 
> > 
> > The DT node looks like this:
> > 
> >                port@0 {
> >                         reg = <0>;
> >                         #address-cells = <1>;
> >                         #size-cells = <0>;
> >                         lcdc_panel_output: endpoint@0 {
> >                                 reg = <0>;
> >                                 wiring = "red-blue-reversed";
> >                                 remote-endpoint = <&panel_input>;
> >                         };
> >                 };
> > 
> > This allows us to specify the swapping in the endpoint and
> > not in the panel.
> > So we can use the same panel, with the same bus_format, in several
> > designs some with red-blue swapped (reversed), and some not.
> 
> A colleague suggested a property in the endpoint as well, but I shied
> away because of the extra hassle. Seems there's won't be a way around it ^^'..
> 
> How do you intend to propagate this different wiring setting?

The way I have it implmented is more or less like this:

First find the wiring property:
1) Look up endpoint using of_graph_get_endpoint_by_regs()
2) Get wiring property
3) of_node_put(endpoint);

And then find and attach the panel:
4) drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, &bridge);
5) devm_drm_panel_bridge_add(dev, panel, DRM_MODE_CONNECTOR_DPI);
6) Then based on the wiring property I adjust bus_format
7) drm_simple_display_pipe_init()
8) drm_simple_display_pipe_attach_bridge()

But this is all virgin code that for now can build,
but has not yet seen any testing.
It is a lot of boilerplate for something relatively simple
and I hope there are ways to simplify this.
Relevant parts of the file pasted below.

But the translation of bus_format in a central place may prove a bit
difficult and I assume this as something that can differ
a lot between different HW solutions.

> How about having drm_of_find_panel_or_bridge adjust the
> (*panel)->connector->display_info.bus_formats array to account for the
> different wiring? That way there shouldn't be any need to adjust drivers.
But if you prove me wrong and this fly I am all for it.

Keep in mind that I am novice in the DRM land. So there may be better ways to do it.

	Sam


static int lcdc_get_of_wiring(struct lcdc *lcdc,
			      const struct device_node *ep)
{
	const char *str;
	int ret;

	ret = of_property_read_string(ep, "wiring", &str);
	if (ret)
		return ret;

	if (strcmp(str, "red-green-reversed") == 0) {
		lcdc->wiring_reversed = true;
	} else if (strcmp(str, "straight") == 0) {
		/* Use default format */
	} else {
		DRM_DEV_ERROR(lcdc->dev, "unknown \"wiring\" property: %s",
			      str);
		return -EINVAL;
	}

	return 0;
}

static int lcdc_display_init(struct lcdc *lcdc, struct drm_device *drm)
{
	struct drm_display_info *display_info;
	const u32 *formats;
	size_t nformats;
	int ret;

	display_info = &lcdc->panel->connector->display_info;

	if (!display_info->num_bus_formats || !display_info->bus_formats) {
		DRM_DEV_ERROR(lcdc->dev, "missing bus_format from panel");
		return -EINVAL;
	}

	switch (display_info->bus_formats[0]) {
		case MEDIA_BUS_FMT_RGB888_1X24:
		case MEDIA_BUS_FMT_RGB565_1X16:
			lcdc->bus_format = display_info->bus_formats[0];
			break;
		default:
			DRM_DEV_ERROR(lcdc->dev, "unsupported bus_format: %d",
				      display_info->bus_formats[0]);
			return -EINVAL;
	}

	/* Select formats depending on wiring (from bus_formats + from DT) */
	if (lcdc->bus_format == MEDIA_BUS_FMT_RGB888_1X24) {
		if (!lcdc->wiring_reversed) {
			formats = bgr_formats_24;
			nformats = ARRAY_SIZE(bgr_formats_24);
		} else {
			formats = rgb_formats_24;
			nformats = ARRAY_SIZE(rgb_formats_24);
		}
	} else {
		if (!lcdc->wiring_reversed) {
			formats = bgr_formats_16;
			nformats = ARRAY_SIZE(bgr_formats_16);
		} else {
			formats = rgb_formats_16;
			nformats = ARRAY_SIZE(rgb_formats_16);
		}
	}

	ret = drm_simple_display_pipe_init(drm, &lcdc->pipe,
					   &lcdc_display_funcs,
					   formats, nformats,
					   NULL, &lcdc->connector);
	if (ret < 0)
		DRM_DEV_ERROR(lcdc->dev, "failed to init display pipe: %d",
			      ret);

	return ret;
}

static int lcdc_attach_panel(struct lcdc *lcdc, struct drm_device *drm)
{
	struct drm_bridge *bridge;
	struct drm_panel *panel;
	struct device *dev;
	int ret;

	dev = lcdc->dev;

	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, &bridge);
	if (ret < 0)
		return ret;

	if (panel) {
		lcdc->panel = panel;
		bridge = devm_drm_panel_bridge_add(dev, panel,
						   DRM_MODE_CONNECTOR_DPI);
		ret = PTR_ERR_OR_ZERO(bridge);
		if (ret < 0) {
			DRM_DEV_ERROR(dev, "failed to add bridge: %d", ret);
			return ret;
		}

	} else {
		DRM_DEV_ERROR(dev, "the bridge is not a panel");
		return -ENODEV;
	}

	ret = lcdc_display_init(lcdc, drm);
	if (ret < 0)
		return ret;

	ret = drm_simple_display_pipe_attach_bridge(&lcdc->pipe, bridge);
	if (ret < 0)
		DRM_DEV_ERROR(dev, "failed to attach bridge: %d", ret);

	return ret;
}

static int lcdc_create_output(struct lcdc *lcdc, struct drm_device *drm)
{
	struct device_node *endpoint;
	int ret;

	/* port@0/endpoint@0 is the only port/endpoint */
	endpoint = of_graph_get_endpoint_by_regs(drm->dev->of_node, 0, 0);
	if (!endpoint) {
		DRM_DEV_ERROR(lcdc->dev, "failed to find endpoint node");
		return -ENODEV;
	}

	lcdc_get_of_wiring(lcdc, endpoint);
	of_node_put(endpoint);

	ret = lcdc_attach_panel(lcdc, drm);

	return ret;
}


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2019-01-07 18:04 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-02 17:02 [PATCH 0/3] drm/mxsfb: support swapped RGB lanes Ahmad Fatoum
2019-01-02 17:02 ` [PATCH 1/3] drm/mxsfb: use bus_format to determine pixel RGB component order Ahmad Fatoum
2019-01-02 17:14   ` Ahmad Fatoum
2019-01-02 17:02 ` [PATCH 2/3] drm/mxsfb: implement interface-pix-fmt of_property to override bus format Ahmad Fatoum
2019-01-02 17:02 ` [PATCH 3/3] dt-bindings: mxsfb: document new interface-pix-fmt property Ahmad Fatoum
2019-01-02 21:05 ` [PATCH 0/3] drm/mxsfb: support swapped RGB lanes Stefan Agner
2019-01-02 21:37   ` Sam Ravnborg
2019-01-07 17:35     ` Ahmad Fatoum
2019-01-07 18:04       ` Sam Ravnborg [this message]
2019-03-27 14:26         ` Ahmad Fatoum
2019-01-03  9:59   ` Ahmad Fatoum
2019-03-27 14:30   ` Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190107180425.GA28018@ravnborg.org \
    --to=sam@ravnborg.org \
    --cc=a.fatoum@pengutronix.de \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kernel@pengutronix.de \
    --cc=marex@denx.de \
    --cc=peda@axentia.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox