48
48
#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc
49
49
#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00
50
50
51
+ #define PCIE_RC_CFG_PRIV1_ROOT_CAP 0x4f8
52
+ #define PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK 0xf8
53
+
51
54
#define PCIE_RC_DL_MDIO_ADDR 0x1100
52
55
#define PCIE_RC_DL_MDIO_WR_DATA 0x1104
53
56
#define PCIE_RC_DL_MDIO_RD_DATA 0x1108
121
124
122
125
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
123
126
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
127
+ #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK 0x200000
124
128
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
125
129
#define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000
126
-
130
+ #define PCIE_CLKREQ_MASK \
131
+ (PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK | \
132
+ PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK)
127
133
128
134
#define PCIE_INTR2_CPU_BASE 0x4300
129
135
#define PCIE_MSI_INTR2_BASE 0x4500
@@ -1028,13 +1034,89 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
1028
1034
return 0 ;
1029
1035
}
1030
1036
1037
+ /*
1038
+ * This extends the timeout period for an access to an internal bus. This
1039
+ * access timeout may occur during L1SS sleep periods, even without the
1040
+ * presence of a PCIe access.
1041
+ */
1042
+ static void brcm_extend_rbus_timeout (struct brcm_pcie * pcie )
1043
+ {
1044
+ /* TIMEOUT register is two registers before RGR1_SW_INIT_1 */
1045
+ const unsigned int REG_OFFSET = PCIE_RGR1_SW_INIT_1 (pcie ) - 8 ;
1046
+ u32 timeout_us = 4000000 ; /* 4 seconds, our setting for L1SS */
1047
+
1048
+ /* Each unit in timeout register is 1/216,000,000 seconds */
1049
+ writel (216 * timeout_us , pcie -> base + REG_OFFSET );
1050
+ }
1051
+
1052
+ static void brcm_config_clkreq (struct brcm_pcie * pcie )
1053
+ {
1054
+ static const char err_msg [] = "invalid 'brcm,clkreq-mode' DT string\n" ;
1055
+ const char * mode = "default" ;
1056
+ u32 clkreq_cntl ;
1057
+ int ret , tmp ;
1058
+
1059
+ ret = of_property_read_string (pcie -> np , "brcm,clkreq-mode" , & mode );
1060
+ if (ret && ret != - EINVAL ) {
1061
+ dev_err (pcie -> dev , err_msg );
1062
+ mode = "safe" ;
1063
+ }
1064
+
1065
+ /* Start out assuming safe mode (both mode bits cleared) */
1066
+ clkreq_cntl = readl (pcie -> base + PCIE_MISC_HARD_PCIE_HARD_DEBUG );
1067
+ clkreq_cntl &= ~PCIE_CLKREQ_MASK ;
1068
+
1069
+ if (strcmp (mode , "no-l1ss" ) == 0 ) {
1070
+ /*
1071
+ * "no-l1ss" -- Provides Clock Power Management, L0s, and
1072
+ * L1, but cannot provide L1 substate (L1SS) power
1073
+ * savings. If the downstream device connected to the RC is
1074
+ * L1SS capable AND the OS enables L1SS, all PCIe traffic
1075
+ * may abruptly halt, potentially hanging the system.
1076
+ */
1077
+ clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK ;
1078
+ /*
1079
+ * We want to un-advertise L1 substates because if the OS
1080
+ * tries to configure the controller into using L1 substate
1081
+ * power savings it may fail or hang when the RC HW is in
1082
+ * "no-l1ss" mode.
1083
+ */
1084
+ tmp = readl (pcie -> base + PCIE_RC_CFG_PRIV1_ROOT_CAP );
1085
+ u32p_replace_bits (& tmp , 2 , PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK );
1086
+ writel (tmp , pcie -> base + PCIE_RC_CFG_PRIV1_ROOT_CAP );
1087
+
1088
+ } else if (strcmp (mode , "default" ) == 0 ) {
1089
+ /*
1090
+ * "default" -- Provides L0s, L1, and L1SS, but not
1091
+ * compliant to provide Clock Power Management;
1092
+ * specifically, may not be able to meet the Tclron max
1093
+ * timing of 400ns as specified in "Dynamic Clock Control",
1094
+ * section 3.2.5.2.2 of the PCIe spec. This situation is
1095
+ * atypical and should happen only with older devices.
1096
+ */
1097
+ clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK ;
1098
+ brcm_extend_rbus_timeout (pcie );
1099
+
1100
+ } else {
1101
+ /*
1102
+ * "safe" -- No power savings; refclk is driven by RC
1103
+ * unconditionally.
1104
+ */
1105
+ if (strcmp (mode , "safe" ) != 0 )
1106
+ dev_err (pcie -> dev , err_msg );
1107
+ mode = "safe" ;
1108
+ }
1109
+ writel (clkreq_cntl , pcie -> base + PCIE_MISC_HARD_PCIE_HARD_DEBUG );
1110
+
1111
+ dev_info (pcie -> dev , "clkreq-mode set to %s\n" , mode );
1112
+ }
1113
+
1031
1114
static int brcm_pcie_start_link (struct brcm_pcie * pcie )
1032
1115
{
1033
1116
struct device * dev = pcie -> dev ;
1034
1117
void __iomem * base = pcie -> base ;
1035
1118
u16 nlw , cls , lnksta ;
1036
1119
bool ssc_good = false;
1037
- u32 tmp ;
1038
1120
int ret , i ;
1039
1121
1040
1122
/* Unassert the fundamental reset */
@@ -1059,6 +1141,8 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
1059
1141
return - ENODEV ;
1060
1142
}
1061
1143
1144
+ brcm_config_clkreq (pcie );
1145
+
1062
1146
if (pcie -> gen )
1063
1147
brcm_pcie_set_gen (pcie , pcie -> gen );
1064
1148
@@ -1077,14 +1161,6 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
1077
1161
pci_speed_string (pcie_link_speed [cls ]), nlw ,
1078
1162
ssc_good ? "(SSC)" : "(!SSC)" );
1079
1163
1080
- /*
1081
- * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
1082
- * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
1083
- */
1084
- tmp = readl (base + PCIE_MISC_HARD_PCIE_HARD_DEBUG );
1085
- tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK ;
1086
- writel (tmp , base + PCIE_MISC_HARD_PCIE_HARD_DEBUG );
1087
-
1088
1164
return 0 ;
1089
1165
}
1090
1166
0 commit comments