imx-drm: lock scanout transfers for consecutive bursts

- Lock the IDMAC scanout channel for multiple back-to-back bursts if possible,
   to improve memory bandwidth utilisation.
 - Replace a few occurences of state->fb with the already existing local fb
   variable in ipu_plane_atomic_update
 -----BEGIN PGP SIGNATURE-----
 
 iQJMBAABCAA2FiEEBsBxhV1FaKwXuCOBUMKIHHCeYOsFAlltvQYYHHBoaWxpcHAu
 emFiZWxAZ21haWwuY29tAAoJEFDCiBxwnmDr8HMQAIFY9yGeyhSpLlI2FM32UKvW
 Si5KYZ74DNGEMt1/zy8/ruGe20nYIgMUbSkaIlX2Brpkoo2gUcV21wxTYHpomjz+
 y9wVYosBC4OY2crd8mFbWRYLKA4UmOvN9iAs9oeZ7Yw58NKyfV2x36nHvLgPULri
 wFcDj32V9260f6DqMSNLtQDJULwbDR6tclYcmodX5zp3J2jYTS8I5o2nKtXPgeKa
 yeRwlDq0NKqq6n3tuzTrmR2qBC41ebuF7FQftEHykPyFAuV/XtKT82T2ZYJHbqPc
 NG3E3ShnbFP0wIJOTF3V4GO8lg4jBaBVrw1c5DzYtYpsalthXOZVUCTShpcRxHkk
 hZVO9nq4ooo/q7xIgmq1C/BSR5FXloDqLTZgwlv9sjHkkCeeeIIbqjN7a1ukjzJA
 zxlrlbuiNSyQMMutYcQIT60Zva0hXlS1YJ6fBH894TqT7uw0QDVaE+AbSdVfw6Mq
 OqNEktWXgMuREwSbuXtKE4d3IXhWx6PsGyxcq77jLaRe+Uk3fornjQ3IS7F2li45
 MyEQo4LJhzyy5gwVe3NUUh/BN8lfuP3iO6ukOgEP37cAS6KA37Jy02BCSNZw4NMj
 Z30Kw7r+HvwQCrVZPSXuM+qiO6U8Pp/biAPv09CleHtoyZiZmkt/xXVM6J8XPMdw
 lHjZiEGDnFGwIER1FHKw
 =nXzK
 -----END PGP SIGNATURE-----

Merge tag 'imx-drm-next-2017-07-18' of git://git.pengutronix.de/git/pza/linux into drm-next

imx-drm: lock scanout transfers for consecutive bursts

- Lock the IDMAC scanout channel for multiple back-to-back bursts if possible,
  to improve memory bandwidth utilisation.
- Replace a few occurences of state->fb with the already existing local fb
  variable in ipu_plane_atomic_update

* tag 'imx-drm-next-2017-07-18' of git://git.pengutronix.de/git/pza/linux:
  drm/imx: lock scanout transfers for consecutive bursts
  drm/imx: ipuv3-plane: use fb local variable instead of state->fb
This commit is contained in:
Dave Airlie 2017-08-22 16:51:11 +10:00
commit 6b9dfb5991

View File

@ -496,6 +496,27 @@ static int ipu_chan_assign_axi_id(int ipu_chan)
}
}
static void ipu_calculate_bursts(u32 width, u32 cpp, u32 stride,
u8 *burstsize, u8 *num_bursts)
{
const unsigned int width_bytes = width * cpp;
unsigned int npb, bursts;
/* Maximum number of pixels per burst without overshooting stride */
for (npb = 64 / cpp; npb > 0; --npb) {
if (round_up(width_bytes, npb * cpp) <= stride)
break;
}
*burstsize = npb;
/* Maximum number of consecutive bursts without overshooting stride */
for (bursts = 8; bursts > 1; bursts /= 2) {
if (round_up(width_bytes, npb * cpp * bursts) <= stride)
break;
}
*num_bursts = bursts;
}
static void ipu_plane_atomic_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
@ -509,6 +530,9 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
unsigned long alpha_eba = 0;
enum ipu_color_space ics;
unsigned int axi_id = 0;
const struct drm_format_info *info;
u8 burstsize, num_bursts;
u32 width, height;
int active;
if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_FG)
@ -525,8 +549,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
drm_rect_width(&state->src) >> 16,
drm_rect_height(&state->src) >> 16,
state->fb->pitches[0],
state->fb->format->format, &eba);
fb->pitches[0],
fb->format->format, &eba);
}
if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) {
@ -553,11 +577,11 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
break;
case IPU_DP_FLOW_SYNC_FG:
ics = ipu_drm_fourcc_to_colorspace(state->fb->format->format);
ics = ipu_drm_fourcc_to_colorspace(fb->format->format);
ipu_dp_setup_channel(ipu_plane->dp, ics,
IPUV3_COLORSPACE_UNKNOWN);
/* Enable local alpha on partial plane */
switch (state->fb->format->format) {
switch (fb->format->format) {
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_RGBA5551:
@ -583,15 +607,21 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_dmfc_config_wait4eot(ipu_plane->dmfc, drm_rect_width(dst));
width = drm_rect_width(&state->src) >> 16;
height = drm_rect_height(&state->src) >> 16;
info = drm_format_info(fb->format->format);
ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
&burstsize, &num_bursts);
ipu_cpmem_zero(ipu_plane->ipu_ch);
ipu_cpmem_set_resolution(ipu_plane->ipu_ch,
drm_rect_width(&state->src) >> 16,
drm_rect_height(&state->src) >> 16);
ipu_cpmem_set_fmt(ipu_plane->ipu_ch, state->fb->format->format);
ipu_cpmem_set_resolution(ipu_plane->ipu_ch, width, height);
ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->format->format);
ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, burstsize);
ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1);
ipu_cpmem_set_stride(ipu_plane->ipu_ch, state->fb->pitches[0]);
ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]);
ipu_cpmem_set_axi_id(ipu_plane->ipu_ch, axi_id);
switch (fb->format->format) {
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
@ -631,6 +661,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
case DRM_FORMAT_RGBX8888_A8:
case DRM_FORMAT_BGRX8888_A8:
alpha_eba = drm_plane_state_to_eba(state, 1);
num_bursts = 0;
dev_dbg(ipu_plane->base.dev->dev, "phys = %lu %lu, x = %d, y = %d",
eba, alpha_eba, state->src.x1 >> 16, state->src.y1 >> 16);
@ -644,8 +675,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
ipu_idmac_set_double_buffer(ipu_plane->alpha_ch, 1);
ipu_cpmem_set_stride(ipu_plane->alpha_ch,
state->fb->pitches[1]);
ipu_cpmem_set_stride(ipu_plane->alpha_ch, fb->pitches[1]);
ipu_cpmem_set_burstsize(ipu_plane->alpha_ch, 16);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 0, alpha_eba);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 1, alpha_eba);
@ -657,6 +687,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
}
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba);
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts);
ipu_plane_enable(ipu_plane);
}