1 /* 2 * Allwinner sun4i USB PHY driver 3 * 4 * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com> 5 * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com> 6 * Copyright (C) 2014 Roman Byshko <rbyshko@gmail.com> 7 * 8 * Modelled arch/arm/mach-sunxi/usb_phy.c to compatible with generic-phy. 9 * 10 * SPDX-License-Identifier: GPL-2.0+ 11 */ 12 13 #include <common.h> 14 #include <dm.h> 15 #include <dm/device.h> 16 #include <generic-phy.h> 17 #include <phy-sun4i-usb.h> 18 #include <asm/gpio.h> 19 #include <asm/io.h> 20 #include <asm/arch/clock.h> 21 #include <asm/arch/cpu.h> 22 23 #define REG_ISCR 0x00 24 #define REG_PHYCTL_A10 0x04 25 #define REG_PHYBIST 0x08 26 #define REG_PHYTUNE 0x0c 27 #define REG_PHYCTL_A33 0x10 28 #define REG_PHY_OTGCTL 0x20 29 #define REG_PMU_UNK1 0x10 30 31 /* Common Control Bits for Both PHYs */ 32 #define PHY_PLL_BW 0x03 33 #define PHY_RES45_CAL_EN 0x0c 34 35 /* Private Control Bits for Each PHY */ 36 #define PHY_TX_AMPLITUDE_TUNE 0x20 37 #define PHY_TX_SLEWRATE_TUNE 0x22 38 #define PHY_DISCON_TH_SEL 0x2a 39 #define PHY_SQUELCH_DETECT 0x3c 40 41 #define PHYCTL_DATA BIT(7) 42 #define OTGCTL_ROUTE_MUSB BIT(0) 43 44 #define PHY_TX_RATE BIT(4) 45 #define PHY_TX_MAGNITUDE BIT(2) 46 #define PHY_TX_AMPLITUDE_LEN 5 47 48 #define PHY_RES45_CAL_DATA BIT(0) 49 #define PHY_RES45_CAL_LEN 1 50 #define PHY_DISCON_TH_LEN 2 51 52 #define SUNXI_AHB_ICHR8_EN BIT(10) 53 #define SUNXI_AHB_INCR4_BURST_EN BIT(9) 54 #define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) 55 #define SUNXI_ULPI_BYPASS_EN BIT(0) 56 57 /* A83T specific control bits for PHY0 */ 58 #define PHY_CTL_VBUSVLDEXT BIT(5) 59 #define PHY_CTL_SIDDQ BIT(3) 60 61 /* A83T specific control bits for PHY2 HSIC */ 62 #define SUNXI_EHCI_HS_FORCE BIT(20) 63 #define SUNXI_HSIC_CONNECT_INT BIT(16) 64 #define SUNXI_HSIC BIT(1) 65 66 #define MAX_PHYS 4 67 68 enum sun4i_usb_phy_type { 69 sun4i_a10_phy, 70 sun6i_a31_phy, 71 sun8i_a33_phy, 72 sun8i_a83t_phy, 73 sun8i_h3_phy, 74 sun8i_v3s_phy, 75 sun50i_a64_phy, 76 }; 77 78 struct sun4i_usb_phy_cfg { 79 int num_phys; 80 enum sun4i_usb_phy_type type; 81 u32 disc_thresh; 82 u8 phyctl_offset; 83 bool enable_pmu_unk1; 84 bool phy0_dual_route; 85 }; 86 87 struct sun4i_usb_phy_info { 88 const char *gpio_vbus; 89 const char *gpio_vbus_det; 90 const char *gpio_id_det; 91 int rst_mask; 92 } phy_info[] = { 93 { 94 .gpio_vbus = CONFIG_USB0_VBUS_PIN, 95 .gpio_vbus_det = CONFIG_USB0_VBUS_DET, 96 .gpio_id_det = CONFIG_USB0_ID_DET, 97 .rst_mask = (CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK), 98 }, 99 { 100 .gpio_vbus = CONFIG_USB1_VBUS_PIN, 101 .gpio_vbus_det = NULL, 102 .gpio_id_det = NULL, 103 .rst_mask = (CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK), 104 }, 105 { 106 .gpio_vbus = CONFIG_USB2_VBUS_PIN, 107 .gpio_vbus_det = NULL, 108 .gpio_id_det = NULL, 109 #ifdef CONFIG_MACH_SUN8I_A83T 110 .rst_mask = (CCM_USB_CTRL_HSIC_RST | CCM_USB_CTRL_HSIC_CLK | 111 CCM_USB_CTRL_12M_CLK), 112 #else 113 .rst_mask = (CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK), 114 #endif 115 }, 116 { 117 .gpio_vbus = CONFIG_USB3_VBUS_PIN, 118 .gpio_vbus_det = NULL, 119 .gpio_id_det = NULL, 120 }, 121 }; 122 123 struct sun4i_usb_phy_plat { 124 void __iomem *pmu; 125 int power_on_count; 126 int gpio_vbus; 127 int gpio_vbus_det; 128 int gpio_id_det; 129 int rst_mask; 130 int id; 131 }; 132 133 struct sun4i_usb_phy_data { 134 void __iomem *base; 135 struct sunxi_ccm_reg *ccm; 136 const struct sun4i_usb_phy_cfg *cfg; 137 struct sun4i_usb_phy_plat *usb_phy; 138 }; 139 140 static int initial_usb_scan_delay = CONFIG_INITIAL_USB_SCAN_DELAY; 141 142 static void sun4i_usb_phy_write(struct phy *phy, u32 addr, u32 data, int len) 143 { 144 struct sun4i_usb_phy_data *phy_data = dev_get_priv(phy->dev); 145 struct sun4i_usb_phy_plat *usb_phy = &phy_data->usb_phy[phy->id]; 146 u32 temp, usbc_bit = BIT(usb_phy->id * 2); 147 void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; 148 int i; 149 150 if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) { 151 /* SoCs newer than A33 need us to set phyctl to 0 explicitly */ 152 writel(0, phyctl); 153 } 154 155 for (i = 0; i < len; i++) { 156 temp = readl(phyctl); 157 158 /* clear the address portion */ 159 temp &= ~(0xff << 8); 160 161 /* set the address */ 162 temp |= ((addr + i) << 8); 163 writel(temp, phyctl); 164 165 /* set the data bit and clear usbc bit*/ 166 temp = readb(phyctl); 167 if (data & 0x1) 168 temp |= PHYCTL_DATA; 169 else 170 temp &= ~PHYCTL_DATA; 171 temp &= ~usbc_bit; 172 writeb(temp, phyctl); 173 174 /* pulse usbc_bit */ 175 temp = readb(phyctl); 176 temp |= usbc_bit; 177 writeb(temp, phyctl); 178 179 temp = readb(phyctl); 180 temp &= ~usbc_bit; 181 writeb(temp, phyctl); 182 183 data >>= 1; 184 } 185 } 186 187 static void sun4i_usb_phy_passby(struct phy *phy, bool enable) 188 { 189 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 190 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 191 u32 bits, reg_value; 192 193 if (!usb_phy->pmu) 194 return; 195 196 bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN | 197 SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN; 198 199 /* A83T USB2 is HSIC */ 200 if (data->cfg->type == sun8i_a83t_phy && usb_phy->id == 2) 201 bits |= SUNXI_EHCI_HS_FORCE | SUNXI_HSIC_CONNECT_INT | 202 SUNXI_HSIC; 203 204 reg_value = readl(usb_phy->pmu); 205 206 if (enable) 207 reg_value |= bits; 208 else 209 reg_value &= ~bits; 210 211 writel(reg_value, usb_phy->pmu); 212 } 213 214 static int sun4i_usb_phy_power_on(struct phy *phy) 215 { 216 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 217 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 218 219 if (initial_usb_scan_delay) { 220 mdelay(initial_usb_scan_delay); 221 initial_usb_scan_delay = 0; 222 } 223 224 usb_phy->power_on_count++; 225 if (usb_phy->power_on_count != 1) 226 return 0; 227 228 if (usb_phy->gpio_vbus >= 0) 229 gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_UP); 230 231 return 0; 232 } 233 234 static int sun4i_usb_phy_power_off(struct phy *phy) 235 { 236 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 237 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 238 239 usb_phy->power_on_count--; 240 if (usb_phy->power_on_count != 0) 241 return 0; 242 243 if (usb_phy->gpio_vbus >= 0) 244 gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_DISABLE); 245 246 return 0; 247 } 248 249 static void sun4i_usb_phy0_reroute(struct sun4i_usb_phy_data *data, bool id_det) 250 { 251 u32 regval; 252 253 regval = readl(data->base + REG_PHY_OTGCTL); 254 if (!id_det) { 255 /* Host mode. Route phy0 to EHCI/OHCI */ 256 regval &= ~OTGCTL_ROUTE_MUSB; 257 } else { 258 /* Peripheral mode. Route phy0 to MUSB */ 259 regval |= OTGCTL_ROUTE_MUSB; 260 } 261 writel(regval, data->base + REG_PHY_OTGCTL); 262 } 263 264 static int sun4i_usb_phy_init(struct phy *phy) 265 { 266 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 267 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 268 u32 val; 269 270 setbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask); 271 272 if (data->cfg->type == sun8i_a83t_phy) { 273 if (phy->id == 0) { 274 val = readl(data->base + data->cfg->phyctl_offset); 275 val |= PHY_CTL_VBUSVLDEXT; 276 val &= ~PHY_CTL_SIDDQ; 277 writel(val, data->base + data->cfg->phyctl_offset); 278 } 279 } else { 280 if (usb_phy->pmu && data->cfg->enable_pmu_unk1) { 281 val = readl(usb_phy->pmu + REG_PMU_UNK1); 282 writel(val & ~2, usb_phy->pmu + REG_PMU_UNK1); 283 } 284 285 if (usb_phy->id == 0) 286 sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 287 PHY_RES45_CAL_DATA, 288 PHY_RES45_CAL_LEN); 289 290 /* Adjust PHY's magnitude and rate */ 291 sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 292 PHY_TX_MAGNITUDE | PHY_TX_RATE, 293 PHY_TX_AMPLITUDE_LEN); 294 295 /* Disconnect threshold adjustment */ 296 sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, 297 data->cfg->disc_thresh, PHY_DISCON_TH_LEN); 298 } 299 300 sun4i_usb_phy_passby(phy, true); 301 302 sun4i_usb_phy0_reroute(data, true); 303 304 return 0; 305 } 306 307 static int sun4i_usb_phy_exit(struct phy *phy) 308 { 309 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 310 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 311 312 if (phy->id == 0) { 313 if (data->cfg->type == sun8i_a83t_phy) { 314 void __iomem *phyctl = data->base + 315 data->cfg->phyctl_offset; 316 317 writel(readl(phyctl) | PHY_CTL_SIDDQ, phyctl); 318 } 319 } 320 321 sun4i_usb_phy_passby(phy, false); 322 323 clrbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask); 324 325 return 0; 326 } 327 328 static int sun4i_usb_phy_xlate(struct phy *phy, 329 struct ofnode_phandle_args *args) 330 { 331 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 332 333 if (args->args_count >= data->cfg->num_phys) 334 return -EINVAL; 335 336 if (args->args_count) 337 phy->id = args->args[0]; 338 else 339 phy->id = 0; 340 341 debug("%s: phy_id = %ld\n", __func__, phy->id); 342 return 0; 343 } 344 345 int sun4i_usb_phy_vbus_detect(struct phy *phy) 346 { 347 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 348 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 349 int err, retries = 3; 350 351 debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det); 352 353 if (usb_phy->gpio_vbus_det < 0) 354 return usb_phy->gpio_vbus_det; 355 356 err = gpio_get_value(usb_phy->gpio_vbus_det); 357 /* 358 * Vbus may have been provided by the board and just been turned of 359 * some milliseconds ago on reset, what we're measuring then is a 360 * residual charge on Vbus, sleep a bit and try again. 361 */ 362 while (err > 0 && retries--) { 363 mdelay(100); 364 err = gpio_get_value(usb_phy->gpio_vbus_det); 365 } 366 367 return err; 368 } 369 370 int sun4i_usb_phy_id_detect(struct phy *phy) 371 { 372 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 373 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 374 375 debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det); 376 377 if (usb_phy->gpio_id_det < 0) 378 return usb_phy->gpio_id_det; 379 380 return gpio_get_value(usb_phy->gpio_id_det); 381 } 382 383 void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled) 384 { 385 sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2); 386 } 387 388 static struct phy_ops sun4i_usb_phy_ops = { 389 .of_xlate = sun4i_usb_phy_xlate, 390 .init = sun4i_usb_phy_init, 391 .power_on = sun4i_usb_phy_power_on, 392 .power_off = sun4i_usb_phy_power_off, 393 .exit = sun4i_usb_phy_exit, 394 }; 395 396 static int sun4i_usb_phy_probe(struct udevice *dev) 397 { 398 struct sun4i_usb_phy_plat *plat = dev_get_platdata(dev); 399 struct sun4i_usb_phy_data *data = dev_get_priv(dev); 400 int i, ret; 401 402 data->cfg = (const struct sun4i_usb_phy_cfg *)dev_get_driver_data(dev); 403 if (!data->cfg) 404 return -EINVAL; 405 406 data->base = (void __iomem *)devfdt_get_addr_name(dev, "phy_ctrl"); 407 if (IS_ERR(data->base)) 408 return PTR_ERR(data->base); 409 410 data->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 411 if (IS_ERR(data->ccm)) 412 return PTR_ERR(data->ccm); 413 414 data->usb_phy = plat; 415 for (i = 0; i < data->cfg->num_phys; i++) { 416 struct sun4i_usb_phy_plat *phy = &plat[i]; 417 struct sun4i_usb_phy_info *info = &phy_info[i]; 418 char name[16]; 419 420 phy->gpio_vbus = sunxi_name_to_gpio(info->gpio_vbus); 421 if (phy->gpio_vbus >= 0) { 422 ret = gpio_request(phy->gpio_vbus, "usb_vbus"); 423 if (ret) 424 return ret; 425 ret = gpio_direction_output(phy->gpio_vbus, 0); 426 if (ret) 427 return ret; 428 } 429 430 phy->gpio_vbus_det = sunxi_name_to_gpio(info->gpio_vbus_det); 431 if (phy->gpio_vbus_det >= 0) { 432 ret = gpio_request(phy->gpio_vbus_det, "usb_vbus_det"); 433 if (ret) 434 return ret; 435 ret = gpio_direction_input(phy->gpio_vbus_det); 436 if (ret) 437 return ret; 438 } 439 440 phy->gpio_id_det = sunxi_name_to_gpio(info->gpio_id_det); 441 if (phy->gpio_id_det >= 0) { 442 ret = gpio_request(phy->gpio_id_det, "usb_id_det"); 443 if (ret) 444 return ret; 445 ret = gpio_direction_input(phy->gpio_id_det); 446 if (ret) 447 return ret; 448 sunxi_gpio_set_pull(phy->gpio_id_det, SUNXI_GPIO_PULL_UP); 449 } 450 451 if (i || data->cfg->phy0_dual_route) { 452 snprintf(name, sizeof(name), "pmu%d", i); 453 phy->pmu = (void __iomem *)devfdt_get_addr_name(dev, name); 454 if (IS_ERR(phy->pmu)) 455 return PTR_ERR(phy->pmu); 456 } 457 458 phy->id = i; 459 phy->rst_mask = info->rst_mask; 460 if ((data->cfg->type == sun8i_h3_phy) && (phy->id == 3)) 461 phy->rst_mask = (BIT(3) | BIT(11)); 462 }; 463 464 debug("Allwinner Sun4I USB PHY driver loaded\n"); 465 return 0; 466 } 467 468 static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { 469 .num_phys = 3, 470 .type = sun4i_a10_phy, 471 .disc_thresh = 3, 472 .phyctl_offset = REG_PHYCTL_A10, 473 .enable_pmu_unk1 = false, 474 }; 475 476 static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { 477 .num_phys = 2, 478 .type = sun4i_a10_phy, 479 .disc_thresh = 2, 480 .phyctl_offset = REG_PHYCTL_A10, 481 .enable_pmu_unk1 = false, 482 }; 483 484 static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { 485 .num_phys = 3, 486 .type = sun6i_a31_phy, 487 .disc_thresh = 3, 488 .phyctl_offset = REG_PHYCTL_A10, 489 .enable_pmu_unk1 = false, 490 }; 491 492 static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { 493 .num_phys = 3, 494 .type = sun4i_a10_phy, 495 .disc_thresh = 2, 496 .phyctl_offset = REG_PHYCTL_A10, 497 .enable_pmu_unk1 = false, 498 }; 499 500 static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { 501 .num_phys = 2, 502 .type = sun4i_a10_phy, 503 .disc_thresh = 3, 504 .phyctl_offset = REG_PHYCTL_A10, 505 .enable_pmu_unk1 = false, 506 }; 507 508 static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { 509 .num_phys = 2, 510 .type = sun8i_a33_phy, 511 .disc_thresh = 3, 512 .phyctl_offset = REG_PHYCTL_A33, 513 .enable_pmu_unk1 = false, 514 }; 515 516 static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = { 517 .num_phys = 3, 518 .type = sun8i_a83t_phy, 519 .phyctl_offset = REG_PHYCTL_A33, 520 }; 521 522 static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { 523 .num_phys = 4, 524 .type = sun8i_h3_phy, 525 .disc_thresh = 3, 526 .phyctl_offset = REG_PHYCTL_A33, 527 .enable_pmu_unk1 = true, 528 .phy0_dual_route = true, 529 }; 530 531 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { 532 .num_phys = 1, 533 .type = sun8i_v3s_phy, 534 .disc_thresh = 3, 535 .phyctl_offset = REG_PHYCTL_A33, 536 .enable_pmu_unk1 = true, 537 .phy0_dual_route = true, 538 }; 539 540 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { 541 .num_phys = 2, 542 .type = sun50i_a64_phy, 543 .disc_thresh = 3, 544 .phyctl_offset = REG_PHYCTL_A33, 545 .enable_pmu_unk1 = true, 546 .phy0_dual_route = true, 547 }; 548 549 static const struct udevice_id sun4i_usb_phy_ids[] = { 550 { .compatible = "allwinner,sun4i-a10-usb-phy", .data = (ulong)&sun4i_a10_cfg }, 551 { .compatible = "allwinner,sun5i-a13-usb-phy", .data = (ulong)&sun5i_a13_cfg }, 552 { .compatible = "allwinner,sun6i-a31-usb-phy", .data = (ulong)&sun6i_a31_cfg }, 553 { .compatible = "allwinner,sun7i-a20-usb-phy", .data = (ulong)&sun7i_a20_cfg }, 554 { .compatible = "allwinner,sun8i-a23-usb-phy", .data = (ulong)&sun8i_a23_cfg }, 555 { .compatible = "allwinner,sun8i-a33-usb-phy", .data = (ulong)&sun8i_a33_cfg }, 556 { .compatible = "allwinner,sun8i-a83t-usb-phy", .data = (ulong)&sun8i_a83t_cfg }, 557 { .compatible = "allwinner,sun8i-h3-usb-phy", .data = (ulong)&sun8i_h3_cfg }, 558 { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = (ulong)&sun8i_v3s_cfg }, 559 { .compatible = "allwinner,sun50i-a64-usb-phy", .data = (ulong)&sun50i_a64_cfg}, 560 { } 561 }; 562 563 U_BOOT_DRIVER(sun4i_usb_phy) = { 564 .name = "sun4i_usb_phy", 565 .id = UCLASS_PHY, 566 .of_match = sun4i_usb_phy_ids, 567 .ops = &sun4i_usb_phy_ops, 568 .probe = sun4i_usb_phy_probe, 569 .platdata_auto_alloc_size = sizeof(struct sun4i_usb_phy_plat[MAX_PHYS]), 570 .priv_auto_alloc_size = sizeof(struct sun4i_usb_phy_data), 571 }; 572