linux/arch/arm/mach-pxa/pxa25x.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-pxa/pxa25x.c
   3 *
   4 *  Author:     Nicolas Pitre
   5 *  Created:    Jun 15, 2001
   6 *  Copyright:  MontaVista Software Inc.
   7 *
   8 * Code specific to PXA21x/25x/26x variants.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 *
  14 * Since this file should be linked before any other machine specific file,
  15 * the __initcall() here will be executed first.  This serves as default
  16 * initialization stuff for PXA machines which can be overridden later if
  17 * need be.
  18 */
  19#include <linux/gpio.h>
  20#include <linux/gpio-pxa.h>
  21#include <linux/module.h>
  22#include <linux/kernel.h>
  23#include <linux/init.h>
  24#include <linux/platform_device.h>
  25#include <linux/suspend.h>
  26#include <linux/syscore_ops.h>
  27#include <linux/irq.h>
  28
  29#include <asm/mach/map.h>
  30#include <asm/suspend.h>
  31#include <mach/hardware.h>
  32#include <mach/irqs.h>
  33#include <mach/pxa25x.h>
  34#include <mach/reset.h>
  35#include <mach/pm.h>
  36#include <mach/dma.h>
  37#include <mach/smemc.h>
  38
  39#include "generic.h"
  40#include "devices.h"
  41#include "clock.h"
  42
  43/*
  44 * Various clock factors driven by the CCCR register.
  45 */
  46
  47/* Crystal Frequency to Memory Frequency Multiplier (L) */
  48static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
  49
  50/* Memory Frequency to Run Mode Frequency Multiplier (M) */
  51static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
  52
  53/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
  54/* Note: we store the value N * 2 here. */
  55static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
  56
  57/* Crystal clock */
  58#define BASE_CLK        3686400
  59
  60/*
  61 * Get the clock frequency as reflected by CCCR and the turbo flag.
  62 * We assume these values have been applied via a fcs.
  63 * If info is not 0 we also display the current settings.
  64 */
  65unsigned int pxa25x_get_clk_frequency_khz(int info)
  66{
  67        unsigned long cccr, turbo;
  68        unsigned int l, L, m, M, n2, N;
  69
  70        cccr = CCCR;
  71        asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
  72
  73        l  =  L_clk_mult[(cccr >> 0) & 0x1f];
  74        m  =  M_clk_mult[(cccr >> 5) & 0x03];
  75        n2 = N2_clk_mult[(cccr >> 7) & 0x07];
  76
  77        L = l * BASE_CLK;
  78        M = m * L;
  79        N = n2 * M / 2;
  80
  81        if(info)
  82        {
  83                L += 5000;
  84                printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
  85                        L / 1000000, (L % 1000000) / 10000, l );
  86                M += 5000;
  87                printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
  88                        M / 1000000, (M % 1000000) / 10000, m );
  89                N += 5000;
  90                printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
  91                        N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
  92                        (turbo & 1) ? "" : "in" );
  93        }
  94
  95        return (turbo & 1) ? (N/1000) : (M/1000);
  96}
  97
  98static unsigned long clk_pxa25x_mem_getrate(struct clk *clk)
  99{
 100        return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK;
 101}
 102
 103static const struct clkops clk_pxa25x_mem_ops = {
 104        .enable         = clk_dummy_enable,
 105        .disable        = clk_dummy_disable,
 106        .getrate        = clk_pxa25x_mem_getrate,
 107};
 108
 109static const struct clkops clk_pxa25x_lcd_ops = {
 110        .enable         = clk_pxa2xx_cken_enable,
 111        .disable        = clk_pxa2xx_cken_disable,
 112        .getrate        = clk_pxa25x_mem_getrate,
 113};
 114
 115static unsigned long gpio12_config_32k[] = {
 116        GPIO12_32KHz,
 117};
 118
 119static unsigned long gpio12_config_gpio[] = {
 120        GPIO12_GPIO,
 121};
 122
 123static void clk_gpio12_enable(struct clk *clk)
 124{
 125        pxa2xx_mfp_config(gpio12_config_32k, 1);
 126}
 127
 128static void clk_gpio12_disable(struct clk *clk)
 129{
 130        pxa2xx_mfp_config(gpio12_config_gpio, 1);
 131}
 132
 133static const struct clkops clk_pxa25x_gpio12_ops = {
 134        .enable         = clk_gpio12_enable,
 135        .disable        = clk_gpio12_disable,
 136};
 137
 138static unsigned long gpio11_config_3m6[] = {
 139        GPIO11_3_6MHz,
 140};
 141
 142static unsigned long gpio11_config_gpio[] = {
 143        GPIO11_GPIO,
 144};
 145
 146static void clk_gpio11_enable(struct clk *clk)
 147{
 148        pxa2xx_mfp_config(gpio11_config_3m6, 1);
 149}
 150
 151static void clk_gpio11_disable(struct clk *clk)
 152{
 153        pxa2xx_mfp_config(gpio11_config_gpio, 1);
 154}
 155
 156static const struct clkops clk_pxa25x_gpio11_ops = {
 157        .enable         = clk_gpio11_enable,
 158        .disable        = clk_gpio11_disable,
 159};
 160
 161/*
 162 * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz)
 163 * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
 164 * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
 165 */
 166
 167/*
 168 * PXA 2xx clock declarations.
 169 */
 170static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1);
 171static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1);
 172static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1);
 173static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1);
 174static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5);
 175static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0);
 176static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0);
 177static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0);
 178static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0);
 179static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0);
 180static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0);
 181static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0);
 182static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0);
 183static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0);
 184static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0);
 185
 186static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops);
 187static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0);
 188static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0);
 189static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0);
 190
 191static struct clk_lookup pxa25x_clkregs[] = {
 192        INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL),
 193        INIT_CLKREG(&clk_pxa25x_ffuart, "pxa2xx-uart.0", NULL),
 194        INIT_CLKREG(&clk_pxa25x_btuart, "pxa2xx-uart.1", NULL),
 195        INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-uart.2", NULL),
 196        INIT_CLKREG(&clk_pxa25x_usb, "pxa25x-udc", NULL),
 197        INIT_CLKREG(&clk_pxa25x_mmc, "pxa2xx-mci.0", NULL),
 198        INIT_CLKREG(&clk_pxa25x_i2c, "pxa2xx-i2c.0", NULL),
 199        INIT_CLKREG(&clk_pxa25x_ssp, "pxa25x-ssp.0", NULL),
 200        INIT_CLKREG(&clk_pxa25x_nssp, "pxa25x-nssp.1", NULL),
 201        INIT_CLKREG(&clk_pxa25x_assp, "pxa25x-nssp.2", NULL),
 202        INIT_CLKREG(&clk_pxa25x_pwm0, "pxa25x-pwm.0", NULL),
 203        INIT_CLKREG(&clk_pxa25x_pwm1, "pxa25x-pwm.1", NULL),
 204        INIT_CLKREG(&clk_pxa25x_i2s, "pxa2xx-i2s", NULL),
 205        INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-ir", "UARTCLK"),
 206        INIT_CLKREG(&clk_pxa25x_ficp, "pxa2xx-ir", "FICPCLK"),
 207        INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"),
 208        INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
 209        INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
 210        INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
 211#ifdef CONFIG_CPU_PXA26x
 212        INIT_CLKREG(&clk_dummy, "pxa26x-gpio", NULL),
 213#else
 214        INIT_CLKREG(&clk_dummy, "pxa25x-gpio", NULL),
 215#endif
 216        INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 217};
 218
 219static struct clk_lookup pxa25x_hwuart_clkreg =
 220        INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL);
 221
 222#ifdef CONFIG_PM
 223
 224#define SAVE(x)         sleep_save[SLEEP_SAVE_##x] = x
 225#define RESTORE(x)      x = sleep_save[SLEEP_SAVE_##x]
 226
 227/*
 228 * List of global PXA peripheral registers to preserve.
 229 * More ones like CP and general purpose register values are preserved
 230 * with the stack pointer in sleep.S.
 231 */
 232enum {
 233        SLEEP_SAVE_PSTR,
 234        SLEEP_SAVE_COUNT
 235};
 236
 237
 238static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
 239{
 240        SAVE(PSTR);
 241}
 242
 243static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
 244{
 245        RESTORE(PSTR);
 246}
 247
 248static void pxa25x_cpu_pm_enter(suspend_state_t state)
 249{
 250        /* Clear reset status */
 251        RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
 252
 253        switch (state) {
 254        case PM_SUSPEND_MEM:
 255                cpu_suspend(PWRMODE_SLEEP, pxa25x_finish_suspend);
 256                break;
 257        }
 258}
 259
 260static int pxa25x_cpu_pm_prepare(void)
 261{
 262        /* set resume return address */
 263        PSPR = virt_to_phys(cpu_resume);
 264        return 0;
 265}
 266
 267static void pxa25x_cpu_pm_finish(void)
 268{
 269        /* ensure not to come back here if it wasn't intended */
 270        PSPR = 0;
 271}
 272
 273static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
 274        .save_count     = SLEEP_SAVE_COUNT,
 275        .valid          = suspend_valid_only_mem,
 276        .save           = pxa25x_cpu_pm_save,
 277        .restore        = pxa25x_cpu_pm_restore,
 278        .enter          = pxa25x_cpu_pm_enter,
 279        .prepare        = pxa25x_cpu_pm_prepare,
 280        .finish         = pxa25x_cpu_pm_finish,
 281};
 282
 283static void __init pxa25x_init_pm(void)
 284{
 285        pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
 286}
 287#else
 288static inline void pxa25x_init_pm(void) {}
 289#endif
 290
 291/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
 292 */
 293
 294static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
 295{
 296        int gpio = pxa_irq_to_gpio(d->irq);
 297        uint32_t mask = 0;
 298
 299        if (gpio >= 0 && gpio < 85)
 300                return gpio_set_wake(gpio, on);
 301
 302        if (d->irq == IRQ_RTCAlrm) {
 303                mask = PWER_RTC;
 304                goto set_pwer;
 305        }
 306
 307        return -EINVAL;
 308
 309set_pwer:
 310        if (on)
 311                PWER |= mask;
 312        else
 313                PWER &=~mask;
 314
 315        return 0;
 316}
 317
 318void __init pxa25x_init_irq(void)
 319{
 320        pxa_init_irq(32, pxa25x_set_wake);
 321}
 322
 323#ifdef CONFIG_CPU_PXA26x
 324void __init pxa26x_init_irq(void)
 325{
 326        pxa_init_irq(32, pxa25x_set_wake);
 327}
 328#endif
 329
 330static struct map_desc pxa25x_io_desc[] __initdata = {
 331        {       /* Mem Ctl */
 332                .virtual        = (unsigned long)SMEMC_VIRT,
 333                .pfn            = __phys_to_pfn(PXA2XX_SMEMC_BASE),
 334                .length         = 0x00200000,
 335                .type           = MT_DEVICE
 336        },
 337};
 338
 339void __init pxa25x_map_io(void)
 340{
 341        pxa_map_io();
 342        iotable_init(ARRAY_AND_SIZE(pxa25x_io_desc));
 343        pxa25x_get_clk_frequency_khz(1);
 344}
 345
 346static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = {
 347        .irq_base       = PXA_GPIO_TO_IRQ(0),
 348        .gpio_set_wake  = gpio_set_wake,
 349};
 350
 351static struct platform_device *pxa25x_devices[] __initdata = {
 352        &pxa25x_device_udc,
 353        &pxa_device_pmu,
 354        &pxa_device_i2s,
 355        &sa1100_device_rtc,
 356        &pxa25x_device_ssp,
 357        &pxa25x_device_nssp,
 358        &pxa25x_device_assp,
 359        &pxa25x_device_pwm0,
 360        &pxa25x_device_pwm1,
 361        &pxa_device_asoc_platform,
 362};
 363
 364static int __init pxa25x_init(void)
 365{
 366        int ret = 0;
 367
 368        if (cpu_is_pxa25x()) {
 369
 370                reset_status = RCSR;
 371
 372                clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
 373
 374                if ((ret = pxa_init_dma(IRQ_DMA, 16)))
 375                        return ret;
 376
 377                pxa25x_init_pm();
 378
 379                register_syscore_ops(&pxa_irq_syscore_ops);
 380                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
 381                register_syscore_ops(&pxa2xx_clock_syscore_ops);
 382
 383                pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
 384                ret = platform_add_devices(pxa25x_devices,
 385                                           ARRAY_SIZE(pxa25x_devices));
 386                if (ret)
 387                        return ret;
 388        }
 389
 390        /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
 391        if (cpu_is_pxa255())
 392                clkdev_add(&pxa25x_hwuart_clkreg);
 393
 394        return ret;
 395}
 396
 397postcore_initcall(pxa25x_init);
 398