linux/arch/arm/mach-at91/at91sam9263.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-at91/at91sam9263.c
   3 *
   4 *  Copyright (C) 2007 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/at91sam9263.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 at91sam9263_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 - AT91SAM9263_SRAM0_SIZE,
  35                .pfn            = __phys_to_pfn(AT91SAM9263_SRAM0_BASE),
  36                .length         = AT91SAM9263_SRAM0_SIZE,
  37                .type           = MT_DEVICE,
  38        }, {
  39                .virtual        = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE,
  40                .pfn            = __phys_to_pfn(AT91SAM9263_SRAM1_BASE),
  41                .length         = AT91SAM9263_SRAM1_SIZE,
  42                .type           = MT_DEVICE,
  43        },
  44};
  45
  46/* --------------------------------------------------------------------
  47 *  Clocks
  48 * -------------------------------------------------------------------- */
  49
  50/*
  51 * The peripheral clocks.
  52 */
  53static struct clk pioA_clk = {
  54        .name           = "pioA_clk",
  55        .pmc_mask       = 1 << AT91SAM9263_ID_PIOA,
  56        .type           = CLK_TYPE_PERIPHERAL,
  57};
  58static struct clk pioB_clk = {
  59        .name           = "pioB_clk",
  60        .pmc_mask       = 1 << AT91SAM9263_ID_PIOB,
  61        .type           = CLK_TYPE_PERIPHERAL,
  62};
  63static struct clk pioCDE_clk = {
  64        .name           = "pioCDE_clk",
  65        .pmc_mask       = 1 << AT91SAM9263_ID_PIOCDE,
  66        .type           = CLK_TYPE_PERIPHERAL,
  67};
  68static struct clk usart0_clk = {
  69        .name           = "usart0_clk",
  70        .pmc_mask       = 1 << AT91SAM9263_ID_US0,
  71        .type           = CLK_TYPE_PERIPHERAL,
  72};
  73static struct clk usart1_clk = {
  74        .name           = "usart1_clk",
  75        .pmc_mask       = 1 << AT91SAM9263_ID_US1,
  76        .type           = CLK_TYPE_PERIPHERAL,
  77};
  78static struct clk usart2_clk = {
  79        .name           = "usart2_clk",
  80        .pmc_mask       = 1 << AT91SAM9263_ID_US2,
  81        .type           = CLK_TYPE_PERIPHERAL,
  82};
  83static struct clk mmc0_clk = {
  84        .name           = "mci0_clk",
  85        .pmc_mask       = 1 << AT91SAM9263_ID_MCI0,
  86        .type           = CLK_TYPE_PERIPHERAL,
  87};
  88static struct clk mmc1_clk = {
  89        .name           = "mci1_clk",
  90        .pmc_mask       = 1 << AT91SAM9263_ID_MCI1,
  91        .type           = CLK_TYPE_PERIPHERAL,
  92};
  93static struct clk can_clk = {
  94        .name           = "can_clk",
  95        .pmc_mask       = 1 << AT91SAM9263_ID_CAN,
  96        .type           = CLK_TYPE_PERIPHERAL,
  97};
  98static struct clk twi_clk = {
  99        .name           = "twi_clk",
 100        .pmc_mask       = 1 << AT91SAM9263_ID_TWI,
 101        .type           = CLK_TYPE_PERIPHERAL,
 102};
 103static struct clk spi0_clk = {
 104        .name           = "spi0_clk",
 105        .pmc_mask       = 1 << AT91SAM9263_ID_SPI0,
 106        .type           = CLK_TYPE_PERIPHERAL,
 107};
 108static struct clk spi1_clk = {
 109        .name           = "spi1_clk",
 110        .pmc_mask       = 1 << AT91SAM9263_ID_SPI1,
 111        .type           = CLK_TYPE_PERIPHERAL,
 112};
 113static struct clk ssc0_clk = {
 114        .name           = "ssc0_clk",
 115        .pmc_mask       = 1 << AT91SAM9263_ID_SSC0,
 116        .type           = CLK_TYPE_PERIPHERAL,
 117};
 118static struct clk ssc1_clk = {
 119        .name           = "ssc1_clk",
 120        .pmc_mask       = 1 << AT91SAM9263_ID_SSC1,
 121        .type           = CLK_TYPE_PERIPHERAL,
 122};
 123static struct clk ac97_clk = {
 124        .name           = "ac97_clk",
 125        .pmc_mask       = 1 << AT91SAM9263_ID_AC97C,
 126        .type           = CLK_TYPE_PERIPHERAL,
 127};
 128static struct clk tcb_clk = {
 129        .name           = "tcb_clk",
 130        .pmc_mask       = 1 << AT91SAM9263_ID_TCB,
 131        .type           = CLK_TYPE_PERIPHERAL,
 132};
 133static struct clk pwm_clk = {
 134        .name           = "pwm_clk",
 135        .pmc_mask       = 1 << AT91SAM9263_ID_PWMC,
 136        .type           = CLK_TYPE_PERIPHERAL,
 137};
 138static struct clk macb_clk = {
 139        .name           = "macb_clk",
 140        .pmc_mask       = 1 << AT91SAM9263_ID_EMAC,
 141        .type           = CLK_TYPE_PERIPHERAL,
 142};
 143static struct clk dma_clk = {
 144        .name           = "dma_clk",
 145        .pmc_mask       = 1 << AT91SAM9263_ID_DMA,
 146        .type           = CLK_TYPE_PERIPHERAL,
 147};
 148static struct clk twodge_clk = {
 149        .name           = "2dge_clk",
 150        .pmc_mask       = 1 << AT91SAM9263_ID_2DGE,
 151        .type           = CLK_TYPE_PERIPHERAL,
 152};
 153static struct clk udc_clk = {
 154        .name           = "udc_clk",
 155        .pmc_mask       = 1 << AT91SAM9263_ID_UDP,
 156        .type           = CLK_TYPE_PERIPHERAL,
 157};
 158static struct clk isi_clk = {
 159        .name           = "isi_clk",
 160        .pmc_mask       = 1 << AT91SAM9263_ID_ISI,
 161        .type           = CLK_TYPE_PERIPHERAL,
 162};
 163static struct clk lcdc_clk = {
 164        .name           = "lcdc_clk",
 165        .pmc_mask       = 1 << AT91SAM9263_ID_LCDC,
 166        .type           = CLK_TYPE_PERIPHERAL,
 167};
 168static struct clk ohci_clk = {
 169        .name           = "ohci_clk",
 170        .pmc_mask       = 1 << AT91SAM9263_ID_UHP,
 171        .type           = CLK_TYPE_PERIPHERAL,
 172};
 173
 174static struct clk *periph_clocks[] __initdata = {
 175        &pioA_clk,
 176        &pioB_clk,
 177        &pioCDE_clk,
 178        &usart0_clk,
 179        &usart1_clk,
 180        &usart2_clk,
 181        &mmc0_clk,
 182        &mmc1_clk,
 183        &can_clk,
 184        &twi_clk,
 185        &spi0_clk,
 186        &spi1_clk,
 187        &ssc0_clk,
 188        &ssc1_clk,
 189        &ac97_clk,
 190        &tcb_clk,
 191        &pwm_clk,
 192        &macb_clk,
 193        &twodge_clk,
 194        &udc_clk,
 195        &isi_clk,
 196        &lcdc_clk,
 197        &dma_clk,
 198        &ohci_clk,
 199        // irq0 .. irq1
 200};
 201
 202/*
 203 * The four programmable clocks.
 204 * You must configure pin multiplexing to bring these signals out.
 205 */
 206static struct clk pck0 = {
 207        .name           = "pck0",
 208        .pmc_mask       = AT91_PMC_PCK0,
 209        .type           = CLK_TYPE_PROGRAMMABLE,
 210        .id             = 0,
 211};
 212static struct clk pck1 = {
 213        .name           = "pck1",
 214        .pmc_mask       = AT91_PMC_PCK1,
 215        .type           = CLK_TYPE_PROGRAMMABLE,
 216        .id             = 1,
 217};
 218static struct clk pck2 = {
 219        .name           = "pck2",
 220        .pmc_mask       = AT91_PMC_PCK2,
 221        .type           = CLK_TYPE_PROGRAMMABLE,
 222        .id             = 2,
 223};
 224static struct clk pck3 = {
 225        .name           = "pck3",
 226        .pmc_mask       = AT91_PMC_PCK3,
 227        .type           = CLK_TYPE_PROGRAMMABLE,
 228        .id             = 3,
 229};
 230
 231static void __init at91sam9263_register_clocks(void)
 232{
 233        int i;
 234
 235        for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 236                clk_register(periph_clocks[i]);
 237
 238        clk_register(&pck0);
 239        clk_register(&pck1);
 240        clk_register(&pck2);
 241        clk_register(&pck3);
 242}
 243
 244/* --------------------------------------------------------------------
 245 *  GPIO
 246 * -------------------------------------------------------------------- */
 247
 248static struct at91_gpio_bank at91sam9263_gpio[] = {
 249        {
 250                .id             = AT91SAM9263_ID_PIOA,
 251                .offset         = AT91_PIOA,
 252                .clock          = &pioA_clk,
 253        }, {
 254                .id             = AT91SAM9263_ID_PIOB,
 255                .offset         = AT91_PIOB,
 256                .clock          = &pioB_clk,
 257        }, {
 258                .id             = AT91SAM9263_ID_PIOCDE,
 259                .offset         = AT91_PIOC,
 260                .clock          = &pioCDE_clk,
 261        }, {
 262                .id             = AT91SAM9263_ID_PIOCDE,
 263                .offset         = AT91_PIOD,
 264                .clock          = &pioCDE_clk,
 265        }, {
 266                .id             = AT91SAM9263_ID_PIOCDE,
 267                .offset         = AT91_PIOE,
 268                .clock          = &pioCDE_clk,
 269        }
 270};
 271
 272static void at91sam9263_reset(void)
 273{
 274        at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
 275}
 276
 277static void at91sam9263_poweroff(void)
 278{
 279        at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
 280}
 281
 282
 283/* --------------------------------------------------------------------
 284 *  AT91SAM9263 processor initialization
 285 * -------------------------------------------------------------------- */
 286
 287void __init at91sam9263_initialize(unsigned long main_clock)
 288{
 289        /* Map peripherals */
 290        iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));
 291
 292        at91_arch_reset = at91sam9263_reset;
 293        pm_power_off = at91sam9263_poweroff;
 294        at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
 295
 296        /* Init clock subsystem */
 297        at91_clock_init(main_clock);
 298
 299        /* Register the processor-specific clocks */
 300        at91sam9263_register_clocks();
 301
 302        /* Register GPIO subsystem */
 303        at91_gpio_init(at91sam9263_gpio, 5);
 304}
 305
 306/* --------------------------------------------------------------------
 307 *  Interrupt initialization
 308 * -------------------------------------------------------------------- */
 309
 310/*
 311 * The default interrupt priority levels (0 = lowest, 7 = highest).
 312 */
 313static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
 314        7,      /* Advanced Interrupt Controller (FIQ) */
 315        7,      /* System Peripherals */
 316        1,      /* Parallel IO Controller A */
 317        1,      /* Parallel IO Controller B */
 318        1,      /* Parallel IO Controller C, D and E */
 319        0,
 320        0,
 321        5,      /* USART 0 */
 322        5,      /* USART 1 */
 323        5,      /* USART 2 */
 324        0,      /* Multimedia Card Interface 0 */
 325        0,      /* Multimedia Card Interface 1 */
 326        3,      /* CAN */
 327        6,      /* Two-Wire Interface */
 328        5,      /* Serial Peripheral Interface 0 */
 329        5,      /* Serial Peripheral Interface 1 */
 330        4,      /* Serial Synchronous Controller 0 */
 331        4,      /* Serial Synchronous Controller 1 */
 332        5,      /* AC97 Controller */
 333        0,      /* Timer Counter 0, 1 and 2 */
 334        0,      /* Pulse Width Modulation Controller */
 335        3,      /* Ethernet */
 336        0,
 337        0,      /* 2D Graphic Engine */
 338        2,      /* USB Device Port */
 339        0,      /* Image Sensor Interface */
 340        3,      /* LDC Controller */
 341        0,      /* DMA Controller */
 342        0,
 343        2,      /* USB Host port */
 344        0,      /* Advanced Interrupt Controller (IRQ0) */
 345        0,      /* Advanced Interrupt Controller (IRQ1) */
 346};
 347
 348void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS])
 349{
 350        if (!priority)
 351                priority = at91sam9263_default_irq_priority;
 352
 353        /* Initialize the AIC interrupt controller */
 354        at91_aic_init(priority);
 355
 356        /* Enable GPIO interrupts */
 357        at91_gpio_irq_setup();
 358}
 359