|
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 */
|
@@ -856,6 +897,7 @@ static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie)
|
856 | 897 | const u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
|
857 | 898 | int ret, i;
|
858 | 899 | u32 tmp;
|
| 900 | + u8 qos_map[8]; |
859 | 901 |
|
860 | 902 | /* Allow a 54MHz (xosc) refclk source */
|
861 | 903 | ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, SET_ADDR_OFFSET, 0x1600);
|
@@ -903,6 +945,84 @@ static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie)
|
903 | 945 | writel(0xB2D0000, pcie->base + PCIE_MISC_UBUS_TIMEOUT);
|
904 | 946 | writel(0xABA0000, pcie->base + PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT);
|
905 | 947 |
|
| 948 | + /* |
| 949 | + * BCM2712 has a configurable QoS mechanism that assigns TLP Traffic Classes |
| 950 | + * to separate AXI IDs with a configurable priority scheme. |
| 951 | + * Dynamic priority elevation is supported through reception of Type 1 |
| 952 | + * Vendor Defined Messages, but several bugs make this largely ineffective. |
| 953 | + */ |
| 954 | + |
| 955 | + /* Disable broken forwarding search. Set chicken bits for 2712D0 */ |
| 956 | + tmp = readl(pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 957 | + tmp &= ~AXI_REQFIFO_EN_QOS_PROPAGATION; |
| 958 | + tmp |= AXI_EN_RCLK_QOS_ARRAY_FIX | AXI_EN_QOS_UPDATE_TIMING_FIX | |
| 959 | + AXI_DIS_QOS_GATING_IN_MASTER; |
| 960 | + writel(tmp, pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 961 | + |
| 962 | + /* |
| 963 | + * Work around spurious QoS=0 assignments to inbound traffic. |
| 964 | + * If the QOS_UPDATE_TIMING_FIX bit is Reserved-0, then this is a |
| 965 | + * 2712C1 chip, or a single-lane RC. Use the best-effort alternative |
| 966 | + * which is to partially throttle AXI requests in-flight to SDRAM. |
| 967 | + */ |
| 968 | + tmp = readl(pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 969 | + if (!(tmp & AXI_EN_QOS_UPDATE_TIMING_FIX)) { |
| 970 | + tmp &= ~AXI_MASTER_MAX_OUTSTANDING_REQUESTS_MASK; |
| 971 | + tmp |= 15; |
| 972 | + writel(tmp, pcie->base + PCIE_MISC_AXI_INTF_CTRL); |
| 973 | + } |
| 974 | + |
| 975 | + /* Disable VDM reception by default */ |
| 976 | + tmp = readl(pcie->base + PCIE_MISC_CTRL_1); |
| 977 | + tmp &= ~PCIE_MISC_CTRL_1_EN_VDM_QOS_CONTROL_MASK; |
| 978 | + writel(tmp, pcie->base + PCIE_MISC_CTRL_1); |
| 979 | + |
| 980 | + if (!of_property_read_u8_array(pcie->np, "brcm,fifo-qos-map", qos_map, 4)) { |
| 981 | + |
| 982 | + /* |
| 983 | + * Backpressure mode - each element is QoS for each |
| 984 | + * quartile of FIFO level. Each TC gets the same map, because |
| 985 | + * this mode is intended for nonrealtime EPs. |
| 986 | + */ |
| 987 | + tmp = 0; |
| 988 | + for (i = 0; i < 4; i++) { |
| 989 | + /* Priorities range from 0-15 */ |
| 990 | + qos_map[i] &= 0x0f; |
| 991 | + tmp |= qos_map[i] << (i * 4); |
| 992 | + } |
| 993 | + for (i = 0; i < 8; i++) |
| 994 | + writel(tmp, pcie->base + PCIE_MISC_TC_QUEUE_TO_QOS_MAP(i)); |
| 995 | + |
| 996 | + } else if (!of_property_read_u8_array(pcie->np, "brcm,vdm-qos-map", qos_map, 8)) { |
| 997 | + /* Enable VDM reception */ |
| 998 | + tmp = readl(pcie->base + PCIE_MISC_CTRL_1); |
| 999 | + tmp |= PCIE_MISC_CTRL_1_EN_VDM_QOS_CONTROL_MASK; |
| 1000 | + writel(tmp, pcie->base + PCIE_MISC_CTRL_1); |
| 1001 | + |
| 1002 | + tmp = 0; |
| 1003 | + for (i = 0; i < 8; i++) { |
| 1004 | + /* Priorities range from 0-15 */ |
| 1005 | + qos_map[i] &= 0x0f; |
| 1006 | + tmp |= qos_map[i] << (i * 4); |
| 1007 | + } |
| 1008 | + /* Broken forwarding means no point separating panic priorities from normal */ |
| 1009 | + writel(tmp, pcie->base + PCIE_MISC_VDM_PRIORITY_TO_QOS_MAP_LO); |
| 1010 | + writel(tmp, pcie->base + PCIE_MISC_VDM_PRIORITY_TO_QOS_MAP_HI); |
| 1011 | + |
| 1012 | + /* Match Vendor ID of 0 */ |
| 1013 | + writel(0, pcie->base + PCIE_RC_TL_VDM_CTL1); |
| 1014 | + |
| 1015 | + /* |
| 1016 | + * Forward VDMs to priority interface anyway - |
| 1017 | + * useful for debugging starvation through the received VDM count fields. |
| 1018 | + */ |
| 1019 | + tmp = readl(pcie->base + PCIE_RC_TL_VDM_CTL0); |
| 1020 | + tmp |= PCIE_RC_TL_VDM_CTL0_VDM_ENABLED_MASK | |
| 1021 | + PCIE_RC_TL_VDM_CTL0_VDM_IGNORETAG_MASK | |
| 1022 | + PCIE_RC_TL_VDM_CTL0_VDM_IGNOREVNDRID_MASK; |
| 1023 | + writel(tmp, pcie->base + PCIE_RC_TL_VDM_CTL0); |
| 1024 | + } |
| 1025 | + |
906 | 1026 | return 0;
|
907 | 1027 | }
|
908 | 1028 |
|
|
0 commit comments