From 96c8657d24845e90e9719f41c9b830007b9e7c68 Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Fri, 17 Sep 2021 23:45:25 +0000 Subject: [PATCH] intel_extreme: fix haswell virt display scroll/pan, ticket #17261 --- .../graphics/intel_extreme/intel_extreme.h | 2 ++ .../accelerants/intel_extreme/mode.cpp | 28 ++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index aa5e636562..e59f6ccc59 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -741,6 +741,7 @@ struct intel_free_graphics_memory { // reserved on A #define INTEL_DISPLAY_A_IMAGE_SIZE (0x0190 | REGS_NORTH_PLANE_CONTROL) #define INTEL_DISPLAY_A_SURFACE (0x019c | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_A_OFFSET_HAS (0x01a4 | REGS_NORTH_PLANE_CONTROL) // i965 and up only #define INTEL_DISPLAY_B_CONTROL (0x1180 | REGS_NORTH_PLANE_CONTROL) @@ -749,6 +750,7 @@ struct intel_free_graphics_memory { #define INTEL_DISPLAY_B_POS (0x118c | REGS_NORTH_PLANE_CONTROL) #define INTEL_DISPLAY_B_IMAGE_SIZE (0x1190 | REGS_NORTH_PLANE_CONTROL) #define INTEL_DISPLAY_B_SURFACE (0x119c | REGS_NORTH_PLANE_CONTROL) +#define INTEL_DISPLAY_B_OFFSET_HAS (0x11a4 | REGS_NORTH_PLANE_CONTROL) // i965 and up only // INTEL_DISPLAY_A_CONTROL source pixel format diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 3c5c051073..b2dea5b7a8 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -111,7 +111,7 @@ sanitize_display_mode(display_mode& mode) static void -set_frame_buffer_registers(uint32 baseRegister, uint32 surfaceRegister) +set_frame_buffer_registers(uint32 offset) { intel_shared_info &sharedInfo = *gInfo->shared_info; display_mode &mode = gInfo->current_mode; @@ -121,16 +121,24 @@ set_frame_buffer_registers(uint32 baseRegister, uint32 surfaceRegister) || sharedInfo.device_type.InGroup(INTEL_GROUP_ILK) || sharedInfo.device_type.InFamily(INTEL_FAMILY_SER5) || sharedInfo.device_type.InFamily(INTEL_FAMILY_SOC0)) { - write32(baseRegister, mode.v_display_start * sharedInfo.bytes_per_row - + mode.h_display_start * (sharedInfo.bits_per_pixel + 7) / 8); - read32(baseRegister); - write32(surfaceRegister, sharedInfo.frame_buffer_offset); - read32(surfaceRegister); + if (sharedInfo.device_type.InGroup(INTEL_GROUP_HAS)) { + write32(INTEL_DISPLAY_A_OFFSET_HAS + offset, + ((uint32)mode.v_display_start << 16) + | (uint32)mode.h_display_start); + read32(INTEL_DISPLAY_A_OFFSET_HAS + offset); + } else { + write32(INTEL_DISPLAY_A_BASE + offset, + mode.v_display_start * sharedInfo.bytes_per_row + + mode.h_display_start * (sharedInfo.bits_per_pixel + 7) / 8); + read32(INTEL_DISPLAY_A_BASE + offset); + } + write32(INTEL_DISPLAY_A_SURFACE + offset, sharedInfo.frame_buffer_offset); + read32(INTEL_DISPLAY_A_SURFACE + offset); } else { - write32(baseRegister, sharedInfo.frame_buffer_offset + write32(INTEL_DISPLAY_A_BASE + offset, sharedInfo.frame_buffer_offset + mode.v_display_start * sharedInfo.bytes_per_row + mode.h_display_start * (sharedInfo.bits_per_pixel + 7) / 8); - read32(baseRegister); + read32(INTEL_DISPLAY_A_BASE + offset); } } @@ -140,8 +148,8 @@ set_frame_buffer_base() { // TODO we always set both displays to the same address. When we support // multiple framebuffers, they should get different addresses here. - set_frame_buffer_registers(INTEL_DISPLAY_A_BASE, INTEL_DISPLAY_A_SURFACE); - set_frame_buffer_registers(INTEL_DISPLAY_B_BASE, INTEL_DISPLAY_B_SURFACE); + set_frame_buffer_registers(0); + set_frame_buffer_registers(INTEL_DISPLAY_OFFSET); }