sam440: Use the correct base for PCI Config Space accesses for 440/460
[AROS.git] / arch / ppc-sam440 / pci / driverclass.c
blobf406b12cb3a15a6b8f24d9f5dd4a2909f25e0b0f
1 /*
2 Copyright © 2004-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: PCI direct driver for i386 native.
6 Lang: English
7 */
9 #define __OOP_NOATTRBASES__
11 #include <exec/types.h>
12 #include <hidd/pci.h>
13 #include <oop/oop.h>
15 #include <utility/tagitem.h>
17 #include <proto/exec.h>
18 #include <proto/utility.h>
19 #include <proto/oop.h>
21 #include <resources/processor.h>
22 #include <proto/processor.h>
24 #include <aros/symbolsets.h>
25 #include <asm/amcc440.h>
26 #include <asm/io.h>
28 #include "pci.h"
30 #define DEBUG 1
31 #include <aros/debug.h>
33 #undef HiddPCIDriverAttrBase
34 #undef HiddAttrBase
36 #define HiddPCIDriverAttrBase (PSD(cl)->hiddPCIDriverAB)
37 #define HiddAttrBase (PSD(cl)->hiddAB)
39 #define CFGADD(bus,dev,func,reg) \
40 ( psd->CfgBase | ((bus)<<16) | \
41 ((dev)<<11) | ((func)<<8) | ((reg)&~3))
43 typedef union _pcicfg
45 ULONG ul;
46 UWORD uw[2];
47 UBYTE ub[4];
48 } pcicfg;
51 We overload the New method in order to introduce the Hidd Name and
52 HardwareName attributes.
54 OOP_Object *PCI440__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
56 struct pRoot_New mymsg;
58 struct TagItem mytags[] = {
59 { aHidd_Name, (IPTR)"PCINative" },
60 { aHidd_HardwareName, (IPTR)"AMCC440 native direct access PCI driver" },
61 { aHidd_PCIDriver_IOBase, PCI0_IO },
62 { TAG_DONE, 0 }
65 mymsg.mID = msg->mID;
66 mymsg.attrList = (struct TagItem *)&mytags[0];
68 if (msg->attrList)
70 mytags[3].ti_Tag = TAG_MORE;
71 mytags[3].ti_Data = (IPTR)msg->attrList;
74 msg = &mymsg;
76 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
78 return o;
81 static ULONG ReadConfigLong(struct pci_staticdata *psd, UBYTE bus, UBYTE dev, UBYTE sub, UWORD reg)
83 ULONG temp;
85 Disable();
86 outl_le(CFGADD(bus, dev, sub, reg),PCI0_CFGADDR);
87 temp=inl_le(PCI0_CFGDATA);
88 Enable();
89 if (reg == 0x3c && psd->IntLine != 0xff) { /* PCICS_INT_LINE */
90 temp &= ~0xff;
91 temp |= psd->IntLine;
93 DB2(bug("[PCI440] -> %08x = %08x\n", CFGADD(bus, dev, sub, reg), temp));
95 return temp;
98 ULONG PCI440__Hidd_PCIDriver__ReadConfigLong(OOP_Class *cl, OOP_Object *o,
99 struct pHidd_PCIDriver_ReadConfigLong *msg)
101 return ReadConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg);
104 static void WriteConfigLong(struct pci_staticdata *psd, UBYTE bus, UBYTE dev, UBYTE sub, UWORD reg, ULONG val)
106 DB2(bug("[PCI440] <- %08x = %08x\n", CFGADD(bus, dev, sub, reg), val));
107 Disable();
108 outl_le(CFGADD(bus, dev, sub, reg),PCI0_CFGADDR);
109 outl_le(val,PCI0_CFGDATA);
110 Enable();
113 void PCI440__Hidd_PCIDriver__WriteConfigLong(OOP_Class *cl, OOP_Object *o,
114 struct pHidd_PCIDriver_WriteConfigLong *msg)
116 WriteConfigLong(PSD(cl), msg->bus, msg->dev, msg->sub, msg->reg, msg->val);
119 /* Class initialization and destruction */
120 static inline ULONG GetPVR(void)
122 struct Library *ProcessorBase = OpenResource(PROCESSORNAME);
123 ULONG pvr = 0;
125 if (ProcessorBase) {
126 struct TagItem tags[] = {
127 { GCIT_Model, (IPTR)&pvr },
128 { TAG_END }
130 GetCPUInfo(tags);
133 return pvr;
136 static int PCI440_InitClass(LIBBASETYPEPTR LIBBASE)
138 OOP_Object *pci;
139 ULONG pvr;
141 D(bug("PCI440: Driver initialization\n"));
143 pvr = GetPVR();
144 if (pvr == PVR_PPC460EX_B) {
145 LIBBASE->psd.IntLine = INTR_UIC0_PCI0_IN;
146 LIBBASE->psd.CfgBase = 0x00000000;
147 } else {
148 LIBBASE->psd.IntLine = 0xff;
149 LIBBASE->psd.CfgBase = 0x80000000;
152 struct pHidd_PCI_AddHardwareDriver msg,*pmsg=&msg;
154 LIBBASE->psd.hiddPCIDriverAB = OOP_ObtainAttrBase(IID_Hidd_PCIDriver);
155 LIBBASE->psd.hiddAB = OOP_ObtainAttrBase(IID_Hidd);
156 if (LIBBASE->psd.hiddPCIDriverAB == 0 || LIBBASE->psd.hiddAB == 0)
158 D(bug("PCI440: ObtainAttrBases failed\n"));
159 return FALSE;
162 msg.driverClass = LIBBASE->psd.driverClass;
163 msg.mID = OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_AddHardwareDriver);
164 D(bug("PCI440: Adding Driver to main the class OK\n"));
166 pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
167 OOP_DoMethod(pci, (OOP_Msg)pmsg);
168 OOP_DisposeObject(pci);
170 D(bug("PCI440: CPU %p%p:%p%p PCI (0x%08x)\n",
171 inl_le(PCI0_POM0LAH), inl_le(PCI0_POM0LAL),
172 inl_le(PCI0_POM0PCIAH), inl_le(PCI0_POM0PCIAL),
173 ~(inl_le(PCI0_POM0SA) & ~0xf) + 1
175 D(bug("PCI440: CPU %p%p:%p%p PCI (0x%08x)\n",
176 inl_le(PCI0_POM1LAH), inl_le(PCI0_POM1LAL),
177 inl_le(PCI0_POM1PCIAH), inl_le(PCI0_POM1PCIAL),
178 ~(inl_le(PCI0_POM1SA) & ~0xf) + 1
180 uint64_t sa = ((uint64_t)inl_le(PCI0_PIM0SAH) << 32) | inl_le(PCI0_PIM0SAL);
181 sa = ~(sa & ~0xfULL) + 1;
182 D(bug("PCI440: PCI %p%p:%p%p CPU (0x%08x%08x)\n",
183 inl_le(PCI0_BAR0H), inl_le(PCI0_BAR0L) & ~0xf,
184 inl_le(PCI0_PIM0LAH), inl_le(PCI0_PIM0LAL),
185 (uint32_t)(sa >>32), (uint32_t)sa
188 D(bug("PCI440: All OK\n"));
190 return TRUE;
193 static int PCI440_ExpungeClass(LIBBASETYPEPTR LIBBASE)
195 D(bug("PCI440: Class destruction\n"));
197 OOP_ReleaseAttrBase(IID_Hidd_PCIDriver);
198 OOP_ReleaseAttrBase(IID_Hidd);
200 return TRUE;
203 ADD2INITLIB(PCI440_InitClass, 0)
204 ADD2EXPUNGELIB(PCI440_ExpungeClass, 0)