/*
 * drivers/display/vout/cvbs.c
 *
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 *
 * 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.
 *
 * Author: jets.yan@amlogic.com
 *
*/
#include <common.h>
#include <asm/arch/io.h>
#include <asm/arch/secure_apb.h>
#include <asm/arch/cpu.h>
#include <asm/arch/cpu_id.h>
#include "aml_cvbs_regs.h"
#include "aml_cvbs_config.h"

/*----------------------------------------------------------------------------*/
// global variables
enum CVBS_MODE_e
{
	VMODE_PAL,
	VMODE_NTSC,
	VMODE_PAL_M,
	VMODE_PAL_N,
	VMODE_NTSC_M,
	VMODE_MAX
};

unsigned int cvbs_mode = VMODE_MAX;
/*bit[0]: 0=vid_pll, 1=gp0_pll*/
/*bit[1]: 0=vid2_clk, 1=vid1_clk*/
/*path 0:vid_pll vid2_clk*/
/*path 1:gp0_pll vid2_clk*/
/*path 2:vid_pll vid1_clk*/
/*path 3:gp0_pll vid1_clk*/
static unsigned int s_enci_clk_path = 0;

/*----------------------------------------------------------------------------*/
// interface for registers of soc

#define REG_OFFSET_VCBUS(reg)       (((reg) << 2))
#define REG_OFFSET_CBUS(reg)		(((reg) << 2))

/* memory mapping */
#define REG_ADDR_HIU(reg)           (reg + 0L)
#define REG_ADDR_VCBUS(reg)         (REG_BASE_VCBUS + REG_OFFSET_VCBUS(reg))
#define REG_ADDR_CBUS(reg)			(REG_BASE_CBUS + REG_OFFSET_CBUS(reg))

static unsigned int cvbs_get_hiu_logic_addr(unsigned int addr_offset)
{
	return (REG_BASE_HIU + ((addr_offset&0xff)<<2));
}

static int cvbs_write_cbus(unsigned int addr_offset, unsigned int value)
{
	*(volatile unsigned int *)REG_ADDR_CBUS(addr_offset) = (value);
	return 0;
}

static int cvbs_read_cbus(unsigned int addr_offset)
{
	unsigned int val = 0;

	val = *(volatile unsigned int *)(REG_ADDR_CBUS(addr_offset));
	return val;
}

static int cvbs_write_hiu(unsigned int addr, unsigned int value)
{
	*(volatile unsigned int *)REG_ADDR_HIU(addr) = (value);
	return 0;
}

static int cvbs_read_hiu(unsigned int addr)
{
	unsigned int val = 0;

	val = *(volatile unsigned int *)(REG_ADDR_HIU(addr));
	return val;
}

static int cvbs_set_hiu_bits(unsigned int addr, unsigned int value, unsigned int start, unsigned int len)
{
	cvbs_write_hiu(addr, ((cvbs_read_hiu(addr) &
			~(((1L << (len))-1) << (start))) |
			(((value)&((1L<<(len))-1)) << (start))));
	return 0;
}

static int cvbs_get_hiu_bits(unsigned int addr, unsigned int start, unsigned int len)
{
	return (cvbs_read_hiu(addr) >> (start)) & ((1L << (len)) - 1);
}

static unsigned int cvbs_read_vcbus(unsigned int addr_offset)
{
	unsigned int val = 0;

	val = *(volatile unsigned int *)(REG_ADDR_VCBUS(addr_offset));
	return val;
}

static int cvbs_write_vcbus(unsigned int addr_offset, unsigned int value)
{
	*(volatile unsigned int *)REG_ADDR_VCBUS(addr_offset) = (value);
	return 0;
}

