From f2ce282b7eb86bc3e739fb254fd7e0be1fba0cdd Mon Sep 17 00:00:00 2001 From: Austin Tajiri Date: Mon, 13 Mar 2023 00:35:34 +0000 Subject: [PATCH] gpu: nvgpu: add HALs for ECC interrupt handling registers Add HALs for reading ECC status, retrieving ECC error info, and clearing ECC errors. Use these HALs in place of direct register access in GV11B/GA10B ECC interrupt handlers. Jira NVGPU-9217 Change-Id: I792f05ede5576b958b678bc5eb8f2b8dc5e7c4d7 Signed-off-by: Austin Tajiri Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2869898 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-misra Reviewed-by: svc-mobile-cert Reviewed-by: Tejal Kudav Reviewed-by: Seema Khowala GVS: Gerrit_Virtual_Submit --- .../hal/fb/intr/fb_intr_ecc_ga10b_fusa.c | 26 ++- .../gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b.h | 20 ++- .../hal/fb/intr/fb_intr_ecc_gv11b_fusa.c | 150 ++++++++++++------ drivers/gpu/nvgpu/hal/init/hal_ga100.c | 9 ++ drivers/gpu/nvgpu/hal/init/hal_ga10b.c | 9 ++ drivers/gpu/nvgpu/hal/init/hal_gv11b.c | 9 ++ drivers/gpu/nvgpu/hal/init/hal_tu104.c | 9 ++ drivers/gpu/nvgpu/include/nvgpu/gops/fb.h | 21 ++- 8 files changed, 188 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_ga10b_fusa.c b/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_ga10b_fusa.c index 8e6b37029..80348a54c 100644 --- a/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_ga10b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_ga10b_fusa.c @@ -1,7 +1,7 @@ /* * GA10B FB INTR ECC * - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2023, 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"), @@ -33,7 +33,7 @@ void ga10b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status) { - u32 corrected_cnt, uncorrected_cnt; + u32 ecc_addr, corrected_cnt, uncorrected_cnt; u32 unique_corrected_delta, unique_uncorrected_delta; u32 unique_corrected_overflow, unique_uncorrected_overflow; @@ -41,10 +41,8 @@ void ga10b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status) * The unique counters tracks the instances of ecc (un)corrected errors * where the present, previous error addresses are different. */ - corrected_cnt = nvgpu_readl(g, - fb_mmu_l2tlb_ecc_corrected_err_count_r()); - uncorrected_cnt = nvgpu_readl(g, - fb_mmu_l2tlb_ecc_uncorrected_err_count_r()); + g->ops.fb.intr.get_l2tlb_ecc_info(g, &ecc_addr, &corrected_cnt, + &uncorrected_cnt); unique_corrected_delta = fb_mmu_l2tlb_ecc_corrected_err_count_unique_v(corrected_cnt); @@ -87,7 +85,7 @@ void ga10b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status) void ga10b_fb_intr_handle_ecc_hubtlb(struct gk20a *g, u32 ecc_status) { - u32 corrected_cnt, uncorrected_cnt; + u32 ecc_addr, corrected_cnt, uncorrected_cnt; u32 unique_corrected_delta, unique_uncorrected_delta; u32 unique_corrected_overflow, unique_uncorrected_overflow; @@ -95,10 +93,8 @@ void ga10b_fb_intr_handle_ecc_hubtlb(struct gk20a *g, u32 ecc_status) * The unique counters tracks the instances of ecc (un)corrected errors * where the present, previous error addresses are different. */ - corrected_cnt = nvgpu_readl(g, - fb_mmu_hubtlb_ecc_corrected_err_count_r()); - uncorrected_cnt = nvgpu_readl(g, - fb_mmu_hubtlb_ecc_uncorrected_err_count_r()); + g->ops.fb.intr.get_hubtlb_ecc_info(g, &ecc_addr, &corrected_cnt, + &uncorrected_cnt); unique_corrected_delta = fb_mmu_hubtlb_ecc_corrected_err_count_unique_v(corrected_cnt); @@ -141,7 +137,7 @@ void ga10b_fb_intr_handle_ecc_hubtlb(struct gk20a *g, u32 ecc_status) void ga10b_fb_intr_handle_ecc_fillunit(struct gk20a *g, u32 ecc_status) { - u32 corrected_cnt, uncorrected_cnt; + u32 ecc_addr, corrected_cnt, uncorrected_cnt; u32 unique_corrected_delta, unique_uncorrected_delta; u32 unique_corrected_overflow, unique_uncorrected_overflow; @@ -149,10 +145,8 @@ void ga10b_fb_intr_handle_ecc_fillunit(struct gk20a *g, u32 ecc_status) * The unique counters tracks the instances of ecc (un)corrected errors * where the present, previous error addresses are different. */ - corrected_cnt = nvgpu_readl(g, - fb_mmu_fillunit_ecc_corrected_err_count_r()); - uncorrected_cnt = nvgpu_readl(g, - fb_mmu_fillunit_ecc_uncorrected_err_count_r()); + g->ops.fb.intr.get_fillunit_ecc_info(g, &ecc_addr, &corrected_cnt, + &uncorrected_cnt); unique_corrected_delta = fb_mmu_fillunit_ecc_corrected_err_count_unique_v(corrected_cnt); diff --git a/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b.h b/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b.h index 9ade90178..a8c1eb3d6 100644 --- a/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b.h +++ b/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b.h @@ -1,7 +1,7 @@ /* * GV11B FB INTR ECC * - * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2023, 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"), @@ -32,6 +32,24 @@ struct gk20a; struct nvgpu_hw_err_inject_info; struct nvgpu_hw_err_inject_info_desc; +u32 gv11b_fb_intr_read_l2tlb_ecc_status(struct gk20a *g); +u32 gv11b_fb_intr_read_hubtlb_ecc_status(struct gk20a *g); +u32 gv11b_fb_intr_read_fillunit_ecc_status(struct gk20a *g); + +void gv11b_fb_intr_get_l2tlb_ecc_info(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt); +void gv11b_fb_intr_get_hubtlb_ecc_info(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt); +void gv11b_fb_intr_get_fillunit_ecc_info(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt); + +void gv11b_fb_intr_clear_ecc_l2tlb(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected); +void gv11b_fb_intr_clear_ecc_hubtlb(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected); +void gv11b_fb_intr_clear_ecc_fillunit(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected); + void gv11b_fb_intr_handle_ecc(struct gk20a *g); void gv11b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status); void gv11b_fb_intr_handle_ecc_fillunit(struct gk20a *g, u32 ecc_status); diff --git a/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b_fusa.c b/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b_fusa.c index eb54fad71..33c3cbd5f 100644 --- a/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fb/intr/fb_intr_ecc_gv11b_fusa.c @@ -1,7 +1,7 @@ /* * GV11B ECC INTR * - * Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2023, 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"), @@ -31,6 +31,90 @@ #include +u32 gv11b_fb_intr_read_l2tlb_ecc_status(struct gk20a *g) +{ + return nvgpu_readl(g, fb_mmu_l2tlb_ecc_status_r()); +} + +u32 gv11b_fb_intr_read_hubtlb_ecc_status(struct gk20a *g) +{ + return nvgpu_readl(g, fb_mmu_hubtlb_ecc_status_r()); +} + +u32 gv11b_fb_intr_read_fillunit_ecc_status(struct gk20a *g) +{ + return nvgpu_readl(g, fb_mmu_fillunit_ecc_status_r()); +} + +void gv11b_fb_intr_get_l2tlb_ecc_info(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt) +{ + *ecc_addr = nvgpu_readl(g, fb_mmu_l2tlb_ecc_address_r()); + *corrected_cnt = nvgpu_readl(g, + fb_mmu_l2tlb_ecc_corrected_err_count_r()); + *uncorrected_cnt = nvgpu_readl(g, + fb_mmu_l2tlb_ecc_uncorrected_err_count_r()); +} + +void gv11b_fb_intr_get_hubtlb_ecc_info(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt) +{ + *ecc_addr = nvgpu_readl(g, fb_mmu_hubtlb_ecc_address_r()); + *corrected_cnt = nvgpu_readl(g, + fb_mmu_hubtlb_ecc_corrected_err_count_r()); + *uncorrected_cnt = nvgpu_readl(g, + fb_mmu_hubtlb_ecc_uncorrected_err_count_r()); +} + +void gv11b_fb_intr_get_fillunit_ecc_info(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt) +{ + *ecc_addr = nvgpu_readl(g, fb_mmu_fillunit_ecc_address_r()); + *corrected_cnt = nvgpu_readl(g, + fb_mmu_fillunit_ecc_corrected_err_count_r()); + *uncorrected_cnt = nvgpu_readl(g, + fb_mmu_fillunit_ecc_uncorrected_err_count_r()); +} + +void gv11b_fb_intr_clear_ecc_l2tlb(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected) +{ + if (clear_corrected) { + nvgpu_writel(g, fb_mmu_l2tlb_ecc_corrected_err_count_r(), 0); + } + if (clear_uncorrected) { + nvgpu_writel(g, fb_mmu_l2tlb_ecc_uncorrected_err_count_r(), 0); + } + nvgpu_writel(g, fb_mmu_l2tlb_ecc_status_r(), + fb_mmu_l2tlb_ecc_status_reset_clear_f()); +} + +void gv11b_fb_intr_clear_ecc_hubtlb(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected) +{ + if (clear_corrected) { + nvgpu_writel(g, fb_mmu_hubtlb_ecc_corrected_err_count_r(), 0); + } + if (clear_uncorrected) { + nvgpu_writel(g, fb_mmu_hubtlb_ecc_uncorrected_err_count_r(), 0); + } + nvgpu_writel(g, fb_mmu_hubtlb_ecc_status_r(), + fb_mmu_hubtlb_ecc_status_reset_clear_f()); +} + +void gv11b_fb_intr_clear_ecc_fillunit(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected) +{ + if (clear_corrected) { + nvgpu_writel(g, fb_mmu_fillunit_ecc_corrected_err_count_r(), 0); + } + if (clear_uncorrected) { + nvgpu_writel(g, fb_mmu_fillunit_ecc_uncorrected_err_count_r(), 0); + } + nvgpu_writel(g, fb_mmu_fillunit_ecc_status_r(), + fb_mmu_fillunit_ecc_status_reset_clear_f()); +} + static void gv11b_fb_intr_handle_ecc_l2tlb_errs(struct gk20a *g, u32 ecc_status, u32 ecc_addr) { @@ -62,11 +146,8 @@ void gv11b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status) u32 corrected_delta, uncorrected_delta; u32 corrected_overflow, uncorrected_overflow; - ecc_addr = nvgpu_readl(g, fb_mmu_l2tlb_ecc_address_r()); - corrected_cnt = nvgpu_readl(g, - fb_mmu_l2tlb_ecc_corrected_err_count_r()); - uncorrected_cnt = nvgpu_readl(g, - fb_mmu_l2tlb_ecc_uncorrected_err_count_r()); + g->ops.fb.intr.get_l2tlb_ecc_info(g, &ecc_addr, &corrected_cnt, + &uncorrected_cnt); corrected_delta = fb_mmu_l2tlb_ecc_corrected_err_count_total_v( corrected_cnt); @@ -79,15 +160,9 @@ void gv11b_fb_intr_handle_ecc_l2tlb(struct gk20a *g, u32 ecc_status) fb_mmu_l2tlb_ecc_status_uncorrected_err_total_counter_overflow_m(); /* clear the interrupt */ - if ((corrected_delta > 0U) || (corrected_overflow != 0U)) { - nvgpu_writel(g, fb_mmu_l2tlb_ecc_corrected_err_count_r(), 0); - } - if ((uncorrected_delta > 0U) || (uncorrected_overflow != 0U)) { - nvgpu_writel(g, fb_mmu_l2tlb_ecc_uncorrected_err_count_r(), 0); - } - - nvgpu_writel(g, fb_mmu_l2tlb_ecc_status_r(), - fb_mmu_l2tlb_ecc_status_reset_clear_f()); + g->ops.fb.intr.clear_ecc_l2tlb(g, + ((corrected_delta > 0U) || (corrected_overflow != 0U)), + ((uncorrected_delta > 0U) || (uncorrected_overflow != 0U))); /* Handle overflow */ if (corrected_overflow != 0U) { @@ -152,11 +227,8 @@ void gv11b_fb_intr_handle_ecc_hubtlb(struct gk20a *g, u32 ecc_status) u32 corrected_delta, uncorrected_delta; u32 corrected_overflow, uncorrected_overflow; - ecc_addr = nvgpu_readl(g, fb_mmu_hubtlb_ecc_address_r()); - corrected_cnt = nvgpu_readl(g, - fb_mmu_hubtlb_ecc_corrected_err_count_r()); - uncorrected_cnt = nvgpu_readl(g, - fb_mmu_hubtlb_ecc_uncorrected_err_count_r()); + g->ops.fb.intr.get_hubtlb_ecc_info(g, &ecc_addr, &corrected_cnt, + &uncorrected_cnt); corrected_delta = fb_mmu_hubtlb_ecc_corrected_err_count_total_v( corrected_cnt); @@ -169,15 +241,9 @@ void gv11b_fb_intr_handle_ecc_hubtlb(struct gk20a *g, u32 ecc_status) fb_mmu_hubtlb_ecc_status_uncorrected_err_total_counter_overflow_m(); /* clear the interrupt */ - if ((corrected_delta > 0U) || (corrected_overflow != 0U)) { - nvgpu_writel(g, fb_mmu_hubtlb_ecc_corrected_err_count_r(), 0); - } - if ((uncorrected_delta > 0U) || (uncorrected_overflow != 0U)) { - nvgpu_writel(g, fb_mmu_hubtlb_ecc_uncorrected_err_count_r(), 0); - } - - nvgpu_writel(g, fb_mmu_hubtlb_ecc_status_r(), - fb_mmu_hubtlb_ecc_status_reset_clear_f()); + g->ops.fb.intr.clear_ecc_hubtlb(g, + ((corrected_delta > 0U) || (corrected_overflow != 0U)), + ((uncorrected_delta > 0U) || (uncorrected_overflow != 0U))); /* Handle overflow */ if (corrected_overflow != 0U) { @@ -261,11 +327,8 @@ void gv11b_fb_intr_handle_ecc_fillunit(struct gk20a *g, u32 ecc_status) u32 corrected_delta, uncorrected_delta; u32 corrected_overflow, uncorrected_overflow; - ecc_addr = nvgpu_readl(g, fb_mmu_fillunit_ecc_address_r()); - corrected_cnt = nvgpu_readl(g, - fb_mmu_fillunit_ecc_corrected_err_count_r()); - uncorrected_cnt = nvgpu_readl(g, - fb_mmu_fillunit_ecc_uncorrected_err_count_r()); + g->ops.fb.intr.get_fillunit_ecc_info(g, &ecc_addr, &corrected_cnt, + &uncorrected_cnt); corrected_delta = fb_mmu_fillunit_ecc_corrected_err_count_total_v( corrected_cnt); @@ -278,16 +341,9 @@ void gv11b_fb_intr_handle_ecc_fillunit(struct gk20a *g, u32 ecc_status) fb_mmu_fillunit_ecc_status_uncorrected_err_total_counter_overflow_m(); /* clear the interrupt */ - if ((corrected_delta > 0U) || (corrected_overflow != 0U)) { - nvgpu_writel(g, fb_mmu_fillunit_ecc_corrected_err_count_r(), 0); - } - if ((uncorrected_delta > 0U) || (uncorrected_overflow != 0U)) { - nvgpu_writel(g, - fb_mmu_fillunit_ecc_uncorrected_err_count_r(), 0); - } - - nvgpu_writel(g, fb_mmu_fillunit_ecc_status_r(), - fb_mmu_fillunit_ecc_status_reset_clear_f()); + g->ops.fb.intr.clear_ecc_fillunit(g, + ((corrected_delta > 0U) || (corrected_overflow != 0U)), + ((uncorrected_delta > 0U) || (uncorrected_overflow != 0U))); /* Handle overflow */ if (corrected_overflow != 0U) { @@ -330,17 +386,17 @@ void gv11b_fb_intr_handle_ecc(struct gk20a *g) nvgpu_info(g, "ecc uncorrected error notify"); - status = nvgpu_readl(g, fb_mmu_l2tlb_ecc_status_r()); + status = g->ops.fb.intr.read_l2tlb_ecc_status(g); if (status != 0U) { g->ops.fb.intr.handle_ecc_l2tlb(g, status); } - status = nvgpu_readl(g, fb_mmu_hubtlb_ecc_status_r()); + status = g->ops.fb.intr.read_hubtlb_ecc_status(g); if (status != 0U) { g->ops.fb.intr.handle_ecc_hubtlb(g, status); } - status = nvgpu_readl(g, fb_mmu_fillunit_ecc_status_r()); + status = g->ops.fb.intr.read_fillunit_ecc_status(g); if (status != 0U) { g->ops.fb.intr.handle_ecc_fillunit(g, status); } diff --git a/drivers/gpu/nvgpu/hal/init/hal_ga100.c b/drivers/gpu/nvgpu/hal/init/hal_ga100.c index 5b9d906eb..08d1a7050 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_ga100.c +++ b/drivers/gpu/nvgpu/hal/init/hal_ga100.c @@ -897,6 +897,15 @@ static const struct gops_fb_intr ga100_ops_fb_intr = { .handle_ecc_l2tlb = ga10b_fb_intr_handle_ecc_l2tlb, .handle_ecc_hubtlb = ga10b_fb_intr_handle_ecc_hubtlb, .handle_ecc_fillunit = ga10b_fb_intr_handle_ecc_fillunit, + .read_l2tlb_ecc_status = gv11b_fb_intr_read_l2tlb_ecc_status, + .read_hubtlb_ecc_status = gv11b_fb_intr_read_hubtlb_ecc_status, + .read_fillunit_ecc_status = gv11b_fb_intr_read_fillunit_ecc_status, + .get_l2tlb_ecc_info = gv11b_fb_intr_get_l2tlb_ecc_info, + .get_hubtlb_ecc_info = gv11b_fb_intr_get_hubtlb_ecc_info, + .get_fillunit_ecc_info = gv11b_fb_intr_get_fillunit_ecc_info, + .clear_ecc_l2tlb = gv11b_fb_intr_clear_ecc_l2tlb, + .clear_ecc_hubtlb = gv11b_fb_intr_clear_ecc_hubtlb, + .clear_ecc_fillunit = gv11b_fb_intr_clear_ecc_fillunit, }; static const struct gops_fb ga100_ops_fb = { diff --git a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c index 1ad164174..aba4cb9a3 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c @@ -905,6 +905,15 @@ static const struct gops_fb_intr ga10b_ops_fb_intr = { .handle_ecc_l2tlb = ga10b_fb_intr_handle_ecc_l2tlb, .handle_ecc_hubtlb = ga10b_fb_intr_handle_ecc_hubtlb, .handle_ecc_fillunit = ga10b_fb_intr_handle_ecc_fillunit, + .read_l2tlb_ecc_status = gv11b_fb_intr_read_l2tlb_ecc_status, + .read_hubtlb_ecc_status = gv11b_fb_intr_read_hubtlb_ecc_status, + .read_fillunit_ecc_status = gv11b_fb_intr_read_fillunit_ecc_status, + .get_l2tlb_ecc_info = gv11b_fb_intr_get_l2tlb_ecc_info, + .get_hubtlb_ecc_info = gv11b_fb_intr_get_hubtlb_ecc_info, + .get_fillunit_ecc_info = gv11b_fb_intr_get_fillunit_ecc_info, + .clear_ecc_l2tlb = gv11b_fb_intr_clear_ecc_l2tlb, + .clear_ecc_hubtlb = gv11b_fb_intr_clear_ecc_hubtlb, + .clear_ecc_fillunit = gv11b_fb_intr_clear_ecc_fillunit, }; #ifdef CONFIG_NVGPU_HAL_NON_FUSA diff --git a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c index de46064ed..f412c5c55 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c @@ -764,6 +764,15 @@ static const struct gops_fb_intr gv11b_ops_fb_intr = { .handle_ecc_l2tlb = gv11b_fb_intr_handle_ecc_l2tlb, .handle_ecc_hubtlb = gv11b_fb_intr_handle_ecc_hubtlb, .handle_ecc_fillunit = gv11b_fb_intr_handle_ecc_fillunit, + .read_l2tlb_ecc_status = gv11b_fb_intr_read_l2tlb_ecc_status, + .read_hubtlb_ecc_status = gv11b_fb_intr_read_hubtlb_ecc_status, + .read_fillunit_ecc_status = gv11b_fb_intr_read_fillunit_ecc_status, + .get_l2tlb_ecc_info = gv11b_fb_intr_get_l2tlb_ecc_info, + .get_hubtlb_ecc_info = gv11b_fb_intr_get_hubtlb_ecc_info, + .get_fillunit_ecc_info = gv11b_fb_intr_get_fillunit_ecc_info, + .clear_ecc_l2tlb = gv11b_fb_intr_clear_ecc_l2tlb, + .clear_ecc_hubtlb = gv11b_fb_intr_clear_ecc_hubtlb, + .clear_ecc_fillunit = gv11b_fb_intr_clear_ecc_fillunit, }; static const struct gops_fb gv11b_ops_fb = { diff --git a/drivers/gpu/nvgpu/hal/init/hal_tu104.c b/drivers/gpu/nvgpu/hal/init/hal_tu104.c index 80e1c5df0..857fe37b6 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_tu104.c +++ b/drivers/gpu/nvgpu/hal/init/hal_tu104.c @@ -808,6 +808,15 @@ static const struct gops_fb_intr tu104_ops_fb_intr = { .handle_ecc_l2tlb = gv11b_fb_intr_handle_ecc_l2tlb, .handle_ecc_hubtlb = gv11b_fb_intr_handle_ecc_hubtlb, .handle_ecc_fillunit = gv11b_fb_intr_handle_ecc_fillunit, + .read_l2tlb_ecc_status = gv11b_fb_intr_read_l2tlb_ecc_status, + .read_hubtlb_ecc_status = gv11b_fb_intr_read_hubtlb_ecc_status, + .read_fillunit_ecc_status = gv11b_fb_intr_read_fillunit_ecc_status, + .get_l2tlb_ecc_info = gv11b_fb_intr_get_l2tlb_ecc_info, + .get_hubtlb_ecc_info = gv11b_fb_intr_get_hubtlb_ecc_info, + .get_fillunit_ecc_info = gv11b_fb_intr_get_fillunit_ecc_info, + .clear_ecc_l2tlb = gv11b_fb_intr_clear_ecc_l2tlb, + .clear_ecc_hubtlb = gv11b_fb_intr_clear_ecc_hubtlb, + .clear_ecc_fillunit = gv11b_fb_intr_clear_ecc_fillunit, }; static const struct gops_fb tu104_ops_fb = { diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/fb.h b/drivers/gpu/nvgpu/include/nvgpu/gops/fb.h index aea8dc72d..35a66454c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/fb.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/fb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2023, 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"), @@ -121,6 +121,25 @@ struct gops_fb_intr { */ void (*handle_ecc_fillunit)(struct gk20a *g, u32 status); + /** @cond DOXYGEN_SHOULD_SKIP_THIS */ + u32 (*read_l2tlb_ecc_status)(struct gk20a *g); + u32 (*read_hubtlb_ecc_status)(struct gk20a *g); + u32 (*read_fillunit_ecc_status)(struct gk20a *g); + + void (*get_l2tlb_ecc_info)(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt); + void (*get_hubtlb_ecc_info)(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt); + void (*get_fillunit_ecc_info)(struct gk20a *g, u32 *ecc_addr, + u32 *corrected_cnt, u32 *uncorrected_cnt); + + void (*clear_ecc_l2tlb)(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected); + void (*clear_ecc_hubtlb)(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected); + void (*clear_ecc_fillunit)(struct gk20a *g, + bool clear_corrected, bool clear_uncorrected); + /** @endcond DOXYGEN_SHOULD_SKIP_THIS */ }; struct gops_fb_ecc {