1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver.
3
4 Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
5 Precision Insight, Inc., Cedar Park, Texas, and
6 VA Linux Systems Inc., Fremont, California.
7
8 Copyright 2009 Haiku, Inc. All rights reserved.
9 Distributed under the terms of the MIT license.
10
11 Authors:
12 Gerald Zajac 2009
13 */
14
15
16 #include "accelerant.h"
17 #include "rage128.h"
18
19
20
21 uint32
Rage128_DPMSCapabilities(void)22 Rage128_DPMSCapabilities(void)
23 {
24 // Return DPMS modes supported by this device.
25
26 return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
27 }
28
29
30 uint32
Rage128_GetDPMSMode(void)31 Rage128_GetDPMSMode(void)
32 {
33 // Return the current DPMS mode.
34
35 uint32 tmp = INREG(R128_CRTC_EXT_CNTL);
36 uint32 mode;
37
38 if( (tmp & R128_CRTC_DISPLAY_DIS) == 0 )
39 mode = B_DPMS_ON;
40 else if( (tmp & R128_CRTC_VSYNC_DIS) == 0 )
41 mode = B_DPMS_STAND_BY;
42 else if( (tmp & R128_CRTC_HSYNC_DIS) == 0 )
43 mode = B_DPMS_SUSPEND;
44 else
45 mode = B_DPMS_OFF;
46
47 TRACE("Rage128_DPMSMode() mode: %d\n", mode);
48 return mode;
49 }
50
51
52 status_t
Rage128_SetDPMSMode(uint32 dpmsMode)53 Rage128_SetDPMSMode(uint32 dpmsMode)
54 {
55 // Set the display into one of the Display Power Management modes,
56 // and return B_OK if successful, else return B_ERROR.
57
58 SharedInfo& si = *gInfo.sharedInfo;
59
60 TRACE("Rage128_SetDPMSMode() mode: %d, display type: %d\n", dpmsMode, si.displayType);
61
62 int mask = (R128_CRTC_DISPLAY_DIS
63 | R128_CRTC_HSYNC_DIS
64 | R128_CRTC_VSYNC_DIS);
65
66 switch (dpmsMode) {
67 case B_DPMS_ON:
68 // Screen: On; HSync: On, VSync: On.
69 OUTREGM(R128_CRTC_EXT_CNTL, 0, mask);
70 break;
71
72 case B_DPMS_STAND_BY:
73 // Screen: Off; HSync: Off, VSync: On.
74 OUTREGM(R128_CRTC_EXT_CNTL,
75 R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, mask);
76 break;
77
78 case B_DPMS_SUSPEND:
79 // Screen: Off; HSync: On, VSync: Off.
80 OUTREGM(R128_CRTC_EXT_CNTL,
81 R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, mask);
82 break;
83
84 case B_DPMS_OFF:
85 // Screen: Off; HSync: Off, VSync: Off.
86 OUTREGM(R128_CRTC_EXT_CNTL, mask, mask);
87 break;
88
89 default:
90 TRACE("Invalid DPMS mode %d\n", dpmsMode);
91 return B_ERROR;
92 }
93
94 if (si.displayType == MT_LAPTOP) {
95 uint32 genCtrl;
96
97 switch (dpmsMode) {
98 case B_DPMS_ON:
99 genCtrl = INREG(R128_LVDS_GEN_CNTL);
100 genCtrl |= R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON | R128_LVDS_DIGON;
101 genCtrl &= ~R128_LVDS_DISPLAY_DIS;
102 OUTREG(R128_LVDS_GEN_CNTL, genCtrl);
103 break;
104
105 case B_DPMS_STAND_BY:
106 case B_DPMS_SUSPEND:
107 case B_DPMS_OFF:
108 genCtrl = INREG(R128_LVDS_GEN_CNTL);
109 genCtrl |= R128_LVDS_DISPLAY_DIS;
110 OUTREG(R128_LVDS_GEN_CNTL, genCtrl);
111 snooze(10);
112 genCtrl &= ~(R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON | R128_LVDS_DIGON);
113 OUTREG(R128_LVDS_GEN_CNTL, genCtrl);
114 break;
115
116 default:
117 TRACE("Invalid DPMS mode %d\n", dpmsMode);
118 return B_ERROR;
119 }
120 }
121
122 if (gInfo.sharedInfo->displayType == MT_DVI) {
123 switch (dpmsMode) {
124 case B_DPMS_ON:
125 OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL)
126 | (R128_FP_FPON | R128_FP_TDMS_EN));
127 break;
128
129 case B_DPMS_STAND_BY:
130 case B_DPMS_SUSPEND:
131 case B_DPMS_OFF:
132 OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL)
133 & ~(R128_FP_FPON | R128_FP_TDMS_EN));
134 break;
135
136 default:
137 TRACE("Invalid DPMS mode %d\n", dpmsMode);
138 return B_ERROR;
139 }
140 }
141
142 return B_OK;
143 }
144
145