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
next prev parent 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.