162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * linux/arch/m68k/sun3/config.c 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 1996,1997 Pekka Pietik{inen 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 762306a36Sopenharmony_ci * License. See the file COPYING in the main directory of this archive 862306a36Sopenharmony_ci * for more details. 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/types.h> 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/mm.h> 1462306a36Sopenharmony_ci#include <linux/seq_file.h> 1562306a36Sopenharmony_ci#include <linux/tty.h> 1662306a36Sopenharmony_ci#include <linux/console.h> 1762306a36Sopenharmony_ci#include <linux/init.h> 1862306a36Sopenharmony_ci#include <linux/memblock.h> 1962306a36Sopenharmony_ci#include <linux/platform_device.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <asm/oplib.h> 2262306a36Sopenharmony_ci#include <asm/setup.h> 2362306a36Sopenharmony_ci#include <asm/contregs.h> 2462306a36Sopenharmony_ci#include <asm/movs.h> 2562306a36Sopenharmony_ci#include <asm/pgalloc.h> 2662306a36Sopenharmony_ci#include <asm/sun3-head.h> 2762306a36Sopenharmony_ci#include <asm/sun3mmu.h> 2862306a36Sopenharmony_ci#include <asm/machdep.h> 2962306a36Sopenharmony_ci#include <asm/machines.h> 3062306a36Sopenharmony_ci#include <asm/idprom.h> 3162306a36Sopenharmony_ci#include <asm/intersil.h> 3262306a36Sopenharmony_ci#include <asm/irq.h> 3362306a36Sopenharmony_ci#include <asm/sections.h> 3462306a36Sopenharmony_ci#include <asm/sun3ints.h> 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cichar sun3_reserved_pmeg[SUN3_PMEGS_NUM]; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic void sun3_sched_init(void); 3962306a36Sopenharmony_ciextern void sun3_get_model (char* model); 4062306a36Sopenharmony_ciextern int sun3_hwclk(int set, struct rtc_time *t); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_civolatile char* clock_va; 4362306a36Sopenharmony_ciextern unsigned long availmem; 4462306a36Sopenharmony_ciunsigned long num_pages; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic void sun3_get_hardware_list(struct seq_file *m) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci seq_printf(m, "PROM Revision:\t%s\n", romvec->pv_monid); 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_civoid __init sun3_init(void) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci unsigned char enable_register; 5462306a36Sopenharmony_ci int i; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci m68k_machtype= MACH_SUN3; 5762306a36Sopenharmony_ci m68k_cputype = CPU_68020; 5862306a36Sopenharmony_ci m68k_fputype = FPU_68881; /* mc68881 actually */ 5962306a36Sopenharmony_ci m68k_mmutype = MMU_SUN3; 6062306a36Sopenharmony_ci clock_va = (char *) 0xfe06000; /* dark */ 6162306a36Sopenharmony_ci sun3_intreg = (unsigned char *) 0xfe0a000; /* magic */ 6262306a36Sopenharmony_ci sun3_disable_interrupts(); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci prom_init((void *)LINUX_OPPROM_BEGVM); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci GET_CONTROL_BYTE(AC_SENABLE,enable_register); 6762306a36Sopenharmony_ci enable_register |= 0x50; /* Enable FPU */ 6862306a36Sopenharmony_ci SET_CONTROL_BYTE(AC_SENABLE,enable_register); 6962306a36Sopenharmony_ci GET_CONTROL_BYTE(AC_SENABLE,enable_register); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci /* This code looks suspicious, because it doesn't subtract 7262306a36Sopenharmony_ci memory belonging to the kernel from the available space */ 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci memset(sun3_reserved_pmeg, 0, sizeof(sun3_reserved_pmeg)); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci /* Reserve important PMEGS */ 7862306a36Sopenharmony_ci /* FIXME: These should be probed instead of hardcoded */ 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci for (i=0; i<8; i++) /* Kernel PMEGs */ 8162306a36Sopenharmony_ci sun3_reserved_pmeg[i] = 1; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci sun3_reserved_pmeg[247] = 1; /* ROM mapping */ 8462306a36Sopenharmony_ci sun3_reserved_pmeg[248] = 1; /* AMD Ethernet */ 8562306a36Sopenharmony_ci sun3_reserved_pmeg[251] = 1; /* VB area */ 8662306a36Sopenharmony_ci sun3_reserved_pmeg[254] = 1; /* main I/O */ 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci sun3_reserved_pmeg[249] = 1; 8962306a36Sopenharmony_ci sun3_reserved_pmeg[252] = 1; 9062306a36Sopenharmony_ci sun3_reserved_pmeg[253] = 1; 9162306a36Sopenharmony_ci set_fc(USER_DATA); 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/* Without this, Bad Things happen when something calls arch_reset. */ 9562306a36Sopenharmony_cistatic void sun3_reboot (void) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci prom_reboot ("vmlinux"); 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic void sun3_halt (void) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci prom_halt (); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* sun3 bootmem allocation */ 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic void __init sun3_bootmem_alloc(unsigned long memory_start, 10862306a36Sopenharmony_ci unsigned long memory_end) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci unsigned long start_page; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci /* align start/end to page boundaries */ 11362306a36Sopenharmony_ci memory_start = ((memory_start + (PAGE_SIZE-1)) & PAGE_MASK); 11462306a36Sopenharmony_ci memory_end = memory_end & PAGE_MASK; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci start_page = __pa(memory_start) >> PAGE_SHIFT; 11762306a36Sopenharmony_ci max_pfn = num_pages = __pa(memory_end) >> PAGE_SHIFT; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci high_memory = (void *)memory_end; 12062306a36Sopenharmony_ci availmem = memory_start; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci m68k_setup_node(0); 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_civoid __init config_sun3(void) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci unsigned long memory_start, memory_end; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci pr_info("ARCH: SUN3\n"); 13162306a36Sopenharmony_ci idprom_init(); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* Subtract kernel memory from available memory */ 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci mach_sched_init = sun3_sched_init; 13662306a36Sopenharmony_ci mach_init_IRQ = sun3_init_IRQ; 13762306a36Sopenharmony_ci mach_reset = sun3_reboot; 13862306a36Sopenharmony_ci mach_get_model = sun3_get_model; 13962306a36Sopenharmony_ci mach_hwclk = sun3_hwclk; 14062306a36Sopenharmony_ci mach_halt = sun3_halt; 14162306a36Sopenharmony_ci mach_get_hardware_list = sun3_get_hardware_list; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci memory_start = ((((unsigned long)_end) + 0x2000) & ~0x1fff); 14462306a36Sopenharmony_ci// PROM seems to want the last couple of physical pages. --m 14562306a36Sopenharmony_ci memory_end = *(romvec->pv_sun3mem) + PAGE_OFFSET - 2*PAGE_SIZE; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci m68k_num_memory=1; 14862306a36Sopenharmony_ci m68k_memory[0].size=*(romvec->pv_sun3mem); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci sun3_bootmem_alloc(memory_start, memory_end); 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic void __init sun3_sched_init(void) 15462306a36Sopenharmony_ci{ 15562306a36Sopenharmony_ci sun3_disable_interrupts(); 15662306a36Sopenharmony_ci intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE); 15762306a36Sopenharmony_ci intersil_clock->int_reg=INTERSIL_HZ_100_MASK; 15862306a36Sopenharmony_ci intersil_clear(); 15962306a36Sopenharmony_ci sun3_enable_irq(5); 16062306a36Sopenharmony_ci intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_ENABLE|INTERSIL_24H_MODE); 16162306a36Sopenharmony_ci sun3_enable_interrupts(); 16262306a36Sopenharmony_ci intersil_clear(); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SUN3_SCSI) 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic const struct resource sun3_scsi_vme_rsrc[] __initconst = { 16862306a36Sopenharmony_ci { 16962306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 17062306a36Sopenharmony_ci .start = SUN3_VEC_VMESCSI0, 17162306a36Sopenharmony_ci .end = SUN3_VEC_VMESCSI0, 17262306a36Sopenharmony_ci }, { 17362306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 17462306a36Sopenharmony_ci .start = 0xff200000, 17562306a36Sopenharmony_ci .end = 0xff200021, 17662306a36Sopenharmony_ci }, { 17762306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 17862306a36Sopenharmony_ci .start = SUN3_VEC_VMESCSI1, 17962306a36Sopenharmony_ci .end = SUN3_VEC_VMESCSI1, 18062306a36Sopenharmony_ci }, { 18162306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 18262306a36Sopenharmony_ci .start = 0xff204000, 18362306a36Sopenharmony_ci .end = 0xff204021, 18462306a36Sopenharmony_ci }, 18562306a36Sopenharmony_ci}; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci/* 18862306a36Sopenharmony_ci * Int: level 2 autovector 18962306a36Sopenharmony_ci * IO: type 1, base 0x00140000, 5 bits phys space: A<4..0> 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_cistatic const struct resource sun3_scsi_rsrc[] __initconst = { 19262306a36Sopenharmony_ci { 19362306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 19462306a36Sopenharmony_ci .start = 2, 19562306a36Sopenharmony_ci .end = 2, 19662306a36Sopenharmony_ci }, { 19762306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 19862306a36Sopenharmony_ci .start = 0x00140000, 19962306a36Sopenharmony_ci .end = 0x0014001f, 20062306a36Sopenharmony_ci }, 20162306a36Sopenharmony_ci}; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ciint __init sun3_platform_init(void) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci switch (idprom->id_machtype) { 20662306a36Sopenharmony_ci case SM_SUN3 | SM_3_160: 20762306a36Sopenharmony_ci case SM_SUN3 | SM_3_260: 20862306a36Sopenharmony_ci platform_device_register_simple("sun3_scsi_vme", -1, 20962306a36Sopenharmony_ci sun3_scsi_vme_rsrc, ARRAY_SIZE(sun3_scsi_vme_rsrc)); 21062306a36Sopenharmony_ci break; 21162306a36Sopenharmony_ci case SM_SUN3 | SM_3_50: 21262306a36Sopenharmony_ci case SM_SUN3 | SM_3_60: 21362306a36Sopenharmony_ci platform_device_register_simple("sun3_scsi", -1, 21462306a36Sopenharmony_ci sun3_scsi_rsrc, ARRAY_SIZE(sun3_scsi_rsrc)); 21562306a36Sopenharmony_ci break; 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci return 0; 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ciarch_initcall(sun3_platform_init); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci#endif 223