| @@ -11,6 +11,7 @@ · 10 unmodified lines |
| 11 | 11 | #include <linux/platform_device.h> |
| 12 | 12 | #include <linux/dma-map-ops.h> |
| 13 | 13 | #include <linux/io.h> |
| 14 | +#include <linux/delay.h> |
| 14 | 15 | |
| 15 | 16 | #include <asm/irq.h> |
| 16 | 17 | |
| @@ -206,8 +207,6 @@ static inline void udc_device_init(struct omap_usb_config *pdata) · 189 unmodified lines |
| 206 | 207 | |
| 207 | 208 | #endif |
| 208 | 209 | |
| 209 | | −#if IS_ENABLED(CONFIG_USB_OHCI_HCD) |
| 210 | | − |
| 211 | 210 | /* The dmamask must be set for OHCI to work */ |
| 212 | 211 | static u64 ohci_dmamask = ~(u32)0; |
| 213 | 212 | |
| @@ -236,20 +235,15 @@ static struct platform_device ohci_device = { · 22 unmodified lines |
| 236 | 235 | |
| 237 | 236 | static inline void ohci_device_init(struct omap_usb_config *pdata) |
| 238 | 237 | { |
| 238 | + if (!IS_ENABLED(CONFIG_USB_OHCI_HCD)) |
| 239 | + return; |
| 240 | + |
| 239 | 241 | if (cpu_is_omap7xx()) |
| 240 | 242 | ohci_resources[1].start = INT_7XX_USB_HHC_1; |
| 241 | 243 | pdata->ohci_device = &ohci_device; |
| 242 | 244 | pdata->ocpi_enable = &ocpi_enable; |
| 243 | 245 | } |
| 244 | 246 | |
| 245 | | −#else |
| 246 | | − |
| 247 | | −static inline void ohci_device_init(struct omap_usb_config *pdata) |
| 248 | | −{ |
| 249 | | −} |
| 250 | | − |
| 251 | | −#endif |
| 252 | | − |
| 253 | 247 | #if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) |
| 254 | 248 | |
| 255 | 249 | static struct resource otg_resources[] = { |
| @@ -534,33 +528,87 @@ bad: · 278 unmodified lines |
| 534 | 528 | } |
| 535 | 529 | |
| 536 | 530 | #ifdef CONFIG_ARCH_OMAP15XX |
| 531 | +/* OMAP-1510 OHCI has its own MMU for DMA */ |
| 532 | +#define OMAP1510_LB_MEMSIZE 32 /* Should be same as SDRAM size */ |
| 533 | +#define OMAP1510_LB_CLOCK_DIV 0xfffec10c |
| 534 | +#define OMAP1510_LB_MMU_CTL 0xfffec208 |
| 535 | +#define OMAP1510_LB_MMU_LCK 0xfffec224 |
| 536 | +#define OMAP1510_LB_MMU_LD_TLB 0xfffec228 |
| 537 | +#define OMAP1510_LB_MMU_CAM_H 0xfffec22c |
| 538 | +#define OMAP1510_LB_MMU_CAM_L 0xfffec230 |
| 539 | +#define OMAP1510_LB_MMU_RAM_H 0xfffec234 |
| 540 | +#define OMAP1510_LB_MMU_RAM_L 0xfffec238 |
| 537 | 541 | |
| 538 | | −/* ULPD_DPLL_CTRL */ |
| 539 | | −#define DPLL_IOB (1 << 13) |
| 540 | | −#define DPLL_PLL_ENABLE (1 << 4) |
| 541 | | −#define DPLL_LOCK (1 << 0) |
| 542 | +/* |
| 543 | + * Bus address is physical address, except for OMAP-1510 Local Bus. |
| 544 | + * OMAP-1510 bus address is translated into a Local Bus address if the |
| 545 | + * OMAP bus type is lbus. |
| 546 | + */ |
| 547 | +#define OMAP1510_LB_OFFSET UL(0x30000000) |
| 542 | 548 | |
| 543 | | −/* ULPD_APLL_CTRL */ |
| 544 | | −#define APLL_NDPLL_SWITCH (1 << 0) |
| 549 | +/* |
| 550 | + * OMAP-1510 specific Local Bus clock on/off |
| 551 | + */ |
| 552 | +static int omap_1510_local_bus_power(int on) |
| 553 | +{ |
| 554 | + if (on) { |
| 555 | + omap_writel((1 << 1) | (1 << 0), OMAP1510_LB_MMU_CTL); |
| 556 | + udelay(200); |
| 557 | + } else { |
| 558 | + omap_writel(0, OMAP1510_LB_MMU_CTL); |
| 559 | + } |
| 545 | 560 | |
| 546 | | −static int omap_1510_usb_ohci_notifier(struct notifier_block *nb, |
| 547 | | − unsigned long event, void *data) |
| 561 | + return 0; |
| 562 | +} |
| 563 | + |
| 564 | +/* |
| 565 | + * OMAP-1510 specific Local Bus initialization |
| 566 | + * NOTE: This assumes 32MB memory size in OMAP1510LB_MEMSIZE. |
| 567 | + * See also arch/mach-omap/memory.h for __virt_to_dma() and |
| 568 | + * __dma_to_virt() which need to match with the physical |
| 569 | + * Local Bus address below. |
| 570 | + */ |
| 571 | +static int omap_1510_local_bus_init(void) |
| 548 | 572 | { |
| 549 | | − struct device *dev = data; |
| 573 | + unsigned int tlb; |
| 574 | + unsigned long lbaddr, physaddr; |
| 575 | + |
| 576 | + omap_writel((omap_readl(OMAP1510_LB_CLOCK_DIV) & 0xfffffff8) | 0x4, |
| 577 | + OMAP1510_LB_CLOCK_DIV); |
| 578 | + |
| 579 | + /* Configure the Local Bus MMU table */ |
| 580 | + for (tlb = 0; tlb < OMAP1510_LB_MEMSIZE; tlb++) { |
| 581 | + lbaddr = tlb * 0x00100000 + OMAP1510_LB_OFFSET; |
| 582 | + physaddr = tlb * 0x00100000 + PHYS_OFFSET; |
| 583 | + omap_writel((lbaddr & 0x0fffffff) >> 22, OMAP1510_LB_MMU_CAM_H); |
| 584 | + omap_writel(((lbaddr & 0x003ffc00) >> 6) | 0xc, |
| 585 | + OMAP1510_LB_MMU_CAM_L); |
| 586 | + omap_writel(physaddr >> 16, OMAP1510_LB_MMU_RAM_H); |
| 587 | + omap_writel((physaddr & 0x0000fc00) | 0x300, OMAP1510_LB_MMU_RAM_L); |
| 588 | + omap_writel(tlb << 4, OMAP1510_LB_MMU_LCK); |
| 589 | + omap_writel(0x1, OMAP1510_LB_MMU_LD_TLB); |
| 590 | + } |
| 550 | 591 | |
| 551 | | − if (event != BUS_NOTIFY_ADD_DEVICE) |
| 552 | | − return NOTIFY_DONE; |
| 592 | + /* Enable the walking table */ |
| 593 | + omap_writel(omap_readl(OMAP1510_LB_MMU_CTL) | (1 << 3), OMAP1510_LB_MMU_CTL); |
| 594 | + udelay(200); |
| 553 | 595 | |
| 554 | | − if (strncmp(dev_name(dev), "ohci", 4) == 0 && |
| 555 | | − dma_direct_set_offset(dev, PHYS_OFFSET, OMAP1510_LB_OFFSET, |
| 556 | | − (u64)-1)) |
| 557 | | − WARN_ONCE(1, "failed to set DMA offset\n"); |
| 558 | | − return NOTIFY_OK; |
| 596 | + return 0; |
| 559 | 597 | } |
| 560 | 598 | |
| 561 | | −static struct notifier_block omap_1510_usb_ohci_nb = { |
| 562 | | − .notifier_call = omap_1510_usb_ohci_notifier, |
| 563 | | −}; |
| 599 | +static void omap_1510_local_bus_reset(void) |
| 600 | +{ |
| 601 | + omap_1510_local_bus_power(1); |
| 602 | + omap_1510_local_bus_init(); |
| 603 | +} |
| 604 | + |
| 605 | +/* ULPD_DPLL_CTRL */ |
| 606 | +#define DPLL_IOB (1 << 13) |
| 607 | +#define DPLL_PLL_ENABLE (1 << 4) |
| 608 | +#define DPLL_LOCK (1 << 0) |
| 609 | + |
| 610 | +/* ULPD_APLL_CTRL */ |
| 611 | +#define APLL_NDPLL_SWITCH (1 << 0) |
| 564 | 612 | |
| 565 | 613 | static void __init omap_1510_usb_init(struct omap_usb_config *config) |
| 566 | 614 | { |
| @@ -616,19 +664,19 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) · 49 unmodified lines |
| 616 | 664 | } |
| 617 | 665 | #endif |
| 618 | 666 | |
| 619 | | −#if IS_ENABLED(CONFIG_USB_OHCI_HCD) |
| 620 | | − if (config->register_host) { |
| 667 | + if (IS_ENABLED(CONFIG_USB_OHCI_HCD) && config->register_host) { |
| 621 | 668 | int status; |
| 622 | 669 | |
| 623 | | − bus_register_notifier(&platform_bus_type, |
| 624 | | − &omap_1510_usb_ohci_nb); |
| 625 | 670 | ohci_device.dev.platform_data = config; |
| 671 | + dma_direct_set_offset(&ohci_device.dev, PHYS_OFFSET, |
| 672 | + OMAP1510_LB_OFFSET, (u64)-1); |
| 626 | 673 | status = platform_device_register(&ohci_device); |
| 627 | 674 | if (status) |
| 628 | 675 | pr_debug("can't register OHCI device, %d\n", status); |
| 629 | 676 | /* hcd explicitly gates 48MHz */ |
| 677 | + |
| 678 | + config->lb_reset = omap_1510_local_bus_reset; |
| 630 | 679 | } |
| 631 | | −#endif |
| 632 | 680 | } |
| 633 | 681 | |
| 634 | 682 | #else |