* B_MOVE_DISPLAY and B_SET_INDEXED_COLORS should now work for the digital

output as well.
* Obviously got the register for INTEL_DISPLAY_B_DIGITAL_PORT wrong - it's
  not 0x61000 but 0x61140, maybe that can explain the fun we had at BeGeistert :)
* Renamed the analog display registers to better fit the digital ones, ie.
  replaced DISPLAY with DISPLAY_A - although this might be not really correct
  as it seems that the pipes can be selected arbitrarily.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17566 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-05-23 16:51:40 +00:00
parent a0902420ff
commit c5f5d8347e
5 changed files with 69 additions and 53 deletions
@@ -181,17 +181,17 @@ struct intel_free_graphics_memory {
#define INTEL_RING_BUFFER_ENABLED 1
// display A
#define INTEL_DISPLAY_HTOTAL 0x60000
#define INTEL_DISPLAY_HBLANK 0x60004
#define INTEL_DISPLAY_HSYNC 0x60008
#define INTEL_DISPLAY_VTOTAL 0x6000c
#define INTEL_DISPLAY_VBLANK 0x60010
#define INTEL_DISPLAY_VSYNC 0x60014
#define INTEL_DISPLAY_IMAGE_SIZE 0x6001c
#define INTEL_DISPLAY_A_HTOTAL 0x60000
#define INTEL_DISPLAY_A_HBLANK 0x60004
#define INTEL_DISPLAY_A_HSYNC 0x60008
#define INTEL_DISPLAY_A_VTOTAL 0x6000c
#define INTEL_DISPLAY_A_VBLANK 0x60010
#define INTEL_DISPLAY_A_VSYNC 0x60014
#define INTEL_DISPLAY_A_IMAGE_SIZE 0x6001c
#define INTEL_DISPLAY_CONTROL 0x70180
#define INTEL_DISPLAY_BASE 0x70184
#define INTEL_DISPLAY_BYTES_PER_ROW 0x70188
#define INTEL_DISPLAY_A_CONTROL 0x70180
#define INTEL_DISPLAY_A_BASE 0x70184
#define INTEL_DISPLAY_A_BYTES_PER_ROW 0x70188
#define DISPLAY_CONTROL_ENABLED (1UL << 31)
#define DISPLAY_CONTROL_GAMMA (1UL << 30)
#define DISPLAY_CONTROL_COLOR_MASK (0x0fUL << 26)
@@ -200,20 +200,20 @@ struct intel_free_graphics_memory {
#define DISPLAY_CONTROL_RGB16 (5UL << 26)
#define DISPLAY_CONTROL_RGB32 (7UL << 26)
#define DISPLAY_VGA_DISPLAY_CONTROL 0x71400
#define INTEL_VGA_DISPLAY_CONTROL 0x71400
#define VGA_DISPLAY_DISABLED (1UL << 31)
#define INTEL_DISPLAY_PALETTE 0x0a000
#define INTEL_DISPLAY_A_PALETTE 0x0a000
#define INTEL_DISPLAY_PIPE_CONTROL 0x70008
#define INTEL_DISPLAY_A_PIPE_CONTROL 0x70008
#define DISPLAY_PIPE_ENABLED (1UL << 31)
#define INTEL_DISPLAY_PIPE_STATUS 0x70024
#define INTEL_DISPLAY_A_PIPE_STATUS 0x70024
#define DISPLAY_PIPE_VBLANK_ENABLED (1UL << 17)
#define DISPLAY_PIPE_VBLANK_STATUS (1UL << 1)
#define INTEL_DISPLAY_PLL 0x06014
#define INTEL_DISPLAY_PLL_DIVISOR_0 0x06040
#define INTEL_DISPLAY_PLL_DIVISOR_1 0x06044
#define INTEL_DISPLAY_A_PLL 0x06014
#define INTEL_DISPLAY_A_PLL_DIVISOR_0 0x06040
#define INTEL_DISPLAY_A_PLL_DIVISOR_1 0x06044
#define DISPLAY_PLL_ENABLED (1UL << 31)
#define DISPLAY_PLL_2X_CLOCK (1UL << 30)
#define DISPLAY_PLL_SYNC_LOCK_ENABLED (1UL << 29)
@@ -229,7 +229,7 @@ struct intel_free_graphics_memory {
#define DISPLAY_PLL_M1_DIVISOR_SHIFT 8
#define DISPLAY_PLL_M2_DIVISOR_SHIFT 0
#define INTEL_DISPLAY_ANALOG_PORT 0x61100
#define INTEL_DISPLAY_A_ANALOG_PORT 0x61100
#define DISPLAY_MONITOR_PORT_ENABLED (1UL << 31)
#define DISPLAY_MONITOR_VGA_POLARITY (1UL << 15)
#define DISPLAY_MONITOR_MODE_MASK (3UL << 10)
@@ -242,7 +242,7 @@ struct intel_free_graphics_memory {
#define DISPLAY_MONITOR_POSITIVE_VSYNC (2UL << 3)
// display B
#define INTEL_DISPLAY_B_DIGITAL_PORT 0x61000
#define INTEL_DISPLAY_B_DIGITAL_PORT 0x61140
#define INTEL_DISPLAY_B_IMAGE_SIZE 0x6101c
#define INTEL_DISPLAY_B_PIPE_CONTROL 0x71008
@@ -251,6 +251,12 @@ struct intel_free_graphics_memory {
#define INTEL_DISPLAY_B_BASE 0x71184
#define INTEL_DISPLAY_B_BYTES_PER_ROW 0x71188
#define INTEL_DISPLAY_B_PALETTE 0x0a800
#define INTEL_DISPLAY_A_DIGITAL_PORT 0x61120
#define INTEL_DISPLAY_C_DIGITAL 0x61160
#define INTEL_DISPLAY_LVDS_PORT 0x61180
// cursor
#define INTEL_CURSOR_CONTROL 0x70080
#define INTEL_CURSOR_BASE 0x70084
@@ -192,7 +192,7 @@ intel_init_accelerant(int device)
gInfo->head_mode = 0;
if (read32(INTEL_DISPLAY_B_PIPE_CONTROL) & DISPLAY_PIPE_ENABLED)
gInfo->head_mode |= HEAD_MODE_B_DIGITAL;
if (read32(INTEL_DISPLAY_PIPE_CONTROL) & DISPLAY_PIPE_ENABLED)
if (read32(INTEL_DISPLAY_A_PIPE_CONTROL) & DISPLAY_PIPE_ENABLED)
gInfo->head_mode |= HEAD_MODE_A_ANALOG;
status = create_mode_list();
@@ -23,21 +23,21 @@ extern "C" void _sPrintf(const char *format, ...);
void
enable_display_plane(bool enable)
{
uint32 planeAControl = read32(INTEL_DISPLAY_CONTROL);
uint32 planeAControl = read32(INTEL_DISPLAY_A_CONTROL);
uint32 planeBControl = read32(INTEL_DISPLAY_B_CONTROL);
if (enable) {
// when enabling the display, the register values are updated automatically
if (gInfo->head_mode & HEAD_MODE_A_ANALOG)
write32(INTEL_DISPLAY_CONTROL, planeAControl | DISPLAY_CONTROL_ENABLED);
write32(INTEL_DISPLAY_A_CONTROL, planeAControl | DISPLAY_CONTROL_ENABLED);
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL)
write32(INTEL_DISPLAY_B_CONTROL, planeBControl | DISPLAY_CONTROL_ENABLED);
} else {
// when disabling it, we have to trigger the update using a write to
// the display base address
if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
write32(INTEL_DISPLAY_CONTROL, planeAControl & ~DISPLAY_CONTROL_ENABLED);
write32(INTEL_DISPLAY_BASE, gInfo->shared_info->frame_buffer_offset);
write32(INTEL_DISPLAY_A_CONTROL, planeAControl & ~DISPLAY_CONTROL_ENABLED);
write32(INTEL_DISPLAY_A_BASE, gInfo->shared_info->frame_buffer_offset);
}
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
write32(INTEL_DISPLAY_B_CONTROL, planeBControl & ~DISPLAY_CONTROL_ENABLED);
@@ -50,17 +50,17 @@ enable_display_plane(bool enable)
static void
enable_display_pipe(bool enable)
{
uint32 pipeAControl = read32(INTEL_DISPLAY_PIPE_CONTROL);
uint32 pipeAControl = read32(INTEL_DISPLAY_A_PIPE_CONTROL);
uint32 pipeBControl = read32(INTEL_DISPLAY_B_PIPE_CONTROL);
if (enable) {
if (gInfo->head_mode & HEAD_MODE_A_ANALOG)
write32(INTEL_DISPLAY_PIPE_CONTROL, pipeAControl | DISPLAY_PIPE_ENABLED);
write32(INTEL_DISPLAY_A_PIPE_CONTROL, pipeAControl | DISPLAY_PIPE_ENABLED);
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL)
write32(INTEL_DISPLAY_B_PIPE_CONTROL, pipeBControl | DISPLAY_PIPE_ENABLED);
} else {
if (gInfo->head_mode & HEAD_MODE_A_ANALOG)
write32(INTEL_DISPLAY_PIPE_CONTROL, pipeAControl & ~DISPLAY_PIPE_ENABLED);
write32(INTEL_DISPLAY_A_PIPE_CONTROL, pipeAControl & ~DISPLAY_PIPE_ENABLED);
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL)
write32(INTEL_DISPLAY_B_PIPE_CONTROL, pipeBControl & ~DISPLAY_PIPE_ENABLED);
}
@@ -95,7 +95,7 @@ set_display_power_mode(uint32 mode)
}
if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
write32(INTEL_DISPLAY_ANALOG_PORT, (read32(INTEL_DISPLAY_ANALOG_PORT)
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));
}
+32 -22
View File
@@ -267,7 +267,7 @@ intel_set_display_mode(display_mode *mode)
* sharedInfo.bytes_per_row, gInfo->frame_buffer_handle,
offset) == B_OK) {
sharedInfo.frame_buffer_offset = offset;
write32(INTEL_DISPLAY_BASE, offset);
write32(INTEL_DISPLAY_A_BASE, offset);
}
return B_NO_MEMORY;
@@ -276,29 +276,29 @@ intel_set_display_mode(display_mode *mode)
sharedInfo.frame_buffer_offset = offset;
// make sure VGA display is disabled
write32(DISPLAY_VGA_DISPLAY_CONTROL, read32(DISPLAY_VGA_DISPLAY_CONTROL)
write32(INTEL_VGA_DISPLAY_CONTROL, read32(INTEL_VGA_DISPLAY_CONTROL)
| VGA_DISPLAY_DISABLED);
if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
// update timing parameters
write32(INTEL_DISPLAY_HTOTAL, ((uint32)(target.timing.h_total - 1) << 16)
write32(INTEL_DISPLAY_A_HTOTAL, ((uint32)(target.timing.h_total - 1) << 16)
| ((uint32)target.timing.h_display - 1));
write32(INTEL_DISPLAY_HBLANK, ((uint32)(target.timing.h_total - 1) << 16)
write32(INTEL_DISPLAY_A_HBLANK, ((uint32)(target.timing.h_total - 1) << 16)
| ((uint32)target.timing.h_display - 1));
write32(INTEL_DISPLAY_HSYNC, ((uint32)(target.timing.h_sync_end - 1) << 16)
write32(INTEL_DISPLAY_A_HSYNC, ((uint32)(target.timing.h_sync_end - 1) << 16)
| ((uint32)target.timing.h_sync_start - 1));
write32(INTEL_DISPLAY_VTOTAL, ((uint32)(target.timing.v_total - 1) << 16)
write32(INTEL_DISPLAY_A_VTOTAL, ((uint32)(target.timing.v_total - 1) << 16)
| ((uint32)target.timing.v_display - 1));
write32(INTEL_DISPLAY_VBLANK, ((uint32)(target.timing.v_total - 1) << 16)
write32(INTEL_DISPLAY_A_VBLANK, ((uint32)(target.timing.v_total - 1) << 16)
| ((uint32)target.timing.v_display - 1));
write32(INTEL_DISPLAY_VSYNC, ((uint32)(target.timing.v_sync_end - 1) << 16)
write32(INTEL_DISPLAY_A_VSYNC, ((uint32)(target.timing.v_sync_end - 1) << 16)
| ((uint32)target.timing.v_sync_start - 1));
write32(INTEL_DISPLAY_IMAGE_SIZE, ((uint32)(target.timing.h_display - 1) << 16)
write32(INTEL_DISPLAY_A_IMAGE_SIZE, ((uint32)(target.timing.h_display - 1) << 16)
| ((uint32)target.timing.v_display - 1));
write32(INTEL_DISPLAY_ANALOG_PORT, (read32(INTEL_DISPLAY_ANALOG_PORT)
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 ? DISPLAY_MONITOR_POSITIVE_HSYNC : 0)
| ((target.timing.flags & B_POSITIVE_VSYNC) != 0 ? DISPLAY_MONITOR_POSITIVE_VSYNC : 0));
@@ -308,25 +308,25 @@ intel_set_display_mode(display_mode *mode)
// switch divisor register with every mode change (not required)
uint32 divisorRegister;
if (gInfo->shared_info->pll_info.divisor_register == INTEL_DISPLAY_PLL_DIVISOR_0)
divisorRegister = INTEL_DISPLAY_PLL_DIVISOR_1;
if (gInfo->shared_info->pll_info.divisor_register == INTEL_DISPLAY_A_PLL_DIVISOR_0)
divisorRegister = INTEL_DISPLAY_A_PLL_DIVISOR_1;
else
divisorRegister = INTEL_DISPLAY_PLL_DIVISOR_0;
divisorRegister = INTEL_DISPLAY_A_PLL_DIVISOR_0;
write32(divisorRegister,
(((nDivisor - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT) & DISPLAY_PLL_N_DIVISOR_MASK)
| (((m1Divisor - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT) & DISPLAY_PLL_M1_DIVISOR_MASK)
| (((m2Divisor - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT) & DISPLAY_PLL_M2_DIVISOR_MASK));
write32(INTEL_DISPLAY_PLL, DISPLAY_PLL_ENABLED | DISPLAY_PLL_2X_CLOCK
write32(INTEL_DISPLAY_A_PLL, DISPLAY_PLL_ENABLED | DISPLAY_PLL_2X_CLOCK
| DISPLAY_PLL_NO_VGA_CONTROL | DISPLAY_PLL_DIVIDE_4X
| (((postDivisor - 2) << DISPLAY_PLL_POST_DIVISOR_SHIFT) & DISPLAY_PLL_POST_DIVISOR_MASK)
| (divisorRegister == INTEL_DISPLAY_PLL_DIVISOR_1 ? DISPLAY_PLL_DIVISOR_1 : 0));
| (divisorRegister == INTEL_DISPLAY_A_PLL_DIVISOR_1 ? DISPLAY_PLL_DIVISOR_1 : 0));
}
// These two have to be set for display B, too - this obviously means
// that the second head always must adopt the color space of the first
// head.
write32(INTEL_DISPLAY_CONTROL, (read32(INTEL_DISPLAY_CONTROL)
write32(INTEL_DISPLAY_A_CONTROL, (read32(INTEL_DISPLAY_A_CONTROL)
& ~(DISPLAY_CONTROL_COLOR_MASK | DISPLAY_CONTROL_GAMMA)) | colorMode);
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
@@ -342,8 +342,8 @@ intel_set_display_mode(display_mode *mode)
// changing bytes per row seems to be ignored if the plane/pipe is turned off
if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
write32(INTEL_DISPLAY_BYTES_PER_ROW, bytesPerRow);
write32(INTEL_DISPLAY_BASE, sharedInfo.frame_buffer_offset);
write32(INTEL_DISPLAY_A_BYTES_PER_ROW, bytesPerRow);
write32(INTEL_DISPLAY_A_BASE, sharedInfo.frame_buffer_offset);
// triggers writing back double-buffered registers
}
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
@@ -440,9 +440,16 @@ intel_move_display(uint16 horizontalStart, uint16 verticalStart)
mode.h_display_start = horizontalStart;
mode.v_display_start = verticalStart;
write32(INTEL_DISPLAY_BASE, sharedInfo.frame_buffer_offset
+ verticalStart * sharedInfo.bytes_per_row
+ horizontalStart * (sharedInfo.bits_per_pixel + 7) / 8);
if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
write32(INTEL_DISPLAY_A_BASE, sharedInfo.frame_buffer_offset
+ verticalStart * sharedInfo.bytes_per_row
+ horizontalStart * (sharedInfo.bits_per_pixel + 7) / 8);
}
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
write32(INTEL_DISPLAY_B_BASE, sharedInfo.frame_buffer_offset
+ verticalStart * sharedInfo.bytes_per_row
+ horizontalStart * (sharedInfo.bits_per_pixel + 7) / 8);
}
return B_OK;
}
@@ -470,7 +477,10 @@ intel_set_indexed_colors(uint count, uint8 first, uint8 *colors, uint32 flags)
uint32 color = colors[0] << 16 | colors[1] << 8 | colors[2];
colors += 3;
write32(INTEL_DISPLAY_PALETTE + first * sizeof(uint32), color);
if (gInfo->head_mode & HEAD_MODE_A_ANALOG)
write32(INTEL_DISPLAY_A_PALETTE + first * sizeof(uint32), color);
if (gInfo->head_mode & HEAD_MODE_B_DIGITAL)
write32(INTEL_DISPLAY_B_PALETTE + first * sizeof(uint32), color);
}
}
@@ -211,7 +211,7 @@ intel_interrupt_handler(void *data)
handled = release_vblank_sem(info);
// make sure we'll get another one of those
write32(info.registers + INTEL_DISPLAY_PIPE_STATUS, DISPLAY_PIPE_VBLANK_STATUS);
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS, DISPLAY_PIPE_VBLANK_STATUS);
}
// setting the bit clears it!
@@ -253,7 +253,7 @@ init_interrupt_handler(intel_info &info)
read16(info.registers + INTEL_INTERRUPT_ENABLED) | INTERRUPT_VBLANK);
write16(info.registers + INTEL_INTERRUPT_MASK, ~INTERRUPT_VBLANK);
write32(info.registers + INTEL_DISPLAY_PIPE_STATUS,
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS,
DISPLAY_PIPE_VBLANK_STATUS);
write16(info.registers + INTEL_INTERRUPT_IDENTITY, ~0);
}
@@ -397,7 +397,7 @@ intel_extreme_init(intel_info &info)
info.shared_info->pll_info.reference_frequency = 48000; // 48 kHz
info.shared_info->pll_info.min_frequency = 25000; // 25 MHz (not tested)
info.shared_info->pll_info.max_frequency = 350000; // 350 MHz RAM DAC speed
info.shared_info->pll_info.divisor_register = INTEL_DISPLAY_PLL_DIVISOR_0;
info.shared_info->pll_info.divisor_register = INTEL_DISPLAY_A_PLL_DIVISOR_0;
info.shared_info->device_type = info.device_type;
#ifdef __HAIKU__