void single_frame_update(struct hisi_fb_data_type *hisifd)
{
	char __iomem *dss_base = NULL;

	BUG_ON(hisifd == NULL);

	dss_base = hisifd->dss_base;

	if (hisifd->index == PRIMARY_PANEL_IDX) {
		if (is_mipi_cmd_panel(hisifd)) {
			set_reg(dss_base + PDP_LDI_FRM_MSK, 1, 1, 24);
		}
		set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 0);
	} else if (hisifd->index == EXTERNAL_PANEL_IDX) {
		if (is_mipi_cmd_panel(hisifd)) {
			set_reg(dss_base + SDP_LDI_FRM_MSK, 1, 1, 24);
		}
		set_reg(dss_base + SDP_LDI_CTRL, 1, 1, 0);
	} else {
		;
	}

	if (hisifd->vsync_ctrl.vsync_report_fnc) {
		atomic_inc(&(hisifd->vsync_ctrl.buffer_updated));
	}
}
static int mipi_dsi_on_sub2(struct hisi_fb_data_type *hisifd, char __iomem *mipi_dsi_base)
{
	BUG_ON(hisifd == NULL);
	BUG_ON(mipi_dsi_base == NULL);

	if (is_mipi_video_panel(hisifd)) {
		/* switch to video mode */
		set_reg(mipi_dsi_base + MIPIDSI_MODE_CFG_OFFSET, 0x0, 1, 0);
	}

	if (is_mipi_cmd_panel(hisifd)) {
		/* cmd mode: high speed mode */
		set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x0, 7, 8);
		set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x0, 4, 16);
		set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x0, 1, 24);
	}

	/* enable EOTP TX */
	set_reg(mipi_dsi_base + MIPIDSI_PCKHDL_CFG_OFFSET, 0x1, 1, 0);

	/* enable generate High Speed clock */
	set_reg(mipi_dsi_base + MIPIDSI_LPCLK_CTRL_OFFSET, 0x1, 1, 0);

	return 0;
}
void hisi_dss_mctl_ov_set_ctl_dbg_reg(struct hisi_fb_data_type *hisifd, char __iomem *mctl_dgb)
{
	if (hisifd == NULL) {
		HISI_FB_ERR("hisifd is null");
		return;
	}

	if (is_mipi_cmd_panel(hisifd) && (hisifd->ldi_data_gate_en == 1)) {
		//open underflow clear
		set_reg(mctl_dgb, 0x782620, 32, 0);
	} else {
		//open underflow clear
		set_reg(mctl_dgb, 0x70A620, 32, 0);
		//set_reg(mctl_dgb, 0xB02620, 32, 0);
	}
}
void init_dpp(struct hisi_fb_data_type *hisifd)
{
	char __iomem *dpp_base = NULL;

	BUG_ON(hisifd == NULL);

	if (hisifd->index == PRIMARY_PANEL_IDX) {
		dpp_base = hisifd->dss_base + DSS_DPP0_CTRL_OFFSET;
	} else {
		HISI_FB_ERR("fb%d, not support!", hisifd->index);
		return ;
	}

	set_reg(dpp_base + DPP_IMG_HRZ, DSS_WIDTH(hisifd->panel_info.xres), 13, 0);
	set_reg(dpp_base + DPP_IMG_VRT, DSS_HEIGHT(hisifd->panel_info.yres), 13, 0);

#ifdef CONFIG_FIX_DIRTY_REGION_UPDT
	if (is_mipi_cmd_panel(hisifd)) {
		outp32(dpp_base + DPP_CLK_GT, 0xA);
	}
#endif
}
void init_ldi(struct hisi_fb_data_type *hisifd)
{
	char __iomem *dss_base = 0;
	struct hisi_panel_info *pinfo = NULL;

	BUG_ON(hisifd == NULL);

	pinfo = &(hisifd->panel_info);
	dss_base = hisifd->dss_base;

	if (hisifd->index == PRIMARY_PANEL_IDX) {
		if (is_dual_mipi_panel(hisifd)) {
			outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL0,
				pinfo->ldi.h_front_porch | (pinfo->ldi.h_back_porch << 16));
			outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL1,
				DSS_WIDTH(pinfo->xres / 2) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16));

			outp32(dss_base + PDP_LDI_DPI1_HRZ_CTRL0,
				pinfo->ldi.h_back_porch << 16);
			outp32(dss_base + PDP_LDI_DPI1_HRZ_CTRL1,
				DSS_WIDTH(pinfo->xres / 2) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16));

			outp32(dss_base + PDP_LDI_OVERLAP_SIZE,
				pinfo->ldi.dpi0_overlap_size | (pinfo->ldi.dpi1_overlap_size << 16));

			/* dual_mode_en */
			set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 5);
			/* split mode */
			set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 16);
		} else {
			outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL0,
				pinfo->ldi.h_front_porch | (pinfo->ldi.h_back_porch << 16));
			outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL1,
				DSS_WIDTH(pinfo->xres) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16));
		}
		outp32(dss_base + PDP_LDI_VRT_CTRL0,
			pinfo->ldi.v_front_porch | (pinfo->ldi.v_back_porch << 16));
		outp32(dss_base + PDP_LDI_VRT_CTRL1,
			DSS_HEIGHT(pinfo->yres) | (DSS_HEIGHT(pinfo->ldi.v_pulse_width) << 16));
		outp32(dss_base + PDP_LDI_PLR_CTRL,
			pinfo->ldi.vsync_plr | (pinfo->ldi.hsync_plr << 1) |
			(pinfo->ldi.pixelclk_plr << 2) | (pinfo->ldi.data_en_plr << 3));

		/* ldi disable */
		set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 0);
		/* data_gate_en: mipi command LCD open */
		if (is_mipi_cmd_panel(hisifd)) {
			//set_reg(dss_base + PDP_LDI_CTRL, 0x1, 1, 2);
			set_reg(dss_base + PDP_LDI_FRM_MSK, 0x1, 1, 0);
		}
		/* bpp */
		set_reg(dss_base + PDP_LDI_CTRL, pinfo->bpp, 2, 3);
		/* bgr */
		set_reg(dss_base + PDP_LDI_CTRL, pinfo->bgr_fmt, 1, 13);
		/* color mode: for mipi dsi */
		/*set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 14);*/
		/* shutdown: for mipi dsi */
		/*set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 15);*/

	#ifdef CONFIG_HISI_FB_COLORBAR_USED
		/* colorbar width */
		set_reg(dss_base + PDP_LDI_CTRL, DSS_WIDTH(0x3c), 7, 6);
		/* colorbar ort */
		set_reg(dss_base + PDP_LDI_WORK_MODE, 0, 1, 1);
		/* colorbar enable */
		set_reg(dss_base + PDP_LDI_WORK_MODE, 0, 1, 0);
	#else
		/* normal */
		outp32(dss_base + PDP_LDI_WORK_MODE, 0x1);
	#endif
		/* for ddr pmqos */
		outp32(dss_base + PDP_LDI_VINACT_MSK_LEN,
		pinfo->ldi.v_front_porch);
		outp32(dss_base + PDP_LDI_CG_CTRL, 0x0);
		/* use default value */
		/*outp32(dss_base + PDP_SRAM_LP_CTRL, );*/

		/* for 3D frame by frame */
		/*outp32(dss_base + PDP_LDI_3D_CTRL, );
		outp32(dss_base + PDP_LDI_DE_SPACE_LOW, );
		set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 1);*/

		/* for 1Hz LCD and mipi command LCD */
		/*outp32(dss_base + PDP_LDI_FRM_MSK, );*/
		if (is_mipi_cmd_panel(hisifd)) {
			set_reg(dss_base + PDP_DSI_CMD_MOD_CTRL, 0x1, 1, 0);
			set_reg(dss_base + PDP_DSI_TE_CTRL, 0x4001, 32, 0);
			set_reg(dss_base + PDP_DSI_TE_HS_NUM, 0x0, 32, 0);
			set_reg(dss_base + PDP_DSI_TE_HS_WD, 0xF0F, 32, 0);
			set_reg(dss_base + PDP_DSI_TE_VS_WD, 0x3FC0FF, 32, 0);
		}

		/*
		** for test
		** 2'b00: reserved
		** 2'b01: LDI0->DSI0
		** 2'b10: LDI0->DSI1
		** 2'b11: LDI1
		*/
	#if defined(CONFIG_ARCH_HI3630FPGA) || defined(CONFIG_HISI_3635_FPGA) \
		|| defined(CONFIG_HISI_3650_FPGA)
		set_reg(dss_base + DSS_GLB_TEST_SEL, 0x1, 2, 0);
	#endif
	} else if (hisifd->index == EXTERNAL_PANEL_IDX) {
		outp32(dss_base + SDP_LDI_HRZ_CTRL0,
			pinfo->ldi.h_front_porch | (pinfo->ldi.h_back_porch << 16));
		outp32(dss_base + SDP_LDI_HRZ_CTRL1,
			DSS_WIDTH(pinfo->xres) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16));
		outp32(dss_base + SDP_LDI_VRT_CTRL0,
			pinfo->ldi.v_front_porch | (pinfo->ldi.v_back_porch << 16));
		outp32(dss_base + SDP_LDI_VRT_CTRL1,
			DSS_HEIGHT(pinfo->yres) | (DSS_HEIGHT(pinfo->ldi.v_pulse_width) << 16));
		outp32(dss_base + SDP_LDI_PLR_CTRL,
			pinfo->ldi.vsync_plr | (pinfo->ldi.hsync_plr << 1) |
			(pinfo->ldi.pixelclk_plr << 2) | (pinfo->ldi.data_en_plr << 3));

		/* ldi disable */
		set_reg(dss_base + SDP_LDI_CTRL, 0, 1, 0);
		/* data_gate_en */
		/*set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 2);*/
		/* bpp */
		set_reg(dss_base + SDP_LDI_CTRL, pinfo->bpp, 2, 3);
		/* bgr */
		set_reg(dss_base + SDP_LDI_CTRL, pinfo->bgr_fmt, 1, 13);
		/* color mode */
		/*set_reg(dss_base + SDP_LDI_CTRL, 0, 1, 14);*/
		/* shutdown */
		/*set_reg(dss_base + SDP_LDI_CTRL, 0, 1, 15);*/

	#ifdef CONFIG_HISI_FB_COLORBAR_USED
		/* colorbar width */
		set_reg(dss_base + SDP_LDI_CTRL, DSS_WIDTH(0x3c), 7, 6);
		/* colorbar ort */
		set_reg(dss_base + SDP_LDI_WORK_MODE, 0, 1, 1);
		/* colorbar enable */
		set_reg(dss_base + SDP_LDI_WORK_MODE, 0, 1, 0);
	#else
		/* normal */
		outp32(dss_base + SDP_LDI_WORK_MODE, 0x1);
	#endif
		outp32(dss_base + SDP_LDI_VINACT_MSK_LEN,
			pinfo->ldi.v_front_porch);
	} else {
		HISI_FB_ERR("fb%d, not support!", hisifd->index);
		return ;
	}
}
void init_sbl(struct hisi_fb_data_type *hisifd)
{
	char __iomem *dpp_base = NULL;
	char __iomem *sbl_base = NULL;
	uint32_t tmp = 0;

	BUG_ON(hisifd == NULL);

	if (hisifd->index == PRIMARY_PANEL_IDX) {
		dpp_base = hisifd->dss_base + DSS_DPP0_CTRL_OFFSET;
		sbl_base = hisifd->dss_base + DSS_DPP_SBL_OFFSET;
	} else {
		HISI_FB_ERR("fb%d, not support!", hisifd->index);
		return ;
	}

	if (is_mipi_cmd_panel(hisifd)) {
		outp32(sbl_base + SBL_CONFIG_BUFFER_MODE, 0x2);
	} else {
		outp32(sbl_base + SBL_CONFIG_BUFFER_MODE, 0x0);
	}

	outp32(sbl_base + SBL_AUTOMATIC_START_CALC_STRENGTH_DRC_BACKLIGHT_SEL, 0x80);
	tmp = hisifd->panel_info.xres;
	outp32(sbl_base + SBL_FRAME_WIDTH_L, (tmp & 0xff));
	outp32(sbl_base + SBL_FRAME_WIDTH_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.yres;
	outp32(sbl_base + SBL_FRAME_HEIGHT_L, (tmp & 0xff));
	outp32(sbl_base + SBL_FRAME_HEIGHT_H, ((tmp >> 8) & 0xff));
	outp32(sbl_base + SBL_APICAL_DITHER, 0x0);
	tmp = hisifd->bl_level;
	outp32(sbl_base + SBL_BACKLIGHT_L, (tmp & 0xff));
	outp32(sbl_base + SBL_BACKLIGHT_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.backlight_scale;
	outp32(sbl_base + SBL_BACKLIGHT_SCALE_L, (tmp & 0xff));
	outp32(sbl_base + SBL_BACKLIGHT_SCALE_H, (tmp >> 8) & 0xff);
	tmp = hisifd->panel_info.smart_bl.strength_limit;
	outp32(sbl_base + SBL_STRENGTH_LIMIT, tmp);
	tmp = hisifd->panel_info.smart_bl.calibration_a;
	outp32(sbl_base + SBL_CALIBRATION_A_L, (tmp & 0xff));
	outp32(sbl_base + SBL_CALIBRATION_A_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.calibration_b;
	outp32(sbl_base + SBL_CALIBRATION_B_L, (tmp & 0xff));
	outp32(sbl_base + SBL_CALIBRATION_B_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.calibration_c;
	outp32(sbl_base + SBL_CALIBRATION_C_L, (tmp & 0xff));
	outp32(sbl_base + SBL_CALIBRATION_C_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.calibration_d;
	outp32(sbl_base + SBL_CALIBRATION_D_L, (tmp & 0xff));
	outp32(sbl_base + SBL_CALIBRATION_D_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.t_filter_control;
	outp32(sbl_base + SBL_T_FILTER_CONTROL, tmp);
	tmp = hisifd->panel_info.smart_bl.backlight_min;
	outp32(sbl_base + SBL_BACKLIGHT_MIN_L, (tmp & 0xff));
	outp32(sbl_base + SBL_BACKLIGHT_MIN_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.backlight_max;
	outp32(sbl_base + SBL_BACKLIGHT_MAX_L, (tmp & 0xff));
	outp32(sbl_base + SBL_BACKLIGHT_MAX_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.ambient_light_min;
	outp32(sbl_base + SBL_AMBIENT_LIGHT_MIN_L, (tmp & 0xff));
	outp32(sbl_base + SBL_AMBIENT_LIGHT_MIN_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.filter_a;
	outp32(sbl_base + SBL_FILTER_A_L, (tmp & 0xff));
	outp32(sbl_base + SBL_FILTER_A_H, ((tmp >> 8) & 0xff));
	tmp = hisifd->panel_info.smart_bl.filter_b;
	outp32(sbl_base + SBL_FILTER_B, tmp);
	tmp = hisifd->panel_info.smart_bl.logo_left;
	outp32(sbl_base + SBL_LOGO_LEFT, tmp);
	tmp = hisifd->panel_info.smart_bl.logo_top;
	outp32(sbl_base + SBL_LOGO_TOP, tmp);
	outp32(sbl_base + SBL_ENABLE, 0x0);

	if (hisifd->panel_info.sbl_support == 1) {
		outp32(dpp_base + DPP_SBL, 0x1);
	} else {
		outp32(dpp_base + DPP_SBL, 0x0);
	}
}
예제 #7
0
static void dpe_interrupt_unmask(struct k3_fb_data_type *k3fd)
{
	char __iomem *dss_base = 0;
	u32 unmask = 0;

	BUG_ON(k3fd == NULL);

	dss_base = k3fd->dss_base;

	if (k3fd->index == PRIMARY_PANEL_IDX) {
		/* Stage 1  interrupts */
		//unmask = ~0;
		//unmask &= ~(BIT_PDP_LDI0_IRQ_CPU | BIT_WBE0_MMU_IRQ_CPU);
		unmask = 0x0;
		outp32(dss_base + DSS_GLB_PDP_CPU_IRQ_MSK, unmask);

		/*
		** Stage 2 interrupts
		** BIT_LDI_UNFLOW_INT in k3_baselayer_init
		*/
		unmask = ~0;

		if (is_mipi_cmd_panel(k3fd))
			unmask &= ~(BIT_BACKLIGHT_INT | BIT_VACTIVE0_START_INT | BIT_LDI_TE0_PIN_INT);
		else
			unmask &= ~(BIT_BACKLIGHT_INT | BIT_VSYNC_INT | BIT_VACTIVE0_START_INT);
		outp32(dss_base + PDP_LDI_CPU_IRQ_MSK, unmask);

		unmask = ~0;
		unmask &= ~(BIT_WBE0_FRAME_END_CPU_CH1 | BIT_WBE0_FRAME_END_CPU_CH0);
		outp32(dss_base + DSS_DPE0_OFFSET +
			DSS_DP_CTRL_OFFSET + PDP_WBE0_CPU_IRQ_MSK, unmask);
	} else if (k3fd->index == EXTERNAL_PANEL_IDX) {
		/* Stage 1  interrupts */
		//unmask = ~0;
		//unmask &= ~(BIT_SDP_LDI1_IRQ_MCU | BIT_WBE0_MMU_IRQ_CPU);
		unmask = 0x0;
		outp32(dss_base + DSS_GLB_SDP_CPU_IRQ_MSK, unmask);

		/* Stage 2 interrupts */
		unmask = ~0;
		unmask &= ~(BIT_VSYNC_INT | BIT_VACTIVE0_START_INT);
		outp32(dss_base + SDP_LDI_CPU_IRQ_MSK, unmask);

		unmask = ~0;
		unmask &= ~(BIT_WBE0_FRAME_END_CPU_CH1 | BIT_WBE0_FRAME_END_CPU_CH0);
		outp32(dss_base + DSS_DPE1_OFFSET +
			DSS_DP_CTRL_OFFSET + SDP_WBE0_CPU_IRQ_MSK, unmask);
	} else if (k3fd->index == AUXILIARY_PANEL_IDX) {
		/* Stage 1  interrupts */
		//unmask = ~0;
		//unmask &= ~(BIT_OFFLINE_S2_IRQ_CPU_OFF |
		//	BIT_WBE1_MMU_IRQ_CPU_OFF | BIT_WBE0_MMU_IRQ_CPU_OFF |
		//	BIT_CMDLIST_IRQ_CPU_OFF);
		unmask = 0x0;
		outp32(dss_base + DSS_GLB_OFFLINE_CPU_IRQ_MSK, unmask);

		/* Stage 2 interrupts */
		unmask = ~0;
		unmask &= ~(BIT_OFFLINE_WBE1_CH0_FRM_END_CPU |
			BIT_OFFLINE_WBE1_CH1_FRM_END_CPU);
		outp32(dss_base + DSS_DPE3_OFFSET +
			DSS_DP_CTRL_OFFSET + OFFLINE_WBE1_CPU_IRQ_MSK, unmask);

		/* enable adp irq */
		//outp32(dss_base + DSS_GLB_OFFLINE_S2_CPU_IRQ_MSK, 0);
		/* enable cmdlist irq */
		//set_reg(dss_base + DSS_CMD_LIST_OFFSET + CMDLIST_CH4_INTE, 0x3F, 6, 0);
		//set_reg(dss_base + DSS_CMD_LIST_OFFSET + CMDLIST_CH5_INTE, 0x3F, 6, 0);
	} else {
		K3_FB_ERR("fb%d, not support this device!\n", k3fd->index);
	}
}
static void mipi_init(struct hisi_fb_data_type *hisifd, char __iomem *mipi_dsi_base)
{
	uint32_t hline_time = 0;
	uint32_t hsa_time = 0;
	uint32_t hbp_time = 0;
	uint32_t pixel_clk = 0;
	unsigned long dw_jiffies = 0;
	struct mipi_dsi_phy_ctrl phy_ctrl = {0};
	uint32_t tmp = 0;
	bool is_ready = false;
	struct hisi_panel_info *pinfo = NULL;

	BUG_ON(hisifd == NULL);
	BUG_ON(mipi_dsi_base == NULL);

	pinfo = &(hisifd->panel_info);
	get_dsi_phy_ctrl(pinfo->mipi.dsi_bit_clk, &phy_ctrl);

	/* config TE */
	if (is_mipi_cmd_panel(hisifd)) {
		/* config to command mode */
		set_reg(mipi_dsi_base + MIPIDSI_MODE_CFG_OFFSET, 0x1, 1, 0);
		/* ALLOWED_CMD_SIZE */
		set_reg(mipi_dsi_base + MIPIDSI_EDPI_CMD_SIZE_OFFSET, pinfo->xres, 16, 0);
		/* cnt=2 in update-patial scene, cnt nees to be checked for different panels*/
		set_reg(mipi_dsi_base + MIPIDSI_HS_WR_TO_CNT_OFFSET, 0x1000002, 25, 0);

		/* phy_stop_wait_time */
		set_reg(mipi_dsi_base + MIPIDSI_PHY_IF_CFG_OFFSET, 0x30, 8, 8);

		/* FIXME: test tearing effect, if use gpio, no need */
		/*set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x1, 1, 0);*/
	}

	/*--------------configuring the DPI packet transmission----------------*/
	/*
	** 1. Global configuration
	** Configure Register PHY_IF_CFG with the correct number of lanes
	** to be used by the controller.
	*/
	set_reg(mipi_dsi_base + MIPIDSI_PHY_IF_CFG_OFFSET, pinfo->mipi.lane_nums, 2, 0);

	/*
	** 2. Configure the DPI Interface:
	** This defines how the DPI interface interacts with the controller.
	*/
	set_reg(mipi_dsi_base + MIPIDSI_DPI_VCID_OFFSET, pinfo->mipi.vc, 2, 0);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_COLOR_CODING_OFFSET, pinfo->mipi.color_mode, 4, 0);

	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.data_en_plr, 1, 0);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.vsync_plr, 1, 1);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.hsync_plr, 1, 2);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, 0x0, 1, 3);
	set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, 0x0, 1, 4);

	if (pinfo->bpp == LCD_RGB666) {
		set_reg(mipi_dsi_base + MIPIDSI_DPI_COLOR_CODING_OFFSET, 0x1, 1, 8);
	}

	/*
	** 3. Select the Video Transmission Mode:
	** This defines how the processor requires the video line to be
	** transported through the DSI link.
	*/

	/* video mode: low power mode */
	set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, 0x3f, 6, 8);
	/* set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, 0x0, 1, 14); */

	/* burst mode */
	set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, phy_ctrl.burst_mode, 2, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_PKT_SIZE_OFFSET, pinfo->xres, 14, 0);

	/* for dsi read, BTA enable*/
	set_reg(mipi_dsi_base + MIPIDSI_PCKHDL_CFG_OFFSET, 0x1, 1, 2);

	/*
	** 4. Define the DPI Horizontal timing configuration:
	**
	** Hsa_time = HSA*(PCLK period/Clk Lane Byte Period);
	** Hbp_time = HBP*(PCLK period/Clk Lane Byte Period);
	** Hline_time = (HSA+HBP+HACT+HFP)*(PCLK period/Clk Lane Byte Period);
	*/
	pixel_clk = pinfo->pxl_clk_rate / 1000000;
	hsa_time = pinfo->ldi.h_pulse_width * phy_ctrl.lane_byte_clk / pixel_clk;
	hbp_time = pinfo->ldi.h_back_porch * phy_ctrl.lane_byte_clk / pixel_clk;
	hline_time = (pinfo->ldi.h_pulse_width + pinfo->ldi.h_back_porch +
		pinfo->xres + pinfo->ldi.h_front_porch) *
		phy_ctrl.lane_byte_clk / pixel_clk;
	set_reg(mipi_dsi_base + MIPIDSI_VID_HSA_TIME_OFFSET, hsa_time, 12, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_HBP_TIME_OFFSET, hbp_time, 12, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_HLINE_TIME_OFFSET, hline_time, 15, 0);

	/*
	** 5. Define the Vertical line configuration:
	*/
	set_reg(mipi_dsi_base + MIPIDSI_VID_VSA_LINES_OFFSET, pinfo->ldi.v_pulse_width, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_VBP_LINES_OFFSET, pinfo->ldi.v_back_porch, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_VFP_LINES_OFFSET, pinfo->ldi.v_front_porch, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_VID_VACTIVE_LINES_OFFSET, pinfo->yres, 14, 0);
	set_reg(mipi_dsi_base + MIPIDSI_TO_CNT_CFG_OFFSET, 0x7FF, 16, 0);

	/* Configure core's phy parameters */
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, 4095, 15, 0);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET, phy_ctrl.clk_lane_lp2hs_time, 10, 0);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET, phy_ctrl.clk_lane_hs2lp_time, 10, 16);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, phy_ctrl.data_lane_lp2hs_time, 8, 16);
	set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, phy_ctrl.data_lane_hs2lp_time, 8, 24);

	/*------------DSI and D-PHY Initialization-----------------*/
	/* 1. Waking up Core */
	set_reg(mipi_dsi_base + MIPIDSI_PWR_UP_OFFSET, 0x1, 1, 0);

	/*
	** 3. Configure the TX_ESC clock frequency to a frequency lower than 20 MHz
	** that is the maximum allowed frequency for D-PHY ESCAPE mode.
	*/

	set_reg(mipi_dsi_base + MIPIDSI_CLKMGR_CFG_OFFSET, phy_ctrl.clk_division, 8, 0);
	set_reg(mipi_dsi_base + MIPIDSI_CLKMGR_CFG_OFFSET, phy_ctrl.clk_division, 8, 8);


	/*
	** 4. Configure the DPHY PLL clock frequency through the TEST Interface to
	** operate at XX Hz,
	*/

	/* Write CP current */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010011);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.cp_current);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write LPF Control */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010012);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.lpf_ctrl);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/*Configured N and M factors effective*/
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010019);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.factors_effective);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write N Pll */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010017);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.n_pll-1);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write M Pll part 1 */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_1);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write M Pll part 2 */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_2);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Set hsfreqrange */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010044);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.hsfreqrange);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Set PLL unlocking filter */
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010016);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.pll_unlocking_filter);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

#if 0
	/* Set the phy direction*/
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x000100b0);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00000001);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
#endif

	outp32(mipi_dsi_base + MIPIDSI_PHY_RSTZ_OFFSET, 0x0000000F);

	is_ready = false;
	dw_jiffies = jiffies + HZ / 2;
	do {
		tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET);
		if ((tmp & 0x00000001) == 0x00000001) {
			is_ready = true;
			break;
		}
	} while (time_after(dw_jiffies, jiffies));

	if (!is_ready) {
		HISI_FB_INFO("fb%d, phylock is not ready!MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n",
			hisifd->index, tmp);
	}

	is_ready = false;
	dw_jiffies = jiffies + HZ / 2;
	do {
		tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET);
		if ((tmp & 0x00000004) == 0x00000004) {
			is_ready = true;
			break;
		}
	} while (time_after(dw_jiffies, jiffies));

	if (!is_ready) {
		HISI_FB_INFO("fb%d, phystopstateclklane is not ready! MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n",
			hisifd->index, tmp);
	}
}
int mipi_dsi_bit_clk_upt_isr_handler(struct hisi_fb_data_type *hisifd)
{
	char __iomem *mipi_dsi0_base = NULL;
	struct mipi_dsi_phy_ctrl phy_ctrl = {0};
	struct hisi_panel_info *pinfo = NULL;
	uint32_t dsi_bit_clk_upt = 0;
	uint32_t hline_time = 0;
	uint32_t hsa_time = 0;
	uint32_t hbp_time = 0;
	uint32_t pixel_clk = 0;

	uint32_t tmp = 0;
	bool is_ready = false;
	int i = 0;

	BUG_ON(hisifd == NULL);
	pinfo = &(hisifd->panel_info);
	dsi_bit_clk_upt = pinfo->mipi.dsi_bit_clk_upt;
	mipi_dsi0_base = hisifd->mipi_dsi0_base;

	if (hisifd->index != PRIMARY_PANEL_IDX) {
		HISI_FB_ERR("fb%d, not support!", hisifd->index);
		return 0;
	}

	if (dsi_bit_clk_upt == pinfo->mipi.dsi_bit_clk) {
		return 0;
	}

	HISI_FB_DEBUG("fb%d +.\n", hisifd->index);

	/* get new phy_ctrl value according to dsi_bit_clk_next */
	get_dsi_phy_ctrl(pinfo->mipi.dsi_bit_clk_upt, &phy_ctrl);

	/*
	** Configure the DPHY PLL clock frequency through the TEST Interface to
	** operate at XX Hz,
	*/

	/* Write M Pll part 1 */
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_1);

	/*wait until dphy data lane enter into stop state*/
	for (i = 0; i < 40; i++) {
		tmp = inp32(mipi_dsi0_base + MIPIDSI_PHY_STATUS_OFFSET);
		if ((tmp & 0x00000a90) == 0x00000a90) {
			is_ready = true;
			break;
		}
		udelay(1);
	}

	if (!is_ready) {
		HISI_FB_ERR("fb%d, phystopstatedatalane is not ready! MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n",
			hisifd->index, tmp);
		return 0;
	}

	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	pinfo->mipi.dsi_bit_clk = dsi_bit_clk_upt;

	/* Write M Pll part 2 */
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_2);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Set hsfreqrange */
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010044);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.hsfreqrange);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write CP current */
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010011);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.cp_current);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	/* Write LPF Control */
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010012);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.lpf_ctrl);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002);
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000);

	if (!is_mipi_cmd_panel(hisifd)) {
		/*
		** Define the DPI Horizontal timing configuration:
		**
		** Hsa_time = HSA*(PCLK period/Clk Lane Byte Period);
		** Hbp_time = HBP*(PCLK period/Clk Lane Byte Period);
		** Hline_time = (HSA+HBP+HACT+HFP)*(PCLK period/Clk Lane Byte Period);
		*/
		pixel_clk = pinfo->pxl_clk_rate / 1000000;
		hsa_time = pinfo->ldi.h_pulse_width * phy_ctrl.lane_byte_clk / pixel_clk;
		hbp_time = pinfo->ldi.h_back_porch * phy_ctrl.lane_byte_clk / pixel_clk;
		hline_time = (pinfo->ldi.h_pulse_width + pinfo->ldi.h_back_porch +
		pinfo->xres + pinfo->ldi.h_front_porch) *
		phy_ctrl.lane_byte_clk / pixel_clk;

		outp32(mipi_dsi0_base + MIPIDSI_VID_HSA_TIME_OFFSET, hsa_time);
		outp32(mipi_dsi0_base + MIPIDSI_VID_HBP_TIME_OFFSET, hbp_time);
		outp32(mipi_dsi0_base + MIPIDSI_VID_HLINE_TIME_OFFSET, hline_time);
	}

	/* Configure core's phy parameters */
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET,
		(phy_ctrl.clk_lane_lp2hs_time + (phy_ctrl.clk_lane_hs2lp_time << 16)));
	outp32(mipi_dsi0_base + MIPIDSI_PHY_TMR_CFG_OFFSET,
		(4095 + (phy_ctrl.data_lane_lp2hs_time << 16) + (phy_ctrl.data_lane_hs2lp_time << 24)));

	/*
	** Configure the TX_ESC clock frequency to a frequency lower than 20 MHz
	** that is the maximum allowed frequency for D-PHY ESCAPE mode.
	*/
	outp32(mipi_dsi0_base + MIPIDSI_CLKMGR_CFG_OFFSET, (phy_ctrl.clk_division + (phy_ctrl.clk_division<<8)));

	HISI_FB_DEBUG("fb%d -.\n", hisifd->index);

	return 0;
}