linux/arch/arm/mach-s5p64x0/cpu.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-s5p64x0/cpu.c
   2 *
   3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
   4 *              http://www.samsung.com
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9*/
  10
  11#include <linux/kernel.h>
  12#include <linux/types.h>
  13#include <linux/interrupt.h>
  14#include <linux/list.h>
  15#include <linux/timer.h>
  16#include <linux/init.h>
  17#include <linux/clk.h>
  18#include <linux/io.h>
  19#include <linux/sysdev.h>
  20#include <linux/serial_core.h>
  21#include <linux/platform_device.h>
  22#include <linux/sched.h>
  23
  24#include <asm/mach/arch.h>
  25#include <asm/mach/map.h>
  26#include <asm/mach/irq.h>
  27#include <asm/proc-fns.h>
  28#include <asm/irq.h>
  29
  30#include <mach/hardware.h>
  31#include <mach/map.h>
  32#include <mach/regs-clock.h>
  33
  34#include <plat/regs-serial.h>
  35#include <plat/cpu.h>
  36#include <plat/devs.h>
  37#include <plat/clock.h>
  38#include <plat/s5p6440.h>
  39#include <plat/s5p6450.h>
  40#include <plat/adc-core.h>
  41
  42/* Initial IO mappings */
  43
  44static struct map_desc s5p64x0_iodesc[] __initdata = {
  45        {
  46                .virtual        = (unsigned long)S5P_VA_GPIO,
  47                .pfn            = __phys_to_pfn(S5P64X0_PA_GPIO),
  48                .length         = SZ_4K,
  49                .type           = MT_DEVICE,
  50        }, {
  51                .virtual        = (unsigned long)VA_VIC0,
  52                .pfn            = __phys_to_pfn(S5P64X0_PA_VIC0),
  53                .length         = SZ_16K,
  54                .type           = MT_DEVICE,
  55        }, {
  56                .virtual        = (unsigned long)VA_VIC1,
  57                .pfn            = __phys_to_pfn(S5P64X0_PA_VIC1),
  58                .length         = SZ_16K,
  59                .type           = MT_DEVICE,
  60        },
  61};
  62
  63static struct map_desc s5p6440_iodesc[] __initdata = {
  64        {
  65                .virtual        = (unsigned long)S3C_VA_UART,
  66                .pfn            = __phys_to_pfn(S5P6440_PA_UART(0)),
  67                .length         = SZ_4K,
  68                .type           = MT_DEVICE,
  69        },
  70};
  71
  72static struct map_desc s5p6450_iodesc[] __initdata = {
  73        {
  74                .virtual        = (unsigned long)S3C_VA_UART,
  75                .pfn            = __phys_to_pfn(S5P6450_PA_UART(0)),
  76                .length         = SZ_512K,
  77                .type           = MT_DEVICE,
  78        }, {
  79                .virtual        = (unsigned long)S3C_VA_UART + SZ_512K,
  80                .pfn            = __phys_to_pfn(S5P6450_PA_UART(5)),
  81                .length         = SZ_4K,
  82                .type           = MT_DEVICE,
  83        },
  84};
  85
  86static void s5p64x0_idle(void)
  87{
  88        unsigned long val;
  89
  90        if (!need_resched()) {
  91                val = __raw_readl(S5P64X0_PWR_CFG);
  92                val &= ~(0x3 << 5);
  93                val |= (0x1 << 5);
  94                __raw_writel(val, S5P64X0_PWR_CFG);
  95
  96                cpu_do_idle();
  97        }
  98        local_irq_enable();
  99}
 100
 101/*
 102 * s5p64x0_map_io
 103 *
 104 * register the standard CPU IO areas
 105 */
 106
 107void __init s5p6440_map_io(void)
 108{
 109        /* initialize any device information early */
 110        s3c_adc_setname("s3c64xx-adc");
 111
 112        iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
 113        iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
 114}
 115
 116void __init s5p6450_map_io(void)
 117{
 118        /* initialize any device information early */
 119        s3c_adc_setname("s3c64xx-adc");
 120
 121        iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
 122        iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6440_iodesc));
 123}
 124
 125/*
 126 * s5p64x0_init_clocks
 127 *
 128 * register and setup the CPU clocks
 129 */
 130
 131void __init s5p6440_init_clocks(int xtal)
 132{
 133        printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
 134
 135        s3c24xx_register_baseclocks(xtal);
 136        s5p_register_clocks(xtal);
 137        s5p6440_register_clocks();
 138        s5p6440_setup_clocks();
 139}
 140
 141void __init s5p6450_init_clocks(int xtal)
 142{
 143        printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
 144
 145        s3c24xx_register_baseclocks(xtal);
 146        s5p_register_clocks(xtal);
 147        s5p6450_register_clocks();
 148        s5p6450_setup_clocks();
 149}
 150
 151/*
 152 * s5p64x0_init_irq
 153 *
 154 * register the CPU interrupts
 155 */
 156
 157void __init s5p6440_init_irq(void)
 158{
 159        /* S5P6440 supports 2 VIC */
 160        u32 vic[2];
 161
 162        /*
 163         * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
 164         * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
 165         */
 166        vic[0] = 0xff800ae7;
 167        vic[1] = 0xffbf23e5;
 168
 169        s5p_init_irq(vic, ARRAY_SIZE(vic));
 170}
 171
 172void __init s5p6450_init_irq(void)
 173{
 174        /* S5P6450 supports only 2 VIC */
 175        u32 vic[2];
 176
 177        /*
 178         * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
 179         * VIC1 is missing IRQ VIC1[12, 14, 23]
 180         */
 181        vic[0] = 0xff9f1fff;
 182        vic[1] = 0xff7fafff;
 183
 184        s5p_init_irq(vic, ARRAY_SIZE(vic));
 185}
 186
 187struct sysdev_class s5p64x0_sysclass = {
 188        .name   = "s5p64x0-core",
 189};
 190
 191static struct sys_device s5p64x0_sysdev = {
 192        .cls    = &s5p64x0_sysclass,
 193};
 194
 195static int __init s5p64x0_core_init(void)
 196{
 197        return sysdev_class_register(&s5p64x0_sysclass);
 198}
 199core_initcall(s5p64x0_core_init);
 200
 201int __init s5p64x0_init(void)
 202{
 203        printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
 204
 205        /* set idle function */
 206        pm_idle = s5p64x0_idle;
 207
 208        return sysdev_register(&s5p64x0_sysdev);
 209}
 210