1/* 2 * arch/arm/mach-at91/at91sam9261.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/mach/arch.h> 16#include <asm/mach/map.h> 17#include <asm/arch/at91sam9261.h> 18#include <asm/arch/at91_pmc.h> 19#include <asm/arch/at91_rstc.h> 20 21#include "generic.h" 22#include "clock.h" 23 24static struct map_desc at91sam9261_io_desc[] __initdata = { 25 { 26 .virtual = AT91_VA_BASE_SYS, 27 .pfn = __phys_to_pfn(AT91_BASE_SYS), 28 .length = SZ_16K, 29 .type = MT_DEVICE, 30 }, { 31 .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, 32 .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), 33 .length = AT91SAM9261_SRAM_SIZE, 34 .type = MT_DEVICE, 35 }, 36}; 37 38/* -------------------------------------------------------------------- 39 * Clocks 40 * -------------------------------------------------------------------- */ 41 42/* 43 * The peripheral clocks. 44 */ 45static struct clk pioA_clk = { 46 .name = "pioA_clk", 47 .pmc_mask = 1 << AT91SAM9261_ID_PIOA, 48 .type = CLK_TYPE_PERIPHERAL, 49}; 50static struct clk pioB_clk = { 51 .name = "pioB_clk", 52 .pmc_mask = 1 << AT91SAM9261_ID_PIOB, 53 .type = CLK_TYPE_PERIPHERAL, 54}; 55static struct clk pioC_clk = { 56 .name = "pioC_clk", 57 .pmc_mask = 1 << AT91SAM9261_ID_PIOC, 58 .type = CLK_TYPE_PERIPHERAL, 59}; 60static struct clk usart0_clk = { 61 .name = "usart0_clk", 62 .pmc_mask = 1 << AT91SAM9261_ID_US0, 63 .type = CLK_TYPE_PERIPHERAL, 64}; 65static struct clk usart1_clk = { 66 .name = "usart1_clk", 67 .pmc_mask = 1 << AT91SAM9261_ID_US1, 68 .type = CLK_TYPE_PERIPHERAL, 69}; 70static struct clk usart2_clk = { 71 .name = "usart2_clk", 72 .pmc_mask = 1 << AT91SAM9261_ID_US2, 73 .type = CLK_TYPE_PERIPHERAL, 74}; 75static struct clk mmc_clk = { 76 .name = "mci_clk", 77 .pmc_mask = 1 << AT91SAM9261_ID_MCI, 78 .type = CLK_TYPE_PERIPHERAL, 79}; 80static struct clk udc_clk = { 81 .name = "udc_clk", 82 .pmc_mask = 1 << AT91SAM9261_ID_UDP, 83 .type = CLK_TYPE_PERIPHERAL, 84}; 85static struct clk twi_clk = { 86 .name = "twi_clk", 87 .pmc_mask = 1 << AT91SAM9261_ID_TWI, 88 .type = CLK_TYPE_PERIPHERAL, 89}; 90static struct clk spi0_clk = { 91 .name = "spi0_clk", 92 .pmc_mask = 1 << AT91SAM9261_ID_SPI0, 93 .type = CLK_TYPE_PERIPHERAL, 94}; 95static struct clk spi1_clk = { 96 .name = "spi1_clk", 97 .pmc_mask = 1 << AT91SAM9261_ID_SPI1, 98 .type = CLK_TYPE_PERIPHERAL, 99}; 100static struct clk ssc0_clk = { 101 .name = "ssc0_clk", 102 .pmc_mask = 1 << AT91SAM9261_ID_SSC0, 103 .type = CLK_TYPE_PERIPHERAL, 104}; 105static struct clk ssc1_clk = { 106 .name = "ssc1_clk", 107 .pmc_mask = 1 << AT91SAM9261_ID_SSC1, 108 .type = CLK_TYPE_PERIPHERAL, 109}; 110static struct clk ssc2_clk = { 111 .name = "ssc2_clk", 112 .pmc_mask = 1 << AT91SAM9261_ID_SSC2, 113 .type = CLK_TYPE_PERIPHERAL, 114}; 115static struct clk tc0_clk = { 116 .name = "tc0_clk", 117 .pmc_mask = 1 << AT91SAM9261_ID_TC0, 118 .type = CLK_TYPE_PERIPHERAL, 119}; 120static struct clk tc1_clk = { 121 .name = "tc1_clk", 122 .pmc_mask = 1 << AT91SAM9261_ID_TC1, 123 .type = CLK_TYPE_PERIPHERAL, 124}; 125static struct clk tc2_clk = { 126 .name = "tc2_clk", 127 .pmc_mask = 1 << AT91SAM9261_ID_TC2, 128 .type = CLK_TYPE_PERIPHERAL, 129}; 130static struct clk ohci_clk = { 131 .name = "ohci_clk", 132 .pmc_mask = 1 << AT91SAM9261_ID_UHP, 133 .type = CLK_TYPE_PERIPHERAL, 134}; 135static struct clk lcdc_clk = { 136 .name = "lcdc_clk", 137 .pmc_mask = 1 << AT91SAM9261_ID_LCDC, 138 .type = CLK_TYPE_PERIPHERAL, 139}; 140 141static struct clk *periph_clocks[] __initdata = { 142 &pioA_clk, 143 &pioB_clk, 144 &pioC_clk, 145 &usart0_clk, 146 &usart1_clk, 147 &usart2_clk, 148 &mmc_clk, 149 &udc_clk, 150 &twi_clk, 151 &spi0_clk, 152 &spi1_clk, 153 &ssc0_clk, 154 &ssc1_clk, 155 &ssc2_clk, 156 &tc0_clk, 157 &tc1_clk, 158 &tc2_clk, 159 &ohci_clk, 160 &lcdc_clk, 161 // irq0 .. irq2 162}; 163 164/* 165 * The four programmable clocks. 166 * You must configure pin multiplexing to bring these signals out. 167 */ 168static struct clk pck0 = { 169 .name = "pck0", 170 .pmc_mask = AT91_PMC_PCK0, 171 .type = CLK_TYPE_PROGRAMMABLE, 172 .id = 0, 173}; 174static struct clk pck1 = { 175 .name = "pck1", 176 .pmc_mask = AT91_PMC_PCK1, 177 .type = CLK_TYPE_PROGRAMMABLE, 178 .id = 1, 179}; 180static struct clk pck2 = { 181 .name = "pck2", 182 .pmc_mask = AT91_PMC_PCK2, 183 .type = CLK_TYPE_PROGRAMMABLE, 184 .id = 2, 185}; 186static struct clk pck3 = { 187 .name = "pck3", 188 .pmc_mask = AT91_PMC_PCK3, 189 .type = CLK_TYPE_PROGRAMMABLE, 190 .id = 3, 191}; 192 193/* HClocks */ 194static struct clk hck0 = { 195 .name = "hck0", 196 .pmc_mask = AT91_PMC_HCK0, 197 .type = CLK_TYPE_SYSTEM, 198 .id = 0, 199}; 200static struct clk hck1 = { 201 .name = "hck1", 202 .pmc_mask = AT91_PMC_HCK1, 203 .type = CLK_TYPE_SYSTEM, 204 .id = 1, 205}; 206 207static void __init at91sam9261_register_clocks(void) 208{ 209 int i; 210 211 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) 212 clk_register(periph_clocks[i]); 213 214 clk_register(&pck0); 215 clk_register(&pck1); 216 clk_register(&pck2); 217 clk_register(&pck3); 218 219 clk_register(&hck0); 220 clk_register(&hck1); 221} 222 223/* -------------------------------------------------------------------- 224 * GPIO 225 * -------------------------------------------------------------------- */ 226 227static struct at91_gpio_bank at91sam9261_gpio[] = { 228 { 229 .id = AT91SAM9261_ID_PIOA, 230 .offset = AT91_PIOA, 231 .clock = &pioA_clk, 232 }, { 233 .id = AT91SAM9261_ID_PIOB, 234 .offset = AT91_PIOB, 235 .clock = &pioB_clk, 236 }, { 237 .id = AT91SAM9261_ID_PIOC, 238 .offset = AT91_PIOC, 239 .clock = &pioC_clk, 240 } 241}; 242 243static void at91sam9261_reset(void) 244{ 245 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); 246} 247 248 249/* -------------------------------------------------------------------- 250 * AT91SAM9261 processor initialization 251 * -------------------------------------------------------------------- */ 252 253void __init at91sam9261_initialize(unsigned long main_clock) 254{ 255 /* Map peripherals */ 256 iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); 257 258 at91_arch_reset = at91sam9261_reset; 259 at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) 260 | (1 << AT91SAM9261_ID_IRQ2); 261 262 /* Init clock subsystem */ 263 at91_clock_init(main_clock); 264 265 /* Register the processor-specific clocks */ 266 at91sam9261_register_clocks(); 267 268 /* Register GPIO subsystem */ 269 at91_gpio_init(at91sam9261_gpio, 3); 270} 271 272/* -------------------------------------------------------------------- 273 * Interrupt initialization 274 * -------------------------------------------------------------------- */ 275 276/* 277 * The default interrupt priority levels (0 = lowest, 7 = highest). 278 */ 279static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { 280 7, /* Advanced Interrupt Controller */ 281 7, /* System Peripherals */ 282 0, /* Parallel IO Controller A */ 283 0, /* Parallel IO Controller B */ 284 0, /* Parallel IO Controller C */ 285 0, 286 6, /* USART 0 */ 287 6, /* USART 1 */ 288 6, /* USART 2 */ 289 0, /* Multimedia Card Interface */ 290 4, /* USB Device Port */ 291 0, /* Two-Wire Interface */ 292 6, /* Serial Peripheral Interface 0 */ 293 6, /* Serial Peripheral Interface 1 */ 294 5, /* Serial Synchronous Controller 0 */ 295 5, /* Serial Synchronous Controller 1 */ 296 5, /* Serial Synchronous Controller 2 */ 297 0, /* Timer Counter 0 */ 298 0, /* Timer Counter 1 */ 299 0, /* Timer Counter 2 */ 300 3, /* USB Host port */ 301 3, /* LCD Controller */ 302 0, 303 0, 304 0, 305 0, 306 0, 307 0, 308 0, 309 0, /* Advanced Interrupt Controller */ 310 0, /* Advanced Interrupt Controller */ 311 0, /* Advanced Interrupt Controller */ 312}; 313 314void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) 315{ 316 if (!priority) 317 priority = at91sam9261_default_irq_priority; 318 319 /* Initialize the AIC interrupt controller */ 320 at91_aic_init(priority); 321 322 /* Enable GPIO interrupts */ 323 at91_gpio_irq_setup(); 324} 325