From 6d93d6d5c4863eefb5a02dcf95f3c92ac478c5ae Mon Sep 17 00:00:00 2001 From: Christopher Harvey Date: Wed, 8 May 2013 19:10:38 +0000 Subject: [PATCH] --- yaml --- r: 375487 b: refs/heads/master c: 9f1d036648c1c5ed81b0e98d7a06d55df972701e h: refs/heads/master i: 375485: bb9151eec6e41924a5963b494876365d78494783 375483: e7a179384a876a443b3408149146f6dd79301481 375479: 09ea7e1c7a7ee23a2e22c02e5a624c81913898b7 375471: 3668a483f76754d3a138ef47507314a41c6a36dd 375455: 8eb0b39ca4ceae5517d783e6b39523e12fbd6d98 375423: e1cb8752a5e075c20d027daa4c351ebee6c07dbc v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/mgag200/mgag200_mode.c | 27 +++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 5183b02f5034..268b9c1c7f1e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3cdc0e8d6142aaf3eb84a53eab6de1160da290a3 +refs/heads/master: 9f1d036648c1c5ed81b0e98d7a06d55df972701e diff --git a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c index 0326989a6aec..e8e20c653b1d 100644 --- a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -654,12 +654,26 @@ static void mga_g200wb_commit(struct drm_crtc *crtc) WREG_DAC(MGA1064_GEN_IO_DATA, tmp); } - +/* + This is how the framebuffer base address is stored in g200 cards: + * Assume @offset is the gpu_addr variable of the framebuffer object + * Then addr is the number of _pixels_ (not bytes) from the start of + VRAM to the first pixel we want to display. (divided by 2 for 32bit + framebuffers) + * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers + addr<20> -> CRTCEXT0<6> + addr<19-16> -> CRTCEXT0<3-0> + addr<15-8> -> CRTCC<7-0> + addr<7-0> -> CRTCD<7-0> + CRTCEXT0 has to be programmed last to trigger an update and make the + new addr variable take effect. + */ void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) { struct mga_device *mdev = crtc->dev->dev_private; u32 addr; int count; + u8 crtcext0; while (RREG8(0x1fda) & 0x08); while (!(RREG8(0x1fda) & 0x08)); @@ -667,10 +681,17 @@ void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) count = RREG8(MGAREG_VCOUNT) + 2; while (RREG8(MGAREG_VCOUNT) < count); - addr = offset >> 2; + WREG8(MGAREG_CRTCEXT_INDEX, 0); + crtcext0 = RREG8(MGAREG_CRTCEXT_DATA); + crtcext0 &= 0xB0; + addr = offset / 8; + /* Can't store addresses any higher than that... + but we also don't have more than 16MB of memory, so it should be fine. */ + WARN_ON(addr > 0x1fffff); + crtcext0 |= (!!(addr & (1<<20)))<<6; WREG_CRT(0x0d, (u8)(addr & 0xff)); WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff); - WREG_CRT(0xaf, (u8)(addr >> 16) & 0xf); + WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0); }