From 227c6f7b7a499dd58e0db6859736cfe586ef0897 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Fri, 10 Aug 2018 14:09:36 -0700 Subject: gpu: nvgpu: Move fuse HAL to common Move implementation of fuse HAL to common/fuse. Also implements new fuse query functions for FBIO, FBP, TPC floorsweeping and security fuses. JIRA NVGPU-957 Change-Id: I55e256a4f1b59d50a721d4942907f70dc57467c4 Signed-off-by: Terje Bergstrom Reviewed-on: https://git-master.nvidia.com/r/1797177 --- drivers/gpu/nvgpu/common/fuse/fuse_gp106.c | 230 +++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 drivers/gpu/nvgpu/common/fuse/fuse_gp106.c (limited to 'drivers/gpu/nvgpu/common/fuse/fuse_gp106.c') diff --git a/drivers/gpu/nvgpu/common/fuse/fuse_gp106.c b/drivers/gpu/nvgpu/common/fuse/fuse_gp106.c new file mode 100644 index 00000000..17951e27 --- /dev/null +++ b/drivers/gpu/nvgpu/common/fuse/fuse_gp106.c @@ -0,0 +1,230 @@ +/* + * GP106 FUSE + * + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "gk20a/gk20a.h" + +#include "fuse_gp106.h" + +#include + +int gp106_fuse_check_priv_security(struct gk20a *g) +{ + __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true); + __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); + + return 0; +} + +u32 gp106_fuse_read_vin_cal_fuse_rev(struct gk20a *g) +{ + return fuse_vin_cal_fuse_rev_data_v( + gk20a_readl(g, fuse_vin_cal_fuse_rev_r())); +} + +u32 gp106_fuse_read_vin_cal_slope_intercept_fuse(struct gk20a *g, + u32 vin_id, u32 *slope, + u32 *intercept) +{ + u32 data = 0; + u32 interceptdata = 0; + u32 slopedata = 0; + u32 gpc0data; + u32 gpc0slopedata; + u32 gpc0interceptdata; + + /* read gpc0 irrespective of vin id */ + gpc0data = gk20a_readl(g, fuse_vin_cal_gpc0_r()); + if (gpc0data == 0xFFFFFFFF) + return -EINVAL; + + switch (vin_id) { + case CTRL_CLK_VIN_ID_GPC0: + break; + + case CTRL_CLK_VIN_ID_GPC1: + data = gk20a_readl(g, fuse_vin_cal_gpc1_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC2: + data = gk20a_readl(g, fuse_vin_cal_gpc2_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC3: + data = gk20a_readl(g, fuse_vin_cal_gpc3_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC4: + data = gk20a_readl(g, fuse_vin_cal_gpc4_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC5: + data = gk20a_readl(g, fuse_vin_cal_gpc5_delta_r()); + break; + + case CTRL_CLK_VIN_ID_SYS: + case CTRL_CLK_VIN_ID_XBAR: + case CTRL_CLK_VIN_ID_LTC: + data = gk20a_readl(g, fuse_vin_cal_shared_delta_r()); + break; + + case CTRL_CLK_VIN_ID_SRAM: + data = gk20a_readl(g, fuse_vin_cal_sram_delta_r()); + break; + + default: + return -EINVAL; + } + if (data == 0xFFFFFFFF) + return -EINVAL; + + gpc0interceptdata = (fuse_vin_cal_gpc0_icpt_int_data_v(gpc0data) << + fuse_vin_cal_gpc0_icpt_frac_data_s()) + + fuse_vin_cal_gpc0_icpt_frac_data_v(gpc0data); + gpc0interceptdata = (gpc0interceptdata * 1000U) >> + fuse_vin_cal_gpc0_icpt_frac_data_s(); + + switch (vin_id) { + case CTRL_CLK_VIN_ID_GPC0: + break; + + case CTRL_CLK_VIN_ID_GPC1: + case CTRL_CLK_VIN_ID_GPC2: + case CTRL_CLK_VIN_ID_GPC3: + case CTRL_CLK_VIN_ID_GPC4: + case CTRL_CLK_VIN_ID_GPC5: + case CTRL_CLK_VIN_ID_SYS: + case CTRL_CLK_VIN_ID_XBAR: + case CTRL_CLK_VIN_ID_LTC: + interceptdata = (fuse_vin_cal_gpc1_delta_icpt_int_data_v(data) << + fuse_vin_cal_gpc1_delta_icpt_frac_data_s()) + + fuse_vin_cal_gpc1_delta_icpt_frac_data_v(data); + interceptdata = (interceptdata * 1000U) >> + fuse_vin_cal_gpc1_delta_icpt_frac_data_s(); + break; + + case CTRL_CLK_VIN_ID_SRAM: + interceptdata = (fuse_vin_cal_sram_delta_icpt_int_data_v(data) << + fuse_vin_cal_sram_delta_icpt_frac_data_s()) + + fuse_vin_cal_sram_delta_icpt_frac_data_v(data); + interceptdata = (interceptdata * 1000U) >> + fuse_vin_cal_sram_delta_icpt_frac_data_s(); + break; + + default: + return -EINVAL; + } + + if (fuse_vin_cal_gpc1_delta_icpt_sign_data_v(data)) + *intercept = gpc0interceptdata - interceptdata; + else + *intercept = gpc0interceptdata + interceptdata; + + /* slope */ + gpc0slopedata = (fuse_vin_cal_gpc0_slope_int_data_v(gpc0data) << + fuse_vin_cal_gpc0_slope_frac_data_s()) + + fuse_vin_cal_gpc0_slope_frac_data_v(gpc0data); + gpc0slopedata = (gpc0slopedata * 1000U) >> + fuse_vin_cal_gpc0_slope_frac_data_s(); + switch (vin_id) { + case CTRL_CLK_VIN_ID_GPC0: + break; + + case CTRL_CLK_VIN_ID_GPC1: + case CTRL_CLK_VIN_ID_GPC2: + case CTRL_CLK_VIN_ID_GPC3: + case CTRL_CLK_VIN_ID_GPC4: + case CTRL_CLK_VIN_ID_GPC5: + case CTRL_CLK_VIN_ID_SYS: + case CTRL_CLK_VIN_ID_XBAR: + case CTRL_CLK_VIN_ID_LTC: + case CTRL_CLK_VIN_ID_SRAM: + slopedata = + (fuse_vin_cal_gpc1_delta_slope_int_data_v(data)) * 1000; + break; + + default: + return -EINVAL; + } + + if (fuse_vin_cal_gpc1_delta_slope_sign_data_v(data)) + *slope = gpc0slopedata - slopedata; + else + *slope = gpc0slopedata + slopedata; + return 0; +} + +u32 gp106_fuse_read_vin_cal_gain_offset_fuse(struct gk20a *g, + u32 vin_id, s8 *gain, + s8 *offset) +{ + u32 data = 0; + + switch (vin_id) { + case CTRL_CLK_VIN_ID_GPC0: + data = gk20a_readl(g, fuse_vin_cal_gpc0_r()); + break; + + case CTRL_CLK_VIN_ID_GPC1: + data = gk20a_readl(g, fuse_vin_cal_gpc1_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC2: + data = gk20a_readl(g, fuse_vin_cal_gpc2_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC3: + data = gk20a_readl(g, fuse_vin_cal_gpc3_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC4: + data = gk20a_readl(g, fuse_vin_cal_gpc4_delta_r()); + break; + + case CTRL_CLK_VIN_ID_GPC5: + data = gk20a_readl(g, fuse_vin_cal_gpc5_delta_r()); + break; + + case CTRL_CLK_VIN_ID_SYS: + case CTRL_CLK_VIN_ID_XBAR: + case CTRL_CLK_VIN_ID_LTC: + data = gk20a_readl(g, fuse_vin_cal_shared_delta_r()); + break; + + case CTRL_CLK_VIN_ID_SRAM: + data = gk20a_readl(g, fuse_vin_cal_sram_delta_r()); + break; + + default: + return -EINVAL; + } + if (data == 0xFFFFFFFF) + return -EINVAL; + *gain = (s8) (data >> 16) & 0x1f; + *offset = (s8) data & 0x7f; + + return 0; +} -- cgit v1.2.2