| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 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> | 
| Ben Dooks | 1deb507 | 2008-12-12 00:24:31 +0000 | [diff] [blame] | 19 | #include <linux/sysdev.h> | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 20 | #include <linux/serial_core.h> | 
|  | 21 | #include <linux/platform_device.h> | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 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 <plat/s3c6400.h> | 
|  | 37 | #include <plat/s3c6410.h> | 
|  | 38 |  | 
|  | 39 | /* table of supported CPUs */ | 
|  | 40 |  | 
|  | 41 | static const char name_s3c6400[] = "S3C6400"; | 
|  | 42 | static const char name_s3c6410[] = "S3C6410"; | 
|  | 43 |  | 
|  | 44 | static 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 |  | 
|  | 69 | static struct map_desc s3c_iodesc[] __initdata = { | 
|  | 70 | { | 
| Ben Dooks | f945ee1 | 2008-10-21 14:07:13 +0100 | [diff] [blame] | 71 | .virtual	= (unsigned long)S3C_VA_SYS, | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 72 | .pfn		= __phys_to_pfn(S3C64XX_PA_SYSCON), | 
|  | 73 | .length		= SZ_4K, | 
|  | 74 | .type		= MT_DEVICE, | 
|  | 75 | }, { | 
|  | 76 | .virtual	= (unsigned long)(S3C_VA_UART + UART_OFFS), | 
|  | 77 | .pfn		= __phys_to_pfn(S3C_PA_UART), | 
|  | 78 | .length		= SZ_4K, | 
|  | 79 | .type		= MT_DEVICE, | 
|  | 80 | }, { | 
| Ben Dooks | f945ee1 | 2008-10-21 14:07:13 +0100 | [diff] [blame] | 81 | .virtual	= (unsigned long)S3C_VA_VIC0, | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 82 | .pfn		= __phys_to_pfn(S3C64XX_PA_VIC0), | 
|  | 83 | .length		= SZ_16K, | 
|  | 84 | .type		= MT_DEVICE, | 
|  | 85 | }, { | 
| Ben Dooks | f945ee1 | 2008-10-21 14:07:13 +0100 | [diff] [blame] | 86 | .virtual	= (unsigned long)S3C_VA_VIC1, | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 87 | .pfn		= __phys_to_pfn(S3C64XX_PA_VIC1), | 
|  | 88 | .length		= SZ_16K, | 
|  | 89 | .type		= MT_DEVICE, | 
| Ben Dooks | f982dc5 | 2008-10-21 14:06:57 +0100 | [diff] [blame] | 90 | }, { | 
| Ben Dooks | f945ee1 | 2008-10-21 14:07:13 +0100 | [diff] [blame] | 91 | .virtual	= (unsigned long)S3C_VA_TIMER, | 
| Ben Dooks | f982dc5 | 2008-10-21 14:06:57 +0100 | [diff] [blame] | 92 | .pfn		= __phys_to_pfn(S3C_PA_TIMER), | 
|  | 93 | .length		= SZ_16K, | 
|  | 94 | .type		= MT_DEVICE, | 
| Ben Dooks | 94df868 | 2008-10-21 14:07:07 +0100 | [diff] [blame] | 95 | }, { | 
| Ben Dooks | f945ee1 | 2008-10-21 14:07:13 +0100 | [diff] [blame] | 96 | .virtual	= (unsigned long)S3C64XX_VA_GPIO, | 
| Ben Dooks | 94df868 | 2008-10-21 14:07:07 +0100 | [diff] [blame] | 97 | .pfn		= __phys_to_pfn(S3C64XX_PA_GPIO), | 
|  | 98 | .length		= SZ_4K, | 
|  | 99 | .type		= MT_DEVICE, | 
| Ben Dooks | 5b3d515 | 2008-12-12 00:24:38 +0000 | [diff] [blame] | 100 | }, { | 
|  | 101 | .virtual	= (unsigned long)S3C64XX_VA_MODEM, | 
|  | 102 | .pfn		= __phys_to_pfn(S3C64XX_PA_MODEM), | 
|  | 103 | .length		= SZ_4K, | 
|  | 104 | .type		= MT_DEVICE, | 
| Ben Dooks | 543899f | 2009-05-17 23:40:30 +0100 | [diff] [blame] | 105 | }, { | 
|  | 106 | .virtual	= (unsigned long)S3C_VA_WATCHDOG, | 
|  | 107 | .pfn		= __phys_to_pfn(S3C64XX_PA_WATCHDOG), | 
|  | 108 | .length		= SZ_4K, | 
|  | 109 | .type		= MT_DEVICE, | 
| Maurus Cuelenaere | 23196a4 | 2009-11-20 13:04:08 +0100 | [diff] [blame] | 110 | }, { | 
|  | 111 | .virtual	= (unsigned long)S3C_VA_USB_HSPHY, | 
|  | 112 | .pfn		= __phys_to_pfn(S3C64XX_PA_USB_HSPHY), | 
|  | 113 | .length		= SZ_1K, | 
|  | 114 | .type		= MT_DEVICE, | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 115 | }, | 
|  | 116 | }; | 
|  | 117 |  | 
| Ben Dooks | 1deb507 | 2008-12-12 00:24:31 +0000 | [diff] [blame] | 118 |  | 
|  | 119 | struct sysdev_class s3c64xx_sysclass = { | 
|  | 120 | .name	= "s3c64xx-core", | 
|  | 121 | }; | 
|  | 122 |  | 
|  | 123 | static struct sys_device s3c64xx_sysdev = { | 
|  | 124 | .cls	= &s3c64xx_sysclass, | 
|  | 125 | }; | 
|  | 126 |  | 
|  | 127 |  | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 128 | /* read cpu identification code */ | 
|  | 129 |  | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 130 | void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) | 
|  | 131 | { | 
|  | 132 | unsigned long idcode; | 
|  | 133 |  | 
|  | 134 | /* initialise the io descriptors we need for initialisation */ | 
|  | 135 | iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); | 
|  | 136 | iotable_init(mach_desc, size); | 
|  | 137 |  | 
|  | 138 | idcode = __raw_readl(S3C_VA_SYS + 0x118); | 
| Ben Dooks | e074f98 | 2009-03-24 17:31:42 +0000 | [diff] [blame] | 139 | if (!idcode) { | 
|  | 140 | /* S3C6400 has the ID register in a different place, | 
|  | 141 | * and needs a write before it can be read. */ | 
|  | 142 |  | 
|  | 143 | __raw_writel(0x0, S3C_VA_SYS + 0xA1C); | 
|  | 144 | idcode = __raw_readl(S3C_VA_SYS + 0xA1C); | 
|  | 145 | } | 
|  | 146 |  | 
| Ben Dooks | beda30f | 2008-10-21 14:06:49 +0100 | [diff] [blame] | 147 | s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); | 
|  | 148 | } | 
| Ben Dooks | 1deb507 | 2008-12-12 00:24:31 +0000 | [diff] [blame] | 149 |  | 
|  | 150 | static __init int s3c64xx_sysdev_init(void) | 
|  | 151 | { | 
|  | 152 | sysdev_class_register(&s3c64xx_sysclass); | 
|  | 153 | return sysdev_register(&s3c64xx_sysdev); | 
|  | 154 | } | 
|  | 155 |  | 
|  | 156 | core_initcall(s3c64xx_sysdev_init); |