Skip to content

Commit 41ab70e

Browse files
committed
Merge tag 'imx-drm-next-2021-05-12' of git://git.pengutronix.de/git/pza/linux into drm-next
drm/imx: fixes, dma-fence annotation, and color encoding/range plane properties - Annotate dma-fence critical section in atomic_commit_tail - Fix PRG modifiers after drmm resource conversion to regain tiled scanout capability - Add 8 pixel alignment fix to support 1366x768 resolution - Stop advertising YUV formats on planes that don't support them - Add COLOR_ENCODING and COLOR_RANGE plane properties on planes that support them - Remove unnecessarily exported symbols Signed-off-by: Dave Airlie <[email protected]> From: Philipp Zabel <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 3a3ca72 + fc1e985 commit 41ab70e

File tree

8 files changed

+167
-24
lines changed

8 files changed

+167
-24
lines changed

drivers/gpu/drm/imx/imx-drm-core.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
8181
struct drm_plane_state *old_plane_state, *new_plane_state;
8282
bool plane_disabling = false;
8383
int i;
84+
bool fence_cookie = dma_fence_begin_signalling();
8485

8586
drm_atomic_helper_commit_modeset_disables(dev, state);
8687

@@ -111,6 +112,7 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
111112
}
112113

113114
drm_atomic_helper_commit_hw_done(state);
115+
dma_fence_end_signalling(fence_cookie);
114116
}
115117

116118
static const struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = {
@@ -145,9 +147,26 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
145147
/* none so far */
146148
};
147149

150+
static int imx_drm_dumb_create(struct drm_file *file_priv,
151+
struct drm_device *drm,
152+
struct drm_mode_create_dumb *args)
153+
{
154+
u32 width = args->width;
155+
int ret;
156+
157+
args->width = ALIGN(width, 8);
158+
159+
ret = drm_gem_cma_dumb_create(file_priv, drm, args);
160+
if (ret)
161+
return ret;
162+
163+
args->width = width;
164+
return ret;
165+
}
166+
148167
static const struct drm_driver imx_drm_driver = {
149168
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
150-
DRM_GEM_CMA_DRIVER_OPS,
169+
DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(imx_drm_dumb_create),
151170
.ioctls = imx_drm_ioctls,
152171
.num_ioctls = ARRAY_SIZE(imx_drm_ioctls),
153172
.fops = &imx_drm_driver_fops,

drivers/gpu/drm/imx/imx-ldb.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder,
274274
"%s: mode exceeds 85 MHz pixel clock\n", __func__);
275275
}
276276

277+
if (!IS_ALIGNED(mode->hdisplay, 8)) {
278+
dev_warn(ldb->dev,
279+
"%s: hdisplay does not align to 8 byte\n", __func__);
280+
}
281+
277282
if (dual) {
278283
serial_clk = 3500UL * mode->clock;
279284
imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);

drivers/gpu/drm/imx/ipuv3-crtc.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,19 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
305305
sig_cfg.vsync_pin = imx_crtc_state->di_vsync_pin;
306306

307307
drm_display_mode_to_videomode(mode, &sig_cfg.mode);
308+
if (!IS_ALIGNED(sig_cfg.mode.hactive, 8)) {
309+
unsigned int new_hactive = ALIGN(sig_cfg.mode.hactive, 8);
310+
311+
dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n",
312+
sig_cfg.mode.hactive, new_hactive);
313+
314+
sig_cfg.mode.hfront_porch = new_hactive - sig_cfg.mode.hactive;
315+
sig_cfg.mode.hactive = new_hactive;
316+
}
308317

309318
ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
310319
mode->flags & DRM_MODE_FLAG_INTERLACE,
311-
imx_crtc_state->bus_format, mode->hdisplay);
320+
imx_crtc_state->bus_format, sig_cfg.mode.hactive);
312321
ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
313322
}
314323

drivers/gpu/drm/imx/ipuv3-plane.c

Lines changed: 96 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,17 @@ to_ipu_plane_state(struct drm_plane_state *p)
3030
return container_of(p, struct ipu_plane_state, base);
3131
}
3232

33+
static unsigned int ipu_src_rect_width(const struct drm_plane_state *state)
34+
{
35+
return ALIGN(drm_rect_width(&state->src) >> 16, 8);
36+
}
37+
3338
static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p)
3439
{
3540
return container_of(p, struct ipu_plane, base);
3641
}
3742

