/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
 * drivers/display/osd/dolby_vision.c
 *
 * Copyright (C) 2020 Amlogic, Inc. All rights reserved.
 *
 */

#include <common.h>
#include <asm/arch/io.h>
#include <asm/arch/secure_apb.h>
#include <amlogic/vmode.h>
#include <amlogic/storage_if.h>
#include <amlogic/vout.h>
#include <amlogic/hdmi.h>
#include <amlogic/dolby_vision.h>
#include <malloc.h>

#include <config.h>
#include <mmc.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <amlogic/dolby_vision_func.h>
#include <asm/cpu_id.h>

#include "vpp.h"
#include "hdr2.h"

#include <asm/arch/io.h>
#include <asm/arch/secure_apb.h>

static struct dovi_setting_s dovi_setting;
static struct dovi_mode_s dovi_mode;
static unsigned int dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_BYPASS;
static unsigned int dolby_vision_ll_policy = DOLBY_VISION_LL_DISABLE;
static unsigned int dv_ll_output_mode = DOLBY_VISION_OUTPUT_MODE_HDR10;
static unsigned int dolby_vision_target_min = 50; /* 0.0001 */
static unsigned int dolby_vision_target_max[3][3] = {
	{ 4000, 1000, 100 }, /* DOVI => DOVI/HDR/SDR */
	{ 1000, 1000, 100 }, /* HDR =>  DOVI/HDR/SDR */
	{ 600, 1000, 100 },  /* SDR =>  DOVI/HDR/SDR */
};
static unsigned int dolby_vision_target_graphics_max[3] = {
	300, 375, 100
}; /* DOVI/HDR/SDR */

/* 0: video priority 1: graphic priority */
static unsigned int dv_graphics_priority = 1;

static unsigned int vinfo_width = 1920;
static unsigned int vinfo_height = 1080;
static unsigned int vinfo_duration_num = 60;
static unsigned int vinfo_field_height = 1080;
static bool dolby_vision_on;
static char *dolby_status;

static bool dv_fw_valid = true;

#define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
#define MATRIX_5x3_COEF_SIZE 24

static int RGB709_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
	0, 0, 0, /* pre offset */
	COEFF_NORM(0.181873),	COEFF_NORM(0.611831),	COEFF_NORM(0.061765),
	COEFF_NORM(-0.100251),	COEFF_NORM(-0.337249),	COEFF_NORM(0.437500),
	COEFF_NORM(0.437500),	COEFF_NORM(-0.397384),	COEFF_NORM(-0.040116),
	0, 0, 0, /* 10'/11'/12' */
	0, 0, 0, /* 20'/21'/22' */
	64, 512, 512, /* offset */
	0, 0, 0 /* mode, right_shift, clip_en */
};
static int bypass_coeff[MATRIX_5x3_COEF_SIZE] = {
	0, 0, 0, /* pre offset */
	COEFF_NORM(1.0),	COEFF_NORM(0.0),	COEFF_NORM(0.0),
	COEFF_NORM(0.0),	COEFF_NORM(1.0),	COEFF_NORM(0.0),
	COEFF_NORM(0.0),	COEFF_NORM(0.0),	COEFF_NORM(1.0),
	0, 0, 0, /* 10'/11'/12' */
	0, 0, 0, /* 20'/21'/22' */
	0, 0, 0, /* offset */
	0, 0, 0 /* mode, right_shift, clip_en */
};
static int dvll_RGB_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
	0, 0, 0, /* pre offset */
	COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
	COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
	COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
	0, 0, 0, /* 10'/11'/12' */
	0, 0, 0, /* 20'/21'/22' */
	64, 512, 512, /* offset */
	0, 0, 0 /* mode, right_shift, clip_en */
};

static int *cur_osd_mtx = RGB709_to_YUV709l_coeff;
static int *cur_vd1_mtx = bypass_coeff;
static unsigned int debug_enable = 0;

static bool tv_mode;

#define MAX_PARAM   8

#define REG_OFFSET_VCBUS(reg)           ((reg << 2))
#define REG_ADDR_VCBUS(reg)             (REG_BASE_VCBUS + REG_OFFSET_VCBUS(reg))

static inline u32 READ_VPP_REG(u32 reg)
{
	return (*(volatile unsigned int *)REG_ADDR_VCBUS(reg));
}

static inline void WRITE_VPP_REG(u32 reg,
	 const u32 val)
{
	*(volatile unsigned int *)REG_ADDR_VCBUS(reg) = (val);
}

static inline void WRITE_VPP_REG_BITS(uint32_t reg,
	const uint32_t value, const uint32_t start, const uint32_t len)
{
	WRITE_VPP_REG(reg, ((READ_VPP_REG(reg) &
		~(((1L << (len)) - 1) << (start))) |
		(((value) & ((1L << (len)) - 1)) << (start))));
}

static bool is_meson_gxm(void)
{
	if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXM)
		return true;
	else
		return false;
}
static bool is_meson_g12(void)
{
	if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_G12A ||
		get_cpu_id().family_id == MESON_CPU_MAJOR_ID_G12B ||
		get_cpu_id().family_id == MESON_CPU_MAJOR_ID_SM1)
		return true;
	else
		return false;
}

static bool is_meson_box(void)
{
	if (is_meson_gxm() || is_meson_g12())
		return true;
	else
		return false;
}

static bool is_meson_txlx(void)
{
	if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_TXLX)
		return true;
	else
		return false;
}

static bool is_meson_txlx_tvmode(void)
{
	if ((is_meson_txlx()) && (tv_mode == 1))
		return true;
	else
		return false;
}
static bool is_meson_txlx_stbmode(void)
{
	if ((is_meson_txlx()) && (tv_mode == 0))
		return true;
	else
		return false;
}
static bool is_meson_tm2(void)
{
	if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_TM2)
		return true;
	else
		return false;
}

static bool is_meson_tm2_tvmode(void)
{
	if ((is_meson_tm2()) && (tv_mode == 1))
		return true;
	else
		return false;
}

static bool is_meson_tm2_stbmode(void)
{
	if ((is_meson_tm2()) && (tv_mode == 0))
		return true;
	else
		return false;
}

