Skip to content

Commit 6afb772

Browse files
Maciej Purskidaeinki
authored andcommitted
drm/exynos: move connector creation to attach callback
The current implementation assumes that the only possible peripheral device for DSIM is a panel. Using an output bridge child device should also be possible. If an output bridge is available, don't create a new connector. Instead, call drm_bridge_attach() and set encoder's bridge to NULL in order to avoid an out bridge from being visible by the framework, as the DSI bus needs control on enabling its child output bridge. Such sequence is required by Toshiba TC358764 bridge, which is a DSI peripheral bridge device. changed in v5: - detach bridge in mipi_dsi detach callback Signed-off-by: Maciej Purski <m.purski@samsung.com> [ a.hajda@samsung.com: v5 ] Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Manually merged due to merge conflict. Signed-off-by: Inki Dae <inki.dae@samsung.com>
1 parent 2782622 commit 6afb772

File tree

1 file changed

+32
-21
lines changed

1 file changed

+32
-21
lines changed

drivers/gpu/drm/exynos/exynos_drm_dsi.c

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ struct exynos_dsi {
255255
struct mipi_dsi_host dsi_host;
256256
struct drm_connector connector;
257257
struct drm_panel *panel;
258+
struct drm_bridge *out_bridge;
258259
struct device *dev;
259260

260261
void __iomem *reg_base;
@@ -1499,7 +1500,30 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
14991500
struct mipi_dsi_device *device)
15001501
{
15011502
struct exynos_dsi *dsi = host_to_dsi(host);
1502-
struct drm_device *drm = dsi->connector.dev;
1503+
struct drm_encoder *encoder = &dsi->encoder;
1504+
struct drm_device *drm = encoder->dev;
1505+
struct drm_bridge *out_bridge;
1506+
1507+
out_bridge = of_drm_find_bridge(device->dev.of_node);
1508+
if (out_bridge) {
1509+
drm_bridge_attach(encoder, out_bridge, NULL);
1510+
dsi->out_bridge = out_bridge;
1511+
encoder->bridge = NULL;
1512+
} else {
1513+
int ret = exynos_dsi_create_connector(encoder);
1514+
1515+
if (ret) {
1516+
DRM_ERROR("failed to create connector ret = %d\n", ret);
1517+
drm_encoder_cleanup(encoder);
1518+
return ret;
1519+
}
1520+
1521+
dsi->panel = of_drm_find_panel(device->dev.of_node);
1522+
if (dsi->panel) {
1523+
drm_panel_attach(dsi->panel, &dsi->connector);
1524+
dsi->connector.status = connector_status_connected;
1525+
}
1526+
}
15031527

15041528
/*
15051529
* This is a temporary solution and should be made by more generic way.
@@ -1518,14 +1542,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
15181542
dsi->lanes = device->lanes;
15191543
dsi->format = device->format;
15201544
dsi->mode_flags = device->mode_flags;
1521-
dsi->panel = of_drm_find_panel(device->dev.of_node);
1522-
if (IS_ERR(dsi->panel))
1523-
dsi->panel = NULL;
1524-
1525-
if (dsi->panel) {
1526-
drm_panel_attach(dsi->panel, &dsi->connector);
1527-
dsi->connector.status = connector_status_connected;
1528-
}
15291545
exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
15301546
!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
15311547

@@ -1541,19 +1557,21 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
15411557
struct mipi_dsi_device *device)
15421558
{
15431559
struct exynos_dsi *dsi = host_to_dsi(host);
1544-
struct drm_device *drm = dsi->connector.dev;
1545-
1546-
mutex_lock(&drm->mode_config.mutex);
1560+
struct drm_device *drm = dsi->encoder.dev;
15471561

15481562
if (dsi->panel) {
1563+
mutex_lock(&drm->mode_config.mutex);
15491564
exynos_dsi_disable(&dsi->encoder);
15501565
drm_panel_detach(dsi->panel);
15511566
dsi->panel = NULL;
15521567
dsi->connector.status = connector_status_disconnected;
1568+
mutex_unlock(&drm->mode_config.mutex);
1569+
} else {
1570+
if (dsi->out_bridge->funcs->detach)
1571+
dsi->out_bridge->funcs->detach(dsi->out_bridge);
1572+
dsi->out_bridge = NULL;
15531573
}
15541574

1555-
mutex_unlock(&drm->mode_config.mutex);
1556-
15571575
if (drm->mode_config.poll_enabled)
15581576
drm_kms_helper_hotplug_event(drm);
15591577

@@ -1657,13 +1675,6 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
16571675
if (ret < 0)
16581676
return ret;
16591677

1660-
ret = exynos_dsi_create_connector(encoder);
1661-
if (ret) {
1662-
DRM_ERROR("failed to create connector ret = %d\n", ret);
1663-
drm_encoder_cleanup(encoder);
1664-
return ret;
1665-
}
1666-
16671678
if (dsi->in_bridge_node) {
16681679
in_bridge = of_drm_find_bridge(dsi->in_bridge_node);
16691680
if (in_bridge)

0 commit comments

Comments
 (0)