1/* 2 * arch/arm/mach-at91/at91sam9260.c 3 * 4 * Copyright (C) 2006 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/cpu.h> 18#include <asm/arch/at91sam9260.h> 19#include <asm/arch/at91_pmc.h> 20#include <asm/arch/at91_rstc.h> 21 22#include "generic.h" 23#include "clock.h" 24 25static struct map_desc at91sam9260_io_desc[] __initdata = { 26 { 27 .virtual = AT91_VA_BASE_SYS, 28 .pfn = __phys_to_pfn(AT91_BASE_SYS), 29 .length = SZ_16K, 30 .type = MT_DEVICE, 31 } 32}; 33 34static struct map_desc at91sam9260_sram_desc[] __initdata = { 35 { 36 .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, 37 .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), 38 .length = AT91SAM9260_SRAM0_SIZE, 39 .type = MT_DEVICE, 40 }, { 41 .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, 42 .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), 43 .length = AT91SAM9260_SRAM1_SIZE, 44 .type = MT_DEVICE, 45 } 46}; 47 48static struct map_desc at91sam9xe_sram_desc[] __initdata = { 49 { 50 .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE), 51 .type = MT_DEVICE, 52 } 53}; 54 55/* -------------------------------------------------------------------- 56 * Clocks 57 * -------------------------------------------------------------------- */ 58 59/* 60 * The peripheral clocks. 61 */ 62static struct clk pioA_clk = { 63 .name = "pioA_clk", 64 .pmc_mask = 1 << AT91SAM9260_ID_PIOA, 65 .type = CLK_TYPE_PERIPHERAL, 66}; 67static struct clk pioB_clk = { 68 .name = "pioB_clk", 69 .pmc_mask = 1 << AT91SAM9260_ID_PIOB, 70 .type = CLK_TYPE_PERIPHERAL, 71}; 72static struct clk pioC_clk = { 73 .name = "pioC_clk", 74 .pmc_mask = 1 << AT91SAM9260_ID_PIOC, 75 .type = CLK_TYPE_PERIPHERAL, 76}; 77static struct clk adc_clk = { 78 .name = "adc_clk", 79 .pmc_mask = 1 << AT91SAM9260_ID_ADC, 80 .type = CLK_TYPE_PERIPHERAL, 81}; 82static struct clk usart0_clk = { 83 .name = "usart0_clk", 84 .pmc_mask = 1 << AT91SAM9260_ID_US0, 85 .type = CLK_TYPE_PERIPHERAL, 86}; 87static struct clk usart1_clk = { 88 .name = "usart1_clk", 89 .pmc_mask = 1 << AT91SAM9260_ID_US1, 90 .type = CLK_TYPE_PERIPHERAL, 91}; 92static struct clk usart2_clk = { 93 .name = "usart2_clk", 94 .pmc_mask = 1 << AT91SAM9260_ID_US2, 95 .type = CLK_TYPE_PERIPHERAL, 96}; 97static struct clk mmc_clk = { 98 .name = "mci_clk", 99 .pmc_mask = 1 << AT91SAM9260_ID_MCI, 100 .type = CLK_TYPE_PERIPHERAL, 101}; 102static struct clk udc_clk = { 103 .name = "udc_clk", 104 .pmc_mask = 1 << AT91SAM9260_ID_UDP, 105 .type = CLK_TYPE_PERIPHERAL, 106}; 107static struct clk twi_clk = { 108 .name = "twi_clk", 109 .pmc_mask = 1 << AT91SAM9260_ID_TWI, 110 .type = CLK_TYPE_PERIPHERAL, 111}; 112static struct clk spi0_clk = { 113 .name = "spi0_clk", 114 .pmc_mask = 1 << AT91SAM9260_ID_SPI0, 115 .type = CLK_TYPE_PERIPHERAL, 116}; 117static struct clk spi1_clk = { 118 .name = "spi1_clk", 119 .pmc_mask = 1 << AT91SAM9260_ID_SPI1, 120 .type = CLK_TYPE_PERIPHERAL, 121}; 122static struct clk ssc_clk = { 123 .name = "ssc_clk", 124 .pmc_mask = 1 << AT91SAM9260_ID_SSC, 125 .type = CLK_TYPE_PERIPHERAL, 126}; 127static struct clk tc0_clk = { 128 .name = "tc0_clk", 129 .pmc_mask = 1 << AT91SAM9260_ID_TC0, 130 .type = CLK_TYPE_PERIPHERAL, 131}; 132static struct clk tc1_clk = { 133 .name = "tc1_clk", 134 .pmc_mask = 1 << AT91SAM9260_ID_TC1, 135 .type = CLK_TYPE_PERIPHERAL, 136}; 137static struct clk tc2_clk = { 138 .name = "tc2_clk", 139 .pmc_mask = 1 << AT91SAM9260_ID_TC2, 140 .type = CLK_TYPE_PERIPHERAL, 141}; 142static struct clk ohci_clk = { 143 .name = "ohci_clk", 144 .pmc_mask = 1 << AT91SAM9260_ID_UHP, 145 .type = CLK_TYPE_PERIPHERAL, 146}; 147static struct clk macb_clk = { 148 .name = "macb_clk", 149 .pmc_mask = 1 << AT91SAM9260_ID_EMAC, 150 .type = CLK_TYPE_PERIPHERAL, 151}; 152static struct clk isi_clk = { 153 .name = "isi_clk", 154 .pmc_mask = 1 << AT91SAM9260_ID_ISI, 155 .type = CLK_TYPE_PERIPHERAL, 156}; 157static struct clk usart3_clk = { 158 .name = "usart3_clk", 159 .pmc_mask = 1 << AT91SAM9260_ID_US3, 160 .type = CLK_TYPE_PERIPHERAL, 161}; 162static struct clk usart4_clk = { 163 .name = "usart4_clk", 164 .pmc_mask = 1 << AT91SAM9260_ID_US4, 165 .type = CLK_TYPE_PERIPHERAL, 166}; 167static struct clk usart5_clk = { 168 .name = "usart5_clk", 169 .pmc_mask = 1 << AT91SAM9260_ID_US5, 170 .type = CLK_TYPE_PERIPHERAL, 171}; 172static struct clk tc3_clk = { 173 .name = "tc3_clk", 174 .pmc_mask = 1 << AT91SAM9260_ID_TC3, 175 .type = CLK_TYPE_PERIPHERAL, 176}; 177static struct clk tc4_clk = { 178 .name = "tc4_clk", 179 .pmc_mask = 1 << AT91SAM9260_ID_TC4, 180 .type = CLK_TYPE_PERIPHERAL, 181}; 182static struct clk tc5_clk = { 183 .name = "tc5_clk", 184 .pmc_mask = 1 << AT91SAM9260_ID_TC5, 185 .type = CLK_TYPE_PERIPHERAL, 186}; 187 188static struct clk *periph_clocks[] __initdata = { 189 &pioA_clk, 190 &pioB_clk, 191 &pioC_clk, 192 &adc_clk, 193 &usart0_clk, 194 &usart1_clk, 195 &usart2_clk, 196 &mmc_clk, 197 &udc_clk, 198 &twi_clk, 199 &spi0_clk, 200 &spi1_clk, 201 &ssc_clk, 202 &tc0_clk, 203 &tc1_clk, 204 &tc2_clk, 205 &ohci_clk, 206 &macb_clk, 207 &isi_clk, 208 &usart3_clk, 209 &usart4_clk, 210 &usart5_clk, 211 &tc3_clk, 212 &tc4_clk, 213 &tc5_clk, 214 // irq0 .. irq2 215}; 216 217/* 218 * The two programmable clocks. 219 * You must configure pin multiplexing to bring these signals out. 220 */ 221static struct clk pck0 = { 222 .name = "pck0", 223 .pmc_mask = AT91_PMC_PCK0, 224 .type = CLK_TYPE_PROGRAMMABLE, 225 .id = 0, 226}; 227static struct clk pck1 = { 228 .name = "pck1", 229 .pmc_mask = AT91_PMC_PCK1, 230 .type = CLK_TYPE_PROGRAMMABLE, 231 .id = 1, 232}; 233 234static void __init at91sam9260_register_clocks(void) 235{ 236 int i; 237 238 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) 239 clk_register(periph_clocks[i]); 240 241 clk_register(&pck0); 242 clk_register(&pck1); 243} 244 245/* -------------------------------------------------------------------- 246 * GPIO 247 * -------------------------------------------------------------------- */ 248 249static struct at91_gpio_bank at91sam9260_gpio[] = { 250 { 251 .id = AT91SAM9260_ID_PIOA, 252 .offset = AT91_PIOA, 253 .clock = &pioA_clk, 254 }, { 255 .id = AT91SAM9260_ID_PIOB, 256 .offset = AT91_PIOB, 257 .clock = &pioB_clk, 258 }, { 259 .id = AT91SAM9260_ID_PIOC, 260 .offset = AT91_PIOC, 261 .clock = &pioC_clk, 262 } 263}; 264 265static void at91sam9260_reset(void) 266{ 267 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); 268} 269 270 271/* -------------------------------------------------------------------- 272 * AT91SAM9260 processor initialization 273 * -------------------------------------------------------------------- */ 274 275static void __init at91sam9xe_initialize(void) 276{ 277 unsigned long cidr, sram_size; 278 279 cidr = at91_sys_read(AT91_DBGU_CIDR); 280 281 switch (cidr & AT91_CIDR_SRAMSIZ) { 282 case AT91_CIDR_SRAMSIZ_32K: 283 sram_size = 2 * SZ_16K; 284 break; 285 case AT91_CIDR_SRAMSIZ_16K: 286 default: 287 sram_size = SZ_16K; 288 } 289 290 at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size; 291 at91sam9xe_sram_desc->length = sram_size; 292 293 iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); 294} 295 296void __init at91sam9260_initialize(unsigned long main_clock) 297{ 298 /* Map peripherals */ 299 iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); 300 301 if (cpu_is_at91sam9xe()) 302 at91sam9xe_initialize(); 303 else 304 iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); 305 306 at91_arch_reset = at91sam9260_reset; 307 at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) 308 | (1 << AT91SAM9260_ID_IRQ2); 309 310 /* Init clock subsystem */ 311 at91_clock_init(main_clock); 312 313 /* Register the processor-specific clocks */ 314 at91sam9260_register_clocks(); 315 316 /* Register GPIO subsystem */ 317 at91_gpio_init(at91sam9260_gpio, 3); 318} 319 320/* -------------------------------------------------------------------- 321 * Interrupt initialization 322 * -------------------------------------------------------------------- */ 323 324/* 325 * The default interrupt priority levels (0 = lowest, 7 = highest). 326 */ 327static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { 328 7, /* Advanced Interrupt Controller */ 329 7, /* System Peripherals */ 330 0, /* Parallel IO Controller A */ 331 0, /* Parallel IO Controller B */ 332 0, /* Parallel IO Controller C */ 333 0, /* Analog-to-Digital Converter */ 334 6, /* USART 0 */ 335 6, /* USART 1 */ 336 6, /* USART 2 */ 337 0, /* Multimedia Card Interface */ 338 4, /* USB Device Port */ 339 0, /* Two-Wire Interface */ 340 6, /* Serial Peripheral Interface 0 */ 341 6, /* Serial Peripheral Interface 1 */ 342 5, /* Serial Synchronous Controller */ 343 0, 344 0, 345 0, /* Timer Counter 0 */ 346 0, /* Timer Counter 1 */ 347 0, /* Timer Counter 2 */ 348 3, /* USB Host port */ 349 3, /* Ethernet */ 350 0, /* Image Sensor Interface */ 351 6, /* USART 3 */ 352 6, /* USART 4 */ 353 6, /* USART 5 */ 354 0, /* Timer Counter 3 */ 355 0, /* Timer Counter 4 */ 356 0, /* Timer Counter 5 */ 357 0, /* Advanced Interrupt Controller */ 358 0, /* Advanced Interrupt Controller */ 359 0, /* Advanced Interrupt Controller */ 360}; 361 362void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) 363{ 364 if (!priority) 365 priority = at91sam9260_default_irq_priority; 366 367 /* Initialize the AIC interrupt controller */ 368 at91_aic_init(priority); 369 370 /* Enable GPIO interrupts */ 371 at91_gpio_irq_setup(); 372} 373