aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMihail Atanassov <mihail.atanassov@arm.com>2017-01-23 10:24:35 -0500
committerLiviu Dudau <Liviu.Dudau@arm.com>2017-01-26 10:46:19 -0500
commit83d642ee6dbec57ef1639a3de1e383fbfc5c44ec (patch)
treec0bdb4752227b0aab0d124f1d4b17130dd7a0229
parentb70b332f14b704b22894571bc422812f539aea4f (diff)
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: Mihail Atanassov <mihail.atanassov@arm.com> [Removed smart layer stride setup, comment and commit message clarifications] Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c17
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.h5
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c34
-rw-r--r--drivers/gpu/drm/arm/malidp_regs.h4
4 files changed, 50 insertions, 10 deletions
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 9ec6d6904f5e..488aedf5b58d 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -74,16 +74,16 @@ static const struct malidp_format_id malidp550_de_formats[] = {
74}; 74};
75 75
76static const struct malidp_layer malidp500_layers[] = { 76static const struct malidp_layer malidp500_layers[] = {
77 { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE }, 77 { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
78 { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE }, 78 { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE },
79 { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE }, 79 { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE },
80}; 80};
81 81
82static const struct malidp_layer malidp550_layers[] = { 82static const struct malidp_layer malidp550_layers[] = {
83 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE }, 83 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
84 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE }, 84 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE },
85 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE }, 85 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
86 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE }, 86 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 0 },
87}; 87};
88 88
89#define MALIDP_DE_DEFAULT_PREFETCH_START 5 89#define MALIDP_DE_DEFAULT_PREFETCH_START 5
@@ -447,6 +447,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
447 .set_config_valid = malidp500_set_config_valid, 447 .set_config_valid = malidp500_set_config_valid,
448 .modeset = malidp500_modeset, 448 .modeset = malidp500_modeset,
449 .rotmem_required = malidp500_rotmem_required, 449 .rotmem_required = malidp500_rotmem_required,
450 .features = MALIDP_DEVICE_LV_HAS_3_STRIDES,
450 }, 451 },
451 [MALIDP_550] = { 452 [MALIDP_550] = {
452 .map = { 453 .map = {
@@ -480,6 +481,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
480 .set_config_valid = malidp550_set_config_valid, 481 .set_config_valid = malidp550_set_config_valid,
481 .modeset = malidp550_modeset, 482 .modeset = malidp550_modeset,
482 .rotmem_required = malidp550_rotmem_required, 483 .rotmem_required = malidp550_rotmem_required,
484 .features = 0,
483 }, 485 },
484 [MALIDP_650] = { 486 [MALIDP_650] = {
485 .map = { 487 .map = {
@@ -514,6 +516,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = {
514 .set_config_valid = malidp550_set_config_valid, 516 .set_config_valid = malidp550_set_config_valid,
515 .modeset = malidp550_modeset, 517 .modeset = malidp550_modeset,
516 .rotmem_required = malidp550_rotmem_required, 518 .rotmem_required = malidp550_rotmem_required,
519 .features = 0,
517 }, 520 },
518}; 521};
519 522
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index 4f8c884d1960..00974b59407d 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -58,6 +58,7 @@ struct malidp_layer {
58 u16 id; /* layer ID */ 58 u16 id; /* layer ID */
59 u16 base; /* address offset for the register bank */ 59 u16 base; /* address offset for the register bank */
60 u16 ptr; /* address offset for the pointer register */ 60 u16 ptr; /* address offset for the pointer register */
61 u16 stride_offset; /* Offset to the first stride register. */
61}; 62};
62 63
63/* regmap features */ 64/* regmap features */
@@ -93,6 +94,10 @@ struct malidp_hw_regmap {
93 const u8 bus_align_bytes; 94 const u8 bus_align_bytes;
94}; 95};
95 96
97/* device features */
98/* Unlike DP550/650, DP500 has 3 stride registers in its video layer. */
99#define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0)
100
96struct malidp_hw_device { 101struct malidp_hw_device {
97 const struct malidp_hw_regmap map; 102 const struct malidp_hw_regmap map;
98 void __iomem *regs; 103 void __iomem *regs;
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 837874e79334..414aada10fe5 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -37,7 +37,6 @@
37#define LAYER_V_VAL(x) (((x) & 0x1fff) << 16) 37#define LAYER_V_VAL(x) (((x) & 0x1fff) << 16)
38#define MALIDP_LAYER_COMP_SIZE 0x010 38#define MALIDP_LAYER_COMP_SIZE 0x010
39#define MALIDP_LAYER_OFFSET 0x014 39#define MALIDP_LAYER_OFFSET 0x014
40#define MALIDP_LAYER_STRIDE 0x018
41 40
42/* 41/*
43 * This 4-entry look-up-table is used to determine the full 8-bit alpha value 42 * 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 (state->crtc_h < mp->hwdev->min_line_size)) 137 (state->crtc_h < mp->hwdev->min_line_size))
139 return -EINVAL; 138 return -EINVAL;
140 139
140 /*
141 * DP550/650 video layers can accept 3 plane formats only if
142 * fb->pitches[1] == fb->pitches[2] since they don't have a
143 * third plane stride register.
144 */
145 if (ms->n_planes == 3 &&
146 !(mp->hwdev->features & MALIDP_DEVICE_LV_HAS_3_STRIDES) &&
147 (state->fb->pitches[1] != state->fb->pitches[2]))
148 return -EINVAL;
149
141 /* packed RGB888 / BGR888 can't be rotated or flipped */ 150 /* packed RGB888 / BGR888 can't be rotated or flipped */
142 if (state->rotation != DRM_ROTATE_0 && 151 if (state->rotation != DRM_ROTATE_0 &&
143 (fb->format->format == DRM_FORMAT_RGB888 || 152 (fb->format->format == DRM_FORMAT_RGB888 ||
@@ -170,6 +179,25 @@ static int malidp_de_plane_check(struct drm_plane *plane,
170 return 0; 179 return 0;
171} 180}
172 181
182static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
183 int num_planes, unsigned int pitches[3])
184{
185 int i;
186 int num_strides = num_planes;
187
188 if (!mp->layer->stride_offset)
189 return;
190
191 if (num_planes == 3)
192 num_strides = (mp->hwdev->features &
193 MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
194
195 for (i = 0; i < num_strides; ++i)
196 malidp_hw_write(mp->hwdev, pitches[i],
197 mp->layer->base +
198 mp->layer->stride_offset + i * 4);
199}
200
173static void malidp_de_plane_update(struct drm_plane *plane, 201static void malidp_de_plane_update(struct drm_plane *plane,
174 struct drm_plane_state *old_state) 202 struct drm_plane_state *old_state)
175{ 203{
@@ -200,9 +228,9 @@ static void malidp_de_plane_update(struct drm_plane *plane,
200 obj->paddr += plane->state->fb->offsets[i]; 228 obj->paddr += plane->state->fb->offsets[i];
201 malidp_hw_write(mp->hwdev, lower_32_bits(obj->paddr), ptr); 229 malidp_hw_write(mp->hwdev, lower_32_bits(obj->paddr), ptr);
202 malidp_hw_write(mp->hwdev, upper_32_bits(obj->paddr), ptr + 4); 230 malidp_hw_write(mp->hwdev, upper_32_bits(obj->paddr), ptr + 4);
203 malidp_hw_write(mp->hwdev, plane->state->fb->pitches[i],
204 mp->layer->base + MALIDP_LAYER_STRIDE);
205 } 231 }
232 malidp_de_set_plane_pitches(mp, ms->n_planes,
233 plane->state->fb->pitches);
206 234
207 malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h), 235 malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h),
208 mp->layer->base + MALIDP_LAYER_SIZE); 236 mp->layer->base + MALIDP_LAYER_SIZE);
diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h
index e0651d28c485..aff6d4a84e99 100644
--- a/drivers/gpu/drm/arm/malidp_regs.h
+++ b/drivers/gpu/drm/arm/malidp_regs.h
@@ -81,6 +81,10 @@
81#define MALIDP_DE_SYNC_WIDTH 0x8 81#define MALIDP_DE_SYNC_WIDTH 0x8
82#define MALIDP_DE_HV_ACTIVE 0xc 82#define MALIDP_DE_HV_ACTIVE 0xc
83 83
84/* Stride register offsets relative to Lx_BASE */
85#define MALIDP_DE_LG_STRIDE 0x18
86#define MALIDP_DE_LV_STRIDE0 0x18
87
84/* macros to set values into registers */ 88/* macros to set values into registers */
85#define MALIDP_DE_H_FRONTPORCH(x) (((x) & 0xfff) << 0) 89#define MALIDP_DE_H_FRONTPORCH(x) (((x) & 0xfff) << 0)
86#define MALIDP_DE_H_BACKPORCH(x) (((x) & 0x3ff) << 16) 90#define MALIDP_DE_H_BACKPORCH(x) (((x) & 0x3ff) << 16)