1/* linux/arch/arm/plat-s3c64xx/cpu.c 2 * 3 * Copyright 2008 Openmoko, Inc. 4 * Copyright 2008 Simtec Electronics 5 * Ben Dooks <ben@simtec.co.uk> 6 * http://armlinux.simtec.co.uk/ 7 * 8 * S3C64XX CPU Support 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13*/ 14 15#include <linux/init.h> 16#include <linux/module.h> 17#include <linux/interrupt.h> 18#include <linux/ioport.h> 19#include <linux/sysdev.h> 20#include <linux/serial_core.h> 21#include <linux/platform_device.h> 22#include <linux/io.h> 23 24#include <mach/hardware.h> 25#include <mach/map.h> 26 27#include <asm/mach/arch.h> 28#include <asm/mach/map.h> 29 30#include <plat/regs-serial.h> 31 32#include <plat/cpu.h> 33#include <plat/devs.h> 34#include <plat/clock.h> 35 36#include <mach/s3c6400.h> 37#include <mach/s3c6410.h> 38 39/* table of supported CPUs */ 40 41static const char name_s3c6400[] = "S3C6400"; 42static const char name_s3c6410[] = "S3C6410"; 43 44static struct cpu_table cpu_ids[] __initdata = { 45 { 46 .idcode = 0x36400000, 47 .idmask = 0xfffff000, 48 .map_io = s3c6400_map_io, 49 .init_clocks = s3c6400_init_clocks, 50 .init_uarts = s3c6400_init_uarts, 51 .init = s3c6400_init, 52 .name = name_s3c6400, 53 }, { 54 .idcode = 0x36410100, 55 .idmask = 0xffffff00, 56 .map_io = s3c6410_map_io, 57 .init_clocks = s3c6410_init_clocks, 58 .init_uarts = s3c6410_init_uarts, 59 .init = s3c6410_init, 60 .name = name_s3c6410, 61 }, 62}; 63 64/* minimal IO mapping */ 65 66/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */ 67#define UART_OFFS (S3C_PA_UART & 0xfffff) 68 69static struct map_desc s3c_iodesc[] __initdata = { 70 { 71 .virtual = (unsigned long)S3C_VA_SYS, 72 .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON), 73 .length = SZ_4K, 74 .type = MT_DEVICE, 75 }, { 76 .virtual = (unsigned long)S3C_VA_MEM, 77 .pfn = __phys_to_pfn(S3C64XX_PA_SROM), 78 .length = SZ_4K, 79 .type = MT_DEVICE, 80 }, { 81 .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS), 82 .pfn = __phys_to_pfn(S3C_PA_UART), 83 .length = SZ_4K, 84 .type = MT_DEVICE, 85 }, { 86 .virtual = (unsigned long)VA_VIC0, 87 .pfn = __phys_to_pfn(S3C64XX_PA_VIC0), 88 .length = SZ_16K, 89 .type = MT_DEVICE, 90 }, { 91 .virtual = (unsigned long)VA_VIC1, 92 .pfn = __phys_to_pfn(S3C64XX_PA_VIC1), 93 .length = SZ_16K, 94 .type = MT_DEVICE, 95 }, { 96 .virtual = (unsigned long)S3C_VA_TIMER, 97 .pfn = __phys_to_pfn(S3C_PA_TIMER), 98 .length = SZ_16K, 99 .type = MT_DEVICE, 100 }, { 101 .virtual = (unsigned long)S3C64XX_VA_GPIO, 102 .pfn = __phys_to_pfn(S3C64XX_PA_GPIO), 103 .length = SZ_4K, 104 .type = MT_DEVICE, 105 }, { 106 .virtual = (unsigned long)S3C64XX_VA_MODEM, 107 .pfn = __phys_to_pfn(S3C64XX_PA_MODEM), 108 .length = SZ_4K, 109 .type = MT_DEVICE, 110 }, { 111 .virtual = (unsigned long)S3C_VA_WATCHDOG, 112 .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG), 113 .length = SZ_4K, 114 .type = MT_DEVICE, 115 }, { 116 .virtual = (unsigned long)S3C_VA_USB_HSPHY, 117 .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY), 118 .length = SZ_1K, 119 .type = MT_DEVICE, 120 }, 121}; 122 123 124struct sysdev_class s3c64xx_sysclass = { 125 .name = "s3c64xx-core", 126}; 127 128static struct sys_device s3c64xx_sysdev = { 129 .cls = &s3c64xx_sysclass, 130}; 131 132/* uart registration process */ 133 134void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) 135{ 136 s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no); 137} 138 139/* read cpu identification code */ 140 141void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) 142{ 143 unsigned long idcode; 144 145 /* initialise the io descriptors we need for initialisation */ 146 iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); 147 iotable_init(mach_desc, size); 148 149 idcode = __raw_readl(S3C_VA_SYS + 0x118); 150 if (!idcode) { 151 /* S3C6400 has the ID register in a different place, 152 * and needs a write before it can be read. */ 153 154 __raw_writel(0x0, S3C_VA_SYS + 0xA1C); 155 idcode = __raw_readl(S3C_VA_SYS + 0xA1C); 156 } 157 158 s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); 159} 160 161static __init int s3c64xx_sysdev_init(void) 162{ 163 sysdev_class_register(&s3c64xx_sysclass); 164 return sysdev_register(&s3c64xx_sysdev); 165} 166 167core_initcall(s3c64xx_sysdev_init); 168