forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/usb/dwc2/core.c
....@@ -524,10 +524,25 @@
524524 greset |= GRSTCTL_CSFTRST;
525525 dwc2_writel(hsotg, greset, GRSTCTL);
526526
527
- if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, GRSTCTL_CSFTRST, 10000)) {
528
- dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL GRSTCTL_CSFTRST\n",
529
- __func__);
530
- return -EBUSY;
527
+ if ((hsotg->hw_params.snpsid & DWC2_CORE_REV_MASK) <
528
+ (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) {
529
+ if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL,
530
+ GRSTCTL_CSFTRST, 10000)) {
531
+ dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL_CSFTRST\n",
532
+ __func__);
533
+ return -EBUSY;
534
+ }
535
+ } else {
536
+ if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL,
537
+ GRSTCTL_CSFTRST_DONE, 10000)) {
538
+ dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL_CSFTRST_DONE\n",
539
+ __func__);
540
+ return -EBUSY;
541
+ }
542
+ greset = dwc2_readl(hsotg, GRSTCTL);
543
+ greset &= ~GRSTCTL_CSFTRST;
544
+ greset |= GRSTCTL_CSFTRST_DONE;
545
+ dwc2_writel(hsotg, greset, GRSTCTL);
531546 }
532547
533548 /* Wait for AHB master IDLE state */
....@@ -641,14 +656,24 @@
641656 */
642657 void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg)
643658 {
659
+ u32 count = 0;
660
+
644661 switch (hsotg->dr_mode) {
645662 case USB_DR_MODE_HOST:
646663 /*
647664 * NOTE: This is required for some rockchip soc based
648665 * platforms on their host-only dwc2.
649666 */
650
- if (!dwc2_hw_is_otg(hsotg))
651
- msleep(50);
667
+ if (!dwc2_hw_is_otg(hsotg)) {
668
+ while (dwc2_readl(hsotg, GOTGCTL) & GOTGCTL_CONID_B) {
669
+ msleep(20);
670
+ if (++count > 10)
671
+ break;
672
+ }
673
+ if (count > 10)
674
+ dev_err(hsotg->dev,
675
+ "Waiting for Host Mode timed out");
676
+ }
652677
653678 break;
654679 case USB_DR_MODE_PERIPHERAL:
....@@ -1020,6 +1045,217 @@
10201045 return -ETIMEDOUT;
10211046 }
10221047
1048
+/*
1049
+ * Initializes the FSLSPClkSel field of the HCFG register depending on the
1050
+ * PHY type
1051
+ */
1052
+void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
1053
+{
1054
+ u32 hcfg, val;
1055
+
1056
+ if ((hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
1057
+ hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
1058
+ hsotg->params.ulpi_fs_ls) ||
1059
+ hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
1060
+ /* Full speed PHY */
1061
+ val = HCFG_FSLSPCLKSEL_48_MHZ;
1062
+ } else {
1063
+ /* High speed PHY running at full speed or high speed */
1064
+ val = HCFG_FSLSPCLKSEL_30_60_MHZ;
1065
+ }
1066
+
1067
+ dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val);
1068
+ hcfg = dwc2_readl(hsotg, HCFG);
1069
+ hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
1070
+ hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT;
1071
+ dwc2_writel(hsotg, hcfg, HCFG);
1072
+}
1073
+
1074
+static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
1075
+{
1076
+ u32 usbcfg, ggpio, i2cctl;
1077
+ int retval = 0;
1078
+
1079
+ /*
1080
+ * core_init() is now called on every switch so only call the
1081
+ * following for the first time through
1082
+ */
1083
+ if (select_phy) {
1084
+ dev_dbg(hsotg->dev, "FS PHY selected\n");
1085
+
1086
+ usbcfg = dwc2_readl(hsotg, GUSBCFG);
1087
+ if (!(usbcfg & GUSBCFG_PHYSEL)) {
1088
+ usbcfg |= GUSBCFG_PHYSEL;
1089
+ dwc2_writel(hsotg, usbcfg, GUSBCFG);
1090
+
1091
+ /* Reset after a PHY select */
1092
+ retval = dwc2_core_reset(hsotg, false);
1093
+
1094
+ if (retval) {
1095
+ dev_err(hsotg->dev,
1096
+ "%s: Reset failed, aborting", __func__);
1097
+ return retval;
1098
+ }
1099
+ }
1100
+
1101
+ if (hsotg->params.activate_stm_fs_transceiver) {
1102
+ ggpio = dwc2_readl(hsotg, GGPIO);
1103
+ if (!(ggpio & GGPIO_STM32_OTG_GCCFG_PWRDWN)) {
1104
+ dev_dbg(hsotg->dev, "Activating transceiver\n");
1105
+ /*
1106
+ * STM32F4x9 uses the GGPIO register as general
1107
+ * core configuration register.
1108
+ */
1109
+ ggpio |= GGPIO_STM32_OTG_GCCFG_PWRDWN;
1110
+ dwc2_writel(hsotg, ggpio, GGPIO);
1111
+ }
1112
+ }
1113
+ }
1114
+
1115
+ /*
1116
+ * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1117
+ * do this on HNP Dev/Host mode switches (done in dev_init and
1118
+ * host_init).
1119
+ */
1120
+ if (dwc2_is_host_mode(hsotg))
1121
+ dwc2_init_fs_ls_pclk_sel(hsotg);
1122
+
1123
+ if (hsotg->params.i2c_enable) {
1124
+ dev_dbg(hsotg->dev, "FS PHY enabling I2C\n");
1125
+
1126
+ /* Program GUSBCFG.OtgUtmiFsSel to I2C */
1127
+ usbcfg = dwc2_readl(hsotg, GUSBCFG);
1128
+ usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL;
1129
+ dwc2_writel(hsotg, usbcfg, GUSBCFG);
1130
+
1131
+ /* Program GI2CCTL.I2CEn */
1132
+ i2cctl = dwc2_readl(hsotg, GI2CCTL);
1133
+ i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK;
1134
+ i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT;
1135
+ i2cctl &= ~GI2CCTL_I2CEN;
1136
+ dwc2_writel(hsotg, i2cctl, GI2CCTL);
1137
+ i2cctl |= GI2CCTL_I2CEN;
1138
+ dwc2_writel(hsotg, i2cctl, GI2CCTL);
1139
+ }
1140
+
1141
+ return retval;
1142
+}
1143
+
1144
+static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
1145
+{
1146
+ u32 usbcfg, usbcfg_old;
1147
+ int retval = 0;
1148
+
1149
+ if (!select_phy)
1150
+ return 0;
1151
+
1152
+ usbcfg = dwc2_readl(hsotg, GUSBCFG);
1153
+ usbcfg_old = usbcfg;
1154
+
1155
+ /*
1156
+ * HS PHY parameters. These parameters are preserved during soft reset
1157
+ * so only program the first time. Do a soft reset immediately after
1158
+ * setting phyif.
1159
+ */
1160
+ switch (hsotg->params.phy_type) {
1161
+ case DWC2_PHY_TYPE_PARAM_ULPI:
1162
+ /* ULPI interface */
1163
+ dev_dbg(hsotg->dev, "HS ULPI PHY selected\n");
1164
+ usbcfg |= GUSBCFG_ULPI_UTMI_SEL;
1165
+ usbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL);
1166
+ if (hsotg->params.phy_ulpi_ddr)
1167
+ usbcfg |= GUSBCFG_DDRSEL;
1168
+
1169
+ /* Set external VBUS indicator as needed. */
1170
+ if (hsotg->params.oc_disable)
1171
+ usbcfg |= (GUSBCFG_ULPI_INT_VBUS_IND |
1172
+ GUSBCFG_INDICATORPASSTHROUGH);
1173
+ break;
1174
+ case DWC2_PHY_TYPE_PARAM_UTMI:
1175
+ /* UTMI+ interface */
1176
+ dev_dbg(hsotg->dev, "HS UTMI+ PHY selected\n");
1177
+ usbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16);
1178
+ if (hsotg->params.phy_utmi_width == 16)
1179
+ usbcfg |= GUSBCFG_PHYIF16;
1180
+ break;
1181
+ default:
1182
+ dev_err(hsotg->dev, "FS PHY selected at HS!\n");
1183
+ break;
1184
+ }
1185
+
1186
+ if (usbcfg != usbcfg_old) {
1187
+ dwc2_writel(hsotg, usbcfg, GUSBCFG);
1188
+
1189
+ /* Reset after setting the PHY parameters */
1190
+ retval = dwc2_core_reset(hsotg, false);
1191
+ if (retval) {
1192
+ dev_err(hsotg->dev,
1193
+ "%s: Reset failed, aborting", __func__);
1194
+ return retval;
1195
+ }
1196
+ }
1197
+
1198
+ return retval;
1199
+}
1200
+
1201
+static void dwc2_set_turnaround_time(struct dwc2_hsotg *hsotg)
1202
+{
1203
+ u32 usbcfg;
1204
+
1205
+ if (hsotg->params.phy_type != DWC2_PHY_TYPE_PARAM_UTMI)
1206
+ return;
1207
+
1208
+ usbcfg = dwc2_readl(hsotg, GUSBCFG);
1209
+
1210
+ usbcfg &= ~GUSBCFG_USBTRDTIM_MASK;
1211
+ if (hsotg->params.phy_utmi_width == 16)
1212
+ usbcfg |= 5 << GUSBCFG_USBTRDTIM_SHIFT;
1213
+ else
1214
+ usbcfg |= 9 << GUSBCFG_USBTRDTIM_SHIFT;
1215
+
1216
+ dwc2_writel(hsotg, usbcfg, GUSBCFG);
1217
+}
1218
+
1219
+int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
1220
+{
1221
+ u32 usbcfg;
1222
+ int retval = 0;
1223
+
1224
+ if ((hsotg->params.speed == DWC2_SPEED_PARAM_FULL ||
1225
+ hsotg->params.speed == DWC2_SPEED_PARAM_LOW) &&
1226
+ hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
1227
+ /* If FS/LS mode with FS/LS PHY */
1228
+ retval = dwc2_fs_phy_init(hsotg, select_phy);
1229
+ if (retval)
1230
+ return retval;
1231
+ } else {
1232
+ /* High speed PHY */
1233
+ retval = dwc2_hs_phy_init(hsotg, select_phy);
1234
+ if (retval)
1235
+ return retval;
1236
+
1237
+ if (dwc2_is_device_mode(hsotg))
1238
+ dwc2_set_turnaround_time(hsotg);
1239
+ }
1240
+
1241
+ if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
1242
+ hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
1243
+ hsotg->params.ulpi_fs_ls) {
1244
+ dev_dbg(hsotg->dev, "Setting ULPI FSLS\n");
1245
+ usbcfg = dwc2_readl(hsotg, GUSBCFG);
1246
+ usbcfg |= GUSBCFG_ULPI_FS_LS;
1247
+ usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M;
1248
+ dwc2_writel(hsotg, usbcfg, GUSBCFG);
1249
+ } else {
1250
+ usbcfg = dwc2_readl(hsotg, GUSBCFG);
1251
+ usbcfg &= ~GUSBCFG_ULPI_FS_LS;
1252
+ usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M;
1253
+ dwc2_writel(hsotg, usbcfg, GUSBCFG);
1254
+ }
1255
+
1256
+ return retval;
1257
+}
1258
+
10231259 MODULE_DESCRIPTION("DESIGNWARE HS OTG Core");
10241260 MODULE_AUTHOR("Synopsys, Inc.");
10251261 MODULE_LICENSE("Dual BSD/GPL");