1 /* 2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include "accelerant_protos.h" 11 #include "accelerant.h" 12 13 14 #undef TRACE 15 //#define TRACE_DPMS 16 #ifdef TRACE_DPMS 17 # define TRACE(x...) _sPrintf("intel_extreme: " x) 18 #else 19 # define TRACE(x...) 20 #endif 21 22 #define ERROR(x...) _sPrintf("intel_extreme: " x) 23 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 24 25 26 static void 27 enable_all_pipes(bool enable) 28 { 29 // Go over each port and enable pipe/plane 30 for (uint32 i = 0; i < gInfo->port_count; i++) { 31 if (gInfo->ports[i] == NULL) 32 continue; 33 if (!gInfo->ports[i]->IsConnected()) 34 continue; 35 if (gInfo->ports[i]->GetPipe() == NULL) 36 continue; 37 38 gInfo->ports[i]->Power(enable); 39 } 40 41 read32(INTEL_DISPLAY_A_BASE); 42 // flush the possibly cached PCI bus writes 43 44 set_frame_buffer_base(); 45 } 46 47 48 static void 49 enable_lvds_panel(bool enable) 50 { 51 bool hasPCH = (gInfo->shared_info->pch_info != INTEL_PCH_NONE); 52 53 int controlRegister = hasPCH ? PCH_PANEL_CONTROL : INTEL_PANEL_CONTROL; 54 int statusRegister = hasPCH ? PCH_PANEL_STATUS : INTEL_PANEL_STATUS; 55 56 uint32 control = read32(controlRegister); 57 uint32 panelStatus; 58 59 if (enable) { 60 if ((control & PANEL_CONTROL_POWER_TARGET_ON) == 0) { 61 write32(controlRegister, control | PANEL_CONTROL_POWER_TARGET_ON 62 /*| (hasPCH ? PANEL_REGISTER_UNLOCK : 0)*/); 63 } 64 65 if (!hasPCH) { 66 do { 67 panelStatus = read32(statusRegister); 68 } while ((panelStatus & PANEL_STATUS_POWER_ON) == 0); 69 } 70 } else { 71 if ((control & PANEL_CONTROL_POWER_TARGET_ON) != 0) { 72 write32(controlRegister, (control & ~PANEL_CONTROL_POWER_TARGET_ON) 73 /*| (hasPCH ? PANEL_REGISTER_UNLOCK : 0)*/); 74 } 75 76 if (!hasPCH) 77 { 78 do { 79 panelStatus = read32(statusRegister); 80 } while ((panelStatus & PANEL_STATUS_POWER_ON) != 0); 81 } 82 } 83 } 84 85 86 void 87 set_display_power_mode(uint32 mode) 88 { 89 uint32 monitorMode = 0; 90 91 if (mode == B_DPMS_ON) { 92 uint32 pll = read32(INTEL_DISPLAY_A_PLL); 93 if ((pll & DISPLAY_PLL_ENABLED) == 0) { 94 // reactivate PLL 95 write32(INTEL_DISPLAY_A_PLL, pll); 96 read32(INTEL_DISPLAY_A_PLL); 97 spin(150); 98 write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); 99 read32(INTEL_DISPLAY_A_PLL); 100 spin(150); 101 write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); 102 read32(INTEL_DISPLAY_A_PLL); 103 spin(150); 104 } 105 106 pll = read32(INTEL_DISPLAY_B_PLL); 107 if ((pll & DISPLAY_PLL_ENABLED) == 0) { 108 // reactivate PLL 109 write32(INTEL_DISPLAY_B_PLL, pll); 110 read32(INTEL_DISPLAY_B_PLL); 111 spin(150); 112 write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED); 113 read32(INTEL_DISPLAY_B_PLL); 114 spin(150); 115 write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED); 116 read32(INTEL_DISPLAY_B_PLL); 117 spin(150); 118 } 119 120 enable_all_pipes(true); 121 } 122 123 wait_for_vblank(); 124 125 switch (mode) { 126 case B_DPMS_ON: 127 monitorMode = DISPLAY_MONITOR_ON; 128 break; 129 case B_DPMS_SUSPEND: 130 monitorMode = DISPLAY_MONITOR_SUSPEND; 131 break; 132 case B_DPMS_STAND_BY: 133 monitorMode = DISPLAY_MONITOR_STAND_BY; 134 break; 135 case B_DPMS_OFF: 136 monitorMode = DISPLAY_MONITOR_OFF; 137 break; 138 } 139 140 //fixme: port DPMS programming should better be in Ports.cpp. Resetup.. 141 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { 142 write32(INTEL_ANALOG_PORT, (read32(INTEL_ANALOG_PORT) 143 & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) 144 | monitorMode 145 | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); 146 } 147 148 //fixme: port DPMS programming should better be in Ports.cpp and is faulty. Resetup.. 149 if (false) {//gInfo->head_mode & HEAD_MODE_B_DIGITAL) { 150 write32(INTEL_DIGITAL_PORT_B, (read32(INTEL_DIGITAL_PORT_B) 151 & ~(/*DISPLAY_MONITOR_MODE_MASK |*/ DISPLAY_MONITOR_PORT_ENABLED)) 152 | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); 153 // TODO: monitorMode? 154 } 155 156 if (mode != B_DPMS_ON) 157 enable_all_pipes(false); 158 159 if (mode == B_DPMS_OFF) { 160 write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL) 161 | DISPLAY_PLL_ENABLED); 162 write32(INTEL_DISPLAY_B_PLL, read32(INTEL_DISPLAY_B_PLL) 163 | DISPLAY_PLL_ENABLED); 164 165 read32(INTEL_DISPLAY_B_PLL); 166 // flush the possibly cached PCI bus writes 167 168 spin(150); 169 } 170 171 if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0) 172 enable_lvds_panel(mode == B_DPMS_ON); 173 174 read32(INTEL_DISPLAY_A_BASE); 175 // flush the possibly cached PCI bus writes 176 } 177 178 179 // #pragma mark - 180 181 182 uint32 183 intel_dpms_capabilities(void) 184 { 185 CALLED(); 186 return B_DPMS_ON | B_DPMS_SUSPEND | B_DPMS_STAND_BY | B_DPMS_OFF; 187 } 188 189 190 uint32 191 intel_dpms_mode(void) 192 { 193 CALLED(); 194 return gInfo->shared_info->dpms_mode; 195 } 196 197 198 status_t 199 intel_set_dpms_mode(uint32 mode) 200 { 201 CALLED(); 202 gInfo->shared_info->dpms_mode = mode; 203 set_display_power_mode(mode); 204 205 return B_OK; 206 } 207 208