diff options
author | Dave Airlie <airlied@redhat.com> | 2016-04-06 23:50:25 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-05-05 03:19:49 +0300 |
commit | 8c4f2bbd66784f00a509bf0787aa16b19ceaa6c7 (patch) | |
tree | 1703f24e6b1a07b558e3cd5c65b8b0d341edb443 | |
parent | 8b2cf4f5758f172d0980688383cea83241dc59e6 (diff) | |
download | linux-8c4f2bbd66784f00a509bf0787aa16b19ceaa6c7.tar.xz |
drm/radeon: add support for SET_APPEND_CNT packet3 (v2)
This adds support to the command parser for the set append counter
packet3, this is required to support atomic counters on
evergreen/cayman GPUs.
v2: fixup some of the hardcoded numbers with real register names
(Christian)
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 3 |
3 files changed, 90 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 9e93205eb9e4..18ddd752b64b 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -2608,6 +2608,51 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, } } break; + case PACKET3_SET_APPEND_CNT: + { + uint32_t areg; + uint32_t allowed_reg_base; + uint32_t source_sel; + if (pkt->count != 2) { + DRM_ERROR("bad SET_APPEND_CNT (invalid count)\n"); + return -EINVAL; + } + + allowed_reg_base = GDS_APPEND_COUNT_0; + allowed_reg_base -= PACKET3_SET_CONTEXT_REG_START; + allowed_reg_base >>= 2; + + areg = idx_value >> 16; + if (areg < allowed_reg_base || areg > (allowed_reg_base + 11)) { + dev_warn(p->dev, "forbidden register for append cnt 0x%08x at %d\n", + areg, idx); + return -EINVAL; + } + + source_sel = G_PACKET3_SET_APPEND_CNT_SRC_SELECT(idx_value); + if (source_sel == PACKET3_SAC_SRC_SEL_MEM) { + uint64_t offset; + uint32_t swap; + r = radeon_cs_packet_next_reloc(p, &reloc, 0); + if (r) { + DRM_ERROR("bad SET_APPEND_CNT (missing reloc)\n"); + return -EINVAL; + } + offset = radeon_get_ib_value(p, idx + 1); + swap = offset & 0x3; + offset &= ~0x3; + + offset += ((u64)(radeon_get_ib_value(p, idx + 2) & 0xff)) << 32; + + offset += reloc->gpu_offset; + ib[idx+1] = (offset & 0xfffffffc) | swap; + ib[idx+2] = upper_32_bits(offset) & 0xff; + } else { + DRM_ERROR("bad SET_APPEND_CNT (unsupported operation)\n"); + return -EINVAL; + } + break; + } case PACKET3_NOP: break; default: diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 13b6029d65cc..0b174e14e9a6 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -1689,6 +1689,36 @@ #define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 #define PACKET3_SET_RESOURCE_INDIRECT 0x74 #define PACKET3_SET_APPEND_CNT 0x75 +/* SET_APPEND_CNT - documentation + * 1. header + * 2. COMMAND + * 1:0 - SOURCE SEL + * 15:2 - Reserved + * 31:16 - WR_REG_OFFSET - context register to write source data to. + * (one of R_02872C_GDS_APPEND_COUNT_0-11) + * 3. CONTROL + * (for source == mem) + * 31:2 SRC_ADDRESS_LO + * 0:1 SWAP + * (for source == GDS) + * 31:0 GDS offset + * (for source == DATA) + * 31:0 DATA + * (for source == REG) + * 31:0 REG + * 4. SRC_ADDRESS_HI[7:0] + * kernel driver 2.44 only supports SRC == MEM. + */ +#define PACKET3_SET_APPEND_CNT_SRC_SELECT(x) ((x) << 0) +#define G_PACKET3_SET_APPEND_CNT_SRC_SELECT(x) ((x & 0x3) >> 0) +/* source is from the data in CONTROL */ +#define PACKET3_SAC_SRC_SEL_DATA 0x0 +/* source is from register */ +#define PACKET3_SAC_SRC_SEL_REG 0x1 +/* source is from GDS offset in CONTROL */ +#define PACKET3_SAC_SRC_SEL_GDS 0x2 +/* source is from memory address */ +#define PACKET3_SAC_SRC_SEL_MEM 0x3 #define SQ_RESOURCE_CONSTANT_WORD7_0 0x3001c #define S__SQ_CONSTANT_TYPE(x) (((x) & 3) << 30) @@ -2005,6 +2035,19 @@ #define GDS_ADDR_BASE 0x28720 +#define GDS_APPEND_COUNT_0 0x2872C +#define GDS_APPEND_COUNT_1 0x28730 +#define GDS_APPEND_COUNT_2 0x28734 +#define GDS_APPEND_COUNT_3 0x28738 +#define GDS_APPEND_COUNT_4 0x2873C +#define GDS_APPEND_COUNT_5 0x28740 +#define GDS_APPEND_COUNT_6 0x28744 +#define GDS_APPEND_COUNT_7 0x28748 +#define GDS_APPEND_COUNT_8 0x2874c +#define GDS_APPEND_COUNT_9 0x28750 +#define GDS_APPEND_COUNT_10 0x28754 +#define GDS_APPEND_COUNT_11 0x28758 + #define CB_IMMED0_BASE 0x28b9c #define CB_IMMED1_BASE 0x28ba0 #define CB_IMMED2_BASE 0x28ba4 diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d2a925ed2346..1ff77cea436d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -93,9 +93,10 @@ * 2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing support * 2.42.0 - Add VCE/VUI (Video Usability Information) support * 2.43.0 - RADEON_INFO_GPU_RESET_COUNTER + * 2.44.0 - SET_APPEND_CNT packet3 support */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 43 +#define KMS_DRIVER_MINOR 44 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); |