* enhance tracing of accelerant
* introduce a global struct to hold register locations for Radeon HD chipset model this accelerant was spawned for. * add Radeon 5430 PCIID git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41555 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
|
* Alexander von Gluck, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -24,13 +25,14 @@
|
|||||||
#define TRACE_ACCELERANT
|
#define TRACE_ACCELERANT
|
||||||
#ifdef TRACE_ACCELERANT
|
#ifdef TRACE_ACCELERANT
|
||||||
extern "C" void _sPrintf(const char *format, ...);
|
extern "C" void _sPrintf(const char *format, ...);
|
||||||
# define TRACE(x) _sPrintf x
|
# define TRACE(x...) _sPrintf("radeon_hd: " x)
|
||||||
#else
|
#else
|
||||||
# define TRACE(x) ;
|
# define TRACE(x...) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct accelerant_info *gInfo;
|
struct accelerant_info *gInfo;
|
||||||
|
struct register_info *gRegister;
|
||||||
|
|
||||||
|
|
||||||
class AreaCloner {
|
class AreaCloner {
|
||||||
@@ -92,10 +94,13 @@ init_common(int device, bool isClone)
|
|||||||
// initialize global accelerant info structure
|
// initialize global accelerant info structure
|
||||||
|
|
||||||
gInfo = (accelerant_info *)malloc(sizeof(accelerant_info));
|
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;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
memset(gInfo, 0, sizeof(accelerant_info));
|
memset(gInfo, 0, sizeof(accelerant_info));
|
||||||
|
memset(gRegister, 0, sizeof(register_info));
|
||||||
|
|
||||||
gInfo->is_clone = isClone;
|
gInfo->is_clone = isClone;
|
||||||
gInfo->device = device;
|
gInfo->device = device;
|
||||||
@@ -118,8 +123,8 @@ init_common(int device, bool isClone)
|
|||||||
status_t status = sharedCloner.InitCheck();
|
status_t status = sharedCloner.InitCheck();
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
free(gInfo);
|
free(gInfo);
|
||||||
TRACE(("radeon_init_accelerant() failed shared area%i, %i\n",
|
TRACE("%s, failed shared area%i, %i\n",
|
||||||
data.shared_info_area, gInfo->shared_info_area));
|
__func__, data.shared_info_area, gInfo->shared_info_area);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +159,60 @@ uninit_common(void)
|
|||||||
close(gInfo->device);
|
close(gInfo->device);
|
||||||
|
|
||||||
free(gInfo);
|
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
|
status_t
|
||||||
radeon_init_accelerant(int device)
|
radeon_init_accelerant(int device)
|
||||||
{
|
{
|
||||||
TRACE(("radeon_init_accelerant()\n"));
|
TRACE("%s enter\n", __func__);
|
||||||
|
|
||||||
status_t status = init_common(device, false);
|
status_t status = init_common(device, false);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
status = init_registers();
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
radeon_shared_info &info = *gInfo->shared_info;
|
radeon_shared_info &info = *gInfo->shared_info;
|
||||||
|
|
||||||
init_lock(&info.accelerant_lock, "radeon hd accelerant");
|
init_lock(&info.accelerant_lock, "radeon hd accelerant");
|
||||||
@@ -182,7 +245,7 @@ radeon_init_accelerant(int device)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("radeon_init_accelerant() done\n"));
|
TRACE("%s done\n", __func__);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +256,7 @@ radeon_init_accelerant(int device)
|
|||||||
void
|
void
|
||||||
radeon_uninit_accelerant(void)
|
radeon_uninit_accelerant(void)
|
||||||
{
|
{
|
||||||
TRACE(("radeon_uninit_accelerant()\n"));
|
TRACE("%s enter\n", __func__);
|
||||||
|
|
||||||
gInfo->mode_list = NULL;
|
gInfo->mode_list = NULL;
|
||||||
|
|
||||||
@@ -203,5 +266,6 @@ radeon_uninit_accelerant(void)
|
|||||||
uninit_lock(&info.engine_lock);
|
uninit_lock(&info.engine_lock);
|
||||||
|
|
||||||
uninit_common();
|
uninit_common();
|
||||||
|
TRACE("%s done\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,32 @@ struct accelerant_info {
|
|||||||
display_mode lvds_panel_mode;
|
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_A_ANALOG 0x01
|
||||||
#define HEAD_MODE_B_DIGITAL 0x02
|
#define HEAD_MODE_B_DIGITAL 0x02
|
||||||
#define HEAD_MODE_CLONE 0x03
|
#define HEAD_MODE_CLONE 0x03
|
||||||
#define HEAD_MODE_LVDS_PANEL 0x08
|
#define HEAD_MODE_LVDS_PANEL 0x08
|
||||||
|
|
||||||
extern accelerant_info *gInfo;
|
extern accelerant_info *gInfo;
|
||||||
|
extern register_info *gRegister;
|
||||||
|
|
||||||
// register access
|
// register access
|
||||||
|
|
||||||
|
|||||||
@@ -152,104 +152,60 @@ CardBlankSet(int crtNumber, bool blank)
|
|||||||
static void
|
static void
|
||||||
CardFBSet(int crtNumber, display_mode *mode)
|
CardFBSet(int crtNumber, display_mode *mode)
|
||||||
{
|
{
|
||||||
uint16_t chipset = gInfo->shared_info->device_chipset;
|
|
||||||
|
|
||||||
uint32 colorMode;
|
uint32 colorMode;
|
||||||
uint32 bytesPerRow;
|
uint32 bytesPerRow;
|
||||||
uint32 bitsPerPixel;
|
uint32 bitsPerPixel;
|
||||||
|
|
||||||
// Our registers
|
uint16_t regOffset = (crtNumber == 0)
|
||||||
// (set to 0 to avoid reading/writing random memory if not set)
|
? gRegister->regOffsetCRT0 : gRegister->regOffsetCRT1;
|
||||||
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;
|
|
||||||
|
|
||||||
get_color_space_format(*mode, colorMode, bytesPerRow, bitsPerPixel);
|
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.
|
// disable R/B swap, disable tiling, disable 16bit alpha, etc.
|
||||||
write32AtMask(regOffset + grphEnable, 1, 0x00000001);
|
write32AtMask(regOffset + gRegister->grphEnable, 1, 0x00000001);
|
||||||
write32(regOffset + grphControl, 0);
|
write32(regOffset + gRegister->grphControl, 0);
|
||||||
|
|
||||||
switch (mode->space) {
|
switch (mode->space) {
|
||||||
case B_CMAP8:
|
case B_CMAP8:
|
||||||
write32AtMask(regOffset + grphControl, 0, 0x00000703);
|
write32AtMask(regOffset + gRegister->grphControl,
|
||||||
|
0, 0x00000703);
|
||||||
break;
|
break;
|
||||||
case B_RGB15_LITTLE:
|
case B_RGB15_LITTLE:
|
||||||
write32AtMask(regOffset + grphControl, 0x000001, 0x00000703);
|
write32AtMask(regOffset + gRegister->grphControl,
|
||||||
|
0x000001, 0x00000703);
|
||||||
break;
|
break;
|
||||||
case B_RGB16_LITTLE:
|
case B_RGB16_LITTLE:
|
||||||
write32AtMask(regOffset + grphControl, 0x000101, 0x00000703);
|
write32AtMask(regOffset + gRegister->grphControl,
|
||||||
|
0x000101, 0x00000703);
|
||||||
break;
|
break;
|
||||||
case B_RGB24_LITTLE:
|
case B_RGB24_LITTLE:
|
||||||
case B_RGB32_LITTLE:
|
case B_RGB32_LITTLE:
|
||||||
default:
|
default:
|
||||||
write32AtMask(regOffset + grphControl, 0x000002, 0x00000703);
|
write32AtMask(regOffset + gRegister->grphControl,
|
||||||
|
0x000002, 0x00000703);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
write32(regOffset + grphSwapControl, 0);
|
write32(regOffset + gRegister->grphSwapControl, 0);
|
||||||
// only for chipsets > r600
|
// only for chipsets > r600
|
||||||
// R5xx - RS690 case is GRPH_CONTROL bit 16
|
// R5xx - RS690 case is GRPH_CONTROL bit 16
|
||||||
|
|
||||||
uint32 fbIntAddress = read32(R6XX_CONFIG_FB_BASE);
|
uint32 fbIntAddress = read32(R6XX_CONFIG_FB_BASE);
|
||||||
uint32 fbOffset = gInfo->shared_info->frame_buffer_offset;
|
uint32 fbOffset = gInfo->shared_info->frame_buffer_offset;
|
||||||
|
|
||||||
write32(regOffset + grphPrimarySurfaceAddr,
|
write32(regOffset + gRegister->grphPrimarySurfaceAddr,
|
||||||
fbOffset + fbIntAddress);
|
fbOffset + fbIntAddress);
|
||||||
|
|
||||||
write32(regOffset + grphPitch, bytesPerRow / 4);
|
write32(regOffset + gRegister->grphPitch, bytesPerRow / 4);
|
||||||
write32(regOffset + grphSurfaceOffsetX, 0);
|
write32(regOffset + gRegister->grphSurfaceOffsetX, 0);
|
||||||
write32(regOffset + grphSurfaceOffsetY, 0);
|
write32(regOffset + gRegister->grphSurfaceOffsetY, 0);
|
||||||
write32(regOffset + grphXStart, 0);
|
write32(regOffset + gRegister->grphXStart, 0);
|
||||||
write32(regOffset + grphYStart, 0);
|
write32(regOffset + gRegister->grphYStart, 0);
|
||||||
write32(regOffset + grphXEnd, mode->virtual_width);
|
write32(regOffset + gRegister->grphXEnd, mode->virtual_width);
|
||||||
write32(regOffset + grphYEnd, mode->virtual_height);
|
write32(regOffset + gRegister->grphYEnd, mode->virtual_height);
|
||||||
|
|
||||||
/* D1Mode registers */
|
/* D1Mode registers */
|
||||||
write32(regOffset + grphDesktopHeight, mode->virtual_height);
|
write32(regOffset + gRegister->grphDesktopHeight, mode->virtual_height);
|
||||||
|
|
||||||
// update shared info
|
// update shared info
|
||||||
gInfo->shared_info->bytes_per_row = bytesPerRow;
|
gInfo->shared_info->bytes_per_row = bytesPerRow;
|
||||||
@@ -261,21 +217,8 @@ CardFBSet(int crtNumber, display_mode *mode)
|
|||||||
static void
|
static void
|
||||||
CardModeSet(int crtNumber, display_mode *mode)
|
CardModeSet(int crtNumber, display_mode *mode)
|
||||||
{
|
{
|
||||||
uint16_t chipset = gInfo->shared_info->device_chipset;
|
uint16_t regOffset = (crtNumber == 0)
|
||||||
|
? gRegister->regOffsetCRT0 : gRegister->regOffsetCRT1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
CardBlankSet(crtNumber, true);
|
CardBlankSet(crtNumber, true);
|
||||||
|
|
||||||
@@ -285,7 +228,7 @@ CardModeSet(int crtNumber, display_mode *mode)
|
|||||||
__func__, displayTiming.h_display, displayTiming.v_display);
|
__func__, displayTiming.h_display, displayTiming.v_display);
|
||||||
|
|
||||||
// enable read requests
|
// enable read requests
|
||||||
write32AtMask(regOffset + grphControl, 0, 0x01000000);
|
write32AtMask(regOffset + gRegister->grphControl, 0, 0x01000000);
|
||||||
|
|
||||||
// *** Horizontal
|
// *** Horizontal
|
||||||
write32(regOffset + D1CRTC_H_TOTAL, displayTiming.h_total - 1);
|
write32(regOffset + D1CRTC_H_TOTAL, displayTiming.h_total - 1);
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ const struct supported_device {
|
|||||||
|
|
||||||
// R800 series (HD54xx - HD59xx)
|
// R800 series (HD54xx - HD59xx)
|
||||||
// Codename: Evergreen
|
// Codename: Evergreen
|
||||||
|
{0x68e1, RADEON_R800 | 0x0, "Radeon HD 5430"}, /*RV8XX*/
|
||||||
{0x68f9, RADEON_R800 | 0x0, "Radeon HD 5450"}, /*RV8XX*/
|
{0x68f9, RADEON_R800 | 0x0, "Radeon HD 5450"}, /*RV8XX*/
|
||||||
{0x68e0, RADEON_R800 | 0x0, "Radeon HD 5470"}, /*RV8XX*/
|
{0x68e0, RADEON_R800 | 0x0, "Radeon HD 5470"}, /*RV8XX*/
|
||||||
{0x68da, RADEON_R800 | 0x0, "Radeon HD 5500"}, /*RV8XX*/
|
{0x68da, RADEON_R800 | 0x0, "Radeon HD 5500"}, /*RV8XX*/
|
||||||
|
|||||||
Reference in New Issue
Block a user