static bool is_meson_tvmode(void)
{
	if (is_meson_tm2_tvmode() ||
		is_meson_txlx_tvmode())
		return true;
	else
		return false;
}
#ifdef CONFIG_AML_DOLBY
/*check dolby enable status,if status is disabled, not enable dolby
*/
int is_dolby_enable(void)
{
	if (!dolby_status)
		dolby_status = getenv("dolby_status");

	printf("dolby_status %s %d\n", dolby_status, dv_fw_valid);

	if (!dv_fw_valid || !dolby_status)
		return 0;
	if (!strcmp(dolby_status, DOLBY_VISION_SET_STD) ||
		!strcmp(dolby_status, DOLBY_VISION_SET_LL_YUV) ||
		!strcmp(dolby_status, DOLBY_VISION_SET_LL_RGB))
		return 1;
	else
		return 0;
}
bool request_ll_mode(void)
{
	if (!dolby_status)
		dolby_status = getenv("dolby_status");

	if (!dolby_status)
		return false;

	if (!strcmp(dolby_status, DOLBY_VISION_SET_LL_RGB) ||
		!strcmp(dolby_status, DOLBY_VISION_SET_LL_YUV)) {
		printf("request LL mode\n");
		return true;
	} else
		return false;
}
bool check_dolby_vision_on(void)
{
	if ((get_cpu_id().family_id == MESON_CPU_MAJOR_ID_G12A) ||
		(get_cpu_id().family_id == MESON_CPU_MAJOR_ID_G12B) ||
		(get_cpu_id().family_id == MESON_CPU_MAJOR_ID_SM1) ||
		(get_cpu_id().family_id == MESON_CPU_MAJOR_ID_TM2)) {
		if (READ_VPP_REG(DOLBY_CORE3_SWAP_CTRL0) & 0x1)
			return true;
	}
	return false;
}
#endif

unsigned int  dv_read_reg(unsigned int addr)
{
	return READ_VPP_REG(addr);
}

void  dv_write_reg(unsigned int addr, unsigned int value)
{
	WRITE_VPP_REG(addr, value);
}
/*
static int check_tv_has_changed(struct hdmitx_dev* hdmitx_device)
{
	return hdmitx_device->RXCap.edid_changed;
}*/

static int check_tv_hpd_status(struct hdmitx_dev* hdmitx_device)
{
	return hdmitx_get_hpd_state_ext();
}


static int check_tv_support_dv(struct hdmitx_dev *hdmitx_device)
{
	struct dv_info* dv_info = NULL;
	int maxTMDSRate = 0;
	//int preferredMode = hdmitx_device->RXCap.preferred_mode;

	//1.tv not changed, use outputmode from env
	//2.tv changed,hdmi will choose best mode and update outputmode to env
	char *outputmode = getenv("outputmode");
	printf("check_tv_support_dv, outputmode %s\n", outputmode);

	if (!hdmitx_device)
		return 0;
	if (hdmitx_device->RXCap.dv_info.ieeeoui != 0x00d046)
		return 0;
	if (hdmitx_device->RXCap.dv_info.block_flag != CORRECT)
		return 0;

	dv_info = &hdmitx_device->RXCap.dv_info;

	if (dv_info->ver == 0) {
		dovi_mode.dv_rgb_444_8bit = 1;
		if (dv_info->sup_2160p60hz)
			dovi_mode.sup_2160p60hz = 1;
	} else if ((dv_info->ver == 1) && (dv_info->length == 0xB)) {
		dovi_mode.dv_rgb_444_8bit = 1;
		if (dv_info->low_latency == 0x01)
			dovi_mode.ll_ycbcr_422_12bit = 1;
		if (dv_info->sup_2160p60hz)
			dovi_mode.sup_2160p60hz = 1;
	} else if ((dv_info->ver == 1) && (dv_info->length == 0xE)) {
		dovi_mode.dv_rgb_444_8bit = 1;
		if (dv_info->sup_2160p60hz)
			dovi_mode.sup_2160p60hz = 1;
	} else if (dv_info->ver == 2) {
		dovi_mode.ll_ycbcr_422_12bit = 1;
		if ((dv_info->Interface != 0x00) && (dv_info->Interface != 0x01))
			dovi_mode.dv_rgb_444_8bit = 1;
		if ((dv_info->Interface == 0x01) || (dv_info->Interface == 0x03)) {
			if (dv_info->sup_10b_12b_444 == 0x1)
				dovi_mode.ll_rgb_444_10bit = 1;
			if (dv_info->sup_10b_12b_444 == 0x2)
				dovi_mode.ll_rgb_444_12bit = 1;
		}
		dovi_mode.sup_2160p60hz = 1;
	}

	//if preferred mode is 4k, make sure it can be truly supported in DV format
	if (hdmitx_device->RXCap.Max_TMDS_Clock2 != 0) {
		maxTMDSRate = hdmitx_device->RXCap.Max_TMDS_Clock2 * 5;
		printf("check_tv_support_dv: maxTMDSRate1 = %d\n", maxTMDSRate);
	} else {
		if (hdmitx_device->RXCap.Max_TMDS_Clock1 < 0xf)
			hdmitx_device->RXCap.Max_TMDS_Clock1 = 0x1e;
		maxTMDSRate = hdmitx_device->RXCap.Max_TMDS_Clock1 * 5;
		printf("check_tv_support_dv: maxTMDSRate2 = %d\n", maxTMDSRate);
	}
	//return true only if DV can truly be supported for a given mode
	if (strstr(outputmode, "2160p60hz") || strstr(outputmode, "2160p50hz")) {
		if ((dovi_mode.sup_2160p60hz) && (maxTMDSRate >= 594)) {
			//safety check for yuv420 - shudn't be the case
			if (!strcmp(outputmode, "2160p60hz420"))
				setenv("outputmode", "2160p60hz");
			if (!strcmp(outputmode, "2160p50hz420"))
				setenv("outputmode", "2160p50hz");
			printf("check_tv_support_dv: 4k60 dovi supported\n");
			return 1;
		} else {
			printf("check_tv_support_dv: 4k60 dovi NOT supported\n");
			return 0;
		}
	}
	return 1;
}

static int check_tv_support_hdr(struct hdmitx_dev *hdmitx_device)
{
	if (!hdmitx_device)
		return 0;
	if (hdmitx_device->RXCap.hdr_info.hdr_sup_eotf_smpte_st_2084)
		return 1;
	return 0;
}

