1 /*
2 * Allwinner SoCs display driver.
3 *
4 * Copyright (c) 2007-2017 Allwinnertech Co., Ltd.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17 #include "disp_rtwb.h"
18
19 #if defined(SUPPORT_RTWB)
20
21 struct disp_device_private_data {
22 u32 enabled;
23 bool suspended;
24
25 enum disp_tv_mode tv_mode;
26 struct disp_device_config config;
27
28 struct disp_irq_info irq_info;
29 struct disp_rtwb_timings *video_info;
30 wait_queue_head_t wait_wb_finish_queue;
31 atomic_t wati_wb_finish_flag;
32 struct clk *clk;
33 struct clk *clk_bus;
34 struct reset_control *rst;
35
36 };
37
38 struct disp_rtwb_timings {
39 unsigned int tv_mode; /* video information code */
40 unsigned int pixel_repeat; /* pixel repeat (pixel_repeat+1) times */
41 unsigned int x_res;
42 unsigned int y_res;
43 bool b_interlace;
44 unsigned int trd_mode;
45 unsigned int fps;
46 };
47
48 static struct disp_rtwb_timings video_timing[] = {
49 {
50 .tv_mode = DISP_TV_MOD_720P_60HZ,
51 .pixel_repeat = 0,
52 .x_res = 1280,
53 .y_res = 720,
54 .b_interlace = 0,
55 .trd_mode = 0,
56 .fps = 60,
57 },
58 {
59 .tv_mode = DISP_TV_MOD_720P_50HZ,
60 .pixel_repeat = 0,
61 .x_res = 1280,
62 .y_res = 720,
63 .b_interlace = 0,
64 .trd_mode = 0,
65 .fps = 50,
66 },
67 {
68 .tv_mode = DISP_TV_MOD_1080I_60HZ,
69 .pixel_repeat = 0,
70 .x_res = 1920,
71 .y_res = 1080,
72 .b_interlace = 1,
73 .trd_mode = 0,
74 .fps = 60,
75 },
76 {
77 .tv_mode = DISP_TV_MOD_1080I_50HZ,
78 .pixel_repeat = 0,
79 .x_res = 1920,
80 .y_res = 1080,
81 .b_interlace = 1,
82 .trd_mode = 0,
83 .fps = 50,
84 },
85 {
86 .tv_mode = DISP_TV_MOD_1080P_60HZ,
87 .pixel_repeat = 0,
88 .x_res = 1920,
89 .y_res = 1080,
90 .b_interlace = 0,
91 .trd_mode = 0,
92 .fps = 60,
93 },
94 {
95 .tv_mode = DISP_TV_MOD_1080P_50HZ,
96 .pixel_repeat = 0,
97 .x_res = 1920,
98 .y_res = 1080,
99 .b_interlace = 0,
100 .trd_mode = 0,
101 .fps = 50,
102 },
103 {
104 .tv_mode = DISP_TV_MOD_1080P_24HZ_3D_FP,
105 .pixel_repeat = 0,
106 .x_res = 1920,
107 .y_res = 2160,
108 .b_interlace = 0,
109 .trd_mode = 1,
110 .fps = 24,
111 },
112 {
113 .tv_mode = DISP_TV_MOD_1080P_30HZ,
114 .pixel_repeat = 0,
115 .x_res = 1920,
116 .y_res = 1080,
117 .b_interlace = 0,
118 .trd_mode = 0,
119 .fps = 30,
120 },
121 {
122 .tv_mode = DISP_TV_MOD_1080P_25HZ,
123 .pixel_repeat = 0,
124 .x_res = 1920,
125 .y_res = 1080,
126 .b_interlace = 0,
127 .trd_mode = 0,
128 .fps = 25,
129 },
130 {
131 .tv_mode = DISP_TV_MOD_1080P_24HZ,
132 .pixel_repeat = 0,
133 .x_res = 1920,
134 .y_res = 1080,
135 .b_interlace = 0,
136 .trd_mode = 0,
137 .fps = 24,
138 },
139 {
140 .tv_mode = DISP_TV_MOD_720P_50HZ_3D_FP,
141 .pixel_repeat = 0,
142 .x_res = 1280,
143 .y_res = 1440,
144 .b_interlace = 0,
145 .trd_mode = 1,
146 .fps = 50,
147 },
148 {
149 .tv_mode = DISP_TV_MOD_720P_60HZ_3D_FP,
150 .pixel_repeat = 0,
151 .x_res = 1280,
152 .y_res = 1440,
153 .b_interlace = 0,
154 .trd_mode = 1,
155 .fps = 60,
156 },
157 {
158 .tv_mode = DISP_TV_MOD_3840_2160P_30HZ,
159 .pixel_repeat = 0,
160 .x_res = 3840,
161 .y_res = 2160,
162 .b_interlace = 0,
163 .trd_mode = 0,
164 .fps = 30,
165 },
166 {
167 .tv_mode = DISP_TV_MOD_3840_2160P_25HZ,
168 .pixel_repeat = 0,
169 .x_res = 3840,
170 .y_res = 2160,
171 .b_interlace = 0,
172 .trd_mode = 0,
173 .fps = 25,
174 },
175 {
176 .tv_mode = DISP_TV_MOD_3840_2160P_24HZ,
177 .pixel_repeat = 0,
178 .x_res = 3840,
179 .y_res = 2160,
180 .b_interlace = 0,
181 .trd_mode = 0,
182 .fps = 24,
183 },
184 {
185 .tv_mode = DISP_TV_MOD_4096_2160P_24HZ,
186 .pixel_repeat = 0,
187 .x_res = 4096,
188 .y_res = 2160,
189 .b_interlace = 0,
190 .trd_mode = 0,
191 .fps = 24,
192 },
193 {
194 .tv_mode = DISP_TV_MOD_4096_2160P_25HZ,
195 .pixel_repeat = 0,
196 .x_res = 4096,
197 .y_res = 2160,
198 .b_interlace = 0,
199 .trd_mode = 0,
200 .fps = 25
201 },
202 {
203 .tv_mode = DISP_TV_MOD_4096_2160P_30HZ,
204 .pixel_repeat = 0,
205 .x_res = 4096,
206 .y_res = 2160,
207 .b_interlace = 0,
208 .trd_mode = 0,
209 .fps = 30,
210 },
211 {
212 .tv_mode = DISP_TV_MOD_3840_2160P_60HZ,
213 .pixel_repeat = 0,
214 .x_res = 3840,
215 .y_res = 2160,
216 .b_interlace = 0,
217 .trd_mode = 0,
218 .fps = 60,
219 },
220 {
221 .tv_mode = DISP_TV_MOD_4096_2160P_60HZ,
222 .pixel_repeat = 0,
223 .x_res = 4096,
224 .y_res = 2160,
225 .b_interlace = 0,
226 .trd_mode = 0,
227 .fps = 60,
228 },
229 {
230 .tv_mode = DISP_TV_MOD_3840_2160P_50HZ,
231 .pixel_repeat = 0,
232 .x_res = 3840,
233 .y_res = 2160,
234 .b_interlace = 0,
235 .trd_mode = 0,
236 .fps = 50,
237 },
238 {
239 .tv_mode = DISP_TV_MOD_4096_2160P_50HZ,
240 .pixel_repeat = 0,
241 .x_res = 4096,
242 .y_res = 2160,
243 .b_interlace = 0,
244 .trd_mode = 0,
245 .fps = 50,
246 },
247 {
248 .tv_mode = DISP_TV_MOD_2560_1440P_60HZ,
249 .pixel_repeat = 0,
250 .x_res = 3840,
251 .y_res = 2160,
252 .b_interlace = 0,
253 .trd_mode = 0,
254 .fps = 60,
255 },
256 {
257 .tv_mode = DISP_TV_MOD_1440_2560P_70HZ,
258 .pixel_repeat = 0,
259 .x_res = 1440,
260 .y_res = 2560,
261 .b_interlace = 0,
262 .trd_mode = 0,
263 .fps = 70,
264 },
265 {
266 .tv_mode = DISP_TV_MOD_1080_1920P_60HZ,
267 .pixel_repeat = 0,
268 .x_res = 1080,
269 .y_res = 1920,
270 .b_interlace = 0,
271 .trd_mode = 0,
272 .fps = 60,
273 },
274 {
275 .tv_mode = DISP_TV_MOD_1280_1024P_60HZ,
276 .pixel_repeat = 0,
277 .x_res = 1280,
278 .y_res = 1024,
279 .b_interlace = 0,
280 .trd_mode = 0,
281 .fps = 60,
282 },
283 {
284 .tv_mode = DISP_TV_MOD_1024_768P_60HZ,
285 .pixel_repeat = 0,
286 .x_res = 1024,
287 .y_res = 768,
288 .b_interlace = 0,
289 .trd_mode = 0,
290 .fps = 60,
291 },
292 {
293 .tv_mode = DISP_TV_MOD_900_540P_60HZ,
294 .pixel_repeat = 0,
295 .x_res = 900,
296 .y_res = 540,
297 .b_interlace = 0,
298 .trd_mode = 0,
299 .fps = 60,
300 },
301 };
302
303 static spinlock_t g_rtwb_data_lock;
304 static struct disp_device *g_rtwb_devices;
305 static struct disp_device_private_data *g_rtwb_private;
306
disp_rtwb_get_priv(struct disp_device * p_rtwb)307 static struct disp_device_private_data *disp_rtwb_get_priv(struct disp_device
308 *p_rtwb)
309 {
310 if (p_rtwb == NULL) {
311 DE_WRN("NULL hdl!\n");
312 return NULL;
313 }
314
315 return (struct disp_device_private_data *)p_rtwb->priv_data;
316 }
317
disp_rtwb_irq_handler(u32 sel,u32 irq_flag,void * ptr)318 static s32 disp_rtwb_irq_handler(u32 sel, u32 irq_flag, void *ptr)
319 {
320 struct disp_device *p_rtwb = (struct disp_device *)ptr;
321 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
322
323 if (irq_flag & DISP_AL_CAPTURE_IRQ_FLAG_FRAME_END) {
324 if (de_wb_irq_query_and_clear(0, WB_IRQ_STATE_PROC_END |
325 WB_IRQ_STATE_FINISH)) {
326 sync_event_proc(p_rtwb->disp, true);
327 atomic_set(&p_rtwbp->wati_wb_finish_flag, 1);
328 wake_up(&p_rtwbp->wait_wb_finish_queue);
329 }
330 }
331 return DISP_IRQ_RETURN;
332 }
333
334
rtwb_get_video_timing_info(struct disp_device * p_rtwb,struct disp_video_timings * video_info)335 static s32 rtwb_get_video_timing_info(struct disp_device *p_rtwb, struct disp_video_timings *video_info)
336 {
337 struct disp_rtwb_timings *info;
338 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
339 int ret = -1;
340 int i, list_num;
341
342 if (!p_rtwb || !video_info || !p_rtwbp) {
343 DE_WRN("tv init null hdl!\n");
344 return DIS_FAIL;
345 }
346
347 info = video_timing;
348 list_num = sizeof(video_timing)/sizeof(struct disp_rtwb_timings);
349 for (i = 0; i < list_num; i++) {
350 if (info->tv_mode == p_rtwbp->tv_mode) {
351 video_info->tv_mode = info->tv_mode;
352 video_info->pixel_repeat = info->pixel_repeat;
353 video_info->x_res = info->x_res;
354 video_info->y_res = info->y_res;
355 video_info->b_interlace = info->b_interlace;
356 video_info->trd_mode = info->trd_mode;
357 p_rtwbp->video_info = info;
358 ret = 0;
359 break;
360 }
361 info++;
362 }
363 return ret;
364 }
365
disp_rtwb_enable(struct disp_device * p_rtwb)366 s32 disp_rtwb_enable(struct disp_device *p_rtwb)
367 {
368 int ret;
369 struct disp_manager *mgr = NULL;
370 unsigned long flags;
371 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
372
373 if (!p_rtwb || !p_rtwbp) {
374 DE_WRN(" p_rtwb | p_rtwbp is null\n");
375 return DIS_FAIL;
376 }
377
378 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
379 DE_WRN("tv set func null hdl!\n");
380 return DIS_FAIL;
381 }
382 mgr = p_rtwb->manager;
383 if (!mgr) {
384 DE_WRN("tv%d's mgr is NULL\n", p_rtwb->disp);
385 return DIS_FAIL;
386 }
387
388 if (p_rtwbp->enabled == 1) {
389 DE_WRN("tv%d is already open\n", p_rtwb->disp);
390 return DIS_FAIL;
391 }
392
393 rtwb_get_video_timing_info(p_rtwb, &p_rtwb->timings);
394
395 ret = reset_control_deassert(p_rtwbp->rst);
396 if (ret) {
397 DE_WRN("%s(%d): reset_control_deassert for rst failed\n", __func__, __LINE__);
398 return ret;
399 }
400
401 ret = clk_prepare_enable(p_rtwbp->clk);
402 if (ret) {
403 DE_WRN("%s(%d): clk_prepare_enable for clk failed\n", __func__, __LINE__);
404 return ret;
405 }
406
407 ret = clk_prepare_enable(p_rtwbp->clk_bus);
408 if (ret) {
409 DE_WRN("%s(%d): clk_prepare_enable for clk_bus failed\n", __func__, __LINE__);
410 return ret;
411 }
412
413 disp_al_capture_init(p_rtwb->disp);
414 disp_al_capture_set_irq_enable(p_rtwb->disp,
415 DISP_AL_CAPTURE_IRQ_FLAG_FRAME_END, 1);
416 disp_al_capture_set_mode(p_rtwb->disp, SELF_GENERATED_TIMING);
417
418 if (mgr->enable)
419 mgr->enable(mgr);
420
421 #if defined(HAVE_DEVICE_COMMON_MODULE)
422 tcon_de_attach(0xf, mgr->disp);
423 #endif
424
425
426 disp_register_irq(p_rtwb->disp + DISP_SCREEN_NUM + DISP_WB_NUM,
427 &p_rtwbp->irq_info);
428
429 spin_lock_irqsave(&g_rtwb_data_lock, flags);
430 p_rtwbp->enabled = 1;
431 spin_unlock_irqrestore(&g_rtwb_data_lock, flags);
432
433 return 0;
434 }
435
436
disp_rtwb_disable(struct disp_device * p_rtwb)437 s32 disp_rtwb_disable(struct disp_device *p_rtwb)
438 {
439 int ret;
440 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
441 unsigned long flags;
442 struct disp_manager *mgr = NULL;
443
444 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
445 DE_WRN("tv set func null hdl!\n");
446 return DIS_FAIL;
447 }
448
449 mgr = p_rtwb->manager;
450 if (!mgr) {
451 DE_WRN("tv%d's mgr is NULL\n", p_rtwb->disp);
452 return DIS_FAIL;
453 }
454
455 if (p_rtwbp->enabled == 0) {
456 DE_WRN("tv%d is already closed\n", p_rtwb->disp);
457 return DIS_FAIL;
458 }
459
460 spin_lock_irqsave(&g_rtwb_data_lock, flags);
461 p_rtwbp->enabled = 0;
462 spin_unlock_irqrestore(&g_rtwb_data_lock, flags);
463
464 if (mgr->disable)
465 mgr->disable(mgr);
466
467 disp_al_capture_set_irq_enable(p_rtwb->disp,
468 DISP_AL_CAPTURE_IRQ_FLAG_FRAME_END, 0);
469 disp_al_capture_set_mode(p_rtwb->disp, TIMING_FROM_TCON);
470 disp_al_capture_exit(p_rtwb->disp);
471
472 clk_disable_unprepare(p_rtwbp->clk);
473 clk_disable_unprepare(p_rtwbp->clk_bus);
474 ret = reset_control_assert(p_rtwbp->rst);
475 if (ret) {
476 DE_WRN("%s(%d): reset_control_assert for rst failed\n", __func__, __LINE__);
477 return ret;
478 }
479
480 disp_unregister_irq(p_rtwb->disp + DISP_SCREEN_NUM + DISP_WB_NUM,
481 &p_rtwbp->irq_info);
482 return 0;
483 }
484
disp_rtwb_is_enabled(struct disp_device * p_rtwb)485 s32 disp_rtwb_is_enabled(struct disp_device *p_rtwb)
486 {
487 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
488
489 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
490 DE_WRN("tv set func null hdl!\n");
491 return DIS_FAIL;
492 }
493
494 return p_rtwbp->enabled;
495
496 }
497
498
disp_rtwb_init(struct disp_device * p_rtwb)499 static s32 disp_rtwb_init(struct disp_device *p_rtwb)
500 {
501 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
502
503 if (!p_rtwb || !p_rtwbp) {
504 DE_WRN("tv init null hdl!\n");
505 return DIS_FAIL;
506 }
507
508 init_waitqueue_head(&p_rtwbp->wait_wb_finish_queue);
509 atomic_set(&p_rtwbp->wati_wb_finish_flag, 0);
510 return 0;
511 }
512
disp_rtwb_exit(struct disp_device * p_rtwb)513 s32 disp_rtwb_exit(struct disp_device *p_rtwb)
514 {
515 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
516
517 if (!p_rtwb || !p_rtwbp) {
518 DE_WRN("tv init null hdl!\n");
519 return DIS_FAIL;
520 }
521 disp_rtwb_disable(p_rtwb);
522 kfree(p_rtwb);
523 kfree(p_rtwbp);
524 return 0;
525 }
526
527
disp_rtwb_set_mode(struct disp_device * p_rtwb,enum disp_tv_mode tv_mode)528 s32 disp_rtwb_set_mode(struct disp_device *p_rtwb, enum disp_tv_mode tv_mode)
529 {
530 s32 ret = 0;
531 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
532
533 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
534 DE_WRN("tv set func null hdl!\n");
535 return DIS_FAIL;
536 }
537
538 p_rtwbp->tv_mode = tv_mode;
539
540 return ret;
541 }
542
disp_rtwb_get_mode(struct disp_device * p_rtwb)543 s32 disp_rtwb_get_mode(struct disp_device *p_rtwb)
544 {
545
546 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
547
548 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
549 DE_WRN("tv set func null hdl!\n");
550 return DIS_FAIL;
551 }
552
553
554 return p_rtwbp->tv_mode;
555
556 }
557
disp_rtwb_get_input_csc(struct disp_device * p_rtwb)558 s32 disp_rtwb_get_input_csc(struct disp_device *p_rtwb)
559 {
560 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
561
562 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
563 DE_WRN("tv set func null hdl!\n");
564 return DIS_FAIL;
565 }
566
567
568 return 1; /*FIXME*/
569 }
570
571
disp_rtwb_check_support_mode(struct disp_device * p_rtwb,enum disp_output_type tv_mode)572 s32 disp_rtwb_check_support_mode(struct disp_device *p_rtwb, enum disp_output_type tv_mode)
573 {
574 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
575 u32 i, list_num;
576 struct disp_rtwb_timings *info;
577
578 if ((NULL == p_rtwb) || (NULL == p_rtwbp)) {
579 DE_WRN("tv set func null hdl!\n");
580 return DIS_FAIL;
581 }
582
583 info = video_timing;
584 list_num = sizeof(video_timing)/sizeof(struct disp_rtwb_timings);
585 for (i = 0; i < list_num; i++) {
586 if (info->tv_mode == tv_mode)
587 return 1;
588 info++;
589 }
590 return 0;
591 }
592
593
disp_rtwb_get_fps(struct disp_device * p_rtwb)594 static s32 disp_rtwb_get_fps(struct disp_device *p_rtwb)
595 {
596 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
597
598 if (!p_rtwb || !p_rtwbp) {
599 DE_WRN("tv set func null hdl!\n");
600 return 0;
601 }
602
603 if (p_rtwbp->video_info) {
604 return p_rtwbp->video_info->fps;
605 } else
606 return 0;
607 }
608
609
disp_rtwb_check_config_dirty(struct disp_device * p_rtwb,struct disp_device_config * config)610 static disp_config_update_t disp_rtwb_check_config_dirty(struct disp_device *p_rtwb,
611 struct disp_device_config *config)
612 {
613 disp_config_update_t ret = DISP_NOT_UPDATE;
614 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
615
616 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
617 DE_WRN("NULL hdl!\n");
618 ret = DISP_NOT_UPDATE;
619 goto exit;
620 }
621
622 if ((p_rtwbp->enabled == 0) ||
623 (config->mode != p_rtwbp->tv_mode))
624 ret = DISP_NORMAL_UPDATE;
625
626 exit:
627 return ret;
628 }
629
disp_rtwb_set_static_config(struct disp_device * p_rtwb,struct disp_device_config * config)630 static s32 disp_rtwb_set_static_config(struct disp_device *p_rtwb,
631 struct disp_device_config *config)
632 {
633 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
634
635 if (!p_rtwb || !p_rtwbp) {
636 DE_WRN("Null pointer!\n");
637 return -1;
638 }
639
640 memcpy(&p_rtwbp->config, config, sizeof(struct disp_device_config));
641
642 p_rtwbp->config.type = p_rtwb->type;
643 p_rtwbp->config.mode = config->mode;
644 return disp_rtwb_set_mode(p_rtwb, config->mode);
645 }
646
disp_rtwb_get_static_config(struct disp_device * p_rtwb,struct disp_device_config * config)647 static s32 disp_rtwb_get_static_config(struct disp_device *p_rtwb,
648 struct disp_device_config *config)
649 {
650 int ret = 0;
651 struct disp_device_private_data *p_rtwbp = disp_rtwb_get_priv(p_rtwb);
652
653 if ((p_rtwb == NULL) || (p_rtwbp == NULL)) {
654 DE_WRN("NULL hdl!\n");
655 ret = -1;
656 goto exit;
657 }
658
659 memcpy(config,
660 &p_rtwbp->config,
661 sizeof(struct disp_device_config));
662 config->type = p_rtwb->type;
663 config->mode = p_rtwbp->tv_mode;
664
665 exit:
666 return ret;
667 }
668
669
670
671 /**
672 * @name :disp_init_rtwb
673 * @brief :register rtwb display device
674 * @param[IN] :para:pointer of hardware resource
675 * @return :0 if success
676 */
disp_init_rtwb(struct disp_bsp_init_para * para)677 s32 disp_init_rtwb(struct disp_bsp_init_para *para)
678 {
679 u32 disp = 0;
680 struct disp_device *p_rtwb;
681 struct disp_device_private_data *p_rtwbp;
682 u32 hwdev_index = 0;
683 u32 num_devices_support_rtwb = 0;
684
685 spin_lock_init(&g_rtwb_data_lock);
686
687
688 num_devices_support_rtwb = bsp_disp_feat_get_num_screens();
689 g_rtwb_devices = kmalloc(sizeof(struct disp_device)
690 * num_devices_support_rtwb,
691 GFP_KERNEL | __GFP_ZERO);
692 if (g_rtwb_devices == NULL) {
693 DE_WRN("malloc memory fail!\n");
694 goto malloc_err;
695 }
696
697 g_rtwb_private = kmalloc_array(num_devices_support_rtwb, sizeof(*p_rtwbp),
698 GFP_KERNEL | __GFP_ZERO);
699 if (g_rtwb_private == NULL) {
700 DE_WRN("malloc memory fail!\n");
701 goto malloc_err;
702 }
703
704 disp = 0;
705 for (hwdev_index = 0; hwdev_index < num_devices_support_rtwb; hwdev_index++) {
706 p_rtwb = &g_rtwb_devices[disp];
707 p_rtwbp = &g_rtwb_private[disp];
708 p_rtwb->priv_data = (void *)p_rtwbp;
709 p_rtwb->disp = disp;
710 p_rtwb->hwdev_index = hwdev_index;
711 snprintf(p_rtwb->name, sizeof(p_rtwb->name), "rtwb%d", disp);
712 p_rtwb->type = DISP_OUTPUT_TYPE_RTWB;
713 p_rtwbp->tv_mode = DISP_TV_MOD_1080P_60HZ;
714
715 p_rtwbp->clk = para->clk_de[hwdev_index];
716 p_rtwbp->clk_bus = para->clk_bus_de[hwdev_index];
717 p_rtwbp->rst = para->rst_bus_de[hwdev_index];
718
719 p_rtwbp->irq_info.sel = disp;
720 p_rtwbp->irq_info.irq_flag =
721 DISP_AL_CAPTURE_IRQ_FLAG_FRAME_END;
722 p_rtwbp->irq_info.ptr = (void *)p_rtwb;
723 p_rtwbp->irq_info.irq_handler = disp_rtwb_irq_handler;
724
725 p_rtwb->set_manager = disp_device_set_manager;
726 p_rtwb->unset_manager = disp_device_unset_manager;
727 p_rtwb->get_resolution = disp_device_get_resolution;
728 p_rtwb->get_timings = disp_device_get_timings;
729 p_rtwb->is_interlace = disp_device_is_interlace;
730 p_rtwb->init = disp_rtwb_init;
731 p_rtwb->exit = disp_rtwb_exit;
732 p_rtwb->enable = disp_rtwb_enable;
733 p_rtwb->disable = disp_rtwb_disable;
734 p_rtwb->is_enabled = disp_rtwb_is_enabled;
735 p_rtwb->set_mode = disp_rtwb_set_mode;
736 p_rtwb->get_mode = disp_rtwb_get_mode;
737 p_rtwb->set_static_config = disp_rtwb_set_static_config;
738 p_rtwb->get_static_config = disp_rtwb_get_static_config;
739 p_rtwb->check_config_dirty = disp_rtwb_check_config_dirty;
740 p_rtwb->check_support_mode = disp_rtwb_check_support_mode;
741 p_rtwb->get_input_csc = disp_rtwb_get_input_csc;
742 p_rtwb->get_fps = disp_rtwb_get_fps;
743 p_rtwb->init(p_rtwb);
744
745 disp_device_register(p_rtwb);
746 disp++;
747 }
748 return 0;
749
750 malloc_err:
751 kfree(g_rtwb_devices);
752 kfree(g_rtwb_private);
753 g_rtwb_devices = NULL;
754 g_rtwb_private = NULL;
755
756 return -1;
757 }
758
759 /**
760 * @name :disp_exit_rtwb
761 * @brief :unregister rtwb display device
762 * @return :0 if success
763 */
disp_exit_rtwb(void)764 s32 disp_exit_rtwb(void)
765 {
766 u32 num_devices;
767 u32 disp = 0;
768 struct disp_device *p_rtwb;
769 u32 hwdev_index = 0;
770
771 if (!g_rtwb_devices)
772 return 0;
773
774 num_devices = bsp_disp_feat_get_num_screens();
775 disp = 0;
776 for (hwdev_index = 0; hwdev_index < num_devices; hwdev_index++) {
777
778 p_rtwb = &g_rtwb_devices[disp];
779 disp_device_unregister(p_rtwb);
780
781 p_rtwb->exit(p_rtwb);
782 disp++;
783 }
784
785 kfree(g_rtwb_devices);
786 kfree(g_rtwb_private);
787 g_rtwb_devices = NULL;
788 g_rtwb_private = NULL;
789
790 return 0;
791 }
792
793 /**
794 * @name :disp_rtwb_config
795 * @brief :config rtwb in out param
796 * @param[IN] :mgr:pointer of display manager
797 * @param[IN] :info:pointer of capture info
798 * @return :0 if success
799 */
disp_rtwb_config(struct disp_manager * mgr,struct disp_capture_info2 * info)800 struct dmabuf_item *disp_rtwb_config(struct disp_manager *mgr, struct disp_capture_info2 *info)
801 {
802 struct disp_capture_info_inner info_inner;
803 struct dmabuf_item *item;
804 struct disp_device *dispdev = NULL;
805 enum disp_csc_type cs = DISP_CSC_TYPE_RGB;
806 struct disp_device_private_data *p_rtwbp = NULL;
807 struct disp_capture_config config;
808 u32 width = 0, height = 0;
809 struct fb_address_transfer fb;
810
811 if ((NULL == mgr) || (0 == mgr->is_enabled(mgr))) {
812 DE_WRN("manager disable!\n");
813 goto exit;
814 }
815 dispdev = mgr->device;
816 if (!dispdev || dispdev->type != DISP_OUTPUT_TYPE_RTWB) {
817 DE_WRN("disp device is NULL! or device type is not rtwb\n");
818 goto exit;
819 }
820
821 p_rtwbp = disp_rtwb_get_priv(dispdev);
822 if (!p_rtwbp) {
823 DE_WRN("Null p_rtwbp!\n");
824 return NULL;
825 }
826
827 /*after de enable*/
828
829 atomic_set(&p_rtwbp->wati_wb_finish_flag, 0);
830
831 memset(&info_inner, 0, sizeof(struct disp_s_frame_inner));
832 memcpy(&info_inner.window, &info->window, sizeof(struct disp_rect));
833 info_inner.out_frame.format = info->out_frame.format;
834 memcpy(info_inner.out_frame.size, info->out_frame.size,
835 sizeof(struct disp_rectsz) * 3);
836 memcpy(&info_inner.out_frame.crop, &info->out_frame.crop,
837 sizeof(struct disp_rect));
838 info_inner.out_frame.fd = info->out_frame.fd;
839
840 item = disp_dma_map(info_inner.out_frame.fd);
841 if (item == NULL) {
842 DE_WRN("disp dma map fail!\n");
843 goto exit;
844 }
845
846 memset(&fb, 0, sizeof(struct fb_address_transfer));
847 fb.format = info_inner.out_frame.format;
848 memcpy(fb.size, info_inner.out_frame.size,
849 sizeof(struct disp_rectsz) * 3);
850 fb.dma_addr = item->dma_addr;
851 disp_set_fb_info(&fb, true);
852 memcpy(info_inner.out_frame.addr, fb.addr, sizeof(long long) * 3);
853
854 memset(&config, 0, sizeof(struct disp_capture_config));
855
856 config.disp = mgr->disp;
857
858 memcpy(&config.out_frame, &info_inner.out_frame,
859 sizeof(struct disp_s_frame_inner));
860
861 memcpy(&config.in_frame.crop, &info_inner.window,
862 sizeof(struct disp_rect));
863 if (dispdev->get_input_csc)
864 cs = dispdev->get_input_csc(dispdev);
865 if (DISP_CSC_TYPE_RGB == cs)
866 config.in_frame.format = DISP_FORMAT_ARGB_8888;
867 else if (DISP_CSC_TYPE_YUV444 == cs)
868 config.in_frame.format = DISP_FORMAT_YUV444_P;
869 else if (DISP_CSC_TYPE_YUV422 == cs)
870 config.in_frame.format = DISP_FORMAT_YUV422_P;
871 else
872 config.in_frame.format = DISP_FORMAT_YUV420_P;
873
874 if (dispdev->get_resolution)
875 dispdev->get_resolution(dispdev, &width, &height);
876 config.in_frame.size[0].width = width;
877 config.in_frame.size[1].width = width;
878 config.in_frame.size[2].width = width;
879 config.in_frame.size[0].height = height;
880 config.in_frame.size[1].height = height;
881 config.in_frame.size[2].height = height;
882 if ((0 == config.in_frame.crop.width) ||
883 (0 == config.in_frame.crop.height)) {
884 config.in_frame.crop.width = width;
885 config.in_frame.crop.height = height;
886 }
887
888 DE_INF("disp:%d flag:%d in_fmt:%d in_fd:%d in_crop[%d %d %d "
889 "%d],in_size[%u %u, %u %u, %u "
890 "%u],in_addr[0x%llx,0x%llx,0x%llx],out_fmt:%d out_fd:%d "
891 "out_crop[%d %d %d %d],out_size[%u %u, %u %u, %u "
892 "%u],out_addr[0x%llx,0x%llx,0x%llx]\n",
893 config.disp, config.flags, config.in_frame.format,
894 config.in_frame.fd, config.in_frame.crop.x,
895 config.in_frame.crop.y, config.in_frame.crop.width,
896 config.in_frame.crop.height, config.in_frame.size[0].width,
897 config.in_frame.size[0].height, config.in_frame.size[1].width,
898 config.in_frame.size[1].height, config.in_frame.size[2].width,
899 config.in_frame.size[2].height, config.in_frame.addr[0],
900 config.in_frame.addr[1], config.in_frame.addr[2],
901 config.out_frame.format, config.out_frame.fd,
902 config.out_frame.crop.x, config.out_frame.crop.y,
903 config.out_frame.crop.width, config.out_frame.crop.height,
904 config.out_frame.size[0].width, config.out_frame.size[0].height,
905 config.out_frame.size[1].width, config.out_frame.size[1].height,
906 config.out_frame.size[2].width, config.out_frame.size[2].height,
907 config.out_frame.addr[0], config.out_frame.addr[1],
908 config.out_frame.addr[2]);
909
910 if (disp_feat_is_using_wb_rcq(mgr->disp)) {
911 disp_al_capture_set_all_rcq_head_dirty(mgr->disp, 0);
912 disp_al_capture_set_rcq_update(mgr->disp, 0);
913 }
914 disp_al_capture_apply(mgr->disp, &config);
915 if (disp_feat_is_using_wb_rcq(mgr->disp))
916 disp_al_capture_set_rcq_update(mgr->disp, 1);
917 else
918 disp_al_capture_sync(mgr->disp);
919
920 exit:
921 return item;
922 }
923
disp_rtwb_wait_finish(struct disp_manager * mgr)924 s32 disp_rtwb_wait_finish(struct disp_manager *mgr)
925 {
926 struct disp_device *dispdev = NULL;
927 struct disp_device_private_data *p_rtwbp = NULL;
928 int ret = 0;
929
930 if ((NULL == mgr) || (0 == mgr->is_enabled(mgr))) {
931 DE_WRN("manager disable!\n");
932 return -1;
933 }
934
935 dispdev = mgr->device;
936
937 if (!dispdev || dispdev->type != DISP_OUTPUT_TYPE_RTWB) {
938 DE_WRN("disp device is NULL! or device type is not rtwb\n");
939 return -1;
940 }
941 p_rtwbp = disp_rtwb_get_priv(dispdev);
942 if (!p_rtwbp) {
943 DE_WRN("Null p_rtwbp!\n");
944 return -1;
945 }
946
947 de_top_start_rtwb(dispdev->disp, 1);
948
949 ret = wait_event_timeout(
950 p_rtwbp->wait_wb_finish_queue,
951 atomic_read(&p_rtwbp->wati_wb_finish_flag) == 1,
952 msecs_to_jiffies(100));
953 if (ret <= 0) {
954 DE_WRN("rtwb pending timout!\n");
955 atomic_set(&p_rtwbp->wati_wb_finish_flag, 1);
956 wake_up(&p_rtwbp->wait_wb_finish_queue);
957 ret = -1;
958 } else
959 ret = 0;
960
961
962 de_top_start_rtwb(dispdev->disp, 0);
963 return ret;
964 }
965
966 #endif
967