* added support for GM45 (might work for other chips in the G4 series)
* added header for dealing with binary numbers and bitmasks (C++ templates) these "macro's" might not work well for long words, though git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33749 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
bd56fd8a4c
commit
dfdfbd3eef
|
@ -9,6 +9,7 @@
|
|||
#define INTEL_EXTREME_H
|
||||
|
||||
|
||||
#include "binary-utils.h"
|
||||
#include "lock.h"
|
||||
|
||||
#include <Accelerant.h>
|
||||
|
@ -32,6 +33,7 @@
|
|||
#define INTEL_TYPE_94x (INTEL_TYPE_9xx | 0x0080)
|
||||
#define INTEL_TYPE_96x (INTEL_TYPE_9xx | 0x0100)
|
||||
#define INTEL_TYPE_Gxx (INTEL_TYPE_9xx | 0x0200)
|
||||
#define INTEL_TYPE_G4x (INTEL_TYPE_9xx | 0x0400)
|
||||
// models
|
||||
#define INTEL_TYPE_MOBILE 0x0008
|
||||
#define INTEL_TYPE_915 (INTEL_TYPE_91x)
|
||||
|
@ -40,6 +42,8 @@
|
|||
#define INTEL_TYPE_965 (INTEL_TYPE_96x)
|
||||
#define INTEL_TYPE_965M (INTEL_TYPE_96x | INTEL_TYPE_MOBILE)
|
||||
#define INTEL_TYPE_G33 (INTEL_TYPE_Gxx)
|
||||
#define INTEL_TYPE_G45 (INTEL_TYPE_G4x)
|
||||
#define INTEL_TYPE_GM45 (INTEL_TYPE_G4x | INTEL_TYPE_MOBILE)
|
||||
|
||||
#define DEVICE_NAME "intel_extreme"
|
||||
#define INTEL_ACCELERANT_NAME "intel_extreme.accelerant"
|
||||
|
@ -179,13 +183,33 @@ struct intel_free_graphics_memory {
|
|||
// Register definitions, taken from X driver
|
||||
|
||||
// PCI bridge memory management
|
||||
#define INTEL_GRAPHICS_MEMORY_CONTROL 0x52
|
||||
#define INTEL_GRAPHICS_MEMORY_CONTROL 0x52 // GGC - (G)MCH Graphics Control Register
|
||||
#define MEMORY_CONTROL_ENABLED 0x0004
|
||||
#define MEMORY_MASK 0x0001
|
||||
#define STOLEN_MEMORY_MASK 0x0070
|
||||
#define i965_GTT_MASK 0x000e
|
||||
#define G33_GTT_MASK 0x0300
|
||||
|
||||
#define G4X_GGC_GGMS_MASK BITMASK(11,8)
|
||||
#define G4X_GGC_GMS_MASK BITMASK(7,4) // also for G33, but
|
||||
// probably not for
|
||||
// older chips
|
||||
#define G4X_GGMS_NONE (BINARY(0000) << 8)
|
||||
#define G4X_GGMS_NO_IVT_1M (BINARY(0001) << 8)
|
||||
#define G4X_GGMS_NO_IVT_2M (BINARY(0011) << 8)
|
||||
#define G4X_GGMS_IVT_2M (BINARY(1001) << 8)
|
||||
#define G4X_GGMS_IVT_3M (BINARY(1010) << 8)
|
||||
#define G4X_GGMS_IVT_4M (BINARY(1011) << 8)
|
||||
|
||||
#define G4X_GMS_32MB (BINARY(0101) << 4)
|
||||
#define G4X_GMS_64MB (BINARY(0111) << 4)
|
||||
#define G4X_GMS_128MB (BINARY(1000) << 4)
|
||||
#define G4X_GMS_256MB (BINARY(1001) << 4)
|
||||
#define G4X_GMS_96MB (BINARY(1010) << 4)
|
||||
#define G4X_GMS_160MB (BINARY(1011) << 4)
|
||||
#define G4X_GMS_224MB (BINARY(1100) << 4)
|
||||
#define G4X_GMS_352MB (BINARY(1101) << 4)
|
||||
|
||||
// models i830 and up
|
||||
#define i830_LOCAL_MEMORY_ONLY 0x10
|
||||
#define i830_STOLEN_512K 0x20
|
||||
|
@ -220,6 +244,24 @@ struct intel_free_graphics_memory {
|
|||
#define i965_GTT_512K (0 << 1)
|
||||
#define G33_GTT_1M (1 << 8)
|
||||
#define G33_GTT_2M (2 << 8)
|
||||
|
||||
#define G4X_GTTMMADR 0x10
|
||||
#define G4X_GTTMMADR_MBA_MASK BITMASK(35,22)
|
||||
#define G4X_GTTMMADR_MT_MASK BITMASK(2,2)
|
||||
#define G4X_MMIO_SIZE (512ULL << 10)
|
||||
|
||||
#define G4X_GMADR 0x18
|
||||
#define G4X_GMADR_MBA_512MB_MASK BITMASK(35,29)
|
||||
#define G4X_GMADR_MBA_256MB_MASK BITMASK(35,28)
|
||||
#define G4X_GMADR_AM_512MB_MASK BITMASK(28,4)
|
||||
#define G4X_GMADR_AM_256MB_MASK BITMASK(27,4)
|
||||
#define G4X_GMADR_MT_MASK BITMASK(2,2)
|
||||
|
||||
#define G4X_MSAC 0x66
|
||||
#define G4X_MSAC_LHSAS_MASK BITMASK(2,1)
|
||||
#define G4X_LHSAS_512MB (BINARY(11) << 1)
|
||||
#define G4X_LHSAS_256MB (BINARY(01) << 1)
|
||||
|
||||
#define GTT_ENTRY_VALID 0x01
|
||||
#define GTT_ENTRY_LOCAL_MEMORY 0x02
|
||||
#define GTT_PAGE_SHIFT 12
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Brecht Machiels, brecht@mos6581.org
|
||||
*/
|
||||
|
||||
#ifndef _BINARY_UTILS_H
|
||||
#define _BINARY_UTILS_H
|
||||
|
||||
|
||||
/* macro for a one-bit bitmask
|
||||
*/
|
||||
|
||||
#define BIT(n) (1ULL << n)
|
||||
|
||||
/* macro/templates to create bitmasks
|
||||
*/
|
||||
|
||||
#define BITMASK(high, low) ((unsigned long long)(BitMask<high, low>::value))
|
||||
|
||||
template<int h, int l>
|
||||
struct BitMask
|
||||
{
|
||||
enum { value = (BitMask<h-l-1,0>::value +
|
||||
(1ULL << h - l)) << l };
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct BitMask<-1,0>
|
||||
{
|
||||
enum { value = 0ULL };
|
||||
};
|
||||
|
||||
|
||||
/* macro/templates to enter binary constants
|
||||
*/
|
||||
|
||||
#define BINARY(binstring) ((unsigned long long)(Binary<0##binstring>::value))
|
||||
|
||||
// http://www.eptacom.net/pubblicazioni/pub_eng/binary.html
|
||||
template<const unsigned long long N> struct Binary
|
||||
{
|
||||
enum { value = (N % 8ULL) + 2ULL * Binary<N / 8ULL>::value };
|
||||
};
|
||||
|
||||
|
||||
struct Binary<0>
|
||||
{
|
||||
enum { value = 0ULL } ;
|
||||
};
|
||||
|
||||
|
||||
/* macro/templates to determine offset
|
||||
|
||||
NOTE: broken for high bit indices
|
||||
*/
|
||||
|
||||
#define MASKOFFSET(mask) (MaskOffset<mask, (mask & 1UL)>::count)
|
||||
|
||||
template<const unsigned long mask, unsigned int firstBit>
|
||||
struct MaskOffset
|
||||
{
|
||||
enum { count = MaskOffset<(mask >> 1), ((mask >> 1) & 1UL)>::count + 1 };
|
||||
};
|
||||
|
||||
|
||||
template<const unsigned long mask>
|
||||
struct MaskOffset<mask, 1>
|
||||
{
|
||||
enum { count = 0 };
|
||||
};
|
||||
|
||||
#endif // _BINARY_UTILS_H
|
||||
|
|
@ -5,6 +5,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
|
|||
UsePrivateHeaders graphics ;
|
||||
UsePrivateHeaders [ FDirName graphics intel_extreme ] ;
|
||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
Addon intel_extreme.accelerant :
|
||||
accelerant.cpp
|
||||
|
|
|
@ -130,7 +130,8 @@ set_frame_buffer_base()
|
|||
surfaceRegister = INTEL_DISPLAY_B_SURFACE;
|
||||
}
|
||||
|
||||
if (sharedInfo.device_type.InGroup(INTEL_TYPE_96x)) {
|
||||
if (sharedInfo.device_type.InGroup(INTEL_TYPE_96x)
|
||||
|| sharedInfo.device_type.InGroup(INTEL_TYPE_G4x)) {
|
||||
write32(baseRegister, mode.v_display_start * sharedInfo.bytes_per_row
|
||||
+ mode.h_display_start * (sharedInfo.bits_per_pixel + 7) / 8);
|
||||
read32(baseRegister);
|
||||
|
@ -217,7 +218,17 @@ get_pll_limits(pll_limits &limits)
|
|||
// Note, the limits are taken from the X driver; they have not yet been
|
||||
// tested
|
||||
|
||||
if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_G4x)) {
|
||||
// single LVDS output
|
||||
// NOTE: not sure these will work with CRT displays
|
||||
static const pll_limits kLimits = {
|
||||
// p, p1, p2, high, n, m, m1, m2
|
||||
{ 28, 2, 14, false, 1, 104, 17, 5}, // min
|
||||
{112, 8, 0, true, 3, 138, 23, 11}, // max
|
||||
200000, 1750000, 3500000
|
||||
};
|
||||
limits = kLimits;
|
||||
} else if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
|
||||
// TODO: support LVDS output limits as well
|
||||
// (Update: Output limits are adjusted in the computation (post2=7/14))
|
||||
// Should move them here!
|
||||
|
|
|
@ -7,6 +7,7 @@ UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ;
|
|||
UsePrivateHeaders [ FDirName graphics intel_extreme ] ;
|
||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
UsePrivateHeaders drivers graphics kernel ;
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
KernelAddon <agp_gart>intel :
|
||||
intel_gart.cpp
|
||||
|
|
|
@ -68,6 +68,8 @@ const struct supported_device {
|
|||
{0x29b0, 0x29b2, INTEL_TYPE_G33, "G33"},
|
||||
{0x29c0, 0x29c2, INTEL_TYPE_G33, "Q35"},
|
||||
{0x29d0, 0x29d2, INTEL_TYPE_G33, "Q33"},
|
||||
|
||||
{0x2a40, 0x2a42, INTEL_TYPE_GM45, "GM45"},
|
||||
};
|
||||
|
||||
struct intel_info {
|
||||
|
@ -146,6 +148,27 @@ determine_memory_sizes(intel_info &info, size_t >tSize, size_t &stolenSize)
|
|||
gttSize = 2 << 20;
|
||||
break;
|
||||
}
|
||||
} else if ((info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_G4x) {
|
||||
switch (memoryConfig & G4X_GGC_GGMS_MASK) {
|
||||
case G4X_GGMS_NONE:
|
||||
gttSize = 0;
|
||||
break;
|
||||
case G4X_GGMS_NO_IVT_1M:
|
||||
gttSize = 1 << 20;
|
||||
break;
|
||||
case G4X_GGMS_NO_IVT_2M:
|
||||
gttSize = 2 << 20;
|
||||
break;
|
||||
case G4X_GGMS_IVT_2M:
|
||||
gttSize = 2 << 20;
|
||||
break;
|
||||
case G4X_GGMS_IVT_3M:
|
||||
gttSize = 3 << 20;
|
||||
break;
|
||||
case G4X_GGMS_IVT_4M:
|
||||
gttSize = 4 << 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
|
||||
|
@ -159,12 +182,14 @@ determine_memory_sizes(intel_info &info, size_t >tSize, size_t &stolenSize)
|
|||
} else if ((info.type & INTEL_TYPE_9xx) != 0)
|
||||
frameBufferSize = info.display.u.h0.base_register_sizes[2];
|
||||
|
||||
TRACE(("frame buffer size %lu MB\n", frameBufferSize >> 20));
|
||||
gttSize = frameBufferSize / 1024;
|
||||
}
|
||||
|
||||
// TODO: test with different models!
|
||||
|
||||
if (info.type == INTEL_TYPE_83x) {
|
||||
// Older chips
|
||||
switch (memoryConfig & STOLEN_MEMORY_MASK) {
|
||||
case i830_LOCAL_MEMORY_ONLY:
|
||||
// TODO: determine its size!
|
||||
|
@ -173,12 +198,42 @@ determine_memory_sizes(intel_info &info, size_t >tSize, size_t &stolenSize)
|
|||
case i830_STOLEN_512K:
|
||||
memorySize >>= 1;
|
||||
break;
|
||||
case i830_STOLEN_1M:
|
||||
// default case
|
||||
break;
|
||||
case i830_STOLEN_8M:
|
||||
memorySize *= 8;
|
||||
break;
|
||||
}
|
||||
} else if (info.type == INTEL_TYPE_G4x) {
|
||||
switch (memoryConfig & G4X_GGC_GMS_MASK) {
|
||||
case G4X_GMS_32MB:
|
||||
memorySize *= 32;
|
||||
break;
|
||||
case G4X_GMS_64MB:
|
||||
memorySize *= 64;
|
||||
break;
|
||||
case G4X_GMS_128MB:
|
||||
memorySize *= 128;
|
||||
break;
|
||||
case G4X_GMS_256MB:
|
||||
memorySize *= 256;
|
||||
break;
|
||||
case G4X_GMS_96MB:
|
||||
memorySize *= 96;
|
||||
break;
|
||||
case G4X_GMS_160MB:
|
||||
memorySize *= 160;
|
||||
break;
|
||||
case G4X_GMS_224MB:
|
||||
memorySize *= 224;
|
||||
break;
|
||||
case G4X_GMS_352MB:
|
||||
memorySize *= 352;
|
||||
break;
|
||||
}
|
||||
} else if (info.type == INTEL_TYPE_85x
|
||||
|| (info.type & INTEL_TYPE_9xx) != 0) {
|
||||
|| (info.type & INTEL_TYPE_9xx) == INTEL_TYPE_9xx) {
|
||||
switch (memoryConfig & STOLEN_MEMORY_MASK) {
|
||||
case i855_STOLEN_MEMORY_4M:
|
||||
memorySize *= 4;
|
||||
|
@ -205,6 +260,9 @@ determine_memory_sizes(intel_info &info, size_t >tSize, size_t &stolenSize)
|
|||
memorySize *= 256;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// TODO: error out!
|
||||
memorySize = 4096;
|
||||
}
|
||||
|
||||
stolenSize = memorySize - 4096;
|
||||
|
@ -241,7 +299,7 @@ intel_map(intel_info &info)
|
|||
mmioIndex = 0;
|
||||
fbIndex = 2;
|
||||
}
|
||||
|
||||
|
||||
AreaKeeper mmioMapper;
|
||||
info.registers_area = mmioMapper.Map("intel GMCH mmio",
|
||||
(void *)info.display.u.h0.base_registers[mmioIndex],
|
||||
|
@ -271,7 +329,10 @@ intel_map(intel_info &info)
|
|||
if (get_memory_map(scratchAddress, B_PAGE_SIZE, &entry, 1) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if ((info.type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx)
|
||||
if ((info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_G4x)
|
||||
info.gtt_physical_base = info.display.u.h0.base_registers[mmioIndex]
|
||||
+ (2UL << 20);
|
||||
else if ((info.type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx)
|
||||
info.gtt_physical_base = get_pci_config(info.display, i915_GTT_BASE, 4);
|
||||
else {
|
||||
info.gtt_physical_base = read32(info.registers
|
||||
|
@ -307,11 +368,15 @@ intel_map(intel_info &info)
|
|||
info.aperture_stolen_size = stolenSize;
|
||||
if (info.aperture_size == 0)
|
||||
info.aperture_size = info.display.u.h0.base_register_sizes[fbIndex];
|
||||
|
||||
|
||||
dprintf("intel_gart: detected %ld MB of stolen memory, aperture "
|
||||
"size %ld MB, GTT size %ld KB\n", (stolenSize + (1023 << 10)) >> 20,
|
||||
info.aperture_size >> 20, gttSize >> 10);
|
||||
|
||||
dprintf("intel_gart: GTT base = 0x%lx\n", info.gtt_physical_base);
|
||||
dprintf("intel_gart: MMIO base = 0x%lx\n", info.display.u.h0.base_registers[mmioIndex]);
|
||||
dprintf("intel_gart: GMR base = 0x%lx\n", info.aperture_physical_base);
|
||||
|
||||
AreaKeeper apertureMapper;
|
||||
info.aperture_area = apertureMapper.Map("intel graphics aperture",
|
||||
(void *)info.aperture_physical_base, info.aperture_size,
|
||||
|
|
|
@ -5,6 +5,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
|
|||
UsePrivateHeaders [ FDirName graphics intel_extreme ] ;
|
||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
UsePrivateHeaders graphics kernel ;
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
KernelAddon intel_extreme :
|
||||
driver.cpp
|
||||
|
|
|
@ -54,6 +54,7 @@ const struct supported_device {
|
|||
{0x29b2, INTEL_TYPE_G33, "G33G"},
|
||||
{0x29c2, INTEL_TYPE_G33, "Q35G"},
|
||||
{0x29d2, INTEL_TYPE_G33, "Q33G"},
|
||||
{0x2a42, INTEL_TYPE_GM45, "GM45"},
|
||||
};
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
|
|
@ -238,11 +238,25 @@ intel_extreme_init(intel_info &info)
|
|||
primary.offset = (addr_t)primary.base - info.aperture_base;
|
||||
}
|
||||
|
||||
// Clock gating
|
||||
// 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 if (info.device_type.InGroup(INTEL_TYPE_G4x)) {
|
||||
dprintf("G4x clock gating\n");
|
||||
write32(info.registers + 0x6204, 0);
|
||||
write32(info.registers + 0x6208, BIT(9) | BIT(7) | BIT(6));
|
||||
write32(info.registers + 0x6210, 0);
|
||||
|
||||
uint32 dspclk_gate_val = BIT(28) | BIT(3) | BIT(2);
|
||||
if ((info.device_type.type & INTEL_TYPE_MOBILE) == INTEL_TYPE_MOBILE) {
|
||||
dprintf("G4x mobile clock gating\n");
|
||||
dspclk_gate_val |= BIT(18);
|
||||
}
|
||||
write32(info.registers + 0x6200, dspclk_gate_val) ;
|
||||
|
||||
} else {
|
||||
dprintf("i965 quirk\n");
|
||||
write32(info.registers + 0x6204, (1L << 29) | (1L << 23));
|
||||
|
|
Loading…
Reference in New Issue