#if 0
/* not needed anymore */
/*if tv has changed, choose the preferred mode and check if dv support this preferred mode*/
static int check_tv_dv_mode(struct hdmitx_dev *hdmitx_device)
{

	if (dovi_mode.dv_rgb_444_8bit) {
		setenv("colorattribute", "444,8bit");
		if ((hdmitx_device->RXCap.preferred_mode
			== HDMI_3840x2160p50_16x9) ||
			(hdmitx_device->RXCap.preferred_mode
			== HDMI_3840x2160p60_16x9)) {
			if ((dovi_mode.sup_2160p60hz) &&
				(hdmitx_device->RXCap.Max_TMDS_Clock2 * 5 == 600))
				setenv("outputmode", "2160p60hz");
			else
				setenv("outputmode", "1080p60hz");
		 } else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1920x1080p60_16x9)
			setenv("outputmode", "1080p60hz");
		else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1920x1080p50_16x9)
			setenv("outputmode", "1080p50hz");
		else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1280x720p60_16x9)
			setenv("outputmode", "720p60hz");
		else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1280x720p50_16x9)
			setenv("outputmode", "720p50hz");
		else
			setenv("outputmode", "1080p60hz");
		printf("output dv standard mode : mode is : %s  attr: %s\n",
			getenv("outputmode"), getenv("colorattribute"));
	} else if (dovi_mode.ll_ycbcr_422_12bit) {
		setenv("colorattribute", "422,12bit");
		if ((hdmitx_device->RXCap.preferred_mode
			== HDMI_3840x2160p50_16x9) ||
			(hdmitx_device->RXCap.preferred_mode
			== HDMI_3840x2160p60_16x9)) {
			if ((dovi_mode.sup_2160p60hz) &&
				(hdmitx_device->RXCap.Max_TMDS_Clock2 * 5 == 600))
				setenv("outputmode", "2160p60hz");
			else
				setenv("outputmode", "1080p60hz");
		} else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1920x1080p60_16x9)
			setenv("outputmode", "1080p60hz");
		else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1920x1080p50_16x9)
			setenv("outputmode", "1080p50hz");
		else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1280x720p60_16x9)
			setenv("outputmode", "720p60hz");
		else if (hdmitx_device->RXCap.preferred_mode
			== HDMI_1280x720p50_16x9)
			setenv("outputmode", "720p50hz");
		else
			setenv("outputmode", "1080p60hz");
		printf("output dv LL 422 mode : mode is : %s  attr: %s\n",
			getenv("outputmode"), getenv("colorattribute"));
	} else if (dovi_mode.ll_rgb_444_10bit) {
		setenv("colorattribute", "444,10bit");
		setenv("outputmode", "1080p60hz");
		printf("output dv LL 444 mode : mode is : %s  attr: %s\n",
			getenv("outputmode"), getenv("colorattribute"));
	} else if (dovi_mode.ll_rgb_444_12bit) {
		setenv("colorattribute", "444,12bit");
		setenv("outputmode", "1080p60hz");
		printf("output dv LL 444 mode : mode is : %s  attr: %s\n",
			getenv("outputmode"), getenv("colorattribute"));
	} else {
		setenv("colorattribute", "444,8bit");
		setenv("outputmode", "1080p60hz");
	}
	return 0;
}
#endif

/*true: attr match with dv_moder*/
/*false: attr not match with dv_mode*/
static bool is_attr_match(void)
{
	char *attr = getenv("colorattribute");

	/*two case use std mode: */
	/*1.user not requeset LL mode*/
	/*2.user request LL mode but sink not support LL mode*/
	if (dovi_mode.dv_rgb_444_8bit &&
		(!request_ll_mode() || dovi_mode.ll_ycbcr_422_12bit == 0)) { /*STD*/
		if (strncmp(attr, "444,8bit", strlen("444,8bit"))) {
			printf("expect output DV, but attr is %s\n", attr);
			return false;
		}
	} else if (dovi_mode.ll_ycbcr_422_12bit) { /*LL YUV*/
		if (strncmp(attr, "422,12bit", strlen("422,12bit"))) {
			printf("expect output LL YUV, but attr is %s\n", attr);
			dovi_setting.dst_format = FORMAT_SDR;
			return false;
		}
	} else if (dovi_mode.ll_rgb_444_10bit) {  /*LL RGB*/
		if (strncmp(attr, "444,10bit", strlen("444,10bit"))) {
			printf("expect output LL RGB, but attr is %s\n", attr);
			dovi_setting.dst_format = FORMAT_SDR;
			return false;
		}
	}
	return true;
}
static int check_tv_support(struct hdmitx_dev *hdmitx_device)
{
	if (check_tv_support_dv(hdmitx_device)) {
		if (is_attr_match()) {
			dovi_setting.dst_format = FORMAT_DOVI;
			printf("output dovi mode: mode is : %s  attr: %s\n",
				getenv("outputmode"), getenv("colorattribute"));
		} else {
			dovi_setting.dst_format = FORMAT_SDR;
			printf("attr is not match, change to output SDR\n");
		}
	} else if (check_tv_support_hdr(hdmitx_device)) {
		dovi_setting.dst_format = FORMAT_HDR10;
		printf("output hdr mode: mode is : %s  attr: %s\n",
			getenv("outputmode"), getenv("colorattribute"));
	} else {
		dovi_setting.dst_format = FORMAT_SDR;
		printf("output sdr mode: mode is : %s  attr: %s\n",
			getenv("outputmode"), getenv("colorattribute"));
	}
	return 0;
}

static void dolby_vision_get_vinfo(struct hdmitx_dev *hdmitx_device)
{
	uint32_t width;
	uint32_t height;
	uint32_t sync_duration_num;
	uint32_t field_height;
	char  *mode_name;

	mode_name = getenv("outputmode");

	if (strstr(mode_name, "1080")) {
		width = 1920;
		height = 1080;
	} else if (strstr(mode_name, "2160")) {
		width = 3840;
		height = 2160;
	} else if (strstr(mode_name, "720")) {
		width = 1280;
		height = 720;
	} else if (strstr(mode_name, "576")) {
		width = 720;
		height = 576;
	} else if (strstr(mode_name, "480")) {
		width = 720;
		height = 480;
	} else if (strstr(mode_name, "smpte")) {
		width = 4096;
		height = 2160;
	} else {
		printf("unkown mode, use default 1080p\n");
		width = 1920;
		height = 1080;
	}

	if (strstr(mode_name, "60hz"))
		sync_duration_num = 60;
	else if (strstr(mode_name, "50hz"))
		sync_duration_num = 50;
	else if (strstr(mode_name, "30hz"))
		sync_duration_num = 30;
	else if (strstr(mode_name, "25hz"))
		sync_duration_num = 25;
	else if (strstr(mode_name, "24hz"))
		sync_duration_num = 24;
	else
		sync_duration_num = 60;

	if (strstr(mode_name, "i"))
		field_height = height/2;
	else
		field_height = height;

	vinfo_width = width;
	vinfo_height = height;
	vinfo_duration_num = sync_duration_num;
	vinfo_field_height = field_height;

}

