|
213 | 213 | #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT 0x0 |
214 | 214 |
|
215 | 215 | /* BCM7712/2712-specific registers */ |
| 216 | + |
| 217 | +#define PCIE_RC_TL_VDM_CTL0 0x0a20 |
| 218 | +#define PCIE_RC_TL_VDM_CTL0_VDM_ENABLED_MASK 0x10000 |
| 219 | +#define PCIE_RC_TL_VDM_CTL0_VDM_IGNORETAG_MASK 0x20000 |
| 220 | +#define PCIE_RC_TL_VDM_CTL0_VDM_IGNOREVNDRID_MASK 0x40000 |
| 221 | + |
| 222 | +#define PCIE_RC_TL_VDM_CTL1 0x0a0c |
| 223 | +#define PCIE_RC_TL_VDM_CTL1_VDM_VNDRID0_MASK 0x0000ffff |
| 224 | +#define PCIE_RC_TL_VDM_CTL1_VDM_VNDRID1_MASK 0xffff0000 |
| 225 | + |
| 226 | +#define PCIE_MISC_CTRL_1 0x40A0 |
| 227 | +#define PCIE_MISC_CTRL_1_OUTBOUND_TC_MASK 0xf |
| 228 | +#define PCIE_MISC_CTRL_1_OUTBOUND_NO_SNOOP_MASK BIT(3) |
| 229 | +#define PCIE_MISC_CTRL_1_OUTBOUND_RO_MASK BIT(4) |
| 230 | +#define PCIE_MISC_CTRL_1_EN_VDM_QOS_CONTROL_MASK BIT(5) |
| 231 | + |
216 | 232 | #define PCIE_MISC_UBUS_CTRL 0x40a4 |
217 | 233 | #define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK BIT(13) |
218 | 234 | #define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK BIT(19) |
|
221 | 237 |
|
222 | 238 | #define PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT 0x405c |
223 | 239 |
|
| 240 | +/* AXI priority forwarding - automatic level-based */ |
| 241 | +#define PCIE_MISC_TC_QUEUE_TO_QOS_MAP(x) (0x4160 - (x) * 4) |
| 242 | +/* Defined in quarter-fullness */ |
| 243 | +#define QUEUE_THRESHOLD_34_TO_QOS_MAP_SHIFT 12 |
| 244 | +#define QUEUE_THRESHOLD_23_TO_QOS_MAP_SHIFT 8 |
| 245 | +#define QUEUE_THRESHOLD_12_TO_QOS_MAP_SHIFT 4 |
| 246 | +#define QUEUE_THRESHOLD_01_TO_QOS_MAP_SHIFT 0 |
| 247 | +#define QUEUE_THRESHOLD_MASK 0xf |
| 248 | + |
| 249 | +/* VDM messages indexing TCs to AXI priorities */ |
| 250 | +/* Indexes 8-15 */ |
| 251 | +#define PCIE_MISC_VDM_PRIORITY_TO_QOS_MAP_HI 0x4164 |
| 252 | +/* Indexes 0-7 */ |
| 253 | +#define PCIE_MISC_VDM_PRIORITY_TO_QOS_MAP_LO 0x4168 |
| 254 | +#define VDM_PRIORITY_TO_QOS_MAP_SHIFT(x) (4 * (x)) |
| 255 | +#define VDM_PRIORITY_TO_QOS_MAP_MASK 0xf |
| 256 | + |
| 257 | +#define PCIE_MISC_AXI_INTF_CTRL 0x416C |
| 258 | +#define AXI_EN_RCLK_QOS_ARRAY_FIX BIT(13) |
| 259 | +#define AXI_EN_QOS_UPDATE_TIMING_FIX BIT(12) |
| 260 | +#define AXI_DIS_QOS_GATING_IN_MASTER BIT(11) |
| 261 | +#define AXI_REQFIFO_EN_QOS_PROPAGATION BIT(7) |
| 262 | +#define AXI_BRIDGE_LOW_LATENCY_MODE BIT(6) |
| 263 | +#define AXI_MASTER_MAX_OUTSTANDING_REQUESTS_MASK 0x3f |
| 264 | + |
224 | 265 | #define PCIE_MISC_AXI_READ_ERROR_DATA 0x4170 |
225 | 266 |
|
226 | 267 | /* Forward declarations */ |
@@ -855,7 +896,7 @@ static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie) |
855 | 896 | const u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030, 0x5030, 0x0007 }; |
856 | 897 | const u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e }; |
857 | 898 | int ret, i; |
858 | | - u32 tmp; |
| 899 | + u32 tmp, qos_map; |
859 | 900 |
|
860 | 901 | /* Allow a 54MHz (xosc) refclk source */ |
861 | 902 | ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, SET_ADDR_OFFSET, 0x1600); |
@@ -903,6 +944,73 @@ static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie) |
903 | 944 | writel(0xB2D0000, pcie->base + PCIE_MISC_UBUS_TIMEOUT); |
904 | 945 | writel(0xABA0000, pcie->base + PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT); |
905 | 946 |
|
| 947 | + /* |
| 948 | + * BCM2712 has a configurable QoS mechanism that assigns TLP Traffic Classes |
| 949 | + * to separate AXI IDs with a configurable priority scheme. |
| 950 | + * Dynamic priority elevation is supported through reception of Type 1 |
| 951 | + * Vendor Defined Messages, but several bugs make this largely ineffective. |
| 952 | + */ |
| 953 | + |
| 954 | + /* Disable broken forwarding search. Set chicken bits for 2712D0 */ |
| 955 | + tmp = readl(pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 956 | + tmp &= ~AXI_REQFIFO_EN_QOS_PROPAGATION; |
| 957 | + tmp |= AXI_EN_RCLK_QOS_ARRAY_FIX | AXI_EN_QOS_UPDATE_TIMING_FIX | |
| 958 | + AXI_DIS_QOS_GATING_IN_MASTER; |
| 959 | + writel(tmp, pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 960 | + |
| 961 | + /* |
| 962 | + * Work around spurious QoS=0 assignments to inbound traffic. |
| 963 | + * If the QOS_UPDATE_TIMING_FIX bit is Reserved-0, then this is a |
| 964 | + * 2712C1 chip, or a single-lane RC. Use the best-effort alternative |
| 965 | + * which is to partially throttle AXI requests in-flight to SDRAM. |
| 966 | + */ |
| 967 | + tmp = readl(pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 968 | + if (!(tmp & AXI_EN_QOS_UPDATE_TIMING_FIX)) { |
| 969 | + tmp &= ~AXI_MASTER_MAX_OUTSTANDING_REQUESTS_MASK; |
| 970 | + tmp |= 15; |
| 971 | + writel(tmp, pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 972 | + } |
| 973 | + |
| 974 | + /* Disable VDM reception by default */ |
| 975 | + tmp = readl(pcie->base + PCIE_MISC_CTRL_1); |
| 976 | + tmp &= ~PCIE_MISC_CTRL_1_EN_VDM_QOS_CONTROL_MASK; |
| 977 | + writel(tmp, pcie->base + PCIE_MISC_CTRL_1); |
| 978 | + |
| 979 | + if (!of_property_read_u32(pcie->np, "brcm,fifo-qos-map", &qos_map)) { |
| 980 | + /* |
| 981 | + * Backpressure mode - bottom 4 nibbles are QoS for each |
| 982 | + * quartile of FIFO level. Each TC gets the same map, because |
| 983 | + * this mode is intended for nonrealtime EPs. |
| 984 | + */ |
| 985 | + qos_map &= 0x0000ffff; |
| 986 | + for (i = 0; i < 8; i++) |
| 987 | + writel(qos_map, pcie->base + PCIE_MISC_TC_QUEUE_TO_QOS_MAP(i)); |
| 988 | + |
| 989 | + } else if (!of_property_read_u32(pcie->np, "brcm,vdm-qos-map", &qos_map)) { |
| 990 | + |
| 991 | + /* Enable VDM reception */ |
| 992 | + tmp = readl(pcie->base + PCIE_MISC_CTRL_1); |
| 993 | + tmp |= PCIE_MISC_CTRL_1_EN_VDM_QOS_CONTROL_MASK; |
| 994 | + writel(tmp, pcie->base + PCIE_MISC_CTRL_1); |
| 995 | + |
| 996 | + /* Broken forwarding means no point separating panic priorities from normal */ |
| 997 | + writel(qos_map, pcie->base + PCIE_MISC_VDM_PRIORITY_TO_QOS_MAP_LO); |
| 998 | + writel(qos_map, pcie->base + PCIE_MISC_VDM_PRIORITY_TO_QOS_MAP_HI); |
| 999 | + |
| 1000 | + /* Match Vendor ID of 0 */ |
| 1001 | + writel(0, pcie->base + PCIE_RC_TL_VDM_CTL1); |
| 1002 | + |
| 1003 | + /* |
| 1004 | + * Forward VDMs to priority interface anyway - |
| 1005 | + * useful for debugging starvation through the received VDM count fields. |
| 1006 | + */ |
| 1007 | + tmp = readl(pcie->base + PCIE_RC_TL_VDM_CTL0); |
| 1008 | + tmp |= PCIE_RC_TL_VDM_CTL0_VDM_ENABLED_MASK | |
| 1009 | + PCIE_RC_TL_VDM_CTL0_VDM_IGNORETAG_MASK | |
| 1010 | + PCIE_RC_TL_VDM_CTL0_VDM_IGNOREVNDRID_MASK; |
| 1011 | + writel(tmp, pcie->base + PCIE_RC_TL_VDM_CTL0); |
| 1012 | + } |
| 1013 | + |
906 | 1014 | return 0; |
907 | 1015 | } |
908 | 1016 |
|
|
0 commit comments