From f2ad7e091643807678e3a812b0ec16f57d2ef41c Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Fri, 29 Mar 2019 22:37:58 +0530 Subject: [PATCH] gpu: nvgpu: separate sec2 isr into common and hal SEC2 isr handling requires message processing in common msg unit. That unit requires interfaces from hal to know if the msg interrupt was received, set the msg interrupt and handle other interrupts. JIRA NVGPU-2025 Change-Id: I3b5ad8968ea9298cc769113417931c4678009cf1 Signed-off-by: Sagar Kamble Reviewed-on: https://git-master.nvidia.com/r/2085753 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/sec2/sec2_msg.c | 52 ++++++++++++++++- drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 6 +- drivers/gpu/nvgpu/tu104/hal_tu104.c | 6 +- drivers/gpu/nvgpu/tu104/sec2_tu104.c | 72 ++++++++++-------------- drivers/gpu/nvgpu/tu104/sec2_tu104.h | 7 ++- 5 files changed, 95 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/nvgpu/common/sec2/sec2_msg.c b/drivers/gpu/nvgpu/common/sec2/sec2_msg.c index 504c457bf..1ecc248bf 100644 --- a/drivers/gpu/nvgpu/common/sec2/sec2_msg.c +++ b/drivers/gpu/nvgpu/common/sec2/sec2_msg.c @@ -199,6 +199,54 @@ exit: return status; } +static void sec2_isr(struct gk20a *g, struct nvgpu_sec2 *sec2) +{ + bool recheck = false; + u32 intr; + + if (!g->ops.sec2.is_interrupted(sec2)) { + return; + } + + nvgpu_mutex_acquire(&sec2->isr_mutex); + if (!sec2->isr_enabled) { + goto exit; + } + + intr = g->ops.sec2.get_intr(g); + if (intr == 0U) { + goto exit; + } + + /* + * Handle swgen0 interrupt to process received messages from SEC2. + * If any other interrupt is to be handled with some software + * action expected, then it should be handled here. + * g->ops.sec2.isr call below will handle other hardware interrupts + * that are not expected to be handled in software. + */ + if (g->ops.sec2.msg_intr_received(g)) { + if (nvgpu_sec2_process_message(sec2) != 0) { + g->ops.sec2.clr_intr(g, intr); + goto exit; + } + recheck = true; + } + + g->ops.sec2.process_intr(g, sec2); + g->ops.sec2.clr_intr(g, intr); + + if (recheck) { + if (!nvgpu_sec2_queue_is_empty(sec2->queues, + SEC2_NV_MSGQ_LOG_ID)) { + g->ops.sec2.set_msg_intr(g); + } + } + +exit: + nvgpu_mutex_release(&sec2->isr_mutex); +} + int nvgpu_sec2_wait_message_cond(struct nvgpu_sec2 *sec2, u32 timeout_ms, void *var, u8 val) { @@ -213,9 +261,7 @@ int nvgpu_sec2_wait_message_cond(struct nvgpu_sec2 *sec2, u32 timeout_ms, return 0; } - if (g->ops.sec2.is_interrupted(sec2)) { - g->ops.sec2.isr(g); - } + sec2_isr(g, sec2); nvgpu_usleep_range(delay, delay * 2U); delay = min_t(u32, delay << 1U, POLL_DELAY_MAX_US); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index b7fa8af28..0270b92e2 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -1840,7 +1840,11 @@ struct gpu_ops { void (*secured_sec2_start)(struct gk20a *g); void (*enable_irq)(struct nvgpu_sec2 *sec2, bool enable); bool (*is_interrupted)(struct nvgpu_sec2 *sec2); - void (*isr)(struct gk20a *g); + u32 (*get_intr)(struct gk20a *g); + bool (*msg_intr_received)(struct gk20a *g); + void (*set_msg_intr)(struct gk20a *g); + void (*clr_intr)(struct gk20a *g, u32 intr); + void (*process_intr)(struct gk20a *g, struct nvgpu_sec2 *sec2); void (*msgq_tail)(struct gk20a *g, struct nvgpu_sec2 *sec2, u32 *tail, bool set); u32 (*falcon_base_addr)(void); diff --git a/drivers/gpu/nvgpu/tu104/hal_tu104.c b/drivers/gpu/nvgpu/tu104/hal_tu104.c index 9ddf4b1cf..749bd3a82 100644 --- a/drivers/gpu/nvgpu/tu104/hal_tu104.c +++ b/drivers/gpu/nvgpu/tu104/hal_tu104.c @@ -1412,7 +1412,11 @@ static const struct gpu_ops tu104_ops = { .secured_sec2_start = tu104_start_sec2_secure, .enable_irq = tu104_sec2_enable_irq, .is_interrupted = tu104_sec2_is_interrupted, - .isr = tu104_sec2_isr, + .get_intr = tu104_sec2_get_intr, + .msg_intr_received = tu104_sec2_msg_intr_received, + .set_msg_intr = tu104_sec2_set_msg_intr, + .clr_intr = tu104_sec2_clr_intr, + .process_intr = tu104_sec2_process_intr, .msgq_tail = tu104_sec2_msgq_tail, .falcon_base_addr = tu104_sec2_falcon_base_addr, .sec2_reset = tu104_sec2_reset, diff --git a/drivers/gpu/nvgpu/tu104/sec2_tu104.c b/drivers/gpu/nvgpu/tu104/sec2_tu104.c index 0a110e8ca..bbd6ea95e 100644 --- a/drivers/gpu/nvgpu/tu104/sec2_tu104.c +++ b/drivers/gpu/nvgpu/tu104/sec2_tu104.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -310,7 +309,7 @@ void tu104_sec2_enable_irq(struct nvgpu_sec2 *sec2, bool enable) u32 intr_mask; u32 intr_dest; - nvgpu_falcon_set_irq(&g->sec2.flcn, false, 0x0, 0x0); + g->ops.falcon.set_irq(&sec2->flcn, false, 0x0, 0x0); if (enable) { /* dest 0=falcon, 1=host; level 0=irq0, 1=irq1 */ @@ -343,7 +342,7 @@ void tu104_sec2_enable_irq(struct nvgpu_sec2 *sec2, bool enable) psec_falcon_irqmset_swgen0_f(1) | psec_falcon_irqmset_swgen1_f(1); - nvgpu_falcon_set_irq(&g->sec2.flcn, true, intr_mask, intr_dest); + g->ops.falcon.set_irq(&sec2->flcn, true, intr_mask, intr_dest); } } @@ -364,34 +363,43 @@ bool tu104_sec2_is_interrupted(struct nvgpu_sec2 *sec2) return false; } -void tu104_sec2_isr(struct gk20a *g) +u32 tu104_sec2_get_intr(struct gk20a *g) { - struct nvgpu_sec2 *sec2 = &g->sec2; - struct nvgpu_engine_mem_queue *queue; - u32 intr, mask; - bool recheck = false; - - nvgpu_mutex_acquire(&sec2->isr_mutex); - if (!sec2->isr_enabled) { - nvgpu_mutex_release(&sec2->isr_mutex); - return; - } + u32 mask; mask = gk20a_readl(g, psec_falcon_irqmask_r()) & gk20a_readl(g, psec_falcon_irqdest_r()); - intr = gk20a_readl(g, psec_falcon_irqstat_r()); + return gk20a_readl(g, psec_falcon_irqstat_r()) & mask; +} - intr = gk20a_readl(g, psec_falcon_irqstat_r()) & mask; - if (intr == 0U) { - gk20a_writel(g, psec_falcon_irqsclr_r(), intr); - nvgpu_mutex_release(&sec2->isr_mutex); - return; - } +bool tu104_sec2_msg_intr_received(struct gk20a *g) +{ + u32 intr = tu104_sec2_get_intr(g); + + return (intr & psec_falcon_irqstat_swgen0_true_f()) != 0U; +} + +void tu104_sec2_set_msg_intr(struct gk20a *g) +{ + gk20a_writel(g, psec_falcon_irqsset_r(), + psec_falcon_irqsset_swgen0_set_f()); +} + +void tu104_sec2_clr_intr(struct gk20a *g, u32 intr) +{ + gk20a_writel(g, psec_falcon_irqsclr_r(), intr); +} + +void tu104_sec2_process_intr(struct gk20a *g, struct nvgpu_sec2 *sec2) +{ + u32 intr; + + intr = tu104_sec2_get_intr(g); if ((intr & psec_falcon_irqstat_halt_true_f()) != 0U) { nvgpu_err(g, "sec2 halt intr not implemented"); - nvgpu_falcon_dump_stats(&g->sec2.flcn); + g->ops.falcon.dump_falcon_stats(&sec2->flcn); } if ((intr & psec_falcon_irqstat_exterr_true_f()) != 0U) { nvgpu_err(g, @@ -402,27 +410,7 @@ void tu104_sec2_isr(struct gk20a *g) ~psec_falcon_exterrstat_valid_m()); } - if ((intr & psec_falcon_irqstat_swgen0_true_f()) != 0U) { - if (nvgpu_sec2_process_message(sec2) != 0) { - gk20a_writel(g, psec_falcon_irqsclr_r(), intr); - goto exit; - } - recheck = true; - } - - gk20a_writel(g, psec_falcon_irqsclr_r(), intr); - - if (recheck) { - queue = sec2->queues[SEC2_NV_MSGQ_LOG_ID]; - if (!nvgpu_engine_mem_queue_is_empty(queue)) { - gk20a_writel(g, psec_falcon_irqsset_r(), - psec_falcon_irqsset_swgen0_set_f()); - } - } - -exit: nvgpu_sec2_dbg(g, "Done"); - nvgpu_mutex_release(&sec2->isr_mutex); } void tu104_start_sec2_secure(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/tu104/sec2_tu104.h b/drivers/gpu/nvgpu/tu104/sec2_tu104.h index 2b2a5f0cd..83f84e1de 100644 --- a/drivers/gpu/nvgpu/tu104/sec2_tu104.h +++ b/drivers/gpu/nvgpu/tu104/sec2_tu104.h @@ -23,6 +23,7 @@ #ifndef NVGPU_SEC2_TU104_H #define NVGPU_SEC2_TU104_H +struct gk20a; struct nvgpu_sec2; int tu104_sec2_reset(struct gk20a *g); @@ -39,8 +40,12 @@ int tu104_sec2_queue_tail(struct gk20a *g, u32 queue_id, u32 queue_index, void tu104_sec2_msgq_tail(struct gk20a *g, struct nvgpu_sec2 *sec2, u32 *tail, bool set); -void tu104_sec2_isr(struct gk20a *g); bool tu104_sec2_is_interrupted(struct nvgpu_sec2 *sec2); +u32 tu104_sec2_get_intr(struct gk20a *g); +bool tu104_sec2_msg_intr_received(struct gk20a *g); +void tu104_sec2_set_msg_intr(struct gk20a *g); +void tu104_sec2_clr_intr(struct gk20a *g, u32 intr); +void tu104_sec2_process_intr(struct gk20a *g, struct nvgpu_sec2 *sec2); void tu104_sec2_enable_irq(struct nvgpu_sec2 *sec2, bool enable); void tu104_start_sec2_secure(struct gk20a *g); u32 tu104_sec2_falcon_base_addr(void);