linux/arch/arm/mach-at91/at91sam9261.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-at91/at91sam9261.c
   3 *
   4 *  Copyright (C) 2005 SAN People
   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 as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 */
  12
  13#include <linux/module.h>
  14
  15#include <asm/proc-fns.h>
  16#include <asm/irq.h>
  17#include <asm/mach/arch.h>
  18#include <asm/mach/map.h>
  19#include <asm/system_misc.h>
  20#include <mach/cpu.h>
  21#include <mach/at91sam9261.h>
  22#include <mach/at91_aic.h>
  23#include <mach/at91_pmc.h>
  24#include <mach/at91_rstc.h>
  25
  26#include "soc.h"
  27#include "generic.h"
  28#include "clock.h"
  29#include "sam9_smc.h"
  30
  31/* --------------------------------------------------------------------
  32 *  Clocks
  33 * -------------------------------------------------------------------- */
  34
  35/*
  36 * The peripheral clocks.
  37 */
  38static struct clk pioA_clk = {
  39        .name           = "pioA_clk",
  40        .pmc_mask       = 1 << AT91SAM9261_ID_PIOA,
  41        .type           = CLK_TYPE_PERIPHERAL,
  42};
  43static struct clk pioB_clk = {
  44        .name           = "pioB_clk",
  45        .pmc_mask       = 1 << AT91SAM9261_ID_PIOB,
  46        .type           = CLK_TYPE_PERIPHERAL,
  47};
  48static struct clk pioC_clk = {
  49        .name           = "pioC_clk",
  50        .pmc_mask       = 1 << AT91SAM9261_ID_PIOC,
  51        .type           = CLK_TYPE_PERIPHERAL,
  52};
  53static struct clk usart0_clk = {
  54        .name           = "usart0_clk",
  55        .pmc_mask       = 1 << AT91SAM9261_ID_US0,
  56        .type           = CLK_TYPE_PERIPHERAL,
  57};
  58static struct clk usart1_clk = {
  59        .name           = "usart1_clk",
  60        .pmc_mask       = 1 << AT91SAM9261_ID_US1,
  61        .type           = CLK_TYPE_PERIPHERAL,
  62};
  63static struct clk usart2_clk = {
  64        .name           = "usart2_clk",
  65        .pmc_mask       = 1 << AT91SAM9261_ID_US2,
  66        .type           = CLK_TYPE_PERIPHERAL,
  67};
  68static struct clk mmc_clk = {
  69        .name           = "mci_clk",
  70        .pmc_mask       = 1 << AT91SAM9261_ID_MCI,
  71        .type           = CLK_TYPE_PERIPHERAL,
  72};
  73static struct clk udc_clk = {
  74        .name           = "udc_clk",
  75        .pmc_mask       = 1 << AT91SAM9261_ID_UDP,
  76        .type           = CLK_TYPE_PERIPHERAL,
  77};
  78static struct clk twi_clk = {
  79        .name           = "twi_clk",
  80        .pmc_mask       = 1 << AT91SAM9261_ID_TWI,
  81        .type           = CLK_TYPE_PERIPHERAL,
  82};
  83static struct clk spi0_clk = {
  84        .name           = "spi0_clk",
  85        .pmc_mask       = 1 << AT91SAM9261_ID_SPI0,
  86        .type           = CLK_TYPE_PERIPHERAL,
  87};
  88static struct clk spi1_clk = {
  89        .name           = "spi1_clk",
  90        .pmc_mask       = 1 << AT91SAM9261_ID_SPI1,
  91        .type           = CLK_TYPE_PERIPHERAL,
  92};
  93static struct clk ssc0_clk = {
  94        .name           = "ssc0_clk",
  95        .pmc_mask       = 1 << AT91SAM9261_ID_SSC0,
  96        .type           = CLK_TYPE_PERIPHERAL,
  97};
  98static struct clk ssc1_clk = {
  99        .name           = "ssc1_clk",
 100        .pmc_mask       = 1 << AT91SAM9261_ID_SSC1,
 101        .type           = CLK_TYPE_PERIPHERAL,
 102};
 103static struct clk ssc2_clk = {
 104        .name           = "ssc2_clk",
 105        .pmc_mask       = 1 << AT91SAM9261_ID_SSC2,
 106        .type           = CLK_TYPE_PERIPHERAL,
 107};
 108static struct clk tc0_clk = {
 109        .name           = "tc0_clk",
 110        .pmc_mask       = 1 << AT91SAM9261_ID_TC0,
 111        .type           = CLK_TYPE_PERIPHERAL,
 112};
 113static struct clk tc1_clk = {
 114        .name           = "tc1_clk",
 115        .pmc_mask       = 1 << AT91SAM9261_ID_TC1,
 116        .type           = CLK_TYPE_PERIPHERAL,
 117};
 118static struct clk tc2_clk = {
 119        .name           = "tc2_clk",
 120        .pmc_mask       = 1 << AT91SAM9261_ID_TC2,
 121        .type           = CLK_TYPE_PERIPHERAL,
 122};
 123static struct clk ohci_clk = {
 124        .name           = "ohci_clk",
 125        .pmc_mask       = 1 << AT91SAM9261_ID_UHP,
 126        .type           = CLK_TYPE_PERIPHERAL,
 127};
 128static struct clk lcdc_clk = {
 129        .name           = "lcdc_clk",
 130        .pmc_mask       = 1 << AT91SAM9261_ID_LCDC,
 131        .type           = CLK_TYPE_PERIPHERAL,
 132};
 133
 134/* HClocks */
 135static struct clk hck0 = {
 136        .name           = "hck0",
 137        .pmc_mask       = AT91_PMC_HCK0,
 138        .type           = CLK_TYPE_SYSTEM,
 139        .id             = 0,
 140};
 141static struct clk hck1 = {
 142        .name           = "hck1",
 143        .pmc_mask       = AT91_PMC_HCK1,
 144        .type           = CLK_TYPE_SYSTEM,
 145        .id             = 1,
 146};
 147
 148static struct clk *periph_clocks[] __initdata = {
 149        &pioA_clk,
 150        &pioB_clk,
 151        &pioC_clk,
 152        &usart0_clk,
 153        &usart1_clk,
 154        &usart2_clk,
 155        &mmc_clk,
 156        &udc_clk,
 157        &twi_clk,
 158        &spi0_clk,
 159        &spi1_clk,
 160        &ssc0_clk,
 161        &ssc1_clk,
 162        &ssc2_clk,
 163        &tc0_clk,
 164        &tc1_clk,
 165        &tc2_clk,
 166        &ohci_clk,
 167        &lcdc_clk,
 168        // irq0 .. irq2
 169};
 170
 171static struct clk_lookup periph_clocks_lookups[] = {
 172        CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
 173        CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
 174        CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
 175        CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
 176        CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
 177        CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
 178        CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
 179        CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
 180        CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0),
 181        CLKDEV_CON_ID("pioA", &pioA_clk),
 182        CLKDEV_CON_ID("pioB", &pioB_clk),
 183        CLKDEV_CON_ID("pioC", &pioC_clk),
 184};
 185
 186static struct clk_lookup usart_clocks_lookups[] = {
 187        CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
 188        CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
 189        CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
 190        CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
 191};
 192
 193/*
 194 * The four programmable clocks.
 195 * You must configure pin multiplexing to bring these signals out.
 196 */
 197static struct clk pck0 = {
 198        .name           = "pck0",
 199        .pmc_mask       = AT91_PMC_PCK0,
 200        .type           = CLK_TYPE_PROGRAMMABLE,
 201        .id             = 0,
 202};
 203static struct clk pck1 = {
 204        .name           = "pck1",
 205        .pmc_mask       = AT91_PMC_PCK1,
 206        .type           = CLK_TYPE_PROGRAMMABLE,
 207        .id             = 1,
 208};
 209static struct clk pck2 = {
 210        .name           = "pck2",
 211        .pmc_mask       = AT91_PMC_PCK2,
 212        .type           = CLK_TYPE_PROGRAMMABLE,
 213        .id             = 2,
 214};
 215static struct clk pck3 = {
 216        .name           = "pck3",
 217        .pmc_mask       = AT91_PMC_PCK3,
 218        .type           = CLK_TYPE_PROGRAMMABLE,
 219        .id             = 3,
 220};
 221
 222static void __init at91sam9261_register_clocks(void)
 223{
 224        int i;
 225
 226        for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 227                clk_register(periph_clocks[i]);
 228
 229        clkdev_add_table(periph_clocks_lookups,
 230                         ARRAY_SIZE(periph_clocks_lookups));
 231        clkdev_add_table(usart_clocks_lookups,
 232                         ARRAY_SIZE(usart_clocks_lookups));
 233
 234        clk_register(&pck0);
 235        clk_register(&pck1);
 236        clk_register(&pck2);
 237        clk_register(&pck3);
 238
 239        clk_register(&hck0);
 240        clk_register(&hck1);
 241}
 242
 243/* --------------------------------------------------------------------
 244 *  GPIO
 245 * -------------------------------------------------------------------- */
 246
 247static struct at91_gpio_bank at91sam9261_gpio[] __initdata = {
 248        {
 249                .id             = AT91SAM9261_ID_PIOA,
 250                .regbase        = AT91SAM9261_BASE_PIOA,
 251        }, {
 252                .id             = AT91SAM9261_ID_PIOB,
 253                .regbase        = AT91SAM9261_BASE_PIOB,
 254        }, {
 255                .id             = AT91SAM9261_ID_PIOC,
 256                .regbase        = AT91SAM9261_BASE_PIOC,
 257        }
 258};
 259
 260/* --------------------------------------------------------------------
 261 *  AT91SAM9261 processor initialization
 262 * -------------------------------------------------------------------- */
 263
 264static void __init at91sam9261_map_io(void)
 265{
 266        if (cpu_is_at91sam9g10())
 267                at91_init_sram(0, AT91SAM9G10_SRAM_BASE, AT91SAM9G10_SRAM_SIZE);
 268        else
 269                at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE);
 270}
 271
 272static void __init at91sam9261_ioremap_registers(void)
 273{
 274        at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
 275        at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
 276        at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512);
 277        at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
 278        at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
 279        at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX);
 280}
 281
 282static void __init at91sam9261_initialize(void)
 283{
 284        arm_pm_idle = at91sam9_idle;
 285        arm_pm_restart = at91sam9_alt_restart;
 286        at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
 287                        | (1 << AT91SAM9261_ID_IRQ2);
 288
 289        /* Register GPIO subsystem */
 290        at91_gpio_init(at91sam9261_gpio, 3);
 291}
 292
 293/* --------------------------------------------------------------------
 294 *  Interrupt initialization
 295 * -------------------------------------------------------------------- */
 296
 297/*
 298 * The default interrupt priority levels (0 = lowest, 7 = highest).
 299 */
 300static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
 301        7,      /* Advanced Interrupt Controller */
 302        7,      /* System Peripherals */
 303        1,      /* Parallel IO Controller A */
 304        1,      /* Parallel IO Controller B */
 305        1,      /* Parallel IO Controller C */
 306        0,
 307        5,      /* USART 0 */
 308        5,      /* USART 1 */
 309        5,      /* USART 2 */
 310        0,      /* Multimedia Card Interface */
 311        2,      /* USB Device Port */
 312        6,      /* Two-Wire Interface */
 313        5,      /* Serial Peripheral Interface 0 */
 314        5,      /* Serial Peripheral Interface 1 */
 315        4,      /* Serial Synchronous Controller 0 */
 316        4,      /* Serial Synchronous Controller 1 */
 317        4,      /* Serial Synchronous Controller 2 */
 318        0,      /* Timer Counter 0 */
 319        0,      /* Timer Counter 1 */
 320        0,      /* Timer Counter 2 */
 321        2,      /* USB Host port */
 322        3,      /* LCD Controller */
 323        0,
 324        0,
 325        0,
 326        0,
 327        0,
 328        0,
 329        0,
 330        0,      /* Advanced Interrupt Controller */
 331        0,      /* Advanced Interrupt Controller */
 332        0,      /* Advanced Interrupt Controller */
 333};
 334
 335struct at91_init_soc __initdata at91sam9261_soc = {
 336        .map_io = at91sam9261_map_io,
 337        .default_irq_priority = at91sam9261_default_irq_priority,
 338        .ioremap_registers = at91sam9261_ioremap_registers,
 339        .register_clocks = at91sam9261_register_clocks,
 340        .init = at91sam9261_initialize,
 341};
 342