From abbf73ee990512ac16ca77e8bb23288495e1f9f4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 11 Nov 2010 09:38:15 +1000 Subject: evergreen: add UMS VT switch support. This isn't perfect, but it brings back text VTs here on the DAC and DVI outputs. --- src/radeon_driver.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/radeon_probe.h | 9 ++- 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 @@ -4483,6 +4483,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) { @@ -4841,6 +4982,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) { @@ -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]; -- cgit v1.2.3