forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/arm/malidp_planes.c
....@@ -1,20 +1,21 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
34 * Author: Liviu Dudau <Liviu.Dudau@arm.com>
45 *
5
- * This program is free software and is provided to you under the terms of the
6
- * GNU General Public License version 2 as published by the Free Software
7
- * Foundation, and any use by you of this program is subject to the terms
8
- * of such GNU licence.
9
- *
106 * ARM Mali DP plane manipulation routines.
117 */
128
13
-#include <drm/drmP.h>
9
+#include <linux/iommu.h>
10
+#include <linux/platform_device.h>
11
+
1412 #include <drm/drm_atomic.h>
1513 #include <drm/drm_atomic_helper.h>
14
+#include <drm/drm_drv.h>
1615 #include <drm/drm_fb_cma_helper.h>
16
+#include <drm/drm_fourcc.h>
1717 #include <drm/drm_gem_cma_helper.h>
18
+#include <drm/drm_gem_framebuffer_helper.h>
1819 #include <drm/drm_plane_helper.h>
1920 #include <drm/drm_print.h>
2021
....@@ -36,6 +37,7 @@
3637 #define LAYER_COMP_MASK (0x3 << 12)
3738 #define LAYER_COMP_PIXEL (0x3 << 12)
3839 #define LAYER_COMP_PLANE (0x2 << 12)
40
+#define LAYER_PMUL_ENABLE (0x1 << 14)
3941 #define LAYER_ALPHA_OFFSET (16)
4042 #define LAYER_ALPHA_MASK (0xff)
4143 #define LAYER_ALPHA(x) (((x) & LAYER_ALPHA_MASK) << LAYER_ALPHA_OFFSET)
....@@ -48,6 +50,8 @@
4850 #define MALIDP550_LS_ENABLE 0x01c
4951 #define MALIDP550_LS_R1_IN_SIZE 0x020
5052
53
+#define MODIFIERS_COUNT_MAX 15
54
+
5155 /*
5256 * This 4-entry look-up-table is used to determine the full 8-bit alpha value
5357 * for formats with 1- or 2-bit alpha channels.
....@@ -55,6 +59,13 @@
5559 * opacity for 2-bit formats.
5660 */
5761 #define MALIDP_ALPHA_LUT 0xffaa5500
62
+
63
+/* page sizes the MMU prefetcher can support */
64
+#define MALIDP_MMU_PREFETCH_PARTIAL_PGSIZES (SZ_4K | SZ_64K)
65
+#define MALIDP_MMU_PREFETCH_FULL_PGSIZES (SZ_1M | SZ_2M)
66
+
67
+/* readahead for partial-frame prefetch */
68
+#define MALIDP_MMU_PREFETCH_READAHEAD 8
5869
5970 static void malidp_de_plane_destroy(struct drm_plane *plane)
6071 {
....@@ -78,11 +89,8 @@
7889 kfree(state);
7990 plane->state = NULL;
8091 state = kzalloc(sizeof(*state), GFP_KERNEL);
81
- if (state) {
82
- state->base.plane = plane;
83
- state->base.rotation = DRM_MODE_ROTATE_0;
84
- plane->state = &state->base;
85
- }
92
+ if (state)
93
+ __drm_atomic_helper_plane_reset(plane, &state->base);
8694 }
8795
8896 static struct
....@@ -103,6 +111,9 @@
103111 state->format = m_state->format;
104112 state->n_planes = m_state->n_planes;
105113
114
+ state->mmu_prefetch_mode = m_state->mmu_prefetch_mode;
115
+ state->mmu_prefetch_pgsize = m_state->mmu_prefetch_pgsize;
116
+
106117 return &state->base;
107118 }
108119
....@@ -115,6 +126,12 @@
115126 kfree(m_state);
116127 }
117128
129
+static const char * const prefetch_mode_names[] = {
130
+ [MALIDP_PREFETCH_MODE_NONE] = "MMU_PREFETCH_NONE",
131
+ [MALIDP_PREFETCH_MODE_PARTIAL] = "MMU_PREFETCH_PARTIAL",
132
+ [MALIDP_PREFETCH_MODE_FULL] = "MMU_PREFETCH_FULL",
133
+};
134
+
118135 static void malidp_plane_atomic_print_state(struct drm_printer *p,
119136 const struct drm_plane_state *state)
120137 {
....@@ -123,6 +140,120 @@
123140 drm_printf(p, "\trotmem_size=%u\n", ms->rotmem_size);
124141 drm_printf(p, "\tformat_id=%u\n", ms->format);
125142 drm_printf(p, "\tn_planes=%u\n", ms->n_planes);
143
+ drm_printf(p, "\tmmu_prefetch_mode=%s\n",
144
+ prefetch_mode_names[ms->mmu_prefetch_mode]);
145
+ drm_printf(p, "\tmmu_prefetch_pgsize=%d\n", ms->mmu_prefetch_pgsize);
146
+}
147
+
148
+bool malidp_format_mod_supported(struct drm_device *drm,
149
+ u32 format, u64 modifier)
150
+{
151
+ const struct drm_format_info *info;
152
+ const u64 *modifiers;
153
+ struct malidp_drm *malidp = drm->dev_private;
154
+ const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
155
+
156
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
157
+ return false;
158
+
159
+ /* Some pixel formats are supported without any modifier */
160
+ if (modifier == DRM_FORMAT_MOD_LINEAR) {
161
+ /*
162
+ * However these pixel formats need to be supported with
163
+ * modifiers only
164
+ */
165
+ return !malidp_hw_format_is_afbc_only(format);
166
+ }
167
+
168
+ if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_ARM) {
169
+ DRM_ERROR("Unknown modifier (not Arm)\n");
170
+ return false;
171
+ }
172
+
173
+ if (modifier &
174
+ ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_MOD_VALID_BITS)) {
175
+ DRM_DEBUG_KMS("Unsupported modifiers\n");
176
+ return false;
177
+ }
178
+
179
+ modifiers = malidp_format_modifiers;
180
+
181
+ /* SPLIT buffers must use SPARSE layout */
182
+ if (WARN_ON_ONCE((modifier & AFBC_SPLIT) && !(modifier & AFBC_SPARSE)))
183
+ return false;
184
+
185
+ /* CBR only applies to YUV formats, where YTR should be always 0 */
186
+ if (WARN_ON_ONCE((modifier & AFBC_CBR) && (modifier & AFBC_YTR)))
187
+ return false;
188
+
189
+ while (*modifiers != DRM_FORMAT_MOD_INVALID) {
190
+ if (*modifiers == modifier)
191
+ break;
192
+
193
+ modifiers++;
194
+ }
195
+
196
+ /* return false, if the modifier was not found */
197
+ if (*modifiers == DRM_FORMAT_MOD_INVALID) {
198
+ DRM_DEBUG_KMS("Unsupported modifier\n");
199
+ return false;
200
+ }
201
+
202
+ info = drm_format_info(format);
203
+
204
+ if (info->num_planes != 1) {
205
+ DRM_DEBUG_KMS("AFBC buffers expect one plane\n");
206
+ return false;
207
+ }
208
+
209
+ if (malidp_hw_format_is_linear_only(format) == true) {
210
+ DRM_DEBUG_KMS("Given format (0x%x) is supported is linear mode only\n",
211
+ format);
212
+ return false;
213
+ }
214
+
215
+ /*
216
+ * RGB formats need to provide YTR modifier and YUV formats should not
217
+ * provide YTR modifier.
218
+ */
219
+ if (!(info->is_yuv) != !!(modifier & AFBC_FORMAT_MOD_YTR)) {
220
+ DRM_DEBUG_KMS("AFBC_FORMAT_MOD_YTR is %s for %s formats\n",
221
+ info->is_yuv ? "disallowed" : "mandatory",
222
+ info->is_yuv ? "YUV" : "RGB");
223
+ return false;
224
+ }
225
+
226
+ if (modifier & AFBC_SPLIT) {
227
+ if (!info->is_yuv) {
228
+ if (info->cpp[0] <= 2) {
229
+ DRM_DEBUG_KMS("RGB formats <= 16bpp are not supported with SPLIT\n");
230
+ return false;
231
+ }
232
+ }
233
+
234
+ if ((info->hsub != 1) || (info->vsub != 1)) {
235
+ if (!(format == DRM_FORMAT_YUV420_10BIT &&
236
+ (map->features & MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT))) {
237
+ DRM_DEBUG_KMS("Formats which are sub-sampled should never be split\n");
238
+ return false;
239
+ }
240
+ }
241
+ }
242
+
243
+ if (modifier & AFBC_CBR) {
244
+ if ((info->hsub == 1) || (info->vsub == 1)) {
245
+ DRM_DEBUG_KMS("Formats which are not sub-sampled should not have CBR set\n");
246
+ return false;
247
+ }
248
+ }
249
+
250
+ return true;
251
+}
252
+
253
+static bool malidp_format_mod_supported_per_plane(struct drm_plane *plane,
254
+ u32 format, u64 modifier)
255
+{
256
+ return malidp_format_mod_supported(plane->dev, format, modifier);
126257 }
127258
128259 static const struct drm_plane_funcs malidp_de_plane_funcs = {
....@@ -133,6 +264,7 @@
133264 .atomic_duplicate_state = malidp_duplicate_plane_state,
134265 .atomic_destroy_state = malidp_destroy_plane_state,
135266 .atomic_print_state = malidp_plane_atomic_print_state,
267
+ .format_mod_supported = malidp_format_mod_supported_per_plane,
136268 };
137269
138270 static int malidp_se_check_scaling(struct malidp_plane *mp,
....@@ -176,6 +308,199 @@
176308 return 0;
177309 }
178310
311
+static u32 malidp_get_pgsize_bitmap(struct malidp_plane *mp)
312
+{
313
+ u32 pgsize_bitmap = 0;
314
+
315
+ if (iommu_present(&platform_bus_type)) {
316
+ struct iommu_domain *mmu_dom =
317
+ iommu_get_domain_for_dev(mp->base.dev->dev);
318
+
319
+ if (mmu_dom)
320
+ pgsize_bitmap = mmu_dom->pgsize_bitmap;
321
+ }
322
+
323
+ return pgsize_bitmap;
324
+}
325
+
326
+/*
327
+ * Check if the framebuffer is entirely made up of pages at least pgsize in
328
+ * size. Only a heuristic: assumes that each scatterlist entry has been aligned
329
+ * to the largest page size smaller than its length and that the MMU maps to
330
+ * the largest page size possible.
331
+ */
332
+static bool malidp_check_pages_threshold(struct malidp_plane_state *ms,
333
+ u32 pgsize)
334
+{
335
+ int i;
336
+
337
+ for (i = 0; i < ms->n_planes; i++) {
338
+ struct drm_gem_object *obj;
339
+ struct drm_gem_cma_object *cma_obj;
340
+ struct sg_table *sgt;
341
+ struct scatterlist *sgl;
342
+
343
+ obj = drm_gem_fb_get_obj(ms->base.fb, i);
344
+ cma_obj = to_drm_gem_cma_obj(obj);
345
+
346
+ if (cma_obj->sgt)
347
+ sgt = cma_obj->sgt;
348
+ else
349
+ sgt = obj->funcs->get_sg_table(obj);
350
+
351
+ if (IS_ERR(sgt))
352
+ return false;
353
+
354
+ sgl = sgt->sgl;
355
+
356
+ while (sgl) {
357
+ if (sgl->length < pgsize) {
358
+ if (!cma_obj->sgt)
359
+ kfree(sgt);
360
+ return false;
361
+ }
362
+
363
+ sgl = sg_next(sgl);
364
+ }
365
+ if (!cma_obj->sgt)
366
+ kfree(sgt);
367
+ }
368
+
369
+ return true;
370
+}
371
+
372
+/*
373
+ * Check if it is possible to enable partial-frame MMU prefetch given the
374
+ * current format, AFBC state and rotation.
375
+ */
376
+static bool malidp_partial_prefetch_supported(u32 format, u64 modifier,
377
+ unsigned int rotation)
378
+{
379
+ bool afbc, sparse;
380
+
381
+ /* rotation and horizontal flip not supported for partial prefetch */
382
+ if (rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 |
383
+ DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X))
384
+ return false;
385
+
386
+ afbc = modifier & DRM_FORMAT_MOD_ARM_AFBC(0);
387
+ sparse = modifier & AFBC_FORMAT_MOD_SPARSE;
388
+
389
+ switch (format) {
390
+ case DRM_FORMAT_ARGB2101010:
391
+ case DRM_FORMAT_RGBA1010102:
392
+ case DRM_FORMAT_BGRA1010102:
393
+ case DRM_FORMAT_ARGB8888:
394
+ case DRM_FORMAT_RGBA8888:
395
+ case DRM_FORMAT_BGRA8888:
396
+ case DRM_FORMAT_XRGB8888:
397
+ case DRM_FORMAT_XBGR8888:
398
+ case DRM_FORMAT_RGBX8888:
399
+ case DRM_FORMAT_BGRX8888:
400
+ case DRM_FORMAT_RGB888:
401
+ case DRM_FORMAT_RGBA5551:
402
+ case DRM_FORMAT_RGB565:
403
+ /* always supported */
404
+ return true;
405
+
406
+ case DRM_FORMAT_ABGR2101010:
407
+ case DRM_FORMAT_ABGR8888:
408
+ case DRM_FORMAT_ABGR1555:
409
+ case DRM_FORMAT_BGR565:
410
+ /* supported, but if AFBC then must be sparse mode */
411
+ return (!afbc) || (afbc && sparse);
412
+
413
+ case DRM_FORMAT_BGR888:
414
+ /* supported, but not for AFBC */
415
+ return !afbc;
416
+
417
+ case DRM_FORMAT_YUYV:
418
+ case DRM_FORMAT_UYVY:
419
+ case DRM_FORMAT_NV12:
420
+ case DRM_FORMAT_YUV420:
421
+ /* not supported */
422
+ return false;
423
+
424
+ default:
425
+ return false;
426
+ }
427
+}
428
+
429
+/*
430
+ * Select the preferred MMU prefetch mode. Full-frame prefetch is preferred as
431
+ * long as the framebuffer is all large pages. Otherwise partial-frame prefetch
432
+ * is selected as long as it is supported for the current format. The selected
433
+ * page size for prefetch is returned in pgsize_bitmap.
434
+ */
435
+static enum mmu_prefetch_mode malidp_mmu_prefetch_select_mode
436
+ (struct malidp_plane_state *ms, u32 *pgsize_bitmap)
437
+{
438
+ u32 pgsizes;
439
+
440
+ /* get the full-frame prefetch page size(s) supported by the MMU */
441
+ pgsizes = *pgsize_bitmap & MALIDP_MMU_PREFETCH_FULL_PGSIZES;
442
+
443
+ while (pgsizes) {
444
+ u32 largest_pgsize = 1 << __fls(pgsizes);
445
+
446
+ if (malidp_check_pages_threshold(ms, largest_pgsize)) {
447
+ *pgsize_bitmap = largest_pgsize;
448
+ return MALIDP_PREFETCH_MODE_FULL;
449
+ }
450
+
451
+ pgsizes -= largest_pgsize;
452
+ }
453
+
454
+ /* get the partial-frame prefetch page size(s) supported by the MMU */
455
+ pgsizes = *pgsize_bitmap & MALIDP_MMU_PREFETCH_PARTIAL_PGSIZES;
456
+
457
+ if (malidp_partial_prefetch_supported(ms->base.fb->format->format,
458
+ ms->base.fb->modifier,
459
+ ms->base.rotation)) {
460
+ /* partial prefetch using the smallest page size */
461
+ *pgsize_bitmap = 1 << __ffs(pgsizes);
462
+ return MALIDP_PREFETCH_MODE_PARTIAL;
463
+ }
464
+ *pgsize_bitmap = 0;
465
+ return MALIDP_PREFETCH_MODE_NONE;
466
+}
467
+
468
+static u32 malidp_calc_mmu_control_value(enum mmu_prefetch_mode mode,
469
+ u8 readahead, u8 n_planes, u32 pgsize)
470
+{
471
+ u32 mmu_ctrl = 0;
472
+
473
+ if (mode != MALIDP_PREFETCH_MODE_NONE) {
474
+ mmu_ctrl |= MALIDP_MMU_CTRL_EN;
475
+
476
+ if (mode == MALIDP_PREFETCH_MODE_PARTIAL) {
477
+ mmu_ctrl |= MALIDP_MMU_CTRL_MODE;
478
+ mmu_ctrl |= MALIDP_MMU_CTRL_PP_NUM_REQ(readahead);
479
+ }
480
+
481
+ if (pgsize == SZ_64K || pgsize == SZ_2M) {
482
+ int i;
483
+
484
+ for (i = 0; i < n_planes; i++)
485
+ mmu_ctrl |= MALIDP_MMU_CTRL_PX_PS(i);
486
+ }
487
+ }
488
+
489
+ return mmu_ctrl;
490
+}
491
+
492
+static void malidp_de_prefetch_settings(struct malidp_plane *mp,
493
+ struct malidp_plane_state *ms)
494
+{
495
+ if (!mp->layer->mmu_ctrl_offset)
496
+ return;
497
+
498
+ /* get the page sizes supported by the MMU */
499
+ ms->mmu_prefetch_pgsize = malidp_get_pgsize_bitmap(mp);
500
+ ms->mmu_prefetch_mode =
501
+ malidp_mmu_prefetch_select_mode(ms, &ms->mmu_prefetch_pgsize);
502
+}
503
+
179504 static int malidp_de_plane_check(struct drm_plane *plane,
180505 struct drm_plane_state *state)
181506 {
....@@ -183,27 +508,42 @@
183508 struct malidp_plane_state *ms = to_malidp_plane_state(state);
184509 bool rotated = state->rotation & MALIDP_ROTATED_MASK;
185510 struct drm_framebuffer *fb;
511
+ u16 pixel_alpha = state->pixel_blend_mode;
186512 int i, ret;
513
+ unsigned int block_w, block_h;
187514
188
- if (!state->crtc || !state->fb)
515
+ if (!state->crtc || WARN_ON(!state->fb))
189516 return 0;
190517
191518 fb = state->fb;
192519
193520 ms->format = malidp_hw_get_format_id(&mp->hwdev->hw->map,
194
- mp->layer->id,
195
- fb->format->format);
521
+ mp->layer->id, fb->format->format,
522
+ !!fb->modifier);
196523 if (ms->format == MALIDP_INVALID_FORMAT_ID)
197524 return -EINVAL;
198525
199526 ms->n_planes = fb->format->num_planes;
200527 for (i = 0; i < ms->n_planes; i++) {
201528 u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
202
- if (fb->pitches[i] & (alignment - 1)) {
529
+
530
+ if (((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
531
+ & (alignment - 1)) && !(fb->modifier)) {
203532 DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
204533 fb->pitches[i], i);
205534 return -EINVAL;
206535 }
536
+ }
537
+
538
+ block_w = drm_format_info_block_width(fb->format, 0);
539
+ block_h = drm_format_info_block_height(fb->format, 0);
540
+ if (fb->width % block_w || fb->height % block_h) {
541
+ DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
542
+ return -EINVAL;
543
+ }
544
+ if ((state->src_x >> 16) % block_w || (state->src_y >> 16) % block_h) {
545
+ DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
546
+ return -EINVAL;
207547 }
208548
209549 if ((state->crtc_w > mp->hwdev->max_line_size) ||
....@@ -226,11 +566,26 @@
226566 if (ret)
227567 return ret;
228568
229
- /* packed RGB888 / BGR888 can't be rotated or flipped */
230
- if (state->rotation != DRM_MODE_ROTATE_0 &&
231
- (fb->format->format == DRM_FORMAT_RGB888 ||
232
- fb->format->format == DRM_FORMAT_BGR888))
569
+ /* validate the rotation constraints for each layer */
570
+ if (state->rotation != DRM_MODE_ROTATE_0) {
571
+ if (mp->layer->rot == ROTATE_NONE)
572
+ return -EINVAL;
573
+ if ((mp->layer->rot == ROTATE_COMPRESSED) && !(fb->modifier))
574
+ return -EINVAL;
575
+ /*
576
+ * packed RGB888 / BGR888 can't be rotated or flipped
577
+ * unless they are stored in a compressed way
578
+ */
579
+ if ((fb->format->format == DRM_FORMAT_RGB888 ||
580
+ fb->format->format == DRM_FORMAT_BGR888) && !(fb->modifier))
581
+ return -EINVAL;
582
+ }
583
+
584
+ /* SMART layer does not support AFBC */
585
+ if (mp->layer->id == DE_SMART && fb->modifier) {
586
+ DRM_ERROR("AFBC framebuffer not supported in SMART layer");
233587 return -EINVAL;
588
+ }
234589
235590 ms->rotmem_size = 0;
236591 if (state->rotation & MALIDP_ROTATED_MASK) {
....@@ -238,12 +593,21 @@
238593
239594 val = mp->hwdev->hw->rotmem_required(mp->hwdev, state->crtc_w,
240595 state->crtc_h,
241
- fb->format->format);
596
+ fb->format->format,
597
+ !!(fb->modifier));
242598 if (val < 0)
243599 return val;
244600
245601 ms->rotmem_size = val;
246602 }
603
+
604
+ /* HW can't support plane + pixel blending */
605
+ if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
606
+ (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE) &&
607
+ fb->format->has_alpha)
608
+ return -EINVAL;
609
+
610
+ malidp_de_prefetch_settings(mp, ms);
247611
248612 return 0;
249613 }
....@@ -261,10 +625,18 @@
261625 num_strides = (mp->hwdev->hw->features &
262626 MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
263627
264
- for (i = 0; i < num_strides; ++i)
265
- malidp_hw_write(mp->hwdev, pitches[i],
628
+ /*
629
+ * The drm convention for pitch is that it needs to cover width * cpp,
630
+ * but our hardware wants the pitch/stride to cover all rows included
631
+ * in a tile.
632
+ */
633
+ for (i = 0; i < num_strides; ++i) {
634
+ unsigned int block_h = drm_format_info_block_height(mp->base.state->fb->format, i);
635
+
636
+ malidp_hw_write(mp->hwdev, pitches[i] * block_h,
266637 mp->layer->base +
267638 mp->layer->stride_offset + i * 4);
639
+ }
268640 }
269641
270642 static const s16
....@@ -321,38 +693,142 @@
321693 }
322694 }
323695
696
+static void malidp_de_set_mmu_control(struct malidp_plane *mp,
697
+ struct malidp_plane_state *ms)
698
+{
699
+ u32 mmu_ctrl;
700
+
701
+ /* check hardware supports MMU prefetch */
702
+ if (!mp->layer->mmu_ctrl_offset)
703
+ return;
704
+
705
+ mmu_ctrl = malidp_calc_mmu_control_value(ms->mmu_prefetch_mode,
706
+ MALIDP_MMU_PREFETCH_READAHEAD,
707
+ ms->n_planes,
708
+ ms->mmu_prefetch_pgsize);
709
+
710
+ malidp_hw_write(mp->hwdev, mmu_ctrl,
711
+ mp->layer->base + mp->layer->mmu_ctrl_offset);
712
+}
713
+
714
+static void malidp_set_plane_base_addr(struct drm_framebuffer *fb,
715
+ struct malidp_plane *mp,
716
+ int plane_index)
717
+{
718
+ dma_addr_t paddr;
719
+ u16 ptr;
720
+ struct drm_plane *plane = &mp->base;
721
+ bool afbc = fb->modifier ? true : false;
722
+
723
+ ptr = mp->layer->ptr + (plane_index << 4);
724
+
725
+ /*
726
+ * drm_fb_cma_get_gem_addr() alters the physical base address of the
727
+ * framebuffer as per the plane's src_x, src_y co-ordinates (ie to
728
+ * take care of source cropping).
729
+ * For AFBC, this is not needed as the cropping is handled by _AD_CROP_H
730
+ * and _AD_CROP_V registers.
731
+ */
732
+ if (!afbc) {
733
+ paddr = drm_fb_cma_get_gem_addr(fb, plane->state,
734
+ plane_index);
735
+ } else {
736
+ struct drm_gem_cma_object *obj;
737
+
738
+ obj = drm_fb_cma_get_gem_obj(fb, plane_index);
739
+
740
+ if (WARN_ON(!obj))
741
+ return;
742
+ paddr = obj->paddr;
743
+ }
744
+
745
+ malidp_hw_write(mp->hwdev, lower_32_bits(paddr), ptr);
746
+ malidp_hw_write(mp->hwdev, upper_32_bits(paddr), ptr + 4);
747
+}
748
+
749
+static void malidp_de_set_plane_afbc(struct drm_plane *plane)
750
+{
751
+ struct malidp_plane *mp;
752
+ u32 src_w, src_h, val = 0, src_x, src_y;
753
+ struct drm_framebuffer *fb = plane->state->fb;
754
+
755
+ mp = to_malidp_plane(plane);
756
+
757
+ /* no afbc_decoder_offset means AFBC is not supported on this plane */
758
+ if (!mp->layer->afbc_decoder_offset)
759
+ return;
760
+
761
+ if (!fb->modifier) {
762
+ malidp_hw_write(mp->hwdev, 0, mp->layer->afbc_decoder_offset);
763
+ return;
764
+ }
765
+
766
+ /* convert src values from Q16 fixed point to integer */
767
+ src_w = plane->state->src_w >> 16;
768
+ src_h = plane->state->src_h >> 16;
769
+ src_x = plane->state->src_x >> 16;
770
+ src_y = plane->state->src_y >> 16;
771
+
772
+ val = ((fb->width - (src_x + src_w)) << MALIDP_AD_CROP_RIGHT_OFFSET) |
773
+ src_x;
774
+ malidp_hw_write(mp->hwdev, val,
775
+ mp->layer->afbc_decoder_offset + MALIDP_AD_CROP_H);
776
+
777
+ val = ((fb->height - (src_y + src_h)) << MALIDP_AD_CROP_BOTTOM_OFFSET) |
778
+ src_y;
779
+ malidp_hw_write(mp->hwdev, val,
780
+ mp->layer->afbc_decoder_offset + MALIDP_AD_CROP_V);
781
+
782
+ val = MALIDP_AD_EN;
783
+ if (fb->modifier & AFBC_FORMAT_MOD_SPLIT)
784
+ val |= MALIDP_AD_BS;
785
+ if (fb->modifier & AFBC_FORMAT_MOD_YTR)
786
+ val |= MALIDP_AD_YTR;
787
+
788
+ malidp_hw_write(mp->hwdev, val, mp->layer->afbc_decoder_offset);
789
+}
790
+
324791 static void malidp_de_plane_update(struct drm_plane *plane,
325792 struct drm_plane_state *old_state)
326793 {
327794 struct malidp_plane *mp;
328795 struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
796
+ struct drm_plane_state *state = plane->state;
797
+ u16 pixel_alpha = state->pixel_blend_mode;
798
+ u8 plane_alpha = state->alpha >> 8;
329799 u32 src_w, src_h, dest_w, dest_h, val;
330800 int i;
331
- bool format_has_alpha = plane->state->fb->format->has_alpha;
801
+ struct drm_framebuffer *fb = plane->state->fb;
332802
333803 mp = to_malidp_plane(plane);
334804
335
- /* convert src values from Q16 fixed point to integer */
336
- src_w = plane->state->src_w >> 16;
337
- src_h = plane->state->src_h >> 16;
338
- dest_w = plane->state->crtc_w;
339
- dest_h = plane->state->crtc_h;
805
+ /*
806
+ * For AFBC framebuffer, use the framebuffer width and height for
807
+ * configuring layer input size register.
808
+ */
809
+ if (fb->modifier) {
810
+ src_w = fb->width;
811
+ src_h = fb->height;
812
+ } else {
813
+ /* convert src values from Q16 fixed point to integer */
814
+ src_w = state->src_w >> 16;
815
+ src_h = state->src_h >> 16;
816
+ }
817
+
818
+ dest_w = state->crtc_w;
819
+ dest_h = state->crtc_h;
340820
341821 val = malidp_hw_read(mp->hwdev, mp->layer->base);
342822 val = (val & ~LAYER_FORMAT_MASK) | ms->format;
343823 malidp_hw_write(mp->hwdev, val, mp->layer->base);
344824
345
- for (i = 0; i < ms->n_planes; i++) {
346
- /* calculate the offset for the layer's plane registers */
347
- u16 ptr = mp->layer->ptr + (i << 4);
348
- dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
349
- plane->state, i);
825
+ for (i = 0; i < ms->n_planes; i++)
826
+ malidp_set_plane_base_addr(fb, mp, i);
350827
351
- malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
352
- malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
353
- }
828
+ malidp_de_set_mmu_control(mp, ms);
829
+
354830 malidp_de_set_plane_pitches(mp, ms->n_planes,
355
- plane->state->fb->pitches);
831
+ state->fb->pitches);
356832
357833 if ((plane->state->color_encoding != old_state->color_encoding) ||
358834 (plane->state->color_range != old_state->color_range))
....@@ -365,52 +841,58 @@
365841 malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
366842 mp->layer->base + MALIDP_LAYER_COMP_SIZE);
367843
368
- malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->crtc_x) |
369
- LAYER_V_VAL(plane->state->crtc_y),
844
+ malidp_hw_write(mp->hwdev, LAYER_H_VAL(state->crtc_x) |
845
+ LAYER_V_VAL(state->crtc_y),
370846 mp->layer->base + MALIDP_LAYER_OFFSET);
371847
372
- if (mp->layer->id == DE_SMART)
848
+ if (mp->layer->id == DE_SMART) {
849
+ /*
850
+ * Enable the first rectangle in the SMART layer to be
851
+ * able to use it as a drm plane.
852
+ */
853
+ malidp_hw_write(mp->hwdev, 1,
854
+ mp->layer->base + MALIDP550_LS_ENABLE);
373855 malidp_hw_write(mp->hwdev,
374856 LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h),
375857 mp->layer->base + MALIDP550_LS_R1_IN_SIZE);
858
+ }
859
+
860
+ malidp_de_set_plane_afbc(plane);
376861
377862 /* first clear the rotation bits */
378863 val = malidp_hw_read(mp->hwdev, mp->layer->base + MALIDP_LAYER_CONTROL);
379864 val &= ~LAYER_ROT_MASK;
380865
381866 /* setup the rotation and axis flip bits */
382
- if (plane->state->rotation & DRM_MODE_ROTATE_MASK)
867
+ if (state->rotation & DRM_MODE_ROTATE_MASK)
383868 val |= ilog2(plane->state->rotation & DRM_MODE_ROTATE_MASK) <<
384869 LAYER_ROT_OFFSET;
385
- if (plane->state->rotation & DRM_MODE_REFLECT_X)
870
+ if (state->rotation & DRM_MODE_REFLECT_X)
386871 val |= LAYER_H_FLIP;
387
- if (plane->state->rotation & DRM_MODE_REFLECT_Y)
872
+ if (state->rotation & DRM_MODE_REFLECT_Y)
388873 val |= LAYER_V_FLIP;
389874
390
- val &= ~LAYER_COMP_MASK;
391
- if (format_has_alpha) {
875
+ val &= ~(LAYER_COMP_MASK | LAYER_PMUL_ENABLE | LAYER_ALPHA(0xff));
392876
393
- /*
394
- * always enable pixel alpha blending until we have a way
395
- * to change blend modes
396
- */
397
- val |= LAYER_COMP_PIXEL;
398
- } else {
399
-
400
- /*
401
- * do not enable pixel alpha blending as the color channel
402
- * does not have any alpha information
403
- */
877
+ if (state->alpha != DRM_BLEND_ALPHA_OPAQUE) {
404878 val |= LAYER_COMP_PLANE;
405
-
406
- /* Set layer alpha coefficient to 0xff ie fully opaque */
407
- val |= LAYER_ALPHA(0xff);
879
+ } else if (state->fb->format->has_alpha) {
880
+ /* We only care about blend mode if the format has alpha */
881
+ switch (pixel_alpha) {
882
+ case DRM_MODE_BLEND_PREMULTI:
883
+ val |= LAYER_COMP_PIXEL | LAYER_PMUL_ENABLE;
884
+ break;
885
+ case DRM_MODE_BLEND_COVERAGE:
886
+ val |= LAYER_COMP_PIXEL;
887
+ break;
888
+ }
408889 }
890
+ val |= LAYER_ALPHA(plane_alpha);
409891
410892 val &= ~LAYER_FLOWCFG(LAYER_FLOWCFG_MASK);
411
- if (plane->state->crtc) {
893
+ if (state->crtc) {
412894 struct malidp_crtc_state *m =
413
- to_malidp_crtc_state(plane->state->crtc->state);
895
+ to_malidp_crtc_state(state->crtc->state);
414896
415897 if (m->scaler_config.scale_enable &&
416898 m->scaler_config.plane_src_id == mp->layer->id)
....@@ -440,6 +922,11 @@
440922 .atomic_disable = malidp_de_plane_disable,
441923 };
442924
925
+static const uint64_t linear_only_modifiers[] = {
926
+ DRM_FORMAT_MOD_LINEAR,
927
+ DRM_FORMAT_MOD_INVALID
928
+};
929
+
443930 int malidp_de_planes_init(struct drm_device *drm)
444931 {
445932 struct malidp_drm *malidp = drm->dev_private;
....@@ -449,8 +936,30 @@
449936 unsigned long crtcs = BIT(drm->mode_config.num_crtc);
450937 unsigned long flags = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 |
451938 DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
939
+ unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
940
+ BIT(DRM_MODE_BLEND_PREMULTI) |
941
+ BIT(DRM_MODE_BLEND_COVERAGE);
452942 u32 *formats;
453
- int ret, i, j, n;
943
+ int ret, i = 0, j = 0, n;
944
+ u64 supported_modifiers[MODIFIERS_COUNT_MAX];
945
+ const u64 *modifiers;
946
+
947
+ modifiers = malidp_format_modifiers;
948
+
949
+ if (!(map->features & MALIDP_DEVICE_AFBC_SUPPORT_SPLIT)) {
950
+ /*
951
+ * Since our hardware does not support SPLIT, so build the list
952
+ * of supported modifiers excluding SPLIT ones.
953
+ */
954
+ while (*modifiers != DRM_FORMAT_MOD_INVALID) {
955
+ if (!(*modifiers & AFBC_SPLIT))
956
+ supported_modifiers[j++] = *modifiers;
957
+
958
+ modifiers++;
959
+ }
960
+ supported_modifiers[j++] = DRM_FORMAT_MOD_INVALID;
961
+ modifiers = supported_modifiers;
962
+ }
454963
455964 formats = kcalloc(map->n_pixel_formats, sizeof(*formats), GFP_KERNEL);
456965 if (!formats) {
....@@ -475,9 +984,15 @@
475984
476985 plane_type = (i == 0) ? DRM_PLANE_TYPE_PRIMARY :
477986 DRM_PLANE_TYPE_OVERLAY;
987
+
988
+ /*
989
+ * All the layers except smart layer supports AFBC modifiers.
990
+ */
478991 ret = drm_universal_plane_init(drm, &plane->base, crtcs,
479
- &malidp_de_plane_funcs, formats,
480
- n, NULL, plane_type, NULL);
992
+ &malidp_de_plane_funcs, formats, n,
993
+ (id == DE_SMART) ? linear_only_modifiers : modifiers,
994
+ plane_type, NULL);
995
+
481996 if (ret < 0)
482997 goto cleanup;
483998
....@@ -486,13 +1001,10 @@
4861001 plane->hwdev = malidp->dev;
4871002 plane->layer = &map->layers[i];
4881003
1004
+ drm_plane_create_alpha_property(&plane->base);
1005
+ drm_plane_create_blend_mode_property(&plane->base, blend_caps);
1006
+
4891007 if (id == DE_SMART) {
490
- /*
491
- * Enable the first rectangle in the SMART layer to be
492
- * able to use it as a drm plane.
493
- */
494
- malidp_hw_write(malidp->dev, 1,
495
- plane->layer->base + MALIDP550_LS_ENABLE);
4961008 /* Skip the features which the SMART layer doesn't have. */
4971009 continue;
4981010 }