18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * linux/arch/m68k/sun3/config.c 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 1996,1997 Pekka Pietik{inen 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 78c2ecf20Sopenharmony_ci * License. See the file COPYING in the main directory of this archive 88c2ecf20Sopenharmony_ci * for more details. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/types.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/mm.h> 148c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 158c2ecf20Sopenharmony_ci#include <linux/tty.h> 168c2ecf20Sopenharmony_ci#include <linux/console.h> 178c2ecf20Sopenharmony_ci#include <linux/init.h> 188c2ecf20Sopenharmony_ci#include <linux/memblock.h> 198c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <asm/oplib.h> 228c2ecf20Sopenharmony_ci#include <asm/setup.h> 238c2ecf20Sopenharmony_ci#include <asm/contregs.h> 248c2ecf20Sopenharmony_ci#include <asm/movs.h> 258c2ecf20Sopenharmony_ci#include <asm/pgalloc.h> 268c2ecf20Sopenharmony_ci#include <asm/sun3-head.h> 278c2ecf20Sopenharmony_ci#include <asm/sun3mmu.h> 288c2ecf20Sopenharmony_ci#include <asm/machdep.h> 298c2ecf20Sopenharmony_ci#include <asm/machines.h> 308c2ecf20Sopenharmony_ci#include <asm/idprom.h> 318c2ecf20Sopenharmony_ci#include <asm/intersil.h> 328c2ecf20Sopenharmony_ci#include <asm/irq.h> 338c2ecf20Sopenharmony_ci#include <asm/sections.h> 348c2ecf20Sopenharmony_ci#include <asm/segment.h> 358c2ecf20Sopenharmony_ci#include <asm/sun3ints.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cichar sun3_reserved_pmeg[SUN3_PMEGS_NUM]; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic void sun3_sched_init(irq_handler_t handler); 408c2ecf20Sopenharmony_ciextern void sun3_get_model (char* model); 418c2ecf20Sopenharmony_ciextern int sun3_hwclk(int set, struct rtc_time *t); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_civolatile char* clock_va; 448c2ecf20Sopenharmony_ciextern unsigned long availmem; 458c2ecf20Sopenharmony_ciunsigned long num_pages; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic void sun3_get_hardware_list(struct seq_file *m) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci seq_printf(m, "PROM Revision:\t%s\n", romvec->pv_monid); 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_civoid __init sun3_init(void) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci unsigned char enable_register; 558c2ecf20Sopenharmony_ci int i; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci m68k_machtype= MACH_SUN3; 588c2ecf20Sopenharmony_ci m68k_cputype = CPU_68020; 598c2ecf20Sopenharmony_ci m68k_fputype = FPU_68881; /* mc68881 actually */ 608c2ecf20Sopenharmony_ci m68k_mmutype = MMU_SUN3; 618c2ecf20Sopenharmony_ci clock_va = (char *) 0xfe06000; /* dark */ 628c2ecf20Sopenharmony_ci sun3_intreg = (unsigned char *) 0xfe0a000; /* magic */ 638c2ecf20Sopenharmony_ci sun3_disable_interrupts(); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci prom_init((void *)LINUX_OPPROM_BEGVM); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci GET_CONTROL_BYTE(AC_SENABLE,enable_register); 688c2ecf20Sopenharmony_ci enable_register |= 0x50; /* Enable FPU */ 698c2ecf20Sopenharmony_ci SET_CONTROL_BYTE(AC_SENABLE,enable_register); 708c2ecf20Sopenharmony_ci GET_CONTROL_BYTE(AC_SENABLE,enable_register); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* This code looks suspicious, because it doesn't subtract 738c2ecf20Sopenharmony_ci memory belonging to the kernel from the available space */ 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci memset(sun3_reserved_pmeg, 0, sizeof(sun3_reserved_pmeg)); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* Reserve important PMEGS */ 798c2ecf20Sopenharmony_ci /* FIXME: These should be probed instead of hardcoded */ 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci for (i=0; i<8; i++) /* Kernel PMEGs */ 828c2ecf20Sopenharmony_ci sun3_reserved_pmeg[i] = 1; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci sun3_reserved_pmeg[247] = 1; /* ROM mapping */ 858c2ecf20Sopenharmony_ci sun3_reserved_pmeg[248] = 1; /* AMD Ethernet */ 868c2ecf20Sopenharmony_ci sun3_reserved_pmeg[251] = 1; /* VB area */ 878c2ecf20Sopenharmony_ci sun3_reserved_pmeg[254] = 1; /* main I/O */ 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci sun3_reserved_pmeg[249] = 1; 908c2ecf20Sopenharmony_ci sun3_reserved_pmeg[252] = 1; 918c2ecf20Sopenharmony_ci sun3_reserved_pmeg[253] = 1; 928c2ecf20Sopenharmony_ci set_fs(KERNEL_DS); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* Without this, Bad Things happen when something calls arch_reset. */ 968c2ecf20Sopenharmony_cistatic void sun3_reboot (void) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci prom_reboot ("vmlinux"); 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic void sun3_halt (void) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci prom_halt (); 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci/* sun3 bootmem allocation */ 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic void __init sun3_bootmem_alloc(unsigned long memory_start, 1098c2ecf20Sopenharmony_ci unsigned long memory_end) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci unsigned long start_page; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci /* align start/end to page boundaries */ 1148c2ecf20Sopenharmony_ci memory_start = ((memory_start + (PAGE_SIZE-1)) & PAGE_MASK); 1158c2ecf20Sopenharmony_ci memory_end = memory_end & PAGE_MASK; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci start_page = __pa(memory_start) >> PAGE_SHIFT; 1188c2ecf20Sopenharmony_ci max_pfn = num_pages = __pa(memory_end) >> PAGE_SHIFT; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci high_memory = (void *)memory_end; 1218c2ecf20Sopenharmony_ci availmem = memory_start; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci m68k_setup_node(0); 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_civoid __init config_sun3(void) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci unsigned long memory_start, memory_end; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci pr_info("ARCH: SUN3\n"); 1328c2ecf20Sopenharmony_ci idprom_init(); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci /* Subtract kernel memory from available memory */ 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci mach_sched_init = sun3_sched_init; 1378c2ecf20Sopenharmony_ci mach_init_IRQ = sun3_init_IRQ; 1388c2ecf20Sopenharmony_ci mach_reset = sun3_reboot; 1398c2ecf20Sopenharmony_ci mach_get_model = sun3_get_model; 1408c2ecf20Sopenharmony_ci mach_hwclk = sun3_hwclk; 1418c2ecf20Sopenharmony_ci mach_halt = sun3_halt; 1428c2ecf20Sopenharmony_ci mach_get_hardware_list = sun3_get_hardware_list; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci memory_start = ((((unsigned long)_end) + 0x2000) & ~0x1fff); 1458c2ecf20Sopenharmony_ci// PROM seems to want the last couple of physical pages. --m 1468c2ecf20Sopenharmony_ci memory_end = *(romvec->pv_sun3mem) + PAGE_OFFSET - 2*PAGE_SIZE; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci m68k_num_memory=1; 1498c2ecf20Sopenharmony_ci m68k_memory[0].size=*(romvec->pv_sun3mem); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci sun3_bootmem_alloc(memory_start, memory_end); 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic void __init sun3_sched_init(irq_handler_t timer_routine) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci sun3_disable_interrupts(); 1578c2ecf20Sopenharmony_ci intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE); 1588c2ecf20Sopenharmony_ci intersil_clock->int_reg=INTERSIL_HZ_100_MASK; 1598c2ecf20Sopenharmony_ci intersil_clear(); 1608c2ecf20Sopenharmony_ci sun3_enable_irq(5); 1618c2ecf20Sopenharmony_ci intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_ENABLE|INTERSIL_24H_MODE); 1628c2ecf20Sopenharmony_ci sun3_enable_interrupts(); 1638c2ecf20Sopenharmony_ci intersil_clear(); 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SUN3_SCSI) 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic const struct resource sun3_scsi_vme_rsrc[] __initconst = { 1698c2ecf20Sopenharmony_ci { 1708c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1718c2ecf20Sopenharmony_ci .start = SUN3_VEC_VMESCSI0, 1728c2ecf20Sopenharmony_ci .end = SUN3_VEC_VMESCSI0, 1738c2ecf20Sopenharmony_ci }, { 1748c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1758c2ecf20Sopenharmony_ci .start = 0xff200000, 1768c2ecf20Sopenharmony_ci .end = 0xff200021, 1778c2ecf20Sopenharmony_ci }, { 1788c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1798c2ecf20Sopenharmony_ci .start = SUN3_VEC_VMESCSI1, 1808c2ecf20Sopenharmony_ci .end = SUN3_VEC_VMESCSI1, 1818c2ecf20Sopenharmony_ci }, { 1828c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1838c2ecf20Sopenharmony_ci .start = 0xff204000, 1848c2ecf20Sopenharmony_ci .end = 0xff204021, 1858c2ecf20Sopenharmony_ci }, 1868c2ecf20Sopenharmony_ci}; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci/* 1898c2ecf20Sopenharmony_ci * Int: level 2 autovector 1908c2ecf20Sopenharmony_ci * IO: type 1, base 0x00140000, 5 bits phys space: A<4..0> 1918c2ecf20Sopenharmony_ci */ 1928c2ecf20Sopenharmony_cistatic const struct resource sun3_scsi_rsrc[] __initconst = { 1938c2ecf20Sopenharmony_ci { 1948c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1958c2ecf20Sopenharmony_ci .start = 2, 1968c2ecf20Sopenharmony_ci .end = 2, 1978c2ecf20Sopenharmony_ci }, { 1988c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1998c2ecf20Sopenharmony_ci .start = 0x00140000, 2008c2ecf20Sopenharmony_ci .end = 0x0014001f, 2018c2ecf20Sopenharmony_ci }, 2028c2ecf20Sopenharmony_ci}; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ciint __init sun3_platform_init(void) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci switch (idprom->id_machtype) { 2078c2ecf20Sopenharmony_ci case SM_SUN3 | SM_3_160: 2088c2ecf20Sopenharmony_ci case SM_SUN3 | SM_3_260: 2098c2ecf20Sopenharmony_ci platform_device_register_simple("sun3_scsi_vme", -1, 2108c2ecf20Sopenharmony_ci sun3_scsi_vme_rsrc, ARRAY_SIZE(sun3_scsi_vme_rsrc)); 2118c2ecf20Sopenharmony_ci break; 2128c2ecf20Sopenharmony_ci case SM_SUN3 | SM_3_50: 2138c2ecf20Sopenharmony_ci case SM_SUN3 | SM_3_60: 2148c2ecf20Sopenharmony_ci platform_device_register_simple("sun3_scsi", -1, 2158c2ecf20Sopenharmony_ci sun3_scsi_rsrc, ARRAY_SIZE(sun3_scsi_rsrc)); 2168c2ecf20Sopenharmony_ci break; 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci return 0; 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ciarch_initcall(sun3_platform_init); 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci#endif 224