1/* 2 * BK Id: %F% %I% %G% %U% %#% 3 */ 4/* 5 * linux/arch/ppc/kernel/setup.c 6 * 7 * Copyright (C) 1995 Linus Torvalds 8 * Adapted from 'alpha' version by Gary Thomas 9 * Modified by Cort Dougan (cort@cs.nmt.edu) 10 * Modified for MBX using prep/chrp/pmac functions by Dan (dmalek@jlc.net) 11 * Further modified for generic 8xx and 8260 by Dan. 12 */ 13 14/* 15 * bootup setup stuff.. 16 */ 17 18#include <linux/config.h> 19#include <linux/errno.h> 20#include <linux/sched.h> 21#include <linux/kernel.h> 22#include <linux/mm.h> 23#include <linux/stddef.h> 24#include <linux/unistd.h> 25#include <linux/ptrace.h> 26#include <linux/slab.h> 27#include <linux/user.h> 28#include <linux/a.out.h> 29#include <linux/tty.h> 30#include <linux/major.h> 31#include <linux/interrupt.h> 32#include <linux/reboot.h> 33#include <linux/init.h> 34#include <linux/blk.h> 35#include <linux/ioport.h> 36#include <linux/ide.h> 37#include <linux/seq_file.h> 38 39#include <asm/mmu.h> 40#include <asm/processor.h> 41#include <asm/residual.h> 42#include <asm/io.h> 43#include <asm/pgtable.h> 44#include <asm/ide.h> 45#include <asm/mpc8260.h> 46#include <asm/immap_8260.h> 47#include <asm/machdep.h> 48#include <asm/bootinfo.h> 49#include <asm/time.h> 50 51#include "ppc8260_pic.h" 52 53static int m8260_set_rtc_time(unsigned long time); 54static unsigned long m8260_get_rtc_time(void); 55static void m8260_calibrate_decr(void); 56 57unsigned char __res[sizeof(bd_t)]; 58 59extern void m8260_cpm_reset(void); 60 61static void __init 62m8260_setup_arch(void) 63{ 64 /* Reset the Communication Processor Module. 65 */ 66 m8260_cpm_reset(); 67} 68 69static void 70abort(void) 71{ 72#ifdef CONFIG_XMON 73 extern void xmon(void *); 74 xmon(0); 75#endif 76 machine_restart(NULL); 77} 78 79/* The decrementer counts at the system (internal) clock frequency 80 * divided by four. 81 */ 82static void __init 83m8260_calibrate_decr(void) 84{ 85 bd_t *binfo = (bd_t *)__res; 86 int freq, divisor; 87 88 freq = binfo->bi_busfreq; 89 divisor = 4; 90 tb_ticks_per_jiffy = freq / HZ / divisor; 91 tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); 92} 93 94/* The 8260 has an internal 1-second timer update register that 95 * we should use for this purpose. 96 */ 97static uint rtc_time; 98 99static static int 100m8260_set_rtc_time(unsigned long time) 101{ 102 rtc_time = time; 103 return(0); 104} 105 106static unsigned long 107m8260_get_rtc_time(void) 108{ 109 110 /* Get time from the RTC. 111 */ 112 return((unsigned long)rtc_time); 113} 114 115static void 116m8260_restart(char *cmd) 117{ 118 extern void m8260_gorom(bd_t *bi, uint addr); 119 uint startaddr; 120 121 /* Most boot roms have a warmstart as the second instruction 122 * of the reset vector. If that doesn't work for you, change this 123 * or the reboot program to send a proper address. 124 */ 125 startaddr = 0xff000104; 126 127 if (cmd != NULL) { 128 if (!strncmp(cmd, "startaddr=", 10)) 129 startaddr = simple_strtoul(&cmd[10], NULL, 0); 130 } 131 132 m8260_gorom((unsigned int)__pa(__res), startaddr); 133} 134 135static void 136m8260_power_off(void) 137{ 138 m8260_restart(NULL); 139} 140 141static void 142m8260_halt(void) 143{ 144 m8260_restart(NULL); 145} 146 147 148static int 149m8260_show_percpuinfo(struct seq_file *m, int i) 150{ 151 bd_t *bp; 152 153 bp = (bd_t *)__res; 154 155 seq_printf(m, "core clock\t: %d MHz\n" 156 "CPM clock\t: %d MHz\n" 157 "bus clock\t: %d MHz\n", 158 bp->bi_intfreq / 1000000, 159 bp->bi_cpmfreq / 1000000, 160 bp->bi_busfreq / 1000000); 161 162 return 0; 163} 164 165/* Initialize the internal interrupt controller. The number of 166 * interrupts supported can vary with the processor type, and the 167 * 8260 family can have up to 64. 168 * External interrupts can be either edge or level triggered, and 169 * need to be initialized by the appropriate driver. 170 */ 171static void __init 172m8260_init_IRQ(void) 173{ 174 int i; 175 void cpm_interrupt_init(void); 176 177 for ( i = 0 ; i < NR_SIU_INTS ; i++ ) 178 irq_desc[i].handler = &ppc8260_pic; 179 180 /* Initialize the default interrupt mapping priorities, 181 * in case the boot rom changed something on us. 182 */ 183 immr->im_intctl.ic_sicr = 0; 184 immr->im_intctl.ic_siprr = 0x05309770; 185 immr->im_intctl.ic_scprrh = 0x05309770; 186 immr->im_intctl.ic_scprrl = 0x05309770; 187 188} 189 190/* 191 * Same hack as 8xx 192 */ 193static unsigned long __init 194m8260_find_end_of_memory(void) 195{ 196 bd_t *binfo; 197 extern unsigned char __res[]; 198 199 binfo = (bd_t *)__res; 200 201 return binfo->bi_memsize; 202} 203 204/* Map the IMMR, plus anything else we can cover 205 * in that upper space according to the memory controller 206 * chip select mapping. Grab another bunch of space 207 * below that for stuff we can't cover in the upper. 208 */ 209static void __init 210m8260_map_io(void) 211{ 212 io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO); 213 io_block_mapping(0xe0000000, 0xe0000000, 0x10000000, _PAGE_IO); 214} 215 216void __init 217platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 218 unsigned long r6, unsigned long r7) 219{ 220 parse_bootinfo(find_bootinfo()); 221 222 if ( r3 ) 223 memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); 224 225#ifdef CONFIG_BLK_DEV_INITRD 226 /* take care of initrd if we have one */ 227 if ( r4 ) 228 { 229 initrd_start = r4 + KERNELBASE; 230 initrd_end = r5 + KERNELBASE; 231 } 232#endif /* CONFIG_BLK_DEV_INITRD */ 233 /* take care of cmd line */ 234 if ( r6 ) 235 { 236 237 *(char *)(r7+KERNELBASE) = 0; 238 strcpy(cmd_line, (char *)(r6+KERNELBASE)); 239 } 240 241 ppc_md.setup_arch = m8260_setup_arch; 242 ppc_md.show_percpuinfo = m8260_show_percpuinfo; 243 ppc_md.irq_cannonicalize = NULL; 244 ppc_md.init_IRQ = m8260_init_IRQ; 245 ppc_md.get_irq = m8260_get_irq; 246 ppc_md.init = NULL; 247 248 ppc_md.restart = m8260_restart; 249 ppc_md.power_off = m8260_power_off; 250 ppc_md.halt = m8260_halt; 251 252 ppc_md.time_init = NULL; 253 ppc_md.set_rtc_time = m8260_set_rtc_time; 254 ppc_md.get_rtc_time = m8260_get_rtc_time; 255 ppc_md.calibrate_decr = m8260_calibrate_decr; 256 257 ppc_md.find_end_of_memory = m8260_find_end_of_memory; 258 ppc_md.setup_io_mappings = m8260_map_io; 259 260 ppc_md.kbd_setkeycode = NULL; 261 ppc_md.kbd_getkeycode = NULL; 262 ppc_md.kbd_translate = NULL; 263 ppc_md.kbd_unexpected_up = NULL; 264 ppc_md.kbd_leds = NULL; 265 ppc_md.kbd_init_hw = NULL; 266 ppc_md.ppc_kbd_sysrq_xlate = NULL; 267} 268 269/* Mainly for ksyms. 270*/ 271int 272request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), 273 unsigned long flag, const char *naem, void *dev) 274{ 275 panic("request IRQ\n"); 276} 277