summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
diff options
context:
space:
mode:
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}