xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon/init.c (revision 002f37b0cca92e4cf72857c72ac95db5a8b09615)
1 /*
2  * Copyright (c) 2002-2004, Thomas Kurschel
3  * Copyright (c) 2006-2007, Euan Kirkhope
4  *
5  * Distributed under the terms of the MIT license.
6  */
7 
8 /*
9 	Init and clean-up of devices
10 
11 	TODO: support for multiple virtual card per device is
12 	not implemented yet - there is only one per device;
13 	apart from additional device names, we need proper
14 	management of graphics mem to not interfere.
15 */
16 
17 #include "dac_regs.h"
18 #include "tv_out_regs.h"
19 #include "fp_regs.h"
20 #include "mmio.h"
21 #include "radeon_driver.h"
22 
23 #include <PCI.h>
24 
25 #include <stdio.h>
26 #include <string.h>
27 
28 // helper macros for easier PCI access
29 #define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s))
30 #define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v))
31 
32 extern radeon_settings current_settings;
33 
34 // map frame buffer and registers
35 // mmio_only - true = map registers only (used during detection)
36 status_t Radeon_MapDevice( device_info *di, bool mmio_only )
37 {
38 	// framebuffer is stored in PCI range 0,
39 	// register map in PCI range 2
40 	int regs = 2;
41 	int fb   = 0;
42 	char buffer[100];
43 	shared_info *si = di->si;
44 	uint32	tmp;
45 	pci_info *pcii = &(di->pcii);
46 	status_t result;
47 
48 	SHOW_FLOW( 3, "device: %02X%02X%02X",
49 		di->pcii.bus, di->pcii.device, di->pcii.function );
50 
51 	si->ROM_area = si->regs_area = si->memory[mt_local].area = 0;
52 
53 	// enable memory mapped IO and frame buffer
54 	// also, enable bus mastering (some BIOSes seem to
55 	// disable that, like mine)
56 	tmp = get_pci( PCI_command, 2 );
57 	SHOW_FLOW( 3, "old PCI command state: 0x%08lx", tmp );
58 	tmp |= PCI_command_io | PCI_command_memory | PCI_command_master;
59 	set_pci( PCI_command, 2, tmp );
60 
61 	// registers cannot be accessed directly by user apps,
62 	// they need to clone area for safety reasons
63 	SHOW_INFO( 1, "physical address of memory-mapped I/O: 0x%8lx-0x%8lx",
64 		di->pcii.u.h0.base_registers[regs],
65 		di->pcii.u.h0.base_registers[regs] + di->pcii.u.h0.base_register_sizes[regs] - 1 );
66 
67 	sprintf( buffer, "%04X_%04X_%02X%02X%02X regs",
68 		di->pcii.vendor_id, di->pcii.device_id,
69 		di->pcii.bus, di->pcii.device, di->pcii.function );
70 
71 	si->regs_area = map_physical_memory(
72 		buffer,
73 		di->pcii.u.h0.base_registers[regs],
74 		di->pcii.u.h0.base_register_sizes[regs],
75 		B_ANY_KERNEL_ADDRESS,
76 		/*// for "poke" debugging
77 		B_READ_AREA + B_WRITE_AREA*/
78 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
79 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA,
80 #else
81 		0,
82 #endif
83 		(void **)&(di->regs));
84 	if( si->regs_area < 0 )
85 		return si->regs_area;
86 
87 	// that's all during detection as we have no clue about ROM or
88 	// frame buffer at this point
89 	if( mmio_only )
90 		return B_OK;
91 
92 	// ROM must be explicetely mapped by applications too
93 	sprintf( buffer, "%04X_%04X_%02X%02X%02X ROM",
94 		di->pcii.vendor_id, di->pcii.device_id,
95 		di->pcii.bus, di->pcii.device, di->pcii.function );
96 
97 	si->ROM_area = map_physical_memory(
98 		buffer,
99 		di->rom.phys_address,
100 		di->rom.size,
101 		B_ANY_KERNEL_ADDRESS,
102 		0,
103 		(void **)&(di->rom.rom_ptr));
104 	if( si->ROM_area < 0 ) {
105 		result = si->ROM_area;
106 		goto err2;
107 	}
108 
109 	if( di->pcii.u.h0.base_register_sizes[fb] > di->local_mem_size ) {
110 		// Radeons allocate more address range then really needed ->
111 		// only map the area that contains physical memory
112 		SHOW_INFO( 1, "restrict frame buffer from 0x%8lx to 0x%8lx bytes",
113 			di->pcii.u.h0.base_register_sizes[fb],
114 			di->local_mem_size
115 		);
116 		di->pcii.u.h0.base_register_sizes[fb] = di->local_mem_size;
117 	}
118 
119 	// framebuffer can be accessed by everyone
120 	// this is not a perfect solution; preferably, only
121 	// those areas owned by an application are mapped into
122 	// its address space
123 	// (this hack is needed by BeOS to write something onto screen in KDL)
124 	SHOW_INFO( 1, "physical address of framebuffer: 0x%8lx-0x%8lx",
125 		di->pcii.u.h0.base_registers[fb],
126 		di->pcii.u.h0.base_registers[fb] + di->pcii.u.h0.base_register_sizes[fb] - 1 );
127 
128 	sprintf(buffer, "%04X_%04X_%02X%02X%02X framebuffer",
129 		di->pcii.vendor_id, di->pcii.device_id,
130 		di->pcii.bus, di->pcii.device, di->pcii.function);
131 
132 	si->memory[mt_local].area = map_physical_memory(
133 		buffer,
134 		di->pcii.u.h0.base_registers[fb],
135 		di->pcii.u.h0.base_register_sizes[fb],
136 		B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC,
137 		B_READ_AREA + B_WRITE_AREA,
138 		(void **)&(si->local_mem));
139 
140 	if( si->memory[mt_local].area < 0 ) {
141 		SHOW_FLOW0( 3, "couldn't enable WC for frame buffer" );
142 		si->memory[mt_local].area = map_physical_memory(
143 			buffer,
144 			di->pcii.u.h0.base_registers[fb],
145 			di->pcii.u.h0.base_register_sizes[fb],
146 			B_ANY_KERNEL_BLOCK_ADDRESS,
147 			B_READ_AREA + B_WRITE_AREA,
148 			(void **)&(si->local_mem));
149 	}
150 
151 	SHOW_FLOW( 3, "mapped frame buffer @%p", si->local_mem );
152 
153 	if( si->memory[mt_local].area < 0 ) {
154 		result = si->memory[mt_local].area;
155 		goto err;
156 	}
157 
158 	// save physical address though noone can probably make
159 	// any use of it
160 	si->framebuffer_pci = (void *) di->pcii.u.h0.base_registers_pci[fb];
161 
162 	return B_OK;
163 
164 err:
165 	delete_area( si->ROM_area );
166 err2:
167 	delete_area( si->regs_area );
168 	return result;
169 }
170 
171 
172 // unmap PCI ranges
173 void Radeon_UnmapDevice(device_info *di)
174 {
175 	shared_info *si = di->si;
176 	pci_info *pcii = &(di->pcii);
177 	uint32 tmp;
178 
179 	SHOW_FLOW0( 3, "" );
180 
181 	// disable PCI ranges (though it probably won't
182 	// hurt	leaving them enabled)
183 	tmp = get_pci( PCI_command, 2 );
184 	tmp &= ~PCI_command_io | PCI_command_memory | PCI_command_master;
185 	set_pci( PCI_command, 2, tmp );
186 
187 	if( si->regs_area > 0 )
188 		delete_area( si->regs_area );
189 
190 	if( si->ROM_area > 0 )
191 		delete_area( si->ROM_area );
192 
193 	if( si->memory[mt_local].area > 0 )
194 		delete_area( si->memory[mt_local].area );
195 
196 	si->regs_area = si->ROM_area = si->memory[mt_local].area = 0;
197 }
198 
199 
200 // initialize shared infos on first open
201 status_t Radeon_FirstOpen( device_info *di )
202 {
203 	status_t result;
204 	char buffer[100];	// B_OS_NAME_LENGTH is too short
205 	shared_info *si;
206 	//uint32 /*dma_block, */dma_offset;
207 
208 	// create shared info; don't allow access by apps -
209 	// they'll clone it
210 	sprintf( buffer, "%04X_%04X_%02X%02X%02X shared",
211 		di->pcii.vendor_id, di->pcii.device_id,
212 		di->pcii.bus, di->pcii.device, di->pcii.function );
213 
214 	di->shared_area = create_area(
215 		buffer,
216 		(void **)&(di->si),
217 		B_ANY_KERNEL_ADDRESS,
218 		(sizeof(shared_info) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1),
219 		B_FULL_LOCK,
220 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
221 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA
222 #else
223 		0
224 #endif
225 		);
226 	if (di->shared_area < 0) {
227 		result = di->shared_area;
228 		goto err8;
229 	}
230 
231 	memset( di->si, 0, sizeof( *di->si ));
232 
233 	si = di->si;
234 
235 	si->settings = di->settings = current_settings;
236 
237 	if (di->settings.force_acc_dma)
238 		di->acc_dma = true;
239 	if (di->settings.force_acc_mmio) // force mmio will override dma... a tristate fuzzylogic, grey bool would be nice...
240 		di->acc_dma = false;
241 
242 #ifdef ENABLE_LOGGING
243 #ifdef LOG_INCLUDE_STARTUP
244 	si->log = log_init( 1000000 );
245 #endif
246 #endif
247 
248 	// copy all info into shared info
249 	si->vendor_id = di->pcii.vendor_id;
250 	si->device_id = di->pcii.device_id;
251 	si->revision = di->pcii.revision;
252 
253 	si->asic = di->asic;
254 	si->is_mobility = di->is_mobility;
255 	si->tv_chip = di->tv_chip;
256 	si->new_pll = di->new_pll;
257 	si->is_igp = di->is_igp;
258 	si->has_no_i2c = di->has_no_i2c;
259 	si->is_atombios = di->is_atombios;
260 	si->is_mobility = di->is_mobility;
261 	si->panel_pwr_delay = di->si->panel_pwr_delay;
262 	si->acc_dma = di->acc_dma;
263 
264 	memcpy(&si->routing, &di->routing, sizeof(disp_entity));
265 
266 	// detecting theatre channel in kernel would lead to code duplication,
267 	// so we let the first accelerant take care of it
268 	si->theatre_channel = -1;
269 
270 	si->crtc[0].crtc_idx = 0;
271 	si->crtc[0].flatpanel_port = 0;
272 	si->crtc[1].crtc_idx = 1;
273 	si->crtc[1].flatpanel_port = 1;
274 	si->num_crtc = di->num_crtc;
275 
276 	if (di->is_mobility)
277 		si->flatpanels[0] = di->fp_info;
278 
279 	si->pll = di->pll;
280 
281 	// create virtual card info; don't allow access by apps -
282 	// they'll clone it
283 	sprintf( buffer, "%04X_%04X_%02X%02X%02X virtual card 0",
284 		di->pcii.vendor_id, di->pcii.device_id,
285 		di->pcii.bus, di->pcii.device, di->pcii.function );
286 	di->virtual_card_area = create_area(
287 		buffer,
288 		(void **)&(di->vc),
289 		B_ANY_KERNEL_ADDRESS,
290 		(sizeof(virtual_card) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1),
291 		B_FULL_LOCK,
292 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
293 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA
294 #else
295 		0
296 #endif
297 		);
298 	if (di->virtual_card_area < 0) {
299 		result = di->virtual_card_area;
300 		goto err7;
301 	}
302 
303 	// currently, we assign fixed ports to this virtual card
304 	di->vc->assigned_crtc[0] = true;
305 	di->vc->assigned_crtc[1] = si->num_crtc > 1;
306 	di->vc->controlled_displays =
307 		dd_tv_crt | dd_crt | dd_lvds | dd_dvi | dd_dvi_ext | dd_ctv | dd_stv;
308 
309 	di->vc->fb_mem_handle = 0;
310 	di->vc->cursor.mem_handle = 0;
311 
312 	// create unique id
313 	di->vc->id = di->virtual_card_area;
314 
315 	result = Radeon_MapDevice( di, false );
316 	if (result < 0)
317 		goto err6;
318 
319 	// save dac2_cntl register
320 	// on M6, we need to restore that during uninit, else you only get
321 	// garbage on screen on reboot if both CRTCs are used
322 	if( di->asic == rt_rv100 && di->is_mobility)
323 		di->dac2_cntl = INREG( di->regs, RADEON_DAC_CNTL2 );
324 
325 	memcpy(&si->tmds_pll, &di->tmds_pll, sizeof(di->tmds_pll));
326 	si->tmds_pll_cntl = INREG( di->regs, RADEON_TMDS_PLL_CNTL);
327 	si->tmds_transmitter_cntl = INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL);
328 
329 	// print these out to capture bios status...
330 //	if ( di->is_mobility ) {
331 		SHOW_INFO0( 2, "Copy of Laptop Display Regs for Reference:");
332 		SHOW_INFO( 2, "LVDS GEN = %8lx", INREG( di->regs, RADEON_LVDS_GEN_CNTL ));
333 		SHOW_INFO( 2, "LVDS PLL = %8lx", INREG( di->regs, RADEON_LVDS_PLL_CNTL ));
334 		SHOW_INFO( 2, "TMDS PLL = %8lx", INREG( di->regs, RADEON_TMDS_PLL_CNTL ));
335 		SHOW_INFO( 2, "TMDS TRANS = %8lx", INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL ));
336 		SHOW_INFO( 2, "FP1 GEN = %8lx", INREG( di->regs, RADEON_FP_GEN_CNTL ));
337 		SHOW_INFO( 2, "FP2 GEN = %8lx", INREG( di->regs, RADEON_FP2_GEN_CNTL ));
338 		SHOW_INFO( 2, "TV DAC = %8lx", INREG( di->regs, RADEON_TV_DAC_CNTL )); //not setup right when ext dvi
339 //	}
340 
341 	result = Radeon_InitPCIGART( di );
342 	if( result < 0 )
343 		goto err5;
344 
345 	si->memory[mt_local].size = di->local_mem_size;
346 
347 	si->memory[mt_PCI].area = di->pci_gart.buffer.area;
348 	si->memory[mt_PCI].size = di->pci_gart.buffer.size;
349 
350 	// currently, defaultnon-local memory is PCI memory
351 	si->nonlocal_type = mt_PCI;
352 
353 	Radeon_InitMemController( di );
354 
355 	// currently, we don't support VBI - something is broken there
356 	// (it doesn't change a thing apart from crashing)
357 	result = Radeon_SetupIRQ( di, buffer );
358 	if( result < 0 )
359 		goto err4;
360 
361 	// resolution of 2D register is 1K, resolution of CRTC etc. is higher,
362 	// so 1K is the minimum block size;
363 	// (CP cannot use local mem)
364 	di->memmgr[mt_local] = mem_init("radeon local memory", 0, di->local_mem_size, 1024,
365 		di->local_mem_size / 1024);
366 	if (di->memmgr[mt_local] == NULL) {
367 		result = B_NO_MEMORY;
368 		goto err3;
369 	}
370 
371 	// CP requires 4K alignment, which is the most restrictive I found
372 	di->memmgr[mt_PCI] = mem_init("radeon PCI GART memory", 0, di->pci_gart.buffer.size, 4096,
373 		di->pci_gart.buffer.size / 4096);
374 	if (di->memmgr[mt_PCI] == NULL) {
375 		result = B_NO_MEMORY;
376 		goto err2;
377 	}
378 
379 	// no AGP support
380 	di->memmgr[mt_AGP] = NULL;
381 
382 	// fix AGP settings for IGP chipset
383 	Radeon_Set_AGP( di, !di->settings.force_pci ); // disable AGP
384 
385 
386 	// time to init Command Processor
387 	result = Radeon_InitCP( di );
388 	if( result != B_OK )
389 		goto err;
390 
391 	if ( di->acc_dma )
392 	{
393 		result = Radeon_InitDMA( di );
394 		if( result != B_OK )
395 			goto err0;
396 	}
397 	else
398 	{
399 		SHOW_INFO0( 0, "DMA is diabled using PIO mode");
400 	}
401 
402 //	mem_alloc( di->local_memmgr, 0x100000, (void *)-1, &dma_block, &dma_offset );
403 /*	dma_offset = 15 * 1024 * 1024;
404 
405 	si->nonlocal_mem = (uint32 *)((uint32)si->framebuffer + dma_offset);
406 	si->nonlocal_vm_start = (uint32)si->framebuffer_pci + dma_offset;*/
407 
408 	// set dynamic clocks for Mobilty chips
409 	if (di->is_mobility && di->settings.dynamic_clocks)
410 		Radeon_SetDynamicClock( di, 1);
411 
412 	return B_OK;
413 
414 err0:
415 	Radeon_UninitCP( di );
416 err:
417 	mem_destroy( di->memmgr[mt_PCI] );
418 err2:
419 	mem_destroy( di->memmgr[mt_local] );
420 err3:
421 	Radeon_CleanupIRQ( di );
422 err4:
423 	Radeon_CleanupPCIGART( di );
424 err5:
425 	Radeon_UnmapDevice( di );
426 err6:
427 	delete_area( di->virtual_card_area );
428 err7:
429 	delete_area( di->shared_area );
430 err8:
431 	return result;
432 }
433 
434 // clean up shared info on last close
435 // (we could for device destruction, but this makes
436 // testing easier as everythings gets cleaned up
437 // during tests)
438 void Radeon_LastClose( device_info *di )
439 {
440 	if ( di->acc_dma )
441 		Radeon_UninitCP( di );
442 
443 	// M6 fix - unfortunately, the device is never closed by app_server,
444 	// not even before reboot
445 	if( di->asic == rt_rv100 && di->is_mobility)
446 		OUTREG( di->regs, RADEON_DAC_CNTL2, di->dac2_cntl );
447 
448 
449 	mem_destroy( di->memmgr[mt_local] );
450 
451 	if( di->memmgr[mt_PCI] )
452 		mem_destroy( di->memmgr[mt_PCI] );
453 
454 	if( di->memmgr[mt_AGP] )
455 		mem_destroy( di->memmgr[mt_AGP] );
456 
457 	Radeon_CleanupIRQ( di );
458 	Radeon_CleanupPCIGART( di );
459 	Radeon_UnmapDevice(di);
460 
461 #ifdef ENABLE_LOGGING
462 #ifdef LOG_INCLUDE_STARTUP
463 	log_exit( di->si->log );
464 #endif
465 #endif
466 
467 	delete_area( di->virtual_card_area );
468 	delete_area( di->shared_area );
469 }
470