Merge tag 'drm-intel-next-2022-09-16-1' of git://anongit.freedesktop.org/drm/drm...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / display / intel_fbdev.c
index 221336178991f04fe3e219108f628d58e20c90c0..112aa0447a0dc1ea4ca10b40471bf7d1171e7204 100644 (file)
@@ -198,8 +198,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
        struct i915_ggtt *ggtt = to_gt(dev_priv)->ggtt;
-       const struct i915_ggtt_view view = {
-               .type = I915_GGTT_VIEW_NORMAL,
+       const struct i915_gtt_view view = {
+               .type = I915_GTT_VIEW_NORMAL,
        };
        intel_wakeref_t wakeref;
        struct fb_info *info;
@@ -210,6 +210,12 @@ static int intelfb_create(struct drm_fb_helper *helper,
        struct drm_i915_gem_object *obj;
        int ret;
 
+       mutex_lock(&ifbdev->hpd_lock);
+       ret = ifbdev->hpd_suspended ? -EAGAIN : 0;
+       mutex_unlock(&ifbdev->hpd_lock);
+       if (ret)
+               return ret;
+
        if (intel_fb &&
            (sizes->fb_width > intel_fb->base.width ||
             sizes->fb_height > intel_fb->base.height)) {
@@ -500,7 +506,7 @@ static void intel_fbdev_suspend_worker(struct work_struct *work)
 {
        intel_fbdev_set_suspend(&container_of(work,
                                              struct drm_i915_private,
-                                             fbdev_suspend_work)->drm,
+                                             display.fbdev.suspend_work)->drm,
                                FBINFO_STATE_RUNNING,
                                true);
 }
@@ -530,8 +536,8 @@ int intel_fbdev_init(struct drm_device *dev)
                return ret;
        }
 
-       dev_priv->fbdev = ifbdev;
-       INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);
+       dev_priv->display.fbdev.fbdev = ifbdev;
+       INIT_WORK(&dev_priv->display.fbdev.suspend_work, intel_fbdev_suspend_worker);
 
        return 0;
 }
@@ -548,7 +554,7 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
 
 void intel_fbdev_initial_config_async(struct drm_device *dev)
 {
-       struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
+       struct intel_fbdev *ifbdev = to_i915(dev)->display.fbdev.fbdev;
 
        if (!ifbdev)
                return;
@@ -568,12 +574,13 @@ static void intel_fbdev_sync(struct intel_fbdev *ifbdev)
 
 void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
 {
-       struct intel_fbdev *ifbdev = dev_priv->fbdev;
+       struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
 
        if (!ifbdev)
                return;
 
-       cancel_work_sync(&dev_priv->fbdev_suspend_work);
+       intel_fbdev_set_suspend(&dev_priv->drm, FBINFO_STATE_SUSPENDED, true);
+
        if (!current_is_async())
                intel_fbdev_sync(ifbdev);
 
@@ -582,7 +589,7 @@ void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
 
 void intel_fbdev_fini(struct drm_i915_private *dev_priv)
 {
-       struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->fbdev);
+       struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->display.fbdev.fbdev);
 
        if (!ifbdev)
                return;
@@ -596,7 +603,7 @@ void intel_fbdev_fini(struct drm_i915_private *dev_priv)
  */
 static void intel_fbdev_hpd_set_suspend(struct drm_i915_private *i915, int state)
 {
-       struct intel_fbdev *ifbdev = i915->fbdev;
+       struct intel_fbdev *ifbdev = i915->display.fbdev.fbdev;
        bool send_hpd = false;
 
        mutex_lock(&ifbdev->hpd_lock);
@@ -614,11 +621,11 @@ static void intel_fbdev_hpd_set_suspend(struct drm_i915_private *i915, int state
 void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_fbdev *ifbdev = dev_priv->fbdev;
+       struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
        struct fb_info *info;
 
        if (!ifbdev || !ifbdev->vma)
-               return;
+               goto set_suspend;
 
        info = ifbdev->helper.fbdev;
 
@@ -631,7 +638,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
                 * ourselves, so only flush outstanding work upon suspend!
                 */
                if (state != FBINFO_STATE_RUNNING)
-                       flush_work(&dev_priv->fbdev_suspend_work);
+                       flush_work(&dev_priv->display.fbdev.suspend_work);
 
                console_lock();
        } else {
@@ -645,7 +652,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
                        /* Don't block our own workqueue as this can
                         * be run in parallel with other i915.ko tasks.
                         */
-                       schedule_work(&dev_priv->fbdev_suspend_work);
+                       schedule_work(&dev_priv->display.fbdev.suspend_work);
                        return;
                }
        }
@@ -661,12 +668,13 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
        drm_fb_helper_set_suspend(&ifbdev->helper, state);
        console_unlock();
 
+set_suspend:
        intel_fbdev_hpd_set_suspend(dev_priv, state);
 }
 
 void intel_fbdev_output_poll_changed(struct drm_device *dev)
 {
-       struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
+       struct intel_fbdev *ifbdev = to_i915(dev)->display.fbdev.fbdev;
        bool send_hpd;
 
        if (!ifbdev)
@@ -685,7 +693,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
 
 void intel_fbdev_restore_mode(struct drm_device *dev)
 {
-       struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
+       struct intel_fbdev *ifbdev = to_i915(dev)->display.fbdev.fbdev;
 
        if (!ifbdev)
                return;