Copyright (c) 2002, Thomas Kurschel
Part of Radeon kernel driver
Memory controller setup.
The memory controller of the Radeon provides a universal mapping
from addresses generated by the different DMA units within the
graphics chip to addresses in local/PCI/AGP memory. Here, we
set this mapping up.
Further we initialize some bus controller registers here (where bus
means non-local memory interface).
*/
#include "radeon_driver.h"
#include "buscntrl_regs.h"
#include "config_regs.h"
#include "mmio.h"
#include "memcntrl_regs.h"
static uint32 getTopOfRam()
{
system_info info;
get_system_info( &info );
return info.max_pages * 4096;
}
static void Radeon_SetupMCAddresses_Direct( device_info *di )
{
shared_info *si = di->si;
uint32 aper0 = INREG( di->regs, RADEON_CONFIG_APER_0_BASE );
if ( IS_DI_R300_VARIANT || di->asic == rt_rv280 ) {
aper0 &= ~( di->local_mem_size - 1 );
}
si->memory[mt_local].virtual_addr_start = aper0;
si->memory[mt_local].virtual_size = di->local_mem_size;
si->memory[mt_PCI].virtual_addr_start = (getTopOfRam() + 4095) & ~4095;
si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;
si->memory[mt_AGP].virtual_addr_start =
(si->memory[mt_PCI].virtual_addr_start + si->memory[mt_PCI].virtual_size
+ 0x3fffff) & ~0x3fffff;
si->memory[mt_AGP].virtual_size = 0x400000;
}
#if 0
static void Radeon_SetupMCAddresses_Safe( device_info *di )
{
shared_info *si = di->si;
si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;
si->memory[mt_PCI].virtual_addr_start = 0 - si->memory[mt_PCI].virtual_size;
si->memory[mt_AGP].virtual_size = 0x400000;
si->memory[mt_AGP].virtual_addr_start =
si->memory[mt_PCI].virtual_addr_start -
si->memory[mt_AGP].virtual_size;
si->memory[mt_local].virtual_addr_start = 0;
si->memory[mt_local].virtual_size =
si->memory[mt_AGP].virtual_addr_start -
si->memory[mt_local].virtual_addr_start;
}
#endif
static void Radeon_SetupMCAddresses_IGP( device_info *di )
{
shared_info *si = di->si;
uint32 tom;
tom = INREG( di->regs, RADEON_NB_TOM );
si->memory[mt_local].virtual_addr_start = (tom & 0xffff) << 16;
si->memory[mt_local].virtual_size =
(((tom >> 16) + 1) << 16) -
si->memory[mt_local].virtual_addr_start;
si->memory[mt_PCI].virtual_addr_start = ((((tom >> 16) + 1) << 16) + 4095) & ~4095;
si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;
si->memory[mt_AGP].virtual_addr_start =
(si->memory[mt_PCI].virtual_addr_start +
si->memory[mt_PCI].virtual_size + 0x3fffff) & ~0x3fffff;
si->memory[mt_AGP].virtual_size = 0x400000;
}
void Radeon_InitMemController( device_info *di )
{
vuint8 *regs = di->regs;
shared_info *si = di->si;
if( di->is_igp )
Radeon_SetupMCAddresses_IGP( di );
else
Radeon_SetupMCAddresses_Direct( di );
SHOW_INFO0( 3, "Graphics card address mapping:" );
SHOW_INFO( 3, " local memory 0x%" B_PRIx32 "@0x%" B_PRIx32,
si->memory[mt_local].virtual_size, si->memory[mt_local].virtual_addr_start );
SHOW_INFO( 3, " PCI GART 0x%" B_PRIx32 "@0x%" B_PRIx32,
si->memory[mt_PCI].virtual_size, si->memory[mt_PCI].virtual_addr_start );
SHOW_INFO( 3, " disabled AGP GART 0x%" B_PRIx32 "@0x%" B_PRIx32,
si->memory[mt_AGP].virtual_size, si->memory[mt_AGP].virtual_addr_start );
OUTREGP( regs, RADEON_AIC_CNTL, RADEON_PCIGART_TRANSLATE_EN,
~RADEON_PCIGART_TRANSLATE_EN );
OUTREG( regs, RADEON_AIC_PT_BASE, di->pci_gart.GATT.phys );
OUTREG( regs, RADEON_AIC_LO_ADDR, si->memory[mt_PCI].virtual_addr_start );
OUTREG( regs, RADEON_AIC_HI_ADDR, si->memory[mt_PCI].virtual_addr_start +
si->memory[mt_PCI].virtual_size - 1 );
OUTREG( regs, RADEON_MC_AGP_LOCATION, 0xffffffc0
(si->memory[mt_AGP].virtual_addr_start >> 16) |
((si->memory[mt_AGP].virtual_addr_start + si->memory[mt_AGP].virtual_size - 1) & 0xffff0000 )*/);
OUTREG( regs, RADEON_AGP_COMMAND, 0 );
OUTREG( regs, RADEON_MC_FB_LOCATION,
((si->memory[mt_local].virtual_addr_start + si->memory[mt_local].virtual_size - 1) & 0xffff0000) |
(si->memory[mt_local].virtual_addr_start >> 16) );
OUTREG( regs, RADEON_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
OUTREG( regs, RADEON_CRTC2_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
OUTREG( regs, RADEON_OV0_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
}