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