Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
   1/*
   2 * Copyright © 2010 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21 * DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors:
  24 * jim liu <jim.liu@intel.com>
  25 * Jackie Li<yaodong.li@intel.com>
  26 */
  27
  28#include "mdfld_dsi_dpi.h"
  29#include "mdfld_output.h"
  30#include "mdfld_dsi_pkg_sender.h"
  31#include "psb_drv.h"
  32#include "tc35876x-dsi-lvds.h"
  33
  34static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output,
  35								int pipe);
  36
  37static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
  38{
  39	u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
  40	int timeout = 0;
  41
  42	udelay(500);
  43
  44	/* This will time out after approximately 2+ seconds */
  45	while ((timeout < 20000) &&
  46		(REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
  47		udelay(100);
  48		timeout++;
  49	}
  50
  51	if (timeout == 20000)
  52		DRM_INFO("MIPI: HS Data FIFO was never cleared!\n");
  53}
  54
  55static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
  56{
  57	u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
  58	int timeout = 0;
  59
  60	udelay(500);
  61
  62	/* This will time out after approximately 2+ seconds */
  63	while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg)
  64					& DSI_FIFO_GEN_HS_CTRL_FULL)) {
  65		udelay(100);
  66		timeout++;
  67	}
  68	if (timeout == 20000)
  69		DRM_INFO("MIPI: HS CMD FIFO was never cleared!\n");
  70}
  71
  72static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
  73{
  74	u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
  75	int timeout = 0;
  76
  77	udelay(500);
  78
  79	/* This will time out after approximately 2+ seconds */
  80	while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) &
  81					DPI_FIFO_EMPTY) != DPI_FIFO_EMPTY)) {
  82		udelay(100);
  83		timeout++;
  84	}
  85
  86	if (timeout == 20000)
  87		DRM_ERROR("MIPI: DPI FIFO was never cleared\n");
  88}
  89
  90static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
  91{
  92	u32 intr_stat_reg = MIPI_INTR_STAT_REG(pipe);
  93	int timeout = 0;
  94
  95	udelay(500);
  96
  97	/* This will time out after approximately 2+ seconds */
  98	while ((timeout < 20000) && (!(REG_READ(intr_stat_reg)
  99					& DSI_INTR_STATE_SPL_PKG_SENT))) {
 100		udelay(100);
 101		timeout++;
 102	}
 103
 104	if (timeout == 20000)
 105                DRM_ERROR("MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
 106}
 107
 108/* For TC35876X */
 109
 110static void dsi_set_device_ready_state(struct drm_device *dev, int state,
 111				int pipe)
 112{
 113	REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), !!state, 0, 0);
 114}
 115
 116static void dsi_set_pipe_plane_enable_state(struct drm_device *dev,
 117							int state, int pipe)
 118{
 119	struct drm_psb_private *dev_priv = dev->dev_private;
 120	u32 pipeconf_reg = PIPEACONF;
 121	u32 dspcntr_reg = DSPACNTR;
 122
 123	u32 dspcntr = dev_priv->dspcntr[pipe];
 124	u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
 125
 126	if (pipe) {
 127		pipeconf_reg = PIPECCONF;
 128		dspcntr_reg = DSPCCNTR;
 129	} else
 130		mipi &= (~0x03);
 131
 132	if (state) {
 133		/*Set up pipe */
 134		REG_WRITE(pipeconf_reg, BIT(31));
 135
 136		if (REG_BIT_WAIT(pipeconf_reg, 1, 30))
 137			dev_err(&dev->pdev->dev, "%s: Pipe enable timeout\n",
 138				__func__);
 139
 140		/*Set up display plane */
 141		REG_WRITE(dspcntr_reg, dspcntr);
 142	} else {
 143		u32 dspbase_reg = pipe ? MDFLD_DSPCBASE : MRST_DSPABASE;
 144
 145		/* Put DSI lanes to ULPS to disable pipe */
 146		REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 2, 2, 1);
 147		REG_READ(MIPI_DEVICE_READY_REG(pipe)); /* posted write? */
 148
 149		/* LP Hold */
 150		REG_FLD_MOD(MIPI_PORT_CONTROL(pipe), 0, 16, 16);
 151		REG_READ(MIPI_PORT_CONTROL(pipe)); /* posted write? */
 152
 153		/* Disable display plane */
 154		REG_FLD_MOD(dspcntr_reg, 0, 31, 31);
 155
 156		/* Flush the plane changes ??? posted write? */
 157		REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
 158		REG_READ(dspbase_reg);
 159
 160		/* Disable PIPE */
 161		REG_FLD_MOD(pipeconf_reg, 0, 31, 31);
 162
 163		if (REG_BIT_WAIT(pipeconf_reg, 0, 30))
 164			dev_err(&dev->pdev->dev, "%s: Pipe disable timeout\n",
 165				__func__);
 166
 167		if (REG_BIT_WAIT(MIPI_GEN_FIFO_STAT_REG(pipe), 1, 28))
 168			dev_err(&dev->pdev->dev, "%s: FIFO not empty\n",
 169				__func__);
 170	}
 171}
 172
 173static void mdfld_dsi_configure_down(struct mdfld_dsi_encoder *dsi_encoder,
 174								int pipe)
 175{
 176	struct mdfld_dsi_dpi_output *dpi_output =
 177				MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
 178	struct mdfld_dsi_config *dsi_config =
 179				mdfld_dsi_encoder_get_config(dsi_encoder);
 180	struct drm_device *dev = dsi_config->dev;
 181	struct drm_psb_private *dev_priv = dev->dev_private;
 182
 183	if (!dev_priv->dpi_panel_on[pipe]) {
 184		dev_err(dev->dev, "DPI panel is already off\n");
 185		return;
 186	}
 187	tc35876x_toshiba_bridge_panel_off(dev);
 188	tc35876x_set_bridge_reset_state(dev, 1);
 189	dsi_set_pipe_plane_enable_state(dev, 0, pipe);
 190	mdfld_dsi_dpi_shut_down(dpi_output, pipe);
 191	dsi_set_device_ready_state(dev, 0, pipe);
 192}
 193
 194static void mdfld_dsi_configure_up(struct mdfld_dsi_encoder *dsi_encoder,
 195								int pipe)
 196{
 197	struct mdfld_dsi_dpi_output *dpi_output =
 198				MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
 199	struct mdfld_dsi_config *dsi_config =
 200				mdfld_dsi_encoder_get_config(dsi_encoder);
 201	struct drm_device *dev = dsi_config->dev;
 202	struct drm_psb_private *dev_priv = dev->dev_private;
 203
 204	if (dev_priv->dpi_panel_on[pipe]) {
 205		dev_err(dev->dev, "DPI panel is already on\n");
 206		return;
 207	}
 208
 209	/* For resume path sequence */
 210	mdfld_dsi_dpi_shut_down(dpi_output, pipe);
 211	dsi_set_device_ready_state(dev, 0, pipe);
 212
 213	dsi_set_device_ready_state(dev, 1, pipe);
 214	tc35876x_set_bridge_reset_state(dev, 0);
 215	tc35876x_configure_lvds_bridge(dev);
 216	mdfld_dsi_dpi_turn_on(dpi_output, pipe);  /* Send turn on command */
 217	dsi_set_pipe_plane_enable_state(dev, 1, pipe);
 218}
 219/* End for TC35876X */
 220
 221/* ************************************************************************* *\
 222 * FUNCTION: mdfld_dsi_tpo_ic_init
 223 *
 224 * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
 225 *               restore_display_registers.  since this function does not
 226 *               acquire the mutex, it is important that the calling function
 227 *               does!
 228\* ************************************************************************* */
 229static void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
 230{
 231	struct drm_device *dev = dsi_config->dev;
 232	u32 dcsChannelNumber = dsi_config->channel_num;
 233	u32 gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe);
 234	u32 gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe);
 235	u32 gen_ctrl_val = GEN_LONG_WRITE;
 236
 237	DRM_INFO("Enter mrst init TPO MIPI display.\n");
 238
 239	gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
 240
 241	/* Flip page order */
 242	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 243	REG_WRITE(gen_data_reg, 0x00008036);
 244	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 245	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
 246
 247	/* 0xF0 */
 248	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 249	REG_WRITE(gen_data_reg, 0x005a5af0);
 250	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 251	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 252
 253	/* Write protection key */
 254	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 255	REG_WRITE(gen_data_reg, 0x005a5af1);
 256	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 257	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 258
 259	/* 0xFC */
 260	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 261	REG_WRITE(gen_data_reg, 0x005a5afc);
 262	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 263	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 264
 265	/* 0xB7 */
 266	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 267	REG_WRITE(gen_data_reg, 0x770000b7);
 268	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 269	REG_WRITE(gen_data_reg, 0x00000044);
 270	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 271	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS));
 272
 273	/* 0xB6 */
 274	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 275	REG_WRITE(gen_data_reg, 0x000a0ab6);
 276	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 277	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 278
 279	/* 0xF2 */
 280	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 281	REG_WRITE(gen_data_reg, 0x081010f2);
 282	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 283	REG_WRITE(gen_data_reg, 0x4a070708);
 284	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 285	REG_WRITE(gen_data_reg, 0x000000c5);
 286	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 287	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
 288
 289	/* 0xF8 */
 290	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 291	REG_WRITE(gen_data_reg, 0x024003f8);
 292	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 293	REG_WRITE(gen_data_reg, 0x01030a04);
 294	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 295	REG_WRITE(gen_data_reg, 0x0e020220);
 296	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 297	REG_WRITE(gen_data_reg, 0x00000004);
 298	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 299	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS));
 300
 301	/* 0xE2 */
 302	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 303	REG_WRITE(gen_data_reg, 0x398fc3e2);
 304	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 305	REG_WRITE(gen_data_reg, 0x0000916f);
 306	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 307	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS));
 308
 309	/* 0xB0 */
 310	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 311	REG_WRITE(gen_data_reg, 0x000000b0);
 312	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 313	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
 314
 315	/* 0xF4 */
 316	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 317	REG_WRITE(gen_data_reg, 0x240242f4);
 318	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 319	REG_WRITE(gen_data_reg, 0x78ee2002);
 320	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 321	REG_WRITE(gen_data_reg, 0x2a071050);
 322	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 323	REG_WRITE(gen_data_reg, 0x507fee10);
 324	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 325	REG_WRITE(gen_data_reg, 0x10300710);
 326	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 327	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS));
 328
 329	/* 0xBA */
 330	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 331	REG_WRITE(gen_data_reg, 0x19fe07ba);
 332	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 333	REG_WRITE(gen_data_reg, 0x101c0a31);
 334	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 335	REG_WRITE(gen_data_reg, 0x00000010);
 336	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 337	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
 338
 339	/* 0xBB */
 340	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 341	REG_WRITE(gen_data_reg, 0x28ff07bb);
 342	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 343	REG_WRITE(gen_data_reg, 0x24280a31);
 344	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 345	REG_WRITE(gen_data_reg, 0x00000034);
 346	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 347	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
 348
 349	/* 0xFB */
 350	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 351	REG_WRITE(gen_data_reg, 0x535d05fb);
 352	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 353	REG_WRITE(gen_data_reg, 0x1b1a2130);
 354	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 355	REG_WRITE(gen_data_reg, 0x221e180e);
 356	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 357	REG_WRITE(gen_data_reg, 0x131d2120);
 358	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 359	REG_WRITE(gen_data_reg, 0x535d0508);
 360	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 361	REG_WRITE(gen_data_reg, 0x1c1a2131);
 362	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 363	REG_WRITE(gen_data_reg, 0x231f160d);
 364	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 365	REG_WRITE(gen_data_reg, 0x111b2220);
 366	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 367	REG_WRITE(gen_data_reg, 0x535c2008);
 368	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 369	REG_WRITE(gen_data_reg, 0x1f1d2433);
 370	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 371	REG_WRITE(gen_data_reg, 0x2c251a10);
 372	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 373	REG_WRITE(gen_data_reg, 0x2c34372d);
 374	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 375	REG_WRITE(gen_data_reg, 0x00000023);
 376	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 377	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
 378
 379	/* 0xFA */
 380	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 381	REG_WRITE(gen_data_reg, 0x525c0bfa);
 382	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 383	REG_WRITE(gen_data_reg, 0x1c1c232f);
 384	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 385	REG_WRITE(gen_data_reg, 0x2623190e);
 386	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 387	REG_WRITE(gen_data_reg, 0x18212625);
 388	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 389	REG_WRITE(gen_data_reg, 0x545d0d0e);
 390	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 391	REG_WRITE(gen_data_reg, 0x1e1d2333);
 392	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 393	REG_WRITE(gen_data_reg, 0x26231a10);
 394	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 395	REG_WRITE(gen_data_reg, 0x1a222725);
 396	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 397	REG_WRITE(gen_data_reg, 0x545d280f);
 398	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 399	REG_WRITE(gen_data_reg, 0x21202635);
 400	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 401	REG_WRITE(gen_data_reg, 0x31292013);
 402	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 403	REG_WRITE(gen_data_reg, 0x31393d33);
 404	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 405	REG_WRITE(gen_data_reg, 0x00000029);
 406	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 407	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
 408
 409	/* Set DM */
 410	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 411	REG_WRITE(gen_data_reg, 0x000100f7);
 412	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 413	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 414}
 415
 416static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count,
 417						int num_lane, int bpp)
 418{
 419	return (u16)((pixel_clock_count * bpp) / (num_lane * 8));
 420}
 421
 422/*
 423 * Calculate the dpi time basing on a given drm mode @mode
 424 * return 0 on success.
 425 * FIXME: I was using proposed mode value for calculation, may need to
 426 * use crtc mode values later
 427 */
 428int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode,
 429				struct mdfld_dsi_dpi_timing *dpi_timing,
 430				int num_lane, int bpp)
 431{
 432	int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
 433	int pclk_vsync, pclk_vfp, pclk_vbp;
 434
 435	pclk_hactive = mode->hdisplay;
 436	pclk_hfp = mode->hsync_start - mode->hdisplay;
 437	pclk_hsync = mode->hsync_end - mode->hsync_start;
 438	pclk_hbp = mode->htotal - mode->hsync_end;
 439
 440	pclk_vfp = mode->vsync_start - mode->vdisplay;
 441	pclk_vsync = mode->vsync_end - mode->vsync_start;
 442	pclk_vbp = mode->vtotal - mode->vsync_end;
 443
 444	/*
 445	 * byte clock counts were calculated by following formula
 446	 * bclock_count = pclk_count * bpp / num_lane / 8
 447	 */
 448	dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(
 449						pclk_hsync, num_lane, bpp);
 450	dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(
 451						pclk_hbp, num_lane, bpp);
 452	dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(
 453						pclk_hfp, num_lane, bpp);
 454	dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(
 455						pclk_hactive, num_lane, bpp);
 456	dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(
 457						pclk_vsync, num_lane, bpp);
 458	dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(
 459						pclk_vbp, num_lane, bpp);
 460	dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(
 461						pclk_vfp, num_lane, bpp);
 462
 463	return 0;
 464}
 465
 466void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config,
 467								int pipe)
 468{
 469	struct drm_device *dev = dsi_config->dev;
 470	int lane_count = dsi_config->lane_count;
 471	struct mdfld_dsi_dpi_timing dpi_timing;
 472	struct drm_display_mode *mode = dsi_config->mode;
 473	u32 val;
 474
 475	/*un-ready device*/
 476	REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 0, 0, 0);
 477
 478	/*init dsi adapter before kicking off*/
 479	REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018);
 480
 481	/*enable all interrupts*/
 482	REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff);
 483
 484	/*set up func_prg*/
 485	val = lane_count;
 486	val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
 487
 488	switch (dsi_config->bpp) {
 489	case 16:
 490		val |= DSI_DPI_COLOR_FORMAT_RGB565;
 491		break;
 492	case 18:
 493		val |= DSI_DPI_COLOR_FORMAT_RGB666;
 494		break;
 495	case 24:
 496		val |= DSI_DPI_COLOR_FORMAT_RGB888;
 497		break;
 498	default:
 499		DRM_ERROR("unsupported color format, bpp = %d\n",
 500							dsi_config->bpp);
 501	}
 502	REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), val);
 503
 504	REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe),
 505			(mode->vtotal * mode->htotal * dsi_config->bpp /
 506				(8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
 507	REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe),
 508				0xffff & DSI_LP_RX_TIMEOUT_MASK);
 509
 510	/*max value: 20 clock cycles of txclkesc*/
 511	REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe),
 512				0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
 513
 514	/*min 21 txclkesc, max: ffffh*/
 515	REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe),
 516				0xffff & DSI_RESET_TIMER_MASK);
 517
 518	REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe),
 519				mode->vdisplay << 16 | mode->hdisplay);
 520
 521	/*set DPI timing registers*/
 522	mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing,
 523				dsi_config->lane_count, dsi_config->bpp);
 524
 525	REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe),
 526			dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
 527	REG_WRITE(MIPI_HBP_COUNT_REG(pipe),
 528			dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
 529	REG_WRITE(MIPI_HFP_COUNT_REG(pipe),
 530			dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
 531	REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe),
 532			dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
 533	REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe),
 534			dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
 535	REG_WRITE(MIPI_VBP_COUNT_REG(pipe),
 536			dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
 537	REG_WRITE(MIPI_VFP_COUNT_REG(pipe),
 538			dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
 539
 540	REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x46);
 541
 542	/*min: 7d0 max: 4e20*/
 543	REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0x000007d0);
 544
 545	/*set up video mode*/
 546	val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
 547	REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), val);
 548
 549	REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000);
 550
 551	REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004);
 552
 553	/*TODO: figure out how to setup these registers*/
 554	if (mdfld_get_panel_type(dev, pipe) == TC35876X)
 555		REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008);
 556	else
 557		REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150c3408);
 558
 559	REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), (0xa << 16) | 0x14);
 560
 561	if (mdfld_get_panel_type(dev, pipe) == TC35876X)
 562		tc35876x_set_bridge_reset_state(dev, 0);  /*Pull High Reset */
 563
 564	/*set device ready*/
 565	REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 1, 0, 0);
 566}
 567
 568void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
 569{
 570	struct drm_device *dev = output->dev;
 571
 572	/* clear special packet sent bit */
 573	if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT)
 574		REG_WRITE(MIPI_INTR_STAT_REG(pipe),
 575					DSI_INTR_STATE_SPL_PKG_SENT);
 576
 577	/*send turn on package*/
 578	REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_TURN_ON);
 579
 580	/*wait for SPL_PKG_SENT interrupt*/
 581	mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
 582
 583	if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT)
 584		REG_WRITE(MIPI_INTR_STAT_REG(pipe),
 585					DSI_INTR_STATE_SPL_PKG_SENT);
 586
 587	output->panel_on = 1;
 588
 589	/* FIXME the following is disabled to WA the X slow start issue
 590	   for TMD panel
 591	if (pipe == 2)
 592		dev_priv->dpi_panel_on2 = true;
 593	else if (pipe == 0)
 594		dev_priv->dpi_panel_on = true; */
 595}
 596
 597static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output,
 598								int pipe)
 599{
 600	struct drm_device *dev = output->dev;
 601
 602	/*if output is on, or mode setting didn't happen, ignore this*/
 603	if ((!output->panel_on) || output->first_boot) {
 604		output->first_boot = 0;
 605		return;
 606	}
 607
 608	/* Wait for dpi fifo to empty */
 609	mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
 610
 611	/* Clear the special packet interrupt bit if set */
 612	if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT)
 613		REG_WRITE(MIPI_INTR_STAT_REG(pipe),
 614					DSI_INTR_STATE_SPL_PKG_SENT);
 615
 616	if (REG_READ(MIPI_DPI_CONTROL_REG(pipe)) == DSI_DPI_CTRL_HS_SHUTDOWN)
 617		goto shutdown_out;
 618
 619	REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_SHUTDOWN);
 620
 621shutdown_out:
 622	output->panel_on = 0;
 623	output->first_boot = 0;
 624
 625	/* FIXME the following is disabled to WA the X slow start issue
 626	   for TMD panel
 627	if (pipe == 2)
 628		dev_priv->dpi_panel_on2 = false;
 629	else if (pipe == 0)
 630		dev_priv->dpi_panel_on = false;	 */
 631}
 632
 633static void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
 634{
 635	struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder);
 636	struct mdfld_dsi_dpi_output *dpi_output =
 637				MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
 638	struct mdfld_dsi_config *dsi_config =
 639				mdfld_dsi_encoder_get_config(dsi_encoder);
 640	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
 641	struct drm_device *dev = dsi_config->dev;
 642	struct drm_psb_private *dev_priv = dev->dev_private;
 643
 644	/*start up display island if it was shutdown*/
 645	if (!gma_power_begin(dev, true))
 646		return;
 647
 648	if (on) {
 649		if (mdfld_get_panel_type(dev, pipe) == TMD_VID)
 650			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 651		else if (mdfld_get_panel_type(dev, pipe) == TC35876X)
 652			mdfld_dsi_configure_up(dsi_encoder, pipe);
 653		else {
 654			/*enable mipi port*/
 655			REG_WRITE(MIPI_PORT_CONTROL(pipe),
 656				REG_READ(MIPI_PORT_CONTROL(pipe)) | BIT(31));
 657			REG_READ(MIPI_PORT_CONTROL(pipe));
 658
 659			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 660			mdfld_dsi_tpo_ic_init(dsi_config, pipe);
 661		}
 662		dev_priv->dpi_panel_on[pipe] = true;
 663	} else {
 664		if (mdfld_get_panel_type(dev, pipe) == TMD_VID)
 665			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
 666		else if (mdfld_get_panel_type(dev, pipe) == TC35876X)
 667			mdfld_dsi_configure_down(dsi_encoder, pipe);
 668		else {
 669			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
 670
 671			/*disable mipi port*/
 672			REG_WRITE(MIPI_PORT_CONTROL(pipe),
 673				REG_READ(MIPI_PORT_CONTROL(pipe)) & ~BIT(31));
 674			REG_READ(MIPI_PORT_CONTROL(pipe));
 675		}
 676		dev_priv->dpi_panel_on[pipe] = false;
 677	}
 678	gma_power_end(dev);
 679}
 680
 681void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
 682{
 683	mdfld_dsi_dpi_set_power(encoder, mode == DRM_MODE_DPMS_ON);
 684}
 685
 686bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
 687				     const struct drm_display_mode *mode,
 688				     struct drm_display_mode *adjusted_mode)
 689{
 690	struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder);
 691	struct mdfld_dsi_config *dsi_config =
 692				mdfld_dsi_encoder_get_config(dsi_encoder);
 693	struct drm_display_mode *fixed_mode = dsi_config->fixed_mode;
 694
 695	if (fixed_mode) {
 696		adjusted_mode->hdisplay = fixed_mode->hdisplay;
 697		adjusted_mode->hsync_start = fixed_mode->hsync_start;
 698		adjusted_mode->hsync_end = fixed_mode->hsync_end;
 699		adjusted_mode->htotal = fixed_mode->htotal;
 700		adjusted_mode->vdisplay = fixed_mode->vdisplay;
 701		adjusted_mode->vsync_start = fixed_mode->vsync_start;
 702		adjusted_mode->vsync_end = fixed_mode->vsync_end;
 703		adjusted_mode->vtotal = fixed_mode->vtotal;
 704		adjusted_mode->clock = fixed_mode->clock;
 705		drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
 706	}
 707	return true;
 708}
 709
 710void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder)
 711{
 712	mdfld_dsi_dpi_set_power(encoder, false);
 713}
 714
 715void mdfld_dsi_dpi_commit(struct drm_encoder *encoder)
 716{
 717	mdfld_dsi_dpi_set_power(encoder, true);
 718}
 719
 720/* For TC35876X */
 721/* This functionality was implemented in FW in iCDK */
 722/* But removed in DV0 and later. So need to add here. */
 723static void mipi_set_properties(struct mdfld_dsi_config *dsi_config, int pipe)
 724{
 725	struct drm_device *dev = dsi_config->dev;
 726
 727	REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018);
 728	REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff);
 729	REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe), 0xffffff);
 730	REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe), 0xffffff);
 731	REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe), 0x14);
 732	REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe), 0xff);
 733	REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x25);
 734	REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0xf0);
 735	REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000);
 736	REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004);
 737	REG_WRITE(MIPI_DBI_BW_CTRL_REG(pipe), 0x00000820);
 738	REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), (0xa << 16) | 0x14);
 739}
 740
 741static void mdfld_mipi_set_video_timing(struct mdfld_dsi_config *dsi_config,
 742					int pipe)
 743{
 744	struct drm_device *dev = dsi_config->dev;
 745	struct mdfld_dsi_dpi_timing dpi_timing;
 746	struct drm_display_mode *mode = dsi_config->mode;
 747
 748	mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing,
 749					dsi_config->lane_count,
 750					dsi_config->bpp);
 751
 752	REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe),
 753		mode->vdisplay << 16 | mode->hdisplay);
 754	REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe),
 755		dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
 756	REG_WRITE(MIPI_HBP_COUNT_REG(pipe),
 757		dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
 758	REG_WRITE(MIPI_HFP_COUNT_REG(pipe),
 759		dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
 760	REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe),
 761		dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
 762	REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe),
 763		dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
 764	REG_WRITE(MIPI_VBP_COUNT_REG(pipe),
 765		dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
 766	REG_WRITE(MIPI_VFP_COUNT_REG(pipe),
 767		dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
 768}
 769
 770static void mdfld_mipi_config(struct mdfld_dsi_config *dsi_config, int pipe)
 771{
 772	struct drm_device *dev = dsi_config->dev;
 773	int lane_count = dsi_config->lane_count;
 774
 775	if (pipe) {
 776		REG_WRITE(MIPI_PORT_CONTROL(0), 0x00000002);
 777		REG_WRITE(MIPI_PORT_CONTROL(2), 0x80000000);
 778	} else {
 779		REG_WRITE(MIPI_PORT_CONTROL(0), 0x80010000);
 780		REG_WRITE(MIPI_PORT_CONTROL(2), 0x00);
 781	}
 782
 783	REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150A600F);
 784	REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), 0x0000000F);
 785
 786	/* lane_count = 3 */
 787	REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), 0x00000200 | lane_count);
 788
 789	mdfld_mipi_set_video_timing(dsi_config, pipe);
 790}
 791
 792static void mdfld_set_pipe_timing(struct mdfld_dsi_config *dsi_config, int pipe)
 793{
 794	struct drm_device *dev = dsi_config->dev;
 795	struct drm_display_mode *mode = dsi_config->mode;
 796
 797	REG_WRITE(HTOTAL_A, ((mode->htotal - 1) << 16) | (mode->hdisplay - 1));
 798	REG_WRITE(HBLANK_A, ((mode->htotal - 1) << 16) | (mode->hdisplay - 1));
 799	REG_WRITE(HSYNC_A,
 800		((mode->hsync_end - 1) << 16) | (mode->hsync_start - 1));
 801
 802	REG_WRITE(VTOTAL_A, ((mode->vtotal - 1) << 16) | (mode->vdisplay - 1));
 803	REG_WRITE(VBLANK_A, ((mode->vtotal - 1) << 16) | (mode->vdisplay - 1));
 804	REG_WRITE(VSYNC_A,
 805		((mode->vsync_end - 1) << 16) | (mode->vsync_start - 1));
 806
 807	REG_WRITE(PIPEASRC,
 808		((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 809}
 810/* End for TC35876X */
 811
 812void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
 813				   struct drm_display_mode *mode,
 814				   struct drm_display_mode *adjusted_mode)
 815{
 816	struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder);
 817	struct mdfld_dsi_dpi_output *dpi_output =
 818					MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
 819	struct mdfld_dsi_config *dsi_config =
 820				mdfld_dsi_encoder_get_config(dsi_encoder);
 821	struct drm_device *dev = dsi_config->dev;
 822	struct drm_psb_private *dev_priv = dev->dev_private;
 823	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
 824	u32 pipeconf_reg = PIPEACONF;
 825	u32 dspcntr_reg = DSPACNTR;
 826	u32 pipeconf, dspcntr;
 827
 828	u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
 829
 830	if (WARN_ON(pipe < 0))
 831		return;
 832
 833	pipeconf = dev_priv->pipeconf[pipe];
 834	dspcntr = dev_priv->dspcntr[pipe];
 835
 836	if (pipe) {
 837		pipeconf_reg = PIPECCONF;
 838		dspcntr_reg = DSPCCNTR;
 839	} else {
 840		if (mdfld_get_panel_type(dev, pipe) == TC35876X)
 841			mipi &= (~0x03); /* Use all four lanes */
 842		else
 843			mipi |= 2;
 844	}
 845
 846	/*start up display island if it was shutdown*/
 847	if (!gma_power_begin(dev, true))
 848		return;
 849
 850	if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
 851		/*
 852		 * The following logic is required to reset the bridge and
 853		 * configure. This also starts the DSI clock at 200MHz.
 854		 */
 855		tc35876x_set_bridge_reset_state(dev, 0);  /*Pull High Reset */
 856		tc35876x_toshiba_bridge_panel_on(dev);
 857		udelay(100);
 858		/* Now start the DSI clock */
 859		REG_WRITE(MRST_DPLL_A, 0x00);
 860		REG_WRITE(MRST_FPA0, 0xC1);
 861		REG_WRITE(MRST_DPLL_A, 0x00800000);
 862		udelay(500);
 863		REG_WRITE(MRST_DPLL_A, 0x80800000);
 864
 865		if (REG_BIT_WAIT(pipeconf_reg, 1, 29))
 866			dev_err(&dev->pdev->dev, "%s: DSI PLL lock timeout\n",
 867				__func__);
 868
 869		REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008);
 870
 871		mipi_set_properties(dsi_config, pipe);
 872		mdfld_mipi_config(dsi_config, pipe);
 873		mdfld_set_pipe_timing(dsi_config, pipe);
 874
 875		REG_WRITE(DSPABASE, 0x00);
 876		REG_WRITE(DSPASIZE,
 877			((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
 878
 879		REG_WRITE(DSPACNTR, 0x98000000);
 880		REG_WRITE(DSPASURF, 0x00);
 881
 882		REG_WRITE(VGACNTRL, 0x80000000);
 883		REG_WRITE(DEVICE_READY_REG, 0x00000001);
 884
 885		REG_WRITE(MIPI_PORT_CONTROL(pipe), 0x80810000);
 886	} else {
 887		/*set up mipi port FIXME: do at init time */
 888		REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi);
 889	}
 890	REG_READ(MIPI_PORT_CONTROL(pipe));
 891
 892	if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
 893		/* NOP */
 894	} else if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
 895		/* set up DSI controller DPI interface */
 896		mdfld_dsi_dpi_controller_init(dsi_config, pipe);
 897
 898		/* Configure MIPI Bridge and Panel */
 899		tc35876x_configure_lvds_bridge(dev);
 900		dev_priv->dpi_panel_on[pipe] = true;
 901	} else {
 902		/*turn on DPI interface*/
 903		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 904	}
 905
 906	/*set up pipe*/
 907	REG_WRITE(pipeconf_reg, pipeconf);
 908	REG_READ(pipeconf_reg);
 909
 910	/*set up display plane*/
 911	REG_WRITE(dspcntr_reg, dspcntr);
 912	REG_READ(dspcntr_reg);
 913
 914	msleep(20); /* FIXME: this should wait for vblank */
 915
 916	if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
 917		/* NOP */
 918	} else if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
 919		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 920	} else {
 921		/* init driver ic */
 922		mdfld_dsi_tpo_ic_init(dsi_config, pipe);
 923		/*init backlight*/
 924		mdfld_dsi_brightness_init(dsi_config, pipe);
 925	}
 926
 927	gma_power_end(dev);
 928}
 929
 930/*
 931 * Init DSI DPI encoder.
 932 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
 933 * return pointer of newly allocated DPI encoder, NULL on error
 934 */
 935struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
 936				struct mdfld_dsi_connector *dsi_connector,
 937				const struct panel_funcs *p_funcs)
 938{
 939	struct mdfld_dsi_dpi_output *dpi_output = NULL;
 940	struct mdfld_dsi_config *dsi_config;
 941	struct drm_connector *connector = NULL;
 942	struct drm_encoder *encoder = NULL;
 943	int pipe;
 944	u32 data;
 945	int ret;
 946
 947	pipe = dsi_connector->pipe;
 948
 949	if (mdfld_get_panel_type(dev, pipe) != TC35876X) {
 950		dsi_config = mdfld_dsi_get_config(dsi_connector);
 951
 952		/* panel hard-reset */
 953		if (p_funcs->reset) {
 954			ret = p_funcs->reset(pipe);
 955			if (ret) {
 956				DRM_ERROR("Panel %d hard-reset failed\n", pipe);
 957				return NULL;
 958			}
 959		}
 960
 961		/* panel drvIC init */
 962		if (p_funcs->drv_ic_init)
 963			p_funcs->drv_ic_init(dsi_config, pipe);
 964
 965		/* panel power mode detect */
 966		ret = mdfld_dsi_get_power_mode(dsi_config, &data, false);
 967		if (ret) {
 968			DRM_ERROR("Panel %d get power mode failed\n", pipe);
 969			dsi_connector->status = connector_status_disconnected;
 970		} else {
 971			DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
 972			dsi_connector->status = connector_status_connected;
 973		}
 974	}
 975
 976	dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL);
 977	if (!dpi_output) {
 978		DRM_ERROR("No memory\n");
 979		return NULL;
 980	}
 981
 982	if (dsi_connector->pipe)
 983		dpi_output->panel_on = 0;
 984	else
 985		dpi_output->panel_on = 0;
 986
 987	dpi_output->dev = dev;
 988	if (mdfld_get_panel_type(dev, pipe) != TC35876X)
 989		dpi_output->p_funcs = p_funcs;
 990	dpi_output->first_boot = 1;
 991
 992	/*get fixed mode*/
 993	dsi_config = mdfld_dsi_get_config(dsi_connector);
 994
 995	/*create drm encoder object*/
 996	connector = &dsi_connector->base.base;
 997	encoder = &dpi_output->base.base.base;
 998	drm_encoder_init(dev,
 999			encoder,
1000			p_funcs->encoder_funcs,
1001			DRM_MODE_ENCODER_LVDS, NULL);
1002	drm_encoder_helper_add(encoder,
1003				p_funcs->encoder_helper_funcs);
1004
1005	/*attach to given connector*/
1006	drm_mode_connector_attach_encoder(connector, encoder);
1007
1008	/*set possible crtcs and clones*/
1009	if (dsi_connector->pipe) {
1010		encoder->possible_crtcs = (1 << 2);
1011		encoder->possible_clones = (1 << 1);
1012	} else {
1013		encoder->possible_crtcs = (1 << 0);
1014		encoder->possible_clones = (1 << 0);
1015	}
1016
1017	dsi_connector->base.encoder = &dpi_output->base.base;
1018
1019	return &dpi_output->base;
1020}