summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2017-09-27 16:21:44 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-10-13 18:19:55 -0400
commitbe3750bc9eb60f8696c20b7298cc282eea17ac1b (patch)
treeb36fb818ce58a96fc7f2822480433057bd28faf4 /drivers
parentff9c3fc20a27444cd1ff7d9402965023e425f404 (diff)
gpu: nvgpu: Abstract IO aperture accessors
Add abstraction of IO aperture accessors. Add new functions gk20a_io_exists() and gk20a_io_valid_reg() to remove dependencies to aperture fields from common code. Implement Linux version of the abstraction by moving gk20a_readl() and gk20a_writel() to new Linux specific io.c. Move the fields defining IO aperture to nvgpu_os_linux. Add t19x specific IO aperture initialization functions and add t19x specific section to nvgpu_os_linux. JIRA NVGPU-259 Change-Id: I09e79cda60d11a20d1099a9aaa6d2375236e94ce Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1569698 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/Makefile.nvgpu1
-rw-r--r--drivers/gpu/nvgpu/common/linux/driver_common.c4
-rw-r--r--drivers/gpu/nvgpu/common/linux/io.c110
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.c77
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.h4
-rw-r--r--drivers/gpu/nvgpu/common/linux/nvgpu_mem.c13
-rw-r--r--drivers/gpu/nvgpu/common/linux/os_linux.h14
-rw-r--r--drivers/gpu/nvgpu/common/linux/pci.c13
-rw-r--r--drivers/gpu/nvgpu/common/pramin.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c26
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h81
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/io.h49
-rw-r--r--drivers/gpu/nvgpu/vgpu/fifo_vgpu.c3
-rw-r--r--drivers/gpu/nvgpu/vgpu/vgpu.c18
15 files changed, 274 insertions, 144 deletions
diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu
index a792ab33..fa774566 100644
--- a/drivers/gpu/nvgpu/Makefile.nvgpu
+++ b/drivers/gpu/nvgpu/Makefile.nvgpu
@@ -46,6 +46,7 @@ nvgpu-y := \
46 common/linux/intr.o \ 46 common/linux/intr.o \
47 common/linux/sysfs.o \ 47 common/linux/sysfs.o \
48 common/linux/cde.o \ 48 common/linux/cde.o \
49 common/linux/io.o \
49 common/mm/nvgpu_allocator.o \ 50 common/mm/nvgpu_allocator.o \
50 common/mm/bitmap_allocator.o \ 51 common/mm/bitmap_allocator.o \
51 common/mm/buddy_allocator.o \ 52 common/mm/buddy_allocator.o \
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c
index 7c4645a8..734bc1d2 100644
--- a/drivers/gpu/nvgpu/common/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/common/linux/driver_common.c
@@ -54,8 +54,8 @@ static void nvgpu_init_vars(struct gk20a *g)
54 nvgpu_mutex_init(&g->poweron_lock); 54 nvgpu_mutex_init(&g->poweron_lock);
55 nvgpu_mutex_init(&g->poweroff_lock); 55 nvgpu_mutex_init(&g->poweroff_lock);
56 56
57 g->regs_saved = g->regs; 57 l->regs_saved = l->regs;
58 g->bar1_saved = g->bar1; 58 l->bar1_saved = l->bar1;
59 59
60 g->emc3d_ratio = EMC3D_DEFAULT_RATIO; 60 g->emc3d_ratio = EMC3D_DEFAULT_RATIO;
61 61
diff --git a/drivers/gpu/nvgpu/common/linux/io.c b/drivers/gpu/nvgpu/common/linux/io.c
new file mode 100644
index 00000000..04a9fbe8
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/linux/io.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13
14#include <nvgpu/io.h>
15#include <nvgpu/types.h>
16
17#include "os_linux.h"
18#include "gk20a/gk20a.h"
19
20void nvgpu_writel(struct gk20a *g, u32 r, u32 v)
21{
22 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
23
24 if (unlikely(!l->regs)) {
25 __gk20a_warn_on_no_regs();
26 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
27 } else {
28 writel_relaxed(v, l->regs + r);
29 nvgpu_smp_wmb();
30 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
31 }
32}
33
34u32 nvgpu_readl(struct gk20a *g, u32 r)
35{
36 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
37 u32 v = 0xffffffff;
38
39 if (unlikely(!l->regs)) {
40 __gk20a_warn_on_no_regs();
41 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
42 } else {
43 v = readl(l->regs + r);
44 if (v == 0xffffffff)
45 __nvgpu_check_gpu_state(g);
46 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
47 }
48
49 return v;
50}
51
52void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v)
53{
54 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
55
56 if (unlikely(!l->regs)) {
57 __gk20a_warn_on_no_regs();
58 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
59 } else {
60 nvgpu_smp_wmb();
61 do {
62 writel_relaxed(v, l->regs + r);
63 } while (readl(l->regs + r) != v);
64 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
65 }
66}
67
68void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v)
69{
70 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
71
72 if (unlikely(!l->bar1)) {
73 __gk20a_warn_on_no_regs();
74 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
75 } else {
76 nvgpu_smp_wmb();
77 writel_relaxed(v, l->bar1 + b);
78 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
79 }
80}
81
82u32 nvgpu_bar1_readl(struct gk20a *g, u32 b)
83{
84 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
85 u32 v = 0xffffffff;
86
87 if (unlikely(!l->bar1)) {
88 __gk20a_warn_on_no_regs();
89 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
90 } else {
91 v = readl(l->bar1 + b);
92 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
93 }
94
95 return v;
96}
97
98bool nvgpu_io_exists(struct gk20a *g)
99{
100 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
101
102 return l->regs != NULL;
103}
104
105bool nvgpu_io_valid_reg(struct gk20a *g, u32 r)
106{
107 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
108
109 return r < resource_size(l->regs);
110}
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c
index 52f987b2..fe3e4e6f 100644
--- a/drivers/gpu/nvgpu/common/linux/module.c
+++ b/drivers/gpu/nvgpu/common/linux/module.c
@@ -137,6 +137,23 @@ void gk20a_idle(struct gk20a *g)
137 } 137 }
138} 138}
139 139
140/*
141 * Undoes gk20a_lockout_registers().
142 */
143static int gk20a_restore_registers(struct gk20a *g)
144{
145 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
146
147 l->regs = l->regs_saved;
148 l->bar1 = l->bar1_saved;
149
150#ifdef CONFIG_TEGRA_19x_GPU
151 t19x_restore_registers(g);
152#endif
153
154 return 0;
155}
156
140int gk20a_pm_finalize_poweron(struct device *dev) 157int gk20a_pm_finalize_poweron(struct device *dev)
141{ 158{
142 struct gk20a *g = get_gk20a(dev); 159 struct gk20a *g = get_gk20a(dev);
@@ -198,6 +215,27 @@ done:
198 return err; 215 return err;
199} 216}
200 217
218/*
219 * Locks out the driver from accessing GPU registers. This prevents access to
220 * thse registers after the GPU has been clock or power gated. This should help
221 * find annoying bugs where register reads and writes are silently dropped
222 * after the GPU has been turned off. On older chips these reads and writes can
223 * also lock the entire CPU up.
224 */
225static int gk20a_lockout_registers(struct gk20a *g)
226{
227 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
228
229 l->regs = NULL;
230 l->bar1 = NULL;
231
232#ifdef CONFIG_TEGRA_19x_GPU
233 t19x_lockout_registers(g);
234#endif
235
236 return 0;
237}
238
201static int gk20a_pm_prepare_poweroff(struct device *dev) 239static int gk20a_pm_prepare_poweroff(struct device *dev)
202{ 240{
203 struct gk20a *g = get_gk20a(dev); 241 struct gk20a *g = get_gk20a(dev);
@@ -511,6 +549,8 @@ static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id)
511 549
512void gk20a_remove_support(struct gk20a *g) 550void gk20a_remove_support(struct gk20a *g)
513{ 551{
552 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
553
514 tegra_unregister_idle_unidle(gk20a_do_idle); 554 tegra_unregister_idle_unidle(gk20a_do_idle);
515 555
516 nvgpu_kfree(g, g->dbg_regops_tmp_buf); 556 nvgpu_kfree(g, g->dbg_regops_tmp_buf);
@@ -535,36 +575,41 @@ void gk20a_remove_support(struct gk20a *g)
535 575
536 /* free mappings to registers, etc */ 576 /* free mappings to registers, etc */
537 577
538 if (g->regs) { 578 if (l->regs) {
539 iounmap(g->regs); 579 iounmap(l->regs);
540 g->regs = NULL; 580 l->regs = NULL;
541 } 581 }
542 if (g->bar1) { 582 if (l->bar1) {
543 iounmap(g->bar1); 583 iounmap(l->bar1);
544 g->bar1 = NULL; 584 l->bar1 = NULL;
545 } 585 }
586
587#ifdef CONFIG_TEGRA_19x_GPU
588 t19x_remove_support(g);
589#endif
546} 590}
547 591
548static int gk20a_init_support(struct platform_device *dev) 592static int gk20a_init_support(struct platform_device *dev)
549{ 593{
550 int err = 0; 594 int err = 0;
551 struct gk20a *g = get_gk20a(&dev->dev); 595 struct gk20a *g = get_gk20a(&dev->dev);
596 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
552 597
553 tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g); 598 tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g);
554 599
555 g->regs = gk20a_ioremap_resource(dev, GK20A_BAR0_IORESOURCE_MEM, 600 l->regs = gk20a_ioremap_resource(dev, GK20A_BAR0_IORESOURCE_MEM,
556 &g->reg_mem); 601 &l->reg_mem);
557 if (IS_ERR(g->regs)) { 602 if (IS_ERR(l->regs)) {
558 nvgpu_err(g, "failed to remap gk20a registers"); 603 nvgpu_err(g, "failed to remap gk20a registers");
559 err = PTR_ERR(g->regs); 604 err = PTR_ERR(l->regs);
560 goto fail; 605 goto fail;
561 } 606 }
562 607
563 g->bar1 = gk20a_ioremap_resource(dev, GK20A_BAR1_IORESOURCE_MEM, 608 l->bar1 = gk20a_ioremap_resource(dev, GK20A_BAR1_IORESOURCE_MEM,
564 &g->bar1_mem); 609 &l->bar1_mem);
565 if (IS_ERR(g->bar1)) { 610 if (IS_ERR(l->bar1)) {
566 nvgpu_err(g, "failed to remap gk20a bar1"); 611 nvgpu_err(g, "failed to remap gk20a bar1");
567 err = PTR_ERR(g->bar1); 612 err = PTR_ERR(l->bar1);
568 goto fail; 613 goto fail;
569 } 614 }
570 615
@@ -584,6 +629,10 @@ static int gk20a_init_support(struct platform_device *dev)
584 goto fail; 629 goto fail;
585 } 630 }
586 631
632#ifdef CONFIG_TEGRA_19x_GPU
633 t19x_init_support(g);
634#endif
635
587 return 0; 636 return 0;
588 637
589fail: 638fail:
diff --git a/drivers/gpu/nvgpu/common/linux/module.h b/drivers/gpu/nvgpu/common/linux/module.h
index 55a3b692..5814d63a 100644
--- a/drivers/gpu/nvgpu/common/linux/module.h
+++ b/drivers/gpu/nvgpu/common/linux/module.h
@@ -13,6 +13,10 @@
13#ifndef __NVGPU_COMMON_LINUX_MODULE_H__ 13#ifndef __NVGPU_COMMON_LINUX_MODULE_H__
14#define __NVGPU_COMMON_LINUX_MODULE_H__ 14#define __NVGPU_COMMON_LINUX_MODULE_H__
15 15
16#ifdef CONFIG_TEGRA_19x_GPU
17#include <nvgpu/linux/module_t19x.h>
18#endif
19
16struct gk20a; 20struct gk20a;
17struct device; 21struct device;
18 22
diff --git a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
index 8740ac3d..1dbbd1a0 100644
--- a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
+++ b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
@@ -105,9 +105,10 @@ void nvgpu_mem_end(struct gk20a *g, struct nvgpu_mem *mem)
105 105
106static void pramin_access_batch_rd_n(struct gk20a *g, u32 start, u32 words, u32 **arg) 106static void pramin_access_batch_rd_n(struct gk20a *g, u32 start, u32 words, u32 **arg)
107{ 107{
108 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
108 u32 r = start, *dest_u32 = *arg; 109 u32 r = start, *dest_u32 = *arg;
109 110
110 if (!g->regs) { 111 if (!l->regs) {
111 __gk20a_warn_on_no_regs(); 112 __gk20a_warn_on_no_regs();
112 return; 113 return;
113 } 114 }
@@ -182,15 +183,16 @@ void nvgpu_mem_rd_n(struct gk20a *g, struct nvgpu_mem *mem,
182 183
183static void pramin_access_batch_wr_n(struct gk20a *g, u32 start, u32 words, u32 **arg) 184static void pramin_access_batch_wr_n(struct gk20a *g, u32 start, u32 words, u32 **arg)
184{ 185{
186 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
185 u32 r = start, *src_u32 = *arg; 187 u32 r = start, *src_u32 = *arg;
186 188
187 if (!g->regs) { 189 if (!l->regs) {
188 __gk20a_warn_on_no_regs(); 190 __gk20a_warn_on_no_regs();
189 return; 191 return;
190 } 192 }
191 193
192 while (words--) { 194 while (words--) {
193 writel_relaxed(*src_u32++, g->regs + r); 195 writel_relaxed(*src_u32++, l->regs + r);
194 r += sizeof(u32); 196 r += sizeof(u32);
195 } 197 }
196 198
@@ -256,15 +258,16 @@ void nvgpu_mem_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset,
256 258
257static void pramin_access_batch_set(struct gk20a *g, u32 start, u32 words, u32 **arg) 259static void pramin_access_batch_set(struct gk20a *g, u32 start, u32 words, u32 **arg)
258{ 260{
261 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
259 u32 r = start, repeat = **arg; 262 u32 r = start, repeat = **arg;
260 263
261 if (!g->regs) { 264 if (!l->regs) {
262 __gk20a_warn_on_no_regs(); 265 __gk20a_warn_on_no_regs();
263 return; 266 return;
264 } 267 }
265 268
266 while (words--) { 269 while (words--) {
267 writel_relaxed(repeat, g->regs + r); 270 writel_relaxed(repeat, l->regs + r);
268 r += sizeof(u32); 271 r += sizeof(u32);
269 } 272 }
270} 273}
diff --git a/drivers/gpu/nvgpu/common/linux/os_linux.h b/drivers/gpu/nvgpu/common/linux/os_linux.h
index 48479843..4a3128c3 100644
--- a/drivers/gpu/nvgpu/common/linux/os_linux.h
+++ b/drivers/gpu/nvgpu/common/linux/os_linux.h
@@ -18,6 +18,9 @@
18 18
19#include <linux/cdev.h> 19#include <linux/cdev.h>
20 20
21#ifdef CONFIG_TEGRA_19x_GPU
22#include <nvgpu/linux/os_linux_t19x.h>
23#endif
21#include "gk20a/gk20a.h" 24#include "gk20a/gk20a.h"
22#include "cde.h" 25#include "cde.h"
23 26
@@ -85,6 +88,17 @@ struct nvgpu_os_linux {
85 struct work_struct nonstall_fn_work; 88 struct work_struct nonstall_fn_work;
86 struct workqueue_struct *nonstall_work_queue; 89 struct workqueue_struct *nonstall_work_queue;
87 90
91 struct resource *reg_mem;
92 void __iomem *regs;
93 void __iomem *regs_saved;
94
95 struct resource *bar1_mem;
96 void __iomem *bar1;
97 void __iomem *bar1_saved;
98
99#ifdef CONFIG_TEGRA_19x_GPU
100 struct nvgpu_os_linux_t19x t19x;
101#endif
88#ifdef CONFIG_DEBUG_FS 102#ifdef CONFIG_DEBUG_FS
89 struct dentry *debugfs; 103 struct dentry *debugfs;
90 struct dentry *debugfs_alias; 104 struct dentry *debugfs_alias;
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index 401080ed..50d079bb 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -348,20 +348,21 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
348{ 348{
349 int err = 0; 349 int err = 0;
350 struct gk20a *g = get_gk20a(&pdev->dev); 350 struct gk20a *g = get_gk20a(&pdev->dev);
351 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
351 352
352 g->regs = ioremap(pci_resource_start(pdev, 0), 353 l->regs = ioremap(pci_resource_start(pdev, 0),
353 pci_resource_len(pdev, 0)); 354 pci_resource_len(pdev, 0));
354 if (IS_ERR(g->regs)) { 355 if (IS_ERR(l->regs)) {
355 nvgpu_err(g, "failed to remap gk20a registers"); 356 nvgpu_err(g, "failed to remap gk20a registers");
356 err = PTR_ERR(g->regs); 357 err = PTR_ERR(l->regs);
357 goto fail; 358 goto fail;
358 } 359 }
359 360
360 g->bar1 = ioremap(pci_resource_start(pdev, 1), 361 l->bar1 = ioremap(pci_resource_start(pdev, 1),
361 pci_resource_len(pdev, 1)); 362 pci_resource_len(pdev, 1));
362 if (IS_ERR(g->bar1)) { 363 if (IS_ERR(l->bar1)) {
363 nvgpu_err(g, "failed to remap gk20a bar1"); 364 nvgpu_err(g, "failed to remap gk20a bar1");
364 err = PTR_ERR(g->bar1); 365 err = PTR_ERR(l->bar1);
365 goto fail; 366 goto fail;
366 } 367 }
367 368
diff --git a/drivers/gpu/nvgpu/common/pramin.c b/drivers/gpu/nvgpu/common/pramin.c
index b6166f51..9b04d5a3 100644
--- a/drivers/gpu/nvgpu/common/pramin.c
+++ b/drivers/gpu/nvgpu/common/pramin.c
@@ -51,7 +51,7 @@ void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem,
51 * driver should be refactored to prevent this from happening, but for 51 * driver should be refactored to prevent this from happening, but for
52 * now it is ok just to ignore the writes 52 * now it is ok just to ignore the writes
53 */ 53 */
54 if (!g->regs && nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING)) 54 if (!gk20a_io_exists(g) && nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING))
55 return; 55 return;
56 56
57 alloc = mem->vidmem_alloc; 57 alloc = mem->vidmem_alloc;
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index cac62db7..a4becda0 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -65,32 +65,6 @@ void __nvgpu_check_gpu_state(struct gk20a *g)
65 } 65 }
66} 66}
67 67
68/*
69 * Locks out the driver from accessing GPU registers. This prevents access to
70 * thse registers after the GPU has been clock or power gated. This should help
71 * find annoying bugs where register reads and writes are silently dropped
72 * after the GPU has been turned off. On older chips these reads and writes can
73 * also lock the entire CPU up.
74 */
75int gk20a_lockout_registers(struct gk20a *g)
76{
77 g->regs = NULL;
78 g->bar1 = NULL;
79
80 return 0;
81}
82
83/*
84 * Undoes gk20a_lockout_registers().
85 */
86int gk20a_restore_registers(struct gk20a *g)
87{
88 g->regs = g->regs_saved;
89 g->bar1 = g->bar1_saved;
90
91 return 0;
92}
93
94void __gk20a_warn_on_no_regs(void) 68void __gk20a_warn_on_no_regs(void)
95{ 69{
96 WARN_ONCE(1, "Attempted access to GPU regs after unmapping!"); 70 WARN_ONCE(1, "Attempted access to GPU regs after unmapping!");
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index a45a7b4e..bf10055a 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -44,6 +44,7 @@ struct nvgpu_mem_sgt;
44 44
45#include <nvgpu/lock.h> 45#include <nvgpu/lock.h>
46#include <nvgpu/thread.h> 46#include <nvgpu/thread.h>
47#include <nvgpu/io.h>
47#ifdef CONFIG_DEBUG_FS 48#ifdef CONFIG_DEBUG_FS
48#include <linux/debugfs.h> 49#include <linux/debugfs.h>
49#endif 50#endif
@@ -1067,14 +1068,6 @@ struct gk20a {
1067 1068
1068 struct nvgpu_ref refcount; 1069 struct nvgpu_ref refcount;
1069 1070
1070 struct resource *reg_mem;
1071 void __iomem *regs;
1072 void __iomem *regs_saved;
1073
1074 struct resource *bar1_mem;
1075 void __iomem *bar1;
1076 void __iomem *bar1_saved;
1077
1078 const char *name; 1071 const char *name;
1079 1072
1080 bool gpu_reset_done; 1073 bool gpu_reset_done;
@@ -1339,81 +1332,9 @@ enum gk20a_nonstall_ops {
1339}; 1332};
1340 1333
1341/* register accessors */ 1334/* register accessors */
1342int gk20a_lockout_registers(struct gk20a *g);
1343int gk20a_restore_registers(struct gk20a *g);
1344
1345void __nvgpu_check_gpu_state(struct gk20a *g); 1335void __nvgpu_check_gpu_state(struct gk20a *g);
1346void __gk20a_warn_on_no_regs(void); 1336void __gk20a_warn_on_no_regs(void);
1347 1337
1348static inline void gk20a_writel(struct gk20a *g, u32 r, u32 v)
1349{
1350 if (unlikely(!g->regs)) {
1351 __gk20a_warn_on_no_regs();
1352 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
1353 } else {
1354 writel_relaxed(v, g->regs + r);
1355 nvgpu_smp_wmb();
1356 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
1357 }
1358}
1359static inline u32 gk20a_readl(struct gk20a *g, u32 r)
1360{
1361
1362 u32 v = 0xffffffff;
1363
1364 if (unlikely(!g->regs)) {
1365 __gk20a_warn_on_no_regs();
1366 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
1367 } else {
1368 v = readl(g->regs + r);
1369 if (v == 0xffffffff)
1370 __nvgpu_check_gpu_state(g);
1371 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
1372 }
1373
1374 return v;
1375}
1376static inline void gk20a_writel_check(struct gk20a *g, u32 r, u32 v)
1377{
1378 if (unlikely(!g->regs)) {
1379 __gk20a_warn_on_no_regs();
1380 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
1381 } else {
1382 nvgpu_smp_wmb();
1383 do {
1384 writel_relaxed(v, g->regs + r);
1385 } while (readl(g->regs + r) != v);
1386 gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
1387 }
1388}
1389
1390static inline void gk20a_bar1_writel(struct gk20a *g, u32 b, u32 v)
1391{
1392 if (unlikely(!g->bar1)) {
1393 __gk20a_warn_on_no_regs();
1394 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
1395 } else {
1396 nvgpu_smp_wmb();
1397 writel_relaxed(v, g->bar1 + b);
1398 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
1399 }
1400}
1401
1402static inline u32 gk20a_bar1_readl(struct gk20a *g, u32 b)
1403{
1404 u32 v = 0xffffffff;
1405
1406 if (unlikely(!g->bar1)) {
1407 __gk20a_warn_on_no_regs();
1408 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x (failed)", b, v);
1409 } else {
1410 v = readl(g->bar1 + b);
1411 gk20a_dbg(gpu_dbg_reg, "b=0x%x v=0x%x", b, v);
1412 }
1413
1414 return v;
1415}
1416
1417/* convenience */ 1338/* convenience */
1418static inline struct gk20a *gk20a_from_as(struct gk20a_as *as) 1339static inline struct gk20a *gk20a_from_as(struct gk20a_as *as)
1419{ 1340{
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 707bfb87..6f829282 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -5256,8 +5256,7 @@ static inline bool is_valid_cyclestats_bar0_offset_gk20a(struct gk20a *g,
5256 is_bar0_global_offset_whitelisted_gk20a(g, offset); 5256 is_bar0_global_offset_whitelisted_gk20a(g, offset);
5257 /* resource size check in case there was a problem 5257 /* resource size check in case there was a problem
5258 * with allocating the assumed size of bar0 */ 5258 * with allocating the assumed size of bar0 */
5259 valid = valid && 5259 valid = valid && gk20a_io_valid_reg(g, offset);
5260 offset < resource_size(g->regs);
5261 return valid; 5260 return valid;
5262} 5261}
5263#endif 5262#endif
diff --git a/drivers/gpu/nvgpu/include/nvgpu/io.h b/drivers/gpu/nvgpu/include/nvgpu/io.h
new file mode 100644
index 00000000..94ae8f95
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/io.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22#ifndef __NVGPU_IO_H__
23#define __NVGPU_IO_H__
24
25#include <nvgpu/types.h>
26#ifdef CONFIG_TEGRA_19x_GPU
27#include <nvgpu/io_t19x.h>
28#endif
29
30/* Legacy defines - should be removed once everybody uses nvgpu_* */
31#define gk20a_writel nvgpu_writel
32#define gk20a_readl nvgpu_readl
33#define gk20a_writel_check nvgpu_writel_check
34#define gk20a_bar1_writel nvgpu_bar1_writel
35#define gk20a_bar1_readl nvgpu_bar1_readl
36#define gk20a_io_exists nvgpu_io_exists
37#define gk20a_io_valid_reg nvgpu_io_valid_reg
38
39struct gk20a;
40
41void nvgpu_writel(struct gk20a *g, u32 r, u32 v);
42u32 nvgpu_readl(struct gk20a *g, u32 r);
43void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v);
44void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v);
45u32 nvgpu_bar1_readl(struct gk20a *g, u32 b);
46bool nvgpu_io_exists(struct gk20a *g);
47bool nvgpu_io_valid_reg(struct gk20a *g, u32 r);
48
49#endif
diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
index 9010c4a3..73a67d91 100644
--- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
@@ -268,6 +268,7 @@ clean_up_runlist:
268 268
269static int vgpu_init_fifo_setup_sw(struct gk20a *g) 269static int vgpu_init_fifo_setup_sw(struct gk20a *g)
270{ 270{
271 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
271 struct fifo_gk20a *f = &g->fifo; 272 struct fifo_gk20a *f = &g->fifo;
272 struct device *d = dev_from_gk20a(g); 273 struct device *d = dev_from_gk20a(g);
273 struct vgpu_priv_data *priv = vgpu_get_priv_data(g); 274 struct vgpu_priv_data *priv = vgpu_get_priv_data(g);
@@ -305,7 +306,7 @@ static int vgpu_init_fifo_setup_sw(struct gk20a *g)
305 /* if reduced BAR1 range is specified, use offset of 0 306 /* if reduced BAR1 range is specified, use offset of 0
306 * (server returns offset assuming full BAR1 range) 307 * (server returns offset assuming full BAR1 range)
307 */ 308 */
308 if (resource_size(g->bar1_mem) == 309 if (resource_size(l->bar1_mem) ==
309 (resource_size_t)f->userd.size) 310 (resource_size_t)f->userd.size)
310 f->userd.gpu_va = 0; 311 f->userd.gpu_va = 0;
311 } 312 }
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c
index c13d8ff0..b63202c1 100644
--- a/drivers/gpu/nvgpu/vgpu/vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/vgpu.c
@@ -216,6 +216,7 @@ static int vgpu_intr_thread(void *dev_id)
216 216
217static void vgpu_remove_support(struct gk20a *g) 217static void vgpu_remove_support(struct gk20a *g)
218{ 218{
219 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
219 struct vgpu_priv_data *priv = 220 struct vgpu_priv_data *priv =
220 vgpu_get_priv_data_from_dev(dev_from_gk20a(g)); 221 vgpu_get_priv_data_from_dev(dev_from_gk20a(g));
221 struct tegra_vgpu_intr_msg msg; 222 struct tegra_vgpu_intr_msg msg;
@@ -245,18 +246,20 @@ static void vgpu_remove_support(struct gk20a *g)
245 246
246 /* free mappings to registers, etc*/ 247 /* free mappings to registers, etc*/
247 248
248 if (g->bar1) { 249 if (l->bar1) {
249 iounmap(g->bar1); 250 iounmap(l->bar1);
250 g->bar1 = NULL; 251 l->bar1 = NULL;
251 } 252 }
252} 253}
253 254
254static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform) 255static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform)
255{ 256{
257 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
258
256 nvgpu_mutex_init(&g->poweron_lock); 259 nvgpu_mutex_init(&g->poweron_lock);
257 nvgpu_mutex_init(&g->poweroff_lock); 260 nvgpu_mutex_init(&g->poweroff_lock);
258 g->regs_saved = g->regs; 261 l->regs_saved = l->regs;
259 g->bar1_saved = g->bar1; 262 l->bar1_saved = l->bar1;
260 263
261 nvgpu_init_list_node(&g->pending_sema_waits); 264 nvgpu_init_list_node(&g->pending_sema_waits);
262 nvgpu_raw_spinlock_init(&g->pending_sema_waits_lock); 265 nvgpu_raw_spinlock_init(&g->pending_sema_waits_lock);
@@ -276,6 +279,7 @@ static int vgpu_init_support(struct platform_device *pdev)
276{ 279{
277 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 280 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
278 struct gk20a *g = get_gk20a(&pdev->dev); 281 struct gk20a *g = get_gk20a(&pdev->dev);
282 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
279 void __iomem *regs; 283 void __iomem *regs;
280 int err = 0; 284 int err = 0;
281 285
@@ -292,8 +296,8 @@ static int vgpu_init_support(struct platform_device *pdev)
292 err = PTR_ERR(regs); 296 err = PTR_ERR(regs);
293 goto fail; 297 goto fail;
294 } 298 }
295 g->bar1 = regs; 299 l->bar1 = regs;
296 g->bar1_mem = r; 300 l->bar1_mem = r;
297 } 301 }
298 302
299 nvgpu_mutex_init(&g->dbg_sessions_lock); 303 nvgpu_mutex_init(&g->dbg_sessions_lock);