- Give PCI controllers lower unit numbers than legacy controllers.
[cake.git] / arch / common / hidd.radeon / ati_init.c
blobfa315560198e6d7356a1705de7f6d9e5e4cd225d
1 /*
2 Copyright © 2003-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/symbolsets.h>
8 #include <exec/execbase.h>
9 #include <exec/types.h>
10 #include <exec/resident.h>
11 #include <exec/libraries.h>
12 #include <exec/memory.h>
13 #include <exec/lists.h>
14 #include <exec/semaphores.h>
15 #include <dos/bptr.h>
17 #include <utility/utility.h>
19 #define DEBUG 1
21 #include <proto/exec.h>
22 #include <proto/oop.h>
23 #include <aros/debug.h>
25 #include <hidd/i2c.h>
26 #include <hidd/pci.h>
27 #include <hidd/graphics.h>
29 #include "ati.h"
30 #include "ids.h"
31 #include "radeon.h"
32 #include "radeon_reg.h"
33 #include "radeon_macros.h"
34 #include LC_LIBDEFS_FILE
36 #undef HiddPCIDeviceAttrBase
37 #undef HiddGfxAttrBase
38 #undef HiddPixFmtAttrBase
39 #undef HiddSyncAttrBase
40 #undef HiddBitMapAttrBase
41 #undef HiddI2CAttrBase
42 #undef HiddI2CDeviceAttrBase
43 #define HiddPCIDeviceAttrBase (LIBBASE->sd.pciAttrBase)
44 #define HiddATIBitMapAttrBase (LIBBASE->sd.atiBitMapAttrBase)
45 #define HiddBitMapAttrBase (LIBBASE->sd.bitMapAttrBase)
46 #define HiddPixFmtAttrBase (LIBBASE->sd.pixFmtAttrBase)
47 #define HiddGfxAttrBase (LIBBASE->sd.gfxAttrBase)
48 #define HiddSyncAttrBase (LIBBASE->sd.syncAttrBase)
49 #define HiddI2CAttrBase (LIBBASE->sd.i2cAttrBase)
50 #define HiddI2CDeviceAttrBase (LIBBASE->sd.i2cDeviceAttrBase)
51 #define __IHidd_PlanarBM (LIBBASE->sd.planarAttrBase)
53 static
54 AROS_UFH3(void, Enumerator,
55 AROS_UFHA(struct Hook *,hook, A0),
56 AROS_UFHA(OOP_Object *, pciDevice, A2),
57 AROS_UFHA(APTR, message, A1))
59 AROS_USERFUNC_INIT
60 LIBBASETYPEPTR LIBBASE = (LIBBASETYPEPTR)hook->h_Data;
61 struct ati_staticdata *sd = &LIBBASE->sd;
63 struct ATIDevice *sup = (struct ATIDevice *)support;
64 IPTR ProductID;
65 IPTR VendorID;
67 if (sd->PCIDevice != NULL)
68 return;
70 /* Get the Device's ProductID */
71 OOP_GetAttr(pciDevice, aHidd_PCIDevice_ProductID, &ProductID);
72 OOP_GetAttr(pciDevice, aHidd_PCIDevice_VendorID, &VendorID);
74 D(bug("[ATI] Enumerator: checking productid %04x vendorid %04x %08x\n",
75 ProductID, VendorID, pciDevice));
77 /* And try to match it with supported cards */
78 while (sup->VendorID)
80 BOOL found = FALSE;
82 if (sup->VendorID == VendorID)
84 if (!sup->masked_check && (sup->ProductID == ProductID))
86 found = TRUE;
88 else if (sup->masked_check && (sup->ProductID == (ProductID & 0xFFF0)))
90 found = TRUE;
94 if (found)
96 /* Matching card found */
97 APTR buf;
98 ULONG size;
99 OOP_Object *driver;
100 struct MemChunk *mc;
102 struct TagItem attrs[] = {
103 { aHidd_PCIDevice_isIO, TRUE }, /* Don't listen IO transactions */
104 { aHidd_PCIDevice_isMEM, TRUE }, /* Listen to MEM transactions */
105 { aHidd_PCIDevice_isMaster, TRUE }, /* Can work in BusMaster */
106 { TAG_DONE, 0UL },
109 D(bug("[ATI] Enumerator: found productid %04x vendorid %04x masked_check %d\n",
110 sup->ProductID, sup->VendorID, sup->masked_check));
112 sd->Card.ProductID = ProductID;
113 sd->Card.VendorID = VendorID;
114 sd->Card.Type = sup->Type;
117 Fix PCI device attributes (perhaps already set, but if the
118 ATI would be the second card in the system, it may stay
119 uninitialized.
121 OOP_SetAttrs(pciDevice, (struct TagItem*)&attrs);
123 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Driver, (APTR)&driver);
124 sd->PCIDriver = driver;
126 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Base0, (APTR)&buf);
127 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Size0, (APTR)&size);
129 sd->Card.FbAddress = (IPTR)buf;
130 sd->Card.FrameBuffer = (IPTR)HIDD_PCIDriver_MapPCI(driver, buf, size);
131 mc = (struct MemChunk *)sd->Card.FrameBuffer;
133 sd->CardMem.mh_Node.ln_Type = NT_MEMORY;
134 sd->CardMem.mh_Node.ln_Name = "ATI Framebuffer";
135 sd->CardMem.mh_First = mc;
136 sd->CardMem.mh_Lower = (APTR)mc;
138 D(bug("[ATI] Got framebuffer @ %x (size=%dMiB)\n", sd->Card.FrameBuffer, size>>20));
140 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Base2, (APTR)&buf);
141 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Size2, (APTR)&size);
143 sd->Card.MMIO = (APTR)HIDD_PCIDriver_MapPCI(driver, buf, size);
144 D(bug("[ATI] Got registers @ %x (size=%dKiB)\n", sd->Card.MMIO, size>>10));
146 OOP_GetAttr(pciDevice, aHidd_PCIDevice_RomBase, (APTR)&buf);
147 OOP_GetAttr(pciDevice, aHidd_PCIDevice_RomSize, (APTR)&size);
149 D(bug("[ATI] RomBase provided by ATI card: %x\n", buf));
151 if (buf)
152 sd->Card.vbios_org = (APTR)HIDD_PCIDriver_MapPCI(driver, buf, size);
153 else
154 sd->Card.vbios_org = (APTR)HIDD_PCIDriver_MapPCI(driver, (APTR)0x000c0000, size);
155 sd->Card.VBIOS = sd->Card.vbios_org;
156 D(bug("[ATI] Got BIOS @ %x (size=%dKiB)\n", sd->Card.VBIOS, size>>10));
158 if (sup->Init(sd))
160 struct CardState *state = AllocPooled(sd->memPool, sizeof(struct CardState));
162 sd->poweron_state = AllocPooled(sd->memPool, sizeof(struct CardState));
163 SaveState(sd, sd->poweron_state);
165 sd->CardMem.mh_Free = sd->Card.FbUsableSize;
166 sd->CardMem.mh_Upper = (APTR)(sd->CardMem.mh_Free + (IPTR)mc);
168 mc->mc_Next = NULL;
169 mc->mc_Bytes = sd->CardMem.mh_Free;
171 D(bug("[ATI] Usable size: %dKB\n", sd->CardMem.mh_Free >> 10));
173 sd->scratch_buffer = AllocBitmapArea(sd, 4096, 16, 4, TRUE);
174 sd->Card.CursorStart = AllocBitmapArea(sd, 64, 64, 4, TRUE);
175 sd->cpuscratch = AllocPooled(sd->memPool, 4096*4);
177 OUTREG(RADEON_CUR_HORZ_VERT_OFF,RADEON_CUR_LOCK | 0);
178 OUTREG(RADEON_CUR_HORZ_VERT_POSN,RADEON_CUR_LOCK | 0);
179 OUTREG(RADEON_CUR_OFFSET, sd->Card.CursorStart);
181 sd->PCIDevice = pciDevice;
183 /*-------- DO NOT CHANGE/REMOVE -------------*/
184 bug("\003\n"); /* Tell vga text mode debug output to die */
185 /*-------- DO NOT CHANGE/REMOVE -------------*/
187 else
189 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Size0, (APTR)&size);
190 HIDD_PCIDriver_UnmapPCI(driver, (APTR)sd->Card.FrameBuffer, size);
191 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Size2, (APTR)&size);
192 HIDD_PCIDriver_UnmapPCI(driver, (APTR)sd->Card.MMIO, size);
193 OOP_GetAttr(pciDevice, aHidd_PCIDevice_RomSize, (APTR)&size);
194 HIDD_PCIDriver_UnmapPCI(driver, (APTR)sd->Card.vbios_org, size);
195 sd->PCIDevice = NULL;
198 break;
201 sup++;
204 D(bug("[ATI] Enumerator found a card (ProductID=%04x)\n", ProductID));
205 D(bug("[ATI] The card is %ssupported\n",
206 sd->PCIDevice ? "":"un"));
208 AROS_USERFUNC_EXIT
211 static int ATI_Init(LIBBASETYPEPTR LIBBASE)
213 struct ati_staticdata *sd = &LIBBASE->sd;
215 struct OOP_ABDescr attrbases[] =
217 { (STRPTR)IID_Hidd_PCIDevice, &HiddPCIDeviceAttrBase },
218 { (STRPTR)IID_Hidd_BitMap, &HiddBitMapAttrBase },
219 { (STRPTR)IID_Hidd_PixFmt, &HiddPixFmtAttrBase },
220 { (STRPTR)IID_Hidd_Sync, &HiddSyncAttrBase },
221 { (STRPTR)IID_Hidd_Gfx, &HiddGfxAttrBase },
222 { (STRPTR)IID_Hidd_ATIBitMap, &HiddATIBitMapAttrBase },
223 { (STRPTR)IID_Hidd_I2C, &HiddI2CAttrBase },
224 { (STRPTR)IID_Hidd_I2CDevice, &HiddI2CDeviceAttrBase },
225 { (STRPTR)IID_Hidd_PlanarBM, &__IHidd_PlanarBM },
226 { NULL, NULL }
229 D(bug("[ATI] Init\n"));
231 sd->memPool = CreatePool(MEMF_CLEAR | MEMF_PUBLIC | MEMF_SEM_PROTECTED, 8192, 4096);
233 if (sd->memPool)
235 if (OOP_ObtainAttrBases(attrbases))
237 sd->mid_CopyMemBox8 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_CopyMemBox8);
238 sd->mid_CopyMemBox16 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_CopyMemBox16);
239 sd->mid_CopyMemBox32 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_CopyMemBox32);
240 sd->mid_PutMem32Image8 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMem32Image8);
241 sd->mid_PutMem32Image16 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMem32Image16);
242 sd->mid_GetMem32Image8 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_GetMem32Image8);
243 sd->mid_GetMem32Image16 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_GetMem32Image16);
244 sd->mid_Clear = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_Clear);
245 sd->mid_PutMemTemplate8 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMemTemplate8);
246 sd->mid_PutMemTemplate16= OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMemTemplate16);
247 sd->mid_PutMemTemplate32= OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMemTemplate32);
248 sd->mid_PutMemPattern8 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMemPattern8);
249 sd->mid_PutMemPattern16 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMemPattern16);
250 sd->mid_PutMemPattern32 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_PutMemPattern32);
251 sd->mid_CopyLUTMemBox16 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_CopyLUTMemBox16);
252 sd->mid_CopyLUTMemBox32 = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_CopyLUTMemBox32);
253 sd->mid_GetImage = OOP_GetMethodID((STRPTR)CLID_Hidd_BitMap, moHidd_BitMap_GetImage);
255 InitSemaphore(&LIBBASE->sd.HWLock);
256 InitSemaphore(&LIBBASE->sd.MultiBMLock);
258 /* Initialize MsgPort */
259 LIBBASE->sd.mp.mp_SigBit = SIGB_SINGLE;
260 LIBBASE->sd.mp.mp_Flags = PA_SIGNAL;
261 LIBBASE->sd.mp.mp_SigTask = FindTask(NULL);
262 LIBBASE->sd.mp.mp_Node.ln_Type = NT_MSGPORT;
263 NEWLIST(&LIBBASE->sd.mp.mp_MsgList);
265 LIBBASE->sd.tr.tr_node.io_Message.mn_ReplyPort = &LIBBASE->sd.mp;
266 LIBBASE->sd.tr.tr_node.io_Message.mn_Length = sizeof(LIBBASE->sd.tr);
268 if (!OpenDevice((STRPTR)"timer.device", UNIT_MICROHZ, (struct IORequest *)&LIBBASE->sd.tr, 0))
270 if ((LIBBASE->sd.PCIObject = OOP_NewObject(NULL, (STRPTR)CLID_Hidd_PCI, NULL)))
272 struct Hook FindHook = {
273 h_Entry: (IPTR (*)())Enumerator,
274 h_Data: LIBBASE,
277 struct TagItem Requirements[] = {
278 { tHidd_PCI_Interface, 0x00 },
279 { tHidd_PCI_Class, 0x03 },
280 { tHidd_PCI_SubClass, 0x00 },
281 { tHidd_PCI_VendorID, 0x1002 }, // ATI VendorID. May require more of them
282 { TAG_DONE, 0UL }
285 HIDD_PCI_EnumDevices(LIBBASE->sd.PCIObject, &FindHook, Requirements);
287 return TRUE;
291 OOP_ReleaseAttrBases(attrbases);
294 DeletePool(LIBBASE->sd.memPool);
297 return FALSE;
300 static int ATI_Expunge(LIBBASETYPEPTR LIBBASE)
302 struct ati_staticdata *sd = &LIBBASE->sd;
304 struct OOP_ABDescr attrbases[] =
306 { (STRPTR)IID_Hidd_PCIDevice, &HiddPCIDeviceAttrBase },
307 { (STRPTR)IID_Hidd_BitMap, &HiddBitMapAttrBase },
308 { (STRPTR)IID_Hidd_PixFmt, &HiddPixFmtAttrBase },
309 { (STRPTR)IID_Hidd_Sync, &HiddSyncAttrBase },
310 { (STRPTR)IID_Hidd_Gfx, &HiddGfxAttrBase },
311 { (STRPTR)IID_Hidd_ATIBitMap, &HiddATIBitMapAttrBase },
312 { (STRPTR)IID_Hidd_I2C, &HiddI2CAttrBase },
313 { (STRPTR)IID_Hidd_I2CDevice, &HiddI2CDeviceAttrBase },
314 { (STRPTR)IID_Hidd_PlanarBM, &__IHidd_PlanarBM },
315 { NULL, NULL }
318 if (sd->PCIDevice)
320 IPTR size;
321 OOP_GetAttr(sd->PCIDevice, aHidd_PCIDevice_Size0, (APTR)&size);
322 HIDD_PCIDriver_UnmapPCI(sd->PCIDriver, (APTR)sd->Card.FrameBuffer, size);
323 OOP_GetAttr(sd->PCIDevice, aHidd_PCIDevice_Size2, (APTR)&size);
324 HIDD_PCIDriver_UnmapPCI(sd->PCIDriver, (APTR)sd->Card.MMIO, size);
325 OOP_GetAttr(sd->PCIDevice, aHidd_PCIDevice_RomSize, (APTR)&size);
326 HIDD_PCIDriver_UnmapPCI(sd->PCIDriver, (APTR)sd->Card.vbios_org, size);
327 sd->PCIDevice = NULL;
330 OOP_DisposeObject(sd->PCIObject);
331 OOP_ReleaseAttrBases(attrbases);
332 DeletePool(sd->memPool);
334 return TRUE;
337 ADD2INITLIB(ATI_Init, 0)
338 ADD2EXPUNGELIB(ATI_Expunge, 0)
339 ADD2LIBS((STRPTR)"graphics.hidd", 0, static struct Library *, __gfxbase);