From c0668f05ea1e2429444d6aad2a40dda81aba7ec8 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 10 Nov 2014 10:34:24 +0200 Subject: gpu: nvgpu: Retrieve intr & reset id from HW Query interrupt number and reset id from HW. Use the number from HW when enabling and detecting interrupts. Bug 200036089 Bug 1567274 Change-Id: If9cb4db79a19dcb193ba7ad9db7081f4fe1ab433 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/600988 --- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 109 +++++++++++++++++---------------- drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 8 +-- drivers/gpu/nvgpu/gk20a/gk20a.c | 23 ++++--- drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h | 10 ++- drivers/gpu/nvgpu/gk20a/mc_gk20a.c | 15 ++++- drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h | 8 +++ drivers/gpu/nvgpu/vgpu/fifo_vgpu.c | 2 - 7 files changed, 99 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index df6b84c5..64203027 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -72,8 +72,6 @@ static int init_engine_info(struct fifo_gk20a *f) { struct gk20a *g = f->g; struct device *d = dev_from_gk20a(g); - struct fifo_engine_info_gk20a *gr_info; - const u32 gr_sw_id = ENGINE_GR_GK20A; u32 i; u32 max_info_entries = top_device_info__size_1_v(); @@ -81,77 +79,80 @@ static int init_engine_info(struct fifo_gk20a *f) /* all we really care about finding is the graphics entry */ /* especially early on in sim it probably thinks it has more */ - f->num_engines = 1; - - gr_info = f->engine_info + gr_sw_id; - - gr_info->sw_id = gr_sw_id; - gr_info->name = "gr"; - gr_info->dev_info_id = top_device_info_type_enum_graphics_v(); - gr_info->mmu_fault_id = fifo_intr_mmu_fault_eng_id_graphics_v(); - gr_info->runlist_id = ~0; - gr_info->pbdma_id = ~0; - gr_info->engine_id = ~0; + f->num_engines = 2; for (i = 0; i < max_info_entries; i++) { + struct fifo_engine_info_gk20a *info = NULL; u32 table_entry = gk20a_readl(f->g, top_device_info_r(i)); u32 entry = top_device_info_entry_v(table_entry); - u32 engine_enum = top_device_info_type_enum_v(table_entry); - u32 table_entry2 = 0; + u32 engine_enum; + int pbdma_id; + u32 runlist_bit; - if (entry == top_device_info_entry_not_valid_v()) + if (entry != top_device_info_entry_enum_v()) continue; - if (top_device_info_chain_v(table_entry) == - top_device_info_chain_enable_v()) { + /* we only care about GR engine here */ + engine_enum = top_device_info_engine_enum_v(table_entry); + if (engine_enum >= ENGINE_INVAL_GK20A) + continue; - table_entry2 = gk20a_readl(f->g, - top_device_info_r(++i)); + gk20a_dbg_info("info: engine_id %d", + top_device_info_engine_enum_v(table_entry)); + info = &g->fifo.engine_info[engine_enum]; - engine_enum = top_device_info_type_enum_v(table_entry2); - } + info->runlist_id = + top_device_info_runlist_enum_v(table_entry); + gk20a_dbg_info("gr info: runlist_id %d", info->runlist_id); - /* we only care about GR engine here */ - if (entry == top_device_info_entry_enum_v() && - engine_enum == gr_info->dev_info_id) { - int pbdma_id; - u32 runlist_bit; - - gr_info->runlist_id = - top_device_info_runlist_enum_v(table_entry); - gk20a_dbg_info("gr info: runlist_id %d", gr_info->runlist_id); - - gr_info->engine_id = - top_device_info_engine_enum_v(table_entry); - gk20a_dbg_info("gr info: engine_id %d", gr_info->engine_id); - - runlist_bit = 1 << gr_info->runlist_id; - - for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) { - gk20a_dbg_info("gr info: pbdma_map[%d]=%d", - pbdma_id, f->pbdma_map[pbdma_id]); - if (f->pbdma_map[pbdma_id] & runlist_bit) - break; - } + info->engine_id = + top_device_info_engine_enum_v(table_entry); + gk20a_dbg_info("gr info: engine_id %d", info->engine_id); - if (pbdma_id == f->num_pbdma) { - gk20a_err(d, "busted pbmda map"); - return -EINVAL; - } - gr_info->pbdma_id = pbdma_id; + runlist_bit = 1 << info->runlist_id; - break; + for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) { + gk20a_dbg_info("gr info: pbdma_map[%d]=%d", + pbdma_id, f->pbdma_map[pbdma_id]); + if (f->pbdma_map[pbdma_id] & runlist_bit) + break; } - } - if (gr_info->runlist_id == ~0) { - gk20a_err(d, "busted device info"); - return -EINVAL; + if (pbdma_id == f->num_pbdma) { + gk20a_err(d, "busted pbmda map"); + return -EINVAL; + } + info->pbdma_id = pbdma_id; + + info->intr_id = + top_device_info_intr_enum_v(table_entry); + gk20a_dbg_info("gr info: intr_id %d", info->intr_id); + + info->reset_id = + top_device_info_reset_enum_v(table_entry); + gk20a_dbg_info("gr info: reset_id %d", + info->reset_id); + } return 0; } +u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g) +{ + u32 eng_intr_mask = 0; + int i = 0; + + for (i = 0; i < g->fifo.max_engines; i++) { + u32 intr_id = g->fifo.engine_info[i].intr_id; + + if (intr_id) + eng_intr_mask |= BIT(intr_id); + } + + return eng_intr_mask; +} + static void gk20a_remove_fifo_support(struct fifo_gk20a *f) { struct gk20a *g = f->g; diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 61783c7d..ecae970f 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h @@ -77,14 +77,11 @@ struct fifo_mmu_fault_info_gk20a { }; struct fifo_engine_info_gk20a { - u32 sw_id; - const char *name; - u32 dev_info_id; u32 engine_id; u32 runlist_id; + u32 intr_id; + u32 reset_id; u32 pbdma_id; - u32 mmu_fault_id; - u32 rc_mask; struct fifo_pbdma_exception_info_gk20a pbdma_exception_info; struct fifo_engine_exception_info_gk20a engine_exception_info; struct fifo_mmu_fault_info_gk20a mmu_fault_info; @@ -171,4 +168,5 @@ void gk20a_init_fifo(struct gpu_ops *gops); void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, unsigned long fault_id); int gk20a_fifo_wait_engine_idle(struct gk20a *g); +u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g); #endif /*__GR_GK20A_H__*/ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 1bd1c898..91cd5834 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -757,11 +757,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev) if (err) goto done; - enable_irq(g->irq_stall); - enable_irq(g->irq_nonstall); - - g->ops.mc.intr_enable(g); - if (!tegra_platform_is_silicon()) gk20a_writel(g, bus_intr_en_0_r(), 0x0); else @@ -814,6 +809,14 @@ static int gk20a_pm_finalize_poweron(struct device *dev) goto done; } + err = gk20a_init_fifo_support(g); + if (err) { + gk20a_err(dev, "failed to init gk20a fifo"); + goto done; + } + + g->ops.mc.intr_enable(g); + err = gk20a_enable_gr_hw(g); if (err) { gk20a_err(dev, "failed to enable gr"); @@ -833,12 +836,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev) goto done; } - err = gk20a_init_fifo_support(g); - if (err) { - gk20a_err(dev, "failed to init gk20a fifo"); - goto done; - } - err = gk20a_init_gr_support(g); if (err) { gk20a_err(dev, "failed to init gk20a gr"); @@ -857,7 +854,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev) goto done; } - gk20a_channel_resume(g); set_user_nice(current, nice_value); @@ -868,6 +864,9 @@ static int gk20a_pm_finalize_poweron(struct device *dev) if (platform->has_cde) gk20a_init_cde_support(g); + enable_irq(g->irq_stall); + enable_irq(g->irq_nonstall); + #ifdef CONFIG_INPUT_CFBOOST if (!g->boost_added) { gk20a_dbg_info("add touch boost"); diff --git a/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h index ab527d25..f3ca7498 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2012-2014, 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, @@ -98,6 +98,14 @@ static inline u32 top_device_info_runlist_enum_v(u32 r) { return (r >> 21) & 0xf; } +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15) & 0x1f; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9) & 0x1f; +} static inline u32 top_device_info_type_enum_v(u32 r) { return (r >> 2) & 0x1fffffff; diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c index 53701605..4d176403 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c @@ -71,7 +71,7 @@ irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g) gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0); - if (mc_intr_0 & mc_intr_0_pgraph_pending_f()) + if (mc_intr_0 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id)) gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g)); if (mc_intr_0 & mc_intr_0_pfifo_pending_f()) gk20a_fifo_isr(g); @@ -105,7 +105,7 @@ irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g) if (mc_intr_1 & mc_intr_0_pfifo_pending_f()) gk20a_fifo_nonstall_isr(g); - if (mc_intr_1 & mc_intr_0_pgraph_pending_f()) + if (mc_intr_1 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id)) gk20a_gr_nonstall_isr(g); gk20a_writel(g, mc_intr_en_1_r(), @@ -119,9 +119,20 @@ irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g) void mc_gk20a_intr_enable(struct gk20a *g) { + u32 eng_intr_mask = gk20a_fifo_engine_interrupt_mask(g); + + gk20a_writel(g, mc_intr_mask_1_r(), + mc_intr_0_pfifo_pending_f() + | eng_intr_mask); gk20a_writel(g, mc_intr_en_1_r(), mc_intr_en_1_inta_hardware_f()); + gk20a_writel(g, mc_intr_mask_0_r(), + mc_intr_0_pfifo_pending_f() + | mc_intr_0_priv_ring_pending_f() + | mc_intr_0_ltc_pending_f() + | mc_intr_0_pbus_pending_f() + | eng_intr_mask); gk20a_writel(g, mc_intr_en_0_r(), mc_intr_en_0_inta_hardware_f()); } diff --git a/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h index a2405a04..42a82a12 100644 --- a/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h @@ -102,6 +102,14 @@ static inline u32 top_device_info_runlist_enum_v(u32 r) { return (r >> 21) & 0xf; } +static inline u32 top_device_info_intr_enum_v(u32 r) +{ + return (r >> 15) & 0x1f; +} +static inline u32 top_device_info_reset_enum_v(u32 r) +{ + return (r >> 9) & 0x1f; +} static inline u32 top_device_info_type_enum_v(u32 r) { return (r >> 2) & 0x1fffffff; diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c index 9bbb39f0..80a89e1e 100644 --- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c @@ -162,8 +162,6 @@ static int init_engine_info(struct fifo_gk20a *f) gr_info = f->engine_info + gr_sw_id; - gr_info->sw_id = gr_sw_id; - gr_info->name = "gr"; /* FIXME: retrieve this from server */ gr_info->runlist_id = 0; return 0; -- cgit v1.2.2