static int cvbs_set_vcbus_bits(unsigned int addr_offset, unsigned int value, unsigned int start, unsigned int len)
{
	cvbs_write_vcbus(addr_offset, ((cvbs_read_vcbus(addr_offset) &
		~(((1L << (len))-1) << (start))) |
		(((value)&((1L<<(len))-1)) << (start))));
	return 0;
}
#if 0
static int cvbs_get_vcbus_bits(unsigned int addr_offset, unsigned int start, unsigned int len)
{
	return (cvbs_read_vcbus(addr_offset) >> (start)) & ((1L << (len)) - 1);}
#endif

/*----------------------------------------------------------------------------*/
// interface for cpu id checking

static int check_cpu_type(unsigned int cpu_type)
{
	return (cvbs_read_cbus(ASSIST_HW_REV)==cpu_type);
}

static bool inline is_equal_after_meson_cpu(unsigned int id)
{
	return (get_cpu_id().family_id >= id)?1:0;
}

static bool inline is_meson_gxl_cpu(void)
{
	return (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXL)?
		1:0;
}

static bool inline is_meson_gxlx_cpu(void)
{
	return (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXLX)?
		1:0;
}

static bool inline is_meson_g12a_cpu(void)
{
	return (get_cpu_id().family_id ==
		MESON_CPU_MAJOR_ID_G12A) ? 1 : 0;
}

static inline bool is_meson_g12b_cpu(void)
{
	return (get_cpu_id().family_id ==
		MESON_CPU_MAJOR_ID_G12B) ? 1 : 0;
}

static bool inline is_meson_txl_cpu(void)
{
	return (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_TXL)?
		1:0;
}

static bool inline is_meson_gxm_cpu(void)
{
	return (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXM)?
		1:0;

}
static bool inline is_meson_gxl_package_905X(void)
{
	return ((get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXL) &&
		(get_cpu_id().package_id == MESON_CPU_PACKAGE_ID_905X))?
		1:0;
}

static bool inline is_meson_gxl_package_905L(void)
{
	return ((get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXL) &&
		(get_cpu_id().package_id == MESON_CPU_PACKAGE_ID_905L))?
		1:0;
}

/*----------------------------------------------------------------------------*/
// configuration for enci bist
int cvbs_set_bist(char* bist_mode)
{
	if (!strcmp(bist_mode, "off"))
	{
		cvbs_write_vcbus(ENCI_VIDEO_MODE_ADV,	0x26);
		cvbs_write_vcbus(ENCI_TST_EN,			0x0);
	} else
	{
		unsigned int mode = 0;

		if (!strcmp(bist_mode, "fixval") || !strcmp(bist_mode, "0"))
			mode = 0;
		else if (!strcmp(bist_mode, "colorbar") || !strcmp(bist_mode, "1"))
			mode = 1;
		else if (!strcmp(bist_mode, "thinline") || !strcmp(bist_mode, "2"))
			mode = 2;
		else if (!strcmp(bist_mode, "dotgrid") || !strcmp(bist_mode, "3"))
			mode = 3;

		cvbs_write_vcbus(ENCI_VIDEO_MODE_ADV,	0x2);
		cvbs_write_vcbus(ENCI_TST_MDSEL, 		mode);
		cvbs_write_vcbus(ENCI_TST_CLRBAR_STRT,	0x112);
		cvbs_write_vcbus(ENCI_TST_CLRBAR_WIDTH,	0xb4);
		cvbs_write_vcbus(ENCI_TST_EN,			0x1);
	}

	return 0;
}

/*----------------------------------------------------------------------------*/
// configuration for vdac pin of the soc.
// config vdac path:
//	0 : close
//	1 : enci
//	2 : atv
//	3 : passthrough
int cvbs_set_vdac(int status)
{
	switch (status)
	{
	case 0:// close vdac
		cvbs_write_hiu(HHI_VDAC_CNTL0, 0);
		if (is_equal_after_meson_cpu(MESON_CPU_MAJOR_ID_TXL) &&
			!is_meson_gxlx_cpu() && !is_meson_g12a_cpu() &&
			!is_meson_g12b_cpu())
			cvbs_write_hiu(HHI_VDAC_CNTL1, 0);
		else
			cvbs_write_hiu(HHI_VDAC_CNTL1, 8);
		break;
	case 1:// from enci to vdac
		cvbs_set_vcbus_bits(VENC_VDAC_DACSEL0, 0, 5, 1);
		if (is_meson_g12a_cpu())
			cvbs_write_hiu(HHI_VDAC_CNTL0, 0x906001);
		else if (is_meson_g12b_cpu())
			cvbs_write_hiu(HHI_VDAC_CNTL0, 0x8f6001);
		else if (is_equal_after_meson_cpu(MESON_CPU_MAJOR_ID_GXL)) {
			if (is_equal_after_meson_cpu(MESON_CPU_MAJOR_ID_TXL) &&
				!is_meson_gxlx_cpu())
				cvbs_write_hiu(HHI_VDAC_CNTL0, 0x620001);
			else
				cvbs_write_hiu(HHI_VDAC_CNTL0, 0xb0001);
		} else
			cvbs_write_hiu(HHI_VDAC_CNTL0, 1);

		if (is_equal_after_meson_cpu(MESON_CPU_MAJOR_ID_TXL) &&
			!is_meson_gxlx_cpu() && !is_meson_g12a_cpu() &&
			!is_meson_g12b_cpu())
			cvbs_write_hiu(HHI_VDAC_CNTL1, 8);
		else
			cvbs_write_hiu(HHI_VDAC_CNTL1, 0);
		break;
	case 2:// from atv to vdac
		cvbs_set_vcbus_bits(VENC_VDAC_DACSEL0, 1, 5, 1);
		cvbs_write_hiu(HHI_VDAC_CNTL0, 1);
		cvbs_write_hiu(HHI_VDAC_CNTL1, 0);
		break;
	case 3:// from cvbs_in passthrough to cvbs_out with vdac disabled
		cvbs_write_hiu(HHI_VDAC_CNTL0, 0x400);
		cvbs_write_hiu(HHI_VDAC_CNTL1, 8);
		break;
	default:
		break;
	}

	return 0;
}

/*----------------------------------------------------------------------------*/
// interface for debug
static void cvbs_dump_cvbs_regs(void)
{
	struct reg_s *p = NULL;

	if (VMODE_PAL == cvbs_mode) {
		// 576cvbs
		p = (struct reg_s*)&tvregs_576cvbs_enc[0];

	} else if (VMODE_NTSC == cvbs_mode) {
		// 480cvbs
		p = (struct reg_s*)&tvregs_480cvbs_enc[0];
	}

	if (NULL == p) {
		printf("it's not in cvbs mode!\n");
		return;
	}

	if (MREG_END_MARKER != p->reg)
		printf("cvbs enci registers:\n");
	while (MREG_END_MARKER != p->reg) {
		printf("    vcbus[0x%.2x] = 0x%.4x\n", p->reg, cvbs_read_vcbus(p->reg));
		p ++;
	}

	return;
}

unsigned int cvbs_clk_regs[] = {
	HHI_HDMI_PLL_CNTL0,
	HHI_HDMI_PLL_CNTL1,
	HHI_HDMI_PLL_CNTL2,
	HHI_HDMI_PLL_CNTL3,
	HHI_HDMI_PLL_CNTL4,
	HHI_HDMI_PLL_CNTL5,
	HHI_HDMI_PLL_CNTL6,
	HHI_VID_PLL_CLK_DIV,
	HHI_VIID_CLK_DIV,
	HHI_VIID_CLK_CNTL,
	HHI_VID_CLK_DIV,
	HHI_VID_CLK_CNTL2,
	MREG_END_MARKER
};

static void cvbs_dump_clock_regs(void)
{
	unsigned int *p = &cvbs_clk_regs[0];

	if (MREG_END_MARKER != *p)
		printf("cvbs clock registers:\n");
	while (MREG_END_MARKER != *p) {
		printf("    hiu[0x%.2x] = 0x%.4x\n", *p, cvbs_read_hiu(*p));
		p ++;
	}

	return;
}

int cvbs_reg_debug(int argc, char* const argv[])
{
	unsigned int addr, start, end, value;

	if (!strcmp(argv[1], "r"))
	{
		if (argc != 4)
			goto fail_cmd;

		addr = simple_strtoul(argv[3], NULL, 16);
		if (!strcmp(argv[2], "c"))
			printf("cvbs read cbus[0x%.2x] = 0x%.4x\n", addr, cvbs_read_cbus(addr));
		else if (!strcmp(argv[2], "h"))
			printf("cvbs read hiu[0x%.2x] = 0x%.4x\n", addr, cvbs_read_hiu(cvbs_get_hiu_logic_addr(addr)));
		else if (!strcmp(argv[2], "v"))
			printf("cvbs read vcbus[0x%.2x] = 0x%.4x\n", addr, cvbs_read_vcbus(addr));
	} else if (!strcmp(argv[1], "w")) {
		if (argc != 5)
			goto fail_cmd;

		addr = simple_strtoul(argv[4], NULL, 16);
		value = simple_strtoul(argv[2], NULL, 16);
		if (!strcmp(argv[3], "c")) {
			cvbs_write_cbus(addr, value);
			printf("cvbs write cbus[0x%.2x] = 0x%.4x\n", addr, cvbs_read_cbus(addr));
		} else if (!strcmp(argv[3], "h")) {
			cvbs_write_hiu(cvbs_get_hiu_logic_addr(addr), value);
			printf("cvbs write hiu[0x%.2x] = 0x%.4x\n", addr, cvbs_read_hiu(cvbs_get_hiu_logic_addr(addr)));
		} else if (!strcmp(argv[3], "v")) {
			cvbs_write_vcbus(addr, value);
			printf("cvbs write hiu[0x%.2x] = 0x%.4x\n", addr, cvbs_read_vcbus(addr));
		}
	} else if (!strcmp(argv[1], "dump")) {
		unsigned int i = 0;
		unsigned int type = 0xff;

		if (argc != 5)
			goto fail_cmd;

		if (!strcmp(argv[2], "h"))
			type = BUS_TYPE_CBUS;
		if (!strcmp(argv[2], "h"))
			type = BUS_TYPE_HIU;
		else if (!strcmp(argv[2], "v"))
			type = BUS_TYPE_VCBUS;

		if (type == 0xff)
			goto fail_cmd;

		start = simple_strtoul(argv[3], NULL, 16);
		end = simple_strtoul(argv[4], NULL, 16);

		if (type == BUS_TYPE_CBUS) {
			for (i=start; i<=end; i++)
				printf("cvbs read cbus[0x%.2x] = 0x%.4x\n", i, cvbs_read_cbus(i));
		} if (type == BUS_TYPE_HIU) {
			for (i=start; i<=end; i++)
				printf("cvbs read hiu[0x%.2x] = 0x%.4x\n", i, cvbs_read_hiu(cvbs_get_hiu_logic_addr(i)));
		} else if (type == BUS_TYPE_VCBUS) {
			for (i=start; i<=end; i++)
				printf("cvbs read vcbus[0x%.2x] = 0x%.4x\n", i, cvbs_read_vcbus(i));
		}
	} else if (!strcmp(argv[1], "clock")) {
		if (argc != 2)
			goto fail_cmd;

		cvbs_dump_clock_regs();
	} else if (!strcmp(argv[1], "enci")) {
		if (argc != 2)
			goto fail_cmd;

		cvbs_dump_cvbs_regs();
	} else if (!strcmp(argv[1], "set_clkpath")) {
		if (argc != 3)
			goto fail_cmd;
		value = simple_strtoul(argv[2], NULL, 0);
		if (check_cpu_type(MESON_CPU_MAJOR_ID_G12A) ||
			check_cpu_type(MESON_CPU_MAJOR_ID_G12B)) {
			if (value == 1 || value == 2 ||
				value == 3 || value == 0) {
				s_enci_clk_path = value;
				printf("path 0:vid_pll vid2_clk\n");
				printf("path 1:gp0_pll vid2_clk\n");
				printf("path 2:vid_pll vid1_clk\n");
				printf("path 3:gp0_pll vid1_clk\n");
				printf("you select path %d\n", s_enci_clk_path);
			} else {
				printf("invalid value, only 0/1/2/3\n");
				printf("bit[0]: 0=vid_pll, 1=gp0_pll\n");
				printf("bit[1]: 0=vid2_clk, 1=vid1_clk\n");
			}
		} else
			printf("only support G12A chip");
	}

	return 0;

fail_cmd:
	return 1;
}

