radeon: add support for reverse engineered xpress200m

The IGPGART setup code was traced using mmio-trace on fglrx by myself
and Phillip Ezolt <phillipezolt@gmail.com> on dri-devel.

This code doesn't let the 3D driver work properly as the card has no
vertex shader support.

Thanks to Matthew Garrett + Ubuntu for providing me some hardware to do this
work on.
This commit is contained in:
Dave Airlie 2007-04-09 21:52:59 +10:00
parent b25558bb73
commit a70f8e0ab2
6 changed files with 98 additions and 8 deletions

View file

@ -205,10 +205,18 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
page_base = (u32) entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
if (gart_info->is_pcie)
switch(gart_info->gart_reg_if) {
case DRM_ATI_GART_IGP:
*pci_gart = cpu_to_le32((page_base) | 0xc);
break;
case DRM_ATI_GART_PCIE:
*pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
else
break;
default:
case DRM_ATI_GART_PCI:
*pci_gart = cpu_to_le32(page_base);
break;
}
pci_gart++;
page_base += ATI_PCIGART_PAGE_SIZE;
}

View file

@ -587,9 +587,13 @@ typedef struct drm_vbl_sig {
#define DRM_ATI_GART_MAIN 1
#define DRM_ATI_GART_FB 2
#define DRM_ATI_GART_PCI 1
#define DRM_ATI_GART_PCIE 2
#define DRM_ATI_GART_IGP 3
typedef struct ati_pcigart_info {
int gart_table_location;
int is_pcie;
int gart_reg_if;
void *addr;
dma_addr_t bus_addr;
drm_local_map_t mapping;

View file

@ -98,6 +98,7 @@
0x1002 0x5653 CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X700 M26"
0x1002 0x5834 CHIP_RS300|RADEON_IS_IGP "ATI Radeon RS300 9100 IGP"
0x1002 0x5835 CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY "ATI Radeon RS300 Mobility IGP"
0x1002 0x5955 CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon XPRESS 200M 5955"
0x1002 0x5960 CHIP_RV280 "ATI Radeon RV280 9250"
0x1002 0x5961 CHIP_RV280 "ATI Radeon RV280 9200"
0x1002 0x5962 CHIP_RV280 "ATI Radeon RV280 9200"

View file

@ -563,7 +563,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
dev_priv->gart_info.addr = NULL;
dev_priv->gart_info.bus_addr = 0;
dev_priv->gart_info.is_pcie = 0;
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
DRM_ERROR("failed to init PCI GART!\n");
dev->dev_private = (void *)dev_priv;

View file

@ -824,12 +824,21 @@ static int RADEON_READ_PLL(drm_device_t * dev, int addr)
return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
}
static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
{
RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
return RADEON_READ(RADEON_PCIE_DATA);
}
static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
{
u32 ret;
RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f);
ret = RADEON_READ(RADEON_IGPGART_DATA);
RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f);
return ret;
}
#if RADEON_FIFO_DEBUG
static void radeon_status(drm_radeon_private_t * dev_priv)
{
@ -1266,7 +1275,45 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
}
}
/* Enable or disable PCI-E GART on the chip */
/* Enable or disable IGP GART on the chip */
static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
{
u32 temp, tmp;
tmp = RADEON_READ(RADEON_AIC_CNTL);
DRM_DEBUG("setting igpgart AIC CNTL is %08X\n", tmp);
if (on) {
DRM_DEBUG("programming igpgart %08X %08lX %08X\n",
dev_priv->gart_vm_start,
(long)dev_priv->gart_info.bus_addr,
dev_priv->gart_size);
RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000);
RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_38, 0x1);
RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800);
RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR,
dev_priv->gart_info.bus_addr);
temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39);
RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp);
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
dev_priv->gart_size = 32*1024*1024;
RADEON_WRITE(RADEON_MC_AGP_LOCATION,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
(dev_priv->gart_vm_start >> 16)));
temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_38);
RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_38, temp);
RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_2E);
RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_2E, 0x1);
RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_2E);
RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_2E, 0x0);
}
}
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@ -1301,6 +1348,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;
if (dev_priv->flags & RADEON_IS_IGPGART) {
radeon_set_igpgart(dev_priv, on);
return;
}
if (dev_priv->flags & RADEON_IS_PCIE) {
radeon_set_pciegart(dev_priv, on);
return;
@ -1635,8 +1687,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev_priv->gart_info.addr =
dev_priv->gart_info.mapping.handle;
dev_priv->gart_info.is_pcie =
!!(dev_priv->flags & RADEON_IS_PCIE);
if (dev_priv->flags & RADEON_IS_PCIE)
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
else
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
dev_priv->gart_info.gart_table_location =
DRM_ATI_GART_FB;
@ -1644,6 +1698,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev_priv->gart_info.addr,
dev_priv->pcigart_offset);
} else {
if (dev_priv->flags & RADEON_IS_IGPGART)
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
else
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
dev_priv->gart_info.gart_table_location =
DRM_ATI_GART_MAIN;
dev_priv->gart_info.addr = NULL;

View file

@ -145,6 +145,7 @@ enum radeon_chip_flags {
RADEON_IS_PCIE = 0x00200000UL,
RADEON_NEW_MEMMAP = 0x00400000UL,
RADEON_IS_PCI = 0x00800000UL,
RADEON_IS_IGPGART = 0x01000000UL,
};
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
@ -432,6 +433,16 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,
#define RADEON_PCIE_TX_GART_END_LO 0x16
#define RADEON_PCIE_TX_GART_END_HI 0x17
#define RADEON_IGPGART_INDEX 0x168
#define RADEON_IGPGART_DATA 0x16c
#define RADEON_IGPGART_UNK_18 0x18
#define RADEON_IGPGART_CTRL 0x2b
#define RADEON_IGPGART_BASE_ADDR 0x2c
#define RADEON_IGPGART_UNK_2E 0x2e
#define RADEON_IGPGART_UNK_38 0x38
#define RADEON_IGPGART_UNK_39 0x39
#define RADEON_MPP_TB_CONFIG 0x01c0
#define RADEON_MEM_CNTL 0x0140
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
@ -994,6 +1005,14 @@ do { \
RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
} while (0)
#define RADEON_WRITE_IGPGART( addr, val ) \
do { \
RADEON_WRITE( RADEON_IGPGART_INDEX, \
((addr) & 0x7f) | (1 << 8)); \
RADEON_WRITE( RADEON_IGPGART_DATA, (val) ); \
RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f ); \
} while (0)
#define RADEON_WRITE_PCIE( addr, val ) \
do { \
RADEON_WRITE8( RADEON_PCIE_INDEX, \