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

Commit c9a1be96 authored by Jerome Glisse's avatar Jerome Glisse Committed by Dave Airlie
Browse files

drm/radeon/kms: consolidate GART code, fix segfault after GPU lockup V2



After GPU lockup VRAM gart table is unpinned and thus its pointer
becomes unvalid. This patch move the unpin code to a common helper
function and set pointer to NULL so that page update code can check
if it should update GPU page table or not. That way bo still bound
to GART can be unbound (pci_unmap_page for all there page) properly
while there is no need to update the GPU page table.

V2 move the test for null gart out of the loop, small optimization

Signed-off-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 0e2c978e
Loading
Loading
Loading
Loading
+2 −10
Original line number Diff line number Diff line
@@ -894,7 +894,7 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)
	u32 tmp;
	int r;

	if (rdev->gart.table.vram.robj == NULL) {
	if (rdev->gart.robj == NULL) {
		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
		return -EINVAL;
	}
@@ -946,7 +946,6 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)
void evergreen_pcie_gart_disable(struct radeon_device *rdev)
{
	u32 tmp;
	int r;

	/* Disable all tables */
	WREG32(VM_CONTEXT0_CNTL, 0);
@@ -966,14 +965,7 @@ void evergreen_pcie_gart_disable(struct radeon_device *rdev)
	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
	if (rdev->gart.table.vram.robj) {
		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
		if (likely(r == 0)) {
			radeon_bo_kunmap(rdev->gart.table.vram.robj);
			radeon_bo_unpin(rdev->gart.table.vram.robj);
			radeon_bo_unreserve(rdev->gart.table.vram.robj);
		}
	}
	radeon_gart_table_vram_unpin(rdev);
}

void evergreen_pcie_gart_fini(struct radeon_device *rdev)
+2 −11
Original line number Diff line number Diff line
@@ -935,7 +935,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
{
	int r;

	if (rdev->gart.table.vram.robj == NULL) {
	if (rdev->gart.robj == NULL) {
		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
		return -EINVAL;
	}
@@ -980,8 +980,6 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)

void cayman_pcie_gart_disable(struct radeon_device *rdev)
{
	int r;

	/* Disable all tables */
	WREG32(VM_CONTEXT0_CNTL, 0);
	WREG32(VM_CONTEXT1_CNTL, 0);
@@ -997,14 +995,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev)
	WREG32(VM_L2_CNTL2, 0);
	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
	if (rdev->gart.table.vram.robj) {
		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
		if (likely(r == 0)) {
			radeon_bo_kunmap(rdev->gart.table.vram.robj);
			radeon_bo_unpin(rdev->gart.table.vram.robj);
			radeon_bo_unreserve(rdev->gart.table.vram.robj);
		}
	}
	radeon_gart_table_vram_unpin(rdev);
}

void cayman_pcie_gart_fini(struct radeon_device *rdev)
+4 −2
Original line number Diff line number Diff line
@@ -577,7 +577,7 @@ int r100_pci_gart_init(struct radeon_device *rdev)
{
	int r;

	if (rdev->gart.table.ram.ptr) {
	if (rdev->gart.ptr) {
		WARN(1, "R100 PCI GART already initialized\n");
		return 0;
	}
@@ -636,10 +636,12 @@ void r100_pci_gart_disable(struct radeon_device *rdev)

int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
{
	u32 *gtt = rdev->gart.ptr;

	if (i < 0 || i > rdev->gart.num_gpu_pages) {
		return -EINVAL;
	}
	rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr));
	gtt[i] = cpu_to_le32(lower_32_bits(addr));
	return 0;
}

+4 −12
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)

int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
{
	void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
	void __iomem *ptr = rdev->gart.ptr;

	if (i < 0 || i > rdev->gart.num_gpu_pages) {
		return -EINVAL;
@@ -93,7 +93,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev)
{
	int r;

	if (rdev->gart.table.vram.robj) {
	if (rdev->gart.robj) {
		WARN(1, "RV370 PCIE GART already initialized\n");
		return 0;
	}
@@ -116,7 +116,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
	uint32_t tmp;
	int r;

	if (rdev->gart.table.vram.robj == NULL) {
	if (rdev->gart.robj == NULL) {
		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
		return -EINVAL;
	}
@@ -154,7 +154,6 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
void rv370_pcie_gart_disable(struct radeon_device *rdev)
{
	u32 tmp;
	int r;

	WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0);
	WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0);
@@ -163,14 +162,7 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
	tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
	tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
	WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
	if (rdev->gart.table.vram.robj) {
		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
		if (likely(r == 0)) {
			radeon_bo_kunmap(rdev->gart.table.vram.robj);
			radeon_bo_unpin(rdev->gart.table.vram.robj);
			radeon_bo_unreserve(rdev->gart.table.vram.robj);
		}
	}
	radeon_gart_table_vram_unpin(rdev);
}

void rv370_pcie_gart_fini(struct radeon_device *rdev)
+5 −12
Original line number Diff line number Diff line
@@ -895,7 +895,7 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
	/* flush hdp cache so updates hit vram */
	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
	    !(rdev->flags & RADEON_IS_AGP)) {
		void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
		void __iomem *ptr = (void *)rdev->gart.ptr;
		u32 tmp;

		/* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
@@ -930,7 +930,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev)
{
	int r;

	if (rdev->gart.table.vram.robj) {
	if (rdev->gart.robj) {
		WARN(1, "R600 PCIE GART already initialized\n");
		return 0;
	}
@@ -947,7 +947,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
	u32 tmp;
	int r, i;

	if (rdev->gart.table.vram.robj == NULL) {
	if (rdev->gart.robj == NULL) {
		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
		return -EINVAL;
	}
@@ -1002,7 +1002,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
void r600_pcie_gart_disable(struct radeon_device *rdev)
{
	u32 tmp;
	int i, r;
	int i;

	/* Disable all tables */
	for (i = 0; i < 7; i++)
@@ -1029,14 +1029,7 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
	if (rdev->gart.table.vram.robj) {
		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
		if (likely(r == 0)) {
			radeon_bo_kunmap(rdev->gart.table.vram.robj);
			radeon_bo_unpin(rdev->gart.table.vram.robj);
			radeon_bo_unreserve(rdev->gart.table.vram.robj);
		}
	}
	radeon_gart_table_vram_unpin(rdev);
}

void r600_pcie_gart_fini(struct radeon_device *rdev)
Loading