/*----------------------------------------------------------------------------*/
// configuration for clock
#define WAIT_FOR_PLL_LOCKED(reg)                \
	do {                                    \
		unsigned int pll_lock;          \
		unsigned int time_out = 0;      \
		do {                            \
			udelay(20);             \
			pll_lock = cvbs_get_hiu_bits(reg, 31, 1);  \
			time_out ++;                               \
		} while ((pll_lock == 0) && (time_out < 10000));   \
		if (pll_lock == 0)                                 \
			printf("[error]: cvbs pll lock failed\n"); \
	} while(0);

static void cvbs_config_hdmipll_gxl(void)
{
#if (defined(AML_MESON_GXL))
	printf("%s\n", __func__);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL, 0x4000027b);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL1, 0x800cb300);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL2, 0xa6212844);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL3, 0x0c4d000c);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL4, 0x001fa729);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL5, 0x01a31500);
	cvbs_set_hiu_bits(HHI_HDMI_PLL_CNTL, 0x1, 28, 1);
	cvbs_set_hiu_bits(HHI_HDMI_PLL_CNTL, 0x0, 28, 1);
	WAIT_FOR_PLL_LOCKED(HHI_HDMI_PLL_CNTL);
#endif
	return;
}

static void cvbs_config_hdmipll_g12a(void)
{
	printf("%s\n", __func__);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL0,	0x1a0504f7);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL1,	0x00010000);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL2,	0x00000000);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL3,	0x6a28dc00);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL4,	0x65771290);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL5,	0x39272000);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL6,	0x56540000);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL0,	0x3a0504f7);
	udelay(100);
	cvbs_write_hiu(HHI_HDMI_PLL_CNTL0,	0x1a0504f7);
	WAIT_FOR_PLL_LOCKED(HHI_HDMI_PLL_CNTL0);
	return;
}

static void cvbs_config_gp0pll_g12a(void)
{
	printf("%s\n", __func__);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL0,	0x180204f7);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL1,	0x00010000);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL2,	0x00000000);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL3,	0x6a28dc00);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL4,	0x65771290);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL5,	0x39272000);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL6,	0x56540000);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL0,	0x380204f7);
	udelay(100);
	cvbs_write_hiu(HHI_GP0_PLL_CNTL0,	0x180204f7);
	WAIT_FOR_PLL_LOCKED(HHI_GP0_PLL_CNTL0);
	return;
}

