1 /* 2 * Copyright 2006, 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 } else { 36 // when disabling it, we have to trigger the update using a write to 37 // the display base address 38 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { 39 write32(INTEL_DISPLAY_A_CONTROL, planeAControl & ~DISPLAY_CONTROL_ENABLED); 40 write32(INTEL_DISPLAY_A_BASE, gInfo->shared_info->frame_buffer_offset); 41 } 42 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { 43 write32(INTEL_DISPLAY_B_CONTROL, planeBControl & ~DISPLAY_CONTROL_ENABLED); 44 write32(INTEL_DISPLAY_B_BASE, gInfo->shared_info->frame_buffer_offset); 45 } 46 } 47 } 48 49 50 static void 51 enable_display_pipe(bool enable) 52 { 53 uint32 pipeAControl = read32(INTEL_DISPLAY_A_PIPE_CONTROL); 54 uint32 pipeBControl = read32(INTEL_DISPLAY_B_PIPE_CONTROL); 55 56 if (enable) { 57 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) 58 write32(INTEL_DISPLAY_A_PIPE_CONTROL, pipeAControl | DISPLAY_PIPE_ENABLED); 59 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) 60 write32(INTEL_DISPLAY_B_PIPE_CONTROL, pipeBControl | DISPLAY_PIPE_ENABLED); 61 } else { 62 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) 63 write32(INTEL_DISPLAY_A_PIPE_CONTROL, pipeAControl & ~DISPLAY_PIPE_ENABLED); 64 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) 65 write32(INTEL_DISPLAY_B_PIPE_CONTROL, pipeBControl & ~DISPLAY_PIPE_ENABLED); 66 } 67 } 68 69 70 void 71 set_display_power_mode(uint32 mode) 72 { 73 uint32 monitorMode = 0; 74 75 if (mode == B_DPMS_ON) { 76 enable_display_pipe(true); 77 enable_display_plane(true); 78 } 79 80 wait_for_vblank(); 81 82 switch (mode) { 83 case B_DPMS_ON: 84 monitorMode = DISPLAY_MONITOR_ON; 85 break; 86 case B_DPMS_SUSPEND: 87 monitorMode = DISPLAY_MONITOR_SUSPEND; 88 break; 89 case B_DPMS_STAND_BY: 90 monitorMode = DISPLAY_MONITOR_STAND_BY; 91 break; 92 case B_DPMS_OFF: 93 monitorMode = DISPLAY_MONITOR_OFF; 94 break; 95 } 96 97 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { 98 write32(INTEL_DISPLAY_A_ANALOG_PORT, (read32(INTEL_DISPLAY_A_ANALOG_PORT) 99 & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) 100 | monitorMode | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); 101 } 102 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { 103 write32(INTEL_DISPLAY_B_DIGITAL_PORT, (read32(INTEL_DISPLAY_B_DIGITAL_PORT) 104 & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) 105 | monitorMode | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); 106 } 107 108 if (mode != B_DPMS_ON) { 109 enable_display_plane(false); 110 enable_display_pipe(false); 111 } 112 } 113 114 115 // #pragma mark - 116 117 118 uint32 119 intel_dpms_capabilities(void) 120 { 121 TRACE(("intel_dpms_capabilities()\n")); 122 return B_DPMS_ON | B_DPMS_SUSPEND | B_DPMS_STAND_BY | B_DPMS_OFF; 123 } 124 125 126 uint32 127 intel_dpms_mode(void) 128 { 129 TRACE(("intel_dpms_mode()\n")); 130 return gInfo->shared_info->dpms_mode; 131 } 132 133 134 status_t 135 intel_set_dpms_mode(uint32 mode) 136 { 137 TRACE(("intel_set_dpms_mode()\n")); 138 gInfo->shared_info->dpms_mode = mode; 139 set_display_power_mode(mode); 140 141 return B_OK; 142 } 143 144