cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

reg_helper.h (17774B)


      1/*
      2 * Copyright 2016 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 */
     24
     25#ifndef DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
     26#define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
     27
     28#include "dm_services.h"
     29
     30/* macro for register read/write
     31 * user of macro need to define
     32 *
     33 * CTX ==> macro to ptr to dc_context
     34 *    eg. aud110->base.ctx
     35 *
     36 * REG ==> macro to location of register offset
     37 *    eg. aud110->regs->reg
     38 */
     39#define REG_READ(reg_name) \
     40		dm_read_reg(CTX, REG(reg_name))
     41
     42#define REG_WRITE(reg_name, value) \
     43		dm_write_reg(CTX, REG(reg_name), value)
     44
     45#ifdef REG_SET
     46#undef REG_SET
     47#endif
     48
     49#ifdef REG_GET
     50#undef REG_GET
     51#endif
     52
     53/* macro to set register fields. */
     54#define REG_SET_N(reg_name, n, initial_val, ...)	\
     55		generic_reg_set_ex(CTX, \
     56				REG(reg_name), \
     57				initial_val, \
     58				n, __VA_ARGS__)
     59
     60#define FN(reg_name, field) \
     61	FD(reg_name##__##field)
     62
     63#define REG_SET(reg_name, initial_val, field, val)	\
     64		REG_SET_N(reg_name, 1, initial_val, \
     65				FN(reg_name, field), val)
     66
     67#define REG_SET_2(reg, init_value, f1, v1, f2, v2)	\
     68		REG_SET_N(reg, 2, init_value, \
     69				FN(reg, f1), v1,\
     70				FN(reg, f2), v2)
     71
     72#define REG_SET_3(reg, init_value, f1, v1, f2, v2, f3, v3)	\
     73		REG_SET_N(reg, 3, init_value, \
     74				FN(reg, f1), v1,\
     75				FN(reg, f2), v2,\
     76				FN(reg, f3), v3)
     77
     78#define REG_SET_4(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4)	\
     79		REG_SET_N(reg, 4, init_value, \
     80				FN(reg, f1), v1,\
     81				FN(reg, f2), v2,\
     82				FN(reg, f3), v3,\
     83				FN(reg, f4), v4)
     84
     85#define REG_SET_5(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
     86		f5, v5)	\
     87		REG_SET_N(reg, 5, init_value, \
     88				FN(reg, f1), v1,\
     89				FN(reg, f2), v2,\
     90				FN(reg, f3), v3,\
     91				FN(reg, f4), v4,\
     92				FN(reg, f5), v5)
     93
     94#define REG_SET_6(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
     95		f5, v5, f6, v6)	\
     96		REG_SET_N(reg, 6, init_value, \
     97				FN(reg, f1), v1,\
     98				FN(reg, f2), v2,\
     99				FN(reg, f3), v3,\
    100				FN(reg, f4), v4,\
    101				FN(reg, f5), v5,\
    102				FN(reg, f6), v6)
    103
    104#define REG_SET_7(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
    105		f5, v5, f6, v6, f7, v7)	\
    106		REG_SET_N(reg, 7, init_value, \
    107				FN(reg, f1), v1,\
    108				FN(reg, f2), v2,\
    109				FN(reg, f3), v3,\
    110				FN(reg, f4), v4,\
    111				FN(reg, f5), v5,\
    112				FN(reg, f6), v6,\
    113				FN(reg, f7), v7)
    114
    115#define REG_SET_8(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,	\
    116		f5, v5, f6, v6, f7, v7, f8, v8)	\
    117		REG_SET_N(reg, 8, init_value, \
    118				FN(reg, f1), v1,\
    119				FN(reg, f2), v2,\
    120				FN(reg, f3), v3,\
    121				FN(reg, f4), v4,\
    122				FN(reg, f5), v5,\
    123				FN(reg, f6), v6,\
    124				FN(reg, f7), v7,\
    125				FN(reg, f8), v8)
    126
    127#define REG_SET_9(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
    128		v5, f6, v6, f7, v7, f8, v8, f9, v9)	\
    129		REG_SET_N(reg, 9, init_value, \
    130				FN(reg, f1), v1,\
    131				FN(reg, f2), v2, \
    132				FN(reg, f3), v3, \
    133				FN(reg, f4), v4, \
    134				FN(reg, f5), v5, \
    135				FN(reg, f6), v6, \
    136				FN(reg, f7), v7, \
    137				FN(reg, f8), v8, \
    138				FN(reg, f9), v9)
    139
    140#define REG_SET_10(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
    141		v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10)	\
    142		REG_SET_N(reg, 10, init_value, \
    143				FN(reg, f1), v1,\
    144				FN(reg, f2), v2, \
    145				FN(reg, f3), v3, \
    146				FN(reg, f4), v4, \
    147				FN(reg, f5), v5, \
    148				FN(reg, f6), v6, \
    149				FN(reg, f7), v7, \
    150				FN(reg, f8), v8, \
    151				FN(reg, f9), v9, \
    152				FN(reg, f10), v10)
    153
    154/* macro to get register fields
    155 * read given register and fill in field value in output parameter */
    156#define REG_GET(reg_name, field, val)	\
    157		generic_reg_get(CTX, REG(reg_name), \
    158				FN(reg_name, field), val)
    159
    160#define REG_GET_2(reg_name, f1, v1, f2, v2)	\
    161		generic_reg_get2(CTX, REG(reg_name), \
    162				FN(reg_name, f1), v1, \
    163				FN(reg_name, f2), v2)
    164
    165#define REG_GET_3(reg_name, f1, v1, f2, v2, f3, v3)	\
    166		generic_reg_get3(CTX, REG(reg_name), \
    167				FN(reg_name, f1), v1, \
    168				FN(reg_name, f2), v2, \
    169				FN(reg_name, f3), v3)
    170
    171#define REG_GET_4(reg_name, f1, v1, f2, v2, f3, v3, f4, v4)	\
    172		generic_reg_get4(CTX, REG(reg_name), \
    173				FN(reg_name, f1), v1, \
    174				FN(reg_name, f2), v2, \
    175				FN(reg_name, f3), v3, \
    176				FN(reg_name, f4), v4)
    177
    178#define REG_GET_5(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)	\
    179		generic_reg_get5(CTX, REG(reg_name), \
    180				FN(reg_name, f1), v1, \
    181				FN(reg_name, f2), v2, \
    182				FN(reg_name, f3), v3, \
    183				FN(reg_name, f4), v4, \
    184				FN(reg_name, f5), v5)
    185
    186#define REG_GET_6(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)	\
    187		generic_reg_get6(CTX, REG(reg_name), \
    188				FN(reg_name, f1), v1, \
    189				FN(reg_name, f2), v2, \
    190				FN(reg_name, f3), v3, \
    191				FN(reg_name, f4), v4, \
    192				FN(reg_name, f5), v5, \
    193				FN(reg_name, f6), v6)
    194
    195#define REG_GET_7(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7)	\
    196		generic_reg_get7(CTX, REG(reg_name), \
    197				FN(reg_name, f1), v1, \
    198				FN(reg_name, f2), v2, \
    199				FN(reg_name, f3), v3, \
    200				FN(reg_name, f4), v4, \
    201				FN(reg_name, f5), v5, \
    202				FN(reg_name, f6), v6, \
    203				FN(reg_name, f7), v7)
    204
    205#define REG_GET_8(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8)	\
    206		generic_reg_get8(CTX, REG(reg_name), \
    207				FN(reg_name, f1), v1, \
    208				FN(reg_name, f2), v2, \
    209				FN(reg_name, f3), v3, \
    210				FN(reg_name, f4), v4, \
    211				FN(reg_name, f5), v5, \
    212				FN(reg_name, f6), v6, \
    213				FN(reg_name, f7), v7, \
    214				FN(reg_name, f8), v8)
    215
    216/* macro to poll and wait for a register field to read back given value */
    217
    218#define REG_WAIT(reg_name, field, val, delay_between_poll_us, max_try)	\
    219		generic_reg_wait(CTX, \
    220				REG(reg_name), FN(reg_name, field), val,\
    221				delay_between_poll_us, max_try, __func__, __LINE__)
    222
    223/* macro to update (read, modify, write) register fields
    224 */
    225#define REG_UPDATE_N(reg_name, n, ...)	\
    226		generic_reg_update_ex(CTX, \
    227				REG(reg_name), \
    228				n, __VA_ARGS__)
    229
    230#define REG_UPDATE(reg_name, field, val)	\
    231		REG_UPDATE_N(reg_name, 1, \
    232				FN(reg_name, field), val)
    233
    234#define REG_UPDATE_2(reg, f1, v1, f2, v2)	\
    235		REG_UPDATE_N(reg, 2,\
    236				FN(reg, f1), v1,\
    237				FN(reg, f2), v2)
    238
    239#define REG_UPDATE_3(reg, f1, v1, f2, v2, f3, v3)	\
    240		REG_UPDATE_N(reg, 3, \
    241				FN(reg, f1), v1,\
    242				FN(reg, f2), v2, \
    243				FN(reg, f3), v3)
    244
    245#define REG_UPDATE_4(reg, f1, v1, f2, v2, f3, v3, f4, v4)	\
    246		REG_UPDATE_N(reg, 4, \
    247				FN(reg, f1), v1,\
    248				FN(reg, f2), v2, \
    249				FN(reg, f3), v3, \
    250				FN(reg, f4), v4)
    251
    252#define REG_UPDATE_5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)	\
    253		REG_UPDATE_N(reg, 5, \
    254				FN(reg, f1), v1,\
    255				FN(reg, f2), v2, \
    256				FN(reg, f3), v3, \
    257				FN(reg, f4), v4, \
    258				FN(reg, f5), v5)
    259
    260#define REG_UPDATE_6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)	\
    261		REG_UPDATE_N(reg, 6, \
    262				FN(reg, f1), v1,\
    263				FN(reg, f2), v2, \
    264				FN(reg, f3), v3, \
    265				FN(reg, f4), v4, \
    266				FN(reg, f5), v5, \
    267				FN(reg, f6), v6)
    268
    269#define REG_UPDATE_7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7)	\
    270		REG_UPDATE_N(reg, 7, \
    271				FN(reg, f1), v1,\
    272				FN(reg, f2), v2, \
    273				FN(reg, f3), v3, \
    274				FN(reg, f4), v4, \
    275				FN(reg, f5), v5, \
    276				FN(reg, f6), v6, \
    277				FN(reg, f7), v7)
    278
    279#define REG_UPDATE_8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8)	\
    280		REG_UPDATE_N(reg, 8, \
    281				FN(reg, f1), v1,\
    282				FN(reg, f2), v2, \
    283				FN(reg, f3), v3, \
    284				FN(reg, f4), v4, \
    285				FN(reg, f5), v5, \
    286				FN(reg, f6), v6, \
    287				FN(reg, f7), v7, \
    288				FN(reg, f8), v8)
    289
    290#define REG_UPDATE_9(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9)	\
    291		REG_UPDATE_N(reg, 9, \
    292				FN(reg, f1), v1,\
    293				FN(reg, f2), v2, \
    294				FN(reg, f3), v3, \
    295				FN(reg, f4), v4, \
    296				FN(reg, f5), v5, \
    297				FN(reg, f6), v6, \
    298				FN(reg, f7), v7, \
    299				FN(reg, f8), v8, \
    300				FN(reg, f9), v9)
    301
    302#define REG_UPDATE_10(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10)\
    303		REG_UPDATE_N(reg, 10, \
    304				FN(reg, f1), v1,\
    305				FN(reg, f2), v2, \
    306				FN(reg, f3), v3, \
    307				FN(reg, f4), v4, \
    308				FN(reg, f5), v5, \
    309				FN(reg, f6), v6, \
    310				FN(reg, f7), v7, \
    311				FN(reg, f8), v8, \
    312				FN(reg, f9), v9, \
    313				FN(reg, f10), v10)
    314
    315#define REG_UPDATE_14(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
    316		v10, f11, v11, f12, v12, f13, v13, f14, v14)\
    317		REG_UPDATE_N(reg, 14, \
    318				FN(reg, f1), v1,\
    319				FN(reg, f2), v2, \
    320				FN(reg, f3), v3, \
    321				FN(reg, f4), v4, \
    322				FN(reg, f5), v5, \
    323				FN(reg, f6), v6, \
    324				FN(reg, f7), v7, \
    325				FN(reg, f8), v8, \
    326				FN(reg, f9), v9, \
    327				FN(reg, f10), v10, \
    328				FN(reg, f11), v11, \
    329				FN(reg, f12), v12, \
    330				FN(reg, f13), v13, \
    331				FN(reg, f14), v14)
    332
    333#define REG_UPDATE_19(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
    334		v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19)\
    335		REG_UPDATE_N(reg, 19, \
    336				FN(reg, f1), v1,\
    337				FN(reg, f2), v2, \
    338				FN(reg, f3), v3, \
    339				FN(reg, f4), v4, \
    340				FN(reg, f5), v5, \
    341				FN(reg, f6), v6, \
    342				FN(reg, f7), v7, \
    343				FN(reg, f8), v8, \
    344				FN(reg, f9), v9, \
    345				FN(reg, f10), v10, \
    346				FN(reg, f11), v11, \
    347				FN(reg, f12), v12, \
    348				FN(reg, f13), v13, \
    349				FN(reg, f14), v14, \
    350				FN(reg, f15), v15, \
    351				FN(reg, f16), v16, \
    352				FN(reg, f17), v17, \
    353				FN(reg, f18), v18, \
    354				FN(reg, f19), v19)
    355
    356#define REG_UPDATE_20(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
    357		v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19, f20, v20)\
    358		REG_UPDATE_N(reg, 20, \
    359				FN(reg, f1), v1,\
    360				FN(reg, f2), v2, \
    361				FN(reg, f3), v3, \
    362				FN(reg, f4), v4, \
    363				FN(reg, f5), v5, \
    364				FN(reg, f6), v6, \
    365				FN(reg, f7), v7, \
    366				FN(reg, f8), v8, \
    367				FN(reg, f9), v9, \
    368				FN(reg, f10), v10, \
    369				FN(reg, f11), v11, \
    370				FN(reg, f12), v12, \
    371				FN(reg, f13), v13, \
    372				FN(reg, f14), v14, \
    373				FN(reg, f15), v15, \
    374				FN(reg, f16), v16, \
    375				FN(reg, f17), v17, \
    376				FN(reg, f18), v18, \
    377				FN(reg, f19), v19, \
    378				FN(reg, f20), v20)
    379/* macro to update a register field to specified values in given sequences.
    380 * useful when toggling bits
    381 */
    382#define REG_UPDATE_SEQ_2(reg, f1, v1, f2, v2) \
    383{	uint32_t val = REG_UPDATE(reg, f1, v1); \
    384	REG_SET(reg, val, f2, v2); }
    385
    386#define REG_UPDATE_SEQ_3(reg, f1, v1, f2, v2, f3, v3) \
    387{	uint32_t val = REG_UPDATE(reg, f1, v1); \
    388	val = REG_SET(reg, val, f2, v2); \
    389	REG_SET(reg, val, f3, v3); }
    390
    391uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
    392		uint8_t shift, uint32_t mask, uint32_t *field_value);
    393
    394uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
    395		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    396		uint8_t shift2, uint32_t mask2, uint32_t *field_value2);
    397
    398uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
    399		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    400		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
    401		uint8_t shift3, uint32_t mask3, uint32_t *field_value3);
    402
    403uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr,
    404		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    405		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
    406		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
    407		uint8_t shift4, uint32_t mask4, uint32_t *field_value4);
    408
    409uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
    410		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    411		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
    412		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
    413		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
    414		uint8_t shift5, uint32_t mask5, uint32_t *field_value5);
    415
    416uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr,
    417		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    418		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
    419		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
    420		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
    421		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
    422		uint8_t shift6, uint32_t mask6, uint32_t *field_value6);
    423
    424uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr,
    425		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    426		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
    427		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
    428		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
    429		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
    430		uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
    431		uint8_t shift7, uint32_t mask7, uint32_t *field_value7);
    432
    433uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
    434		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    435		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
    436		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
    437		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
    438		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
    439		uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
    440		uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
    441		uint8_t shift8, uint32_t mask8, uint32_t *field_value8);
    442
    443
    444/* indirect register access */
    445
    446#define IX_REG_SET_N(index_reg_name, data_reg_name, index, n, initial_val, ...)	\
    447		generic_indirect_reg_update_ex(CTX, \
    448				REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
    449				initial_val, \
    450				n, __VA_ARGS__)
    451
    452#define IX_REG_SET_2(index_reg_name, data_reg_name, index, init_value, f1, v1, f2, v2)	\
    453		IX_REG_SET_N(index_reg_name, data_reg_name, index, 2, init_value, \
    454				FN(reg, f1), v1,\
    455				FN(reg, f2), v2)
    456
    457
    458#define IX_REG_READ(index_reg_name, data_reg_name, index) \
    459		generic_read_indirect_reg(CTX, REG(index_reg_name), REG(data_reg_name), IND_REG(index))
    460
    461#define IX_REG_GET_N(index_reg_name, data_reg_name, index, n, ...) \
    462		generic_indirect_reg_get(CTX, REG(index_reg_name), REG(data_reg_name), \
    463				IND_REG(index), \
    464				n, __VA_ARGS__)
    465
    466#define IX_REG_GET(index_reg_name, data_reg_name, index, field, val) \
    467		IX_REG_GET_N(index_reg_name, data_reg_name, index, 1, \
    468				FN(data_reg_name, field), val)
    469
    470#define IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, n, ...)	\
    471		generic_indirect_reg_update_ex(CTX, \
    472				REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
    473				IX_REG_READ(index_reg_name, data_reg_name, index), \
    474				n, __VA_ARGS__)
    475
    476#define IX_REG_UPDATE_2(index_reg_name, data_reg_name, index, f1, v1, f2, v2)	\
    477		IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, 2,\
    478				FN(reg, f1), v1,\
    479				FN(reg, f2), v2)
    480
    481void generic_write_indirect_reg(const struct dc_context *ctx,
    482		uint32_t addr_index, uint32_t addr_data,
    483		uint32_t index, uint32_t data);
    484
    485uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
    486		uint32_t addr_index, uint32_t addr_data,
    487		uint32_t index);
    488
    489uint32_t generic_indirect_reg_get(const struct dc_context *ctx,
    490		uint32_t addr_index, uint32_t addr_data,
    491		uint32_t index, int n,
    492		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    493		...);
    494
    495uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
    496		uint32_t addr_index, uint32_t addr_data,
    497		uint32_t index, uint32_t reg_val, int n,
    498		uint8_t shift1, uint32_t mask1, uint32_t field_value1,
    499		...);
    500
    501/* indirect register access
    502 * underlying implementation determines which index/data pair to be used
    503 * in a synchronous way
    504 */
    505#define IX_REG_SET_N_SYNC(index, n, initial_val, ...)	\
    506		generic_indirect_reg_update_ex_sync(CTX, \
    507				IND_REG(index), \
    508				initial_val, \
    509				n, __VA_ARGS__)
    510
    511#define IX_REG_SET_2_SYNC(index, init_value, f1, v1, f2, v2)	\
    512		IX_REG_SET_N_SYNC(index, 2, init_value, \
    513				FN(reg, f1), v1,\
    514				FN(reg, f2), v2)
    515
    516#define IX_REG_GET_N_SYNC(index, n, ...) \
    517		generic_indirect_reg_get_sync(CTX, \
    518				IND_REG(index), \
    519				n, __VA_ARGS__)
    520
    521#define IX_REG_GET_SYNC(index, field, val) \
    522		IX_REG_GET_N_SYNC(index, 1, \
    523				FN(data_reg_name, field), val)
    524
    525uint32_t generic_indirect_reg_get_sync(const struct dc_context *ctx,
    526		uint32_t index, int n,
    527		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
    528		...);
    529
    530uint32_t generic_indirect_reg_update_ex_sync(const struct dc_context *ctx,
    531		uint32_t index, uint32_t reg_val, int n,
    532		uint8_t shift1, uint32_t mask1, uint32_t field_value1,
    533		...);
    534
    535/* register offload macros
    536 *
    537 * instead of MMIO to register directly, in some cases we want
    538 * to gather register sequence and execute the register sequence
    539 * from another thread so we optimize time required for lengthy ops
    540 */
    541
    542/* start gathering register sequence */
    543#define REG_SEQ_START() \
    544	reg_sequence_start_gather(CTX)
    545
    546/* start execution of register sequence gathered since REG_SEQ_START */
    547#define REG_SEQ_SUBMIT() \
    548	reg_sequence_start_execute(CTX)
    549
    550/* wait for the last REG_SEQ_SUBMIT to finish */
    551#define REG_SEQ_WAIT_DONE() \
    552	reg_sequence_wait_done(CTX)
    553
    554#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */