vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / intel_extreme / dpms.cpp
blob474984d2cb64126fc99966df7500a6c908eba704
1 /*
2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
10 #include "accelerant_protos.h"
11 #include "accelerant.h"
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
22 #define ERROR(x...) _sPrintf("intel_extreme: " x)
23 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
26 static void
27 enable_all_pipes(bool enable)
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;
36 gInfo->ports[i]->Power(enable);
39 read32(INTEL_DISPLAY_A_BASE);
40 // flush the possibly cached PCI bus writes
42 set_frame_buffer_base();
46 static void
47 enable_lvds_panel(bool enable)
49 bool hasPCH = (gInfo->shared_info->pch_info != INTEL_PCH_NONE);
51 int controlRegister = hasPCH ? PCH_PANEL_CONTROL : INTEL_PANEL_CONTROL;
52 int statusRegister = hasPCH ? PCH_PANEL_STATUS : INTEL_PANEL_STATUS;
54 uint32 control = read32(controlRegister);
55 uint32 panelStatus;
57 if (enable) {
58 if ((control & PANEL_CONTROL_POWER_TARGET_ON) == 0) {
59 write32(controlRegister, control | PANEL_CONTROL_POWER_TARGET_ON
60 /*| (hasPCH ? PANEL_REGISTER_UNLOCK : 0)*/);
63 if (!hasPCH) {
64 do {
65 panelStatus = read32(statusRegister);
66 } while ((panelStatus & PANEL_STATUS_POWER_ON) == 0);
68 } else {
69 if ((control & PANEL_CONTROL_POWER_TARGET_ON) != 0) {
70 write32(controlRegister, (control & ~PANEL_CONTROL_POWER_TARGET_ON)
71 /*| (hasPCH ? PANEL_REGISTER_UNLOCK : 0)*/);
74 if (!hasPCH)
76 do {
77 panelStatus = read32(statusRegister);
78 } while ((panelStatus & PANEL_STATUS_POWER_ON) != 0);
84 void
85 set_display_power_mode(uint32 mode)
87 uint32 monitorMode = 0;
89 if (mode == B_DPMS_ON) {
90 uint32 pll = read32(INTEL_DISPLAY_A_PLL);
91 if ((pll & DISPLAY_PLL_ENABLED) == 0) {
92 // reactivate PLL
93 write32(INTEL_DISPLAY_A_PLL, pll);
94 read32(INTEL_DISPLAY_A_PLL);
95 spin(150);
96 write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
97 read32(INTEL_DISPLAY_A_PLL);
98 spin(150);
99 write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
100 read32(INTEL_DISPLAY_A_PLL);
101 spin(150);
104 pll = read32(INTEL_DISPLAY_B_PLL);
105 if ((pll & DISPLAY_PLL_ENABLED) == 0) {
106 // reactivate PLL
107 write32(INTEL_DISPLAY_B_PLL, pll);
108 read32(INTEL_DISPLAY_B_PLL);
109 spin(150);
110 write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
111 read32(INTEL_DISPLAY_B_PLL);
112 spin(150);
113 write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
114 read32(INTEL_DISPLAY_B_PLL);
115 spin(150);
118 enable_all_pipes(true);
121 wait_for_vblank();
123 switch (mode) {
124 case B_DPMS_ON:
125 monitorMode = DISPLAY_MONITOR_ON;
126 break;
127 case B_DPMS_SUSPEND:
128 monitorMode = DISPLAY_MONITOR_SUSPEND;
129 break;
130 case B_DPMS_STAND_BY:
131 monitorMode = DISPLAY_MONITOR_STAND_BY;
132 break;
133 case B_DPMS_OFF:
134 monitorMode = DISPLAY_MONITOR_OFF;
135 break;
138 if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
139 write32(INTEL_ANALOG_PORT, (read32(INTEL_ANALOG_PORT)
140 & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED))
141 | monitorMode
142 | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0));
145 if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
146 write32(INTEL_DIGITAL_PORT_B, (read32(INTEL_DIGITAL_PORT_B)
147 & ~(/*DISPLAY_MONITOR_MODE_MASK |*/ DISPLAY_MONITOR_PORT_ENABLED))
148 | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0));
149 // TODO: monitorMode?
152 if (mode != B_DPMS_ON)
153 enable_all_pipes(false);
155 if (mode == B_DPMS_OFF) {
156 write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL)
157 | DISPLAY_PLL_ENABLED);
158 write32(INTEL_DISPLAY_B_PLL, read32(INTEL_DISPLAY_B_PLL)
159 | DISPLAY_PLL_ENABLED);
161 read32(INTEL_DISPLAY_B_PLL);
162 // flush the possibly cached PCI bus writes
164 spin(150);
167 if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0)
168 enable_lvds_panel(mode == B_DPMS_ON);
170 read32(INTEL_DISPLAY_A_BASE);
171 // flush the possibly cached PCI bus writes
175 // #pragma mark -
178 uint32
179 intel_dpms_capabilities(void)
181 CALLED();
182 return B_DPMS_ON | B_DPMS_SUSPEND | B_DPMS_STAND_BY | B_DPMS_OFF;
186 uint32
187 intel_dpms_mode(void)
189 CALLED();
190 return gInfo->shared_info->dpms_mode;
194 status_t
195 intel_set_dpms_mode(uint32 mode)
197 CALLED();
198 gInfo->shared_info->dpms_mode = mode;
199 set_display_power_mode(mode);
201 return B_OK;