2 Copyright (c) 2002, Thomas Kurschel
5 Part of Radeon kernel driver
7 Memory controller setup.
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
14 Further we initialize some bus controller registers here (where bus
15 means non-local memory interface).
18 #include "radeon_driver.h"
19 #include "buscntrl_regs.h"
20 #include "config_regs.h"
22 #include "memcntrl_regs.h"
25 // get last RAM address + 1, i.e. first unused physical address
26 static uint32
getTopOfRam()
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
);
35 return info
.max_pages
* 4096;
38 // graphics card addresses correspond to physical CPU addresses as much as possible
39 static void Radeon_SetupMCAddresses_Direct( device_info
*di
)
41 shared_info
*si
= di
->si
;
42 uint32 aper0
= INREG( di
->regs
, RADEON_CONFIG_APER_0_BASE
);
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 );
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
;
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
;
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;
76 // graphics card addresses are mapped in a way to restrict direct main memory access
77 static void Radeon_SetupMCAddresses_Safe( device_info
*di
)
79 shared_info
*si
= di
->si
;
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
85 // locate PCI GART at top of address space
86 // warning about size: there are quite strong alignment restrictions,
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
;
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
;
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
;
111 // graphics cards addresses are mapped IGP compliantly
112 static void Radeon_SetupMCAddresses_IGP( device_info
*di
)
114 shared_info
*si
= di
->si
;
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
;
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
;
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;
138 void Radeon_InitMemController( device_info
*di
)
140 vuint8
*regs
= di
->regs
;
141 shared_info
*si
= di
->si
;
144 Radeon_SetupMCAddresses_IGP( di
);
146 Radeon_SetupMCAddresses_Direct
/*Radeon_SetupMCAddresses_Safe*/( di
);
148 SHOW_INFO0( 3, "Graphics card address mapping:" );
149 SHOW_INFO( 3, " local memory 0x%lx@0x%lx",
150 si
->memory
[mt_local
].virtual_size
, si
->memory
[mt_local
].virtual_addr_start
);
151 SHOW_INFO( 3, " PCI GART 0x%lx@0x%lx",
152 si
->memory
[mt_PCI
].virtual_size
, si
->memory
[mt_PCI
].virtual_addr_start
);
153 SHOW_INFO( 3, " disabled AGP GART 0x%lx@0x%lx",
154 si
->memory
[mt_AGP
].virtual_size
, si
->memory
[mt_AGP
].virtual_addr_start
);
156 //si->nonlocal_mem = di->DMABuffer.ptr;
159 OUTREGP( regs
, RADEON_AIC_CNTL
, RADEON_PCIGART_TRANSLATE_EN
,
160 ~RADEON_PCIGART_TRANSLATE_EN
);
162 // set PCI GART page-table base address
163 OUTREG( regs
, RADEON_AIC_PT_BASE
, di
->pci_gart
.GATT
.phys
);
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 );
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 )*/);
177 OUTREG( regs
, RADEON_AGP_COMMAND
, 0 );
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) );
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
);
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 );
197 // SHOW_FLOW0( 3, "done" );