hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
....@@ -1,31 +1,23 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2014, 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
8
+#include <linux/delay.h>
9
+#include <linux/interconnect.h>
1910 #include <linux/of_irq.h>
11
+
12
+#include <drm/drm_debugfs.h>
13
+#include <drm/drm_drv.h>
14
+#include <drm/drm_file.h>
15
+#include <drm/drm_vblank.h>
2016
2117 #include "msm_drv.h"
2218 #include "msm_gem.h"
2319 #include "msm_mmu.h"
2420 #include "mdp5_kms.h"
25
-
26
-static const char *iommu_ports[] = {
27
- "mdp_0",
28
-};
2921
3022 static int mdp5_hw_init(struct msm_kms *kms)
3123 {
....@@ -144,46 +136,58 @@
144136
145137 state->mdp5_kms = mdp5_kms;
146138
147
- drm_atomic_private_obj_init(&mdp5_kms->glob_state,
139
+ drm_atomic_private_obj_init(mdp5_kms->dev, &mdp5_kms->glob_state,
148140 &state->base,
149141 &mdp5_global_state_funcs);
150142 return 0;
151143 }
152144
145
+static void mdp5_enable_commit(struct msm_kms *kms)
146
+{
147
+ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
148
+ pm_runtime_get_sync(&mdp5_kms->pdev->dev);
149
+}
150
+
151
+static void mdp5_disable_commit(struct msm_kms *kms)
152
+{
153
+ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
154
+ pm_runtime_put_sync(&mdp5_kms->pdev->dev);
155
+}
156
+
153157 static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
154158 {
155159 struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
156
- struct device *dev = &mdp5_kms->pdev->dev;
157160 struct mdp5_global_state *global_state;
158161
159162 global_state = mdp5_get_existing_global_state(mdp5_kms);
160
-
161
- pm_runtime_get_sync(dev);
162163
163164 if (mdp5_kms->smp)
164165 mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp);
165166 }
166167
167
-static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
168
+static void mdp5_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
169
+{
170
+ /* TODO */
171
+}
172
+
173
+static void mdp5_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
168174 {
169175 struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
170
- struct device *dev = &mdp5_kms->pdev->dev;
171
- struct mdp5_global_state *global_state;
176
+ struct drm_crtc *crtc;
172177
173
- drm_atomic_helper_wait_for_vblanks(mdp5_kms->dev, state);
178
+ for_each_crtc_mask(mdp5_kms->dev, crtc, crtc_mask)
179
+ mdp5_crtc_wait_for_commit_done(crtc);
180
+}
181
+
182
+static void mdp5_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
183
+{
184
+ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
185
+ struct mdp5_global_state *global_state;
174186
175187 global_state = mdp5_get_existing_global_state(mdp5_kms);
176188
177189 if (mdp5_kms->smp)
178190 mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp);
179
-
180
- pm_runtime_put_sync(dev);
181
-}
182
-
183
-static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms,
184
- struct drm_crtc *crtc)
185
-{
186
- mdp5_crtc_wait_for_commit_done(crtc);
187191 }
188192
189193 static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
....@@ -225,8 +229,7 @@
225229 mdp5_pipe_destroy(mdp5_kms->hwpipes[i]);
226230
227231 if (aspace) {
228
- aspace->mmu->funcs->detach(aspace->mmu,
229
- iommu_ports, ARRAY_SIZE(iommu_ports));
232
+ aspace->mmu->funcs->detach(aspace->mmu);
230233 msm_gem_address_space_put(aspace);
231234 }
232235 }
....@@ -256,17 +259,9 @@
256259
257260 static int mdp5_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
258261 {
259
- struct drm_device *dev = minor->dev;
260
- int ret;
261
-
262
- ret = drm_debugfs_create_files(mdp5_debugfs_list,
263
- ARRAY_SIZE(mdp5_debugfs_list),
264
- minor->debugfs_root, minor);
265
-
266
- if (ret) {
267
- dev_err(dev->dev, "could not install mdp5_debugfs_list\n");
268
- return ret;
269
- }
262
+ drm_debugfs_create_files(mdp5_debugfs_list,
263
+ ARRAY_SIZE(mdp5_debugfs_list),
264
+ minor->debugfs_root, minor);
270265
271266 return 0;
272267 }
....@@ -281,9 +276,12 @@
281276 .irq = mdp5_irq,
282277 .enable_vblank = mdp5_enable_vblank,
283278 .disable_vblank = mdp5_disable_vblank,
279
+ .flush_commit = mdp5_flush_commit,
280
+ .enable_commit = mdp5_enable_commit,
281
+ .disable_commit = mdp5_disable_commit,
284282 .prepare_commit = mdp5_prepare_commit,
283
+ .wait_flush = mdp5_wait_flush,
285284 .complete_commit = mdp5_complete_commit,
286
- .wait_for_crtc_commit_done = mdp5_wait_for_crtc_commit_done,
287285 .get_format = mdp_get_format,
288286 .round_pixclk = mdp5_round_pixclk,
289287 .set_split_display = mdp5_set_split_display,
....@@ -303,6 +301,10 @@
303301 mdp5_kms->enable_count--;
304302 WARN_ON(mdp5_kms->enable_count < 0);
305303
304
+ if (mdp5_kms->tbu_rt_clk)
305
+ clk_disable_unprepare(mdp5_kms->tbu_rt_clk);
306
+ if (mdp5_kms->tbu_clk)
307
+ clk_disable_unprepare(mdp5_kms->tbu_clk);
306308 clk_disable_unprepare(mdp5_kms->ahb_clk);
307309 clk_disable_unprepare(mdp5_kms->axi_clk);
308310 clk_disable_unprepare(mdp5_kms->core_clk);
....@@ -323,6 +325,10 @@
323325 clk_prepare_enable(mdp5_kms->core_clk);
324326 if (mdp5_kms->lut_clk)
325327 clk_prepare_enable(mdp5_kms->lut_clk);
328
+ if (mdp5_kms->tbu_clk)
329
+ clk_prepare_enable(mdp5_kms->tbu_clk);
330
+ if (mdp5_kms->tbu_rt_clk)
331
+ clk_prepare_enable(mdp5_kms->tbu_rt_clk);
326332
327333 return 0;
328334 }
....@@ -337,7 +343,7 @@
337343
338344 encoder = mdp5_encoder_init(dev, intf, ctl);
339345 if (IS_ERR(encoder)) {
340
- dev_err(dev->dev, "failed to construct encoder\n");
346
+ DRM_DEV_ERROR(dev->dev, "failed to construct encoder\n");
341347 return encoder;
342348 }
343349
....@@ -418,7 +424,7 @@
418424 int dsi_id = get_dsi_id_from_intf(hw_cfg, intf->num);
419425
420426 if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) {
421
- dev_err(dev->dev, "failed to find dsi from intf %d\n",
427
+ DRM_DEV_ERROR(dev->dev, "failed to find dsi from intf %d\n",
422428 intf->num);
423429 ret = -EINVAL;
424430 break;
....@@ -443,7 +449,7 @@
443449 break;
444450 }
445451 default:
446
- dev_err(dev->dev, "unknown intf: %d\n", intf->type);
452
+ DRM_DEV_ERROR(dev->dev, "unknown intf: %d\n", intf->type);
447453 ret = -EINVAL;
448454 break;
449455 }
....@@ -455,13 +461,10 @@
455461 {
456462 struct drm_device *dev = mdp5_kms->dev;
457463 struct msm_drm_private *priv = dev->dev_private;
458
- const struct mdp5_cfg_hw *hw_cfg;
459464 unsigned int num_crtcs;
460465 int i, ret, pi = 0, ci = 0;
461466 struct drm_plane *primary[MAX_BASES] = { NULL };
462467 struct drm_plane *cursor[MAX_BASES] = { NULL };
463
-
464
- hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
465468
466469 /*
467470 * Construct encoders and modeset initialize connector devices
....@@ -500,7 +503,7 @@
500503 plane = mdp5_plane_init(dev, type);
501504 if (IS_ERR(plane)) {
502505 ret = PTR_ERR(plane);
503
- dev_err(dev->dev, "failed to construct plane %d (%d)\n", i, ret);
506
+ DRM_DEV_ERROR(dev->dev, "failed to construct plane %d (%d)\n", i, ret);
504507 goto fail;
505508 }
506509 priv->planes[priv->num_planes++] = plane;
....@@ -517,7 +520,7 @@
517520 crtc = mdp5_crtc_init(dev, primary[i], cursor[i], i);
518521 if (IS_ERR(crtc)) {
519522 ret = PTR_ERR(crtc);
520
- dev_err(dev->dev, "failed to construct crtc %d (%d)\n", i, ret);
523
+ DRM_DEV_ERROR(dev->dev, "failed to construct crtc %d (%d)\n", i, ret);
521524 goto fail;
522525 }
523526 priv->crtcs[priv->num_crtcs++] = crtc;
....@@ -552,7 +555,7 @@
552555 *major = FIELD(version, MDP5_HW_VERSION_MAJOR);
553556 *minor = FIELD(version, MDP5_HW_VERSION_MINOR);
554557
555
- dev_info(dev, "MDP5 version v%d.%d", *major, *minor);
558
+ DRM_DEV_INFO(dev, "MDP5 version v%d.%d", *major, *minor);
556559 }
557560
558561 static int get_clk(struct platform_device *pdev, struct clk **clkp,
....@@ -561,7 +564,7 @@
561564 struct device *dev = &pdev->dev;
562565 struct clk *clk = msm_clk_get(pdev, name);
563566 if (IS_ERR(clk) && mandatory) {
564
- dev_err(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk));
567
+ DRM_DEV_ERROR(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk));
565568 return PTR_ERR(clk);
566569 }
567570 if (IS_ERR(clk))
....@@ -570,98 +573,6 @@
570573 *clkp = clk;
571574
572575 return 0;
573
-}
574
-
575
-static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
576
-{
577
- struct drm_device *dev = crtc->dev;
578
- struct drm_encoder *encoder;
579
-
580
- drm_for_each_encoder(encoder, dev)
581
- if (encoder->crtc == crtc)
582
- return encoder;
583
-
584
- return NULL;
585
-}
586
-
587
-static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
588
- bool in_vblank_irq, int *vpos, int *hpos,
589
- ktime_t *stime, ktime_t *etime,
590
- const struct drm_display_mode *mode)
591
-{
592
- struct msm_drm_private *priv = dev->dev_private;
593
- struct drm_crtc *crtc;
594
- struct drm_encoder *encoder;
595
- int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
596
-
597
- crtc = priv->crtcs[pipe];
598
- if (!crtc) {
599
- DRM_ERROR("Invalid crtc %d\n", pipe);
600
- return false;
601
- }
602
-
603
- encoder = get_encoder_from_crtc(crtc);
604
- if (!encoder) {
605
- DRM_ERROR("no encoder found for crtc %d\n", pipe);
606
- return false;
607
- }
608
-
609
- vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
610
- vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
611
-
612
- /*
613
- * the line counter is 1 at the start of the VSYNC pulse and VTOTAL at
614
- * the end of VFP. Translate the porch values relative to the line
615
- * counter positions.
616
- */
617
-
618
- vactive_start = vsw + vbp + 1;
619
-
620
- vactive_end = vactive_start + mode->crtc_vdisplay;
621
-
622
- /* last scan line before VSYNC */
623
- vfp_end = mode->crtc_vtotal;
624
-
625
- if (stime)
626
- *stime = ktime_get();
627
-
628
- line = mdp5_encoder_get_linecount(encoder);
629
-
630
- if (line < vactive_start) {
631
- line -= vactive_start;
632
- } else if (line > vactive_end) {
633
- line = line - vfp_end - vactive_start;
634
- } else {
635
- line -= vactive_start;
636
- }
637
-
638
- *vpos = line;
639
- *hpos = 0;
640
-
641
- if (etime)
642
- *etime = ktime_get();
643
-
644
- return true;
645
-}
646
-
647
-static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
648
-{
649
- struct msm_drm_private *priv = dev->dev_private;
650
- struct drm_crtc *crtc;
651
- struct drm_encoder *encoder;
652
-
653
- if (pipe >= priv->num_crtcs)
654
- return 0;
655
-
656
- crtc = priv->crtcs[pipe];
657
- if (!crtc)
658
- return 0;
659
-
660
- encoder = get_encoder_from_crtc(crtc);
661
- if (!encoder)
662
- return 0;
663
-
664
- return mdp5_encoder_get_framecount(encoder);
665576 }
666577
667578 struct msm_kms *mdp5_kms_init(struct drm_device *dev)
....@@ -673,6 +584,7 @@
673584 struct msm_kms *kms;
674585 struct msm_gem_address_space *aspace;
675586 int irq, i, ret;
587
+ struct device *iommu_dev;
676588
677589 /* priv->kms would have been populated by the MDP5 driver */
678590 kms = priv->kms;
....@@ -686,9 +598,9 @@
686598 pdev = mdp5_kms->pdev;
687599
688600 irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
689
- if (irq < 0) {
690
- ret = irq;
691
- dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
601
+ if (!irq) {
602
+ ret = -EINVAL;
603
+ DRM_DEV_ERROR(&pdev->dev, "failed to get irq\n");
692604 goto fail;
693605 }
694606
....@@ -712,24 +624,27 @@
712624 mdelay(16);
713625
714626 if (config->platform.iommu) {
715
- aspace = msm_gem_address_space_create(&pdev->dev,
716
- config->platform.iommu, "mdp5");
627
+ struct msm_mmu *mmu;
628
+
629
+ iommu_dev = &pdev->dev;
630
+ if (!dev_iommu_fwspec_get(iommu_dev))
631
+ iommu_dev = iommu_dev->parent;
632
+
633
+ mmu = msm_iommu_new(iommu_dev, config->platform.iommu);
634
+
635
+ aspace = msm_gem_address_space_create(mmu, "mdp5",
636
+ 0x1000, 0x100000000 - 0x1000);
637
+
717638 if (IS_ERR(aspace)) {
639
+ if (!IS_ERR(mmu))
640
+ mmu->funcs->destroy(mmu);
718641 ret = PTR_ERR(aspace);
719642 goto fail;
720643 }
721644
722645 kms->aspace = aspace;
723
-
724
- ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
725
- ARRAY_SIZE(iommu_ports));
726
- if (ret) {
727
- dev_err(&pdev->dev, "failed to attach iommu: %d\n",
728
- ret);
729
- goto fail;
730
- }
731646 } else {
732
- dev_info(&pdev->dev,
647
+ DRM_DEV_INFO(&pdev->dev,
733648 "no iommu, fallback to phys contig buffers for scanout\n");
734649 aspace = NULL;
735650 }
....@@ -738,7 +653,7 @@
738653
739654 ret = modeset_init(mdp5_kms);
740655 if (ret) {
741
- dev_err(&pdev->dev, "modeset_init failed: %d\n", ret);
656
+ DRM_DEV_ERROR(&pdev->dev, "modeset_init failed: %d\n", ret);
742657 goto fail;
743658 }
744659
....@@ -747,10 +662,7 @@
747662 dev->mode_config.max_width = 0xffff;
748663 dev->mode_config.max_height = 0xffff;
749664
750
- dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos;
751
- dev->driver->get_scanout_position = mdp5_get_scanoutpos;
752
- dev->driver->get_vblank_counter = mdp5_get_vblank_counter;
753
- dev->max_vblank_count = 0xffffffff;
665
+ dev->max_vblank_count = 0; /* max_vblank_count is set on each CRTC */
754666 dev->vblank_disable_immediate = true;
755667
756668 return kms;
....@@ -795,7 +707,7 @@
795707 hwpipe = mdp5_pipe_init(pipes[i], offsets[i], caps);
796708 if (IS_ERR(hwpipe)) {
797709 ret = PTR_ERR(hwpipe);
798
- dev_err(dev->dev, "failed to construct pipe for %s (%d)\n",
710
+ DRM_DEV_ERROR(dev->dev, "failed to construct pipe for %s (%d)\n",
799711 pipe2name(pipes[i]), ret);
800712 return ret;
801713 }
....@@ -867,7 +779,7 @@
867779 mixer = mdp5_mixer_init(&hw_cfg->lm.instances[i]);
868780 if (IS_ERR(mixer)) {
869781 ret = PTR_ERR(mixer);
870
- dev_err(dev->dev, "failed to construct LM%d (%d)\n",
782
+ DRM_DEV_ERROR(dev->dev, "failed to construct LM%d (%d)\n",
871783 i, ret);
872784 return ret;
873785 }
....@@ -897,7 +809,7 @@
897809
898810 intf = kzalloc(sizeof(*intf), GFP_KERNEL);
899811 if (!intf) {
900
- dev_err(dev->dev, "failed to construct INTF%d\n", i);
812
+ DRM_DEV_ERROR(dev->dev, "failed to construct INTF%d\n", i);
901813 return -ENOMEM;
902814 }
903815
....@@ -958,6 +870,8 @@
958870
959871 /* optional clocks: */
960872 get_clk(pdev, &mdp5_kms->lut_clk, "lut", false);
873
+ get_clk(pdev, &mdp5_kms->tbu_clk, "tbu", false);
874
+ get_clk(pdev, &mdp5_kms->tbu_rt_clk, "tbu_rt", false);
961875
962876 /* we need to set a default rate before enabling. Set a safe
963877 * rate first, then figure out hw revision, and then set a
....@@ -1049,9 +963,46 @@
1049963 .unbind = mdp5_unbind,
1050964 };
1051965
966
+static int mdp5_setup_interconnect(struct platform_device *pdev)
967
+{
968
+ struct icc_path *path0 = of_icc_get(&pdev->dev, "mdp0-mem");
969
+ struct icc_path *path1 = of_icc_get(&pdev->dev, "mdp1-mem");
970
+ struct icc_path *path_rot = of_icc_get(&pdev->dev, "rotator-mem");
971
+
972
+ if (IS_ERR(path0))
973
+ return PTR_ERR(path0);
974
+
975
+ if (!path0) {
976
+ /* no interconnect support is not necessarily a fatal
977
+ * condition, the platform may simply not have an
978
+ * interconnect driver yet. But warn about it in case
979
+ * bootloader didn't setup bus clocks high enough for
980
+ * scanout.
981
+ */
982
+ dev_warn(&pdev->dev, "No interconnect support may cause display underflows!\n");
983
+ return 0;
984
+ }
985
+
986
+ icc_set_bw(path0, 0, MBps_to_icc(6400));
987
+
988
+ if (!IS_ERR_OR_NULL(path1))
989
+ icc_set_bw(path1, 0, MBps_to_icc(6400));
990
+ if (!IS_ERR_OR_NULL(path_rot))
991
+ icc_set_bw(path_rot, 0, MBps_to_icc(6400));
992
+
993
+ return 0;
994
+}
995
+
1052996 static int mdp5_dev_probe(struct platform_device *pdev)
1053997 {
998
+ int ret;
999
+
10541000 DBG("");
1001
+
1002
+ ret = mdp5_setup_interconnect(pdev);
1003
+ if (ret)
1004
+ return ret;
1005
+
10551006 return component_add(&pdev->dev, &mdp5_ops);
10561007 }
10571008