static void mdfld_mipi_set_video_timing(struct mdfld_dsi_config *dsi_config,
					int pipe)
{
	struct drm_device *dev = dsi_config->dev;
	struct mdfld_dsi_dpi_timing dpi_timing;
	struct drm_display_mode *mode = dsi_config->mode;

	mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing,
					dsi_config->lane_count,
					dsi_config->bpp);

	REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe),
		mode->vdisplay << 16 | mode->hdisplay);
	REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe),
		dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_HBP_COUNT_REG(pipe),
		dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_HFP_COUNT_REG(pipe),
		dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe),
		dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe),
		dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_VBP_COUNT_REG(pipe),
		dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_VFP_COUNT_REG(pipe),
		dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
}
/**
 * Setup DPI timing for video mode MIPI panel.
 * NOTE: do NOT modify this function
 */
static void __mdfld_dsi_dpi_set_timing(struct mdfld_dsi_config *config,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode)
{
	struct mdfld_dsi_dpi_timing dpi_timing;
	struct mdfld_dsi_hw_context *ctx;
	
	if (!config) {
                DRM_ERROR("Invalid parameters\n");
                return;
        }

	struct drm_device *dev = config->dev;

	mode = adjusted_mode;
	ctx = &config->dsi_hw_context;

	mutex_lock(&config->context_lock);

	/*dpi resolution*/
	if (is_dual_dsi(dev))
		ctx->dpi_resolution = (mode->vdisplay << 16 | (mode->hdisplay / 2));
	else
		ctx->dpi_resolution = (mode->vdisplay << 16 | mode->hdisplay);

	/*Calculate DPI timing*/
	mdfld_dsi_dpi_timing_calculation(dev, mode, &dpi_timing,
			config->lane_count,
			config->bpp);

	/*update HW context with new DPI timings*/
	ctx->hsync_count = dpi_timing.hsync_count;
	ctx->hbp_count = dpi_timing.hbp_count;
	ctx->hfp_count = dpi_timing.hfp_count;
	ctx->hactive_count = dpi_timing.hactive_count;
	ctx->vsync_count = dpi_timing.vsync_count;
	ctx->vbp_count = dpi_timing.vbp_count;
	ctx->vfp_count = dpi_timing.vfp_count;

	mutex_unlock(&config->context_lock);
}
void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config,
								int pipe)
{
	struct drm_device *dev = dsi_config->dev;
	int lane_count = dsi_config->lane_count;
	struct mdfld_dsi_dpi_timing dpi_timing;
	struct drm_display_mode *mode = dsi_config->mode;
	u32 val;

	/*un-ready device*/
	REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 0, 0, 0);

	/*init dsi adapter before kicking off*/
	REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018);

	/*enable all interrupts*/
	REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff);

	/*set up func_prg*/
	val = lane_count;
	val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;

	switch (dsi_config->bpp) {
	case 16:
		val |= DSI_DPI_COLOR_FORMAT_RGB565;
		break;
	case 18:
		val |= DSI_DPI_COLOR_FORMAT_RGB666;
		break;
	case 24:
		val |= DSI_DPI_COLOR_FORMAT_RGB888;
		break;
	default:
		DRM_ERROR("unsupported color format, bpp = %d\n",
							dsi_config->bpp);
	}
	REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), val);

	REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe),
			(mode->vtotal * mode->htotal * dsi_config->bpp /
				(8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
	REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe),
				0xffff & DSI_LP_RX_TIMEOUT_MASK);

	/*max value: 20 clock cycles of txclkesc*/
	REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe),
				0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);

	/*min 21 txclkesc, max: ffffh*/
	REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe),
				0xffff & DSI_RESET_TIMER_MASK);

	REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe),
				mode->vdisplay << 16 | mode->hdisplay);

	/*set DPI timing registers*/
	mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing,
				dsi_config->lane_count, dsi_config->bpp);

	REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe),
			dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_HBP_COUNT_REG(pipe),
			dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_HFP_COUNT_REG(pipe),
			dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe),
			dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe),
			dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_VBP_COUNT_REG(pipe),
			dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
	REG_WRITE(MIPI_VFP_COUNT_REG(pipe),
			dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);

	REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x46);

	/*min: 7d0 max: 4e20*/
	REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0x000007d0);

	/*set up video mode*/
	val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
	REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), val);

	REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000);

	REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004);

	/*TODO: figure out how to setup these registers*/
	if (mdfld_get_panel_type(dev, pipe) == TC35876X)
		REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008);
	else
		REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150c3408);

	REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), (0xa << 16) | 0x14);

	if (mdfld_get_panel_type(dev, pipe) == TC35876X)
		tc35876x_set_bridge_reset_state(dev, 0);  /*Pull High Reset */

	/*set device ready*/
	REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 1, 0, 0);
}