• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/arm/plat-brcm/
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