More SandyBridge specifics: Use the proper registers for display detection and
DPMS. Still needs to be reworked... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42846 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -227,6 +227,8 @@ struct intel_free_graphics_memory {
|
||||
// up, SandyBridge, etc.).
|
||||
#define PCH_DE_INTERRUPT_ENABLE 0x4400c // INTEL_INTERRUPT_ENABLED
|
||||
#define PCH_DISPLAY_A_ANALOG_PORT 0xe1100 // INTEL_DISPLAY_A_ANALOG_PORT
|
||||
#define PCH_DISPLAY_A_DIGITAL_PORT 0xe1120 // INTEL_DISPLAY_A_DIGITAL_PORT
|
||||
#define PCH_DISPLAY_B_DIGITAL_PORT 0xe1140 // INTEL_DISPLAY_B_DIGITAL_PORT
|
||||
#define PCH_DISPLAY_LVDS_PORT 0xe1180 // INTEL_DISPLAY_LVDS_PORT
|
||||
#define PCH_I2C_IO_A 0xc5010 // INTEL_I2C_IO_A
|
||||
#define PCH_I2C_IO_C 0xc5018 // INTEL_I2C_IO_C
|
||||
@@ -249,6 +251,9 @@ struct intel_free_graphics_memory {
|
||||
#define PCH_TRANSCODER_B_VBLANK 0xe1010 // INTEL_DISPLAY_B_VBLANK
|
||||
#define PCH_TRANSCODER_B_VSYNC 0xe1014 // INTEL_DISPLAY_B_VSYNC
|
||||
|
||||
#define PCH_LVDS_DETECTED (1 << 1)
|
||||
|
||||
|
||||
// SandyBridge (SNB)
|
||||
#define SNB_GRAPHICS_MEMORY_CONTROL 0x50
|
||||
|
||||
@@ -387,6 +392,8 @@ struct intel_free_graphics_memory {
|
||||
#define INTEL_DISPLAY_A_CONTROL 0x70180
|
||||
#define INTEL_DISPLAY_A_BASE 0x70184
|
||||
#define INTEL_DISPLAY_A_BYTES_PER_ROW 0x70188
|
||||
#define INTEL_DISPLAY_A_POS 0x7018c // reserved
|
||||
#define INTEL_DISPLAY_A_PIPE_SIZE 0x70190
|
||||
#define INTEL_DISPLAY_A_SURFACE 0x7019c // i965 and up only
|
||||
#define DISPLAY_CONTROL_ENABLED (1UL << 31)
|
||||
#define DISPLAY_CONTROL_GAMMA (1UL << 30)
|
||||
@@ -408,6 +415,7 @@ struct intel_free_graphics_memory {
|
||||
#define DISPLAY_PIPE_VBLANK_STATUS (1UL << 1)
|
||||
|
||||
#define INTEL_DISPLAY_A_PLL 0x06014
|
||||
#define INTEL_DISPLAY_A_PLL_MULTIPLIER_DIVISOR 0x0601c
|
||||
#define INTEL_DISPLAY_A_PLL_DIVISOR_0 0x06040
|
||||
#define INTEL_DISPLAY_A_PLL_DIVISOR_1 0x06044
|
||||
|
||||
@@ -428,7 +436,7 @@ struct intel_free_graphics_memory {
|
||||
#define INTEL_DISPLAY_B_CONTROL 0x71180
|
||||
#define INTEL_DISPLAY_B_BASE 0x71184
|
||||
#define INTEL_DISPLAY_B_BYTES_PER_ROW 0x71188
|
||||
#define INTEL_DISPLAY_B_POS 0x7118C
|
||||
#define INTEL_DISPLAY_B_POS 0x7118c
|
||||
|
||||
#define INTEL_DISPLAY_B_IMAGE_SIZE 0x6101c
|
||||
#define INTEL_DISPLAY_B_SURFACE 0x7119c // i965 and up only
|
||||
|
||||
@@ -203,22 +203,27 @@ intel_init_accelerant(int device)
|
||||
if (read32(INTEL_DISPLAY_A_PIPE_CONTROL) & DISPLAY_PIPE_ENABLED)
|
||||
gInfo->head_mode |= HEAD_MODE_A_ANALOG;
|
||||
|
||||
uint32 lvds = read32(INTEL_DISPLAY_LVDS_PORT);
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
int lvdsRegister = isSNB ? PCH_DISPLAY_LVDS_PORT : INTEL_DISPLAY_LVDS_PORT;
|
||||
uint32 lvds = read32(lvdsRegister);
|
||||
|
||||
// If we have an enabled display pipe we save the passed information and
|
||||
// assume it is the valid panel size..
|
||||
// Later we query for proper EDID info if it exists, or figure something
|
||||
// else out. (Default modes, etc.)
|
||||
if ((lvds & DISPLAY_PIPE_ENABLED) != 0) {
|
||||
if ((isSNB && (lvds & PCH_LVDS_DETECTED) != 0)
|
||||
|| (!isSNB && (lvds & DISPLAY_PIPE_ENABLED) != 0)) {
|
||||
save_lvds_mode();
|
||||
gInfo->head_mode |= HEAD_MODE_LVDS_PANEL;
|
||||
}
|
||||
|
||||
TRACE(("head detected: %#x\n", gInfo->head_mode));
|
||||
TRACE(("adpa: %08lx, dova: %08lx, dovb: %08lx, lvds: %08lx\n",
|
||||
read32(INTEL_DISPLAY_A_ANALOG_PORT),
|
||||
read32(INTEL_DISPLAY_A_DIGITAL_PORT),
|
||||
read32(INTEL_DISPLAY_B_DIGITAL_PORT), read32(INTEL_DISPLAY_LVDS_PORT)));
|
||||
read32(isSNB ? PCH_DISPLAY_A_ANALOG_PORT : INTEL_DISPLAY_A_ANALOG_PORT),
|
||||
read32(isSNB ? PCH_DISPLAY_A_DIGITAL_PORT
|
||||
: INTEL_DISPLAY_A_DIGITAL_PORT),
|
||||
read32(isSNB ? PCH_DISPLAY_B_DIGITAL_PORT
|
||||
: INTEL_DISPLAY_B_DIGITAL_PORT), read32(lvdsRegister)));
|
||||
|
||||
status = create_mode_list();
|
||||
if (status != B_OK) {
|
||||
|
||||
@@ -104,32 +104,35 @@ set_display_power_mode(uint32 mode)
|
||||
{
|
||||
uint32 monitorMode = 0;
|
||||
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
if (mode == B_DPMS_ON) {
|
||||
uint32 pll = read32(INTEL_DISPLAY_A_PLL);
|
||||
int targetRegister = isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL;
|
||||
uint32 pll = read32(targetRegister);
|
||||
if ((pll & DISPLAY_PLL_ENABLED) == 0) {
|
||||
// reactivate PLL
|
||||
write32(INTEL_DISPLAY_A_PLL, pll);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
write32(targetRegister, pll);
|
||||
read32(targetRegister);
|
||||
spin(150);
|
||||
write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(150);
|
||||
write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(150);
|
||||
}
|
||||
|
||||
pll = read32(INTEL_DISPLAY_B_PLL);
|
||||
targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL;
|
||||
pll = read32(targetRegister);
|
||||
if ((pll & DISPLAY_PLL_ENABLED) == 0) {
|
||||
// reactivate PLL
|
||||
write32(INTEL_DISPLAY_B_PLL, pll);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
write32(targetRegister, pll);
|
||||
read32(targetRegister);
|
||||
spin(150);
|
||||
write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(150);
|
||||
write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(150);
|
||||
}
|
||||
|
||||
@@ -155,12 +158,16 @@ set_display_power_mode(uint32 mode)
|
||||
}
|
||||
|
||||
if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
|
||||
write32(INTEL_DISPLAY_A_ANALOG_PORT, (read32(INTEL_DISPLAY_A_ANALOG_PORT)
|
||||
int targetRegister
|
||||
= isSNB ? PCH_DISPLAY_A_ANALOG_PORT : INTEL_DISPLAY_A_ANALOG_PORT;
|
||||
write32(targetRegister, (read32(targetRegister)
|
||||
& ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED))
|
||||
| monitorMode | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0));
|
||||
}
|
||||
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
|
||||
write32(INTEL_DISPLAY_B_DIGITAL_PORT, (read32(INTEL_DISPLAY_B_DIGITAL_PORT)
|
||||
int targetRegister
|
||||
= isSNB ? PCH_DISPLAY_B_DIGITAL_PORT : INTEL_DISPLAY_B_DIGITAL_PORT;
|
||||
write32(targetRegister, (read32(targetRegister)
|
||||
& ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED))
|
||||
| (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0));
|
||||
// TODO: monitorMode?
|
||||
@@ -173,18 +180,21 @@ set_display_power_mode(uint32 mode)
|
||||
}
|
||||
|
||||
if (mode == B_DPMS_OFF) {
|
||||
write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL)
|
||||
int targetRegister = isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL;
|
||||
write32(targetRegister, read32(targetRegister)
|
||||
| DISPLAY_PLL_ENABLED);
|
||||
write32(INTEL_DISPLAY_B_PLL, read32(INTEL_DISPLAY_B_PLL)
|
||||
targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL;
|
||||
write32(targetRegister, read32(targetRegister)
|
||||
| DISPLAY_PLL_ENABLED);
|
||||
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
// flush the eventually cached PCI bus writes
|
||||
read32(targetRegister);
|
||||
// flush the possibly cached PCI bus writes
|
||||
|
||||
spin(150);
|
||||
}
|
||||
|
||||
if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0)
|
||||
// TODO: fix for SNB
|
||||
if (!isSNB && (gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0)
|
||||
enable_lvds_panel(mode == B_DPMS_ON);
|
||||
|
||||
read32(INTEL_DISPLAY_A_BASE);
|
||||
|
||||
Reference in New Issue
Block a user