38-
static const uint32_t ipu_plane_formats[] = {
43+
static const uint32_t ipu_plane_all_formats[] = {
3944
DRM_FORMAT_ARGB1555,
4045
DRM_FORMAT_XRGB1555,
4146
DRM_FORMAT_ABGR1555,
@@ -72,6 +77,31 @@ static const uint32_t ipu_plane_formats[] = {
7277
DRM_FORMAT_BGRX8888_A8,
7378
};
7479

80+
static const uint32_t ipu_plane_rgb_formats[] = {
81+
DRM_FORMAT_ARGB1555,
82+
DRM_FORMAT_XRGB1555,
83+
DRM_FORMAT_ABGR1555,
84+
DRM_FORMAT_XBGR1555,
85+
DRM_FORMAT_RGBA5551,
86+
DRM_FORMAT_BGRA5551,
87+
DRM_FORMAT_ARGB4444,
88+
DRM_FORMAT_ARGB8888,
89+
DRM_FORMAT_XRGB8888,
90+
DRM_FORMAT_ABGR8888,
91+
DRM_FORMAT_XBGR8888,
92+
DRM_FORMAT_RGBA8888,
93+
DRM_FORMAT_RGBX8888,
94+
DRM_FORMAT_BGRA8888,
95+
DRM_FORMAT_BGRX8888,
96+
DRM_FORMAT_RGB565,
97+
DRM_FORMAT_RGB565_A8,
98+
DRM_FORMAT_BGR565_A8,
99+
DRM_FORMAT_RGB888_A8,
100+
DRM_FORMAT_BGR888_A8,
101+
DRM_FORMAT_RGBX8888_A8,
102+
DRM_FORMAT_BGRX8888_A8,
103+
};
104+
75105
static const uint64_t ipu_format_modifiers[] = {
76106
DRM_FORMAT_MOD_LINEAR,
77107
DRM_FORMAT_MOD_INVALID
@@ -264,7 +294,6 @@ void ipu_plane_disable_deferred(struct drm_plane *plane)
264294
ipu_plane_disable(ipu_plane, false);
265295
}
266296
}
267-
EXPORT_SYMBOL_GPL(ipu_plane_disable_deferred);
268297

269298
static void ipu_plane_state_reset(struct drm_plane *plane)
270299
{
@@ -284,6 +313,8 @@ static void ipu_plane_state_reset(struct drm_plane *plane)
284313
__drm_atomic_helper_plane_reset(plane, &ipu_state->base);
285314
ipu_state->base.zpos = zpos;
286315
ipu_state->base.normalized_zpos = zpos;
316+
ipu_state->base.color_encoding = DRM_COLOR_YCBCR_BT601;
317+
ipu_state->base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
287318
}
288319
}
289320

@@ -320,10 +351,11 @@ static bool ipu_plane_format_mod_supported(struct drm_plane *plane,
320351
if (modifier == DRM_FORMAT_MOD_LINEAR)
321352
return true;
322353

323-
/* without a PRG there are no supported modifiers */
324-
if (!ipu_prg_present(ipu))
325-
return false;
326-
354+
/*
355+
* Without a PRG the possible modifiers list only includes the linear
356+
* modifier, so we always take the early return from this function and
357+
* only end up here if the PRG is present.
358+
*/
327359
return ipu_prg_format_supported(ipu, format, modifier);
328360
}
329361

@@ -415,6 +447,12 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
415447
if (old_fb && fb->pitches[0] != old_fb->pitches[0])
416448
crtc_state->mode_changed = true;
417449

450+
if (ALIGN(fb->width, 8) * fb->format->cpp[0] >
451+
fb->pitches[0] + fb->offsets[0]) {
452+
dev_warn(dev, "pitch is not big enough for 8 pixels alignment");
453+
return -EINVAL;
454+
}
455+
418456
switch (fb->format->format) {
419457
case DRM_FORMAT_YUV420:
420458
case DRM_FORMAT_YVU420:
@@ -590,12 +628,31 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
590628
if (ipu_state->use_pre) {
591629
axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
592630
ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
593-
drm_rect_width(&new_state->src) >> 16,
631+
ipu_src_rect_width(new_state),
594632
drm_rect_height(&new_state->src) >> 16,
595633
fb->pitches[0], fb->format->format,
596634
fb->modifier, &eba);
597635
}
598636

