aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-09 14:10:28 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-08-09 15:28:13 -0400
commitf38fdb6a376ead4ce8c6c1c75f71cc35b9e40bfc (patch)
tree21a5a6ecc4d2b3ef3fba629bab1d17bb36f6d7a7 /drivers/gpu
parent95484b57265caa671a57efed06e322d56461774b (diff)
drm/nouveau/ltc: add zbc drivers
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ltc.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltc/base.c46
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c20
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c20
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h13
6 files changed, 108 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltc.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltc.h
index de9ac0325c6e..b909a7363f6b 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ltc.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltc.h
@@ -4,6 +4,8 @@
4#include <core/subdev.h> 4#include <core/subdev.h>
5#include <core/device.h> 5#include <core/device.h>
6 6
7#define NOUVEAU_LTC_MAX_ZBC_CNT 16
8
7struct nouveau_mm_node; 9struct nouveau_mm_node;
8 10
9struct nouveau_ltc { 11struct nouveau_ltc {
@@ -13,6 +15,11 @@ struct nouveau_ltc {
13 struct nouveau_mm_node **); 15 struct nouveau_mm_node **);
14 void (*tags_free)(struct nouveau_ltc *, struct nouveau_mm_node **); 16 void (*tags_free)(struct nouveau_ltc *, struct nouveau_mm_node **);
15 void (*tags_clear)(struct nouveau_ltc *, u32 first, u32 count); 17 void (*tags_clear)(struct nouveau_ltc *, u32 first, u32 count);
18
19 int zbc_min;
20 int zbc_max;
21 int (*zbc_color_get)(struct nouveau_ltc *, int index, const u32[4]);
22 int (*zbc_depth_get)(struct nouveau_ltc *, int index, const u32);
16}; 23};
17 24
18static inline struct nouveau_ltc * 25static inline struct nouveau_ltc *
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/base.c
index c99bf3f7352f..32ed442c5913 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/base.c
@@ -58,6 +58,45 @@ nvkm_ltc_tags_clear(struct nouveau_ltc *ltc, u32 first, u32 count)
58 impl->cbc_wait(priv); 58 impl->cbc_wait(priv);
59} 59}
60 60
61static int
62nvkm_ltc_zbc_color_get(struct nouveau_ltc *ltc, int index, const u32 color[4])
63{
64 const struct nvkm_ltc_impl *impl = (void *)nv_oclass(ltc);
65 struct nvkm_ltc_priv *priv = (void *)ltc;
66 memcpy(priv->zbc_color[index], color, sizeof(priv->zbc_color[index]));
67 impl->zbc_clear_color(priv, index, color);
68 return index;
69}
70
71static int
72nvkm_ltc_zbc_depth_get(struct nouveau_ltc *ltc, int index, const u32 depth)
73{
74 const struct nvkm_ltc_impl *impl = (void *)nv_oclass(ltc);
75 struct nvkm_ltc_priv *priv = (void *)ltc;
76 priv->zbc_depth[index] = depth;
77 impl->zbc_clear_depth(priv, index, depth);
78 return index;
79}
80
81int
82_nvkm_ltc_init(struct nouveau_object *object)
83{
84 const struct nvkm_ltc_impl *impl = (void *)nv_oclass(object);
85 struct nvkm_ltc_priv *priv = (void *)object;
86 int ret, i;
87
88 ret = nouveau_subdev_init(&priv->base.base);
89 if (ret)
90 return ret;
91
92 for (i = priv->base.zbc_min; i <= priv->base.zbc_max; i++) {
93 impl->zbc_clear_color(priv, i, priv->zbc_color[i]);
94 impl->zbc_clear_depth(priv, i, priv->zbc_depth[i]);
95 }
96
97 return 0;
98}
99
61int 100int
62nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine, 101nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
63 struct nouveau_oclass *oclass, int length, void **pobject) 102 struct nouveau_oclass *oclass, int length, void **pobject)
@@ -72,9 +111,16 @@ nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
72 if (ret) 111 if (ret)
73 return ret; 112 return ret;
74 113
114 memset(priv->zbc_color, 0x00, sizeof(priv->zbc_color));
115 memset(priv->zbc_depth, 0x00, sizeof(priv->zbc_depth));
116
75 priv->base.base.intr = impl->intr; 117 priv->base.base.intr = impl->intr;
76 priv->base.tags_alloc = nvkm_ltc_tags_alloc; 118 priv->base.tags_alloc = nvkm_ltc_tags_alloc;
77 priv->base.tags_free = nvkm_ltc_tags_free; 119 priv->base.tags_free = nvkm_ltc_tags_free;
78 priv->base.tags_clear = nvkm_ltc_tags_clear; 120 priv->base.tags_clear = nvkm_ltc_tags_clear;
121 priv->base.zbc_min = 1; /* reserve 0 for disabled */
122 priv->base.zbc_max = min(impl->zbc, NOUVEAU_LTC_MAX_ZBC_CNT) - 1;
123 priv->base.zbc_color_get = nvkm_ltc_zbc_color_get;
124 priv->base.zbc_depth_get = nvkm_ltc_zbc_depth_get;
79 return 0; 125 return 0;
80} 126}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c
index f72ab8191d9d..9e00a1ede120 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c
@@ -45,6 +45,23 @@ gf100_ltc_cbc_wait(struct nvkm_ltc_priv *priv)
45 } 45 }
46} 46}
47 47
48void
49gf100_ltc_zbc_clear_color(struct nvkm_ltc_priv *priv, int i, const u32 color[4])
50{
51 nv_mask(priv, 0x17ea44, 0x0000000f, i);
52 nv_wr32(priv, 0x17ea48, color[0]);
53 nv_wr32(priv, 0x17ea4c, color[1]);
54 nv_wr32(priv, 0x17ea50, color[2]);
55 nv_wr32(priv, 0x17ea54, color[3]);
56}
57
58void
59gf100_ltc_zbc_clear_depth(struct nvkm_ltc_priv *priv, int i, const u32 depth)
60{
61 nv_mask(priv, 0x17ea44, 0x0000000f, i);
62 nv_wr32(priv, 0x17ea58, depth);
63}
64
48static void 65static void
49gf100_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts) 66gf100_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts)
50{ 67{
@@ -194,4 +211,7 @@ gf100_ltc_oclass = &(struct nvkm_ltc_impl) {
194 .intr = gf100_ltc_intr, 211 .intr = gf100_ltc_intr,
195 .cbc_clear = gf100_ltc_cbc_clear, 212 .cbc_clear = gf100_ltc_cbc_clear,
196 .cbc_wait = gf100_ltc_cbc_wait, 213 .cbc_wait = gf100_ltc_cbc_wait,
214 .zbc = 16,
215 .zbc_clear_color = gf100_ltc_zbc_clear_color,
216 .zbc_clear_depth = gf100_ltc_zbc_clear_depth,
197}.base; 217}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c
index 063caf791800..ea716569745d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c
@@ -52,4 +52,7 @@ gk104_ltc_oclass = &(struct nvkm_ltc_impl) {
52 .intr = gf100_ltc_intr, 52 .intr = gf100_ltc_intr,
53 .cbc_clear = gf100_ltc_cbc_clear, 53 .cbc_clear = gf100_ltc_cbc_clear,
54 .cbc_wait = gf100_ltc_cbc_wait, 54 .cbc_wait = gf100_ltc_cbc_wait,
55 .zbc = 16,
56 .zbc_clear_color = gf100_ltc_zbc_clear_color,
57 .zbc_clear_depth = gf100_ltc_zbc_clear_depth,
55}.base; 58}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c
index c05333ebaff2..4761b2e9af00 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c
@@ -46,6 +46,23 @@ gm107_ltc_cbc_wait(struct nvkm_ltc_priv *priv)
46} 46}
47 47
48static void 48static void
49gm107_ltc_zbc_clear_color(struct nvkm_ltc_priv *priv, int i, const u32 color[4])
50{
51 nv_mask(priv, 0x17e338, 0x0000000f, i);
52 nv_wr32(priv, 0x17e33c, color[0]);
53 nv_wr32(priv, 0x17e340, color[1]);
54 nv_wr32(priv, 0x17e344, color[2]);
55 nv_wr32(priv, 0x17e348, color[3]);
56}
57
58static void
59gm107_ltc_zbc_clear_depth(struct nvkm_ltc_priv *priv, int i, const u32 depth)
60{
61 nv_mask(priv, 0x17e338, 0x0000000f, i);
62 nv_wr32(priv, 0x17e34c, depth);
63}
64
65static void
49gm107_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts) 66gm107_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts)
50{ 67{
51 u32 base = 0x140000 + (ltc * 0x2000) + (lts * 0x400); 68 u32 base = 0x140000 + (ltc * 0x2000) + (lts * 0x400);
@@ -134,4 +151,7 @@ gm107_ltc_oclass = &(struct nvkm_ltc_impl) {
134 .intr = gm107_ltc_intr, 151 .intr = gm107_ltc_intr,
135 .cbc_clear = gm107_ltc_cbc_clear, 152 .cbc_clear = gm107_ltc_cbc_clear,
136 .cbc_wait = gm107_ltc_cbc_wait, 153 .cbc_wait = gm107_ltc_cbc_wait,
154 .zbc = 16,
155 .zbc_clear_color = gm107_ltc_zbc_clear_color,
156 .zbc_clear_depth = gm107_ltc_zbc_clear_depth,
137}.base; 157}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h b/drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h
index 96d12a220400..594924f39126 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h
@@ -8,10 +8,14 @@ struct nvkm_ltc_priv {
8 struct nouveau_ltc base; 8 struct nouveau_ltc base;
9 u32 ltc_nr; 9 u32 ltc_nr;
10 u32 lts_nr; 10 u32 lts_nr;
11
11 u32 num_tags; 12 u32 num_tags;
12 u32 tag_base; 13 u32 tag_base;
13 struct nouveau_mm tags; 14 struct nouveau_mm tags;
14 struct nouveau_mm_node *tag_ram; 15 struct nouveau_mm_node *tag_ram;
16
17 u32 zbc_color[NOUVEAU_LTC_MAX_ZBC_CNT][4];
18 u32 zbc_depth[NOUVEAU_LTC_MAX_ZBC_CNT];
15}; 19};
16 20
17#define nvkm_ltc_create(p,e,o,d) \ 21#define nvkm_ltc_create(p,e,o,d) \
@@ -33,7 +37,7 @@ int nvkm_ltc_create_(struct nouveau_object *, struct nouveau_object *,
33 struct nouveau_oclass *, int, void **); 37 struct nouveau_oclass *, int, void **);
34 38
35#define _nvkm_ltc_dtor _nouveau_subdev_dtor 39#define _nvkm_ltc_dtor _nouveau_subdev_dtor
36#define _nvkm_ltc_init _nouveau_subdev_init 40int _nvkm_ltc_init(struct nouveau_object *);
37#define _nvkm_ltc_fini _nouveau_subdev_fini 41#define _nvkm_ltc_fini _nouveau_subdev_fini
38 42
39int gf100_ltc_ctor(struct nouveau_object *, struct nouveau_object *, 43int gf100_ltc_ctor(struct nouveau_object *, struct nouveau_object *,
@@ -47,12 +51,19 @@ void gf100_ltc_tags_free(struct nouveau_ltc *, struct nouveau_mm_node **);
47struct nvkm_ltc_impl { 51struct nvkm_ltc_impl {
48 struct nouveau_oclass base; 52 struct nouveau_oclass base;
49 void (*intr)(struct nouveau_subdev *); 53 void (*intr)(struct nouveau_subdev *);
54
50 void (*cbc_clear)(struct nvkm_ltc_priv *, u32 start, u32 limit); 55 void (*cbc_clear)(struct nvkm_ltc_priv *, u32 start, u32 limit);
51 void (*cbc_wait)(struct nvkm_ltc_priv *); 56 void (*cbc_wait)(struct nvkm_ltc_priv *);
57
58 int zbc;
59 void (*zbc_clear_color)(struct nvkm_ltc_priv *, int, const u32[4]);
60 void (*zbc_clear_depth)(struct nvkm_ltc_priv *, int, const u32);
52}; 61};
53 62
54void gf100_ltc_intr(struct nouveau_subdev *); 63void gf100_ltc_intr(struct nouveau_subdev *);
55void gf100_ltc_cbc_clear(struct nvkm_ltc_priv *, u32, u32); 64void gf100_ltc_cbc_clear(struct nvkm_ltc_priv *, u32, u32);
56void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *); 65void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *);
66void gf100_ltc_zbc_clear_color(struct nvkm_ltc_priv *, int, const u32[4]);
67void gf100_ltc_zbc_clear_depth(struct nvkm_ltc_priv *, int, const u32);
57 68
58#endif 69#endif