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 825 u32 pipeconf_reg = PIPEACONF; 826 u32 dspcntr_reg = DSPACNTR; 827 828 u32 pipeconf = dev_priv->pipeconf[pipe]; 829 u32 dspcntr = dev_priv->dspcntr[pipe]; 830 u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; 831 832 if (pipe) { 833 pipeconf_reg = PIPECCONF; 834 dspcntr_reg = DSPCCNTR; 835 } else { 836 if (mdfld_get_panel_type(dev, pipe) == TC35876X) 837 mipi &= (~0x03); /* Use all four lanes */ 838 else 839 mipi |= 2; 840 } 841 842 /*start up display island if it was shutdown*/ 843 if (!gma_power_begin(dev, true)) 844 return; 845 846 if (mdfld_get_panel_type(dev, pipe) == TC35876X) { 847 /* 848 * The following logic is required to reset the bridge and 849 * configure. This also starts the DSI clock at 200MHz. 850 */ 851 tc35876x_set_bridge_reset_state(dev, 0); /*Pull High Reset */ 852 tc35876x_toshiba_bridge_panel_on(dev); 853 udelay(100); 854 /* Now start the DSI clock */ 855 REG_WRITE(MRST_DPLL_A, 0x00); 856 REG_WRITE(MRST_FPA0, 0xC1); 857 REG_WRITE(MRST_DPLL_A, 0x00800000); 858 udelay(500); 859 REG_WRITE(MRST_DPLL_A, 0x80800000); 860 861 if (REG_BIT_WAIT(pipeconf_reg, 1, 29)) 862 dev_err(&dev->pdev->dev, "%s: DSI PLL lock timeout\n", 863 __func__); 864 865 REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008); 866 867 mipi_set_properties(dsi_config, pipe); 868 mdfld_mipi_config(dsi_config, pipe); 869 mdfld_set_pipe_timing(dsi_config, pipe); 870 871 REG_WRITE(DSPABASE, 0x00); 872 REG_WRITE(DSPASIZE, 873 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); 874 875 REG_WRITE(DSPACNTR, 0x98000000); 876 REG_WRITE(DSPASURF, 0x00); 877 878 REG_WRITE(VGACNTRL, 0x80000000); 879 REG_WRITE(DEVICE_READY_REG, 0x00000001); 880 881 REG_WRITE(MIPI_PORT_CONTROL(pipe), 0x80810000); 882 } else { 883 /*set up mipi port FIXME: do at init time */ 884 REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi); 885 } 886 REG_READ(MIPI_PORT_CONTROL(pipe)); 887 888 if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { 889 /* NOP */ 890 } else if (mdfld_get_panel_type(dev, pipe) == TC35876X) { 891 /* set up DSI controller DPI interface */ 892 mdfld_dsi_dpi_controller_init(dsi_config, pipe); 893 894 /* Configure MIPI Bridge and Panel */ 895 tc35876x_configure_lvds_bridge(dev); 896 dev_priv->dpi_panel_on[pipe] = true; 897 } else { 898 /*turn on DPI interface*/ 899 mdfld_dsi_dpi_turn_on(dpi_output, pipe); 900 } 901 902 /*set up pipe*/ 903 REG_WRITE(pipeconf_reg, pipeconf); 904 REG_READ(pipeconf_reg); 905 906 /*set up display plane*/ 907 REG_WRITE(dspcntr_reg, dspcntr); 908 REG_READ(dspcntr_reg); 909 910 msleep(20); /* FIXME: this should wait for vblank */ 911 912 if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { 913 /* NOP */ 914 } else if (mdfld_get_panel_type(dev, pipe) == TC35876X) { 915 mdfld_dsi_dpi_turn_on(dpi_output, pipe); 916 } else { 917 /* init driver ic */ 918 mdfld_dsi_tpo_ic_init(dsi_config, pipe); 919 /*init backlight*/ 920 mdfld_dsi_brightness_init(dsi_config, pipe); 921 } 922 923 gma_power_end(dev); 924} 925 926/* 927 * Init DSI DPI encoder. 928 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector 929 * return pointer of newly allocated DPI encoder, NULL on error 930 */ 931struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, 932 struct mdfld_dsi_connector *dsi_connector, 933 const struct panel_funcs *p_funcs) 934{ 935 struct mdfld_dsi_dpi_output *dpi_output = NULL; 936 struct mdfld_dsi_config *dsi_config; 937 struct drm_connector *connector = NULL; 938 struct drm_encoder *encoder = NULL; 939 int pipe; 940 u32 data; 941 int ret; 942 943 pipe = dsi_connector->pipe; 944 945 if (mdfld_get_panel_type(dev, pipe) != TC35876X) { 946 dsi_config = mdfld_dsi_get_config(dsi_connector); 947 948 /* panel hard-reset */ 949 if (p_funcs->reset) { 950 ret = p_funcs->reset(pipe); 951 if (ret) { 952 DRM_ERROR("Panel %d hard-reset failed\n", pipe); 953 return NULL; 954 } 955 } 956 957 /* panel drvIC init */ 958 if (p_funcs->drv_ic_init) 959 p_funcs->drv_ic_init(dsi_config, pipe); 960 961 /* panel power mode detect */ 962 ret = mdfld_dsi_get_power_mode(dsi_config, &data, false); 963 if (ret) { 964 DRM_ERROR("Panel %d get power mode failed\n", pipe); 965 dsi_connector->status = connector_status_disconnected; 966 } else { 967 DRM_INFO("pipe %d power mode 0x%x\n", pipe, data); 968 dsi_connector->status = connector_status_connected; 969 } 970 } 971 972 dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL); 973 if (!dpi_output) { 974 DRM_ERROR("No memory\n"); 975 return NULL; 976 } 977 978 if (dsi_connector->pipe) 979 dpi_output->panel_on = 0; 980 else 981 dpi_output->panel_on = 0; 982 983 dpi_output->dev = dev; 984 if (mdfld_get_panel_type(dev, pipe) != TC35876X) 985 dpi_output->p_funcs = p_funcs; 986 dpi_output->first_boot = 1; 987 988 /*get fixed mode*/ 989 dsi_config = mdfld_dsi_get_config(dsi_connector); 990 991 /*create drm encoder object*/ 992 connector = &dsi_connector->base.base; 993 encoder = &dpi_output->base.base.base; 994 drm_encoder_init(dev, 995 encoder, 996 p_funcs->encoder_funcs, 997 DRM_MODE_ENCODER_LVDS); 998 drm_encoder_helper_add(encoder, 999 p_funcs->encoder_helper_funcs); 1000 1001 /*attach to given connector*/ 1002 drm_mode_connector_attach_encoder(connector, encoder); 1003 1004 /*set possible crtcs and clones*/ 1005 if (dsi_connector->pipe) { 1006 encoder->possible_crtcs = (1 << 2); 1007 encoder->possible_clones = (1 << 1); 1008 } else { 1009 encoder->possible_crtcs = (1 << 0); 1010 encoder->possible_clones = (1 << 0); 1011 } 1012 1013 dsi_connector->base.encoder = &dpi_output->base.base; 1014 1015 return &dpi_output->base; 1016} 1017