* [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled
@ 2016-06-17 10:13 Lucas Stach
2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst
If there is no framebuffer mode that can be restored, all outputs should
be disabled in order to avoid information leaks.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/gpu/drm/imx/imx-drm-core.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 82656654fb21..c63378661e11 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -63,7 +63,19 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
{
struct imx_drm_device *imxdrm = drm->dev_private;
- drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
+ if (imxdrm->fbhelper) {
+ drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
+ } else {
+ struct drm_connector *connector;
+
+ /* no kernel mode to go back to, disable all outputs */
+ drm_modeset_lock_all(drm);
+ drm_for_each_connector(connector, drm)
+ connector->encoder = NULL;
+ drm_modeset_unlock_all(drm);
+
+ drm_helper_disable_unused_functions(drm);
+ }
}
static int imx_drm_driver_unload(struct drm_device *drm)
--
2.8.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach
2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
2016-07-11 10:25 ` Philipp Zabel
2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst
Check the return code on panel attach. Avoids a kernel crash later
on if the attach failed.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/gpu/drm/imx/imx-ldb.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index beff793bb717..48166df14042 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -427,8 +427,12 @@ static int imx_ldb_register(struct drm_device *drm,
drm_connector_init(drm, &imx_ldb_ch->connector,
&imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
- if (imx_ldb_ch->panel)
- drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector);
+ if (imx_ldb_ch->panel) {
+ ret = drm_panel_attach(imx_ldb_ch->panel,
+ &imx_ldb_ch->connector);
+ if (ret)
+ return ret;
+ }
drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
&imx_ldb_ch->encoder);
--
2.8.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind
2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
2016-06-20 12:03 ` Philipp Zabel
2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst
Make sure to leave a clean panel state behind and allow to
properly attach to the panel again on a rebind.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/gpu/drm/imx/imx-ldb.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 48166df14042..9e117a654417 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -671,6 +671,9 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
for (i = 0; i < 2; i++) {
struct imx_ldb_channel *channel = &imx_ldb->channel[i];
+ if (channel->panel)
+ drm_panel_detach(channel->panel);
+
if (!channel->connector.funcs)
continue;
--
2.8.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops
2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
2016-06-17 12:48 ` Daniel Vetter
2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
2016-06-17 12:45 ` [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Daniel Vetter
4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst
Drop the load/unload driver ops, as they are deprecated because of their
inherent races, with devices being visible to userspace before they are
fully initialized.
Move this code into the driver bind/unbind routines bracketed by the
proper drm_dev_alloc/register and drm_dev_unregister/unref calls.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/gpu/drm/imx/imx-drm-core.c | 247 ++++++++++++++++++-------------------
1 file changed, 121 insertions(+), 126 deletions(-)
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index c63378661e11..799a68976590 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -78,25 +78,6 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
}
}
-static int imx_drm_driver_unload(struct drm_device *drm)
-{
- struct imx_drm_device *imxdrm = drm->dev_private;
-
- drm_kms_helper_poll_fini(drm);
-
- if (imxdrm->fbhelper)
- drm_fbdev_cma_fini(imxdrm->fbhelper);
-
- component_unbind_all(drm->dev, drm);
-
- drm_vblank_cleanup(drm);
- drm_mode_config_cleanup(drm);
-
- platform_set_drvdata(drm->platformdev, NULL);
-
- return 0;
-}
-
static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
{
struct imx_drm_device *imxdrm = crtc->dev->dev_private;
@@ -223,109 +204,6 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
};
/*
- * Main DRM initialisation. This binds, initialises and registers
- * with DRM the subcomponents of the driver.
- */
-static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
-{
- struct imx_drm_device *imxdrm;
- struct drm_connector *connector;
- int ret;
-
- imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
- if (!imxdrm)
- return -ENOMEM;
-
- imxdrm->drm = drm;
-
- drm->dev_private = imxdrm;
-
- /*
- * enable drm irq mode.
- * - with irq_enabled = true, we can use the vblank feature.
- *
- * P.S. note that we wouldn't use drm irq handler but
- * just specific driver own one instead because
- * drm framework supports only one irq handler and
- * drivers can well take care of their interrupts
- */
- drm->irq_enabled = true;
-
- /*
- * set max width and height as default value(4096x4096).
- * this value would be used to check framebuffer size limitation
- * at drm_mode_addfb().
- */
- drm->mode_config.min_width = 64;
- drm->mode_config.min_height = 64;
- drm->mode_config.max_width = 4096;
- drm->mode_config.max_height = 4096;
- drm->mode_config.funcs = &imx_drm_mode_config_funcs;
-
- drm_mode_config_init(drm);
-
- ret = drm_vblank_init(drm, MAX_CRTC);
- if (ret)
- goto err_kms;
-
- platform_set_drvdata(drm->platformdev, drm);
-
- /* Now try and bind all our sub-components */
- ret = component_bind_all(drm->dev, drm);
- if (ret)
- goto err_vblank;
-
- /*
- * All components are now added, we can publish the connector sysfs
- * entries to userspace. This will generate hotplug events and so
- * userspace will expect to be able to access DRM at this point.
- */
- list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
- ret = drm_connector_register(connector);
- if (ret) {
- dev_err(drm->dev,
- "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
- connector->base.id,
- connector->name, ret);
- goto err_unbind;
- }
- }
-
- /*
- * All components are now initialised, so setup the fb helper.
- * The fb helper takes copies of key hardware information, so the
- * crtcs/connectors/encoders must not change after this point.
- */
-#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
- if (legacyfb_depth != 16 && legacyfb_depth != 32) {
- dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
- legacyfb_depth = 16;
- }
- drm_helper_disable_unused_functions(drm);
- imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
- drm->mode_config.num_crtc, MAX_CRTC);
- if (IS_ERR(imxdrm->fbhelper)) {
- ret = PTR_ERR(imxdrm->fbhelper);
- imxdrm->fbhelper = NULL;
- goto err_unbind;
- }
-#endif
-
- drm_kms_helper_poll_init(drm);
-
- return 0;
-
-err_unbind:
- component_unbind_all(drm->dev, drm);
-err_vblank:
- drm_vblank_cleanup(drm);
-err_kms:
- drm_mode_config_cleanup(drm);
-
- return ret;
-}
-
-/*
* imx_drm_add_crtc - add a new crtc
*/
int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
@@ -416,8 +294,6 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
static struct drm_driver imx_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
- .load = imx_drm_driver_load,
- .unload = imx_drm_driver_unload,
.lastclose = imx_drm_driver_lastclose,
.set_busid = drm_platform_set_busid,
.gem_free_object_unlocked = drm_gem_cma_free_object,
@@ -471,12 +347,131 @@ static int compare_of(struct device *dev, void *data)
static int imx_drm_bind(struct device *dev)
{
- return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
+ struct drm_device *drm;
+ struct imx_drm_device *imxdrm;
+ int ret;
+
+ drm = drm_dev_alloc(&imx_drm_driver, dev);
+ if (!drm)
+ return -ENOMEM;
+
+ imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
+ if (!imxdrm) {
+ ret = -ENOMEM;
+ goto err_unref;
+ }
+
+ imxdrm->drm = drm;
+ drm->dev_private = imxdrm;
+
+ /*
+ * enable drm irq mode.
+ * - with irq_enabled = true, we can use the vblank feature.
+ *
+ * P.S. note that we wouldn't use drm irq handler but
+ * just specific driver own one instead because
+ * drm framework supports only one irq handler and
+ * drivers can well take care of their interrupts
+ */
+ drm->irq_enabled = true;
+
+ /*
+ * set max width and height as default value(4096x4096).
+ * this value would be used to check framebuffer size limitation
+ * at drm_mode_addfb().
+ */
+ drm->mode_config.min_width = 64;
+ drm->mode_config.min_height = 64;
+ drm->mode_config.max_width = 4096;
+ drm->mode_config.max_height = 4096;
+ drm->mode_config.funcs = &imx_drm_mode_config_funcs;
+
+ drm_mode_config_init(drm);
+
+ ret = drm_vblank_init(drm, MAX_CRTC);
+ if (ret)
+ goto err_kms;
+
+ dev_set_drvdata(dev, drm);
+
+ /* Now try and bind all our sub-components */
+ ret = component_bind_all(dev, drm);
+ if (ret)
+ goto err_vblank;
+
+ ret = drm_dev_register(drm, 0);
+ if (ret)
+ goto err_unbind;
+
+ /*
+ * All components are now added, we can publish the connector sysfs
+ * entries to userspace. This will generate hotplug events and so
+ * userspace will expect to be able to access DRM at this point.
+ */
+ ret = drm_connector_register_all(drm);
+ if (ret)
+ goto err_unregister;
+
+ /*
+ * All components are now initialised, so setup the fb helper.
+ * The fb helper takes copies of key hardware information, so the
+ * crtcs/connectors/encoders must not change after this point.
+ */
+#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
+ if (legacyfb_depth != 16 && legacyfb_depth != 32) {
+ dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
+ legacyfb_depth = 16;
+ }
+ drm_helper_disable_unused_functions(drm);
+ imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
+ drm->mode_config.num_crtc, MAX_CRTC);
+ if (IS_ERR(imxdrm->fbhelper)) {
+ ret = PTR_ERR(imxdrm->fbhelper);
+ imxdrm->fbhelper = NULL;
+ goto err_unregister;
+ }
+#endif
+
+ drm_kms_helper_poll_init(drm);
+
+ return 0;
+
+err_unregister:
+ drm_dev_unregister(drm);
+err_unbind:
+ component_unbind_all(drm->dev, drm);
+err_vblank:
+ drm_vblank_cleanup(drm);
+err_kms:
+ drm_mode_config_cleanup(drm);
+err_unref:
+ drm_dev_unref(drm);
+
+ return ret;
}
static void imx_drm_unbind(struct device *dev)
{
- drm_put_dev(dev_get_drvdata(dev));
+ struct drm_device *drm = dev_get_drvdata(dev);
+ struct imx_drm_device *imxdrm = drm->dev_private;
+ struct drm_fbdev_cma *fbhelper = imxdrm->fbhelper;
+
+ drm_kms_helper_poll_fini(drm);
+ /* device is going down, so no need to restore fbdev modes */
+ imxdrm->fbhelper = NULL;
+
+ drm_connector_unregister_all(drm);
+ drm_dev_unregister(drm);
+
+ if (fbhelper)
+ drm_fbdev_cma_fini(fbhelper);
+
+ component_unbind_all(drm->dev, drm);
+ dev_set_drvdata(dev, NULL);
+
+ drm_mode_config_cleanup(drm);
+
+ drm_dev_unref(drm);
}
static const struct component_master_ops imx_drm_ops = {
--
2.8.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind
2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
` (2 preceding siblings ...)
2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
@ 2016-06-17 10:13 ` Lucas Stach
2016-06-20 12:00 ` Philipp Zabel
2016-06-17 12:45 ` [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Daniel Vetter
4 siblings, 1 reply; 11+ messages in thread
From: Lucas Stach @ 2016-06-17 10:13 UTC (permalink / raw)
To: Philipp Zabel; +Cc: kernel, dri-devel, patchwork-lst
Instead let drm_mode_config_cleanup() do the work when taking down
the master device. This requires all cleanup functions to be
properly hooked up to the mode object .destroy callback.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/gpu/drm/bridge/dw-hdmi.c | 3 ---
drivers/gpu/drm/imx/imx-drm-core.c | 4 ++--
drivers/gpu/drm/imx/imx-ldb.c | 6 ------
drivers/gpu/drm/imx/imx-tve.c | 3 ---
drivers/gpu/drm/imx/ipuv3-crtc.c | 9 ++++++---
drivers/gpu/drm/imx/parallel-display.c | 3 ---
6 files changed, 8 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index c9d941283d30..5f97977f7e5c 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1834,9 +1834,6 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
/* Disable all interrupts */
hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
- hdmi->connector.funcs->destroy(&hdmi->connector);
- hdmi->encoder->funcs->destroy(hdmi->encoder);
-
clk_disable_unprepare(hdmi->iahb_clk);
clk_disable_unprepare(hdmi->isfr_clk);
i2c_put_adapter(hdmi->ddc);
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 799a68976590..71e33666cae8 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -466,11 +466,11 @@ static void imx_drm_unbind(struct device *dev)
if (fbhelper)
drm_fbdev_cma_fini(fbhelper);
+ drm_mode_config_cleanup(drm);
+
component_unbind_all(drm->dev, drm);
dev_set_drvdata(dev, NULL);
- drm_mode_config_cleanup(drm);
-
drm_dev_unref(drm);
}
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 9e117a654417..b49948d51110 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -674,12 +674,6 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
if (channel->panel)
drm_panel_detach(channel->panel);
- if (!channel->connector.funcs)
- continue;
-
- channel->connector.funcs->destroy(&channel->connector);
- channel->encoder.funcs->destroy(&channel->encoder);
-
kfree(channel->edid);
i2c_put_adapter(channel->ddc);
}
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index baf788121287..3973b2c85e2d 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -688,9 +688,6 @@ static void imx_tve_unbind(struct device *dev, struct device *master,
{
struct imx_tve *tve = dev_get_drvdata(dev);
- tve->connector.funcs->destroy(&tve->connector);
- tve->encoder.funcs->destroy(&tve->encoder);
-
if (!IS_ERR(tve->dac_reg))
regulator_disable(tve->dac_reg);
}
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index fc040417e1e8..4d5dbea48cef 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -228,9 +228,14 @@ put_vblank:
return ret;
}
+static void ipu_crtc_cleanup(struct drm_crtc *crtc)
+{
+ imx_drm_remove_crtc(to_ipu_crtc(crtc)->imx_crtc);
+}
+
static const struct drm_crtc_funcs ipu_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
- .destroy = drm_crtc_cleanup,
+ .destroy = ipu_crtc_cleanup,
.page_flip = ipu_page_flip,
};
@@ -551,8 +556,6 @@ static void ipu_drm_unbind(struct device *dev, struct device *master,
{
struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev);
- imx_drm_remove_crtc(ipu_crtc->imx_crtc);
-
destroy_workqueue(ipu_crtc->flip_queue);
ipu_plane_put_resources(ipu_crtc->plane[0]);
ipu_put_resources(ipu_crtc);
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 2d1fd02cd3d6..a1fa8fc91336 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -248,9 +248,6 @@ static void imx_pd_unbind(struct device *dev, struct device *master,
{
struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
- imxpd->encoder.funcs->destroy(&imxpd->encoder);
- imxpd->connector.funcs->destroy(&imxpd->connector);
-
kfree(imxpd->edid);
}
--
2.8.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled
2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
` (3 preceding siblings ...)
2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
@ 2016-06-17 12:45 ` Daniel Vetter
4 siblings, 0 replies; 11+ messages in thread
From: Daniel Vetter @ 2016-06-17 12:45 UTC (permalink / raw)
To: Lucas Stach; +Cc: dri-devel, kernel, patchwork-lst
On Fri, Jun 17, 2016 at 12:13:38PM +0200, Lucas Stach wrote:
> If there is no framebuffer mode that can be restored, all outputs should
> be disabled in order to avoid information leaks.
No, this was a short-term regression that's now fixed again. When a client
closes or calls rmfb, we make sure that buffer isn't in use any more. This
shouldn't be needed any more.
Also, a generic fix in driver code. Tsk! ;-)
Cheers, Daniel
>
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/gpu/drm/imx/imx-drm-core.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index 82656654fb21..c63378661e11 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -63,7 +63,19 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
> {
> struct imx_drm_device *imxdrm = drm->dev_private;
>
> - drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
> + if (imxdrm->fbhelper) {
> + drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
> + } else {
> + struct drm_connector *connector;
> +
> + /* no kernel mode to go back to, disable all outputs */
> + drm_modeset_lock_all(drm);
> + drm_for_each_connector(connector, drm)
> + connector->encoder = NULL;
> + drm_modeset_unlock_all(drm);
> +
> + drm_helper_disable_unused_functions(drm);
> + }
> }
>
> static int imx_drm_driver_unload(struct drm_device *drm)
> --
> 2.8.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops
2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
@ 2016-06-17 12:48 ` Daniel Vetter
2016-06-24 7:46 ` Ying Liu
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Vetter @ 2016-06-17 12:48 UTC (permalink / raw)
To: Lucas Stach; +Cc: dri-devel, kernel, patchwork-lst
On Fri, Jun 17, 2016 at 12:13:41PM +0200, Lucas Stach wrote:
> Drop the load/unload driver ops, as they are deprecated because of their
> inherent races, with devices being visible to userspace before they are
> fully initialized.
>
> Move this code into the driver bind/unbind routines bracketed by the
> proper drm_dev_alloc/register and drm_dev_unregister/unref calls.
>
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/gpu/drm/imx/imx-drm-core.c | 247 ++++++++++++++++++-------------------
> 1 file changed, 121 insertions(+), 126 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index c63378661e11..799a68976590 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -78,25 +78,6 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
> }
> }
>
> -static int imx_drm_driver_unload(struct drm_device *drm)
> -{
> - struct imx_drm_device *imxdrm = drm->dev_private;
> -
> - drm_kms_helper_poll_fini(drm);
> -
> - if (imxdrm->fbhelper)
> - drm_fbdev_cma_fini(imxdrm->fbhelper);
> -
> - component_unbind_all(drm->dev, drm);
> -
> - drm_vblank_cleanup(drm);
> - drm_mode_config_cleanup(drm);
> -
> - platform_set_drvdata(drm->platformdev, NULL);
> -
> - return 0;
> -}
> -
> static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
> {
> struct imx_drm_device *imxdrm = crtc->dev->dev_private;
> @@ -223,109 +204,6 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
> };
>
> /*
> - * Main DRM initialisation. This binds, initialises and registers
> - * with DRM the subcomponents of the driver.
> - */
> -static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
> -{
> - struct imx_drm_device *imxdrm;
> - struct drm_connector *connector;
> - int ret;
> -
> - imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
> - if (!imxdrm)
> - return -ENOMEM;
> -
> - imxdrm->drm = drm;
> -
> - drm->dev_private = imxdrm;
> -
> - /*
> - * enable drm irq mode.
> - * - with irq_enabled = true, we can use the vblank feature.
> - *
> - * P.S. note that we wouldn't use drm irq handler but
> - * just specific driver own one instead because
> - * drm framework supports only one irq handler and
> - * drivers can well take care of their interrupts
> - */
> - drm->irq_enabled = true;
> -
> - /*
> - * set max width and height as default value(4096x4096).
> - * this value would be used to check framebuffer size limitation
> - * at drm_mode_addfb().
> - */
> - drm->mode_config.min_width = 64;
> - drm->mode_config.min_height = 64;
> - drm->mode_config.max_width = 4096;
> - drm->mode_config.max_height = 4096;
> - drm->mode_config.funcs = &imx_drm_mode_config_funcs;
> -
> - drm_mode_config_init(drm);
> -
> - ret = drm_vblank_init(drm, MAX_CRTC);
> - if (ret)
> - goto err_kms;
> -
> - platform_set_drvdata(drm->platformdev, drm);
> -
> - /* Now try and bind all our sub-components */
> - ret = component_bind_all(drm->dev, drm);
> - if (ret)
> - goto err_vblank;
> -
> - /*
> - * All components are now added, we can publish the connector sysfs
> - * entries to userspace. This will generate hotplug events and so
> - * userspace will expect to be able to access DRM at this point.
> - */
> - list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
> - ret = drm_connector_register(connector);
> - if (ret) {
> - dev_err(drm->dev,
> - "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
> - connector->base.id,
> - connector->name, ret);
> - goto err_unbind;
> - }
> - }
> -
> - /*
> - * All components are now initialised, so setup the fb helper.
> - * The fb helper takes copies of key hardware information, so the
> - * crtcs/connectors/encoders must not change after this point.
> - */
> -#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
> - if (legacyfb_depth != 16 && legacyfb_depth != 32) {
> - dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
> - legacyfb_depth = 16;
> - }
> - drm_helper_disable_unused_functions(drm);
> - imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
> - drm->mode_config.num_crtc, MAX_CRTC);
> - if (IS_ERR(imxdrm->fbhelper)) {
> - ret = PTR_ERR(imxdrm->fbhelper);
> - imxdrm->fbhelper = NULL;
> - goto err_unbind;
> - }
> -#endif
> -
> - drm_kms_helper_poll_init(drm);
> -
> - return 0;
> -
> -err_unbind:
> - component_unbind_all(drm->dev, drm);
> -err_vblank:
> - drm_vblank_cleanup(drm);
> -err_kms:
> - drm_mode_config_cleanup(drm);
> -
> - return ret;
> -}
> -
> -/*
> * imx_drm_add_crtc - add a new crtc
> */
> int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
> @@ -416,8 +294,6 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
>
> static struct drm_driver imx_drm_driver = {
> .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
> - .load = imx_drm_driver_load,
> - .unload = imx_drm_driver_unload,
> .lastclose = imx_drm_driver_lastclose,
> .set_busid = drm_platform_set_busid,
> .gem_free_object_unlocked = drm_gem_cma_free_object,
> @@ -471,12 +347,131 @@ static int compare_of(struct device *dev, void *data)
>
> static int imx_drm_bind(struct device *dev)
> {
> - return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
> + struct drm_device *drm;
> + struct imx_drm_device *imxdrm;
> + int ret;
> +
> + drm = drm_dev_alloc(&imx_drm_driver, dev);
> + if (!drm)
> + return -ENOMEM;
> +
> + imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
> + if (!imxdrm) {
> + ret = -ENOMEM;
> + goto err_unref;
> + }
> +
> + imxdrm->drm = drm;
> + drm->dev_private = imxdrm;
> +
> + /*
> + * enable drm irq mode.
> + * - with irq_enabled = true, we can use the vblank feature.
> + *
> + * P.S. note that we wouldn't use drm irq handler but
> + * just specific driver own one instead because
> + * drm framework supports only one irq handler and
> + * drivers can well take care of their interrupts
> + */
> + drm->irq_enabled = true;
> +
> + /*
> + * set max width and height as default value(4096x4096).
> + * this value would be used to check framebuffer size limitation
> + * at drm_mode_addfb().
> + */
> + drm->mode_config.min_width = 64;
> + drm->mode_config.min_height = 64;
> + drm->mode_config.max_width = 4096;
> + drm->mode_config.max_height = 4096;
> + drm->mode_config.funcs = &imx_drm_mode_config_funcs;
> +
> + drm_mode_config_init(drm);
> +
> + ret = drm_vblank_init(drm, MAX_CRTC);
> + if (ret)
> + goto err_kms;
> +
> + dev_set_drvdata(dev, drm);
> +
> + /* Now try and bind all our sub-components */
> + ret = component_bind_all(dev, drm);
> + if (ret)
> + goto err_vblank;
> +
> + ret = drm_dev_register(drm, 0);
In principle this should be the last step in the init sequence, otherwise
you might have userspace fighting with your init code over the hw. Please
move down.
> + if (ret)
> + goto err_unbind;
> +
> + /*
> + * All components are now added, we can publish the connector sysfs
> + * entries to userspace. This will generate hotplug events and so
> + * userspace will expect to be able to access DRM at this point.
> + */
> + ret = drm_connector_register_all(drm);
This (and connector_unregister_all) just became unecessary with the
patches from Chris that I merged into drm-misc today. Please remove.
> + if (ret)
> + goto err_unregister;
> +
> + /*
> + * All components are now initialised, so setup the fb helper.
> + * The fb helper takes copies of key hardware information, so the
> + * crtcs/connectors/encoders must not change after this point.
> + */
> +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
> + if (legacyfb_depth != 16 && legacyfb_depth != 32) {
> + dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
> + legacyfb_depth = 16;
> + }
> + drm_helper_disable_unused_functions(drm);
fyi, you need to nuke this when switching to atomic.
> + imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
> + drm->mode_config.num_crtc, MAX_CRTC);
> + if (IS_ERR(imxdrm->fbhelper)) {
> + ret = PTR_ERR(imxdrm->fbhelper);
> + imxdrm->fbhelper = NULL;
> + goto err_unregister;
> + }
> +#endif
> +
> + drm_kms_helper_poll_init(drm);
> +
> + return 0;
> +
> +err_unregister:
> + drm_dev_unregister(drm);
> +err_unbind:
> + component_unbind_all(drm->dev, drm);
> +err_vblank:
> + drm_vblank_cleanup(drm);
> +err_kms:
> + drm_mode_config_cleanup(drm);
> +err_unref:
> + drm_dev_unref(drm);
> +
> + return ret;
> }
>
> static void imx_drm_unbind(struct device *dev)
> {
> - drm_put_dev(dev_get_drvdata(dev));
> + struct drm_device *drm = dev_get_drvdata(dev);
> + struct imx_drm_device *imxdrm = drm->dev_private;
> + struct drm_fbdev_cma *fbhelper = imxdrm->fbhelper;
> +
> + drm_kms_helper_poll_fini(drm);
> + /* device is going down, so no need to restore fbdev modes */
> + imxdrm->fbhelper = NULL;
> +
> + drm_connector_unregister_all(drm);
> + drm_dev_unregister(drm);
Same here: unregister should be first, connector_unregister_all isn't
needed any more.
-Daniel
> +
> + if (fbhelper)
> + drm_fbdev_cma_fini(fbhelper);
> +
> + component_unbind_all(drm->dev, drm);
> + dev_set_drvdata(dev, NULL);
> +
> + drm_mode_config_cleanup(drm);
> +
> + drm_dev_unref(drm);
> }
>
> static const struct component_master_ops imx_drm_ops = {
> --
> 2.8.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind
2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
@ 2016-06-20 12:00 ` Philipp Zabel
0 siblings, 0 replies; 11+ messages in thread
From: Philipp Zabel @ 2016-06-20 12:00 UTC (permalink / raw)
To: Lucas Stach; +Cc: kernel, dri-devel, patchwork-lst
Am Freitag, den 17.06.2016, 12:13 +0200 schrieb Lucas Stach:
> Instead let drm_mode_config_cleanup() do the work when taking down
> the master device. This requires all cleanup functions to be
> properly hooked up to the mode object .destroy callback.
>
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/gpu/drm/bridge/dw-hdmi.c | 3 ---
> drivers/gpu/drm/imx/imx-drm-core.c | 4 ++--
> drivers/gpu/drm/imx/imx-ldb.c | 6 ------
> drivers/gpu/drm/imx/imx-tve.c | 3 ---
> drivers/gpu/drm/imx/ipuv3-crtc.c | 9 ++++++---
> drivers/gpu/drm/imx/parallel-display.c | 3 ---
> 6 files changed, 8 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
> index c9d941283d30..5f97977f7e5c 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -1834,9 +1834,6 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
> /* Disable all interrupts */
> hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
>
> - hdmi->connector.funcs->destroy(&hdmi->connector);
> - hdmi->encoder->funcs->destroy(hdmi->encoder);
> -
> clk_disable_unprepare(hdmi->iahb_clk);
> clk_disable_unprepare(hdmi->isfr_clk);
> i2c_put_adapter(hdmi->ddc);
The rockchip driver already calls drm_mode_config_cleanup after
component_unbind_all, so I this change should work for the rockchip
driver as is?
> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index 799a68976590..71e33666cae8 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -466,11 +466,11 @@ static void imx_drm_unbind(struct device *dev)
> if (fbhelper)
> drm_fbdev_cma_fini(fbhelper);
>
> + drm_mode_config_cleanup(drm);
> +
> component_unbind_all(drm->dev, drm);
> dev_set_drvdata(dev, NULL);
>
> - drm_mode_config_cleanup(drm);
> -
> drm_dev_unref(drm);
> }
regards
Philipp
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind
2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
@ 2016-06-20 12:03 ` Philipp Zabel
0 siblings, 0 replies; 11+ messages in thread
From: Philipp Zabel @ 2016-06-20 12:03 UTC (permalink / raw)
To: Lucas Stach; +Cc: kernel, dri-devel, patchwork-lst
Am Freitag, den 17.06.2016, 12:13 +0200 schrieb Lucas Stach:
> Make sure to leave a clean panel state behind and allow to
> properly attach to the panel again on a rebind.
>
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/gpu/drm/imx/imx-ldb.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
> index 48166df14042..9e117a654417 100644
> --- a/drivers/gpu/drm/imx/imx-ldb.c
> +++ b/drivers/gpu/drm/imx/imx-ldb.c
> @@ -671,6 +671,9 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
> for (i = 0; i < 2; i++) {
> struct imx_ldb_channel *channel = &imx_ldb->channel[i];
>
> + if (channel->panel)
> + drm_panel_detach(channel->panel);
I think this should also be done in the bind error path.
regards
Philipp
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops
2016-06-17 12:48 ` Daniel Vetter
@ 2016-06-24 7:46 ` Ying Liu
0 siblings, 0 replies; 11+ messages in thread
From: Ying Liu @ 2016-06-24 7:46 UTC (permalink / raw)
To: Daniel Vetter; +Cc: patchwork-lst, kernel, DRI Development
On Fri, Jun 17, 2016 at 8:48 PM, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Fri, Jun 17, 2016 at 12:13:41PM +0200, Lucas Stach wrote:
>> Drop the load/unload driver ops, as they are deprecated because of their
>> inherent races, with devices being visible to userspace before they are
>> fully initialized.
>>
>> Move this code into the driver bind/unbind routines bracketed by the
>> proper drm_dev_alloc/register and drm_dev_unregister/unref calls.
>>
>> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
>> ---
>> drivers/gpu/drm/imx/imx-drm-core.c | 247 ++++++++++++++++++-------------------
>> 1 file changed, 121 insertions(+), 126 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
>> index c63378661e11..799a68976590 100644
>> --- a/drivers/gpu/drm/imx/imx-drm-core.c
>> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
>> @@ -78,25 +78,6 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
>> }
>> }
>>
>> -static int imx_drm_driver_unload(struct drm_device *drm)
>> -{
>> - struct imx_drm_device *imxdrm = drm->dev_private;
>> -
>> - drm_kms_helper_poll_fini(drm);
>> -
>> - if (imxdrm->fbhelper)
>> - drm_fbdev_cma_fini(imxdrm->fbhelper);
>> -
>> - component_unbind_all(drm->dev, drm);
>> -
>> - drm_vblank_cleanup(drm);
>> - drm_mode_config_cleanup(drm);
>> -
>> - platform_set_drvdata(drm->platformdev, NULL);
>> -
>> - return 0;
>> -}
>> -
>> static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
>> {
>> struct imx_drm_device *imxdrm = crtc->dev->dev_private;
>> @@ -223,109 +204,6 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
>> };
>>
>> /*
>> - * Main DRM initialisation. This binds, initialises and registers
>> - * with DRM the subcomponents of the driver.
>> - */
>> -static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
>> -{
>> - struct imx_drm_device *imxdrm;
>> - struct drm_connector *connector;
>> - int ret;
>> -
>> - imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
>> - if (!imxdrm)
>> - return -ENOMEM;
>> -
>> - imxdrm->drm = drm;
>> -
>> - drm->dev_private = imxdrm;
>> -
>> - /*
>> - * enable drm irq mode.
>> - * - with irq_enabled = true, we can use the vblank feature.
>> - *
>> - * P.S. note that we wouldn't use drm irq handler but
>> - * just specific driver own one instead because
>> - * drm framework supports only one irq handler and
>> - * drivers can well take care of their interrupts
>> - */
>> - drm->irq_enabled = true;
>> -
>> - /*
>> - * set max width and height as default value(4096x4096).
>> - * this value would be used to check framebuffer size limitation
>> - * at drm_mode_addfb().
>> - */
>> - drm->mode_config.min_width = 64;
>> - drm->mode_config.min_height = 64;
>> - drm->mode_config.max_width = 4096;
>> - drm->mode_config.max_height = 4096;
>> - drm->mode_config.funcs = &imx_drm_mode_config_funcs;
>> -
>> - drm_mode_config_init(drm);
>> -
>> - ret = drm_vblank_init(drm, MAX_CRTC);
>> - if (ret)
>> - goto err_kms;
>> -
>> - platform_set_drvdata(drm->platformdev, drm);
>> -
>> - /* Now try and bind all our sub-components */
>> - ret = component_bind_all(drm->dev, drm);
>> - if (ret)
>> - goto err_vblank;
>> -
>> - /*
>> - * All components are now added, we can publish the connector sysfs
>> - * entries to userspace. This will generate hotplug events and so
>> - * userspace will expect to be able to access DRM at this point.
>> - */
>> - list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
>> - ret = drm_connector_register(connector);
>> - if (ret) {
>> - dev_err(drm->dev,
>> - "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
>> - connector->base.id,
>> - connector->name, ret);
>> - goto err_unbind;
>> - }
>> - }
>> -
>> - /*
>> - * All components are now initialised, so setup the fb helper.
>> - * The fb helper takes copies of key hardware information, so the
>> - * crtcs/connectors/encoders must not change after this point.
>> - */
>> -#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
>> - if (legacyfb_depth != 16 && legacyfb_depth != 32) {
>> - dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
>> - legacyfb_depth = 16;
>> - }
>> - drm_helper_disable_unused_functions(drm);
>> - imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
>> - drm->mode_config.num_crtc, MAX_CRTC);
>> - if (IS_ERR(imxdrm->fbhelper)) {
>> - ret = PTR_ERR(imxdrm->fbhelper);
>> - imxdrm->fbhelper = NULL;
>> - goto err_unbind;
>> - }
>> -#endif
>> -
>> - drm_kms_helper_poll_init(drm);
>> -
>> - return 0;
>> -
>> -err_unbind:
>> - component_unbind_all(drm->dev, drm);
>> -err_vblank:
>> - drm_vblank_cleanup(drm);
>> -err_kms:
>> - drm_mode_config_cleanup(drm);
>> -
>> - return ret;
>> -}
>> -
>> -/*
>> * imx_drm_add_crtc - add a new crtc
>> */
>> int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
>> @@ -416,8 +294,6 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
>>
>> static struct drm_driver imx_drm_driver = {
>> .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
>> - .load = imx_drm_driver_load,
>> - .unload = imx_drm_driver_unload,
>> .lastclose = imx_drm_driver_lastclose,
>> .set_busid = drm_platform_set_busid,
>> .gem_free_object_unlocked = drm_gem_cma_free_object,
>> @@ -471,12 +347,131 @@ static int compare_of(struct device *dev, void *data)
>>
>> static int imx_drm_bind(struct device *dev)
>> {
>> - return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
>> + struct drm_device *drm;
>> + struct imx_drm_device *imxdrm;
>> + int ret;
>> +
>> + drm = drm_dev_alloc(&imx_drm_driver, dev);
>> + if (!drm)
>> + return -ENOMEM;
>> +
>> + imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
>> + if (!imxdrm) {
>> + ret = -ENOMEM;
>> + goto err_unref;
>> + }
>> +
>> + imxdrm->drm = drm;
>> + drm->dev_private = imxdrm;
>> +
>> + /*
>> + * enable drm irq mode.
>> + * - with irq_enabled = true, we can use the vblank feature.
>> + *
>> + * P.S. note that we wouldn't use drm irq handler but
>> + * just specific driver own one instead because
>> + * drm framework supports only one irq handler and
>> + * drivers can well take care of their interrupts
>> + */
>> + drm->irq_enabled = true;
>> +
>> + /*
>> + * set max width and height as default value(4096x4096).
>> + * this value would be used to check framebuffer size limitation
>> + * at drm_mode_addfb().
>> + */
>> + drm->mode_config.min_width = 64;
>> + drm->mode_config.min_height = 64;
>> + drm->mode_config.max_width = 4096;
>> + drm->mode_config.max_height = 4096;
>> + drm->mode_config.funcs = &imx_drm_mode_config_funcs;
>> +
>> + drm_mode_config_init(drm);
>> +
>> + ret = drm_vblank_init(drm, MAX_CRTC);
>> + if (ret)
>> + goto err_kms;
>> +
>> + dev_set_drvdata(dev, drm);
>> +
>> + /* Now try and bind all our sub-components */
>> + ret = component_bind_all(dev, drm);
>> + if (ret)
>> + goto err_vblank;
>> +
>> + ret = drm_dev_register(drm, 0);
>
> In principle this should be the last step in the init sequence, otherwise
> you might have userspace fighting with your init code over the hw. Please
> move down.
>
>> + if (ret)
>> + goto err_unbind;
>> +
>> + /*
>> + * All components are now added, we can publish the connector sysfs
>> + * entries to userspace. This will generate hotplug events and so
>> + * userspace will expect to be able to access DRM at this point.
>> + */
>> + ret = drm_connector_register_all(drm);
>
> This (and connector_unregister_all) just became unecessary with the
> patches from Chris that I merged into drm-misc today. Please remove.
>
>> + if (ret)
>> + goto err_unregister;
>> +
>> + /*
>> + * All components are now initialised, so setup the fb helper.
>> + * The fb helper takes copies of key hardware information, so the
>> + * crtcs/connectors/encoders must not change after this point.
>> + */
>> +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
>> + if (legacyfb_depth != 16 && legacyfb_depth != 32) {
>> + dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
>> + legacyfb_depth = 16;
>> + }
>> + drm_helper_disable_unused_functions(drm);
>
> fyi, you need to nuke this when switching to atomic.
I've got this done in my imx-drm atomic conversion v2 patch set.
Regards,
Liu Ying
>
>> + imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
>> + drm->mode_config.num_crtc, MAX_CRTC);
>> + if (IS_ERR(imxdrm->fbhelper)) {
>> + ret = PTR_ERR(imxdrm->fbhelper);
>> + imxdrm->fbhelper = NULL;
>> + goto err_unregister;
>> + }
>> +#endif
>> +
>> + drm_kms_helper_poll_init(drm);
>> +
>> + return 0;
>> +
>> +err_unregister:
>> + drm_dev_unregister(drm);
>> +err_unbind:
>> + component_unbind_all(drm->dev, drm);
>> +err_vblank:
>> + drm_vblank_cleanup(drm);
>> +err_kms:
>> + drm_mode_config_cleanup(drm);
>> +err_unref:
>> + drm_dev_unref(drm);
>> +
>> + return ret;
>> }
>>
>> static void imx_drm_unbind(struct device *dev)
>> {
>> - drm_put_dev(dev_get_drvdata(dev));
>> + struct drm_device *drm = dev_get_drvdata(dev);
>> + struct imx_drm_device *imxdrm = drm->dev_private;
>> + struct drm_fbdev_cma *fbhelper = imxdrm->fbhelper;
>> +
>> + drm_kms_helper_poll_fini(drm);
>> + /* device is going down, so no need to restore fbdev modes */
>> + imxdrm->fbhelper = NULL;
>> +
>> + drm_connector_unregister_all(drm);
>> + drm_dev_unregister(drm);
>
> Same here: unregister should be first, connector_unregister_all isn't
> needed any more.
> -Daniel
>
>> +
>> + if (fbhelper)
>> + drm_fbdev_cma_fini(fbhelper);
>> +
>> + component_unbind_all(drm->dev, drm);
>> + dev_set_drvdata(dev, NULL);
>> +
>> + drm_mode_config_cleanup(drm);
>> +
>> + drm_dev_unref(drm);
>> }
>>
>> static const struct component_master_ops imx_drm_ops = {
>> --
>> 2.8.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach
2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
@ 2016-07-11 10:25 ` Philipp Zabel
0 siblings, 0 replies; 11+ messages in thread
From: Philipp Zabel @ 2016-07-11 10:25 UTC (permalink / raw)
To: Lucas Stach; +Cc: kernel, dri-devel, patchwork-lst
Am Freitag, den 17.06.2016, 12:13 +0200 schrieb Lucas Stach:
> Check the return code on panel attach. Avoids a kernel crash later
> on if the attach failed.
>
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/gpu/drm/imx/imx-ldb.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
> index beff793bb717..48166df14042 100644
> --- a/drivers/gpu/drm/imx/imx-ldb.c
> +++ b/drivers/gpu/drm/imx/imx-ldb.c
> @@ -427,8 +427,12 @@ static int imx_ldb_register(struct drm_device *drm,
> drm_connector_init(drm, &imx_ldb_ch->connector,
> &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
>
> - if (imx_ldb_ch->panel)
> - drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector);
> + if (imx_ldb_ch->panel) {
> + ret = drm_panel_attach(imx_ldb_ch->panel,
> + &imx_ldb_ch->connector);
> + if (ret)
> + return ret;
> + }
>
> drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
> &imx_ldb_ch->encoder);
Applied, thanks.
regards
Philipp
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2016-07-11 10:25 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-17 10:13 [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Lucas Stach
2016-06-17 10:13 ` [PATCH 2/5] drm/imx: imx-ldb: check return code on panel attach Lucas Stach
2016-07-11 10:25 ` Philipp Zabel
2016-06-17 10:13 ` [PATCH 3/5] drm/imx: imx-ldb: detach panel on unbind Lucas Stach
2016-06-20 12:03 ` Philipp Zabel
2016-06-17 10:13 ` [PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops Lucas Stach
2016-06-17 12:48 ` Daniel Vetter
2016-06-24 7:46 ` Ying Liu
2016-06-17 10:13 ` [PATCH 5/5] drm/imx: don't destroy mode objects manually on driver unbind Lucas Stach
2016-06-20 12:00 ` Philipp Zabel
2016-06-17 12:45 ` [PATCH 1/5] drm/imx: disable outputs in lastclose when framebuffer emulation is disabled Daniel Vetter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox