summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2016-05-13 10:56:43 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-05-18 11:15:11 -0400
commit67a41e46a230cde7353e4cd46040f1e71d7cd289 (patch)
tree0697ce5ba224db6a92cdab0b192a8069f669be63 /drivers/gpu/nvgpu/gk20a
parent8f48afe26bc39fd7508646e8c3ea6bfeb665beae (diff)
gpu: nvgpu: Read all fields of device_info
We were not using the engine_type field in device info, and the code did not handle chained entries properly. The code assumed that first entry is for graphics and second for CE, which is not always true. Improve the code to go through all entries of device_info, and preserve values across entries until we reach the last entry. Only last entry triggers a write to fifo engine info. There can also be multiple engines with same type, so accumulate interrupts and reset ids from all of them. As the code got fixed, now it reads the engine enum correctly from hardware. We used to compare that against CE0, but we should compare against CE2. gk20a_fifo_reset_engine() uses wrong constants - it is passed a internal numbering of engines, but it compares them against hardware engine enum. Change-Id: Ia59273921c602d2a090f7a5b1404afb0fca2532c Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1147746 Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c116
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h5
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h30
-rw-r--r--drivers/gpu/nvgpu/gk20a/mc_gk20a.c8
5 files changed, 108 insertions, 52 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index cdbb4a6c..6ee73ffe 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -68,6 +68,20 @@ static inline u32 gk20a_mmu_id_to_engine_id(u32 engine_id)
68 } 68 }
69} 69}
70 70
71int gk20a_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type)
72{
73 int ret = ENGINE_INVAL_GK20A;
74
75 gk20a_dbg_info("engine type %d", engine_type);
76 if (engine_type == top_device_info_type_enum_graphics_v())
77 ret = ENGINE_GR_GK20A;
78 else if (engine_type == top_device_info_type_enum_copy2_v())
79 ret = ENGINE_CE2_GK20A;
80 else
81 gk20a_err(g->dev, "unknown engine %d", engine_type);
82
83 return ret;
84}
71 85
72static int init_engine_info(struct fifo_gk20a *f) 86static int init_engine_info(struct fifo_gk20a *f)
73{ 87{
@@ -75,6 +89,12 @@ static int init_engine_info(struct fifo_gk20a *f)
75 struct device *d = dev_from_gk20a(g); 89 struct device *d = dev_from_gk20a(g);
76 u32 i; 90 u32 i;
77 u32 max_info_entries = top_device_info__size_1_v(); 91 u32 max_info_entries = top_device_info__size_1_v();
92 u32 engine_enum = ENGINE_INVAL_GK20A;
93 u32 engine_id = ~0;
94 u32 runlist_id = ~0;
95 u32 pbdma_id = ~0;
96 u32 intr_id = ~0;
97 u32 reset_id = ~0;
78 98
79 gk20a_dbg_fn(""); 99 gk20a_dbg_fn("");
80 100
@@ -83,57 +103,71 @@ static int init_engine_info(struct fifo_gk20a *f)
83 f->num_engines = 2; 103 f->num_engines = 2;
84 104
85 for (i = 0; i < max_info_entries; i++) { 105 for (i = 0; i < max_info_entries; i++) {
86 struct fifo_engine_info_gk20a *info = NULL;
87 u32 table_entry = gk20a_readl(f->g, top_device_info_r(i)); 106 u32 table_entry = gk20a_readl(f->g, top_device_info_r(i));
88 u32 entry = top_device_info_entry_v(table_entry); 107 u32 entry = top_device_info_entry_v(table_entry);
89 u32 engine_enum;
90 int pbdma_id;
91 u32 runlist_bit; 108 u32 runlist_bit;
92 109
93 if (entry != top_device_info_entry_enum_v()) 110 if (entry == top_device_info_entry_enum_v()) {
94 continue; 111 if (top_device_info_engine_v(table_entry)) {
112 engine_id =
113 top_device_info_engine_enum_v(table_entry);
114 gk20a_dbg_info("info: engine_id %d",
115 top_device_info_engine_enum_v(table_entry));
116 }
95 117
96 /* we only care about GR engine here */
97 engine_enum = top_device_info_engine_enum_v(table_entry);
98 if (engine_enum >= ENGINE_INVAL_GK20A)
99 continue;
100 118
101 gk20a_dbg_info("info: engine_id %d", 119 if (top_device_info_runlist_v(table_entry)) {
102 top_device_info_engine_enum_v(table_entry)); 120 runlist_id =
103 info = &g->fifo.engine_info[engine_enum]; 121 top_device_info_runlist_enum_v(table_entry);
122 gk20a_dbg_info("gr info: runlist_id %d", runlist_id);
104 123
105 info->runlist_id = 124 runlist_bit = BIT(runlist_id);
106 top_device_info_runlist_enum_v(table_entry);
107 gk20a_dbg_info("gr info: runlist_id %d", info->runlist_id);
108 125
109 info->engine_id = 126 for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) {
110 top_device_info_engine_enum_v(table_entry); 127 gk20a_dbg_info("gr info: pbdma_map[%d]=%d",
111 gk20a_dbg_info("gr info: engine_id %d", info->engine_id); 128 pbdma_id, f->pbdma_map[pbdma_id]);
129 if (f->pbdma_map[pbdma_id] & runlist_bit)
130 break;
131 }
112 132
113 runlist_bit = 1 << info->runlist_id; 133 if (pbdma_id == f->num_pbdma) {
134 gk20a_err(d, "busted pbdma map");
135 return -EINVAL;
136 }
137 }
114 138
115 for (pbdma_id = 0; pbdma_id < f->num_pbdma; pbdma_id++) { 139 if (top_device_info_intr_v(table_entry)) {
116 gk20a_dbg_info("gr info: pbdma_map[%d]=%d", 140 intr_id =
117 pbdma_id, f->pbdma_map[pbdma_id]); 141 top_device_info_intr_enum_v(table_entry);
118 if (f->pbdma_map[pbdma_id] & runlist_bit) 142 gk20a_dbg_info("gr info: intr_id %d", intr_id);
119 break; 143 }
120 }
121 144
122 if (pbdma_id == f->num_pbdma) { 145 if (top_device_info_reset_v(table_entry)) {
123 gk20a_err(d, "busted pbmda map"); 146 reset_id =
124 return -EINVAL; 147 top_device_info_reset_enum_v(table_entry);
148 gk20a_dbg_info("gr info: reset_id %d",
149 reset_id);
150 }
151 } else if (entry == top_device_info_entry_engine_type_v()) {
152 u32 engine_type =
153 top_device_info_type_enum_v(table_entry);
154 engine_enum =
155 g->ops.fifo.engine_enum_from_type(g, engine_type);
125 } 156 }
126 info->pbdma_id = pbdma_id;
127 157
128 info->intr_id = 158 if (!top_device_info_chain_v(table_entry)) {
129 top_device_info_intr_enum_v(table_entry); 159 if (engine_enum < ENGINE_INVAL_GK20A) {
130 gk20a_dbg_info("gr info: intr_id %d", info->intr_id); 160 struct fifo_engine_info_gk20a *info =
161 &g->fifo.engine_info[engine_enum];
131 162
132 info->reset_id = 163 info->intr_mask |= BIT(intr_id);
133 top_device_info_reset_enum_v(table_entry); 164 info->reset_mask |= BIT(reset_id);
134 gk20a_dbg_info("gr info: reset_id %d", 165 info->runlist_id = runlist_id;
135 info->reset_id); 166 info->pbdma_id = pbdma_id;
136 167
168 engine_enum = ENGINE_INVAL_GK20A;
169 }
170 }
137 } 171 }
138 172
139 return 0; 173 return 0;
@@ -145,13 +179,12 @@ u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g)
145 int i = 0; 179 int i = 0;
146 180
147 for (i = 0; i < g->fifo.max_engines; i++) { 181 for (i = 0; i < g->fifo.max_engines; i++) {
148 u32 intr_id = g->fifo.engine_info[i].intr_id; 182 u32 intr_mask = g->fifo.engine_info[i].intr_mask;
149 if (i == ENGINE_CE2_GK20A && 183 if (i == ENGINE_CE2_GK20A &&
150 (!g->ops.ce2.isr_stall || !g->ops.ce2.isr_nonstall)) 184 (!g->ops.ce2.isr_stall || !g->ops.ce2.isr_nonstall))
151 continue; 185 continue;
152 186
153 if (intr_id) 187 eng_intr_mask |= intr_mask;
154 eng_intr_mask |= BIT(intr_id);
155 } 188 }
156 189
157 return eng_intr_mask; 190 return eng_intr_mask;
@@ -771,7 +804,7 @@ void gk20a_fifo_reset_engine(struct gk20a *g, u32 engine_id)
771{ 804{
772 gk20a_dbg_fn(""); 805 gk20a_dbg_fn("");
773 806
774 if (engine_id == top_device_info_type_enum_graphics_v()) { 807 if (engine_id == ENGINE_GR_GK20A) {
775 if (support_gk20a_pmu(g->dev) && g->elpg_enabled) 808 if (support_gk20a_pmu(g->dev) && g->elpg_enabled)
776 gk20a_pmu_disable_elpg(g); 809 gk20a_pmu_disable_elpg(g);
777 /*HALT_PIPELINE method, halt GR engine*/ 810 /*HALT_PIPELINE method, halt GR engine*/
@@ -788,7 +821,7 @@ void gk20a_fifo_reset_engine(struct gk20a *g, u32 engine_id)
788 if (support_gk20a_pmu(g->dev) && g->elpg_enabled) 821 if (support_gk20a_pmu(g->dev) && g->elpg_enabled)
789 gk20a_pmu_enable_elpg(g); 822 gk20a_pmu_enable_elpg(g);
790 } 823 }
791 if (engine_id == top_device_info_type_enum_copy0_v()) 824 if (engine_id == ENGINE_CE2_GK20A)
792 gk20a_reset(g, mc_enable_ce2_m()); 825 gk20a_reset(g, mc_enable_ce2_m());
793} 826}
794 827
@@ -2694,4 +2727,5 @@ void gk20a_init_fifo(struct gpu_ops *gops)
2694 gops->fifo.get_pbdma_signature = gk20a_fifo_get_pbdma_signature; 2727 gops->fifo.get_pbdma_signature = gk20a_fifo_get_pbdma_signature;
2695 gops->fifo.set_runlist_interleave = gk20a_fifo_set_runlist_interleave; 2728 gops->fifo.set_runlist_interleave = gk20a_fifo_set_runlist_interleave;
2696 gops->fifo.force_reset_ch = gk20a_fifo_force_reset_ch; 2729 gops->fifo.force_reset_ch = gk20a_fifo_force_reset_ch;
2730 gops->fifo.engine_enum_from_type = gk20a_fifo_engine_enum_from_type;
2697} 2731}
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
index c95ba71c..e795eba0 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
@@ -79,8 +79,8 @@ struct fifo_mmu_fault_info_gk20a {
79struct fifo_engine_info_gk20a { 79struct fifo_engine_info_gk20a {
80 u32 engine_id; 80 u32 engine_id;
81 u32 runlist_id; 81 u32 runlist_id;
82 u32 intr_id; 82 u32 intr_mask;
83 u32 reset_id; 83 u32 reset_mask;
84 u32 pbdma_id; 84 u32 pbdma_id;
85 struct fifo_pbdma_exception_info_gk20a pbdma_exception_info; 85 struct fifo_pbdma_exception_info_gk20a pbdma_exception_info;
86 struct fifo_engine_exception_info_gk20a engine_exception_info; 86 struct fifo_engine_exception_info_gk20a engine_exception_info;
@@ -222,5 +222,6 @@ void gk20a_fifo_debugfs_init(struct device *dev);
222 222
223const char *gk20a_fifo_interleave_level_name(u32 interleave_level); 223const char *gk20a_fifo_interleave_level_name(u32 interleave_level);
224 224
225int gk20a_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type);
225 226
226#endif /*__GR_GK20A_H__*/ 227#endif /*__GR_GK20A_H__*/
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 5d06a441..d5310b02 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -330,6 +330,7 @@ struct gpu_ops {
330 int (*channel_set_timeslice)(struct channel_gk20a *ch, 330 int (*channel_set_timeslice)(struct channel_gk20a *ch,
331 u32 timeslice); 331 u32 timeslice);
332 int (*force_reset_ch)(struct channel_gk20a *ch, bool verbose); 332 int (*force_reset_ch)(struct channel_gk20a *ch, bool verbose);
333 int (*engine_enum_from_type)(struct gk20a *g, u32 engine_type);
333 } fifo; 334 } fifo;
334 struct pmu_v { 335 struct pmu_v {
335 /*used for change of enum zbc update cmd id from ver 0 to ver1*/ 336 /*used for change of enum zbc update cmd id from ver 0 to ver1*/
diff --git a/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_top_gk20a.h
index 35d9d347..6981cf71 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-2015, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2012-2016, 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,
@@ -118,13 +118,29 @@ static inline u32 top_device_info_type_enum_graphics_f(void)
118{ 118{
119 return 0x0; 119 return 0x0;
120} 120}
121static inline u32 top_device_info_type_enum_copy0_v(void) 121static inline u32 top_device_info_type_enum_copy2_v(void)
122{ 122{
123 return 0x00000001; 123 return 0x00000003;
124}
125static inline u32 top_device_info_type_enum_copy2_f(void)
126{
127 return 0xc;
124} 128}
125static inline u32 top_device_info_type_enum_copy0_f(void) 129static inline u32 top_device_info_engine_v(u32 r)
126{ 130{
127 return 0x4; 131 return (r >> 5) & 0x1;
132}
133static inline u32 top_device_info_runlist_v(u32 r)
134{
135 return (r >> 4) & 0x1;
136}
137static inline u32 top_device_info_intr_v(u32 r)
138{
139 return (r >> 3) & 0x1;
140}
141static inline u32 top_device_info_reset_v(u32 r)
142{
143 return (r >> 2) & 0x1;
128} 144}
129static inline u32 top_device_info_entry_v(u32 r) 145static inline u32 top_device_info_entry_v(u32 r)
130{ 146{
@@ -138,6 +154,10 @@ static inline u32 top_device_info_entry_enum_v(void)
138{ 154{
139 return 0x00000002; 155 return 0x00000002;
140} 156}
157static inline u32 top_device_info_entry_engine_type_v(void)
158{
159 return 0x00000003;
160}
141static inline u32 top_fs_status_fbp_r(void) 161static inline u32 top_fs_status_fbp_r(void)
142{ 162{
143 return 0x00022548; 163 return 0x00022548;
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
index fe6448c9..70da7a02 100644
--- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
@@ -84,9 +84,9 @@ irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g)
84 84
85 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0); 85 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0);
86 86
87 if (mc_intr_0 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id)) 87 if (mc_intr_0 & g->fifo.engine_info[ENGINE_GR_GK20A].intr_mask)
88 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g)); 88 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g));
89 if (mc_intr_0 & BIT(g->fifo.engine_info[ENGINE_CE2_GK20A].intr_id) 89 if (mc_intr_0 & g->fifo.engine_info[ENGINE_CE2_GK20A].intr_mask
90 && g->ops.ce2.isr_stall) 90 && g->ops.ce2.isr_stall)
91 g->ops.ce2.isr_stall(g); 91 g->ops.ce2.isr_stall(g);
92 if (mc_intr_0 & mc_intr_0_pfifo_pending_f()) 92 if (mc_intr_0 & mc_intr_0_pfifo_pending_f())
@@ -132,9 +132,9 @@ irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g)
132 gk20a_fifo_nonstall_isr(g); 132 gk20a_fifo_nonstall_isr(g);
133 if (mc_intr_1 & mc_intr_0_priv_ring_pending_f()) 133 if (mc_intr_1 & mc_intr_0_priv_ring_pending_f())
134 gk20a_priv_ring_isr(g); 134 gk20a_priv_ring_isr(g);
135 if (mc_intr_1 & BIT(g->fifo.engine_info[ENGINE_GR_GK20A].intr_id)) 135 if (mc_intr_1 & g->fifo.engine_info[ENGINE_GR_GK20A].intr_mask)
136 gk20a_gr_nonstall_isr(g); 136 gk20a_gr_nonstall_isr(g);
137 if (mc_intr_1 & BIT(g->fifo.engine_info[ENGINE_CE2_GK20A].intr_id) 137 if (mc_intr_1 & g->fifo.engine_info[ENGINE_CE2_GK20A].intr_mask
138 && g->ops.ce2.isr_nonstall) 138 && g->ops.ce2.isr_nonstall)
139 g->ops.ce2.isr_nonstall(g); 139 g->ops.ce2.isr_nonstall(g);
140 140