Merge tag 'amd-drm-fixes-5.15-2021-10-06' of https://gitlab.freedesktop.org/agd5f...
authorDave Airlie <airlied@redhat.com>
Fri, 8 Oct 2021 01:40:21 +0000 (11:40 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 8 Oct 2021 01:40:21 +0000 (11:40 +1000)
amd-drm-fixes-5.15-2021-10-06:

amdgpu:
- DCN 3.1 DP alt mode fixes
- S0ix gfxoff fix
- Fix DRM_AMD_DC_SI dependencies
- PCIe DPC handling fix
- DCN 3.1 scaling fix
- Documentation fix

amdkfd:
- Fix potential memory leak
- IOMMUv2 init fixes

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211006203828.4818-1-alexander.deucher@amd.com
14 files changed:
Documentation/gpu/amdgpu.rst
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/display/Kconfig
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
drivers/gpu/drm/amd/display/include/dal_asic_id.h
drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h

index 364680c..8ba72e8 100644 (file)
@@ -300,8 +300,8 @@ pcie_replay_count
 .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
    :doc: pcie_replay_count
 
-+GPU SmartShift Information
-============================
+GPU SmartShift Information
+==========================
 
 GPU SmartShift information via sysfs
 
index d356e32..269437b 100644 (file)
@@ -1087,6 +1087,7 @@ struct amdgpu_device {
 
        bool                            no_hw_access;
        struct pci_saved_state          *pci_state;
+       pci_channel_state_t             pci_channel_state;
 
        struct amdgpu_reset_control     *reset_cntl;
 };
index 2d6b2d7..054c1a2 100644 (file)
@@ -563,6 +563,7 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem *mem,
 
        dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
        sg_free_table(ttm->sg);
+       kfree(ttm->sg);
        ttm->sg = NULL;
 }
 
index ab3794c..af9bdf1 100644 (file)
@@ -2394,10 +2394,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
        if (r)
                goto init_failed;
 
-       r = amdgpu_amdkfd_resume_iommu(adev);
-       if (r)
-               goto init_failed;
-
        r = amdgpu_device_ip_hw_init_phase1(adev);
        if (r)
                goto init_failed;
@@ -2436,6 +2432,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
        if (!adev->gmc.xgmi.pending_reset)
                amdgpu_amdkfd_device_init(adev);
 
+       r = amdgpu_amdkfd_resume_iommu(adev);
+       if (r)
+               goto init_failed;
+
        amdgpu_fru_get_product_info(adev);
 
 init_failed:
@@ -5399,6 +5399,8 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
                return PCI_ERS_RESULT_DISCONNECT;
        }
 
