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_vga.h"
18
19 #if defined(SUPPORT_VGA)
20
21 static struct disp_device *vgas;
22 static struct disp_vga_private_data *vga_private;
23
24 static s32 disp_vga_set_hpd(struct disp_device *vga, u32 state);
disp_vga_get_priv(struct disp_device * vga)25 static struct disp_vga_private_data *disp_vga_get_priv(struct disp_device *vga)
26 {
27 if (vga == NULL) {
28 DE_WRN("device hdl is NULL!\n");
29 return NULL;
30 }
31
32 return (struct disp_vga_private_data *)vga->priv_data;
33 }
34
35 #if defined(__LINUX_PLAT__)
disp_vga_event_proc(int irq,void * parg)36 static s32 disp_vga_event_proc(int irq, void *parg)
37 #else
38 static s32 disp_vga_event_proc(void *parg)
39 #endif
40 {
41 struct disp_device *vga = (struct disp_device *)parg;
42 struct disp_manager *mgr = NULL;
43 u32 hwdev_index;
44
45 if (vga == NULL) {
46 DE_WRN("device hdl is NULL!\n");
47 return DISP_IRQ_RETURN;
48 }
49
50 hwdev_index = vga->hwdev_index;
51 if (disp_al_device_query_irq(hwdev_index)) {
52 int cur_line = disp_al_device_get_cur_line(hwdev_index);
53 int start_delay = disp_al_device_get_start_delay(hwdev_index);
54
55 mgr = vga->manager;
56 if (mgr == NULL)
57 return DISP_IRQ_RETURN;
58
59 if (cur_line <= (start_delay - 4))
60 sync_event_proc(mgr->disp, false);
61 else
62 sync_event_proc(mgr->disp, true);
63 }
64
65 return DISP_IRQ_RETURN;
66 }
67
vga_clk_init(struct disp_device * vga)68 static s32 vga_clk_init(struct disp_device *vga)
69 {
70 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
71
72 if (!vga || !vgap) {
73 DE_WRN("device hdl is NULL!\n");
74 return DIS_FAIL;
75 }
76
77 vgap->clk_parent = clk_get_parent(vgap->clk);
78
79 return 0;
80 }
81
vga_clk_exit(struct disp_device * vga)82 static s32 vga_clk_exit(struct disp_device *vga)
83 {
84 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
85
86 if (!vga || !vgap) {
87 DE_WRN("device hdl is NULL!\n");
88 return DIS_FAIL;
89 }
90
91 return 0;
92 }
93
vga_clk_config(struct disp_device * vga)94 static s32 vga_clk_config(struct disp_device *vga)
95 {
96 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
97
98 if (!vga || !vgap) {
99 DE_WRN("device hdl is NULL!\n");
100 return DIS_FAIL;
101 }
102
103 return clk_set_rate(vgap->clk, vga->timings.pixel_clk);
104 }
105
vga_clk_enable(struct disp_device * vga)106 static s32 vga_clk_enable(struct disp_device *vga)
107 {
108 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
109
110 if (!vga || !vgap) {
111 DE_WRN("device hdl is NULL!\n");
112 return DIS_FAIL;
113 }
114
115 return clk_prepare_enable(vgap->clk);
116 }
117
vga_clk_disable(struct disp_device * vga)118 static s32 vga_clk_disable(struct disp_device *vga)
119 {
120 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
121
122 if (!vga || !vgap) {
123 DE_WRN("device hdl is NULL!\n");
124 return DIS_FAIL;
125 }
126
127 clk_disable(vgap->clk);
128
129 return 0;
130 }
131
vga_calc_judge_line(struct disp_device * vga)132 static s32 vga_calc_judge_line(struct disp_device *vga)
133 {
134 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
135 int start_delay, usec_start_delay;
136 int usec_judge_point;
137
138 if (!vga || !vgap) {
139 DE_WRN("VGA init null hdl!\n");
140 return DIS_FAIL;
141 }
142
143 /*
144 * usec_per_line = 1 / fps / vt * 1000000
145 * = 1 / (pixel_clk / vt / ht) / vt * 1000000
146 * = ht / pixel_clk * 1000000
147 */
148 vgap->frame_per_sec = DIV_ROUND_CLOSEST(
149 vgap->video_info->pixel_clk * (vgap->video_info->b_interlace + 1),
150 (vgap->video_info->hor_total_time *
151 vgap->video_info->ver_total_time *
152 (vgap->video_info->trd_mode + 1)));
153 vgap->usec_per_line = vgap->video_info->hor_total_time
154 * 1000000 / vgap->video_info->pixel_clk;
155
156 start_delay = disp_al_device_get_start_delay(vga->hwdev_index);
157 usec_start_delay = start_delay * vgap->usec_per_line;
158
159 if (usec_start_delay <= 200)
160 usec_judge_point = usec_start_delay * 3 / 7;
161 else if (usec_start_delay <= 400)
162 usec_judge_point = usec_start_delay / 2;
163 else
164 usec_judge_point = 200;
165 if (vgap->usec_per_line)
166 vgap->judge_line = usec_judge_point / vgap->usec_per_line;
167 else
168 DE_WRN("usec_per_line is Null,someting is wrong!\n");
169
170 return 0;
171 }
172
cal_real_frame_period(struct disp_device * vga)173 static s32 cal_real_frame_period(struct disp_device *vga)
174 {
175 s32 ret = -1;
176 struct disp_vga_private_data *vgap;
177 unsigned long long temp = 0;
178
179 if (!vga) {
180 DE_WRN("device hdl is NULL!\n");
181 goto OUT;
182 }
183
184 vgap = disp_vga_get_priv(vga);
185
186 if (!vgap) {
187 DE_WRN("vgap hdl is NULL!\n");
188 goto OUT;
189 }
190
191 if (!vgap->clk || !vgap->video_info) {
192 DE_WRN("vga clk | video_info null!\n");
193 goto OUT;
194 }
195
196 vga->timings.dclk_rate_set = clk_get_rate(vgap->clk);
197
198 if (vga->timings.dclk_rate_set == 0) {
199 DE_WRN(" vga dclk_rate_set is 0!\n");
200 goto OUT;
201 }
202
203 temp = ONE_SEC * vgap->video_info->hor_total_time *
204 vgap->video_info->ver_total_time;
205
206 do_div(temp, vga->timings.dclk_rate_set *
207 (vgap->video_info->b_interlace + 1));
208
209 vga->timings.frame_period = temp;
210
211 vga->timings.start_delay =
212 disp_al_device_get_start_delay(vga->hwdev_index);
213
214 DE_INF("vga frame period:%llu\n", vga->timings.frame_period);
215 ret = 0;
216
217 OUT:
218 return ret;
219 }
220
disp_vga_enable(struct disp_device * vga)221 static s32 disp_vga_enable(struct disp_device *vga)
222 {
223 int ret;
224 struct disp_manager *mgr = NULL;
225 unsigned long flags;
226 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
227
228 if ((vga == NULL) || (vgap == NULL)) {
229 DE_WRN("device hdl is NULL!\n");
230 return DIS_FAIL;
231 }
232
233 mgr = vga->manager;
234 if (!mgr) {
235 DE_WRN("device%d's mgr is NULL!\n", vga->disp);
236 return DIS_FAIL;
237 }
238
239 if (vgap->enabled) {
240 DE_WRN("device%d is already enabled!\n", vga->disp);
241 return DIS_FAIL;
242 }
243 if (vgap->tv_func.tv_get_video_timing_info == NULL) {
244 DE_WRN("get_video_timing_info func is null\n");
245 return DIS_FAIL;
246 }
247
248 vgap->tv_func.tv_get_video_timing_info(vga->disp, &(vgap->video_info));
249
250 if (vgap->video_info == NULL) {
251 DE_WRN("video info is null\n");
252 return DIS_FAIL;
253 }
254 memcpy(&vga->timings, vgap->video_info,
255 sizeof(struct disp_video_timings));
256 vga_calc_judge_line(vga);
257 mutex_lock(&vgap->mlock);
258 if (vgap->enabled)
259 goto exit;
260 if (mgr->enable)
261 mgr->enable(mgr);
262
263 if (vgap->tv_func.tv_enable == NULL) {
264 DE_WRN("enable is NULL\n");
265 goto exit;
266 }
267 vga_clk_config(vga);
268 ret = vga_clk_enable(vga);
269 if (ret != 0) {
270 DE_WRN("fail to enable clock\n");
271 goto exit;
272 }
273
274 ret = cal_real_frame_period(vga);
275 if (ret)
276 DE_WRN("cal_real_frame_period fali:%d\n", ret);
277
278 vgap->tv_func.tv_enable(vga->disp);
279 disp_al_vga_cfg(vga->hwdev_index, vgap->video_info);
280 disp_al_vga_enable(vga->hwdev_index);
281
282 ret = disp_sys_register_irq(vgap->irq_no, 0,
283 disp_vga_event_proc, (void *)vga, 0, 0);
284 if (ret != 0)
285 DE_WRN("request irq failed!\n");
286
287 disp_sys_enable_irq(vgap->irq_no);
288 spin_lock_irqsave(&vgap->data_lock, flags);
289 vgap->enabled = true;
290 spin_unlock_irqrestore(&vgap->data_lock, flags);
291
292 exit:
293 mutex_unlock(&vgap->mlock);
294
295 return 0;
296 }
297
disp_vga_sw_enable(struct disp_device * vga)298 static s32 disp_vga_sw_enable(struct disp_device *vga)
299 {
300 struct disp_manager *mgr = NULL;
301 unsigned long flags;
302 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
303
304 if (!vga || !vgap) {
305 DE_WRN("device hdl is NULL!\n");
306 return DIS_FAIL;
307 }
308
309 mgr = vga->manager;
310 if (!mgr) {
311 DE_WRN("device%d's mgr is NULL\n", vga->disp);
312 return DIS_FAIL;
313 }
314
315 if (vgap->enabled) {
316 DE_WRN("device%d is already enabled\n", vga->disp);
317 return DIS_FAIL;
318 }
319 if (vgap->tv_func.tv_get_video_timing_info == NULL) {
320 DE_WRN("get_video_timing_info func is null\n");
321 return DIS_FAIL;
322 }
323
324 vgap->tv_func.tv_get_video_timing_info(vga->disp, &(vgap->video_info));
325
326 if (vgap->video_info == NULL) {
327 DE_WRN("video info is null\n");
328 return DIS_FAIL;
329 }
330 memcpy(&vga->timings, vgap->video_info,
331 sizeof(struct disp_video_timings));
332 vga_calc_judge_line(vga);
333 mutex_lock(&vgap->mlock);
334 if (mgr->sw_enable)
335 mgr->sw_enable(mgr);
336 if (vgap->tv_func.tv_enable == NULL) {
337 DE_WRN("enable func is NULL\n");
338 goto exit;
339 }
340
341 disp_al_vga_irq_disable(vga->hwdev_index);
342 disp_sys_register_irq(vgap->irq_no, 0, disp_vga_event_proc, (void *)vga,
343 0, 0);
344 disp_sys_enable_irq(vgap->irq_no);
345 disp_al_vga_irq_enable(vga->hwdev_index);
346
347 #if !defined(CONFIG_COMMON_CLK_ENABLE_SYNCBOOT)
348 if (vga_clk_enable(vga) != 0)
349 goto exit;
350 #endif
351
352 if (0 != cal_real_frame_period(vga))
353 DE_WRN("cal_real_frame_period fali!\n");
354
355 spin_lock_irqsave(&vgap->data_lock, flags);
356 vgap->enabled = true;
357 spin_unlock_irqrestore(&vgap->data_lock, flags);
358
359 exit:
360 mutex_unlock(&vgap->mlock);
361
362 return 0;
363 }
364
disp_vga_disable(struct disp_device * vga)365 s32 disp_vga_disable(struct disp_device *vga)
366 {
367 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
368 unsigned long flags;
369 struct disp_manager *mgr = NULL;
370
371 if ((vga == NULL) || (vgap == NULL)) {
372 DE_WRN("device hdl is NULL!\n");
373 return DIS_FAIL;
374 }
375
376 mgr = vga->manager;
377 if (!mgr) {
378 DE_WRN("device%d's mgr is NULL\n", vga->disp);
379 return DIS_FAIL;
380 }
381
382 if (!vgap->enabled) {
383 DE_WRN("device%d is already disabled\n", vga->disp);
384 return DIS_FAIL;
385 }
386 if (vgap->tv_func.tv_disable == NULL) {
387 DE_WRN("disable func is NULL\n");
388 return -1;
389 }
390
391 mutex_lock(&vgap->mlock);
392
393 spin_lock_irqsave(&vgap->data_lock, flags);
394 vgap->enabled = false;
395 spin_unlock_irqrestore(&vgap->data_lock, flags);
396
397 disp_vga_set_hpd(vga, 0);
398 vgap->tv_func.tv_disable(vga->disp);
399 disp_al_vga_disable(vga->hwdev_index);
400 if (mgr->disable)
401 mgr->disable(mgr);
402 vga_clk_disable(vga);
403 vgap->video_info = NULL;
404
405 disp_sys_disable_irq(vgap->irq_no);
406 disp_sys_unregister_irq(vgap->irq_no, disp_vga_event_proc, (void *)vga);
407
408 mutex_unlock(&vgap->mlock);
409
410 return 0;
411 }
412
disp_vga_init(struct disp_device * vga)413 static s32 disp_vga_init(struct disp_device *vga)
414 {
415 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
416
417 if (!vga || !vgap) {
418 DE_WRN("device hdl is NULL!\n");
419 return DIS_FAIL;
420 }
421
422 vga_clk_init(vga);
423
424 return 0;
425 }
426
disp_vga_exit(struct disp_device * vga)427 static s32 disp_vga_exit(struct disp_device *vga)
428 {
429 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
430
431 if (!vga || !vgap) {
432 DE_WRN("device hdl is NULL!\n");
433 return DIS_FAIL;
434 }
435 disp_vga_disable(vga);
436
437 vga_clk_exit(vga);
438
439 kfree(vga);
440 kfree(vgap);
441 return 0;
442 }
443
disp_vga_is_enabled(struct disp_device * vga)444 static s32 disp_vga_is_enabled(struct disp_device *vga)
445 {
446 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
447
448 if ((vga == NULL) || (vgap == NULL)) {
449 DE_WRN("device hdl is NULL!\n");
450 return DIS_FAIL;
451 }
452
453 return vgap->enabled ? 1 : 0;
454 }
455
456 /**
457 * disp_vga_check_if_enabled - check vga if be enabled status
458 *
459 * this function only be used by bsp_disp_sync_with_hw to check
460 * the device enabled status when driver init
461 */
disp_vga_check_if_enabled(struct disp_device * vga)462 static s32 disp_vga_check_if_enabled(struct disp_device *vga)
463 {
464 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
465 int ret = 1;
466
467 if ((vga == NULL) || (vgap == NULL)) {
468 DE_WRN("device hdl is NULL!\n");
469 return DIS_FAIL;
470 }
471
472 #if !defined(CONFIG_COMMON_CLK_ENABLE_SYNCBOOT)
473 if (vgap->clk &&
474 (__clk_is_enabled(vgap->clk) == 0))
475 ret = 0;
476 #endif
477
478 return ret;
479 }
480
disp_vga_suspend(struct disp_device * vga)481 static s32 disp_vga_suspend(struct disp_device *vga)
482 {
483 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
484
485 if ((vga == NULL) || (vgap == NULL)) {
486 DE_WRN("device hdl is NULL!\n");
487 return DIS_FAIL;
488 }
489
490 mutex_lock(&vgap->mlock);
491 if (!vgap->suspended) {
492 vgap->suspended = true;
493 if (vgap->tv_func.tv_suspend != NULL)
494 vgap->tv_func.tv_suspend(vga->disp);
495 }
496 mutex_unlock(&vgap->mlock);
497
498 return 0;
499 }
500
disp_vga_resume(struct disp_device * vga)501 static s32 disp_vga_resume(struct disp_device *vga)
502 {
503 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
504
505 if ((vga == NULL) || (vgap == NULL)) {
506 DE_WRN("device hdl is NULL!\n");
507 return DIS_FAIL;
508 }
509
510 mutex_lock(&vgap->mlock);
511 if (vgap->suspended) {
512 if (vgap->tv_func.tv_resume != NULL)
513 vgap->tv_func.tv_resume(vga->disp);
514
515 vgap->suspended = false;
516 }
517 mutex_unlock(&vgap->mlock);
518
519 return 0;
520 }
521
disp_vga_set_mode(struct disp_device * vga,u32 vga_mode)522 static s32 disp_vga_set_mode(struct disp_device *vga, u32 vga_mode)
523 {
524 s32 ret = 0;
525 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
526
527 if ((vga == NULL) || (vgap == NULL)) {
528 DE_WRN("device hdl is NULL!\n");
529 return DIS_FAIL;
530 }
531
532 if (vgap->tv_func.tv_set_mode == NULL) {
533 DE_WRN("set_mode func is null!\n");
534 return DIS_FAIL;
535 }
536
537 ret = vgap->tv_func.tv_set_mode(vga->disp, vga_mode);
538 if (ret == 0)
539 vgap->vga_mode = vga_mode;
540
541 return ret;
542 }
543
disp_vga_get_mode(struct disp_device * vga)544 static s32 disp_vga_get_mode(struct disp_device *vga)
545 {
546 enum disp_tv_mode vga_mode;
547 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
548
549 if ((vga == NULL) || (vgap == NULL)) {
550 DE_WRN("device hdl is NULL!\n");
551 return DIS_FAIL;
552 }
553
554 if (vgap->tv_func.tv_get_mode == NULL) {
555 DE_WRN("set_mode is null!\n");
556 return -1;
557 }
558
559 vga_mode = vgap->tv_func.tv_get_mode(vga->disp);
560
561 if (vga_mode != vgap->vga_mode)
562 vgap->vga_mode = vga_mode;
563
564 return vgap->vga_mode;
565 }
566
disp_vga_get_input_csc(struct disp_device * vga)567 static s32 disp_vga_get_input_csc(struct disp_device *vga)
568 {
569 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
570
571 if ((vga == NULL) || (vgap == NULL)) {
572 DE_WRN("device hdl is NULL!\n");
573 return DIS_FAIL;
574 }
575
576 if (vgap->tv_func.tv_get_input_csc == NULL)
577 return DIS_FAIL;
578
579 return vgap->tv_func.tv_get_input_csc(vga->disp); /* 0 or 1. */
580 }
581
disp_vga_set_func(struct disp_device * vga,struct disp_tv_func * func)582 static s32 disp_vga_set_func(struct disp_device *vga, struct disp_tv_func *func)
583 {
584 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
585
586 if ((vga == NULL) || (vgap == NULL)) {
587 DE_WRN("device hdl is NULL!\n");
588 return DIS_FAIL;
589 }
590
591 vgap->tv_func.tv_enable = func->tv_enable;
592 vgap->tv_func.tv_disable = func->tv_disable;
593 vgap->tv_func.tv_suspend = func->tv_suspend;
594 vgap->tv_func.tv_resume = func->tv_resume;
595 vgap->tv_func.tv_get_mode = func->tv_get_mode;
596 vgap->tv_func.tv_set_mode = func->tv_set_mode;
597 vgap->tv_func.tv_get_input_csc = func->tv_get_input_csc;
598 vgap->tv_func.tv_get_video_timing_info = func->tv_get_video_timing_info;
599 vgap->tv_func.tv_mode_support = func->tv_mode_support;
600 vgap->tv_func.tv_hot_plugging_detect = func->tv_hot_plugging_detect;
601 vgap->tv_func.tv_set_enhance_mode = func->tv_set_enhance_mode;
602
603 return 0;
604 }
605
disp_vga_check_support_mode(struct disp_device * vga,enum disp_tv_mode vga_mode)606 static s32 disp_vga_check_support_mode(struct disp_device *vga,
607 enum disp_tv_mode vga_mode)
608 {
609 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
610
611 if ((vga == NULL) || (vgap == NULL)) {
612 DE_WRN("device hdl is NULL!\n");
613 return DIS_FAIL;
614 }
615
616 if (vgap->tv_func.tv_get_input_csc == NULL)
617 return DIS_FAIL;
618 return vgap->tv_func.tv_mode_support(vga->disp, vga_mode);
619 }
620
disp_vga_set_hpd(struct disp_device * vga,u32 state)621 static s32 disp_vga_set_hpd(struct disp_device *vga, u32 state)
622 {
623 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
624
625 if ((vga == NULL) || (vgap == NULL)) {
626 DE_WRN("device hdl is NULL!\n");
627 return DIS_FAIL;
628 }
629
630 if (vgap->tv_func.tv_hot_plugging_detect == NULL)
631 return DIS_FAIL;
632
633 return vgap->tv_func.tv_hot_plugging_detect(state);
634 }
635
disp_set_enhance_mode(struct disp_device * vga,u32 mode)636 static s32 disp_set_enhance_mode(struct disp_device *vga, u32 mode)
637 {
638 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
639
640 if ((vga == NULL) || (vgap == NULL)) {
641 DE_WRN("device hdl is NULL!\n");
642 return DIS_FAIL;
643 }
644
645 if (vgap->tv_func.tv_hot_plugging_detect == NULL) {
646 DE_WRN("set_enhance_mode is null!\n");
647 return DIS_FAIL;
648 }
649
650 return vgap->tv_func.tv_set_enhance_mode(vga->disp, mode);
651 }
652
disp_vga_get_fps(struct disp_device * vga)653 static s32 disp_vga_get_fps(struct disp_device *vga)
654 {
655 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
656
657 if ((vga == NULL) || (vgap == NULL)) {
658 DE_WRN("vga set func null hdl!\n");
659 return 0;
660 }
661
662 return vgap->frame_per_sec;
663 }
664
disp_vga_set_static_config(struct disp_device * vga,struct disp_device_config * config)665 static s32 disp_vga_set_static_config(struct disp_device *vga,
666 struct disp_device_config *config)
667 {
668 return disp_vga_set_mode(vga, config->mode);
669 }
670
disp_vga_get_static_config(struct disp_device * vga,struct disp_device_config * config)671 static s32 disp_vga_get_static_config(struct disp_device *vga,
672 struct disp_device_config *config)
673 {
674 int ret = 0;
675 struct disp_vga_private_data *vgap = disp_vga_get_priv(vga);
676
677 if ((vga == NULL) || (vgap == NULL)) {
678 DE_WRN("NULL hdl!\n");
679 ret = -1;
680 goto exit;
681 }
682
683 config->type = vga->type;
684 config->mode = vgap->vga_mode;
685 if (vgap->tv_func.tv_get_input_csc)
686 config->format = vgap->tv_func.tv_get_input_csc(vga->disp);
687
688 exit:
689 return ret;
690 }
691
692 static disp_config_update_t
disp_vga_check_config_dirty(struct disp_device * vga,struct disp_device_config * config)693 disp_vga_check_config_dirty(struct disp_device *vga,
694 struct disp_device_config *config)
695 {
696 disp_config_update_t ret = DISP_NOT_UPDATE;
697 struct disp_vga_private_data *vgap = NULL;
698
699 if (!vga) {
700 DE_WRN("NULL hdl!\n");
701 goto exit;
702 }
703
704 vgap = disp_vga_get_priv(vga);
705 if (!vgap) {
706 DE_WRN("NULL hdl!\n");
707 goto exit;
708 }
709
710 if ((vgap->enabled == 0) || (config->mode != vgap->vga_mode))
711 ret = DISP_NORMAL_UPDATE;
712
713 exit:
714 return ret;
715 }
716
disp_init_vga(void)717 s32 disp_init_vga(void)
718 {
719 u32 value = 0;
720 u32 ret = 0;
721 char type_name[32];
722 char compat[32];
723 char status[10] = { 0 };
724 const char *str;
725 struct device_node *node;
726 u32 num_devices;
727 u32 disp = 0;
728 struct disp_device *vga;
729 struct disp_vga_private_data *vgap;
730 u32 hwdev_index = 0;
731 u32 num_devices_support_vga = 0;
732
733 sprintf(compat, "allwinner,sunxi-tv");
734 num_devices = bsp_disp_feat_get_num_devices();
735 for (hwdev_index = 0; hwdev_index < num_devices; hwdev_index++) {
736 if (bsp_disp_feat_is_supported_output_types(hwdev_index,
737 DISP_OUTPUT_TYPE_VGA))
738 num_devices_support_vga++;
739 }
740 vgas = kmalloc_array(num_devices_support_vga, sizeof(*vga),
741 GFP_KERNEL | __GFP_ZERO);
742 if (vgas == NULL) {
743 DE_WRN("malloc memory fail!\n");
744 return DIS_FAIL;
745 }
746
747 vga_private = kmalloc_array(num_devices_support_vga, sizeof(*vgap),
748 GFP_KERNEL | __GFP_ZERO);
749 if (vga_private == NULL) {
750 DE_WRN("malloc memory fail!\n");
751 return DIS_FAIL;
752 }
753
754 disp = 0;
755 for (hwdev_index = 0; hwdev_index < num_devices; hwdev_index++) {
756 if (!bsp_disp_feat_is_supported_output_types(hwdev_index,
757 DISP_OUTPUT_TYPE_VGA)) {
758 DE_DBG("screen %d do not support VGA TYPE!\n",
759 hwdev_index);
760 continue;
761 }
762 sprintf(type_name, "tv%d", disp);
763 node = of_find_compatible_node(NULL, type_name, compat);
764
765 ret = of_property_read_string(node, "status", &str);
766 memcpy((void *)status, str, strlen(str) + 1);
767 if (ret || strcmp(status, "okay")) {
768 DE_DBG("disp%d not support vga\n", disp);
769 disp++;
770 continue;
771 }
772
773 ret = of_property_read_u32_array(node, "interface", &value, 1);
774 if (ret || value != DISP_VGA) {
775 DE_DBG("disp%d not support vga\n", disp);
776 disp++;
777 continue;
778 }
779
780 vga = &vgas[disp];
781 vgap = &vga_private[disp];
782 vga->priv_data = (void *)vgap;
783
784 spin_lock_init(&vgap->data_lock);
785 mutex_init(&vgap->mlock);
786 vga->disp = disp;
787 vga->hwdev_index = hwdev_index;
788 sprintf(vga->name, "vga%d", disp);
789 vga->type = DISP_OUTPUT_TYPE_VGA;
790 vgap->vga_mode = DISP_TV_MOD_PAL;
791 vgap->irq_no = gdisp.init_para.irq_no[DISP_MOD_LCD0 +
792 hwdev_index];
793 vgap->clk = gdisp.init_para.mclk[DISP_MOD_LCD0 + hwdev_index];
794
795 vga->set_manager = disp_device_set_manager;
796 vga->unset_manager = disp_device_unset_manager;
797 vga->get_resolution = disp_device_get_resolution;
798 vga->get_timings = disp_device_get_timings;
799
800 vga->init = disp_vga_init;
801 vga->exit = disp_vga_exit;
802 vga->set_tv_func = disp_vga_set_func;
803 vga->enable = disp_vga_enable;
804 vga->sw_enable = disp_vga_sw_enable;
805 vga->disable = disp_vga_disable;
806 vga->is_enabled = disp_vga_is_enabled;
807 vga->check_if_enabled = disp_vga_check_if_enabled;
808 vga->set_mode = disp_vga_set_mode;
809 vga->get_mode = disp_vga_get_mode;
810 vga->set_static_config = disp_vga_set_static_config;
811 vga->get_static_config = disp_vga_get_static_config;
812 vga->check_config_dirty = disp_vga_check_config_dirty;
813 vga->check_support_mode = disp_vga_check_support_mode;
814 vga->get_input_csc = disp_vga_get_input_csc;
815 vga->suspend = disp_vga_suspend;
816 vga->resume = disp_vga_resume;
817 vga->set_enhance_mode = disp_set_enhance_mode;
818 vga->get_fps = disp_vga_get_fps;
819 vga->get_status = disp_device_get_status;
820 vga->is_in_safe_period = disp_device_is_in_safe_period;
821 vga->usec_before_vblank = disp_device_usec_before_vblank;
822 vga->show_builtin_patten = disp_device_show_builtin_patten;
823 vga->init(vga);
824 disp_device_register(vga);
825 disp++;
826 }
827
828 return 0;
829 }
830
831 #endif
832