Commit de7d09ff authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/cirrus: Store HW format/pitch in primary-plane state

The hardware settings for color format and pitch are state of the
primary plane. Store the values in the primary plane's state structure
struct cirrus_primary_plane_state. Adapt all callers.

All fields in struct cirrus_device are now considered immutable after
initialization. Plane updates consider the difference between the old
and the new plane state before updating format or pitch.
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230215161517.5113-17-tzimmermann@suse.de
parent 74b9a444
...@@ -63,10 +63,6 @@ struct cirrus_device { ...@@ -63,10 +63,6 @@ struct cirrus_device {
struct drm_encoder encoder; struct drm_encoder encoder;
struct drm_connector connector; struct drm_connector connector;
/* HW scanout buffer */
const struct drm_format_info *format;
unsigned int pitch;
/* HW resources */ /* HW resources */
void __iomem *vram; void __iomem *vram;
void __iomem *mmio; void __iomem *mmio;
...@@ -76,6 +72,10 @@ struct cirrus_device { ...@@ -76,6 +72,10 @@ struct cirrus_device {
struct cirrus_primary_plane_state { struct cirrus_primary_plane_state {
struct drm_shadow_plane_state base; struct drm_shadow_plane_state base;
/* HW scanout buffer */
const struct drm_format_info *format;
unsigned int pitch;
}; };
static inline struct cirrus_primary_plane_state * static inline struct cirrus_primary_plane_state *
...@@ -268,15 +268,14 @@ static void cirrus_mode_set(struct cirrus_device *cirrus, ...@@ -268,15 +268,14 @@ static void cirrus_mode_set(struct cirrus_device *cirrus,
} }
static void cirrus_format_set(struct cirrus_device *cirrus, static void cirrus_format_set(struct cirrus_device *cirrus,
struct drm_framebuffer *fb) const struct drm_format_info *format)
{ {
u8 sr07, hdr; u8 sr07, hdr;
sr07 = rreg_seq(cirrus, 0x07); sr07 = rreg_seq(cirrus, 0x07);
sr07 &= 0xe0; sr07 &= 0xe0;
cirrus->format = cirrus_format(fb); switch (format->format) {
switch (cirrus->format->format) {
case DRM_FORMAT_C8: case DRM_FORMAT_C8:
sr07 |= 0x11; sr07 |= 0x11;
hdr = 0x00; hdr = 0x00;
...@@ -308,20 +307,18 @@ static void cirrus_format_set(struct cirrus_device *cirrus, ...@@ -308,20 +307,18 @@ static void cirrus_format_set(struct cirrus_device *cirrus,
wreg_hdr(cirrus, hdr); wreg_hdr(cirrus, hdr);
} }
static void cirrus_pitch_set(struct cirrus_device *cirrus, static void cirrus_pitch_set(struct cirrus_device *cirrus, unsigned int pitch)
struct drm_framebuffer *fb)
{ {
u8 cr13, cr1b; u8 cr13, cr1b;
/* Program the pitch */ /* Program the pitch */
cirrus->pitch = cirrus_pitch(fb); cr13 = pitch / 8;
cr13 = cirrus->pitch / 8;
wreg_crt(cirrus, VGA_CRTC_OFFSET, cr13); wreg_crt(cirrus, VGA_CRTC_OFFSET, cr13);
/* Enable extended blanking and pitch bits, and enable full memory */ /* Enable extended blanking and pitch bits, and enable full memory */
cr1b = 0x22; cr1b = 0x22;
cr1b |= (cirrus->pitch >> 7) & 0x10; cr1b |= (pitch >> 7) & 0x10;
cr1b |= (cirrus->pitch >> 6) & 0x40; cr1b |= (pitch >> 6) & 0x40;
wreg_crt(cirrus, 0x1b, cr1b); wreg_crt(cirrus, 0x1b, cr1b);
cirrus_set_start_address(cirrus, 0); cirrus_set_start_address(cirrus, 0);
...@@ -345,6 +342,8 @@ static int cirrus_primary_plane_helper_atomic_check(struct drm_plane *plane, ...@@ -345,6 +342,8 @@ static int cirrus_primary_plane_helper_atomic_check(struct drm_plane *plane,
struct drm_atomic_state *state) struct drm_atomic_state *state)
{ {
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
struct cirrus_primary_plane_state *new_primary_plane_state =
to_cirrus_primary_plane_state(new_plane_state);
struct drm_framebuffer *fb = new_plane_state->fb; struct drm_framebuffer *fb = new_plane_state->fb;
struct drm_crtc *new_crtc = new_plane_state->crtc; struct drm_crtc *new_crtc = new_plane_state->crtc;
struct drm_crtc_state *new_crtc_state = NULL; struct drm_crtc_state *new_crtc_state = NULL;
...@@ -371,6 +370,9 @@ static int cirrus_primary_plane_helper_atomic_check(struct drm_plane *plane, ...@@ -371,6 +370,9 @@ static int cirrus_primary_plane_helper_atomic_check(struct drm_plane *plane,
else if (pitch * fb->height > CIRRUS_VRAM_SIZE) else if (pitch * fb->height > CIRRUS_VRAM_SIZE)
return -EINVAL; return -EINVAL;
new_primary_plane_state->format = cirrus_format(fb);
new_primary_plane_state->pitch = pitch;
return 0; return 0;
} }
...@@ -379,9 +381,15 @@ static void cirrus_primary_plane_helper_atomic_update(struct drm_plane *plane, ...@@ -379,9 +381,15 @@ static void cirrus_primary_plane_helper_atomic_update(struct drm_plane *plane,
{ {
struct cirrus_device *cirrus = to_cirrus(plane->dev); struct cirrus_device *cirrus = to_cirrus(plane->dev);
struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
struct cirrus_primary_plane_state *primary_plane_state =
to_cirrus_primary_plane_state(plane_state);
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_framebuffer *fb = plane_state->fb; struct drm_framebuffer *fb = plane_state->fb;
const struct drm_format_info *format = primary_plane_state->format;
unsigned int pitch = primary_plane_state->pitch;
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
struct cirrus_primary_plane_state *old_primary_plane_state =
to_cirrus_primary_plane_state(old_plane_state);
struct iosys_map vaddr = IOSYS_MAP_INIT_VADDR_IOMEM(cirrus->vram); struct iosys_map vaddr = IOSYS_MAP_INIT_VADDR_IOMEM(cirrus->vram);
struct drm_atomic_helper_damage_iter iter; struct drm_atomic_helper_damage_iter iter;
struct drm_rect damage; struct drm_rect damage;
...@@ -393,18 +401,17 @@ static void cirrus_primary_plane_helper_atomic_update(struct drm_plane *plane, ...@@ -393,18 +401,17 @@ static void cirrus_primary_plane_helper_atomic_update(struct drm_plane *plane,
if (!drm_dev_enter(&cirrus->dev, &idx)) if (!drm_dev_enter(&cirrus->dev, &idx))
return; return;
if (cirrus->format != cirrus_format(fb)) if (old_primary_plane_state->format != format)
cirrus_format_set(cirrus, fb); cirrus_format_set(cirrus, format);
if (cirrus->pitch != cirrus_pitch(fb)) if (old_primary_plane_state->pitch != pitch)
cirrus_pitch_set(cirrus, fb); cirrus_pitch_set(cirrus, pitch);
drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
drm_atomic_for_each_plane_damage(&iter, &damage) { drm_atomic_for_each_plane_damage(&iter, &damage) {
unsigned int offset = drm_fb_clip_offset(cirrus->pitch, fb->format, &damage); unsigned int offset = drm_fb_clip_offset(pitch, format, &damage);
struct iosys_map dst = IOSYS_MAP_INIT_OFFSET(&vaddr, offset); struct iosys_map dst = IOSYS_MAP_INIT_OFFSET(&vaddr, offset);
drm_fb_blit(&dst, &cirrus->pitch, cirrus->format->format, drm_fb_blit(&dst, &pitch, format->format, shadow_plane_state->data, fb, &damage);
&shadow_plane_state->data[0], fb, &damage);
} }
drm_dev_exit(idx); drm_dev_exit(idx);
...@@ -420,6 +427,8 @@ static struct drm_plane_state * ...@@ -420,6 +427,8 @@ static struct drm_plane_state *
cirrus_primary_plane_atomic_duplicate_state(struct drm_plane *plane) cirrus_primary_plane_atomic_duplicate_state(struct drm_plane *plane)
{ {
struct drm_plane_state *plane_state = plane->state; struct drm_plane_state *plane_state = plane->state;
struct cirrus_primary_plane_state *primary_plane_state =
to_cirrus_primary_plane_state(plane_state);
struct cirrus_primary_plane_state *new_primary_plane_state; struct cirrus_primary_plane_state *new_primary_plane_state;
struct drm_shadow_plane_state *new_shadow_plane_state; struct drm_shadow_plane_state *new_shadow_plane_state;
...@@ -432,6 +441,8 @@ cirrus_primary_plane_atomic_duplicate_state(struct drm_plane *plane) ...@@ -432,6 +441,8 @@ cirrus_primary_plane_atomic_duplicate_state(struct drm_plane *plane)
new_shadow_plane_state = &new_primary_plane_state->base; new_shadow_plane_state = &new_primary_plane_state->base;
__drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state); __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state);
new_primary_plane_state->format = primary_plane_state->format;
new_primary_plane_state->pitch = primary_plane_state->pitch;
return &new_shadow_plane_state->base; return &new_shadow_plane_state->base;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment