| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* linux/arch/arm/mach-s3c2410/s3c2410.c | 
|  | 2 | * | 
|  | 3 | * Copyright (c) 2003-2005 Simtec Electronics | 
|  | 4 | *	Ben Dooks <ben@simtec.co.uk> | 
|  | 5 | * | 
|  | 6 | * http://www.simtec.co.uk/products/EB2410ITX/ | 
|  | 7 | * | 
|  | 8 | * This program is free software; you can redistribute it and/or modify | 
|  | 9 | * it under the terms of the GNU General Public License version 2 as | 
|  | 10 | * published by the Free Software Foundation. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 11 | */ | 
|  | 12 |  | 
|  | 13 | #include <linux/kernel.h> | 
|  | 14 | #include <linux/types.h> | 
|  | 15 | #include <linux/interrupt.h> | 
|  | 16 | #include <linux/list.h> | 
|  | 17 | #include <linux/timer.h> | 
|  | 18 | #include <linux/init.h> | 
| Ben Dooks | a341305 | 2006-06-22 22:18:13 +0100 | [diff] [blame] | 19 | #include <linux/sysdev.h> | 
| Russell King | d052d1b | 2005-10-29 19:07:23 +0100 | [diff] [blame] | 20 | #include <linux/platform_device.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 21 |  | 
|  | 22 | #include <asm/mach/arch.h> | 
|  | 23 | #include <asm/mach/map.h> | 
|  | 24 | #include <asm/mach/irq.h> | 
|  | 25 |  | 
|  | 26 | #include <asm/hardware.h> | 
|  | 27 | #include <asm/io.h> | 
|  | 28 | #include <asm/irq.h> | 
|  | 29 |  | 
|  | 30 | #include <asm/arch/regs-clock.h> | 
|  | 31 | #include <asm/arch/regs-serial.h> | 
|  | 32 |  | 
|  | 33 | #include "s3c2410.h" | 
|  | 34 | #include "cpu.h" | 
| Ben Dooks | 66a9b49 | 2006-06-18 23:04:05 +0100 | [diff] [blame] | 35 | #include "devs.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 36 | #include "clock.h" | 
|  | 37 |  | 
|  | 38 | /* Initial IO mappings */ | 
|  | 39 |  | 
|  | 40 | static struct map_desc s3c2410_iodesc[] __initdata = { | 
|  | 41 | IODESC_ENT(USBHOST), | 
|  | 42 | IODESC_ENT(CLKPWR), | 
|  | 43 | IODESC_ENT(LCD), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | IODESC_ENT(TIMER), | 
|  | 45 | IODESC_ENT(ADC), | 
| Dimitry Andric | 62ee914 | 2005-08-17 13:01:19 +0100 | [diff] [blame] | 46 | IODESC_ENT(WATCHDOG), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 | }; | 
|  | 48 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 49 | /* our uart devices */ | 
|  | 50 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 51 | /* uart registration process */ | 
|  | 52 |  | 
|  | 53 | void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no) | 
|  | 54 | { | 
| Ben Dooks | 66a9b49 | 2006-06-18 23:04:05 +0100 | [diff] [blame] | 55 | s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 56 | } | 
|  | 57 |  | 
|  | 58 | /* s3c2410_map_io | 
|  | 59 | * | 
|  | 60 | * register the standard cpu IO areas, and any passed in from the | 
|  | 61 | * machine specific initialisation. | 
|  | 62 | */ | 
|  | 63 |  | 
|  | 64 | void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size) | 
|  | 65 | { | 
|  | 66 | /* register our io-tables */ | 
|  | 67 |  | 
|  | 68 | iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); | 
|  | 69 | iotable_init(mach_desc, mach_size); | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | void __init s3c2410_init_clocks(int xtal) | 
|  | 73 | { | 
|  | 74 | unsigned long tmp; | 
|  | 75 | unsigned long fclk; | 
|  | 76 | unsigned long hclk; | 
|  | 77 | unsigned long pclk; | 
|  | 78 |  | 
|  | 79 | /* now we've got our machine bits initialised, work out what | 
|  | 80 | * clocks we've got */ | 
|  | 81 |  | 
|  | 82 | fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal); | 
|  | 83 |  | 
|  | 84 | tmp = __raw_readl(S3C2410_CLKDIVN); | 
|  | 85 |  | 
|  | 86 | /* work out clock scalings */ | 
|  | 87 |  | 
|  | 88 | hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1); | 
|  | 89 | pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1); | 
|  | 90 |  | 
|  | 91 | /* print brieft summary of clocks, etc */ | 
|  | 92 |  | 
|  | 93 | printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", | 
|  | 94 | print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); | 
|  | 95 |  | 
|  | 96 | /* initialise the clocks here, to allow other things like the | 
|  | 97 | * console to use them | 
|  | 98 | */ | 
|  | 99 |  | 
|  | 100 | s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); | 
| Ben Dooks | 99c1385 | 2006-06-22 22:18:20 +0100 | [diff] [blame] | 101 | s3c2410_baseclk_add(); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 102 | } | 
|  | 103 |  | 
| Ben Dooks | a341305 | 2006-06-22 22:18:13 +0100 | [diff] [blame] | 104 | struct sysdev_class s3c2410_sysclass = { | 
|  | 105 | set_kset_name("s3c2410-core"), | 
|  | 106 | }; | 
|  | 107 |  | 
|  | 108 | static struct sys_device s3c2410_sysdev = { | 
|  | 109 | .cls		= &s3c2410_sysclass, | 
|  | 110 | }; | 
|  | 111 |  | 
|  | 112 | /* need to register class before we actually register the device, and | 
|  | 113 | * we also need to ensure that it has been initialised before any of the | 
|  | 114 | * drivers even try to use it (even if not on an s3c2440 based system) | 
|  | 115 | * as a driver which may support both 2410 and 2440 may try and use it. | 
|  | 116 | */ | 
|  | 117 |  | 
|  | 118 | static int __init s3c2410_core_init(void) | 
|  | 119 | { | 
|  | 120 | return sysdev_class_register(&s3c2410_sysclass); | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | core_initcall(s3c2410_core_init); | 
|  | 124 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 125 | int __init s3c2410_init(void) | 
|  | 126 | { | 
|  | 127 | printk("S3C2410: Initialising architecture\n"); | 
|  | 128 |  | 
| Ben Dooks | a341305 | 2006-06-22 22:18:13 +0100 | [diff] [blame] | 129 | return sysdev_register(&s3c2410_sysdev); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 130 | } |