aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-03 16:28:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-03 16:28:14 -0400
commitd6748066ad0e8b2514545998f8367ebb3906f299 (patch)
treef7a9bfd764a8fb781aeda0ef2249afbab42dddf7 /arch/mips
parentf04c045f8ce69c22bda9d99eb927276b776135fc (diff)
parent3ba1e543ab4b02640d396098f2f6a199560d5f2d (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/mips')
-rw-r--r--arch/mips/Kconfig5
-rw-r--r--arch/mips/Makefile4
-rw-r--r--arch/mips/alchemy/Kconfig50
-rw-r--r--arch/mips/alchemy/common/Makefile6
-rw-r--r--arch/mips/alchemy/common/dbdma.c203
-rw-r--r--arch/mips/alchemy/common/dma.c72
-rw-r--r--arch/mips/alchemy/common/gpiolib.c (renamed from arch/mips/alchemy/common/gpiolib-au1000.c)35
-rw-r--r--arch/mips/alchemy/common/pci.c104
-rw-r--r--arch/mips/alchemy/common/platform.c370
-rw-r--r--arch/mips/alchemy/common/power.c46
-rw-r--r--arch/mips/alchemy/common/setup.c6
-rw-r--r--arch/mips/alchemy/devboards/db1200/platform.c153
-rw-r--r--arch/mips/alchemy/devboards/db1x00/board_setup.c28
-rw-r--r--arch/mips/alchemy/devboards/db1x00/platform.c198
-rw-r--r--arch/mips/alchemy/devboards/pb1100/platform.c49
-rw-r--r--arch/mips/alchemy/devboards/pb1200/platform.c190
-rw-r--r--arch/mips/alchemy/devboards/pb1500/board_setup.c33
-rw-r--r--arch/mips/alchemy/devboards/pb1500/platform.c71
-rw-r--r--arch/mips/alchemy/devboards/pb1550/board_setup.c6
-rw-r--r--arch/mips/alchemy/devboards/pb1550/platform.c119
-rw-r--r--arch/mips/alchemy/gpr/board_setup.c12
-rw-r--r--arch/mips/alchemy/gpr/platform.c47
-rw-r--r--arch/mips/alchemy/mtx-1/board_setup.c40
-rw-r--r--arch/mips/alchemy/mtx-1/platform.c62
-rw-r--r--arch/mips/alchemy/xxs1500/board_setup.c8
-rw-r--r--arch/mips/alchemy/xxs1500/platform.c12
-rw-r--r--arch/mips/include/asm/cacheflush.h24
-rw-r--r--arch/mips/include/asm/cpu.h3
-rw-r--r--arch/mips/include/asm/io.h12
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1000.h559
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx.h43
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h116
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_ide.h1
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_psc.h26
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio-au1000.h31
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio.h79
-rw-r--r--arch/mips/include/asm/mach-db1x00/db1200.h2
-rw-r--r--arch/mips/include/asm/mach-db1x00/db1x00.h16
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1200.h18
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1550.h16
-rw-r--r--arch/mips/include/asm/mipsprom.h6
-rw-r--r--arch/mips/include/asm/mipsregs.h8
-rw-r--r--arch/mips/include/asm/prom.h6
-rw-r--r--arch/mips/include/asm/regdef.h6
-rw-r--r--arch/mips/jz4740/gpio.c140
-rw-r--r--arch/mips/jz4740/irq.c92
-rw-r--r--arch/mips/jz4740/irq.h6
-rw-r--r--arch/mips/jz4740/pm.c3
-rw-r--r--arch/mips/kernel/Makefile5
-rw-r--r--arch/mips/kernel/cpu-probe.c3
-rw-r--r--arch/mips/kernel/perf_event.c519
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c1241
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/mm/c-octeon.c6
-rw-r--r--arch/mips/mm/c-r3k.c7
-rw-r--r--arch/mips/mm/c-r4k.c35
-rw-r--r--arch/mips/mm/c-tx39.c7
-rw-r--r--arch/mips/mm/cache.c5
-rw-r--r--arch/mips/mm/tlb-r3k.c4
-rw-r--r--arch/mips/mm/tlb-r4k.c4
-rw-r--r--arch/mips/netlogic/Platform5
-rw-r--r--arch/mips/netlogic/xlr/setup.c4
-rw-r--r--arch/mips/netlogic/xlr/smp.c6
-rw-r--r--arch/mips/netlogic/xlr/smpboot.S16
-rw-r--r--arch/mips/pci/Makefile3
-rw-r--r--arch/mips/pci/fixup-au1000.c43
-rw-r--r--arch/mips/pci/ops-au1000.c308
-rw-r--r--arch/mips/pci/pci-alchemy.c516
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_setup.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/py-console.c12
-rw-r--r--arch/mips/pnx8550/common/prom.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c4
72 files changed, 3050 insertions, 2850 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4cbc6d8de21..62b9677c39a 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
51config AR7 53config 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
210config LANTIQ 213config LANTIQ
211 bool "Lantiq based platforms" 214 bool "Lantiq based platforms"
@@ -2092,7 +2095,7 @@ config NODES_SHIFT
2092 2095
2093config HW_PERF_EVENTS 2096config 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 53e3514ba10..9b4cb00407d 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -226,7 +226,7 @@ LDFLAGS += -m $(ld-emul)
226ifdef CONFIG_MIPS 226ifdef CONFIG_MIPS
227CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \ 227CHECKFLAGS += $(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/$$/'/")
230ifdef CONFIG_64BIT 230ifdef CONFIG_64BIT
231CHECKFLAGS += -m64 231CHECKFLAGS += -m64
232endif 232endif
@@ -295,7 +295,9 @@ endif
295 295
296install: 296install:
297 $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) 297 $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
298ifdef 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)
300endif
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 2ccfd4a135b..2a68be6a1b9 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
25config MIPS_BOSPORUS 25config 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
32config MIPS_DB1000 32config 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
40config MIPS_DB1100 40config 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
47config MIPS_DB1200 47config 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
55config MIPS_DB1500 55config 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
65config MIPS_DB1550 65config 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
74config MIPS_MIRAGE 74config 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
81config MIPS_PB1000 81config 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
90config MIPS_PB1100 90config 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
99config MIPS_PB1200 99config 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
107config MIPS_PB1500 107config 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
115config MIPS_PB1550 115config 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
124config MIPS_XXS1500 124config 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
131config MIPS_GPR 131config 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
140endchoice 140endchoice
141
142config SOC_AU1000
143 bool
144 select ALCHEMY_GPIOINT_AU1000
145
146config SOC_AU1100
147 bool
148 select ALCHEMY_GPIOINT_AU1000
149
150config SOC_AU1500
151 bool
152 select ALCHEMY_GPIOINT_AU1000
153
154config SOC_AU1550
155 bool
156 select ALCHEMY_GPIOINT_AU1000
157
158config SOC_AU1200
159 bool
160 select ALCHEMY_GPIOINT_AU1000
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index 27811fe341d..811ece7b22e 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
14ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) 14ifeq ($(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
18endif 16endif
19
20obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index 3a5abb54d50..0e63ee487d6 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);
63static int dbdma_initialized; 61static int dbdma_initialized;
64 62
65static dbdev_tab_t dbdev_tab[] = { 63static dbdev_tab_t *dbdev_tab;
66#ifdef CONFIG_SOC_AU1550 64
65static 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 }, 111static 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
180static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; 154static 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
1031static int __init au1xxx_dbdma_init(void) 1005static 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}
1063subsys_initcall(au1xxx_dbdma_init);
1064 1033
1065#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ 1034static 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}
1044subsys_initcall(alchemy_dbdma_init);
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c
index 347980e79a8..9b624e2c0fc 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
240static int __init au1000_dma_init(void) 238static 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
263out: 261out:
264 return 0; 262 return 0;
265} 263}
266arch_initcall(au1000_dma_init); 264arch_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 c8e1a94d4a9..91fb4d9e30f 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
39static int gpio2_get(struct gpio_chip *chip, unsigned offset) 39static 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
118static int __init alchemy_gpiolib_init(void) 118static 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}
126arch_initcall(alchemy_gpiolib_init); 133arch_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 7866cf50cf9..00000000000
--- 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 */
40static 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
47static 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
54extern struct pci_ops au1x_pci_ops;
55
56static 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)
63static unsigned long virt_io_addr;
64#endif
65
66static 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
104arch_initcall(au1x_pci_setup);
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index f72c48d4804..c8e5d72a582 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) */
115static 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 */
129static u64 ohci_dmamask = DMA_BIT_MASK(32);
130
131static 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
145static 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
158static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
159
160static 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) */
174static 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
187static u64 ehci_dmamask = DMA_BIT_MASK(32);
188
189static 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) */
201static 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
214static u64 udc_dmamask = DMA_BIT_MASK(32);
215 114
216static struct platform_device au1xxx_usb_gdt_device = { 115/* The dmamask must be set for OHCI/EHCI to work */
217 .name = "au1xxx-udc", 116static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
218 .id = 0, 117static 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) */ 119static unsigned long alchemy_ohci_data[][2] __initdata = {
228static 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
241static u64 uoc_dmamask = DMA_BIT_MASK(32); 127static unsigned long alchemy_ehci_data[][2] __initdata = {
242 128 [ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT },
243static 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
254static struct resource au1200_lcd_resources[] = { 131static 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
267static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
268
269static 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
280static 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
282extern struct au1xmmc_platform_data au1xmmc_platdata[2]; 146 return 0;
147}
283 148
284static struct resource au1200_mmc0_resources[] = { 149static 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
307static 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];
320static 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
343static 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
359static 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
367static 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
394static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { 216static 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
524static 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
544static int __init au1xxx_platform_init(void) 353static 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
556arch_initcall(au1xxx_platform_init); 364arch_initcall(au1xxx_platform_init);
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index b86324a4260..bdd6651e9a4 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 */
52static unsigned int sleep_usb[2];
53static unsigned int sleep_sys_clocks[5]; 50static unsigned int sleep_sys_clocks[5];
54static unsigned int sleep_sys_pinfunc; 51static unsigned int sleep_sys_pinfunc;
55static unsigned int sleep_static_memctlr[4][3]; 52static unsigned int sleep_static_memctlr[4][3];
@@ -57,31 +54,6 @@ static unsigned int sleep_static_memctlr[4][3];
57 54
58static void save_core_regs(void) 55static 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 1b887c86841..37ffd997c61 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 */
74phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) 74phys_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 dda090bf74e..c61867c93c4 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
219static u64 ide_dmamask = DMA_BIT_MASK(32); 224static 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 */ 336static struct au1xmmc_platform_data db1200mmc_platdata = {
332struct 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
344static 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
367static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
368
369static 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
383static 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
396static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
397
398static 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
344static struct resource au1200_psc0_res[] = { 411static 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
402static struct resource au1200_psc1_res[] = { 469static 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 = {
449static struct platform_device *db1200_devs[] __initdata = { 516static 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 5c956fe8760..7cd36e631f6 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
44char 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
53char 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
62char irq_tab_alchemy[][5] __initdata = { 44char 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
94char 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
100static void mirage_power_off(void) 76static 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 7057d28f730..9e6b3d442ac 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
31struct 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
95static 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
114static 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
141static 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
167static 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
186static 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
194static struct alchemy_pci_platdata db1xxx_pci_pd = {
195 .board_map_irq = db1xxx_map_pci_irq,
196};
197
198static 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
206static 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 */
211arch_initcall(db15x0_pci_init);
212#endif
213
214#ifdef CONFIG_MIPS_DB1100
215static 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
228static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
229
230static 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
91static struct resource alchemy_ac97c_res[] = { 242static 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 = {
130static int __init db1xxx_dev_init(void) 281static 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 2c8dc29759f..9c57c01a68c 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
30static 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
43static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
44
45static 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
28static int __init pb1100_dev_init(void) 56static 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 3ef2dceeb79..54f7f7b0676 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
91const struct au1xmmc_platform_data au1xmmc_platdata[2] = { 93static 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
110static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
111
112static 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
135static 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
147static 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
170static 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
108static struct resource ide_resources[] = { 183static 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
121static u64 ide_dmamask = DMA_BIT_MASK(32); 201static 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
244static 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
267static 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
274static 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
287static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
288
289static 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
164static struct platform_device *board_platform_devices[] __initdata = { 300static 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
169static int __init board_register_devices(void) 309static 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 3b4fa320696..37c1883b5ea 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
37char 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
43const char *get_system_type(void) 36const 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 d443bc7aa76..1e52a01bac0 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
29static 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
46static 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
54static 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
65static 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
27static int __init pb1500_dev_init(void) 73static 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}
49device_initcall(pb1500_dev_init); 94arch_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 b790213848b..0f62d1e3df2 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
41char 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
46const char *get_system_type(void) 40const 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 d7150d0f49c..a4604b8a349 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
31static 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
54static 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
62static struct alchemy_pci_platdata pb1550_pci_pd = {
63 .board_map_irq = pb1550_map_pci_irq,
64};
65
66static 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
74static 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
97static 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
29static int __init pb1550_dev_init(void) 104static 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}
69device_initcall(pb1550_dev_init); 140arch_initcall(pb1550_dev_init);
diff --git a/arch/mips/alchemy/gpr/board_setup.c b/arch/mips/alchemy/gpr/board_setup.c
index 5f8f0691ed2..dea45c78fdc 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
39char irq_tab_alchemy[][5] __initdata = {
40 [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff },
41};
42
43static void gpr_reset(char *c) 39static 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 14b46629cfc..982ce85db60 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
172static 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
180static 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
190static 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
201static 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
170static struct platform_device *gpr_devices[] __initdata = { 209static 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
216static 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 */
221arch_initcall(gpr_pci_init);
222
223
177static int __init gpr_dev_init(void) 224static 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 3ae984cf98c..851a5ab4c8f 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
41char 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
52extern int (*board_pci_idsel)(unsigned int devsel, int assert);
53int mtx1_pci_idsel(unsigned int devsel, int assert);
54
55static void mtx1_reset(char *c) 41static 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
107int
108mtx1_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
124static int __init mtx1_init_irq(void) 84static 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 55628e390fd..cc47b6868ca 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
138static 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
146static 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
162static 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
173static int mtx1_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
174{
175 return mtx1_irqtab[slot][pin];
176}
177
178static 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
190static 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
138static struct __initdata platform_device * mtx1_devs[] = { 199static 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 81e57fad07a..3fa83f72e01 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
83static int __init xxs1500_init_irq(void) 75static int __init xxs1500_init_irq(void)
diff --git a/arch/mips/alchemy/xxs1500/platform.c b/arch/mips/alchemy/xxs1500/platform.c
index e87c45cde61..06a3a459b8a 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 40bb9fde205..69468ded282 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);
114extern void *kmap_coherent(struct page *page, unsigned long addr); 114extern void *kmap_coherent(struct page *page, unsigned long addr);
115extern void kunmap_coherent(void); 115extern void kunmap_coherent(void);
116 116
117#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
118static 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 */
127extern void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
128
129static 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
135static 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 5f95a4bfc73..2f7f41873f2 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 b04e4de5dd2..a58f22998a8 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 f260ebed713..de24ec57dd2 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);
245void alchemy_sleep_au1550(void); 245void alchemy_sleep_au1550(void);
246void au_sleep(void); 246void au_sleep(void);
247 247
248/* USB: drivers/usb/host/alchemy-common.c */
249enum alchemy_usb_block {
250 ALCHEMY_USB_OHCI0,
251 ALCHEMY_USB_UDC0,
252 ALCHEMY_USB_EHCI0,
253 ALCHEMY_USB_OTG0,
254};
255int alchemy_usb_control(int block, int enable);
256
257/* PCI controller platform data */
258struct 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 1b3655090ed..00000000000
--- 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 2fdacfe85e2..323ce2d145f 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 5656c72de6d..e306384b141 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 5a5cb738642..4e3f3bc26c6 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 1f41a522906..73853b5a2a3 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 */
354static 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
363static inline void __alchemy_gpio2_mod_int(int gpio2, int en) 352static 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 c3f60cdc320..fcdc8c4809d 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 */
20static 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 */
56static 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 3404248f509..7a39657108c 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 a919dac525a..a5affb0568e 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 fce4332ebb7..374416adb65 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 f835c88e959..443b88adebf 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 146d41b67ad..e93943fabea 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
74extern char *prom_getenv(char *); 74extern 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 6a6f8a8f542..2ea7b817feb 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 857d9b7858a..7a6e82ef449 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);
25static inline void device_tree_init(void) { } 25static 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 7c8ecb6b9c4..785a5189b37 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 4397972949f..e1ddb95c05e 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 @@
77struct jz_gpio_chip { 77struct 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
103static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) 99static 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
108static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) 105static 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
332static void jz_gpio_irq_mask(struct irq_data *data)
333{
334 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET);
335};
336
337static void jz_gpio_irq_unmask(struct irq_data *data) 323static 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
354static void jz_gpio_irq_shutdown(struct irq_data *data) 339static 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
363static void jz_gpio_irq_ack(struct irq_data *data)
364{
365 jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR);
366};
367
368static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) 348static 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)
408static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) 388static 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
422static 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 */
438static 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
461static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip) 419static 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
468static 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
478static 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
486static 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
494static 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
499static 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
521static int __init jz4740_gpio_init(void) 459static 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 d82c0c430e0..fc57ded326d 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
34static void __iomem *jz_intc_base; 34static void __iomem *jz_intc_base;
35static uint32_t jz_intc_wakeup;
36static 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) 42static irqreturn_t jz4740_cascade(int irq, void *data)
45
46static 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
51static 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
56static 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
61static int intc_irq_set_wake(struct irq_data *data, unsigned int on) 54static 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
71static struct irq_chip intc_irq_type = { 62void 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
79static 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; 68void 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
91static struct irqaction jz4740_cascade_action = { 74static struct irqaction jz4740_cascade_action = {
@@ -95,7 +78,9 @@ static struct irqaction jz4740_cascade_action = {
95 78
96void __init arch_init_irq(void) 79void __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
125void 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
132void 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
140static inline void intc_seq_reg(struct seq_file *s, const char *name, 124static 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 56b5eadd1fa..f75e39d6288 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
18extern void jz4740_intc_suspend(void); 18#include <linux/irq.h>
19extern void jz4740_intc_resume(void); 19
20extern void jz4740_irq_suspend(struct irq_data *data);
21extern 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 902d5b50124..6744fa723f7 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
26static int jz4740_pm_enter(suspend_state_t state) 25static 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 83bba332bbf..1a966183e35 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 \
11ifdef CONFIG_FUNCTION_TRACER 11ifdef CONFIG_FUNCTION_TRACER
12CFLAGS_REMOVE_ftrace.o = -pg 12CFLAGS_REMOVE_ftrace.o = -pg
13CFLAGS_REMOVE_early_printk.o = -pg 13CFLAGS_REMOVE_early_printk.o = -pg
14CFLAGS_REMOVE_perf_event.o = -pg
15CFLAGS_REMOVE_perf_event_mipsxx.o = -pg
14endif 16endif
15 17
16obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o 18obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
@@ -106,7 +108,8 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
106 108
107obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ 109obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
108 110
109obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o 111obj-$(CONFIG_PERF_EVENTS) += perf_event.o
112obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o
110 113
111obj-$(CONFIG_JUMP_LABEL) += jump_label.o 114obj-$(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 ebc0cd20b35..aa327a75598 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)
978platform: 978platform:
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 0aee944ac38..c1cf9c6c3f7 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
37struct 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};
63DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
64 .saved_ctrl = {0},
65};
66
67/* The description of MIPS performance events. */
68struct 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
91static struct mips_perf_event raw_event;
92static DEFINE_MUTEX(raw_event_mutex);
93
94#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
95#define C(x) PERF_COUNT_HW_CACHE_##x
96
97struct 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
119static const struct mips_pmu *mipspmu;
120
121static int
122mipspmu_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
164static 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
174again:
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
197static 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
216static 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
232static 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
263out:
264 perf_pmu_enable(event->pmu);
265 return err;
266}
267
268static 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
283static 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
294static void mipspmu_enable(struct pmu *pmu)
295{
296 if (mipspmu)
297 mipspmu->start();
298}
299
300static void mipspmu_disable(struct pmu *pmu)
301{
302 if (mipspmu)
303 mipspmu->stop();
304}
305
306static atomic_t active_events = ATOMIC_INIT(0);
307static DEFINE_MUTEX(pmu_reserve_mutex);
308static int (*save_perf_irq)(void);
309
310static 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
339static 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 */
351static void reset_counters(void *arg);
352static int __hw_perf_event_init(struct perf_event *event);
353
354static 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
369static 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
412static 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
423static inline unsigned int
424mipspmu_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
440static const struct mips_perf_event *
441mipspmu_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
452static const struct mips_perf_event *
453mipspmu_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
482static 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
494static 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 */
516static void
517handle_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 */
540void perf_callchain_user(struct perf_callchain_entry *entry,
541 struct pt_regs *regs)
542{
543}
544 27
545static void save_raw_perf_callchain(struct perf_callchain_entry *entry, 28static 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 e5ad09a9baf..4f2971bcf8e 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
32struct 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};
49DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
50 .saved_ctrl = {0},
51};
52
53/* The description of MIPS performance events. */
54struct 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
78static struct mips_perf_event raw_event;
79static DEFINE_MUTEX(raw_event_mutex);
80
81#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
82#define C(x) PERF_COUNT_HW_CACHE_##x
83
84struct 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
101static 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
37static int cpu_has_mipsmt_pertccounters; 135static int cpu_has_mipsmt_pertccounters;
38 136
137static 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 */
52static inline unsigned int vpe_shift(void) 152static 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
62static inline unsigned int vpe_shift(void) 160static unsigned int counters_total_to_per_cpu(unsigned int counters)
63{
64 return 0;
65}
66#endif /* CONFIG_MIPS_MT_SMP */
67
68static inline unsigned int
69counters_total_to_per_cpu(unsigned int counters)
70{ 161{
71 return counters >> vpe_shift(); 162 return counters >> vpe_shift();
72} 163}
73 164
74static inline unsigned int 165static unsigned int counters_per_cpu_to_total(unsigned int counters)
75counters_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
82static 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 \
97static 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
124static 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
138static inline int n_counters(void) 175static void resume_local_counters(void);
139{ 176static void pause_local_counters(void);
140 int counters; 177static irqreturn_t mipsxx_pmu_handle_irq(int, void *);
178static int mipsxx_pmu_handle_shared_irq(void);
141 179
142 switch (current_cpu_type()) { 180static 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: 187static 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
159static void reset_counters(void *arg) 210static 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
178static inline u64 229static void mipsxx_pmu_write_counter(unsigned int idx, u64 val)
179mipsxx_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
196static inline void 249static void mipsxx_pmu_write_counter_64(unsigned int idx, u64 val)
197mipsxx_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
215static inline unsigned int 269static unsigned int mipsxx_pmu_read_control(unsigned int idx)
216mipsxx_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
233static inline void 288static void mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
234mipsxx_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
308static 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
338static 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
353static 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
367static 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
403static 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
410again:
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
424static 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
440static 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
453static 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
484out:
485 perf_pmu_enable(event->pmu);
486 return err;
487}
488
489static 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
504static 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
515static 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 */
534static 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
542static atomic_t active_events = ATOMIC_INIT(0);
543static DEFINE_MUTEX(pmu_reserve_mutex);
544static int (*save_perf_irq)(void);
545
546static 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
575static 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 */
587static void reset_counters(void *arg);
588static int __hw_perf_event_init(struct perf_event *event);
589
590static 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
605static 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
648static 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
659static 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
253static 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
675static 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
686static 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
715static 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
727static 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 */
749static 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
766static 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
780static 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
801static 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. */
257static const struct mips_perf_event mipsxxcore_event_map 821static 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
844static 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. */
281static const struct mips_perf_event mipsxxcore_cache_map 855static 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
1088static 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
514static void 1184static void check_and_calc_range(struct perf_event *event,
515check_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
539static void 1208static void check_and_calc_range(struct perf_event *event,
540check_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
625static void pause_local_counters(void) 1292static 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
653static void resume_local_counters(void) 1308static 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
673static int mipsxx_pmu_handle_shared_irq(void) 1319static 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
736static irqreturn_t 1377static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
737mipsxx_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
742static 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 */
761static 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
769static int
770mipsxx_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
800static void
801mipsxx_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
819static void
820mipsxx_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 */
895static const struct mips_perf_event * 1443static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
896mipsxx_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
973static struct mips_pmu mipsxxcore_pmu = { 1520static 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
988static 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
1003static int __init 1553static int __init
1004init_hw_perf_events(void) 1554init_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}
1080early_initcall(init_hw_perf_events); 1655early_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 865bc7a6f5a..47920657968 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 16c4d256b76..daa81f7284a 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
172static 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 e6b0efd3f6a..0765583d0c9 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
302static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size)
303{
304 BUG();
305}
306
302static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) 307static 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 b9aabb998a3..a79fe9aa772 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
725struct flush_kernel_vmap_range_args {
726 unsigned long vaddr;
727 int size;
728};
729
730static 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
748static 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
725static inline void rm7k_erratum31(void) 758static 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 d352fad3e45..a43c197ccf8 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
256static void tx39_flush_kernel_vmap_range(unsigned long vaddr, int size)
257{
258 BUG();
259}
260
256static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) 261static 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 12af739048f..829320c7b17 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);
35void (*__flush_cache_vmap)(void); 35void (*__flush_cache_vmap)(void);
36void (*__flush_cache_vunmap)(void); 36void (*__flush_cache_vunmap)(void);
37 37
38void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
39void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
40
41EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
42
38/* MIPS specific cache operations */ 43/* MIPS specific cache operations */
39void (*flush_cache_sigtramp)(unsigned long addr); 44void (*flush_cache_sigtramp)(unsigned long addr);
40void (*local_flush_data_cache_page)(void * addr); 45void (*local_flush_data_cache_page)(void * addr);
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c
index 40424affef8..87bb85d8d53 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
226void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, 226void 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 ba40325caea..0d394e0e883 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
340void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, 340void 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 f87c1640abb..b648b487fd6 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
5cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic 5cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic
6 6
7# 7#
8# use mips64 if xlr is not available
9#
10cflags-$(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#
10core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/ 15core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
index 482802569e7..cee25ddd088 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);
53unsigned long nlm_common_ebase = 0x0; 53unsigned long nlm_common_ebase = 0x0;
54struct psb_info nlm_prom_info; 54struct psb_info nlm_prom_info;
55 55
56static void nlm_early_serial_setup(void) 56static 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
104static void build_arcs_cmdline(int *argv) 104static 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 d842bce5c94..080284ded50 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
192unsigned long secondary_entry_point; 196unsigned long secondary_entry_point;
193 197
194int nlm_wakeup_secondary_cpus(u32 wakeup_mask) 198int __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 b8e074402c9..8cb7889ce0c 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
46NESTED(prom_pre_boot_secondary_cpus, 16, sp) 48NESTED(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
75END(prom_pre_boot_secondary_cpus) 77END(prom_pre_boot_secondary_cpus)
78 __FINIT
76 79
80/*
81 * NMI code, used for CPU wakeup, copied to reset entry
82 */
77NESTED(nlm_boot_smp_nmi, 0, sp) 83NESTED(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 4df87993744..bb82cbdbc62 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -18,14 +18,13 @@ obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o
18obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o 18obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ 19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
20 ops-bcm63xx.o 20 ops-bcm63xx.o
21obj-$(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#
25obj-$(CONFIG_LASAT) += pci-lasat.o 26obj-$(CONFIG_LASAT) += pci-lasat.o
26obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o 27obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
27obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
28obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
29obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o 28obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
30obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o 29obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o
31obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o 30obj-$(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 e2ddfc49237..00000000000
--- 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
32extern char irq_tab_alchemy[][5];
33
34int __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 */
40int 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 9a57c5ab91d..00000000000
--- 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
49int (*board_pci_idsel)(unsigned int devsel, int assert);
50
51void 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
71static struct vm_struct *pci_cfg_vm;
72static int pci_cfg_wired_entry;
73static 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 */
82void __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
93static 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
189static 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
204static 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
217static 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
226static 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
243static 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
260static 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
269static 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
292static 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
305struct 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 00000000000..4ee57104e47
--- /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
28struct 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 */
46static 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
53static 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
60static 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
80static 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
87static 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
188static 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
202static 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
214static 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
220static 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
237static 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
254static 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
260static 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
283static 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
296static struct pci_ops alchemy_pci_ops = {
297 .read = alchemy_pci_read,
298 .write = alchemy_pci_write,
299};
300
301static int alchemy_pci_def_idsel(unsigned int devsel, int assert)
302{
303 return 1; /* success */
304}
305
306static 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
415out4:
416 iounmap(virt_io);
417out3:
418 iounmap(ctx->regs);
419out2:
420 release_mem_region(r->start, resource_size(r));
421out1:
422 kfree(ctx);
423out:
424 return ret;
425}
426
427
428#ifdef CONFIG_PM
429/* save PCI controller register contents. */
430static 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
450static 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
472static 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
483static 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
492static 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}
502arch_initcall(alchemy_pci_init);
503
504
505int __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
513int 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 0abfbe04ffc..655308a4e1c 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 434d7b1a8c6..b7f1d9c4a8a 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 32f70097c3c..49639e8120d 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
33char * prom_getcmdline(void) 33char * __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 b18b04e4857..f90dce315e0 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
340void __devinit register_bridge_irq(unsigned int irq) 340void 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
345int __devinit request_bridge_irq(struct bridge_controller *bc) 345int 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;