diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-03 16:28:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-03 16:28:14 -0400 |
commit | d6748066ad0e8b2514545998f8367ebb3906f299 (patch) | |
tree | f7a9bfd764a8fb781aeda0ef2249afbab42dddf7 /arch | |
parent | f04c045f8ce69c22bda9d99eb927276b776135fc (diff) | |
parent | 3ba1e543ab4b02640d396098f2f6a199560d5f2d (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (37 commits)
MIPS: O32: Provide definition of registers ta0 .. ta3.
MIPS: perf: Add Octeon support for hardware perf.
MIPS: perf: Add support for 64-bit perf counters.
MIPS: perf: Reorganize contents of perf support files.
MIPS: perf: Cleanup formatting in arch/mips/kernel/perf_event.c
MIPS: Add accessor macros for 64-bit performance counter registers.
MIPS: Add probes for more Octeon II CPUs.
MIPS: Add more CPU identifiers for Octeon II CPUs.
MIPS: XLR, XLS: Add comment for smp setup
MIPS: JZ4740: GPIO: Check correct IRQ in demux handler
MIPS: JZ4740: GPIO: Simplify IRQ demuxer
MIPS: JZ4740: Use generic irq chip
MIPS: Alchemy: remove all CONFIG_SOC_AU1??? defines
MIPS: Alchemy: kill au1xxx.h header
MIPS: Alchemy: clean DMA code of CONFIG_SOC_AU1??? defines
MIPS, IDE: Alchem, au1xxx-ide: Remove pb1200/db1200 header dep
MIPS: Alchemy: Redo PCI as platform driver
MIPS: Alchemy: more base address cleanup
MIPS: Alchemy: rewrite USB platform setup.
MIPS: Alchemy: abstract USB block control register access
...
Fix up trivial conflicts in:
arch/mips/alchemy/devboards/db1x00/platform.c
drivers/ide/Kconfig
drivers/mmc/host/au1xmmc.c
drivers/video/Kconfig
sound/mips/Kconfig
Diffstat (limited to 'arch')
72 files changed, 3050 insertions, 2850 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4cbc6d8de210..62b9677c39a1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -47,6 +47,8 @@ config MIPS_ALCHEMY | |||
47 | select GENERIC_GPIO | 47 | select GENERIC_GPIO |
48 | select ARCH_WANT_OPTIONAL_GPIOLIB | 48 | select ARCH_WANT_OPTIONAL_GPIOLIB |
49 | select SYS_SUPPORTS_ZBOOT | 49 | select SYS_SUPPORTS_ZBOOT |
50 | select USB_ARCH_HAS_OHCI | ||
51 | select USB_ARCH_HAS_EHCI | ||
50 | 52 | ||
51 | config AR7 | 53 | config AR7 |
52 | bool "Texas Instruments AR7" | 54 | bool "Texas Instruments AR7" |
@@ -206,6 +208,7 @@ config MACH_JZ4740 | |||
206 | select SYS_HAS_EARLY_PRINTK | 208 | select SYS_HAS_EARLY_PRINTK |
207 | select HAVE_PWM | 209 | select HAVE_PWM |
208 | select HAVE_CLK | 210 | select HAVE_CLK |
211 | select GENERIC_IRQ_CHIP | ||
209 | 212 | ||
210 | config LANTIQ | 213 | config LANTIQ |
211 | bool "Lantiq based platforms" | 214 | bool "Lantiq based platforms" |
@@ -2092,7 +2095,7 @@ config NODES_SHIFT | |||
2092 | 2095 | ||
2093 | config HW_PERF_EVENTS | 2096 | config HW_PERF_EVENTS |
2094 | bool "Enable hardware performance counter support for perf events" | 2097 | bool "Enable hardware performance counter support for perf events" |
2095 | depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32 | 2098 | depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON) |
2096 | default y | 2099 | default y |
2097 | help | 2100 | help |
2098 | Enable hardware performance counter support for perf events. If | 2101 | Enable hardware performance counter support for perf events. If |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 53e3514ba10e..9b4cb00407d7 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -226,7 +226,7 @@ LDFLAGS += -m $(ld-emul) | |||
226 | ifdef CONFIG_MIPS | 226 | ifdef CONFIG_MIPS |
227 | CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \ | 227 | CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \ |
228 | egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ | 228 | egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ |
229 | sed -e 's/^\#define /-D/' -e "s/ /='/" -e "s/$$/'/") | 229 | sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/") |
230 | ifdef CONFIG_64BIT | 230 | ifdef CONFIG_64BIT |
231 | CHECKFLAGS += -m64 | 231 | CHECKFLAGS += -m64 |
232 | endif | 232 | endif |
@@ -295,7 +295,9 @@ endif | |||
295 | 295 | ||
296 | install: | 296 | install: |
297 | $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) | 297 | $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) |
298 | ifdef CONFIG_SYS_SUPPORTS_ZBOOT | ||
298 | $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE) | 299 | $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE) |
300 | endif | ||
299 | $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE) | 301 | $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE) |
300 | $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) | 302 | $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) |
301 | 303 | ||
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig index 2ccfd4a135bc..2a68be6a1b97 100644 --- a/arch/mips/alchemy/Kconfig +++ b/arch/mips/alchemy/Kconfig | |||
@@ -18,20 +18,20 @@ config MIPS_MTX1 | |||
18 | bool "4G Systems MTX-1 board" | 18 | bool "4G Systems MTX-1 board" |
19 | select DMA_NONCOHERENT | 19 | select DMA_NONCOHERENT |
20 | select HW_HAS_PCI | 20 | select HW_HAS_PCI |
21 | select SOC_AU1500 | 21 | select ALCHEMY_GPIOINT_AU1000 |
22 | select SYS_SUPPORTS_LITTLE_ENDIAN | 22 | select SYS_SUPPORTS_LITTLE_ENDIAN |
23 | select SYS_HAS_EARLY_PRINTK | 23 | select SYS_HAS_EARLY_PRINTK |
24 | 24 | ||
25 | config MIPS_BOSPORUS | 25 | config MIPS_BOSPORUS |
26 | bool "Alchemy Bosporus board" | 26 | bool "Alchemy Bosporus board" |
27 | select SOC_AU1500 | 27 | select ALCHEMY_GPIOINT_AU1000 |
28 | select DMA_NONCOHERENT | 28 | select DMA_NONCOHERENT |
29 | select SYS_SUPPORTS_LITTLE_ENDIAN | 29 | select SYS_SUPPORTS_LITTLE_ENDIAN |
30 | select SYS_HAS_EARLY_PRINTK | 30 | select SYS_HAS_EARLY_PRINTK |
31 | 31 | ||
32 | config MIPS_DB1000 | 32 | config MIPS_DB1000 |
33 | bool "Alchemy DB1000 board" | 33 | bool "Alchemy DB1000 board" |
34 | select SOC_AU1000 | 34 | select ALCHEMY_GPIOINT_AU1000 |
35 | select DMA_NONCOHERENT | 35 | select DMA_NONCOHERENT |
36 | select HW_HAS_PCI | 36 | select HW_HAS_PCI |
37 | select SYS_SUPPORTS_LITTLE_ENDIAN | 37 | select SYS_SUPPORTS_LITTLE_ENDIAN |
@@ -39,14 +39,14 @@ config MIPS_DB1000 | |||
39 | 39 | ||
40 | config MIPS_DB1100 | 40 | config MIPS_DB1100 |
41 | bool "Alchemy DB1100 board" | 41 | bool "Alchemy DB1100 board" |
42 | select SOC_AU1100 | 42 | select ALCHEMY_GPIOINT_AU1000 |
43 | select DMA_NONCOHERENT | 43 | select DMA_NONCOHERENT |
44 | select SYS_SUPPORTS_LITTLE_ENDIAN | 44 | select SYS_SUPPORTS_LITTLE_ENDIAN |
45 | select SYS_HAS_EARLY_PRINTK | 45 | select SYS_HAS_EARLY_PRINTK |
46 | 46 | ||
47 | config MIPS_DB1200 | 47 | config MIPS_DB1200 |
48 | bool "Alchemy DB1200 board" | 48 | bool "Alchemy DB1200 board" |
49 | select SOC_AU1200 | 49 | select ALCHEMY_GPIOINT_AU1000 |
50 | select DMA_COHERENT | 50 | select DMA_COHERENT |
51 | select MIPS_DISABLE_OBSOLETE_IDE | 51 | select MIPS_DISABLE_OBSOLETE_IDE |
52 | select SYS_SUPPORTS_LITTLE_ENDIAN | 52 | select SYS_SUPPORTS_LITTLE_ENDIAN |
@@ -54,7 +54,7 @@ config MIPS_DB1200 | |||
54 | 54 | ||
55 | config MIPS_DB1500 | 55 | config MIPS_DB1500 |
56 | bool "Alchemy DB1500 board" | 56 | bool "Alchemy DB1500 board" |
57 | select SOC_AU1500 | 57 | select ALCHEMY_GPIOINT_AU1000 |
58 | select DMA_NONCOHERENT | 58 | select DMA_NONCOHERENT |
59 | select HW_HAS_PCI | 59 | select HW_HAS_PCI |
60 | select MIPS_DISABLE_OBSOLETE_IDE | 60 | select MIPS_DISABLE_OBSOLETE_IDE |
@@ -64,7 +64,7 @@ config MIPS_DB1500 | |||
64 | 64 | ||
65 | config MIPS_DB1550 | 65 | config MIPS_DB1550 |
66 | bool "Alchemy DB1550 board" | 66 | bool "Alchemy DB1550 board" |
67 | select SOC_AU1550 | 67 | select ALCHEMY_GPIOINT_AU1000 |
68 | select HW_HAS_PCI | 68 | select HW_HAS_PCI |
69 | select DMA_NONCOHERENT | 69 | select DMA_NONCOHERENT |
70 | select MIPS_DISABLE_OBSOLETE_IDE | 70 | select MIPS_DISABLE_OBSOLETE_IDE |
@@ -74,13 +74,13 @@ config MIPS_DB1550 | |||
74 | config MIPS_MIRAGE | 74 | config MIPS_MIRAGE |
75 | bool "Alchemy Mirage board" | 75 | bool "Alchemy Mirage board" |
76 | select DMA_NONCOHERENT | 76 | select DMA_NONCOHERENT |
77 | select SOC_AU1500 | 77 | select ALCHEMY_GPIOINT_AU1000 |
78 | select SYS_SUPPORTS_LITTLE_ENDIAN | 78 | select SYS_SUPPORTS_LITTLE_ENDIAN |
79 | select SYS_HAS_EARLY_PRINTK | 79 | select SYS_HAS_EARLY_PRINTK |
80 | 80 | ||
81 | config MIPS_PB1000 | 81 | config MIPS_PB1000 |
82 | bool "Alchemy PB1000 board" | 82 | bool "Alchemy PB1000 board" |
83 | select SOC_AU1000 | 83 | select ALCHEMY_GPIOINT_AU1000 |
84 | select DMA_NONCOHERENT | 84 | select DMA_NONCOHERENT |
85 | select HW_HAS_PCI | 85 | select HW_HAS_PCI |
86 | select SWAP_IO_SPACE | 86 | select SWAP_IO_SPACE |
@@ -89,7 +89,7 @@ config MIPS_PB1000 | |||
89 | 89 | ||
90 | config MIPS_PB1100 | 90 | config MIPS_PB1100 |
91 | bool "Alchemy PB1100 board" | 91 | bool "Alchemy PB1100 board" |
92 | select SOC_AU1100 | 92 | select ALCHEMY_GPIOINT_AU1000 |
93 | select DMA_NONCOHERENT | 93 | select DMA_NONCOHERENT |
94 | select HW_HAS_PCI | 94 | select HW_HAS_PCI |
95 | select SWAP_IO_SPACE | 95 | select SWAP_IO_SPACE |
@@ -98,7 +98,7 @@ config MIPS_PB1100 | |||
98 | 98 | ||
99 | config MIPS_PB1200 | 99 | config MIPS_PB1200 |
100 | bool "Alchemy PB1200 board" | 100 | bool "Alchemy PB1200 board" |
101 | select SOC_AU1200 | 101 | select ALCHEMY_GPIOINT_AU1000 |
102 | select DMA_NONCOHERENT | 102 | select DMA_NONCOHERENT |
103 | select MIPS_DISABLE_OBSOLETE_IDE | 103 | select MIPS_DISABLE_OBSOLETE_IDE |
104 | select SYS_SUPPORTS_LITTLE_ENDIAN | 104 | select SYS_SUPPORTS_LITTLE_ENDIAN |
@@ -106,7 +106,7 @@ config MIPS_PB1200 | |||
106 | 106 | ||
107 | config MIPS_PB1500 | 107 | config MIPS_PB1500 |
108 | bool "Alchemy PB1500 board" | 108 | bool "Alchemy PB1500 board" |
109 | select SOC_AU1500 | 109 | select ALCHEMY_GPIOINT_AU1000 |
110 | select DMA_NONCOHERENT | 110 | select DMA_NONCOHERENT |
111 | select HW_HAS_PCI | 111 | select HW_HAS_PCI |
112 | select SYS_SUPPORTS_LITTLE_ENDIAN | 112 | select SYS_SUPPORTS_LITTLE_ENDIAN |
@@ -114,7 +114,7 @@ config MIPS_PB1500 | |||
114 | 114 | ||
115 | config MIPS_PB1550 | 115 | config MIPS_PB1550 |
116 | bool "Alchemy PB1550 board" | 116 | bool "Alchemy PB1550 board" |
117 | select SOC_AU1550 | 117 | select ALCHEMY_GPIOINT_AU1000 |
118 | select DMA_NONCOHERENT | 118 | select DMA_NONCOHERENT |
119 | select HW_HAS_PCI | 119 | select HW_HAS_PCI |
120 | select MIPS_DISABLE_OBSOLETE_IDE | 120 | select MIPS_DISABLE_OBSOLETE_IDE |
@@ -124,13 +124,13 @@ config MIPS_PB1550 | |||
124 | config MIPS_XXS1500 | 124 | config MIPS_XXS1500 |
125 | bool "MyCable XXS1500 board" | 125 | bool "MyCable XXS1500 board" |
126 | select DMA_NONCOHERENT | 126 | select DMA_NONCOHERENT |
127 | select SOC_AU1500 | 127 | select ALCHEMY_GPIOINT_AU1000 |
128 | select SYS_SUPPORTS_LITTLE_ENDIAN | 128 | select SYS_SUPPORTS_LITTLE_ENDIAN |
129 | select SYS_HAS_EARLY_PRINTK | 129 | select SYS_HAS_EARLY_PRINTK |
130 | 130 | ||
131 | config MIPS_GPR | 131 | config MIPS_GPR |
132 | bool "Trapeze ITS GPR board" | 132 | bool "Trapeze ITS GPR board" |
133 | select SOC_AU1550 | 133 | select ALCHEMY_GPIOINT_AU1000 |
134 | select HW_HAS_PCI | 134 | select HW_HAS_PCI |
135 | select DMA_NONCOHERENT | 135 | select DMA_NONCOHERENT |
136 | select MIPS_DISABLE_OBSOLETE_IDE | 136 | select MIPS_DISABLE_OBSOLETE_IDE |
@@ -138,23 +138,3 @@ config MIPS_GPR | |||
138 | select SYS_HAS_EARLY_PRINTK | 138 | select SYS_HAS_EARLY_PRINTK |
139 | 139 | ||
140 | endchoice | 140 | endchoice |
141 | |||
142 | config SOC_AU1000 | ||
143 | bool | ||
144 | select ALCHEMY_GPIOINT_AU1000 | ||
145 | |||
146 | config SOC_AU1100 | ||
147 | bool | ||
148 | select ALCHEMY_GPIOINT_AU1000 | ||
149 | |||
150 | config SOC_AU1500 | ||
151 | bool | ||
152 | select ALCHEMY_GPIOINT_AU1000 | ||
153 | |||
154 | config SOC_AU1550 | ||
155 | bool | ||
156 | select ALCHEMY_GPIOINT_AU1000 | ||
157 | |||
158 | config SOC_AU1200 | ||
159 | bool | ||
160 | select ALCHEMY_GPIOINT_AU1000 | ||
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index 27811fe341d6..811ece7b22e3 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile | |||
@@ -12,9 +12,5 @@ obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o | |||
12 | 12 | ||
13 | # optional gpiolib support | 13 | # optional gpiolib support |
14 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) | 14 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) |
15 | ifeq ($(CONFIG_GPIOLIB),y) | 15 | obj-$(CONFIG_GPIOLIB) += gpiolib.o |
16 | obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o | ||
17 | endif | ||
18 | endif | 16 | endif |
19 | |||
20 | obj-$(CONFIG_PCI) += pci.o | ||
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 3a5abb54d505..0e63ee487d6d 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c | |||
@@ -40,8 +40,6 @@ | |||
40 | #include <asm/mach-au1x00/au1000.h> | 40 | #include <asm/mach-au1x00/au1000.h> |
41 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 41 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
42 | 42 | ||
43 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
44 | |||
45 | /* | 43 | /* |
46 | * The Descriptor Based DMA supports up to 16 channels. | 44 | * The Descriptor Based DMA supports up to 16 channels. |
47 | * | 45 | * |
@@ -62,120 +60,96 @@ static dbdma_global_t *dbdma_gptr = | |||
62 | (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); | 60 | (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); |
63 | static int dbdma_initialized; | 61 | static int dbdma_initialized; |
64 | 62 | ||
65 | static dbdev_tab_t dbdev_tab[] = { | 63 | static dbdev_tab_t *dbdev_tab; |
66 | #ifdef CONFIG_SOC_AU1550 | 64 | |
65 | static dbdev_tab_t au1550_dbdev_tab[] __initdata = { | ||
67 | /* UARTS */ | 66 | /* UARTS */ |
68 | { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, | 67 | { AU1550_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, |
69 | { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, | 68 | { AU1550_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, |
70 | { DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 }, | 69 | { AU1550_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 }, |
71 | { DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 }, | 70 | { AU1550_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 }, |
72 | 71 | ||
73 | /* EXT DMA */ | 72 | /* EXT DMA */ |
74 | { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, | 73 | { AU1550_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, |
75 | { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, | 74 | { AU1550_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, |
76 | { DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 }, | 75 | { AU1550_DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 }, |
77 | { DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 }, | 76 | { AU1550_DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 }, |
78 | 77 | ||
79 | /* USB DEV */ | 78 | /* USB DEV */ |
80 | { DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 }, | 79 | { AU1550_DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 }, |
81 | { DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 }, | 80 | { AU1550_DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 }, |
82 | { DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 }, | 81 | { AU1550_DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 }, |
83 | { DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 }, | 82 | { AU1550_DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 }, |
84 | { DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 }, | 83 | { AU1550_DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 }, |
85 | { DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 }, | 84 | { AU1550_DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 }, |
86 | 85 | ||
87 | /* PSC 0 */ | 86 | /* PSCs */ |
88 | { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, | 87 | { AU1550_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, |
89 | { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, | 88 | { AU1550_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, |
90 | 89 | { AU1550_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 }, | |
91 | /* PSC 1 */ | 90 | { AU1550_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 }, |
92 | { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 }, | 91 | { AU1550_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 }, |
93 | { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 }, | 92 | { AU1550_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 }, |
94 | 93 | { AU1550_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 }, | |
95 | /* PSC 2 */ | 94 | { AU1550_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 }, |
96 | { DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 }, | 95 | |
97 | { DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 }, | 96 | { AU1550_DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */ |
98 | 97 | { AU1550_DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */ | |
99 | /* PSC 3 */ | ||
100 | { DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 }, | ||
101 | { DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 }, | ||
102 | |||
103 | { DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */ | ||
104 | { DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */ | ||
105 | 98 | ||
106 | /* MAC 0 */ | 99 | /* MAC 0 */ |
107 | { DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 100 | { AU1550_DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, |
108 | { DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, | 101 | { AU1550_DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, |
109 | 102 | ||
110 | /* MAC 1 */ | 103 | /* MAC 1 */ |
111 | { DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 104 | { AU1550_DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, |
112 | { DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, | 105 | { AU1550_DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, |
113 | |||
114 | #endif /* CONFIG_SOC_AU1550 */ | ||
115 | 106 | ||
116 | #ifdef CONFIG_SOC_AU1200 | 107 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
117 | { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, | 108 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
118 | { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, | 109 | }; |
119 | { DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 }, | ||
120 | { DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 }, | ||
121 | |||
122 | { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, | ||
123 | { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, | ||
124 | 110 | ||
125 | { DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 111 | static dbdev_tab_t au1200_dbdev_tab[] __initdata = { |
126 | { DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 112 | { AU1200_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, |
127 | { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 113 | { AU1200_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, |
128 | { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 114 | { AU1200_DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 }, |
115 | { AU1200_DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 }, | ||
129 | 116 | ||
130 | { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, | 117 | { AU1200_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, |
131 | { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, | 118 | { AU1200_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, |
132 | { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, | ||
133 | { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 }, | ||
134 | 119 | ||
135 | { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, | 120 | { AU1200_DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
136 | { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, | 121 | { AU1200_DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
122 | { AU1200_DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
123 | { AU1200_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
137 | 124 | ||
138 | { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 }, | 125 | { AU1200_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, |
139 | { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 }, | 126 | { AU1200_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, |
140 | { DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 127 | { AU1200_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, |
128 | { AU1200_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 }, | ||
141 | 129 | ||
142 | { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 }, | 130 | { AU1200_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, |
143 | { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 }, | 131 | { AU1200_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, |
144 | { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
145 | 132 | ||
146 | { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, | 133 | { AU1200_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 }, |
147 | { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, | 134 | { AU1200_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 }, |
148 | { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, | 135 | { AU1200_DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
149 | { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 136 | { AU1200_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 }, |
137 | { AU1200_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 }, | ||
138 | { AU1200_DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
150 | 139 | ||
151 | { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 140 | { AU1200_DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, |
141 | { AU1200_DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, | ||
142 | { AU1200_DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, | ||
143 | { AU1200_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
152 | 144 | ||
153 | #endif /* CONFIG_SOC_AU1200 */ | 145 | { AU1200_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, |
154 | 146 | ||
155 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 147 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
156 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 148 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
157 | |||
158 | /* Provide 16 user definable device types */ | ||
159 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
160 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
161 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
162 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
163 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
164 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
165 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
166 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
167 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
168 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
169 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
170 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
171 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
172 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
173 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
174 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
175 | }; | 149 | }; |
176 | 150 | ||
177 | #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) | 151 | /* 32 predefined plus 32 custom */ |
178 | 152 | #define DBDEV_TAB_SIZE 64 | |
179 | 153 | ||
180 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; | 154 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; |
181 | 155 | ||
@@ -1028,38 +1002,43 @@ static struct syscore_ops alchemy_dbdma_syscore_ops = { | |||
1028 | .resume = alchemy_dbdma_resume, | 1002 | .resume = alchemy_dbdma_resume, |
1029 | }; | 1003 | }; |
1030 | 1004 | ||
1031 | static int __init au1xxx_dbdma_init(void) | 1005 | static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) |
1032 | { | 1006 | { |
1033 | int irq_nr, ret; | 1007 | int ret; |
1008 | |||
1009 | dbdev_tab = kzalloc(sizeof(dbdev_tab_t) * DBDEV_TAB_SIZE, GFP_KERNEL); | ||
1010 | if (!dbdev_tab) | ||
1011 | return -ENOMEM; | ||
1012 | |||
1013 | memcpy(dbdev_tab, idtable, 32 * sizeof(dbdev_tab_t)); | ||
1014 | for (ret = 32; ret < DBDEV_TAB_SIZE; ret++) | ||
1015 | dbdev_tab[ret].dev_id = ~0; | ||
1034 | 1016 | ||
1035 | dbdma_gptr->ddma_config = 0; | 1017 | dbdma_gptr->ddma_config = 0; |
1036 | dbdma_gptr->ddma_throttle = 0; | 1018 | dbdma_gptr->ddma_throttle = 0; |
1037 | dbdma_gptr->ddma_inten = 0xffff; | 1019 | dbdma_gptr->ddma_inten = 0xffff; |
1038 | au_sync(); | 1020 | au_sync(); |
1039 | 1021 | ||
1040 | switch (alchemy_get_cputype()) { | 1022 | ret = request_irq(irq, dbdma_interrupt, IRQF_DISABLED, "dbdma", |
1041 | case ALCHEMY_CPU_AU1550: | 1023 | (void *)dbdma_gptr); |
1042 | irq_nr = AU1550_DDMA_INT; | ||
1043 | break; | ||
1044 | case ALCHEMY_CPU_AU1200: | ||
1045 | irq_nr = AU1200_DDMA_INT; | ||
1046 | break; | ||
1047 | default: | ||
1048 | return -ENODEV; | ||
1049 | } | ||
1050 | |||
1051 | ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED, | ||
1052 | "Au1xxx dbdma", (void *)dbdma_gptr); | ||
1053 | if (ret) | 1024 | if (ret) |
1054 | printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); | 1025 | printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); |
1055 | else { | 1026 | else { |
1056 | dbdma_initialized = 1; | 1027 | dbdma_initialized = 1; |
1057 | printk(KERN_INFO "Alchemy DBDMA initialized\n"); | ||
1058 | register_syscore_ops(&alchemy_dbdma_syscore_ops); | 1028 | register_syscore_ops(&alchemy_dbdma_syscore_ops); |
1059 | } | 1029 | } |
1060 | 1030 | ||
1061 | return ret; | 1031 | return ret; |
1062 | } | 1032 | } |
1063 | subsys_initcall(au1xxx_dbdma_init); | ||
1064 | 1033 | ||
1065 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ | 1034 | static int __init alchemy_dbdma_init(void) |
1035 | { | ||
1036 | switch (alchemy_get_cputype()) { | ||
1037 | case ALCHEMY_CPU_AU1550: | ||
1038 | return dbdma_setup(AU1550_DDMA_INT, au1550_dbdev_tab); | ||
1039 | case ALCHEMY_CPU_AU1200: | ||
1040 | return dbdma_setup(AU1200_DDMA_INT, au1200_dbdev_tab); | ||
1041 | } | ||
1042 | return 0; | ||
1043 | } | ||
1044 | subsys_initcall(alchemy_dbdma_init); | ||
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c index 347980e79a89..9b624e2c0fcf 100644 --- a/arch/mips/alchemy/common/dma.c +++ b/arch/mips/alchemy/common/dma.c | |||
@@ -40,8 +40,6 @@ | |||
40 | #include <asm/mach-au1x00/au1000.h> | 40 | #include <asm/mach-au1x00/au1000.h> |
41 | #include <asm/mach-au1x00/au1000_dma.h> | 41 | #include <asm/mach-au1x00/au1000_dma.h> |
42 | 42 | ||
43 | #if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \ | ||
44 | defined(CONFIG_SOC_AU1100) | ||
45 | /* | 43 | /* |
46 | * A note on resource allocation: | 44 | * A note on resource allocation: |
47 | * | 45 | * |
@@ -88,12 +86,12 @@ static const struct dma_dev { | |||
88 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ | 86 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ |
89 | { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ | 87 | { 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 */ | 88 | { 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 */ | 89 | { AU1000_USB_UDC_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ |
92 | { AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ | 90 | { AU1000_USB_UDC_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ |
93 | { AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ | 91 | { AU1000_USB_UDC_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ |
94 | { AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ | 92 | { AU1000_USB_UDC_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ |
95 | { AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ | 93 | { 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 */ | 94 | { 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! */ | 95 | /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ |
98 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ | 96 | { 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 */ | 97 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ |
@@ -170,13 +168,13 @@ int request_au1000_dma(int dev_id, const char *dev_str, | |||
170 | const struct dma_dev *dev; | 168 | const struct dma_dev *dev; |
171 | int i, ret; | 169 | int i, ret; |
172 | 170 | ||
173 | #if defined(CONFIG_SOC_AU1100) | 171 | if (alchemy_get_cputype() == ALCHEMY_CPU_AU1100) { |
174 | if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2)) | 172 | if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2)) |
175 | return -EINVAL; | 173 | return -EINVAL; |
176 | #else | 174 | } else { |
177 | if (dev_id < 0 || dev_id >= DMA_NUM_DEV) | 175 | if (dev_id < 0 || dev_id >= DMA_NUM_DEV) |
178 | return -EINVAL; | 176 | return -EINVAL; |
179 | #endif | 177 | } |
180 | 178 | ||
181 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) | 179 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) |
182 | if (au1000_dma_table[i].dev_id < 0) | 180 | if (au1000_dma_table[i].dev_id < 0) |
@@ -239,30 +237,28 @@ EXPORT_SYMBOL(free_au1000_dma); | |||
239 | 237 | ||
240 | static int __init au1000_dma_init(void) | 238 | static int __init au1000_dma_init(void) |
241 | { | 239 | { |
242 | int base, i; | 240 | int base, i; |
243 | 241 | ||
244 | switch (alchemy_get_cputype()) { | 242 | switch (alchemy_get_cputype()) { |
245 | case ALCHEMY_CPU_AU1000: | 243 | case ALCHEMY_CPU_AU1000: |
246 | base = AU1000_DMA_INT_BASE; | 244 | base = AU1000_DMA_INT_BASE; |
247 | break; | 245 | break; |
248 | case ALCHEMY_CPU_AU1500: | 246 | case ALCHEMY_CPU_AU1500: |
249 | base = AU1500_DMA_INT_BASE; | 247 | base = AU1500_DMA_INT_BASE; |
250 | break; | 248 | break; |
251 | case ALCHEMY_CPU_AU1100: | 249 | case ALCHEMY_CPU_AU1100: |
252 | base = AU1100_DMA_INT_BASE; | 250 | base = AU1100_DMA_INT_BASE; |
253 | break; | 251 | break; |
254 | default: | 252 | default: |
255 | goto out; | 253 | goto out; |
256 | } | 254 | } |
257 | 255 | ||
258 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) | 256 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) |
259 | au1000_dma_table[i].irq = base + i; | 257 | au1000_dma_table[i].irq = base + i; |
260 | 258 | ||
261 | printk(KERN_INFO "Alchemy DMA initialized\n"); | 259 | printk(KERN_INFO "Alchemy DMA initialized\n"); |
262 | 260 | ||
263 | out: | 261 | out: |
264 | return 0; | 262 | return 0; |
265 | } | 263 | } |
266 | arch_initcall(au1000_dma_init); | 264 | arch_initcall(au1000_dma_init); |
267 | |||
268 | #endif /* AU1000 AU1500 AU1100 */ | ||
diff --git a/arch/mips/alchemy/common/gpiolib-au1000.c b/arch/mips/alchemy/common/gpiolib.c index c8e1a94d4a95..91fb4d9e30fd 100644 --- a/arch/mips/alchemy/common/gpiolib-au1000.c +++ b/arch/mips/alchemy/common/gpiolib.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org> | 2 | * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org> |
3 | * GPIOLIB support for Au1000, Au1500, Au1100, Au1550 and Au12x0. | 3 | * GPIOLIB support for Alchemy chips. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License as published by the | 6 | * under the terms of the GNU General Public License as published by the |
@@ -23,18 +23,18 @@ | |||
23 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | * | 24 | * |
25 | * Notes : | 25 | * Notes : |
26 | * au1000 SoC have only one GPIO block : GPIO1 | 26 | * This file must ONLY be built when CONFIG_GPIOLIB=y and |
27 | * Au1100, Au15x0, Au12x0 have a second one : GPIO2 | 27 | * CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail! |
28 | * au1000 SoC have only one GPIO block : GPIO1 | ||
29 | * Au1100, Au15x0, Au12x0 have a second one : GPIO2 | ||
28 | */ | 30 | */ |
29 | 31 | ||
32 | #include <linux/init.h> | ||
30 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 34 | #include <linux/module.h> |
32 | #include <linux/types.h> | 35 | #include <linux/types.h> |
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/gpio.h> | 36 | #include <linux/gpio.h> |
35 | 37 | #include <asm/mach-au1x00/gpio-au1000.h> | |
36 | #include <asm/mach-au1x00/au1000.h> | ||
37 | #include <asm/mach-au1x00/gpio.h> | ||
38 | 38 | ||
39 | static int gpio2_get(struct gpio_chip *chip, unsigned offset) | 39 | static int gpio2_get(struct gpio_chip *chip, unsigned offset) |
40 | { | 40 | { |
@@ -115,12 +115,19 @@ struct gpio_chip alchemy_gpio_chip[] = { | |||
115 | }, | 115 | }, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static int __init alchemy_gpiolib_init(void) | 118 | static int __init alchemy_gpiochip_init(void) |
119 | { | 119 | { |
120 | gpiochip_add(&alchemy_gpio_chip[0]); | 120 | int ret = 0; |
121 | if (alchemy_get_cputype() != ALCHEMY_CPU_AU1000) | 121 | |
122 | gpiochip_add(&alchemy_gpio_chip[1]); | 122 | switch (alchemy_get_cputype()) { |
123 | 123 | case ALCHEMY_CPU_AU1000: | |
124 | return 0; | 124 | ret = gpiochip_add(&alchemy_gpio_chip[0]); |
125 | break; | ||
126 | case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200: | ||
127 | ret = gpiochip_add(&alchemy_gpio_chip[0]); | ||
128 | ret |= gpiochip_add(&alchemy_gpio_chip[1]); | ||
129 | break; | ||
130 | } | ||
131 | return ret; | ||
125 | } | 132 | } |
126 | arch_initcall(alchemy_gpiolib_init); | 133 | arch_initcall(alchemy_gpiochip_init); |
diff --git a/arch/mips/alchemy/common/pci.c b/arch/mips/alchemy/common/pci.c deleted file mode 100644 index 7866cf50cf99..000000000000 --- a/arch/mips/alchemy/common/pci.c +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Alchemy/AMD Au1x00 PCI support. | ||
4 | * | ||
5 | * Copyright 2001-2003, 2007-2008 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
7 | * | ||
8 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) | ||
9 | * | ||
10 | * Support for all devices (greater than 16) added by David Gathright. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
20 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
23 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
24 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License along | ||
29 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
30 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
31 | */ | ||
32 | |||
33 | #include <linux/pci.h> | ||
34 | #include <linux/kernel.h> | ||
35 | #include <linux/init.h> | ||
36 | |||
37 | #include <asm/mach-au1x00/au1000.h> | ||
38 | |||
39 | /* TBD */ | ||
40 | static struct resource pci_io_resource = { | ||
41 | .start = PCI_IO_START, | ||
42 | .end = PCI_IO_END, | ||
43 | .name = "PCI IO space", | ||
44 | .flags = IORESOURCE_IO | ||
45 | }; | ||
46 | |||
47 | static struct resource pci_mem_resource = { | ||
48 | .start = PCI_MEM_START, | ||
49 | .end = PCI_MEM_END, | ||
50 | .name = "PCI memory space", | ||
51 | .flags = IORESOURCE_MEM | ||
52 | }; | ||
53 | |||
54 | extern struct pci_ops au1x_pci_ops; | ||
55 | |||
56 | static struct pci_controller au1x_controller = { | ||
57 | .pci_ops = &au1x_pci_ops, | ||
58 | .io_resource = &pci_io_resource, | ||
59 | .mem_resource = &pci_mem_resource, | ||
60 | }; | ||
61 | |||
62 | #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) | ||
63 | static unsigned long virt_io_addr; | ||
64 | #endif | ||
65 | |||
66 | static int __init au1x_pci_setup(void) | ||
67 | { | ||
68 | extern void au1x_pci_cfg_init(void); | ||
69 | |||
70 | #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) | ||
71 | virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, | ||
72 | Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1); | ||
73 | |||
74 | if (!virt_io_addr) { | ||
75 | printk(KERN_ERR "Unable to ioremap pci space\n"); | ||
76 | return 1; | ||
77 | } | ||
78 | au1x_controller.io_map_base = virt_io_addr; | ||
79 | |||
80 | #ifdef CONFIG_DMA_NONCOHERENT | ||
81 | { | ||
82 | /* | ||
83 | * Set the NC bit in controller for Au1500 pre-AC silicon | ||
84 | */ | ||
85 | u32 prid = read_c0_prid(); | ||
86 | |||
87 | if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) { | ||
88 | au_writel((1 << 16) | au_readl(Au1500_PCI_CFG), | ||
89 | Au1500_PCI_CFG); | ||
90 | printk(KERN_INFO "Non-coherent PCI accesses enabled\n"); | ||
91 | } | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | set_io_port_base(virt_io_addr); | ||
96 | #endif | ||
97 | |||
98 | au1x_pci_cfg_init(); | ||
99 | |||
100 | register_pci_controller(&au1x_controller); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | arch_initcall(au1x_pci_setup); | ||
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index f72c48d4804c..c8e5d72a5826 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/serial_8250.h> | 18 | #include <linux/serial_8250.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | 20 | ||
21 | #include <asm/mach-au1x00/au1xxx.h> | 21 | #include <asm/mach-au1x00/au1000.h> |
22 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 22 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
23 | #include <asm/mach-au1x00/au1100_mmc.h> | 23 | #include <asm/mach-au1x00/au1100_mmc.h> |
24 | #include <asm/mach-au1x00/au1xxx_eth.h> | 24 | #include <asm/mach-au1x00/au1xxx_eth.h> |
@@ -111,270 +111,87 @@ static void __init alchemy_setup_uarts(int ctype) | |||
111 | printk(KERN_INFO "Alchemy: failed to register UARTs\n"); | 111 | printk(KERN_INFO "Alchemy: failed to register UARTs\n"); |
112 | } | 112 | } |
113 | 113 | ||
114 | /* OHCI (USB full speed host controller) */ | ||
115 | static struct resource au1xxx_usb_ohci_resources[] = { | ||
116 | [0] = { | ||
117 | .start = USB_OHCI_BASE, | ||
118 | .end = USB_OHCI_BASE + USB_OHCI_LEN - 1, | ||
119 | .flags = IORESOURCE_MEM, | ||
120 | }, | ||
121 | [1] = { | ||
122 | .start = FOR_PLATFORM_C_USB_HOST_INT, | ||
123 | .end = FOR_PLATFORM_C_USB_HOST_INT, | ||
124 | .flags = IORESOURCE_IRQ, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | /* The dmamask must be set for OHCI to work */ | ||
129 | static u64 ohci_dmamask = DMA_BIT_MASK(32); | ||
130 | |||
131 | static struct platform_device au1xxx_usb_ohci_device = { | ||
132 | .name = "au1xxx-ohci", | ||
133 | .id = 0, | ||
134 | .dev = { | ||
135 | .dma_mask = &ohci_dmamask, | ||
136 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
137 | }, | ||
138 | .num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources), | ||
139 | .resource = au1xxx_usb_ohci_resources, | ||
140 | }; | ||
141 | |||
142 | /*** AU1100 LCD controller ***/ | ||
143 | |||
144 | #ifdef CONFIG_FB_AU1100 | ||
145 | static struct resource au1100_lcd_resources[] = { | ||
146 | [0] = { | ||
147 | .start = LCD_PHYS_ADDR, | ||
148 | .end = LCD_PHYS_ADDR + 0x800 - 1, | ||
149 | .flags = IORESOURCE_MEM, | ||
150 | }, | ||
151 | [1] = { | ||
152 | .start = AU1100_LCD_INT, | ||
153 | .end = AU1100_LCD_INT, | ||
154 | .flags = IORESOURCE_IRQ, | ||
155 | } | ||
156 | }; | ||
157 | |||
158 | static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); | ||
159 | |||
160 | static struct platform_device au1100_lcd_device = { | ||
161 | .name = "au1100-lcd", | ||
162 | .id = 0, | ||
163 | .dev = { | ||
164 | .dma_mask = &au1100_lcd_dmamask, | ||
165 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
166 | }, | ||
167 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
168 | .resource = au1100_lcd_resources, | ||
169 | }; | ||
170 | #endif | ||
171 | |||
172 | #ifdef CONFIG_SOC_AU1200 | ||
173 | /* EHCI (USB high speed host controller) */ | ||
174 | static struct resource au1xxx_usb_ehci_resources[] = { | ||
175 | [0] = { | ||
176 | .start = USB_EHCI_BASE, | ||
177 | .end = USB_EHCI_BASE + USB_EHCI_LEN - 1, | ||
178 | .flags = IORESOURCE_MEM, | ||
179 | }, | ||
180 | [1] = { | ||
181 | .start = AU1200_USB_INT, | ||
182 | .end = AU1200_USB_INT, | ||
183 | .flags = IORESOURCE_IRQ, | ||
184 | }, | ||
185 | }; | ||
186 | |||
187 | static u64 ehci_dmamask = DMA_BIT_MASK(32); | ||
188 | |||
189 | static struct platform_device au1xxx_usb_ehci_device = { | ||
190 | .name = "au1xxx-ehci", | ||
191 | .id = 0, | ||
192 | .dev = { | ||
193 | .dma_mask = &ehci_dmamask, | ||
194 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
195 | }, | ||
196 | .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources), | ||
197 | .resource = au1xxx_usb_ehci_resources, | ||
198 | }; | ||
199 | |||
200 | /* Au1200 UDC (USB gadget controller) */ | ||
201 | static struct resource au1xxx_usb_gdt_resources[] = { | ||
202 | [0] = { | ||
203 | .start = USB_UDC_BASE, | ||
204 | .end = USB_UDC_BASE + USB_UDC_LEN - 1, | ||
205 | .flags = IORESOURCE_MEM, | ||
206 | }, | ||
207 | [1] = { | ||
208 | .start = AU1200_USB_INT, | ||
209 | .end = AU1200_USB_INT, | ||
210 | .flags = IORESOURCE_IRQ, | ||
211 | }, | ||
212 | }; | ||
213 | |||
214 | static u64 udc_dmamask = DMA_BIT_MASK(32); | ||
215 | 114 | ||
216 | static struct platform_device au1xxx_usb_gdt_device = { | 115 | /* The dmamask must be set for OHCI/EHCI to work */ |
217 | .name = "au1xxx-udc", | 116 | static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32); |
218 | .id = 0, | 117 | static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32); |
219 | .dev = { | ||
220 | .dma_mask = &udc_dmamask, | ||
221 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
222 | }, | ||
223 | .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources), | ||
224 | .resource = au1xxx_usb_gdt_resources, | ||
225 | }; | ||
226 | 118 | ||
227 | /* Au1200 UOC (USB OTG controller) */ | 119 | static unsigned long alchemy_ohci_data[][2] __initdata = { |
228 | static struct resource au1xxx_usb_otg_resources[] = { | 120 | [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, |
229 | [0] = { | 121 | [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, |
230 | .start = USB_UOC_BASE, | 122 | [ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT }, |
231 | .end = USB_UOC_BASE + USB_UOC_LEN - 1, | 123 | [ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT }, |
232 | .flags = IORESOURCE_MEM, | 124 | [ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT }, |
233 | }, | ||
234 | [1] = { | ||
235 | .start = AU1200_USB_INT, | ||
236 | .end = AU1200_USB_INT, | ||
237 | .flags = IORESOURCE_IRQ, | ||
238 | }, | ||
239 | }; | 125 | }; |
240 | 126 | ||
241 | static u64 uoc_dmamask = DMA_BIT_MASK(32); | 127 | static unsigned long alchemy_ehci_data[][2] __initdata = { |
242 | 128 | [ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT }, | |
243 | static struct platform_device au1xxx_usb_otg_device = { | ||
244 | .name = "au1xxx-uoc", | ||
245 | .id = 0, | ||
246 | .dev = { | ||
247 | .dma_mask = &uoc_dmamask, | ||
248 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
249 | }, | ||
250 | .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources), | ||
251 | .resource = au1xxx_usb_otg_resources, | ||
252 | }; | 129 | }; |
253 | 130 | ||
254 | static struct resource au1200_lcd_resources[] = { | 131 | static int __init _new_usbres(struct resource **r, struct platform_device **d) |
255 | [0] = { | 132 | { |
256 | .start = LCD_PHYS_ADDR, | 133 | *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); |
257 | .end = LCD_PHYS_ADDR + 0x800 - 1, | 134 | if (!*r) |
258 | .flags = IORESOURCE_MEM, | 135 | return -ENOMEM; |
259 | }, | 136 | *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL); |
260 | [1] = { | 137 | if (!*d) { |
261 | .start = AU1200_LCD_INT, | 138 | kfree(*r); |
262 | .end = AU1200_LCD_INT, | 139 | return -ENOMEM; |
263 | .flags = IORESOURCE_IRQ, | ||
264 | } | 140 | } |
265 | }; | ||
266 | |||
267 | static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32); | ||
268 | |||
269 | static struct platform_device au1200_lcd_device = { | ||
270 | .name = "au1200-lcd", | ||
271 | .id = 0, | ||
272 | .dev = { | ||
273 | .dma_mask = &au1200_lcd_dmamask, | ||
274 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
275 | }, | ||
276 | .num_resources = ARRAY_SIZE(au1200_lcd_resources), | ||
277 | .resource = au1200_lcd_resources, | ||
278 | }; | ||
279 | 141 | ||
280 | static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); | 142 | (*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
143 | (*d)->num_resources = 2; | ||
144 | (*d)->resource = *r; | ||
281 | 145 | ||
282 | extern struct au1xmmc_platform_data au1xmmc_platdata[2]; | 146 | return 0; |
147 | } | ||
283 | 148 | ||
284 | static struct resource au1200_mmc0_resources[] = { | 149 | static void __init alchemy_setup_usb(int ctype) |
285 | [0] = { | 150 | { |
286 | .start = AU1100_SD0_PHYS_ADDR, | 151 | struct resource *res; |
287 | .end = AU1100_SD0_PHYS_ADDR + 0xfff, | 152 | struct platform_device *pdev; |
288 | .flags = IORESOURCE_MEM, | ||
289 | }, | ||
290 | [1] = { | ||
291 | .start = AU1200_SD_INT, | ||
292 | .end = AU1200_SD_INT, | ||
293 | .flags = IORESOURCE_IRQ, | ||
294 | }, | ||
295 | [2] = { | ||
296 | .start = DSCR_CMD0_SDMS_TX0, | ||
297 | .end = DSCR_CMD0_SDMS_TX0, | ||
298 | .flags = IORESOURCE_DMA, | ||
299 | }, | ||
300 | [3] = { | ||
301 | .start = DSCR_CMD0_SDMS_RX0, | ||
302 | .end = DSCR_CMD0_SDMS_RX0, | ||
303 | .flags = IORESOURCE_DMA, | ||
304 | } | ||
305 | }; | ||
306 | 153 | ||
307 | static struct platform_device au1200_mmc0_device = { | 154 | /* setup OHCI0. Every variant has one */ |
308 | .name = "au1xxx-mmc", | 155 | if (_new_usbres(&res, &pdev)) |
309 | .id = 0, | 156 | return; |
310 | .dev = { | ||
311 | .dma_mask = &au1xxx_mmc_dmamask, | ||
312 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
313 | .platform_data = &au1xmmc_platdata[0], | ||
314 | }, | ||
315 | .num_resources = ARRAY_SIZE(au1200_mmc0_resources), | ||
316 | .resource = au1200_mmc0_resources, | ||
317 | }; | ||
318 | 157 | ||
319 | #ifndef CONFIG_MIPS_DB1200 | 158 | res[0].start = alchemy_ohci_data[ctype][0]; |
320 | static struct resource au1200_mmc1_resources[] = { | 159 | res[0].end = res[0].start + 0x100 - 1; |
321 | [0] = { | 160 | res[0].flags = IORESOURCE_MEM; |
322 | .start = AU1100_SD1_PHYS_ADDR, | 161 | res[1].start = alchemy_ohci_data[ctype][1]; |
323 | .end = AU1100_SD1_PHYS_ADDR + 0xfff, | 162 | res[1].end = res[1].start; |
324 | .flags = IORESOURCE_MEM, | 163 | res[1].flags = IORESOURCE_IRQ; |
325 | }, | 164 | pdev->name = "au1xxx-ohci"; |
326 | [1] = { | 165 | pdev->id = 0; |
327 | .start = AU1200_SD_INT, | 166 | pdev->dev.dma_mask = &alchemy_ohci_dmamask; |
328 | .end = AU1200_SD_INT, | 167 | |
329 | .flags = IORESOURCE_IRQ, | 168 | if (platform_device_register(pdev)) |
330 | }, | 169 | printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n"); |
331 | [2] = { | 170 | |
332 | .start = DSCR_CMD0_SDMS_TX1, | 171 | |
333 | .end = DSCR_CMD0_SDMS_TX1, | 172 | /* setup EHCI0: Au1200 */ |
334 | .flags = IORESOURCE_DMA, | 173 | if (ctype == ALCHEMY_CPU_AU1200) { |
335 | }, | 174 | if (_new_usbres(&res, &pdev)) |
336 | [3] = { | 175 | return; |
337 | .start = DSCR_CMD0_SDMS_RX1, | 176 | |
338 | .end = DSCR_CMD0_SDMS_RX1, | 177 | res[0].start = alchemy_ehci_data[ctype][0]; |
339 | .flags = IORESOURCE_DMA, | 178 | res[0].end = res[0].start + 0x100 - 1; |
179 | res[0].flags = IORESOURCE_MEM; | ||
180 | res[1].start = alchemy_ehci_data[ctype][1]; | ||
181 | res[1].end = res[1].start; | ||
182 | res[1].flags = IORESOURCE_IRQ; | ||
183 | pdev->name = "au1xxx-ehci"; | ||
184 | pdev->id = 0; | ||
185 | pdev->dev.dma_mask = &alchemy_ehci_dmamask; | ||
186 | |||
187 | if (platform_device_register(pdev)) | ||
188 | printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n"); | ||
340 | } | 189 | } |
341 | }; | 190 | } |
342 | |||
343 | static struct platform_device au1200_mmc1_device = { | ||
344 | .name = "au1xxx-mmc", | ||
345 | .id = 1, | ||
346 | .dev = { | ||
347 | .dma_mask = &au1xxx_mmc_dmamask, | ||
348 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
349 | .platform_data = &au1xmmc_platdata[1], | ||
350 | }, | ||
351 | .num_resources = ARRAY_SIZE(au1200_mmc1_resources), | ||
352 | .resource = au1200_mmc1_resources, | ||
353 | }; | ||
354 | #endif /* #ifndef CONFIG_MIPS_DB1200 */ | ||
355 | #endif /* #ifdef CONFIG_SOC_AU1200 */ | ||
356 | |||
357 | /* All Alchemy demoboards with I2C have this #define in their headers */ | ||
358 | #ifdef SMBUS_PSC_BASE | ||
359 | static struct resource pbdb_smbus_resources[] = { | ||
360 | { | ||
361 | .start = CPHYSADDR(SMBUS_PSC_BASE), | ||
362 | .end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff), | ||
363 | .flags = IORESOURCE_MEM, | ||
364 | }, | ||
365 | }; | ||
366 | |||
367 | static struct platform_device pbdb_smbus_device = { | ||
368 | .name = "au1xpsc_smbus", | ||
369 | .id = 0, /* bus number */ | ||
370 | .num_resources = ARRAY_SIZE(pbdb_smbus_resources), | ||
371 | .resource = pbdb_smbus_resources, | ||
372 | }; | ||
373 | #endif | ||
374 | 191 | ||
375 | /* Macro to help defining the Ethernet MAC resources */ | 192 | /* Macro to help defining the Ethernet MAC resources */ |
376 | #define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */ | 193 | #define MAC_RES_COUNT 4 /* MAC regs, MAC en, MAC INT, MACDMA regs */ |
377 | #define MAC_RES(_base, _enable, _irq) \ | 194 | #define MAC_RES(_base, _enable, _irq, _macdma) \ |
378 | { \ | 195 | { \ |
379 | .start = _base, \ | 196 | .start = _base, \ |
380 | .end = _base + 0xffff, \ | 197 | .end = _base + 0xffff, \ |
@@ -389,28 +206,37 @@ static struct platform_device pbdb_smbus_device = { | |||
389 | .start = _irq, \ | 206 | .start = _irq, \ |
390 | .end = _irq, \ | 207 | .end = _irq, \ |
391 | .flags = IORESOURCE_IRQ \ | 208 | .flags = IORESOURCE_IRQ \ |
209 | }, \ | ||
210 | { \ | ||
211 | .start = _macdma, \ | ||
212 | .end = _macdma + 0x1ff, \ | ||
213 | .flags = IORESOURCE_MEM, \ | ||
392 | } | 214 | } |
393 | 215 | ||
394 | static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { | 216 | static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { |
395 | [ALCHEMY_CPU_AU1000] = { | 217 | [ALCHEMY_CPU_AU1000] = { |
396 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | 218 | MAC_RES(AU1000_MAC0_PHYS_ADDR, |
397 | AU1000_MACEN_PHYS_ADDR, | 219 | AU1000_MACEN_PHYS_ADDR, |
398 | AU1000_MAC0_DMA_INT) | 220 | AU1000_MAC0_DMA_INT, |
221 | AU1000_MACDMA0_PHYS_ADDR) | ||
399 | }, | 222 | }, |
400 | [ALCHEMY_CPU_AU1500] = { | 223 | [ALCHEMY_CPU_AU1500] = { |
401 | MAC_RES(AU1500_MAC0_PHYS_ADDR, | 224 | MAC_RES(AU1500_MAC0_PHYS_ADDR, |
402 | AU1500_MACEN_PHYS_ADDR, | 225 | AU1500_MACEN_PHYS_ADDR, |
403 | AU1500_MAC0_DMA_INT) | 226 | AU1500_MAC0_DMA_INT, |
227 | AU1000_MACDMA0_PHYS_ADDR) | ||
404 | }, | 228 | }, |
405 | [ALCHEMY_CPU_AU1100] = { | 229 | [ALCHEMY_CPU_AU1100] = { |
406 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | 230 | MAC_RES(AU1000_MAC0_PHYS_ADDR, |
407 | AU1000_MACEN_PHYS_ADDR, | 231 | AU1000_MACEN_PHYS_ADDR, |
408 | AU1100_MAC0_DMA_INT) | 232 | AU1100_MAC0_DMA_INT, |
233 | AU1000_MACDMA0_PHYS_ADDR) | ||
409 | }, | 234 | }, |
410 | [ALCHEMY_CPU_AU1550] = { | 235 | [ALCHEMY_CPU_AU1550] = { |
411 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | 236 | MAC_RES(AU1000_MAC0_PHYS_ADDR, |
412 | AU1000_MACEN_PHYS_ADDR, | 237 | AU1000_MACEN_PHYS_ADDR, |
413 | AU1550_MAC0_DMA_INT) | 238 | AU1550_MAC0_DMA_INT, |
239 | AU1000_MACDMA0_PHYS_ADDR) | ||
414 | }, | 240 | }, |
415 | }; | 241 | }; |
416 | 242 | ||
@@ -429,17 +255,20 @@ static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = { | |||
429 | [ALCHEMY_CPU_AU1000] = { | 255 | [ALCHEMY_CPU_AU1000] = { |
430 | MAC_RES(AU1000_MAC1_PHYS_ADDR, | 256 | MAC_RES(AU1000_MAC1_PHYS_ADDR, |
431 | AU1000_MACEN_PHYS_ADDR + 4, | 257 | AU1000_MACEN_PHYS_ADDR + 4, |
432 | AU1000_MAC1_DMA_INT) | 258 | AU1000_MAC1_DMA_INT, |
259 | AU1000_MACDMA1_PHYS_ADDR) | ||
433 | }, | 260 | }, |
434 | [ALCHEMY_CPU_AU1500] = { | 261 | [ALCHEMY_CPU_AU1500] = { |
435 | MAC_RES(AU1500_MAC1_PHYS_ADDR, | 262 | MAC_RES(AU1500_MAC1_PHYS_ADDR, |
436 | AU1500_MACEN_PHYS_ADDR + 4, | 263 | AU1500_MACEN_PHYS_ADDR + 4, |
437 | AU1500_MAC1_DMA_INT) | 264 | AU1500_MAC1_DMA_INT, |
265 | AU1000_MACDMA1_PHYS_ADDR) | ||
438 | }, | 266 | }, |
439 | [ALCHEMY_CPU_AU1550] = { | 267 | [ALCHEMY_CPU_AU1550] = { |
440 | MAC_RES(AU1000_MAC1_PHYS_ADDR, | 268 | MAC_RES(AU1000_MAC1_PHYS_ADDR, |
441 | AU1000_MACEN_PHYS_ADDR + 4, | 269 | AU1000_MACEN_PHYS_ADDR + 4, |
442 | AU1550_MAC1_DMA_INT) | 270 | AU1550_MAC1_DMA_INT, |
271 | AU1000_MACDMA1_PHYS_ADDR) | ||
443 | }, | 272 | }, |
444 | }; | 273 | }; |
445 | 274 | ||
@@ -521,36 +350,15 @@ static void __init alchemy_setup_macs(int ctype) | |||
521 | } | 350 | } |
522 | } | 351 | } |
523 | 352 | ||
524 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | ||
525 | &au1xxx_usb_ohci_device, | ||
526 | #ifdef CONFIG_FB_AU1100 | ||
527 | &au1100_lcd_device, | ||
528 | #endif | ||
529 | #ifdef CONFIG_SOC_AU1200 | ||
530 | &au1xxx_usb_ehci_device, | ||
531 | &au1xxx_usb_gdt_device, | ||
532 | &au1xxx_usb_otg_device, | ||
533 | &au1200_lcd_device, | ||
534 | &au1200_mmc0_device, | ||
535 | #ifndef CONFIG_MIPS_DB1200 | ||
536 | &au1200_mmc1_device, | ||
537 | #endif | ||
538 | #endif | ||
539 | #ifdef SMBUS_PSC_BASE | ||
540 | &pbdb_smbus_device, | ||
541 | #endif | ||
542 | }; | ||
543 | |||
544 | static int __init au1xxx_platform_init(void) | 353 | static int __init au1xxx_platform_init(void) |
545 | { | 354 | { |
546 | int err, ctype = alchemy_get_cputype(); | 355 | int ctype = alchemy_get_cputype(); |
547 | 356 | ||
548 | alchemy_setup_uarts(ctype); | 357 | alchemy_setup_uarts(ctype); |
549 | alchemy_setup_macs(ctype); | 358 | alchemy_setup_macs(ctype); |
359 | alchemy_setup_usb(ctype); | ||
550 | 360 | ||
551 | err = platform_add_devices(au1xxx_platform_devices, | 361 | return 0; |
552 | ARRAY_SIZE(au1xxx_platform_devices)); | ||
553 | return err; | ||
554 | } | 362 | } |
555 | 363 | ||
556 | arch_initcall(au1xxx_platform_init); | 364 | arch_initcall(au1xxx_platform_init); |
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index b86324a42601..bdd6651e9a4f 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | #include <asm/mach-au1x00/au1000.h> | 38 | #include <asm/mach-au1x00/au1000.h> |
39 | 39 | ||
40 | #ifdef CONFIG_PM | ||
41 | |||
42 | /* | 40 | /* |
43 | * We need to save/restore a bunch of core registers that are | 41 | * We need to save/restore a bunch of core registers that are |
44 | * either volatile or reset to some state across a processor sleep. | 42 | * either volatile or reset to some state across a processor sleep. |
@@ -49,7 +47,6 @@ | |||
49 | * We only have to save/restore registers that aren't otherwise | 47 | * We only have to save/restore registers that aren't otherwise |
50 | * done as part of a driver pm_* function. | 48 | * done as part of a driver pm_* function. |
51 | */ | 49 | */ |
52 | static unsigned int sleep_usb[2]; | ||
53 | static unsigned int sleep_sys_clocks[5]; | 50 | static unsigned int sleep_sys_clocks[5]; |
54 | static unsigned int sleep_sys_pinfunc; | 51 | static unsigned int sleep_sys_pinfunc; |
55 | static unsigned int sleep_static_memctlr[4][3]; | 52 | static unsigned int sleep_static_memctlr[4][3]; |
@@ -57,31 +54,6 @@ static unsigned int sleep_static_memctlr[4][3]; | |||
57 | 54 | ||
58 | static void save_core_regs(void) | 55 | static void save_core_regs(void) |
59 | { | 56 | { |
60 | #ifndef CONFIG_SOC_AU1200 | ||
61 | /* Shutdown USB host/device. */ | ||
62 | sleep_usb[0] = au_readl(USB_HOST_CONFIG); | ||
63 | |||
64 | /* There appears to be some undocumented reset register.... */ | ||
65 | au_writel(0, 0xb0100004); | ||
66 | au_sync(); | ||
67 | au_writel(0, USB_HOST_CONFIG); | ||
68 | au_sync(); | ||
69 | |||
70 | sleep_usb[1] = au_readl(USBD_ENABLE); | ||
71 | au_writel(0, USBD_ENABLE); | ||
72 | au_sync(); | ||
73 | |||
74 | #else /* AU1200 */ | ||
75 | |||
76 | /* enable access to OTG mmio so we can save OTG CAP/MUX. | ||
77 | * FIXME: write an OTG driver and move this stuff there! | ||
78 | */ | ||
79 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
80 | au_sync(); | ||
81 | sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */ | ||
82 | sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */ | ||
83 | #endif | ||
84 | |||
85 | /* Clocks and PLLs. */ | 57 | /* Clocks and PLLs. */ |
86 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); | 58 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); |
87 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); | 59 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); |
@@ -125,22 +97,6 @@ static void restore_core_regs(void) | |||
125 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); | 97 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); |
126 | au_sync(); | 98 | au_sync(); |
127 | 99 | ||
128 | #ifndef CONFIG_SOC_AU1200 | ||
129 | au_writel(sleep_usb[0], USB_HOST_CONFIG); | ||
130 | au_writel(sleep_usb[1], USBD_ENABLE); | ||
131 | au_sync(); | ||
132 | #else | ||
133 | /* enable access to OTG memory */ | ||
134 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
135 | au_sync(); | ||
136 | |||
137 | /* restore OTG caps and port mux. */ | ||
138 | au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */ | ||
139 | au_sync(); | ||
140 | au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */ | ||
141 | au_sync(); | ||
142 | #endif | ||
143 | |||
144 | /* Restore the static memory controller configuration. */ | 100 | /* Restore the static memory controller configuration. */ |
145 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); | 101 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); |
146 | au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); | 102 | au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); |
@@ -174,5 +130,3 @@ void au_sleep(void) | |||
174 | 130 | ||
175 | restore_core_regs(); | 131 | restore_core_regs(); |
176 | } | 132 | } |
177 | |||
178 | #endif /* CONFIG_PM */ | ||
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 1b887c868417..37ffd997c616 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -73,8 +73,8 @@ void __init plat_mem_setup(void) | |||
73 | /* This routine should be valid for all Au1x based boards */ | 73 | /* This routine should be valid for all Au1x based boards */ |
74 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 74 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) |
75 | { | 75 | { |
76 | u32 start = (u32)Au1500_PCI_MEM_START; | 76 | unsigned long start = ALCHEMY_PCI_MEMWIN_START; |
77 | u32 end = (u32)Au1500_PCI_MEM_END; | 77 | unsigned long end = ALCHEMY_PCI_MEMWIN_END; |
78 | 78 | ||
79 | /* Don't fixup 36-bit addresses */ | 79 | /* Don't fixup 36-bit addresses */ |
80 | if ((phys_addr >> 32) != 0) | 80 | if ((phys_addr >> 32) != 0) |
@@ -82,7 +82,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
82 | 82 | ||
83 | /* Check for PCI memory window */ | 83 | /* Check for PCI memory window */ |
84 | if (phys_addr >= start && (phys_addr + size - 1) <= end) | 84 | if (phys_addr >= start && (phys_addr + size - 1) <= end) |
85 | return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START); | 85 | return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); |
86 | 86 | ||
87 | /* default nop */ | 87 | /* default nop */ |
88 | return phys_addr; | 88 | return phys_addr; |
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c index dda090bf74e6..c61867c93c4a 100644 --- a/arch/mips/alchemy/devboards/db1200/platform.c +++ b/arch/mips/alchemy/devboards/db1200/platform.c | |||
@@ -213,7 +213,12 @@ static struct resource db1200_ide_res[] = { | |||
213 | .start = DB1200_IDE_INT, | 213 | .start = DB1200_IDE_INT, |
214 | .end = DB1200_IDE_INT, | 214 | .end = DB1200_IDE_INT, |
215 | .flags = IORESOURCE_IRQ, | 215 | .flags = IORESOURCE_IRQ, |
216 | } | 216 | }, |
217 | [2] = { | ||
218 | .start = AU1200_DSCR_CMD0_DMA_REQ1, | ||
219 | .end = AU1200_DSCR_CMD0_DMA_REQ1, | ||
220 | .flags = IORESOURCE_DMA, | ||
221 | }, | ||
217 | }; | 222 | }; |
218 | 223 | ||
219 | static u64 ide_dmamask = DMA_BIT_MASK(32); | 224 | static u64 ide_dmamask = DMA_BIT_MASK(32); |
@@ -328,23 +333,85 @@ static struct led_classdev db1200_mmc_led = { | |||
328 | .brightness_set = db1200_mmcled_set, | 333 | .brightness_set = db1200_mmcled_set, |
329 | }; | 334 | }; |
330 | 335 | ||
331 | /* needed by arch/mips/alchemy/common/platform.c */ | 336 | static struct au1xmmc_platform_data db1200mmc_platdata = { |
332 | struct au1xmmc_platform_data au1xmmc_platdata[] = { | 337 | .cd_setup = db1200_mmc_cd_setup, |
338 | .set_power = db1200_mmc_set_power, | ||
339 | .card_inserted = db1200_mmc_card_inserted, | ||
340 | .card_readonly = db1200_mmc_card_readonly, | ||
341 | .led = &db1200_mmc_led, | ||
342 | }; | ||
343 | |||
344 | static struct resource au1200_mmc0_resources[] = { | ||
333 | [0] = { | 345 | [0] = { |
334 | .cd_setup = db1200_mmc_cd_setup, | 346 | .start = AU1100_SD0_PHYS_ADDR, |
335 | .set_power = db1200_mmc_set_power, | 347 | .end = AU1100_SD0_PHYS_ADDR + 0xfff, |
336 | .card_inserted = db1200_mmc_card_inserted, | 348 | .flags = IORESOURCE_MEM, |
337 | .card_readonly = db1200_mmc_card_readonly, | 349 | }, |
338 | .led = &db1200_mmc_led, | 350 | [1] = { |
351 | .start = AU1200_SD_INT, | ||
352 | .end = AU1200_SD_INT, | ||
353 | .flags = IORESOURCE_IRQ, | ||
354 | }, | ||
355 | [2] = { | ||
356 | .start = AU1200_DSCR_CMD0_SDMS_TX0, | ||
357 | .end = AU1200_DSCR_CMD0_SDMS_TX0, | ||
358 | .flags = IORESOURCE_DMA, | ||
359 | }, | ||
360 | [3] = { | ||
361 | .start = AU1200_DSCR_CMD0_SDMS_RX0, | ||
362 | .end = AU1200_DSCR_CMD0_SDMS_RX0, | ||
363 | .flags = IORESOURCE_DMA, | ||
364 | } | ||
365 | }; | ||
366 | |||
367 | static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); | ||
368 | |||
369 | static struct platform_device db1200_mmc0_dev = { | ||
370 | .name = "au1xxx-mmc", | ||
371 | .id = 0, | ||
372 | .dev = { | ||
373 | .dma_mask = &au1xxx_mmc_dmamask, | ||
374 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
375 | .platform_data = &db1200mmc_platdata, | ||
376 | }, | ||
377 | .num_resources = ARRAY_SIZE(au1200_mmc0_resources), | ||
378 | .resource = au1200_mmc0_resources, | ||
379 | }; | ||
380 | |||
381 | /**********************************************************************/ | ||
382 | |||
383 | static struct resource au1200_lcd_res[] = { | ||
384 | [0] = { | ||
385 | .start = AU1200_LCD_PHYS_ADDR, | ||
386 | .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1, | ||
387 | .flags = IORESOURCE_MEM, | ||
388 | }, | ||
389 | [1] = { | ||
390 | .start = AU1200_LCD_INT, | ||
391 | .end = AU1200_LCD_INT, | ||
392 | .flags = IORESOURCE_IRQ, | ||
393 | } | ||
394 | }; | ||
395 | |||
396 | static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32); | ||
397 | |||
398 | static struct platform_device au1200_lcd_dev = { | ||
399 | .name = "au1200-lcd", | ||
400 | .id = 0, | ||
401 | .dev = { | ||
402 | .dma_mask = &au1200_lcd_dmamask, | ||
403 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
339 | }, | 404 | }, |
405 | .num_resources = ARRAY_SIZE(au1200_lcd_res), | ||
406 | .resource = au1200_lcd_res, | ||
340 | }; | 407 | }; |
341 | 408 | ||
342 | /**********************************************************************/ | 409 | /**********************************************************************/ |
343 | 410 | ||
344 | static struct resource au1200_psc0_res[] = { | 411 | static struct resource au1200_psc0_res[] = { |
345 | [0] = { | 412 | [0] = { |
346 | .start = PSC0_PHYS_ADDR, | 413 | .start = AU1550_PSC0_PHYS_ADDR, |
347 | .end = PSC0_PHYS_ADDR + 0x000fffff, | 414 | .end = AU1550_PSC0_PHYS_ADDR + 0xfff, |
348 | .flags = IORESOURCE_MEM, | 415 | .flags = IORESOURCE_MEM, |
349 | }, | 416 | }, |
350 | [1] = { | 417 | [1] = { |
@@ -353,13 +420,13 @@ static struct resource au1200_psc0_res[] = { | |||
353 | .flags = IORESOURCE_IRQ, | 420 | .flags = IORESOURCE_IRQ, |
354 | }, | 421 | }, |
355 | [2] = { | 422 | [2] = { |
356 | .start = DSCR_CMD0_PSC0_TX, | 423 | .start = AU1200_DSCR_CMD0_PSC0_TX, |
357 | .end = DSCR_CMD0_PSC0_TX, | 424 | .end = AU1200_DSCR_CMD0_PSC0_TX, |
358 | .flags = IORESOURCE_DMA, | 425 | .flags = IORESOURCE_DMA, |
359 | }, | 426 | }, |
360 | [3] = { | 427 | [3] = { |
361 | .start = DSCR_CMD0_PSC0_RX, | 428 | .start = AU1200_DSCR_CMD0_PSC0_RX, |
362 | .end = DSCR_CMD0_PSC0_RX, | 429 | .end = AU1200_DSCR_CMD0_PSC0_RX, |
363 | .flags = IORESOURCE_DMA, | 430 | .flags = IORESOURCE_DMA, |
364 | }, | 431 | }, |
365 | }; | 432 | }; |
@@ -401,8 +468,8 @@ static struct platform_device db1200_spi_dev = { | |||
401 | 468 | ||
402 | static struct resource au1200_psc1_res[] = { | 469 | static struct resource au1200_psc1_res[] = { |
403 | [0] = { | 470 | [0] = { |
404 | .start = PSC1_PHYS_ADDR, | 471 | .start = AU1550_PSC1_PHYS_ADDR, |
405 | .end = PSC1_PHYS_ADDR + 0x000fffff, | 472 | .end = AU1550_PSC1_PHYS_ADDR + 0xfff, |
406 | .flags = IORESOURCE_MEM, | 473 | .flags = IORESOURCE_MEM, |
407 | }, | 474 | }, |
408 | [1] = { | 475 | [1] = { |
@@ -411,13 +478,13 @@ static struct resource au1200_psc1_res[] = { | |||
411 | .flags = IORESOURCE_IRQ, | 478 | .flags = IORESOURCE_IRQ, |
412 | }, | 479 | }, |
413 | [2] = { | 480 | [2] = { |
414 | .start = DSCR_CMD0_PSC1_TX, | 481 | .start = AU1200_DSCR_CMD0_PSC1_TX, |
415 | .end = DSCR_CMD0_PSC1_TX, | 482 | .end = AU1200_DSCR_CMD0_PSC1_TX, |
416 | .flags = IORESOURCE_DMA, | 483 | .flags = IORESOURCE_DMA, |
417 | }, | 484 | }, |
418 | [3] = { | 485 | [3] = { |
419 | .start = DSCR_CMD0_PSC1_RX, | 486 | .start = AU1200_DSCR_CMD0_PSC1_RX, |
420 | .end = DSCR_CMD0_PSC1_RX, | 487 | .end = AU1200_DSCR_CMD0_PSC1_RX, |
421 | .flags = IORESOURCE_DMA, | 488 | .flags = IORESOURCE_DMA, |
422 | }, | 489 | }, |
423 | }; | 490 | }; |
@@ -449,6 +516,8 @@ static struct platform_device db1200_audiodma_dev = { | |||
449 | static struct platform_device *db1200_devs[] __initdata = { | 516 | static struct platform_device *db1200_devs[] __initdata = { |
450 | NULL, /* PSC0, selected by S6.8 */ | 517 | NULL, /* PSC0, selected by S6.8 */ |
451 | &db1200_ide_dev, | 518 | &db1200_ide_dev, |
519 | &db1200_mmc0_dev, | ||
520 | &au1200_lcd_dev, | ||
452 | &db1200_eth_dev, | 521 | &db1200_eth_dev, |
453 | &db1200_rtc_dev, | 522 | &db1200_rtc_dev, |
454 | &db1200_nand_dev, | 523 | &db1200_nand_dev, |
@@ -526,32 +595,28 @@ static int __init db1200_dev_init(void) | |||
526 | 595 | ||
527 | /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ | 596 | /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ |
528 | __raw_writel(PSC_SEL_CLK_SERCLK, | 597 | __raw_writel(PSC_SEL_CLK_SERCLK, |
529 | (void __iomem *)KSEG1ADDR(PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); | 598 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); |
530 | wmb(); | 599 | wmb(); |
531 | 600 | ||
532 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, | 601 | db1x_register_pcmcia_socket( |
533 | PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | 602 | AU1000_PCMCIA_ATTR_PHYS_ADDR, |
534 | PCMCIA_MEM_PHYS_ADDR, | 603 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, |
535 | PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | 604 | AU1000_PCMCIA_MEM_PHYS_ADDR, |
536 | PCMCIA_IO_PHYS_ADDR, | 605 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, |
537 | PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | 606 | AU1000_PCMCIA_IO_PHYS_ADDR, |
538 | DB1200_PC0_INT, | 607 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, |
539 | DB1200_PC0_INSERT_INT, | 608 | DB1200_PC0_INT, DB1200_PC0_INSERT_INT, |
540 | /*DB1200_PC0_STSCHG_INT*/0, | 609 | /*DB1200_PC0_STSCHG_INT*/0, DB1200_PC0_EJECT_INT, 0); |
541 | DB1200_PC0_EJECT_INT, | 610 | |
542 | 0); | 611 | db1x_register_pcmcia_socket( |
543 | 612 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | |
544 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | 613 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, |
545 | PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, | 614 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, |
546 | PCMCIA_MEM_PHYS_ADDR + 0x004000000, | 615 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, |
547 | PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, | 616 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, |
548 | PCMCIA_IO_PHYS_ADDR + 0x004000000, | 617 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, |
549 | PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, | 618 | DB1200_PC1_INT, DB1200_PC1_INSERT_INT, |
550 | DB1200_PC1_INT, | 619 | /*DB1200_PC1_STSCHG_INT*/0, DB1200_PC1_EJECT_INT, 1); |
551 | DB1200_PC1_INSERT_INT, | ||
552 | /*DB1200_PC1_STSCHG_INT*/0, | ||
553 | DB1200_PC1_EJECT_INT, | ||
554 | 1); | ||
555 | 620 | ||
556 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; | 621 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; |
557 | db1x_register_norflash(64 << 20, 2, swapped); | 622 | db1x_register_norflash(64 << 20, 2, swapped); |
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c index 5c956fe8760f..7cd36e631f6c 100644 --- a/arch/mips/alchemy/devboards/db1x00/board_setup.c +++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c | |||
@@ -40,24 +40,6 @@ | |||
40 | 40 | ||
41 | #include <prom.h> | 41 | #include <prom.h> |
42 | 42 | ||
43 | #ifdef CONFIG_MIPS_DB1500 | ||
44 | char irq_tab_alchemy[][5] __initdata = { | ||
45 | [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371 */ | ||
46 | [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */ | ||
47 | }; | ||
48 | |||
49 | #endif | ||
50 | |||
51 | |||
52 | #ifdef CONFIG_MIPS_DB1550 | ||
53 | char irq_tab_alchemy[][5] __initdata = { | ||
54 | [11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 - on-board HPT371 */ | ||
55 | [12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */ | ||
56 | [13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */ | ||
57 | }; | ||
58 | #endif | ||
59 | |||
60 | |||
61 | #ifdef CONFIG_MIPS_BOSPORUS | 43 | #ifdef CONFIG_MIPS_BOSPORUS |
62 | char irq_tab_alchemy[][5] __initdata = { | 44 | char irq_tab_alchemy[][5] __initdata = { |
63 | [11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */ | 45 | [11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */ |
@@ -91,12 +73,6 @@ const char *get_system_type(void) | |||
91 | 73 | ||
92 | 74 | ||
93 | #ifdef CONFIG_MIPS_MIRAGE | 75 | #ifdef CONFIG_MIPS_MIRAGE |
94 | char irq_tab_alchemy[][5] __initdata = { | ||
95 | [11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX */ | ||
96 | [12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300 */ | ||
97 | [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 13 - miniPCI */ | ||
98 | }; | ||
99 | |||
100 | static void mirage_power_off(void) | 76 | static void mirage_power_off(void) |
101 | { | 77 | { |
102 | alchemy_gpio_direction_output(210, 1); | 78 | alchemy_gpio_direction_output(210, 1); |
@@ -158,9 +134,7 @@ void __init board_setup(void) | |||
158 | /* initialize board register space */ | 134 | /* initialize board register space */ |
159 | bcsr_init(bcsr1, bcsr2); | 135 | bcsr_init(bcsr1, bcsr2); |
160 | 136 | ||
161 | /* Not valid for Au1550 */ | 137 | #if defined(CONFIG_IRDA) && defined(CONFIG_AU1000_FIR) |
162 | #if defined(CONFIG_IRDA) && \ | ||
163 | (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) | ||
164 | { | 138 | { |
165 | u32 pin_func; | 139 | u32 pin_func; |
166 | 140 | ||
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c index 7057d28f7301..9e6b3d442acd 100644 --- a/arch/mips/alchemy/devboards/db1x00/platform.c +++ b/arch/mips/alchemy/devboards/db1x00/platform.c | |||
@@ -20,14 +20,16 @@ | |||
20 | 20 | ||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
24 | 25 | ||
25 | #include <asm/mach-au1x00/au1000.h> | 26 | #include <asm/mach-au1x00/au1000.h> |
26 | #include <asm/mach-au1x00/au1000_dma.h> | 27 | #include <asm/mach-au1x00/au1000_dma.h> |
27 | #include <asm/mach-au1x00/au1xxx.h> | ||
28 | #include <asm/mach-db1x00/bcsr.h> | 28 | #include <asm/mach-db1x00/bcsr.h> |
29 | #include "../platform.h" | 29 | #include "../platform.h" |
30 | 30 | ||
31 | struct pci_dev; | ||
32 | |||
31 | /* DB1xxx PCMCIA interrupt sources: | 33 | /* DB1xxx PCMCIA interrupt sources: |
32 | * CD0/1 GPIO0/3 | 34 | * CD0/1 GPIO0/3 |
33 | * STSCHG0/1 GPIO1/4 | 35 | * STSCHG0/1 GPIO1/4 |
@@ -88,6 +90,155 @@ | |||
88 | #endif | 90 | #endif |
89 | #endif | 91 | #endif |
90 | 92 | ||
93 | #ifdef CONFIG_PCI | ||
94 | #ifdef CONFIG_MIPS_DB1500 | ||
95 | static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
96 | { | ||
97 | if ((slot < 12) || (slot > 13) || pin == 0) | ||
98 | return -1; | ||
99 | if (slot == 12) | ||
100 | return (pin == 1) ? AU1500_PCI_INTA : 0xff; | ||
101 | if (slot == 13) { | ||
102 | switch (pin) { | ||
103 | case 1: return AU1500_PCI_INTA; | ||
104 | case 2: return AU1500_PCI_INTB; | ||
105 | case 3: return AU1500_PCI_INTC; | ||
106 | case 4: return AU1500_PCI_INTD; | ||
107 | } | ||
108 | } | ||
109 | return -1; | ||
110 | } | ||
111 | #endif | ||
112 | |||
113 | #ifdef CONFIG_MIPS_DB1550 | ||
114 | static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
115 | { | ||
116 | if ((slot < 11) || (slot > 13) || pin == 0) | ||
117 | return -1; | ||
118 | if (slot == 11) | ||
119 | return (pin == 1) ? AU1550_PCI_INTC : 0xff; | ||
120 | if (slot == 12) { | ||
121 | switch (pin) { | ||
122 | case 1: return AU1550_PCI_INTB; | ||
123 | case 2: return AU1550_PCI_INTC; | ||
124 | case 3: return AU1550_PCI_INTD; | ||
125 | case 4: return AU1550_PCI_INTA; | ||
126 | } | ||
127 | } | ||
128 | if (slot == 13) { | ||
129 | switch (pin) { | ||
130 | case 1: return AU1550_PCI_INTA; | ||
131 | case 2: return AU1550_PCI_INTB; | ||
132 | case 3: return AU1550_PCI_INTC; | ||
133 | case 4: return AU1550_PCI_INTD; | ||
134 | } | ||
135 | } | ||
136 | return -1; | ||
137 | } | ||
138 | #endif | ||
139 | |||
140 | #ifdef CONFIG_MIPS_BOSPORUS | ||
141 | static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
142 | { | ||
143 | if ((slot < 11) || (slot > 13) || pin == 0) | ||
144 | return -1; | ||
145 | if (slot == 12) | ||
146 | return (pin == 1) ? AU1500_PCI_INTA : 0xff; | ||
147 | if (slot == 11) { | ||
148 | switch (pin) { | ||
149 | case 1: return AU1500_PCI_INTA; | ||
150 | case 2: return AU1500_PCI_INTB; | ||
151 | default: return 0xff; | ||
152 | } | ||
153 | } | ||
154 | if (slot == 13) { | ||
155 | switch (pin) { | ||
156 | case 1: return AU1500_PCI_INTA; | ||
157 | case 2: return AU1500_PCI_INTB; | ||
158 | case 3: return AU1500_PCI_INTC; | ||
159 | case 4: return AU1500_PCI_INTD; | ||
160 | } | ||
161 | } | ||
162 | return -1; | ||
163 | } | ||
164 | #endif | ||
165 | |||
166 | #ifdef CONFIG_MIPS_MIRAGE | ||
167 | static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
168 | { | ||
169 | if ((slot < 11) || (slot > 13) || pin == 0) | ||
170 | return -1; | ||
171 | if (slot == 11) | ||
172 | return (pin == 1) ? AU1500_PCI_INTD : 0xff; | ||
173 | if (slot == 12) | ||
174 | return (pin == 3) ? AU1500_PCI_INTC : 0xff; | ||
175 | if (slot == 13) { | ||
176 | switch (pin) { | ||
177 | case 1: return AU1500_PCI_INTA; | ||
178 | case 2: return AU1500_PCI_INTB; | ||
179 | default: return 0xff; | ||
180 | } | ||
181 | } | ||
182 | return -1; | ||
183 | } | ||
184 | #endif | ||
185 | |||
186 | static struct resource alchemy_pci_host_res[] = { | ||
187 | [0] = { | ||
188 | .start = AU1500_PCI_PHYS_ADDR, | ||
189 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
190 | .flags = IORESOURCE_MEM, | ||
191 | }, | ||
192 | }; | ||
193 | |||
194 | static struct alchemy_pci_platdata db1xxx_pci_pd = { | ||
195 | .board_map_irq = db1xxx_map_pci_irq, | ||
196 | }; | ||
197 | |||
198 | static struct platform_device db1xxx_pci_host_dev = { | ||
199 | .dev.platform_data = &db1xxx_pci_pd, | ||
200 | .name = "alchemy-pci", | ||
201 | .id = 0, | ||
202 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
203 | .resource = alchemy_pci_host_res, | ||
204 | }; | ||
205 | |||
206 | static int __init db15x0_pci_init(void) | ||
207 | { | ||
208 | return platform_device_register(&db1xxx_pci_host_dev); | ||
209 | } | ||
210 | /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ | ||
211 | arch_initcall(db15x0_pci_init); | ||
212 | #endif | ||
213 | |||
214 | #ifdef CONFIG_MIPS_DB1100 | ||
215 | static struct resource au1100_lcd_resources[] = { | ||
216 | [0] = { | ||
217 | .start = AU1100_LCD_PHYS_ADDR, | ||
218 | .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1, | ||
219 | .flags = IORESOURCE_MEM, | ||
220 | }, | ||
221 | [1] = { | ||
222 | .start = AU1100_LCD_INT, | ||
223 | .end = AU1100_LCD_INT, | ||
224 | .flags = IORESOURCE_IRQ, | ||
225 | } | ||
226 | }; | ||
227 | |||
228 | static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); | ||
229 | |||
230 | static struct platform_device au1100_lcd_device = { | ||
231 | .name = "au1100-lcd", | ||
232 | .id = 0, | ||
233 | .dev = { | ||
234 | .dma_mask = &au1100_lcd_dmamask, | ||
235 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
236 | }, | ||
237 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
238 | .resource = au1100_lcd_resources, | ||
239 | }; | ||
240 | #endif | ||
241 | |||
91 | static struct resource alchemy_ac97c_res[] = { | 242 | static struct resource alchemy_ac97c_res[] = { |
92 | [0] = { | 243 | [0] = { |
93 | .start = AU1000_AC97_PHYS_ADDR, | 244 | .start = AU1000_AC97_PHYS_ADDR, |
@@ -130,29 +281,28 @@ static struct platform_device db1x00_audio_dev = { | |||
130 | static int __init db1xxx_dev_init(void) | 281 | static int __init db1xxx_dev_init(void) |
131 | { | 282 | { |
132 | #ifdef DB1XXX_HAS_PCMCIA | 283 | #ifdef DB1XXX_HAS_PCMCIA |
133 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, | 284 | db1x_register_pcmcia_socket( |
134 | PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | 285 | AU1000_PCMCIA_ATTR_PHYS_ADDR, |
135 | PCMCIA_MEM_PHYS_ADDR, | 286 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, |
136 | PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | 287 | AU1000_PCMCIA_MEM_PHYS_ADDR, |
137 | PCMCIA_IO_PHYS_ADDR, | 288 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, |
138 | PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | 289 | AU1000_PCMCIA_IO_PHYS_ADDR, |
139 | DB1XXX_PCMCIA_CARD0, | 290 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, |
140 | DB1XXX_PCMCIA_CD0, | 291 | DB1XXX_PCMCIA_CARD0, DB1XXX_PCMCIA_CD0, |
141 | /*DB1XXX_PCMCIA_STSCHG0*/0, | 292 | /*DB1XXX_PCMCIA_STSCHG0*/0, 0, 0); |
142 | 0, | 293 | |
143 | 0); | 294 | db1x_register_pcmcia_socket( |
144 | 295 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | |
145 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | 296 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, |
146 | PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, | 297 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, |
147 | PCMCIA_MEM_PHYS_ADDR + 0x004000000, | 298 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, |
148 | PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, | 299 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, |
149 | PCMCIA_IO_PHYS_ADDR + 0x004000000, | 300 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, |
150 | PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, | 301 | DB1XXX_PCMCIA_CARD1, DB1XXX_PCMCIA_CD1, |
151 | DB1XXX_PCMCIA_CARD1, | 302 | /*DB1XXX_PCMCIA_STSCHG1*/0, 0, 1); |
152 | DB1XXX_PCMCIA_CD1, | 303 | #endif |
153 | /*DB1XXX_PCMCIA_STSCHG1*/0, | 304 | #ifdef CONFIG_MIPS_DB1100 |
154 | 0, | 305 | platform_device_register(&au1100_lcd_device); |
155 | 1); | ||
156 | #endif | 306 | #endif |
157 | db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED); | 307 | db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED); |
158 | 308 | ||
diff --git a/arch/mips/alchemy/devboards/pb1100/platform.c b/arch/mips/alchemy/devboards/pb1100/platform.c index 2c8dc29759fd..9c57c01a68c4 100644 --- a/arch/mips/alchemy/devboards/pb1100/platform.c +++ b/arch/mips/alchemy/devboards/pb1100/platform.c | |||
@@ -19,31 +19,58 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/platform_device.h> | ||
22 | 24 | ||
23 | #include <asm/mach-au1x00/au1000.h> | 25 | #include <asm/mach-au1x00/au1000.h> |
24 | #include <asm/mach-db1x00/bcsr.h> | 26 | #include <asm/mach-db1x00/bcsr.h> |
25 | 27 | ||
26 | #include "../platform.h" | 28 | #include "../platform.h" |
27 | 29 | ||
30 | static struct resource au1100_lcd_resources[] = { | ||
31 | [0] = { | ||
32 | .start = AU1100_LCD_PHYS_ADDR, | ||
33 | .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1, | ||
34 | .flags = IORESOURCE_MEM, | ||
35 | }, | ||
36 | [1] = { | ||
37 | .start = AU1100_LCD_INT, | ||
38 | .end = AU1100_LCD_INT, | ||
39 | .flags = IORESOURCE_IRQ, | ||
40 | } | ||
41 | }; | ||
42 | |||
43 | static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); | ||
44 | |||
45 | static struct platform_device au1100_lcd_device = { | ||
46 | .name = "au1100-lcd", | ||
47 | .id = 0, | ||
48 | .dev = { | ||
49 | .dma_mask = &au1100_lcd_dmamask, | ||
50 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
51 | }, | ||
52 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
53 | .resource = au1100_lcd_resources, | ||
54 | }; | ||
55 | |||
28 | static int __init pb1100_dev_init(void) | 56 | static int __init pb1100_dev_init(void) |
29 | { | 57 | { |
30 | int swapped; | 58 | int swapped; |
31 | 59 | ||
32 | /* PCMCIA. single socket, identical to Pb1500 */ | 60 | /* PCMCIA. single socket, identical to Pb1500 */ |
33 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, | 61 | db1x_register_pcmcia_socket( |
34 | PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | 62 | AU1000_PCMCIA_ATTR_PHYS_ADDR, |
35 | PCMCIA_MEM_PHYS_ADDR, | 63 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, |
36 | PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | 64 | AU1000_PCMCIA_MEM_PHYS_ADDR, |
37 | PCMCIA_IO_PHYS_ADDR, | 65 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, |
38 | PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | 66 | AU1000_PCMCIA_IO_PHYS_ADDR, |
39 | AU1100_GPIO11_INT, /* card */ | 67 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, |
40 | AU1100_GPIO9_INT, /* insert */ | 68 | AU1100_GPIO11_INT, AU1100_GPIO9_INT, /* card / insert */ |
41 | /*AU1100_GPIO10_INT*/0, /* stschg */ | 69 | /*AU1100_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */ |
42 | 0, /* eject */ | ||
43 | 0); /* id */ | ||
44 | 70 | ||
45 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; | 71 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; |
46 | db1x_register_norflash(64 * 1024 * 1024, 4, swapped); | 72 | db1x_register_norflash(64 * 1024 * 1024, 4, swapped); |
73 | platform_device_register(&au1100_lcd_device); | ||
47 | 74 | ||
48 | return 0; | 75 | return 0; |
49 | } | 76 | } |
diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c index 3ef2dceeb796..54f7f7b0676e 100644 --- a/arch/mips/alchemy/devboards/pb1200/platform.c +++ b/arch/mips/alchemy/devboards/pb1200/platform.c | |||
@@ -24,9 +24,11 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/smc91x.h> | 25 | #include <linux/smc91x.h> |
26 | 26 | ||
27 | #include <asm/mach-au1x00/au1xxx.h> | 27 | #include <asm/mach-au1x00/au1000.h> |
28 | #include <asm/mach-au1x00/au1100_mmc.h> | 28 | #include <asm/mach-au1x00/au1100_mmc.h> |
29 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
29 | #include <asm/mach-db1x00/bcsr.h> | 30 | #include <asm/mach-db1x00/bcsr.h> |
31 | #include <asm/mach-pb1x00/pb1200.h> | ||
30 | 32 | ||
31 | #include "../platform.h" | 33 | #include "../platform.h" |
32 | 34 | ||
@@ -88,7 +90,7 @@ static int pb1200mmc1_card_inserted(void *mmc_host) | |||
88 | return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0; | 90 | return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0; |
89 | } | 91 | } |
90 | 92 | ||
91 | const struct au1xmmc_platform_data au1xmmc_platdata[2] = { | 93 | static struct au1xmmc_platform_data pb1200mmc_platdata[2] = { |
92 | [0] = { | 94 | [0] = { |
93 | .set_power = pb1200mmc0_set_power, | 95 | .set_power = pb1200mmc0_set_power, |
94 | .card_inserted = pb1200mmc0_card_inserted, | 96 | .card_inserted = pb1200mmc0_card_inserted, |
@@ -105,6 +107,79 @@ const struct au1xmmc_platform_data au1xmmc_platdata[2] = { | |||
105 | }, | 107 | }, |
106 | }; | 108 | }; |
107 | 109 | ||
110 | static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); | ||
111 | |||
112 | static struct resource au1200_mmc0_res[] = { | ||
113 | [0] = { | ||
114 | .start = AU1100_SD0_PHYS_ADDR, | ||
115 | .end = AU1100_SD0_PHYS_ADDR + 0xfff, | ||
116 | .flags = IORESOURCE_MEM, | ||
117 | }, | ||
118 | [1] = { | ||
119 | .start = AU1200_SD_INT, | ||
120 | .end = AU1200_SD_INT, | ||
121 | .flags = IORESOURCE_IRQ, | ||
122 | }, | ||
123 | [2] = { | ||
124 | .start = AU1200_DSCR_CMD0_SDMS_TX0, | ||
125 | .end = AU1200_DSCR_CMD0_SDMS_TX0, | ||
126 | .flags = IORESOURCE_DMA, | ||
127 | }, | ||
128 | [3] = { | ||
129 | .start = AU1200_DSCR_CMD0_SDMS_RX0, | ||
130 | .end = AU1200_DSCR_CMD0_SDMS_RX0, | ||
131 | .flags = IORESOURCE_DMA, | ||
132 | } | ||
133 | }; | ||
134 | |||
135 | static struct platform_device pb1200_mmc0_dev = { | ||
136 | .name = "au1xxx-mmc", | ||
137 | .id = 0, | ||
138 | .dev = { | ||
139 | .dma_mask = &au1xxx_mmc_dmamask, | ||
140 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
141 | .platform_data = &pb1200mmc_platdata[0], | ||
142 | }, | ||
143 | .num_resources = ARRAY_SIZE(au1200_mmc0_res), | ||
144 | .resource = au1200_mmc0_res, | ||
145 | }; | ||
146 | |||
147 | static struct resource au1200_mmc1_res[] = { | ||
148 | [0] = { | ||
149 | .start = AU1100_SD1_PHYS_ADDR, | ||
150 | .end = AU1100_SD1_PHYS_ADDR + 0xfff, | ||
151 | .flags = IORESOURCE_MEM, | ||
152 | }, | ||
153 | [1] = { | ||
154 | .start = AU1200_SD_INT, | ||
155 | .end = AU1200_SD_INT, | ||
156 | .flags = IORESOURCE_IRQ, | ||
157 | }, | ||
158 | [2] = { | ||
159 | .start = AU1200_DSCR_CMD0_SDMS_TX1, | ||
160 | .end = AU1200_DSCR_CMD0_SDMS_TX1, | ||
161 | .flags = IORESOURCE_DMA, | ||
162 | }, | ||
163 | [3] = { | ||
164 | .start = AU1200_DSCR_CMD0_SDMS_RX1, | ||
165 | .end = AU1200_DSCR_CMD0_SDMS_RX1, | ||
166 | .flags = IORESOURCE_DMA, | ||
167 | } | ||
168 | }; | ||
169 | |||
170 | static struct platform_device pb1200_mmc1_dev = { | ||
171 | .name = "au1xxx-mmc", | ||
172 | .id = 1, | ||
173 | .dev = { | ||
174 | .dma_mask = &au1xxx_mmc_dmamask, | ||
175 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
176 | .platform_data = &pb1200mmc_platdata[1], | ||
177 | }, | ||
178 | .num_resources = ARRAY_SIZE(au1200_mmc1_res), | ||
179 | .resource = au1200_mmc1_res, | ||
180 | }; | ||
181 | |||
182 | |||
108 | static struct resource ide_resources[] = { | 183 | static struct resource ide_resources[] = { |
109 | [0] = { | 184 | [0] = { |
110 | .start = IDE_PHYS_ADDR, | 185 | .start = IDE_PHYS_ADDR, |
@@ -115,7 +190,12 @@ static struct resource ide_resources[] = { | |||
115 | .start = IDE_INT, | 190 | .start = IDE_INT, |
116 | .end = IDE_INT, | 191 | .end = IDE_INT, |
117 | .flags = IORESOURCE_IRQ | 192 | .flags = IORESOURCE_IRQ |
118 | } | 193 | }, |
194 | [2] = { | ||
195 | .start = AU1200_DSCR_CMD0_DMA_REQ1, | ||
196 | .end = AU1200_DSCR_CMD0_DMA_REQ1, | ||
197 | .flags = IORESOURCE_DMA, | ||
198 | }, | ||
119 | }; | 199 | }; |
120 | 200 | ||
121 | static u64 ide_dmamask = DMA_BIT_MASK(32); | 201 | static u64 ide_dmamask = DMA_BIT_MASK(32); |
@@ -161,38 +241,94 @@ static struct platform_device smc91c111_device = { | |||
161 | .resource = smc91c111_resources | 241 | .resource = smc91c111_resources |
162 | }; | 242 | }; |
163 | 243 | ||
244 | static struct resource au1200_psc0_res[] = { | ||
245 | [0] = { | ||
246 | .start = AU1550_PSC0_PHYS_ADDR, | ||
247 | .end = AU1550_PSC0_PHYS_ADDR + 0xfff, | ||
248 | .flags = IORESOURCE_MEM, | ||
249 | }, | ||
250 | [1] = { | ||
251 | .start = AU1200_PSC0_INT, | ||
252 | .end = AU1200_PSC0_INT, | ||
253 | .flags = IORESOURCE_IRQ, | ||
254 | }, | ||
255 | [2] = { | ||
256 | .start = AU1200_DSCR_CMD0_PSC0_TX, | ||
257 | .end = AU1200_DSCR_CMD0_PSC0_TX, | ||
258 | .flags = IORESOURCE_DMA, | ||
259 | }, | ||
260 | [3] = { | ||
261 | .start = AU1200_DSCR_CMD0_PSC0_RX, | ||
262 | .end = AU1200_DSCR_CMD0_PSC0_RX, | ||
263 | .flags = IORESOURCE_DMA, | ||
264 | }, | ||
265 | }; | ||
266 | |||
267 | static struct platform_device pb1200_i2c_dev = { | ||
268 | .name = "au1xpsc_smbus", | ||
269 | .id = 0, /* bus number */ | ||
270 | .num_resources = ARRAY_SIZE(au1200_psc0_res), | ||
271 | .resource = au1200_psc0_res, | ||
272 | }; | ||
273 | |||
274 | static struct resource au1200_lcd_res[] = { | ||
275 | [0] = { | ||
276 | .start = AU1200_LCD_PHYS_ADDR, | ||
277 | .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1, | ||
278 | .flags = IORESOURCE_MEM, | ||
279 | }, | ||
280 | [1] = { | ||
281 | .start = AU1200_LCD_INT, | ||
282 | .end = AU1200_LCD_INT, | ||
283 | .flags = IORESOURCE_IRQ, | ||
284 | } | ||
285 | }; | ||
286 | |||
287 | static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32); | ||
288 | |||
289 | static struct platform_device au1200_lcd_dev = { | ||
290 | .name = "au1200-lcd", | ||
291 | .id = 0, | ||
292 | .dev = { | ||
293 | .dma_mask = &au1200_lcd_dmamask, | ||
294 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
295 | }, | ||
296 | .num_resources = ARRAY_SIZE(au1200_lcd_res), | ||
297 | .resource = au1200_lcd_res, | ||
298 | }; | ||
299 | |||
164 | static struct platform_device *board_platform_devices[] __initdata = { | 300 | static struct platform_device *board_platform_devices[] __initdata = { |
165 | &ide_device, | 301 | &ide_device, |
166 | &smc91c111_device | 302 | &smc91c111_device, |
303 | &pb1200_i2c_dev, | ||
304 | &pb1200_mmc0_dev, | ||
305 | &pb1200_mmc1_dev, | ||
306 | &au1200_lcd_dev, | ||
167 | }; | 307 | }; |
168 | 308 | ||
169 | static int __init board_register_devices(void) | 309 | static int __init board_register_devices(void) |
170 | { | 310 | { |
171 | int swapped; | 311 | int swapped; |
172 | 312 | ||
173 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, | 313 | db1x_register_pcmcia_socket( |
174 | PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | 314 | AU1000_PCMCIA_ATTR_PHYS_ADDR, |
175 | PCMCIA_MEM_PHYS_ADDR, | 315 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, |
176 | PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | 316 | AU1000_PCMCIA_MEM_PHYS_ADDR, |
177 | PCMCIA_IO_PHYS_ADDR, | 317 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, |
178 | PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | 318 | AU1000_PCMCIA_IO_PHYS_ADDR, |
179 | PB1200_PC0_INT, | 319 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, |
180 | PB1200_PC0_INSERT_INT, | 320 | PB1200_PC0_INT, PB1200_PC0_INSERT_INT, |
181 | /*PB1200_PC0_STSCHG_INT*/0, | 321 | /*PB1200_PC0_STSCHG_INT*/0, PB1200_PC0_EJECT_INT, 0); |
182 | PB1200_PC0_EJECT_INT, | 322 | |
183 | 0); | 323 | db1x_register_pcmcia_socket( |
184 | 324 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000, | |
185 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000, | 325 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, |
186 | PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, | 326 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000, |
187 | PCMCIA_MEM_PHYS_ADDR + 0x008000000, | 327 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, |
188 | PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, | 328 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000, |
189 | PCMCIA_IO_PHYS_ADDR + 0x008000000, | 329 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, |
190 | PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, | 330 | PB1200_PC1_INT, PB1200_PC1_INSERT_INT, |
191 | PB1200_PC1_INT, | 331 | /*PB1200_PC1_STSCHG_INT*/0, PB1200_PC1_EJECT_INT, 1); |
192 | PB1200_PC1_INSERT_INT, | ||
193 | /*PB1200_PC1_STSCHG_INT*/0, | ||
194 | PB1200_PC1_EJECT_INT, | ||
195 | 1); | ||
196 | 332 | ||
197 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; | 333 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; |
198 | db1x_register_norflash(128 * 1024 * 1024, 2, swapped); | 334 | db1x_register_norflash(128 * 1024 * 1024, 2, swapped); |
diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c index 3b4fa3206969..37c1883b5ea9 100644 --- a/arch/mips/alchemy/devboards/pb1500/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c | |||
@@ -33,13 +33,6 @@ | |||
33 | 33 | ||
34 | #include <prom.h> | 34 | #include <prom.h> |
35 | 35 | ||
36 | |||
37 | char irq_tab_alchemy[][5] __initdata = { | ||
38 | [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT370 */ | ||
39 | [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */ | ||
40 | }; | ||
41 | |||
42 | |||
43 | const char *get_system_type(void) | 36 | const char *get_system_type(void) |
44 | { | 37 | { |
45 | return "Alchemy Pb1500"; | 38 | return "Alchemy Pb1500"; |
@@ -101,20 +94,18 @@ void __init board_setup(void) | |||
101 | #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ | 94 | #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ |
102 | 95 | ||
103 | #ifdef CONFIG_PCI | 96 | #ifdef CONFIG_PCI |
104 | /* Setup PCI bus controller */ | 97 | { |
105 | au_writel(0, Au1500_PCI_CMEM); | 98 | void __iomem *base = |
106 | au_writel(0x00003fff, Au1500_CFG_BASE); | 99 | (void __iomem *)KSEG1ADDR(AU1500_PCI_PHYS_ADDR); |
107 | #if defined(__MIPSEB__) | 100 | /* Setup PCI bus controller */ |
108 | au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); | 101 | __raw_writel(0x00003fff, base + PCI_REG_CMEM); |
109 | #else | 102 | __raw_writel(0xf0000000, base + PCI_REG_MWMASK_DEV); |
110 | au_writel(0xf, Au1500_PCI_CFG); | 103 | __raw_writel(0, base + PCI_REG_MWBASE_REV_CCL); |
111 | #endif | 104 | __raw_writel(0x02a00356, base + PCI_REG_STATCMD); |
112 | au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); | 105 | __raw_writel(0x00003c04, base + PCI_REG_PARAM); |
113 | au_writel(0, Au1500_PCI_MWBASE_REV_CCL); | 106 | __raw_writel(0x00000008, base + PCI_REG_MBAR); |
114 | au_writel(0x02a00356, Au1500_PCI_STATCMD); | 107 | wmb(); |
115 | au_writel(0x00003c04, Au1500_PCI_HDRTYPE); | 108 | } |
116 | au_writel(0x00000008, Au1500_PCI_MBAR); | ||
117 | au_sync(); | ||
118 | #endif | 109 | #endif |
119 | 110 | ||
120 | /* Enable sys bus clock divider when IDLE state or no bus activity. */ | 111 | /* Enable sys bus clock divider when IDLE state or no bus activity. */ |
diff --git a/arch/mips/alchemy/devboards/pb1500/platform.c b/arch/mips/alchemy/devboards/pb1500/platform.c index d443bc7aa76e..1e52a01bac00 100644 --- a/arch/mips/alchemy/devboards/pb1500/platform.c +++ b/arch/mips/alchemy/devboards/pb1500/platform.c | |||
@@ -18,32 +18,77 @@ | |||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/dma-mapping.h> | ||
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/platform_device.h> | ||
22 | #include <asm/mach-au1x00/au1000.h> | 24 | #include <asm/mach-au1x00/au1000.h> |
23 | #include <asm/mach-db1x00/bcsr.h> | 25 | #include <asm/mach-db1x00/bcsr.h> |
24 | 26 | ||
25 | #include "../platform.h" | 27 | #include "../platform.h" |
26 | 28 | ||
29 | static int pb1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
30 | { | ||
31 | if ((slot < 12) || (slot > 13) || pin == 0) | ||
32 | return -1; | ||
33 | if (slot == 12) | ||
34 | return (pin == 1) ? AU1500_PCI_INTA : 0xff; | ||
35 | if (slot == 13) { | ||
36 | switch (pin) { | ||
37 | case 1: return AU1500_PCI_INTA; | ||
38 | case 2: return AU1500_PCI_INTB; | ||
39 | case 3: return AU1500_PCI_INTC; | ||
40 | case 4: return AU1500_PCI_INTD; | ||
41 | } | ||
42 | } | ||
43 | return -1; | ||
44 | } | ||
45 | |||
46 | static struct resource alchemy_pci_host_res[] = { | ||
47 | [0] = { | ||
48 | .start = AU1500_PCI_PHYS_ADDR, | ||
49 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
50 | .flags = IORESOURCE_MEM, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static struct alchemy_pci_platdata pb1500_pci_pd = { | ||
55 | .board_map_irq = pb1500_map_pci_irq, | ||
56 | .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H | | ||
57 | PCI_CONFIG_CH | | ||
58 | #if defined(__MIPSEB__) | ||
59 | PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM, | ||
60 | #else | ||
61 | 0, | ||
62 | #endif | ||
63 | }; | ||
64 | |||
65 | static struct platform_device pb1500_pci_host = { | ||
66 | .dev.platform_data = &pb1500_pci_pd, | ||
67 | .name = "alchemy-pci", | ||
68 | .id = 0, | ||
69 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
70 | .resource = alchemy_pci_host_res, | ||
71 | }; | ||
72 | |||
27 | static int __init pb1500_dev_init(void) | 73 | static int __init pb1500_dev_init(void) |
28 | { | 74 | { |
29 | int swapped; | 75 | int swapped; |
30 | 76 | ||
31 | /* PCMCIA. single socket, identical to Pb1500 */ | 77 | /* PCMCIA. single socket, identical to Pb1100 */ |
32 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, | 78 | db1x_register_pcmcia_socket( |
33 | PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | 79 | AU1000_PCMCIA_ATTR_PHYS_ADDR, |
34 | PCMCIA_MEM_PHYS_ADDR, | 80 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, |
35 | PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | 81 | AU1000_PCMCIA_MEM_PHYS_ADDR, |
36 | PCMCIA_IO_PHYS_ADDR, | 82 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, |
37 | PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | 83 | AU1000_PCMCIA_IO_PHYS_ADDR, |
38 | AU1500_GPIO11_INT, /* card */ | 84 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, |
39 | AU1500_GPIO9_INT, /* insert */ | 85 | AU1500_GPIO11_INT, AU1500_GPIO9_INT, /* card / insert */ |
40 | /*AU1500_GPIO10_INT*/0, /* stschg */ | 86 | /*AU1500_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */ |
41 | 0, /* eject */ | ||
42 | 0); /* id */ | ||
43 | 87 | ||
44 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; | 88 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; |
45 | db1x_register_norflash(64 * 1024 * 1024, 4, swapped); | 89 | db1x_register_norflash(64 * 1024 * 1024, 4, swapped); |
90 | platform_device_register(&pb1500_pci_host); | ||
46 | 91 | ||
47 | return 0; | 92 | return 0; |
48 | } | 93 | } |
49 | device_initcall(pb1500_dev_init); | 94 | arch_initcall(pb1500_dev_init); |
diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c index b790213848bd..0f62d1e3df24 100644 --- a/arch/mips/alchemy/devboards/pb1550/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c | |||
@@ -37,12 +37,6 @@ | |||
37 | 37 | ||
38 | #include <prom.h> | 38 | #include <prom.h> |
39 | 39 | ||
40 | |||
41 | char irq_tab_alchemy[][5] __initdata = { | ||
42 | [12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */ | ||
43 | [13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */ | ||
44 | }; | ||
45 | |||
46 | const char *get_system_type(void) | 40 | const char *get_system_type(void) |
47 | { | 41 | { |
48 | return "Alchemy Pb1550"; | 42 | return "Alchemy Pb1550"; |
diff --git a/arch/mips/alchemy/devboards/pb1550/platform.c b/arch/mips/alchemy/devboards/pb1550/platform.c index d7150d0f49c0..a4604b8a349e 100644 --- a/arch/mips/alchemy/devboards/pb1550/platform.c +++ b/arch/mips/alchemy/devboards/pb1550/platform.c | |||
@@ -18,14 +18,89 @@ | |||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/dma-mapping.h> | ||
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | 23 | #include <linux/platform_device.h> | |
23 | #include <asm/mach-au1x00/au1000.h> | 24 | #include <asm/mach-au1x00/au1000.h> |
25 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
24 | #include <asm/mach-pb1x00/pb1550.h> | 26 | #include <asm/mach-pb1x00/pb1550.h> |
25 | #include <asm/mach-db1x00/bcsr.h> | 27 | #include <asm/mach-db1x00/bcsr.h> |
26 | 28 | ||
27 | #include "../platform.h" | 29 | #include "../platform.h" |
28 | 30 | ||
31 | static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
32 | { | ||
33 | if ((slot < 12) || (slot > 13) || pin == 0) | ||
34 | return -1; | ||
35 | if (slot == 12) { | ||
36 | switch (pin) { | ||
37 | case 1: return AU1500_PCI_INTB; | ||
38 | case 2: return AU1500_PCI_INTC; | ||
39 | case 3: return AU1500_PCI_INTD; | ||
40 | case 4: return AU1500_PCI_INTA; | ||
41 | } | ||
42 | } | ||
43 | if (slot == 13) { | ||
44 | switch (pin) { | ||
45 | case 1: return AU1500_PCI_INTA; | ||
46 | case 2: return AU1500_PCI_INTB; | ||
47 | case 3: return AU1500_PCI_INTC; | ||
48 | case 4: return AU1500_PCI_INTD; | ||
49 | } | ||
50 | } | ||
51 | return -1; | ||
52 | } | ||
53 | |||
54 | static struct resource alchemy_pci_host_res[] = { | ||
55 | [0] = { | ||
56 | .start = AU1500_PCI_PHYS_ADDR, | ||
57 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
58 | .flags = IORESOURCE_MEM, | ||
59 | }, | ||
60 | }; | ||
61 | |||
62 | static struct alchemy_pci_platdata pb1550_pci_pd = { | ||
63 | .board_map_irq = pb1550_map_pci_irq, | ||
64 | }; | ||
65 | |||
66 | static struct platform_device pb1550_pci_host = { | ||
67 | .dev.platform_data = &pb1550_pci_pd, | ||
68 | .name = "alchemy-pci", | ||
69 | .id = 0, | ||
70 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
71 | .resource = alchemy_pci_host_res, | ||
72 | }; | ||
73 | |||
74 | static struct resource au1550_psc2_res[] = { | ||
75 | [0] = { | ||
76 | .start = AU1550_PSC2_PHYS_ADDR, | ||
77 | .end = AU1550_PSC2_PHYS_ADDR + 0xfff, | ||
78 | .flags = IORESOURCE_MEM, | ||
79 | }, | ||
80 | [1] = { | ||
81 | .start = AU1550_PSC2_INT, | ||
82 | .end = AU1550_PSC2_INT, | ||
83 | .flags = IORESOURCE_IRQ, | ||
84 | }, | ||
85 | [2] = { | ||
86 | .start = AU1550_DSCR_CMD0_PSC2_TX, | ||
87 | .end = AU1550_DSCR_CMD0_PSC2_TX, | ||
88 | .flags = IORESOURCE_DMA, | ||
89 | }, | ||
90 | [3] = { | ||
91 | .start = AU1550_DSCR_CMD0_PSC2_RX, | ||
92 | .end = AU1550_DSCR_CMD0_PSC2_RX, | ||
93 | .flags = IORESOURCE_DMA, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static struct platform_device pb1550_i2c_dev = { | ||
98 | .name = "au1xpsc_smbus", | ||
99 | .id = 0, /* bus number */ | ||
100 | .num_resources = ARRAY_SIZE(au1550_psc2_res), | ||
101 | .resource = au1550_psc2_res, | ||
102 | }; | ||
103 | |||
29 | static int __init pb1550_dev_init(void) | 104 | static int __init pb1550_dev_init(void) |
30 | { | 105 | { |
31 | int swapped; | 106 | int swapped; |
@@ -37,33 +112,29 @@ static int __init pb1550_dev_init(void) | |||
37 | * drivers are used to shared irqs and b) statuschange isn't really use- | 112 | * drivers are used to shared irqs and b) statuschange isn't really use- |
38 | * ful anyway. | 113 | * ful anyway. |
39 | */ | 114 | */ |
40 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, | 115 | db1x_register_pcmcia_socket( |
41 | PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | 116 | AU1000_PCMCIA_ATTR_PHYS_ADDR, |
42 | PCMCIA_MEM_PHYS_ADDR, | 117 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, |
43 | PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | 118 | AU1000_PCMCIA_MEM_PHYS_ADDR, |
44 | PCMCIA_IO_PHYS_ADDR, | 119 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, |
45 | PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | 120 | AU1000_PCMCIA_IO_PHYS_ADDR, |
46 | AU1550_GPIO201_205_INT, | 121 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, |
47 | AU1550_GPIO0_INT, | 122 | AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0); |
48 | 0, | ||
49 | 0, | ||
50 | 0); | ||
51 | 123 | ||
52 | db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000, | 124 | db1x_register_pcmcia_socket( |
53 | PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, | 125 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000, |
54 | PCMCIA_MEM_PHYS_ADDR + 0x008000000, | 126 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, |
55 | PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, | 127 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000, |
56 | PCMCIA_IO_PHYS_ADDR + 0x008000000, | 128 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, |
57 | PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, | 129 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000, |
58 | AU1550_GPIO201_205_INT, | 130 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, |
59 | AU1550_GPIO1_INT, | 131 | AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1); |
60 | 0, | ||
61 | 0, | ||
62 | 1); | ||
63 | 132 | ||
64 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT; | 133 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT; |
65 | db1x_register_norflash(128 * 1024 * 1024, 4, swapped); | 134 | db1x_register_norflash(128 * 1024 * 1024, 4, swapped); |
135 | platform_device_register(&pb1550_pci_host); | ||
136 | platform_device_register(&pb1550_i2c_dev); | ||
66 | 137 | ||
67 | return 0; | 138 | return 0; |
68 | } | 139 | } |
69 | device_initcall(pb1550_dev_init); | 140 | arch_initcall(pb1550_dev_init); |
diff --git a/arch/mips/alchemy/gpr/board_setup.c b/arch/mips/alchemy/gpr/board_setup.c index 5f8f0691ed2d..dea45c78fdcd 100644 --- a/arch/mips/alchemy/gpr/board_setup.c +++ b/arch/mips/alchemy/gpr/board_setup.c | |||
@@ -36,10 +36,6 @@ | |||
36 | 36 | ||
37 | #include <prom.h> | 37 | #include <prom.h> |
38 | 38 | ||
39 | char irq_tab_alchemy[][5] __initdata = { | ||
40 | [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, | ||
41 | }; | ||
42 | |||
43 | static void gpr_reset(char *c) | 39 | static void gpr_reset(char *c) |
44 | { | 40 | { |
45 | /* switch System-LED to orange (red# and green# on) */ | 41 | /* switch System-LED to orange (red# and green# on) */ |
@@ -76,12 +72,4 @@ void __init board_setup(void) | |||
76 | 72 | ||
77 | /* Take away Reset of UMTS-card */ | 73 | /* Take away Reset of UMTS-card */ |
78 | alchemy_gpio_direction_output(215, 1); | 74 | alchemy_gpio_direction_output(215, 1); |
79 | |||
80 | #ifdef CONFIG_PCI | ||
81 | #if defined(__MIPSEB__) | ||
82 | au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); | ||
83 | #else | ||
84 | au_writel(0xf, Au1500_PCI_CFG); | ||
85 | #endif | ||
86 | #endif | ||
87 | } | 75 | } |
diff --git a/arch/mips/alchemy/gpr/platform.c b/arch/mips/alchemy/gpr/platform.c index 14b46629cfc8..982ce85db60d 100644 --- a/arch/mips/alchemy/gpr/platform.c +++ b/arch/mips/alchemy/gpr/platform.c | |||
@@ -167,6 +167,45 @@ static struct i2c_board_info gpr_i2c_info[] __initdata = { | |||
167 | } | 167 | } |
168 | }; | 168 | }; |
169 | 169 | ||
170 | |||
171 | |||
172 | static struct resource alchemy_pci_host_res[] = { | ||
173 | [0] = { | ||
174 | .start = AU1500_PCI_PHYS_ADDR, | ||
175 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
176 | .flags = IORESOURCE_MEM, | ||
177 | }, | ||
178 | }; | ||
179 | |||
180 | static int gpr_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
181 | { | ||
182 | if ((slot == 0) && (pin == 1)) | ||
183 | return AU1550_PCI_INTA; | ||
184 | else if ((slot == 0) && (pin == 2)) | ||
185 | return AU1550_PCI_INTB; | ||
186 | |||
187 | return -1; | ||
188 | } | ||
189 | |||
190 | static struct alchemy_pci_platdata gpr_pci_pd = { | ||
191 | .board_map_irq = gpr_map_pci_irq, | ||
192 | .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H | | ||
193 | PCI_CONFIG_CH | | ||
194 | #if defined(__MIPSEB__) | ||
195 | PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM, | ||
196 | #else | ||
197 | 0, | ||
198 | #endif | ||
199 | }; | ||
200 | |||
201 | static struct platform_device gpr_pci_host_dev = { | ||
202 | .dev.platform_data = &gpr_pci_pd, | ||
203 | .name = "alchemy-pci", | ||
204 | .id = 0, | ||
205 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
206 | .resource = alchemy_pci_host_res, | ||
207 | }; | ||
208 | |||
170 | static struct platform_device *gpr_devices[] __initdata = { | 209 | static struct platform_device *gpr_devices[] __initdata = { |
171 | &gpr_wdt_device, | 210 | &gpr_wdt_device, |
172 | &gpr_mtd_device, | 211 | &gpr_mtd_device, |
@@ -174,6 +213,14 @@ static struct platform_device *gpr_devices[] __initdata = { | |||
174 | &gpr_led_devices, | 213 | &gpr_led_devices, |
175 | }; | 214 | }; |
176 | 215 | ||
216 | static int __init gpr_pci_init(void) | ||
217 | { | ||
218 | return platform_device_register(&gpr_pci_host_dev); | ||
219 | } | ||
220 | /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ | ||
221 | arch_initcall(gpr_pci_init); | ||
222 | |||
223 | |||
177 | static int __init gpr_dev_init(void) | 224 | static int __init gpr_dev_init(void) |
178 | { | 225 | { |
179 | i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info)); | 226 | i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info)); |
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c index 3ae984cf98cf..851a5ab4c8f2 100644 --- a/arch/mips/alchemy/mtx-1/board_setup.c +++ b/arch/mips/alchemy/mtx-1/board_setup.c | |||
@@ -38,20 +38,6 @@ | |||
38 | 38 | ||
39 | #include <prom.h> | 39 | #include <prom.h> |
40 | 40 | ||
41 | char irq_tab_alchemy[][5] __initdata = { | ||
42 | [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */ | ||
43 | [1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */ | ||
44 | [2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */ | ||
45 | [3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */ | ||
46 | [4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */ | ||
47 | [5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */ | ||
48 | [6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */ | ||
49 | [7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ | ||
50 | }; | ||
51 | |||
52 | extern int (*board_pci_idsel)(unsigned int devsel, int assert); | ||
53 | int mtx1_pci_idsel(unsigned int devsel, int assert); | ||
54 | |||
55 | static void mtx1_reset(char *c) | 41 | static void mtx1_reset(char *c) |
56 | { | 42 | { |
57 | /* Jump to the reset vector */ | 43 | /* Jump to the reset vector */ |
@@ -74,15 +60,6 @@ void __init board_setup(void) | |||
74 | alchemy_gpio_direction_output(204, 0); | 60 | alchemy_gpio_direction_output(204, 0); |
75 | #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ | 61 | #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ |
76 | 62 | ||
77 | #ifdef CONFIG_PCI | ||
78 | #if defined(__MIPSEB__) | ||
79 | au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); | ||
80 | #else | ||
81 | au_writel(0xf, Au1500_PCI_CFG); | ||
82 | #endif | ||
83 | board_pci_idsel = mtx1_pci_idsel; | ||
84 | #endif | ||
85 | |||
86 | /* Initialize sys_pinfunc */ | 63 | /* Initialize sys_pinfunc */ |
87 | au_writel(SYS_PF_NI2, SYS_PINFUNC); | 64 | au_writel(SYS_PF_NI2, SYS_PINFUNC); |
88 | 65 | ||
@@ -104,23 +81,6 @@ void __init board_setup(void) | |||
104 | printk(KERN_INFO "4G Systems MTX-1 Board\n"); | 81 | printk(KERN_INFO "4G Systems MTX-1 Board\n"); |
105 | } | 82 | } |
106 | 83 | ||
107 | int | ||
108 | mtx1_pci_idsel(unsigned int devsel, int assert) | ||
109 | { | ||
110 | /* This function is only necessary to support a proprietary Cardbus | ||
111 | * adapter on the mtx-1 "singleboard" variant. It triggers a custom | ||
112 | * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals. | ||
113 | */ | ||
114 | if (assert && devsel != 0) | ||
115 | /* Suppress signal to Cardbus */ | ||
116 | alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */ | ||
117 | else | ||
118 | alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */ | ||
119 | |||
120 | udelay(1); | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | static int __init mtx1_init_irq(void) | 84 | static int __init mtx1_init_irq(void) |
125 | { | 85 | { |
126 | irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); | 86 | irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); |
diff --git a/arch/mips/alchemy/mtx-1/platform.c b/arch/mips/alchemy/mtx-1/platform.c index 55628e390fd7..cc47b6868ca3 100644 --- a/arch/mips/alchemy/mtx-1/platform.c +++ b/arch/mips/alchemy/mtx-1/platform.c | |||
@@ -135,7 +135,69 @@ static struct platform_device mtx1_mtd = { | |||
135 | .resource = &mtx1_mtd_resource, | 135 | .resource = &mtx1_mtd_resource, |
136 | }; | 136 | }; |
137 | 137 | ||
138 | static struct resource alchemy_pci_host_res[] = { | ||
139 | [0] = { | ||
140 | .start = AU1500_PCI_PHYS_ADDR, | ||
141 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
142 | .flags = IORESOURCE_MEM, | ||
143 | }, | ||
144 | }; | ||
145 | |||
146 | static int mtx1_pci_idsel(unsigned int devsel, int assert) | ||
147 | { | ||
148 | /* This function is only necessary to support a proprietary Cardbus | ||
149 | * adapter on the mtx-1 "singleboard" variant. It triggers a custom | ||
150 | * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals. | ||
151 | */ | ||
152 | if (assert && devsel != 0) | ||
153 | /* Suppress signal to Cardbus */ | ||
154 | alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */ | ||
155 | else | ||
156 | alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */ | ||
157 | |||
158 | udelay(1); | ||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | static const char mtx1_irqtab[][5] = { | ||
163 | [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */ | ||
164 | [1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */ | ||
165 | [2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */ | ||
166 | [3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */ | ||
167 | [4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */ | ||
168 | [5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */ | ||
169 | [6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */ | ||
170 | [7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ | ||
171 | }; | ||
172 | |||
173 | static int mtx1_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
174 | { | ||
175 | return mtx1_irqtab[slot][pin]; | ||
176 | } | ||
177 | |||
178 | static struct alchemy_pci_platdata mtx1_pci_pd = { | ||
179 | .board_map_irq = mtx1_map_pci_irq, | ||
180 | .board_pci_idsel = mtx1_pci_idsel, | ||
181 | .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H | | ||
182 | PCI_CONFIG_CH | | ||
183 | #if defined(__MIPSEB__) | ||
184 | PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM, | ||
185 | #else | ||
186 | 0, | ||
187 | #endif | ||
188 | }; | ||
189 | |||
190 | static struct platform_device mtx1_pci_host = { | ||
191 | .dev.platform_data = &mtx1_pci_pd, | ||
192 | .name = "alchemy-pci", | ||
193 | .id = 0, | ||
194 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
195 | .resource = alchemy_pci_host_res, | ||
196 | }; | ||
197 | |||
198 | |||
138 | static struct __initdata platform_device * mtx1_devs[] = { | 199 | static struct __initdata platform_device * mtx1_devs[] = { |
200 | &mtx1_pci_host, | ||
139 | &mtx1_gpio_leds, | 201 | &mtx1_gpio_leds, |
140 | &mtx1_wdt, | 202 | &mtx1_wdt, |
141 | &mtx1_button, | 203 | &mtx1_button, |
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c index 81e57fad07ab..3fa83f72e014 100644 --- a/arch/mips/alchemy/xxs1500/board_setup.c +++ b/arch/mips/alchemy/xxs1500/board_setup.c | |||
@@ -70,14 +70,6 @@ void __init board_setup(void) | |||
70 | /* Enable DTR (MCR bit 0) = USB power up */ | 70 | /* Enable DTR (MCR bit 0) = USB power up */ |
71 | __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18)); | 71 | __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18)); |
72 | wmb(); | 72 | wmb(); |
73 | |||
74 | #ifdef CONFIG_PCI | ||
75 | #if defined(__MIPSEB__) | ||
76 | au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); | ||
77 | #else | ||
78 | au_writel(0xf, Au1500_PCI_CFG); | ||
79 | #endif | ||
80 | #endif | ||
81 | } | 73 | } |
82 | 74 | ||
83 | static int __init xxs1500_init_irq(void) | 75 | static int __init xxs1500_init_irq(void) |
diff --git a/arch/mips/alchemy/xxs1500/platform.c b/arch/mips/alchemy/xxs1500/platform.c index e87c45cde61b..06a3a459b8aa 100644 --- a/arch/mips/alchemy/xxs1500/platform.c +++ b/arch/mips/alchemy/xxs1500/platform.c | |||
@@ -27,20 +27,20 @@ static struct resource xxs1500_pcmcia_res[] = { | |||
27 | { | 27 | { |
28 | .name = "pcmcia-io", | 28 | .name = "pcmcia-io", |
29 | .flags = IORESOURCE_MEM, | 29 | .flags = IORESOURCE_MEM, |
30 | .start = PCMCIA_IO_PHYS_ADDR, | 30 | .start = AU1000_PCMCIA_IO_PHYS_ADDR, |
31 | .end = PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1, | 31 | .end = AU1000_PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1, |
32 | }, | 32 | }, |
33 | { | 33 | { |
34 | .name = "pcmcia-attr", | 34 | .name = "pcmcia-attr", |
35 | .flags = IORESOURCE_MEM, | 35 | .flags = IORESOURCE_MEM, |
36 | .start = PCMCIA_ATTR_PHYS_ADDR, | 36 | .start = AU1000_PCMCIA_ATTR_PHYS_ADDR, |
37 | .end = PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | 37 | .end = AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, |
38 | }, | 38 | }, |
39 | { | 39 | { |
40 | .name = "pcmcia-mem", | 40 | .name = "pcmcia-mem", |
41 | .flags = IORESOURCE_MEM, | 41 | .flags = IORESOURCE_MEM, |
42 | .start = PCMCIA_MEM_PHYS_ADDR, | 42 | .start = AU1000_PCMCIA_MEM_PHYS_ADDR, |
43 | .end = PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | 43 | .end = AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, |
44 | }, | 44 | }, |
45 | }; | 45 | }; |
46 | 46 | ||
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h index 40bb9fde205f..69468ded2828 100644 --- a/arch/mips/include/asm/cacheflush.h +++ b/arch/mips/include/asm/cacheflush.h | |||
@@ -114,4 +114,28 @@ unsigned long run_uncached(void *func); | |||
114 | extern void *kmap_coherent(struct page *page, unsigned long addr); | 114 | extern void *kmap_coherent(struct page *page, unsigned long addr); |
115 | extern void kunmap_coherent(void); | 115 | extern void kunmap_coherent(void); |
116 | 116 | ||
117 | #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE | ||
118 | static inline void flush_kernel_dcache_page(struct page *page) | ||
119 | { | ||
120 | BUG_ON(cpu_has_dc_aliases && PageHighMem(page)); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * For now flush_kernel_vmap_range and invalidate_kernel_vmap_range both do a | ||
125 | * cache writeback and invalidate operation. | ||
126 | */ | ||
127 | extern void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); | ||
128 | |||
129 | static inline void flush_kernel_vmap_range(void *vaddr, int size) | ||
130 | { | ||
131 | if (cpu_has_dc_aliases) | ||
132 | __flush_kernel_vmap_range((unsigned long) vaddr, size); | ||
133 | } | ||
134 | |||
135 | static inline void invalidate_kernel_vmap_range(void *vaddr, int size) | ||
136 | { | ||
137 | if (cpu_has_dc_aliases) | ||
138 | __flush_kernel_vmap_range((unsigned long) vaddr, size); | ||
139 | } | ||
140 | |||
117 | #endif /* _ASM_CACHEFLUSH_H */ | 141 | #endif /* _ASM_CACHEFLUSH_H */ |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 5f95a4bfc735..2f7f41873f24 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -135,6 +135,9 @@ | |||
135 | #define PRID_IMP_CAVIUM_CN50XX 0x0600 | 135 | #define PRID_IMP_CAVIUM_CN50XX 0x0600 |
136 | #define PRID_IMP_CAVIUM_CN52XX 0x0700 | 136 | #define PRID_IMP_CAVIUM_CN52XX 0x0700 |
137 | #define PRID_IMP_CAVIUM_CN63XX 0x9000 | 137 | #define PRID_IMP_CAVIUM_CN63XX 0x9000 |
138 | #define PRID_IMP_CAVIUM_CN68XX 0x9100 | ||
139 | #define PRID_IMP_CAVIUM_CN66XX 0x9200 | ||
140 | #define PRID_IMP_CAVIUM_CN61XX 0x9300 | ||
138 | 141 | ||
139 | /* | 142 | /* |
140 | * These are the PRID's for when 23:16 == PRID_COMP_INGENIC | 143 | * These are the PRID's for when 23:16 == PRID_COMP_INGENIC |
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index b04e4de5dd2e..a58f22998a86 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
@@ -329,14 +329,10 @@ static inline void pfx##write##bwlq(type val, \ | |||
329 | "dsrl32 %L0, %L0, 0" "\n\t" \ | 329 | "dsrl32 %L0, %L0, 0" "\n\t" \ |
330 | "dsll32 %M0, %M0, 0" "\n\t" \ | 330 | "dsll32 %M0, %M0, 0" "\n\t" \ |
331 | "or %L0, %L0, %M0" "\n\t" \ | 331 | "or %L0, %L0, %M0" "\n\t" \ |
332 | ".set push" "\n\t" \ | ||
333 | ".set noreorder" "\n\t" \ | ||
334 | ".set nomacro" "\n\t" \ | ||
335 | "sd %L0, %2" "\n\t" \ | 332 | "sd %L0, %2" "\n\t" \ |
336 | ".set pop" "\n\t" \ | ||
337 | ".set mips0" "\n" \ | 333 | ".set mips0" "\n" \ |
338 | : "=r" (__tmp) \ | 334 | : "=r" (__tmp) \ |
339 | : "0" (__val), "R" (*__mem)); \ | 335 | : "0" (__val), "m" (*__mem)); \ |
340 | if (irq) \ | 336 | if (irq) \ |
341 | local_irq_restore(__flags); \ | 337 | local_irq_restore(__flags); \ |
342 | } else \ | 338 | } else \ |
@@ -359,16 +355,12 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ | |||
359 | local_irq_save(__flags); \ | 355 | local_irq_save(__flags); \ |
360 | __asm__ __volatile__( \ | 356 | __asm__ __volatile__( \ |
361 | ".set mips3" "\t\t# __readq" "\n\t" \ | 357 | ".set mips3" "\t\t# __readq" "\n\t" \ |
362 | ".set push" "\n\t" \ | ||
363 | ".set noreorder" "\n\t" \ | ||
364 | ".set nomacro" "\n\t" \ | ||
365 | "ld %L0, %1" "\n\t" \ | 358 | "ld %L0, %1" "\n\t" \ |
366 | ".set pop" "\n\t" \ | ||
367 | "dsra32 %M0, %L0, 0" "\n\t" \ | 359 | "dsra32 %M0, %L0, 0" "\n\t" \ |
368 | "sll %L0, %L0, 0" "\n\t" \ | 360 | "sll %L0, %L0, 0" "\n\t" \ |
369 | ".set mips0" "\n" \ | 361 | ".set mips0" "\n" \ |
370 | : "=r" (__val) \ | 362 | : "=r" (__val) \ |
371 | : "R" (*__mem)); \ | 363 | : "m" (*__mem)); \ |
372 | if (irq) \ | 364 | if (irq) \ |
373 | local_irq_restore(__flags); \ | 365 | local_irq_restore(__flags); \ |
374 | } else { \ | 366 | } else { \ |
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index f260ebed713b..de24ec57dd2f 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h | |||
@@ -245,6 +245,23 @@ 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 | |||
257 | /* PCI controller platform data */ | ||
258 | struct alchemy_pci_platdata { | ||
259 | int (*board_map_irq)(const struct pci_dev *d, u8 slot, u8 pin); | ||
260 | int (*board_pci_idsel)(unsigned int devsel, int assert); | ||
261 | /* bits to set/clear in PCI_CONFIG register */ | ||
262 | unsigned long pci_cfg_set; | ||
263 | unsigned long pci_cfg_clr; | ||
264 | }; | ||
248 | 265 | ||
249 | /* SOC Interrupt numbers */ | 266 | /* SOC Interrupt numbers */ |
250 | 267 | ||
@@ -575,38 +592,95 @@ enum soc_au1200_ints { | |||
575 | #endif /* !defined (_LANGUAGE_ASSEMBLY) */ | 592 | #endif /* !defined (_LANGUAGE_ASSEMBLY) */ |
576 | 593 | ||
577 | /* | 594 | /* |
578 | * SDRAM register offsets | 595 | * Physical base addresses for integrated peripherals |
596 | * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 | ||
579 | */ | 597 | */ |
580 | #if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \ | ||
581 | defined(CONFIG_SOC_AU1100) | ||
582 | #define MEM_SDMODE0 0x0000 | ||
583 | #define MEM_SDMODE1 0x0004 | ||
584 | #define MEM_SDMODE2 0x0008 | ||
585 | #define MEM_SDADDR0 0x000C | ||
586 | #define MEM_SDADDR1 0x0010 | ||
587 | #define MEM_SDADDR2 0x0014 | ||
588 | #define MEM_SDREFCFG 0x0018 | ||
589 | #define MEM_SDPRECMD 0x001C | ||
590 | #define MEM_SDAUTOREF 0x0020 | ||
591 | #define MEM_SDWRMD0 0x0024 | ||
592 | #define MEM_SDWRMD1 0x0028 | ||
593 | #define MEM_SDWRMD2 0x002C | ||
594 | #define MEM_SDSLEEP 0x0030 | ||
595 | #define MEM_SDSMCKE 0x0034 | ||
596 | 598 | ||
597 | /* | 599 | #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ |
598 | * MEM_SDMODE register content definitions | 600 | #define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */ |
599 | */ | 601 | #define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */ |
602 | #define AU1000_IRDA_PHYS_ADDR 0x10300000 /* 02 */ | ||
603 | #define AU1200_AES_PHYS_ADDR 0x10300000 /* 4 */ | ||
604 | #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | ||
605 | #define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | ||
606 | #define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | ||
607 | #define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */ | ||
608 | #define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */ | ||
609 | #define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */ | ||
610 | #define AU1550_PSC2_PHYS_ADDR 0x10A00000 /* 3 */ | ||
611 | #define AU1550_PSC3_PHYS_ADDR 0x10B00000 /* 3 */ | ||
612 | #define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */ | ||
613 | #define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */ | ||
614 | #define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */ | ||
615 | #define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */ | ||
616 | #define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */ | ||
617 | #define AU1200_SWCNT_PHYS_ADDR 0x1110010C /* 4 */ | ||
618 | #define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */ | ||
619 | #define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */ | ||
620 | #define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */ | ||
621 | #define AU1000_SSI0_PHYS_ADDR 0x11600000 /* 02 */ | ||
622 | #define AU1000_SSI1_PHYS_ADDR 0x11680000 /* 02 */ | ||
623 | #define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */ | ||
624 | #define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ | ||
625 | #define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */ | ||
626 | #define AU1550_PSC0_PHYS_ADDR 0x11A00000 /* 34 */ | ||
627 | #define AU1550_PSC1_PHYS_ADDR 0x11B00000 /* 34 */ | ||
628 | #define AU1000_MEM_PHYS_ADDR 0x14000000 /* 01234 */ | ||
629 | #define AU1000_STATIC_MEM_PHYS_ADDR 0x14001000 /* 01234 */ | ||
630 | #define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */ | ||
631 | #define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */ | ||
632 | #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */ | ||
633 | #define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | ||
634 | #define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | ||
635 | #define AU1200_CIM_PHYS_ADDR 0x14004000 /* 4 */ | ||
636 | #define AU1500_PCI_PHYS_ADDR 0x14005000 /* 13 */ | ||
637 | #define AU1550_PE_PHYS_ADDR 0x14008000 /* 3 */ | ||
638 | #define AU1200_MAEBE_PHYS_ADDR 0x14010000 /* 4 */ | ||
639 | #define AU1200_MAEFE_PHYS_ADDR 0x14012000 /* 4 */ | ||
640 | #define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */ | ||
641 | #define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */ | ||
642 | #define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */ | ||
643 | #define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */ | ||
644 | #define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */ | ||
645 | #define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */ | ||
646 | #define AU1100_LCD_PHYS_ADDR 0x15000000 /* 2 */ | ||
647 | #define AU1200_LCD_PHYS_ADDR 0x15000000 /* 4 */ | ||
648 | #define AU1500_PCI_MEM_PHYS_ADDR 0x400000000ULL /* 13 */ | ||
649 | #define AU1500_PCI_IO_PHYS_ADDR 0x500000000ULL /* 13 */ | ||
650 | #define AU1500_PCI_CONFIG0_PHYS_ADDR 0x600000000ULL /* 13 */ | ||
651 | #define AU1500_PCI_CONFIG1_PHYS_ADDR 0x680000000ULL /* 13 */ | ||
652 | #define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 01234 */ | ||
653 | #define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 01234 */ | ||
654 | #define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 01234 */ | ||
655 | |||
656 | |||
657 | /* Au1000 SDRAM memory controller register offsets */ | ||
658 | #define AU1000_MEM_SDMODE0 0x0000 | ||
659 | #define AU1000_MEM_SDMODE1 0x0004 | ||
660 | #define AU1000_MEM_SDMODE2 0x0008 | ||
661 | #define AU1000_MEM_SDADDR0 0x000C | ||
662 | #define AU1000_MEM_SDADDR1 0x0010 | ||
663 | #define AU1000_MEM_SDADDR2 0x0014 | ||
664 | #define AU1000_MEM_SDREFCFG 0x0018 | ||
665 | #define AU1000_MEM_SDPRECMD 0x001C | ||
666 | #define AU1000_MEM_SDAUTOREF 0x0020 | ||
667 | #define AU1000_MEM_SDWRMD0 0x0024 | ||
668 | #define AU1000_MEM_SDWRMD1 0x0028 | ||
669 | #define AU1000_MEM_SDWRMD2 0x002C | ||
670 | #define AU1000_MEM_SDSLEEP 0x0030 | ||
671 | #define AU1000_MEM_SDSMCKE 0x0034 | ||
672 | |||
673 | /* MEM_SDMODE register content definitions */ | ||
600 | #define MEM_SDMODE_F (1 << 22) | 674 | #define MEM_SDMODE_F (1 << 22) |
601 | #define MEM_SDMODE_SR (1 << 21) | 675 | #define MEM_SDMODE_SR (1 << 21) |
602 | #define MEM_SDMODE_BS (1 << 20) | 676 | #define MEM_SDMODE_BS (1 << 20) |
603 | #define MEM_SDMODE_RS (3 << 18) | 677 | #define MEM_SDMODE_RS (3 << 18) |
604 | #define MEM_SDMODE_CS (7 << 15) | 678 | #define MEM_SDMODE_CS (7 << 15) |
605 | #define MEM_SDMODE_TRAS (15 << 11) | 679 | #define MEM_SDMODE_TRAS (15 << 11) |
606 | #define MEM_SDMODE_TMRD (3 << 9) | 680 | #define MEM_SDMODE_TMRD (3 << 9) |
607 | #define MEM_SDMODE_TWR (3 << 7) | 681 | #define MEM_SDMODE_TWR (3 << 7) |
608 | #define MEM_SDMODE_TRP (3 << 5) | 682 | #define MEM_SDMODE_TRP (3 << 5) |
609 | #define MEM_SDMODE_TRCD (3 << 3) | 683 | #define MEM_SDMODE_TRCD (3 << 3) |
610 | #define MEM_SDMODE_TCL (7 << 0) | 684 | #define MEM_SDMODE_TCL (7 << 0) |
611 | 685 | ||
612 | #define MEM_SDMODE_BS_2Bank (0 << 20) | 686 | #define MEM_SDMODE_BS_2Bank (0 << 20) |
@@ -628,173 +702,43 @@ enum soc_au1200_ints { | |||
628 | #define MEM_SDMODE_TRCD_N(N) ((N) << 3) | 702 | #define MEM_SDMODE_TRCD_N(N) ((N) << 3) |
629 | #define MEM_SDMODE_TCL_N(N) ((N) << 0) | 703 | #define MEM_SDMODE_TCL_N(N) ((N) << 0) |
630 | 704 | ||
631 | /* | 705 | /* MEM_SDADDR register contents definitions */ |
632 | * MEM_SDADDR register contents definitions | ||
633 | */ | ||
634 | #define MEM_SDADDR_E (1 << 20) | 706 | #define MEM_SDADDR_E (1 << 20) |
635 | #define MEM_SDADDR_CSBA (0x03FF << 10) | 707 | #define MEM_SDADDR_CSBA (0x03FF << 10) |
636 | #define MEM_SDADDR_CSMASK (0x03FF << 0) | 708 | #define MEM_SDADDR_CSMASK (0x03FF << 0) |
637 | #define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) | 709 | #define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) |
638 | #define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) | 710 | #define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) |
639 | 711 | ||
640 | /* | 712 | /* MEM_SDREFCFG register content definitions */ |
641 | * MEM_SDREFCFG register content definitions | ||
642 | */ | ||
643 | #define MEM_SDREFCFG_TRC (15 << 28) | 713 | #define MEM_SDREFCFG_TRC (15 << 28) |
644 | #define MEM_SDREFCFG_TRPM (3 << 26) | 714 | #define MEM_SDREFCFG_TRPM (3 << 26) |
645 | #define MEM_SDREFCFG_E (1 << 25) | 715 | #define MEM_SDREFCFG_E (1 << 25) |
646 | #define MEM_SDREFCFG_RE (0x1ffffff << 0) | 716 | #define MEM_SDREFCFG_RE (0x1ffffff << 0) |
647 | #define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC) | 717 | #define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC) |
648 | #define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM) | 718 | #define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM) |
649 | #define MEM_SDREFCFG_REF_N(N) (N) | 719 | #define MEM_SDREFCFG_REF_N(N) (N) |
650 | #endif | ||
651 | |||
652 | /***********************************************************************/ | ||
653 | 720 | ||
654 | /* | 721 | /* Au1550 SDRAM Register Offsets */ |
655 | * Au1550 SDRAM Register Offsets | 722 | #define AU1550_MEM_SDMODE0 0x0800 |
656 | */ | 723 | #define AU1550_MEM_SDMODE1 0x0808 |
657 | 724 | #define AU1550_MEM_SDMODE2 0x0810 | |
658 | /***********************************************************************/ | 725 | #define AU1550_MEM_SDADDR0 0x0820 |
659 | 726 | #define AU1550_MEM_SDADDR1 0x0828 | |
660 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | 727 | #define AU1550_MEM_SDADDR2 0x0830 |
661 | #define MEM_SDMODE0 0x0800 | 728 | #define AU1550_MEM_SDCONFIGA 0x0840 |
662 | #define MEM_SDMODE1 0x0808 | 729 | #define AU1550_MEM_SDCONFIGB 0x0848 |
663 | #define MEM_SDMODE2 0x0810 | 730 | #define AU1550_MEM_SDSTAT 0x0850 |
664 | #define MEM_SDADDR0 0x0820 | 731 | #define AU1550_MEM_SDERRADDR 0x0858 |
665 | #define MEM_SDADDR1 0x0828 | 732 | #define AU1550_MEM_SDSTRIDE0 0x0860 |
666 | #define MEM_SDADDR2 0x0830 | 733 | #define AU1550_MEM_SDSTRIDE1 0x0868 |
667 | #define MEM_SDCONFIGA 0x0840 | 734 | #define AU1550_MEM_SDSTRIDE2 0x0870 |
668 | #define MEM_SDCONFIGB 0x0848 | 735 | #define AU1550_MEM_SDWRMD0 0x0880 |
669 | #define MEM_SDSTAT 0x0850 | 736 | #define AU1550_MEM_SDWRMD1 0x0888 |
670 | #define MEM_SDERRADDR 0x0858 | 737 | #define AU1550_MEM_SDWRMD2 0x0890 |
671 | #define MEM_SDSTRIDE0 0x0860 | 738 | #define AU1550_MEM_SDPRECMD 0x08C0 |
672 | #define MEM_SDSTRIDE1 0x0868 | 739 | #define AU1550_MEM_SDAUTOREF 0x08C8 |
673 | #define MEM_SDSTRIDE2 0x0870 | 740 | #define AU1550_MEM_SDSREF 0x08D0 |
674 | #define MEM_SDWRMD0 0x0880 | 741 | #define AU1550_MEM_SDSLEEP MEM_SDSREF |
675 | #define MEM_SDWRMD1 0x0888 | ||
676 | #define MEM_SDWRMD2 0x0890 | ||
677 | #define MEM_SDPRECMD 0x08C0 | ||
678 | #define MEM_SDAUTOREF 0x08C8 | ||
679 | #define MEM_SDSREF 0x08D0 | ||
680 | #define MEM_SDSLEEP MEM_SDSREF | ||
681 | |||
682 | #endif | ||
683 | |||
684 | /* | ||
685 | * Physical base addresses for integrated peripherals | ||
686 | * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 | ||
687 | */ | ||
688 | |||
689 | #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ | ||
690 | #define AU1000_USBD_PHYS_ADDR 0x10200000 /* 0123 */ | ||
691 | #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | ||
692 | #define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | ||
693 | #define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | ||
694 | #define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */ | ||
695 | #define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */ | ||
696 | #define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */ | ||
697 | #define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */ | ||
698 | #define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */ | ||
699 | #define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */ | ||
700 | #define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */ | ||
701 | #define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */ | ||
702 | #define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */ | ||
703 | #define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */ | ||
704 | #define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */ | ||
705 | #define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */ | ||
706 | #define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ | ||
707 | #define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */ | ||
708 | #define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */ | ||
709 | #define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */ | ||
710 | #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */ | ||
711 | #define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | ||
712 | #define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | ||
713 | |||
714 | |||
715 | #ifdef CONFIG_SOC_AU1000 | ||
716 | #define MEM_PHYS_ADDR 0x14000000 | ||
717 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | ||
718 | #define USBH_PHYS_ADDR 0x10100000 | ||
719 | #define IRDA_PHYS_ADDR 0x10300000 | ||
720 | #define SSI0_PHYS_ADDR 0x11600000 | ||
721 | #define SSI1_PHYS_ADDR 0x11680000 | ||
722 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL | ||
723 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL | ||
724 | #define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL | ||
725 | #endif | ||
726 | |||
727 | /********************************************************************/ | ||
728 | |||
729 | #ifdef CONFIG_SOC_AU1500 | ||
730 | #define MEM_PHYS_ADDR 0x14000000 | ||
731 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | ||
732 | #define USBH_PHYS_ADDR 0x10100000 | ||
733 | #define PCI_PHYS_ADDR 0x14005000 | ||
734 | #define PCI_MEM_PHYS_ADDR 0x400000000ULL | ||
735 | #define PCI_IO_PHYS_ADDR 0x500000000ULL | ||
736 | #define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL | ||
737 | #define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL | ||
738 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL | ||
739 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL | ||
740 | #define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL | ||
741 | #endif | ||
742 | |||
743 | /********************************************************************/ | ||
744 | |||
745 | #ifdef CONFIG_SOC_AU1100 | ||
746 | #define MEM_PHYS_ADDR 0x14000000 | ||
747 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | ||
748 | #define USBH_PHYS_ADDR 0x10100000 | ||
749 | #define IRDA_PHYS_ADDR 0x10300000 | ||
750 | #define SSI0_PHYS_ADDR 0x11600000 | ||
751 | #define SSI1_PHYS_ADDR 0x11680000 | ||
752 | #define LCD_PHYS_ADDR 0x15000000 | ||
753 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL | ||
754 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL | ||
755 | #define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL | ||
756 | #endif | ||
757 | |||
758 | /***********************************************************************/ | ||
759 | |||
760 | #ifdef CONFIG_SOC_AU1550 | ||
761 | #define MEM_PHYS_ADDR 0x14000000 | ||
762 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | ||
763 | #define USBH_PHYS_ADDR 0x14020000 | ||
764 | #define PCI_PHYS_ADDR 0x14005000 | ||
765 | #define PE_PHYS_ADDR 0x14008000 | ||
766 | #define PSC0_PHYS_ADDR 0x11A00000 | ||
767 | #define PSC1_PHYS_ADDR 0x11B00000 | ||
768 | #define PSC2_PHYS_ADDR 0x10A00000 | ||
769 | #define PSC3_PHYS_ADDR 0x10B00000 | ||
770 | #define PCI_MEM_PHYS_ADDR 0x400000000ULL | ||
771 | #define PCI_IO_PHYS_ADDR 0x500000000ULL | ||
772 | #define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL | ||
773 | #define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL | ||
774 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL | ||
775 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL | ||
776 | #define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL | ||
777 | #endif | ||
778 | |||
779 | /***********************************************************************/ | ||
780 | |||
781 | #ifdef CONFIG_SOC_AU1200 | ||
782 | #define MEM_PHYS_ADDR 0x14000000 | ||
783 | #define STATIC_MEM_PHYS_ADDR 0x14001000 | ||
784 | #define AES_PHYS_ADDR 0x10300000 | ||
785 | #define CIM_PHYS_ADDR 0x14004000 | ||
786 | #define USBM_PHYS_ADDR 0x14020000 | ||
787 | #define USBH_PHYS_ADDR 0x14020100 | ||
788 | #define PSC0_PHYS_ADDR 0x11A00000 | ||
789 | #define PSC1_PHYS_ADDR 0x11B00000 | ||
790 | #define LCD_PHYS_ADDR 0x15000000 | ||
791 | #define SWCNT_PHYS_ADDR 0x1110010C | ||
792 | #define MAEFE_PHYS_ADDR 0x14012000 | ||
793 | #define MAEBE_PHYS_ADDR 0x14010000 | ||
794 | #define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL | ||
795 | #define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL | ||
796 | #define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL | ||
797 | #endif | ||
798 | 742 | ||
799 | /* Static Bus Controller */ | 743 | /* Static Bus Controller */ |
800 | #define MEM_STCFG0 0xB4001000 | 744 | #define MEM_STCFG0 0xB4001000 |
@@ -813,81 +757,14 @@ enum soc_au1200_ints { | |||
813 | #define MEM_STTIME3 0xB4001034 | 757 | #define MEM_STTIME3 0xB4001034 |
814 | #define MEM_STADDR3 0xB4001038 | 758 | #define MEM_STADDR3 0xB4001038 |
815 | 759 | ||
816 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
817 | #define MEM_STNDCTL 0xB4001100 | 760 | #define MEM_STNDCTL 0xB4001100 |
818 | #define MEM_STSTAT 0xB4001104 | 761 | #define MEM_STSTAT 0xB4001104 |
819 | 762 | ||
820 | #define MEM_STNAND_CMD 0x0 | 763 | #define MEM_STNAND_CMD 0x0 |
821 | #define MEM_STNAND_ADDR 0x4 | 764 | #define MEM_STNAND_ADDR 0x4 |
822 | #define MEM_STNAND_DATA 0x20 | 765 | #define MEM_STNAND_DATA 0x20 |
823 | #endif | ||
824 | |||
825 | 766 | ||
826 | 767 | ||
827 | |||
828 | /* Au1000 */ | ||
829 | #ifdef CONFIG_SOC_AU1000 | ||
830 | |||
831 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ | ||
832 | #define USB_HOST_CONFIG 0xB017FFFC | ||
833 | #define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT | ||
834 | #endif /* CONFIG_SOC_AU1000 */ | ||
835 | |||
836 | /* Au1500 */ | ||
837 | #ifdef CONFIG_SOC_AU1500 | ||
838 | |||
839 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ | ||
840 | #define USB_HOST_CONFIG 0xB017fffc | ||
841 | #define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT | ||
842 | #endif /* CONFIG_SOC_AU1500 */ | ||
843 | |||
844 | /* Au1100 */ | ||
845 | #ifdef CONFIG_SOC_AU1100 | ||
846 | |||
847 | #define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */ | ||
848 | #define USB_HOST_CONFIG 0xB017FFFC | ||
849 | #define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT | ||
850 | #endif /* CONFIG_SOC_AU1100 */ | ||
851 | |||
852 | #ifdef CONFIG_SOC_AU1550 | ||
853 | |||
854 | #define USB_OHCI_BASE 0x14020000 /* phys addr for ioremap */ | ||
855 | #define USB_OHCI_LEN 0x00060000 | ||
856 | #define USB_HOST_CONFIG 0xB4027ffc | ||
857 | #define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT | ||
858 | #endif /* CONFIG_SOC_AU1550 */ | ||
859 | |||
860 | |||
861 | #ifdef CONFIG_SOC_AU1200 | ||
862 | |||
863 | #define USB_UOC_BASE 0x14020020 | ||
864 | #define USB_UOC_LEN 0x20 | ||
865 | #define USB_OHCI_BASE 0x14020100 | ||
866 | #define USB_OHCI_LEN 0x100 | ||
867 | #define USB_EHCI_BASE 0x14020200 | ||
868 | #define USB_EHCI_LEN 0x100 | ||
869 | #define USB_UDC_BASE 0x14022000 | ||
870 | #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 | |||
887 | #define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT | ||
888 | |||
889 | #endif /* CONFIG_SOC_AU1200 */ | ||
890 | |||
891 | /* Programmable Counters 0 and 1 */ | 768 | /* Programmable Counters 0 and 1 */ |
892 | #define SYS_BASE 0xB1900000 | 769 | #define SYS_BASE 0xB1900000 |
893 | #define SYS_COUNTER_CNTRL (SYS_BASE + 0x14) | 770 | #define SYS_COUNTER_CNTRL (SYS_BASE + 0x14) |
@@ -958,56 +835,6 @@ enum soc_au1200_ints { | |||
958 | # define I2S_CONTROL_D (1 << 1) | 835 | # define I2S_CONTROL_D (1 << 1) |
959 | # define I2S_CONTROL_CE (1 << 0) | 836 | # define I2S_CONTROL_CE (1 << 0) |
960 | 837 | ||
961 | /* USB Host Controller */ | ||
962 | #ifndef USB_OHCI_LEN | ||
963 | #define USB_OHCI_LEN 0x00100000 | ||
964 | #endif | ||
965 | |||
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 | 838 | ||
1012 | /* Ethernet Controllers */ | 839 | /* Ethernet Controllers */ |
1013 | 840 | ||
@@ -1322,7 +1149,6 @@ enum soc_au1200_ints { | |||
1322 | # define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) | 1149 | # define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) |
1323 | 1150 | ||
1324 | /* Au1200 only */ | 1151 | /* Au1200 only */ |
1325 | #ifdef CONFIG_SOC_AU1200 | ||
1326 | #define SYS_PINFUNC_DMA (1 << 31) | 1152 | #define SYS_PINFUNC_DMA (1 << 31) |
1327 | #define SYS_PINFUNC_S0A (1 << 30) | 1153 | #define SYS_PINFUNC_S0A (1 << 30) |
1328 | #define SYS_PINFUNC_S1A (1 << 29) | 1154 | #define SYS_PINFUNC_S1A (1 << 29) |
@@ -1350,7 +1176,6 @@ enum soc_au1200_ints { | |||
1350 | #define SYS_PINFUNC_P0B (1 << 4) | 1176 | #define SYS_PINFUNC_P0B (1 << 4) |
1351 | #define SYS_PINFUNC_U0T (1 << 3) | 1177 | #define SYS_PINFUNC_U0T (1 << 3) |
1352 | #define SYS_PINFUNC_S1B (1 << 2) | 1178 | #define SYS_PINFUNC_S1B (1 << 2) |
1353 | #endif | ||
1354 | 1179 | ||
1355 | /* Power Management */ | 1180 | /* Power Management */ |
1356 | #define SYS_SCRATCH0 0xB1900018 | 1181 | #define SYS_SCRATCH0 0xB1900018 |
@@ -1406,12 +1231,12 @@ enum soc_au1200_ints { | |||
1406 | # define SYS_CS_MI2_MASK (0x7 << SYS_CS_MI2_BIT) | 1231 | # define SYS_CS_MI2_MASK (0x7 << SYS_CS_MI2_BIT) |
1407 | # define SYS_CS_DI2 (1 << 16) | 1232 | # define SYS_CS_DI2 (1 << 16) |
1408 | # define SYS_CS_CI2 (1 << 15) | 1233 | # define SYS_CS_CI2 (1 << 15) |
1409 | #ifdef CONFIG_SOC_AU1100 | 1234 | |
1410 | # define SYS_CS_ML_BIT 7 | 1235 | # define SYS_CS_ML_BIT 7 |
1411 | # define SYS_CS_ML_MASK (0x7 << SYS_CS_ML_BIT) | 1236 | # define SYS_CS_ML_MASK (0x7 << SYS_CS_ML_BIT) |
1412 | # define SYS_CS_DL (1 << 6) | 1237 | # define SYS_CS_DL (1 << 6) |
1413 | # define SYS_CS_CL (1 << 5) | 1238 | # define SYS_CS_CL (1 << 5) |
1414 | #else | 1239 | |
1415 | # define SYS_CS_MUH_BIT 12 | 1240 | # define SYS_CS_MUH_BIT 12 |
1416 | # define SYS_CS_MUH_MASK (0x7 << SYS_CS_MUH_BIT) | 1241 | # define SYS_CS_MUH_MASK (0x7 << SYS_CS_MUH_BIT) |
1417 | # define SYS_CS_DUH (1 << 11) | 1242 | # define SYS_CS_DUH (1 << 11) |
@@ -1420,7 +1245,7 @@ enum soc_au1200_ints { | |||
1420 | # define SYS_CS_MUD_MASK (0x7 << SYS_CS_MUD_BIT) | 1245 | # define SYS_CS_MUD_MASK (0x7 << SYS_CS_MUD_BIT) |
1421 | # define SYS_CS_DUD (1 << 6) | 1246 | # define SYS_CS_DUD (1 << 6) |
1422 | # define SYS_CS_CUD (1 << 5) | 1247 | # define SYS_CS_CUD (1 << 5) |
1423 | #endif | 1248 | |
1424 | # define SYS_CS_MIR_BIT 2 | 1249 | # define SYS_CS_MIR_BIT 2 |
1425 | # define SYS_CS_MIR_MASK (0x7 << SYS_CS_MIR_BIT) | 1250 | # define SYS_CS_MIR_MASK (0x7 << SYS_CS_MIR_BIT) |
1426 | # define SYS_CS_DIR (1 << 1) | 1251 | # define SYS_CS_DIR (1 << 1) |
@@ -1467,58 +1292,30 @@ enum soc_au1200_ints { | |||
1467 | # define AC97C_RS (1 << 1) | 1292 | # define AC97C_RS (1 << 1) |
1468 | # define AC97C_CE (1 << 0) | 1293 | # define AC97C_CE (1 << 0) |
1469 | 1294 | ||
1470 | #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) | ||
1471 | /* Au1500 PCI Controller */ | ||
1472 | #define Au1500_CFG_BASE 0xB4005000 /* virtual, KSEG1 addr */ | ||
1473 | #define Au1500_PCI_CMEM (Au1500_CFG_BASE + 0) | ||
1474 | #define Au1500_PCI_CFG (Au1500_CFG_BASE + 4) | ||
1475 | # define PCI_ERROR ((1 << 22) | (1 << 23) | (1 << 24) | \ | ||
1476 | (1 << 25) | (1 << 26) | (1 << 27)) | ||
1477 | #define Au1500_PCI_B2BMASK_CCH (Au1500_CFG_BASE + 8) | ||
1478 | #define Au1500_PCI_B2B0_VID (Au1500_CFG_BASE + 0xC) | ||
1479 | #define Au1500_PCI_B2B1_ID (Au1500_CFG_BASE + 0x10) | ||
1480 | #define Au1500_PCI_MWMASK_DEV (Au1500_CFG_BASE + 0x14) | ||
1481 | #define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18) | ||
1482 | #define Au1500_PCI_ERR_ADDR (Au1500_CFG_BASE + 0x1C) | ||
1483 | #define Au1500_PCI_SPEC_INTACK (Au1500_CFG_BASE + 0x20) | ||
1484 | #define Au1500_PCI_ID (Au1500_CFG_BASE + 0x100) | ||
1485 | #define Au1500_PCI_STATCMD (Au1500_CFG_BASE + 0x104) | ||
1486 | #define Au1500_PCI_CLASSREV (Au1500_CFG_BASE + 0x108) | ||
1487 | #define Au1500_PCI_HDRTYPE (Au1500_CFG_BASE + 0x10C) | ||
1488 | #define Au1500_PCI_MBAR (Au1500_CFG_BASE + 0x110) | ||
1489 | |||
1490 | #define Au1500_PCI_HDR 0xB4005100 /* virtual, KSEG1 addr */ | ||
1491 | 1295 | ||
1492 | /* | 1296 | /* The PCI chip selects are outside the 32bit space, and since we can't |
1493 | * All of our structures, like PCI resource, have 32-bit members. | 1297 | * just program the 36bit addresses into BARs, we have to take a chunk |
1494 | * Drivers are expected to do an ioremap on the PCI MEM resource, but it's | 1298 | * out of the 32bit space and reserve it for PCI. When these addresses |
1495 | * hard to store 0x4 0000 0000 in a 32-bit type. We require a small patch | 1299 | * are ioremap()ed, they'll be fixed up to the real 36bit address before |
1496 | * to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and | 1300 | * being passed to the real ioremap function. |
1497 | * (u32)Au1500_PCI_MEM_END and change those to the full 36-bit PCI MEM | ||
1498 | * addresses. For PCI I/O, it's simpler because we get to do the ioremap | ||
1499 | * ourselves and then adjust the device's resources. | ||
1500 | */ | 1301 | */ |
1501 | #define Au1500_EXT_CFG 0x600000000ULL | 1302 | #define ALCHEMY_PCI_MEMWIN_START (AU1500_PCI_MEM_PHYS_ADDR >> 4) |
1502 | #define Au1500_EXT_CFG_TYPE1 0x680000000ULL | 1303 | #define ALCHEMY_PCI_MEMWIN_END (ALCHEMY_PCI_MEMWIN_START + 0x0FFFFFFF) |
1503 | #define Au1500_PCI_IO_START 0x500000000ULL | ||
1504 | #define Au1500_PCI_IO_END 0x5000FFFFFULL | ||
1505 | #define Au1500_PCI_MEM_START 0x440000000ULL | ||
1506 | #define Au1500_PCI_MEM_END 0x44FFFFFFFULL | ||
1507 | 1304 | ||
1508 | #define PCI_IO_START 0x00001000 | 1305 | /* for PCI IO it's simpler because we get to do the ioremap ourselves and then |
1509 | #define PCI_IO_END 0x000FFFFF | 1306 | * adjust the device's resources. |
1510 | #define PCI_MEM_START 0x40000000 | 1307 | */ |
1511 | #define PCI_MEM_END 0x4FFFFFFF | 1308 | #define ALCHEMY_PCI_IOWIN_START 0x00001000 |
1309 | #define ALCHEMY_PCI_IOWIN_END 0x0000FFFF | ||
1512 | 1310 | ||
1513 | #define PCI_FIRST_DEVFN (0 << 3) | 1311 | #ifdef CONFIG_PCI |
1514 | #define PCI_LAST_DEVFN (19 << 3) | ||
1515 | 1312 | ||
1516 | #define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */ | 1313 | #define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */ |
1517 | #define IOPORT_RESOURCE_END 0xffffffff | 1314 | #define IOPORT_RESOURCE_END 0xffffffff |
1518 | #define IOMEM_RESOURCE_START 0x10000000 | 1315 | #define IOMEM_RESOURCE_START 0x10000000 |
1519 | #define IOMEM_RESOURCE_END 0xfffffffffULL | 1316 | #define IOMEM_RESOURCE_END 0xfffffffffULL |
1520 | 1317 | ||
1521 | #else /* Au1000 and Au1100 and Au1200 */ | 1318 | #else |
1522 | 1319 | ||
1523 | /* Don't allow any legacy ports probing */ | 1320 | /* Don't allow any legacy ports probing */ |
1524 | #define IOPORT_RESOURCE_START 0x10000000 | 1321 | #define IOPORT_RESOURCE_START 0x10000000 |
@@ -1526,13 +1323,77 @@ enum soc_au1200_ints { | |||
1526 | #define IOMEM_RESOURCE_START 0x10000000 | 1323 | #define IOMEM_RESOURCE_START 0x10000000 |
1527 | #define IOMEM_RESOURCE_END 0xfffffffffULL | 1324 | #define IOMEM_RESOURCE_END 0xfffffffffULL |
1528 | 1325 | ||
1529 | #define PCI_IO_START 0 | ||
1530 | #define PCI_IO_END 0 | ||
1531 | #define PCI_MEM_START 0 | ||
1532 | #define PCI_MEM_END 0 | ||
1533 | #define PCI_FIRST_DEVFN 0 | ||
1534 | #define PCI_LAST_DEVFN 0 | ||
1535 | |||
1536 | #endif | 1326 | #endif |
1537 | 1327 | ||
1328 | /* PCI controller block register offsets */ | ||
1329 | #define PCI_REG_CMEM 0x0000 | ||
1330 | #define PCI_REG_CONFIG 0x0004 | ||
1331 | #define PCI_REG_B2BMASK_CCH 0x0008 | ||
1332 | #define PCI_REG_B2BBASE0_VID 0x000C | ||
1333 | #define PCI_REG_B2BBASE1_SID 0x0010 | ||
1334 | #define PCI_REG_MWMASK_DEV 0x0014 | ||
1335 | #define PCI_REG_MWBASE_REV_CCL 0x0018 | ||
1336 | #define PCI_REG_ERR_ADDR 0x001C | ||
1337 | #define PCI_REG_SPEC_INTACK 0x0020 | ||
1338 | #define PCI_REG_ID 0x0100 | ||
1339 | #define PCI_REG_STATCMD 0x0104 | ||
1340 | #define PCI_REG_CLASSREV 0x0108 | ||
1341 | #define PCI_REG_PARAM 0x010C | ||
1342 | #define PCI_REG_MBAR 0x0110 | ||
1343 | #define PCI_REG_TIMEOUT 0x0140 | ||
1344 | |||
1345 | /* PCI controller block register bits */ | ||
1346 | #define PCI_CMEM_E (1 << 28) /* enable cacheable memory */ | ||
1347 | #define PCI_CMEM_CMBASE(x) (((x) & 0x3fff) << 14) | ||
1348 | #define PCI_CMEM_CMMASK(x) ((x) & 0x3fff) | ||
1349 | #define PCI_CONFIG_ERD (1 << 27) /* pci error during R/W */ | ||
1350 | #define PCI_CONFIG_ET (1 << 26) /* error in target mode */ | ||
1351 | #define PCI_CONFIG_EF (1 << 25) /* fatal error */ | ||
1352 | #define PCI_CONFIG_EP (1 << 24) /* parity error */ | ||
1353 | #define PCI_CONFIG_EM (1 << 23) /* multiple errors */ | ||
1354 | #define PCI_CONFIG_BM (1 << 22) /* bad master error */ | ||
1355 | #define PCI_CONFIG_PD (1 << 20) /* PCI Disable */ | ||
1356 | #define PCI_CONFIG_BME (1 << 19) /* Byte Mask Enable for reads */ | ||
1357 | #define PCI_CONFIG_NC (1 << 16) /* mark mem access non-coherent */ | ||
1358 | #define PCI_CONFIG_IA (1 << 15) /* INTA# enabled (target mode) */ | ||
1359 | #define PCI_CONFIG_IP (1 << 13) /* int on PCI_PERR# */ | ||
1360 | #define PCI_CONFIG_IS (1 << 12) /* int on PCI_SERR# */ | ||
1361 | #define PCI_CONFIG_IMM (1 << 11) /* int on master abort */ | ||
1362 | #define PCI_CONFIG_ITM (1 << 10) /* int on target abort (as master) */ | ||
1363 | #define PCI_CONFIG_ITT (1 << 9) /* int on target abort (as target) */ | ||
1364 | #define PCI_CONFIG_IPB (1 << 8) /* int on PERR# in bus master acc */ | ||
1365 | #define PCI_CONFIG_SIC_NO (0 << 6) /* no byte mask changes */ | ||
1366 | #define PCI_CONFIG_SIC_BA_ADR (1 << 6) /* on byte/hw acc, invert adr bits */ | ||
1367 | #define PCI_CONFIG_SIC_HWA_DAT (2 << 6) /* on halfword acc, swap data */ | ||
1368 | #define PCI_CONFIG_SIC_ALL (3 << 6) /* swap data bytes on all accesses */ | ||
1369 | #define PCI_CONFIG_ST (1 << 5) /* swap data by target transactions */ | ||
1370 | #define PCI_CONFIG_SM (1 << 4) /* swap data from PCI ctl */ | ||
1371 | #define PCI_CONFIG_AEN (1 << 3) /* enable internal arbiter */ | ||
1372 | #define PCI_CONFIG_R2H (1 << 2) /* REQ2# to hi-prio arbiter */ | ||
1373 | #define PCI_CONFIG_R1H (1 << 1) /* REQ1# to hi-prio arbiter */ | ||
1374 | #define PCI_CONFIG_CH (1 << 0) /* PCI ctl to hi-prio arbiter */ | ||
1375 | #define PCI_B2BMASK_B2BMASK(x) (((x) & 0xffff) << 16) | ||
1376 | #define PCI_B2BMASK_CCH(x) ((x) & 0xffff) /* 16 upper bits of class code */ | ||
1377 | #define PCI_B2BBASE0_VID_B0(x) (((x) & 0xffff) << 16) | ||
1378 | #define PCI_B2BBASE0_VID_SV(x) ((x) & 0xffff) | ||
1379 | #define PCI_B2BBASE1_SID_B1(x) (((x) & 0xffff) << 16) | ||
1380 | #define PCI_B2BBASE1_SID_SI(x) ((x) & 0xffff) | ||
1381 | #define PCI_MWMASKDEV_MWMASK(x) (((x) & 0xffff) << 16) | ||
1382 | #define PCI_MWMASKDEV_DEVID(x) ((x) & 0xffff) | ||
1383 | #define PCI_MWBASEREVCCL_BASE(x) (((x) & 0xffff) << 16) | ||
1384 | #define PCI_MWBASEREVCCL_REV(x) (((x) & 0xff) << 8) | ||
1385 | #define PCI_MWBASEREVCCL_CCL(x) ((x) & 0xff) | ||
1386 | #define PCI_ID_DID(x) (((x) & 0xffff) << 16) | ||
1387 | #define PCI_ID_VID(x) ((x) & 0xffff) | ||
1388 | #define PCI_STATCMD_STATUS(x) (((x) & 0xffff) << 16) | ||
1389 | #define PCI_STATCMD_CMD(x) ((x) & 0xffff) | ||
1390 | #define PCI_CLASSREV_CLASS(x) (((x) & 0x00ffffff) << 8) | ||
1391 | #define PCI_CLASSREV_REV(x) ((x) & 0xff) | ||
1392 | #define PCI_PARAM_BIST(x) (((x) & 0xff) << 24) | ||
1393 | #define PCI_PARAM_HT(x) (((x) & 0xff) << 16) | ||
1394 | #define PCI_PARAM_LT(x) (((x) & 0xff) << 8) | ||
1395 | #define PCI_PARAM_CLS(x) ((x) & 0xff) | ||
1396 | #define PCI_TIMEOUT_RETRIES(x) (((x) & 0xff) << 8) /* max retries */ | ||
1397 | #define PCI_TIMEOUT_TO(x) ((x) & 0xff) /* target ready timeout */ | ||
1398 | |||
1538 | #endif | 1399 | #endif |
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx.h b/arch/mips/include/asm/mach-au1x00/au1xxx.h deleted file mode 100644 index 1b3655090ed3..000000000000 --- a/arch/mips/include/asm/mach-au1x00/au1xxx.h +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License as published by the | ||
4 | * Free Software Foundation; either version 2 of the License, or (at your | ||
5 | * option) any later version. | ||
6 | * | ||
7 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
8 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
9 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
10 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
11 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
12 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
13 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
14 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
15 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
16 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #ifndef _AU1XXX_H_ | ||
24 | #define _AU1XXX_H_ | ||
25 | |||
26 | #include <asm/mach-au1x00/au1000.h> | ||
27 | |||
28 | #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \ | ||
29 | defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) | ||
30 | #include <asm/mach-db1x00/db1x00.h> | ||
31 | |||
32 | #elif defined(CONFIG_MIPS_PB1550) | ||
33 | #include <asm/mach-pb1x00/pb1550.h> | ||
34 | |||
35 | #elif defined(CONFIG_MIPS_PB1200) | ||
36 | #include <asm/mach-pb1x00/pb1200.h> | ||
37 | |||
38 | #elif defined(CONFIG_MIPS_DB1200) | ||
39 | #include <asm/mach-db1x00/db1200.h> | ||
40 | |||
41 | #endif | ||
42 | |||
43 | #endif /* _AU1XXX_H_ */ | ||
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h index 2fdacfe85e23..323ce2d145f2 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | |||
@@ -126,66 +126,62 @@ typedef volatile struct au1xxx_ddma_desc { | |||
126 | #define SW_STATUS_INUSE (1 << 0) | 126 | #define SW_STATUS_INUSE (1 << 0) |
127 | 127 | ||
128 | /* Command 0 device IDs. */ | 128 | /* Command 0 device IDs. */ |
129 | #ifdef CONFIG_SOC_AU1550 | 129 | #define AU1550_DSCR_CMD0_UART0_TX 0 |
130 | #define DSCR_CMD0_UART0_TX 0 | 130 | #define AU1550_DSCR_CMD0_UART0_RX 1 |
131 | #define DSCR_CMD0_UART0_RX 1 | 131 | #define AU1550_DSCR_CMD0_UART3_TX 2 |
132 | #define DSCR_CMD0_UART3_TX 2 | 132 | #define AU1550_DSCR_CMD0_UART3_RX 3 |
133 | #define DSCR_CMD0_UART3_RX 3 | 133 | #define AU1550_DSCR_CMD0_DMA_REQ0 4 |
134 | #define DSCR_CMD0_DMA_REQ0 4 | 134 | #define AU1550_DSCR_CMD0_DMA_REQ1 5 |
135 | #define DSCR_CMD0_DMA_REQ1 5 | 135 | #define AU1550_DSCR_CMD0_DMA_REQ2 6 |
136 | #define DSCR_CMD0_DMA_REQ2 6 | 136 | #define AU1550_DSCR_CMD0_DMA_REQ3 7 |
137 | #define DSCR_CMD0_DMA_REQ3 7 | 137 | #define AU1550_DSCR_CMD0_USBDEV_RX0 8 |
138 | #define DSCR_CMD0_USBDEV_RX0 8 | 138 | #define AU1550_DSCR_CMD0_USBDEV_TX0 9 |
139 | #define DSCR_CMD0_USBDEV_TX0 9 | 139 | #define AU1550_DSCR_CMD0_USBDEV_TX1 10 |
140 | #define DSCR_CMD0_USBDEV_TX1 10 | 140 | #define AU1550_DSCR_CMD0_USBDEV_TX2 11 |
141 | #define DSCR_CMD0_USBDEV_TX2 11 | 141 | #define AU1550_DSCR_CMD0_USBDEV_RX3 12 |
142 | #define DSCR_CMD0_USBDEV_RX3 12 | 142 | #define AU1550_DSCR_CMD0_USBDEV_RX4 13 |
143 | #define DSCR_CMD0_USBDEV_RX4 13 | 143 | #define AU1550_DSCR_CMD0_PSC0_TX 14 |
144 | #define DSCR_CMD0_PSC0_TX 14 | 144 | #define AU1550_DSCR_CMD0_PSC0_RX 15 |
145 | #define DSCR_CMD0_PSC0_RX 15 | 145 | #define AU1550_DSCR_CMD0_PSC1_TX 16 |
146 | #define DSCR_CMD0_PSC1_TX 16 | 146 | #define AU1550_DSCR_CMD0_PSC1_RX 17 |
147 | #define DSCR_CMD0_PSC1_RX 17 | 147 | #define AU1550_DSCR_CMD0_PSC2_TX 18 |
148 | #define DSCR_CMD0_PSC2_TX 18 | 148 | #define AU1550_DSCR_CMD0_PSC2_RX 19 |
149 | #define DSCR_CMD0_PSC2_RX 19 | 149 | #define AU1550_DSCR_CMD0_PSC3_TX 20 |
150 | #define DSCR_CMD0_PSC3_TX 20 | 150 | #define AU1550_DSCR_CMD0_PSC3_RX 21 |
151 | #define DSCR_CMD0_PSC3_RX 21 | 151 | #define AU1550_DSCR_CMD0_PCI_WRITE 22 |
152 | #define DSCR_CMD0_PCI_WRITE 22 | 152 | #define AU1550_DSCR_CMD0_NAND_FLASH 23 |
153 | #define DSCR_CMD0_NAND_FLASH 23 | 153 | #define AU1550_DSCR_CMD0_MAC0_RX 24 |
154 | #define DSCR_CMD0_MAC0_RX 24 | 154 | #define AU1550_DSCR_CMD0_MAC0_TX 25 |
155 | #define DSCR_CMD0_MAC0_TX 25 | 155 | #define AU1550_DSCR_CMD0_MAC1_RX 26 |
156 | #define DSCR_CMD0_MAC1_RX 26 | 156 | #define AU1550_DSCR_CMD0_MAC1_TX 27 |
157 | #define DSCR_CMD0_MAC1_TX 27 | 157 | |
158 | #endif /* CONFIG_SOC_AU1550 */ | 158 | #define AU1200_DSCR_CMD0_UART0_TX 0 |
159 | 159 | #define AU1200_DSCR_CMD0_UART0_RX 1 | |
160 | #ifdef CONFIG_SOC_AU1200 | 160 | #define AU1200_DSCR_CMD0_UART1_TX 2 |
161 | #define DSCR_CMD0_UART0_TX 0 | 161 | #define AU1200_DSCR_CMD0_UART1_RX 3 |
162 | #define DSCR_CMD0_UART0_RX 1 | 162 | #define AU1200_DSCR_CMD0_DMA_REQ0 4 |
163 | #define DSCR_CMD0_UART1_TX 2 | 163 | #define AU1200_DSCR_CMD0_DMA_REQ1 5 |
164 | #define DSCR_CMD0_UART1_RX 3 | 164 | #define AU1200_DSCR_CMD0_MAE_BE 6 |
165 | #define DSCR_CMD0_DMA_REQ0 4 | 165 | #define AU1200_DSCR_CMD0_MAE_FE 7 |
166 | #define DSCR_CMD0_DMA_REQ1 5 | 166 | #define AU1200_DSCR_CMD0_SDMS_TX0 8 |
167 | #define DSCR_CMD0_MAE_BE 6 | 167 | #define AU1200_DSCR_CMD0_SDMS_RX0 9 |
168 | #define DSCR_CMD0_MAE_FE 7 | 168 | #define AU1200_DSCR_CMD0_SDMS_TX1 10 |
169 | #define DSCR_CMD0_SDMS_TX0 8 | 169 | #define AU1200_DSCR_CMD0_SDMS_RX1 11 |
170 | #define DSCR_CMD0_SDMS_RX0 9 | 170 | #define AU1200_DSCR_CMD0_AES_TX 13 |
171 | #define DSCR_CMD0_SDMS_TX1 10 | 171 | #define AU1200_DSCR_CMD0_AES_RX 12 |
172 | #define DSCR_CMD0_SDMS_RX1 11 | 172 | #define AU1200_DSCR_CMD0_PSC0_TX 14 |
173 | #define DSCR_CMD0_AES_TX 13 | 173 | #define AU1200_DSCR_CMD0_PSC0_RX 15 |
174 | #define DSCR_CMD0_AES_RX 12 | 174 | #define AU1200_DSCR_CMD0_PSC1_TX 16 |
175 | #define DSCR_CMD0_PSC0_TX 14 | 175 | #define AU1200_DSCR_CMD0_PSC1_RX 17 |
176 | #define DSCR_CMD0_PSC0_RX 15 | 176 | #define AU1200_DSCR_CMD0_CIM_RXA 18 |
177 | #define DSCR_CMD0_PSC1_TX 16 | 177 | #define AU1200_DSCR_CMD0_CIM_RXB 19 |
178 | #define DSCR_CMD0_PSC1_RX 17 | 178 | #define AU1200_DSCR_CMD0_CIM_RXC 20 |
179 | #define DSCR_CMD0_CIM_RXA 18 | 179 | #define AU1200_DSCR_CMD0_MAE_BOTH 21 |
180 | #define DSCR_CMD0_CIM_RXB 19 | 180 | #define AU1200_DSCR_CMD0_LCD 22 |
181 | #define DSCR_CMD0_CIM_RXC 20 | 181 | #define AU1200_DSCR_CMD0_NAND_FLASH 23 |
182 | #define DSCR_CMD0_MAE_BOTH 21 | 182 | #define AU1200_DSCR_CMD0_PSC0_SYNC 24 |
183 | #define DSCR_CMD0_LCD 22 | 183 | #define AU1200_DSCR_CMD0_PSC1_SYNC 25 |
184 | #define DSCR_CMD0_NAND_FLASH 23 | 184 | #define AU1200_DSCR_CMD0_CIM_SYNC 26 |
185 | #define DSCR_CMD0_PSC0_SYNC 24 | ||
186 | #define DSCR_CMD0_PSC1_SYNC 25 | ||
187 | #define DSCR_CMD0_CIM_SYNC 26 | ||
188 | #endif /* CONFIG_SOC_AU1200 */ | ||
189 | 185 | ||
190 | #define DSCR_CMD0_THROTTLE 30 | 186 | #define DSCR_CMD0_THROTTLE 30 |
191 | #define DSCR_CMD0_ALWAYS 31 | 187 | #define DSCR_CMD0_ALWAYS 31 |
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h b/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h index 5656c72de6d3..e306384b1414 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h | |||
@@ -58,6 +58,7 @@ typedef struct { | |||
58 | #endif | 58 | #endif |
59 | int irq; | 59 | int irq; |
60 | u32 regbase; | 60 | u32 regbase; |
61 | int ddma_id; | ||
61 | } _auide_hwif; | 62 | } _auide_hwif; |
62 | 63 | ||
63 | /******************************************************************************/ | 64 | /******************************************************************************/ |
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h b/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h index 5a5cb7386427..4e3f3bc26c60 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h | |||
@@ -33,19 +33,6 @@ | |||
33 | #ifndef _AU1000_PSC_H_ | 33 | #ifndef _AU1000_PSC_H_ |
34 | #define _AU1000_PSC_H_ | 34 | #define _AU1000_PSC_H_ |
35 | 35 | ||
36 | /* The PSC base addresses. */ | ||
37 | #ifdef CONFIG_SOC_AU1550 | ||
38 | #define PSC0_BASE_ADDR 0xb1a00000 | ||
39 | #define PSC1_BASE_ADDR 0xb1b00000 | ||
40 | #define PSC2_BASE_ADDR 0xb0a00000 | ||
41 | #define PSC3_BASE_ADDR 0xb0b00000 | ||
42 | #endif | ||
43 | |||
44 | #ifdef CONFIG_SOC_AU1200 | ||
45 | #define PSC0_BASE_ADDR 0xb1a00000 | ||
46 | #define PSC1_BASE_ADDR 0xb1b00000 | ||
47 | #endif | ||
48 | |||
49 | /* | 36 | /* |
50 | * The PSC select and control registers are common to all protocols. | 37 | * The PSC select and control registers are common to all protocols. |
51 | */ | 38 | */ |
@@ -80,19 +67,6 @@ | |||
80 | #define PSC_AC97GPO_OFFSET 0x00000028 | 67 | #define PSC_AC97GPO_OFFSET 0x00000028 |
81 | #define PSC_AC97GPI_OFFSET 0x0000002c | 68 | #define PSC_AC97GPI_OFFSET 0x0000002c |
82 | 69 | ||
83 | #define AC97_PSC_SEL (AC97_PSC_BASE + PSC_SEL_OFFSET) | ||
84 | #define AC97_PSC_CTRL (AC97_PSC_BASE + PSC_CTRL_OFFSET) | ||
85 | #define PSC_AC97CFG (AC97_PSC_BASE + PSC_AC97CFG_OFFSET) | ||
86 | #define PSC_AC97MSK (AC97_PSC_BASE + PSC_AC97MSK_OFFSET) | ||
87 | #define PSC_AC97PCR (AC97_PSC_BASE + PSC_AC97PCR_OFFSET) | ||
88 | #define PSC_AC97STAT (AC97_PSC_BASE + PSC_AC97STAT_OFFSET) | ||
89 | #define PSC_AC97EVNT (AC97_PSC_BASE + PSC_AC97EVNT_OFFSET) | ||
90 | #define PSC_AC97TXRX (AC97_PSC_BASE + PSC_AC97TXRX_OFFSET) | ||
91 | #define PSC_AC97CDC (AC97_PSC_BASE + PSC_AC97CDC_OFFSET) | ||
92 | #define PSC_AC97RST (AC97_PSC_BASE + PSC_AC97RST_OFFSET) | ||
93 | #define PSC_AC97GPO (AC97_PSC_BASE + PSC_AC97GPO_OFFSET) | ||
94 | #define PSC_AC97GPI (AC97_PSC_BASE + PSC_AC97GPI_OFFSET) | ||
95 | |||
96 | /* AC97 Config Register. */ | 70 | /* AC97 Config Register. */ |
97 | #define PSC_AC97CFG_RT_MASK (3 << 30) | 71 | #define PSC_AC97CFG_RT_MASK (3 << 30) |
98 | #define PSC_AC97CFG_RT_FIFO1 (0 << 30) | 72 | #define PSC_AC97CFG_RT_FIFO1 (0 << 30) |
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h index 1f41a522906d..73853b5a2a31 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h +++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h | |||
@@ -347,17 +347,6 @@ static inline int alchemy_gpio2_to_irq(int gpio) | |||
347 | 347 | ||
348 | /**********************************************************************/ | 348 | /**********************************************************************/ |
349 | 349 | ||
350 | /* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before | ||
351 | * SYS_PININPUTEN is written to at least once. On Au1550/Au1200 this | ||
352 | * register enables use of GPIOs as wake source. | ||
353 | */ | ||
354 | static inline void alchemy_gpio1_input_enable(void) | ||
355 | { | ||
356 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
357 | __raw_writel(0, base + SYS_PININPUTEN); /* the write op is key */ | ||
358 | wmb(); | ||
359 | } | ||
360 | |||
361 | /* GPIO2 shared interrupts and control */ | 350 | /* GPIO2 shared interrupts and control */ |
362 | 351 | ||
363 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) | 352 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) |
@@ -561,6 +550,7 @@ static inline int alchemy_irq_to_gpio(int irq) | |||
561 | 550 | ||
562 | #ifndef CONFIG_GPIOLIB | 551 | #ifndef CONFIG_GPIOLIB |
563 | 552 | ||
553 | #ifdef CONFIG_ALCHEMY_GPIOINT_AU1000 | ||
564 | 554 | ||
565 | #ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */ | 555 | #ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */ |
566 | 556 | ||
@@ -665,24 +655,7 @@ static inline void gpio_unexport(unsigned gpio) | |||
665 | 655 | ||
666 | #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ | 656 | #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ |
667 | 657 | ||
668 | 658 | #endif /* CONFIG_ALCHEMY_GPIOINT_AU1000 */ | |
669 | #else /* CONFIG GPIOLIB */ | ||
670 | |||
671 | |||
672 | /* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */ | ||
673 | #ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (2) */ | ||
674 | |||
675 | /* get everything through gpiolib */ | ||
676 | #define gpio_to_irq __gpio_to_irq | ||
677 | #define gpio_get_value __gpio_get_value | ||
678 | #define gpio_set_value __gpio_set_value | ||
679 | #define gpio_cansleep __gpio_cansleep | ||
680 | #define irq_to_gpio alchemy_irq_to_gpio | ||
681 | |||
682 | #include <asm-generic/gpio.h> | ||
683 | |||
684 | #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ | ||
685 | |||
686 | 659 | ||
687 | #endif /* !CONFIG_GPIOLIB */ | 660 | #endif /* !CONFIG_GPIOLIB */ |
688 | 661 | ||
diff --git a/arch/mips/include/asm/mach-au1x00/gpio.h b/arch/mips/include/asm/mach-au1x00/gpio.h index c3f60cdc3203..fcdc8c4809db 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio.h +++ b/arch/mips/include/asm/mach-au1x00/gpio.h | |||
@@ -1,10 +1,83 @@ | |||
1 | /* | ||
2 | * Alchemy GPIO support. | ||
3 | * | ||
4 | * With CONFIG_GPIOLIB=y different types of on-chip GPIO can be supported within | ||
5 | * the same kernel image. | ||
6 | * With CONFIG_GPIOLIB=n, your board must select ALCHEMY_GPIOINT_AU1XXX for the | ||
7 | * appropriate CPU type (AU1000 currently). | ||
8 | */ | ||
9 | |||
1 | #ifndef _ALCHEMY_GPIO_H_ | 10 | #ifndef _ALCHEMY_GPIO_H_ |
2 | #define _ALCHEMY_GPIO_H_ | 11 | #define _ALCHEMY_GPIO_H_ |
3 | 12 | ||
4 | #if defined(CONFIG_ALCHEMY_GPIOINT_AU1000) | 13 | #include <asm/mach-au1x00/au1000.h> |
5 | |||
6 | #include <asm/mach-au1x00/gpio-au1000.h> | 14 | #include <asm/mach-au1x00/gpio-au1000.h> |
7 | 15 | ||
8 | #endif | 16 | /* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before |
17 | * SYS_PININPUTEN is written to at least once. On Au1550/Au1200/Au1300 this | ||
18 | * register enables use of GPIOs as wake source. | ||
19 | */ | ||
20 | static inline void alchemy_gpio1_input_enable(void) | ||
21 | { | ||
22 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
23 | __raw_writel(0, base + 0x110); /* the write op is key */ | ||
24 | wmb(); | ||
25 | } | ||
26 | |||
27 | |||
28 | /* Linux gpio framework integration. | ||
29 | * | ||
30 | * 4 use cases of Alchemy GPIOS: | ||
31 | *(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y: | ||
32 | * Board must register gpiochips. | ||
33 | *(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n: | ||
34 | * A gpiochip for the 75 GPIOs is registered. | ||
35 | * | ||
36 | *(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y: | ||
37 | * the boards' gpio.h must provide the linux gpio wrapper functions, | ||
38 | * | ||
39 | *(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n: | ||
40 | * inlinable gpio functions are provided which enable access to the | ||
41 | * Au1300 gpios only by using the numbers straight out of the data- | ||
42 | * sheets. | ||
43 | |||
44 | * Cases 1 and 3 are intended for boards which want to provide their own | ||
45 | * GPIO namespace and -operations (i.e. for example you have 8 GPIOs | ||
46 | * which are in part provided by spare Au1300 GPIO pins and in part by | ||
47 | * an external FPGA but you still want them to be accssible in linux | ||
48 | * as gpio0-7. The board can of course use the alchemy_gpioX_* functions | ||
49 | * as required). | ||
50 | */ | ||
51 | |||
52 | #ifdef CONFIG_GPIOLIB | ||
53 | |||
54 | /* wraps the cpu-dependent irq_to_gpio functions */ | ||
55 | /* FIXME: gpiolib needs an irq_to_gpio hook */ | ||
56 | static inline int __au_irq_to_gpio(unsigned int irq) | ||
57 | { | ||
58 | switch (alchemy_get_cputype()) { | ||
59 | case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200: | ||
60 | return alchemy_irq_to_gpio(irq); | ||
61 | } | ||
62 | return -EINVAL; | ||
63 | } | ||
64 | |||
65 | |||
66 | /* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */ | ||
67 | #ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (2) */ | ||
68 | |||
69 | /* get everything through gpiolib */ | ||
70 | #define gpio_to_irq __gpio_to_irq | ||
71 | #define gpio_get_value __gpio_get_value | ||
72 | #define gpio_set_value __gpio_set_value | ||
73 | #define gpio_cansleep __gpio_cansleep | ||
74 | #define irq_to_gpio __au_irq_to_gpio | ||
75 | |||
76 | #include <asm-generic/gpio.h> | ||
77 | |||
78 | #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ | ||
79 | |||
80 | |||
81 | #endif /* CONFIG_GPIOLIB */ | ||
9 | 82 | ||
10 | #endif /* _ALCHEMY_GPIO_H_ */ | 83 | #endif /* _ALCHEMY_GPIO_H_ */ |
diff --git a/arch/mips/include/asm/mach-db1x00/db1200.h b/arch/mips/include/asm/mach-db1x00/db1200.h index 3404248f5094..7a39657108c4 100644 --- a/arch/mips/include/asm/mach-db1x00/db1200.h +++ b/arch/mips/include/asm/mach-db1x00/db1200.h | |||
@@ -46,8 +46,6 @@ | |||
46 | 46 | ||
47 | #define IDE_PHYS_ADDR 0x18800000 | 47 | #define IDE_PHYS_ADDR 0x18800000 |
48 | #define IDE_REG_SHIFT 5 | 48 | #define IDE_REG_SHIFT 5 |
49 | #define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1 | ||
50 | #define IDE_RQSIZE 128 | ||
51 | 49 | ||
52 | #define DB1200_IDE_PHYS_ADDR IDE_PHYS_ADDR | 50 | #define DB1200_IDE_PHYS_ADDR IDE_PHYS_ADDR |
53 | #define DB1200_IDE_PHYS_LEN (16 << IDE_REG_SHIFT) | 51 | #define DB1200_IDE_PHYS_LEN (16 << IDE_REG_SHIFT) |
diff --git a/arch/mips/include/asm/mach-db1x00/db1x00.h b/arch/mips/include/asm/mach-db1x00/db1x00.h index a919dac525a1..a5affb0568ef 100644 --- a/arch/mips/include/asm/mach-db1x00/db1x00.h +++ b/arch/mips/include/asm/mach-db1x00/db1x00.h | |||
@@ -31,15 +31,15 @@ | |||
31 | 31 | ||
32 | #ifdef CONFIG_MIPS_DB1550 | 32 | #ifdef CONFIG_MIPS_DB1550 |
33 | 33 | ||
34 | #define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX | 34 | #define DBDMA_AC97_TX_CHAN AU1550_DSCR_CMD0_PSC1_TX |
35 | #define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX | 35 | #define DBDMA_AC97_RX_CHAN AU1550_DSCR_CMD0_PSC1_RX |
36 | #define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX | 36 | #define DBDMA_I2S_TX_CHAN AU1550_DSCR_CMD0_PSC3_TX |
37 | #define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX | 37 | #define DBDMA_I2S_RX_CHAN AU1550_DSCR_CMD0_PSC3_RX |
38 | 38 | ||
39 | #define SPI_PSC_BASE PSC0_BASE_ADDR | 39 | #define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR |
40 | #define AC97_PSC_BASE PSC1_BASE_ADDR | 40 | #define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR |
41 | #define SMBUS_PSC_BASE PSC2_BASE_ADDR | 41 | #define SMBUS_PSC_BASE AU1550_PSC2_PHYS_ADDR |
42 | #define I2S_PSC_BASE PSC3_BASE_ADDR | 42 | #define I2S_PSC_BASE AU1550_PSC3_PHYS_ADDR |
43 | 43 | ||
44 | #define NAND_PHYS_ADDR 0x20000000 | 44 | #define NAND_PHYS_ADDR 0x20000000 |
45 | 45 | ||
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1200.h b/arch/mips/include/asm/mach-pb1x00/pb1200.h index fce4332ebb7f..374416adb65b 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1200.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1200.h | |||
@@ -28,23 +28,23 @@ | |||
28 | #include <asm/mach-au1x00/au1000.h> | 28 | #include <asm/mach-au1x00/au1000.h> |
29 | #include <asm/mach-au1x00/au1xxx_psc.h> | 29 | #include <asm/mach-au1x00/au1xxx_psc.h> |
30 | 30 | ||
31 | #define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX | 31 | #define DBDMA_AC97_TX_CHAN AU1200_DSCR_CMD0_PSC1_TX |
32 | #define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX | 32 | #define DBDMA_AC97_RX_CHAN AU1200_DSCR_CMD0_PSC1_RX |
33 | #define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX | 33 | #define DBDMA_I2S_TX_CHAN AU1200_DSCR_CMD0_PSC1_TX |
34 | #define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX | 34 | #define DBDMA_I2S_RX_CHAN AU1200_DSCR_CMD0_PSC1_RX |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * SPI and SMB are muxed on the Pb1200 board. | 37 | * SPI and SMB are muxed on the Pb1200 board. |
38 | * Refer to board documentation. | 38 | * Refer to board documentation. |
39 | */ | 39 | */ |
40 | #define SPI_PSC_BASE PSC0_BASE_ADDR | 40 | #define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR |
41 | #define SMBUS_PSC_BASE PSC0_BASE_ADDR | 41 | #define SMBUS_PSC_BASE AU1550_PSC0_PHYS_ADDR |
42 | /* | 42 | /* |
43 | * AC97 and I2S are muxed on the Pb1200 board. | 43 | * AC97 and I2S are muxed on the Pb1200 board. |
44 | * Refer to board documentation. | 44 | * Refer to board documentation. |
45 | */ | 45 | */ |
46 | #define AC97_PSC_BASE PSC1_BASE_ADDR | 46 | #define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR |
47 | #define I2S_PSC_BASE PSC1_BASE_ADDR | 47 | #define I2S_PSC_BASE AU1550_PSC1_PHYS_ADDR |
48 | 48 | ||
49 | 49 | ||
50 | #define BCSR_SYSTEM_VDDI 0x001F | 50 | #define BCSR_SYSTEM_VDDI 0x001F |
@@ -76,8 +76,6 @@ | |||
76 | #define IDE_REG_SHIFT 5 | 76 | #define IDE_REG_SHIFT 5 |
77 | #define IDE_PHYS_LEN (16 << IDE_REG_SHIFT) | 77 | #define IDE_PHYS_LEN (16 << IDE_REG_SHIFT) |
78 | #define IDE_INT PB1200_IDE_INT | 78 | #define IDE_INT PB1200_IDE_INT |
79 | #define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1 | ||
80 | #define IDE_RQSIZE 128 | ||
81 | 79 | ||
82 | #define NAND_PHYS_ADDR 0x1C000000 | 80 | #define NAND_PHYS_ADDR 0x1C000000 |
83 | 81 | ||
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h index f835c88e9593..443b88adebf1 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1550.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1550.h | |||
@@ -30,15 +30,15 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <asm/mach-au1x00/au1xxx_psc.h> | 31 | #include <asm/mach-au1x00/au1xxx_psc.h> |
32 | 32 | ||
33 | #define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX | 33 | #define DBDMA_AC97_TX_CHAN AU1550_DSCR_CMD0_PSC1_TX |
34 | #define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX | 34 | #define DBDMA_AC97_RX_CHAN AU1550_DSCR_CMD0_PSC1_RX |
35 | #define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX | 35 | #define DBDMA_I2S_TX_CHAN AU1550_DSCR_CMD0_PSC3_TX |
36 | #define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX | 36 | #define DBDMA_I2S_RX_CHAN AU1550_DSCR_CMD0_PSC3_RX |
37 | 37 | ||
38 | #define SPI_PSC_BASE PSC0_BASE_ADDR | 38 | #define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR |
39 | #define AC97_PSC_BASE PSC1_BASE_ADDR | 39 | #define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR |
40 | #define SMBUS_PSC_BASE PSC2_BASE_ADDR | 40 | #define SMBUS_PSC_BASE AU1550_PSC2_PHYS_ADDR |
41 | #define I2S_PSC_BASE PSC3_BASE_ADDR | 41 | #define I2S_PSC_BASE AU1550_PSC3_PHYS_ADDR |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Timing values as described in databook, * ns value stripped of | 44 | * Timing values as described in databook, * ns value stripped of |
diff --git a/arch/mips/include/asm/mipsprom.h b/arch/mips/include/asm/mipsprom.h index 146d41b67adc..e93943fabeac 100644 --- a/arch/mips/include/asm/mipsprom.h +++ b/arch/mips/include/asm/mipsprom.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #ifndef __ASM_MIPS_PROM_H | 1 | #ifndef __ASM_MIPSPROM_H |
2 | #define __ASM_MIPS_PROM_H | 2 | #define __ASM_MIPSPROM_H |
3 | 3 | ||
4 | #define PROM_RESET 0 | 4 | #define PROM_RESET 0 |
5 | #define PROM_EXEC 1 | 5 | #define PROM_EXEC 1 |
@@ -73,4 +73,4 @@ | |||
73 | 73 | ||
74 | extern char *prom_getenv(char *); | 74 | extern char *prom_getenv(char *); |
75 | 75 | ||
76 | #endif /* __ASM_MIPS_PROM_H */ | 76 | #endif /* __ASM_MIPSPROM_H */ |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 6a6f8a8f542d..2ea7b817feb8 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -1006,18 +1006,26 @@ do { \ | |||
1006 | #define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val) | 1006 | #define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val) |
1007 | #define read_c0_perfcntr0() __read_32bit_c0_register($25, 1) | 1007 | #define read_c0_perfcntr0() __read_32bit_c0_register($25, 1) |
1008 | #define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val) | 1008 | #define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val) |
1009 | #define read_c0_perfcntr0_64() __read_64bit_c0_register($25, 1) | ||
1010 | #define write_c0_perfcntr0_64(val) __write_64bit_c0_register($25, 1, val) | ||
1009 | #define read_c0_perfctrl1() __read_32bit_c0_register($25, 2) | 1011 | #define read_c0_perfctrl1() __read_32bit_c0_register($25, 2) |
1010 | #define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val) | 1012 | #define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val) |
1011 | #define read_c0_perfcntr1() __read_32bit_c0_register($25, 3) | 1013 | #define read_c0_perfcntr1() __read_32bit_c0_register($25, 3) |
1012 | #define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val) | 1014 | #define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val) |
1015 | #define read_c0_perfcntr1_64() __read_64bit_c0_register($25, 3) | ||
1016 | #define write_c0_perfcntr1_64(val) __write_64bit_c0_register($25, 3, val) | ||
1013 | #define read_c0_perfctrl2() __read_32bit_c0_register($25, 4) | 1017 | #define read_c0_perfctrl2() __read_32bit_c0_register($25, 4) |
1014 | #define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val) | 1018 | #define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val) |
1015 | #define read_c0_perfcntr2() __read_32bit_c0_register($25, 5) | 1019 | #define read_c0_perfcntr2() __read_32bit_c0_register($25, 5) |
1016 | #define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val) | 1020 | #define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val) |
1021 | #define read_c0_perfcntr2_64() __read_64bit_c0_register($25, 5) | ||
1022 | #define write_c0_perfcntr2_64(val) __write_64bit_c0_register($25, 5, val) | ||
1017 | #define read_c0_perfctrl3() __read_32bit_c0_register($25, 6) | 1023 | #define read_c0_perfctrl3() __read_32bit_c0_register($25, 6) |
1018 | #define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val) | 1024 | #define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val) |
1019 | #define read_c0_perfcntr3() __read_32bit_c0_register($25, 7) | 1025 | #define read_c0_perfcntr3() __read_32bit_c0_register($25, 7) |
1020 | #define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val) | 1026 | #define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val) |
1027 | #define read_c0_perfcntr3_64() __read_64bit_c0_register($25, 7) | ||
1028 | #define write_c0_perfcntr3_64(val) __write_64bit_c0_register($25, 7, val) | ||
1021 | 1029 | ||
1022 | /* RM9000 PerfCount performance counter register */ | 1030 | /* RM9000 PerfCount performance counter register */ |
1023 | #define read_c0_perfcount() __read_64bit_c0_register($25, 0) | 1031 | #define read_c0_perfcount() __read_64bit_c0_register($25, 0) |
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index 857d9b7858ad..7a6e82ef449b 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h | |||
@@ -8,8 +8,8 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | #ifndef __ASM_MIPS_PROM_H | 11 | #ifndef __ASM_PROM_H |
12 | #define __ASM_MIPS_PROM_H | 12 | #define __ASM_PROM_H |
13 | 13 | ||
14 | #ifdef CONFIG_OF | 14 | #ifdef CONFIG_OF |
15 | #include <asm/bootinfo.h> | 15 | #include <asm/bootinfo.h> |
@@ -25,4 +25,4 @@ extern void device_tree_init(void); | |||
25 | static inline void device_tree_init(void) { } | 25 | static inline void device_tree_init(void) { } |
26 | #endif /* CONFIG_OF */ | 26 | #endif /* CONFIG_OF */ |
27 | 27 | ||
28 | #endif /* _ASM_MIPS_PROM_H */ | 28 | #endif /* __ASM_PROM_H */ |
diff --git a/arch/mips/include/asm/regdef.h b/arch/mips/include/asm/regdef.h index 7c8ecb6b9c40..785a5189b374 100644 --- a/arch/mips/include/asm/regdef.h +++ b/arch/mips/include/asm/regdef.h | |||
@@ -6,6 +6,8 @@ | |||
6 | * Copyright (C) 1985 MIPS Computer Systems, Inc. | 6 | * Copyright (C) 1985 MIPS Computer Systems, Inc. |
7 | * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle | 7 | * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle |
8 | * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. | 8 | * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. |
9 | * Copyright (C) 2011 Wind River Systems, | ||
10 | * written by Ralf Baechle <ralf@linux-mips.org> | ||
9 | */ | 11 | */ |
10 | #ifndef _ASM_REGDEF_H | 12 | #ifndef _ASM_REGDEF_H |
11 | #define _ASM_REGDEF_H | 13 | #define _ASM_REGDEF_H |
@@ -30,9 +32,13 @@ | |||
30 | #define t2 $10 | 32 | #define t2 $10 |
31 | #define t3 $11 | 33 | #define t3 $11 |
32 | #define t4 $12 | 34 | #define t4 $12 |
35 | #define ta0 $12 | ||
33 | #define t5 $13 | 36 | #define t5 $13 |
37 | #define ta1 $13 | ||
34 | #define t6 $14 | 38 | #define t6 $14 |
39 | #define ta2 $14 | ||
35 | #define t7 $15 | 40 | #define t7 $15 |
41 | #define ta3 $15 | ||
36 | #define s0 $16 /* callee saved */ | 42 | #define s0 $16 /* callee saved */ |
37 | #define s1 $17 | 43 | #define s1 $17 |
38 | #define s2 $18 | 44 | #define s2 $18 |
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 4397972949fa..e1ddb95c05e3 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c | |||
@@ -17,8 +17,6 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | 19 | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/syscore_ops.h> | ||
22 | #include <linux/io.h> | 20 | #include <linux/io.h> |
23 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
24 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
@@ -30,6 +28,8 @@ | |||
30 | 28 | ||
31 | #include <asm/mach-jz4740/base.h> | 29 | #include <asm/mach-jz4740/base.h> |
32 | 30 | ||
31 | #include "irq.h" | ||
32 | |||
33 | #define JZ4740_GPIO_BASE_A (32*0) | 33 | #define JZ4740_GPIO_BASE_A (32*0) |
34 | #define JZ4740_GPIO_BASE_B (32*1) | 34 | #define JZ4740_GPIO_BASE_B (32*1) |
35 | #define JZ4740_GPIO_BASE_C (32*2) | 35 | #define JZ4740_GPIO_BASE_C (32*2) |
@@ -77,14 +77,10 @@ | |||
77 | struct jz_gpio_chip { | 77 | struct jz_gpio_chip { |
78 | unsigned int irq; | 78 | unsigned int irq; |
79 | unsigned int irq_base; | 79 | unsigned int irq_base; |
80 | uint32_t wakeup; | ||
81 | uint32_t suspend_mask; | ||
82 | uint32_t edge_trigger_both; | 80 | uint32_t edge_trigger_both; |
83 | 81 | ||
84 | void __iomem *base; | 82 | void __iomem *base; |
85 | 83 | ||
86 | spinlock_t lock; | ||
87 | |||
88 | struct gpio_chip gpio_chip; | 84 | struct gpio_chip gpio_chip; |
89 | }; | 85 | }; |
90 | 86 | ||
@@ -102,7 +98,8 @@ static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *g | |||
102 | 98 | ||
103 | static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) | 99 | static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) |
104 | { | 100 | { |
105 | return irq_data_get_irq_chip_data(data); | 101 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); |
102 | return gc->private; | ||
106 | } | 103 | } |
107 | 104 | ||
108 | static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) | 105 | static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) |
@@ -304,21 +301,15 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
304 | { | 301 | { |
305 | uint32_t flag; | 302 | uint32_t flag; |
306 | unsigned int gpio_irq; | 303 | unsigned int gpio_irq; |
307 | unsigned int gpio_bank; | ||
308 | struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc); | 304 | struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc); |
309 | 305 | ||
310 | gpio_bank = JZ4740_IRQ_GPIO0 - irq; | ||
311 | |||
312 | flag = readl(chip->base + JZ_REG_GPIO_FLAG); | 306 | flag = readl(chip->base + JZ_REG_GPIO_FLAG); |
313 | |||
314 | if (!flag) | 307 | if (!flag) |
315 | return; | 308 | return; |
316 | 309 | ||
317 | gpio_irq = __fls(flag); | 310 | gpio_irq = chip->irq_base + __fls(flag); |
318 | 311 | ||
319 | jz_gpio_check_trigger_both(chip, irq); | 312 | jz_gpio_check_trigger_both(chip, gpio_irq); |
320 | |||
321 | gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0); | ||
322 | 313 | ||
323 | generic_handle_irq(gpio_irq); | 314 | generic_handle_irq(gpio_irq); |
324 | }; | 315 | }; |
@@ -329,18 +320,12 @@ static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg) | |||
329 | writel(IRQ_TO_BIT(data->irq), chip->base + reg); | 320 | writel(IRQ_TO_BIT(data->irq), chip->base + reg); |
330 | } | 321 | } |
331 | 322 | ||
332 | static void jz_gpio_irq_mask(struct irq_data *data) | ||
333 | { | ||
334 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET); | ||
335 | }; | ||
336 | |||
337 | static void jz_gpio_irq_unmask(struct irq_data *data) | 323 | static void jz_gpio_irq_unmask(struct irq_data *data) |
338 | { | 324 | { |
339 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); | 325 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); |
340 | 326 | ||
341 | jz_gpio_check_trigger_both(chip, data->irq); | 327 | jz_gpio_check_trigger_both(chip, data->irq); |
342 | 328 | irq_gc_unmask_enable_reg(data); | |
343 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR); | ||
344 | }; | 329 | }; |
345 | 330 | ||
346 | /* TODO: Check if function is gpio */ | 331 | /* TODO: Check if function is gpio */ |
@@ -353,18 +338,13 @@ static unsigned int jz_gpio_irq_startup(struct irq_data *data) | |||
353 | 338 | ||
354 | static void jz_gpio_irq_shutdown(struct irq_data *data) | 339 | static void jz_gpio_irq_shutdown(struct irq_data *data) |
355 | { | 340 | { |
356 | jz_gpio_irq_mask(data); | 341 | irq_gc_mask_disable_reg(data); |
357 | 342 | ||
358 | /* Set direction to input */ | 343 | /* Set direction to input */ |
359 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); | 344 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); |
360 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR); | 345 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR); |
361 | } | 346 | } |
362 | 347 | ||
363 | static void jz_gpio_irq_ack(struct irq_data *data) | ||
364 | { | ||
365 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR); | ||
366 | }; | ||
367 | |||
368 | static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) | 348 | static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) |
369 | { | 349 | { |
370 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); | 350 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); |
@@ -408,35 +388,13 @@ static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) | |||
408 | static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) | 388 | static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) |
409 | { | 389 | { |
410 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); | 390 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); |
411 | spin_lock(&chip->lock); | ||
412 | if (on) | ||
413 | chip->wakeup |= IRQ_TO_BIT(data->irq); | ||
414 | else | ||
415 | chip->wakeup &= ~IRQ_TO_BIT(data->irq); | ||
416 | spin_unlock(&chip->lock); | ||
417 | 391 | ||
392 | irq_gc_set_wake(data, on); | ||
418 | irq_set_irq_wake(chip->irq, on); | 393 | irq_set_irq_wake(chip->irq, on); |
394 | |||
419 | return 0; | 395 | return 0; |
420 | } | 396 | } |
421 | 397 | ||
422 | static struct irq_chip jz_gpio_irq_chip = { | ||
423 | .name = "GPIO", | ||
424 | .irq_mask = jz_gpio_irq_mask, | ||
425 | .irq_unmask = jz_gpio_irq_unmask, | ||
426 | .irq_ack = jz_gpio_irq_ack, | ||
427 | .irq_startup = jz_gpio_irq_startup, | ||
428 | .irq_shutdown = jz_gpio_irq_shutdown, | ||
429 | .irq_set_type = jz_gpio_irq_set_type, | ||
430 | .irq_set_wake = jz_gpio_irq_set_wake, | ||
431 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
432 | }; | ||
433 | |||
434 | /* | ||
435 | * This lock class tells lockdep that GPIO irqs are in a different | ||
436 | * category than their parents, so it won't report false recursion. | ||
437 | */ | ||
438 | static struct lock_class_key gpio_lock_class; | ||
439 | |||
440 | #define JZ4740_GPIO_CHIP(_bank) { \ | 398 | #define JZ4740_GPIO_CHIP(_bank) { \ |
441 | .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \ | 399 | .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \ |
442 | .gpio_chip = { \ | 400 | .gpio_chip = { \ |
@@ -458,64 +416,44 @@ static struct jz_gpio_chip jz4740_gpio_chips[] = { | |||
458 | JZ4740_GPIO_CHIP(D), | 416 | JZ4740_GPIO_CHIP(D), |
459 | }; | 417 | }; |
460 | 418 | ||
461 | static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip) | 419 | static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) |
462 | { | ||
463 | chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); | ||
464 | writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); | ||
465 | writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); | ||
466 | } | ||
467 | |||
468 | static int jz4740_gpio_suspend(void) | ||
469 | { | ||
470 | int i; | ||
471 | |||
472 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++) | ||
473 | jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]); | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip) | ||
479 | { | 420 | { |
480 | uint32_t mask = chip->suspend_mask; | 421 | struct irq_chip_generic *gc; |
422 | struct irq_chip_type *ct; | ||
481 | 423 | ||
482 | writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR); | 424 | chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100); |
483 | writel(mask, chip->base + JZ_REG_GPIO_MASK_SET); | ||
484 | } | ||
485 | 425 | ||
486 | static void jz4740_gpio_resume(void) | 426 | chip->irq = JZ4740_IRQ_INTC_GPIO(id); |
487 | { | 427 | irq_set_handler_data(chip->irq, chip); |
488 | int i; | 428 | irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler); |
489 | 429 | ||
490 | for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--) | 430 | gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base, |
491 | jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]); | 431 | chip->base, handle_level_irq); |
492 | } | ||
493 | 432 | ||
494 | static struct syscore_ops jz4740_gpio_syscore_ops = { | 433 | gc->wake_enabled = IRQ_MSK(chip->gpio_chip.ngpio); |
495 | .suspend = jz4740_gpio_suspend, | 434 | gc->private = chip; |
496 | .resume = jz4740_gpio_resume, | ||
497 | }; | ||
498 | 435 | ||
499 | static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) | 436 | ct = gc->chip_types; |
500 | { | 437 | ct->regs.enable = JZ_REG_GPIO_MASK_CLEAR; |
501 | int irq; | 438 | ct->regs.disable = JZ_REG_GPIO_MASK_SET; |
439 | ct->regs.ack = JZ_REG_GPIO_FLAG_CLEAR; | ||
502 | 440 | ||
503 | spin_lock_init(&chip->lock); | 441 | ct->chip.name = "GPIO"; |
442 | ct->chip.irq_mask = irq_gc_mask_disable_reg; | ||
443 | ct->chip.irq_unmask = jz_gpio_irq_unmask; | ||
444 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
445 | ct->chip.irq_suspend = jz4740_irq_suspend; | ||
446 | ct->chip.irq_resume = jz4740_irq_resume; | ||
447 | ct->chip.irq_startup = jz_gpio_irq_startup; | ||
448 | ct->chip.irq_shutdown = jz_gpio_irq_shutdown; | ||
449 | ct->chip.irq_set_type = jz_gpio_irq_set_type; | ||
450 | ct->chip.irq_set_wake = jz_gpio_irq_set_wake; | ||
451 | ct->chip.flags = IRQCHIP_SET_TYPE_MASKED; | ||
504 | 452 | ||
505 | chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100); | 453 | irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio), |
454 | IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL); | ||
506 | 455 | ||
507 | gpiochip_add(&chip->gpio_chip); | 456 | gpiochip_add(&chip->gpio_chip); |
508 | |||
509 | chip->irq = JZ4740_IRQ_INTC_GPIO(id); | ||
510 | irq_set_handler_data(chip->irq, chip); | ||
511 | irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler); | ||
512 | |||
513 | for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) { | ||
514 | irq_set_lockdep_class(irq, &gpio_lock_class); | ||
515 | irq_set_chip_data(irq, chip); | ||
516 | irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, | ||
517 | handle_level_irq); | ||
518 | } | ||
519 | } | 457 | } |
520 | 458 | ||
521 | static int __init jz4740_gpio_init(void) | 459 | static int __init jz4740_gpio_init(void) |
@@ -525,8 +463,6 @@ static int __init jz4740_gpio_init(void) | |||
525 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) | 463 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) |
526 | jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); | 464 | jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); |
527 | 465 | ||
528 | register_syscore_ops(&jz4740_gpio_syscore_ops); | ||
529 | |||
530 | printk(KERN_INFO "JZ4740 GPIO initialized\n"); | 466 | printk(KERN_INFO "JZ4740 GPIO initialized\n"); |
531 | 467 | ||
532 | return 0; | 468 | return 0; |
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c index d82c0c430e03..fc57ded326d8 100644 --- a/arch/mips/jz4740/irq.c +++ b/arch/mips/jz4740/irq.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <asm/mach-jz4740/base.h> | 32 | #include <asm/mach-jz4740/base.h> |
33 | 33 | ||
34 | static void __iomem *jz_intc_base; | 34 | static void __iomem *jz_intc_base; |
35 | static uint32_t jz_intc_wakeup; | ||
36 | static uint32_t jz_intc_saved; | ||
37 | 35 | ||
38 | #define JZ_REG_INTC_STATUS 0x00 | 36 | #define JZ_REG_INTC_STATUS 0x00 |
39 | #define JZ_REG_INTC_MASK 0x04 | 37 | #define JZ_REG_INTC_MASK 0x04 |
@@ -41,51 +39,36 @@ static uint32_t jz_intc_saved; | |||
41 | #define JZ_REG_INTC_CLEAR_MASK 0x0c | 39 | #define JZ_REG_INTC_CLEAR_MASK 0x0c |
42 | #define JZ_REG_INTC_PENDING 0x10 | 40 | #define JZ_REG_INTC_PENDING 0x10 |
43 | 41 | ||
44 | #define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE) | 42 | static irqreturn_t jz4740_cascade(int irq, void *data) |
45 | |||
46 | static inline unsigned long intc_irq_bit(struct irq_data *data) | ||
47 | { | 43 | { |
48 | return (unsigned long)irq_data_get_irq_chip_data(data); | 44 | uint32_t irq_reg; |
49 | } | ||
50 | 45 | ||
51 | static void intc_irq_unmask(struct irq_data *data) | 46 | irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING); |
52 | { | ||
53 | writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK); | ||
54 | } | ||
55 | 47 | ||
56 | static void intc_irq_mask(struct irq_data *data) | 48 | if (irq_reg) |
57 | { | 49 | generic_handle_irq(__fls(irq_reg) + JZ4740_IRQ_BASE); |
58 | writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK); | 50 | |
51 | return IRQ_HANDLED; | ||
59 | } | 52 | } |
60 | 53 | ||
61 | static int intc_irq_set_wake(struct irq_data *data, unsigned int on) | 54 | static void jz4740_irq_set_mask(struct irq_chip_generic *gc, uint32_t mask) |
62 | { | 55 | { |
63 | if (on) | 56 | struct irq_chip_regs *regs = &gc->chip_types->regs; |
64 | jz_intc_wakeup |= intc_irq_bit(data); | ||
65 | else | ||
66 | jz_intc_wakeup &= ~intc_irq_bit(data); | ||
67 | 57 | ||
68 | return 0; | 58 | writel(mask, gc->reg_base + regs->enable); |
59 | writel(~mask, gc->reg_base + regs->disable); | ||
69 | } | 60 | } |
70 | 61 | ||
71 | static struct irq_chip intc_irq_type = { | 62 | void jz4740_irq_suspend(struct irq_data *data) |
72 | .name = "INTC", | ||
73 | .irq_mask = intc_irq_mask, | ||
74 | .irq_mask_ack = intc_irq_mask, | ||
75 | .irq_unmask = intc_irq_unmask, | ||
76 | .irq_set_wake = intc_irq_set_wake, | ||
77 | }; | ||
78 | |||
79 | static irqreturn_t jz4740_cascade(int irq, void *data) | ||
80 | { | 63 | { |
81 | uint32_t irq_reg; | 64 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); |
82 | 65 | jz4740_irq_set_mask(gc, gc->wake_active); | |
83 | irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING); | 66 | } |
84 | |||
85 | if (irq_reg) | ||
86 | generic_handle_irq(__fls(irq_reg) + JZ4740_IRQ_BASE); | ||
87 | 67 | ||
88 | return IRQ_HANDLED; | 68 | void jz4740_irq_resume(struct irq_data *data) |
69 | { | ||
70 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); | ||
71 | jz4740_irq_set_mask(gc, gc->mask_cache); | ||
89 | } | 72 | } |
90 | 73 | ||
91 | static struct irqaction jz4740_cascade_action = { | 74 | static struct irqaction jz4740_cascade_action = { |
@@ -95,7 +78,9 @@ static struct irqaction jz4740_cascade_action = { | |||
95 | 78 | ||
96 | void __init arch_init_irq(void) | 79 | void __init arch_init_irq(void) |
97 | { | 80 | { |
98 | int i; | 81 | struct irq_chip_generic *gc; |
82 | struct irq_chip_type *ct; | ||
83 | |||
99 | mips_cpu_irq_init(); | 84 | mips_cpu_irq_init(); |
100 | 85 | ||
101 | jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14); | 86 | jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14); |
@@ -103,10 +88,22 @@ void __init arch_init_irq(void) | |||
103 | /* Mask all irqs */ | 88 | /* Mask all irqs */ |
104 | writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK); | 89 | writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK); |
105 | 90 | ||
106 | for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) { | 91 | gc = irq_alloc_generic_chip("INTC", 1, JZ4740_IRQ_BASE, jz_intc_base, |
107 | irq_set_chip_data(i, (void *)IRQ_BIT(i)); | 92 | handle_level_irq); |
108 | irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq); | 93 | |
109 | } | 94 | gc->wake_enabled = IRQ_MSK(32); |
95 | |||
96 | ct = gc->chip_types; | ||
97 | ct->regs.enable = JZ_REG_INTC_CLEAR_MASK; | ||
98 | ct->regs.disable = JZ_REG_INTC_SET_MASK; | ||
99 | ct->chip.irq_unmask = irq_gc_unmask_enable_reg; | ||
100 | ct->chip.irq_mask = irq_gc_mask_disable_reg; | ||
101 | ct->chip.irq_mask_ack = irq_gc_mask_disable_reg; | ||
102 | ct->chip.irq_set_wake = irq_gc_set_wake; | ||
103 | ct->chip.irq_suspend = jz4740_irq_suspend; | ||
104 | ct->chip.irq_resume = jz4740_irq_resume; | ||
105 | |||
106 | irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL); | ||
110 | 107 | ||
111 | setup_irq(2, &jz4740_cascade_action); | 108 | setup_irq(2, &jz4740_cascade_action); |
112 | } | 109 | } |
@@ -122,19 +119,6 @@ asmlinkage void plat_irq_dispatch(void) | |||
122 | spurious_interrupt(); | 119 | spurious_interrupt(); |
123 | } | 120 | } |
124 | 121 | ||
125 | void jz4740_intc_suspend(void) | ||
126 | { | ||
127 | jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK); | ||
128 | writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK); | ||
129 | writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK); | ||
130 | } | ||
131 | |||
132 | void jz4740_intc_resume(void) | ||
133 | { | ||
134 | writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK); | ||
135 | writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK); | ||
136 | } | ||
137 | |||
138 | #ifdef CONFIG_DEBUG_FS | 122 | #ifdef CONFIG_DEBUG_FS |
139 | 123 | ||
140 | static inline void intc_seq_reg(struct seq_file *s, const char *name, | 124 | static inline void intc_seq_reg(struct seq_file *s, const char *name, |
diff --git a/arch/mips/jz4740/irq.h b/arch/mips/jz4740/irq.h index 56b5eadd1fa2..f75e39d62885 100644 --- a/arch/mips/jz4740/irq.h +++ b/arch/mips/jz4740/irq.h | |||
@@ -15,7 +15,9 @@ | |||
15 | #ifndef __MIPS_JZ4740_IRQ_H__ | 15 | #ifndef __MIPS_JZ4740_IRQ_H__ |
16 | #define __MIPS_JZ4740_IRQ_H__ | 16 | #define __MIPS_JZ4740_IRQ_H__ |
17 | 17 | ||
18 | extern void jz4740_intc_suspend(void); | 18 | #include <linux/irq.h> |
19 | extern void jz4740_intc_resume(void); | 19 | |
20 | extern void jz4740_irq_suspend(struct irq_data *data); | ||
21 | extern void jz4740_irq_resume(struct irq_data *data); | ||
20 | 22 | ||
21 | #endif | 23 | #endif |
diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c index 902d5b50124c..6744fa723f72 100644 --- a/arch/mips/jz4740/pm.c +++ b/arch/mips/jz4740/pm.c | |||
@@ -21,11 +21,9 @@ | |||
21 | #include <asm/mach-jz4740/clock.h> | 21 | #include <asm/mach-jz4740/clock.h> |
22 | 22 | ||
23 | #include "clock.h" | 23 | #include "clock.h" |
24 | #include "irq.h" | ||
25 | 24 | ||
26 | static int jz4740_pm_enter(suspend_state_t state) | 25 | static int jz4740_pm_enter(suspend_state_t state) |
27 | { | 26 | { |
28 | jz4740_intc_suspend(); | ||
29 | jz4740_clock_suspend(); | 27 | jz4740_clock_suspend(); |
30 | 28 | ||
31 | jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP); | 29 | jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP); |
@@ -37,7 +35,6 @@ static int jz4740_pm_enter(suspend_state_t state) | |||
37 | jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE); | 35 | jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE); |
38 | 36 | ||
39 | jz4740_clock_resume(); | 37 | jz4740_clock_resume(); |
40 | jz4740_intc_resume(); | ||
41 | 38 | ||
42 | return 0; | 39 | return 0; |
43 | } | 40 | } |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 83bba332bbfc..1a966183e353 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -11,6 +11,8 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ | |||
11 | ifdef CONFIG_FUNCTION_TRACER | 11 | ifdef CONFIG_FUNCTION_TRACER |
12 | CFLAGS_REMOVE_ftrace.o = -pg | 12 | CFLAGS_REMOVE_ftrace.o = -pg |
13 | CFLAGS_REMOVE_early_printk.o = -pg | 13 | CFLAGS_REMOVE_early_printk.o = -pg |
14 | CFLAGS_REMOVE_perf_event.o = -pg | ||
15 | CFLAGS_REMOVE_perf_event_mipsxx.o = -pg | ||
14 | endif | 16 | endif |
15 | 17 | ||
16 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o | 18 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o |
@@ -106,7 +108,8 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o | |||
106 | 108 | ||
107 | obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ | 109 | obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ |
108 | 110 | ||
109 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o | 111 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o |
112 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o | ||
110 | 113 | ||
111 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o | 114 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o |
112 | 115 | ||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index ebc0cd20b35d..aa327a755982 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -978,7 +978,10 @@ static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu) | |||
978 | platform: | 978 | platform: |
979 | set_elf_platform(cpu, "octeon"); | 979 | set_elf_platform(cpu, "octeon"); |
980 | break; | 980 | break; |
981 | case PRID_IMP_CAVIUM_CN61XX: | ||
981 | case PRID_IMP_CAVIUM_CN63XX: | 982 | case PRID_IMP_CAVIUM_CN63XX: |
983 | case PRID_IMP_CAVIUM_CN66XX: | ||
984 | case PRID_IMP_CAVIUM_CN68XX: | ||
982 | c->cputype = CPU_CAVIUM_OCTEON2; | 985 | c->cputype = CPU_CAVIUM_OCTEON2; |
983 | __cpu_name[cpu] = "Cavium Octeon II"; | 986 | __cpu_name[cpu] = "Cavium Octeon II"; |
984 | set_elf_platform(cpu, "octeon2"); | 987 | set_elf_platform(cpu, "octeon2"); |
diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c index 0aee944ac380..c1cf9c6c3f77 100644 --- a/arch/mips/kernel/perf_event.c +++ b/arch/mips/kernel/perf_event.c | |||
@@ -14,533 +14,16 @@ | |||
14 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/cpumask.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/smp.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/perf_event.h> | 17 | #include <linux/perf_event.h> |
22 | #include <linux/uaccess.h> | ||
23 | 18 | ||
24 | #include <asm/irq.h> | ||
25 | #include <asm/irq_regs.h> | ||
26 | #include <asm/stacktrace.h> | 19 | #include <asm/stacktrace.h> |
27 | #include <asm/time.h> /* For perf_irq */ | ||
28 | |||
29 | /* These are for 32bit counters. For 64bit ones, define them accordingly. */ | ||
30 | #define MAX_PERIOD ((1ULL << 32) - 1) | ||
31 | #define VALID_COUNT 0x7fffffff | ||
32 | #define TOTAL_BITS 32 | ||
33 | #define HIGHEST_BIT 31 | ||
34 | |||
35 | #define MIPS_MAX_HWEVENTS 4 | ||
36 | |||
37 | struct cpu_hw_events { | ||
38 | /* Array of events on this cpu. */ | ||
39 | struct perf_event *events[MIPS_MAX_HWEVENTS]; | ||
40 | |||
41 | /* | ||
42 | * Set the bit (indexed by the counter number) when the counter | ||
43 | * is used for an event. | ||
44 | */ | ||
45 | unsigned long used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)]; | ||
46 | |||
47 | /* | ||
48 | * The borrowed MSB for the performance counter. A MIPS performance | ||
49 | * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit | ||
50 | * counters) as a factor of determining whether a counter overflow | ||
51 | * should be signaled. So here we use a separate MSB for each | ||
52 | * counter to make things easy. | ||
53 | */ | ||
54 | unsigned long msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)]; | ||
55 | |||
56 | /* | ||
57 | * Software copy of the control register for each performance counter. | ||
58 | * MIPS CPUs vary in performance counters. They use this differently, | ||
59 | * and even may not use it. | ||
60 | */ | ||
61 | unsigned int saved_ctrl[MIPS_MAX_HWEVENTS]; | ||
62 | }; | ||
63 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { | ||
64 | .saved_ctrl = {0}, | ||
65 | }; | ||
66 | |||
67 | /* The description of MIPS performance events. */ | ||
68 | struct mips_perf_event { | ||
69 | unsigned int event_id; | ||
70 | /* | ||
71 | * MIPS performance counters are indexed starting from 0. | ||
72 | * CNTR_EVEN indicates the indexes of the counters to be used are | ||
73 | * even numbers. | ||
74 | */ | ||
75 | unsigned int cntr_mask; | ||
76 | #define CNTR_EVEN 0x55555555 | ||
77 | #define CNTR_ODD 0xaaaaaaaa | ||
78 | #ifdef CONFIG_MIPS_MT_SMP | ||
79 | enum { | ||
80 | T = 0, | ||
81 | V = 1, | ||
82 | P = 2, | ||
83 | } range; | ||
84 | #else | ||
85 | #define T | ||
86 | #define V | ||
87 | #define P | ||
88 | #endif | ||
89 | }; | ||
90 | |||
91 | static struct mips_perf_event raw_event; | ||
92 | static DEFINE_MUTEX(raw_event_mutex); | ||
93 | |||
94 | #define UNSUPPORTED_PERF_EVENT_ID 0xffffffff | ||
95 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
96 | |||
97 | struct mips_pmu { | ||
98 | const char *name; | ||
99 | int irq; | ||
100 | irqreturn_t (*handle_irq)(int irq, void *dev); | ||
101 | int (*handle_shared_irq)(void); | ||
102 | void (*start)(void); | ||
103 | void (*stop)(void); | ||
104 | int (*alloc_counter)(struct cpu_hw_events *cpuc, | ||
105 | struct hw_perf_event *hwc); | ||
106 | u64 (*read_counter)(unsigned int idx); | ||
107 | void (*write_counter)(unsigned int idx, u64 val); | ||
108 | void (*enable_event)(struct hw_perf_event *evt, int idx); | ||
109 | void (*disable_event)(int idx); | ||
110 | const struct mips_perf_event *(*map_raw_event)(u64 config); | ||
111 | const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX]; | ||
112 | const struct mips_perf_event (*cache_event_map) | ||
113 | [PERF_COUNT_HW_CACHE_MAX] | ||
114 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
115 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | ||
116 | unsigned int num_counters; | ||
117 | }; | ||
118 | |||
119 | static const struct mips_pmu *mipspmu; | ||
120 | |||
121 | static int | ||
122 | mipspmu_event_set_period(struct perf_event *event, | ||
123 | struct hw_perf_event *hwc, | ||
124 | int idx) | ||
125 | { | ||
126 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
127 | s64 left = local64_read(&hwc->period_left); | ||
128 | s64 period = hwc->sample_period; | ||
129 | int ret = 0; | ||
130 | u64 uleft; | ||
131 | unsigned long flags; | ||
132 | |||
133 | if (unlikely(left <= -period)) { | ||
134 | left = period; | ||
135 | local64_set(&hwc->period_left, left); | ||
136 | hwc->last_period = period; | ||
137 | ret = 1; | ||
138 | } | ||
139 | |||
140 | if (unlikely(left <= 0)) { | ||
141 | left += period; | ||
142 | local64_set(&hwc->period_left, left); | ||
143 | hwc->last_period = period; | ||
144 | ret = 1; | ||
145 | } | ||
146 | |||
147 | if (left > (s64)MAX_PERIOD) | ||
148 | left = MAX_PERIOD; | ||
149 | |||
150 | local64_set(&hwc->prev_count, (u64)-left); | ||
151 | |||
152 | local_irq_save(flags); | ||
153 | uleft = (u64)(-left) & MAX_PERIOD; | ||
154 | uleft > VALID_COUNT ? | ||
155 | set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs); | ||
156 | mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT); | ||
157 | local_irq_restore(flags); | ||
158 | |||
159 | perf_event_update_userpage(event); | ||
160 | |||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | static void mipspmu_event_update(struct perf_event *event, | ||
165 | struct hw_perf_event *hwc, | ||
166 | int idx) | ||
167 | { | ||
168 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
169 | unsigned long flags; | ||
170 | int shift = 64 - TOTAL_BITS; | ||
171 | s64 prev_raw_count, new_raw_count; | ||
172 | u64 delta; | ||
173 | |||
174 | again: | ||
175 | prev_raw_count = local64_read(&hwc->prev_count); | ||
176 | local_irq_save(flags); | ||
177 | /* Make the counter value be a "real" one. */ | ||
178 | new_raw_count = mipspmu->read_counter(idx); | ||
179 | if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) { | ||
180 | new_raw_count &= VALID_COUNT; | ||
181 | clear_bit(idx, cpuc->msbs); | ||
182 | } else | ||
183 | new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT); | ||
184 | local_irq_restore(flags); | ||
185 | |||
186 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, | ||
187 | new_raw_count) != prev_raw_count) | ||
188 | goto again; | ||
189 | |||
190 | delta = (new_raw_count << shift) - (prev_raw_count << shift); | ||
191 | delta >>= shift; | ||
192 | |||
193 | local64_add(delta, &event->count); | ||
194 | local64_sub(delta, &hwc->period_left); | ||
195 | } | ||
196 | |||
197 | static void mipspmu_start(struct perf_event *event, int flags) | ||
198 | { | ||
199 | struct hw_perf_event *hwc = &event->hw; | ||
200 | |||
201 | if (!mipspmu) | ||
202 | return; | ||
203 | |||
204 | if (flags & PERF_EF_RELOAD) | ||
205 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); | ||
206 | |||
207 | hwc->state = 0; | ||
208 | |||
209 | /* Set the period for the event. */ | ||
210 | mipspmu_event_set_period(event, hwc, hwc->idx); | ||
211 | |||
212 | /* Enable the event. */ | ||
213 | mipspmu->enable_event(hwc, hwc->idx); | ||
214 | } | ||
215 | |||
216 | static void mipspmu_stop(struct perf_event *event, int flags) | ||
217 | { | ||
218 | struct hw_perf_event *hwc = &event->hw; | ||
219 | |||
220 | if (!mipspmu) | ||
221 | return; | ||
222 | |||
223 | if (!(hwc->state & PERF_HES_STOPPED)) { | ||
224 | /* We are working on a local event. */ | ||
225 | mipspmu->disable_event(hwc->idx); | ||
226 | barrier(); | ||
227 | mipspmu_event_update(event, hwc, hwc->idx); | ||
228 | hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static int mipspmu_add(struct perf_event *event, int flags) | ||
233 | { | ||
234 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
235 | struct hw_perf_event *hwc = &event->hw; | ||
236 | int idx; | ||
237 | int err = 0; | ||
238 | |||
239 | perf_pmu_disable(event->pmu); | ||
240 | |||
241 | /* To look for a free counter for this event. */ | ||
242 | idx = mipspmu->alloc_counter(cpuc, hwc); | ||
243 | if (idx < 0) { | ||
244 | err = idx; | ||
245 | goto out; | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * If there is an event in the counter we are going to use then | ||
250 | * make sure it is disabled. | ||
251 | */ | ||
252 | event->hw.idx = idx; | ||
253 | mipspmu->disable_event(idx); | ||
254 | cpuc->events[idx] = event; | ||
255 | |||
256 | hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
257 | if (flags & PERF_EF_START) | ||
258 | mipspmu_start(event, PERF_EF_RELOAD); | ||
259 | |||
260 | /* Propagate our changes to the userspace mapping. */ | ||
261 | perf_event_update_userpage(event); | ||
262 | |||
263 | out: | ||
264 | perf_pmu_enable(event->pmu); | ||
265 | return err; | ||
266 | } | ||
267 | |||
268 | static void mipspmu_del(struct perf_event *event, int flags) | ||
269 | { | ||
270 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
271 | struct hw_perf_event *hwc = &event->hw; | ||
272 | int idx = hwc->idx; | ||
273 | |||
274 | WARN_ON(idx < 0 || idx >= mipspmu->num_counters); | ||
275 | |||
276 | mipspmu_stop(event, PERF_EF_UPDATE); | ||
277 | cpuc->events[idx] = NULL; | ||
278 | clear_bit(idx, cpuc->used_mask); | ||
279 | |||
280 | perf_event_update_userpage(event); | ||
281 | } | ||
282 | |||
283 | static void mipspmu_read(struct perf_event *event) | ||
284 | { | ||
285 | struct hw_perf_event *hwc = &event->hw; | ||
286 | |||
287 | /* Don't read disabled counters! */ | ||
288 | if (hwc->idx < 0) | ||
289 | return; | ||
290 | |||
291 | mipspmu_event_update(event, hwc, hwc->idx); | ||
292 | } | ||
293 | |||
294 | static void mipspmu_enable(struct pmu *pmu) | ||
295 | { | ||
296 | if (mipspmu) | ||
297 | mipspmu->start(); | ||
298 | } | ||
299 | |||
300 | static void mipspmu_disable(struct pmu *pmu) | ||
301 | { | ||
302 | if (mipspmu) | ||
303 | mipspmu->stop(); | ||
304 | } | ||
305 | |||
306 | static atomic_t active_events = ATOMIC_INIT(0); | ||
307 | static DEFINE_MUTEX(pmu_reserve_mutex); | ||
308 | static int (*save_perf_irq)(void); | ||
309 | |||
310 | static int mipspmu_get_irq(void) | ||
311 | { | ||
312 | int err; | ||
313 | |||
314 | if (mipspmu->irq >= 0) { | ||
315 | /* Request my own irq handler. */ | ||
316 | err = request_irq(mipspmu->irq, mipspmu->handle_irq, | ||
317 | IRQF_DISABLED | IRQF_NOBALANCING, | ||
318 | "mips_perf_pmu", NULL); | ||
319 | if (err) { | ||
320 | pr_warning("Unable to request IRQ%d for MIPS " | ||
321 | "performance counters!\n", mipspmu->irq); | ||
322 | } | ||
323 | } else if (cp0_perfcount_irq < 0) { | ||
324 | /* | ||
325 | * We are sharing the irq number with the timer interrupt. | ||
326 | */ | ||
327 | save_perf_irq = perf_irq; | ||
328 | perf_irq = mipspmu->handle_shared_irq; | ||
329 | err = 0; | ||
330 | } else { | ||
331 | pr_warning("The platform hasn't properly defined its " | ||
332 | "interrupt controller.\n"); | ||
333 | err = -ENOENT; | ||
334 | } | ||
335 | |||
336 | return err; | ||
337 | } | ||
338 | |||
339 | static void mipspmu_free_irq(void) | ||
340 | { | ||
341 | if (mipspmu->irq >= 0) | ||
342 | free_irq(mipspmu->irq, NULL); | ||
343 | else if (cp0_perfcount_irq < 0) | ||
344 | perf_irq = save_perf_irq; | ||
345 | } | ||
346 | |||
347 | /* | ||
348 | * mipsxx/rm9000/loongson2 have different performance counters, they have | ||
349 | * specific low-level init routines. | ||
350 | */ | ||
351 | static void reset_counters(void *arg); | ||
352 | static int __hw_perf_event_init(struct perf_event *event); | ||
353 | |||
354 | static void hw_perf_event_destroy(struct perf_event *event) | ||
355 | { | ||
356 | if (atomic_dec_and_mutex_lock(&active_events, | ||
357 | &pmu_reserve_mutex)) { | ||
358 | /* | ||
359 | * We must not call the destroy function with interrupts | ||
360 | * disabled. | ||
361 | */ | ||
362 | on_each_cpu(reset_counters, | ||
363 | (void *)(long)mipspmu->num_counters, 1); | ||
364 | mipspmu_free_irq(); | ||
365 | mutex_unlock(&pmu_reserve_mutex); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | static int mipspmu_event_init(struct perf_event *event) | ||
370 | { | ||
371 | int err = 0; | ||
372 | |||
373 | switch (event->attr.type) { | ||
374 | case PERF_TYPE_RAW: | ||
375 | case PERF_TYPE_HARDWARE: | ||
376 | case PERF_TYPE_HW_CACHE: | ||
377 | break; | ||
378 | |||
379 | default: | ||
380 | return -ENOENT; | ||
381 | } | ||
382 | |||
383 | if (!mipspmu || event->cpu >= nr_cpumask_bits || | ||
384 | (event->cpu >= 0 && !cpu_online(event->cpu))) | ||
385 | return -ENODEV; | ||
386 | |||
387 | if (!atomic_inc_not_zero(&active_events)) { | ||
388 | if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { | ||
389 | atomic_dec(&active_events); | ||
390 | return -ENOSPC; | ||
391 | } | ||
392 | |||
393 | mutex_lock(&pmu_reserve_mutex); | ||
394 | if (atomic_read(&active_events) == 0) | ||
395 | err = mipspmu_get_irq(); | ||
396 | |||
397 | if (!err) | ||
398 | atomic_inc(&active_events); | ||
399 | mutex_unlock(&pmu_reserve_mutex); | ||
400 | } | ||
401 | |||
402 | if (err) | ||
403 | return err; | ||
404 | |||
405 | err = __hw_perf_event_init(event); | ||
406 | if (err) | ||
407 | hw_perf_event_destroy(event); | ||
408 | |||
409 | return err; | ||
410 | } | ||
411 | |||
412 | static struct pmu pmu = { | ||
413 | .pmu_enable = mipspmu_enable, | ||
414 | .pmu_disable = mipspmu_disable, | ||
415 | .event_init = mipspmu_event_init, | ||
416 | .add = mipspmu_add, | ||
417 | .del = mipspmu_del, | ||
418 | .start = mipspmu_start, | ||
419 | .stop = mipspmu_stop, | ||
420 | .read = mipspmu_read, | ||
421 | }; | ||
422 | |||
423 | static inline unsigned int | ||
424 | mipspmu_perf_event_encode(const struct mips_perf_event *pev) | ||
425 | { | ||
426 | /* | ||
427 | * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for | ||
428 | * event_id. | ||
429 | */ | ||
430 | #ifdef CONFIG_MIPS_MT_SMP | ||
431 | return ((unsigned int)pev->range << 24) | | ||
432 | (pev->cntr_mask & 0xffff00) | | ||
433 | (pev->event_id & 0xff); | ||
434 | #else | ||
435 | return (pev->cntr_mask & 0xffff00) | | ||
436 | (pev->event_id & 0xff); | ||
437 | #endif | ||
438 | } | ||
439 | |||
440 | static const struct mips_perf_event * | ||
441 | mipspmu_map_general_event(int idx) | ||
442 | { | ||
443 | const struct mips_perf_event *pev; | ||
444 | |||
445 | pev = ((*mipspmu->general_event_map)[idx].event_id == | ||
446 | UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) : | ||
447 | &(*mipspmu->general_event_map)[idx]); | ||
448 | |||
449 | return pev; | ||
450 | } | ||
451 | |||
452 | static const struct mips_perf_event * | ||
453 | mipspmu_map_cache_event(u64 config) | ||
454 | { | ||
455 | unsigned int cache_type, cache_op, cache_result; | ||
456 | const struct mips_perf_event *pev; | ||
457 | |||
458 | cache_type = (config >> 0) & 0xff; | ||
459 | if (cache_type >= PERF_COUNT_HW_CACHE_MAX) | ||
460 | return ERR_PTR(-EINVAL); | ||
461 | |||
462 | cache_op = (config >> 8) & 0xff; | ||
463 | if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) | ||
464 | return ERR_PTR(-EINVAL); | ||
465 | |||
466 | cache_result = (config >> 16) & 0xff; | ||
467 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) | ||
468 | return ERR_PTR(-EINVAL); | ||
469 | |||
470 | pev = &((*mipspmu->cache_event_map) | ||
471 | [cache_type] | ||
472 | [cache_op] | ||
473 | [cache_result]); | ||
474 | |||
475 | if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID) | ||
476 | return ERR_PTR(-EOPNOTSUPP); | ||
477 | |||
478 | return pev; | ||
479 | |||
480 | } | ||
481 | |||
482 | static int validate_event(struct cpu_hw_events *cpuc, | ||
483 | struct perf_event *event) | ||
484 | { | ||
485 | struct hw_perf_event fake_hwc = event->hw; | ||
486 | |||
487 | /* Allow mixed event group. So return 1 to pass validation. */ | ||
488 | if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) | ||
489 | return 1; | ||
490 | |||
491 | return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0; | ||
492 | } | ||
493 | |||
494 | static int validate_group(struct perf_event *event) | ||
495 | { | ||
496 | struct perf_event *sibling, *leader = event->group_leader; | ||
497 | struct cpu_hw_events fake_cpuc; | ||
498 | |||
499 | memset(&fake_cpuc, 0, sizeof(fake_cpuc)); | ||
500 | |||
501 | if (!validate_event(&fake_cpuc, leader)) | ||
502 | return -ENOSPC; | ||
503 | |||
504 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { | ||
505 | if (!validate_event(&fake_cpuc, sibling)) | ||
506 | return -ENOSPC; | ||
507 | } | ||
508 | |||
509 | if (!validate_event(&fake_cpuc, event)) | ||
510 | return -ENOSPC; | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | /* This is needed by specific irq handlers in perf_event_*.c */ | ||
516 | static void | ||
517 | handle_associated_event(struct cpu_hw_events *cpuc, | ||
518 | int idx, struct perf_sample_data *data, struct pt_regs *regs) | ||
519 | { | ||
520 | struct perf_event *event = cpuc->events[idx]; | ||
521 | struct hw_perf_event *hwc = &event->hw; | ||
522 | |||
523 | mipspmu_event_update(event, hwc, idx); | ||
524 | data->period = event->hw.last_period; | ||
525 | if (!mipspmu_event_set_period(event, hwc, idx)) | ||
526 | return; | ||
527 | |||
528 | if (perf_event_overflow(event, data, regs)) | ||
529 | mipspmu->disable_event(idx); | ||
530 | } | ||
531 | |||
532 | #include "perf_event_mipsxx.c" | ||
533 | 20 | ||
534 | /* Callchain handling code. */ | 21 | /* Callchain handling code. */ |
535 | 22 | ||
536 | /* | 23 | /* |
537 | * Leave userspace callchain empty for now. When we find a way to trace | 24 | * Leave userspace callchain empty for now. When we find a way to trace |
538 | * the user stack callchains, we add here. | 25 | * the user stack callchains, we will add it here. |
539 | */ | 26 | */ |
540 | void perf_callchain_user(struct perf_callchain_entry *entry, | ||
541 | struct pt_regs *regs) | ||
542 | { | ||
543 | } | ||
544 | 27 | ||
545 | static void save_raw_perf_callchain(struct perf_callchain_entry *entry, | 28 | static void save_raw_perf_callchain(struct perf_callchain_entry *entry, |
546 | unsigned long reg29) | 29 | unsigned long reg29) |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index e5ad09a9baf7..4f2971bcf8e5 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -1,13 +1,112 @@ | |||
1 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) || \ | 1 | /* |
2 | defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_SB1) | 2 | * Linux performance counter support for MIPS. |
3 | * | ||
4 | * Copyright (C) 2010 MIPS Technologies, Inc. | ||
5 | * Copyright (C) 2011 Cavium Networks, Inc. | ||
6 | * Author: Deng-Cheng Zhu | ||
7 | * | ||
8 | * This code is based on the implementation for ARM, which is in turn | ||
9 | * based on the sparc64 perf event code and the x86 code. Performance | ||
10 | * counter access is based on the MIPS Oprofile code. And the callchain | ||
11 | * support references the code of MIPS stacktrace.c. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/cpumask.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/smp.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/perf_event.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | |||
25 | #include <asm/irq.h> | ||
26 | #include <asm/irq_regs.h> | ||
27 | #include <asm/stacktrace.h> | ||
28 | #include <asm/time.h> /* For perf_irq */ | ||
29 | |||
30 | #define MIPS_MAX_HWEVENTS 4 | ||
31 | |||
32 | struct cpu_hw_events { | ||
33 | /* Array of events on this cpu. */ | ||
34 | struct perf_event *events[MIPS_MAX_HWEVENTS]; | ||
35 | |||
36 | /* | ||
37 | * Set the bit (indexed by the counter number) when the counter | ||
38 | * is used for an event. | ||
39 | */ | ||
40 | unsigned long used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)]; | ||
41 | |||
42 | /* | ||
43 | * Software copy of the control register for each performance counter. | ||
44 | * MIPS CPUs vary in performance counters. They use this differently, | ||
45 | * and even may not use it. | ||
46 | */ | ||
47 | unsigned int saved_ctrl[MIPS_MAX_HWEVENTS]; | ||
48 | }; | ||
49 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { | ||
50 | .saved_ctrl = {0}, | ||
51 | }; | ||
52 | |||
53 | /* The description of MIPS performance events. */ | ||
54 | struct mips_perf_event { | ||
55 | unsigned int event_id; | ||
56 | /* | ||
57 | * MIPS performance counters are indexed starting from 0. | ||
58 | * CNTR_EVEN indicates the indexes of the counters to be used are | ||
59 | * even numbers. | ||
60 | */ | ||
61 | unsigned int cntr_mask; | ||
62 | #define CNTR_EVEN 0x55555555 | ||
63 | #define CNTR_ODD 0xaaaaaaaa | ||
64 | #define CNTR_ALL 0xffffffff | ||
65 | #ifdef CONFIG_MIPS_MT_SMP | ||
66 | enum { | ||
67 | T = 0, | ||
68 | V = 1, | ||
69 | P = 2, | ||
70 | } range; | ||
71 | #else | ||
72 | #define T | ||
73 | #define V | ||
74 | #define P | ||
75 | #endif | ||
76 | }; | ||
77 | |||
78 | static struct mips_perf_event raw_event; | ||
79 | static DEFINE_MUTEX(raw_event_mutex); | ||
80 | |||
81 | #define UNSUPPORTED_PERF_EVENT_ID 0xffffffff | ||
82 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
83 | |||
84 | struct mips_pmu { | ||
85 | u64 max_period; | ||
86 | u64 valid_count; | ||
87 | u64 overflow; | ||
88 | const char *name; | ||
89 | int irq; | ||
90 | u64 (*read_counter)(unsigned int idx); | ||
91 | void (*write_counter)(unsigned int idx, u64 val); | ||
92 | const struct mips_perf_event *(*map_raw_event)(u64 config); | ||
93 | const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX]; | ||
94 | const struct mips_perf_event (*cache_event_map) | ||
95 | [PERF_COUNT_HW_CACHE_MAX] | ||
96 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
97 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | ||
98 | unsigned int num_counters; | ||
99 | }; | ||
100 | |||
101 | static struct mips_pmu mipspmu; | ||
3 | 102 | ||
4 | #define M_CONFIG1_PC (1 << 4) | 103 | #define M_CONFIG1_PC (1 << 4) |
5 | 104 | ||
6 | #define M_PERFCTL_EXL (1UL << 0) | 105 | #define M_PERFCTL_EXL (1 << 0) |
7 | #define M_PERFCTL_KERNEL (1UL << 1) | 106 | #define M_PERFCTL_KERNEL (1 << 1) |
8 | #define M_PERFCTL_SUPERVISOR (1UL << 2) | 107 | #define M_PERFCTL_SUPERVISOR (1 << 2) |
9 | #define M_PERFCTL_USER (1UL << 3) | 108 | #define M_PERFCTL_USER (1 << 3) |
10 | #define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) | 109 | #define M_PERFCTL_INTERRUPT_ENABLE (1 << 4) |
11 | #define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) | 110 | #define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) |
12 | #define M_PERFCTL_VPEID(vpe) ((vpe) << 16) | 111 | #define M_PERFCTL_VPEID(vpe) ((vpe) << 16) |
13 | #define M_PERFCTL_MT_EN(filter) ((filter) << 20) | 112 | #define M_PERFCTL_MT_EN(filter) ((filter) << 20) |
@@ -15,8 +114,8 @@ | |||
15 | #define M_TC_EN_VPE M_PERFCTL_MT_EN(1) | 114 | #define M_TC_EN_VPE M_PERFCTL_MT_EN(1) |
16 | #define M_TC_EN_TC M_PERFCTL_MT_EN(2) | 115 | #define M_TC_EN_TC M_PERFCTL_MT_EN(2) |
17 | #define M_PERFCTL_TCID(tcid) ((tcid) << 22) | 116 | #define M_PERFCTL_TCID(tcid) ((tcid) << 22) |
18 | #define M_PERFCTL_WIDE (1UL << 30) | 117 | #define M_PERFCTL_WIDE (1 << 30) |
19 | #define M_PERFCTL_MORE (1UL << 31) | 118 | #define M_PERFCTL_MORE (1 << 31) |
20 | 119 | ||
21 | #define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \ | 120 | #define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \ |
22 | M_PERFCTL_KERNEL | \ | 121 | M_PERFCTL_KERNEL | \ |
@@ -31,11 +130,12 @@ | |||
31 | #endif | 130 | #endif |
32 | #define M_PERFCTL_EVENT_MASK 0xfe0 | 131 | #define M_PERFCTL_EVENT_MASK 0xfe0 |
33 | 132 | ||
34 | #define M_COUNTER_OVERFLOW (1UL << 31) | ||
35 | 133 | ||
36 | #ifdef CONFIG_MIPS_MT_SMP | 134 | #ifdef CONFIG_MIPS_MT_SMP |
37 | static int cpu_has_mipsmt_pertccounters; | 135 | static int cpu_has_mipsmt_pertccounters; |
38 | 136 | ||
137 | static DEFINE_RWLOCK(pmuint_rwlock); | ||
138 | |||
39 | /* | 139 | /* |
40 | * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because | 140 | * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because |
41 | * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs. | 141 | * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs. |
@@ -49,209 +149,673 @@ static int cpu_has_mipsmt_pertccounters; | |||
49 | #endif | 149 | #endif |
50 | 150 | ||
51 | /* Copied from op_model_mipsxx.c */ | 151 | /* Copied from op_model_mipsxx.c */ |
52 | static inline unsigned int vpe_shift(void) | 152 | static unsigned int vpe_shift(void) |
53 | { | 153 | { |
54 | if (num_possible_cpus() > 1) | 154 | if (num_possible_cpus() > 1) |
55 | return 1; | 155 | return 1; |
56 | 156 | ||
57 | return 0; | 157 | return 0; |
58 | } | 158 | } |
59 | #else /* !CONFIG_MIPS_MT_SMP */ | ||
60 | #define vpe_id() 0 | ||
61 | 159 | ||
62 | static inline unsigned int vpe_shift(void) | 160 | static unsigned int counters_total_to_per_cpu(unsigned int counters) |
63 | { | ||
64 | return 0; | ||
65 | } | ||
66 | #endif /* CONFIG_MIPS_MT_SMP */ | ||
67 | |||
68 | static inline unsigned int | ||
69 | counters_total_to_per_cpu(unsigned int counters) | ||
70 | { | 161 | { |
71 | return counters >> vpe_shift(); | 162 | return counters >> vpe_shift(); |
72 | } | 163 | } |
73 | 164 | ||
74 | static inline unsigned int | 165 | static unsigned int counters_per_cpu_to_total(unsigned int counters) |
75 | counters_per_cpu_to_total(unsigned int counters) | ||
76 | { | 166 | { |
77 | return counters << vpe_shift(); | 167 | return counters << vpe_shift(); |
78 | } | 168 | } |
79 | 169 | ||
80 | #define __define_perf_accessors(r, n, np) \ | 170 | #else /* !CONFIG_MIPS_MT_SMP */ |
81 | \ | 171 | #define vpe_id() 0 |
82 | static inline unsigned int r_c0_ ## r ## n(void) \ | ||
83 | { \ | ||
84 | unsigned int cpu = vpe_id(); \ | ||
85 | \ | ||
86 | switch (cpu) { \ | ||
87 | case 0: \ | ||
88 | return read_c0_ ## r ## n(); \ | ||
89 | case 1: \ | ||
90 | return read_c0_ ## r ## np(); \ | ||
91 | default: \ | ||
92 | BUG(); \ | ||
93 | } \ | ||
94 | return 0; \ | ||
95 | } \ | ||
96 | \ | ||
97 | static inline void w_c0_ ## r ## n(unsigned int value) \ | ||
98 | { \ | ||
99 | unsigned int cpu = vpe_id(); \ | ||
100 | \ | ||
101 | switch (cpu) { \ | ||
102 | case 0: \ | ||
103 | write_c0_ ## r ## n(value); \ | ||
104 | return; \ | ||
105 | case 1: \ | ||
106 | write_c0_ ## r ## np(value); \ | ||
107 | return; \ | ||
108 | default: \ | ||
109 | BUG(); \ | ||
110 | } \ | ||
111 | return; \ | ||
112 | } \ | ||
113 | |||
114 | __define_perf_accessors(perfcntr, 0, 2) | ||
115 | __define_perf_accessors(perfcntr, 1, 3) | ||
116 | __define_perf_accessors(perfcntr, 2, 0) | ||
117 | __define_perf_accessors(perfcntr, 3, 1) | ||
118 | |||
119 | __define_perf_accessors(perfctrl, 0, 2) | ||
120 | __define_perf_accessors(perfctrl, 1, 3) | ||
121 | __define_perf_accessors(perfctrl, 2, 0) | ||
122 | __define_perf_accessors(perfctrl, 3, 1) | ||
123 | |||
124 | static inline int __n_counters(void) | ||
125 | { | ||
126 | if (!(read_c0_config1() & M_CONFIG1_PC)) | ||
127 | return 0; | ||
128 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) | ||
129 | return 1; | ||
130 | if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) | ||
131 | return 2; | ||
132 | if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) | ||
133 | return 3; | ||
134 | 172 | ||
135 | return 4; | 173 | #endif /* CONFIG_MIPS_MT_SMP */ |
136 | } | ||
137 | 174 | ||
138 | static inline int n_counters(void) | 175 | static void resume_local_counters(void); |
139 | { | 176 | static void pause_local_counters(void); |
140 | int counters; | 177 | static irqreturn_t mipsxx_pmu_handle_irq(int, void *); |
178 | static int mipsxx_pmu_handle_shared_irq(void); | ||
141 | 179 | ||
142 | switch (current_cpu_type()) { | 180 | static unsigned int mipsxx_pmu_swizzle_perf_idx(unsigned int idx) |
143 | case CPU_R10000: | 181 | { |
144 | counters = 2; | 182 | if (vpe_id() == 1) |
145 | break; | 183 | idx = (idx + 2) & 3; |
184 | return idx; | ||
185 | } | ||
146 | 186 | ||
147 | case CPU_R12000: | 187 | static u64 mipsxx_pmu_read_counter(unsigned int idx) |
148 | case CPU_R14000: | 188 | { |
149 | counters = 4; | 189 | idx = mipsxx_pmu_swizzle_perf_idx(idx); |
150 | break; | ||
151 | 190 | ||
191 | switch (idx) { | ||
192 | case 0: | ||
193 | /* | ||
194 | * The counters are unsigned, we must cast to truncate | ||
195 | * off the high bits. | ||
196 | */ | ||
197 | return (u32)read_c0_perfcntr0(); | ||
198 | case 1: | ||
199 | return (u32)read_c0_perfcntr1(); | ||
200 | case 2: | ||
201 | return (u32)read_c0_perfcntr2(); | ||
202 | case 3: | ||
203 | return (u32)read_c0_perfcntr3(); | ||
152 | default: | 204 | default: |
153 | counters = __n_counters(); | 205 | WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); |
206 | return 0; | ||
154 | } | 207 | } |
155 | |||
156 | return counters; | ||
157 | } | 208 | } |
158 | 209 | ||
159 | static void reset_counters(void *arg) | 210 | static u64 mipsxx_pmu_read_counter_64(unsigned int idx) |
160 | { | 211 | { |
161 | int counters = (int)(long)arg; | 212 | idx = mipsxx_pmu_swizzle_perf_idx(idx); |
162 | switch (counters) { | 213 | |
163 | case 4: | 214 | switch (idx) { |
164 | w_c0_perfctrl3(0); | 215 | case 0: |
165 | w_c0_perfcntr3(0); | 216 | return read_c0_perfcntr0_64(); |
166 | case 3: | ||
167 | w_c0_perfctrl2(0); | ||
168 | w_c0_perfcntr2(0); | ||
169 | case 2: | ||
170 | w_c0_perfctrl1(0); | ||
171 | w_c0_perfcntr1(0); | ||
172 | case 1: | 217 | case 1: |
173 | w_c0_perfctrl0(0); | 218 | return read_c0_perfcntr1_64(); |
174 | w_c0_perfcntr0(0); | 219 | case 2: |
220 | return read_c0_perfcntr2_64(); | ||
221 | case 3: | ||
222 | return read_c0_perfcntr3_64(); | ||
223 | default: | ||
224 | WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); | ||
225 | return 0; | ||
175 | } | 226 | } |
176 | } | 227 | } |
177 | 228 | ||
178 | static inline u64 | 229 | static void mipsxx_pmu_write_counter(unsigned int idx, u64 val) |
179 | mipsxx_pmu_read_counter(unsigned int idx) | ||
180 | { | 230 | { |
231 | idx = mipsxx_pmu_swizzle_perf_idx(idx); | ||
232 | |||
181 | switch (idx) { | 233 | switch (idx) { |
182 | case 0: | 234 | case 0: |
183 | return r_c0_perfcntr0(); | 235 | write_c0_perfcntr0(val); |
236 | return; | ||
184 | case 1: | 237 | case 1: |
185 | return r_c0_perfcntr1(); | 238 | write_c0_perfcntr1(val); |
239 | return; | ||
186 | case 2: | 240 | case 2: |
187 | return r_c0_perfcntr2(); | 241 | write_c0_perfcntr2(val); |
242 | return; | ||
188 | case 3: | 243 | case 3: |
189 | return r_c0_perfcntr3(); | 244 | write_c0_perfcntr3(val); |
190 | default: | 245 | return; |
191 | WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); | ||
192 | return 0; | ||
193 | } | 246 | } |
194 | } | 247 | } |
195 | 248 | ||
196 | static inline void | 249 | static void mipsxx_pmu_write_counter_64(unsigned int idx, u64 val) |
197 | mipsxx_pmu_write_counter(unsigned int idx, u64 val) | ||
198 | { | 250 | { |
251 | idx = mipsxx_pmu_swizzle_perf_idx(idx); | ||
252 | |||
199 | switch (idx) { | 253 | switch (idx) { |
200 | case 0: | 254 | case 0: |
201 | w_c0_perfcntr0(val); | 255 | write_c0_perfcntr0_64(val); |
202 | return; | 256 | return; |
203 | case 1: | 257 | case 1: |
204 | w_c0_perfcntr1(val); | 258 | write_c0_perfcntr1_64(val); |
205 | return; | 259 | return; |
206 | case 2: | 260 | case 2: |
207 | w_c0_perfcntr2(val); | 261 | write_c0_perfcntr2_64(val); |
208 | return; | 262 | return; |
209 | case 3: | 263 | case 3: |
210 | w_c0_perfcntr3(val); | 264 | write_c0_perfcntr3_64(val); |
211 | return; | 265 | return; |
212 | } | 266 | } |
213 | } | 267 | } |
214 | 268 | ||
215 | static inline unsigned int | 269 | static unsigned int mipsxx_pmu_read_control(unsigned int idx) |
216 | mipsxx_pmu_read_control(unsigned int idx) | ||
217 | { | 270 | { |
271 | idx = mipsxx_pmu_swizzle_perf_idx(idx); | ||
272 | |||
218 | switch (idx) { | 273 | switch (idx) { |
219 | case 0: | 274 | case 0: |
220 | return r_c0_perfctrl0(); | 275 | return read_c0_perfctrl0(); |
221 | case 1: | 276 | case 1: |
222 | return r_c0_perfctrl1(); | 277 | return read_c0_perfctrl1(); |
223 | case 2: | 278 | case 2: |
224 | return r_c0_perfctrl2(); | 279 | return read_c0_perfctrl2(); |
225 | case 3: | 280 | case 3: |
226 | return r_c0_perfctrl3(); | 281 | return read_c0_perfctrl3(); |
227 | default: | 282 | default: |
228 | WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); | 283 | WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx); |
229 | return 0; | 284 | return 0; |
230 | } | 285 | } |
231 | } | 286 | } |
232 | 287 | ||
233 | static inline void | 288 | static void mipsxx_pmu_write_control(unsigned int idx, unsigned int val) |
234 | mipsxx_pmu_write_control(unsigned int idx, unsigned int val) | ||
235 | { | 289 | { |
290 | idx = mipsxx_pmu_swizzle_perf_idx(idx); | ||
291 | |||
236 | switch (idx) { | 292 | switch (idx) { |
237 | case 0: | 293 | case 0: |
238 | w_c0_perfctrl0(val); | 294 | write_c0_perfctrl0(val); |
239 | return; | 295 | return; |
240 | case 1: | 296 | case 1: |
241 | w_c0_perfctrl1(val); | 297 | write_c0_perfctrl1(val); |
242 | return; | 298 | return; |
243 | case 2: | 299 | case 2: |
244 | w_c0_perfctrl2(val); | 300 | write_c0_perfctrl2(val); |
245 | return; | 301 | return; |
246 | case 3: | 302 | case 3: |
247 | w_c0_perfctrl3(val); | 303 | write_c0_perfctrl3(val); |
304 | return; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | static int mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc, | ||
309 | struct hw_perf_event *hwc) | ||
310 | { | ||
311 | int i; | ||
312 | |||
313 | /* | ||
314 | * We only need to care the counter mask. The range has been | ||
315 | * checked definitely. | ||
316 | */ | ||
317 | unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff; | ||
318 | |||
319 | for (i = mipspmu.num_counters - 1; i >= 0; i--) { | ||
320 | /* | ||
321 | * Note that some MIPS perf events can be counted by both | ||
322 | * even and odd counters, wheresas many other are only by | ||
323 | * even _or_ odd counters. This introduces an issue that | ||
324 | * when the former kind of event takes the counter the | ||
325 | * latter kind of event wants to use, then the "counter | ||
326 | * allocation" for the latter event will fail. In fact if | ||
327 | * they can be dynamically swapped, they both feel happy. | ||
328 | * But here we leave this issue alone for now. | ||
329 | */ | ||
330 | if (test_bit(i, &cntr_mask) && | ||
331 | !test_and_set_bit(i, cpuc->used_mask)) | ||
332 | return i; | ||
333 | } | ||
334 | |||
335 | return -EAGAIN; | ||
336 | } | ||
337 | |||
338 | static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx) | ||
339 | { | ||
340 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
341 | |||
342 | WARN_ON(idx < 0 || idx >= mipspmu.num_counters); | ||
343 | |||
344 | cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) | | ||
345 | (evt->config_base & M_PERFCTL_CONFIG_MASK) | | ||
346 | /* Make sure interrupt enabled. */ | ||
347 | M_PERFCTL_INTERRUPT_ENABLE; | ||
348 | /* | ||
349 | * We do not actually let the counter run. Leave it until start(). | ||
350 | */ | ||
351 | } | ||
352 | |||
353 | static void mipsxx_pmu_disable_event(int idx) | ||
354 | { | ||
355 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
356 | unsigned long flags; | ||
357 | |||
358 | WARN_ON(idx < 0 || idx >= mipspmu.num_counters); | ||
359 | |||
360 | local_irq_save(flags); | ||
361 | cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) & | ||
362 | ~M_PERFCTL_COUNT_EVENT_WHENEVER; | ||
363 | mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]); | ||
364 | local_irq_restore(flags); | ||
365 | } | ||
366 | |||
367 | static int mipspmu_event_set_period(struct perf_event *event, | ||
368 | struct hw_perf_event *hwc, | ||
369 | int idx) | ||
370 | { | ||
371 | u64 left = local64_read(&hwc->period_left); | ||
372 | u64 period = hwc->sample_period; | ||
373 | int ret = 0; | ||
374 | |||
375 | if (unlikely((left + period) & (1ULL << 63))) { | ||
376 | /* left underflowed by more than period. */ | ||
377 | left = period; | ||
378 | local64_set(&hwc->period_left, left); | ||
379 | hwc->last_period = period; | ||
380 | ret = 1; | ||
381 | } else if (unlikely((left + period) <= period)) { | ||
382 | /* left underflowed by less than period. */ | ||
383 | left += period; | ||
384 | local64_set(&hwc->period_left, left); | ||
385 | hwc->last_period = period; | ||
386 | ret = 1; | ||
387 | } | ||
388 | |||
389 | if (left > mipspmu.max_period) { | ||
390 | left = mipspmu.max_period; | ||
391 | local64_set(&hwc->period_left, left); | ||
392 | } | ||
393 | |||
394 | local64_set(&hwc->prev_count, mipspmu.overflow - left); | ||
395 | |||
396 | mipspmu.write_counter(idx, mipspmu.overflow - left); | ||
397 | |||
398 | perf_event_update_userpage(event); | ||
399 | |||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | static void mipspmu_event_update(struct perf_event *event, | ||
404 | struct hw_perf_event *hwc, | ||
405 | int idx) | ||
406 | { | ||
407 | u64 prev_raw_count, new_raw_count; | ||
408 | u64 delta; | ||
409 | |||
410 | again: | ||
411 | prev_raw_count = local64_read(&hwc->prev_count); | ||
412 | new_raw_count = mipspmu.read_counter(idx); | ||
413 | |||
414 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, | ||
415 | new_raw_count) != prev_raw_count) | ||
416 | goto again; | ||
417 | |||
418 | delta = new_raw_count - prev_raw_count; | ||
419 | |||
420 | local64_add(delta, &event->count); | ||
421 | local64_sub(delta, &hwc->period_left); | ||
422 | } | ||
423 | |||
424 | static void mipspmu_start(struct perf_event *event, int flags) | ||
425 | { | ||
426 | struct hw_perf_event *hwc = &event->hw; | ||
427 | |||
428 | if (flags & PERF_EF_RELOAD) | ||
429 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); | ||
430 | |||
431 | hwc->state = 0; | ||
432 | |||
433 | /* Set the period for the event. */ | ||
434 | mipspmu_event_set_period(event, hwc, hwc->idx); | ||
435 | |||
436 | /* Enable the event. */ | ||
437 | mipsxx_pmu_enable_event(hwc, hwc->idx); | ||
438 | } | ||
439 | |||
440 | static void mipspmu_stop(struct perf_event *event, int flags) | ||
441 | { | ||
442 | struct hw_perf_event *hwc = &event->hw; | ||
443 | |||
444 | if (!(hwc->state & PERF_HES_STOPPED)) { | ||
445 | /* We are working on a local event. */ | ||
446 | mipsxx_pmu_disable_event(hwc->idx); | ||
447 | barrier(); | ||
448 | mipspmu_event_update(event, hwc, hwc->idx); | ||
449 | hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | static int mipspmu_add(struct perf_event *event, int flags) | ||
454 | { | ||
455 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
456 | struct hw_perf_event *hwc = &event->hw; | ||
457 | int idx; | ||
458 | int err = 0; | ||
459 | |||
460 | perf_pmu_disable(event->pmu); | ||
461 | |||
462 | /* To look for a free counter for this event. */ | ||
463 | idx = mipsxx_pmu_alloc_counter(cpuc, hwc); | ||
464 | if (idx < 0) { | ||
465 | err = idx; | ||
466 | goto out; | ||
467 | } | ||
468 | |||
469 | /* | ||
470 | * If there is an event in the counter we are going to use then | ||
471 | * make sure it is disabled. | ||
472 | */ | ||
473 | event->hw.idx = idx; | ||
474 | mipsxx_pmu_disable_event(idx); | ||
475 | cpuc->events[idx] = event; | ||
476 | |||
477 | hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
478 | if (flags & PERF_EF_START) | ||
479 | mipspmu_start(event, PERF_EF_RELOAD); | ||
480 | |||
481 | /* Propagate our changes to the userspace mapping. */ | ||
482 | perf_event_update_userpage(event); | ||
483 | |||
484 | out: | ||
485 | perf_pmu_enable(event->pmu); | ||
486 | return err; | ||
487 | } | ||
488 | |||
489 | static void mipspmu_del(struct perf_event *event, int flags) | ||
490 | { | ||
491 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
492 | struct hw_perf_event *hwc = &event->hw; | ||
493 | int idx = hwc->idx; | ||
494 | |||
495 | WARN_ON(idx < 0 || idx >= mipspmu.num_counters); | ||
496 | |||
497 | mipspmu_stop(event, PERF_EF_UPDATE); | ||
498 | cpuc->events[idx] = NULL; | ||
499 | clear_bit(idx, cpuc->used_mask); | ||
500 | |||
501 | perf_event_update_userpage(event); | ||
502 | } | ||
503 | |||
504 | static void mipspmu_read(struct perf_event *event) | ||
505 | { | ||
506 | struct hw_perf_event *hwc = &event->hw; | ||
507 | |||
508 | /* Don't read disabled counters! */ | ||
509 | if (hwc->idx < 0) | ||
248 | return; | 510 | return; |
511 | |||
512 | mipspmu_event_update(event, hwc, hwc->idx); | ||
513 | } | ||
514 | |||
515 | static void mipspmu_enable(struct pmu *pmu) | ||
516 | { | ||
517 | #ifdef CONFIG_MIPS_MT_SMP | ||
518 | write_unlock(&pmuint_rwlock); | ||
519 | #endif | ||
520 | resume_local_counters(); | ||
521 | } | ||
522 | |||
523 | /* | ||
524 | * MIPS performance counters can be per-TC. The control registers can | ||
525 | * not be directly accessed accross CPUs. Hence if we want to do global | ||
526 | * control, we need cross CPU calls. on_each_cpu() can help us, but we | ||
527 | * can not make sure this function is called with interrupts enabled. So | ||
528 | * here we pause local counters and then grab a rwlock and leave the | ||
529 | * counters on other CPUs alone. If any counter interrupt raises while | ||
530 | * we own the write lock, simply pause local counters on that CPU and | ||
531 | * spin in the handler. Also we know we won't be switched to another | ||
532 | * CPU after pausing local counters and before grabbing the lock. | ||
533 | */ | ||
534 | static void mipspmu_disable(struct pmu *pmu) | ||
535 | { | ||
536 | pause_local_counters(); | ||
537 | #ifdef CONFIG_MIPS_MT_SMP | ||
538 | write_lock(&pmuint_rwlock); | ||
539 | #endif | ||
540 | } | ||
541 | |||
542 | static atomic_t active_events = ATOMIC_INIT(0); | ||
543 | static DEFINE_MUTEX(pmu_reserve_mutex); | ||
544 | static int (*save_perf_irq)(void); | ||
545 | |||
546 | static int mipspmu_get_irq(void) | ||
547 | { | ||
548 | int err; | ||
549 | |||
550 | if (mipspmu.irq >= 0) { | ||
551 | /* Request my own irq handler. */ | ||
552 | err = request_irq(mipspmu.irq, mipsxx_pmu_handle_irq, | ||
553 | IRQF_PERCPU | IRQF_NOBALANCING, | ||
554 | "mips_perf_pmu", NULL); | ||
555 | if (err) { | ||
556 | pr_warning("Unable to request IRQ%d for MIPS " | ||
557 | "performance counters!\n", mipspmu.irq); | ||
558 | } | ||
559 | } else if (cp0_perfcount_irq < 0) { | ||
560 | /* | ||
561 | * We are sharing the irq number with the timer interrupt. | ||
562 | */ | ||
563 | save_perf_irq = perf_irq; | ||
564 | perf_irq = mipsxx_pmu_handle_shared_irq; | ||
565 | err = 0; | ||
566 | } else { | ||
567 | pr_warning("The platform hasn't properly defined its " | ||
568 | "interrupt controller.\n"); | ||
569 | err = -ENOENT; | ||
249 | } | 570 | } |
571 | |||
572 | return err; | ||
573 | } | ||
574 | |||
575 | static void mipspmu_free_irq(void) | ||
576 | { | ||
577 | if (mipspmu.irq >= 0) | ||
578 | free_irq(mipspmu.irq, NULL); | ||
579 | else if (cp0_perfcount_irq < 0) | ||
580 | perf_irq = save_perf_irq; | ||
250 | } | 581 | } |
251 | 582 | ||
583 | /* | ||
584 | * mipsxx/rm9000/loongson2 have different performance counters, they have | ||
585 | * specific low-level init routines. | ||
586 | */ | ||
587 | static void reset_counters(void *arg); | ||
588 | static int __hw_perf_event_init(struct perf_event *event); | ||
589 | |||
590 | static void hw_perf_event_destroy(struct perf_event *event) | ||
591 | { | ||
592 | if (atomic_dec_and_mutex_lock(&active_events, | ||
593 | &pmu_reserve_mutex)) { | ||
594 | /* | ||
595 | * We must not call the destroy function with interrupts | ||
596 | * disabled. | ||
597 | */ | ||
598 | on_each_cpu(reset_counters, | ||
599 | (void *)(long)mipspmu.num_counters, 1); | ||
600 | mipspmu_free_irq(); | ||
601 | mutex_unlock(&pmu_reserve_mutex); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static int mipspmu_event_init(struct perf_event *event) | ||
606 | { | ||
607 | int err = 0; | ||
608 | |||
609 | switch (event->attr.type) { | ||
610 | case PERF_TYPE_RAW: | ||
611 | case PERF_TYPE_HARDWARE: | ||
612 | case PERF_TYPE_HW_CACHE: | ||
613 | break; | ||
614 | |||
615 | default: | ||
616 | return -ENOENT; | ||
617 | } | ||
618 | |||
619 | if (event->cpu >= nr_cpumask_bits || | ||
620 | (event->cpu >= 0 && !cpu_online(event->cpu))) | ||
621 | return -ENODEV; | ||
622 | |||
623 | if (!atomic_inc_not_zero(&active_events)) { | ||
624 | if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { | ||
625 | atomic_dec(&active_events); | ||
626 | return -ENOSPC; | ||
627 | } | ||
628 | |||
629 | mutex_lock(&pmu_reserve_mutex); | ||
630 | if (atomic_read(&active_events) == 0) | ||
631 | err = mipspmu_get_irq(); | ||
632 | |||
633 | if (!err) | ||
634 | atomic_inc(&active_events); | ||
635 | mutex_unlock(&pmu_reserve_mutex); | ||
636 | } | ||
637 | |||
638 | if (err) | ||
639 | return err; | ||
640 | |||
641 | err = __hw_perf_event_init(event); | ||
642 | if (err) | ||
643 | hw_perf_event_destroy(event); | ||
644 | |||
645 | return err; | ||
646 | } | ||
647 | |||
648 | static struct pmu pmu = { | ||
649 | .pmu_enable = mipspmu_enable, | ||
650 | .pmu_disable = mipspmu_disable, | ||
651 | .event_init = mipspmu_event_init, | ||
652 | .add = mipspmu_add, | ||
653 | .del = mipspmu_del, | ||
654 | .start = mipspmu_start, | ||
655 | .stop = mipspmu_stop, | ||
656 | .read = mipspmu_read, | ||
657 | }; | ||
658 | |||
659 | static unsigned int mipspmu_perf_event_encode(const struct mips_perf_event *pev) | ||
660 | { | ||
661 | /* | ||
662 | * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for | ||
663 | * event_id. | ||
664 | */ | ||
252 | #ifdef CONFIG_MIPS_MT_SMP | 665 | #ifdef CONFIG_MIPS_MT_SMP |
253 | static DEFINE_RWLOCK(pmuint_rwlock); | 666 | return ((unsigned int)pev->range << 24) | |
667 | (pev->cntr_mask & 0xffff00) | | ||
668 | (pev->event_id & 0xff); | ||
669 | #else | ||
670 | return (pev->cntr_mask & 0xffff00) | | ||
671 | (pev->event_id & 0xff); | ||
254 | #endif | 672 | #endif |
673 | } | ||
674 | |||
675 | static const struct mips_perf_event *mipspmu_map_general_event(int idx) | ||
676 | { | ||
677 | const struct mips_perf_event *pev; | ||
678 | |||
679 | pev = ((*mipspmu.general_event_map)[idx].event_id == | ||
680 | UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) : | ||
681 | &(*mipspmu.general_event_map)[idx]); | ||
682 | |||
683 | return pev; | ||
684 | } | ||
685 | |||
686 | static const struct mips_perf_event *mipspmu_map_cache_event(u64 config) | ||
687 | { | ||
688 | unsigned int cache_type, cache_op, cache_result; | ||
689 | const struct mips_perf_event *pev; | ||
690 | |||
691 | cache_type = (config >> 0) & 0xff; | ||
692 | if (cache_type >= PERF_COUNT_HW_CACHE_MAX) | ||
693 | return ERR_PTR(-EINVAL); | ||
694 | |||
695 | cache_op = (config >> 8) & 0xff; | ||
696 | if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) | ||
697 | return ERR_PTR(-EINVAL); | ||
698 | |||
699 | cache_result = (config >> 16) & 0xff; | ||
700 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) | ||
701 | return ERR_PTR(-EINVAL); | ||
702 | |||
703 | pev = &((*mipspmu.cache_event_map) | ||
704 | [cache_type] | ||
705 | [cache_op] | ||
706 | [cache_result]); | ||
707 | |||
708 | if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID) | ||
709 | return ERR_PTR(-EOPNOTSUPP); | ||
710 | |||
711 | return pev; | ||
712 | |||
713 | } | ||
714 | |||
715 | static int validate_event(struct cpu_hw_events *cpuc, | ||
716 | struct perf_event *event) | ||
717 | { | ||
718 | struct hw_perf_event fake_hwc = event->hw; | ||
719 | |||
720 | /* Allow mixed event group. So return 1 to pass validation. */ | ||
721 | if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) | ||
722 | return 1; | ||
723 | |||
724 | return mipsxx_pmu_alloc_counter(cpuc, &fake_hwc) >= 0; | ||
725 | } | ||
726 | |||
727 | static int validate_group(struct perf_event *event) | ||
728 | { | ||
729 | struct perf_event *sibling, *leader = event->group_leader; | ||
730 | struct cpu_hw_events fake_cpuc; | ||
731 | |||
732 | memset(&fake_cpuc, 0, sizeof(fake_cpuc)); | ||
733 | |||
734 | if (!validate_event(&fake_cpuc, leader)) | ||
735 | return -ENOSPC; | ||
736 | |||
737 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { | ||
738 | if (!validate_event(&fake_cpuc, sibling)) | ||
739 | return -ENOSPC; | ||
740 | } | ||
741 | |||
742 | if (!validate_event(&fake_cpuc, event)) | ||
743 | return -ENOSPC; | ||
744 | |||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | /* This is needed by specific irq handlers in perf_event_*.c */ | ||
749 | static void handle_associated_event(struct cpu_hw_events *cpuc, | ||
750 | int idx, struct perf_sample_data *data, | ||
751 | struct pt_regs *regs) | ||
752 | { | ||
753 | struct perf_event *event = cpuc->events[idx]; | ||
754 | struct hw_perf_event *hwc = &event->hw; | ||
755 | |||
756 | mipspmu_event_update(event, hwc, idx); | ||
757 | data->period = event->hw.last_period; | ||
758 | if (!mipspmu_event_set_period(event, hwc, idx)) | ||
759 | return; | ||
760 | |||
761 | if (perf_event_overflow(event, data, regs)) | ||
762 | mipsxx_pmu_disable_event(idx); | ||
763 | } | ||
764 | |||
765 | |||
766 | static int __n_counters(void) | ||
767 | { | ||
768 | if (!(read_c0_config1() & M_CONFIG1_PC)) | ||
769 | return 0; | ||
770 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) | ||
771 | return 1; | ||
772 | if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) | ||
773 | return 2; | ||
774 | if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) | ||
775 | return 3; | ||
776 | |||
777 | return 4; | ||
778 | } | ||
779 | |||
780 | static int n_counters(void) | ||
781 | { | ||
782 | int counters; | ||
783 | |||
784 | switch (current_cpu_type()) { | ||
785 | case CPU_R10000: | ||
786 | counters = 2; | ||
787 | break; | ||
788 | |||
789 | case CPU_R12000: | ||
790 | case CPU_R14000: | ||
791 | counters = 4; | ||
792 | break; | ||
793 | |||
794 | default: | ||
795 | counters = __n_counters(); | ||
796 | } | ||
797 | |||
798 | return counters; | ||
799 | } | ||
800 | |||
801 | static void reset_counters(void *arg) | ||
802 | { | ||
803 | int counters = (int)(long)arg; | ||
804 | switch (counters) { | ||
805 | case 4: | ||
806 | mipsxx_pmu_write_control(3, 0); | ||
807 | mipspmu.write_counter(3, 0); | ||
808 | case 3: | ||
809 | mipsxx_pmu_write_control(2, 0); | ||
810 | mipspmu.write_counter(2, 0); | ||
811 | case 2: | ||
812 | mipsxx_pmu_write_control(1, 0); | ||
813 | mipspmu.write_counter(1, 0); | ||
814 | case 1: | ||
815 | mipsxx_pmu_write_control(0, 0); | ||
816 | mipspmu.write_counter(0, 0); | ||
817 | } | ||
818 | } | ||
255 | 819 | ||
256 | /* 24K/34K/1004K cores can share the same event map. */ | 820 | /* 24K/34K/1004K cores can share the same event map. */ |
257 | static const struct mips_perf_event mipsxxcore_event_map | 821 | static const struct mips_perf_event mipsxxcore_event_map |
@@ -277,6 +841,16 @@ static const struct mips_perf_event mipsxx74Kcore_event_map | |||
277 | [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, | 841 | [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, |
278 | }; | 842 | }; |
279 | 843 | ||
844 | static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = { | ||
845 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL }, | ||
846 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL }, | ||
847 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x2b, CNTR_ALL }, | ||
848 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x2e, CNTR_ALL }, | ||
849 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x08, CNTR_ALL }, | ||
850 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x09, CNTR_ALL }, | ||
851 | [PERF_COUNT_HW_BUS_CYCLES] = { 0x25, CNTR_ALL }, | ||
852 | }; | ||
853 | |||
280 | /* 24K/34K/1004K cores can share the same cache event map. */ | 854 | /* 24K/34K/1004K cores can share the same cache event map. */ |
281 | static const struct mips_perf_event mipsxxcore_cache_map | 855 | static const struct mips_perf_event mipsxxcore_cache_map |
282 | [PERF_COUNT_HW_CACHE_MAX] | 856 | [PERF_COUNT_HW_CACHE_MAX] |
@@ -510,10 +1084,105 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map | |||
510 | }, | 1084 | }, |
511 | }; | 1085 | }; |
512 | 1086 | ||
1087 | |||
1088 | static const struct mips_perf_event octeon_cache_map | ||
1089 | [PERF_COUNT_HW_CACHE_MAX] | ||
1090 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
1091 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
1092 | [C(L1D)] = { | ||
1093 | [C(OP_READ)] = { | ||
1094 | [C(RESULT_ACCESS)] = { 0x2b, CNTR_ALL }, | ||
1095 | [C(RESULT_MISS)] = { 0x2e, CNTR_ALL }, | ||
1096 | }, | ||
1097 | [C(OP_WRITE)] = { | ||
1098 | [C(RESULT_ACCESS)] = { 0x30, CNTR_ALL }, | ||
1099 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1100 | }, | ||
1101 | [C(OP_PREFETCH)] = { | ||
1102 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1103 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1104 | }, | ||
1105 | }, | ||
1106 | [C(L1I)] = { | ||
1107 | [C(OP_READ)] = { | ||
1108 | [C(RESULT_ACCESS)] = { 0x18, CNTR_ALL }, | ||
1109 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1110 | }, | ||
1111 | [C(OP_WRITE)] = { | ||
1112 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1113 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1114 | }, | ||
1115 | [C(OP_PREFETCH)] = { | ||
1116 | [C(RESULT_ACCESS)] = { 0x19, CNTR_ALL }, | ||
1117 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1118 | }, | ||
1119 | }, | ||
1120 | [C(LL)] = { | ||
1121 | [C(OP_READ)] = { | ||
1122 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1123 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1124 | }, | ||
1125 | [C(OP_WRITE)] = { | ||
1126 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1127 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1128 | }, | ||
1129 | [C(OP_PREFETCH)] = { | ||
1130 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1131 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1132 | }, | ||
1133 | }, | ||
1134 | [C(DTLB)] = { | ||
1135 | /* | ||
1136 | * Only general DTLB misses are counted use the same event for | ||
1137 | * read and write. | ||
1138 | */ | ||
1139 | [C(OP_READ)] = { | ||
1140 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1141 | [C(RESULT_MISS)] = { 0x35, CNTR_ALL }, | ||
1142 | }, | ||
1143 | [C(OP_WRITE)] = { | ||
1144 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1145 | [C(RESULT_MISS)] = { 0x35, CNTR_ALL }, | ||
1146 | }, | ||
1147 | [C(OP_PREFETCH)] = { | ||
1148 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1149 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1150 | }, | ||
1151 | }, | ||
1152 | [C(ITLB)] = { | ||
1153 | [C(OP_READ)] = { | ||
1154 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1155 | [C(RESULT_MISS)] = { 0x37, CNTR_ALL }, | ||
1156 | }, | ||
1157 | [C(OP_WRITE)] = { | ||
1158 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1159 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1160 | }, | ||
1161 | [C(OP_PREFETCH)] = { | ||
1162 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1163 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1164 | }, | ||
1165 | }, | ||
1166 | [C(BPU)] = { | ||
1167 | /* Using the same code for *HW_BRANCH* */ | ||
1168 | [C(OP_READ)] = { | ||
1169 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1170 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1171 | }, | ||
1172 | [C(OP_WRITE)] = { | ||
1173 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1174 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1175 | }, | ||
1176 | [C(OP_PREFETCH)] = { | ||
1177 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1178 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
1179 | }, | ||
1180 | }, | ||
1181 | }; | ||
1182 | |||
513 | #ifdef CONFIG_MIPS_MT_SMP | 1183 | #ifdef CONFIG_MIPS_MT_SMP |
514 | static void | 1184 | static void check_and_calc_range(struct perf_event *event, |
515 | check_and_calc_range(struct perf_event *event, | 1185 | const struct mips_perf_event *pev) |
516 | const struct mips_perf_event *pev) | ||
517 | { | 1186 | { |
518 | struct hw_perf_event *hwc = &event->hw; | 1187 | struct hw_perf_event *hwc = &event->hw; |
519 | 1188 | ||
@@ -536,9 +1205,8 @@ check_and_calc_range(struct perf_event *event, | |||
536 | hwc->config_base |= M_TC_EN_ALL; | 1205 | hwc->config_base |= M_TC_EN_ALL; |
537 | } | 1206 | } |
538 | #else | 1207 | #else |
539 | static void | 1208 | static void check_and_calc_range(struct perf_event *event, |
540 | check_and_calc_range(struct perf_event *event, | 1209 | const struct mips_perf_event *pev) |
541 | const struct mips_perf_event *pev) | ||
542 | { | 1210 | { |
543 | } | 1211 | } |
544 | #endif | 1212 | #endif |
@@ -560,7 +1228,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
560 | } else if (PERF_TYPE_RAW == event->attr.type) { | 1228 | } else if (PERF_TYPE_RAW == event->attr.type) { |
561 | /* We are working on the global raw event. */ | 1229 | /* We are working on the global raw event. */ |
562 | mutex_lock(&raw_event_mutex); | 1230 | mutex_lock(&raw_event_mutex); |
563 | pev = mipspmu->map_raw_event(event->attr.config); | 1231 | pev = mipspmu.map_raw_event(event->attr.config); |
564 | } else { | 1232 | } else { |
565 | /* The event type is not (yet) supported. */ | 1233 | /* The event type is not (yet) supported. */ |
566 | return -EOPNOTSUPP; | 1234 | return -EOPNOTSUPP; |
@@ -605,7 +1273,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
605 | hwc->config = 0; | 1273 | hwc->config = 0; |
606 | 1274 | ||
607 | if (!hwc->sample_period) { | 1275 | if (!hwc->sample_period) { |
608 | hwc->sample_period = MAX_PERIOD; | 1276 | hwc->sample_period = mipspmu.max_period; |
609 | hwc->last_period = hwc->sample_period; | 1277 | hwc->last_period = hwc->sample_period; |
610 | local64_set(&hwc->period_left, hwc->sample_period); | 1278 | local64_set(&hwc->period_left, hwc->sample_period); |
611 | } | 1279 | } |
@@ -618,70 +1286,47 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
618 | } | 1286 | } |
619 | 1287 | ||
620 | event->destroy = hw_perf_event_destroy; | 1288 | event->destroy = hw_perf_event_destroy; |
621 | |||
622 | return err; | 1289 | return err; |
623 | } | 1290 | } |
624 | 1291 | ||
625 | static void pause_local_counters(void) | 1292 | static void pause_local_counters(void) |
626 | { | 1293 | { |
627 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1294 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
628 | int counters = mipspmu->num_counters; | 1295 | int ctr = mipspmu.num_counters; |
629 | unsigned long flags; | 1296 | unsigned long flags; |
630 | 1297 | ||
631 | local_irq_save(flags); | 1298 | local_irq_save(flags); |
632 | switch (counters) { | 1299 | do { |
633 | case 4: | 1300 | ctr--; |
634 | cpuc->saved_ctrl[3] = r_c0_perfctrl3(); | 1301 | cpuc->saved_ctrl[ctr] = mipsxx_pmu_read_control(ctr); |
635 | w_c0_perfctrl3(cpuc->saved_ctrl[3] & | 1302 | mipsxx_pmu_write_control(ctr, cpuc->saved_ctrl[ctr] & |
636 | ~M_PERFCTL_COUNT_EVENT_WHENEVER); | 1303 | ~M_PERFCTL_COUNT_EVENT_WHENEVER); |
637 | case 3: | 1304 | } while (ctr > 0); |
638 | cpuc->saved_ctrl[2] = r_c0_perfctrl2(); | ||
639 | w_c0_perfctrl2(cpuc->saved_ctrl[2] & | ||
640 | ~M_PERFCTL_COUNT_EVENT_WHENEVER); | ||
641 | case 2: | ||
642 | cpuc->saved_ctrl[1] = r_c0_perfctrl1(); | ||
643 | w_c0_perfctrl1(cpuc->saved_ctrl[1] & | ||
644 | ~M_PERFCTL_COUNT_EVENT_WHENEVER); | ||
645 | case 1: | ||
646 | cpuc->saved_ctrl[0] = r_c0_perfctrl0(); | ||
647 | w_c0_perfctrl0(cpuc->saved_ctrl[0] & | ||
648 | ~M_PERFCTL_COUNT_EVENT_WHENEVER); | ||
649 | } | ||
650 | local_irq_restore(flags); | 1305 | local_irq_restore(flags); |
651 | } | 1306 | } |
652 | 1307 | ||
653 | static void resume_local_counters(void) | 1308 | static void resume_local_counters(void) |
654 | { | 1309 | { |
655 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1310 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
656 | int counters = mipspmu->num_counters; | 1311 | int ctr = mipspmu.num_counters; |
657 | unsigned long flags; | ||
658 | 1312 | ||
659 | local_irq_save(flags); | 1313 | do { |
660 | switch (counters) { | 1314 | ctr--; |
661 | case 4: | 1315 | mipsxx_pmu_write_control(ctr, cpuc->saved_ctrl[ctr]); |
662 | w_c0_perfctrl3(cpuc->saved_ctrl[3]); | 1316 | } while (ctr > 0); |
663 | case 3: | ||
664 | w_c0_perfctrl2(cpuc->saved_ctrl[2]); | ||
665 | case 2: | ||
666 | w_c0_perfctrl1(cpuc->saved_ctrl[1]); | ||
667 | case 1: | ||
668 | w_c0_perfctrl0(cpuc->saved_ctrl[0]); | ||
669 | } | ||
670 | local_irq_restore(flags); | ||
671 | } | 1317 | } |
672 | 1318 | ||
673 | static int mipsxx_pmu_handle_shared_irq(void) | 1319 | static int mipsxx_pmu_handle_shared_irq(void) |
674 | { | 1320 | { |
675 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1321 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
676 | struct perf_sample_data data; | 1322 | struct perf_sample_data data; |
677 | unsigned int counters = mipspmu->num_counters; | 1323 | unsigned int counters = mipspmu.num_counters; |
678 | unsigned int counter; | 1324 | u64 counter; |
679 | int handled = IRQ_NONE; | 1325 | int handled = IRQ_NONE; |
680 | struct pt_regs *regs; | 1326 | struct pt_regs *regs; |
681 | 1327 | ||
682 | if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26))) | 1328 | if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26))) |
683 | return handled; | 1329 | return handled; |
684 | |||
685 | /* | 1330 | /* |
686 | * First we pause the local counters, so that when we are locked | 1331 | * First we pause the local counters, so that when we are locked |
687 | * here, the counters are all paused. When it gets locked due to | 1332 | * here, the counters are all paused. When it gets locked due to |
@@ -702,13 +1347,9 @@ static int mipsxx_pmu_handle_shared_irq(void) | |||
702 | #define HANDLE_COUNTER(n) \ | 1347 | #define HANDLE_COUNTER(n) \ |
703 | case n + 1: \ | 1348 | case n + 1: \ |
704 | if (test_bit(n, cpuc->used_mask)) { \ | 1349 | if (test_bit(n, cpuc->used_mask)) { \ |
705 | counter = r_c0_perfcntr ## n(); \ | 1350 | counter = mipspmu.read_counter(n); \ |
706 | if (counter & M_COUNTER_OVERFLOW) { \ | 1351 | if (counter & mipspmu.overflow) { \ |
707 | w_c0_perfcntr ## n(counter & \ | 1352 | handle_associated_event(cpuc, n, &data, regs); \ |
708 | VALID_COUNT); \ | ||
709 | if (test_and_change_bit(n, cpuc->msbs)) \ | ||
710 | handle_associated_event(cpuc, \ | ||
711 | n, &data, regs); \ | ||
712 | handled = IRQ_HANDLED; \ | 1353 | handled = IRQ_HANDLED; \ |
713 | } \ | 1354 | } \ |
714 | } | 1355 | } |
@@ -733,104 +1374,11 @@ static int mipsxx_pmu_handle_shared_irq(void) | |||
733 | return handled; | 1374 | return handled; |
734 | } | 1375 | } |
735 | 1376 | ||
736 | static irqreturn_t | 1377 | static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev) |
737 | mipsxx_pmu_handle_irq(int irq, void *dev) | ||
738 | { | 1378 | { |
739 | return mipsxx_pmu_handle_shared_irq(); | 1379 | return mipsxx_pmu_handle_shared_irq(); |
740 | } | 1380 | } |
741 | 1381 | ||
742 | static void mipsxx_pmu_start(void) | ||
743 | { | ||
744 | #ifdef CONFIG_MIPS_MT_SMP | ||
745 | write_unlock(&pmuint_rwlock); | ||
746 | #endif | ||
747 | resume_local_counters(); | ||
748 | } | ||
749 | |||
750 | /* | ||
751 | * MIPS performance counters can be per-TC. The control registers can | ||
752 | * not be directly accessed across CPUs. Hence if we want to do global | ||
753 | * control, we need cross CPU calls. on_each_cpu() can help us, but we | ||
754 | * can not make sure this function is called with interrupts enabled. So | ||
755 | * here we pause local counters and then grab a rwlock and leave the | ||
756 | * counters on other CPUs alone. If any counter interrupt raises while | ||
757 | * we own the write lock, simply pause local counters on that CPU and | ||
758 | * spin in the handler. Also we know we won't be switched to another | ||
759 | * CPU after pausing local counters and before grabbing the lock. | ||
760 | */ | ||
761 | static void mipsxx_pmu_stop(void) | ||
762 | { | ||
763 | pause_local_counters(); | ||
764 | #ifdef CONFIG_MIPS_MT_SMP | ||
765 | write_lock(&pmuint_rwlock); | ||
766 | #endif | ||
767 | } | ||
768 | |||
769 | static int | ||
770 | mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc, | ||
771 | struct hw_perf_event *hwc) | ||
772 | { | ||
773 | int i; | ||
774 | |||
775 | /* | ||
776 | * We only need to care the counter mask. The range has been | ||
777 | * checked definitely. | ||
778 | */ | ||
779 | unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff; | ||
780 | |||
781 | for (i = mipspmu->num_counters - 1; i >= 0; i--) { | ||
782 | /* | ||
783 | * Note that some MIPS perf events can be counted by both | ||
784 | * even and odd counters, wheresas many other are only by | ||
785 | * even _or_ odd counters. This introduces an issue that | ||
786 | * when the former kind of event takes the counter the | ||
787 | * latter kind of event wants to use, then the "counter | ||
788 | * allocation" for the latter event will fail. In fact if | ||
789 | * they can be dynamically swapped, they both feel happy. | ||
790 | * But here we leave this issue alone for now. | ||
791 | */ | ||
792 | if (test_bit(i, &cntr_mask) && | ||
793 | !test_and_set_bit(i, cpuc->used_mask)) | ||
794 | return i; | ||
795 | } | ||
796 | |||
797 | return -EAGAIN; | ||
798 | } | ||
799 | |||
800 | static void | ||
801 | mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx) | ||
802 | { | ||
803 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
804 | unsigned long flags; | ||
805 | |||
806 | WARN_ON(idx < 0 || idx >= mipspmu->num_counters); | ||
807 | |||
808 | local_irq_save(flags); | ||
809 | cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) | | ||
810 | (evt->config_base & M_PERFCTL_CONFIG_MASK) | | ||
811 | /* Make sure interrupt enabled. */ | ||
812 | M_PERFCTL_INTERRUPT_ENABLE; | ||
813 | /* | ||
814 | * We do not actually let the counter run. Leave it until start(). | ||
815 | */ | ||
816 | local_irq_restore(flags); | ||
817 | } | ||
818 | |||
819 | static void | ||
820 | mipsxx_pmu_disable_event(int idx) | ||
821 | { | ||
822 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
823 | unsigned long flags; | ||
824 | |||
825 | WARN_ON(idx < 0 || idx >= mipspmu->num_counters); | ||
826 | |||
827 | local_irq_save(flags); | ||
828 | cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) & | ||
829 | ~M_PERFCTL_COUNT_EVENT_WHENEVER; | ||
830 | mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]); | ||
831 | local_irq_restore(flags); | ||
832 | } | ||
833 | |||
834 | /* 24K */ | 1382 | /* 24K */ |
835 | #define IS_UNSUPPORTED_24K_EVENT(r, b) \ | 1383 | #define IS_UNSUPPORTED_24K_EVENT(r, b) \ |
836 | ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \ | 1384 | ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \ |
@@ -892,8 +1440,7 @@ mipsxx_pmu_disable_event(int idx) | |||
892 | * then 128 needs to be added to 15 as the input for the event config, | 1440 | * then 128 needs to be added to 15 as the input for the event config, |
893 | * i.e., 143 (0x8F) to be used. | 1441 | * i.e., 143 (0x8F) to be used. |
894 | */ | 1442 | */ |
895 | static const struct mips_perf_event * | 1443 | static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) |
896 | mipsxx_pmu_map_raw_event(u64 config) | ||
897 | { | 1444 | { |
898 | unsigned int raw_id = config & 0xff; | 1445 | unsigned int raw_id = config & 0xff; |
899 | unsigned int base_id = raw_id & 0x7f; | 1446 | unsigned int base_id = raw_id & 0x7f; |
@@ -970,40 +1517,44 @@ mipsxx_pmu_map_raw_event(u64 config) | |||
970 | return &raw_event; | 1517 | return &raw_event; |
971 | } | 1518 | } |
972 | 1519 | ||
973 | static struct mips_pmu mipsxxcore_pmu = { | 1520 | static const struct mips_perf_event *octeon_pmu_map_raw_event(u64 config) |
974 | .handle_irq = mipsxx_pmu_handle_irq, | 1521 | { |
975 | .handle_shared_irq = mipsxx_pmu_handle_shared_irq, | 1522 | unsigned int raw_id = config & 0xff; |
976 | .start = mipsxx_pmu_start, | 1523 | unsigned int base_id = raw_id & 0x7f; |
977 | .stop = mipsxx_pmu_stop, | ||
978 | .alloc_counter = mipsxx_pmu_alloc_counter, | ||
979 | .read_counter = mipsxx_pmu_read_counter, | ||
980 | .write_counter = mipsxx_pmu_write_counter, | ||
981 | .enable_event = mipsxx_pmu_enable_event, | ||
982 | .disable_event = mipsxx_pmu_disable_event, | ||
983 | .map_raw_event = mipsxx_pmu_map_raw_event, | ||
984 | .general_event_map = &mipsxxcore_event_map, | ||
985 | .cache_event_map = &mipsxxcore_cache_map, | ||
986 | }; | ||
987 | 1524 | ||
988 | static struct mips_pmu mipsxx74Kcore_pmu = { | 1525 | |
989 | .handle_irq = mipsxx_pmu_handle_irq, | 1526 | raw_event.cntr_mask = CNTR_ALL; |
990 | .handle_shared_irq = mipsxx_pmu_handle_shared_irq, | 1527 | raw_event.event_id = base_id; |
991 | .start = mipsxx_pmu_start, | 1528 | |
992 | .stop = mipsxx_pmu_stop, | 1529 | if (current_cpu_type() == CPU_CAVIUM_OCTEON2) { |
993 | .alloc_counter = mipsxx_pmu_alloc_counter, | 1530 | if (base_id > 0x42) |
994 | .read_counter = mipsxx_pmu_read_counter, | 1531 | return ERR_PTR(-EOPNOTSUPP); |
995 | .write_counter = mipsxx_pmu_write_counter, | 1532 | } else { |
996 | .enable_event = mipsxx_pmu_enable_event, | 1533 | if (base_id > 0x3a) |
997 | .disable_event = mipsxx_pmu_disable_event, | 1534 | return ERR_PTR(-EOPNOTSUPP); |
998 | .map_raw_event = mipsxx_pmu_map_raw_event, | 1535 | } |
999 | .general_event_map = &mipsxx74Kcore_event_map, | 1536 | |
1000 | .cache_event_map = &mipsxx74Kcore_cache_map, | 1537 | switch (base_id) { |
1001 | }; | 1538 | case 0x00: |
1539 | case 0x0f: | ||
1540 | case 0x1e: | ||
1541 | case 0x1f: | ||
1542 | case 0x2f: | ||
1543 | case 0x34: | ||
1544 | case 0x3b ... 0x3f: | ||
1545 | return ERR_PTR(-EOPNOTSUPP); | ||
1546 | default: | ||
1547 | break; | ||
1548 | } | ||
1549 | |||
1550 | return &raw_event; | ||
1551 | } | ||
1002 | 1552 | ||
1003 | static int __init | 1553 | static int __init |
1004 | init_hw_perf_events(void) | 1554 | init_hw_perf_events(void) |
1005 | { | 1555 | { |
1006 | int counters, irq; | 1556 | int counters, irq; |
1557 | int counter_bits; | ||
1007 | 1558 | ||
1008 | pr_info("Performance counters: "); | 1559 | pr_info("Performance counters: "); |
1009 | 1560 | ||
@@ -1035,32 +1586,36 @@ init_hw_perf_events(void) | |||
1035 | } | 1586 | } |
1036 | #endif | 1587 | #endif |
1037 | 1588 | ||
1038 | on_each_cpu(reset_counters, (void *)(long)counters, 1); | 1589 | mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; |
1039 | 1590 | ||
1040 | switch (current_cpu_type()) { | 1591 | switch (current_cpu_type()) { |
1041 | case CPU_24K: | 1592 | case CPU_24K: |
1042 | mipsxxcore_pmu.name = "mips/24K"; | 1593 | mipspmu.name = "mips/24K"; |
1043 | mipsxxcore_pmu.num_counters = counters; | 1594 | mipspmu.general_event_map = &mipsxxcore_event_map; |
1044 | mipsxxcore_pmu.irq = irq; | 1595 | mipspmu.cache_event_map = &mipsxxcore_cache_map; |
1045 | mipspmu = &mipsxxcore_pmu; | ||
1046 | break; | 1596 | break; |
1047 | case CPU_34K: | 1597 | case CPU_34K: |
1048 | mipsxxcore_pmu.name = "mips/34K"; | 1598 | mipspmu.name = "mips/34K"; |
1049 | mipsxxcore_pmu.num_counters = counters; | 1599 | mipspmu.general_event_map = &mipsxxcore_event_map; |
1050 | mipsxxcore_pmu.irq = irq; | 1600 | mipspmu.cache_event_map = &mipsxxcore_cache_map; |
1051 | mipspmu = &mipsxxcore_pmu; | ||
1052 | break; | 1601 | break; |
1053 | case CPU_74K: | 1602 | case CPU_74K: |
1054 | mipsxx74Kcore_pmu.name = "mips/74K"; | 1603 | mipspmu.name = "mips/74K"; |
1055 | mipsxx74Kcore_pmu.num_counters = counters; | 1604 | mipspmu.general_event_map = &mipsxx74Kcore_event_map; |
1056 | mipsxx74Kcore_pmu.irq = irq; | 1605 | mipspmu.cache_event_map = &mipsxx74Kcore_cache_map; |
1057 | mipspmu = &mipsxx74Kcore_pmu; | ||
1058 | break; | 1606 | break; |
1059 | case CPU_1004K: | 1607 | case CPU_1004K: |
1060 | mipsxxcore_pmu.name = "mips/1004K"; | 1608 | mipspmu.name = "mips/1004K"; |
1061 | mipsxxcore_pmu.num_counters = counters; | 1609 | mipspmu.general_event_map = &mipsxxcore_event_map; |
1062 | mipsxxcore_pmu.irq = irq; | 1610 | mipspmu.cache_event_map = &mipsxxcore_cache_map; |
1063 | mipspmu = &mipsxxcore_pmu; | 1611 | break; |
1612 | case CPU_CAVIUM_OCTEON: | ||
1613 | case CPU_CAVIUM_OCTEON_PLUS: | ||
1614 | case CPU_CAVIUM_OCTEON2: | ||
1615 | mipspmu.name = "octeon"; | ||
1616 | mipspmu.general_event_map = &octeon_event_map; | ||
1617 | mipspmu.cache_event_map = &octeon_cache_map; | ||
1618 | mipspmu.map_raw_event = octeon_pmu_map_raw_event; | ||
1064 | break; | 1619 | break; |
1065 | default: | 1620 | default: |
1066 | pr_cont("Either hardware does not support performance " | 1621 | pr_cont("Either hardware does not support performance " |
@@ -1068,15 +1623,33 @@ init_hw_perf_events(void) | |||
1068 | return -ENODEV; | 1623 | return -ENODEV; |
1069 | } | 1624 | } |
1070 | 1625 | ||
1071 | if (mipspmu) | 1626 | mipspmu.num_counters = counters; |
1072 | pr_cont("%s PMU enabled, %d counters available to each " | 1627 | mipspmu.irq = irq; |
1073 | "CPU, irq %d%s\n", mipspmu->name, counters, irq, | 1628 | |
1074 | irq < 0 ? " (share with timer interrupt)" : ""); | 1629 | if (read_c0_perfctrl0() & M_PERFCTL_WIDE) { |
1630 | mipspmu.max_period = (1ULL << 63) - 1; | ||
1631 | mipspmu.valid_count = (1ULL << 63) - 1; | ||
1632 | mipspmu.overflow = 1ULL << 63; | ||
1633 | mipspmu.read_counter = mipsxx_pmu_read_counter_64; | ||
1634 | mipspmu.write_counter = mipsxx_pmu_write_counter_64; | ||
1635 | counter_bits = 64; | ||
1636 | } else { | ||
1637 | mipspmu.max_period = (1ULL << 31) - 1; | ||
1638 | mipspmu.valid_count = (1ULL << 31) - 1; | ||
1639 | mipspmu.overflow = 1ULL << 31; | ||
1640 | mipspmu.read_counter = mipsxx_pmu_read_counter; | ||
1641 | mipspmu.write_counter = mipsxx_pmu_write_counter; | ||
1642 | counter_bits = 32; | ||
1643 | } | ||
1644 | |||
1645 | on_each_cpu(reset_counters, (void *)(long)counters, 1); | ||
1646 | |||
1647 | pr_cont("%s PMU enabled, %d %d-bit counters available to each " | ||
1648 | "CPU, irq %d%s\n", mipspmu.name, counters, counter_bits, irq, | ||
1649 | irq < 0 ? " (share with timer interrupt)" : ""); | ||
1075 | 1650 | ||
1076 | perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); | 1651 | perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); |
1077 | 1652 | ||
1078 | return 0; | 1653 | return 0; |
1079 | } | 1654 | } |
1080 | early_initcall(init_hw_perf_events); | 1655 | early_initcall(init_hw_perf_events); |
1081 | |||
1082 | #endif /* defined(CONFIG_CPU_MIPS32)... */ | ||
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 865bc7a6f5a1..47920657968d 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -496,7 +496,7 @@ einval: li v0, -ENOSYS | |||
496 | sys sys_lookup_dcookie 4 | 496 | sys sys_lookup_dcookie 4 |
497 | sys sys_epoll_create 1 | 497 | sys sys_epoll_create 1 |
498 | sys sys_epoll_ctl 4 | 498 | sys sys_epoll_ctl 4 |
499 | sys sys_epoll_wait 3 /* 4250 */ | 499 | sys sys_epoll_wait 4 /* 4250 */ |
500 | sys sys_remap_file_pages 5 | 500 | sys sys_remap_file_pages 5 |
501 | sys sys_set_tid_address 1 | 501 | sys sys_set_tid_address 1 |
502 | sys sys_restart_syscall 0 | 502 | sys sys_restart_syscall 0 |
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 16c4d256b76f..daa81f7284ac 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c | |||
@@ -169,6 +169,10 @@ static void octeon_flush_cache_page(struct vm_area_struct *vma, | |||
169 | octeon_flush_icache_all_cores(vma); | 169 | octeon_flush_icache_all_cores(vma); |
170 | } | 170 | } |
171 | 171 | ||
172 | static void octeon_flush_kernel_vmap_range(unsigned long vaddr, int size) | ||
173 | { | ||
174 | BUG(); | ||
175 | } | ||
172 | 176 | ||
173 | /** | 177 | /** |
174 | * Probe Octeon's caches | 178 | * Probe Octeon's caches |
@@ -273,6 +277,8 @@ void __cpuinit octeon_cache_init(void) | |||
273 | flush_icache_range = octeon_flush_icache_range; | 277 | flush_icache_range = octeon_flush_icache_range; |
274 | local_flush_icache_range = local_octeon_flush_icache_range; | 278 | local_flush_icache_range = local_octeon_flush_icache_range; |
275 | 279 | ||
280 | __flush_kernel_vmap_range = octeon_flush_kernel_vmap_range; | ||
281 | |||
276 | build_clear_page(); | 282 | build_clear_page(); |
277 | build_copy_page(); | 283 | build_copy_page(); |
278 | } | 284 | } |
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index e6b0efd3f6a4..0765583d0c92 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c | |||
@@ -299,6 +299,11 @@ static void r3k_flush_cache_sigtramp(unsigned long addr) | |||
299 | write_c0_status(flags); | 299 | write_c0_status(flags); |
300 | } | 300 | } |
301 | 301 | ||
302 | static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size) | ||
303 | { | ||
304 | BUG(); | ||
305 | } | ||
306 | |||
302 | static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) | 307 | static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) |
303 | { | 308 | { |
304 | /* Catch bad driver code */ | 309 | /* Catch bad driver code */ |
@@ -323,6 +328,8 @@ void __cpuinit r3k_cache_init(void) | |||
323 | flush_icache_range = r3k_flush_icache_range; | 328 | flush_icache_range = r3k_flush_icache_range; |
324 | local_flush_icache_range = r3k_flush_icache_range; | 329 | local_flush_icache_range = r3k_flush_icache_range; |
325 | 330 | ||
331 | __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; | ||
332 | |||
326 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; | 333 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; |
327 | local_flush_data_cache_page = local_r3k_flush_data_cache_page; | 334 | local_flush_data_cache_page = local_r3k_flush_data_cache_page; |
328 | flush_data_cache_page = r3k_flush_data_cache_page; | 335 | flush_data_cache_page = r3k_flush_data_cache_page; |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index b9aabb998a32..a79fe9aa7721 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -722,6 +722,39 @@ static void r4k_flush_icache_all(void) | |||
722 | r4k_blast_icache(); | 722 | r4k_blast_icache(); |
723 | } | 723 | } |
724 | 724 | ||
725 | struct flush_kernel_vmap_range_args { | ||
726 | unsigned long vaddr; | ||
727 | int size; | ||
728 | }; | ||
729 | |||
730 | static inline void local_r4k_flush_kernel_vmap_range(void *args) | ||
731 | { | ||
732 | struct flush_kernel_vmap_range_args *vmra = args; | ||
733 | unsigned long vaddr = vmra->vaddr; | ||
734 | int size = vmra->size; | ||
735 | |||
736 | /* | ||
737 | * Aliases only affect the primary caches so don't bother with | ||
738 | * S-caches or T-caches. | ||
739 | */ | ||
740 | if (cpu_has_safe_index_cacheops && size >= dcache_size) | ||
741 | r4k_blast_dcache(); | ||
742 | else { | ||
743 | R4600_HIT_CACHEOP_WAR_IMPL; | ||
744 | blast_dcache_range(vaddr, vaddr + size); | ||
745 | } | ||
746 | } | ||
747 | |||
748 | static void r4k_flush_kernel_vmap_range(unsigned long vaddr, int size) | ||
749 | { | ||
750 | struct flush_kernel_vmap_range_args args; | ||
751 | |||
752 | args.vaddr = (unsigned long) vaddr; | ||
753 | args.size = size; | ||
754 | |||
755 | r4k_on_each_cpu(local_r4k_flush_kernel_vmap_range, &args); | ||
756 | } | ||
757 | |||
725 | static inline void rm7k_erratum31(void) | 758 | static inline void rm7k_erratum31(void) |
726 | { | 759 | { |
727 | const unsigned long ic_lsize = 32; | 760 | const unsigned long ic_lsize = 32; |
@@ -1403,6 +1436,8 @@ void __cpuinit r4k_cache_init(void) | |||
1403 | flush_cache_page = r4k_flush_cache_page; | 1436 | flush_cache_page = r4k_flush_cache_page; |
1404 | flush_cache_range = r4k_flush_cache_range; | 1437 | flush_cache_range = r4k_flush_cache_range; |
1405 | 1438 | ||
1439 | __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range; | ||
1440 | |||
1406 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; | 1441 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; |
1407 | flush_icache_all = r4k_flush_icache_all; | 1442 | flush_icache_all = r4k_flush_icache_all; |
1408 | local_flush_data_cache_page = local_r4k_flush_data_cache_page; | 1443 | local_flush_data_cache_page = local_r4k_flush_data_cache_page; |
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index d352fad3e451..a43c197ccf8c 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c | |||
@@ -253,6 +253,11 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end) | |||
253 | } | 253 | } |
254 | } | 254 | } |
255 | 255 | ||
256 | static void tx39_flush_kernel_vmap_range(unsigned long vaddr, int size) | ||
257 | { | ||
258 | BUG(); | ||
259 | } | ||
260 | |||
256 | static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) | 261 | static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) |
257 | { | 262 | { |
258 | unsigned long end; | 263 | unsigned long end; |
@@ -394,6 +399,8 @@ void __cpuinit tx39_cache_init(void) | |||
394 | flush_icache_range = tx39_flush_icache_range; | 399 | flush_icache_range = tx39_flush_icache_range; |
395 | local_flush_icache_range = tx39_flush_icache_range; | 400 | local_flush_icache_range = tx39_flush_icache_range; |
396 | 401 | ||
402 | __flush_kernel_vmap_range = tx39_flush_kernel_vmap_range; | ||
403 | |||
397 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; | 404 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; |
398 | local_flush_data_cache_page = local_tx39_flush_data_cache_page; | 405 | local_flush_data_cache_page = local_tx39_flush_data_cache_page; |
399 | flush_data_cache_page = tx39_flush_data_cache_page; | 406 | flush_data_cache_page = tx39_flush_data_cache_page; |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 12af739048fa..829320c7b175 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -35,6 +35,11 @@ void (*local_flush_icache_range)(unsigned long start, unsigned long end); | |||
35 | void (*__flush_cache_vmap)(void); | 35 | void (*__flush_cache_vmap)(void); |
36 | void (*__flush_cache_vunmap)(void); | 36 | void (*__flush_cache_vunmap)(void); |
37 | 37 | ||
38 | void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); | ||
39 | void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); | ||
40 | |||
41 | EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); | ||
42 | |||
38 | /* MIPS specific cache operations */ | 43 | /* MIPS specific cache operations */ |
39 | void (*flush_cache_sigtramp)(unsigned long addr); | 44 | void (*flush_cache_sigtramp)(unsigned long addr); |
40 | void (*local_flush_data_cache_page)(void * addr); | 45 | void (*local_flush_data_cache_page)(void * addr); |
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index 40424affef83..87bb85d8d537 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c | |||
@@ -223,8 +223,8 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) | |||
223 | local_irq_restore(flags); | 223 | local_irq_restore(flags); |
224 | } | 224 | } |
225 | 225 | ||
226 | void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | 226 | void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, |
227 | unsigned long entryhi, unsigned long pagemask) | 227 | unsigned long entryhi, unsigned long pagemask) |
228 | { | 228 | { |
229 | unsigned long flags; | 229 | unsigned long flags; |
230 | unsigned long old_ctx; | 230 | unsigned long old_ctx; |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index ba40325caea6..0d394e0e8837 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -337,8 +337,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
337 | EXIT_CRITICAL(flags); | 337 | EXIT_CRITICAL(flags); |
338 | } | 338 | } |
339 | 339 | ||
340 | void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | 340 | void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, |
341 | unsigned long entryhi, unsigned long pagemask) | 341 | unsigned long entryhi, unsigned long pagemask) |
342 | { | 342 | { |
343 | unsigned long flags; | 343 | unsigned long flags; |
344 | unsigned long wired; | 344 | unsigned long wired; |
diff --git a/arch/mips/netlogic/Platform b/arch/mips/netlogic/Platform index f87c1640abb5..b648b487fd66 100644 --- a/arch/mips/netlogic/Platform +++ b/arch/mips/netlogic/Platform | |||
@@ -5,6 +5,11 @@ cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic | |||
5 | cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic | 5 | cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic |
6 | 6 | ||
7 | # | 7 | # |
8 | # use mips64 if xlr is not available | ||
9 | # | ||
10 | cflags-$(CONFIG_NLM_XLR) += $(call cc-option,-march=xlr,-march=mips64) | ||
11 | |||
12 | # | ||
8 | # NETLOGIC XLR/XLS SoC, Simulator and boards | 13 | # NETLOGIC XLR/XLS SoC, Simulator and boards |
9 | # | 14 | # |
10 | core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/ | 15 | core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/ |
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index 482802569e74..cee25ddd0887 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c | |||
@@ -53,7 +53,7 @@ unsigned long netlogic_io_base = (unsigned long)(DEFAULT_NETLOGIC_IO_BASE); | |||
53 | unsigned long nlm_common_ebase = 0x0; | 53 | unsigned long nlm_common_ebase = 0x0; |
54 | struct psb_info nlm_prom_info; | 54 | struct psb_info nlm_prom_info; |
55 | 55 | ||
56 | static void nlm_early_serial_setup(void) | 56 | static void __init nlm_early_serial_setup(void) |
57 | { | 57 | { |
58 | struct uart_port s; | 58 | struct uart_port s; |
59 | nlm_reg_t *uart_base; | 59 | nlm_reg_t *uart_base; |
@@ -101,7 +101,7 @@ void __init prom_free_prom_memory(void) | |||
101 | /* Nothing yet */ | 101 | /* Nothing yet */ |
102 | } | 102 | } |
103 | 103 | ||
104 | static void build_arcs_cmdline(int *argv) | 104 | static void __init build_arcs_cmdline(int *argv) |
105 | { | 105 | { |
106 | int i, remain, len; | 106 | int i, remain, len; |
107 | char *arg; | 107 | char *arg; |
diff --git a/arch/mips/netlogic/xlr/smp.c b/arch/mips/netlogic/xlr/smp.c index d842bce5c940..080284ded508 100644 --- a/arch/mips/netlogic/xlr/smp.c +++ b/arch/mips/netlogic/xlr/smp.c | |||
@@ -158,6 +158,10 @@ void __init nlm_smp_setup(void) | |||
158 | 158 | ||
159 | num_cpus = 1; | 159 | num_cpus = 1; |
160 | for (i = 0; i < NR_CPUS; i++) { | 160 | for (i = 0; i < NR_CPUS; i++) { |
161 | /* | ||
162 | * BSP is not set in nlm_cpu_ready array, it is only for | ||
163 | * ASPs (goto see smpboot.S) | ||
164 | */ | ||
161 | if (nlm_cpu_ready[i]) { | 165 | if (nlm_cpu_ready[i]) { |
162 | cpu_set(i, phys_cpu_present_map); | 166 | cpu_set(i, phys_cpu_present_map); |
163 | __cpu_number_map[i] = num_cpus; | 167 | __cpu_number_map[i] = num_cpus; |
@@ -191,7 +195,7 @@ struct plat_smp_ops nlm_smp_ops = { | |||
191 | 195 | ||
192 | unsigned long secondary_entry_point; | 196 | unsigned long secondary_entry_point; |
193 | 197 | ||
194 | int nlm_wakeup_secondary_cpus(u32 wakeup_mask) | 198 | int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask) |
195 | { | 199 | { |
196 | unsigned int tid, pid, ipi, i, boot_cpu; | 200 | unsigned int tid, pid, ipi, i, boot_cpu; |
197 | void *reset_vec; | 201 | void *reset_vec; |
diff --git a/arch/mips/netlogic/xlr/smpboot.S b/arch/mips/netlogic/xlr/smpboot.S index b8e074402c99..8cb7889ce0cc 100644 --- a/arch/mips/netlogic/xlr/smpboot.S +++ b/arch/mips/netlogic/xlr/smpboot.S | |||
@@ -32,17 +32,19 @@ | |||
32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/init.h> | ||
36 | |||
35 | #include <asm/asm.h> | 37 | #include <asm/asm.h> |
36 | #include <asm/asm-offsets.h> | 38 | #include <asm/asm-offsets.h> |
37 | #include <asm/regdef.h> | 39 | #include <asm/regdef.h> |
38 | #include <asm/mipsregs.h> | 40 | #include <asm/mipsregs.h> |
39 | 41 | ||
40 | 42 | /* | |
41 | /* Don't jump to linux function from Bootloader stack. Change it | 43 | * Early code for secondary CPUs. This will get them out of the bootloader |
42 | * here. Kernel might allocate bootloader memory before all the CPUs are | 44 | * code and into linux. Needed because the bootloader area will be taken |
43 | * brought up (eg: Inode cache region) and we better don't overwrite this | 45 | * and initialized by linux. |
44 | * memory | ||
45 | */ | 46 | */ |
47 | __CPUINIT | ||
46 | NESTED(prom_pre_boot_secondary_cpus, 16, sp) | 48 | NESTED(prom_pre_boot_secondary_cpus, 16, sp) |
47 | .set mips64 | 49 | .set mips64 |
48 | mfc0 t0, $15, 1 # read ebase | 50 | mfc0 t0, $15, 1 # read ebase |
@@ -73,7 +75,11 @@ NESTED(prom_pre_boot_secondary_cpus, 16, sp) | |||
73 | jr t0 | 75 | jr t0 |
74 | nop | 76 | nop |
75 | END(prom_pre_boot_secondary_cpus) | 77 | END(prom_pre_boot_secondary_cpus) |
78 | __FINIT | ||
76 | 79 | ||
80 | /* | ||
81 | * NMI code, used for CPU wakeup, copied to reset entry | ||
82 | */ | ||
77 | NESTED(nlm_boot_smp_nmi, 0, sp) | 83 | NESTED(nlm_boot_smp_nmi, 0, sp) |
78 | .set push | 84 | .set push |
79 | .set noat | 85 | .set noat |
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 4df879937446..bb82cbdbc62a 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -18,14 +18,13 @@ obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o | |||
18 | obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o | 18 | obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o |
19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ | 19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ |
20 | ops-bcm63xx.o | 20 | ops-bcm63xx.o |
21 | obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o | ||
21 | 22 | ||
22 | # | 23 | # |
23 | # These are still pretty much in the old state, watch, go blind. | 24 | # These are still pretty much in the old state, watch, go blind. |
24 | # | 25 | # |
25 | obj-$(CONFIG_LASAT) += pci-lasat.o | 26 | obj-$(CONFIG_LASAT) += pci-lasat.o |
26 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o | 27 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o |
27 | obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o | ||
28 | obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o | ||
29 | obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o | 28 | obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o |
30 | obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o | 29 | obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o |
31 | obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o | 30 | obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o |
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c deleted file mode 100644 index e2ddfc49237c..000000000000 --- a/arch/mips/pci/fixup-au1000.c +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Board specific PCI fixups. | ||
4 | * | ||
5 | * Copyright 2001-2003, 2008 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/pci.h> | ||
30 | #include <linux/init.h> | ||
31 | |||
32 | extern char irq_tab_alchemy[][5]; | ||
33 | |||
34 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
35 | { | ||
36 | return irq_tab_alchemy[slot][pin]; | ||
37 | } | ||
38 | |||
39 | /* Do platform specific device initialization at pci_enable_device() time */ | ||
40 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c deleted file mode 100644 index 9a57c5ab91dd..000000000000 --- a/arch/mips/pci/ops-au1000.c +++ /dev/null | |||
@@ -1,308 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Alchemy/AMD Au1xx0 PCI support. | ||
4 | * | ||
5 | * Copyright 2001-2003, 2007-2008 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
7 | * | ||
8 | * Support for all devices (greater than 16) added by David Gathright. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
16 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
18 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
21 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License along | ||
27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
28 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | #include <linux/types.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/vmalloc.h> | ||
36 | |||
37 | #include <asm/mach-au1x00/au1000.h> | ||
38 | |||
39 | #undef DEBUG | ||
40 | #ifdef DEBUG | ||
41 | #define DBG(x...) printk(KERN_DEBUG x) | ||
42 | #else | ||
43 | #define DBG(x...) | ||
44 | #endif | ||
45 | |||
46 | #define PCI_ACCESS_READ 0 | ||
47 | #define PCI_ACCESS_WRITE 1 | ||
48 | |||
49 | int (*board_pci_idsel)(unsigned int devsel, int assert); | ||
50 | |||
51 | void mod_wired_entry(int entry, unsigned long entrylo0, | ||
52 | unsigned long entrylo1, unsigned long entryhi, | ||
53 | unsigned long pagemask) | ||
54 | { | ||
55 | unsigned long old_pagemask; | ||
56 | unsigned long old_ctx; | ||
57 | |||
58 | /* Save old context and create impossible VPN2 value */ | ||
59 | old_ctx = read_c0_entryhi() & 0xff; | ||
60 | old_pagemask = read_c0_pagemask(); | ||
61 | write_c0_index(entry); | ||
62 | write_c0_pagemask(pagemask); | ||
63 | write_c0_entryhi(entryhi); | ||
64 | write_c0_entrylo0(entrylo0); | ||
65 | write_c0_entrylo1(entrylo1); | ||
66 | tlb_write_indexed(); | ||
67 | write_c0_entryhi(old_ctx); | ||
68 | write_c0_pagemask(old_pagemask); | ||
69 | } | ||
70 | |||
71 | static struct vm_struct *pci_cfg_vm; | ||
72 | static int pci_cfg_wired_entry; | ||
73 | static unsigned long last_entryLo0, last_entryLo1; | ||
74 | |||
75 | /* | ||
76 | * We can't ioremap the entire pci config space because it's too large. | ||
77 | * Nor can we call ioremap dynamically because some device drivers use | ||
78 | * the PCI config routines from within interrupt handlers and that | ||
79 | * becomes a problem in get_vm_area(). We use one wired TLB to handle | ||
80 | * all config accesses for all busses. | ||
81 | */ | ||
82 | void __init au1x_pci_cfg_init(void) | ||
83 | { | ||
84 | /* Reserve a wired entry for PCI config accesses */ | ||
85 | pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP); | ||
86 | if (!pci_cfg_vm) | ||
87 | panic(KERN_ERR "PCI unable to get vm area\n"); | ||
88 | pci_cfg_wired_entry = read_c0_wired(); | ||
89 | add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K); | ||
90 | last_entryLo0 = last_entryLo1 = 0xffffffff; | ||
91 | } | ||
92 | |||
93 | static int config_access(unsigned char access_type, struct pci_bus *bus, | ||
94 | unsigned int dev_fn, unsigned char where, u32 *data) | ||
95 | { | ||
96 | #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) | ||
97 | unsigned int device = PCI_SLOT(dev_fn); | ||
98 | unsigned int function = PCI_FUNC(dev_fn); | ||
99 | unsigned long offset, status; | ||
100 | unsigned long cfg_base; | ||
101 | unsigned long flags; | ||
102 | int error = PCIBIOS_SUCCESSFUL; | ||
103 | unsigned long entryLo0, entryLo1; | ||
104 | |||
105 | if (device > 19) { | ||
106 | *data = 0xffffffff; | ||
107 | return -1; | ||
108 | } | ||
109 | |||
110 | local_irq_save(flags); | ||
111 | au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)), | ||
112 | Au1500_PCI_STATCMD); | ||
113 | au_sync_udelay(1); | ||
114 | |||
115 | /* | ||
116 | * Allow board vendors to implement their own off-chip IDSEL. | ||
117 | * If it doesn't succeed, may as well bail out at this point. | ||
118 | */ | ||
119 | if (board_pci_idsel && board_pci_idsel(device, 1) == 0) { | ||
120 | *data = 0xffffffff; | ||
121 | local_irq_restore(flags); | ||
122 | return -1; | ||
123 | } | ||
124 | |||
125 | /* Setup the config window */ | ||
126 | if (bus->number == 0) | ||
127 | cfg_base = (1 << device) << 11; | ||
128 | else | ||
129 | cfg_base = 0x80000000 | (bus->number << 16) | (device << 11); | ||
130 | |||
131 | /* Setup the lower bits of the 36-bit address */ | ||
132 | offset = (function << 8) | (where & ~0x3); | ||
133 | /* Pick up any address that falls below the page mask */ | ||
134 | offset |= cfg_base & ~PAGE_MASK; | ||
135 | |||
136 | /* Page boundary */ | ||
137 | cfg_base = cfg_base & PAGE_MASK; | ||
138 | |||
139 | /* | ||
140 | * To improve performance, if the current device is the same as | ||
141 | * the last device accessed, we don't touch the TLB. | ||
142 | */ | ||
143 | entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7; | ||
144 | entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7; | ||
145 | if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) { | ||
146 | mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1, | ||
147 | (unsigned long)pci_cfg_vm->addr, PM_4K); | ||
148 | last_entryLo0 = entryLo0; | ||
149 | last_entryLo1 = entryLo1; | ||
150 | } | ||
151 | |||
152 | if (access_type == PCI_ACCESS_WRITE) | ||
153 | au_writel(*data, (int)(pci_cfg_vm->addr + offset)); | ||
154 | else | ||
155 | *data = au_readl((int)(pci_cfg_vm->addr + offset)); | ||
156 | |||
157 | au_sync_udelay(2); | ||
158 | |||
159 | DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n", | ||
160 | access_type, bus->number, device, where, *data, offset); | ||
161 | |||
162 | /* Check master abort */ | ||
163 | status = au_readl(Au1500_PCI_STATCMD); | ||
164 | |||
165 | if (status & (1 << 29)) { | ||
166 | *data = 0xffffffff; | ||
167 | error = -1; | ||
168 | DBG("Au1x Master Abort\n"); | ||
169 | } else if ((status >> 28) & 0xf) { | ||
170 | DBG("PCI ERR detected: device %u, status %lx\n", | ||
171 | device, (status >> 28) & 0xf); | ||
172 | |||
173 | /* Clear errors */ | ||
174 | au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD); | ||
175 | |||
176 | *data = 0xffffffff; | ||
177 | error = -1; | ||
178 | } | ||
179 | |||
180 | /* Take away the IDSEL. */ | ||
181 | if (board_pci_idsel) | ||
182 | (void)board_pci_idsel(device, 0); | ||
183 | |||
184 | local_irq_restore(flags); | ||
185 | return error; | ||
186 | #endif | ||
187 | } | ||
188 | |||
189 | static int read_config_byte(struct pci_bus *bus, unsigned int devfn, | ||
190 | int where, u8 *val) | ||
191 | { | ||
192 | u32 data; | ||
193 | int ret; | ||
194 | |||
195 | ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); | ||
196 | if (where & 1) | ||
197 | data >>= 8; | ||
198 | if (where & 2) | ||
199 | data >>= 16; | ||
200 | *val = data & 0xff; | ||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | static int read_config_word(struct pci_bus *bus, unsigned int devfn, | ||
205 | int where, u16 *val) | ||
206 | { | ||
207 | u32 data; | ||
208 | int ret; | ||
209 | |||
210 | ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); | ||
211 | if (where & 2) | ||
212 | data >>= 16; | ||
213 | *val = data & 0xffff; | ||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | static int read_config_dword(struct pci_bus *bus, unsigned int devfn, | ||
218 | int where, u32 *val) | ||
219 | { | ||
220 | int ret; | ||
221 | |||
222 | ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | static int write_config_byte(struct pci_bus *bus, unsigned int devfn, | ||
227 | int where, u8 val) | ||
228 | { | ||
229 | u32 data = 0; | ||
230 | |||
231 | if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) | ||
232 | return -1; | ||
233 | |||
234 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
235 | (val << ((where & 3) << 3)); | ||
236 | |||
237 | if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) | ||
238 | return -1; | ||
239 | |||
240 | return PCIBIOS_SUCCESSFUL; | ||
241 | } | ||
242 | |||
243 | static int write_config_word(struct pci_bus *bus, unsigned int devfn, | ||
244 | int where, u16 val) | ||
245 | { | ||
246 | u32 data = 0; | ||
247 | |||
248 | if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) | ||
249 | return -1; | ||
250 | |||
251 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
252 | (val << ((where & 3) << 3)); | ||
253 | |||
254 | if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) | ||
255 | return -1; | ||
256 | |||
257 | return PCIBIOS_SUCCESSFUL; | ||
258 | } | ||
259 | |||
260 | static int write_config_dword(struct pci_bus *bus, unsigned int devfn, | ||
261 | int where, u32 val) | ||
262 | { | ||
263 | if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val)) | ||
264 | return -1; | ||
265 | |||
266 | return PCIBIOS_SUCCESSFUL; | ||
267 | } | ||
268 | |||
269 | static int config_read(struct pci_bus *bus, unsigned int devfn, | ||
270 | int where, int size, u32 *val) | ||
271 | { | ||
272 | switch (size) { | ||
273 | case 1: { | ||
274 | u8 _val; | ||
275 | int rc = read_config_byte(bus, devfn, where, &_val); | ||
276 | |||
277 | *val = _val; | ||
278 | return rc; | ||
279 | } | ||
280 | case 2: { | ||
281 | u16 _val; | ||
282 | int rc = read_config_word(bus, devfn, where, &_val); | ||
283 | |||
284 | *val = _val; | ||
285 | return rc; | ||
286 | } | ||
287 | default: | ||
288 | return read_config_dword(bus, devfn, where, val); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | static int config_write(struct pci_bus *bus, unsigned int devfn, | ||
293 | int where, int size, u32 val) | ||
294 | { | ||
295 | switch (size) { | ||
296 | case 1: | ||
297 | return write_config_byte(bus, devfn, where, (u8) val); | ||
298 | case 2: | ||
299 | return write_config_word(bus, devfn, where, (u16) val); | ||
300 | default: | ||
301 | return write_config_dword(bus, devfn, where, val); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | struct pci_ops au1x_pci_ops = { | ||
306 | config_read, | ||
307 | config_write | ||
308 | }; | ||
diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c new file mode 100644 index 000000000000..4ee57104e47b --- /dev/null +++ b/arch/mips/pci/pci-alchemy.c | |||
@@ -0,0 +1,516 @@ | |||
1 | /* | ||
2 | * Alchemy PCI host mode support. | ||
3 | * | ||
4 | * Copyright 2001-2003, 2007-2008 MontaVista Software Inc. | ||
5 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
6 | * | ||
7 | * Support for all devices (greater than 16) added by David Gathright. | ||
8 | */ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/vmalloc.h> | ||
16 | |||
17 | #include <asm/mach-au1x00/au1000.h> | ||
18 | |||
19 | #ifdef CONFIG_DEBUG_PCI | ||
20 | #define DBG(x...) printk(KERN_DEBUG x) | ||
21 | #else | ||
22 | #define DBG(x...) do {} while (0) | ||
23 | #endif | ||
24 | |||
25 | #define PCI_ACCESS_READ 0 | ||
26 | #define PCI_ACCESS_WRITE 1 | ||
27 | |||
28 | struct alchemy_pci_context { | ||
29 | struct pci_controller alchemy_pci_ctrl; /* leave as first member! */ | ||
30 | void __iomem *regs; /* ctrl base */ | ||
31 | /* tools for wired entry for config space access */ | ||
32 | unsigned long last_elo0; | ||
33 | unsigned long last_elo1; | ||
34 | int wired_entry; | ||
35 | struct vm_struct *pci_cfg_vm; | ||
36 | |||
37 | unsigned long pm[12]; | ||
38 | |||
39 | int (*board_map_irq)(const struct pci_dev *d, u8 slot, u8 pin); | ||
40 | int (*board_pci_idsel)(unsigned int devsel, int assert); | ||
41 | }; | ||
42 | |||
43 | /* IO/MEM resources for PCI. Keep the memres in sync with __fixup_bigphys_addr | ||
44 | * in arch/mips/alchemy/common/setup.c | ||
45 | */ | ||
46 | static struct resource alchemy_pci_def_memres = { | ||
47 | .start = ALCHEMY_PCI_MEMWIN_START, | ||
48 | .end = ALCHEMY_PCI_MEMWIN_END, | ||
49 | .name = "PCI memory space", | ||
50 | .flags = IORESOURCE_MEM | ||
51 | }; | ||
52 | |||
53 | static struct resource alchemy_pci_def_iores = { | ||
54 | .start = ALCHEMY_PCI_IOWIN_START, | ||
55 | .end = ALCHEMY_PCI_IOWIN_END, | ||
56 | .name = "PCI IO space", | ||
57 | .flags = IORESOURCE_IO | ||
58 | }; | ||
59 | |||
60 | static void mod_wired_entry(int entry, unsigned long entrylo0, | ||
61 | unsigned long entrylo1, unsigned long entryhi, | ||
62 | unsigned long pagemask) | ||
63 | { | ||
64 | unsigned long old_pagemask; | ||
65 | unsigned long old_ctx; | ||
66 | |||
67 | /* Save old context and create impossible VPN2 value */ | ||
68 | old_ctx = read_c0_entryhi() & 0xff; | ||
69 | old_pagemask = read_c0_pagemask(); | ||
70 | write_c0_index(entry); | ||
71 | write_c0_pagemask(pagemask); | ||
72 | write_c0_entryhi(entryhi); | ||
73 | write_c0_entrylo0(entrylo0); | ||
74 | write_c0_entrylo1(entrylo1); | ||
75 | tlb_write_indexed(); | ||
76 | write_c0_entryhi(old_ctx); | ||
77 | write_c0_pagemask(old_pagemask); | ||
78 | } | ||
79 | |||
80 | static void alchemy_pci_wired_entry(struct alchemy_pci_context *ctx) | ||
81 | { | ||
82 | ctx->wired_entry = read_c0_wired(); | ||
83 | add_wired_entry(0, 0, (unsigned long)ctx->pci_cfg_vm->addr, PM_4K); | ||
84 | ctx->last_elo0 = ctx->last_elo1 = ~0; | ||
85 | } | ||
86 | |||
87 | static int config_access(unsigned char access_type, struct pci_bus *bus, | ||
88 | unsigned int dev_fn, unsigned char where, u32 *data) | ||
89 | { | ||
90 | struct alchemy_pci_context *ctx = bus->sysdata; | ||
91 | unsigned int device = PCI_SLOT(dev_fn); | ||
92 | unsigned int function = PCI_FUNC(dev_fn); | ||
93 | unsigned long offset, status, cfg_base, flags, entryLo0, entryLo1, r; | ||
94 | int error = PCIBIOS_SUCCESSFUL; | ||
95 | |||
96 | if (device > 19) { | ||
97 | *data = 0xffffffff; | ||
98 | return -1; | ||
99 | } | ||
100 | |||
101 | /* YAMON on all db1xxx boards wipes the TLB and writes zero to C0_wired | ||
102 | * on resume, clearing our wired entry. Unfortunately the ->resume() | ||
103 | * callback is called way way way too late (and ->suspend() too early) | ||
104 | * to have them destroy and recreate it. Instead just test if c0_wired | ||
105 | * is now lower than the index we retrieved before suspending and then | ||
106 | * recreate the entry if necessary. Of course this is totally bonkers | ||
107 | * and breaks as soon as someone else adds another wired entry somewhere | ||
108 | * else. Anyone have any ideas how to handle this better? | ||
109 | */ | ||
110 | if (unlikely(read_c0_wired() < ctx->wired_entry)) | ||
111 | alchemy_pci_wired_entry(ctx); | ||
112 | |||
113 | local_irq_save(flags); | ||
114 | r = __raw_readl(ctx->regs + PCI_REG_STATCMD) & 0x0000ffff; | ||
115 | r |= PCI_STATCMD_STATUS(0x2000); | ||
116 | __raw_writel(r, ctx->regs + PCI_REG_STATCMD); | ||
117 | wmb(); | ||
118 | |||
119 | /* Allow board vendors to implement their own off-chip IDSEL. | ||
120 | * If it doesn't succeed, may as well bail out at this point. | ||
121 | */ | ||
122 | if (ctx->board_pci_idsel(device, 1) == 0) { | ||
123 | *data = 0xffffffff; | ||
124 | local_irq_restore(flags); | ||
125 | return -1; | ||
126 | } | ||
127 | |||
128 | /* Setup the config window */ | ||
129 | if (bus->number == 0) | ||
130 | cfg_base = (1 << device) << 11; | ||
131 | else | ||
132 | cfg_base = 0x80000000 | (bus->number << 16) | (device << 11); | ||
133 | |||
134 | /* Setup the lower bits of the 36-bit address */ | ||
135 | offset = (function << 8) | (where & ~0x3); | ||
136 | /* Pick up any address that falls below the page mask */ | ||
137 | offset |= cfg_base & ~PAGE_MASK; | ||
138 | |||
139 | /* Page boundary */ | ||
140 | cfg_base = cfg_base & PAGE_MASK; | ||
141 | |||
142 | /* To improve performance, if the current device is the same as | ||
143 | * the last device accessed, we don't touch the TLB. | ||
144 | */ | ||
145 | entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7; | ||
146 | entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7; | ||
147 | if ((entryLo0 != ctx->last_elo0) || (entryLo1 != ctx->last_elo1)) { | ||
148 | mod_wired_entry(ctx->wired_entry, entryLo0, entryLo1, | ||
149 | (unsigned long)ctx->pci_cfg_vm->addr, PM_4K); | ||
150 | ctx->last_elo0 = entryLo0; | ||
151 | ctx->last_elo1 = entryLo1; | ||
152 | } | ||
153 | |||
154 | if (access_type == PCI_ACCESS_WRITE) | ||
155 | __raw_writel(*data, ctx->pci_cfg_vm->addr + offset); | ||
156 | else | ||
157 | *data = __raw_readl(ctx->pci_cfg_vm->addr + offset); | ||
158 | wmb(); | ||
159 | |||
160 | DBG("alchemy-pci: cfg access %d bus %u dev %u at %x dat %x conf %lx\n", | ||
161 | access_type, bus->number, device, where, *data, offset); | ||
162 | |||
163 | /* check for errors, master abort */ | ||
164 | status = __raw_readl(ctx->regs + PCI_REG_STATCMD); | ||
165 | if (status & (1 << 29)) { | ||
166 | *data = 0xffffffff; | ||
167 | error = -1; | ||
168 | DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d", | ||
169 | access_type, bus->number, device); | ||
170 | } else if ((status >> 28) & 0xf) { | ||
171 | DBG("alchemy-pci: PCI ERR detected: dev %d, status %lx\n", | ||
172 | device, (status >> 28) & 0xf); | ||
173 | |||
174 | /* clear errors */ | ||
175 | __raw_writel(status & 0xf000ffff, ctx->regs + PCI_REG_STATCMD); | ||
176 | |||
177 | *data = 0xffffffff; | ||
178 | error = -1; | ||
179 | } | ||
180 | |||
181 | /* Take away the IDSEL. */ | ||
182 | (void)ctx->board_pci_idsel(device, 0); | ||
183 | |||
184 | local_irq_restore(flags); | ||
185 | return error; | ||
186 | } | ||
187 | |||
188 | static int read_config_byte(struct pci_bus *bus, unsigned int devfn, | ||
189 | int where, u8 *val) | ||
190 | { | ||
191 | u32 data; | ||
192 | int ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); | ||
193 | |||
194 | if (where & 1) | ||
195 | data >>= 8; | ||
196 | if (where & 2) | ||
197 | data >>= 16; | ||
198 | *val = data & 0xff; | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | static int read_config_word(struct pci_bus *bus, unsigned int devfn, | ||
203 | int where, u16 *val) | ||
204 | { | ||
205 | u32 data; | ||
206 | int ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); | ||
207 | |||
208 | if (where & 2) | ||
209 | data >>= 16; | ||
210 | *val = data & 0xffff; | ||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | static int read_config_dword(struct pci_bus *bus, unsigned int devfn, | ||
215 | int where, u32 *val) | ||
216 | { | ||
217 | return config_access(PCI_ACCESS_READ, bus, devfn, where, val); | ||
218 | } | ||
219 | |||
220 | static int write_config_byte(struct pci_bus *bus, unsigned int devfn, | ||
221 | int where, u8 val) | ||
222 | { | ||
223 | u32 data = 0; | ||
224 | |||
225 | if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) | ||
226 | return -1; | ||
227 | |||
228 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
229 | (val << ((where & 3) << 3)); | ||
230 | |||
231 | if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) | ||
232 | return -1; | ||
233 | |||
234 | return PCIBIOS_SUCCESSFUL; | ||
235 | } | ||
236 | |||
237 | static int write_config_word(struct pci_bus *bus, unsigned int devfn, | ||
238 | int where, u16 val) | ||
239 | { | ||
240 | u32 data = 0; | ||
241 | |||
242 | if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) | ||
243 | return -1; | ||
244 | |||
245 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
246 | (val << ((where & 3) << 3)); | ||
247 | |||
248 | if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) | ||
249 | return -1; | ||
250 | |||
251 | return PCIBIOS_SUCCESSFUL; | ||
252 | } | ||
253 | |||
254 | static int write_config_dword(struct pci_bus *bus, unsigned int devfn, | ||
255 | int where, u32 val) | ||
256 | { | ||
257 | return config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val); | ||
258 | } | ||
259 | |||
260 | static int alchemy_pci_read(struct pci_bus *bus, unsigned int devfn, | ||
261 | int where, int size, u32 *val) | ||
262 | { | ||
263 | switch (size) { | ||
264 | case 1: { | ||
265 | u8 _val; | ||
266 | int rc = read_config_byte(bus, devfn, where, &_val); | ||
267 | |||
268 | *val = _val; | ||
269 | return rc; | ||
270 | } | ||
271 | case 2: { | ||
272 | u16 _val; | ||
273 | int rc = read_config_word(bus, devfn, where, &_val); | ||
274 | |||
275 | *val = _val; | ||
276 | return rc; | ||
277 | } | ||
278 | default: | ||
279 | return read_config_dword(bus, devfn, where, val); | ||
280 | } | ||
281 | } | ||
282 | |||
283 | static int alchemy_pci_write(struct pci_bus *bus, unsigned int devfn, | ||
284 | int where, int size, u32 val) | ||
285 | { | ||
286 | switch (size) { | ||
287 | case 1: | ||
288 | return write_config_byte(bus, devfn, where, (u8) val); | ||
289 | case 2: | ||
290 | return write_config_word(bus, devfn, where, (u16) val); | ||
291 | default: | ||
292 | return write_config_dword(bus, devfn, where, val); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | static struct pci_ops alchemy_pci_ops = { | ||
297 | .read = alchemy_pci_read, | ||
298 | .write = alchemy_pci_write, | ||
299 | }; | ||
300 | |||
301 | static int alchemy_pci_def_idsel(unsigned int devsel, int assert) | ||
302 | { | ||
303 | return 1; /* success */ | ||
304 | } | ||
305 | |||
306 | static int __devinit alchemy_pci_probe(struct platform_device *pdev) | ||
307 | { | ||
308 | struct alchemy_pci_platdata *pd = pdev->dev.platform_data; | ||
309 | struct alchemy_pci_context *ctx; | ||
310 | void __iomem *virt_io; | ||
311 | unsigned long val; | ||
312 | struct resource *r; | ||
313 | int ret; | ||
314 | |||
315 | /* need at least PCI IRQ mapping table */ | ||
316 | if (!pd) { | ||
317 | dev_err(&pdev->dev, "need platform data for PCI setup\n"); | ||
318 | ret = -ENODEV; | ||
319 | goto out; | ||
320 | } | ||
321 | |||
322 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
323 | if (!ctx) { | ||
324 | dev_err(&pdev->dev, "no memory for pcictl context\n"); | ||
325 | ret = -ENOMEM; | ||
326 | goto out; | ||
327 | } | ||
328 | |||
329 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
330 | if (!r) { | ||
331 | dev_err(&pdev->dev, "no pcictl ctrl regs resource\n"); | ||
332 | ret = -ENODEV; | ||
333 | goto out1; | ||
334 | } | ||
335 | |||
336 | if (!request_mem_region(r->start, resource_size(r), pdev->name)) { | ||
337 | dev_err(&pdev->dev, "cannot claim pci regs\n"); | ||
338 | ret = -ENODEV; | ||
339 | goto out1; | ||
340 | } | ||
341 | |||
342 | ctx->regs = ioremap_nocache(r->start, resource_size(r)); | ||
343 | if (!ctx->regs) { | ||
344 | dev_err(&pdev->dev, "cannot map pci regs\n"); | ||
345 | ret = -ENODEV; | ||
346 | goto out2; | ||
347 | } | ||
348 | |||
349 | /* map parts of the PCI IO area */ | ||
350 | /* REVISIT: if this changes with a newer variant (doubt it) make this | ||
351 | * a platform resource. | ||
352 | */ | ||
353 | virt_io = ioremap(AU1500_PCI_IO_PHYS_ADDR, 0x00100000); | ||
354 | if (!virt_io) { | ||
355 | dev_err(&pdev->dev, "cannot remap pci io space\n"); | ||
356 | ret = -ENODEV; | ||
357 | goto out3; | ||
358 | } | ||
359 | ctx->alchemy_pci_ctrl.io_map_base = (unsigned long)virt_io; | ||
360 | |||
361 | #ifdef CONFIG_DMA_NONCOHERENT | ||
362 | /* Au1500 revisions older than AD have borked coherent PCI */ | ||
363 | if ((alchemy_get_cputype() == ALCHEMY_CPU_AU1500) && | ||
364 | (read_c0_prid() < 0x01030202)) { | ||
365 | val = __raw_readl(ctx->regs + PCI_REG_CONFIG); | ||
366 | val |= PCI_CONFIG_NC; | ||
367 | __raw_writel(val, ctx->regs + PCI_REG_CONFIG); | ||
368 | wmb(); | ||
369 | dev_info(&pdev->dev, "non-coherent PCI on Au1500 AA/AB/AC\n"); | ||
370 | } | ||
371 | #endif | ||
372 | |||
373 | if (pd->board_map_irq) | ||
374 | ctx->board_map_irq = pd->board_map_irq; | ||
375 | |||
376 | if (pd->board_pci_idsel) | ||
377 | ctx->board_pci_idsel = pd->board_pci_idsel; | ||
378 | else | ||
379 | ctx->board_pci_idsel = alchemy_pci_def_idsel; | ||
380 | |||
381 | /* fill in relevant pci_controller members */ | ||
382 | ctx->alchemy_pci_ctrl.pci_ops = &alchemy_pci_ops; | ||
383 | ctx->alchemy_pci_ctrl.mem_resource = &alchemy_pci_def_memres; | ||
384 | ctx->alchemy_pci_ctrl.io_resource = &alchemy_pci_def_iores; | ||
385 | |||
386 | /* we can't ioremap the entire pci config space because it's too large, | ||
387 | * nor can we dynamically ioremap it because some drivers use the | ||
388 | * PCI config routines from within atomic contex and that becomes a | ||
389 | * problem in get_vm_area(). Instead we use one wired TLB entry to | ||
390 | * handle all config accesses for all busses. | ||
391 | */ | ||
392 | ctx->pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP); | ||
393 | if (!ctx->pci_cfg_vm) { | ||
394 | dev_err(&pdev->dev, "unable to get vm area\n"); | ||
395 | ret = -ENOMEM; | ||
396 | goto out4; | ||
397 | } | ||
398 | ctx->wired_entry = 8192; /* impossibly high value */ | ||
399 | |||
400 | set_io_port_base((unsigned long)ctx->alchemy_pci_ctrl.io_map_base); | ||
401 | |||
402 | /* board may want to modify bits in the config register, do it now */ | ||
403 | val = __raw_readl(ctx->regs + PCI_REG_CONFIG); | ||
404 | val &= ~pd->pci_cfg_clr; | ||
405 | val |= pd->pci_cfg_set; | ||
406 | val &= ~PCI_CONFIG_PD; /* clear disable bit */ | ||
407 | __raw_writel(val, ctx->regs + PCI_REG_CONFIG); | ||
408 | wmb(); | ||
409 | |||
410 | platform_set_drvdata(pdev, ctx); | ||
411 | register_pci_controller(&ctx->alchemy_pci_ctrl); | ||
412 | |||
413 | return 0; | ||
414 | |||
415 | out4: | ||
416 | iounmap(virt_io); | ||
417 | out3: | ||
418 | iounmap(ctx->regs); | ||
419 | out2: | ||
420 | release_mem_region(r->start, resource_size(r)); | ||
421 | out1: | ||
422 | kfree(ctx); | ||
423 | out: | ||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | |||
428 | #ifdef CONFIG_PM | ||
429 | /* save PCI controller register contents. */ | ||
430 | static int alchemy_pci_suspend(struct device *dev) | ||
431 | { | ||
432 | struct alchemy_pci_context *ctx = dev_get_drvdata(dev); | ||
433 | |||
434 | ctx->pm[0] = __raw_readl(ctx->regs + PCI_REG_CMEM); | ||
435 | ctx->pm[1] = __raw_readl(ctx->regs + PCI_REG_CONFIG) & 0x0009ffff; | ||
436 | ctx->pm[2] = __raw_readl(ctx->regs + PCI_REG_B2BMASK_CCH); | ||
437 | ctx->pm[3] = __raw_readl(ctx->regs + PCI_REG_B2BBASE0_VID); | ||
438 | ctx->pm[4] = __raw_readl(ctx->regs + PCI_REG_B2BBASE1_SID); | ||
439 | ctx->pm[5] = __raw_readl(ctx->regs + PCI_REG_MWMASK_DEV); | ||
440 | ctx->pm[6] = __raw_readl(ctx->regs + PCI_REG_MWBASE_REV_CCL); | ||
441 | ctx->pm[7] = __raw_readl(ctx->regs + PCI_REG_ID); | ||
442 | ctx->pm[8] = __raw_readl(ctx->regs + PCI_REG_CLASSREV); | ||
443 | ctx->pm[9] = __raw_readl(ctx->regs + PCI_REG_PARAM); | ||
444 | ctx->pm[10] = __raw_readl(ctx->regs + PCI_REG_MBAR); | ||
445 | ctx->pm[11] = __raw_readl(ctx->regs + PCI_REG_TIMEOUT); | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int alchemy_pci_resume(struct device *dev) | ||
451 | { | ||
452 | struct alchemy_pci_context *ctx = dev_get_drvdata(dev); | ||
453 | |||
454 | __raw_writel(ctx->pm[0], ctx->regs + PCI_REG_CMEM); | ||
455 | __raw_writel(ctx->pm[2], ctx->regs + PCI_REG_B2BMASK_CCH); | ||
456 | __raw_writel(ctx->pm[3], ctx->regs + PCI_REG_B2BBASE0_VID); | ||
457 | __raw_writel(ctx->pm[4], ctx->regs + PCI_REG_B2BBASE1_SID); | ||
458 | __raw_writel(ctx->pm[5], ctx->regs + PCI_REG_MWMASK_DEV); | ||
459 | __raw_writel(ctx->pm[6], ctx->regs + PCI_REG_MWBASE_REV_CCL); | ||
460 | __raw_writel(ctx->pm[7], ctx->regs + PCI_REG_ID); | ||
461 | __raw_writel(ctx->pm[8], ctx->regs + PCI_REG_CLASSREV); | ||
462 | __raw_writel(ctx->pm[9], ctx->regs + PCI_REG_PARAM); | ||
463 | __raw_writel(ctx->pm[10], ctx->regs + PCI_REG_MBAR); | ||
464 | __raw_writel(ctx->pm[11], ctx->regs + PCI_REG_TIMEOUT); | ||
465 | wmb(); | ||
466 | __raw_writel(ctx->pm[1], ctx->regs + PCI_REG_CONFIG); | ||
467 | wmb(); | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static const struct dev_pm_ops alchemy_pci_pmops = { | ||
473 | .suspend = alchemy_pci_suspend, | ||
474 | .resume = alchemy_pci_resume, | ||
475 | }; | ||
476 | |||
477 | #define ALCHEMY_PCICTL_PM (&alchemy_pci_pmops) | ||
478 | |||
479 | #else | ||
480 | #define ALCHEMY_PCICTL_PM NULL | ||
481 | #endif | ||
482 | |||
483 | static struct platform_driver alchemy_pcictl_driver = { | ||
484 | .probe = alchemy_pci_probe, | ||
485 | .driver = { | ||
486 | .name = "alchemy-pci", | ||
487 | .owner = THIS_MODULE, | ||
488 | .pm = ALCHEMY_PCICTL_PM, | ||
489 | }, | ||
490 | }; | ||
491 | |||
492 | static int __init alchemy_pci_init(void) | ||
493 | { | ||
494 | /* Au1500/Au1550 have PCI */ | ||
495 | switch (alchemy_get_cputype()) { | ||
496 | case ALCHEMY_CPU_AU1500: | ||
497 | case ALCHEMY_CPU_AU1550: | ||
498 | return platform_driver_register(&alchemy_pcictl_driver); | ||
499 | } | ||
500 | return 0; | ||
501 | } | ||
502 | arch_initcall(alchemy_pci_init); | ||
503 | |||
504 | |||
505 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
506 | { | ||
507 | struct alchemy_pci_context *ctx = dev->sysdata; | ||
508 | if (ctx && ctx->board_map_irq) | ||
509 | return ctx->board_map_irq(dev, slot, pin); | ||
510 | return -1; | ||
511 | } | ||
512 | |||
513 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
514 | { | ||
515 | return 0; | ||
516 | } | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c index 0abfbe04ffc9..655308a4e1cd 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
15 | #include <asm/r4kcache.h> | 15 | #include <asm/r4kcache.h> |
16 | #include <asm/reboot.h> | 16 | #include <asm/reboot.h> |
17 | #include <asm/smp-ops.h> | ||
17 | #include <asm/time.h> | 18 | #include <asm/time.h> |
18 | 19 | ||
19 | #include <msp_prom.h> | 20 | #include <msp_prom.h> |
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c index 434d7b1a8c6a..b7f1d9c4a8a3 100644 --- a/arch/mips/pmc-sierra/yosemite/py-console.c +++ b/arch/mips/pmc-sierra/yosemite/py-console.c | |||
@@ -65,15 +65,11 @@ static unsigned char readb_outer_space(unsigned long long phys) | |||
65 | 65 | ||
66 | __asm__ __volatile__ ( | 66 | __asm__ __volatile__ ( |
67 | " .set mips3 \n" | 67 | " .set mips3 \n" |
68 | " .set push \n" | ||
69 | " .set noreorder \n" | ||
70 | " .set nomacro \n" | ||
71 | " ld %0, %1 \n" | 68 | " ld %0, %1 \n" |
72 | " .set pop \n" | ||
73 | " lbu %0, (%0) \n" | 69 | " lbu %0, (%0) \n" |
74 | " .set mips0 \n" | 70 | " .set mips0 \n" |
75 | : "=r" (res) | 71 | : "=r" (res) |
76 | : "R" (vaddr)); | 72 | : "m" (vaddr)); |
77 | 73 | ||
78 | write_c0_status(sr); | 74 | write_c0_status(sr); |
79 | ssnop_4(); | 75 | ssnop_4(); |
@@ -93,15 +89,11 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c) | |||
93 | 89 | ||
94 | __asm__ __volatile__ ( | 90 | __asm__ __volatile__ ( |
95 | " .set mips3 \n" | 91 | " .set mips3 \n" |
96 | " .set push \n" | ||
97 | " .set noreorder \n" | ||
98 | " .set nomacro \n" | ||
99 | " ld %0, %1 \n" | 92 | " ld %0, %1 \n" |
100 | " .set pop \n" | ||
101 | " sb %2, (%0) \n" | 93 | " sb %2, (%0) \n" |
102 | " .set mips0 \n" | 94 | " .set mips0 \n" |
103 | : "=&r" (tmp) | 95 | : "=&r" (tmp) |
104 | : "R" (vaddr), "r" (c)); | 96 | : "m" (vaddr), "r" (c)); |
105 | 97 | ||
106 | write_c0_status(sr); | 98 | write_c0_status(sr); |
107 | ssnop_4(); | 99 | ssnop_4(); |
diff --git a/arch/mips/pnx8550/common/prom.c b/arch/mips/pnx8550/common/prom.c index 32f70097c3c7..49639e8120d8 100644 --- a/arch/mips/pnx8550/common/prom.c +++ b/arch/mips/pnx8550/common/prom.c | |||
@@ -30,7 +30,7 @@ typedef struct | |||
30 | }t_env_var; | 30 | }t_env_var; |
31 | 31 | ||
32 | 32 | ||
33 | char * prom_getcmdline(void) | 33 | char * __init prom_getcmdline(void) |
34 | { | 34 | { |
35 | return &(arcs_cmdline[0]); | 35 | return &(arcs_cmdline[0]); |
36 | } | 36 | } |
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index b18b04e48577..f90dce315e04 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
@@ -337,12 +337,12 @@ static struct irq_chip bridge_irq_type = { | |||
337 | .irq_unmask = enable_bridge_irq, | 337 | .irq_unmask = enable_bridge_irq, |
338 | }; | 338 | }; |
339 | 339 | ||
340 | void __devinit register_bridge_irq(unsigned int irq) | 340 | void register_bridge_irq(unsigned int irq) |
341 | { | 341 | { |
342 | irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); | 342 | irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); |
343 | } | 343 | } |
344 | 344 | ||
345 | int __devinit request_bridge_irq(struct bridge_controller *bc) | 345 | int request_bridge_irq(struct bridge_controller *bc) |
346 | { | 346 | { |
347 | int irq = allocate_irqno(); | 347 | int irq = allocate_irqno(); |
348 | int swlevel, cpu; | 348 | int swlevel, cpu; |