Skip to content

Commit

Permalink
mgag200: Enable atomic gamma lut update
Browse files Browse the repository at this point in the history
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@redhat.com>
  • Loading branch information
Jocelyn Falempe authored and intel-lab-lkp committed May 9, 2022
1 parent b53c24f commit c0e0a39
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_mode.c
Expand Up @@ -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;
Expand Down Expand Up @@ -950,6 +990,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;
Expand All @@ -960,7 +1001,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]);
}

Expand Down Expand Up @@ -1107,6 +1151,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;
Expand Down

0 comments on commit c0e0a39

Please sign in to comment.