linux/bootstrap: use Forbid/Permit only when thread is main AROS thread
[AROS.git] / workbench / hidds / agp / i915bridgedeviceclass.c
blobf0a925cbea8680ce22bf97b772534cc3681e9e1c
1 /*
2 Copyright © 2010-2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <hidd/agp.h>
7 #include <hidd/pci.h>
8 #include <proto/oop.h>
9 #include <proto/exec.h>
10 #define DEBUG 1
11 #include <aros/debug.h>
13 #include "agp_private.h"
15 #undef HiddAGPBridgeDeviceAttrBase
16 #define HiddAGPBridgeDeviceAttrBase (SD(cl)->hiddAGPBridgeDeviceAB)
18 #define GFX_INTEL_I915_REGSADDR 0x10
19 #define GFX_INTEL_I915_GATTADDR 0x1C
20 #define GFX_INTEL_I915_GMADDR 0x18
21 #define GFX_INTEL_I810_PGETBL_CTL 0x2020
22 #define GFX_INTEL_I810_PGETBL_ENABLED 0x00000001
23 #define AGP_INTEL_I830_GMCH_CTRL 0x52
24 #define AGP_INTEL_I830_GMCH_ENABLED 0x4
26 #define IS_915_BRIDGE(x) \
27 ( \
28 (x == 0x2588) || /* 915 */ \
29 (x == 0x2580) || /* 82915G_HB */ \
30 (x == 0x2590) || /* 82915GM_HB */ \
31 (x == 0x2770) || /* 82945G_HB */ \
32 (x == 0x27A0) || /* 82945GM_HB */ \
33 (x == 0x27AC) /* 82945GME_HB */ \
34 ) \
36 #define IS_915_GFX(x) \
37 ( \
38 (x == 0x258a) || /* 915 */ \
39 (x == 0x2582) || /* 82915G_IG */ \
40 (x == 0x2592) || /* 82915GM_IG */ \
41 (x == 0x2772) || /* 82945G_IG */ \
42 (x == 0x27A2) || /* 82945GM_IG */ \
43 (x == 0x27AE) /* 82945GME_IG */ \
46 /* NON-PUBLIC METHODS */
47 VOID METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, FlushGattTable)
49 /* This function is a NOOP */
52 BOOL METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, CreateGattTable)
54 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
56 /* The GATT table is automatically created during POST - just use it */
57 OOP_Object * igpdev = i915bddata->igp;
58 /* ULONG gattsize = 256 * 1024; */ /* TODO: 1MB for G33 */
59 ULONG gatttableaddr = 0; /* Address of GATT table */
60 ULONG registersaddr = 0; /* Address of registers */
62 gatttableaddr = readconfiglong(igpdev, GFX_INTEL_I915_GATTADDR);
63 registersaddr = readconfiglong(igpdev, GFX_INTEL_I915_REGSADDR);
64 registersaddr &= 0xfff80000;
66 /* TODO: PCI MAP: agpsd->intelgatttable = (gatttableaddr, gatttablesize) */
67 i915bddata->gatttable = (ULONG*)(IPTR)gatttableaddr;
69 /* TODO: PCI MAP: agpsd->intelregs = (registersaddr, 128 * 4096) */
70 i915bddata->regs = (UBYTE*)(IPTR)registersaddr;
72 // ???? = (ULONG*)(readl(i915bddata->intelregs + GFX_INTEL_I810_PGETBL_CTL) & 0xfffff000);
74 D(bug("[AGP] [Intel 915] Intel GATT table 0x%x, Regs 0x%x\n",
75 (ULONG)(IPTR)i915bddata->gatttable, (ULONG)(IPTR)i915bddata->regs));
77 flushcpucache();
79 /* Create scratch page */
80 i915bddata->scratchmembuffer = AllocVec(4096 * 2, MEMF_PUBLIC | MEMF_CLEAR);
81 i915bddata->scratchmem = (ULONG*)(ALIGN((IPTR)i915bddata->scratchmembuffer, 4096));
82 D(bug("[AGP] [Intel 915] Created scratch memory at 0x%x\n", (ULONG)(IPTR)i915bddata->scratchmem));
84 /* TODO: Detect the amount of stolen memory */
85 i915bddata->firstgattentry = 0;
87 return TRUE;
90 BOOL METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, ScanAndDetectDevices)
92 /* TODO: IMPLEMENT */
93 /* TODO: Check if interrupt is set */
94 return FALSE;
97 /* PUBLIC METHODS */
98 OOP_Object * METHOD(i915BridgeDevice, Root, New)
100 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
102 if (o)
104 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
105 i915bddata->flushpage = NULL;
106 i915bddata->state = STATE_UNKNOWN;
107 InitSemaphore(&i915bddata->lock);
108 i915bddata->gatttable = NULL;
109 i915bddata->scratchmem = NULL;
110 i915bddata->bridgemode = 0;
111 i915bddata->bridgeaperbase = 0;
112 i915bddata->bridgeapersize = 0;
113 i915bddata->regs = 0;
114 i915bddata->igp = NULL;
115 i915bddata->scratchmembuffer = NULL;
118 return o;
121 VOID i915BridgeDevice__Root__Dispose(OOP_Class * cl, OOP_Object * o, OOP_Msg msg)
123 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
125 /* Free GATT table -> NOOP */
127 /* TODO: unmap flush page */
128 /* TODO: release flush page resource */
129 /* TODO: unmap agpsd->intelgatttable */
130 /* TODO: unmap agpsd->intelregs */
132 FreeVec(i915bddata->scratchmembuffer);
133 i915bddata->scratchmembuffer = NULL;
134 i915bddata->scratchmem = NULL;
136 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
139 VOID METHOD(i915BridgeDevice, Root, Get)
141 ULONG idx;
142 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
144 if (IS_AGPBRIDGEDEV_ATTR(msg->attrID, idx))
146 switch (idx)
148 case aoHidd_AGPBridgeDevice_Mode:
149 *msg->storage = i915bddata->bridgemode;
150 return;
152 case aoHidd_AGPBridgeDevice_ApertureBase:
153 *msg->storage = i915bddata->bridgeaperbase;
154 return;
156 case aoHidd_AGPBridgeDevice_ApertureSize:
157 *msg->storage = i915bddata->bridgeapersize;
158 return;
162 /* Use parent class for all other properties */
163 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
166 BOOL METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, Enable)
168 /* This function is a NOOP */
169 return TRUE;
172 VOID METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, FlushChipset)
174 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
176 if (i915bddata->flushpage)
177 writel(1, i915bddata->flushpage);
180 VOID METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, UnBindMemory)
182 ULONG i;
183 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
185 D(bug("[AGP] [Intel 915] Unbind offset %d, size %d\n", msg->offset, msg->size));
187 if (i915bddata->state != STATE_ENABLED)
188 return;
190 if (msg->size == 0)
191 return;
193 ObtainSemaphore(&i915bddata->lock);
195 /* TODO: Check if offset is not before intelfirstgattentry */
197 /* Remove entries from GATT table */
198 for(i = 0; i < msg->size / 4096; i++)
200 writel((ULONG)(IPTR)i915bddata->scratchmem, i915bddata->gatttable + msg->offset + i);
203 readl(i915bddata->gatttable + msg->offset + i - 1); /* PCI posting */
205 /* Flush CPU cache - make sure data in GATT is up to date */
206 flushcpucache();
208 /* Flush GATT table */
209 struct pHidd_AGPBridgeDevice_FlushGattTable fgtmsg = {
210 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_FlushGattTable)
213 OOP_DoMethod(o, (OOP_Msg)&fgtmsg);
215 ReleaseSemaphore(&i915bddata->lock);
218 VOID METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, BindMemory)
220 ULONG i;
221 ULONG mask = 0x00000001;
222 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
224 D(bug("[AGP] [Intel 915] Bind address 0x%x into offset %d, size %d\n", (ULONG)msg->address, msg->offset, msg->size));
226 if (i915bddata->state != STATE_ENABLED)
227 return;
229 ObtainSemaphore(&i915bddata->lock);
231 /* TODO: Check if offset is not before intelfirstgattentry */
233 /* TODO: check if offset + size / 4096 ends before gatt_table end */
235 /* TODO: get mask type - check if mast type is of supported type */
237 /* Flush incomming memory - will be done in flush_cpu_cache below */
239 /* Additional mask for cached memory */
240 if (msg->type == vHidd_AGP_CachedMemory)
241 mask |= 0x00000006;
243 /* Insert entries into GATT table */
244 for(i = 0; i < msg->size / 4096; i++)
246 /* Write masked memory address into GATT */
247 writel((msg->address + (4096 * i)) | mask,
248 i915bddata->gatttable + msg->offset + i);
251 readl(i915bddata->gatttable + msg->offset + i - 1); /* PCI posting */
253 /* Flush CPU cache - make sure data in GATT is up to date */
254 flushcpucache();
256 /* Flush GATT table at card */
257 struct pHidd_AGPBridgeDevice_FlushGattTable fgtmsg = {
258 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_FlushGattTable)
261 OOP_DoMethod(o, (OOP_Msg)&fgtmsg);
263 ReleaseSemaphore(&i915bddata->lock);
266 #undef HiddPCIDeviceAttrBase
267 #define HiddPCIDeviceAttrBase (SD(cl)->hiddPCIDeviceAB)
269 BOOL METHOD(i915BridgeDevice, Hidd_AGPBridgeDevice, Initialize)
271 struct HIDDi915BridgeDeviceData * i915bddata = OOP_INST_DATA(cl, o);
272 OOP_Object * bridgedev = NULL;
273 OOP_Object * igpdev = NULL;
274 UWORD gmchctrl = 0;
275 ULONG entries = 0, i = 0;
277 struct pHidd_AGPBridgeDevice_ScanAndDetectDevices saddmsg = {
278 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_ScanAndDetectDevices)
281 /* Scan for bridge and igp devices */
282 if (!OOP_DoMethod(o, (OOP_Msg)&saddmsg))
283 return FALSE;
285 igpdev = i915bddata->igp;
286 //TODO: bridgedev = ???
289 /* Initialize */
292 /* Getting GART size - from video card */
293 OOP_GetAttr(igpdev, aHidd_PCIDevice_Size2, (APTR)&i915bddata->bridgeapersize);
295 D(bug("[AGP] [Intel 915] Read aperture size: %d MB\n", (ULONG)i915bddata->bridgeapersize));
297 /* Creation of GATT table */
298 struct pHidd_AGPBridgeDevice_CreateGattTable cgtmsg = {
299 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_CreateGattTable)
301 if (!OOP_DoMethod(o, (OOP_Msg)&cgtmsg))
302 return FALSE;
304 /* Getting GART base */
305 i915bddata->bridgeaperbase = (IPTR)readconfiglong(igpdev, GFX_INTEL_I915_GMADDR);
306 i915bddata->bridgeaperbase &= (~0x0fUL) /* PCI_BASE_ADDRESS_MEM_MASK */;
307 D(bug("[AGP] [Intel 915] Reading aperture base: 0x%x\n", (ULONG)i915bddata->bridgeaperbase));
309 /* Enabled GATT */
310 gmchctrl = readconfigword(bridgedev, AGP_INTEL_I830_GMCH_CTRL);
311 gmchctrl |= AGP_INTEL_I830_GMCH_ENABLED;
312 writeconfigword(bridgedev, AGP_INTEL_I830_GMCH_CTRL, gmchctrl);
314 /* FIXME: gatttable means differnt thing now - this is old code */
315 /* writel((ULONG)i915bddata->gatttable | GFX_INTEL_I810_PGETBL_ENABLED,
316 i915bddata->regs + GFX_INTEL_I810_PGETBL_CTL);*/
318 readl(i915bddata->regs + GFX_INTEL_I810_PGETBL_CTL); /* PCI Posting */
320 /* Bind GATT to scratch page */
321 entries = i915bddata->bridgeapersize * 1024 * 1024 / 4096;
322 for (i = i915bddata->firstgattentry; i < entries; i++)
324 writel((ULONG)(IPTR)i915bddata->scratchmem, i915bddata->gatttable + i);
326 readl(i915bddata->gatttable + i - 1); /* PCI Posting. */
328 flushcpucache();
330 /* TODO: Setup chipset flushing */
331 i915bddata->flushpage = NULL;
334 /* THIS CLASS IS NOT FULLY IMPLEMENT AND NOT TESTED AT ALL */
335 return FALSE;