Merge tag 'amd-drm-next-6.9-2024-02-09' of https://gitlab.freedesktop.org/agd5f/linux...
authorDave Airlie <airlied@redhat.com>
Tue, 13 Feb 2024 01:32:23 +0000 (11:32 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 13 Feb 2024 01:32:23 +0000 (11:32 +1000)
amd-drm-next-6.9-2024-02-09:

amdgpu:
- Validate DMABuf imports in compute VMs
- Add RAS ACA framework
- PSP 13 fixes
- Misc code cleanups
- Replay fixes
- Atom interpretor PS, WS bounds checking
- DML2 fixes
- Audio fixes
- DCN 3.5 Z state fixes
- Remove deprecated ida_simple usage
- UBSAN fixes
- RAS fixes
- Enable seq64 infrastructure
- DC color block enablement
- Documentation updates
- DC documentation updates
- DMCUB updates
- S3 fixes
- VCN 4.0.5 fixes
- DP MST fixes
- SR-IOV fixes

amdkfd:
- Validate DMABuf imports in compute VMs
- SVM fixes
- Trap handler updates

radeon:
- Atom interpretor PS, WS bounds checking
- Misc code cleanups

UAPI:
- Bump KFD version so UMDs know that the fixes that enable the management of
  VA mappings in compute VMs using the GEM_VA ioctl for DMABufs exported from KFD are present
- Add INFO query for input power.  This matches the existing INFO query for average
  power.  Used in gaming HUDs, etc.
  Example userspace: https://github.com/Umio-Yasuno/libdrm-amdgpu-sys-rs/tree/input_power

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240209221459.5453-1-alexander.deucher@amd.com
1  2 
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c

@@@ -329,8 -329,7 +329,8 @@@ int amdgpu_gfx_kiq_init_ring(struct amd
  
        ring->eop_gpu_addr = kiq->eop_gpu_addr;
        ring->no_scheduler = true;
 -      sprintf(ring->name, "kiq_%d.%d.%d.%d", xcc_id, ring->me, ring->pipe, ring->queue);
 +      snprintf(ring->name, sizeof(ring->name), "kiq_%d.%d.%d.%d",
 +               xcc_id, ring->me, ring->pipe, ring->queue);
        r = amdgpu_ring_init(adev, ring, 1024, irq, AMDGPU_CP_KIQ_IRQ_DRIVER0,
                             AMDGPU_RING_PRIO_DEFAULT, NULL);
        if (r)
@@@ -643,8 -642,8 +643,8 @@@ int amdgpu_gfx_enable_kcq(struct amdgpu
        kiq->pmf->kiq_set_resources(kiq_ring, queue_mask);
        for (i = 0; i < adev->gfx.num_compute_rings; i++) {
                j = i + xcc_id * adev->gfx.num_compute_rings;
-                       kiq->pmf->kiq_map_queues(kiq_ring,
-                                                &adev->gfx.compute_ring[j]);
+               kiq->pmf->kiq_map_queues(kiq_ring,
+                                        &adev->gfx.compute_ring[j]);
        }
  
        r = amdgpu_ring_test_helper(kiq_ring);
@@@ -67,6 -67,7 +67,7 @@@
  #include "amdgpu_dm_debugfs.h"
  #endif
  #include "amdgpu_dm_psr.h"
+ #include "amdgpu_dm_replay.h"
  
  #include "ivsrcid/ivsrcid_vislands30.h"
  
@@@ -2121,6 -2122,16 +2122,16 @@@ static int dm_dmub_sw_init(struct amdgp
        const struct dmcub_firmware_header_v1_0 *hdr;
        enum dmub_asic dmub_asic;
        enum dmub_status status;
+       static enum dmub_window_memory_type window_memory_type[DMUB_WINDOW_TOTAL] = {
+               DMUB_WINDOW_MEMORY_TYPE_FB,             //DMUB_WINDOW_0_INST_CONST
+               DMUB_WINDOW_MEMORY_TYPE_FB,             //DMUB_WINDOW_1_STACK
+               DMUB_WINDOW_MEMORY_TYPE_FB,             //DMUB_WINDOW_2_BSS_DATA
+               DMUB_WINDOW_MEMORY_TYPE_FB,             //DMUB_WINDOW_3_VBIOS
+               DMUB_WINDOW_MEMORY_TYPE_FB,             //DMUB_WINDOW_4_MAILBOX
+               DMUB_WINDOW_MEMORY_TYPE_FB,             //DMUB_WINDOW_5_TRACEBUFF
+               DMUB_WINDOW_MEMORY_TYPE_FB,             //DMUB_WINDOW_6_FW_STATE
+               DMUB_WINDOW_MEMORY_TYPE_FB              //DMUB_WINDOW_7_SCRATCH_MEM
+       };
        int r;
  
        switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
                adev->dm.dmub_fw->data +
                le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
                PSP_HEADER_BYTES;
-       region_params.is_mailbox_in_inbox = false;
+       region_params.window_memory_type = window_memory_type;
  
        status = dmub_srv_calc_region_info(dmub_srv, &region_params,
                                           &region_info);
        memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr;
        memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr;
        memory_params.region_info = &region_info;
+       memory_params.window_memory_type = window_memory_type;
  
        adev->dm.dmub_fb_info =
                kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL);
@@@ -4399,6 -4411,7 +4411,7 @@@ static int amdgpu_dm_initialize_drm_dev
        enum dc_connection_type new_connection_type = dc_connection_none;
        const struct dc_plane_cap *plane;
        bool psr_feature_enabled = false;
+       bool replay_feature_enabled = false;
        int max_overlay = dm->dc->caps.max_slave_planes;
  
        dm->display_indexes_num = dm->dc->caps.max_streams;
                }
        }
  
+       /* Determine whether to enable Replay support by default. */
+       if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
+               switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
+               case IP_VERSION(3, 1, 4):
+               case IP_VERSION(3, 1, 5):
+               case IP_VERSION(3, 1, 6):
+               case IP_VERSION(3, 2, 0):
+               case IP_VERSION(3, 2, 1):
+               case IP_VERSION(3, 5, 0):
+                       replay_feature_enabled = true;
+                       break;
+               default:
+                       replay_feature_enabled = amdgpu_dc_feature_mask & DC_REPLAY_MASK;
+                       break;
+               }
+       }
        /* loops over all connectors on the board */
        for (i = 0; i < link_cnt; i++) {
                struct dc_link *link = NULL;
                                amdgpu_dm_update_connector_after_detect(aconnector);
                                setup_backlight_device(dm, aconnector);
  
+                               /* Disable PSR if Replay can be enabled */
+                               if (replay_feature_enabled)
+                                       if (amdgpu_dm_set_replay_caps(link, aconnector))
+                                               psr_feature_enabled = false;
                                if (psr_feature_enabled)
                                        amdgpu_dm_set_psr_caps(link);
  
@@@ -6402,10 -6437,81 +6437,81 @@@ int amdgpu_dm_connector_atomic_get_prop
        return ret;
  }
  
