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 <atajiri@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2869898
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Tejal Kudav <tkudav@nvidia.com>
Reviewed-by: Seema Khowala <seemaj@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Austin Tajiri
2023-03-13 00:35:34 +00:00
committed by mobile promotions
parent a7caa8da79
commit f2ce282b7e
8 changed files with 188 additions and 65 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 <nvgpu/hw/gv11b/hw_fb_gv11b.h>
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);
}

View File

@@ -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 = {

View File

@@ -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

View File

@@ -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 = {

View File

@@ -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 = {

View File

@@ -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 {