gpu: nvgpu: Add CBC clean and invalidate

Bug 1409151

Change-Id: I232af159d402f818cf972498d721c3b57846ce74
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
This commit is contained in:
Arto Merilainen
2014-04-09 15:04:33 +03:00
committed by Dan Willemsen
parent 2c615d68b8
commit 38de7b6475
4 changed files with 44 additions and 15 deletions

View File

@@ -56,12 +56,19 @@ struct cooling_device_gk20a {
struct gk20a *g; struct gk20a *g;
}; };
enum gk20a_cbc_op {
gk20a_cbc_op_clear,
gk20a_cbc_op_clean,
gk20a_cbc_op_invalidate,
};
struct gpu_ops { struct gpu_ops {
struct { struct {
int (*determine_L2_size_bytes)(struct gk20a *gk20a); int (*determine_L2_size_bytes)(struct gk20a *gk20a);
void (*set_max_ways_evict_last)(struct gk20a *g, u32 max_ways); void (*set_max_ways_evict_last)(struct gk20a *g, u32 max_ways);
int (*init_comptags)(struct gk20a *g, struct gr_gk20a *gr); int (*init_comptags)(struct gk20a *g, struct gr_gk20a *gr);
int (*clear_comptags)(struct gk20a *g, u32 min, u32 max); int (*cbc_ctrl)(struct gk20a *g, enum gk20a_cbc_op op,
u32 min, u32 max);
void (*set_zbc_color_entry)(struct gk20a *g, void (*set_zbc_color_entry)(struct gk20a *g,
struct zbc_entry *color_val, struct zbc_entry *color_val,
u32 index); u32 index);

View File

@@ -82,6 +82,14 @@ static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void)
{ {
return 0x0017e8c8; return 0x0017e8c8;
} }
static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void)
{
return 0x1;
}
static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void)
{
return 0x2;
}
static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r)
{ {
return (r >> 2) & 0x1; return (r >> 2) & 0x1;

View File

@@ -108,10 +108,12 @@ static int gk20a_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr)
return 0; return 0;
} }
static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) static int gk20a_ltc_cbc_ctrl(struct gk20a *g, enum gk20a_cbc_op op,
u32 min, u32 max)
{ {
int err = 0;
struct gr_gk20a *gr = &g->gr; struct gr_gk20a *gr = &g->gr;
u32 fbp, slice, ctrl1, val; u32 fbp, slice, ctrl1, val, hw_op = 0;
unsigned long end_jiffies = jiffies + unsigned long end_jiffies = jiffies +
msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
u32 delay = GR_IDLE_CHECK_DEFAULT; u32 delay = GR_IDLE_CHECK_DEFAULT;
@@ -124,13 +126,24 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max)
if (gr->compbit_store.size == 0) if (gr->compbit_store.size == 0)
return 0; return 0;
gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(), mutex_lock(&g->mm.l2_op_lock);
ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min));
gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(), if (op == gk20a_cbc_op_clear) {
ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max)); gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(),
ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min));
gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(),
ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max));
hw_op = ltc_ltcs_ltss_cbc_ctrl1_clear_active_f();
} else if (op == gk20a_cbc_op_clean) {
hw_op = ltc_ltcs_ltss_cbc_ctrl1_clean_active_f();
} else if (op == gk20a_cbc_op_invalidate) {
hw_op = ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f();
} else {
BUG_ON(1);
}
gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(), gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(),
gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | hw_op);
ltc_ltcs_ltss_cbc_ctrl1_clear_active_f());
for (fbp = 0; fbp < gr->num_fbps; fbp++) { for (fbp = 0; fbp < gr->num_fbps; fbp++) {
for (slice = 0; slice < slices_per_fbp; slice++) { for (slice = 0; slice < slices_per_fbp; slice++) {
@@ -143,8 +156,7 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max)
do { do {
val = gk20a_readl(g, ctrl1); val = gk20a_readl(g, ctrl1);
if (ltc_ltcs_ltss_cbc_ctrl1_clear_v(val) != if (!(val & hw_op))
ltc_ltcs_ltss_cbc_ctrl1_clear_active_v())
break; break;
usleep_range(delay, delay * 2); usleep_range(delay, delay * 2);
@@ -157,11 +169,13 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max)
if (!time_before(jiffies, end_jiffies)) { if (!time_before(jiffies, end_jiffies)) {
gk20a_err(dev_from_gk20a(g), gk20a_err(dev_from_gk20a(g),
"comp tag clear timeout\n"); "comp tag clear timeout\n");
return -EBUSY; err = -EBUSY;
goto out;
} }
} }
} }
out:
mutex_unlock(&g->mm.l2_op_lock);
return 0; return 0;
} }
@@ -200,7 +214,7 @@ void gk20a_init_ltc(struct gpu_ops *gops)
gops->ltc.determine_L2_size_bytes = gk20a_determine_L2_size_bytes; gops->ltc.determine_L2_size_bytes = gk20a_determine_L2_size_bytes;
gops->ltc.set_max_ways_evict_last = gk20a_ltc_set_max_ways_evict_last; gops->ltc.set_max_ways_evict_last = gk20a_ltc_set_max_ways_evict_last;
gops->ltc.init_comptags = gk20a_ltc_init_comptags; gops->ltc.init_comptags = gk20a_ltc_init_comptags;
gops->ltc.clear_comptags = gk20a_ltc_clear_comptags; gops->ltc.cbc_ctrl = gk20a_ltc_cbc_ctrl;
gops->ltc.set_zbc_color_entry = gk20a_ltc_set_zbc_color_entry; gops->ltc.set_zbc_color_entry = gk20a_ltc_set_zbc_color_entry;
gops->ltc.set_zbc_depth_entry = gk20a_ltc_set_zbc_depth_entry; gops->ltc.set_zbc_depth_entry = gk20a_ltc_set_zbc_depth_entry;
gops->ltc.clear_zbc_color_entry = gk20a_ltc_clear_zbc_color_entry; gops->ltc.clear_zbc_color_entry = gk20a_ltc_clear_zbc_color_entry;

View File

@@ -1380,7 +1380,7 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
gk20a_get_comptags(d, dmabuf, &comptags); gk20a_get_comptags(d, dmabuf, &comptags);
/* init/clear the ctag buffer */ /* init/clear the ctag buffer */
g->ops.ltc.clear_comptags(g, g->ops.ltc.cbc_ctrl(g, gk20a_cbc_op_clear,
comptags.offset, comptags.offset,
comptags.offset + comptags.lines - 1); comptags.offset + comptags.lines - 1);
} }