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

Commit 65337e60 authored by Samuel Li's avatar Samuel Li Committed by Alex Deucher
Browse files

drm/radeon: Use direct mapping for fast fb access on RS780/RS880 (v2)



v2: fix trailing whitespace

Signed-off-by: default avatarSamuel Li <samuel.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e49f3959
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -1046,6 +1046,24 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
	return -1;
}

uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg)
{
	uint32_t r;

	WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg));
	r = RREG32(R_0028FC_MC_DATA);
	WREG32(R_0028F8_MC_INDEX, ~C_0028F8_MC_IND_ADDR);
	return r;
}

void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
	WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg) |
		S_0028F8_MC_IND_WR_EN(1));
	WREG32(R_0028FC_MC_DATA, v);
	WREG32(R_0028F8_MC_INDEX, 0x7F);
}

static void r600_mc_program(struct radeon_device *rdev)
{
	struct rv515_mc_save save;
@@ -1181,6 +1199,8 @@ static int r600_mc_init(struct radeon_device *rdev)
{
	u32 tmp;
	int chansize, numchan;
	uint32_t h_addr, l_addr;
	unsigned long long k8_addr;

	/* Get VRAM informations */
	rdev->mc.vram_is_ddr = true;
@@ -1221,7 +1241,30 @@ static int r600_mc_init(struct radeon_device *rdev)
	if (rdev->flags & RADEON_IS_IGP) {
		rs690_pm_info(rdev);
		rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);

		if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
			/* Use K8 direct mapping for fast fb access. */
			rdev->fastfb_working = false;
			h_addr = G_000012_K8_ADDR_EXT(RREG32_MC(R_000012_MC_MISC_UMA_CNTL));
			l_addr = RREG32_MC(R_000011_K8_FB_LOCATION);
			k8_addr = ((unsigned long long)h_addr) << 32 | l_addr;
#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
			if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL)
#endif
			{
				/* FastFB shall be used with UMA memory. Here it is simply disabled when sideport
		 		* memory is present.
		 		*/
				if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) {
					DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n",
						(unsigned long long)rdev->mc.aper_base, k8_addr);
					rdev->mc.aper_base = (resource_size_t)k8_addr;
					rdev->fastfb_working = true;
				}
			}
  		}
	}

	radeon_update_bandwidth_info(rdev);
	return 0;
}
+8 −0
Original line number Diff line number Diff line
@@ -1342,6 +1342,14 @@
#define	PACKET3_STRMOUT_BASE_UPDATE			0x72 /* r7xx */
#define	PACKET3_SURFACE_BASE_UPDATE			0x73

#define R_000011_K8_FB_LOCATION                 0x11
#define R_000012_MC_MISC_UMA_CNTL               0x12
#define   G_000012_K8_ADDR_EXT(x)               (((x) >> 0) & 0xFF)
#define R_0028F8_MC_INDEX			0x28F8
#define   	S_0028F8_MC_IND_ADDR(x)                 (((x) & 0x1FF) << 0)
#define   	C_0028F8_MC_IND_ADDR                    0xFFFFFE00
#define   	S_0028F8_MC_IND_WR_EN(x)                (((x) & 0x1) << 9)
#define R_0028FC_MC_DATA                        0x28FC

#define	R_008020_GRBM_SOFT_RESET		0x8020
#define		S_008020_SOFT_RESET_CP(x)		(((x) & 1) << 0)
+4 −0
Original line number Diff line number Diff line
@@ -122,6 +122,10 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
		rdev->mc_rreg = &rs600_mc_rreg;
		rdev->mc_wreg = &rs600_mc_wreg;
	}
	if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
		rdev->mc_rreg = &rs780_mc_rreg;
		rdev->mc_wreg = &rs780_mc_wreg;
	}
	if (rdev->family >= CHIP_R600) {
		rdev->pciep_rreg = &r600_pciep_rreg;
		rdev->pciep_wreg = &r600_pciep_wreg;
+2 −0
Original line number Diff line number Diff line
@@ -347,6 +347,8 @@ extern bool r600_gui_idle(struct radeon_device *rdev);
extern void r600_pm_misc(struct radeon_device *rdev);
extern void r600_pm_init_profile(struct radeon_device *rdev);
extern void rs780_pm_init_profile(struct radeon_device *rdev);
extern uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg);
extern void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
extern int r600_get_pcie_lanes(struct radeon_device *rdev);