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\n", __func__); 61 } 62 } 63 64 65 PanelFitter::~PanelFitter() 66 { 67 } 68 69 70 bool 71 PanelFitter::IsEnabled() 72 { 73 return (read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL) 74 & PANEL_FITTER_ENABLED) != 0; 75 } 76 77 78 void 79 PanelFitter::Enable(const display_timing& timing) 80 { 81 _Enable(true); 82 83 // TODO: program the window position based on the mode, setup/select filter 84 // Note: for now assuming fitter was setup by BIOS and pipeA has fitterA, etc. 85 TRACE("%s: PCH_PANEL_FITTER_CONTROL, 0x%" B_PRIx32 "\n", __func__, read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL)); 86 TRACE("%s: PCH_PANEL_FITTER_WINDOW_POS, 0x%" B_PRIx32 "\n", __func__, read32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_POS)); 87 88 // Window size _must_ be the last register programmed as it 'arms'/unlocks all the other ones.. 89 write32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_SIZE, (timing.h_display << 16) | timing.v_display); 90 } 91 92 93 void 94 PanelFitter::Disable() 95 { 96 _Enable(false); 97 98 // Window size _must_ be the last register programmed as it 'arms'/unlocks all the other ones.. 99 write32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_SIZE, 0); 100 } 101 102 103 void 104 PanelFitter::_Enable(bool enable) 105 { 106 uint32 targetRegister = fRegisterBase + PCH_PANEL_FITTER_CONTROL; 107 write32(targetRegister, (read32(targetRegister) & ~PANEL_FITTER_ENABLED) 108 | (enable ? PANEL_FITTER_ENABLED : 0)); 109 read32(targetRegister); 110 } 111