[PATCH] mgag200: Enable atomic gamma lut update

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support for atomic update of gamma lut.
With this patch the "Night light" feature of gnome3
is working properly on mgag200.

Signed-off-by: Jocelyn Falempe <jfalempe@xxxxxxxxxx>
---
 drivers/gpu/drm/mgag200/mgag200_mode.c | 46 ++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 6e18d3bbd720..9fc688e15db8 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -86,6 +86,46 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc)
 	}
 }
 
+static void mga_crtc_update_lut(struct mga_device *mdev,
+				struct drm_crtc_state *state,
+				u8 depth)
+{
+	struct drm_color_lut * lut;
+	int i;
+	
+	if (!state->color_mgmt_changed || !state->gamma_lut)
+		return
+
+	lut = (struct drm_color_lut *) state->gamma_lut->data;
+	WREG8(DAC_INDEX + MGA1064_INDEX, 0);
+
+	if (depth == 15) {
+		/* 16 bits r5g5b5a1 */
+		for (i = 0; i < MGAG200_LUT_SIZE; i += 8) {
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].red >> 8);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].green >> 8);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].blue >> 8);
+		}
+	} else if (depth == 16) {
+		/* 16 bits r5g6b5, as green has one more bit, 
+		 * add padding with 0 for red and blue. */
+		for (i = 0; i < MGAG200_LUT_SIZE; i += 4) {
+			u8 red = 2 * i < MGAG200_LUT_SIZE ? lut[2 * i].red >> 8 : 0;
+			u8 blue = 2 * i < MGAG200_LUT_SIZE ? lut[2 * i].red >> 8 : 0;
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, red);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].green >> 8);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, blue);
+		}
+	} else {
+		/* 24 bits r8g8b8 */
+		for (i = 0; i < MGAG200_LUT_SIZE; i++) {
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].red >> 8);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].green >> 8);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].blue >> 8);
+		}
+	}
+}
+
 static inline void mga_wait_vsync(struct mga_device *mdev)
 {
 	unsigned long timeout = jiffies + HZ/10;
@@ -953,6 +993,7 @@ mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
 				   struct drm_plane_state *old_state)
 {
 	struct drm_plane *plane = &pipe->plane;
+	struct drm_crtc *crtc = &pipe->crtc;
 	struct drm_device *dev = plane->dev;
 	struct mga_device *mdev = to_mga_device(dev);
 	struct drm_plane_state *state = plane->state;
@@ -963,7 +1004,10 @@ mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
 	if (!fb)
 		return;
 
+	mga_crtc_update_lut(mdev, crtc->state, fb->format->depth);
+
 	if (drm_atomic_helper_damage_merged(old_state, state, &damage))
+
 		mgag200_handle_damage(mdev, fb, &damage, &shadow_plane_state->data[0]);
 }
 
@@ -1110,6 +1154,8 @@ int mgag200_modeset_init(struct mga_device *mdev)
 	/* FIXME: legacy gamma tables; convert to CRTC state */
 	drm_mode_crtc_set_gamma_size(&pipe->crtc, MGAG200_LUT_SIZE);
 
+	drm_crtc_enable_color_mgmt(&pipe->crtc, 0, false, MGAG200_LUT_SIZE);
+
 	drm_mode_config_reset(dev);
 
 	return 0;
-- 
2.35.3




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux