Skip to content

Commit

Permalink
[ARM] 4370/3: AT91: Support for Atmel AT91SAM9RL processors.
Browse files Browse the repository at this point in the history
Add support for Atmel's new AT91SAM9RL range of processors.
Includes similar peripherals as other AT91SAM9 processors, but with a
High-speed USB controller and various sizes of internal SRAM.

Signed-off-by: Nicolas Ferre <nicolas.ferre@rfo.atmel.com>
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Andrew Victor authored and Russell King committed May 11, 2007
1 parent 9da7cf2 commit 877d772
Show file tree
Hide file tree
Showing 13 changed files with 1,207 additions and 3 deletions.
3 changes: 3 additions & 0 deletions arch/arm/mach-at91/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ config ARCH_AT91SAM9261
config ARCH_AT91SAM9263
bool "AT91SAM9263"

config ARCH_AT91SAM9RL
bool "AT91SAM9RL"

endchoice

# ----------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-at91/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devic
obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o
obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o

# AT91RM9200 board-specific support
obj-$(CONFIG_MACH_ONEARM) += board-1arm.o
Expand Down
341 changes: 341 additions & 0 deletions arch/arm/mach-at91/at91sam9rl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,341 @@
/*
* arch/arm/mach-at91/at91sam9rl.c
*
* Copyright (C) 2005 SAN People
* Copyright (C) 2007 Atmel Corporation
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/

#include <linux/module.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/cpu.h>
#include <asm/arch/at91sam9rl.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_rstc.h>

#include "generic.h"
#include "clock.h"

static struct map_desc at91sam9rl_io_desc[] __initdata = {
{
.virtual = AT91_VA_BASE_SYS,
.pfn = __phys_to_pfn(AT91_BASE_SYS),
.length = SZ_16K,
.type = MT_DEVICE,
},
};

static struct map_desc at91sam9rl_sram_desc[] __initdata = {
{
.pfn = __phys_to_pfn(AT91SAM9RL_SRAM_BASE),
.type = MT_DEVICE,
}
};

/* --------------------------------------------------------------------
* Clocks
* -------------------------------------------------------------------- */

/*
* The peripheral clocks.
*/
static struct clk pioA_clk = {
.name = "pioA_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_PIOA,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pioB_clk = {
.name = "pioB_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_PIOB,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pioC_clk = {
.name = "pioC_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_PIOC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pioD_clk = {
.name = "pioD_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_PIOD,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk usart0_clk = {
.name = "usart0_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_US0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk usart1_clk = {
.name = "usart1_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_US1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk usart2_clk = {
.name = "usart2_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_US2,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk usart3_clk = {
.name = "usart3_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_US3,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk mmc_clk = {
.name = "mci_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_MCI,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk twi0_clk = {
.name = "twi0_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_TWI0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk twi1_clk = {
.name = "twi1_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_TWI1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk spi_clk = {
.name = "spi_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_SPI,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc0_clk = {
.name = "ssc0_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_SSC0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc1_clk = {
.name = "ssc1_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_SSC1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tc0_clk = {
.name = "tc0_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_TC0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tc1_clk = {
.name = "tc1_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_TC1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tc2_clk = {
.name = "tc2_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_TC2,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pwmc_clk = {
.name = "pwmc_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_PWMC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tsc_clk = {
.name = "tsc_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_TSC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk dma_clk = {
.name = "dma_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_DMA,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk udphs_clk = {
.name = "udphs_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_UDPHS,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk lcdc_clk = {
.name = "lcdc_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_LCDC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ac97_clk = {
.name = "ac97_clk",
.pmc_mask = 1 << AT91SAM9RL_ID_AC97C,
.type = CLK_TYPE_PERIPHERAL,
};

static struct clk *periph_clocks[] __initdata = {
&pioA_clk,
&pioB_clk,
&pioC_clk,
&pioD_clk,
&usart0_clk,
&usart1_clk,
&usart2_clk,
&usart3_clk,
&mmc_clk,
&twi0_clk,
&twi1_clk,
&spi_clk,
&ssc0_clk,
&ssc1_clk,
&tc0_clk,
&tc1_clk,
&tc2_clk,
&pwmc_clk,
&tsc_clk,
&dma_clk,
&udphs_clk,
&lcdc_clk,
&ac97_clk,
// irq0
};

