1fd4e5a5baff3df7bd889216716779d383c6a25c1Kukjin Kim/* 268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * Copyright (c) 2006 Simtec Electronics 368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * Ben Dooks <ben@simtec.co.uk> 468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * 568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * http://armlinux.simtec.co.uk/. 668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * 768d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * This program is free software; you can redistribute it and/or modify 868d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * it under the terms of the GNU General Public License version 2 as 968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * published by the Free Software Foundation. 1068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks*/ 1168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 1268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <linux/kernel.h> 1368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <linux/types.h> 1468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <linux/interrupt.h> 1568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <linux/list.h> 1668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <linux/timer.h> 1768d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <linux/init.h> 18e425382ed90d221ef9031a1b2d97d9bfedcf90c3Ben Dooks#include <linux/clk.h> 19eca8c2424171b6b6b2dcb0faa92dfddd1e3297d9Ben Dooks#include <linux/delay.h> 204a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sievers#include <linux/device.h> 21bb072c3cf21d1c9a5a2eeb5a00679ee7bf39675bRafael J. Wysocki#include <linux/syscore_ops.h> 22b6d1f542e3f44f8988b601e3ca6277c143282179Ben Dooks#include <linux/serial_core.h> 23334a1c70bb03d7077849e88d8571a32d1d36194dTushar Behera#include <linux/serial_s3c.h> 2468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <linux/platform_device.h> 25fced80c735941fa518ac67c0b61bbe153fb8c050Russell King#include <linux/io.h> 267b6d864b48d95e6ea1df7df64475b9cb9616dcf9Robin Holt#include <linux/reboot.h> 2768d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 2868d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <asm/mach/arch.h> 2968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <asm/mach/map.h> 3068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <asm/mach/irq.h> 3168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 32c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks#include <asm/proc-fns.h> 3368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#include <asm/irq.h> 349f97da78bf018206fb623cd351d454af2f105fe0David Howells#include <asm/system_misc.h> 3568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 36fd4e5a5baff3df7bd889216716779d383c6a25c1Kukjin Kim#include <mach/hardware.h> 37a09e64fbc0094e3073dbb09c3b4bfe4ab669244bRussell King#include <mach/regs-clock.h> 38fd4e5a5baff3df7bd889216716779d383c6a25c1Kukjin Kim#include <mach/regs-gpio.h> 3968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 40a2b7ba9ca471438c2bb0c3bdf0ff2ed7fdce3d2fBen Dooks#include <plat/cpu.h> 41fd4e5a5baff3df7bd889216716779d383c6a25c1Kukjin Kim#include <plat/cpu-freq.h> 42a2b7ba9ca471438c2bb0c3bdf0ff2ed7fdce3d2fBen Dooks#include <plat/devs.h> 43ef3f2dd4810cca5bf5b1d3648968b50fb267d5e2Atul Dahiya#include <plat/nand-core.h> 44fd4e5a5baff3df7bd889216716779d383c6a25c1Kukjin Kim#include <plat/pm.h> 45fd4e5a5baff3df7bd889216716779d383c6a25c1Kukjin Kim#include <plat/regs-spi.h> 46fd4e5a5baff3df7bd889216716779d383c6a25c1Kukjin Kim 47d8fdec168542971f6ffbf0883c8be2e9bbb22ca6Heiko Stuebner#include "common.h" 48b4353784ea6d5fd4cffa7498b656f5a72d20f2cdKukjin Kim#include "regs-dsc.h" 4914cce0e7754e72516af8406a90c7c3eb177632d4Kukjin Kim#include "s3c2412-power.h" 50b4353784ea6d5fd4cffa7498b656f5a72d20f2cdKukjin Kim 5168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#ifndef CONFIG_CPU_S3C2412_ONLY 5268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooksvoid __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; 5350dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooks 5450dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooksstatic inline void s3c2412_init_gpio2(void) 5550dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooks{ 5650dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooks s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; 5750dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooks} 5850dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooks#else 5950dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooks#define s3c2412_init_gpio2() do { } while(0) 6068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks#endif 6168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 6268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks/* Initial IO mappings */ 6368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 6468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooksstatic struct map_desc s3c2412_iodesc[] __initdata = { 6568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks IODESC_ENT(CLKPWR), 6668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks IODESC_ENT(TIMER), 6768d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks IODESC_ENT(WATCHDOG), 6825400036867fa7a135fca17810555400d176acaaBen Dooks { 6925400036867fa7a135fca17810555400d176acaaBen Dooks .virtual = (unsigned long)S3C2412_VA_SSMC, 7025400036867fa7a135fca17810555400d176acaaBen Dooks .pfn = __phys_to_pfn(S3C2412_PA_SSMC), 7125400036867fa7a135fca17810555400d176acaaBen Dooks .length = SZ_1M, 7225400036867fa7a135fca17810555400d176acaaBen Dooks .type = MT_DEVICE, 7325400036867fa7a135fca17810555400d176acaaBen Dooks }, 7425400036867fa7a135fca17810555400d176acaaBen Dooks { 7525400036867fa7a135fca17810555400d176acaaBen Dooks .virtual = (unsigned long)S3C2412_VA_EBI, 7625400036867fa7a135fca17810555400d176acaaBen Dooks .pfn = __phys_to_pfn(S3C2412_PA_EBI), 7725400036867fa7a135fca17810555400d176acaaBen Dooks .length = SZ_1M, 7825400036867fa7a135fca17810555400d176acaaBen Dooks .type = MT_DEVICE, 7925400036867fa7a135fca17810555400d176acaaBen Dooks }, 8068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks}; 8168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 8268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks/* uart registration process */ 8368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 8468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooksvoid __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no) 8568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks{ 8668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no); 8768d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 8868d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks /* rename devices that are s3c2412/s3c2413 specific */ 8968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks s3c_device_sdi.name = "s3c2412-sdi"; 9072d70d06d8e431f40fc2d41710615735c0a84aedBen Dooks s3c_device_lcd.name = "s3c2412-lcd"; 91ef3f2dd4810cca5bf5b1d3648968b50fb267d5e2Atul Dahiya s3c_nand_setname("s3c2412-nand"); 92e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil 93f3fb5a556c99118186581e6546a9c41e1f73cf6fBen Dooks /* alter IRQ of SDI controller */ 94f3fb5a556c99118186581e6546a9c41e1f73cf6fBen Dooks 95f3fb5a556c99118186581e6546a9c41e1f73cf6fBen Dooks s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI; 96f3fb5a556c99118186581e6546a9c41e1f73cf6fBen Dooks s3c_device_sdi.resource[1].end = IRQ_S3C2412_SDI; 97f3fb5a556c99118186581e6546a9c41e1f73cf6fBen Dooks 98e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil /* spi channel related changes, s3c2412/13 specific */ 99e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil s3c_device_spi0.name = "s3c2412-spi"; 100e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24; 101e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil s3c_device_spi1.name = "s3c2412-spi"; 102e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil s3c_device_spi1.resource[0].start = S3C24XX_PA_SPI + S3C2412_SPI1; 103e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil s3c_device_spi1.resource[0].end = S3C24XX_PA_SPI + S3C2412_SPI1 + 0x24; 104e903382ceae1dd85e650ffc7e98facdd59cc7a3fSandeep Sanjay Patil 10568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks} 10668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 107c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks/* s3c2412_idle 108c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks * 109c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks * use the standard idle call by ensuring the idle mode 110c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks * in power config, then issuing the idle co-processor 111c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks * instruction 112c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks*/ 113c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks 114c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooksstatic void s3c2412_idle(void) 115c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks{ 116c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks unsigned long tmp; 117c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks 118c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks /* ensure our idle mode is to go to idle */ 119c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks 120c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks tmp = __raw_readl(S3C2412_PWRCFG); 121c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK; 122c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE; 123c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks __raw_writel(tmp, S3C2412_PWRCFG); 124c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks 125c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks cpu_do_idle(); 126c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks} 127c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks 12868d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks/* s3c2412_map_io 12968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * 13068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * register the standard cpu IO areas, and any passed in from the 13168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * machine specific initialisation. 13268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks*/ 13368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 13474b265d4e0555b9fc9cc75eb8876140ecf8c6b8aBen Dooksvoid __init s3c2412_map_io(void) 13568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks{ 13668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks /* move base of IO */ 13768d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 13850dedf168c1afd23cbc6c4fd8429c9e931b4e813Ben Dooks s3c2412_init_gpio2(); 13968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 140c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks /* set our idle function */ 141c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks 14292311272c1a5148e5e19d0ebc9acda0ed978fba7Nicolas Pitre arm_pm_idle = s3c2412_idle; 143c84cbb246e5a5235af30ddbe49d23bb1eaf64addBen Dooks 14468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks /* register our io-tables */ 14568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 14668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); 14768d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks} 14868d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 1494a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sievers/* need to register the subsystem before we actually register the device, and 15068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * we also need to ensure that it has been initialised before any of the 15168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * drivers even try to use it (even if not on an s3c2412 based system) 15268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks * as a driver which may support both 2410 and 2440 may try and use it. 15368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks*/ 15468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 1554a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sieversstruct bus_type s3c2412_subsys = { 156af5ca3f4ec5cc4432a42a73b050dd8898ce8fd00Kay Sievers .name = "s3c2412-core", 1574a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sievers .dev_name = "s3c2412-core", 15868d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks}; 15968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 16068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooksstatic int __init s3c2412_core_init(void) 16168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks{ 1624a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sievers return subsys_system_register(&s3c2412_subsys, NULL); 16368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks} 16468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 16568d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dookscore_initcall(s3c2412_core_init); 16668d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 1674a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sieversstatic struct device s3c2412_dev = { 1684a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sievers .bus = &s3c2412_subsys, 16968d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks}; 17068d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 17168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooksint __init s3c2412_init(void) 17268d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks{ 17368d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks printk("S3C2412: Initialising architecture\n"); 17468d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks 175fb630b9fc902e24209166b1659a8b375bf38099cDomenico Andreoli#ifdef CONFIG_PM 176bb072c3cf21d1c9a5a2eeb5a00679ee7bf39675bRafael J. Wysocki register_syscore_ops(&s3c2412_pm_syscore_ops); 177bb072c3cf21d1c9a5a2eeb5a00679ee7bf39675bRafael J. Wysocki register_syscore_ops(&s3c24xx_irq_syscore_ops); 178d8fdec168542971f6ffbf0883c8be2e9bbb22ca6Heiko Stuebner#endif 179bb072c3cf21d1c9a5a2eeb5a00679ee7bf39675bRafael J. Wysocki 1804a858cfc9af87cc60b3113c3b7b377a4305eac6aKay Sievers return device_register(&s3c2412_dev); 18168d9ab394f06f95fd4ca612c08edf13e410fd8d0Ben Dooks} 182