]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
HID: sony: Remove the size check for the Dualshock 4 HID Descriptor
[mirror_ubuntu-artful-kernel.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 .base = { 0x00100 },
30 },
31 .smp = {
32 .mmb_count = 22,
33 .mmb_size = 4096,
34 .clients = {
35 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4, [SSPP_VIG2] = 7,
36 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
37 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
38 },
39 },
40 .ctl = {
41 .count = 5,
42 .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
43 .flush_hw_mask = 0x0003ffff,
44 },
45 .pipe_vig = {
46 .count = 3,
47 .base = { 0x01200, 0x01600, 0x01a00 },
48 .caps = MDP_PIPE_CAP_HFLIP |
49 MDP_PIPE_CAP_VFLIP |
50 MDP_PIPE_CAP_SCALE |
51 MDP_PIPE_CAP_CSC |
52 0,
53 },
54 .pipe_rgb = {
55 .count = 3,
56 .base = { 0x01e00, 0x02200, 0x02600 },
57 .caps = MDP_PIPE_CAP_HFLIP |
58 MDP_PIPE_CAP_VFLIP |
59 MDP_PIPE_CAP_SCALE |
60 0,
61 },
62 .pipe_dma = {
63 .count = 2,
64 .base = { 0x02a00, 0x02e00 },
65 .caps = MDP_PIPE_CAP_HFLIP |
66 MDP_PIPE_CAP_VFLIP |
67 0,
68 },
69 .lm = {
70 .count = 5,
71 .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 },
72 .nb_stages = 5,
73 },
74 .dspp = {
75 .count = 3,
76 .base = { 0x04600, 0x04a00, 0x04e00 },
77 },
78 .pp = {
79 .count = 3,
80 .base = { 0x21b00, 0x21c00, 0x21d00 },
81 },
82 .intf = {
83 .base = { 0x21100, 0x21300, 0x21500, 0x21700 },
84 .connect = {
85 [0] = INTF_eDP,
86 [1] = INTF_DSI,
87 [2] = INTF_DSI,
88 [3] = INTF_HDMI,
89 },
90 },
91 .max_clk = 200000000,
92 };
93
94 const struct mdp5_cfg_hw msm8x74v2_config = {
95 .name = "msm8x74",
96 .mdp = {
97 .count = 1,
98 .base = { 0x00100 },
99 },
100 .smp = {
101 .mmb_count = 22,
102 .mmb_size = 4096,
103 .clients = {
104 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4, [SSPP_VIG2] = 7,
105 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
106 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
107 },
108 },
109 .ctl = {
110 .count = 5,
111 .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
112 .flush_hw_mask = 0x0003ffff,
113 },
114 .pipe_vig = {
115 .count = 3,
116 .base = { 0x01200, 0x01600, 0x01a00 },
117 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
118 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
119 MDP_PIPE_CAP_DECIMATION,
120 },
121 .pipe_rgb = {
122 .count = 3,
123 .base = { 0x01e00, 0x02200, 0x02600 },
124 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
125 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
126 },
127 .pipe_dma = {
128 .count = 2,
129 .base = { 0x02a00, 0x02e00 },
130 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
131 },
132 .lm = {
133 .count = 5,
134 .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 },
135 .nb_stages = 5,
136 .max_width = 2048,
137 .max_height = 0xFFFF,
138 },
139 .dspp = {
140 .count = 3,
141 .base = { 0x04600, 0x04a00, 0x04e00 },
142 },
143 .ad = {
144 .count = 2,
145 .base = { 0x13100, 0x13300 },
146 },
147 .pp = {
148 .count = 3,
149 .base = { 0x12d00, 0x12e00, 0x12f00 },
150 },
151 .intf = {
152 .base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
153 .connect = {
154 [0] = INTF_eDP,
155 [1] = INTF_DSI,
156 [2] = INTF_DSI,
157 [3] = INTF_HDMI,
158 },
159 },
160 .max_clk = 200000000,
161 };
162
163 const struct mdp5_cfg_hw apq8084_config = {
164 .name = "apq8084",
165 .mdp = {
166 .count = 1,
167 .base = { 0x00100 },
168 },
169 .smp = {
170 .mmb_count = 44,
171 .mmb_size = 8192,
172 .clients = {
173 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4,
174 [SSPP_VIG2] = 7, [SSPP_VIG3] = 19,
175 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
176 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
177 [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
178 },
179 .reserved_state[0] = GENMASK(7, 0), /* first 8 MMBs */
180 .reserved = {
181 /* Two SMP blocks are statically tied to RGB pipes: */
182 [16] = 2, [17] = 2, [18] = 2, [22] = 2,
183 },
184 },
185 .ctl = {
186 .count = 5,
187 .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
188 .flush_hw_mask = 0x003fffff,
189 },
190 .pipe_vig = {
191 .count = 4,
192 .base = { 0x01200, 0x01600, 0x01a00, 0x01e00 },
193 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
194 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
195 MDP_PIPE_CAP_DECIMATION,
196 },
197 .pipe_rgb = {
198 .count = 4,
199 .base = { 0x02200, 0x02600, 0x02a00, 0x02e00 },
200 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
201 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
202 },
203 .pipe_dma = {
204 .count = 2,
205 .base = { 0x03200, 0x03600 },
206 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
207 },
208 .lm = {
209 .count = 6,
210 .base = { 0x03a00, 0x03e00, 0x04200, 0x04600, 0x04a00, 0x04e00 },
211 .nb_stages = 5,
212 .max_width = 2048,
213 .max_height = 0xFFFF,
214 },
215 .dspp = {
216 .count = 4,
217 .base = { 0x05200, 0x05600, 0x05a00, 0x05e00 },
218
219 },
220 .ad = {
221 .count = 3,
222 .base = { 0x13500, 0x13700, 0x13900 },
223 },
224 .pp = {
225 .count = 4,
226 .base = { 0x12f00, 0x13000, 0x13100, 0x13200 },
227 },
228 .intf = {
229 .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
230 .connect = {
231 [0] = INTF_eDP,
232 [1] = INTF_DSI,
233 [2] = INTF_DSI,
234 [3] = INTF_HDMI,
235 },
236 },
237 .max_clk = 320000000,
238 };
239
240 const struct mdp5_cfg_hw msm8x16_config = {
241 .name = "msm8x16",
242 .mdp = {
243 .count = 1,
244 .base = { 0x01000 },
245 },
246 .smp = {
247 .mmb_count = 8,
248 .mmb_size = 8192,
249 .clients = {
250 [SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
251 [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
252 },
253 },
254 .ctl = {
255 .count = 5,
256 .base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
257 .flush_hw_mask = 0x4003ffff,
258 },
259 .pipe_vig = {
260 .count = 1,
261 .base = { 0x05000 },
262 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
263 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
264 MDP_PIPE_CAP_DECIMATION,
265 },
266 .pipe_rgb = {
267 .count = 2,
268 .base = { 0x15000, 0x17000 },
269 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
270 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
271 },
272 .pipe_dma = {
273 .count = 1,
274 .base = { 0x25000 },
275 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
276 },
277 .lm = {
278 .count = 2, /* LM0 and LM3 */
279 .base = { 0x45000, 0x48000 },
280 .nb_stages = 5,
281 .max_width = 2048,
282 .max_height = 0xFFFF,
283 },
284 .dspp = {
285 .count = 1,
286 .base = { 0x55000 },
287
288 },
289 .intf = {
290 .base = { 0x00000, 0x6b800 },
291 .connect = {
292 [0] = INTF_DISABLED,
293 [1] = INTF_DSI,
294 },
295 },
296 .max_clk = 320000000,
297 };
298
299 const struct mdp5_cfg_hw msm8x94_config = {
300 .name = "msm8x94",
301 .mdp = {
302 .count = 1,
303 .base = { 0x01000 },
304 },
305 .smp = {
306 .mmb_count = 44,
307 .mmb_size = 8192,
308 .clients = {
309 [SSPP_VIG0] = 1, [SSPP_VIG1] = 4,
310 [SSPP_VIG2] = 7, [SSPP_VIG3] = 19,
311 [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
312 [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
313 [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
314 },
315 .reserved_state[0] = GENMASK(23, 0), /* first 24 MMBs */
316 .reserved = {
317 [1] = 1, [4] = 1, [7] = 1, [19] = 1,
318 [16] = 5, [17] = 5, [18] = 5, [22] = 5,
319 },
320 },
321 .ctl = {
322 .count = 5,
323 .base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
324 .flush_hw_mask = 0xf0ffffff,
325 },
326 .pipe_vig = {
327 .count = 4,
328 .base = { 0x05000, 0x07000, 0x09000, 0x0b000 },
329 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
330 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
331 MDP_PIPE_CAP_DECIMATION,
332 },
333 .pipe_rgb = {
334 .count = 4,
335 .base = { 0x15000, 0x17000, 0x19000, 0x1b000 },
336 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
337 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
338 },
339 .pipe_dma = {
340 .count = 2,
341 .base = { 0x25000, 0x27000 },
342 .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
343 },
344 .lm = {
345 .count = 6,
346 .base = { 0x45000, 0x46000, 0x47000, 0x48000, 0x49000, 0x4a000 },
347 .nb_stages = 8,
348 .max_width = 2048,
349 .max_height = 0xFFFF,
350 },
351 .dspp = {
352 .count = 4,
353 .base = { 0x55000, 0x57000, 0x59000, 0x5b000 },
354
355 },
356 .ad = {
357 .count = 3,
358 .base = { 0x79000, 0x79800, 0x7a000 },
359 },
360 .pp = {
361 .count = 4,
362 .base = { 0x71000, 0x71800, 0x72000, 0x72800 },
363 },
364 .intf = {
365 .base = { 0x6b000, 0x6b800, 0x6c000, 0x6c800, 0x6d000 },
366 .connect = {
367 [0] = INTF_DISABLED,
368 [1] = INTF_DSI,
369 [2] = INTF_DSI,
370 [3] = INTF_HDMI,
371 },
372 },
373 .max_clk = 320000000,
374 };
375
376 static const struct mdp5_cfg_handler cfg_handlers[] = {
377 { .revision = 0, .config = { .hw = &msm8x74v1_config } },
378 { .revision = 2, .config = { .hw = &msm8x74v2_config } },
379 { .revision = 3, .config = { .hw = &apq8084_config } },
380 { .revision = 6, .config = { .hw = &msm8x16_config } },
381 { .revision = 9, .config = { .hw = &msm8x94_config } },
382 };
383
384 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
385
386 const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler)
387 {
388 return cfg_handler->config.hw;
389 }
390
391 struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler)
392 {
393 return &cfg_handler->config;
394 }
395
396 int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler)
397 {
398 return cfg_handler->revision;
399 }
400
401 void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler)
402 {
403 kfree(cfg_handler);
404 }
405
406 struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
407 uint32_t major, uint32_t minor)
408 {
409 struct drm_device *dev = mdp5_kms->dev;
410 struct platform_device *pdev = dev->platformdev;
411 struct mdp5_cfg_handler *cfg_handler;
412 struct mdp5_cfg_platform *pconfig;
413 int i, ret = 0;
414
415 cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL);
416 if (unlikely(!cfg_handler)) {
417 ret = -ENOMEM;
418 goto fail;
419 }
420
421 if (major != 1) {
422 dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n",
423 major, minor);
424 ret = -ENXIO;
425 goto fail;
426 }
427
428 /* only after mdp5_cfg global pointer's init can we access the hw */
429 for (i = 0; i < ARRAY_SIZE(cfg_handlers); i++) {
430 if (cfg_handlers[i].revision != minor)
431 continue;
432 mdp5_cfg = cfg_handlers[i].config.hw;
433
434 break;
435 }
436 if (unlikely(!mdp5_cfg)) {
437 dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
438 major, minor);
439 ret = -ENXIO;
440 goto fail;
441 }
442
443 cfg_handler->revision = minor;
444 cfg_handler->config.hw = mdp5_cfg;
445
446 pconfig = mdp5_get_config(pdev);
447 memcpy(&cfg_handler->config.platform, pconfig, sizeof(*pconfig));
448
449 DBG("MDP5: %s hw config selected", mdp5_cfg->name);
450
451 return cfg_handler;
452
453 fail:
454 if (cfg_handler)
455 mdp5_cfg_destroy(cfg_handler);
456
457 return NULL;
458 }
459
460 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev)
461 {
462 static struct mdp5_cfg_platform config = {};
463 #ifdef CONFIG_OF
464 /* TODO */
465 #endif
466 config.iommu = iommu_domain_alloc(&platform_bus_type);
467
468 return &config;
469 }