Merge branch 'master' of /home/src/linux-2.6/
[linux-2.6] / arch / sh / boards / superh / microdev / setup.c
1 /*
2  * arch/sh/boards/superh/microdev/setup.c
3  *
4  * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5  * Copyright (C) 2003, 2004 SuperH, Inc.
6  * Copyright (C) 2004 Paul Mundt
7  *
8  * SuperH SH4-202 MicroDev board support.
9  *
10  * May be copied or modified under the terms of the GNU General Public
11  * License.  See linux/COPYING for more information.
12  */
13
14 #include <linux/config.h>
15 #include <linux/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/ioport.h>
18 #include <asm/io.h>
19 #include <asm/mach/irq.h>
20 #include <asm/mach/io.h>
21 #include <asm/machvec.h>
22 #include <asm/machvec_init.h>
23
24 extern void microdev_heartbeat(void);
25
26 /*
27  * The Machine Vector
28  */
29
30 struct sh_machine_vector mv_sh4202_microdev __initmv = {
31         .mv_nr_irqs             = 72,           /* QQQ need to check this - use the MACRO */
32
33         .mv_inb                 = microdev_inb,
34         .mv_inw                 = microdev_inw,
35         .mv_inl                 = microdev_inl,
36         .mv_outb                = microdev_outb,
37         .mv_outw                = microdev_outw,
38         .mv_outl                = microdev_outl,
39
40         .mv_inb_p               = microdev_inb_p,
41         .mv_inw_p               = microdev_inw_p,
42         .mv_inl_p               = microdev_inl_p,
43         .mv_outb_p              = microdev_outb_p,
44         .mv_outw_p              = microdev_outw_p,
45         .mv_outl_p              = microdev_outl_p,
46
47         .mv_insb                = microdev_insb,
48         .mv_insw                = microdev_insw,
49         .mv_insl                = microdev_insl,
50         .mv_outsb               = microdev_outsb,
51         .mv_outsw               = microdev_outsw,
52         .mv_outsl               = microdev_outsl,
53
54         .mv_isa_port2addr       = microdev_isa_port2addr,
55
56         .mv_init_irq            = init_microdev_irq,
57
58 #ifdef CONFIG_HEARTBEAT
59         .mv_heartbeat           = microdev_heartbeat,
60 #endif
61 };
62 ALIAS_MV(sh4202_microdev)
63
64 /****************************************************************************/
65
66
67         /*
68          * Setup for the SMSC FDC37C93xAPM
69          */
70 #define SMSC_CONFIG_PORT_ADDR    (0x3F0)
71 #define SMSC_INDEX_PORT_ADDR     SMSC_CONFIG_PORT_ADDR
72 #define SMSC_DATA_PORT_ADDR      (SMSC_INDEX_PORT_ADDR + 1)
73
74 #define SMSC_ENTER_CONFIG_KEY    0x55
75 #define SMSC_EXIT_CONFIG_KEY     0xaa
76
77 #define SMCS_LOGICAL_DEV_INDEX   0x07   /* Logical Device Number */
78 #define SMSC_DEVICE_ID_INDEX     0x20   /* Device ID */
79 #define SMSC_DEVICE_REV_INDEX    0x21   /* Device Revision */
80 #define SMSC_ACTIVATE_INDEX      0x30   /* Activate */
81 #define SMSC_PRIMARY_BASE_INDEX  0x60   /* Primary Base Address */
82 #define SMSC_SECONDARY_BASE_INDEX 0x62  /* Secondary Base Address */
83 #define SMSC_PRIMARY_INT_INDEX   0x70   /* Primary Interrupt Select */
84 #define SMSC_SECONDARY_INT_INDEX 0x72   /* Secondary Interrupt Select */
85 #define SMSC_HDCS0_INDEX         0xf0   /* HDCS0 Address Decoder */
86 #define SMSC_HDCS1_INDEX         0xf1   /* HDCS1 Address Decoder */
87
88 #define SMSC_IDE1_DEVICE        1       /* IDE #1 logical device */
89 #define SMSC_IDE2_DEVICE        2       /* IDE #2 logical device */
90 #define SMSC_PARALLEL_DEVICE    3       /* Parallel Port logical device */
91 #define SMSC_SERIAL1_DEVICE     4       /* Serial #1 logical device */
92 #define SMSC_SERIAL2_DEVICE     5       /* Serial #2 logical device */
93 #define SMSC_KEYBOARD_DEVICE    7       /* Keyboard logical device */
94 #define SMSC_CONFIG_REGISTERS   8       /* Configuration Registers (Aux I/O) */
95
96 #define SMSC_READ_INDEXED(index) ({ \
97         outb((index), SMSC_INDEX_PORT_ADDR); \
98         inb(SMSC_DATA_PORT_ADDR); })
99 #define SMSC_WRITE_INDEXED(val, index) ({ \
100         outb((index), SMSC_INDEX_PORT_ADDR); \
101         outb((val),   SMSC_DATA_PORT_ADDR); })
102
103 #define IDE1_PRIMARY_BASE       0x01f0  /* Task File Registe base for IDE #1 */
104 #define IDE1_SECONDARY_BASE     0x03f6  /* Miscellaneous AT registers for IDE #1 */
105 #define IDE2_PRIMARY_BASE       0x0170  /* Task File Registe base for IDE #2 */
106 #define IDE2_SECONDARY_BASE     0x0376  /* Miscellaneous AT registers for IDE #2 */
107
108 #define SERIAL1_PRIMARY_BASE    0x03f8
109 #define SERIAL2_PRIMARY_BASE    0x02f8
110
111 #define MSB(x)          ( (x) >> 8 )
112 #define LSB(x)          ( (x) & 0xff )
113
114         /* General-Purpose base address on CPU-board FPGA */
115 #define MICRODEV_FPGA_GP_BASE           0xa6100000ul
116
117         /* assume a Keyboard Controller is present */
118 int microdev_kbd_controller_present = 1;
119
120 const char *get_system_type(void)
121 {
122         return "SH4-202 MicroDev";
123 }
124
125 static struct resource smc91x_resources[] = {
126         [0] = {
127                 .start          = 0x300,
128                 .end            = 0x300 + 0x0001000 - 1,
129                 .flags          = IORESOURCE_MEM,
130         },
131         [1] = {
132                 .start          = MICRODEV_LINUX_IRQ_ETHERNET,
133                 .end            = MICRODEV_LINUX_IRQ_ETHERNET,
134                 .flags          = IORESOURCE_IRQ,
135         },
136 };
137
138 static struct platform_device smc91x_device = {
139         .name           = "smc91x",
140         .id             = -1,
141         .num_resources  = ARRAY_SIZE(smc91x_resources),
142         .resource       = smc91x_resources,
143 };
144
145 static int __init smc91x_setup(void)
146 {
147         return platform_device_register(&smc91x_device);
148 }
149
150 __initcall(smc91x_setup);
151
152         /*
153          * Initialize the board
154          */
155 void __init platform_setup(void)
156 {
157         int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
158         const int fpgaRevision = *fpgaRevisionRegister;
159         int * const CacheControlRegister = (int*)CCR;
160
161         printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
162                 get_system_type(), fpgaRevision, *CacheControlRegister);
163 }
164
165
166 /****************************************************************************/
167
168
169         /*
170          * Setup for the SMSC FDC37C93xAPM
171          */
172 static int __init smsc_superio_setup(void)
173 {
174
175         unsigned char devid, devrev;
176
177                 /* Initially the chip is in run state */
178                 /* Put it into configuration state */
179         outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
180
181                 /* Read device ID info */
182         devid  = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
183         devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
184         if ( (devid==0x30) && (devrev==0x01) )
185         {
186                 printk("SMSC FDC37C93xAPM SuperIO device detected\n");
187         }
188         else
189         {               /* not the device identity we expected */
190                 printk("Not detected a SMSC FDC37C93xAPM SuperIO device (devid=0x%02x, rev=0x%02x)\n",
191                         devid, devrev);
192                         /* inform the keyboard driver that we have no keyboard controller */
193                 microdev_kbd_controller_present = 0;
194                         /* little point in doing anything else in this functon */
195                 return 0;
196         }
197
198                 /* Select the keyboard device */
199         SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
200                 /* enable it */
201         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
202                 /* enable the interrupts */
203         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
204         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
205
206                 /* Select the Serial #1 device */
207         SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
208                 /* enable it */
209         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
210                 /* program with port addresses */
211         SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
212         SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
213         SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
214                 /* enable the interrupts */
215         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
216
217                 /* Select the Serial #2 device */
218         SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
219                 /* enable it */
220         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
221                 /* program with port addresses */
222         SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
223         SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
224         SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
225                 /* enable the interrupts */
226         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
227
228                 /* Select the IDE#1 device */
229         SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
230                 /* enable it */
231         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
232                 /* program with port addresses */
233         SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
234         SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
235         SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
236         SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
237         SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
238         SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
239                 /* select the interrupt */
240         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
241
242                 /* Select the IDE#2 device */
243         SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
244                 /* enable it */
245         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
246                 /* program with port addresses */
247         SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
248         SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
249         SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
250         SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
251                 /* select the interrupt */
252         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
253
254                 /* Select the configuration registers */
255         SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
256                 /* enable the appropriate GPIO pins for IDE functionality:
257                  * bit[0]   In/Out              1==input;  0==output
258                  * bit[1]   Polarity            1==invert; 0==no invert
259                  * bit[2]   Int Enb #1          1==Enable Combined IRQ #1; 0==disable
260                  * bit[3:4] Function Select     00==original; 01==Alternate Function #1
261                  */
262         SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
263         SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
264         SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
265         SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
266         SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
267
268                 /* Exit the configuraton state */
269         outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
270
271         return 0;
272 }
273
274
275 /* This is grotty, but, because kernel is always referenced on the link line
276  * before any devices, this is safe.
277  */
278 __initcall(smsc_superio_setup);