Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60f92683 authored by Maciej Cencora's avatar Maciej Cencora Committed by Dave Airlie
Browse files

drm/radeon: add initial rs690 support to drm.



This adds support for configuring the RS690 GART.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 00e962c5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 \
+81 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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
@@ -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);
@@ -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;
+38 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ enum radeon_family {
	CHIP_R420,
	CHIP_RV410,
	CHIP_RS400,
	CHIP_RS690,
	CHIP_RV515,
	CHIP_R520,
	CHIP_RV530,
@@ -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
@@ -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 )					\