• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hi3519av100_vo.h"
22 
23 #define CMD_VO_ARGS_BASE10 10
24 #define CMD_VO_ARGS_BASE16 16
25 #define CMD_VO_ARGS_BASE_ALL 0
26 
27 extern int set_vobg(unsigned int dev, unsigned int rgb);
28 extern int start_vo(unsigned int dev, unsigned int type, unsigned int sync);
29 extern int stop_vo(unsigned int dev);
30 extern int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect layer_rect);
31 extern int stop_videolayer(unsigned int layer);
32 
33 extern int hdmi_display(unsigned int vosync, unsigned int input, unsigned int output);
34 extern void hdmi_stop(void);
35 
36 extern int mipi_tx_display(unsigned int vosync);
37 extern int mipi_tx_stop(void);
38 
39 extern int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect gx_rect);
40 extern int stop_gx(unsigned int layer);
41 
42 #define VO_DEV_MAX_NUM         3
43 static unsigned int g_a_interface_type[VO_DEV_MAX_NUM] = {[0 ... (VO_DEV_MAX_NUM - 1)] = 0};
44 
check_vo_support(unsigned int dev,unsigned int type,unsigned int sync)45 static int check_vo_support(unsigned int dev, unsigned int type, unsigned int sync)
46 {
47     /* check interface type, ONLY VGA & HDMI interface is supported. */
48     if (dev == VO_DEV_DHD0) {
49         if ((type & ~(VO_INTF_HDMI | VO_INTF_BT1120 | VO_INTF_BT656 | VO_INTF_MIPI | VO_INTF_MIPI_SLAVE)) ||
50             (type == 0)) {
51             printf("hd%u only supports HDMI, BT.656, BT.1120, mipi_tx intftype, intf %u is illegal!\n", dev, type);
52             return -1;
53         }
54         /* just one interface at the the time for a dev. */
55         if (type & ~(VO_INTF_HDMI | VO_INTF_BT1120) &&
56             (type & ~(VO_INTF_HDMI | VO_INTF_MIPI)) &&
57             (type & ~VO_INTF_BT656) &&
58             (type & ~VO_INTF_MIPI_SLAVE)) {
59             printf("for VO %u, only HDMI and BT.1120 can be used at the same time!\n", dev);
60             return -1;
61         }
62     } else if (dev == VO_DEV_DHD1) {
63         if ((type
64              & ~(VO_INTF_BT1120 | VO_INTF_BT656 | VO_INTF_MIPI |
65              VO_INTF_MIPI_SLAVE | VO_INTF_LCD_6BIT | VO_INTF_LCD_8BIT |
66              VO_INTF_LCD_16BIT | VO_INTF_LCD_18BIT | VO_INTF_LCD_24BIT)) ||
67             (type == 0)) {
68             printf("hd%u only supports BT.656, BT.1120, mipi_tx, LCD intftype, intf %u is illegal!\n", dev, type);
69             return -1;
70         }
71         /* just one interface at the the time for a dev. */
72         if (
73             (type & ~VO_INTF_BT1120) && (type & ~VO_INTF_BT656) &&
74             (type & ~VO_INTF_MIPI) && (type & ~VO_INTF_MIPI_SLAVE) &&
75             (type & ~VO_INTF_LCD_6BIT) && (type & ~VO_INTF_LCD_8BIT) &&
76             (type & ~VO_INTF_LCD_16BIT) && (type & ~VO_INTF_LCD_18BIT) &&
77             (type & ~VO_INTF_LCD_24BIT)
78         ) {
79             printf("vo(%u), none of (BT.1120,BT.656,MIPI,LCD) can use at the same time!\n", dev);
80             return -1;
81         }
82     } else {
83         printf("unknow dev(%u)!\n", dev);
84         return -1;
85     }
86 
87     if (VO_INTF_HDMI & type) {
88         if (!(((sync >= VO_OUTPUT_1080P24) && (sync <= VO_OUTPUT_640x480_60))  ||
89               ((sync >= VO_OUTPUT_1920x2160_30) && (sync <= VO_OUTPUT_4096x2160_60)))) {
90             printf("vo%u's intfsync %u illegal!\n", dev, sync);
91             return -1;
92         }
93     }
94 
95     if (VO_INTF_BT1120 & type) {
96         if ((sync < VO_OUTPUT_1080P24) ||
97             (sync > VO_OUTPUT_7680x4320_30)) {
98             printf("vo%u's intfsync %u illegal!\n", dev, sync);
99             return -1;
100         }
101     }
102 
103     if ((VO_INTF_MIPI & type) || (VO_INTF_MIPI_SLAVE & type)) {
104         if (dev == VO_DEV_DHD0) {
105             if ((sync != VO_OUTPUT_576P50) &&
106                 (sync != VO_OUTPUT_720P50) &&
107                 (sync != VO_OUTPUT_720P60) &&
108                 (sync != VO_OUTPUT_1024x768_60) &&
109                 (sync != VO_OUTPUT_1280x1024_60) &&
110                 (sync != VO_OUTPUT_720x1280_60) &&
111                 (sync != VO_OUTPUT_1080x1920_60) &&
112                 (sync != VO_OUTPUT_1080P60) &&
113                 (sync != VO_OUTPUT_3840x2160_30) &&
114                 (sync != VO_OUTPUT_3840x2160_60)) {
115                 printf("for MIPI(mipi_tx) intface, vo%u's intfsync %u illegal!\n", dev, sync);
116                 return -1;
117             }
118         } else if (dev == VO_DEV_DHD1) {
119             if ((sync != VO_OUTPUT_576P50) &&
120                 (sync != VO_OUTPUT_720P50) &&
121                 (sync != VO_OUTPUT_720P60) &&
122                 (sync != VO_OUTPUT_1024x768_60) &&
123                 (sync != VO_OUTPUT_1280x1024_60) &&
124                 (sync != VO_OUTPUT_720x1280_60) &&
125                 (sync != VO_OUTPUT_1080x1920_60) &&
126                 (sync != VO_OUTPUT_1080P60)) {
127                 printf("for MIPI(mipi_tx) intface, vo%u's intfsync %u illegal! \n", dev, sync);
128                 return -1;
129             }
130         }
131     }
132 
133     if (type == (VO_INTF_HDMI | VO_INTF_MIPI)) {
134         if ((sync == VO_OUTPUT_576P50) ||
135             (sync == VO_OUTPUT_1024x768_60)) {
136             printf("when HDMI+MIPI, not support 576P50 or 1024x768_60\n");
137             return -1;
138         }
139     }
140 
141     return 0;
142 }
143 
do_vobg(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])144 static int do_vobg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
145 {
146     unsigned int dev, rgb;
147 
148     if (argc < 3) {
149         printf("insufficient parameter!\n");
150         printf ("usage:\n%s\n", cmdtp->usage);
151         return -1;
152     }
153 
154     dev = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
155     rgb = (unsigned int)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE_ALL);
156     if (dev >= VO_DEV_BUTT) {
157         printf("invalid parameter!\n");
158         return -1;
159     }
160 
161     set_vobg(dev, rgb);
162 
163     printf("dev %u set background color!\n", dev);
164 
165     return 0;
166 }
167 
do_startvo(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])168 static int do_startvo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
169 {
170     unsigned int dev, intftype, sync;
171 
172     if (argc < 4) {
173         printf("insufficient parameter!\n");
174         printf ("usage:\n%s\n", cmdtp->usage);
175         return -1;
176     }
177 
178     dev      = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
179     intftype = (unsigned int)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE10);
180     sync     = (unsigned int)simple_strtoul(argv[3], NULL, CMD_VO_ARGS_BASE10);
181     if ((dev >= VO_DEV_BUTT) || (sync >= VO_OUTPUT_BUTT)) {
182         printf("invalid parameter!\n");
183         return -1;
184     }
185 
186     if (check_vo_support(dev, intftype, sync)) {
187         printf("unsupport parameter!\n");
188         return -1;
189     }
190 
191     start_vo(dev, intftype, sync);
192 
193     g_a_interface_type[dev] =  intftype;
194 
195     if (intftype & VO_INTF_HDMI) {
196         if (intftype == (VO_INTF_HDMI | VO_INTF_MIPI)) {
197             hdmi_display(sync, 0, 2);
198         } else {
199             hdmi_display(sync, 2, 2);
200         }
201     }
202 
203     if (intftype & VO_INTF_MIPI) {
204         /* to call mipi_display. */
205         mipi_tx_display(sync);
206     }
207 
208     printf("dev %u opened!\n", dev);
209 
210     return 0;
211 }
212 
do_stopvo(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])213 static int do_stopvo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
214 {
215     unsigned int dev;
216     if (argc < 2) {
217         printf("insufficient parameter!\n");
218         printf ("usage:\n%s\n", cmdtp->usage);
219         return -1;
220     }
221 
222     dev = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
223     if (dev >= VO_DEV_BUTT) {
224         printf("invalid parameter!\n");
225         return -1;
226     }
227 
228     if (g_a_interface_type[dev] & VO_INTF_HDMI) {
229         g_a_interface_type[dev] = 0;
230         hdmi_stop();
231     }
232 
233     if (g_a_interface_type[dev] & VO_INTF_MIPI) {
234         mipi_tx_stop();
235     }
236 
237     stop_vo(dev);
238 
239     printf("dev %u closed!\n", dev);
240 
241     return 0;
242 }
243 
do_startvl(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])244 static int do_startvl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
245 {
246     unsigned int layer, strd, x, y, w, h;
247     unsigned long addr;
248     hi_vo_rect layer_rect;
249     int max_x, max_y, layer_max_w, layer_max_h;
250 
251     if (argc < 8) {
252         printf("insufficient parameter!\n");
253         printf ("usage:\n%s\n", cmdtp->usage);
254         return -1;
255     }
256 
257     layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
258     addr  = (unsigned long)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE16);
259     strd  = (unsigned int)simple_strtoul(argv[3], NULL, CMD_VO_ARGS_BASE10);
260     x     = (unsigned int)simple_strtoul(argv[4], NULL, CMD_VO_ARGS_BASE10);
261     y     = (unsigned int)simple_strtoul(argv[5], NULL, CMD_VO_ARGS_BASE10);
262     w     = (unsigned int)simple_strtoul(argv[6], NULL, CMD_VO_ARGS_BASE10);
263     h     = (unsigned int)simple_strtoul(argv[7], NULL, CMD_VO_ARGS_BASE10);
264 
265     if (layer == VO_LAYER_VHD0) {
266         max_x = VHD0_PIC_MAX_WIDTH;
267         max_y = VHD0_PIC_MAX_HEIGHT;
268         layer_max_w = VHD0_PIC_MAX_WIDTH;
269         layer_max_h = VHD0_PIC_MAX_HEIGHT;
270     } else if (layer == VO_LAYER_VHD1) {
271         max_x =VHD1_PIC_MAX_WIDTH;
272         max_y = VHD1_PIC_MAX_HEIGHT;
273         layer_max_w = VHD1_PIC_MAX_WIDTH;
274         layer_max_h = VHD1_PIC_MAX_HEIGHT;
275     } else {
276         printf("invalid parameter!\n");
277         return -1;
278     }
279 
280     if((strd > (layer_max_w * 2)) ||
281         (x > max_x) || (x & 0x1) ||
282         (y > max_y) || (y & 0x1) ||
283         (w > layer_max_w) || (w & 0x1) || (w < PIC_MIN_LENTH) ||
284         (h > layer_max_h) || (h & 0x1) || (h < PIC_MIN_LENTH)) {
285         printf("invalid parameter!\n");
286         return -1;
287     }
288 
289 
290     layer_rect.x = x;
291     layer_rect.y = y;
292     layer_rect.w = w;
293     layer_rect.h = h;
294 
295     start_videolayer(layer, addr, strd, layer_rect);
296 
297     printf("video layer %u opened!\n", layer);
298 
299     return 0;
300 }
301 
do_stopvl(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])302 static int do_stopvl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
303 {
304     unsigned int layer;
305 
306     if (argc < 2) {
307         printf("insufficient parameter!\n");
308         printf ("usage:\n%s\n", cmdtp->usage);
309         return -1;
310     }
311 
312     layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
313 
314     if ((layer > VO_LAYER_VSD0) || (layer == VO_LAYER_VP)) {
315         printf("invalid parameter!\n");
316         return -1;
317     }
318 
319     stop_videolayer(layer);
320 
321     printf("video layer %u closed!\n", layer);
322 
323     return 0;
324 }
325 
do_startgx(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])326 static int do_startgx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
327 {
328     unsigned int layer, strd, x, y, w, h;
329     unsigned long addr;
330     hi_vo_rect gx_rect;
331     int max_x, max_y, layer_max_w, layer_max_h;
332     if (argc < 8) {
333         printf("insufficient parameter!\n");
334         printf ("usage:\n%s\n", cmdtp->usage);
335         return -1;
336     }
337 
338     layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
339     addr  = (unsigned long)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE16);
340     strd  = (unsigned int)simple_strtoul(argv[3], NULL, CMD_VO_ARGS_BASE10);
341     x     = (unsigned int)simple_strtoul(argv[4], NULL, CMD_VO_ARGS_BASE10);
342     y     = (unsigned int)simple_strtoul(argv[5], NULL, CMD_VO_ARGS_BASE10);
343     w     = (unsigned int)simple_strtoul(argv[6], NULL, CMD_VO_ARGS_BASE10);
344     h     = (unsigned int)simple_strtoul(argv[7], NULL, CMD_VO_ARGS_BASE10);
345 
346     if (layer == VO_GRAPHC_G0) {
347         max_x =GFX0_PIC_MAX_WIDTH;
348         max_y = GFX0_PIC_MAX_HEIGHT;
349         layer_max_w = GFX0_PIC_MAX_WIDTH;
350         layer_max_h = GFX0_PIC_MAX_HEIGHT;
351     } else if (layer == VO_GRAPHC_G1) {
352         max_x =GFX1_PIC_MAX_WIDTH;
353         max_y = GFX1_PIC_MAX_HEIGHT;
354         layer_max_w = GFX1_PIC_MAX_WIDTH;
355         layer_max_h = GFX1_PIC_MAX_HEIGHT;
356     } else {
357         printf("invalid parameter!\n");
358         return -1;
359     }
360 
361     if((strd > (layer_max_w * 2)) ||
362         (x > max_x) || (x & 0x1) ||
363         (y > max_y) || (y & 0x1) ||
364         (w > layer_max_w) || (w & 0x1) || (w < PIC_MIN_LENTH) ||
365         (h > layer_max_h) || (h & 0x1) || (h < PIC_MIN_LENTH)) {
366         printf("invalid parameter!\n");
367         return -1;
368     }
369 
370     gx_rect.x = x;
371     gx_rect.y = y;
372     gx_rect.w = w;
373     gx_rect.h = h;
374 
375     start_gx(layer, addr, strd, gx_rect);
376 
377     printf("graphic layer %u opened!\n", layer);
378 
379     return 0;
380 }
381 
do_stopgx(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])382 static int do_stopgx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
383 {
384     unsigned int layer;
385 
386     if (argc < 2) {
387         printf("insufficient parameter!\n");
388         printf ("usage:\n%s\n", cmdtp->usage);
389         return -1;
390     }
391 
392     layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
393 
394     if (layer >= VO_GRAPHC_BUTT) {
395         printf("invalid parameter!\n");
396         return -1;
397     }
398 
399     stop_gx(layer);
400 
401     printf("graphic layer %u closed!\n", layer);
402 
403     return 0;
404 }
405 
406 U_BOOT_CMD(
407     startvo,    CFG_MAXARGS,    1,  do_startvo,
408     "startvo   - open vo device with a certain output interface.\n"
409     "\t- startvo [dev intftype sync]",
410     "\nargs: [dev, intftype, sync]\n"
411     "\t-<dev> : 0: DHD0,1: DHD1\n"
412     "\t-<intftype>: 8(BT.656),16(BT.1120),32(HDMI),16384(mipi_tx)\n"
413     "\t-<sync>: typical value:\n"
414     "\t\t0(PAL),          1(NTSC),         4(1080P30),      6(720P60)\n"
415     "\t\t10(1080P60),     21(1920x1200),   26(2560x1440_30),31(3840x2160_30)\n"
416     "\t\t33(3840x2160_60),45(1080x1920_60),47(user)\n");
417 
418 U_BOOT_CMD(
419     stopvo,    CFG_MAXARGS,    1,  do_stopvo,
420     "stopvo   - close interface of vo device.\n"
421     "\t- stopvo [dev]",
422     "\nargs: [dev]\n"
423     "\t-<dev> : 0~1(HD0~HD1)\n");
424 
425 U_BOOT_CMD(
426     startvl,    CFG_MAXARGS,    1,  do_startvl,
427     "startvl   - open video layer.\n"
428     "\t- startvl [layer addr stride x y w h]\n",
429     "\nargs: [layer, addr, stride, x, y, w, h]\n"
430     "\t-<layer>   : 0(V0), 1(V1)\n"
431     "\t-<addr>    : picture address\n"
432     "\t-<stride>  : picture stride\n"
433     "\t-<x,y,w,h> : display area\n");
434 
435 U_BOOT_CMD(
436     stopvl,    CFG_MAXARGS,    1,  do_stopvl,
437     "stopvl   - close video layer.\n"
438     "\t- stopvl [layer]",
439     "\nargs: [layer]\n"
440     "\t-<layer> : 0(V0), 1(V1)\n");
441 
442 U_BOOT_CMD(
443     setvobg,    CFG_MAXARGS,    1,  do_vobg,
444     "setvobg   - set vo backgroud color.\n"
445     "\t- setvobg [dev color]",
446     "\nargs: [dev, color]\n"
447     "\t-<dev> : 0~1(HD0~1)\n"
448     "\t-<color>: rgb color space\n");
449 
450 U_BOOT_CMD(
451     startgx,    CFG_MAXARGS,    1,  do_startgx,
452     "startgx   - open graphics layer.\n"
453     "\t- startgx [layer addr stride x y w h]\n",
454     "\nargs: [layer, addr, stride, x, y, w, h]\n"
455     "\t-<layer>   : 0(G0), 1(G1)\n"
456     "\t-<addr>    : picture address\n"
457     "\t-<stride>  : picture stride\n"
458     "\t-<x,y,w,h> : display area\n");
459 
460 U_BOOT_CMD(
461     stopgx,    CFG_MAXARGS,    1,  do_stopgx,
462     "stopgx   - close graphics layer.\n"
463     "\t- stopgx [layer]",
464     "\nargs: [layer]\n"
465     "\t-<layer> : 0(G0), 1(G1)\n");
466