1 /* 2 * Samsung EXYNOS5 SoC series USB DRD PHY driver 3 * 4 * Phy provider for USB 3.0 DRD controller on Exynos5 SoC series 5 * 6 * Copyright (C) 2014 Samsung Electronics Co., Ltd. 7 * Author: Vivek Gautam <gautam.vivek@samsung.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14 #include <linux/clk.h> 15 #include <linux/delay.h> 16 #include <linux/io.h> 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/of_address.h> 21 #include <linux/of_device.h> 22 #include <linux/phy/phy.h> 23 #include <linux/platform_device.h> 24 #include <linux/mutex.h> 25 #include <linux/mfd/syscon.h> 26 #include <linux/regmap.h> 27 #include <linux/regulator/consumer.h> 28 #include <linux/soc/samsung/exynos-regs-pmu.h> 29 30 /* Exynos USB PHY registers */ 31 #define EXYNOS5_FSEL_9MHZ6 0x0 32 #define EXYNOS5_FSEL_10MHZ 0x1 33 #define EXYNOS5_FSEL_12MHZ 0x2 34 #define EXYNOS5_FSEL_19MHZ2 0x3 35 #define EXYNOS5_FSEL_20MHZ 0x4 36 #define EXYNOS5_FSEL_24MHZ 0x5 37 #define EXYNOS5_FSEL_50MHZ 0x7 38 39 /* EXYNOS5: USB 3.0 DRD PHY registers */ 40 #define EXYNOS5_DRD_LINKSYSTEM 0x04 41 42 #define LINKSYSTEM_FLADJ_MASK (0x3f << 1) 43 #define LINKSYSTEM_FLADJ(_x) ((_x) << 1) 44 #define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27) 45 46 #define EXYNOS5_DRD_PHYUTMI 0x08 47 48 #define PHYUTMI_OTGDISABLE BIT(6) 49 #define PHYUTMI_FORCESUSPEND BIT(1) 50 #define PHYUTMI_FORCESLEEP BIT(0) 51 52 #define EXYNOS5_DRD_PHYPIPE 0x0c 53 54 #define EXYNOS5_DRD_PHYCLKRST 0x10 55 56 #define PHYCLKRST_EN_UTMISUSPEND BIT(31) 57 58 #define PHYCLKRST_SSC_REFCLKSEL_MASK (0xff << 23) 59 #define PHYCLKRST_SSC_REFCLKSEL(_x) ((_x) << 23) 60 61 #define PHYCLKRST_SSC_RANGE_MASK (0x03 << 21) 62 #define PHYCLKRST_SSC_RANGE(_x) ((_x) << 21) 63 64 #define PHYCLKRST_SSC_EN BIT(20) 65 #define PHYCLKRST_REF_SSP_EN BIT(19) 66 #define PHYCLKRST_REF_CLKDIV2 BIT(18) 67 68 #define PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11) 69 #define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11) 70 #define PHYCLKRST_MPLL_MULTIPLIER_50M_REF (0x32 << 11) 71 #define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF (0x68 << 11) 72 #define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF (0x7d << 11) 73 #define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF (0x02 << 11) 74 75 #define PHYCLKRST_FSEL_UTMI_MASK (0x7 << 5) 76 #define PHYCLKRST_FSEL_PIPE_MASK (0x7 << 8) 77 #define PHYCLKRST_FSEL(_x) ((_x) << 5) 78 #define PHYCLKRST_FSEL_PAD_100MHZ (0x27 << 5) 79 #define PHYCLKRST_FSEL_PAD_24MHZ (0x2a << 5) 80 #define PHYCLKRST_FSEL_PAD_20MHZ (0x31 << 5) 81 #define PHYCLKRST_FSEL_PAD_19_2MHZ (0x38 << 5) 82 83 #define PHYCLKRST_RETENABLEN BIT(4) 84 85 #define PHYCLKRST_REFCLKSEL_MASK (0x03 << 2) 86 #define PHYCLKRST_REFCLKSEL_PAD_REFCLK (0x2 << 2) 87 #define PHYCLKRST_REFCLKSEL_EXT_REFCLK (0x3 << 2) 88 89 #define PHYCLKRST_PORTRESET BIT(1) 90 #define PHYCLKRST_COMMONONN BIT(0) 91 92 #define EXYNOS5_DRD_PHYREG0 0x14 93 #define EXYNOS5_DRD_PHYREG1 0x18 94 95 #define EXYNOS5_DRD_PHYPARAM0 0x1c 96 97 #define PHYPARAM0_REF_USE_PAD BIT(31) 98 #define PHYPARAM0_REF_LOSLEVEL_MASK (0x1f << 26) 99 #define PHYPARAM0_REF_LOSLEVEL (0x9 << 26) 100 101 #define EXYNOS5_DRD_PHYPARAM1 0x20 102 103 #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) 104 #define PHYPARAM1_PCS_TXDEEMPH (0x1c) 105 106 #define EXYNOS5_DRD_PHYTERM 0x24 107 108 #define EXYNOS5_DRD_PHYTEST 0x28 109 110 #define PHYTEST_POWERDOWN_SSP BIT(3) 111 #define PHYTEST_POWERDOWN_HSP BIT(2) 112 113 #define EXYNOS5_DRD_PHYADP 0x2c 114 115 #define EXYNOS5_DRD_PHYUTMICLKSEL 0x30 116 117 #define PHYUTMICLKSEL_UTMI_CLKSEL BIT(2) 118 119 #define EXYNOS5_DRD_PHYRESUME 0x34 120 #define EXYNOS5_DRD_LINKPORT 0x44 121 122 #define KHZ 1000 123 #define MHZ (KHZ * KHZ) 124 125 enum exynos5_usbdrd_phy_id { 126 EXYNOS5_DRDPHY_UTMI, 127 EXYNOS5_DRDPHY_PIPE3, 128 EXYNOS5_DRDPHYS_NUM, 129 }; 130 131 struct phy_usb_instance; 132 struct exynos5_usbdrd_phy; 133 134 struct exynos5_usbdrd_phy_config { 135 u32 id; 136 void (*phy_isol)(struct phy_usb_instance *inst, u32 on); 137 void (*phy_init)(struct exynos5_usbdrd_phy *phy_drd); 138 unsigned int (*set_refclk)(struct phy_usb_instance *inst); 139 }; 140 141 struct exynos5_usbdrd_phy_drvdata { 142 const struct exynos5_usbdrd_phy_config *phy_cfg; 143 u32 pmu_offset_usbdrd0_phy; 144 u32 pmu_offset_usbdrd1_phy; 145 bool has_common_clk_gate; 146 }; 147 148 /** 149 * struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY 150 * @dev: pointer to device instance of this platform device 151 * @reg_phy: usb phy controller register memory base 152 * @clk: phy clock for register access 153 * @pipeclk: clock for pipe3 phy 154 * @utmiclk: clock for utmi+ phy 155 * @itpclk: clock for ITP generation 156 * @drv_data: pointer to SoC level driver data structure 157 * @phys[]: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY 158 * instances each with its 'phy' and 'phy_cfg'. 159 * @extrefclk: frequency select settings when using 'separate 160 * reference clocks' for SS and HS operations 161 * @ref_clk: reference clock to PHY block from which PHY's 162 * operational clocks are derived 163 * vbus: VBUS regulator for phy 164 * vbus_boost: Boost regulator for VBUS present on few Exynos boards 165 */ 166 struct exynos5_usbdrd_phy { 167 struct device *dev; 168 void __iomem *reg_phy; 169 struct clk *clk; 170 struct clk *pipeclk; 171 struct clk *utmiclk; 172 struct clk *itpclk; 173 const struct exynos5_usbdrd_phy_drvdata *drv_data; 174 struct phy_usb_instance { 175 struct phy *phy; 176 u32 index; 177 struct regmap *reg_pmu; 178 u32 pmu_offset; 179 const struct exynos5_usbdrd_phy_config *phy_cfg; 180 } phys[EXYNOS5_DRDPHYS_NUM]; 181 u32 extrefclk; 182 struct clk *ref_clk; 183 struct regulator *vbus; 184 struct regulator *vbus_boost; 185 }; 186 187 static inline 188 struct exynos5_usbdrd_phy *to_usbdrd_phy(struct phy_usb_instance *inst) 189 { 190 return container_of((inst), struct exynos5_usbdrd_phy, 191 phys[(inst)->index]); 192 } 193 194 /* 195 * exynos5_rate_to_clk() converts the supplied clock rate to the value that 196 * can be written to the phy register. 197 */ 198 static unsigned int exynos5_rate_to_clk(unsigned long rate, u32 *reg) 199 { 200 /* EXYNOS5_FSEL_MASK */ 201 202 switch (rate) { 203 case 9600 * KHZ: 204 *reg = EXYNOS5_FSEL_9MHZ6; 205 break; 206 case 10 * MHZ: 207 *reg = EXYNOS5_FSEL_10MHZ; 208 break; 209 case 12 * MHZ: 210 *reg = EXYNOS5_FSEL_12MHZ; 211 break; 212 case 19200 * KHZ: 213 *reg = EXYNOS5_FSEL_19MHZ2; 214 break; 215 case 20 * MHZ: 216 *reg = EXYNOS5_FSEL_20MHZ; 217 break; 218 case 24 * MHZ: 219 *reg = EXYNOS5_FSEL_24MHZ; 220 break; 221 case 50 * MHZ: 222 *reg = EXYNOS5_FSEL_50MHZ; 223 break; 224 default: 225 return -EINVAL; 226 } 227 228 return 0; 229 } 230 231 static void exynos5_usbdrd_phy_isol(struct phy_usb_instance *inst, 232 unsigned int on) 233 { 234 unsigned int val; 235 236 if (!inst->reg_pmu) 237 return; 238 239 val = on ? 0 : EXYNOS4_PHY_ENABLE; 240 241 regmap_update_bits(inst->reg_pmu, inst->pmu_offset, 242 EXYNOS4_PHY_ENABLE, val); 243 } 244 245 /* 246 * Sets the pipe3 phy's clk as EXTREFCLK (XXTI) which is internal clock 247 * from clock core. Further sets multiplier values and spread spectrum 248 * clock settings for SuperSpeed operations. 249 */ 250 static unsigned int 251 exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) 252 { 253 u32 reg; 254 struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 255 256 /* restore any previous reference clock settings */ 257 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 258 259 /* Use EXTREFCLK as ref clock */ 260 reg &= ~PHYCLKRST_REFCLKSEL_MASK; 261 reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; 262 263 /* FSEL settings corresponding to reference clock */ 264 reg &= ~PHYCLKRST_FSEL_PIPE_MASK | 265 PHYCLKRST_MPLL_MULTIPLIER_MASK | 266 PHYCLKRST_SSC_REFCLKSEL_MASK; 267 switch (phy_drd->extrefclk) { 268 case EXYNOS5_FSEL_50MHZ: 269 reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | 270 PHYCLKRST_SSC_REFCLKSEL(0x00)); 271 break; 272 case EXYNOS5_FSEL_24MHZ: 273 reg |= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF | 274 PHYCLKRST_SSC_REFCLKSEL(0x88)); 275 break; 276 case EXYNOS5_FSEL_20MHZ: 277 reg |= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF | 278 PHYCLKRST_SSC_REFCLKSEL(0x00)); 279 break; 280 case EXYNOS5_FSEL_19MHZ2: 281 reg |= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF | 282 PHYCLKRST_SSC_REFCLKSEL(0x88)); 283 break; 284 default: 285 dev_dbg(phy_drd->dev, "unsupported ref clk\n"); 286 break; 287 } 288 289 return reg; 290 } 291 292 /* 293 * Sets the utmi phy's clk as EXTREFCLK (XXTI) which is internal clock 294 * from clock core. Further sets the FSEL values for HighSpeed operations. 295 */ 296 static unsigned int 297 exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) 298 { 299 u32 reg; 300 struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 301 302 /* restore any previous reference clock settings */ 303 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 304 305 reg &= ~PHYCLKRST_REFCLKSEL_MASK; 306 reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; 307 308 reg &= ~PHYCLKRST_FSEL_UTMI_MASK | 309 PHYCLKRST_MPLL_MULTIPLIER_MASK | 310 PHYCLKRST_SSC_REFCLKSEL_MASK; 311 reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); 312 313 return reg; 314 } 315 316 static void exynos5_usbdrd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) 317 { 318 u32 reg; 319 320 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 321 /* Set Tx De-Emphasis level */ 322 reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; 323 reg |= PHYPARAM1_PCS_TXDEEMPH; 324 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 325 326 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); 327 reg &= ~PHYTEST_POWERDOWN_SSP; 328 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); 329 } 330 331 static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) 332 { 333 u32 reg; 334 335 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); 336 /* Set Loss-of-Signal Detector sensitivity */ 337 reg &= ~PHYPARAM0_REF_LOSLEVEL_MASK; 338 reg |= PHYPARAM0_REF_LOSLEVEL; 339 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); 340 341 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 342 /* Set Tx De-Emphasis level */ 343 reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; 344 reg |= PHYPARAM1_PCS_TXDEEMPH; 345 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 346 347 /* UTMI Power Control */ 348 writel(PHYUTMI_OTGDISABLE, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); 349 350 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); 351 reg &= ~PHYTEST_POWERDOWN_HSP; 352 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); 353 } 354 355 static int exynos5_usbdrd_phy_init(struct phy *phy) 356 { 357 int ret; 358 u32 reg; 359 struct phy_usb_instance *inst = phy_get_drvdata(phy); 360 struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 361 362 ret = clk_prepare_enable(phy_drd->clk); 363 if (ret) 364 return ret; 365 366 /* Reset USB 3.0 PHY */ 367 writel(0x0, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); 368 writel(0x0, phy_drd->reg_phy + EXYNOS5_DRD_PHYRESUME); 369 370 /* 371 * Setting the Frame length Adj value[6:1] to default 0x20 372 * See xHCI 1.0 spec, 5.2.4 373 */ 374 reg = LINKSYSTEM_XHCI_VERSION_CONTROL | 375 LINKSYSTEM_FLADJ(0x20); 376 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); 377 378 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); 379 /* Select PHY CLK source */ 380 reg &= ~PHYPARAM0_REF_USE_PAD; 381 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); 382 383 /* This bit must be set for both HS and SS operations */ 384 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMICLKSEL); 385 reg |= PHYUTMICLKSEL_UTMI_CLKSEL; 386 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMICLKSEL); 387 388 /* UTMI or PIPE3 specific init */ 389 inst->phy_cfg->phy_init(phy_drd); 390 391 /* reference clock settings */ 392 reg = inst->phy_cfg->set_refclk(inst); 393 394 /* Digital power supply in normal operating mode */ 395 reg |= PHYCLKRST_RETENABLEN | 396 /* Enable ref clock for SS function */ 397 PHYCLKRST_REF_SSP_EN | 398 /* Enable spread spectrum */ 399 PHYCLKRST_SSC_EN | 400 /* Power down HS Bias and PLL blocks in suspend mode */ 401 PHYCLKRST_COMMONONN | 402 /* Reset the port */ 403 PHYCLKRST_PORTRESET; 404 405 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 406 407 udelay(10); 408 409 reg &= ~PHYCLKRST_PORTRESET; 410 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 411 412 clk_disable_unprepare(phy_drd->clk); 413 414 return 0; 415 } 416 417 static int exynos5_usbdrd_phy_exit(struct phy *phy) 418 { 419 int ret; 420 u32 reg; 421 struct phy_usb_instance *inst = phy_get_drvdata(phy); 422 struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 423 424 ret = clk_prepare_enable(phy_drd->clk); 425 if (ret) 426 return ret; 427 428 reg = PHYUTMI_OTGDISABLE | 429 PHYUTMI_FORCESUSPEND | 430 PHYUTMI_FORCESLEEP; 431 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); 432 433 /* Resetting the PHYCLKRST enable bits to reduce leakage current */ 434 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 435 reg &= ~(PHYCLKRST_REF_SSP_EN | 436 PHYCLKRST_SSC_EN | 437 PHYCLKRST_COMMONONN); 438 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 439 440 /* Control PHYTEST to remove leakage current */ 441 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); 442 reg |= PHYTEST_POWERDOWN_SSP | 443 PHYTEST_POWERDOWN_HSP; 444 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); 445 446 clk_disable_unprepare(phy_drd->clk); 447 448 return 0; 449 } 450 451 static int exynos5_usbdrd_phy_power_on(struct phy *phy) 452 { 453 int ret; 454 struct phy_usb_instance *inst = phy_get_drvdata(phy); 455 struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 456 457 dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); 458 459 clk_prepare_enable(phy_drd->ref_clk); 460 if (!phy_drd->drv_data->has_common_clk_gate) { 461 clk_prepare_enable(phy_drd->pipeclk); 462 clk_prepare_enable(phy_drd->utmiclk); 463 clk_prepare_enable(phy_drd->itpclk); 464 } 465 466 /* Enable VBUS supply */ 467 if (phy_drd->vbus_boost) { 468 ret = regulator_enable(phy_drd->vbus_boost); 469 if (ret) { 470 dev_err(phy_drd->dev, 471 "Failed to enable VBUS boost supply\n"); 472 goto fail_vbus; 473 } 474 } 475 476 if (phy_drd->vbus) { 477 ret = regulator_enable(phy_drd->vbus); 478 if (ret) { 479 dev_err(phy_drd->dev, "Failed to enable VBUS supply\n"); 480 goto fail_vbus_boost; 481 } 482 } 483 484 /* Power-on PHY*/ 485 inst->phy_cfg->phy_isol(inst, 0); 486 487 return 0; 488 489 fail_vbus_boost: 490 if (phy_drd->vbus_boost) 491 regulator_disable(phy_drd->vbus_boost); 492 493 fail_vbus: 494 clk_disable_unprepare(phy_drd->ref_clk); 495 if (!phy_drd->drv_data->has_common_clk_gate) { 496 clk_disable_unprepare(phy_drd->itpclk); 497 clk_disable_unprepare(phy_drd->utmiclk); 498 clk_disable_unprepare(phy_drd->pipeclk); 499 } 500 501 return ret; 502 } 503 504 static int exynos5_usbdrd_phy_power_off(struct phy *phy) 505 { 506 struct phy_usb_instance *inst = phy_get_drvdata(phy); 507 struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 508 509 dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n"); 510 511 /* Power-off the PHY */ 512 inst->phy_cfg->phy_isol(inst, 1); 513 514 /* Disable VBUS supply */ 515 if (phy_drd->vbus) 516 regulator_disable(phy_drd->vbus); 517 if (phy_drd->vbus_boost) 518 regulator_disable(phy_drd->vbus_boost); 519 520 clk_disable_unprepare(phy_drd->ref_clk); 521 if (!phy_drd->drv_data->has_common_clk_gate) { 522 clk_disable_unprepare(phy_drd->itpclk); 523 clk_disable_unprepare(phy_drd->pipeclk); 524 clk_disable_unprepare(phy_drd->utmiclk); 525 } 526 527 return 0; 528 } 529 530 static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev, 531 struct of_phandle_args *args) 532 { 533 struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev); 534 535 if (WARN_ON(args->args[0] >= EXYNOS5_DRDPHYS_NUM)) 536 return ERR_PTR(-ENODEV); 537 538 return phy_drd->phys[args->args[0]].phy; 539 } 540 541 static const struct phy_ops exynos5_usbdrd_phy_ops = { 542 .init = exynos5_usbdrd_phy_init, 543 .exit = exynos5_usbdrd_phy_exit, 544 .power_on = exynos5_usbdrd_phy_power_on, 545 .power_off = exynos5_usbdrd_phy_power_off, 546 .owner = THIS_MODULE, 547 }; 548 549 static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) 550 { 551 unsigned long ref_rate; 552 int ret; 553 554 phy_drd->clk = devm_clk_get(phy_drd->dev, "phy"); 555 if (IS_ERR(phy_drd->clk)) { 556 dev_err(phy_drd->dev, "Failed to get phy clock\n"); 557 return PTR_ERR(phy_drd->clk); 558 } 559 560 phy_drd->ref_clk = devm_clk_get(phy_drd->dev, "ref"); 561 if (IS_ERR(phy_drd->ref_clk)) { 562 dev_err(phy_drd->dev, "Failed to get phy reference clock\n"); 563 return PTR_ERR(phy_drd->ref_clk); 564 } 565 ref_rate = clk_get_rate(phy_drd->ref_clk); 566 567 ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); 568 if (ret) { 569 dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", 570 ref_rate); 571 return ret; 572 } 573 574 if (!phy_drd->drv_data->has_common_clk_gate) { 575 phy_drd->pipeclk = devm_clk_get(phy_drd->dev, "phy_pipe"); 576 if (IS_ERR(phy_drd->pipeclk)) { 577 dev_info(phy_drd->dev, 578 "PIPE3 phy operational clock not specified\n"); 579 phy_drd->pipeclk = NULL; 580 } 581 582 phy_drd->utmiclk = devm_clk_get(phy_drd->dev, "phy_utmi"); 583 if (IS_ERR(phy_drd->utmiclk)) { 584 dev_info(phy_drd->dev, 585 "UTMI phy operational clock not specified\n"); 586 phy_drd->utmiclk = NULL; 587 } 588 589 phy_drd->itpclk = devm_clk_get(phy_drd->dev, "itp"); 590 if (IS_ERR(phy_drd->itpclk)) { 591 dev_info(phy_drd->dev, 592 "ITP clock from main OSC not specified\n"); 593 phy_drd->itpclk = NULL; 594 } 595 } 596 597 return 0; 598 } 599 600 static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = { 601 { 602 .id = EXYNOS5_DRDPHY_UTMI, 603 .phy_isol = exynos5_usbdrd_phy_isol, 604 .phy_init = exynos5_usbdrd_utmi_init, 605 .set_refclk = exynos5_usbdrd_utmi_set_refclk, 606 }, 607 { 608 .id = EXYNOS5_DRDPHY_PIPE3, 609 .phy_isol = exynos5_usbdrd_phy_isol, 610 .phy_init = exynos5_usbdrd_pipe3_init, 611 .set_refclk = exynos5_usbdrd_pipe3_set_refclk, 612 }, 613 }; 614 615 static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { 616 .phy_cfg = phy_cfg_exynos5, 617 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, 618 .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, 619 .has_common_clk_gate = true, 620 }; 621 622 static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { 623 .phy_cfg = phy_cfg_exynos5, 624 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, 625 .has_common_clk_gate = true, 626 }; 627 628 static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { 629 .phy_cfg = phy_cfg_exynos5, 630 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, 631 .pmu_offset_usbdrd1_phy = EXYNOS5433_USBHOST30_PHY_CONTROL, 632 .has_common_clk_gate = false, 633 }; 634 635 static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { 636 .phy_cfg = phy_cfg_exynos5, 637 .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, 638 .has_common_clk_gate = false, 639 }; 640 641 static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { 642 { 643 .compatible = "samsung,exynos5250-usbdrd-phy", 644 .data = &exynos5250_usbdrd_phy 645 }, { 646 .compatible = "samsung,exynos5420-usbdrd-phy", 647 .data = &exynos5420_usbdrd_phy 648 }, { 649 .compatible = "samsung,exynos5433-usbdrd-phy", 650 .data = &exynos5433_usbdrd_phy 651 }, { 652 .compatible = "samsung,exynos7-usbdrd-phy", 653 .data = &exynos7_usbdrd_phy 654 }, 655 { }, 656 }; 657 MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match); 658 659 static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) 660 { 661 struct device *dev = &pdev->dev; 662 struct device_node *node = dev->of_node; 663 struct exynos5_usbdrd_phy *phy_drd; 664 struct phy_provider *phy_provider; 665 struct resource *res; 666 const struct exynos5_usbdrd_phy_drvdata *drv_data; 667 struct regmap *reg_pmu; 668 u32 pmu_offset; 669 int i, ret; 670 int channel; 671 672 phy_drd = devm_kzalloc(dev, sizeof(*phy_drd), GFP_KERNEL); 673 if (!phy_drd) 674 return -ENOMEM; 675 676 dev_set_drvdata(dev, phy_drd); 677 phy_drd->dev = dev; 678 679 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 680 phy_drd->reg_phy = devm_ioremap_resource(dev, res); 681 if (IS_ERR(phy_drd->reg_phy)) 682 return PTR_ERR(phy_drd->reg_phy); 683 684 drv_data = of_device_get_match_data(dev); 685 if (!drv_data) 686 return -EINVAL; 687 688 phy_drd->drv_data = drv_data; 689 690 ret = exynos5_usbdrd_phy_clk_handle(phy_drd); 691 if (ret) { 692 dev_err(dev, "Failed to initialize clocks\n"); 693 return ret; 694 } 695 696 reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, 697 "samsung,pmu-syscon"); 698 if (IS_ERR(reg_pmu)) { 699 dev_err(dev, "Failed to lookup PMU regmap\n"); 700 return PTR_ERR(reg_pmu); 701 } 702 703 /* 704 * Exynos5420 SoC has multiple channels for USB 3.0 PHY, with 705 * each having separate power control registers. 706 * 'channel' facilitates to set such registers. 707 */ 708 channel = of_alias_get_id(node, "usbdrdphy"); 709 if (channel < 0) 710 dev_dbg(dev, "Not a multi-controller usbdrd phy\n"); 711 712 switch (channel) { 713 case 1: 714 pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd1_phy; 715 break; 716 case 0: 717 default: 718 pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd0_phy; 719 break; 720 } 721 722 /* Get Vbus regulators */ 723 phy_drd->vbus = devm_regulator_get(dev, "vbus"); 724 if (IS_ERR(phy_drd->vbus)) { 725 ret = PTR_ERR(phy_drd->vbus); 726 if (ret == -EPROBE_DEFER) 727 return ret; 728 729 dev_warn(dev, "Failed to get VBUS supply regulator\n"); 730 phy_drd->vbus = NULL; 731 } 732 733 phy_drd->vbus_boost = devm_regulator_get(dev, "vbus-boost"); 734 if (IS_ERR(phy_drd->vbus_boost)) { 735 ret = PTR_ERR(phy_drd->vbus_boost); 736 if (ret == -EPROBE_DEFER) 737 return ret; 738 739 dev_warn(dev, "Failed to get VBUS boost supply regulator\n"); 740 phy_drd->vbus_boost = NULL; 741 } 742 743 dev_vdbg(dev, "Creating usbdrd_phy phy\n"); 744 745 for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) { 746 struct phy *phy = devm_phy_create(dev, NULL, 747 &exynos5_usbdrd_phy_ops); 748 if (IS_ERR(phy)) { 749 dev_err(dev, "Failed to create usbdrd_phy phy\n"); 750 return PTR_ERR(phy); 751 } 752 753 phy_drd->phys[i].phy = phy; 754 phy_drd->phys[i].index = i; 755 phy_drd->phys[i].reg_pmu = reg_pmu; 756 phy_drd->phys[i].pmu_offset = pmu_offset; 757 phy_drd->phys[i].phy_cfg = &drv_data->phy_cfg[i]; 758 phy_set_drvdata(phy, &phy_drd->phys[i]); 759 } 760 761 phy_provider = devm_of_phy_provider_register(dev, 762 exynos5_usbdrd_phy_xlate); 763 if (IS_ERR(phy_provider)) { 764 dev_err(phy_drd->dev, "Failed to register phy provider\n"); 765 return PTR_ERR(phy_provider); 766 } 767 768 return 0; 769 } 770 771 static struct platform_driver exynos5_usb3drd_phy = { 772 .probe = exynos5_usbdrd_phy_probe, 773 .driver = { 774 .of_match_table = exynos5_usbdrd_phy_of_match, 775 .name = "exynos5_usb3drd_phy", 776 } 777 }; 778 779 module_platform_driver(exynos5_usb3drd_phy); 780 MODULE_DESCRIPTION("Samsung EXYNOS5 SoCs USB 3.0 DRD controller PHY driver"); 781 MODULE_AUTHOR("Vivek Gautam <gautam.vivek@samsung.com>"); 782 MODULE_LICENSE("GPL v2"); 783 MODULE_ALIAS("platform:exynos5_usb3drd_phy"); 784