Am 06.04.2016 um 22:50 schrieb Dave Airlie: > From: Dave Airlie <airlied at redhat.com> > > 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) > > Signed-off-by: Dave Airlie <airlied at redhat.com>
Reviewed-by: Christian König <christian.koenig at amd.com> > --- > drivers/gpu/drm/radeon/evergreen_cs.c | 45 > +++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/radeon/evergreend.h | 43 +++++++++++++++++++++++++++++++++ > drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- > 3 files changed, 90 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c > b/drivers/gpu/drm/radeon/evergreen_cs.c > index 9e93205..18ddd75 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 13b6029..0b174e1 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 a4b5dbd..1f96b04 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);