static int dolby_vision_parse(struct hdmitx_dev *hdmitx_device)
{
	enum signal_format_enum src_format = FORMAT_SDR;
	enum signal_format_enum dst_format = dovi_setting.dst_format;
	unsigned int graphic_min = 50;
	unsigned int graphic_max = 100;
	unsigned int target_max = 100;
	unsigned int w = 3840;
	unsigned int h = 2160;
	int ret = 0;

	dolby_vision_get_vinfo(hdmitx_device);
	dovi_setting.vout_width = vinfo_width;
	dovi_setting.vout_height= vinfo_height;
	dovi_setting.g_bitdepth = 8;
	dovi_setting.g_format = G_SDR_RGB;
	dovi_setting.video_width = w << 16;
	dovi_setting.video_height = h << 16;

	if(dst_format >= 0
		&& dst_format <= 2)
		graphic_max = dolby_vision_target_graphics_max[dst_format];

	if (dovi_setting.dst_format == FORMAT_DOVI) {
		memset(&dovi_setting.vsvdb_tbl[0],
			0, sizeof(dovi_setting.vsvdb_tbl));
		memcpy(&dovi_setting.vsvdb_tbl[0],
			&hdmitx_device->RXCap.dv_info.rawdata[0],
			hdmitx_device->RXCap.dv_info.length + 1);

		//two case use std mode:
		//1.user not requeset LL mode
		//2.user request LL mode but sink not support LL mode
		if (dovi_mode.dv_rgb_444_8bit &&
			(!request_ll_mode() || dovi_mode.ll_ycbcr_422_12bit == 0))
			;
		else if (dovi_mode.ll_ycbcr_422_12bit) {
			dovi_setting.use_ll_flag = 1;
			dovi_setting.dovi_ll_enable = 1;
		} else if (dovi_mode.ll_rgb_444_10bit) {
			dovi_setting.use_ll_flag = 1;
			dovi_setting.dovi_ll_enable = 1;
			dovi_setting.ll_rgb_desired= 1;
			dovi_setting.diagnostic_enable = 1;
		}
	} else if (dovi_setting.dst_format == FORMAT_HDR10) {
		if (hdmitx_device->RXCap.hdr_info.hdr_lum_max) {
			graphic_max = 50 * (2 ^ (hdmitx_device->RXCap.hdr_info.hdr_lum_max >> 5));
			graphic_max = graphic_max * 10000
				* hdmitx_device->RXCap.hdr_info.hdr_lum_min
				* hdmitx_device->RXCap.hdr_info.hdr_lum_min
				/ (255 * 255 * 100);
		}
	} else
		;

	if ((src_format >= 0 && src_format <= 2) &&
		(dst_format >= 0 && dst_format <= 2))
		target_max = dolby_vision_target_max[src_format][dst_format];

	ret = control_path(
		src_format, dst_format,
		NULL, 0,
		NULL, 0,
		dv_graphics_priority,
		12, 0, 0,
		graphic_min,
		graphic_max * 10000,
		dolby_vision_target_min,
		target_max * 10000, 1,
		NULL,
		&dovi_setting);
	return ret;
}

static bool need_skip_cvm(unsigned int is_graphic) {
	return false;
}

static unsigned int mtx_en_mux;
static void video_effect_bypass(int bypass)
{
	WRITE_VPP_REG(VPP_EOTF_CTL, 0);
	WRITE_VPP_REG(XVYCC_LUT_CTL, 0);
	WRITE_VPP_REG(XVYCC_INV_LUT_CTL, 0);
	WRITE_VPP_REG(VPP_VADJ_CTRL, 0);
	WRITE_VPP_REG(VPP_GAINOFF_CTRL0, 0);
	WRITE_VPP_REG(VPP_VE_ENABLE_CTRL, 0);
	WRITE_VPP_REG(XVYCC_VD1_RGB_CTRST, 0);
}
static void vpp_set_mtx_en_write(void)
{
	int reg_val;

	reg_val = READ_VPP_REG(VPP_MATRIX_CTRL);
	WRITE_VPP_REG(VPP_MATRIX_CTRL, (reg_val &
		(~(POST_MTX_EN_MASK |
		VD2_MTX_EN_MASK |
		VD1_MTX_EN_MASK |
		XVY_MTX_EN_MASK |
		OSD1_MTX_EN_MASK))) |
		mtx_en_mux);
}

static void vpp_set_mtx_en_read(void)
{
	int reg_value;

	reg_value = READ_VPP_REG(VPP_MATRIX_CTRL);
	mtx_en_mux = reg_value &
		(POST_MTX_EN_MASK |
		VD2_MTX_EN_MASK |
		VD1_MTX_EN_MASK |
		XVY_MTX_EN_MASK |
		OSD1_MTX_EN_MASK);
}

static int enable_rgb_to_yuv_matrix_for_dvll(
	int32_t on, uint32_t *coeff_orig, uint32_t bits)
{
	int32_t i;
	uint32_t coeff01, coeff23, coeff45, coeff67, coeff89;
	uint32_t scale, shift, offset[3];
	int32_t *coeff = dvll_RGB_to_YUV709l_coeff;

	if ((bits < 10) || (bits > 12))
		return -1;
	if (on && !coeff_orig)
		return -2;
	if (on) {
		coeff01 = coeff_orig[0];
		coeff23 = coeff_orig[1];
		coeff45 = coeff_orig[2];
		coeff67 = coeff_orig[3];
		coeff89 = coeff_orig[4] & 0xffff;
		scale = (coeff_orig[4] >> 16) & 0x0f;
		offset[0] = coeff_orig[5];
		offset[1] = 0; /* coeff_orig[6]; */
		offset[2] = 0; /* coeff_orig[7]; */

		coeff[0] = coeff[1] = coeff[2] = 0; /* pre offset */

		coeff[5] = (int32_t)((coeff01 & 0xffff) << 16) >> 16;
		coeff[3] = (int32_t)coeff01 >> 16;
		coeff[4] = (int32_t)((coeff23 & 0xffff) << 16) >> 16;
		coeff[8] = (int32_t)coeff23 >> 16;
		coeff[6] = (int32_t)((coeff45 & 0xffff) << 16) >> 16;
		coeff[7] = (int32_t)coeff45 >> 16;
		coeff[11] = (int32_t)((coeff67 & 0xffff) << 16) >> 16;
		coeff[9] = (int32_t)coeff67 >> 16;
		coeff[10] = (int32_t)((coeff89 & 0xffff) << 16) >> 16;

		if (scale > 12) {
			shift = scale - 12;
			for (i = 3; i < 12; i++)
				coeff[i] = (coeff[i] + (1 << (shift - 1))) >> shift;
		} else if (scale < 12) {
			shift = 12 - scale;
			for (i = 3; i < 12; i++)
				coeff[i] <<= shift;
		}

		/* post offset */
		coeff[18] = offset[0];
		coeff[19] = offset[1];
		coeff[20] = offset[2];

		coeff[5] = ((coeff[3] + coeff[4] + coeff[5]) & 0xfffe)
			- coeff[3] - coeff[4];
		coeff[8] = 0 - coeff[6] - coeff[7];
		coeff[11] = 0 - coeff[9] - coeff[10];
		coeff[18] -= (0x1000 - coeff[3] - coeff[4] - coeff[5]) >> 1;

		coeff[22] = 2;
		vpp_set_mtx_en_read();
		WRITE_VPP_REG(VPP_MATRIX_CTRL, 0);
		set_vpp_matrix(VPP_MATRIX_OSD,
			cur_osd_mtx, CSC_OFF);
		set_vpp_matrix(VPP_MATRIX_VD1,
			cur_vd1_mtx, CSC_OFF);
		set_vpp_matrix(VPP_MATRIX_POST,
			coeff, CSC_ON);
		vpp_set_mtx_en_write();
	}
	return 0;
}

