mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 08:02:07 +00:00
drm/nouveau/ltc: add zbc drivers
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
95484b5726
commit
f38fdb6a37
@ -4,6 +4,8 @@
|
|||||||
#include <core/subdev.h>
|
#include <core/subdev.h>
|
||||||
#include <core/device.h>
|
#include <core/device.h>
|
||||||
|
|
||||||
|
#define NOUVEAU_LTC_MAX_ZBC_CNT 16
|
||||||
|
|
||||||
struct nouveau_mm_node;
|
struct nouveau_mm_node;
|
||||||
|
|
||||||
struct nouveau_ltc {
|
struct nouveau_ltc {
|
||||||
@ -13,6 +15,11 @@ struct nouveau_ltc {
|
|||||||
struct nouveau_mm_node **);
|
struct nouveau_mm_node **);
|
||||||
void (*tags_free)(struct nouveau_ltc *, struct nouveau_mm_node **);
|
void (*tags_free)(struct nouveau_ltc *, struct nouveau_mm_node **);
|
||||||
void (*tags_clear)(struct nouveau_ltc *, u32 first, u32 count);
|
void (*tags_clear)(struct nouveau_ltc *, u32 first, u32 count);
|
||||||
|
|
||||||
|
int zbc_min;
|
||||||
|
int zbc_max;
|
||||||
|
int (*zbc_color_get)(struct nouveau_ltc *, int index, const u32[4]);
|
||||||
|
int (*zbc_depth_get)(struct nouveau_ltc *, int index, const u32);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct nouveau_ltc *
|
static inline struct nouveau_ltc *
|
||||||
|
@ -58,6 +58,45 @@ nvkm_ltc_tags_clear(struct nouveau_ltc *ltc, u32 first, u32 count)
|
|||||||
impl->cbc_wait(priv);
|
impl->cbc_wait(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvkm_ltc_zbc_color_get(struct nouveau_ltc *ltc, int index, const u32 color[4])
|
||||||
|
{
|
||||||
|
const struct nvkm_ltc_impl *impl = (void *)nv_oclass(ltc);
|
||||||
|
struct nvkm_ltc_priv *priv = (void *)ltc;
|
||||||
|
memcpy(priv->zbc_color[index], color, sizeof(priv->zbc_color[index]));
|
||||||
|
impl->zbc_clear_color(priv, index, color);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvkm_ltc_zbc_depth_get(struct nouveau_ltc *ltc, int index, const u32 depth)
|
||||||
|
{
|
||||||
|
const struct nvkm_ltc_impl *impl = (void *)nv_oclass(ltc);
|
||||||
|
struct nvkm_ltc_priv *priv = (void *)ltc;
|
||||||
|
priv->zbc_depth[index] = depth;
|
||||||
|
impl->zbc_clear_depth(priv, index, depth);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_nvkm_ltc_init(struct nouveau_object *object)
|
||||||
|
{
|
||||||
|
const struct nvkm_ltc_impl *impl = (void *)nv_oclass(object);
|
||||||
|
struct nvkm_ltc_priv *priv = (void *)object;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
ret = nouveau_subdev_init(&priv->base.base);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = priv->base.zbc_min; i <= priv->base.zbc_max; i++) {
|
||||||
|
impl->zbc_clear_color(priv, i, priv->zbc_color[i]);
|
||||||
|
impl->zbc_clear_depth(priv, i, priv->zbc_depth[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
|
nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||||
struct nouveau_oclass *oclass, int length, void **pobject)
|
struct nouveau_oclass *oclass, int length, void **pobject)
|
||||||
@ -72,9 +111,16 @@ nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
memset(priv->zbc_color, 0x00, sizeof(priv->zbc_color));
|
||||||
|
memset(priv->zbc_depth, 0x00, sizeof(priv->zbc_depth));
|
||||||
|
|
||||||
priv->base.base.intr = impl->intr;
|
priv->base.base.intr = impl->intr;
|
||||||
priv->base.tags_alloc = nvkm_ltc_tags_alloc;
|
priv->base.tags_alloc = nvkm_ltc_tags_alloc;
|
||||||
priv->base.tags_free = nvkm_ltc_tags_free;
|
priv->base.tags_free = nvkm_ltc_tags_free;
|
||||||
priv->base.tags_clear = nvkm_ltc_tags_clear;
|
priv->base.tags_clear = nvkm_ltc_tags_clear;
|
||||||
|
priv->base.zbc_min = 1; /* reserve 0 for disabled */
|
||||||
|
priv->base.zbc_max = min(impl->zbc, NOUVEAU_LTC_MAX_ZBC_CNT) - 1;
|
||||||
|
priv->base.zbc_color_get = nvkm_ltc_zbc_color_get;
|
||||||
|
priv->base.zbc_depth_get = nvkm_ltc_zbc_depth_get;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,23 @@ gf100_ltc_cbc_wait(struct nvkm_ltc_priv *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gf100_ltc_zbc_clear_color(struct nvkm_ltc_priv *priv, int i, const u32 color[4])
|
||||||
|
{
|
||||||
|
nv_mask(priv, 0x17ea44, 0x0000000f, i);
|
||||||
|
nv_wr32(priv, 0x17ea48, color[0]);
|
||||||
|
nv_wr32(priv, 0x17ea4c, color[1]);
|
||||||
|
nv_wr32(priv, 0x17ea50, color[2]);
|
||||||
|
nv_wr32(priv, 0x17ea54, color[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gf100_ltc_zbc_clear_depth(struct nvkm_ltc_priv *priv, int i, const u32 depth)
|
||||||
|
{
|
||||||
|
nv_mask(priv, 0x17ea44, 0x0000000f, i);
|
||||||
|
nv_wr32(priv, 0x17ea58, depth);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gf100_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts)
|
gf100_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts)
|
||||||
{
|
{
|
||||||
@ -194,4 +211,7 @@ gf100_ltc_oclass = &(struct nvkm_ltc_impl) {
|
|||||||
.intr = gf100_ltc_intr,
|
.intr = gf100_ltc_intr,
|
||||||
.cbc_clear = gf100_ltc_cbc_clear,
|
.cbc_clear = gf100_ltc_cbc_clear,
|
||||||
.cbc_wait = gf100_ltc_cbc_wait,
|
.cbc_wait = gf100_ltc_cbc_wait,
|
||||||
|
.zbc = 16,
|
||||||
|
.zbc_clear_color = gf100_ltc_zbc_clear_color,
|
||||||
|
.zbc_clear_depth = gf100_ltc_zbc_clear_depth,
|
||||||
}.base;
|
}.base;
|
||||||
|
@ -52,4 +52,7 @@ gk104_ltc_oclass = &(struct nvkm_ltc_impl) {
|
|||||||
.intr = gf100_ltc_intr,
|
.intr = gf100_ltc_intr,
|
||||||
.cbc_clear = gf100_ltc_cbc_clear,
|
.cbc_clear = gf100_ltc_cbc_clear,
|
||||||
.cbc_wait = gf100_ltc_cbc_wait,
|
.cbc_wait = gf100_ltc_cbc_wait,
|
||||||
|
.zbc = 16,
|
||||||
|
.zbc_clear_color = gf100_ltc_zbc_clear_color,
|
||||||
|
.zbc_clear_depth = gf100_ltc_zbc_clear_depth,
|
||||||
}.base;
|
}.base;
|
||||||
|
@ -45,6 +45,23 @@ gm107_ltc_cbc_wait(struct nvkm_ltc_priv *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gm107_ltc_zbc_clear_color(struct nvkm_ltc_priv *priv, int i, const u32 color[4])
|
||||||
|
{
|
||||||
|
nv_mask(priv, 0x17e338, 0x0000000f, i);
|
||||||
|
nv_wr32(priv, 0x17e33c, color[0]);
|
||||||
|
nv_wr32(priv, 0x17e340, color[1]);
|
||||||
|
nv_wr32(priv, 0x17e344, color[2]);
|
||||||
|
nv_wr32(priv, 0x17e348, color[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gm107_ltc_zbc_clear_depth(struct nvkm_ltc_priv *priv, int i, const u32 depth)
|
||||||
|
{
|
||||||
|
nv_mask(priv, 0x17e338, 0x0000000f, i);
|
||||||
|
nv_wr32(priv, 0x17e34c, depth);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gm107_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts)
|
gm107_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts)
|
||||||
{
|
{
|
||||||
@ -134,4 +151,7 @@ gm107_ltc_oclass = &(struct nvkm_ltc_impl) {
|
|||||||
.intr = gm107_ltc_intr,
|
.intr = gm107_ltc_intr,
|
||||||
.cbc_clear = gm107_ltc_cbc_clear,
|
.cbc_clear = gm107_ltc_cbc_clear,
|
||||||
.cbc_wait = gm107_ltc_cbc_wait,
|
.cbc_wait = gm107_ltc_cbc_wait,
|
||||||
|
.zbc = 16,
|
||||||
|
.zbc_clear_color = gm107_ltc_zbc_clear_color,
|
||||||
|
.zbc_clear_depth = gm107_ltc_zbc_clear_depth,
|
||||||
}.base;
|
}.base;
|
||||||
|
@ -8,10 +8,14 @@ struct nvkm_ltc_priv {
|
|||||||
struct nouveau_ltc base;
|
struct nouveau_ltc base;
|
||||||
u32 ltc_nr;
|
u32 ltc_nr;
|
||||||
u32 lts_nr;
|
u32 lts_nr;
|
||||||
|
|
||||||
u32 num_tags;
|
u32 num_tags;
|
||||||
u32 tag_base;
|
u32 tag_base;
|
||||||
struct nouveau_mm tags;
|
struct nouveau_mm tags;
|
||||||
struct nouveau_mm_node *tag_ram;
|
struct nouveau_mm_node *tag_ram;
|
||||||
|
|
||||||
|
u32 zbc_color[NOUVEAU_LTC_MAX_ZBC_CNT][4];
|
||||||
|
u32 zbc_depth[NOUVEAU_LTC_MAX_ZBC_CNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define nvkm_ltc_create(p,e,o,d) \
|
#define nvkm_ltc_create(p,e,o,d) \
|
||||||
@ -33,7 +37,7 @@ int nvkm_ltc_create_(struct nouveau_object *, struct nouveau_object *,
|
|||||||
struct nouveau_oclass *, int, void **);
|
struct nouveau_oclass *, int, void **);
|
||||||
|
|
||||||
#define _nvkm_ltc_dtor _nouveau_subdev_dtor
|
#define _nvkm_ltc_dtor _nouveau_subdev_dtor
|
||||||
#define _nvkm_ltc_init _nouveau_subdev_init
|
int _nvkm_ltc_init(struct nouveau_object *);
|
||||||
#define _nvkm_ltc_fini _nouveau_subdev_fini
|
#define _nvkm_ltc_fini _nouveau_subdev_fini
|
||||||
|
|
||||||
int gf100_ltc_ctor(struct nouveau_object *, struct nouveau_object *,
|
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 **);
|
|||||||
struct nvkm_ltc_impl {
|
struct nvkm_ltc_impl {
|
||||||
struct nouveau_oclass base;
|
struct nouveau_oclass base;
|
||||||
void (*intr)(struct nouveau_subdev *);
|
void (*intr)(struct nouveau_subdev *);
|
||||||
|
|
||||||
void (*cbc_clear)(struct nvkm_ltc_priv *, u32 start, u32 limit);
|
void (*cbc_clear)(struct nvkm_ltc_priv *, u32 start, u32 limit);
|
||||||
void (*cbc_wait)(struct nvkm_ltc_priv *);
|
void (*cbc_wait)(struct nvkm_ltc_priv *);
|
||||||
|
|
||||||
|
int zbc;
|
||||||
|
void (*zbc_clear_color)(struct nvkm_ltc_priv *, int, const u32[4]);
|
||||||
|
void (*zbc_clear_depth)(struct nvkm_ltc_priv *, int, const u32);
|
||||||
};
|
};
|
||||||
|
|
||||||
void gf100_ltc_intr(struct nouveau_subdev *);
|
void gf100_ltc_intr(struct nouveau_subdev *);
|
||||||
void gf100_ltc_cbc_clear(struct nvkm_ltc_priv *, u32, u32);
|
void gf100_ltc_cbc_clear(struct nvkm_ltc_priv *, u32, u32);
|
||||||
void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *);
|
void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *);
|
||||||
|
void gf100_ltc_zbc_clear_color(struct nvkm_ltc_priv *, int, const u32[4]);
|
||||||
|
void gf100_ltc_zbc_clear_depth(struct nvkm_ltc_priv *, int, const u32);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user