Merge tag 'amd-drm-next-5.7-2020-02-26' of git://people.freedesktop.org/~agd5f/linux...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_drv.c
index 30a1e3ac21d669c3b0b21c62c4c7b0122dc4df84..e1c4c2df716b578bbd7faf2ba91227cb00ff48aa 100644 (file)
@@ -1021,6 +1021,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
                            const struct pci_device_id *ent)
 {
        struct drm_device *dev;
+       struct amdgpu_device *adev;
        unsigned long flags = ent->driver_data;
        int ret, retry = 0;
        bool supports_atomic = false;
@@ -1090,6 +1091,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, dev);
 
+       amdgpu_driver_load_kms(dev, ent->driver_data);
+
 retry_init:
        ret = drm_dev_register(dev, ent->driver_data);
        if (ret == -EAGAIN && ++retry <= 3) {
@@ -1100,6 +1103,11 @@ retry_init:
        } else if (ret)
                goto err_pci;
 
+       adev = dev->dev_private;
+       ret = amdgpu_debugfs_init(adev);
+       if (ret)
+               DRM_ERROR("Creating debugfs files failed (%d).\n", ret);
+
        return 0;
 
 err_pci:
@@ -1113,6 +1121,7 @@ static void
 amdgpu_pci_remove(struct pci_dev *pdev)
 {
        struct drm_device *dev = pci_get_drvdata(pdev);
+       struct amdgpu_device *adev = dev->dev_private;
 
 #ifdef MODULE
        if (THIS_MODULE->state != MODULE_STATE_GOING)
@@ -1120,6 +1129,8 @@ amdgpu_pci_remove(struct pci_dev *pdev)
                DRM_ERROR("Hotplug removal is not supported\n");
        drm_dev_unplug(dev);
        drm_dev_put(dev);
+       amdgpu_debugfs_fini(adev);
+       amdgpu_driver_unload_kms(dev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
 }
@@ -1147,7 +1158,7 @@ static int amdgpu_pmops_suspend(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
 
-       return amdgpu_device_suspend(drm_dev, true, true);
+       return amdgpu_device_suspend(drm_dev, true);
 }
 
 static int amdgpu_pmops_resume(struct device *dev)
@@ -1155,13 +1166,14 @@ static int amdgpu_pmops_resume(struct device *dev)
        struct drm_device *drm_dev = dev_get_drvdata(dev);
 
        /* GPU comes up enabled by the bios on resume */
-       if (amdgpu_device_is_px(drm_dev)) {
+       if (amdgpu_device_supports_boco(drm_dev) ||
+           amdgpu_device_supports_baco(drm_dev)) {
                pm_runtime_disable(dev);
                pm_runtime_set_active(dev);
                pm_runtime_enable(dev);
        }
 
-       return amdgpu_device_resume(drm_dev, true, true);
+       return amdgpu_device_resume(drm_dev, true);
 }
 
 static int amdgpu_pmops_freeze(struct device *dev)
@@ -1170,7 +1182,7 @@ static int amdgpu_pmops_freeze(struct device *dev)
        struct amdgpu_device *adev = drm_dev->dev_private;
        int r;
 
-       r = amdgpu_device_suspend(drm_dev, false, true);
+       r = amdgpu_device_suspend(drm_dev, true);
        if (r)
                return r;
        return amdgpu_asic_reset(adev);
@@ -1180,46 +1192,70 @@ static int amdgpu_pmops_thaw(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
 
-       return amdgpu_device_resume(drm_dev, false, true);
+       return amdgpu_device_resume(drm_dev, true);
 }
 
 static int amdgpu_pmops_poweroff(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
 
-       return amdgpu_device_suspend(drm_dev, true, true);
+       return amdgpu_device_suspend(drm_dev, true);
 }
 
 static int amdgpu_pmops_restore(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
 
-       return amdgpu_device_resume(drm_dev, false, true);
+       return amdgpu_device_resume(drm_dev, true);
 }
 
 static int amdgpu_pmops_runtime_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct drm_device *drm_dev = pci_get_drvdata(pdev);
-       int ret;
+       struct amdgpu_device *adev = drm_dev->dev_private;
+       int ret, i;
 
-       if (!amdgpu_device_is_px(drm_dev)) {
+       if (!adev->runpm) {
                pm_runtime_forbid(dev);
                return -EBUSY;
        }
 
-       drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+       /* wait for all rings to drain before suspending */
+       for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
+               struct amdgpu_ring *ring = adev->rings[i];
+               if (ring && ring->sched.ready) {
+                       ret = amdgpu_fence_wait_empty(ring);
+                       if (ret)
+                               return -EBUSY;
+               }
+       }
+
+       adev->in_runpm = true;
+       if (amdgpu_device_supports_boco(drm_dev))
+               drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
        drm_kms_helper_poll_disable(drm_dev);
 
-       ret = amdgpu_device_suspend(drm_dev, false, false);
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_ignore_hotplug(pdev);
-       if (amdgpu_is_atpx_hybrid())
-               pci_set_power_state(pdev, PCI_D3cold);
-       else if (!amdgpu_has_atpx_dgpu_power_cntl())
-               pci_set_power_state(pdev, PCI_D3hot);
-       drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
+       ret = amdgpu_device_suspend(drm_dev, false);
+       if (ret)
+               return ret;
+
+       if (amdgpu_device_supports_boco(drm_dev)) {
+               /* Only need to handle PCI state in the driver for ATPX
+                * PCI core handles it for _PR3.
+                */
+               if (amdgpu_is_atpx_hybrid()) {
+                       pci_ignore_hotplug(pdev);
+               } else {
+                       pci_save_state(pdev);
+                       pci_disable_device(pdev);
+                       pci_ignore_hotplug(pdev);
+                       pci_set_power_state(pdev, PCI_D3cold);
+               }
+               drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
+       } else if (amdgpu_device_supports_baco(drm_dev)) {
+               amdgpu_device_baco_enter(drm_dev);
+       }
 
        return 0;
 }
