Skip to content

Commit

Permalink
drm/panel-simple: allow LVDS format override
Browse files Browse the repository at this point in the history
Some panels support multiple LVDS data mapping formats, which can be
used e.g. run displays on jeida-18 format when only 3 LVDS lanes are
available.

Add parsing of an optional data-mapping devicetree property, which also
touches up the bits per color to match the bus format.

Signed-off-by: Johannes Zink <j.zink@pengutronix.de>
Link: https://lore.kernel.org/r/20230523-simplepanel_support_nondefault_datamapping-v5-3-0d7928edafab@pengutronix.de
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230523-simplepanel_support_nondefault_datamapping-v5-3-0d7928edafab@pengutronix.de
  • Loading branch information
Johannes Zink authored and Neil Armstrong committed Oct 9, 2023
1 parent 66b66c9 commit 1cd3ea3
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions drivers/gpu/drm/panel/panel-simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
#include <drm/drm_of.h>

/**
* struct panel_desc - Describes a simple panel.
Expand Down Expand Up @@ -549,6 +550,51 @@ static void panel_simple_parse_panel_timing_node(struct device *dev,
dev_err(dev, "Reject override mode: No display_timing found\n");
}

static int panel_simple_override_nondefault_lvds_datamapping(struct device *dev,
struct panel_simple *panel)
{
int ret, bpc;

ret = drm_of_lvds_get_data_mapping(dev->of_node);
if (ret < 0) {
if (ret == -EINVAL)
dev_warn(dev, "Ignore invalid data-mapping property\n");

/*
* Ignore non-existing or malformatted property, fallback to
* default data-mapping, and return 0.
*/
return 0;
}

switch (ret) {
default:
WARN_ON(1);
fallthrough;
case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
fallthrough;
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
bpc = 8;
break;
case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
bpc = 6;
}

if (panel->desc->bpc != bpc || panel->desc->bus_format != ret) {
struct panel_desc *override_desc;

override_desc = devm_kmemdup(dev, panel->desc, sizeof(*panel->desc), GFP_KERNEL);
if (!override_desc)
return -ENOMEM;

override_desc->bus_format = ret;
override_desc->bpc = bpc;
panel->desc = override_desc;
}

return 0;
}

static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
{
struct panel_simple *panel;
Expand Down Expand Up @@ -601,6 +647,13 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
panel_simple_parse_panel_timing_node(dev, panel, &dt);
}

if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
/* Optional data-mapping property for overriding bus format */
err = panel_simple_override_nondefault_lvds_datamapping(dev, panel);
if (err)
goto free_ddc;
}

connector_type = desc->connector_type;
/* Catch common mistakes for panels. */
switch (connector_type) {
Expand Down

0 comments on commit 1cd3ea3

Please sign in to comment.