MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / nios2nommu / kernel / setup.c
blob476cf2f72895b6f4244059ce5993b0007c9d2b17
1 /*
2 21Mar2001 1.1 dgt/microtronix: Altera Excalibur/Nios32 port
3 30Jun2003 kenw/microtronix: Remove cmdline check in flash
4 */
6 /*
7 * linux/arch/niosnommu/kernel/setup.c
9 * Copyright (C) 2004 Microtronix Datacom Ltd.
10 * Copyright (C) 2001 Vic Phillips {vic@microtronix.com}
11 * Copyleft (C) 2000 James D. Schettine {james@telos-systems.com}
12 * Copyright (C) 1999 Greg Ungerer (gerg@moreton.com.au)
13 * Copyright (C) 1998,2000 D. Jeff Dionne <jeff@lineo.ca>
14 * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
15 * Copyright (C) 1995 Hamish Macdonald
17 * All rights reserved.
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
27 * NON INFRINGEMENT. See the GNU General Public License for more
28 * details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 * This file handles the architecture-dependent parts of system setup
40 #include <linux/kernel.h>
41 #include <linux/sched.h>
42 #include <linux/platform_device.h>
43 #include <linux/delay.h>
44 #include <linux/interrupt.h>
45 #include <linux/fs.h>
46 #include <linux/fb.h>
47 #include <linux/module.h>
48 #include <linux/console.h>
49 #include <linux/genhd.h>
50 #include <linux/errno.h>
51 #include <linux/string.h>
52 #include <linux/major.h>
53 #include <linux/bootmem.h>
54 #include <linux/initrd.h>
55 #include <linux/seq_file.h>
57 #include <asm/irq.h>
58 #include <asm/byteorder.h>
59 //#include <asm/niosconf.h>
60 #include <asm/asm-offsets.h>
62 #ifdef CONFIG_BLK_DEV_INITRD
63 #include <asm/pgtable.h>
64 #endif
66 #ifdef CONFIG_NIOS_SPI
67 #include <asm/spi.h>
68 extern ssize_t spi_write(struct file *filp, const char *buf, size_t count, loff_t *ppos);
69 extern ssize_t spi_read (struct file *filp, char *buf, size_t count, loff_t *ppos);
70 extern loff_t spi_lseek (struct file *filp, loff_t offset, int origin);
71 extern int spi_open (struct inode *inode, struct file *filp);
72 extern int spi_release (struct inode *inode, struct file *filp);
73 #endif
75 #ifdef CONFIG_CONSOLE
76 extern struct consw *conswitchp;
77 #endif
79 unsigned long rom_length;
80 unsigned long memory_start;
81 unsigned long memory_end;
83 EXPORT_SYMBOL(memory_start);
84 EXPORT_SYMBOL(memory_end);
86 #ifndef CONFIG_CMDLINE
87 #define CONFIG_CMDLINE "CONSOLE=/dev/ttyS0 root=/dev/rom0 ro"
88 #endif
90 #ifndef CONFIG_PASS_CMDLINE
91 static char default_command_line[] = CONFIG_CMDLINE;
92 #endif
93 static char command_line[COMMAND_LINE_SIZE] = { 0, };
96 /* r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11*/
97 /* r12 r13 r14 r15 or2 ra fp sp gp es ste ea*/
98 static struct pt_regs fake_regs = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\
99 0, 0, 0, 0, 0, (unsigned long)cpu_idle, 0, 0, 0, 0, 0, 0};
101 #define CPU "NIOS2"
103 #if defined (CONFIG_CS89x0) || defined (CONFIG_SMC91111) || defined (CONFIG_OPEN_ETH) || defined (CONFIG_MTIP1000_ETH) || defined (CONFIG_DM9000_ETH) || defined (CONFIG_SMC91X) || defined (CONFIG_DM9000) || defined (CONFIG_DM9KS)
104 #if defined (CONFIG_MTIP1000_ETH) //;dgt3;
105 #include <../drivers/net/mtip1000.h> //;dgt3;
106 #endif //;dgt3;
108 unsigned char *excalibur_enet_hwaddr;
109 unsigned char excalibur_enet_hwaddr_array[6];
110 #endif
112 // save args passed from u-boot, called from head.S
113 void nios2_boot_init(unsigned r4,unsigned r5,unsigned r6,unsigned r7)
115 #if defined(CONFIG_PASS_CMDLINE)
116 if (r4 == 0x534f494e) // r4 is magic NIOS, to become board info check in the future
118 #if defined(CONFIG_BLK_DEV_INITRD)
120 * If the init RAM disk has been configured in, and there's a valid
121 * starting address for it, set it up.
123 if (r5) {
124 initrd_start = r5;
125 initrd_end = r6;
127 #endif /* CONFIG_BLK_DEV_INITRD */
128 if (r7)
129 strncpy(command_line, (char *)r7, COMMAND_LINE_SIZE);
131 #endif
134 inline void flash_command(int base, int offset, short data)
136 volatile unsigned short * ptr=(unsigned short*) (base);
138 ptr[0x555]=0xaa;
139 ptr[0x2aa]=0x55;
140 ptr[offset]=data;
143 inline void exit_se_flash(int base)
145 flash_command(base, 0x555, 0x90);
146 *(unsigned short*)base=0;
149 void setup_arch(char **cmdline_p)
151 int bootmap_size;
152 extern int _stext, _etext;
153 extern int _edata, _end;
154 extern int _ramend;
155 #ifdef DEBUG
156 extern int _sdata, _sbss, _ebss;
157 #ifdef CONFIG_BLK_DEV_BLKMEM
158 extern int *romarray;
159 #endif
160 #endif
161 #if 0 // krh
162 unsigned char *psrc=(unsigned char *)((NIOS_FLASH_START + NIOS_FLASH_END)>>1);
163 int i=0;
164 #endif // krh
166 memory_start = (unsigned long)&_end;
167 memory_end = (unsigned long) &_ramend;
169 #if 0 //;kenw;
170 /* copy the command line from booting paramter region */
171 #if defined (nasys_am29lv065d_flash_0) //;dgt;
172 { //;dgt;
173 // ...TBA... //;dgt;
174 } //;dgt;
175 #else //;dgt;
176 flash_command((int)psrc, 0x555, 0x88);
177 while ((*psrc!=0xFF) && (i<sizeof(command_line))) {
178 command_line[i++]=*psrc++;
180 command_line[i]=0;
181 exit_se_flash(((NIOS_FLASH_START + NIOS_FLASH_END)>>1) );
182 if (command_line[0]==0)
183 #endif //;dgt;
184 #endif //;kenw;
185 #ifndef CONFIG_PASS_CMDLINE
186 memcpy(command_line, default_command_line, sizeof(default_command_line));
187 #endif
189 printk("\x0F\r\n\nuClinux/Nios II\n");
190 printk("Altera Nios II support (C) 2004 Microtronix Datacom Ltd.\n");
192 #ifdef DEBUG
193 printk("KERNEL -> TEXT=0x%08x-0x%08x DATA=0x%08x-0x%08x "
194 "BSS=0x%08x-0x%08x\n", (int) &_stext, (int) &_etext,
195 (int) &_sdata, (int) &_edata,
196 (int) &_sbss, (int) &_ebss);
197 printk("KERNEL -> MEM=0x%06x-0x%06x STACK=0x%06x-0x%06x\n",
198 (int) memory_start, (int) memory_end,
199 (int) memory_end, (int) nasys_program_mem_end);
200 #endif
202 init_mm.start_code = (unsigned long) &_stext;
203 init_mm.end_code = (unsigned long) &_etext;
204 init_mm.end_data = (unsigned long) &_edata;
205 init_mm.brk = (unsigned long) 0;
206 init_task.thread.kregs = &fake_regs;
208 #if 0
209 ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
210 #endif
212 /* Keep a copy of command line */
213 *cmdline_p = &command_line[0];
215 memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
216 saved_command_line[COMMAND_LINE_SIZE-1] = 0;
218 #ifdef DEBUG
219 if (strlen(*cmdline_p))
220 printk("Command line: '%s'\n", *cmdline_p);
221 else
222 printk("No Command line passed\n");
223 #endif
226 #if defined (CONFIG_CS89x0) || defined (CONFIG_SMC91111) || defined (CONFIG_OPEN_ETH) || defined (CONFIG_MTIP1000_ETH) || defined (CONFIG_DM9000_ETH) || defined (CONFIG_SMC91X) || defined (CONFIG_DM9000) || defined (CONFIG_DM9KS)
228 #if defined (CONFIG_MTIP1000_ETH) //;dgt3;
229 (*((np_mtip_mac *) //;dgt3;
230 (na_mtip_mac_control_port))). //;dgt3;
231 COMMAND_CONFIG = 0; //;dgt3;
232 #endif //;dgt3;
234 /* now read the hwaddr of the ethernet --wentao*/
236 #if 1 //;dgt2;
237 // #if defined (nasys_am29lv065d_flash_0) //;dgt;
238 { //;dgt;
239 unsigned char *flashptr = //;dgt;
240 ((unsigned char *) //;dgt;
241 (( //;dgt;
242 #if defined (na_flash_kernel_end) //;dgt2;
243 na_flash_kernel_end //;dgt2;
244 #else //;dgt2;
245 #if defined (na_flash_kernel_base) //;dgt2;
246 na_flash_kernel_base + //;dgt;
247 #else //;dgt2;
248 na_flash_kernel + //;dgt2;
249 #endif //;dgt2;
250 na_flash_kernel_size //;dgt2;
251 #endif //;dgt2;
252 - 0x00010000))); //;dgt;
253 // last 64K of Altera stratix/cyclone flash //;dgt;
254 //;dgt;
255 if((*((unsigned long *) flashptr)) == 0x00005AFE) //;dgt;
256 { //;dgt;
257 memcpy(excalibur_enet_hwaddr_array, //;dgt;
258 ((void*) (flashptr+4)),6); //;dgt;
259 } //;dgt;
260 else //;dgt;
261 { //;dgt;
262 printk("\nsetup_arch: No persistant network" //;dgt;
263 " settings signature at %08lX\n", //;dgt;
264 ((unsigned long) flashptr)); //;dgt;
265 *((unsigned long *) //;dgt;
266 (&(excalibur_enet_hwaddr_array[0]))) = //;dgt;
267 0x00ED0700; //;dgt2;
268 /* 0x00-07-ED: Altera Corporation. //;dgt; */
269 *((unsigned short *) //;dgt;
270 (&(excalibur_enet_hwaddr_array[4]))) = //;dgt;
271 0x0000; //;dgt;
272 /* Should be: 0x-00-07-ED-0A-03-(Random# 0-256) //;dgt2; */
273 /* 0x-00-07-ED-0A-xx-yy Vermont boards //;dgt2; */
274 /* 0x-00-07-ED-0B-xx-yy Rhode Island boards //;dgt2; */
275 /* 0x-00-07-ED-0C-xx-yy Delaware boards //;dgt2; */
276 /* 00 Internal Altera //;dgt2; */
277 /* 01 Beta, pre-production//;dgt2; */
278 /* 02 Beta, pre-production//;dgt2; */
279 /* 03 Customer use //;dgt2; */
280 } //;dgt;
281 } //;dgt;
282 #else //;dgt;
283 flash_command(NIOS_FLASH_START, 0x555, 0x88);
284 memcpy(excalibur_enet_hwaddr_array,(void*)NIOS_FLASH_START,6);
285 exit_se_flash(NIOS_FLASH_START);;
286 #endif //;dgt;
288 /* now do the checking, make sure we got a valid addr */
289 if (excalibur_enet_hwaddr_array[0] & (unsigned char)1)
291 printk("Ethernet hardware address:Clearing invalid bit #0\n");
292 excalibur_enet_hwaddr_array[0] ^= (unsigned char)1;
294 excalibur_enet_hwaddr=excalibur_enet_hwaddr_array;
295 #ifdef DEBUG
296 printk("Setup the hardware addr for ethernet\n\t %02x %02x %02x %02x %02x %02x\n",
297 excalibur_enet_hwaddr[0],excalibur_enet_hwaddr[1],
298 excalibur_enet_hwaddr[2],excalibur_enet_hwaddr[3],
299 excalibur_enet_hwaddr[4],excalibur_enet_hwaddr[5]);
300 #endif
301 #endif
305 * give all the memory to the bootmap allocator, tell it to put the
306 * boot mem_map at the start of memory
308 bootmap_size = init_bootmem_node(
309 NODE_DATA(0),
310 memory_start >> PAGE_SHIFT, /* map goes here */
311 PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
312 memory_end >> PAGE_SHIFT);
314 * free the usable memory, we have to make sure we do not free
315 * the bootmem bitmap so we then reserve it after freeing it :-)
317 free_bootmem(memory_start, memory_end - memory_start);
318 reserve_bootmem(memory_start, bootmap_size);
319 #ifdef CONFIG_BLK_DEV_INITRD
320 if (initrd_start) reserve_bootmem(virt_to_phys((void *)initrd_start), initrd_end - initrd_start);
321 #endif /* CONFIG_BLK_DEV_INITRD */
323 * get kmalloc into gear
325 paging_init();
326 #ifdef CONFIG_VT
327 #if defined(CONFIG_DUMMY_CONSOLE)
328 conswitchp = &dummy_con;
329 #endif
330 #endif
332 #ifdef DEBUG
333 printk("Done setup_arch\n");
334 #endif
338 int get_cpuinfo(char * buffer)
340 char *cpu, *mmu, *fpu;
341 u_long clockfreq;
343 cpu = CPU;
344 mmu = "none";
345 fpu = "none";
347 clockfreq = nasys_clock_freq;
349 return(sprintf(buffer, "CPU:\t\t%s\n"
350 "MMU:\t\t%s\n"
351 "FPU:\t\t%s\n"
352 "Clocking:\t%lu.%1luMHz\n"
353 "BogoMips:\t%lu.%02lu\n"
354 "Calibration:\t%lu loops\n",
355 cpu, mmu, fpu,
356 clockfreq/1000000,(clockfreq/100000)%10,
357 (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
358 (loops_per_jiffy*HZ)));
363 * Get CPU information for use by the procfs.
366 static int show_cpuinfo(struct seq_file *m, void *v)
368 char *cpu, *mmu, *fpu;
369 u_long clockfreq;
371 cpu = CPU;
372 mmu = "none";
373 fpu = "none";
375 clockfreq = nasys_clock_freq;
377 seq_printf(m, "CPU:\t\t%s\n"
378 "MMU:\t\t%s\n"
379 "FPU:\t\t%s\n"
380 "Clocking:\t%lu.%1luMHz\n"
381 "BogoMips:\t%lu.%02lu\n"
382 "Calibration:\t%lu loops\n",
383 cpu, mmu, fpu,
384 clockfreq/1000000,(clockfreq/100000)%10,
385 (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
386 (loops_per_jiffy*HZ));
388 return 0;
391 #ifdef CONFIG_NIOS_SPI
393 static int bcd2char( int x )
395 if ( (x & 0xF) > 0x90 || (x & 0x0F) > 0x09 )
396 return 99;
398 return (((x & 0xF0) >> 4) * 10) + (x & 0x0F);
401 #endif // CONFIG_NIOS_SPI
404 void arch_gettod(int *year, int *month, int *date, int *hour, int *min, int *sec)
406 #ifdef CONFIG_NIOS_SPI
407 /********************************************************************/
408 /* Read the CMOS clock on the Microtronix Datacom O/S Support card. */
409 /* Use the SPI driver code, but circumvent the file system by using */
410 /* its internal functions. */
411 /********************************************************************/
412 int hr;
414 struct /*********************************/
415 { /* The SPI payload. Warning: the */
416 unsigned short register_addr; /* sizeof() operator will return */
417 unsigned char value; /* a length of 4 instead of 3! */
418 } spi_data; /*********************************/
421 if ( spi_open( NULL, NULL ) )
423 printk( "Cannot open SPI driver to read system CMOS clock.\n" );
424 *year = *month = *date = *hour = *min = *sec = 0;
425 return;
428 spi_lseek( NULL, clockCS, 0 /* == SEEK_SET */ );
430 spi_data.register_addr = clock_write_control;
431 spi_data.value = 0x40; // Write protect
432 spi_write( NULL, (const char *)&spi_data, 3, NULL );
434 spi_data.register_addr = clock_read_sec;
435 spi_data.value = 0;
436 spi_read( NULL, (char *)&spi_data, 3, NULL );
437 *sec = (int)bcd2char( spi_data.value );
439 spi_data.register_addr = clock_read_min;
440 spi_data.value = 0;
441 spi_read( NULL, (char *)&spi_data, 3, NULL );
442 *min = (int)bcd2char( spi_data.value );
444 spi_data.register_addr = clock_read_hour;
445 spi_data.value = 0;
446 spi_read( NULL, (char *)&spi_data, 3, NULL );
447 hr = (int)bcd2char( spi_data.value );
448 if ( hr & 0x40 ) // Check 24-hr bit
449 hr = (hr & 0x3F) + 12; // Convert to 24-hr
451 *hour = hr;
455 spi_data.register_addr = clock_read_date;
456 spi_data.value = 0;
457 spi_read( NULL, (char *)&spi_data, 3, NULL );
458 *date = (int)bcd2char( spi_data.value );
460 spi_data.register_addr = clock_read_month;
461 spi_data.value = 0;
462 spi_read( NULL, (char *)&spi_data, 3, NULL );
463 *month = (int)bcd2char( spi_data.value );
465 spi_data.register_addr = clock_read_year;
466 spi_data.value = 0;
467 spi_read( NULL, (char *)&spi_data, 3, NULL );
468 *year = (int)bcd2char( spi_data.value );
471 spi_release( NULL, NULL );
472 #else
473 *year = *month = *date = *hour = *min = *sec = 0;
475 #endif
478 static void *cpuinfo_start (struct seq_file *m, loff_t *pos)
480 return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
483 static void *cpuinfo_next (struct seq_file *m, void *v, loff_t *pos)
485 ++*pos;
486 return cpuinfo_start (m, pos);
489 static void cpuinfo_stop (struct seq_file *m, void *v)
493 struct seq_operations cpuinfo_op = {
494 start: cpuinfo_start,
495 next: cpuinfo_next,
496 stop: cpuinfo_stop,
497 show: show_cpuinfo
501 // adapted from linux/arch/arm/mach-versatile/core.c and mach-bast
502 // note, hardware MAC address is still undefined
504 #if defined(CONFIG_SMC91X) && defined(na_enet)
506 #ifndef LAN91C111_REGISTERS_OFFSET
507 #define LAN91C111_REGISTERS_OFFSET 0x300
508 #endif
510 static struct resource smc91x_resources[] = {
511 [0] = {
512 .start = na_enet + LAN91C111_REGISTERS_OFFSET,
513 .end = na_enet + LAN91C111_REGISTERS_OFFSET + 0x100 - 1, // 32bits,64k, LAN91C111_REGISTERS_OFFSET 0x0300 ?
514 .flags = IORESOURCE_MEM,
516 [1] = {
517 .start = na_enet_irq,
518 .end = na_enet_irq,
519 .flags = IORESOURCE_IRQ,
522 static struct platform_device smc91x_device = {
523 .name = "smc91x",
524 .id = 0,
525 .num_resources = ARRAY_SIZE(smc91x_resources),
526 .resource = smc91x_resources,
528 static int __init smc91x_device_init(void)
530 /* customizes platform devices, or adds new ones */
531 platform_device_register(&smc91x_device);
532 return 0;
534 arch_initcall(smc91x_device_init);
535 #endif // CONFIG_SMC91X
538 #if defined(na_DM9000A) && !defined(na_dm9000) // defs for DE2
539 #define na_dm9000 na_DM9000A
540 #define na_dm9000_irq na_DM9000A_irq
541 #endif
543 #if defined(CONFIG_DM9000) && defined(na_dm9000)
544 #include <linux/dm9000.h>
545 static struct resource dm9k_resource[] = {
546 [0] = {
547 .start = na_dm9000,
548 .end = na_dm9000 + 3,
549 .flags = IORESOURCE_MEM,
551 [1] = {
552 .start = na_dm9000 + 4,
553 .end = na_dm9000 + 4 + 3,
554 .flags = IORESOURCE_MEM,
556 [2] = {
557 .start = na_dm9000_irq,
558 .end = na_dm9000_irq,
559 .flags = IORESOURCE_IRQ,
563 static struct dm9000_plat_data dm9k_platdata = {
564 .flags = DM9000_PLATF_16BITONLY,
566 static struct platform_device dm9k_device = {
567 .name = "dm9000",
568 .id = 0,
569 .num_resources = ARRAY_SIZE(dm9k_resource),
570 .resource = dm9k_resource,
571 .dev = {
572 .platform_data = &dm9k_platdata,
575 static int __init dm9k_device_init(void)
577 /* customizes platform devices, or adds new ones */
578 platform_device_register(&dm9k_device);
579 return 0;
581 arch_initcall(dm9k_device_init);
582 #endif // CONFIG_DM9000
585 #if defined(CONFIG_SERIO_ALTPS2) && defined(na_ps2_0)
587 static struct resource altps2_0_resources[] = {
588 [0] = {
589 .start = na_ps2_0,
590 .end = na_ps2_0 + 0x8 - 1,
591 .flags = IORESOURCE_MEM,
593 [1] = {
594 .start = na_ps2_0_irq,
595 .end = na_ps2_0_irq,
596 .flags = IORESOURCE_IRQ,
599 static struct platform_device altps2_0_device = {
600 .name = "altps2",
601 .id = 0,
602 .num_resources = ARRAY_SIZE(altps2_0_resources),
603 .resource = altps2_0_resources,
606 #if defined(na_ps2_1)
607 static struct resource altps2_1_resources[] = {
608 [0] = {
609 .start = na_ps2_1,
610 .end = na_ps2_1 + 0x8 - 1,
611 .flags = IORESOURCE_MEM,
613 [1] = {
614 .start = na_ps2_1_irq,
615 .end = na_ps2_1_irq,
616 .flags = IORESOURCE_IRQ,
619 static struct platform_device altps2_1_device = {
620 .name = "altps2",
621 .id = 0,
622 .num_resources = ARRAY_SIZE(altps2_1_resources),
623 .resource = altps2_1_resources,
625 #endif // na_ps2_1
627 static int __init altps2_device_init(void)
629 /* customizes platform devices, or adds new ones */
630 platform_device_register(&altps2_0_device);
631 #if defined(na_ps2_1)
632 platform_device_register(&altps2_1_device);
633 #endif // na_ps2_1
634 return 0;
636 arch_initcall(altps2_device_init);
637 #endif // CONFIG_SERIO_ALTPS2
639 #if defined(CONFIG_I2C_GPIO) && defined(na_gpio_0)
640 #include <asm/gpio.h>
642 static struct gpio_i2c_pins i2c_gpio_0_pins = {
643 .sda_pin = (na_gpio_0+(0<<2)),
644 .scl_pin = (na_gpio_0+(1<<2)),
647 static struct platform_device i2c_gpio_0_controller = {
648 .name = "GPIO-I2C",
649 .id = 0,
650 .dev = {
651 .platform_data = &i2c_gpio_0_pins,
653 .num_resources = 0
656 static int __init i2c_gpio_device_init(void)
658 /* customizes platform devices, or adds new ones */
659 platform_device_register(&i2c_gpio_0_controller);
660 return 0;
662 arch_initcall(i2c_gpio_device_init);
664 #endif // CONFIG_I2C_GPIO