attempt to register additional cores
[AROS.git] / arch / arm-native / kernel / platform_bcm2708.c
blob8b2d27d46bff3cf9d4d05bded4d1c5eb35fb714f
1 /*
2 Copyright © 2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/kernel.h>
7 #include <aros/symbolsets.h>
9 #include <proto/exec.h>
11 #include <inttypes.h>
12 #include <hardware/intbits.h>
14 #include "kernel_intern.h"
15 #include "kernel_base.h"
16 #include "kernel_cpu.h"
17 #include "kernel_interrupts.h"
18 #include "kernel_intr.h"
20 extern void cpu_Register(void);
22 static void bcm2708_init(void)
27 static void bcm2708_toggle_led(int LED, int state)
29 if (__arm_periiobase == BCM2836_PERIPHYSBASE)
31 int pin = 35;
32 IPTR gpiofunc = GPCLR1;
34 if (LED == ARM_LED_ACTIVITY)
35 pin = 47;
37 if (state == ARM_LED_ON)
38 gpiofunc = GPSET1;
40 *(volatile unsigned int *)gpiofunc = (1 << (pin-32));
42 else
44 // RasPi 1 only allows us to toggle the activity LED
45 if (state)
46 *(volatile unsigned int *)GPCLR0 = (1 << 16);
47 else
48 *(volatile unsigned int *)GPSET0 = (1 << 16);
52 static void bcm2708_gputimer_handler(unsigned int timerno, void *unused1)
54 unsigned int stc, cs;
56 D(bug("[KRN:BCM2708] %s(%d)\n", __PRETTY_FUNCTION__, timerno));
58 /* Aknowledge our timer interrupt */
59 cs = *((volatile unsigned int *)(SYSTIMER_CS));
60 cs &= ~ (1 << timerno);
61 *((volatile unsigned int *)(SYSTIMER_CS)) = cs;
63 /* Signal the Exec VBlankServer */
64 if (SysBase && (SysBase->IDNestCnt < 0)) {
65 core_Cause(INTB_VERTB, 1L << INTB_VERTB);
68 /* Refresh our timer interrupt */
69 stc = *((volatile unsigned int *)(SYSTIMER_CLO));
70 stc += VBLANK_INTERVAL;
71 *((volatile unsigned int *)(SYSTIMER_CS)) = cs | (1 << timerno);
72 *((volatile unsigned int *)(SYSTIMER_C0 + (timerno * 4))) = stc;
74 D(bug("[BCM2708] %s: Done..\n", __PRETTY_FUNCTION__));
77 static bcm2708_init_gputimer(struct KernelBase *KernelBase)
79 struct IntrNode *GPUTimerHandle;
80 unsigned int stc;
82 D(bug("[KRN:BCM2708] %s(%012p)\n", __PRETTY_FUNCTION__, KernelBase));
84 if ((GPUTimerHandle = AllocMem(sizeof(struct IntrNode), MEMF_PUBLIC|MEMF_CLEAR)) != NULL)
86 D(bug("[KRN:BCM2708] %s: IntrNode @ 0x%p:\n", __PRETTY_FUNCTION__, GPUTimerHandle));
87 D(bug("[KRN:BCM2708] %s: Using GPUTimer %d for VBlank\n", __PRETTY_FUNCTION__, VBLANK_TIMER));
89 GPUTimerHandle->in_Handler = bcm2708_gputimer_handler;
90 GPUTimerHandle->in_HandlerData = VBLANK_TIMER;
91 GPUTimerHandle->in_HandlerData2 = KernelBase;
92 GPUTimerHandle->in_type = it_interrupt;
93 GPUTimerHandle->in_nr = IRQ_TIMER0 + VBLANK_TIMER;
95 ADDHEAD(&KernelBase->kb_Interrupts[IRQ_TIMER0 + VBLANK_TIMER], &GPUTimerHandle->in_Node);
97 D(bug("[KRN:BCM2708] %s: Enabling Hardware IRQ.. \n", __PRETTY_FUNCTION__));
99 stc = *((volatile unsigned int *)(SYSTIMER_CLO));
100 stc += VBLANK_INTERVAL;
101 *((volatile unsigned int *)(SYSTIMER_CS)) = (1 << VBLANK_TIMER);
102 *((volatile unsigned int *)(SYSTIMER_C0 + (VBLANK_TIMER * 4))) = stc;
104 ictl_enable_irq(IRQ_TIMER0 + VBLANK_TIMER, KernelBase);
107 D(bug("[KRN:BCM2708] %s: Done.. \n", __PRETTY_FUNCTION__));
109 return GPUTimerHandle;
113 static IPTR bcm2708_probe(struct ARM_Implementation *krnARMImpl, struct TagItem *msg)
115 //TODO: really detect if we are running on a broadcom 2835/2836
116 if (krnARMImpl->ARMI_Family == 7) /* bcm2836 uses armv7 */
117 __arm_periiobase = BCM2836_PERIPHYSBASE;
118 else
119 __arm_periiobase = BCM2835_PERIPHYSBASE;
121 krnARMImpl->ARMI_InitTimer = &bcm2708_init_gputimer;
122 krnARMImpl->ARMI_LED_Toggle = &bcm2708_toggle_led;
124 if (__arm_periiobase == BCM2836_PERIPHYSBASE)
126 int core;
127 for (core = 1; core < 3; core ++)
129 *((volatile unsigned int *)(0x4000008C + (0x10 * core))) = cpu_Register;
132 if (krnARMImpl->ARMI_Delay)
133 krnARMImpl->ARMI_Delay(1500);
136 return TRUE;
139 ADD2SET(bcm2708_probe, ARMPLATFORMS, 0);