diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2018-02-12 04:44:37 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2018-09-03 09:13:25 -0400 |
commit | 52b9ef246d6a8667c87771d1b0fdb982afc88c7f (patch) | |
tree | 4c0b9a9e0fd58d05dc357086069bce0d74a1f65c /drivers/gpu/drm/omapdrm/omap_drv.c | |
parent | fb96b67c8ae0c91e17f0f9fe88cfce406ace6a94 (diff) |
drm/omap: Manage the usable omap_dss_device list within omap_drm_private
Instead of reaching back to DSS to iterate through the dss_devices every
time, use an internal array where we store the available and usable
dss_devices.
At the same time remove the omapdss_device_is_connected() check from
omap_modeset_init() as it became irrelevant: We are not adding dssdevs
if their connect failed.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.c | 94 |
1 files changed, 59 insertions, 35 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index e5afecb4fd45..d1a1129a3f5d 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c | |||
@@ -149,18 +149,27 @@ static int get_connector_type(struct omap_dss_device *dssdev) | |||
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
152 | static void omap_disconnect_dssdevs(void) | 152 | static void omap_disconnect_dssdevs(struct drm_device *ddev) |
153 | { | 153 | { |
154 | struct omap_dss_device *dssdev = NULL; | 154 | struct omap_drm_private *priv = ddev->dev_private; |
155 | unsigned int i; | ||
156 | |||
157 | for (i = 0; i < priv->num_dssdevs; i++) { | ||
158 | struct omap_dss_device *dssdev = priv->dssdevs[i]; | ||
155 | 159 | ||
156 | for_each_dss_dev(dssdev) | ||
157 | dssdev->driver->disconnect(dssdev); | 160 | dssdev->driver->disconnect(dssdev); |
161 | priv->dssdevs[i] = NULL; | ||
162 | omap_dss_put_device(dssdev); | ||
163 | } | ||
164 | |||
165 | priv->num_dssdevs = 0; | ||
158 | } | 166 | } |
159 | 167 | ||
160 | static int omap_connect_dssdevs(void) | 168 | static int omap_connect_dssdevs(struct drm_device *ddev) |
161 | { | 169 | { |
162 | int r; | 170 | struct omap_drm_private *priv = ddev->dev_private; |
163 | struct omap_dss_device *dssdev = NULL; | 171 | struct omap_dss_device *dssdev = NULL; |
172 | int r; | ||
164 | 173 | ||
165 | if (!omapdss_stack_is_ready()) | 174 | if (!omapdss_stack_is_ready()) |
166 | return -EPROBE_DEFER; | 175 | return -EPROBE_DEFER; |
@@ -173,6 +182,14 @@ static int omap_connect_dssdevs(void) | |||
173 | } else if (r) { | 182 | } else if (r) { |
174 | dev_warn(dssdev->dev, "could not connect display: %s\n", | 183 | dev_warn(dssdev->dev, "could not connect display: %s\n", |
175 | dssdev->name); | 184 | dssdev->name); |
185 | } else { | ||
186 | omap_dss_get_device(dssdev); | ||
187 | priv->dssdevs[priv->num_dssdevs++] = dssdev; | ||
188 | if (priv->num_dssdevs == ARRAY_SIZE(priv->dssdevs)) { | ||
189 | /* To balance the 'for_each_dss_dev' loop */ | ||
190 | omap_dss_put_device(dssdev); | ||
191 | break; | ||
192 | } | ||
176 | } | 193 | } |
177 | } | 194 | } |
178 | 195 | ||
@@ -183,7 +200,7 @@ cleanup: | |||
183 | * if we are deferring probe, we disconnect the devices we previously | 200 | * if we are deferring probe, we disconnect the devices we previously |
184 | * connected | 201 | * connected |
185 | */ | 202 | */ |
186 | omap_disconnect_dssdevs(); | 203 | omap_disconnect_dssdevs(ddev); |
187 | 204 | ||
188 | return r; | 205 | return r; |
189 | } | 206 | } |
@@ -208,6 +225,7 @@ static int omap_modeset_init(struct drm_device *dev) | |||
208 | int num_ovls = priv->dispc_ops->get_num_ovls(priv->dispc); | 225 | int num_ovls = priv->dispc_ops->get_num_ovls(priv->dispc); |
209 | int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc); | 226 | int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc); |
210 | int num_crtcs, crtc_idx, plane_idx; | 227 | int num_crtcs, crtc_idx, plane_idx; |
228 | unsigned int i; | ||
211 | int ret; | 229 | int ret; |
212 | u32 plane_crtc_mask; | 230 | u32 plane_crtc_mask; |
213 | 231 | ||
@@ -225,11 +243,7 @@ static int omap_modeset_init(struct drm_device *dev) | |||
225 | * configuration does not match the expectations or exceeds | 243 | * configuration does not match the expectations or exceeds |
226 | * the available resources, the configuration is rejected. | 244 | * the available resources, the configuration is rejected. |
227 | */ | 245 | */ |
228 | num_crtcs = 0; | 246 | num_crtcs = priv->num_dssdevs; |
229 | for_each_dss_dev(dssdev) | ||
230 | if (omapdss_device_is_connected(dssdev)) | ||
231 | num_crtcs++; | ||
232 | |||
233 | if (num_crtcs > num_mgrs || num_crtcs > num_ovls || | 247 | if (num_crtcs > num_mgrs || num_crtcs > num_ovls || |
234 | num_crtcs > ARRAY_SIZE(priv->crtcs) || | 248 | num_crtcs > ARRAY_SIZE(priv->crtcs) || |
235 | num_crtcs > ARRAY_SIZE(priv->planes) || | 249 | num_crtcs > ARRAY_SIZE(priv->planes) || |
@@ -247,15 +261,13 @@ static int omap_modeset_init(struct drm_device *dev) | |||
247 | 261 | ||
248 | crtc_idx = 0; | 262 | crtc_idx = 0; |
249 | plane_idx = 0; | 263 | plane_idx = 0; |
250 | for_each_dss_dev(dssdev) { | 264 | for (i = 0; i < priv->num_dssdevs; i++) { |
265 | struct omap_dss_device *dssdev = priv->dssdevs[i]; | ||
251 | struct drm_connector *connector; | 266 | struct drm_connector *connector; |
252 | struct drm_encoder *encoder; | 267 | struct drm_encoder *encoder; |
253 | struct drm_plane *plane; | 268 | struct drm_plane *plane; |
254 | struct drm_crtc *crtc; | 269 | struct drm_crtc *crtc; |
255 | 270 | ||
256 | if (!omapdss_device_is_connected(dssdev)) | ||
257 | continue; | ||
258 | |||
259 | encoder = omap_encoder_init(dev, dssdev); | 271 | encoder = omap_encoder_init(dev, dssdev); |
260 | if (!encoder) | 272 | if (!encoder) |
261 | return -ENOMEM; | 273 | return -ENOMEM; |
@@ -335,11 +347,14 @@ static int omap_modeset_init(struct drm_device *dev) | |||
335 | /* | 347 | /* |
336 | * Enable the HPD in external components if supported | 348 | * Enable the HPD in external components if supported |
337 | */ | 349 | */ |
338 | static void omap_modeset_enable_external_hpd(void) | 350 | static void omap_modeset_enable_external_hpd(struct drm_device *ddev) |
339 | { | 351 | { |
340 | struct omap_dss_device *dssdev = NULL; | 352 | struct omap_drm_private *priv = ddev->dev_private; |
353 | int i; | ||
354 | |||
355 | for (i = 0; i < priv->num_dssdevs; i++) { | ||
356 | struct omap_dss_device *dssdev = priv->dssdevs[i]; | ||
341 | 357 | ||
342 | for_each_dss_dev(dssdev) { | ||
343 | if (dssdev->driver->enable_hpd) | 358 | if (dssdev->driver->enable_hpd) |
344 | dssdev->driver->enable_hpd(dssdev); | 359 | dssdev->driver->enable_hpd(dssdev); |
345 | } | 360 | } |
@@ -348,11 +363,14 @@ static void omap_modeset_enable_external_hpd(void) | |||
348 | /* | 363 | /* |
349 | * Disable the HPD in external components if supported | 364 | * Disable the HPD in external components if supported |
350 | */ | 365 | */ |
351 | static void omap_modeset_disable_external_hpd(void) | 366 | static void omap_modeset_disable_external_hpd(struct drm_device *ddev) |
352 | { | 367 | { |
353 | struct omap_dss_device *dssdev = NULL; | 368 | struct omap_drm_private *priv = ddev->dev_private; |
369 | int i; | ||
370 | |||
371 | for (i = 0; i < priv->num_dssdevs; i++) { | ||
372 | struct omap_dss_device *dssdev = priv->dssdevs[i]; | ||
354 | 373 | ||
355 | for_each_dss_dev(dssdev) { | ||
356 | if (dssdev->driver->disable_hpd) | 374 | if (dssdev->driver->disable_hpd) |
357 | dssdev->driver->disable_hpd(dssdev); | 375 | dssdev->driver->disable_hpd(dssdev); |
358 | } | 376 | } |
@@ -540,7 +558,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) | |||
540 | 558 | ||
541 | omap_crtc_pre_init(priv); | 559 | omap_crtc_pre_init(priv); |
542 | 560 | ||
543 | ret = omap_connect_dssdevs(); | 561 | ret = omap_connect_dssdevs(ddev); |
544 | if (ret) | 562 | if (ret) |
545 | goto err_crtc_uninit; | 563 | goto err_crtc_uninit; |
546 | 564 | ||
@@ -577,7 +595,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) | |||
577 | omap_fbdev_init(ddev); | 595 | omap_fbdev_init(ddev); |
578 | 596 | ||
579 | drm_kms_helper_poll_init(ddev); | 597 | drm_kms_helper_poll_init(ddev); |
580 | omap_modeset_enable_external_hpd(); | 598 | omap_modeset_enable_external_hpd(ddev); |
581 | 599 | ||
582 | /* | 600 | /* |
583 | * Register the DRM device with the core and the connectors with | 601 | * Register the DRM device with the core and the connectors with |
@@ -590,7 +608,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) | |||
590 | return 0; | 608 | return 0; |
591 | 609 | ||
592 | err_cleanup_helpers: | 610 | err_cleanup_helpers: |
593 | omap_modeset_disable_external_hpd(); | 611 | omap_modeset_disable_external_hpd(ddev); |
594 | drm_kms_helper_poll_fini(ddev); | 612 | drm_kms_helper_poll_fini(ddev); |
595 | 613 | ||
596 | omap_fbdev_fini(ddev); | 614 | omap_fbdev_fini(ddev); |
@@ -600,7 +618,7 @@ err_cleanup_modeset: | |||
600 | err_gem_deinit: | 618 | err_gem_deinit: |
601 | omap_gem_deinit(ddev); | 619 | omap_gem_deinit(ddev); |
602 | destroy_workqueue(priv->wq); | 620 | destroy_workqueue(priv->wq); |
603 | omap_disconnect_dssdevs(); | 621 | omap_disconnect_dssdevs(ddev); |
604 | err_crtc_uninit: | 622 | err_crtc_uninit: |
605 | omap_crtc_pre_uninit(); | 623 | omap_crtc_pre_uninit(); |
606 | drm_dev_unref(ddev); | 624 | drm_dev_unref(ddev); |
@@ -615,7 +633,7 @@ static void omapdrm_cleanup(struct omap_drm_private *priv) | |||
615 | 633 | ||
616 | drm_dev_unregister(ddev); | 634 | drm_dev_unregister(ddev); |
617 | 635 | ||
618 | omap_modeset_disable_external_hpd(); | 636 | omap_modeset_disable_external_hpd(ddev); |
619 | drm_kms_helper_poll_fini(ddev); | 637 | drm_kms_helper_poll_fini(ddev); |
620 | 638 | ||
621 | omap_fbdev_fini(ddev); | 639 | omap_fbdev_fini(ddev); |
@@ -629,7 +647,7 @@ static void omapdrm_cleanup(struct omap_drm_private *priv) | |||
629 | 647 | ||
630 | destroy_workqueue(priv->wq); | 648 | destroy_workqueue(priv->wq); |
631 | 649 | ||
632 | omap_disconnect_dssdevs(); | 650 | omap_disconnect_dssdevs(ddev); |
633 | omap_crtc_pre_uninit(); | 651 | omap_crtc_pre_uninit(); |
634 | 652 | ||
635 | drm_dev_unref(ddev); | 653 | drm_dev_unref(ddev); |
@@ -674,11 +692,14 @@ static int pdev_remove(struct platform_device *pdev) | |||
674 | } | 692 | } |
675 | 693 | ||
676 | #ifdef CONFIG_PM_SLEEP | 694 | #ifdef CONFIG_PM_SLEEP |
677 | static int omap_drm_suspend_all_displays(void) | 695 | static int omap_drm_suspend_all_displays(struct drm_device *ddev) |
678 | { | 696 | { |
679 | struct omap_dss_device *dssdev = NULL; | 697 | struct omap_drm_private *priv = ddev->dev_private; |
698 | int i; | ||
699 | |||
700 | for (i = 0; i < priv->num_dssdevs; i++) { | ||
701 | struct omap_dss_device *dssdev = priv->dssdevs[i]; | ||
680 | 702 | ||
681 | for_each_dss_dev(dssdev) { | ||
682 | if (!dssdev->driver) | 703 | if (!dssdev->driver) |
683 | continue; | 704 | continue; |
684 | 705 | ||
@@ -693,11 +714,14 @@ static int omap_drm_suspend_all_displays(void) | |||
693 | return 0; | 714 | return 0; |
694 | } | 715 | } |
695 | 716 | ||
696 | static int omap_drm_resume_all_displays(void) | 717 | static int omap_drm_resume_all_displays(struct drm_device *ddev) |
697 | { | 718 | { |
698 | struct omap_dss_device *dssdev = NULL; | 719 | struct omap_drm_private *priv = ddev->dev_private; |
720 | int i; | ||
721 | |||
722 | for (i = 0; i < priv->num_dssdevs; i++) { | ||
723 | struct omap_dss_device *dssdev = priv->dssdevs[i]; | ||
699 | 724 | ||
700 | for_each_dss_dev(dssdev) { | ||
701 | if (!dssdev->driver) | 725 | if (!dssdev->driver) |
702 | continue; | 726 | continue; |
703 | 727 | ||
@@ -718,7 +742,7 @@ static int omap_drm_suspend(struct device *dev) | |||
718 | drm_kms_helper_poll_disable(drm_dev); | 742 | drm_kms_helper_poll_disable(drm_dev); |
719 | 743 | ||
720 | drm_modeset_lock_all(drm_dev); | 744 | drm_modeset_lock_all(drm_dev); |
721 | omap_drm_suspend_all_displays(); | 745 | omap_drm_suspend_all_displays(drm_dev); |
722 | drm_modeset_unlock_all(drm_dev); | 746 | drm_modeset_unlock_all(drm_dev); |
723 | 747 | ||
724 | return 0; | 748 | return 0; |
@@ -730,7 +754,7 @@ static int omap_drm_resume(struct device *dev) | |||
730 | struct drm_device *drm_dev = priv->ddev; | 754 | struct drm_device *drm_dev = priv->ddev; |
731 | 755 | ||
732 | drm_modeset_lock_all(drm_dev); | 756 | drm_modeset_lock_all(drm_dev); |
733 | omap_drm_resume_all_displays(); | 757 | omap_drm_resume_all_displays(drm_dev); |
734 | drm_modeset_unlock_all(drm_dev); | 758 | drm_modeset_unlock_all(drm_dev); |
735 | 759 | ||
736 | drm_kms_helper_poll_enable(drm_dev); | 760 | drm_kms_helper_poll_enable(drm_dev); |