diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 82 |
2 files changed, 66 insertions, 21 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 5e56fc81..a65ca6c2 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -309,6 +309,11 @@ int gk20a_restore_registers(struct gk20a *g) | |||
309 | return 0; | 309 | return 0; |
310 | } | 310 | } |
311 | 311 | ||
312 | void __gk20a_warn_on_no_regs(void) | ||
313 | { | ||
314 | WARN_ONCE(1, "Attempted access to GPU regs after unmapping!"); | ||
315 | } | ||
316 | |||
312 | static void kunmap_and_free_iopage(void **kvaddr, struct page **page) | 317 | static void kunmap_and_free_iopage(void **kvaddr, struct page **page) |
313 | { | 318 | { |
314 | if (*kvaddr) { | 319 | if (*kvaddr) { |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index d219b815..eab9843a 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -1107,11 +1107,18 @@ do { \ | |||
1107 | 1107 | ||
1108 | #endif | 1108 | #endif |
1109 | 1109 | ||
1110 | #define gk20a_err(d, fmt, arg...) \ | 1110 | #define gk20a_err(d, fmt, arg...) \ |
1111 | dev_err(d, "%s: " fmt "\n", __func__, ##arg) | 1111 | do { \ |
1112 | if (d) \ | ||
1113 | dev_err(d, "%s: " fmt "\n", __func__, ##arg); \ | ||
1114 | } while (0) | ||
1115 | |||
1116 | #define gk20a_warn(d, fmt, arg...) \ | ||
1117 | do { \ | ||
1118 | if (d) \ | ||
1119 | dev_warn(d, "%s: " fmt "\n", __func__, ##arg); \ | ||
1120 | } while (0) | ||
1112 | 1121 | ||
1113 | #define gk20a_warn(d, fmt, arg...) \ | ||
1114 | dev_warn(d, "%s: " fmt "\n", __func__, ##arg) | ||
1115 | 1122 | ||
1116 | #define gk20a_dbg_fn(fmt, arg...) \ | 1123 | #define gk20a_dbg_fn(fmt, arg...) \ |
1117 | gk20a_dbg(gpu_dbg_fn, fmt, ##arg) | 1124 | gk20a_dbg(gpu_dbg_fn, fmt, ##arg) |
@@ -1126,44 +1133,74 @@ int gk20a_lockout_registers(struct gk20a *g); | |||
1126 | int gk20a_restore_registers(struct gk20a *g); | 1133 | int gk20a_restore_registers(struct gk20a *g); |
1127 | 1134 | ||
1128 | void __nvgpu_check_gpu_state(struct gk20a *g); | 1135 | void __nvgpu_check_gpu_state(struct gk20a *g); |
1136 | void __gk20a_warn_on_no_regs(void); | ||
1129 | 1137 | ||
1130 | static inline void gk20a_writel(struct gk20a *g, u32 r, u32 v) | 1138 | static inline void gk20a_writel(struct gk20a *g, u32 r, u32 v) |
1131 | { | 1139 | { |
1132 | gk20a_dbg(gpu_dbg_reg, " r=0x%x v=0x%x", r, v); | 1140 | if (unlikely(!g->regs)) { |
1133 | writel_relaxed(v, g->regs + r); | 1141 | __gk20a_warn_on_no_regs(); |
1134 | wmb(); | 1142 | gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); |
1143 | } else { | ||
1144 | writel_relaxed(v, g->regs + r); | ||
1145 | wmb(); | ||
1146 | gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v); | ||
1147 | } | ||
1135 | } | 1148 | } |
1136 | static inline u32 gk20a_readl(struct gk20a *g, u32 r) | 1149 | static inline u32 gk20a_readl(struct gk20a *g, u32 r) |
1137 | { | 1150 | { |
1138 | u32 v = readl(g->regs + r); | ||
1139 | 1151 | ||
1140 | if (v == 0xffffffff) | 1152 | u32 v = 0xffffffff; |
1141 | __nvgpu_check_gpu_state(g); | ||
1142 | 1153 | ||
1143 | gk20a_dbg(gpu_dbg_reg, " r=0x%x v=0x%x", r, v); | 1154 | if (unlikely(!g->regs)) { |
1155 | __gk20a_warn_on_no_regs(); | ||
1156 | gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); | ||
1157 | } else { | ||
1158 | v = readl(g->regs + r); | ||
1159 | if (v == 0xffffffff) | ||
1160 | __nvgpu_check_gpu_state(g); | ||
1161 | gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v); | ||
1162 | } | ||
1144 | 1163 | ||
1145 | return v; | 1164 | return v; |
1146 | } | 1165 | } |
1147 | static inline void gk20a_writel_check(struct gk20a *g, u32 r, u32 v) | 1166 | static inline void gk20a_writel_check(struct gk20a *g, u32 r, u32 v) |
1148 | { | 1167 | { |
1149 | gk20a_dbg(gpu_dbg_reg, " r=0x%x v=0x%x", r, v); | 1168 | if (unlikely(!g->regs)) { |
1150 | wmb(); | 1169 | __gk20a_warn_on_no_regs(); |
1151 | do { | 1170 | gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); |
1152 | writel_relaxed(v, g->regs + r); | 1171 | } else { |
1153 | } while (readl(g->regs + r) != v); | 1172 | wmb(); |
1173 | do { | ||
1174 | writel_relaxed(v, g->regs + r); | ||
1175 | } while (readl(g->regs + r) != v); | ||
1176 | gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v); | ||
1177 | } | ||
1154 | } | 1178 | } |
1155 | 1179 | ||
1156 | static inline void gk20a_bar1_writel(struct gk20a *g, u32 b, u32 v) | 1180 | static inline void gk20a_bar1_writel(struct gk20a *g, u32 b, u32 v) |
1157 | { | 1181 | { |
1158 | gk20a_dbg(gpu_dbg_reg, " b=0x%x v=0x%x", b, v); | 1182 | if (unlikely(!g->bar1)) { |
1159 | wmb(); | 1183 | __gk20a_warn_on_no_regs(); |
1160 | writel_relaxed(v, g->bar1 + b); | 1184 | gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v); |
1185 | } else { | ||
1186 | wmb(); | ||
1187 | writel_relaxed(v, g->bar1 + b); | ||
1188 | gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x", b, v); | ||
1189 | } | ||
1161 | } | 1190 | } |
1162 | 1191 | ||
1163 | static inline u32 gk20a_bar1_readl(struct gk20a *g, u32 b) | 1192 | static inline u32 gk20a_bar1_readl(struct gk20a *g, u32 b) |
1164 | { | 1193 | { |
1165 | u32 v = readl(g->bar1 + b); | 1194 | u32 v = 0xffffffff; |
1166 | gk20a_dbg(gpu_dbg_reg, " b=0x%x v=0x%x", b, v); | 1195 | |
1196 | if (unlikely(!g->bar1)) { | ||
1197 | __gk20a_warn_on_no_regs(); | ||
1198 | gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v); | ||
1199 | } else { | ||
1200 | v = readl(g->bar1 + b); | ||
1201 | gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x", b, v); | ||
1202 | } | ||
1203 | |||
1167 | return v; | 1204 | return v; |
1168 | } | 1205 | } |
1169 | 1206 | ||
@@ -1174,6 +1211,9 @@ static inline struct device *dev_from_gk20a(struct gk20a *g) | |||
1174 | } | 1211 | } |
1175 | static inline struct gk20a *gk20a_from_dev(struct device *dev) | 1212 | static inline struct gk20a *gk20a_from_dev(struct device *dev) |
1176 | { | 1213 | { |
1214 | if (!dev) | ||
1215 | return NULL; | ||
1216 | |||
1177 | return ((struct gk20a_platform *)dev_get_drvdata(dev))->g; | 1217 | return ((struct gk20a_platform *)dev_get_drvdata(dev))->g; |
1178 | } | 1218 | } |
1179 | static inline struct gk20a *gk20a_from_as(struct gk20a_as *as) | 1219 | static inline struct gk20a *gk20a_from_as(struct gk20a_as *as) |