rpi2 as well as B+ boards use LEDs wired between GPIO and ground. Fix setting LED...
[AROS.git] / arch / arm-raspi / kernel / platform_bcm2708.c
blobb40ae3a13fb9d7d93858c859b9116309c0fd55bf
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 static void bcm2708_init(void)
25 static void bcm2708_toggle_led(int LED, int state)
27 if (__arm_periiobase == BCM2836_PERIPHYSBASE)
29 int pin = 35;
30 IPTR gpiofunc = GPCLR1;
32 if (LED == ARM_LED_ACTIVITY)
33 pin = 47;
35 if (state == ARM_LED_ON)
36 gpiofunc = GPSET1;
38 *(volatile unsigned int *)gpiofunc = (1 << (pin-32));
40 else
42 // RasPi 1 only allows us to toggle the activity LED
43 if (state)
44 *(volatile unsigned int *)GPCLR0 = (1 << 16);
45 else
46 *(volatile unsigned int *)GPSET0 = (1 << 16);
50 static void bcm2708_gputimer_handler(unsigned int timerno, void *unused1)
52 unsigned int stc, cs;
54 D(bug("[KRN:BCM2708] %s(%d)\n", __PRETTY_FUNCTION__, timerno));
56 /* Aknowledge our timer interrupt */
57 cs = *((volatile unsigned int *)(SYSTIMER_CS));
58 cs &= ~ (1 << timerno);
59 *((volatile unsigned int *)(SYSTIMER_CS)) = cs;
61 /* Signal the Exec VBlankServer */
62 if (SysBase && (SysBase->IDNestCnt < 0)) {
63 core_Cause(INTB_VERTB, 1L << INTB_VERTB);
66 /* Refresh our timer interrupt */
67 stc = *((volatile unsigned int *)(SYSTIMER_CLO));
68 stc += VBLANK_INTERVAL;
69 *((volatile unsigned int *)(SYSTIMER_CS)) = cs | (1 << timerno);
70 *((volatile unsigned int *)(SYSTIMER_C0 + (timerno * 4))) = stc;
72 D(bug("[BCM2708] %s: Done..\n", __PRETTY_FUNCTION__));
75 static bcm2708_init_gputimer(struct KernelBase *KernelBase)
77 struct IntrNode *GPUTimerHandle;
78 unsigned int stc;
80 D(bug("[KRN:BCM2708] %s(%012p)\n", __PRETTY_FUNCTION__, KernelBase));
82 if ((GPUTimerHandle = AllocMem(sizeof(struct IntrNode), MEMF_PUBLIC|MEMF_CLEAR)) != NULL)
84 D(bug("[KRN:BCM2708] %s: IntrNode @ 0x%p:\n", __PRETTY_FUNCTION__, GPUTimerHandle));
85 D(bug("[KRN:BCM2708] %s: Using GPUTimer %d for VBlank\n", __PRETTY_FUNCTION__, VBLANK_TIMER));
87 GPUTimerHandle->in_Handler = bcm2708_gputimer_handler;
88 GPUTimerHandle->in_HandlerData = VBLANK_TIMER;
89 GPUTimerHandle->in_HandlerData2 = KernelBase;
90 GPUTimerHandle->in_type = it_interrupt;
91 GPUTimerHandle->in_nr = IRQ_TIMER0 + VBLANK_TIMER;
93 ADDHEAD(&KernelBase->kb_Interrupts[IRQ_TIMER0 + VBLANK_TIMER], &GPUTimerHandle->in_Node);
95 D(bug("[KRN:BCM2708] %s: Enabling Hardware IRQ.. \n", __PRETTY_FUNCTION__));
97 stc = *((volatile unsigned int *)(SYSTIMER_CLO));
98 stc += VBLANK_INTERVAL;
99 *((volatile unsigned int *)(SYSTIMER_CS)) = (1 << VBLANK_TIMER);
100 *((volatile unsigned int *)(SYSTIMER_C0 + (VBLANK_TIMER * 4))) = stc;
102 ictl_enable_irq(IRQ_TIMER0 + VBLANK_TIMER, KernelBase);
105 D(bug("[KRN:BCM2708] %s: Done.. \n", __PRETTY_FUNCTION__));
107 return GPUTimerHandle;
111 static IPTR bcm2708_probe(struct ARM_Implementation *krnARMImpl, struct TagItem *msg)
113 //TODO: really detect if we are running on a broadcom 2835/2836
114 if (krnARMImpl->ARMI_Family == 7) /* bcm2836 uses armv7 */
115 __arm_periiobase = BCM2836_PERIPHYSBASE;
116 else
117 __arm_periiobase = BCM2835_PERIPHYSBASE;
119 krnARMImpl->ARMI_InitTimer = &bcm2708_init_gputimer;
120 krnARMImpl->ARMI_LED_Toggle = &bcm2708_toggle_led;
122 return TRUE;
125 ADD2SET(bcm2708_probe, ARMPLATFORMS, 0);