bool _s5p_tv_if_init_hd_reg(void)
{
	struct s5p_tv_status *st = &s5ptv_status;
	bool timing_correction_en = st->hdmi_tg_cmd.timing_correction_en;
	bool bt656_sync_en = st->hdmi_tg_cmd.bt656_sync_en;
	bool tg_en;

	TVOUTIFPRINTK("audio type : %d, hdcp : %s)\n\r",
		st->hdmi_audio_type, st->hdcp_en ? "enabled" : "disabled");

/* C110_HDCP:
	if (st->hdcp_en) {
		if (!(st->hpd_status)) {
			TVOUTIFPRINTK("HPD is not detected\n\r");
			return false;
		}
	}
*/

	if (!_s5p_tv_if_init_hd_video_reg())
		return false;

	switch (st->hdmi_audio_type) {

	case HDMI_AUDIO_PCM:
		/* 
		* PCM, Samplingrate 44100, 16bit, 
		* ignore framesize cuz stream is PCM.
		*/
		__s5p_hdmi_audio_init(PCM, 44100, 16, 0); 
		break;

	case HDMI_AUDIO_NO:
		break;

	default:
		TVOUTIFPRINTK("invalid hdmi_audio_type(%d)\n\r",
			st->hdmi_audio_type);
		return false;
		break;
	}

	if (!__s5p_hdmi_start(st->hdmi_audio_type,
			      st->hdcp_en,
			      st->hdcp_i2c_client)) {
		return false;
	}

	st->hdmi_tg_cmd.tg_en = true;
	tg_en = st->hdmi_tg_cmd.tg_en;

	__s5p_hdmi_video_init_tg_cmd(timing_correction_en,
		bt656_sync_en, tg_en);

	return true;
}
/*
 * TV cut off sequence
 * VP stop -> Mixer stop -> HDMI stop -> HDMI TG stop
 * Above sequence should be satisfied.
 */
bool _s5p_tv_if_stop(void)
{
	struct s5p_tv_status *st = &s5ptv_status;

	bool t_corr_en 	 = st->hdmi_tg_cmd.timing_correction_en;
	bool sync_en 	 = st->hdmi_tg_cmd.bt656_sync_en;
	enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	TVOUTIFPRINTK("tvout sub sys. stopped!!\n");

	__s5p_vm_stop();

	switch (out_mode) {

	case TVOUT_OUTPUT_COMPOSITE:

	case TVOUT_OUTPUT_SVIDEO:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:

	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		if (st->tvout_output_enable)
			__s5p_sdout_stop();
		break;

	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_DVI:
		if (st->tvout_output_enable) {
			__s5p_hdmi_stop();
			__s5p_hdmi_video_init_tg_cmd(t_corr_en, sync_en,
				false);
		}
		break;

	default:
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", out_mode);
		return false;
		break;
	}


#ifdef CONFIG_CPU_S5PC100
	if (__s5p_tv_power_get_power_status()) {
		__s5p_tv_clk_stop();
		__s5p_tv_poweroff();
	}
#endif

	st->tvout_output_enable = false;
	st->tvout_param_available = false;

	return true;
}
bool _s5p_tv_if_init_hd_reg(void)
{
	s5p_tv_status *st = &s5ptv_status;
	
	TVOUTIFPRINTK("audio type : %d, hdcp : %s)\n\r", 
		st->hdmi_audio_type, st->hdcp_en ? "enabled":"disabled");

/* C110_HDCP: 
	if (st->hdcp_en) {
		if ( !(st->hpd_status)) {
			TVOUTIFPRINTK("HPD is not detected\n\r");
			return false;
		}
	}
*/

	if (!_s5p_tv_if_init_hd_video_reg())
		return false;

	switch (st->hdmi_audio_type) {

	case HDMI_AUDIO_PCM:
		/* 
		* PCM, Samplingrate 44100, 16bit, 
		* ignore framesize cuz stream is PCM.
		*/
		__s5p_hdmi_audio_init(PCM, 44100, 16, 0); 
		break;

	case HDMI_AUDIO_NO:
		break;

	default:
		TVOUTIFPRINTK("invalid hdmi_audio_type(%d)\n\r", 
			st->hdmi_audio_type);
		return false;
		break;
	}

/* C110_HDCP: */ //st->hpd_status = 1;

	__s5p_hdmi_stop();

	if (!__s5p_hdmi_start(st->hdmi_audio_type,
			      (st->hdcp_en && st->hpd_status),
			      st->hdcp_i2c_client)) {
		return false;
	}

	return true;
}
/*
 * TV cut off sequence
 * VP stop -> Mixer stop -> HDMI stop -> HDMI TG stop
 * Above sequence should be satisfied.
 */
bool s5p_tv_if_stop(void)
{
	struct s5p_tv_status *st = &g_s5ptv_status;

	bool t_corr_en = st->hdmi_tg_cmd.timing_correction_en;
	bool sync_en = st->hdmi_tg_cmd.bt656_sync_en;
	enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	TVOUTIFPRINTK("tvout sub sys. stopped!!\n");

	s5p_vm_stop();

	switch (out_mode) {
	case TVOUT_OUTPUT_COMPOSITE:
	case TVOUT_OUTPUT_SVIDEO:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		if (st->tvout_output_enable)
			s5p_sdout_stop();
		break;
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_DVI:
		if (st->tvout_output_enable) {
			s5p_hdmi_stop();
			s5p_hdmi_video_init_tg_cmd(t_corr_en, sync_en, false);
		}
		break;
	default:
		pr_err("%s::invalid out_mode parameter(%d)\n",
			__func__, out_mode);
		return false;
		break;
	}

	st->tvout_output_enable = false;
	st->tvout_param_available = false;

	return true;
}
bool _s5p_tv_if_start(void)
{
	s5p_tv_status *st = &s5ptv_status;
	s5p_tv_clk_err cerr = HDMI_NO_ERROR;

	s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	__s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, 
		false);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER, 
		false);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER, 
		false);

	_s5p_tv_if_stop();

	if (st->vp_layer_enable) 
	{
		_s5p_vlayer_stop();
		// In order to start video layer on the s5p_tv_resume() or handle_calbe() function
		st->vp_layer_enable = true; 
	}

	// Clear All Interrupt Pending
	__s5p_vm_clear_pend_all();
	

	/*
	* have not to call 
	* another request function simultaneously
	*/
#ifdef CONFIG_CPU_S5PC100

	s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode;

	if (!__s5p_tv_power_get_power_status()) { 
		__s5p_tv_poweron();
	}
#endif
#ifdef CONFIG_CPU_S5PV210
        // move to tv_phy_power()
	//__s5p_tv_poweron();
#endif
	__s5p_tv_clk_set_vmixer_hclk_onoff(true);
	__s5p_tv_clk_set_vmixer_sclk_onoff(true);

	switch (out_mode) {

	case TVOUT_OUTPUT_COMPOSITE:

	case TVOUT_OUTPUT_SVIDEO:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:

	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		__s5p_tv_clk_init_video_mixer(TVOUT_CLK_VMIXER_SRCCLK_VCLK_54);
		__s5p_tv_clk_set_sdout_hclk_onoff(true);
		__s5p_tv_clk_set_sdout_sclk_onoff(true);
		__s5p_tv_clk_set_hdmi_hclk_onoff(false);
		__s5p_tv_clk_set_hdmi_sclk_onoff(false);
#ifdef CONFIG_CPU_S5PC100
		__s5p_tv_clk_init_hpll(0xffff, 96, 6, 3);
#endif
#ifdef CONFIG_CPU_S5PV210
		__s5p_tv_clk_init_hpll(0, 0xffff, 108, 6, 3);
#endif		
		break;

	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:		
	case TVOUT_OUTPUT_DVI:
		__s5p_tv_clk_init_video_mixer(TVOUT_CLK_VMIXER_SRCCLK_MOUT_HPLL);
		__s5p_tv_clk_set_sdout_hclk_onoff(false);
		__s5p_tv_clk_set_sdout_sclk_onoff(false);
		__s5p_tv_clk_set_hdmi_hclk_onoff(true);
		__s5p_tv_clk_set_hdmi_sclk_onoff(true);


		cerr = __s5p_tv_clk_init_href(S5P_TV_CLK_HPLL_REF_27M);

		if (cerr != S5P_TV_CLK_ERR_NO_ERROR) {
			return false;
		}

		cerr = __s5p_tv_clk_init_mout_hpll(S5P_TV_CLK_MOUT_HPLL_FOUT_HPLL);

		if (cerr != S5P_TV_CLK_ERR_NO_ERROR) {
			return false;
		}

#ifdef CONFIG_CPU_S5PC100

		__s5p_tv_clk_init_hdmi_ratio(2);

		switch (disp_mode) {

		case TVOUT_480P_60_16_9:

		case TVOUT_480P_60_4_3:

		case TVOUT_576P_50_16_9:

		case TVOUT_576P_50_4_3:
			__s5p_tv_clk_init_hpll(0xffff, 96, 6, 3);
			break;

	
		case TVOUT_720P_50:

		case TVOUT_720P_60:
			__s5p_tv_clk_init_hpll(0xffff, 132, 6, 2);
			break;

		default:
			_s5p_tv_if_stop();
			TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r",
					out_mode);
			st->tvout_param_available = false;
			return false;
			break;
		}
#endif 

#ifdef CONFIG_CPU_S5PV210

		__s5p_tv_clk_init_hdmi_ratio(0);
#endif		
		
		__s5p_tv_clk_hpll_onoff(true);

#ifdef CONFIG_CPU_S5PC100
		__s5p_tv_poweroff();
		__s5p_tv_poweron();
