video: tegra: tsec: Launch threaded handler only for SWGEN0

Launch threaded handler to drain TSEC messages only for
SWGEN0 interrupt.

If SWGEN1 interrupt is received to pull out print buffer
then ignore it and mask it out so that it is not received
in future

Bug 3897473

Change-Id: I16e2d442ba77141286171f69114ecf309d411ec7
Signed-off-by: Nikesh Oswal <noswal@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2822539
Tested-by: Sahil Patki <spatki@nvidia.com>
Reviewed-by: Sahil Patki <spatki@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Nikesh Oswal
2022-12-06 11:44:42 +00:00
committed by Laxman Dewangan
parent be91d1bd18
commit 83576bbd5d
2 changed files with 47 additions and 8 deletions

View File

@@ -576,25 +576,50 @@ static irqreturn_t tsec_irq_top_half(int irq, void *dev_id)
unsigned long flags;
struct platform_device *pdev = (struct platform_device *)(dev_id);
struct tsec_device_data *pdata = platform_get_drvdata(pdev);
irqreturn_t irq_ret_val = IRQ_HANDLED;
u32 irq_status;
spin_lock_irqsave(&pdata->mirq_lock, flags);
/* Read the interrupt status */
irq_status = tsec_readl(pdata, tsec_irqstat_r());
/* Clear the interrupt */
tsec_writel(pdata, tsec_thi_int_status_r(),
tsec_thi_int_status_clr_f());
tsec_writel(pdata, tsec_irqsclr_r(),
tsec_irqsclr_swgen0_set_f());
/* Mask the interrupt.
* Clear RISCV Mask for SWGEN0, so that no more SWGEN0
* interrupts will be routed to CCPLEX, it will be re-enabled
* by the bottom half
/* Wakeup threaded handler for SWGEN0 Irq */
if (irq_status & tsec_irqstat_swgen0()) {
/* Clear SWGEN0 Interrupt */
tsec_writel(pdata, tsec_irqsclr_r(),
tsec_irqsclr_swgen0_set_f());
/* Mask the interrupt.
* Clear RISCV Mask for SWGEN0, so that no more SWGEN0
* interrupts will be routed to CCPLEX, it will be re-enabled
* by the bottom half
*/
tsec_writel(pdata, tsec_riscv_irqmclr_r(),
tsec_riscv_irqmclr_swgen0_set_f());
irq_ret_val = IRQ_WAKE_THREAD;
irq_status &= ~(tsec_irqstat_swgen0());
}
/* RISCV FW is generating SWGEN1 when it logs something
* in the print buffer at below path
* nvriscv/drivers/src/debug/debug.c:164: irqFireSwGen(SYS_INTR_SWGEN1)
* We dont want to pull out the print buffer from CCPLEX
* hence we just mask out SWGEN1 interrupt here so that it
* is not received any further
*/
tsec_writel(pdata, tsec_riscv_irqmclr_r(), tsec_riscv_irqmclr_swgen0_set_f());
if (irq_status & tsec_irqstat_swgen1()) {
tsec_writel(pdata, tsec_riscv_irqmclr_r(),
tsec_riscv_irqmclr_swgen1_set_f());
irq_status &= ~(tsec_irqstat_swgen1());
}
spin_unlock_irqrestore(&pdata->mirq_lock, flags);
return IRQ_WAKE_THREAD;
return irq_ret_val;
}
static irqreturn_t tsec_irq_bottom_half(int irq, void *args)

View File

@@ -101,6 +101,20 @@ static inline u32 tsec_irqsclr_swgen0_set_f(void)
return 0x40;
}
static inline u32 tsec_irqstat_r(void)
{
/* NV_PSEC_FALCON_IRQSTAT_0 */
return 0x1008;
}
static inline u32 tsec_irqstat_swgen0(void)
{
return 0x40;
}
static inline u32 tsec_irqstat_swgen1(void)
{
return 0x80;
}
static inline u32 tsec_riscv_irqmset_r(void)
{
/* NV_PSEC_RISCV_IRQMSET_0 */