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