+ /**
+  * DOC: panel power savings
+  *
+  * The display manager allows you to set your desired **panel power savings**
+  * level (between 0-4, with 0 representing off), e.g. using the following::
+  *
+  *   # echo 3 > /sys/class/drm/card0-eDP-1/amdgpu/panel_power_savings
+  *
+  * Modifying this value can have implications on color accuracy, so tread
+  * carefully.
+  */
+ static ssize_t panel_power_savings_show(struct device *device,
+                                       struct device_attribute *attr,
+                                       char *buf)
+ {
+       struct drm_connector *connector = dev_get_drvdata(device);
+       struct drm_device *dev = connector->dev;
+       u8 val;
+       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+       val = to_dm_connector_state(connector->state)->abm_level ==
+               ABM_LEVEL_IMMEDIATE_DISABLE ? 0 :
+               to_dm_connector_state(connector->state)->abm_level;
+       drm_modeset_unlock(&dev->mode_config.connection_mutex);
+       return sysfs_emit(buf, "%u\n", val);
+ }
+ static ssize_t panel_power_savings_store(struct device *device,
+                                        struct device_attribute *attr,
+                                        const char *buf, size_t count)
+ {
+       struct drm_connector *connector = dev_get_drvdata(device);
+       struct drm_device *dev = connector->dev;
+       long val;
+       int ret;
+       ret = kstrtol(buf, 0, &val);
+       if (ret)
+               return ret;
+       if (val < 0 || val > 4)
+               return -EINVAL;
+       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+       to_dm_connector_state(connector->state)->abm_level = val ?:
+               ABM_LEVEL_IMMEDIATE_DISABLE;
+       drm_modeset_unlock(&dev->mode_config.connection_mutex);
+       drm_kms_helper_hotplug_event(dev);
+       return count;
+ }
+ static DEVICE_ATTR_RW(panel_power_savings);
+ static struct attribute *amdgpu_attrs[] = {
+       &dev_attr_panel_power_savings.attr,
+       NULL
+ };
+ static const struct attribute_group amdgpu_group = {
+       .name = "amdgpu",
+       .attrs = amdgpu_attrs
+ };
  static void amdgpu_dm_connector_unregister(struct drm_connector *connector)
  {
        struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
  
+       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+               sysfs_remove_group(&connector->kdev->kobj, &amdgpu_group);
        drm_dp_aux_unregister(&amdgpu_dm_connector->dm_dp_aux.aux);
  }
  
