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*/
18status_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. */
28status_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. */
41status_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.  */
157sem_id ACCELERANT_RETRACE_SEMAPHORE(void)
158{
159	if (si->ps.int_assigned)
160		return si->vblank;
161	else
162		return B_ERROR;
163}
164