forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
....@@ -1,26 +1,18 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
34 * Copyright (C) 2013 Red Hat
45 * Author: Rob Clark <robdclark@gmail.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms of the GNU General Public License version 2 as published by
8
- * the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful, but WITHOUT
11
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
- * more details.
14
- *
15
- * You should have received a copy of the GNU General Public License along with
16
- * this program. If not, see <http://www.gnu.org/licenses/>.
176 */
187
198 #include <linux/sort.h>
9
+
2010 #include <drm/drm_mode.h>
2111 #include <drm/drm_crtc.h>
22
-#include <drm/drm_crtc_helper.h>
2312 #include <drm/drm_flip_work.h>
13
+#include <drm/drm_fourcc.h>
14
+#include <drm/drm_probe_helper.h>
15
+#include <drm/drm_vblank.h>
2416
2517 #include "mdp5_kms.h"
2618
....@@ -173,8 +165,8 @@
173165 struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base);
174166 struct msm_kms *kms = &mdp5_kms->base.base;
175167
176
- msm_gem_put_iova(val, kms->aspace);
177
- drm_gem_object_put_unlocked(val);
168
+ msm_gem_unpin_iova(val, kms->aspace);
169
+ drm_gem_object_put(val);
178170 }
179171
180172 static void mdp5_crtc_destroy(struct drm_crtc *crtc)
....@@ -222,7 +214,6 @@
222214 struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
223215 struct mdp5_kms *mdp5_kms = get_kms(crtc);
224216 struct drm_plane *plane;
225
- const struct mdp5_cfg_hw *hw_cfg;
226217 struct mdp5_plane_state *pstate, *pstates[STAGE_MAX + 1] = {NULL};
227218 const struct mdp_format *format;
228219 struct mdp5_hw_mixer *mixer = pipeline->mixer;
....@@ -239,8 +230,6 @@
239230 u32 mixer_op_mode = 0;
240231 u32 val;
241232 #define blender(stage) ((stage) - STAGE0)
242
-
243
- hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
244233
245234 spin_lock_irqsave(&mdp5_crtc->lm_lock, flags);
246235
....@@ -384,14 +373,7 @@
384373
385374 mode = &crtc->state->adjusted_mode;
386375
387
- DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
388
- crtc->name, mode->base.id, mode->name,
389
- mode->vrefresh, mode->clock,
390
- mode->hdisplay, mode->hsync_start,
391
- mode->hsync_end, mode->htotal,
392
- mode->vdisplay, mode->vsync_start,
393
- mode->vsync_end, mode->vtotal,
394
- mode->type, mode->flags);
376
+ DBG("%s: set mode: " DRM_MODE_FMT, crtc->name, DRM_MODE_ARG(mode));
395377
396378 mixer_width = mode->hdisplay;
397379 if (r_mixer)
....@@ -421,6 +403,83 @@
421403 }
422404
423405 spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
406
+}
407
+
408
+static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
409
+{
410
+ struct drm_device *dev = crtc->dev;
411
+ struct drm_encoder *encoder;
412
+
413
+ drm_for_each_encoder(encoder, dev)
414
+ if (encoder->crtc == crtc)
415
+ return encoder;
416
+
417
+ return NULL;
418
+}
419
+
420
+static bool mdp5_crtc_get_scanout_position(struct drm_crtc *crtc,
421
+ bool in_vblank_irq,
422
+ int *vpos, int *hpos,
423
+ ktime_t *stime, ktime_t *etime,
424
+ const struct drm_display_mode *mode)
425
+{
426
+ unsigned int pipe = crtc->index;
427
+ struct drm_encoder *encoder;
428
+ int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
429
+
430
+
431
+ encoder = get_encoder_from_crtc(crtc);
432
+ if (!encoder) {
433
+ DRM_ERROR("no encoder found for crtc %d\n", pipe);
434
+ return false;
435
+ }
436
+
437
+ vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
438
+ vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
439
+
440
+ /*
441
+ * the line counter is 1 at the start of the VSYNC pulse and VTOTAL at
442
+ * the end of VFP. Translate the porch values relative to the line
443
+ * counter positions.
444
+ */
445
+
446
+ vactive_start = vsw + vbp + 1;
447
+
448
+ vactive_end = vactive_start + mode->crtc_vdisplay;
449
+
450
+ /* last scan line before VSYNC */
451
+ vfp_end = mode->crtc_vtotal;
452
+
453
+ if (stime)
454
+ *stime = ktime_get();
455
+
456
+ line = mdp5_encoder_get_linecount(encoder);
457
+
458
+ if (line < vactive_start)
459
+ line -= vactive_start;
460
+ else if (line > vactive_end)
461
+ line = line - vfp_end - vactive_start;
462
+ else
463
+ line -= vactive_start;
464
+
465
+ *vpos = line;
466
+ *hpos = 0;
467
+
468
+ if (etime)
469
+ *etime = ktime_get();
470
+
471
+ return true;
472
+}
473
+
474
+static u32 mdp5_crtc_get_vblank_counter(struct drm_crtc *crtc)
475
+{
476
+ struct drm_encoder *encoder;
477
+
478
+ encoder = get_encoder_from_crtc(crtc);
479
+ if (!encoder)
480
+ return 0;
481
+
482
+ return mdp5_encoder_get_framecount(encoder);
424483 }
425484
426485 static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
....@@ -455,6 +514,18 @@
455514 }
456515
457516 mdp5_crtc->enabled = false;
517
+}
518
+
519
+static void mdp5_crtc_vblank_on(struct drm_crtc *crtc)
520
+{
521
+ struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
522
+ struct mdp5_interface *intf = mdp5_cstate->pipeline.intf;
523
+ u32 count;
524
+
525
+ count = intf->mode == MDP5_INTF_DSI_MODE_COMMAND ? 0 : 0xffffffff;
526
+ drm_crtc_set_max_vblank_count(crtc, count);
527
+
528
+ drm_crtc_vblank_on(crtc);
458529 }
459530
460531 static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
....@@ -493,7 +564,7 @@
493564 }
494565
495566 /* Restore vblank irq handling after power is enabled */
496
- drm_crtc_vblank_on(crtc);
567
+ mdp5_crtc_vblank_on(crtc);
497568
498569 mdp5_crtc_mode_set_nofb(crtc);
499570
....@@ -537,9 +608,15 @@
537608 if (ret)
538609 return ret;
539610
540
- mdp5_mixer_release(new_crtc_state->state, old_mixer);
611
+ ret = mdp5_mixer_release(new_crtc_state->state, old_mixer);
612
+ if (ret)
613
+ return ret;
614
+
541615 if (old_r_mixer) {
542
- mdp5_mixer_release(new_crtc_state->state, old_r_mixer);
616
+ ret = mdp5_mixer_release(new_crtc_state->state, old_r_mixer);
617
+ if (ret)
618
+ return ret;
619
+
543620 if (!need_right_mixer)
544621 pipeline->r_mixer = NULL;
545622 }
....@@ -662,7 +739,7 @@
662739
663740 ret = mdp5_crtc_setup_pipeline(crtc, state, need_right_mixer);
664741 if (ret) {
665
- dev_err(dev->dev, "couldn't assign mixers %d\n", ret);
742
+ DRM_DEV_ERROR(dev->dev, "couldn't assign mixers %d\n", ret);
666743 return ret;
667744 }
668745
....@@ -679,7 +756,7 @@
679756 * and that we don't have conflicting mixer stages:
680757 */
681758 if ((cnt + start - 1) >= hw_cfg->lm.nb_stages) {
682
- dev_err(dev->dev, "too many planes! cnt=%d, start stage=%d\n",
759
+ DRM_DEV_ERROR(dev->dev, "too many planes! cnt=%d, start stage=%d\n",
683760 cnt, start);
684761 return -EINVAL;
685762 }
....@@ -789,6 +866,7 @@
789866
790867 static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
791868 {
869
+ const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ARGB8888);
792870 struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
793871 struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
794872 struct mdp5_kms *mdp5_kms = get_kms(crtc);
....@@ -807,7 +885,7 @@
807885 width = mdp5_crtc->cursor.width;
808886 height = mdp5_crtc->cursor.height;
809887
810
- stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
888
+ stride = width * info->cpp[0];
811889
812890 get_roi(crtc, &roi_w, &roi_h);
813891
....@@ -879,7 +957,7 @@
879957 }
880958
881959 if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
882
- dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
960
+ DRM_DEV_ERROR(dev->dev, "bad cursor size: %dx%d\n", width, height);
883961 return -EINVAL;
884962 }
885963
....@@ -887,7 +965,7 @@
887965 if (!ctl)
888966 return -EINVAL;
889967
890
- /* don't support LM cursors when we we have source split enabled */
968
+ /* don't support LM cursors when we have source split enabled */
891969 if (mdp5_cstate->pipeline.r_mixer)
892970 return -EINVAL;
893971
....@@ -903,10 +981,12 @@
903981 if (!cursor_bo)
904982 return -ENOENT;
905983
906
- ret = msm_gem_get_iova(cursor_bo, kms->aspace,
984
+ ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace,
907985 &mdp5_crtc->cursor.iova);
908
- if (ret)
986
+ if (ret) {
987
+ drm_gem_object_put(cursor_bo);
909988 return -EINVAL;
989
+ }
910990
911991 pm_runtime_get_sync(&pdev->dev);
912992
....@@ -924,7 +1004,7 @@
9241004 set_cursor:
9251005 ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable);
9261006 if (ret) {
927
- dev_err(dev->dev, "failed to %sable cursor: %d\n",
1007
+ DRM_DEV_ERROR(dev->dev, "failed to %sable cursor: %d\n",
9281008 cursor_enable ? "en" : "dis", ret);
9291009 goto end;
9301010 }
....@@ -958,7 +1038,7 @@
9581038 return -EINVAL;
9591039 }
9601040
961
- /* don't support LM cursors when we we have source split enabled */
1041
+ /* don't support LM cursors when we have source split enabled */
9621042 if (mdp5_cstate->pipeline.r_mixer)
9631043 return -EINVAL;
9641044
....@@ -1009,23 +1089,6 @@
10091089 drm_printf(p, "\tcmd_mode=%d\n", mdp5_cstate->cmd_mode);
10101090 }
10111091
1012
-static void mdp5_crtc_reset(struct drm_crtc *crtc)
1013
-{
1014
- struct mdp5_crtc_state *mdp5_cstate;
1015
-
1016
- if (crtc->state) {
1017
- __drm_atomic_helper_crtc_destroy_state(crtc->state);
1018
- kfree(to_mdp5_crtc_state(crtc->state));
1019
- }
1020
-
1021
- mdp5_cstate = kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL);
1022
-
1023
- if (mdp5_cstate) {
1024
- mdp5_cstate->base.crtc = crtc;
1025
- crtc->state = &mdp5_cstate->base;
1026
- }
1027
-}
1028
-
10291092 static struct drm_crtc_state *
10301093 mdp5_crtc_duplicate_state(struct drm_crtc *crtc)
10311094 {
....@@ -1053,6 +1116,31 @@
10531116 kfree(mdp5_cstate);
10541117 }
10551118
1119
+static void mdp5_crtc_reset(struct drm_crtc *crtc)
1120
+{
1121
+ struct mdp5_crtc_state *mdp5_cstate =
1122
+ kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL);
1123
+
1124
+ if (crtc->state)
1125
+ mdp5_crtc_destroy_state(crtc, crtc->state);
1126
+
1127
+ __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
1128
+}
1129
+
1130
+static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
1131
+ .set_config = drm_atomic_helper_set_config,
1132
+ .destroy = mdp5_crtc_destroy,
1133
+ .page_flip = drm_atomic_helper_page_flip,
1134
+ .reset = mdp5_crtc_reset,
1135
+ .atomic_duplicate_state = mdp5_crtc_duplicate_state,
1136
+ .atomic_destroy_state = mdp5_crtc_destroy_state,
1137
+ .atomic_print_state = mdp5_crtc_atomic_print_state,
1138
+ .get_vblank_counter = mdp5_crtc_get_vblank_counter,
1139
+ .enable_vblank = msm_crtc_enable_vblank,
1140
+ .disable_vblank = msm_crtc_disable_vblank,
1141
+ .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
1142
+};
1143
+
10561144 static const struct drm_crtc_funcs mdp5_crtc_funcs = {
10571145 .set_config = drm_atomic_helper_set_config,
10581146 .destroy = mdp5_crtc_destroy,
....@@ -1063,6 +1151,10 @@
10631151 .cursor_set = mdp5_crtc_cursor_set,
10641152 .cursor_move = mdp5_crtc_cursor_move,
10651153 .atomic_print_state = mdp5_crtc_atomic_print_state,
1154
+ .get_vblank_counter = mdp5_crtc_get_vblank_counter,
1155
+ .enable_vblank = msm_crtc_enable_vblank,
1156
+ .disable_vblank = msm_crtc_disable_vblank,
1157
+ .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
10661158 };
10671159
10681160 static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
....@@ -1072,6 +1164,7 @@
10721164 .atomic_flush = mdp5_crtc_atomic_flush,
10731165 .atomic_enable = mdp5_crtc_atomic_enable,
10741166 .atomic_disable = mdp5_crtc_atomic_disable,
1167
+ .get_scanout_position = mdp5_crtc_get_scanout_position,
10751168 };
10761169
10771170 static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
....@@ -1105,7 +1198,7 @@
11051198 struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc,
11061199 pp_done);
11071200
1108
- complete(&mdp5_crtc->pp_completion);
1201
+ complete_all(&mdp5_crtc->pp_completion);
11091202 }
11101203
11111204 static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc)
....@@ -1236,6 +1329,8 @@
12361329 mdp5_crtc->lm_cursor_enabled = cursor_plane ? false : true;
12371330
12381331 drm_crtc_init_with_planes(dev, crtc, plane, cursor_plane,
1332
+ cursor_plane ?
1333
+ &mdp5_crtc_no_lm_cursor_funcs :
12391334 &mdp5_crtc_funcs, NULL);
12401335
12411336 drm_flip_work_init(&mdp5_crtc->unref_cursor_work,