xref: /haiku/src/add-ons/accelerants/matrox/GetModeInfo.c (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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-11/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 	LOG(4, ("GET_DISPLAY_MODE: returning current mode\n"));
24 
25 	*current_mode = si->dm;
26 	return B_OK;
27 }
28 
29 /* Return the frame buffer configuration information. */
30 status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb)
31 {
32 	/* check for NULL pointer */
33 	if (afb == NULL) return B_ERROR;
34 
35 	*afb = si->fbc;
36 	return B_OK;
37 }
38 
39 /* Return the maximum and minium pixelclock limits for the specified mode. */
40 /* Rewritten / fixed by Rudolf */
41 /* NOTE:
42  * Due to BeOS constraints output for all heads will be limited to the head with
43  * the least capabilities. (BeOS should ask for seperate constraints for all heads.) */
44 status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high)
45 {
46 	uint32 max_pclk = 0;
47 	uint32 min_pclk = 0;
48 
49 	/* check for NULL pointers */
50 	if ((dm == NULL) || (low == NULL) || (high == NULL)) return B_ERROR;
51 
52 	/* specify requested info */
53 	if (dm->flags & DUALHEAD_BITS)
54 	{
55 		/* dualhead mode */
56 		/* find min. value */
57 		switch (si->ps.card_type)
58 		{
59 			case G550:
60 			case G450:
61 				*low = ((si->ps.min_video_vco * 1000) / 16);
62 				break;
63 			default:
64 				*low = ((si->ps.min_video_vco * 1000) / 8);
65 				break;
66 		}
67 		/* find max. value */
68 		switch (dm->space)
69 		{
70 			case B_CMAP8:
71 				max_pclk = si->ps.max_dac2_clock_8;
72 				break;
73 			case B_RGB15_LITTLE:
74 			case B_RGB16_LITTLE:
75 				max_pclk = si->ps.max_dac2_clock_16;
76 				break;
77 			case B_RGB24_LITTLE:
78 				max_pclk = si->ps.max_dac2_clock_24;
79 				break;
80 			case B_RGB32_LITTLE:
81 				/* specially noted because of RAM speed constraints! */
82 				max_pclk = si->ps.max_dac2_clock_32dh;
83 				break;
84 			default:
85 				/* use fail-safe value */
86 				max_pclk = si->ps.max_dac2_clock_32dh;
87 				break;
88 		}
89 		/* return values in kHz */
90 		*high = max_pclk * 1000;
91 	}
92 	else
93 	{
94 		/* singlehead mode */
95 		/* find min. value */
96 		switch (si->ps.card_type)
97 		{
98 			case G550:
99 			case G450:
100 				*low = ((si->ps.min_pixel_vco * 1000) / 16);
101 				break;
102 			default:
103 				*low = ((si->ps.min_pixel_vco * 1000) / 8);
104 				break;
105 		}
106 		/* find max. value */
107 		switch (dm->space)
108 		{
109 			case B_CMAP8:
110 				max_pclk = si->ps.max_dac1_clock_8;
111 				break;
112 			case B_RGB15_LITTLE:
113 			case B_RGB16_LITTLE:
114 				max_pclk = si->ps.max_dac1_clock_16;
115 				break;
116 			case B_RGB24_LITTLE:
117 				max_pclk = si->ps.max_dac1_clock_24;
118 				break;
119 			case B_RGB32_LITTLE:
120 				max_pclk = si->ps.max_dac1_clock_32;
121 				break;
122 			default:
123 				/* use fail-safe value */
124 				max_pclk = si->ps.max_dac1_clock_32;
125 				break;
126 		}
127 		/* return values in kHz */
128 		*high = max_pclk * 1000;
129 	}
130 
131 	/* clamp lower limit to 48Hz vertical refresh for now.
132 	 * Apparantly the BeOS screenprefs app does limit the upper refreshrate to 90Hz,
133 	 * while it does not limit the lower refreshrate. */
134 	min_pclk = ((uint32)dm->timing.h_total * (uint32)dm->timing.v_total * 48) / 1000;
135 	if (min_pclk > *low) *low = min_pclk;
136 
137 	return B_OK;
138 }
139 
140 /* Return the semaphore id that will be used to signal a vertical sync occured.  */
141 sem_id ACCELERANT_RETRACE_SEMAPHORE(void)
142 {
143 	if (si->ps.int_assigned)
144 		return si->vblank;
145 	else
146 		return B_ERROR;
147 }
148