1 --- a/arch/mips/au1000/common/au1xxx_irqmap.c
2 +++ b/arch/mips/au1000/common/au1xxx_irqmap.c
3 @@ -172,14 +172,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
4 { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
5 { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
6 { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
7 - { AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 },
8 - { AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
9 - { AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
10 - { AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
11 - { AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 },
12 - { AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
13 - { AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
14 - { AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
15 + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
16 + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
17 + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
18 + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
19 + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
20 + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
21 + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
22 + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
23 { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
24 { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
25 { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
26 @@ -200,14 +200,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
27 { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
28 { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
29 { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
30 - { AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 },
31 - { AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
32 - { AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
33 - { AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
34 - { AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 },
35 - { AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
36 - { AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
37 - { AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
38 + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
39 + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
40 + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
41 + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
42 + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
43 + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
44 + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
45 + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
46 { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
47 { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
48 { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
49 --- a/arch/mips/au1000/common/cputable.c
50 +++ b/arch/mips/au1000/common/cputable.c
51 @@ -39,7 +39,8 @@ struct cpu_spec cpu_specs[] = {
52 { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 },
53 { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
54 { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
55 - { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 },
56 + { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 },
57 + { 0xffffffff, 0x04030201, "Au1200 AC", 0, 0 },
58 { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
61 --- a/arch/mips/au1000/common/dbdma.c
62 +++ b/arch/mips/au1000/common/dbdma.c
64 #include <asm/au1xxx_dbdma.h>
65 #include <asm/system.h>
67 +#include <linux/module.h>
69 #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
72 @@ -60,37 +62,10 @@ static spinlock_t au1xxx_dbdma_spin_lock
74 #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1))
76 -static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
77 -static int dbdma_initialized;
78 +static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
79 +static int dbdma_initialized=0;
80 static void au1xxx_dbdma_init(void);
82 -typedef struct dbdma_device_table {
87 - u32 dev_physaddr; /* If FIFO */
89 - u32 dev_intpolarity;
92 -typedef struct dbdma_chan_config {
95 - dbdev_tab_t *chan_src;
96 - dbdev_tab_t *chan_dest;
97 - au1x_dma_chan_t *chan_ptr;
98 - au1x_ddma_desc_t *chan_desc_base;
99 - au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr;
100 - void *chan_callparam;
101 - void (*chan_callback)(int, void *, struct pt_regs *);
104 -#define DEV_FLAGS_INUSE (1 << 0)
105 -#define DEV_FLAGS_ANYUSE (1 << 1)
106 -#define DEV_FLAGS_OUT (1 << 2)
107 -#define DEV_FLAGS_IN (1 << 3)
109 static dbdev_tab_t dbdev_tab[] = {
110 #ifdef CONFIG_SOC_AU1550
112 @@ -156,13 +131,13 @@ static dbdev_tab_t dbdev_tab[] = {
113 { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
114 { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
116 - { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
117 - { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
118 - { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
119 - { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
120 + { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
121 + { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
122 + { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
123 + { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
125 - { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
126 - { DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
127 + { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
128 + { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
130 { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
131 { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
132 @@ -172,9 +147,9 @@ static dbdev_tab_t dbdev_tab[] = {
133 { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
134 { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
136 - { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
137 - { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
138 - { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
139 + { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
140 + { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
141 + { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
142 { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
144 { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
145 @@ -183,6 +158,24 @@ static dbdev_tab_t dbdev_tab[] = {
147 { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
148 { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
150 + /* Provide 16 user definable device types */
151 + { 0, 0, 0, 0, 0, 0, 0 },
152 + { 0, 0, 0, 0, 0, 0, 0 },
153 + { 0, 0, 0, 0, 0, 0, 0 },
154 + { 0, 0, 0, 0, 0, 0, 0 },
155 + { 0, 0, 0, 0, 0, 0, 0 },
156 + { 0, 0, 0, 0, 0, 0, 0 },
157 + { 0, 0, 0, 0, 0, 0, 0 },
158 + { 0, 0, 0, 0, 0, 0, 0 },
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 },
169 #define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t))
170 @@ -202,6 +195,30 @@ find_dbdev_id (u32 id)
175 +au1xxx_ddma_add_device(dbdev_tab_t *dev)
178 + dbdev_tab_t *p=NULL;
179 + static u16 new_id=0x1000;
181 + p = find_dbdev_id(0);
184 + memcpy(p, dev, sizeof(dbdev_tab_t));
185 + p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id);
189 + printk("add_device: id:%x flags:%x padd:%x\n",
190 + p->dev_id, p->dev_flags, p->dev_physaddr );
196 +EXPORT_SYMBOL(au1xxx_ddma_add_device);
198 /* Allocate a channel and return a non-zero descriptor if successful.
201 @@ -214,7 +231,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
203 dbdev_tab_t *stp, *dtp;
205 - volatile au1x_dma_chan_t *cp;
206 + au1x_dma_chan_t *cp;
208 /* We do the intialization on the first channel allocation.
209 * We have to wait because of the interrupt handler initialization
210 @@ -224,9 +241,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
212 dbdma_initialized = 1;
214 - if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS))
217 if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
218 if ((dtp = find_dbdev_id(destid)) == NULL) return 0;
220 @@ -268,9 +282,9 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
221 /* If kmalloc fails, it is caught below same
222 * as a channel not available.
224 - ctp = (chan_tab_t *)kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
225 + ctp = (chan_tab_t *)
226 + kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
227 chan_tab_ptr[i] = ctp;
228 - ctp->chan_index = chan = i;
232 @@ -278,10 +292,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
235 memset(ctp, 0, sizeof(chan_tab_t));
236 + ctp->chan_index = chan = i;
237 dcp = DDMA_CHANNEL_BASE;
238 dcp += (0x0100 * chan);
239 ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
240 - cp = (volatile au1x_dma_chan_t *)dcp;
241 + cp = (au1x_dma_chan_t *)dcp;
243 ctp->chan_dest = dtp;
244 ctp->chan_callback = callback;
245 @@ -298,6 +313,9 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
247 if (dtp->dev_intpolarity)
249 + if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
250 + (dtp->dev_flags & DEV_FLAGS_SYNC))
251 + i |= DDMA_CFG_SYNC;
255 @@ -308,14 +326,14 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 d
256 rv = (u32)(&chan_tab_ptr[chan]);
259 - /* Release devices.
261 + /* Release devices */
262 stp->dev_flags &= ~DEV_FLAGS_INUSE;
263 dtp->dev_flags &= ~DEV_FLAGS_INUSE;
268 +EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
270 /* Set the device width if source or destination is a FIFO.
271 * Should be 8, 16, or 32 bits.
272 @@ -343,6 +361,7 @@ au1xxx_dbdma_set_devwidth(u32 chanid, in
276 +EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
278 /* Allocate a descriptor ring, initializing as much as possible.
280 @@ -369,7 +388,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int
281 * and if we try that first we are likely to not waste larger
284 - desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
285 + desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
286 + GFP_KERNEL|GFP_DMA);
290 @@ -380,7 +400,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int
291 kfree((const void *)desc_base);
292 i = entries * sizeof(au1x_ddma_desc_t);
293 i += (sizeof(au1x_ddma_desc_t) - 1);
294 - if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
295 + if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
298 desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
299 @@ -460,9 +480,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int
300 /* If source input is fifo, set static address.
302 if (stp->dev_flags & DEV_FLAGS_IN) {
303 - src0 = stp->dev_physaddr;
304 - src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
305 + if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
306 + src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
308 + src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
311 + if (stp->dev_physaddr)
312 + src0 = stp->dev_physaddr;
314 /* Set up dest1. For now, assume no stride and increment.
315 * A channel attribute update can change this later.
316 @@ -486,10 +511,18 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int
317 /* If destination output is fifo, set static address.
319 if (dtp->dev_flags & DEV_FLAGS_OUT) {
320 - dest0 = dtp->dev_physaddr;
321 + if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
322 + dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
324 dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
326 + if (dtp->dev_physaddr)
327 + dest0 = dtp->dev_physaddr;
330 + printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
331 + dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
333 for (i=0; i<entries; i++) {
334 dp->dscr_cmd0 = cmd0;
335 dp->dscr_cmd1 = cmd1;
336 @@ -498,6 +531,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int
337 dp->dscr_dest0 = dest0;
338 dp->dscr_dest1 = dest1;
340 + dp->sw_context = dp->sw_status = 0;
341 dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
344 @@ -510,13 +544,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int
346 return (u32)(ctp->chan_desc_base);
348 +EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
350 /* Put a source buffer into the DMA ring.
351 * This updates the source pointer and byte count. Normally used
352 * for memory to fifo transfers.
355 -au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
356 +_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
359 au1x_ddma_desc_t *dp;
360 @@ -543,24 +578,40 @@ au1xxx_dbdma_put_source(u32 chanid, void
362 dp->dscr_source0 = virt_to_phys(buf);
363 dp->dscr_cmd1 = nbytes;
364 - dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
365 - ctp->chan_ptr->ddma_dbell = 0xffffffff; /* Make it go */
368 + if (flags & DDMA_FLAGS_IE)
369 + dp->dscr_cmd0 |= DSCR_CMD0_IE;
370 + if (flags & DDMA_FLAGS_NOIE)
371 + dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
372 /* Get next descriptor pointer.
374 ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
377 + * There is an errata on the Au1200/Au1550 parts that could result
378 + * in "stale" data being DMA'd. It has to do with the snoop logic on
379 + * the dache eviction buffer. NONCOHERENT_IO is on by default for
380 + * these parts. If it is fixedin the future, these dma_cache_inv will
381 + * just be nothing more than empty macros. See io.h.
383 + dma_cache_wback_inv(buf,nbytes);
384 + dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
386 + dma_cache_wback_inv(dp, sizeof(dp));
387 + ctp->chan_ptr->ddma_dbell = 0;
389 /* return something not zero.
393 +EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
395 /* Put a destination buffer into the DMA ring.
396 * This updates the destination pointer and byte count. Normally used
397 * to place an empty buffer into the ring for fifo to memory transfers.
400 -au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
401 +_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
404 au1x_ddma_desc_t *dp;
405 @@ -582,11 +633,33 @@ au1xxx_dbdma_put_dest(u32 chanid, void *
406 if (dp->dscr_cmd0 & DSCR_CMD0_V)
409 - /* Load up buffer address and byte count.
411 + /* Load up buffer address and byte count */
414 + if (flags & DDMA_FLAGS_IE)
415 + dp->dscr_cmd0 |= DSCR_CMD0_IE;
416 + if (flags & DDMA_FLAGS_NOIE)
417 + dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
419 dp->dscr_dest0 = virt_to_phys(buf);
420 dp->dscr_cmd1 = nbytes;
422 + printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
423 + dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
424 + dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
427 + * There is an errata on the Au1200/Au1550 parts that could result in
428 + * "stale" data being DMA'd. It has to do with the snoop logic on the
429 + * dache eviction buffer. NONCOHERENT_IO is on by default for these
430 + * parts. If it is fixedin the future, these dma_cache_inv will just
431 + * be nothing more than empty macros. See io.h.
433 + dma_cache_inv(buf,nbytes);
434 dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
436 + dma_cache_wback_inv(dp, sizeof(dp));
437 + ctp->chan_ptr->ddma_dbell = 0;
439 /* Get next descriptor pointer.
441 @@ -596,6 +669,7 @@ au1xxx_dbdma_put_dest(u32 chanid, void *
445 +EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
447 /* Get a destination buffer into the DMA ring.
448 * Normally used to get a full buffer from the ring during fifo
449 @@ -645,7 +719,7 @@ void
450 au1xxx_dbdma_stop(u32 chanid)
453 - volatile au1x_dma_chan_t *cp;
454 + au1x_dma_chan_t *cp;
455 int halt_timeout = 0;
457 ctp = *((chan_tab_t **)chanid);
458 @@ -665,6 +739,7 @@ au1xxx_dbdma_stop(u32 chanid)
459 cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
462 +EXPORT_SYMBOL(au1xxx_dbdma_stop);
464 /* Start using the current descriptor pointer. If the dbdma encounters
465 * a not valid descriptor, it will stop. In this case, we can just
466 @@ -674,17 +749,17 @@ void
467 au1xxx_dbdma_start(u32 chanid)
470 - volatile au1x_dma_chan_t *cp;
471 + au1x_dma_chan_t *cp;
473 ctp = *((chan_tab_t **)chanid);
476 cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
477 cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */
479 - cp->ddma_dbell = 0xffffffff; /* Make it go */
480 + cp->ddma_dbell = 0;
483 +EXPORT_SYMBOL(au1xxx_dbdma_start);
486 au1xxx_dbdma_reset(u32 chanid)
487 @@ -703,15 +778,21 @@ au1xxx_dbdma_reset(u32 chanid)
490 dp->dscr_cmd0 &= ~DSCR_CMD0_V;
491 + /* reset our SW status -- this is used to determine
492 + * if a descriptor is in use by upper level SW. Since
493 + * posting can reset 'V' bit.
496 dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
497 } while (dp != ctp->chan_desc_base);
499 +EXPORT_SYMBOL(au1xxx_dbdma_reset);
502 au1xxx_get_dma_residue(u32 chanid)
505 - volatile au1x_dma_chan_t *cp;
506 + au1x_dma_chan_t *cp;
509 ctp = *((chan_tab_t **)chanid);
510 @@ -746,15 +827,16 @@ au1xxx_dbdma_chan_free(u32 chanid)
514 +EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
517 dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
520 + u32 intstat, flags;
523 au1x_ddma_desc_t *dp;
524 - volatile au1x_dma_chan_t *cp;
525 + au1x_dma_chan_t *cp;
527 intstat = dbdma_gptr->ddma_intstat;
529 @@ -773,18 +855,26 @@ dbdma_interrupt(int irq, void *dev_id, s
530 (ctp->chan_callback)(irq, ctp->chan_callparam, regs);
532 ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
537 -au1xxx_dbdma_init(void)
538 +static void au1xxx_dbdma_init(void)
542 dbdma_gptr->ddma_config = 0;
543 dbdma_gptr->ddma_throttle = 0;
544 dbdma_gptr->ddma_inten = 0xffff;
547 - if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT,
548 +#if defined(CONFIG_SOC_AU1550)
549 + irq_nr = AU1550_DDMA_INT;
550 +#elif defined(CONFIG_SOC_AU1200)
551 + irq_nr = AU1200_DDMA_INT;
553 + #error Unknown Au1x00 SOC
556 + if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT,
557 "Au1xxx dbdma", (void *)dbdma_gptr))
558 printk("Can't get 1550 dbdma irq");
560 @@ -795,7 +885,8 @@ au1xxx_dbdma_dump(u32 chanid)
562 au1x_ddma_desc_t *dp;
563 dbdev_tab_t *stp, *dtp;
564 - volatile au1x_dma_chan_t *cp;
565 + au1x_dma_chan_t *cp;
568 ctp = *((chan_tab_t **)chanid);
570 @@ -820,15 +911,64 @@ au1xxx_dbdma_dump(u32 chanid)
571 dp = ctp->chan_desc_base;
574 - printk("dp %08x, cmd0 %08x, cmd1 %08x\n",
575 - (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
576 - printk("src0 %08x, src1 %08x, dest0 %08x\n",
577 - dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0);
578 - printk("dest1 %08x, stat %08x, nxtptr %08x\n",
579 - dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr);
580 + printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
581 + i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
582 + printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
583 + dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
584 + printk("stat %08x, nxtptr %08x\n",
585 + dp->dscr_stat, dp->dscr_nxtptr);
586 dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
587 } while (dp != ctp->chan_desc_base);
590 +/* Put a descriptor into the DMA ring.
591 + * This updates the source/destination pointers and byte count.
594 +au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
597 + au1x_ddma_desc_t *dp;
600 + /* I guess we could check this to be within the
601 + * range of the table......
603 + ctp = *((chan_tab_t **)chanid);
605 + /* We should have multiple callers for a particular channel,
606 + * an interrupt doesn't affect this pointer nor the descriptor,
607 + * so no locking should be needed.
611 + /* If the descriptor is valid, we are way ahead of the DMA
612 + * engine, so just return an error condition.
614 + if (dp->dscr_cmd0 & DSCR_CMD0_V)
617 + /* Load up buffer addresses and byte count.
619 + dp->dscr_dest0 = dscr->dscr_dest0;
620 + dp->dscr_source0 = dscr->dscr_source0;
621 + dp->dscr_dest1 = dscr->dscr_dest1;
622 + dp->dscr_source1 = dscr->dscr_source1;
623 + dp->dscr_cmd1 = dscr->dscr_cmd1;
624 + nbytes = dscr->dscr_cmd1;
625 + /* Allow the caller to specifiy if an interrupt is generated */
626 + dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
627 + dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
628 + ctp->chan_ptr->ddma_dbell = 0;
630 + /* Get next descriptor pointer.
632 + ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
634 + /* return something not zero.
639 #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
642 +++ b/arch/mips/au1000/common/gpio.c
645 + * This program is free software; you can redistribute it and/or modify it
646 + * under the terms of the GNU General Public License as published by the
647 + * Free Software Foundation; either version 2 of the License, or (at your
648 + * option) any later version.
650 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
651 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
652 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
653 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
654 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
655 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
656 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
657 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
658 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
659 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
661 + * You should have received a copy of the GNU General Public License along
662 + * with this program; if not, write to the Free Software Foundation, Inc.,
663 + * 675 Mass Ave, Cambridge, MA 02139, USA.
666 +#include <asm/au1000.h>
667 +#include <asm/au1xxx_gpio.h>
670 +#if !defined(CONFIG_SOC_AU1000)
671 +static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE;
673 +#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
675 +int au1xxx_gpio2_read(int signal)
678 +/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */
679 + return ((gpio2->pinstate >> signal) & 0x01);
682 +void au1xxx_gpio2_write(int signal, int value)
686 + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) |
690 +void au1xxx_gpio2_tristate(int signal)
693 + gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */
697 +int au1xxx_gpio1_read(int signal)
699 +/* gpio1->trioutclr |= (0x01 << signal); */
700 + return ((gpio1->pinstaterd >> signal) & 0x01);
703 +void au1xxx_gpio1_write(int signal, int value)
706 + gpio1->outputset = (0x01 << signal);
708 + gpio1->outputclr = (0x01 << signal); /* Output a Zero */
711 +void au1xxx_gpio1_tristate(int signal)
713 + gpio1->trioutclr = (0x01 << signal); /* Tristate signal */
717 +int au1xxx_gpio_read(int signal)
720 +#if defined(CONFIG_SOC_AU1000)
723 + return au1xxx_gpio2_read(signal);
726 + return au1xxx_gpio1_read(signal);
729 +void au1xxx_gpio_write(int signal, int value)
732 +#if defined(CONFIG_SOC_AU1000)
735 + au1xxx_gpio2_write(signal, value);
738 + au1xxx_gpio1_write(signal, value);
741 +void au1xxx_gpio_tristate(int signal)
744 +#if defined(CONFIG_SOC_AU1000)
747 + au1xxx_gpio2_tristate(signal);
750 + au1xxx_gpio1_tristate(signal);
753 +void au1xxx_gpio1_set_inputs(void)
755 + gpio1->pininputen = 0;
758 +EXPORT_SYMBOL(au1xxx_gpio1_set_inputs);
759 +EXPORT_SYMBOL(au1xxx_gpio_tristate);
760 +EXPORT_SYMBOL(au1xxx_gpio_write);
761 +EXPORT_SYMBOL(au1xxx_gpio_read);
762 --- a/arch/mips/au1000/common/irq.c
763 +++ b/arch/mips/au1000/common/irq.c
764 @@ -303,8 +303,30 @@ static struct hw_interrupt_type level_ir
768 -void startup_match20_interrupt(void)
769 +void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *))
771 + static struct irqaction action;
772 + /* This is a big problem.... since we didn't use request_irq
773 + when kernel/irq.c calls probe_irq_xxx this interrupt will
774 + be probed for usage. This will end up disabling the device :(
776 + Give it a bogus "action" pointer -- this will keep it from
777 + getting auto-probed!
779 + By setting the status to match that of request_irq() we
780 + can avoid it. --cgray
782 + action.dev_id = handler;
785 + action.name = "Au1xxx TOY";
786 + action.handler = handler;
787 + action.next = NULL;
789 + irq_desc[AU1000_TOY_MATCH2_INT].action = &action;
790 + irq_desc[AU1000_TOY_MATCH2_INT].status
791 + &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
793 local_enable_irq(AU1000_TOY_MATCH2_INT);
796 @@ -508,6 +530,7 @@ void intc0_req0_irqdispatch(struct pt_re
798 if (!intc0_req0) return;
800 +#ifdef AU1000_USB_DEV_REQ_INT
802 * Because of the tight timing of SETUP token to reply
803 * transactions, the USB devices-side packet complete
804 @@ -518,6 +541,7 @@ void intc0_req0_irqdispatch(struct pt_re
805 do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
810 irq = au_ffs(intc0_req0) - 1;
811 intc0_req0 &= ~(1<<irq);
812 @@ -536,17 +560,7 @@ void intc0_req1_irqdispatch(struct pt_re
814 irq = au_ffs(intc0_req1) - 1;
815 intc0_req1 &= ~(1<<irq);
817 - if (irq == AU1000_TOY_MATCH2_INT) {
818 - mask_and_ack_rise_edge_irq(irq);
819 - counter0_irq(irq, NULL, regs);
820 - local_enable_irq(irq);
831 --- a/arch/mips/au1000/common/Makefile
832 +++ b/arch/mips/au1000/common/Makefile
833 @@ -19,9 +19,9 @@ O_TARGET := au1000.o
834 export-objs = prom.o clocks.o power.o usbdev.o
836 obj-y := prom.o int-handler.o irq.o puts.o time.o reset.o cputable.o \
837 - au1xxx_irqmap.o clocks.o power.o setup.o sleeper.o dma.o dbdma.o
838 + au1xxx_irqmap.o clocks.o power.o setup.o sleeper.o dma.o dbdma.o gpio.o
840 -export-objs += dma.o dbdma.o
841 +export-objs += dma.o dbdma.o gpio.o
843 obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o
844 obj-$(CONFIG_KGDB) += dbg_io.o
845 --- a/arch/mips/au1000/common/pci_fixup.c
846 +++ b/arch/mips/au1000/common/pci_fixup.c
847 @@ -75,9 +75,13 @@ void __init pcibios_fixup(void)
849 #ifdef CONFIG_NONCOHERENT_IO
851 - * Set the NC bit in controller for pre-AC silicon
852 + * Set the NC bit in controller for Au1500 pre-AC silicon
854 - au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
855 + u32 prid = read_c0_prid();
856 + if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
857 + au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
858 + printk("Non-coherent PCI accesses enabled\n");
860 printk("Non-coherent PCI accesses enabled\n");
863 --- a/arch/mips/au1000/common/pci_ops.c
864 +++ b/arch/mips/au1000/common/pci_ops.c
865 @@ -162,6 +162,7 @@ unsigned long last_entryLo0, last_entryL
866 static int config_access(unsigned char access_type, struct pci_dev *dev,
867 unsigned char where, u32 * data)
869 + int error = PCIBIOS_SUCCESSFUL;
870 #if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
871 unsigned char bus = dev->bus->number;
872 unsigned int dev_fn = dev->devfn;
873 @@ -170,7 +171,6 @@ static int config_access(unsigned char a
874 unsigned long offset, status;
875 unsigned long cfg_base;
877 - int error = PCIBIOS_SUCCESSFUL;
878 unsigned long entryLo0, entryLo1;
881 @@ -205,9 +205,8 @@ static int config_access(unsigned char a
882 last_entryLo0 = last_entryLo1 = 0xffffffff;
885 - /* Since the Au1xxx doesn't do the idsel timing exactly to spec,
886 - * many board vendors implement their own off-chip idsel, so call
887 - * it now. If it doesn't succeed, may as well bail out at this point.
888 + /* Allow board vendors to implement their own off-chip idsel.
889 + * If it doesn't succeed, may as well bail out at this point.
891 if (board_pci_idsel) {
892 if (board_pci_idsel(device, 1) == 0) {
893 @@ -271,8 +270,11 @@ static int config_access(unsigned char a
896 local_irq_restore(flags);
899 + /* Fake out Config space access with no responder */
900 + *data = 0xFFFFFFFF;
906 --- a/arch/mips/au1000/common/power.c
907 +++ b/arch/mips/au1000/common/power.c
910 static void calibrate_delay(void);
912 -extern void set_au1x00_speed(unsigned int new_freq);
913 extern unsigned int get_au1x00_speed(void);
914 extern unsigned long get_au1x00_uart_baud_base(void);
915 extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
916 @@ -116,6 +115,7 @@ save_core_regs(void)
917 sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
918 sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
920 +#ifndef CONFIG_SOC_AU1200
921 /* Shutdown USB host/device.
923 sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
924 @@ -127,6 +127,7 @@ save_core_regs(void)
926 sleep_usbdev_enable = au_readl(USBD_ENABLE);
927 au_writel(0, USBD_ENABLE); au_sync();
930 /* Save interrupt controller state.
932 @@ -212,14 +213,12 @@ void wakeup_from_suspend(void)
935 unsigned long wakeup, flags;
936 - extern void save_and_sleep(void);
937 + extern unsigned int save_and_sleep(void);
939 spin_lock_irqsave(&pm_lock,flags);
945 /** The code below is all system dependent and we should probably
946 ** have a function call out of here to set this up. You need
947 ** to configure the GPIO or timer interrupts that will bring
948 @@ -227,27 +226,26 @@ int au_sleep(void)
949 ** For testing, the TOY counter wakeup is useful.
954 au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
956 /* gpio 6 can cause a wake up event */
957 wakeup = au_readl(SYS_WAKEMSK);
958 wakeup &= ~(1 << 8); /* turn off match20 wakeup */
959 - wakeup |= 1 << 6; /* turn on gpio 6 wakeup */
960 + wakeup = 1 << 5; /* turn on gpio 6 wakeup */
962 - /* For testing, allow match20 to wake us up.
964 + /* For testing, allow match20 to wake us up. */
965 #ifdef SLEEP_TEST_TIMEOUT
966 wakeup_counter0_set(sleep_ticks);
968 wakeup = 1 << 8; /* turn on match20 wakeup */
971 - au_writel(1, SYS_WAKESRC); /* clear cause */
972 + au_writel(0, SYS_WAKESRC); /* clear cause */
974 au_writel(wakeup, SYS_WAKEMSK);
977 + DPRINTK("Entering sleep!\n");
980 /* after a wakeup, the cpu vectors back to 0x1fc00000 so
981 @@ -255,6 +253,7 @@ int au_sleep(void)
984 spin_unlock_irqrestore(&pm_lock, flags);
985 + DPRINTK("Leaving sleep!\n");
989 @@ -285,7 +284,6 @@ static int pm_do_sleep(ctl_table * ctl,
995 retval = pm_send_all(PM_RESUME, (void *) 0);
997 @@ -296,7 +294,6 @@ static int pm_do_suspend(ctl_table * ctl
998 void *buffer, size_t * len)
1001 - void au1k_wait(void);
1005 @@ -305,119 +302,9 @@ static int pm_do_suspend(ctl_table * ctl
1010 - retval = pm_send_all(PM_RESUME, (void *) 0);
1016 -static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
1017 - void *buffer, size_t * len)
1019 - int retval = 0, i;
1020 - unsigned long val, pll;
1021 -#define TMPBUFLEN 64
1022 -#define MAX_CPU_FREQ 396
1023 - char buf[TMPBUFLEN], *p;
1024 - unsigned long flags, intc0_mask, intc1_mask;
1025 - unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
1027 - unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
1029 - spin_lock_irqsave(&pm_lock, flags);
1033 - /* Parse the new frequency */
1034 - if (*len > TMPBUFLEN - 1) {
1035 - spin_unlock_irqrestore(&pm_lock, flags);
1038 - if (copy_from_user(buf, buffer, *len)) {
1039 - spin_unlock_irqrestore(&pm_lock, flags);
1044 - val = simple_strtoul(p, &p, 0);
1045 - if (val > MAX_CPU_FREQ) {
1046 - spin_unlock_irqrestore(&pm_lock, flags);
1051 - if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */
1052 - /* revisit this for higher speed cpus */
1053 - spin_unlock_irqrestore(&pm_lock, flags);
1057 - old_baud_base = get_au1x00_uart_baud_base();
1058 - old_cpu_freq = get_au1x00_speed();
1060 - new_cpu_freq = pll * 12 * 1000000;
1061 - new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
1062 - set_au1x00_speed(new_cpu_freq);
1063 - set_au1x00_uart_baud_base(new_baud_base);
1065 - old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
1067 - ((old_refresh * new_cpu_freq) /
1068 - old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
1070 - au_writel(pll, SYS_CPUPLL);
1072 - au_writel(new_refresh, MEM_SDREFCFG);
1075 - for (i = 0; i < 4; i++) {
1077 - (UART_BASE + UART_MOD_CNTRL +
1078 - i * 0x00100000) == 3) {
1080 - au_readl(UART_BASE + UART_CLK +
1082 - // baud_rate = baud_base/clk
1083 - baud_rate = old_baud_base / old_clk;
1084 - /* we won't get an exact baud rate and the error
1085 - * could be significant enough that our new
1086 - * calculation will result in a clock that will
1087 - * give us a baud rate that's too far off from
1088 - * what we really want.
1090 - if (baud_rate > 100000)
1091 - baud_rate = 115200;
1092 - else if (baud_rate > 50000)
1093 - baud_rate = 57600;
1094 - else if (baud_rate > 30000)
1095 - baud_rate = 38400;
1096 - else if (baud_rate > 17000)
1097 - baud_rate = 19200;
1099 - (baud_rate = 9600);
1100 - // new_clk = new_baud_base/baud_rate
1101 - new_clk = new_baud_base / baud_rate;
1102 - au_writel(new_clk,
1103 - UART_BASE + UART_CLK +
1105 - au_sync_delay(10);
1108 + retval = pm_send_all(PM_RESUME, (void *) 0);
1112 - /* We don't want _any_ interrupts other than
1113 - * match20. Otherwise our calibrate_delay()
1114 - * calculation will be off, potentially a lot.
1116 - intc0_mask = save_local_and_disable(0);
1117 - intc1_mask = save_local_and_disable(1);
1118 - local_enable_irq(AU1000_TOY_MATCH2_INT);
1119 - spin_unlock_irqrestore(&pm_lock, flags);
1120 - calibrate_delay();
1121 - restore_local_and_enable(0, intc0_mask);
1122 - restore_local_and_enable(1, intc1_mask);
1126 @@ -425,7 +312,6 @@ static int pm_do_freq(ctl_table * ctl, i
1127 static struct ctl_table pm_table[] = {
1128 {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend},
1129 {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep},
1130 - {CTL_ACPI, "freq", NULL, 0, 0600, NULL, &pm_do_freq},
1134 --- a/arch/mips/au1000/common/reset.c
1135 +++ b/arch/mips/au1000/common/reset.c
1137 #include <asm/system.h>
1138 #include <asm/au1000.h>
1140 -extern int au_sleep(void);
1142 void au1000_restart(char *command)
1144 /* Set all integrated peripherals to disabled states */
1145 @@ -144,6 +142,26 @@ void au1000_restart(char *command)
1146 au_writel(0x00, 0xb1900064); /* sys_auxpll */
1147 au_writel(0x00, 0xb1900100); /* sys_pininputen */
1149 + case 0x04000000: /* Au1200 */
1150 + au_writel(0x00, 0xb400300c); /* ddma */
1151 + au_writel(0x00, 0xb1a00004); /* psc 0 */
1152 + au_writel(0x00, 0xb1b00004); /* psc 1 */
1153 + au_writel(0x00d02000, 0xb4020004); /* ehci, ohci, udc, otg */
1154 + au_writel(0x00, 0xb5000004); /* lcd */
1155 + au_writel(0x00, 0xb060000c); /* sd0 */
1156 + au_writel(0x00, 0xb068000c); /* sd1 */
1157 + au_writel(0x00, 0xb1100100); /* swcnt */
1158 + au_writel(0x00, 0xb0300000); /* aes */
1159 + au_writel(0x00, 0xb4004000); /* cim */
1160 + au_writel(0x00, 0xb1100100); /* uart0_enable */
1161 + au_writel(0x00, 0xb1200100); /* uart1_enable */
1162 + au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
1163 + au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
1164 + au_writel(0x00, 0xb1900028); /* sys_clksrc */
1165 + au_writel(0x10, 0xb1900060); /* sys_cpupll */
1166 + au_writel(0x00, 0xb1900064); /* sys_auxpll */
1167 + au_writel(0x00, 0xb1900100); /* sys_pininputen */
1172 @@ -163,32 +181,23 @@ void au1000_restart(char *command)
1174 void au1000_halt(void)
1176 -#if defined(CONFIG_MIPS_PB1550)
1177 - /* power off system */
1178 - printk("\n** Powering off Pb1550\n");
1179 - au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
1181 - while(1); /* should not get here */
1183 - printk(KERN_NOTICE "\n** You can safely turn off the power\n");
1184 -#ifdef CONFIG_MIPS_MIRAGE
1185 - au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
1190 - /* should not get here */
1191 - printk(KERN_ERR "Unable to put cpu in sleep mode\n");
1195 + /* Use WAIT in a low-power infinite spin loop */
1197 __asm__(".set\tmips3\n\t"
1204 void au1000_power_off(void)
1206 + extern void board_power_off (void);
1208 + printk(KERN_NOTICE "\n** You can safely turn off the power\n");
1210 + /* Give board a chance to power-off */
1211 + board_power_off();
1213 + /* If board can't power-off, spin forever */
1216 --- a/arch/mips/au1000/common/setup.c
1217 +++ b/arch/mips/au1000/common/setup.c
1218 @@ -174,6 +174,40 @@ void __init au1x00_setup(void)
1219 initrd_end = (unsigned long)&__rd_end;
1222 +#if defined(CONFIG_SOC_AU1200)
1223 +#ifdef CONFIG_USB_EHCI_HCD
1224 + if ((argptr = strstr(argptr, "usb_ehci=")) == NULL) {
1225 + char usb_args[80];
1226 + argptr = prom_getcmdline();
1227 + memset(usb_args, 0, sizeof(usb_args));
1228 + sprintf(usb_args, " usb_ehci=base:0x%x,len:0x%x,irq:%d",
1229 + USB_EHCI_BASE, USB_EHCI_LEN, AU1000_USB_HOST_INT);
1230 + strcat(argptr, usb_args);
1232 +#ifdef CONFIG_USB_AMD5536UDC
1233 + /* enable EHC + OHC + UDC clocks, memory and bus mastering */
1234 +/* au_writel( 0x00DF207F, USB_MSR_BASE + 4); */
1235 + au_writel( 0xC0DF207F, USB_MSR_BASE + 4); // incl. prefetch
1237 + /* enable EHC + OHC clocks, memory and bus mastering */
1238 +/* au_writel( 0x00DB200F, USB_MSR_BASE + 4); */
1239 + au_writel( 0xC0DB200F, USB_MSR_BASE + 4); /* incl. prefetch */
1243 +#else /* CONFIG_USB_EHCI_HCD */
1245 +#ifdef CONFIG_USB_AMD5536UDC
1246 +#ifndef CONFIG_USB_OHCI
1247 + /* enable UDC clocks, memory and bus mastering */
1248 +/* au_writel( 0x00DC2070, USB_MSR_BASE + 4); */
1249 + au_writel( 0xC0DC2070, USB_MSR_BASE + 4); // incl. prefetch
1253 +#endif /* CONFIG_USB_EHCI_HCD */
1254 +#endif /* CONFIG_SOC_AU1200 */
1256 #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
1257 #ifdef CONFIG_USB_OHCI
1258 if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
1259 @@ -187,19 +221,38 @@ void __init au1x00_setup(void)
1262 #ifdef CONFIG_USB_OHCI
1263 - // enable host controller and wait for reset done
1264 +#if defined(CONFIG_SOC_AU1200)
1265 +#ifndef CONFIG_USB_EHCI_HCD
1266 +#ifdef CONFIG_USB_AMD5536UDC
1267 + /* enable OHC + UDC clocks, memory and bus mastering */
1268 +/* au_writel( 0x00DD2073, USB_MSR_BASE + 4); */
1269 + au_writel( 0xC0DD2073, USB_MSR_BASE + 4); // incl. prefetch
1271 + /* enable OHC clocks, memory and bus mastering */
1272 + au_writel( 0x00D12003, USB_MSR_BASE + 4);
1275 +printk("DEBUG: Reading Au1200 USB2 reg 0x%x\n", au_readl(USB_MSR_BASE + 4));
1278 + /* Au1000, Au1500, Au1100, Au1550 */
1279 + /* enable host controller and wait for reset done */
1280 au_writel(0x08, USB_HOST_CONFIG);
1282 au_writel(0x0E, USB_HOST_CONFIG);
1284 - au_readl(USB_HOST_CONFIG); // throw away first read
1285 + au_readl(USB_HOST_CONFIG); /* throw away first read */
1286 while (!(au_readl(USB_HOST_CONFIG) & 0x10))
1287 au_readl(USB_HOST_CONFIG);
1288 +#endif /* CONFIG_SOC_AU1200 */
1290 -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
1293 +#endif /* defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) */
1297 - // Needed if PCI video card in use
1298 + /* Needed if PCI video card in use */
1299 conswitchp = &dummy_con;
1302 @@ -209,8 +262,7 @@ void __init au1x00_setup(void)
1305 #ifdef CONFIG_BLK_DEV_IDE
1306 - /* Board setup takes precedence for unique devices.
1308 + /* Board setup takes precedence for unique devices. */
1309 if ((ide_ops == NULL) || (ide_ops == &no_ide_ops))
1310 ide_ops = &std_ide_ops;
1312 --- a/arch/mips/au1000/common/sleeper.S
1313 +++ b/arch/mips/au1000/common/sleeper.S
1315 #include <asm/addrspace.h>
1316 #include <asm/regdef.h>
1317 #include <asm/stackframe.h>
1318 +#include <asm/au1000.h>
1321 + * Note: This file is *not* conditional on CONFIG_PM since Alchemy sleep
1322 + * need not be tied to any particular power management scheme.
1325 + .extern ___flush_cache_all
1332 -/* Save all of the processor general registers and go to sleep.
1333 - * A wakeup condition will get us back here to restore the registers.
1335 + * Save the processor general registers and go to sleep. A wakeup
1336 + * condition will get us back here to restore the registers.
1338 -LEAF(save_and_sleep)
1340 +/* still need to fix alignment issues here */
1341 +save_and_sleep_frmsz = 48
1342 +NESTED(save_and_sleep, save_and_sleep_frmsz, ra)
1346 + subu sp, save_and_sleep_frmsz
1347 + sw ra, save_and_sleep_frmsz-4(sp)
1348 + sw s0, save_and_sleep_frmsz-8(sp)
1349 + sw s1, save_and_sleep_frmsz-12(sp)
1350 + sw s2, save_and_sleep_frmsz-16(sp)
1351 + sw s3, save_and_sleep_frmsz-20(sp)
1352 + sw s4, save_and_sleep_frmsz-24(sp)
1353 + sw s5, save_and_sleep_frmsz-28(sp)
1354 + sw s6, save_and_sleep_frmsz-32(sp)
1355 + sw s7, save_and_sleep_frmsz-36(sp)
1356 + sw s8, save_and_sleep_frmsz-40(sp)
1357 + sw gp, save_and_sleep_frmsz-44(sp)
1359 + /* We only need to save the registers that the calling function
1360 + * hasn't saved for us. 0 is always zero. 8 - 15, 24 and 25 are
1361 + * temporaries and can be used without saving. 26 and 27 are reserved
1362 + * for interrupt/trap handling and expected to change. 29 is the
1363 + * stack pointer which is handled as a special case here.
1368 @@ -34,14 +65,6 @@ LEAF(save_and_sleep)
1374 - sw $10, PT_R10(sp)
1375 - sw $11, PT_R11(sp)
1376 - sw $12, PT_R12(sp)
1377 - sw $13, PT_R13(sp)
1378 - sw $14, PT_R14(sp)
1379 - sw $15, PT_R15(sp)
1383 @@ -50,32 +73,47 @@ LEAF(save_and_sleep)
1387 - sw $24, PT_R24(sp)
1388 - sw $25, PT_R25(sp)
1389 - sw $26, PT_R26(sp)
1390 - sw $27, PT_R27(sp)
1392 - sw $29, PT_R29(sp)
1395 +#define PT_C0STATUS PT_LO
1396 +#define PT_CONTEXT PT_HI
1397 +#define PT_PAGEMASK PT_EPC
1398 +#define PT_CONFIG PT_BVADDR
1401 + sw k0, PT_C0STATUS(sp) // 0x20
1402 mfc0 k0, CP0_CONTEXT
1404 + sw k0, PT_CONTEXT(sp) // 0x1c
1405 mfc0 k0, CP0_PAGEMASK
1407 + sw k0, PT_PAGEMASK(sp) // 0x18
1410 + sw k0, PT_CONFIG(sp) // 0x14
1416 + sw zero, 0(t0) /* Get the processor ready to sleep */
1419 /* Now set up the scratch registers so the boot rom will
1420 * return to this point upon wakeup.
1421 + * sys_scratch0 : SP
1422 + * sys_scratch1 : RA
1424 + li t0, SYS_SCRATCH0
1425 + li t1, SYS_SCRATCH1
1427 + la k0, resume_from_sleep
1431 + * Flush DCACHE to make sure context is in memory
1439 + la t1,___flush_cache_all /* _flush_cache_all is a function pointer */
1444 /* Put SDRAM into self refresh. Preload instructions into cache,
1445 * issue a precharge, then auto refresh, then sleep commands to it.
1446 @@ -88,30 +126,65 @@ LEAF(save_and_sleep)
1450 + /* Put SDRAM to sleep */
1453 - sw zero, 0x001c(k0) /* Precharge */
1454 - sw zero, 0x0020(k0) /* Auto refresh */
1455 - sw zero, 0x0030(k0) /* SDRAM sleep */
1456 + li a0, MEM_PHYS_ADDR
1457 + or a0, a0, 0xA0000000
1458 +#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1500)
1459 + lw k0, MEM_SDMODE0(a0)
1460 + sw zero, MEM_SDPRECMD(a0) /* Precharge */
1461 + sw zero, MEM_SDAUTOREF(a0) /* Auto Refresh */
1462 + sw zero, MEM_SDSLEEP(a0) /* Sleep */
1466 - sw zero, 0x0078(k1) /* get ready to sleep */
1468 +#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
1469 + sw zero, MEM_SDPRECMD(a0) /* Precharge */
1470 + sw zero, MEM_SDSREF(a0)
1472 + #lw t0, MEM_SDSTAT(a0)
1473 + #and t0, t0, 0x01000000
1476 + lw t1, MEM_SDSTAT(a0)
1478 + beq zero, t2, refresh_not_set
1481 + li t0, ~0x30000000
1482 + lw t1, MEM_SDCONFIGA(a0)
1484 + sw t1, MEM_SDCONFIGA(a0)
1486 - sw zero, 0x007c(k1) /* Put processor to sleep */
1490 + sw zero, 0(t0) /* Put processor to sleep */
1502 /* This is where we return upon wakeup.
1503 * Reload all of the registers and return.
1512 + lw k0, PT_C0STATUS(sp) // 0x20
1515 + lw k0, PT_CONTEXT(sp) // 0x1c
1516 mtc0 k0, CP0_CONTEXT
1518 + lw k0, PT_PAGEMASK(sp) // 0x18
1519 mtc0 k0, CP0_PAGEMASK
1521 + lw k0, PT_CONFIG(sp) // 0x14
1525 @@ -120,14 +193,6 @@ sdsleep:
1531 - lw $10, PT_R10(sp)
1532 - lw $11, PT_R11(sp)
1533 - lw $12, PT_R12(sp)
1534 - lw $13, PT_R13(sp)
1535 - lw $14, PT_R14(sp)
1536 - lw $15, PT_R15(sp)
1540 @@ -136,15 +201,36 @@ sdsleep:
1544 - lw $24, PT_R24(sp)
1545 - lw $25, PT_R25(sp)
1546 - lw $26, PT_R26(sp)
1547 - lw $27, PT_R27(sp)
1549 - lw $29, PT_R29(sp)
1556 + /* clear the wake source, but save it as the return value of the function */
1557 + li t0, SYS_WAKESRC
1564 + lw gp, save_and_sleep_frmsz-44(sp)
1565 + lw s8, save_and_sleep_frmsz-40(sp)
1566 + lw s7, save_and_sleep_frmsz-36(sp)
1567 + lw s6, save_and_sleep_frmsz-32(sp)
1568 + lw s5, save_and_sleep_frmsz-28(sp)
1569 + lw s4, save_and_sleep_frmsz-24(sp)
1570 + lw s3, save_and_sleep_frmsz-20(sp)
1571 + lw s2, save_and_sleep_frmsz-16(sp)
1572 + lw s1, save_and_sleep_frmsz-12(sp)
1573 + lw s0, save_and_sleep_frmsz-8(sp)
1574 + lw ra, save_and_sleep_frmsz-4(sp)
1576 + addu sp, save_and_sleep_frmsz
1582 --- a/arch/mips/au1000/common/time.c
1583 +++ b/arch/mips/au1000/common/time.c
1585 #include <linux/mc146818rtc.h>
1586 #include <linux/timex.h>
1588 -extern void startup_match20_interrupt(void);
1589 extern void do_softirq(void);
1590 extern volatile unsigned long wall_jiffies;
1591 unsigned long missed_heart_beats = 0;
1592 @@ -59,14 +58,14 @@ static unsigned long r4k_offset; /* Amou
1593 static unsigned long r4k_cur; /* What counter should be at next timer irq */
1594 extern rwlock_t xtime_lock;
1595 int no_au1xxx_32khz;
1596 -void (*au1k_wait_ptr)(void);
1597 +extern int allow_au1k_wait; /* default off for CP0 Counter */
1599 /* Cycle counter value at the previous timer interrupt.. */
1600 static unsigned int timerhi = 0, timerlo = 0;
1603 #define MATCH20_INC 328
1604 -extern void startup_match20_interrupt(void);
1605 +extern void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *));
1606 static unsigned long last_pc0, last_match20;
1609 @@ -385,7 +384,6 @@ void __init au1xxx_timer_setup(void)
1611 unsigned int est_freq;
1612 extern unsigned long (*do_gettimeoffset)(void);
1613 - extern void au1k_wait(void);
1615 printk("calculating r4koff... ");
1616 r4k_offset = cal_r4koff();
1617 @@ -437,9 +435,6 @@ void __init au1xxx_timer_setup(void)
1618 au_writel(0, SYS_TOYWRITE);
1619 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
1621 - au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
1622 - au_writel(~0, SYS_WAKESRC);
1624 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
1626 /* setup match20 to interrupt once every 10ms */
1627 @@ -447,13 +442,13 @@ void __init au1xxx_timer_setup(void)
1628 au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
1630 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
1631 - startup_match20_interrupt();
1632 + startup_match20_interrupt(counter0_irq);
1634 do_gettimeoffset = do_fast_pm_gettimeoffset;
1636 /* We can use the real 'wait' instruction.
1638 - au1k_wait_ptr = au1k_wait;
1639 + allow_au1k_wait = 1;
1643 --- a/arch/mips/au1000/db1x00/board_setup.c
1644 +++ b/arch/mips/au1000/db1x00/board_setup.c
1646 #include <asm/au1000.h>
1647 #include <asm/db1x00.h>
1649 -extern struct rtc_ops no_rtc_ops;
1650 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) && defined(CONFIG_MIPS_DB1550)
1651 +#include <asm/au1xxx_dbdma.h>
1652 +extern struct ide_ops *ide_ops;
1653 +extern struct ide_ops au1xxx_ide_ops;
1654 +extern u32 au1xxx_ide_virtbase;
1655 +extern u64 au1xxx_ide_physbase;
1656 +extern int au1xxx_ide_irq;
1659 +chan_tab_t *ide_read_ch, *ide_write_ch;
1660 +u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma
1662 +dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 };
1663 +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */
1665 -/* not correct for db1550 */
1666 -static BCSR * const bcsr = (BCSR *)0xAE000000;
1667 +extern struct rtc_ops no_rtc_ops;
1669 void board_reset (void)
1671 @@ -57,6 +69,13 @@ void board_reset (void)
1672 au_writel(0x00000000, 0xAE00001C);
1675 +void board_power_off (void)
1677 +#ifdef CONFIG_MIPS_MIRAGE
1678 + au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
1682 void __init board_setup(void)
1685 @@ -108,8 +127,42 @@ void __init board_setup(void)
1686 au_writel(0x02000200, GPIO2_OUTPUT);
1689 +#if defined(CONFIG_AU1XXX_SMC91111)
1690 +#define CPLD_CONTROL (0xAF00000C)
1692 + extern uint32_t au1xxx_smc91111_base;
1693 + extern unsigned int au1xxx_smc91111_irq;
1694 + extern int au1xxx_smc91111_nowait;
1696 + au1xxx_smc91111_base = 0xAC000300;
1697 + au1xxx_smc91111_irq = AU1000_GPIO_8;
1698 + au1xxx_smc91111_nowait = 1;
1700 + /* set up the Static Bus timing - only 396Mhz */
1701 + bcsr->resets |= 0x7;
1702 + au_writel(0x00010003, MEM_STCFG0);
1703 + au_writel(0x000c00c0, MEM_STCFG2);
1704 + au_writel(0x85E1900D, MEM_STTIME2);
1706 +#endif /* end CONFIG_SMC91111 */
1709 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) && defined(CONFIG_MIPS_DB1550)
1711 + * Iniz IDE parameters
1713 + ide_ops = &au1xxx_ide_ops;
1714 + au1xxx_ide_irq = DAUGHTER_CARD_IRQ;
1715 + au1xxx_ide_physbase = AU1XXX_ATA_PHYS_ADDR;
1716 + au1xxx_ide_virtbase = KSEG1ADDR(AU1XXX_ATA_PHYS_ADDR);
1719 + * change PIO or PIO+Ddma
1720 + * check the GPIO-6 pin condition. db1550:s6_dot
1722 + switch4ddma = (au_readl(SYS_PINSTATERD) & (1 << 6)) ? 1 : 0;
1725 #ifdef CONFIG_MIPS_DB1000
1726 printk("AMD Alchemy Au1000/Db1000 Board\n");
1728 --- a/arch/mips/au1000/db1x00/irqmap.c
1729 +++ b/arch/mips/au1000/db1x00/irqmap.c
1730 @@ -53,6 +53,7 @@ au1xxx_irq_map_t au1xxx_irq_map[] = {
1731 #ifdef CONFIG_MIPS_DB1550
1732 { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ#
1733 { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ#
1734 + { AU1000_GPIO_8, INTC_INT_LOW_LEVEL, 0 }, // Daughtercard IRQ#
1736 { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 Fully_Interted#
1737 { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 STSCHG#
1738 --- a/arch/mips/au1000/db1x00/Makefile
1739 +++ b/arch/mips/au1000/db1x00/Makefile
1740 @@ -17,4 +17,11 @@ O_TARGET := db1x00.o
1741 obj-y := init.o board_setup.o irqmap.o
1742 obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o
1744 +ifdef CONFIG_MIPS_DB1100
1746 +obj-y += mmc_support.o
1747 +export-objs += mmc_support.o
1751 include $(TOPDIR)/Rules.make
1753 +++ b/arch/mips/au1000/db1x00/mmc_support.c
1756 + * BRIEF MODULE DESCRIPTION
1758 + * MMC support routines for DB1100.
1761 + * Copyright (c) 2003-2004 Embedded Edge, LLC.
1762 + * Author: Embedded Edge, LLC.
1763 + * Contact: dan@embeddededge.com
1765 + * This program is free software; you can redistribute it and/or modify it
1766 + * under the terms of the GNU General Public License as published by the
1767 + * Free Software Foundation; either version 2 of the License, or (at your
1768 + * option) any later version.
1770 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1771 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1772 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1773 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1774 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1775 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1776 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1777 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1778 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1779 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1781 + * You should have received a copy of the GNU General Public License along
1782 + * with this program; if not, write to the Free Software Foundation, Inc.,
1783 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1788 +#include <linux/config.h>
1789 +#include <linux/kernel.h>
1790 +#include <linux/module.h>
1791 +#include <linux/init.h>
1793 +#include <asm/irq.h>
1794 +#include <asm/au1000.h>
1795 +#include <asm/au1100_mmc.h>
1796 +#include <asm/db1x00.h>
1799 +/* SD/MMC controller support functions */
1804 +void mmc_card_inserted(int _n_, int *_res_)
1806 + u32 gpios = au_readl(SYS_PINSTATERD);
1807 + u32 emptybit = (_n_) ? (1<<20) : (1<<19);
1808 + *_res_ = ((gpios & emptybit) == 0);
1812 + * Check card write protection.
1814 +void mmc_card_writable(int _n_, int *_res_)
1816 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
1817 + unsigned long mmc_wp, board_specific;
1820 + mmc_wp = BCSR_BOARD_SD1_WP;
1822 + mmc_wp = BCSR_BOARD_SD0_WP;
1825 + board_specific = au_readl((unsigned long)(&bcsr->specific));
1827 + if (!(board_specific & mmc_wp)) {/* low means card writable */
1835 + * Apply power to card slot.
1837 +void mmc_power_on(int _n_)
1839 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
1840 + unsigned long mmc_pwr, board_specific;
1843 + mmc_pwr = BCSR_BOARD_SD1_PWR;
1845 + mmc_pwr = BCSR_BOARD_SD0_PWR;
1848 + board_specific = au_readl((unsigned long)(&bcsr->specific));
1849 + board_specific |= mmc_pwr;
1851 + au_writel(board_specific, (int)(&bcsr->specific));
1856 + * Remove power from card slot.
1858 +void mmc_power_off(int _n_)
1860 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
1861 + unsigned long mmc_pwr, board_specific;
1864 + mmc_pwr = BCSR_BOARD_SD1_PWR;
1866 + mmc_pwr = BCSR_BOARD_SD0_PWR;
1869 + board_specific = au_readl((unsigned long)(&bcsr->specific));
1870 + board_specific &= ~mmc_pwr;
1872 + au_writel(board_specific, (int)(&bcsr->specific));
1876 +EXPORT_SYMBOL(mmc_card_inserted);
1877 +EXPORT_SYMBOL(mmc_card_writable);
1878 +EXPORT_SYMBOL(mmc_power_on);
1879 +EXPORT_SYMBOL(mmc_power_off);
1882 +++ b/arch/mips/au1000/ficmmp/au1200_ibutton.c
1884 +/* ----------------------------------------------------------------------
1887 + * Copyright (C) 2003 Intrinsyc Software Inc.
1889 + * Intel Personal Media Player buttons
1891 + * This program is free software; you can redistribute it and/or modify
1892 + * it under the terms of the GNU General Public License version 2 as
1893 + * published by the Free Software Foundation.
1895 + * May 02, 2003 : Initial version [FB]
1897 + ------------------------------------------------------------------------*/
1899 +#include <linux/config.h>
1900 +#include <linux/module.h>
1901 +#include <linux/kernel.h>
1902 +#include <linux/init.h>
1903 +#include <linux/fs.h>
1904 +#include <linux/sched.h>
1905 +#include <linux/miscdevice.h>
1906 +#include <linux/errno.h>
1907 +#include <linux/poll.h>
1908 +#include <linux/delay.h>
1909 +#include <linux/input.h>
1911 +#include <asm/au1000.h>
1912 +#include <asm/uaccess.h>
1913 +#include <asm/au1xxx_gpio.h>
1914 +#include <asm/irq.h>
1915 +#include <asm/keyboard.h>
1916 +#include <linux/time.h>
1918 +#define DRIVER_VERSION "V1.0"
1919 +#define DRIVER_AUTHOR "FIC"
1920 +#define DRIVER_DESC "FIC Travis Media Player Button Driver"
1921 +#define DRIVER_NAME "Au1200Button"
1923 +#define BUTTON_MAIN (1<<1)
1924 +#define BUTTON_SELECT (1<<6)
1925 +#define BUTTON_GUIDE (1<<12)
1926 +#define BUTTON_DOWN (1<<17)
1927 +#define BUTTON_LEFT (1<<19)
1928 +#define BUTTON_RIGHT (1<<26)
1929 +#define BUTTON_UP (1<<28)
1931 +#define BUTTON_MASK (\
1941 +#define BUTTON_INVERT (\
1951 +char button_map[32]={0,KEY_S,0,0,0,0,KEY_ENTER,0,0,0,0,0,KEY_G,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1952 +//char button_map[32]={0,0,0,0,0,0,KEY_ENTER,0,0,0,0,0,KEY_G,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1954 +//char button_map[32]={0,KEY_TAB,0,0,0,0,KEY_M,0,0,0,0,0,KEY_S,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1955 +//char button_map[32]={0,0,0,0,0,0,KEY_M,0,0,0,0,0,KEY_S,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1957 +#define BUTTON_COUNT (sizeof (button_map) / sizeof (button_map[0]))
1959 +struct input_dev dev;
1960 +struct timeval cur_tv;
1962 +static unsigned int old_tv_usec = 0;
1964 +static unsigned int read_button_state(void)
1966 + unsigned int state;
1968 + state = au_readl(SYS_PINSTATERD) & BUTTON_MASK; /* get gpio status */
1970 + state ^= BUTTON_INVERT; /* invert main & guide button */
1972 + /* printk("au1200_ibutton.c: button state [0x%X]\r\n",state); */
1976 +//This function returns 0 if the allowed microseconds have elapsed since the last call to ths function, otherwise it returns 1 to indicate a bounce condition
1977 +static unsigned int bounce()
1980 + unsigned int elapsed_time;
1982 + do_gettimeofday (&cur_tv);
1984 + if (!old_tv_usec) {
1985 + old_tv_usec = cur_tv.tv_usec;
1989 + if(cur_tv.tv_usec > old_tv_usec) {
1990 + /* If there hasn't been rollover */
1991 + elapsed_time = ((cur_tv.tv_usec - old_tv_usec));
1994 + /* Accounting for rollover */
1995 + elapsed_time = ((1000000 - old_tv_usec + cur_tv.tv_usec));
1998 + if (elapsed_time > 250000) {
1999 + old_tv_usec = 0; /* reset the bounce time */
2006 +/* button interrupt handler */
2007 +static void button_interrupt(int irq, void *dev, struct pt_regs *regs)
2010 + unsigned int i,bit_mask, key_choice;
2013 + /* Report state to upper level */
2015 + button_state = read_button_state() & BUTTON_MASK; /* get new gpio status */
2017 + /* Return if this is a repeated (bouncing) event */
2021 + /* we want to make keystrokes */
2022 + for( i=0; i< BUTTON_COUNT; i++) {
2024 + if (button_state & bit_mask) {
2025 + key_choice = button_map[i];
2026 + /* toggle key down */
2027 + input_report_key(dev, key_choice, 1);
2028 + /* toggle key up */
2029 + input_report_key(dev, key_choice, 0);
2030 + printk("ibutton gpio %d stat %x scan code %d\r\n",
2031 + i, button_state, key_choice);
2032 + /* Only report the first key event; it doesn't make
2033 + * sense for two keys to be pressed at the same time,
2034 + * and causes problems with the directional keys
2042 +button_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
2044 + static int prev_scancode;
2046 + printk( "ibutton.c: translate: scancode=%x raw_mode=%x\n",
2047 + scancode, raw_mode);
2049 + if (scancode == 0xe0 || scancode == 0xe1) {
2050 + prev_scancode = scancode;
2054 + if (scancode == 0x00 || scancode == 0xff) {
2055 + prev_scancode = 0;
2059 + *keycode = scancode;
2064 +/* init button hardware */
2065 +static int button_hw_init(void)
2067 + unsigned int ipinfunc=0;
2069 + printk("au1200_ibutton.c: Initializing buttons hardware\n");
2071 + // initialize GPIO pin function assignments
2073 + ipinfunc = au_readl(SYS_PINFUNC);
2075 + ipinfunc &= ~(SYS_PINFUNC_DMA | SYS_PINFUNC_S0A | SYS_PINFUNC_S0B);
2076 + au_writel( ipinfunc ,SYS_PINFUNC);
2078 + ipinfunc |= (SYS_PINFUNC_S0C);
2079 + au_writel( ipinfunc ,SYS_PINFUNC);
2084 +/* button driver init */
2085 +static int __init button_init(void)
2088 + unsigned int flag=0;
2090 + printk("au1200_ibutton.c: button_init()\r\n");
2094 + /* register all button irq handler */
2096 + for(i=0; i< sizeof(button_map)/sizeof(button_map[0]); i++)
2098 + /* register irq <-- gpio 1 ,6 ,12 , 17 ,19 , 26 ,28 */
2099 + if(button_map[i] != 0)
2101 + ret = request_irq(AU1000_GPIO_0 + i ,
2102 + &button_interrupt , SA_INTERRUPT ,
2103 + DRIVER_NAME , &dev);
2104 + if(ret) flag |= 1<<i;
2108 + printk("au1200_ibutton.c: request_irq,ret:0x%x\r\n",ret);
2111 + printk("au1200_ibutton.c: request_irq:%X failed\r\n",flag);
2115 + dev.name = DRIVER_NAME;
2116 + dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
2118 + for (i=0;i<sizeof(button_map)/sizeof(button_map[0]);i++)
2120 + dev.keybit[LONG(button_map[i])] |= BIT(button_map[i]);
2123 + input_register_device(&dev);
2125 + /* ready to receive interrupts */
2130 +/* button driver exit */
2131 +static void __exit button_exit(void)
2135 + for(i=0;i<sizeof(button_map)/sizeof(button_map[0]);i++)
2137 + if(button_map[i] != 0)
2139 + free_irq( AU1000_GPIO_0 + i, &dev);
2143 + input_unregister_device(&dev);
2145 + printk("au1200_ibutton.c: button_exit()\r\n");
2148 +module_init(button_init);
2149 +module_exit(button_exit);
2151 +MODULE_AUTHOR( DRIVER_AUTHOR );
2152 +MODULE_DESCRIPTION( DRIVER_DESC );
2153 +MODULE_LICENSE("GPL");
2155 +++ b/arch/mips/au1000/ficmmp/au1xxx_dock.c
2158 + * Copyright (C) 2003 Metrowerks, All Rights Reserved.
2160 + * This program is free software; you can redistribute it and/or modify
2161 + * it under the terms of the GNU General Public License version 2 as
2162 + * published by the Free Software Foundation.
2165 +#include <linux/config.h>
2166 +#include <linux/module.h>
2167 +#include <linux/init.h>
2168 +#include <linux/fs.h>
2169 +#include <linux/sched.h>
2170 +#include <linux/miscdevice.h>
2171 +#include <linux/errno.h>
2172 +#include <linux/poll.h>
2173 +#include <asm/au1000.h>
2174 +#include <asm/uaccess.h>
2175 +#include <asm/au1xxx_gpio.h>
2178 +#if defined(CONFIG_MIPS_FICMMP)
2179 + #define DOCK_GPIO 215
2181 + #error Unsupported Au1xxx Platform
2184 +#define MAKE_FLAG 0x20
2192 +#define DPRINTK(format, args...) printk(__FUNCTION__ ": " format, ## args)
2194 +#define DPRINTK(format, args...) do { } while (0)
2197 +/* Please note that this driver is based on a timer and is not interrupt
2198 + * driven. If you are going to make use of this driver, you will need to have
2199 + * your application open the dock listing from the /dev directory first.
2202 +struct au1xxx_dock {
2203 + struct fasync_struct *fasync;
2204 + wait_queue_head_t read_wait;
2206 + unsigned int debounce;
2207 + unsigned int current;
2208 + unsigned int last;
2211 +static struct au1xxx_dock dock_info;
2214 +static void dock_timer_periodic(void *data);
2216 +static struct tq_struct dock_task = {
2217 + routine: dock_timer_periodic,
2221 +static int cleanup_flag = 0;
2222 +static DECLARE_WAIT_QUEUE_HEAD(cleanup_wait_queue);
2225 +static unsigned int read_dock_state(void)
2229 + state = au1xxx_gpio_read(DOCK_GPIO);
2231 + /* printk( "Current Dock State: %d\n", state ); */
2237 +static void dock_timer_periodic(void *data)
2239 + struct au1xxx_dock *dock = (struct au1xxx_dock *)data;
2240 + unsigned long dock_state;
2242 + /* If cleanup wants us to die */
2243 + if (cleanup_flag) {
2244 + /* now cleanup_module can return */
2245 + wake_up(&cleanup_wait_queue);
2247 + /* put ourselves back in the task queue */
2248 + queue_task(&dock_task, &tq_timer);
2251 + /* read current dock */
2252 + dock_state = read_dock_state();
2254 + /* if dock states hasn't changed */
2255 + /* save time and be done. */
2256 + if (dock_state == dock->current) {
2260 + if (dock_state == dock->debounce) {
2261 + dock->current = dock_state;
2263 + dock->debounce = dock_state;
2265 + if (dock->current != dock->last) {
2266 + if (waitqueue_active(&dock->read_wait)) {
2267 + wake_up_interruptible(&dock->read_wait);
2273 +static ssize_t au1xxx_dock_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
2275 + struct au1xxx_dock *dock = filp->private_data;
2283 + while (dock->current == dock->last) {
2284 + if (filp->f_flags & O_NONBLOCK) {
2287 + interruptible_sleep_on(&dock->read_wait);
2288 + if (signal_pending(current)) {
2289 + return -ERESTARTSYS;
2293 + cur = dock->current;
2294 + last = dock->last;
2298 + event[0] = cur ? 'D' : 'U';
2306 + err = copy_to_user(buffer, &event, 3);
2315 +static int au1xxx_dock_open(struct inode *inode, struct file *filp)
2317 + struct au1xxx_dock *dock = &dock_info;
2319 + MOD_INC_USE_COUNT;
2321 + filp->private_data = dock;
2323 + if (dock->open_count++ == 0) {
2324 + dock_task.data = dock;
2326 + queue_task(&dock_task, &tq_timer);
2333 +static unsigned int au1xxx_dock_poll(struct file *filp, poll_table *wait)
2335 + struct au1xxx_dock *dock = filp->private_data;
2338 + DPRINTK("start\n");
2339 + poll_wait(filp, &dock->read_wait, wait);
2340 + if (dock->current != dock->last) {
2341 + ret = POLLIN | POLLRDNORM;
2347 +static int au1xxx_dock_release(struct inode *inode, struct file *filp)
2349 + struct au1xxx_dock *dock = filp->private_data;
2351 + DPRINTK("start\n");
2353 + if (--dock->open_count == 0) {
2355 + sleep_on(&cleanup_wait_queue);
2357 + MOD_DEC_USE_COUNT;
2364 +static struct file_operations au1xxx_dock_fops = {
2365 + owner: THIS_MODULE,
2366 + read: au1xxx_dock_read,
2367 + poll: au1xxx_dock_poll,
2368 + open: au1xxx_dock_open,
2369 + release: au1xxx_dock_release,
2373 + * The au1xxx dock is a misc device:
2375 + * Minor 22 /dev/dock
2377 + * This is /dev/misc/dock if devfs is used.
2380 +static struct miscdevice au1xxx_dock_dev = {
2383 + fops: &au1xxx_dock_fops,
2386 +static int __init au1xxx_dock_init(void)
2388 + struct au1xxx_dock *dock = &dock_info;
2391 + DPRINTK("Initializing dock driver\n");
2392 + dock->open_count = 0;
2394 + init_waitqueue_head(&dock->read_wait);
2397 + /* yamon configures GPIO pins for the dock
2398 + * no initialization needed
2401 + ret = misc_register(&au1xxx_dock_dev);
2403 + DPRINTK("dock driver fully initialized.\n");
2409 +static void __exit au1xxx_dock_exit(void)
2411 + DPRINTK("unloading dock driver\n");
2412 + misc_deregister(&au1xxx_dock_dev);
2416 +module_init(au1xxx_dock_init);
2417 +module_exit(au1xxx_dock_exit);
2419 +++ b/arch/mips/au1000/ficmmp/board_setup.c
2423 + * BRIEF MODULE DESCRIPTION
2424 + * Alchemy Pb1200 board setup.
2426 + * This program is free software; you can redistribute it and/or modify it
2427 + * under the terms of the GNU General Public License as published by the
2428 + * Free Software Foundation; either version 2 of the License, or (at your
2429 + * option) any later version.
2431 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2432 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2433 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2434 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2435 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2436 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2437 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2438 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2439 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2440 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2442 + * You should have received a copy of the GNU General Public License along
2443 + * with this program; if not, write to the Free Software Foundation, Inc.,
2444 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2446 +#include <linux/config.h>
2447 +#include <linux/init.h>
2448 +#include <linux/sched.h>
2449 +#include <linux/ioport.h>
2450 +#include <linux/mm.h>
2451 +#include <linux/console.h>
2452 +#include <linux/mc146818rtc.h>
2453 +#include <linux/delay.h>
2454 +#include <linux/ide.h>
2456 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
2457 +#include <linux/ide.h>
2460 +#include <asm/cpu.h>
2461 +#include <asm/bootinfo.h>
2462 +#include <asm/irq.h>
2463 +#include <asm/keyboard.h>
2464 +#include <asm/mipsregs.h>
2465 +#include <asm/reboot.h>
2466 +#include <asm/pgtable.h>
2467 +#include <asm/au1000.h>
2468 +#include <asm/ficmmp.h>
2469 +#include <asm/au1xxx_dbdma.h>
2470 +#include <asm/au1xxx_gpio.h>
2472 +extern struct rtc_ops no_rtc_ops;
2474 +/* value currently in the board configuration register */
2475 +u16 ficmmp_config = 0;
2477 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
2478 +extern struct ide_ops *ide_ops;
2479 +extern struct ide_ops au1xxx_ide_ops;
2480 +extern u32 au1xxx_ide_virtbase;
2481 +extern u64 au1xxx_ide_physbase;
2482 +extern int au1xxx_ide_irq;
2486 +chan_tab_t *ide_read_ch, *ide_write_ch;
2487 +u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma
2489 +dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 };
2490 +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */
2492 +void board_reset (void)
2494 + au_writel(0, 0xAD80001C);
2497 +void board_power_off (void)
2501 +void __init board_setup(void)
2503 + char *argptr = NULL;
2505 + rtc_ops = &no_rtc_ops;
2507 + ficmmp_config_init(); //Initialize FIC control register
2510 + /* Enable PSC1 SYNC for AC97. Normaly done in audio driver,
2511 + * but it is board specific code, so put it here.
2513 + pin_func = au_readl(SYS_PINFUNC);
2515 + pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
2516 + au_writel(pin_func, SYS_PINFUNC);
2518 + au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
2522 +#if defined( CONFIG_I2C_ALGO_AU1550 )
2524 + u32 freq0, clksrc;
2526 + /* Select SMBUS in CPLD */
2527 + /* bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); */
2529 + pin_func = au_readl(SYS_PINFUNC);
2531 + pin_func &= ~(3<<17 | 1<<4);
2532 + /* Set GPIOs correctly */
2533 + pin_func |= 2<<17;
2534 + au_writel(pin_func, SYS_PINFUNC);
2537 + /* The i2c driver depends on 50Mhz clock */
2538 + freq0 = au_readl(SYS_FREQCTRL0);
2540 + freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
2541 + freq0 |= (3<<SYS_FC_FRDIV1_BIT);
2542 + /* 396Mhz / (3+1)*2 == 49.5Mhz */
2543 + au_writel(freq0, SYS_FREQCTRL0);
2545 + freq0 |= SYS_FC_FE1;
2546 + au_writel(freq0, SYS_FREQCTRL0);
2549 + clksrc = au_readl(SYS_CLKSRC);
2551 + clksrc &= ~0x01f00000;
2552 + /* bit 22 is EXTCLK0 for PSC0 */
2553 + clksrc |= (0x3 << 22);
2554 + au_writel(clksrc, SYS_CLKSRC);
2559 +#ifdef CONFIG_FB_AU1200
2560 + argptr = prom_getcmdline();
2561 + strcat(argptr, " video=au1200fb:");
2564 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
2566 + * Iniz IDE parameters
2568 + ide_ops = &au1xxx_ide_ops;
2569 + au1xxx_ide_irq = FICMMP_IDE_INT;
2570 + au1xxx_ide_physbase = AU1XXX_ATA_PHYS_ADDR;
2571 + au1xxx_ide_virtbase = KSEG1ADDR(AU1XXX_ATA_PHYS_ADDR);
2574 + ide_ops = &au1xxx_ide_ops;
2575 + au1xxx_ide_irq = FICMMP_IDE_INT;
2576 + au1xxx_ide_base = KSEG1ADDR(AU1XXX_ATA_BASE);
2578 + au1xxx_gpio_write(9, 1);
2579 + printk("B4001010: %X\n", *((u32*)0xB4001010));
2580 + printk("B4001014: %X\n", *((u32*)0xB4001014));
2581 + printk("B4001018: %X\n", *((u32*)0xB4001018));
2582 + printk("B1900100: %X\n", *((u32*)0xB1900100));
2585 + ficmmp_config_clear(FICMMP_CONFIG_IDERST);
2587 + ficmmp_config_set(FICMMP_CONFIG_IDERST);
2591 + * change PIO or PIO+Ddma
2592 + * check the GPIO-5 pin condition. pb1200:s18_dot
2594 +/* switch4ddma = 0; //(au_readl(SYS_PINSTATERD) & (1 << 5)) ? 1 : 0; */
2597 + /* The Pb1200 development board uses external MUX for PSC0 to
2598 + support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
2600 +#if defined(CONFIG_AU1550_PSC_SPI) && defined(CONFIG_I2C_ALGO_AU1550)
2601 + #error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\
2602 + Refer to Pb1200 documentation.
2603 +#elif defined( CONFIG_AU1550_PSC_SPI )
2604 + //bcsr->resets |= BCSR_RESETS_PCS0MUX;
2605 +#elif defined( CONFIG_I2C_ALGO_AU1550 )
2606 + //bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
2610 + printk("FIC Multimedia Player Board\n");
2611 + au1xxx_gpio_tristate(5);
2612 + printk("B1900100: %X\n", *((volatile u32*)0xB1900100));
2613 + printk("B190002C: %X\n", *((volatile u32*)0xB190002C));
2617 +board_au1200fb_panel (void)
2619 + au1xxx_gpio_tristate(6);
2621 + if (au1xxx_gpio_read(12) == 0)
2622 + return 9; /* FS453_640x480 (Composite/S-Video) */
2624 + return 7; /* Sharp 320x240 TFT */
2628 +board_au1200fb_panel_init (void)
2630 + /*Enable data buffers*/
2631 + ficmmp_config_clear(FICMMP_CONFIG_LCMDATAOUT);
2632 + /*Take LCD out of reset*/
2633 + ficmmp_config_set(FICMMP_CONFIG_LCMPWREN | FICMMP_CONFIG_LCMEN);
2638 +board_au1200fb_panel_shutdown (void)
2640 + /*Disable data buffers*/
2641 + ficmmp_config_set(FICMMP_CONFIG_LCMDATAOUT);
2642 + /*Put LCD in reset, remove power*/
2643 + ficmmp_config_clear(FICMMP_CONFIG_LCMEN | FICMMP_CONFIG_LCMPWREN);
2648 +++ b/arch/mips/au1000/ficmmp/init.c
2652 + * BRIEF MODULE DESCRIPTION
2653 + * PB1200 board setup
2655 + * This program is free software; you can redistribute it and/or modify it
2656 + * under the terms of the GNU General Public License as published by the
2657 + * Free Software Foundation; either version 2 of the License, or (at your
2658 + * option) any later version.
2660 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2661 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2662 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2663 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2664 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2665 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2666 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2667 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2668 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2669 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2671 + * You should have received a copy of the GNU General Public License along
2672 + * with this program; if not, write to the Free Software Foundation, Inc.,
2673 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2676 +#include <linux/init.h>
2677 +#include <linux/mm.h>
2678 +#include <linux/sched.h>
2679 +#include <linux/bootmem.h>
2680 +#include <asm/addrspace.h>
2681 +#include <asm/bootinfo.h>
2682 +#include <linux/config.h>
2683 +#include <linux/string.h>
2684 +#include <linux/kernel.h>
2685 +#include <linux/sched.h>
2688 +char **prom_argv, **prom_envp;
2689 +extern void __init prom_init_cmdline(void);
2690 +extern char *prom_getenv(char *envname);
2692 +const char *get_system_type(void)
2694 + return "FIC Multimedia Player (Au1200)";
2697 +u32 mae_memsize = 0;
2699 +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
2701 + unsigned char *memsize_str;
2702 + unsigned long memsize;
2708 + mips_machgroup = MACH_GROUP_ALCHEMY;
2709 + mips_machtype = MACH_PB1000; /* set the platform # */
2710 + prom_init_cmdline();
2712 + memsize_str = prom_getenv("memsize");
2713 + if (!memsize_str) {
2714 + memsize = 0x08000000;
2716 + memsize = simple_strtol(memsize_str, NULL, 0);
2719 + /* reserved 32MB for MAE driver */
2720 + memsize -= (32 * 1024 * 1024);
2721 + add_memory_region(0, memsize, BOOT_MEM_RAM);
2722 + mae_memsize = memsize; /* for drivers/char/au1xxx_mae.c */
2727 +++ b/arch/mips/au1000/ficmmp/irqmap.c
2730 + * BRIEF MODULE DESCRIPTION
2731 + * Au1xxx irq map table
2733 + * This program is free software; you can redistribute it and/or modify it
2734 + * under the terms of the GNU General Public License as published by the
2735 + * Free Software Foundation; either version 2 of the License, or (at your
2736 + * option) any later version.
2738 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2739 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2740 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2741 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2742 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2743 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2744 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2745 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2746 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2747 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2749 + * You should have received a copy of the GNU General Public License along
2750 + * with this program; if not, write to the Free Software Foundation, Inc.,
2751 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2753 +#include <linux/errno.h>
2754 +#include <linux/init.h>
2755 +#include <linux/irq.h>
2756 +#include <linux/kernel_stat.h>
2757 +#include <linux/module.h>
2758 +#include <linux/signal.h>
2759 +#include <linux/sched.h>
2760 +#include <linux/types.h>
2761 +#include <linux/interrupt.h>
2762 +#include <linux/ioport.h>
2763 +#include <linux/timex.h>
2764 +#include <linux/slab.h>
2765 +#include <linux/random.h>
2766 +#include <linux/delay.h>
2768 +#include <asm/bitops.h>
2769 +#include <asm/bootinfo.h>
2770 +#include <asm/io.h>
2771 +#include <asm/mipsregs.h>
2772 +#include <asm/system.h>
2773 +#include <asm/au1000.h>
2774 +#include <asm/ficmmp.h>
2776 +au1xxx_irq_map_t au1xxx_irq_map[] = {
2777 + { FICMMP_IDE_INT, INTC_INT_HIGH_LEVEL, 0 },
2778 + { AU1XXX_SMC91111_IRQ, INTC_INT_HIGH_LEVEL, 0 },
2779 + { AU1000_GPIO_1 , INTC_INT_FALL_EDGE, 0 }, // main button
2780 + { AU1000_GPIO_6 , INTC_INT_RISE_EDGE, 0 }, // select button
2781 + { AU1000_GPIO_12, INTC_INT_FALL_EDGE, 0 }, // guide button
2782 + { AU1000_GPIO_17, INTC_INT_RISE_EDGE, 0 }, // down button
2783 + { AU1000_GPIO_19, INTC_INT_RISE_EDGE, 0 }, // left button
2784 + { AU1000_GPIO_26, INTC_INT_RISE_EDGE, 0 }, // right button
2785 + { AU1000_GPIO_28, INTC_INT_RISE_EDGE, 0 }, // up button
2788 +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
2791 +++ b/arch/mips/au1000/ficmmp/Makefile
2794 +# Copyright 2000 MontaVista Software Inc.
2795 +# Author: MontaVista Software, Inc.
2796 +# ppopov@mvista.com or source@mvista.com
2798 +# Makefile for the Alchemy Semiconductor FIC board.
2800 +# Note! Dependencies are done automagically by 'make dep', which also
2801 +# removes any old dependencies. DON'T put your own dependencies here
2802 +# unless it's something special (ie not a .c file).
2805 +USE_STANDARD_AS_RULE := true
2807 +O_TARGET := ficmmp.o
2809 +obj-y := init.o board_setup.o irqmap.o au1200_ibutton.o au1xxx_dock.o
2812 +obj-y += mmc_support.o
2813 +export-objs +=mmc_support.o
2817 +include $(TOPDIR)/Rules.make
2818 --- a/arch/mips/au1000/hydrogen3/board_setup.c
2819 +++ b/arch/mips/au1000/hydrogen3/board_setup.c
2820 @@ -51,12 +51,19 @@ void board_reset (void)
2824 +void board_power_off (void)
2828 void __init board_setup(void)
2832 rtc_ops = &no_rtc_ops;
2834 + /* Set GPIO14 high to make CD/DAT1 high for MMC to work */
2835 + au_writel(1<<14, SYS_OUTPUTSET);
2837 #ifdef CONFIG_AU1X00_USB_DEVICE
2838 // 2nd USB port is USB device
2839 pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
2841 +++ b/arch/mips/au1000/hydrogen3/buttons.c
2844 + * Copyright (C) 2003 Metrowerks, All Rights Reserved.
2846 + * This program is free software; you can redistribute it and/or modify
2847 + * it under the terms of the GNU General Public License version 2 as
2848 + * published by the Free Software Foundation.
2851 +#include <linux/config.h>
2852 +#include <linux/module.h>
2853 +#include <linux/init.h>
2854 +#include <linux/fs.h>
2855 +#include <linux/sched.h>
2856 +#include <linux/miscdevice.h>
2857 +#include <linux/errno.h>
2858 +#include <linux/poll.h>
2859 +#include <asm/au1000.h>
2860 +#include <asm/uaccess.h>
2862 +#define BUTTON_SELECT (1<<1)
2863 +#define BUTTON_1 (1<<2)
2864 +#define BUTTON_2 (1<<3)
2865 +#define BUTTON_ONOFF (1<<6)
2866 +#define BUTTON_3 (1<<7)
2867 +#define BUTTON_4 (1<<8)
2868 +#define BUTTON_LEFT (1<<9)
2869 +#define BUTTON_DOWN (1<<10)
2870 +#define BUTTON_RIGHT (1<<11)
2871 +#define BUTTON_UP (1<<12)
2873 +#define BUTTON_MASK (\
2886 +#define BUTTON_INVERT (\
2900 +#define MAKE_FLAG 0x20
2908 +#define DPRINTK(format, args...) printk(__FUNCTION__ ": " format, ## args)
2910 +#define DPRINTK(format, args...) do { } while (0)
2913 +/* Please note that this driver is based on a timer and is not interrupt
2914 + * driven. If you are going to make use of this driver, you will need to have
2915 + * your application open the buttons listing from the /dev directory first.
2918 +struct hydrogen3_buttons {
2919 + struct fasync_struct *fasync;
2920 + wait_queue_head_t read_wait;
2922 + unsigned int debounce;
2923 + unsigned int current;
2924 + unsigned int last;
2927 +static struct hydrogen3_buttons buttons_info;
2930 +static void button_timer_periodic(void *data);
2932 +static struct tq_struct button_task = {
2933 + routine: button_timer_periodic,
2937 +static int cleanup_flag = 0;
2938 +static DECLARE_WAIT_QUEUE_HEAD(cleanup_wait_queue);
2941 +static unsigned int read_button_state(void)
2943 + unsigned long state;
2945 + state = inl(SYS_PINSTATERD) & BUTTON_MASK;
2946 + state ^= BUTTON_INVERT;
2948 + DPRINTK( "Current Button State: %d\n", state );
2954 +static void button_timer_periodic(void *data)
2956 + struct hydrogen3_buttons *buttons = (struct hydrogen3_buttons *)data;
2957 + unsigned long button_state;
2959 + // If cleanup wants us to die
2960 + if (cleanup_flag) {
2961 + wake_up(&cleanup_wait_queue); // now cleanup_module can return
2963 + queue_task(&button_task, &tq_timer); // put ourselves back in the task queue
2966 + // read current buttons
2967 + button_state = read_button_state();
2969 + // if no buttons are down and nothing to do then
2970 + // save time and be done.
2971 + if ((button_state == 0) && (buttons->current == 0)) {
2975 + if (button_state == buttons->debounce) {
2976 + buttons->current = button_state;
2978 + buttons->debounce = button_state;
2980 +// printk("0x%04x\n", button_state);
2981 + if (buttons->current != buttons->last) {
2982 + if (waitqueue_active(&buttons->read_wait)) {
2983 + wake_up_interruptible(&buttons->read_wait);
2989 +static ssize_t hydrogen3_buttons_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
2991 + struct hydrogen3_buttons *buttons = filp->private_data;
3000 + DPRINTK("start\n");
3004 + while (buttons->current == buttons->last) {
3005 + if (filp->f_flags & O_NONBLOCK) {
3008 + interruptible_sleep_on(&buttons->read_wait);
3009 + if (signal_pending(current)) {
3010 + return -ERESTARTSYS;
3014 + cur = buttons->current;
3015 + last = buttons->last;
3019 + for (bit = 0; (bit < 16) && count; bit++) {
3020 + if ((cur ^ last) & bit_mask) {
3021 + if (cur & bit_mask) {
3022 + events[index] = (bit | MAKE_FLAG) + 'A';
3025 + events[index] = bit + 'A';
3026 + last &= ~bit_mask;
3033 + buttons->last = last;
3039 + err = copy_to_user(buffer, events, index);
3048 +static int hydrogen3_buttons_open(struct inode *inode, struct file *filp)
3050 + struct hydrogen3_buttons *buttons = &buttons_info;
3052 + DPRINTK("start\n");
3053 + MOD_INC_USE_COUNT;
3055 + filp->private_data = buttons;
3057 + if (buttons->open_count++ == 0) {
3058 + button_task.data = buttons;
3060 + queue_task(&button_task, &tq_timer);
3067 +static unsigned int hydrogen3_buttons_poll(struct file *filp, poll_table *wait)
3069 + struct hydrogen3_buttons *buttons = filp->private_data;
3072 + DPRINTK("start\n");
3073 + poll_wait(filp, &buttons->read_wait, wait);
3074 + if (buttons->current != buttons->last) {
3075 + ret = POLLIN | POLLRDNORM;
3081 +static int hydrogen3_buttons_release(struct inode *inode, struct file *filp)
3083 + struct hydrogen3_buttons *buttons = filp->private_data;
3085 + DPRINTK("start\n");
3087 + if (--buttons->open_count == 0) {
3089 + sleep_on(&cleanup_wait_queue);
3091 + MOD_DEC_USE_COUNT;
3098 +static struct file_operations hydrogen3_buttons_fops = {
3099 + owner: THIS_MODULE,
3100 + read: hydrogen3_buttons_read,
3101 + poll: hydrogen3_buttons_poll,
3102 + open: hydrogen3_buttons_open,
3103 + release: hydrogen3_buttons_release,
3107 + * The hydrogen3 buttons is a misc device:
3109 + * Minor 22 /dev/buttons
3111 + * This is /dev/misc/buttons if devfs is used.
3114 +static struct miscdevice hydrogen3_buttons_dev = {
3117 + fops: &hydrogen3_buttons_fops,
3120 +static int __init hydrogen3_buttons_init(void)
3122 + struct hydrogen3_buttons *buttons = &buttons_info;
3125 + DPRINTK("Initializing buttons driver\n");
3126 + buttons->open_count = 0;
3128 + init_waitqueue_head(&buttons->read_wait);
3131 + // yamon configures GPIO pins for the buttons
3132 + // no initialization needed
3134 + ret = misc_register(&hydrogen3_buttons_dev);
3136 + DPRINTK("Buttons driver fully initialized.\n");
3142 +static void __exit hydrogen3_buttons_exit(void)
3144 + DPRINTK("unloading buttons driver\n");
3145 + misc_deregister(&hydrogen3_buttons_dev);
3149 +module_init(hydrogen3_buttons_init);
3150 +module_exit(hydrogen3_buttons_exit);
3151 --- a/arch/mips/au1000/hydrogen3/Makefile
3152 +++ b/arch/mips/au1000/hydrogen3/Makefile
3153 @@ -14,6 +14,11 @@ USE_STANDARD_AS_RULE := true
3155 O_TARGET := hydrogen3.o
3157 -obj-y := init.o board_setup.o irqmap.o
3158 +obj-y := init.o board_setup.o irqmap.o buttons.o
3161 +obj-y += mmc_support.o
3162 +export-objs +=mmc_support.o
3165 include $(TOPDIR)/Rules.make
3167 +++ b/arch/mips/au1000/hydrogen3/mmc_support.c
3170 + * BRIEF MODULE DESCRIPTION
3172 + * MMC support routines for Hydrogen3.
3175 + * Copyright (c) 2003-2004 Embedded Edge, LLC.
3176 + * Author: Embedded Edge, LLC.
3177 + * Contact: dan@embeddededge.com
3179 + * This program is free software; you can redistribute it and/or modify it
3180 + * under the terms of the GNU General Public License as published by the
3181 + * Free Software Foundation; either version 2 of the License, or (at your
3182 + * option) any later version.
3184 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3185 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3186 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
3187 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3188 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3189 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3190 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3191 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3192 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3193 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3195 + * You should have received a copy of the GNU General Public License along
3196 + * with this program; if not, write to the Free Software Foundation, Inc.,
3197 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3202 +#include <linux/config.h>
3203 +#include <linux/kernel.h>
3204 +#include <linux/module.h>
3205 +#include <linux/init.h>
3207 +#include <asm/irq.h>
3208 +#include <asm/au1000.h>
3209 +#include <asm/au1100_mmc.h>
3211 +#define GPIO_17_WP 0x20000
3213 +/* SD/MMC controller support functions */
3218 +void mmc_card_inserted(int _n_, int *_res_)
3220 + u32 gpios = au_readl(SYS_PINSTATERD);
3221 + u32 emptybit = (1<<16);
3222 + *_res_ = ((gpios & emptybit) == 0);
3226 + * Check card write protection.
3228 +void mmc_card_writable(int _n_, int *_res_)
3230 + unsigned long mmc_wp, board_specific;
3231 + board_specific = au_readl(SYS_OUTPUTSET);
3232 + mmc_wp=GPIO_17_WP;
3233 + if (!(board_specific & mmc_wp)) {/* low means card writable */
3240 + * Apply power to card slot.
3242 +void mmc_power_on(int _n_)
3247 + * Remove power from card slot.
3249 +void mmc_power_off(int _n_)
3253 +EXPORT_SYMBOL(mmc_card_inserted);
3254 +EXPORT_SYMBOL(mmc_card_writable);
3255 +EXPORT_SYMBOL(mmc_power_on);
3256 +EXPORT_SYMBOL(mmc_power_off);
3258 --- a/arch/mips/au1000/mtx-1/board_setup.c
3259 +++ b/arch/mips/au1000/mtx-1/board_setup.c
3262 extern struct rtc_ops no_rtc_ops;
3264 +void board_reset (void)
3266 + /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
3267 + au_writel(0x00000000, 0xAE00001C);
3270 void __init board_setup(void)
3272 rtc_ops = &no_rtc_ops;
3273 --- a/arch/mips/au1000/mtx-1/irqmap.c
3274 +++ b/arch/mips/au1000/mtx-1/irqmap.c
3275 @@ -72,10 +72,10 @@ au1xxx_pci_irqmap(struct pci_dev *dev, u
3279 - {INTA, INTB, INTC, INTD}, /* IDSEL 0 */
3280 - {INTA, INTB, INTC, INTD}, /* IDSEL 1 */
3281 - {INTA, INTB, INTC, INTD}, /* IDSEL 2 */
3282 - {INTA, INTB, INTC, INTD}, /* IDSEL 3 */
3283 + {INTA, INTB, INTX, INTX}, /* IDSEL 0 */
3284 + {INTB, INTA, INTX, INTX}, /* IDSEL 1 */
3285 + {INTC, INTD, INTX, INTX}, /* IDSEL 2 */
3286 + {INTD, INTC, INTX, INTX}, /* IDSEL 3 */
3288 const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4;
3289 return PCI_IRQ_TABLE_LOOKUP;
3290 --- a/arch/mips/au1000/pb1000/board_setup.c
3291 +++ b/arch/mips/au1000/pb1000/board_setup.c
3292 @@ -58,6 +58,10 @@ void board_reset (void)
3296 +void board_power_off (void)
3300 void __init board_setup(void)
3302 u32 pin_func, static_cfg0;
3303 --- a/arch/mips/au1000/pb1100/board_setup.c
3304 +++ b/arch/mips/au1000/pb1100/board_setup.c
3305 @@ -62,6 +62,10 @@ void board_reset (void)
3306 au_writel(0x00000000, 0xAE00001C);
3309 +void board_power_off (void)
3313 void __init board_setup(void)
3316 --- a/arch/mips/au1000/pb1100/Makefile
3317 +++ b/arch/mips/au1000/pb1100/Makefile
3318 @@ -16,4 +16,10 @@ O_TARGET := pb1100.o
3320 obj-y := init.o board_setup.o irqmap.o
3324 +obj-y += mmc_support.o
3325 +export-objs += mmc_support.o
3328 include $(TOPDIR)/Rules.make
3330 +++ b/arch/mips/au1000/pb1100/mmc_support.c
3333 + * BRIEF MODULE DESCRIPTION
3335 + * MMC support routines for PB1100.
3338 + * Copyright (c) 2003-2004 Embedded Edge, LLC.
3339 + * Author: Embedded Edge, LLC.
3340 + * Contact: dan@embeddededge.com
3342 + * This program is free software; you can redistribute it and/or modify it
3343 + * under the terms of the GNU General Public License as published by the
3344 + * Free Software Foundation; either version 2 of the License, or (at your
3345 + * option) any later version.
3347 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3348 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3349 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
3350 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3351 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3352 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3353 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3354 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3355 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3356 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3358 + * You should have received a copy of the GNU General Public License along
3359 + * with this program; if not, write to the Free Software Foundation, Inc.,
3360 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3365 +#include <linux/config.h>
3366 +#include <linux/kernel.h>
3367 +#include <linux/module.h>
3368 +#include <linux/init.h>
3370 +#include <asm/irq.h>
3371 +#include <asm/au1000.h>
3372 +#include <asm/au1100_mmc.h>
3373 +#include <asm/pb1100.h>
3376 +/* SD/MMC controller support functions */
3381 +void mmc_card_inserted(int _n_, int *_res_)
3383 + u32 gpios = au_readl(SYS_PINSTATERD);
3384 + u32 emptybit = (_n_) ? (1<<15) : (1<<14);
3385 + *_res_ = ((gpios & emptybit) == 0);
3389 + * Check card write protection.
3391 +void mmc_card_writable(int _n_, int *_res_)
3393 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
3394 + unsigned long mmc_wp, board_specific;
3397 + mmc_wp = BCSR_PCMCIA_SD1_WP;
3399 + mmc_wp = BCSR_PCMCIA_SD0_WP;
3402 + board_specific = au_readl((unsigned long)(&bcsr->pcmcia));
3404 + if (!(board_specific & mmc_wp)) {/* low means card writable */
3412 + * Apply power to card slot.
3414 +void mmc_power_on(int _n_)
3416 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
3417 + unsigned long mmc_pwr, board_specific;
3420 + mmc_pwr = BCSR_PCMCIA_SD1_PWR;
3422 + mmc_pwr = BCSR_PCMCIA_SD0_PWR;
3425 + board_specific = au_readl((unsigned long)(&bcsr->pcmcia));
3426 + board_specific |= mmc_pwr;
3428 + au_writel(board_specific, (int)(&bcsr->pcmcia));
3433 + * Remove power from card slot.
3435 +void mmc_power_off(int _n_)
3437 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
3438 + unsigned long mmc_pwr, board_specific;
3441 + mmc_pwr = BCSR_PCMCIA_SD1_PWR;
3443 + mmc_pwr = BCSR_PCMCIA_SD0_PWR;
3446 + board_specific = au_readl((unsigned long)(&bcsr->pcmcia));
3447 + board_specific &= ~mmc_pwr;
3449 + au_writel(board_specific, (int)(&bcsr->pcmcia));
3453 +EXPORT_SYMBOL(mmc_card_inserted);
3454 +EXPORT_SYMBOL(mmc_card_writable);
3455 +EXPORT_SYMBOL(mmc_power_on);
3456 +EXPORT_SYMBOL(mmc_power_off);
3459 +++ b/arch/mips/au1000/pb1200/board_setup.c
3463 + * BRIEF MODULE DESCRIPTION
3464 + * Alchemy Pb1200 board setup.
3466 + * This program is free software; you can redistribute it and/or modify it
3467 + * under the terms of the GNU General Public License as published by the
3468 + * Free Software Foundation; either version 2 of the License, or (at your
3469 + * option) any later version.
3471 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3472 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3473 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
3474 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3475 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3476 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3477 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3478 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3479 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3480 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3482 + * You should have received a copy of the GNU General Public License along
3483 + * with this program; if not, write to the Free Software Foundation, Inc.,
3484 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3486 +#include <linux/config.h>
3487 +#include <linux/init.h>
3488 +#include <linux/sched.h>
3489 +#include <linux/ioport.h>
3490 +#include <linux/mm.h>
3491 +#include <linux/console.h>
3492 +#include <linux/mc146818rtc.h>
3493 +#include <linux/delay.h>
3495 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
3496 +#include <linux/ide.h>
3499 +#include <asm/cpu.h>
3500 +#include <asm/bootinfo.h>
3501 +#include <asm/irq.h>
3502 +#include <asm/keyboard.h>
3503 +#include <asm/mipsregs.h>
3504 +#include <asm/reboot.h>
3505 +#include <asm/pgtable.h>
3506 +#include <asm/au1000.h>
3507 +#include <asm/au1xxx_dbdma.h>
3509 +#ifdef CONFIG_MIPS_PB1200
3510 +#include <asm/pb1200.h>
3513 +#ifdef CONFIG_MIPS_DB1200
3514 +#include <asm/db1200.h>
3515 +#define PB1200_ETH_INT DB1200_ETH_INT
3516 +#define PB1200_IDE_INT DB1200_IDE_INT
3519 +extern struct rtc_ops no_rtc_ops;
3521 +extern void _board_init_irq(void);
3522 +extern void (*board_init_irq)(void);
3524 +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX
3525 +extern struct ide_ops *ide_ops;
3526 +extern struct ide_ops au1xxx_ide_ops;
3527 +extern u32 au1xxx_ide_virtbase;
3528 +extern u64 au1xxx_ide_physbase;
3529 +extern int au1xxx_ide_irq;
3533 +chan_tab_t *ide_read_ch, *ide_write_ch;
3534 +u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma
3536 +dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 };
3537 +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */
3539 +void board_reset (void)
3544 +void board_power_off (void)
3546 + bcsr->resets = 0xC000;
3549 +void __init board_setup(void)
3551 + char *argptr = NULL;
3553 + rtc_ops = &no_rtc_ops;
3556 + /* Enable PSC1 SYNC for AC97. Normaly done in audio driver,
3557 + * but it is board specific code, so put it here.
3559 + pin_func = au_readl(SYS_PINFUNC);
3561 + pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
3562 + au_writel(pin_func, SYS_PINFUNC);
3564 + au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
3568 +#if defined( CONFIG_I2C_ALGO_AU1550 )
3570 + u32 freq0, clksrc;
3572 + /* Select SMBUS in CPLD */