diff options
| author | Olof Johansson <olof@lixom.net> | 2013-06-14 20:36:30 -0400 |
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2013-06-14 20:36:30 -0400 |
| commit | a1149269646ae95c3985f5cf1c8a15b97bb30d8a (patch) | |
| tree | f56db201ab0328feec913d90b7b60fef7054065a | |
| parent | 5ae13ef4e1045d6ec5d445947b42c839b9731bec (diff) | |
| parent | 1a87b01d3b18709ae240ec90ae612354dd44d9a9 (diff) | |
Merge tag 'renesas-phy-rcar-usb-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/soc
From Simon Horman:
Renesas USB updates for v3.11
These updates are by Sergei Shtylyov to clean-up USB support
present for R8A7779/Marzen and then extend USB support coverage to
R8A7778/BOCK-W.
* tag 'renesas-phy-rcar-usb-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
ARM: shmobile: BOCK-W: add USB support
ARM: shmobile: r8a7778: add USB support
phy-rcar-usb: add R8A7778 support
phy-rcar-usb: handle platform data
ARM: shmobile: Marzen: pass platform data to USB PHY device
phy-rcar-usb: add platform data
phy-rcar-usb: correct base address
ARM: shmobile: r8a7779: remove USB PHY 2nd memory resource
phy-rcar-usb: remove EHCI internal buffer setup
ARM: shmobile: r8a7779: setup EHCI internal buffer
ehci-platform: add pre_setup() method to platform data
ARM: shmobile: Marzen: move USB EHCI, OHCI, and PHY devices to R8A7779 code
Conflicts:
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-shmobile/setup-r8a7778.c
Signed-off-by: Olof Johansson <olof@lixom.net>
| -rw-r--r-- | arch/arm/mach-shmobile/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/board-bockw.c | 8 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/board-marzen.c | 181 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/clock-r8a7778.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/include/mach/r8a7778.h | 3 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/include/mach/r8a7779.h | 3 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/setup-r8a7778.c | 108 | ||||
| -rw-r--r-- | arch/arm/mach-shmobile/setup-r8a7779.c | 196 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-platform.c | 6 | ||||
| -rw-r--r-- | drivers/usb/phy/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-rcar-usb.c | 128 | ||||
| -rw-r--r-- | include/linux/platform_data/usb-rcar-phy.h | 28 | ||||
| -rw-r--r-- | include/linux/usb/ehci_pdriver.h | 4 |
13 files changed, 450 insertions, 231 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 5414402938a5..757c4e97375f 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
| @@ -41,6 +41,8 @@ config ARCH_R8A7778 | |||
| 41 | select CPU_V7 | 41 | select CPU_V7 |
| 42 | select SH_CLK_CPG | 42 | select SH_CLK_CPG |
| 43 | select ARM_GIC | 43 | select ARM_GIC |
| 44 | select USB_ARCH_HAS_EHCI | ||
| 45 | select USB_ARCH_HAS_OHCI | ||
| 44 | 46 | ||
| 45 | config ARCH_R8A7779 | 47 | config ARCH_R8A7779 |
| 46 | bool "R-Car H1 (R8A77790)" | 48 | bool "R-Car H1 (R8A77790)" |
diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index dac4365c5158..7ed2401b899c 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c | |||
| @@ -38,12 +38,18 @@ static struct resource smsc911x_resources[] = { | |||
| 38 | DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */ | 38 | DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */ |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static struct rcar_phy_platform_data usb_phy_platform_data __initdata; | ||
| 42 | |||
| 41 | static const struct pinctrl_map bockw_pinctrl_map[] = { | 43 | static const struct pinctrl_map bockw_pinctrl_map[] = { |
| 42 | /* SCIF0 */ | 44 | /* SCIF0 */ |
| 43 | PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778", | 45 | PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778", |
| 44 | "scif0_data_a", "scif0"), | 46 | "scif0_data_a", "scif0"), |
| 45 | PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778", | 47 | PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778", |
| 46 | "scif0_ctrl", "scif0"), | 48 | "scif0_ctrl", "scif0"), |
| 49 | PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", | ||
| 50 | "usb0", "usb0"), | ||
| 51 | PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", | ||
| 52 | "usb1", "usb1"), | ||
| 47 | }; | 53 | }; |
| 48 | 54 | ||
| 49 | #define IRQ0MR 0x30 | 55 | #define IRQ0MR 0x30 |
| @@ -54,6 +60,7 @@ static void __init bockw_init(void) | |||
| 54 | r8a7778_clock_init(); | 60 | r8a7778_clock_init(); |
| 55 | r8a7778_init_irq_extpin(1); | 61 | r8a7778_init_irq_extpin(1); |
| 56 | r8a7778_add_standard_devices(); | 62 | r8a7778_add_standard_devices(); |
| 63 | r8a7778_add_usb_phy_device(&usb_phy_platform_data); | ||
| 57 | 64 | ||
| 58 | pinctrl_register_mappings(bockw_pinctrl_map, | 65 | pinctrl_register_mappings(bockw_pinctrl_map, |
| 59 | ARRAY_SIZE(bockw_pinctrl_map)); | 66 | ARRAY_SIZE(bockw_pinctrl_map)); |
| @@ -91,4 +98,5 @@ DT_MACHINE_START(BOCKW_DT, "bockw") | |||
| 91 | .init_machine = bockw_init, | 98 | .init_machine = bockw_init, |
| 92 | .init_time = shmobile_timer_init, | 99 | .init_time = shmobile_timer_init, |
| 93 | .dt_compat = bockw_boards_compat_dt, | 100 | .dt_compat = bockw_boards_compat_dt, |
| 101 | .init_late = r8a7778_init_late, | ||
| 94 | MACHINE_END | 102 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 9112faef923b..b1b41b199f99 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c | |||
| @@ -37,10 +37,6 @@ | |||
| 37 | #include <linux/mmc/host.h> | 37 | #include <linux/mmc/host.h> |
| 38 | #include <linux/mmc/sh_mobile_sdhi.h> | 38 | #include <linux/mmc/sh_mobile_sdhi.h> |
| 39 | #include <linux/mfd/tmio.h> | 39 | #include <linux/mfd/tmio.h> |
| 40 | #include <linux/usb/otg.h> | ||
| 41 | #include <linux/usb/ehci_pdriver.h> | ||
| 42 | #include <linux/usb/ohci_pdriver.h> | ||
| 43 | #include <linux/pm_runtime.h> | ||
| 44 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
| 45 | #include <mach/r8a7779.h> | 41 | #include <mach/r8a7779.h> |
| 46 | #include <mach/common.h> | 42 | #include <mach/common.h> |
| @@ -61,6 +57,8 @@ static struct regulator_consumer_supply dummy_supplies[] = { | |||
| 61 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | 57 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), |
| 62 | }; | 58 | }; |
| 63 | 59 | ||
| 60 | static struct rcar_phy_platform_data usb_phy_platform_data __initdata; | ||
| 61 | |||
| 64 | /* SMSC LAN89218 */ | 62 | /* SMSC LAN89218 */ |
| 65 | static struct resource smsc911x_resources[] = { | 63 | static struct resource smsc911x_resources[] = { |
| 66 | [0] = { | 64 | [0] = { |
| @@ -150,26 +148,6 @@ static struct platform_device hspi_device = { | |||
| 150 | .num_resources = ARRAY_SIZE(hspi_resources), | 148 | .num_resources = ARRAY_SIZE(hspi_resources), |
| 151 | }; | 149 | }; |
| 152 | 150 | ||
| 153 | /* USB PHY */ | ||
| 154 | static struct resource usb_phy_resources[] = { | ||
| 155 | [0] = { | ||
| 156 | .start = 0xffe70000, | ||
| 157 | .end = 0xffe70900 - 1, | ||
| 158 | .flags = IORESOURCE_MEM, | ||
| 159 | }, | ||
| 160 | [1] = { | ||
| 161 | .start = 0xfff70000, | ||
| 162 | .end = 0xfff70900 - 1, | ||
| 163 | .flags = IORESOURCE_MEM, | ||
| 164 | }, | ||
| 165 | }; | ||
| 166 | |||
| 167 | static struct platform_device usb_phy_device = { | ||
| 168 | .name = "rcar_usb_phy", | ||
| 169 | .resource = usb_phy_resources, | ||
| 170 | .num_resources = ARRAY_SIZE(usb_phy_resources), | ||
| 171 | }; | ||
| 172 | |||
| 173 | /* LEDS */ | 151 | /* LEDS */ |
| 174 | static struct gpio_led marzen_leds[] = { | 152 | static struct gpio_led marzen_leds[] = { |
| 175 | { | 153 | { |
| @@ -205,161 +183,9 @@ static struct platform_device *marzen_devices[] __initdata = { | |||
| 205 | &sdhi0_device, | 183 | &sdhi0_device, |
| 206 | &thermal_device, | 184 | &thermal_device, |
| 207 | &hspi_device, | 185 | &hspi_device, |
| 208 | &usb_phy_device, | ||
| 209 | &leds_device, | 186 | &leds_device, |
| 210 | }; | 187 | }; |
| 211 | 188 | ||
| 212 | /* USB */ | ||
| 213 | static struct usb_phy *phy; | ||
| 214 | static int usb_power_on(struct platform_device *pdev) | ||
| 215 | { | ||
| 216 | if (IS_ERR(phy)) | ||
| 217 | return PTR_ERR(phy); | ||
| 218 | |||
| 219 | pm_runtime_enable(&pdev->dev); | ||
| 220 | pm_runtime_get_sync(&pdev->dev); | ||
| 221 | |||
| 222 | usb_phy_init(phy); | ||
| 223 | |||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 227 | static void usb_power_off(struct platform_device *pdev) | ||
| 228 | { | ||
| 229 | if (IS_ERR(phy)) | ||
| 230 | return; | ||
| 231 | |||
| 232 | usb_phy_shutdown(phy); | ||
| 233 | |||
| 234 | pm_runtime_put_sync(&pdev->dev); | ||
| 235 | pm_runtime_disable(&pdev->dev); | ||
| 236 | } | ||
| 237 | |||
| 238 | static struct usb_ehci_pdata ehcix_pdata = { | ||
| 239 | .power_on = usb_power_on, | ||
| 240 | .power_off = usb_power_off, | ||
| 241 | .power_suspend = usb_power_off, | ||
| 242 | }; | ||
| 243 | |||
| 244 | static struct resource ehci0_resources[] = { | ||
| 245 | [0] = { | ||
| 246 | .start = 0xffe70000, | ||
| 247 | .end = 0xffe70400 - 1, | ||
| 248 | .flags = IORESOURCE_MEM, | ||
| 249 | }, | ||
| 250 | [1] = { | ||
| 251 | .start = gic_iid(0x4c), | ||
| 252 | .flags = IORESOURCE_IRQ, | ||
| 253 | }, | ||
| 254 | }; | ||
| 255 | |||
| 256 | static struct platform_device ehci0_device = { | ||
| 257 | .name = "ehci-platform", | ||
| 258 | .id = 0, | ||
| 259 | .dev = { | ||
| 260 | .dma_mask = &ehci0_device.dev.coherent_dma_mask, | ||
| 261 | .coherent_dma_mask = 0xffffffff, | ||
| 262 | .platform_data = &ehcix_pdata, | ||
| 263 | }, | ||
| 264 | .num_resources = ARRAY_SIZE(ehci0_resources), | ||
| 265 | .resource = ehci0_resources, | ||
| 266 | }; | ||
| 267 | |||
| 268 | static struct resource ehci1_resources[] = { | ||
| 269 | [0] = { | ||
| 270 | .start = 0xfff70000, | ||
| 271 | .end = 0xfff70400 - 1, | ||
| 272 | .flags = IORESOURCE_MEM, | ||
| 273 | }, | ||
| 274 | [1] = { | ||
| 275 | .start = gic_iid(0x4d), | ||
| 276 | .flags = IORESOURCE_IRQ, | ||
| 277 | }, | ||
| 278 | }; | ||
| 279 | |||
| 280 | static struct platform_device ehci1_device = { | ||
| 281 | .name = "ehci-platform", | ||
| 282 | .id = 1, | ||
| 283 | .dev = { | ||
| 284 | .dma_mask = &ehci1_device.dev.coherent_dma_mask, | ||
| 285 | .coherent_dma_mask = 0xffffffff, | ||
| 286 | .platform_data = &ehcix_pdata, | ||
| 287 | }, | ||
| 288 | .num_resources = ARRAY_SIZE(ehci1_resources), | ||
| 289 | .resource = ehci1_resources, | ||
| 290 | }; | ||
| 291 | |||
| 292 | static struct usb_ohci_pdata ohcix_pdata = { | ||
| 293 | .power_on = usb_power_on, | ||
| 294 | .power_off = usb_power_off, | ||
| 295 | .power_suspend = usb_power_off, | ||
| 296 | }; | ||
| 297 | |||
| 298 | static struct resource ohci0_resources[] = { | ||
| 299 | [0] = { | ||
| 300 | .start = 0xffe70400, | ||
| 301 | .end = 0xffe70800 - 1, | ||
| 302 | .flags = IORESOURCE_MEM, | ||
| 303 | }, | ||
| 304 | [1] = { | ||
| 305 | .start = gic_iid(0x4c), | ||
| 306 | .flags = IORESOURCE_IRQ, | ||
| 307 | }, | ||
| 308 | }; | ||
| 309 | |||
| 310 | static struct platform_device ohci0_device = { | ||
| 311 | .name = "ohci-platform", | ||
| 312 | .id = 0, | ||
| 313 | .dev = { | ||
| 314 | .dma_mask = &ohci0_device.dev.coherent_dma_mask, | ||
| 315 | .coherent_dma_mask = 0xffffffff, | ||
| 316 | .platform_data = &ohcix_pdata, | ||
| 317 | }, | ||
| 318 | .num_resources = ARRAY_SIZE(ohci0_resources), | ||
| 319 | .resource = ohci0_resources, | ||
| 320 | }; | ||
| 321 | |||
| 322 | static struct resource ohci1_resources[] = { | ||
| 323 | [0] = { | ||
| 324 | .start = 0xfff70400, | ||
| 325 | .end = 0xfff70800 - 1, | ||
| 326 | .flags = IORESOURCE_MEM, | ||
| 327 | }, | ||
| 328 | [1] = { | ||
| 329 | .start = gic_iid(0x4d), | ||
| 330 | .flags = IORESOURCE_IRQ, | ||
| 331 | }, | ||
| 332 | }; | ||
| 333 | |||
| 334 | static struct platform_device ohci1_device = { | ||
| 335 | .name = "ohci-platform", | ||
| 336 | .id = 1, | ||
| 337 | .dev = { | ||
| 338 | .dma_mask = &ohci1_device.dev.coherent_dma_mask, | ||
| 339 | .coherent_dma_mask = 0xffffffff, | ||
| 340 | .platform_data = &ohcix_pdata, | ||
| 341 | }, | ||
| 342 | .num_resources = ARRAY_SIZE(ohci1_resources), | ||
| 343 | .resource = ohci1_resources, | ||
| 344 | }; | ||
| 345 | |||
| 346 | static struct platform_device *marzen_late_devices[] __initdata = { | ||
| 347 | &ehci0_device, | ||
| 348 | &ehci1_device, | ||
| 349 | &ohci0_device, | ||
| 350 | &ohci1_device, | ||
| 351 | }; | ||
| 352 | |||
| 353 | void __init marzen_init_late(void) | ||
| 354 | { | ||
| 355 | /* get usb phy */ | ||
| 356 | phy = usb_get_phy(USB_PHY_TYPE_USB2); | ||
| 357 | |||
| 358 | shmobile_init_late(); | ||
| 359 | platform_add_devices(marzen_late_devices, | ||
| 360 | ARRAY_SIZE(marzen_late_devices)); | ||
| 361 | } | ||
| 362 | |||
| 363 | static const struct pinctrl_map marzen_pinctrl_map[] = { | 189 | static const struct pinctrl_map marzen_pinctrl_map[] = { |
| 364 | /* HSPI0 */ | 190 | /* HSPI0 */ |
| 365 | PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779", | 191 | PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779", |
| @@ -407,6 +233,7 @@ static void __init marzen_init(void) | |||
| 407 | r8a7779_pinmux_init(); | 233 | r8a7779_pinmux_init(); |
| 408 | 234 | ||
| 409 | r8a7779_add_standard_devices(); | 235 | r8a7779_add_standard_devices(); |
| 236 | r8a7779_add_usb_phy_device(&usb_phy_platform_data); | ||
| 410 | platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); | 237 | platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); |
| 411 | } | 238 | } |
| 412 | 239 | ||
| @@ -417,6 +244,6 @@ MACHINE_START(MARZEN, "marzen") | |||
| 417 | .nr_irqs = NR_IRQS_LEGACY, | 244 | .nr_irqs = NR_IRQS_LEGACY, |
| 418 | .init_irq = r8a7779_init_irq, | 245 | .init_irq = r8a7779_init_irq, |
| 419 | .init_machine = marzen_init, | 246 | .init_machine = marzen_init, |
| 420 | .init_late = marzen_init_late, | 247 | .init_late = r8a7779_init_late, |
| 421 | .init_time = r8a7779_earlytimer_init, | 248 | .init_time = r8a7779_earlytimer_init, |
| 422 | MACHINE_END | 249 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index b251e4d0924d..696d206adc3f 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c | |||
| @@ -105,6 +105,7 @@ static struct clk *main_clks[] = { | |||
| 105 | enum { | 105 | enum { |
| 106 | MSTP323, MSTP322, MSTP321, | 106 | MSTP323, MSTP322, MSTP321, |
| 107 | MSTP114, | 107 | MSTP114, |
| 108 | MSTP100, | ||
| 108 | MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, | 109 | MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, |
| 109 | MSTP016, MSTP015, | 110 | MSTP016, MSTP015, |
| 110 | MSTP_NR }; | 111 | MSTP_NR }; |
| @@ -114,6 +115,7 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
| 114 | [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ | 115 | [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ |
| 115 | [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ | 116 | [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ |
| 116 | [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ | 117 | [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ |
| 118 | [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 0, 0), /* USB0/1 */ | ||
| 117 | [MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */ | 119 | [MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */ |
| 118 | [MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */ | 120 | [MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */ |
| 119 | [MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */ | 121 | [MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */ |
| @@ -130,6 +132,8 @@ static struct clk_lookup lookups[] = { | |||
| 130 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ | 132 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ |
| 131 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ | 133 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ |
| 132 | CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */ | 134 | CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */ |
| 135 | CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ | ||
| 136 | CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ | ||
| 133 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */ | 137 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */ |
| 134 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */ | 138 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */ |
| 135 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */ | 139 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */ |
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index ae65b459483f..1d4207cc0b04 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h | |||
| @@ -20,10 +20,13 @@ | |||
| 20 | 20 | ||
| 21 | #include <linux/mmc/sh_mobile_sdhi.h> | 21 | #include <linux/mmc/sh_mobile_sdhi.h> |
| 22 | #include <linux/sh_eth.h> | 22 | #include <linux/sh_eth.h> |
| 23 | #include <linux/platform_data/usb-rcar-phy.h> | ||
| 23 | 24 | ||
| 24 | extern void r8a7778_add_standard_devices(void); | 25 | extern void r8a7778_add_standard_devices(void); |
| 25 | extern void r8a7778_add_standard_devices_dt(void); | 26 | extern void r8a7778_add_standard_devices_dt(void); |
| 26 | extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); | 27 | extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); |
| 28 | extern void r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata); | ||
| 29 | extern void r8a7778_init_late(void); | ||
| 27 | extern void r8a7778_init_delay(void); | 30 | extern void r8a7778_init_delay(void); |
| 28 | extern void r8a7778_init_irq(void); | 31 | extern void r8a7778_init_irq(void); |
| 29 | extern void r8a7778_init_irq_dt(void); | 32 | extern void r8a7778_init_irq_dt(void); |
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index 188b295938a5..fc47073c7ba9 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/sh_clk.h> | 4 | #include <linux/sh_clk.h> |
| 5 | #include <linux/pm_domain.h> | 5 | #include <linux/pm_domain.h> |
| 6 | #include <linux/sh_eth.h> | 6 | #include <linux/sh_eth.h> |
| 7 | #include <linux/platform_data/usb-rcar-phy.h> | ||
| 7 | 8 | ||
| 8 | struct platform_device; | 9 | struct platform_device; |
| 9 | 10 | ||
| @@ -33,6 +34,8 @@ extern void r8a7779_add_early_devices(void); | |||
| 33 | extern void r8a7779_add_standard_devices(void); | 34 | extern void r8a7779_add_standard_devices(void); |
| 34 | extern void r8a7779_add_standard_devices_dt(void); | 35 | extern void r8a7779_add_standard_devices_dt(void); |
| 35 | extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata); | 36 | extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata); |
| 37 | extern void r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata); | ||
| 38 | extern void r8a7779_init_late(void); | ||
| 36 | extern void r8a7779_clock_init(void); | 39 | extern void r8a7779_clock_init(void); |
| 37 | extern void r8a7779_pinmux_init(void); | 40 | extern void r8a7779_pinmux_init(void); |
| 38 | extern void r8a7779_pm_init(void); | 41 | extern void r8a7779_pm_init(void); |
diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 1b9b7f2a5016..f84885a71f6f 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c | |||
| @@ -30,6 +30,12 @@ | |||
| 30 | #include <linux/irqchip.h> | 30 | #include <linux/irqchip.h> |
| 31 | #include <linux/serial_sci.h> | 31 | #include <linux/serial_sci.h> |
| 32 | #include <linux/sh_timer.h> | 32 | #include <linux/sh_timer.h> |
| 33 | #include <linux/pm_runtime.h> | ||
| 34 | #include <linux/usb/phy.h> | ||
| 35 | #include <linux/usb/hcd.h> | ||
| 36 | #include <linux/usb/ehci_pdriver.h> | ||
| 37 | #include <linux/usb/ohci_pdriver.h> | ||
| 38 | #include <linux/dma-mapping.h> | ||
| 33 | #include <mach/irqs.h> | 39 | #include <mach/irqs.h> |
| 34 | #include <mach/r8a7778.h> | 40 | #include <mach/r8a7778.h> |
| 35 | #include <mach/common.h> | 41 | #include <mach/common.h> |
| @@ -89,6 +95,99 @@ static struct sh_timer_config sh_tmu1_platform_data = { | |||
| 89 | &sh_tmu##idx##_platform_data, \ | 95 | &sh_tmu##idx##_platform_data, \ |
| 90 | sizeof(sh_tmu##idx##_platform_data)) | 96 | sizeof(sh_tmu##idx##_platform_data)) |
| 91 | 97 | ||
| 98 | /* USB PHY */ | ||
| 99 | static struct resource usb_phy_resources[] __initdata = { | ||
| 100 | DEFINE_RES_MEM(0xffe70800, 0x100), | ||
| 101 | DEFINE_RES_MEM(0xffe76000, 0x100), | ||
| 102 | }; | ||
| 103 | |||
| 104 | void __init r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata) | ||
| 105 | { | ||
| 106 | platform_device_register_resndata(&platform_bus, "rcar_usb_phy", -1, | ||
| 107 | usb_phy_resources, | ||
| 108 | ARRAY_SIZE(usb_phy_resources), | ||
| 109 | pdata, sizeof(*pdata)); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* USB */ | ||
| 113 | static struct usb_phy *phy; | ||
| 114 | |||
| 115 | static int usb_power_on(struct platform_device *pdev) | ||
| 116 | { | ||
| 117 | if (IS_ERR(phy)) | ||
| 118 | return PTR_ERR(phy); | ||
| 119 | |||
| 120 | pm_runtime_enable(&pdev->dev); | ||
| 121 | pm_runtime_get_sync(&pdev->dev); | ||
| 122 | |||
| 123 | usb_phy_init(phy); | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void usb_power_off(struct platform_device *pdev) | ||
| 129 | { | ||
| 130 | if (IS_ERR(phy)) | ||
| 131 | return; | ||
| 132 | |||
| 133 | usb_phy_shutdown(phy); | ||
| 134 | |||
| 135 | pm_runtime_put_sync(&pdev->dev); | ||
| 136 | pm_runtime_disable(&pdev->dev); | ||
| 137 | } | ||
| 138 | |||
| 139 | static int ehci_init_internal_buffer(struct usb_hcd *hcd) | ||
| 140 | { | ||
| 141 | /* | ||
| 142 | * Below are recommended values from the datasheet; | ||
| 143 | * see [USB :: Setting of EHCI Internal Buffer]. | ||
| 144 | */ | ||
| 145 | /* EHCI IP internal buffer setting */ | ||
| 146 | iowrite32(0x00ff0040, hcd->regs + 0x0094); | ||
| 147 | /* EHCI IP internal buffer enable */ | ||
| 148 | iowrite32(0x00000001, hcd->regs + 0x009C); | ||
| 149 | |||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | static struct usb_ehci_pdata ehci_pdata __initdata = { | ||
| 154 | .power_on = usb_power_on, | ||
| 155 | .power_off = usb_power_off, | ||
| 156 | .power_suspend = usb_power_off, | ||
| 157 | .pre_setup = ehci_init_internal_buffer, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static struct resource ehci_resources[] __initdata = { | ||
| 161 | DEFINE_RES_MEM(0xffe70000, 0x400), | ||
| 162 | DEFINE_RES_IRQ(gic_iid(0x4c)), | ||
| 163 | }; | ||
| 164 | |||
| 165 | static struct usb_ohci_pdata ohci_pdata __initdata = { | ||
| 166 | .power_on = usb_power_on, | ||
| 167 | .power_off = usb_power_off, | ||
| 168 | .power_suspend = usb_power_off, | ||
| 169 | }; | ||
| 170 | |||
| 171 | static struct resource ohci_resources[] __initdata = { | ||
| 172 | DEFINE_RES_MEM(0xffe70400, 0x400), | ||
| 173 | DEFINE_RES_IRQ(gic_iid(0x4c)), | ||
| 174 | }; | ||
| 175 | |||
| 176 | #define USB_PLATFORM_INFO(hci) \ | ||
| 177 | static struct platform_device_info hci##_info __initdata = { \ | ||
| 178 | .parent = &platform_bus, \ | ||
| 179 | .name = #hci "-platform", \ | ||
| 180 | .id = -1, \ | ||
| 181 | .res = hci##_resources, \ | ||
| 182 | .num_res = ARRAY_SIZE(hci##_resources), \ | ||
| 183 | .data = &hci##_pdata, \ | ||
| 184 | .size_data = sizeof(hci##_pdata), \ | ||
| 185 | .dma_mask = DMA_BIT_MASK(32), \ | ||
| 186 | } | ||
| 187 | |||
| 188 | USB_PLATFORM_INFO(ehci); | ||
| 189 | USB_PLATFORM_INFO(ohci); | ||
| 190 | |||
| 92 | /* Ether */ | 191 | /* Ether */ |
| 93 | static struct resource ether_resources[] = { | 192 | static struct resource ether_resources[] = { |
| 94 | DEFINE_RES_MEM(0xfde00000, 0x400), | 193 | DEFINE_RES_MEM(0xfde00000, 0x400), |
| @@ -197,6 +296,14 @@ void __init r8a7778_add_standard_devices(void) | |||
| 197 | r8a7778_register_tmu(1); | 296 | r8a7778_register_tmu(1); |
| 198 | } | 297 | } |
| 199 | 298 | ||
| 299 | void __init r8a7778_init_late(void) | ||
| 300 | { | ||
| 301 | phy = usb_get_phy(USB_PHY_TYPE_USB2); | ||
| 302 | |||
| 303 | platform_device_register_full(&ehci_info); | ||
| 304 | platform_device_register_full(&ohci_info); | ||
| 305 | } | ||
| 306 | |||
| 200 | static struct renesas_intc_irqpin_config irqpin_platform_data = { | 307 | static struct renesas_intc_irqpin_config irqpin_platform_data = { |
| 201 | .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ | 308 | .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ |
| 202 | .sense_bitfield_width = 2, | 309 | .sense_bitfield_width = 2, |
| @@ -310,6 +417,7 @@ DT_MACHINE_START(R8A7778_DT, "Generic R8A7778 (Flattened Device Tree)") | |||
| 310 | .init_machine = r8a7778_add_standard_devices_dt, | 417 | .init_machine = r8a7778_add_standard_devices_dt, |
| 311 | .init_time = shmobile_timer_init, | 418 | .init_time = shmobile_timer_init, |
| 312 | .dt_compat = r8a7778_compat_dt, | 419 | .dt_compat = r8a7778_compat_dt, |
| 420 | .init_late = r8a7778_init_late, | ||
| 313 | MACHINE_END | 421 | MACHINE_END |
| 314 | 422 | ||
| 315 | #endif /* CONFIG_USE_OF */ | 423 | #endif /* CONFIG_USE_OF */ |
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index dbb13f289e79..06804a1eb1eb 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c | |||
| @@ -32,6 +32,11 @@ | |||
| 32 | #include <linux/sh_intc.h> | 32 | #include <linux/sh_intc.h> |
| 33 | #include <linux/sh_timer.h> | 33 | #include <linux/sh_timer.h> |
| 34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
| 35 | #include <linux/usb/otg.h> | ||
| 36 | #include <linux/usb/hcd.h> | ||
| 37 | #include <linux/usb/ehci_pdriver.h> | ||
| 38 | #include <linux/usb/ohci_pdriver.h> | ||
| 39 | #include <linux/pm_runtime.h> | ||
| 35 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
| 36 | #include <mach/irqs.h> | 41 | #include <mach/irqs.h> |
| 37 | #include <mach/r8a7779.h> | 42 | #include <mach/r8a7779.h> |
| @@ -383,6 +388,165 @@ static struct platform_device sata_device = { | |||
| 383 | }, | 388 | }, |
| 384 | }; | 389 | }; |
| 385 | 390 | ||
| 391 | /* USB PHY */ | ||
| 392 | static struct resource usb_phy_resources[] __initdata = { | ||
| 393 | [0] = { | ||
| 394 | .start = 0xffe70800, | ||
| 395 | .end = 0xffe70900 - 1, | ||
| 396 | .flags = IORESOURCE_MEM, | ||
| 397 | }, | ||
| 398 | }; | ||
| 399 | |||
| 400 | /* USB */ | ||
| 401 | static struct usb_phy *phy; | ||
| 402 | |||
| 403 | static int usb_power_on(struct platform_device *pdev) | ||
| 404 | { | ||
| 405 | if (IS_ERR(phy)) | ||
| 406 | return PTR_ERR(phy); | ||
| 407 | |||
| 408 | pm_runtime_enable(&pdev->dev); | ||
| 409 | pm_runtime_get_sync(&pdev->dev); | ||
| 410 | |||
| 411 | usb_phy_init(phy); | ||
| 412 | |||
| 413 | return 0; | ||
| 414 | } | ||
| 415 | |||
| 416 | static void usb_power_off(struct platform_device *pdev) | ||
| 417 | { | ||
| 418 | if (IS_ERR(phy)) | ||
| 419 | return; | ||
| 420 | |||
| 421 | usb_phy_shutdown(phy); | ||
| 422 | |||
| 423 | pm_runtime_put_sync(&pdev->dev); | ||
| 424 | pm_runtime_disable(&pdev->dev); | ||
| 425 | } | ||
| 426 | |||
| 427 | static int ehci_init_internal_buffer(struct usb_hcd *hcd) | ||
| 428 | { | ||
| 429 | /* | ||
| 430 | * Below are recommended values from the datasheet; | ||
| 431 | * see [USB :: Setting of EHCI Internal Buffer]. | ||
| 432 | */ | ||
| 433 | /* EHCI IP internal buffer setting */ | ||
| 434 | iowrite32(0x00ff0040, hcd->regs + 0x0094); | ||
| 435 | /* EHCI IP internal buffer enable */ | ||
| 436 | iowrite32(0x00000001, hcd->regs + 0x009C); | ||
| 437 | |||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | |||
| 441 | static struct usb_ehci_pdata ehcix_pdata = { | ||
| 442 | .power_on = usb_power_on, | ||
| 443 | .power_off = usb_power_off, | ||
| 444 | .power_suspend = usb_power_off, | ||
| 445 | .pre_setup = ehci_init_internal_buffer, | ||
| 446 | }; | ||
| 447 | |||
| 448 | static struct resource ehci0_resources[] = { | ||
| 449 | [0] = { | ||
| 450 | .start = 0xffe70000, | ||
| 451 | .end = 0xffe70400 - 1, | ||
| 452 | .flags = IORESOURCE_MEM, | ||
| 453 | }, | ||
| 454 | [1] = { | ||
| 455 | .start = gic_iid(0x4c), | ||
| 456 | .flags = IORESOURCE_IRQ, | ||
| 457 | }, | ||
| 458 | }; | ||
| 459 | |||
| 460 | static struct platform_device ehci0_device = { | ||
| 461 | .name = "ehci-platform", | ||
| 462 | .id = 0, | ||
| 463 | .dev = { | ||
| 464 | .dma_mask = &ehci0_device.dev.coherent_dma_mask, | ||
| 465 | .coherent_dma_mask = 0xffffffff, | ||
| 466 | .platform_data = &ehcix_pdata, | ||
| 467 | }, | ||
| 468 | .num_resources = ARRAY_SIZE(ehci0_resources), | ||
| 469 | .resource = ehci0_resources, | ||
| 470 | }; | ||
| 471 | |||
| 472 | static struct resource ehci1_resources[] = { | ||
| 473 | [0] = { | ||
| 474 | .start = 0xfff70000, | ||
| 475 | .end = 0xfff70400 - 1, | ||
| 476 | .flags = IORESOURCE_MEM, | ||
| 477 | }, | ||
| 478 | [1] = { | ||
| 479 | .start = gic_iid(0x4d), | ||
| 480 | .flags = IORESOURCE_IRQ, | ||
| 481 | }, | ||
| 482 | }; | ||
| 483 | |||
| 484 | static struct platform_device ehci1_device = { | ||
| 485 | .name = "ehci-platform", | ||
| 486 | .id = 1, | ||
| 487 | .dev = { | ||
| 488 | .dma_mask = &ehci1_device.dev.coherent_dma_mask, | ||
| 489 | .coherent_dma_mask = 0xffffffff, | ||
| 490 | .platform_data = &ehcix_pdata, | ||
| 491 | }, | ||
| 492 | .num_resources = ARRAY_SIZE(ehci1_resources), | ||
| 493 | .resource = ehci1_resources, | ||
| 494 | }; | ||
| 495 | |||
| 496 | static struct usb_ohci_pdata ohcix_pdata = { | ||
| 497 | .power_on = usb_power_on, | ||
| 498 | .power_off = usb_power_off, | ||
| 499 | .power_suspend = usb_power_off, | ||
| 500 | }; | ||
| 501 | |||
| 502 | static struct resource ohci0_resources[] = { | ||
| 503 | [0] = { | ||
| 504 | .start = 0xffe70400, | ||
| 505 | .end = 0xffe70800 - 1, | ||
| 506 | .flags = IORESOURCE_MEM, | ||
| 507 | }, | ||
| 508 | [1] = { | ||
| 509 | .start = gic_iid(0x4c), | ||
| 510 | .flags = IORESOURCE_IRQ, | ||
| 511 | }, | ||
| 512 | }; | ||
| 513 | |||
| 514 | static struct platform_device ohci0_device = { | ||
| 515 | .name = "ohci-platform", | ||
| 516 | .id = 0, | ||
| 517 | .dev = { | ||
| 518 | .dma_mask = &ohci0_device.dev.coherent_dma_mask, | ||
| 519 | .coherent_dma_mask = 0xffffffff, | ||
| 520 | .platform_data = &ohcix_pdata, | ||
| 521 | }, | ||
| 522 | .num_resources = ARRAY_SIZE(ohci0_resources), | ||
| 523 | .resource = ohci0_resources, | ||
| 524 | }; | ||
| 525 | |||
| 526 | static struct resource ohci1_resources[] = { | ||
| 527 | [0] = { | ||
| 528 | .start = 0xfff70400, | ||
| 529 | .end = 0xfff70800 - 1, | ||
| 530 | .flags = IORESOURCE_MEM, | ||
| 531 | }, | ||
| 532 | [1] = { | ||
| 533 | .start = gic_iid(0x4d), | ||
| 534 | .flags = IORESOURCE_IRQ, | ||
| 535 | }, | ||
| 536 | }; | ||
| 537 | |||
| 538 | static struct platform_device ohci1_device = { | ||
| 539 | .name = "ohci-platform", | ||
| 540 | .id = 1, | ||
| 541 | .dev = { | ||
| 542 | .dma_mask = &ohci1_device.dev.coherent_dma_mask, | ||
| 543 | .coherent_dma_mask = 0xffffffff, | ||
| 544 | .platform_data = &ohcix_pdata, | ||
| 545 | }, | ||
| 546 | .num_resources = ARRAY_SIZE(ohci1_resources), | ||
| 547 | .resource = ohci1_resources, | ||
| 548 | }; | ||
| 549 | |||
| 386 | /* Ether */ | 550 | /* Ether */ |
| 387 | static struct resource ether_resources[] = { | 551 | static struct resource ether_resources[] = { |
| 388 | { | 552 | { |
| @@ -406,7 +570,7 @@ static struct platform_device *r8a7779_devices_dt[] __initdata = { | |||
| 406 | &tmu01_device, | 570 | &tmu01_device, |
| 407 | }; | 571 | }; |
| 408 | 572 | ||
| 409 | static struct platform_device *r8a7779_late_devices[] __initdata = { | 573 | static struct platform_device *r8a7779_standard_devices[] __initdata = { |
| 410 | &i2c0_device, | 574 | &i2c0_device, |
| 411 | &i2c1_device, | 575 | &i2c1_device, |
| 412 | &i2c2_device, | 576 | &i2c2_device, |
| @@ -426,8 +590,8 @@ void __init r8a7779_add_standard_devices(void) | |||
| 426 | 590 | ||
| 427 | platform_add_devices(r8a7779_devices_dt, | 591 | platform_add_devices(r8a7779_devices_dt, |
| 428 | ARRAY_SIZE(r8a7779_devices_dt)); | 592 | ARRAY_SIZE(r8a7779_devices_dt)); |
| 429 | platform_add_devices(r8a7779_late_devices, | 593 | platform_add_devices(r8a7779_standard_devices, |
| 430 | ARRAY_SIZE(r8a7779_late_devices)); | 594 | ARRAY_SIZE(r8a7779_standard_devices)); |
| 431 | } | 595 | } |
| 432 | 596 | ||
| 433 | void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) | 597 | void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) |
| @@ -438,6 +602,14 @@ void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) | |||
| 438 | pdata, sizeof(*pdata)); | 602 | pdata, sizeof(*pdata)); |
| 439 | } | 603 | } |
| 440 | 604 | ||
| 605 | void __init r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata) | ||
| 606 | { | ||
| 607 | platform_device_register_resndata(&platform_bus, "rcar_usb_phy", -1, | ||
| 608 | usb_phy_resources, | ||
| 609 | ARRAY_SIZE(usb_phy_resources), | ||
| 610 | pdata, sizeof(*pdata)); | ||
| 611 | } | ||
| 612 | |||
| 441 | /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ | 613 | /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ |
| 442 | void __init __weak r8a7779_register_twd(void) { } | 614 | void __init __weak r8a7779_register_twd(void) { } |
| 443 | 615 | ||
| @@ -470,6 +642,23 @@ void __init r8a7779_add_early_devices(void) | |||
| 470 | */ | 642 | */ |
| 471 | } | 643 | } |
| 472 | 644 | ||
| 645 | static struct platform_device *r8a7779_late_devices[] __initdata = { | ||
| 646 | &ehci0_device, | ||
| 647 | &ehci1_device, | ||
| 648 | &ohci0_device, | ||
| 649 | &ohci1_device, | ||
| 650 | }; | ||
| 651 | |||
| 652 | void __init r8a7779_init_late(void) | ||
| 653 | { | ||
| 654 | /* get USB PHY */ | ||
| 655 | phy = usb_get_phy(USB_PHY_TYPE_USB2); | ||
| 656 | |||
| 657 | shmobile_init_late(); | ||
| 658 | platform_add_devices(r8a7779_late_devices, | ||
| 659 | ARRAY_SIZE(r8a7779_late_devices)); | ||
| 660 | } | ||
| 661 | |||
| 473 | #ifdef CONFIG_USE_OF | 662 | #ifdef CONFIG_USE_OF |
| 474 | void __init r8a7779_init_delay(void) | 663 | void __init r8a7779_init_delay(void) |
| 475 | { | 664 | { |
| @@ -503,6 +692,7 @@ DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") | |||
| 503 | .init_irq = r8a7779_init_irq_dt, | 692 | .init_irq = r8a7779_init_irq_dt, |
| 504 | .init_machine = r8a7779_add_standard_devices_dt, | 693 | .init_machine = r8a7779_add_standard_devices_dt, |
| 505 | .init_time = shmobile_timer_init, | 694 | .init_time = shmobile_timer_init, |
| 695 | .init_late = r8a7779_init_late, | ||
| 506 | .dt_compat = r8a7779_compat_dt, | 696 | .dt_compat = r8a7779_compat_dt, |
| 507 | MACHINE_END | 697 | MACHINE_END |
| 508 | #endif /* CONFIG_USE_OF */ | 698 | #endif /* CONFIG_USE_OF */ |
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index f47f2594c9d4..d1f5cea435aa 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c | |||
| @@ -48,6 +48,12 @@ static int ehci_platform_reset(struct usb_hcd *hcd) | |||
| 48 | ehci->big_endian_desc = pdata->big_endian_desc; | 48 | ehci->big_endian_desc = pdata->big_endian_desc; |
| 49 | ehci->big_endian_mmio = pdata->big_endian_mmio; | 49 | ehci->big_endian_mmio = pdata->big_endian_mmio; |
| 50 | 50 | ||
| 51 | if (pdata->pre_setup) { | ||
| 52 | retval = pdata->pre_setup(hcd); | ||
| 53 | if (retval < 0) | ||
| 54 | return retval; | ||
| 55 | } | ||
| 56 | |||
| 51 | ehci->caps = hcd->regs + pdata->caps_offset; | 57 | ehci->caps = hcd->regs + pdata->caps_offset; |
| 52 | retval = ehci_setup(hcd); | 58 | retval = ehci_setup(hcd); |
| 53 | if (retval) | 59 | if (retval) |
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 7ef3eb8617a6..13c09c299f15 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig | |||
| @@ -180,15 +180,15 @@ config USB_MXS_PHY | |||
| 180 | MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. | 180 | MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. |
| 181 | 181 | ||
| 182 | config USB_RCAR_PHY | 182 | config USB_RCAR_PHY |
| 183 | tristate "Renesas R-Car USB phy support" | 183 | tristate "Renesas R-Car USB PHY support" |
| 184 | depends on USB || USB_GADGET | 184 | depends on USB || USB_GADGET |
| 185 | help | 185 | help |
| 186 | Say Y here to add support for the Renesas R-Car USB phy driver. | 186 | Say Y here to add support for the Renesas R-Car USB common PHY driver. |
| 187 | This chip is typically used as USB phy for USB host, gadget. | 187 | This chip is typically used as USB PHY for USB host, gadget. |
| 188 | This driver supports: R8A7779 | 188 | This driver supports R8A7778 and R8A7779. |
| 189 | 189 | ||
| 190 | To compile this driver as a module, choose M here: the | 190 | To compile this driver as a module, choose M here: the |
| 191 | module will be called rcar-phy. | 191 | module will be called phy-rcar-usb. |
| 192 | 192 | ||
| 193 | config USB_ULPI | 193 | config USB_ULPI |
| 194 | bool "Generic ULPI Transceiver Driver" | 194 | bool "Generic ULPI Transceiver Driver" |
diff --git a/drivers/usb/phy/phy-rcar-usb.c b/drivers/usb/phy/phy-rcar-usb.c index a35681b0c501..ae909408958d 100644 --- a/drivers/usb/phy/phy-rcar-usb.c +++ b/drivers/usb/phy/phy-rcar-usb.c | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Renesas R-Car USB phy driver | 2 | * Renesas R-Car USB phy driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2012 Renesas Solutions Corp. | 4 | * Copyright (C) 2012-2013 Renesas Solutions Corp. |
| 5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| 6 | * Copyright (C) 2013 Cogent Embedded, Inc. | ||
| 6 | * | 7 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 8 | * 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 | * it under the terms of the GNU General Public License version 2 as |
| @@ -15,17 +16,41 @@ | |||
| 15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 18 | 19 | #include <linux/platform_data/usb-rcar-phy.h> | |
| 19 | /* USBH common register */ | 20 | |
| 20 | #define USBPCTRL0 0x0800 | 21 | /* REGS block */ |
| 21 | #define USBPCTRL1 0x0804 | 22 | #define USBPCTRL0 0x00 |
| 22 | #define USBST 0x0808 | 23 | #define USBPCTRL1 0x04 |
| 23 | #define USBEH0 0x080C | 24 | #define USBST 0x08 |
| 24 | #define USBOH0 0x081C | 25 | #define USBEH0 0x0C |
| 25 | #define USBCTL0 0x0858 | 26 | #define USBOH0 0x1C |
| 26 | #define EIIBC1 0x0094 | 27 | #define USBCTL0 0x58 |
| 27 | #define EIIBC2 0x009C | 28 | |
| 28 | 29 | /* High-speed signal quality characteristic control registers (R8A7778 only) */ | |
| 30 | #define HSQCTL1 0x24 | ||
| 31 | #define HSQCTL2 0x28 | ||
| 32 | |||
| 33 | /* USBPCTRL0 */ | ||
| 34 | #define OVC2 (1 << 10) /* (R8A7779 only) */ | ||
| 35 | /* Switches the OVC input pin for port 2: */ | ||
| 36 | /* 1: USB_OVC2, 0: OVC2 */ | ||
| 37 | #define OVC1_VBUS1 (1 << 9) /* Switches the OVC input pin for port 1: */ | ||
| 38 | /* 1: USB_OVC1, 0: OVC1/VBUS1 */ | ||
| 39 | /* Function mode: set to 0 */ | ||
| 40 | #define OVC0 (1 << 8) /* Switches the OVC input pin for port 0: */ | ||
| 41 | /* 1: USB_OVC0 pin, 0: OVC0 */ | ||
| 42 | #define OVC2_ACT (1 << 6) /* (R8A7779 only) */ | ||
| 43 | /* Host mode: OVC2 polarity: */ | ||
| 44 | /* 1: active-high, 0: active-low */ | ||
| 45 | #define PENC (1 << 4) /* Function mode: output level of PENC1 pin: */ | ||
| 46 | /* 1: high, 0: low */ | ||
| 47 | #define OVC0_ACT (1 << 3) /* Host mode: OVC0 polarity: */ | ||
| 48 | /* 1: active-high, 0: active-low */ | ||
| 49 | #define OVC1_ACT (1 << 1) /* Host mode: OVC1 polarity: */ | ||
| 50 | /* 1: active-high, 0: active-low */ | ||
| 51 | /* Function mode: be sure to set to 1 */ | ||
| 52 | #define PORT1 (1 << 0) /* Selects port 1 mode: */ | ||
| 53 | /* 1: function, 0: host */ | ||
| 29 | /* USBPCTRL1 */ | 54 | /* USBPCTRL1 */ |
| 30 | #define PHY_RST (1 << 2) | 55 | #define PHY_RST (1 << 2) |
| 31 | #define PLL_ENB (1 << 1) | 56 | #define PLL_ENB (1 << 1) |
| @@ -58,8 +83,10 @@ static int rcar_usb_phy_init(struct usb_phy *phy) | |||
| 58 | { | 83 | { |
| 59 | struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); | 84 | struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); |
| 60 | struct device *dev = phy->dev; | 85 | struct device *dev = phy->dev; |
| 86 | struct rcar_phy_platform_data *pdata = dev->platform_data; | ||
| 61 | void __iomem *reg0 = priv->reg0; | 87 | void __iomem *reg0 = priv->reg0; |
| 62 | void __iomem *reg1 = priv->reg1; | 88 | void __iomem *reg1 = priv->reg1; |
| 89 | static const u8 ovcn_act[] = { OVC0_ACT, OVC1_ACT, OVC2_ACT }; | ||
| 63 | int i; | 90 | int i; |
| 64 | u32 val; | 91 | u32 val; |
| 65 | unsigned long flags; | 92 | unsigned long flags; |
| @@ -77,7 +104,16 @@ static int rcar_usb_phy_init(struct usb_phy *phy) | |||
| 77 | /* (2) start USB-PHY internal PLL */ | 104 | /* (2) start USB-PHY internal PLL */ |
| 78 | iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1)); | 105 | iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1)); |
| 79 | 106 | ||
| 80 | /* (3) USB module status check */ | 107 | /* (3) set USB-PHY in accord with the conditions of usage */ |
| 108 | if (reg1) { | ||
| 109 | u32 hsqctl1 = pdata->ferrite_bead ? 0x41 : 0; | ||
| 110 | u32 hsqctl2 = pdata->ferrite_bead ? 0x0d : 7; | ||
| 111 | |||
| 112 | iowrite32(hsqctl1, reg1 + HSQCTL1); | ||
| 113 | iowrite32(hsqctl2, reg1 + HSQCTL2); | ||
| 114 | } | ||
| 115 | |||
| 116 | /* (4) USB module status check */ | ||
| 81 | for (i = 0; i < 1024; i++) { | 117 | for (i = 0; i < 1024; i++) { |
| 82 | udelay(10); | 118 | udelay(10); |
| 83 | val = ioread32(reg0 + USBST); | 119 | val = ioread32(reg0 + USBST); |
| @@ -90,24 +126,24 @@ static int rcar_usb_phy_init(struct usb_phy *phy) | |||
| 90 | goto phy_init_end; | 126 | goto phy_init_end; |
| 91 | } | 127 | } |
| 92 | 128 | ||
| 93 | /* (4) USB-PHY reset clear */ | 129 | /* (5) USB-PHY reset clear */ |
| 94 | iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1)); | 130 | iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1)); |
| 95 | 131 | ||
| 96 | /* set platform specific port settings */ | 132 | /* Board specific port settings */ |
| 97 | iowrite32(0x00000000, (reg0 + USBPCTRL0)); | 133 | val = 0; |
| 98 | 134 | if (pdata->port1_func) | |
| 99 | /* | 135 | val |= PORT1; |
| 100 | * EHCI IP internal buffer setting | 136 | if (pdata->penc1) |
| 101 | * EHCI IP internal buffer enable | 137 | val |= PENC; |
| 102 | * | 138 | for (i = 0; i < 3; i++) { |
| 103 | * These are recommended value of a datasheet | 139 | /* OVCn bits follow each other in the right order */ |
| 104 | * see [USB :: EHCI internal buffer setting] | 140 | if (pdata->ovc_pin[i].select_3_3v) |
| 105 | */ | 141 | val |= OVC0 << i; |
| 106 | iowrite32(0x00ff0040, (reg0 + EIIBC1)); | 142 | /* OVCn_ACT bits are spaced by irregular intervals */ |
| 107 | iowrite32(0x00ff0040, (reg1 + EIIBC1)); | 143 | if (pdata->ovc_pin[i].active_high) |
| 108 | 144 | val |= ovcn_act[i]; | |
| 109 | iowrite32(0x00000001, (reg0 + EIIBC2)); | 145 | } |
| 110 | iowrite32(0x00000001, (reg1 + EIIBC2)); | 146 | iowrite32(val, (reg0 + USBPCTRL0)); |
| 111 | 147 | ||
| 112 | /* | 148 | /* |
| 113 | * Bus alignment settings | 149 | * Bus alignment settings |
| @@ -134,10 +170,8 @@ static void rcar_usb_phy_shutdown(struct usb_phy *phy) | |||
| 134 | 170 | ||
| 135 | spin_lock_irqsave(&priv->lock, flags); | 171 | spin_lock_irqsave(&priv->lock, flags); |
| 136 | 172 | ||
| 137 | if (priv->counter-- == 1) { /* last user */ | 173 | if (priv->counter-- == 1) /* last user */ |
| 138 | iowrite32(0x00000000, (reg0 + USBPCTRL0)); | ||
| 139 | iowrite32(0x00000000, (reg0 + USBPCTRL1)); | 174 | iowrite32(0x00000000, (reg0 + USBPCTRL1)); |
| 140 | } | ||
| 141 | 175 | ||
| 142 | spin_unlock_irqrestore(&priv->lock, flags); | 176 | spin_unlock_irqrestore(&priv->lock, flags); |
| 143 | } | 177 | } |
| @@ -147,27 +181,29 @@ static int rcar_usb_phy_probe(struct platform_device *pdev) | |||
| 147 | struct rcar_usb_phy_priv *priv; | 181 | struct rcar_usb_phy_priv *priv; |
| 148 | struct resource *res0, *res1; | 182 | struct resource *res0, *res1; |
| 149 | struct device *dev = &pdev->dev; | 183 | struct device *dev = &pdev->dev; |
| 150 | void __iomem *reg0, *reg1; | 184 | void __iomem *reg0, *reg1 = NULL; |
| 151 | int ret; | 185 | int ret; |
| 152 | 186 | ||
| 187 | if (!pdev->dev.platform_data) { | ||
| 188 | dev_err(dev, "No platform data\n"); | ||
| 189 | return -EINVAL; | ||
| 190 | } | ||
| 191 | |||
| 153 | res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 192 | res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 154 | res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 193 | if (!res0) { |
| 155 | if (!res0 || !res1) { | ||
| 156 | dev_err(dev, "Not enough platform resources\n"); | 194 | dev_err(dev, "Not enough platform resources\n"); |
| 157 | return -EINVAL; | 195 | return -EINVAL; |
| 158 | } | 196 | } |
| 159 | 197 | ||
| 160 | /* | 198 | reg0 = devm_ioremap_resource(dev, res0); |
| 161 | * CAUTION | 199 | if (IS_ERR(reg0)) |
| 162 | * | 200 | return PTR_ERR(reg0); |
| 163 | * Because this phy address is also mapped under OHCI/EHCI address area, | 201 | |
| 164 | * this driver can't use devm_request_and_ioremap(dev, res) here | 202 | res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 165 | */ | 203 | if (res1) { |
| 166 | reg0 = devm_ioremap_nocache(dev, res0->start, resource_size(res0)); | 204 | reg1 = devm_ioremap_resource(dev, res1); |
| 167 | reg1 = devm_ioremap_nocache(dev, res1->start, resource_size(res1)); | 205 | if (IS_ERR(reg1)) |
| 168 | if (!reg0 || !reg1) { | 206 | return PTR_ERR(reg1); |
| 169 | dev_err(dev, "ioremap error\n"); | ||
| 170 | return -ENOMEM; | ||
| 171 | } | 207 | } |
| 172 | 208 | ||
| 173 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 209 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
diff --git a/include/linux/platform_data/usb-rcar-phy.h b/include/linux/platform_data/usb-rcar-phy.h new file mode 100644 index 000000000000..8ec6964a32a5 --- /dev/null +++ b/include/linux/platform_data/usb-rcar-phy.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2013 Renesas Solutions Corp. | ||
| 3 | * Copyright (C) 2013 Cogent Embedded, Inc. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef __USB_RCAR_PHY_H | ||
| 11 | #define __USB_RCAR_PHY_H | ||
| 12 | |||
| 13 | #include <linux/types.h> | ||
| 14 | |||
| 15 | struct rcar_phy_platform_data { | ||
| 16 | bool ferrite_bead:1; /* (R8A7778 only) */ | ||
| 17 | |||
| 18 | bool port1_func:1; /* true: port 1 used by function, false: host */ | ||
| 19 | unsigned penc1:1; /* Output of the PENC1 pin in function mode */ | ||
| 20 | struct { /* Overcurrent pin control for ports 0..2 */ | ||
| 21 | bool select_3_3v:1; /* true: USB_OVCn pin, false: OVCn pin */ | ||
| 22 | /* Set to false on port 1 in function mode */ | ||
| 23 | bool active_high:1; /* true: active high, false: active low */ | ||
| 24 | /* Set to true on port 1 in function mode */ | ||
| 25 | } ovc_pin[3]; /* (R8A7778 only has 2 ports) */ | ||
| 26 | }; | ||
| 27 | |||
| 28 | #endif /* __USB_RCAR_PHY_H */ | ||
diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h index 99238b096f7e..7eb4dcd0d386 100644 --- a/include/linux/usb/ehci_pdriver.h +++ b/include/linux/usb/ehci_pdriver.h | |||
| @@ -19,6 +19,9 @@ | |||
| 19 | #ifndef __USB_CORE_EHCI_PDRIVER_H | 19 | #ifndef __USB_CORE_EHCI_PDRIVER_H |
| 20 | #define __USB_CORE_EHCI_PDRIVER_H | 20 | #define __USB_CORE_EHCI_PDRIVER_H |
| 21 | 21 | ||
| 22 | struct platform_device; | ||
| 23 | struct usb_hcd; | ||
| 24 | |||
| 22 | /** | 25 | /** |
| 23 | * struct usb_ehci_pdata - platform_data for generic ehci driver | 26 | * struct usb_ehci_pdata - platform_data for generic ehci driver |
| 24 | * | 27 | * |
| @@ -50,6 +53,7 @@ struct usb_ehci_pdata { | |||
| 50 | /* Turn on only VBUS suspend power and hotplug detection, | 53 | /* Turn on only VBUS suspend power and hotplug detection, |
| 51 | * turn off everything else */ | 54 | * turn off everything else */ |
| 52 | void (*power_suspend)(struct platform_device *pdev); | 55 | void (*power_suspend)(struct platform_device *pdev); |
| 56 | int (*pre_setup)(struct usb_hcd *hcd); | ||
| 53 | }; | 57 | }; |
| 54 | 58 | ||
| 55 | #endif /* __USB_CORE_EHCI_PDRIVER_H */ | 59 | #endif /* __USB_CORE_EHCI_PDRIVER_H */ |
