|
@@ -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,
|
|
static void ipu_plane_atomic_update(struct drm_plane *plane,
|
|
struct drm_plane_state *old_state)
|
|
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;
|
|
unsigned long alpha_eba = 0;
|
|
enum ipu_color_space ics;
|
|
enum ipu_color_space ics;
|
|
unsigned int axi_id = 0;
|
|
unsigned int axi_id = 0;
|
|
|
|
+ const struct drm_format_info *info;
|
|
|
|
+ u8 burstsize, num_bursts;
|
|
|
|
+ u32 width, height;
|
|
int active;
|
|
int active;
|
|
|
|
|
|
if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_FG)
|
|
if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_FG)
|
|
@@ -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));
|
|
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_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_resolution(ipu_plane->ipu_ch, width, height);
|
|
ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->format->format);
|
|
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_cpmem_set_high_priority(ipu_plane->ipu_ch);
|
|
ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1);
|
|
ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1);
|
|
ipu_cpmem_set_stride(ipu_plane->ipu_ch, 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);
|
|
ipu_cpmem_set_axi_id(ipu_plane->ipu_ch, axi_id);
|
|
|
|
+
|
|
switch (fb->format->format) {
|
|
switch (fb->format->format) {
|
|
case DRM_FORMAT_YUV420:
|
|
case DRM_FORMAT_YUV420:
|
|
case DRM_FORMAT_YVU420:
|
|
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_RGBX8888_A8:
|
|
case DRM_FORMAT_BGRX8888_A8:
|
|
case DRM_FORMAT_BGRX8888_A8:
|
|
alpha_eba = drm_plane_state_to_eba(state, 1);
|
|
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",
|
|
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);
|
|
eba, alpha_eba, state->src.x1 >> 16, state->src.y1 >> 16);
|
|
@@ -656,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, 0, eba);
|
|
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, 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);
|
|
ipu_plane_enable(ipu_plane);
|
|
}
|
|
}
|
|
|
|
|