aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2016-11-28 14:28:29 -0500
committerRob Clark <robdclark@gmail.com>2016-11-28 15:14:12 -0500
commitfb039981923950716c4e5bccef19d1716ffd298e (patch)
tree1f1d7626daba1bbc4a05ed7018c08f88f0d767f6
parentae53a829d5c9715b651ee33e266eaa4454e7f2ad (diff)
drm/msm: Add adreno_gpu_write64()
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@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c11
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h24
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 ff6489444423..b999349b7d2d 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -430,7 +430,9 @@ static void a3xx_dump(struct msm_gpu *gpu)
430/* Register offset defines for A3XX */ 430/* Register offset defines for A3XX */
431static const unsigned int a3xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { 431static const unsigned int a3xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
432 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE), 432 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE),
433 REG_ADRENO_SKIP(REG_ADRENO_CP_RB_BASE_HI),
433 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_AXXX_CP_RB_RPTR_ADDR), 434 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_AXXX_CP_RB_RPTR_ADDR),
435 REG_ADRENO_SKIP(REG_ADRENO_CP_RB_RPTR_ADDR_HI),
434 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_AXXX_CP_RB_RPTR), 436 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_AXXX_CP_RB_RPTR),
435 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_AXXX_CP_RB_WPTR), 437 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_AXXX_CP_RB_WPTR),
436 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_AXXX_CP_RB_CNTL), 438 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 5858fb3bad0d..511bc855cc7f 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -470,7 +470,9 @@ static void a4xx_show(struct msm_gpu *gpu, struct seq_file *m)
470/* Register offset defines for A4XX, in order of enum adreno_regs */ 470/* Register offset defines for A4XX, in order of enum adreno_regs */
471static const unsigned int a4xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { 471static const unsigned int a4xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
472 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A4XX_CP_RB_BASE), 472 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A4XX_CP_RB_BASE),
473 REG_ADRENO_SKIP(REG_ADRENO_CP_RB_BASE_HI),
473 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A4XX_CP_RB_RPTR_ADDR), 474 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A4XX_CP_RB_RPTR_ADDR),
475 REG_ADRENO_SKIP(REG_ADRENO_CP_RB_RPTR_ADDR_HI),
474 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A4XX_CP_RB_RPTR), 476 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A4XX_CP_RB_RPTR),
475 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A4XX_CP_RB_WPTR), 477 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A4XX_CP_RB_WPTR),
476 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A4XX_CP_RB_CNTL), 478 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 04080f9b7e09..6684ba8fa9be 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)
79 (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0)); 79 (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0));
80 80
81 /* Setup ringbuffer address: */ 81 /* Setup ringbuffer address: */
82 adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_BASE, gpu->rb_iova); 82 adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_BASE,
83 REG_ADRENO_CP_RB_BASE_HI, gpu->rb_iova);
83 84
84 if (!adreno_is_a430(adreno_gpu)) 85 if (!adreno_is_a430(adreno_gpu)) {
85 adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR, 86 adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR,
86 rbmemptr(adreno_gpu, rptr)); 87 REG_ADRENO_CP_RB_RPTR_ADDR_HI,
88 rbmemptr(adreno_gpu, rptr));
89 }
87 90
88 return 0; 91 return 0;
89} 92}
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index d0f9e1e3acd6..2758e162ebb6 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -28,6 +28,9 @@
28#include "adreno_pm4.xml.h" 28#include "adreno_pm4.xml.h"
29 29
30#define REG_ADRENO_DEFINE(_offset, _reg) [_offset] = (_reg) + 1 30#define REG_ADRENO_DEFINE(_offset, _reg) [_offset] = (_reg) + 1
31#define REG_SKIP ~0
32#define REG_ADRENO_SKIP(_offset) [_offset] = REG_SKIP
33
31/** 34/**
32 * adreno_regs: List of registers that are used in across all 35 * adreno_regs: List of registers that are used in across all
33 * 3D devices. Each device type has different offset value for the same 36 * 3D devices. Each device type has different offset value for the same
@@ -36,7 +39,9 @@
36 */ 39 */
37enum adreno_regs { 40enum adreno_regs {
38 REG_ADRENO_CP_RB_BASE, 41 REG_ADRENO_CP_RB_BASE,
42 REG_ADRENO_CP_RB_BASE_HI,
39 REG_ADRENO_CP_RB_RPTR_ADDR, 43 REG_ADRENO_CP_RB_RPTR_ADDR,
44 REG_ADRENO_CP_RB_RPTR_ADDR_HI,
40 REG_ADRENO_CP_RB_RPTR, 45 REG_ADRENO_CP_RB_RPTR,
41 REG_ADRENO_CP_RB_WPTR, 46 REG_ADRENO_CP_RB_WPTR,
42 REG_ADRENO_CP_RB_CNTL, 47 REG_ADRENO_CP_RB_CNTL,
@@ -220,7 +225,7 @@ OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
220} 225}
221 226
222/* 227/*
223 * adreno_checkreg_off() - Checks the validity of a register enum 228 * adreno_reg_check() - Checks the validity of a register enum
224 * @gpu: Pointer to struct adreno_gpu 229 * @gpu: Pointer to struct adreno_gpu
225 * @offset_name: The register enum that is checked 230 * @offset_name: The register enum that is checked
226 */ 231 */
@@ -231,6 +236,16 @@ static inline bool adreno_reg_check(struct adreno_gpu *gpu,
231 !gpu->reg_offsets[offset_name]) { 236 !gpu->reg_offsets[offset_name]) {
232 BUG(); 237 BUG();
233 } 238 }
239
240 /*
241 * REG_SKIP is a special value that tell us that the register in
242 * question isn't implemented on target but don't trigger a BUG(). This
243 * is used to cleanly implement adreno_gpu_write64() and
244 * adreno_gpu_read64() in a generic fashion
245 */
246 if (gpu->reg_offsets[offset_name] == REG_SKIP)
247 return false;
248
234 return true; 249 return true;
235} 250}
236 251
@@ -255,4 +270,11 @@ static inline void adreno_gpu_write(struct adreno_gpu *gpu,
255struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); 270struct msm_gpu *a3xx_gpu_init(struct drm_device *dev);
256struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); 271struct msm_gpu *a4xx_gpu_init(struct drm_device *dev);
257 272
273static inline void adreno_gpu_write64(struct adreno_gpu *gpu,
274 enum adreno_regs lo, enum adreno_regs hi, u64 data)
275{
276 adreno_gpu_write(gpu, lo, lower_32_bits(data));
277 adreno_gpu_write(gpu, hi, upper_32_bits(data));
278}
279
258#endif /* __ADRENO_GPU_H__ */ 280#endif /* __ADRENO_GPU_H__ */