summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <glisse@freedesktop.org>2007-07-11 01:14:28 +0200
committerJerome Glisse <glisse@freedesktop.org>2007-07-11 01:14:28 +0200
commitbba2303c531e65f653b652c42e08d44ec144d93c (patch)
tree59cb58fac92a0f85ba23b64a92479df3b3c0fee8
parent9b6b0acf7263627a25546c4b6452ff3abb090793 (diff)
avivo: fix framebuffer offset handling.
We were missing one register for framebuffer offset. Moreover avivo engine needs that x offset be a multiple of 4. There is still a bug with virtual framebuffer, i don't pick properly the current screen size.
-rw-r--r--avivotool/avivotool.c9
-rw-r--r--include/avivo.h3
-rw-r--r--include/radeon_reg.h8
-rw-r--r--xorg/avivo.c9
-rw-r--r--xorg/avivo_crtc.c19
-rw-r--r--xorg/avivo_state.c6
6 files changed, 41 insertions, 13 deletions
diff --git a/avivotool/avivotool.c b/avivotool/avivotool.c
index 9b53ea6..5d72dae 100644
--- a/avivotool/avivotool.c
+++ b/avivotool/avivotool.c
@@ -691,7 +691,8 @@ static struct {
REGLIST(AVIVO_CRTC1_PITCH),
REGLIST(AVIVO_CRTC1_X_LENGTH),
REGLIST(AVIVO_CRTC1_Y_LENGTH),
- REGLIST(AVIVO_CRTC1_OFFSET),
+ REGLIST(AVIVO_CRTC1_OFFSET_START),
+ REGLIST(AVIVO_CRTC1_OFFSET_END),
REGLIST(AVIVO_CRTC1_EXPANSION_CNTL),
REGLIST(AVIVO_CRTC1_EXPANSION_SOURCE),
REGLIST(AVIVO_CRTC2_H_TOTAL),
@@ -1004,7 +1005,11 @@ void radeon_cmd_regs(const char *type)
16, 31, "DECIMALHeight",
0, 15, "DECIMALWidth",
0, 0, NULL);
- SHOW_REG_BITS(AVIVO_CRTC1_OFFSET,
+ SHOW_REG_BITS(AVIVO_CRTC1_OFFSET_START,
+ 16, 31, "DECIMALx",
+ 0, 15, "DECIMALy",
+ 0, 0, NULL);
+ SHOW_REG_BITS(AVIVO_CRTC1_OFFSET_END,
16, 31, "DECIMALx",
0, 15, "DECIMALy",
0, 0, NULL);
diff --git a/include/avivo.h b/include/avivo.h
index 9686dde..dff5de5 100644
--- a/include/avivo.h
+++ b/include/avivo.h
@@ -117,7 +117,8 @@ struct avivo_state
int crtc1_x_length;
int crtc1_y_length;
int crtc1_fb_height;
- int crtc1_offset;
+ int crtc1_offset_start;
+ int crtc1_offset_end;
int crtc1_expn_size;
int crtc1_expn_cntl;
int crtc1_6594;
diff --git a/include/radeon_reg.h b/include/radeon_reg.h
index 3b4ee8c..1e8247d 100644
--- a/include/radeon_reg.h
+++ b/include/radeon_reg.h
@@ -3263,8 +3263,10 @@
#define AVIVO_CRTC1_X_LENGTH 0x6134
#define AVIVO_CRTC1_Y_LENGTH 0x6138
+#define AVIVO_CRTC1_OFFSET_END 0x6454
+
#define AVIVO_CRTC1_FB_HEIGHT 0x652c
-#define AVIVO_CRTC1_OFFSET 0x6580
+#define AVIVO_CRTC1_OFFSET_START 0x6580
#define AVIVO_CRTC1_EXPANSION_SOURCE 0x6584
#define AVIVO_CRTC1_EXPANSION_CNTL 0x6590
# define AVIVO_CRTC_EXPANSION_EN (1 << 0)
@@ -3308,8 +3310,10 @@
#define AVIVO_CRTC2_X_LENGTH 0x6934
#define AVIVO_CRTC2_Y_LENGTH 0x6938
+#define AVIVO_CRTC2_OFFSET_END 0x6c54
+
#define AVIVO_CRTC2_FB_HEIGHT 0x6d2c
-#define AVIVO_CRTC2_OFFSET 0x6d80
+#define AVIVO_CRTC2_OFFSET_START 0x6d80
#define AVIVO_CRTC2_EXPANSION_SOURCE 0x6d84
#define AVIVO_CRTC2_EXPANSION_CNTL 0x6d90
#define AVIVO_CRTC2_6594 0x6d94
diff --git a/xorg/avivo.c b/xorg/avivo.c
index a268352..308fc50 100644
--- a/xorg/avivo.c
+++ b/xorg/avivo.c
@@ -670,8 +670,15 @@ avivo_adjust_frame(int index, int x, int y, int flags)
xf86CrtcPtr crtc = output->crtc;
struct avivo_crtc_private *avivo_crtc = crtc->driver_private;
+ xf86DrvMsg(screen_info->scrnIndex, X_INFO,
+ "adjust frame: %d %d %d %d\n", index, x, y, flags);
if (crtc && crtc->enabled) {
- OUTREG(AVIVO_CRTC1_OFFSET + avivo_crtc->crtc_offset, (x << 16) | y);
+ x = x & ~3;
+ OUTREG(AVIVO_CRTC1_OFFSET_START + avivo_crtc->crtc_offset,
+ (x << 16) | y);
+ OUTREG(AVIVO_CRTC1_OFFSET_END + avivo_crtc->crtc_offset,
+ ((crtc->mode.HDisplay + x - 128) << 16) |
+ (crtc->mode.HDisplay + y -128));
crtc->x = output->initial_x + x;
crtc->y = output->initial_y + y;
}
diff --git a/xorg/avivo_crtc.c b/xorg/avivo_crtc.c
index 834dcd1..1804b3d 100644
--- a/xorg/avivo_crtc.c
+++ b/xorg/avivo_crtc.c
@@ -33,10 +33,10 @@
#include "radeon_reg.h"
static Bool
-avivo_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
+avivo_xf86crtc_resize(ScrnInfoPtr screen_info, int width, int height)
{
- scrn->virtualX = width;
- scrn->virtualY = height;
+ screen_info->virtualX = width;
+ screen_info->virtualY = height;
return TRUE;
}
@@ -195,6 +195,7 @@ avivo_crtc_mode_set(xf86CrtcPtr crtc,
DisplayModePtr adjusted_mode,
int x, int y)
{
+ ScrnInfoPtr screen_info = crtc->scrn;
struct avivo_crtc_private *avivo_crtc = crtc->driver_private;
struct avivo_info *avivo = avivo_get_info(crtc->scrn);
unsigned long fb_location = avivo_crtc->fb_offset + avivo->fb_addr;
@@ -219,7 +220,7 @@ avivo_crtc_mode_set(xf86CrtcPtr crtc,
- adjusted_mode->CrtcVSyncStart) << 16;
avivo_crtc->v_sync_pol = (adjusted_mode->Flags & V_NVSYNC) ? 1 : 0;
avivo_crtc->fb_width = adjusted_mode->CrtcHDisplay;
- avivo_crtc->fb_height = adjusted_mode->CrtcVDisplay;
+ avivo_crtc->fb_height = screen_info->virtualY;
avivo_crtc->fb_pitch = adjusted_mode->CrtcHDisplay;
avivo_crtc->fb_offset = 0;
avivo_crtc->fb_length = avivo_crtc->fb_pitch * avivo_crtc->fb_height * 4;
@@ -261,6 +262,14 @@ avivo_crtc_mode_set(xf86CrtcPtr crtc,
fb_location + avivo_crtc->fb_length);
OUTREG(AVIVO_CRTC1_MODE + avivo_crtc->crtc_offset, 0);
OUTREG(AVIVO_CRTC1_60c0_MYSTERY + avivo_crtc->crtc_offset, 0);
+ /* avivo can only shift offset by 4 pixel in x if you program somethings
+ * not multiple of 4 you gonna drive the GPU crazy and likely won't
+ * be able to restore it without cold reboot (vbe post not enough)
+ */
+ x = x & ~3;
+ OUTREG(AVIVO_CRTC1_OFFSET_END + avivo_crtc->crtc_offset,
+ ((mode->HDisplay + x -128) << 16) | (mode->VDisplay + y - 128));
+ OUTREG(AVIVO_CRTC1_OFFSET_START + avivo_crtc->crtc_offset, (x << 16) | y);
/* set PLL TODO: there is likely PLL registers we miss for having
* different PLL for each CRTC for instance.
@@ -275,13 +284,13 @@ avivo_crtc_mode_set(xf86CrtcPtr crtc,
(mode->HDisplay << 16) | mode->VDisplay);
OUTREG(AVIVO_CRTC1_EXPANSION_CNTL + avivo_crtc->crtc_offset,
AVIVO_CRTC_EXPANSION_EN);
+ OUTREG(AVIVO_CRTC1_6594 + avivo_crtc->crtc_offset, AVIVO_CRTC1_6594_VALUE);
OUTREG(AVIVO_CRTC1_659C + avivo_crtc->crtc_offset, AVIVO_CRTC1_659C_VALUE);
OUTREG(AVIVO_CRTC1_65A8 + avivo_crtc->crtc_offset, AVIVO_CRTC1_65A8_VALUE);
OUTREG(AVIVO_CRTC1_65AC + avivo_crtc->crtc_offset, AVIVO_CRTC1_65AC_VALUE);
OUTREG(AVIVO_CRTC1_65B8 + avivo_crtc->crtc_offset, AVIVO_CRTC1_65B8_VALUE);
OUTREG(AVIVO_CRTC1_65BC + avivo_crtc->crtc_offset, AVIVO_CRTC1_65BC_VALUE);
OUTREG(AVIVO_CRTC1_65C8 + avivo_crtc->crtc_offset, AVIVO_CRTC1_65C8_VALUE);
- OUTREG(AVIVO_CRTC1_6594 + avivo_crtc->crtc_offset, AVIVO_CRTC1_6594_VALUE);
OUTREG(AVIVO_CRTC1_65A4 + avivo_crtc->crtc_offset, AVIVO_CRTC1_65A4_VALUE);
OUTREG(AVIVO_CRTC1_65B0 + avivo_crtc->crtc_offset, AVIVO_CRTC1_65B0_VALUE);
OUTREG(AVIVO_CRTC1_65C0 + avivo_crtc->crtc_offset, AVIVO_CRTC1_65C0_VALUE);
diff --git a/xorg/avivo_state.c b/xorg/avivo_state.c
index 21f5541..9e874c2 100644
--- a/xorg/avivo_state.c
+++ b/xorg/avivo_state.c
@@ -124,7 +124,8 @@ avivo_restore_state(ScrnInfoPtr screen_info)
OUTREG(AVIVO_CRTC1_X_LENGTH, state->crtc1_x_length);
OUTREG(AVIVO_CRTC1_Y_LENGTH, state->crtc1_y_length);
OUTREG(AVIVO_CRTC1_FB_HEIGHT, state->crtc1_fb_height);
- OUTREG(AVIVO_CRTC1_OFFSET, state->crtc1_offset);
+ OUTREG(AVIVO_CRTC1_OFFSET_START, state->crtc1_offset_start);
+ OUTREG(AVIVO_CRTC1_OFFSET_END, state->crtc1_offset_end);
OUTREG(AVIVO_CRTC1_EXPANSION_SOURCE, state->crtc1_expn_size);
OUTREG(AVIVO_CRTC1_EXPANSION_CNTL, state->crtc1_expn_cntl);
OUTREG(AVIVO_CRTC1_6594, state->crtc1_6594);
@@ -241,7 +242,8 @@ avivo_save_state(ScrnInfoPtr screen_info)
state->crtc1_x_length = INREG(AVIVO_CRTC1_X_LENGTH);
state->crtc1_y_length = INREG(AVIVO_CRTC1_Y_LENGTH);
state->crtc1_fb_height = INREG(AVIVO_CRTC1_FB_HEIGHT);
- state->crtc1_offset = INREG(AVIVO_CRTC1_OFFSET);
+ state->crtc1_offset_start = INREG(AVIVO_CRTC1_OFFSET_START);
+ state->crtc1_offset_end = INREG(AVIVO_CRTC1_OFFSET_END);
state->crtc1_expn_size = INREG(AVIVO_CRTC1_EXPANSION_SOURCE);
state->crtc1_expn_cntl = INREG(AVIVO_CRTC1_EXPANSION_CNTL);
state->crtc1_6594 = INREG(AVIVO_CRTC1_6594);