diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index e2ef215504..2d90d88f18 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -54,6 +54,43 @@ #define DEVICE_NAME "intel_extreme" #define INTEL_ACCELERANT_NAME "intel_extreme.accelerant" +// We encode the register block into the value and extract/translate it when +// actually accessing. +#define REGISTER_BLOCK_COUNT 7 +#define REGISTER_BLOCK_SHIFT 24 +#define REGISTER_BLOCK_MASK 0xff000000 +#define REGISTER_REGISTER_MASK 0x00ffffff +#define REGISTER_BLOCK(x) ((x & REGISTER_BLOCK_MASK) >> REGISTER_BLOCK_SHIFT) +#define REGISTER_REGISTER(x) (x & REGISTER_REGISTER_MASK) + +#define REGS_FLAT (0 << REGISTER_BLOCK_SHIFT) +#define REGS_INTERRUPT (1 << REGISTER_BLOCK_SHIFT) +#define REGS_NORTH_SHARED (2 << REGISTER_BLOCK_SHIFT) +#define REGS_NORTH_PIPE_AND_PORT (3 << REGISTER_BLOCK_SHIFT) +#define REGS_NORTH_PLANE_CONTROL (4 << REGISTER_BLOCK_SHIFT) +#define REGS_SOUTH_SHARED (5 << REGISTER_BLOCK_SHIFT) +#define REGS_SOUTH_TRANSCODER_PORT (6 << REGISTER_BLOCK_SHIFT) + +// register blocks for (G)MCH/ICH based platforms +#define MCH_INTERRUPT_REGISTER_BASE 0x020a0 +#define MCH_SHARED_REGISTER_BASE 0x00000 +#define MCH_PIPE_AND_PORT_REGISTER_BASE 0x60000 +#define MCH_PLANE_CONTROL_REGISTER_BASE 0x70000 +#define ICH_SHARED_REGISTER_BASE 0x00000 +#define ICH_PORT_REGISTER_BASE 0x60000 + +// PCH - Platform Control Hub - Newer hardware moves from a MCH/ICH based setup +// to a PCH based one, that means anything that used to communicate via (G)MCH +// registers needs to use different ones on PCH based platforms (Ironlake and +// up, SandyBridge, etc.). +#define PCH_DE_INTERRUPT_REGISTER_BASE 0x44000 +#define PCH_NORTH_SHARED_REGISTER_BASE 0x40000 +#define PCH_NORTH_PIPE_AND_PORT_REGISTER_BASE 0x60000 +#define PCH_NORTH_PLANE_CONTROL_REGISTER_BASE 0x70000 +#define PCH_SOUTH_SHARED_REGISTER_BASE 0xc0000 +#define PCH_SOUTH_TRANSCODER_AND_PORT_REGISTER_BASE 0xe0000 + + struct DeviceType { uint32 type; @@ -114,6 +151,7 @@ struct intel_shared_info { uint32 dpms_mode; area_id registers_area; // area of memory mapped registers + uint32 register_blocks[REGISTER_BLOCK_COUNT]; uint8* status_page; phys_addr_t physical_status_page; uint8* graphics_memory; @@ -221,58 +259,6 @@ struct intel_free_graphics_memory { #define G4X_STOLEN_MEMORY_224MB 0xc0 #define G4X_STOLEN_MEMORY_352MB 0xd0 -// PCH - Platform Control Hub - Newer hardware moves from a MCH/ICH based setup -// to a PCH based one, that means anything that used to communicate via (G)MCH -// registers needs to use different ones on PCH based platforms (Ironlake and -// up, SandyBridge, etc.). - -// North Shared Functions -#define PCH_DE_POWER_MEASUREMENT 0x42400 -#define PCH_DE_INTERRUPT_STATUS 0x44000 // INTEL_INTERRUPT_STATUS -#define PCH_DE_INTERRUPT_MASK 0x44004 // INTEL_INTERRUPT_MASK -#define PCH_DE_INTERRUPT_IDENTITY 0x44008 // INTEL_INTERRUPT_IDENTITY -#define PCH_DE_INTERRUPT_ENABLED 0x4400c // INTEL_INTERRUPT_ENABLED -#define PCH_DISPLAY_A_PALETTE 0x4a000 // INTEL_DISPLAY_A_PALETTE -#define PCH_DISPLAY_B_PALETTE 0x4a800 // INTEL_DISPLAY_B_PALETTE - -#define PCH_INTERRUPT_VBLANK_PIPEA (1 << 7) -#define PCH_INTERRUPT_VBLANK_PIPEB (1 << 15) - -// South Shared Functions -#define PCH_I2C_IO_A 0xc5010 // INTEL_I2C_IO_A -#define PCH_I2C_IO_C 0xc5018 // INTEL_I2C_IO_C -#define PCH_DISPLAY_A_PLL 0xc6014 // INTEL_DISPLAY_A_PLL -#define PCH_DISPLAY_B_PLL 0xc6018 // INTEL_DISPLAY_B_PLL -#define PCH_DISPLAY_A_PLL_DIVISOR_0 0xc6040 // INTEL_DISPLAY_A_PLL_DIVISOR_0 -#define PCH_DISPLAY_A_PLL_DIVISOR_1 0xc6044 // INTEL_DISPLAY_A_PLL_DIVISOR_1 -#define PCH_DISPLAY_B_PLL_DIVISOR_0 0xc6048 // INTEL_DISPLAY_B_PLL_DIVISOR_0 -#define PCH_DISPLAY_B_PLL_DIVISOR_1 0xc604c // INTEL_DISPLAY_B_PLL_DIVISOR_1 -#define PCH_PANEL_CONTROL 0xc7200 // INTEL_PANEL_CONTROL -#define PCH_PANEL_STATUS 0xc7204 // INTEL_PANEL_STATUS - -#define PANEL_REGISTER_UNLOCK (0xabcd << 16) - -// South Display Engine (SDE) Transcoder and Port Controls -#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_TRANSCODER_A_HTOTAL 0xe0000 // INTEL_DISPLAY_A_HTOTAL -#define PCH_TRANSCODER_A_HBLANK 0xe0004 // INTEL_DISPLAY_A_HBLANK -#define PCH_TRANSCODER_A_HSYNC 0xe0008 // INTEL_DISPLAY_A_HSYNC -#define PCH_TRANSCODER_A_VTOTAL 0xe000c // INTEL_DISPLAY_A_VTOTAL -#define PCH_TRANSCODER_A_VBLANK 0xe0010 // INTEL_DISPLAY_A_VBLANK -#define PCH_TRANSCODER_A_VSYNC 0xe0014 // INTEL_DISPLAY_A_VSYNC -#define PCH_TRANSCODER_B_HTOTAL 0xe1000 // INTEL_DISPLAY_B_HTOTAL -#define PCH_TRANSCODER_B_HBLANK 0xe1004 // INTEL_DISPLAY_B_HBLANK -#define PCH_TRANSCODER_B_HSYNC 0xe1008 // INTEL_DISPLAY_B_HSYNC -#define PCH_TRANSCODER_B_VTOTAL 0xe100c // INTEL_DISPLAY_B_VTOTAL -#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 @@ -326,13 +312,6 @@ struct intel_free_graphics_memory { #define GTT_ENTRY_LOCAL_MEMORY 0x02 #define GTT_PAGE_SHIFT 12 -// interrupts -#define INTEL_INTERRUPT_ENABLED 0x020a0 -#define INTEL_INTERRUPT_IDENTITY 0x020a4 -#define INTEL_INTERRUPT_MASK 0x020a8 -#define INTEL_INTERRUPT_STATUS 0x020ac -#define INTERRUPT_VBLANK_PIPEA (1 << 7) -#define INTERRUPT_VBLANK_PIPEB (1 << 5) // ring buffer #define INTEL_PRIMARY_RING_BUFFER 0x02030 @@ -347,8 +326,19 @@ struct intel_free_graphics_memory { #define INTEL_RING_BUFFER_HEAD_MASK 0x001ffffc #define INTEL_RING_BUFFER_ENABLED 1 +// interrupts +#define INTEL_INTERRUPT_ENABLED (0x0000 | REGS_INTERRUPT) +#define INTEL_INTERRUPT_IDENTITY (0x0004 | REGS_INTERRUPT) +#define INTEL_INTERRUPT_MASK (0x0008 | REGS_INTERRUPT) +#define INTEL_INTERRUPT_STATUS (0x000c | REGS_INTERRUPT) +#define INTERRUPT_VBLANK_PIPEA (1 << 7) +#define INTERRUPT_VBLANK_PIPEB (1 << 5) +// TODO: verify that these are actually different on older versions +#define PCH_INTERRUPT_VBLANK_PIPEA (1 << 7) +#define PCH_INTERRUPT_VBLANK_PIPEB (1 << 15) + // display ports -#define INTEL_DISPLAY_A_ANALOG_PORT 0x61100 +#define INTEL_DISPLAY_A_ANALOG_PORT (0x1100 | REGS_SOUTH_TRANSCODER_PORT) #define DISPLAY_MONITOR_PORT_ENABLED (1UL << 31) #define DISPLAY_MONITOR_PIPE_B (1UL << 30) #define DISPLAY_MONITOR_VGA_POLARITY (1UL << 15) @@ -360,9 +350,9 @@ struct intel_free_graphics_memory { #define DISPLAY_MONITOR_POLARITY_MASK (3UL << 3) #define DISPLAY_MONITOR_POSITIVE_HSYNC (1UL << 3) #define DISPLAY_MONITOR_POSITIVE_VSYNC (2UL << 3) -#define INTEL_DISPLAY_A_DIGITAL_PORT 0x61120 -#define INTEL_DISPLAY_C_DIGITAL 0x61160 -#define INTEL_DISPLAY_LVDS_PORT 0x61180 +#define INTEL_DISPLAY_A_DIGITAL_PORT (0x1120 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_C_DIGITAL (0x1160 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_LVDS_PORT (0x1180 | REGS_SOUTH_TRANSCODER_PORT) #define LVDS_POST2_RATE_SLOW 14 // PLL Divisors #define LVDS_POST2_RATE_FAST 7 #define LVDS_CLKB_POWER_MASK (3 << 4) @@ -399,21 +389,51 @@ struct intel_free_graphics_memory { #define DISPLAY_PLL_M2_DIVISOR_SHIFT 0 #define DISPLAY_PLL_PULSE_PHASE_SHIFT 9 -// display A -#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 +// display +#define INTEL_DISPLAY_A_HTOTAL (0x0000 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_A_HBLANK (0x0004 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_A_HSYNC (0x0008 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_A_VTOTAL (0x000c | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_A_VBLANK (0x0010 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_A_VSYNC (0x0014 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_A_IMAGE_SIZE (0x001c | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_B_HTOTAL (0x1000 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_B_HBLANK (0x1004 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_B_HSYNC (0x1008 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_B_VTOTAL (0x100c | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_B_VBLANK (0x1010 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_B_VSYNC (0x1014 | REGS_SOUTH_TRANSCODER_PORT) +#define INTEL_DISPLAY_B_IMAGE_SIZE (0x101c | REGS_SOUTH_TRANSCODER_PORT) + +#define INTEL_DISPLAY_B_DIGITAL_PORT (0x1140 | REGS_SOUTH_TRANSCODER_PORT) + +// planes +#define INTEL_DISPLAY_A_PIPE_CONTROL (0x0008 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_PIPE_CONTROL (0x1008 | REGS_NORTH_PLANE_CONTROL) +#define DISPLAY_PIPE_ENABLED (1UL << 31) + +#define INTEL_DISPLAY_A_PIPE_STATUS (0x0024 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_PIPE_STATUS (0x1024 | REGS_NORTH_PLANE_CONTROL) +#define DISPLAY_PIPE_VBLANK_ENABLED (1UL << 17) +#define DISPLAY_PIPE_VBLANK_STATUS (1UL << 1) + +#define INTEL_DISPLAY_A_CONTROL (0x0180 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_A_BASE (0x0184 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_A_BYTES_PER_ROW (0x0188 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_A_POS (0x018c | REGS_NORTH_PLANE_CONTROL) + // reserved on A +#define INTEL_DISPLAY_A_PIPE_SIZE (0x0190 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_A_SURFACE (0x019c | REGS_NORTH_PLANE_CONTROL) + // i965 and up only + +#define INTEL_DISPLAY_B_CONTROL (0x1180 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_BASE (0x1184 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_BYTES_PER_ROW (0x1188 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_POS (0x118c | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_PIPE_SIZE (0x1190 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_SURFACE (0x119c | REGS_NORTH_PLANE_CONTROL) + // i965 and up only -#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) #define DISPLAY_CONTROL_COLOR_MASK (0x0fUL << 26) @@ -422,51 +442,64 @@ struct intel_free_graphics_memory { #define DISPLAY_CONTROL_RGB16 (5UL << 26) #define DISPLAY_CONTROL_RGB32 (6UL << 26) +// cursors +#define INTEL_CURSOR_CONTROL (0x0080 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_CURSOR_BASE (0x0084 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_CURSOR_POSITION (0x0088 | REGS_NORTH_PLANE_CONTROL) +#define INTEL_CURSOR_PALETTE (0x0090 | REGS_NORTH_PLANE_CONTROL) + // (- 0x009f) +#define INTEL_CURSOR_SIZE (0x00a0 | REGS_NORTH_PLANE_CONTROL) +#define CURSOR_ENABLED (1UL << 31) +#define CURSOR_FORMAT_2_COLORS (0UL << 24) +#define CURSOR_FORMAT_3_COLORS (1UL << 24) +#define CURSOR_FORMAT_4_COLORS (2UL << 24) +#define CURSOR_FORMAT_ARGB (4UL << 24) +#define CURSOR_FORMAT_XRGB (5UL << 24) +#define CURSOR_POSITION_NEGATIVE 0x8000 +#define CURSOR_POSITION_MASK 0x3fff + +// palette registers +#define INTEL_DISPLAY_A_PALETTE (0xa000 | REGS_NORTH_SHARED) +#define INTEL_DISPLAY_B_PALETTE (0xa800 | REGS_NORTH_SHARED) + +// PLL registers +#define INTEL_DISPLAY_A_PLL (0x6014 | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_B_PLL (0x6018 | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_A_PLL_MULTIPLIER_DIVISOR \ + (0x601c | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_B_PLL_MULTIPLIER_DIVISOR \ + (0x6020 | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_A_PLL_DIVISOR_0 (0x6040 | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_A_PLL_DIVISOR_1 (0x6044 | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_B_PLL_DIVISOR_0 (0x6048 | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_B_PLL_DIVISOR_1 (0x604c | REGS_SOUTH_SHARED) + +// i2c +#define INTEL_I2C_IO_A (0x5010 | REGS_SOUTH_SHARED) +#define INTEL_I2C_IO_B (0x5014 | REGS_SOUTH_SHARED) +#define INTEL_I2C_IO_C (0x5018 | REGS_SOUTH_SHARED) +#define INTEL_I2C_IO_D (0x501c | REGS_SOUTH_SHARED) +#define INTEL_I2C_IO_E (0x5020 | REGS_SOUTH_SHARED) +#define INTEL_I2C_IO_F (0x5024 | REGS_SOUTH_SHARED) +#define INTEL_I2C_IO_G (0x5028 | REGS_SOUTH_SHARED) +#define INTEL_I2C_IO_H (0x502c | REGS_SOUTH_SHARED) + +#define I2C_CLOCK_DIRECTION_MASK (1 << 0) +#define I2C_CLOCK_DIRECTION_OUT (1 << 1) +#define I2C_CLOCK_VALUE_MASK (1 << 2) +#define I2C_CLOCK_VALUE_OUT (1 << 3) +#define I2C_CLOCK_VALUE_IN (1 << 4) +#define I2C_DATA_DIRECTION_MASK (1 << 8) +#define I2C_DATA_DIRECTION_OUT (1 << 9) +#define I2C_DATA_VALUE_MASK (1 << 10) +#define I2C_DATA_VALUE_OUT (1 << 11) +#define I2C_DATA_VALUE_IN (1 << 12) +#define I2C_RESERVED ((1 << 13) | (1 << 5)) + +// TODO: on IronLake this is in the north shared block at 0x41000 #define INTEL_VGA_DISPLAY_CONTROL 0x71400 #define VGA_DISPLAY_DISABLED (1UL << 31) -#define INTEL_DISPLAY_A_PALETTE 0x0a000 - -#define INTEL_DISPLAY_A_PIPE_CONTROL 0x70008 -#define DISPLAY_PIPE_ENABLED (1UL << 31) -#define INTEL_DISPLAY_A_PIPE_STATUS 0x70024 -#define DISPLAY_PIPE_VBLANK_ENABLED (1UL << 17) -#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 - -// display B -#define INTEL_DISPLAY_B_HTOTAL 0x61000 -#define INTEL_DISPLAY_B_HBLANK 0x61004 -#define INTEL_DISPLAY_B_HSYNC 0x61008 -#define INTEL_DISPLAY_B_VTOTAL 0x6100c -#define INTEL_DISPLAY_B_VBLANK 0x61010 -#define INTEL_DISPLAY_B_VSYNC 0x61014 - -#define INTEL_DISPLAY_B_DIGITAL_PORT 0x61140 -#define INTEL_DISPLAY_B_PIPE_SIZE 0x71190 - -#define INTEL_DISPLAY_B_PIPE_CONTROL 0x71008 -#define INTEL_DISPLAY_B_PIPE_STATUS 0x71024 - -#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_IMAGE_SIZE 0x6101c -#define INTEL_DISPLAY_B_SURFACE 0x7119c // i965 and up only - -#define INTEL_DISPLAY_B_PALETTE 0x0a800 - -#define INTEL_DISPLAY_B_PLL 0x06018 -#define INTEL_DISPLAY_B_PLL_MULTIPLIER_DIVISOR 0x06020 -#define INTEL_DISPLAY_B_PLL_DIVISOR_0 0x06048 -#define INTEL_DISPLAY_B_PLL_DIVISOR_1 0x0604c - // LVDS panel #define INTEL_PANEL_STATUS 0x61200 #define PANEL_STATUS_POWER_ON (1UL << 31) @@ -475,20 +508,12 @@ struct intel_free_graphics_memory { #define INTEL_PANEL_FIT_CONTROL 0x61230 #define INTEL_PANEL_FIT_RATIOS 0x61234 -// cursor -#define INTEL_CURSOR_CONTROL 0x70080 -#define INTEL_CURSOR_BASE 0x70084 -#define INTEL_CURSOR_POSITION 0x70088 -#define INTEL_CURSOR_PALETTE 0x70090 // (- 0x7009f) -#define INTEL_CURSOR_SIZE 0x700a0 -#define CURSOR_ENABLED (1UL << 31) -#define CURSOR_FORMAT_2_COLORS (0UL << 24) -#define CURSOR_FORMAT_3_COLORS (1UL << 24) -#define CURSOR_FORMAT_4_COLORS (2UL << 24) -#define CURSOR_FORMAT_ARGB (4UL << 24) -#define CURSOR_FORMAT_XRGB (5UL << 24) -#define CURSOR_POSITION_NEGATIVE 0x8000 -#define CURSOR_POSITION_MASK 0x3fff +// LVDS on IronLake and up +#define PCH_PANEL_CONTROL 0xc7200 +#define PCH_PANEL_STATUS 0xc7204 +#define PANEL_REGISTER_UNLOCK (0xabcd << 16) +#define PCH_LVDS_DETECTED (1 << 1) + // ring buffer commands @@ -519,31 +544,7 @@ struct intel_free_graphics_memory { #define COMMAND_MODE_RGB16 0x01 #define COMMAND_MODE_RGB32 0x03 -// i2c - -#define INTEL_I2C_IO_A 0x5010 -#define INTEL_I2C_IO_B 0x5014 -#define INTEL_I2C_IO_C 0x5018 -#define INTEL_I2C_IO_D 0x501c -#define INTEL_I2C_IO_E 0x5020 -#define INTEL_I2C_IO_F 0x5024 -#define INTEL_I2C_IO_G 0x5028 -#define INTEL_I2C_IO_H 0x502c - -#define I2C_CLOCK_DIRECTION_MASK (1 << 0) -#define I2C_CLOCK_DIRECTION_OUT (1 << 1) -#define I2C_CLOCK_VALUE_MASK (1 << 2) -#define I2C_CLOCK_VALUE_OUT (1 << 3) -#define I2C_CLOCK_VALUE_IN (1 << 4) -#define I2C_DATA_DIRECTION_MASK (1 << 8) -#define I2C_DATA_DIRECTION_OUT (1 << 9) -#define I2C_DATA_VALUE_MASK (1 << 10) -#define I2C_DATA_VALUE_OUT (1 << 11) -#define I2C_DATA_VALUE_IN (1 << 12) -#define I2C_RESERVED ((1 << 13) | (1 << 5)) - // overlay - #define INTEL_OVERLAY_UPDATE 0x30000 #define INTEL_OVERLAY_TEST 0x30004 #define INTEL_OVERLAY_STATUS 0x30008 diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index a3545ccd80..3d9b0023cf 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -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) { diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index 2b4da8485e..a0216a9115 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -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; } diff --git a/src/add-ons/accelerants/intel_extreme/dpms.cpp b/src/add-ons/accelerants/intel_extreme/dpms.cpp index 37fee355f6..4a4a3beea2 100644 --- a/src/add-ons/accelerants/intel_extreme/dpms.cpp +++ b/src/add-ons/accelerants/intel_extreme/dpms.cpp @@ -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 } diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 6cf97ab5a5..4e09262329 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -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); } } diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp index b867fc95c6..d3321f390a 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp @@ -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); } diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h index 68d851f57f..06956d7e58 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h @@ -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 */ diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index e959216691..34c9fbd216 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -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); diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h index a655ec0b60..906395d4de 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h @@ -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;