1*b843c749SSergey Zigachev /* 2*b843c749SSergey Zigachev * Copyright 2017 Advanced Micro Devices, Inc. 3*b843c749SSergey Zigachev * 4*b843c749SSergey Zigachev * Permission is hereby granted, free of charge, to any person obtaining a 5*b843c749SSergey Zigachev * copy of this software and associated documentation files (the "Software"), 6*b843c749SSergey Zigachev * to deal in the Software without restriction, including without limitation 7*b843c749SSergey Zigachev * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*b843c749SSergey Zigachev * and/or sell copies of the Software, and to permit persons to whom the 9*b843c749SSergey Zigachev * Software is furnished to do so, subject to the following conditions: 10*b843c749SSergey Zigachev * 11*b843c749SSergey Zigachev * The above copyright notice and this permission notice shall be included in 12*b843c749SSergey Zigachev * all copies or substantial portions of the Software. 13*b843c749SSergey Zigachev * 14*b843c749SSergey Zigachev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*b843c749SSergey Zigachev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*b843c749SSergey Zigachev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17*b843c749SSergey Zigachev * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18*b843c749SSergey Zigachev * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19*b843c749SSergey Zigachev * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20*b843c749SSergey Zigachev * OTHER DEALINGS IN THE SOFTWARE. 21*b843c749SSergey Zigachev * 22*b843c749SSergey Zigachev */ 23*b843c749SSergey Zigachev /* 24*b843c749SSergey Zigachev * dc_helper.c 25*b843c749SSergey Zigachev * 26*b843c749SSergey Zigachev * Created on: Aug 30, 2016 27*b843c749SSergey Zigachev * Author: agrodzov 28*b843c749SSergey Zigachev */ 29*b843c749SSergey Zigachev #include "dm_services.h" 30*b843c749SSergey Zigachev #include <stdarg.h> 31*b843c749SSergey Zigachev 32*b843c749SSergey Zigachev uint32_t generic_reg_update_ex(const struct dc_context *ctx, 33*b843c749SSergey Zigachev uint32_t addr, uint32_t reg_val, int n, 34*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t field_value1, 35*b843c749SSergey Zigachev ...) 36*b843c749SSergey Zigachev { 37*b843c749SSergey Zigachev uint32_t shift, mask, field_value; 38*b843c749SSergey Zigachev int i = 1; 39*b843c749SSergey Zigachev 40*b843c749SSergey Zigachev va_list ap; 41*b843c749SSergey Zigachev va_start(ap, field_value1); 42*b843c749SSergey Zigachev 43*b843c749SSergey Zigachev reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1); 44*b843c749SSergey Zigachev 45*b843c749SSergey Zigachev while (i < n) { 46*b843c749SSergey Zigachev shift = va_arg(ap, uint32_t); 47*b843c749SSergey Zigachev mask = va_arg(ap, uint32_t); 48*b843c749SSergey Zigachev field_value = va_arg(ap, uint32_t); 49*b843c749SSergey Zigachev 50*b843c749SSergey Zigachev reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift); 51*b843c749SSergey Zigachev i++; 52*b843c749SSergey Zigachev } 53*b843c749SSergey Zigachev 54*b843c749SSergey Zigachev dm_write_reg(ctx, addr, reg_val); 55*b843c749SSergey Zigachev va_end(ap); 56*b843c749SSergey Zigachev 57*b843c749SSergey Zigachev return reg_val; 58*b843c749SSergey Zigachev } 59*b843c749SSergey Zigachev 60*b843c749SSergey Zigachev uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr, 61*b843c749SSergey Zigachev uint8_t shift, uint32_t mask, uint32_t *field_value) 62*b843c749SSergey Zigachev { 63*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 64*b843c749SSergey Zigachev *field_value = get_reg_field_value_ex(reg_val, mask, shift); 65*b843c749SSergey Zigachev return reg_val; 66*b843c749SSergey Zigachev } 67*b843c749SSergey Zigachev 68*b843c749SSergey Zigachev uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr, 69*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 70*b843c749SSergey Zigachev uint8_t shift2, uint32_t mask2, uint32_t *field_value2) 71*b843c749SSergey Zigachev { 72*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 73*b843c749SSergey Zigachev *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 74*b843c749SSergey Zigachev *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 75*b843c749SSergey Zigachev return reg_val; 76*b843c749SSergey Zigachev } 77*b843c749SSergey Zigachev 78*b843c749SSergey Zigachev uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr, 79*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 80*b843c749SSergey Zigachev uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 81*b843c749SSergey Zigachev uint8_t shift3, uint32_t mask3, uint32_t *field_value3) 82*b843c749SSergey Zigachev { 83*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 84*b843c749SSergey Zigachev *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 85*b843c749SSergey Zigachev *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 86*b843c749SSergey Zigachev *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 87*b843c749SSergey Zigachev return reg_val; 88*b843c749SSergey Zigachev } 89*b843c749SSergey Zigachev 90*b843c749SSergey Zigachev uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr, 91*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 92*b843c749SSergey Zigachev uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 93*b843c749SSergey Zigachev uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 94*b843c749SSergey Zigachev uint8_t shift4, uint32_t mask4, uint32_t *field_value4) 95*b843c749SSergey Zigachev { 96*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 97*b843c749SSergey Zigachev *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 98*b843c749SSergey Zigachev *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 99*b843c749SSergey Zigachev *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 100*b843c749SSergey Zigachev *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); 101*b843c749SSergey Zigachev return reg_val; 102*b843c749SSergey Zigachev } 103*b843c749SSergey Zigachev 104*b843c749SSergey Zigachev uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr, 105*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 106*b843c749SSergey Zigachev uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 107*b843c749SSergey Zigachev uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 108*b843c749SSergey Zigachev uint8_t shift4, uint32_t mask4, uint32_t *field_value4, 109*b843c749SSergey Zigachev uint8_t shift5, uint32_t mask5, uint32_t *field_value5) 110*b843c749SSergey Zigachev { 111*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 112*b843c749SSergey Zigachev *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 113*b843c749SSergey Zigachev *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 114*b843c749SSergey Zigachev *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 115*b843c749SSergey Zigachev *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); 116*b843c749SSergey Zigachev *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5); 117*b843c749SSergey Zigachev return reg_val; 118*b843c749SSergey Zigachev } 119*b843c749SSergey Zigachev 120*b843c749SSergey Zigachev uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr, 121*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 122*b843c749SSergey Zigachev uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 123*b843c749SSergey Zigachev uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 124*b843c749SSergey Zigachev uint8_t shift4, uint32_t mask4, uint32_t *field_value4, 125*b843c749SSergey Zigachev uint8_t shift5, uint32_t mask5, uint32_t *field_value5, 126*b843c749SSergey Zigachev uint8_t shift6, uint32_t mask6, uint32_t *field_value6) 127*b843c749SSergey Zigachev { 128*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 129*b843c749SSergey Zigachev *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 130*b843c749SSergey Zigachev *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 131*b843c749SSergey Zigachev *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 132*b843c749SSergey Zigachev *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); 133*b843c749SSergey Zigachev *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5); 134*b843c749SSergey Zigachev *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6); 135*b843c749SSergey Zigachev return reg_val; 136*b843c749SSergey Zigachev } 137*b843c749SSergey Zigachev 138*b843c749SSergey Zigachev uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr, 139*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 140*b843c749SSergey Zigachev uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 141*b843c749SSergey Zigachev uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 142*b843c749SSergey Zigachev uint8_t shift4, uint32_t mask4, uint32_t *field_value4, 143*b843c749SSergey Zigachev uint8_t shift5, uint32_t mask5, uint32_t *field_value5, 144*b843c749SSergey Zigachev uint8_t shift6, uint32_t mask6, uint32_t *field_value6, 145*b843c749SSergey Zigachev uint8_t shift7, uint32_t mask7, uint32_t *field_value7) 146*b843c749SSergey Zigachev { 147*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 148*b843c749SSergey Zigachev *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 149*b843c749SSergey Zigachev *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 150*b843c749SSergey Zigachev *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 151*b843c749SSergey Zigachev *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); 152*b843c749SSergey Zigachev *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5); 153*b843c749SSergey Zigachev *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6); 154*b843c749SSergey Zigachev *field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7); 155*b843c749SSergey Zigachev return reg_val; 156*b843c749SSergey Zigachev } 157*b843c749SSergey Zigachev 158*b843c749SSergey Zigachev uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr, 159*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 160*b843c749SSergey Zigachev uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 161*b843c749SSergey Zigachev uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 162*b843c749SSergey Zigachev uint8_t shift4, uint32_t mask4, uint32_t *field_value4, 163*b843c749SSergey Zigachev uint8_t shift5, uint32_t mask5, uint32_t *field_value5, 164*b843c749SSergey Zigachev uint8_t shift6, uint32_t mask6, uint32_t *field_value6, 165*b843c749SSergey Zigachev uint8_t shift7, uint32_t mask7, uint32_t *field_value7, 166*b843c749SSergey Zigachev uint8_t shift8, uint32_t mask8, uint32_t *field_value8) 167*b843c749SSergey Zigachev { 168*b843c749SSergey Zigachev uint32_t reg_val = dm_read_reg(ctx, addr); 169*b843c749SSergey Zigachev *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 170*b843c749SSergey Zigachev *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 171*b843c749SSergey Zigachev *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 172*b843c749SSergey Zigachev *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); 173*b843c749SSergey Zigachev *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5); 174*b843c749SSergey Zigachev *field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6); 175*b843c749SSergey Zigachev *field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7); 176*b843c749SSergey Zigachev *field_value8 = get_reg_field_value_ex(reg_val, mask8, shift8); 177*b843c749SSergey Zigachev return reg_val; 178*b843c749SSergey Zigachev } 179*b843c749SSergey Zigachev /* note: va version of this is pretty bad idea, since there is a output parameter pass by pointer 180*b843c749SSergey Zigachev * compiler won't be able to check for size match and is prone to stack corruption type of bugs 181*b843c749SSergey Zigachev 182*b843c749SSergey Zigachev uint32_t generic_reg_get(const struct dc_context *ctx, 183*b843c749SSergey Zigachev uint32_t addr, int n, ...) 184*b843c749SSergey Zigachev { 185*b843c749SSergey Zigachev uint32_t shift, mask; 186*b843c749SSergey Zigachev uint32_t *field_value; 187*b843c749SSergey Zigachev uint32_t reg_val; 188*b843c749SSergey Zigachev int i = 0; 189*b843c749SSergey Zigachev 190*b843c749SSergey Zigachev reg_val = dm_read_reg(ctx, addr); 191*b843c749SSergey Zigachev 192*b843c749SSergey Zigachev va_list ap; 193*b843c749SSergey Zigachev va_start(ap, n); 194*b843c749SSergey Zigachev 195*b843c749SSergey Zigachev while (i < n) { 196*b843c749SSergey Zigachev shift = va_arg(ap, uint32_t); 197*b843c749SSergey Zigachev mask = va_arg(ap, uint32_t); 198*b843c749SSergey Zigachev field_value = va_arg(ap, uint32_t *); 199*b843c749SSergey Zigachev 200*b843c749SSergey Zigachev *field_value = get_reg_field_value_ex(reg_val, mask, shift); 201*b843c749SSergey Zigachev i++; 202*b843c749SSergey Zigachev } 203*b843c749SSergey Zigachev 204*b843c749SSergey Zigachev va_end(ap); 205*b843c749SSergey Zigachev 206*b843c749SSergey Zigachev return reg_val; 207*b843c749SSergey Zigachev } 208*b843c749SSergey Zigachev */ 209*b843c749SSergey Zigachev 210*b843c749SSergey Zigachev uint32_t generic_reg_wait(const struct dc_context *ctx, 211*b843c749SSergey Zigachev uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value, 212*b843c749SSergey Zigachev unsigned int delay_between_poll_us, unsigned int time_out_num_tries, 213*b843c749SSergey Zigachev const char *func_name, int line) 214*b843c749SSergey Zigachev { 215*b843c749SSergey Zigachev uint32_t field_value; 216*b843c749SSergey Zigachev uint32_t reg_val; 217*b843c749SSergey Zigachev int i; 218*b843c749SSergey Zigachev 219*b843c749SSergey Zigachev /* something is terribly wrong if time out is > 200ms. (5Hz) */ 220*b843c749SSergey Zigachev ASSERT(delay_between_poll_us * time_out_num_tries <= 200000); 221*b843c749SSergey Zigachev 222*b843c749SSergey Zigachev if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { 223*b843c749SSergey Zigachev /* 35 seconds */ 224*b843c749SSergey Zigachev delay_between_poll_us = 35000; 225*b843c749SSergey Zigachev time_out_num_tries = 1000; 226*b843c749SSergey Zigachev } 227*b843c749SSergey Zigachev 228*b843c749SSergey Zigachev for (i = 0; i <= time_out_num_tries; i++) { 229*b843c749SSergey Zigachev if (i) { 230*b843c749SSergey Zigachev if (delay_between_poll_us >= 1000) 231*b843c749SSergey Zigachev msleep(delay_between_poll_us/1000); 232*b843c749SSergey Zigachev else if (delay_between_poll_us > 0) 233*b843c749SSergey Zigachev udelay(delay_between_poll_us); 234*b843c749SSergey Zigachev } 235*b843c749SSergey Zigachev 236*b843c749SSergey Zigachev reg_val = dm_read_reg(ctx, addr); 237*b843c749SSergey Zigachev 238*b843c749SSergey Zigachev field_value = get_reg_field_value_ex(reg_val, mask, shift); 239*b843c749SSergey Zigachev 240*b843c749SSergey Zigachev if (field_value == condition_value) { 241*b843c749SSergey Zigachev if (i * delay_between_poll_us > 1000) 242*b843c749SSergey Zigachev dm_output_to_console("REG_WAIT taking a while: %dms in %s line:%d\n", 243*b843c749SSergey Zigachev delay_between_poll_us * i / 1000, 244*b843c749SSergey Zigachev func_name, line); 245*b843c749SSergey Zigachev return reg_val; 246*b843c749SSergey Zigachev } 247*b843c749SSergey Zigachev } 248*b843c749SSergey Zigachev 249*b843c749SSergey Zigachev dm_error("REG_WAIT timeout %dus * %d tries - %s line:%d\n", 250*b843c749SSergey Zigachev delay_between_poll_us, time_out_num_tries, 251*b843c749SSergey Zigachev func_name, line); 252*b843c749SSergey Zigachev 253*b843c749SSergey Zigachev if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 254*b843c749SSergey Zigachev BREAK_TO_DEBUGGER(); 255*b843c749SSergey Zigachev 256*b843c749SSergey Zigachev return reg_val; 257*b843c749SSergey Zigachev } 258*b843c749SSergey Zigachev 259*b843c749SSergey Zigachev void generic_write_indirect_reg(const struct dc_context *ctx, 260*b843c749SSergey Zigachev uint32_t addr_index, uint32_t addr_data, 261*b843c749SSergey Zigachev uint32_t index, uint32_t data) 262*b843c749SSergey Zigachev { 263*b843c749SSergey Zigachev dm_write_reg(ctx, addr_index, index); 264*b843c749SSergey Zigachev dm_write_reg(ctx, addr_data, data); 265*b843c749SSergey Zigachev } 266*b843c749SSergey Zigachev 267*b843c749SSergey Zigachev uint32_t generic_read_indirect_reg(const struct dc_context *ctx, 268*b843c749SSergey Zigachev uint32_t addr_index, uint32_t addr_data, 269*b843c749SSergey Zigachev uint32_t index) 270*b843c749SSergey Zigachev { 271*b843c749SSergey Zigachev uint32_t value = 0; 272*b843c749SSergey Zigachev 273*b843c749SSergey Zigachev dm_write_reg(ctx, addr_index, index); 274*b843c749SSergey Zigachev value = dm_read_reg(ctx, addr_data); 275*b843c749SSergey Zigachev 276*b843c749SSergey Zigachev return value; 277*b843c749SSergey Zigachev } 278*b843c749SSergey Zigachev 279*b843c749SSergey Zigachev 280*b843c749SSergey Zigachev uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx, 281*b843c749SSergey Zigachev uint32_t addr_index, uint32_t addr_data, 282*b843c749SSergey Zigachev uint32_t index, uint32_t reg_val, int n, 283*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t field_value1, 284*b843c749SSergey Zigachev ...) 285*b843c749SSergey Zigachev { 286*b843c749SSergey Zigachev uint32_t shift, mask, field_value; 287*b843c749SSergey Zigachev int i = 1; 288*b843c749SSergey Zigachev 289*b843c749SSergey Zigachev va_list ap; 290*b843c749SSergey Zigachev 291*b843c749SSergey Zigachev va_start(ap, field_value1); 292*b843c749SSergey Zigachev 293*b843c749SSergey Zigachev reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1); 294*b843c749SSergey Zigachev 295*b843c749SSergey Zigachev while (i < n) { 296*b843c749SSergey Zigachev shift = va_arg(ap, uint32_t); 297*b843c749SSergey Zigachev mask = va_arg(ap, uint32_t); 298*b843c749SSergey Zigachev field_value = va_arg(ap, uint32_t); 299*b843c749SSergey Zigachev 300*b843c749SSergey Zigachev reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift); 301*b843c749SSergey Zigachev i++; 302*b843c749SSergey Zigachev } 303*b843c749SSergey Zigachev 304*b843c749SSergey Zigachev generic_write_indirect_reg(ctx, addr_index, addr_data, index, reg_val); 305*b843c749SSergey Zigachev va_end(ap); 306*b843c749SSergey Zigachev 307*b843c749SSergey Zigachev return reg_val; 308*b843c749SSergey Zigachev } 309