static int dolby_core2_set(
	const uint32_t dm_count,
	const uint32_t lut_count,
	uint32_t *p_core2_dm_regs,
	uint32_t *p_core2_lut,
	int hsize,
	int vsize,
	int dolby_enable,
	int lut_endian)
{
	uint32_t count;
	int i;
	uint32_t bypass_flag = 0;

	uint32_t g_htotal_add = 0x40;
	uint32_t g_vtotal_add = 0x80;
	uint32_t g_vsize_add = 0;
	uint32_t g_vwidth = 0x18;
	uint32_t g_hwidth = 0x10;
	uint32_t g_vpotch;
	uint32_t g_hpotch = 0x10;

	/* adjust core2 setting to work around*/
	/* fixing with 1080p24hz and 480p60hz */
	if ((vinfo_width < 1280) && ((vinfo_height < 720)
		&& (vinfo_field_height < 720)))
		g_vpotch = 0x60;
	else if ((vinfo_width == 1280) &&
		 (vinfo_height == 720) &&
		 (vinfo_field_height < 720))
		g_vpotch = 0x60;
	else if ((vinfo_width == 1920) &&
		  (vinfo_height == 1080) &&
		  (vinfo_duration_num == 24))
		g_vpotch = 0x60;
	else if ((vinfo_width == 1920) &&
		 (vinfo_height == 1080) &&
		 (vinfo_field_height < 1080))
		g_vpotch = 0x60;
	else if ((vinfo_width == 1280) && (vinfo_height == 720))
		g_vpotch = 0x38;
	else
		g_vpotch = 0x20;

	WRITE_VPP_REG(DOLBY_CORE2A_CLKGATE_CTRL, 0);
	WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL0, 0);

	WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL1,
		((hsize + g_htotal_add) << 16)
		| (vsize + g_vtotal_add + g_vsize_add));
	WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL2,
		(hsize << 16) | (vsize + g_vsize_add));
	WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL3,
		(g_hwidth << 16) | g_vwidth);
	WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL4,
		(g_hpotch << 16) | g_vpotch);
	if (is_meson_txlx_stbmode())
		WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL5, 0xf8000000);
	else if (is_meson_g12() || is_meson_tm2_stbmode())
		WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL5,  0xa8000000);
	else
		WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL5, 0x0);

	WRITE_VPP_REG(DOLBY_CORE2A_DMA_CTRL, 0x0);
	WRITE_VPP_REG(DOLBY_CORE2A_REG_START + 2, 1);
	if (need_skip_cvm(1))
		bypass_flag |= 1 << 0;
	WRITE_VPP_REG(DOLBY_CORE2A_REG_START + 2, 1);
	WRITE_VPP_REG(DOLBY_CORE2A_REG_START + 1,
		2 | bypass_flag);
	WRITE_VPP_REG(DOLBY_CORE2A_REG_START + 1,
		2 | bypass_flag);
	WRITE_VPP_REG(DOLBY_CORE2A_CTRL, 0);

	WRITE_VPP_REG(DOLBY_CORE2A_CTRL, 0);

	if (dm_count == 0)
		count = 24;
	else
		count = dm_count;
	for (i = 0; i < count; i++)
		WRITE_VPP_REG(
			DOLBY_CORE2A_REG_START + 6 + i,
			p_core2_dm_regs[i]);

	/* core2 metadata program done */
	WRITE_VPP_REG(DOLBY_CORE2A_REG_START + 3, 1);

	if (lut_count == 0)
		count = 256 * 5;
	else
		count = lut_count;

	WRITE_VPP_REG(DOLBY_CORE2A_DMA_CTRL, 0x1401);
	if (lut_endian)
		for (i = 0; i < count; i += 4) {
			WRITE_VPP_REG(DOLBY_CORE2A_DMA_PORT,
				p_core2_lut[i+3]);
			WRITE_VPP_REG(DOLBY_CORE2A_DMA_PORT,
				p_core2_lut[i+2]);
			WRITE_VPP_REG(DOLBY_CORE2A_DMA_PORT,
				p_core2_lut[i+1]);
			WRITE_VPP_REG(DOLBY_CORE2A_DMA_PORT,
				p_core2_lut[i]);
		}
	else
		for (i = 0; i < count; i++)
			WRITE_VPP_REG(DOLBY_CORE2A_DMA_PORT,
				p_core2_lut[i]);

	/* enable core2 */
	WRITE_VPP_REG(DOLBY_CORE2A_SWAP_CTRL0, dolby_enable << 0);

	if (debug_enable) {
		printf("core2\n");
		for (i = 0; i < 24; i++)
			printf("%08x\n", p_core2_dm_regs[i]);
		printf("core2 swap\n");
		for (i = DOLBY_CORE2A_CLKGATE_CTRL;
			i <= DOLBY_CORE2A_DMA_PORT; i++)
			printf("[0x%4x] = 0x%x\n",
				i, READ_VPP_REG(i));
		printf("core2 real reg\n");
		for (i = DOLBY_CORE2A_REG_START;
			i <= DOLBY_CORE2A_REG_START + 5; i++)
			printf("[0x%4x] = 0x%x\n",
				i, READ_VPP_REG(i));
	}

	return 0;
}

