v2.4.7.8 -> v2.4.8
[opensuse:kernel.git] / arch / arm / mach-sa1100 / hw.c
1 /*
2  * arch/arm/kernel/hw-sa1100.c
3  *
4  * SA1100-dependent machine specifics
5  *
6  * Copyright (C) 2000 Nicolas Pitre <nico@cam.org>
7  *
8  * This will certainly contain more stuff with time... like power management,
9  * special hardware autodetection, etc.
10  *
11  */
12 #include <linux/config.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <linux/sched.h>
17
18 #include <asm/delay.h>
19 #include <asm/hardware.h>
20 #include <asm/mach-types.h>
21
22 /*
23  * SA1100 GPIO edge detection for IRQs:
24  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
25  * This must be called *before* the appropriate IRQ is registered.
26  * Use this instead of directly setting GRER/GFER.
27  */
28
29 int GPIO_IRQ_rising_edge;
30 int GPIO_IRQ_falling_edge;
31
32 void set_GPIO_IRQ_edge( int gpio_mask, int edge )
33 {
34         if( edge & GPIO_FALLING_EDGE )
35                 GPIO_IRQ_falling_edge |= gpio_mask;
36         else
37                 GPIO_IRQ_falling_edge &= ~gpio_mask;
38         if( edge & GPIO_RISING_EDGE )
39                 GPIO_IRQ_rising_edge |= gpio_mask;
40         else
41                 GPIO_IRQ_rising_edge &= ~gpio_mask;
42 }
43
44 EXPORT_SYMBOL(set_GPIO_IRQ_edge);
45
46
47 #ifdef CONFIG_SA1100_ASSABET
48
49 unsigned long BCR_value = BCR_DB1110;
50 unsigned long SCR_value = SCR_INIT;
51 EXPORT_SYMBOL(BCR_value);
52 EXPORT_SYMBOL(SCR_value);
53
54 /*
55  * Read System Configuration "Register"
56  * (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
57  * User's Guide", section 4.4.1)
58  *
59  * This same scan is performed in arch/arm/boot/compressed/head-sa1100.S
60  * to set up the serial port for decompression status messages. We 
61  * repeat it here because the kernel may not be loaded as a zImage, and
62  * also because it's a hassle to communicate the SCR value to the kernel
63  * from the decompressor.
64  */
65
66 void __init get_assabet_scr(void)
67 {
68         unsigned long flags, scr, i;
69
70         local_irq_save(flags);
71         GPDR |= 0x3fc;                  /* Configure GPIO 9:2 as outputs */
72         GPSR = 0x3fc;                   /* Write 0xFF to GPIO 9:2 */
73         GPDR &= ~(0x3fc);               /* Configure GPIO 9:2 as inputs */
74         for(i = 100; i--; scr = GPLR);  /* Read GPIO 9:2 */
75         GPDR |= 0x3fc;                  /*  restore correct pin direction */
76         local_irq_restore(flags);
77         scr &= 0x3fc;                   /* save as system configuration byte. */
78
79         SCR_value = scr;
80 }
81
82 #endif  /* CONFIG_SA1100_ASSABET */
83
84
85 #if defined(CONFIG_SA1100_BITSY)
86 /*
87  * Bitsy has extended, write-only memory-mapped GPIO's
88  */
89 static int bitsy_egpio = EGPIO_BITSY_RS232_ON;
90 void clr_bitsy_egpio(unsigned long x) 
91 {
92   bitsy_egpio &= ~x;
93   BITSY_EGPIO = bitsy_egpio;
94 }
95 void set_bitsy_egpio(unsigned long x) 
96 {
97   bitsy_egpio |= x;
98   BITSY_EGPIO = bitsy_egpio;
99 }
100 EXPORT_SYMBOL(clr_bitsy_egpio);
101 EXPORT_SYMBOL(set_bitsy_egpio);
102 #endif
103
104
105 #ifdef CONFIG_SA1111
106
107 static void __init sa1111_init(void){
108   unsigned long id=SKID;
109
110   if((id & SKID_ID_MASK) == SKID_SA1111_ID)
111     printk(KERN_INFO "SA-1111 Microprocessor Companion Chip: "
112            "silicon revision %x, metal revision %x\n",
113            (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
114   else {
115     printk(KERN_ERR "Could not detect SA-1111!\n");
116     return;
117   }
118
119   /* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
120    * (SA-1110 Developer's Manual, section 9.1.2.1)
121    */
122   GAFR |= GPIO_32_768kHz;
123   GPDR |= GPIO_32_768kHz;
124   TUCR = TUCR_3_6864MHz;
125
126   /* Now, set up the PLL and RCLK in the SA-1111: */
127   SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
128   udelay(100);
129   SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;
130
131   /* SA-1111 Register Access Bus should now be available. Clocks for
132    * any other SA-1111 functional blocks must be enabled separately
133    * using the SKPCR.
134    */
135
136   /* If the system is going to use the SA-1111 DMA engines, set up
137    * the memory bus request/grant pins. Also configure the shared
138    * memory controller on the SA-1111 (SA-1111 Developer's Manual,
139    * section 3.2.3) and power up the DMA bus clock:
140    */
141   if(machine_is_assabet()){
142
143     GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
144     GPDR |= GPIO_MBGNT;
145     GPDR &= ~GPIO_MBREQ;
146     TUCR |= TUCR_MR;
147
148     /* Assabet is populated by default with two Samsung KM416S8030T-G8
149      * 128Mb SDRAMs, which are organized as 12-bit (row addr) x 9-bit
150      * (column addr), according to the data sheet. Apparently, the 
151      * bank selects factor into the row address, as Angel sets up the
152      * SA-1110 to use 14x9 addresses. The SDRAM datasheet specifies
153      * that when running at 100-125MHz, the CAS latency for -8 parts
154      * is 3 cycles, which is consistent with Angel.
155      */
156
157     SMCR = (SMCR_DTIM | SMCR_MBGE | 
158             FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) |
159             ((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0));
160
161     SKPCR |= SKPCR_DCLKEN;
162   }
163 }
164
165 #else
166 #define sa1111_init()  printk( "Warning: missing SA1111 support\n" )
167 #endif
168
169
170 static int __init hw_sa1100_init(void)
171 {
172         if( machine_is_assabet() ){
173                 if(machine_has_neponset()){
174 #ifdef CONFIG_ASSABET_NEPONSET
175                         LEDS = WHOAMI;
176                         sa1111_init();
177 #else
178                         printk( "Warning: Neponset detected but full support "
179                                 "hasn't been configured in the kernel\n" );
180 #endif
181                 }
182         } else if (machine_is_xp860()) {
183                 sa1111_init();
184         }
185         return 0;
186 }
187
188 module_init(hw_sa1100_init);