drm/nvd0/disp: implement support for colour vibrance control

Ported from original nv50 commit by Christoph, with added support for the
setting on later chipsets.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index b444aa7..f8ff778 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -741,6 +741,37 @@
 }
 
 static int
+nvd0_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update)
+{
+	struct nvd0_mast *mast = nvd0_mast(nv_crtc->base.dev);
+	u32 *push, hue, vib;
+	int adj;
+
+	adj = (nv_crtc->color_vibrance > 0) ? 50 : 0;
+	vib = ((nv_crtc->color_vibrance * 2047 + adj) / 100) & 0xfff;
+	hue = ((nv_crtc->vibrant_hue * 2047) / 100) & 0xfff;
+
+	push = evo_wait(mast, 16);
+	if (push) {
+		if (nvd0_vers(mast) < NVD0_DISP_MAST_CLASS) {
+			evo_mthd(push, 0x08a8 + (nv_crtc->index * 0x400), 1);
+			evo_data(push, (hue << 20) | (vib << 8));
+		} else {
+			evo_mthd(push, 0x0498 + (nv_crtc->index * 0x300), 1);
+			evo_data(push, (hue << 20) | (vib << 8));
+		}
+
+		if (update) {
+			evo_mthd(push, 0x0080, 1);
+			evo_data(push, 0x00000000);
+		}
+		evo_kick(push, mast);
+	}
+
+	return 0;
+}
+
+static int
 nvd0_crtc_set_image(struct nouveau_crtc *nv_crtc, struct drm_framebuffer *fb,
 		    int x, int y, bool update)
 {
@@ -1055,6 +1086,7 @@
 	nv_connector = nouveau_crtc_connector_get(nv_crtc);
 	nvd0_crtc_set_dither(nv_crtc, false);
 	nvd0_crtc_set_scale(nv_crtc, false);
+	nvd0_crtc_set_color_vibrance(nv_crtc, false);
 	nvd0_crtc_set_image(nv_crtc, crtc->fb, x, y, false);
 	return 0;
 }
@@ -1248,6 +1280,9 @@
 	head->base.index = index;
 	head->base.set_dither = nvd0_crtc_set_dither;
 	head->base.set_scale = nvd0_crtc_set_scale;
+	head->base.set_color_vibrance = nvd0_crtc_set_color_vibrance;
+	head->base.color_vibrance = 50;
+	head->base.vibrant_hue = 0;
 	head->base.cursor.set_offset = nvd0_cursor_set_offset;
 	head->base.cursor.set_pos = nvd0_cursor_set_pos;
 	for (i = 0; i < 256; i++) {