1 /* 2 * Copyright 2011, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz, mmlr@mlotz.ch 7 */ 8 9 10 #include "PanelFitter.h" 11 12 #include <stdlib.h> 13 #include <string.h> 14 #include <Debug.h> 15 16 #include "accelerant.h" 17 #include "intel_extreme.h" 18 19 20 #undef TRACE 21 #define TRACE_FITTER 22 #ifdef TRACE_FITTER 23 # define TRACE(x...) _sPrintf("intel_extreme: " x) 24 #else 25 # define TRACE(x...) 26 #endif 27 28 #define ERROR(x...) _sPrintf("intel_extreme: " x) 29 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 30 31 32 // #pragma mark - PanelFitter 33 34 35 PanelFitter::PanelFitter(pipe_index pipeIndex) 36 : 37 fRegisterBase(PCH_PANEL_FITTER_BASE_REGISTER) 38 { 39 // SkyLake has a newer type of panelfitter, called panelscaler (PS) there 40 if (gInfo->shared_info->device_type.Generation() >= 9) { 41 fRegisterBase += 0x100; 42 } 43 if (pipeIndex == INTEL_PIPE_B) { 44 fRegisterBase += PCH_PANEL_FITTER_PIPE_OFFSET; 45 } 46 if (pipeIndex == INTEL_PIPE_C) { 47 fRegisterBase += 2 * PCH_PANEL_FITTER_PIPE_OFFSET; 48 } 49 TRACE("%s: requested fitter #%d\n", __func__, (int)pipeIndex); 50 51 uint32 fitCtl = read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL); 52 if (fitCtl & PANEL_FITTER_ENABLED) { 53 if (gInfo->shared_info->device_type.Generation() <= 8) { 54 TRACE("%s: this fitter is connected to pipe #%" B_PRIx32 "\n", __func__, 55 ((fitCtl & PANEL_FITTER_PIPE_MASK) >> 29) + 1); 56 } else { 57 TRACE("%s: this fitter is enabled by the BIOS\n", __func__); 58 } 59 } else { 60 TRACE("%s: this fitter is not setup by the BIOS: Enabling.\n", __func__); 61 fitCtl |= PANEL_FITTER_ENABLED; 62 write32(fRegisterBase + PCH_PANEL_FITTER_CONTROL, fitCtl); 63 } 64 } 65 66 67 PanelFitter::~PanelFitter() 68 { 69 } 70 71 72 bool 73 PanelFitter::IsEnabled() 74 { 75 return (read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL) 76 & PANEL_FITTER_ENABLED) != 0; 77 } 78 79 80 void 81 PanelFitter::Enable(const display_timing& timing) 82 { 83 _Enable(true); 84 85 // TODO: program the window position based on the mode, setup/select filter 86 // Note: for now assuming fitter was setup by BIOS and pipeA has fitterA, etc. 87 TRACE("%s: PCH_PANEL_FITTER_CONTROL, 0x%" B_PRIx32 "\n", __func__, read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL)); 88 TRACE("%s: PCH_PANEL_FITTER_WINDOW_POS, 0x%" B_PRIx32 "\n", __func__, read32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_POS)); 89 90 // Window size _must_ be the last register programmed as it 'arms'/unlocks all the other ones.. 91 write32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_SIZE, (timing.h_display << 16) | timing.v_display); 92 } 93 94 95 void 96 PanelFitter::Disable() 97 { 98 _Enable(false); 99 100 // Window size _must_ be the last register programmed as it 'arms'/unlocks all the other ones.. 101 write32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_SIZE, 0); 102 } 103 104 105 void 106 PanelFitter::_Enable(bool enable) 107 { 108 uint32 targetRegister = fRegisterBase + PCH_PANEL_FITTER_CONTROL; 109 write32(targetRegister, (read32(targetRegister) & ~PANEL_FITTER_ENABLED) 110 | (enable ? PANEL_FITTER_ENABLED : 0)); 111 read32(targetRegister); 112 } 113