diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 14:10:28 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 15:28:13 -0400 |
commit | f38fdb6a376ead4ce8c6c1c75f71cc35b9e40bfc (patch) | |
tree | 21a5a6ecc4d2b3ef3fba629bab1d17bb36f6d7a7 /drivers/gpu | |
parent | 95484b57265caa671a57efed06e322d56461774b (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.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltc/base.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h | 13 |
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 | |||
7 | struct nouveau_mm_node; | 9 | struct nouveau_mm_node; |
8 | 10 | ||
9 | struct nouveau_ltc { | 11 | struct 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 | ||
18 | static inline struct nouveau_ltc * | 25 | static 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 | ||
61 | static int | ||
62 | nvkm_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 | |||
71 | static int | ||
72 | nvkm_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 | |||
81 | int | ||
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 | |||
61 | int | 100 | int |
62 | nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine, | 101 | nvkm_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 | ||
48 | void | ||
49 | gf100_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 | |||
58 | void | ||
59 | gf100_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 | |||
48 | static void | 65 | static void |
49 | gf100_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts) | 66 | gf100_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 | ||
48 | static void | 48 | static void |
49 | gm107_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 | |||
58 | static void | ||
59 | gm107_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 | |||
65 | static void | ||
49 | gm107_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts) | 66 | gm107_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 | 40 | int _nvkm_ltc_init(struct nouveau_object *); |
37 | #define _nvkm_ltc_fini _nouveau_subdev_fini | 41 | #define _nvkm_ltc_fini _nouveau_subdev_fini |
38 | 42 | ||
39 | int gf100_ltc_ctor(struct nouveau_object *, struct nouveau_object *, | 43 | int 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 **); | |||
47 | struct nvkm_ltc_impl { | 51 | struct 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 | ||
54 | void gf100_ltc_intr(struct nouveau_subdev *); | 63 | void gf100_ltc_intr(struct nouveau_subdev *); |
55 | void gf100_ltc_cbc_clear(struct nvkm_ltc_priv *, u32, u32); | 64 | void gf100_ltc_cbc_clear(struct nvkm_ltc_priv *, u32, u32); |
56 | void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *); | 65 | void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *); |
66 | void gf100_ltc_zbc_clear_color(struct nvkm_ltc_priv *, int, const u32[4]); | ||
67 | void gf100_ltc_zbc_clear_depth(struct nvkm_ltc_priv *, int, const u32); | ||
57 | 68 | ||
58 | #endif | 69 | #endif |