Skip to content

Commit

Permalink
drm/mgag200: Store primary plane's color format in CRTC state
Browse files Browse the repository at this point in the history
Store the primary plane's color format in the CRTC state and use
it for programming the CRTC's gamma LUTs.

Gamma tables (i.e., color management) are provided by the CRTC, but
depend in the primary plane's color format. Store the format in the
CRTC state and use it. This has not been an issue with simple-KMS
helpers, which mix-up plane and CRTC state to some extent. For using
regular atomic helpers, it's necessary to distinguish between the two.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Tested-by: Jocelyn Falempe <jfalempe@redhat.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220728124103.30159-6-tzimmermann@suse.de
  • Loading branch information
Thomas Zimmermann committed Jul 29, 2022
1 parent 2d70b9a commit ed2ef21
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 10 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ struct mgag200_pll {
struct mgag200_crtc_state {
struct drm_crtc_state base;

/* Primary-plane format; required for modesetting and color mgmt. */
const struct drm_format_info *format;

struct mgag200_pll_values pixpllc;
};

Expand Down
22 changes: 12 additions & 10 deletions drivers/gpu/drm/mgag200/mgag200_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,9 @@ static void mgag200_set_offset(struct mga_device *mdev,
WREG_ECRT(0x00, crtcext0);
}

static void mgag200_set_format_regs(struct mga_device *mdev,
const struct drm_framebuffer *fb)
static void mgag200_set_format_regs(struct mga_device *mdev, const struct drm_format_info *format)
{
struct drm_device *dev = &mdev->base;
const struct drm_format_info *format = fb->format;
unsigned int bpp, bppshift, scale;
u8 crtcext3, xmulctrl;

Expand Down Expand Up @@ -501,7 +499,7 @@ static void mgag200_g200er_reset_tagfifo(struct mga_device *mdev)

static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev,
const struct drm_display_mode *mode,
const struct drm_framebuffer *fb)
const struct drm_format_info *format)
{
struct mgag200_g200se_device *g200se = to_mgag200_g200se_device(&mdev->base);
unsigned int hiprilvl;
Expand All @@ -513,9 +511,9 @@ static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev,
unsigned int bpp;
unsigned long mb;

if (fb->format->cpp[0] * 8 > 16)
if (format->cpp[0] * 8 > 16)
bpp = 32;
else if (fb->format->cpp[0] * 8 > 8)
else if (format->cpp[0] * 8 > 8)
bpp = 16;
else
bpp = 8;
Expand Down Expand Up @@ -695,6 +693,7 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state);
struct drm_framebuffer *fb = plane_state->fb;
const struct drm_format_info *format = mgag200_crtc_state->format;
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_rect fullscreen = {
.x1 = 0,
Expand All @@ -706,7 +705,7 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
if (mdev->type == G200_WB || mdev->type == G200_EW3)
mgag200_g200wb_hold_bmc(mdev);

mgag200_set_format_regs(mdev, fb);
mgag200_set_format_regs(mdev, format);
mgag200_set_mode_regs(mdev, adjusted_mode);

pixpll->funcs->update(pixpll, &mgag200_crtc_state->pixpllc);
Expand All @@ -715,17 +714,17 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
mgag200_g200er_reset_tagfifo(mdev);

if (IS_G200_SE(mdev))
mgag200_g200se_set_hiprilvl(mdev, adjusted_mode, fb);
mgag200_g200se_set_hiprilvl(mdev, adjusted_mode, format);
else if (mdev->type == G200_EV)
mgag200_g200ev_set_hiprilvl(mdev);

if (mdev->type == G200_WB || mdev->type == G200_EW3)
mgag200_g200wb_release_bmc(mdev);

if (crtc_state->gamma_lut)
mgag200_crtc_set_gamma(mdev, fb->format, crtc_state->gamma_lut->data);
mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data);
else
mgag200_crtc_set_gamma_linear(mdev, fb->format);
mgag200_crtc_set_gamma_linear(mdev, format);

mgag200_enable_display(mdev);

Expand Down Expand Up @@ -768,6 +767,8 @@ mgag200_simple_display_pipe_check(struct drm_simple_display_pipe *pipe,
if (!fb || (fb->format != new_fb->format))
crtc_state->mode_changed = true; /* update PLL settings */

mgag200_crtc_state->format = new_fb->format;

if (crtc_state->mode_changed) {
ret = pixpll->funcs->compute(pixpll, crtc_state->mode.clock,
&mgag200_crtc_state->pixpllc);
Expand Down Expand Up @@ -831,6 +832,7 @@ mgag200_simple_display_pipe_duplicate_crtc_state(struct drm_simple_display_pipe
return NULL;
__drm_atomic_helper_crtc_duplicate_state(crtc, &new_mgag200_crtc_state->base);

new_mgag200_crtc_state->format = mgag200_crtc_state->format;
memcpy(&new_mgag200_crtc_state->pixpllc, &mgag200_crtc_state->pixpllc,
sizeof(new_mgag200_crtc_state->pixpllc));

Expand Down

0 comments on commit ed2ef21

Please sign in to comment.