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

drm/radeon: add support for ASPM on CIK asics

Enables PCIE ASPM (Active State Power Management) on
CIK asics.

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

+222 -1
+151
drivers/gpu/drm/radeon/cik.c
··· 62 62 extern int si_rlc_init(struct radeon_device *rdev); 63 63 static void cik_rlc_stop(struct radeon_device *rdev); 64 64 static void cik_pcie_gen3_enable(struct radeon_device *rdev); 65 + static void cik_program_aspm(struct radeon_device *rdev); 65 66 66 67 /* 67 68 * Indirect registers accessor ··· 5953 5952 5954 5953 /* enable pcie gen2/3 link */ 5955 5954 cik_pcie_gen3_enable(rdev); 5955 + /* enable aspm */ 5956 + cik_program_aspm(rdev); 5956 5957 5957 5958 cik_mc_program(rdev); 5958 5959 ··· 7213 7210 if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0) 7214 7211 break; 7215 7212 udelay(1); 7213 + } 7214 + } 7215 + 7216 + static void cik_program_aspm(struct radeon_device *rdev) 7217 + { 7218 + u32 data, orig; 7219 + bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false; 7220 + bool disable_clkreq = false; 7221 + 7222 + if (radeon_aspm == 0) 7223 + return; 7224 + 7225 + /* XXX double check IGPs */ 7226 + if (rdev->flags & RADEON_IS_IGP) 7227 + return; 7228 + 7229 + if (!(rdev->flags & RADEON_IS_PCIE)) 7230 + return; 7231 + 7232 + orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL); 7233 + data &= ~LC_XMIT_N_FTS_MASK; 7234 + data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN; 7235 + if (orig != data) 7236 + WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data); 7237 + 7238 + orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3); 7239 + data |= LC_GO_TO_RECOVERY; 7240 + if (orig != data) 7241 + WREG32_PCIE_PORT(PCIE_LC_CNTL3, data); 7242 + 7243 + orig = data = RREG32_PCIE_PORT(PCIE_P_CNTL); 7244 + data |= P_IGNORE_EDB_ERR; 7245 + if (orig != data) 7246 + WREG32_PCIE_PORT(PCIE_P_CNTL, data); 7247 + 7248 + orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL); 7249 + data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK); 7250 + data |= LC_PMI_TO_L1_DIS; 7251 + if (!disable_l0s) 7252 + data |= LC_L0S_INACTIVITY(7); 7253 + 7254 + if (!disable_l1) { 7255 + data |= LC_L1_INACTIVITY(7); 7256 + data &= ~LC_PMI_TO_L1_DIS; 7257 + if (orig != data) 7258 + WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 7259 + 7260 + if (!disable_plloff_in_l1) { 7261 + bool clk_req_support; 7262 + 7263 + orig = data = RREG32_PCIE_PORT(PB0_PIF_PWRDOWN_0); 7264 + data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 7265 + data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 7266 + if (orig != data) 7267 + WREG32_PCIE_PORT(PB0_PIF_PWRDOWN_0, data); 7268 + 7269 + orig = data = RREG32_PCIE_PORT(PB0_PIF_PWRDOWN_1); 7270 + data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 7271 + data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 7272 + if (orig != data) 7273 + WREG32_PCIE_PORT(PB0_PIF_PWRDOWN_1, data); 7274 + 7275 + orig = data = RREG32_PCIE_PORT(PB1_PIF_PWRDOWN_0); 7276 + data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 7277 + data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 7278 + if (orig != data) 7279 + WREG32_PCIE_PORT(PB1_PIF_PWRDOWN_0, data); 7280 + 7281 + orig = data = RREG32_PCIE_PORT(PB1_PIF_PWRDOWN_1); 7282 + data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 7283 + data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 7284 + if (orig != data) 7285 + WREG32_PCIE_PORT(PB1_PIF_PWRDOWN_1, data); 7286 + 7287 + orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 7288 + data &= ~LC_DYN_LANES_PWR_STATE_MASK; 7289 + data |= LC_DYN_LANES_PWR_STATE(3); 7290 + if (orig != data) 7291 + WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data); 7292 + 7293 + if (!disable_clkreq) { 7294 + struct pci_dev *root = rdev->pdev->bus->self; 7295 + u32 lnkcap; 7296 + 7297 + clk_req_support = false; 7298 + pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap); 7299 + if (lnkcap & PCI_EXP_LNKCAP_CLKPM) 7300 + clk_req_support = true; 7301 + } else { 7302 + clk_req_support = false; 7303 + } 7304 + 7305 + if (clk_req_support) { 7306 + orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2); 7307 + data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23; 7308 + if (orig != data) 7309 + WREG32_PCIE_PORT(PCIE_LC_CNTL2, data); 7310 + 7311 + orig = data = RREG32_SMC(THM_CLK_CNTL); 7312 + data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK); 7313 + data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1); 7314 + if (orig != data) 7315 + WREG32_SMC(THM_CLK_CNTL, data); 7316 + 7317 + orig = data = RREG32_SMC(MISC_CLK_CTRL); 7318 + data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK); 7319 + data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1); 7320 + if (orig != data) 7321 + WREG32_SMC(MISC_CLK_CTRL, data); 7322 + 7323 + orig = data = RREG32_SMC(CG_CLKPIN_CNTL); 7324 + data &= ~BCLK_AS_XCLK; 7325 + if (orig != data) 7326 + WREG32_SMC(CG_CLKPIN_CNTL, data); 7327 + 7328 + orig = data = RREG32_SMC(CG_CLKPIN_CNTL_2); 7329 + data &= ~FORCE_BIF_REFCLK_EN; 7330 + if (orig != data) 7331 + WREG32_SMC(CG_CLKPIN_CNTL_2, data); 7332 + 7333 + orig = data = RREG32_SMC(MPLL_BYPASSCLK_SEL); 7334 + data &= ~MPLL_CLKOUT_SEL_MASK; 7335 + data |= MPLL_CLKOUT_SEL(4); 7336 + if (orig != data) 7337 + WREG32_SMC(MPLL_BYPASSCLK_SEL, data); 7338 + } 7339 + } 7340 + } else { 7341 + if (orig != data) 7342 + WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 7343 + } 7344 + 7345 + orig = data = RREG32_PCIE_PORT(PCIE_CNTL2); 7346 + data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN; 7347 + if (orig != data) 7348 + WREG32_PCIE_PORT(PCIE_CNTL2, data); 7349 + 7350 + if (!disable_l0s) { 7351 + data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL); 7352 + if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) { 7353 + data = RREG32_PCIE_PORT(PCIE_LC_STATUS1); 7354 + if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) { 7355 + orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL); 7356 + data &= ~LC_L0S_INACTIVITY_MASK; 7357 + if (orig != data) 7358 + WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 7359 + } 7360 + } 7216 7361 } 7217 7362 }
+71 -1
drivers/gpu/drm/radeon/cikd.h
··· 32 32 #define GENERAL_PWRMGT 0xC0200000 33 33 # define GPU_COUNTER_CLK (1 << 15) 34 34 35 + #define MPLL_BYPASSCLK_SEL 0xC050019C 36 + # define MPLL_CLKOUT_SEL(x) ((x) << 8) 37 + # define MPLL_CLKOUT_SEL_MASK 0xFF00 35 38 #define CG_CLKPIN_CNTL 0xC05001A0 36 39 # define XTALIN_DIVIDE (1 << 1) 40 + # define BCLK_AS_XCLK (1 << 2) 41 + #define CG_CLKPIN_CNTL_2 0xC05001A4 42 + # define FORCE_BIF_REFCLK_EN (1 << 3) 43 + # define MUX_TCLK_TO_XCLK (1 << 8) 44 + #define THM_CLK_CNTL 0xC05001A8 45 + # define CMON_CLK_SEL(x) ((x) << 0) 46 + # define CMON_CLK_SEL_MASK 0xFF 47 + # define TMON_CLK_SEL(x) ((x) << 8) 48 + # define TMON_CLK_SEL_MASK 0xFF00 49 + #define MISC_CLK_CTRL 0xC05001AC 50 + # define DEEP_SLEEP_CLK_SEL(x) ((x) << 0) 51 + # define DEEP_SLEEP_CLK_SEL_MASK 0xFF 52 + # define ZCLK_SEL(x) ((x) << 8) 53 + # define ZCLK_SEL_MASK 0xFF00 37 54 38 55 /* PCIE registers idx/data 0x38/0x3c */ 56 + #define PB0_PIF_PWRDOWN_0 0x1100012 /* PCIE */ 57 + # define PLL_POWER_STATE_IN_TXS2_0(x) ((x) << 7) 58 + # define PLL_POWER_STATE_IN_TXS2_0_MASK (0x7 << 7) 59 + # define PLL_POWER_STATE_IN_TXS2_0_SHIFT 7 60 + # define PLL_POWER_STATE_IN_OFF_0(x) ((x) << 10) 61 + # define PLL_POWER_STATE_IN_OFF_0_MASK (0x7 << 10) 62 + # define PLL_POWER_STATE_IN_OFF_0_SHIFT 10 63 + # define PLL_RAMP_UP_TIME_0(x) ((x) << 24) 64 + # define PLL_RAMP_UP_TIME_0_MASK (0x7 << 24) 65 + # define PLL_RAMP_UP_TIME_0_SHIFT 24 66 + #define PB0_PIF_PWRDOWN_1 0x1100013 /* PCIE */ 67 + # define PLL_POWER_STATE_IN_TXS2_1(x) ((x) << 7) 68 + # define PLL_POWER_STATE_IN_TXS2_1_MASK (0x7 << 7) 69 + # define PLL_POWER_STATE_IN_TXS2_1_SHIFT 7 70 + # define PLL_POWER_STATE_IN_OFF_1(x) ((x) << 10) 71 + # define PLL_POWER_STATE_IN_OFF_1_MASK (0x7 << 10) 72 + # define PLL_POWER_STATE_IN_OFF_1_SHIFT 10 73 + # define PLL_RAMP_UP_TIME_1(x) ((x) << 24) 74 + # define PLL_RAMP_UP_TIME_1_MASK (0x7 << 24) 75 + # define PLL_RAMP_UP_TIME_1_SHIFT 24 76 + 77 + #define PCIE_CNTL2 0x1001001c /* PCIE */ 78 + # define SLV_MEM_LS_EN (1 << 16) 79 + # define MST_MEM_LS_EN (1 << 18) 80 + # define REPLAY_MEM_LS_EN (1 << 19) 81 + 39 82 #define PCIE_LC_STATUS1 0x1400028 /* PCIE */ 40 83 # define LC_REVERSE_RCVR (1 << 0) 41 84 # define LC_REVERSE_XMIT (1 << 1) ··· 86 43 # define LC_OPERATING_LINK_WIDTH_SHIFT 2 87 44 # define LC_DETECTED_LINK_WIDTH_MASK (0x7 << 5) 88 45 # define LC_DETECTED_LINK_WIDTH_SHIFT 5 46 + 47 + #define PCIE_P_CNTL 0x1400040 /* PCIE */ 48 + # define P_IGNORE_EDB_ERR (1 << 6) 49 + 50 + #define PB1_PIF_PWRDOWN_0 0x2100012 /* PCIE */ 51 + #define PB1_PIF_PWRDOWN_1 0x2100013 /* PCIE */ 52 + 53 + #define PCIE_LC_CNTL 0x100100A0 /* PCIE */ 54 + # define LC_L0S_INACTIVITY(x) ((x) << 8) 55 + # define LC_L0S_INACTIVITY_MASK (0xf << 8) 56 + # define LC_L0S_INACTIVITY_SHIFT 8 57 + # define LC_L1_INACTIVITY(x) ((x) << 12) 58 + # define LC_L1_INACTIVITY_MASK (0xf << 12) 59 + # define LC_L1_INACTIVITY_SHIFT 12 60 + # define LC_PMI_TO_L1_DIS (1 << 16) 61 + # define LC_ASPM_TO_L1_DIS (1 << 24) 89 62 90 63 #define PCIE_LC_LINK_WIDTH_CNTL 0x100100A2 /* PCIE */ 91 64 # define LC_LINK_WIDTH_SHIFT 0 ··· 124 65 # define LC_DYN_LANES_PWR_STATE(x) ((x) << 21) 125 66 # define LC_DYN_LANES_PWR_STATE_MASK (0x3 << 21) 126 67 # define LC_DYN_LANES_PWR_STATE_SHIFT 21 127 - 68 + #define PCIE_LC_N_FTS_CNTL 0x100100a3 /* PCIE */ 69 + # define LC_XMIT_N_FTS(x) ((x) << 0) 70 + # define LC_XMIT_N_FTS_MASK (0xff << 0) 71 + # define LC_XMIT_N_FTS_SHIFT 0 72 + # define LC_XMIT_N_FTS_OVERRIDE_EN (1 << 8) 73 + # define LC_N_FTS_MASK (0xff << 24) 128 74 #define PCIE_LC_SPEED_CNTL 0x100100A4 /* PCIE */ 129 75 # define LC_GEN2_EN_STRAP (1 << 0) 130 76 # define LC_GEN3_EN_STRAP (1 << 1) ··· 151 87 # define LC_OTHER_SIDE_EVER_SENT_GEN3 (1 << 20) 152 88 # define LC_OTHER_SIDE_SUPPORTS_GEN3 (1 << 21) 153 89 90 + #define PCIE_LC_CNTL2 0x100100B1 /* PCIE */ 91 + # define LC_ALLOW_PDWN_IN_L1 (1 << 17) 92 + # define LC_ALLOW_PDWN_IN_L23 (1 << 18) 93 + 94 + #define PCIE_LC_CNTL3 0x100100B5 /* PCIE */ 95 + # define LC_GO_TO_RECOVERY (1 << 30) 154 96 #define PCIE_LC_CNTL4 0x100100B6 /* PCIE */ 155 97 # define LC_REDO_EQ (1 << 5) 156 98 # define LC_SET_QUIESCE (1 << 13)