2 21Mar2001 1.1 dgt/microtronix: Altera Excalibur/Nios32 port
3 30Jun2003 kenw/microtronix: Remove cmdline check in flash
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
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>
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>
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>
66 #ifdef CONFIG_NIOS_SPI
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
);
76 extern struct consw
*conswitchp
;
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"
90 #ifndef CONFIG_PASS_CMDLINE
91 static char default_command_line
[] = CONFIG_CMDLINE
;
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};
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;
108 unsigned char *excalibur_enet_hwaddr
;
109 unsigned char excalibur_enet_hwaddr_array
[6];
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.
127 #endif /* CONFIG_BLK_DEV_INITRD */
129 strncpy(command_line
, (char *)r7
, COMMAND_LINE_SIZE
);
134 inline void flash_command(int base
, int offset
, short data
)
136 volatile unsigned short * ptr
=(unsigned short*) (base
);
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
)
152 extern int _stext
, _etext
;
153 extern int _edata
, _end
;
156 extern int _sdata
, _sbss
, _ebss
;
157 #ifdef CONFIG_BLK_DEV_BLKMEM
158 extern int *romarray
;
162 unsigned char *psrc
=(unsigned char *)((NIOS_FLASH_START
+ NIOS_FLASH_END
)>>1);
166 memory_start
= (unsigned long)&_end
;
167 memory_end
= (unsigned long) &_ramend
;
170 /* copy the command line from booting paramter region */
171 #if defined (nasys_am29lv065d_flash_0) //;dgt;
176 flash_command((int)psrc
, 0x555, 0x88);
177 while ((*psrc
!=0xFF) && (i
<sizeof(command_line
))) {
178 command_line
[i
++]=*psrc
++;
181 exit_se_flash(((NIOS_FLASH_START
+ NIOS_FLASH_END
)>>1) );
182 if (command_line
[0]==0)
185 #ifndef CONFIG_PASS_CMDLINE
186 memcpy(command_line
, default_command_line
, sizeof(default_command_line
));
189 printk("\x0F\r\n\nuClinux/Nios II\n");
190 printk("Altera Nios II support (C) 2004 Microtronix Datacom Ltd.\n");
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
);
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
;
209 ROOT_DEV
= MKDEV(BLKMEM_MAJOR
,0);
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;
219 if (strlen(*cmdline_p
))
220 printk("Command line: '%s'\n", *cmdline_p
);
222 printk("No Command line passed\n");
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;
234 /* now read the hwaddr of the ethernet --wentao*/
237 // #if defined (nasys_am29lv065d_flash_0) //;dgt;
239 unsigned char *flashptr
= //;dgt;
240 ((unsigned char *) //;dgt;
242 #if defined (na_flash_kernel_end) //;dgt2;
243 na_flash_kernel_end
//;dgt2;
245 #if defined (na_flash_kernel_base) //;dgt2;
246 na_flash_kernel_base
+ //;dgt;
248 na_flash_kernel
+ //;dgt2;
250 na_flash_kernel_size
//;dgt2;
252 - 0x00010000))); //;dgt;
253 // last 64K of Altera stratix/cyclone flash //;dgt;
255 if((*((unsigned long *) flashptr
)) == 0x00005AFE) //;dgt;
257 memcpy(excalibur_enet_hwaddr_array
, //;dgt;
258 ((void*) (flashptr
+4)),6); //;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;
268 /* 0x00-07-ED: Altera Corporation. //;dgt; */
269 *((unsigned short *) //;dgt;
270 (&(excalibur_enet_hwaddr_array
[4]))) = //;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; */
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
);;
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
;
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]);
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(
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
327 #if defined(CONFIG_DUMMY_CONSOLE)
328 conswitchp
= &dummy_con
;
333 printk("Done setup_arch\n");
338 int get_cpuinfo(char * buffer
)
340 char *cpu
, *mmu
, *fpu
;
347 clockfreq
= nasys_clock_freq
;
349 return(sprintf(buffer
, "CPU:\t\t%s\n"
352 "Clocking:\t%lu.%1luMHz\n"
353 "BogoMips:\t%lu.%02lu\n"
354 "Calibration:\t%lu loops\n",
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
;
375 clockfreq
= nasys_clock_freq
;
377 seq_printf(m
, "CPU:\t\t%s\n"
380 "Clocking:\t%lu.%1luMHz\n"
381 "BogoMips:\t%lu.%02lu\n"
382 "Calibration:\t%lu loops\n",
384 clockfreq
/1000000,(clockfreq
/100000)%10,
385 (loops_per_jiffy
*HZ
)/500000,((loops_per_jiffy
*HZ
)/5000)%100,
386 (loops_per_jiffy
*HZ
));
391 #ifdef CONFIG_NIOS_SPI
393 static int bcd2char( int x
)
395 if ( (x
& 0xF) > 0x90 || (x
& 0x0F) > 0x09 )
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 /********************************************************************/
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;
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
;
436 spi_read( NULL
, (char *)&spi_data
, 3, NULL
);
437 *sec
= (int)bcd2char( spi_data
.value
);
439 spi_data
.register_addr
= clock_read_min
;
441 spi_read( NULL
, (char *)&spi_data
, 3, NULL
);
442 *min
= (int)bcd2char( spi_data
.value
);
444 spi_data
.register_addr
= clock_read_hour
;
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
455 spi_data
.register_addr
= clock_read_date
;
457 spi_read( NULL
, (char *)&spi_data
, 3, NULL
);
458 *date
= (int)bcd2char( spi_data
.value
);
460 spi_data
.register_addr
= clock_read_month
;
462 spi_read( NULL
, (char *)&spi_data
, 3, NULL
);
463 *month
= (int)bcd2char( spi_data
.value
);
465 spi_data
.register_addr
= clock_read_year
;
467 spi_read( NULL
, (char *)&spi_data
, 3, NULL
);
468 *year
= (int)bcd2char( spi_data
.value
);
471 spi_release( NULL
, NULL
);
473 *year
= *month
= *date
= *hour
= *min
= *sec
= 0;
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
)
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
,
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
510 static struct resource smc91x_resources
[] = {
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
,
517 .start
= na_enet_irq
,
519 .flags
= IORESOURCE_IRQ
,
522 static struct platform_device smc91x_device
= {
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
);
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
543 #if defined(CONFIG_DM9000) && defined(na_dm9000)
544 #include <linux/dm9000.h>
545 static struct resource dm9k_resource
[] = {
548 .end
= na_dm9000
+ 3,
549 .flags
= IORESOURCE_MEM
,
552 .start
= na_dm9000
+ 4,
553 .end
= na_dm9000
+ 4 + 3,
554 .flags
= IORESOURCE_MEM
,
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
= {
569 .num_resources
= ARRAY_SIZE(dm9k_resource
),
570 .resource
= dm9k_resource
,
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
);
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
[] = {
590 .end
= na_ps2_0
+ 0x8 - 1,
591 .flags
= IORESOURCE_MEM
,
594 .start
= na_ps2_0_irq
,
596 .flags
= IORESOURCE_IRQ
,
599 static struct platform_device altps2_0_device
= {
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
[] = {
610 .end
= na_ps2_1
+ 0x8 - 1,
611 .flags
= IORESOURCE_MEM
,
614 .start
= na_ps2_1_irq
,
616 .flags
= IORESOURCE_IRQ
,
619 static struct platform_device altps2_1_device
= {
622 .num_resources
= ARRAY_SIZE(altps2_1_resources
),
623 .resource
= altps2_1_resources
,
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
);
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
= {
651 .platform_data
= &i2c_gpio_0_pins
,
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
);
662 arch_initcall(i2c_gpio_device_init
);
664 #endif // CONFIG_I2C_GPIO