1/*
2	Copyright (c) 2002, Thomas Kurschel
3
4
5	Part of Radeon kernel driver
6
7	Memory controller setup.
8
9	The memory controller of the Radeon provides a universal mapping
10	from addresses generated by the different DMA units within the
11	graphics chip to addresses in local/PCI/AGP memory. Here, we
12	set this mapping up.
13
14	Further we initialize some bus controller registers here (where bus
15	means non-local memory interface).
16*/
17
18#include "radeon_driver.h"
19#include "buscntrl_regs.h"
20#include "config_regs.h"
21#include "mmio.h"
22#include "memcntrl_regs.h"
23
24
25// get last RAM address + 1, i.e. first unused physical address
26static uint32 getTopOfRam()
27{
28	system_info info;
29
30	// there is no function to really get this info;
31	// as a hack, we ask for number of physical RAM pages and hope
32	// they are contigous, starting at address 0
33	get_system_info( &info );
34
35	return info.max_pages * 4096;
36}
37
38// graphics card addresses correspond to physical CPU addresses as much as possible
39static void Radeon_SetupMCAddresses_Direct( device_info *di )
40{
41	shared_info *si = di->si;
42	uint32 aper0 = INREG( di->regs, RADEON_CONFIG_APER_0_BASE );
43
44	// bug in asics mean memory must be aligned to memory size...
45	if ( IS_DI_R300_VARIANT || di->asic == rt_rv280 ) {
46		aper0 &= ~( di->local_mem_size - 1 );
47	}
48
49	// set address range of video memory;
50	// use the same addresses the CPU sees
51	si->memory[mt_local].virtual_addr_start = aper0;
52	si->memory[mt_local].virtual_size = di->local_mem_size;
53
54	// PCI GART has no corresponding CPU address space, so we must find an unused
55	// one; we assume that the addresses directly after physical RAM are
56	// not in use as the BIOS should have allocated address for PCI devices
57	// starting with highest address possible.
58	// no problem in terms of alignment: it must be a multiple 4K only
59	si->memory[mt_PCI].virtual_addr_start = (getTopOfRam() + 4095) & ~4095;
60	si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;
61
62	// similar problem with AGP: though there _is_ a corresponding CPU address space,
63	// we don't know it (this would require finding the AGP bridge and
64	// getting info from there, which would be a dangerous hack);
65	// solution is to locate AGP aperture directly after PCI GART;
66	// we define a 4 MB aperture to meet any possible alignment restrictions
67	si->memory[mt_AGP].virtual_addr_start =
68		(si->memory[mt_PCI].virtual_addr_start + si->memory[mt_PCI].virtual_size
69		+ 0x3fffff) & ~0x3fffff;
70	si->memory[mt_AGP].virtual_size = 0x400000;
71
72}
73
74
75#if 0
76// graphics card addresses are mapped in a way to restrict direct main memory access
77static void Radeon_SetupMCAddresses_Safe( device_info *di )
78{
79	shared_info *si = di->si;
80
81	// any address not covered by frame buffer, PCI GART or AGP aperture
82	// leads to a direct memory access
83	// -> this is dangerous, so we make sure entire address space is mapped
84
85	// locate PCI GART at top of address space
86	// warning about size: there are quite strong alignment restrictions,
87	// so we better obey!
88	si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;
89	si->memory[mt_PCI].virtual_addr_start = 0 - si->memory[mt_PCI].virtual_size;
90
91	// let AGP range overlap with frame buffer to hide it;
92	// according to spec, frame buffer should win but we better
93	// choose an unused-area to avoid trouble
94	// (specs don't talk about overlapping area, let's hope
95	// the memory controller won't choke if we ever access it)
96	si->memory[mt_AGP].virtual_size = 0x400000;
97	si->memory[mt_AGP].virtual_addr_start =
98		si->memory[mt_PCI].virtual_addr_start -
99		si->memory[mt_AGP].virtual_size;
100
101	// set address range of video memory
102	// let it cover all remaining addresses;
103	// addresses are wrapped
104	si->memory[mt_local].virtual_addr_start = 0;
105	si->memory[mt_local].virtual_size =
106		si->memory[mt_AGP].virtual_addr_start -
107		si->memory[mt_local].virtual_addr_start;
108}
109#endif
110
111// graphics cards addresses are mapped IGP compliantly
112static void Radeon_SetupMCAddresses_IGP( device_info *di )
113{
114	shared_info *si = di->si;
115	uint32 tom;
116
117	// the frame buffer memory address range is read from TOM register
118	// it located at end of physical RAM (at least it seems so)
119	tom = INREG( di->regs, RADEON_NB_TOM );
120	si->memory[mt_local].virtual_addr_start = (tom & 0xffff) << 16;
121	si->memory[mt_local].virtual_size =
122		(((tom >> 16) + 1) << 16) -
123		si->memory[mt_local].virtual_addr_start;
124
125	// after the frame buffer, physical memory should end and unused
126	// physical addresses start - good location to put the PCI GART to
127	si->memory[mt_PCI].virtual_addr_start = ((((tom >> 16) + 1) << 16) + 4095) & ~4095;
128	si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;
129
130	// locate AGP aperture after PCI GART
131	si->memory[mt_AGP].virtual_addr_start =
132		(si->memory[mt_PCI].virtual_addr_start +
133		si->memory[mt_PCI].virtual_size + 0x3fffff) & ~0x3fffff;
134	si->memory[mt_AGP].virtual_size = 0x400000;
135
136}
137
138void Radeon_InitMemController( device_info *di )
139{
140	vuint8 *regs = di->regs;
141	shared_info *si = di->si;
142
143	if( di->is_igp )
144		Radeon_SetupMCAddresses_IGP( di );
145	else
146		Radeon_SetupMCAddresses_Direct/*Radeon_SetupMCAddresses_Safe*/( di );
147
148	SHOW_INFO0( 3, "Graphics card address mapping:" );
149	SHOW_INFO( 3, " local memory 0x%" B_PRIx32 "@0x%" B_PRIx32,
150		si->memory[mt_local].virtual_size, si->memory[mt_local].virtual_addr_start );
151	SHOW_INFO( 3, " PCI GART 0x%" B_PRIx32 "@0x%" B_PRIx32,
152		si->memory[mt_PCI].virtual_size, si->memory[mt_PCI].virtual_addr_start );
153	SHOW_INFO( 3, " disabled AGP GART 0x%" B_PRIx32 "@0x%" B_PRIx32,
154		si->memory[mt_AGP].virtual_size, si->memory[mt_AGP].virtual_addr_start );
155
156	//si->nonlocal_mem = di->DMABuffer.ptr;
157
158	// Turn on PCI GART
159	OUTREGP( regs, RADEON_AIC_CNTL, RADEON_PCIGART_TRANSLATE_EN,
160		~RADEON_PCIGART_TRANSLATE_EN );
161
162	// set PCI GART page-table base address
163	OUTREG( regs, RADEON_AIC_PT_BASE, di->pci_gart.GATT.phys );
164
165	// set address range for PCI address translation
166	// we must restrict range to the actually used GART size here!
167	OUTREG( regs, RADEON_AIC_LO_ADDR, si->memory[mt_PCI].virtual_addr_start );
168	OUTREG( regs, RADEON_AIC_HI_ADDR, si->memory[mt_PCI].virtual_addr_start +
169		si->memory[mt_PCI].virtual_size/*di->pci_gart.buffer.size*/ - 1 );
170
171	// set AGP address range
172	OUTREG( regs, RADEON_MC_AGP_LOCATION, 0xffffffc0 /* EK magic numbers from X.org
173		(si->memory[mt_AGP].virtual_addr_start >> 16) |
174		((si->memory[mt_AGP].virtual_addr_start + si->memory[mt_AGP].virtual_size - 1) & 0xffff0000 )*/);
175
176	// disable AGP
177	OUTREG( regs, RADEON_AGP_COMMAND, 0 );
178
179	// set address range of video memory
180	// (lower word = begin >> 16
181	//  upper word = end >> 16)
182	OUTREG( regs, RADEON_MC_FB_LOCATION,
183		((si->memory[mt_local].virtual_addr_start + si->memory[mt_local].virtual_size - 1) & 0xffff0000) |
184		 (si->memory[mt_local].virtual_addr_start >> 16) );
185
186	// base address of CRTC and others must be same as frame buffer address
187	// (we could specify any address too, but local memory is of course first choice)
188	OUTREG( regs, RADEON_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
189	OUTREG( regs, RADEON_CRTC2_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
190	OUTREG( regs, RADEON_OV0_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
191
192	// fix some bus controller setting
193	// I reckon this takes care of discarding data unnecessarily read
194	// during a burst; let's hope this will fix the nasty CP crashing problem
195	// EK this seems unecessary. OUTREGP( regs, RADEON_BUS_CNTL, RADEON_BUS_RD_DISCARD_EN, ~RADEON_BUS_RD_DISCARD_EN );
196
197//	SHOW_FLOW0( 3, "done" );
198}
199
200