Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / ppc-chrp / efika / pci / driverclass.c
blobb843828a68cd4963c81e3caa9b159ea287cda288
1 /*
2 * driverclass.c
4 * Created on: Oct 14, 2008
5 * Author: misc
6 */
8 #define __OOP_NOATTRBASES__
10 #include <exec/types.h>
11 #include <hidd/pci.h>
12 #include <oop/oop.h>
14 #include <utility/tagitem.h>
16 #include <proto/exec.h>
17 #include <proto/utility.h>
18 #include <proto/oop.h>
19 #include <proto/openfirmware.h>
20 #include <proto/kernel.h>
22 #include <aros/symbolsets.h>
23 #include <asm/mpc5200b.h>
24 #include <asm/io.h>
26 #include "pci.h"
28 #define DEBUG 1
29 #include <aros/debug.h>
31 #undef HiddPCIDriverAttrBase
32 #undef HiddAttrBase
34 #define HiddPCIDriverAttrBase (PSD(cl)->hiddPCIDriverAB)
35 #define HiddAttrBase (PSD(cl)->hiddAB)
37 #define CFGADD(bus,dev,func,reg) \
38 ( 0x80000000 | ((bus)<<16) | \
39 ((dev)<<11) | ((func)<<8) | ((reg)&~3))
41 typedef union _pcicfg
43 ULONG ul;
44 UWORD uw[2];
45 UBYTE ub[4];
46 } pcicfg;
49 We overload the New method in order to introduce the Hidd Name and
50 HardwareName attributes.
52 OOP_Object *PCIEfika__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
54 struct pRoot_New mymsg;
56 struct TagItem mytags[] = {
57 { aHidd_Name, (IPTR)"PCINative" },
58 { aHidd_HardwareName, (IPTR)"Efika5200 native direct access PCI driver" },
59 { TAG_DONE, 0 }
62 mymsg.mID = msg->mID;
63 mymsg.attrList = (struct TagItem *)&mytags;
65 if (msg->attrList)
67 mytags[2].ti_Tag = TAG_MORE;
68 mytags[2].ti_Data = (IPTR)msg->attrList;
71 msg = &mymsg;
73 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
75 return o;
78 ULONG ReadConfigLong(struct pci_staticdata *psd, UBYTE bus, UBYTE dev, UBYTE sub, UBYTE reg)
80 ULONG temp;
82 Disable();
83 outl(CFGADD(bus, dev, sub, reg),(ULONG*)(psd->mbar + 0xdf8));
84 sync();
85 temp=inl_le(psd->pciio);
86 outl(0, (ULONG *)(psd->mbar + 0xdf8));
87 sync();
88 Enable();
90 return temp;
93 ULONG PCIEfika__Hidd_PCIDriver__ReadConfigLong(OOP_Class *cl, OOP_Object *o,
94 struct pHidd_PCIDriver_ReadConfigLong *msg)
96 ULONG val = ReadConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg);
97 return val;
100 UWORD ReadConfigWord(struct pci_staticdata *psd, UBYTE bus, UBYTE dev, UBYTE sub, UBYTE reg)
102 pcicfg temp;
104 temp.ul = ReadConfigLong(psd, bus, dev, sub, reg);
106 return temp.uw[1 - ((reg&2)>>1)];
110 UWORD PCIEfika__Hidd_PCIDriver__ReadConfigWord(OOP_Class *cl, OOP_Object *o,
111 struct pHidd_PCIDriver_ReadConfigWord *msg)
113 return ReadConfigWord(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg);
116 UBYTE PCIEfika__Hidd_PCIDriver__ReadConfigByte(OOP_Class *cl, OOP_Object *o,
117 struct pHidd_PCIDriver_ReadConfigByte *msg)
119 pcicfg temp;
121 temp.ul = ReadConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg);
122 return temp.ub[3 - (msg->reg & 3)];
125 void WriteConfigLong(struct pci_staticdata *psd, UBYTE bus, UBYTE dev, UBYTE sub, UBYTE reg, ULONG val)
127 Disable();
128 outl(CFGADD(bus, dev, sub, reg),(ULONG*)(psd->mbar + 0xdf8));
129 sync();
130 outl_le(val, psd->pciio);
131 outl(0, (ULONG *)(psd->mbar + 0xdf8));
132 sync();
133 Enable();
136 void PCIEfika__Hidd_PCIDriver__WriteConfigLong(OOP_Class *cl, OOP_Object *o,
137 struct pHidd_PCIDriver_WriteConfigLong *msg)
139 WriteConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg, msg->val);
142 void PCIEfika__Hidd_PCIDriver__WriteConfigWord(OOP_Class *cl, OOP_Object *o,
143 struct pHidd_PCIDriver_WriteConfigWord *msg)
145 pcicfg temp;
147 temp.ul = ReadConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg);
148 temp.uw[1 - ((msg->reg&2)>>1)] = msg->val;
149 WriteConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg, temp.ul);
152 void PCIEfika__Hidd_PCIDriver__WriteConfigByte(OOP_Class *cl, OOP_Object *o,
153 struct pHidd_PCIDriver_WriteConfigByte *msg)
155 pcicfg temp;
157 temp.ul = ReadConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg);
158 temp.ub[3 - (msg->reg & 3)] = msg->val;
159 WriteConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg, temp.ul);
162 void *PCIEfika__Hidd_PCIDriver__MapPCI(OOP_Class *cl, OOP_Object *o,
163 struct pHidd_PCIDriver_MapPCI *msg)
165 void *KernelBase = OpenResource("kernel.resource");
166 KrnMapGlobal(msg->PCIAddress, msg->PCIAddress, msg->Length, MAP_CacheInhibit | MAP_Guarded | MAP_Readable | MAP_Writable);
167 return msg->PCIAddress;
170 void *PCIEfika__Hidd_PCIDriver__AllocPCIMem(OOP_Class *cl, OOP_Object *o,
171 struct pHidd_PCIDriver_AllocPCIMem *msg)
173 void *KernelBase = OpenResource("kernel.resource");
174 void *memory = OOP_DoSuperMethod(cl, o, msg);
176 if (memory)
178 KrnSetProtection(memory, msg->Size, MAP_CacheInhibit | MAP_Guarded | MAP_Readable | MAP_Writable);
181 return memory;
185 PCIDriver::FreePCIMemory(Address) frees previously allocated memory for PCI
186 devices
188 VOID PCIEfika__Hidd_PCIDriver__FreePCIMem(OOP_Class *cl, OOP_Object *o,
189 struct pHidd_PCIDriver_FreePCIMem *msg)
191 void *KernelBase = OpenResource("kernel.resource");
192 KrnSetProtection(msg->Address, 4096, MAP_Readable | MAP_Writable);
193 OOP_DoSuperMethod(cl, o, msg);
197 /* Class initialization and destruction */
199 static int PCIEfika_InitClass(LIBBASETYPEPTR LIBBASE)
201 OOP_Object *pci;
202 int i;
203 ULONG temp;
204 void *OpenFirmwareBase = NULL;
205 void *KernelBase = NULL;
207 D(bug("[PCI_Efika] Driver initialization\n"));
209 KernelBase = OpenResource("kernel.resource");
210 OpenFirmwareBase = OpenResource("openfirmware.resource");
211 D(bug("[PCI_Efika] OpenFirmwareBase = %08x\n", OpenFirmwareBase));
213 void *key = OF_OpenKey("/builtin");
214 if (key)
216 void *prop = OF_FindProperty(key, "reg");
217 if (prop)
219 intptr_t *mbar = OF_GetPropValue(prop);
220 LIBBASE->psd.mbar = (void *)(*mbar);
222 D(bug("[PCI_Efika] MBAR located at %08x\n", LIBBASE->psd.mbar));
226 D(bug("[PCI_Efika] PCITBATR0 = %08x\n", inl(LIBBASE->psd.mbar + 0x0d64)));
227 D(bug("[PCI_Efika] PCITBATR1 = %08x\n", inl(LIBBASE->psd.mbar + 0x0d68)));
229 D(bug("[PCI_Efika] PCIIW0BTAR = %08x\n", inl(LIBBASE->psd.mbar + 0x0d70)));
230 D(bug("[PCI_Efika] PCIIW1BTAR = %08x\n", inl(LIBBASE->psd.mbar + 0x0d74)));
231 D(bug("[PCI_Efika] PCIIW2BTAR = %08x\n", inl(LIBBASE->psd.mbar + 0x0d78)));
233 D(bug("[PCI_Efika] PCIIWCR = %08x\n", inl(LIBBASE->psd.mbar + 0x0d80)));
234 D(bug("[PCI_Efika] PCIICR = %08x\n", inl(LIBBASE->psd.mbar + 0x0d84)));
236 for (i=0; i < 3; i++)
238 uint8_t attr = inl(LIBBASE->psd.mbar + 0xd80) >> (24 - i*8);
240 /* If bit 0 of attribute is cleared, then the window is not used */
241 if ((attr & 1) == 0)
242 continue;
244 temp = inl(LIBBASE->psd.mbar + 0xd70 + i*4);
245 uint32_t size = 0x1000000 + ((temp << 8) & 0xff000000);
246 uint32_t base = temp & 0xff000000;
248 D(bug("[PCI_Efika] PCI %s: %08x - %08x\n", attr & 8 ? "IO" : "MEM", base, base + size - 1));
249 if (attr & 8)
251 LIBBASE->psd.pciio = (uint8_t *)base;
252 LIBBASE->psd.pciio_size = size;
254 else
256 LIBBASE->psd.pcimem = (uint8_t *)base;
257 LIBBASE->psd.pcimem_size = size;
261 /* Map first 64K of PCI IO space. More than that is not used anyway :) */
262 KrnMapGlobal(LIBBASE->psd.pciio, LIBBASE->psd.pciio, 0x10000, MAP_CacheInhibit | MAP_Guarded | MAP_Readable | MAP_Writable);
264 struct pHidd_PCI_AddHardwareDriver msg,*pmsg=&msg;
266 LIBBASE->psd.hiddPCIDriverAB = OOP_ObtainAttrBase(IID_Hidd_PCIDriver);
267 LIBBASE->psd.hiddAB = OOP_ObtainAttrBase(IID_Hidd);
268 if (LIBBASE->psd.hiddPCIDriverAB == 0 || LIBBASE->psd.hiddAB == 0)
270 D(bug("[PCI_Efika] ObtainAttrBases failed\n"));
271 return FALSE;
274 msg.driverClass = LIBBASE->psd.driverClass;
275 msg.mID = OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_AddHardwareDriver);
276 D(bug("[PCI_Efika] Adding Driver to main the class OK\n"));
278 pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
279 OOP_DoMethod(pci, (OOP_Msg)pmsg);
280 OOP_DisposeObject(pci);
282 D(bug("[PCI_Efika] All OK\n"));
284 return TRUE;
287 static int PCIEfika_ExpungeClass(LIBBASETYPEPTR LIBBASE)
289 D(bug("[PCI_Efika] Class destruction\n"));
291 OOP_ReleaseAttrBase(IID_Hidd_PCIDriver);
292 OOP_ReleaseAttrBase(IID_Hidd);
294 return TRUE;
297 ADD2INITLIB(PCIEfika_InitClass, 0)
298 ADD2EXPUNGELIB(PCIEfika_ExpungeClass, 0)