summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2014-11-10 03:34:24 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:12:14 -0400
commitc0668f05ea1e2429444d6aad2a40dda81aba7ec8 (patch)
treee022679a8f6690d16d3c47ebd77021075ce914d3
parent3a504842cd2696bd2feb496f4f4555ace82b4ab1 (diff)
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 <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/600988
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c109
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h8
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c23
-rw-r--r--drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h10
-rw-r--r--drivers/gpu/nvgpu/gk20a/mc_gk20a.c15
-rw-r--r--drivers/gpu/nvgpu/gm20b/hw_top_gm20b.h8
-rw-r--r--drivers/gpu/nvgpu/vgpu/fifo_vgpu.c2
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)
72{ 72{
73 struct gk20a *g = f->g; 73 struct gk20a *g = f->g;
74 struct device *d = dev_from_gk20a(g); 74 struct device *d = dev_from_gk20a(g);
75 struct fifo_engine_info_gk20a *gr_info;
76 const u32 gr_sw_id = ENGINE_GR_GK20A;
77 u32 i; 75 u32 i;
78 u32 max_info_entries = top_device_info__size_1_v(); 76 u32 max_info_entries = top_device_info__size_1_v();
79 77
@@ -81,77 +79,80 @@ static int init_engine_info(struct fifo_gk20a *f)
81 79
82 /* all we really care about finding is the graphics entry */ 80 /* all we really care about finding is the graphics entry */
83 /* especially early on in sim it probably thinks it has more */ 81 /* especially early on in sim it probably thinks it has more */
84 f->num_engines = 1; 82 f->num_engines = 2;
85
86 gr_info = f->engine_info + gr_sw_id;
87
88 gr_info->sw_id = gr_sw_id;
89 gr_info->name = "gr";
90 gr_info->dev_info_id = top_device_info_type_enum_graphics_v();
91 gr_info->mmu_fault_id = fifo_intr_mmu_fault_eng_id_graphics_v();
92 gr_info->runlist_id = ~0;
93 gr_info->pbdma_id = ~0;
94 gr_info->engine_id = ~0;
95 83
96 for (i = 0; i < max_info_entries; i++) { 84 for (i = 0; i < max_info_entries; i++) {
85 struct fifo_engine_info_gk20a *info = NULL;
97 u32 table_entry = gk20a_readl(f->g, top_device_info_r(i)); 86 u32 table_entry = gk20a_readl(f->g, top_device_info_r(i));
98 u32 entry = top_device_info_entry_v(table_entry); 87 u32 entry = top_device_info_entry_v(table_entry);
99 u32 engine_enum = top_device_info_type_enum_v(table_entry); 88 u32 engine_enum;
100 u32 table_entry2 = 0; 89 int pbdma_id;
90 u32 runlist_bit;
101 91
102 if (entry == top_device_info_entry_not_valid_v()) 92 if (entry != top_device_info_entry_enum_v())
103 continue; 93 continue;
104 94
105 if (top_device_info_chain_v(table_entry) == 95 /* we only care about GR engine here */
106 top_device_info_chain_enable_v()) { 96 engine_enum = top_device_info_engine_enum_v(table_entry);
97 if (engine_enum >= ENGINE_INVAL_GK20A)
98 continue;
107 99
108 table_entry2 = gk20a_readl(f->g, 100 gk20a_dbg_info("info: engine_id %d",
109 top_device_info_r(++i)); 101 top_device_info_engine_enum_v(table_entry));
102 info = &g->fifo.engine_info[engine_enum];
110 103
111 engine_enum = top_device_info_type_enum_v(table_entry2); 104 info->runlist_id =
112 } 105 top_device_info_runlist_enum_v(table_entry);
106 gk20a_dbg_info("gr info: runlist_id %d", info->runlist_id);
113 107
114 /* we only care about GR engine here */ 108 info->engine_id =
115 if (entry == top_device_info_entry_enum_v() && 109 top_device_info_engine_enum_v(table_entry);
116 engine_enum == gr_info->dev_info_id) { 110 gk20a_dbg_info("gr info: engine_id %d", info->engine_id);
117 int pbdma_id;
118 u32 runlist_bit;
119
120 gr_info->runlist_id =
121 top_device_info_runlist_enum_v(table_entry);
122 gk20a_dbg_info("gr info: runlist_id %d", gr_info->runlist_id);
123
124 gr_info->engine_id =
125 top_device_info_engine_enum_v(table_entry);
126 gk20a_dbg_info("gr info: engine_id %d", gr_info->engine_id);
127
128 runlist_bit = 1 << gr_info->runlist_id;
129
130 for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) {
131 gk20a_dbg_info("gr info: pbdma_map[%d]=%d",
132 pbdma_id, f->pbdma_map[pbdma_id]);
133 if (f->pbdma_map[pbdma_id] & runlist_bit)
134 break;
135 }
136 111
137 if (pbdma_id == f->num_pbdma) { 112 runlist_bit = 1 << info->runlist_id;
138 gk20a_err(d, "busted pbmda map");
139 return -EINVAL;
140 }
141 gr_info->pbdma_id = pbdma_id;
142 113
143 break; 114 for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) {
115 gk20a_dbg_info("gr info: pbdma_map[%d]=%d",
116 pbdma_id, f->pbdma_map[pbdma_id]);
117 if (f->pbdma_map[pbdma_id] & runlist_bit)
118 break;
144 } 119 }
145 }
146 120
147 if (gr_info->runlist_id == ~0) { 121 if (pbdma_id == f->num_pbdma) {
148 gk20a_err(d, "busted device info"); 122 gk20a_err(d, "busted pbmda map");
149 return -EINVAL; 123 return -EINVAL;
124 }
125 info->pbdma_id = pbdma_id;
126
127 info->intr_id =
128 top_device_info_intr_enum_v(table_entry);
129 gk20a_dbg_info("gr info: intr_id %d", info->intr_id);
130
131 info->reset_id =
132 top_device_info_reset_enum_v(table_entry);
133 gk20a_dbg_info("gr info: reset_id %d",
134 info->reset_id);
135
150 } 136 }
151 137
152 return 0; 138 return 0;
153} 139}
154 140
141u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g)
142{
143 u32 eng_intr_mask = 0;
144 int i = 0;
145
146 for (i = 0; i < g->fifo.max_engines; i++) {
147 u32 intr_id = g->fifo.engine_info[i].intr_id;
148
149 if (intr_id)
150 eng_intr_mask |= BIT(intr_id);
151 }
152
153 return eng_intr_mask;
154}
155
155static void gk20a_remove_fifo_support(struct fifo_gk20a *f) 156static void gk20a_remove_fifo_support(struct fifo_gk20a *f)
156{ 157{
157 struct gk20a *g = f->g; 158 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 {
77}; 77};
78 78
79struct fifo_engine_info_gk20a { 79struct fifo_engine_info_gk20a {
80 u32 sw_id;
81 const char *name;
82 u32 dev_info_id;
83 u32 engine_id; 80 u32 engine_id;
84 u32 runlist_id; 81 u32 runlist_id;
82 u32 intr_id;
83 u32 reset_id;
85 u32 pbdma_id; 84 u32 pbdma_id;
86 u32 mmu_fault_id;
87 u32 rc_mask;
88 struct fifo_pbdma_exception_info_gk20a pbdma_exception_info; 85 struct fifo_pbdma_exception_info_gk20a pbdma_exception_info;
89 struct fifo_engine_exception_info_gk20a engine_exception_info; 86 struct fifo_engine_exception_info_gk20a engine_exception_info;
90 struct fifo_mmu_fault_info_gk20a mmu_fault_info; 87 struct fifo_mmu_fault_info_gk20a mmu_fault_info;
@@ -171,4 +168,5 @@ void gk20a_init_fifo(struct gpu_ops *gops);
171void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, 168void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g,
172 unsigned long fault_id); 169 unsigned long fault_id);
173int gk20a_fifo_wait_engine_idle(struct gk20a *g); 170int gk20a_fifo_wait_engine_idle(struct gk20a *g);
171u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g);
174#endif /*__GR_GK20A_H__*/ 172#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)
757 if (err) 757 if (err)
758 goto done; 758 goto done;
759 759
760 enable_irq(g->irq_stall);
761 enable_irq(g->irq_nonstall);
762
763 g->ops.mc.intr_enable(g);
764
765 if (!tegra_platform_is_silicon()) 760 if (!tegra_platform_is_silicon())
766 gk20a_writel(g, bus_intr_en_0_r(), 0x0); 761 gk20a_writel(g, bus_intr_en_0_r(), 0x0);
767 else 762 else
@@ -814,6 +809,14 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
814 goto done; 809 goto done;
815 } 810 }
816 811
812 err = gk20a_init_fifo_support(g);
813 if (err) {
814 gk20a_err(dev, "failed to init gk20a fifo");
815 goto done;
816 }
817
818 g->ops.mc.intr_enable(g);
819
817 err = gk20a_enable_gr_hw(g); 820 err = gk20a_enable_gr_hw(g);
818 if (err) { 821 if (err) {
819 gk20a_err(dev, "failed to enable gr"); 822 gk20a_err(dev, "failed to enable gr");
@@ -833,12 +836,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
833 goto done; 836 goto done;
834 } 837 }
835 838
836 err = gk20a_init_fifo_support(g);
837 if (err) {
838 gk20a_err(dev, "failed to init gk20a fifo");
839 goto done;
840 }
841
842 err = gk20a_init_gr_support(g); 839 err = gk20a_init_gr_support(g);
843 if (err) { 840 if (err) {
844 gk20a_err(dev, "failed to init gk20a gr"); 841 gk20a_err(dev, "failed to init gk20a gr");
@@ -857,7 +854,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
857 goto done; 854 goto done;
858 } 855 }
859 856
860
861 gk20a_channel_resume(g); 857 gk20a_channel_resume(g);
862 set_user_nice(current, nice_value); 858 set_user_nice(current, nice_value);
863 859
@@ -868,6 +864,9 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
868 if (platform->has_cde) 864 if (platform->has_cde)
869 gk20a_init_cde_support(g); 865 gk20a_init_cde_support(g);
870 866
867 enable_irq(g->irq_stall);
868 enable_irq(g->irq_nonstall);
869
871#ifdef CONFIG_INPUT_CFBOOST 870#ifdef CONFIG_INPUT_CFBOOST
872 if (!g->boost_added) { 871 if (!g->boost_added) {
873 gk20a_dbg_info("add touch boost"); 872 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 @@
1/* 1/*
2 * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * 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)
98{ 98{
99 return (r >> 21) & 0xf; 99 return (r >> 21) & 0xf;
100} 100}
101static inline u32 top_device_info_intr_enum_v(u32 r)
102{
103 return (r >> 15) & 0x1f;
104}
105static inline u32 top_device_info_reset_enum_v(u32 r)
106{
107 return (r >> 9) & 0x1f;
108}
101static inline u32 top_device_info_type_enum_v(u32 r) 109static inline u32 top_device_info_type_enum_v(u32 r)
102{ 110{
103 return (r >> 2) & 0x1fffffff; 111 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)
71 71
72 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0); 72 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0);
73 73
74 if (mc_intr_0 & mc_intr_0_pgraph_pending_f()) 74 if (mc_intr_0 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id))
75 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g)); 75 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g));
76 if (mc_intr_0 & mc_intr_0_pfifo_pending_f()) 76 if (mc_intr_0 & mc_intr_0_pfifo_pending_f())
77 gk20a_fifo_isr(g); 77 gk20a_fifo_isr(g);
@@ -105,7 +105,7 @@ irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g)
105 105
106 if (mc_intr_1 & mc_intr_0_pfifo_pending_f()) 106 if (mc_intr_1 & mc_intr_0_pfifo_pending_f())
107 gk20a_fifo_nonstall_isr(g); 107 gk20a_fifo_nonstall_isr(g);
108 if (mc_intr_1 & mc_intr_0_pgraph_pending_f()) 108 if (mc_intr_1 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id))
109 gk20a_gr_nonstall_isr(g); 109 gk20a_gr_nonstall_isr(g);
110 110
111 gk20a_writel(g, mc_intr_en_1_r(), 111 gk20a_writel(g, mc_intr_en_1_r(),
@@ -119,9 +119,20 @@ irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g)
119 119
120void mc_gk20a_intr_enable(struct gk20a *g) 120void mc_gk20a_intr_enable(struct gk20a *g)
121{ 121{
122 u32 eng_intr_mask = gk20a_fifo_engine_interrupt_mask(g);
123
124 gk20a_writel(g, mc_intr_mask_1_r(),
125 mc_intr_0_pfifo_pending_f()
126 | eng_intr_mask);
122 gk20a_writel(g, mc_intr_en_1_r(), 127 gk20a_writel(g, mc_intr_en_1_r(),
123 mc_intr_en_1_inta_hardware_f()); 128 mc_intr_en_1_inta_hardware_f());
124 129
130 gk20a_writel(g, mc_intr_mask_0_r(),
131 mc_intr_0_pfifo_pending_f()
132 | mc_intr_0_priv_ring_pending_f()
133 | mc_intr_0_ltc_pending_f()
134 | mc_intr_0_pbus_pending_f()
135 | eng_intr_mask);
125 gk20a_writel(g, mc_intr_en_0_r(), 136 gk20a_writel(g, mc_intr_en_0_r(),
126 mc_intr_en_0_inta_hardware_f()); 137 mc_intr_en_0_inta_hardware_f());
127} 138}
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)
102{ 102{
103 return (r >> 21) & 0xf; 103 return (r >> 21) & 0xf;
104} 104}
105static inline u32 top_device_info_intr_enum_v(u32 r)
106{
107 return (r >> 15) & 0x1f;
108}
109static inline u32 top_device_info_reset_enum_v(u32 r)
110{
111 return (r >> 9) & 0x1f;
112}
105static inline u32 top_device_info_type_enum_v(u32 r) 113static inline u32 top_device_info_type_enum_v(u32 r)
106{ 114{
107 return (r >> 2) & 0x1fffffff; 115 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)
162 162
163 gr_info = f->engine_info + gr_sw_id; 163 gr_info = f->engine_info + gr_sw_id;
164 164
165 gr_info->sw_id = gr_sw_id;
166 gr_info->name = "gr";
167 /* FIXME: retrieve this from server */ 165 /* FIXME: retrieve this from server */
168 gr_info->runlist_id = 0; 166 gr_info->runlist_id = 0;
169 return 0; 167 return 0;