Path: blob/master/arch/arm/mach-at91/at91sam9263.c
10817 views
/*1* arch/arm/mach-at91/at91sam9263.c2*3* Copyright (C) 2007 Atmel Corporation.4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10*/1112#include <linux/module.h>13#include <linux/pm.h>1415#include <asm/irq.h>16#include <asm/mach/arch.h>17#include <asm/mach/map.h>18#include <mach/at91sam9263.h>19#include <mach/at91_pmc.h>20#include <mach/at91_rstc.h>21#include <mach/at91_shdwc.h>2223#include "generic.h"24#include "clock.h"2526static struct map_desc at91sam9263_io_desc[] __initdata = {27{28.virtual = AT91_VA_BASE_SYS,29.pfn = __phys_to_pfn(AT91_BASE_SYS),30.length = SZ_16K,31.type = MT_DEVICE,32}, {33.virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE,34.pfn = __phys_to_pfn(AT91SAM9263_SRAM0_BASE),35.length = AT91SAM9263_SRAM0_SIZE,36.type = MT_DEVICE,37}, {38.virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE,39.pfn = __phys_to_pfn(AT91SAM9263_SRAM1_BASE),40.length = AT91SAM9263_SRAM1_SIZE,41.type = MT_DEVICE,42},43};4445/* --------------------------------------------------------------------46* Clocks47* -------------------------------------------------------------------- */4849/*50* The peripheral clocks.51*/52static struct clk pioA_clk = {53.name = "pioA_clk",54.pmc_mask = 1 << AT91SAM9263_ID_PIOA,55.type = CLK_TYPE_PERIPHERAL,56};57static struct clk pioB_clk = {58.name = "pioB_clk",59.pmc_mask = 1 << AT91SAM9263_ID_PIOB,60.type = CLK_TYPE_PERIPHERAL,61};62static struct clk pioCDE_clk = {63.name = "pioCDE_clk",64.pmc_mask = 1 << AT91SAM9263_ID_PIOCDE,65.type = CLK_TYPE_PERIPHERAL,66};67static struct clk usart0_clk = {68.name = "usart0_clk",69.pmc_mask = 1 << AT91SAM9263_ID_US0,70.type = CLK_TYPE_PERIPHERAL,71};72static struct clk usart1_clk = {73.name = "usart1_clk",74.pmc_mask = 1 << AT91SAM9263_ID_US1,75.type = CLK_TYPE_PERIPHERAL,76};77static struct clk usart2_clk = {78.name = "usart2_clk",79.pmc_mask = 1 << AT91SAM9263_ID_US2,80.type = CLK_TYPE_PERIPHERAL,81};82static struct clk mmc0_clk = {83.name = "mci0_clk",84.pmc_mask = 1 << AT91SAM9263_ID_MCI0,85.type = CLK_TYPE_PERIPHERAL,86};87static struct clk mmc1_clk = {88.name = "mci1_clk",89.pmc_mask = 1 << AT91SAM9263_ID_MCI1,90.type = CLK_TYPE_PERIPHERAL,91};92static struct clk can_clk = {93.name = "can_clk",94.pmc_mask = 1 << AT91SAM9263_ID_CAN,95.type = CLK_TYPE_PERIPHERAL,96};97static struct clk twi_clk = {98.name = "twi_clk",99.pmc_mask = 1 << AT91SAM9263_ID_TWI,100.type = CLK_TYPE_PERIPHERAL,101};102static struct clk spi0_clk = {103.name = "spi0_clk",104.pmc_mask = 1 << AT91SAM9263_ID_SPI0,105.type = CLK_TYPE_PERIPHERAL,106};107static struct clk spi1_clk = {108.name = "spi1_clk",109.pmc_mask = 1 << AT91SAM9263_ID_SPI1,110.type = CLK_TYPE_PERIPHERAL,111};112static struct clk ssc0_clk = {113.name = "ssc0_clk",114.pmc_mask = 1 << AT91SAM9263_ID_SSC0,115.type = CLK_TYPE_PERIPHERAL,116};117static struct clk ssc1_clk = {118.name = "ssc1_clk",119.pmc_mask = 1 << AT91SAM9263_ID_SSC1,120.type = CLK_TYPE_PERIPHERAL,121};122static struct clk ac97_clk = {123.name = "ac97_clk",124.pmc_mask = 1 << AT91SAM9263_ID_AC97C,125.type = CLK_TYPE_PERIPHERAL,126};127static struct clk tcb_clk = {128.name = "tcb_clk",129.pmc_mask = 1 << AT91SAM9263_ID_TCB,130.type = CLK_TYPE_PERIPHERAL,131};132static struct clk pwm_clk = {133.name = "pwm_clk",134.pmc_mask = 1 << AT91SAM9263_ID_PWMC,135.type = CLK_TYPE_PERIPHERAL,136};137static struct clk macb_clk = {138.name = "macb_clk",139.pmc_mask = 1 << AT91SAM9263_ID_EMAC,140.type = CLK_TYPE_PERIPHERAL,141};142static struct clk dma_clk = {143.name = "dma_clk",144.pmc_mask = 1 << AT91SAM9263_ID_DMA,145.type = CLK_TYPE_PERIPHERAL,146};147static struct clk twodge_clk = {148.name = "2dge_clk",149.pmc_mask = 1 << AT91SAM9263_ID_2DGE,150.type = CLK_TYPE_PERIPHERAL,151};152static struct clk udc_clk = {153.name = "udc_clk",154.pmc_mask = 1 << AT91SAM9263_ID_UDP,155.type = CLK_TYPE_PERIPHERAL,156};157static struct clk isi_clk = {158.name = "isi_clk",159.pmc_mask = 1 << AT91SAM9263_ID_ISI,160.type = CLK_TYPE_PERIPHERAL,161};162static struct clk lcdc_clk = {163.name = "lcdc_clk",164.pmc_mask = 1 << AT91SAM9263_ID_LCDC,165.type = CLK_TYPE_PERIPHERAL,166};167static struct clk ohci_clk = {168.name = "ohci_clk",169.pmc_mask = 1 << AT91SAM9263_ID_UHP,170.type = CLK_TYPE_PERIPHERAL,171};172173static struct clk *periph_clocks[] __initdata = {174&pioA_clk,175&pioB_clk,176&pioCDE_clk,177&usart0_clk,178&usart1_clk,179&usart2_clk,180&mmc0_clk,181&mmc1_clk,182&can_clk,183&twi_clk,184&spi0_clk,185&spi1_clk,186&ssc0_clk,187&ssc1_clk,188&ac97_clk,189&tcb_clk,190&pwm_clk,191&macb_clk,192&twodge_clk,193&udc_clk,194&isi_clk,195&lcdc_clk,196&dma_clk,197&ohci_clk,198// irq0 .. irq1199};200201static struct clk_lookup periph_clocks_lookups[] = {202CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),203CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),204CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),205CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),206CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),207CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),208CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),209};210211static struct clk_lookup usart_clocks_lookups[] = {212CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),213CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),214CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),215CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),216};217218/*219* The four 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};234static struct clk pck2 = {235.name = "pck2",236.pmc_mask = AT91_PMC_PCK2,237.type = CLK_TYPE_PROGRAMMABLE,238.id = 2,239};240static struct clk pck3 = {241.name = "pck3",242.pmc_mask = AT91_PMC_PCK3,243.type = CLK_TYPE_PROGRAMMABLE,244.id = 3,245};246247static void __init at91sam9263_register_clocks(void)248{249int i;250251for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)252clk_register(periph_clocks[i]);253254clkdev_add_table(periph_clocks_lookups,255ARRAY_SIZE(periph_clocks_lookups));256clkdev_add_table(usart_clocks_lookups,257ARRAY_SIZE(usart_clocks_lookups));258259clk_register(&pck0);260clk_register(&pck1);261clk_register(&pck2);262clk_register(&pck3);263}264265static struct clk_lookup console_clock_lookup;266267void __init at91sam9263_set_console_clock(int id)268{269if (id >= ARRAY_SIZE(usart_clocks_lookups))270return;271272console_clock_lookup.con_id = "usart";273console_clock_lookup.clk = usart_clocks_lookups[id].clk;274clkdev_add(&console_clock_lookup);275}276277/* --------------------------------------------------------------------278* GPIO279* -------------------------------------------------------------------- */280281static struct at91_gpio_bank at91sam9263_gpio[] = {282{283.id = AT91SAM9263_ID_PIOA,284.offset = AT91_PIOA,285.clock = &pioA_clk,286}, {287.id = AT91SAM9263_ID_PIOB,288.offset = AT91_PIOB,289.clock = &pioB_clk,290}, {291.id = AT91SAM9263_ID_PIOCDE,292.offset = AT91_PIOC,293.clock = &pioCDE_clk,294}, {295.id = AT91SAM9263_ID_PIOCDE,296.offset = AT91_PIOD,297.clock = &pioCDE_clk,298}, {299.id = AT91SAM9263_ID_PIOCDE,300.offset = AT91_PIOE,301.clock = &pioCDE_clk,302}303};304305static void at91sam9263_poweroff(void)306{307at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);308}309310311/* --------------------------------------------------------------------312* AT91SAM9263 processor initialization313* -------------------------------------------------------------------- */314315void __init at91sam9263_map_io(void)316{317/* Map peripherals */318iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));319}320321void __init at91sam9263_initialize(unsigned long main_clock)322{323at91_arch_reset = at91sam9_alt_reset;324pm_power_off = at91sam9263_poweroff;325at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);326327/* Init clock subsystem */328at91_clock_init(main_clock);329330/* Register the processor-specific clocks */331at91sam9263_register_clocks();332333/* Register GPIO subsystem */334at91_gpio_init(at91sam9263_gpio, 5);335}336337/* --------------------------------------------------------------------338* Interrupt initialization339* -------------------------------------------------------------------- */340341/*342* The default interrupt priority levels (0 = lowest, 7 = highest).343*/344static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {3457, /* Advanced Interrupt Controller (FIQ) */3467, /* System Peripherals */3471, /* Parallel IO Controller A */3481, /* Parallel IO Controller B */3491, /* Parallel IO Controller C, D and E */3500,3510,3525, /* USART 0 */3535, /* USART 1 */3545, /* USART 2 */3550, /* Multimedia Card Interface 0 */3560, /* Multimedia Card Interface 1 */3573, /* CAN */3586, /* Two-Wire Interface */3595, /* Serial Peripheral Interface 0 */3605, /* Serial Peripheral Interface 1 */3614, /* Serial Synchronous Controller 0 */3624, /* Serial Synchronous Controller 1 */3635, /* AC97 Controller */3640, /* Timer Counter 0, 1 and 2 */3650, /* Pulse Width Modulation Controller */3663, /* Ethernet */3670,3680, /* 2D Graphic Engine */3692, /* USB Device Port */3700, /* Image Sensor Interface */3713, /* LDC Controller */3720, /* DMA Controller */3730,3742, /* USB Host port */3750, /* Advanced Interrupt Controller (IRQ0) */3760, /* Advanced Interrupt Controller (IRQ1) */377};378379void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS])380{381if (!priority)382priority = at91sam9263_default_irq_priority;383384/* Initialize the AIC interrupt controller */385at91_aic_init(priority);386387/* Enable GPIO interrupts */388at91_gpio_irq_setup();389}390391392