Skip to content

Commit

Permalink
drm/radeon/kms: consolidate GART code, fix segfault after GPU lockup V2
Browse files Browse the repository at this point in the history
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: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Jerome Glisse authored and Dave Airlie committed Nov 4, 2011
1 parent 0e2c978 commit c9a1be9
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 116 deletions.
12 changes: 2 additions & 10 deletions drivers/gpu/drm/radeon/evergreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down
13 changes: 2 additions & 11 deletions drivers/gpu/drm/radeon/ni.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
16 changes: 4 additions & 12 deletions drivers/gpu/drm/radeon/r300.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down
17 changes: 5 additions & 12 deletions drivers/gpu/drm/radeon/r600.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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++)
Expand All @@ -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)
Expand Down
22 changes: 5 additions & 17 deletions drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,30 +307,17 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
*/
struct radeon_mc;

struct radeon_gart_table_ram {
volatile uint32_t *ptr;
};

struct radeon_gart_table_vram {
struct radeon_bo *robj;
volatile uint32_t *ptr;
};

union radeon_gart_table {
struct radeon_gart_table_ram ram;
struct radeon_gart_table_vram vram;
};

#define RADEON_GPU_PAGE_SIZE 4096
#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
#define RADEON_GPU_PAGE_SHIFT 12

struct radeon_gart {
dma_addr_t table_addr;
struct radeon_bo *robj;
void *ptr;
unsigned num_gpu_pages;
unsigned num_cpu_pages;
unsigned table_size;
union radeon_gart_table table;
struct page **pages;
dma_addr_t *pages_addr;
bool *ttm_alloced;
Expand All @@ -341,13 +328,16 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev);
void radeon_gart_table_ram_free(struct radeon_device *rdev);
int radeon_gart_table_vram_alloc(struct radeon_device *rdev);
void radeon_gart_table_vram_free(struct radeon_device *rdev);
int radeon_gart_table_vram_pin(struct radeon_device *rdev);
void radeon_gart_table_vram_unpin(struct radeon_device *rdev);
int radeon_gart_init(struct radeon_device *rdev);
void radeon_gart_fini(struct radeon_device *rdev);
void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
int pages);
int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
int pages, struct page **pagelist,
dma_addr_t *dma_addr);
void radeon_gart_restore(struct radeon_device *rdev);


/*
Expand Down Expand Up @@ -1445,8 +1435,6 @@ void radeon_ring_write(struct radeon_device *rdev, uint32_t v);
/* AGP */
extern int radeon_gpu_reset(struct radeon_device *rdev);
extern void radeon_agp_disable(struct radeon_device *rdev);
extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
extern void radeon_gart_restore(struct radeon_device *rdev);
extern int radeon_modeset_init(struct radeon_device *rdev);
extern void radeon_modeset_fini(struct radeon_device *rdev);
extern bool radeon_card_posted(struct radeon_device *rdev);
Expand Down
Loading

0 comments on commit c9a1be9

Please sign in to comment.