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
32extern radeon_settings current_settings;
33
34// map frame buffer and registers
35// mmio_only - true = map registers only (used during detection)
36status_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%08" B_PRIx32, 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,
64		"physical address of memory-mapped I/O: 0x%8" B_PRIx32 "-0x%8" B_PRIx32,
65		di->pcii.u.h0.base_registers[regs],
66		di->pcii.u.h0.base_registers[regs] + di->pcii.u.h0.base_register_sizes[regs] - 1 );
67
68	sprintf( buffer, "%04X_%04X_%02X%02X%02X regs",
69		di->pcii.vendor_id, di->pcii.device_id,
70		di->pcii.bus, di->pcii.device, di->pcii.function );
71
72	si->regs_area = map_physical_memory(
73		buffer,
74		di->pcii.u.h0.base_registers[regs],
75		di->pcii.u.h0.base_register_sizes[regs],
76		B_ANY_KERNEL_ADDRESS,
77		/*// for "poke" debugging
78		B_READ_AREA + B_WRITE_AREA*/
79		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA,
80		(void **)&(di->regs));
81	if( si->regs_area < 0 )
82		return si->regs_area;
83
84	// that's all during detection as we have no clue about ROM or
85	// frame buffer at this point
86	if( mmio_only )
87		return B_OK;
88
89	// ROM must be explicetely mapped by applications too
90	sprintf( buffer, "%04X_%04X_%02X%02X%02X ROM",
91		di->pcii.vendor_id, di->pcii.device_id,
92		di->pcii.bus, di->pcii.device, di->pcii.function );
93
94	si->ROM_area = map_physical_memory(
95		buffer,
96		di->rom.phys_address,
97		di->rom.size,
98		B_ANY_KERNEL_ADDRESS,
99		0,
100		(void **)&(di->rom.rom_ptr));
101	if( si->ROM_area < 0 ) {
102		result = si->ROM_area;
103		goto err2;
104	}
105
106	if( di->pcii.u.h0.base_register_sizes[fb] > di->local_mem_size ) {
107		// Radeons allocate more address range then really needed ->
108		// only map the area that contains physical memory
109		SHOW_INFO( 1,
110			"restrict frame buffer from 0x%8" B_PRIx32
111			" to 0x%8" B_PRIx32 " 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,
124		"physical address of framebuffer: 0x%8" B_PRIx32 "-0x%8" B_PRIx32,
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 | B_CLONEABLE_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 | B_CLONEABLE_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
164err:
165	delete_area( si->ROM_area );
166err2:
167	delete_area( si->regs_area );
168	return result;
169}
170
171
172// unmap PCI ranges
173void 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
201status_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		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA);
221	if (di->shared_area < 0) {
222		result = di->shared_area;
223		goto err8;
224	}
225
226	memset( di->si, 0, sizeof( *di->si ));
227
228	si = di->si;
229
230	si->settings = di->settings = current_settings;
231
232	if (di->settings.force_acc_dma)
233		di->acc_dma = true;
234	if (di->settings.force_acc_mmio) // force mmio will override dma... a tristate fuzzylogic, grey bool would be nice...
235		di->acc_dma = false;
236
237#ifdef ENABLE_LOGGING
238#ifdef LOG_INCLUDE_STARTUP
239	si->log = log_init( 1000000 );
240#endif
241#endif
242
243	// copy all info into shared info
244	si->vendor_id = di->pcii.vendor_id;
245	si->device_id = di->pcii.device_id;
246	si->revision = di->pcii.revision;
247
248	si->asic = di->asic;
249	si->is_mobility = di->is_mobility;
250	si->tv_chip = di->tv_chip;
251	si->new_pll = di->new_pll;
252	si->is_igp = di->is_igp;
253	si->has_no_i2c = di->has_no_i2c;
254	si->is_atombios = di->is_atombios;
255	si->is_mobility = di->is_mobility;
256	si->panel_pwr_delay = di->si->panel_pwr_delay;
257	si->acc_dma = di->acc_dma;
258
259	memcpy(&si->routing, &di->routing, sizeof(disp_entity));
260
261	// detecting theatre channel in kernel would lead to code duplication,
262	// so we let the first accelerant take care of it
263	si->theatre_channel = -1;
264
265	si->crtc[0].crtc_idx = 0;
266	si->crtc[0].flatpanel_port = 0;
267	si->crtc[1].crtc_idx = 1;
268	si->crtc[1].flatpanel_port = 1;
269	si->num_crtc = di->num_crtc;
270
271	if (di->is_mobility)
272		si->flatpanels[0] = di->fp_info;
273
274	si->pll = di->pll;
275
276	// create virtual card info; don't allow access by apps -
277	// they'll clone it
278	sprintf( buffer, "%04X_%04X_%02X%02X%02X virtual card 0",
279		di->pcii.vendor_id, di->pcii.device_id,
280		di->pcii.bus, di->pcii.device, di->pcii.function );
281	di->virtual_card_area = create_area(
282		buffer,
283		(void **)&(di->vc),
284		B_ANY_KERNEL_ADDRESS,
285		(sizeof(virtual_card) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1),
286		B_FULL_LOCK,
287		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA);
288	if (di->virtual_card_area < 0) {
289		result = di->virtual_card_area;
290		goto err7;
291	}
292
293	// currently, we assign fixed ports to this virtual card
294	di->vc->assigned_crtc[0] = true;
295	di->vc->assigned_crtc[1] = si->num_crtc > 1;
296	di->vc->controlled_displays =
297		dd_tv_crt | dd_crt | dd_lvds | dd_dvi | dd_dvi_ext | dd_ctv | dd_stv;
298
299	di->vc->fb_mem_handle = 0;
300	di->vc->cursor.mem_handle = 0;
301
302	// create unique id
303	di->vc->id = di->virtual_card_area;
304
305	result = Radeon_MapDevice( di, false );
306	if (result < 0)
307		goto err6;
308
309	// save dac2_cntl register
310	// on M6, we need to restore that during uninit, else you only get
311	// garbage on screen on reboot if both CRTCs are used
312	if( di->asic == rt_rv100 && di->is_mobility)
313		di->dac2_cntl = INREG( di->regs, RADEON_DAC_CNTL2 );
314
315	memcpy(&si->tmds_pll, &di->tmds_pll, sizeof(di->tmds_pll));
316	si->tmds_pll_cntl = INREG( di->regs, RADEON_TMDS_PLL_CNTL);
317	si->tmds_transmitter_cntl = INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL);
318
319	// print these out to capture bios status...
320//	if ( di->is_mobility ) {
321		SHOW_INFO0( 2, "Copy of Laptop Display Regs for Reference:");
322		SHOW_INFO( 2, "LVDS GEN = %8" B_PRIx32,
323			INREG( di->regs, RADEON_LVDS_GEN_CNTL ));
324		SHOW_INFO( 2, "LVDS PLL = %8" B_PRIx32,
325			INREG( di->regs, RADEON_LVDS_PLL_CNTL ));
326		SHOW_INFO( 2, "TMDS PLL = %8" B_PRIx32,
327			INREG( di->regs, RADEON_TMDS_PLL_CNTL ));
328		SHOW_INFO( 2, "TMDS TRANS = %8" B_PRIx32,
329			INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL ));
330		SHOW_INFO( 2, "FP1 GEN = %8" B_PRIx32,
331			INREG( di->regs, RADEON_FP_GEN_CNTL ));
332		SHOW_INFO( 2, "FP2 GEN = %8" B_PRIx32 ,
333			INREG( di->regs, RADEON_FP2_GEN_CNTL ));
334		SHOW_INFO( 2, "TV DAC = %8" B_PRIx32 ,
335			INREG( di->regs, RADEON_TV_DAC_CNTL )); //not setup right when ext dvi
336//	}
337
338	result = Radeon_InitPCIGART( di );
339	if( result < 0 )
340		goto err5;
341
342	si->memory[mt_local].size = di->local_mem_size;
343
344	si->memory[mt_PCI].area = di->pci_gart.buffer.area;
345	si->memory[mt_PCI].size = di->pci_gart.buffer.size;
346
347	// currently, defaultnon-local memory is PCI memory
348	si->nonlocal_type = mt_PCI;
349
350	Radeon_InitMemController( di );
351
352	// currently, we don't support VBI - something is broken there
353	// (it doesn't change a thing apart from crashing)
354	result = Radeon_SetupIRQ( di, buffer );
355	if( result < 0 )
356		goto err4;
357
358	// resolution of 2D register is 1K, resolution of CRTC etc. is higher,
359	// so 1K is the minimum block size;
360	// (CP cannot use local mem)
361	di->memmgr[mt_local] = mem_init("radeon local memory", 0, di->local_mem_size, 1024,
362		di->local_mem_size / 1024);
363	if (di->memmgr[mt_local] == NULL) {
364		result = B_NO_MEMORY;
365		goto err3;
366	}
367
368	// CP requires 4K alignment, which is the most restrictive I found
369	di->memmgr[mt_PCI] = mem_init("radeon PCI GART memory", 0, di->pci_gart.buffer.size, 4096,
370		di->pci_gart.buffer.size / 4096);
371	if (di->memmgr[mt_PCI] == NULL) {
372		result = B_NO_MEMORY;
373		goto err2;
374	}
375
376	// no AGP support
377	di->memmgr[mt_AGP] = NULL;
378
379	// fix AGP settings for IGP chipset
380	Radeon_Set_AGP( di, !di->settings.force_pci ); // disable AGP
381
382
383	// time to init Command Processor
384	result = Radeon_InitCP( di );
385	if( result != B_OK )
386		goto err;
387
388	if ( di->acc_dma )
389	{
390		result = Radeon_InitDMA( di );
391		if( result != B_OK )
392			goto err0;
393	}
394	else
395	{
396		SHOW_INFO0( 0, "DMA is diabled using PIO mode");
397	}
398
399//	mem_alloc( di->local_memmgr, 0x100000, (void *)-1, &dma_block, &dma_offset );
400/*	dma_offset = 15 * 1024 * 1024;
401
402	si->nonlocal_mem = (uint32 *)((uint32)si->framebuffer + dma_offset);
403	si->nonlocal_vm_start = (uint32)si->framebuffer_pci + dma_offset;*/
404
405	// set dynamic clocks for Mobilty chips
406	if (di->is_mobility && di->settings.dynamic_clocks)
407		Radeon_SetDynamicClock( di, 1);
408
409	return B_OK;
410
411err0:
412	Radeon_UninitCP( di );
413err:
414	mem_destroy( di->memmgr[mt_PCI] );
415err2:
416	mem_destroy( di->memmgr[mt_local] );
417err3:
418	Radeon_CleanupIRQ( di );
419err4:
420	Radeon_CleanupPCIGART( di );
421err5:
422	Radeon_UnmapDevice( di );
423err6:
424	delete_area( di->virtual_card_area );
425err7:
426	delete_area( di->shared_area );
427err8:
428	return result;
429}
430
431// clean up shared info on last close
432// (we could for device destruction, but this makes
433// testing easier as everythings gets cleaned up
434// during tests)
435void Radeon_LastClose( device_info *di )
436{
437	if ( di->acc_dma )
438		Radeon_UninitCP( di );
439
440	// M6 fix - unfortunately, the device is never closed by app_server,
441	// not even before reboot
442	if( di->asic == rt_rv100 && di->is_mobility)
443		OUTREG( di->regs, RADEON_DAC_CNTL2, di->dac2_cntl );
444
445
446	mem_destroy( di->memmgr[mt_local] );
447
448	if( di->memmgr[mt_PCI] )
449		mem_destroy( di->memmgr[mt_PCI] );
450
451	if( di->memmgr[mt_AGP] )
452		mem_destroy( di->memmgr[mt_AGP] );
453
454	Radeon_CleanupIRQ( di );
455	Radeon_CleanupPCIGART( di );
456	Radeon_UnmapDevice(di);
457
458#ifdef ENABLE_LOGGING
459#ifdef LOG_INCLUDE_STARTUP
460	log_exit( di->si->log );
461#endif
462#endif
463
464	delete_area( di->virtual_card_area );
465	delete_area( di->shared_area );
466}
467