Merge tag 'amd-drm-next-5.12-2021-01-08' of https://gitlab.freedesktop.org/agd5f...
authorDave Airlie <airlied@redhat.com>
Thu, 14 Jan 2021 23:05:23 +0000 (09:05 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 14 Jan 2021 23:05:32 +0000 (09:05 +1000)
amd-drm-next-5.12-2021-01-08:

amdgpu:
- Rework IH ring handling on vega and navi
- Rework HDP handling for vega and navi
- swSMU documenation updates
- Overdrive support for Sienna Cichlid and newer asics
- swSMU updates for vangogh
- swSMU updates for renoir
- Enable FP16 on DCE8-11
- Misc code cleanups and bug fixes

radeon:
- Fixes for platforms that can't access PCI resources correctly
- Misc code cleanups

From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210108221811.3868-1-alexander.deucher@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
1  2 
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

@@@ -55,6 -55,7 +55,6 @@@
  #include <drm/ttm/ttm_bo_api.h>
  #include <drm/ttm/ttm_bo_driver.h>
  #include <drm/ttm/ttm_placement.h>
 -#include <drm/ttm/ttm_module.h>
  #include <drm/ttm/ttm_execbuf_util.h>
  
  #include <drm/amdgpu_drm.h>
@@@ -88,6 -89,7 +88,7 @@@
  #include "amdgpu_gfx.h"
  #include "amdgpu_sdma.h"
  #include "amdgpu_nbio.h"
+ #include "amdgpu_hdp.h"
  #include "amdgpu_dm.h"
  #include "amdgpu_virt.h"
  #include "amdgpu_csa.h"
  #include "amdgpu_gfxhub.h"
  #include "amdgpu_df.h"
  #include "amdgpu_smuio.h"
+ #include "amdgpu_hdp.h"
  
  #define MAX_GPU_INSTANCE              16
  
@@@ -607,7 -610,6 +609,6 @@@ struct amdgpu_asic_funcs 
        /* invalidate hdp read cache */
        void (*invalidate_hdp)(struct amdgpu_device *adev,
                               struct amdgpu_ring *ring);
-       void (*reset_hdp_ras_error_count)(struct amdgpu_device *adev);
        /* check if the asic needs a full reset of if soft reset will work */
        bool (*need_full_reset)(struct amdgpu_device *adev);
        /* initialize doorbell layout for specific asic*/
@@@ -920,6 -922,9 +921,9 @@@ struct amdgpu_device 
        /* nbio */
        struct amdgpu_nbio              nbio;
  
+       /* hdp */
+       struct amdgpu_hdp               hdp;
        /* smuio */
        struct amdgpu_smuio             smuio;
  
@@@ -1201,8 -1206,10 +1205,10 @@@ int emu_soc_asic_init(struct amdgpu_dev
  #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
  #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v)))
  #define amdgpu_asic_get_config_memsize(adev) (adev)->asic_funcs->get_config_memsize((adev))
- #define amdgpu_asic_flush_hdp(adev, r) (adev)->asic_funcs->flush_hdp((adev), (r))
- #define amdgpu_asic_invalidate_hdp(adev, r) (adev)->asic_funcs->invalidate_hdp((adev), (r))
+ #define amdgpu_asic_flush_hdp(adev, r) \
+       ((adev)->asic_funcs->flush_hdp ? (adev)->asic_funcs->flush_hdp((adev), (r)) : (adev)->hdp.funcs->flush_hdp((adev), (r)))
+ #define amdgpu_asic_invalidate_hdp(adev, r) \
+       ((adev)->asic_funcs->invalidate_hdp ? (adev)->asic_funcs->invalidate_hdp((adev), (r)) : (adev)->hdp.funcs->invalidate_hdp((adev), (r)))
  #define amdgpu_asic_need_full_reset(adev) (adev)->asic_funcs->need_full_reset((adev))
  #define amdgpu_asic_init_doorbell_index(adev) (adev)->asic_funcs->init_doorbell_index((adev))
  #define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
@@@ -1281,8 -1288,6 +1287,8 @@@ int amdgpu_enable_vblank_kms(struct drm
  void amdgpu_disable_vblank_kms(struct drm_crtc *crtc);
  long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd,
                             unsigned long arg);
 +int amdgpu_info_ioctl(struct drm_device *dev, void *data,
 +                    struct drm_file *filp);
  
  /*
   * functions used by amdgpu_encoder.c
@@@ -2548,11 -2548,11 +2548,11 @@@ static int amdgpu_device_ip_fini(struc
        if (adev->gmc.xgmi.num_physical_nodes > 1)
                amdgpu_xgmi_remove_device(adev);
  
-       amdgpu_amdkfd_device_fini(adev);
        amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
        amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
  
+       amdgpu_amdkfd_device_fini(adev);
        /* need to disable SMC first */
        for (i = 0; i < adev->num_ip_blocks; i++) {
                if (!adev->ip_blocks[i].status.hw)
@@@ -3034,7 -3034,7 +3034,7 @@@ bool amdgpu_device_asic_has_dc_support(
  #endif
        default:
                if (amdgpu_dc > 0)
-                       DRM_INFO("Display Core has been requested via kernel parameter "
+                       DRM_INFO_ONCE("Display Core has been requested via kernel parameter "
                                         "but isn't supported by ASIC, ignoring\n");
                return false;
        }
@@@ -4155,8 -4155,8 +4155,8 @@@ bool amdgpu_device_has_job_running(stru
                        continue;
  
                spin_lock(&ring->sched.job_list_lock);
 -              job = list_first_entry_or_null(&ring->sched.ring_mirror_list,
 -                              struct drm_sched_job, node);
 +              job = list_first_entry_or_null(&ring->sched.pending_list,
 +                                             struct drm_sched_job, list);
                spin_unlock(&ring->sched.job_list_lock);
                if (job)
                        return true;
@@@ -40,6 -40,7 +40,7 @@@
  #include <linux/dma-buf.h>
  #include <linux/dma-fence-array.h>
  #include <linux/pci-p2pdma.h>
+ #include <linux/pm_runtime.h>
  
  /**
   * amdgpu_gem_prime_mmap - &drm_driver.gem_prime_mmap implementation
@@@ -151,9 -152,13 +152,13 @@@ static int amdgpu_dma_buf_attach(struc
        if (attach->dev->driver == adev->dev->driver)
                return 0;
  
+       r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
+       if (r < 0)
+               goto out;
        r = amdgpu_bo_reserve(bo, false);
        if (unlikely(r != 0))
-               return r;
+               goto out;
  
        /*
         * We only create shared fences for internal use, but importers
         */
        r = __dma_resv_make_exclusive(bo->tbo.base.resv);
        if (r)
-               return r;
+               goto out;
  
        bo->prime_shared_count++;
        amdgpu_bo_unreserve(bo);
        return 0;
+ out:
+       pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
+       return r;
  }
  
  /**
@@@ -189,6 -198,9 +198,9 @@@ static void amdgpu_dma_buf_detach(struc
  
        if (attach->dev->driver != adev->dev->driver && bo->prime_shared_count)
                bo->prime_shared_count--;
+       pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
+       pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
  }
  
  /**
@@@ -269,7 -281,7 +281,7 @@@ static struct sg_table *amdgpu_dma_buf_
        case TTM_PL_TT:
                sgt = drm_prime_pages_to_sg(obj->dev,
                                            bo->tbo.ttm->pages,
 -                                          bo->tbo.num_pages);
 +                                          bo->tbo.ttm->num_pages);
                if (IS_ERR(sgt))
                        return sgt;
  
@@@ -21,7 -21,7 +21,7 @@@
   *
   */
  
- #if !defined(_AMDGPU_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+ #if !defined(_AMDGPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
  #define _AMDGPU_TRACE_H_
  
  #include <linux/stringify.h>
@@@ -127,7 -127,7 +127,7 @@@ TRACE_EVENT(amdgpu_bo_create
  
            TP_fast_assign(
                           __entry->bo = bo;
 -                         __entry->pages = bo->tbo.num_pages;
 +                         __entry->pages = bo->tbo.mem.num_pages;
                           __entry->type = bo->tbo.mem.mem_type;
                           __entry->prefer = bo->preferred_domains;
                           __entry->allow = bo->allowed_domains;
@@@ -60,7 -60,6 +60,6 @@@
  
  #include <linux/module.h>
  #include <linux/moduleparam.h>
- #include <linux/version.h>
  #include <linux/types.h>
  #include <linux/pm_runtime.h>
  #include <linux/pci.h>
@@@ -2386,8 -2385,7 +2385,7 @@@ void amdgpu_dm_update_connector_after_d
  
                        drm_connector_update_edid_property(connector,
                                                           aconnector->edid);
-                       aconnector->num_modes = drm_add_edid_modes(connector, aconnector->edid);
-                       drm_connector_list_update(connector);
+                       drm_add_edid_modes(connector, aconnector->edid);
  
                        if (aconnector->dc_link->aux_mode)
                                drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
@@@ -3760,10 -3758,53 +3758,53 @@@ static const struct drm_encoder_funcs a
  };
  
  
+ static void get_min_max_dc_plane_scaling(struct drm_device *dev,
+                                        struct drm_framebuffer *fb,
+                                        int *min_downscale, int *max_upscale)
+ {
+       struct amdgpu_device *adev = drm_to_adev(dev);
+       struct dc *dc = adev->dm.dc;
+       /* Caps for all supported planes are the same on DCE and DCN 1 - 3 */
+       struct dc_plane_cap *plane_cap = &dc->caps.planes[0];
+       switch (fb->format->format) {
+       case DRM_FORMAT_P010:
+       case DRM_FORMAT_NV12:
+       case DRM_FORMAT_NV21:
+               *max_upscale = plane_cap->max_upscale_factor.nv12;
+               *min_downscale = plane_cap->max_downscale_factor.nv12;
+               break;
+       case DRM_FORMAT_XRGB16161616F:
+       case DRM_FORMAT_ARGB16161616F:
+       case DRM_FORMAT_XBGR16161616F:
+       case DRM_FORMAT_ABGR16161616F:
+               *max_upscale = plane_cap->max_upscale_factor.fp16;
+               *min_downscale = plane_cap->max_downscale_factor.fp16;
+               break;
+       default:
+               *max_upscale = plane_cap->max_upscale_factor.argb8888;
+               *min_downscale = plane_cap->max_downscale_factor.argb8888;
+               break;
+       }
+       /*
+        * A factor of 1 in the plane_cap means to not allow scaling, ie. use a
+        * scaling factor of 1.0 == 1000 units.
+        */
+       if (*max_upscale == 1)
+               *max_upscale = 1000;
+       if (*min_downscale == 1)
+               *min_downscale = 1000;
+ }
  static int fill_dc_scaling_info(const struct drm_plane_state *state,
                                struct dc_scaling_info *scaling_info)
  {
-       int scale_w, scale_h;
+       int scale_w, scale_h, min_downscale, max_upscale;
  
        memset(scaling_info, 0, sizeof(*scaling_info));
  
        /* DRM doesn't specify clipping on destination output. */
        scaling_info->clip_rect = scaling_info->dst_rect;
  
-       /* TODO: Validate scaling per-format with DC plane caps */
+       /* Validate scaling per-format with DC plane caps */
+       if (state->plane && state->plane->dev && state->fb) {
+               get_min_max_dc_plane_scaling(state->plane->dev, state->fb,
+                                            &min_downscale, &max_upscale);
+       } else {
+               min_downscale = 250;
+               max_upscale = 16000;
+       }
        scale_w = scaling_info->dst_rect.width * 1000 /
                  scaling_info->src_rect.width;
  
-       if (scale_w < 250 || scale_w > 16000)
+       if (scale_w < min_downscale || scale_w > max_upscale)
                return -EINVAL;
  
        scale_h = scaling_info->dst_rect.height * 1000 /
                  scaling_info->src_rect.height;
  
-       if (scale_h < 250 || scale_h > 16000)
+       if (scale_h < min_downscale || scale_h > max_upscale)
                return -EINVAL;
  
        /*
@@@ -5414,6 -5463,7 +5463,7 @@@ static inline int dm_set_vblank(struct 
        struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
        struct amdgpu_device *adev = drm_to_adev(crtc->dev);
        struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
+       struct amdgpu_display_manager *dm = &adev->dm;
        int rc = 0;
  
        if (enable) {
                return rc;
  
        irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst;
-       return dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY;
+       if (!dc_interrupt_set(adev->dm.dc, irq_source, enable))
+               return -EBUSY;
+       mutex_lock(&dm->dc_lock);
+       if (enable)
+               dm->active_vblank_irq_count++;
+       else
+               dm->active_vblank_irq_count--;
+ #if defined(CONFIG_DRM_AMD_DC_DCN)
+       dc_allow_idle_optimizations(
+               adev->dm.dc, dm->active_vblank_irq_count == 0 ? true : false);
+       DRM_DEBUG_DRIVER("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0);
+ #endif
+       mutex_unlock(&dm->dc_lock);
+       return 0;
  }
  
  static int dm_enable_vblank(struct drm_crtc *crtc)
@@@ -5446,6 -5516,7 +5516,6 @@@ static void dm_disable_vblank(struct dr
  static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
        .reset = dm_crtc_reset_state,
        .destroy = amdgpu_dm_crtc_destroy,
 -      .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
        .atomic_duplicate_state = dm_crtc_duplicate_state,
@@@ -6424,12 -6495,26 +6494,26 @@@ static void dm_plane_helper_cleanup_fb(
  static int dm_plane_helper_check_state(struct drm_plane_state *state,
                                       struct drm_crtc_state *new_crtc_state)
  {
-       int max_downscale = 0;
-       int max_upscale = INT_MAX;
+       struct drm_framebuffer *fb = state->fb;
+       int min_downscale, max_upscale;
+       int min_scale = 0;
+       int max_scale = INT_MAX;
+       /* Plane enabled? Get min/max allowed scaling factors from plane caps. */
+       if (fb && state->crtc) {
+               get_min_max_dc_plane_scaling(state->crtc->dev, fb,
+                                            &min_downscale, &max_upscale);
+               /*
+                * Convert to drm convention: 16.16 fixed point, instead of dc's
+                * 1.0 == 1000. Also drm scaling is src/dst instead of dc's
+                * dst/src, so min_scale = 1.0 / max_upscale, etc.
+                */
+               min_scale = (1000 << 16) / max_upscale;
+               max_scale = (1000 << 16) / min_downscale;
+       }
  
-       /* TODO: These should be checked against DC plane caps */
        return drm_atomic_helper_check_plane_state(
-               state, new_crtc_state, max_downscale, max_upscale, true, true);
+               state, new_crtc_state, min_scale, max_scale, true, true);
  }
  
  static int dm_plane_atomic_check(struct drm_plane *plane,
@@@ -8378,8 -8463,7 +8462,7 @@@ static void amdgpu_dm_atomic_commit_tai
                        acrtc->dm_irq_params.stream = dm_new_crtc_state->stream;
                        manage_dm_interrupts(adev, acrtc, true);
                }
- #ifdef CONFIG_DEBUG_FS
-               if (new_crtc_state->active &&
+               if (IS_ENABLED(CONFIG_DEBUG_FS) && new_crtc_state->active &&
                        amdgpu_dm_is_valid_crc_source(dm_new_crtc_state->crc_src)) {
                        /**
                         * Frontend may have changed so reapply the CRC capture
                                amdgpu_dm_crtc_configure_crc_source(
                                        crtc, dm_new_crtc_state, dm_new_crtc_state->crc_src);
                }
- #endif
        }
  
        for_each_new_crtc_in_state(state, crtc, new_crtc_state, j)
@@@ -23,8 -23,6 +23,7 @@@
   *
   */
  
- #include <linux/version.h>
 +#include <drm/drm_atomic.h>
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_dp_mst_helper.h>
  #include <drm/drm_dp_helper.h>
@@@ -253,10 -251,8 +252,10 @@@ static int dm_dp_mst_get_modes(struct d
  
  static struct drm_encoder *
  dm_mst_atomic_best_encoder(struct drm_connector *connector,
 -                         struct drm_connector_state *connector_state)
 +                         struct drm_atomic_state *state)
  {
 +      struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state,
 +                                                                                       connector);
        struct drm_device *dev = connector->dev;
        struct amdgpu_device *adev = drm_to_adev(dev);
        struct amdgpu_crtc *acrtc = to_amdgpu_crtc(connector_state->crtc);