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        INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
 212};
 213
 214static struct clk_lookup pxa25x_hwuart_clkreg =
 215        INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL);
 216
 217#ifdef CONFIG_PM
 218
 219#define SAVE(x)         sleep_save[SLEEP_SAVE_##x] = x
 220#define RESTORE(x)      x = sleep_save[SLEEP_SAVE_##x]
 221
 222/*
 223 * List of global PXA peripheral registers to preserve.
 224 * More ones like CP and general purpose register values are preserved
 225 * with the stack pointer in sleep.S.
 226 */
 227enum {
 228        SLEEP_SAVE_PSTR,
 229        SLEEP_SAVE_COUNT
 230};
 231
 232
 233static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
 234{
 235        SAVE(PSTR);
 236}
 237
 238static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
 239{
 240        RESTORE(PSTR);
 241}
 242
 243static void pxa25x_cpu_pm_enter(suspend_state_t state)
 244{
 245        /* Clear reset status */
 246        RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
 247
 248        switch (state) {
 249        case PM_SUSPEND_MEM:
 250                cpu_suspend(PWRMODE_SLEEP, pxa25x_finish_suspend);
 251                break;
 252        }
 253}
 254
 255static int pxa25x_cpu_pm_prepare(void)
 256{
 257        /* set resume return address */
 258        PSPR = virt_to_phys(cpu_resume);
 259        return 0;
 260}
 261
 262static void pxa25x_cpu_pm_finish(void)
 263{
 264        /* ensure not to come back here if it wasn't intended */
 265        PSPR = 0;
 266}
 267
 268static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
 269        .save_count     = SLEEP_SAVE_COUNT,
 270        .valid          = suspend_valid_only_mem,
 271        .save           = pxa25x_cpu_pm_save,
 272        .restore        = pxa25x_cpu_pm_restore,
 273        .enter          = pxa25x_cpu_pm_enter,
 274        .prepare        = pxa25x_cpu_pm_prepare,
 275        .finish         = pxa25x_cpu_pm_finish,
 276};
 277
 278static void __init pxa25x_init_pm(void)
 279{
 280        pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
 281}
 282#else
 283static inline void pxa25x_init_pm(void) {}
 284#endif
 285
 286/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
 287 */
 288
 289static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
 290{
 291        int gpio = pxa_irq_to_gpio(d->irq);
 292        uint32_t mask = 0;
 293
 294        if (gpio >= 0 && gpio < 85)
 295                return gpio_set_wake(gpio, on);
 296
 297        if (d->irq == IRQ_RTCAlrm) {
 298                mask = PWER_RTC;
 299                goto set_pwer;
 300        }
 301
 302        return -EINVAL;
 303
 304set_pwer:
 305        if (on)
 306                PWER |= mask;
 307        else
 308                PWER &=~mask;
 309
 310        return 0;
 311}
 312
 313void __init pxa25x_init_irq(void)
 314{
 315        pxa_init_irq(32, pxa25x_set_wake);
 316}
 317
 318#ifdef CONFIG_CPU_PXA26x
 319void __init pxa26x_init_irq(void)
 320{
 321        pxa_init_irq(32, pxa25x_set_wake);
 322}
 323#endif
 324
 325static struct map_desc pxa25x_io_desc[] __initdata = {
 326        {       /* Mem Ctl */
 327                .virtual        = (unsigned long)SMEMC_VIRT,
 328                .pfn            = __phys_to_pfn(PXA2XX_SMEMC_BASE),
 329                .length         = 0x00200000,
 330                .type           = MT_DEVICE
 331        },
 332};
 333
 334void __init pxa25x_map_io(void)
 335{
 336        pxa_map_io();
 337        iotable_init(ARRAY_AND_SIZE(pxa25x_io_desc));
 338        pxa25x_get_clk_frequency_khz(1);
 339}
 340
 341static struct platform_device *pxa25x_devices[] __initdata = {
 342        &pxa25x_device_udc,
 343        &pxa_device_pmu,
 344        &pxa_device_i2s,
 345        &sa1100_device_rtc,
 346        &pxa25x_device_ssp,
 347        &pxa25x_device_nssp,
 348        &pxa25x_device_assp,
 349        &pxa25x_device_pwm0,
 350        &pxa25x_device_pwm1,
 351        &pxa_device_asoc_platform,
 352};
 353
 354static int __init pxa25x_init(void)
 355{
 356        int ret = 0;
 357
 358        if (cpu_is_pxa25x()) {
 359
 360                reset_status = RCSR;
 361
 362                clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
 363
 364                if ((ret = pxa_init_dma(IRQ_DMA, 16)))
 365                        return ret;
 366
 367                pxa25x_init_pm();
 368
 369                register_syscore_ops(&pxa_irq_syscore_ops);
 370                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
 371                register_syscore_ops(&pxa2xx_clock_syscore_ops);
 372
 373                ret = platform_add_devices(pxa25x_devices,
 374                                           ARRAY_SIZE(pxa25x_devices));
 375                if (ret)
 376                        return ret;
 377        }
 378
 379        /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
 380        if (cpu_is_pxa255())
 381                clkdev_add(&pxa25x_hwuart_clkreg);
 382
 383        return ret;
 384}
 385
 386postcore_initcall(pxa25x_init);
 387