summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2022-07-28 15:40:54 +0300
committerThomas Zimmermann <tzimmermann@suse.de>2022-07-29 17:01:46 +0300
commited2ef21f1089ef9b3b943b4e365600e615ce827d (patch)
treeee257f9b63775663066ca18289da47f148e6ff64
parent2d70b9a1482e09f8465452c4655ffe20c605d526 (diff)
downloadlinux-ed2ef21f1089ef9b3b943b4e365600e615ce827d.tar.xz
drm/mgag200: Store primary plane's color format in CRTC state
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
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h3
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c22
2 files changed, 15 insertions, 10 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index face2904556a..bf6a01ff9719 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -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;
};
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 6635d8745851..e392e2646359 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -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;
@@ -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;
@@ -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;
@@ -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,
@@ -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);
@@ -715,7 +714,7 @@ 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);
@@ -723,9 +722,9 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
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);
@@ -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);
@@ -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));