xref: /haiku/src/add-ons/accelerants/radeon/GetModeInfo.c (revision 4bd0c1066b227cec4b79883bdef697c7a27f2e90)
1 /*
2  * Copyright (c) 2002, Thomas Kurschel
3  * Distributed under the terms of the MIT License.
4  */
5 
6 /*!	Public mode-specific info functions */
7 
8 
9 #include "radeon_accelerant.h"
10 #include "GlobalData.h"
11 #include "generic.h"
12 
13 #include <GraphicsDefs.h>
14 
15 #include <string.h>
16 
17 
18 status_t
19 GET_DISPLAY_MODE(display_mode *mode)
20 {
21 	virtual_card *vc = ai->vc;
22 
23 	// TBD: there is a race condition if someone else is just setting it
24 	//      we won't lock up but return non-sense
25 
26 	*mode = vc->mode;
27 
28 	// we hide multi-monitor-mode because :-
29 	// - we want to look like an ordinary single-screen driver
30 	// - the multi-mode is already adapted to current screen configuration,
31 	//   and the mode should be configuration-independant
32 	Radeon_HideMultiMode(vc, mode);
33 	return B_OK;
34 }
35 
36 
37 status_t
38 GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb)
39 {
40 	virtual_card *vc = ai->vc;
41 
42 	// TBD: race condition again
43 
44 	// easy again, as the last mode set stored the info in a convienient form
45 	*afb = vc->fbc;
46 	return B_OK;
47 }
48 
49 
50 status_t
51 GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high)
52 {
53 	// we ignore stuff like DVI/LCD restrictions -
54 	// they are handled	automatically on set_display_mode
55 	uint32 total_pix = (uint32)dm->timing.h_total * (uint32)dm->timing.v_total;
56 	uint32 clock_limit = ai->si->pll.max_pll_freq * 10;
57 
58 	/* lower limit of about 48Hz vertical refresh */
59 	*low = (total_pix * 48L) / 1000L;
60 	if (*low > clock_limit)
61 		return B_ERROR;
62 
63 	*high = clock_limit;
64 	return B_OK;
65 }
66 
67 
68 #ifdef __HAIKU__
69 
70 status_t
71 radeon_get_preferred_display_mode(display_mode* mode)
72 {
73 	fp_info *fpInfo = &ai->si->flatpanels[0];
74 	disp_entity* routes = &ai->si->routing;
75 	uint32 i;
76 
77 	if (routes->port_info[0].edid_valid || routes->port_info[1].edid_valid) {
78 		// prefer EDID data in this case
79 		return B_ERROR;
80 	}
81 
82 	if ((ai->vc->connected_displays & (dd_dvi | dd_dvi_ext | dd_lvds)) == 0)
83 		return B_NOT_SUPPORTED;
84 
85 	// Mode has already been added by addFPMode(), just return it
86 
87 	for (i = 0; i < ai->si->mode_count; ++i) {
88 		if (ai->mode_list[i].timing.h_display == fpInfo->panel_xres
89 			&& ai->mode_list[i].timing.v_display == fpInfo->panel_yres
90 			&& ai->mode_list[i].virtual_width == fpInfo->panel_xres
91 			&& ai->mode_list[i].virtual_height == fpInfo->panel_yres
92 			&& ai->mode_list[i].space == B_RGB32_LITTLE) {
93 			memcpy(mode, &ai->mode_list[i], sizeof(display_mode));
94 			return B_OK;
95 		}
96 	}
97 
98 	return B_ERROR;
99 }
100 
101 
102 status_t
103 radeon_get_edid_info(void* info, size_t size, uint32* _version)
104 {
105 	disp_entity* routes = &ai->si->routing;
106 	int32 index;
107 
108 	if (size < sizeof(struct edid1_info))
109 		return B_BUFFER_OVERFLOW;
110 
111 	if (routes->port_info[0].edid_valid)
112 		index = 0;
113 	else if (routes->port_info[1].edid_valid)
114 		index = 1;
115 	else
116 		return B_ERROR;
117 
118 	memcpy(info, &routes->port_info[index].edid, sizeof(struct edid1_info));
119 	*_version = EDID_VERSION_1;
120 	return B_OK;
121 }
122 
123 #endif	// __HAIKU__
124 
125 /*
126 	Return the semaphore id that will be used to signal a vertical retrace
127 	occured.
128 */
129 sem_id
130 ACCELERANT_RETRACE_SEMAPHORE(void)
131 {
132 	virtual_card *vc = ai->vc;
133 
134 	/*
135 	NOTE:
136 		The kernel driver created this for us.  We don't know if the system is
137 		using real interrupts, or if we're faking it, and we don't care.
138 		If we choose not to support this at all, we'd just return B_ERROR here,
139 		and the user wouldn't get any kind of vertical retrace support.
140 	*/
141 	// with multi-monitor mode, we have two vertical blanks!
142 	// until we find a better solution, we always return virtual port 0,
143 	// which may be either physical port 0 or 1
144 	int crtcIndex;
145 
146 	if( vc->used_crtc[0] )
147 		crtcIndex = 0;
148 	else
149 		crtcIndex = 1;
150 
151 	//SHOW_INFO( 3, "semaphore: %x", ai->si->ports[physical_port].vblank );
152 
153 	return ai->si->crtc[crtcIndex].vblank;
154 }
155