Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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