1/* 2 * Northstar SoC main platform file. 3 * 4 */ 5 6#include <linux/types.h> 7#include <linux/init.h> 8#include <linux/kernel.h> 9#include <linux/io.h> 10#include <linux/ioport.h> 11#include <linux/platform_device.h> 12#include <linux/clk.h> 13#include <linux/delay.h> 14#include <linux/serial_8250.h> 15#include <linux/proc_fs.h> 16#include <linux/spi/spi.h> 17#include <linux/irq.h> 18#include <linux/spinlock.h> 19#include <asm/hardware/cache-l2x0.h> 20#include <asm/mach/map.h> 21#include <asm/clkdev.h> 22#include <asm/uaccess.h> 23#include <mach/clkdev.h> 24#include <mach/io_map.h> 25#include <plat/bsp.h> 26#include <plat/mpcore.h> 27#include <plat/plat-bcm5301x.h> 28 29#include <typedefs.h> 30#include <sbchipc.h> 31 32#ifdef CONFIG_SMP 33#include <asm/spinlock.h> 34#endif 35 36#define SOC_CHIPCOMON_A_REG_VA(offset) (SOC_CHIPCOMON_A_BASE_VA + (offset)) 37#define SOC_CHIPCOMON_A_INTSTATUS_VA SOC_CHIPCOMON_A_REG_VA(CC_INTSTATUS) 38#define SOC_CHIPCOMON_A_INTMASK_VA SOC_CHIPCOMON_A_REG_VA(CC_INTMASK) 39#define SOC_CHIPCOMON_A_GPIOINPUT_VA SOC_CHIPCOMON_A_REG_VA(CC_GPIOIN) 40#define SOC_CHIPCOMON_A_GPIOINTPOLARITY_VA SOC_CHIPCOMON_A_REG_VA(CC_GPIOPOL) 41#define SOC_CHIPCOMON_A_GPIOINTMASK_VA SOC_CHIPCOMON_A_REG_VA(CC_GPIOINTM) 42#define SOC_CHIPCOMON_A_GPIOEVENT_VA SOC_CHIPCOMON_A_REG_VA(CC_GPIOEVENT) 43#define SOC_CHIPCOMON_A_GPIOEVENTINTMASK_VA SOC_CHIPCOMON_A_REG_VA(CC_GPIOEVENTMASK) 44#define SOC_CHIPCOMON_A_GPIOEVENTINTPOLARITY_VA SOC_CHIPCOMON_A_REG_VA(CC_GPIOEVENTPOL) 45#define SOC_CHIPCOMON_A_CORECAP SOC_CHIPCOMON_A_REG_VA(CC_CAPABILITIES) 46#define SOC_CHIPCOMON_A_CORECTRL SOC_CHIPCOMON_A_REG_VA(0x08) 47#define SOC_CHIPCOMON_A_CLKDIV SOC_CHIPCOMON_A_REG_VA(CC_CLKDIV) 48 49#define SOC_CHIPCOMON_A_INTMASK_UART (1 << 6) 50#define SOC_CHIPCOMON_A_INTMASK_GPIO (1 << 0) 51 52#define SOC_CHIPCOMON_A_CORECAP_UARTCLKSEL_M 0x3 53#define SOC_CHIPCOMON_A_CORECAP_UARTCLKSEL_S 3 54 55#define SOC_CHIPCOMON_A_CORECTRL_UARTCLKOVR_M 0x1 56#define SOC_CHIPCOMON_A_CORECTRL_UARTCLKOVR_S 0 57 58#define SOC_CHIPCOMON_A_CLKDIV_UARTCLKDIV_M 0xFF 59#define SOC_CHIPCOMON_A_CLKDIV_UARTCLKDIV_S 0 60 61#define SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT (SOC_IDM_BASE_VA + 0x21408) 62 63#define SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT_UARTCLKSEL_M 0x1 64#define SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT_UARTCLKSEL_S 17 65 66#define PLAT_SM_CLR(val, field) ((val) & ~(field##_M << field##_S)) 67#define PLAT_SM_SET(val, field, field_val) ((val) | (((field_val) & field##_M) << field##_S)) 68#define PLAT_SM_GET(val, field) (((val) >> field##_S) & field##_M) 69#define PLAT_SM_ASSIGN(val, field, field_val) PLAT_SM_SET(PLAT_SM_CLR(val, field), field, field_val) 70 71static struct clk * _soc_refclk = NULL; 72 73#ifdef CONFIG_PLAT_UART_CLOCKS 74 75#if CONFIG_PLAT_CCA_UART0_DIVIDER <= 0xFFFF 76# define CONFIG_PLAT_CCA_UART0_DIVIDER_FLAG UPF_SPD_CUST 77#else 78# define CONFIG_PLAT_CCA_UART0_DIVIDER_FLAG 0 79#endif 80 81#if CONFIG_PLAT_CCA_UART1_DIVIDER <= 0xFFFF 82# define CONFIG_PLAT_CCA_UART1_DIVIDER_FLAG UPF_SPD_CUST 83#else 84# define CONFIG_PLAT_CCA_UART1_DIVIDER_FLAG 0 85#endif 86 87#if CONFIG_PLAT_CCB_UART0_DIVIDER <= 0xFFFF 88# define CONFIG_PLAT_CCB_UART0_DIVIDER_FLAG UPF_SPD_CUST 89#else 90# define CONFIG_PLAT_CCB_UART0_DIVIDER_FLAG 0 91#endif 92 93#else 94 95#define CONFIG_PLAT_CCA_UART0_DIVIDER 0 96#define CONFIG_PLAT_CCA_UART1_DIVIDER 0 97#define CONFIG_PLAT_CCB_UART0_DIVIDER 0 98 99#define CONFIG_PLAT_CCA_UART0_DIVIDER_FLAG 0 100#define CONFIG_PLAT_CCA_UART1_DIVIDER_FLAG 0 101#define CONFIG_PLAT_CCB_UART0_DIVIDER_FLAG 0 102 103#endif /* PLAT_UART_CLOCKS */ 104 105 106static struct plat_serial8250_port uart_ports[] = { 107 { 108 .type = PORT_16550, 109 .flags = UPF_FIXED_TYPE | UPF_SHARE_IRQ | CONFIG_PLAT_CCA_UART0_DIVIDER_FLAG, 110 .regshift = 0, 111 .iotype = UPIO_MEM, 112 .mapbase = (resource_size_t)(PLAT_UART1_PA), 113 .membase = (void __iomem *) PLAT_UART1_VA, 114 .irq = IRQ_CCA_UART, 115 .custom_divisor = CONFIG_PLAT_CCA_UART0_DIVIDER, 116 }, 117 { 118 .type = PORT_16550, 119 .flags = UPF_FIXED_TYPE | UPF_SHARE_IRQ | CONFIG_PLAT_CCA_UART1_DIVIDER_FLAG, 120 .regshift = 0, 121 .iotype = UPIO_MEM, 122 .mapbase = (resource_size_t)(PLAT_UART2_PA), 123 .membase = (void __iomem *) PLAT_UART2_VA, 124 .irq = IRQ_CCA_UART, 125 .custom_divisor = CONFIG_PLAT_CCA_UART1_DIVIDER, 126 }, 127#ifdef CONFIG_PLAT_MUX_CONSOLE_CCB 128 { 129 .type = PORT_16550, 130 .flags = UPF_FIXED_TYPE | CONFIG_PLAT_CCB_UART0_DIVIDER_FLAG, 131 .regshift = 2, /* Chipcommon B regs are 32-bit aligned */ 132 .iotype = UPIO_MEM, 133 .mapbase = (resource_size_t)(PLAT_UART0_PA), 134 .membase = (void __iomem *) PLAT_UART0_VA, 135 .irq = IRQ_CCB_UART0, 136 .custom_divisor = CONFIG_PLAT_CCB_UART0_DIVIDER, 137 }, 138#endif /* CONFIG_PLAT_MUX_CONSOLE_CCB */ 139 { .flags = 0, }, /* List terminatoir */ 140}; 141 142static struct platform_device platform_serial_device = { 143 .name = "serial8250", 144 .id = PLAT8250_DEV_PLATFORM, /* <linux/serial_8250.h> */ 145 .dev = { 146 .platform_data = uart_ports, 147 }, 148}; 149 150static struct platform_device platform_spi_master_device = { 151 .name = "bcm5301x-spi-master", 152 .id = 1, /* Bus number */ 153 .dev = { 154 .platform_data = NULL, /* Passed to driver */ 155 }, 156}; 157 158/* 159 * Map fix-mapped I/O that is needed before full MMU operation 160 */ 161void __init soc_map_io( struct clk * refclk ) 162{ 163 struct map_desc desc[2] ; 164 165 /* 166 * Map Chipcommon A & B to a fixed virtual location 167 * as these contain all the system UARTs, which are 168 * needed for low-level debugging, 169 * it have already been mapped from mach_desc earlier 170 * but that is undone from page_init() 171 */ 172 173 desc[0].virtual = IO_BASE_VA; 174 desc[0].pfn = __phys_to_pfn( IO_BASE_PA ); 175 desc[0].length = SZ_16M ; /* CCA+CCB: 0x18000000-0x18ffffff */ 176 desc[0].type = MT_DEVICE ; 177 178 iotable_init( desc, 1); 179 180 mpcore_map_io( ); 181 /* Save refclk for later use */ 182 _soc_refclk = refclk ; 183} 184 185static int soc_abort_handler(unsigned long addr, unsigned int fsr, 186 struct pt_regs *regs) 187{ 188 /* 189 * These happen for no good reason 190 * possibly left over from CFE 191 */ 192 printk( KERN_WARNING 193 "External imprecise Data abort at " 194 "addr=%#lx, fsr=%#x ignored.\n", 195 addr, fsr ); 196 197 /* Returning non-zero causes fault display and panic */ 198 return 0; 199} 200 201static void __init soc_aborts_enable(void) 202{ 203 u32 x; 204 205 /* Install our hook */ 206 hook_fault_code(16 + 6, soc_abort_handler, SIGBUS, 0, 207 "imprecise external abort"); 208 209 /* Enable external aborts - clear "A" bit in CPSR */ 210 211 /* Read CPSR */ 212 asm( "mrs %0,cpsr": "=&r" (x) : : ); 213 214 x &= ~ PSR_A_BIT ; 215 216 /* Update CPSR, affect bits 8-15 */ 217 asm( "msr cpsr_x,%0; nop; nop": : "r" (x) : "cc" ); 218 219} 220 221#ifdef CONFIG_PLAT_CCA_GPIO_IRQ 222 223#include <asm/gpio.h> 224 225struct soc_cca_gpio_irq_data { 226 unsigned int type; 227}; 228 229static void soc_cca_gpio_handle(void) 230{ 231 uint32 mask = readl(SOC_CHIPCOMON_A_GPIOINTMASK_VA); 232 uint32 polarity = readl(SOC_CHIPCOMON_A_GPIOINTPOLARITY_VA); 233 uint32 input = readl(SOC_CHIPCOMON_A_GPIOINPUT_VA); 234 uint32 event = readl(SOC_CHIPCOMON_A_GPIOEVENT_VA); 235 uint32 eventmask = readl(SOC_CHIPCOMON_A_GPIOEVENTINTMASK_VA); 236 int gpio; 237 238 for (gpio = 0; gpio < IRQ_CCA_GPIO_N; ++gpio) { 239 uint32 gpio_bit = (1 << gpio); 240 uint32 level_triggered = ((input ^ polarity) & mask & gpio_bit); 241 uint32 edge_triggered = (event & eventmask & gpio_bit); 242 243 if (level_triggered || edge_triggered) { 244 generic_handle_irq(IRQ_CCA_GPIO(gpio)); 245 } 246 } 247} 248 249static void soc_cca_irq_handler(unsigned int irq, struct irq_desc *desc) 250{ 251 uint32 status = readl(SOC_CHIPCOMON_A_INTSTATUS_VA); 252 253 desc->chip->mask(irq); 254 desc->chip->ack(irq); 255 256 if (status & SOC_CHIPCOMON_A_INTMASK_UART) { 257 generic_handle_irq(IRQ_CCA_UART); 258 } 259 260 if (status & SOC_CHIPCOMON_A_INTMASK_GPIO) { 261 soc_cca_gpio_handle(); 262 } 263 264 desc->chip->unmask(irq); 265} 266 267static void soc_cca_gpio_irq_update_type(unsigned int irq) 268{ 269 int gpio = irq_to_gpio(irq); 270 struct soc_cca_gpio_irq_data *pdata; 271 uint32 gpio_bit; 272 unsigned int type; 273 274 if (gpio < 0) { 275 return; 276 } 277 278 pdata = get_irq_data(irq); 279 type = pdata->type; 280 gpio_bit = (1 << gpio); 281 282 if (type & IRQ_TYPE_LEVEL_LOW) { 283 writel(readl(SOC_CHIPCOMON_A_GPIOINTPOLARITY_VA) | gpio_bit, 284 SOC_CHIPCOMON_A_GPIOINTPOLARITY_VA); 285 } else if (type & IRQ_TYPE_LEVEL_HIGH) { 286 writel(readl(SOC_CHIPCOMON_A_GPIOINTPOLARITY_VA) & ~gpio_bit, 287 SOC_CHIPCOMON_A_GPIOINTPOLARITY_VA); 288 } else if (type & IRQ_TYPE_EDGE_FALLING) { 289 writel(readl(SOC_CHIPCOMON_A_GPIOEVENTINTPOLARITY_VA) | gpio_bit, 290 SOC_CHIPCOMON_A_GPIOEVENTINTPOLARITY_VA); 291 } else if (type & IRQ_TYPE_EDGE_RISING) { 292 writel(readl(SOC_CHIPCOMON_A_GPIOEVENTINTPOLARITY_VA) & ~gpio_bit, 293 SOC_CHIPCOMON_A_GPIOEVENTINTPOLARITY_VA); 294 } 295} 296 297static void soc_cca_gpio_irq_ack(unsigned int irq) 298{ 299 int gpio = irq_to_gpio(irq); 300 301 if (gpio < 0) { 302 return; 303 } 304 305 writel((1 << gpio), SOC_CHIPCOMON_A_GPIOEVENT_VA); 306} 307 308static void soc_cca_gpio_irq_maskunmask(unsigned int irq, bool mask) 309{ 310 int gpio = irq_to_gpio(irq); 311 struct soc_cca_gpio_irq_data *data; 312 uint32 mask_addr; 313 uint32 gpio_bit; 314 uint32 val; 315 316 if (gpio < 0) { 317 return; 318 } 319 320 data = get_irq_data(irq); 321 gpio_bit = (1 << gpio); 322 323 if (data->type & IRQ_TYPE_EDGE_BOTH) { 324 mask_addr = SOC_CHIPCOMON_A_GPIOEVENTINTMASK_VA; 325 } else { 326 mask_addr = SOC_CHIPCOMON_A_GPIOINTMASK_VA; 327 } 328 329 val = readl(mask_addr); 330 if (mask) { 331 val &= ~gpio_bit; 332 } else { 333 val |= gpio_bit; 334 } 335 writel(val, mask_addr); 336} 337 338static void soc_cca_gpio_irq_mask(unsigned int irq) 339{ 340 soc_cca_gpio_irq_maskunmask(irq, true); 341} 342 343static void soc_cca_gpio_irq_unmask(unsigned int irq) 344{ 345 soc_cca_gpio_irq_maskunmask(irq, false); 346} 347 348static void soc_cca_gpio_irq_enable(unsigned int irq) 349{ 350 soc_cca_gpio_irq_update_type(irq); 351 soc_cca_gpio_irq_ack(irq); 352 soc_cca_gpio_irq_unmask(irq); 353} 354 355static void soc_cca_gpio_irq_disable(unsigned int irq) 356{ 357 soc_cca_gpio_irq_mask(irq); 358} 359 360static int soc_cca_gpio_irq_set_type(unsigned int irq, unsigned int type) 361{ 362 struct soc_cca_gpio_irq_data *pdata; 363 364 if (irq_to_gpio(irq) < 0) { 365 return -EINVAL; 366 } 367 368 if ((type & IRQ_TYPE_SENSE_MASK) == 0) { 369 return -EINVAL; 370 } 371 372 pdata = get_irq_data(irq); 373 pdata->type = type & IRQ_TYPE_SENSE_MASK; 374 375 return 0; 376} 377 378static struct irq_chip cca_gpio_irq_chip = { 379 .name = "CCA_GPIO", 380 .ack = soc_cca_gpio_irq_ack, 381 .mask = soc_cca_gpio_irq_mask, 382 .unmask = soc_cca_gpio_irq_unmask, 383 .enable = soc_cca_gpio_irq_enable, 384 .disable = soc_cca_gpio_irq_disable, 385 .set_type = soc_cca_gpio_irq_set_type, 386}; 387 388static void __init soc_cca_irq_enable(void) 389{ 390 static struct soc_cca_gpio_irq_data irq_data[IRQ_CCA_GPIO_N]; 391 int irq; 392 393 for (irq = IRQ_CCA_FIRST; irq <= IRQ_CCA_LAST; ++irq) { 394 if (irq == IRQ_CCA_UART) { 395 set_irq_chip(irq, NULL); 396 } else { 397 set_irq_chip(irq, &cca_gpio_irq_chip); 398 set_irq_data(irq, &irq_data[irq_to_gpio(irq)]); 399 } 400 set_irq_handler(irq, handle_level_irq); 401 set_irq_flags(irq, IRQF_VALID); 402 } 403 404 set_irq_chained_handler(IRQ_CCA, soc_cca_irq_handler); 405 406 printk(KERN_INFO"%d IRQ chained: UART, GPIOs\n", IRQ_CCA); 407} 408 409#else 410 411static void __init soc_cca_irq_enable(void) 412{ 413} 414 415#endif /* CONFIG_PLAT_CCA_GPIO_IRQ */ 416 417/* 418 * This SoC relies on MPCORE GIC interrupt controller 419 */ 420void __init soc_init_irq( void ) 421{ 422 mpcore_init_gic(); 423 soc_aborts_enable(); 424 soc_cca_irq_enable(); 425} 426 427/* 428 * Initialize SoC timers 429 */ 430void __init soc_init_timer( void ) 431{ 432 unsigned long periphclk_freq; 433 struct clk * clk ; 434 435 /* Clocks need to be setup early */ 436 soc_dmu_init( _soc_refclk ); 437 soc_cru_init( _soc_refclk ); 438 439 /* get mpcore PERIPHCLK from clock modules */ 440 clk = clk_get_sys( NULL, "periph_clk"); 441 BUG_ON( IS_ERR_OR_NULL (clk) ); 442 periphclk_freq = clk_get_rate( clk ); 443 BUG_ON( !periphclk_freq ); 444 445 /* Fire up the global MPCORE timer */ 446 mpcore_init_timer( periphclk_freq ); 447 448} 449 450static void __init soc_config_cca_uart_clock(void) 451{ 452#if defined(CONFIG_PLAT_CCA_UART_CLK_DEFAULT) 453 /* Do nothing. Use what already set. */ 454#elif defined(CONFIG_PLAT_CCA_UART_CLK_INTERNAL_OVERRIDE) 455 writel(PLAT_SM_SET(readl(SOC_CHIPCOMON_A_CORECTRL), SOC_CHIPCOMON_A_CORECTRL_UARTCLKOVR, 1), 456 SOC_CHIPCOMON_A_CORECTRL); 457#elif defined(CONFIG_PLAT_CCA_UART_CLK_INTERNAL_DIVIDER) 458 writel(PLAT_SM_ASSIGN(readl(SOC_CHIPCOMON_A_CLKDIV), SOC_CHIPCOMON_A_CLKDIV_UARTCLKDIV, CONFIG_PLAT_CCA_UART_CLK_INTERNAL_DIVIDER_VAL), 459 SOC_CHIPCOMON_A_CLKDIV); 460 writel(PLAT_SM_CLR(readl(SOC_CHIPCOMON_A_CORECTRL), SOC_CHIPCOMON_A_CORECTRL_UARTCLKOVR), 461 SOC_CHIPCOMON_A_CORECTRL); 462 writel(PLAT_SM_SET(readl(SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT), SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT_UARTCLKSEL, 1), 463 SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT); 464#elif defined(CONFIG_PLAT_CCA_UART_CLK_EXTERNAL) 465 writel(PLAT_SM_CLR(readl(SOC_CHIPCOMON_A_CORECTRL), SOC_CHIPCOMON_A_CORECTRL_UARTCLKOVR), 466 SOC_CHIPCOMON_A_CORECTRL); 467 writel(PLAT_SM_CLR(readl(SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT), SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT_UARTCLKSEL), 468 SOC_APBX_IDM_IDM_IO_CONTROL_DIRECT); 469#endif 470} 471 472static void __init soc_get_uart_clk_rate(u32 *clk_rate_cca, u32 *clk_rate_ccb) 473{ 474 struct clk *clk_ext = _soc_refclk; 475 struct clk *clk_int = clk_get_sys(NULL, "iproc_slow_clk"); 476 u32 clk_rate_int = clk_get_rate(clk_int); 477 u32 UARTClkSel = PLAT_SM_GET(readl(SOC_CHIPCOMON_A_CORECAP), SOC_CHIPCOMON_A_CORECAP_UARTCLKSEL); 478 u32 UARTClkOvr = PLAT_SM_GET(readl(SOC_CHIPCOMON_A_CORECTRL), SOC_CHIPCOMON_A_CORECTRL_UARTCLKOVR); 479 u32 UARTClkDiv = PLAT_SM_GET(readl(SOC_CHIPCOMON_A_CLKDIV), SOC_CHIPCOMON_A_CLKDIV_UARTCLKDIV); 480 481 BUG_ON(!clk_int); 482 BUG_ON(!clk_ext); 483 BUG_ON(UARTClkSel > 1); 484 485 if (UARTClkDiv == 0) { 486 UARTClkDiv = 0x100; 487 } 488 489 if (UARTClkOvr) { 490 /* internal reference clock source */ 491 *clk_rate_cca = clk_rate_int; 492 } else if (UARTClkSel) { 493 /* internal reference clock source with applied divider */ 494 *clk_rate_cca = clk_rate_int / UARTClkDiv; 495 } else { 496 /* external reference clock source */ 497 *clk_rate_cca = clk_get_rate(clk_ext); 498 } 499 500 *clk_rate_ccb = clk_rate_int; 501 502 printk(KERN_INFO "CCA UART Clock Config: Sel=%d Ovr=%d Div=%d\n", 503 UARTClkSel, UARTClkOvr, UARTClkDiv); 504 printk(KERN_INFO "CCA UART Clock rate %uHz CCB UART Clock rate %uHz\n", 505 *clk_rate_cca, *clk_rate_ccb); 506} 507 508static void __init soc_fixup_uart_ports(void) 509{ 510 u32 clk_rate_cca, clk_rate_ccb; 511 unsigned i; 512 513 soc_config_cca_uart_clock(); 514 515 soc_get_uart_clk_rate(&clk_rate_cca, &clk_rate_ccb); 516 517 for (i = 0; i < ARRAY_SIZE(uart_ports); i++) { 518 /* Last empty entry */ 519 if (uart_ports[i].flags == 0) 520 break; 521 522 if (uart_ports[i].irq == 0) 523 uart_ports[i].flags |= UPF_AUTO_IRQ; 524 525 /* UART clock rate */ 526 uart_ports[i].uartclk = (uart_ports[i].irq == IRQ_CCA_UART) ? 527 clk_rate_cca : clk_rate_ccb; 528 } 529} 530 531/* 532 * Install all other SoC device drivers 533 * that are not automatically discoverable. 534 */ 535void __init soc_add_devices( void ) 536{ 537 u32 i; 538 539 /* Fixup UART port structure */ 540 soc_fixup_uart_ports(); 541 542 /* Install SoC devices in the system: uarts */ 543 platform_device_register( & platform_serial_device ); 544 545 /* Install SoC devices in the system: SPI master */ 546 platform_device_register( & platform_spi_master_device ); 547 548 /* Enable UART interrupt in ChipcommonA */ 549 i = readl( SOC_CHIPCOMON_A_BASE_VA + 0x24 ); 550 i |= SOC_CHIPCOMON_A_INTMASK_UART; 551 writel( i, SOC_CHIPCOMON_A_BASE_VA + 0x24 ); 552 553#ifdef CONFIG_PLAT_CCA_GPIO_IRQ 554 /* Enable GPIO interrupts in ChipcommonA */ 555 i = readl( SOC_CHIPCOMON_A_INTMASK_VA ); 556 i |= SOC_CHIPCOMON_A_INTMASK_GPIO; 557 writel( i, SOC_CHIPCOMON_A_INTMASK_VA ); 558#endif /* CONFIG_PLAT_CCA_GPIO_IRQ */ 559} 560 561void plat_wake_secondary_cpu( unsigned cpu, void (* _sec_entry_va)(void) ) 562{ 563 void __iomem * rombase = NULL; 564 phys_addr_t lut_pa; 565 u32 offset, mask; 566 u32 val ; 567 568 mask = ( 1UL << PAGE_SHIFT) -1 ; 569 570 lut_pa = SOC_ROM_BASE_PA & ~mask ; 571 offset = SOC_ROM_BASE_PA & mask ; 572 offset += SOC_ROM_LUT_OFF; 573 574 rombase = ioremap( lut_pa, PAGE_SIZE ); 575 if( rombase == NULL ) 576 return; 577 val = virt_to_phys( _sec_entry_va ); 578 579 writel( val, rombase + offset ); 580 581 smp_wmb(); /* probably not needed - io regs are not cached */ 582 583#ifdef CONFIG_SMP 584 dsb_sev(); /* Exit WFI */ 585#endif 586 mb(); 587 588 iounmap( rombase ); 589} 590 591#ifdef CONFIG_CACHE_L310 592/* 593 * SoC initialization that need to be done early, 594 * e.g. L2 cache, clock, I/O pin mux, power management 595 */ 596static int __init bcm5301_pl310_init( void ) 597{ 598 void __iomem *l2cache_base; 599 u32 auxctl_val, auxctl_msk ; 600 extern void __init l310_init( void __iomem *, u32, u32, int ); 601 602 /* Default AUXCTL modifiers */ 603 auxctl_val = 0UL; 604 auxctl_msk = ~0UL ; 605 606 /* Customize AUXCTL */ 607 auxctl_val |= 0 << 0 ; /* Full line of zero Enable - requires A9 cfg */ 608 auxctl_val |= 1 << 25; /* Cache replacement policy - round robin */ 609 auxctl_val |= 1 << 29; /* Instruction prefetch enable */ 610 auxctl_val |= 1 << 28; /* Data prefetch enable */ 611 auxctl_val |= 1 << 30; /* Early BRESP enable */ 612 613 if (ACP_WAR_ENAB() || arch_is_coherent()) 614 auxctl_val |= 1 << 11; /* Store buffer device limitation enable */ 615 616 l2cache_base = ioremap( L2CC_BASE_PA, SZ_4K ); 617 618 /* Configure using default aux control value */ 619 if( l2cache_base != NULL ) 620 l310_init( l2cache_base, auxctl_val, auxctl_msk, 32 ); 621 622 return 0; 623} 624early_initcall( bcm5301_pl310_init ); 625#endif 626