Path: blob/master/arch/arm/mach-at91/at91sam9261.c
10817 views
/*1* arch/arm/mach-at91/at91sam9261.c2*3* Copyright (C) 2005 SAN People4*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/cpu.h>19#include <mach/at91sam9261.h>20#include <mach/at91_pmc.h>21#include <mach/at91_rstc.h>22#include <mach/at91_shdwc.h>2324#include "generic.h"25#include "clock.h"2627static struct map_desc at91sam9261_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};3536static struct map_desc at91sam9261_sram_desc[] __initdata = {37{38.virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,39.pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE),40.length = AT91SAM9261_SRAM_SIZE,41.type = MT_DEVICE,42},43};4445static struct map_desc at91sam9g10_sram_desc[] __initdata = {46{47.virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE,48.pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE),49.length = AT91SAM9G10_SRAM_SIZE,50.type = MT_DEVICE,51},52};5354/* --------------------------------------------------------------------55* Clocks56* -------------------------------------------------------------------- */5758/*59* The peripheral clocks.60*/61static struct clk pioA_clk = {62.name = "pioA_clk",63.pmc_mask = 1 << AT91SAM9261_ID_PIOA,64.type = CLK_TYPE_PERIPHERAL,65};66static struct clk pioB_clk = {67.name = "pioB_clk",68.pmc_mask = 1 << AT91SAM9261_ID_PIOB,69.type = CLK_TYPE_PERIPHERAL,70};71static struct clk pioC_clk = {72.name = "pioC_clk",73.pmc_mask = 1 << AT91SAM9261_ID_PIOC,74.type = CLK_TYPE_PERIPHERAL,75};76static struct clk usart0_clk = {77.name = "usart0_clk",78.pmc_mask = 1 << AT91SAM9261_ID_US0,79.type = CLK_TYPE_PERIPHERAL,80};81static struct clk usart1_clk = {82.name = "usart1_clk",83.pmc_mask = 1 << AT91SAM9261_ID_US1,84.type = CLK_TYPE_PERIPHERAL,85};86static struct clk usart2_clk = {87.name = "usart2_clk",88.pmc_mask = 1 << AT91SAM9261_ID_US2,89.type = CLK_TYPE_PERIPHERAL,90};91static struct clk mmc_clk = {92.name = "mci_clk",93.pmc_mask = 1 << AT91SAM9261_ID_MCI,94.type = CLK_TYPE_PERIPHERAL,95};96static struct clk udc_clk = {97.name = "udc_clk",98.pmc_mask = 1 << AT91SAM9261_ID_UDP,99.type = CLK_TYPE_PERIPHERAL,100};101static struct clk twi_clk = {102.name = "twi_clk",103.pmc_mask = 1 << AT91SAM9261_ID_TWI,104.type = CLK_TYPE_PERIPHERAL,105};106static struct clk spi0_clk = {107.name = "spi0_clk",108.pmc_mask = 1 << AT91SAM9261_ID_SPI0,109.type = CLK_TYPE_PERIPHERAL,110};111static struct clk spi1_clk = {112.name = "spi1_clk",113.pmc_mask = 1 << AT91SAM9261_ID_SPI1,114.type = CLK_TYPE_PERIPHERAL,115};116static struct clk ssc0_clk = {117.name = "ssc0_clk",118.pmc_mask = 1 << AT91SAM9261_ID_SSC0,119.type = CLK_TYPE_PERIPHERAL,120};121static struct clk ssc1_clk = {122.name = "ssc1_clk",123.pmc_mask = 1 << AT91SAM9261_ID_SSC1,124.type = CLK_TYPE_PERIPHERAL,125};126static struct clk ssc2_clk = {127.name = "ssc2_clk",128.pmc_mask = 1 << AT91SAM9261_ID_SSC2,129.type = CLK_TYPE_PERIPHERAL,130};131static struct clk tc0_clk = {132.name = "tc0_clk",133.pmc_mask = 1 << AT91SAM9261_ID_TC0,134.type = CLK_TYPE_PERIPHERAL,135};136static struct clk tc1_clk = {137.name = "tc1_clk",138.pmc_mask = 1 << AT91SAM9261_ID_TC1,139.type = CLK_TYPE_PERIPHERAL,140};141static struct clk tc2_clk = {142.name = "tc2_clk",143.pmc_mask = 1 << AT91SAM9261_ID_TC2,144.type = CLK_TYPE_PERIPHERAL,145};146static struct clk ohci_clk = {147.name = "ohci_clk",148.pmc_mask = 1 << AT91SAM9261_ID_UHP,149.type = CLK_TYPE_PERIPHERAL,150};151static struct clk lcdc_clk = {152.name = "lcdc_clk",153.pmc_mask = 1 << AT91SAM9261_ID_LCDC,154.type = CLK_TYPE_PERIPHERAL,155};156157static struct clk *periph_clocks[] __initdata = {158&pioA_clk,159&pioB_clk,160&pioC_clk,161&usart0_clk,162&usart1_clk,163&usart2_clk,164&mmc_clk,165&udc_clk,166&twi_clk,167&spi0_clk,168&spi1_clk,169&ssc0_clk,170&ssc1_clk,171&ssc2_clk,172&tc0_clk,173&tc1_clk,174&tc2_clk,175&ohci_clk,176&lcdc_clk,177// irq0 .. irq2178};179180static struct clk_lookup periph_clocks_lookups[] = {181CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),182CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),183CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),184CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),185CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk),186CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),187CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),188CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),189};190191static struct clk_lookup usart_clocks_lookups[] = {192CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),193CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),194CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),195CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),196};197198/*199* The four programmable clocks.200* You must configure pin multiplexing to bring these signals out.201*/202static struct clk pck0 = {203.name = "pck0",204.pmc_mask = AT91_PMC_PCK0,205.type = CLK_TYPE_PROGRAMMABLE,206.id = 0,207};208static struct clk pck1 = {209.name = "pck1",210.pmc_mask = AT91_PMC_PCK1,211.type = CLK_TYPE_PROGRAMMABLE,212.id = 1,213};214static struct clk pck2 = {215.name = "pck2",216.pmc_mask = AT91_PMC_PCK2,217.type = CLK_TYPE_PROGRAMMABLE,218.id = 2,219};220static struct clk pck3 = {221.name = "pck3",222.pmc_mask = AT91_PMC_PCK3,223.type = CLK_TYPE_PROGRAMMABLE,224.id = 3,225};226227/* HClocks */228static struct clk hck0 = {229.name = "hck0",230.pmc_mask = AT91_PMC_HCK0,231.type = CLK_TYPE_SYSTEM,232.id = 0,233};234static struct clk hck1 = {235.name = "hck1",236.pmc_mask = AT91_PMC_HCK1,237.type = CLK_TYPE_SYSTEM,238.id = 1,239};240241static void __init at91sam9261_register_clocks(void)242{243int i;244245for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)246clk_register(periph_clocks[i]);247248clkdev_add_table(periph_clocks_lookups,249ARRAY_SIZE(periph_clocks_lookups));250clkdev_add_table(usart_clocks_lookups,251ARRAY_SIZE(usart_clocks_lookups));252253clk_register(&pck0);254clk_register(&pck1);255clk_register(&pck2);256clk_register(&pck3);257258clk_register(&hck0);259clk_register(&hck1);260}261262static struct clk_lookup console_clock_lookup;263264void __init at91sam9261_set_console_clock(int id)265{266if (id >= ARRAY_SIZE(usart_clocks_lookups))267return;268269console_clock_lookup.con_id = "usart";270console_clock_lookup.clk = usart_clocks_lookups[id].clk;271clkdev_add(&console_clock_lookup);272}273274/* --------------------------------------------------------------------275* GPIO276* -------------------------------------------------------------------- */277278static struct at91_gpio_bank at91sam9261_gpio[] = {279{280.id = AT91SAM9261_ID_PIOA,281.offset = AT91_PIOA,282.clock = &pioA_clk,283}, {284.id = AT91SAM9261_ID_PIOB,285.offset = AT91_PIOB,286.clock = &pioB_clk,287}, {288.id = AT91SAM9261_ID_PIOC,289.offset = AT91_PIOC,290.clock = &pioC_clk,291}292};293294static void at91sam9261_poweroff(void)295{296at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);297}298299300/* --------------------------------------------------------------------301* AT91SAM9261 processor initialization302* -------------------------------------------------------------------- */303304void __init at91sam9261_map_io(void)305{306/* Map peripherals */307iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));308309if (cpu_is_at91sam9g10())310iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));311else312iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));313}314315void __init at91sam9261_initialize(unsigned long main_clock)316{317at91_arch_reset = at91sam9_alt_reset;318pm_power_off = at91sam9261_poweroff;319at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)320| (1 << AT91SAM9261_ID_IRQ2);321322/* Init clock subsystem */323at91_clock_init(main_clock);324325/* Register the processor-specific clocks */326at91sam9261_register_clocks();327328/* Register GPIO subsystem */329at91_gpio_init(at91sam9261_gpio, 3);330}331332/* --------------------------------------------------------------------333* Interrupt initialization334* -------------------------------------------------------------------- */335336/*337* The default interrupt priority levels (0 = lowest, 7 = highest).338*/339static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {3407, /* Advanced Interrupt Controller */3417, /* System Peripherals */3421, /* Parallel IO Controller A */3431, /* Parallel IO Controller B */3441, /* Parallel IO Controller C */3450,3465, /* USART 0 */3475, /* USART 1 */3485, /* USART 2 */3490, /* Multimedia Card Interface */3502, /* USB Device Port */3516, /* Two-Wire Interface */3525, /* Serial Peripheral Interface 0 */3535, /* Serial Peripheral Interface 1 */3544, /* Serial Synchronous Controller 0 */3554, /* Serial Synchronous Controller 1 */3564, /* Serial Synchronous Controller 2 */3570, /* Timer Counter 0 */3580, /* Timer Counter 1 */3590, /* Timer Counter 2 */3602, /* USB Host port */3613, /* LCD Controller */3620,3630,3640,3650,3660,3670,3680,3690, /* Advanced Interrupt Controller */3700, /* Advanced Interrupt Controller */3710, /* Advanced Interrupt Controller */372};373374void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS])375{376if (!priority)377priority = at91sam9261_default_irq_priority;378379/* Initialize the AIC interrupt controller */380at91_aic_init(priority);381382/* Enable GPIO interrupts */383at91_gpio_irq_setup();384}385386387