#endif
		break;

	default:
		_s5p_tv_if_stop();
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", 
			st->tvout_param.out_mode);
		st->tvout_param_available = false;
		return false;
		break;
	}

	if (!_s5p_tv_if_init_vm_reg()) {
		return false;
	}

	switch (out_mode) {

	case TVOUT_OUTPUT_COMPOSITE:

	case TVOUT_OUTPUT_SVIDEO:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:

	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:

		if (!_s5p_tv_if_init_sd_reg()) {
			return false;
		}

		break;

	case TVOUT_OUTPUT_DVI:
		st->hdmi_audio_type = HDMI_AUDIO_NO;
		
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:		
		if (!_s5p_tv_if_init_hd_reg()) {
			return false;
		}

		break;

	default:
		_s5p_tv_if_stop();
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", 
				out_mode);
		return false;
		break;
	}

	st->tvout_output_enable = true;

	__s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, 
		true);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER, 
		true);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER, 
		true);

	// Clear All Interrupt Pending
	__s5p_vm_clear_pend_all();

	TVOUTIFPRINTK("()\n\r");

	return true;
}
bool _s5p_tv_if_init_avi_frame(tvout_output_if* tvout_if)
{
	s5p_tv_status *st = &s5ptv_status;
	TVOUTIFPRINTK("(%d, %d)\n\r", tvout_if->disp_mode, 
			tvout_if->out_mode);
	
	st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC;
	st->avi_byte[1] = AVI_ITU709;
	st->avi_byte[4] = AVI_NO_PIXEL_REPEAT;

	switch (tvout_if->disp_mode) {

#ifdef CONFIG_CPU_S5PV210
	case TVOUT_480P_59:
#endif
	case TVOUT_480P_60_16_9:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_3;
		break;

	case TVOUT_480P_60_4_3:
		st->avi_byte[1] |= AVI_PAR_4_3;
		st->avi_byte[3] = AVI_VIC_2;
		break;

	case TVOUT_576P_50_16_9:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_18;
		break;

	case TVOUT_576P_50_4_3:
		st->avi_byte[1] |= AVI_PAR_4_3;
		st->avi_byte[3] = AVI_VIC_17;
		break;

	case TVOUT_720P_50:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_19;
		break;

	case TVOUT_720P_60:
#ifdef CONFIG_CPU_S5PV210
	case TVOUT_720P_59:
#endif			
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_4;
		break;

#ifdef CONFIG_CPU_S5PV210
	case TVOUT_1080I_50:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_20;
		break;

	case TVOUT_1080I_59:
	case TVOUT_1080I_60:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_5;
		break;
		
	case TVOUT_1080P_50:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_31;
		break;

	case TVOUT_1080P_30:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_34;		

	case TVOUT_1080P_59:
	case TVOUT_1080P_60:
		st->avi_byte[1] |= AVI_PAR_16_9;
		st->avi_byte[3] = AVI_VIC_16;
		break;		
#endif
	default:
		TVOUTIFPRINTK("invalid disp_mode parameter(%d)\n\r", 
			tvout_if->out_mode);
		return false;
		break;
	}

	switch (tvout_if->out_mode) {

	case TVOUT_OUTPUT_DVI:
		st->hdmi_av_info_frame.trans_type = HDMI_DO_NOT_TANS;		
		st->avi_byte[0] = AVI_RGB_IF;
		st->avi_byte[1] = AVI_ITU601;
		break;
		
	case TVOUT_OUTPUT_HDMI_RGB:		
		st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC;
		st->avi_byte[0] = AVI_RGB_IF;
		st->avi_byte[1] = AVI_ITU601;
		break;

	case TVOUT_OUTPUT_HDMI:
		st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC;
		st->avi_byte[0] = AVI_YCBCR444_IF;
		st->avi_byte[1] = AVI_ITU709;
		break;

	default:
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r", 
			tvout_if->out_mode);
		return false;
		break;
	}

	st->hdmi_av_info_frame.check_sum = _s5p_tv_if_video_avi_checksum();

	TVOUTIFPRINTK("()\n\r");
	return true;
}
bool _s5p_tv_if_init_hd_video_reg(void)
{
	s5p_tv_hdmi_err herr = 0;
	s5p_tv_hdmi_csc_type cscType;
	s5p_tv_status *st = &s5ptv_status;

	bool blue_enable = st->hdmi_video_blue_screen.enable;
	u8 cb_b = st->hdmi_video_blue_screen.cb_b;
	u8 y_g = st->hdmi_video_blue_screen.y_g;
	u8 cr_r = st->hdmi_video_blue_screen.cr_r;
	
	u8 y_min = st->hdmi_color_range.y_min;
	u8 y_max = st->hdmi_color_range.y_max;
	u8 c_min = st->hdmi_color_range.c_min;
	u8 c_max = st->hdmi_color_range.c_max;

	s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode;
	s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	s5p_hdmi_transmit a_trans_type = st->hdmi_av_info_frame.trans_type;
	u8 a_check_sum = st->hdmi_av_info_frame.check_sum;
	u8 *a_data = st->hdmi_av_info_frame.data;

	s5p_hdmi_transmit m_trans_type = st->hdmi_mpg_info_frame.trans_type;
	u8 m_check_sum = st->hdmi_mpg_info_frame.check_sum;
	u8 *m_data = st->hdmi_mpg_info_frame.data;

	s5p_hdmi_transmit s_trans_type = st->hdmi_spd_info_frame.trans_type;
	u8 *spd_header = st->hdmi_spd_info_frame.spd_header;
	u8 *spd_data = st->hdmi_spd_info_frame.spd_data;

	bool timing_correction_en = st->hdmi_tg_cmd.timing_correction_en;
	bool bt656_sync_en = st->hdmi_tg_cmd.bt656_sync_en;
	bool tg_en;

	
	herr = __s5p_hdmi_video_init_display_mode(disp_mode,out_mode);

	if (herr != HDMI_NO_ERROR) {
		return false;
	}

	__s5p_hdmi_video_init_bluescreen(blue_enable,cb_b,y_g,cr_r);


	__s5p_hdmi_video_init_color_range(y_min,y_max,c_min,c_max);

	switch (out_mode) {

	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_HDMI:
		cscType = HDMI_BYPASS;
		break;
		
	case TVOUT_OUTPUT_DVI:
		cscType = HDMI_CSC_YUV601_TO_RGB_LR;
		break;

	default:
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r",
				out_mode);
		return false;
		break;
	}

	herr = __s5p_hdmi_video_init_csc(cscType);

	if (herr != HDMI_NO_ERROR) {
		return false;
	}

	herr =  __s5p_hdmi_video_init_avi_infoframe(a_trans_type,
					a_check_sum,a_data);

	if (herr != HDMI_NO_ERROR) {
		return false;
	}

	herr = __s5p_hdmi_video_init_mpg_infoframe(m_trans_type,
					m_check_sum,m_data);

	if (herr != HDMI_NO_ERROR) {
		return false;
	}

	herr = __s5p_hdmi_init_spd_infoframe(s_trans_type,
					spd_header,spd_data);

	if (herr != HDMI_NO_ERROR) {
		return false;
	}

	st->hdmi_tg_cmd.tg_en = true;
	tg_en = st->hdmi_tg_cmd.tg_en;

	__s5p_hdmi_video_init_tg_cmd(timing_correction_en,bt656_sync_en,tg_en);

	return true;
}
bool _s5p_tv_if_init_vm_reg(void)
{
	u8 i = 0;
	s5p_tv_vmx_err merr = 0;
	s5p_tv_status *st = &s5ptv_status;
	s5p_tv_o_mode out_mode = st->tvout_param.out_mode;
	s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode;

	bool cr_en = st->bg_dither.cr_dither_en;
	bool cb_en = st->bg_dither.cr_dither_en;
	bool y_en = st->bg_dither.cr_dither_en;
		
	s5p_vmx_burst_mode burst = st->grp_burst;
	s5p_endian_type endian = st->grp_endian;
	

	merr = __s5p_vm_init_status_reg(burst,endian);

	if (merr != VMIXER_NO_ERROR) {
		return false;
	}

	merr = __s5p_vm_init_display_mode(disp_mode,out_mode);

	if (merr != VMIXER_NO_ERROR) {
		return false;
	}

	__s5p_vm_init_bg_dither_enable(cr_en,cb_en,y_en);

	for(i = VMIXER_BG_COLOR_0; i <= VMIXER_BG_COLOR_2; i++) {
		merr = __s5p_vm_init_bg_color(i,
				     st->bg_color[i].color_y,
				     st->bg_color[i].color_cb,
				     st->bg_color[i].color_cr);

		if (merr != VMIXER_NO_ERROR)
			return false;
	}

	switch (out_mode) {

	case TVOUT_OUTPUT_COMPOSITE:

	case TVOUT_OUTPUT_SVIDEO:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:

	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		__s5p_vm_init_csc_coef_default(VMIXER_CSC_RGB_TO_YUV601_FR);
		break;

	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_DVI:

		switch (disp_mode) {

		case TVOUT_NTSC_M :

		case TVOUT_PAL_BDGHI:

		case TVOUT_PAL_M:

		case TVOUT_PAL_N:

		case TVOUT_PAL_NC:

		case TVOUT_PAL_60:

		case TVOUT_NTSC_443:
			break;

		case TVOUT_480P_60_16_9:

		case TVOUT_480P_60_4_3:
#ifdef CONFIG_CPU_S5PV210
// SPMOON_TEST
		case TVOUT_480P_59:			
#endif
		case TVOUT_576P_50_16_9:

		case TVOUT_576P_50_4_3:
			__s5p_vm_init_csc_coef_default(VMIXER_CSC_RGB_TO_YUV601_FR);
			break;

		case TVOUT_720P_60:

		case TVOUT_720P_50:

#ifdef CONFIG_CPU_S5PV210
// SPMOON_TEST
		case TVOUT_720P_59:			

		case TVOUT_1080I_60:

		case TVOUT_1080I_59:

		case TVOUT_1080I_50:
			
		case TVOUT_1080P_60:

		case TVOUT_1080P_30:

		case TVOUT_1080P_59:			

		case TVOUT_1080P_50:
#endif				
			__s5p_vm_init_csc_coef_default(VMIXER_CSC_RGB_TO_YUV709_FR);
		break;
		}

		break;

	default:
		TVOUTIFPRINTK("invalid tvout_param.out_mode parameter(%d)\n\r",
			      out_mode);
		return false;
		break;
	}

	__s5p_vm_start();

	return true;
}
/*
* before call this ftn. set the status data!!
*/
bool _s5p_tv_if_set_disp(void)
{
	s5p_tv_status *st = &s5ptv_status;

	s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode;
	s5p_tv_o_mode out_mode = st->tvout_param.out_mode;
	
	TVOUTIFPRINTK("(%d, %d)\n\r",disp_mode,out_mode);

	switch (disp_mode) {

	case TVOUT_NTSC_M:

	case TVOUT_NTSC_443:
		st->sdout_video_scale_cfg.component_level=S5P_TV_SD_LEVEL_0IRE;
		st->sdout_video_scale_cfg.component_ratio=SDOUT_VTOS_RATIO_7_3;
		st->sdout_video_scale_cfg.composite_level=S5P_TV_SD_LEVEL_75IRE;
		st->sdout_video_scale_cfg.composite_ratio=SDOUT_VTOS_RATIO_10_4;
		break;

	case TVOUT_PAL_BDGHI:

	case TVOUT_PAL_M:

	case TVOUT_PAL_N:

	case TVOUT_PAL_NC:

	case TVOUT_PAL_60:
		st->sdout_video_scale_cfg.component_level=S5P_TV_SD_LEVEL_0IRE;
		st->sdout_video_scale_cfg.component_ratio=SDOUT_VTOS_RATIO_7_3;
		st->sdout_video_scale_cfg.composite_level=S5P_TV_SD_LEVEL_0IRE;
		st->sdout_video_scale_cfg.composite_ratio=SDOUT_VTOS_RATIO_7_3;
		break;

	case TVOUT_480P_60_16_9:

	case TVOUT_480P_60_4_3:

	case TVOUT_576P_50_16_9:

	case TVOUT_576P_50_4_3:

	case TVOUT_720P_50:

	case TVOUT_720P_60:

#ifdef CONFIG_CPU_S5PV210

	case TVOUT_1080I_50:

	case TVOUT_1080I_60:

	case TVOUT_1080P_50:

	case TVOUT_1080P_60:

	case TVOUT_1080P_30:		

	case TVOUT_480P_59:		

	case TVOUT_720P_59:		

	case TVOUT_1080I_59:

	case TVOUT_1080P_59:		
#endif		
		if (!_s5p_tv_if_init_avi_frame(&st->tvout_param)) {
			st->tvout_param_available = false;
			return false;
		}

		break;

	default:
		TVOUTIFPRINTK("invalid disp_mode parameter(%d)\n\r",disp_mode);
		st->tvout_param_available = false;
		return false;
		break;
	}

	switch (out_mode) {

	case TVOUT_OUTPUT_COMPOSITE:
		st->sdout_order = S5P_TV_SD_O_ORDER_COMPOSITE_Y_C_CVBS;
		st->sdout_dac_on[2] = false;
		st->sdout_dac_on[1] = false;
		st->sdout_dac_on[0] = true;
		break;

	case TVOUT_OUTPUT_SVIDEO:
		st->sdout_order = S5P_TV_SD_O_ORDER_COMPOSITE_C_Y_CVBS;
		st->sdout_dac_on[2] = true;
		st->sdout_dac_on[1] = true;
		st->sdout_dac_on[0] = false;
		break;

	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:

	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		st->sdout_order = S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY;
		st->sdout_dac_on[2] = true;
		st->sdout_dac_on[1] = true;
		st->sdout_dac_on[0] = true;
		break;

	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_DVI:
		st->hdmi_video_blue_screen.cb_b = 0;//128;
		st->hdmi_video_blue_screen.y_g  = 0;
		st->hdmi_video_blue_screen.cr_r = 0;//128;
		break;

	default:
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r",out_mode);
		st->tvout_param_available = false;
		return false;
		break;
	}
#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_PM_PWR_GATING )
    if((st->hpd_status) && st->suspend_status == false)
    {
#endif
	_s5p_tv_if_start();
#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_PM_PWR_GATING )
    }
    // If the cable is not inserted or system is on suspend mode 
    // Just set variable, _s5p_tv_if_start() function will be called in resume or handle_cable function according to this variable
    else
        st->tvout_output_enable = true;
#endif
	
	return true;
}
bool _s5p_tv_if_init_hd_video_reg(void)
{
	enum s5p_tv_hdmi_err herr = 0;
	enum s5p_tv_hdmi_csc_type cscType;
	struct s5p_tv_status *st = &s5ptv_status;

	u8 cb_b = st->hdmi_video_blue_screen.cb_b;
	u8 y_g = st->hdmi_video_blue_screen.y_g;
	u8 cr_r = st->hdmi_video_blue_screen.cr_r;

	u8 y_min = st->hdmi_color_range.y_min;
	u8 y_max = st->hdmi_color_range.y_max;
	u8 c_min = st->hdmi_color_range.c_min;
	u8 c_max = st->hdmi_color_range.c_max;

	enum s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode;
	enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	enum s5p_hdmi_transmit *a_trans_type =
		&st->hdmi_av_info_frame.trans_type;
	u8 *a_check_sum = &st->hdmi_av_info_frame.check_sum;
	u8 *a_data = st->hdmi_av_info_frame.data;

	enum s5p_hdmi_transmit m_trans_type =
		st->hdmi_mpg_info_frame.trans_type;
	u8 m_check_sum = st->hdmi_mpg_info_frame.check_sum;
	u8 *m_data = st->hdmi_mpg_info_frame.data;

	enum s5p_hdmi_transmit s_trans_type =
		st->hdmi_spd_info_frame.trans_type;
	u8 *spd_header = st->hdmi_spd_info_frame.spd_header;
	u8 *spd_data = st->hdmi_spd_info_frame.spd_data;

	if (!_s5p_tv_if_init_avi_frame(&st->tvout_param)) {
		st->tvout_param_available = false;
		return false;
	}

	herr = __s5p_hdmi_video_init_display_mode(disp_mode, out_mode, a_data);

	if (herr != HDMI_NO_ERROR)
		return false;

	st->hdmi_av_info_frame.check_sum = _s5p_tv_if_video_avi_checksum();

	if (!st->hdcp_en)
		__s5p_hdmi_video_init_bluescreen(
				st->hdmi_video_blue_screen.enable,
				cb_b, y_g, cr_r);

	__s5p_hdmi_video_init_color_range(y_min, y_max, c_min, c_max);

	switch (out_mode) {

	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_HDMI:
		cscType = HDMI_BYPASS;
		break;

	case TVOUT_OUTPUT_DVI:
		cscType = HDMI_CSC_YUV601_TO_RGB_LR;
		s_trans_type = HDMI_DO_NOT_TANS;
		break;

	default:
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r",
				out_mode);
		return false;
		break;
	}

	herr = __s5p_hdmi_video_init_csc(cscType);

	if (herr != HDMI_NO_ERROR)
		return false;


	herr =  __s5p_hdmi_video_init_avi_infoframe(*a_trans_type,
					*a_check_sum, a_data);

	if (herr != HDMI_NO_ERROR)
		return false;


	herr = __s5p_hdmi_video_init_mpg_infoframe(m_trans_type,
					m_check_sum, m_data);

	if (herr != HDMI_NO_ERROR)
		return false;


	herr = __s5p_hdmi_init_spd_infoframe(s_trans_type,
					spd_header, spd_data);

	if (herr != HDMI_NO_ERROR)
		return false;

	return true;
}
/*
* before call this ftn. set the status data!!
*/
bool s5p_tv_if_set_disp(void)
{
	struct s5p_tv_status *st = &g_s5ptv_status;

	enum s5p_tv_disp_mode disp_mode = st->tvout_param.disp_mode;
	enum s5p_tv_o_mode    out_mode  = st->tvout_param.out_mode;

	TVOUTIFPRINTK("(%d, %d)\n", disp_mode, out_mode);

	switch (disp_mode) {
	case TVOUT_NTSC_M:
	case TVOUT_NTSC_443:
		st->sdout_video_scale_cfg.component_level =
			S5P_TV_SD_LEVEL_0IRE;
		st->sdout_video_scale_cfg.component_ratio =
			SDOUT_VTOS_RATIO_7_3;
		st->sdout_video_scale_cfg.composite_level =
			S5P_TV_SD_LEVEL_75IRE;
		st->sdout_video_scale_cfg.composite_ratio =
			SDOUT_VTOS_RATIO_10_4;
		break;
	case TVOUT_PAL_BDGHI:
	case TVOUT_PAL_M:
	case TVOUT_PAL_N:
	case TVOUT_PAL_NC:
	case TVOUT_PAL_60:
		st->sdout_video_scale_cfg.component_level =
			S5P_TV_SD_LEVEL_0IRE;
		st->sdout_video_scale_cfg.component_ratio =
			SDOUT_VTOS_RATIO_7_3;
		st->sdout_video_scale_cfg.composite_level =
			S5P_TV_SD_LEVEL_0IRE;
		st->sdout_video_scale_cfg.composite_ratio =
			SDOUT_VTOS_RATIO_7_3;
		break;
	case TVOUT_480P_60_16_9:
	case TVOUT_480P_60_4_3:
	case TVOUT_576P_50_16_9:
	case TVOUT_576P_50_4_3:
	case TVOUT_720P_50:
	case TVOUT_720P_60:
	case TVOUT_1080I_50:
	case TVOUT_1080I_60:
	case TVOUT_1080P_50:
	case TVOUT_1080P_60:
	case TVOUT_1080P_30:
	case TVOUT_480P_59:
	case TVOUT_720P_59:
	case TVOUT_1080I_59:
	case TVOUT_1080P_59:
		break;
	default:
		pr_err("%s::invalid disp_mode parameter(%d)\n",
			__func__, disp_mode);
		st->tvout_param_available = false;
		return false;
		break;
	}

	switch (out_mode) {
	case TVOUT_OUTPUT_COMPOSITE:
		st->sdout_order = S5P_TV_SD_O_ORDER_COMPOSITE_Y_C_CVBS;
		st->sdout_dac_on[SDOUT_CHANNEL_0] = true;
		st->sdout_dac_on[SDOUT_CHANNEL_1] = false;
		st->sdout_dac_on[SDOUT_CHANNEL_2] = false;
		break;
	case TVOUT_OUTPUT_SVIDEO:
		st->sdout_order = S5P_TV_SD_O_ORDER_COMPOSITE_C_Y_CVBS;
		st->sdout_dac_on[SDOUT_CHANNEL_0] = false;
		st->sdout_dac_on[SDOUT_CHANNEL_1] = true;
		st->sdout_dac_on[SDOUT_CHANNEL_2] = true;
		break;
	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		st->sdout_order = S5P_TV_SD_O_ORDER_COMPONENT_RBG_PRPBY;
		st->sdout_dac_on[SDOUT_CHANNEL_0] = true;
		st->sdout_dac_on[SDOUT_CHANNEL_1] = true;
		st->sdout_dac_on[SDOUT_CHANNEL_2] = true;
		break;
	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_DVI:
		st->hdmi_video_blue_screen.cb_b = 0;/* 128 */;
		st->hdmi_video_blue_screen.y_g  = 0;
		st->hdmi_video_blue_screen.cr_r = 0;/* 128 */;
		break;
	default:
		pr_err("%s::invalid out_mode parameter(%d)\n",
			__func__, out_mode);
		st->tvout_param_available = false;
		return false;
		break;
	}
#if defined(CONFIG_PM)
    if ((st->hpd_status) && st->suspend_status == false) {
#endif
	s5p_tv_if_start();
#if defined(CONFIG_PM)
    }
    /* If the cable is not inserted or system is on suspend mode
     * Just set variable, s5p_tv_if_start() function will be called in resume
     * or handle_cable function according to this variable
     */
    else
	    st->tvout_output_enable = true;
#endif

	return true;
}
bool s5p_tv_if_start(void)
{
	struct s5p_tv_status *st = &g_s5ptv_status;

	enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, false);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER,  false);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER,  false);

	s5p_tv_if_stop();

	if (st->vp_layer_enable) {
		s5p_vlayer_stop();
		/* In order to start video layer on the s5p_tv_resume()
		 * or handle_calbe() function
		 */
		st->vp_layer_enable = true;
	}

	/* Clear All Interrupt Pending */
	s5p_vm_clear_pend_all();

	/*
	* have not to call
	* another request function simultaneously
	*/
	switch (out_mode) {
	case TVOUT_OUTPUT_COMPOSITE:
	case TVOUT_OUTPUT_SVIDEO:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		clk_set_parent(st->sclk_mixer, st->sclk_dac);
		break;
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_DVI:
		clk_set_parent(st->sclk_mixer, st->sclk_hdmi);
		clk_set_parent(st->sclk_hdmi, st->sclk_hdmiphy);
		break;
	default:
		pr_err("%s::invalid out_mode parameter(%d)\n",
			__func__, st->tvout_param.out_mode);

		s5p_tv_if_stop();

		st->tvout_param_available = false;
		return false;
		break;
	}

	if (!s5p_tv_if_init_vm_reg()) {
		pr_err("%s::s5p_tv_if_init_vm_reg() fail\n", __func__);
		return false;
	}

	switch (out_mode) {
	case TVOUT_OUTPUT_COMPOSITE:
	case TVOUT_OUTPUT_SVIDEO:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		if (!s5p_tv_if_init_sd_reg()) {
			pr_err("%s::s5p_tv_if_init_sd_reg() fail\n",
				__func__);
			return false;
		}
		break;
	case TVOUT_OUTPUT_DVI:
		st->hdmi_audio_type = HDMI_AUDIO_NO;
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
		if (!s5p_tv_if_init_hd_reg()) {
			pr_err("%s::s5p_tv_if_init_hd_reg() fail\n",
				__func__);
			return false;
		}
		if (g_s5ptv_status.hdcp_en)
			s5p_start_hdcp();
		break;
	default:
		s5p_tv_if_stop();
		pr_err("%s::invalid out_mode parameter(%d)\n",
			__func__, out_mode);
		return false;
		break;
	}

	st->tvout_output_enable = true;

	s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, true);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER,  true);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER,  true);

	/* Clear All Interrupt Pending */
	s5p_vm_clear_pend_all();

	TVOUTIFPRINTK("()\n");

	return true;
}
static bool s5p_tv_if_init_avi_frame(struct tvout_output_if *tvout_if)
{
	struct s5p_tv_status *st = &g_s5ptv_status;
	TVOUTIFPRINTK("(%d, %d)\n", tvout_if->disp_mode,
			tvout_if->out_mode);

	st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC;
	st->avi_byte[1] = AVI_ITU709;
	st->avi_byte[4] = AVI_NO_PIXEL_REPEAT;

	switch (tvout_if->disp_mode) {
	case TVOUT_480P_59:
	case TVOUT_480P_60_16_9:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU601;
		st->avi_byte[3] = AVI_VIC_3;
		break;
	case TVOUT_480P_60_4_3:
		st->avi_byte[1] = AVI_PAR_4_3 | AVI_ITU601;
		st->avi_byte[3] = AVI_VIC_2;
		break;
	case TVOUT_576P_50_16_9:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU601;
		st->avi_byte[3] = AVI_VIC_18;
		break;
	case TVOUT_576P_50_4_3:
		st->avi_byte[1] = AVI_PAR_4_3 | AVI_ITU601;
		st->avi_byte[3] = AVI_VIC_17;
		break;
	case TVOUT_720P_50:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709;
		st->avi_byte[3] = AVI_VIC_19;
		break;
	case TVOUT_720P_60:
	case TVOUT_720P_59:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709;
		st->avi_byte[3] = AVI_VIC_4;
		break;
	case TVOUT_1080I_50:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709;
		st->avi_byte[3] = AVI_VIC_20;
		break;
	case TVOUT_1080I_59:
	case TVOUT_1080I_60:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709;
		st->avi_byte[3] = AVI_VIC_5;
		break;
	case TVOUT_1080P_50:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709;
		st->avi_byte[3] = AVI_VIC_31;
		break;
	case TVOUT_1080P_30:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709;
		st->avi_byte[3] = AVI_VIC_34;
	case TVOUT_1080P_59:
	case TVOUT_1080P_60:
		st->avi_byte[1] = AVI_PAR_16_9 | AVI_ITU709;
		st->avi_byte[3] = AVI_VIC_16;
		break;
	default:
		pr_err("%s::invalid disp_mode parameter(%d)\n",
			__func__, tvout_if->out_mode);
		return false;
		break;
	}

	switch (tvout_if->out_mode) {
	case TVOUT_OUTPUT_DVI:
		st->hdmi_av_info_frame.trans_type = HDMI_DO_NOT_TANS;
		st->avi_byte[0] = AVI_RGB_IF;
		break;
	case TVOUT_OUTPUT_HDMI_RGB:
		st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC;
		st->avi_byte[0] = AVI_RGB_IF;
		break;
	case TVOUT_OUTPUT_HDMI:
		st->hdmi_av_info_frame.trans_type = HDMI_TRANS_EVERY_SYNC;
		st->avi_byte[0] = AVI_YCBCR444_IF;
		break;
	default:
		pr_err("%s::invalid out_mode parameter(%d)\n",
			__func__, tvout_if->out_mode);
		return false;
		break;
	}

	st->avi_byte[1] |= AVI_SAME_WITH_PICTURE_AR;

	TVOUTIFPRINTK("()\n");
	return true;
}
bool _s5p_tv_if_start(void)
{
	struct s5p_tv_status *st = &s5ptv_status;


	enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	__s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER,
		false);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER,
		false);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER,
		false);

	_s5p_tv_if_stop();

	if (st->vp_layer_enable) 
	{
		_s5p_vlayer_stop();
		// In order to start video layer on the s5p_tv_resume() or handle_calbe() function
		st->vp_layer_enable = true; 
	}

	// Clear All Interrupt Pending
	__s5p_vm_clear_pend_all();


	/*
	* have not to call
	* another request function simultaneously
	*/