static int dolby_core3_set(
	uint32_t dm_count,
	uint32_t md_count,
	uint32_t *p_core3_dm_regs,
	uint32_t *p_core3_md_regs,
	int hsize,
	int vsize,
	int dolby_enable,
	int scramble_en,
	u8 pps_state)
{
	uint32_t count;
	int i;
	int vsize_hold = 0x10;
	uint32_t diag_mode = 0;
	uint32_t cur_dv_mode = dolby_vision_mode;
	uint32_t diag_enable = 0;

	uint32_t htotal_add = 0x140;
	uint32_t vtotal_add = 0x40;
	uint32_t vsize_add = 0;

	if (dovi_setting.diagnostic_enable
		|| dovi_setting.dovi_ll_enable)
		diag_enable = 1;

	if (((cur_dv_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL)
		|| (cur_dv_mode == DOLBY_VISION_OUTPUT_MODE_IPT))
		&& diag_enable) {
		cur_dv_mode = dv_ll_output_mode & 0xff;

		if (is_meson_g12() || is_meson_tm2_stbmode()) {
			if (dolby_vision_ll_policy == DOLBY_VISION_LL_YUV422)
				diag_mode = 0x20;
			else
				diag_mode = 3;
		} else
			diag_mode = 3;
	}
	if (is_meson_box() || is_meson_tm2_stbmode()) {
		if (dovi_setting.dovi_ll_enable &&
			dovi_setting.diagnostic_enable == 0) {
			WRITE_VPP_REG_BITS(
				VPP_DOLBY_CTRL,
				3, 6, 2); /* post matrix */
			WRITE_VPP_REG_BITS(
				VPP_MATRIX_CTRL,
				1, 0, 1); /* post matrix */
		} else {
			WRITE_VPP_REG_BITS(
				VPP_DOLBY_CTRL,
				0, 6, 2); /* post matrix */
			WRITE_VPP_REG_BITS(
				VPP_MATRIX_CTRL,
				0, 0, 1); /* post matrix */
		}
	} else if (is_meson_txlx_stbmode()) {
			WRITE_VPP_REG_BITS(
				VPP_DOLBY_CTRL,
				1, 0, 1); /* skip pps/dither/cm */
			WRITE_VPP_REG(
				VPP_DAT_CONV_PARA0, 0x08000800);

		if (dovi_setting.dovi_ll_enable &&
			dovi_setting.diagnostic_enable == 0) {
			/*bypass gainoff to vks */
			/*enable wn tp vks*/
			WRITE_VPP_REG_BITS(
				VPP_DOLBY_CTRL, 0, 2, 1);
			WRITE_VPP_REG_BITS(
				VPP_DOLBY_CTRL, 1, 1, 1);
			WRITE_VPP_REG(
				VPP_DAT_CONV_PARA1, 0x8000800);
			WRITE_VPP_REG_BITS(
				VPP_MATRIX_CTRL,
				1, 0, 1); /* post matrix */
		} else {
			/* bypass wm tp vks*/
			WRITE_VPP_REG_BITS(
				VPP_DOLBY_CTRL, 1, 2, 1);
			WRITE_VPP_REG_BITS(
				VPP_DOLBY_CTRL, 0, 1, 1);
			WRITE_VPP_REG(
				VPP_DAT_CONV_PARA1, 0x20002000);
			if (is_meson_tvmode())
				enable_rgb_to_yuv_matrix_for_dvll(
					0, NULL, 12);
			else
				WRITE_VPP_REG_BITS(
					VPP_MATRIX_CTRL,
					0, 0, 1);
		}
	}

	/* flush post matrix table when ll mode on and setting changed */
	if (dovi_setting.dovi_ll_enable &&
		(dovi_setting.diagnostic_enable == 0))
		enable_rgb_to_yuv_matrix_for_dvll(
			1, &p_core3_dm_regs[18], 12);

	WRITE_VPP_REG(DOLBY_CORE3_CLKGATE_CTRL, 0);
	WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL1,
		((hsize + htotal_add) << 16)
		| (vsize + vtotal_add + vsize_add + vsize_hold * 2));
	WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL2,
		(hsize << 16) | (vsize + vsize_add));
	WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL3,
		(0x80 << 16) | vsize_hold);
	WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL4,
		(0x04 << 16) | vsize_hold);
	WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL5, 0x0000);
	if (cur_dv_mode != DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL)
		WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL6, 0);
	else
		WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL6,
			0x10000000);  /* swap UV */
	WRITE_VPP_REG(DOLBY_CORE3_REG_START + 5, 7);
	WRITE_VPP_REG(DOLBY_CORE3_REG_START + 4, 4);
	WRITE_VPP_REG(DOLBY_CORE3_REG_START + 4, 2);
	WRITE_VPP_REG(DOLBY_CORE3_REG_START + 2, 1);
	/* Control Register, address 0x04 2:0 RW */
	/* Output_operating mode*/
	/*   00- IPT 12 bit 444 bypass Dolby Vision output*/
	/*   01- IPT 12 bit tunnelled over RGB 8 bit 444, dolby vision output*/
	/*   02- HDR10 output, RGB 10 bit 444 PQ*/
	/*   03- Deep color SDR, RGB 10 bit 444 Gamma*/
	/*   04- SDR, RGB 8 bit 444 Gamma*/
	WRITE_VPP_REG(DOLBY_CORE3_REG_START + 1, cur_dv_mode);
	WRITE_VPP_REG(DOLBY_CORE3_REG_START + 1, cur_dv_mode);
	/* for delay */

	if (dm_count == 0)
		count = 26;
	else
		count = dm_count;
	for (i = 0; i < count; i++)
		WRITE_VPP_REG(DOLBY_CORE3_REG_START + 0x6 + i,
			p_core3_dm_regs[i]);
	/* from addr 0x18 */

	count = md_count;
	for (i = 0; i < count; i++)
		WRITE_VPP_REG(DOLBY_CORE3_REG_START + 0x24 + i,
			p_core3_md_regs[i]);
	for (; i < (128+1); i++)
		WRITE_VPP_REG(DOLBY_CORE3_REG_START + 0x24 + i, 0);

	/* from addr 0x90 */
	/* core3 metadata program done */
	WRITE_VPP_REG(DOLBY_CORE3_REG_START + 3, 1);

	WRITE_VPP_REG(DOLBY_CORE3_DIAG_CTRL, diag_mode);
	/* enable core3 */
	WRITE_VPP_REG(DOLBY_CORE3_SWAP_CTRL0, (dolby_enable << 0));

	if (debug_enable) {
		printf("core3\n");
		for (i = 0; i < 26; i++)
			printf("%08x\n", p_core3_dm_regs[i]);
		printf("core3 swap\n");
		for (i = DOLBY_CORE3_CLKGATE_CTRL;
			i <= 0x36fd; i++)
			printf("[0x%4x] = 0x%x\n",
				i, READ_VPP_REG(i));
		printf("core3 real reg\n");
		for (i = DOLBY_CORE3_REG_START;
			i <= DOLBY_CORE3_REG_START + 67; i++)
			printf("[0x%4x] = 0x%x\n",
				i, READ_VPP_REG(i));

		printf("core3 metadata, count %d\n",md_count);
		for (i = 0; i < md_count; i++)
			printf("%08x\n", p_core3_md_regs[i]);
	}

	return 0;
}

int apply_stb_core_settings(void)
{
	uint32_t graphics_w = 1920;
	uint32_t graphics_h = 1080;

	if (!is_dolby_enable())
		return 0;
	if (dovi_setting.dst_format == FORMAT_INVALID)
		return 0;

	printf("%s\n", __func__);
	if (dovi_setting.dst_format == FORMAT_DOVI) {
		if (dovi_setting.dovi_ll_enable) {
			if (dovi_setting.diagnostic_enable) {
				dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_IPT;
				dolby_vision_ll_policy = DOLBY_VISION_LL_RGB444;
			} else {
				dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_IPT;
				dolby_vision_ll_policy = DOLBY_VISION_LL_YUV422;
			}
		} else
			dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL;
	} else if (dovi_setting.dst_format == FORMAT_HDR10)
		dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_HDR10;
	else
		dolby_vision_mode = DOLBY_VISION_OUTPUT_MODE_SDR8;

	dolby_core2_set(24, 256 * 5,
		(uint32_t *)&dovi_setting.dm_reg2,
		(uint32_t *)&dovi_setting.dm_lut2,
		graphics_w, graphics_h, 1, 1);

	dolby_core3_set(26, dovi_setting.md_reg3.size,
		(uint32_t *)&dovi_setting.dm_reg3,
		dovi_setting.md_reg3.raw_metadata,
		vinfo_width, vinfo_height, 1, 1, 0);
	return 0;
}

