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 <aalex@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2660075
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Antony Clince Alex
2022-01-27 02:35:13 +00:00
committed by mobile promotions
parent 29a0a146ac
commit 40397ac0c4
13 changed files with 43 additions and 46 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,
};

View File

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

View File

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