xref: /haiku/src/add-ons/accelerants/intel_extreme/dpms.cpp (revision 95b7699fe97493b57bd55065cbd7b847dedb91a4)
1e404297eSAxel Dörfler /*
2d7e91d92SAxel Dörfler  * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3e404297eSAxel Dörfler  * Distributed under the terms of the MIT License.
4e404297eSAxel Dörfler  *
5e404297eSAxel Dörfler  * Authors:
6e404297eSAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
7e404297eSAxel Dörfler  */
8e404297eSAxel Dörfler 
9e404297eSAxel Dörfler 
10e404297eSAxel Dörfler #include "accelerant_protos.h"
11e404297eSAxel Dörfler #include "accelerant.h"
12e404297eSAxel Dörfler 
13e404297eSAxel Dörfler 
14881a823eSAlexander von Gluck IV #undef TRACE
15943578b1SAxel Dörfler //#define TRACE_DPMS
16943578b1SAxel Dörfler #ifdef TRACE_DPMS
17be3f7a8fSAlexander von Gluck IV #	define TRACE(x...) _sPrintf("intel_extreme: " x)
18943578b1SAxel Dörfler #else
19881a823eSAlexander von Gluck IV #	define TRACE(x...)
20943578b1SAxel Dörfler #endif
21943578b1SAxel Dörfler 
22be3f7a8fSAlexander von Gluck IV #define ERROR(x...) _sPrintf("intel_extreme: " x)
23881a823eSAlexander von Gluck IV #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
24881a823eSAlexander von Gluck IV 
25943578b1SAxel Dörfler 
26b979c66cSAlexander von Gluck IV static void
enable_all_pipes(bool enable)27b979c66cSAlexander von Gluck IV enable_all_pipes(bool enable)
28e404297eSAxel Dörfler {
29b979c66cSAlexander von Gluck IV 	// Go over each port and enable pipe/plane
30b979c66cSAlexander von Gluck IV 	for (uint32 i = 0; i < gInfo->port_count; i++) {
31b979c66cSAlexander von Gluck IV 		if (gInfo->ports[i] == NULL)
32b979c66cSAlexander von Gluck IV 			continue;
33b979c66cSAlexander von Gluck IV 		if (!gInfo->ports[i]->IsConnected())
34b979c66cSAlexander von Gluck IV 			continue;
350af04dccSRudolf Cornelissen 		if (gInfo->ports[i]->GetPipe() == NULL)
360af04dccSRudolf Cornelissen 			continue;
37e404297eSAxel Dörfler 
38b979c66cSAlexander von Gluck IV 		gInfo->ports[i]->Power(enable);
39c788baedSMichael Lotz 	}
40cbd40810SAxel Dörfler 
41cbd40810SAxel Dörfler 	read32(INTEL_DISPLAY_A_BASE);
42b979c66cSAlexander von Gluck IV 		// flush the possibly cached PCI bus writes
43cbd40810SAxel Dörfler 
44cbd40810SAxel Dörfler 	set_frame_buffer_base();
45a0902420SAxel Dörfler }
46e404297eSAxel Dörfler 
47e404297eSAxel Dörfler 
482d5f339dSAxel Dörfler static void
enable_lvds_panel(bool enable)492d5f339dSAxel Dörfler enable_lvds_panel(bool enable)
502d5f339dSAxel Dörfler {
5192e254d0SAlexander von Gluck IV 	bool hasPCH = (gInfo->shared_info->pch_info != INTEL_PCH_NONE);
52f0468be3SMichael Lotz 
539e2e0d8dSMichael Lotz 	int controlRegister = hasPCH ? PCH_PANEL_CONTROL : INTEL_PANEL_CONTROL;
549e2e0d8dSMichael Lotz 	int statusRegister = hasPCH ? PCH_PANEL_STATUS : INTEL_PANEL_STATUS;
5516cc5977SMichael Lotz 
5616cc5977SMichael Lotz 	uint32 control = read32(controlRegister);
572d5f339dSAxel Dörfler 	uint32 panelStatus;
582d5f339dSAxel Dörfler 
592d5f339dSAxel Dörfler 	if (enable) {
602d5f339dSAxel Dörfler 		if ((control & PANEL_CONTROL_POWER_TARGET_ON) == 0) {
6116cc5977SMichael Lotz 			write32(controlRegister, control | PANEL_CONTROL_POWER_TARGET_ON
62adc0f76eSAdrien Destugues 				/*| (hasPCH ? PANEL_REGISTER_UNLOCK : 0)*/);
632d5f339dSAxel Dörfler 		}
642d5f339dSAxel Dörfler 
65adc0f76eSAdrien Destugues 		if (!hasPCH) {
662d5f339dSAxel Dörfler 			do {
6716cc5977SMichael Lotz 				panelStatus = read32(statusRegister);
682d5f339dSAxel Dörfler 			} while ((panelStatus & PANEL_STATUS_POWER_ON) == 0);
69adc0f76eSAdrien Destugues 		}
702d5f339dSAxel Dörfler 	} else {
712d5f339dSAxel Dörfler 		if ((control & PANEL_CONTROL_POWER_TARGET_ON) != 0) {
7216cc5977SMichael Lotz 			write32(controlRegister, (control & ~PANEL_CONTROL_POWER_TARGET_ON)
73adc0f76eSAdrien Destugues 				/*| (hasPCH ? PANEL_REGISTER_UNLOCK : 0)*/);
742d5f339dSAxel Dörfler 		}
752d5f339dSAxel Dörfler 
76adc0f76eSAdrien Destugues 		if (!hasPCH)
77adc0f76eSAdrien Destugues 		{
782d5f339dSAxel Dörfler 			do {
7916cc5977SMichael Lotz 				panelStatus = read32(statusRegister);
802d5f339dSAxel Dörfler 			} while ((panelStatus & PANEL_STATUS_POWER_ON) != 0);
812d5f339dSAxel Dörfler 		}
822d5f339dSAxel Dörfler 	}
83adc0f76eSAdrien Destugues }
842d5f339dSAxel Dörfler 
852d5f339dSAxel Dörfler 
86e404297eSAxel Dörfler void
set_display_power_mode(uint32 mode)87e404297eSAxel Dörfler set_display_power_mode(uint32 mode)
88e404297eSAxel Dörfler {
89e404297eSAxel Dörfler 	uint32 monitorMode = 0;
90e404297eSAxel Dörfler 
91e404297eSAxel Dörfler 	if (mode == B_DPMS_ON) {
92f0468be3SMichael Lotz 		uint32 pll = read32(INTEL_DISPLAY_A_PLL);
93cbd40810SAxel Dörfler 		if ((pll & DISPLAY_PLL_ENABLED) == 0) {
94cbd40810SAxel Dörfler 			// reactivate PLL
95f0468be3SMichael Lotz 			write32(INTEL_DISPLAY_A_PLL, pll);
96f0468be3SMichael Lotz 			read32(INTEL_DISPLAY_A_PLL);
97cbd40810SAxel Dörfler 			spin(150);
98f0468be3SMichael Lotz 			write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
99f0468be3SMichael Lotz 			read32(INTEL_DISPLAY_A_PLL);
100cbd40810SAxel Dörfler 			spin(150);
101f0468be3SMichael Lotz 			write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED);
102f0468be3SMichael Lotz 			read32(INTEL_DISPLAY_A_PLL);
103cbd40810SAxel Dörfler 			spin(150);
104cbd40810SAxel Dörfler 		}
105cbd40810SAxel Dörfler 
106f0468be3SMichael Lotz 		pll = read32(INTEL_DISPLAY_B_PLL);
1072d5f339dSAxel Dörfler 		if ((pll & DISPLAY_PLL_ENABLED) == 0) {
1082d5f339dSAxel Dörfler 			// reactivate PLL
109f0468be3SMichael Lotz 			write32(INTEL_DISPLAY_B_PLL, pll);
110f0468be3SMichael Lotz 			read32(INTEL_DISPLAY_B_PLL);
1112d5f339dSAxel Dörfler 			spin(150);
112f0468be3SMichael Lotz 			write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
113f0468be3SMichael Lotz 			read32(INTEL_DISPLAY_B_PLL);
1142d5f339dSAxel Dörfler 			spin(150);
115f0468be3SMichael Lotz 			write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED);
116f0468be3SMichael Lotz 			read32(INTEL_DISPLAY_B_PLL);
1172d5f339dSAxel Dörfler 			spin(150);
1182d5f339dSAxel Dörfler 		}
1192d5f339dSAxel Dörfler 
120b979c66cSAlexander von Gluck IV 		enable_all_pipes(true);
121e404297eSAxel Dörfler 	}
122e404297eSAxel Dörfler 
123a0902420SAxel Dörfler 	wait_for_vblank();
124e404297eSAxel Dörfler 
125e404297eSAxel Dörfler 	switch (mode) {
126e404297eSAxel Dörfler 		case B_DPMS_ON:
127e404297eSAxel Dörfler 			monitorMode = DISPLAY_MONITOR_ON;
128e404297eSAxel Dörfler 			break;
129e404297eSAxel Dörfler 		case B_DPMS_SUSPEND:
130e404297eSAxel Dörfler 			monitorMode = DISPLAY_MONITOR_SUSPEND;
131e404297eSAxel Dörfler 			break;
132e404297eSAxel Dörfler 		case B_DPMS_STAND_BY:
133e404297eSAxel Dörfler 			monitorMode = DISPLAY_MONITOR_STAND_BY;
134e404297eSAxel Dörfler 			break;
135e404297eSAxel Dörfler 		case B_DPMS_OFF:
136e404297eSAxel Dörfler 			monitorMode = DISPLAY_MONITOR_OFF;
137e404297eSAxel Dörfler 			break;
138e404297eSAxel Dörfler 	}
139e404297eSAxel Dörfler 
140*95b7699fSRudolf Cornelissen 	//fixme: port DPMS programming should better be in Ports.cpp. Resetup..
141a0902420SAxel Dörfler 	if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
14250f0b3feSAlexander von Gluck IV 		write32(INTEL_ANALOG_PORT, (read32(INTEL_ANALOG_PORT)
143e404297eSAxel Dörfler 				& ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED))
144c788baedSMichael Lotz 			| monitorMode
145c788baedSMichael Lotz 			| (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0));
146a0902420SAxel Dörfler 	}
14750f0b3feSAlexander von Gluck IV 
148*95b7699fSRudolf Cornelissen 	//fixme: port DPMS programming should better be in Ports.cpp and is faulty. Resetup..
149*95b7699fSRudolf Cornelissen 	if (false) {//gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
15050f0b3feSAlexander von Gluck IV 		write32(INTEL_DIGITAL_PORT_B, (read32(INTEL_DIGITAL_PORT_B)
15150f0b3feSAlexander von Gluck IV 				& ~(/*DISPLAY_MONITOR_MODE_MASK |*/ DISPLAY_MONITOR_PORT_ENABLED))
1522d5f339dSAxel Dörfler 			| (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0));
1532d5f339dSAxel Dörfler 			// TODO: monitorMode?
154a0902420SAxel Dörfler 	}
155e404297eSAxel Dörfler 
156b979c66cSAlexander von Gluck IV 	if (mode != B_DPMS_ON)
157b979c66cSAlexander von Gluck IV 		enable_all_pipes(false);
15861dad86aSAxel Dörfler 
159cbd40810SAxel Dörfler 	if (mode == B_DPMS_OFF) {
160f0468be3SMichael Lotz 		write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL)
1612d5f339dSAxel Dörfler 			| DISPLAY_PLL_ENABLED);
162f0468be3SMichael Lotz 		write32(INTEL_DISPLAY_B_PLL, read32(INTEL_DISPLAY_B_PLL)
1632d5f339dSAxel Dörfler 			| DISPLAY_PLL_ENABLED);
1642d5f339dSAxel Dörfler 
165f0468be3SMichael Lotz 		read32(INTEL_DISPLAY_B_PLL);
166951b5e51SMichael Lotz 			// flush the possibly cached PCI bus writes
1672d5f339dSAxel Dörfler 
168cbd40810SAxel Dörfler 		spin(150);
169cbd40810SAxel Dörfler 	}
170cbd40810SAxel Dörfler 
171f0468be3SMichael Lotz 	if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0)
1722d5f339dSAxel Dörfler 		enable_lvds_panel(mode == B_DPMS_ON);
1732d5f339dSAxel Dörfler 
17461dad86aSAxel Dörfler 	read32(INTEL_DISPLAY_A_BASE);
175f0468be3SMichael Lotz 		// flush the possibly cached PCI bus writes
176e404297eSAxel Dörfler }
177e404297eSAxel Dörfler 
178e404297eSAxel Dörfler 
179e404297eSAxel Dörfler //	#pragma mark -
180e404297eSAxel Dörfler 
181e404297eSAxel Dörfler 
182e404297eSAxel Dörfler uint32
intel_dpms_capabilities(void)183e404297eSAxel Dörfler intel_dpms_capabilities(void)
184e404297eSAxel Dörfler {
185881a823eSAlexander von Gluck IV 	CALLED();
186e404297eSAxel Dörfler 	return B_DPMS_ON | B_DPMS_SUSPEND | B_DPMS_STAND_BY | B_DPMS_OFF;
187e404297eSAxel Dörfler }
188e404297eSAxel Dörfler 
189e404297eSAxel Dörfler 
190e404297eSAxel Dörfler uint32
intel_dpms_mode(void)191e404297eSAxel Dörfler intel_dpms_mode(void)
192e404297eSAxel Dörfler {
193881a823eSAlexander von Gluck IV 	CALLED();
194e404297eSAxel Dörfler 	return gInfo->shared_info->dpms_mode;
195e404297eSAxel Dörfler }
196e404297eSAxel Dörfler 
197e404297eSAxel Dörfler 
198e404297eSAxel Dörfler status_t
intel_set_dpms_mode(uint32 mode)199e404297eSAxel Dörfler intel_set_dpms_mode(uint32 mode)
200e404297eSAxel Dörfler {
201881a823eSAlexander von Gluck IV 	CALLED();
202e404297eSAxel Dörfler 	gInfo->shared_info->dpms_mode = mode;
203e404297eSAxel Dörfler 	set_display_power_mode(mode);
204e404297eSAxel Dörfler 
205e404297eSAxel Dörfler 	return B_OK;
206e404297eSAxel Dörfler }
207e404297eSAxel Dörfler 
208