~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/ppc/platforms/pplus_setup.c

Version: ~ [ linux-5.10-rc1 ] ~ [ linux-5.9.1 ] ~ [ linux-5.8.16 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.72 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.152 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.202 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.240 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.240 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * arch/ppc/platforms/pplus_setup.c
  3  *
  4  * Board setup routines for MCG PowerPlus
  5  *
  6  * Author: Randy Vinson <rvinson@mvista.com>
  7  *
  8  * Derived from original PowerPlus PReP work by
  9  * Cort Dougan, Johnnie Peters, Matt Porter, and
 10  * Troy Benjegerdes.
 11  *
 12  * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
 13  * the terms of the GNU General Public License version 2.  This program
 14  * is licensed "as is" without any warranty of any kind, whether express
 15  * or implied.
 16  */
 17 
 18 #include <linux/config.h>
 19 #include <linux/delay.h>
 20 #include <linux/module.h>
 21 #include <linux/errno.h>
 22 #include <linux/sched.h>
 23 #include <linux/kernel.h>
 24 #include <linux/mm.h>
 25 #include <linux/stddef.h>
 26 #include <linux/unistd.h>
 27 #include <linux/ptrace.h>
 28 #include <linux/slab.h>
 29 #include <linux/user.h>
 30 #include <linux/a.out.h>
 31 #include <linux/tty.h>
 32 #include <linux/major.h>
 33 #include <linux/interrupt.h>
 34 #include <linux/reboot.h>
 35 #include <linux/init.h>
 36 #include <linux/initrd.h>
 37 #include <linux/ioport.h>
 38 #include <linux/console.h>
 39 #include <linux/timex.h>
 40 #include <linux/pci.h>
 41 #include <linux/irq.h>
 42 #include <linux/ide.h>
 43 #include <linux/kdev_t.h>
 44 #include <linux/seq_file.h>
 45 #include <linux/root_dev.h>
 46 
 47 #include <asm/sections.h>
 48 #include <asm/mmu.h>
 49 #include <asm/system.h>
 50 #include <asm/residual.h>
 51 #include <asm/io.h>
 52 #include <asm/pgtable.h>
 53 #include <asm/cache.h>
 54 #include <asm/dma.h>
 55 #include <asm/machdep.h>
 56 #include <asm/mk48t59.h>
 57 #include <asm/prep_nvram.h>
 58 #include <asm/raven.h>
 59 #include <asm/vga.h>
 60 #include <asm/time.h>
 61 
 62 #include <asm/i8259.h>
 63 #include <asm/open_pic.h>
 64 #include <asm/pplus.h>
 65 #include <asm/todc.h>
 66 #include <asm/bootinfo.h>
 67 
 68 #undef DUMP_DBATS
 69 
 70 TODC_ALLOC();
 71 
 72 extern char saved_command_line[];
 73 
 74 extern void pplus_setup_hose(void);
 75 extern void pplus_set_VIA_IDE_native(void);
 76 
 77 extern unsigned long loops_per_jiffy;
 78 
 79 static int
 80 pplus_show_cpuinfo(struct seq_file *m)
 81 {
 82         extern char *Motherboard_map_name;
 83 
 84         seq_printf(m, "vendor\t\t: Motorola MCG\n");
 85         seq_printf(m, "machine\t\t: %s\n", Motherboard_map_name);
 86 
 87         return 0;
 88 }
 89 
 90 static void __init
 91 pplus_setup_arch(void)
 92 {
 93         unsigned char reg;
 94 
 95         if ( ppc_md.progress )
 96                 ppc_md.progress("pplus_setup_arch: enter\n", 0);
 97 
 98         /* init to some ~sane value until calibrate_delay() runs */
 99         loops_per_jiffy = 50000000;
100 
101         if ( ppc_md.progress )
102                 ppc_md.progress("pplus_setup_arch: find_bridges\n", 0);
103 
104         /* Setup PCI host bridge */
105         pplus_setup_hose();
106 
107         /* Set up floppy in PS/2 mode */
108         outb(0x09, SIO_CONFIG_RA);
109         reg = inb(SIO_CONFIG_RD);
110         reg = (reg & 0x3F) | 0x40;
111         outb(reg, SIO_CONFIG_RD);
112         outb(reg, SIO_CONFIG_RD);       /* Have to write twice to change! */
113 
114         /* Enable L2.  Assume we don't need to flush -- Cort*/
115         *(unsigned char *)(0x8000081c) |= 3;
116 
117 #ifdef CONFIG_BLK_DEV_INITRD
118         if (initrd_start)
119                 ROOT_DEV = Root_RAM0;
120         else
121 #endif
122 #ifdef CONFIG_ROOT_NFS
123                 ROOT_DEV = Root_NFS;
124 #else
125                 ROOT_DEV = Root_SDA2;
126 #endif
127 
128         printk(KERN_INFO "Motorola PowerPlus Platform\n");
129         printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
130 
131         if ( ppc_md.progress )
132                 ppc_md.progress("pplus_setup_arch: raven_init\n", 0);
133 
134         raven_init();
135 
136 #ifdef CONFIG_VGA_CONSOLE
137         /* remap the VGA memory */
138         vgacon_remap_base = 0xf0000000;
139         conswitchp = &vga_con;
140 #elif defined(CONFIG_DUMMY_CONSOLE)
141         conswitchp = &dummy_con;
142 #endif
143 #ifdef CONFIG_PPCBUG_NVRAM
144         /* Read in NVRAM data */
145         init_prep_nvram();
146 
147         /* if no bootargs, look in NVRAM */
148         if ( cmd_line[0] == '\0' ) {
149                 char *bootargs;
150                  bootargs = prep_nvram_get_var("bootargs");
151                  if (bootargs != NULL) {
152                          strcpy(cmd_line, bootargs);
153                          /* again.. */
154                          strcpy(saved_command_line, cmd_line);
155                 }
156         }
157 #endif
158         if ( ppc_md.progress )
159                 ppc_md.progress("pplus_setup_arch: exit\n", 0);
160 }
161 
162 static void
163 pplus_restart(char *cmd)
164 {
165         unsigned long i = 10000;
166 
167         local_irq_disable();
168 
169         /* set VIA IDE controller into native mode */
170         pplus_set_VIA_IDE_native();
171 
172         /* set exception prefix high - to the prom */
173         _nmask_and_or_msr(0, MSR_IP);
174 
175         /* make sure bit 0 (reset) is a 0 */
176         outb( inb(0x92) & ~1L , 0x92 );
177         /* signal a reset to system control port A - soft reset */
178         outb( inb(0x92) | 1 , 0x92 );
179 
180         while ( i != 0 ) i++;
181         panic("restart failed\n");
182 }
183 
184 static void
185 pplus_halt(void)
186 {
187         /* set exception prefix high - to the prom */
188         _nmask_and_or_msr(MSR_EE, MSR_IP);
189 
190         /* make sure bit 0 (reset) is a 0 */
191         outb( inb(0x92) & ~1L , 0x92 );
192         /* signal a reset to system control port A - soft reset */
193         outb( inb(0x92) | 1 , 0x92 );
194 
195         while ( 1 ) ;
196         /*
197          * Not reached
198          */
199 }
200 
201 static void
202 pplus_power_off(void)
203 {
204         pplus_halt();
205 }
206 
207 static unsigned int
208 pplus_irq_canonicalize(u_int irq)
209 {
210         if (irq == 2)
211         {
212                 return 9;
213         }
214         else
215         {
216                 return irq;
217         }
218 }
219 
220 static void __init
221 pplus_init_IRQ(void)
222 {
223         int i;
224 
225         if (OpenPIC_Addr != NULL)
226                 openpic_init(1, NUM_8259_INTERRUPTS, 0, -1);
227         for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
228                 irq_desc[i].handler = &i8259_pic;
229         i8259_init(NULL);
230 }
231 
232 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
233 /*
234  * IDE stuff.
235  */
236 static int
237 pplus_ide_default_irq(unsigned long base)
238 {
239         switch (base) {
240                 case 0x1f0: return 14;
241                 case 0x170: return 15;
242                 default: return 0;
243         }
244 }
245 
246 static unsigned long
247 pplus_ide_default_io_base(int index)
248 {
249         switch (index) {
250                 case 0: return 0x1f0;
251                 case 1: return 0x170;
252                 default:
253                         return 0;
254         }
255 }
256 
257 static void __init
258 pplus_ide_init_hwif_ports (hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
259 {
260         unsigned long reg = data_port;
261         int i;
262 
263         for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
264                 hw->io_ports[i] = reg;
265                 reg += 1;
266         }
267         if (ctrl_port) {
268                 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
269         } else {
270                 hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
271         }
272         if (irq != NULL)
273                 *irq = pplus_ide_default_irq(data_port);
274 }
275 #endif
276 
277 #ifdef CONFIG_SMP
278 /* PowerPlus (MTX) support */
279 static int __init
280 smp_pplus_probe(void)
281 {
282         extern int mot_multi;
283 
284         if (mot_multi) {
285                 openpic_request_IPIs();
286                 smp_hw_index[1] = 1;
287                 return 2;
288         }
289 
290         return 1;
291 }
292 
293 static void __init
294 smp_pplus_kick_cpu(int nr)
295 {
296         *(unsigned long *)KERNELBASE = nr;
297         asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
298         printk("CPU1 reset, waiting\n");
299 }
300 
301 static void __init
302 smp_pplus_setup_cpu(int cpu_nr)
303 {
304         if (OpenPIC_Addr)
305                 do_openpic_setup_cpu();
306 }
307 
308 static struct smp_ops_t pplus_smp_ops = {
309         smp_openpic_message_pass,
310         smp_pplus_probe,
311         smp_pplus_kick_cpu,
312         smp_pplus_setup_cpu,
313         .give_timebase = smp_generic_give_timebase,
314         .take_timebase = smp_generic_take_timebase,
315 };
316 #endif /* CONFIG_SMP */
317 
318 #ifdef DUMP_DBATS
319 static void print_dbat(int idx, u32 bat) {
320 
321         char str[64];
322 
323         sprintf(str, "DBAT%c%c = 0x%08x\n",
324                 (char)((idx - DBAT0U) / 2) + '',
325                 (idx & 1) ? 'L' : 'U', bat);
326         ppc_md.progress(str, 0);
327 }
328 
329 #define DUMP_DBAT(x) \
330         do { \
331         u32 __temp = mfspr(x);\
332         print_dbat(x, __temp); \
333         } while (0)
334 
335 static void dump_dbats(void) {
336 
337         if (ppc_md.progress) {
338                 DUMP_DBAT(DBAT0U);
339                 DUMP_DBAT(DBAT0L);
340                 DUMP_DBAT(DBAT1U);
341                 DUMP_DBAT(DBAT1L);
342                 DUMP_DBAT(DBAT2U);
343                 DUMP_DBAT(DBAT2L);
344                 DUMP_DBAT(DBAT3U);
345                 DUMP_DBAT(DBAT3L);
346         }
347 }
348 #endif
349 
350 static unsigned long __init
351 pplus_find_end_of_memory(void)
352 {
353         unsigned long total;
354 
355         if (ppc_md.progress)
356                 ppc_md.progress("pplus_find_end_of_memory\n",0);
357 
358 #ifdef DUMP_DBATS
359         dump_dbats();
360 #endif
361 
362         total = pplus_get_mem_size(0xfef80000);
363         return (total);
364 }
365 
366 static void __init
367 pplus_map_io(void)
368 {
369         io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
370         io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO);
371 }
372 
373 static void __init
374 pplus_init2(void)
375 {
376 #ifdef CONFIG_NVRAM
377         request_region(PREP_NVRAM_AS0, 0x8, "nvram");
378 #endif
379         request_region(0x20,0x20,"pic1");
380         request_region(0xa0,0x20,"pic2");
381         request_region(0x00,0x20,"dma1");
382         request_region(0x40,0x20,"timer");
383         request_region(0x80,0x10,"dma page reg");
384         request_region(0xc0,0x20,"dma2");
385 }
386 
387 /*
388  * Set BAT 2 to access 0x8000000 so progress messages will work and set BAT 3
389  * to 0xf0000000 to access Falcon/Raven or Hawk registers
390  */
391 static __inline__ void
392 pplus_set_bat(void)
393 {
394         static int      mapping_set = 0;
395 
396         if (!mapping_set) {
397 
398                 /* wait for all outstanding memory accesses to complete */
399                 mb();
400 
401                 /* setup DBATs */
402                 mtspr(DBAT2U, 0x80001ffe);
403                 mtspr(DBAT2L, 0x8000002a);
404                 mtspr(DBAT3U, 0xf0001ffe);
405                 mtspr(DBAT3L, 0xf000002a);
406 
407                 /* wait for updates */
408                 mb();
409 
410                 mapping_set = 1;
411         }
412 
413         return;
414 }
415 
416 #ifdef CONFIG_SERIAL_TEXT_DEBUG
417 #include <linux/serial.h>
418 #include <linux/serialP.h>
419 #include <linux/serial_reg.h>
420 #include <asm/serial.h>
421 
422 static struct serial_state rs_table[RS_TABLE_SIZE] = {
423         SERIAL_PORT_DFNS        /* Defined in <asm/serial.h> */
424 };
425 
426         void
427 pplus_progress(char *s, unsigned short hex)
428 {
429         volatile char c;
430         volatile unsigned long com_port;
431         u16 shift;
432 
433         com_port = rs_table[0].port + isa_io_base;
434         shift = rs_table[0].iomem_reg_shift;
435 
436         while ((c = *s++) != 0) {
437                 while ((*((volatile unsigned char *)com_port +
438                                                 (UART_LSR << shift)) & UART_LSR_THRE) == 0)
439                         ;
440                 *(volatile unsigned char *)com_port = c;
441 
442                 if (c == '\n') {
443                         while ((*((volatile unsigned char *)com_port +
444                                                         (UART_LSR << shift)) & UART_LSR_THRE) == 0)
445                                 ;
446                         *(volatile unsigned char *)com_port = '\r';
447                 }
448         }
449 }
450 #endif  /* CONFIG_SERIAL_TEXT_DEBUG */
451 
452 void __init
453 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
454                 unsigned long r6, unsigned long r7)
455 {
456         parse_bootinfo(find_bootinfo());
457 
458         /* Map in board regs, etc. */
459         pplus_set_bat();
460 
461         isa_io_base = PREP_ISA_IO_BASE;
462         isa_mem_base = PREP_ISA_MEM_BASE;
463         pci_dram_offset = PREP_PCI_DRAM_OFFSET;
464         ISA_DMA_THRESHOLD = 0x00ffffff;
465         DMA_MODE_READ = 0x44;
466         DMA_MODE_WRITE = 0x48;
467 
468         ppc_md.setup_arch     = pplus_setup_arch;
469         ppc_md.show_percpuinfo = NULL;
470         ppc_md.show_cpuinfo    = pplus_show_cpuinfo;
471         ppc_md.irq_canonicalize = pplus_irq_canonicalize;
472         ppc_md.init_IRQ       = pplus_init_IRQ;
473         /* this gets changed later on if we have an OpenPIC -- Cort */
474         ppc_md.get_irq        = i8259_irq;
475         ppc_md.init           = pplus_init2;
476 
477         ppc_md.restart        = pplus_restart;
478         ppc_md.power_off      = pplus_power_off;
479         ppc_md.halt           = pplus_halt;
480 
481         TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1,
482                   PREP_NVRAM_DATA, 8);
483 
484         ppc_md.time_init      = todc_time_init;
485         ppc_md.set_rtc_time   = todc_set_rtc_time;
486         ppc_md.get_rtc_time   = todc_get_rtc_time;
487         ppc_md.calibrate_decr = todc_calibrate_decr;
488         ppc_md.nvram_read_val = todc_m48txx_read_val;
489         ppc_md.nvram_write_val = todc_m48txx_write_val;
490 
491         ppc_md.find_end_of_memory = pplus_find_end_of_memory;
492         ppc_md.setup_io_mappings = pplus_map_io;
493 
494 #ifdef CONFIG_SERIAL_TEXT_DEBUG
495         ppc_md.progress = pplus_progress;
496 #endif
497 
498 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
499         ppc_ide_md.default_irq = pplus_ide_default_irq;
500         ppc_ide_md.default_io_base = pplus_ide_default_io_base;
501         ppc_ide_md.ide_init_hwif = pplus_ide_init_hwif_ports;
502 #endif
503 
504 #ifdef CONFIG_SMP
505         ppc_md.smp_ops           = &pplus_smp_ops;
506 #endif /* CONFIG_SMP */
507 }
508 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp