void decon_reg_set_clkval(u32 clkdiv)
{
	u32 val;

	decon_write_mask(VIDCON0, ~0, VIDCON0_CLKVALUP);

	val = (clkdiv >= 1) ? VIDCON0_CLKVAL_F(clkdiv - 1) : 0;
	decon_write_mask(VIDCON0, val, VIDCON0_CLKVAL_F_MASK);
}
void decon_reg_set_vidout(enum s3c_fb_psr_mode mode, u32 en)
{
	if (mode == S3C_FB_MIPI_COMMAND_MODE)
		decon_write_mask(VIDOUTCON0, VIDOUTCON0_I80IF_F, VIDOUTCON0_IF_MASK);
	else
		decon_write_mask(VIDOUTCON0, VIDOUTCON0_RGBIF_F, VIDOUTCON0_IF_MASK);

	decon_write_mask(VIDOUTCON0, en ? ~0 : 0, VIDOUTCON0_LCD_ON_F);
}
void decon_reg_set_rgb_order(enum decon_rgb_order order)
{
	u32 val = VIDCON2_RGB_ORDER_O_RGB;

	switch (order) {
	case DECON_RGB:
		val = VIDCON2_RGB_ORDER_O_RGB;
		break;
	case DECON_GBR:
		val = VIDCON2_RGB_ORDER_O_GBR;
		break;
	case DECON_BRG:
		val = VIDCON2_RGB_ORDER_O_BRG;
		break;
	case DECON_BGR:
		val = VIDCON2_RGB_ORDER_O_BGR;
		break;
	case DECON_RBG:
		val = VIDCON2_RGB_ORDER_O_RBG;
		break;
	case DECON_GRB:
		val = VIDCON2_RGB_ORDER_O_GRB;
		break;
	}

	decon_write_mask(VIDCON2, val, VIDCON2_RGB_ORDER_O_MASK);
}
void decon_reg_set_winmap(u32 idx, u32 color, u32 en)
{
	u32 val = en ? WINxMAP_MAP : 0;

	val |= WINxMAP_MAP_COLOUR(color);
	decon_write_mask(WINxMAP(idx), val, WINxMAP_MAP | WINxMAP_MAP_COLOUR_MASK);
}
irqreturn_t decon_int_irq_handler(int irq, void *dev_data)
{
	struct decon_device *decon = dev_data;
	u32 irq_sts_reg;
	ktime_t timestamp;
	u32 fifo_level;

	timestamp = ktime_get();

	spin_lock(&decon->slock);
	if ((decon->state == DECON_STATE_OFF) ||
		(decon->state == DECON_STATE_LPD)) {
		goto irq_end;
	}

	irq_sts_reg = decon_read(decon->id, VIDINTCON1);
	if (irq_sts_reg & VIDINTCON1_INT_FRAME) {
		/* VSYNC interrupt, accept it */
		decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FRAME);
		decon->vsync_info.timestamp = timestamp;
		wake_up_interruptible_all(&decon->vsync_info.wait);
	}
	if (irq_sts_reg & VIDINTCON1_INT_FIFO) {
		/* TODO: false underrun check only for EVT0. This will be removed in EVT1 */
		fifo_level = FRAMEFIFO_FIFO0_VALID_SIZE_GET(decon_read(decon->id, FRAMEFIFO_REG7));
		decon->underrun_stat.fifo_level = fifo_level;
		decon->underrun_stat.prev_overlap_cnt = decon->prev_overlap_cnt;
		decon->underrun_stat.cur_overlap_cnt = decon->cur_overlap_cnt;
		decon->underrun_stat.chmap = decon_read(0, WINCHMAP0);
		decon->underrun_stat.aclk = decon->res.aclk->rate;
		decon->underrun_stat.mif_pll = decon->res.mif_pll->rate;
		decon_int_get_enabled_win(decon);
		decon_oneshot_underrun_log(decon);
		decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FIFO);
		/* TODO: underrun function */
		/* s3c_fb_log_fifo_underflow_locked(decon, timestamp); */
	}
	if (irq_sts_reg & VIDINTCON1_INT_I80) {
		decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_I80);
	}

irq_end:
	spin_unlock(&decon->slock);

	return IRQ_HANDLED;
}
/* enable(unmask) / disable(mask) hw trigger */
void decon_reg_set_trigger(enum decon_trig_mode trig, enum decon_set_trig en)
{
	u32 val = (en == DECON_TRIG_ENABLE) ? ~0 : 0;
	u32 reg_id = TRIGCON_HWTRIGMASK_I80_RGB;

	if (trig == DECON_SW_TRIG)
		reg_id = TRIGCON_SWTRIGCMD_I80_RGB;

	decon_write_mask(TRIGCON, val, reg_id);
}
/* set DECON's interrupt. It depends on mode(video mode or command mode) */
void decon_reg_set_int(struct decon_psr_info *psr, u32 en)
{
	u32 val;

	val = VIDINTCON0_INT_ENABLE | VIDINTCON0_FIFOLEVEL_EMPTY |
		VIDINTCON0_INT_FIFO | VIDINTCON0_FIFOSEL_MAIN_EN;

	val |= VIDINTCON0_INT_FRAME | VIDINTCON0_FRAMESEL0_VSYNC;
	if (psr->psr_mode == S3C_FB_MIPI_COMMAND_MODE)
		val |= VIDINTCON0_INT_I80_EN;

	if (en) {
		if (psr->psr_mode == S3C_FB_MIPI_COMMAND_MODE)
			decon_write_mask(VIDINTCON1, ~0, VIDINTCON1_INT_I80);

		decon_write_mask(VIDINTCON0, val, ~0);
	} else {
		decon_write_mask(VIDINTCON0, 0, VIDINTCON0_INT_ENABLE);
	}
}
irqreturn_t decon_ext_dsi_irq_handler(int irq, void *dev_data)
{
	struct decon_device *decon = dev_data;
	ktime_t timestamp = ktime_get();
	u32 irq_sts_reg;
	u32 wb_irq_sts_reg;

	spin_lock(&decon->slock);

	irq_sts_reg = decon_read(decon->id, VIDINTCON1);
	wb_irq_sts_reg = decon_read(decon->id, VIDINTCON3);
	if (irq_sts_reg & VIDINTCON1_INT_FRAME) {
		/* VSYNC interrupt, accept it */
		decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FRAME);
		decon->vsync_info.timestamp = timestamp;
		wake_up_interruptible_all(&decon->vsync_info.wait);
	}
	if (irq_sts_reg & VIDINTCON1_INT_FIFO) {
		decon_err("DECON-ext FIFO underrun\n");
		decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_FIFO);
	}
	if (irq_sts_reg & VIDINTCON1_INT_I80) {
		decon_write_mask(decon->id, VIDINTCON1, ~0, VIDINTCON1_INT_I80);
		wake_up_interruptible_all(&decon->wait_frmdone);
	}
#if 0 
	if (wb_irq_sts_reg & VIDINTCON3_WB_FRAME_DONE) {
		decon_dbg("write-back frame done\n");
		DISP_SS_EVENT_LOG(DISP_EVT_WB_FRAME_DONE, &decon->sd, ktime_set(0, 0));
		decon_write_mask(decon->id, VIDINTCON3, ~0, VIDINTCON3_WB_FRAME_DONE);
		atomic_set(&decon->wb_done, STATE_DONE);
		wake_up_interruptible_all(&decon->wait_frmdone);
		decon_reg_per_frame_off(decon->id);
		decon_reg_update_standalone(decon->id);
		decon_reg_wb_swtrigger(decon->id);
		decon_reg_wait_stop_status_timeout(decon->id, 20 * 1000);
	}
#endif
	spin_unlock(&decon->slock);
	return IRQ_HANDLED;
}
void decon_reg_configure_trigger(enum decon_trig_mode mode)
{
	u32 val, mask;

	mask = TRIGCON_SWTRIGEN_I80_RGB | TRIGCON_HWTRIGEN_I80_RGB |
		TRIGCON_HWTRIGMASK_I80_RGB | TRIGCON_TRIGEN_PER_I80_RGB_F |
		TRIGCON_TRIGEN_I80_RGB_F;

	val = TRIGCON_TRIGEN_PER_I80_RGB_F | TRIGCON_TRIGEN_I80_RGB_F;

	if (mode == DECON_SW_TRIG)
		val |= TRIGCON_SWTRIGEN_I80_RGB;
	else
		val |= TRIGCON_HWTRIGEN_I80_RGB;

	decon_write_mask(TRIGCON, val, mask);
}
void decon_reg_set_fixvclk(enum decon_hold_scheme mode)
{
	u32 val = VIDCON1_VCLK_HOLD;

	switch (mode) {
	case DECON_VCLK_HOLD:
		val = VIDCON1_VCLK_HOLD;
		break;
	case DECON_VCLK_RUNNING:
		val = VIDCON1_VCLK_RUN;
		break;
	case DECON_VCLK_RUN_VDEN_DISABLE:
		val = VIDCON1_VCLK_RUN_VDEN_DISABLE;
		break;
	}

	decon_write_mask(VIDCON1, val, VIDCON1_VCLK_MASK);
}
void decon_reg_direct_on_off(u32 en)
{
	u32 val = en ? ~0 : 0;

	decon_write_mask(VIDCON0, val, VIDCON0_ENVID_F | VIDCON0_ENVID);
}
void decon_reg_set_crc(u32 en)
{
	u32 val = en ? ~0 : 0;

	decon_write_mask(CRCCTRL, val, CRCCTRL_CRCCLKEN | CRCCTRL_CRCEN);
}
/* enable each window */
void decon_reg_activate_window(u32 index)
{
	decon_write_mask(WINCON(index), ~0, WINCONx_ENWIN);
	decon_reg_update_standalone();
}
/* prohibit shadow update during writing something to SFR */
void decon_reg_shadow_protect_win(u32 idx, u32 protect)
{
	u32 val = protect ? ~0 : 0;

	decon_write_mask(SHADOWCON, val, SHADOWCON_WINx_PROTECT(idx));
}
void decon_reg_per_frame_off(void)
{
	decon_write_mask(VIDCON0, 0, VIDCON0_ENVID_F);
}
void decon_reg_set_freerun_mode(u32 en)
{
	decon_write_mask(VIDCON0, en ? ~0 : 0, VIDCON0_VLCKFREE);
}
void decon_reg_update_standalone(void)
{
	decon_write_mask(DECON_UPDATE, ~0, DECON_UPDATE_STANDALONE_F);
}
void decon_reg_set_clkgate_mode(u32 en)
{
	u32 val = en ? ~0 : 0;

	decon_write_mask(DECON_CMU, val, DECON_CMU_ALL_CLKGATE_ENABLE);
}