static int  enable_dolby_vision(void)
{
	printf("%s\n", __func__);
	if (is_meson_g12() || is_meson_tm2_stbmode()) {
		hdr_func(OSD1_HDR, HDR_BYPASS);

		/*enable core3*/
		WRITE_VPP_REG_BITS(VPP_DOLBY_CTRL, 1, 3, 1);
		WRITE_VPP_REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL,
			0x0);
		WRITE_VPP_REG(VPP_WRAP_OSD2_MATRIX_EN_CTRL,
			0x0);
		WRITE_VPP_REG(VPP_WRAP_OSD3_MATRIX_EN_CTRL,
			0x0);

		/*enable core2*/
		WRITE_VPP_REG_BITS(DOLBY_PATH_CTRL, 0, 2, 1);

		/* bypass all video effect */
		video_effect_bypass(1);
		/* 12->10 before vadj1*/
		/* 10->12 before post blend */
		WRITE_VPP_REG(VPP_DAT_CONV_PARA0,
			0x20002000);
		/* 12->10 before vadj2*/
		/* 10->12 after gainoff */
		WRITE_VPP_REG(VPP_DAT_CONV_PARA1,
			0x20002000);

		WRITE_VPP_REG(VPP_MATRIX_CTRL, 0);
		WRITE_VPP_REG(VPP_DUMMY_DATA1,0x80200);

		if (((dolby_vision_mode ==
			DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL)
			|| (dolby_vision_mode ==
			DOLBY_VISION_OUTPUT_MODE_IPT)) &&
			(dovi_setting.diagnostic_enable == 0) &&
			dovi_setting.dovi_ll_enable) {
			uint32_t *reg = (uint32_t *)&dovi_setting.dm_reg3;
			/* input u12 -0x800 to s12 */
			WRITE_VPP_REG(VPP_DAT_CONV_PARA1,
				0x8000800);
			/* bypass vadj */
			WRITE_VPP_REG(VPP_VADJ_CTRL, 0);
			/* bypass gainoff */
			WRITE_VPP_REG(VPP_GAINOFF_CTRL0, 0);
			/* enable wm tp vks*/
			/* bypass gainoff to vks */
			WRITE_VPP_REG_BITS(VPP_DOLBY_CTRL, 1, 1, 2);
			enable_rgb_to_yuv_matrix_for_dvll(1, &reg[18],
				(dv_ll_output_mode >> 8)& 0xff);
		} else
			enable_rgb_to_yuv_matrix_for_dvll(0, NULL, 12);

		dolby_vision_on = true;
		setenv("dolby_vision_on", "1");
		run_command("saveenv", 0);
		printk("Dolby Vision turn on\n");
	}
	return 0;
}

static int prepare_drm_pkt(struct master_display_info_s *data,
	struct dovi_setting_s *setting, const struct hdmitx_dev *hdmitx_device)
{
	struct hdr10_infoframe *p_hdr;

	p_hdr = &setting->hdr_info;
	if (!data || !hdmitx_device || !setting)
		return -1;

	data->features = (1 << 29) | (5 << 26) | (0 << 25) | (1 << 24)
			| (9 << 16) | (0x10 << 8) | (10 << 0);

	/* ko return primaries in RGB order, uboot send pkt in RGB order, */
	/* to keep same with kernel*/
	data->primaries[0][0] = (p_hdr->primaries_x_0_msb << 8)
	| p_hdr->primaries_x_0_lsb;
	data->primaries[0][1] = (p_hdr->primaries_y_0_msb << 8)
	| p_hdr->primaries_y_0_lsb;
	data->primaries[1][0] = (p_hdr->primaries_x_1_msb << 8)
	| p_hdr->primaries_x_1_lsb;
	data->primaries[1][1] = (p_hdr->primaries_y_1_msb << 8)
	| p_hdr->primaries_y_1_lsb;
	data->primaries[2][0] = (p_hdr->primaries_x_2_msb << 8)
		| p_hdr->primaries_x_2_lsb;
	data->primaries[2][1] = (p_hdr->primaries_y_2_msb << 8)
		| p_hdr->primaries_y_2_lsb;
	data->white_point[0] = (p_hdr->white_point_x_msb << 8)
		| p_hdr->white_point_x_lsb;
	data->white_point[1] = (p_hdr->white_point_y_msb << 8)
		| p_hdr->white_point_y_lsb;
	data->luminance[0] =
		(p_hdr->max_display_mastering_lum_msb << 8)
		| p_hdr->max_display_mastering_lum_lsb;
	data->luminance[1] =
		(p_hdr->min_display_mastering_lum_msb << 8)
		| p_hdr->min_display_mastering_lum_lsb;

	data->max_content =
		(p_hdr->max_content_light_level_msb << 8)
		| p_hdr->max_content_light_level_lsb;
	data->max_frame_average =
		(p_hdr->max_frame_avg_light_level_msb << 8)
		| p_hdr->max_frame_avg_light_level_lsb;
	return 0;
}

static int prepare_vsif_pkt(struct dv_vsif_para *vsif,
	struct dovi_setting_s *setting, const struct hdmitx_dev *hdmitx_device)
{
	if (!vsif || !hdmitx_device || !setting)
			return -1;
	vsif->vers.ver2.low_latency = setting->dovi_ll_enable;
	vsif->vers.ver2.dobly_vision_signal = 1;
	if (hdmitx_device->RXCap.dv_info.sup_backlight_control &&
		(setting->ext_md.avail_level_mask &
		EXT_MD_LEVEL_2)) {
		vsif->vers.ver2.backlt_ctrl_MD_present = 1;
		vsif->vers.ver2.eff_tmax_PQ_hi =
			setting->ext_md.level_2.target_max_pq_h & 0xf;
			vsif->vers.ver2.eff_tmax_PQ_low =
			setting->ext_md.level_2.target_max_pq_l;
	} else {
		vsif->vers.ver2.backlt_ctrl_MD_present = 0;
		vsif->vers.ver2.eff_tmax_PQ_hi = 0;
		vsif->vers.ver2.eff_tmax_PQ_low = 0;
	}

	if (setting->dovi_ll_enable &&
		(setting->ext_md.avail_level_mask &
		EXT_MD_LEVEL_255)) {
		vsif->vers.ver2.auxiliary_MD_present = 1;
		vsif->vers.ver2.auxiliary_runmode =
			setting->ext_md.level_255.run_mode;
		vsif->vers.ver2.auxiliary_runversion =
			setting->ext_md.level_255.run_version;
		vsif->vers.ver2.auxiliary_debug0 =
			setting->ext_md.level_255.dm_debug_0;
	} else {
		vsif->vers.ver2.auxiliary_MD_present = 0;
		vsif->vers.ver2.auxiliary_runmode = 0;
		vsif->vers.ver2.auxiliary_runversion = 0;
		vsif->vers.ver2.auxiliary_debug0 = 0;
	}
	return 0;
}

