1 /* 2 * Copyright 2006-2007, 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 //#define TRACE_DPMS 15 #ifdef TRACE_DPMS 16 extern "C" void _sPrintf(const char *format, ...); 17 # define TRACE(x) _sPrintf x 18 #else 19 # define TRACE(x) ; 20 #endif 21 22 23 void 24 enable_display_plane(bool enable) 25 { 26 uint32 planeAControl = read32(INTEL_DISPLAY_A_CONTROL); 27 uint32 planeBControl = read32(INTEL_DISPLAY_B_CONTROL); 28 29 if (enable) { 30 // when enabling the display, the register values are updated automatically 31 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) 32 write32(INTEL_DISPLAY_A_CONTROL, planeAControl | DISPLAY_CONTROL_ENABLED); 33 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) 34 write32(INTEL_DISPLAY_B_CONTROL, planeBControl | DISPLAY_CONTROL_ENABLED); 35 36 read32(INTEL_DISPLAY_A_BASE); 37 // flush the eventually cached PCI bus writes 38 } else { 39 // when disabling it, we have to trigger the update using a write to 40 // the display base address 41 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) 42 write32(INTEL_DISPLAY_A_CONTROL, planeAControl & ~DISPLAY_CONTROL_ENABLED); 43 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) 44 write32(INTEL_DISPLAY_B_CONTROL, planeBControl & ~DISPLAY_CONTROL_ENABLED); 45 46 set_frame_buffer_base(); 47 } 48 } 49 50 51 static void 52 enable_display_pipe(bool enable) 53 { 54 uint32 pipeAControl = read32(INTEL_DISPLAY_A_PIPE_CONTROL); 55 uint32 pipeBControl = read32(INTEL_DISPLAY_B_PIPE_CONTROL); 56 57 if (enable) { 58 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) 59 write32(INTEL_DISPLAY_A_PIPE_CONTROL, pipeAControl | DISPLAY_PIPE_ENABLED); 60 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) 61 write32(INTEL_DISPLAY_B_PIPE_CONTROL, pipeBControl | DISPLAY_PIPE_ENABLED); 62 } else { 63 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) 64 write32(INTEL_DISPLAY_A_PIPE_CONTROL, pipeAControl & ~DISPLAY_PIPE_ENABLED); 65 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) 66 write32(INTEL_DISPLAY_B_PIPE_CONTROL, pipeBControl & ~DISPLAY_PIPE_ENABLED); 67 } 68 69 read32(INTEL_DISPLAY_A_BASE); 70 // flush the eventually cached PCI bus writes 71 } 72 73 74 void 75 set_display_power_mode(uint32 mode) 76 { 77 uint32 monitorMode = 0; 78 79 if (mode == B_DPMS_ON) { 80 uint32 pll = read32(INTEL_DISPLAY_A_PLL); 81 if ((pll & DISPLAY_PLL_ENABLED) == 0) { 82 // reactivate PLL 83 write32(INTEL_DISPLAY_A_PLL, pll); 84 read32(INTEL_DISPLAY_A_PLL); 85 spin(150); 86 write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); 87 read32(INTEL_DISPLAY_A_PLL); 88 spin(150); 89 write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); 90 read32(INTEL_DISPLAY_A_PLL); 91 spin(150); 92 } 93 94 enable_display_pipe(true); 95 enable_display_plane(true); 96 } 97 98 wait_for_vblank(); 99 100 switch (mode) { 101 case B_DPMS_ON: 102 monitorMode = DISPLAY_MONITOR_ON; 103 break; 104 case B_DPMS_SUSPEND: 105 monitorMode = DISPLAY_MONITOR_SUSPEND; 106 break; 107 case B_DPMS_STAND_BY: 108 monitorMode = DISPLAY_MONITOR_STAND_BY; 109 break; 110 case B_DPMS_OFF: 111 monitorMode = DISPLAY_MONITOR_OFF; 112 break; 113 } 114 115 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { 116 write32(INTEL_DISPLAY_A_ANALOG_PORT, (read32(INTEL_DISPLAY_A_ANALOG_PORT) 117 & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) 118 | monitorMode | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); 119 } 120 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { 121 write32(INTEL_DISPLAY_B_DIGITAL_PORT, (read32(INTEL_DISPLAY_B_DIGITAL_PORT) 122 & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) 123 | monitorMode | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); 124 } 125 126 if (mode != B_DPMS_ON) { 127 enable_display_plane(false); 128 wait_for_vblank(); 129 enable_display_pipe(false); 130 } 131 132 if (mode == B_DPMS_OFF) { 133 write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL) | DISPLAY_PLL_ENABLED); 134 read32(INTEL_DISPLAY_A_PLL); 135 spin(150); 136 } 137 138 read32(INTEL_DISPLAY_A_BASE); 139 // flush the eventually cached PCI bus writes 140 } 141 142 143 // #pragma mark - 144 145 146 uint32 147 intel_dpms_capabilities(void) 148 { 149 TRACE(("intel_dpms_capabilities()\n")); 150 return B_DPMS_ON | B_DPMS_SUSPEND | B_DPMS_STAND_BY | B_DPMS_OFF; 151 } 152 153 154 uint32 155 intel_dpms_mode(void) 156 { 157 TRACE(("intel_dpms_mode()\n")); 158 return gInfo->shared_info->dpms_mode; 159 } 160 161 162 status_t 163 intel_set_dpms_mode(uint32 mode) 164 { 165 TRACE(("intel_set_dpms_mode()\n")); 166 gInfo->shared_info->dpms_mode = mode; 167 set_display_power_mode(mode); 168 169 return B_OK; 170 } 171 172