summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a.h
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2016-11-07 19:12:45 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-01-04 18:53:55 -0500
commita0242464f5f12d9f10fbf0d05614bfadde84386c (patch)
tree2f5981f5b9e90811c675ef59e2d1ca10e440c0ed /drivers/gpu/nvgpu/gk20a/gk20a.h
parentb82d27e38490dc1155ece7d433fbcb6713b5a53b (diff)
gpu: nvgpu: Handle no GPU cases in helper funcs
In many helper functions like gk20a_readl() the code assumed that the GPU is present and registers and available. However, during GPU shutdown this may not be the case. In theory the driver should not be accessing GPU registers during GPU shutdown (since shutdown is triggered by GPU registers being unavailable) but these changes handle any missed cases where this may happen. This goes for GPU device access as well. Many parts of the code assume that if the struct gk20a is valid, the the GPU dev must be there are well. This isn't always the case, it seems. Bug 1816516 Bug 1807277 Change-Id: Icaf6fd56ab7860724e77bda0f5e8d48f0da15642 Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1250024 (cherry picked from commit e8c9997b2d7cd424d798ecfce1307e6193c0cf32) Reviewed-on: http://git-master/r/1274473 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.h')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h82
1 files changed, 61 insertions, 21 deletions
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);
1126int gk20a_restore_registers(struct gk20a *g); 1133int gk20a_restore_registers(struct gk20a *g);
1127 1134
1128void __nvgpu_check_gpu_state(struct gk20a *g); 1135void __nvgpu_check_gpu_state(struct gk20a *g);
1136void __gk20a_warn_on_no_regs(void);
1129 1137
1130static inline void gk20a_writel(struct gk20a *g, u32 r, u32 v) 1138static 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}
1136static inline u32 gk20a_readl(struct gk20a *g, u32 r) 1149static 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}
1147static inline void gk20a_writel_check(struct gk20a *g, u32 r, u32 v) 1166static 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
1156static inline void gk20a_bar1_writel(struct gk20a *g, u32 b, u32 v) 1180static 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
1163static inline u32 gk20a_bar1_readl(struct gk20a *g, u32 b) 1192static 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}
1175static inline struct gk20a *gk20a_from_dev(struct device *dev) 1212static 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}
1179static inline struct gk20a *gk20a_from_as(struct gk20a_as *as) 1219static inline struct gk20a *gk20a_from_as(struct gk20a_as *as)