14562236bSHarry Wentland /*
2bf93b448SAlex Deucher  * Copyright 2017 Advanced Micro Devices, Inc.
3bf93b448SAlex Deucher  *
4bf93b448SAlex Deucher  * Permission is hereby granted, free of charge, to any person obtaining a
5bf93b448SAlex Deucher  * copy of this software and associated documentation files (the "Software"),
6bf93b448SAlex Deucher  * to deal in the Software without restriction, including without limitation
7bf93b448SAlex Deucher  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf93b448SAlex Deucher  * and/or sell copies of the Software, and to permit persons to whom the
9bf93b448SAlex Deucher  * Software is furnished to do so, subject to the following conditions:
10bf93b448SAlex Deucher  *
11bf93b448SAlex Deucher  * The above copyright notice and this permission notice shall be included in
12bf93b448SAlex Deucher  * all copies or substantial portions of the Software.
13bf93b448SAlex Deucher  *
14bf93b448SAlex Deucher  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bf93b448SAlex Deucher  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bf93b448SAlex Deucher  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17bf93b448SAlex Deucher  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18bf93b448SAlex Deucher  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19bf93b448SAlex Deucher  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20bf93b448SAlex Deucher  * OTHER DEALINGS IN THE SOFTWARE.
21bf93b448SAlex Deucher  *
22bf93b448SAlex Deucher  */
23bf93b448SAlex Deucher /*
244562236bSHarry Wentland  * dc_helper.c
254562236bSHarry Wentland  *
264562236bSHarry Wentland  *  Created on: Aug 30, 2016
274562236bSHarry Wentland  *      Author: agrodzov
284562236bSHarry Wentland  */
294562236bSHarry Wentland #include "dm_services.h"
304562236bSHarry Wentland #include <stdarg.h>
314562236bSHarry Wentland 
324562236bSHarry Wentland uint32_t generic_reg_update_ex(const struct dc_context *ctx,
334562236bSHarry Wentland 		uint32_t addr, uint32_t reg_val, int n,
344562236bSHarry Wentland 		uint8_t shift1, uint32_t mask1, uint32_t field_value1,
354562236bSHarry Wentland 		...)
364562236bSHarry Wentland {
374562236bSHarry Wentland 	uint32_t shift, mask, field_value;
384562236bSHarry Wentland 	int i = 1;
394562236bSHarry Wentland 
404562236bSHarry Wentland 	va_list ap;
414562236bSHarry Wentland 	va_start(ap, field_value1);
424562236bSHarry Wentland 
434562236bSHarry Wentland 	reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1);
444562236bSHarry Wentland 
454562236bSHarry Wentland 	while (i < n) {
464562236bSHarry Wentland 		shift = va_arg(ap, uint32_t);
474562236bSHarry Wentland 		mask = va_arg(ap, uint32_t);
484562236bSHarry Wentland 		field_value = va_arg(ap, uint32_t);
494562236bSHarry Wentland 
504562236bSHarry Wentland 		reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift);
514562236bSHarry Wentland 		i++;
524562236bSHarry Wentland 	}
534562236bSHarry Wentland 
544562236bSHarry Wentland 	dm_write_reg(ctx, addr, reg_val);
554562236bSHarry Wentland 	va_end(ap);
564562236bSHarry Wentland 
574562236bSHarry Wentland 	return reg_val;
584562236bSHarry Wentland }
594562236bSHarry Wentland 
604562236bSHarry Wentland uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
614562236bSHarry Wentland 		uint8_t shift, uint32_t mask, uint32_t *field_value)
624562236bSHarry Wentland {
634562236bSHarry Wentland 	uint32_t reg_val = dm_read_reg(ctx, addr);
644562236bSHarry Wentland 	*field_value = get_reg_field_value_ex(reg_val, mask, shift);
654562236bSHarry Wentland 	return reg_val;
664562236bSHarry Wentland }
674562236bSHarry Wentland 
684562236bSHarry Wentland uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
694562236bSHarry Wentland 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
704562236bSHarry Wentland 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2)
714562236bSHarry Wentland {
724562236bSHarry Wentland 	uint32_t reg_val = dm_read_reg(ctx, addr);
734562236bSHarry Wentland 	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
744562236bSHarry Wentland 	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
754562236bSHarry Wentland 	return reg_val;
764562236bSHarry Wentland }
774562236bSHarry Wentland 
784562236bSHarry Wentland uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
794562236bSHarry Wentland 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
804562236bSHarry Wentland 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
814562236bSHarry Wentland 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3)
824562236bSHarry Wentland {
834562236bSHarry Wentland 	uint32_t reg_val = dm_read_reg(ctx, addr);
844562236bSHarry Wentland 	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
854562236bSHarry Wentland 	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
864562236bSHarry Wentland 	*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
874562236bSHarry Wentland 	return reg_val;
884562236bSHarry Wentland }
894562236bSHarry Wentland 
9098d2cc2bSAndrew Wong uint32_t generic_reg_get4(const struct dc_context *ctx, uint32_t addr,
9198d2cc2bSAndrew Wong 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
9298d2cc2bSAndrew Wong 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
9398d2cc2bSAndrew Wong 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
9498d2cc2bSAndrew Wong 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4)
9598d2cc2bSAndrew Wong {
9698d2cc2bSAndrew Wong 	uint32_t reg_val = dm_read_reg(ctx, addr);
9798d2cc2bSAndrew Wong 	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
9898d2cc2bSAndrew Wong 	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
9998d2cc2bSAndrew Wong 	*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
10098d2cc2bSAndrew Wong 	*field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
10198d2cc2bSAndrew Wong 	return reg_val;
10298d2cc2bSAndrew Wong }
10398d2cc2bSAndrew Wong 
1044562236bSHarry Wentland uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
1054562236bSHarry Wentland 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
1064562236bSHarry Wentland 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
1074562236bSHarry Wentland 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
1084562236bSHarry Wentland 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
1094562236bSHarry Wentland 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5)
1104562236bSHarry Wentland {
1114562236bSHarry Wentland 	uint32_t reg_val = dm_read_reg(ctx, addr);
1124562236bSHarry Wentland 	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
1134562236bSHarry Wentland 	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
1144562236bSHarry Wentland 	*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
1154562236bSHarry Wentland 	*field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
1164562236bSHarry Wentland 	*field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
1174562236bSHarry Wentland 	return reg_val;
1184562236bSHarry Wentland }
1194562236bSHarry Wentland 
1200a93dc7fSDmytro Laktyushkin uint32_t generic_reg_get6(const struct dc_context *ctx, uint32_t addr,
1210a93dc7fSDmytro Laktyushkin 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
1220a93dc7fSDmytro Laktyushkin 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
1230a93dc7fSDmytro Laktyushkin 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
1240a93dc7fSDmytro Laktyushkin 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
1250a93dc7fSDmytro Laktyushkin 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
1260a93dc7fSDmytro Laktyushkin 		uint8_t shift6, uint32_t mask6, uint32_t *field_value6)
1270a93dc7fSDmytro Laktyushkin {
1280a93dc7fSDmytro Laktyushkin 	uint32_t reg_val = dm_read_reg(ctx, addr);
1290a93dc7fSDmytro Laktyushkin 	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
1300a93dc7fSDmytro Laktyushkin 	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
1310a93dc7fSDmytro Laktyushkin 	*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
1320a93dc7fSDmytro Laktyushkin 	*field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
1330a93dc7fSDmytro Laktyushkin 	*field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
1340a93dc7fSDmytro Laktyushkin 	*field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
1350a93dc7fSDmytro Laktyushkin 	return reg_val;
1360a93dc7fSDmytro Laktyushkin }
1370a93dc7fSDmytro Laktyushkin 
1380a93dc7fSDmytro Laktyushkin uint32_t generic_reg_get7(const struct dc_context *ctx, uint32_t addr,
1390a93dc7fSDmytro Laktyushkin 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
1400a93dc7fSDmytro Laktyushkin 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
1410a93dc7fSDmytro Laktyushkin 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
1420a93dc7fSDmytro Laktyushkin 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
1430a93dc7fSDmytro Laktyushkin 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
1440a93dc7fSDmytro Laktyushkin 		uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
1450a93dc7fSDmytro Laktyushkin 		uint8_t shift7, uint32_t mask7, uint32_t *field_value7)
1460a93dc7fSDmytro Laktyushkin {
1470a93dc7fSDmytro Laktyushkin 	uint32_t reg_val = dm_read_reg(ctx, addr);
1480a93dc7fSDmytro Laktyushkin 	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
1490a93dc7fSDmytro Laktyushkin 	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
1500a93dc7fSDmytro Laktyushkin 	*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
1510a93dc7fSDmytro Laktyushkin 	*field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
1520a93dc7fSDmytro Laktyushkin 	*field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
1530a93dc7fSDmytro Laktyushkin 	*field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
1540a93dc7fSDmytro Laktyushkin 	*field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7);
1550a93dc7fSDmytro Laktyushkin 	return reg_val;
1560a93dc7fSDmytro Laktyushkin }
1570a93dc7fSDmytro Laktyushkin 
1580a93dc7fSDmytro Laktyushkin uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
1590a93dc7fSDmytro Laktyushkin 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
1600a93dc7fSDmytro Laktyushkin 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
1610a93dc7fSDmytro Laktyushkin 		uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
1620a93dc7fSDmytro Laktyushkin 		uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
1630a93dc7fSDmytro Laktyushkin 		uint8_t shift5, uint32_t mask5, uint32_t *field_value5,
1640a93dc7fSDmytro Laktyushkin 		uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
1650a93dc7fSDmytro Laktyushkin 		uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
1660a93dc7fSDmytro Laktyushkin 		uint8_t shift8, uint32_t mask8, uint32_t *field_value8)
1670a93dc7fSDmytro Laktyushkin {
1680a93dc7fSDmytro Laktyushkin 	uint32_t reg_val = dm_read_reg(ctx, addr);
1690a93dc7fSDmytro Laktyushkin 	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
1700a93dc7fSDmytro Laktyushkin 	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
1710a93dc7fSDmytro Laktyushkin 	*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
1720a93dc7fSDmytro Laktyushkin 	*field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
1730a93dc7fSDmytro Laktyushkin 	*field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
1740a93dc7fSDmytro Laktyushkin 	*field_value6 = get_reg_field_value_ex(reg_val, mask6, shift6);
1750a93dc7fSDmytro Laktyushkin 	*field_value7 = get_reg_field_value_ex(reg_val, mask7, shift7);
1760a93dc7fSDmytro Laktyushkin 	*field_value8 = get_reg_field_value_ex(reg_val, mask8, shift8);
1770a93dc7fSDmytro Laktyushkin 	return reg_val;
1780a93dc7fSDmytro Laktyushkin }
1794562236bSHarry Wentland /* note:  va version of this is pretty bad idea, since there is a output parameter pass by pointer
1804562236bSHarry Wentland  * compiler won't be able to check for size match and is prone to stack corruption type of bugs
1814562236bSHarry Wentland 
1824562236bSHarry Wentland uint32_t generic_reg_get(const struct dc_context *ctx,
1834562236bSHarry Wentland 		uint32_t addr, int n, ...)
1844562236bSHarry Wentland {
1854562236bSHarry Wentland 	uint32_t shift, mask;
1864562236bSHarry Wentland 	uint32_t *field_value;
1874562236bSHarry Wentland 	uint32_t reg_val;
1884562236bSHarry Wentland 	int i = 0;
1894562236bSHarry Wentland 
1904562236bSHarry Wentland 	reg_val = dm_read_reg(ctx, addr);
1914562236bSHarry Wentland 
1924562236bSHarry Wentland 	va_list ap;
1934562236bSHarry Wentland 	va_start(ap, n);
1944562236bSHarry Wentland 
1954562236bSHarry Wentland 	while (i < n) {
1964562236bSHarry Wentland 		shift = va_arg(ap, uint32_t);
1974562236bSHarry Wentland 		mask = va_arg(ap, uint32_t);
1984562236bSHarry Wentland 		field_value = va_arg(ap, uint32_t *);
1994562236bSHarry Wentland 
2004562236bSHarry Wentland 		*field_value = get_reg_field_value_ex(reg_val, mask, shift);
2014562236bSHarry Wentland 		i++;
2024562236bSHarry Wentland 	}
2034562236bSHarry Wentland 
2044562236bSHarry Wentland 	va_end(ap);
2054562236bSHarry Wentland 
2064562236bSHarry Wentland 	return reg_val;
2074562236bSHarry Wentland }
2084562236bSHarry Wentland */
2094562236bSHarry Wentland 
2104562236bSHarry Wentland uint32_t generic_reg_wait(const struct dc_context *ctx,
2114562236bSHarry Wentland 	uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value,
2124562236bSHarry Wentland 	unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
213daf6b57dSDmytro Laktyushkin 	const char *func_name, int line)
2144562236bSHarry Wentland {
2154562236bSHarry Wentland 	uint32_t field_value;
2164562236bSHarry Wentland 	uint32_t reg_val;
2174562236bSHarry Wentland 	int i;
2184562236bSHarry Wentland 
2198a5d8245STony Cheng 	/* something is terribly wrong if time out is > 200ms. (5Hz) */
2208a5d8245STony Cheng 	ASSERT(delay_between_poll_us * time_out_num_tries <= 200000);
2218a5d8245STony Cheng 
222f0558542SDmytro Laktyushkin 	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
223f0558542SDmytro Laktyushkin 		/* 35 seconds */
224f0558542SDmytro Laktyushkin 		delay_between_poll_us = 35000;
225f0558542SDmytro Laktyushkin 		time_out_num_tries = 1000;
226f0558542SDmytro Laktyushkin 	}
22711589813SDmytro Laktyushkin 
2284562236bSHarry Wentland 	for (i = 0; i <= time_out_num_tries; i++) {
2294562236bSHarry Wentland 		if (i) {
230755d3bcfSEric Yang 			if (delay_between_poll_us >= 1000)
2314562236bSHarry Wentland 				msleep(delay_between_poll_us/1000);
232755d3bcfSEric Yang 			else if (delay_between_poll_us > 0)
233755d3bcfSEric Yang 				udelay(delay_between_poll_us);
2344562236bSHarry Wentland 		}
2354562236bSHarry Wentland 
2364562236bSHarry Wentland 		reg_val = dm_read_reg(ctx, addr);
2374562236bSHarry Wentland 
2384562236bSHarry Wentland 		field_value = get_reg_field_value_ex(reg_val, mask, shift);
2394562236bSHarry Wentland 
24042cf181bSDmytro Laktyushkin 		if (field_value == condition_value) {
24142cf181bSDmytro Laktyushkin 			if (i * delay_between_poll_us > 1000)
24242cf181bSDmytro Laktyushkin 				dm_output_to_console("REG_WAIT taking a while: %dms in %s line:%d\n",
24342cf181bSDmytro Laktyushkin 						delay_between_poll_us * i / 1000,
24442cf181bSDmytro Laktyushkin 						func_name, line);
2454562236bSHarry Wentland 			return reg_val;
2464562236bSHarry Wentland 		}
24742cf181bSDmytro Laktyushkin 	}
2484562236bSHarry Wentland 
249daf6b57dSDmytro Laktyushkin 	dm_error("REG_WAIT timeout %dus * %d tries - %s line:%d\n",
2508a5d8245STony Cheng 			delay_between_poll_us, time_out_num_tries,
2518a5d8245STony Cheng 			func_name, line);
252f0558542SDmytro Laktyushkin 
253f0558542SDmytro Laktyushkin 	if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
25411589813SDmytro Laktyushkin 		BREAK_TO_DEBUGGER();
25511589813SDmytro Laktyushkin 
2564562236bSHarry Wentland 	return reg_val;
2574562236bSHarry Wentland }
258