2 Copyright © 1995-2019, 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>
15 #include <graphics/displayinfo.h>
16 #include <proto/oop.h>
17 #include <proto/exec.h>
18 #include <proto/utility.h>
23 #include "intelgma_hidd.h"
24 #include "intelG45_regs.h"
25 #include "intelgma_gallium.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 */
453 OOP_Object
*i2cBus
= NULL
;
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
;
518 i2cBus
= OOP_NewObject(sd
->IntelI2C
, NULL
, i2c_attrs
);
522 if (HIDD_I2C_ProbeAddress(i2cBus
, 0xa0))
524 struct TagItem attrs
[] = {
525 { aHidd_I2CDevice_Driver
, (IPTR
)i2cBus
},
526 { aHidd_I2CDevice_Address
, 0xa0 },
527 { aHidd_I2CDevice_Name
, (IPTR
)"Display" },
531 D(bug("[GMA] I2C display device found\n"));
533 OOP_Object
*i2cDev
= OOP_NewObject(NULL
, CLID_Hidd_I2CDevice
, attrs
);
537 G45_parse_ddc(cl
, &tags
, poolptr
, i2cDev
);
544 tags
->ti_Tag
= TAG_DONE
;
547 struct TagItem mytags
[] = {
548 { aHidd_Gfx_ModeTags
, (IPTR
)modetags
},
549 { aHidd_Name
, (IPTR
)"IntelGMA" },
550 { aHidd_HardwareName
, (IPTR
)"Intel GMA Display Adaptor" },
551 { aHidd_ProducerName
, (IPTR
)"Intel Corporation" },
552 { TAG_MORE
, (IPTR
)msg
->attrList
}
555 struct pRoot_New mymsg
;
557 mymsg
.mID
= msg
->mID
;
558 mymsg
.attrList
= mytags
;
562 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
565 struct g45data
* gfxdata
= OOP_INST_DATA(cl
, o
);
566 gfxdata
->i2cobj
= i2cBus
;
569 /* Create compositor object */
571 struct TagItem comptags
[] =
573 { aHidd_Compositor_GfxHidd
, (IPTR
)o
},
574 { TAG_DONE
, TAG_DONE
}
576 sd
->compositor
= OOP_NewObject(sd
->compositorclass
, NULL
, comptags
);
577 /* TODO: Check if object was created, how to handle ? */
581 FreeVecPooled(sd
->MemPool
, modetags
);
582 FreeVecPooled(sd
->MemPool
, poolptr
);
584 D(bug("[GMA] INTELG45::New() = %p\n", o
));
589 void METHOD(INTELG45
, Root
, Get
)
591 D(bug("[GMA] Root Get\n"));
595 if (IS_GFX_ATTR(msg
->attrID
, idx
))
599 case aoHidd_Gfx_SupportsHWCursor
:
600 *msg
->storage
= (IPTR
)TRUE
;
604 case aoHidd_Gfx_NoFrameBuffer
:
605 *msg
->storage
= (IPTR
)TRUE
;
609 case aoHidd_Gfx_HWSpriteTypes
:
610 *msg
->storage
= vHidd_SpriteType_DirectColor
;
614 case aoHidd_Gfx_DPMSLevel
:
615 *msg
->storage
= SD(cl
)->dpms
;
622 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
627 void METHOD(INTELG45
, Root
, Set
)
629 D(bug("[GMA] Root Set\n"));
633 struct TagItem
*tags
= msg
->attrList
;
635 while ((tag
= NextTagItem(&tags
)))
637 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
641 case aoHidd_Gfx_DPMSLevel
:
643 uint32_t adpa
= readl(sd
->Card
.MMIO
+ G45_ADPA
) & ~G45_ADPA_DPMS_MASK
;
644 switch (tag
->ti_Data
)
646 case vHidd_Gfx_DPMSLevel_On
:
647 adpa
|= G45_ADPA_DPMS_ON
;
649 case vHidd_Gfx_DPMSLevel_Off
:
650 adpa
|= G45_ADPA_DPMS_OFF
;
652 case vHidd_Gfx_DPMSLevel_Standby
:
653 adpa
|= G45_ADPA_DPMS_STANDBY
;
655 case vHidd_Gfx_DPMSLevel_Suspend
:
656 adpa
|= G45_ADPA_DPMS_SUSPEND
;
659 writel(adpa
, sd
->Card
.MMIO
+ G45_ADPA
);
660 sd
->dpms
= tag
->ti_Data
;
668 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
672 OOP_Object
* METHOD(INTELG45
, Hidd_Gfx
, CreateObject
)
674 OOP_Object
*object
= NULL
;
676 if (msg
->cl
== SD(cl
)->basebm
)
678 struct pHidd_Gfx_CreateObject mymsg
;
680 HIDDT_StdPixFmt stdpf
;
682 struct TagItem mytags
[] =
684 { TAG_IGNORE
, TAG_IGNORE
}, /* Placeholder for aHidd_BitMap_ClassPtr */
685 { TAG_IGNORE
, TAG_IGNORE
}, /* Placeholder for aHidd_BitMap_Align */
686 { aHidd_BitMap_IntelG45_CompositorHidd
, (IPTR
)sd
->compositor
},
687 { TAG_MORE
, (IPTR
)msg
->attrList
}
690 /* Check if user provided valid ModeID */
691 /* Check for framebuffer - not needed as IntelG45 is a NoFramebuffer driver */
692 /* Check for displayable - not needed - displayable has ModeID and we don't
693 distinguish between on-screen and off-screen bitmaps */
694 modeid
= (HIDDT_ModeID
)GetTagData(aHidd_BitMap_ModeID
, vHidd_ModeID_Invalid
, msg
->attrList
);
695 if (vHidd_ModeID_Invalid
!= modeid
)
697 /* User supplied a valid modeid. We can use our bitmap class */
698 mytags
[0].ti_Tag
= aHidd_BitMap_ClassPtr
;
699 mytags
[0].ti_Data
= (IPTR
)SD(cl
)->BMClass
;
702 /* Check if bitmap is a planar bitmap */
703 stdpf
= (HIDDT_StdPixFmt
)GetTagData(aHidd_BitMap_StdPixFmt
, vHidd_StdPixFmt_Unknown
, msg
->attrList
);
704 if (vHidd_StdPixFmt_Plane
== stdpf
)
706 mytags
[1].ti_Tag
= aHidd_BitMap_Align
;
707 mytags
[1].ti_Data
= 32;
710 /* We init a new message struct */
711 mymsg
.mID
= msg
->mID
;
713 mymsg
.attrList
= mytags
;
715 /* Pass the new message to the superclass */
716 object
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)&mymsg
);
718 else if (SD(cl
)->basegallium
&& (msg
->cl
== SD(cl
)->basegallium
))
720 /* Create the gallium 3d driver object .. */
721 object
= OOP_NewObject(NULL
, CLID_Hidd_Gallium_IntelGMA
, msg
->attrList
);
723 else if (SD(cl
)->basei2c
&& (msg
->cl
== SD(cl
)->basei2c
))
725 struct g45data
* gfxdata
= OOP_INST_DATA(cl
, o
);
726 /* Expose the i2c bus object .. */
727 object
= gfxdata
->i2cobj
;
730 object
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
736 void METHOD(INTELG45
, Hidd_Gfx
, SetCursorVisible
)
738 sd
->CursorVisible
= msg
->visible
;
741 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_ARGB
,
742 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
746 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_OFF
,
747 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
753 void METHOD(INTELG45
, Hidd_Gfx
, SetCursorPos
)
755 SetCursorPosition(sd
,msg
->x
,msg
->y
);
756 sd
->pointerx
= msg
->x
;
757 sd
->pointery
= msg
->y
;
760 BOOL
METHOD(INTELG45
, Hidd_Gfx
, SetCursorShape
)
762 if (msg
->shape
== NULL
)
764 sd
->CursorVisible
= 0;
765 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_OFF
,
766 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
770 IPTR width
, height
, x
;
772 ULONG
*curimg
= (ULONG
*)((IPTR
)sd
->CursorImage
+ (IPTR
)sd
->Card
.Framebuffer
);
774 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Width
, &width
);
775 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Height
, &height
);
777 if (width
> 64) width
= 64;
778 if (height
> 64) height
= 64;
780 for (x
= 0; x
< 64*64; x
++)
783 HIDD_BM_GetImage(msg
->shape
, (UBYTE
*)curimg
, 64*4, 0, 0, width
, height
, vHidd_StdPixFmt_BGRA32
);
784 writel( (sd
->pipe
== PIPE_A
? G45_CURCNTR_PIPE_A
: G45_CURCNTR_PIPE_B
) | G45_CURCNTR_TYPE_ARGB
,
785 sd
->Card
.MMIO
+ (sd
->pipe
== PIPE_A
? G45_CURACNTR
:G45_CURBCNTR
));
792 void METHOD(INTELG45
, Hidd_Gfx
, CopyBox
)
794 ULONG mode
= GC_DRMD(msg
->gc
);
797 /* Check whether we can get Drawable attribute of our GMA class */
798 OOP_GetAttr(msg
->src
, aHidd_GMABitMap_Drawable
, &src
);
799 OOP_GetAttr(msg
->dest
, aHidd_GMABitMap_Drawable
, &dst
);
803 /* No. One of the bitmaps is not a GMA bitmap */
804 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
808 /* Yes. Get the instance data of both bitmaps */
809 GMABitMap_t
*bm_src
= OOP_INST_DATA(OOP_OCLASS(msg
->src
), msg
->src
);
810 GMABitMap_t
*bm_dst
= OOP_INST_DATA(OOP_OCLASS(msg
->dest
), msg
->dest
);
812 // D(bug("[GMA] CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
813 // bm_src->framebuffer,msg->srcX,msg->srcY,bm_src->depth,
814 // bm_dst->framebuffer,msg->destX,msg->destY,bm_dst->depth,
815 // msg->width, msg->height));
817 /* Case -1: (To be fixed) one of the bitmaps have chunky outside GFX mem */
818 if (!bm_src
->fbgfx
|| !bm_dst
->fbgfx
)
820 D(bug("[GMA] one of bitmaps outside VRAM! CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
821 bm_src
->framebuffer
,msg
->srcX
,msg
->srcY
,bm_src
->depth
,
822 bm_dst
->framebuffer
,msg
->destX
,msg
->destY
,bm_dst
->depth
,
823 msg
->width
, msg
->height
));
825 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
827 /* Case 0: one of bitmaps is 8bpp, whereas the other is TrueColor one */
828 else if ((bm_src
->depth
<= 8 || bm_dst
->depth
<= 8) &&
829 (bm_src
->depth
!= bm_dst
->depth
))
831 /* Unsupported case */
832 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
835 /* Case 1: both bitmaps have the same depth - use Blit engine */
836 else if (bm_src
->depth
== bm_dst
->depth
)
839 LOCK_BITMAP_BM(bm_src
)
840 LOCK_BITMAP_BM(bm_dst
)
845 uint32_t br00
, br13
, br22
, br23
, br09
, br11
, br26
, br12
;
847 br00
= (2 << 29) | (0x53 << 22) | (6);
848 if (bm_dst
->bpp
== 4)
851 br13
= bm_dst
->pitch
| ROP_table
[mode
].rop
;
852 if (bm_dst
->bpp
== 4)
854 else if (bm_dst
->bpp
== 2)
857 br22
= msg
->destX
| (msg
->destY
<< 16);
858 br23
= (msg
->destX
+ msg
->width
) | (msg
->destY
+ msg
->height
) << 16;
859 br09
= bm_dst
->framebuffer
;
860 br11
= bm_src
->pitch
;
861 br26
= msg
->srcX
| (msg
->srcY
<< 16);
862 br12
= bm_src
->framebuffer
;
880 UNLOCK_BITMAP_BM(bm_src
)
881 UNLOCK_BITMAP_BM(bm_dst
)
883 else /* Case 2: different bitmaps.Use 3d hardware. */
885 D(bug("[GMA] Depth mismatch! CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
886 bm_src
->framebuffer
,msg
->srcX
,msg
->srcY
,bm_src
->depth
,
887 bm_dst
->framebuffer
,msg
->destX
,msg
->destY
,bm_dst
->depth
,
888 msg
->width
, msg
->height
));
891 LOCK_BITMAP_BM(bm_src
)
892 LOCK_BITMAP_BM(bm_dst
)
895 BOOL done
= copybox3d( bm_dst
, bm_src
,
896 msg
->destX
, msg
->destY
, msg
->width
, msg
->height
,
897 msg
->srcX
, msg
->srcY
, msg
->width
, msg
->height
);
899 UNLOCK_BITMAP_BM(bm_src
)
900 UNLOCK_BITMAP_BM(bm_dst
)
902 if( ! done
) OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
907 ULONG
METHOD(INTELG45
, Hidd_Gfx
, ShowViewPorts
)
909 struct pHidd_Compositor_BitMapStackChanged bscmsg
=
911 mID
: OOP_GetMethodID(IID_Hidd_Compositor
, moHidd_Compositor_BitMapStackChanged
),
914 D(bug("[IntelG45] ShowViewPorts enter TopLevelBM %x\n", msg
->Data
->Bitmap
));
915 OOP_DoMethod(sd
->compositor
, (OOP_Msg
)&bscmsg
);
916 return TRUE
; /* Indicate driver supports this method */
919 BOOL
HIDD_INTELG45_SwitchToVideoMode(OOP_Object
* bm
)
921 OOP_Class
* cl
= OOP_OCLASS(bm
);
922 GMABitMap_t
* bmdata
= OOP_INST_DATA(cl
, bm
);
923 OOP_Object
* gfx
= NULL
;
928 IPTR hdisp
, vdisp
, hstart
, hend
, htotal
, vstart
, vend
, vtotal
;
930 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, &e
);
931 gfx
= (OOP_Object
*)e
;
933 bug("[IntelG45] HIDD_INTELG45_SwitchToVideoMode bitmap:%x\n",bmdata
);
935 /* We should be able to get modeID from the bitmap */
936 OOP_GetAttr(bm
, aHidd_BitMap_ModeID
, &modeid
);
938 if (modeid
== vHidd_ModeID_Invalid
)
940 D(bug("[IntelG45] Invalid ModeID\n"));
944 /* Get Sync and PixelFormat properties */
945 struct pHidd_Gfx_GetMode __getmodemsg
=
950 }, *getmodemsg
= &__getmodemsg
;
952 getmodemsg
->mID
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_GetMode
);
953 OOP_DoMethod(gfx
, (OOP_Msg
)getmodemsg
);
955 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixel
);
956 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &hdisp
);
957 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &vdisp
);
958 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &hstart
);
959 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &vstart
);
960 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &hend
);
961 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &vend
);
962 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &htotal
);
963 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &vtotal
);
965 D(bug("[IntelG45] Sync: %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
966 pixel
, hdisp
, hstart
, hend
, htotal
, vdisp
, vstart
, vend
, vtotal
));
968 if (bmdata
->state
&& sd
->VisibleBitmap
!= bmdata
)
970 /* Suppose bm has properly allocated state structure */
974 SetCursorPosition(sd
,0,0);
976 sd
->VisibleBitmap
= bmdata
;
977 G45_LoadState(sd
, bmdata
->state
);
979 SetCursorPosition(sd
,sd
->pointerx
,sd
->pointery
);
988 BOOL
HIDD_INTELG45_SetFramebuffer(OOP_Object
* bm
)
990 OOP_Class
* cl
= OOP_OCLASS(bm
);
991 GMABitMap_t
* bmdata
= OOP_INST_DATA(cl
, bm
);
992 //bug("[IntelG45] HIDD_INTELG45_SetFramebuffer %x %d,%d\n",bmdata,bmdata->xoffset,bmdata->yoffset);
995 char *linoff_reg
= sd
->Card
.MMIO
+ ((sd
->pipe
== PIPE_A
) ? G45_DSPALINOFF
: G45_DSPBLINOFF
);
996 char *stride_reg
= sd
->Card
.MMIO
+ ((sd
->pipe
== PIPE_A
) ? G45_DSPASTRIDE
: G45_DSPBSTRIDE
);
998 // bitmap width in bytes
999 writel( bmdata
->state
->dspstride
, stride_reg
);
1001 // framebuffer address + possible xy offset
1002 writel( bmdata
->framebuffer
- ( bmdata
->yoffset
* bmdata
->pitch
+
1003 bmdata
->xoffset
* bmdata
->bpp
) ,linoff_reg
);
1004 readl( linoff_reg
);
1007 //bug("[IntelG45] HIDD_INTELG45_SetFramebuffer: not Framebuffer Bitmap!\n");
1012 static struct HIDD_ModeProperties modeprops
=
1019 ULONG
METHOD(INTELG45
, Hidd_Gfx
, ModeProperties
)
1021 ULONG len
= msg
->propsLen
;
1022 if (len
> sizeof(modeprops
))
1023 len
= sizeof(modeprops
);
1024 CopyMem(&modeprops
, msg
->props
, len
);
1029 static const struct OOP_MethodDescr INTELG45_Root_descr
[] =
1031 {(OOP_MethodFunc
)INTELG45__Root__New
, moRoot_New
},
1032 {(OOP_MethodFunc
)INTELG45__Root__Get
, moRoot_Get
},
1033 {(OOP_MethodFunc
)INTELG45__Root__Set
, moRoot_Set
},
1036 #define NUM_INTELG45_Root_METHODS 3
1038 static const struct OOP_MethodDescr INTELG45_Hidd_Gfx_descr
[] =
1040 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__CopyBox
, moHidd_Gfx_CopyBox
},
1041 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__CreateObject
, moHidd_Gfx_CreateObject
},
1042 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__SetCursorVisible
, moHidd_Gfx_SetCursorVisible
},
1043 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__SetCursorPos
, moHidd_Gfx_SetCursorPos
},
1044 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__SetCursorShape
, moHidd_Gfx_SetCursorShape
},
1045 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__ShowViewPorts
, moHidd_Gfx_ShowViewPorts
},
1046 {(OOP_MethodFunc
)INTELG45__Hidd_Gfx__ModeProperties
, moHidd_Gfx_ModeProperties
},
1049 #define NUM_INTELG45_Hidd_Gfx_METHODS 7
1051 const struct OOP_InterfaceDescr INTELG45_ifdescr
[] =
1053 {INTELG45_Root_descr
, IID_Root
, NUM_INTELG45_Root_METHODS
},
1054 {INTELG45_Hidd_Gfx_descr
, IID_Hidd_Gfx
, NUM_INTELG45_Hidd_Gfx_METHODS
},