diff --git a/src/freedreno/common/freedreno_pm4.h b/src/freedreno/common/freedreno_pm4.h new file mode 100644 index 00000000000..78b4e0feda8 --- /dev/null +++ b/src/freedreno/common/freedreno_pm4.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012-2018 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Clark + */ + +#ifndef FREEDRENO_PM4_H_ +#define FREEDRENO_PM4_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CP_TYPE0_PKT 0x00000000 +#define CP_TYPE2_PKT 0x80000000 +#define CP_TYPE3_PKT 0xc0000000 +#define CP_TYPE4_PKT 0x40000000 +#define CP_TYPE7_PKT 0x70000000 + +/* + * Helpers for pm4 pkt header building/parsing: + */ + +static inline unsigned +pm4_odd_parity_bit(unsigned val) +{ + /* See: http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel + * note that we want odd parity so 0x6996 is inverted. + */ + val ^= val >> 16; + val ^= val >> 8; + val ^= val >> 4; + val &= 0xf; + return (~0x6996 >> val) & 1; +} + +static inline uint32_t +pm4_pkt0_hdr(uint16_t regindx, uint16_t cnt) +{ + return CP_TYPE0_PKT | ((cnt - 1) << 16) | (regindx & 0x7fff); +} + +static inline uint32_t +pm4_pkt3_hdr(uint8_t opcode, uint16_t cnt) +{ + return CP_TYPE3_PKT | ((cnt - 1) << 16) | ((opcode & 0xff) << 8); +} + +static inline uint32_t +pm4_pkt4_hdr(uint16_t regindx, uint16_t cnt) +{ + return CP_TYPE4_PKT | cnt | (pm4_odd_parity_bit(cnt) << 7) | + ((regindx & 0x3ffff) << 8) | + ((pm4_odd_parity_bit(regindx) << 27)); +} + +static inline uint32_t +pm4_pkt7_hdr(uint8_t opcode, uint16_t cnt) +{ + return CP_TYPE7_PKT | cnt | (pm4_odd_parity_bit(cnt) << 15) | + ((opcode & 0x7f) << 16) | + ((pm4_odd_parity_bit(opcode) << 23)); +} + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* FREEDRENO_PM4_H_ */ diff --git a/src/freedreno/common/meson.build b/src/freedreno/common/meson.build index 30ef23043a7..4e449e40f4e 100644 --- a/src/freedreno/common/meson.build +++ b/src/freedreno/common/meson.build @@ -24,6 +24,7 @@ libfreedreno_common = static_library( 'disasm.h', 'freedreno_dev_info.c', 'freedreno_dev_info.h', + 'freedreno_pm4.h', 'freedreno_uuid.c', 'freedreno_uuid.h', 'freedreno_guardband.h', diff --git a/src/freedreno/drm/freedreno_ringbuffer.h b/src/freedreno/drm/freedreno_ringbuffer.h index cf47a76e7e6..193b5f9312b 100644 --- a/src/freedreno/drm/freedreno_ringbuffer.h +++ b/src/freedreno/drm/freedreno_ringbuffer.h @@ -35,6 +35,7 @@ #include "adreno_common.xml.h" #include "adreno_pm4.xml.h" #include "freedreno_drmif.h" +#include "freedreno_pm4.h" #ifdef __cplusplus extern "C" { @@ -312,7 +313,7 @@ static inline void OUT_PKT0(struct fd_ringbuffer *ring, uint16_t regindx, uint16_t cnt) { BEGIN_RING(ring, cnt + 1); - OUT_RING(ring, CP_TYPE0_PKT | ((cnt - 1) << 16) | (regindx & 0x7FFF)); + OUT_RING(ring, pm4_pkt0_hdr(regindx, cnt)); } static inline void @@ -333,35 +334,18 @@ OUT_PKT3(struct fd_ringbuffer *ring, uint8_t opcode, uint16_t cnt) * Starting with a5xx, pkt4/pkt7 are used instead of pkt0/pkt3 */ -static inline unsigned -_odd_parity_bit(unsigned val) -{ - /* See: http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel - * note that we want odd parity so 0x6996 is inverted. - */ - val ^= val >> 16; - val ^= val >> 8; - val ^= val >> 4; - val &= 0xf; - return (~0x6996 >> val) & 1; -} - static inline void OUT_PKT4(struct fd_ringbuffer *ring, uint16_t regindx, uint16_t cnt) { BEGIN_RING(ring, cnt + 1); - OUT_RING(ring, CP_TYPE4_PKT | cnt | (_odd_parity_bit(cnt) << 7) | - ((regindx & 0x3ffff) << 8) | - ((_odd_parity_bit(regindx) << 27))); + OUT_RING(ring, pm4_pkt4_hdr(regindx, cnt)); } static inline void OUT_PKT7(struct fd_ringbuffer *ring, uint8_t opcode, uint16_t cnt) { BEGIN_RING(ring, cnt + 1); - OUT_RING(ring, CP_TYPE7_PKT | cnt | (_odd_parity_bit(cnt) << 15) | - ((opcode & 0x7f) << 16) | - ((_odd_parity_bit(opcode) << 23))); + OUT_RING(ring, pm4_pkt7_hdr(opcode, cnt)); } static inline void diff --git a/src/freedreno/vulkan/tu_cs.h b/src/freedreno/vulkan/tu_cs.h index 77be4319a11..006da12b1b1 100644 --- a/src/freedreno/vulkan/tu_cs.h +++ b/src/freedreno/vulkan/tu_cs.h @@ -27,6 +27,8 @@ #include "adreno_pm4.xml.h" +#include "freedreno_pm4.h" + void tu_cs_init(struct tu_cs *cs, struct tu_device *device, @@ -168,19 +170,6 @@ tu_cs_emit_array(struct tu_cs *cs, const uint32_t *values, uint32_t length) cs->cur += length; } -static inline unsigned -tu_odd_parity_bit(unsigned val) -{ - /* See: http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel - * note that we want odd parity so 0x6996 is inverted. - */ - val ^= val >> 16; - val ^= val >> 8; - val ^= val >> 4; - val &= 0xf; - return (~0x6996 >> val) & 1; -} - /** * Get the size of the remaining space in the current BO. */ @@ -217,9 +206,7 @@ static inline void tu_cs_emit_pkt4(struct tu_cs *cs, uint16_t regindx, uint16_t cnt) { tu_cs_reserve(cs, cnt + 1); - tu_cs_emit(cs, CP_TYPE4_PKT | cnt | (tu_odd_parity_bit(cnt) << 7) | - ((regindx & 0x3ffff) << 8) | - ((tu_odd_parity_bit(regindx) << 27))); + tu_cs_emit(cs, pm4_pkt4_hdr(regindx, cnt)); } /** @@ -229,9 +216,7 @@ static inline void tu_cs_emit_pkt7(struct tu_cs *cs, uint8_t opcode, uint16_t cnt) { tu_cs_reserve(cs, cnt + 1); - tu_cs_emit(cs, CP_TYPE7_PKT | cnt | (tu_odd_parity_bit(cnt) << 15) | - ((opcode & 0x7f) << 16) | - ((tu_odd_parity_bit(opcode) << 23))); + tu_cs_emit(cs, pm4_pkt7_hdr(opcode, cnt)); } static inline void diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_pack.h b/src/gallium/drivers/freedreno/a6xx/fd6_pack.h index 75a811d0969..50d95a514da 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_pack.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_pack.h @@ -79,9 +79,7 @@ struct fd_reg_pair { \ BEGIN_RING(ring, count + 1); \ uint32_t *p = ring->cur; \ - *p++ = CP_TYPE4_PKT | count | (_odd_parity_bit(count) << 7) | \ - ((regs[0].reg & 0x3ffff) << 8) | \ - ((_odd_parity_bit(regs[0].reg) << 27)); \ + *p++ = pm4_pkt4_hdr(regs[0].reg, count); \ \ __ONE_REG(0, __VA_ARGS__); \ __ONE_REG(1, __VA_ARGS__); \ @@ -111,8 +109,7 @@ struct fd_reg_pair { \ BEGIN_RING(ring, count + 1); \ uint32_t *p = ring->cur; \ - *p++ = CP_TYPE7_PKT | count | (_odd_parity_bit(count) << 15) | \ - ((opcode & 0x7f) << 16) | ((_odd_parity_bit(opcode) << 23)); \ + *p++ = pm4_pkt7_hdr(opcode, count); \ \ __ONE_REG(0, __VA_ARGS__); \ __ONE_REG(1, __VA_ARGS__); \ @@ -147,8 +144,7 @@ struct fd_reg_pair { \ BEGIN_RING(ring, count + 1); \ uint32_t *p = ring->cur; \ - *p++ = CP_TYPE7_PKT | count | (_odd_parity_bit(count) << 15) | \ - ((opcode & 0x7f) << 16) | ((_odd_parity_bit(opcode) << 23)); \ + *p++ = pm4_pkt7_hdr(opcode, count); \ \ __ONE_REG(0, __VA_ARGS__); \ __ONE_REG(1, __VA_ARGS__); \