linux/arch/arm/mach-s3c24xx/s3c2412.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Copyright (c) 2006 Simtec Electronics
   4//      Ben Dooks <ben@simtec.co.uk>
   5//
   6// http://armlinux.simtec.co.uk/.
   7
   8#include <linux/kernel.h>
   9#include <linux/types.h>
  10#include <linux/interrupt.h>
  11#include <linux/list.h>
  12#include <linux/timer.h>
  13#include <linux/init.h>
  14#include <linux/clk.h>
  15#include <linux/delay.h>
  16#include <linux/device.h>
  17#include <linux/syscore_ops.h>
  18#include <linux/serial_core.h>
  19#include <linux/serial_s3c.h>
  20#include <linux/platform_device.h>
  21#include <linux/io.h>
  22#include <linux/reboot.h>
  23
  24#include <asm/mach/arch.h>
  25#include <asm/mach/map.h>
  26#include <asm/mach/irq.h>
  27
  28#include <asm/proc-fns.h>
  29#include <asm/irq.h>
  30#include <asm/system_misc.h>
  31
  32#include <mach/hardware.h>
  33#include <mach/regs-clock.h>
  34#include <mach/regs-gpio.h>
  35
  36#include <plat/cpu.h>
  37#include <plat/cpu-freq.h>
  38#include <plat/devs.h>
  39#include <plat/pm.h>
  40#include <plat/regs-spi.h>
  41
  42#include "common.h"
  43#include "nand-core.h"
  44#include "regs-dsc.h"
  45#include "s3c2412-power.h"
  46
  47#ifndef CONFIG_CPU_S3C2412_ONLY
  48void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
  49
  50static inline void s3c2412_init_gpio2(void)
  51{
  52        s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
  53}
  54#else
  55#define s3c2412_init_gpio2() do { } while(0)
  56#endif
  57
  58/* Initial IO mappings */
  59
  60static struct map_desc s3c2412_iodesc[] __initdata = {
  61        IODESC_ENT(CLKPWR),
  62        IODESC_ENT(TIMER),
  63        IODESC_ENT(WATCHDOG),
  64        {
  65                .virtual = (unsigned long)S3C2412_VA_SSMC,
  66                .pfn     = __phys_to_pfn(S3C2412_PA_SSMC),
  67                .length  = SZ_1M,
  68                .type    = MT_DEVICE,
  69        },
  70        {
  71                .virtual = (unsigned long)S3C2412_VA_EBI,
  72                .pfn     = __phys_to_pfn(S3C2412_PA_EBI),
  73                .length  = SZ_1M,
  74                .type    = MT_DEVICE,
  75        },
  76};
  77
  78/* uart registration process */
  79
  80void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
  81{
  82        s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
  83
  84        /* rename devices that are s3c2412/s3c2413 specific */
  85        s3c_device_sdi.name  = "s3c2412-sdi";
  86        s3c_device_lcd.name  = "s3c2412-lcd";
  87        s3c_nand_setname("s3c2412-nand");
  88
  89        /* alter IRQ of SDI controller */
  90
  91        s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
  92        s3c_device_sdi.resource[1].end   = IRQ_S3C2412_SDI;
  93
  94        /* spi channel related changes, s3c2412/13 specific */
  95        s3c_device_spi0.name = "s3c2412-spi";
  96        s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
  97        s3c_device_spi1.name = "s3c2412-spi";
  98        s3c_device_spi1.resource[0].start = S3C24XX_PA_SPI + S3C2412_SPI1;
  99        s3c_device_spi1.resource[0].end = S3C24XX_PA_SPI + S3C2412_SPI1 + 0x24;
 100
 101}
 102
 103/* s3c2412_idle
 104 *
 105 * use the standard idle call by ensuring the idle mode
 106 * in power config, then issuing the idle co-processor
 107 * instruction
 108*/
 109
 110static void s3c2412_idle(void)
 111{
 112        unsigned long tmp;
 113
 114        /* ensure our idle mode is to go to idle */
 115
 116        tmp = __raw_readl(S3C2412_PWRCFG);
 117        tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
 118        tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
 119        __raw_writel(tmp, S3C2412_PWRCFG);
 120
 121        cpu_do_idle();
 122}
 123
 124/* s3c2412_map_io
 125 *
 126 * register the standard cpu IO areas, and any passed in from the
 127 * machine specific initialisation.
 128*/
 129
 130void __init s3c2412_map_io(void)
 131{
 132        /* move base of IO */
 133
 134        s3c2412_init_gpio2();
 135
 136        /* set our idle function */
 137
 138        arm_pm_idle = s3c2412_idle;
 139
 140        /* register our io-tables */
 141
 142        iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
 143}
 144
 145/* need to register the subsystem before we actually register the device, and
 146 * we also need to ensure that it has been initialised before any of the
 147 * drivers even try to use it (even if not on an s3c2412 based system)
 148 * as a driver which may support both 2410 and 2440 may try and use it.
 149*/
 150
 151struct bus_type s3c2412_subsys = {
 152        .name = "s3c2412-core",
 153        .dev_name = "s3c2412-core",
 154};
 155
 156static int __init s3c2412_core_init(void)
 157{
 158        return subsys_system_register(&s3c2412_subsys, NULL);
 159}
 160
 161core_initcall(s3c2412_core_init);
 162
 163static struct device s3c2412_dev = {
 164        .bus            = &s3c2412_subsys,
 165};
 166
 167int __init s3c2412_init(void)
 168{
 169        printk("S3C2412: Initialising architecture\n");
 170
 171#ifdef CONFIG_PM_SLEEP
 172        register_syscore_ops(&s3c2412_pm_syscore_ops);
 173        register_syscore_ops(&s3c24xx_irq_syscore_ops);
 174#endif
 175
 176        return device_register(&s3c2412_dev);
 177}
 178