Skip to content

Commit 42d64e3

Browse files
jannaumarcan
authored andcommitted
drm/apple: Update swap handling
- opaque -> is_premultiplied - swap_enabled BIT(31) seems to be update background with dcp_swap.bg_color - add unused fields is_tearing_allowed, ycbcr_matrix, protection_opts, unk_num, unk_denom Changes: use is_premultiplied only for XRGB8/XBGR8, Update background only when necessary. Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 34dcf1e commit 42d64e3

2 files changed

Lines changed: 32 additions & 28 deletions

File tree

drivers/gpu/drm/apple/iomfb.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,9 +1062,9 @@ void dcp_poweroff(struct platform_device *pdev)
10621062
// clear surfaces
10631063
memset(&dcp->swap, 0, sizeof(dcp->swap));
10641064

1065-
dcp->swap.swap.swap_enabled = DCP_REMOVE_LAYERS | 0x7;
1066-
dcp->swap.swap.swap_completed = DCP_REMOVE_LAYERS | 0x7;
1067-
dcp->swap.swap.unk_10c = 0xFF000000;
1065+
dcp->swap.swap.swap_enabled =
1066+
dcp->swap.swap.swap_completed = IOMFB_SET_BACKGROUND | 0xF;
1067+
dcp->swap.swap.bg_color = 0xFF000000;
10681068

10691069
/*
10701070
* Turn off the backlight. This matters because the DCP's idea of
@@ -1618,7 +1618,8 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
16181618
* sticks around.
16191619
*/
16201620
if (!dcp->surfaces_cleared) {
1621-
req->swap.swap_enabled = DCP_REMOVE_LAYERS | 0xF;
1621+
req->swap.swap_enabled = IOMFB_SET_BACKGROUND | 0xF;
1622+
req->swap.bg_color = 0xFF000000;
16221623
dcp->surfaces_cleared = true;
16231624
}
16241625

@@ -1628,7 +1629,7 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
16281629
struct drm_framebuffer *fb = new_state->fb;
16291630
struct drm_gem_dma_object *obj;
16301631
struct drm_rect src_rect;
1631-
bool opaque = false;
1632+
bool is_premultiplied = false;
16321633

16331634
/* skip planes not for this crtc */
16341635
if (old_state->crtc != crtc && new_state->crtc != crtc)
@@ -1659,18 +1660,21 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
16591660
}
16601661

16611662
if (!new_state->fb) {
1662-
if (old_state->fb)
1663-
req->swap.swap_enabled |= DCP_REMOVE_LAYERS;
1664-
16651663
l += 1;
16661664
continue;
16671665
}
16681666
req->surf_null[l] = false;
16691667
has_surface = 1;
16701668

1671-
if (!fb->format->has_alpha ||
1672-
new_state->plane->type == DRM_PLANE_TYPE_PRIMARY)
1673-
opaque = true;
1669+
/*
1670+
* DCP doesn't support XBGR8 / XRGB8 natively. Blending as
1671+
* pre-multiplied alpha with a black background can be used as
1672+
* workaround for the bottommost plane.
1673+
*/
1674+
if (fb->format->format == DRM_FORMAT_XRGB8888 ||
1675+
fb->format->format == DRM_FORMAT_XBGR8888)
1676+
is_premultiplied = true;
1677+
16741678
drm_rect_fp_to_int(&src_rect, &new_state->src);
16751679

16761680
req->swap.src_rect[l] = drm_to_dcp_rect(&src_rect);
@@ -1688,7 +1692,7 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
16881692
req->surf_iova[l] = obj->dma_addr + fb->offsets[0];
16891693

16901694
req->surf[l] = (struct dcp_surface){
1691-
.opaque = opaque,
1695+
.is_premultiplied = is_premultiplied,
16921696
.format = drm_format_to_dcp(fb->format->format),
16931697
.xfer_func = DCP_XFER_FUNC_SDR,
16941698
.colorspace = DCP_COLORSPACE_NATIVE,
@@ -1709,9 +1713,6 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
17091713
l += 1;
17101714
}
17111715

1712-
/* These fields should be set together */
1713-
req->swap.swap_completed = req->swap.swap_enabled;
1714-
17151716
if (modeset) {
17161717
struct dcp_display_mode *mode;
17171718
struct dcp_wait_cookie *cookie;
@@ -1772,9 +1773,15 @@ void dcp_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
17721773
return;
17731774
}
17741775

1776+
/* Set black background */
1777+
req->swap.swap_enabled |= IOMFB_SET_BACKGROUND;
1778+
req->swap.bg_color = 0xFF000000;
17751779
req->clear = 1;
17761780
}
17771781

1782+
/* These fields should be set together */
1783+
req->swap.swap_completed = req->swap.swap_enabled;
1784+
17781785
/* update brightness if changed */
17791786
if (dcp->brightness.update) {
17801787
req->swap.bl_unk = 1;

drivers/gpu/drm/apple/iomfb.h

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,9 @@ struct dcp_rect {
102102
} __packed;
103103

104104
/*
105-
* Set in the swap_{enabled,completed} field to remove missing
106-
* layers. Without this flag, the DCP will assume missing layers have
107-
* not changed since the previous frame and will preserve their
108-
* content.
109-
*/
110-
#define DCP_REMOVE_LAYERS BIT(31)
105+
* Update background color to struct dcp_swap.bg_color
106+
*/
107+
#define IOMFB_SET_BACKGROUND BIT(31)
111108

112109
struct dcp_swap {
113110
u64 ts1;
@@ -126,7 +123,7 @@ struct dcp_swap {
126123
u32 swap_enabled;
127124
u32 swap_completed;
128125

129-
u32 unk_10c;
126+
u32 bg_color;
130127
u8 unk_110[0x1b8];
131128
u32 unk_2c8;
132129
u8 unk_2cc[0x14];
@@ -160,12 +157,12 @@ struct dcp_component_types {
160157
/* Information describing a surface */
161158
struct dcp_surface {
162159
u8 is_tiled;
163-
u8 unk_1;
164-
u8 opaque; /** ignore alpha, also required YUV overlays */
160+
u8 is_tearing_allowed;
161+
u8 is_premultiplied;
165162
u32 plane_cnt;
166163
u32 plane_cnt2;
167164
u32 format; /* DCP fourcc */
168-
u32 unk_f;
165+
u32 ycbcr_matrix;
169166
u8 xfer_func;
170167
u8 colorspace;
171168
u32 stride;
@@ -176,16 +173,16 @@ struct dcp_surface {
176173
u32 width;
177174
u32 height;
178175
u32 buf_size;
179-
u32 unk_2d;
180-
u32 unk_31;
176+
u64 protection_opts;
181177
u32 surface_id;
182178
struct dcp_component_types comp_types[MAX_PLANES];
183179
u64 has_comp;
184180
struct dcp_plane_info planes[MAX_PLANES];
185181
u64 has_planes;
186182
u32 compression_info[MAX_PLANES][13];
187183
u64 has_compr_info;
188-
u64 unk_1f5;
184+
u32 unk_num;
185+
u32 unk_denom;
189186
u8 padding[7];
190187
} __packed;
191188

0 commit comments

Comments
 (0)