1/* 2 * Chip-specific setup code for the AT91SAM9G45 family 3 * 4 * Copyright (C) 2009 Atmel Corporation. 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/at91sam9g45.h> 20#include <mach/at91_pmc.h> 21#include <mach/at91_rstc.h> 22#include <mach/at91_shdwc.h> 23#include <mach/cpu.h> 24 25#include "generic.h" 26#include "clock.h" 27 28static struct map_desc at91sam9g45_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 .virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE, 36 .pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE), 37 .length = AT91SAM9G45_SRAM_SIZE, 38 .type = MT_DEVICE, 39 } 40}; 41 42/* -------------------------------------------------------------------- 43 * Clocks 44 * -------------------------------------------------------------------- */ 45 46/* 47 * The peripheral clocks. 48 */ 49static struct clk pioA_clk = { 50 .name = "pioA_clk", 51 .pmc_mask = 1 << AT91SAM9G45_ID_PIOA, 52 .type = CLK_TYPE_PERIPHERAL, 53}; 54static struct clk pioB_clk = { 55 .name = "pioB_clk", 56 .pmc_mask = 1 << AT91SAM9G45_ID_PIOB, 57 .type = CLK_TYPE_PERIPHERAL, 58}; 59static struct clk pioC_clk = { 60 .name = "pioC_clk", 61 .pmc_mask = 1 << AT91SAM9G45_ID_PIOC, 62 .type = CLK_TYPE_PERIPHERAL, 63}; 64static struct clk pioDE_clk = { 65 .name = "pioDE_clk", 66 .pmc_mask = 1 << AT91SAM9G45_ID_PIODE, 67 .type = CLK_TYPE_PERIPHERAL, 68}; 69static struct clk usart0_clk = { 70 .name = "usart0_clk", 71 .pmc_mask = 1 << AT91SAM9G45_ID_US0, 72 .type = CLK_TYPE_PERIPHERAL, 73}; 74static struct clk usart1_clk = { 75 .name = "usart1_clk", 76 .pmc_mask = 1 << AT91SAM9G45_ID_US1, 77 .type = CLK_TYPE_PERIPHERAL, 78}; 79static struct clk usart2_clk = { 80 .name = "usart2_clk", 81 .pmc_mask = 1 << AT91SAM9G45_ID_US2, 82 .type = CLK_TYPE_PERIPHERAL, 83}; 84static struct clk usart3_clk = { 85 .name = "usart3_clk", 86 .pmc_mask = 1 << AT91SAM9G45_ID_US3, 87 .type = CLK_TYPE_PERIPHERAL, 88}; 89static struct clk mmc0_clk = { 90 .name = "mci0_clk", 91 .pmc_mask = 1 << AT91SAM9G45_ID_MCI0, 92 .type = CLK_TYPE_PERIPHERAL, 93}; 94static struct clk twi0_clk = { 95 .name = "twi0_clk", 96 .pmc_mask = 1 << AT91SAM9G45_ID_TWI0, 97 .type = CLK_TYPE_PERIPHERAL, 98}; 99static struct clk twi1_clk = { 100 .name = "twi1_clk", 101 .pmc_mask = 1 << AT91SAM9G45_ID_TWI1, 102 .type = CLK_TYPE_PERIPHERAL, 103}; 104static struct clk spi0_clk = { 105 .name = "spi0_clk", 106 .pmc_mask = 1 << AT91SAM9G45_ID_SPI0, 107 .type = CLK_TYPE_PERIPHERAL, 108}; 109static struct clk spi1_clk = { 110 .name = "spi1_clk", 111 .pmc_mask = 1 << AT91SAM9G45_ID_SPI1, 112 .type = CLK_TYPE_PERIPHERAL, 113}; 114static struct clk ssc0_clk = { 115 .name = "ssc0_clk", 116 .pmc_mask = 1 << AT91SAM9G45_ID_SSC0, 117 .type = CLK_TYPE_PERIPHERAL, 118}; 119static struct clk ssc1_clk = { 120 .name = "ssc1_clk", 121 .pmc_mask = 1 << AT91SAM9G45_ID_SSC1, 122 .type = CLK_TYPE_PERIPHERAL, 123}; 124static struct clk tcb0_clk = { 125 .name = "tcb0_clk", 126 .pmc_mask = 1 << AT91SAM9G45_ID_TCB, 127 .type = CLK_TYPE_PERIPHERAL, 128}; 129static struct clk pwm_clk = { 130 .name = "pwm_clk", 131 .pmc_mask = 1 << AT91SAM9G45_ID_PWMC, 132 .type = CLK_TYPE_PERIPHERAL, 133}; 134static struct clk tsc_clk = { 135 .name = "tsc_clk", 136 .pmc_mask = 1 << AT91SAM9G45_ID_TSC, 137 .type = CLK_TYPE_PERIPHERAL, 138}; 139static struct clk dma_clk = { 140 .name = "dma_clk", 141 .pmc_mask = 1 << AT91SAM9G45_ID_DMA, 142 .type = CLK_TYPE_PERIPHERAL, 143}; 144static struct clk uhphs_clk = { 145 .name = "uhphs_clk", 146 .pmc_mask = 1 << AT91SAM9G45_ID_UHPHS, 147 .type = CLK_TYPE_PERIPHERAL, 148}; 149static struct clk lcdc_clk = { 150 .name = "lcdc_clk", 151 .pmc_mask = 1 << AT91SAM9G45_ID_LCDC, 152 .type = CLK_TYPE_PERIPHERAL, 153}; 154static struct clk ac97_clk = { 155 .name = "ac97_clk", 156 .pmc_mask = 1 << AT91SAM9G45_ID_AC97C, 157 .type = CLK_TYPE_PERIPHERAL, 158}; 159static struct clk macb_clk = { 160 .name = "macb_clk", 161 .pmc_mask = 1 << AT91SAM9G45_ID_EMAC, 162 .type = CLK_TYPE_PERIPHERAL, 163}; 164static struct clk isi_clk = { 165 .name = "isi_clk", 166 .pmc_mask = 1 << AT91SAM9G45_ID_ISI, 167 .type = CLK_TYPE_PERIPHERAL, 168}; 169static struct clk udphs_clk = { 170 .name = "udphs_clk", 171 .pmc_mask = 1 << AT91SAM9G45_ID_UDPHS, 172 .type = CLK_TYPE_PERIPHERAL, 173}; 174static struct clk mmc1_clk = { 175 .name = "mci1_clk", 176 .pmc_mask = 1 << AT91SAM9G45_ID_MCI1, 177 .type = CLK_TYPE_PERIPHERAL, 178}; 179 180/* Video decoder clock - Only for sam9m10/sam9m11 */ 181static struct clk vdec_clk = { 182 .name = "vdec_clk", 183 .pmc_mask = 1 << AT91SAM9G45_ID_VDEC, 184 .type = CLK_TYPE_PERIPHERAL, 185}; 186 187/* One additional fake clock for ohci */ 188static struct clk ohci_clk = { 189 .name = "ohci_clk", 190 .pmc_mask = 0, 191 .type = CLK_TYPE_PERIPHERAL, 192 .parent = &uhphs_clk, 193}; 194 195/* One additional fake clock for second TC block */ 196static struct clk tcb1_clk = { 197 .name = "tcb1_clk", 198 .pmc_mask = 0, 199 .type = CLK_TYPE_PERIPHERAL, 200 .parent = &tcb0_clk, 201}; 202 203static struct clk *periph_clocks[] __initdata = { 204 &pioA_clk, 205 &pioB_clk, 206 &pioC_clk, 207 &pioDE_clk, 208 &usart0_clk, 209 &usart1_clk, 210 &usart2_clk, 211 &usart3_clk, 212 &mmc0_clk, 213 &twi0_clk, 214 &twi1_clk, 215 &spi0_clk, 216 &spi1_clk, 217 &ssc0_clk, 218 &ssc1_clk, 219 &tcb0_clk, 220 &pwm_clk, 221 &tsc_clk, 222 &dma_clk, 223 &uhphs_clk, 224 &lcdc_clk, 225 &ac97_clk, 226 &macb_clk, 227 &isi_clk, 228 &udphs_clk, 229 &mmc1_clk, 230 // irq0 231 &ohci_clk, 232 &tcb1_clk, 233}; 234 235/* 236 * The two programmable clocks. 237 * You must configure pin multiplexing to bring these signals out. 238 */ 239static struct clk pck0 = { 240 .name = "pck0", 241 .pmc_mask = AT91_PMC_PCK0, 242 .type = CLK_TYPE_PROGRAMMABLE, 243 .id = 0, 244}; 245static struct clk pck1 = { 246 .name = "pck1", 247 .pmc_mask = AT91_PMC_PCK1, 248 .type = CLK_TYPE_PROGRAMMABLE, 249 .id = 1, 250}; 251 252static void __init at91sam9g45_register_clocks(void) 253{ 254 int i; 255 256 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) 257 clk_register(periph_clocks[i]); 258 259 if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11()) 260 clk_register(&vdec_clk); 261 262 clk_register(&pck0); 263 clk_register(&pck1); 264} 265 266/* -------------------------------------------------------------------- 267 * GPIO 268 * -------------------------------------------------------------------- */ 269 270static struct at91_gpio_bank at91sam9g45_gpio[] = { 271 { 272 .id = AT91SAM9G45_ID_PIOA, 273 .offset = AT91_PIOA, 274 .clock = &pioA_clk, 275 }, { 276 .id = AT91SAM9G45_ID_PIOB, 277 .offset = AT91_PIOB, 278 .clock = &pioB_clk, 279 }, { 280 .id = AT91SAM9G45_ID_PIOC, 281 .offset = AT91_PIOC, 282 .clock = &pioC_clk, 283 }, { 284 .id = AT91SAM9G45_ID_PIODE, 285 .offset = AT91_PIOD, 286 .clock = &pioDE_clk, 287 }, { 288 .id = AT91SAM9G45_ID_PIODE, 289 .offset = AT91_PIOE, 290 .clock = &pioDE_clk, 291 } 292}; 293 294static void at91sam9g45_reset(void) 295{ 296 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); 297} 298 299static void at91sam9g45_poweroff(void) 300{ 301 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); 302} 303 304 305/* -------------------------------------------------------------------- 306 * AT91SAM9G45 processor initialization 307 * -------------------------------------------------------------------- */ 308 309void __init at91sam9g45_initialize(unsigned long main_clock) 310{ 311 /* Map peripherals */ 312 iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc)); 313 314 at91_arch_reset = at91sam9g45_reset; 315 pm_power_off = at91sam9g45_poweroff; 316 at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); 317 318 /* Init clock subsystem */ 319 at91_clock_init(main_clock); 320 321 /* Register the processor-specific clocks */ 322 at91sam9g45_register_clocks(); 323 324 /* Register GPIO subsystem */ 325 at91_gpio_init(at91sam9g45_gpio, 5); 326} 327 328/* -------------------------------------------------------------------- 329 * Interrupt initialization 330 * -------------------------------------------------------------------- */ 331 332/* 333 * The default interrupt priority levels (0 = lowest, 7 = highest). 334 */ 335static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { 336 7, /* Advanced Interrupt Controller (FIQ) */ 337 7, /* System Peripherals */ 338 1, /* Parallel IO Controller A */ 339 1, /* Parallel IO Controller B */ 340 1, /* Parallel IO Controller C */ 341 1, /* Parallel IO Controller D and E */ 342 0, 343 5, /* USART 0 */ 344 5, /* USART 1 */ 345 5, /* USART 2 */ 346 5, /* USART 3 */ 347 0, /* Multimedia Card Interface 0 */ 348 6, /* Two-Wire Interface 0 */ 349 6, /* Two-Wire Interface 1 */ 350 5, /* Serial Peripheral Interface 0 */ 351 5, /* Serial Peripheral Interface 1 */ 352 4, /* Serial Synchronous Controller 0 */ 353 4, /* Serial Synchronous Controller 1 */ 354 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ 355 0, /* Pulse Width Modulation Controller */ 356 0, /* Touch Screen Controller */ 357 0, /* DMA Controller */ 358 2, /* USB Host High Speed port */ 359 3, /* LDC Controller */ 360 5, /* AC97 Controller */ 361 3, /* Ethernet */ 362 0, /* Image Sensor Interface */ 363 2, /* USB Device High speed port */ 364 0, 365 0, /* Multimedia Card Interface 1 */ 366 0, 367 0, /* Advanced Interrupt Controller (IRQ0) */ 368}; 369 370void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS]) 371{ 372 if (!priority) 373 priority = at91sam9g45_default_irq_priority; 374 375 /* Initialize the AIC interrupt controller */ 376 at91_aic_init(priority); 377 378 /* Enable GPIO interrupts */ 379 at91_gpio_irq_setup(); 380} 381