aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-08-22 23:55:42 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-10-02 23:13:07 -0400
commit2c1a425e7d537ea655fa276f267c0b1cd100ff34 (patch)
tree1267a971b398399475e4cde7640cb6fe22b42a09 /drivers/gpu
parent757833cc9f0c334ecf739836f4e052c11bf81264 (diff)
drm/nve0/ibus: handle PIBUS interrupts to prevent storm
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/Makefile1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ibus.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nve0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c123
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c1
6 files changed, 162 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index cb237af3b21d..1c506c5a9a48 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -73,6 +73,7 @@ nouveau-y += core/subdev/gpio/nvd0.o
73nouveau-y += core/subdev/i2c/base.o 73nouveau-y += core/subdev/i2c/base.o
74nouveau-y += core/subdev/i2c/aux.o 74nouveau-y += core/subdev/i2c/aux.o
75nouveau-y += core/subdev/i2c/bit.o 75nouveau-y += core/subdev/i2c/bit.o
76nouveau-y += core/subdev/ibus/nve0.o
76nouveau-y += core/subdev/instmem/base.o 77nouveau-y += core/subdev/instmem/base.o
77nouveau-y += core/subdev/instmem/nv04.o 78nouveau-y += core/subdev/instmem/nv04.o
78nouveau-y += core/subdev/instmem/nv40.o 79nouveau-y += core/subdev/instmem/nv40.o
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
index 130559327bad..c32f96a22704 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -17,6 +17,7 @@ enum nv_subdev_type {
17 NVDEV_SUBDEV_TIMER, 17 NVDEV_SUBDEV_TIMER,
18 NVDEV_SUBDEV_FB, 18 NVDEV_SUBDEV_FB,
19 NVDEV_SUBDEV_LTCG, 19 NVDEV_SUBDEV_LTCG,
20 NVDEV_SUBDEV_IBUS,
20 NVDEV_SUBDEV_INSTMEM, 21 NVDEV_SUBDEV_INSTMEM,
21 NVDEV_SUBDEV_VM, 22 NVDEV_SUBDEV_VM,
22 NVDEV_SUBDEV_BAR, 23 NVDEV_SUBDEV_BAR,
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
new file mode 100644
index 000000000000..f014594f4265
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
@@ -0,0 +1,33 @@
1#ifndef __NOUVEAU_IBUS_H__
2#define __NOUVEAU_IBUS_H__
3
4#include <core/subdev.h>
5#include <core/device.h>
6
7struct nouveau_ibus {
8 struct nouveau_subdev base;
9};
10
11static inline struct nouveau_ibus *
12nouveau_ibus(void *obj)
13{
14 return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_IBUS];
15}
16
17#define nouveau_ibus_create(p,e,o,d) \
18 nouveau_subdev_create_((p), (e), (o), 0, "PIBUS", "ibus", \
19 sizeof(**d), (void **)d)
20#define nouveau_ibus_destroy(p) \
21 nouveau_subdev_destroy(&(p)->base)
22#define nouveau_ibus_init(p) \
23 nouveau_subdev_init(&(p)->base)
24#define nouveau_ibus_fini(p,s) \
25 nouveau_subdev_fini(&(p)->base, (s))
26
27#define _nouveau_ibus_dtor _nouveau_subdev_dtor
28#define _nouveau_ibus_init _nouveau_subdev_init
29#define _nouveau_ibus_fini _nouveau_subdev_fini
30
31extern struct nouveau_oclass nve0_ibus_oclass;
32
33#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
index efb8ddcff56c..0d9d86b8124c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
@@ -33,6 +33,7 @@
33#include <subdev/timer.h> 33#include <subdev/timer.h>
34#include <subdev/fb.h> 34#include <subdev/fb.h>
35#include <subdev/ltcg.h> 35#include <subdev/ltcg.h>
36#include <subdev/ibus.h>
36#include <subdev/instmem.h> 37#include <subdev/instmem.h>
37#include <subdev/vm.h> 38#include <subdev/vm.h>
38#include <subdev/bar.h> 39#include <subdev/bar.h>
@@ -60,6 +61,7 @@ nve0_identify(struct nouveau_device *device)
60 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 61 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
61 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; 62 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
62 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; 63 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
64 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
63 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; 65 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
64 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; 66 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
65 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; 67 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
@@ -83,6 +85,7 @@ nve0_identify(struct nouveau_device *device)
83 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 85 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
84 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; 86 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
85 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; 87 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
88 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
86 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; 89 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
87 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; 90 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
88 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; 91 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c
new file mode 100644
index 000000000000..7120124dceac
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c
@@ -0,0 +1,123 @@
1/*
2 * Copyright 2012 Red Hat Inc.
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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include <subdev/ibus.h>
26
27struct nve0_ibus_priv {
28 struct nouveau_ibus base;
29};
30
31static void
32nve0_ibus_intr_hub(struct nve0_ibus_priv *priv, int i)
33{
34 u32 addr = nv_rd32(priv, 0x122120 + (i * 0x0800));
35 u32 data = nv_rd32(priv, 0x122124 + (i * 0x0800));
36 u32 stat = nv_rd32(priv, 0x122128 + (i * 0x0800));
37 nv_error(priv, "HUB%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
38 nv_mask(priv, 0x122128 + (i * 0x0800), 0x00000200, 0x00000000);
39}
40
41static void
42nve0_ibus_intr_rop(struct nve0_ibus_priv *priv, int i)
43{
44 u32 addr = nv_rd32(priv, 0x124120 + (i * 0x0800));
45 u32 data = nv_rd32(priv, 0x124124 + (i * 0x0800));
46 u32 stat = nv_rd32(priv, 0x124128 + (i * 0x0800));
47 nv_error(priv, "ROP%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
48 nv_mask(priv, 0x124128 + (i * 0x0800), 0x00000200, 0x00000000);
49}
50
51static void
52nve0_ibus_intr_gpc(struct nve0_ibus_priv *priv, int i)
53{
54 u32 addr = nv_rd32(priv, 0x128120 + (i * 0x0800));
55 u32 data = nv_rd32(priv, 0x128124 + (i * 0x0800));
56 u32 stat = nv_rd32(priv, 0x128128 + (i * 0x0800));
57 nv_error(priv, "GPC%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
58 nv_mask(priv, 0x128128 + (i * 0x0800), 0x00000200, 0x00000000);
59}
60
61static void
62nve0_ibus_intr(struct nouveau_subdev *subdev)
63{
64 struct nve0_ibus_priv *priv = (void *)subdev;
65 u32 intr0 = nv_rd32(priv, 0x120058);
66 u32 intr1 = nv_rd32(priv, 0x12005c);
67 u32 hubnr = nv_rd32(priv, 0x120070);
68 u32 ropnr = nv_rd32(priv, 0x120074);
69 u32 gpcnr = nv_rd32(priv, 0x120078);
70 u32 i;
71
72 for (i = 0; (intr0 & 0x0000ff00) && i < hubnr; i++) {
73 u32 stat = 0x00000100 << i;
74 if (intr0 & stat) {
75 nve0_ibus_intr_hub(priv, i);
76 intr0 &= ~stat;
77 }
78 }
79
80 for (i = 0; (intr0 & 0xffff0000) && i < ropnr; i++) {
81 u32 stat = 0x00010000 << i;
82 if (intr0 & stat) {
83 nve0_ibus_intr_rop(priv, i);
84 intr0 &= ~stat;
85 }
86 }
87
88 for (i = 0; intr1 && i < gpcnr; i++) {
89 u32 stat = 0x00000001 << i;
90 if (intr1 & stat) {
91 nve0_ibus_intr_gpc(priv, i);
92 intr1 &= ~stat;
93 }
94 }
95}
96
97static int
98nve0_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
99 struct nouveau_oclass *oclass, void *data, u32 size,
100 struct nouveau_object **pobject)
101{
102 struct nve0_ibus_priv *priv;
103 int ret;
104
105 ret = nouveau_ibus_create(parent, engine, oclass, &priv);
106 *pobject = nv_object(priv);
107 if (ret)
108 return ret;
109
110 nv_subdev(priv)->intr = nve0_ibus_intr;
111 return 0;
112}
113
114struct nouveau_oclass
115nve0_ibus_oclass = {
116 .handle = NV_SUBDEV(IBUS, 0xe0),
117 .ofuncs = &(struct nouveau_ofuncs) {
118 .ctor = nve0_ibus_ctor,
119 .dtor = _nouveau_ibus_dtor,
120 .init = _nouveau_ibus_init,
121 .fini = _nouveau_ibus_fini,
122 },
123};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
index bd9e99463ff7..c2b81e30a17d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
@@ -40,6 +40,7 @@ nvc0_mc_intr[] = {
40 { 0x00200000, NVDEV_SUBDEV_GPIO }, 40 { 0x00200000, NVDEV_SUBDEV_GPIO },
41 { 0x02000000, NVDEV_SUBDEV_LTCG }, 41 { 0x02000000, NVDEV_SUBDEV_LTCG },
42 { 0x04000000, NVDEV_ENGINE_DISP }, 42 { 0x04000000, NVDEV_ENGINE_DISP },
43 { 0x40000000, NVDEV_SUBDEV_IBUS },
43 { 0x80000000, NVDEV_ENGINE_SW }, 44 { 0x80000000, NVDEV_ENGINE_SW },
44 {}, 45 {},
45}; 46};