aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy/common
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/mips/alchemy/common
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/mips/alchemy/common')
-rw-r--r--arch/mips/alchemy/common/Makefile10
-rw-r--r--arch/mips/alchemy/common/dbdma.c238
-rw-r--r--arch/mips/alchemy/common/dma.c72
-rw-r--r--arch/mips/alchemy/common/gpiolib.c175
-rw-r--r--arch/mips/alchemy/common/irq.c875
-rw-r--r--arch/mips/alchemy/common/platform.c431
-rw-r--r--arch/mips/alchemy/common/power.c49
-rw-r--r--arch/mips/alchemy/common/setup.c6
-rw-r--r--arch/mips/alchemy/common/sleeper.S73
-rw-r--r--arch/mips/alchemy/common/time.c30
-rw-r--r--arch/mips/alchemy/common/usb.c614
-rw-r--r--arch/mips/alchemy/common/vss.c84
12 files changed, 759 insertions, 1898 deletions
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index cb83d8d21ae..27811fe341d 100644
--- a/arch/mips/alchemy/common/Makefile
+++ b/arch/mips/alchemy/common/Makefile
@@ -6,9 +6,15 @@
6# 6#
7 7
8obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ 8obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
9 sleeper.o dma.o dbdma.o vss.o irq.o usb.o 9 sleeper.o dma.o dbdma.o
10
11obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o
10 12
11# optional gpiolib support 13# optional gpiolib support
12ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) 14ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
13 obj-$(CONFIG_GPIOLIB) += gpiolib.o 15 ifeq ($(CONFIG_GPIOLIB),y)
16 obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o
17 endif
14endif 18endif
19
20obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index cf02d7dc2df..3a5abb54d50 100644
--- a/arch/mips/alchemy/common/dbdma.c
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -40,6 +40,8 @@
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
43/* 45/*
44 * The Descriptor Based DMA supports up to 16 channels. 46 * The Descriptor Based DMA supports up to 16 channels.
45 * 47 *
@@ -60,140 +62,120 @@ static dbdma_global_t *dbdma_gptr =
60 (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); 62 (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
61static int dbdma_initialized; 63static int dbdma_initialized;
62 64
63static dbdev_tab_t *dbdev_tab; 65static dbdev_tab_t dbdev_tab[] = {
64 66#ifdef CONFIG_SOC_AU1550
65static dbdev_tab_t au1550_dbdev_tab[] __initdata = {
66 /* UARTS */ 67 /* UARTS */
67 { AU1550_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, 68 { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
68 { AU1550_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, 69 { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
69 { AU1550_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 }, 70 { DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 },
70 { AU1550_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 }, 71 { DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 },
71 72
72 /* EXT DMA */ 73 /* EXT DMA */
73 { AU1550_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, 74 { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
74 { AU1550_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, 75 { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
75 { AU1550_DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 }, 76 { DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 },
76 { AU1550_DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 }, 77 { DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 },
77 78
78 /* USB DEV */ 79 /* USB DEV */
79 { AU1550_DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 }, 80 { DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 },
80 { AU1550_DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 }, 81 { DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 },
81 { AU1550_DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 }, 82 { DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 },
82 { AU1550_DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 }, 83 { DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 },
83 { AU1550_DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 }, 84 { DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 },
84 { AU1550_DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 }, 85 { DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 },
85
86 /* PSCs */
87 { AU1550_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
88 { AU1550_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
89 { AU1550_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
90 { AU1550_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
91 { AU1550_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 },
92 { AU1550_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 },
93 { AU1550_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 },
94 { AU1550_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 },
95
96 { AU1550_DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */
97 { AU1550_DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */
98
99 /* MAC 0 */
100 { AU1550_DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
101 { AU1550_DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
102
103 /* MAC 1 */
104 { AU1550_DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
105 { AU1550_DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
106
107 { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
108 { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
109};
110 86
111static dbdev_tab_t au1200_dbdev_tab[] __initdata = { 87 /* PSC 0 */
112 { AU1200_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, 88 { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
113 { AU1200_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, 89 { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 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 },
116 90
117 { AU1200_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, 91 /* PSC 1 */
118 { AU1200_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, 92 { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
93 { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
119 94
120 { AU1200_DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 95 /* PSC 2 */
121 { AU1200_DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 96 { DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 },
122 { AU1200_DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 97 { DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 },
123 { AU1200_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
124 98
125 { AU1200_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, 99 /* PSC 3 */
126 { AU1200_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, 100 { DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 },
127 { AU1200_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, 101 { DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 },
128 { AU1200_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
129 102
130 { AU1200_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, 103 { DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */
131 { AU1200_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, 104 { DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */
132 105
133 { AU1200_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 }, 106 /* MAC 0 */
134 { AU1200_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 }, 107 { DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
135 { AU1200_DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 108 { DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 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 },
139 109
140 { AU1200_DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, 110 /* MAC 1 */
141 { AU1200_DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, 111 { DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
142 { AU1200_DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, 112 { DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
143 { AU1200_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
144 113
145 { AU1200_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, 114#endif /* CONFIG_SOC_AU1550 */
146 115
147 { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 116#ifdef CONFIG_SOC_AU1200
148 { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 117 { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
149}; 118 { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
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 },
150 121
151static dbdev_tab_t au1300_dbdev_tab[] __initdata = { 122 { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
152 { AU1300_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x10100004, 0, 0 }, 123 { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
153 { AU1300_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x10100000, 0, 0 },
154 { AU1300_DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x10101004, 0, 0 },
155 { AU1300_DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x10101000, 0, 0 },
156 { AU1300_DSCR_CMD0_UART2_TX, DEV_FLAGS_OUT, 0, 8, 0x10102004, 0, 0 },
157 { AU1300_DSCR_CMD0_UART2_RX, DEV_FLAGS_IN, 0, 8, 0x10102000, 0, 0 },
158 { AU1300_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x10103004, 0, 0 },
159 { AU1300_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x10103000, 0, 0 },
160 124
161 { AU1300_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, 125 { DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
162 { AU1300_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, 126 { DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
163 { AU1300_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 8, 8, 0x10601000, 0, 0 }, 127 { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
164 { AU1300_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 8, 8, 0x10601004, 0, 0 }, 128 { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
165 129
166 { AU1300_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, 130 { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
167 { AU1300_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, 131 { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 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 },
168 134
169 { AU1300_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0001c, 0, 0 }, 135 { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
170 { AU1300_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x10a0001c, 0, 0 }, 136 { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
171 { AU1300_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0101c, 0, 0 },
172 { AU1300_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x10a0101c, 0, 0 },
173 { AU1300_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0201c, 0, 0 },
174 { AU1300_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 16, 0x10a0201c, 0, 0 },
175 { AU1300_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0301c, 0, 0 },
176 { AU1300_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 16, 0x10a0301c, 0, 0 },
177 137
178 { AU1300_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 138 { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 },
179 { AU1300_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, 139 { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 },
140 { DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
180 141
181 { AU1300_DSCR_CMD0_SDMS_TX2, DEV_FLAGS_OUT, 4, 8, 0x10602000, 0, 0 }, 142 { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 },
182 { AU1300_DSCR_CMD0_SDMS_RX2, DEV_FLAGS_IN, 4, 8, 0x10602004, 0, 0 }, 143 { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 },
144 { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
183 145
184 { AU1300_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 146 { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
147 { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
148 { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
149 { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
185 150
186 { AU1300_DSCR_CMD0_UDMA, DEV_FLAGS_ANYUSE, 0, 32, 0x14001810, 0, 0 }, 151 { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
187 152
188 { AU1300_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, 153#endif /* CONFIG_SOC_AU1200 */
189 { AU1300_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
190 154
191 { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 155 { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
192 { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, 156 { 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 },
193}; 175};
194 176
195/* 32 predefined plus 32 custom */ 177#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
196#define DBDEV_TAB_SIZE 64 178
197 179
198static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; 180static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
199 181
@@ -1046,44 +1028,38 @@ static struct syscore_ops alchemy_dbdma_syscore_ops = {
1046 .resume = alchemy_dbdma_resume, 1028 .resume = alchemy_dbdma_resume,
1047}; 1029};
1048 1030
1049static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) 1031static int __init au1xxx_dbdma_init(void)
1050{ 1032{
1051 int ret; 1033 int irq_nr, ret;
1052
1053 dbdev_tab = kzalloc(sizeof(dbdev_tab_t) * DBDEV_TAB_SIZE, GFP_KERNEL);
1054 if (!dbdev_tab)
1055 return -ENOMEM;
1056
1057 memcpy(dbdev_tab, idtable, 32 * sizeof(dbdev_tab_t));
1058 for (ret = 32; ret < DBDEV_TAB_SIZE; ret++)
1059 dbdev_tab[ret].dev_id = ~0;
1060 1034
1061 dbdma_gptr->ddma_config = 0; 1035 dbdma_gptr->ddma_config = 0;
1062 dbdma_gptr->ddma_throttle = 0; 1036 dbdma_gptr->ddma_throttle = 0;
1063 dbdma_gptr->ddma_inten = 0xffff; 1037 dbdma_gptr->ddma_inten = 0xffff;
1064 au_sync(); 1038 au_sync();
1065 1039
1066 ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr); 1040 switch (alchemy_get_cputype()) {
1041 case ALCHEMY_CPU_AU1550:
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);
1067 if (ret) 1053 if (ret)
1068 printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); 1054 printk(KERN_ERR "Cannot grab DBDMA interrupt!\n");
1069 else { 1055 else {
1070 dbdma_initialized = 1; 1056 dbdma_initialized = 1;
1057 printk(KERN_INFO "Alchemy DBDMA initialized\n");
1071 register_syscore_ops(&alchemy_dbdma_syscore_ops); 1058 register_syscore_ops(&alchemy_dbdma_syscore_ops);
1072 } 1059 }
1073 1060
1074 return ret; 1061 return ret;
1075} 1062}
1063subsys_initcall(au1xxx_dbdma_init);
1076 1064
1077static int __init alchemy_dbdma_init(void) 1065#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
1078{
1079 switch (alchemy_get_cputype()) {
1080 case ALCHEMY_CPU_AU1550:
1081 return dbdma_setup(AU1550_DDMA_INT, au1550_dbdev_tab);
1082 case ALCHEMY_CPU_AU1200:
1083 return dbdma_setup(AU1200_DDMA_INT, au1200_dbdev_tab);
1084 case ALCHEMY_CPU_AU1300:
1085 return dbdma_setup(AU1300_DDMA_INT, au1300_dbdev_tab);
1086 }
1087 return 0;
1088}
1089subsys_initcall(alchemy_dbdma_init);
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c
index 9b624e2c0fc..347980e79a8 100644
--- a/arch/mips/alchemy/common/dma.c
+++ b/arch/mips/alchemy/common/dma.c
@@ -40,6 +40,8 @@
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)
43/* 45/*
44 * A note on resource allocation: 46 * A note on resource allocation:
45 * 47 *
@@ -86,12 +88,12 @@ static const struct dma_dev {
86 { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ 88 { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */
87 { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ 89 { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */
88 { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */ 90 { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */
89 { AU1000_USB_UDC_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ 91 { AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */
90 { AU1000_USB_UDC_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ 92 { AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */
91 { AU1000_USB_UDC_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ 93 { AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */
92 { AU1000_USB_UDC_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ 94 { AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */
93 { AU1000_USB_UDC_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ 95 { AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */
94 { AU1000_USB_UDC_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */ 96 { AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */
95 /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ 97 /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */
96 { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ 98 { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */
97 { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ 99 { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */
@@ -168,13 +170,13 @@ int request_au1000_dma(int dev_id, const char *dev_str,
168 const struct dma_dev *dev; 170 const struct dma_dev *dev;
169 int i, ret; 171 int i, ret;
170 172
171 if (alchemy_get_cputype() == ALCHEMY_CPU_AU1100) { 173#if defined(CONFIG_SOC_AU1100)
172 if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2)) 174 if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
173 return -EINVAL; 175 return -EINVAL;
174 } else { 176#else
175 if (dev_id < 0 || dev_id >= DMA_NUM_DEV) 177 if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
176 return -EINVAL; 178 return -EINVAL;
177 } 179#endif
178 180
179 for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) 181 for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
180 if (au1000_dma_table[i].dev_id < 0) 182 if (au1000_dma_table[i].dev_id < 0)
@@ -237,28 +239,30 @@ EXPORT_SYMBOL(free_au1000_dma);
237 239
238static int __init au1000_dma_init(void) 240static int __init au1000_dma_init(void)
239{ 241{
240 int base, i; 242 int base, i;
241 243
242 switch (alchemy_get_cputype()) { 244 switch (alchemy_get_cputype()) {
243 case ALCHEMY_CPU_AU1000: 245 case ALCHEMY_CPU_AU1000:
244 base = AU1000_DMA_INT_BASE; 246 base = AU1000_DMA_INT_BASE;
245 break; 247 break;
246 case ALCHEMY_CPU_AU1500: 248 case ALCHEMY_CPU_AU1500:
247 base = AU1500_DMA_INT_BASE; 249 base = AU1500_DMA_INT_BASE;
248 break; 250 break;
249 case ALCHEMY_CPU_AU1100: 251 case ALCHEMY_CPU_AU1100:
250 base = AU1100_DMA_INT_BASE; 252 base = AU1100_DMA_INT_BASE;
251 break; 253 break;
252 default: 254 default:
253 goto out; 255 goto out;
254 } 256 }
255 257
256 for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) 258 for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
257 au1000_dma_table[i].irq = base + i; 259 au1000_dma_table[i].irq = base + i;
258 260
259 printk(KERN_INFO "Alchemy DMA initialized\n"); 261 printk(KERN_INFO "Alchemy DMA initialized\n");
260 262
261out: 263out:
262 return 0; 264 return 0;
263} 265}
264arch_initcall(au1000_dma_init); 266arch_initcall(au1000_dma_init);
267
268#endif /* AU1000 AU1500 AU1100 */
diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c
deleted file mode 100644
index f1b50f0c01d..00000000000
--- a/arch/mips/alchemy/common/gpiolib.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/*
2 * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
3 * GPIOLIB support for Alchemy chips.
4 *
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
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Notes :
26 * This file must ONLY be built when CONFIG_GPIOLIB=y and
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
30 * Au1300 is totally different: 1 block with up to 128 GPIOs
31 */
32
33#include <linux/init.h>
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/types.h>
37#include <linux/gpio.h>
38#include <asm/mach-au1x00/gpio-au1000.h>
39#include <asm/mach-au1x00/gpio-au1300.h>
40
41static int gpio2_get(struct gpio_chip *chip, unsigned offset)
42{
43 return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
44}
45
46static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
47{
48 alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value);
49}
50
51static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
52{
53 return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE);
54}
55
56static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset,
57 int value)
58{
59 return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE,
60 value);
61}
62
63static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
64{
65 return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE);
66}
67
68
69static int gpio1_get(struct gpio_chip *chip, unsigned offset)
70{
71 return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
72}
73
74static void gpio1_set(struct gpio_chip *chip,
75 unsigned offset, int value)
76{
77 alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value);
78}
79
80static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
81{
82 return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE);
83}
84
85static int gpio1_direction_output(struct gpio_chip *chip,
86 unsigned offset, int value)
87{
88 return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE,
89 value);
90}
91
92static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset)
93{
94 return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE);
95}
96
97struct gpio_chip alchemy_gpio_chip[] = {
98 [0] = {
99 .label = "alchemy-gpio1",
100 .direction_input = gpio1_direction_input,
101 .direction_output = gpio1_direction_output,
102 .get = gpio1_get,
103 .set = gpio1_set,
104 .to_irq = gpio1_to_irq,
105 .base = ALCHEMY_GPIO1_BASE,
106 .ngpio = ALCHEMY_GPIO1_NUM,
107 },
108 [1] = {
109 .label = "alchemy-gpio2",
110 .direction_input = gpio2_direction_input,
111 .direction_output = gpio2_direction_output,
112 .get = gpio2_get,
113 .set = gpio2_set,
114 .to_irq = gpio2_to_irq,
115 .base = ALCHEMY_GPIO2_BASE,
116 .ngpio = ALCHEMY_GPIO2_NUM,
117 },
118};
119
120static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
121{
122 return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
123}
124
125static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
126{
127 au1300_gpio_set_value(off + AU1300_GPIO_BASE, v);
128}
129
130static int alchemy_gpic_dir_input(struct gpio_chip *chip, unsigned int off)
131{
132 return au1300_gpio_direction_input(off + AU1300_GPIO_BASE);
133}
134
135static int alchemy_gpic_dir_output(struct gpio_chip *chip, unsigned int off,
136 int v)
137{
138 return au1300_gpio_direction_output(off + AU1300_GPIO_BASE, v);
139}
140
141static int alchemy_gpic_gpio_to_irq(struct gpio_chip *chip, unsigned int off)
142{
143 return au1300_gpio_to_irq(off + AU1300_GPIO_BASE);
144}
145
146static struct gpio_chip au1300_gpiochip = {
147 .label = "alchemy-gpic",
148 .direction_input = alchemy_gpic_dir_input,
149 .direction_output = alchemy_gpic_dir_output,
150 .get = alchemy_gpic_get,
151 .set = alchemy_gpic_set,
152 .to_irq = alchemy_gpic_gpio_to_irq,
153 .base = AU1300_GPIO_BASE,
154 .ngpio = AU1300_GPIO_NUM,
155};
156
157static int __init alchemy_gpiochip_init(void)
158{
159 int ret = 0;
160
161 switch (alchemy_get_cputype()) {
162 case ALCHEMY_CPU_AU1000:
163 ret = gpiochip_add(&alchemy_gpio_chip[0]);
164 break;
165 case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200:
166 ret = gpiochip_add(&alchemy_gpio_chip[0]);
167 ret |= gpiochip_add(&alchemy_gpio_chip[1]);
168 break;
169 case ALCHEMY_CPU_AU1300:
170 ret = gpiochip_add(&au1300_gpiochip);
171 break;
172 }
173 return ret;
174}
175arch_initcall(alchemy_gpiochip_init);
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index 94fbcd19eb9..8b60ba0675e 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -25,15 +25,19 @@
25 * 675 Mass Ave, Cambridge, MA 02139, USA. 25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */ 26 */
27 27
28#include <linux/export.h> 28#include <linux/bitops.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/irq.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
32#include <linux/syscore_ops.h> 33#include <linux/syscore_ops.h>
33 34
34#include <asm/irq_cpu.h> 35#include <asm/irq_cpu.h>
36#include <asm/mipsregs.h>
35#include <asm/mach-au1x00/au1000.h> 37#include <asm/mach-au1x00/au1000.h>
36#include <asm/mach-au1x00/gpio-au1300.h> 38#ifdef CONFIG_MIPS_PB1000
39#include <asm/mach-pb1x00/pb1000.h>
40#endif
37 41
38/* Interrupt Controller register offsets */ 42/* Interrupt Controller register offsets */
39#define IC_CFG0RD 0x40 43#define IC_CFG0RD 0x40
@@ -65,17 +69,7 @@
65#define IC_FALLINGCLR 0x7C 69#define IC_FALLINGCLR 0x7C
66#define IC_TESTBIT 0x80 70#define IC_TESTBIT 0x80
67 71
68/* per-processor fixed function irqs */ 72static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
69struct alchemy_irqmap {
70 int irq; /* linux IRQ number */
71 int type; /* IRQ_TYPE_ */
72 int prio; /* irq priority, 0 highest, 3 lowest */
73 int internal; /* GPIC: internal source (no ext. pin)? */
74};
75
76static int au1x_ic_settype(struct irq_data *d, unsigned int type);
77static int au1300_gpic_settype(struct irq_data *d, unsigned int type);
78
79 73
80/* NOTE on interrupt priorities: The original writers of this code said: 74/* NOTE on interrupt priorities: The original writers of this code said:
81 * 75 *
@@ -83,207 +77,176 @@ static int au1300_gpic_settype(struct irq_data *d, unsigned int type);
83 * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT) 77 * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
84 * needs the highest priority. 78 * needs the highest priority.
85 */ 79 */
86struct alchemy_irqmap au1000_irqmap[] __initdata = { 80
87 { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 81/* per-processor fixed function irqs */
88 { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 82struct au1xxx_irqmap {
89 { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 83 int im_irq;
90 { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 84 int im_type;
91 { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 85 int im_request; /* set 1 to get higher priority */
92 { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
93 { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
94 { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
95 { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
96 { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
97 { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
98 { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
99 { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
100 { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
101 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
102 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
103 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
104 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
105 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
106 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
107 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
108 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
109 { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
110 { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
111 { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
112 { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
113 { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
114 { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
115 { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
116 { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
117 { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
118 { -1, },
119}; 86};
120 87
121struct alchemy_irqmap au1500_irqmap[] __initdata = { 88struct au1xxx_irqmap au1000_irqmap[] __initdata = {
122 { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 89 { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
123 { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 90 { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
124 { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 91 { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
125 { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 92 { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
126 { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 93 { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
127 { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 94 { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
128 { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 95 { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
129 { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 96 { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
130 { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 97 { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
131 { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 98 { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
132 { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 99 { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
133 { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 100 { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
134 { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 101 { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
135 { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 102 { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
136 { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 103 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
137 { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 104 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
138 { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 105 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
139 { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 106 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
140 { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 107 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
141 { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 108 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
142 { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 109 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
143 { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, 110 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
144 { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 }, 111 { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
145 { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 112 { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
146 { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 113 { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
147 { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 114 { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
148 { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 115 { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
149 { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 116 { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
150 { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 117 { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
118 { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
119 { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
151 { -1, }, 120 { -1, },
152}; 121};
153 122
154struct alchemy_irqmap au1100_irqmap[] __initdata = { 123struct au1xxx_irqmap au1500_irqmap[] __initdata = {
155 { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 124 { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
156 { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 125 { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
157 { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 126 { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
158 { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 127 { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
159 { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 128 { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
160 { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 129 { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
161 { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 130 { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
162 { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 131 { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
163 { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 132 { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
164 { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 133 { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
165 { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 134 { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
166 { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 135 { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
167 { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 136 { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
168 { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 137 { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
169 { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 138 { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
170 { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 139 { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
171 { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 140 { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
172 { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 141 { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
173 { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 142 { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
174 { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 143 { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
175 { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 144 { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
176 { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, 145 { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
177 { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 146 { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
178 { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 147 { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
179 { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 }, 148 { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
180 { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 149 { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
181 { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 150 { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
182 { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 151 { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
183 { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 152 { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
184 { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
185 { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
186 { -1, }, 153 { -1, },
187}; 154};
188 155
189struct alchemy_irqmap au1550_irqmap[] __initdata = { 156struct au1xxx_irqmap au1100_irqmap[] __initdata = {
190 { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 157 { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
191 { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 158 { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
192 { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 159 { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
193 { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 160 { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
194 { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 161 { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
195 { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 162 { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
196 { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 163 { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
197 { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 164 { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
198 { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 165 { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
199 { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 166 { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
200 { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 167 { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
201 { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 168 { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
202 { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 169 { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
203 { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 170 { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
204 { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 171 { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
205 { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 172 { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
206 { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 173 { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
207 { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 174 { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
208 { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 175 { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
209 { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 176 { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
210 { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 177 { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
211 { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, 178 { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
212 { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 179 { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
213 { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 }, 180 { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
214 { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 181 { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
215 { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, 182 { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
216 { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 183 { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
217 { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 184 { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
185 { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
186 { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
187 { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
218 { -1, }, 188 { -1, },
219}; 189};
220 190
221struct alchemy_irqmap au1200_irqmap[] __initdata = { 191struct au1xxx_irqmap au1550_irqmap[] __initdata = {
222 { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 192 { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
223 { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 193 { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
224 { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 194 { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
225 { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 195 { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
226 { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 196 { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
227 { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 197 { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
228 { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 198 { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
229 { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 199 { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
230 { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 200 { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
231 { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 201 { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
232 { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 202 { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
233 { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 203 { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
234 { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 204 { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
235 { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 205 { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
236 { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 206 { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
237 { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 207 { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
238 { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 208 { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
239 { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 209 { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
240 { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, 210 { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
241 { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, 211 { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
242 { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 212 { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
243 { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 213 { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
244 { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, 214 { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
215 { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
216 { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
217 { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
218 { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
219 { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
245 { -1, }, 220 { -1, },
246}; 221};
247 222
248static struct alchemy_irqmap au1300_irqmap[] __initdata = { 223struct au1xxx_irqmap au1200_irqmap[] __initdata = {
249 /* multifunction: gpio pin or device */ 224 { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
250 { AU1300_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 225 { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
251 { AU1300_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 226 { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
252 { AU1300_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 227 { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
253 { AU1300_SD1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 228 { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
254 { AU1300_SD2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 229 { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
255 { AU1300_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 230 { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
256 { AU1300_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 231 { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
257 { AU1300_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 232 { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
258 { AU1300_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 233 { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
259 { AU1300_NAND_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, 234 { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
260 /* au1300 internal */ 235 { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
261 { AU1300_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, 236 { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
262 { AU1300_MMU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, 237 { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
263 { AU1300_MPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, 238 { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
264 { AU1300_GPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, 239 { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
265 { AU1300_UDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, 240 { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
266 { AU1300_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, 241 { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
267 { AU1300_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, 242 { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
268 { AU1300_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, 243 { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
269 { AU1300_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, 244 { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
270 { AU1300_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, 245 { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
271 { AU1300_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, 246 { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
272 { AU1300_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, 247 { -1, },
273 { AU1300_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 1, },
274 { AU1300_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
275 { AU1300_SD0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
276 { AU1300_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
277 { AU1300_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
278 { AU1300_BSA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
279 { AU1300_MPE_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
280 { AU1300_ITE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
281 { AU1300_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
282 { AU1300_CIM_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
283 { -1, }, /* terminator */
284}; 248};
285 249
286/******************************************************************************/
287 250
288static void au1x_ic0_unmask(struct irq_data *d) 251static void au1x_ic0_unmask(struct irq_data *d)
289{ 252{
@@ -302,6 +265,14 @@ static void au1x_ic1_unmask(struct irq_data *d)
302 265
303 __raw_writel(1 << bit, base + IC_MASKSET); 266 __raw_writel(1 << bit, base + IC_MASKSET);
304 __raw_writel(1 << bit, base + IC_WAKESET); 267 __raw_writel(1 << bit, base + IC_WAKESET);
268
269/* very hacky. does the pb1000 cpld auto-disable this int?
270 * nowhere in the current kernel sources is it disabled. --mlau
271 */
272#if defined(CONFIG_MIPS_PB1000)
273 if (d->irq == AU1000_GPIO15_INT)
274 __raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */
275#endif
305 wmb(); 276 wmb();
306} 277}
307 278
@@ -499,219 +470,40 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
499 return ret; 470 return ret;
500} 471}
501 472
502/******************************************************************************/ 473asmlinkage void plat_irq_dispatch(void)
503
504/*
505 * au1300_gpic_chgcfg - change PIN configuration.
506 * @gpio: pin to change (0-based GPIO number from datasheet).
507 * @clr: clear all bits set in 'clr'.
508 * @set: set these bits.
509 *
510 * modifies a pins' configuration register, bits set in @clr will
511 * be cleared in the register, bits in @set will be set.
512 */
513static inline void au1300_gpic_chgcfg(unsigned int gpio,
514 unsigned long clr,
515 unsigned long set)
516{
517 void __iomem *r = AU1300_GPIC_ADDR;
518 unsigned long l;
519
520 r += gpio * 4; /* offset into pin config array */
521 l = __raw_readl(r + AU1300_GPIC_PINCFG);
522 l &= ~clr;
523 l |= set;
524 __raw_writel(l, r + AU1300_GPIC_PINCFG);
525 wmb();
526}
527
528/*
529 * au1300_pinfunc_to_gpio - assign a pin as GPIO input (GPIO ctrl).
530 * @pin: pin (0-based GPIO number from datasheet).
531 *
532 * Assigns a GPIO pin to the GPIO controller, so its level can either
533 * be read or set through the generic GPIO functions.
534 * If you need a GPOUT, use au1300_gpio_set_value(pin, 0/1).
535 * REVISIT: is this function really necessary?
536 */
537void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio)
538{
539 au1300_gpio_direction_input(gpio + AU1300_GPIO_BASE);
540}
541EXPORT_SYMBOL_GPL(au1300_pinfunc_to_gpio);
542
543/*
544 * au1300_pinfunc_to_dev - assign a pin to the device function.
545 * @pin: pin (0-based GPIO number from datasheet).
546 *
547 * Assigns a GPIO pin to its associated device function; the pin will be
548 * driven by the device and not through GPIO functions.
549 */
550void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio)
551{
552 void __iomem *r = AU1300_GPIC_ADDR;
553 unsigned long bit;
554
555 r += GPIC_GPIO_BANKOFF(gpio);
556 bit = GPIC_GPIO_TO_BIT(gpio);
557 __raw_writel(bit, r + AU1300_GPIC_DEVSEL);
558 wmb();
559}
560EXPORT_SYMBOL_GPL(au1300_pinfunc_to_dev);
561
562/*
563 * au1300_set_irq_priority - set internal priority of IRQ.
564 * @irq: irq to set priority (linux irq number).
565 * @p: priority (0 = highest, 3 = lowest).
566 */
567void au1300_set_irq_priority(unsigned int irq, int p)
568{
569 irq -= ALCHEMY_GPIC_INT_BASE;
570 au1300_gpic_chgcfg(irq, GPIC_CFG_IL_MASK, GPIC_CFG_IL_SET(p));
571}
572EXPORT_SYMBOL_GPL(au1300_set_irq_priority);
573
574/*
575 * au1300_set_dbdma_gpio - assign a gpio to one of the DBDMA triggers.
576 * @dchan: dbdma trigger select (0, 1).
577 * @gpio: pin to assign as trigger.
578 *
579 * DBDMA controller has 2 external trigger sources; this function
580 * assigns a GPIO to the selected trigger.
581 */
582void au1300_set_dbdma_gpio(int dchan, unsigned int gpio)
583{
584 unsigned long r;
585
586 if ((dchan >= 0) && (dchan <= 1)) {
587 r = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
588 r &= ~(0xff << (8 * dchan));
589 r |= (gpio & 0x7f) << (8 * dchan);
590 __raw_writel(r, AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
591 wmb();
592 }
593}
594
595static inline void gpic_pin_set_idlewake(unsigned int gpio, int allow)
596{
597 au1300_gpic_chgcfg(gpio, GPIC_CFG_IDLEWAKE,
598 allow ? GPIC_CFG_IDLEWAKE : 0);
599}
600
601static void au1300_gpic_mask(struct irq_data *d)
602{
603 void __iomem *r = AU1300_GPIC_ADDR;
604 unsigned long bit, irq = d->irq;
605
606 irq -= ALCHEMY_GPIC_INT_BASE;
607 r += GPIC_GPIO_BANKOFF(irq);
608 bit = GPIC_GPIO_TO_BIT(irq);
609 __raw_writel(bit, r + AU1300_GPIC_IDIS);
610 wmb();
611
612 gpic_pin_set_idlewake(irq, 0);
613}
614
615static void au1300_gpic_unmask(struct irq_data *d)
616{
617 void __iomem *r = AU1300_GPIC_ADDR;
618 unsigned long bit, irq = d->irq;
619
620 irq -= ALCHEMY_GPIC_INT_BASE;
621
622 gpic_pin_set_idlewake(irq, 1);
623
624 r += GPIC_GPIO_BANKOFF(irq);
625 bit = GPIC_GPIO_TO_BIT(irq);
626 __raw_writel(bit, r + AU1300_GPIC_IEN);
627 wmb();
628}
629
630static void au1300_gpic_maskack(struct irq_data *d)
631{
632 void __iomem *r = AU1300_GPIC_ADDR;
633 unsigned long bit, irq = d->irq;
634
635 irq -= ALCHEMY_GPIC_INT_BASE;
636 r += GPIC_GPIO_BANKOFF(irq);
637 bit = GPIC_GPIO_TO_BIT(irq);
638 __raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */
639 __raw_writel(bit, r + AU1300_GPIC_IDIS); /* mask */
640 wmb();
641
642 gpic_pin_set_idlewake(irq, 0);
643}
644
645static void au1300_gpic_ack(struct irq_data *d)
646{
647 void __iomem *r = AU1300_GPIC_ADDR;
648 unsigned long bit, irq = d->irq;
649
650 irq -= ALCHEMY_GPIC_INT_BASE;
651 r += GPIC_GPIO_BANKOFF(irq);
652 bit = GPIC_GPIO_TO_BIT(irq);
653 __raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */
654 wmb();
655}
656
657static struct irq_chip au1300_gpic = {
658 .name = "GPIOINT",
659 .irq_ack = au1300_gpic_ack,
660 .irq_mask = au1300_gpic_mask,
661 .irq_mask_ack = au1300_gpic_maskack,
662 .irq_unmask = au1300_gpic_unmask,
663 .irq_set_type = au1300_gpic_settype,
664};
665
666static int au1300_gpic_settype(struct irq_data *d, unsigned int type)
667{ 474{
668 unsigned long s; 475 unsigned int pending = read_c0_status() & read_c0_cause();
669 unsigned char *name = NULL; 476 unsigned long s, off;
670 irq_flow_handler_t hdl = NULL; 477
671 478 if (pending & CAUSEF_IP7) {
672 switch (type) { 479 off = MIPS_CPU_IRQ_BASE + 7;
673 case IRQ_TYPE_LEVEL_HIGH: 480 goto handle;
674 s = GPIC_CFG_IC_LEVEL_HIGH; 481 } else if (pending & CAUSEF_IP2) {
675 name = "high"; 482 s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT;
676 hdl = handle_level_irq; 483 off = AU1000_INTC0_INT_BASE;
677 break; 484 } else if (pending & CAUSEF_IP3) {
678 case IRQ_TYPE_LEVEL_LOW: 485 s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT;
679 s = GPIC_CFG_IC_LEVEL_LOW; 486 off = AU1000_INTC0_INT_BASE;
680 name = "low"; 487 } else if (pending & CAUSEF_IP4) {
681 hdl = handle_level_irq; 488 s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT;
682 break; 489 off = AU1000_INTC1_INT_BASE;
683 case IRQ_TYPE_EDGE_RISING: 490 } else if (pending & CAUSEF_IP5) {
684 s = GPIC_CFG_IC_EDGE_RISE; 491 s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT;
685 name = "posedge"; 492 off = AU1000_INTC1_INT_BASE;
686 hdl = handle_edge_irq; 493 } else
687 break; 494 goto spurious;
688 case IRQ_TYPE_EDGE_FALLING: 495
689 s = GPIC_CFG_IC_EDGE_FALL; 496 s = __raw_readl((void __iomem *)s);
690 name = "negedge"; 497 if (unlikely(!s)) {
691 hdl = handle_edge_irq; 498spurious:
692 break; 499 spurious_interrupt();
693 case IRQ_TYPE_EDGE_BOTH: 500 return;
694 s = GPIC_CFG_IC_EDGE_BOTH;
695 name = "bothedge";
696 hdl = handle_edge_irq;
697 break;
698 case IRQ_TYPE_NONE:
699 s = GPIC_CFG_IC_OFF;
700 name = "disabled";
701 hdl = handle_level_irq;
702 break;
703 default:
704 return -EINVAL;
705 } 501 }
706 502 off += __ffs(s);
707 __irq_set_chip_handler_name_locked(d->irq, &au1300_gpic, hdl, name); 503handle:
708 504 do_IRQ(off);
709 au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);
710
711 return 0;
712} 505}
713 506
714/******************************************************************************/
715 507
716static inline void ic_init(void __iomem *base) 508static inline void ic_init(void __iomem *base)
717{ 509{
@@ -729,159 +521,13 @@ static inline void ic_init(void __iomem *base)
729 wmb(); 521 wmb();
730} 522}
731 523
732static unsigned long alchemy_gpic_pmdata[ALCHEMY_GPIC_INT_NUM + 6]; 524static void __init au1000_init_irq(struct au1xxx_irqmap *map)
733
734static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
735{
736 d[0] = __raw_readl(base + IC_CFG0RD);
737 d[1] = __raw_readl(base + IC_CFG1RD);
738 d[2] = __raw_readl(base + IC_CFG2RD);
739 d[3] = __raw_readl(base + IC_SRCRD);
740 d[4] = __raw_readl(base + IC_ASSIGNRD);
741 d[5] = __raw_readl(base + IC_WAKERD);
742 d[6] = __raw_readl(base + IC_MASKRD);
743 ic_init(base); /* shut it up too while at it */
744}
745
746static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
747{
748 ic_init(base);
749
750 __raw_writel(d[0], base + IC_CFG0SET);
751 __raw_writel(d[1], base + IC_CFG1SET);
752 __raw_writel(d[2], base + IC_CFG2SET);
753 __raw_writel(d[3], base + IC_SRCSET);
754 __raw_writel(d[4], base + IC_ASSIGNSET);
755 __raw_writel(d[5], base + IC_WAKESET);
756 wmb();
757
758 __raw_writel(d[6], base + IC_MASKSET);
759 wmb();
760}
761
762static int alchemy_ic_suspend(void)
763{
764 alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
765 alchemy_gpic_pmdata);
766 alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
767 &alchemy_gpic_pmdata[7]);
768 return 0;
769}
770
771static void alchemy_ic_resume(void)
772{
773 alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
774 &alchemy_gpic_pmdata[7]);
775 alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
776 alchemy_gpic_pmdata);
777}
778
779static int alchemy_gpic_suspend(void)
780{
781 void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
782 int i;
783
784 /* save 4 interrupt mask status registers */
785 alchemy_gpic_pmdata[0] = __raw_readl(base + AU1300_GPIC_IEN + 0x0);
786 alchemy_gpic_pmdata[1] = __raw_readl(base + AU1300_GPIC_IEN + 0x4);
787 alchemy_gpic_pmdata[2] = __raw_readl(base + AU1300_GPIC_IEN + 0x8);
788 alchemy_gpic_pmdata[3] = __raw_readl(base + AU1300_GPIC_IEN + 0xc);
789
790 /* save misc register(s) */
791 alchemy_gpic_pmdata[4] = __raw_readl(base + AU1300_GPIC_DMASEL);
792
793 /* molto silenzioso */
794 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
795 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
796 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
797 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
798 wmb();
799
800 /* save pin/int-type configuration */
801 base += AU1300_GPIC_PINCFG;
802 for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
803 alchemy_gpic_pmdata[i + 5] = __raw_readl(base + (i << 2));
804
805 wmb();
806
807 return 0;
808}
809
810static void alchemy_gpic_resume(void)
811{
812 void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
813 int i;
814
815 /* disable all first */
816 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
817 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
818 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
819 __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
820 wmb();
821
822 /* restore pin/int-type configurations */
823 base += AU1300_GPIC_PINCFG;
824 for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
825 __raw_writel(alchemy_gpic_pmdata[i + 5], base + (i << 2));
826 wmb();
827
828 /* restore misc register(s) */
829 base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
830 __raw_writel(alchemy_gpic_pmdata[4], base + AU1300_GPIC_DMASEL);
831 wmb();
832
833 /* finally restore masks */
834 __raw_writel(alchemy_gpic_pmdata[0], base + AU1300_GPIC_IEN + 0x0);
835 __raw_writel(alchemy_gpic_pmdata[1], base + AU1300_GPIC_IEN + 0x4);
836 __raw_writel(alchemy_gpic_pmdata[2], base + AU1300_GPIC_IEN + 0x8);
837 __raw_writel(alchemy_gpic_pmdata[3], base + AU1300_GPIC_IEN + 0xc);
838 wmb();
839}
840
841static struct syscore_ops alchemy_ic_pmops = {
842 .suspend = alchemy_ic_suspend,
843 .resume = alchemy_ic_resume,
844};
845
846static struct syscore_ops alchemy_gpic_pmops = {
847 .suspend = alchemy_gpic_suspend,
848 .resume = alchemy_gpic_resume,
849};
850
851/******************************************************************************/
852
853/* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */
854#define DISP(name, base, addr) \
855static void au1000_##name##_dispatch(unsigned int irq, struct irq_desc *d) \
856{ \
857 unsigned long r = __raw_readl((void __iomem *)KSEG1ADDR(addr)); \
858 if (likely(r)) \
859 generic_handle_irq(base + __ffs(r)); \
860 else \
861 spurious_interrupt(); \
862}
863
864DISP(ic0r0, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ0INT)
865DISP(ic0r1, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ1INT)
866DISP(ic1r0, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ0INT)
867DISP(ic1r1, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ1INT)
868
869static void alchemy_gpic_dispatch(unsigned int irq, struct irq_desc *d)
870{
871 int i = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_PRIENC);
872 generic_handle_irq(ALCHEMY_GPIC_INT_BASE + i);
873}
874
875/******************************************************************************/
876
877static void __init au1000_init_irq(struct alchemy_irqmap *map)
878{ 525{
879 unsigned int bit, irq_nr; 526 unsigned int bit, irq_nr;
880 void __iomem *base; 527 void __iomem *base;
881 528
882 ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR)); 529 ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
883 ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR)); 530 ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
884 register_syscore_ops(&alchemy_ic_pmops);
885 mips_cpu_irq_init(); 531 mips_cpu_irq_init();
886 532
887 /* register all 64 possible IC0+IC1 irq sources as type "none". 533 /* register all 64 possible IC0+IC1 irq sources as type "none".
@@ -898,8 +544,8 @@ static void __init au1000_init_irq(struct alchemy_irqmap *map)
898 /* 544 /*
899 * Initialize IC0, which is fixed per processor. 545 * Initialize IC0, which is fixed per processor.
900 */ 546 */
901 while (map->irq != -1) { 547 while (map->im_irq != -1) {
902 irq_nr = map->irq; 548 irq_nr = map->im_irq;
903 549
904 if (irq_nr >= AU1000_INTC1_INT_BASE) { 550 if (irq_nr >= AU1000_INTC1_INT_BASE) {
905 bit = irq_nr - AU1000_INTC1_INT_BASE; 551 bit = irq_nr - AU1000_INTC1_INT_BASE;
@@ -908,61 +554,16 @@ static void __init au1000_init_irq(struct alchemy_irqmap *map)
908 bit = irq_nr - AU1000_INTC0_INT_BASE; 554 bit = irq_nr - AU1000_INTC0_INT_BASE;
909 base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); 555 base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
910 } 556 }
911 if (map->prio == 0) 557 if (map->im_request)
912 __raw_writel(1 << bit, base + IC_ASSIGNSET); 558 __raw_writel(1 << bit, base + IC_ASSIGNSET);
913 559
914 au1x_ic_settype(irq_get_irq_data(irq_nr), map->type); 560 au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
915 ++map; 561 ++map;
916 } 562 }
917 563
918 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, au1000_ic0r0_dispatch); 564 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
919 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, au1000_ic0r1_dispatch);
920 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, au1000_ic1r0_dispatch);
921 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, au1000_ic1r1_dispatch);
922}
923
924static void __init alchemy_gpic_init_irq(const struct alchemy_irqmap *dints)
925{
926 int i;
927 void __iomem *bank_base;
928
929 register_syscore_ops(&alchemy_gpic_pmops);
930 mips_cpu_irq_init();
931
932 /* disable & ack all possible interrupt sources */
933 for (i = 0; i < 4; i++) {
934 bank_base = AU1300_GPIC_ADDR + (i * 4);
935 __raw_writel(~0UL, bank_base + AU1300_GPIC_IDIS);
936 wmb();
937 __raw_writel(~0UL, bank_base + AU1300_GPIC_IPEND);
938 wmb();
939 }
940
941 /* register an irq_chip for them, with 2nd highest priority */
942 for (i = ALCHEMY_GPIC_INT_BASE; i <= ALCHEMY_GPIC_INT_LAST; i++) {
943 au1300_set_irq_priority(i, 1);
944 au1300_gpic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
945 }
946
947 /* setup known on-chip sources */
948 while ((i = dints->irq) != -1) {
949 au1300_gpic_settype(irq_get_irq_data(i), dints->type);
950 au1300_set_irq_priority(i, dints->prio);
951
952 if (dints->internal)
953 au1300_pinfunc_to_dev(i - ALCHEMY_GPIC_INT_BASE);
954
955 dints++;
956 }
957
958 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, alchemy_gpic_dispatch);
959 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, alchemy_gpic_dispatch);
960 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, alchemy_gpic_dispatch);
961 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, alchemy_gpic_dispatch);
962} 565}
963 566
964/******************************************************************************/
965
966void __init arch_init_irq(void) 567void __init arch_init_irq(void)
967{ 568{
968 switch (alchemy_get_cputype()) { 569 switch (alchemy_get_cputype()) {
@@ -981,17 +582,65 @@ void __init arch_init_irq(void)
981 case ALCHEMY_CPU_AU1200: 582 case ALCHEMY_CPU_AU1200:
982 au1000_init_irq(au1200_irqmap); 583 au1000_init_irq(au1200_irqmap);
983 break; 584 break;
984 case ALCHEMY_CPU_AU1300:
985 alchemy_gpic_init_irq(au1300_irqmap);
986 break;
987 default:
988 pr_err("unknown Alchemy IRQ core\n");
989 break;
990 } 585 }
991} 586}
992 587
993asmlinkage void plat_irq_dispatch(void) 588
589static unsigned long alchemy_ic_pmdata[7 * 2];
590
591static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
994{ 592{
995 unsigned long r = (read_c0_status() & read_c0_cause()) >> 8; 593 d[0] = __raw_readl(base + IC_CFG0RD);
996 do_IRQ(MIPS_CPU_IRQ_BASE + __ffs(r & 0xff)); 594 d[1] = __raw_readl(base + IC_CFG1RD);
595 d[2] = __raw_readl(base + IC_CFG2RD);
596 d[3] = __raw_readl(base + IC_SRCRD);
597 d[4] = __raw_readl(base + IC_ASSIGNRD);
598 d[5] = __raw_readl(base + IC_WAKERD);
599 d[6] = __raw_readl(base + IC_MASKRD);
600 ic_init(base); /* shut it up too while at it */
601}
602
603static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
604{
605 ic_init(base);
606
607 __raw_writel(d[0], base + IC_CFG0SET);
608 __raw_writel(d[1], base + IC_CFG1SET);
609 __raw_writel(d[2], base + IC_CFG2SET);
610 __raw_writel(d[3], base + IC_SRCSET);
611 __raw_writel(d[4], base + IC_ASSIGNSET);
612 __raw_writel(d[5], base + IC_WAKESET);
613 wmb();
614
615 __raw_writel(d[6], base + IC_MASKSET);
616 wmb();
617}
618
619static int alchemy_ic_suspend(void)
620{
621 alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
622 alchemy_ic_pmdata);
623 alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
624 &alchemy_ic_pmdata[7]);
625 return 0;
626}
627
628static void alchemy_ic_resume(void)
629{
630 alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
631 &alchemy_ic_pmdata[7]);
632 alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
633 alchemy_ic_pmdata);
634}
635
636static struct syscore_ops alchemy_ic_syscore_ops = {
637 .suspend = alchemy_ic_suspend,
638 .resume = alchemy_ic_resume,
639};
640
641static int __init alchemy_ic_pm_init(void)
642{
643 register_syscore_ops(&alchemy_ic_syscore_ops);
644 return 0;
997} 645}
646device_initcall(alchemy_ic_pm_init);
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 7af941d8e71..f72c48d4804 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -17,10 +17,8 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/serial_8250.h> 18#include <linux/serial_8250.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/usb/ehci_pdriver.h>
21#include <linux/usb/ohci_pdriver.h>
22 20
23#include <asm/mach-au1x00/au1000.h> 21#include <asm/mach-au1x00/au1xxx.h>
24#include <asm/mach-au1x00/au1xxx_dbdma.h> 22#include <asm/mach-au1x00/au1xxx_dbdma.h>
25#include <asm/mach-au1x00/au1100_mmc.h> 23#include <asm/mach-au1x00/au1100_mmc.h>
26#include <asm/mach-au1x00/au1xxx_eth.h> 24#include <asm/mach-au1x00/au1xxx_eth.h>
@@ -84,12 +82,6 @@ static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
84 PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT), 82 PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
85 PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT), 83 PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
86 }, 84 },
87 [ALCHEMY_CPU_AU1300] = {
88 PORT(AU1300_UART0_PHYS_ADDR, AU1300_UART0_INT),
89 PORT(AU1300_UART1_PHYS_ADDR, AU1300_UART1_INT),
90 PORT(AU1300_UART2_PHYS_ADDR, AU1300_UART2_INT),
91 PORT(AU1300_UART3_PHYS_ADDR, AU1300_UART3_INT),
92 },
93}; 85};
94 86
95static struct platform_device au1xx0_uart_device = { 87static struct platform_device au1xx0_uart_device = {
@@ -119,158 +111,270 @@ static void __init alchemy_setup_uarts(int ctype)
119 printk(KERN_INFO "Alchemy: failed to register UARTs\n"); 111 printk(KERN_INFO "Alchemy: failed to register UARTs\n");
120} 112}
121 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};
122 127
123/* The dmamask must be set for OHCI/EHCI to work */ 128/* The dmamask must be set for OHCI to work */
124static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32); 129static u64 ohci_dmamask = DMA_BIT_MASK(32);
125static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
126 130
127/* Power on callback for the ehci platform driver */ 131static struct platform_device au1xxx_usb_ohci_device = {
128static int alchemy_ehci_power_on(struct platform_device *pdev) 132 .name = "au1xxx-ohci",
129{ 133 .id = 0,
130 return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); 134 .dev = {
131} 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};
132 141
133/* Power off/suspend callback for the ehci platform driver */ 142/*** AU1100 LCD controller ***/
134static void alchemy_ehci_power_off(struct platform_device *pdev)
135{
136 alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
137}
138 143
139static struct usb_ehci_pdata alchemy_ehci_pdata = { 144#ifdef CONFIG_FB_AU1100
140 .no_io_watchdog = 1, 145static struct resource au1100_lcd_resources[] = {
141 .power_on = alchemy_ehci_power_on, 146 [0] = {
142 .power_off = alchemy_ehci_power_off, 147 .start = LCD_PHYS_ADDR,
143 .power_suspend = alchemy_ehci_power_off, 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 }
144}; 156};
145 157
146/* Power on callback for the ohci platform driver */ 158static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
147static int alchemy_ohci_power_on(struct platform_device *pdev)
148{
149 int unit;
150 159
151 unit = (pdev->id == 1) ? 160static struct platform_device au1100_lcd_device = {
152 ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; 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
153 171
154 return alchemy_usb_control(unit, 1); 172#ifdef CONFIG_SOC_AU1200
155} 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};
156 186
157/* Power off/suspend callback for the ohci platform driver */ 187static u64 ehci_dmamask = DMA_BIT_MASK(32);
158static void alchemy_ohci_power_off(struct platform_device *pdev)
159{
160 int unit;
161 188
162 unit = (pdev->id == 1) ? 189static struct platform_device au1xxx_usb_ehci_device = {
163 ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; 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};
164 199
165 alchemy_usb_control(unit, 0); 200/* Au1200 UDC (USB gadget controller) */
166} 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);
167 215
168static struct usb_ohci_pdata alchemy_ohci_pdata = { 216static struct platform_device au1xxx_usb_gdt_device = {
169 .power_on = alchemy_ohci_power_on, 217 .name = "au1xxx-udc",
170 .power_off = alchemy_ohci_power_off, 218 .id = 0,
171 .power_suspend = alchemy_ohci_power_off, 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,
172}; 225};
173 226
174static unsigned long alchemy_ohci_data[][2] __initdata = { 227/* Au1200 UOC (USB OTG controller) */
175 [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, 228static struct resource au1xxx_usb_otg_resources[] = {
176 [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, 229 [0] = {
177 [ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT }, 230 .start = USB_UOC_BASE,
178 [ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT }, 231 .end = USB_UOC_BASE + USB_UOC_LEN - 1,
179 [ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT }, 232 .flags = IORESOURCE_MEM,
180 [ALCHEMY_CPU_AU1300] = { AU1300_USB_OHCI0_PHYS_ADDR, AU1300_USB_INT }, 233 },
234 [1] = {
235 .start = AU1200_USB_INT,
236 .end = AU1200_USB_INT,
237 .flags = IORESOURCE_IRQ,
238 },
181}; 239};
182 240
183static unsigned long alchemy_ehci_data[][2] __initdata = { 241static u64 uoc_dmamask = DMA_BIT_MASK(32);
184 [ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT }, 242
185 [ALCHEMY_CPU_AU1300] = { AU1300_USB_EHCI_PHYS_ADDR, AU1300_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,
186}; 252};
187 253
188static int __init _new_usbres(struct resource **r, struct platform_device **d) 254static struct resource au1200_lcd_resources[] = {
189{ 255 [0] = {
190 *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); 256 .start = LCD_PHYS_ADDR,
191 if (!*r) 257 .end = LCD_PHYS_ADDR + 0x800 - 1,
192 return -ENOMEM; 258 .flags = IORESOURCE_MEM,
193 *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL); 259 },
194 if (!*d) { 260 [1] = {
195 kfree(*r); 261 .start = AU1200_LCD_INT,
196 return -ENOMEM; 262 .end = AU1200_LCD_INT,
263 .flags = IORESOURCE_IRQ,
197 } 264 }
265};
198 266
199 (*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32); 267static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
200 (*d)->num_resources = 2;
201 (*d)->resource = *r;
202 268
203 return 0; 269static struct platform_device au1200_lcd_device = {
204} 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};
205 279
206static void __init alchemy_setup_usb(int ctype) 280static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
207{
208 struct resource *res;
209 struct platform_device *pdev;
210 281
211 /* setup OHCI0. Every variant has one */ 282extern struct au1xmmc_platform_data au1xmmc_platdata[2];
212 if (_new_usbres(&res, &pdev))
213 return;
214 283
215 res[0].start = alchemy_ohci_data[ctype][0]; 284static struct resource au1200_mmc0_resources[] = {
216 res[0].end = res[0].start + 0x100 - 1; 285 [0] = {
217 res[0].flags = IORESOURCE_MEM; 286 .start = AU1100_SD0_PHYS_ADDR,
218 res[1].start = alchemy_ohci_data[ctype][1]; 287 .end = AU1100_SD0_PHYS_ADDR + 0xfff,
219 res[1].end = res[1].start; 288 .flags = IORESOURCE_MEM,
220 res[1].flags = IORESOURCE_IRQ; 289 },
221 pdev->name = "ohci-platform"; 290 [1] = {
222 pdev->id = 0; 291 .start = AU1200_SD_INT,
223 pdev->dev.dma_mask = &alchemy_ohci_dmamask; 292 .end = AU1200_SD_INT,
224 pdev->dev.platform_data = &alchemy_ohci_pdata; 293 .flags = IORESOURCE_IRQ,
225 294 },
226 if (platform_device_register(pdev)) 295 [2] = {
227 printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n"); 296 .start = DSCR_CMD0_SDMS_TX0,
228 297 .end = DSCR_CMD0_SDMS_TX0,
229 298 .flags = IORESOURCE_DMA,
230 /* setup EHCI0: Au1200/Au1300 */ 299 },
231 if ((ctype == ALCHEMY_CPU_AU1200) || (ctype == ALCHEMY_CPU_AU1300)) { 300 [3] = {
232 if (_new_usbres(&res, &pdev)) 301 .start = DSCR_CMD0_SDMS_RX0,
233 return; 302 .end = DSCR_CMD0_SDMS_RX0,
234 303 .flags = IORESOURCE_DMA,
235 res[0].start = alchemy_ehci_data[ctype][0];
236 res[0].end = res[0].start + 0x100 - 1;
237 res[0].flags = IORESOURCE_MEM;
238 res[1].start = alchemy_ehci_data[ctype][1];
239 res[1].end = res[1].start;
240 res[1].flags = IORESOURCE_IRQ;
241 pdev->name = "ehci-platform";
242 pdev->id = 0;
243 pdev->dev.dma_mask = &alchemy_ehci_dmamask;
244 pdev->dev.platform_data = &alchemy_ehci_pdata;
245
246 if (platform_device_register(pdev))
247 printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
248 } 304 }
305};
306
307static struct platform_device au1200_mmc0_device = {
308 .name = "au1xxx-mmc",
309 .id = 0,
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};
249 318
250 /* Au1300: OHCI1 */ 319#ifndef CONFIG_MIPS_DB1200
251 if (ctype == ALCHEMY_CPU_AU1300) { 320static struct resource au1200_mmc1_resources[] = {
252 if (_new_usbres(&res, &pdev)) 321 [0] = {
253 return; 322 .start = AU1100_SD1_PHYS_ADDR,
254 323 .end = AU1100_SD1_PHYS_ADDR + 0xfff,
255 res[0].start = AU1300_USB_OHCI1_PHYS_ADDR; 324 .flags = IORESOURCE_MEM,
256 res[0].end = res[0].start + 0x100 - 1; 325 },
257 res[0].flags = IORESOURCE_MEM; 326 [1] = {
258 res[1].start = AU1300_USB_INT; 327 .start = AU1200_SD_INT,
259 res[1].end = res[1].start; 328 .end = AU1200_SD_INT,
260 res[1].flags = IORESOURCE_IRQ; 329 .flags = IORESOURCE_IRQ,
261 pdev->name = "ohci-platform"; 330 },
262 pdev->id = 1; 331 [2] = {
263 pdev->dev.dma_mask = &alchemy_ohci_dmamask; 332 .start = DSCR_CMD0_SDMS_TX1,
264 pdev->dev.platform_data = &alchemy_ohci_pdata; 333 .end = DSCR_CMD0_SDMS_TX1,
265 334 .flags = IORESOURCE_DMA,
266 if (platform_device_register(pdev)) 335 },
267 printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n"); 336 [3] = {
337 .start = DSCR_CMD0_SDMS_RX1,
338 .end = DSCR_CMD0_SDMS_RX1,
339 .flags = IORESOURCE_DMA,
268 } 340 }
269} 341};
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
270 374
271/* Macro to help defining the Ethernet MAC resources */ 375/* Macro to help defining the Ethernet MAC resources */
272#define MAC_RES_COUNT 4 /* MAC regs, MAC en, MAC INT, MACDMA regs */ 376#define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */
273#define MAC_RES(_base, _enable, _irq, _macdma) \ 377#define MAC_RES(_base, _enable, _irq) \
274 { \ 378 { \
275 .start = _base, \ 379 .start = _base, \
276 .end = _base + 0xffff, \ 380 .end = _base + 0xffff, \
@@ -285,37 +389,28 @@ static void __init alchemy_setup_usb(int ctype)
285 .start = _irq, \ 389 .start = _irq, \
286 .end = _irq, \ 390 .end = _irq, \
287 .flags = IORESOURCE_IRQ \ 391 .flags = IORESOURCE_IRQ \
288 }, \
289 { \
290 .start = _macdma, \
291 .end = _macdma + 0x1ff, \
292 .flags = IORESOURCE_MEM, \
293 } 392 }
294 393
295static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { 394static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
296 [ALCHEMY_CPU_AU1000] = { 395 [ALCHEMY_CPU_AU1000] = {
297 MAC_RES(AU1000_MAC0_PHYS_ADDR, 396 MAC_RES(AU1000_MAC0_PHYS_ADDR,
298 AU1000_MACEN_PHYS_ADDR, 397 AU1000_MACEN_PHYS_ADDR,
299 AU1000_MAC0_DMA_INT, 398 AU1000_MAC0_DMA_INT)
300 AU1000_MACDMA0_PHYS_ADDR)
301 }, 399 },
302 [ALCHEMY_CPU_AU1500] = { 400 [ALCHEMY_CPU_AU1500] = {
303 MAC_RES(AU1500_MAC0_PHYS_ADDR, 401 MAC_RES(AU1500_MAC0_PHYS_ADDR,
304 AU1500_MACEN_PHYS_ADDR, 402 AU1500_MACEN_PHYS_ADDR,
305 AU1500_MAC0_DMA_INT, 403 AU1500_MAC0_DMA_INT)
306 AU1000_MACDMA0_PHYS_ADDR)
307 }, 404 },
308 [ALCHEMY_CPU_AU1100] = { 405 [ALCHEMY_CPU_AU1100] = {
309 MAC_RES(AU1000_MAC0_PHYS_ADDR, 406 MAC_RES(AU1000_MAC0_PHYS_ADDR,
310 AU1000_MACEN_PHYS_ADDR, 407 AU1000_MACEN_PHYS_ADDR,
311 AU1100_MAC0_DMA_INT, 408 AU1100_MAC0_DMA_INT)
312 AU1000_MACDMA0_PHYS_ADDR)
313 }, 409 },
314 [ALCHEMY_CPU_AU1550] = { 410 [ALCHEMY_CPU_AU1550] = {
315 MAC_RES(AU1000_MAC0_PHYS_ADDR, 411 MAC_RES(AU1000_MAC0_PHYS_ADDR,
316 AU1000_MACEN_PHYS_ADDR, 412 AU1000_MACEN_PHYS_ADDR,
317 AU1550_MAC0_DMA_INT, 413 AU1550_MAC0_DMA_INT)
318 AU1000_MACDMA0_PHYS_ADDR)
319 }, 414 },
320}; 415};
321 416
@@ -334,20 +429,17 @@ static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
334 [ALCHEMY_CPU_AU1000] = { 429 [ALCHEMY_CPU_AU1000] = {
335 MAC_RES(AU1000_MAC1_PHYS_ADDR, 430 MAC_RES(AU1000_MAC1_PHYS_ADDR,
336 AU1000_MACEN_PHYS_ADDR + 4, 431 AU1000_MACEN_PHYS_ADDR + 4,
337 AU1000_MAC1_DMA_INT, 432 AU1000_MAC1_DMA_INT)
338 AU1000_MACDMA1_PHYS_ADDR)
339 }, 433 },
340 [ALCHEMY_CPU_AU1500] = { 434 [ALCHEMY_CPU_AU1500] = {
341 MAC_RES(AU1500_MAC1_PHYS_ADDR, 435 MAC_RES(AU1500_MAC1_PHYS_ADDR,
342 AU1500_MACEN_PHYS_ADDR + 4, 436 AU1500_MACEN_PHYS_ADDR + 4,
343 AU1500_MAC1_DMA_INT, 437 AU1500_MAC1_DMA_INT)
344 AU1000_MACDMA1_PHYS_ADDR)
345 }, 438 },
346 [ALCHEMY_CPU_AU1550] = { 439 [ALCHEMY_CPU_AU1550] = {
347 MAC_RES(AU1000_MAC1_PHYS_ADDR, 440 MAC_RES(AU1000_MAC1_PHYS_ADDR,
348 AU1000_MACEN_PHYS_ADDR + 4, 441 AU1000_MACEN_PHYS_ADDR + 4,
349 AU1550_MAC1_DMA_INT, 442 AU1550_MAC1_DMA_INT)
350 AU1000_MACDMA1_PHYS_ADDR)
351 }, 443 },
352}; 444};
353 445
@@ -386,12 +478,13 @@ static void __init alchemy_setup_macs(int ctype)
386 if (alchemy_get_macs(ctype) < 1) 478 if (alchemy_get_macs(ctype) < 1)
387 return; 479 return;
388 480
389 macres = kmemdup(au1xxx_eth0_resources[ctype], 481 macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
390 sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
391 if (!macres) { 482 if (!macres) {
392 printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n"); 483 printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
393 return; 484 return;
394 } 485 }
486 memcpy(macres, au1xxx_eth0_resources[ctype],
487 sizeof(struct resource) * MAC_RES_COUNT);
395 au1xxx_eth0_device.resource = macres; 488 au1xxx_eth0_device.resource = macres;
396 489
397 i = prom_get_ethernet_addr(ethaddr); 490 i = prom_get_ethernet_addr(ethaddr);
@@ -407,12 +500,13 @@ static void __init alchemy_setup_macs(int ctype)
407 if (alchemy_get_macs(ctype) < 2) 500 if (alchemy_get_macs(ctype) < 2)
408 return; 501 return;
409 502
410 macres = kmemdup(au1xxx_eth1_resources[ctype], 503 macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
411 sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
412 if (!macres) { 504 if (!macres) {
413 printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n"); 505 printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
414 return; 506 return;
415 } 507 }
508 memcpy(macres, au1xxx_eth1_resources[ctype],
509 sizeof(struct resource) * MAC_RES_COUNT);
416 au1xxx_eth1_device.resource = macres; 510 au1xxx_eth1_device.resource = macres;
417 511
418 ethaddr[5] += 1; /* next addr for 2nd MAC */ 512 ethaddr[5] += 1; /* next addr for 2nd MAC */
@@ -427,15 +521,36 @@ static void __init alchemy_setup_macs(int ctype)
427 } 521 }
428} 522}
429 523
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
430static int __init au1xxx_platform_init(void) 544static int __init au1xxx_platform_init(void)
431{ 545{
432 int ctype = alchemy_get_cputype(); 546 int err, ctype = alchemy_get_cputype();
433 547
434 alchemy_setup_uarts(ctype); 548 alchemy_setup_uarts(ctype);
435 alchemy_setup_macs(ctype); 549 alchemy_setup_macs(ctype);
436 alchemy_setup_usb(ctype);
437 550
438 return 0; 551 err = platform_add_devices(au1xxx_platform_devices,
552 ARRAY_SIZE(au1xxx_platform_devices));
553 return err;
439} 554}
440 555
441arch_initcall(au1xxx_platform_init); 556arch_initcall(au1xxx_platform_init);
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index 0c7fce2a3c1..b86324a4260 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -37,6 +37,8 @@
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
40/* 42/*
41 * We need to save/restore a bunch of core registers that are 43 * We need to save/restore a bunch of core registers that are
42 * either volatile or reset to some state across a processor sleep. 44 * either volatile or reset to some state across a processor sleep.
@@ -47,6 +49,7 @@
47 * We only have to save/restore registers that aren't otherwise 49 * We only have to save/restore registers that aren't otherwise
48 * done as part of a driver pm_* function. 50 * done as part of a driver pm_* function.
49 */ 51 */
52static unsigned int sleep_usb[2];
50static unsigned int sleep_sys_clocks[5]; 53static unsigned int sleep_sys_clocks[5];
51static unsigned int sleep_sys_pinfunc; 54static unsigned int sleep_sys_pinfunc;
52static unsigned int sleep_static_memctlr[4][3]; 55static unsigned int sleep_static_memctlr[4][3];
@@ -54,6 +57,31 @@ static unsigned int sleep_static_memctlr[4][3];
54 57
55static void save_core_regs(void) 58static void save_core_regs(void)
56{ 59{
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
57 /* Clocks and PLLs. */ 85 /* Clocks and PLLs. */
58 sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); 86 sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
59 sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); 87 sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
@@ -97,6 +125,22 @@ static void restore_core_regs(void)
97 au_writel(sleep_sys_pinfunc, SYS_PINFUNC); 125 au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
98 au_sync(); 126 au_sync();
99 127
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
100 /* Restore the static memory controller configuration. */ 144 /* Restore the static memory controller configuration. */
101 au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); 145 au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
102 au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); 146 au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
@@ -126,10 +170,9 @@ void au_sleep(void)
126 case ALCHEMY_CPU_AU1200: 170 case ALCHEMY_CPU_AU1200:
127 alchemy_sleep_au1550(); 171 alchemy_sleep_au1550();
128 break; 172 break;
129 case ALCHEMY_CPU_AU1300:
130 alchemy_sleep_au1300();
131 break;
132 } 173 }
133 174
134 restore_core_regs(); 175 restore_core_regs();
135} 176}
177
178#endif /* CONFIG_PM */
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
index 37ffd997c61..1b887c86841 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 unsigned long start = ALCHEMY_PCI_MEMWIN_START; 76 u32 start = (u32)Au1500_PCI_MEM_START;
77 unsigned long end = ALCHEMY_PCI_MEMWIN_END; 77 u32 end = (u32)Au1500_PCI_MEM_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)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); 85 return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START);
86 86
87 /* default nop */ 87 /* default nop */
88 return phys_addr; 88 return phys_addr;
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S
index c7bcc7e5c82..77f3c743b71 100644
--- a/arch/mips/alchemy/common/sleeper.S
+++ b/arch/mips/alchemy/common/sleeper.S
@@ -153,79 +153,6 @@ LEAF(alchemy_sleep_au1550)
153 153
154END(alchemy_sleep_au1550) 154END(alchemy_sleep_au1550)
155 155
156/* sleepcode for Au1300 memory controller type */
157LEAF(alchemy_sleep_au1300)
158
159 SETUP_SLEEP
160
161 /* cache following instructions, as memory gets put to sleep */
162 la t0, 2f
163 la t1, 4f
164 subu t2, t1, t0
165
166 .set mips3
167
1681: cache 0x14, 0(t0)
169 subu t2, t2, 32
170 bgez t2, 1b
171 addu t0, t0, 32
172
173 .set mips0
174
1752: lui a0, 0xb400 /* mem_xxx */
176
177 /* disable all ports in mem_sdportcfga */
178 sw zero, 0x868(a0) /* mem_sdportcfga */
179 sync
180
181 /* disable ODT */
182 li t0, 0x03010000
183 sw t0, 0x08d8(a0) /* mem_sdcmd0 */
184 sw t0, 0x08dc(a0) /* mem_sdcmd1 */
185 sync
186
187 /* precharge */
188 li t0, 0x23000400
189 sw t0, 0x08dc(a0) /* mem_sdcmd1 */
190 sw t0, 0x08d8(a0) /* mem_sdcmd0 */
191 sync
192
193 /* auto refresh */
194 sw zero, 0x08c8(a0) /* mem_sdautoref */
195 sync
196
197 /* block access to the DDR */
198 lw t0, 0x0848(a0) /* mem_sdconfigb */
199 li t1, (1 << 7 | 0x3F)
200 or t0, t0, t1
201 sw t0, 0x0848(a0) /* mem_sdconfigb */
202 sync
203
204 /* issue the Self Refresh command */
205 li t0, 0x10000000
206 sw t0, 0x08dc(a0) /* mem_sdcmd1 */
207 sw t0, 0x08d8(a0) /* mem_sdcmd0 */
208 sync
209
210 /* wait for sdram to enter self-refresh mode */
211 lui t0, 0x0300
2123: lw t1, 0x0850(a0) /* mem_sdstat */
213 and t2, t1, t0
214 bne t2, t0, 3b
215 nop
216
217 /* disable SDRAM clocks */
218 li t0, ~(3<<28)
219 lw t1, 0x0840(a0) /* mem_sdconfiga */
220 and t1, t1, t0 /* clear CE[1:0] */
221 sw t1, 0x0840(a0) /* mem_sdconfiga */
222 sync
223
224 DO_SLEEP
2254:
226
227END(alchemy_sleep_au1300)
228
229 156
230 /* This is where we return upon wakeup. 157 /* This is where we return upon wakeup.
231 * Reload all of the registers and return. 158 * Reload all of the registers and return.
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
index b67930d1932..d5da6adbf63 100644
--- a/arch/mips/alchemy/common/time.c
+++ b/arch/mips/alchemy/common/time.c
@@ -53,7 +53,7 @@ static struct clocksource au1x_counter1_clocksource = {
53 .read = au1x_counter1_read, 53 .read = au1x_counter1_read,
54 .mask = CLOCKSOURCE_MASK(32), 54 .mask = CLOCKSOURCE_MASK(32),
55 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 55 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
56 .rating = 1500, 56 .rating = 100,
57}; 57};
58 58
59static int au1x_rtcmatch2_set_next_event(unsigned long delta, 59static int au1x_rtcmatch2_set_next_event(unsigned long delta,
@@ -84,7 +84,7 @@ static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id)
84static struct clock_event_device au1x_rtcmatch2_clockdev = { 84static struct clock_event_device au1x_rtcmatch2_clockdev = {
85 .name = "rtcmatch2", 85 .name = "rtcmatch2",
86 .features = CLOCK_EVT_FEAT_ONESHOT, 86 .features = CLOCK_EVT_FEAT_ONESHOT,
87 .rating = 1500, 87 .rating = 100,
88 .set_next_event = au1x_rtcmatch2_set_next_event, 88 .set_next_event = au1x_rtcmatch2_set_next_event,
89 .set_mode = au1x_rtcmatch2_set_mode, 89 .set_mode = au1x_rtcmatch2_set_mode,
90 .cpumask = cpu_all_mask, 90 .cpumask = cpu_all_mask,
@@ -92,7 +92,7 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = {
92 92
93static struct irqaction au1x_rtcmatch2_irqaction = { 93static struct irqaction au1x_rtcmatch2_irqaction = {
94 .handler = au1x_rtcmatch2_irq, 94 .handler = au1x_rtcmatch2_irq,
95 .flags = IRQF_TIMER, 95 .flags = IRQF_DISABLED | IRQF_TIMER,
96 .name = "timer", 96 .name = "timer",
97 .dev_id = &au1x_rtcmatch2_clockdev, 97 .dev_id = &au1x_rtcmatch2_clockdev,
98}; 98};
@@ -146,7 +146,7 @@ static int __init alchemy_time_init(unsigned int m2int)
146 cd->shift = 32; 146 cd->shift = 32;
147 cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift); 147 cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift);
148 cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); 148 cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
149 cd->min_delta_ns = clockevent_delta2ns(9, cd); /* ~0.28ms */ 149 cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */
150 clockevents_register_device(cd); 150 clockevents_register_device(cd);
151 setup_irq(m2int, &au1x_rtcmatch2_irqaction); 151 setup_irq(m2int, &au1x_rtcmatch2_irqaction);
152 152
@@ -158,13 +158,26 @@ cntr_err:
158 return -1; 158 return -1;
159} 159}
160 160
161static void __init alchemy_setup_c0timer(void)
162{
163 /*
164 * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this
165 * function is called. Because the Alchemy counters are unusable
166 * the C0 timekeeping code is installed and use of the 'wait'
167 * instruction must be prohibited, which is done most easily by
168 * assigning NULL to cpu_wait.
169 */
170 cpu_wait = NULL;
171 r4k_clockevent_init();
172 init_r4k_clocksource();
173}
174
161static int alchemy_m2inttab[] __initdata = { 175static int alchemy_m2inttab[] __initdata = {
162 AU1000_RTC_MATCH2_INT, 176 AU1000_RTC_MATCH2_INT,
163 AU1500_RTC_MATCH2_INT, 177 AU1500_RTC_MATCH2_INT,
164 AU1100_RTC_MATCH2_INT, 178 AU1100_RTC_MATCH2_INT,
165 AU1550_RTC_MATCH2_INT, 179 AU1550_RTC_MATCH2_INT,
166 AU1200_RTC_MATCH2_INT, 180 AU1200_RTC_MATCH2_INT,
167 AU1300_RTC_MATCH2_INT,
168}; 181};
169 182
170void __init plat_time_init(void) 183void __init plat_time_init(void)
@@ -172,7 +185,8 @@ void __init plat_time_init(void)
172 int t; 185 int t;
173 186
174 t = alchemy_get_cputype(); 187 t = alchemy_get_cputype();
175 if (t == ALCHEMY_CPU_UNKNOWN || 188 if (t == ALCHEMY_CPU_UNKNOWN)
176 alchemy_time_init(alchemy_m2inttab[t])) 189 alchemy_setup_c0timer();
177 cpu_wait = NULL; /* wait doesn't work with r4k timer */ 190 else if (alchemy_time_init(alchemy_m2inttab[t]))
191 alchemy_setup_c0timer();
178} 192}
diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c
deleted file mode 100644
index 936af8359fb..00000000000
--- a/arch/mips/alchemy/common/usb.c
+++ /dev/null
@@ -1,614 +0,0 @@
1/*
2 * USB block power/access management abstraction.
3 *
4 * Au1000+: The OHCI block control register is at the far end of the OHCI memory
5 * area. Au1550 has OHCI on different base address. No need to handle
6 * UDC here.
7 * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG
8 * as well as the PHY for EHCI and UDC.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/spinlock.h>
16#include <linux/syscore_ops.h>
17#include <asm/mach-au1x00/au1000.h>
18
19/* control register offsets */
20#define AU1000_OHCICFG 0x7fffc
21#define AU1550_OHCICFG 0x07ffc
22#define AU1200_USBCFG 0x04
23
24/* Au1000 USB block config bits */
25#define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */
26#define USBHEN_CE (1 << 3) /* OHCI block clock enable */
27#define USBHEN_E (1 << 2) /* OHCI block enable */
28#define USBHEN_C (1 << 1) /* OHCI block coherency bit */
29#define USBHEN_BE (1 << 0) /* OHCI Big-Endian */
30
31/* Au1200 USB config bits */
32#define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */
33#define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */
34#define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */
35#define USBCFG_SSD (1 << 23) /* serial short detect en */
36#define USBCFG_PPE (1 << 19) /* HS PHY PLL */
37#define USBCFG_UCE (1 << 18) /* UDC clock enable */
38#define USBCFG_ECE (1 << 17) /* EHCI clock enable */
39#define USBCFG_OCE (1 << 16) /* OHCI clock enable */
40#define USBCFG_FLA(x) (((x) & 0x3f) << 8)
41#define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */
42#define USBCFG_GME (1 << 6) /* OTG mem access */
43#define USBCFG_DBE (1 << 5) /* UDC busmaster enable */
44#define USBCFG_DME (1 << 4) /* UDC mem enable */
45#define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */
46#define USBCFG_EME (1 << 2) /* EHCI mem enable */
47#define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */
48#define USBCFG_OME (1 << 0) /* OHCI mem enable */
49#define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\
50 USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \
51 USBCFG_GME | USBCFG_DBE | USBCFG_DME | \
52 USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \
53 USBCFG_OME)
54
55/* Au1300 USB config registers */
56#define USB_DWC_CTRL1 0x00
57#define USB_DWC_CTRL2 0x04
58#define USB_VBUS_TIMER 0x10
59#define USB_SBUS_CTRL 0x14
60#define USB_MSR_ERR 0x18
61#define USB_DWC_CTRL3 0x1C
62#define USB_DWC_CTRL4 0x20
63#define USB_OTG_STATUS 0x28
64#define USB_DWC_CTRL5 0x2C
65#define USB_DWC_CTRL6 0x30
66#define USB_DWC_CTRL7 0x34
67#define USB_PHY_STATUS 0xC0
68#define USB_INT_STATUS 0xC4
69#define USB_INT_ENABLE 0xC8
70
71#define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */
72#define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */
73#define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */
74
75#define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */
76#define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */
77#define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */
78
79#define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19)
80#define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18)
81#define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17)
82#define USB_DWC_CTRL3_OTG0_CKEN (1 << 16)
83
84#define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */
85
86#define USB_INTEN_FORCE 0x20
87#define USB_INTEN_PHY 0x10
88#define USB_INTEN_UDC 0x08
89#define USB_INTEN_EHCI 0x04
90#define USB_INTEN_OHCI1 0x02
91#define USB_INTEN_OHCI0 0x01
92
93static DEFINE_SPINLOCK(alchemy_usb_lock);
94
95static inline void __au1300_usb_phyctl(void __iomem *base, int enable)
96{
97 unsigned long r, s;
98
99 r = __raw_readl(base + USB_DWC_CTRL2);
100 s = __raw_readl(base + USB_DWC_CTRL3);
101
102 s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN |
103 USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN;
104
105 if (enable) {
106 /* simply enable all PHYs */
107 r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
108 USB_DWC_CTRL2_PHYRS;
109 __raw_writel(r, base + USB_DWC_CTRL2);
110 wmb();
111 } else if (!s) {
112 /* no USB block active, do disable all PHYs */
113 r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
114 USB_DWC_CTRL2_PHYRS);
115 __raw_writel(r, base + USB_DWC_CTRL2);
116 wmb();
117 }
118}
119
120static inline void __au1300_ohci_control(void __iomem *base, int enable, int id)
121{
122 unsigned long r;
123
124 if (enable) {
125 __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */
126 wmb();
127
128 r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */
129 r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
130 : USB_DWC_CTRL3_OHCI1_CKEN;
131 __raw_writel(r, base + USB_DWC_CTRL3);
132 wmb();
133
134 __au1300_usb_phyctl(base, enable); /* power up the PHYs */
135
136 r = __raw_readl(base + USB_INT_ENABLE);
137 r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1;
138 __raw_writel(r, base + USB_INT_ENABLE);
139 wmb();
140
141 /* reset the OHCI start clock bit */
142 __raw_writel(0, base + USB_DWC_CTRL7);
143 wmb();
144 } else {
145 r = __raw_readl(base + USB_INT_ENABLE);
146 r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1);
147 __raw_writel(r, base + USB_INT_ENABLE);
148 wmb();
149
150 r = __raw_readl(base + USB_DWC_CTRL3);
151 r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
152 : USB_DWC_CTRL3_OHCI1_CKEN);
153 __raw_writel(r, base + USB_DWC_CTRL3);
154 wmb();
155
156 __au1300_usb_phyctl(base, enable);
157 }
158}
159
160static inline void __au1300_ehci_control(void __iomem *base, int enable)
161{
162 unsigned long r;
163
164 if (enable) {
165 r = __raw_readl(base + USB_DWC_CTRL3);
166 r |= USB_DWC_CTRL3_EHCI0_CKEN;
167 __raw_writel(r, base + USB_DWC_CTRL3);
168 wmb();
169
170 r = __raw_readl(base + USB_DWC_CTRL1);
171 r |= USB_DWC_CTRL1_HSTRS;
172 __raw_writel(r, base + USB_DWC_CTRL1);
173 wmb();
174
175 __au1300_usb_phyctl(base, enable);
176
177 r = __raw_readl(base + USB_INT_ENABLE);
178 r |= USB_INTEN_EHCI;
179 __raw_writel(r, base + USB_INT_ENABLE);
180 wmb();
181 } else {
182 r = __raw_readl(base + USB_INT_ENABLE);
183 r &= ~USB_INTEN_EHCI;
184 __raw_writel(r, base + USB_INT_ENABLE);
185 wmb();
186
187 r = __raw_readl(base + USB_DWC_CTRL1);
188 r &= ~USB_DWC_CTRL1_HSTRS;
189 __raw_writel(r, base + USB_DWC_CTRL1);
190 wmb();
191
192 r = __raw_readl(base + USB_DWC_CTRL3);
193 r &= ~USB_DWC_CTRL3_EHCI0_CKEN;
194 __raw_writel(r, base + USB_DWC_CTRL3);
195 wmb();
196
197 __au1300_usb_phyctl(base, enable);
198 }
199}
200
201static inline void __au1300_udc_control(void __iomem *base, int enable)
202{
203 unsigned long r;
204
205 if (enable) {
206 r = __raw_readl(base + USB_DWC_CTRL1);
207 r |= USB_DWC_CTRL1_DCRS;
208 __raw_writel(r, base + USB_DWC_CTRL1);
209 wmb();
210
211 __au1300_usb_phyctl(base, enable);
212
213 r = __raw_readl(base + USB_INT_ENABLE);
214 r |= USB_INTEN_UDC;
215 __raw_writel(r, base + USB_INT_ENABLE);
216 wmb();
217 } else {
218 r = __raw_readl(base + USB_INT_ENABLE);
219 r &= ~USB_INTEN_UDC;
220 __raw_writel(r, base + USB_INT_ENABLE);
221 wmb();
222
223 r = __raw_readl(base + USB_DWC_CTRL1);
224 r &= ~USB_DWC_CTRL1_DCRS;
225 __raw_writel(r, base + USB_DWC_CTRL1);
226 wmb();
227
228 __au1300_usb_phyctl(base, enable);
229 }
230}
231
232static inline void __au1300_otg_control(void __iomem *base, int enable)
233{
234 unsigned long r;
235 if (enable) {
236 r = __raw_readl(base + USB_DWC_CTRL3);
237 r |= USB_DWC_CTRL3_OTG0_CKEN;
238 __raw_writel(r, base + USB_DWC_CTRL3);
239 wmb();
240
241 r = __raw_readl(base + USB_DWC_CTRL1);
242 r &= ~USB_DWC_CTRL1_OTGD;
243 __raw_writel(r, base + USB_DWC_CTRL1);
244 wmb();
245
246 __au1300_usb_phyctl(base, enable);
247 } else {
248 r = __raw_readl(base + USB_DWC_CTRL1);
249 r |= USB_DWC_CTRL1_OTGD;
250 __raw_writel(r, base + USB_DWC_CTRL1);
251 wmb();
252
253 r = __raw_readl(base + USB_DWC_CTRL3);
254 r &= ~USB_DWC_CTRL3_OTG0_CKEN;
255 __raw_writel(r, base + USB_DWC_CTRL3);
256 wmb();
257
258 __au1300_usb_phyctl(base, enable);
259 }
260}
261
262static inline int au1300_usb_control(int block, int enable)
263{
264 void __iomem *base =
265 (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
266 int ret = 0;
267
268 switch (block) {
269 case ALCHEMY_USB_OHCI0:
270 __au1300_ohci_control(base, enable, 0);
271 break;
272 case ALCHEMY_USB_OHCI1:
273 __au1300_ohci_control(base, enable, 1);
274 break;
275 case ALCHEMY_USB_EHCI0:
276 __au1300_ehci_control(base, enable);
277 break;
278 case ALCHEMY_USB_UDC0:
279 __au1300_udc_control(base, enable);
280 break;
281 case ALCHEMY_USB_OTG0:
282 __au1300_otg_control(base, enable);
283 break;
284 default:
285 ret = -ENODEV;
286 }
287 return ret;
288}
289
290static inline void au1300_usb_init(void)
291{
292 void __iomem *base =
293 (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
294
295 /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4
296 * here at all: Port 2 routing (EHCI or UDC) must be set either
297 * by boot firmware or platform init code; I can't autodetect
298 * a sane setting.
299 */
300 __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */
301 wmb();
302 __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */
303 wmb();
304 __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */
305 wmb();
306 __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */
307 wmb();
308 /* set coherent access bit */
309 __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL);
310 wmb();
311}
312
313static inline void __au1200_ohci_control(void __iomem *base, int enable)
314{
315 unsigned long r = __raw_readl(base + AU1200_USBCFG);
316 if (enable) {
317 __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG);
318 wmb();
319 udelay(2000);
320 } else {
321 __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG);
322 wmb();
323 udelay(1000);
324 }
325}
326
327static inline void __au1200_ehci_control(void __iomem *base, int enable)
328{
329 unsigned long r = __raw_readl(base + AU1200_USBCFG);
330 if (enable) {
331 __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG);
332 wmb();
333 udelay(1000);
334 } else {
335 if (!(r & USBCFG_UCE)) /* UDC also off? */
336 r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
337 __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG);
338 wmb();
339 udelay(1000);
340 }
341}
342
343static inline void __au1200_udc_control(void __iomem *base, int enable)
344{
345 unsigned long r = __raw_readl(base + AU1200_USBCFG);
346 if (enable) {
347 __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG);
348 wmb();
349 } else {
350 if (!(r & USBCFG_ECE)) /* EHCI also off? */
351 r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
352 __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG);
353 wmb();
354 }
355}
356
357static inline int au1200_coherency_bug(void)
358{
359#if defined(CONFIG_DMA_COHERENT)
360 /* Au1200 AB USB does not support coherent memory */
361 if (!(read_c0_prid() & 0xff)) {
362 printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n");
363 printk(KERN_INFO "Au1200 USB: update your board or re-configure"
364 " the kernel\n");
365 return -ENODEV;
366 }
367#endif
368 return 0;
369}
370
371static inline int au1200_usb_control(int block, int enable)
372{
373 void __iomem *base =
374 (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
375 int ret = 0;
376
377 switch (block) {
378 case ALCHEMY_USB_OHCI0:
379 ret = au1200_coherency_bug();
380 if (ret && enable)
381 goto out;
382 __au1200_ohci_control(base, enable);
383 break;
384 case ALCHEMY_USB_UDC0:
385 __au1200_udc_control(base, enable);
386 break;
387 case ALCHEMY_USB_EHCI0:
388 ret = au1200_coherency_bug();
389 if (ret && enable)
390 goto out;
391 __au1200_ehci_control(base, enable);
392 break;
393 default:
394 ret = -ENODEV;
395 }
396out:
397 return ret;
398}
399
400
401/* initialize USB block(s) to a known working state */
402static inline void au1200_usb_init(void)
403{
404 void __iomem *base =
405 (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
406 __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG);
407 wmb();
408 udelay(1000);
409}
410
411static inline void au1000_usb_init(unsigned long rb, int reg)
412{
413 void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
414 unsigned long r = __raw_readl(base);
415
416#if defined(__BIG_ENDIAN)
417 r |= USBHEN_BE;
418#endif
419 r |= USBHEN_C;
420
421 __raw_writel(r, base);
422 wmb();
423 udelay(1000);
424}
425
426
427static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
428{
429 void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
430 unsigned long r = __raw_readl(base + creg);
431
432 if (enable) {
433 __raw_writel(r | USBHEN_CE, base + creg);
434 wmb();
435 udelay(1000);
436 __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg);
437 wmb();
438 udelay(1000);
439
440 /* wait for reset complete (read reg twice: au1500 erratum) */
441 while (__raw_readl(base + creg),
442 !(__raw_readl(base + creg) & USBHEN_RD))
443 udelay(1000);
444 } else {
445 __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
446 wmb();
447 }
448}
449
450static inline int au1000_usb_control(int block, int enable, unsigned long rb,
451 int creg)
452{
453 int ret = 0;
454
455 switch (block) {
456 case ALCHEMY_USB_OHCI0:
457 __au1xx0_ohci_control(enable, rb, creg);
458 break;
459 default:
460 ret = -ENODEV;
461 }
462 return ret;
463}
464
465/*
466 * alchemy_usb_control - control Alchemy on-chip USB blocks
467 * @block: USB block to target
468 * @enable: set 1 to enable a block, 0 to disable
469 */
470int alchemy_usb_control(int block, int enable)
471{
472 unsigned long flags;
473 int ret;
474
475 spin_lock_irqsave(&alchemy_usb_lock, flags);
476 switch (alchemy_get_cputype()) {
477 case ALCHEMY_CPU_AU1000:
478 case ALCHEMY_CPU_AU1500:
479 case ALCHEMY_CPU_AU1100:
480 ret = au1000_usb_control(block, enable,
481 AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
482 break;
483 case ALCHEMY_CPU_AU1550:
484 ret = au1000_usb_control(block, enable,
485 AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
486 break;
487 case ALCHEMY_CPU_AU1200:
488 ret = au1200_usb_control(block, enable);
489 break;
490 case ALCHEMY_CPU_AU1300:
491 ret = au1300_usb_control(block, enable);
492 break;
493 default:
494 ret = -ENODEV;
495 }
496 spin_unlock_irqrestore(&alchemy_usb_lock, flags);
497 return ret;
498}
499EXPORT_SYMBOL_GPL(alchemy_usb_control);
500
501
502static unsigned long alchemy_usb_pmdata[2];
503
504static void au1000_usb_pm(unsigned long br, int creg, int susp)
505{
506 void __iomem *base = (void __iomem *)KSEG1ADDR(br);
507
508 if (susp) {
509 alchemy_usb_pmdata[0] = __raw_readl(base + creg);
510 /* There appears to be some undocumented reset register.... */
511 __raw_writel(0, base + 0x04);
512 wmb();
513 __raw_writel(0, base + creg);
514 wmb();
515 } else {
516 __raw_writel(alchemy_usb_pmdata[0], base + creg);
517 wmb();
518 }
519}
520
521static void au1200_usb_pm(int susp)
522{
523 void __iomem *base =
524 (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR);
525 if (susp) {
526 /* save OTG_CAP/MUX registers which indicate port routing */
527 /* FIXME: write an OTG driver to do that */
528 alchemy_usb_pmdata[0] = __raw_readl(base + 0x00);
529 alchemy_usb_pmdata[1] = __raw_readl(base + 0x04);
530 } else {
531 /* restore access to all MMIO areas */
532 au1200_usb_init();
533
534 /* restore OTG_CAP/MUX registers */
535 __raw_writel(alchemy_usb_pmdata[0], base + 0x00);
536 __raw_writel(alchemy_usb_pmdata[1], base + 0x04);
537 wmb();
538 }
539}
540
541static void au1300_usb_pm(int susp)
542{
543 void __iomem *base =
544 (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
545 /* remember Port2 routing */
546 if (susp) {
547 alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4);
548 } else {
549 au1300_usb_init();
550 __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4);
551 wmb();
552 }
553}
554
555static void alchemy_usb_pm(int susp)
556{
557 switch (alchemy_get_cputype()) {
558 case ALCHEMY_CPU_AU1000:
559 case ALCHEMY_CPU_AU1500:
560 case ALCHEMY_CPU_AU1100:
561 au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp);
562 break;
563 case ALCHEMY_CPU_AU1550:
564 au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp);
565 break;
566 case ALCHEMY_CPU_AU1200:
567 au1200_usb_pm(susp);
568 break;
569 case ALCHEMY_CPU_AU1300:
570 au1300_usb_pm(susp);
571 break;
572 }
573}
574
575static int alchemy_usb_suspend(void)
576{
577 alchemy_usb_pm(1);
578 return 0;
579}
580
581static void alchemy_usb_resume(void)
582{
583 alchemy_usb_pm(0);
584}
585
586static struct syscore_ops alchemy_usb_pm_ops = {
587 .suspend = alchemy_usb_suspend,
588 .resume = alchemy_usb_resume,
589};
590
591static int __init alchemy_usb_init(void)
592{
593 switch (alchemy_get_cputype()) {
594 case ALCHEMY_CPU_AU1000:
595 case ALCHEMY_CPU_AU1500:
596 case ALCHEMY_CPU_AU1100:
597 au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
598 break;
599 case ALCHEMY_CPU_AU1550:
600 au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
601 break;
602 case ALCHEMY_CPU_AU1200:
603 au1200_usb_init();
604 break;
605 case ALCHEMY_CPU_AU1300:
606 au1300_usb_init();
607 break;
608 }
609
610 register_syscore_ops(&alchemy_usb_pm_ops);
611
612 return 0;
613}
614arch_initcall(alchemy_usb_init);
diff --git a/arch/mips/alchemy/common/vss.c b/arch/mips/alchemy/common/vss.c
deleted file mode 100644
index d23b1444d36..00000000000
--- a/arch/mips/alchemy/common/vss.c
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 * Au1300 media block power gating (VSS)
3 *
4 * This is a stop-gap solution until I have the clock framework integration
5 * ready. This stuff here really must be handled transparently when clocks
6 * for various media blocks are enabled/disabled.
7 */
8
9#include <linux/module.h>
10#include <linux/spinlock.h>
11#include <asm/mach-au1x00/au1000.h>
12
13#define VSS_GATE 0x00 /* gate wait timers */
14#define VSS_CLKRST 0x04 /* clock/block control */
15#define VSS_FTR 0x08 /* footers */
16
17#define VSS_ADDR(blk) (KSEG1ADDR(AU1300_VSS_PHYS_ADDR) + (blk * 0x0c))
18
19static DEFINE_SPINLOCK(au1300_vss_lock);
20
21/* enable a block as outlined in the databook */
22static inline void __enable_block(int block)
23{
24 void __iomem *base = (void __iomem *)VSS_ADDR(block);
25
26 __raw_writel(3, base + VSS_CLKRST); /* enable clock, assert reset */
27 wmb();
28
29 __raw_writel(0x01fffffe, base + VSS_GATE); /* maximum setup time */
30 wmb();
31
32 /* enable footers in sequence */
33 __raw_writel(0x01, base + VSS_FTR);
34 wmb();
35 __raw_writel(0x03, base + VSS_FTR);
36 wmb();
37 __raw_writel(0x07, base + VSS_FTR);
38 wmb();
39 __raw_writel(0x0f, base + VSS_FTR);
40 wmb();
41
42 __raw_writel(0x01ffffff, base + VSS_GATE); /* start FSM too */
43 wmb();
44
45 __raw_writel(2, base + VSS_CLKRST); /* deassert reset */
46 wmb();
47
48 __raw_writel(0x1f, base + VSS_FTR); /* enable isolation cells */
49 wmb();
50}
51
52/* disable a block as outlined in the databook */
53static inline void __disable_block(int block)
54{
55 void __iomem *base = (void __iomem *)VSS_ADDR(block);
56
57 __raw_writel(0x0f, base + VSS_FTR); /* disable isolation cells */
58 wmb();
59 __raw_writel(0, base + VSS_GATE); /* disable FSM */
60 wmb();
61 __raw_writel(3, base + VSS_CLKRST); /* assert reset */
62 wmb();
63 __raw_writel(1, base + VSS_CLKRST); /* disable clock */
64 wmb();
65 __raw_writel(0, base + VSS_FTR); /* disable all footers */
66 wmb();
67}
68
69void au1300_vss_block_control(int block, int enable)
70{
71 unsigned long flags;
72
73 if (alchemy_get_cputype() != ALCHEMY_CPU_AU1300)
74 return;
75
76 /* only one block at a time */
77 spin_lock_irqsave(&au1300_vss_lock, flags);
78 if (enable)
79 __enable_block(block);
80 else
81 __disable_block(block);
82 spin_unlock_irqrestore(&au1300_vss_lock, flags);
83}
84EXPORT_SYMBOL_GPL(au1300_vss_block_control);