Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f38fdb6a authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/ltc: add zbc drivers



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 95484b57
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@
#include <core/subdev.h>
#include <core/device.h>

#define NOUVEAU_LTC_MAX_ZBC_CNT 16

struct nouveau_mm_node;

struct nouveau_ltc {
@@ -13,6 +15,11 @@ 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);

	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 *
+46 −0
Original line number Diff line number Diff line
@@ -58,6 +58,45 @@ nvkm_ltc_tags_clear(struct nouveau_ltc *ltc, u32 first, u32 count)
	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
nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
		 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)
		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.tags_alloc = nvkm_ltc_tags_alloc;
	priv->base.tags_free = nvkm_ltc_tags_free;
	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;
}
+20 −0
Original line number Diff line number Diff line
@@ -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
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,
	.cbc_clear = gf100_ltc_cbc_clear,
	.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;
+3 −0
Original line number Diff line number Diff line
@@ -52,4 +52,7 @@ gk104_ltc_oclass = &(struct nvkm_ltc_impl) {
	.intr = gf100_ltc_intr,
	.cbc_clear = gf100_ltc_cbc_clear,
	.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;
+20 −0
Original line number Diff line number Diff line
@@ -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
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,
	.cbc_clear = gm107_ltc_cbc_clear,
	.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;
Loading