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