static void cvbs_set_vid1_clk(unsigned int src_pll)
{
	int sel = 0;

	printf("%s\n", __func__);
	if (src_pll == 0) { /* hpll */
		/* divider: 1 */
		/* Disable the div output clock */
		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 0, 19, 1);
		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 0, 15, 1);

		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 1, 18, 1);
		/* Enable the final output clock */
		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 1, 19, 1);
		sel = 0;
	} else { /* gp0_pll */
		sel = 1;
	}

	/* xd: 55 */
	/* setup the XD divider value */
	cvbs_set_hiu_bits(HHI_VID_CLK_DIV, (55 - 1), VCLK_XD0, 8);
	//udelay(5);
	/*0x59[16]/0x5f[19]/0x5f[20]*/
	cvbs_set_hiu_bits(HHI_VID_CLK_CNTL, sel, VCLK_CLK_IN_SEL, 3);
	cvbs_set_hiu_bits(HHI_VID_CLK_CNTL, 1, VCLK_EN0, 1);
	//udelay(2);

	/* vclk: 27M */
	/* [31:28]=0 enci_clk_sel, select vclk_div1 */
	cvbs_set_hiu_bits(HHI_VID_CLK_DIV, 0, 28, 4);
	cvbs_set_hiu_bits(HHI_VIID_CLK_DIV, 0, 28, 4);
	/* release vclk_div_reset and enable vclk_div */
	cvbs_set_hiu_bits(HHI_VID_CLK_DIV, 1, VCLK_XD_EN, 2);
	//udelay(5);

	cvbs_set_hiu_bits(HHI_VID_CLK_CNTL, 1, VCLK_DIV1_EN, 1);

	cvbs_set_hiu_bits(HHI_VID_CLK_CNTL, 1, VCLK_SOFT_RST, 1);
	//udelay(10);
	cvbs_set_hiu_bits(HHI_VID_CLK_CNTL, 0, VCLK_SOFT_RST, 1);
	//udelay(5);
}

static void cvbs_set_vid2_clk(unsigned int src_pll)
{
	int sel = 0;

	printf("%s\n", __func__);
	if (src_pll == 0) { /* hpll */
		/* divider: 1 */
		/* Disable the div output clock */
		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 0, 19, 1);
		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 0, 15, 1);

		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 1, 18, 1);
		/* Enable the final output clock */
		cvbs_set_hiu_bits(HHI_VID_PLL_CLK_DIV, 1, 19, 1);
		sel = 0;
	} else { /* gp0_pll */
		sel = 1;
	}

	/* xd: 55 */
	/* setup the XD divider value */
	cvbs_set_hiu_bits(HHI_VIID_CLK_DIV, (55 - 1), VCLK2_XD, 8);
	//udelay(5);
	/* Bit[18:16] - v2_cntl_clk_in_sel: vid_pll */
	cvbs_set_hiu_bits(HHI_VIID_CLK_CNTL, sel, VCLK2_CLK_IN_SEL, 3);
	cvbs_set_hiu_bits(HHI_VIID_CLK_CNTL, 1, VCLK2_EN, 1);
	//udelay(2);

	/* vclk: 27M */
	/* [31:28]=8 enci_clk_sel, select vclk2_div1 */
	cvbs_set_hiu_bits(HHI_VID_CLK_DIV, 8, 28, 4);
	cvbs_set_hiu_bits(HHI_VIID_CLK_DIV, 8, 28, 4);
	/* release vclk2_div_reset and enable vclk2_div */
	cvbs_set_hiu_bits(HHI_VIID_CLK_DIV, 1, VCLK2_XD_EN, 2);
	//udelay(5);

	cvbs_set_hiu_bits(HHI_VIID_CLK_CNTL, 1, VCLK2_DIV1_EN, 1);
	cvbs_set_hiu_bits(HHI_VIID_CLK_CNTL, 1, VCLK2_SOFT_RST, 1);
	//udelay(10);
	cvbs_set_hiu_bits(HHI_VIID_CLK_CNTL, 0, VCLK2_SOFT_RST, 1);
	//udelay(5);
}

static int cvbs_config_clock(void)
{
	/* pll output 1485M */
	if (check_cpu_type(MESON_CPU_MAJOR_ID_G12A) ||
			check_cpu_type(MESON_CPU_MAJOR_ID_G12B)) {
		if (s_enci_clk_path & 0x1)
			cvbs_config_gp0pll_g12a();
		else
			cvbs_config_hdmipll_g12a();
	}
	else if (is_equal_after_meson_cpu(MESON_CPU_MAJOR_ID_GXL))
		cvbs_config_hdmipll_gxl();

	if (check_cpu_type(MESON_CPU_MAJOR_ID_G12A) ||
		check_cpu_type(MESON_CPU_MAJOR_ID_G12B)) {
		if (s_enci_clk_path & 0x2)
			cvbs_set_vid1_clk(s_enci_clk_path & 0x1);
		else
			cvbs_set_vid2_clk(s_enci_clk_path & 0x1);
	} else {
		cvbs_set_vid2_clk(0);
	}

	cvbs_set_hiu_bits(HHI_VID_CLK_CNTL2, 1, 0, 1);
	cvbs_set_hiu_bits(HHI_VID_CLK_CNTL2, 1, 4, 1);

	return 0;
}

