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