summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-11-11 09:38:15 +1000
committerDave Airlie <airlied@redhat.com>2010-11-11 12:56:15 +1000
commitabbf73ee990512ac16ca77e8bb23288495e1f9f4 (patch)
tree1f05ca0790d5547a05b54796eea560da033f71f1
parente1dfaf93d06bc5eafdbc2e1823d19204ce8f242c (diff)
evergreen: add UMS VT switch support.
This isn't perfect, but it brings back text VTs here on the DAC and DVI outputs.
-rw-r--r--src/radeon_driver.c172
-rw-r--r--src/radeon_probe.h9
2 files changed, 179 insertions, 2 deletions
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 049c57a7..ae2f5258 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4484,6 +4484,147 @@ static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
}
static void
+evergreen_save_grph(ScrnInfoPtr pScrn, RADEONSavePtr save, int index)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ struct avivo_state *state = &save->avivo;
+ uint32_t grph_offset[] = {0x0, 0xc00, 0x9800, 0xa400, 0xb000, 0xbc00};
+
+ state->grph[index].enable = INREG(grph_offset[index] + EVERGREEN_GRPH_ENABLE);
+ state->grph[index].control = INREG(grph_offset[index] + EVERGREEN_GRPH_CONTROL);
+ state->grph[index].swap_control = INREG(grph_offset[index] + EVERGREEN_GRPH_SWAP_CONTROL);
+ state->grph[index].prim_surf_addr = INREG(grph_offset[index] + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS);
+ state->grph[index].sec_surf_addr = INREG(grph_offset[index] + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS);
+ state->grph[index].pitch = INREG(grph_offset[index] + EVERGREEN_GRPH_PITCH);
+ state->grph[index].prim_surf_addr_hi = INREG(grph_offset[index] + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH);
+ state->grph[index].sec_surf_addr_hi = INREG(grph_offset[index] + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH);
+ state->grph[index].x_offset = INREG(grph_offset[index] + EVERGREEN_GRPH_SURFACE_OFFSET_X);
+ state->grph[index].y_offset = INREG(grph_offset[index] + EVERGREEN_GRPH_SURFACE_OFFSET_Y);
+ state->grph[index].x_start = INREG(grph_offset[index] + EVERGREEN_GRPH_X_START);
+ state->grph[index].y_start = INREG(grph_offset[index] + EVERGREEN_GRPH_Y_START);
+ state->grph[index].x_end = INREG(grph_offset[index] + EVERGREEN_GRPH_X_END);
+ state->grph[index].y_end = INREG(grph_offset[index] + EVERGREEN_GRPH_Y_END);
+
+ state->grph[index].desktop_height = INREG(grph_offset[index] + EVERGREEN_DESKTOP_HEIGHT);
+ state->grph[index].viewport_start = INREG(grph_offset[index] + EVERGREEN_VIEWPORT_START);
+ state->grph[index].viewport_size = INREG(grph_offset[index] + EVERGREEN_VIEWPORT_SIZE);
+ state->grph[index].mode_data_format = INREG(grph_offset[index] + EVERGREEN_DATA_FORMAT);
+}
+
+static void
+evergreen_restore_grph(ScrnInfoPtr pScrn, RADEONSavePtr restore, int index)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ struct avivo_state *state = &restore->avivo;
+ uint32_t grph_offset[] = {0x0, 0xc00, 0x9800, 0xa400, 0xb000, 0xbc00};
+
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_ENABLE, state->grph[index].enable);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_CONTROL, state->grph[index].control);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_SWAP_CONTROL, state->grph[index].swap_control);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS, state->grph[index].prim_surf_addr);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS, state->grph[index].sec_surf_addr);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_PITCH, state->grph[index].pitch);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, state->grph[index].prim_surf_addr_hi);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, state->grph[index].sec_surf_addr_hi);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_SURFACE_OFFSET_X, state->grph[index].x_offset);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_SURFACE_OFFSET_Y, state->grph[index].y_offset);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_X_START, state->grph[index].x_start);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_Y_START, state->grph[index].y_start);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_X_END, state->grph[index].x_end);
+ OUTREG(grph_offset[index] + EVERGREEN_GRPH_Y_END, state->grph[index].y_end);
+
+ OUTREG(grph_offset[index] + EVERGREEN_DESKTOP_HEIGHT, state->grph[index].desktop_height);
+ OUTREG(grph_offset[index] + EVERGREEN_VIEWPORT_START, state->grph[index].viewport_start);
+ OUTREG(grph_offset[index] + EVERGREEN_VIEWPORT_SIZE, state->grph[index].viewport_size);
+ OUTREG(grph_offset[index] + EVERGREEN_DATA_FORMAT, state->grph[index].mode_data_format);
+}
+
+static uint32_t evergreen_dac_regs[] = {
+ 0x6690, 0x6694, 0x66b0, 0x66cc, 0x66d0, 0x66d4, 0x66d8 };
+
+static uint32_t evergreen_scl1_regs[] = {
+ 0x6d08, 0x6d0c, 0x6d14, 0x6d1c };
+
+static uint32_t evergreen_crtc_regs[] = {
+ 0x6e00, 0x6e04, 0x6e08, 0x6e0c, 0x6e1c, 0x6e34, 0x6e38, 0x6e3c, 0x6e70, 0x6e74, 0x6e78};
+
+#define EG_REG_SCL1_NUM (sizeof(evergreen_scl1_regs)/sizeof(uint32_t))
+#define EG_REG_CRTC_NUM (sizeof(evergreen_crtc_regs)/sizeof(uint32_t))
+#define EG_DAC_NUM (sizeof(evergreen_dac_regs)/sizeof(uint32_t))
+
+
+static void
+evergreen_save_crtc(ScrnInfoPtr pScrn, RADEONSavePtr save, int index)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ struct avivo_state *state = &save->avivo;
+ int i;
+
+ uint32_t crtc_offset[] = {EVERGREEN_CRTC0_REGISTER_OFFSET,
+ EVERGREEN_CRTC1_REGISTER_OFFSET,
+ EVERGREEN_CRTC2_REGISTER_OFFSET,
+ EVERGREEN_CRTC3_REGISTER_OFFSET,
+ EVERGREEN_CRTC4_REGISTER_OFFSET,
+ EVERGREEN_CRTC5_REGISTER_OFFSET};
+
+ for (i = 0; i < EG_REG_CRTC_NUM; i++) {
+ state->eg_crtc[index][i] = INREG(crtc_offset[index] + evergreen_crtc_regs[i]);
+ }
+}
+
+static void
+evergreen_restore_crtc(ScrnInfoPtr pScrn, RADEONSavePtr restore, int index)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ struct avivo_state *state = &restore->avivo;
+ int i;
+ uint32_t crtc_offset[] = {EVERGREEN_CRTC0_REGISTER_OFFSET,
+ EVERGREEN_CRTC1_REGISTER_OFFSET,
+ EVERGREEN_CRTC2_REGISTER_OFFSET,
+ EVERGREEN_CRTC3_REGISTER_OFFSET,
+ EVERGREEN_CRTC4_REGISTER_OFFSET,
+ EVERGREEN_CRTC5_REGISTER_OFFSET};
+
+ for (i = 0; i < EG_REG_CRTC_NUM; i++) {
+ OUTREG(crtc_offset[index] + evergreen_crtc_regs[i], state->eg_crtc[index][i]);
+ }
+}
+
+static void
+evergreen_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ struct avivo_state *state = &save->avivo;
+ int i, j;
+
+ state->vga1_cntl = INREG(AVIVO_D1VGA_CONTROL);
+ state->vga2_cntl = INREG(AVIVO_D2VGA_CONTROL);
+ state->vga3_cntl = INREG(EVERGREEN_D3VGA_CONTROL);
+ state->vga4_cntl = INREG(EVERGREEN_D4VGA_CONTROL);
+ state->vga5_cntl = INREG(EVERGREEN_D5VGA_CONTROL);
+ state->vga6_cntl = INREG(EVERGREEN_D6VGA_CONTROL);
+ state->vga_render_control = INREG(AVIVO_VGA_RENDER_CONTROL);
+
+ for (i = 0; i < 6; i++)
+ evergreen_save_grph(pScrn, save, i);
+
+ for (i = 0; i < 6; i++)
+ evergreen_save_crtc(pScrn, save, i);
+
+ for (i = 0; i < EG_DAC_NUM; i++)
+ state->daca[i] = INREG(evergreen_dac_regs[i]);
+
+ for (i = 0; i < EG_REG_SCL1_NUM; i++)
+ state->d1scl[i] = INREG(evergreen_scl1_regs[i]);
+
+}
+
+static void
avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -4842,6 +4983,35 @@ avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
}
static void
+evergreen_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ struct avivo_state *state = &restore->avivo;
+ int i, j;
+
+ OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
+ OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);;
+ OUTREG(EVERGREEN_D3VGA_CONTROL, state->vga3_cntl);
+ OUTREG(EVERGREEN_D4VGA_CONTROL, state->vga4_cntl);
+ OUTREG(EVERGREEN_D5VGA_CONTROL, state->vga5_cntl);
+ OUTREG(EVERGREEN_D6VGA_CONTROL, state->vga6_cntl);
+ OUTREG(AVIVO_VGA_RENDER_CONTROL, state->vga_render_control);
+
+ for (i = 0; i < 6; i++)
+ evergreen_restore_grph(pScrn, restore, i);
+
+ for (i = 0; i < 6; i++)
+ evergreen_restore_crtc(pScrn, restore, i);
+
+ for (i = 0; i < EG_DAC_NUM; i++)
+ OUTREG(evergreen_dac_regs[i], state->daca[i]);
+
+ for (i = 0; i < EG_REG_SCL1_NUM; i++)
+ OUTREG(evergreen_scl1_regs[i], state->d1scl[i]);
+}
+
+static void
avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -5338,6 +5508,7 @@ static void RADEONSave(ScrnInfoPtr pScrn)
if (IS_DCE4_VARIANT) {
RADEONSaveMemMapRegisters(pScrn, save);
+ evergreen_save(pScrn, save);
//XXX
} else if (IS_AVIVO_VARIANT) {
RADEONSaveMemMapRegisters(pScrn, save);
@@ -5393,6 +5564,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
if (IS_DCE4_VARIANT) {
RADEONRestoreMemMapRegisters(pScrn, restore);
+ evergreen_restore(pScrn, restore);
//XXX
} else if (IS_AVIVO_VARIANT) {
RADEONRestoreMemMapRegisters(pScrn, restore);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 78179ed3..2b78a1f1 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -344,9 +344,12 @@ struct avivo_crtc_state {
struct avivo_grph_state {
uint32_t enable;
uint32_t control;
+ uint32_t swap_control;
uint32_t prim_surf_addr;
uint32_t sec_surf_addr;
uint32_t pitch;
+ uint32_t prim_surf_addr_hi;
+ uint32_t sec_surf_addr_hi;
uint32_t x_offset;
uint32_t y_offset;
uint32_t x_start;
@@ -385,9 +388,11 @@ struct avivo_state
struct avivo_pll_state vga28_ppll;
struct avivo_pll_state vga41_ppll;
- struct avivo_crtc_state crtc[6];
+ struct avivo_crtc_state crtc[2];
- struct avivo_grph_state grph[2];
+ uint32_t eg_crtc[6][15];
+
+ struct avivo_grph_state grph[6];
/* DDIA block on RS6xx chips */
uint32_t ddia[37];