Commit 1f79c60e authored by Stephan Gerhold's avatar Stephan Gerhold Committed by Linus Walleij

drm/mcde: dsi: Fix duplicated DSI connector

Using a (single) DSI display with MCDE currently results in
two "connected" connectors:

  Connector: DSI-1
          id             : 34
          encoder id     : 0
          conn           : connected
          size           : 0x0 (mm)
          count_modes    : 0
          count_props    : 5
          props          : 1 2 5 6 4
          count_encoders : 1
          encoders       : 33
  Connector: DSI-2
          id             : 35
          encoder id     : 33
          conn           : connected
          size           : 53x89 (mm)
          count_modes    : 1
          count_props    : 5
          props          : 1 2 5 6 4
          count_encoders : 1
          encoders       : 33
    Mode: "480x800" 480x800 60

Although both show up as connected, the first one does not have
any size and no available modes. This confuses userspace tools
(e.g. kmscube) who look for available modes for the first connector.

The reason for the duplicated connector is that mcde_dsi.c and the
DRM panel bridge helper both set up a DSI connector, with more or less
the same code. The connector set up by the DRM panel bridge is the
one that is correctly set up in the example above.

Therefore we can just remove the connector setup from mcde_dsi.c
and let the DRM core handle all the hard work.
Signed-off-by: default avatarStephan Gerhold <stephan@gerhold.net>
Tested-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191106165835.2863-6-stephan@gerhold.net
parent 6ddfb00d
...@@ -39,7 +39,6 @@ struct mcde_dsi { ...@@ -39,7 +39,6 @@ struct mcde_dsi {
struct device *dev; struct device *dev;
struct mcde *mcde; struct mcde *mcde;
struct drm_bridge bridge; struct drm_bridge bridge;
struct drm_connector connector;
struct drm_panel *panel; struct drm_panel *panel;
struct drm_bridge *bridge_out; struct drm_bridge *bridge_out;
struct mipi_dsi_host dsi_host; struct mipi_dsi_host dsi_host;
...@@ -64,11 +63,6 @@ static inline struct mcde_dsi *host_to_mcde_dsi(struct mipi_dsi_host *h) ...@@ -64,11 +63,6 @@ static inline struct mcde_dsi *host_to_mcde_dsi(struct mipi_dsi_host *h)
return container_of(h, struct mcde_dsi, dsi_host); return container_of(h, struct mcde_dsi, dsi_host);
} }
static inline struct mcde_dsi *connector_to_mcde_dsi(struct drm_connector *c)
{
return container_of(c, struct mcde_dsi, connector);
}
bool mcde_dsi_irq(struct mipi_dsi_device *mdsi) bool mcde_dsi_irq(struct mipi_dsi_device *mdsi)
{ {
struct mcde_dsi *d; struct mcde_dsi *d;
...@@ -843,67 +837,23 @@ static void mcde_dsi_bridge_disable(struct drm_bridge *bridge) ...@@ -843,67 +837,23 @@ static void mcde_dsi_bridge_disable(struct drm_bridge *bridge)
clk_disable_unprepare(d->lp_clk); clk_disable_unprepare(d->lp_clk);
} }
/*
* This connector needs no special handling, just use the default
* helpers for everything. It's pretty dummy.
*/
static const struct drm_connector_funcs mcde_dsi_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static int mcde_dsi_get_modes(struct drm_connector *connector)
{
struct mcde_dsi *d = connector_to_mcde_dsi(connector);
/* Just pass the question to the panel */
if (d->panel)
return drm_panel_get_modes(d->panel);
/* TODO: deal with bridges */
return 0;
}
static const struct drm_connector_helper_funcs
mcde_dsi_connector_helper_funcs = {
.get_modes = mcde_dsi_get_modes,
};
static int mcde_dsi_bridge_attach(struct drm_bridge *bridge) static int mcde_dsi_bridge_attach(struct drm_bridge *bridge)
{ {
struct mcde_dsi *d = bridge_to_mcde_dsi(bridge); struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);
struct drm_device *drm = bridge->dev; struct drm_device *drm = bridge->dev;
int ret; int ret;
drm_connector_helper_add(&d->connector,
&mcde_dsi_connector_helper_funcs);
if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) { if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) {
dev_err(d->dev, "we need atomic updates\n"); dev_err(d->dev, "we need atomic updates\n");
return -ENOTSUPP; return -ENOTSUPP;
} }
ret = drm_connector_init(drm, &d->connector, /* Attach the DSI bridge to the output (panel etc) bridge */
&mcde_dsi_connector_funcs,
DRM_MODE_CONNECTOR_DSI);
if (ret) {
dev_err(d->dev, "failed to initialize DSI bridge connector\n");
return ret;
}
d->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
/* The encoder in the bridge attached to the DSI bridge */
drm_connector_attach_encoder(&d->connector, bridge->encoder);
/* Then we attach the DSI bridge to the output (panel etc) bridge */
ret = drm_bridge_attach(bridge->encoder, d->bridge_out, bridge); ret = drm_bridge_attach(bridge->encoder, d->bridge_out, bridge);
if (ret) { if (ret) {
dev_err(d->dev, "failed to attach the DSI bridge\n"); dev_err(d->dev, "failed to attach the DSI bridge\n");
return ret; return ret;
} }
d->connector.status = connector_status_connected;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment