/* * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include "hi3516ev200_vo.h" #define CMD_VO_ARGS_BASE10 10 #define CMD_VO_ARGS_BASE16 16 #define CMD_VO_ARGS_BASE_ALL 0 extern int set_vobg(unsigned int dev, unsigned int rgb); extern int start_vo(unsigned int dev, unsigned int type, unsigned int sync); extern int stop_vo(unsigned int dev); extern int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect layer_rect); extern int stop_videolayer(unsigned int layer); extern int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, hi_vo_rect gx_rect); extern int stop_gx(unsigned int layer); static int check_vo_support(unsigned int dev, unsigned int type, unsigned int sync) { /* check interface type, ONLY VGA & HDMI interface is supported. */ if (dev == VO_DEV_DHD0) { if ((type & (~(VO_INTF_BT1120 | VO_INTF_BT656 | VO_INTF_LCD_6BIT | VO_INTF_LCD_8BIT | VO_INTF_LCD_16BIT))) || (type == 0)) { printf("hd%u only supports BT.656,BT.1120,LCD_6BIT/8BIT/16BIT intftype, intf %u is illegal!\n", dev, type); return -1; } } else { printf("unknow dev(%u)!\n", dev); return -1; } if (sync == VO_OUTPUT_USER) { return 0; } if (VO_INTF_BT1120 & type) { if ((((sync < VO_OUTPUT_1080P24) && (sync > VO_OUTPUT_1080I60)) || ((sync < VO_OUTPUT_576P50) && (sync > VO_OUTPUT_1024x768_60))) && (sync != VO_OUTPUT_640x480_60)) { printf("vo%u's intfsync %u illegal!\n", dev, sync); return -1; } } if (VO_INTF_BT656 & type) { if ((sync != VO_OUTPUT_PAL) && (sync != VO_OUTPUT_NTSC)) { printf("vo%u's intfsync %u illegal!\n", dev, sync); return -1; } } if (VO_INTF_LCD_8BIT & type) { if (VO_OUTPUT_320x240_60 != sync) { printf("vo%u's intfsync %u illegal!\n", dev, sync); return -1; } } if (VO_INTF_LCD_6BIT & type) { if ((sync < VO_OUTPUT_320x240_50) || (sync > VO_OUTPUT_240x320_50)) { printf("vo%u's intfsync %u illegal!\n", dev, sync); return -1; } } if (VO_INTF_LCD_16BIT & type) { if (VO_OUTPUT_240x320_60 != sync) { printf("vo%u's intfsync %u illegal!\n", dev, sync); return -1; } } return 0; } static int do_vobg(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { unsigned int dev, rgb; if (argc < 3) { printf("insufficient parameter!\n"); printf("usage:\n%s\n", cmdtp->usage); return -1; } dev = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10); rgb = (unsigned int)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE_ALL); if (dev >= VO_DEV_BUTT) { printf("invalid parameter!\n"); return -1; } set_vobg(dev, rgb); printf("dev %u set background color!\n", dev); return 0; } static int do_startvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { unsigned int dev, intftype, sync; if (argc < 4) { printf("insufficient parameter!\n"); printf("usage:\n%s\n", cmdtp->usage); return -1; } dev = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10); intftype = (unsigned int)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE10); sync = (unsigned int)simple_strtoul(argv[3], NULL, CMD_VO_ARGS_BASE10); if ((dev >= VO_DEV_BUTT) || (sync >= VO_OUTPUT_BUTT)) { printf("invalid parameter!\n"); return -1; } if (check_vo_support(dev, intftype, sync)) { printf("unsupport parameter!\n"); return -1; } start_vo(dev, intftype, sync); printf("dev %u opened!\n", dev); return 0; } static int do_stopvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { unsigned int dev; if (argc < 2) { printf("insufficient parameter!\n"); printf("usage:\n%s\n", cmdtp->usage); return -1; } dev = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10); if (dev >= VO_DEV_BUTT) { printf("invalid parameter!\n"); return -1; } stop_vo(dev); printf("dev %u closed!\n", dev); return 0; } static int do_startvl(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { unsigned int layer, strd, x, y, w, h; unsigned long addr; hi_vo_rect layer_rect; if (argc < 8) { printf("insufficient parameter!\n"); printf("usage:\n%s\n", cmdtp->usage); return -1; } layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10); addr = (unsigned long)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE16); strd = (unsigned int)simple_strtoul(argv[3], NULL, CMD_VO_ARGS_BASE10); x = (unsigned int)simple_strtoul(argv[4], NULL, CMD_VO_ARGS_BASE10); y = (unsigned int)simple_strtoul(argv[5], NULL, CMD_VO_ARGS_BASE10); w = (unsigned int)simple_strtoul(argv[6], NULL, CMD_VO_ARGS_BASE10); h = (unsigned int)simple_strtoul(argv[7], NULL, CMD_VO_ARGS_BASE10); if ((layer != VO_LAYER_VHD0) || (strd > (PIC_MAX_WIDTH * 2)) || ((x > PIC_MAX_WIDTH) || (x & 0x1)) || ((y > PIC_MAX_HEIGHT) || (y & 0x1)) || ((w > PIC_MAX_WIDTH) || (w & 0x1) || (w < PIC_MIN_LENTH)) || ((h > PIC_MAX_HEIGHT) || (h & 0x1) || (h < PIC_MIN_LENTH))) { printf("invalid parameter!\n"); return -1; } layer_rect.x = x; layer_rect.y = y; layer_rect.w = w; layer_rect.h = h; start_videolayer(layer, addr, strd, layer_rect); printf("video layer %u opened!\n", layer); return 0; } static int do_stopvl(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { unsigned int layer; if (argc < 2) { printf("insufficient parameter!\n"); printf("usage:\n%s\n", cmdtp->usage); return -1; } layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10); if (layer > VO_LAYER_VHD0) { printf("invalid parameter!\n"); return -1; } stop_videolayer(layer); printf("video layer %u closed!\n", layer); return 0; } static int do_startgx(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { unsigned int layer, strd, x, y, w, h; unsigned long addr; hi_vo_rect gx_rect; if (argc < 8) { printf("insufficient parameter!\n"); printf("usage:\n%s\n", cmdtp->usage); return -1; } layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10); addr = (unsigned long)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE16); strd = (unsigned int)simple_strtoul(argv[3], NULL, CMD_VO_ARGS_BASE10); x = (unsigned int)simple_strtoul(argv[4], NULL, CMD_VO_ARGS_BASE10); y = (unsigned int)simple_strtoul(argv[5], NULL, CMD_VO_ARGS_BASE10); w = (unsigned int)simple_strtoul(argv[6], NULL, CMD_VO_ARGS_BASE10); h = (unsigned int)simple_strtoul(argv[7], NULL, CMD_VO_ARGS_BASE10); if ((layer != VO_GRAPHC_G0) || ((x > PIC_MAX_WIDTH) || (x & 0x1)) || ((y > PIC_MAX_HEIGHT) || (y & 0x1)) || ((w > PIC_MAX_WIDTH) || (w & 0x1) || (w < PIC_MIN_LENTH)) || ((h > PIC_MAX_HEIGHT) || (h & 0x1) || (h < PIC_MIN_LENTH))) { printf("invalid parameter!\n"); return -1; } gx_rect.x = x; gx_rect.y = y; gx_rect.w = w; gx_rect.h = h; start_gx(layer, addr, strd, gx_rect); printf("graphic layer %u opened!\n", layer); return 0; } static int do_stopgx(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { unsigned int layer; if (argc < 2) { printf("insufficient parameter!\n"); printf("usage:\n%s\n", cmdtp->usage); return -1; } layer = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10); if (layer >= VO_GRAPHC_BUTT) { printf("invalid parameter!\n"); return -1; } stop_gx(layer); printf("graphic layer %u closed!\n", layer); return 0; } U_BOOT_CMD(startvo, CFG_MAXARGS, 1, do_startvo, "startvo - open vo device with a certain output interface.\n" "\t- startvo [dev intftype sync]", "\nargs: [dev, intftype, sync]\n" "\t- : 0: DHD0\n" "\t-: 8(BT.656),16(BT.1120),512(LCD_6BIT),1024(LCD_8BIT),2048(LCD_16BIT)\n" "\t-: typical value:\n" "\t\tfor BT.656:\n" "\t\t\t0(PAL), 1(NTSC)\n" "\t\tfor BT.1120:\n" "\t\t\t2(1080P24), 3(1080P25), 4(1080P30), 5(720P50)\n" "\t\t\t6(720P60), 7(1080I50), 8(1080I60), 11(576P50)\n" "\t\t\t12(480P60), 13(800x600), 14(1024x768), 22(640x480)\n" "\t\tfor LCD:\n" "\t\t\t39(320x240P60), 40(320x240P50), 41(240x320P50), 42(240x320P60)\n"); U_BOOT_CMD(stopvo, CFG_MAXARGS, 1, do_stopvo, "stopvo - close interface of vo device.\n" "\t- stopvo [dev]", "\nargs: [dev]\n" "\t- : 0(HD0)\n"); U_BOOT_CMD(startvl, CFG_MAXARGS, 1, do_startvl, "startvl - open video layer.\n" "\t- startvl [layer addr stride x y w h]\n", "\nargs: [layer, addr, stride, x, y, w, h]\n" "\t- : 0(V0)\n" "\t- : picture address\n" "\t- : picture stride\n" "\t- : display area\n"); U_BOOT_CMD(stopvl, CFG_MAXARGS, 1, do_stopvl, "stopvl - close video layer.\n" "\t- stopvl [layer]", "\nargs: [layer]\n" "\t- : 0(V0)\n"); U_BOOT_CMD(setvobg, CFG_MAXARGS, 1, do_vobg, "setvobg - set vo backgroud color.\n" "\t- setvobg [dev color]", "\nargs: [dev, color]\n" "\t- : 0(HD0)\n" "\t-: rgb color space\n"); U_BOOT_CMD(startgx, CFG_MAXARGS, 1, do_startgx, "startgx - open graphics layer.\n" "\t- startgx [layer addr stride x y w h]\n", "\nargs: [layer, addr, stride, x, y, w, h]\n" "\t- : 0(G0)\n" "\t- : picture address\n" "\t- : picture stride\n" "\t- : display area\n"); U_BOOT_CMD(stopgx, CFG_MAXARGS, 1, do_stopgx, "stopgx - close graphics layer.\n" "\t- stopgx [layer]", "\nargs: [layer]\n" "\t- : 0(G0)\n");