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