The NT36672E panel in the MIPI D-PHY mode is connected over 4 data lanes, a mismatching device tree description results in a panel, which won't work.
Get the PHY type of the DSI link from the PHY of the DSI host, and get the number of data lanes from the DSI host endpoint to check the match. Signed-off-by: Vladimir Zapolskiy <[email protected]> --- .../gpu/drm/panel/panel-novatek-nt36672e.c | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c index 0a2d54ee8069..33676e334b9f 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c @@ -5,14 +5,18 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_graph.h> #include <linux/regulator/consumer.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_modes.h> +#include <drm/drm_of.h> #include <drm/drm_panel.h> #include <video/mipi_display.h> +#include <dt-bindings/phy/phy.h> + static const struct regulator_bulk_data nt36672e_supplies[] = { { .supply = "vddi", .init_load_uA = 62000 }, }; @@ -536,6 +540,30 @@ static const struct drm_panel_funcs nt36672e_drm_funcs = { .get_modes = nt36672e_panel_get_modes, }; +/* + * Get the PHY type of the DSI link from the PHY of the DSI host, MIPI D-PHY + * is the default, if the PHY type is not specified. + */ +static u32 nt36672e_get_dsi_phy_type(struct device *dev) +{ + struct device_node *host, *phy; + u32 phy_type = PHY_TYPE_DPHY; + + host = of_graph_get_remote_node(dev->of_node, 0, 0); + if (!host) + return phy_type; + + phy = of_parse_phandle(host, "phys", 0); + of_node_put(host); + if (!phy) + return phy_type; + + of_property_read_u32(phy, "phy-type", &phy_type); + of_node_put(phy); + + return phy_type; +} + static int nt36672e_panel_probe(struct mipi_dsi_device *dsi) { struct device *dev = &dsi->dev; @@ -598,6 +626,15 @@ static int nt36672e_panel_probe(struct mipi_dsi_device *dsi) dsi->format = ctx->desc->format; dsi->mode_flags = ctx->desc->mode_flags; + /* A MIPI D-PHY link to the panel shall have exactly 4 data lanes */ + if (nt36672e_get_dsi_phy_type(dev) == PHY_TYPE_DPHY) { + ret = drm_of_get_data_lanes_count_remote(dev->of_node, 0, -1, 1, 4); + if (ret > 0 && ret != 4) + return dev_err_probe(dev, -EINVAL, + "%d D-PHY data lanes described, 4 required\n", + ret); + } + ret = drm_panel_of_backlight(&ctx->panel); if (ret) return dev_err_probe(dev, ret, "Failed to get backlight\n"); -- 2.51.0
