xref: /haiku/src/add-ons/accelerants/s3/savage_dpms.cpp (revision 893988af824e65e49e55f517b157db8386e8002b)
1 /*
2 	Haiku S3 Savage driver adapted from the X.org Savage driver.
3 
4 	Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
5 	Copyright (c) 2003-2006, X.Org Foundation
6 
7 	Copyright 2007-2008 Haiku, Inc.  All rights reserved.
8 	Distributed under the terms of the MIT license.
9 
10 	Authors:
11 	Gerald Zajac 2006-2008
12 */
13 
14 
15 #include "accel.h"
16 #include "savage.h"
17 
18 
19 
20 uint32
21 Savage_DPMSCapabilities(void)
22 {
23 	// Return DPMS modes supported by this device.
24 
25 	return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
26 }
27 
28 
29 uint32
30 Savage_GetDPMSMode(void)
31 {
32 	// Return the current DPMS mode.
33 
34 	// Note:  I do not know whether the following code is correctly reading
35 	// the current DPMS mode.  I'm assuming that reading back the bits that
36 	// were set by function SET_DPMS_MODE will give the current DPMS mode.
37 
38 	SharedInfo& si = *gInfo.sharedInfo;
39 	uint32 mode = B_DPMS_ON;
40 
41 	if (si.displayType == MT_CRT) {
42 		switch (ReadSeqReg(0x0d) & 0x70) {
43 			case 0:
44 				mode = B_DPMS_ON;
45 				break;
46 			case 0x10:
47 				mode = B_DPMS_STAND_BY;
48 				break;
49 			case 0x40:
50 				mode = B_DPMS_SUSPEND;
51 				break;
52 			case 0x50:
53 				mode = B_DPMS_OFF;
54 				break;
55 			default:
56 				TRACE("Unknown DPMS mode, reg sr0D: 0x%X\n", ReadSeqReg(0x0d));
57 		}
58 	} else if (si.displayType == MT_LCD || si.displayType == MT_DFP) {
59 		mode = ((ReadSeqReg(0x31) & 0x10) ? B_DPMS_ON : B_DPMS_OFF);
60 	}
61 
62 	TRACE("Savage_GetDPMSMode() mode: %d\n", mode);
63 	return mode;
64 }
65 
66 
67 status_t
68 Savage_SetDPMSMode(uint32 dpmsMode)
69 {
70 	// Set the display into one of the Display Power Management modes,
71 	// and return B_OK if successful, else return B_ERROR.
72 
73 	SharedInfo& si = *gInfo.sharedInfo;
74 
75 	TRACE("Savage_SetDPMSMode() mode: %d, display type: %d\n", dpmsMode, si.displayType);
76 
77 	if (si.displayType == MT_CRT) {
78 		WriteSeqReg(0x08, 0x06);		// unlock extended sequencer regs
79 
80 		uint8 sr0D = ReadSeqReg(0x0d) & 0x03;
81 
82 		switch (dpmsMode) {
83 			case B_DPMS_ON:
84 				break;
85 			case B_DPMS_STAND_BY:
86 				sr0D |= 0x10;
87 				break;
88 			case B_DPMS_SUSPEND:
89 				sr0D |= 0x40;
90 				break;
91 			case B_DPMS_OFF:
92 				sr0D |= 0x50;
93 				break;
94 			default:
95 				TRACE("Invalid DPMS mode %d\n", dpmsMode);
96 				return B_ERROR;
97 		}
98 
99 		WriteSeqReg(0x0d, sr0D);
100 	} else if (si.displayType == MT_LCD || si.displayType == MT_DFP) {
101 		switch (dpmsMode) {
102 			case B_DPMS_ON:
103 				WriteSeqReg(0x31, 0x10, 0x10);	// SR31 bit 4 - FP enable
104 				break;
105 			case B_DPMS_STAND_BY:
106 			case B_DPMS_SUSPEND:
107 			case B_DPMS_OFF:
108 				WriteSeqReg(0x31, 0x00, 0x10);	// SR31 bit 4 - FP enable
109 				break;
110 			default:
111 				TRACE("Invalid DPMS mode %d\n", dpmsMode);
112 				return B_ERROR;
113 		}
114 	}
115 
116 	return B_OK;
117 }
118 
119