1/* 2 * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 5250 support 3 * 4 * Copyright (C) 2013 Samsung Electronics Co., Ltd. 5 * Author: Kamil Debski <k.debski@samsung.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/delay.h> 13#include <linux/io.h> 14#include <linux/phy/phy.h> 15#include <linux/regmap.h> 16#include "phy-samsung-usb2.h" 17 18/* Exynos USB PHY registers */ 19#define EXYNOS_5250_REFCLKSEL_CRYSTAL 0x0 20#define EXYNOS_5250_REFCLKSEL_XO 0x1 21#define EXYNOS_5250_REFCLKSEL_CLKCORE 0x2 22 23#define EXYNOS_5250_FSEL_9MHZ6 0x0 24#define EXYNOS_5250_FSEL_10MHZ 0x1 25#define EXYNOS_5250_FSEL_12MHZ 0x2 26#define EXYNOS_5250_FSEL_19MHZ2 0x3 27#define EXYNOS_5250_FSEL_20MHZ 0x4 28#define EXYNOS_5250_FSEL_24MHZ 0x5 29#define EXYNOS_5250_FSEL_50MHZ 0x7 30 31/* Normal host */ 32#define EXYNOS_5250_HOSTPHYCTRL0 0x0 33 34#define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL BIT(31) 35#define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT 19 36#define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_MASK \ 37 (0x3 << EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT) 38#define EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT 16 39#define EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK \ 40 (0x7 << EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT) 41#define EXYNOS_5250_HOSTPHYCTRL0_TESTBURNIN BIT(11) 42#define EXYNOS_5250_HOSTPHYCTRL0_RETENABLE BIT(10) 43#define EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N BIT(9) 44#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_MASK (0x3 << 7) 45#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_DUAL (0x0 << 7) 46#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ID0 (0x1 << 7) 47#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ANALOGTEST (0x2 << 7) 48#define EXYNOS_5250_HOSTPHYCTRL0_SIDDQ BIT(6) 49#define EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP BIT(5) 50#define EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND BIT(4) 51#define EXYNOS_5250_HOSTPHYCTRL0_WORDINTERFACE BIT(3) 52#define EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST BIT(2) 53#define EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST BIT(1) 54#define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST BIT(0) 55 56/* HSIC0 & HSIC1 */ 57#define EXYNOS_5250_HSICPHYCTRL1 0x10 58#define EXYNOS_5250_HSICPHYCTRL2 0x20 59 60#define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_MASK (0x3 << 23) 61#define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT (0x2 << 23) 62#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_MASK (0x7f << 16) 63#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 (0x24 << 16) 64#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_15 (0x1c << 16) 65#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_16 (0x1a << 16) 66#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_19_2 (0x15 << 16) 67#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_20 (0x14 << 16) 68#define EXYNOS_5250_HSICPHYCTRLX_SIDDQ BIT(6) 69#define EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP BIT(5) 70#define EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND BIT(4) 71#define EXYNOS_5250_HSICPHYCTRLX_WORDINTERFACE BIT(3) 72#define EXYNOS_5250_HSICPHYCTRLX_UTMISWRST BIT(2) 73#define EXYNOS_5250_HSICPHYCTRLX_PHYSWRST BIT(0) 74 75/* EHCI control */ 76#define EXYNOS_5250_HOSTEHCICTRL 0x30 77#define EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN BIT(29) 78#define EXYNOS_5250_HOSTEHCICTRL_ENAINCR4 BIT(28) 79#define EXYNOS_5250_HOSTEHCICTRL_ENAINCR8 BIT(27) 80#define EXYNOS_5250_HOSTEHCICTRL_ENAINCR16 BIT(26) 81#define EXYNOS_5250_HOSTEHCICTRL_AUTOPPDONOVRCUREN BIT(25) 82#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT 19 83#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \ 84 (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT) 85#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT 13 86#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_MASK \ 87 (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT) 88#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL2_SHIFT 7 89#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \ 90 (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT) 91#define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT 1 92#define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_MASK \ 93 (0x1 << EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT) 94#define EXYNOS_5250_HOSTEHCICTRL_SIMULATIONMODE BIT(0) 95 96/* OHCI control */ 97#define EXYNOS_5250_HOSTOHCICTRL 0x34 98#define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT 1 99#define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_MASK \ 100 (0x3ff << EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT) 101#define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVALEN BIT(0) 102 103/* USBOTG */ 104#define EXYNOS_5250_USBOTGSYS 0x38 105#define EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET BIT(14) 106#define EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG BIT(13) 107#define EXYNOS_5250_USBOTGSYS_PHY_SW_RST BIT(12) 108#define EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT 9 109#define EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK \ 110 (0x3 << EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT) 111#define EXYNOS_5250_USBOTGSYS_ID_PULLUP BIT(8) 112#define EXYNOS_5250_USBOTGSYS_COMMON_ON BIT(7) 113#define EXYNOS_5250_USBOTGSYS_FSEL_SHIFT 4 114#define EXYNOS_5250_USBOTGSYS_FSEL_MASK \ 115 (0x3 << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT) 116#define EXYNOS_5250_USBOTGSYS_FORCE_SLEEP BIT(3) 117#define EXYNOS_5250_USBOTGSYS_OTGDISABLE BIT(2) 118#define EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG BIT(1) 119#define EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND BIT(0) 120 121/* Isolation, configured in the power management unit */ 122#define EXYNOS_5250_USB_ISOL_OTG_OFFSET 0x704 123#define EXYNOS_5250_USB_ISOL_OTG BIT(0) 124#define EXYNOS_5250_USB_ISOL_HOST_OFFSET 0x708 125#define EXYNOS_5250_USB_ISOL_HOST BIT(0) 126 127/* Mode swtich register */ 128#define EXYNOS_5250_MODE_SWITCH_OFFSET 0x230 129#define EXYNOS_5250_MODE_SWITCH_MASK 1 130#define EXYNOS_5250_MODE_SWITCH_DEVICE 0 131#define EXYNOS_5250_MODE_SWITCH_HOST 1 132 133enum exynos4x12_phy_id { 134 EXYNOS5250_DEVICE, 135 EXYNOS5250_HOST, 136 EXYNOS5250_HSIC0, 137 EXYNOS5250_HSIC1, 138 EXYNOS5250_NUM_PHYS, 139}; 140 141/* 142 * exynos5250_rate_to_clk() converts the supplied clock rate to the value that 143 * can be written to the phy register. 144 */ 145static int exynos5250_rate_to_clk(unsigned long rate, u32 *reg) 146{ 147 /* EXYNOS_5250_FSEL_MASK */ 148 149 switch (rate) { 150 case 9600 * KHZ: 151 *reg = EXYNOS_5250_FSEL_9MHZ6; 152 break; 153 case 10 * MHZ: 154 *reg = EXYNOS_5250_FSEL_10MHZ; 155 break; 156 case 12 * MHZ: 157 *reg = EXYNOS_5250_FSEL_12MHZ; 158 break; 159 case 19200 * KHZ: 160 *reg = EXYNOS_5250_FSEL_19MHZ2; 161 break; 162 case 20 * MHZ: 163 *reg = EXYNOS_5250_FSEL_20MHZ; 164 break; 165 case 24 * MHZ: 166 *reg = EXYNOS_5250_FSEL_24MHZ; 167 break; 168 case 50 * MHZ: 169 *reg = EXYNOS_5250_FSEL_50MHZ; 170 break; 171 default: 172 return -EINVAL; 173 } 174 175 return 0; 176} 177 178static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on) 179{ 180 struct samsung_usb2_phy_driver *drv = inst->drv; 181 u32 offset; 182 u32 mask; 183 184 switch (inst->cfg->id) { 185 case EXYNOS5250_DEVICE: 186 offset = EXYNOS_5250_USB_ISOL_OTG_OFFSET; 187 mask = EXYNOS_5250_USB_ISOL_OTG; 188 break; 189 case EXYNOS5250_HOST: 190 offset = EXYNOS_5250_USB_ISOL_HOST_OFFSET; 191 mask = EXYNOS_5250_USB_ISOL_HOST; 192 break; 193 default: 194 return; 195 }; 196 197 regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); 198} 199 200static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst) 201{ 202 struct samsung_usb2_phy_driver *drv = inst->drv; 203 u32 ctrl0; 204 u32 otg; 205 u32 ehci; 206 u32 ohci; 207 u32 hsic; 208 209 switch (inst->cfg->id) { 210 case EXYNOS5250_DEVICE: 211 regmap_update_bits(drv->reg_sys, 212 EXYNOS_5250_MODE_SWITCH_OFFSET, 213 EXYNOS_5250_MODE_SWITCH_MASK, 214 EXYNOS_5250_MODE_SWITCH_DEVICE); 215 216 /* OTG configuration */ 217 otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); 218 /* The clock */ 219 otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK; 220 otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT; 221 /* Reset */ 222 otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | 223 EXYNOS_5250_USBOTGSYS_FORCE_SLEEP | 224 EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG); 225 otg |= EXYNOS_5250_USBOTGSYS_PHY_SW_RST | 226 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | 227 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | 228 EXYNOS_5250_USBOTGSYS_OTGDISABLE; 229 /* Ref clock */ 230 otg &= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK; 231 otg |= EXYNOS_5250_REFCLKSEL_CLKCORE << 232 EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT; 233 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); 234 udelay(100); 235 otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST | 236 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | 237 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | 238 EXYNOS_5250_USBOTGSYS_OTGDISABLE); 239 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); 240 241 242 break; 243 case EXYNOS5250_HOST: 244 case EXYNOS5250_HSIC0: 245 case EXYNOS5250_HSIC1: 246 /* Host registers configuration */ 247 ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); 248 /* The clock */ 249 ctrl0 &= ~EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK; 250 ctrl0 |= drv->ref_reg_val << 251 EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT; 252 253 /* Reset */ 254 ctrl0 &= ~(EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST | 255 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL | 256 EXYNOS_5250_HOSTPHYCTRL0_SIDDQ | 257 EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND | 258 EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP); 259 ctrl0 |= EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST | 260 EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST | 261 EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N; 262 writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); 263 udelay(10); 264 ctrl0 &= ~(EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST | 265 EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST); 266 writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); 267 268 /* OTG configuration */ 269 otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); 270 /* The clock */ 271 otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK; 272 otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT; 273 /* Reset */ 274 otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | 275 EXYNOS_5250_USBOTGSYS_FORCE_SLEEP | 276 EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG); 277 otg |= EXYNOS_5250_USBOTGSYS_PHY_SW_RST | 278 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | 279 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | 280 EXYNOS_5250_USBOTGSYS_OTGDISABLE; 281 /* Ref clock */ 282 otg &= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK; 283 otg |= EXYNOS_5250_REFCLKSEL_CLKCORE << 284 EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT; 285 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); 286 udelay(10); 287 otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST | 288 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | 289 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET); 290 291 /* HSIC phy configuration */ 292 hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 | 293 EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT | 294 EXYNOS_5250_HSICPHYCTRLX_PHYSWRST); 295 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); 296 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); 297 udelay(10); 298 hsic &= ~EXYNOS_5250_HSICPHYCTRLX_PHYSWRST; 299 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); 300 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); 301 /* The following delay is necessary for the reset sequence to be 302 * completed */ 303 udelay(80); 304 305 /* Enable EHCI DMA burst */ 306 ehci = readl(drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL); 307 ehci |= EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN | 308 EXYNOS_5250_HOSTEHCICTRL_ENAINCR4 | 309 EXYNOS_5250_HOSTEHCICTRL_ENAINCR8 | 310 EXYNOS_5250_HOSTEHCICTRL_ENAINCR16; 311 writel(ehci, drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL); 312 313 /* OHCI settings */ 314 ohci = readl(drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL); 315 /* Following code is based on the old driver */ 316 ohci |= 0x1 << 3; 317 writel(ohci, drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL); 318 319 break; 320 } 321 exynos5250_isol(inst, 0); 322 323 return 0; 324} 325 326static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst) 327{ 328 struct samsung_usb2_phy_driver *drv = inst->drv; 329 u32 ctrl0; 330 u32 otg; 331 u32 hsic; 332 333 exynos5250_isol(inst, 1); 334 335 switch (inst->cfg->id) { 336 case EXYNOS5250_DEVICE: 337 otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); 338 otg |= (EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | 339 EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG | 340 EXYNOS_5250_USBOTGSYS_FORCE_SLEEP); 341 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); 342 break; 343 case EXYNOS5250_HOST: 344 ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); 345 ctrl0 |= (EXYNOS_5250_HOSTPHYCTRL0_SIDDQ | 346 EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND | 347 EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP | 348 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST | 349 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL); 350 writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); 351 break; 352 case EXYNOS5250_HSIC0: 353 case EXYNOS5250_HSIC1: 354 hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 | 355 EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT | 356 EXYNOS_5250_HSICPHYCTRLX_SIDDQ | 357 EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP | 358 EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND 359 ); 360 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); 361 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); 362 break; 363 } 364 365 return 0; 366} 367 368 369static const struct samsung_usb2_common_phy exynos5250_phys[] = { 370 { 371 .label = "device", 372 .id = EXYNOS5250_DEVICE, 373 .power_on = exynos5250_power_on, 374 .power_off = exynos5250_power_off, 375 }, 376 { 377 .label = "host", 378 .id = EXYNOS5250_HOST, 379 .power_on = exynos5250_power_on, 380 .power_off = exynos5250_power_off, 381 }, 382 { 383 .label = "hsic0", 384 .id = EXYNOS5250_HSIC0, 385 .power_on = exynos5250_power_on, 386 .power_off = exynos5250_power_off, 387 }, 388 { 389 .label = "hsic1", 390 .id = EXYNOS5250_HSIC1, 391 .power_on = exynos5250_power_on, 392 .power_off = exynos5250_power_off, 393 }, 394}; 395 396const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = { 397 .has_mode_switch = 1, 398 .num_phys = EXYNOS5250_NUM_PHYS, 399 .phys = exynos5250_phys, 400 .rate_to_clk = exynos5250_rate_to_clk, 401}; 402