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. 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> 19#include <linux/sysdev.h> 20#include <linux/serial_core.h> 21#include <linux/platform_device.h> 22 23#include <asm/mach/arch.h> 24#include <asm/mach/map.h> 25#include <asm/mach/irq.h> 26 27#include <asm/hardware.h> 28#include <asm/io.h> 29#include <asm/irq.h> 30 31#include <asm/arch/regs-clock.h> 32#include <asm/arch/regs-serial.h> 33 34#include <asm/plat-s3c24xx/s3c2410.h> 35#include <asm/plat-s3c24xx/cpu.h> 36#include <asm/plat-s3c24xx/devs.h> 37#include <asm/plat-s3c24xx/clock.h> 38 39/* Initial IO mappings */ 40 41static struct map_desc s3c2410_iodesc[] __initdata = { 42 IODESC_ENT(CLKPWR), 43 IODESC_ENT(LCD), 44 IODESC_ENT(TIMER), 45 IODESC_ENT(WATCHDOG), 46}; 47 48/* our uart devices */ 49 50/* uart registration process */ 51 52void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no) 53{ 54 s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no); 55} 56 57/* s3c2410_map_io 58 * 59 * register the standard cpu IO areas, and any passed in from the 60 * machine specific initialisation. 61*/ 62 63void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size) 64{ 65 /* register our io-tables */ 66 67 iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); 68 iotable_init(mach_desc, mach_size); 69} 70 71void __init s3c2410_init_clocks(int xtal) 72{ 73 unsigned long tmp; 74 unsigned long fclk; 75 unsigned long hclk; 76 unsigned long pclk; 77 78 /* now we've got our machine bits initialised, work out what 79 * clocks we've got */ 80 81 fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal); 82 83 tmp = __raw_readl(S3C2410_CLKDIVN); 84 85 /* work out clock scalings */ 86 87 hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1); 88 pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1); 89 90 /* print brieft summary of clocks, etc */ 91 92 printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", 93 print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); 94 95 /* initialise the clocks here, to allow other things like the 96 * console to use them 97 */ 98 99 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); 100 s3c2410_baseclk_add(); 101} 102 103struct sysdev_class s3c2410_sysclass = { 104 set_kset_name("s3c2410-core"), 105}; 106 107static struct sys_device s3c2410_sysdev = { 108 .cls = &s3c2410_sysclass, 109}; 110 111/* need to register class before we actually register the device, and 112 * we also need to ensure that it has been initialised before any of the 113 * drivers even try to use it (even if not on an s3c2410 based system) 114 * as a driver which may support both 2410 and 2440 may try and use it. 115*/ 116 117static int __init s3c2410_core_init(void) 118{ 119 return sysdev_class_register(&s3c2410_sysclass); 120} 121 122core_initcall(s3c2410_core_init); 123 124int __init s3c2410_init(void) 125{ 126 printk("S3C2410: Initialising architecture\n"); 127 128 return sysdev_register(&s3c2410_sysdev); 129} 130