diff options
-rw-r--r-- | arch/mips/alchemy/common/dma.c | 12 | ||||
-rw-r--r-- | arch/mips/alchemy/common/power.c | 42 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-au1x00/au1000.h | 84 | ||||
-rw-r--r-- | drivers/usb/host/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/host/alchemy-common.c | 337 | ||||
-rw-r--r-- | drivers/usb/host/ehci-au1xxx.c | 77 | ||||
-rw-r--r-- | drivers/usb/host/ohci-au1xxx.c | 110 |
7 files changed, 382 insertions, 281 deletions
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c index 347980e79a89..6652a237b920 100644 --- a/arch/mips/alchemy/common/dma.c +++ b/arch/mips/alchemy/common/dma.c | |||
@@ -88,12 +88,12 @@ static const struct dma_dev { | |||
88 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ | 88 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ |
89 | { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ | 89 | { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ |
90 | { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */ | 90 | { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */ |
91 | { AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ | 91 | { AU1000_USB_UDC_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ |
92 | { AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ | 92 | { AU1000_USB_UDC_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ |
93 | { AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ | 93 | { AU1000_USB_UDC_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ |
94 | { AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ | 94 | { AU1000_USB_UDC_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ |
95 | { AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ | 95 | { AU1000_USB_UDC_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ |
96 | { AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */ | 96 | { AU1000_USB_UDC_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */ |
97 | /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ | 97 | /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ |
98 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ | 98 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ |
99 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ | 99 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ |
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 9ec85597bbf3..bdd6651e9a4f 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -47,7 +47,6 @@ | |||
47 | * We only have to save/restore registers that aren't otherwise | 47 | * We only have to save/restore registers that aren't otherwise |
48 | * done as part of a driver pm_* function. | 48 | * done as part of a driver pm_* function. |
49 | */ | 49 | */ |
50 | static unsigned int sleep_usb[2]; | ||
51 | static unsigned int sleep_sys_clocks[5]; | 50 | static unsigned int sleep_sys_clocks[5]; |
52 | static unsigned int sleep_sys_pinfunc; | 51 | static unsigned int sleep_sys_pinfunc; |
53 | static unsigned int sleep_static_memctlr[4][3]; | 52 | static unsigned int sleep_static_memctlr[4][3]; |
@@ -55,31 +54,6 @@ static unsigned int sleep_static_memctlr[4][3]; | |||
55 | 54 | ||
56 | static void save_core_regs(void) | 55 | static void save_core_regs(void) |
57 | { | 56 | { |
58 | #ifndef CONFIG_SOC_AU1200 | ||
59 | /* Shutdown USB host/device. */ | ||
60 | sleep_usb[0] = au_readl(USB_HOST_CONFIG); | ||
61 | |||
62 | /* There appears to be some undocumented reset register.... */ | ||
63 | au_writel(0, 0xb0100004); | ||
64 | au_sync(); | ||
65 | au_writel(0, USB_HOST_CONFIG); | ||
66 | au_sync(); | ||
67 | |||
68 | sleep_usb[1] = au_readl(USBD_ENABLE); | ||
69 | au_writel(0, USBD_ENABLE); | ||
70 | au_sync(); | ||
71 | |||
72 | #else /* AU1200 */ | ||
73 | |||
74 | /* enable access to OTG mmio so we can save OTG CAP/MUX. | ||
75 | * FIXME: write an OTG driver and move this stuff there! | ||
76 | */ | ||
77 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
78 | au_sync(); | ||
79 | sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */ | ||
80 | sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */ | ||
81 | #endif | ||
82 | |||
83 | /* Clocks and PLLs. */ | 57 | /* Clocks and PLLs. */ |
84 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); | 58 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); |
85 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); | 59 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); |
@@ -123,22 +97,6 @@ static void restore_core_regs(void) | |||
123 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); | 97 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); |
124 | au_sync(); | 98 | au_sync(); |
125 | 99 | ||
126 | #ifndef CONFIG_SOC_AU1200 | ||
127 | au_writel(sleep_usb[0], USB_HOST_CONFIG); | ||
128 | au_writel(sleep_usb[1], USBD_ENABLE); | ||
129 | au_sync(); | ||
130 | #else | ||
131 | /* enable access to OTG memory */ | ||
132 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
133 | au_sync(); | ||
134 | |||
135 | /* restore OTG caps and port mux. */ | ||
136 | au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */ | ||
137 | au_sync(); | ||
138 | au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */ | ||
139 | au_sync(); | ||
140 | #endif | ||
141 | |||
142 | /* Restore the static memory controller configuration. */ | 100 | /* Restore the static memory controller configuration. */ |
143 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); | 101 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); |
144 | au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); | 102 | au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); |
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index f260ebed713b..3b0a1e774dc9 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h | |||
@@ -245,6 +245,15 @@ void alchemy_sleep_au1000(void); | |||
245 | void alchemy_sleep_au1550(void); | 245 | void alchemy_sleep_au1550(void); |
246 | void au_sleep(void); | 246 | void au_sleep(void); |
247 | 247 | ||
248 | /* USB: drivers/usb/host/alchemy-common.c */ | ||
249 | enum alchemy_usb_block { | ||
250 | ALCHEMY_USB_OHCI0, | ||
251 | ALCHEMY_USB_UDC0, | ||
252 | ALCHEMY_USB_EHCI0, | ||
253 | ALCHEMY_USB_OTG0, | ||
254 | }; | ||
255 | int alchemy_usb_control(int block, int enable); | ||
256 | |||
248 | 257 | ||
249 | /* SOC Interrupt numbers */ | 258 | /* SOC Interrupt numbers */ |
250 | 259 | ||
@@ -687,7 +696,8 @@ enum soc_au1200_ints { | |||
687 | */ | 696 | */ |
688 | 697 | ||
689 | #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ | 698 | #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ |
690 | #define AU1000_USBD_PHYS_ADDR 0x10200000 /* 0123 */ | 699 | #define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */ |
700 | #define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */ | ||
691 | #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | 701 | #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ |
692 | #define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | 702 | #define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ |
693 | #define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | 703 | #define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ |
@@ -710,12 +720,17 @@ enum soc_au1200_ints { | |||
710 | #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */ | 720 | #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */ |
711 | #define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | 721 | #define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ |
712 | #define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | 722 | #define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ |
723 | #define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */ | ||
724 | #define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */ | ||
725 | #define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */ | ||
726 | #define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */ | ||
727 | #define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */ | ||
728 | #define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */ | ||
713 | 729 | ||
714 | 730 | ||
715 | #ifdef CONFIG_SOC_AU1000 | 731 | #ifdef CONFIG_SOC_AU1000 |
716 | #define MEM_PHYS_ADDR 0x14000000 | 732 | #define MEM_PHYS_ADDR 0x14000000 |
717 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 733 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
718 | #define USBH_PHYS_ADDR 0x10100000 | ||
719 | #define IRDA_PHYS_ADDR 0x10300000 | 734 | #define IRDA_PHYS_ADDR 0x10300000 |
720 | #define SSI0_PHYS_ADDR 0x11600000 | 735 | #define SSI0_PHYS_ADDR 0x11600000 |
721 | #define SSI1_PHYS_ADDR 0x11680000 | 736 | #define SSI1_PHYS_ADDR 0x11680000 |
@@ -729,7 +744,6 @@ enum soc_au1200_ints { | |||
729 | #ifdef CONFIG_SOC_AU1500 | 744 | #ifdef CONFIG_SOC_AU1500 |
730 | #define MEM_PHYS_ADDR 0x14000000 | 745 | #define MEM_PHYS_ADDR 0x14000000 |
731 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 746 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
732 | #define USBH_PHYS_ADDR 0x10100000 | ||
733 | #define PCI_PHYS_ADDR 0x14005000 | 747 | #define PCI_PHYS_ADDR 0x14005000 |
734 | #define PCI_MEM_PHYS_ADDR 0x400000000ULL | 748 | #define PCI_MEM_PHYS_ADDR 0x400000000ULL |
735 | #define PCI_IO_PHYS_ADDR 0x500000000ULL | 749 | #define PCI_IO_PHYS_ADDR 0x500000000ULL |
@@ -745,7 +759,6 @@ enum soc_au1200_ints { | |||
745 | #ifdef CONFIG_SOC_AU1100 | 759 | #ifdef CONFIG_SOC_AU1100 |
746 | #define MEM_PHYS_ADDR 0x14000000 | 760 | #define MEM_PHYS_ADDR 0x14000000 |
747 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 761 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
748 | #define USBH_PHYS_ADDR 0x10100000 | ||
749 | #define IRDA_PHYS_ADDR 0x10300000 | 762 | #define IRDA_PHYS_ADDR 0x10300000 |
750 | #define SSI0_PHYS_ADDR 0x11600000 | 763 | #define SSI0_PHYS_ADDR 0x11600000 |
751 | #define SSI1_PHYS_ADDR 0x11680000 | 764 | #define SSI1_PHYS_ADDR 0x11680000 |
@@ -760,7 +773,6 @@ enum soc_au1200_ints { | |||
760 | #ifdef CONFIG_SOC_AU1550 | 773 | #ifdef CONFIG_SOC_AU1550 |
761 | #define MEM_PHYS_ADDR 0x14000000 | 774 | #define MEM_PHYS_ADDR 0x14000000 |
762 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 775 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
763 | #define USBH_PHYS_ADDR 0x14020000 | ||
764 | #define PCI_PHYS_ADDR 0x14005000 | 776 | #define PCI_PHYS_ADDR 0x14005000 |
765 | #define PE_PHYS_ADDR 0x14008000 | 777 | #define PE_PHYS_ADDR 0x14008000 |
766 | #define PSC0_PHYS_ADDR 0x11A00000 | 778 | #define PSC0_PHYS_ADDR 0x11A00000 |
@@ -783,8 +795,6 @@ enum soc_au1200_ints { | |||
783 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | 795 | #define STATIC_MEM_PHYS_ADDR 0x14001000 |
784 | #define AES_PHYS_ADDR 0x10300000 | 796 | #define AES_PHYS_ADDR 0x10300000 |
785 | #define CIM_PHYS_ADDR 0x14004000 | 797 | #define CIM_PHYS_ADDR 0x14004000 |
786 | #define USBM_PHYS_ADDR 0x14020000 | ||
787 | #define USBH_PHYS_ADDR 0x14020100 | ||
788 | #define PSC0_PHYS_ADDR 0x11A00000 | 798 | #define PSC0_PHYS_ADDR 0x11A00000 |
789 | #define PSC1_PHYS_ADDR 0x11B00000 | 799 | #define PSC1_PHYS_ADDR 0x11B00000 |
790 | #define LCD_PHYS_ADDR 0x15000000 | 800 | #define LCD_PHYS_ADDR 0x15000000 |
@@ -868,21 +878,6 @@ enum soc_au1200_ints { | |||
868 | #define USB_EHCI_LEN 0x100 | 878 | #define USB_EHCI_LEN 0x100 |
869 | #define USB_UDC_BASE 0x14022000 | 879 | #define USB_UDC_BASE 0x14022000 |
870 | #define USB_UDC_LEN 0x2000 | 880 | #define USB_UDC_LEN 0x2000 |
871 | #define USB_MSR_BASE 0xB4020000 | ||
872 | #define USB_MSR_MCFG 4 | ||
873 | #define USBMSRMCFG_OMEMEN 0 | ||
874 | #define USBMSRMCFG_OBMEN 1 | ||
875 | #define USBMSRMCFG_EMEMEN 2 | ||
876 | #define USBMSRMCFG_EBMEN 3 | ||
877 | #define USBMSRMCFG_DMEMEN 4 | ||
878 | #define USBMSRMCFG_DBMEN 5 | ||
879 | #define USBMSRMCFG_GMEMEN 6 | ||
880 | #define USBMSRMCFG_OHCCLKEN 16 | ||
881 | #define USBMSRMCFG_EHCCLKEN 17 | ||
882 | #define USBMSRMCFG_UDCCLKEN 18 | ||
883 | #define USBMSRMCFG_PHYPLLEN 19 | ||
884 | #define USBMSRMCFG_RDCOMB 30 | ||
885 | #define USBMSRMCFG_PFEN 31 | ||
886 | 881 | ||
887 | #define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT | 882 | #define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT |
888 | 883 | ||
@@ -963,51 +958,6 @@ enum soc_au1200_ints { | |||
963 | #define USB_OHCI_LEN 0x00100000 | 958 | #define USB_OHCI_LEN 0x00100000 |
964 | #endif | 959 | #endif |
965 | 960 | ||
966 | #ifndef CONFIG_SOC_AU1200 | ||
967 | |||
968 | /* USB Device Controller */ | ||
969 | #define USBD_EP0RD 0xB0200000 | ||
970 | #define USBD_EP0WR 0xB0200004 | ||
971 | #define USBD_EP2WR 0xB0200008 | ||
972 | #define USBD_EP3WR 0xB020000C | ||
973 | #define USBD_EP4RD 0xB0200010 | ||
974 | #define USBD_EP5RD 0xB0200014 | ||
975 | #define USBD_INTEN 0xB0200018 | ||
976 | #define USBD_INTSTAT 0xB020001C | ||
977 | # define USBDEV_INT_SOF (1 << 12) | ||
978 | # define USBDEV_INT_HF_BIT 6 | ||
979 | # define USBDEV_INT_HF_MASK (0x3f << USBDEV_INT_HF_BIT) | ||
980 | # define USBDEV_INT_CMPLT_BIT 0 | ||
981 | # define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT) | ||
982 | #define USBD_CONFIG 0xB0200020 | ||
983 | #define USBD_EP0CS 0xB0200024 | ||
984 | #define USBD_EP2CS 0xB0200028 | ||
985 | #define USBD_EP3CS 0xB020002C | ||
986 | #define USBD_EP4CS 0xB0200030 | ||
987 | #define USBD_EP5CS 0xB0200034 | ||
988 | # define USBDEV_CS_SU (1 << 14) | ||
989 | # define USBDEV_CS_NAK (1 << 13) | ||
990 | # define USBDEV_CS_ACK (1 << 12) | ||
991 | # define USBDEV_CS_BUSY (1 << 11) | ||
992 | # define USBDEV_CS_TSIZE_BIT 1 | ||
993 | # define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT) | ||
994 | # define USBDEV_CS_STALL (1 << 0) | ||
995 | #define USBD_EP0RDSTAT 0xB0200040 | ||
996 | #define USBD_EP0WRSTAT 0xB0200044 | ||
997 | #define USBD_EP2WRSTAT 0xB0200048 | ||
998 | #define USBD_EP3WRSTAT 0xB020004C | ||
999 | #define USBD_EP4RDSTAT 0xB0200050 | ||
1000 | #define USBD_EP5RDSTAT 0xB0200054 | ||
1001 | # define USBDEV_FSTAT_FLUSH (1 << 6) | ||
1002 | # define USBDEV_FSTAT_UF (1 << 5) | ||
1003 | # define USBDEV_FSTAT_OF (1 << 4) | ||
1004 | # define USBDEV_FSTAT_FCNT_BIT 0 | ||
1005 | # define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT) | ||
1006 | #define USBD_ENABLE 0xB0200058 | ||
1007 | # define USBDEV_ENABLE (1 << 1) | ||
1008 | # define USBDEV_CE (1 << 0) | ||
1009 | |||
1010 | #endif /* !CONFIG_SOC_AU1200 */ | ||
1011 | 961 | ||
1012 | /* Ethernet Controllers */ | 962 | /* Ethernet Controllers */ |
1013 | 963 | ||
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 624a362f2fee..436cd71c6bec 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -35,3 +35,4 @@ obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o | |||
35 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o | 35 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o |
36 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o | 36 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o |
37 | obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o | 37 | obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o |
38 | obj-$(CONFIG_MIPS_ALCHEMY) += alchemy-common.o | ||
diff --git a/drivers/usb/host/alchemy-common.c b/drivers/usb/host/alchemy-common.c new file mode 100644 index 000000000000..b4192c964d0d --- /dev/null +++ b/drivers/usb/host/alchemy-common.c | |||
@@ -0,0 +1,337 @@ | |||
1 | /* | ||
2 | * USB block power/access management abstraction. | ||
3 | * | ||
4 | * Au1000+: The OHCI block control register is at the far end of the OHCI memory | ||
5 | * area. Au1550 has OHCI on different base address. No need to handle | ||
6 | * UDC here. | ||
7 | * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG | ||
8 | * as well as the PHY for EHCI and UDC. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/syscore_ops.h> | ||
17 | #include <asm/mach-au1x00/au1000.h> | ||
18 | |||
19 | /* control register offsets */ | ||
20 | #define AU1000_OHCICFG 0x7fffc | ||
21 | #define AU1550_OHCICFG 0x07ffc | ||
22 | #define AU1200_USBCFG 0x04 | ||
23 | |||
24 | /* Au1000 USB block config bits */ | ||
25 | #define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */ | ||
26 | #define USBHEN_CE (1 << 3) /* OHCI block clock enable */ | ||
27 | #define USBHEN_E (1 << 2) /* OHCI block enable */ | ||
28 | #define USBHEN_C (1 << 1) /* OHCI block coherency bit */ | ||
29 | #define USBHEN_BE (1 << 0) /* OHCI Big-Endian */ | ||
30 | |||
31 | /* Au1200 USB config bits */ | ||
32 | #define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */ | ||
33 | #define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */ | ||
34 | #define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */ | ||
35 | #define USBCFG_SSD (1 << 23) /* serial short detect en */ | ||
36 | #define USBCFG_PPE (1 << 19) /* HS PHY PLL */ | ||
37 | #define USBCFG_UCE (1 << 18) /* UDC clock enable */ | ||
38 | #define USBCFG_ECE (1 << 17) /* EHCI clock enable */ | ||
39 | #define USBCFG_OCE (1 << 16) /* OHCI clock enable */ | ||
40 | #define USBCFG_FLA(x) (((x) & 0x3f) << 8) | ||
41 | #define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */ | ||
42 | #define USBCFG_GME (1 << 6) /* OTG mem access */ | ||
43 | #define USBCFG_DBE (1 << 5) /* UDC busmaster enable */ | ||
44 | #define USBCFG_DME (1 << 4) /* UDC mem enable */ | ||
45 | #define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */ | ||
46 | #define USBCFG_EME (1 << 2) /* EHCI mem enable */ | ||
47 | #define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */ | ||
48 | #define USBCFG_OME (1 << 0) /* OHCI mem enable */ | ||
49 | #define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\ | ||
50 | USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \ | ||
51 | USBCFG_GME | USBCFG_DBE | USBCFG_DME | \ | ||
52 | USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ | ||
53 | USBCFG_OME) | ||
54 | |||
55 | |||
56 | static DEFINE_SPINLOCK(alchemy_usb_lock); | ||
57 | |||
58 | |||
59 | static inline void __au1200_ohci_control(void __iomem *base, int enable) | ||
60 | { | ||
61 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
62 | if (enable) { | ||
63 | __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG); | ||
64 | wmb(); | ||
65 | udelay(2000); | ||
66 | } else { | ||
67 | __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG); | ||
68 | wmb(); | ||
69 | udelay(1000); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | static inline void __au1200_ehci_control(void __iomem *base, int enable) | ||
74 | { | ||
75 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
76 | if (enable) { | ||
77 | __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG); | ||
78 | wmb(); | ||
79 | udelay(1000); | ||
80 | } else { | ||
81 | if (!(r & USBCFG_UCE)) /* UDC also off? */ | ||
82 | r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ | ||
83 | __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG); | ||
84 | wmb(); | ||
85 | udelay(1000); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | static inline void __au1200_udc_control(void __iomem *base, int enable) | ||
90 | { | ||
91 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
92 | if (enable) { | ||
93 | __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG); | ||
94 | wmb(); | ||
95 | } else { | ||
96 | if (!(r & USBCFG_ECE)) /* EHCI also off? */ | ||
97 | r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ | ||
98 | __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG); | ||
99 | wmb(); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static inline int au1200_coherency_bug(void) | ||
104 | { | ||
105 | #if defined(CONFIG_DMA_COHERENT) | ||
106 | /* Au1200 AB USB does not support coherent memory */ | ||
107 | if (!(read_c0_prid() & 0xff)) { | ||
108 | printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n"); | ||
109 | printk(KERN_INFO "Au1200 USB: update your board or re-configure" | ||
110 | " the kernel\n"); | ||
111 | return -ENODEV; | ||
112 | } | ||
113 | #endif | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static inline int au1200_usb_control(int block, int enable) | ||
118 | { | ||
119 | void __iomem *base = | ||
120 | (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); | ||
121 | int ret = 0; | ||
122 | |||
123 | switch (block) { | ||
124 | case ALCHEMY_USB_OHCI0: | ||
125 | ret = au1200_coherency_bug(); | ||
126 | if (ret && enable) | ||
127 | goto out; | ||
128 | __au1200_ohci_control(base, enable); | ||
129 | break; | ||
130 | case ALCHEMY_USB_UDC0: | ||
131 | __au1200_udc_control(base, enable); | ||
132 | break; | ||
133 | case ALCHEMY_USB_EHCI0: | ||
134 | ret = au1200_coherency_bug(); | ||
135 | if (ret && enable) | ||
136 | goto out; | ||
137 | __au1200_ehci_control(base, enable); | ||
138 | break; | ||
139 | default: | ||
140 | ret = -ENODEV; | ||
141 | } | ||
142 | out: | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | |||
147 | /* initialize USB block(s) to a known working state */ | ||
148 | static inline void au1200_usb_init(void) | ||
149 | { | ||
150 | void __iomem *base = | ||
151 | (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); | ||
152 | __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG); | ||
153 | wmb(); | ||
154 | udelay(1000); | ||
155 | } | ||
156 | |||
157 | static inline void au1000_usb_init(unsigned long rb, int reg) | ||
158 | { | ||
159 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); | ||
160 | unsigned long r = __raw_readl(base); | ||
161 | |||
162 | #if defined(__BIG_ENDIAN) | ||
163 | r |= USBHEN_BE; | ||
164 | #endif | ||
165 | r |= USBHEN_C; | ||
166 | |||
167 | __raw_writel(r, base); | ||
168 | wmb(); | ||
169 | udelay(1000); | ||
170 | } | ||
171 | |||
172 | |||
173 | static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) | ||
174 | { | ||
175 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb); | ||
176 | unsigned long r = __raw_readl(base + creg); | ||
177 | |||
178 | if (enable) { | ||
179 | __raw_writel(r | USBHEN_CE, base + creg); | ||
180 | wmb(); | ||
181 | udelay(1000); | ||
182 | __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg); | ||
183 | wmb(); | ||
184 | udelay(1000); | ||
185 | |||
186 | /* wait for reset complete (read reg twice: au1500 erratum) */ | ||
187 | while (__raw_readl(base + creg), | ||
188 | !(__raw_readl(base + creg) & USBHEN_RD)) | ||
189 | udelay(1000); | ||
190 | } else { | ||
191 | __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); | ||
192 | wmb(); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | static inline int au1000_usb_control(int block, int enable, unsigned long rb, | ||
197 | int creg) | ||
198 | { | ||
199 | int ret = 0; | ||
200 | |||
201 | switch (block) { | ||
202 | case ALCHEMY_USB_OHCI0: | ||
203 | __au1xx0_ohci_control(enable, rb, creg); | ||
204 | break; | ||
205 | default: | ||
206 | ret = -ENODEV; | ||
207 | } | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * alchemy_usb_control - control Alchemy on-chip USB blocks | ||
213 | * @block: USB block to target | ||
214 | * @enable: set 1 to enable a block, 0 to disable | ||
215 | */ | ||
216 | int alchemy_usb_control(int block, int enable) | ||
217 | { | ||
218 | unsigned long flags; | ||
219 | int ret; | ||
220 | |||
221 | spin_lock_irqsave(&alchemy_usb_lock, flags); | ||
222 | switch (alchemy_get_cputype()) { | ||
223 | case ALCHEMY_CPU_AU1000: | ||
224 | case ALCHEMY_CPU_AU1500: | ||
225 | case ALCHEMY_CPU_AU1100: | ||
226 | ret = au1000_usb_control(block, enable, | ||
227 | AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | ||
228 | break; | ||
229 | case ALCHEMY_CPU_AU1550: | ||
230 | ret = au1000_usb_control(block, enable, | ||
231 | AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | ||
232 | break; | ||
233 | case ALCHEMY_CPU_AU1200: | ||
234 | ret = au1200_usb_control(block, enable); | ||
235 | break; | ||
236 | default: | ||
237 | ret = -ENODEV; | ||
238 | } | ||
239 | spin_unlock_irqrestore(&alchemy_usb_lock, flags); | ||
240 | return ret; | ||
241 | } | ||
242 | EXPORT_SYMBOL_GPL(alchemy_usb_control); | ||
243 | |||
244 | |||
245 | static unsigned long alchemy_usb_pmdata[2]; | ||
246 | |||
247 | static void au1000_usb_pm(unsigned long br, int creg, int susp) | ||
248 | { | ||
249 | void __iomem *base = (void __iomem *)KSEG1ADDR(br); | ||
250 | |||
251 | if (susp) { | ||
252 | alchemy_usb_pmdata[0] = __raw_readl(base + creg); | ||
253 | /* There appears to be some undocumented reset register.... */ | ||
254 | __raw_writel(0, base + 0x04); | ||
255 | wmb(); | ||
256 | __raw_writel(0, base + creg); | ||
257 | wmb(); | ||
258 | } else { | ||
259 | __raw_writel(alchemy_usb_pmdata[0], base + creg); | ||
260 | wmb(); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | static void au1200_usb_pm(int susp) | ||
265 | { | ||
266 | void __iomem *base = | ||
267 | (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR); | ||
268 | if (susp) { | ||
269 | /* save OTG_CAP/MUX registers which indicate port routing */ | ||
270 | /* FIXME: write an OTG driver to do that */ | ||
271 | alchemy_usb_pmdata[0] = __raw_readl(base + 0x00); | ||
272 | alchemy_usb_pmdata[1] = __raw_readl(base + 0x04); | ||
273 | } else { | ||
274 | /* restore access to all MMIO areas */ | ||
275 | au1200_usb_init(); | ||
276 | |||
277 | /* restore OTG_CAP/MUX registers */ | ||
278 | __raw_writel(alchemy_usb_pmdata[0], base + 0x00); | ||
279 | __raw_writel(alchemy_usb_pmdata[1], base + 0x04); | ||
280 | wmb(); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | static void alchemy_usb_pm(int susp) | ||
285 | { | ||
286 | switch (alchemy_get_cputype()) { | ||
287 | case ALCHEMY_CPU_AU1000: | ||
288 | case ALCHEMY_CPU_AU1500: | ||
289 | case ALCHEMY_CPU_AU1100: | ||
290 | au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp); | ||
291 | break; | ||
292 | case ALCHEMY_CPU_AU1550: | ||
293 | au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp); | ||
294 | break; | ||
295 | case ALCHEMY_CPU_AU1200: | ||
296 | au1200_usb_pm(susp); | ||
297 | break; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | static int alchemy_usb_suspend(void) | ||
302 | { | ||
303 | alchemy_usb_pm(1); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static void alchemy_usb_resume(void) | ||
308 | { | ||
309 | alchemy_usb_pm(0); | ||
310 | } | ||
311 | |||
312 | static struct syscore_ops alchemy_usb_pm_ops = { | ||
313 | .suspend = alchemy_usb_suspend, | ||
314 | .resume = alchemy_usb_resume, | ||
315 | }; | ||
316 | |||
317 | static int __init alchemy_usb_init(void) | ||
318 | { | ||
319 | switch (alchemy_get_cputype()) { | ||
320 | case ALCHEMY_CPU_AU1000: | ||
321 | case ALCHEMY_CPU_AU1500: | ||
322 | case ALCHEMY_CPU_AU1100: | ||
323 | au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | ||
324 | break; | ||
325 | case ALCHEMY_CPU_AU1550: | ||
326 | au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | ||
327 | break; | ||
328 | case ALCHEMY_CPU_AU1200: | ||
329 | au1200_usb_init(); | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | register_syscore_ops(&alchemy_usb_pm_ops); | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | arch_initcall(alchemy_usb_init); | ||
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 42ae57409908..e480dc17394d 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -14,61 +14,9 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <asm/mach-au1x00/au1000.h> | 15 | #include <asm/mach-au1x00/au1000.h> |
16 | 16 | ||
17 | #define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) | ||
18 | #define USB_MCFG_PFEN (1<<31) | ||
19 | #define USB_MCFG_RDCOMB (1<<30) | ||
20 | #define USB_MCFG_SSDEN (1<<23) | ||
21 | #define USB_MCFG_PHYPLLEN (1<<19) | ||
22 | #define USB_MCFG_UCECLKEN (1<<18) | ||
23 | #define USB_MCFG_EHCCLKEN (1<<17) | ||
24 | #ifdef CONFIG_DMA_COHERENT | ||
25 | #define USB_MCFG_UCAM (1<<7) | ||
26 | #else | ||
27 | #define USB_MCFG_UCAM (0) | ||
28 | #endif | ||
29 | #define USB_MCFG_EBMEN (1<<3) | ||
30 | #define USB_MCFG_EMEMEN (1<<2) | ||
31 | |||
32 | #define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN) | ||
33 | #define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \ | ||
34 | USBH_ENABLE_CE | USB_MCFG_SSDEN | \ | ||
35 | USB_MCFG_UCAM | USB_MCFG_EBMEN | \ | ||
36 | USB_MCFG_EMEMEN) | ||
37 | |||
38 | #define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN) | ||
39 | 17 | ||
40 | extern int usb_disabled(void); | 18 | extern int usb_disabled(void); |
41 | 19 | ||
42 | static void au1xxx_start_ehc(void) | ||
43 | { | ||
44 | /* enable clock to EHCI block and HS PHY PLL*/ | ||
45 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
46 | au_sync(); | ||
47 | udelay(1000); | ||
48 | |||
49 | /* enable EHCI mmio */ | ||
50 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
51 | au_sync(); | ||
52 | udelay(1000); | ||
53 | } | ||
54 | |||
55 | static void au1xxx_stop_ehc(void) | ||
56 | { | ||
57 | unsigned long c; | ||
58 | |||
59 | /* Disable mem */ | ||
60 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG); | ||
61 | au_sync(); | ||
62 | udelay(1000); | ||
63 | |||
64 | /* Disable EHC clock. If the HS PHY is unused disable it too. */ | ||
65 | c = au_readl(USB_HOST_CONFIG) & ~USB_MCFG_EHCCLKEN; | ||
66 | if (!(c & USB_MCFG_UCECLKEN)) /* UDC disabled? */ | ||
67 | c &= ~USB_MCFG_PHYPLLEN; /* yes: disable HS PHY PLL */ | ||
68 | au_writel(c, USB_HOST_CONFIG); | ||
69 | au_sync(); | ||
70 | } | ||
71 | |||
72 | static int au1xxx_ehci_setup(struct usb_hcd *hcd) | 20 | static int au1xxx_ehci_setup(struct usb_hcd *hcd) |
73 | { | 21 | { |
74 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 22 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
@@ -136,16 +84,6 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
136 | if (usb_disabled()) | 84 | if (usb_disabled()) |
137 | return -ENODEV; | 85 | return -ENODEV; |
138 | 86 | ||
139 | #if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT) | ||
140 | /* Au1200 AB USB does not support coherent memory */ | ||
141 | if (!(read_c0_prid() & 0xff)) { | ||
142 | printk(KERN_INFO "%s: this is chip revision AB!\n", pdev->name); | ||
143 | printk(KERN_INFO "%s: update your board or re-configure" | ||
144 | " the kernel\n", pdev->name); | ||
145 | return -ENODEV; | ||
146 | } | ||
147 | #endif | ||
148 | |||
149 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | 87 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { |
150 | pr_debug("resource[1] is not IORESOURCE_IRQ"); | 88 | pr_debug("resource[1] is not IORESOURCE_IRQ"); |
151 | return -ENOMEM; | 89 | return -ENOMEM; |
@@ -171,7 +109,11 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
171 | goto err2; | 109 | goto err2; |
172 | } | 110 | } |
173 | 111 | ||
174 | au1xxx_start_ehc(); | 112 | if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) { |
113 | printk(KERN_INFO "%s: controller init failed!\n", pdev->name); | ||
114 | ret = -ENODEV; | ||
115 | goto err3; | ||
116 | } | ||
175 | 117 | ||
176 | ehci = hcd_to_ehci(hcd); | 118 | ehci = hcd_to_ehci(hcd); |
177 | ehci->caps = hcd->regs; | 119 | ehci->caps = hcd->regs; |
@@ -187,7 +129,8 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
187 | return ret; | 129 | return ret; |
188 | } | 130 | } |
189 | 131 | ||
190 | au1xxx_stop_ehc(); | 132 | alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); |
133 | err3: | ||
191 | iounmap(hcd->regs); | 134 | iounmap(hcd->regs); |
192 | err2: | 135 | err2: |
193 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 136 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
@@ -201,10 +144,10 @@ static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev) | |||
201 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 144 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
202 | 145 | ||
203 | usb_remove_hcd(hcd); | 146 | usb_remove_hcd(hcd); |
147 | alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); | ||
204 | iounmap(hcd->regs); | 148 | iounmap(hcd->regs); |
205 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 149 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
206 | usb_put_hcd(hcd); | 150 | usb_put_hcd(hcd); |
207 | au1xxx_stop_ehc(); | ||
208 | platform_set_drvdata(pdev, NULL); | 151 | platform_set_drvdata(pdev, NULL); |
209 | 152 | ||
210 | return 0; | 153 | return 0; |
@@ -236,7 +179,7 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev) | |||
236 | // could save FLADJ in case of Vaux power loss | 179 | // could save FLADJ in case of Vaux power loss |
237 | // ... we'd only use it to handle clock skew | 180 | // ... we'd only use it to handle clock skew |
238 | 181 | ||
239 | au1xxx_stop_ehc(); | 182 | alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); |
240 | 183 | ||
241 | return rc; | 184 | return rc; |
242 | } | 185 | } |
@@ -246,7 +189,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev) | |||
246 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 189 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
247 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 190 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
248 | 191 | ||
249 | au1xxx_start_ehc(); | 192 | alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); |
250 | 193 | ||
251 | // maybe restore FLADJ | 194 | // maybe restore FLADJ |
252 | 195 | ||
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 958d985f2951..299d719495f1 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -23,92 +23,9 @@ | |||
23 | 23 | ||
24 | #include <asm/mach-au1x00/au1000.h> | 24 | #include <asm/mach-au1x00/au1000.h> |
25 | 25 | ||
26 | #ifndef CONFIG_SOC_AU1200 | ||
27 | |||
28 | #define USBH_ENABLE_BE (1<<0) | ||
29 | #define USBH_ENABLE_C (1<<1) | ||
30 | #define USBH_ENABLE_E (1<<2) | ||
31 | #define USBH_ENABLE_CE (1<<3) | ||
32 | #define USBH_ENABLE_RD (1<<4) | ||
33 | |||
34 | #ifdef __LITTLE_ENDIAN | ||
35 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C) | ||
36 | #elif defined(__BIG_ENDIAN) | ||
37 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | \ | ||
38 | USBH_ENABLE_BE) | ||
39 | #else | ||
40 | #error not byte order defined | ||
41 | #endif | ||
42 | |||
43 | #else /* Au1200 */ | ||
44 | |||
45 | #define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) | ||
46 | #define USB_MCFG_PFEN (1<<31) | ||
47 | #define USB_MCFG_RDCOMB (1<<30) | ||
48 | #define USB_MCFG_SSDEN (1<<23) | ||
49 | #define USB_MCFG_OHCCLKEN (1<<16) | ||
50 | #ifdef CONFIG_DMA_COHERENT | ||
51 | #define USB_MCFG_UCAM (1<<7) | ||
52 | #else | ||
53 | #define USB_MCFG_UCAM (0) | ||
54 | #endif | ||
55 | #define USB_MCFG_OBMEN (1<<1) | ||
56 | #define USB_MCFG_OMEMEN (1<<0) | ||
57 | |||
58 | #define USBH_ENABLE_CE USB_MCFG_OHCCLKEN | ||
59 | |||
60 | #define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \ | ||
61 | USBH_ENABLE_CE | USB_MCFG_SSDEN | \ | ||
62 | USB_MCFG_UCAM | \ | ||
63 | USB_MCFG_OBMEN | USB_MCFG_OMEMEN) | ||
64 | |||
65 | #define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN) | ||
66 | |||
67 | #endif /* Au1200 */ | ||
68 | 26 | ||
69 | extern int usb_disabled(void); | 27 | extern int usb_disabled(void); |
70 | 28 | ||
71 | static void au1xxx_start_ohc(void) | ||
72 | { | ||
73 | /* enable host controller */ | ||
74 | #ifndef CONFIG_SOC_AU1200 | ||
75 | au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
76 | au_sync(); | ||
77 | udelay(1000); | ||
78 | |||
79 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
80 | au_sync(); | ||
81 | udelay(1000); | ||
82 | |||
83 | /* wait for reset complete (read register twice; see au1500 errata) */ | ||
84 | while (au_readl(USB_HOST_CONFIG), | ||
85 | !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) | ||
86 | udelay(1000); | ||
87 | |||
88 | #else /* Au1200 */ | ||
89 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
90 | au_sync(); | ||
91 | udelay(1000); | ||
92 | |||
93 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
94 | au_sync(); | ||
95 | udelay(2000); | ||
96 | #endif /* Au1200 */ | ||
97 | } | ||
98 | |||
99 | static void au1xxx_stop_ohc(void) | ||
100 | { | ||
101 | #ifdef CONFIG_SOC_AU1200 | ||
102 | /* Disable mem */ | ||
103 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG); | ||
104 | au_sync(); | ||
105 | udelay(1000); | ||
106 | #endif | ||
107 | /* Disable clock */ | ||
108 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
109 | au_sync(); | ||
110 | } | ||
111 | |||
112 | static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) | 29 | static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) |
113 | { | 30 | { |
114 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | 31 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
@@ -178,17 +95,6 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
178 | if (usb_disabled()) | 95 | if (usb_disabled()) |
179 | return -ENODEV; | 96 | return -ENODEV; |
180 | 97 | ||
181 | #if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT) | ||
182 | /* Au1200 AB USB does not support coherent memory */ | ||
183 | if (!(read_c0_prid() & 0xff)) { | ||
184 | printk(KERN_INFO "%s: this is chip revision AB !!\n", | ||
185 | pdev->name); | ||
186 | printk(KERN_INFO "%s: update your board or re-configure " | ||
187 | "the kernel\n", pdev->name); | ||
188 | return -ENODEV; | ||
189 | } | ||
190 | #endif | ||
191 | |||
192 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | 98 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { |
193 | pr_debug("resource[1] is not IORESOURCE_IRQ\n"); | 99 | pr_debug("resource[1] is not IORESOURCE_IRQ\n"); |
194 | return -ENOMEM; | 100 | return -ENOMEM; |
@@ -214,7 +120,12 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
214 | goto err2; | 120 | goto err2; |
215 | } | 121 | } |
216 | 122 | ||
217 | au1xxx_start_ohc(); | 123 | if (alchemy_usb_control(ALCHEMY_USB_OHCI0, 1)) { |
124 | printk(KERN_INFO "%s: controller init failed!\n", pdev->name); | ||
125 | ret = -ENODEV; | ||
126 | goto err3; | ||
127 | } | ||
128 | |||
218 | ohci_hcd_init(hcd_to_ohci(hcd)); | 129 | ohci_hcd_init(hcd_to_ohci(hcd)); |
219 | 130 | ||
220 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | 131 | ret = usb_add_hcd(hcd, pdev->resource[1].start, |
@@ -224,7 +135,8 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
224 | return ret; | 135 | return ret; |
225 | } | 136 | } |
226 | 137 | ||
227 | au1xxx_stop_ohc(); | 138 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); |
139 | err3: | ||
228 | iounmap(hcd->regs); | 140 | iounmap(hcd->regs); |
229 | err2: | 141 | err2: |
230 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 142 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
@@ -238,7 +150,7 @@ static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) | |||
238 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 150 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
239 | 151 | ||
240 | usb_remove_hcd(hcd); | 152 | usb_remove_hcd(hcd); |
241 | au1xxx_stop_ohc(); | 153 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); |
242 | iounmap(hcd->regs); | 154 | iounmap(hcd->regs); |
243 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 155 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
244 | usb_put_hcd(hcd); | 156 | usb_put_hcd(hcd); |
@@ -275,7 +187,7 @@ static int ohci_hcd_au1xxx_drv_suspend(struct device *dev) | |||
275 | 187 | ||
276 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 188 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
277 | 189 | ||
278 | au1xxx_stop_ohc(); | 190 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); |
279 | bail: | 191 | bail: |
280 | spin_unlock_irqrestore(&ohci->lock, flags); | 192 | spin_unlock_irqrestore(&ohci->lock, flags); |
281 | 193 | ||
@@ -286,7 +198,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev) | |||
286 | { | 198 | { |
287 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 199 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
288 | 200 | ||
289 | au1xxx_start_ohc(); | 201 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 1); |
290 | 202 | ||
291 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 203 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
292 | ohci_finish_controller_resume(hcd); | 204 | ohci_finish_controller_resume(hcd); |