Commit 13199270 authored by Ilia Mirkin's avatar Ilia Mirkin Committed by Ben Skeggs
Browse files

drm/nouveau/kms/gf119-: allow both 256- and 1024-sized LUTs to be used



The hardware supports either size. Also add checks to ensure that only
these two sizes may be used for supplying a LUT.

Signed-off-by: default avatarIlia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 11a86309
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -75,12 +75,16 @@ base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
	}
}

static void
base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
static bool
base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
{
	asyw->xlut.i.mode = 7;
	if (size != 256 && size != 1024)
		return false;

	asyw->xlut.i.mode = size == 1024 ? 4 : 7;
	asyw->xlut.i.enable = 2;
	asyw->xlut.i.load = head907d_olut_load;
	return true;
}

static inline u32
@@ -160,6 +164,7 @@ base907c = {
	.csc_set = base907c_csc_set,
	.csc_clr = base907c_csc_clr,
	.olut_core = true,
	.ilut_size = 1024,
	.xlut_set = base907c_xlut_set,
	.xlut_clr = base907c_xlut_clr,
	.image_set = base907c_image_set,
+18 −8
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ nv50_head_atomic_check_lut(struct nv50_head *head,
{
	struct nv50_disp *disp = nv50_disp(head->base.base.dev);
	struct drm_property_blob *olut = asyh->state.gamma_lut;
	int size;

	/* Determine whether core output LUT should be enabled. */
	if (olut) {
@@ -229,14 +230,23 @@ nv50_head_atomic_check_lut(struct nv50_head *head,
		}
	}

	if (!olut && !head->func->olut_identity) {
	if (!olut) {
		if (!head->func->olut_identity) {
			asyh->olut.handle = 0;
			return 0;
		}
		size = 0;
	} else {
		size = drm_color_lut_size(olut);
	}

	if (!head->func->olut(head, asyh, size)) {
		DRM_DEBUG_KMS("Invalid olut\n");
		return -EINVAL;
	}
	asyh->olut.handle = disp->core->chan.vram.handle;
	asyh->olut.buffer = !asyh->olut.buffer;
	head->func->olut(head, asyh);

	return 0;
}

@@ -510,11 +520,11 @@ nv50_head_create(struct drm_device *dev, int index)
	drm_crtc_init_with_planes(dev, crtc, &base->plane, &curs->plane,
				  &nv50_head_func, "head-%d", head->base.index);
	drm_crtc_helper_add(crtc, &nv50_head_help);
	/* Keep the legacy gamma size at 256 to avoid compatibility issues */
	drm_mode_crtc_set_gamma_size(crtc, 256);
	if (disp->disp->object.oclass >= GF110_DISP)
		drm_crtc_enable_color_mgmt(crtc, 256, true, 256);
	else
		drm_crtc_enable_color_mgmt(crtc, 0, false, 256);
	drm_crtc_enable_color_mgmt(crtc, base->func->ilut_size,
				   disp->disp->object.oclass >= GF110_DISP,
				   head->func->olut_size);

	if (head->func->olut_set) {
		ret = nv50_lut_init(disp, &drm->client.mmu, &head->olut);
+4 −3
Original line number Diff line number Diff line
@@ -20,8 +20,9 @@ void nv50_head_flush_clr(struct nv50_head *, struct nv50_head_atom *, bool y);
struct nv50_head_func {
	void (*view)(struct nv50_head *, struct nv50_head_atom *);
	void (*mode)(struct nv50_head *, struct nv50_head_atom *);
	void (*olut)(struct nv50_head *, struct nv50_head_atom *);
	bool (*olut)(struct nv50_head *, struct nv50_head_atom *, int);
	bool olut_identity;
	int  olut_size;
	void (*olut_set)(struct nv50_head *, struct nv50_head_atom *);
	void (*olut_clr)(struct nv50_head *);
	void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
@@ -43,7 +44,7 @@ struct nv50_head_func {
extern const struct nv50_head_func head507d;
void head507d_view(struct nv50_head *, struct nv50_head_atom *);
void head507d_mode(struct nv50_head *, struct nv50_head_atom *);
void head507d_olut(struct nv50_head *, struct nv50_head_atom *);
bool head507d_olut(struct nv50_head *, struct nv50_head_atom *, int);
void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *);
void head507d_core_clr(struct nv50_head *);
int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
@@ -60,7 +61,7 @@ extern const struct nv50_head_func head827d;
extern const struct nv50_head_func head907d;
void head907d_view(struct nv50_head *, struct nv50_head_atom *);
void head907d_mode(struct nv50_head *, struct nv50_head_atom *);
void head907d_olut(struct nv50_head *, struct nv50_head_atom *);
bool head907d_olut(struct nv50_head *, struct nv50_head_atom *, int);
void head907d_olut_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_olut_clr(struct nv50_head *);
void head907d_core_set(struct nv50_head *, struct nv50_head_atom *);
+7 −2
Original line number Diff line number Diff line
@@ -271,15 +271,19 @@ head507d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
	writew(readw(mem - 4), mem + 4);
}

void
head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
bool
head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
{
	if (size != 256)
		return false;

	if (asyh->base.cpp == 1)
		asyh->olut.mode = 0;
	else
		asyh->olut.mode = 1;

	asyh->olut.load = head507d_olut_load;
	return true;
}

void
@@ -328,6 +332,7 @@ head507d = {
	.view = head507d_view,
	.mode = head507d_mode,
	.olut = head507d_olut,
	.olut_size = 256,
	.olut_set = head507d_olut_set,
	.olut_clr = head507d_olut_clr,
	.core_calc = head507d_core_calc,
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ head827d = {
	.view = head507d_view,
	.mode = head507d_mode,
	.olut = head507d_olut,
	.olut_size = 256,
	.olut_set = head827d_olut_set,
	.olut_clr = head827d_olut_clr,
	.core_calc = head507d_core_calc,
Loading