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