Skip to content

Commit

Permalink
drm/radeon: add initial rs690 support to drm.
Browse files Browse the repository at this point in the history
This adds support for configuring the RS690 GART.

Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Maciej Cencora authored and Dave Airlie committed Feb 19, 2008
1 parent 00e962c commit 60f9268
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/char/drm/drm_pciids.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@
{0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
{0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
{0, 0, 0}

#define r128_PCI_IDS \
Expand Down
81 changes: 81 additions & 0 deletions drivers/char/drm/radeon_cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,11 +825,19 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
return ret;
}

static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
return RADEON_READ(RS690_MC_DATA);
}

u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
{

if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
else
Expand All @@ -840,6 +848,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
else
Expand All @@ -850,6 +860,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
else
Expand Down Expand Up @@ -1362,6 +1374,70 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
}
}

/* Enable or disable RS690 GART on the chip */
static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on)
{
u32 temp;

if (on) {
DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n",
dev_priv->gart_vm_start,
(long)dev_priv->gart_info.bus_addr,
dev_priv->gart_size);

temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL);
RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000);

RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);

temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID);
RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800);

RS690_WRITE_MCIND(RS690_MC_GART_BASE,
dev_priv->gart_info.bus_addr);

temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL);
RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000);

RS690_WRITE_MCIND(RS690_MC_AGP_BASE,
(unsigned int)dev_priv->gart_vm_start);

dev_priv->gart_size = 32*1024*1024;
temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
0xffff0000) | (dev_priv->gart_vm_start >> 16));

RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp);

temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE);
RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);

do {
temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
RS690_MC_GART_CLEAR_DONE)
break;
DRM_UDELAY(1);
} while (1);

RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
RS690_MC_GART_CC_CLEAR);
do {
temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
RS690_MC_GART_CLEAR_DONE)
break;
DRM_UDELAY(1);
} while (1);

RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
RS690_MC_GART_CC_NO_CHANGE);
} else {
RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS);
}
}

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);
Expand Down Expand Up @@ -1396,6 +1472,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;

if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
radeon_set_rs690gart(dev_priv, on);
return;
}

if (dev_priv->flags & RADEON_IS_IGPGART) {
radeon_set_igpgart(dev_priv, on);
return;
Expand Down
38 changes: 38 additions & 0 deletions drivers/char/drm/radeon_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ enum radeon_family {
CHIP_R420,
CHIP_RV410,
CHIP_RS400,
CHIP_RS690,
CHIP_RV515,
CHIP_R520,
CHIP_RV530,
Expand Down Expand Up @@ -467,6 +468,36 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
#define RADEON_IGPGART_ENABLE 0x38
#define RADEON_IGPGART_UNK_39 0x39

#define RS690_MC_INDEX 0x78
# define RS690_MC_INDEX_MASK 0x1ff
# define RS690_MC_INDEX_WR_EN (1 << 9)
# define RS690_MC_INDEX_WR_ACK 0x7f
#define RS690_MC_DATA 0x7c

#define RS690_MC_MISC_CNTL 0x18
#define RS690_MC_GART_FEATURE_ID 0x2b
#define RS690_MC_GART_BASE 0x2c
#define RS690_MC_GART_CACHE_CNTL 0x2e
# define RS690_MC_GART_CC_NO_CHANGE 0x0
# define RS690_MC_GART_CC_CLEAR 0x1
# define RS690_MC_GART_CLEAR_STATUS (1 << 1)
# define RS690_MC_GART_CLEAR_DONE (0 << 1)
# define RS690_MC_GART_CLEAR_PENDING (1 << 1)
#define RS690_MC_AGP_SIZE 0x38
# define RS690_MC_GART_DIS 0x0
# define RS690_MC_GART_EN 0x1
# define RS690_MC_AGP_SIZE_32MB (0 << 1)
# define RS690_MC_AGP_SIZE_64MB (1 << 1)
# define RS690_MC_AGP_SIZE_128MB (2 << 1)
# define RS690_MC_AGP_SIZE_256MB (3 << 1)
# define RS690_MC_AGP_SIZE_512MB (4 << 1)
# define RS690_MC_AGP_SIZE_1GB (5 << 1)
# define RS690_MC_AGP_SIZE_2GB (6 << 1)
#define RS690_MC_AGP_MODE_CONTROL 0x39
#define RS690_MC_FB_LOCATION 0x100
#define RS690_MC_AGP_LOCATION 0x101
#define RS690_MC_AGP_BASE 0x102

#define R520_MC_IND_INDEX 0x70
#define R520_MC_IND_WR_EN (1<<24)
#define R520_MC_IND_DATA 0x74
Expand Down Expand Up @@ -1076,6 +1107,13 @@ do { \
RADEON_WRITE(R520_MC_IND_INDEX, 0); \
} while (0)

#define RS690_WRITE_MCIND( addr, val ) \
do { \
RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \
RADEON_WRITE(RS690_MC_DATA, val); \
RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
} while (0)

#define CP_PACKET0( reg, n ) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET0_TABLE( reg, n ) \
Expand Down

0 comments on commit 60f9268

Please sign in to comment.