2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
8 #include <aros/debug.h>
9 #include <aros/libcall.h>
10 #include <aros/asmcall.h>
11 #include <aros/symbolsets.h>
12 #include <utility/tagitem.h>
13 #include <hidd/graphics.h>
15 #include <graphics/displayinfo.h>
16 #include <proto/oop.h>
17 #include <proto/exec.h>
18 #include <proto/utility.h>
23 #include "intelG45_intern.h"
24 #include "intelG45_regs.h"
25 #include "gallium_intern.h"
26 #include "compositing.h"
28 #define sd ((struct g45staticdata*)SD(cl))
30 #define MAX_MODE_NAME_LEN 30
32 #define SYNC_TAG_COUNT 16
33 #define SYNC_LIST_COUNT (15 + 8 + 4)
35 #define DEBUG_POINTER 1
39 #define PRINT_POINTER(image, xsize, xmax, ymax) \
40 bug("[GMA] Pointer data:\n"); \
42 ULONG *pix = (ULONG *)image; \
45 for (y = 0; y < ymax; y++) { \
46 for (x = 0; x < xmax; x++) \
47 bug("0x%08X ", pix[x]); \
54 #define PRINT_POINTER(image, xsize, xmax, ymax)
57 /* Definitions used in CVT formula */
62 #define DUTY_CYCLE(period) \
63 (((C - J) / 2 + J) * 1000 - (M / 2 * (period) / 1000))
64 #define MIN_DUTY_CYCLE 20 /* % */
65 #define MIN_V_PORCH 3 /* lines */
66 #define MIN_V_PORCH_TIME 550 /* us */
67 #define CLOCK_STEP 250000 /* Hz */
83 /* Partial implementation of CVT formula */
84 void calcTimings(int x
, int y
, int vfreq
, sync_t
*sync
)
86 ULONG h_period
, h_freq
, h_total
, h_blank
, h_front
, h_sync
, h_back
,
87 v_total
, v_front
, v_sync
, v_back
, duty_cycle
, pixel_freq
;
92 /* Get horizontal period in microseconds */
93 h_period
= (1000000000 / vfreq
- MIN_V_PORCH_TIME
* 1000)
96 /* Vertical front porch is fixed */
97 v_front
= MIN_V_PORCH
;
99 /* Use aspect ratio to determine V-sync lines */
102 else if (x
== y
* 16 / 9)
104 else if (x
== y
* 16 / 10)
106 else if (x
== y
* 5 / 4)
108 else if (x
== y
* 15 / 9)
113 /* Get vertical back porch */
114 v_back
= MIN_V_PORCH_TIME
* 1000 / h_period
+ 1;
115 if (v_back
< MIN_V_PORCH
)
116 v_back
= MIN_V_PORCH
;
119 /* Get total lines per frame */
120 v_total
= y
+ v_front
+ v_sync
+ v_back
;
122 /* Get horizontal blanking pixels */
123 duty_cycle
= DUTY_CYCLE(h_period
);
124 if (duty_cycle
< MIN_DUTY_CYCLE
)
125 duty_cycle
= MIN_DUTY_CYCLE
;
127 h_blank
= 10 * x
* duty_cycle
/ (100000 - duty_cycle
);
128 h_blank
/= 2 * 8 * 10;
129 h_blank
= h_blank
* (2 * 8);
131 /* Get total pixels in a line */
132 h_total
= x
+ h_blank
;
134 /* Calculate frequencies for each pixel, line and field */
135 h_freq
= 1000000000 / h_period
;
136 pixel_freq
= h_freq
* h_total
/ CLOCK_STEP
* CLOCK_STEP
;
137 h_freq
= pixel_freq
/ h_total
;
139 /* Back porch is half of H-blank */
140 h_back
= h_blank
/ 2;
142 /* H-sync is a fixed percentage of H-total */
143 h_sync
= h_total
/ 100 * 8;
145 /* Front porch is whatever's left */
146 h_front
= h_blank
- h_sync
- h_back
;
148 /* Fill in VBE timings structure */
149 sync
->htotal
= h_total
;
150 sync
->hstart
= x
+ h_front
;
151 sync
->hend
= h_total
- h_back
;
152 sync
->vtotal
= v_total
;
153 sync
->vstart
= y
+ v_front
;
154 sync
->vend
= v_total
- v_back
;
155 sync
->pixel
= pixel_freq
;
158 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
159 struct TagItem sync_ ## name[]={ \
160 { aHidd_Sync_PixelClock, clock*1000 }, \
161 { aHidd_Sync_HDisp, hdisp }, \
162 { aHidd_Sync_HSyncStart, hstart }, \
163 { aHidd_Sync_HSyncEnd, hend }, \
164 { aHidd_Sync_HTotal, htotal }, \
165 { aHidd_Sync_VDisp, vdisp }, \
166 { aHidd_Sync_VSyncStart, vstart }, \
167 { aHidd_Sync_VSyncEnd, vend }, \
168 { aHidd_Sync_VTotal, vtotal }, \
169 { aHidd_Sync_Description, (IPTR)descr }, \
172 #define PUSH_TAG(ptr, tag, data) do { (*(ptr))->ti_Tag = (tag); (*(ptr))->ti_Data= (IPTR)(data); (*ptr)++; } while(0)
174 void createSync(OOP_Class
*cl
, int x
, int y
, int refresh
, struct TagItem
**tagsptr
, struct TagItem
**poolptr
)
177 char *description
= AllocVecPooled(sd
->MemPool
, MAX_MODE_NAME_LEN
+ 1);
178 snprintf(description
, MAX_MODE_NAME_LEN
, "GMA: %dx%d@%d", x
, y
, refresh
);
179 calcTimings(x
, y
, refresh
, &sync
);
181 D(bug("[GMA] %s %d %d %d %d %d %d %d %d %d -HSync +VSync\n", description
+5,
182 sync
.pixel
/ 1000, sync
.width
, sync
.hstart
, sync
.hend
, sync
.htotal
,
183 sync
.height
, sync
.vstart
, sync
.vend
, sync
.vtotal
));
185 PUSH_TAG(tagsptr
, aHidd_Gfx_SyncTags
, *poolptr
);
187 PUSH_TAG(poolptr
, aHidd_Sync_Description
, description
);
188 PUSH_TAG(poolptr
, aHidd_Sync_PixelClock
, sync
.pixel
);
190 PUSH_TAG(poolptr
, aHidd_Sync_HDisp
, sync
.width
);
191 PUSH_TAG(poolptr
, aHidd_Sync_HSyncStart
, sync
.hstart
);
192 PUSH_TAG(poolptr
, aHidd_Sync_HSyncEnd
, sync
.hend
);
193 PUSH_TAG(poolptr
, aHidd_Sync_HTotal
, sync
.htotal
);
195 PUSH_TAG(poolptr
, aHidd_Sync_VDisp
, sync
.height
);
196 PUSH_TAG(poolptr
, aHidd_Sync_VSyncStart
, sync
.vstart
);
197 PUSH_TAG(poolptr
, aHidd_Sync_VSyncEnd
, sync
.vend
);
198 PUSH_TAG(poolptr
, aHidd_Sync_VTotal
, sync
.vtotal
);
200 PUSH_TAG(poolptr
, aHidd_Sync_VMin
, sync
.height
);
201 PUSH_TAG(poolptr
, aHidd_Sync_VMax
, 4096);
202 PUSH_TAG(poolptr
, aHidd_Sync_HMin
, sync
.width
);
203 PUSH_TAG(poolptr
, aHidd_Sync_HMax
, 4096);
205 PUSH_TAG(poolptr
, aHidd_Sync_Flags
, vHidd_Sync_VSyncPlus
);
206 PUSH_TAG(poolptr
, TAG_DONE
, 0);
209 static VOID
G45_parse_ddc(OOP_Class
*cl
, struct TagItem
**tagsptr
,
210 struct TagItem
*poolptr
, OOP_Object
*obj
)
212 struct pHidd_I2CDevice_WriteRead msg
;
219 D(bug("[GMA] Trying to parse the DDC data\n"));
221 msg
.mID
= OOP_GetMethodID((STRPTR
)IID_Hidd_I2CDevice
, moHidd_I2CDevice_WriteRead
);
222 msg
.readBuffer
= &edid
[0];
223 msg
.readLength
= 128;
224 msg
.writeBuffer
= &wb
[0];
227 OOP_DoMethod(obj
, &msg
.mID
);
229 for (i
=0; i
< 128; i
++)
233 edid
[0] == 0 && edid
[1] == 0xff && edid
[2] == 0xff && edid
[3] == 0xff &&
234 edid
[4] == 0xff && edid
[5] == 0xff && edid
[6] == 0xff && edid
[7] == 0)
236 D(bug("[GMA] Valid EDID%d.%d header\n", edid
[18], edid
[19]));
238 D(bug("[GMA] Established timing: %02x %02x %02x\n", edid
[35], edid
[36], edid
[37]));
240 createSync(cl
, 720, 400, 70, tagsptr
, &poolptr
);
242 createSync(cl
, 720, 400, 88, tagsptr
, &poolptr
);
244 createSync(cl
, 640, 480, 60, tagsptr
, &poolptr
);
246 createSync(cl
, 640, 480, 67, tagsptr
, &poolptr
);
248 createSync(cl
, 640, 480, 72, tagsptr
, &poolptr
);
250 createSync(cl
, 640, 480, 75, tagsptr
, &poolptr
);
252 createSync(cl
, 800, 600, 56, tagsptr
, &poolptr
);
254 createSync(cl
, 800, 600, 60, tagsptr
, &poolptr
);
256 createSync(cl
, 800, 600, 72, tagsptr
, &poolptr
);
258 createSync(cl
, 800, 600, 75, tagsptr
, &poolptr
);
260 createSync(cl
, 832, 624, 75, tagsptr
, &poolptr
);
262 createSync(cl
, 1024, 768, 60, tagsptr
, &poolptr
);
264 createSync(cl
, 1024, 768, 70, tagsptr
, &poolptr
);
266 createSync(cl
, 1024, 768, 75, tagsptr
, &poolptr
);
268 createSync(cl
, 1280, 1024, 75, tagsptr
, &poolptr
);
270 //createSync(cl, 736, 566, 60, tagsptr, &poolptr);
272 D(bug("[GMA] Standard timing identification:\n"));
274 for (i
=38; i
< 54; i
+=2)
277 w
= edid
[i
] * 8 + 248;
280 freq
= (edid
[i
+1] & 0x3f) + 60;
281 switch (edid
[i
+1] >> 6)
296 createSync(cl
, w
, h
, freq
, tagsptr
, &poolptr
);
300 for (i
=54; i
< 126; i
+= 18)
302 if (edid
[i
] || edid
[i
+1])
304 int ha
, hb
, va
, vb
, hsync_o
, hsync_w
, vsync_o
, vsync_w
, pixel
;
307 ha
|= (edid
[i
+4] >> 4) << 8;
308 hb
|= (edid
[i
+4] & 0x0f) << 8;
311 va
|= (edid
[i
+7] >> 4) << 8;
312 vb
|= (edid
[i
+7] & 0x0f) << 8;
315 vsync_o
= edid
[i
+10] >> 4;
316 vsync_w
= edid
[i
+10] & 0x0f;
317 hsync_o
|= 0x300 & ((edid
[i
+11] >> 6) << 8);
318 hsync_w
|= 0x300 & ((edid
[i
+11] >> 4) << 8);
319 vsync_o
|= 0x30 & ((edid
[i
+11] >> 2) << 4);
320 vsync_w
|= 0x30 & ((edid
[i
+11]) << 4);
322 pixel
= (edid
[i
] | (edid
[i
+1] << 8));
324 D(bug("[GMA] Modeline: "));
325 D(bug("%dx%d Pixel: %d0 kHz %d %d %d %d %d %d %d %d\n", ha
, va
, pixel
,
326 ha
, hb
, hsync_o
, hsync_w
,
327 va
, vb
, vsync_o
, vsync_w
));
329 description
= AllocVecPooled(sd
->MemPool
, MAX_MODE_NAME_LEN
+ 1);
330 snprintf(description
, MAX_MODE_NAME_LEN
, "GMA: %dx%d@%d N",
331 ha
, va
, (int)(((pixel
* 10 / (uint32_t)(ha
+ hb
)) * 1000)
332 / ((uint32_t)(va
+ vb
))));
334 PUSH_TAG(tagsptr
, aHidd_Gfx_SyncTags
, poolptr
);
336 PUSH_TAG(&poolptr
, aHidd_Sync_Description
, description
);
337 PUSH_TAG(&poolptr
, aHidd_Sync_PixelClock
, pixel
*10000);
339 PUSH_TAG(&poolptr
, aHidd_Sync_HDisp
, ha
);
340 PUSH_TAG(&poolptr
, aHidd_Sync_HSyncStart
, ha
+hsync_o
);
341 PUSH_TAG(&poolptr
, aHidd_Sync_HSyncEnd
, ha
+hsync_o
+hsync_w
);
342 PUSH_TAG(&poolptr
, aHidd_Sync_HTotal
, ha
+hb
);
344 PUSH_TAG(&poolptr
, aHidd_Sync_VDisp
, va
);
345 PUSH_TAG(&poolptr
, aHidd_Sync_VSyncStart
, va
+vsync_o
);
346 PUSH_TAG(&poolptr
, aHidd_Sync_VSyncEnd
, va
+vsync_o
+vsync_w
);
347 PUSH_TAG(&poolptr
, aHidd_Sync_VTotal
, va
+vb
);
349 PUSH_TAG(&poolptr
, aHidd_Sync_VMin
, va
);
350 PUSH_TAG(&poolptr
, aHidd_Sync_VMax
, 4096);
351 PUSH_TAG(&poolptr
, aHidd_Sync_HMin
, ha
);
352 PUSH_TAG(&poolptr
, aHidd_Sync_HMax
, 4096);
354 PUSH_TAG(&poolptr
, aHidd_Sync_Flags
, vHidd_Sync_VSyncPlus
);
355 PUSH_TAG(&poolptr
, TAG_DONE
, 0);
363 D(bug("[GMA] Monitor Serial: %s\n", &edid
[i
+5]));
366 D(bug("[GMA] ASCII String: %s\n", &edid
[i
+5]));
369 D(bug("[GMA] Monitor Name: %s\n", &edid
[i
+5]));
372 if (edid
[i
+10] == 0 && edid
[i
+11] == 0x0a)
374 D(bug("[GMA] Monitor limits: H: %d - %d kHz, V: %d - %d Hz, PixelClock: %dMHz\n",
375 edid
[i
+7], edid
[i
+8], edid
[i
+5], edid
[i
+6], edid
[i
+9]*10));
379 D(bug("[GMA] Entry %02x\n", edid
[i
+3]));
385 D(bug("[GMA] %d additional pages available\n", edid
[126]));
388 D(bug("[GMA] Not a valid EDID data\n"));
392 OOP_Object
*METHOD(INTELG45
, Root
, New
)
394 D(bug("[GMA] Root New\n"));
396 struct TagItem
*modetags
, *tags
;
397 struct TagItem
*poolptr
;
399 struct TagItem pftags_24bpp
[] = {
400 { aHidd_PixFmt_RedShift
, 8 }, /* 0 */
401 { aHidd_PixFmt_GreenShift
, 16 }, /* 1 */
402 { aHidd_PixFmt_BlueShift
, 24 }, /* 2 */
403 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
404 { aHidd_PixFmt_RedMask
, 0x00ff0000 }, /* 4 */
405 { aHidd_PixFmt_GreenMask
, 0x0000ff00 }, /* 5 */
406 { aHidd_PixFmt_BlueMask
, 0x000000ff }, /* 6 */
407 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
408 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
409 { aHidd_PixFmt_Depth
, 24 }, /* 9 */
410 { aHidd_PixFmt_BytesPerPixel
, 4 }, /* 10 */
411 { aHidd_PixFmt_BitsPerPixel
, 24 }, /* 11 */
412 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_BGR032
}, /* 12 Native */
413 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
417 struct TagItem pftags_16bpp
[] = {
418 { aHidd_PixFmt_RedShift
, 16 }, /* 0 */
419 { aHidd_PixFmt_GreenShift
, 21 }, /* 1 */
420 { aHidd_PixFmt_BlueShift
, 27 }, /* 2 */
421 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
422 { aHidd_PixFmt_RedMask
, 0x0000f800 }, /* 4 */
423 { aHidd_PixFmt_GreenMask
, 0x000007e0 }, /* 5 */
424 { aHidd_PixFmt_BlueMask
, 0x0000001f }, /* 6 */
425 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
426 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
427 { aHidd_PixFmt_Depth
, 16 }, /* 9 */
428 { aHidd_PixFmt_BytesPerPixel
, 2 }, /* 10 */
429 { aHidd_PixFmt_BitsPerPixel
, 16 }, /* 11 */
430 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_RGB16_LE
}, /* 12 */
431 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
435 // struct TagItem pftags_15bpp[] = {
436 // { aHidd_PixFmt_RedShift, 17 }, /* 0 */
437 // { aHidd_PixFmt_GreenShift, 22 }, /* 1 */
438 // { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
439 // { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
440 // { aHidd_PixFmt_RedMask, 0x00007c00 }, /* 4 */
441 // { aHidd_PixFmt_GreenMask, 0x000003e0 }, /* 5 */
442 // { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
443 // { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
444 // { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
445 // { aHidd_PixFmt_Depth, 15 }, /* 9 */
446 // { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
447 // { aHidd_PixFmt_BitsPerPixel, 15 }, /* 11 */
448 // { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB15_LE }, /* 12 */
449 // { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
455 modetags
= tags
= AllocVecPooled(sd
->MemPool
,
456 sizeof (struct TagItem
) * (3 + SYNC_LIST_COUNT
+ 1));
457 poolptr
= AllocVecPooled(sd
->MemPool
,
458 sizeof(struct TagItem
) * SYNC_TAG_COUNT
* SYNC_LIST_COUNT
);
460 struct TagItem i2c_attrs
[] = {
461 // { aHidd_I2C_HoldTime, 40 },
462 // { aHidd_I2C_RiseFallTime, 40 },
466 tags
->ti_Tag
= aHidd_Gfx_PixFmtTags
;
467 tags
->ti_Data
= (IPTR
)pftags_24bpp
;
470 tags
->ti_Tag
= aHidd_Gfx_PixFmtTags
;
471 tags
->ti_Data
= (IPTR
)pftags_16bpp
;
474 // tags->ti_Tag = aHidd_Gfx_PixFmtTags;
475 // tags->ti_Data = (IPTR)pftags_15bpp;
478 if( sd
->pipe
== PIPE_B
)
480 char *description
= AllocVecPooled(sd
->MemPool
, MAX_MODE_NAME_LEN
+ 1);
481 snprintf(description
, MAX_MODE_NAME_LEN
, "GMA_LVDS:%dx%d",
482 sd
->lvds_fixed
.hdisp
, sd
->lvds_fixed
.vdisp
);
485 struct TagItem sync_native
[]={
486 { aHidd_Sync_PixelClock
,sd
->lvds_fixed
.pixelclock
*1000000 },
487 { aHidd_Sync_HDisp
, sd
->lvds_fixed
.hdisp
},
488 { aHidd_Sync_HSyncStart
,sd
->lvds_fixed
.hstart
},
489 { aHidd_Sync_HSyncEnd
, sd
->lvds_fixed
.hend
},
490 { aHidd_Sync_HTotal
, sd
->lvds_fixed
.htotal
},
491 { aHidd_Sync_VDisp
, sd
->lvds_fixed
.vdisp
},
492 { aHidd_Sync_VSyncStart
,sd
->lvds_fixed
.vstart
},
493 { aHidd_Sync_VSyncEnd
, sd
->lvds_fixed
.vend
},
494 { aHidd_Sync_VTotal
, sd
->lvds_fixed
.vtotal
},
495 { aHidd_Sync_VMin
, sd
->lvds_fixed
.vdisp
},
496 { aHidd_Sync_VMax
, 4096},
497 { aHidd_Sync_HMin
, sd
->lvds_fixed
.hdisp
},
498 { aHidd_Sync_HMax
, 4096},
499 { aHidd_Sync_Description
, (IPTR
)description
},
502 MAKE_SYNC(640x480_60
, 25174,
507 tags
->ti_Tag
= aHidd_Gfx_SyncTags
;
508 tags
->ti_Data
= (IPTR
)sync_640x480_60
;
511 tags
->ti_Tag
= aHidd_Gfx_SyncTags
;
512 tags
->ti_Data
= (IPTR
)sync_native
;
519 i2c
= OOP_NewObject(sd
->IntelI2C
, NULL
, i2c_attrs
);
523 if (HIDD_I2C_ProbeAddress(i2c
, 0xa0))
525 struct TagItem attrs
[] = {
526 { aHidd_I2CDevice_Driver
, (IPTR
)i2c
},
527 { aHidd_I2CDevice_Address
, 0xa0 },
528 { aHidd_I2CDevice_Name
, (IPTR
)"Display" },
532 D(bug("[GMA] I2C device found\n"));
534 OOP_Object
*obj
= OOP_NewObject(NULL
, CLID_Hidd_I2CDevice
, attrs
);
538 G45_parse_ddc(cl
, &tags
, poolptr
, obj
);
540 OOP_DisposeObject(obj
);
543 OOP_DisposeObject(i2c
);
548 tags
->ti_Tag
= TAG_DONE
;
551 struct TagItem mytags
[] = {
552 { aHidd_Gfx_ModeTags
, (IPTR
)modetags
},
553 { TAG_MORE
, (IPTR
)msg
->attrList
}
556 struct pRoot_New mymsg
;
558 mymsg
.mID
= msg
->mID
;
559 mymsg
.attrList
= mytags
;
563 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
567 /* Create compositing object */
569 struct TagItem comptags
[] =
571 { aHidd_Compositing_GfxHidd
, (IPTR
)o
},
572 { TAG_DONE
, TAG_DONE
}
574 sd
->compositing
= OOP_NewObject(sd
->compositingclass
, NULL
, comptags
);
575 /* TODO: Check if object was created, how to handle ? */
579 FreeVecPooled(sd
->MemPool
, modetags
);
580 FreeVecPooled(sd
->MemPool
, poolptr
);
582 D(bug("[GMA] INTELG45::New() = %p\n", o
));
587 void METHOD(INTELG45
, Root
, Get
)
589 D(bug("[GMA] Root Get\n"));
593 if (IS_GFX_ATTR(msg
->attrID
, idx
))
597 case aoHidd_Gfx_SupportsHWCursor
:
598 *msg
->storage
= (IPTR
)TRUE
;
602 case aoHidd_Gfx_NoFrameBuffer
:
603 *msg
->storage
= (IPTR
)TRUE
;
607 case aoHidd_Gfx_HWSpriteTypes
:
608 *msg
->storage
= vHidd_SpriteType_DirectColor
;
612 case aoHidd_Gfx_DPMSLevel
:
613 *msg
->storage
= SD(cl
)->dpms
;
620 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
625 void METHOD(INTELG45
, Root
, Set
)
627 D(bug("[GMA] Root Set\n"));
631 struct TagItem
*tags
= msg
->attrList
;
633 while ((tag
= NextTagItem(&tags
)))
635 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
639 case aoHidd_Gfx_DPMSLevel
:
641 uint32_t adpa
= readl(sd
->Card
.MMIO
+ G45_ADPA
) & ~G45_ADPA_DPMS_MASK
;
642 switch (tag
->ti_Data
)
644 case vHidd_Gfx_DPMSLevel_On
:
645 adpa
|= G45_ADPA_DPMS_ON
;
647 case vHidd_Gfx_DPMSLevel_Off
:
648 adpa
|= G45_ADPA_DPMS_OFF
;
650 case vHidd_Gfx_DPMSLevel_Standby
:
651 adpa
|= G45_ADPA_DPMS_STANDBY
;
653 case vHidd_Gfx_DPMSLevel_Suspend
:
654 adpa
|= G45_ADPA_DPMS_SUSPEND
;
657 writel(adpa
, sd
->Card
.MMIO
+ G45_ADPA
);
658 sd
->dpms
= tag
->ti_Data
;
666 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
670 OOP_Object
* METHOD(INTELG45
, Hidd_Gfx
, CreateObject
)
672 OOP_Object
*object
= NULL
;
674 if (msg
->cl
== SD(cl
)->basebm
)
676 struct pHidd_Gfx_CreateObject mymsg
;
678 HIDDT_StdPixFmt stdpf
;
680 struct TagItem mytags
[] =
682 { TAG_IGNORE
, TAG_IGNORE
}, /* Placeholder for aHidd_BitMap_ClassPtr */
683 { TAG_IGNORE
, TAG_IGNORE
}, /* Placeholder for aHidd_BitMap_Align */
684 { aHidd_BitMap_IntelG45_CompositingHidd
, (IPTR
)sd
->compositing
},
685 { TAG_MORE
, (IPTR
)msg
->attrList
}
688 /* Check if user provided valid ModeID */
689 /* Check for framebuffer - not needed as IntelG45 is a NoFramebuffer driver */
690 /* Check for displayable - not needed - displayable has ModeID and we don't
691 distinguish between on-screen and off-screen bitmaps */
692 modeid
= (HIDDT_ModeID
)GetTagData(aHidd_BitMap_ModeID
, vHidd_ModeID_Invalid
, msg
->attrList
);
693 if (vHidd_ModeID_Invalid
!= modeid
)
695 /* User supplied a valid modeid. We can use our bitmap class */
696 mytags
[0].ti_Tag
= aHidd_BitMap_ClassPtr
;
697 mytags
[0].ti_Data
= (IPTR
)SD(cl
)->BMClass
;
700 /* Check if bitmap is a planar bitmap */
701 stdpf
= (HIDDT_StdPixFmt
)GetTagData(aHidd_BitMap_StdPixFmt
, vHidd_StdPixFmt_Unknown
, msg
->attrList
);
702 if (vHidd_StdPixFmt_Plane
== stdpf
)
704 mytags
[1].ti_Tag
= aHidd_BitMap_Align
;
705 mytags
[1].ti_Data
= 32;
708 /* We init a new message struct */
709 mymsg
.mID
= msg
->mID
;
711 mymsg
.attrList
= mytags
;
713 /* Pass the new message to the superclass */
714 object
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)&mymsg
);
716 else if (SD(cl
)->basegallium
&& (msg
->cl
== SD(cl
)->basegallium
))
718 object
= OOP_NewObject(NULL
, CLID_Hidd_Gallium_IntelGMA
, msg
->attrList
);
721 object
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
727 void METHOD(INTELG45
, Hidd_Gfx
, SetCursorVisible
)
729 sd
->CursorVisible
= msg
->visible
;
732 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_ARGB
,
733 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
737 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_OFF
,
738 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
744 void METHOD(INTELG45
, Hidd_Gfx
, SetCursorPos
)
746 SetCursorPosition(sd
,msg
->x
,msg
->y
);
747 sd
->pointerx
= msg
->x
;
748 sd
->pointery
= msg
->y
;
751 BOOL
METHOD(INTELG45
, Hidd_Gfx
, SetCursorShape
)
753 if (msg
->shape
== NULL
)
755 sd
->CursorVisible
= 0;
756 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_OFF
,
757 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
761 IPTR width
, height
, x
;
763 ULONG
*curimg
= (ULONG
*)((IPTR
)sd
->CursorImage
+ (IPTR
)sd
->Card
.Framebuffer
);
765 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Width
, &width
);
766 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Height
, &height
);
768 if (width
> 64) width
= 64;
769 if (height
> 64) height
= 64;
771 for (x
= 0; x
< 64*64; x
++)
774 HIDD_BM_GetImage(msg
->shape
, (UBYTE
*)curimg
, 64*4, 0, 0, width
, height
, vHidd_StdPixFmt_BGRA32
);
775 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_ARGB
,
776 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
783 void METHOD(INTELG45
, Hidd_Gfx
, CopyBox
)
785 ULONG mode
= GC_DRMD(msg
->gc
);
788 /* Check whether we can get Drawable attribute of our GMA class */
789 OOP_GetAttr(msg
->src
, aHidd_GMABitMap_Drawable
, &src
);
790 OOP_GetAttr(msg
->dest
, aHidd_GMABitMap_Drawable
, &dst
);
794 /* No. One of the bitmaps is not a GMA bitmap */
795 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
799 /* Yes. Get the instance data of both bitmaps */
800 GMABitMap_t
*bm_src
= OOP_INST_DATA(OOP_OCLASS(msg
->src
), msg
->src
);
801 GMABitMap_t
*bm_dst
= OOP_INST_DATA(OOP_OCLASS(msg
->dest
), msg
->dest
);
803 // D(bug("[GMA] CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
804 // bm_src->framebuffer,msg->srcX,msg->srcY,bm_src->depth,
805 // bm_dst->framebuffer,msg->destX,msg->destY,bm_dst->depth,
806 // msg->width, msg->height));
808 /* Case -1: (To be fixed) one of the bitmaps have chunky outside GFX mem */
809 if (!bm_src
->fbgfx
|| !bm_dst
->fbgfx
)
811 D(bug("[GMA] one of bitmaps outside VRAM! CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
812 bm_src
->framebuffer
,msg
->srcX
,msg
->srcY
,bm_src
->depth
,
813 bm_dst
->framebuffer
,msg
->destX
,msg
->destY
,bm_dst
->depth
,
814 msg
->width
, msg
->height
));
816 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
818 /* Case 0: one of bitmaps is 8bpp, whereas the other is TrueColor one */
819 else if ((bm_src
->depth
<= 8 || bm_dst
->depth
<= 8) &&
820 (bm_src
->depth
!= bm_dst
->depth
))
822 /* Unsupported case */
823 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
826 /* Case 1: both bitmaps have the same depth - use Blit engine */
827 else if (bm_src
->depth
== bm_dst
->depth
)
830 LOCK_BITMAP_BM(bm_src
)
831 LOCK_BITMAP_BM(bm_dst
)
836 uint32_t br00
, br13
, br22
, br23
, br09
, br11
, br26
, br12
;
838 br00
= (2 << 29) | (0x53 << 22) | (6);
839 if (bm_dst
->bpp
== 4)
842 br13
= bm_dst
->pitch
| ROP_table
[mode
].rop
;
843 if (bm_dst
->bpp
== 4)
845 else if (bm_dst
->bpp
== 2)
848 br22
= msg
->destX
| (msg
->destY
<< 16);
849 br23
= (msg
->destX
+ msg
->width
) | (msg
->destY
+ msg
->height
) << 16;
850 br09
= bm_dst
->framebuffer
;
851 br11
= bm_src
->pitch
;
852 br26
= msg
->srcX
| (msg
->srcY
<< 16);
853 br12
= bm_src
->framebuffer
;
871 UNLOCK_BITMAP_BM(bm_src
)
872 UNLOCK_BITMAP_BM(bm_dst
)
874 else /* Case 2: different bitmaps.Use 3d hardware. */
876 D(bug("[GMA] Depth mismatch! CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
877 bm_src
->framebuffer
,msg
->srcX
,msg
->srcY
,bm_src
->depth
,
878 bm_dst
->framebuffer
,msg
->destX
,msg
->destY
,bm_dst
->depth
,
879 msg
->width
, msg
->height
));
882 LOCK_BITMAP_BM(bm_src
)
883 LOCK_BITMAP_BM(bm_dst
)
886 BOOL done
= copybox3d( bm_dst
, bm_src
,
887 msg
->destX
, msg
->destY
, msg
->width
, msg
->height
,
888 msg
->srcX
, msg
->srcY
, msg
->width
, msg
->height
);
890 UNLOCK_BITMAP_BM(bm_src
)
891 UNLOCK_BITMAP_BM(bm_dst
)
893 if( ! done
) OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
898 ULONG
METHOD(INTELG45
, Hidd_Gfx
, ShowViewPorts
)
900 struct pHidd_Compositing_BitMapStackChanged bscmsg
=
902 mID
: OOP_GetMethodID(IID_Hidd_Compositing
, moHidd_Compositing_BitMapStackChanged
),
905 D(bug("[IntelG45] ShowViewPorts enter TopLevelBM %x\n", msg
->Data
->Bitmap
));
906 OOP_DoMethod(sd
->compositing
, (OOP_Msg
)&bscmsg
);
907 return TRUE
; /* Indicate driver supports this method */
910 BOOL
HIDD_INTELG45_SwitchToVideoMode(OOP_Object
* bm
)
912 OOP_Class
* cl
= OOP_OCLASS(bm
);
913 GMABitMap_t
* bmdata
= OOP_INST_DATA(cl
, bm
);
914 OOP_Object
* gfx
= NULL
;
919 IPTR hdisp
, vdisp
, hstart
, hend
, htotal
, vstart
, vend
, vtotal
;
921 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, &e
);
922 gfx
= (OOP_Object
*)e
;
924 bug("[IntelG45] HIDD_INTELG45_SwitchToVideoMode bitmap:%x\n",bmdata
);
926 /* We should be able to get modeID from the bitmap */
927 OOP_GetAttr(bm
, aHidd_BitMap_ModeID
, &modeid
);
929 if (modeid
== vHidd_ModeID_Invalid
)
931 D(bug("[IntelG45] Invalid ModeID\n"));
935 /* Get Sync and PixelFormat properties */
936 struct pHidd_Gfx_GetMode __getmodemsg
=
941 }, *getmodemsg
= &__getmodemsg
;
943 getmodemsg
->mID
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_GetMode
);
944 OOP_DoMethod(gfx
, (OOP_Msg
)getmodemsg
);
946 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixel
);
947 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &hdisp
);
948 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &vdisp
);
949 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &hstart
);
950 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &vstart
);
951 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &hend
);
952 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &vend
);
953 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &htotal
);
954 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &vtotal
);
956 D(bug("[IntelG45] Sync: %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
957 pixel
, hdisp
, hstart
, hend
, htotal
, vdisp
, vstart
, vend
, vtotal
));
959 if (bmdata
->state
&& sd
->VisibleBitmap
!= bmdata
)
961 /* Suppose bm has properly allocated state structure */
965 SetCursorPosition(sd
,0,0);
967 sd
->VisibleBitmap
= bmdata
;
968 G45_LoadState(sd
, bmdata
->state
);
970 SetCursorPosition(sd
,sd
->pointerx
,sd
->pointery
);
979 BOOL
HIDD_INTELG45_SetFramebuffer(OOP_Object
* bm
)
981 OOP_Class
* cl
= OOP_OCLASS(bm
);
982 GMABitMap_t
* bmdata
= OOP_INST_DATA(cl
, bm
);
983 //bug("[IntelG45] HIDD_INTELG45_SetFramebuffer %x %d,%d\n",bmdata,bmdata->xoffset,bmdata->yoffset);
986 char *linoff_reg
= sd
->Card
.MMIO
+ ((sd
->pipe
== PIPE_A
) ? G45_DSPALINOFF
: G45_DSPBLINOFF
);
987 char *stride_reg
= sd
->Card
.MMIO
+ ((sd
->pipe
== PIPE_A
) ? G45_DSPASTRIDE
: G45_DSPBSTRIDE
);
989 // bitmap width in bytes
990 writel( bmdata
->state
->dspstride
, stride_reg
);
992 // framebuffer address + possible xy offset
993 writel( bmdata
->framebuffer
- ( bmdata
->yoffset
* bmdata
->pitch
+
994 bmdata
->xoffset
* bmdata
->bpp
) ,linoff_reg
);
998 //bug("[IntelG45] HIDD_INTELG45_SetFramebuffer: not Framebuffer Bitmap!\n");
1003 static struct HIDD_ModeProperties modeprops
=
1010 ULONG
METHOD(INTELG45
, Hidd_Gfx
, ModeProperties
)
1012 ULONG len
= msg
->propsLen
;
1013 if (len
> sizeof(modeprops
))
1014 len
= sizeof(modeprops
);
1015 CopyMem(&modeprops
, msg
->props
, len
);
1020 static const struct OOP_MethodDescr INTELG45_Root_descr
[] =
1022 {(OOP_MethodFunc
)INTELG45__Root__New
, moRoot_New
},
1023 {(OOP_MethodFunc
)INTELG45__Root__Get
, moRoot_Get
},
1024 {(OOP_MethodFunc
)INTELG45__Root__Set
, moRoot_Set
},
1027 #define NUM_INTELG45_Root_METHODS 3
1029 static const struct OOP_MethodDescr INTELG45_Hidd_Gfx_descr
[] =
1031 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__CopyBox
, moHidd_Gfx_CopyBox
},
1032 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__CreateObject
, moHidd_Gfx_CreateObject
},
1033 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__SetCursorVisible
, moHidd_Gfx_SetCursorVisible
},
1034 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__SetCursorPos
, moHidd_Gfx_SetCursorPos
},
1035 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__SetCursorShape
, moHidd_Gfx_SetCursorShape
},
1036 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__ShowViewPorts
, moHidd_Gfx_ShowViewPorts
},
1037 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__ModeProperties
, moHidd_Gfx_ModeProperties
},
1040 #define NUM_INTELG45_Hidd_Gfx_METHODS 7
1042 const struct OOP_InterfaceDescr INTELG45_ifdescr
[] =
1044 {INTELG45_Root_descr
, IID_Root
, NUM_INTELG45_Root_METHODS
},
1045 {INTELG45_Hidd_Gfx_descr
, IID_Hidd_Gfx
, NUM_INTELG45_Hidd_Gfx_METHODS
},