#ifdef CONFIG_CPU_S5PV210
        // move to tv_phy_power()
	//__s5p_tv_poweron();
#endif

	switch (out_mode) {

	case TVOUT_OUTPUT_COMPOSITE:

	case TVOUT_OUTPUT_SVIDEO:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:

	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:


#ifdef CONFIG_CPU_S5PV210
		clk_set_parent(st->sclk_mixer, st->sclk_dac);
#endif
		break;

	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_DVI:


#ifdef CONFIG_CPU_S5PV210
		clk_set_parent(st->sclk_mixer, st->sclk_hdmi);
		clk_set_parent(st->sclk_hdmi, st->sclk_hdmiphy);
#endif

		break;

	default:
		_s5p_tv_if_stop();
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r",
			st->tvout_param.out_mode);
		st->tvout_param_available = false;
		return false;
		break;
	}

	if (!_s5p_tv_if_init_vm_reg())
		return false;


	switch (out_mode) {

	case TVOUT_OUTPUT_COMPOSITE:

	case TVOUT_OUTPUT_SVIDEO:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:

	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:

	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:

		if (!_s5p_tv_if_init_sd_reg())
			return false;


		break;

	case TVOUT_OUTPUT_DVI:
		st->hdmi_audio_type = HDMI_AUDIO_NO;

	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
		if (!_s5p_tv_if_init_hd_reg())
			return false;
		if (s5ptv_status.hdcp_en)
		{
			__s5p_start_hdcp();
		}
		break;

	default:
		_s5p_tv_if_stop();
		TVOUTIFPRINTK("invalid out_mode parameter(%d)\n\r",
				out_mode);
		return false;
		break;
	}

	st->tvout_output_enable = true;

	__s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER,
		true);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER,
		true);
	__s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER,
		true);

	/* Clear All Interrupt Pending */
	__s5p_vm_clear_pend_all();

	TVOUTIFPRINTK("()\n\r");

	return true;
}