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_update_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 /* macro to poll and wait for a register field to read back given value */ 187 188 #define REG_WAIT(reg_name, field, val, delay_between_poll_us, max_try) \ 189 generic_reg_wait(CTX, \ 190 REG(reg_name), FN(reg_name, field), val,\ 191 delay_between_poll_us, max_try, __func__) 192 193 /* macro to update (read, modify, write) register fields 194 */ 195 #define REG_UPDATE_N(reg_name, n, ...) \ 196 generic_reg_update_ex(CTX, \ 197 REG(reg_name), \ 198 REG_READ(reg_name), \ 199 n, __VA_ARGS__) 200 201 #define REG_UPDATE(reg_name, field, val) \ 202 REG_UPDATE_N(reg_name, 1, \ 203 FN(reg_name, field), val) 204 205 #define REG_UPDATE_2(reg, f1, v1, f2, v2) \ 206 REG_UPDATE_N(reg, 2,\ 207 FN(reg, f1), v1,\ 208 FN(reg, f2), v2) 209 210 #define REG_UPDATE_3(reg, f1, v1, f2, v2, f3, v3) \ 211 REG_UPDATE_N(reg, 3, \ 212 FN(reg, f1), v1,\ 213 FN(reg, f2), v2, \ 214 FN(reg, f3), v3) 215 216 #define REG_UPDATE_4(reg, f1, v1, f2, v2, f3, v3, f4, v4) \ 217 REG_UPDATE_N(reg, 4, \ 218 FN(reg, f1), v1,\ 219 FN(reg, f2), v2, \ 220 FN(reg, f3), v3, \ 221 FN(reg, f4), v4) 222 223 #define REG_UPDATE_5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \ 224 REG_UPDATE_N(reg, 5, \ 225 FN(reg, f1), v1,\ 226 FN(reg, f2), v2, \ 227 FN(reg, f3), v3, \ 228 FN(reg, f4), v4, \ 229 FN(reg, f5), v5) 230 231 #define REG_UPDATE_6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \ 232 REG_UPDATE_N(reg, 6, \ 233 FN(reg, f1), v1,\ 234 FN(reg, f2), v2, \ 235 FN(reg, f3), v3, \ 236 FN(reg, f4), v4, \ 237 FN(reg, f5), v5, \ 238 FN(reg, f6), v6) 239 240 #define REG_UPDATE_7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \ 241 REG_UPDATE_N(reg, 7, \ 242 FN(reg, f1), v1,\ 243 FN(reg, f2), v2, \ 244 FN(reg, f3), v3, \ 245 FN(reg, f4), v4, \ 246 FN(reg, f5), v5, \ 247 FN(reg, f6), v6, \ 248 FN(reg, f7), v7) 249 250 #define REG_UPDATE_8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \ 251 REG_UPDATE_N(reg, 8, \ 252 FN(reg, f1), v1,\ 253 FN(reg, f2), v2, \ 254 FN(reg, f3), v3, \ 255 FN(reg, f4), v4, \ 256 FN(reg, f5), v5, \ 257 FN(reg, f6), v6, \ 258 FN(reg, f7), v7, \ 259 FN(reg, f8), v8) 260 261 #define REG_UPDATE_9(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9) \ 262 REG_UPDATE_N(reg, 9, \ 263 FN(reg, f1), v1,\ 264 FN(reg, f2), v2, \ 265 FN(reg, f3), v3, \ 266 FN(reg, f4), v4, \ 267 FN(reg, f5), v5, \ 268 FN(reg, f6), v6, \ 269 FN(reg, f7), v7, \ 270 FN(reg, f8), v8, \ 271 FN(reg, f9), v9) 272 273 #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) \ 274 REG_UPDATE_N(reg, 10, \ 275 FN(reg, f1), v1,\ 276 FN(reg, f2), v2, \ 277 FN(reg, f3), v3, \ 278 FN(reg, f4), v4, \ 279 FN(reg, f5), v5, \ 280 FN(reg, f6), v6, \ 281 FN(reg, f7), v7, \ 282 FN(reg, f8), v8, \ 283 FN(reg, f9), v9, \ 284 FN(reg, f10), v10) 285 286 /* macro to update a register field to specified values in given sequences. 287 * useful when toggling bits 288 */ 289 #define REG_UPDATE_SEQ(reg, field, value1, value2) \ 290 { uint32_t val = REG_UPDATE(reg, field, value1); \ 291 REG_SET(reg, val, field, value2); } 292 293 /* macro to update fields in register 1 field at a time in given order */ 294 #define REG_UPDATE_1BY1_2(reg, f1, v1, f2, v2) \ 295 { uint32_t val = REG_UPDATE(reg, f1, v1); \ 296 REG_SET(reg, val, f2, v2); } 297 298 #define REG_UPDATE_1BY1_3(reg, f1, v1, f2, v2, f3, v3) \ 299 { uint32_t val = REG_UPDATE(reg, f1, v1); \ 300 val = REG_SET(reg, val, f2, v2); \ 301 REG_SET(reg, val, f3, v3); } 302 303 uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr, 304 uint8_t shift, uint32_t mask, uint32_t *field_value); 305 306 uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr, 307 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 308 uint8_t shift2, uint32_t mask2, uint32_t *field_value2); 309 310 uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr, 311 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 312 uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 313 uint8_t shift3, uint32_t mask3, uint32_t *field_value3); 314 315 uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr, 316 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 317 uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 318 uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 319 uint8_t shift4, uint32_t mask4, uint32_t *field_value4); 320 321 uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr, 322 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 323 uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 324 uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 325 uint8_t shift4, uint32_t mask4, uint32_t *field_value4, 326 uint8_t shift5, uint32_t mask5, uint32_t *field_value5); 327 328 #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */ 329