* Rework how registers are accessed. Most registers are now grouped into
register blocks and we encode their block into the register definition. On register access these blocks are then translated into the final address. * Set up the register blocks for (G)MCH and PCH variants. * Remove most SandyBridge code that was actually PCH specific and is now taken care of automatically. * This will temporarily break SandyBridge support again until the right transcoders are actually programmed. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42857 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -123,7 +123,7 @@ init_common(int device, bool isClone)
|
||||
|
||||
AreaCloner regsCloner;
|
||||
gInfo->regs_area = regsCloner.Clone("intel extreme regs",
|
||||
(void **)&gInfo->regs, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA,
|
||||
(void **)&gInfo->registers, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA,
|
||||
gInfo->shared_info->registers_area);
|
||||
status = regsCloner.InitCheck();
|
||||
if (status < B_OK) {
|
||||
@@ -203,14 +203,13 @@ intel_init_accelerant(int device)
|
||||
if (read32(INTEL_DISPLAY_A_PIPE_CONTROL) & DISPLAY_PIPE_ENABLED)
|
||||
gInfo->head_mode |= HEAD_MODE_A_ANALOG;
|
||||
|
||||
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);
|
||||
uint32 lvds = read32(INTEL_DISPLAY_LVDS_PORT);
|
||||
|
||||
// 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.)
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
if ((isSNB && (lvds & PCH_LVDS_DETECTED) != 0)
|
||||
|| (!isSNB && (lvds & DISPLAY_PIPE_ENABLED) != 0)) {
|
||||
save_lvds_mode();
|
||||
@@ -219,11 +218,9 @@ intel_init_accelerant(int device)
|
||||
|
||||
TRACE(("head detected: %#x\n", gInfo->head_mode));
|
||||
TRACE(("adpa: %08lx, dova: %08lx, dovb: %08lx, lvds: %08lx\n",
|
||||
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)));
|
||||
read32(INTEL_DISPLAY_A_ANALOG_PORT),
|
||||
read32(INTEL_DISPLAY_A_DIGITAL_PORT),
|
||||
read32(INTEL_DISPLAY_B_DIGITAL_PORT), read32(INTEL_DISPLAY_LVDS_PORT)));
|
||||
|
||||
status = create_mode_list();
|
||||
if (status != B_OK) {
|
||||
|
||||
@@ -31,7 +31,7 @@ struct overlay_frame {
|
||||
};
|
||||
|
||||
struct accelerant_info {
|
||||
vuint8 *regs;
|
||||
uint8 *registers;
|
||||
area_id regs_area;
|
||||
|
||||
intel_shared_info *shared_info;
|
||||
@@ -74,15 +74,19 @@ extern accelerant_info *gInfo;
|
||||
// register access
|
||||
|
||||
inline uint32
|
||||
read32(uint32 offset)
|
||||
read32(uint32 encodedRegister)
|
||||
{
|
||||
return *(volatile uint32 *)(gInfo->regs + offset);
|
||||
return *(volatile uint32 *)(gInfo->registers
|
||||
+ gInfo->shared_info->register_blocks[REGISTER_BLOCK(encodedRegister)]
|
||||
+ REGISTER_REGISTER(encodedRegister));
|
||||
}
|
||||
|
||||
inline void
|
||||
write32(uint32 offset, uint32 value)
|
||||
write32(uint32 encodedRegister, uint32 value)
|
||||
{
|
||||
*(volatile uint32 *)(gInfo->regs + offset) = value;
|
||||
*(volatile uint32 *)(gInfo->registers
|
||||
+ gInfo->shared_info->register_blocks[REGISTER_BLOCK(encodedRegister)]
|
||||
+ REGISTER_REGISTER(encodedRegister)) = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -75,6 +75,11 @@ static void
|
||||
enable_lvds_panel(bool enable)
|
||||
{
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
if (isSNB) {
|
||||
// TODO: fix for SNB
|
||||
return;
|
||||
}
|
||||
|
||||
int controlRegister = isSNB ? PCH_PANEL_CONTROL : INTEL_PANEL_CONTROL;
|
||||
int statusRegister = isSNB ? PCH_PANEL_STATUS : INTEL_PANEL_STATUS;
|
||||
|
||||
@@ -108,35 +113,32 @@ 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) {
|
||||
int targetRegister = isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL;
|
||||
uint32 pll = read32(targetRegister);
|
||||
uint32 pll = read32(INTEL_DISPLAY_A_PLL);
|
||||
if ((pll & DISPLAY_PLL_ENABLED) == 0) {
|
||||
// reactivate PLL
|
||||
write32(targetRegister, pll);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_A_PLL, pll);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
spin(150);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
spin(150);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
spin(150);
|
||||
}
|
||||
|
||||
targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL;
|
||||
pll = read32(targetRegister);
|
||||
pll = read32(INTEL_DISPLAY_B_PLL);
|
||||
if ((pll & DISPLAY_PLL_ENABLED) == 0) {
|
||||
// reactivate PLL
|
||||
write32(targetRegister, pll);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_B_PLL, pll);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
spin(150);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
spin(150);
|
||||
write32(targetRegister, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
spin(150);
|
||||
}
|
||||
|
||||
@@ -162,17 +164,15 @@ set_display_power_mode(uint32 mode)
|
||||
}
|
||||
|
||||
if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
|
||||
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))
|
||||
write32(INTEL_DISPLAY_A_ANALOG_PORT,
|
||||
(read32(INTEL_DISPLAY_A_ANALOG_PORT)
|
||||
& ~(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) {
|
||||
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))
|
||||
write32(INTEL_DISPLAY_B_DIGITAL_PORT,
|
||||
(read32(INTEL_DISPLAY_B_DIGITAL_PORT)
|
||||
& ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED))
|
||||
| (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0));
|
||||
// TODO: monitorMode?
|
||||
}
|
||||
@@ -184,25 +184,22 @@ set_display_power_mode(uint32 mode)
|
||||
}
|
||||
|
||||
if (mode == B_DPMS_OFF) {
|
||||
int targetRegister = isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL;
|
||||
write32(targetRegister, read32(targetRegister)
|
||||
write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL)
|
||||
| DISPLAY_PLL_ENABLED);
|
||||
targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL;
|
||||
write32(targetRegister, read32(targetRegister)
|
||||
write32(INTEL_DISPLAY_B_PLL, read32(INTEL_DISPLAY_B_PLL)
|
||||
| DISPLAY_PLL_ENABLED);
|
||||
|
||||
read32(targetRegister);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
// flush the possibly cached PCI bus writes
|
||||
|
||||
spin(150);
|
||||
}
|
||||
|
||||
// TODO: fix for SNB
|
||||
if (!isSNB && (gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0)
|
||||
if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0)
|
||||
enable_lvds_panel(mode == B_DPMS_ON);
|
||||
|
||||
read32(INTEL_DISPLAY_A_BASE);
|
||||
// flush the eventually cached PCI bus writes
|
||||
// flush the possibly cached PCI bus writes
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -154,10 +154,8 @@ set_frame_buffer_base()
|
||||
status_t
|
||||
create_mode_list(void)
|
||||
{
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
|
||||
i2c_bus bus;
|
||||
bus.cookie = (void*)(isSNB ? PCH_I2C_IO_A : INTEL_I2C_IO_A);
|
||||
bus.cookie = (void*)INTEL_I2C_IO_A;
|
||||
bus.set_signals = &set_i2c_signals;
|
||||
bus.get_signals = &get_i2c_signals;
|
||||
ddc2_init_timing(&bus);
|
||||
@@ -169,7 +167,7 @@ create_mode_list(void)
|
||||
} else {
|
||||
TRACE(("intel_extreme: getting EDID on port A (analog) failed : %s. "
|
||||
"Trying on port C (lvds)\n", strerror(error)));
|
||||
bus.cookie = (void*)(isSNB ? PCH_I2C_IO_C : INTEL_I2C_IO_C);
|
||||
bus.cookie = (void*)INTEL_I2C_IO_C;
|
||||
error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL);
|
||||
if (error == B_OK) {
|
||||
edid_dump(&gInfo->edid_info);
|
||||
@@ -324,12 +322,8 @@ compute_pll_divisors(const display_mode ¤t, pll_divisors& divisors,
|
||||
|
||||
TRACE(("required MHz: %g\n", requestedPixelClock));
|
||||
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
|
||||
if (isLVDS) {
|
||||
int targetRegister
|
||||
= isSNB ? PCH_DISPLAY_LVDS_PORT : INTEL_DISPLAY_LVDS_PORT;
|
||||
if ((read32(targetRegister) & LVDS_CLKB_POWER_MASK)
|
||||
if ((read32(INTEL_DISPLAY_LVDS_PORT) & LVDS_CLKB_POWER_MASK)
|
||||
== LVDS_CLKB_POWER_UP)
|
||||
divisors.post2 = LVDS_POST2_RATE_FAST;
|
||||
else
|
||||
@@ -418,26 +412,6 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister)
|
||||
vSyncRegister = INTEL_DISPLAY_B_VSYNC;
|
||||
imageSizeRegister = INTEL_DISPLAY_B_IMAGE_SIZE;
|
||||
controlRegister = INTEL_DISPLAY_B_CONTROL;
|
||||
} else if (pllRegister == PCH_DISPLAY_A_PLL) {
|
||||
pllDivisor = read32((pll & DISPLAY_PLL_DIVISOR_1) != 0
|
||||
? PCH_DISPLAY_A_PLL_DIVISOR_1 : PCH_DISPLAY_A_PLL_DIVISOR_0);
|
||||
|
||||
hTotalRegister = PCH_TRANSCODER_A_HTOTAL;
|
||||
vTotalRegister = PCH_TRANSCODER_A_VTOTAL;
|
||||
hSyncRegister = PCH_TRANSCODER_A_HSYNC;
|
||||
vSyncRegister = PCH_TRANSCODER_A_VSYNC;
|
||||
imageSizeRegister = INTEL_DISPLAY_A_IMAGE_SIZE;
|
||||
controlRegister = INTEL_DISPLAY_A_CONTROL;
|
||||
} else if (pllRegister == PCH_DISPLAY_B_PLL) {
|
||||
pllDivisor = read32((pll & DISPLAY_PLL_DIVISOR_1) != 0
|
||||
? PCH_DISPLAY_B_PLL_DIVISOR_1 : PCH_DISPLAY_B_PLL_DIVISOR_0);
|
||||
|
||||
hTotalRegister = PCH_TRANSCODER_B_HTOTAL;
|
||||
vTotalRegister = PCH_TRANSCODER_B_VTOTAL;
|
||||
hSyncRegister = PCH_TRANSCODER_B_HSYNC;
|
||||
vSyncRegister = PCH_TRANSCODER_B_VSYNC;
|
||||
imageSizeRegister = INTEL_DISPLAY_B_IMAGE_SIZE;
|
||||
controlRegister = INTEL_DISPLAY_B_CONTROL;
|
||||
} else {
|
||||
// TODO: not supported
|
||||
return;
|
||||
@@ -565,12 +539,9 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister)
|
||||
void
|
||||
save_lvds_mode(void)
|
||||
{
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
|
||||
// dump currently programmed mode.
|
||||
display_mode biosMode;
|
||||
retrieve_current_mode(biosMode,
|
||||
isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL);
|
||||
retrieve_current_mode(biosMode, INTEL_DISPLAY_B_PLL);
|
||||
gInfo->lvds_panel_mode = biosMode;
|
||||
}
|
||||
|
||||
@@ -749,9 +720,6 @@ if (first) {
|
||||
write32(INTEL_VGA_DISPLAY_CONTROL, VGA_DISPLAY_DISABLED);
|
||||
read32(INTEL_VGA_DISPLAY_CONTROL);
|
||||
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
int targetRegister;
|
||||
|
||||
if ((gInfo->head_mode & HEAD_MODE_B_DIGITAL) != 0) {
|
||||
// For LVDS panels, we actually always set the native mode in hardware
|
||||
// Then we use the panel fitter to scale the picture to that.
|
||||
@@ -829,8 +797,7 @@ if (first) {
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
|
||||
} else {
|
||||
write32(isSNB ? PCH_DISPLAY_B_PLL_DIVISOR_0
|
||||
: INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
@@ -838,15 +805,12 @@ if (first) {
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
}
|
||||
targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL;
|
||||
write32(targetRegister, dpll & ~DISPLAY_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_B_PLL, dpll & ~DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
spin(150);
|
||||
}
|
||||
|
||||
targetRegister
|
||||
= isSNB ? PCH_DISPLAY_LVDS_PORT : INTEL_DISPLAY_LVDS_PORT;
|
||||
uint32 lvds = read32(targetRegister) | LVDS_PORT_EN
|
||||
uint32 lvds = read32(INTEL_DISPLAY_LVDS_PORT) | LVDS_PORT_EN
|
||||
| LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
|
||||
|
||||
lvds |= LVDS_18BIT_DITHER;
|
||||
@@ -863,8 +827,8 @@ if (first) {
|
||||
else
|
||||
lvds &= ~(LVDS_B0B3PAIRS_POWER_UP | LVDS_CLKB_POWER_UP);
|
||||
|
||||
write32(targetRegister, lvds);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_LVDS_PORT, lvds);
|
||||
read32(INTEL_DISPLAY_LVDS_PORT);
|
||||
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
@@ -873,8 +837,7 @@ if (first) {
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
|
||||
} else {
|
||||
write32(isSNB ? PCH_DISPLAY_B_PLL_DIVISOR_0
|
||||
: INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
@@ -883,9 +846,8 @@ if (first) {
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
}
|
||||
|
||||
targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL;
|
||||
write32(targetRegister, dpll);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_B_PLL, dpll);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
|
||||
// Wait for the clocks to stabilize
|
||||
spin(150);
|
||||
@@ -905,9 +867,9 @@ if (first) {
|
||||
write32(INTEL_DISPLAY_B_PLL_MULTIPLIER_DIVISOR, (0 << 24)
|
||||
| ((pixelMultiply - 1) << 8));
|
||||
} else
|
||||
write32(targetRegister, dpll);
|
||||
write32(INTEL_DISPLAY_B_PLL, dpll);
|
||||
|
||||
read32(targetRegister);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
spin(150);
|
||||
|
||||
// update timing parameters
|
||||
@@ -928,14 +890,14 @@ if (first) {
|
||||
+ (hardwareTarget.timing.h_total
|
||||
- target.timing.h_display) / 2;
|
||||
|
||||
write32(isSNB ? PCH_TRANSCODER_B_HTOTAL : INTEL_DISPLAY_B_HTOTAL,
|
||||
write32(INTEL_DISPLAY_B_HTOTAL,
|
||||
((uint32)(hardwareTarget.timing.h_total - 1) << 16)
|
||||
| ((uint32)target.timing.h_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_HBLANK : INTEL_DISPLAY_B_HBLANK,
|
||||
write32(INTEL_DISPLAY_B_HBLANK,
|
||||
((uint32)(hardwareTarget.timing.h_total - borderWidth / 2 - 1)
|
||||
<< 16)
|
||||
| ((uint32)target.timing.h_display + borderWidth / 2 - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_HSYNC : INTEL_DISPLAY_B_HSYNC,
|
||||
write32(INTEL_DISPLAY_B_HSYNC,
|
||||
((uint32)(syncCenter + syncWidth / 2 - 1) << 16)
|
||||
| ((uint32)syncCenter - syncWidth / 2 - 1));
|
||||
|
||||
@@ -949,15 +911,15 @@ if (first) {
|
||||
+ (hardwareTarget.timing.v_total
|
||||
- target.timing.v_display) / 2;
|
||||
|
||||
write32(isSNB ? PCH_TRANSCODER_B_VTOTAL : INTEL_DISPLAY_B_VTOTAL,
|
||||
write32(INTEL_DISPLAY_B_VTOTAL,
|
||||
((uint32)(hardwareTarget.timing.v_total - 1) << 16)
|
||||
| ((uint32)target.timing.v_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_VBLANK : INTEL_DISPLAY_B_VBLANK,
|
||||
write32(INTEL_DISPLAY_B_VBLANK,
|
||||
((uint32)(hardwareTarget.timing.v_total - borderHeight / 2 - 1)
|
||||
<< 16)
|
||||
| ((uint32)target.timing.v_display
|
||||
+ borderHeight / 2 - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_VSYNC : INTEL_DISPLAY_B_VSYNC,
|
||||
write32(INTEL_DISPLAY_B_VSYNC,
|
||||
((uint32)(syncCenter + syncHeight / 2 - 1) << 16)
|
||||
| ((uint32)syncCenter - syncHeight / 2 - 1));
|
||||
|
||||
@@ -966,23 +928,23 @@ if (first) {
|
||||
// sync)
|
||||
// write32(0x61020, 0x00FF0000);
|
||||
} else {
|
||||
write32(isSNB ? PCH_TRANSCODER_B_HTOTAL : INTEL_DISPLAY_B_HTOTAL,
|
||||
write32(INTEL_DISPLAY_B_HTOTAL,
|
||||
((uint32)(target.timing.h_total - 1) << 16)
|
||||
| ((uint32)target.timing.h_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_HBLANK : INTEL_DISPLAY_B_HBLANK,
|
||||
write32(INTEL_DISPLAY_B_HBLANK,
|
||||
((uint32)(target.timing.h_total - 1) << 16)
|
||||
| ((uint32)target.timing.h_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_HSYNC : INTEL_DISPLAY_B_HSYNC,
|
||||
write32(INTEL_DISPLAY_B_HSYNC,
|
||||
((uint32)(target.timing.h_sync_end - 1) << 16)
|
||||
| ((uint32)target.timing.h_sync_start - 1));
|
||||
|
||||
write32(isSNB ? PCH_TRANSCODER_B_VTOTAL : INTEL_DISPLAY_B_VTOTAL,
|
||||
write32(INTEL_DISPLAY_B_VTOTAL,
|
||||
((uint32)(target.timing.v_total - 1) << 16)
|
||||
| ((uint32)target.timing.v_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_VBLANK : INTEL_DISPLAY_B_VBLANK,
|
||||
write32(INTEL_DISPLAY_B_VBLANK,
|
||||
((uint32)(target.timing.v_total - 1) << 16)
|
||||
| ((uint32)target.timing.v_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_B_VSYNC : INTEL_DISPLAY_B_VSYNC, (
|
||||
write32(INTEL_DISPLAY_B_VSYNC, (
|
||||
(uint32)(target.timing.v_sync_end - 1) << 16)
|
||||
| ((uint32)target.timing.v_sync_start - 1));
|
||||
}
|
||||
@@ -1016,8 +978,7 @@ if (first) {
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
|
||||
} else {
|
||||
write32(isSNB ? PCH_DISPLAY_A_PLL_DIVISOR_0
|
||||
: INTEL_DISPLAY_A_PLL_DIVISOR_0,
|
||||
write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
@@ -1059,32 +1020,31 @@ if (first) {
|
||||
pll |= DISPLAY_PLL_POST1_DIVIDE_2;
|
||||
}
|
||||
|
||||
targetRegister = isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL;
|
||||
write32(targetRegister, pll);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_A_PLL, pll);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
spin(150);
|
||||
write32(targetRegister, pll);
|
||||
read32(targetRegister);
|
||||
write32(INTEL_DISPLAY_A_PLL, pll);
|
||||
read32(INTEL_DISPLAY_A_PLL);
|
||||
spin(150);
|
||||
|
||||
// update timing parameters
|
||||
write32(isSNB ? PCH_TRANSCODER_A_HTOTAL : INTEL_DISPLAY_A_HTOTAL,
|
||||
write32(INTEL_DISPLAY_A_HTOTAL,
|
||||
((uint32)(target.timing.h_total - 1) << 16)
|
||||
| ((uint32)target.timing.h_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_A_HBLANK : INTEL_DISPLAY_A_HBLANK,
|
||||
write32(INTEL_DISPLAY_A_HBLANK,
|
||||
((uint32)(target.timing.h_total - 1) << 16)
|
||||
| ((uint32)target.timing.h_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_A_HSYNC : INTEL_DISPLAY_A_HSYNC,
|
||||
write32(INTEL_DISPLAY_A_HSYNC,
|
||||
((uint32)(target.timing.h_sync_end - 1) << 16)
|
||||
| ((uint32)target.timing.h_sync_start - 1));
|
||||
|
||||
write32(isSNB ? PCH_TRANSCODER_A_VTOTAL : INTEL_DISPLAY_A_VTOTAL,
|
||||
write32(INTEL_DISPLAY_A_VTOTAL,
|
||||
((uint32)(target.timing.v_total - 1) << 16)
|
||||
| ((uint32)target.timing.v_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_A_VBLANK : INTEL_DISPLAY_A_VBLANK,
|
||||
write32(INTEL_DISPLAY_A_VBLANK,
|
||||
((uint32)(target.timing.v_total - 1) << 16)
|
||||
| ((uint32)target.timing.v_display - 1));
|
||||
write32(isSNB ? PCH_TRANSCODER_A_VSYNC : INTEL_DISPLAY_A_VSYNC,
|
||||
write32(INTEL_DISPLAY_A_VSYNC,
|
||||
((uint32)(target.timing.v_sync_end - 1) << 16)
|
||||
| ((uint32)target.timing.v_sync_start - 1));
|
||||
|
||||
@@ -1092,10 +1052,8 @@ if (first) {
|
||||
((uint32)(target.virtual_width - 1) << 16)
|
||||
| ((uint32)target.virtual_height - 1));
|
||||
|
||||
targetRegister
|
||||
= isSNB ? PCH_DISPLAY_A_ANALOG_PORT : INTEL_DISPLAY_A_ANALOG_PORT;
|
||||
write32(targetRegister,
|
||||
(read32(targetRegister)
|
||||
write32(INTEL_DISPLAY_A_ANALOG_PORT,
|
||||
(read32(INTEL_DISPLAY_A_ANALOG_PORT)
|
||||
& ~(DISPLAY_MONITOR_POLARITY_MASK
|
||||
| DISPLAY_MONITOR_VGA_POLARITY))
|
||||
| ((target.timing.flags & B_POSITIVE_HSYNC) != 0
|
||||
@@ -1151,9 +1109,7 @@ intel_get_display_mode(display_mode *_currentMode)
|
||||
{
|
||||
TRACE(("intel_get_display_mode()\n"));
|
||||
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
retrieve_current_mode(*_currentMode,
|
||||
isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL);
|
||||
retrieve_current_mode(*_currentMode, INTEL_DISPLAY_A_PLL);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -1259,11 +1215,8 @@ intel_set_indexed_colors(uint count, uint8 first, uint8 *colors, uint32 flags)
|
||||
uint32 color = colors[0] << 16 | colors[1] << 8 | colors[2];
|
||||
colors += 3;
|
||||
|
||||
bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
|
||||
write32((isSNB ? PCH_DISPLAY_A_PALETTE : INTEL_DISPLAY_A_PALETTE)
|
||||
+ first * sizeof(uint32), color);
|
||||
write32((isSNB ? PCH_DISPLAY_B_PALETTE : INTEL_DISPLAY_B_PALETTE)
|
||||
+ first * sizeof(uint32), color);
|
||||
write32(INTEL_DISPLAY_A_PALETTE + first * sizeof(uint32), color);
|
||||
write32(INTEL_DISPLAY_B_PALETTE + first * sizeof(uint32), color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,14 +76,14 @@ getset_register(int argc, char **argv)
|
||||
kprintf("intel_extreme register %#lx\n", reg);
|
||||
|
||||
intel_info &info = *gDeviceInfo[0];
|
||||
uint32 oldValue = read32(info.registers + reg);
|
||||
uint32 oldValue = read32(info, reg);
|
||||
|
||||
kprintf(" %svalue: %#lx (%lu)\n", set ? "old " : "", oldValue, oldValue);
|
||||
|
||||
if (set) {
|
||||
write32(info.registers + reg, value);
|
||||
write32(info, reg, value);
|
||||
|
||||
value = read32(info.registers + reg);
|
||||
value = read32(info, reg);
|
||||
kprintf(" new value: %#lx (%lu)\n", value, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,16 +17,6 @@
|
||||
#include "intel_extreme_private.h"
|
||||
|
||||
|
||||
// PCI Communications
|
||||
|
||||
#define read8(address) (*((volatile uint8*)(address)))
|
||||
#define read16(address) (*((volatile uint16*)(address)))
|
||||
#define read32(address) (*((volatile uint32*)(address)))
|
||||
#define write8(address, data) (*((volatile uint8*)(address)) = (data))
|
||||
#define write16(address, data) (*((volatile uint16*)(address)) = (data))
|
||||
#define write32(address, data) (*((volatile uint32*)(address)) = (data))
|
||||
|
||||
|
||||
extern char* gDeviceNames[];
|
||||
extern intel_info* gDeviceInfo[];
|
||||
extern pci_module_info* gPCI;
|
||||
@@ -49,4 +39,40 @@ set_pci_config(pci_info* info, uint8 offset, uint8 size, uint32 value)
|
||||
size, value);
|
||||
}
|
||||
|
||||
|
||||
static inline uint16
|
||||
read16(intel_info &info, uint32 encodedRegister)
|
||||
{
|
||||
return *(volatile uint16 *)(info.registers
|
||||
+ info.shared_info->register_blocks[REGISTER_BLOCK(encodedRegister)]
|
||||
+ REGISTER_REGISTER(encodedRegister));
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
read32(intel_info &info, uint32 encodedRegister)
|
||||
{
|
||||
return *(volatile uint32 *)(info.registers
|
||||
+ info.shared_info->register_blocks[REGISTER_BLOCK(encodedRegister)]
|
||||
+ REGISTER_REGISTER(encodedRegister));
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
write16(intel_info &info, uint32 encodedRegister, uint16 value)
|
||||
{
|
||||
*(volatile uint16 *)(info.registers
|
||||
+ info.shared_info->register_blocks[REGISTER_BLOCK(encodedRegister)]
|
||||
+ REGISTER_REGISTER(encodedRegister)) = value;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
write32(intel_info &info, uint32 encodedRegister, uint32 value)
|
||||
{
|
||||
*(volatile uint32 *)(info.registers
|
||||
+ info.shared_info->register_blocks[REGISTER_BLOCK(encodedRegister)]
|
||||
+ REGISTER_REGISTER(encodedRegister)) = value;
|
||||
}
|
||||
|
||||
#endif /* DRIVER_H */
|
||||
|
||||
@@ -76,20 +76,20 @@ intel_interrupt_handler(void *data)
|
||||
{
|
||||
intel_info &info = *(intel_info *)data;
|
||||
|
||||
bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB);
|
||||
uint32 identity = read16(info.registers
|
||||
+ (isSNB ? PCH_DE_INTERRUPT_IDENTITY : INTEL_INTERRUPT_IDENTITY));
|
||||
uint16 identity = read16(info, INTEL_INTERRUPT_IDENTITY);
|
||||
if (identity == 0)
|
||||
return B_UNHANDLED_INTERRUPT;
|
||||
|
||||
int32 handled = B_HANDLED_INTERRUPT;
|
||||
|
||||
uint32 mask = isSNB ? PCH_INTERRUPT_VBLANK_PIPEA : INTERRUPT_VBLANK_PIPEA;
|
||||
// TODO: verify that these aren't actually the same
|
||||
bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB);
|
||||
uint16 mask = isSNB ? PCH_INTERRUPT_VBLANK_PIPEA : INTERRUPT_VBLANK_PIPEA;
|
||||
if ((identity & mask) != 0) {
|
||||
handled = release_vblank_sem(info);
|
||||
|
||||
// make sure we'll get another one of those
|
||||
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS,
|
||||
write32(info, INTEL_DISPLAY_A_PIPE_STATUS,
|
||||
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
||||
}
|
||||
|
||||
@@ -98,13 +98,12 @@ intel_interrupt_handler(void *data)
|
||||
handled = release_vblank_sem(info);
|
||||
|
||||
// make sure we'll get another one of those
|
||||
write32(info.registers + INTEL_DISPLAY_B_PIPE_STATUS,
|
||||
write32(info, INTEL_DISPLAY_B_PIPE_STATUS,
|
||||
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
||||
}
|
||||
|
||||
// setting the bit clears it!
|
||||
write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_IDENTITY
|
||||
: INTEL_INTERRUPT_IDENTITY), identity);
|
||||
write16(info, INTEL_INTERRUPT_IDENTITY, identity);
|
||||
|
||||
return handled;
|
||||
}
|
||||
@@ -138,26 +137,22 @@ init_interrupt_handler(intel_info &info)
|
||||
status = install_io_interrupt_handler(info.pci->u.h0.interrupt_line,
|
||||
&intel_interrupt_handler, (void *)&info, 0);
|
||||
if (status == B_OK) {
|
||||
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS,
|
||||
write32(info, INTEL_DISPLAY_A_PIPE_STATUS,
|
||||
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
||||
write32(info.registers + INTEL_DISPLAY_B_PIPE_STATUS,
|
||||
write32(info, INTEL_DISPLAY_B_PIPE_STATUS,
|
||||
DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED);
|
||||
|
||||
bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB);
|
||||
write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_IDENTITY
|
||||
: INTEL_INTERRUPT_IDENTITY), ~0);
|
||||
write16(info, INTEL_INTERRUPT_IDENTITY, ~0);
|
||||
|
||||
// enable interrupts - we only want VBLANK interrupts
|
||||
bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB);
|
||||
uint16 enable = isSNB
|
||||
? (PCH_INTERRUPT_VBLANK_PIPEA | PCH_INTERRUPT_VBLANK_PIPEB)
|
||||
: (INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB);
|
||||
|
||||
write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_ENABLED
|
||||
: INTEL_INTERRUPT_ENABLED),
|
||||
read16(info.registers + (isSNB ? PCH_DE_INTERRUPT_ENABLED
|
||||
: INTEL_INTERRUPT_ENABLED)) | enable);
|
||||
write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_MASK
|
||||
: INTEL_INTERRUPT_MASK), ~enable);
|
||||
write16(info, INTEL_INTERRUPT_ENABLED,
|
||||
read16(info, INTEL_INTERRUPT_ENABLED) | enable);
|
||||
write16(info, INTEL_INTERRUPT_MASK, ~enable);
|
||||
}
|
||||
}
|
||||
if (status < B_OK) {
|
||||
@@ -248,6 +243,40 @@ intel_extreme_init(intel_info &info)
|
||||
return info.registers_area;
|
||||
}
|
||||
|
||||
uint32 *blocks = info.shared_info->register_blocks;
|
||||
blocks[REGISTER_BLOCK(REGS_FLAT)] = 0;
|
||||
|
||||
// setup the register blocks for the different architectures
|
||||
if (info.device_type.InGroup(INTEL_TYPE_SNB)) {
|
||||
// PCH based platforms (IronLake and up)
|
||||
blocks[REGISTER_BLOCK(REGS_INTERRUPT)]
|
||||
= PCH_DE_INTERRUPT_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_NORTH_SHARED)]
|
||||
= PCH_NORTH_SHARED_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_NORTH_PIPE_AND_PORT)]
|
||||
= PCH_NORTH_PIPE_AND_PORT_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_NORTH_PLANE_CONTROL)]
|
||||
= PCH_NORTH_PLANE_CONTROL_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_SOUTH_SHARED)]
|
||||
= PCH_SOUTH_SHARED_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_SOUTH_TRANSCODER_PORT)]
|
||||
= PCH_SOUTH_TRANSCODER_AND_PORT_REGISTER_BASE;
|
||||
} else {
|
||||
// (G)MCH/ICH based platforms
|
||||
blocks[REGISTER_BLOCK(REGS_INTERRUPT)]
|
||||
= MCH_INTERRUPT_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_NORTH_SHARED)]
|
||||
= MCH_SHARED_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_NORTH_PIPE_AND_PORT)]
|
||||
= MCH_PIPE_AND_PORT_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_NORTH_PLANE_CONTROL)]
|
||||
= MCH_PLANE_CONTROL_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_SOUTH_SHARED)]
|
||||
= ICH_SHARED_REGISTER_BASE;
|
||||
blocks[REGISTER_BLOCK(REGS_SOUTH_TRANSCODER_PORT)]
|
||||
= ICH_PORT_REGISTER_BASE;
|
||||
}
|
||||
|
||||
// make sure bus master, memory-mapped I/O, and frame buffer is enabled
|
||||
set_pci_config(info.pci, PCI_command, 2, get_pci_config(info.pci, PCI_command, 2)
|
||||
| PCI_command_io | PCI_command_memory | PCI_command_master);
|
||||
@@ -269,27 +298,27 @@ intel_extreme_init(intel_info &info)
|
||||
// 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));
|
||||
write32(info, 0x6204, (1L << 29));
|
||||
} else if (info.device_type.InGroup(INTEL_TYPE_SNB)) {
|
||||
dprintf("SNB clock gating\n");
|
||||
write32(info.registers + 0x42020, (1L << 28) | (1L << 7) | (1L << 5));
|
||||
write32(info, 0x42020, (1L << 28) | (1L << 7) | (1L << 5));
|
||||
} else if (info.device_type.InGroup(INTEL_TYPE_G4x)) {
|
||||
dprintf("G4x clock gating\n");
|
||||
write32(info.registers + 0x6204, 0);
|
||||
write32(info.registers + 0x6208, (1L << 9) | (1L << 7) | (1L << 6));
|
||||
write32(info.registers + 0x6210, 0);
|
||||
write32(info, 0x6204, 0);
|
||||
write32(info, 0x6208, (1L << 9) | (1L << 7) | (1L << 6));
|
||||
write32(info, 0x6210, 0);
|
||||
|
||||
uint32 gateValue = (1L << 28) | (1L << 3) | (1L << 2);
|
||||
if ((info.device_type.type & INTEL_TYPE_MOBILE) == INTEL_TYPE_MOBILE) {
|
||||
dprintf("G4x mobile clock gating\n");
|
||||
gateValue |= 1L << 18;
|
||||
}
|
||||
write32(info.registers + 0x6200, gateValue);
|
||||
write32(info, 0x6200, gateValue);
|
||||
} else {
|
||||
dprintf("i965 quirk\n");
|
||||
write32(info.registers + 0x6204, (1L << 29) | (1L << 23));
|
||||
write32(info, 0x6204, (1L << 29) | (1L << 23));
|
||||
}
|
||||
write32(info.registers + 0x7408, 0x10);
|
||||
write32(info, 0x7408, 0x10);
|
||||
|
||||
// no errors, so keep areas and mappings
|
||||
sharedCreator.Detach();
|
||||
@@ -367,11 +396,8 @@ intel_extreme_uninit(intel_info &info)
|
||||
|
||||
if (!info.fake_interrupts && info.shared_info->vblank_sem > 0) {
|
||||
// disable interrupt generation
|
||||
bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB);
|
||||
write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_ENABLED
|
||||
: INTEL_INTERRUPT_ENABLED), 0);
|
||||
write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_MASK
|
||||
: INTEL_INTERRUPT_MASK), ~0);
|
||||
write16(info, INTEL_INTERRUPT_ENABLED, 0);
|
||||
write16(info, INTEL_INTERRUPT_MASK, ~0);
|
||||
|
||||
remove_io_interrupt_handler(info.pci->u.h0.interrupt_line,
|
||||
intel_interrupt_handler, &info);
|
||||
|
||||
@@ -24,7 +24,9 @@ struct intel_info {
|
||||
pci_info* pci;
|
||||
addr_t aperture_base;
|
||||
aperture_id aperture;
|
||||
|
||||
uint8* registers;
|
||||
|
||||
area_id registers_area;
|
||||
struct intel_shared_info* shared_info;
|
||||
area_id shared_area;
|
||||
|
||||
Reference in New Issue
Block a user