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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox