GNU Linux-libre 4.9.309-gnu1
[releases.git] / drivers / gpu / drm / msm / mdp / mdp5 / mdp5_cfg.c
1 /*
2  * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 and
6  * only version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include "mdp5_kms.h"
15 #include "mdp5_cfg.h"
16
17 struct mdp5_cfg_handler {
18         int revision;
19         struct mdp5_cfg config;
20 };
21
22 /* mdp5_cfg must be exposed (used in mdp5.xml.h) */
23 const struct mdp5_cfg_hw *mdp5_cfg = NULL;
24
25 const struct mdp5_cfg_hw msm8x74v1_config = {
26         .name = "msm8x74v1",
27         .mdp = {
28                 .count = 1,
29                 .caps = MDP_CAP_SMP |
30                         0,
31         },
32         .smp = {
33                 .mmb_count = 22,
34                 .mmb_size = 4096,
35                 .clients = {
36                         [SSPP_VIG0] =  1, [SSPP_VIG1] =  4, [SSPP_VIG2] =  7,
37                         [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
38                         [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
39                 },
40         },
41         .ctl = {
42                 .count = 5,
43                 .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
44                 .flush_hw_mask = 0x0003ffff,
45         },
46         .pipe_vig = {
47                 .count = 3,
48                 .base = { 0x01100, 0x01500, 0x01900 },
49                 .caps = MDP_PIPE_CAP_HFLIP |
50                         MDP_PIPE_CAP_VFLIP |
51                         MDP_PIPE_CAP_SCALE |
52                         MDP_PIPE_CAP_CSC   |
53                         0,
54         },
55         .pipe_rgb = {
56                 .count = 3,
57                 .base = { 0x01d00, 0x02100, 0x02500 },
58                 .caps = MDP_PIPE_CAP_HFLIP |
59                         MDP_PIPE_CAP_VFLIP |
60                         MDP_PIPE_CAP_SCALE |
61                         0,
62         },
63         .pipe_dma = {
64                 .count = 2,
65                 .base = { 0x02900, 0x02d00 },
66                 .caps = MDP_PIPE_CAP_HFLIP |
67                         MDP_PIPE_CAP_VFLIP |
68                         0,
69         },
70         .lm = {
71                 .count = 5,
72                 .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
73                 .nb_stages = 5,
74         },
75         .dspp = {
76                 .count = 3,
77                 .base = { 0x04500, 0x04900, 0x04d00 },
78         },
79         .pp = {
80                 .count = 3,
81                 .base = { 0x21a00, 0x21b00, 0x21c00 },
82         },
83         .intf = {
84                 .base = { 0x21000, 0x21200, 0x21400, 0x21600 },
85                 .connect = {
86                         [0] = INTF_eDP,
87                         [1] = INTF_DSI,
88                         [2] = INTF_DSI,
89                         [3] = INTF_HDMI,
90                 },
91         },
92         .max_clk = 200000000,
93 };
94
95 const struct mdp5_cfg_hw msm8x74v2_config = {
96         .name = "msm8x74",
97         .mdp = {
98                 .count = 1,
99                 .caps = MDP_CAP_SMP |
100                         0,
101         },
102         .smp = {
103                 .mmb_count = 22,
104                 .mmb_size = 4096,
105                 .clients = {
106                         [SSPP_VIG0] =  1, [SSPP_VIG1] =  4, [SSPP_VIG2] =  7,
107                         [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
108                         [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
109                 },
110         },
111         .ctl = {
112                 .count = 5,
113                 .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
114                 .flush_hw_mask = 0x0003ffff,
115         },
116         .pipe_vig = {
117                 .count = 3,
118                 .base = { 0x01100, 0x01500, 0x01900 },
119                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
120                                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
121                                 MDP_PIPE_CAP_DECIMATION,
122         },
123         .pipe_rgb = {
124                 .count = 3,
125                 .base = { 0x01d00, 0x02100, 0x02500 },
126                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
127                                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
128         },
129         .pipe_dma = {
130                 .count = 2,
131                 .base = { 0x02900, 0x02d00 },
132                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
133         },
134         .lm = {
135                 .count = 5,
136                 .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
137                 .nb_stages = 5,
138                 .max_width = 2048,
139                 .max_height = 0xFFFF,
140         },
141         .dspp = {
142                 .count = 3,
143                 .base = { 0x04500, 0x04900, 0x04d00 },
144         },
145         .ad = {
146                 .count = 2,
147                 .base = { 0x13000, 0x13200 },
148         },
149         .pp = {
150                 .count = 3,
151                 .base = { 0x12c00, 0x12d00, 0x12e00 },
152         },
153         .intf = {
154                 .base = { 0x12400, 0x12600, 0x12800, 0x12a00 },
155                 .connect = {
156                         [0] = INTF_eDP,
157                         [1] = INTF_DSI,
158                         [2] = INTF_DSI,
159                         [3] = INTF_HDMI,
160                 },
161         },
162         .max_clk = 200000000,
163 };
164
165 const struct mdp5_cfg_hw apq8084_config = {
166         .name = "apq8084",
167         .mdp = {
168                 .count = 1,
169                 .caps = MDP_CAP_SMP |
170                         0,
171         },
172         .smp = {
173                 .mmb_count = 44,
174                 .mmb_size = 8192,
175                 .clients = {
176                         [SSPP_VIG0] =  1, [SSPP_VIG1] =  4,
177                         [SSPP_VIG2] =  7, [SSPP_VIG3] = 19,
178                         [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
179                         [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
180                         [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
181                 },
182                 .reserved_state[0] = GENMASK(7, 0),     /* first 8 MMBs */
183                 .reserved = {
184                         /* Two SMP blocks are statically tied to RGB pipes: */
185                         [16] = 2, [17] = 2, [18] = 2, [22] = 2,
186                 },
187         },
188         .ctl = {
189                 .count = 5,
190                 .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
191                 .flush_hw_mask = 0x003fffff,
192         },
193         .pipe_vig = {
194                 .count = 4,
195                 .base = { 0x01100, 0x01500, 0x01900, 0x01d00 },
196                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
197                                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
198                                 MDP_PIPE_CAP_DECIMATION,
199         },
200         .pipe_rgb = {
201                 .count = 4,
202                 .base = { 0x02100, 0x02500, 0x02900, 0x02d00 },
203                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
204                                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
205         },
206         .pipe_dma = {
207                 .count = 2,
208                 .base = { 0x03100, 0x03500 },
209                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
210         },
211         .lm = {
212                 .count = 6,
213                 .base = { 0x03900, 0x03d00, 0x04100, 0x04500, 0x04900, 0x04d00 },
214                 .nb_stages = 5,
215                 .max_width = 2048,
216                 .max_height = 0xFFFF,
217         },
218         .dspp = {
219                 .count = 4,
220                 .base = { 0x05100, 0x05500, 0x05900, 0x05d00 },
221
222         },
223         .ad = {
224                 .count = 3,
225                 .base = { 0x13400, 0x13600, 0x13800 },
226         },
227         .pp = {
228                 .count = 4,
229                 .base = { 0x12e00, 0x12f00, 0x13000, 0x13100 },
230         },
231         .intf = {
232                 .base = { 0x12400, 0x12600, 0x12800, 0x12a00, 0x12c00 },
233                 .connect = {
234                         [0] = INTF_eDP,
235                         [1] = INTF_DSI,
236                         [2] = INTF_DSI,
237                         [3] = INTF_HDMI,
238                 },
239         },
240         .max_clk = 320000000,
241 };
242
243 const struct mdp5_cfg_hw msm8x16_config = {
244         .name = "msm8x16",
245         .mdp = {
246                 .count = 1,
247                 .base = { 0x0 },
248                 .caps = MDP_CAP_SMP |
249                         0,
250         },
251         .smp = {
252                 .mmb_count = 8,
253                 .mmb_size = 8192,
254                 .clients = {
255                         [SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
256                         [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
257                 },
258         },
259         .ctl = {
260                 .count = 5,
261                 .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
262                 .flush_hw_mask = 0x4003ffff,
263         },
264         .pipe_vig = {
265                 .count = 1,
266                 .base = { 0x04000 },
267                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
268                                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
269                                 MDP_PIPE_CAP_DECIMATION,
270         },
271         .pipe_rgb = {
272                 .count = 2,
273                 .base = { 0x14000, 0x16000 },
274                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
275                                 MDP_PIPE_CAP_DECIMATION,
276         },
277         .pipe_dma = {
278                 .count = 1,
279                 .base = { 0x24000 },
280                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
281         },
282         .lm = {
283                 .count = 2, /* LM0 and LM3 */
284                 .base = { 0x44000, 0x47000 },
285                 .nb_stages = 8,
286                 .max_width = 2048,
287                 .max_height = 0xFFFF,
288         },
289         .dspp = {
290                 .count = 1,
291                 .base = { 0x54000 },
292
293         },
294         .intf = {
295                 .base = { 0x00000, 0x6a800 },
296                 .connect = {
297                         [0] = INTF_DISABLED,
298                         [1] = INTF_DSI,
299                 },
300         },
301         .max_clk = 320000000,
302 };
303
304 const struct mdp5_cfg_hw msm8x94_config = {
305         .name = "msm8x94",
306         .mdp = {
307                 .count = 1,
308                 .caps = MDP_CAP_SMP |
309                         0,
310         },
311         .smp = {
312                 .mmb_count = 44,
313                 .mmb_size = 8192,
314                 .clients = {
315                         [SSPP_VIG0] =  1, [SSPP_VIG1] =  4,
316                         [SSPP_VIG2] =  7, [SSPP_VIG3] = 19,
317                         [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
318                         [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
319                         [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
320                 },
321                 .reserved_state[0] = GENMASK(23, 0),    /* first 24 MMBs */
322                 .reserved = {
323                          [1] = 1,  [4] = 1,  [7] = 1, [19] = 1,
324                         [16] = 5, [17] = 5, [18] = 5, [22] = 5,
325                 },
326         },
327         .ctl = {
328                 .count = 5,
329                 .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
330                 .flush_hw_mask = 0xf0ffffff,
331         },
332         .pipe_vig = {
333                 .count = 4,
334                 .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
335                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
336                                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
337                                 MDP_PIPE_CAP_DECIMATION,
338         },
339         .pipe_rgb = {
340                 .count = 4,
341                 .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
342                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
343                                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
344         },
345         .pipe_dma = {
346                 .count = 2,
347                 .base = { 0x24000, 0x26000 },
348                 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
349         },
350         .lm = {
351                 .count = 6,
352                 .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
353                 .nb_stages = 8,
354                 .max_width = 2048,
355                 .max_height = 0xFFFF,
356         },
357         .dspp = {
358                 .count = 4,
359                 .base = { 0x54000, 0x56000, 0x58000, 0x5a000 },
360
361         },
362         .ad = {
363                 .count = 3,
364                 .base = { 0x78000, 0x78800, 0x79000 },
365         },
366         .pp = {
367                 .count = 4,
368                 .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
369         },
370         .intf = {
371                 .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
372                 .connect = {
373                         [0] = INTF_DISABLED,
374                         [1] = INTF_DSI,
375                         [2] = INTF_DSI,
376                         [3] = INTF_HDMI,
377                 },
378         },
379         .max_clk = 400000000,
380 };
381
382 const struct mdp5_cfg_hw msm8x96_config = {
383         .name = "msm8x96",
384         .mdp = {
385                 .count = 1,
386                 .caps = MDP_CAP_DSC |
387                         MDP_CAP_CDM |
388                         0,
389         },
390         .ctl = {
391                 .count = 5,
392                 .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
393                 .flush_hw_mask = 0xf4ffffff,
394         },
395         .pipe_vig = {
396                 .count = 4,
397                 .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
398                 .caps = MDP_PIPE_CAP_HFLIP      |
399                         MDP_PIPE_CAP_VFLIP      |
400                         MDP_PIPE_CAP_SCALE      |
401                         MDP_PIPE_CAP_CSC        |
402                         MDP_PIPE_CAP_DECIMATION |
403                         MDP_PIPE_CAP_SW_PIX_EXT |
404                         0,
405         },
406         .pipe_rgb = {
407                 .count = 4,
408                 .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
409                 .caps = MDP_PIPE_CAP_HFLIP      |
410                         MDP_PIPE_CAP_VFLIP      |
411                         MDP_PIPE_CAP_SCALE      |
412                         MDP_PIPE_CAP_DECIMATION |
413                         MDP_PIPE_CAP_SW_PIX_EXT |
414                         0,
415         },
416         .pipe_dma = {
417                 .count = 2,
418                 .base = { 0x24000, 0x26000 },
419                 .caps = MDP_PIPE_CAP_HFLIP      |
420                         MDP_PIPE_CAP_VFLIP      |
421                         MDP_PIPE_CAP_SW_PIX_EXT |
422                         0,
423         },
424         .lm = {
425                 .count = 6,
426                 .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
427                 .nb_stages = 8,
428                 .max_width = 2560,
429                 .max_height = 0xFFFF,
430         },
431         .dspp = {
432                 .count = 2,
433                 .base = { 0x54000, 0x56000 },
434         },
435         .ad = {
436                 .count = 3,
437                 .base = { 0x78000, 0x78800, 0x79000 },
438         },
439         .pp = {
440                 .count = 4,
441                 .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
442         },
443         .cdm = {
444                 .count = 1,
445                 .base = { 0x79200 },
446         },
447         .dsc = {
448                 .count = 2,
449                 .base = { 0x80000, 0x80400 },
450         },
451         .intf = {
452                 .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
453                 .connect = {
454                         [0] = INTF_DISABLED,
455                         [1] = INTF_DSI,
456                         [2] = INTF_DSI,
457                         [3] = INTF_HDMI,
458                 },
459         },
460         .max_clk = 412500000,
461 };
462
463 static const struct mdp5_cfg_handler cfg_handlers[] = {
464         { .revision = 0, .config = { .hw = &msm8x74v1_config } },
465         { .revision = 2, .config = { .hw = &msm8x74v2_config } },
466         { .revision = 3, .config = { .hw = &apq8084_config } },
467         { .revision = 6, .config = { .hw = &msm8x16_config } },
468         { .revision = 9, .config = { .hw = &msm8x94_config } },
469         { .revision = 7, .config = { .hw = &msm8x96_config } },
470 };
471
472 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
473
474 const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler)
475 {
476         return cfg_handler->config.hw;
477 }
478
479 struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler)
480 {
481         return &cfg_handler->config;
482 }
483
484 int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler)
485 {
486         return cfg_handler->revision;
487 }
488
489 void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler)
490 {
491         kfree(cfg_handler);
492 }
493
494 struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
495                 uint32_t major, uint32_t minor)
496 {
497         struct drm_device *dev = mdp5_kms->dev;
498         struct platform_device *pdev = dev->platformdev;
499         struct mdp5_cfg_handler *cfg_handler;
500         struct mdp5_cfg_platform *pconfig;
501         int i, ret = 0;
502
503         cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL);
504         if (unlikely(!cfg_handler)) {
505                 ret = -ENOMEM;
506                 goto fail;
507         }
508
509         if (major != 1) {
510                 dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n",
511                                 major, minor);
512                 ret = -ENXIO;
513                 goto fail;
514         }
515
516         /* only after mdp5_cfg global pointer's init can we access the hw */
517         for (i = 0; i < ARRAY_SIZE(cfg_handlers); i++) {
518                 if (cfg_handlers[i].revision != minor)
519                         continue;
520                 mdp5_cfg = cfg_handlers[i].config.hw;
521
522                 break;
523         }
524         if (unlikely(!mdp5_cfg)) {
525                 dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
526                                 major, minor);
527                 ret = -ENXIO;
528                 goto fail;
529         }
530
531         cfg_handler->revision = minor;
532         cfg_handler->config.hw = mdp5_cfg;
533
534         pconfig = mdp5_get_config(pdev);
535         memcpy(&cfg_handler->config.platform, pconfig, sizeof(*pconfig));
536
537         DBG("MDP5: %s hw config selected", mdp5_cfg->name);
538
539         return cfg_handler;
540
541 fail:
542         if (cfg_handler)
543                 mdp5_cfg_destroy(cfg_handler);
544
545         return ERR_PTR(ret);
546 }
547
548 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev)
549 {
550         static struct mdp5_cfg_platform config = {};
551
552         config.iommu = iommu_domain_alloc(&platform_bus_type);
553
554         return &config;
555 }