diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.cpp b/src/add-ons/accelerants/radeon_hd/accelerant.cpp index 8c5c81a7f0..fccbf836ab 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.cpp +++ b/src/add-ons/accelerants/radeon_hd/accelerant.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2006-2009, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de + * Alexander von Gluck, kallisti5@unixzen.com */ @@ -24,13 +25,14 @@ #define TRACE_ACCELERANT #ifdef TRACE_ACCELERANT extern "C" void _sPrintf(const char *format, ...); -# define TRACE(x) _sPrintf x +# define TRACE(x...) _sPrintf("radeon_hd: " x) #else -# define TRACE(x) ; +# define TRACE(x...) ; #endif struct accelerant_info *gInfo; +struct register_info *gRegister; class AreaCloner { @@ -92,10 +94,13 @@ init_common(int device, bool isClone) // initialize global accelerant info structure gInfo = (accelerant_info *)malloc(sizeof(accelerant_info)); - if (gInfo == NULL) + gRegister = (register_info *)malloc(sizeof(register_info)); + + if (gInfo == NULL || gRegister == NULL) return B_NO_MEMORY; memset(gInfo, 0, sizeof(accelerant_info)); + memset(gRegister, 0, sizeof(register_info)); gInfo->is_clone = isClone; gInfo->device = device; @@ -118,8 +123,8 @@ init_common(int device, bool isClone) status_t status = sharedCloner.InitCheck(); if (status < B_OK) { free(gInfo); - TRACE(("radeon_init_accelerant() failed shared area%i, %i\n", - data.shared_info_area, gInfo->shared_info_area)); + TRACE("%s, failed shared area%i, %i\n", + __func__, data.shared_info_area, gInfo->shared_info_area); return status; } @@ -154,6 +159,60 @@ uninit_common(void) close(gInfo->device); free(gInfo); + free(gRegister); +} + + +/*! Populate gRegister with device dependant register locations */ +static status_t +init_registers() +{ + // gInfo should always be populated before running this + if (gInfo == NULL) + return B_ERROR; + + uint16_t chipset = gInfo->shared_info->device_chipset; + + if (chipset >= RADEON_R800) { + gRegister->regOffsetCRT0 = EVERGREEN_CRTC0_REGISTER_OFFSET; + gRegister->regOffsetCRT1 = EVERGREEN_CRTC1_REGISTER_OFFSET; + gRegister->grphEnable = EVERGREEN_GRPH_ENABLE; + gRegister->grphControl = EVERGREEN_GRPH_CONTROL; + gRegister->grphSwapControl = EVERGREEN_GRPH_SWAP_CONTROL; + gRegister->grphPrimarySurfaceAddr + = EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS; + gRegister->grphPitch = EVERGREEN_GRPH_PITCH; + gRegister->grphSurfaceOffsetX = EVERGREEN_GRPH_SURFACE_OFFSET_X; + gRegister->grphSurfaceOffsetY = EVERGREEN_GRPH_SURFACE_OFFSET_Y; + gRegister->grphXStart = EVERGREEN_GRPH_X_START; + gRegister->grphYStart = EVERGREEN_GRPH_Y_START; + gRegister->grphXEnd = EVERGREEN_GRPH_X_END; + gRegister->grphYEnd = EVERGREEN_GRPH_Y_END; + gRegister->grphDesktopHeight = EVERGREEN_DESKTOP_HEIGHT; + } else if (chipset >= RADEON_R600 && chipset < RADEON_R800) { + gRegister->regOffsetCRT0 = D1_REG_OFFSET; + gRegister->regOffsetCRT1 = D2_REG_OFFSET; + gRegister->grphEnable = D1GRPH_ENABLE; + gRegister->grphControl = D1GRPH_CONTROL; + gRegister->grphSwapControl = D1GRPH_SWAP_CNTL; + gRegister->grphPrimarySurfaceAddr = D1GRPH_PRIMARY_SURFACE_ADDRESS; + gRegister->grphPitch = D1GRPH_PITCH; + gRegister->grphSurfaceOffsetX = D1GRPH_SURFACE_OFFSET_X; + gRegister->grphSurfaceOffsetY = D1GRPH_SURFACE_OFFSET_Y; + gRegister->grphXStart = D1GRPH_X_START; + gRegister->grphYStart = D1GRPH_Y_START; + gRegister->grphXEnd = D1GRPH_X_END; + gRegister->grphYEnd = D1GRPH_Y_END; + gRegister->grphDesktopHeight = D1MODE_DESKTOP_HEIGHT; + } else { + // this really shouldn't happen unless a driver PCIID chipset is wrong + TRACE("%s, unknown Radeon chipset: r%X\n", __func__, chipset); + return B_ERROR; + } + + TRACE("%s, registers for ATI chipset r%X initilized\n", __func__, chipset); + + return B_OK; } @@ -164,12 +223,16 @@ uninit_common(void) status_t radeon_init_accelerant(int device) { - TRACE(("radeon_init_accelerant()\n")); + TRACE("%s enter\n", __func__); status_t status = init_common(device, false); if (status != B_OK) return status; + status = init_registers(); + if (status != B_OK) + return status; + radeon_shared_info &info = *gInfo->shared_info; init_lock(&info.accelerant_lock, "radeon hd accelerant"); @@ -182,7 +245,7 @@ radeon_init_accelerant(int device) return status; } - TRACE(("radeon_init_accelerant() done\n")); + TRACE("%s done\n", __func__); return B_OK; } @@ -193,7 +256,7 @@ radeon_init_accelerant(int device) void radeon_uninit_accelerant(void) { - TRACE(("radeon_uninit_accelerant()\n")); + TRACE("%s enter\n", __func__); gInfo->mode_list = NULL; @@ -203,5 +266,6 @@ radeon_uninit_accelerant(void) uninit_lock(&info.engine_lock); uninit_common(); + TRACE("%s done\n", __func__); } diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index 620874e0d7..27a7f2168f 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -36,12 +36,32 @@ struct accelerant_info { display_mode lvds_panel_mode; }; + +struct register_info { + uint16_t regOffsetCRT0; + uint16_t regOffsetCRT1; + uint16_t grphEnable; + uint16_t grphControl; + uint16_t grphSwapControl; + uint16_t grphPrimarySurfaceAddr; + uint16_t grphPitch; + uint16_t grphSurfaceOffsetX; + uint16_t grphSurfaceOffsetY; + uint16_t grphXStart; + uint16_t grphYStart; + uint16_t grphXEnd; + uint16_t grphYEnd; + uint16_t grphDesktopHeight; +}; + + #define HEAD_MODE_A_ANALOG 0x01 #define HEAD_MODE_B_DIGITAL 0x02 #define HEAD_MODE_CLONE 0x03 #define HEAD_MODE_LVDS_PANEL 0x08 extern accelerant_info *gInfo; +extern register_info *gRegister; // register access diff --git a/src/add-ons/accelerants/radeon_hd/mode.cpp b/src/add-ons/accelerants/radeon_hd/mode.cpp index 968593296e..9c7fcfbf4c 100644 --- a/src/add-ons/accelerants/radeon_hd/mode.cpp +++ b/src/add-ons/accelerants/radeon_hd/mode.cpp @@ -152,104 +152,60 @@ CardBlankSet(int crtNumber, bool blank) static void CardFBSet(int crtNumber, display_mode *mode) { - uint16_t chipset = gInfo->shared_info->device_chipset; - uint32 colorMode; uint32 bytesPerRow; uint32 bitsPerPixel; - // Our registers - // (set to 0 to avoid reading/writing random memory if not set) - uint16_t regOffset = 0; - uint16_t grphEnable = 0; - uint16_t grphControl = 0; - uint16_t grphSwapControl = 0; - uint16_t grphPrimarySurfaceAddr = 0; - uint16_t grphPitch = 0; - uint16_t grphSurfaceOffsetX = 0; - uint16_t grphSurfaceOffsetY = 0; - uint16_t grphXStart = 0; - uint16_t grphYStart = 0; - uint16_t grphXEnd = 0; - uint16_t grphYEnd = 0; - uint16_t grphDesktopHeight = 0; + uint16_t regOffset = (crtNumber == 0) + ? gRegister->regOffsetCRT0 : gRegister->regOffsetCRT1; get_color_space_format(*mode, colorMode, bytesPerRow, bitsPerPixel); - if (chipset >= RADEON_R800) { - // Evergreen registers differ from r600-r700 - regOffset = (crtNumber == 2) - ? EVERGREEN_CRTC1_REGISTER_OFFSET : EVERGREEN_CRTC0_REGISTER_OFFSET; - grphEnable = EVERGREEN_GRPH_ENABLE; - grphControl = EVERGREEN_GRPH_CONTROL; - grphSwapControl = EVERGREEN_GRPH_SWAP_CONTROL; - grphPrimarySurfaceAddr = EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS; - grphPitch = EVERGREEN_GRPH_PITCH; - grphSurfaceOffsetX = EVERGREEN_GRPH_SURFACE_OFFSET_X; - grphSurfaceOffsetY = EVERGREEN_GRPH_SURFACE_OFFSET_Y; - grphXStart = EVERGREEN_GRPH_X_START; - grphYStart = EVERGREEN_GRPH_Y_START; - grphXEnd = EVERGREEN_GRPH_X_END; - grphYEnd = EVERGREEN_GRPH_Y_END; - grphDesktopHeight = EVERGREEN_DESKTOP_HEIGHT; - } else { - // r600-r700 registers - regOffset = (crtNumber == 2) ? D2_REG_OFFSET : D1_REG_OFFSET; - grphEnable = D1GRPH_ENABLE; - grphControl = D1GRPH_CONTROL; - grphSwapControl = D1GRPH_SWAP_CNTL; - grphPrimarySurfaceAddr = D1GRPH_PRIMARY_SURFACE_ADDRESS; - grphPitch = D1GRPH_PITCH; - grphSurfaceOffsetX = D1GRPH_SURFACE_OFFSET_X; - grphSurfaceOffsetY = D1GRPH_SURFACE_OFFSET_Y; - grphXStart = D1GRPH_X_START; - grphYStart = D1GRPH_Y_START; - grphXEnd = D1GRPH_X_END; - grphYEnd = D1GRPH_Y_END; - grphDesktopHeight = D1MODE_DESKTOP_HEIGHT; - } - // disable R/B swap, disable tiling, disable 16bit alpha, etc. - write32AtMask(regOffset + grphEnable, 1, 0x00000001); - write32(regOffset + grphControl, 0); + write32AtMask(regOffset + gRegister->grphEnable, 1, 0x00000001); + write32(regOffset + gRegister->grphControl, 0); switch (mode->space) { case B_CMAP8: - write32AtMask(regOffset + grphControl, 0, 0x00000703); + write32AtMask(regOffset + gRegister->grphControl, + 0, 0x00000703); break; case B_RGB15_LITTLE: - write32AtMask(regOffset + grphControl, 0x000001, 0x00000703); + write32AtMask(regOffset + gRegister->grphControl, + 0x000001, 0x00000703); break; case B_RGB16_LITTLE: - write32AtMask(regOffset + grphControl, 0x000101, 0x00000703); + write32AtMask(regOffset + gRegister->grphControl, + 0x000101, 0x00000703); break; case B_RGB24_LITTLE: case B_RGB32_LITTLE: default: - write32AtMask(regOffset + grphControl, 0x000002, 0x00000703); + write32AtMask(regOffset + gRegister->grphControl, + 0x000002, 0x00000703); break; } - write32(regOffset + grphSwapControl, 0); + write32(regOffset + gRegister->grphSwapControl, 0); // only for chipsets > r600 // R5xx - RS690 case is GRPH_CONTROL bit 16 uint32 fbIntAddress = read32(R6XX_CONFIG_FB_BASE); uint32 fbOffset = gInfo->shared_info->frame_buffer_offset; - write32(regOffset + grphPrimarySurfaceAddr, + write32(regOffset + gRegister->grphPrimarySurfaceAddr, fbOffset + fbIntAddress); - write32(regOffset + grphPitch, bytesPerRow / 4); - write32(regOffset + grphSurfaceOffsetX, 0); - write32(regOffset + grphSurfaceOffsetY, 0); - write32(regOffset + grphXStart, 0); - write32(regOffset + grphYStart, 0); - write32(regOffset + grphXEnd, mode->virtual_width); - write32(regOffset + grphYEnd, mode->virtual_height); + write32(regOffset + gRegister->grphPitch, bytesPerRow / 4); + write32(regOffset + gRegister->grphSurfaceOffsetX, 0); + write32(regOffset + gRegister->grphSurfaceOffsetY, 0); + write32(regOffset + gRegister->grphXStart, 0); + write32(regOffset + gRegister->grphYStart, 0); + write32(regOffset + gRegister->grphXEnd, mode->virtual_width); + write32(regOffset + gRegister->grphYEnd, mode->virtual_height); /* D1Mode registers */ - write32(regOffset + grphDesktopHeight, mode->virtual_height); + write32(regOffset + gRegister->grphDesktopHeight, mode->virtual_height); // update shared info gInfo->shared_info->bytes_per_row = bytesPerRow; @@ -261,21 +217,8 @@ CardFBSet(int crtNumber, display_mode *mode) static void CardModeSet(int crtNumber, display_mode *mode) { - uint16_t chipset = gInfo->shared_info->device_chipset; - - uint16_t regOffset = 0; - uint16_t grphControl = 0; - - if (chipset >= RADEON_R800) { - // Evergreen registers differ from r600-r700 - regOffset = (crtNumber == 2) - ? EVERGREEN_CRTC1_REGISTER_OFFSET : EVERGREEN_CRTC0_REGISTER_OFFSET; - grphControl = EVERGREEN_GRPH_CONTROL; - } else { - // r600-r700 registers - regOffset = (crtNumber == 2) ? D2_REG_OFFSET : D1_REG_OFFSET; - grphControl = D1GRPH_CONTROL; - } + uint16_t regOffset = (crtNumber == 0) + ? gRegister->regOffsetCRT0 : gRegister->regOffsetCRT1; CardBlankSet(crtNumber, true); @@ -285,7 +228,7 @@ CardModeSet(int crtNumber, display_mode *mode) __func__, displayTiming.h_display, displayTiming.v_display); // enable read requests - write32AtMask(regOffset + grphControl, 0, 0x01000000); + write32AtMask(regOffset + gRegister->grphControl, 0, 0x01000000); // *** Horizontal write32(regOffset + D1CRTC_H_TOTAL, displayTiming.h_total - 1); diff --git a/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp b/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp index 2068f9f902..ddfec97aee 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp @@ -104,6 +104,7 @@ const struct supported_device { // R800 series (HD54xx - HD59xx) // Codename: Evergreen + {0x68e1, RADEON_R800 | 0x0, "Radeon HD 5430"}, /*RV8XX*/ {0x68f9, RADEON_R800 | 0x0, "Radeon HD 5450"}, /*RV8XX*/ {0x68e0, RADEON_R800 | 0x0, "Radeon HD 5470"}, /*RV8XX*/ {0x68da, RADEON_R800 | 0x0, "Radeon HD 5500"}, /*RV8XX*/