@@@ -6507,6 -6613,13 +6613,13 @@@ amdgpu_dm_connector_late_register(struc
                to_amdgpu_dm_connector(connector);
        int r;
  
+       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+               r = sysfs_create_group(&connector->kdev->kobj,
+                                      &amdgpu_group);
+               if (r)
+                       return r;
+       }
        amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
  
        if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
@@@ -7622,6 -7735,7 +7735,6 @@@ create_i2c(struct ddc_service *ddc_serv
        if (!i2c)
                return NULL;
        i2c->base.owner = THIS_MODULE;
 -      i2c->base.class = I2C_CLASS_DDC;
        i2c->base.dev.parent = &adev->pdev->dev;
        i2c->base.algo = &amdgpu_dm_i2c_algo;
        snprintf(i2c->base.name, sizeof(i2c->base.name), "AMDGPU DM i2c hw bus %d", link_index);
@@@ -8526,10 -8640,22 +8639,22 @@@ static void amdgpu_dm_commit_planes(str
                        dm_update_pflip_irq_state(drm_to_adev(dev),
                                                  acrtc_attach);
  
-               if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
-                               acrtc_state->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED &&
-                               !acrtc_state->stream->link->psr_settings.psr_feature_enabled)
-                       amdgpu_dm_link_setup_psr(acrtc_state->stream);
+               if (acrtc_state->update_type > UPDATE_TYPE_FAST) {
+                       if (acrtc_state->stream->link->replay_settings.config.replay_supported &&
+                                       !acrtc_state->stream->link->replay_settings.replay_feature_enabled) {
+                               struct amdgpu_dm_connector *aconn =
+                                       (struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
+                               amdgpu_dm_link_setup_replay(acrtc_state->stream->link, aconn);
+                       } else if (acrtc_state->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED &&
+                                       !acrtc_state->stream->link->psr_settings.psr_feature_enabled) {
+                               struct amdgpu_dm_connector *aconn = (struct amdgpu_dm_connector *)
+                                       acrtc_state->stream->dm_stream_context;
+                               if (!aconn->disallow_edp_enter_psr)
+                                       amdgpu_dm_link_setup_psr(acrtc_state->stream);
+                       }
+               }
  
                /* Decrement skip count when PSR is enabled and we're doing fast updates. */
                if (acrtc_state->update_type == UPDATE_TYPE_FAST &&
                            !amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
  #endif
                            !acrtc_state->stream->link->psr_settings.psr_allow_active &&
+                           !aconn->disallow_edp_enter_psr &&
                            (timestamp_ns -
                            acrtc_state->stream->link->psr_settings.psr_dirty_rects_change_timestamp_ns) >
                            500000000)
@@@ -8818,11 -8945,12 +8944,12 @@@ static void amdgpu_dm_commit_streams(st
                }
        } /* for_each_crtc_in_state() */
  
-       /* if there mode set or reset, disable eDP PSR */
+       /* if there mode set or reset, disable eDP PSR, Replay */
        if (mode_set_reset_required) {
                if (dm->vblank_control_workqueue)
                        flush_workqueue(dm->vblank_control_workqueue);
  
+               amdgpu_dm_replay_disable_all(dm);
                amdgpu_dm_psr_disable_all(dm);
        }
  
@@@ -10731,11 -10859,13 +10858,13 @@@ static int amdgpu_dm_atomic_check(struc
                        goto fail;
                }
  
-               ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
-               if (ret) {
-                       DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
-                       ret = -EINVAL;
-                       goto fail;
+               if (dc_resource_is_dsc_encoding_supported(dc)) {
+                       ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
+                       if (ret) {
+                               DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
+                               ret = -EINVAL;
+                               goto fail;
+                       }
                }
  
                ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars);
@@@ -45,6 -45,7 +45,7 @@@
  #include <linux/pci.h>
  #include "amdgpu_ras.h"
  #include "amdgpu_mca.h"
+ #include "amdgpu_aca.h"
  #include "smu_cmn.h"
  #include "mp/mp_13_0_6_offset.h"
  #include "mp/mp_13_0_6_sh_mask.h"
@@@ -1438,7 -1439,10 +1439,10 @@@ static int smu_v13_0_6_irq_process(stru
                                                        entry->src_data[1]);
                                        schedule_work(&smu->throttling_logging_work);
                                }
