Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/cik: add support for pcie gen1/2/3 switching

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+218
+161
drivers/gpu/drm/radeon/cik.c
··· 61 61 extern void si_rlc_fini(struct radeon_device *rdev); 62 62 extern int si_rlc_init(struct radeon_device *rdev); 63 63 static void cik_rlc_stop(struct radeon_device *rdev); 64 + static void cik_pcie_gen3_enable(struct radeon_device *rdev); 64 65 65 66 /* 66 67 * Indirect registers accessor ··· 5950 5949 struct radeon_ring *ring; 5951 5950 int r; 5952 5951 5952 + /* enable pcie gen2/3 link */ 5953 + cik_pcie_gen3_enable(rdev); 5954 + 5953 5955 cik_mc_program(rdev); 5954 5956 5955 5957 if (rdev->flags & RADEON_IS_IGP) { ··· 7054 7050 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); 7055 7051 7056 7052 return 0; 7053 + } 7054 + 7055 + static void cik_pcie_gen3_enable(struct radeon_device *rdev) 7056 + { 7057 + struct pci_dev *root = rdev->pdev->bus->self; 7058 + int bridge_pos, gpu_pos; 7059 + u32 speed_cntl, mask, current_data_rate; 7060 + int ret, i; 7061 + u16 tmp16; 7062 + 7063 + if (radeon_pcie_gen2 == 0) 7064 + return; 7065 + 7066 + if (rdev->flags & RADEON_IS_IGP) 7067 + return; 7068 + 7069 + if (!(rdev->flags & RADEON_IS_PCIE)) 7070 + return; 7071 + 7072 + ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); 7073 + if (ret != 0) 7074 + return; 7075 + 7076 + if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) 7077 + return; 7078 + 7079 + speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 7080 + current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> 7081 + LC_CURRENT_DATA_RATE_SHIFT; 7082 + if (mask & DRM_PCIE_SPEED_80) { 7083 + if (current_data_rate == 2) { 7084 + DRM_INFO("PCIE gen 3 link speeds already enabled\n"); 7085 + return; 7086 + } 7087 + DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n"); 7088 + } else if (mask & DRM_PCIE_SPEED_50) { 7089 + if (current_data_rate == 1) { 7090 + DRM_INFO("PCIE gen 2 link speeds already enabled\n"); 7091 + return; 7092 + } 7093 + DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); 7094 + } 7095 + 7096 + bridge_pos = pci_pcie_cap(root); 7097 + if (!bridge_pos) 7098 + return; 7099 + 7100 + gpu_pos = pci_pcie_cap(rdev->pdev); 7101 + if (!gpu_pos) 7102 + return; 7103 + 7104 + if (mask & DRM_PCIE_SPEED_80) { 7105 + /* re-try equalization if gen3 is not already enabled */ 7106 + if (current_data_rate != 2) { 7107 + u16 bridge_cfg, gpu_cfg; 7108 + u16 bridge_cfg2, gpu_cfg2; 7109 + u32 max_lw, current_lw, tmp; 7110 + 7111 + pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); 7112 + pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); 7113 + 7114 + tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; 7115 + pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); 7116 + 7117 + tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; 7118 + pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); 7119 + 7120 + tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1); 7121 + max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; 7122 + current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT; 7123 + 7124 + if (current_lw < max_lw) { 7125 + tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 7126 + if (tmp & LC_RENEGOTIATION_SUPPORT) { 7127 + tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS); 7128 + tmp |= (max_lw << LC_LINK_WIDTH_SHIFT); 7129 + tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW; 7130 + WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp); 7131 + } 7132 + } 7133 + 7134 + for (i = 0; i < 10; i++) { 7135 + /* check status */ 7136 + pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16); 7137 + if (tmp16 & PCI_EXP_DEVSTA_TRPND) 7138 + break; 7139 + 7140 + pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); 7141 + pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); 7142 + 7143 + pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2); 7144 + pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2); 7145 + 7146 + tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 7147 + tmp |= LC_SET_QUIESCE; 7148 + WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 7149 + 7150 + tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 7151 + tmp |= LC_REDO_EQ; 7152 + WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 7153 + 7154 + mdelay(100); 7155 + 7156 + /* linkctl */ 7157 + pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16); 7158 + tmp16 &= ~PCI_EXP_LNKCTL_HAWD; 7159 + tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); 7160 + pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); 7161 + 7162 + pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16); 7163 + tmp16 &= ~PCI_EXP_LNKCTL_HAWD; 7164 + tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); 7165 + pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); 7166 + 7167 + /* linkctl2 */ 7168 + pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16); 7169 + tmp16 &= ~((1 << 4) | (7 << 9)); 7170 + tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9))); 7171 + pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16); 7172 + 7173 + pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); 7174 + tmp16 &= ~((1 << 4) | (7 << 9)); 7175 + tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9))); 7176 + pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); 7177 + 7178 + tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 7179 + tmp &= ~LC_SET_QUIESCE; 7180 + WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 7181 + } 7182 + } 7183 + } 7184 + 7185 + /* set the link speed */ 7186 + speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE; 7187 + speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; 7188 + WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 7189 + 7190 + pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); 7191 + tmp16 &= ~0xf; 7192 + if (mask & DRM_PCIE_SPEED_80) 7193 + tmp16 |= 3; /* gen3 */ 7194 + else if (mask & DRM_PCIE_SPEED_50) 7195 + tmp16 |= 2; /* gen2 */ 7196 + else 7197 + tmp16 |= 1; /* gen1 */ 7198 + pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); 7199 + 7200 + speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 7201 + speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; 7202 + WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 7203 + 7204 + for (i = 0; i < rdev->usec_timeout; i++) { 7205 + speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 7206 + if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0) 7207 + break; 7208 + udelay(1); 7209 + } 7057 7210 }
+57
drivers/gpu/drm/radeon/cikd.h
··· 35 35 #define CG_CLKPIN_CNTL 0xC05001A0 36 36 # define XTALIN_DIVIDE (1 << 1) 37 37 38 + /* PCIE registers idx/data 0x38/0x3c */ 39 + #define PCIE_LC_STATUS1 0x1400028 /* PCIE */ 40 + # define LC_REVERSE_RCVR (1 << 0) 41 + # define LC_REVERSE_XMIT (1 << 1) 42 + # define LC_OPERATING_LINK_WIDTH_MASK (0x7 << 2) 43 + # define LC_OPERATING_LINK_WIDTH_SHIFT 2 44 + # define LC_DETECTED_LINK_WIDTH_MASK (0x7 << 5) 45 + # define LC_DETECTED_LINK_WIDTH_SHIFT 5 46 + 47 + #define PCIE_LC_LINK_WIDTH_CNTL 0x100100A2 /* PCIE */ 48 + # define LC_LINK_WIDTH_SHIFT 0 49 + # define LC_LINK_WIDTH_MASK 0x7 50 + # define LC_LINK_WIDTH_X0 0 51 + # define LC_LINK_WIDTH_X1 1 52 + # define LC_LINK_WIDTH_X2 2 53 + # define LC_LINK_WIDTH_X4 3 54 + # define LC_LINK_WIDTH_X8 4 55 + # define LC_LINK_WIDTH_X16 6 56 + # define LC_LINK_WIDTH_RD_SHIFT 4 57 + # define LC_LINK_WIDTH_RD_MASK 0x70 58 + # define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) 59 + # define LC_RECONFIG_NOW (1 << 8) 60 + # define LC_RENEGOTIATION_SUPPORT (1 << 9) 61 + # define LC_RENEGOTIATE_EN (1 << 10) 62 + # define LC_SHORT_RECONFIG_EN (1 << 11) 63 + # define LC_UPCONFIGURE_SUPPORT (1 << 12) 64 + # define LC_UPCONFIGURE_DIS (1 << 13) 65 + # define LC_DYN_LANES_PWR_STATE(x) ((x) << 21) 66 + # define LC_DYN_LANES_PWR_STATE_MASK (0x3 << 21) 67 + # define LC_DYN_LANES_PWR_STATE_SHIFT 21 68 + 69 + #define PCIE_LC_SPEED_CNTL 0x100100A4 /* PCIE */ 70 + # define LC_GEN2_EN_STRAP (1 << 0) 71 + # define LC_GEN3_EN_STRAP (1 << 1) 72 + # define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 2) 73 + # define LC_TARGET_LINK_SPEED_OVERRIDE_MASK (0x3 << 3) 74 + # define LC_TARGET_LINK_SPEED_OVERRIDE_SHIFT 3 75 + # define LC_FORCE_EN_SW_SPEED_CHANGE (1 << 5) 76 + # define LC_FORCE_DIS_SW_SPEED_CHANGE (1 << 6) 77 + # define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 7) 78 + # define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 8) 79 + # define LC_INITIATE_LINK_SPEED_CHANGE (1 << 9) 80 + # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 10) 81 + # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 10 82 + # define LC_CURRENT_DATA_RATE_MASK (0x3 << 13) /* 0/1/2 = gen1/2/3 */ 83 + # define LC_CURRENT_DATA_RATE_SHIFT 13 84 + # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 16) 85 + # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 18) 86 + # define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 19) 87 + # define LC_OTHER_SIDE_EVER_SENT_GEN3 (1 << 20) 88 + # define LC_OTHER_SIDE_SUPPORTS_GEN3 (1 << 21) 89 + 90 + #define PCIE_LC_CNTL4 0x100100B6 /* PCIE */ 91 + # define LC_REDO_EQ (1 << 5) 92 + # define LC_SET_QUIESCE (1 << 13) 93 + 94 + /* direct registers */ 38 95 #define PCIE_INDEX 0x38 39 96 #define PCIE_DATA 0x3C 40 97