linux/arch/arm/mach-at91/at91sam9g45.c
<<
>>
Prefs
   1/*
   2 *  Chip-specific setup code for the AT91SAM9G45 family
   3 *
   4 *  Copyright (C) 2009 Atmel Corporation.
   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#include <linux/pm.h>
  15
  16#include <asm/irq.h>
  17#include <asm/mach/arch.h>
  18#include <asm/mach/map.h>
  19#include <mach/at91sam9g45.h>
  20#include <mach/at91_pmc.h>
  21#include <mach/at91_rstc.h>
  22#include <mach/at91_shdwc.h>
  23
  24#include "generic.h"
  25#include "clock.h"
  26
  27static struct map_desc at91sam9g45_io_desc[] __initdata = {
  28        {
  29                .virtual        = AT91_VA_BASE_SYS,
  30                .pfn            = __phys_to_pfn(AT91_BASE_SYS),
  31                .length         = SZ_16K,
  32                .type           = MT_DEVICE,
  33        }, {
  34                .virtual        = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE,
  35                .pfn            = __phys_to_pfn(AT91SAM9G45_SRAM_BASE),
  36                .length         = AT91SAM9G45_SRAM_SIZE,
  37                .type           = MT_DEVICE,
  38        }
  39};
  40
  41/* --------------------------------------------------------------------
  42 *  Clocks
  43 * -------------------------------------------------------------------- */
  44
  45/*
  46 * The peripheral clocks.
  47 */
  48static struct clk pioA_clk = {
  49        .name           = "pioA_clk",
  50        .pmc_mask       = 1 << AT91SAM9G45_ID_PIOA,
  51        .type           = CLK_TYPE_PERIPHERAL,
  52};
  53static struct clk pioB_clk = {
  54        .name           = "pioB_clk",
  55        .pmc_mask       = 1 << AT91SAM9G45_ID_PIOB,
  56        .type           = CLK_TYPE_PERIPHERAL,
  57};
  58static struct clk pioC_clk = {
  59        .name           = "pioC_clk",
  60        .pmc_mask       = 1 << AT91SAM9G45_ID_PIOC,
  61        .type           = CLK_TYPE_PERIPHERAL,
  62};
  63static struct clk pioDE_clk = {
  64        .name           = "pioDE_clk",
  65        .pmc_mask       = 1 << AT91SAM9G45_ID_PIODE,
  66        .type           = CLK_TYPE_PERIPHERAL,
  67};
  68static struct clk usart0_clk = {
  69        .name           = "usart0_clk",
  70        .pmc_mask       = 1 << AT91SAM9G45_ID_US0,
  71        .type           = CLK_TYPE_PERIPHERAL,
  72};
  73static struct clk usart1_clk = {
  74        .name           = "usart1_clk",
  75        .pmc_mask       = 1 << AT91SAM9G45_ID_US1,
  76        .type           = CLK_TYPE_PERIPHERAL,
  77};
  78static struct clk usart2_clk = {
  79        .name           = "usart2_clk",
  80        .pmc_mask       = 1 << AT91SAM9G45_ID_US2,
  81        .type           = CLK_TYPE_PERIPHERAL,
  82};
  83static struct clk usart3_clk = {
  84        .name           = "usart3_clk",
  85        .pmc_mask       = 1 << AT91SAM9G45_ID_US3,
  86        .type           = CLK_TYPE_PERIPHERAL,
  87};
  88static struct clk mmc0_clk = {
  89        .name           = "mci0_clk",
  90        .pmc_mask       = 1 << AT91SAM9G45_ID_MCI0,
  91        .type           = CLK_TYPE_PERIPHERAL,
  92};
  93static struct clk twi0_clk = {
  94        .name           = "twi0_clk",
  95        .pmc_mask       = 1 << AT91SAM9G45_ID_TWI0,
  96        .type           = CLK_TYPE_PERIPHERAL,
  97};
  98static struct clk twi1_clk = {
  99        .name           = "twi1_clk",
 100        .pmc_mask       = 1 << AT91SAM9G45_ID_TWI1,
 101        .type           = CLK_TYPE_PERIPHERAL,
 102};
 103static struct clk spi0_clk = {
 104        .name           = "spi0_clk",
 105        .pmc_mask       = 1 << AT91SAM9G45_ID_SPI0,
 106        .type           = CLK_TYPE_PERIPHERAL,
 107};
 108static struct clk spi1_clk = {
 109        .name           = "spi1_clk",
 110        .pmc_mask       = 1 << AT91SAM9G45_ID_SPI1,
 111        .type           = CLK_TYPE_PERIPHERAL,
 112};
 113static struct clk ssc0_clk = {
 114        .name           = "ssc0_clk",
 115        .pmc_mask       = 1 << AT91SAM9G45_ID_SSC0,
 116        .type           = CLK_TYPE_PERIPHERAL,
 117};
 118static struct clk ssc1_clk = {
 119        .name           = "ssc1_clk",
 120        .pmc_mask       = 1 << AT91SAM9G45_ID_SSC1,
 121        .type           = CLK_TYPE_PERIPHERAL,
 122};
 123static struct clk tcb_clk = {
 124        .name           = "tcb_clk",
 125        .pmc_mask       = 1 << AT91SAM9G45_ID_TCB,
 126        .type           = CLK_TYPE_PERIPHERAL,
 127};
 128static struct clk pwm_clk = {
 129        .name           = "pwm_clk",
 130        .pmc_mask       = 1 << AT91SAM9G45_ID_PWMC,
 131        .type           = CLK_TYPE_PERIPHERAL,
 132};
 133static struct clk tsc_clk = {
 134        .name           = "tsc_clk",
 135        .pmc_mask       = 1 << AT91SAM9G45_ID_TSC,
 136        .type           = CLK_TYPE_PERIPHERAL,
 137};
 138static struct clk dma_clk = {
 139        .name           = "dma_clk",
 140        .pmc_mask       = 1 << AT91SAM9G45_ID_DMA,
 141        .type           = CLK_TYPE_PERIPHERAL,
 142};
 143static struct clk uhphs_clk = {
 144        .name           = "uhphs_clk",
 145        .pmc_mask       = 1 << AT91SAM9G45_ID_UHPHS,
 146        .type           = CLK_TYPE_PERIPHERAL,
 147};
 148static struct clk lcdc_clk = {
 149        .name           = "lcdc_clk",
 150        .pmc_mask       = 1 << AT91SAM9G45_ID_LCDC,
 151        .type           = CLK_TYPE_PERIPHERAL,
 152};
 153static struct clk ac97_clk = {
 154        .name           = "ac97_clk",
 155        .pmc_mask       = 1 << AT91SAM9G45_ID_AC97C,
 156        .type           = CLK_TYPE_PERIPHERAL,
 157};
 158static struct clk macb_clk = {
 159        .name           = "macb_clk",
 160        .pmc_mask       = 1 << AT91SAM9G45_ID_EMAC,
 161        .type           = CLK_TYPE_PERIPHERAL,
 162};
 163static struct clk isi_clk = {
 164        .name           = "isi_clk",
 165        .pmc_mask       = 1 << AT91SAM9G45_ID_ISI,
 166        .type           = CLK_TYPE_PERIPHERAL,
 167};
 168static struct clk udphs_clk = {
 169        .name           = "udphs_clk",
 170        .pmc_mask       = 1 << AT91SAM9G45_ID_UDPHS,
 171        .type           = CLK_TYPE_PERIPHERAL,
 172};
 173static struct clk mmc1_clk = {
 174        .name           = "mci1_clk",
 175        .pmc_mask       = 1 << AT91SAM9G45_ID_MCI1,
 176        .type           = CLK_TYPE_PERIPHERAL,
 177};
 178
 179/* One additional fake clock for ohci */
 180static struct clk ohci_clk = {
 181        .name           = "ohci_clk",
 182        .pmc_mask       = 0,
 183        .type           = CLK_TYPE_PERIPHERAL,
 184        .parent         = &uhphs_clk,
 185};
 186
 187static struct clk *periph_clocks[] __initdata = {
 188        &pioA_clk,
 189        &pioB_clk,
 190        &pioC_clk,
 191        &pioDE_clk,
 192        &usart0_clk,
 193        &usart1_clk,
 194        &usart2_clk,
 195        &usart3_clk,
 196        &mmc0_clk,
 197        &twi0_clk,
 198        &twi1_clk,
 199        &spi0_clk,
 200        &spi1_clk,
 201        &ssc0_clk,
 202        &ssc1_clk,
 203        &tcb_clk,
 204        &pwm_clk,
 205        &tsc_clk,
 206        &dma_clk,
 207        &uhphs_clk,
 208        &lcdc_clk,
 209        &ac97_clk,
 210        &macb_clk,
 211        &isi_clk,
 212        &udphs_clk,
 213        &mmc1_clk,
 214        // irq0
 215        &ohci_clk,
 216};
 217
 218/*
 219 * The two programmable clocks.
 220 * You must configure pin multiplexing to bring these signals out.
 221 */
 222static struct clk pck0 = {
 223        .name           = "pck0",
 224        .pmc_mask       = AT91_PMC_PCK0,
 225        .type           = CLK_TYPE_PROGRAMMABLE,
 226        .id             = 0,
 227};
 228static struct clk pck1 = {
 229        .name           = "pck1",
 230        .pmc_mask       = AT91_PMC_PCK1,
 231        .type           = CLK_TYPE_PROGRAMMABLE,
 232        .id             = 1,
 233};
 234
 235static void __init at91sam9g45_register_clocks(void)
 236{
 237        int i;
 238
 239        for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 240                clk_register(periph_clocks[i]);
 241
 242        clk_register(&pck0);
 243        clk_register(&pck1);
 244}
 245
 246/* --------------------------------------------------------------------
 247 *  GPIO
 248 * -------------------------------------------------------------------- */
 249
 250static struct at91_gpio_bank at91sam9g45_gpio[] = {
 251        {
 252                .id             = AT91SAM9G45_ID_PIOA,
 253                .offset         = AT91_PIOA,
 254                .clock          = &pioA_clk,
 255        }, {
 256                .id             = AT91SAM9G45_ID_PIOB,
 257                .offset         = AT91_PIOB,
 258                .clock          = &pioB_clk,
 259        }, {
 260                .id             = AT91SAM9G45_ID_PIOC,
 261                .offset         = AT91_PIOC,
 262                .clock          = &pioC_clk,
 263        }, {
 264                .id             = AT91SAM9G45_ID_PIODE,
 265                .offset         = AT91_PIOD,
 266                .clock          = &pioDE_clk,
 267        }, {
 268                .id             = AT91SAM9G45_ID_PIODE,
 269                .offset         = AT91_PIOE,
 270                .clock          = &pioDE_clk,
 271        }
 272};
 273
 274static void at91sam9g45_reset(void)
 275{
 276        at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
 277}
 278
 279static void at91sam9g45_poweroff(void)
 280{
 281        at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
 282}
 283
 284
 285/* --------------------------------------------------------------------
 286 *  AT91SAM9G45 processor initialization
 287 * -------------------------------------------------------------------- */
 288
 289void __init at91sam9g45_initialize(unsigned long main_clock)
 290{
 291        /* Map peripherals */
 292        iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
 293
 294        at91_arch_reset = at91sam9g45_reset;
 295        pm_power_off = at91sam9g45_poweroff;
 296        at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
 297
 298        /* Init clock subsystem */
 299        at91_clock_init(main_clock);
 300
 301        /* Register the processor-specific clocks */
 302        at91sam9g45_register_clocks();
 303
 304        /* Register GPIO subsystem */
 305        at91_gpio_init(at91sam9g45_gpio, 5);
 306}
 307
 308/* --------------------------------------------------------------------
 309 *  Interrupt initialization
 310 * -------------------------------------------------------------------- */
 311
 312/*
 313 * The default interrupt priority levels (0 = lowest, 7 = highest).
 314 */
 315static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
 316        7,      /* Advanced Interrupt Controller (FIQ) */
 317        7,      /* System Peripherals */
 318        1,      /* Parallel IO Controller A */
 319        1,      /* Parallel IO Controller B */
 320        1,      /* Parallel IO Controller C */
 321        1,      /* Parallel IO Controller D and E */
 322        0,
 323        5,      /* USART 0 */
 324        5,      /* USART 1 */
 325        5,      /* USART 2 */
 326        5,      /* USART 3 */
 327        0,      /* Multimedia Card Interface 0 */
 328        6,      /* Two-Wire Interface 0 */
 329        6,      /* Two-Wire Interface 1 */
 330        5,      /* Serial Peripheral Interface 0 */
 331        5,      /* Serial Peripheral Interface 1 */
 332        4,      /* Serial Synchronous Controller 0 */
 333        4,      /* Serial Synchronous Controller 1 */
 334        0,      /* Timer Counter 0, 1, 2, 3, 4 and 5 */
 335        0,      /* Pulse Width Modulation Controller */
 336        0,      /* Touch Screen Controller */
 337        0,      /* DMA Controller */
 338        2,      /* USB Host High Speed port */
 339        3,      /* LDC Controller */
 340        5,      /* AC97 Controller */
 341        3,      /* Ethernet */
 342        0,      /* Image Sensor Interface */
 343        2,      /* USB Device High speed port */
 344        0,
 345        0,      /* Multimedia Card Interface 1 */
 346        0,
 347        0,      /* Advanced Interrupt Controller (IRQ0) */
 348};
 349
 350void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS])
 351{
 352        if (!priority)
 353                priority = at91sam9g45_default_irq_priority;
 354
 355        /* Initialize the AIC interrupt controller */
 356        at91_aic_init(priority);
 357
 358        /* Enable GPIO interrupts */
 359        at91_gpio_irq_setup();
 360}
 361