• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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