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 #ifdef CONFIG_MACH_SUN6I 121 .rst_mask = (CCM_USB_CTRL_PHY3_RST | CCM_USB_CTRL_PHY3_CLK), 122 #endif 123 }, 124 }; 125 126 struct sun4i_usb_phy_plat { 127 void __iomem *pmu; 128 int power_on_count; 129 int gpio_vbus; 130 int gpio_vbus_det; 131 int gpio_id_det; 132 int rst_mask; 133 int id; 134 }; 135 136 struct sun4i_usb_phy_data { 137 void __iomem *base; 138 struct sunxi_ccm_reg *ccm; 139 const struct sun4i_usb_phy_cfg *cfg; 140 struct sun4i_usb_phy_plat *usb_phy; 141 }; 142 143 static int initial_usb_scan_delay = CONFIG_INITIAL_USB_SCAN_DELAY; 144 145 static void sun4i_usb_phy_write(struct phy *phy, u32 addr, u32 data, int len) 146 { 147 struct sun4i_usb_phy_data *phy_data = dev_get_priv(phy->dev); 148 struct sun4i_usb_phy_plat *usb_phy = &phy_data->usb_phy[phy->id]; 149 u32 temp, usbc_bit = BIT(usb_phy->id * 2); 150 void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; 151 int i; 152 153 if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) { 154 /* SoCs newer than A33 need us to set phyctl to 0 explicitly */ 155 writel(0, phyctl); 156 } 157 158 for (i = 0; i < len; i++) { 159 temp = readl(phyctl); 160 161 /* clear the address portion */ 162 temp &= ~(0xff << 8); 163 164 /* set the address */ 165 temp |= ((addr + i) << 8); 166 writel(temp, phyctl); 167 168 /* set the data bit and clear usbc bit*/ 169 temp = readb(phyctl); 170 if (data & 0x1) 171 temp |= PHYCTL_DATA; 172 else 173 temp &= ~PHYCTL_DATA; 174 temp &= ~usbc_bit; 175 writeb(temp, phyctl); 176 177 /* pulse usbc_bit */ 178 temp = readb(phyctl); 179 temp |= usbc_bit; 180 writeb(temp, phyctl); 181 182 temp = readb(phyctl); 183 temp &= ~usbc_bit; 184 writeb(temp, phyctl); 185 186 data >>= 1; 187 } 188 } 189 190 static void sun4i_usb_phy_passby(struct phy *phy, bool enable) 191 { 192 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 193 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 194 u32 bits, reg_value; 195 196 if (!usb_phy->pmu) 197 return; 198 199 bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN | 200 SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN; 201 202 /* A83T USB2 is HSIC */ 203 if (data->cfg->type == sun8i_a83t_phy && usb_phy->id == 2) 204 bits |= SUNXI_EHCI_HS_FORCE | SUNXI_HSIC_CONNECT_INT | 205 SUNXI_HSIC; 206 207 reg_value = readl(usb_phy->pmu); 208 209 if (enable) 210 reg_value |= bits; 211 else 212 reg_value &= ~bits; 213 214 writel(reg_value, usb_phy->pmu); 215 } 216 217 static int sun4i_usb_phy_power_on(struct phy *phy) 218 { 219 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 220 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 221 222 if (initial_usb_scan_delay) { 223 mdelay(initial_usb_scan_delay); 224 initial_usb_scan_delay = 0; 225 } 226 227 usb_phy->power_on_count++; 228 if (usb_phy->power_on_count != 1) 229 return 0; 230 231 if (usb_phy->gpio_vbus >= 0) 232 gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_UP); 233 234 return 0; 235 } 236 237 static int sun4i_usb_phy_power_off(struct phy *phy) 238 { 239 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 240 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 241 242 usb_phy->power_on_count--; 243 if (usb_phy->power_on_count != 0) 244 return 0; 245 246 if (usb_phy->gpio_vbus >= 0) 247 gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_DISABLE); 248 249 return 0; 250 } 251 252 static void sun4i_usb_phy0_reroute(struct sun4i_usb_phy_data *data, bool id_det) 253 { 254 u32 regval; 255 256 regval = readl(data->base + REG_PHY_OTGCTL); 257 if (!id_det) { 258 /* Host mode. Route phy0 to EHCI/OHCI */ 259 regval &= ~OTGCTL_ROUTE_MUSB; 260 } else { 261 /* Peripheral mode. Route phy0 to MUSB */ 262 regval |= OTGCTL_ROUTE_MUSB; 263 } 264 writel(regval, data->base + REG_PHY_OTGCTL); 265 } 266 267 static int sun4i_usb_phy_init(struct phy *phy) 268 { 269 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 270 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 271 u32 val; 272 273 setbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask); 274 275 if (data->cfg->type == sun8i_a83t_phy) { 276 if (phy->id == 0) { 277 val = readl(data->base + data->cfg->phyctl_offset); 278 val |= PHY_CTL_VBUSVLDEXT; 279 val &= ~PHY_CTL_SIDDQ; 280 writel(val, data->base + data->cfg->phyctl_offset); 281 } 282 } else { 283 if (usb_phy->pmu && data->cfg->enable_pmu_unk1) { 284 val = readl(usb_phy->pmu + REG_PMU_UNK1); 285 writel(val & ~2, usb_phy->pmu + REG_PMU_UNK1); 286 } 287 288 if (usb_phy->id == 0) 289 sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 290 PHY_RES45_CAL_DATA, 291 PHY_RES45_CAL_LEN); 292 293 /* Adjust PHY's magnitude and rate */ 294 sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 295 PHY_TX_MAGNITUDE | PHY_TX_RATE, 296 PHY_TX_AMPLITUDE_LEN); 297 298 /* Disconnect threshold adjustment */ 299 sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, 300 data->cfg->disc_thresh, PHY_DISCON_TH_LEN); 301 } 302 303 if (usb_phy->id != 0) 304 sun4i_usb_phy_passby(phy, true); 305 306 sun4i_usb_phy0_reroute(data, true); 307 308 return 0; 309 } 310 311 static int sun4i_usb_phy_exit(struct phy *phy) 312 { 313 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 314 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 315 316 if (phy->id == 0) { 317 if (data->cfg->type == sun8i_a83t_phy) { 318 void __iomem *phyctl = data->base + 319 data->cfg->phyctl_offset; 320 321 writel(readl(phyctl) | PHY_CTL_SIDDQ, phyctl); 322 } 323 } 324 325 sun4i_usb_phy_passby(phy, false); 326 327 clrbits_le32(&data->ccm->usb_clk_cfg, usb_phy->rst_mask); 328 329 return 0; 330 } 331 332 static int sun4i_usb_phy_xlate(struct phy *phy, 333 struct ofnode_phandle_args *args) 334 { 335 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 336 337 if (args->args_count >= data->cfg->num_phys) 338 return -EINVAL; 339 340 if (args->args_count) 341 phy->id = args->args[0]; 342 else 343 phy->id = 0; 344 345 debug("%s: phy_id = %ld\n", __func__, phy->id); 346 return 0; 347 } 348 349 int sun4i_usb_phy_vbus_detect(struct phy *phy) 350 { 351 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 352 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 353 int err, retries = 3; 354 355 debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det); 356 357 if (usb_phy->gpio_vbus_det < 0) 358 return usb_phy->gpio_vbus_det; 359 360 err = gpio_get_value(usb_phy->gpio_vbus_det); 361 /* 362 * Vbus may have been provided by the board and just been turned of 363 * some milliseconds ago on reset, what we're measuring then is a 364 * residual charge on Vbus, sleep a bit and try again. 365 */ 366 while (err > 0 && retries--) { 367 mdelay(100); 368 err = gpio_get_value(usb_phy->gpio_vbus_det); 369 } 370 371 return err; 372 } 373 374 int sun4i_usb_phy_id_detect(struct phy *phy) 375 { 376 struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); 377 struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; 378 379 debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det); 380 381 if (usb_phy->gpio_id_det < 0) 382 return usb_phy->gpio_id_det; 383 384 return gpio_get_value(usb_phy->gpio_id_det); 385 } 386 387 void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled) 388 { 389 sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2); 390 } 391 392 static struct phy_ops sun4i_usb_phy_ops = { 393 .of_xlate = sun4i_usb_phy_xlate, 394 .init = sun4i_usb_phy_init, 395 .power_on = sun4i_usb_phy_power_on, 396 .power_off = sun4i_usb_phy_power_off, 397 .exit = sun4i_usb_phy_exit, 398 }; 399 400 static int sun4i_usb_phy_probe(struct udevice *dev) 401 { 402 struct sun4i_usb_phy_plat *plat = dev_get_platdata(dev); 403 struct sun4i_usb_phy_data *data = dev_get_priv(dev); 404 int i, ret; 405 406 data->cfg = (const struct sun4i_usb_phy_cfg *)dev_get_driver_data(dev); 407 if (!data->cfg) 408 return -EINVAL; 409 410 data->base = (void __iomem *)devfdt_get_addr_name(dev, "phy_ctrl"); 411 if (IS_ERR(data->base)) 412 return PTR_ERR(data->base); 413 414 data->ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 415 if (IS_ERR(data->ccm)) 416 return PTR_ERR(data->ccm); 417 418 data->usb_phy = plat; 419 for (i = 0; i < data->cfg->num_phys; i++) { 420 struct sun4i_usb_phy_plat *phy = &plat[i]; 421 struct sun4i_usb_phy_info *info = &phy_info[i]; 422 char name[16]; 423 424 phy->gpio_vbus = sunxi_name_to_gpio(info->gpio_vbus); 425 if (phy->gpio_vbus >= 0) { 426 ret = gpio_request(phy->gpio_vbus, "usb_vbus"); 427 if (ret) 428 return ret; 429 ret = gpio_direction_output(phy->gpio_vbus, 0); 430 if (ret) 431 return ret; 432 } 433 434 phy->gpio_vbus_det = sunxi_name_to_gpio(info->gpio_vbus_det); 435 if (phy->gpio_vbus_det >= 0) { 436 ret = gpio_request(phy->gpio_vbus_det, "usb_vbus_det"); 437 if (ret) 438 return ret; 439 ret = gpio_direction_input(phy->gpio_vbus_det); 440 if (ret) 441 return ret; 442 } 443 444 phy->gpio_id_det = sunxi_name_to_gpio(info->gpio_id_det); 445 if (phy->gpio_id_det >= 0) { 446 ret = gpio_request(phy->gpio_id_det, "usb_id_det"); 447 if (ret) 448 return ret; 449 ret = gpio_direction_input(phy->gpio_id_det); 450 if (ret) 451 return ret; 452 sunxi_gpio_set_pull(phy->gpio_id_det, SUNXI_GPIO_PULL_UP); 453 } 454 455 if (i || data->cfg->phy0_dual_route) { 456 snprintf(name, sizeof(name), "pmu%d", i); 457 phy->pmu = (void __iomem *)devfdt_get_addr_name(dev, name); 458 if (IS_ERR(phy->pmu)) 459 return PTR_ERR(phy->pmu); 460 } 461 462 phy->id = i; 463 phy->rst_mask = info->rst_mask; 464 }; 465 466 setbits_le32(&data->ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE); 467 468 debug("Allwinner Sun4I USB PHY driver loaded\n"); 469 return 0; 470 } 471 472 static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { 473 .num_phys = 3, 474 .type = sun4i_a10_phy, 475 .disc_thresh = 3, 476 .phyctl_offset = REG_PHYCTL_A10, 477 .enable_pmu_unk1 = false, 478 }; 479 480 static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { 481 .num_phys = 2, 482 .type = sun4i_a10_phy, 483 .disc_thresh = 2, 484 .phyctl_offset = REG_PHYCTL_A10, 485 .enable_pmu_unk1 = false, 486 }; 487 488 static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { 489 .num_phys = 3, 490 .type = sun6i_a31_phy, 491 .disc_thresh = 3, 492 .phyctl_offset = REG_PHYCTL_A10, 493 .enable_pmu_unk1 = false, 494 }; 495 496 static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { 497 .num_phys = 3, 498 .type = sun4i_a10_phy, 499 .disc_thresh = 2, 500 .phyctl_offset = REG_PHYCTL_A10, 501 .enable_pmu_unk1 = false, 502 }; 503 504 static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { 505 .num_phys = 2, 506 .type = sun4i_a10_phy, 507 .disc_thresh = 3, 508 .phyctl_offset = REG_PHYCTL_A10, 509 .enable_pmu_unk1 = false, 510 }; 511 512 static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { 513 .num_phys = 2, 514 .type = sun8i_a33_phy, 515 .disc_thresh = 3, 516 .phyctl_offset = REG_PHYCTL_A33, 517 .enable_pmu_unk1 = false, 518 }; 519 520 static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = { 521 .num_phys = 3, 522 .type = sun8i_a83t_phy, 523 .phyctl_offset = REG_PHYCTL_A33, 524 }; 525 526 static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { 527 .num_phys = 4, 528 .type = sun8i_h3_phy, 529 .disc_thresh = 3, 530 .phyctl_offset = REG_PHYCTL_A33, 531 .enable_pmu_unk1 = true, 532 .phy0_dual_route = true, 533 }; 534 535 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { 536 .num_phys = 1, 537 .type = sun8i_v3s_phy, 538 .disc_thresh = 3, 539 .phyctl_offset = REG_PHYCTL_A33, 540 .enable_pmu_unk1 = true, 541 .phy0_dual_route = true, 542 }; 543 544 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { 545 .num_phys = 2, 546 .type = sun50i_a64_phy, 547 .disc_thresh = 3, 548 .phyctl_offset = REG_PHYCTL_A33, 549 .enable_pmu_unk1 = true, 550 .phy0_dual_route = true, 551 }; 552 553 static const struct udevice_id sun4i_usb_phy_ids[] = { 554 { .compatible = "allwinner,sun4i-a10-usb-phy", .data = (ulong)&sun4i_a10_cfg }, 555 { .compatible = "allwinner,sun5i-a13-usb-phy", .data = (ulong)&sun5i_a13_cfg }, 556 { .compatible = "allwinner,sun6i-a31-usb-phy", .data = (ulong)&sun6i_a31_cfg }, 557 { .compatible = "allwinner,sun7i-a20-usb-phy", .data = (ulong)&sun7i_a20_cfg }, 558 { .compatible = "allwinner,sun8i-a23-usb-phy", .data = (ulong)&sun8i_a23_cfg }, 559 { .compatible = "allwinner,sun8i-a33-usb-phy", .data = (ulong)&sun8i_a33_cfg }, 560 { .compatible = "allwinner,sun8i-a83t-usb-phy", .data = (ulong)&sun8i_a83t_cfg }, 561 { .compatible = "allwinner,sun8i-h3-usb-phy", .data = (ulong)&sun8i_h3_cfg }, 562 { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = (ulong)&sun8i_v3s_cfg }, 563 { .compatible = "allwinner,sun50i-a64-usb-phy", .data = (ulong)&sun50i_a64_cfg}, 564 { } 565 }; 566 567 U_BOOT_DRIVER(sun4i_usb_phy) = { 568 .name = "sun4i_usb_phy", 569 .id = UCLASS_PHY, 570 .of_match = sun4i_usb_phy_ids, 571 .ops = &sun4i_usb_phy_ops, 572 .probe = sun4i_usb_phy_probe, 573 .platdata_auto_alloc_size = sizeof(struct sun4i_usb_phy_plat[MAX_PHYS]), 574 .priv_auto_alloc_size = sizeof(struct sun4i_usb_phy_data), 575 }; 576