[PATCH 1/2] drm/radeon: add readonly flag to radeon_gart_set_page v3

Alex Deucher alexdeucher at gmail.com
Fri Jul 11 07:09:43 PDT 2014


On Fri, Jul 11, 2014 at 9:56 AM, Christian König
<deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at amd.com>
>
> v2: use flag instead of boolean
> v3: keep R600_PTE_GART as it is
>
> Signed-off-by: Christian König <christian.koenig at amd.com>
> ---
>  drivers/gpu/drm/radeon/r100.c        |  2 +-
>  drivers/gpu/drm/radeon/r300.c        |  8 ++++++--
>  drivers/gpu/drm/radeon/radeon.h      | 10 ++++++----
>  drivers/gpu/drm/radeon/radeon_asic.h |  8 ++++----
>  drivers/gpu/drm/radeon/radeon_gart.c |  9 +++++----
>  drivers/gpu/drm/radeon/radeon_ttm.c  |  4 ++--
>  drivers/gpu/drm/radeon/rs400.c       |  9 +++++++--
>  drivers/gpu/drm/radeon/rs600.c       |  8 ++++++--
>  8 files changed, 37 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index e32abf3..f58b5d1 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -650,7 +650,7 @@ void r100_pci_gart_disable(struct radeon_device *rdev)
>  }
>
>  void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i,
> -                           uint64_t addr)
> +                           uint64_t addr, uint32_t flags)
>  {
>         u32 *gtt = rdev->gart.ptr;
>         gtt[i] = cpu_to_le32(lower_32_bits(addr));
> diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
> index 8d14e66..b947f42 100644
> --- a/drivers/gpu/drm/radeon/r300.c
> +++ b/drivers/gpu/drm/radeon/r300.c
> @@ -73,13 +73,17 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
>  #define R300_PTE_READABLE  (1 << 3)
>
>  void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i,
> -                             uint64_t addr)
> +                             uint64_t addr, uint32_t flags)
>  {
>         void __iomem *ptr = rdev->gart.ptr;
>
>         addr = (lower_32_bits(addr) >> 8) |
>                ((upper_32_bits(addr) & 0xff) << 24) |
> -              R300_PTE_WRITEABLE | R300_PTE_READABLE;
> +              R300_PTE_READABLE;
> +
> +       if (!(flags & RADEON_GART_PAGE_READONLY))
> +               addr |= R300_PTE_WRITEABLE;
> +
>         /* on x86 we want this to be CPU endian, on powerpc
>          * on powerpc without HW swappers, it'll get swapped on way
>          * into VRAM - so no need for cpu_to_le32 on VRAM tables */
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 7cda75d..8a190ce 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -592,6 +592,8 @@ struct radeon_mc;
>  #define RADEON_GPU_PAGE_SHIFT 12
>  #define RADEON_GPU_PAGE_ALIGN(a) (((a) + RADEON_GPU_PAGE_MASK) & ~RADEON_GPU_PAGE_MASK)
>
> +#define RADEON_GART_PAGE_READONLY      1

This is fine for now, but once we add more flags we should change them
to reflect the usage.  E.g.,
RADEON_GART_PAGE_READ
RADEON_GART_PAGE_WRITE
RADEON_GART_PAGE_SNOOP
and set them explicitly.

Alex

> +
>  struct radeon_gart {
>         dma_addr_t                      table_addr;
>         struct radeon_bo                *robj;
> @@ -616,7 +618,7 @@ 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);
> +                    dma_addr_t *dma_addr, uint32_t flags);
>
>
>  /*
> @@ -855,7 +857,7 @@ struct radeon_mec {
>
>  /* flags used for GART page table entries on R600+ */
>  #define R600_PTE_GART  ( R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED \
> -                       | R600_PTE_READABLE | R600_PTE_WRITEABLE)
> +                       | R600_PTE_READABLE | R600_PTE_WRITEABLE )
>
>  struct radeon_vm_pt {
>         struct radeon_bo                *bo;
> @@ -1775,7 +1777,7 @@ struct radeon_asic {
>         struct {
>                 void (*tlb_flush)(struct radeon_device *rdev);
>                 void (*set_page)(struct radeon_device *rdev, unsigned i,
> -                                uint64_t addr);
> +                                uint64_t addr, uint32_t flags);
>         } gart;
>         struct {
>                 int (*init)(struct radeon_device *rdev);
> @@ -2735,7 +2737,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
>  #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
>  #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev))
>  #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev))
> -#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p))
> +#define radeon_gart_set_page(rdev, i, p, r) (rdev)->asic->gart.set_page((rdev), (i), (p), (r))
>  #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev))
>  #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev))
>  #define radeon_asic_vm_set_page(rdev, ib, pe, addr, count, incr, flags) ((rdev)->asic->vm.set_page((rdev), (ib), (pe), (addr), (count), (incr), (flags)))
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> index 7531b5e..f7d7c33 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -68,7 +68,7 @@ int r100_asic_reset(struct radeon_device *rdev);
>  u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
>  void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
>  void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i,
> -                           uint64_t addr);
> +                           uint64_t addr, uint32_t flags);
>  void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring);
>  int r100_irq_set(struct radeon_device *rdev);
>  int r100_irq_process(struct radeon_device *rdev);
> @@ -172,7 +172,7 @@ extern void r300_fence_ring_emit(struct radeon_device *rdev,
>  extern int r300_cs_parse(struct radeon_cs_parser *p);
>  extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
>  extern void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i,
> -                                    uint64_t addr);
> +                                    uint64_t addr, uint32_t flags);
>  extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
>  extern int rv370_get_pcie_lanes(struct radeon_device *rdev);
>  extern void r300_set_reg_safe(struct radeon_device *rdev);
> @@ -208,7 +208,7 @@ extern int rs400_suspend(struct radeon_device *rdev);
>  extern int rs400_resume(struct radeon_device *rdev);
>  void rs400_gart_tlb_flush(struct radeon_device *rdev);
>  void rs400_gart_set_page(struct radeon_device *rdev, unsigned i,
> -                        uint64_t addr);
> +                        uint64_t addr, uint32_t flags);
>  uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
>  void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
>  int rs400_gart_init(struct radeon_device *rdev);
> @@ -232,7 +232,7 @@ void rs600_irq_disable(struct radeon_device *rdev);
>  u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
>  void rs600_gart_tlb_flush(struct radeon_device *rdev);
>  void rs600_gart_set_page(struct radeon_device *rdev, unsigned i,
> -                        uint64_t addr);
> +                        uint64_t addr, uint32_t flags);
>  uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
>  void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
>  void rs600_bandwidth_update(struct radeon_device *rdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
> index b7d3e84..b26c0b2 100644
> --- a/drivers/gpu/drm/radeon/radeon_gart.c
> +++ b/drivers/gpu/drm/radeon/radeon_gart.c
> @@ -243,7 +243,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
>                         page_base = rdev->gart.pages_addr[p];
>                         for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
>                                 if (rdev->gart.ptr) {
> -                                       radeon_gart_set_page(rdev, t, page_base);
> +                                       radeon_gart_set_page(rdev, t, page_base, 0);
>                                 }
>                                 page_base += RADEON_GPU_PAGE_SIZE;
>                         }
> @@ -266,8 +266,9 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
>   * (all asics).
>   * Returns 0 for success, -EINVAL for failure.
>   */
> -int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
> -                    int pages, struct page **pagelist, dma_addr_t *dma_addr)
> +int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, int pages,
> +                    struct page **pagelist, dma_addr_t *dma_addr,
> +                    uint32_t flags)
>  {
>         unsigned t;
>         unsigned p;
> @@ -287,7 +288,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
>                 if (rdev->gart.ptr) {
>                         page_base = rdev->gart.pages_addr[p];
>                         for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
> -                               radeon_gart_set_page(rdev, t, page_base);
> +                               radeon_gart_set_page(rdev, t, page_base, flags);
>                                 page_base += RADEON_GPU_PAGE_SIZE;
>                         }
>                 }
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index c8a8a51..19d662f 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -528,8 +528,8 @@ static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
>                 WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
>                      ttm->num_pages, bo_mem, ttm);
>         }
> -       r = radeon_gart_bind(gtt->rdev, gtt->offset,
> -                            ttm->num_pages, ttm->pages, gtt->ttm.dma_address);
> +       r = radeon_gart_bind(gtt->rdev, gtt->offset, ttm->num_pages,
> +                            ttm->pages, gtt->ttm.dma_address, 0);
>         if (r) {
>                 DRM_ERROR("failed to bind %lu pages at 0x%08X\n",
>                           ttm->num_pages, (unsigned)gtt->offset);
> diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
> index 4519f9c..5164544 100644
> --- a/drivers/gpu/drm/radeon/rs400.c
> +++ b/drivers/gpu/drm/radeon/rs400.c
> @@ -211,14 +211,19 @@ void rs400_gart_fini(struct radeon_device *rdev)
>  #define RS400_PTE_WRITEABLE (1 << 2)
>  #define RS400_PTE_READABLE  (1 << 3)
>
> -void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, uint64_t addr)
> +void rs400_gart_set_page(struct radeon_device *rdev, unsigned i,
> +                        uint64_t addr, uint32_t flags)
>  {
>         uint32_t entry;
>         u32 *gtt = rdev->gart.ptr;
>
>         entry = (lower_32_bits(addr) & PAGE_MASK) |
>                 ((upper_32_bits(addr) & 0xff) << 4) |
> -               RS400_PTE_WRITEABLE | RS400_PTE_READABLE;
> +               RS400_PTE_READABLE;
> +
> +       if (!(flags & RADEON_GART_PAGE_READONLY))
> +               entry |= RS400_PTE_WRITEABLE;
> +
>         entry = cpu_to_le32(entry);
>         gtt[i] = entry;
>  }
> diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
> index cd7b4b0..cb487c7 100644
> --- a/drivers/gpu/drm/radeon/rs600.c
> +++ b/drivers/gpu/drm/radeon/rs600.c
> @@ -611,15 +611,19 @@ static void rs600_gart_fini(struct radeon_device *rdev)
>         radeon_gart_table_vram_free(rdev);
>  }
>
> -void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, uint64_t addr)
> +void rs600_gart_set_page(struct radeon_device *rdev, unsigned i,
> +                        uint64_t addr, uint32_t flags)
>  {
>         void __iomem *ptr = (void *)rdev->gart.ptr;
>
>         addr = addr & 0xFFFFFFFFFFFFF000ULL;
>         if (addr == rdev->dummy_page.addr)
>                 addr |= R600_PTE_SYSTEM | R600_PTE_SNOOPED;
> -       else
> +       else {
>                 addr |= R600_PTE_GART;
> +               if (flags & RADEON_GART_PAGE_READONLY)
> +                       addr &= ~R600_PTE_WRITEABLE;
> +       }
>         writeq(addr, ptr + (i * 8));
>  }
>
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list