Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2016 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  */
0024 
0025 #ifndef DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
0026 #define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_
0027 
0028 #include "dm_services.h"
0029 
0030 /* macro for register read/write
0031  * user of macro need to define
0032  *
0033  * CTX ==> macro to ptr to dc_context
0034  *    eg. aud110->base.ctx
0035  *
0036  * REG ==> macro to location of register offset
0037  *    eg. aud110->regs->reg
0038  */
0039 #define REG_READ(reg_name) \
0040         dm_read_reg(CTX, REG(reg_name))
0041 
0042 #define REG_WRITE(reg_name, value) \
0043         dm_write_reg(CTX, REG(reg_name), value)
0044 
0045 #ifdef REG_SET
0046 #undef REG_SET
0047 #endif
0048 
0049 #ifdef REG_GET
0050 #undef REG_GET
0051 #endif
0052 
0053 /* macro to set register fields. */
0054 #define REG_SET_N(reg_name, n, initial_val, ...)    \
0055         generic_reg_set_ex(CTX, \
0056                 REG(reg_name), \
0057                 initial_val, \
0058                 n, __VA_ARGS__)
0059 
0060 #define FN(reg_name, field) \
0061     FD(reg_name##__##field)
0062 
0063 #define REG_SET(reg_name, initial_val, field, val)  \
0064         REG_SET_N(reg_name, 1, initial_val, \
0065                 FN(reg_name, field), val)
0066 
0067 #define REG_SET_2(reg, init_value, f1, v1, f2, v2)  \
0068         REG_SET_N(reg, 2, init_value, \
0069                 FN(reg, f1), v1,\
0070                 FN(reg, f2), v2)
0071 
0072 #define REG_SET_3(reg, init_value, f1, v1, f2, v2, f3, v3)  \
0073         REG_SET_N(reg, 3, init_value, \
0074                 FN(reg, f1), v1,\
0075                 FN(reg, f2), v2,\
0076                 FN(reg, f3), v3)
0077 
0078 #define REG_SET_4(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4)  \
0079         REG_SET_N(reg, 4, init_value, \
0080                 FN(reg, f1), v1,\
0081                 FN(reg, f2), v2,\
0082                 FN(reg, f3), v3,\
0083                 FN(reg, f4), v4)
0084 
0085 #define REG_SET_5(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,  \
0086         f5, v5) \
0087         REG_SET_N(reg, 5, init_value, \
0088                 FN(reg, f1), v1,\
0089                 FN(reg, f2), v2,\
0090                 FN(reg, f3), v3,\
0091                 FN(reg, f4), v4,\
0092                 FN(reg, f5), v5)
0093 
0094 #define REG_SET_6(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,  \
0095         f5, v5, f6, v6) \
0096         REG_SET_N(reg, 6, init_value, \
0097                 FN(reg, f1), v1,\
0098                 FN(reg, f2), v2,\
0099                 FN(reg, f3), v3,\
0100                 FN(reg, f4), v4,\
0101                 FN(reg, f5), v5,\
0102                 FN(reg, f6), v6)
0103 
0104 #define REG_SET_7(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,  \
0105         f5, v5, f6, v6, f7, v7) \
0106         REG_SET_N(reg, 7, init_value, \
0107                 FN(reg, f1), v1,\
0108                 FN(reg, f2), v2,\
0109                 FN(reg, f3), v3,\
0110                 FN(reg, f4), v4,\
0111                 FN(reg, f5), v5,\
0112                 FN(reg, f6), v6,\
0113                 FN(reg, f7), v7)
0114 
0115 #define REG_SET_8(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4,  \
0116         f5, v5, f6, v6, f7, v7, f8, v8) \
0117         REG_SET_N(reg, 8, init_value, \
0118                 FN(reg, f1), v1,\
0119                 FN(reg, f2), v2,\
0120                 FN(reg, f3), v3,\
0121                 FN(reg, f4), v4,\
0122                 FN(reg, f5), v5,\
0123                 FN(reg, f6), v6,\
0124                 FN(reg, f7), v7,\
0125                 FN(reg, f8), v8)
0126 
0127 #define REG_SET_9(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
0128         v5, f6, v6, f7, v7, f8, v8, f9, v9) \
0129         REG_SET_N(reg, 9, init_value, \
0130                 FN(reg, f1), v1,\
0131                 FN(reg, f2), v2, \
0132                 FN(reg, f3), v3, \
0133                 FN(reg, f4), v4, \
0134                 FN(reg, f5), v5, \
0135                 FN(reg, f6), v6, \
0136                 FN(reg, f7), v7, \
0137                 FN(reg, f8), v8, \
0138                 FN(reg, f9), v9)
0139 
0140 #define REG_SET_10(reg, init_value, f1, v1, f2, v2, f3, v3, f4, v4, f5, \
0141         v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10)   \
0142         REG_SET_N(reg, 10, init_value, \
0143                 FN(reg, f1), v1,\
0144                 FN(reg, f2), v2, \
0145                 FN(reg, f3), v3, \
0146                 FN(reg, f4), v4, \
0147                 FN(reg, f5), v5, \
0148                 FN(reg, f6), v6, \
0149                 FN(reg, f7), v7, \
0150                 FN(reg, f8), v8, \
0151                 FN(reg, f9), v9, \
0152                 FN(reg, f10), v10)
0153 
0154 /* macro to get register fields
0155  * read given register and fill in field value in output parameter */
0156 #define REG_GET(reg_name, field, val)   \
0157         generic_reg_get(CTX, REG(reg_name), \
0158                 FN(reg_name, field), val)
0159 
0160 #define REG_GET_2(reg_name, f1, v1, f2, v2) \
0161         generic_reg_get2(CTX, REG(reg_name), \
0162                 FN(reg_name, f1), v1, \
0163                 FN(reg_name, f2), v2)
0164 
0165 #define REG_GET_3(reg_name, f1, v1, f2, v2, f3, v3) \
0166         generic_reg_get3(CTX, REG(reg_name), \
0167                 FN(reg_name, f1), v1, \
0168                 FN(reg_name, f2), v2, \
0169                 FN(reg_name, f3), v3)
0170 
0171 #define REG_GET_4(reg_name, f1, v1, f2, v2, f3, v3, f4, v4) \
0172         generic_reg_get4(CTX, REG(reg_name), \
0173                 FN(reg_name, f1), v1, \
0174                 FN(reg_name, f2), v2, \
0175                 FN(reg_name, f3), v3, \
0176                 FN(reg_name, f4), v4)
0177 
0178 #define REG_GET_5(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
0179         generic_reg_get5(CTX, REG(reg_name), \
0180                 FN(reg_name, f1), v1, \
0181                 FN(reg_name, f2), v2, \
0182                 FN(reg_name, f3), v3, \
0183                 FN(reg_name, f4), v4, \
0184                 FN(reg_name, f5), v5)
0185 
0186 #define REG_GET_6(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
0187         generic_reg_get6(CTX, REG(reg_name), \
0188                 FN(reg_name, f1), v1, \
0189                 FN(reg_name, f2), v2, \
0190                 FN(reg_name, f3), v3, \
0191                 FN(reg_name, f4), v4, \
0192                 FN(reg_name, f5), v5, \
0193                 FN(reg_name, f6), v6)
0194 
0195 #define REG_GET_7(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
0196         generic_reg_get7(CTX, REG(reg_name), \
0197                 FN(reg_name, f1), v1, \
0198                 FN(reg_name, f2), v2, \
0199                 FN(reg_name, f3), v3, \
0200                 FN(reg_name, f4), v4, \
0201                 FN(reg_name, f5), v5, \
0202                 FN(reg_name, f6), v6, \
0203                 FN(reg_name, f7), v7)
0204 
0205 #define REG_GET_8(reg_name, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
0206         generic_reg_get8(CTX, REG(reg_name), \
0207                 FN(reg_name, f1), v1, \
0208                 FN(reg_name, f2), v2, \
0209                 FN(reg_name, f3), v3, \
0210                 FN(reg_name, f4), v4, \
0211                 FN(reg_name, f5), v5, \
0212                 FN(reg_name, f6), v6, \
0213                 FN(reg_name, f7), v7, \
0214                 FN(reg_name, f8), v8)
0215 
0216 /* macro to poll and wait for a register field to read back given value */
0217 
0218 #define REG_WAIT(reg_name, field, val, delay_between_poll_us, max_try)  \
0219         generic_reg_wait(CTX, \
0220                 REG(reg_name), FN(reg_name, field), val,\
0221                 delay_between_poll_us, max_try, __func__, __LINE__)
0222 
0223 /* macro to update (read, modify, write) register fields
0224  */
0225 #define REG_UPDATE_N(reg_name, n, ...)  \
0226         generic_reg_update_ex(CTX, \
0227                 REG(reg_name), \
0228                 n, __VA_ARGS__)
0229 
0230 #define REG_UPDATE(reg_name, field, val)    \
0231         REG_UPDATE_N(reg_name, 1, \
0232                 FN(reg_name, field), val)
0233 
0234 #define REG_UPDATE_2(reg, f1, v1, f2, v2)   \
0235         REG_UPDATE_N(reg, 2,\
0236                 FN(reg, f1), v1,\
0237                 FN(reg, f2), v2)
0238 
0239 #define REG_UPDATE_3(reg, f1, v1, f2, v2, f3, v3)   \
0240         REG_UPDATE_N(reg, 3, \
0241                 FN(reg, f1), v1,\
0242                 FN(reg, f2), v2, \
0243                 FN(reg, f3), v3)
0244 
0245 #define REG_UPDATE_4(reg, f1, v1, f2, v2, f3, v3, f4, v4)   \
0246         REG_UPDATE_N(reg, 4, \
0247                 FN(reg, f1), v1,\
0248                 FN(reg, f2), v2, \
0249                 FN(reg, f3), v3, \
0250                 FN(reg, f4), v4)
0251 
0252 #define REG_UPDATE_5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)   \
0253         REG_UPDATE_N(reg, 5, \
0254                 FN(reg, f1), v1,\
0255                 FN(reg, f2), v2, \
0256                 FN(reg, f3), v3, \
0257                 FN(reg, f4), v4, \
0258                 FN(reg, f5), v5)
0259 
0260 #define REG_UPDATE_6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)   \
0261         REG_UPDATE_N(reg, 6, \
0262                 FN(reg, f1), v1,\
0263                 FN(reg, f2), v2, \
0264                 FN(reg, f3), v3, \
0265                 FN(reg, f4), v4, \
0266                 FN(reg, f5), v5, \
0267                 FN(reg, f6), v6)
0268 
0269 #define REG_UPDATE_7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7)   \
0270         REG_UPDATE_N(reg, 7, \
0271                 FN(reg, f1), v1,\
0272                 FN(reg, f2), v2, \
0273                 FN(reg, f3), v3, \
0274                 FN(reg, f4), v4, \
0275                 FN(reg, f5), v5, \
0276                 FN(reg, f6), v6, \
0277                 FN(reg, f7), v7)
0278 
0279 #define REG_UPDATE_8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8)   \
0280         REG_UPDATE_N(reg, 8, \
0281                 FN(reg, f1), v1,\
0282                 FN(reg, f2), v2, \
0283                 FN(reg, f3), v3, \
0284                 FN(reg, f4), v4, \
0285                 FN(reg, f5), v5, \
0286                 FN(reg, f6), v6, \
0287                 FN(reg, f7), v7, \
0288                 FN(reg, f8), v8)
0289 
0290 #define REG_UPDATE_9(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9)   \
0291         REG_UPDATE_N(reg, 9, \
0292                 FN(reg, f1), v1,\
0293                 FN(reg, f2), v2, \
0294                 FN(reg, f3), v3, \
0295                 FN(reg, f4), v4, \
0296                 FN(reg, f5), v5, \
0297                 FN(reg, f6), v6, \
0298                 FN(reg, f7), v7, \
0299                 FN(reg, f8), v8, \
0300                 FN(reg, f9), v9)
0301 
0302 #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)\
0303         REG_UPDATE_N(reg, 10, \
0304                 FN(reg, f1), v1,\
0305                 FN(reg, f2), v2, \
0306                 FN(reg, f3), v3, \
0307                 FN(reg, f4), v4, \
0308                 FN(reg, f5), v5, \
0309                 FN(reg, f6), v6, \
0310                 FN(reg, f7), v7, \
0311                 FN(reg, f8), v8, \
0312                 FN(reg, f9), v9, \
0313                 FN(reg, f10), v10)
0314 
0315 #define REG_UPDATE_14(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
0316         v10, f11, v11, f12, v12, f13, v13, f14, v14)\
0317         REG_UPDATE_N(reg, 14, \
0318                 FN(reg, f1), v1,\
0319                 FN(reg, f2), v2, \
0320                 FN(reg, f3), v3, \
0321                 FN(reg, f4), v4, \
0322                 FN(reg, f5), v5, \
0323                 FN(reg, f6), v6, \
0324                 FN(reg, f7), v7, \
0325                 FN(reg, f8), v8, \
0326                 FN(reg, f9), v9, \
0327                 FN(reg, f10), v10, \
0328                 FN(reg, f11), v11, \
0329                 FN(reg, f12), v12, \
0330                 FN(reg, f13), v13, \
0331                 FN(reg, f14), v14)
0332 
0333 #define REG_UPDATE_19(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
0334         v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19)\
0335         REG_UPDATE_N(reg, 19, \
0336                 FN(reg, f1), v1,\
0337                 FN(reg, f2), v2, \
0338                 FN(reg, f3), v3, \
0339                 FN(reg, f4), v4, \
0340                 FN(reg, f5), v5, \
0341                 FN(reg, f6), v6, \
0342                 FN(reg, f7), v7, \
0343                 FN(reg, f8), v8, \
0344                 FN(reg, f9), v9, \
0345                 FN(reg, f10), v10, \
0346                 FN(reg, f11), v11, \
0347                 FN(reg, f12), v12, \
0348                 FN(reg, f13), v13, \
0349                 FN(reg, f14), v14, \
0350                 FN(reg, f15), v15, \
0351                 FN(reg, f16), v16, \
0352                 FN(reg, f17), v17, \
0353                 FN(reg, f18), v18, \
0354                 FN(reg, f19), v19)
0355 
0356 #define REG_UPDATE_20(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10,\
0357         v10, f11, v11, f12, v12, f13, v13, f14, v14, f15, v15, f16, v16, f17, v17, f18, v18, f19, v19, f20, v20)\
0358         REG_UPDATE_N(reg, 20, \
0359                 FN(reg, f1), v1,\
0360                 FN(reg, f2), v2, \
0361                 FN(reg, f3), v3, \
0362                 FN(reg, f4), v4, \
0363                 FN(reg, f5), v5, \
0364                 FN(reg, f6), v6, \
0365                 FN(reg, f7), v7, \
0366                 FN(reg, f8), v8, \
0367                 FN(reg, f9), v9, \
0368                 FN(reg, f10), v10, \
0369                 FN(reg, f11), v11, \
0370                 FN(reg, f12), v12, \
0371                 FN(reg, f13), v13, \
0372                 FN(reg, f14), v14, \
0373                 FN(reg, f15), v15, \
0374                 FN(reg, f16), v16, \
0375                 FN(reg, f17), v17, \
0376                 FN(reg, f18), v18, \
0377                 FN(reg, f19), v19, \
0378                 FN(reg, f20), v20)
0379 /* macro to update a register field to specified values in given sequences.
0380  * useful when toggling bits
0381  */
0382 #define REG_UPDATE_SEQ_2(reg, f1, v1, f2, v2) \
0383 {   uint32_t val = REG_UPDATE(reg, f1, v1); \
0384     REG_SET(reg, val, f2, v2); }
0385 
0386 #define REG_UPDATE_SEQ_3(reg, f1, v1, f2, v2, f3, v3) \
0387 {   uint32_t val = REG_UPDATE(reg, f1, v1); \
0388     val = REG_SET(reg, val, f2, v2); \
0389     REG_SET(reg, val, f3, v3); }
0390 
0391 uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
0392         uint8_t shift, uint32_t mask, uint32_t *field_value);
0393 
0394 uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
0395         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0396         uint8_t shift2, uint32_t mask2, uint32_t *field_value2);
0397 
0398 uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
0399         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0400         uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
0401         uint8_t shift3, uint32_t mask3, uint32_t *field_value3);
0402 
0403 uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr,
0404         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0405         uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
0406         uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
0407         uint8_t shift4, uint32_t mask4, uint32_t *field_value4);
0408 
0409 uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
0410         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0411         uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
0412         uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
0413         uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
0414         uint8_t shift5, uint32_t mask5, uint32_t *field_value5);
0415 
0416 uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr,
0417         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0418         uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
0419         uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
0420         uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
0421         uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
0422         uint8_t shift6, uint32_t mask6, uint32_t *field_value6);
0423 
0424 uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr,
0425         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0426         uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
0427         uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
0428         uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
0429         uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
0430         uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
0431         uint8_t shift7, uint32_t mask7, uint32_t *field_value7);
0432 
0433 uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
0434         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0435         uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
0436         uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
0437         uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
0438         uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
0439         uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
0440         uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
0441         uint8_t shift8, uint32_t mask8, uint32_t *field_value8);
0442 
0443 
0444 /* indirect register access */
0445 
0446 #define IX_REG_SET_N(index_reg_name, data_reg_name, index, n, initial_val, ...) \
0447         generic_indirect_reg_update_ex(CTX, \
0448                 REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
0449                 initial_val, \
0450                 n, __VA_ARGS__)
0451 
0452 #define IX_REG_SET_2(index_reg_name, data_reg_name, index, init_value, f1, v1, f2, v2)  \
0453         IX_REG_SET_N(index_reg_name, data_reg_name, index, 2, init_value, \
0454                 FN(reg, f1), v1,\
0455                 FN(reg, f2), v2)
0456 
0457 
0458 #define IX_REG_READ(index_reg_name, data_reg_name, index) \
0459         generic_read_indirect_reg(CTX, REG(index_reg_name), REG(data_reg_name), IND_REG(index))
0460 
0461 #define IX_REG_GET_N(index_reg_name, data_reg_name, index, n, ...) \
0462         generic_indirect_reg_get(CTX, REG(index_reg_name), REG(data_reg_name), \
0463                 IND_REG(index), \
0464                 n, __VA_ARGS__)
0465 
0466 #define IX_REG_GET(index_reg_name, data_reg_name, index, field, val) \
0467         IX_REG_GET_N(index_reg_name, data_reg_name, index, 1, \
0468                 FN(data_reg_name, field), val)
0469 
0470 #define IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, n, ...)   \
0471         generic_indirect_reg_update_ex(CTX, \
0472                 REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
0473                 IX_REG_READ(index_reg_name, data_reg_name, index), \
0474                 n, __VA_ARGS__)
0475 
0476 #define IX_REG_UPDATE_2(index_reg_name, data_reg_name, index, f1, v1, f2, v2)   \
0477         IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, 2,\
0478                 FN(reg, f1), v1,\
0479                 FN(reg, f2), v2)
0480 
0481 void generic_write_indirect_reg(const struct dc_context *ctx,
0482         uint32_t addr_index, uint32_t addr_data,
0483         uint32_t index, uint32_t data);
0484 
0485 uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
0486         uint32_t addr_index, uint32_t addr_data,
0487         uint32_t index);
0488 
0489 uint32_t generic_indirect_reg_get(const struct dc_context *ctx,
0490         uint32_t addr_index, uint32_t addr_data,
0491         uint32_t index, int n,
0492         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0493         ...);
0494 
0495 uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
0496         uint32_t addr_index, uint32_t addr_data,
0497         uint32_t index, uint32_t reg_val, int n,
0498         uint8_t shift1, uint32_t mask1, uint32_t field_value1,
0499         ...);
0500 
0501 /* indirect register access
0502  * underlying implementation determines which index/data pair to be used
0503  * in a synchronous way
0504  */
0505 #define IX_REG_SET_N_SYNC(index, n, initial_val, ...)   \
0506         generic_indirect_reg_update_ex_sync(CTX, \
0507                 IND_REG(index), \
0508                 initial_val, \
0509                 n, __VA_ARGS__)
0510 
0511 #define IX_REG_SET_2_SYNC(index, init_value, f1, v1, f2, v2)    \
0512         IX_REG_SET_N_SYNC(index, 2, init_value, \
0513                 FN(reg, f1), v1,\
0514                 FN(reg, f2), v2)
0515 
0516 #define IX_REG_GET_N_SYNC(index, n, ...) \
0517         generic_indirect_reg_get_sync(CTX, \
0518                 IND_REG(index), \
0519                 n, __VA_ARGS__)
0520 
0521 #define IX_REG_GET_SYNC(index, field, val) \
0522         IX_REG_GET_N_SYNC(index, 1, \
0523                 FN(data_reg_name, field), val)
0524 
0525 uint32_t generic_indirect_reg_get_sync(const struct dc_context *ctx,
0526         uint32_t index, int n,
0527         uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
0528         ...);
0529 
0530 uint32_t generic_indirect_reg_update_ex_sync(const struct dc_context *ctx,
0531         uint32_t index, uint32_t reg_val, int n,
0532         uint8_t shift1, uint32_t mask1, uint32_t field_value1,
0533         ...);
0534 
0535 /* register offload macros
0536  *
0537  * instead of MMIO to register directly, in some cases we want
0538  * to gather register sequence and execute the register sequence
0539  * from another thread so we optimize time required for lengthy ops
0540  */
0541 
0542 /* start gathering register sequence */
0543 #define REG_SEQ_START() \
0544     reg_sequence_start_gather(CTX)
0545 
0546 /* start execution of register sequence gathered since REG_SEQ_START */
0547 #define REG_SEQ_SUBMIT() \
0548     reg_sequence_start_execute(CTX)
0549 
0550 /* wait for the last REG_SEQ_SUBMIT to finish */
0551 #define REG_SEQ_WAIT_DONE() \
0552     reg_sequence_wait_done(CTX)
0553 
0554 #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */