xref: /haiku/src/add-ons/accelerants/nvidia/GetModeInfo.c (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
1 /*
2 	Copyright 1999, Be Incorporated.   All Rights Reserved.
3 	This file may be used under the terms of the Be Sample Code License.
4 
5 	Other authors:
6 	Mark Watson
7 	Rudolf Cornelissen 9/2002-10/2005
8 */
9 
10 #define MODULE_BIT 0x02000000
11 
12 #include "acc_std.h"
13 
14 /*
15 	Return the current display mode.  The only time you might return an
16 	error is if a mode hasn't been set. Or if the system hands you a NULL pointer.
17 */
18 status_t GET_DISPLAY_MODE(display_mode *current_mode)
19 {
20 	/* check for NULL pointer */
21 	if (current_mode == NULL) return B_ERROR;
22 
23 	*current_mode = si->dm;
24 	return B_OK;
25 }
26 
27 /* Return the frame buffer configuration information. */
28 status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb)
29 {
30 	/* check for NULL pointer */
31 	if (afb == NULL) return B_ERROR;
32 
33 	*afb = si->fbc;
34 	return B_OK;
35 }
36 
37 /* Return the maximum and minium pixelclock limits for the specified mode. */
38 /* NOTE:
39  * Due to BeOS constraints output for all heads will be limited to the head with
40  * the least capabilities. */
41 status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high)
42 {
43 	uint32 max_pclk = 0;
44 	uint32 min_pclk = 0;
45 
46 	/* check for NULL pointers */
47 	if ((dm == NULL) || (low == NULL) || (high == NULL)) return B_ERROR;
48 
49 	/* specify requested info */
50 	if (dm->flags & DUALHEAD_BITS)
51 	{
52 		/* dualhead mode */
53 		/* find min. value */
54 		switch (si->ps.card_type)
55 		{
56 			default:
57 				*low = ((si->ps.min_video_vco * 1000) / 16);
58 				break;
59 		}
60 		/* find max. value:
61 		 * using decondary DAC specs because they could be narrower (twinview) */
62 		switch (dm->space)
63 		{
64 			case B_CMAP8:
65 				max_pclk = si->ps.max_dac2_clock_8;
66 				break;
67 			case B_RGB15_LITTLE:
68 			case B_RGB16_LITTLE:
69 				max_pclk = si->ps.max_dac2_clock_16;
70 				break;
71 			case B_RGB24_LITTLE:
72 				max_pclk = si->ps.max_dac2_clock_24;
73 				break;
74 			case B_RGB32_LITTLE:
75 				/* specially noted because of RAM speed constraints! */
76 				max_pclk = si->ps.max_dac2_clock_32dh;
77 				break;
78 			default:
79 				/* use fail-safe value */
80 				max_pclk = si->ps.max_dac2_clock_32dh;
81 				break;
82 		}
83 		/* return values in kHz */
84 		*high = max_pclk * 1000;
85 	}
86 	else
87 	{
88 		/* singlehead mode */
89 		/* find min. value */
90 		switch (si->ps.card_type)
91 		{
92 			default:
93 				*low = ((si->ps.min_pixel_vco * 1000) / 16);
94 				break;
95 		}
96 		/* find max. value: depends on which head is used as primary head */
97 		if (!si->ps.crtc2_prim)
98 		{
99 			switch (dm->space)
100 			{
101 				case B_CMAP8:
102 					max_pclk = si->ps.max_dac1_clock_8;
103 					break;
104 				case B_RGB15_LITTLE:
105 				case B_RGB16_LITTLE:
106 					max_pclk = si->ps.max_dac1_clock_16;
107 					break;
108 				case B_RGB24_LITTLE:
109 					max_pclk = si->ps.max_dac1_clock_24;
110 					break;
111 				case B_RGB32_LITTLE:
112 					max_pclk = si->ps.max_dac1_clock_32;
113 					break;
114 				default:
115 					/* use fail-safe value */
116 					max_pclk = si->ps.max_dac1_clock_32;
117 					break;
118 			}
119 		}
120 		else
121 		{
122 			switch (dm->space)
123 			{
124 				case B_CMAP8:
125 					max_pclk = si->ps.max_dac2_clock_8;
126 					break;
127 				case B_RGB15_LITTLE:
128 				case B_RGB16_LITTLE:
129 					max_pclk = si->ps.max_dac2_clock_16;
130 					break;
131 				case B_RGB24_LITTLE:
132 					max_pclk = si->ps.max_dac2_clock_24;
133 					break;
134 				case B_RGB32_LITTLE:
135 					max_pclk = si->ps.max_dac2_clock_32;
136 					break;
137 				default:
138 					/* use fail-safe value */
139 					max_pclk = si->ps.max_dac2_clock_32;
140 					break;
141 			}
142 		}
143 		/* return values in kHz */
144 		*high = max_pclk * 1000;
145 	}
146 
147 	/* clamp lower limit to 48Hz vertical refresh for now.
148 	 * Apparantly the BeOS screenprefs app does limit the upper refreshrate to 90Hz,
149 	 * while it does not limit the lower refreshrate. */
150 	min_pclk = ((uint32)dm->timing.h_total * (uint32)dm->timing.v_total * 48) / 1000;
151 	if (min_pclk > *low) *low = min_pclk;
152 
153 	return B_OK;
154 }
155 
156 /* Return the semaphore id that will be used to signal a vertical sync occured.  */
157 sem_id ACCELERANT_RETRACE_SEMAPHORE(void)
158 {
159 	if (si->ps.int_assigned)
160 		return si->vblank;
161 	else
162 		return B_ERROR;
163 }
164