Files

867 lines
22 KiB
C

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <common.h>
#include <command.h>
#include <environment.h>
#include <malloc.h>
#include <asm/byteorder.h>
#include <amlogic/cpu_id.h>
#ifdef CONFIG_ARMV8_MULTIENTRY
#include <asm/arch-meson/smp.h>
#endif
#ifdef CONFIG_AML_VPP
#include <amlogic/media/vpp/vpp.h>
#else
#define VPP_CM_RGB 0
#define VPP_CM_YUV 2
#define VPP_CM_CrYCb 4
#define VPP_CM_INVALID 0xff
__weak void vpp_matrix_update(int cfmt) {}
__weak void vpp_viu2_matrix_update(int cfmt) {}
__weak void vpp_viu3_matrix_update(int cfmt) {}
#endif
#include <amlogic/media/vout/aml_vout.h>
#ifdef CONFIG_AML_LCD
#include <amlogic/media/vout/lcd/aml_lcd.h>
#endif
#ifdef CONFIG_AML_eDPTX
#include <amlogic/media/vout/eDPTX/DPTX_export.h>
#endif
#ifdef CONFIG_AML_HDMITX
#include <amlogic/media/vout/hdmitx21/hdmitx_ext.h>
#ifdef CONFIG_AML_HDMITX20
#include <amlogic/media/vout/hdmitx/hdmitx.h>
#else
#include <amlogic/media/vout/hdmitx21/hdmitx.h>
#endif
#endif
#ifdef CONFIG_AML_CVBS
#include <amlogic/media/vout/aml_cvbs.h>
#endif
#if defined(CONFIG_AML_CVBS) || defined(CONFIG_AML_HDMITX) || defined(CONFIG_AML_LCD)
static unsigned int vpp_viu1_cm_state = VPP_CM_INVALID;
#endif
static int do_vout_output_job(unsigned char vout_idx, char *mode_str);
int aml_vout_output(uint8_t vout_idx, char *mode)
{
unsigned short on_connector_dev = vout_connector_check(vout_idx);
#ifdef CONFIG_AML_LCD
unsigned int venc_index = on_connector_dev & 0xf;
#endif
#if defined(CONFIG_AML_CVBS) || defined(CONFIG_AML_HDMITX) || \
defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
unsigned int mux_sel = VIU_MUX_MAX, venc_sel = VIU_MUX_MAX;
#endif
int ret = -1;
if (!mode)
return -1;
switch (on_connector_dev & CONNECTOR_DEV_MASK) {
case CONNECTOR_DEV_LCD:
#ifdef CONFIG_AML_LCD
mux_sel = aml_lcd_driver_outputmode_check(venc_index, mode);
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCL)
break;
aml_lcd_driver_enable(venc_index, mode);
ret = 0;
#endif
break;
case CONNECTOR_DEV_eDP:
if (env_get_ulong("eDP_use_legacy_lcd_driver", 10, 0)) {
#ifdef CONFIG_AML_LCD
mux_sel = aml_lcd_driver_outputmode_check(venc_index, mode);
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCL)
break;
aml_lcd_driver_enable(venc_index, mode);
ret = 0;
#endif
} else {
#ifdef CONFIG_AML_eDPTX
mux_sel = dptx_driver_outputmode_check(venc_index, mode);
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCL)
break;
dptx_driver_enable(venc_index, mode);
ret = 0;
#endif
}
break;
case CONNECTOR_DEV_HDMI:
#ifdef CONFIG_AML_HDMITX
mux_sel = hdmi_outputmode_check(mode, 0);
venc_sel = mux_sel & 0xf;
if (venc_sel >= VIU_MUX_MAX)
break;
//ret = aml_hdmitx_output(mode);
printf("\nhdmi not support smp on yet\n");
#endif
break;
case CONNECTOR_DEV_CVBS:
#ifdef CONFIG_AML_CVBS
mux_sel = cvbs_outputmode_check(mode);
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCI)
break;
ret = cvbs_set_vmode(mode);
#endif
break;
default:
break;
}
return ret;
}
#ifdef CONFIG_ARMV8_MULTIENTRY
//param bit[0:7]:curr vout idx; bit[8]:smp;
static void aml_display_on_post_job(unsigned long param)
{
if ((param & 0xf) == 0)
aml_vout_output(0, env_get("outputmode"));
else if ((param & 0xf) == 1)
aml_vout_output(1, env_get("outputmode2"));
else if ((param & 0xf) == 2)
aml_vout_output(2, env_get("outputmode3"));
printf("display[%lu] on post done\n", param);
if (param & 0x100)
secondary_off();
}
#endif
#ifndef VOUT_HDMITX_HPD_CHECK_CMD
#define VOUT_HDMITX_HPD_CHECK_CMD ""
#endif
#ifndef VOUT_OSD_LOGO_CMD
#define VOUT_OSD_LOGO_CMD ""
#endif
#ifndef VOUT_HDMITX_HDMI_CMD2
#define VOUT_HDMITX_HDMI_CMD2 ""
#endif
int aml_display_process(unsigned char vout_idx)
{
unsigned short on_connector_dev = vout_connector_check(vout_idx);
char *cntor;
char cnt_str[64], outputmode[16] = "outputmode\0\0\0";
char vout_cmd[64];
char vout_init_str[64];
if (vout_idx >= VOUT_MAX_CNT) {
printf("VOUT: %s [%u] not supported\n", __func__, vout_idx);
return 0;
}
sprintf(cnt_str, "connector%u_type", vout_idx);
cntor = env_get(cnt_str);
if (!cntor) {
// run_command(cnt_str, 0);
return 0;
}
#if defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
unsigned int smp_flow = 0;
#ifdef CONFIG_ARMV8_MULTIENTRY
int smp_ret;
unsigned char cpu_id = 1;
smp_flow = (unsigned char)env_get_ulong("display_on_smp", 10, 0);
#endif
#endif
#ifdef CONFIG_AML_HDMITX
int st = 0;
#endif
if (vout_idx == 0) {
run_command("setenv display_layer " CONNECTOR0_OSD ";", 0);
// if (smp_flow)
// run_command("vout prepare ${outputmode};", 0);
sprintf(vout_cmd, "vout output ${outputmode};");
sprintf(vout_init_str, "setenv vout_init enable;");
} else if (vout_idx == 1) {
run_command("setenv display_layer " CONNECTOR1_OSD ";", 0);
// run_command("vout2 prepare ${outputmode2};", 0);
sprintf(vout_cmd, "vout2 output ${outputmode2};");
sprintf(vout_init_str, "setenv vout2_init enable;");
outputmode[10] = '2';
} else if (vout_idx == 2) {
run_command("setenv display_layer " CONNECTOR2_OSD ";", 0);
// run_command("vout3 prepare ${outputmode3};", 0);
sprintf(vout_cmd, "vout3 output ${outputmode3};");
sprintf(vout_init_str, "setenv vout3_init enable;");
outputmode[10] = '3';
}
switch (on_connector_dev & CONNECTOR_DEV_MASK) {
#ifdef CONFIG_AML_HDMITX
case CONNECTOR_DEV_HDMI:
case CONNECTOR_DEV_CVBS:
run_command(VOUT_HDMITX_HPD_CHECK_CMD, 0);
st = hdmitx_get_hpd_state_ext();
printf("osd: hpd_state=%c\n", st ? '1' : '0');
if (!st)
break;
run_command(vout_cmd, 0);
run_command(VOUT_OSD_LOGO_CMD, 0);
run_command(VOUT_HDMITX_HDMI_CMD2, 0);
break;
#endif
#if defined(CONFIG_AML_LCD)
case CONNECTOR_DEV_LCD:
if (smp_flow) {
#ifdef CONFIG_ARMV8_MULTIENTRY
if (vout_idx == 0)
run_command("vout prepare ${outputmode};", 0);
run_command(VOUT_OSD_LOGO_CMD, 0);
if (env_get("bootup_display") &&
strcmp(env_get("bootup_display"), "off") == 0) {
printf("%s: bootup_display=%s, stop\n", __func__,
env_get("bootup_display"));
break;
}
smp_ret = run_smp_function(cpu_id + vout_idx,
&aml_display_on_post_job, 0x100 + vout_idx);
if (smp_ret)
printf("display smp failed\n");
else
run_command(vout_init_str, 0);
#endif
} else {
run_command(VOUT_OSD_LOGO_CMD, 0);
do_vout_output_job(vout_idx, env_get(outputmode));
}
break;
#endif
#if defined(CONFIG_AML_eDPTX)
case CONNECTOR_DEV_eDP:
// run_command(vout_cmd, 0);
// run_command(VOUT_OSD_LOGO_CMD, 0);
printf("eDPTX run case: smp_flow=%u\n", smp_flow);
if (smp_flow) {
#ifdef CONFIG_ARMV8_MULTIENTRY
if (vout_idx == 0)
run_command("vout prepare ${outputmode};", 0);
run_command(VOUT_OSD_LOGO_CMD, 0);
if (env_get("bootup_display") &&
strcmp(env_get("bootup_display"), "off") == 0) {
printf("%s: bootup_display=%s, stop\n", __func__,
env_get("bootup_display"));
break;
}
smp_ret = run_smp_function(cpu_id + vout_idx,
&aml_display_on_post_job, 0x100 + vout_idx);
if (smp_ret)
printf("display smp failed\n");
else
run_command(vout_init_str, 0);
#endif
} else {
run_command(VOUT_OSD_LOGO_CMD, 0);
do_vout_output_job(vout_idx, env_get(outputmode));
}
break;
#elif defined(CONFIG_AML_LCD)
case CONNECTOR_DEV_eDP:
run_command(vout_cmd, 0);
run_command(VOUT_OSD_LOGO_CMD, 0);
break;
#endif
default:
break;
}
printf("display[%u]=0x%x -> [%s,%s]\n",
vout_idx, on_connector_dev, cntor, env_get(outputmode));
//run_command(cnt_str, 0);
return 0;
}
static int do_vout_output_job(unsigned char vout_idx, char *mode_str)
{
unsigned short on_connector_dev = vout_connector_check(vout_idx);
#if defined(CONFIG_AML_CVBS) || defined(CONFIG_AML_HDMITX) || \
defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
unsigned int mux_sel = VIU_MUX_MAX, venc_sel = VIU_MUX_MAX;
char vout_init_str[64];
#endif
#ifdef CONFIG_AML_HDMITX
struct vinfo_s *vinfo = vout_get_current_vinfo();
unsigned int fmt_mode = vinfo->vpp_post_out_color_fmt;
char str[64];
#endif
#if defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
unsigned int venc_index = on_connector_dev & 0xf;
unsigned int dptx_color_type = 1;
#endif
#if defined(CONFIG_AML_CVBS) || defined(CONFIG_AML_HDMITX) || \
defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
if (vout_idx)
sprintf(vout_init_str, "setenv vout%u_init enable", vout_idx);
else
sprintf(vout_init_str, "setenv vout_init enable");
#endif
switch (on_connector_dev & CONNECTOR_DEV_MASK) {
case CONNECTOR_DEV_LCD:
#ifdef CONFIG_AML_LCD
mux_sel = aml_lcd_driver_outputmode_check(venc_index, mode_str);
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCL)
break;
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_matrix_update(VPP_CM_RGB);
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu2_matrix_update(VPP_CM_RGB);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu3_matrix_update(VPP_CM_RGB);
}
aml_lcd_driver_enable(venc_index, mode_str);
run_command(vout_init_str, 0);
return 0;
#endif
break;
case CONNECTOR_DEV_eDP:
#if defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
if (env_get_ulong("eDP_use_legacy_lcd_driver", 10, 0)) {
#ifdef CONFIG_AML_LCD
mux_sel = aml_lcd_driver_outputmode_check(venc_index, mode_str);
#endif
} else {
#ifdef CONFIG_AML_eDPTX
mux_sel = dptx_driver_outputmode_check(venc_index, mode_str);
#endif
}
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCL)
break;
if (env_get_ulong("eDP_use_legacy_lcd_driver", 10, 0)) {
#ifdef CONFIG_AML_LCD
aml_lcd_driver_enable(venc_index, mode_str);
#endif
} else {
#ifdef CONFIG_AML_eDPTX
dptx_color_type = dptx_driver_enable(venc_index, mode_str);
#endif
}
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, mux_sel | venc_index << 4);
vpp_matrix_update(dptx_color_type ? VPP_CM_YUV : VPP_CM_RGB);
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, mux_sel | venc_index << 4);
vpp_viu2_matrix_update(dptx_color_type ? VPP_CM_YUV : VPP_CM_RGB);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, mux_sel | venc_index << 4);
vpp_viu3_matrix_update(dptx_color_type ? VPP_CM_YUV : VPP_CM_RGB);
}
run_command(vout_init_str, 0);
return 0;
#endif
break;
case CONNECTOR_DEV_HDMI:
#ifdef CONFIG_AML_HDMITX
mux_sel = hdmi_outputmode_check(mode_str, 0);
venc_sel = mux_sel & 0xf;
if (venc_sel < VIU_MUX_MAX) {
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, mux_sel);
if (fmt_mode == 1)
vpp_matrix_update(VPP_CM_RGB);
else
vpp_matrix_update(VPP_CM_YUV);
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, mux_sel);
if (fmt_mode == 1)
vpp_viu2_matrix_update(VPP_CM_RGB);
else
vpp_viu2_matrix_update(VPP_CM_YUV);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, mux_sel);
if (fmt_mode == 1)
vpp_viu3_matrix_update(VPP_CM_RGB);
else
vpp_viu3_matrix_update(VPP_CM_YUV);
}
memset(str, 0, sizeof(str));
sprintf(str, "hdmitx output %s", mode_str);
run_command(str, 0);
run_command(vout_init_str, 0);
return 0;
}
#endif
break;
case CONNECTOR_DEV_CVBS:
#ifdef CONFIG_AML_CVBS
mux_sel = cvbs_outputmode_check(mode_str);
venc_sel = mux_sel & 0xf;
if (venc_sel == VIU_MUX_ENCI) {
if (cvbs_set_vmode(mode_str) == 0) {
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, mux_sel);
vpp_viu1_cm_state = VPP_CM_YUV;
vpp_matrix_update(VPP_CM_YUV);
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, mux_sel);
vpp_viu2_matrix_update(VPP_CM_YUV);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, mux_sel);
vpp_viu3_matrix_update(VPP_CM_YUV);
}
run_command(vout_init_str, 0);
return 0;
}
}
#endif
break;
default:
break;
}
return 1;
}
static int do_vout_prepare_job(unsigned char vout_idx, char *mode_str)
{
unsigned short on_connector_dev = vout_connector_check(vout_idx);
#if defined(CONFIG_AML_CVBS) || defined(CONFIG_AML_HDMITX) || \
defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
unsigned int mux_sel = VIU_MUX_MAX, venc_sel = VIU_MUX_MAX;
#endif
#if defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
unsigned int venc_index = on_connector_dev & 0xf;
unsigned int dptx_color_type = 1;
#endif
#ifdef CONFIG_AML_HDMITX
struct vinfo_s *vinfo = vout_get_current_vinfo();
unsigned int fmt_mode = vinfo->vpp_post_out_color_fmt;
int st;
char *connector1_type;
#endif
switch (on_connector_dev & CONNECTOR_DEV_MASK) {
case CONNECTOR_DEV_LCD:
#ifdef CONFIG_AML_LCD
mux_sel = aml_lcd_driver_outputmode_check(venc_index, mode_str);
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCL)
break;
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu1_cm_state = VPP_CM_RGB;
vpp_matrix_update(VPP_CM_RGB);
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu2_matrix_update(VPP_CM_RGB);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu3_matrix_update(VPP_CM_RGB);
}
aml_lcd_driver_prepare(venc_index, mode_str);
return 0;
#endif
break;
case CONNECTOR_DEV_eDP:
#if defined(CONFIG_AML_LCD) || defined(CONFIG_AML_eDPTX)
if (env_get_ulong("eDP_use_legacy_lcd_driver", 10, 0)) {
#ifdef CONFIG_AML_LCD
mux_sel = aml_lcd_driver_outputmode_check(venc_index, mode_str);
#endif
} else {
#ifdef CONFIG_AML_eDPTX
mux_sel = dptx_driver_outputmode_check(venc_index, mode_str);
#endif
}
venc_sel = mux_sel & 0xf;
if (venc_sel != VIU_MUX_ENCL)
break;
// vout_viu_mux(VOUT_VIU1_SEL, VIU_MUX_ENCL | venc_index << 4);
if (env_get_ulong("eDP_use_legacy_lcd_driver", 10, 0)) {
#ifdef CONFIG_AML_LCD
aml_lcd_driver_prepare(venc_index, mode_str);
#endif
} else {
#ifdef CONFIG_AML_eDPTX
dptx_color_type = dptx_driver_prepare(venc_index, mode_str);
#endif
}
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu1_cm_state = dptx_color_type ? VPP_CM_CrYCb : VPP_CM_RGB;
vpp_matrix_update(dptx_color_type ? VPP_CM_CrYCb : VPP_CM_RGB);
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu2_matrix_update(dptx_color_type ? VPP_CM_CrYCb : VPP_CM_RGB);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, VIU_MUX_ENCL | venc_index << 4);
vpp_viu3_matrix_update(dptx_color_type ? VPP_CM_CrYCb : VPP_CM_RGB);
}
return 0;
#endif
break;
case CONNECTOR_DEV_HDMI:
#ifdef CONFIG_AML_HDMITX
mux_sel = hdmi_outputmode_check(mode_str, 0);
venc_sel = mux_sel & 0xf;
if (venc_sel < VIU_MUX_MAX) {
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, mux_sel);
if (fmt_mode == 1) {
vpp_viu1_cm_state = VPP_CM_RGB;
vpp_matrix_update(VPP_CM_RGB);
} else {
vpp_viu1_cm_state = VPP_CM_YUV;
vpp_matrix_update(VPP_CM_YUV);
}
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, mux_sel);
vpp_viu2_matrix_update(VPP_CM_YUV);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, mux_sel);
vpp_viu3_matrix_update(VPP_CM_YUV);
}
} else {
/*
* for dual display, hdmitx in viu2, the clkc should always be enabled,
* whether the hpd of hdmitx is high or low.
*/
st = hdmitx_get_hpd_state_ext();
connector1_type = env_get("connector1_type");
if (!st && !strcmp(connector1_type, "HDMI-A-A"))
vout_set_clkc(VOUT_VIU2_SEL);
}
return 0;
#endif
break;
case CONNECTOR_DEV_CVBS:
#ifdef CONFIG_AML_CVBS
mux_sel = cvbs_outputmode_check(mode_str);
venc_sel = mux_sel & 0xf;
if (venc_sel == VIU_MUX_ENCI) {
if (vout_idx == 0) {
vout_viu_mux(VOUT_VIU1_SEL, mux_sel);
vpp_viu1_cm_state = VPP_CM_YUV;
vpp_matrix_update(VPP_CM_YUV);
} else if (vout_idx == 1) {
vout_viu_mux(VOUT_VIU2_SEL, mux_sel);
vpp_viu2_matrix_update(VPP_CM_YUV);
} else if (vout_idx == 2) {
vout_viu_mux(VOUT_VIU3_SEL, mux_sel);
vpp_viu3_matrix_update(VPP_CM_YUV);
}
return 0;
}
#endif
break;
default:
break;
}
return 1;
}
static int do_vout_prepare(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
vout_legacy_panel_mode_support(0);
char mode[32]; //use stack instead of heap for smp
if (argc != 2)
return CMD_RET_FAILURE;
memset(mode, 0, 32);
sprintf(mode, "%s", argv[1]);
if (do_vout_prepare_job(0, mode)) {
printf("VOUT: output prepare fail\n");
vout_pr_connector_and_vmode();
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
static int do_vout_output(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
vout_legacy_panel_mode_support(0);
char mode[32]; //use stack instead of heap for smp
if (argc != 2)
return CMD_RET_FAILURE;
memset(mode, 0, 32);
sprintf(mode, "%s", argv[1]);
if (do_vout_output_job(0, mode)) {
printf("VOUT: output fail\n");
vout_pr_connector_and_vmode();
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
static int do_vout2_output(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
vout_legacy_panel_mode_support(1);
char mode[32]; //use stack instead of heap for smp
if (argc != 2)
return CMD_RET_FAILURE;
memset(mode, 0, 32);
sprintf(mode, "%s", argv[1]);
if (do_vout_output_job(1, mode)) {
printf("VOUT2: output fail\n");
vout_pr_connector_and_vmode();
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
static int do_vout2_prepare(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
vout_legacy_panel_mode_support(1);
char mode[32]; //use stack instead of heap for smp
if (argc != 2)
return CMD_RET_FAILURE;
memset(mode, 0, 32);
sprintf(mode, "%s", argv[1]);
if (do_vout_prepare_job(1, mode)) {
printf("VOUT2: output prepare fail\n");
vout_pr_connector_and_vmode();
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
static int do_vout3_output(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
vout_legacy_panel_mode_support(2);
char mode[32]; //use stack instead of heap for smp
if (argc != 2)
return CMD_RET_FAILURE;
memset(mode, 0, 32);
sprintf(mode, "%s", argv[1]);
do_vout_output_job(2, mode);
printf("VOUT3: output fail\n");
vout_pr_connector_and_vmode();
return CMD_RET_FAILURE;
}
static int do_vout3_prepare(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
vout_legacy_panel_mode_support(2);
char mode[32]; //use stack instead of heap for smp
if (argc != 2)
return CMD_RET_FAILURE;
memset(mode, 0, 32);
sprintf(mode, "%s", argv[1]);
if (do_vout_prepare_job(2, mode)) {
printf("VOUT3: output prepare fail\n");
vout_pr_connector_and_vmode();
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
static int do_vout_info(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
vout_vinfo_dump();
return CMD_RET_SUCCESS;
}
static int do_vout_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
vout_pr_connector_and_vmode();
#ifdef CONFIG_AML_HDMITX
#ifdef CONFIG_AML_HDMITX20
struct hdmitx_dev *hdmitx_device = hdmitx_get_hdev();
#else
struct hdmitx_dev *hdmitx_device = get_hdmitx21_device();
#endif
if (!hdmitx_device) {
printf("\nerror: hdmitx device is null\n");
} else {
printf("\nvalid hdmi mode:\n");
hdmitx_device->hwop.list_support_modes();
}
#endif
#ifdef CONFIG_AML_CVBS
printf("\nvalid cvbs mode:\n");
cvbs_show_valid_vmode();
#endif
#ifdef CONFIG_AML_LCD
printf("\nvalid lcd mode:\n");
aml_lcd_driver_list_support_mode();
#endif
#ifdef CONFIG_AML_eDPTX
printf("\nvalid DisplayPort mode:\n");
dptx_driver_list_vmode(0);
dptx_driver_list_vmode(1);
#endif
return CMD_RET_SUCCESS;
}
static int do_vout_display(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned short on_connector_dev;
on_connector_dev = vout_connector_check(0);
if (on_connector_dev < 0xffff) {
run_command("setenv display_layer " CONNECTOR0_OSD ";", 0);
aml_display_process(0);
}
on_connector_dev = vout_connector_check(1);
if (on_connector_dev < 0xffff) {
run_command("setenv display_layer " CONNECTOR1_OSD ";", 0);
run_command("vout2 prepare ${outputmode2};", 0);
aml_display_process(1);
}
on_connector_dev = vout_connector_check(2);
if (on_connector_dev < 0xffff) {
run_command("setenv display_layer " CONNECTOR2_OSD ";", 0);
run_command("vout3 prepare ${outputmode3};", 0);
aml_display_process(2);
}
return CMD_RET_SUCCESS;
}
#define VOUT_HELPER_STRING \
"vout/vout2/vout3 [list | output format | info | boot_display]\n" \
" list : list for valid video mode names\n" \
" prepare : prepare\n" \
" format : perfered output video mode\n" \
" info : dump vinfo\n"
static cmd_tbl_t cmd_vout_sub[] = {
U_BOOT_CMD_MKENT(boot_display, 1, 1, do_vout_display, "", ""),
U_BOOT_CMD_MKENT(list, 1, 1, do_vout_list, "", ""),
U_BOOT_CMD_MKENT(prepare, 3, 1, do_vout_prepare, "", ""),
U_BOOT_CMD_MKENT(output, 3, 1, do_vout_output, "", ""),
U_BOOT_CMD_MKENT(info, 1, 1, do_vout_info, "", ""),
};
static int do_vout(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
cmd_tbl_t *c;
if (argc < 2)
return cmd_usage(cmdtp);
argc--;
argv++;
c = find_cmd_tbl(argv[0], &cmd_vout_sub[0], ARRAY_SIZE(cmd_vout_sub));
if (c)
return c->cmd(cmdtp, flag, argc, argv);
else
return cmd_usage(cmdtp);
}
U_BOOT_CMD(vout, CONFIG_SYS_MAXARGS, 1, do_vout, "VOUT sub-system", VOUT_HELPER_STRING);
static cmd_tbl_t cmd_vout2_sub[] = {
U_BOOT_CMD_MKENT(prepare, 3, 1, do_vout2_prepare, "", ""),
U_BOOT_CMD_MKENT(output, 3, 1, do_vout2_output, "", ""),
U_BOOT_CMD_MKENT(info, 1, 1, do_vout_info, "", ""),
};
static int do_vout2(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
cmd_tbl_t *c;
if (argc < 2)
return cmd_usage(cmdtp);
argc--;
argv++;
c = find_cmd_tbl(argv[0], &cmd_vout2_sub[0], ARRAY_SIZE(cmd_vout2_sub));
if (c)
return c->cmd(cmdtp, flag, argc, argv);
else
return cmd_usage(cmdtp);
}
U_BOOT_CMD(vout2, CONFIG_SYS_MAXARGS, 1, do_vout2, "VOUT2 sub-system", VOUT_HELPER_STRING);
static cmd_tbl_t cmd_vout3_sub[] = {
U_BOOT_CMD_MKENT(prepare, 3, 1, do_vout3_prepare, "", ""),
U_BOOT_CMD_MKENT(output, 3, 1, do_vout3_output, "", ""),
U_BOOT_CMD_MKENT(info, 1, 1, do_vout_info, "", ""),
};
static int do_vout3(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
cmd_tbl_t *c;
if (argc < 2)
return cmd_usage(cmdtp);
argc--;
argv++;
c = find_cmd_tbl(argv[0], &cmd_vout3_sub[0], ARRAY_SIZE(cmd_vout3_sub));
if (c)
return c->cmd(cmdtp, flag, argc, argv);
else
return cmd_usage(cmdtp);
}
U_BOOT_CMD(vout3, CONFIG_SYS_MAXARGS, 1, do_vout3, "VOUT3 sub-system", VOUT_HELPER_STRING);