2 Copyright © 2010-2013, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
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) \
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 */ \
36 #define IS_915_GFX(x) \
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
));
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;
90 BOOL
METHOD(i915BridgeDevice
, Hidd_AGPBridgeDevice
, ScanAndDetectDevices
)
93 /* TODO: Check if interrupt is set */
98 OOP_Object
* METHOD(i915BridgeDevice
, Root
, New
)
100 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
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
;
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
)
142 struct HIDDi915BridgeDeviceData
* i915bddata
= OOP_INST_DATA(cl
, o
);
144 if (IS_AGPBRIDGEDEV_ATTR(msg
->attrID
, idx
))
148 case aoHidd_AGPBridgeDevice_Mode
:
149 *msg
->storage
= i915bddata
->bridgemode
;
152 case aoHidd_AGPBridgeDevice_ApertureBase
:
153 *msg
->storage
= i915bddata
->bridgeaperbase
;
156 case aoHidd_AGPBridgeDevice_ApertureSize
:
157 *msg
->storage
= i915bddata
->bridgeapersize
;
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 */
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
)
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
)
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 */
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
)
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
)
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
)
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 */
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
;
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
))
285 igpdev
= i915bddata
->igp
;
286 //TODO: bridgedev = ???
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
))
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
));
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. */
330 /* TODO: Setup chipset flushing */
331 i915bddata
->flushpage
= NULL
;
334 /* THIS CLASS IS NOT FULLY IMPLEMENT AND NOT TESTED AT ALL */