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
20uint32
21Savage_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
29uint32
30Savage_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
67status_t
68Savage_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