define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / arch / ppc-sam440 / timer / timer_init.c
blob845fd8631418a41774d7d4e6667e6abb0361655e
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Timer startup and device commands
6 */
8 /****************************************************************************************/
10 #define DEBUG 0
12 #include <exec/types.h>
13 #include <exec/io.h>
14 #include <exec/errors.h>
15 #include <exec/devices.h>
16 #include <exec/alerts.h>
17 #include <exec/initializers.h>
18 #include <devices/timer.h>
19 #include <hidd/timer.h>
20 #include <hardware/intbits.h>
22 #include <proto/exec.h>
23 #include <proto/timer.h>
24 #include <proto/kernel.h>
26 #include <aros/symbolsets.h>
28 #include <asm/io.h>
29 #include <asm/amcc440.h>
31 #include <aros/debug.h>
32 #undef kprintf
33 #include <proto/arossupport.h>
35 //#include "timer_intern.h"
36 #include LC_LIBDEFS_FILE
38 #include "../kernel/syscall.h"
40 #include "lowlevel.h"
42 void DecrementerHandler(struct TimerBase *TimerBase, struct ExecBase *SysBase);
43 void GPTHandler(struct TimerBase *TimerBase, struct ExecBase *SysBase);
45 /****************************************************************************************/
47 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
49 void *KernelBase = rdspr(SPRG4U);
50 struct ExecBase *SysBase = rdspr(SPRG5U);
52 TimerBase->tb_prev_tick = inl(GPT0_TBC);
54 /* Setup the timer.device data */
55 LIBBASE->tb_CurrentTime.tv_secs = 0;
56 LIBBASE->tb_CurrentTime.tv_micro = 0;
57 LIBBASE->tb_VBlankTime.tv_secs = 0;
58 LIBBASE->tb_VBlankTime.tv_micro = 1000000 / (SysBase->VBlankFrequency * SysBase->PowerSupplyFrequency);
59 LIBBASE->tb_Elapsed.tv_secs = 0;
60 LIBBASE->tb_Elapsed.tv_micro = 0;
62 D(kprintf("Timer period: %ld secs, %ld micros\n",
63 LIBBASE->tb_VBlankTime.tv_secs, LIBBASE->tb_VBlankTime.tv_micro));
65 LIBBASE->tb_MiscFlags = TF_GO;
67 /* Initialise the lists */
68 NEWLIST( &LIBBASE->tb_Lists[0] );
69 NEWLIST( &LIBBASE->tb_Lists[1] );
70 NEWLIST( &LIBBASE->tb_Lists[2] );
71 NEWLIST( &LIBBASE->tb_Lists[3] );
72 NEWLIST( &LIBBASE->tb_Lists[4] );
74 /* Start up the interrupt server. This is shared between us and the
75 HIDD that deals with the vblank */
76 LIBBASE->tb_VBlankInt.is_Node.ln_Pri = 0;
77 LIBBASE->tb_VBlankInt.is_Node.ln_Type = NT_INTERRUPT;
78 LIBBASE->tb_VBlankInt.is_Node.ln_Name = (STRPTR)MOD_NAME_STRING;
79 // LIBBASE->tb_VBlankInt.is_Code = (APTR)&VBlankInt;
80 LIBBASE->tb_VBlankInt.is_Data = LIBBASE;
82 // AddIntServer(INTB_TIMERTICK, &LIBBASE->tb_VBlankInt);
83 // KrnAddIRQHandler(0x20, VBlankInt, LIBBASE, SysBase);
84 LIBBASE->tb_VBlankInt.is_Code = KrnAddIRQHandler(INTR_GDP, GPTHandler, LIBBASE, SysBase); //KrnAddExceptionHandler(10, DecrementerHandler, LIBBASE, SysBase);
86 outl(GPT0_DCIS_DCIS, GPT0_DCIS);
87 TimerSetup(TimerBase, inl(GPT0_TBC));
88 //outl(1333, GPT0_DCT0);
91 /* VBlank EMU */
93 LIBBASE->tb_vblank_timerequest.tr_node.io_Command = TR_ADDREQUEST;
94 LIBBASE->tb_vblank_timerequest.tr_node.io_Device = (struct Device *)TimerBase;
95 LIBBASE->tb_vblank_timerequest.tr_node.io_Unit = (struct Unit *)UNIT_MICROHZ;
96 LIBBASE->tb_vblank_timerequest.tr_time.tv_secs = 0;
97 LIBBASE->tb_vblank_timerequest.tr_time.tv_micro = 1000000 / SysBase->VBlankFrequency;
99 SendIO(&LIBBASE->tb_vblank_timerequest.tr_node);
101 return TRUE;
104 /****************************************************************************************/
106 static int GM_UNIQUENAME(Open)
108 LIBBASETYPEPTR LIBBASE,
109 struct timerequest *tr,
110 ULONG unitNum,
111 ULONG flags
115 Normally, we should check the length of the message and other
116 such things, however the RKM documents an example where the
117 length of the timerrequest isn't set, so we must not check
118 this.
120 This fixes bug SF# 741580
123 D(bug("[timer] OpenDevice(%d)\n", unitNum));
124 switch(unitNum)
126 case UNIT_VBLANK:
127 case UNIT_WAITUNTIL:
128 case UNIT_MICROHZ:
129 case UNIT_ECLOCK:
130 case UNIT_WAITECLOCK:
131 tr->tr_node.io_Error = 0;
132 tr->tr_node.io_Unit = (struct Unit *)unitNum;
133 tr->tr_node.io_Device = (struct Device *)LIBBASE;
134 break;
136 default:
137 tr->tr_node.io_Error = IOERR_OPENFAIL;
140 return TRUE;
143 /****************************************************************************************/
145 static int GM_UNIQUENAME(Expunge)(LIBBASETYPEPTR LIBBASE)
147 void *KernelBase = rdspr(SPRG4U);
149 KrnRemIRQHandler(LIBBASE->tb_VBlankInt.is_Code);
151 return TRUE;
154 /****************************************************************************************/
156 ADD2INITLIB(GM_UNIQUENAME(Init), 0)
157 ADD2OPENDEV(GM_UNIQUENAME(Open), 0)
158 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge), 0)