xref: /haiku/src/add-ons/accelerants/radeon/InitAccelerant.c (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /*
2 	Copyright (c) 2002, Thomas Kurschel
3 
4 
5 	Part of Radeon accelerant
6 
7 	Main init/uninit functions
8 */
9 
10 
11 #include "GlobalData.h"
12 #include "generic.h"
13 
14 #include "string.h"
15 #include "unistd.h"
16 #include "sys/types.h"
17 #include "sys/stat.h"
18 #include "fcntl.h"
19 #include <sys/ioctl.h>
20 #include <malloc.h>
21 
22 
23 // init data used by both primary and cloned accelerant
24 //	the_fd - file descriptor of kernel driver
25 //	accelerant_is_clone - if true, this is a cloned accelerant
26 static status_t init_common( int the_fd, bool accelerant_is_clone )
27 {
28 	status_t result;
29 	radeon_get_private_data gpd;
30 
31 	SHOW_FLOW0( 3, "" );
32 
33 	ai = malloc( sizeof( *ai ));
34 	if( ai == NULL )
35 		return B_NO_MEMORY;
36 
37 	memset( ai, 0, sizeof( *ai ));
38 
39 	ai->accelerant_is_clone = accelerant_is_clone;
40 	ai->fd = the_fd;
41 
42 	// get basic info from driver
43 	gpd.magic = RADEON_PRIVATE_DATA_MAGIC;
44 
45 	result = ioctl( ai->fd, RADEON_GET_PRIVATE_DATA, &gpd, sizeof(gpd) );
46 	if (result != B_OK) goto err;
47 
48 	ai->virtual_card_area = clone_area( "Radeon virtual card", (void **)&ai->vc, B_ANY_ADDRESS,
49 		B_READ_AREA | B_WRITE_AREA, gpd.virtual_card_area );
50 	if( ai->virtual_card_area < 0 ) {
51 		result = ai->virtual_card_area;
52 		goto err;
53 	}
54 	ai->shared_info_area = clone_area("Radeon shared info", (void **)&ai->si, B_ANY_ADDRESS,
55 		B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area);
56 	if( ai->shared_info_area < 0 ) {
57 		result = ai->shared_info_area;
58 		goto err2;
59 	}
60 
61 	ai->regs_area = clone_area("Radeon regs area", (void **)&ai->regs, B_ANY_ADDRESS,
62 		B_READ_AREA | B_WRITE_AREA, ai->si->regs_area);
63 	if( ai->regs_area < 0 ) {
64 		result = ai->regs_area;
65 		goto err3;
66 	}
67 
68 	return B_OK;
69 
70 err3:
71 	delete_area( ai->shared_info_area );
72 err2:
73 	delete_area( ai->virtual_card_area );
74 err:
75 	free( ai );
76 	return result;
77 }
78 
79 // clean up data common to both primary and cloned accelerant
80 static void uninit_common( void )
81 {
82 	delete_area( ai->regs_area );
83 	delete_area( ai->shared_info_area );
84 	delete_area( ai->virtual_card_area );
85 
86 	ai->regs_area = ai->shared_info_area = ai->virtual_card_area = 0;
87 
88 	ai->regs = 0;
89 	ai->si = 0;
90 	ai->vc = 0;
91 
92 	// close the file handle ONLY if we're the clone
93 	// (this is what Be tells us ;)
94 	if( ai->accelerant_is_clone )
95 		close( ai->fd );
96 
97 	free( ai );
98 }
99 
100 // public function: init primary accelerant
101 //	the_fd - file handle of kernel driver
102 status_t INIT_ACCELERANT( int the_fd )
103 {
104 	shared_info *si;
105 	virtual_card *vc;
106 	status_t result;
107 
108 	SHOW_FLOW0( 3, "" );
109 
110 	result = init_common( the_fd, 0 );
111 	if (result != B_OK)
112 		goto err;
113 
114 	si = ai->si;
115 	vc = ai->vc;
116 
117 	// init Command Processor
118 	result = Radeon_InitCP( ai );
119 	if( result != B_OK )
120 		goto err2;
121 
122 	// this isn't the best place, but has to be done sometime
123 	Radeon_ReadSettings( vc );
124 
125 	// read FP info via DDC
126 	// (ignore result - if it fails we fall back to BIOS detection)
127 	if( si->fp_port.disp_type == dt_dvi_1 )
128 		Radeon_ReadFPEDID( ai, si );
129 
130 	// create list of supported modes
131 	result = Radeon_CreateModeList( si );
132 	if (result != B_OK)
133 		goto err3;
134 
135 	/* init the shared semaphore */
136 	INIT_BEN( "Radeon engine", si->engine.lock );
137 
138 	// init engine sync token
139 	// (count of issued parameters or commands)
140 	si->engine.last_idle = si->engine.count = 0;
141 	// set last written count to be very old, so it must be written on first use
142 	// (see writeSyncToken)
143 	si->engine.written = -1;
144 
145 	// init overlay
146 	si->overlay_mgr.token = 0;
147 	si->overlay_mgr.inuse = 0;
148 
149 	// mark overlay as inactive
150 	si->active_overlay.port = -1;
151 	si->pending_overlay.port = -1;
152 
153 	// reset list of allocated overlays
154 	vc->overlay_buffers = NULL;
155 
156 	// everything else is initialized upon set_display_mode
157 	return B_OK;
158 
159 err3:
160 err2:
161 	uninit_common();
162 err:
163 	return result;
164 }
165 
166 
167 // public function: return size of clone info
168 ssize_t ACCELERANT_CLONE_INFO_SIZE( void )
169 {
170 	// clone info is device name, so return its maximum size
171 	return MAX_RADEON_DEVICE_NAME_LENGTH;
172 }
173 
174 
175 // public function: return clone info
176 //	data - buffer to contain info (allocated by caller)
177 void GET_ACCELERANT_CLONE_INFO( void *data )
178 {
179 	radeon_device_name dn;
180 	status_t result;
181 
182 	// clone info is device name - ask device driver
183 	dn.magic = RADEON_PRIVATE_DATA_MAGIC;
184 	dn.name = (char *)data;
185 
186 	result = ioctl( ai->fd, RADEON_DEVICE_NAME, &dn, sizeof(dn) );
187 }
188 
189 // public function: init cloned accelerant
190 //	data - clone info from get_accelerant_clone_info
191 status_t CLONE_ACCELERANT( void *data )
192 {
193 	status_t result;
194 	char path[MAXPATHLEN];
195 	int fd;
196 
197 	// create full device name
198 	strcpy(path, "/dev/");//added trailing '/', this fixes cloning accelerant!
199 	strcat(path, (const char *)data);
200 
201 	// open device; according to Be, permissions aren't important
202 	// this will probably change once access right are checked properly
203 	fd = open(path, B_READ_WRITE);
204 	if( fd < 0 )
205 		return fd;
206 
207 	result = init_common( fd, 1 );
208 	if( result != B_OK )
209 		goto err1;
210 
211 	// get (cloned) copy of supported display modes
212 	result = ai->mode_list_area = clone_area(
213 		"Radeon cloned display_modes", (void **)&ai->mode_list,
214 		B_ANY_ADDRESS, B_READ_AREA, ai->si->mode_list_area );
215 	if (result < B_OK)
216 		goto err2;
217 
218 	return B_OK;
219 
220 err2:
221 	uninit_common();
222 err1:
223 	close( fd );
224 	return result;
225 }
226 
227 // public function: uninit primary or cloned accelerant
228 void UNINIT_ACCELERANT( void )
229 {
230 	// TBD:
231 	// we should put accelerator into stable state first -
232 	// on my Laptop, you never can boot Windows/Linux after shutting
233 	// down BeOS; if both ports have been used, even the BIOS screen
234 	// is completely messed up
235 
236 	// cloned accelerants have mode_list cloned, so deleting is OK
237 	// primary accelerant owns mode list, so deleting is OK as well
238 	delete_area( ai->mode_list_area );
239 	ai->mode_list = 0;
240 
241 	uninit_common();
242 }
243 
244 // public function: get some info about graphics card
245 status_t GET_ACCELERANT_DEVICE_INFO( accelerant_device_info *di )
246 {
247 	// is there anyone using it?
248 
249 	// TBD: everything apart from memsize
250 	di->version = B_ACCELERANT_VERSION;
251 	strcpy( di->name, "Radeon" );
252 	strcpy( di->chipset, "Radeon" );
253 	strcpy( di->serial_no, "None" );
254 
255 	di->memory = ai->si->local_mem_size;
256 
257 	// TBD: is max PLL speed really equal to max DAC speed?
258 	di->dac_speed = ai->si->pll.max_pll_freq;
259 
260 	return B_OK;
261 }
262