diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-11-21 13:03:42 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-11-29 09:57:57 +1000 |
commit | f9887d091149406de5c8b388f7e0bb6932dd621b (patch) | |
tree | b00c5f5edb3b8195908fc5712a968b35fa8f497d | |
parent | 647bf61d0399515c526c125450cadaade79b1988 (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 35 |
2 files changed, 36 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index b875fcff973a..f03b07556484 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -324,7 +324,7 @@ nouveau_display_create(struct drm_device *dev) disp->underscan_vborder_property = drm_property_create_range(dev, 0, "underscan vborder", 0, 128); - if (gen == 1) { + if (gen >= 1) { disp->vibrant_hue_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, "vibrant hue", 2); diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index b444aa7a8ae8..f8ff7786ea95 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c @@ -741,6 +741,37 @@ nvd0_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) } 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 @@ nvd0_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, 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 @@ nvd0_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) 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++) { |