diff options
author | Mihail Atanassov <mihail.atanassov@arm.com> | 2017-01-23 10:24:35 -0500 |
---|---|---|
committer | Liviu Dudau <Liviu.Dudau@arm.com> | 2017-01-26 10:46:19 -0500 |
commit | 83d642ee6dbec57ef1639a3de1e383fbfc5c44ec (patch) | |
tree | c0bdb4752227b0aab0d124f1d4b17130dd7a0229 | |
parent | b70b332f14b704b22894571bc422812f539aea4f (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.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_planes.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_regs.h | 4 |
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 | ||
76 | static const struct malidp_layer malidp500_layers[] = { | 76 | static 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 | ||
82 | static const struct malidp_layer malidp550_layers[] = { | 82 | static 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 | |||
96 | struct malidp_hw_device { | 101 | struct 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 | ||
182 | static 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 | |||
173 | static void malidp_de_plane_update(struct drm_plane *plane, | 201 | static 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) |