mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: fix pbdma intr handling
To handle any of the pbdma interrupt, we currently write zero to pbdma_method0 and then clear the interrupt But this is insufficient since we cannot use same intr clear method for all the interrupts Hence, add intr specific routines to handle those interrupts NV_PPBDMA_INTR_0_PBENTRY: - fix the pb_header to have a null opcode - fix the pbdma_method to have a valid nop NV_PPBDMA_INTR_0_METHOD: - fix the pbdma_method to have a valid nop NV_PPBDMA_INTR_0_DEVICE: - fix the pb_header to have a null opcode - go through all pbdma_method0/1/2/3 -- if they contain host s/w methods, replace those methods with a valid NOP Bug 200134238 Change-Id: I10c284a6cdc1441f9d437cea65aae00d3c33a8c8 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/814561 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
Terje Bergstrom
parent
5b7b59714a
commit
68099f8298
@@ -1561,6 +1561,54 @@ static u32 fifo_error_isr(struct gk20a *g, u32 fifo_intr)
|
||||
return handled;
|
||||
}
|
||||
|
||||
static inline void gk20a_fifo_reset_pbdma_header(struct gk20a *g, int pbdma_id)
|
||||
{
|
||||
gk20a_writel(g, pbdma_pb_header_r(pbdma_id),
|
||||
pbdma_pb_header_first_true_f() |
|
||||
pbdma_pb_header_type_non_inc_f());
|
||||
}
|
||||
|
||||
static inline void gk20a_fifo_reset_pbdma_method(struct gk20a *g, int pbdma_id,
|
||||
int pbdma_method_index)
|
||||
{
|
||||
u32 pbdma_method_stride;
|
||||
u32 pbdma_method_reg;
|
||||
|
||||
pbdma_method_stride = pbdma_method1_r(pbdma_id) -
|
||||
pbdma_method0_r(pbdma_id);
|
||||
|
||||
pbdma_method_reg = pbdma_method0_r(pbdma_id) +
|
||||
(pbdma_method_index * pbdma_method_stride);
|
||||
|
||||
gk20a_writel(g, pbdma_method_reg,
|
||||
pbdma_method0_valid_true_f() |
|
||||
pbdma_method0_first_true_f() |
|
||||
pbdma_method0_addr_f(
|
||||
pbdma_udma_nop_r() >> 2));
|
||||
}
|
||||
|
||||
static bool gk20a_fifo_is_sw_method_subch(struct gk20a *g, int pbdma_id,
|
||||
int pbdma_method_index)
|
||||
{
|
||||
u32 pbdma_method_stride;
|
||||
u32 pbdma_method_reg, pbdma_method_subch;
|
||||
|
||||
pbdma_method_stride = pbdma_method1_r(pbdma_id) -
|
||||
pbdma_method0_r(pbdma_id);
|
||||
|
||||
pbdma_method_reg = pbdma_method0_r(pbdma_id) +
|
||||
(pbdma_method_index * pbdma_method_stride);
|
||||
|
||||
pbdma_method_subch = pbdma_method0_subch_v(
|
||||
gk20a_readl(g, pbdma_method_reg));
|
||||
|
||||
if (pbdma_method_subch == 5 || pbdma_method_subch == 6 ||
|
||||
pbdma_method_subch == 7)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
|
||||
struct gk20a *g,
|
||||
struct fifo_gk20a *f,
|
||||
@@ -1570,6 +1618,7 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
|
||||
u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id));
|
||||
u32 handled = 0;
|
||||
bool reset = false;
|
||||
int i;
|
||||
|
||||
gk20a_dbg_fn("");
|
||||
|
||||
@@ -1580,11 +1629,15 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
|
||||
f->intr.pbdma.channel_fatal_0 |
|
||||
f->intr.pbdma.restartable_0) & pbdma_intr_0) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"pbdma_intr_0(%d):0x%08x PBH: %08x SHADOW: %08x M0: %08x",
|
||||
"pbdma_intr_0(%d):0x%08x PBH: %08x SHADOW: %08x M0: %08x %08x %08x %08x",
|
||||
pbdma_id, pbdma_intr_0,
|
||||
gk20a_readl(g, pbdma_pb_header_r(pbdma_id)),
|
||||
gk20a_readl(g, pbdma_hdr_shadow_r(pbdma_id)),
|
||||
gk20a_readl(g, pbdma_method0_r(pbdma_id)));
|
||||
gk20a_readl(g, pbdma_method0_r(pbdma_id)),
|
||||
gk20a_readl(g, pbdma_method1_r(pbdma_id)),
|
||||
gk20a_readl(g, pbdma_method2_r(pbdma_id)),
|
||||
gk20a_readl(g, pbdma_method3_r(pbdma_id))
|
||||
);
|
||||
reset = true;
|
||||
handled |= ((f->intr.pbdma.device_fatal_0 |
|
||||
f->intr.pbdma.channel_fatal_0 |
|
||||
@@ -1592,7 +1645,29 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
|
||||
pbdma_intr_0);
|
||||
}
|
||||
|
||||
gk20a_writel(g, pbdma_method0_r(pbdma_id), 0);
|
||||
if (pbdma_intr_0 & pbdma_intr_0_pbentry_pending_f()) {
|
||||
gk20a_fifo_reset_pbdma_header(g, pbdma_id);
|
||||
gk20a_fifo_reset_pbdma_method(g, pbdma_id, 0);
|
||||
reset = true;
|
||||
}
|
||||
|
||||
if (pbdma_intr_0 & pbdma_intr_0_method_pending_f()) {
|
||||
gk20a_fifo_reset_pbdma_method(g, pbdma_id, 0);
|
||||
reset = true;
|
||||
}
|
||||
|
||||
if (pbdma_intr_0 & pbdma_intr_0_device_pending_f()) {
|
||||
gk20a_fifo_reset_pbdma_header(g, pbdma_id);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (gk20a_fifo_is_sw_method_subch(g,
|
||||
pbdma_id, i))
|
||||
gk20a_fifo_reset_pbdma_method(g,
|
||||
pbdma_id, i);
|
||||
}
|
||||
reset = true;
|
||||
}
|
||||
|
||||
gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -190,6 +190,10 @@ static inline u32 pbdma_pb_header_type_inc_f(void)
|
||||
{
|
||||
return 0x20000000;
|
||||
}
|
||||
static inline u32 pbdma_pb_header_type_non_inc_f(void)
|
||||
{
|
||||
return 0x60000000;
|
||||
}
|
||||
static inline u32 pbdma_hdr_shadow_r(u32 i)
|
||||
{
|
||||
return 0x00040118 + i*8192;
|
||||
@@ -214,6 +218,38 @@ static inline u32 pbdma_method0_r(u32 i)
|
||||
{
|
||||
return 0x000400c0 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_method0_addr_f(u32 v)
|
||||
{
|
||||
return (v & 0xfff) << 2;
|
||||
}
|
||||
static inline u32 pbdma_method0_addr_v(u32 r)
|
||||
{
|
||||
return (r >> 2) & 0xfff;
|
||||
}
|
||||
static inline u32 pbdma_method0_subch_v(u32 r)
|
||||
{
|
||||
return (r >> 16) & 0x7;
|
||||
}
|
||||
static inline u32 pbdma_method0_first_true_f(void)
|
||||
{
|
||||
return 0x400000;
|
||||
}
|
||||
static inline u32 pbdma_method0_valid_true_f(void)
|
||||
{
|
||||
return 0x80000000;
|
||||
}
|
||||
static inline u32 pbdma_method1_r(u32 i)
|
||||
{
|
||||
return 0x000400c8 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_method2_r(u32 i)
|
||||
{
|
||||
return 0x000400d0 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_method3_r(u32 i)
|
||||
{
|
||||
return 0x000400d8 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_data0_r(u32 i)
|
||||
{
|
||||
return 0x000400c4 + i*8192;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -174,6 +174,10 @@ static inline u32 pbdma_pb_header_type_inc_f(void)
|
||||
{
|
||||
return 0x20000000;
|
||||
}
|
||||
static inline u32 pbdma_pb_header_type_non_inc_f(void)
|
||||
{
|
||||
return 0x60000000;
|
||||
}
|
||||
static inline u32 pbdma_hdr_shadow_r(u32 i)
|
||||
{
|
||||
return 0x00040118 + i*8192;
|
||||
@@ -198,6 +202,42 @@ static inline u32 pbdma_method0_r(u32 i)
|
||||
{
|
||||
return 0x000400c0 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_method0_fifo_size_v(void)
|
||||
{
|
||||
return 0x00000004;
|
||||
}
|
||||
static inline u32 pbdma_method0_addr_f(u32 v)
|
||||
{
|
||||
return (v & 0xfff) << 2;
|
||||
}
|
||||
static inline u32 pbdma_method0_addr_v(u32 r)
|
||||
{
|
||||
return (r >> 2) & 0xfff;
|
||||
}
|
||||
static inline u32 pbdma_method0_subch_v(u32 r)
|
||||
{
|
||||
return (r >> 16) & 0x7;
|
||||
}
|
||||
static inline u32 pbdma_method0_first_true_f(void)
|
||||
{
|
||||
return 0x400000;
|
||||
}
|
||||
static inline u32 pbdma_method0_valid_true_f(void)
|
||||
{
|
||||
return 0x80000000;
|
||||
}
|
||||
static inline u32 pbdma_method1_r(u32 i)
|
||||
{
|
||||
return 0x000400c8 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_method2_r(u32 i)
|
||||
{
|
||||
return 0x000400d0 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_method3_r(u32 i)
|
||||
{
|
||||
return 0x000400d8 + i*8192;
|
||||
}
|
||||
static inline u32 pbdma_data0_r(u32 i)
|
||||
{
|
||||
return 0x000400c4 + i*8192;
|
||||
|
||||
Reference in New Issue
Block a user