diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/lvds-codec.c')
-rw-r--r-- | drivers/gpu/drm/bridge/lvds-codec.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/gpu/drm/bridge/lvds-codec.c b/drivers/gpu/drm/bridge/lvds-codec.c index ad460b96c0a3..702ea803a743 100644 --- a/drivers/gpu/drm/bridge/lvds-codec.c +++ b/drivers/gpu/drm/bridge/lvds-codec.c @@ -14,12 +14,14 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_of.h> #include <drm/drm_panel.h> struct lvds_codec { struct device *dev; struct drm_bridge bridge; struct drm_bridge *panel_bridge; + struct drm_bridge_timings timings; struct regulator *vcc; struct gpio_desc *powerdown_gpio; u32 connector_type; @@ -118,7 +120,7 @@ static int lvds_codec_probe(struct platform_device *pdev) struct device_node *bus_node; struct drm_panel *panel; struct lvds_codec *lvds_codec; - const char *mapping; + u32 val; int ret; lvds_codec = devm_kzalloc(dev, sizeof(*lvds_codec), GFP_KERNEL); @@ -174,32 +176,38 @@ static int lvds_codec_probe(struct platform_device *pdev) return -ENXIO; } - ret = of_property_read_string(bus_node, "data-mapping", - &mapping); + ret = drm_of_lvds_get_data_mapping(bus_node); of_node_put(bus_node); - if (ret < 0) { + if (ret == -ENODEV) { dev_warn(dev, "missing 'data-mapping' DT property\n"); + } else if (ret) { + dev_err(dev, "invalid 'data-mapping' DT property\n"); + return ret; } else { - if (!strcmp(mapping, "jeida-18")) { - lvds_codec->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG; - } else if (!strcmp(mapping, "jeida-24")) { - lvds_codec->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA; - } else if (!strcmp(mapping, "vesa-24")) { - lvds_codec->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG; - } else { - dev_err(dev, "invalid 'data-mapping' DT property\n"); - return -EINVAL; - } + lvds_codec->bus_format = ret; lvds_codec->bridge.funcs = &funcs_decoder; } } /* + * Encoder might sample data on different clock edge than the display, + * for example OnSemi FIN3385 has a dedicated strapping pin to select + * the sampling edge. + */ + if (lvds_codec->connector_type == DRM_MODE_CONNECTOR_LVDS && + !of_property_read_u32(dev->of_node, "pclk-sample", &val)) { + lvds_codec->timings.input_bus_flags = val ? + DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE : + DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE; + } + + /* * The panel_bridge bridge is attached to the panel's of_node, * but we need a bridge attached to our of_node for our user * to look up. */ lvds_codec->bridge.of_node = dev->of_node; + lvds_codec->bridge.timings = &lvds_codec->timings; drm_bridge_add(&lvds_codec->bridge); platform_set_drvdata(pdev, lvds_codec); |