Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / ppc-chrp / efika / timer / timer_init.c
blobf111a09b53aa898225c0ef3a00c7ec890e09a019
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>
25 #include <proto/utility.h>
26 #include <proto/openfirmware.h>
28 #include <utility/tagitem.h>
30 #include <aros/symbolsets.h>
32 #include <asm/io.h>
33 #include <asm/mpc5200b.h>
35 #include <aros/debug.h>
36 #include <proto/arossupport.h>
38 //#include "timer_intern.h"
39 #include LC_LIBDEFS_FILE
41 #include "lowlevel.h"
43 void SliceHandler(struct TimerBase *TimerBase, struct ExecBase *SysBase);
44 extern volatile slt_t *slice_timer;
46 /****************************************************************************************/
48 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
50 struct ExecBase *SysBase = getSysBase();
51 void *KernelBase = getKernelBase();
53 TimerBase->tb_prev_tick = mftbl();
55 /* Setup the timer.device data */
56 LIBBASE->tb_CurrentTime.tv_secs = 0;
57 LIBBASE->tb_CurrentTime.tv_micro = 0;
58 LIBBASE->tb_VBlankTime.tv_secs = 0;
59 LIBBASE->tb_VBlankTime.tv_micro = 1000000 / SysBase->VBlankFrequency;
60 LIBBASE->tb_Elapsed.tv_secs = 0;
61 LIBBASE->tb_Elapsed.tv_micro = 0;
63 D(bug("Timer period: %ld secs, %ld micros\n",
64 LIBBASE->tb_VBlankTime.tv_secs, LIBBASE->tb_VBlankTime.tv_micro));
66 LIBBASE->tb_MiscFlags = TF_GO;
68 /* Initialise the lists */
69 NEWLIST( &LIBBASE->tb_Lists[0] );
70 NEWLIST( &LIBBASE->tb_Lists[1] );
71 NEWLIST( &LIBBASE->tb_Lists[2] );
72 NEWLIST( &LIBBASE->tb_Lists[3] );
73 NEWLIST( &LIBBASE->tb_Lists[4] );
75 void *OpenFirmwareBase = OpenResource("openfirmware.resource");
76 void *key = OF_OpenKey("/builtin");
77 if (key)
79 void *prop = OF_FindProperty(key, "reg");
80 if (prop)
82 intptr_t *mbar = OF_GetPropValue(prop);
83 slice_timer = (slt_t *)(*mbar + 0x710);
85 D(bug("MBAR located at %08x\n", *mbar));
86 D(bug("slice timer at %08x\n", slice_timer));
90 /* Start up the interrupt server. This is shared between us and the
91 HIDD that deals with the vblank */
92 LIBBASE->tb_VBlankInt.is_Node.ln_Pri = 0;
93 LIBBASE->tb_VBlankInt.is_Node.ln_Type = NT_INTERRUPT;
94 LIBBASE->tb_VBlankInt.is_Node.ln_Name = (STRPTR)MOD_NAME_STRING;
95 LIBBASE->tb_VBlankInt.is_Data = LIBBASE;
97 LIBBASE->tb_VBlankInt.is_Code = KrnAddIRQHandler(MPC5200B_ST1, SliceHandler, LIBBASE, SysBase); //KrnAddExceptionHandler(10, DecrementerHandler, LIBBASE, SysBase);
99 /* Start the slice timer 1 */
100 // outl(SLT_CF_RUNWAIT | SLT_CF_INTRENA | SLT_CF_ENABLE, &slice_timer->slt_cf);
102 outl(SLT_TS_ST, &slice_timer->slt_ts);
103 // TimerSetup(TimerBase, mftbl());
105 // outl(SLT_TS_ST, &slice_timer->slt_ts);
106 TimerSetup(TimerBase, 0);
108 /* VBlank EMU */
110 LIBBASE->tb_vblank_timerequest.tr_node.io_Command = TR_ADDREQUEST;
111 LIBBASE->tb_vblank_timerequest.tr_node.io_Device = (struct Device *)TimerBase;
112 LIBBASE->tb_vblank_timerequest.tr_node.io_Unit = (struct Unit *)UNIT_MICROHZ;
113 LIBBASE->tb_vblank_timerequest.tr_time.tv_secs = 0;
114 LIBBASE->tb_vblank_timerequest.tr_time.tv_micro = 1000000 / SysBase->VBlankFrequency;
116 SendIO(&LIBBASE->tb_vblank_timerequest.tr_node);
118 return TRUE;
121 /****************************************************************************************/
123 static int GM_UNIQUENAME(Open)
125 LIBBASETYPEPTR LIBBASE,
126 struct timerequest *tr,
127 ULONG unitNum,
128 ULONG flags
132 Normally, we should check the length of the message and other
133 such things, however the RKM documents an example where the
134 length of the timerrequest isn't set, so we must not check
135 this.
137 This fixes bug SF# 741580
140 D(bug("[timer] OpenDevice(%d)\n", unitNum));
141 switch(unitNum)
143 case UNIT_VBLANK:
144 case UNIT_WAITUNTIL:
145 case UNIT_MICROHZ:
146 case UNIT_ECLOCK:
147 case UNIT_WAITECLOCK:
148 tr->tr_node.io_Error = 0;
149 tr->tr_node.io_Unit = (struct Unit *)unitNum;
150 tr->tr_node.io_Device = (struct Device *)LIBBASE;
151 break;
153 default:
154 tr->tr_node.io_Error = IOERR_OPENFAIL;
157 return TRUE;
160 /****************************************************************************************/
162 static int GM_UNIQUENAME(Expunge)(LIBBASETYPEPTR LIBBASE)
164 void *KernelBase = getKernelBase();
166 KrnRemIRQHandler(LIBBASE->tb_VBlankInt.is_Code);
168 return TRUE;
171 /****************************************************************************************/
173 ADD2INITLIB(GM_UNIQUENAME(Init), 0)
174 ADD2OPENDEV(GM_UNIQUENAME(Open), 0)
175 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge), 0)