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