Updated series about drm bridge conversion of exynos dsi.
Patch 1: panel checker
Patch 2: panel_bridge API
Patch 3: Bridge conversion
Patch 4: Atomic functions
[1] https://patchwork.kernel.org/project/dri-devel/cover/20211122070633.89219-1-...
Any inputs? Jagan.
Jagan Teki (4): drm: exynos: dsi: Check panel for panel helpers drm: exynos: dsi: Use drm panel_bridge API drm: exynos: dsi: Convert to bridge driver drm: exynos: dsi: Switch to atomic funcs
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 208 ++++++------------------ 1 file changed, 51 insertions(+), 157 deletions(-)
Trigger the panel operation helpers only if host found the panel.
Add check.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - new patch
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 8d137857818c..0bb44e476633 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1439,7 +1439,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
- drm_panel_disable(dsi->panel); + if (dsi->panel) + drm_panel_disable(dsi->panel);
list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) { if (iter->funcs->disable) @@ -1447,7 +1448,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder) }
exynos_dsi_set_display_enable(dsi, false); - drm_panel_unprepare(dsi->panel); + if (dsi->panel) + drm_panel_unprepare(dsi->panel);
list_for_each_entry(iter, &dsi->bridge_chain, chain_node) { if (iter->funcs->post_disable)
On 10.12.2021 20:19, Jagan Teki wrote:
Trigger the panel operation helpers only if host found the panel.
Add check.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com
Both helpers handle already "NULL panels", so these checks are redundant.
Regards
Andrzej
Changes for v2:
new patch
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 8d137857818c..0bb44e476633 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1439,7 +1439,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
- drm_panel_disable(dsi->panel);
if (dsi->panel)
drm_panel_disable(dsi->panel);
list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) { if (iter->funcs->disable)
@@ -1447,7 +1448,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder) }
exynos_dsi_set_display_enable(dsi, false);
- drm_panel_unprepare(dsi->panel);
if (dsi->panel)
drm_panel_unprepare(dsi->panel);
list_for_each_entry(iter, &dsi->bridge_chain, chain_node) { if (iter->funcs->post_disable)
Hi Andrzej,
On Mon, Dec 13, 2021 at 1:44 PM Andrzej Hajda andrzej.hajda@intel.com wrote:
On 10.12.2021 20:19, Jagan Teki wrote:
Trigger the panel operation helpers only if host found the panel.
Add check.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com
Both helpers handle already "NULL panels", so these checks are redundant.
Got it. Please look at v3 if you have time.
Thanks, Jagan.
Replace the manual panel handling code by a drm panel_bridge via devm_drm_of_get_bridge().
Adding panel_bridge handling,
- Drops drm_connector and related operations as drm_bridge_attach creates connector during attachment.
- Drops panel pointer and iterate the bridge, so-that it can operate the normal bridge and panel_bridge in constitutive callbacks.
This simplifies the driver and allows all components in the display pipeline to be treated as bridges.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - new patch
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 147 +++--------------------- 1 file changed, 14 insertions(+), 133 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 0bb44e476633..8c6f7ac82822 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -254,8 +254,6 @@ struct exynos_dsi_driver_data { struct exynos_dsi { struct drm_encoder encoder; struct mipi_dsi_host dsi_host; - struct drm_connector connector; - struct drm_panel *panel; struct list_head bridge_chain; struct drm_bridge *out_bridge; struct device *dev; @@ -285,7 +283,6 @@ struct exynos_dsi { };
#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) -#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e) { @@ -1391,42 +1388,21 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
dsi->state |= DSIM_STATE_ENABLED;
- if (dsi->panel) { - ret = drm_panel_prepare(dsi->panel); - if (ret < 0) - goto err_put_sync; - } else { - list_for_each_entry_reverse(iter, &dsi->bridge_chain, - chain_node) { - if (iter->funcs->pre_enable) - iter->funcs->pre_enable(iter); - } + list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) { + if (iter->funcs->pre_enable) + iter->funcs->pre_enable(iter); }
exynos_dsi_set_display_mode(dsi); exynos_dsi_set_display_enable(dsi, true);
- if (dsi->panel) { - ret = drm_panel_enable(dsi->panel); - if (ret < 0) - goto err_display_disable; - } else { - list_for_each_entry(iter, &dsi->bridge_chain, chain_node) { - if (iter->funcs->enable) - iter->funcs->enable(iter); - } + list_for_each_entry(iter, &dsi->bridge_chain, chain_node) { + if (iter->funcs->enable) + iter->funcs->enable(iter); }
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; return; - -err_display_disable: - exynos_dsi_set_display_enable(dsi, false); - drm_panel_unprepare(dsi->panel); - -err_put_sync: - dsi->state &= ~DSIM_STATE_ENABLED; - pm_runtime_put(dsi->dev); }
static void exynos_dsi_disable(struct drm_encoder *encoder) @@ -1439,17 +1415,12 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
- if (dsi->panel) - drm_panel_disable(dsi->panel); - list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) { if (iter->funcs->disable) iter->funcs->disable(iter); }
exynos_dsi_set_display_enable(dsi, false); - if (dsi->panel) - drm_panel_unprepare(dsi->panel);
list_for_each_entry(iter, &dsi->bridge_chain, chain_node) { if (iter->funcs->post_disable) @@ -1460,70 +1431,6 @@ static void exynos_dsi_disable(struct drm_encoder *encoder) pm_runtime_put_sync(dsi->dev); }
-static enum drm_connector_status -exynos_dsi_detect(struct drm_connector *connector, bool force) -{ - return connector->status; -} - -static void exynos_dsi_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); - connector->dev = NULL; -} - -static const struct drm_connector_funcs exynos_dsi_connector_funcs = { - .detect = exynos_dsi_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = exynos_dsi_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int exynos_dsi_get_modes(struct drm_connector *connector) -{ - struct exynos_dsi *dsi = connector_to_dsi(connector); - - if (dsi->panel) - return drm_panel_get_modes(dsi->panel, connector); - - return 0; -} - -static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = { - .get_modes = exynos_dsi_get_modes, -}; - -static int exynos_dsi_create_connector(struct drm_encoder *encoder) -{ - struct exynos_dsi *dsi = encoder_to_dsi(encoder); - struct drm_connector *connector = &dsi->connector; - struct drm_device *drm = encoder->dev; - int ret; - - connector->polled = DRM_CONNECTOR_POLL_HPD; - - ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs, - DRM_MODE_CONNECTOR_DSI); - if (ret) { - DRM_DEV_ERROR(dsi->dev, - "Failed to initialize connector with drm\n"); - return ret; - } - - connector->status = connector_status_disconnected; - drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs); - drm_connector_attach_encoder(connector, encoder); - if (!drm->registered) - return 0; - - connector->funcs->reset(connector); - drm_connector_register(connector); - return 0; -} - static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = { .enable = exynos_dsi_enable, .disable = exynos_dsi_disable, @@ -1537,30 +1444,13 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, struct exynos_dsi *dsi = host_to_dsi(host); struct drm_encoder *encoder = &dsi->encoder; struct drm_device *drm = encoder->dev; - struct drm_bridge *out_bridge;
- out_bridge = of_drm_find_bridge(device->dev.of_node); - if (out_bridge) { - drm_bridge_attach(encoder, out_bridge, NULL, 0); - dsi->out_bridge = out_bridge; - list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain); - } else { - int ret = exynos_dsi_create_connector(encoder); - - if (ret) { - DRM_DEV_ERROR(dsi->dev, - "failed to create connector ret = %d\n", - ret); - drm_encoder_cleanup(encoder); - return ret; - } + dsi->out_bridge = devm_drm_of_get_bridge(dsi->dev, dsi->dev->of_node, 0, 0); + if (IS_ERR(dsi->out_bridge)) + return PTR_ERR(dsi->out_bridge);
- dsi->panel = of_drm_find_panel(device->dev.of_node); - if (IS_ERR(dsi->panel)) - dsi->panel = NULL; - else - dsi->connector.status = connector_status_connected; - } + drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0); + list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
/* * This is a temporary solution and should be made by more generic way. @@ -1596,18 +1486,9 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host, struct exynos_dsi *dsi = host_to_dsi(host); struct drm_device *drm = dsi->encoder.dev;
- if (dsi->panel) { - mutex_lock(&drm->mode_config.mutex); - exynos_dsi_disable(&dsi->encoder); - dsi->panel = NULL; - dsi->connector.status = connector_status_disconnected; - mutex_unlock(&drm->mode_config.mutex); - } else { - if (dsi->out_bridge->funcs->detach) - dsi->out_bridge->funcs->detach(dsi->out_bridge); - dsi->out_bridge = NULL; - INIT_LIST_HEAD(&dsi->bridge_chain); - } + if (dsi->out_bridge->funcs->detach) + dsi->out_bridge->funcs->detach(dsi->out_bridge); + INIT_LIST_HEAD(&dsi->bridge_chain);
if (drm->mode_config.poll_enabled) drm_kms_helper_hotplug_event(drm);
Convert the encoders to bridge drivers in order to standardize on a single API with built-in dumb encoder support for compatibility with existing component drivers.
Driver bridge conversion will help to reuse the same bridge on different platforms as exynos dsi driver can be used as a Samsung DSIM and use it for i.MX8MM platform.
Bridge conversion,
- Drops drm_encoder_helper_funcs, bridge_chain.
- Adds drm_bridge_funcs and register a drm bridge.
Convert it.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - drop bridge_chain
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 84 +++++++++++++------------ 1 file changed, 45 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 8c6f7ac82822..37ad94b563c4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -254,7 +254,7 @@ struct exynos_dsi_driver_data { struct exynos_dsi { struct drm_encoder encoder; struct mipi_dsi_host dsi_host; - struct list_head bridge_chain; + struct drm_bridge bridge; struct drm_bridge *out_bridge; struct device *dev;
@@ -284,9 +284,9 @@ struct exynos_dsi {
#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
-static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e) +static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b) { - return container_of(e, struct exynos_dsi, encoder); + return container_of(b, struct exynos_dsi, bridge); }
enum reg_idx { @@ -877,9 +877,10 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi) return 0; }
-static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi) +static void exynos_dsi_set_display_mode(struct drm_bridge *bridge) { - struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode; + struct exynos_dsi *dsi = bridge_to_dsi(bridge); + struct drm_display_mode *m = &bridge->encoder->crtc->state->adjusted_mode; unsigned int num_bits_resol = dsi->driver_data->num_bits_resol; u32 reg;
@@ -1371,10 +1372,10 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi) } }
-static void exynos_dsi_enable(struct drm_encoder *encoder) +static void exynos_dsi_enable(struct drm_bridge *bridge) { - struct exynos_dsi *dsi = encoder_to_dsi(encoder); - struct drm_bridge *iter; + struct exynos_dsi *dsi = bridge_to_dsi(bridge); + const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs; int ret;
if (dsi->state & DSIM_STATE_ENABLED) @@ -1388,52 +1389,53 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
dsi->state |= DSIM_STATE_ENABLED;
- list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) { - if (iter->funcs->pre_enable) - iter->funcs->pre_enable(iter); - } + if (dsi->out_bridge) + funcs->pre_enable(dsi->out_bridge);
- exynos_dsi_set_display_mode(dsi); + exynos_dsi_set_display_mode(bridge); exynos_dsi_set_display_enable(dsi, true);
- list_for_each_entry(iter, &dsi->bridge_chain, chain_node) { - if (iter->funcs->enable) - iter->funcs->enable(iter); - } + if (dsi->out_bridge) + funcs->enable(dsi->out_bridge);
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; return; }
-static void exynos_dsi_disable(struct drm_encoder *encoder) +static void exynos_dsi_disable(struct drm_bridge *bridge) { - struct exynos_dsi *dsi = encoder_to_dsi(encoder); - struct drm_bridge *iter; + struct exynos_dsi *dsi = bridge_to_dsi(bridge); + const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
if (!(dsi->state & DSIM_STATE_ENABLED)) return;
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
- list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) { - if (iter->funcs->disable) - iter->funcs->disable(iter); - } + if (dsi->out_bridge) + funcs->disable(dsi->out_bridge);
exynos_dsi_set_display_enable(dsi, false);
- list_for_each_entry(iter, &dsi->bridge_chain, chain_node) { - if (iter->funcs->post_disable) - iter->funcs->post_disable(iter); - } + if (dsi->out_bridge) + funcs->post_disable(dsi->out_bridge);
dsi->state &= ~DSIM_STATE_ENABLED; pm_runtime_put_sync(dsi->dev); }
-static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = { - .enable = exynos_dsi_enable, - .disable = exynos_dsi_disable, +static int exynos_dsi_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct exynos_dsi *dsi = bridge_to_dsi(bridge); + + return drm_bridge_attach(bridge->encoder, dsi->out_bridge, NULL, 0); +} + +static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = { + .enable = exynos_dsi_enable, + .disable = exynos_dsi_disable, + .attach = exynos_dsi_attach, };
MODULE_DEVICE_TABLE(of, exynos_dsi_of_match); @@ -1449,8 +1451,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, if (IS_ERR(dsi->out_bridge)) return PTR_ERR(dsi->out_bridge);
- drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0); - list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain); + drm_bridge_attach(encoder, &dsi->bridge, NULL, 0);
/* * This is a temporary solution and should be made by more generic way. @@ -1488,7 +1489,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
if (dsi->out_bridge->funcs->detach) dsi->out_bridge->funcs->detach(dsi->out_bridge); - INIT_LIST_HEAD(&dsi->bridge_chain);
if (drm->mode_config.poll_enabled) drm_kms_helper_hotplug_event(drm); @@ -1585,8 +1585,6 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
- drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs); - ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD); if (ret < 0) return ret; @@ -1606,9 +1604,8 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master, void *data) { struct exynos_dsi *dsi = dev_get_drvdata(dev); - struct drm_encoder *encoder = &dsi->encoder;
- exynos_dsi_disable(encoder); + exynos_dsi_disable(&dsi->bridge);
mipi_dsi_host_unregister(&dsi->dsi_host); } @@ -1634,7 +1631,6 @@ static int exynos_dsi_probe(struct platform_device *pdev) init_completion(&dsi->completed); spin_lock_init(&dsi->transfer_lock); INIT_LIST_HEAD(&dsi->transfer_list); - INIT_LIST_HEAD(&dsi->bridge_chain);
dsi->dsi_host.ops = &exynos_dsi_ops; dsi->dsi_host.dev = dev; @@ -1702,6 +1698,12 @@ static int exynos_dsi_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
+ dsi->bridge.funcs = &exynos_dsi_bridge_funcs; + dsi->bridge.of_node = dev->of_node; + dsi->bridge.type = DRM_MODE_CONNECTOR_DSI; + + drm_bridge_add(&dsi->bridge); + ret = component_add(dev, &exynos_dsi_component_ops); if (ret) goto err_disable_runtime; @@ -1716,6 +1718,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
static int exynos_dsi_remove(struct platform_device *pdev) { + struct exynos_dsi *dsi = platform_get_drvdata(pdev); + + drm_bridge_remove(&dsi->bridge); + pm_runtime_disable(&pdev->dev);
component_del(&pdev->dev, &exynos_dsi_component_ops);
The new support drm bridges are moving towards atomic functions.
Replace atomic version of functions to continue the transition to the atomic API.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - new patch
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 37ad94b563c4..f2c12a356952 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1372,7 +1372,8 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi) } }
-static void exynos_dsi_enable(struct drm_bridge *bridge) +static void exynos_dsi_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct exynos_dsi *dsi = bridge_to_dsi(bridge); const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs; @@ -1390,19 +1391,20 @@ static void exynos_dsi_enable(struct drm_bridge *bridge) dsi->state |= DSIM_STATE_ENABLED;
if (dsi->out_bridge) - funcs->pre_enable(dsi->out_bridge); + funcs->atomic_pre_enable(dsi->out_bridge, old_bridge_state);
exynos_dsi_set_display_mode(bridge); exynos_dsi_set_display_enable(dsi, true);
if (dsi->out_bridge) - funcs->enable(dsi->out_bridge); + funcs->atomic_enable(dsi->out_bridge, old_bridge_state);
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; return; }
-static void exynos_dsi_disable(struct drm_bridge *bridge) +static void exynos_dsi_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct exynos_dsi *dsi = bridge_to_dsi(bridge); const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs; @@ -1413,12 +1415,12 @@ static void exynos_dsi_disable(struct drm_bridge *bridge) dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
if (dsi->out_bridge) - funcs->disable(dsi->out_bridge); + funcs->atomic_disable(dsi->out_bridge, old_bridge_state);
exynos_dsi_set_display_enable(dsi, false);
if (dsi->out_bridge) - funcs->post_disable(dsi->out_bridge); + funcs->atomic_post_disable(dsi->out_bridge, old_bridge_state);
dsi->state &= ~DSIM_STATE_ENABLED; pm_runtime_put_sync(dsi->dev); @@ -1433,8 +1435,11 @@ static int exynos_dsi_attach(struct drm_bridge *bridge, }
static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = { - .enable = exynos_dsi_enable, - .disable = exynos_dsi_disable, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_enable = exynos_dsi_atomic_enable, + .atomic_disable = exynos_dsi_atomic_disable, .attach = exynos_dsi_attach, };
@@ -1605,7 +1610,7 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master, { struct exynos_dsi *dsi = dev_get_drvdata(dev);
- exynos_dsi_disable(&dsi->bridge); + exynos_dsi_atomic_disable(&dsi->bridge, NULL);
mipi_dsi_host_unregister(&dsi->dsi_host); }
dri-devel@lists.freedesktop.org