summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a.c
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2014-05-23 16:29:53 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:22 -0400
commit0f9bf924b2be88502c9920ace258c27e0172e3d5 (patch)
tree0bf75c22af5d5e5f8e4fe0396b8c48529352e63a /drivers/gpu/nvgpu/gk20a/gk20a.c
parente2638d73fd56f9a93c44839ebd61d6ba58c40dd8 (diff)
gpu: nvgpu: Remove GPU MMIO access on power/rail gate
This is to weed out accesses to the GPU while it is gated. Otherwise the accesses are silently dropped or cause a HW hang (on older chips). Bug 1514949 Change-Id: Ice4cdb9f1f736978ebb3db847f39c7439bf98134 Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/416339 Reviewed-by: Mitch Luban <mluban@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 2310b81c..c72b8735 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -164,6 +164,32 @@ static inline u32 sim_readl(struct gk20a *g, u32 r)
164 return readl(g->sim.regs+r); 164 return readl(g->sim.regs+r);
165} 165}
166 166
167/*
168 * Locks out the driver from accessing GPU registers. This prevents access to
169 * thse registers after the GPU has been clock or power gated. This should help
170 * find annoying bugs where register reads and writes are silently dropped
171 * after the GPU has been turned off. On older chips these reads and writes can
172 * also lock the entire CPU up.
173 */
174int gk20a_lockout_registers(struct gk20a *g)
175{
176 g->regs = NULL;
177 g->bar1 = NULL;
178
179 return 0;
180}
181
182/*
183 * Undoes gk20a_lockout_registers().
184 */
185int gk20a_restore_registers(struct gk20a *g)
186{
187 g->regs = g->regs_saved;
188 g->bar1 = g->bar1_saved;
189
190 return 0;
191}
192
167static void kunmap_and_free_iopage(void **kvaddr, struct page **page) 193static void kunmap_and_free_iopage(void **kvaddr, struct page **page)
168{ 194{
169 if (*kvaddr) { 195 if (*kvaddr) {
@@ -676,6 +702,9 @@ static int gk20a_init_support(struct platform_device *dev)
676 goto fail; 702 goto fail;
677 } 703 }
678 704
705 g->regs_saved = g->regs;
706 g->bar1_saved = g->bar1;
707
679 /* Get interrupt numbers */ 708 /* Get interrupt numbers */
680 g->irq_nonstall = platform_get_irq(dev, 1); 709 g->irq_nonstall = platform_get_irq(dev, 1);
681 if (g->irq_stall < 0 || g->irq_nonstall < 0) { 710 if (g->irq_stall < 0 || g->irq_nonstall < 0) {
@@ -786,6 +815,9 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
786 815
787 g->power_on = false; 816 g->power_on = false;
788 817
818 /* Stop CPU from accessing the GPU registers. */
819 gk20a_lockout_registers(g);
820
789 return ret; 821 return ret;
790} 822}
791 823
@@ -820,6 +852,10 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
820 852
821 trace_gk20a_finalize_poweron(dev_name(dev)); 853 trace_gk20a_finalize_poweron(dev_name(dev));
822 854
855 err = gk20a_restore_registers(g);
856 if (err)
857 return err;
858
823 nice_value = task_nice(current); 859 nice_value = task_nice(current);
824 set_user_nice(current, -20); 860 set_user_nice(current, -20);
825 861