637+
if (!old_state->fb ||
638+
old_state->fb->format->format != fb->format->format ||
639+
old_state->color_encoding != new_state->color_encoding ||
640+
old_state->color_range != new_state->color_range) {
641+
ics = ipu_drm_fourcc_to_colorspace(fb->format->format);
642+
switch (ipu_plane->dp_flow) {
643+
case IPU_DP_FLOW_SYNC_BG:
644+
ipu_dp_setup_channel(ipu_plane->dp, new_state->color_encoding,
645+
new_state->color_range, ics,
646+
IPUV3_COLORSPACE_RGB);
647+
break;
648+
case IPU_DP_FLOW_SYNC_FG:
649+
ipu_dp_setup_channel(ipu_plane->dp, new_state->color_encoding,
650+
new_state->color_range, ics,
651+
IPUV3_COLORSPACE_UNKNOWN);
652+
break;
653+
}
654+
}
655+
599656
if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) {
600657
/* nothing to do if PRE is used */
601658
if (ipu_state->use_pre)
@@ -615,17 +672,20 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
615672
ics = ipu_drm_fourcc_to_colorspace(fb->format->format);
616673
switch (ipu_plane->dp_flow) {
617674
case IPU_DP_FLOW_SYNC_BG:
618-
ipu_dp_setup_channel(ipu_plane->dp, ics, IPUV3_COLORSPACE_RGB);
675+
ipu_dp_setup_channel(ipu_plane->dp, DRM_COLOR_YCBCR_BT601,
676+
DRM_COLOR_YCBCR_LIMITED_RANGE, ics,
677+
IPUV3_COLORSPACE_RGB);
619678
break;
620679
case IPU_DP_FLOW_SYNC_FG:
621-
ipu_dp_setup_channel(ipu_plane->dp, ics,
622-
IPUV3_COLORSPACE_UNKNOWN);
680+
ipu_dp_setup_channel(ipu_plane->dp, DRM_COLOR_YCBCR_BT601,
681+
DRM_COLOR_YCBCR_LIMITED_RANGE, ics,
682+
IPUV3_COLORSPACE_UNKNOWN);
623683
break;
624684
}
625685

626686
ipu_dmfc_config_wait4eot(ipu_plane->dmfc, drm_rect_width(dst));
627687

628-
width = drm_rect_width(&new_state->src) >> 16;
688+
width = ipu_src_rect_width(new_state);
629689
height = drm_rect_height(&new_state->src) >> 16;
630690
info = drm_format_info(fb->format->format);
631691
ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
@@ -690,7 +750,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
690750

691751
ipu_cpmem_zero(ipu_plane->alpha_ch);
692752
ipu_cpmem_set_resolution(ipu_plane->alpha_ch,
693-
drm_rect_width(&new_state->src) >> 16,
753+
ipu_src_rect_width(new_state),
694754
drm_rect_height(&new_state->src) >> 16);
695755
ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
696756
ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
@@ -821,7 +881,6 @@ int ipu_planes_assign_pre(struct drm_device *dev,
821881

822882
return 0;
823883
}
824-
EXPORT_SYMBOL_GPL(ipu_planes_assign_pre);
825884

826885
struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
827886
int dma, int dp, unsigned int possible_crtcs,
@@ -830,16 +889,28 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
830889
struct ipu_plane *ipu_plane;
831890
const uint64_t *modifiers = ipu_format_modifiers;
832891
unsigned int zpos = (type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1;
892+
unsigned int format_count;
893+
const uint32_t *formats;
833894
int ret;
834895

835896
DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
836897
dma, dp, possible_crtcs);
837898

899+
if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG) {
900+
formats = ipu_plane_all_formats;
901+
format_count = ARRAY_SIZE(ipu_plane_all_formats);
902+
} else {
903+
formats = ipu_plane_rgb_formats;
904+
format_count = ARRAY_SIZE(ipu_plane_rgb_formats);
905+
}
906+
907+
if (ipu_prg_present(ipu))
908+
modifiers = pre_format_modifiers;
909+
838910
ipu_plane = drmm_universal_plane_alloc(dev, struct ipu_plane, base,
839911
possible_crtcs, &ipu_plane_funcs,
840-
ipu_plane_formats,
841-
ARRAY_SIZE(ipu_plane_formats),
842-
modifiers, type, NULL);
912+
formats, format_count, modifiers,
913+
type, NULL);
843914
if (IS_ERR(ipu_plane)) {
844915
DRM_ERROR("failed to allocate and initialize %s plane\n",
845916
zpos ? "overlay" : "primary");
@@ -850,9 +921,6 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
850921
ipu_plane->dma = dma;
851922
ipu_plane->dp_flow = dp;
852923

853-
if (ipu_prg_present(ipu))
854-
modifiers = pre_format_modifiers;
855-
856924
drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs);
857925

858926
if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG)
@@ -864,6 +932,15 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
864932
if (ret)
865933
return ERR_PTR(ret);
866934

935+
ret = drm_plane_create_color_properties(&ipu_plane->base,
936+
BIT(DRM_COLOR_YCBCR_BT601) |
937+
BIT(DRM_COLOR_YCBCR_BT709),
938+
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
939+
DRM_COLOR_YCBCR_BT601,
940+
DRM_COLOR_YCBCR_LIMITED_RANGE);
941+
if (ret)
942+
return ERR_PTR(ret);
943+
867944
ret = ipu_plane_get_resources(dev, ipu_plane);
868945
if (ret) {
869946
DRM_ERROR("failed to get %s plane resources: %pe\n",

drivers/gpu/ipu-v3/ipu-dc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
167167

168168
dc->di = ipu_di_get_num(di);
169169

170+
if (!IS_ALIGNED(width, 8)) {
171+
dev_warn(priv->dev,
172+
"%s: hactive does not align to 8 byte\n", __func__);
173+
}
174+
170175
map = ipu_bus_format_to_map(bus_format);
171176

172177
/*

drivers/gpu/ipu-v3/ipu-di.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,13 @@ int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode)
506506
{
507507
u32 diff;
508508

509+
if (!IS_ALIGNED(mode->hactive, 8) &&
510+
mode->hfront_porch < ALIGN(mode->hactive, 8) - mode->hactive) {
511+
dev_err(di->ipu->dev, "hactive %d is not aligned to 8 and front porch is too small to compensate\n",
512+
mode->hactive);
513+
return -EINVAL;
514+
}
515+
509516
if (mode->vfront_porch >= 2)
510517
return 0;
511518

0 commit comments

Comments
 (0)