/*
* The two programmable clocks.
* You must configure pin multiplexing to bring these signals out.
*/
static struct clk pck0 = {
.name = "pck0",
.pmc_mask = AT91_PMC_PCK0,
.type = CLK_TYPE_PROGRAMMABLE,
.id = 0,
};
static struct clk pck1 = {
.name = "pck1",
.pmc_mask = AT91_PMC_PCK1,
.type = CLK_TYPE_PROGRAMMABLE,
.id = 1,
};

static void __init at91sam9rl_register_clocks(void)
{
int i;

for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
clk_register(periph_clocks[i]);

clk_register(&pck0);
clk_register(&pck1);
}

/* --------------------------------------------------------------------
* GPIO
* -------------------------------------------------------------------- */

static struct at91_gpio_bank at91sam9rl_gpio[] = {
{
.id = AT91SAM9RL_ID_PIOA,
.offset = AT91_PIOA,
.clock = &pioA_clk,
}, {
.id = AT91SAM9RL_ID_PIOB,
.offset = AT91_PIOB,
.clock = &pioB_clk,
}, {
.id = AT91SAM9RL_ID_PIOC,
.offset = AT91_PIOC,
.clock = &pioC_clk,
}, {
.id = AT91SAM9RL_ID_PIOD,
.offset = AT91_PIOD,
.clock = &pioD_clk,
}
};

static void at91sam9rl_reset(void)
{
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}


/* --------------------------------------------------------------------
* AT91SAM9RL processor initialization
* -------------------------------------------------------------------- */

void __init at91sam9rl_initialize(unsigned long main_clock)
{
unsigned long cidr, sram_size;

/* Map peripherals */
iotable_init(at91sam9rl_io_desc, ARRAY_SIZE(at91sam9rl_io_desc));

cidr = at91_sys_read(AT91_DBGU_CIDR);

switch (cidr & AT91_CIDR_SRAMSIZ) {
case AT91_CIDR_SRAMSIZ_32K:
sram_size = 2 * SZ_16K;
break;
case AT91_CIDR_SRAMSIZ_16K:
default:
sram_size = SZ_16K;
}

at91sam9rl_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size;
at91sam9rl_sram_desc->length = sram_size;

/* Map SRAM */
iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc));

at91_arch_reset = at91sam9rl_reset;
at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);

/* Init clock subsystem */
at91_clock_init(main_clock);

/* Register the processor-specific clocks */
at91sam9rl_register_clocks();

/* Register GPIO subsystem */
at91_gpio_init(at91sam9rl_gpio, 4);
}

/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */

/*
* The default interrupt priority levels (0 = lowest, 7 = highest).
*/
static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
7, /* Advanced Interrupt Controller */
7, /* System Peripherals */
1, /* Parallel IO Controller A */
1, /* Parallel IO Controller B */
1, /* Parallel IO Controller C */
1, /* Parallel IO Controller D */
5, /* USART 0 */
5, /* USART 1 */
5, /* USART 2 */
5, /* USART 3 */
0, /* Multimedia Card Interface */
6, /* Two-Wire Interface 0 */
6, /* Two-Wire Interface 1 */
5, /* Serial Peripheral Interface */
4, /* Serial Synchronous Controller 0 */
4, /* Serial Synchronous Controller 1 */
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
0,
0, /* Touch Screen Controller */
0, /* DMA Controller */
2, /* USB Device High speed port */
2, /* LCD Controller */
6, /* AC97 Controller */
0,
0,
0,
0,
0,
0,
0, /* Advanced Interrupt Controller */
};

void __init at91sam9rl_init_interrupts(unsigned int priority[NR_AIC_IRQS])
{
if (!priority)
priority = at91sam9rl_default_irq_priority;

/* Initialize the AIC interrupt controller */
at91_aic_init(priority);

/* Enable GPIO interrupts */
at91_gpio_irq_setup();
}
Loading

0 comments on commit 877d772

Please sign in to comment.