@@ -1228,34 +1264,46 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct drm_device *drm_dev = pci_get_drvdata(pdev);
+       struct amdgpu_device *adev = drm_dev->dev_private;
        int ret;
 
-       if (!amdgpu_device_is_px(drm_dev))
+       if (!adev->runpm)
                return -EINVAL;
 
-       drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
-
-       if (amdgpu_is_atpx_hybrid() ||
-           !amdgpu_has_atpx_dgpu_power_cntl())
-               pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       ret = pci_enable_device(pdev);
-       if (ret)
-               return ret;
-       pci_set_master(pdev);
-
-       ret = amdgpu_device_resume(drm_dev, false, false);
+       if (amdgpu_device_supports_boco(drm_dev)) {
+               drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+
+               /* Only need to handle PCI state in the driver for ATPX
+                * PCI core handles it for _PR3.
+                */
+               if (amdgpu_is_atpx_hybrid()) {
+                       pci_set_master(pdev);
+               } else {
+                       pci_set_power_state(pdev, PCI_D0);
+                       pci_restore_state(pdev);
+                       ret = pci_enable_device(pdev);
+                       if (ret)
+                               return ret;
+                       pci_set_master(pdev);
+               }
+       } else if (amdgpu_device_supports_baco(drm_dev)) {
+               amdgpu_device_baco_exit(drm_dev);
+       }
+       ret = amdgpu_device_resume(drm_dev, false);
        drm_kms_helper_poll_enable(drm_dev);
-       drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
+       if (amdgpu_device_supports_boco(drm_dev))
+               drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
+       adev->in_runpm = false;
        return 0;
 }
 
 static int amdgpu_pmops_runtime_idle(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
+       struct amdgpu_device *adev = drm_dev->dev_private;
        struct drm_crtc *crtc;
 
-       if (!amdgpu_device_is_px(drm_dev)) {
+       if (!adev->runpm) {
                pm_runtime_forbid(dev);
                return -EBUSY;
        }
@@ -1345,32 +1393,15 @@ int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv)
        return 0;
 }
 
-static bool
-amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe,
-                                bool in_vblank_irq, int *vpos, int *hpos,
-                                ktime_t *stime, ktime_t *etime,
-                                const struct drm_display_mode *mode)
-{
-       return amdgpu_display_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
-                                                 stime, etime, mode);
-}
-
 static struct drm_driver kms_driver = {
        .driver_features =
-           DRIVER_USE_AGP | DRIVER_ATOMIC |
+           DRIVER_ATOMIC |
            DRIVER_GEM |
            DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ |
            DRIVER_SYNCOBJ_TIMELINE,
-       .load = amdgpu_driver_load_kms,
        .open = amdgpu_driver_open_kms,
        .postclose = amdgpu_driver_postclose_kms,
        .lastclose = amdgpu_driver_lastclose_kms,
-       .unload = amdgpu_driver_unload_kms,
-       .get_vblank_counter = amdgpu_get_vblank_counter_kms,
-       .enable_vblank = amdgpu_enable_vblank_kms,
-       .disable_vblank = amdgpu_disable_vblank_kms,
-       .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
-       .get_scanout_position = amdgpu_get_crtc_scanout_position,
        .irq_handler = amdgpu_irq_handler,
        .ioctls = amdgpu_ioctls_kms,
        .gem_free_object_unlocked = amdgpu_gem_object_free,