1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
9 struct mdp5_cfg_handler {
11 struct mdp5_cfg config;
14 /* mdp5_cfg must be exposed (used in mdp5.xml.h) */
15 const struct mdp5_cfg_hw *mdp5_cfg = NULL;
17 static const struct mdp5_cfg_hw msm8x74v1_config = {
28 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4, [SSPP_VIG2] = 7,
29 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
30 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
35 .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
36 .flush_hw_mask = 0x0003ffff,
40 .base = { 0x01100, 0x01500, 0x01900 },
41 .caps = MDP_PIPE_CAP_HFLIP |
49 .base = { 0x01d00, 0x02100, 0x02500 },
50 .caps = MDP_PIPE_CAP_HFLIP |
57 .base = { 0x02900, 0x02d00 },
58 .caps = MDP_PIPE_CAP_HFLIP |
64 .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
66 { .id = 0, .pp = 0, .dspp = 0,
67 .caps = MDP_LM_CAP_DISPLAY, },
68 { .id = 1, .pp = 1, .dspp = 1,
69 .caps = MDP_LM_CAP_DISPLAY, },
70 { .id = 2, .pp = 2, .dspp = 2,
71 .caps = MDP_LM_CAP_DISPLAY, },
72 { .id = 3, .pp = -1, .dspp = -1,
73 .caps = MDP_LM_CAP_WB },
74 { .id = 4, .pp = -1, .dspp = -1,
75 .caps = MDP_LM_CAP_WB },
83 .base = { 0x04500, 0x04900, 0x04d00 },
87 .base = { 0x21a00, 0x21b00, 0x21c00 },
90 .base = { 0x21000, 0x21200, 0x21400, 0x21600 },
101 static const struct mdp5_cfg_hw msm8x74v2_config = {
105 .caps = MDP_CAP_SMP |
112 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4, [SSPP_VIG2] = 7,
113 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
114 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
119 .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
120 .flush_hw_mask = 0x0003ffff,
124 .base = { 0x01100, 0x01500, 0x01900 },
125 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
126 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
127 MDP_PIPE_CAP_DECIMATION,
131 .base = { 0x01d00, 0x02100, 0x02500 },
132 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
133 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
137 .base = { 0x02900, 0x02d00 },
138 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
142 .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
144 { .id = 0, .pp = 0, .dspp = 0,
145 .caps = MDP_LM_CAP_DISPLAY, },
146 { .id = 1, .pp = 1, .dspp = 1,
147 .caps = MDP_LM_CAP_DISPLAY, },
148 { .id = 2, .pp = 2, .dspp = 2,
149 .caps = MDP_LM_CAP_DISPLAY, },
150 { .id = 3, .pp = -1, .dspp = -1,
151 .caps = MDP_LM_CAP_WB, },
152 { .id = 4, .pp = -1, .dspp = -1,
153 .caps = MDP_LM_CAP_WB, },
157 .max_height = 0xFFFF,
161 .base = { 0x04500, 0x04900, 0x04d00 },
165 .base = { 0x13000, 0x13200 },
169 .base = { 0x12c00, 0x12d00, 0x12e00 },
172 .base = { 0x12400, 0x12600, 0x12800, 0x12a00 },
180 .max_clk = 200000000,
183 static const struct mdp5_cfg_hw apq8084_config = {
187 .caps = MDP_CAP_SMP |
195 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4,
196 [SSPP_VIG2] = 7, [SSPP_VIG3] = 19,
197 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
198 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
199 [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
201 .reserved_state[0] = GENMASK(7, 0), /* first 8 MMBs */
203 /* Two SMP blocks are statically tied to RGB pipes: */
204 [16] = 2, [17] = 2, [18] = 2, [22] = 2,
209 .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
210 .flush_hw_mask = 0x003fffff,
214 .base = { 0x01100, 0x01500, 0x01900, 0x01d00 },
215 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
216 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
217 MDP_PIPE_CAP_DECIMATION,
221 .base = { 0x02100, 0x02500, 0x02900, 0x02d00 },
222 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
223 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
227 .base = { 0x03100, 0x03500 },
228 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
232 .base = { 0x03900, 0x03d00, 0x04100, 0x04500, 0x04900, 0x04d00 },
234 { .id = 0, .pp = 0, .dspp = 0,
235 .caps = MDP_LM_CAP_DISPLAY |
237 { .id = 1, .pp = 1, .dspp = 1,
238 .caps = MDP_LM_CAP_DISPLAY, },
239 { .id = 2, .pp = 2, .dspp = 2,
240 .caps = MDP_LM_CAP_DISPLAY |
242 { .id = 3, .pp = -1, .dspp = -1,
243 .caps = MDP_LM_CAP_WB, },
244 { .id = 4, .pp = -1, .dspp = -1,
245 .caps = MDP_LM_CAP_WB, },
246 { .id = 5, .pp = 3, .dspp = 3,
247 .caps = MDP_LM_CAP_DISPLAY, },
251 .max_height = 0xFFFF,
255 .base = { 0x05100, 0x05500, 0x05900, 0x05d00 },
260 .base = { 0x13400, 0x13600, 0x13800 },
264 .base = { 0x12e00, 0x12f00, 0x13000, 0x13100 },
267 .base = { 0x12400, 0x12600, 0x12800, 0x12a00, 0x12c00 },
275 .max_clk = 320000000,
278 static const struct mdp5_cfg_hw msm8x16_config = {
283 .caps = MDP_CAP_SMP |
290 [SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
291 [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
296 .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
297 .flush_hw_mask = 0x4003ffff,
302 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
303 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
304 MDP_PIPE_CAP_DECIMATION,
308 .base = { 0x14000, 0x16000 },
309 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
310 MDP_PIPE_CAP_DECIMATION,
315 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
318 .count = 2, /* LM0 and LM3 */
319 .base = { 0x44000, 0x47000 },
321 { .id = 0, .pp = 0, .dspp = 0,
322 .caps = MDP_LM_CAP_DISPLAY, },
323 { .id = 3, .pp = -1, .dspp = -1,
324 .caps = MDP_LM_CAP_WB },
328 .max_height = 0xFFFF,
336 .base = { 0x00000, 0x6a800 },
342 .max_clk = 320000000,
345 static const struct mdp5_cfg_hw msm8x94_config = {
349 .caps = MDP_CAP_SMP |
357 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4,
358 [SSPP_VIG2] = 7, [SSPP_VIG3] = 19,
359 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
360 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
361 [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
363 .reserved_state[0] = GENMASK(23, 0), /* first 24 MMBs */
365 [1] = 1, [4] = 1, [7] = 1, [19] = 1,
366 [16] = 5, [17] = 5, [18] = 5, [22] = 5,
371 .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
372 .flush_hw_mask = 0xf0ffffff,
376 .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
377 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
378 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
379 MDP_PIPE_CAP_DECIMATION,
383 .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
384 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
385 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
389 .base = { 0x24000, 0x26000 },
390 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
394 .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
396 { .id = 0, .pp = 0, .dspp = 0,
397 .caps = MDP_LM_CAP_DISPLAY |
399 { .id = 1, .pp = 1, .dspp = 1,
400 .caps = MDP_LM_CAP_DISPLAY, },
401 { .id = 2, .pp = 2, .dspp = 2,
402 .caps = MDP_LM_CAP_DISPLAY |
404 { .id = 3, .pp = -1, .dspp = -1,
405 .caps = MDP_LM_CAP_WB, },
406 { .id = 4, .pp = -1, .dspp = -1,
407 .caps = MDP_LM_CAP_WB, },
408 { .id = 5, .pp = 3, .dspp = 3,
409 .caps = MDP_LM_CAP_DISPLAY, },
413 .max_height = 0xFFFF,
417 .base = { 0x54000, 0x56000, 0x58000, 0x5a000 },
422 .base = { 0x78000, 0x78800, 0x79000 },
426 .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
429 .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
437 .max_clk = 400000000,
440 static const struct mdp5_cfg_hw msm8x96_config = {
444 .caps = MDP_CAP_DSC |
451 .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
452 .flush_hw_mask = 0xf4ffffff,
456 .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
457 .caps = MDP_PIPE_CAP_HFLIP |
461 MDP_PIPE_CAP_DECIMATION |
462 MDP_PIPE_CAP_SW_PIX_EXT |
467 .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
468 .caps = MDP_PIPE_CAP_HFLIP |
471 MDP_PIPE_CAP_DECIMATION |
472 MDP_PIPE_CAP_SW_PIX_EXT |
477 .base = { 0x24000, 0x26000 },
478 .caps = MDP_PIPE_CAP_HFLIP |
480 MDP_PIPE_CAP_SW_PIX_EXT |
485 .base = { 0x34000, 0x36000 },
486 .caps = MDP_PIPE_CAP_HFLIP |
488 MDP_PIPE_CAP_SW_PIX_EXT |
489 MDP_PIPE_CAP_CURSOR |
495 .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
497 { .id = 0, .pp = 0, .dspp = 0,
498 .caps = MDP_LM_CAP_DISPLAY |
500 { .id = 1, .pp = 1, .dspp = 1,
501 .caps = MDP_LM_CAP_DISPLAY, },
502 { .id = 2, .pp = 2, .dspp = -1,
503 .caps = MDP_LM_CAP_DISPLAY |
505 { .id = 3, .pp = -1, .dspp = -1,
506 .caps = MDP_LM_CAP_WB, },
507 { .id = 4, .pp = -1, .dspp = -1,
508 .caps = MDP_LM_CAP_WB, },
509 { .id = 5, .pp = 3, .dspp = -1,
510 .caps = MDP_LM_CAP_DISPLAY, },
514 .max_height = 0xFFFF,
518 .base = { 0x54000, 0x56000 },
522 .base = { 0x78000, 0x78800, 0x79000 },
526 .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
534 .base = { 0x80000, 0x80400 },
537 .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
545 .max_clk = 412500000,
548 static const struct mdp5_cfg_hw msm8917_config = {
556 .base = { 0x01000, 0x01200, 0x01400 },
557 .flush_hw_mask = 0xffffffff,
562 .caps = MDP_PIPE_CAP_HFLIP |
566 MDP_PIPE_CAP_DECIMATION |
567 MDP_PIPE_CAP_SW_PIX_EXT |
572 .base = { 0x14000, 0x16000 },
573 .caps = MDP_PIPE_CAP_HFLIP |
575 MDP_PIPE_CAP_DECIMATION |
576 MDP_PIPE_CAP_SW_PIX_EXT |
582 .caps = MDP_PIPE_CAP_HFLIP |
584 MDP_PIPE_CAP_SW_PIX_EXT |
590 .caps = MDP_PIPE_CAP_HFLIP |
592 MDP_PIPE_CAP_SW_PIX_EXT |
593 MDP_PIPE_CAP_CURSOR |
599 .base = { 0x44000, 0x45000 },
601 { .id = 0, .pp = 0, .dspp = 0,
602 .caps = MDP_LM_CAP_DISPLAY, },
603 { .id = 1, .pp = -1, .dspp = -1,
604 .caps = MDP_LM_CAP_WB },
608 .max_height = 0xFFFF,
624 .base = { 0x6a000, 0x6a800 },
630 .max_clk = 320000000,
633 static const struct mdp5_cfg_hw msm8998_config = {
637 .caps = MDP_CAP_DSC |
644 .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
645 .flush_hw_mask = 0xf7ffffff,
649 .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
650 .caps = MDP_PIPE_CAP_HFLIP |
654 MDP_PIPE_CAP_DECIMATION |
655 MDP_PIPE_CAP_SW_PIX_EXT |
660 .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
661 .caps = MDP_PIPE_CAP_HFLIP |
664 MDP_PIPE_CAP_DECIMATION |
665 MDP_PIPE_CAP_SW_PIX_EXT |
669 .count = 2, /* driver supports max of 2 currently */
670 .base = { 0x24000, 0x26000, 0x28000, 0x2a000 },
671 .caps = MDP_PIPE_CAP_HFLIP |
673 MDP_PIPE_CAP_SW_PIX_EXT |
678 .base = { 0x34000, 0x36000 },
679 .caps = MDP_PIPE_CAP_HFLIP |
681 MDP_PIPE_CAP_SW_PIX_EXT |
682 MDP_PIPE_CAP_CURSOR |
688 .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
690 { .id = 0, .pp = 0, .dspp = 0,
691 .caps = MDP_LM_CAP_DISPLAY |
693 { .id = 1, .pp = 1, .dspp = 1,
694 .caps = MDP_LM_CAP_DISPLAY, },
695 { .id = 2, .pp = 2, .dspp = -1,
696 .caps = MDP_LM_CAP_DISPLAY |
698 { .id = 3, .pp = -1, .dspp = -1,
699 .caps = MDP_LM_CAP_WB, },
700 { .id = 4, .pp = -1, .dspp = -1,
701 .caps = MDP_LM_CAP_WB, },
702 { .id = 5, .pp = 3, .dspp = -1,
703 .caps = MDP_LM_CAP_DISPLAY, },
707 .max_height = 0xFFFF,
711 .base = { 0x54000, 0x56000 },
715 .base = { 0x78000, 0x78800, 0x79000 },
719 .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
727 .base = { 0x80000, 0x80400 },
730 .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
738 .max_clk = 412500000,
741 static const struct mdp5_cfg_handler cfg_handlers_v1[] = {
742 { .revision = 0, .config = { .hw = &msm8x74v1_config } },
743 { .revision = 2, .config = { .hw = &msm8x74v2_config } },
744 { .revision = 3, .config = { .hw = &apq8084_config } },
745 { .revision = 6, .config = { .hw = &msm8x16_config } },
746 { .revision = 9, .config = { .hw = &msm8x94_config } },
747 { .revision = 7, .config = { .hw = &msm8x96_config } },
748 { .revision = 15, .config = { .hw = &msm8917_config } },
751 static const struct mdp5_cfg_handler cfg_handlers_v3[] = {
752 { .revision = 0, .config = { .hw = &msm8998_config } },
755 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
757 const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler)
759 return cfg_handler->config.hw;
762 struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler)
764 return &cfg_handler->config;
767 int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler)
769 return cfg_handler->revision;
772 void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler)
777 struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
778 uint32_t major, uint32_t minor)
780 struct drm_device *dev = mdp5_kms->dev;
781 struct platform_device *pdev = to_platform_device(dev->dev);
782 struct mdp5_cfg_handler *cfg_handler;
783 const struct mdp5_cfg_handler *cfg_handlers;
784 struct mdp5_cfg_platform *pconfig;
785 int i, ret = 0, num_handlers;
787 cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL);
788 if (unlikely(!cfg_handler)) {
795 cfg_handlers = cfg_handlers_v1;
796 num_handlers = ARRAY_SIZE(cfg_handlers_v1);
799 cfg_handlers = cfg_handlers_v3;
800 num_handlers = ARRAY_SIZE(cfg_handlers_v3);
803 DRM_DEV_ERROR(dev->dev, "unexpected MDP major version: v%d.%d\n",
809 /* only after mdp5_cfg global pointer's init can we access the hw */
810 for (i = 0; i < num_handlers; i++) {
811 if (cfg_handlers[i].revision != minor)
813 mdp5_cfg = cfg_handlers[i].config.hw;
817 if (unlikely(!mdp5_cfg)) {
818 DRM_DEV_ERROR(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
824 cfg_handler->revision = minor;
825 cfg_handler->config.hw = mdp5_cfg;
827 pconfig = mdp5_get_config(pdev);
828 memcpy(&cfg_handler->config.platform, pconfig, sizeof(*pconfig));
830 DBG("MDP5: %s hw config selected", mdp5_cfg->name);
836 mdp5_cfg_destroy(cfg_handler);
841 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev)
843 static struct mdp5_cfg_platform config = {};
845 config.iommu = iommu_domain_alloc(&platform_bus_type);
847 config.iommu->geometry.aperture_start = 0x1000;
848 config.iommu->geometry.aperture_end = 0xffffffff;