Remove obsolete #include <linux/config.h>
[sfrench/cifs-2.6.git] / 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, 2005 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/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/ioport.h>
17 #include <video/s1d13xxxfb.h>
18 #include <asm/microdev.h>
19 #include <asm/io.h>
20 #include <asm/machvec.h>
21
22 extern void microdev_heartbeat(void);
23
24 /*
25  * The Machine Vector
26  */
27
28 struct sh_machine_vector mv_sh4202_microdev __initmv = {
29         .mv_nr_irqs             = 72,           /* QQQ need to check this - use the MACRO */
30
31         .mv_inb                 = microdev_inb,
32         .mv_inw                 = microdev_inw,
33         .mv_inl                 = microdev_inl,
34         .mv_outb                = microdev_outb,
35         .mv_outw                = microdev_outw,
36         .mv_outl                = microdev_outl,
37
38         .mv_inb_p               = microdev_inb_p,
39         .mv_inw_p               = microdev_inw_p,
40         .mv_inl_p               = microdev_inl_p,
41         .mv_outb_p              = microdev_outb_p,
42         .mv_outw_p              = microdev_outw_p,
43         .mv_outl_p              = microdev_outl_p,
44
45         .mv_insb                = microdev_insb,
46         .mv_insw                = microdev_insw,
47         .mv_insl                = microdev_insl,
48         .mv_outsb               = microdev_outsb,
49         .mv_outsw               = microdev_outsw,
50         .mv_outsl               = microdev_outsl,
51
52         .mv_init_irq            = init_microdev_irq,
53
54 #ifdef CONFIG_HEARTBEAT
55         .mv_heartbeat           = microdev_heartbeat,
56 #endif
57 };
58 ALIAS_MV(sh4202_microdev)
59
60 /****************************************************************************/
61
62
63         /*
64          * Setup for the SMSC FDC37C93xAPM
65          */
66 #define SMSC_CONFIG_PORT_ADDR    (0x3F0)
67 #define SMSC_INDEX_PORT_ADDR     SMSC_CONFIG_PORT_ADDR
68 #define SMSC_DATA_PORT_ADDR      (SMSC_INDEX_PORT_ADDR + 1)
69
70 #define SMSC_ENTER_CONFIG_KEY    0x55
71 #define SMSC_EXIT_CONFIG_KEY     0xaa
72
73 #define SMCS_LOGICAL_DEV_INDEX   0x07   /* Logical Device Number */
74 #define SMSC_DEVICE_ID_INDEX     0x20   /* Device ID */
75 #define SMSC_DEVICE_REV_INDEX    0x21   /* Device Revision */
76 #define SMSC_ACTIVATE_INDEX      0x30   /* Activate */
77 #define SMSC_PRIMARY_BASE_INDEX  0x60   /* Primary Base Address */
78 #define SMSC_SECONDARY_BASE_INDEX 0x62  /* Secondary Base Address */
79 #define SMSC_PRIMARY_INT_INDEX   0x70   /* Primary Interrupt Select */
80 #define SMSC_SECONDARY_INT_INDEX 0x72   /* Secondary Interrupt Select */
81 #define SMSC_HDCS0_INDEX         0xf0   /* HDCS0 Address Decoder */
82 #define SMSC_HDCS1_INDEX         0xf1   /* HDCS1 Address Decoder */
83
84 #define SMSC_IDE1_DEVICE        1       /* IDE #1 logical device */
85 #define SMSC_IDE2_DEVICE        2       /* IDE #2 logical device */
86 #define SMSC_PARALLEL_DEVICE    3       /* Parallel Port logical device */
87 #define SMSC_SERIAL1_DEVICE     4       /* Serial #1 logical device */
88 #define SMSC_SERIAL2_DEVICE     5       /* Serial #2 logical device */
89 #define SMSC_KEYBOARD_DEVICE    7       /* Keyboard logical device */
90 #define SMSC_CONFIG_REGISTERS   8       /* Configuration Registers (Aux I/O) */
91
92 #define SMSC_READ_INDEXED(index) ({ \
93         outb((index), SMSC_INDEX_PORT_ADDR); \
94         inb(SMSC_DATA_PORT_ADDR); })
95 #define SMSC_WRITE_INDEXED(val, index) ({ \
96         outb((index), SMSC_INDEX_PORT_ADDR); \
97         outb((val),   SMSC_DATA_PORT_ADDR); })
98
99 #define IDE1_PRIMARY_BASE       0x01f0  /* Task File Registe base for IDE #1 */
100 #define IDE1_SECONDARY_BASE     0x03f6  /* Miscellaneous AT registers for IDE #1 */
101 #define IDE2_PRIMARY_BASE       0x0170  /* Task File Registe base for IDE #2 */
102 #define IDE2_SECONDARY_BASE     0x0376  /* Miscellaneous AT registers for IDE #2 */
103
104 #define SERIAL1_PRIMARY_BASE    0x03f8
105 #define SERIAL2_PRIMARY_BASE    0x02f8
106
107 #define MSB(x)          ( (x) >> 8 )
108 #define LSB(x)          ( (x) & 0xff )
109
110         /* General-Purpose base address on CPU-board FPGA */
111 #define MICRODEV_FPGA_GP_BASE           0xa6100000ul
112
113         /* assume a Keyboard Controller is present */
114 int microdev_kbd_controller_present = 1;
115
116 const char *get_system_type(void)
117 {
118         return "SH4-202 MicroDev";
119 }
120
121 static struct resource smc91x_resources[] = {
122         [0] = {
123                 .start          = 0x300,
124                 .end            = 0x300 + 0x0001000 - 1,
125                 .flags          = IORESOURCE_MEM,
126         },
127         [1] = {
128                 .start          = MICRODEV_LINUX_IRQ_ETHERNET,
129                 .end            = MICRODEV_LINUX_IRQ_ETHERNET,
130                 .flags          = IORESOURCE_IRQ,
131         },
132 };
133
134 static struct platform_device smc91x_device = {
135         .name           = "smc91x",
136         .id             = -1,
137         .num_resources  = ARRAY_SIZE(smc91x_resources),
138         .resource       = smc91x_resources,
139 };
140
141 #ifdef CONFIG_FB_S1D13XXX
142 static struct s1d13xxxfb_regval s1d13806_initregs[] = {
143         { S1DREG_MISC,                  0x00 },
144         { S1DREG_COM_DISP_MODE,         0x00 },
145         { S1DREG_GPIO_CNF0,             0x00 },
146         { S1DREG_GPIO_CNF1,             0x00 },
147         { S1DREG_GPIO_CTL0,             0x00 },
148         { S1DREG_GPIO_CTL1,             0x00 },
149         { S1DREG_CLK_CNF,               0x02 },
150         { S1DREG_LCD_CLK_CNF,           0x01 },
151         { S1DREG_CRT_CLK_CNF,           0x03 },
152         { S1DREG_MPLUG_CLK_CNF,         0x03 },
153         { S1DREG_CPU2MEM_WST_SEL,       0x02 },
154         { S1DREG_SDRAM_REF_RATE,        0x03 },
155         { S1DREG_SDRAM_TC0,             0x00 },
156         { S1DREG_SDRAM_TC1,             0x01 },
157         { S1DREG_MEM_CNF,               0x80 },
158         { S1DREG_PANEL_TYPE,            0x25 },
159         { S1DREG_MOD_RATE,              0x00 },
160         { S1DREG_LCD_DISP_HWIDTH,       0x63 },
161         { S1DREG_LCD_NDISP_HPER,        0x1e },
162         { S1DREG_TFT_FPLINE_START,      0x06 },
163         { S1DREG_TFT_FPLINE_PWIDTH,     0x03 },
164         { S1DREG_LCD_DISP_VHEIGHT0,     0x57 },
165         { S1DREG_LCD_DISP_VHEIGHT1,     0x02 },
166         { S1DREG_LCD_NDISP_VPER,        0x00 },
167         { S1DREG_TFT_FPFRAME_START,     0x0a },
168         { S1DREG_TFT_FPFRAME_PWIDTH,    0x81 },
169         { S1DREG_LCD_DISP_MODE,         0x03 },
170         { S1DREG_LCD_MISC,              0x00 },
171         { S1DREG_LCD_DISP_START0,       0x00 },
172         { S1DREG_LCD_DISP_START1,       0x00 },
173         { S1DREG_LCD_DISP_START2,       0x00 },
174         { S1DREG_LCD_MEM_OFF0,          0x90 },
175         { S1DREG_LCD_MEM_OFF1,          0x01 },
176         { S1DREG_LCD_PIX_PAN,           0x00 },
177         { S1DREG_LCD_DISP_FIFO_HTC,     0x00 },
178         { S1DREG_LCD_DISP_FIFO_LTC,     0x00 },
179         { S1DREG_CRT_DISP_HWIDTH,       0x63 },
180         { S1DREG_CRT_NDISP_HPER,        0x1f },
181         { S1DREG_CRT_HRTC_START,        0x04 },
182         { S1DREG_CRT_HRTC_PWIDTH,       0x8f },
183         { S1DREG_CRT_DISP_VHEIGHT0,     0x57 },
184         { S1DREG_CRT_DISP_VHEIGHT1,     0x02 },
185         { S1DREG_CRT_NDISP_VPER,        0x1b },
186         { S1DREG_CRT_VRTC_START,        0x00 },
187         { S1DREG_CRT_VRTC_PWIDTH,       0x83 },
188         { S1DREG_TV_OUT_CTL,            0x10 },
189         { S1DREG_CRT_DISP_MODE,         0x05 },
190         { S1DREG_CRT_DISP_START0,       0x00 },
191         { S1DREG_CRT_DISP_START1,       0x00 },
192         { S1DREG_CRT_DISP_START2,       0x00 },
193         { S1DREG_CRT_MEM_OFF0,          0x20 },
194         { S1DREG_CRT_MEM_OFF1,          0x03 },
195         { S1DREG_CRT_PIX_PAN,           0x00 },
196         { S1DREG_CRT_DISP_FIFO_HTC,     0x00 },
197         { S1DREG_CRT_DISP_FIFO_LTC,     0x00 },
198         { S1DREG_LCD_CUR_CTL,           0x00 },
199         { S1DREG_LCD_CUR_START,         0x01 },
200         { S1DREG_LCD_CUR_XPOS0,         0x00 },
201         { S1DREG_LCD_CUR_XPOS1,         0x00 },
202         { S1DREG_LCD_CUR_YPOS0,         0x00 },
203         { S1DREG_LCD_CUR_YPOS1,         0x00 },
204         { S1DREG_LCD_CUR_BCTL0,         0x00 },
205         { S1DREG_LCD_CUR_GCTL0,         0x00 },
206         { S1DREG_LCD_CUR_RCTL0,         0x00 },
207         { S1DREG_LCD_CUR_BCTL1,         0x1f },
208         { S1DREG_LCD_CUR_GCTL1,         0x3f },
209         { S1DREG_LCD_CUR_RCTL1,         0x1f },
210         { S1DREG_LCD_CUR_FIFO_HTC,      0x00 },
211         { S1DREG_CRT_CUR_CTL,           0x00 },
212         { S1DREG_CRT_CUR_START,         0x01 },
213         { S1DREG_CRT_CUR_XPOS0,         0x00 },
214         { S1DREG_CRT_CUR_XPOS1,         0x00 },
215         { S1DREG_CRT_CUR_YPOS0,         0x00 },
216         { S1DREG_CRT_CUR_YPOS1,         0x00 },
217         { S1DREG_CRT_CUR_BCTL0,         0x00 },
218         { S1DREG_CRT_CUR_GCTL0,         0x00 },
219         { S1DREG_CRT_CUR_RCTL0,         0x00 },
220         { S1DREG_CRT_CUR_BCTL1,         0x1f },
221         { S1DREG_CRT_CUR_GCTL1,         0x3f },
222         { S1DREG_CRT_CUR_RCTL1,         0x1f },
223         { S1DREG_CRT_CUR_FIFO_HTC,      0x00 },
224         { S1DREG_BBLT_CTL0,             0x00 },
225         { S1DREG_BBLT_CTL1,             0x00 },
226         { S1DREG_BBLT_CC_EXP,           0x00 },
227         { S1DREG_BBLT_OP,               0x00 },
228         { S1DREG_BBLT_SRC_START0,       0x00 },
229         { S1DREG_BBLT_SRC_START1,       0x00 },
230         { S1DREG_BBLT_SRC_START2,       0x00 },
231         { S1DREG_BBLT_DST_START0,       0x00 },
232         { S1DREG_BBLT_DST_START1,       0x00 },
233         { S1DREG_BBLT_DST_START2,       0x00 },
234         { S1DREG_BBLT_MEM_OFF0,         0x00 },
235         { S1DREG_BBLT_MEM_OFF1,         0x00 },
236         { S1DREG_BBLT_WIDTH0,           0x00 },
237         { S1DREG_BBLT_WIDTH1,           0x00 },
238         { S1DREG_BBLT_HEIGHT0,          0x00 },
239         { S1DREG_BBLT_HEIGHT1,          0x00 },
240         { S1DREG_BBLT_BGC0,             0x00 },
241         { S1DREG_BBLT_BGC1,             0x00 },
242         { S1DREG_BBLT_FGC0,             0x00 },
243         { S1DREG_BBLT_FGC1,             0x00 },
244         { S1DREG_LKUP_MODE,             0x00 },
245         { S1DREG_LKUP_ADDR,             0x00 },
246         { S1DREG_PS_CNF,                0x10 },
247         { S1DREG_PS_STATUS,             0x00 },
248         { S1DREG_CPU2MEM_WDOGT,         0x00 },
249         { S1DREG_COM_DISP_MODE,         0x02 },
250 };
251
252 static struct s1d13xxxfb_pdata s1d13806_platform_data = {
253         .initregs       = s1d13806_initregs,
254         .initregssize   = ARRAY_SIZE(s1d13806_initregs),
255 };
256
257 static struct resource s1d13806_resources[] = {
258         [0] = {
259                 .start          = 0x07200000,
260                 .end            = 0x07200000 + 0x00200000 - 1,
261                 .flags          = IORESOURCE_MEM,
262         },
263         [1] = {
264                 .start          = 0x07000000,
265                 .end            = 0x07000000 + 0x00200000 - 1,
266                 .flags          = IORESOURCE_MEM,
267         },
268 };
269
270 static struct platform_device s1d13806_device = {
271         .name           = "s1d13806fb",
272         .id             = -1,
273         .num_resources  = ARRAY_SIZE(s1d13806_resources),
274         .resource       = s1d13806_resources,
275
276         .dev = {
277                 .platform_data  = &s1d13806_platform_data,
278         },
279 };
280 #endif
281
282 static struct platform_device *microdev_devices[] __initdata = {
283         &smc91x_device,
284 #ifdef CONFIG_FB_S1D13XXX
285         &s1d13806_device,
286 #endif
287 };
288
289 static int __init microdev_devices_setup(void)
290 {
291         return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices));
292 }
293
294 __initcall(microdev_devices_setup);
295
296 void __init platform_setup(void)
297 {
298         int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
299         const int fpgaRevision = *fpgaRevisionRegister;
300         int * const CacheControlRegister = (int*)CCR;
301
302         printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
303                 get_system_type(), fpgaRevision, *CacheControlRegister);
304 }
305
306
307 /****************************************************************************/
308
309
310         /*
311          * Setup for the SMSC FDC37C93xAPM
312          */
313 static int __init smsc_superio_setup(void)
314 {
315
316         unsigned char devid, devrev;
317
318                 /* Initially the chip is in run state */
319                 /* Put it into configuration state */
320         outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
321
322                 /* Read device ID info */
323         devid  = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
324         devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
325         if ( (devid==0x30) && (devrev==0x01) )
326         {
327                 printk("SMSC FDC37C93xAPM SuperIO device detected\n");
328         }
329         else
330         {               /* not the device identity we expected */
331                 printk("Not detected a SMSC FDC37C93xAPM SuperIO device (devid=0x%02x, rev=0x%02x)\n",
332                         devid, devrev);
333                         /* inform the keyboard driver that we have no keyboard controller */
334                 microdev_kbd_controller_present = 0;
335                         /* little point in doing anything else in this functon */
336                 return 0;
337         }
338
339                 /* Select the keyboard device */
340         SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
341                 /* enable it */
342         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
343                 /* enable the interrupts */
344         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
345         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
346
347                 /* Select the Serial #1 device */
348         SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
349                 /* enable it */
350         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
351                 /* program with port addresses */
352         SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
353         SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
354         SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
355                 /* enable the interrupts */
356         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
357
358                 /* Select the Serial #2 device */
359         SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
360                 /* enable it */
361         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
362                 /* program with port addresses */
363         SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
364         SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
365         SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
366                 /* enable the interrupts */
367         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
368
369                 /* Select the IDE#1 device */
370         SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
371                 /* enable it */
372         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
373                 /* program with port addresses */
374         SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
375         SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
376         SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
377         SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
378         SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
379         SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
380                 /* select the interrupt */
381         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
382
383                 /* Select the IDE#2 device */
384         SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
385                 /* enable it */
386         SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
387                 /* program with port addresses */
388         SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
389         SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
390         SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
391         SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
392                 /* select the interrupt */
393         SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
394
395                 /* Select the configuration registers */
396         SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
397                 /* enable the appropriate GPIO pins for IDE functionality:
398                  * bit[0]   In/Out              1==input;  0==output
399                  * bit[1]   Polarity            1==invert; 0==no invert
400                  * bit[2]   Int Enb #1          1==Enable Combined IRQ #1; 0==disable
401                  * bit[3:4] Function Select     00==original; 01==Alternate Function #1
402                  */
403         SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
404         SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
405         SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
406         SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
407         SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
408
409                 /* Exit the configuraton state */
410         outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
411
412         return 0;
413 }
414
415
416 /* This is grotty, but, because kernel is always referenced on the link line
417  * before any devices, this is safe.
418  */
419 __initcall(smsc_superio_setup);