Commit 83d642ee authored by Mihail Atanassov's avatar Mihail Atanassov Committed by Liviu Dudau

drm: mali-dp: fix stride setting for multi-plane formats

Hardware has multiple (2 or 3, depending on model) stride
registers per layer; add a function that correctly takes that
into account. On hardware that only has 2 stride registers,
ensure that 3-plane (YUV) content has identical strides
for both chroma planes.
Signed-off-by: default avatarMihail Atanassov <mihail.atanassov@arm.com>
[Removed smart layer stride setup, comment and commit message clarifications]
Signed-off-by: default avatarLiviu Dudau <Liviu.Dudau@arm.com>
parent b70b332f
...@@ -74,16 +74,16 @@ static const struct malidp_format_id malidp550_de_formats[] = { ...@@ -74,16 +74,16 @@ static const struct malidp_format_id malidp550_de_formats[] = {
}; };
static const struct malidp_layer malidp500_layers[] = { static const struct malidp_layer malidp500_layers[] = {
{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE }, { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE }, { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE },
{ DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE }, { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE },
}; };
static const struct malidp_layer malidp550_layers[] = { static const struct malidp_layer malidp550_layers[] = {
{ DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE }, { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
{ DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE }, { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE },
{ DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE }, { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
{ DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE }, { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 0 },
}; };
#define MALIDP_DE_DEFAULT_PREFETCH_START 5 #define MALIDP_DE_DEFAULT_PREFETCH_START 5
...@@ -447,6 +447,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { ...@@ -447,6 +447,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
.set_config_valid = malidp500_set_config_valid, .set_config_valid = malidp500_set_config_valid,
.modeset = malidp500_modeset, .modeset = malidp500_modeset,
.rotmem_required = malidp500_rotmem_required, .rotmem_required = malidp500_rotmem_required,
.features = MALIDP_DEVICE_LV_HAS_3_STRIDES,
}, },
[MALIDP_550] = { [MALIDP_550] = {
.map = { .map = {
...@@ -480,6 +481,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { ...@@ -480,6 +481,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
.set_config_valid = malidp550_set_config_valid, .set_config_valid = malidp550_set_config_valid,
.modeset = malidp550_modeset, .modeset = malidp550_modeset,
.rotmem_required = malidp550_rotmem_required, .rotmem_required = malidp550_rotmem_required,
.features = 0,
}, },
[MALIDP_650] = { [MALIDP_650] = {
.map = { .map = {
...@@ -514,6 +516,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { ...@@ -514,6 +516,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
.set_config_valid = malidp550_set_config_valid, .set_config_valid = malidp550_set_config_valid,
.modeset = malidp550_modeset, .modeset = malidp550_modeset,
.rotmem_required = malidp550_rotmem_required, .rotmem_required = malidp550_rotmem_required,
.features = 0,
}, },
}; };
......
...@@ -58,6 +58,7 @@ struct malidp_layer { ...@@ -58,6 +58,7 @@ struct malidp_layer {
u16 id; /* layer ID */ u16 id; /* layer ID */
u16 base; /* address offset for the register bank */ u16 base; /* address offset for the register bank */
u16 ptr; /* address offset for the pointer register */ u16 ptr; /* address offset for the pointer register */
u16 stride_offset; /* Offset to the first stride register. */
}; };
/* regmap features */ /* regmap features */
...@@ -93,6 +94,10 @@ struct malidp_hw_regmap { ...@@ -93,6 +94,10 @@ struct malidp_hw_regmap {
const u8 bus_align_bytes; const u8 bus_align_bytes;
}; };
/* device features */
/* Unlike DP550/650, DP500 has 3 stride registers in its video layer. */
#define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0)
struct malidp_hw_device { struct malidp_hw_device {
const struct malidp_hw_regmap map; const struct malidp_hw_regmap map;
void __iomem *regs; void __iomem *regs;
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#define LAYER_V_VAL(x) (((x) & 0x1fff) << 16) #define LAYER_V_VAL(x) (((x) & 0x1fff) << 16)
#define MALIDP_LAYER_COMP_SIZE 0x010 #define MALIDP_LAYER_COMP_SIZE 0x010
#define MALIDP_LAYER_OFFSET 0x014 #define MALIDP_LAYER_OFFSET 0x014
#define MALIDP_LAYER_STRIDE 0x018
/* /*
* This 4-entry look-up-table is used to determine the full 8-bit alpha value * This 4-entry look-up-table is used to determine the full 8-bit alpha value
...@@ -138,6 +137,16 @@ static int malidp_de_plane_check(struct drm_plane *plane, ...@@ -138,6 +137,16 @@ static int malidp_de_plane_check(struct drm_plane *plane,
(state->crtc_h < mp->hwdev->min_line_size)) (state->crtc_h < mp->hwdev->min_line_size))
return -EINVAL; return -EINVAL;
/*
* DP550/650 video layers can accept 3 plane formats only if
* fb->pitches[1] == fb->pitches[2] since they don't have a
* third plane stride register.
*/
if (ms->n_planes == 3 &&
!(mp->hwdev->features & MALIDP_DEVICE_LV_HAS_3_STRIDES) &&
(state->fb->pitches[1] != state->fb->pitches[2]))
return -EINVAL;
/* packed RGB888 / BGR888 can't be rotated or flipped */ /* packed RGB888 / BGR888 can't be rotated or flipped */
if (state->rotation != DRM_ROTATE_0 && if (state->rotation != DRM_ROTATE_0 &&
(fb->format->format == DRM_FORMAT_RGB888 || (fb->format->format == DRM_FORMAT_RGB888 ||
...@@ -170,6 +179,25 @@ static int malidp_de_plane_check(struct drm_plane *plane, ...@@ -170,6 +179,25 @@ static int malidp_de_plane_check(struct drm_plane *plane,
return 0; return 0;
} }
static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
int num_planes, unsigned int pitches[3])
{
int i;
int num_strides = num_planes;
if (!mp->layer->stride_offset)
return;
if (num_planes == 3)
num_strides = (mp->hwdev->features &
MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
for (i = 0; i < num_strides; ++i)
malidp_hw_write(mp->hwdev, pitches[i],
mp->layer->base +
mp->layer->stride_offset + i * 4);
}
static void malidp_de_plane_update(struct drm_plane *plane, static void malidp_de_plane_update(struct drm_plane *plane,
struct drm_plane_state *old_state) struct drm_plane_state *old_state)
{ {
...@@ -200,9 +228,9 @@ static void malidp_de_plane_update(struct drm_plane *plane, ...@@ -200,9 +228,9 @@ static void malidp_de_plane_update(struct drm_plane *plane,
obj->paddr += plane->state->fb->offsets[i]; obj->paddr += plane->state->fb->offsets[i];
malidp_hw_write(mp->hwdev, lower_32_bits(obj->paddr), ptr); malidp_hw_write(mp->hwdev, lower_32_bits(obj->paddr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(obj->paddr), ptr + 4); malidp_hw_write(mp->hwdev, upper_32_bits(obj->paddr), ptr + 4);
malidp_hw_write(mp->hwdev, plane->state->fb->pitches[i],
mp->layer->base + MALIDP_LAYER_STRIDE);
} }
malidp_de_set_plane_pitches(mp, ms->n_planes,
plane->state->fb->pitches);
malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h), malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h),
mp->layer->base + MALIDP_LAYER_SIZE); mp->layer->base + MALIDP_LAYER_SIZE);
......
...@@ -81,6 +81,10 @@ ...@@ -81,6 +81,10 @@
#define MALIDP_DE_SYNC_WIDTH 0x8 #define MALIDP_DE_SYNC_WIDTH 0x8
#define MALIDP_DE_HV_ACTIVE 0xc #define MALIDP_DE_HV_ACTIVE 0xc
/* Stride register offsets relative to Lx_BASE */
#define MALIDP_DE_LG_STRIDE 0x18
#define MALIDP_DE_LV_STRIDE0 0x18
/* macros to set values into registers */ /* macros to set values into registers */
#define MALIDP_DE_H_FRONTPORCH(x) (((x) & 0xfff) << 0) #define MALIDP_DE_H_FRONTPORCH(x) (((x) & 0xfff) << 0)
#define MALIDP_DE_H_BACKPORCH(x) (((x) & 0x3ff) << 16) #define MALIDP_DE_H_BACKPORCH(x) (((x) & 0x3ff) << 16)
......
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