1 /* 2 * dc_helper.c 3 * 4 * Created on: Aug 30, 2016 5 * Author: agrodzov 6 */ 7 #include "dm_services.h" 8 #include <stdarg.h> 9 10 uint32_t generic_reg_update_ex(const struct dc_context *ctx, 11 uint32_t addr, uint32_t reg_val, int n, 12 uint8_t shift1, uint32_t mask1, uint32_t field_value1, 13 ...) 14 { 15 uint32_t shift, mask, field_value; 16 int i = 1; 17 18 va_list ap; 19 va_start(ap, field_value1); 20 21 reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1); 22 23 while (i < n) { 24 shift = va_arg(ap, uint32_t); 25 mask = va_arg(ap, uint32_t); 26 field_value = va_arg(ap, uint32_t); 27 28 reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift); 29 i++; 30 } 31 32 dm_write_reg(ctx, addr, reg_val); 33 va_end(ap); 34 35 return reg_val; 36 } 37 38 uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr, 39 uint8_t shift, uint32_t mask, uint32_t *field_value) 40 { 41 uint32_t reg_val = dm_read_reg(ctx, addr); 42 *field_value = get_reg_field_value_ex(reg_val, mask, shift); 43 return reg_val; 44 } 45 46 uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr, 47 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 48 uint8_t shift2, uint32_t mask2, uint32_t *field_value2) 49 { 50 uint32_t reg_val = dm_read_reg(ctx, addr); 51 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 52 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 53 return reg_val; 54 } 55 56 uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr, 57 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 58 uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 59 uint8_t shift3, uint32_t mask3, uint32_t *field_value3) 60 { 61 uint32_t reg_val = dm_read_reg(ctx, addr); 62 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 63 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 64 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 65 return reg_val; 66 } 67 68 uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr, 69 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 70 uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 71 uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 72 uint8_t shift4, uint32_t mask4, uint32_t *field_value4) 73 { 74 uint32_t reg_val = dm_read_reg(ctx, addr); 75 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 76 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 77 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 78 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); 79 return reg_val; 80 } 81 82 uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr, 83 uint8_t shift1, uint32_t mask1, uint32_t *field_value1, 84 uint8_t shift2, uint32_t mask2, uint32_t *field_value2, 85 uint8_t shift3, uint32_t mask3, uint32_t *field_value3, 86 uint8_t shift4, uint32_t mask4, uint32_t *field_value4, 87 uint8_t shift5, uint32_t mask5, uint32_t *field_value5) 88 { 89 uint32_t reg_val = dm_read_reg(ctx, addr); 90 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1); 91 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2); 92 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3); 93 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4); 94 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5); 95 return reg_val; 96 } 97 98 /* note: va version of this is pretty bad idea, since there is a output parameter pass by pointer 99 * compiler won't be able to check for size match and is prone to stack corruption type of bugs 100 101 uint32_t generic_reg_get(const struct dc_context *ctx, 102 uint32_t addr, int n, ...) 103 { 104 uint32_t shift, mask; 105 uint32_t *field_value; 106 uint32_t reg_val; 107 int i = 0; 108 109 reg_val = dm_read_reg(ctx, addr); 110 111 va_list ap; 112 va_start(ap, n); 113 114 while (i < n) { 115 shift = va_arg(ap, uint32_t); 116 mask = va_arg(ap, uint32_t); 117 field_value = va_arg(ap, uint32_t *); 118 119 *field_value = get_reg_field_value_ex(reg_val, mask, shift); 120 i++; 121 } 122 123 va_end(ap); 124 125 return reg_val; 126 } 127 */ 128 129 uint32_t generic_reg_wait(const struct dc_context *ctx, 130 uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value, 131 unsigned int delay_between_poll_us, unsigned int time_out_num_tries, 132 const char *func_name, int line) 133 { 134 uint32_t field_value; 135 uint32_t reg_val; 136 int i; 137 138 /* something is terribly wrong if time out is > 200ms. (5Hz) */ 139 ASSERT(delay_between_poll_us * time_out_num_tries <= 200000); 140 141 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { 142 /* 35 seconds */ 143 delay_between_poll_us = 35000; 144 time_out_num_tries = 1000; 145 } 146 147 for (i = 0; i <= time_out_num_tries; i++) { 148 if (i) { 149 if (delay_between_poll_us >= 1000) 150 msleep(delay_between_poll_us/1000); 151 else if (delay_between_poll_us > 0) 152 udelay(delay_between_poll_us); 153 } 154 155 reg_val = dm_read_reg(ctx, addr); 156 157 field_value = get_reg_field_value_ex(reg_val, mask, shift); 158 159 if (field_value == condition_value) 160 return reg_val; 161 } 162 163 dm_error("REG_WAIT timeout %dus * %d tries - %s line:%d\n", 164 delay_between_poll_us, time_out_num_tries, 165 func_name, line); 166 167 if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 168 BREAK_TO_DEBUGGER(); 169 170 return reg_val; 171 } 172