+       adev->pci_channel_state = state;
+
        switch (state) {
        case pci_channel_io_normal:
                return PCI_ERS_RESULT_CAN_RECOVER;
@@ -5541,6 +5543,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
 
        DRM_INFO("PCI error: resume callback!!\n");
 
+       /* Only continue execution for the case of pci_channel_io_frozen */
+       if (adev->pci_channel_state != pci_channel_io_frozen)
+               return;
+
        for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
                struct amdgpu_ring *ring = adev->rings[i];
 
index e7f06bd..1916ec8 100644 (file)
@@ -31,6 +31,8 @@
 /* delay 0.1 second to enable gfx off feature */
 #define GFX_OFF_DELAY_ENABLE         msecs_to_jiffies(100)
 
+#define GFX_OFF_NO_DELAY 0
+
 /*
  * GPU GFX IP block helpers function.
  */
@@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev)
 
 void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
 {
+       unsigned long delay = GFX_OFF_DELAY_ENABLE;
+
        if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
                return;
 
@@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
 
                adev->gfx.gfx_off_req_count--;
 
-               if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state)
-                       schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
+               if (adev->gfx.gfx_off_req_count == 0 &&
+                   !adev->gfx.gfx_off_state) {
+                       /* If going to s2idle, no need to wait */
+                       if (adev->in_s0ix)
+                               delay = GFX_OFF_NO_DELAY;
+                       schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
+                                             delay);
+               }
        } else {
                if (adev->gfx.gfx_off_req_count == 0) {
                        cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);
index c2a4d92..4a41623 100644 (file)
@@ -1085,18 +1085,12 @@ static int kfd_resume(struct kfd_dev *kfd)
        int err = 0;
 
        err = kfd->dqm->ops.start(kfd->dqm);
-       if (err) {
+       if (err)
                dev_err(kfd_device,
                        "Error starting queue manager for device %x:%x\n",
                        kfd->pdev->vendor, kfd->pdev->device);
-               goto dqm_start_error;
-       }
 
        return err;
-
-dqm_start_error:
-       kfd_iommu_suspend(kfd);
-       return err;
 }
 
 static inline void kfd_queue_work(struct workqueue_struct *wq,
index 7dffc04..127667e 100644 (file)
@@ -25,6 +25,8 @@ config DRM_AMD_DC_HDCP
 
 config DRM_AMD_DC_SI
        bool "AMD DC support for Southern Islands ASICs"
+       depends on DRM_AMDGPU_SI
+       depends on DRM_AMD_DC
        default n
        help
          Choose this option to enable new AMD DC support for SI asics
index 05eaec0..6d655e1 100644 (file)
@@ -1306,12 +1306,6 @@ static void override_training_settings(
 {
        uint32_t lane;
 
-       /* Override link settings */
-       if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
-               lt_settings->link_settings.link_rate = link->preferred_link_setting.link_rate;
-       if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN)
-               lt_settings->link_settings.lane_count = link->preferred_link_setting.lane_count;
-
        /* Override link spread */
        if (!link->dp_ss_off && overrides->downspread != NULL)
                lt_settings->link_settings.link_spread = *overrides->downspread ?
index d8b2261..c337588 100644 (file)
@@ -118,6 +118,7 @@ struct dcn10_link_enc_registers {
        uint32_t RDPCSTX_PHY_CNTL4;
        uint32_t RDPCSTX_PHY_CNTL5;
        uint32_t RDPCSTX_PHY_CNTL6;
+       uint32_t RDPCSPIPE_PHY_CNTL6;
        uint32_t RDPCSTX_PHY_CNTL7;
        uint32_t RDPCSTX_PHY_CNTL8;
        uint32_t RDPCSTX_PHY_CNTL9;
index 90127c1..b089244 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "link_enc_cfg.h"
 #include "dc_dmub_srv.h"
+#include "dal_asic_id.h"
 
 #define CTX \
        enc10->base.ctx
 #define AUX_REG_WRITE(reg_name, val) \
                        dm_write_reg(CTX, AUX_REG(reg_name), val)
 
+#ifndef MIN
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#endif
+
 void dcn31_link_encoder_set_dio_phy_mux(
        struct link_encoder *enc,
        enum encoder_type_select sel,
@@ -215,8 +220,8 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs = {
        .fec_is_active = enc2_fec_is_active,
        .get_dig_frontend = dcn10_get_dig_frontend,
        .get_dig_mode = dcn10_get_dig_mode,
-       .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
-       .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
+       .is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
+       .get_max_link_cap = dcn31_link_encoder_get_max_link_cap,
        .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
 };
 
@@ -404,3 +409,60 @@ void dcn31_link_encoder_disable_output(
        }
 }
 
+bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+       uint32_t dp_alt_mode_disable;
+       bool is_usb_c_alt_mode = false;
+
+       if (enc->features.flags.bits.DP_IS_USB_C) {
+               if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
+                       // [Note] no need to check hw_internal_rev once phy mux selection is ready
+                       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+               } else {
+               /*
+                * B0 phys use a new set of registers to check whether alt mode is disabled.
+                * if value == 1 alt mode is disabled, otherwise it is enabled.
+                */
+                       if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
+                               REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+                       } else {
+                       // [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready
+                               REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+                       }
+               }
+
+               is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
+       }
+
+       return is_usb_c_alt_mode;
+}
+
+void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
+                                                                                struct dc_link_settings *link_settings)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+       uint32_t is_in_usb_c_dp4_mode = 0;
+
+       dcn10_link_encoder_get_max_link_cap(enc, link_settings);
+
+       /* in usb c dp2 mode, max lane count is 2 */
+       if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
+               if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
+                       // [Note] no need to check hw_internal_rev once phy mux selection is ready
+                       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+               } else {
+                       if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
+                               REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+                       } else {
+                               REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+                       }
+               }
+               if (!is_in_usb_c_dp4_mode)
+                       link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
+       }
+}
index 32d1463..3454f1e 100644 (file)
@@ -69,6 +69,7 @@
        SRI(RDPCSTX_PHY_CNTL4, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL5, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL6, RDPCSTX, id), \
