summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
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/fifo_gk20a.c
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/fifo_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c116
1 files changed, 75 insertions, 41 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}