diff options
author | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2012-01-21 17:13:26 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-03-13 03:14:56 -0400 |
commit | df26bc9c320602539b1b5b3d85786e4c8de7bf43 (patch) | |
tree | a7f52151883a1c54a88e7549552effe65b8c0b35 /drivers/gpu | |
parent | 990449c77cafb77e7468722262c049675ab03e30 (diff) |
drm/nv50/display: expose color vibrance control
Signed-off-by: Christoph Bumiller <e0425955@student.tuwien.ac.at>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_crtc.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_crtc.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_evo.h | 3 |
6 files changed, 85 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index cdae563be5bd..9f9d50dbca7f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -519,6 +519,19 @@ nouveau_connector_set_property(struct drm_connector *connector, | |||
519 | return nv_crtc->set_dither(nv_crtc, true); | 519 | return nv_crtc->set_dither(nv_crtc, true); |
520 | } | 520 | } |
521 | 521 | ||
522 | if (nv_crtc && nv_crtc->set_color_vibrance) { | ||
523 | /* Hue */ | ||
524 | if (property == disp->vibrant_hue_property) { | ||
525 | nv_crtc->vibrant_hue = value - 90; | ||
526 | return nv_crtc->set_color_vibrance(nv_crtc, true); | ||
527 | } | ||
528 | /* Saturation */ | ||
529 | if (property == disp->color_vibrance_property) { | ||
530 | nv_crtc->color_vibrance = value - 100; | ||
531 | return nv_crtc->set_color_vibrance(nv_crtc, true); | ||
532 | } | ||
533 | } | ||
534 | |||
522 | if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) | 535 | if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) |
523 | return get_slave_funcs(encoder)->set_property( | 536 | return get_slave_funcs(encoder)->set_property( |
524 | encoder, connector, property, value); | 537 | encoder, connector, property, value); |
@@ -1018,6 +1031,16 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
1018 | 0); | 1031 | 0); |
1019 | } | 1032 | } |
1020 | 1033 | ||
1034 | /* Add hue and saturation options */ | ||
1035 | if (disp->vibrant_hue_property) | ||
1036 | drm_connector_attach_property(connector, | ||
1037 | disp->vibrant_hue_property, | ||
1038 | 90); | ||
1039 | if (disp->color_vibrance_property) | ||
1040 | drm_connector_attach_property(connector, | ||
1041 | disp->color_vibrance_property, | ||
1042 | 150); | ||
1043 | |||
1021 | switch (nv_connector->type) { | 1044 | switch (nv_connector->type) { |
1022 | case DCB_CONNECTOR_VGA: | 1045 | case DCB_CONNECTOR_VGA: |
1023 | if (dev_priv->card_type >= NV_50) { | 1046 | if (dev_priv->card_type >= NV_50) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h index 686f6b4a1da3..e6d0d1eb0133 100644 --- a/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h | |||
@@ -35,6 +35,8 @@ struct nouveau_crtc { | |||
35 | uint32_t dpms_saved_fp_control; | 35 | uint32_t dpms_saved_fp_control; |
36 | uint32_t fp_users; | 36 | uint32_t fp_users; |
37 | int saturation; | 37 | int saturation; |
38 | int color_vibrance; | ||
39 | int vibrant_hue; | ||
38 | int sharpness; | 40 | int sharpness; |
39 | int last_dpms; | 41 | int last_dpms; |
40 | 42 | ||
@@ -67,6 +69,7 @@ struct nouveau_crtc { | |||
67 | 69 | ||
68 | int (*set_dither)(struct nouveau_crtc *crtc, bool update); | 70 | int (*set_dither)(struct nouveau_crtc *crtc, bool update); |
69 | int (*set_scale)(struct nouveau_crtc *crtc, bool update); | 71 | int (*set_scale)(struct nouveau_crtc *crtc, bool update); |
72 | int (*set_color_vibrance)(struct nouveau_crtc *crtc, bool update); | ||
70 | }; | 73 | }; |
71 | 74 | ||
72 | static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc) | 75 | static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 5565e5056ba1..35acc92f647b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -286,6 +286,20 @@ nouveau_display_create(struct drm_device *dev) | |||
286 | disp->underscan_vborder_property = | 286 | disp->underscan_vborder_property = |
287 | drm_property_create_range(dev, 0, "underscan vborder", 0, 128); | 287 | drm_property_create_range(dev, 0, "underscan vborder", 0, 128); |
288 | 288 | ||
289 | if (gen == 1) { | ||
290 | disp->vibrant_hue_property = | ||
291 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
292 | "vibrant hue", 2); | ||
293 | disp->vibrant_hue_property->values[0] = 0; | ||
294 | disp->vibrant_hue_property->values[1] = 180; /* -90..+90 */ | ||
295 | |||
296 | disp->color_vibrance_property = | ||
297 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
298 | "color vibrance", 2); | ||
299 | disp->color_vibrance_property->values[0] = 0; | ||
300 | disp->color_vibrance_property->values[1] = 200; /* -100..+100 */ | ||
301 | } | ||
302 | |||
289 | dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; | 303 | dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; |
290 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1); | 304 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1); |
291 | 305 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3a69a4aabd35..4bb6aeec91f6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -406,6 +406,9 @@ struct nouveau_display_engine { | |||
406 | struct drm_property *underscan_property; | 406 | struct drm_property *underscan_property; |
407 | struct drm_property *underscan_hborder_property; | 407 | struct drm_property *underscan_hborder_property; |
408 | struct drm_property *underscan_vborder_property; | 408 | struct drm_property *underscan_vborder_property; |
409 | /* not really hue and saturation: */ | ||
410 | struct drm_property *vibrant_hue_property; | ||
411 | struct drm_property *color_vibrance_property; | ||
409 | }; | 412 | }; |
410 | 413 | ||
411 | struct nouveau_gpio_engine { | 414 | struct nouveau_gpio_engine { |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 8f6c2ace3adf..701b927998bf 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -170,6 +170,41 @@ nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update) | |||
170 | return ret; | 170 | return ret; |
171 | } | 171 | } |
172 | 172 | ||
173 | static int | ||
174 | nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) | ||
175 | { | ||
176 | struct drm_device *dev = nv_crtc->base.dev; | ||
177 | struct nouveau_channel *evo = nv50_display(dev)->master; | ||
178 | int ret; | ||
179 | int adj; | ||
180 | u32 hue, vib; | ||
181 | |||
182 | NV_DEBUG_KMS(dev, "vibrance = %i, hue = %i\n", | ||
183 | nv_crtc->color_vibrance, nv_crtc->vibrant_hue); | ||
184 | |||
185 | ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); | ||
186 | if (ret) { | ||
187 | NV_ERROR(dev, "no space while setting color vibrance\n"); | ||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | adj = (nv_crtc->color_vibrance > 0) ? 50 : 0; | ||
192 | vib = ((nv_crtc->color_vibrance * 2047 + adj) / 100) & 0xfff; | ||
193 | |||
194 | hue = ((nv_crtc->vibrant_hue * 2047) / 100) & 0xfff; | ||
195 | |||
196 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); | ||
197 | OUT_RING (evo, (hue << 20) | (vib << 8)); | ||
198 | |||
199 | if (update) { | ||
200 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | ||
201 | OUT_RING (evo, 0); | ||
202 | FIRE_RING (evo); | ||
203 | } | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
173 | struct nouveau_connector * | 208 | struct nouveau_connector * |
174 | nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) | 209 | nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) |
175 | { | 210 | { |
@@ -577,8 +612,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
577 | OUT_RING (evo, fb->base.depth == 8 ? | 612 | OUT_RING (evo, fb->base.depth == 8 ? |
578 | NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); | 613 | NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); |
579 | 614 | ||
580 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); | ||
581 | OUT_RING (evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR); | ||
582 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); | 615 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); |
583 | OUT_RING (evo, (y << 16) | x); | 616 | OUT_RING (evo, (y << 16) | x); |
584 | 617 | ||
@@ -661,6 +694,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
661 | 694 | ||
662 | nv_crtc->set_dither(nv_crtc, false); | 695 | nv_crtc->set_dither(nv_crtc, false); |
663 | nv_crtc->set_scale(nv_crtc, false); | 696 | nv_crtc->set_scale(nv_crtc, false); |
697 | nv_crtc->set_color_vibrance(nv_crtc, false); | ||
664 | 698 | ||
665 | return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false); | 699 | return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false); |
666 | } | 700 | } |
@@ -721,6 +755,9 @@ nv50_crtc_create(struct drm_device *dev, int index) | |||
721 | if (!nv_crtc) | 755 | if (!nv_crtc) |
722 | return -ENOMEM; | 756 | return -ENOMEM; |
723 | 757 | ||
758 | nv_crtc->color_vibrance = 50; | ||
759 | nv_crtc->vibrant_hue = 0; | ||
760 | |||
724 | /* Default CLUT parameters, will be activated on the hw upon | 761 | /* Default CLUT parameters, will be activated on the hw upon |
725 | * first mode set. | 762 | * first mode set. |
726 | */ | 763 | */ |
@@ -751,6 +788,7 @@ nv50_crtc_create(struct drm_device *dev, int index) | |||
751 | /* set function pointers */ | 788 | /* set function pointers */ |
752 | nv_crtc->set_dither = nv50_crtc_set_dither; | 789 | nv_crtc->set_dither = nv50_crtc_set_dither; |
753 | nv_crtc->set_scale = nv50_crtc_set_scale; | 790 | nv_crtc->set_scale = nv50_crtc_set_scale; |
791 | nv_crtc->set_color_vibrance = nv50_crtc_set_color_vibrance; | ||
754 | 792 | ||
755 | drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs); | 793 | drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs); |
756 | drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs); | 794 | drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs); |
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.h b/drivers/gpu/drm/nouveau/nv50_evo.h index 3860ca62cb19..771d879bc834 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.h +++ b/drivers/gpu/drm/nouveau/nv50_evo.h | |||
@@ -104,7 +104,8 @@ | |||
104 | #define NV50_EVO_CRTC_SCALE_CTRL_INACTIVE 0x00000000 | 104 | #define NV50_EVO_CRTC_SCALE_CTRL_INACTIVE 0x00000000 |
105 | #define NV50_EVO_CRTC_SCALE_CTRL_ACTIVE 0x00000009 | 105 | #define NV50_EVO_CRTC_SCALE_CTRL_ACTIVE 0x00000009 |
106 | #define NV50_EVO_CRTC_COLOR_CTRL 0x000008a8 | 106 | #define NV50_EVO_CRTC_COLOR_CTRL 0x000008a8 |
107 | #define NV50_EVO_CRTC_COLOR_CTRL_COLOR 0x00040000 | 107 | #define NV50_EVO_CRTC_COLOR_CTRL_VIBRANCE 0x000fff00 |
108 | #define NV50_EVO_CRTC_COLOR_CTRL_HUE 0xfff00000 | ||
108 | #define NV50_EVO_CRTC_FB_POS 0x000008c0 | 109 | #define NV50_EVO_CRTC_FB_POS 0x000008c0 |
109 | #define NV50_EVO_CRTC_REAL_RES 0x000008c8 | 110 | #define NV50_EVO_CRTC_REAL_RES 0x000008c8 |
110 | #define NV50_EVO_CRTC_SCALE_CENTER_OFFSET 0x000008d4 | 111 | #define NV50_EVO_CRTC_SCALE_CENTER_OFFSET 0x000008d4 |