linux/arch/arm/mach-at91/at91sam9x5.c
<<
>>
Prefs
   1/*
   2 *  Chip-specific setup code for the AT91SAM9x5 family
   3 *
   4 *  Copyright (C) 2010-2012 Atmel Corporation.
   5 *
   6 * Licensed under GPLv2 or later.
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/dma-mapping.h>
  11
  12#include <asm/irq.h>
  13#include <asm/mach/arch.h>
  14#include <asm/mach/map.h>
  15#include <mach/at91sam9x5.h>
  16#include <mach/at91_pmc.h>
  17#include <mach/cpu.h>
  18#include <mach/board.h>
  19
  20#include "soc.h"
  21#include "generic.h"
  22#include "clock.h"
  23#include "sam9_smc.h"
  24
  25/* --------------------------------------------------------------------
  26 *  Clocks
  27 * -------------------------------------------------------------------- */
  28
  29/*
  30 * The peripheral clocks.
  31 */
  32static struct clk pioAB_clk = {
  33        .name           = "pioAB_clk",
  34        .pmc_mask       = 1 << AT91SAM9X5_ID_PIOAB,
  35        .type           = CLK_TYPE_PERIPHERAL,
  36};
  37static struct clk pioCD_clk = {
  38        .name           = "pioCD_clk",
  39        .pmc_mask       = 1 << AT91SAM9X5_ID_PIOCD,
  40        .type           = CLK_TYPE_PERIPHERAL,
  41};
  42static struct clk smd_clk = {
  43        .name           = "smd_clk",
  44        .pmc_mask       = 1 << AT91SAM9X5_ID_SMD,
  45        .type           = CLK_TYPE_PERIPHERAL,
  46};
  47static struct clk usart0_clk = {
  48        .name           = "usart0_clk",
  49        .pmc_mask       = 1 << AT91SAM9X5_ID_USART0,
  50        .type           = CLK_TYPE_PERIPHERAL,
  51};
  52static struct clk usart1_clk = {
  53        .name           = "usart1_clk",
  54        .pmc_mask       = 1 << AT91SAM9X5_ID_USART1,
  55        .type           = CLK_TYPE_PERIPHERAL,
  56};
  57static struct clk usart2_clk = {
  58        .name           = "usart2_clk",
  59        .pmc_mask       = 1 << AT91SAM9X5_ID_USART2,
  60        .type           = CLK_TYPE_PERIPHERAL,
  61};
  62/* USART3 clock - Only for sam9g25/sam9x25 */
  63static struct clk usart3_clk = {
  64        .name           = "usart3_clk",
  65        .pmc_mask       = 1 << AT91SAM9X5_ID_USART3,
  66        .type           = CLK_TYPE_PERIPHERAL,
  67};
  68static struct clk twi0_clk = {
  69        .name           = "twi0_clk",
  70        .pmc_mask       = 1 << AT91SAM9X5_ID_TWI0,
  71        .type           = CLK_TYPE_PERIPHERAL,
  72};
  73static struct clk twi1_clk = {
  74        .name           = "twi1_clk",
  75        .pmc_mask       = 1 << AT91SAM9X5_ID_TWI1,
  76        .type           = CLK_TYPE_PERIPHERAL,
  77};
  78static struct clk twi2_clk = {
  79        .name           = "twi2_clk",
  80        .pmc_mask       = 1 << AT91SAM9X5_ID_TWI2,
  81        .type           = CLK_TYPE_PERIPHERAL,
  82};
  83static struct clk mmc0_clk = {
  84        .name           = "mci0_clk",
  85        .pmc_mask       = 1 << AT91SAM9X5_ID_MCI0,
  86        .type           = CLK_TYPE_PERIPHERAL,
  87};
  88static struct clk spi0_clk = {
  89        .name           = "spi0_clk",
  90        .pmc_mask       = 1 << AT91SAM9X5_ID_SPI0,
  91        .type           = CLK_TYPE_PERIPHERAL,
  92};
  93static struct clk spi1_clk = {
  94        .name           = "spi1_clk",
  95        .pmc_mask       = 1 << AT91SAM9X5_ID_SPI1,
  96        .type           = CLK_TYPE_PERIPHERAL,
  97};
  98static struct clk uart0_clk = {
  99        .name           = "uart0_clk",
 100        .pmc_mask       = 1 << AT91SAM9X5_ID_UART0,
 101        .type           = CLK_TYPE_PERIPHERAL,
 102};
 103static struct clk uart1_clk = {
 104        .name           = "uart1_clk",
 105        .pmc_mask       = 1 << AT91SAM9X5_ID_UART1,
 106        .type           = CLK_TYPE_PERIPHERAL,
 107};
 108static struct clk tcb0_clk = {
 109        .name           = "tcb0_clk",
 110        .pmc_mask       = 1 << AT91SAM9X5_ID_TCB,
 111        .type           = CLK_TYPE_PERIPHERAL,
 112};
 113static struct clk pwm_clk = {
 114        .name           = "pwm_clk",
 115        .pmc_mask       = 1 << AT91SAM9X5_ID_PWM,
 116        .type           = CLK_TYPE_PERIPHERAL,
 117};
 118static struct clk adc_clk = {
 119        .name           = "adc_clk",
 120        .pmc_mask       = 1 << AT91SAM9X5_ID_ADC,
 121        .type   = CLK_TYPE_PERIPHERAL,
 122};
 123static struct clk adc_op_clk = {
 124        .name           = "adc_op_clk",
 125        .type           = CLK_TYPE_PERIPHERAL,
 126        .rate_hz        = 5000000,
 127};
 128static struct clk dma0_clk = {
 129        .name           = "dma0_clk",
 130        .pmc_mask       = 1 << AT91SAM9X5_ID_DMA0,
 131        .type   = CLK_TYPE_PERIPHERAL,
 132};
 133static struct clk dma1_clk = {
 134        .name           = "dma1_clk",
 135        .pmc_mask       = 1 << AT91SAM9X5_ID_DMA1,
 136        .type           = CLK_TYPE_PERIPHERAL,
 137};
 138static struct clk uhphs_clk = {
 139        .name           = "uhphs",
 140        .pmc_mask       = 1 << AT91SAM9X5_ID_UHPHS,
 141        .type           = CLK_TYPE_PERIPHERAL,
 142};
 143static struct clk udphs_clk = {
 144        .name           = "udphs_clk",
 145        .pmc_mask       = 1 << AT91SAM9X5_ID_UDPHS,
 146        .type           = CLK_TYPE_PERIPHERAL,
 147};
 148/* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */
 149static struct clk macb0_clk = {
 150        .name           = "pclk",
 151        .pmc_mask       = 1 << AT91SAM9X5_ID_EMAC0,
 152        .type           = CLK_TYPE_PERIPHERAL,
 153};
 154/* lcd clock - Only for sam9g15/sam9g35/sam9x35 */
 155static struct clk lcdc_clk = {
 156        .name           = "lcdc_clk",
 157        .pmc_mask       = 1 << AT91SAM9X5_ID_LCDC,
 158        .type           = CLK_TYPE_PERIPHERAL,
 159};
 160/* isi clock - Only for sam9g25 */
 161static struct clk isi_clk = {
 162        .name           = "isi_clk",
 163        .pmc_mask       = 1 << AT91SAM9X5_ID_ISI,
 164        .type           = CLK_TYPE_PERIPHERAL,
 165};
 166static struct clk mmc1_clk = {
 167        .name           = "mci1_clk",
 168        .pmc_mask       = 1 << AT91SAM9X5_ID_MCI1,
 169        .type           = CLK_TYPE_PERIPHERAL,
 170};
 171/* emac1 clock - Only for sam9x25 */
 172static struct clk macb1_clk = {
 173        .name           = "pclk",
 174        .pmc_mask       = 1 << AT91SAM9X5_ID_EMAC1,
 175        .type           = CLK_TYPE_PERIPHERAL,
 176};
 177static struct clk ssc_clk = {
 178        .name           = "ssc_clk",
 179        .pmc_mask       = 1 << AT91SAM9X5_ID_SSC,
 180        .type           = CLK_TYPE_PERIPHERAL,
 181};
 182/* can0 clock - Only for sam9x35 */
 183static struct clk can0_clk = {
 184        .name           = "can0_clk",
 185        .pmc_mask       = 1 << AT91SAM9X5_ID_CAN0,
 186        .type           = CLK_TYPE_PERIPHERAL,
 187};
 188/* can1 clock - Only for sam9x35 */
 189static struct clk can1_clk = {
 190        .name           = "can1_clk",
 191        .pmc_mask       = 1 << AT91SAM9X5_ID_CAN1,
 192        .type           = CLK_TYPE_PERIPHERAL,
 193};
 194
 195static struct clk *periph_clocks[] __initdata = {
 196        &pioAB_clk,
 197        &pioCD_clk,
 198        &smd_clk,
 199        &usart0_clk,
 200        &usart1_clk,
 201        &usart2_clk,
 202        &twi0_clk,
 203        &twi1_clk,
 204        &twi2_clk,
 205        &mmc0_clk,
 206        &spi0_clk,
 207        &spi1_clk,
 208        &uart0_clk,
 209        &uart1_clk,
 210        &tcb0_clk,
 211        &pwm_clk,
 212        &adc_clk,
 213        &adc_op_clk,
 214        &dma0_clk,
 215        &dma1_clk,
 216        &uhphs_clk,
 217        &udphs_clk,
 218        &mmc1_clk,
 219        &ssc_clk,
 220        // irq0
 221};
 222
 223static struct clk_lookup periph_clocks_lookups[] = {
 224        /* lookup table for DT entries */
 225        CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
 226        CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk),
 227        CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk),
 228        CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk),
 229        CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
 230        CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk),
 231        CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
 232        CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk),
 233        CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk),
 234        CLKDEV_CON_ID("pioA", &pioAB_clk),
 235        CLKDEV_CON_ID("pioB", &pioAB_clk),
 236        CLKDEV_CON_ID("pioC", &pioCD_clk),
 237        CLKDEV_CON_ID("pioD", &pioCD_clk),
 238        /* additional fake clock for macb_hclk */
 239        CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk),
 240        CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk),
 241        CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
 242        CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
 243        CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
 244};
 245
 246/*
 247 * The two programmable clocks.
 248 * You must configure pin multiplexing to bring these signals out.
 249 */
 250static struct clk pck0 = {
 251        .name           = "pck0",
 252        .pmc_mask       = AT91_PMC_PCK0,
 253        .type           = CLK_TYPE_PROGRAMMABLE,
 254        .id             = 0,
 255};
 256static struct clk pck1 = {
 257        .name           = "pck1",
 258        .pmc_mask       = AT91_PMC_PCK1,
 259        .type           = CLK_TYPE_PROGRAMMABLE,
 260        .id             = 1,
 261};
 262
 263static void __init at91sam9x5_register_clocks(void)
 264{
 265        int i;
 266
 267        for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 268                clk_register(periph_clocks[i]);
 269
 270        clkdev_add_table(periph_clocks_lookups,
 271                         ARRAY_SIZE(periph_clocks_lookups));
 272
 273        if (cpu_is_at91sam9g25()
 274        || cpu_is_at91sam9x25())
 275                clk_register(&usart3_clk);
 276
 277        if (cpu_is_at91sam9g25()
 278        || cpu_is_at91sam9x25()
 279        || cpu_is_at91sam9g35()
 280        || cpu_is_at91sam9x35())
 281                clk_register(&macb0_clk);
 282
 283        if (cpu_is_at91sam9g15()
 284        || cpu_is_at91sam9g35()
 285        || cpu_is_at91sam9x35())
 286                clk_register(&lcdc_clk);
 287
 288        if (cpu_is_at91sam9g25())
 289                clk_register(&isi_clk);
 290
 291        if (cpu_is_at91sam9x25())
 292                clk_register(&macb1_clk);
 293
 294        if (cpu_is_at91sam9x25()
 295        || cpu_is_at91sam9x35()) {
 296                clk_register(&can0_clk);
 297                clk_register(&can1_clk);
 298        }
 299
 300        clk_register(&pck0);
 301        clk_register(&pck1);
 302}
 303
 304/* --------------------------------------------------------------------
 305 *  AT91SAM9x5 processor initialization
 306 * -------------------------------------------------------------------- */
 307
 308static void __init at91sam9x5_map_io(void)
 309{
 310        at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
 311}
 312
 313void __init at91sam9x5_initialize(void)
 314{
 315        /* Register GPIO subsystem (using DT) */
 316        at91_gpio_init(NULL, 0);
 317}
 318
 319/* --------------------------------------------------------------------
 320 *  Interrupt initialization
 321 * -------------------------------------------------------------------- */
 322
 323struct at91_init_soc __initdata at91sam9x5_soc = {
 324        .map_io = at91sam9x5_map_io,
 325        .register_clocks = at91sam9x5_register_clocks,
 326        .init = at91sam9x5_initialize,
 327};
 328