diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 76 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 1 |
6 files changed, 51 insertions, 33 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 6056f558..4cce7260 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -1953,7 +1953,7 @@ clean_up: | |||
1953 | return ret; | 1953 | return ret; |
1954 | } | 1954 | } |
1955 | 1955 | ||
1956 | void gk20a_init_fifo(struct gpu_ops *gops) | 1956 | void gk20a_init_channel(struct gpu_ops *gops) |
1957 | { | 1957 | { |
1958 | gops->fifo.bind_channel = channel_gk20a_bind; | 1958 | gops->fifo.bind_channel = channel_gk20a_bind; |
1959 | } | 1959 | } |
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 429db85d..47fc714c 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h | |||
@@ -167,6 +167,6 @@ int gk20a_channel_release(struct inode *inode, struct file *filp); | |||
167 | struct channel_gk20a *gk20a_get_channel_from_file(int fd); | 167 | struct channel_gk20a *gk20a_get_channel_from_file(int fd); |
168 | void gk20a_channel_update(struct channel_gk20a *c, int nr_completed); | 168 | void gk20a_channel_update(struct channel_gk20a *c, int nr_completed); |
169 | 169 | ||
170 | void gk20a_init_fifo(struct gpu_ops *gops); | 170 | void gk20a_init_channel(struct gpu_ops *gops); |
171 | 171 | ||
172 | #endif /*__CHANNEL_GK20A_H__*/ | 172 | #endif /*__CHANNEL_GK20A_H__*/ |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 5575b995..f1987ed5 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -1092,43 +1092,15 @@ static void gk20a_fifo_get_faulty_channel(struct gk20a *g, int engine_id, | |||
1092 | fifo_engine_status_id_v(status); | 1092 | fifo_engine_status_id_v(status); |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, | 1095 | static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, |
1096 | bool verbose) | 1096 | unsigned long engine_ids) |
1097 | { | 1097 | { |
1098 | unsigned long end_jiffies = jiffies + | 1098 | unsigned long end_jiffies = jiffies + |
1099 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | 1099 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); |
1100 | unsigned long delay = GR_IDLE_CHECK_DEFAULT; | 1100 | unsigned long delay = GR_IDLE_CHECK_DEFAULT; |
1101 | unsigned long engine_id, i; | 1101 | unsigned long engine_id; |
1102 | unsigned long _engine_ids = __engine_ids; | ||
1103 | unsigned long engine_ids = 0; | ||
1104 | int ret; | 1102 | int ret; |
1105 | 1103 | ||
1106 | if (verbose) | ||
1107 | gk20a_debug_dump(g->dev); | ||
1108 | |||
1109 | /* store faulted engines in advance */ | ||
1110 | g->fifo.mmu_fault_engines = 0; | ||
1111 | for_each_set_bit(engine_id, &_engine_ids, 32) { | ||
1112 | bool ref_type_ch; | ||
1113 | int ref_chid; | ||
1114 | gk20a_fifo_get_faulty_channel(g, engine_id, &ref_chid, | ||
1115 | &ref_type_ch); | ||
1116 | |||
1117 | /* Reset *all* engines that use the | ||
1118 | * same channel as faulty engine */ | ||
1119 | for (i = 0; i < g->fifo.max_engines; i++) { | ||
1120 | bool type_ch; | ||
1121 | u32 chid; | ||
1122 | gk20a_fifo_get_faulty_channel(g, i, &chid, &type_ch); | ||
1123 | if (ref_type_ch == type_ch && ref_chid == chid) { | ||
1124 | engine_ids |= BIT(i); | ||
1125 | g->fifo.mmu_fault_engines |= | ||
1126 | BIT(gk20a_engine_id_to_mmu_id(i)); | ||
1127 | } | ||
1128 | } | ||
1129 | |||
1130 | } | ||
1131 | |||
1132 | /* trigger faults for all bad engines */ | 1104 | /* trigger faults for all bad engines */ |
1133 | for_each_set_bit(engine_id, &engine_ids, 32) { | 1105 | for_each_set_bit(engine_id, &engine_ids, 32) { |
1134 | if (engine_id > g->fifo.max_engines) { | 1106 | if (engine_id > g->fifo.max_engines) { |
@@ -1164,6 +1136,42 @@ void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, | |||
1164 | gk20a_writel(g, fifo_trigger_mmu_fault_r(engine_id), 0); | 1136 | gk20a_writel(g, fifo_trigger_mmu_fault_r(engine_id), 0); |
1165 | } | 1137 | } |
1166 | 1138 | ||
1139 | void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, | ||
1140 | bool verbose) | ||
1141 | { | ||
1142 | unsigned long engine_id, i; | ||
1143 | unsigned long _engine_ids = __engine_ids; | ||
1144 | unsigned long engine_ids = 0; | ||
1145 | |||
1146 | if (verbose) | ||
1147 | gk20a_debug_dump(g->dev); | ||
1148 | |||
1149 | /* store faulted engines in advance */ | ||
1150 | g->fifo.mmu_fault_engines = 0; | ||
1151 | for_each_set_bit(engine_id, &_engine_ids, 32) { | ||
1152 | bool ref_type_ch; | ||
1153 | int ref_chid; | ||
1154 | gk20a_fifo_get_faulty_channel(g, engine_id, &ref_chid, | ||
1155 | &ref_type_ch); | ||
1156 | |||
1157 | /* Reset *all* engines that use the | ||
1158 | * same channel as faulty engine */ | ||
1159 | for (i = 0; i < g->fifo.max_engines; i++) { | ||
1160 | bool type_ch; | ||
1161 | u32 chid; | ||
1162 | gk20a_fifo_get_faulty_channel(g, i, &chid, &type_ch); | ||
1163 | if (ref_type_ch == type_ch && ref_chid == chid) { | ||
1164 | engine_ids |= BIT(i); | ||
1165 | g->fifo.mmu_fault_engines |= | ||
1166 | BIT(gk20a_engine_id_to_mmu_id(i)); | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | } | ||
1171 | |||
1172 | g->ops.fifo.trigger_mmu_fault(g, engine_ids); | ||
1173 | } | ||
1174 | |||
1167 | 1175 | ||
1168 | static bool gk20a_fifo_handle_sched_error(struct gk20a *g) | 1176 | static bool gk20a_fifo_handle_sched_error(struct gk20a *g) |
1169 | { | 1177 | { |
@@ -1834,3 +1842,9 @@ bool gk20a_fifo_mmu_fault_pending(struct gk20a *g) | |||
1834 | else | 1842 | else |
1835 | return false; | 1843 | return false; |
1836 | } | 1844 | } |
1845 | |||
1846 | void gk20a_init_fifo(struct gpu_ops *gops) | ||
1847 | { | ||
1848 | gk20a_init_channel(gops); | ||
1849 | gops->fifo.trigger_mmu_fault = gk20a_fifo_trigger_mmu_fault; | ||
1850 | } | ||
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 051acda2..078ae8f0 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -158,6 +158,7 @@ int gk20a_fifo_suspend(struct gk20a *g); | |||
158 | bool gk20a_fifo_mmu_fault_pending(struct gk20a *g); | 158 | bool gk20a_fifo_mmu_fault_pending(struct gk20a *g); |
159 | void gk20a_fifo_recover(struct gk20a *g, u32 engine_ids, bool verbose); | 159 | void gk20a_fifo_recover(struct gk20a *g, u32 engine_ids, bool verbose); |
160 | int gk20a_init_fifo_reset_enable_hw(struct gk20a *g); | 160 | int gk20a_init_fifo_reset_enable_hw(struct gk20a *g); |
161 | void gk20a_init_fifo(struct gpu_ops *gops); | ||
161 | 162 | ||
162 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, | 163 | void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, |
163 | unsigned long fault_id); | 164 | unsigned long fault_id); |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 7aca186e..7aa10692 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -137,6 +137,8 @@ struct gpu_ops { | |||
137 | } clock_gating; | 137 | } clock_gating; |
138 | struct { | 138 | struct { |
139 | void (*bind_channel)(struct channel_gk20a *ch_gk20a); | 139 | void (*bind_channel)(struct channel_gk20a *ch_gk20a); |
140 | void (*trigger_mmu_fault)(struct gk20a *g, | ||
141 | unsigned long engine_ids); | ||
140 | } fifo; | 142 | } fifo; |
141 | struct pmu_v { | 143 | struct pmu_v { |
142 | /*used for change of enum zbc update cmd id from ver 0 to ver1*/ | 144 | /*used for change of enum zbc update cmd id from ver 0 to ver1*/ |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index ced1f62f..b2a92f81 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -5333,6 +5333,7 @@ int gk20a_gr_isr(struct gk20a *g) | |||
5333 | u32 fe = gk20a_readl(g, gr_fe_hww_esr_r()); | 5333 | u32 fe = gk20a_readl(g, gr_fe_hww_esr_r()); |
5334 | gk20a_dbg(gpu_dbg_intr, "fe warning %08x\n", fe); | 5334 | gk20a_dbg(gpu_dbg_intr, "fe warning %08x\n", fe); |
5335 | gk20a_writel(g, gr_fe_hww_esr_r(), fe); | 5335 | gk20a_writel(g, gr_fe_hww_esr_r(), fe); |
5336 | need_reset |= -EFAULT; | ||
5336 | } | 5337 | } |
5337 | 5338 | ||
5338 | /* check if a gpc exception has occurred */ | 5339 | /* check if a gpc exception has occurred */ |