1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #include <common.h>
20 #include <command.h>
21 #include "hi_common_vo.h"
22 #include "vo.h"
23 #if CONFIG_HI_HDMI_SUPPORT
24 #include "hi_hdmi.h"
25 #endif
26
27 #define CFG_MAXARGS_SETVOBG 3
28 #define CFG_MAXARGS_STARTVO 4
29 #define CFG_MAXARGS_STOPVO 2
30 #define CFG_MAXARGS_STARTVL 8
31 #define CFG_MAXARGS_STOPVL 2
32 #define CFG_MAXARGS_STARTGX 9
33 #define CFG_MAXARGS_STOPGX 2
34 #define CMD_VO_ARGS_BASE10 10
35 #define CMD_VO_ARGS_BASE16 16
36 #define CMD_VO_ARGS_BASE_ALL 0
37 #define INSUFFICIENT_PARAM_STR "insufficient parameter or operation not permitted!\n"
38
39 #define VO_DEV_MAX_NUM 3
40
41 static unsigned int g_a_interface_type[VO_DEV_MAX_NUM] = { [0 ... (VO_DEV_MAX_NUM - 1)] = 0};
42
vo_get_interface_type(unsigned int dev)43 static unsigned int vo_get_interface_type(unsigned int dev)
44 {
45 if (dev >= VO_DEV_MAX_NUM) {
46 return 0;
47 }
48 return g_a_interface_type[dev];
49 }
50
vo_set_interface_type(unsigned int dev,unsigned int type)51 static void vo_set_interface_type(unsigned int dev, unsigned int type)
52 {
53 if (dev >= VO_DEV_MAX_NUM) {
54 return;
55 }
56 g_a_interface_type[dev] = type;
57 }
58
vobg_parse(char * const argv[],unsigned int * dev,unsigned int * rgb)59 static int vobg_parse(char *const argv[], unsigned int *dev, unsigned int *rgb)
60 {
61 int ret;
62 unsigned long dev_tmp, rgb_tmp;
63 ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &dev_tmp); /* 1st arg */
64 if (ret != 0) {
65 printf("parse dev failed.\n");
66 return -1;
67 }
68 ret = strict_strtoul(argv[2], CMD_VO_ARGS_BASE_ALL, &rgb_tmp); /* 2nd arg */
69 if (ret != 0) {
70 printf("parse color failed.\n");
71 return -1;
72 }
73 *dev = (unsigned int)dev_tmp;
74 *rgb = (unsigned int)rgb_tmp;
75 return 0;
76 }
77
do_vobg(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])78 static int do_vobg(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
79 {
80 int ret;
81 unsigned int dev, rgb;
82
83 if (argc < 3) { /* max 3 args */
84 printf("insufficient parameter!\n");
85 printf("usage:\n%s\n", cmdtp->usage);
86 return -1;
87 }
88 ret = vobg_parse(argv, &dev, &rgb);
89 if (ret != 0) {
90 printf("insufficient parameter!\n");
91 return -1;
92 }
93 ret = set_vobg(dev, rgb);
94 if (ret != 0) {
95 printf(INSUFFICIENT_PARAM_STR);
96 return -1;
97 }
98
99 printf("dev %u set background color 0x%x!\n", dev, rgb);
100
101 return 0;
102 }
103
startvo_parse(char * const argv[],unsigned int * dev,unsigned int * intftype,unsigned int * sync)104 static int startvo_parse(char *const argv[], unsigned int *dev, unsigned int *intftype, unsigned int *sync)
105 {
106 int ret;
107 unsigned long dev_tmp, intftype_tmp, sync_tmp;
108 ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &dev_tmp); /* 1st arg */
109 if (ret != 0) {
110 printf("parse dev failed.\n");
111 return -1;
112 }
113 ret = strict_strtoul(argv[2], CMD_VO_ARGS_BASE10, &intftype_tmp); /* 2nd arg */
114 if (ret != 0) {
115 printf("parse intftype failed.\n");
116 return -1;
117 }
118 ret = strict_strtoul(argv[3], CMD_VO_ARGS_BASE10, &sync_tmp); /* 3rd arg */
119 if (ret != 0) {
120 printf("parse sync failed.\n");
121 return -1;
122 }
123 *dev = (unsigned int)dev_tmp;
124 *intftype = (unsigned int)intftype_tmp;
125 *sync = (unsigned int)sync_tmp;
126 return 0;
127 }
128
129 #if CONFIG_HI_HDMI_SUPPORT
do_start_hdmi(unsigned int intftype,unsigned int sync)130 static void do_start_hdmi(unsigned int intftype, unsigned int sync)
131 {
132 if (intftype & HI_VO_INTF_HDMI) {
133 if (intftype == (HI_VO_INTF_HDMI | HI_VO_INTF_MIPI)) {
134 /* start hdmi */
135 hdmi_display(sync, HI_HDMI_VIDEO_MODE_RGB444, HI_HDMI_VIDEO_MODE_YCBCR444);
136 } else {
137 /* start hdmi */
138 hdmi_display(sync, HI_HDMI_VIDEO_MODE_YCBCR444, HI_HDMI_VIDEO_MODE_YCBCR444);
139 }
140 }
141 }
142 #endif
143
do_startvo(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])144 static int do_startvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
145 {
146 int ret;
147 unsigned int dev, intftype, sync;
148
149 if (argc < 4) { /* max 4 args */
150 printf("insufficient parameter!\n");
151 printf("usage:\n%s\n", cmdtp->usage);
152 return -1;
153 }
154 ret = startvo_parse(argv, &dev, &intftype, &sync);
155 if (ret != 0) {
156 printf("insufficient parameter!\n");
157 return -1;
158 }
159
160 ret = start_vo(dev, intftype, sync);
161 if (ret != 0) {
162 printf(INSUFFICIENT_PARAM_STR);
163 return -1;
164 }
165
166 #if CONFIG_HI_HDMI_SUPPORT
167 do_start_hdmi(intftype, sync);
168 #endif
169
170 vo_set_interface_type(dev, intftype);
171
172 printf("dev %u opened!\n", dev);
173
174 return 0;
175 }
176
do_stop_hdmi(unsigned int dev)177 static void do_stop_hdmi(unsigned int dev)
178 {
179 if (vo_get_interface_type(dev) & HI_VO_INTF_HDMI) {
180 /* stop hdmi */
181 #if CONFIG_HI_HDMI_SUPPORT
182 hdmi_stop();
183 #endif
184 }
185 }
186
do_stop_intf(unsigned int dev)187 static void do_stop_intf(unsigned int dev)
188 {
189 do_stop_hdmi(dev);
190 vo_set_interface_type(dev, 0);
191 }
192
stopvo_parse(char * const argv[],unsigned int * dev)193 static int stopvo_parse(char *const argv[], unsigned int *dev)
194 {
195 int ret;
196 unsigned long dev_tmp;
197 ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &dev_tmp);
198 if (ret != 0) {
199 printf("parse dev failed.\n");
200 return -1;
201 }
202 *dev = (unsigned int)dev_tmp;
203 return 0;
204 }
205
do_stopvo(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])206 static int do_stopvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
207 {
208 int ret;
209 unsigned int dev;
210 if (argc < 2) { /* max 2 args */
211 printf("insufficient parameter!\n");
212 printf("usage:\n%s\n", cmdtp->usage);
213 return -1;
214 }
215 ret = stopvo_parse(argv, &dev);
216 if (ret != 0) {
217 printf("insufficient parameter!\n");
218 return -1;
219 }
220
221 /* step1: stop vo */
222 ret = stop_vo(dev);
223 if (ret != 0) {
224 printf(INSUFFICIENT_PARAM_STR);
225 return -1;
226 }
227 /* step2: stop intf */
228 do_stop_intf(dev);
229
230 printf("dev %u closed!\n", dev);
231
232 return 0;
233 }
234
start_layer_parse(char * const argv[],unsigned int * layer,unsigned long * addr,unsigned int * strd,hi_rect * layer_rect)235 static int start_layer_parse(char *const argv[], unsigned int *layer,
236 unsigned long *addr, unsigned int *strd, hi_rect *layer_rect)
237 {
238 int ret;
239 unsigned long layer_tmp, addr_tmp, strd_tmp, x_tmp, y_tmp, width_tmp, height_tmp;
240 ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &layer_tmp); /* 1st arg */
241 if (ret != 0) {
242 printf("parse layer failed.\n");
243 return -1;
244 }
245 ret = strict_strtoul(argv[2], CMD_VO_ARGS_BASE16, &addr_tmp); /* 2nd arg */
246 if (ret != 0) {
247 printf("parse addr failed.\n");
248 return -1;
249 }
250 ret = strict_strtoul(argv[3], CMD_VO_ARGS_BASE10, &strd_tmp); /* 3rd arg */
251 if (ret != 0) {
252 printf("parse strd failed.\n");
253 return -1;
254 }
255 ret = strict_strtoul(argv[4], CMD_VO_ARGS_BASE10, &x_tmp); /* 4th arg */
256 if (ret != 0) {
257 printf("parse x failed.\n");
258 return -1;
259 }
260 ret = strict_strtoul(argv[5], CMD_VO_ARGS_BASE10, &y_tmp); /* 5th arg */
261 if (ret != 0) {
262 printf("parse y failed.\n");
263 return -1;
264 }
265 ret = strict_strtoul(argv[6], CMD_VO_ARGS_BASE10, &width_tmp); /* 6th arg */
266 if (ret != 0) {
267 printf("parse width failed.\n");
268 return -1;
269 }
270 ret = strict_strtoul(argv[7], CMD_VO_ARGS_BASE10, &height_tmp); /* 7th arg */
271 if (ret != 0) {
272 printf("parse height failed.\n");
273 return -1;
274 }
275 *layer = (unsigned int)layer_tmp;
276 *addr = addr_tmp;
277 *strd = (unsigned int)strd_tmp;
278 layer_rect->x = (unsigned int)x_tmp;
279 layer_rect->y = (unsigned int)y_tmp;
280 layer_rect->width = (unsigned int)width_tmp;
281 layer_rect->height = (unsigned int)height_tmp;
282 return 0;
283 }
284
start_gx_type_parse(char * const argv[],unsigned int * type)285 static int start_gx_type_parse(char *const argv[], unsigned int *type)
286 {
287 int ret;
288 unsigned long type_tmp;
289 ret = strict_strtoul(argv[8], CMD_VO_ARGS_BASE10, &type_tmp); /* 8th arg */
290 if (ret != 0) {
291 printf("parse type failed.\n");
292 return -1;
293 }
294 *type = (unsigned int)type_tmp;
295 return 0;
296 }
297
do_startgx(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])298 static int do_startgx(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
299 {
300 int ret;
301 unsigned int layer, strd, type;
302 unsigned long addr;
303 hi_rect gx_rect;
304 if (argc < 9) { /* max 9 args */
305 printf("insufficient parameter!\n");
306 printf("usage:\n%s\n", cmdtp->usage);
307 return -1;
308 }
309 ret = start_layer_parse(argv, &layer, &addr, &strd, &gx_rect);
310 if (ret != 0) {
311 printf("insufficient parameter!\n");
312 return -1;
313 }
314
315 ret = start_gx_type_parse(argv, &type);
316 if (ret != 0) {
317 printf("insufficient parameter!\n");
318 return -1;
319 }
320
321 ret = start_gx(layer, addr, strd, gx_rect, type);
322 if (ret != 0) {
323 printf(INSUFFICIENT_PARAM_STR);
324 return -1;
325 }
326
327 printf("graphic layer %u opened!\n", layer);
328
329 return 0;
330 }
331
stopgx_parse(char * const argv[],unsigned int * layer)332 static int stopgx_parse(char *const argv[], unsigned int *layer)
333 {
334 int ret;
335 unsigned long layer_tmp;
336 ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &layer_tmp); /* 1st arg */
337 if (ret != 0) {
338 printf("parse layer failed.\n");
339 return -1;
340 }
341 *layer = (unsigned int)layer_tmp;
342 return 0;
343 }
344
do_stopgx(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])345 static int do_stopgx(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
346 {
347 int ret;
348 unsigned int layer;
349
350 if (argc < 2) { /* max 2 args */
351 printf("insufficient parameter!\n");
352 printf("usage:\n%s\n", cmdtp->usage);
353 return -1;
354 }
355
356 ret = stopgx_parse(argv, &layer);
357 if (ret != 0) {
358 printf("insufficient parameter!\n");
359 return -1;
360 }
361
362 ret = stop_gx(layer);
363 if (ret != 0) {
364 printf(INSUFFICIENT_PARAM_STR);
365 return -1;
366 }
367
368 printf("graphic layer %u closed!\n", layer);
369
370 return 0;
371 }
372
do_startvl(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])373 static int do_startvl(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
374 {
375 int ret;
376 unsigned int layer, strd;
377 unsigned long addr;
378 hi_rect layer_rect;
379
380 if (argc < 8) { /* max 8 args */
381 printf("insufficient parameter!\n");
382 printf("usage:\n%s\n", cmdtp->usage);
383 return -1;
384 }
385
386 ret = start_layer_parse(argv, &layer, &addr, &strd, &layer_rect);
387 if (ret != 0) {
388 printf("insufficient parameter!\n");
389 return -1;
390 }
391
392 ret = start_videolayer(layer, addr, strd, layer_rect);
393 if (ret != 0) {
394 printf(INSUFFICIENT_PARAM_STR);
395 return -1;
396 }
397
398 printf("video layer %u opened!\n", layer);
399
400 return 0;
401 }
402
stopvl_parse(char * const argv[],unsigned int * layer)403 static int stopvl_parse(char *const argv[], unsigned int *layer)
404 {
405 int ret;
406 unsigned long layer_tmp;
407 ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &layer_tmp); /* 1st arg */
408 if (ret != 0) {
409 printf("parse layer failed.\n");
410 return -1;
411 }
412 *layer = (unsigned int)layer_tmp;
413 return 0;
414 }
415
do_stopvl(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])416 static int do_stopvl(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
417 {
418 int ret;
419 unsigned int layer;
420
421 if (argc < 2) { /* max 2 args */
422 printf("insufficient parameter!\n");
423 printf("usage:\n%s\n", cmdtp->usage);
424 return -1;
425 }
426 ret = stopvl_parse(argv, &layer);
427 if (ret != 0) {
428 printf("insufficient parameter!\n");
429 return -1;
430 }
431
432 ret = stop_videolayer(layer);
433 if (ret != 0) {
434 printf(INSUFFICIENT_PARAM_STR);
435 return -1;
436 }
437
438 printf("video layer %u closed!\n", layer);
439
440 return 0;
441 }
442
443 #if ((defined(CHIP_HI3531DV200)) || (defined(CHIP_HI3535AV100)))
444 #define USAGE_DEV_STRING \
445 "\t-<dev> : 0: DHD0,1: DHD1,2: DSD0\n"
446
447 #define USAGE_INTF_STRING \
448 "\t-<intftype>: 1(CVBS),2(VGA),8(BT.1120),16(HDMI)\n" \
449
450 #define USAGE_GX_STRING \
451 "\t-<layer> : 4(G0), 5(G1), 7(G3)\n"
452
453 #define USAGE_VL_STRING \
454 "\t-<layer> : 0(V0), 1(V1), 3(V3)\n"
455
456 #elif (defined(CHIP_HI3521DV200))
457
458 #define USAGE_DEV_STRING \
459 "\t-<dev> : 0: DHD0,1: DHD1,2: DSD0\n"
460
461 #define USAGE_INTF_STRING \
462 "\t-<intftype>: 1(CVBS),2(VGA),4(BT.656),8(BT.1120),16(HDMI)\n" \
463
464 #define USAGE_GX_STRING \
465 "\t-<layer> : 4(G0), 5(G1), 7(G3)\n"
466
467 #define USAGE_VL_STRING \
468 "\t-<layer> : 0(V0), 1(V1), 3(V3)\n"
469
470 #elif (defined(CHIP_HI3520DV500))
471
472 #define USAGE_DEV_STRING \
473 "\t-<dev> : 0: DHD0,2: DSD0\n"
474
475 #define USAGE_INTF_STRING \
476 "\t-<intftype>: 1(CVBS),2(VGA),4(BT.656),8(BT.1120),16(HDMI)\n" \
477 "\t\t128(RGB_16BIT),256(RGB_18BIT),512(RGB_24BIT)\n"
478
479 #define USAGE_GX_STRING \
480 "\t-<layer> : 4(G0), 7(G3)\n"
481
482 #define USAGE_VL_STRING \
483 "\t-<layer> : 0(V0), 3(V3)\n"
484
485 #else
486
487 #define USAGE_DEV_STRING \
488 "\t-<dev> : 0: DHD0,1: DHD1,2: DSD0\n"
489
490 #define USAGE_INTF_STRING \
491 "\t-<intftype>: 1(CVBS),2(VGA),8(BT.1120),16(HDMI)\n" \
492 "\t\t32(RGB_6BIT),64(RGB_8BIT),128(RGB_16BIT),256(RGB_18BIT),512(RGB_24BIT)\n"
493
494 #define USAGE_GX_STRING \
495 "\t-<layer> : 4(G0), 5(G1), 7(G3)\n"
496
497 #define USAGE_VL_STRING \
498 "\t-<layer> : 0(V0), 1(V1), 3(V3)\n"
499
500 #endif
501
502 #define USAGE_GX_TYPE \
503 "\t-<type> : 0(argb1555), 1(bmp1555)\n"
504
505 #define USAGE_START_VO \
506 "\nargs: [dev, intftype, sync]\n" \
507 USAGE_DEV_STRING \
508 USAGE_INTF_STRING \
509 "\t-<sync>:\n" \
510 "\t\t0(PAL), 1(NTSC), 2(960H_PAL), 3(960H_NTSC)\n" \
511 "\t\t4(640x480_60), 5(480P60), 6(576P50), 7(800x600_60)\n" \
512 "\t\t8(1024x768_60), 9(720P50), 10(720P60), 11(1280x800_60)\n" \
513 "\t\t12(1280x1024_60),13(1366x768_60), 14(1400x1050_60),15(1440x900_60)\n" \
514 "\t\t16(1600x1200_60),17(1680x1050_60),18(1080P24), 19(1080P25)\n" \
515 "\t\t20(1080P30), 21(1080I50), 22(1080I60), 23(1080P50)\n" \
516 "\t\t24(1080P60), 25(1920x1200_60),26(1920x2160_30),27(2560x1440_30)\n" \
517 "\t\t28(2560x1440_60),29(2560x1600_60),30(3840x2160_24),31(3840x2160_25)\n" \
518 "\t\t32(3840x2160_30),33(3840x2160_50),34(3840x2160_60),35(4096x2160_24)\n" \
519 "\t\t36(4096x2160_25),37(4096x2160_30),38(4096x2160_50),39(4096x2160_60)\n" \
520 "\t\t40(7680x4320_30),41(240x320_50), 42(320x240_50), 43(240x320_60)\n" \
521 "\t\t44(320x240_60), 45(800x600_50), 46(720x1280_60), 47(1080x1920_60)\n" \
522 "\t\t48(user)\n"
523
524 #define USAGE_STOP_VO \
525 "\nargs: [dev]\n" \
526 USAGE_DEV_STRING
527
528 #define USAGE_START_GX \
529 "\nargs: [layer, addr, stride, x, y, w, h, type]\n" \
530 USAGE_GX_STRING \
531 "\t-<addr> : picture address\n" \
532 "\t-<stride> : picture stride\n" \
533 "\t-<x,y,w,h> : display area\n" \
534 USAGE_GX_TYPE
535
536 #define USAGE_STOP_GX \
537 "\nargs: [layer]\n" \
538 USAGE_GX_STRING
539
540 #define USAGE_START_VL \
541 "\nargs: [layer, addr, stride, x, y, w, h]\n" \
542 USAGE_VL_STRING \
543 "\t-<addr> : picture address\n" \
544 "\t-<stride> : picture stride\n" \
545 "\t-<x,y,w,h> : display area\n"
546
547 #define USAGE_STOP_VL \
548 "\nargs: [layer]\n" \
549 USAGE_VL_STRING
550
551 #define USAGE_SET_VO_BG \
552 "\nargs: [dev, color]\n" \
553 USAGE_DEV_STRING \
554 "\t-<color>: rgb color space\n"
555
556 U_BOOT_CMD(startvo, CFG_MAXARGS_STARTVO, 1, do_startvo,
557 "startvo - open vo device with a certain output interface.\n"
558 "\t- startvo [dev intftype sync]", USAGE_START_VO);
559
560 U_BOOT_CMD(stopvo, CFG_MAXARGS_STOPVO, 1, do_stopvo,
561 "stopvo - close interface of vo device.\n"
562 "\t- stopvo [dev]", USAGE_STOP_VO);
563
564 U_BOOT_CMD(startgx, CFG_MAXARGS_STARTGX, 1, do_startgx,
565 "startgx - open graphics layer.\n"
566 "\t- startgx [layer addr stride x y w h type]", USAGE_START_GX);
567
568 U_BOOT_CMD(stopgx, CFG_MAXARGS_STOPGX, 1, do_stopgx,
569 "stopgx - close graphics layer.\n"
570 "\t- stopgx [layer]", USAGE_STOP_GX);
571
572 U_BOOT_CMD(startvl, CFG_MAXARGS_STARTVL, 1, do_startvl,
573 "startvl - open video layer.\n"
574 "\t- startvl [layer addr stride x y w h]", USAGE_START_VL);
575
576 U_BOOT_CMD(stopvl, CFG_MAXARGS_STOPVL, 1, do_stopvl,
577 "stopvl - close video layer.\n"
578 "\t- stopvl [layer]", USAGE_STOP_VL);
579
580 U_BOOT_CMD(setvobg, CFG_MAXARGS_SETVOBG, 1, do_vobg,
581 "setvobg - set vo backgroud color.\n"
582 "\t- setvobg [dev color]", USAGE_SET_VO_BG);
583