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

drm/gma500: Remove Medfield support

Medfield is an outdated mobile platform with apparently no users left.
Remove it from gma500.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210129095604.32423-2-tzimmermann@suse.de
(cherry picked from commit b51035c200bd3423ae5b6b98b54735ef424dc746)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

authored by

Thomas Zimmermann and committed by
Maarten Lankhorst
e1da8112 46d4a938

+2 -5835
-7
drivers/gpu/drm/gma500/Kconfig
··· 26 26 help 27 27 Say yes to include basic support for Intel GMA3600/3650 (Intel 28 28 Cedar Trail) platforms. 29 - 30 - config DRM_MEDFIELD 31 - bool "Intel Medfield support (Experimental)" 32 - depends on DRM_GMA500 && X86_INTEL_MID 33 - help 34 - Say yes to include support for the Intel Medfield platform. 35 -
-10
drivers/gpu/drm/gma500/Makefile
··· 43 43 oaktrail_hdmi.o \ 44 44 oaktrail_hdmi_i2c.o 45 45 46 - gma500_gfx-$(CONFIG_DRM_MEDFIELD) += mdfld_device.o \ 47 - mdfld_output.o \ 48 - mdfld_intel_display.o \ 49 - mdfld_dsi_output.o \ 50 - mdfld_dsi_dpi.o \ 51 - mdfld_dsi_pkg_sender.o \ 52 - mdfld_tpo_vid.o \ 53 - mdfld_tmd_vid.o \ 54 - tc35876x-dsi-lvds.o 55 - 56 46 obj-$(CONFIG_DRM_GMA500) += gma500_gfx.o
-4
drivers/gpu/drm/gma500/cdv_intel_hdmi.c
··· 22 22 * 23 23 * Authors: 24 24 * jim liu <jim.liu@intel.com> 25 - * 26 - * FIXME: 27 - * We should probably make this generic and share it with Medfield 28 25 */ 29 26 30 27 #include <linux/pm_runtime.h> ··· 53 56 bool has_hdmi_audio; 54 57 /* Should set this when detect hotplug */ 55 58 bool hdmi_device_connected; 56 - struct mdfld_hdmi_i2c *i2c_bus; 57 59 struct i2c_adapter *hdmi_i2c_adapter; /* for control functions */ 58 60 struct drm_device *dev; 59 61 };
-564
drivers/gpu/drm/gma500/mdfld_device.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /************************************************************************** 3 - * Copyright (c) 2011, Intel Corporation. 4 - * All Rights Reserved. 5 - * 6 - **************************************************************************/ 7 - 8 - #include <linux/delay.h> 9 - #include <linux/gpio/machine.h> 10 - 11 - #include <asm/intel_scu_ipc.h> 12 - 13 - #include "mdfld_dsi_output.h" 14 - #include "mdfld_output.h" 15 - #include "mid_bios.h" 16 - #include "psb_drv.h" 17 - #include "tc35876x-dsi-lvds.h" 18 - 19 - #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 20 - 21 - #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF 22 - #define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ 23 - #define BLC_PWM_FREQ_CALC_CONSTANT 32 24 - #define MHz 1000000 25 - #define BRIGHTNESS_MIN_LEVEL 1 26 - #define BRIGHTNESS_MAX_LEVEL 100 27 - #define BRIGHTNESS_MASK 0xFF 28 - #define BLC_POLARITY_NORMAL 0 29 - #define BLC_POLARITY_INVERSE 1 30 - #define BLC_ADJUSTMENT_MAX 100 31 - 32 - #define MDFLD_BLC_PWM_PRECISION_FACTOR 10 33 - #define MDFLD_BLC_MAX_PWM_REG_FREQ 0xFFFE 34 - #define MDFLD_BLC_MIN_PWM_REG_FREQ 0x2 35 - 36 - #define MDFLD_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) 37 - #define MDFLD_BACKLIGHT_PWM_CTL_SHIFT (16) 38 - 39 - static struct backlight_device *mdfld_backlight_device; 40 - 41 - int mdfld_set_brightness(struct backlight_device *bd) 42 - { 43 - struct drm_device *dev = 44 - (struct drm_device *)bl_get_data(mdfld_backlight_device); 45 - struct drm_psb_private *dev_priv = dev->dev_private; 46 - int level = bd->props.brightness; 47 - 48 - DRM_DEBUG_DRIVER("backlight level set to %d\n", level); 49 - 50 - /* Perform value bounds checking */ 51 - if (level < BRIGHTNESS_MIN_LEVEL) 52 - level = BRIGHTNESS_MIN_LEVEL; 53 - 54 - if (gma_power_begin(dev, false)) { 55 - u32 adjusted_level = 0; 56 - 57 - /* 58 - * Adjust the backlight level with the percent in 59 - * dev_priv->blc_adj2 60 - */ 61 - adjusted_level = level * dev_priv->blc_adj2; 62 - adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX; 63 - dev_priv->brightness_adjusted = adjusted_level; 64 - 65 - if (mdfld_get_panel_type(dev, 0) == TC35876X) { 66 - if (dev_priv->dpi_panel_on[0] || 67 - dev_priv->dpi_panel_on[2]) 68 - tc35876x_brightness_control(dev, 69 - dev_priv->brightness_adjusted); 70 - } else { 71 - if (dev_priv->dpi_panel_on[0]) 72 - mdfld_dsi_brightness_control(dev, 0, 73 - dev_priv->brightness_adjusted); 74 - } 75 - 76 - if (dev_priv->dpi_panel_on[2]) 77 - mdfld_dsi_brightness_control(dev, 2, 78 - dev_priv->brightness_adjusted); 79 - gma_power_end(dev); 80 - } 81 - 82 - /* cache the brightness for later use */ 83 - dev_priv->brightness = level; 84 - return 0; 85 - } 86 - 87 - static int mdfld_get_brightness(struct backlight_device *bd) 88 - { 89 - struct drm_device *dev = 90 - (struct drm_device *)bl_get_data(mdfld_backlight_device); 91 - struct drm_psb_private *dev_priv = dev->dev_private; 92 - 93 - DRM_DEBUG_DRIVER("brightness = 0x%x \n", dev_priv->brightness); 94 - 95 - /* return locally cached var instead of HW read (due to DPST etc.) */ 96 - return dev_priv->brightness; 97 - } 98 - 99 - static const struct backlight_ops mdfld_ops = { 100 - .get_brightness = mdfld_get_brightness, 101 - .update_status = mdfld_set_brightness, 102 - }; 103 - 104 - static int device_backlight_init(struct drm_device *dev) 105 - { 106 - struct drm_psb_private *dev_priv = (struct drm_psb_private *) 107 - dev->dev_private; 108 - 109 - dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; 110 - dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; 111 - 112 - return 0; 113 - } 114 - 115 - static int mdfld_backlight_init(struct drm_device *dev) 116 - { 117 - struct backlight_properties props; 118 - int ret = 0; 119 - 120 - memset(&props, 0, sizeof(struct backlight_properties)); 121 - props.max_brightness = BRIGHTNESS_MAX_LEVEL; 122 - props.type = BACKLIGHT_PLATFORM; 123 - mdfld_backlight_device = backlight_device_register("mdfld-bl", 124 - NULL, (void *)dev, &mdfld_ops, &props); 125 - 126 - if (IS_ERR(mdfld_backlight_device)) 127 - return PTR_ERR(mdfld_backlight_device); 128 - 129 - ret = device_backlight_init(dev); 130 - if (ret) 131 - return ret; 132 - 133 - mdfld_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL; 134 - mdfld_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL; 135 - backlight_update_status(mdfld_backlight_device); 136 - return 0; 137 - } 138 - #endif 139 - 140 - struct backlight_device *mdfld_get_backlight_device(void) 141 - { 142 - #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 143 - return mdfld_backlight_device; 144 - #else 145 - return NULL; 146 - #endif 147 - } 148 - 149 - /* 150 - * mdfld_save_display_registers 151 - * 152 - * Description: We are going to suspend so save current display 153 - * register state. 154 - * 155 - * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio 156 - */ 157 - static int mdfld_save_display_registers(struct drm_device *dev, int pipenum) 158 - { 159 - struct drm_psb_private *dev_priv = dev->dev_private; 160 - struct medfield_state *regs = &dev_priv->regs.mdfld; 161 - struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; 162 - const struct psb_offset *map = &dev_priv->regmap[pipenum]; 163 - int i; 164 - u32 *mipi_val; 165 - 166 - /* register */ 167 - u32 mipi_reg = MIPI; 168 - 169 - switch (pipenum) { 170 - case 0: 171 - mipi_val = &regs->saveMIPI; 172 - break; 173 - case 1: 174 - mipi_val = &regs->saveMIPI; 175 - break; 176 - case 2: 177 - /* register */ 178 - mipi_reg = MIPI_C; 179 - /* pointer to values */ 180 - mipi_val = &regs->saveMIPI_C; 181 - break; 182 - default: 183 - DRM_ERROR("%s, invalid pipe number.\n", __func__); 184 - return -EINVAL; 185 - } 186 - 187 - /* Pipe & plane A info */ 188 - pipe->dpll = PSB_RVDC32(map->dpll); 189 - pipe->fp0 = PSB_RVDC32(map->fp0); 190 - pipe->conf = PSB_RVDC32(map->conf); 191 - pipe->htotal = PSB_RVDC32(map->htotal); 192 - pipe->hblank = PSB_RVDC32(map->hblank); 193 - pipe->hsync = PSB_RVDC32(map->hsync); 194 - pipe->vtotal = PSB_RVDC32(map->vtotal); 195 - pipe->vblank = PSB_RVDC32(map->vblank); 196 - pipe->vsync = PSB_RVDC32(map->vsync); 197 - pipe->src = PSB_RVDC32(map->src); 198 - pipe->stride = PSB_RVDC32(map->stride); 199 - pipe->linoff = PSB_RVDC32(map->linoff); 200 - pipe->tileoff = PSB_RVDC32(map->tileoff); 201 - pipe->size = PSB_RVDC32(map->size); 202 - pipe->pos = PSB_RVDC32(map->pos); 203 - pipe->surf = PSB_RVDC32(map->surf); 204 - pipe->cntr = PSB_RVDC32(map->cntr); 205 - pipe->status = PSB_RVDC32(map->status); 206 - 207 - /*save palette (gamma) */ 208 - for (i = 0; i < 256; i++) 209 - pipe->palette[i] = PSB_RVDC32(map->palette + (i << 2)); 210 - 211 - if (pipenum == 1) { 212 - regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); 213 - regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); 214 - 215 - regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL); 216 - regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL); 217 - return 0; 218 - } 219 - 220 - *mipi_val = PSB_RVDC32(mipi_reg); 221 - return 0; 222 - } 223 - 224 - /* 225 - * mdfld_restore_display_registers 226 - * 227 - * Description: We are going to resume so restore display register state. 228 - * 229 - * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio 230 - */ 231 - static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) 232 - { 233 - /* To get panel out of ULPS mode. */ 234 - u32 temp = 0; 235 - u32 device_ready_reg = DEVICE_READY_REG; 236 - struct drm_psb_private *dev_priv = dev->dev_private; 237 - struct mdfld_dsi_config *dsi_config = NULL; 238 - struct medfield_state *regs = &dev_priv->regs.mdfld; 239 - struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; 240 - const struct psb_offset *map = &dev_priv->regmap[pipenum]; 241 - u32 i; 242 - u32 dpll; 243 - u32 timeout = 0; 244 - 245 - /* register */ 246 - u32 mipi_reg = MIPI; 247 - 248 - /* values */ 249 - u32 dpll_val = pipe->dpll; 250 - u32 mipi_val = regs->saveMIPI; 251 - 252 - switch (pipenum) { 253 - case 0: 254 - dpll_val &= ~DPLL_VCO_ENABLE; 255 - dsi_config = dev_priv->dsi_configs[0]; 256 - break; 257 - case 1: 258 - dpll_val &= ~DPLL_VCO_ENABLE; 259 - break; 260 - case 2: 261 - mipi_reg = MIPI_C; 262 - mipi_val = regs->saveMIPI_C; 263 - dsi_config = dev_priv->dsi_configs[1]; 264 - break; 265 - default: 266 - DRM_ERROR("%s, invalid pipe number.\n", __func__); 267 - return -EINVAL; 268 - } 269 - 270 - /*make sure VGA plane is off. it initializes to on after reset!*/ 271 - PSB_WVDC32(0x80000000, VGACNTRL); 272 - 273 - if (pipenum == 1) { 274 - PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, map->dpll); 275 - PSB_RVDC32(map->dpll); 276 - 277 - PSB_WVDC32(pipe->fp0, map->fp0); 278 - } else { 279 - 280 - dpll = PSB_RVDC32(map->dpll); 281 - 282 - if (!(dpll & DPLL_VCO_ENABLE)) { 283 - 284 - /* When ungating power of DPLL, needs to wait 0.5us 285 - before enable the VCO */ 286 - if (dpll & MDFLD_PWR_GATE_EN) { 287 - dpll &= ~MDFLD_PWR_GATE_EN; 288 - PSB_WVDC32(dpll, map->dpll); 289 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 290 - udelay(500); 291 - } 292 - 293 - PSB_WVDC32(pipe->fp0, map->fp0); 294 - PSB_WVDC32(dpll_val, map->dpll); 295 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 296 - udelay(500); 297 - 298 - dpll_val |= DPLL_VCO_ENABLE; 299 - PSB_WVDC32(dpll_val, map->dpll); 300 - PSB_RVDC32(map->dpll); 301 - 302 - /* wait for DSI PLL to lock */ 303 - while (timeout < 20000 && 304 - !(PSB_RVDC32(map->conf) & PIPECONF_DSIPLL_LOCK)) { 305 - udelay(150); 306 - timeout++; 307 - } 308 - 309 - if (timeout == 20000) { 310 - DRM_ERROR("%s, can't lock DSIPLL.\n", 311 - __func__); 312 - return -EINVAL; 313 - } 314 - } 315 - } 316 - /* Restore mode */ 317 - PSB_WVDC32(pipe->htotal, map->htotal); 318 - PSB_WVDC32(pipe->hblank, map->hblank); 319 - PSB_WVDC32(pipe->hsync, map->hsync); 320 - PSB_WVDC32(pipe->vtotal, map->vtotal); 321 - PSB_WVDC32(pipe->vblank, map->vblank); 322 - PSB_WVDC32(pipe->vsync, map->vsync); 323 - PSB_WVDC32(pipe->src, map->src); 324 - PSB_WVDC32(pipe->status, map->status); 325 - 326 - /*set up the plane*/ 327 - PSB_WVDC32(pipe->stride, map->stride); 328 - PSB_WVDC32(pipe->linoff, map->linoff); 329 - PSB_WVDC32(pipe->tileoff, map->tileoff); 330 - PSB_WVDC32(pipe->size, map->size); 331 - PSB_WVDC32(pipe->pos, map->pos); 332 - PSB_WVDC32(pipe->surf, map->surf); 333 - 334 - if (pipenum == 1) { 335 - /* restore palette (gamma) */ 336 - /* udelay(50000); */ 337 - for (i = 0; i < 256; i++) 338 - PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); 339 - 340 - PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL); 341 - PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); 342 - 343 - /*TODO: resume HDMI port */ 344 - 345 - /*TODO: resume pipe*/ 346 - 347 - /*enable the plane*/ 348 - PSB_WVDC32(pipe->cntr & ~DISPLAY_PLANE_ENABLE, map->cntr); 349 - 350 - return 0; 351 - } 352 - 353 - /*set up pipe related registers*/ 354 - PSB_WVDC32(mipi_val, mipi_reg); 355 - 356 - /*setup MIPI adapter + MIPI IP registers*/ 357 - if (dsi_config) 358 - mdfld_dsi_controller_init(dsi_config, pipenum); 359 - 360 - if (in_atomic() || in_interrupt()) 361 - mdelay(20); 362 - else 363 - msleep(20); 364 - 365 - /*enable the plane*/ 366 - PSB_WVDC32(pipe->cntr, map->cntr); 367 - 368 - if (in_atomic() || in_interrupt()) 369 - mdelay(20); 370 - else 371 - msleep(20); 372 - 373 - /* LP Hold Release */ 374 - temp = REG_READ(mipi_reg); 375 - temp |= LP_OUTPUT_HOLD_RELEASE; 376 - REG_WRITE(mipi_reg, temp); 377 - mdelay(1); 378 - 379 - 380 - /* Set DSI host to exit from Utra Low Power State */ 381 - temp = REG_READ(device_ready_reg); 382 - temp &= ~ULPS_MASK; 383 - temp |= 0x3; 384 - temp |= EXIT_ULPS_DEV_READY; 385 - REG_WRITE(device_ready_reg, temp); 386 - mdelay(1); 387 - 388 - temp = REG_READ(device_ready_reg); 389 - temp &= ~ULPS_MASK; 390 - temp |= EXITING_ULPS; 391 - REG_WRITE(device_ready_reg, temp); 392 - mdelay(1); 393 - 394 - /*enable the pipe*/ 395 - PSB_WVDC32(pipe->conf, map->conf); 396 - 397 - /* restore palette (gamma) */ 398 - /* udelay(50000); */ 399 - for (i = 0; i < 256; i++) 400 - PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); 401 - 402 - return 0; 403 - } 404 - 405 - static int mdfld_save_registers(struct drm_device *dev) 406 - { 407 - /* mdfld_save_cursor_overlay_registers(dev); */ 408 - mdfld_save_display_registers(dev, 0); 409 - mdfld_save_display_registers(dev, 2); 410 - mdfld_disable_crtc(dev, 0); 411 - mdfld_disable_crtc(dev, 2); 412 - 413 - return 0; 414 - } 415 - 416 - static int mdfld_restore_registers(struct drm_device *dev) 417 - { 418 - mdfld_restore_display_registers(dev, 2); 419 - mdfld_restore_display_registers(dev, 0); 420 - /* mdfld_restore_cursor_overlay_registers(dev); */ 421 - 422 - return 0; 423 - } 424 - 425 - static int mdfld_power_down(struct drm_device *dev) 426 - { 427 - /* FIXME */ 428 - return 0; 429 - } 430 - 431 - static int mdfld_power_up(struct drm_device *dev) 432 - { 433 - /* FIXME */ 434 - return 0; 435 - } 436 - 437 - /* Medfield */ 438 - static const struct psb_offset mdfld_regmap[3] = { 439 - { 440 - .fp0 = MRST_FPA0, 441 - .fp1 = MRST_FPA1, 442 - .cntr = DSPACNTR, 443 - .conf = PIPEACONF, 444 - .src = PIPEASRC, 445 - .dpll = MRST_DPLL_A, 446 - .htotal = HTOTAL_A, 447 - .hblank = HBLANK_A, 448 - .hsync = HSYNC_A, 449 - .vtotal = VTOTAL_A, 450 - .vblank = VBLANK_A, 451 - .vsync = VSYNC_A, 452 - .stride = DSPASTRIDE, 453 - .size = DSPASIZE, 454 - .pos = DSPAPOS, 455 - .surf = DSPASURF, 456 - .addr = MRST_DSPABASE, 457 - .status = PIPEASTAT, 458 - .linoff = DSPALINOFF, 459 - .tileoff = DSPATILEOFF, 460 - .palette = PALETTE_A, 461 - }, 462 - { 463 - .fp0 = MDFLD_DPLL_DIV0, 464 - .cntr = DSPBCNTR, 465 - .conf = PIPEBCONF, 466 - .src = PIPEBSRC, 467 - .dpll = MDFLD_DPLL_B, 468 - .htotal = HTOTAL_B, 469 - .hblank = HBLANK_B, 470 - .hsync = HSYNC_B, 471 - .vtotal = VTOTAL_B, 472 - .vblank = VBLANK_B, 473 - .vsync = VSYNC_B, 474 - .stride = DSPBSTRIDE, 475 - .size = DSPBSIZE, 476 - .pos = DSPBPOS, 477 - .surf = DSPBSURF, 478 - .addr = MRST_DSPBBASE, 479 - .status = PIPEBSTAT, 480 - .linoff = DSPBLINOFF, 481 - .tileoff = DSPBTILEOFF, 482 - .palette = PALETTE_B, 483 - }, 484 - { 485 - .fp0 = MRST_FPA0, /* This is what the old code did ?? */ 486 - .cntr = DSPCCNTR, 487 - .conf = PIPECCONF, 488 - .src = PIPECSRC, 489 - /* No DPLL_C */ 490 - .dpll = MRST_DPLL_A, 491 - .htotal = HTOTAL_C, 492 - .hblank = HBLANK_C, 493 - .hsync = HSYNC_C, 494 - .vtotal = VTOTAL_C, 495 - .vblank = VBLANK_C, 496 - .vsync = VSYNC_C, 497 - .stride = DSPCSTRIDE, 498 - .size = DSPBSIZE, 499 - .pos = DSPCPOS, 500 - .surf = DSPCSURF, 501 - .addr = MDFLD_DSPCBASE, 502 - .status = PIPECSTAT, 503 - .linoff = DSPCLINOFF, 504 - .tileoff = DSPCTILEOFF, 505 - .palette = PALETTE_C, 506 - }, 507 - }; 508 - 509 - /* 510 - * The GPIO lines for resetting DSI pipe 0 and 2 are available in the 511 - * PCI device 0000:00:0c.0 on the Medfield. 512 - */ 513 - static struct gpiod_lookup_table mdfld_dsi_pipe_gpio_table = { 514 - .table = { 515 - GPIO_LOOKUP("0000:00:0c.0", 128, "dsi-pipe0-reset", 516 - GPIO_ACTIVE_HIGH), 517 - GPIO_LOOKUP("0000:00:0c.0", 34, "dsi-pipe2-reset", 518 - GPIO_ACTIVE_HIGH), 519 - { }, 520 - }, 521 - }; 522 - 523 - static int mdfld_chip_setup(struct drm_device *dev) 524 - { 525 - struct drm_psb_private *dev_priv = dev->dev_private; 526 - struct pci_dev *pdev = to_pci_dev(dev->dev); 527 - 528 - if (pci_enable_msi(pdev)) 529 - dev_warn(dev->dev, "Enabling MSI failed!\n"); 530 - dev_priv->regmap = mdfld_regmap; 531 - 532 - /* Associate the GPIO lines with the DRM device */ 533 - mdfld_dsi_pipe_gpio_table.dev_id = dev_name(dev->dev); 534 - gpiod_add_lookup_table(&mdfld_dsi_pipe_gpio_table); 535 - 536 - return mid_chip_setup(dev); 537 - } 538 - 539 - const struct psb_ops mdfld_chip_ops = { 540 - .name = "mdfld", 541 - .pipes = 3, 542 - .crtcs = 3, 543 - .lvds_mask = (1 << 1), 544 - .hdmi_mask = (1 << 1), 545 - .cursor_needs_phys = 0, 546 - .sgx_offset = MRST_SGX_OFFSET, 547 - 548 - .chip_setup = mdfld_chip_setup, 549 - .crtc_helper = &mdfld_helper_funcs, 550 - .crtc_funcs = &psb_intel_crtc_funcs, 551 - 552 - .output_init = mdfld_output_init, 553 - 554 - #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 555 - .backlight_init = mdfld_backlight_init, 556 - #endif 557 - 558 - .save_regs = mdfld_save_registers, 559 - .restore_regs = mdfld_restore_registers, 560 - .save_crtc = gma_crtc_save, 561 - .restore_crtc = gma_crtc_restore, 562 - .power_down = mdfld_power_down, 563 - .power_up = mdfld_power_up, 564 - };
-1017
drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
··· 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 - 38 - static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, 39 - int pipe); 40 - 41 - static 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 - 59 - static 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 - 76 - static 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 - 94 - static 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 - 114 - static 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 - 120 - static 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->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->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->dev, "%s: FIFO not empty\n", 173 - __func__); 174 - } 175 - } 176 - 177 - static 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 - 198 - static 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 - \* ************************************************************************* */ 233 - static 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 - 420 - static 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 - */ 432 - int 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 - 470 - void 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 - 572 - void 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 - 601 - static 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 - 625 - shutdown_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 - 637 - static 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 - 685 - void 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 - 690 - bool 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 - 714 - void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder) 715 - { 716 - mdfld_dsi_dpi_set_power(encoder, false); 717 - } 718 - 719 - void 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. */ 727 - static 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 - 745 - static 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 - 774 - static 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 - 796 - static 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 - 816 - void 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->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 - */ 939 - struct 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 - }
-79
drivers/gpu/drm/gma500/mdfld_dsi_dpi.h
··· 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 - #ifndef __MDFLD_DSI_DPI_H__ 29 - #define __MDFLD_DSI_DPI_H__ 30 - 31 - #include "mdfld_dsi_output.h" 32 - #include "mdfld_output.h" 33 - 34 - struct mdfld_dsi_dpi_timing { 35 - u16 hsync_count; 36 - u16 hbp_count; 37 - u16 hfp_count; 38 - u16 hactive_count; 39 - u16 vsync_count; 40 - u16 vbp_count; 41 - u16 vfp_count; 42 - }; 43 - 44 - struct mdfld_dsi_dpi_output { 45 - struct mdfld_dsi_encoder base; 46 - struct drm_device *dev; 47 - 48 - int panel_on; 49 - int first_boot; 50 - 51 - const struct panel_funcs *p_funcs; 52 - }; 53 - 54 - #define MDFLD_DSI_DPI_OUTPUT(dsi_encoder)\ 55 - container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base) 56 - 57 - /* Export functions */ 58 - extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, 59 - struct mdfld_dsi_dpi_timing *dpi_timing, 60 - int num_lane, int bpp); 61 - extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, 62 - struct mdfld_dsi_connector *dsi_connector, 63 - const struct panel_funcs *p_funcs); 64 - 65 - /* MDFLD DPI helper functions */ 66 - extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode); 67 - extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, 68 - const struct drm_display_mode *mode, 69 - struct drm_display_mode *adjusted_mode); 70 - extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder); 71 - extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder); 72 - extern void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, 73 - struct drm_display_mode *mode, 74 - struct drm_display_mode *adjusted_mode); 75 - extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, 76 - int pipe); 77 - extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, 78 - int pipe); 79 - #endif /*__MDFLD_DSI_DPI_H__*/
-603
drivers/gpu/drm/gma500/mdfld_dsi_output.c
··· 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 - #include <linux/moduleparam.h> 30 - #include <linux/pm_runtime.h> 31 - #include <linux/gpio/consumer.h> 32 - 33 - #include <asm/intel_scu_ipc.h> 34 - 35 - #include "mdfld_dsi_dpi.h" 36 - #include "mdfld_dsi_output.h" 37 - #include "mdfld_dsi_pkg_sender.h" 38 - #include "mdfld_output.h" 39 - #include "tc35876x-dsi-lvds.h" 40 - 41 - /* get the LABC from command line. */ 42 - static int LABC_control = 1; 43 - 44 - #ifdef MODULE 45 - module_param(LABC_control, int, 0644); 46 - #else 47 - 48 - static int __init parse_LABC_control(char *arg) 49 - { 50 - /* LABC control can be passed in as a cmdline parameter */ 51 - /* to enable this feature add LABC=1 to cmdline */ 52 - /* to disable this feature add LABC=0 to cmdline */ 53 - if (!arg) 54 - return -EINVAL; 55 - 56 - if (!strcasecmp(arg, "0")) 57 - LABC_control = 0; 58 - else if (!strcasecmp(arg, "1")) 59 - LABC_control = 1; 60 - 61 - return 0; 62 - } 63 - early_param("LABC", parse_LABC_control); 64 - #endif 65 - 66 - /* 67 - * Check and see if the generic control or data buffer is empty and ready. 68 - */ 69 - void mdfld_dsi_gen_fifo_ready(struct drm_device *dev, u32 gen_fifo_stat_reg, 70 - u32 fifo_stat) 71 - { 72 - u32 GEN_BF_time_out_count; 73 - 74 - /* Check MIPI Adatper command registers */ 75 - for (GEN_BF_time_out_count = 0; 76 - GEN_BF_time_out_count < GEN_FB_TIME_OUT; 77 - GEN_BF_time_out_count++) { 78 - if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat) 79 - break; 80 - udelay(100); 81 - } 82 - 83 - if (GEN_BF_time_out_count == GEN_FB_TIME_OUT) 84 - DRM_ERROR("mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x.\n", 85 - gen_fifo_stat_reg); 86 - } 87 - 88 - /* 89 - * Manage the DSI MIPI keyboard and display brightness. 90 - * FIXME: this is exported to OSPM code. should work out an specific 91 - * display interface to OSPM. 92 - */ 93 - 94 - void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe) 95 - { 96 - struct mdfld_dsi_pkg_sender *sender = 97 - mdfld_dsi_get_pkg_sender(dsi_config); 98 - struct drm_device *dev; 99 - struct drm_psb_private *dev_priv; 100 - u32 gen_ctrl_val; 101 - 102 - if (!sender) { 103 - DRM_ERROR("No sender found\n"); 104 - return; 105 - } 106 - 107 - dev = sender->dev; 108 - dev_priv = dev->dev_private; 109 - 110 - /* Set default display backlight value to 85% (0xd8)*/ 111 - mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1, 112 - true); 113 - 114 - /* Set minimum brightness setting of CABC function to 20% (0x33)*/ 115 - mdfld_dsi_send_mcs_short(sender, write_cabc_min_bright, 0x33, 1, true); 116 - 117 - /* Enable backlight or/and LABC */ 118 - gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON | 119 - BACKLIGHT_ON; 120 - if (LABC_control == 1) 121 - gen_ctrl_val |= DISPLAY_DIMMING_ON | DISPLAY_BRIGHTNESS_AUTO 122 - | GAMMA_AUTO; 123 - 124 - if (LABC_control == 1) 125 - gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON; 126 - 127 - dev_priv->mipi_ctrl_display = gen_ctrl_val; 128 - 129 - mdfld_dsi_send_mcs_short(sender, write_ctrl_display, (u8)gen_ctrl_val, 130 - 1, true); 131 - 132 - mdfld_dsi_send_mcs_short(sender, write_ctrl_cabc, UI_IMAGE, 1, true); 133 - } 134 - 135 - void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level) 136 - { 137 - struct mdfld_dsi_pkg_sender *sender; 138 - struct drm_psb_private *dev_priv; 139 - struct mdfld_dsi_config *dsi_config; 140 - u32 gen_ctrl_val = 0; 141 - int p_type = TMD_VID; 142 - 143 - if (!dev || (pipe != 0 && pipe != 2)) { 144 - DRM_ERROR("Invalid parameter\n"); 145 - return; 146 - } 147 - 148 - p_type = mdfld_get_panel_type(dev, 0); 149 - 150 - dev_priv = dev->dev_private; 151 - 152 - if (pipe) 153 - dsi_config = dev_priv->dsi_configs[1]; 154 - else 155 - dsi_config = dev_priv->dsi_configs[0]; 156 - 157 - sender = mdfld_dsi_get_pkg_sender(dsi_config); 158 - 159 - if (!sender) { 160 - DRM_ERROR("No sender found\n"); 161 - return; 162 - } 163 - 164 - gen_ctrl_val = (level * 0xff / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff; 165 - 166 - dev_dbg(sender->dev->dev, "pipe = %d, gen_ctrl_val = %d.\n", 167 - pipe, gen_ctrl_val); 168 - 169 - if (p_type == TMD_VID) { 170 - /* Set display backlight value */ 171 - mdfld_dsi_send_mcs_short(sender, tmd_write_display_brightness, 172 - (u8)gen_ctrl_val, 1, true); 173 - } else { 174 - /* Set display backlight value */ 175 - mdfld_dsi_send_mcs_short(sender, write_display_brightness, 176 - (u8)gen_ctrl_val, 1, true); 177 - 178 - /* Enable backlight control */ 179 - if (level == 0) 180 - gen_ctrl_val = 0; 181 - else 182 - gen_ctrl_val = dev_priv->mipi_ctrl_display; 183 - 184 - mdfld_dsi_send_mcs_short(sender, write_ctrl_display, 185 - (u8)gen_ctrl_val, 1, true); 186 - } 187 - } 188 - 189 - static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config, 190 - u8 dcs, u32 *data, bool hs) 191 - { 192 - struct mdfld_dsi_pkg_sender *sender 193 - = mdfld_dsi_get_pkg_sender(dsi_config); 194 - 195 - if (!sender || !data) { 196 - DRM_ERROR("Invalid parameter\n"); 197 - return -EINVAL; 198 - } 199 - 200 - return mdfld_dsi_read_mcs(sender, dcs, data, 1, hs); 201 - } 202 - 203 - int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, u32 *mode, 204 - bool hs) 205 - { 206 - if (!dsi_config || !mode) { 207 - DRM_ERROR("Invalid parameter\n"); 208 - return -EINVAL; 209 - } 210 - 211 - return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, hs); 212 - } 213 - 214 - /* 215 - * NOTE: this function was used by OSPM. 216 - * TODO: will be removed later, should work out display interfaces for OSPM 217 - */ 218 - void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe) 219 - { 220 - if (!dsi_config || ((pipe != 0) && (pipe != 2))) { 221 - DRM_ERROR("Invalid parameters\n"); 222 - return; 223 - } 224 - 225 - mdfld_dsi_dpi_controller_init(dsi_config, pipe); 226 - } 227 - 228 - static void mdfld_dsi_connector_save(struct drm_connector *connector) 229 - { 230 - } 231 - 232 - static void mdfld_dsi_connector_restore(struct drm_connector *connector) 233 - { 234 - } 235 - 236 - /* FIXME: start using the force parameter */ 237 - static enum drm_connector_status 238 - mdfld_dsi_connector_detect(struct drm_connector *connector, bool force) 239 - { 240 - struct mdfld_dsi_connector *dsi_connector 241 - = mdfld_dsi_connector(connector); 242 - 243 - dsi_connector->status = connector_status_connected; 244 - 245 - return dsi_connector->status; 246 - } 247 - 248 - static int mdfld_dsi_connector_set_property(struct drm_connector *connector, 249 - struct drm_property *property, 250 - uint64_t value) 251 - { 252 - struct drm_encoder *encoder = connector->encoder; 253 - 254 - if (!strcmp(property->name, "scaling mode") && encoder) { 255 - struct gma_crtc *gma_crtc = to_gma_crtc(encoder->crtc); 256 - bool centerechange; 257 - uint64_t val; 258 - 259 - if (!gma_crtc) 260 - goto set_prop_error; 261 - 262 - switch (value) { 263 - case DRM_MODE_SCALE_FULLSCREEN: 264 - break; 265 - case DRM_MODE_SCALE_NO_SCALE: 266 - break; 267 - case DRM_MODE_SCALE_ASPECT: 268 - break; 269 - default: 270 - goto set_prop_error; 271 - } 272 - 273 - if (drm_object_property_get_value(&connector->base, property, &val)) 274 - goto set_prop_error; 275 - 276 - if (val == value) 277 - goto set_prop_done; 278 - 279 - if (drm_object_property_set_value(&connector->base, 280 - property, value)) 281 - goto set_prop_error; 282 - 283 - centerechange = (val == DRM_MODE_SCALE_NO_SCALE) || 284 - (value == DRM_MODE_SCALE_NO_SCALE); 285 - 286 - if (gma_crtc->saved_mode.hdisplay != 0 && 287 - gma_crtc->saved_mode.vdisplay != 0) { 288 - if (centerechange) { 289 - if (!drm_crtc_helper_set_mode(encoder->crtc, 290 - &gma_crtc->saved_mode, 291 - encoder->crtc->x, 292 - encoder->crtc->y, 293 - encoder->crtc->primary->fb)) 294 - goto set_prop_error; 295 - } else { 296 - const struct drm_encoder_helper_funcs *funcs = 297 - encoder->helper_private; 298 - funcs->mode_set(encoder, 299 - &gma_crtc->saved_mode, 300 - &gma_crtc->saved_adjusted_mode); 301 - } 302 - } 303 - } else if (!strcmp(property->name, "backlight") && encoder) { 304 - if (drm_object_property_set_value(&connector->base, property, 305 - value)) 306 - goto set_prop_error; 307 - else 308 - gma_backlight_set(encoder->dev, value); 309 - } 310 - set_prop_done: 311 - return 0; 312 - set_prop_error: 313 - return -1; 314 - } 315 - 316 - static void mdfld_dsi_connector_destroy(struct drm_connector *connector) 317 - { 318 - struct mdfld_dsi_connector *dsi_connector = 319 - mdfld_dsi_connector(connector); 320 - struct mdfld_dsi_pkg_sender *sender; 321 - 322 - if (!dsi_connector) 323 - return; 324 - drm_connector_unregister(connector); 325 - drm_connector_cleanup(connector); 326 - sender = dsi_connector->pkg_sender; 327 - mdfld_dsi_pkg_sender_destroy(sender); 328 - kfree(dsi_connector); 329 - } 330 - 331 - static int mdfld_dsi_connector_get_modes(struct drm_connector *connector) 332 - { 333 - struct mdfld_dsi_connector *dsi_connector = 334 - mdfld_dsi_connector(connector); 335 - struct mdfld_dsi_config *dsi_config = 336 - mdfld_dsi_get_config(dsi_connector); 337 - struct drm_display_mode *fixed_mode = dsi_config->fixed_mode; 338 - struct drm_display_mode *dup_mode = NULL; 339 - struct drm_device *dev = connector->dev; 340 - 341 - if (fixed_mode) { 342 - dev_dbg(dev->dev, "fixed_mode %dx%d\n", 343 - fixed_mode->hdisplay, fixed_mode->vdisplay); 344 - dup_mode = drm_mode_duplicate(dev, fixed_mode); 345 - drm_mode_probed_add(connector, dup_mode); 346 - return 1; 347 - } 348 - DRM_ERROR("Didn't get any modes!\n"); 349 - return 0; 350 - } 351 - 352 - static enum drm_mode_status mdfld_dsi_connector_mode_valid(struct drm_connector *connector, 353 - struct drm_display_mode *mode) 354 - { 355 - struct mdfld_dsi_connector *dsi_connector = 356 - mdfld_dsi_connector(connector); 357 - struct mdfld_dsi_config *dsi_config = 358 - mdfld_dsi_get_config(dsi_connector); 359 - struct drm_display_mode *fixed_mode = dsi_config->fixed_mode; 360 - 361 - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 362 - return MODE_NO_DBLESCAN; 363 - 364 - if (mode->flags & DRM_MODE_FLAG_INTERLACE) 365 - return MODE_NO_INTERLACE; 366 - 367 - /** 368 - * FIXME: current DC has no fitting unit, reject any mode setting 369 - * request 370 - * Will figure out a way to do up-scaling(panel fitting) later. 371 - **/ 372 - if (fixed_mode) { 373 - if (mode->hdisplay != fixed_mode->hdisplay) 374 - return MODE_PANEL; 375 - 376 - if (mode->vdisplay != fixed_mode->vdisplay) 377 - return MODE_PANEL; 378 - } 379 - 380 - return MODE_OK; 381 - } 382 - 383 - static struct drm_encoder *mdfld_dsi_connector_best_encoder( 384 - struct drm_connector *connector) 385 - { 386 - struct mdfld_dsi_connector *dsi_connector = 387 - mdfld_dsi_connector(connector); 388 - struct mdfld_dsi_config *dsi_config = 389 - mdfld_dsi_get_config(dsi_connector); 390 - return &dsi_config->encoder->base.base; 391 - } 392 - 393 - /*DSI connector funcs*/ 394 - static const struct drm_connector_funcs mdfld_dsi_connector_funcs = { 395 - .dpms = drm_helper_connector_dpms, 396 - .detect = mdfld_dsi_connector_detect, 397 - .fill_modes = drm_helper_probe_single_connector_modes, 398 - .set_property = mdfld_dsi_connector_set_property, 399 - .destroy = mdfld_dsi_connector_destroy, 400 - }; 401 - 402 - /*DSI connector helper funcs*/ 403 - static const struct drm_connector_helper_funcs 404 - mdfld_dsi_connector_helper_funcs = { 405 - .get_modes = mdfld_dsi_connector_get_modes, 406 - .mode_valid = mdfld_dsi_connector_mode_valid, 407 - .best_encoder = mdfld_dsi_connector_best_encoder, 408 - }; 409 - 410 - static int mdfld_dsi_get_default_config(struct drm_device *dev, 411 - struct mdfld_dsi_config *config, int pipe) 412 - { 413 - if (!dev || !config) { 414 - DRM_ERROR("Invalid parameters"); 415 - return -EINVAL; 416 - } 417 - 418 - config->bpp = 24; 419 - if (mdfld_get_panel_type(dev, pipe) == TC35876X) 420 - config->lane_count = 4; 421 - else 422 - config->lane_count = 2; 423 - config->channel_num = 0; 424 - 425 - if (mdfld_get_panel_type(dev, pipe) == TMD_VID) 426 - config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE; 427 - else if (mdfld_get_panel_type(dev, pipe) == TC35876X) 428 - config->video_mode = 429 - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS; 430 - else 431 - config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE; 432 - 433 - return 0; 434 - } 435 - 436 - int mdfld_dsi_panel_reset(struct drm_device *ddev, int pipe) 437 - { 438 - struct device *dev = ddev->dev; 439 - struct gpio_desc *gpiod; 440 - 441 - /* 442 - * Raise the GPIO reset line for the corresponding pipe to HIGH, 443 - * this is probably because it is active low so this takes the 444 - * respective pipe out of reset. (We have no code to put it back 445 - * into reset in this driver.) 446 - */ 447 - switch (pipe) { 448 - case 0: 449 - gpiod = gpiod_get(dev, "dsi-pipe0-reset", GPIOD_OUT_HIGH); 450 - if (IS_ERR(gpiod)) 451 - return PTR_ERR(gpiod); 452 - break; 453 - case 2: 454 - gpiod = gpiod_get(dev, "dsi-pipe2-reset", GPIOD_OUT_HIGH); 455 - if (IS_ERR(gpiod)) 456 - return PTR_ERR(gpiod); 457 - break; 458 - default: 459 - DRM_DEV_ERROR(dev, "Invalid output pipe\n"); 460 - return -EINVAL; 461 - } 462 - gpiod_put(gpiod); 463 - 464 - /* Flush posted writes on the device */ 465 - gpiod = gpiod_get(dev, "dsi-pipe0-reset", GPIOD_ASIS); 466 - if (IS_ERR(gpiod)) 467 - return PTR_ERR(gpiod); 468 - gpiod_get_value(gpiod); 469 - gpiod_put(gpiod); 470 - 471 - return 0; 472 - } 473 - 474 - /* 475 - * MIPI output init 476 - * @dev drm device 477 - * @pipe pipe number. 0 or 2 478 - * @config 479 - * 480 - * Do the initialization of a MIPI output, including create DRM mode objects 481 - * initialization of DSI output on @pipe 482 - */ 483 - void mdfld_dsi_output_init(struct drm_device *dev, 484 - int pipe, 485 - const struct panel_funcs *p_vid_funcs) 486 - { 487 - struct mdfld_dsi_config *dsi_config; 488 - struct mdfld_dsi_connector *dsi_connector; 489 - struct drm_connector *connector; 490 - struct mdfld_dsi_encoder *encoder; 491 - struct drm_psb_private *dev_priv = dev->dev_private; 492 - struct panel_info dsi_panel_info; 493 - u32 width_mm, height_mm; 494 - 495 - dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe); 496 - 497 - if (pipe != 0 && pipe != 2) { 498 - DRM_ERROR("Invalid parameter\n"); 499 - return; 500 - } 501 - 502 - /*create a new connector*/ 503 - dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL); 504 - if (!dsi_connector) { 505 - DRM_ERROR("No memory"); 506 - return; 507 - } 508 - 509 - dsi_connector->pipe = pipe; 510 - 511 - dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), 512 - GFP_KERNEL); 513 - if (!dsi_config) { 514 - DRM_ERROR("cannot allocate memory for DSI config\n"); 515 - goto dsi_init_err0; 516 - } 517 - mdfld_dsi_get_default_config(dev, dsi_config, pipe); 518 - 519 - dsi_connector->private = dsi_config; 520 - 521 - dsi_config->changed = 1; 522 - dsi_config->dev = dev; 523 - 524 - dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev); 525 - if (p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info)) 526 - goto dsi_init_err0; 527 - 528 - width_mm = dsi_panel_info.width_mm; 529 - height_mm = dsi_panel_info.height_mm; 530 - 531 - dsi_config->mode = dsi_config->fixed_mode; 532 - dsi_config->connector = dsi_connector; 533 - 534 - if (!dsi_config->fixed_mode) { 535 - DRM_ERROR("No panel fixed mode was found\n"); 536 - goto dsi_init_err0; 537 - } 538 - 539 - if (pipe && dev_priv->dsi_configs[0]) { 540 - dsi_config->dvr_ic_inited = 0; 541 - dev_priv->dsi_configs[1] = dsi_config; 542 - } else if (pipe == 0) { 543 - dsi_config->dvr_ic_inited = 1; 544 - dev_priv->dsi_configs[0] = dsi_config; 545 - } else { 546 - DRM_ERROR("Trying to init MIPI1 before MIPI0\n"); 547 - goto dsi_init_err0; 548 - } 549 - 550 - 551 - connector = &dsi_connector->base.base; 552 - dsi_connector->base.save = mdfld_dsi_connector_save; 553 - dsi_connector->base.restore = mdfld_dsi_connector_restore; 554 - 555 - drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, 556 - DRM_MODE_CONNECTOR_LVDS); 557 - drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs); 558 - 559 - connector->display_info.subpixel_order = SubPixelHorizontalRGB; 560 - connector->display_info.width_mm = width_mm; 561 - connector->display_info.height_mm = height_mm; 562 - connector->interlace_allowed = false; 563 - connector->doublescan_allowed = false; 564 - 565 - /*attach properties*/ 566 - drm_object_attach_property(&connector->base, 567 - dev->mode_config.scaling_mode_property, 568 - DRM_MODE_SCALE_FULLSCREEN); 569 - drm_object_attach_property(&connector->base, 570 - dev_priv->backlight_property, 571 - MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); 572 - 573 - /*init DSI package sender on this output*/ 574 - if (mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) { 575 - DRM_ERROR("Package Sender initialization failed on pipe %d\n", 576 - pipe); 577 - goto dsi_init_err0; 578 - } 579 - 580 - encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs); 581 - if (!encoder) { 582 - DRM_ERROR("Create DPI encoder failed\n"); 583 - goto dsi_init_err1; 584 - } 585 - encoder->private = dsi_config; 586 - dsi_config->encoder = encoder; 587 - encoder->base.type = (pipe == 0) ? INTEL_OUTPUT_MIPI : 588 - INTEL_OUTPUT_MIPI2; 589 - drm_connector_register(connector); 590 - return; 591 - 592 - /*TODO: add code to destroy outputs on error*/ 593 - dsi_init_err1: 594 - /*destroy sender*/ 595 - mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender); 596 - 597 - drm_connector_cleanup(connector); 598 - 599 - kfree(dsi_config->fixed_mode); 600 - kfree(dsi_config); 601 - dsi_init_err0: 602 - kfree(dsi_connector); 603 - }
-377
drivers/gpu/drm/gma500/mdfld_dsi_output.h
··· 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 - #ifndef __MDFLD_DSI_OUTPUT_H__ 29 - #define __MDFLD_DSI_OUTPUT_H__ 30 - 31 - #include <linux/backlight.h> 32 - 33 - #include <asm/intel-mid.h> 34 - 35 - #include <drm/drm.h> 36 - #include <drm/drm_crtc.h> 37 - #include <drm/drm_edid.h> 38 - 39 - #include "mdfld_output.h" 40 - #include "psb_drv.h" 41 - #include "psb_intel_drv.h" 42 - #include "psb_intel_reg.h" 43 - 44 - #define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) 45 - #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) 46 - #define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end)) 47 - #define FLD_MOD(orig, val, start, end) \ 48 - (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 49 - 50 - #define REG_FLD_MOD(reg, val, start, end) \ 51 - REG_WRITE(reg, FLD_MOD(REG_READ(reg), val, start, end)) 52 - 53 - static inline int REGISTER_FLD_WAIT(struct drm_device *dev, u32 reg, 54 - u32 val, int start, int end) 55 - { 56 - int t = 100000; 57 - 58 - while (FLD_GET(REG_READ(reg), start, end) != val) { 59 - if (--t == 0) 60 - return 1; 61 - } 62 - 63 - return 0; 64 - } 65 - 66 - #define REG_FLD_WAIT(reg, val, start, end) \ 67 - REGISTER_FLD_WAIT(dev, reg, val, start, end) 68 - 69 - #define REG_BIT_WAIT(reg, val, bitnum) \ 70 - REGISTER_FLD_WAIT(dev, reg, val, bitnum, bitnum) 71 - 72 - #define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100 73 - 74 - #ifdef DEBUG 75 - #define CHECK_PIPE(pipe) ({ \ 76 - const typeof(pipe) __pipe = (pipe); \ 77 - BUG_ON(__pipe != 0 && __pipe != 2); \ 78 - __pipe; }) 79 - #else 80 - #define CHECK_PIPE(pipe) (pipe) 81 - #endif 82 - 83 - /* 84 - * Actual MIPIA->MIPIC reg offset is 0x800, value 0x400 is valid for 0 and 2 85 - */ 86 - #define REG_OFFSET(pipe) (CHECK_PIPE(pipe) * 0x400) 87 - 88 - /* mdfld DSI controller registers */ 89 - #define MIPI_DEVICE_READY_REG(pipe) (0xb000 + REG_OFFSET(pipe)) 90 - #define MIPI_INTR_STAT_REG(pipe) (0xb004 + REG_OFFSET(pipe)) 91 - #define MIPI_INTR_EN_REG(pipe) (0xb008 + REG_OFFSET(pipe)) 92 - #define MIPI_DSI_FUNC_PRG_REG(pipe) (0xb00c + REG_OFFSET(pipe)) 93 - #define MIPI_HS_TX_TIMEOUT_REG(pipe) (0xb010 + REG_OFFSET(pipe)) 94 - #define MIPI_LP_RX_TIMEOUT_REG(pipe) (0xb014 + REG_OFFSET(pipe)) 95 - #define MIPI_TURN_AROUND_TIMEOUT_REG(pipe) (0xb018 + REG_OFFSET(pipe)) 96 - #define MIPI_DEVICE_RESET_TIMER_REG(pipe) (0xb01c + REG_OFFSET(pipe)) 97 - #define MIPI_DPI_RESOLUTION_REG(pipe) (0xb020 + REG_OFFSET(pipe)) 98 - #define MIPI_DBI_FIFO_THROTTLE_REG(pipe) (0xb024 + REG_OFFSET(pipe)) 99 - #define MIPI_HSYNC_COUNT_REG(pipe) (0xb028 + REG_OFFSET(pipe)) 100 - #define MIPI_HBP_COUNT_REG(pipe) (0xb02c + REG_OFFSET(pipe)) 101 - #define MIPI_HFP_COUNT_REG(pipe) (0xb030 + REG_OFFSET(pipe)) 102 - #define MIPI_HACTIVE_COUNT_REG(pipe) (0xb034 + REG_OFFSET(pipe)) 103 - #define MIPI_VSYNC_COUNT_REG(pipe) (0xb038 + REG_OFFSET(pipe)) 104 - #define MIPI_VBP_COUNT_REG(pipe) (0xb03c + REG_OFFSET(pipe)) 105 - #define MIPI_VFP_COUNT_REG(pipe) (0xb040 + REG_OFFSET(pipe)) 106 - #define MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe) (0xb044 + REG_OFFSET(pipe)) 107 - #define MIPI_DPI_CONTROL_REG(pipe) (0xb048 + REG_OFFSET(pipe)) 108 - #define MIPI_DPI_DATA_REG(pipe) (0xb04c + REG_OFFSET(pipe)) 109 - #define MIPI_INIT_COUNT_REG(pipe) (0xb050 + REG_OFFSET(pipe)) 110 - #define MIPI_MAX_RETURN_PACK_SIZE_REG(pipe) (0xb054 + REG_OFFSET(pipe)) 111 - #define MIPI_VIDEO_MODE_FORMAT_REG(pipe) (0xb058 + REG_OFFSET(pipe)) 112 - #define MIPI_EOT_DISABLE_REG(pipe) (0xb05c + REG_OFFSET(pipe)) 113 - #define MIPI_LP_BYTECLK_REG(pipe) (0xb060 + REG_OFFSET(pipe)) 114 - #define MIPI_LP_GEN_DATA_REG(pipe) (0xb064 + REG_OFFSET(pipe)) 115 - #define MIPI_HS_GEN_DATA_REG(pipe) (0xb068 + REG_OFFSET(pipe)) 116 - #define MIPI_LP_GEN_CTRL_REG(pipe) (0xb06c + REG_OFFSET(pipe)) 117 - #define MIPI_HS_GEN_CTRL_REG(pipe) (0xb070 + REG_OFFSET(pipe)) 118 - #define MIPI_GEN_FIFO_STAT_REG(pipe) (0xb074 + REG_OFFSET(pipe)) 119 - #define MIPI_HS_LS_DBI_ENABLE_REG(pipe) (0xb078 + REG_OFFSET(pipe)) 120 - #define MIPI_DPHY_PARAM_REG(pipe) (0xb080 + REG_OFFSET(pipe)) 121 - #define MIPI_DBI_BW_CTRL_REG(pipe) (0xb084 + REG_OFFSET(pipe)) 122 - #define MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe) (0xb088 + REG_OFFSET(pipe)) 123 - 124 - #define MIPI_CTRL_REG(pipe) (0xb104 + REG_OFFSET(pipe)) 125 - #define MIPI_DATA_ADD_REG(pipe) (0xb108 + REG_OFFSET(pipe)) 126 - #define MIPI_DATA_LEN_REG(pipe) (0xb10c + REG_OFFSET(pipe)) 127 - #define MIPI_CMD_ADD_REG(pipe) (0xb110 + REG_OFFSET(pipe)) 128 - #define MIPI_CMD_LEN_REG(pipe) (0xb114 + REG_OFFSET(pipe)) 129 - 130 - /* non-uniform reg offset */ 131 - #define MIPI_PORT_CONTROL(pipe) (CHECK_PIPE(pipe) ? MIPI_C : MIPI) 132 - 133 - #define DSI_DEVICE_READY (0x1) 134 - #define DSI_POWER_STATE_ULPS_ENTER (0x2 << 1) 135 - #define DSI_POWER_STATE_ULPS_EXIT (0x1 << 1) 136 - #define DSI_POWER_STATE_ULPS_OFFSET (0x1) 137 - 138 - 139 - #define DSI_ONE_DATA_LANE (0x1) 140 - #define DSI_TWO_DATA_LANE (0x2) 141 - #define DSI_THREE_DATA_LANE (0X3) 142 - #define DSI_FOUR_DATA_LANE (0x4) 143 - #define DSI_DPI_VIRT_CHANNEL_OFFSET (0x3) 144 - #define DSI_DBI_VIRT_CHANNEL_OFFSET (0x5) 145 - #define DSI_DPI_COLOR_FORMAT_RGB565 (0x01 << 7) 146 - #define DSI_DPI_COLOR_FORMAT_RGB666 (0x02 << 7) 147 - #define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK (0x03 << 7) 148 - #define DSI_DPI_COLOR_FORMAT_RGB888 (0x04 << 7) 149 - #define DSI_DBI_COLOR_FORMAT_OPTION2 (0x05 << 13) 150 - 151 - #define DSI_INTR_STATE_RXSOTERROR BIT(0) 152 - 153 - #define DSI_INTR_STATE_SPL_PKG_SENT BIT(30) 154 - #define DSI_INTR_STATE_TE BIT(31) 155 - 156 - #define DSI_HS_TX_TIMEOUT_MASK (0xffffff) 157 - 158 - #define DSI_LP_RX_TIMEOUT_MASK (0xffffff) 159 - 160 - #define DSI_TURN_AROUND_TIMEOUT_MASK (0x3f) 161 - 162 - #define DSI_RESET_TIMER_MASK (0xffff) 163 - 164 - #define DSI_DBI_FIFO_WM_HALF (0x0) 165 - #define DSI_DBI_FIFO_WM_QUARTER (0x1) 166 - #define DSI_DBI_FIFO_WM_LOW (0x2) 167 - 168 - #define DSI_DPI_TIMING_MASK (0xffff) 169 - 170 - #define DSI_INIT_TIMER_MASK (0xffff) 171 - 172 - #define DSI_DBI_RETURN_PACK_SIZE_MASK (0x3ff) 173 - 174 - #define DSI_LP_BYTECLK_MASK (0x0ffff) 175 - 176 - #define DSI_HS_CTRL_GEN_SHORT_W0 (0x03) 177 - #define DSI_HS_CTRL_GEN_SHORT_W1 (0x13) 178 - #define DSI_HS_CTRL_GEN_SHORT_W2 (0x23) 179 - #define DSI_HS_CTRL_GEN_R0 (0x04) 180 - #define DSI_HS_CTRL_GEN_R1 (0x14) 181 - #define DSI_HS_CTRL_GEN_R2 (0x24) 182 - #define DSI_HS_CTRL_GEN_LONG_W (0x29) 183 - #define DSI_HS_CTRL_MCS_SHORT_W0 (0x05) 184 - #define DSI_HS_CTRL_MCS_SHORT_W1 (0x15) 185 - #define DSI_HS_CTRL_MCS_R0 (0x06) 186 - #define DSI_HS_CTRL_MCS_LONG_W (0x39) 187 - #define DSI_HS_CTRL_VC_OFFSET (0x06) 188 - #define DSI_HS_CTRL_WC_OFFSET (0x08) 189 - 190 - #define DSI_FIFO_GEN_HS_DATA_FULL BIT(0) 191 - #define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY BIT(1) 192 - #define DSI_FIFO_GEN_HS_DATA_EMPTY BIT(2) 193 - #define DSI_FIFO_GEN_LP_DATA_FULL BIT(8) 194 - #define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY BIT(9) 195 - #define DSI_FIFO_GEN_LP_DATA_EMPTY BIT(10) 196 - #define DSI_FIFO_GEN_HS_CTRL_FULL BIT(16) 197 - #define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY BIT(17) 198 - #define DSI_FIFO_GEN_HS_CTRL_EMPTY BIT(18) 199 - #define DSI_FIFO_GEN_LP_CTRL_FULL BIT(24) 200 - #define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY BIT(25) 201 - #define DSI_FIFO_GEN_LP_CTRL_EMPTY BIT(26) 202 - #define DSI_FIFO_DBI_EMPTY BIT(27) 203 - #define DSI_FIFO_DPI_EMPTY BIT(28) 204 - 205 - #define DSI_DBI_HS_LP_SWITCH_MASK (0x1) 206 - 207 - #define DSI_HS_LP_SWITCH_COUNTER_OFFSET (0x0) 208 - #define DSI_LP_HS_SWITCH_COUNTER_OFFSET (0x16) 209 - 210 - #define DSI_DPI_CTRL_HS_SHUTDOWN (0x00000001) 211 - #define DSI_DPI_CTRL_HS_TURN_ON (0x00000002) 212 - 213 - /*dsi power modes*/ 214 - #define DSI_POWER_MODE_DISPLAY_ON BIT(2) 215 - #define DSI_POWER_MODE_NORMAL_ON BIT(3) 216 - #define DSI_POWER_MODE_SLEEP_OUT BIT(4) 217 - #define DSI_POWER_MODE_PARTIAL_ON BIT(5) 218 - #define DSI_POWER_MODE_IDLE_ON BIT(6) 219 - 220 - enum { 221 - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1, 222 - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2, 223 - MDFLD_DSI_VIDEO_BURST_MODE = 3, 224 - }; 225 - 226 - #define DSI_DPI_COMPLETE_LAST_LINE BIT(2) 227 - #define DSI_DPI_DISABLE_BTA BIT(3) 228 - 229 - struct mdfld_dsi_connector { 230 - struct gma_connector base; 231 - 232 - int pipe; 233 - void *private; 234 - void *pkg_sender; 235 - 236 - /* Connection status */ 237 - enum drm_connector_status status; 238 - }; 239 - 240 - struct mdfld_dsi_encoder { 241 - struct gma_encoder base; 242 - void *private; 243 - }; 244 - 245 - /* 246 - * DSI config, consists of one DSI connector, two DSI encoders. 247 - * DRM will pick up on DSI encoder basing on differents configs. 248 - */ 249 - struct mdfld_dsi_config { 250 - struct drm_device *dev; 251 - struct drm_display_mode *fixed_mode; 252 - struct drm_display_mode *mode; 253 - 254 - struct mdfld_dsi_connector *connector; 255 - struct mdfld_dsi_encoder *encoder; 256 - 257 - int changed; 258 - 259 - int bpp; 260 - int lane_count; 261 - /*Virtual channel number for this encoder*/ 262 - int channel_num; 263 - /*video mode configure*/ 264 - int video_mode; 265 - 266 - int dvr_ic_inited; 267 - }; 268 - 269 - static inline struct mdfld_dsi_connector *mdfld_dsi_connector( 270 - struct drm_connector *connector) 271 - { 272 - struct gma_connector *gma_connector; 273 - 274 - gma_connector = to_gma_connector(connector); 275 - 276 - return container_of(gma_connector, struct mdfld_dsi_connector, base); 277 - } 278 - 279 - static inline struct mdfld_dsi_encoder *mdfld_dsi_encoder( 280 - struct drm_encoder *encoder) 281 - { 282 - struct gma_encoder *gma_encoder; 283 - 284 - gma_encoder = to_gma_encoder(encoder); 285 - 286 - return container_of(gma_encoder, struct mdfld_dsi_encoder, base); 287 - } 288 - 289 - static inline struct mdfld_dsi_config * 290 - mdfld_dsi_get_config(struct mdfld_dsi_connector *connector) 291 - { 292 - if (!connector) 293 - return NULL; 294 - return (struct mdfld_dsi_config *)connector->private; 295 - } 296 - 297 - static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config) 298 - { 299 - struct mdfld_dsi_connector *dsi_connector; 300 - 301 - if (!config) 302 - return NULL; 303 - 304 - dsi_connector = config->connector; 305 - 306 - if (!dsi_connector) 307 - return NULL; 308 - 309 - return dsi_connector->pkg_sender; 310 - } 311 - 312 - static inline struct mdfld_dsi_config * 313 - mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder) 314 - { 315 - if (!encoder) 316 - return NULL; 317 - return (struct mdfld_dsi_config *)encoder->private; 318 - } 319 - 320 - static inline struct mdfld_dsi_connector * 321 - mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder) 322 - { 323 - struct mdfld_dsi_config *config; 324 - 325 - if (!encoder) 326 - return NULL; 327 - 328 - config = mdfld_dsi_encoder_get_config(encoder); 329 - if (!config) 330 - return NULL; 331 - 332 - return config->connector; 333 - } 334 - 335 - static inline void *mdfld_dsi_encoder_get_pkg_sender( 336 - struct mdfld_dsi_encoder *encoder) 337 - { 338 - struct mdfld_dsi_config *dsi_config; 339 - 340 - dsi_config = mdfld_dsi_encoder_get_config(encoder); 341 - if (!dsi_config) 342 - return NULL; 343 - 344 - return mdfld_dsi_get_pkg_sender(dsi_config); 345 - } 346 - 347 - static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder) 348 - { 349 - struct mdfld_dsi_connector *connector; 350 - 351 - if (!encoder) 352 - return -1; 353 - 354 - connector = mdfld_dsi_encoder_get_connector(encoder); 355 - if (!connector) 356 - return -1; 357 - return connector->pipe; 358 - } 359 - 360 - /* Export functions */ 361 - extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev, 362 - u32 gen_fifo_stat_reg, u32 fifo_stat); 363 - extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, 364 - int pipe); 365 - extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, 366 - int level); 367 - extern void mdfld_dsi_output_init(struct drm_device *dev, 368 - int pipe, 369 - const struct panel_funcs *p_vid_funcs); 370 - extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config, 371 - int pipe); 372 - 373 - extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, 374 - u32 *mode, bool hs); 375 - extern int mdfld_dsi_panel_reset(struct drm_device *dev, int pipe); 376 - 377 - #endif /*__MDFLD_DSI_OUTPUT_H__*/
-679
drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
··· 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 - * Jackie Li<yaodong.li@intel.com> 25 - */ 26 - 27 - #include <linux/delay.h> 28 - #include <linux/freezer.h> 29 - 30 - #include <video/mipi_display.h> 31 - 32 - #include "mdfld_dsi_dpi.h" 33 - #include "mdfld_dsi_output.h" 34 - #include "mdfld_dsi_pkg_sender.h" 35 - 36 - #define MDFLD_DSI_READ_MAX_COUNT 5000 37 - 38 - enum { 39 - MDFLD_DSI_PANEL_MODE_SLEEP = 0x1, 40 - }; 41 - 42 - enum { 43 - MDFLD_DSI_PKG_SENDER_FREE = 0x0, 44 - MDFLD_DSI_PKG_SENDER_BUSY = 0x1, 45 - }; 46 - 47 - static const char *const dsi_errors[] = { 48 - "RX SOT Error", 49 - "RX SOT Sync Error", 50 - "RX EOT Sync Error", 51 - "RX Escape Mode Entry Error", 52 - "RX LP TX Sync Error", 53 - "RX HS Receive Timeout Error", 54 - "RX False Control Error", 55 - "RX ECC Single Bit Error", 56 - "RX ECC Multibit Error", 57 - "RX Checksum Error", 58 - "RX DSI Data Type Not Recognised", 59 - "RX DSI VC ID Invalid", 60 - "TX False Control Error", 61 - "TX ECC Single Bit Error", 62 - "TX ECC Multibit Error", 63 - "TX Checksum Error", 64 - "TX DSI Data Type Not Recognised", 65 - "TX DSI VC ID invalid", 66 - "High Contention", 67 - "Low contention", 68 - "DPI FIFO Under run", 69 - "HS TX Timeout", 70 - "LP RX Timeout", 71 - "Turn Around ACK Timeout", 72 - "ACK With No Error", 73 - "RX Invalid TX Length", 74 - "RX Prot Violation", 75 - "HS Generic Write FIFO Full", 76 - "LP Generic Write FIFO Full", 77 - "Generic Read Data Avail", 78 - "Special Packet Sent", 79 - "Tearing Effect", 80 - }; 81 - 82 - static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender, 83 - u32 mask) 84 - { 85 - struct drm_device *dev = sender->dev; 86 - u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg; 87 - int retry = 0xffff; 88 - 89 - while (retry--) { 90 - if ((mask & REG_READ(gen_fifo_stat_reg)) == mask) 91 - return 0; 92 - udelay(100); 93 - } 94 - DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg)); 95 - return -EIO; 96 - } 97 - 98 - static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender) 99 - { 100 - return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(10) | BIT(18) | 101 - BIT(26) | BIT(27) | BIT(28))); 102 - } 103 - 104 - static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender) 105 - { 106 - return wait_for_gen_fifo_empty(sender, (BIT(10) | BIT(26))); 107 - } 108 - 109 - static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender) 110 - { 111 - return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(18))); 112 - } 113 - 114 - static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask) 115 - { 116 - u32 intr_stat_reg = sender->mipi_intr_stat_reg; 117 - struct drm_device *dev = sender->dev; 118 - 119 - dev_dbg(sender->dev->dev, "Handling error 0x%08x\n", mask); 120 - 121 - switch (mask) { 122 - case BIT(0): 123 - case BIT(1): 124 - case BIT(2): 125 - case BIT(3): 126 - case BIT(4): 127 - case BIT(5): 128 - case BIT(6): 129 - case BIT(7): 130 - case BIT(8): 131 - case BIT(9): 132 - case BIT(10): 133 - case BIT(11): 134 - case BIT(12): 135 - case BIT(13): 136 - dev_dbg(sender->dev->dev, "No Action required\n"); 137 - break; 138 - case BIT(14): 139 - /*wait for all fifo empty*/ 140 - /*wait_for_all_fifos_empty(sender)*/ 141 - break; 142 - case BIT(15): 143 - dev_dbg(sender->dev->dev, "No Action required\n"); 144 - break; 145 - case BIT(16): 146 - break; 147 - case BIT(17): 148 - break; 149 - case BIT(18): 150 - case BIT(19): 151 - dev_dbg(sender->dev->dev, "High/Low contention detected\n"); 152 - /*wait for contention recovery time*/ 153 - /*mdelay(10);*/ 154 - /*wait for all fifo empty*/ 155 - if (0) 156 - wait_for_all_fifos_empty(sender); 157 - break; 158 - case BIT(20): 159 - dev_dbg(sender->dev->dev, "No Action required\n"); 160 - break; 161 - case BIT(21): 162 - /*wait for all fifo empty*/ 163 - /*wait_for_all_fifos_empty(sender);*/ 164 - break; 165 - case BIT(22): 166 - break; 167 - case BIT(23): 168 - case BIT(24): 169 - case BIT(25): 170 - case BIT(26): 171 - case BIT(27): 172 - dev_dbg(sender->dev->dev, "HS Gen fifo full\n"); 173 - REG_WRITE(intr_stat_reg, mask); 174 - wait_for_hs_fifos_empty(sender); 175 - break; 176 - case BIT(28): 177 - dev_dbg(sender->dev->dev, "LP Gen fifo full\n"); 178 - REG_WRITE(intr_stat_reg, mask); 179 - wait_for_lp_fifos_empty(sender); 180 - break; 181 - case BIT(29): 182 - case BIT(30): 183 - case BIT(31): 184 - dev_dbg(sender->dev->dev, "No Action required\n"); 185 - break; 186 - } 187 - 188 - if (mask & REG_READ(intr_stat_reg)) 189 - dev_dbg(sender->dev->dev, 190 - "Cannot clean interrupt 0x%08x\n", mask); 191 - return 0; 192 - } 193 - 194 - static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender) 195 - { 196 - struct drm_device *dev = sender->dev; 197 - u32 intr_stat_reg = sender->mipi_intr_stat_reg; 198 - u32 mask; 199 - u32 intr_stat; 200 - int i; 201 - int err = 0; 202 - 203 - intr_stat = REG_READ(intr_stat_reg); 204 - 205 - for (i = 0; i < 32; i++) { 206 - mask = (0x00000001UL) << i; 207 - if (intr_stat & mask) { 208 - dev_dbg(sender->dev->dev, "[DSI]: %s\n", dsi_errors[i]); 209 - err = handle_dsi_error(sender, mask); 210 - if (err) 211 - DRM_ERROR("Cannot handle error\n"); 212 - } 213 - } 214 - return err; 215 - } 216 - 217 - static int send_short_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, 218 - u8 cmd, u8 param, bool hs) 219 - { 220 - struct drm_device *dev = sender->dev; 221 - u32 ctrl_reg; 222 - u32 val; 223 - u8 virtual_channel = 0; 224 - 225 - if (hs) { 226 - ctrl_reg = sender->mipi_hs_gen_ctrl_reg; 227 - 228 - /* FIXME: wait_for_hs_fifos_empty(sender); */ 229 - } else { 230 - ctrl_reg = sender->mipi_lp_gen_ctrl_reg; 231 - 232 - /* FIXME: wait_for_lp_fifos_empty(sender); */ 233 - } 234 - 235 - val = FLD_VAL(param, 23, 16) | FLD_VAL(cmd, 15, 8) | 236 - FLD_VAL(virtual_channel, 7, 6) | FLD_VAL(data_type, 5, 0); 237 - 238 - REG_WRITE(ctrl_reg, val); 239 - 240 - return 0; 241 - } 242 - 243 - static int send_long_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, 244 - u8 *data, int len, bool hs) 245 - { 246 - struct drm_device *dev = sender->dev; 247 - u32 ctrl_reg; 248 - u32 data_reg; 249 - u32 val; 250 - u8 *p; 251 - u8 b1, b2, b3, b4; 252 - u8 virtual_channel = 0; 253 - int i; 254 - 255 - if (hs) { 256 - ctrl_reg = sender->mipi_hs_gen_ctrl_reg; 257 - data_reg = sender->mipi_hs_gen_data_reg; 258 - 259 - /* FIXME: wait_for_hs_fifos_empty(sender); */ 260 - } else { 261 - ctrl_reg = sender->mipi_lp_gen_ctrl_reg; 262 - data_reg = sender->mipi_lp_gen_data_reg; 263 - 264 - /* FIXME: wait_for_lp_fifos_empty(sender); */ 265 - } 266 - 267 - p = data; 268 - for (i = 0; i < len / 4; i++) { 269 - b1 = *p++; 270 - b2 = *p++; 271 - b3 = *p++; 272 - b4 = *p++; 273 - 274 - REG_WRITE(data_reg, b4 << 24 | b3 << 16 | b2 << 8 | b1); 275 - } 276 - 277 - i = len % 4; 278 - if (i) { 279 - b1 = 0; b2 = 0; b3 = 0; 280 - 281 - switch (i) { 282 - case 3: 283 - b1 = *p++; 284 - b2 = *p++; 285 - b3 = *p++; 286 - break; 287 - case 2: 288 - b1 = *p++; 289 - b2 = *p++; 290 - break; 291 - case 1: 292 - b1 = *p++; 293 - break; 294 - } 295 - 296 - REG_WRITE(data_reg, b3 << 16 | b2 << 8 | b1); 297 - } 298 - 299 - val = FLD_VAL(len, 23, 8) | FLD_VAL(virtual_channel, 7, 6) | 300 - FLD_VAL(data_type, 5, 0); 301 - 302 - REG_WRITE(ctrl_reg, val); 303 - 304 - return 0; 305 - } 306 - 307 - static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, u8 data_type, 308 - u8 *data, u16 len) 309 - { 310 - u8 cmd; 311 - 312 - switch (data_type) { 313 - case MIPI_DSI_DCS_SHORT_WRITE: 314 - case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 315 - case MIPI_DSI_DCS_LONG_WRITE: 316 - cmd = *data; 317 - break; 318 - default: 319 - return 0; 320 - } 321 - 322 - /*this prevents other package sending while doing msleep*/ 323 - sender->status = MDFLD_DSI_PKG_SENDER_BUSY; 324 - 325 - /*wait for 120 milliseconds in case exit_sleep_mode just be sent*/ 326 - if (unlikely(cmd == MIPI_DCS_ENTER_SLEEP_MODE)) { 327 - /*TODO: replace it with msleep later*/ 328 - mdelay(120); 329 - } 330 - 331 - if (unlikely(cmd == MIPI_DCS_EXIT_SLEEP_MODE)) { 332 - /*TODO: replace it with msleep later*/ 333 - mdelay(120); 334 - } 335 - return 0; 336 - } 337 - 338 - static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, u8 data_type, 339 - u8 *data, u16 len) 340 - { 341 - u8 cmd; 342 - 343 - switch (data_type) { 344 - case MIPI_DSI_DCS_SHORT_WRITE: 345 - case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 346 - case MIPI_DSI_DCS_LONG_WRITE: 347 - cmd = *data; 348 - break; 349 - default: 350 - return 0; 351 - } 352 - 353 - /*update panel status*/ 354 - if (unlikely(cmd == MIPI_DCS_ENTER_SLEEP_MODE)) { 355 - sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP; 356 - /*TODO: replace it with msleep later*/ 357 - mdelay(120); 358 - } else if (unlikely(cmd == MIPI_DCS_EXIT_SLEEP_MODE)) { 359 - sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP; 360 - /*TODO: replace it with msleep later*/ 361 - mdelay(120); 362 - } else if (unlikely(cmd == MIPI_DCS_SOFT_RESET)) { 363 - /*TODO: replace it with msleep later*/ 364 - mdelay(5); 365 - } 366 - 367 - sender->status = MDFLD_DSI_PKG_SENDER_FREE; 368 - 369 - return 0; 370 - } 371 - 372 - static int send_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, 373 - u8 *data, u16 len, bool hs) 374 - { 375 - int ret; 376 - 377 - /*handle DSI error*/ 378 - ret = dsi_error_handler(sender); 379 - if (ret) { 380 - DRM_ERROR("Error handling failed\n"); 381 - return -EAGAIN; 382 - } 383 - 384 - /* send pkg */ 385 - if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) { 386 - DRM_ERROR("sender is busy\n"); 387 - return -EAGAIN; 388 - } 389 - 390 - ret = send_pkg_prepare(sender, data_type, data, len); 391 - if (ret) { 392 - DRM_ERROR("send_pkg_prepare error\n"); 393 - return ret; 394 - } 395 - 396 - switch (data_type) { 397 - case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: 398 - case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: 399 - case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: 400 - case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: 401 - case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: 402 - case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: 403 - case MIPI_DSI_DCS_SHORT_WRITE: 404 - case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 405 - case MIPI_DSI_DCS_READ: 406 - ret = send_short_pkg(sender, data_type, data[0], data[1], hs); 407 - break; 408 - case MIPI_DSI_GENERIC_LONG_WRITE: 409 - case MIPI_DSI_DCS_LONG_WRITE: 410 - ret = send_long_pkg(sender, data_type, data, len, hs); 411 - break; 412 - } 413 - 414 - send_pkg_done(sender, data_type, data, len); 415 - 416 - /*FIXME: should I query complete and fifo empty here?*/ 417 - 418 - return ret; 419 - } 420 - 421 - int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, 422 - u32 len, bool hs) 423 - { 424 - unsigned long flags; 425 - 426 - if (!sender || !data || !len) { 427 - DRM_ERROR("Invalid parameters\n"); 428 - return -EINVAL; 429 - } 430 - 431 - spin_lock_irqsave(&sender->lock, flags); 432 - send_pkg(sender, MIPI_DSI_DCS_LONG_WRITE, data, len, hs); 433 - spin_unlock_irqrestore(&sender->lock, flags); 434 - 435 - return 0; 436 - } 437 - 438 - int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd, 439 - u8 param, u8 param_num, bool hs) 440 - { 441 - u8 data[2]; 442 - unsigned long flags; 443 - u8 data_type; 444 - 445 - if (!sender) { 446 - DRM_ERROR("Invalid parameter\n"); 447 - return -EINVAL; 448 - } 449 - 450 - data[0] = cmd; 451 - 452 - if (param_num) { 453 - data_type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; 454 - data[1] = param; 455 - } else { 456 - data_type = MIPI_DSI_DCS_SHORT_WRITE; 457 - data[1] = 0; 458 - } 459 - 460 - spin_lock_irqsave(&sender->lock, flags); 461 - send_pkg(sender, data_type, data, sizeof(data), hs); 462 - spin_unlock_irqrestore(&sender->lock, flags); 463 - 464 - return 0; 465 - } 466 - 467 - int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0, 468 - u8 param1, u8 param_num, bool hs) 469 - { 470 - u8 data[2]; 471 - unsigned long flags; 472 - u8 data_type; 473 - 474 - if (!sender || param_num > 2) { 475 - DRM_ERROR("Invalid parameter\n"); 476 - return -EINVAL; 477 - } 478 - 479 - switch (param_num) { 480 - case 0: 481 - data_type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; 482 - data[0] = 0; 483 - data[1] = 0; 484 - break; 485 - case 1: 486 - data_type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; 487 - data[0] = param0; 488 - data[1] = 0; 489 - break; 490 - case 2: 491 - data_type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; 492 - data[0] = param0; 493 - data[1] = param1; 494 - break; 495 - } 496 - 497 - spin_lock_irqsave(&sender->lock, flags); 498 - send_pkg(sender, data_type, data, sizeof(data), hs); 499 - spin_unlock_irqrestore(&sender->lock, flags); 500 - 501 - return 0; 502 - } 503 - 504 - int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, 505 - u32 len, bool hs) 506 - { 507 - unsigned long flags; 508 - 509 - if (!sender || !data || !len) { 510 - DRM_ERROR("Invalid parameters\n"); 511 - return -EINVAL; 512 - } 513 - 514 - spin_lock_irqsave(&sender->lock, flags); 515 - send_pkg(sender, MIPI_DSI_GENERIC_LONG_WRITE, data, len, hs); 516 - spin_unlock_irqrestore(&sender->lock, flags); 517 - 518 - return 0; 519 - } 520 - 521 - static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type, 522 - u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs) 523 - { 524 - unsigned long flags; 525 - struct drm_device *dev; 526 - int i; 527 - u32 gen_data_reg; 528 - int retry = MDFLD_DSI_READ_MAX_COUNT; 529 - 530 - if (!sender || !data_out || !len_out) { 531 - DRM_ERROR("Invalid parameters\n"); 532 - return -EINVAL; 533 - } 534 - 535 - dev = sender->dev; 536 - 537 - /** 538 - * do reading. 539 - * 0) send out generic read request 540 - * 1) polling read data avail interrupt 541 - * 2) read data 542 - */ 543 - spin_lock_irqsave(&sender->lock, flags); 544 - 545 - REG_WRITE(sender->mipi_intr_stat_reg, BIT(29)); 546 - 547 - if ((REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) 548 - DRM_ERROR("Can NOT clean read data valid interrupt\n"); 549 - 550 - /*send out read request*/ 551 - send_pkg(sender, data_type, data, len, hs); 552 - 553 - /*polling read data avail interrupt*/ 554 - while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) { 555 - udelay(100); 556 - retry--; 557 - } 558 - 559 - if (!retry) { 560 - spin_unlock_irqrestore(&sender->lock, flags); 561 - return -ETIMEDOUT; 562 - } 563 - 564 - REG_WRITE(sender->mipi_intr_stat_reg, BIT(29)); 565 - 566 - /*read data*/ 567 - if (hs) 568 - gen_data_reg = sender->mipi_hs_gen_data_reg; 569 - else 570 - gen_data_reg = sender->mipi_lp_gen_data_reg; 571 - 572 - for (i = 0; i < len_out; i++) 573 - *(data_out + i) = REG_READ(gen_data_reg); 574 - 575 - spin_unlock_irqrestore(&sender->lock, flags); 576 - 577 - return 0; 578 - } 579 - 580 - int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd, 581 - u32 *data, u16 len, bool hs) 582 - { 583 - if (!sender || !data || !len) { 584 - DRM_ERROR("Invalid parameters\n"); 585 - return -EINVAL; 586 - } 587 - 588 - return __read_panel_data(sender, MIPI_DSI_DCS_READ, &cmd, 1, 589 - data, len, hs); 590 - } 591 - 592 - int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, 593 - int pipe) 594 - { 595 - struct mdfld_dsi_pkg_sender *pkg_sender; 596 - struct mdfld_dsi_config *dsi_config = 597 - mdfld_dsi_get_config(dsi_connector); 598 - struct drm_device *dev = dsi_config->dev; 599 - struct drm_psb_private *dev_priv = dev->dev_private; 600 - const struct psb_offset *map = &dev_priv->regmap[pipe]; 601 - u32 mipi_val = 0; 602 - 603 - if (!dsi_connector) { 604 - DRM_ERROR("Invalid parameter\n"); 605 - return -EINVAL; 606 - } 607 - 608 - pkg_sender = dsi_connector->pkg_sender; 609 - 610 - if (!pkg_sender || IS_ERR(pkg_sender)) { 611 - pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender), 612 - GFP_KERNEL); 613 - if (!pkg_sender) { 614 - DRM_ERROR("Create DSI pkg sender failed\n"); 615 - return -ENOMEM; 616 - } 617 - dsi_connector->pkg_sender = (void *)pkg_sender; 618 - } 619 - 620 - pkg_sender->dev = dev; 621 - pkg_sender->dsi_connector = dsi_connector; 622 - pkg_sender->pipe = pipe; 623 - pkg_sender->pkg_num = 0; 624 - pkg_sender->panel_mode = 0; 625 - pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE; 626 - 627 - /*init regs*/ 628 - /* FIXME: should just copy the regmap ptr ? */ 629 - pkg_sender->dpll_reg = map->dpll; 630 - pkg_sender->dspcntr_reg = map->cntr; 631 - pkg_sender->pipeconf_reg = map->conf; 632 - pkg_sender->dsplinoff_reg = map->linoff; 633 - pkg_sender->dspsurf_reg = map->surf; 634 - pkg_sender->pipestat_reg = map->status; 635 - 636 - pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe); 637 - pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe); 638 - pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe); 639 - pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe); 640 - pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe); 641 - pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); 642 - pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe); 643 - pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe); 644 - pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe); 645 - pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe); 646 - 647 - /*init lock*/ 648 - spin_lock_init(&pkg_sender->lock); 649 - 650 - if (mdfld_get_panel_type(dev, pipe) != TC35876X) { 651 - /** 652 - * For video mode, don't enable DPI timing output here, 653 - * will init the DPI timing output during mode setting. 654 - */ 655 - mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; 656 - 657 - if (pipe == 0) 658 - mipi_val |= 0x2; 659 - 660 - REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val); 661 - REG_READ(MIPI_PORT_CONTROL(pipe)); 662 - 663 - /* do dsi controller init */ 664 - mdfld_dsi_controller_init(dsi_config, pipe); 665 - } 666 - 667 - return 0; 668 - } 669 - 670 - void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender) 671 - { 672 - if (!sender || IS_ERR(sender)) 673 - return; 674 - 675 - /*free*/ 676 - kfree(sender); 677 - } 678 - 679 -
-80
drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h
··· 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 - * Jackie Li<yaodong.li@intel.com> 25 - */ 26 - #ifndef __MDFLD_DSI_PKG_SENDER_H__ 27 - #define __MDFLD_DSI_PKG_SENDER_H__ 28 - 29 - #include <linux/kthread.h> 30 - 31 - #define MDFLD_MAX_DCS_PARAM 8 32 - 33 - struct mdfld_dsi_pkg_sender { 34 - struct drm_device *dev; 35 - struct mdfld_dsi_connector *dsi_connector; 36 - u32 status; 37 - u32 panel_mode; 38 - 39 - int pipe; 40 - 41 - spinlock_t lock; 42 - 43 - u32 pkg_num; 44 - 45 - /* Registers */ 46 - u32 dpll_reg; 47 - u32 dspcntr_reg; 48 - u32 pipeconf_reg; 49 - u32 pipestat_reg; 50 - u32 dsplinoff_reg; 51 - u32 dspsurf_reg; 52 - 53 - u32 mipi_intr_stat_reg; 54 - u32 mipi_lp_gen_data_reg; 55 - u32 mipi_hs_gen_data_reg; 56 - u32 mipi_lp_gen_ctrl_reg; 57 - u32 mipi_hs_gen_ctrl_reg; 58 - u32 mipi_gen_fifo_stat_reg; 59 - u32 mipi_data_addr_reg; 60 - u32 mipi_data_len_reg; 61 - u32 mipi_cmd_addr_reg; 62 - u32 mipi_cmd_len_reg; 63 - }; 64 - 65 - extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, 66 - int pipe); 67 - extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender); 68 - int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd, 69 - u8 param, u8 param_num, bool hs); 70 - int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, 71 - u32 len, bool hs); 72 - int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0, 73 - u8 param1, u8 param_num, bool hs); 74 - int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, 75 - u32 len, bool hs); 76 - /* Read interfaces */ 77 - int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd, 78 - u32 *data, u16 len, bool hs); 79 - 80 - #endif
-966
drivers/gpu/drm/gma500/mdfld_intel_display.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright © 2006-2007 Intel Corporation 4 - * 5 - * Authors: 6 - * Eric Anholt <eric@anholt.net> 7 - */ 8 - 9 - #include <linux/delay.h> 10 - #include <linux/i2c.h> 11 - #include <linux/pm_runtime.h> 12 - 13 - #include <drm/drm_crtc.h> 14 - #include <drm/drm_fourcc.h> 15 - 16 - #include "framebuffer.h" 17 - #include "gma_display.h" 18 - #include "mdfld_dsi_output.h" 19 - #include "mdfld_output.h" 20 - #include "psb_intel_reg.h" 21 - 22 - /* Hardcoded currently */ 23 - static int ksel = KSEL_CRYSTAL_19; 24 - 25 - struct psb_intel_range_t { 26 - int min, max; 27 - }; 28 - 29 - struct mrst_limit_t { 30 - struct psb_intel_range_t dot, m, p1; 31 - }; 32 - 33 - struct mrst_clock_t { 34 - /* derived values */ 35 - int dot; 36 - int m; 37 - int p1; 38 - }; 39 - 40 - #define COUNT_MAX 0x10000000 41 - 42 - void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe) 43 - { 44 - struct drm_psb_private *dev_priv = dev->dev_private; 45 - const struct psb_offset *map = &dev_priv->regmap[pipe]; 46 - int count, temp; 47 - 48 - switch (pipe) { 49 - case 0: 50 - case 1: 51 - case 2: 52 - break; 53 - default: 54 - DRM_ERROR("Illegal Pipe Number.\n"); 55 - return; 56 - } 57 - 58 - /* FIXME JLIU7_PO */ 59 - gma_wait_for_vblank(dev); 60 - return; 61 - 62 - /* Wait for for the pipe disable to take effect. */ 63 - for (count = 0; count < COUNT_MAX; count++) { 64 - temp = REG_READ(map->conf); 65 - if ((temp & PIPEACONF_PIPE_STATE) == 0) 66 - break; 67 - } 68 - } 69 - 70 - void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) 71 - { 72 - struct drm_psb_private *dev_priv = dev->dev_private; 73 - const struct psb_offset *map = &dev_priv->regmap[pipe]; 74 - int count, temp; 75 - 76 - switch (pipe) { 77 - case 0: 78 - case 1: 79 - case 2: 80 - break; 81 - default: 82 - DRM_ERROR("Illegal Pipe Number.\n"); 83 - return; 84 - } 85 - 86 - /* FIXME JLIU7_PO */ 87 - gma_wait_for_vblank(dev); 88 - return; 89 - 90 - /* Wait for for the pipe enable to take effect. */ 91 - for (count = 0; count < COUNT_MAX; count++) { 92 - temp = REG_READ(map->conf); 93 - if (temp & PIPEACONF_PIPE_STATE) 94 - break; 95 - } 96 - } 97 - 98 - /* 99 - * Return the pipe currently connected to the panel fitter, 100 - * or -1 if the panel fitter is not present or not in use 101 - */ 102 - static int psb_intel_panel_fitter_pipe(struct drm_device *dev) 103 - { 104 - u32 pfit_control; 105 - 106 - pfit_control = REG_READ(PFIT_CONTROL); 107 - 108 - /* See if the panel fitter is in use */ 109 - if ((pfit_control & PFIT_ENABLE) == 0) 110 - return -1; 111 - 112 - /* 965 can place panel fitter on either pipe */ 113 - return (pfit_control >> 29) & 0x3; 114 - } 115 - 116 - static int check_fb(struct drm_framebuffer *fb) 117 - { 118 - if (!fb) 119 - return 0; 120 - 121 - switch (fb->format->cpp[0] * 8) { 122 - case 8: 123 - case 16: 124 - case 24: 125 - case 32: 126 - return 0; 127 - default: 128 - DRM_ERROR("Unknown color depth\n"); 129 - return -EINVAL; 130 - } 131 - } 132 - 133 - static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, 134 - struct drm_framebuffer *old_fb) 135 - { 136 - struct drm_device *dev = crtc->dev; 137 - struct drm_psb_private *dev_priv = dev->dev_private; 138 - struct drm_framebuffer *fb = crtc->primary->fb; 139 - struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 140 - int pipe = gma_crtc->pipe; 141 - const struct psb_offset *map = &dev_priv->regmap[pipe]; 142 - unsigned long start, offset; 143 - u32 dspcntr; 144 - int ret; 145 - 146 - dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe); 147 - 148 - /* no fb bound */ 149 - if (!fb) { 150 - dev_dbg(dev->dev, "No FB bound\n"); 151 - return 0; 152 - } 153 - 154 - ret = check_fb(fb); 155 - if (ret) 156 - return ret; 157 - 158 - if (pipe > 2) { 159 - DRM_ERROR("Illegal Pipe Number.\n"); 160 - return -EINVAL; 161 - } 162 - 163 - if (!gma_power_begin(dev, true)) 164 - return 0; 165 - 166 - start = to_gtt_range(fb->obj[0])->offset; 167 - offset = y * fb->pitches[0] + x * fb->format->cpp[0]; 168 - 169 - REG_WRITE(map->stride, fb->pitches[0]); 170 - dspcntr = REG_READ(map->cntr); 171 - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 172 - 173 - switch (fb->format->cpp[0] * 8) { 174 - case 8: 175 - dspcntr |= DISPPLANE_8BPP; 176 - break; 177 - case 16: 178 - if (fb->format->depth == 15) 179 - dspcntr |= DISPPLANE_15_16BPP; 180 - else 181 - dspcntr |= DISPPLANE_16BPP; 182 - break; 183 - case 24: 184 - case 32: 185 - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; 186 - break; 187 - } 188 - REG_WRITE(map->cntr, dspcntr); 189 - 190 - dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n", 191 - start, offset, x, y); 192 - REG_WRITE(map->linoff, offset); 193 - REG_READ(map->linoff); 194 - REG_WRITE(map->surf, start); 195 - REG_READ(map->surf); 196 - 197 - gma_power_end(dev); 198 - 199 - return 0; 200 - } 201 - 202 - /* 203 - * Disable the pipe, plane and pll. 204 - * 205 - */ 206 - void mdfld_disable_crtc(struct drm_device *dev, int pipe) 207 - { 208 - struct drm_psb_private *dev_priv = dev->dev_private; 209 - const struct psb_offset *map = &dev_priv->regmap[pipe]; 210 - u32 temp; 211 - 212 - dev_dbg(dev->dev, "pipe = %d\n", pipe); 213 - 214 - 215 - if (pipe != 1) 216 - mdfld_dsi_gen_fifo_ready(dev, MIPI_GEN_FIFO_STAT_REG(pipe), 217 - HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); 218 - 219 - /* Disable display plane */ 220 - temp = REG_READ(map->cntr); 221 - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 222 - REG_WRITE(map->cntr, 223 - temp & ~DISPLAY_PLANE_ENABLE); 224 - /* Flush the plane changes */ 225 - REG_WRITE(map->base, REG_READ(map->base)); 226 - REG_READ(map->base); 227 - } 228 - 229 - /* FIXME_JLIU7 MDFLD_PO revisit */ 230 - 231 - /* Next, disable display pipes */ 232 - temp = REG_READ(map->conf); 233 - if ((temp & PIPEACONF_ENABLE) != 0) { 234 - temp &= ~PIPEACONF_ENABLE; 235 - temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; 236 - REG_WRITE(map->conf, temp); 237 - REG_READ(map->conf); 238 - 239 - /* Wait for for the pipe disable to take effect. */ 240 - mdfldWaitForPipeDisable(dev, pipe); 241 - } 242 - 243 - temp = REG_READ(map->dpll); 244 - if (temp & DPLL_VCO_ENABLE) { 245 - if ((pipe != 1 && 246 - !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) 247 - & PIPEACONF_ENABLE)) || pipe == 1) { 248 - temp &= ~(DPLL_VCO_ENABLE); 249 - REG_WRITE(map->dpll, temp); 250 - REG_READ(map->dpll); 251 - /* Wait for the clocks to turn off. */ 252 - /* FIXME_MDFLD PO may need more delay */ 253 - udelay(500); 254 - 255 - if (!(temp & MDFLD_PWR_GATE_EN)) { 256 - /* gating power of DPLL */ 257 - REG_WRITE(map->dpll, temp | MDFLD_PWR_GATE_EN); 258 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 259 - udelay(5000); 260 - } 261 - } 262 - } 263 - 264 - } 265 - 266 - /* 267 - * Sets the power management mode of the pipe and plane. 268 - * 269 - * This code should probably grow support for turning the cursor off and back 270 - * on appropriately at the same time as we're turning the pipe off/on. 271 - */ 272 - static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) 273 - { 274 - struct drm_device *dev = crtc->dev; 275 - struct drm_psb_private *dev_priv = dev->dev_private; 276 - struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 277 - int pipe = gma_crtc->pipe; 278 - const struct psb_offset *map = &dev_priv->regmap[pipe]; 279 - u32 pipeconf = dev_priv->pipeconf[pipe]; 280 - u32 temp; 281 - int timeout = 0; 282 - 283 - dev_dbg(dev->dev, "mode = %d, pipe = %d\n", mode, pipe); 284 - 285 - /* Note: Old code uses pipe a stat for pipe b but that appears 286 - to be a bug */ 287 - 288 - if (!gma_power_begin(dev, true)) 289 - return; 290 - 291 - /* XXX: When our outputs are all unaware of DPMS modes other than off 292 - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. 293 - */ 294 - switch (mode) { 295 - case DRM_MODE_DPMS_ON: 296 - case DRM_MODE_DPMS_STANDBY: 297 - case DRM_MODE_DPMS_SUSPEND: 298 - /* Enable the DPLL */ 299 - temp = REG_READ(map->dpll); 300 - 301 - if ((temp & DPLL_VCO_ENABLE) == 0) { 302 - /* When ungating power of DPLL, needs to wait 0.5us 303 - before enable the VCO */ 304 - if (temp & MDFLD_PWR_GATE_EN) { 305 - temp &= ~MDFLD_PWR_GATE_EN; 306 - REG_WRITE(map->dpll, temp); 307 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 308 - udelay(500); 309 - } 310 - 311 - REG_WRITE(map->dpll, temp); 312 - REG_READ(map->dpll); 313 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 314 - udelay(500); 315 - 316 - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); 317 - REG_READ(map->dpll); 318 - 319 - /** 320 - * wait for DSI PLL to lock 321 - * NOTE: only need to poll status of pipe 0 and pipe 1, 322 - * since both MIPI pipes share the same PLL. 323 - */ 324 - while ((pipe != 2) && (timeout < 20000) && 325 - !(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) { 326 - udelay(150); 327 - timeout++; 328 - } 329 - } 330 - 331 - /* Enable the plane */ 332 - temp = REG_READ(map->cntr); 333 - if ((temp & DISPLAY_PLANE_ENABLE) == 0) { 334 - REG_WRITE(map->cntr, 335 - temp | DISPLAY_PLANE_ENABLE); 336 - /* Flush the plane changes */ 337 - REG_WRITE(map->base, REG_READ(map->base)); 338 - } 339 - 340 - /* Enable the pipe */ 341 - temp = REG_READ(map->conf); 342 - if ((temp & PIPEACONF_ENABLE) == 0) { 343 - REG_WRITE(map->conf, pipeconf); 344 - 345 - /* Wait for for the pipe enable to take effect. */ 346 - mdfldWaitForPipeEnable(dev, pipe); 347 - } 348 - 349 - /*workaround for sighting 3741701 Random X blank display*/ 350 - /*perform w/a in video mode only on pipe A or C*/ 351 - if (pipe == 0 || pipe == 2) { 352 - REG_WRITE(map->status, REG_READ(map->status)); 353 - msleep(100); 354 - if (PIPE_VBLANK_STATUS & REG_READ(map->status)) 355 - dev_dbg(dev->dev, "OK"); 356 - else { 357 - dev_dbg(dev->dev, "STUCK!!!!"); 358 - /*shutdown controller*/ 359 - temp = REG_READ(map->cntr); 360 - REG_WRITE(map->cntr, 361 - temp & ~DISPLAY_PLANE_ENABLE); 362 - REG_WRITE(map->base, REG_READ(map->base)); 363 - /*mdfld_dsi_dpi_shut_down(dev, pipe);*/ 364 - REG_WRITE(0xb048, 1); 365 - msleep(100); 366 - temp = REG_READ(map->conf); 367 - temp &= ~PIPEACONF_ENABLE; 368 - REG_WRITE(map->conf, temp); 369 - msleep(100); /*wait for pipe disable*/ 370 - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0); 371 - msleep(100); 372 - REG_WRITE(0xb004, REG_READ(0xb004)); 373 - /* try to bring the controller back up again*/ 374 - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 1); 375 - temp = REG_READ(map->cntr); 376 - REG_WRITE(map->cntr, 377 - temp | DISPLAY_PLANE_ENABLE); 378 - REG_WRITE(map->base, REG_READ(map->base)); 379 - /*mdfld_dsi_dpi_turn_on(dev, pipe);*/ 380 - REG_WRITE(0xb048, 2); 381 - msleep(100); 382 - temp = REG_READ(map->conf); 383 - temp |= PIPEACONF_ENABLE; 384 - REG_WRITE(map->conf, temp); 385 - } 386 - } 387 - 388 - gma_crtc_load_lut(crtc); 389 - 390 - /* Give the overlay scaler a chance to enable 391 - if it's on this pipe */ 392 - /* psb_intel_crtc_dpms_video(crtc, true); TODO */ 393 - 394 - break; 395 - case DRM_MODE_DPMS_OFF: 396 - /* Give the overlay scaler a chance to disable 397 - * if it's on this pipe */ 398 - /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ 399 - if (pipe != 1) 400 - mdfld_dsi_gen_fifo_ready(dev, 401 - MIPI_GEN_FIFO_STAT_REG(pipe), 402 - HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); 403 - 404 - /* Disable the VGA plane that we never use */ 405 - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 406 - 407 - /* Disable display plane */ 408 - temp = REG_READ(map->cntr); 409 - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 410 - REG_WRITE(map->cntr, 411 - temp & ~DISPLAY_PLANE_ENABLE); 412 - /* Flush the plane changes */ 413 - REG_WRITE(map->base, REG_READ(map->base)); 414 - REG_READ(map->base); 415 - } 416 - 417 - /* Next, disable display pipes */ 418 - temp = REG_READ(map->conf); 419 - if ((temp & PIPEACONF_ENABLE) != 0) { 420 - temp &= ~PIPEACONF_ENABLE; 421 - temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; 422 - REG_WRITE(map->conf, temp); 423 - REG_READ(map->conf); 424 - 425 - /* Wait for for the pipe disable to take effect. */ 426 - mdfldWaitForPipeDisable(dev, pipe); 427 - } 428 - 429 - temp = REG_READ(map->dpll); 430 - if (temp & DPLL_VCO_ENABLE) { 431 - if ((pipe != 1 && !((REG_READ(PIPEACONF) 432 - | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE)) 433 - || pipe == 1) { 434 - temp &= ~(DPLL_VCO_ENABLE); 435 - REG_WRITE(map->dpll, temp); 436 - REG_READ(map->dpll); 437 - /* Wait for the clocks to turn off. */ 438 - /* FIXME_MDFLD PO may need more delay */ 439 - udelay(500); 440 - } 441 - } 442 - break; 443 - } 444 - gma_power_end(dev); 445 - } 446 - 447 - 448 - #define MDFLD_LIMT_DPLL_19 0 449 - #define MDFLD_LIMT_DPLL_25 1 450 - #define MDFLD_LIMT_DPLL_83 2 451 - #define MDFLD_LIMT_DPLL_100 3 452 - #define MDFLD_LIMT_DSIPLL_19 4 453 - #define MDFLD_LIMT_DSIPLL_25 5 454 - #define MDFLD_LIMT_DSIPLL_83 6 455 - #define MDFLD_LIMT_DSIPLL_100 7 456 - 457 - #define MDFLD_DOT_MIN 19750 458 - #define MDFLD_DOT_MAX 120000 459 - #define MDFLD_DPLL_M_MIN_19 113 460 - #define MDFLD_DPLL_M_MAX_19 155 461 - #define MDFLD_DPLL_P1_MIN_19 2 462 - #define MDFLD_DPLL_P1_MAX_19 10 463 - #define MDFLD_DPLL_M_MIN_25 101 464 - #define MDFLD_DPLL_M_MAX_25 130 465 - #define MDFLD_DPLL_P1_MIN_25 2 466 - #define MDFLD_DPLL_P1_MAX_25 10 467 - #define MDFLD_DPLL_M_MIN_83 64 468 - #define MDFLD_DPLL_M_MAX_83 64 469 - #define MDFLD_DPLL_P1_MIN_83 2 470 - #define MDFLD_DPLL_P1_MAX_83 2 471 - #define MDFLD_DPLL_M_MIN_100 64 472 - #define MDFLD_DPLL_M_MAX_100 64 473 - #define MDFLD_DPLL_P1_MIN_100 2 474 - #define MDFLD_DPLL_P1_MAX_100 2 475 - #define MDFLD_DSIPLL_M_MIN_19 131 476 - #define MDFLD_DSIPLL_M_MAX_19 175 477 - #define MDFLD_DSIPLL_P1_MIN_19 3 478 - #define MDFLD_DSIPLL_P1_MAX_19 8 479 - #define MDFLD_DSIPLL_M_MIN_25 97 480 - #define MDFLD_DSIPLL_M_MAX_25 140 481 - #define MDFLD_DSIPLL_P1_MIN_25 3 482 - #define MDFLD_DSIPLL_P1_MAX_25 9 483 - #define MDFLD_DSIPLL_M_MIN_83 33 484 - #define MDFLD_DSIPLL_M_MAX_83 92 485 - #define MDFLD_DSIPLL_P1_MIN_83 2 486 - #define MDFLD_DSIPLL_P1_MAX_83 3 487 - #define MDFLD_DSIPLL_M_MIN_100 97 488 - #define MDFLD_DSIPLL_M_MAX_100 140 489 - #define MDFLD_DSIPLL_P1_MIN_100 3 490 - #define MDFLD_DSIPLL_P1_MAX_100 9 491 - 492 - static const struct mrst_limit_t mdfld_limits[] = { 493 - { /* MDFLD_LIMT_DPLL_19 */ 494 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 495 - .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19}, 496 - .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19}, 497 - }, 498 - { /* MDFLD_LIMT_DPLL_25 */ 499 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 500 - .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25}, 501 - .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25}, 502 - }, 503 - { /* MDFLD_LIMT_DPLL_83 */ 504 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 505 - .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83}, 506 - .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83}, 507 - }, 508 - { /* MDFLD_LIMT_DPLL_100 */ 509 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 510 - .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100}, 511 - .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100}, 512 - }, 513 - { /* MDFLD_LIMT_DSIPLL_19 */ 514 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 515 - .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19}, 516 - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19}, 517 - }, 518 - { /* MDFLD_LIMT_DSIPLL_25 */ 519 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 520 - .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25}, 521 - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25}, 522 - }, 523 - { /* MDFLD_LIMT_DSIPLL_83 */ 524 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 525 - .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83}, 526 - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83}, 527 - }, 528 - { /* MDFLD_LIMT_DSIPLL_100 */ 529 - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 530 - .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100}, 531 - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100}, 532 - }, 533 - }; 534 - 535 - #define MDFLD_M_MIN 21 536 - #define MDFLD_M_MAX 180 537 - static const u32 mdfld_m_converts[] = { 538 - /* M configuration table from 9-bit LFSR table */ 539 - 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */ 540 - 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */ 541 - 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */ 542 - 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */ 543 - 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */ 544 - 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */ 545 - 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */ 546 - 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */ 547 - 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */ 548 - 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */ 549 - 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */ 550 - 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */ 551 - 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */ 552 - 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */ 553 - 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */ 554 - 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */ 555 - }; 556 - 557 - static const struct mrst_limit_t *mdfld_limit(struct drm_crtc *crtc) 558 - { 559 - const struct mrst_limit_t *limit = NULL; 560 - struct drm_device *dev = crtc->dev; 561 - struct drm_psb_private *dev_priv = dev->dev_private; 562 - 563 - if (gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI) 564 - || gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) { 565 - if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) 566 - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19]; 567 - else if (ksel == KSEL_BYPASS_25) 568 - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25]; 569 - else if ((ksel == KSEL_BYPASS_83_100) && 570 - (dev_priv->core_freq == 166)) 571 - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83]; 572 - else if ((ksel == KSEL_BYPASS_83_100) && 573 - (dev_priv->core_freq == 100 || 574 - dev_priv->core_freq == 200)) 575 - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100]; 576 - } else if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { 577 - if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) 578 - limit = &mdfld_limits[MDFLD_LIMT_DPLL_19]; 579 - else if (ksel == KSEL_BYPASS_25) 580 - limit = &mdfld_limits[MDFLD_LIMT_DPLL_25]; 581 - else if ((ksel == KSEL_BYPASS_83_100) && 582 - (dev_priv->core_freq == 166)) 583 - limit = &mdfld_limits[MDFLD_LIMT_DPLL_83]; 584 - else if ((ksel == KSEL_BYPASS_83_100) && 585 - (dev_priv->core_freq == 100 || 586 - dev_priv->core_freq == 200)) 587 - limit = &mdfld_limits[MDFLD_LIMT_DPLL_100]; 588 - } else { 589 - limit = NULL; 590 - dev_dbg(dev->dev, "mdfld_limit Wrong display type.\n"); 591 - } 592 - 593 - return limit; 594 - } 595 - 596 - /** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ 597 - static void mdfld_clock(int refclk, struct mrst_clock_t *clock) 598 - { 599 - clock->dot = (refclk * clock->m) / clock->p1; 600 - } 601 - 602 - /* 603 - * Returns a set of divisors for the desired target clock with the given refclk, 604 - * or FALSE. Divisor values are the actual divisors for 605 - */ 606 - static bool 607 - mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk, 608 - struct mrst_clock_t *best_clock) 609 - { 610 - struct mrst_clock_t clock; 611 - const struct mrst_limit_t *limit = mdfld_limit(crtc); 612 - int err = target; 613 - 614 - memset(best_clock, 0, sizeof(*best_clock)); 615 - 616 - for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { 617 - for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; 618 - clock.p1++) { 619 - int this_err; 620 - 621 - mdfld_clock(refclk, &clock); 622 - 623 - this_err = abs(clock.dot - target); 624 - if (this_err < err) { 625 - *best_clock = clock; 626 - err = this_err; 627 - } 628 - } 629 - } 630 - return err != target; 631 - } 632 - 633 - static int mdfld_crtc_mode_set(struct drm_crtc *crtc, 634 - struct drm_display_mode *mode, 635 - struct drm_display_mode *adjusted_mode, 636 - int x, int y, 637 - struct drm_framebuffer *old_fb) 638 - { 639 - struct drm_device *dev = crtc->dev; 640 - struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 641 - struct drm_psb_private *dev_priv = dev->dev_private; 642 - int pipe = gma_crtc->pipe; 643 - const struct psb_offset *map = &dev_priv->regmap[pipe]; 644 - int refclk = 0; 645 - int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, 646 - clk_tmp = 0; 647 - struct mrst_clock_t clock; 648 - bool ok; 649 - u32 dpll = 0, fp = 0; 650 - bool is_mipi = false, is_mipi2 = false, is_hdmi = false; 651 - struct drm_mode_config *mode_config = &dev->mode_config; 652 - struct gma_encoder *gma_encoder = NULL; 653 - uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; 654 - struct drm_encoder *encoder; 655 - struct drm_connector *connector; 656 - int timeout = 0; 657 - int ret; 658 - 659 - dev_dbg(dev->dev, "pipe = 0x%x\n", pipe); 660 - 661 - ret = check_fb(crtc->primary->fb); 662 - if (ret) 663 - return ret; 664 - 665 - dev_dbg(dev->dev, "adjusted_hdisplay = %d\n", 666 - adjusted_mode->hdisplay); 667 - dev_dbg(dev->dev, "adjusted_vdisplay = %d\n", 668 - adjusted_mode->vdisplay); 669 - dev_dbg(dev->dev, "adjusted_hsync_start = %d\n", 670 - adjusted_mode->hsync_start); 671 - dev_dbg(dev->dev, "adjusted_hsync_end = %d\n", 672 - adjusted_mode->hsync_end); 673 - dev_dbg(dev->dev, "adjusted_htotal = %d\n", 674 - adjusted_mode->htotal); 675 - dev_dbg(dev->dev, "adjusted_vsync_start = %d\n", 676 - adjusted_mode->vsync_start); 677 - dev_dbg(dev->dev, "adjusted_vsync_end = %d\n", 678 - adjusted_mode->vsync_end); 679 - dev_dbg(dev->dev, "adjusted_vtotal = %d\n", 680 - adjusted_mode->vtotal); 681 - dev_dbg(dev->dev, "adjusted_clock = %d\n", 682 - adjusted_mode->clock); 683 - dev_dbg(dev->dev, "hdisplay = %d\n", 684 - mode->hdisplay); 685 - dev_dbg(dev->dev, "vdisplay = %d\n", 686 - mode->vdisplay); 687 - 688 - if (!gma_power_begin(dev, true)) 689 - return 0; 690 - 691 - memcpy(&gma_crtc->saved_mode, mode, 692 - sizeof(struct drm_display_mode)); 693 - memcpy(&gma_crtc->saved_adjusted_mode, adjusted_mode, 694 - sizeof(struct drm_display_mode)); 695 - 696 - list_for_each_entry(connector, &mode_config->connector_list, head) { 697 - encoder = connector->encoder; 698 - if (!encoder) 699 - continue; 700 - 701 - if (encoder->crtc != crtc) 702 - continue; 703 - 704 - gma_encoder = gma_attached_encoder(connector); 705 - 706 - switch (gma_encoder->type) { 707 - case INTEL_OUTPUT_MIPI: 708 - is_mipi = true; 709 - break; 710 - case INTEL_OUTPUT_MIPI2: 711 - is_mipi2 = true; 712 - break; 713 - case INTEL_OUTPUT_HDMI: 714 - is_hdmi = true; 715 - break; 716 - } 717 - } 718 - 719 - /* Disable the VGA plane that we never use */ 720 - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 721 - 722 - /* Disable the panel fitter if it was on our pipe */ 723 - if (psb_intel_panel_fitter_pipe(dev) == pipe) 724 - REG_WRITE(PFIT_CONTROL, 0); 725 - 726 - /* pipesrc and dspsize control the size that is scaled from, 727 - * which should always be the user's requested size. 728 - */ 729 - if (pipe == 1) { 730 - /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 731 - * (PYR) or 480x854 (TMD), set the sprite width/height and 732 - * souce image size registers with the adjusted mode for 733 - * pipe B. 734 - */ 735 - 736 - /* 737 - * The defined sprite rectangle must always be completely 738 - * contained within the displayable area of the screen image 739 - * (frame buffer). 740 - */ 741 - REG_WRITE(map->size, ((min(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16) 742 - | (min(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1)); 743 - /* Set the CRTC with encoder mode. */ 744 - REG_WRITE(map->src, ((mode->crtc_hdisplay - 1) << 16) 745 - | (mode->crtc_vdisplay - 1)); 746 - } else { 747 - REG_WRITE(map->size, 748 - ((mode->crtc_vdisplay - 1) << 16) | 749 - (mode->crtc_hdisplay - 1)); 750 - REG_WRITE(map->src, 751 - ((mode->crtc_hdisplay - 1) << 16) | 752 - (mode->crtc_vdisplay - 1)); 753 - } 754 - 755 - REG_WRITE(map->pos, 0); 756 - 757 - if (gma_encoder) 758 - drm_object_property_get_value(&connector->base, 759 - dev->mode_config.scaling_mode_property, &scalingType); 760 - 761 - if (scalingType == DRM_MODE_SCALE_NO_SCALE) { 762 - /* Medfield doesn't have register support for centering so we 763 - * need to mess with the h/vblank and h/vsync start and ends 764 - * to get centering 765 - */ 766 - int offsetX = 0, offsetY = 0; 767 - 768 - offsetX = (adjusted_mode->crtc_hdisplay - 769 - mode->crtc_hdisplay) / 2; 770 - offsetY = (adjusted_mode->crtc_vdisplay - 771 - mode->crtc_vdisplay) / 2; 772 - 773 - REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) | 774 - ((adjusted_mode->crtc_htotal - 1) << 16)); 775 - REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) | 776 - ((adjusted_mode->crtc_vtotal - 1) << 16)); 777 - REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 778 - offsetX - 1) | 779 - ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); 780 - REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 781 - offsetX - 1) | 782 - ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); 783 - REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 784 - offsetY - 1) | 785 - ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); 786 - REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 787 - offsetY - 1) | 788 - ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); 789 - } else { 790 - REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | 791 - ((adjusted_mode->crtc_htotal - 1) << 16)); 792 - REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | 793 - ((adjusted_mode->crtc_vtotal - 1) << 16)); 794 - REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | 795 - ((adjusted_mode->crtc_hblank_end - 1) << 16)); 796 - REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | 797 - ((adjusted_mode->crtc_hsync_end - 1) << 16)); 798 - REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | 799 - ((adjusted_mode->crtc_vblank_end - 1) << 16)); 800 - REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | 801 - ((adjusted_mode->crtc_vsync_end - 1) << 16)); 802 - } 803 - 804 - /* Flush the plane changes */ 805 - { 806 - const struct drm_crtc_helper_funcs *crtc_funcs = 807 - crtc->helper_private; 808 - crtc_funcs->mode_set_base(crtc, x, y, old_fb); 809 - } 810 - 811 - /* setup pipeconf */ 812 - dev_priv->pipeconf[pipe] = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */ 813 - 814 - /* Set up the display plane register */ 815 - dev_priv->dspcntr[pipe] = REG_READ(map->cntr); 816 - dev_priv->dspcntr[pipe] |= pipe << DISPPLANE_SEL_PIPE_POS; 817 - dev_priv->dspcntr[pipe] |= DISPLAY_PLANE_ENABLE; 818 - 819 - if (is_mipi2) 820 - goto mrst_crtc_mode_set_exit; 821 - clk = adjusted_mode->clock; 822 - 823 - if (is_hdmi) { 824 - if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) { 825 - refclk = 19200; 826 - 827 - if (is_mipi || is_mipi2) 828 - clk_n = 1, clk_p2 = 8; 829 - else if (is_hdmi) 830 - clk_n = 1, clk_p2 = 10; 831 - } else if (ksel == KSEL_BYPASS_25) { 832 - refclk = 25000; 833 - 834 - if (is_mipi || is_mipi2) 835 - clk_n = 1, clk_p2 = 8; 836 - else if (is_hdmi) 837 - clk_n = 1, clk_p2 = 10; 838 - } else if ((ksel == KSEL_BYPASS_83_100) && 839 - dev_priv->core_freq == 166) { 840 - refclk = 83000; 841 - 842 - if (is_mipi || is_mipi2) 843 - clk_n = 4, clk_p2 = 8; 844 - else if (is_hdmi) 845 - clk_n = 4, clk_p2 = 10; 846 - } else if ((ksel == KSEL_BYPASS_83_100) && 847 - (dev_priv->core_freq == 100 || 848 - dev_priv->core_freq == 200)) { 849 - refclk = 100000; 850 - if (is_mipi || is_mipi2) 851 - clk_n = 4, clk_p2 = 8; 852 - else if (is_hdmi) 853 - clk_n = 4, clk_p2 = 10; 854 - } 855 - 856 - if (is_mipi) 857 - clk_byte = dev_priv->bpp / 8; 858 - else if (is_mipi2) 859 - clk_byte = dev_priv->bpp2 / 8; 860 - 861 - clk_tmp = clk * clk_n * clk_p2 * clk_byte; 862 - 863 - dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d.\n", 864 - clk, clk_n, clk_p2); 865 - dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d.\n", 866 - adjusted_mode->clock, clk_tmp); 867 - 868 - ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock); 869 - 870 - if (!ok) { 871 - DRM_ERROR 872 - ("mdfldFindBestPLL fail in mdfld_crtc_mode_set.\n"); 873 - } else { 874 - m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)]; 875 - 876 - dev_dbg(dev->dev, "dot clock = %d," 877 - "m = %d, p1 = %d, m_conv = %d.\n", 878 - clock.dot, clock.m, 879 - clock.p1, m_conv); 880 - } 881 - 882 - dpll = REG_READ(map->dpll); 883 - 884 - if (dpll & DPLL_VCO_ENABLE) { 885 - dpll &= ~DPLL_VCO_ENABLE; 886 - REG_WRITE(map->dpll, dpll); 887 - REG_READ(map->dpll); 888 - 889 - /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */ 890 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 891 - udelay(500); 892 - 893 - /* reset M1, N1 & P1 */ 894 - REG_WRITE(map->fp0, 0); 895 - dpll &= ~MDFLD_P1_MASK; 896 - REG_WRITE(map->dpll, dpll); 897 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 898 - udelay(500); 899 - } 900 - 901 - /* When ungating power of DPLL, needs to wait 0.5us before 902 - * enable the VCO */ 903 - if (dpll & MDFLD_PWR_GATE_EN) { 904 - dpll &= ~MDFLD_PWR_GATE_EN; 905 - REG_WRITE(map->dpll, dpll); 906 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 907 - udelay(500); 908 - } 909 - dpll = 0; 910 - 911 - if (is_hdmi) 912 - dpll |= MDFLD_VCO_SEL; 913 - 914 - fp = (clk_n / 2) << 16; 915 - fp |= m_conv; 916 - 917 - /* compute bitmask from p1 value */ 918 - dpll |= (1 << (clock.p1 - 2)) << 17; 919 - 920 - } else { 921 - dpll = 0x00800000; 922 - fp = 0x000000c1; 923 - } 924 - 925 - REG_WRITE(map->fp0, fp); 926 - REG_WRITE(map->dpll, dpll); 927 - /* FIXME_MDFLD PO - change 500 to 1 after PO */ 928 - udelay(500); 929 - 930 - dpll |= DPLL_VCO_ENABLE; 931 - REG_WRITE(map->dpll, dpll); 932 - REG_READ(map->dpll); 933 - 934 - /* wait for DSI PLL to lock */ 935 - while (timeout < 20000 && 936 - !(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) { 937 - udelay(150); 938 - timeout++; 939 - } 940 - 941 - if (is_mipi) 942 - goto mrst_crtc_mode_set_exit; 943 - 944 - dev_dbg(dev->dev, "is_mipi = 0x%x\n", is_mipi); 945 - 946 - REG_WRITE(map->conf, dev_priv->pipeconf[pipe]); 947 - REG_READ(map->conf); 948 - 949 - /* Wait for for the pipe enable to take effect. */ 950 - REG_WRITE(map->cntr, dev_priv->dspcntr[pipe]); 951 - gma_wait_for_vblank(dev); 952 - 953 - mrst_crtc_mode_set_exit: 954 - 955 - gma_power_end(dev); 956 - 957 - return 0; 958 - } 959 - 960 - const struct drm_crtc_helper_funcs mdfld_helper_funcs = { 961 - .dpms = mdfld_crtc_dpms, 962 - .mode_set = mdfld_crtc_mode_set, 963 - .mode_set_base = mdfld__intel_pipe_set_base, 964 - .prepare = gma_crtc_prepare, 965 - .commit = gma_crtc_commit, 966 - };
-74
drivers/gpu/drm/gma500/mdfld_output.c
··· 1 - /* 2 - * Copyright (c) 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, sublicensen 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 - * Thomas Eaton <thomas.g.eaton@intel.com> 25 - * Scott Rowe <scott.m.rowe@intel.com> 26 - */ 27 - 28 - #include "mdfld_output.h" 29 - #include "mdfld_dsi_dpi.h" 30 - #include "mdfld_dsi_output.h" 31 - 32 - #include "tc35876x-dsi-lvds.h" 33 - 34 - int mdfld_get_panel_type(struct drm_device *dev, int pipe) 35 - { 36 - struct drm_psb_private *dev_priv = dev->dev_private; 37 - return dev_priv->mdfld_panel_id; 38 - } 39 - 40 - static void mdfld_init_panel(struct drm_device *dev, int mipi_pipe, 41 - int p_type) 42 - { 43 - switch (p_type) { 44 - case TPO_VID: 45 - mdfld_dsi_output_init(dev, mipi_pipe, &mdfld_tpo_vid_funcs); 46 - break; 47 - case TC35876X: 48 - tc35876x_init(dev); 49 - mdfld_dsi_output_init(dev, mipi_pipe, &mdfld_tc35876x_funcs); 50 - break; 51 - case TMD_VID: 52 - mdfld_dsi_output_init(dev, mipi_pipe, &mdfld_tmd_vid_funcs); 53 - break; 54 - case HDMI: 55 - /* if (dev_priv->mdfld_hdmi_present) 56 - mdfld_hdmi_init(dev, &dev_priv->mode_dev); */ 57 - break; 58 - } 59 - } 60 - 61 - 62 - int mdfld_output_init(struct drm_device *dev) 63 - { 64 - struct drm_psb_private *dev_priv = dev->dev_private; 65 - 66 - /* FIXME: hardcoded for now */ 67 - dev_priv->mdfld_panel_id = TC35876X; 68 - /* MIPI panel 1 */ 69 - mdfld_init_panel(dev, 0, dev_priv->mdfld_panel_id); 70 - /* HDMI panel */ 71 - mdfld_init_panel(dev, 1, HDMI); 72 - return 0; 73 - } 74 -
-76
drivers/gpu/drm/gma500/mdfld_output.h
··· 1 - /* 2 - * Copyright (c) 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, sublicensen 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 - * Thomas Eaton <thomas.g.eaton@intel.com> 25 - * Scott Rowe <scott.m.rowe@intel.com> 26 - */ 27 - 28 - #ifndef MDFLD_OUTPUT_H 29 - #define MDFLD_OUTPUT_H 30 - 31 - #include "psb_drv.h" 32 - 33 - #define TPO_PANEL_WIDTH 84 34 - #define TPO_PANEL_HEIGHT 46 35 - #define TMD_PANEL_WIDTH 39 36 - #define TMD_PANEL_HEIGHT 71 37 - 38 - struct mdfld_dsi_config; 39 - 40 - enum panel_type { 41 - TPO_VID, 42 - TMD_VID, 43 - HDMI, 44 - TC35876X, 45 - }; 46 - 47 - struct panel_info { 48 - u32 width_mm; 49 - u32 height_mm; 50 - /* Other info */ 51 - }; 52 - 53 - struct panel_funcs { 54 - const struct drm_encoder_helper_funcs *encoder_helper_funcs; 55 - struct drm_display_mode * (*get_config_mode)(struct drm_device *); 56 - int (*get_panel_info)(struct drm_device *, int, struct panel_info *); 57 - int (*reset)(struct drm_device *, int); 58 - void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe); 59 - }; 60 - 61 - int mdfld_output_init(struct drm_device *dev); 62 - 63 - struct backlight_device *mdfld_get_backlight_device(void); 64 - int mdfld_set_brightness(struct backlight_device *bd); 65 - 66 - int mdfld_get_panel_type(struct drm_device *dev, int pipe); 67 - 68 - extern const struct drm_crtc_helper_funcs mdfld_helper_funcs; 69 - 70 - extern const struct panel_funcs mdfld_tmd_vid_funcs; 71 - extern const struct panel_funcs mdfld_tpo_vid_funcs; 72 - 73 - extern void mdfld_disable_crtc(struct drm_device *dev, int pipe); 74 - extern void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe); 75 - extern void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe); 76 - #endif
-197
drivers/gpu/drm/gma500/mdfld_tmd_vid.c
··· 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 - * Gideon Eaton <eaton. 27 - * Scott Rowe <scott.m.rowe@intel.com> 28 - */ 29 - 30 - #include <linux/delay.h> 31 - 32 - #include "mdfld_dsi_dpi.h" 33 - #include "mdfld_dsi_pkg_sender.h" 34 - 35 - static struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev) 36 - { 37 - struct drm_display_mode *mode; 38 - struct drm_psb_private *dev_priv = dev->dev_private; 39 - struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; 40 - bool use_gct = false; /*Disable GCT for now*/ 41 - 42 - mode = kzalloc(sizeof(*mode), GFP_KERNEL); 43 - if (!mode) 44 - return NULL; 45 - 46 - if (use_gct) { 47 - mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; 48 - mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; 49 - mode->hsync_start = mode->hdisplay + \ 50 - ((ti->hsync_offset_hi << 8) | \ 51 - ti->hsync_offset_lo); 52 - mode->hsync_end = mode->hsync_start + \ 53 - ((ti->hsync_pulse_width_hi << 8) | \ 54 - ti->hsync_pulse_width_lo); 55 - mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ 56 - ti->hblank_lo); 57 - mode->vsync_start = \ 58 - mode->vdisplay + ((ti->vsync_offset_hi << 8) | \ 59 - ti->vsync_offset_lo); 60 - mode->vsync_end = \ 61 - mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \ 62 - ti->vsync_pulse_width_lo); 63 - mode->vtotal = mode->vdisplay + \ 64 - ((ti->vblank_hi << 8) | ti->vblank_lo); 65 - mode->clock = ti->pixel_clock * 10; 66 - 67 - dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); 68 - dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); 69 - dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); 70 - dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); 71 - dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); 72 - dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); 73 - dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); 74 - dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); 75 - dev_dbg(dev->dev, "clock is %d\n", mode->clock); 76 - } else { 77 - mode->hdisplay = 480; 78 - mode->vdisplay = 854; 79 - mode->hsync_start = 487; 80 - mode->hsync_end = 490; 81 - mode->htotal = 499; 82 - mode->vsync_start = 861; 83 - mode->vsync_end = 865; 84 - mode->vtotal = 873; 85 - mode->clock = 33264; 86 - } 87 - 88 - drm_mode_set_name(mode); 89 - drm_mode_set_crtcinfo(mode, 0); 90 - 91 - mode->type |= DRM_MODE_TYPE_PREFERRED; 92 - 93 - return mode; 94 - } 95 - 96 - static int tmd_vid_get_panel_info(struct drm_device *dev, 97 - int pipe, 98 - struct panel_info *pi) 99 - { 100 - if (!dev || !pi) 101 - return -EINVAL; 102 - 103 - pi->width_mm = TMD_PANEL_WIDTH; 104 - pi->height_mm = TMD_PANEL_HEIGHT; 105 - 106 - return 0; 107 - } 108 - 109 - /* ************************************************************************* *\ 110 - * FUNCTION: mdfld_init_TMD_MIPI 111 - * 112 - * DESCRIPTION: This function is called only by mrst_dsi_mode_set and 113 - * restore_display_registers. since this function does not 114 - * acquire the mutex, it is important that the calling function 115 - * does! 116 - \* ************************************************************************* */ 117 - 118 - /* FIXME: make the below data u8 instead of u32; note byte order! */ 119 - static u32 tmd_cmd_mcap_off[] = {0x000000b2}; 120 - static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef}; 121 - static u32 tmd_cmd_set_lane_num[] = {0x006360ef}; 122 - static u32 tmd_cmd_pushing_clock0[] = {0x00cc2fef}; 123 - static u32 tmd_cmd_pushing_clock1[] = {0x00dd6eef}; 124 - static u32 tmd_cmd_set_mode[] = {0x000000b3}; 125 - static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef}; 126 - static u32 tmd_cmd_set_column[] = {0x0100002a, 0x000000df}; 127 - static u32 tmd_cmd_set_page[] = {0x0300002b, 0x00000055}; 128 - static u32 tmd_cmd_set_video_mode[] = {0x00000153}; 129 - /*no auto_bl,need add in furture*/ 130 - static u32 tmd_cmd_enable_backlight[] = {0x00005ab4}; 131 - static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd}; 132 - 133 - static void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config, 134 - int pipe) 135 - { 136 - struct mdfld_dsi_pkg_sender *sender 137 - = mdfld_dsi_get_pkg_sender(dsi_config); 138 - 139 - DRM_INFO("Enter mdfld init TMD MIPI display.\n"); 140 - 141 - if (!sender) { 142 - DRM_ERROR("Cannot get sender\n"); 143 - return; 144 - } 145 - 146 - if (dsi_config->dvr_ic_inited) 147 - return; 148 - 149 - msleep(3); 150 - 151 - /* FIXME: make the below data u8 instead of u32; note byte order! */ 152 - 153 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_mcap_off, 154 - sizeof(tmd_cmd_mcap_off), false); 155 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_enable_lane_switch, 156 - sizeof(tmd_cmd_enable_lane_switch), false); 157 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_lane_num, 158 - sizeof(tmd_cmd_set_lane_num), false); 159 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_pushing_clock0, 160 - sizeof(tmd_cmd_pushing_clock0), false); 161 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_pushing_clock1, 162 - sizeof(tmd_cmd_pushing_clock1), false); 163 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_mode, 164 - sizeof(tmd_cmd_set_mode), false); 165 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_sync_pulse_mode, 166 - sizeof(tmd_cmd_set_sync_pulse_mode), false); 167 - mdfld_dsi_send_mcs_long(sender, (u8 *) tmd_cmd_set_column, 168 - sizeof(tmd_cmd_set_column), false); 169 - mdfld_dsi_send_mcs_long(sender, (u8 *) tmd_cmd_set_page, 170 - sizeof(tmd_cmd_set_page), false); 171 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_video_mode, 172 - sizeof(tmd_cmd_set_video_mode), false); 173 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_enable_backlight, 174 - sizeof(tmd_cmd_enable_backlight), false); 175 - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_backlight_dimming, 176 - sizeof(tmd_cmd_set_backlight_dimming), false); 177 - 178 - dsi_config->dvr_ic_inited = 1; 179 - } 180 - 181 - /*TPO DPI encoder helper funcs*/ 182 - static const struct drm_encoder_helper_funcs 183 - mdfld_tpo_dpi_encoder_helper_funcs = { 184 - .dpms = mdfld_dsi_dpi_dpms, 185 - .mode_fixup = mdfld_dsi_dpi_mode_fixup, 186 - .prepare = mdfld_dsi_dpi_prepare, 187 - .mode_set = mdfld_dsi_dpi_mode_set, 188 - .commit = mdfld_dsi_dpi_commit, 189 - }; 190 - 191 - const struct panel_funcs mdfld_tmd_vid_funcs = { 192 - .encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs, 193 - .get_config_mode = &tmd_vid_get_config_mode, 194 - .get_panel_info = tmd_vid_get_panel_info, 195 - .reset = mdfld_dsi_panel_reset, 196 - .drv_ic_init = mdfld_dsi_tmd_drv_ic_init, 197 - };
-83
drivers/gpu/drm/gma500/mdfld_tpo_vid.c
··· 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 - 30 - static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev) 31 - { 32 - struct drm_display_mode *mode; 33 - 34 - mode = kzalloc(sizeof(*mode), GFP_KERNEL); 35 - if (!mode) 36 - return NULL; 37 - 38 - mode->hdisplay = 864; 39 - mode->vdisplay = 480; 40 - mode->hsync_start = 873; 41 - mode->hsync_end = 876; 42 - mode->htotal = 887; 43 - mode->vsync_start = 487; 44 - mode->vsync_end = 490; 45 - mode->vtotal = 499; 46 - mode->clock = 33264; 47 - 48 - drm_mode_set_name(mode); 49 - drm_mode_set_crtcinfo(mode, 0); 50 - 51 - mode->type |= DRM_MODE_TYPE_PREFERRED; 52 - 53 - return mode; 54 - } 55 - 56 - static int tpo_vid_get_panel_info(struct drm_device *dev, 57 - int pipe, 58 - struct panel_info *pi) 59 - { 60 - if (!dev || !pi) 61 - return -EINVAL; 62 - 63 - pi->width_mm = TPO_PANEL_WIDTH; 64 - pi->height_mm = TPO_PANEL_HEIGHT; 65 - 66 - return 0; 67 - } 68 - 69 - /*TPO DPI encoder helper funcs*/ 70 - static const struct drm_encoder_helper_funcs 71 - mdfld_tpo_dpi_encoder_helper_funcs = { 72 - .dpms = mdfld_dsi_dpi_dpms, 73 - .mode_fixup = mdfld_dsi_dpi_mode_fixup, 74 - .prepare = mdfld_dsi_dpi_prepare, 75 - .mode_set = mdfld_dsi_dpi_mode_set, 76 - .commit = mdfld_dsi_dpi_commit, 77 - }; 78 - 79 - const struct panel_funcs mdfld_tpo_vid_funcs = { 80 - .encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs, 81 - .get_config_mode = &tpo_vid_get_config_mode, 82 - .get_panel_info = tpo_vid_get_panel_info, 83 - };
-12
drivers/gpu/drm/gma500/psb_drv.c
··· 46 46 * PowerVR SGX535 - Poulsbo - Intel GMA 500, Intel Atom Z5xx 47 47 * PowerVR SGX535 - Moorestown - Intel GMA 600 48 48 * PowerVR SGX535 - Oaktrail - Intel GMA 600, Intel Atom Z6xx, E6xx 49 - * PowerVR SGX540 - Medfield - Intel Atom Z2460 50 - * PowerVR SGX544MP2 - Medfield - 51 49 * PowerVR SGX545 - Cedartrail - Intel GMA 3600, Intel Atom D2500, N2600 52 50 * PowerVR SGX545 - Cedartrail - Intel GMA 3650, Intel Atom D2550, D2700, 53 51 * N2800 ··· 63 65 { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, 64 66 { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, 65 67 { 0x8086, 0x4108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, 66 - #endif 67 - #if defined(CONFIG_DRM_MEDFIELD) 68 - { 0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 69 - { 0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 70 - { 0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 71 - { 0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 72 - { 0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 73 - { 0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 74 - { 0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 75 - { 0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops }, 76 68 #endif 77 69 #if defined(CONFIG_DRM_GMA3600) 78 70 { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops },
-66
drivers/gpu/drm/gma500/psb_drv.h
··· 40 40 CHIP_PSB_8108 = 0, /* Poulsbo */ 41 41 CHIP_PSB_8109 = 1, /* Poulsbo */ 42 42 CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */ 43 - CHIP_MFLD_0130 = 3, /* Medfield */ 44 43 }; 45 44 46 45 #define IS_PSB(drm) ((to_pci_dev((drm)->dev)->device & 0xfffe) == 0x8108) 47 46 #define IS_MRST(drm) ((to_pci_dev((drm)->dev)->device & 0xfff0) == 0x4100) 48 - #define IS_MFLD(drm) ((to_pci_dev((drm)->dev)->device & 0xfff8) == 0x0130) 49 47 #define IS_CDV(drm) ((to_pci_dev((drm)->dev)->device & 0xfff0) == 0x0be0) 50 48 51 49 /* Hardware offsets */ 52 50 #define PSB_VDC_OFFSET 0x00000000 53 51 #define PSB_VDC_SIZE 0x000080000 54 52 #define MRST_MMIO_SIZE 0x0000C0000 55 - #define MDFLD_MMIO_SIZE 0x000100000 56 53 #define PSB_SGX_SIZE 0x8000 57 54 #define PSB_SGX_OFFSET 0x00040000 58 55 #define MRST_SGX_OFFSET 0x00080000 ··· 106 109 #define _PSB_DPST_PIPEA_FLAG (1<<6) 107 110 #define _PSB_PIPEA_EVENT_FLAG (1<<6) 108 111 #define _PSB_VSYNC_PIPEA_FLAG (1<<7) 109 - #define _MDFLD_MIPIA_FLAG (1<<16) 110 - #define _MDFLD_MIPIC_FLAG (1<<17) 111 112 #define _PSB_IRQ_DISP_HOTSYNC (1<<17) 112 113 #define _PSB_IRQ_SGX_FLAG (1<<18) 113 114 #define _PSB_IRQ_MSVDX_FLAG (1<<19) ··· 114 119 #define _PSB_PIPE_EVENT_FLAG (_PSB_VSYNC_PIPEA_FLAG | \ 115 120 _PSB_VSYNC_PIPEB_FLAG) 116 121 117 - /* This flag includes all the display IRQ bits excepts the vblank irqs. */ 118 - #define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \ 119 - _MDFLD_PIPEB_EVENT_FLAG | \ 120 - _PSB_PIPEA_EVENT_FLAG | \ 121 - _PSB_VSYNC_PIPEA_FLAG | \ 122 - _MDFLD_MIPIA_FLAG | \ 123 - _MDFLD_MIPIC_FLAG) 124 122 #define PSB_INT_IDENTITY_R 0x20A4 125 123 #define PSB_INT_MASK_R 0x20A8 126 124 #define PSB_INT_ENABLE_R 0x20A0 ··· 178 190 #define PSB_NUM_VBLANKS 2 179 191 #define PSB_WATCHDOG_DELAY (HZ * 2) 180 192 #define PSB_LID_DELAY (HZ / 10) 181 - 182 - #define MDFLD_PNW_B0 0x04 183 - #define MDFLD_PNW_C0 0x08 184 - 185 - #define MDFLD_DSR_2D_3D_0 (1 << 0) 186 - #define MDFLD_DSR_2D_3D_2 (1 << 1) 187 - #define MDFLD_DSR_CURSOR_0 (1 << 2) 188 - #define MDFLD_DSR_CURSOR_2 (1 << 3) 189 - #define MDFLD_DSR_OVERLAY_0 (1 << 4) 190 - #define MDFLD_DSR_OVERLAY_2 (1 << 5) 191 - #define MDFLD_DSR_MIPI_CONTROL (1 << 6) 192 - #define MDFLD_DSR_DAMAGE_MASK_0 ((1 << 0) | (1 << 2) | (1 << 4)) 193 - #define MDFLD_DSR_DAMAGE_MASK_2 ((1 << 1) | (1 << 3) | (1 << 5)) 194 - #define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2) 195 - 196 - #define MDFLD_DSR_RR 45 197 - #define MDFLD_DPU_ENABLE (1 << 31) 198 - #define MDFLD_DSR_FULLSCREEN (1 << 30) 199 - #define MDFLD_DSR_DELAY (HZ / MDFLD_DSR_RR) 200 193 201 194 #define PSB_PWR_STATE_ON 1 202 195 #define PSB_PWR_STATE_OFF 2 ··· 351 382 uint32_t savePWM_CONTROL_LOGIC; 352 383 }; 353 384 354 - struct medfield_state { 355 - uint32_t saveMIPI; 356 - uint32_t saveMIPI_C; 357 - 358 - uint32_t savePFIT_CONTROL; 359 - uint32_t savePFIT_PGM_RATIOS; 360 - uint32_t saveHDMIPHYMISCCTL; 361 - uint32_t saveHDMIB_CONTROL; 362 - }; 363 - 364 385 struct cdv_state { 365 386 uint32_t saveDSPCLK_GATE_D; 366 387 uint32_t saveRAMCLK_GATE_D; ··· 376 417 uint32_t saveVBT; 377 418 union { 378 419 struct psb_state psb; 379 - struct medfield_state mdfld; 380 420 struct cdv_state cdv; 381 421 }; 382 422 uint32_t saveBLC_PWM_CTL2; ··· 548 590 u32 pipeconf[3]; 549 591 u32 dspcntr[3]; 550 592 551 - int mdfld_panel_id; 552 - 553 593 bool dplla_96mhz; /* DPLL data from the VBT */ 554 594 555 595 struct { ··· 693 737 /* oaktrail_device.c */ 694 738 extern const struct psb_ops oaktrail_chip_ops; 695 739 696 - /* mdlfd_device.c */ 697 - extern const struct psb_ops mdfld_chip_ops; 698 - 699 740 /* cdv_device.c */ 700 741 extern const struct psb_ops cdv_chip_ops; 701 742 ··· 727 774 u32 value) 728 775 { 729 776 int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0; 730 - struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0); 731 - pci_write_config_dword(pci_root, 0xD4, value); 732 - pci_write_config_dword(pci_root, 0xD0, mcr); 733 - pci_dev_put(pci_root); 734 - } 735 - static inline u32 MDFLD_MSG_READ32(int domain, uint port, uint offset) 736 - { 737 - int mcr = (0x10<<24) | (port << 16) | (offset << 8); 738 - uint32_t ret_val = 0; 739 - struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0); 740 - pci_write_config_dword(pci_root, 0xD0, mcr); 741 - pci_read_config_dword(pci_root, 0xD4, &ret_val); 742 - pci_dev_put(pci_root); 743 - return ret_val; 744 - } 745 - static inline void MDFLD_MSG_WRITE32(int domain, uint port, uint offset, 746 - u32 value) 747 - { 748 - int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; 749 777 struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0); 750 778 pci_write_config_dword(pci_root, 0xD4, value); 751 779 pci_write_config_dword(pci_root, 0xD0, mcr);
+1 -11
drivers/gpu/drm/gma500/psb_intel_reg.h
··· 595 595 #define PIPE_PIXEL_MASK 0x00ffffff 596 596 #define PIPE_PIXEL_SHIFT 0 597 597 598 - #define FW_BLC_SELF 0x20e0 598 + #define FW_BLC_SELF 0x20e0 599 599 #define FW_BLC_SELF_EN (1<<15) 600 600 601 601 #define DSPARB 0x70030 ··· 789 789 * MOORESTOWN delta registers 790 790 */ 791 791 #define MRST_DPLL_A 0x0f014 792 - #define MDFLD_DPLL_B 0x0f018 793 - #define MDFLD_INPUT_REF_SEL (1 << 14) 794 - #define MDFLD_VCO_SEL (1 << 16) 795 792 #define DPLLA_MODE_LVDS (2 << 26) /* mrst */ 796 - #define MDFLD_PLL_LATCHEN (1 << 28) 797 - #define MDFLD_PWR_GATE_EN (1 << 30) 798 - #define MDFLD_P1_MASK (0x1FF << 17) 799 793 #define MRST_FPA0 0x0f040 800 794 #define MRST_FPA1 0x0f044 801 - #define MDFLD_DPLL_DIV0 0x0f048 802 - #define MDFLD_DPLL_DIV1 0x0f04c 803 795 #define MRST_PERF_MODE 0x020f4 804 796 805 797 /* ··· 840 848 841 849 #define MRST_DSPABASE 0x7019c 842 850 #define MRST_DSPBBASE 0x7119c 843 - #define MDFLD_DSPCBASE 0x7219c 844 851 845 852 /* 846 853 * Moorestown registers. ··· 921 930 #define DEVICE_RESET_REG 0xb01C 922 931 #define DPI_RESOLUTION_REG 0xb020 923 932 #define RES_V_POS 0x10 924 - #define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */ 925 933 #define HORIZ_SYNC_PAD_COUNT_REG 0xb028 926 934 #define HORIZ_BACK_PORCH_COUNT_REG 0xb02C 927 935 #define HORIZ_FRONT_PORCH_COUNT_REG 0xb030
+1 -71
drivers/gpu/drm/gma500/psb_irq.c
··· 10 10 11 11 #include <drm/drm_vblank.h> 12 12 13 - #include "mdfld_output.h" 14 13 #include "power.h" 15 14 #include "psb_drv.h" 16 15 #include "psb_intel_reg.h" ··· 163 164 "%s, can't clear status bits for pipe %d, its value = 0x%x.\n", 164 165 __func__, pipe, PSB_RVDC32(pipe_stat_reg)); 165 166 166 - if (pipe_stat_val & PIPE_VBLANK_STATUS || 167 - (IS_MFLD(dev) && pipe_stat_val & PIPE_TE_STATUS)) { 167 + if (pipe_stat_val & PIPE_VBLANK_STATUS) { 168 168 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); 169 169 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 170 170 unsigned long flags; ··· 261 263 if (vdc_stat & (_PSB_PIPE_EVENT_FLAG|_PSB_IRQ_ASLE)) 262 264 dsp_int = 1; 263 265 264 - /* FIXME: Handle Medfield 265 - if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) 266 - dsp_int = 1; 267 - */ 268 - 269 266 if (vdc_stat & _PSB_IRQ_SGX_FLAG) 270 267 sgx_int = 1; 271 268 if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC) ··· 317 324 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; 318 325 if (dev->vblank[1].enabled) 319 326 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; 320 - 321 - /* FIXME: Handle Medfield irq mask 322 - if (dev->vblank[1].enabled) 323 - dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; 324 - if (dev->vblank[2].enabled) 325 - dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; 326 - */ 327 327 328 328 /* Revisit this area - want per device masks ? */ 329 329 if (dev_priv->ops->hotplug) ··· 490 504 uint32_t reg_val = 0; 491 505 uint32_t pipeconf_reg = mid_pipeconf(pipe); 492 506 493 - /* Medfield is different - we should perhaps extract out vblank 494 - and blacklight etc ops */ 495 - if (IS_MFLD(dev)) 496 - return mdfld_enable_te(dev, pipe); 497 - 498 507 if (gma_power_begin(dev, false)) { 499 508 reg_val = REG_READ(pipeconf_reg); 500 509 gma_power_end(dev); ··· 524 543 struct drm_psb_private *dev_priv = dev->dev_private; 525 544 unsigned long irqflags; 526 545 527 - if (IS_MFLD(dev)) 528 - mdfld_disable_te(dev, pipe); 529 546 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 530 547 531 548 if (pipe == 0) ··· 534 555 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 535 556 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 536 557 psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); 537 - 538 - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 539 - } 540 - 541 - /* 542 - * It is used to enable TE interrupt 543 - */ 544 - int mdfld_enable_te(struct drm_device *dev, int pipe) 545 - { 546 - struct drm_psb_private *dev_priv = 547 - (struct drm_psb_private *) dev->dev_private; 548 - unsigned long irqflags; 549 - uint32_t reg_val = 0; 550 - uint32_t pipeconf_reg = mid_pipeconf(pipe); 551 - 552 - if (gma_power_begin(dev, false)) { 553 - reg_val = REG_READ(pipeconf_reg); 554 - gma_power_end(dev); 555 - } 556 - 557 - if (!(reg_val & PIPEACONF_ENABLE)) 558 - return -EINVAL; 559 - 560 - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 561 - 562 - mid_enable_pipe_event(dev_priv, pipe); 563 - psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); 564 - 565 - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 566 - 567 - return 0; 568 - } 569 - 570 - /* 571 - * It is used to disable TE interrupt 572 - */ 573 - void mdfld_disable_te(struct drm_device *dev, int pipe) 574 - { 575 - struct drm_psb_private *dev_priv = 576 - (struct drm_psb_private *) dev->dev_private; 577 - unsigned long irqflags; 578 - 579 - if (!dev_priv->dsr_enable) 580 - return; 581 - 582 - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 583 - 584 - mid_disable_pipe_event(dev_priv, pipe); 585 - psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); 586 558 587 559 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 588 560 }
-2
drivers/gpu/drm/gma500/psb_irq.h
··· 31 31 void psb_disable_vblank(struct drm_crtc *crtc); 32 32 u32 psb_get_vblank_counter(struct drm_crtc *crtc); 33 33 34 - int mdfld_enable_te(struct drm_device *dev, int pipe); 35 - void mdfld_disable_te(struct drm_device *dev, int pipe); 36 34 #endif /* _PSB_IRQ_H_ */
-14
drivers/gpu/drm/gma500/psb_reg.h
··· 550 550 #define PSB_PM_SSC 0x20 551 551 #define PSB_PM_SSS 0x30 552 552 #define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ 553 - #define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c 554 - #define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 555 - #define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 556 - #define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 557 - #define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */ 558 553 /* Display SSS register bits are different in A0 vs. B0 */ 559 554 #define PSB_PWRGT_GFX_MASK 0x3 560 - #define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0 561 - #define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300 562 - #define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00 563 555 #define PSB_PWRGT_GFX_MASK_B0 0xc3 564 - #define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c 565 - #define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 566 - #define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 567 - #define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 568 - #define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ 569 - #define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ 570 556 #endif
-805
drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c
··· 1 - /* 2 - * Copyright © 2011 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 - */ 24 - 25 - #include <linux/delay.h> 26 - #include <linux/kernel.h> 27 - #include <linux/module.h> 28 - #include <linux/gpio/consumer.h> 29 - 30 - #include <asm/intel_scu_ipc.h> 31 - 32 - #include "mdfld_dsi_dpi.h" 33 - #include "mdfld_dsi_pkg_sender.h" 34 - #include "mdfld_output.h" 35 - #include "tc35876x-dsi-lvds.h" 36 - 37 - static struct i2c_client *tc35876x_client; 38 - static struct i2c_client *cmi_lcd_i2c_client; 39 - /* Panel GPIOs */ 40 - static struct gpio_desc *bridge_reset; 41 - static struct gpio_desc *bridge_bl_enable; 42 - static struct gpio_desc *backlight_voltage; 43 - 44 - 45 - #define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) 46 - #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) 47 - 48 - /* DSI D-PHY Layer Registers */ 49 - #define D0W_DPHYCONTTX 0x0004 50 - #define CLW_DPHYCONTRX 0x0020 51 - #define D0W_DPHYCONTRX 0x0024 52 - #define D1W_DPHYCONTRX 0x0028 53 - #define D2W_DPHYCONTRX 0x002C 54 - #define D3W_DPHYCONTRX 0x0030 55 - #define COM_DPHYCONTRX 0x0038 56 - #define CLW_CNTRL 0x0040 57 - #define D0W_CNTRL 0x0044 58 - #define D1W_CNTRL 0x0048 59 - #define D2W_CNTRL 0x004C 60 - #define D3W_CNTRL 0x0050 61 - #define DFTMODE_CNTRL 0x0054 62 - 63 - /* DSI PPI Layer Registers */ 64 - #define PPI_STARTPPI 0x0104 65 - #define PPI_BUSYPPI 0x0108 66 - #define PPI_LINEINITCNT 0x0110 67 - #define PPI_LPTXTIMECNT 0x0114 68 - #define PPI_LANEENABLE 0x0134 69 - #define PPI_TX_RX_TA 0x013C 70 - #define PPI_CLS_ATMR 0x0140 71 - #define PPI_D0S_ATMR 0x0144 72 - #define PPI_D1S_ATMR 0x0148 73 - #define PPI_D2S_ATMR 0x014C 74 - #define PPI_D3S_ATMR 0x0150 75 - #define PPI_D0S_CLRSIPOCOUNT 0x0164 76 - #define PPI_D1S_CLRSIPOCOUNT 0x0168 77 - #define PPI_D2S_CLRSIPOCOUNT 0x016C 78 - #define PPI_D3S_CLRSIPOCOUNT 0x0170 79 - #define CLS_PRE 0x0180 80 - #define D0S_PRE 0x0184 81 - #define D1S_PRE 0x0188 82 - #define D2S_PRE 0x018C 83 - #define D3S_PRE 0x0190 84 - #define CLS_PREP 0x01A0 85 - #define D0S_PREP 0x01A4 86 - #define D1S_PREP 0x01A8 87 - #define D2S_PREP 0x01AC 88 - #define D3S_PREP 0x01B0 89 - #define CLS_ZERO 0x01C0 90 - #define D0S_ZERO 0x01C4 91 - #define D1S_ZERO 0x01C8 92 - #define D2S_ZERO 0x01CC 93 - #define D3S_ZERO 0x01D0 94 - #define PPI_CLRFLG 0x01E0 95 - #define PPI_CLRSIPO 0x01E4 96 - #define HSTIMEOUT 0x01F0 97 - #define HSTIMEOUTENABLE 0x01F4 98 - 99 - /* DSI Protocol Layer Registers */ 100 - #define DSI_STARTDSI 0x0204 101 - #define DSI_BUSYDSI 0x0208 102 - #define DSI_LANEENABLE 0x0210 103 - #define DSI_LANESTATUS0 0x0214 104 - #define DSI_LANESTATUS1 0x0218 105 - #define DSI_INTSTATUS 0x0220 106 - #define DSI_INTMASK 0x0224 107 - #define DSI_INTCLR 0x0228 108 - #define DSI_LPTXTO 0x0230 109 - 110 - /* DSI General Registers */ 111 - #define DSIERRCNT 0x0300 112 - 113 - /* DSI Application Layer Registers */ 114 - #define APLCTRL 0x0400 115 - #define RDPKTLN 0x0404 116 - 117 - /* Video Path Registers */ 118 - #define VPCTRL 0x0450 119 - #define HTIM1 0x0454 120 - #define HTIM2 0x0458 121 - #define VTIM1 0x045C 122 - #define VTIM2 0x0460 123 - #define VFUEN 0x0464 124 - 125 - /* LVDS Registers */ 126 - #define LVMX0003 0x0480 127 - #define LVMX0407 0x0484 128 - #define LVMX0811 0x0488 129 - #define LVMX1215 0x048C 130 - #define LVMX1619 0x0490 131 - #define LVMX2023 0x0494 132 - #define LVMX2427 0x0498 133 - #define LVCFG 0x049C 134 - #define LVPHY0 0x04A0 135 - #define LVPHY1 0x04A4 136 - 137 - /* System Registers */ 138 - #define SYSSTAT 0x0500 139 - #define SYSRST 0x0504 140 - 141 - /* GPIO Registers */ 142 - /*#define GPIOC 0x0520*/ 143 - #define GPIOO 0x0524 144 - #define GPIOI 0x0528 145 - 146 - /* I2C Registers */ 147 - #define I2CTIMCTRL 0x0540 148 - #define I2CMADDR 0x0544 149 - #define WDATAQ 0x0548 150 - #define RDATAQ 0x054C 151 - 152 - /* Chip/Rev Registers */ 153 - #define IDREG 0x0580 154 - 155 - /* Debug Registers */ 156 - #define DEBUG00 0x05A0 157 - #define DEBUG01 0x05A4 158 - 159 - /* Panel CABC registers */ 160 - #define PANEL_PWM_CONTROL 0x90 161 - #define PANEL_FREQ_DIVIDER_HI 0x91 162 - #define PANEL_FREQ_DIVIDER_LO 0x92 163 - #define PANEL_DUTY_CONTROL 0x93 164 - #define PANEL_MODIFY_RGB 0x94 165 - #define PANEL_FRAMERATE_CONTROL 0x96 166 - #define PANEL_PWM_MIN 0x97 167 - #define PANEL_PWM_REF 0x98 168 - #define PANEL_PWM_MAX 0x99 169 - #define PANEL_ALLOW_DISTORT 0x9A 170 - #define PANEL_BYPASS_PWMI 0x9B 171 - 172 - /* Panel color management registers */ 173 - #define PANEL_CM_ENABLE 0x700 174 - #define PANEL_CM_HUE 0x701 175 - #define PANEL_CM_SATURATION 0x702 176 - #define PANEL_CM_INTENSITY 0x703 177 - #define PANEL_CM_BRIGHTNESS 0x704 178 - #define PANEL_CM_CE_ENABLE 0x705 179 - #define PANEL_CM_PEAK_EN 0x710 180 - #define PANEL_CM_GAIN 0x711 181 - #define PANEL_CM_HUETABLE_START 0x730 182 - #define PANEL_CM_HUETABLE_END 0x747 /* inclusive */ 183 - 184 - /* Input muxing for registers LVMX0003...LVMX2427 */ 185 - enum { 186 - INPUT_R0, /* 0 */ 187 - INPUT_R1, 188 - INPUT_R2, 189 - INPUT_R3, 190 - INPUT_R4, 191 - INPUT_R5, 192 - INPUT_R6, 193 - INPUT_R7, 194 - INPUT_G0, /* 8 */ 195 - INPUT_G1, 196 - INPUT_G2, 197 - INPUT_G3, 198 - INPUT_G4, 199 - INPUT_G5, 200 - INPUT_G6, 201 - INPUT_G7, 202 - INPUT_B0, /* 16 */ 203 - INPUT_B1, 204 - INPUT_B2, 205 - INPUT_B3, 206 - INPUT_B4, 207 - INPUT_B5, 208 - INPUT_B6, 209 - INPUT_B7, 210 - INPUT_HSYNC, /* 24 */ 211 - INPUT_VSYNC, 212 - INPUT_DE, 213 - LOGIC_0, 214 - /* 28...31 undefined */ 215 - }; 216 - 217 - #define INPUT_MUX(lvmx03, lvmx02, lvmx01, lvmx00) \ 218 - (FLD_VAL(lvmx03, 29, 24) | FLD_VAL(lvmx02, 20, 16) | \ 219 - FLD_VAL(lvmx01, 12, 8) | FLD_VAL(lvmx00, 4, 0)) 220 - 221 - /** 222 - * tc35876x_regw - Write DSI-LVDS bridge register using I2C 223 - * @client: struct i2c_client to use 224 - * @reg: register address 225 - * @value: value to write 226 - * 227 - * Returns 0 on success, or a negative error value. 228 - */ 229 - static int tc35876x_regw(struct i2c_client *client, u16 reg, u32 value) 230 - { 231 - int r; 232 - u8 tx_data[] = { 233 - /* NOTE: Register address big-endian, data little-endian. */ 234 - (reg >> 8) & 0xff, 235 - reg & 0xff, 236 - value & 0xff, 237 - (value >> 8) & 0xff, 238 - (value >> 16) & 0xff, 239 - (value >> 24) & 0xff, 240 - }; 241 - struct i2c_msg msgs[] = { 242 - { 243 - .addr = client->addr, 244 - .flags = 0, 245 - .buf = tx_data, 246 - .len = ARRAY_SIZE(tx_data), 247 - }, 248 - }; 249 - 250 - r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 251 - if (r < 0) { 252 - dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x error %d\n", 253 - __func__, reg, value, r); 254 - return r; 255 - } 256 - 257 - if (r < ARRAY_SIZE(msgs)) { 258 - dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x msgs %d\n", 259 - __func__, reg, value, r); 260 - return -EAGAIN; 261 - } 262 - 263 - dev_dbg(&client->dev, "%s: reg 0x%04x val 0x%08x\n", 264 - __func__, reg, value); 265 - 266 - return 0; 267 - } 268 - 269 - /** 270 - * tc35876x_regr - Read DSI-LVDS bridge register using I2C 271 - * @client: struct i2c_client to use 272 - * @reg: register address 273 - * @value: pointer for storing the value 274 - * 275 - * Returns 0 on success, or a negative error value. 276 - */ 277 - static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value) 278 - { 279 - int r; 280 - u8 tx_data[] = { 281 - (reg >> 8) & 0xff, 282 - reg & 0xff, 283 - }; 284 - u8 rx_data[4]; 285 - struct i2c_msg msgs[] = { 286 - { 287 - .addr = client->addr, 288 - .flags = 0, 289 - .buf = tx_data, 290 - .len = ARRAY_SIZE(tx_data), 291 - }, 292 - { 293 - .addr = client->addr, 294 - .flags = I2C_M_RD, 295 - .buf = rx_data, 296 - .len = ARRAY_SIZE(rx_data), 297 - }, 298 - }; 299 - 300 - r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 301 - if (r < 0) { 302 - dev_err(&client->dev, "%s: reg 0x%04x error %d\n", __func__, 303 - reg, r); 304 - return r; 305 - } 306 - 307 - if (r < ARRAY_SIZE(msgs)) { 308 - dev_err(&client->dev, "%s: reg 0x%04x msgs %d\n", __func__, 309 - reg, r); 310 - return -EAGAIN; 311 - } 312 - 313 - *value = rx_data[0] << 24 | rx_data[1] << 16 | 314 - rx_data[2] << 8 | rx_data[3]; 315 - 316 - dev_dbg(&client->dev, "%s: reg 0x%04x value 0x%08x\n", __func__, 317 - reg, *value); 318 - 319 - return 0; 320 - } 321 - 322 - void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state) 323 - { 324 - if (WARN(!tc35876x_client, "%s called before probe", __func__)) 325 - return; 326 - 327 - dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state); 328 - 329 - if (!bridge_reset) 330 - return; 331 - 332 - if (state) { 333 - gpiod_set_value_cansleep(bridge_reset, 0); 334 - mdelay(10); 335 - } else { 336 - /* Pull MIPI Bridge reset pin to Low */ 337 - gpiod_set_value_cansleep(bridge_reset, 0); 338 - mdelay(20); 339 - /* Pull MIPI Bridge reset pin to High */ 340 - gpiod_set_value_cansleep(bridge_reset, 1); 341 - mdelay(40); 342 - } 343 - } 344 - 345 - void tc35876x_configure_lvds_bridge(struct drm_device *dev) 346 - { 347 - struct i2c_client *i2c = tc35876x_client; 348 - u32 ppi_lptxtimecnt; 349 - u32 txtagocnt; 350 - u32 txtasurecnt; 351 - u32 id; 352 - 353 - if (WARN(!tc35876x_client, "%s called before probe", __func__)) 354 - return; 355 - 356 - dev_dbg(&tc35876x_client->dev, "%s\n", __func__); 357 - 358 - if (!tc35876x_regr(i2c, IDREG, &id)) 359 - dev_info(&tc35876x_client->dev, "tc35876x ID 0x%08x\n", id); 360 - else 361 - dev_err(&tc35876x_client->dev, "Cannot read ID\n"); 362 - 363 - ppi_lptxtimecnt = 4; 364 - txtagocnt = (5 * ppi_lptxtimecnt - 3) / 4; 365 - txtasurecnt = 3 * ppi_lptxtimecnt / 2; 366 - tc35876x_regw(i2c, PPI_TX_RX_TA, FLD_VAL(txtagocnt, 26, 16) | 367 - FLD_VAL(txtasurecnt, 10, 0)); 368 - tc35876x_regw(i2c, PPI_LPTXTIMECNT, FLD_VAL(ppi_lptxtimecnt, 10, 0)); 369 - 370 - tc35876x_regw(i2c, PPI_D0S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 371 - tc35876x_regw(i2c, PPI_D1S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 372 - tc35876x_regw(i2c, PPI_D2S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 373 - tc35876x_regw(i2c, PPI_D3S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 374 - 375 - /* Enabling MIPI & PPI lanes, Enable 4 lanes */ 376 - tc35876x_regw(i2c, PPI_LANEENABLE, 377 - BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); 378 - tc35876x_regw(i2c, DSI_LANEENABLE, 379 - BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); 380 - tc35876x_regw(i2c, PPI_STARTPPI, BIT(0)); 381 - tc35876x_regw(i2c, DSI_STARTDSI, BIT(0)); 382 - 383 - /* Setting LVDS output frequency */ 384 - tc35876x_regw(i2c, LVPHY0, FLD_VAL(1, 20, 16) | 385 - FLD_VAL(2, 15, 14) | FLD_VAL(6, 4, 0)); /* 0x00048006 */ 386 - 387 - /* Setting video panel control register,0x00000120 VTGen=ON ?!?!? */ 388 - tc35876x_regw(i2c, VPCTRL, BIT(8) | BIT(5)); 389 - 390 - /* Horizontal back porch and horizontal pulse width. 0x00280028 */ 391 - tc35876x_regw(i2c, HTIM1, FLD_VAL(40, 24, 16) | FLD_VAL(40, 8, 0)); 392 - 393 - /* Horizontal front porch and horizontal active video size. 0x00500500*/ 394 - tc35876x_regw(i2c, HTIM2, FLD_VAL(80, 24, 16) | FLD_VAL(1280, 10, 0)); 395 - 396 - /* Vertical back porch and vertical sync pulse width. 0x000e000a */ 397 - tc35876x_regw(i2c, VTIM1, FLD_VAL(14, 23, 16) | FLD_VAL(10, 7, 0)); 398 - 399 - /* Vertical front porch and vertical display size. 0x000e0320 */ 400 - tc35876x_regw(i2c, VTIM2, FLD_VAL(14, 23, 16) | FLD_VAL(800, 10, 0)); 401 - 402 - /* Set above HTIM1, HTIM2, VTIM1, and VTIM2 at next VSYNC. */ 403 - tc35876x_regw(i2c, VFUEN, BIT(0)); 404 - 405 - /* Soft reset LCD controller. */ 406 - tc35876x_regw(i2c, SYSRST, BIT(2)); 407 - 408 - /* LVDS-TX input muxing */ 409 - tc35876x_regw(i2c, LVMX0003, 410 - INPUT_MUX(INPUT_R5, INPUT_R4, INPUT_R3, INPUT_R2)); 411 - tc35876x_regw(i2c, LVMX0407, 412 - INPUT_MUX(INPUT_G2, INPUT_R7, INPUT_R1, INPUT_R6)); 413 - tc35876x_regw(i2c, LVMX0811, 414 - INPUT_MUX(INPUT_G1, INPUT_G0, INPUT_G4, INPUT_G3)); 415 - tc35876x_regw(i2c, LVMX1215, 416 - INPUT_MUX(INPUT_B2, INPUT_G7, INPUT_G6, INPUT_G5)); 417 - tc35876x_regw(i2c, LVMX1619, 418 - INPUT_MUX(INPUT_B4, INPUT_B3, INPUT_B1, INPUT_B0)); 419 - tc35876x_regw(i2c, LVMX2023, 420 - INPUT_MUX(LOGIC_0, INPUT_B7, INPUT_B6, INPUT_B5)); 421 - tc35876x_regw(i2c, LVMX2427, 422 - INPUT_MUX(INPUT_R0, INPUT_DE, INPUT_VSYNC, INPUT_HSYNC)); 423 - 424 - /* Enable LVDS transmitter. */ 425 - tc35876x_regw(i2c, LVCFG, BIT(0)); 426 - 427 - /* Clear notifications. Don't write reserved bits. Was write 0xffffffff 428 - * to 0x0288, must be in error?! */ 429 - tc35876x_regw(i2c, DSI_INTCLR, FLD_MASK(31, 30) | FLD_MASK(22, 0)); 430 - } 431 - 432 - #define GPIOPWMCTRL 0x38F 433 - #define PWM0CLKDIV0 0x62 /* low byte */ 434 - #define PWM0CLKDIV1 0x61 /* high byte */ 435 - 436 - #define SYSTEMCLK 19200000UL /* 19.2 MHz */ 437 - #define PWM_FREQUENCY 9600 /* Hz */ 438 - 439 - /* f = baseclk / (clkdiv + 1) => clkdiv = (baseclk - f) / f */ 440 - static inline u16 calc_clkdiv(unsigned long baseclk, unsigned int f) 441 - { 442 - return (baseclk - f) / f; 443 - } 444 - 445 - static void tc35876x_brightness_init(struct drm_device *dev) 446 - { 447 - int ret; 448 - u8 pwmctrl; 449 - u16 clkdiv; 450 - 451 - /* Make sure the PWM reference is the 19.2 MHz system clock. Read first 452 - * instead of setting directly to catch potential conflicts between PWM 453 - * users. */ 454 - ret = intel_scu_ipc_ioread8(GPIOPWMCTRL, &pwmctrl); 455 - if (ret || pwmctrl != 0x01) { 456 - if (ret) 457 - dev_err(dev->dev, "GPIOPWMCTRL read failed\n"); 458 - else 459 - dev_warn(dev->dev, "GPIOPWMCTRL was not set to system clock (pwmctrl = 0x%02x)\n", pwmctrl); 460 - 461 - ret = intel_scu_ipc_iowrite8(GPIOPWMCTRL, 0x01); 462 - if (ret) 463 - dev_err(dev->dev, "GPIOPWMCTRL set failed\n"); 464 - } 465 - 466 - clkdiv = calc_clkdiv(SYSTEMCLK, PWM_FREQUENCY); 467 - 468 - ret = intel_scu_ipc_iowrite8(PWM0CLKDIV1, (clkdiv >> 8) & 0xff); 469 - if (!ret) 470 - ret = intel_scu_ipc_iowrite8(PWM0CLKDIV0, clkdiv & 0xff); 471 - 472 - if (ret) 473 - dev_err(dev->dev, "PWM0CLKDIV set failed\n"); 474 - else 475 - dev_dbg(dev->dev, "PWM0CLKDIV set to 0x%04x (%d Hz)\n", 476 - clkdiv, PWM_FREQUENCY); 477 - } 478 - 479 - #define PWM0DUTYCYCLE 0x67 480 - 481 - void tc35876x_brightness_control(struct drm_device *dev, int level) 482 - { 483 - int ret; 484 - u8 duty_val; 485 - u8 panel_duty_val; 486 - 487 - level = clamp(level, 0, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); 488 - 489 - /* PWM duty cycle 0x00...0x63 corresponds to 0...99% */ 490 - duty_val = level * 0x63 / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL; 491 - 492 - /* I won't pretend to understand this formula. The panel spec is quite 493 - * bad engrish. 494 - */ 495 - panel_duty_val = (2 * level - 100) * 0xA9 / 496 - MDFLD_DSI_BRIGHTNESS_MAX_LEVEL + 0x56; 497 - 498 - ret = intel_scu_ipc_iowrite8(PWM0DUTYCYCLE, duty_val); 499 - if (ret) 500 - dev_err(&tc35876x_client->dev, "%s: ipc write fail\n", 501 - __func__); 502 - 503 - if (cmi_lcd_i2c_client) { 504 - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 505 - PANEL_PWM_MAX, panel_duty_val); 506 - if (ret < 0) 507 - dev_err(&cmi_lcd_i2c_client->dev, "%s: i2c write failed\n", 508 - __func__); 509 - } 510 - } 511 - 512 - void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev) 513 - { 514 - if (WARN(!tc35876x_client, "%s called before probe", __func__)) 515 - return; 516 - 517 - dev_dbg(&tc35876x_client->dev, "%s\n", __func__); 518 - 519 - if (bridge_bl_enable) 520 - gpiod_set_value_cansleep(bridge_bl_enable, 0); 521 - 522 - if (backlight_voltage) 523 - gpiod_set_value_cansleep(backlight_voltage, 0); 524 - } 525 - 526 - void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) 527 - { 528 - struct drm_psb_private *dev_priv = dev->dev_private; 529 - 530 - if (WARN(!tc35876x_client, "%s called before probe", __func__)) 531 - return; 532 - 533 - dev_dbg(&tc35876x_client->dev, "%s\n", __func__); 534 - 535 - if (backlight_voltage) { 536 - gpiod_set_value_cansleep(backlight_voltage, 1); 537 - msleep(260); 538 - } 539 - 540 - if (cmi_lcd_i2c_client) { 541 - int ret; 542 - dev_dbg(&cmi_lcd_i2c_client->dev, "setting TCON\n"); 543 - /* Bit 4 is average_saving. Setting it to 1, the brightness is 544 - * referenced to the average of the frame content. 0 means 545 - * reference to the maximum of frame contents. Bits 3:0 are 546 - * allow_distort. When set to a nonzero value, all color values 547 - * between 255-allow_distort*2 and 255 are mapped to the 548 - * 255-allow_distort*2 value. 549 - */ 550 - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 551 - PANEL_ALLOW_DISTORT, 0x10); 552 - if (ret < 0) 553 - dev_err(&cmi_lcd_i2c_client->dev, 554 - "i2c write failed (%d)\n", ret); 555 - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 556 - PANEL_BYPASS_PWMI, 0); 557 - if (ret < 0) 558 - dev_err(&cmi_lcd_i2c_client->dev, 559 - "i2c write failed (%d)\n", ret); 560 - /* Set minimum brightness value - this is tunable */ 561 - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 562 - PANEL_PWM_MIN, 0x35); 563 - if (ret < 0) 564 - dev_err(&cmi_lcd_i2c_client->dev, 565 - "i2c write failed (%d)\n", ret); 566 - } 567 - 568 - if (bridge_bl_enable) 569 - gpiod_set_value_cansleep(bridge_bl_enable, 1); 570 - 571 - tc35876x_brightness_control(dev, dev_priv->brightness_adjusted); 572 - } 573 - 574 - static struct drm_display_mode *tc35876x_get_config_mode(struct drm_device *dev) 575 - { 576 - struct drm_display_mode *mode; 577 - 578 - dev_dbg(dev->dev, "%s\n", __func__); 579 - 580 - mode = kzalloc(sizeof(*mode), GFP_KERNEL); 581 - if (!mode) 582 - return NULL; 583 - 584 - /* FIXME: do this properly. */ 585 - mode->hdisplay = 1280; 586 - mode->vdisplay = 800; 587 - mode->hsync_start = 1360; 588 - mode->hsync_end = 1400; 589 - mode->htotal = 1440; 590 - mode->vsync_start = 814; 591 - mode->vsync_end = 824; 592 - mode->vtotal = 838; 593 - mode->clock = 33324 << 1; 594 - 595 - dev_info(dev->dev, "hdisplay(w) = %d\n", mode->hdisplay); 596 - dev_info(dev->dev, "vdisplay(h) = %d\n", mode->vdisplay); 597 - dev_info(dev->dev, "HSS = %d\n", mode->hsync_start); 598 - dev_info(dev->dev, "HSE = %d\n", mode->hsync_end); 599 - dev_info(dev->dev, "htotal = %d\n", mode->htotal); 600 - dev_info(dev->dev, "VSS = %d\n", mode->vsync_start); 601 - dev_info(dev->dev, "VSE = %d\n", mode->vsync_end); 602 - dev_info(dev->dev, "vtotal = %d\n", mode->vtotal); 603 - dev_info(dev->dev, "clock = %d\n", mode->clock); 604 - 605 - drm_mode_set_name(mode); 606 - drm_mode_set_crtcinfo(mode, 0); 607 - 608 - mode->type |= DRM_MODE_TYPE_PREFERRED; 609 - 610 - return mode; 611 - } 612 - 613 - /* DV1 Active area 216.96 x 135.6 mm */ 614 - #define DV1_PANEL_WIDTH 217 615 - #define DV1_PANEL_HEIGHT 136 616 - 617 - static int tc35876x_get_panel_info(struct drm_device *dev, int pipe, 618 - struct panel_info *pi) 619 - { 620 - if (!dev || !pi) 621 - return -EINVAL; 622 - 623 - pi->width_mm = DV1_PANEL_WIDTH; 624 - pi->height_mm = DV1_PANEL_HEIGHT; 625 - 626 - return 0; 627 - } 628 - 629 - static int tc35876x_bridge_probe(struct i2c_client *client, 630 - const struct i2c_device_id *id) 631 - { 632 - dev_info(&client->dev, "%s\n", __func__); 633 - 634 - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 635 - dev_err(&client->dev, "%s: i2c_check_functionality() failed\n", 636 - __func__); 637 - return -ENODEV; 638 - } 639 - 640 - bridge_reset = devm_gpiod_get_optional(&client->dev, "bridge-reset", GPIOD_OUT_LOW); 641 - if (IS_ERR(bridge_reset)) 642 - return PTR_ERR(bridge_reset); 643 - if (bridge_reset) 644 - gpiod_set_consumer_name(bridge_reset, "tc35876x bridge reset"); 645 - 646 - bridge_bl_enable = devm_gpiod_get_optional(&client->dev, "bl-en", GPIOD_OUT_LOW); 647 - if (IS_ERR(bridge_bl_enable)) 648 - return PTR_ERR(bridge_bl_enable); 649 - if (bridge_bl_enable) 650 - gpiod_set_consumer_name(bridge_bl_enable, "tc35876x panel bl en"); 651 - 652 - backlight_voltage = devm_gpiod_get_optional(&client->dev, "vadd", GPIOD_OUT_LOW); 653 - if (IS_ERR(backlight_voltage)) 654 - return PTR_ERR(backlight_voltage); 655 - if (backlight_voltage) 656 - gpiod_set_consumer_name(backlight_voltage, "tc35876x panel vadd"); 657 - 658 - tc35876x_client = client; 659 - 660 - return 0; 661 - } 662 - 663 - static int tc35876x_bridge_remove(struct i2c_client *client) 664 - { 665 - dev_dbg(&client->dev, "%s\n", __func__); 666 - 667 - tc35876x_client = NULL; 668 - 669 - return 0; 670 - } 671 - 672 - static const struct i2c_device_id tc35876x_bridge_id[] = { 673 - { "i2c_disp_brig", 0 }, 674 - { } 675 - }; 676 - MODULE_DEVICE_TABLE(i2c, tc35876x_bridge_id); 677 - 678 - static struct i2c_driver tc35876x_bridge_i2c_driver = { 679 - .driver = { 680 - .name = "i2c_disp_brig", 681 - }, 682 - .id_table = tc35876x_bridge_id, 683 - .probe = tc35876x_bridge_probe, 684 - .remove = tc35876x_bridge_remove, 685 - }; 686 - 687 - /* LCD panel I2C */ 688 - static int cmi_lcd_i2c_probe(struct i2c_client *client, 689 - const struct i2c_device_id *id) 690 - { 691 - dev_info(&client->dev, "%s\n", __func__); 692 - 693 - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 694 - dev_err(&client->dev, "%s: i2c_check_functionality() failed\n", 695 - __func__); 696 - return -ENODEV; 697 - } 698 - 699 - cmi_lcd_i2c_client = client; 700 - 701 - return 0; 702 - } 703 - 704 - static int cmi_lcd_i2c_remove(struct i2c_client *client) 705 - { 706 - dev_dbg(&client->dev, "%s\n", __func__); 707 - 708 - cmi_lcd_i2c_client = NULL; 709 - 710 - return 0; 711 - } 712 - 713 - static const struct i2c_device_id cmi_lcd_i2c_id[] = { 714 - { "cmi-lcd", 0 }, 715 - { } 716 - }; 717 - MODULE_DEVICE_TABLE(i2c, cmi_lcd_i2c_id); 718 - 719 - static struct i2c_driver cmi_lcd_i2c_driver = { 720 - .driver = { 721 - .name = "cmi-lcd", 722 - }, 723 - .id_table = cmi_lcd_i2c_id, 724 - .probe = cmi_lcd_i2c_probe, 725 - .remove = cmi_lcd_i2c_remove, 726 - }; 727 - 728 - /* HACK to create I2C device while it's not created by platform code */ 729 - #define CMI_LCD_I2C_ADAPTER 2 730 - #define CMI_LCD_I2C_ADDR 0x60 731 - 732 - static int cmi_lcd_hack_create_device(void) 733 - { 734 - struct i2c_adapter *adapter; 735 - struct i2c_client *client; 736 - struct i2c_board_info info = { 737 - .type = "cmi-lcd", 738 - .addr = CMI_LCD_I2C_ADDR, 739 - }; 740 - 741 - pr_debug("%s\n", __func__); 742 - 743 - adapter = i2c_get_adapter(CMI_LCD_I2C_ADAPTER); 744 - if (!adapter) { 745 - pr_err("%s: i2c_get_adapter(%d) failed\n", __func__, 746 - CMI_LCD_I2C_ADAPTER); 747 - return -EINVAL; 748 - } 749 - 750 - client = i2c_new_client_device(adapter, &info); 751 - if (IS_ERR(client)) { 752 - pr_err("%s: creating I2C device failed\n", __func__); 753 - i2c_put_adapter(adapter); 754 - return PTR_ERR(client); 755 - } 756 - 757 - return 0; 758 - } 759 - 760 - static const struct drm_encoder_helper_funcs tc35876x_encoder_helper_funcs = { 761 - .dpms = mdfld_dsi_dpi_dpms, 762 - .mode_fixup = mdfld_dsi_dpi_mode_fixup, 763 - .prepare = mdfld_dsi_dpi_prepare, 764 - .mode_set = mdfld_dsi_dpi_mode_set, 765 - .commit = mdfld_dsi_dpi_commit, 766 - }; 767 - 768 - const struct panel_funcs mdfld_tc35876x_funcs = { 769 - .encoder_helper_funcs = &tc35876x_encoder_helper_funcs, 770 - .get_config_mode = tc35876x_get_config_mode, 771 - .get_panel_info = tc35876x_get_panel_info, 772 - }; 773 - 774 - void tc35876x_init(struct drm_device *dev) 775 - { 776 - int r; 777 - 778 - dev_dbg(dev->dev, "%s\n", __func__); 779 - 780 - cmi_lcd_hack_create_device(); 781 - 782 - r = i2c_add_driver(&cmi_lcd_i2c_driver); 783 - if (r < 0) 784 - dev_err(dev->dev, 785 - "%s: i2c_add_driver() for %s failed (%d)\n", 786 - __func__, cmi_lcd_i2c_driver.driver.name, r); 787 - 788 - r = i2c_add_driver(&tc35876x_bridge_i2c_driver); 789 - if (r < 0) 790 - dev_err(dev->dev, 791 - "%s: i2c_add_driver() for %s failed (%d)\n", 792 - __func__, tc35876x_bridge_i2c_driver.driver.name, r); 793 - 794 - tc35876x_brightness_init(dev); 795 - } 796 - 797 - void tc35876x_exit(void) 798 - { 799 - pr_debug("%s\n", __func__); 800 - 801 - i2c_del_driver(&tc35876x_bridge_i2c_driver); 802 - 803 - if (cmi_lcd_i2c_client) 804 - i2c_del_driver(&cmi_lcd_i2c_driver); 805 - }
-38
drivers/gpu/drm/gma500/tc35876x-dsi-lvds.h
··· 1 - /* 2 - * Copyright © 2011 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 - */ 24 - 25 - #ifndef __MDFLD_DSI_LVDS_BRIDGE_H__ 26 - #define __MDFLD_DSI_LVDS_BRIDGE_H__ 27 - 28 - void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state); 29 - void tc35876x_configure_lvds_bridge(struct drm_device *dev); 30 - void tc35876x_brightness_control(struct drm_device *dev, int level); 31 - void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev); 32 - void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev); 33 - void tc35876x_init(struct drm_device *dev); 34 - void tc35876x_exit(void); 35 - 36 - extern const struct panel_funcs mdfld_tc35876x_funcs; 37 - 38 - #endif /*__MDFLD_DSI_LVDS_BRIDGE_H__*/