+                               break;
+                       default:
+                               dev_dbg(adev->dev, "Unhandled context id %d from client:%d!\n",
+                                                                       ctxid, client_id);
                                break;
                        }
                }
@@@ -1938,6 -1942,7 +1942,6 @@@ static int smu_v13_0_6_i2c_control_init
                smu_i2c->port = i;
                mutex_init(&smu_i2c->mutex);
                control->owner = THIS_MODULE;
 -              control->class = I2C_CLASS_SPD;
                control->dev.parent = &adev->pdev->dev;
                control->algo = &smu_v13_0_6_i2c_algo;
                snprintf(control->name, sizeof(control->name), "AMDGPU SMU %d", i);
@@@ -2547,18 -2552,22 +2551,22 @@@ static int mca_umc_mca_get_err_count(co
                                     enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count)
  {
        uint64_t status0;
+       uint32_t ext_error_code;
+       uint32_t odecc_err_cnt;
  
        status0 = entry->regs[MCA_REG_IDX_STATUS];
+       ext_error_code = MCA_REG__STATUS__ERRORCODEEXT(status0);
+       odecc_err_cnt = MCA_REG__MISC0__ERRCNT(entry->regs[MCA_REG_IDX_MISC0]);
  
        if (!REG_GET_FIELD(status0, MCMP1_STATUST0, Val)) {
                *count = 0;
                return 0;
        }
  
-       if (type == AMDGPU_MCA_ERROR_TYPE_UE && umc_v12_0_is_uncorrectable_error(adev, status0))
-               *count = 1;
-       else if (type == AMDGPU_MCA_ERROR_TYPE_CE && umc_v12_0_is_correctable_error(adev, status0))
-               *count = 1;
+       if (umc_v12_0_is_deferred_error(adev, status0) ||
+           umc_v12_0_is_uncorrectable_error(adev, status0) ||
+           umc_v12_0_is_correctable_error(adev, status0))
+               *count = (ext_error_code == 0) ? odecc_err_cnt : 1;
  
        return 0;
  }
@@@ -2857,6 -2866,143 +2865,143 @@@ static const struct amdgpu_mca_smu_func
        .mca_get_valid_mca_count = mca_smu_get_valid_mca_count,
  };
  
