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 35PanelFitter::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 67PanelFitter::~PanelFitter() 68{ 69} 70 71 72bool 73PanelFitter::IsEnabled() 74{ 75 return (read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL) 76 & PANEL_FITTER_ENABLED) != 0; 77} 78 79 80void 81PanelFitter::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 95void 96PanelFitter::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 105void 106PanelFitter::_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