From 40397ac0c4aceaab64dc1d52b50e9292e45d61af Mon Sep 17 00:00:00 2001 From: Antony Clince Alex Date: Thu, 27 Jan 2022 02:35:13 +0000 Subject: [PATCH] gpu: nvgpu: update CBC init sequence At present, for each resume cycle the driver sends the "nvgpu_cbc_op_clear" command to L2 cache controller, this causes the contents of the compression bit backing store to be cleared, and results in corrupting the metadata for all the compressible surfaces already allocated. Fix this by updating cbc.init function to be aware of resume state and not clear the compression bit backing store, instead issue "nvgpu_cbc_op_invalide" command, this should leave the backing store in a consistent state across suspend/resume cycles. The updated cbc.init HAL for gv11b is reusable acrosss multiple chips, hence remove unnecessary chip specific cbc.init HALs. Bug 3483688 Change-Id: I2de848a083436bc085ee98e438874214cb61261f Signed-off-by: Antony Clince Alex Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2660075 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/cbc/cbc.c | 9 ++++++++- drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.c | 8 +------- drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.h | 3 +-- drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.c | 10 ++++------ drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.h | 4 ++-- drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.c | 23 ++++++++++++++-------- drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.h | 4 ++-- drivers/gpu/nvgpu/hal/cbc/cbc_tu104.c | 9 +-------- drivers/gpu/nvgpu/hal/cbc/cbc_tu104.h | 3 +-- drivers/gpu/nvgpu/hal/init/hal_ga100.c | 4 ++-- drivers/gpu/nvgpu/hal/init/hal_ga10b.c | 2 +- drivers/gpu/nvgpu/hal/init/hal_tu104.c | 6 +++--- drivers/gpu/nvgpu/include/nvgpu/gops/cbc.h | 4 ++-- 13 files changed, 43 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/nvgpu/common/cbc/cbc.c b/drivers/gpu/nvgpu/common/cbc/cbc.c index 8871edb9f..9a04e09b7 100644 --- a/drivers/gpu/nvgpu/common/cbc/cbc.c +++ b/drivers/gpu/nvgpu/common/cbc/cbc.c @@ -62,9 +62,15 @@ int nvgpu_cbc_init_support(struct gk20a *g) { int err = 0; struct nvgpu_cbc *cbc = g->cbc; + bool is_resume = true; nvgpu_log_fn(g, " "); + /* + * If cbc == NULL, the device is being powered-on for the first + * time and hence nvgpu_cbc_init_support is not called as part of + * suspend/resume cycle, so set is_resume to false. + */ if (cbc == NULL) { cbc = nvgpu_kzalloc(g, sizeof(*cbc)); if (cbc == NULL) { @@ -81,10 +87,11 @@ int nvgpu_cbc_init_support(struct gk20a *g) return err; } } + is_resume = false; } if (g->ops.cbc.init != NULL) { - g->ops.cbc.init(g, g->cbc); + g->ops.cbc.init(g, g->cbc, is_resume); } return err; diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.c b/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.c index 09ad0737b..0604bc2b5 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.c +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.c @@ -1,7 +1,7 @@ /* * GA10B CBC * - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2022, 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"), @@ -168,9 +168,3 @@ int ga10b_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc) return 0; } - -void ga10b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc) -{ - g->ops.fb.cbc_configure(g, cbc); - g->ops.cbc.ctrl(g, nvgpu_cbc_op_clear, 0U, cbc->max_comptag_lines - 1U); -} diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.h b/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.h index 42943e519..a55ec6c44 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.h +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_ga10b.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2022, 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,7 +31,6 @@ struct gk20a; struct nvgpu_cbc; int ga10b_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc); -void ga10b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc); #endif #endif /* CBC_GA10B_H */ diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.c b/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.c index 7e6d18f68..8b8391b23 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.c +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.c @@ -230,15 +230,14 @@ u32 gm20b_cbc_fix_config(struct gk20a *g, int base) } -void gm20b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc) +void gm20b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc, bool is_resume) { - u32 max_size = g->max_comptag_mem; - u32 max_comptag_lines = max_size << 3U; - u32 compbit_base_post_divide; u64 compbit_base_post_multiply64; u64 compbit_store_iova; u64 compbit_base_post_divide64; + enum nvgpu_cbc_op cbc_op = is_resume ? nvgpu_cbc_op_invalidate + : nvgpu_cbc_op_clear; #ifdef CONFIG_NVGPU_SIM if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { @@ -282,7 +281,6 @@ void gm20b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc) cbc->compbit_store.base_hw = compbit_base_post_divide; - g->ops.cbc.ctrl(g, nvgpu_cbc_op_invalidate, - 0, max_comptag_lines - 1U); + g->ops.cbc.ctrl(g, cbc_op, 0, cbc->max_comptag_lines - 1U); } diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.h b/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.h index 53e862c3b..4247fc579 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.h +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_gm20b.h @@ -1,7 +1,7 @@ /* * GM20B CBC * - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, 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"), @@ -35,7 +35,7 @@ struct nvgpu_cbc; enum nvgpu_cbc_op; int gm20b_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc); -void gm20b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc); +void gm20b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc, bool is_resume); int gm20b_cbc_ctrl(struct gk20a *g, enum nvgpu_cbc_op op, u32 min, u32 max); u32 gm20b_cbc_fix_config(struct gk20a *g, int base); diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.c b/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.c index 047758999..b2d30488b 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.c +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.c @@ -1,7 +1,7 @@ /* * GV11B CBC * - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, 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"), @@ -29,17 +29,24 @@ #include "cbc_gv11b.h" -void gv11b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc) +void gv11b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc, bool is_resume) { - u32 max_size = g->max_comptag_mem; - /* one tag line covers 64KB */ - u32 max_comptag_lines = max_size << 4; + enum nvgpu_cbc_op cbc_op = is_resume ? nvgpu_cbc_op_invalidate + : nvgpu_cbc_op_clear; nvgpu_log_fn(g, " "); g->ops.fb.cbc_configure(g, cbc); - - g->ops.cbc.ctrl(g, nvgpu_cbc_op_invalidate, - 0, max_comptag_lines - 1U); + /* + * The cbc_op_invalidate command marks all CBC lines as invalid, this + * causes all comptag lines to be fetched from the backing store. + * Whereas, the cbc_op_clear goes a step further and clears the contents + * of the backing store as well, because of this, cbc_op_clear should + * only be called during the first power-on and not on suspend/resume + * cycle, as the backing store might contain valid compression metadata + * for already allocated surfaces and clearing it will corrupt those + * surfaces. + */ + g->ops.cbc.ctrl(g, cbc_op, 0, cbc->max_comptag_lines - 1U); } diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.h b/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.h index 9e645a99a..271c76b5e 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.h +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_gv11b.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, 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"), @@ -28,7 +28,7 @@ struct gk20a; struct nvgpu_cbc; -void gv11b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc); +void gv11b_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc, bool is_resume); #endif #endif diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.c b/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.c index 87d3a8e3d..7a87bfad6 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.c +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.c @@ -1,7 +1,7 @@ /* * TU104 CBC * - * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, 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"), @@ -214,10 +214,3 @@ out: nvgpu_mutex_release(&g->mm.l2_op_lock); return err; } - -void tu104_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc) -{ - g->ops.fb.cbc_configure(g, cbc); - g->ops.cbc.ctrl(g, nvgpu_cbc_op_invalidate, - 0, cbc->max_comptag_lines - 1U); -} diff --git a/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.h b/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.h index d3fa01a2e..55adfdaca 100644 --- a/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.h +++ b/drivers/gpu/nvgpu/hal/cbc/cbc_tu104.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, 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"), @@ -34,7 +34,6 @@ struct nvgpu_cbc; int tu104_cbc_alloc_comptags(struct gk20a *g, struct nvgpu_cbc *cbc); int tu104_cbc_ctrl(struct gk20a *g, enum nvgpu_cbc_op op, u32 min, u32 max); -void tu104_cbc_init(struct gk20a *g, struct nvgpu_cbc *cbc); #endif #endif diff --git a/drivers/gpu/nvgpu/hal/init/hal_ga100.c b/drivers/gpu/nvgpu/hal/init/hal_ga100.c index 3f5068962..89747827d 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_ga100.c +++ b/drivers/gpu/nvgpu/hal/init/hal_ga100.c @@ -108,7 +108,7 @@ #include "hal/priv_ring/priv_ring_ga10b.h" #include "hal/priv_ring/priv_ring_ga100.h" #include "hal/power_features/cg/ga100_gating_reglist.h" -#include "hal/cbc/cbc_gm20b.h" +#include "hal/cbc/cbc_gv11b.h" #include "hal/cbc/cbc_tu104.h" #include "hal/cbc/cbc_ga100.h" #include "hal/therm/therm_gm20b.h" @@ -407,7 +407,7 @@ static const struct gops_ltc ga100_ops_ltc = { static const struct gops_cbc ga100_ops_cbc = { .cbc_init_support = nvgpu_cbc_init_support, .cbc_remove_support = nvgpu_cbc_remove_support, - .init = tu104_cbc_init, + .init = gv11b_cbc_init, .alloc_comptags = ga100_cbc_alloc_comptags, .ctrl = tu104_cbc_ctrl, .fix_config = NULL, diff --git a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c index 83f61258a..18450ac28 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c @@ -376,7 +376,7 @@ static const struct gops_ltc ga10b_ops_ltc = { static const struct gops_cbc ga10b_ops_cbc = { .cbc_init_support = nvgpu_cbc_init_support, .cbc_remove_support = nvgpu_cbc_remove_support, - .init = ga10b_cbc_init, + .init = gv11b_cbc_init, .alloc_comptags = ga10b_cbc_alloc_comptags, .ctrl = tu104_cbc_ctrl, }; diff --git a/drivers/gpu/nvgpu/hal/init/hal_tu104.c b/drivers/gpu/nvgpu/hal/init/hal_tu104.c index 13fd3bc2d..9b1847b51 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_tu104.c +++ b/drivers/gpu/nvgpu/hal/init/hal_tu104.c @@ -1,7 +1,7 @@ /* * TU104 Tegra HAL interface * - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2022, 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"), @@ -51,7 +51,7 @@ #include "hal/priv_ring/priv_ring_gp10b.h" #include "hal/priv_ring/priv_ring_gv11b.h" #include "hal/power_features/cg/tu104_gating_reglist.h" -#include "hal/cbc/cbc_gm20b.h" +#include "hal/cbc/cbc_gv11b.h" #include "hal/cbc/cbc_tu104.h" #include "hal/therm/therm_gm20b.h" #include "hal/therm/therm_tu104.h" @@ -343,7 +343,7 @@ static const struct gops_ltc tu104_ops_ltc = { static const struct gops_cbc tu104_ops_cbc = { .cbc_init_support = nvgpu_cbc_init_support, .cbc_remove_support = nvgpu_cbc_remove_support, - .init = tu104_cbc_init, + .init = gv11b_cbc_init, .alloc_comptags = tu104_cbc_alloc_comptags, .ctrl = tu104_cbc_ctrl, .fix_config = NULL, diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/cbc.h b/drivers/gpu/nvgpu/include/nvgpu/gops/cbc.h index 53793a40a..824e661ad 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/cbc.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/cbc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2022, 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"), @@ -26,7 +26,7 @@ struct gops_cbc { int (*cbc_init_support)(struct gk20a *g); void (*cbc_remove_support)(struct gk20a *g); - void (*init)(struct gk20a *g, struct nvgpu_cbc *cbc); + void (*init)(struct gk20a *g, struct nvgpu_cbc *cbc, bool is_resume); int (*alloc_comptags)(struct gk20a *g, struct nvgpu_cbc *cbc); int (*ctrl)(struct gk20a *g, enum nvgpu_cbc_op op,