+ static int aca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable)
+ {
+       struct smu_context *smu = adev->powerplay.pp_handle;
+       return smu_v13_0_6_mca_set_debug_mode(smu, enable);
+ }
+ static int smu_v13_0_6_get_valid_aca_count(struct smu_context *smu, enum aca_error_type type, u32 *count)
+ {
+       uint32_t msg;
+       int ret;
+       if (!count)
+               return -EINVAL;
+       switch (type) {
+       case ACA_ERROR_TYPE_UE:
+               msg = SMU_MSG_QueryValidMcaCount;
+               break;
+       case ACA_ERROR_TYPE_CE:
+               msg = SMU_MSG_QueryValidMcaCeCount;
+               break;
+       default:
+               return -EINVAL;
+       }
+       ret = smu_cmn_send_smc_msg(smu, msg, count);
+       if (ret) {
+               *count = 0;
+               return ret;
+       }
+       return 0;
+ }
+ static int aca_smu_get_valid_aca_count(struct amdgpu_device *adev,
+                                      enum aca_error_type type, u32 *count)
+ {
+       struct smu_context *smu = adev->powerplay.pp_handle;
+       int ret;
+       switch (type) {
+       case ACA_ERROR_TYPE_UE:
+       case ACA_ERROR_TYPE_CE:
+               ret = smu_v13_0_6_get_valid_aca_count(smu, type, count);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+ }
+ static int __smu_v13_0_6_aca_bank_dump(struct smu_context *smu, enum aca_error_type type,
+                                      int idx, int offset, u32 *val)
+ {
+       uint32_t msg, param;
+       switch (type) {
+       case ACA_ERROR_TYPE_UE:
+               msg = SMU_MSG_McaBankDumpDW;
+               break;
+       case ACA_ERROR_TYPE_CE:
+               msg = SMU_MSG_McaBankCeDumpDW;
+               break;
+       default:
+               return -EINVAL;
+       }
+       param = ((idx & 0xffff) << 16) | (offset & 0xfffc);
+       return smu_cmn_send_smc_msg_with_param(smu, msg, param, (uint32_t *)val);
+ }
+ static int smu_v13_0_6_aca_bank_dump(struct smu_context *smu, enum aca_error_type type,
+                                    int idx, int offset, u32 *val, int count)
+ {
+       int ret, i;
+       if (!val)
+               return -EINVAL;
+       for (i = 0; i < count; i++) {
+               ret = __smu_v13_0_6_aca_bank_dump(smu, type, idx, offset + (i << 2), &val[i]);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+ }
+ static int aca_bank_read_reg(struct amdgpu_device *adev, enum aca_error_type type,
+                            int idx, int reg_idx, u64 *val)
+ {
+       struct smu_context *smu = adev->powerplay.pp_handle;
+       u32 data[2] = {0, 0};
+       int ret;
+       if (!val || reg_idx >= ACA_REG_IDX_COUNT)
+               return -EINVAL;
+       ret = smu_v13_0_6_aca_bank_dump(smu, type, idx, reg_idx * 8, data, ARRAY_SIZE(data));
+       if (ret)
+               return ret;
+       *val = (u64)data[1] << 32 | data[0];
+       dev_dbg(adev->dev, "mca read bank reg: type:%s, index: %d, reg_idx: %d, val: 0x%016llx\n",
+               type == ACA_ERROR_TYPE_UE ? "UE" : "CE", idx, reg_idx, *val);
+       return 0;
+ }
+ static int aca_smu_get_valid_aca_bank(struct amdgpu_device *adev,
+                                     enum aca_error_type type, int idx, struct aca_bank *bank)
+ {
+       int i, ret, count;
+       count = min_t(int, 16, ARRAY_SIZE(bank->regs));
+       for (i = 0; i < count; i++) {
+               ret = aca_bank_read_reg(adev, type, idx, i, &bank->regs[i]);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+ }
+ static const struct aca_smu_funcs smu_v13_0_6_aca_smu_funcs = {
+       .max_ue_bank_count = 12,
+       .max_ce_bank_count = 12,
+       .set_debug_mode = aca_smu_set_debug_mode,
+       .get_valid_aca_count = aca_smu_get_valid_aca_count,
+       .get_valid_aca_bank = aca_smu_get_valid_aca_bank,
+ };
  static int smu_v13_0_6_select_xgmi_plpd_policy(struct smu_context *smu,
                                               enum pp_xgmi_plpd_mode mode)
  {
        return ret;
  }
  
- static ssize_t smu_v13_0_6_get_ecc_info(struct smu_context *smu,
-                       void *table)
- {
-       /* Support ecc info by default */
-       return 0;
- }
  static const struct pptable_funcs smu_v13_0_6_ppt_funcs = {
        /* init dpm */
        .get_allowed_feature_mask = smu_v13_0_6_get_allowed_feature_mask,
        .i2c_init = smu_v13_0_6_i2c_control_init,
        .i2c_fini = smu_v13_0_6_i2c_control_fini,
        .send_hbm_bad_pages_num = smu_v13_0_6_smu_send_hbm_bad_page_num,
-       .get_ecc_info = smu_v13_0_6_get_ecc_info,
  };
  
  void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu)
        smu->smc_driver_if_version = SMU13_0_6_DRIVER_IF_VERSION;
        smu_v13_0_set_smu_mailbox_registers(smu);
        amdgpu_mca_smu_init_funcs(smu->adev, &smu_v13_0_6_mca_smu_funcs);
+       amdgpu_aca_set_smu_funcs(smu->adev, &smu_v13_0_6_aca_smu_funcs);
  }