+       SRI(RDPCSPIPE_PHY_CNTL6, RDPCSPIPE, id), \
        SRI(RDPCSTX_PHY_CNTL7, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL8, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL9, RDPCSTX, id), \
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_MPLL_EN, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_MPLL_EN, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
-       LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
+       LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
+       LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
+       LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_QUOT, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_DEN, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL8, RDPCS_PHY_DP_MPLLB_SSC_PEAK, mask_sh),\
@@ -243,4 +246,13 @@ void dcn31_link_encoder_disable_output(
        struct link_encoder *enc,
        enum signal_type signal);
 
+/*
+ * Check whether USB-C DP Alt mode is disabled
+ */
+bool dcn31_link_encoder_is_in_alt_mode(
+       struct link_encoder *enc);
+
+void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings);
+
 #endif /* __DC_LINK_ENCODER__DCN31_H__ */
index a7702d3..0006bba 100644 (file)
@@ -928,7 +928,7 @@ static const struct dc_debug_options debug_defaults_drv = {
        .disable_dcc = DCC_ENABLE,
        .vsr_support = true,
        .performance_trace = false,
-       .max_downscale_src_width = 7680,/*upto 8K*/
+       .max_downscale_src_width = 3840,/*upto 4K*/
        .disable_pplib_wm_range = false,
        .scl_reset_length10 = true,
        .sanity_checks = false,
@@ -1284,6 +1284,12 @@ static struct stream_encoder *dcn31_stream_encoder_create(
        if (!enc1 || !vpg || !afmt)
                return NULL;
 
+       if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
+                       ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+               if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD))
+                       eng_id = eng_id + 3; // For B0 only. C->F, D->G.
+       }
+
        dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
                                        eng_id, vpg, afmt,
                                        &stream_enc_regs[eng_id],
index 381c17c..5adc471 100644 (file)
@@ -227,7 +227,7 @@ enum {
 #define FAMILY_YELLOW_CARP                     146
 
 #define YELLOW_CARP_A0 0x01
-#define YELLOW_CARP_B0 0x02            // TODO: DCN31 - update with correct B0 ID
+#define YELLOW_CARP_B0 0x1A
 #define YELLOW_CARP_UNKNOWN 0xFF
 
 #ifndef ASICREV_IS_YELLOW_CARP
index 92caf84..01a5655 100644 (file)
 #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_RX_OVRD_OUT_2                                                0xe0c7
 #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_TX_OVRD_IN_2                                                 0xe0c8
 
+//RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT                                            0x10
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT                                        0x11
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT                                    0x12
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK                                              0x00010000L
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK                                          0x00020000L
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK                                      0x00040000L
+
+//RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT                                            0x10
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT                                        0x11
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT                                    0x12
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK                                              0x00010000L
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK                                          0x00020000L
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK                                      0x00040000L
+
+//[Note] Hack. RDPCSPIPE only has 2 instances.
+#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6                                                              0x2e4b
+#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6                                                              0x2e4b
+#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
 
 #endif