18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/arch/arm/mach-rpc/riscpc.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1998-2001 Russell King 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Architecture specific fixups. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci#include <linux/tty.h> 118c2ecf20Sopenharmony_ci#include <linux/delay.h> 128c2ecf20Sopenharmony_ci#include <linux/pm.h> 138c2ecf20Sopenharmony_ci#include <linux/init.h> 148c2ecf20Sopenharmony_ci#include <linux/sched.h> 158c2ecf20Sopenharmony_ci#include <linux/device.h> 168c2ecf20Sopenharmony_ci#include <linux/serial_8250.h> 178c2ecf20Sopenharmony_ci#include <linux/ata_platform.h> 188c2ecf20Sopenharmony_ci#include <linux/io.h> 198c2ecf20Sopenharmony_ci#include <linux/i2c.h> 208c2ecf20Sopenharmony_ci#include <linux/reboot.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <asm/elf.h> 238c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 248c2ecf20Sopenharmony_ci#include <mach/hardware.h> 258c2ecf20Sopenharmony_ci#include <asm/hardware/iomd.h> 268c2ecf20Sopenharmony_ci#include <asm/page.h> 278c2ecf20Sopenharmony_ci#include <asm/domain.h> 288c2ecf20Sopenharmony_ci#include <asm/setup.h> 298c2ecf20Sopenharmony_ci#include <asm/system_misc.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 328c2ecf20Sopenharmony_ci#include <asm/mach/arch.h> 338c2ecf20Sopenharmony_ci#include <asm/mach/time.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ciextern void rpc_init_irq(void); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ciunsigned int vram_size; 388c2ecf20Sopenharmony_ciunsigned int memc_ctrl_reg; 398c2ecf20Sopenharmony_ciunsigned int number_mfm_drives; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic int __init parse_tag_acorn(const struct tag *tag) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci memc_ctrl_reg = tag->u.acorn.memc_control_reg; 448c2ecf20Sopenharmony_ci number_mfm_drives = tag->u.acorn.adfsdrives; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci switch (tag->u.acorn.vram_pages) { 478c2ecf20Sopenharmony_ci case 512: 488c2ecf20Sopenharmony_ci vram_size += PAGE_SIZE * 256; 498c2ecf20Sopenharmony_ci fallthrough; /* ??? */ 508c2ecf20Sopenharmony_ci case 256: 518c2ecf20Sopenharmony_ci vram_size += PAGE_SIZE * 256; 528c2ecf20Sopenharmony_ci default: 538c2ecf20Sopenharmony_ci break; 548c2ecf20Sopenharmony_ci } 558c2ecf20Sopenharmony_ci#if 0 568c2ecf20Sopenharmony_ci if (vram_size) { 578c2ecf20Sopenharmony_ci desc->video_start = 0x02000000; 588c2ecf20Sopenharmony_ci desc->video_end = 0x02000000 + vram_size; 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci#endif 618c2ecf20Sopenharmony_ci return 0; 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci__tagtable(ATAG_ACORN, parse_tag_acorn); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic struct map_desc rpc_io_desc[] __initdata = { 678c2ecf20Sopenharmony_ci { /* VRAM */ 688c2ecf20Sopenharmony_ci .virtual = SCREEN_BASE, 698c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(SCREEN_START), 708c2ecf20Sopenharmony_ci .length = 2*1048576, 718c2ecf20Sopenharmony_ci .type = MT_DEVICE 728c2ecf20Sopenharmony_ci }, { /* IO space */ 738c2ecf20Sopenharmony_ci .virtual = (u32)IO_BASE, 748c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(IO_START), 758c2ecf20Sopenharmony_ci .length = IO_SIZE , 768c2ecf20Sopenharmony_ci .type = MT_DEVICE 778c2ecf20Sopenharmony_ci }, { /* EASI space */ 788c2ecf20Sopenharmony_ci .virtual = (unsigned long)EASI_BASE, 798c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(EASI_START), 808c2ecf20Sopenharmony_ci .length = EASI_SIZE, 818c2ecf20Sopenharmony_ci .type = MT_DEVICE 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic void __init rpc_map_io(void) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci iotable_init(rpc_io_desc, ARRAY_SIZE(rpc_io_desc)); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci /* 908c2ecf20Sopenharmony_ci * Turn off floppy. 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_ci writeb(0xc, PCIO_BASE + (0x3f2 << 2)); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci /* 958c2ecf20Sopenharmony_ci * RiscPC can't handle half-word loads and stores 968c2ecf20Sopenharmony_ci */ 978c2ecf20Sopenharmony_ci elf_hwcap &= ~HWCAP_HALF; 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic struct resource acornfb_resources[] = { 1018c2ecf20Sopenharmony_ci /* VIDC */ 1028c2ecf20Sopenharmony_ci DEFINE_RES_MEM(0x03400000, 0x00200000), 1038c2ecf20Sopenharmony_ci DEFINE_RES_IRQ(IRQ_VSYNCPULSE), 1048c2ecf20Sopenharmony_ci}; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic struct platform_device acornfb_device = { 1078c2ecf20Sopenharmony_ci .name = "acornfb", 1088c2ecf20Sopenharmony_ci .id = -1, 1098c2ecf20Sopenharmony_ci .dev = { 1108c2ecf20Sopenharmony_ci .coherent_dma_mask = 0xffffffff, 1118c2ecf20Sopenharmony_ci }, 1128c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(acornfb_resources), 1138c2ecf20Sopenharmony_ci .resource = acornfb_resources, 1148c2ecf20Sopenharmony_ci}; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic struct resource iomd_resources[] = { 1178c2ecf20Sopenharmony_ci DEFINE_RES_MEM(0x03200000, 0x10000), 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic struct platform_device iomd_device = { 1218c2ecf20Sopenharmony_ci .name = "iomd", 1228c2ecf20Sopenharmony_ci .id = -1, 1238c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(iomd_resources), 1248c2ecf20Sopenharmony_ci .resource = iomd_resources, 1258c2ecf20Sopenharmony_ci}; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic struct resource iomd_kart_resources[] = { 1288c2ecf20Sopenharmony_ci DEFINE_RES_IRQ(IRQ_KEYBOARDRX), 1298c2ecf20Sopenharmony_ci DEFINE_RES_IRQ(IRQ_KEYBOARDTX), 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic struct platform_device kbd_device = { 1338c2ecf20Sopenharmony_ci .name = "kart", 1348c2ecf20Sopenharmony_ci .id = -1, 1358c2ecf20Sopenharmony_ci .dev = { 1368c2ecf20Sopenharmony_ci .parent = &iomd_device.dev, 1378c2ecf20Sopenharmony_ci }, 1388c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(iomd_kart_resources), 1398c2ecf20Sopenharmony_ci .resource = iomd_kart_resources, 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic struct plat_serial8250_port serial_platform_data[] = { 1438c2ecf20Sopenharmony_ci { 1448c2ecf20Sopenharmony_ci .mapbase = 0x03010fe0, 1458c2ecf20Sopenharmony_ci .irq = IRQ_SERIALPORT, 1468c2ecf20Sopenharmony_ci .uartclk = 1843200, 1478c2ecf20Sopenharmony_ci .regshift = 2, 1488c2ecf20Sopenharmony_ci .iotype = UPIO_MEM, 1498c2ecf20Sopenharmony_ci .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST, 1508c2ecf20Sopenharmony_ci }, 1518c2ecf20Sopenharmony_ci { }, 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic struct platform_device serial_device = { 1558c2ecf20Sopenharmony_ci .name = "serial8250", 1568c2ecf20Sopenharmony_ci .id = PLAT8250_DEV_PLATFORM, 1578c2ecf20Sopenharmony_ci .dev = { 1588c2ecf20Sopenharmony_ci .platform_data = serial_platform_data, 1598c2ecf20Sopenharmony_ci }, 1608c2ecf20Sopenharmony_ci}; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic struct pata_platform_info pata_platform_data = { 1638c2ecf20Sopenharmony_ci .ioport_shift = 2, 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistatic struct resource pata_resources[] = { 1678c2ecf20Sopenharmony_ci DEFINE_RES_MEM(0x030107c0, 0x20), 1688c2ecf20Sopenharmony_ci DEFINE_RES_MEM(0x03010fd8, 0x04), 1698c2ecf20Sopenharmony_ci DEFINE_RES_IRQ(IRQ_HARDDISK), 1708c2ecf20Sopenharmony_ci}; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistatic struct platform_device pata_device = { 1738c2ecf20Sopenharmony_ci .name = "pata_platform", 1748c2ecf20Sopenharmony_ci .id = -1, 1758c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(pata_resources), 1768c2ecf20Sopenharmony_ci .resource = pata_resources, 1778c2ecf20Sopenharmony_ci .dev = { 1788c2ecf20Sopenharmony_ci .platform_data = &pata_platform_data, 1798c2ecf20Sopenharmony_ci .coherent_dma_mask = ~0, /* grumble */ 1808c2ecf20Sopenharmony_ci }, 1818c2ecf20Sopenharmony_ci}; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic struct platform_device *devs[] __initdata = { 1848c2ecf20Sopenharmony_ci &iomd_device, 1858c2ecf20Sopenharmony_ci &kbd_device, 1868c2ecf20Sopenharmony_ci &serial_device, 1878c2ecf20Sopenharmony_ci &acornfb_device, 1888c2ecf20Sopenharmony_ci &pata_device, 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistatic struct i2c_board_info i2c_rtc = { 1928c2ecf20Sopenharmony_ci I2C_BOARD_INFO("pcf8583", 0x50) 1938c2ecf20Sopenharmony_ci}; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic int __init rpc_init(void) 1968c2ecf20Sopenharmony_ci{ 1978c2ecf20Sopenharmony_ci i2c_register_board_info(0, &i2c_rtc, 1); 1988c2ecf20Sopenharmony_ci return platform_add_devices(devs, ARRAY_SIZE(devs)); 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ciarch_initcall(rpc_init); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic void rpc_restart(enum reboot_mode mode, const char *cmd) 2048c2ecf20Sopenharmony_ci{ 2058c2ecf20Sopenharmony_ci iomd_writeb(0, IOMD_ROMCR0); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci /* 2088c2ecf20Sopenharmony_ci * Jump into the ROM 2098c2ecf20Sopenharmony_ci */ 2108c2ecf20Sopenharmony_ci soft_restart(0); 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_civoid ioc_timer_init(void); 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ciMACHINE_START(RISCPC, "Acorn-RiscPC") 2168c2ecf20Sopenharmony_ci /* Maintainer: Russell King */ 2178c2ecf20Sopenharmony_ci .atag_offset = 0x100, 2188c2ecf20Sopenharmony_ci .reserve_lp0 = 1, 2198c2ecf20Sopenharmony_ci .reserve_lp1 = 1, 2208c2ecf20Sopenharmony_ci .map_io = rpc_map_io, 2218c2ecf20Sopenharmony_ci .init_irq = rpc_init_irq, 2228c2ecf20Sopenharmony_ci .init_time = ioc_timer_init, 2238c2ecf20Sopenharmony_ci .restart = rpc_restart, 2248c2ecf20Sopenharmony_ciMACHINE_END 225