* Added support for the G33 line of chips: mode setting and acceleration is working fine AFAICT.
* Implemented mapping the GTT area for i9xx chips other than the i965. This should also fix the driver working with these chips at all. * The memory used by the driver now take the GTT area into account - before the GTT could be overwritten theoretically... * Added fix for some i965 quirks from the X driver. * Added some overlay definitions for the i965. * Started support for G33 overlay (not complete yet). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23220 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
971cf1881e
commit
c88e5e410c
@ -27,9 +27,10 @@
|
||||
#define INTEL_TYPE_9xx 0x04
|
||||
#define INTEL_TYPE_83x 0x10
|
||||
#define INTEL_TYPE_85x 0x20
|
||||
#define INTEL_TYPE_915 0x10
|
||||
#define INTEL_TYPE_91x 0x10
|
||||
#define INTEL_TYPE_945 0x20
|
||||
#define INTEL_TYPE_965 0x40
|
||||
#define INTEL_TYPE_G33 0x80
|
||||
|
||||
#define DEVICE_NAME "intel_extreme"
|
||||
#define INTEL_ACCELERANT_NAME "intel_extreme.accelerant"
|
||||
@ -84,6 +85,7 @@ struct intel_shared_info {
|
||||
bool overlay_active;
|
||||
uint32 overlay_token;
|
||||
uint8* physical_overlay_registers;
|
||||
uint32 overlay_offset;
|
||||
|
||||
bool hardware_cursor_enabled;
|
||||
sem_id vblank_sem;
|
||||
@ -138,13 +140,18 @@ struct intel_free_graphics_memory {
|
||||
|
||||
// PCI bridge memory management
|
||||
#define INTEL_GRAPHICS_MEMORY_CONTROL 0x52
|
||||
#define MEMORY_MASK 0x01
|
||||
#define STOLEN_MEMORY_MASK 0x70
|
||||
#define i965_GTT_MASK 0x000e
|
||||
#define G33_GTT_MASK 0x0300
|
||||
|
||||
// models i830 and up
|
||||
#define i830_LOCAL_MEMORY_ONLY 0x10
|
||||
#define i830_STOLEN_512K 0x20
|
||||
#define i830_STOLEN_1M 0x30
|
||||
#define i830_STOLEN_8M 0x40
|
||||
#define i830_FRAME_BUFFER_64M 0x01
|
||||
#define i830_FRAME_BUFFER_128M 0x00
|
||||
|
||||
// models i855 and up
|
||||
#define i855_STOLEN_MEMORY_1M 0x10
|
||||
@ -154,6 +161,8 @@ struct intel_free_graphics_memory {
|
||||
#define i855_STOLEN_MEMORY_32M 0x50
|
||||
#define i855_STOLEN_MEMORY_48M 0x60
|
||||
#define i855_STOLEN_MEMORY_64M 0x70
|
||||
#define i855_STOLEN_MEMORY_128M 0x80
|
||||
#define i855_STOLEN_MEMORY_256M 0x90
|
||||
|
||||
// graphics page translation table
|
||||
#define INTEL_PAGE_TABLE_CONTROL 0x02020
|
||||
@ -163,6 +172,11 @@ struct intel_free_graphics_memory {
|
||||
#define i830_GTT_SIZE 0x20000
|
||||
#define i965_GTT_BASE 0x80000 // (- 0xfffff)
|
||||
#define i965_GTT_SIZE 0x80000
|
||||
#define i965_GTT_128K (2 << 1)
|
||||
#define i965_GTT_256K (1 << 1)
|
||||
#define i965_GTT_512K (0 << 1)
|
||||
#define G33_GTT_1M (1 << 8)
|
||||
#define G33_GTT_2M (2 << 8)
|
||||
#define GTT_ENTRY_VALID 0x01
|
||||
#define GTT_ENTRY_LOCAL_MEMORY 0x02
|
||||
|
||||
@ -481,12 +495,21 @@ struct overlay_registers {
|
||||
|
||||
uint32 _reserved20;
|
||||
|
||||
uint32 start_0y;
|
||||
uint32 start_1y;
|
||||
uint32 start_0u;
|
||||
uint32 start_0v;
|
||||
uint32 start_1u;
|
||||
uint32 start_1v;
|
||||
uint32 _reserved21[6];
|
||||
#if 0
|
||||
// (0x70) AWINPOS - alpha blend window position
|
||||
uint32 awinpos;
|
||||
// (0x74) AWINSZ - alpha blend window size
|
||||
uint32 awinsz;
|
||||
|
||||
uint32 _reserved21[10];
|
||||
#endif
|
||||
|
||||
// (0xa0) FASTHSCALE - fast horizontal downscale (strangely enough,
|
||||
// the next two registers switch the usual Y/RGB vs. UV order)
|
||||
@ -509,6 +532,10 @@ struct overlay_registers {
|
||||
uint16 horizontal_coefficients_uv[128];
|
||||
};
|
||||
|
||||
// i965 overlay support is currently realized using its 3D hardware
|
||||
#define INTEL_i965_OVERLAY_STATE_SIZE 36864
|
||||
#define INTEL_i965_3D_CONTEXT_SIZE 32768
|
||||
|
||||
struct hardware_status {
|
||||
uint32 interrupt_status_register;
|
||||
uint32 _reserved0[3];
|
||||
|
@ -42,15 +42,16 @@ const struct supported_device {
|
||||
{0x2572, INTEL_TYPE_8xx | INTEL_TYPE_85x, "i865G"},
|
||||
{0x3582, INTEL_TYPE_8xx | INTEL_TYPE_85x, "i855G"},
|
||||
|
||||
#if 1
|
||||
{0x2792, INTEL_TYPE_9xx, "i910"},
|
||||
{0x258a, INTEL_TYPE_9xx, "i915"},
|
||||
{0x2582, INTEL_TYPE_9xx, "i915G"},
|
||||
{0x2592, INTEL_TYPE_9xx, "i915GM"},
|
||||
{0x2772, INTEL_TYPE_9xx, "i945G"},
|
||||
{0x27a2, INTEL_TYPE_9xx, "i945GM"},
|
||||
{0x29a2, INTEL_TYPE_9xx | INTEL_TYPE_965, "i965G"}
|
||||
#endif
|
||||
{0x2792, INTEL_TYPE_9xx | INTEL_TYPE_91x, "i910"},
|
||||
{0x258a, INTEL_TYPE_9xx | INTEL_TYPE_91x, "i915"},
|
||||
{0x2582, INTEL_TYPE_9xx | INTEL_TYPE_91x, "i915G"},
|
||||
{0x2592, INTEL_TYPE_9xx | INTEL_TYPE_91x, "i915GM"},
|
||||
{0x2772, INTEL_TYPE_9xx | INTEL_TYPE_945, "i945G"},
|
||||
{0x27a2, INTEL_TYPE_9xx | INTEL_TYPE_945, "i945GM"},
|
||||
{0x29a2, INTEL_TYPE_9xx | INTEL_TYPE_965, "i965G"},
|
||||
{0x29b2, INTEL_TYPE_9xx | INTEL_TYPE_G33, "G33G"},
|
||||
{0x29c2, INTEL_TYPE_9xx | INTEL_TYPE_G33, "Q35G"},
|
||||
{0x29d2, INTEL_TYPE_9xx | INTEL_TYPE_G33, "Q33G"},
|
||||
};
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
@ -104,7 +104,7 @@ static void
|
||||
read_settings(size_t &memorySize, bool &hardwareCursor, bool &ignoreAllocated)
|
||||
{
|
||||
size_t size = 8; // 8 MB
|
||||
hardwareCursor = true;
|
||||
hardwareCursor = false;
|
||||
ignoreAllocated = false;
|
||||
|
||||
void *settings = load_driver_settings("intel_extreme");
|
||||
@ -145,6 +145,45 @@ determine_stolen_memory_size(intel_info &info)
|
||||
// read stolen memory from the PCI configuration of the PCI bridge
|
||||
uint16 memoryConfig = gPCI->read_pci_config(0, 0, 0, INTEL_GRAPHICS_MEMORY_CONTROL, 2);
|
||||
size_t memorySize = 1 << 20; // 1 MB
|
||||
size_t gttSize = 0;
|
||||
|
||||
// TODO: check if the GTT is really part of the stolen memory
|
||||
if (info.device_type == (INTEL_TYPE_9xx | INTEL_TYPE_965)) {
|
||||
switch (memoryConfig & i965_GTT_MASK) {
|
||||
case i965_GTT_128K:
|
||||
gttSize = 128 << 10;
|
||||
break;
|
||||
case i965_GTT_256K:
|
||||
gttSize = 256 << 10;
|
||||
break;
|
||||
case i965_GTT_512K:
|
||||
gttSize = 512 << 10;
|
||||
break;
|
||||
}
|
||||
} else if (info.device_type == (INTEL_TYPE_9xx | INTEL_TYPE_G33)) {
|
||||
switch (memoryConfig & G33_GTT_MASK) {
|
||||
case G33_GTT_1M:
|
||||
gttSize = 1 << 20;
|
||||
break;
|
||||
case G33_GTT_2M:
|
||||
gttSize = 2 << 20;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// older models have the GTT as large as their frame buffer mapping
|
||||
// TODO: check if the i9xx version works with the i8xx chips as well
|
||||
size_t frameBufferSize = 0;
|
||||
if ((info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_8xx) {
|
||||
if ((info.device_type & INTEL_TYPE_83x) != 0
|
||||
&& (memoryConfig & MEMORY_MASK) == i830_FRAME_BUFFER_64M)
|
||||
frameBufferSize = 64 << 20;
|
||||
else
|
||||
frameBufferSize = 128 << 20;
|
||||
} else if ((info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx)
|
||||
frameBufferSize = info.pci->u.h0.base_register_sizes[2];
|
||||
|
||||
gttSize = frameBufferSize / 1024;
|
||||
}
|
||||
|
||||
// TODO: test with different models!
|
||||
|
||||
@ -181,10 +220,16 @@ determine_stolen_memory_size(intel_info &info)
|
||||
case i855_STOLEN_MEMORY_64M:
|
||||
memorySize *= 64;
|
||||
break;
|
||||
case i855_STOLEN_MEMORY_128M:
|
||||
memorySize *= 128;
|
||||
break;
|
||||
case i855_STOLEN_MEMORY_256M:
|
||||
memorySize *= 256;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return memorySize;
|
||||
return memorySize - gttSize - 4096;
|
||||
}
|
||||
|
||||
|
||||
@ -352,7 +397,7 @@ intel_extreme_init(intel_info &info)
|
||||
AreaKeeper graphicsMapper;
|
||||
info.graphics_memory_area = graphicsMapper.Map("intel extreme graphics memory",
|
||||
(void *)info.pci->u.h0.base_registers[fbIndex],
|
||||
totalSize, B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC,
|
||||
totalSize, B_ANY_KERNEL_BLOCK_ADDRESS /*| B_MTR_WC*/,
|
||||
B_READ_AREA | B_WRITE_AREA, (void **)&info.graphics_memory);
|
||||
if (graphicsMapper.InitCheck() < B_OK) {
|
||||
// try again without write combining
|
||||
@ -386,26 +431,33 @@ intel_extreme_init(intel_info &info)
|
||||
|
||||
// init graphics memory manager
|
||||
|
||||
info.memory_manager = mem_init("intel extreme memory manager", 0, totalSize, 1024,
|
||||
min_c(totalSize / 1024, 512));
|
||||
if (info.memory_manager == NULL)
|
||||
return B_NO_MEMORY;
|
||||
AreaKeeper gttMapper;
|
||||
info.gtt_area = -1;
|
||||
|
||||
if ((info.device_type & INTEL_TYPE_9xx) != 0) {
|
||||
if ((info.device_type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_965) {
|
||||
info.gtt_base = info.registers + i965_GTT_BASE;
|
||||
info.gtt_size = i965_GTT_SIZE;
|
||||
} else {
|
||||
// TODO: map it in???
|
||||
info.gtt_base = (uint8*)info.pci->u.h0.base_register_sizes[3];
|
||||
info.gtt_size = i830_GTT_SIZE;
|
||||
// TODO: for now...
|
||||
info.gtt_area = gttMapper.Map("intel extreme gtt",
|
||||
(void *)info.pci->u.h0.base_registers[3], totalSize / 1024,
|
||||
B_ANY_KERNEL_ADDRESS, 0, (void **)&info.gtt_base);
|
||||
if (gttMapper.InitCheck() < B_OK) {
|
||||
dprintf(DEVICE_NAME ": could not map GTT area!\n");
|
||||
return info.gtt_area;
|
||||
}
|
||||
info.gtt_size = totalSize / 1024;
|
||||
}
|
||||
} else {
|
||||
info.gtt_base = info.registers + i830_GTT_BASE;
|
||||
info.gtt_size = i830_GTT_SIZE;
|
||||
}
|
||||
|
||||
info.memory_manager = mem_init("intel extreme memory manager", 0, totalSize, 1024,
|
||||
min_c(totalSize / 1024, 512));
|
||||
if (info.memory_manager == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// reserve ring buffer memory (currently, this memory is placed in
|
||||
// the graphics memory), but this could bring us problems with
|
||||
// write combining...
|
||||
@ -426,11 +478,23 @@ intel_extreme_init(intel_info &info)
|
||||
secondary.base = info.graphics_memory + secondary.offset;
|
||||
}
|
||||
|
||||
// Fix some problems on certain chips (taken from X driver)
|
||||
// TODO: clean this up
|
||||
if (info.pci->device_id == 0x2a02 || info.pci->device_id == 0x2a12) {
|
||||
dprintf("i965GM/i965GME quirk\n");
|
||||
write32(info.registers + 0x6204, (1L << 29));
|
||||
} else {
|
||||
dprintf("i965 quirk\n");
|
||||
write32(info.registers + 0x6204, (1L << 29) | (1L << 23));
|
||||
}
|
||||
write32(info.registers + 0x7408, 0x10);
|
||||
|
||||
// no errors, so keep areas and mappings
|
||||
sharedCreator.Detach();
|
||||
additionalMemoryCreator.Detach();
|
||||
graphicsMapper.Detach();
|
||||
mmioMapper.Detach();
|
||||
gttMapper.Detach();
|
||||
|
||||
info.shared_info->graphics_memory_area = info.graphics_memory_area;
|
||||
info.shared_info->registers_area = info.registers_area;
|
||||
@ -463,8 +527,17 @@ intel_extreme_init(intel_info &info)
|
||||
|
||||
// setup overlay registers
|
||||
|
||||
info.overlay_registers = (overlay_registers *)((uint8 *)info.shared_info
|
||||
+ ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)));
|
||||
if (info.device_type == (INTEL_TYPE_9xx | INTEL_TYPE_G33)) {
|
||||
if (mem_alloc(info.memory_manager, B_PAGE_SIZE, &info,
|
||||
&info.overlay_handle, &info.overlay_offset) == B_OK) {
|
||||
info.overlay_registers = (overlay_registers *)(info.graphics_memory
|
||||
+ info.overlay_offset);
|
||||
info.shared_info->overlay_offset = info.overlay_offset;
|
||||
}
|
||||
} else {
|
||||
info.overlay_registers = (overlay_registers *)((uint8 *)info.shared_info
|
||||
+ ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)));
|
||||
}
|
||||
init_overlay_registers(info.overlay_registers);
|
||||
|
||||
physical_entry physicalEntry;
|
||||
@ -474,12 +547,11 @@ intel_extreme_init(intel_info &info)
|
||||
// The hardware status page and the cursor memory share one area with
|
||||
// the overlay registers and the shared info
|
||||
|
||||
get_memory_map((uint8 *)info.overlay_registers + B_PAGE_SIZE,
|
||||
B_PAGE_SIZE, &physicalEntry, 1);
|
||||
uint8 *base = (uint8 *)info.shared_info + ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info));
|
||||
get_memory_map(base + B_PAGE_SIZE, B_PAGE_SIZE, &physicalEntry, 1);
|
||||
info.shared_info->physical_status_page = (uint8 *)physicalEntry.address;
|
||||
|
||||
get_memory_map((uint8 *)info.overlay_registers + 2 * B_PAGE_SIZE,
|
||||
B_PAGE_SIZE, &physicalEntry, 1);
|
||||
get_memory_map(base + 2 * B_PAGE_SIZE, B_PAGE_SIZE, &physicalEntry, 1);
|
||||
info.shared_info->physical_cursor_memory = (uint8 *)physicalEntry.address;
|
||||
|
||||
// setup the GTT to point to include the additional memory
|
||||
@ -537,6 +609,7 @@ intel_extreme_uninit(intel_info &info)
|
||||
mem_destroy(info.memory_manager);
|
||||
|
||||
delete_area(info.graphics_memory_area);
|
||||
delete_area(info.gtt_area);
|
||||
delete_area(info.registers_area);
|
||||
delete_area(info.shared_area);
|
||||
|
||||
|
@ -26,11 +26,14 @@ struct intel_info {
|
||||
struct intel_shared_info *shared_info;
|
||||
area_id shared_area;
|
||||
|
||||
uint32 overlay_handle;
|
||||
uint32 overlay_offset;
|
||||
struct overlay_registers *overlay_registers;
|
||||
// update buffer, shares an area with shared_info
|
||||
|
||||
uint8 *gtt_base;
|
||||
size_t gtt_size;
|
||||
area_id gtt_area;
|
||||
uint8 *graphics_memory;
|
||||
area_id graphics_memory_area;
|
||||
area_id additional_memory_area;
|
||||
|
Loading…
Reference in New Issue
Block a user