- Allocate 64MB of graphics memory by default instead of maximum possible
[AROS.git] / workbench / hidds / hidd.intelG45 / intelG45_lowlevel.c
blobf0b43aa6e21ed7e68b4d4cc7e788293a26366641
1 /*
2 * intelG45_lowlevel.c
4 * Created on: May 2, 2010
5 * $Id$
6 */
8 #define DEBUG 0
9 #include <aros/debug.h>
10 #include <aros/libcall.h>
11 #include <aros/asmcall.h>
12 #include <aros/symbolsets.h>
14 #include <utility/tagitem.h>
16 #include <hidd/graphics.h>
17 #include <hidd/i2c.h>
19 #include <proto/oop.h>
20 #include <proto/exec.h>
21 #include <proto/utility.h>
23 #include <stdint.h>
24 #include <stdlib.h>
27 #include LC_LIBDEFS_FILE
29 #include "intelG45_intern.h"
30 #include "intelG45_regs.h"
32 typedef struct {
33 uint8_t N;
34 uint8_t M1;
35 uint8_t M2;
36 uint8_t P1;
37 uint8_t P2;
38 uint32_t VCO;
39 uint32_t PixelClock;
40 } GMA_PLL_t;
42 VOID delay_ms(struct g45staticdata *sd, uint32_t msec)
44 /* Allocate a signal within this task context */
46 sd->tr.tr_node.io_Message.mn_ReplyPort->mp_SigBit = SIGB_SINGLE;
47 sd->tr.tr_node.io_Message.mn_ReplyPort->mp_SigTask = FindTask(NULL);
49 /* Specify the request */
50 sd->tr.tr_node.io_Command = TR_ADDREQUEST;
51 sd->tr.tr_time.tv_secs = msec / 1000;
52 sd->tr.tr_time.tv_micro = 1000 * (msec % 1000);
54 /* Wait */
55 DoIO((struct IORequest *)&sd->tr);
57 sd->tr.tr_node.io_Message.mn_ReplyPort->mp_SigTask = NULL;
60 VOID delay_us(struct g45staticdata *sd, uint32_t usec)
62 /* Allocate a signal within this task context */
64 sd->tr.tr_node.io_Message.mn_ReplyPort->mp_SigBit = SIGB_SINGLE;
65 sd->tr.tr_node.io_Message.mn_ReplyPort->mp_SigTask = FindTask(NULL);
67 /* Specify the request */
68 sd->tr.tr_node.io_Command = TR_ADDREQUEST;
69 sd->tr.tr_time.tv_secs = usec / 1000000;
70 sd->tr.tr_time.tv_micro = (usec % 1000000);
72 /* Wait */
73 DoIO((struct IORequest *)&sd->tr);
75 sd->tr.tr_node.io_Message.mn_ReplyPort->mp_SigTask = NULL;
78 static BOOL calc_pll_and_validate(GMA_PLL_t *pll)
80 uint32_t m, p;
82 /* requirement: M1 > M2 */
83 if (pll->M1 <= pll->M2)
84 return FALSE;
86 /* M1 range: 10 .. 20 */
87 if (pll->M1 < 10 || pll->M1 > 20)
88 return FALSE;
90 /* M2 range: 5 .. 9 */
91 if (pll->M2 < 5 || pll->M2 > 9)
92 return FALSE;
94 m = 5 * ((uint32_t)pll->M1 + 2) + (pll->M2 + 2);
96 /* m range: 70 .. 120 */
97 if (m < 70 || m > 120)
98 return FALSE;
100 /* N range: 3 .. 8 */
101 if (pll->N < 3 || pll->N > 8)
102 return FALSE;
104 pll->VCO = (96000 * m) / (pll->N + 2);
106 if (pll->VCO < 1400000 || pll->VCO > 2800000)
107 return FALSE;
109 if (pll->P1 < 1 || pll->P1 > 8)
110 return FALSE;
112 p = (uint32_t)pll->P1 * (uint32_t)pll->P2;
114 /* p range: 5 .. 80 for sDVO/DAC mode */
115 if (p < 5 || p > 80)
116 return FALSE;
118 pll->PixelClock = pll->VCO / p;
120 if (pll->PixelClock < 20000 || pll->PixelClock > 400000)
121 return FALSE;
123 return TRUE;
126 void EnablePipe(struct g45staticdata *sd,LONG pipe){
127 char *pipeconf_reg = sd->Card.MMIO + ((pipe == PIPE_A) ? G45_PIPEACONF : G45_PIPEBCONF);
128 writel( readl( pipeconf_reg ) | G45_PIPECONF_ENABLE ,pipeconf_reg );
131 void DisablePipe(struct g45staticdata *sd,LONG pipe){
132 char *pipeconf_reg = sd->Card.MMIO + ((pipe == PIPE_A) ? G45_PIPEACONF : G45_PIPEBCONF);
134 writel(readl( pipeconf_reg ) & ~G45_PIPECONF_ENABLE, pipeconf_reg );
135 readl( pipeconf_reg );
136 delay_ms(sd, 20);
139 void EnablePlane(struct g45staticdata *sd,LONG plane){
140 char *dspbase_reg = sd->Card.MMIO + ((plane == PIPE_A) ? G45_DSPABASE : G45_DSPBBASE);
141 char *dspcntr_reg = sd->Card.MMIO + ((plane == PIPE_A) ? G45_DSPACNTR : G45_DSPBCNTR);
143 writel( readl( dspcntr_reg ) | G45_DSPCNTR_PLANE_ENABLE ,dspcntr_reg);
144 writel( readl( dspbase_reg ) ,dspbase_reg);
145 delay_ms(sd, 20);
148 void DisablePlane(struct g45staticdata *sd,LONG plane){
149 char *dspbase_reg = sd->Card.MMIO + ((plane == PIPE_A) ? G45_DSPABASE : G45_DSPBBASE);
150 char *dspcntr_reg = sd->Card.MMIO + ((plane == PIPE_A) ? G45_DSPACNTR : G45_DSPBCNTR);
152 writel( readl( dspcntr_reg ) & ~G45_DSPCNTR_PLANE_ENABLE ,dspcntr_reg);
153 writel( readl( dspbase_reg ) ,dspbase_reg);
154 readl( dspbase_reg );
155 delay_ms(sd, 20);
158 void UpdateCursor(struct g45staticdata *sd)
160 writel(sd->CursorBase, sd->Card.MMIO + (sd->pipe == PIPE_A ? G45_CURABASE : G45_CURBBASE));
163 void SetCursorPosition(struct g45staticdata *sd,LONG x,LONG y)
165 LONG width = (sd->VisibleBitmap->state->htotal & 0x0000ffff);
166 LONG height = (sd->VisibleBitmap->state->vtotal & 0x0000ffff);
168 if(x<0)x=0;
169 if(y<0)y=0;
170 if(x>width)x = width; // Grue eats you,if pointer is outside of the screen.
171 if(y>height)y = height;
173 writel(((ULONG)x << G45_CURPOS_XSHIFT) | ((ULONG)y << G45_CURPOS_YSHIFT),
174 sd->Card.MMIO + (sd->pipe == PIPE_A ?G45_CURAPOS:G45_CURBPOS));
175 UpdateCursor(sd);
178 void G45_InitMode(struct g45staticdata *sd, GMAState_t *state,
179 uint16_t width, uint16_t height, uint8_t depth, uint32_t pixelclock, intptr_t framebuffer,
180 uint16_t hdisp, uint16_t vdisp, uint16_t hstart, uint16_t hend, uint16_t htotal,
181 uint16_t vstart, uint16_t vend, uint16_t vtotal, uint32_t flags)
183 bug("[GMA] InitMode %dx%dx%d @ %dHz\n", hdisp, vdisp, depth, ((pixelclock / (uint32_t)htotal) * 1000) / ((uint32_t)vtotal));
184 GMA_PLL_t clock, t;
185 uint32_t err = pixelclock;
187 clock.PixelClock = 0;
190 * Brute force determination of PLL settings. Iterate through all available configurations and select the most
191 * suitable one. I know, nested loops, but there is really no better way to do it
193 if (pixelclock <= 270000)
194 t.P2 = 10;
195 else
196 t.P2 = 5;
198 for (t.M1 = 10; t.M1 <= 20; t.M1++)
200 for (t.M2 = 5; t.M2 <= 9; t.M2++)
202 for (t.N = 3; t.N <= 8; t.N++)
204 for (t.P1=1; t.P1 <= 8; t.P1++)
206 if (calc_pll_and_validate(&t) == TRUE)
208 int this_err = abs(pixelclock - t.PixelClock);
209 if (this_err < err)
211 clock = t;
212 err = this_err;
220 if (clock.PixelClock)
222 D(bug("[GMA] PixelClock: Found: %d kHz, Requested: %d kHz\n", clock.PixelClock, pixelclock));
223 D(bug("[GMA] VCO: %d MHz\n", clock.VCO / 1000));
224 state->fp = clock.N << 16 | clock.M1 << 8 | clock.M2;
226 if (clock.VCO >= 1900000 && clock.VCO < 2400000)
227 state->fp |= 1 << 24;
228 else if (clock.VCO >= 2500000 && clock.VCO < 3000000)
229 state->fp |= 2 << 24;
230 else if (clock.VCO > 3100000)
231 state->fp |= 3 << 24;
233 state->dpll = (10 << G45_DPLL_PHASE_SHIFT) | G45_DPLL_VGA_MODE_DISABLE | G45_DPLL_MODE_DAC_SERIAL;
234 if (clock.P2 >= 10)
235 state->dpll |= G45_DPLL_DAC_SERIAL_P2_DIV_10;
236 else
237 state->dpll |= G45_DPLL_DAC_SERIAL_P2_DIV_5;
238 state->dpll |= (1 << (clock.P1 - 1)) << G45_DPLL_P1_SHIFT;
240 state->dspcntr = readl(sd->Card.MMIO + G45_DSPACNTR ) & 0x000f0000;
242 if (depth <= 8)
244 state->dspcntr |= G45_DSPCNTR_8BPP;
245 state->dspstride = width;
247 else if (depth == 15)
249 state->dspcntr |= G45_DSPCNTR_15BPP;
250 state->dspstride = width * 2;
252 else if (depth == 16)
254 state->dspcntr |= G45_DSPCNTR_16BPP;
255 state->dspstride = width * 2;
257 else
259 state->dspcntr |= G45_DSPCNTR_32BPP;
260 state->dspstride = width * 4;
263 state->pipeconf = G45_PIPECONF_ENABLE;
264 state->dpll |= G45_DPLL_VCO_ENABLE;
265 state->dspcntr |= G45_DSPCNTR_PLANE_ENABLE;
267 state->htotal = (hdisp - 1) | ((htotal - 1) << 16);
268 state->hblank = (hdisp - 1) | ((htotal - 1) << 16);
269 state->hsync = (hstart - 1) | ((hend - 1) << 16);
271 state->vtotal = (vdisp - 1) | ((vtotal - 1) << 16);
272 state->vblank = (vdisp - 1) | ((vtotal - 1) << 16);
273 state->vsync = (vstart - 1) | ((vend - 1) << 16);
275 state->pipesrc = (vdisp - 1) | ((hdisp - 1) << 16);
276 state->dspsurf = 0;
277 state->dsplinoff = framebuffer;
278 state->dspstride = (state->dspstride + 63) & ~63;
280 state->adpa = 0;
282 if (flags & vHidd_Sync_HSyncPlus)
283 state->adpa |= G45_ADPA_HSYNC_PLUS;
284 if (flags & vHidd_Sync_VSyncPlus)
285 state->adpa |= G45_ADPA_VSYNC_PLUS;
287 D(bug("[GMA] dpll=%08x\n", state->dpll));
291 void G45_LoadState(struct g45staticdata *sd, GMAState_t *state)
293 int i;
294 uint32_t tmp;
295 BOOL panelfitter;
297 bug("[GMA] LoadState %dx%dx%d\n",
298 (state->htotal & 0x0000ffff) + 1,
299 (state->vtotal & 0x0000ffff) + 1,
300 (state->dspcntr & G45_DSPCNTR_PIXEL_MASK)==G45_DSPCNTR_8BPP ? 8:
301 (state->dspcntr & G45_DSPCNTR_PIXEL_MASK)==G45_DSPCNTR_15BPP ? 15:
302 (state->dspcntr & G45_DSPCNTR_PIXEL_MASK)==G45_DSPCNTR_16BPP ? 16:
303 (state->dspcntr & G45_DSPCNTR_PIXEL_MASK)==G45_DSPCNTR_32BPP ? 32:666
306 LOCK_HW
307 DO_FLUSH();
309 if( sd->pipe == PIPE_B )
311 /* G45: Volume 3: Display Register
312 • DPLL must be enabled and warmed up before pipe or ports are enabled.
313 • DPLL must be kept enabled until ports are disabled and pipe is completely off.
314 • DPLL frequency must not be changed until ports are disabled and pipe is completely off, except
315 when in native VGA where SR01 25/28 MHz select can be changed.
316 • Planes must be disabled before pipe is disabled or pipe timings changed.
317 • Panelfitter must be enabled or disabled only when pipe is completely off.
318 • On Gen3 set port multiply when enabling a SDVO port.
319 • On Gen3.5 and GenX set port multiply when programming the DPLL.
320 • The internal TV and CRT ports can be left on during a mode switch if DPLL is not touched.
321 • Ports can be freely enabled or disabled on a running pipe, except when port multiply needs to
322 be changed.
325 // DPLL or FP is not touched here ,register value is same in BIOS vesa modes 640x420 and 1024x600
327 // disable vga
328 writel(readl(sd->Card.MMIO + G45_VGACNTRL) | G45_VGACNTRL_VGA_DISABLE, sd->Card.MMIO + G45_VGACNTRL);
330 ULONG hdisp = (state->htotal & 0x0000ffff) + 1;
331 ULONG vdisp = (state->vtotal & 0x0000ffff) + 1;
333 if( hdisp == sd->lvds_fixed.hdisp && vdisp == sd->lvds_fixed.vdisp)
334 panelfitter = FALSE;
335 else
336 panelfitter = TRUE;
338 bug("[GMA] panelfitter %s\n",panelfitter ? "ON":"OFF");
340 DisablePlane(sd,PIPE_B);
341 DisablePipe(sd,PIPE_B);
343 bug("G45_PFIT_CONTROL=%x\n",readl(sd->Card.MMIO + G45_PFIT_CONTROL));
344 bug("G45_PFIT_PGM_RATIOS=%x\n",readl(sd->Card.MMIO + G45_PFIT_PGM_RATIOS));
346 writel(((hdisp - 1) << 16) | (vdisp - 1), sd->Card.MMIO + G45_PIPEBSRC);
347 writel(((vdisp - 1) << 16) | (hdisp - 1), sd->Card.MMIO + G45_DSPBSIZE);
349 // pixel format , use pipe B
350 tmp = readl( sd->Card.MMIO + G45_DSPBCNTR );
351 tmp = ( tmp & ~G45_DSPCNTR_PIXEL_MASK ) | ( state->dspcntr & G45_DSPCNTR_PIXEL_MASK );
352 tmp |= G45_DSPCNTR_SEL_PIPE_B;
353 writel( tmp , sd->Card.MMIO + G45_DSPBCNTR );
354 delay_ms(sd, 20);
356 // bitmap width in bytes
357 writel( state->dspstride , sd->Card.MMIO + G45_DSPBSTRIDE );
359 // framebuffer address
360 writel( state->dsplinoff , sd->Card.MMIO + G45_DSPBLINOFF );
361 readl( sd->Card.MMIO + G45_DSPBLINOFF );
363 delay_ms(sd, 20);
365 // without this pointer color is corrupted
366 ULONG i;
367 for (i = 0; i < 256; i++) {
368 writel( (i << 16) |(i << 8) | i , sd->Card.MMIO + 0x0a800 + 4 * i);//PALETTE_B
371 // enable/disable panelfitter
372 if( panelfitter ){
373 writel( 0 , sd->Card.MMIO + G45_PFIT_PGM_RATIOS );
374 writel( readl(sd->Card.MMIO + G45_PFIT_CONTROL) | G45_PFIT_ENABLE , sd->Card.MMIO + G45_PFIT_CONTROL );
376 else
378 writel( 0 , sd->Card.MMIO + G45_PFIT_PGM_RATIOS );
379 writel( readl(sd->Card.MMIO + G45_PFIT_CONTROL) & ~G45_PFIT_ENABLE , sd->Card.MMIO + G45_PFIT_CONTROL );
381 writel(state->dspsurf, sd->Card.MMIO + G45_DSPBSURF);
382 delay_ms(sd, 1);
384 EnablePipe(sd,PIPE_B);
385 EnablePlane(sd,PIPE_B);
388 else
391 uint32_t tmp;
393 writel(readl(sd->Card.MMIO + 0x61140) & ~(1 << 29), sd->Card.MMIO + 0x61140);
394 writel(readl(sd->Card.MMIO + 0x61160) & ~(1 << 29), sd->Card.MMIO + 0x61160);
396 writel(readl(sd->Card.MMIO + 0x61140) & ~(1 << 31), sd->Card.MMIO + 0x61140);
397 writel(readl(sd->Card.MMIO + 0x61160) & ~(1 << 31), sd->Card.MMIO + 0x61160);
399 // /* Stop cursor */
400 // writel(0, sd->Card.MMIO + 0x70080);
401 // delay_ms(sd, 20);
403 /* Disable pipe */
404 writel(readl(sd->Card.MMIO + G45_PIPEACONF) & ~G45_PIPECONF_ENABLE, sd->Card.MMIO + G45_PIPEACONF);
406 for (i=0; i < 100; i++)
408 if ((readl(sd->Card.MMIO + G45_PIPEACONF) & G45_PIPECONF_ENABLED) == 0)
409 break;
411 /* Disable pipe again and again*/
412 writel(readl(sd->Card.MMIO + G45_PIPEACONF) & ~G45_PIPECONF_ENABLE, sd->Card.MMIO + G45_PIPEACONF);
413 delay_ms(sd, 10);
416 /* Disable DAC */
417 writel(readl(sd->Card.MMIO + G45_ADPA) & ~G45_ADPA_ENABLE, sd->Card.MMIO + G45_ADPA);
419 /* Disable planes */
420 writel(readl(sd->Card.MMIO + G45_DSPACNTR) & ~G45_DSPCNTR_PLANE_ENABLE, sd->Card.MMIO + G45_DSPACNTR);
421 writel(readl(sd->Card.MMIO + G45_DSPBCNTR) & ~G45_DSPCNTR_PLANE_ENABLE, sd->Card.MMIO + G45_DSPBCNTR);
423 /* "VBLANK" delay */
424 delay_ms(sd, 20);
426 /* Stop sync */
427 writel((readl(sd->Card.MMIO + G45_ADPA) & G45_ADPA_MASK) | G45_ADPA_DPMS_OFF, sd->Card.MMIO + G45_ADPA);
429 /* Disable VGA */
430 writel(readl(sd->Card.MMIO + G45_VGACNTRL) | G45_VGACNTRL_VGA_DISABLE, sd->Card.MMIO + G45_VGACNTRL);
432 /* Clear PIPE status */
433 D(bug("[GMA] Old PIPEA Status = %08x\n", readl(sd->Card.MMIO + 0x70024)));
434 writel(0xffff, sd->Card.MMIO + 0x70024);
436 /* Use all 96 fifo entries for PIPE A */
437 writel(95 | (95 << 7), sd->Card.MMIO + 0x70030);
439 /* unprotect some fields */
440 writel(0xabcd0000, sd->Card.MMIO + 0x61204);
442 // tmp = readl(sd->Card.MMIO + G45_DPLLA_CTRL);
443 // D(bug("[GMA] dpll before=%08x\n", tmp));
444 // tmp &= ~G45_DPLL_VCO_ENABLE;
445 // D(bug("[GMA] writing dpll=%08x\n", tmp));
446 // writel(tmp, sd->Card.MMIO + G45_DPLLA_CTRL);
447 // D(bug("[GMA] dpll after=%08x\n", readl(sd->Card.MMIO + G45_DPLLA_CTRL)));
449 delay_us(sd, 150);
451 // writel(state->dspsurf, sd->Card.MMIO + G45_DSPASURF);
453 tmp = readl(sd->Card.MMIO + G45_PIPEACONF);
454 writel(tmp & ~(3 << 18), sd->Card.MMIO + G45_PIPEACONF);
455 writel(readl(sd->Card.MMIO + G45_DSPACNTR) | 0x80000000, sd->Card.MMIO + G45_DSPACNTR);
456 writel(0, sd->Card.MMIO + G45_DSPASURF);
457 writel(readl(sd->Card.MMIO + G45_DSPACNTR) & 0x7fffffff, sd->Card.MMIO + G45_DSPACNTR);
458 writel(0, sd->Card.MMIO + G45_DSPASURF);
459 writel(tmp, sd->Card.MMIO + G45_PIPEACONF);
461 if (state->dpll & G45_DPLL_VCO_ENABLE)
463 writel(state->fp, sd->Card.MMIO + G45_FPA0);
464 writel(state->fp, sd->Card.MMIO + G45_FPA1);
465 writel(state->dpll & ~G45_DPLL_VCO_ENABLE, sd->Card.MMIO + G45_DPLLA_CTRL);
466 (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
467 delay_ms(sd, 1);
468 writel(state->dpll & ~G45_DPLL_VCO_ENABLE, sd->Card.MMIO + G45_DPLLA_CTRL);
469 (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
470 delay_ms(sd, 1);
471 // writel(state->dpll & ~G45_DPLL_VCO_ENABLE, sd->Card.MMIO + G45_DPLLA_CTRL);
472 // (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
473 // delay_ms(sd, 1);
474 // writel(state->dpll & ~G45_DPLL_VCO_ENABLE, sd->Card.MMIO + G45_DPLLA_CTRL);
475 // (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
476 // delay_ms(sd, 1);
477 // writel(state->dpll & ~G45_DPLL_VCO_ENABLE, sd->Card.MMIO + G45_DPLLA_CTRL);
478 // (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
479 // delay_ms(sd, 1);
480 // writel(state->dpll & ~G45_DPLL_VCO_ENABLE, sd->Card.MMIO + G45_DPLLA_CTRL);
481 // (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
482 // delay_ms(sd, 1);
485 writel(state->fp, sd->Card.MMIO + G45_FPA0);
486 writel(state->fp, sd->Card.MMIO + G45_FPA1);
487 writel(state->dpll, sd->Card.MMIO + G45_DPLLA_CTRL);
488 (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
489 delay_us(sd, 150);
490 writel(state->dpll, sd->Card.MMIO + G45_DPLLA_CTRL);
491 D(bug("[GMA] writing dpll=%08x, got %08x\n", state->dpll, readl(sd->Card.MMIO + G45_DPLLA_CTRL)));
492 delay_us(sd, 150);
494 /* protect on again */
495 writel(0x00000000, sd->Card.MMIO + 0x61204);
497 /* Enable DAC*/
498 writel((readl(sd->Card.MMIO + G45_ADPA) & G45_ADPA_MASK) | G45_ADPA_DPMS_OFF | G45_ADPA_ENABLE, sd->Card.MMIO + G45_ADPA);
500 writel(state->htotal, sd->Card.MMIO + G45_HTOTAL_A);
501 writel(state->hblank, sd->Card.MMIO + G45_HBLANK_A);
502 writel(state->hsync, sd->Card.MMIO + G45_HSYNC_A);
503 writel(state->vtotal, sd->Card.MMIO + G45_VTOTAL_A);
504 writel(state->vblank, sd->Card.MMIO + G45_VBLANK_A);
505 writel(state->vsync, sd->Card.MMIO + G45_VSYNC_A);
507 writel(state->pipesrc, sd->Card.MMIO + G45_PIPEASRC);
508 writel(state->pipesrc, sd->Card.MMIO + 0x70190);
509 writel(state->pipeconf, sd->Card.MMIO + G45_PIPEACONF);
510 (void)readl(sd->Card.MMIO + G45_PIPEACONF);
512 writel(state->dspsurf, sd->Card.MMIO + G45_DSPASURF);
513 writel(state->dspstride, sd->Card.MMIO + G45_DSPASTRIDE);
514 writel(state->dsplinoff , sd->Card.MMIO + G45_DSPALINOFF);
516 /* Enable DAC */
517 writel((readl(sd->Card.MMIO + G45_ADPA) & ~G45_ADPA_DPMS_MASK) | G45_ADPA_DPMS_ON, sd->Card.MMIO + G45_ADPA);
519 /* Adjust Sync pulse polarity */
520 writel((readl(sd->Card.MMIO + G45_ADPA) & ~(G45_ADPA_VSYNC_PLUS | G45_ADPA_HSYNC_PLUS)) | state->adpa, sd->Card.MMIO + G45_ADPA);
522 D(bug("[GMA] Loaded state. dpll=%08x %08x %08x %08x %08x %08x %08x\n", state->dpll,
523 readl(sd->Card.MMIO + G45_HTOTAL_A),
524 readl(sd->Card.MMIO + G45_HBLANK_A),
525 readl(sd->Card.MMIO + G45_HSYNC_A),
526 readl(sd->Card.MMIO + G45_VTOTAL_A),
527 readl(sd->Card.MMIO + G45_VBLANK_A),
528 readl(sd->Card.MMIO + G45_VSYNC_A)));
530 if (state->dpll != readl(sd->Card.MMIO + G45_DPLLA_CTRL))
532 D(bug("[GMA] DPLL mismatch!\n"));
533 writel(state->dpll, sd->Card.MMIO + G45_DPLLA_CTRL);
534 (void)readl(sd->Card.MMIO + G45_DPLLA_CTRL);
537 delay_ms(sd, 20);
539 writel(state->dspcntr, sd->Card.MMIO + G45_DSPACNTR);
542 UNLOCK_HW
545 void G45_SaveState(struct g45staticdata *sd, GMAState_t *state)
550 IPTR AllocBitmapArea(struct g45staticdata *sd, ULONG width, ULONG height,
551 ULONG bpp, BOOL must_have)
553 IPTR result;
555 LOCK_HW
557 Forbid();
558 result = (IPTR)Allocate(&sd->CardMem, 1024+((width * bpp + 63) & ~63) * height);
559 Permit();
561 if (result)
562 result +=512;
564 D(bug("[GMA] AllocBitmapArea(%dx%d@%d) = %p\n",
565 width, height, bpp, result));
566 D(bug("[GMA] Available graphics memory is now %ldMB\n", sd->CardMem.mh_Free >> 20));
568 If Allocate failed, make the 0xffffffff as return. If it succeeded, make
569 the memory pointer relative to the begin of GFX memory
571 if (result == 0) result--;
572 else result -= (IPTR)sd->Card.Framebuffer;
574 UNLOCK_HW
576 /* Generic thing. Will be extended later */
577 return result;
580 VOID FreeBitmapArea(struct g45staticdata *sd, IPTR bmp, ULONG width, ULONG height,
581 ULONG bpp)
583 APTR ptr = (APTR)(bmp + sd->Card.Framebuffer-512);
585 LOCK_HW
587 D(bug("[GMA] FreeBitmapArea(%p,%dx%d@%d)\n",
588 ptr, width, height, bpp));
590 Forbid();
591 Deallocate(&sd->CardMem, ptr, 1024+((width * bpp + 63) & ~63) * height);
592 Permit();
593 D(bug("[GMA] Available graphics memory is now %ldMB\n", sd->CardMem.mh_Free >> 20));
595 UNLOCK_HW
598 BOOL adpa_Enabled(struct g45staticdata *sd)
600 return ( readl( sd->Card.MMIO + G45_ADPA ) & G45_ADPA_ENABLE) ? TRUE : FALSE;
603 BOOL lvds_Enabled(struct g45staticdata *sd)
605 return ( readl( sd->Card.MMIO + G45_LVDS ) & G45_LVDS_PORT_EN) ? TRUE : FALSE;
608 void GetSync(struct g45staticdata *sd,struct Sync *sync,ULONG pipe)
610 ULONG htot = readl(sd->Card.MMIO + (pipe == PIPE_A ? G45_HTOTAL_A : G45_HTOTAL_B));
611 ULONG hsync = readl(sd->Card.MMIO + (pipe == PIPE_A ? G45_HSYNC_A : G45_HSYNC_B));
612 ULONG vtot = readl(sd->Card.MMIO + (pipe == PIPE_A ? G45_VTOTAL_A : G45_VTOTAL_B));
613 ULONG vsync = readl(sd->Card.MMIO + (pipe == PIPE_A ? G45_VSYNC_A : G45_VSYNC_B));
615 sync->pixelclock = 48; // dummy value
616 sync->flags =0;
618 sync->hdisp = (htot & 0xffff) + 1;
619 sync->htotal = ((htot & 0xffff0000) >> 16) + 1;
620 sync->hstart = (hsync & 0xffff) + 1;
621 sync->hend = ((hsync & 0xffff0000) >> 16) + 1;
622 sync->vdisp = (vtot & 0xffff) + 1;
623 sync->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
624 sync->vstart = (vsync & 0xffff) + 1;
625 sync->vend = ((vsync & 0xffff0000) >> 16) + 1;
627 sync->width = sync->hdisp;
628 sync->height = sync->vdisp;
630 ULONG dsp_cntr = readl(sd->Card.MMIO + (sd->pipe == 0 ? G45_DSPACNTR : G45_DSPBCNTR));
632 switch (dsp_cntr & G45_DSPCNTR_PIXEL_MASK) {
633 case G45_DSPCNTR_8BPP:
634 sync->depth = 8;
635 break;
636 case G45_DSPCNTR_16BPP:
637 sync->depth = 16;
638 break;
639 case G45_DSPCNTR_32BPP:
640 sync->depth = 32;
641 break;
642 default:
643 bug("[GMA] GetSync: Unknown pixel format.\n");
645 bug("[GMA] GetSync: %d %d %d %d\n",
646 sync->hdisp,
647 sync->hstart,
648 sync->hend,
649 sync->htotal);
651 bug(" %d %d %d %d\n",
652 sync->vdisp,
653 sync->vstart,
654 sync->vend,
655 sync->vtotal);