^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Rockchip PCIe Apis For WIFI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/aspm_ext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static u32 rockchip_pcie_pcie_access_cap(struct pci_dev *pdev, int cap, uint offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) bool is_ext, bool is_write, u32 writeval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) int cap_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) u32 ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) u32 readval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (!(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) pci_err(pdev, "%s: pdev is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* Find Capability offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (is_ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* removing max EXT_CAP_ID check as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * linux kernel definition's max value is not updated yet as per spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) cap_ptr = pci_find_ext_capability(pdev, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* removing max PCI_CAP_ID_MAX check as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * previous kernel versions dont have this definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) cap_ptr = pci_find_capability(pdev, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Return if capability with given ID not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (cap_ptr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) pci_err(pdev, "%s: PCI Cap(0x%02x) not supported.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __func__, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) pci_write_config_dword(pdev, (cap_ptr + offset), writeval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) pci_read_config_dword(pdev, (cap_ptr + offset), &readval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ret = readval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static bool rockchip_pcie_bus_aspm_enable_dev(char *device, struct pci_dev *dev, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 linkctrl_before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 linkctrl_after = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u8 linkctrl_asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) linkctrl_before = rockchip_pcie_pcie_access_cap(dev, PCI_CAP_ID_EXP, PCI_EXP_LNKCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) false, false, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) linkctrl_asm = (linkctrl_before & PCI_EXP_LNKCTL_ASPMC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (linkctrl_asm == PCI_EXP_LNKCTL_ASPM_L1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) pci_err(dev, "%s: %s already enabled linkctrl: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) __func__, device, linkctrl_before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Enable only L1 ASPM (bit 1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) rockchip_pcie_pcie_access_cap(dev, PCI_CAP_ID_EXP, PCI_EXP_LNKCTL, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) true, (linkctrl_before | PCI_EXP_LNKCTL_ASPM_L1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (linkctrl_asm == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pci_err(dev, "%s: %s already disabled linkctrl: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __func__, device, linkctrl_before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* Disable complete ASPM (bit 1 and bit 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) rockchip_pcie_pcie_access_cap(dev, PCI_CAP_ID_EXP, PCI_EXP_LNKCTL, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) true, (linkctrl_before & (~PCI_EXP_LNKCTL_ASPMC)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) linkctrl_after = rockchip_pcie_pcie_access_cap(dev, PCI_CAP_ID_EXP, PCI_EXP_LNKCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) false, false, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) pci_err(dev, "%s: %s %s, linkctrl_before: 0x%x linkctrl_after: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) __func__, device, (enable ? "ENABLE " : "DISABLE"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) linkctrl_before, linkctrl_after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static bool rockchip_pcie_bus_aspm_enable_rc_ep(struct pci_dev *child, struct pci_dev *parent, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Enable only L1 ASPM first RC then EP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ret = rockchip_pcie_bus_aspm_enable_dev("RC", parent, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ret = rockchip_pcie_bus_aspm_enable_dev("EP", child, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Disable complete ASPM first EP then RC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ret = rockchip_pcie_bus_aspm_enable_dev("EP", child, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ret = rockchip_pcie_bus_aspm_enable_dev("RC", parent, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u32 clear, u32 set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pci_read_config_dword(pdev, pos, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) val &= ~clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) val |= set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pci_write_config_dword(pdev, pos, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Convert L1SS T_pwr encoding to usec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static u32 calc_l1ss_pwron(struct pci_dev *pdev, u32 scale, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) switch (scale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return val * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return val * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return val * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 threshold_ns = threshold_us * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* See PCIe r3.1, sec 7.33.3 and sec 6.18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (threshold_ns < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *scale = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *value = threshold_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) } else if (threshold_ns < 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *scale = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *value = threshold_ns >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } else if (threshold_ns < 32768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *scale = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *value = threshold_ns >> 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) } else if (threshold_ns < 1048576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *scale = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *value = threshold_ns >> 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) } else if (threshold_ns < 33554432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *scale = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *value = threshold_ns >> 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *scale = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *value = threshold_ns >> 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Calculate L1.2 PM substate timing parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static void aspm_calc_l1ss_info(struct pci_dev *child, struct pci_dev *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 val1, val2, scale1, scale2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u32 t_common_mode, t_power_on, l1_2_threshold, scale, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u32 ctl1 = 0, ctl2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u32 pctl1, pctl2, cctl1, cctl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 pl1_2_enables, cl1_2_enables;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u32 parent_l1ss_cap, child_l1ss_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Setup L1 substate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) &parent_l1ss_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) &child_l1ss_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Choose the greater of the two Port Common_Mode_Restore_Times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) val1 = (parent_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) val2 = (child_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) t_common_mode = max(val1, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Choose the greater of the two Port T_POWER_ON times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) val1 = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) scale1 = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) val2 = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) scale2 = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (calc_l1ss_pwron(parent, scale1, val1) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) calc_l1ss_pwron(child, scale2, val2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ctl2 |= scale1 | (val1 << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) t_power_on = calc_l1ss_pwron(parent, scale1, val1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ctl2 |= scale2 | (val2 << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) t_power_on = calc_l1ss_pwron(child, scale2, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Set LTR_L1.2_THRESHOLD to the time required to transition the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Link from L0 to L1.2 and back to L0 so we enter L1.2 only if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * downstream devices report (via LTR) that they can tolerate at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * least that much latency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * Based on PCIe r3.1, sec 5.5.3.3.1, Figures 5-16 and 5-17, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Table 5-11. T(POWER_OFF) is at most 2us and T(L1.2) is at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * least 4us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) l1_2_threshold = 2 + 4 + t_common_mode + t_power_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) encode_l12_threshold(l1_2_threshold, &scale, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ctl1 |= t_common_mode << 8 | scale << 29 | value << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, &pctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2, &pctl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1, &cctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL2, &cctl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (ctl1 == pctl1 && ctl1 == cctl1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ctl2 == pctl2 && ctl2 == cctl2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* Disable L1.2 while updating. See PCIe r5.0, sec 5.5.4, 7.8.3.3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pl1_2_enables = pctl1 & PCI_L1SS_CTL1_L1_2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cl1_2_enables = cctl1 & PCI_L1SS_CTL1_L1_2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (pl1_2_enables || cl1_2_enables) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) PCI_L1SS_CTL1_L1_2_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) PCI_L1SS_CTL1_L1_2_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Program T_POWER_ON times in both ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) pci_write_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2, ctl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) pci_write_config_dword(child, child->l1ss + PCI_L1SS_CTL2, ctl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* Program Common_Mode_Restore_Time in upstream device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) PCI_L1SS_CTL1_CM_RESTORE_TIME, ctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* Program LTR_L1.2_THRESHOLD time in both ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) PCI_L1SS_CTL1_LTR_L12_TH_SCALE, ctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) PCI_L1SS_CTL1_LTR_L12_TH_SCALE, ctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (pl1_2_enables || cl1_2_enables) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) pl1_2_enables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) cl1_2_enables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static void rockchip_pcie_bus_l1ss_enable_dev(char *device, struct pci_dev *dev, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u32 l1ssctrl_before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) u32 l1ssctrl_after = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u8 l1ss_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Extendend Capacility Reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) l1ssctrl_before = rockchip_pcie_pcie_access_cap(dev, PCI_EXT_CAP_ID_L1SS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) PCI_L1SS_CTL1, true, false, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) l1ss_ep = (l1ssctrl_before & PCI_L1SS_CTL1_L1SS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (l1ss_ep == PCI_L1SS_CTL1_L1SS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pci_err(dev, "%s: %s already enabled, l1ssctrl: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) __func__, device, l1ssctrl_before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) rockchip_pcie_pcie_access_cap(dev, PCI_EXT_CAP_ID_L1SS, PCI_L1SS_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) true, true, (l1ssctrl_before | PCI_L1SS_CTL1_L1SS_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (l1ss_ep == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) pci_err(dev, "%s: %s already disabled, l1ssctrl: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) __func__, device, l1ssctrl_before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) rockchip_pcie_pcie_access_cap(dev, PCI_EXT_CAP_ID_L1SS, PCI_L1SS_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) true, true, (l1ssctrl_before & (~PCI_L1SS_CTL1_L1SS_MASK)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) l1ssctrl_after = rockchip_pcie_pcie_access_cap(dev, PCI_EXT_CAP_ID_L1SS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) PCI_L1SS_CTL1, true, false, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pci_err(dev, "%s: %s %s, l1ssctrl_before: 0x%x l1ssctrl_after: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) __func__, device, (enable ? "ENABLE " : "DISABLE"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) l1ssctrl_before, l1ssctrl_after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) bool pcie_aspm_ext_is_rc_ep_l1ss_capable(struct pci_dev *child, struct pci_dev *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 parent_l1ss_cap, child_l1ss_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Setup L1 substate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) &parent_l1ss_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) &child_l1ss_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!(parent_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) parent_l1ss_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!(child_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) child_l1ss_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (parent_l1ss_cap && child_l1ss_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) EXPORT_SYMBOL(pcie_aspm_ext_is_rc_ep_l1ss_capable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) void pcie_aspm_ext_l1ss_enable(struct pci_dev *child, struct pci_dev *parent, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* Disable ASPM of RC and EP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ret = rockchip_pcie_bus_aspm_enable_rc_ep(child, parent, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* LRT enable bits loss after wifi off, enable it after power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (parent->ltr_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) pcie_capability_set_word(parent, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_LTR_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* Enable RC then EP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) aspm_calc_l1ss_info(child, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) rockchip_pcie_bus_l1ss_enable_dev("RC", parent, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) rockchip_pcie_bus_l1ss_enable_dev("EP", child, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* Disable EP then RC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rockchip_pcie_bus_l1ss_enable_dev("EP", child, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) rockchip_pcie_bus_l1ss_enable_dev("RC", parent, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* Enable ASPM of RC and EP only if this API disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rockchip_pcie_bus_aspm_enable_rc_ep(child, parent, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) EXPORT_SYMBOL(pcie_aspm_ext_l1ss_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) MODULE_LICENSE("GPL");