/*----------------------------------------------------------------------------*/
// configuration for enci
static void cvbs_write_vcbus_array(struct reg_s *s)
{
	if (s == NULL)
		return ;

	while (s && (MREG_END_MARKER != s->reg))
	{
		cvbs_write_vcbus(s->reg, s->val);
		//printf("reg[0x%.2x] = 0x%.4x\n", s->reg, s->val);
		s ++;
	}
	return ;
}

#ifdef AML_CVBS_PERFORMANCE_COMPATIBILITY_SUPPORT

void cvbs_performance_config(void)
{
	int actived = AML_CVBS_PERFORMANCE_ACTIVED;
	char buf[32];

	sprintf(buf, "setenv cvbs_drv %d", actived);
	run_command(buf, 0);

	return ;
}

static void cvbs_performance_enhancement(int mode)
{
	unsigned int index = AML_CVBS_PERFORMANCE_ACTIVED;
	unsigned int max = 0;
	unsigned int type = 0;
	const struct reg_s *s = NULL;

	if (VMODE_PAL != mode && VMODE_PAL_M != mode && VMODE_PAL_N != mode)
		return;

	if (0xff == index)
		return;

	if (check_cpu_type(MESON_CPU_MAJOR_ID_M8B)) {
		max = sizeof(tvregs_576cvbs_performance_m8b)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_m8b[index];
		type = 1;
	} else if (check_cpu_type(MESON_CPU_MAJOR_ID_M8M2)) {
		max = sizeof(tvregs_576cvbs_performance_m8m2)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_m8m2[index];
		type = 2;
	} else if (check_cpu_type(MESON_CPU_MAJOR_ID_M8)) {
		max = sizeof(tvregs_576cvbs_performance_m8)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_m8[index];
		type = 3;
	} else if (check_cpu_type(MESON_CPU_MAJOR_ID_GXBB)) {
		max = sizeof(tvregs_576cvbs_performance_gxbb)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_gxbb[index];
		type = 4;
	} else if (check_cpu_type(MESON_CPU_MAJOR_ID_GXTVBB)) {
		max = sizeof(tvregs_576cvbs_performance_gxtvbb)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_gxtvbb[index];
		type = 5;
	} else if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) {
		max = sizeof(tvregs_576cvbs_performance_g12a)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_g12a[index];
		type = 9;
	} else if (is_meson_gxlx_cpu()) {
		max = sizeof(tvregs_576cvbs_performance_905l)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_905l[index];
		type = 7;
	} else if (is_equal_after_meson_cpu(MESON_CPU_MAJOR_ID_TXL)) {
		max = sizeof(tvregs_576cvbs_performance_txl)
			/ sizeof(struct reg_s *);
		index = (index >= max) ? 0 : index;
		s = tvregs_576cvbs_performance_txl[index];
		type = 8;
	} else if (is_equal_after_meson_cpu(MESON_CPU_MAJOR_ID_GXL)) {
		if (is_meson_gxl_package_905L()) {
			max = sizeof(tvregs_576cvbs_performance_905l)
				/ sizeof(struct reg_s *);
			index = (index >= max) ? 0 : index;
			s = tvregs_576cvbs_performance_905l[index];
			type = 7;
		} else {
			max = sizeof(tvregs_576cvbs_performance_905x)
				/ sizeof(struct reg_s *);
			index = (index >= max) ? 0 : index;
			s = tvregs_576cvbs_performance_905x[index];
			type = 6;
		}
	}

	printf("cvbs performance type = %d, table = %d\n", type, index);
	cvbs_write_vcbus_array((struct reg_s*)s);

	return;
}

