linux/arch/arm/mach-at91/at91rm9200.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-at91/at91rm9200.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/irq.h>
  16#include <asm/mach/arch.h>
  17#include <asm/mach/map.h>
  18#include <mach/at91rm9200.h>
  19#include <mach/at91_pmc.h>
  20#include <mach/at91_st.h>
  21
  22#include "generic.h"
  23#include "clock.h"
  24
  25static struct map_desc at91rm9200_io_desc[] __initdata = {
  26        {
  27                .virtual        = AT91_VA_BASE_SYS,
  28                .pfn            = __phys_to_pfn(AT91_BASE_SYS),
  29                .length         = SZ_4K,
  30                .type           = MT_DEVICE,
  31        }, {
  32                .virtual        = AT91_VA_BASE_EMAC,
  33                .pfn            = __phys_to_pfn(AT91RM9200_BASE_EMAC),
  34                .length         = SZ_16K,
  35                .type           = MT_DEVICE,
  36        }, {
  37                .virtual        = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE,
  38                .pfn            = __phys_to_pfn(AT91RM9200_SRAM_BASE),
  39                .length         = AT91RM9200_SRAM_SIZE,
  40                .type           = MT_DEVICE,
  41        },
  42};
  43
  44/* --------------------------------------------------------------------
  45 *  Clocks
  46 * -------------------------------------------------------------------- */
  47
  48/*
  49 * The peripheral clocks.
  50 */
  51static struct clk udc_clk = {
  52        .name           = "udc_clk",
  53        .pmc_mask       = 1 << AT91RM9200_ID_UDP,
  54        .type           = CLK_TYPE_PERIPHERAL,
  55};
  56static struct clk ohci_clk = {
  57        .name           = "ohci_clk",
  58        .pmc_mask       = 1 << AT91RM9200_ID_UHP,
  59        .type           = CLK_TYPE_PERIPHERAL,
  60};
  61static struct clk ether_clk = {
  62        .name           = "ether_clk",
  63        .pmc_mask       = 1 << AT91RM9200_ID_EMAC,
  64        .type           = CLK_TYPE_PERIPHERAL,
  65};
  66static struct clk mmc_clk = {
  67        .name           = "mci_clk",
  68        .pmc_mask       = 1 << AT91RM9200_ID_MCI,
  69        .type           = CLK_TYPE_PERIPHERAL,
  70};
  71static struct clk twi_clk = {
  72        .name           = "twi_clk",
  73        .pmc_mask       = 1 << AT91RM9200_ID_TWI,
  74        .type           = CLK_TYPE_PERIPHERAL,
  75};
  76static struct clk usart0_clk = {
  77        .name           = "usart0_clk",
  78        .pmc_mask       = 1 << AT91RM9200_ID_US0,
  79        .type           = CLK_TYPE_PERIPHERAL,
  80};
  81static struct clk usart1_clk = {
  82        .name           = "usart1_clk",
  83        .pmc_mask       = 1 << AT91RM9200_ID_US1,
  84        .type           = CLK_TYPE_PERIPHERAL,
  85};
  86static struct clk usart2_clk = {
  87        .name           = "usart2_clk",
  88        .pmc_mask       = 1 << AT91RM9200_ID_US2,
  89        .type           = CLK_TYPE_PERIPHERAL,
  90};
  91static struct clk usart3_clk = {
  92        .name           = "usart3_clk",
  93        .pmc_mask       = 1 << AT91RM9200_ID_US3,
  94        .type           = CLK_TYPE_PERIPHERAL,
  95};
  96static struct clk spi_clk = {
  97        .name           = "spi_clk",
  98        .pmc_mask       = 1 << AT91RM9200_ID_SPI,
  99        .type           = CLK_TYPE_PERIPHERAL,
 100};
 101static struct clk pioA_clk = {
 102        .name           = "pioA_clk",
 103        .pmc_mask       = 1 << AT91RM9200_ID_PIOA,
 104        .type           = CLK_TYPE_PERIPHERAL,
 105};
 106static struct clk pioB_clk = {
 107        .name           = "pioB_clk",
 108        .pmc_mask       = 1 << AT91RM9200_ID_PIOB,
 109        .type           = CLK_TYPE_PERIPHERAL,
 110};
 111static struct clk pioC_clk = {
 112        .name           = "pioC_clk",
 113        .pmc_mask       = 1 << AT91RM9200_ID_PIOC,
 114        .type           = CLK_TYPE_PERIPHERAL,
 115};
 116static struct clk pioD_clk = {
 117        .name           = "pioD_clk",
 118        .pmc_mask       = 1 << AT91RM9200_ID_PIOD,
 119        .type           = CLK_TYPE_PERIPHERAL,
 120};
 121static struct clk ssc0_clk = {
 122        .name           = "ssc0_clk",
 123        .pmc_mask       = 1 << AT91RM9200_ID_SSC0,
 124        .type           = CLK_TYPE_PERIPHERAL,
 125};
 126static struct clk ssc1_clk = {
 127        .name           = "ssc1_clk",
 128        .pmc_mask       = 1 << AT91RM9200_ID_SSC1,
 129        .type           = CLK_TYPE_PERIPHERAL,
 130};
 131static struct clk ssc2_clk = {
 132        .name           = "ssc2_clk",
 133        .pmc_mask       = 1 << AT91RM9200_ID_SSC2,
 134        .type           = CLK_TYPE_PERIPHERAL,
 135};
 136static struct clk tc0_clk = {
 137        .name           = "tc0_clk",
 138        .pmc_mask       = 1 << AT91RM9200_ID_TC0,
 139        .type           = CLK_TYPE_PERIPHERAL,
 140};
 141static struct clk tc1_clk = {
 142        .name           = "tc1_clk",
 143        .pmc_mask       = 1 << AT91RM9200_ID_TC1,
 144        .type           = CLK_TYPE_PERIPHERAL,
 145};
 146static struct clk tc2_clk = {
 147        .name           = "tc2_clk",
 148        .pmc_mask       = 1 << AT91RM9200_ID_TC2,
 149        .type           = CLK_TYPE_PERIPHERAL,
 150};
 151static struct clk tc3_clk = {
 152        .name           = "tc3_clk",
 153        .pmc_mask       = 1 << AT91RM9200_ID_TC3,
 154        .type           = CLK_TYPE_PERIPHERAL,
 155};
 156static struct clk tc4_clk = {
 157        .name           = "tc4_clk",
 158        .pmc_mask       = 1 << AT91RM9200_ID_TC4,
 159        .type           = CLK_TYPE_PERIPHERAL,
 160};
 161static struct clk tc5_clk = {
 162        .name           = "tc5_clk",
 163        .pmc_mask       = 1 << AT91RM9200_ID_TC5,
 164        .type           = CLK_TYPE_PERIPHERAL,
 165};
 166
 167static struct clk *periph_clocks[] __initdata = {
 168        &pioA_clk,
 169        &pioB_clk,
 170        &pioC_clk,
 171        &pioD_clk,
 172        &usart0_clk,
 173        &usart1_clk,
 174        &usart2_clk,
 175        &usart3_clk,
 176        &mmc_clk,
 177        &udc_clk,
 178        &twi_clk,
 179        &spi_clk,
 180        &ssc0_clk,
 181        &ssc1_clk,
 182        &ssc2_clk,
 183        &tc0_clk,
 184        &tc1_clk,
 185        &tc2_clk,
 186        &tc3_clk,
 187        &tc4_clk,
 188        &tc5_clk,
 189        &ohci_clk,
 190        &ether_clk,
 191        // irq0 .. irq6
 192};
 193
 194/*
 195 * The four programmable clocks.
 196 * You must configure pin multiplexing to bring these signals out.
 197 */
 198static struct clk pck0 = {
 199        .name           = "pck0",
 200        .pmc_mask       = AT91_PMC_PCK0,
 201        .type           = CLK_TYPE_PROGRAMMABLE,
 202        .id             = 0,
 203};
 204static struct clk pck1 = {
 205        .name           = "pck1",
 206        .pmc_mask       = AT91_PMC_PCK1,
 207        .type           = CLK_TYPE_PROGRAMMABLE,
 208        .id             = 1,
 209};
 210static struct clk pck2 = {
 211        .name           = "pck2",
 212        .pmc_mask       = AT91_PMC_PCK2,
 213        .type           = CLK_TYPE_PROGRAMMABLE,
 214        .id             = 2,
 215};
 216static struct clk pck3 = {
 217        .name           = "pck3",
 218        .pmc_mask       = AT91_PMC_PCK3,
 219        .type           = CLK_TYPE_PROGRAMMABLE,
 220        .id             = 3,
 221};
 222
 223static void __init at91rm9200_register_clocks(void)
 224{
 225        int i;
 226
 227        for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 228                clk_register(periph_clocks[i]);
 229
 230        clk_register(&pck0);
 231        clk_register(&pck1);
 232        clk_register(&pck2);
 233        clk_register(&pck3);
 234}
 235
 236/* --------------------------------------------------------------------
 237 *  GPIO
 238 * -------------------------------------------------------------------- */
 239
 240static struct at91_gpio_bank at91rm9200_gpio[] = {
 241        {
 242                .id             = AT91RM9200_ID_PIOA,
 243                .offset         = AT91_PIOA,
 244                .clock          = &pioA_clk,
 245        }, {
 246                .id             = AT91RM9200_ID_PIOB,
 247                .offset         = AT91_PIOB,
 248                .clock          = &pioB_clk,
 249        }, {
 250                .id             = AT91RM9200_ID_PIOC,
 251                .offset         = AT91_PIOC,
 252                .clock          = &pioC_clk,
 253        }, {
 254                .id             = AT91RM9200_ID_PIOD,
 255                .offset         = AT91_PIOD,
 256                .clock          = &pioD_clk,
 257        }
 258};
 259
 260static void at91rm9200_reset(void)
 261{
 262        /*
 263         * Perform a hardware reset with the use of the Watchdog timer.
 264         */
 265        at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
 266        at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
 267}
 268
 269
 270/* --------------------------------------------------------------------
 271 *  AT91RM9200 processor initialization
 272 * -------------------------------------------------------------------- */
 273void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks)
 274{
 275        /* Map peripherals */
 276        iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
 277
 278        at91_arch_reset = at91rm9200_reset;
 279        at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
 280                        | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
 281                        | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5)
 282                        | (1 << AT91RM9200_ID_IRQ6);
 283
 284        /* Init clock subsystem */
 285        at91_clock_init(main_clock);
 286
 287        /* Register the processor-specific clocks */
 288        at91rm9200_register_clocks();
 289
 290        /* Initialize GPIO subsystem */
 291        at91_gpio_init(at91rm9200_gpio, banks);
 292}
 293
 294
 295/* --------------------------------------------------------------------
 296 *  Interrupt initialization
 297 * -------------------------------------------------------------------- */
 298
 299/*
 300 * The default interrupt priority levels (0 = lowest, 7 = highest).
 301 */
 302static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
 303        7,      /* Advanced Interrupt Controller (FIQ) */
 304        7,      /* System Peripherals */
 305        1,      /* Parallel IO Controller A */
 306        1,      /* Parallel IO Controller B */
 307        1,      /* Parallel IO Controller C */
 308        1,      /* Parallel IO Controller D */
 309        5,      /* USART 0 */
 310        5,      /* USART 1 */
 311        5,      /* USART 2 */
 312        5,      /* USART 3 */
 313        0,      /* Multimedia Card Interface */
 314        2,      /* USB Device Port */
 315        6,      /* Two-Wire Interface */
 316        5,      /* Serial Peripheral Interface */
 317        4,      /* Serial Synchronous Controller 0 */
 318        4,      /* Serial Synchronous Controller 1 */
 319        4,      /* Serial Synchronous Controller 2 */
 320        0,      /* Timer Counter 0 */
 321        0,      /* Timer Counter 1 */
 322        0,      /* Timer Counter 2 */
 323        0,      /* Timer Counter 3 */
 324        0,      /* Timer Counter 4 */
 325        0,      /* Timer Counter 5 */
 326        2,      /* USB Host port */
 327        3,      /* Ethernet MAC */
 328        0,      /* Advanced Interrupt Controller (IRQ0) */
 329        0,      /* Advanced Interrupt Controller (IRQ1) */
 330        0,      /* Advanced Interrupt Controller (IRQ2) */
 331        0,      /* Advanced Interrupt Controller (IRQ3) */
 332        0,      /* Advanced Interrupt Controller (IRQ4) */
 333        0,      /* Advanced Interrupt Controller (IRQ5) */
 334        0       /* Advanced Interrupt Controller (IRQ6) */
 335};
 336
 337void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS])
 338{
 339        if (!priority)
 340                priority = at91rm9200_default_irq_priority;
 341
 342        /* Initialize the AIC interrupt controller */
 343        at91_aic_init(priority);
 344
 345        /* Enable GPIO interrupts */
 346        at91_gpio_irq_setup();
 347}
 348