Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");