[Freedreno] [PATCH 07/16] drm/msm: Add adreno_gpu_write64()

Rob Clark robdclark at gmail.com
Mon Nov 7 19:19:53 UTC 2016


On Fri, Nov 4, 2016 at 6:44 PM, Jordan Crouse <jcrouse at codeaurora.org> wrote:
> Add a new generic function to write a "64" bit value. This isn't
> actually a 64 bit operation, it just writes the upper and lower
> 32 bit of a 64 bit value to a specified LO and HI register.  If
> a particular target doesn't support one of the registers it can
> mark that register as SKIP and writes/reads from that register
> will be quietly dropped.
>
> This can be immediately put in place for the ringbuffer base and
> the RPTR address.  Both writes are converted to use
> adreno_gpu_write64() with their respective high and low registers
> and the high register appropriately marked as SKIP for both 32 bit
> targets (a3xx and a4xx). When a5xx comes it will define valid target
> registers for the 'hi' option and everything else will just work.
>
> Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
> ---
>  drivers/gpu/drm/msm/adreno/a3xx_gpu.c   |  2 ++
>  drivers/gpu/drm/msm/adreno/a4xx_gpu.c   |  2 ++
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 11 +++++++----
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h | 24 +++++++++++++++++++++++-
>  4 files changed, 34 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> index 13989d9..806aab4 100644
> --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> @@ -423,7 +423,9 @@ static void a3xx_dump(struct msm_gpu *gpu)
>  /* Register offset defines for A3XX */
>  static const unsigned int a3xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE),
> +       REG_ADRENO_SKIP(REG_ADRENO_CP_RB_BASE_HI),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_AXXX_CP_RB_RPTR_ADDR),
> +       REG_ADRENO_SKIP(REG_ADRENO_CP_RB_RPTR_ADDR_HI),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_AXXX_CP_RB_RPTR),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_AXXX_CP_RB_WPTR),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_AXXX_CP_RB_CNTL),
> diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> index ba16507..f39e082 100644
> --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> @@ -463,7 +463,9 @@ static void a4xx_show(struct msm_gpu *gpu, struct seq_file *m)
>  /* Register offset defines for A4XX, in order of enum adreno_regs */
>  static const unsigned int a4xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A4XX_CP_RB_BASE),
> +       REG_ADRENO_SKIP(REG_ADRENO_CP_RB_BASE_HI),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A4XX_CP_RB_RPTR_ADDR),
> +       REG_ADRENO_SKIP(REG_ADRENO_CP_RB_RPTR_ADDR_HI),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A4XX_CP_RB_RPTR),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A4XX_CP_RB_WPTR),
>         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A4XX_CP_RB_CNTL),
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index 8b2201c..d7b62b8 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -79,11 +79,14 @@ int adreno_hw_init(struct msm_gpu *gpu)
>                         (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0));
>
>         /* Setup ringbuffer address: */
> -       adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_BASE, gpu->rb_iova);
> +       adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_BASE,
> +               REG_ADRENO_CP_RB_BASE_HI, gpu->rb_iova);
>
> -       if (!adreno_is_a430(adreno_gpu))
> -               adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR,
> -                                               rbmemptr(adreno_gpu, rptr));
> +       if (!adreno_is_a430(adreno_gpu)) {
> +               adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR,
> +                       REG_ADRENO_CP_RB_RPTR_ADDR_HI,
> +                       rbmemptr(adreno_gpu, rptr));
> +       }
>
>         return 0;
>  }
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> index 707487f..7b9895f 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> @@ -28,6 +28,9 @@
>  #include "adreno_pm4.xml.h"
>
>  #define REG_ADRENO_DEFINE(_offset, _reg) [_offset] = (_reg) + 1
> +#define REG_SKIP ~0
> +#define REG_ADRENO_SKIP(_offset) [_offset] = REG_SKIP
> +

I think you can drop this.. we use (_reg)+1 so that a zero value in
the table can be interpreted as a skip.  That was one small diff from
how the downstream driver does it.

BR,
-R

>  /**
>   * adreno_regs: List of registers that are used in across all
>   * 3D devices. Each device type has different offset value for the same
> @@ -36,7 +39,9 @@
>   */
>  enum adreno_regs {
>         REG_ADRENO_CP_RB_BASE,
> +       REG_ADRENO_CP_RB_BASE_HI,
>         REG_ADRENO_CP_RB_RPTR_ADDR,
> +       REG_ADRENO_CP_RB_RPTR_ADDR_HI,
>         REG_ADRENO_CP_RB_RPTR,
>         REG_ADRENO_CP_RB_WPTR,
>         REG_ADRENO_CP_RB_CNTL,
> @@ -250,7 +255,7 @@ OUT_PKT7(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
>  }
>
>  /*
> - * adreno_checkreg_off() - Checks the validity of a register enum
> + * adreno_reg_check() - Checks the validity of a register enum
>   * @gpu:               Pointer to struct adreno_gpu
>   * @offset_name:       The register enum that is checked
>   */
> @@ -261,6 +266,16 @@ static inline bool adreno_reg_check(struct adreno_gpu *gpu,
>                         !gpu->reg_offsets[offset_name]) {
>                 BUG();
>         }
> +
> +       /*
> +        * REG_SKIP is a special value that tell us that the register in
> +        * question isn't implemented on target but don't trigger a BUG(). This
> +        * is used to cleanly implement adreno_gpu_write64() and
> +        * adreno_gpu_read64() in a generic fashion
> +        */
> +       if (gpu->reg_offsets[offset_name] == REG_SKIP)
> +               return false;
> +
>         return true;
>  }
>
> @@ -282,4 +297,11 @@ static inline void adreno_gpu_write(struct adreno_gpu *gpu,
>                 gpu_write(&gpu->base, reg - 1, data);
>  }
>
> +static inline void adreno_gpu_write64(struct adreno_gpu *gpu,
> +               enum adreno_regs lo, enum adreno_regs hi, u64 data)
> +{
> +       adreno_gpu_write(gpu, lo, lower_32_bits(data));
> +       adreno_gpu_write(gpu, hi, upper_32_bits(data));
> +}
> +
>  #endif /* __ADRENO_GPU_H__ */
> --
> 1.9.1
>
> _______________________________________________
> Freedreno mailing list
> Freedreno at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno


More information about the Freedreno mailing list