#endif

static int cvbs_config_enci(int vmode)
{
	if (VMODE_PAL == vmode)
		cvbs_write_vcbus_array((struct reg_s*)&tvregs_576cvbs_enc[0]);
	else if (VMODE_NTSC == vmode)
		cvbs_write_vcbus_array((struct reg_s*)&tvregs_480cvbs_enc[0]);
	else if (VMODE_NTSC_M == vmode)
		cvbs_write_vcbus_array((struct reg_s*)&tvregs_480cvbs_enc[0]);
	else if (VMODE_PAL_M == vmode)
		cvbs_write_vcbus_array((struct reg_s*)&tvregs_pal_m_enc[0]);
	else if (VMODE_PAL_N == vmode)
		cvbs_write_vcbus_array((struct reg_s*)&tvregs_pal_n_enc[0]);

	cvbs_performance_enhancement(vmode);

	return 0;
}

/*----------------------------------------------------------------------------*/
// configuration for output
// output vmode: 576cvbs, 480cvbs
int cvbs_set_vmode(char* vmode_name)
{
	if (!strncmp(vmode_name, "576cvbs", strlen("576cvbs"))) {
		cvbs_mode = VMODE_PAL;
		cvbs_config_enci(0);
		cvbs_config_clock();
		cvbs_set_vdac(1);
		return 0;
	} else if (!strncmp(vmode_name, "480cvbs", strlen("480cvbs"))) {
		cvbs_mode = VMODE_NTSC;
		cvbs_config_enci(1);
		cvbs_config_clock();
		cvbs_set_vdac(1);
		return 0;
	} else if (!strncmp(vmode_name, "ntsc_m", strlen("ntsc_m"))) {
		cvbs_mode = VMODE_NTSC_M;
		cvbs_config_enci(VMODE_NTSC_M);
		cvbs_config_clock();
		cvbs_set_vdac(1);
		return 0;
	} else if (!strncmp(vmode_name, "pal_m", strlen("pal_m"))) {
		cvbs_mode = VMODE_PAL_M;
		cvbs_config_enci(VMODE_PAL_M);
		cvbs_config_clock();
		cvbs_set_vdac(1);
		return 0;
	} else if (!strncmp(vmode_name, "pal_n", strlen("pal_n"))) {
		cvbs_mode = VMODE_PAL_N;
		cvbs_config_enci(VMODE_PAL_N);
		cvbs_config_clock();
		cvbs_set_vdac(1);
		return 0;
	} else {
		printf("[%s] is invalid for cvbs.\n", vmode_name);
		return -1;
	}

	return 0;
}

/*----------------------------------------------------------------------------*/
// check for valid video mode
int cvbs_outputmode_check(char *vmode_name)
{
	if ((!strncmp(vmode_name, "576cvbs", strlen("576cvbs"))) ||
		(!strncmp(vmode_name, "480cvbs", strlen("480cvbs"))) ||
		(!strncmp(vmode_name, "ntsc_m", strlen("ntsc_m"))) ||
		(!strncmp(vmode_name, "pal_m", strlen("pal_m"))) ||
		(!strncmp(vmode_name, "pal_n", strlen("pal_n")))) {
		return 0;
	}

	printf("cvbs: outputmode[%s] is invalid\n", vmode_name);
	return -1;
}

/*----------------------------------------------------------------------------*/
// list for valid video mode
void cvbs_show_valid_vmode(void)
{
	printf("576cvbs\n""480cvbs\n""ntsc_m\n""pal_m\n""pal_n\n");
	return;
}

void cvbs_init(void)
{
#ifdef AML_CVBS_PERFORMANCE_COMPATIBILITY_SUPPORT
	cvbs_performance_config();
#endif

	return;
}

