includes: AROS_UFIxx -> AROS_INTxx change
[AROS.git] / arch / ppc-chrp / efika / ata / lowlevel_mpc5200b.c
blobbcd6e1d1b2388d1a57e5ce588f60b2b9f04ae95b
1 #define DEBUG 0
3 #include <aros/debug.h>
4 #include <exec/types.h>
5 #include <asm/io.h>
6 #include <asm/mpc5200b.h>
7 #include <exec/exec.h>
8 #include <exec/tasks.h>
9 #include <exec/memory.h>
10 #include <exec/nodes.h>
11 #include <utility/utility.h>
12 #include <proto/exec.h>
13 #include <proto/timer.h>
14 #include <proto/oop.h>
15 #include <proto/openfirmware.h>
17 #include "ata.h"
19 extern uint8_t *sram;
20 extern bestcomm_t *bestcomm;
21 extern uint32_t bestcomm_taskid;
23 extern void bestcomm_init();
25 UBYTE *mbar;
26 uint32_t bus_frequency;
28 volatile ata_5k2_t *ata_5k2;
30 static void ata_out(UBYTE val, UWORD offset, IPTR port, APTR data)
32 while(inl(&ata_5k2->ata_status) & 0x80000000) asm volatile("nop");
34 if (port +offset * 4 == 0x3a7c)
36 ULONG val = inl(&mbar[port + offset * 4]);
37 outb(0, &mbar[port + 1 + offset * 4]);
40 outl((ULONG)val << 24, &mbar[port + offset * 4]);
43 static UBYTE ata_in(UWORD offset, IPTR port, APTR data)
45 while(inl(&ata_5k2->ata_status) & 0x80000000) asm volatile("nop");
47 if (port +offset * 4 == 0x3a7c)
49 ULONG val = inl(&mbar[port + offset * 4]);
50 outb(0, &mbar[port + 1 + offset * 4]);
53 return inl(&mbar[port + offset * 4]) >> 24;
56 static void ata_outl(ULONG val, UWORD offset, IPTR port, APTR data)
58 while(inl(&ata_5k2->ata_status) & 0x80000000) asm volatile("nop");
60 outl_le(val, &mbar[port + offset * 4]);
63 static VOID ata_insw(APTR address, UWORD port, ULONG count, APTR data)
65 UWORD *addr = address;
66 volatile UWORD *p = (UWORD*)(&mbar[port]);
68 D(bug("[ATA 5k2] insw(%08x, %04x)\n", address, count));
70 count &= ~1;
72 while(inl(&ata_5k2->ata_status) & 0x80000000) asm volatile("nop");
74 asm volatile("sync");
75 while(count)
77 // *addr++ = inw(p);
78 *addr++ = *p;
79 count -= 2;
81 asm volatile("sync");
84 static VOID ata_outsw(APTR address, UWORD port, ULONG count, APTR data)
86 UWORD *addr = address;
87 volatile UWORD *p = (UWORD*)(&mbar[port]);
89 D(bug("[ATA 5k2] outsw(%08x, %04x)\n", address, count));
91 count &= ~1;
93 while(inl(&ata_5k2->ata_status) & 0x80000000) asm volatile("nop");
95 asm volatile("sync");
96 while(count)
98 // outw(*addr++, p);
99 *p = *addr++;
100 count -= 2;
102 asm volatile("sync");
105 static void ata_400ns()
107 register ULONG tick_old, tick;
109 asm volatile("mftbl %0":"=r"(tick_old));
111 do {
112 asm volatile("mftbl %0":"=r"(tick));
113 } while(tick < (tick_old + 15));
116 static AROS_INTH1(ata_Interrupt, void *, data)
118 AROS_INTFUNC_INIT
120 * Our interrupt handler should call this function.
121 * It's our problem how to store bus pointer. Here we use h_Data for it.
123 ata_HandleIRQ(data);
125 return FALSE;
127 AROS_INTFUNC_EXIT
130 /* Actually a quick hack. Proper implementation really needs HIDDizing this code. */
131 static BOOL CreateInterrupt(struct ata_Bus *bus)
133 struct Interrupt *IntHandler = &bus->ab_IntHandler;
136 Prepare nice interrupt for our bus. Even if interrupt sharing is enabled,
137 it should work quite well
139 IntHandler->is_Node.ln_Pri = 10;
140 IntHandler->is_Node.ln_Name = bus->ab_Task->tc_Node.ln_Name;
141 IntHandler->is_Code = (VOID_FUNC)ata_Interrupt;
142 IntHandler->is_Data = bus;
144 AddIntServer(INTB_KERNEL + bus->ab_IRQ, IntHandler);
146 return TRUE;
149 static const struct ata_BusDriver mpc_driver =
151 ata_out,
152 ata_in,
153 ata_outl,
154 ata_insw,
155 ata_outsw,
156 ata_insw, /* These are intentionally the same as 16-bit routines */
157 ata_outsw,
158 CreateInterrupt
161 static int ata_mpc_init(struct ataBase *LIBBASE)
163 int i;
165 * I've decided to use memory pools again. Alloc everything needed from
166 * a pool, so that we avoid memory fragmentation.
168 LIBBASE->ata_MemPool = CreatePool(MEMF_CLEAR | MEMF_PUBLIC | MEMF_SEM_PROTECTED , 8192, 4096);
169 if (LIBBASE->ata_MemPool == NULL)
170 return FALSE;
172 void *OpenFirmwareBase = OpenResource("openfirmware.resource");
173 void *key = OF_OpenKey("/builtin");
174 if (key)
176 void *prop = OF_FindProperty(key, "reg");
177 if (prop)
179 intptr_t *m_ = OF_GetPropValue(prop);
180 mbar = (UBYTE *)*m_;
181 ata_5k2 = (ata_5k2_t *)(*m_ + 0x3a00);
183 D(bug("[ATA] MBAR located at %08x\n", mbar));
186 /* Get the bus frequency for Efika */
187 prop = OF_FindProperty(key, "bus-frequency");
188 if (prop)
190 bus_frequency = *(uint32_t *)OF_GetPropValue(prop);
191 D(bug("[ATA] bus frequency: %d\n", bus_frequency));
195 key = OF_OpenKey("/builtin/ata");
196 if (key)
198 void *prop = OF_FindProperty(key, "reg");
199 if (prop)
201 ata_5k2 = *(ata_5k2_t **)OF_GetPropValue(prop);
203 D(bug("[ATA] ATA registers at %08x\n", ata_5k2));
207 key = OF_OpenKey("/builtin/ata/bestcomm-task");
208 if (key)
210 void *prop = OF_FindProperty(key, "taskid");
211 if (prop)
213 bestcomm_taskid = *(uint32_t *)OF_GetPropValue(prop);
215 D(bug("[ATA] ATA uses bestcomm task %d\n", bestcomm_taskid));
219 key = OF_OpenKey("/builtin/sram");
220 if (key)
222 void *prop = OF_FindProperty(key, "reg");
223 if (prop)
225 sram = *(void **)OF_GetPropValue(prop);
227 D(bug("[ATA] SRAM at %08x\n", sram));
230 key = OF_OpenKey("/builtin/bestcomm");
231 if (key)
233 void *prop = OF_FindProperty(key, "reg");
234 if (prop)
236 bestcomm = *(void **)OF_GetPropValue(prop);
238 D(bug("[ATA] bestcomm at %08x\n", bestcomm));
241 D(bug("[ATA] ata_config=%08x\n", inl(&ata_5k2->ata_config)));
242 D(bug("[ATA] ata_status=%08x\n", inl(&ata_5k2->ata_status)));
243 D(bug("[ATA] ata_pio1=%08x\n", inl(&ata_5k2->ata_pio1)));
244 D(bug("[ATA] ata_pio2=%08x\n", inl(&ata_5k2->ata_pio2)));
246 /* Disable XLB pipelining... */
247 D(bug("[ATA] xlb_config=%08x\n", inl(mbar+0x1f40)));
248 outl(inl(mbar + 0x1f40) | 0x80000000, mbar + 0x1f40);
250 outl(0, &ata_5k2->ata_invalid);
251 outl(0xc3000000, &ata_5k2->ata_config);
253 for (i=0; i < 100 / 4; i++)
254 ata_400ns();
256 /* Hacky timing pokes */
257 outl(0x03000000, &ata_5k2->ata_config);
258 outl(132 << 16, &ata_5k2->ata_invalid);
260 /* PIO2 timing table. Replace it by correct calculations soon !!! */
262 #warning TODO: Set the timings in right way!
264 outl(0x21270e00, &ata_5k2->ata_pio1);
265 outl(0x03050600, &ata_5k2->ata_pio2);
267 bestcomm_init();
270 * FIXME: This code uses static data variables.
271 * Move them into DriverData instead.
273 ata_RegisterBus(0x3a60, 0x3a5c - 8, MPC5200B_ATA, 0, FALSE, &mpc_driver, NULL, LIBBASE);
275 return TRUE;
278 ADD2INITLIB(ata_mpc_init, 20)