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