[PATCH 05/17] drm/cirrus: Split cirrus_mode_set() into smaller functions
Thomas Zimmermann
tzimmermann at suse.de
Wed Feb 15 16:15:05 UTC 2023
Split cirrus_mode_set() into smaller functions that set the display
mode, color format and scnaline pitch individually. Better reflects
the design of the DRM modesetting pipeline.
Done in preparation of converting cirrus to regular atomic helpers.
Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
drivers/gpu/drm/tiny/cirrus.c | 63 +++++++++++++++++++++--------------
1 file changed, 38 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c
index 0b02244bd9f1..60488e49bdb5 100644
--- a/drivers/gpu/drm/tiny/cirrus.c
+++ b/drivers/gpu/drm/tiny/cirrus.c
@@ -178,14 +178,12 @@ static void cirrus_set_start_address(struct cirrus_device *cirrus, u32 offset)
wreg_crt(cirrus, 0x1d, tmp);
}
-static int cirrus_mode_set(struct cirrus_device *cirrus,
- struct drm_display_mode *mode,
- struct drm_framebuffer *fb)
+static void cirrus_mode_set(struct cirrus_device *cirrus,
+ struct drm_display_mode *mode)
{
int hsyncstart, hsyncend, htotal, hdispend;
int vtotal, vdispend;
int tmp;
- int sr07 = 0, hdr = 0;
htotal = mode->htotal / 8;
hsyncend = mode->hsync_end / 8;
@@ -249,15 +247,21 @@ static int cirrus_mode_set(struct cirrus_device *cirrus,
/* Disable Hercules/CGA compatibility */
wreg_crt(cirrus, VGA_CRTC_MODE, 0x03);
+}
+
+static void cirrus_format_set(struct cirrus_device *cirrus,
+ struct drm_framebuffer *fb)
+{
+ u8 sr07, hdr;
sr07 = rreg_seq(cirrus, 0x07);
sr07 &= 0xe0;
- hdr = 0;
cirrus->format = cirrus_format(fb);
switch (cirrus->format->format) {
case DRM_FORMAT_C8:
sr07 |= 0x11;
+ hdr = 0x00;
break;
case DRM_FORMAT_RGB565:
sr07 |= 0x17;
@@ -272,22 +276,11 @@ static int cirrus_mode_set(struct cirrus_device *cirrus,
hdr = 0xc5;
break;
default:
- return -1;
+ return;
}
wreg_seq(cirrus, 0x7, sr07);
- /* Program the pitch */
- cirrus->pitch = cirrus_pitch(fb);
- tmp = cirrus->pitch / 8;
- wreg_crt(cirrus, VGA_CRTC_OFFSET, tmp);
-
- /* Enable extended blanking and pitch bits, and enable full memory */
- tmp = 0x22;
- tmp |= (cirrus->pitch >> 7) & 0x10;
- tmp |= (cirrus->pitch >> 6) & 0x40;
- wreg_crt(cirrus, 0x1b, tmp);
-
/* Enable high-colour modes */
wreg_gfx(cirrus, VGA_GFX_MODE, 0x40);
@@ -295,13 +288,25 @@ static int cirrus_mode_set(struct cirrus_device *cirrus,
wreg_gfx(cirrus, VGA_GFX_MISC, 0x01);
wreg_hdr(cirrus, hdr);
+}
- cirrus_set_start_address(cirrus, 0);
+static void cirrus_pitch_set(struct cirrus_device *cirrus,
+ struct drm_framebuffer *fb)
+{
+ u8 cr13, cr1b;
- /* Unblank (needed on S3 resume, vgabios doesn't do it then) */
- outb(0x20, 0x3c0);
+ /* Program the pitch */
+ cirrus->pitch = cirrus_pitch(fb);
+ cr13 = cirrus->pitch / 8;
+ wreg_crt(cirrus, VGA_CRTC_OFFSET, cr13);
- return 0;
+ /* Enable extended blanking and pitch bits, and enable full memory */
+ cr1b = 0x22;
+ cr1b |= (cirrus->pitch >> 7) & 0x10;
+ cr1b |= (cirrus->pitch >> 6) & 0x40;
+ wreg_crt(cirrus, 0x1b, cr1b);
+
+ cirrus_set_start_address(cirrus, 0);
}
static int cirrus_fb_blit_rect(struct drm_framebuffer *fb,
@@ -413,9 +418,14 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe,
if (!drm_dev_enter(&cirrus->dev, &idx))
return;
- cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb);
+ cirrus_mode_set(cirrus, &crtc_state->mode);
+ cirrus_format_set(cirrus, plane_state->fb);
+ cirrus_pitch_set(cirrus, plane_state->fb);
cirrus_fb_blit_fullscreen(plane_state->fb, &shadow_plane_state->data[0]);
+ /* Unblank (needed on S3 resume, vgabios doesn't do it then) */
+ outb(0x20, 0x3c0);
+
drm_dev_exit(idx);
}
@@ -425,15 +435,18 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev);
struct drm_plane_state *state = pipe->plane.state;
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
- struct drm_crtc *crtc = &pipe->crtc;
struct drm_rect rect;
int idx;
if (!drm_dev_enter(&cirrus->dev, &idx))
return;
- if (state->fb && cirrus->format != cirrus_format(state->fb))
- cirrus_mode_set(cirrus, &crtc->mode, state->fb);
+ if (state->fb) {
+ if (cirrus->format != cirrus_format(state->fb))
+ cirrus_format_set(cirrus, state->fb);
+ if (cirrus->pitch != cirrus_pitch(state->fb))
+ cirrus_pitch_set(cirrus, state->fb);
+ }
if (drm_atomic_helper_damage_merged(old_state, state, &rect))
cirrus_fb_blit_rect(state->fb, &shadow_plane_state->data[0], &rect);
--
2.39.1
More information about the dri-devel
mailing list