Merge branch 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes

This pull-request includes some bug fixes and code cleanups.
Especially, this fixes the bind failure issue occurred when it tries
to re-bind Exynos drm driver after unbound, and the modetest failure
issue incurred by not having a pair to vblank on and off requests.

* 'exynos-drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
  drm/exynos: correct connector->dpms field before resuming
  drm/exynos: enable vblank after DPMS on
  drm/exynos: init kms poll at the end of initialization
  drm/exynos: propagate plane initialization errors
  drm/exynos: vidi: fix build warning
  drm/exynos: remove explicit encoder/connector de-initialization
  drm/exynos: init vblank with real number of crtcs
This commit is contained in:
Dave Airlie 2014-11-03 05:23:17 +10:00
commit 66338feee4
7 changed files with 29 additions and 42 deletions

View File

@ -1355,13 +1355,8 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
void *data) void *data)
{ {
struct exynos_drm_display *display = dev_get_drvdata(dev); struct exynos_drm_display *display = dev_get_drvdata(dev);
struct exynos_dp_device *dp = display->ctx;
struct drm_encoder *encoder = dp->encoder;
exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);
exynos_dp_connector_destroy(&dp->connector);
encoder->funcs->destroy(encoder);
} }
static const struct component_ops exynos_dp_ops = { static const struct component_ops exynos_dp_ops = {

View File

@ -71,13 +71,16 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
!atomic_read(&exynos_crtc->pending_flip), !atomic_read(&exynos_crtc->pending_flip),
HZ/20)) HZ/20))
atomic_set(&exynos_crtc->pending_flip, 0); atomic_set(&exynos_crtc->pending_flip, 0);
drm_vblank_off(crtc->dev, exynos_crtc->pipe); drm_crtc_vblank_off(crtc);
} }
if (manager->ops->dpms) if (manager->ops->dpms)
manager->ops->dpms(manager, mode); manager->ops->dpms(manager, mode);
exynos_crtc->dpms = mode; exynos_crtc->dpms = mode;
if (mode == DRM_MODE_DPMS_ON)
drm_crtc_vblank_on(crtc);
} }
static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)

View File

@ -338,14 +338,10 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
int exynos_dpi_remove(struct device *dev) int exynos_dpi_remove(struct device *dev)
{ {
struct drm_encoder *encoder = exynos_dpi_display.encoder;
struct exynos_dpi *ctx = exynos_dpi_display.ctx; struct exynos_dpi *ctx = exynos_dpi_display.ctx;
exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF);
exynos_dpi_connector_destroy(&ctx->connector);
encoder->funcs->destroy(encoder);
if (ctx->panel) if (ctx->panel)
drm_panel_detach(ctx->panel); drm_panel_detach(ctx->panel);

View File

@ -87,16 +87,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
plane = exynos_plane_init(dev, possible_crtcs, plane = exynos_plane_init(dev, possible_crtcs,
DRM_PLANE_TYPE_OVERLAY); DRM_PLANE_TYPE_OVERLAY);
if (IS_ERR(plane)) if (!IS_ERR(plane))
goto err_mode_config_cleanup; continue;
}
/* init kms poll for handling hpd */ ret = PTR_ERR(plane);
drm_kms_helper_poll_init(dev);
ret = drm_vblank_init(dev, MAX_CRTC);
if (ret)
goto err_mode_config_cleanup; goto err_mode_config_cleanup;
}
/* setup possible_clones. */ /* setup possible_clones. */
exynos_drm_encoder_setup(dev); exynos_drm_encoder_setup(dev);
@ -106,15 +102,16 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
/* Try to bind all sub drivers. */ /* Try to bind all sub drivers. */
ret = component_bind_all(dev->dev, dev); ret = component_bind_all(dev->dev, dev);
if (ret) if (ret)
goto err_cleanup_vblank; goto err_mode_config_cleanup;
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret)
goto err_unbind_all;
/* Probe non kms sub drivers and virtual display driver. */ /* Probe non kms sub drivers and virtual display driver. */
ret = exynos_drm_device_subdrv_probe(dev); ret = exynos_drm_device_subdrv_probe(dev);
if (ret) if (ret)
goto err_unbind_all; goto err_cleanup_vblank;
/* force connectors detection */
drm_helper_hpd_irq_event(dev);
/* /*
* enable drm irq mode. * enable drm irq mode.
@ -133,12 +130,18 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
*/ */
dev->vblank_disable_allowed = true; dev->vblank_disable_allowed = true;
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(dev);
/* force connectors detection */
drm_helper_hpd_irq_event(dev);
return 0; return 0;
err_unbind_all:
component_unbind_all(dev->dev, dev);
err_cleanup_vblank: err_cleanup_vblank:
drm_vblank_cleanup(dev); drm_vblank_cleanup(dev);
err_unbind_all:
component_unbind_all(dev->dev, dev);
err_mode_config_cleanup: err_mode_config_cleanup:
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
drm_release_iommu_mapping(dev); drm_release_iommu_mapping(dev);
@ -155,8 +158,8 @@ static int exynos_drm_unload(struct drm_device *dev)
exynos_drm_fbdev_fini(dev); exynos_drm_fbdev_fini(dev);
drm_kms_helper_poll_fini(dev); drm_kms_helper_poll_fini(dev);
component_unbind_all(dev->dev, dev);
drm_vblank_cleanup(dev); drm_vblank_cleanup(dev);
component_unbind_all(dev->dev, dev);
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
drm_release_iommu_mapping(dev); drm_release_iommu_mapping(dev);
@ -191,8 +194,12 @@ static int exynos_drm_resume(struct drm_device *dev)
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->funcs->dpms) if (connector->funcs->dpms) {
connector->funcs->dpms(connector, connector->dpms); int dpms = connector->dpms;
connector->dpms = DRM_MODE_DPMS_OFF;
connector->funcs->dpms(connector, dpms);
}
} }
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);

View File

@ -1660,13 +1660,9 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
void *data) void *data)
{ {
struct exynos_dsi *dsi = exynos_dsi_display.ctx; struct exynos_dsi *dsi = exynos_dsi_display.ctx;
struct drm_encoder *encoder = dsi->encoder;
exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF);
exynos_dsi_connector_destroy(&dsi->connector);
encoder->funcs->destroy(encoder);
mipi_dsi_host_unregister(&dsi->dsi_host); mipi_dsi_host_unregister(&dsi->dsi_host);
} }

View File

@ -630,7 +630,6 @@ static int vidi_remove(struct platform_device *pdev)
{ {
struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
struct vidi_context *ctx = mgr->ctx; struct vidi_context *ctx = mgr->ctx;
struct drm_encoder *encoder = ctx->encoder;
if (ctx->raw_edid != (struct edid *)fake_edid_info) { if (ctx->raw_edid != (struct edid *)fake_edid_info) {
kfree(ctx->raw_edid); kfree(ctx->raw_edid);
@ -639,9 +638,6 @@ static int vidi_remove(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
encoder->funcs->destroy(encoder);
drm_connector_cleanup(&ctx->connector);
return 0; return 0;
} }

View File

@ -2312,12 +2312,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
static void hdmi_unbind(struct device *dev, struct device *master, void *data) static void hdmi_unbind(struct device *dev, struct device *master, void *data)
{ {
struct exynos_drm_display *display = get_hdmi_display(dev);
struct drm_encoder *encoder = display->encoder;
struct hdmi_context *hdata = display->ctx;
hdmi_connector_destroy(&hdata->connector);
encoder->funcs->destroy(encoder);
} }
static const struct component_ops hdmi_component_ops = { static const struct component_ops hdmi_component_ops = {