* turns out r800 has different register locations :(

* remove device_type and replace with device_chipset
* change MEMSIZE to >> 10 as r600-r700 store this in bytes (r800 uses MB and will be fixed soon)
* add if statement to select what register locations to use based on chipset
** Maybe use a struct or something to store these in a standardized way?


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41525 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV 2011-05-16 04:03:18 +00:00
parent 8ba4ac51f5
commit 2be925fd04
5 changed files with 88 additions and 62 deletions

View File

@ -24,11 +24,6 @@
#define VENDOR_ID_ATI 0x1002
// TODO : Remove masks as they don't apply to radeon
#define RADEON_TYPE_FAMILY_MASK 0xf000
#define RADEON_TYPE_GROUP_MASK 0xfff0
#define RADEON_TYPE_MODEL_MASK 0xffff
#define RADEON_R600 0x0600
#define RADEON_R700 0x0700
#define RADEON_R800 0x0800
@ -43,37 +38,6 @@
#define MODES_BOOT_INFO "vesa_modes/v1"
struct DeviceType {
uint32 type;
DeviceType(int t)
{
type = t;
}
DeviceType& operator=(int t)
{
type = t;
return *this;
}
bool InFamily(uint32 family) const
{
return (type & RADEON_TYPE_FAMILY_MASK) == family;
}
bool InGroup(uint32 group) const
{
return (type & RADEON_TYPE_GROUP_MASK) == group;
}
bool IsModel(uint32 model) const
{
return (type & RADEON_TYPE_MODEL_MASK) == model;
}
};
// info about PLL on graphics card
struct pll_info {
uint32 reference_frequency;
@ -141,7 +105,7 @@ struct radeon_shared_info {
uint16 cursor_hot_x;
uint16 cursor_hot_y;
DeviceType device_type;
uint32 device_chipset;
char device_identifier[32];
struct pll_info pll_info;
};

View File

@ -154,56 +154,104 @@ CardBlankSet(int crtNumber, bool blank)
static void
CardFBSet(int crtNumber, display_mode *mode)
{
uint16_t regOffset = (crtNumber == 2) ? D2_REG_OFFSET : D1_REG_OFFSET;
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;
get_color_space_format(*mode, colorMode, bytesPerRow, bitsPerPixel);
write32AtMask(regOffset + D1GRPH_ENABLE, 1, 0x00000001);
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;
}
write32(regOffset + D1GRPH_CONTROL, 0);
// 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);
write32(regOffset + grphControl, 0);
switch (mode->space) {
case B_CMAP8:
write32AtMask(regOffset + D1GRPH_CONTROL, 0, 0x00000703);
write32AtMask(regOffset + grphControl, 0, 0x00000703);
break;
case B_RGB15_LITTLE:
write32AtMask(regOffset + D1GRPH_CONTROL, 0x000001, 0x00000703);
write32AtMask(regOffset + grphControl, 0x000001, 0x00000703);
break;
case B_RGB16_LITTLE:
write32AtMask(regOffset + D1GRPH_CONTROL, 0x000101, 0x00000703);
write32AtMask(regOffset + grphControl, 0x000101, 0x00000703);
break;
case B_RGB24_LITTLE:
case B_RGB32_LITTLE:
default:
write32AtMask(regOffset + D1GRPH_CONTROL, 0x000002, 0x00000703);
write32AtMask(regOffset + grphControl, 0x000002, 0x00000703);
break;
}
write32(regOffset + D1GRPH_SWAP_CNTL, 0);
write32(regOffset + 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 + D1GRPH_PRIMARY_SURFACE_ADDRESS,
write32(regOffset + grphPrimarySurfaceAddr,
fbOffset + fbIntAddress);
write32(regOffset + D1GRPH_PITCH, bytesPerRow / 4);
write32(regOffset + D1GRPH_SURFACE_OFFSET_X, 0);
write32(regOffset + D1GRPH_SURFACE_OFFSET_Y, 0);
write32(regOffset + D1GRPH_X_START, 0);
write32(regOffset + D1GRPH_Y_START, 0);
write32(regOffset + D1GRPH_X_END, mode->virtual_width);
write32(regOffset + D1GRPH_Y_END, mode->virtual_height);
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);
/* D1Mode registers */
write32(regOffset + D1MODE_DESKTOP_HEIGHT, mode->virtual_height);
write32(regOffset + grphDesktopHeight, mode->virtual_height);
// update shared info
gInfo->shared_info->bytes_per_row = bytesPerRow;
@ -215,7 +263,21 @@ CardFBSet(int crtNumber, display_mode *mode)
static void
CardModeSet(int crtNumber, display_mode *mode)
{
uint16_t regOffset = (crtNumber == 2) ? D2_REG_OFFSET : D1_REG_OFFSET;
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;
}
CardBlankSet(crtNumber, true);
@ -225,7 +287,7 @@ CardModeSet(int crtNumber, display_mode *mode)
__func__, displayTiming.h_display, displayTiming.v_display);
// enable read requests
write32AtMask(regOffset + D1CRTC_CONTROL, 0, 0x01000000);
write32AtMask(regOffset + grphControl, 0, 0x01000000);
// *** Horizontal
write32(regOffset + D1CRTC_H_TOTAL, displayTiming.h_total - 1);

View File

@ -38,7 +38,7 @@
// list of supported devices
const struct supported_device {
uint32 device_id;
int32 type;
int32 chipset;
const char* name;
} kSupportedDevices[] = {
// R600 series (HD24xx - HD42xx)
@ -223,7 +223,7 @@ init_driver(void)
gDeviceInfo[found]->pci = info;
gDeviceInfo[found]->registers = (uint8 *)info->u.h0.base_registers[0];
gDeviceInfo[found]->device_identifier = kSupportedDevices[type].name;
gDeviceInfo[found]->device_type = kSupportedDevices[type].type;
gDeviceInfo[found]->device_chipset = kSupportedDevices[type].chipset;
dprintf(DEVICE_NAME ": GPU(%ld) %s, revision = 0x%x\n", found,
kSupportedDevices[type].name, info->revision);

View File

@ -111,9 +111,9 @@ radeon_hd_init(radeon_info &info)
// Read R6XX memory size into shared info
info.shared_info->graphics_memory_size
= read32(info.registers + R6XX_CONFIG_MEMSIZE);
= read32(info.registers + R6XX_CONFIG_MEMSIZE) >> 10;
TRACE("card(%ld): found %ld MB memory on card.\n", info.id,
TRACE("card(%ld): found %ld KB memory on card.\n", info.id,
info.shared_info->graphics_memory_size);
TRACE("card(%ld): %s completed successfully!\n", info.id, __func__);

View File

@ -32,7 +32,7 @@ struct radeon_info {
area_id shared_area;
const char* device_identifier;
DeviceType device_type;
uint32 device_chipset;
};