2 Copyright 2010, 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 if (i915bddata
->scratchmembuffer
)
133 FreeVec(i915bddata
->scratchmembuffer
);
134 i915bddata
->scratchmembuffer
= NULL
;
135 i915bddata
->scratchmem
= NULL
;
137 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
140 VOID
METHOD(i915BridgeDevice
, Root
, Get
)
143 struct HIDDi915BridgeDeviceData
* i915bddata
= OOP_INST_DATA(cl
, o
);
145 if (IS_AGPBRIDGEDEV_ATTR(msg
->attrID
, idx
))
149 case aoHidd_AGPBridgeDevice_Mode
:
150 *msg
->storage
= i915bddata
->bridgemode
;
153 case aoHidd_AGPBridgeDevice_ApertureBase
:
154 *msg
->storage
= i915bddata
->bridgeaperbase
;
157 case aoHidd_AGPBridgeDevice_ApertureSize
:
158 *msg
->storage
= i915bddata
->bridgeapersize
;
163 /* Use parent class for all other properties */
164 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
167 BOOL
METHOD(i915BridgeDevice
, Hidd_AGPBridgeDevice
, Enable
)
169 /* This function is a NOOP */
173 VOID
METHOD(i915BridgeDevice
, Hidd_AGPBridgeDevice
, FlushChipset
)
175 struct HIDDi915BridgeDeviceData
* i915bddata
= OOP_INST_DATA(cl
, o
);
177 if (i915bddata
->flushpage
)
178 writel(1, i915bddata
->flushpage
);
181 VOID
METHOD(i915BridgeDevice
, Hidd_AGPBridgeDevice
, UnBindMemory
)
184 struct HIDDi915BridgeDeviceData
* i915bddata
= OOP_INST_DATA(cl
, o
);
186 D(bug("[AGP] [Intel 915] Unbind offset %d, size %d\n", msg
->offset
, msg
->size
));
188 if (i915bddata
->state
!= STATE_ENABLED
)
194 ObtainSemaphore(&i915bddata
->lock
);
196 /* TODO: Check if offset is not before intelfirstgattentry */
198 /* Remove entries from GATT table */
199 for(i
= 0; i
< msg
->size
/ 4096; i
++)
201 writel((ULONG
)(IPTR
)i915bddata
->scratchmem
, i915bddata
->gatttable
+ msg
->offset
+ i
);
204 readl(i915bddata
->gatttable
+ msg
->offset
+ i
- 1); /* PCI posting */
206 /* Flush CPU cache - make sure data in GATT is up to date */
209 /* Flush GATT table */
210 struct pHidd_AGPBridgeDevice_FlushGattTable fgtmsg
= {
211 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_FlushGattTable
)
214 OOP_DoMethod(o
, (OOP_Msg
)&fgtmsg
);
216 ReleaseSemaphore(&i915bddata
->lock
);
219 VOID
METHOD(i915BridgeDevice
, Hidd_AGPBridgeDevice
, BindMemory
)
222 ULONG mask
= 0x00000001;
223 struct HIDDi915BridgeDeviceData
* i915bddata
= OOP_INST_DATA(cl
, o
);
225 D(bug("[AGP] [Intel 915] Bind address 0x%x into offset %d, size %d\n", (ULONG
)msg
->address
, msg
->offset
, msg
->size
));
227 if (i915bddata
->state
!= STATE_ENABLED
)
230 ObtainSemaphore(&i915bddata
->lock
);
232 /* TODO: Check if offset is not before intelfirstgattentry */
234 /* TODO: check if offset + size / 4096 ends before gatt_table end */
236 /* TODO: get mask type - check if mast type is of supported type */
238 /* Flush incomming memory - will be done in flush_cpu_cache below */
240 /* Additional mask for cached memory */
241 if (msg
->type
== vHidd_AGP_CachedMemory
)
244 /* Insert entries into GATT table */
245 for(i
= 0; i
< msg
->size
/ 4096; i
++)
247 /* Write masked memory address into GATT */
248 writel((msg
->address
+ (4096 * i
)) | mask
,
249 i915bddata
->gatttable
+ msg
->offset
+ i
);
252 readl(i915bddata
->gatttable
+ msg
->offset
+ i
- 1); /* PCI posting */
254 /* Flush CPU cache - make sure data in GATT is up to date */
257 /* Flush GATT table at card */
258 struct pHidd_AGPBridgeDevice_FlushGattTable fgtmsg
= {
259 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_FlushGattTable
)
262 OOP_DoMethod(o
, (OOP_Msg
)&fgtmsg
);
264 ReleaseSemaphore(&i915bddata
->lock
);
267 #undef HiddPCIDeviceAttrBase
268 #define HiddPCIDeviceAttrBase (SD(cl)->hiddPCIDeviceAB)
270 BOOL
METHOD(i915BridgeDevice
, Hidd_AGPBridgeDevice
, Initialize
)
272 struct HIDDi915BridgeDeviceData
* i915bddata
= OOP_INST_DATA(cl
, o
);
273 OOP_Object
* bridgedev
= NULL
;
274 OOP_Object
* igpdev
= NULL
;
276 ULONG entries
= 0, i
= 0;
278 struct pHidd_AGPBridgeDevice_ScanAndDetectDevices saddmsg
= {
279 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_ScanAndDetectDevices
)
282 /* Scan for bridge and igp devices */
283 if (!OOP_DoMethod(o
, (OOP_Msg
)&saddmsg
))
286 igpdev
= i915bddata
->igp
;
287 //TODO: bridgedev = ???
293 /* Getting GART size - from video card */
294 OOP_GetAttr(igpdev
, aHidd_PCIDevice_Size2
, (APTR
)&i915bddata
->bridgeapersize
);
296 D(bug("[AGP] [Intel 915] Read aperture size: %d MB\n", (ULONG
)i915bddata
->bridgeapersize
));
298 /* Creation of GATT table */
299 struct pHidd_AGPBridgeDevice_CreateGattTable cgtmsg
= {
300 mID
: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice
, moHidd_AGPBridgeDevice_CreateGattTable
)
302 if (!OOP_DoMethod(o
, (OOP_Msg
)&cgtmsg
))
305 /* Getting GART base */
306 i915bddata
->bridgeaperbase
= (IPTR
)readconfiglong(igpdev
, GFX_INTEL_I915_GMADDR
);
307 i915bddata
->bridgeaperbase
&= (~0x0fUL
) /* PCI_BASE_ADDRESS_MEM_MASK */;
308 D(bug("[AGP] [Intel 915] Reading aperture base: 0x%x\n", (ULONG
)i915bddata
->bridgeaperbase
));
311 gmchctrl
= readconfigword(bridgedev
, AGP_INTEL_I830_GMCH_CTRL
);
312 gmchctrl
|= AGP_INTEL_I830_GMCH_ENABLED
;
313 writeconfigword(bridgedev
, AGP_INTEL_I830_GMCH_CTRL
, gmchctrl
);
315 /* FIXME: gatttable means differnt thing now - this is old code */
316 /* writel((ULONG)i915bddata->gatttable | GFX_INTEL_I810_PGETBL_ENABLED,
317 i915bddata->regs + GFX_INTEL_I810_PGETBL_CTL);*/
319 readl(i915bddata
->regs
+ GFX_INTEL_I810_PGETBL_CTL
); /* PCI Posting */
321 /* Bind GATT to scratch page */
322 entries
= i915bddata
->bridgeapersize
* 1024 * 1024 / 4096;
323 for (i
= i915bddata
->firstgattentry
; i
< entries
; i
++)
325 writel((ULONG
)(IPTR
)i915bddata
->scratchmem
, i915bddata
->gatttable
+ i
);
327 readl(i915bddata
->gatttable
+ i
- 1); /* PCI Posting. */
331 /* TODO: Setup chipset flushing */
332 i915bddata
->flushpage
= NULL
;
335 /* THIS CLASS IS NOT FULLY IMPLEMENT AND NOT TESTED AT ALL */