]>
Commit | Line | Data |
---|---|---|
2e362e17 | 1 | /* |
02dfd9d2 | 2 | * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. |
2e362e17 SV |
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 | ||
8a94b0aa | 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 = { | |
2e362e17 | 95 | .name = "msm8x74", |
f5253812 SV |
96 | .mdp = { |
97 | .count = 1, | |
98 | .base = { 0x00100 }, | |
99 | }, | |
2e362e17 SV |
100 | .smp = { |
101 | .mmb_count = 22, | |
102 | .mmb_size = 4096, | |
6fa6acdf SV |
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 | }, | |
2e362e17 SV |
108 | }, |
109 | .ctl = { | |
110 | .count = 5, | |
111 | .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, | |
389b09a1 | 112 | .flush_hw_mask = 0x0003ffff, |
2e362e17 SV |
113 | }, |
114 | .pipe_vig = { | |
115 | .count = 3, | |
116 | .base = { 0x01200, 0x01600, 0x01a00 }, | |
3498409f | 117 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
118 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC | | |
119 | MDP_PIPE_CAP_DECIMATION, | |
2e362e17 SV |
120 | }, |
121 | .pipe_rgb = { | |
122 | .count = 3, | |
123 | .base = { 0x01e00, 0x02200, 0x02600 }, | |
3498409f | 124 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
125 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION, | |
2e362e17 SV |
126 | }, |
127 | .pipe_dma = { | |
128 | .count = 2, | |
129 | .base = { 0x02a00, 0x02e00 }, | |
3498409f | 130 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP, |
2e362e17 SV |
131 | }, |
132 | .lm = { | |
133 | .count = 5, | |
134 | .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 }, | |
135 | .nb_stages = 5, | |
9b7a9fc2 HL |
136 | .max_width = 2048, |
137 | .max_height = 0xFFFF, | |
2e362e17 SV |
138 | }, |
139 | .dspp = { | |
140 | .count = 3, | |
141 | .base = { 0x04600, 0x04a00, 0x04e00 }, | |
142 | }, | |
143 | .ad = { | |
144 | .count = 2, | |
8a94b0aa | 145 | .base = { 0x13100, 0x13300 }, |
2e362e17 | 146 | }, |
38305907 HL |
147 | .pp = { |
148 | .count = 3, | |
149 | .base = { 0x12d00, 0x12e00, 0x12f00 }, | |
150 | }, | |
2e362e17 | 151 | .intf = { |
2e362e17 | 152 | .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, |
fe34464d SV |
153 | .connect = { |
154 | [0] = INTF_eDP, | |
155 | [1] = INTF_DSI, | |
156 | [2] = INTF_DSI, | |
157 | [3] = INTF_HDMI, | |
158 | }, | |
67ac0a2d | 159 | }, |
2e362e17 SV |
160 | .max_clk = 200000000, |
161 | }; | |
162 | ||
163 | const struct mdp5_cfg_hw apq8084_config = { | |
164 | .name = "apq8084", | |
f5253812 SV |
165 | .mdp = { |
166 | .count = 1, | |
167 | .base = { 0x00100 }, | |
168 | }, | |
2e362e17 SV |
169 | .smp = { |
170 | .mmb_count = 44, | |
171 | .mmb_size = 8192, | |
6fa6acdf SV |
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 | }, | |
2e362e17 | 179 | .reserved_state[0] = GENMASK(7, 0), /* first 8 MMBs */ |
6fa6acdf SV |
180 | .reserved = { |
181 | /* Two SMP blocks are statically tied to RGB pipes: */ | |
182 | [16] = 2, [17] = 2, [18] = 2, [22] = 2, | |
183 | }, | |
2e362e17 SV |
184 | }, |
185 | .ctl = { | |
186 | .count = 5, | |
187 | .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, | |
389b09a1 | 188 | .flush_hw_mask = 0x003fffff, |
2e362e17 SV |
189 | }, |
190 | .pipe_vig = { | |
191 | .count = 4, | |
192 | .base = { 0x01200, 0x01600, 0x01a00, 0x01e00 }, | |
3498409f | 193 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
194 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC | | |
195 | MDP_PIPE_CAP_DECIMATION, | |
2e362e17 SV |
196 | }, |
197 | .pipe_rgb = { | |
198 | .count = 4, | |
199 | .base = { 0x02200, 0x02600, 0x02a00, 0x02e00 }, | |
3498409f | 200 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
201 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION, | |
2e362e17 SV |
202 | }, |
203 | .pipe_dma = { | |
204 | .count = 2, | |
205 | .base = { 0x03200, 0x03600 }, | |
3498409f | 206 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP, |
2e362e17 SV |
207 | }, |
208 | .lm = { | |
209 | .count = 6, | |
210 | .base = { 0x03a00, 0x03e00, 0x04200, 0x04600, 0x04a00, 0x04e00 }, | |
211 | .nb_stages = 5, | |
9b7a9fc2 HL |
212 | .max_width = 2048, |
213 | .max_height = 0xFFFF, | |
2e362e17 SV |
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 | }, | |
38305907 HL |
224 | .pp = { |
225 | .count = 4, | |
226 | .base = { 0x12f00, 0x13000, 0x13100, 0x13200 }, | |
227 | }, | |
2e362e17 | 228 | .intf = { |
2e362e17 | 229 | .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, |
fe34464d SV |
230 | .connect = { |
231 | [0] = INTF_eDP, | |
232 | [1] = INTF_DSI, | |
233 | [2] = INTF_DSI, | |
234 | [3] = INTF_HDMI, | |
235 | }, | |
67ac0a2d | 236 | }, |
2e362e17 SV |
237 | .max_clk = 320000000, |
238 | }; | |
239 | ||
02dfd9d2 SV |
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 }, | |
3498409f | 262 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
263 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC | | |
264 | MDP_PIPE_CAP_DECIMATION, | |
02dfd9d2 SV |
265 | }, |
266 | .pipe_rgb = { | |
267 | .count = 2, | |
268 | .base = { 0x15000, 0x17000 }, | |
3498409f | 269 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
270 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION, | |
02dfd9d2 SV |
271 | }, |
272 | .pipe_dma = { | |
273 | .count = 1, | |
274 | .base = { 0x25000 }, | |
3498409f | 275 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP, |
02dfd9d2 SV |
276 | }, |
277 | .lm = { | |
278 | .count = 2, /* LM0 and LM3 */ | |
279 | .base = { 0x45000, 0x48000 }, | |
280 | .nb_stages = 5, | |
9b7a9fc2 HL |
281 | .max_width = 2048, |
282 | .max_height = 0xFFFF, | |
02dfd9d2 SV |
283 | }, |
284 | .dspp = { | |
285 | .count = 1, | |
286 | .base = { 0x55000 }, | |
287 | ||
288 | }, | |
289 | .intf = { | |
fe34464d SV |
290 | .base = { 0x00000, 0x6b800 }, |
291 | .connect = { | |
292 | [0] = INTF_DISABLED, | |
293 | [1] = INTF_DSI, | |
294 | }, | |
02dfd9d2 | 295 | }, |
02dfd9d2 SV |
296 | .max_clk = 320000000, |
297 | }; | |
298 | ||
3a84f846 SV |
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 }, | |
3498409f | 329 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
330 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC | | |
331 | MDP_PIPE_CAP_DECIMATION, | |
3a84f846 SV |
332 | }, |
333 | .pipe_rgb = { | |
334 | .count = 4, | |
335 | .base = { 0x15000, 0x17000, 0x19000, 0x1b000 }, | |
3498409f | 336 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
337 | MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION, | |
3a84f846 SV |
338 | }, |
339 | .pipe_dma = { | |
340 | .count = 2, | |
341 | .base = { 0x25000, 0x27000 }, | |
3498409f | 342 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP, |
3a84f846 SV |
343 | }, |
344 | .lm = { | |
345 | .count = 6, | |
346 | .base = { 0x45000, 0x46000, 0x47000, 0x48000, 0x49000, 0x4a000 }, | |
347 | .nb_stages = 8, | |
9b7a9fc2 HL |
348 | .max_width = 2048, |
349 | .max_height = 0xFFFF, | |
3a84f846 SV |
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 | ||
2e362e17 | 376 | static const struct mdp5_cfg_handler cfg_handlers[] = { |
8a94b0aa | 377 | { .revision = 0, .config = { .hw = &msm8x74v1_config } }, |
378 | { .revision = 2, .config = { .hw = &msm8x74v2_config } }, | |
2e362e17 | 379 | { .revision = 3, .config = { .hw = &apq8084_config } }, |
02dfd9d2 | 380 | { .revision = 6, .config = { .hw = &msm8x16_config } }, |
3a84f846 | 381 | { .revision = 9, .config = { .hw = &msm8x94_config } }, |
2e362e17 SV |
382 | }; |
383 | ||
2e362e17 SV |
384 | static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev); |
385 | ||
42238da8 | 386 | const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler) |
2e362e17 | 387 | { |
2e362e17 SV |
388 | return cfg_handler->config.hw; |
389 | } | |
390 | ||
42238da8 | 391 | struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler) |
2e362e17 | 392 | { |
2e362e17 SV |
393 | return &cfg_handler->config; |
394 | } | |
395 | ||
42238da8 | 396 | int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler) |
2e362e17 | 397 | { |
2e362e17 SV |
398 | return cfg_handler->revision; |
399 | } | |
400 | ||
42238da8 | 401 | void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler) |
2e362e17 | 402 | { |
2e362e17 SV |
403 | kfree(cfg_handler); |
404 | } | |
405 | ||
42238da8 | 406 | struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, |
2e362e17 SV |
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 | } |