static const char *output_str[4] = {
	"DOVI",
	"HDR10",
	"SDR",
	"DOVI_LL"
};

void send_hdmi_pkt(void)
{
	struct dv_vsif_para vsif;
	struct master_display_info_s drmif;

	if (!is_dolby_enable())
		return;

	printf("send hdmi pkt %d [%s] dovi_setting.dst_format = %d\n",
		dovi_setting.dst_format,
		(dovi_setting.dst_format >= 0 && dovi_setting.dst_format < 4) ?
		output_str[dovi_setting.dst_format] : "NULL",
		dovi_setting.dst_format);

	if (dovi_setting.dst_format == FORMAT_DOVI) {
		memset(&vsif, 0, sizeof(vsif));
		prepare_vsif_pkt(&vsif, &dovi_setting, &hdmitx_device);

		if (dovi_setting.dovi_ll_enable)
			hdmitx_set_vsif_pkt( EOTF_T_LL_MODE,
				dovi_setting.diagnostic_enable
				? RGB_10_12BIT : YUV422_BIT12,
				&vsif);
		else
			hdmitx_set_vsif_pkt(EOTF_T_DOLBYVISION, RGB_8BIT,
				&vsif);
	} else if (dovi_setting.dst_format == FORMAT_HDR10) {
		memset(&drmif, 0, sizeof(drmif));
		prepare_drm_pkt(&drmif, &dovi_setting, &hdmitx_device);
		hdmitx_set_drm_pkt(&drmif);
	} else
		return;
}

/*check hpd status:
 *1. hdmi connected: set hdr/dv mode based on capability of TV if dv enabled.
 *2. no hdmi: output sdr if dv enabled.
 */
void dolby_vision_process(void)
{
	if (!check_tv_hpd_status(&hdmitx_device)) {
		if (is_dolby_enable()) {
			dovi_setting.dst_format = FORMAT_SDR;
			printf("dolby_vision_process: no hpd, dst_format = SDR\n");
		} else {
			printf("dolby_vision_process: no tv and dv disabled\n");
			setenv("dolby_vision_on", "0");
			run_command("saveenv", 0);
			return;
		}
	} else {
		if (is_dolby_enable()) {
			check_tv_support(&hdmitx_device);
			printf("dolby_vision_process: hpd: dst_format=%d\n",
						dovi_setting.dst_format);
		} else {
			printf("dolby_vision_process: hpd: dv disabled\n");
			setenv("dolby_vision_on", "0");
			run_command("saveenv", 0);
			return;
		}
	}
	if (dovi_setting.dst_format == FORMAT_INVALID) {
		printf("dolby_vision_process: dst_format = FORMAT_INVALID\n");
		setenv("dolby_vision_on", "0");
		run_command("saveenv", 0);
		return;
	}
	if (dolby_vision_parse(&hdmitx_device) == 0) {
		apply_stb_core_settings();
		enable_dolby_vision();
	} else {
		printf("dolby_vision_process: control path failed\n");
		dovi_setting.dst_format = FORMAT_INVALID;
		dv_fw_valid = false;
		setenv("dolby_vision_on", "0");
		run_command("saveenv", 0);
		return;
	}
	/*dv send hdmi vsif after hdmi set mode*/
	/* so we add another cmd to send this hdmi package solely*/
}
void dolbyvision_dump_setting() {
	int i;
	uint32_t *p;
	if (!is_dolby_enable()) {
		printf("dv is disabled\n");
		return;
	}
	printf("core2\n");
	p = (uint32_t *)&dovi_setting.dm_reg2;
	for (i = 0; i < 24; i++)
		printf("%08x\n", p[i]);
	printf("core2 swap\n");
	for (i = DOLBY_CORE2A_CLKGATE_CTRL;
		i <= DOLBY_CORE2A_DMA_PORT; i++)
		printf("[0x%4x] = 0x%x\n",
			i, READ_VPP_REG(i));
	printf("core2 real reg\n");
	for (i = DOLBY_CORE2A_REG_START;
		i <= DOLBY_CORE2A_REG_START + 5; i++)
		printf("[0x%4x] = 0x%x\n",
			i, READ_VPP_REG(i));

	printf("\ncore2lut\n");
	p = (uint32_t *)&dovi_setting.dm_lut2.tm_lut_i;
	for (i = 0; i < 64; i++)
		printf("%08x, %08x, %08x, %08x\n",
			p[i*4+3], p[i*4+2], p[i*4+1], p[i*4]);
	printf("\n");
	p = (uint32_t *)&dovi_setting.dm_lut2.tm_lut_s;
	for (i = 0; i < 64; i++)
		printf("%08x, %08x, %08x, %08x\n",
			p[i*4+3], p[i*4+2], p[i*4+1], p[i*4]);
	printf("\n");
	p = (uint32_t *)&dovi_setting.dm_lut2.sm_lut_i;
	for (i = 0; i < 64; i++)
		printf("%08x, %08x, %08x, %08x\n",
			p[i*4+3], p[i*4+2], p[i*4+1], p[i*4]);
	printf("\n");
	p = (uint32_t *)&dovi_setting.dm_lut2.sm_lut_s;
	for (i = 0; i < 64; i++)
		printf("%08x, %08x, %08x, %08x\n",
			p[i*4+3], p[i*4+2], p[i*4+1], p[i*4]);
	printf("\n");
	p = (uint32_t *)&dovi_setting.dm_lut2.g_2_l;
	for (i = 0; i < 64; i++)
		printf("%08x, %08x, %08x, %08x\n",
			p[i*4+3], p[i*4+2], p[i*4+1], p[i*4]);
	printf("\n");

	printf("core3\n");
	p = (uint32_t *)&dovi_setting.dm_reg3;
	for (i = 0; i < 26; i++)
		printf("%08x\n", p[i]);
	printf("core3 swap\n");
	for (i = DOLBY_CORE3_CLKGATE_CTRL;
		i <= DOLBY_CORE3_CLKGATE_CTRL + 13; i++)
		printf("[0x%4x] = 0x%x\n",
			i, READ_VPP_REG(i));
	printf("core3 real reg\n");
	for (i = DOLBY_CORE3_REG_START;
		i <= DOLBY_CORE3_REG_START + 67; i++)
		printf("[0x%4x] = 0x%x\n",
			i, READ_VPP_REG(i));

	if (dolby_vision_mode <= DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) {
		printf("\ncore3_meta %d\n", dovi_setting.md_reg3.size);
		p = dovi_setting.md_reg3.raw_metadata;
		for (i = 0; i < dovi_setting.md_reg3.size; i++)
			printf("%08x\n", p[i]);
		printf("\n");
	}

}
void dolbyvision_debug(int enable_debug) {
	debug_enable = enable_debug;
}
