| @@ -41,9 +41,11 @@ · 40 unmodified lines |
| 41 | | 41 | |
| 42 | #include "i915_drv.h" | 42 | #include "i915_drv.h" |
| 43 | #include "i915_reg.h" | 43 | #include "i915_reg.h" |
| | 44 | #include "intel_de.h" |
| 44 | #include "intel_display_types.h" | 45 | #include "intel_display_types.h" |
| 45 | #include "intel_dsi.h" | 46 | #include "intel_dsi.h" |
| 46 | #include "intel_dsi_vbt.h" | 47 | #include "intel_dsi_vbt.h" |
| | 48 | #include "intel_gmbus_regs.h" |
| 47 | #include "vlv_dsi.h" | 49 | #include "vlv_dsi.h" |
| 48 | #include "vlv_dsi_regs.h" | 50 | #include "vlv_dsi_regs.h" |
| 49 | #include "vlv_sideband.h" | 51 | #include "vlv_sideband.h" |
| @@ -377,6 +379,85 @@ static void icl_exec_gpio(struct intel_connector *connector, · 327 unmodified lines |
| 377 | drm_dbg_kms(&dev_priv->drm, "Skipping ICL GPIO element execution\n"); | 379 | drm_dbg_kms(&dev_priv->drm, "Skipping ICL GPIO element execution\n"); |
| 378 | } | 380 | } |
| 379 | | 381 | |
| | 382 | enum { |
| | 383 | MIPI_RESET_1 = 0, |
| | 384 | MIPI_AVDD_EN_1, |
| | 385 | MIPI_BKLT_EN_1, |
| | 386 | MIPI_AVEE_EN_1, |
| | 387 | MIPI_VIO_EN_1, |
| | 388 | MIPI_RESET_2, |
| | 389 | MIPI_AVDD_EN_2, |
| | 390 | MIPI_BKLT_EN_2, |
| | 391 | MIPI_AVEE_EN_2, |
| | 392 | MIPI_VIO_EN_2, |
| | 393 | }; |
| | 394 | |
| | 395 | static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv, |
| | 396 | int gpio, bool value) |
| | 397 | { |
| | 398 | int index; |
| | 399 | |
| | 400 | if (drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) == 11 && gpio >= MIPI_RESET_2)) |
| | 401 | return; |
| | 402 | |
| | 403 | switch (gpio) { |
| | 404 | case MIPI_RESET_1: |
| | 405 | case MIPI_RESET_2: |
| | 406 | index = gpio == MIPI_RESET_1 ? HPD_PORT_A : HPD_PORT_B; |
| | 407 | |
| | 408 | /* |
| | 409 | * Disable HPD to set the pin to output, and set output |
| | 410 | * value. The HPD pin should not be enabled for DSI anyway, |
| | 411 | * assuming the board design and VBT are sane, and the pin isn't |
| | 412 | * used by a non-DSI encoder. |
| | 413 | * |
| | 414 | * The locking protects against concurrent SHOTPLUG_CTL_DDI |
| | 415 | * modifications in irq setup and handling. |
| | 416 | */ |
| | 417 | spin_lock_irq(&dev_priv->irq_lock); |
| | 418 | intel_de_rmw(dev_priv, SHOTPLUG_CTL_DDI, |
| | 419 | SHOTPLUG_CTL_DDI_HPD_ENABLE(index) | |
| | 420 | SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index), |
| | 421 | value ? SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index) : 0); |
| | 422 | spin_unlock_irq(&dev_priv->irq_lock); |
| | 423 | break; |
| | 424 | case MIPI_AVDD_EN_1: |
| | 425 | case MIPI_AVDD_EN_2: |
| | 426 | index = gpio == MIPI_AVDD_EN_1 ? 0 : 1; |
| | 427 | |
| | 428 | intel_de_rmw(dev_priv, PP_CONTROL(index), PANEL_POWER_ON, |
| | 429 | value ? PANEL_POWER_ON : 0); |
| | 430 | break; |
| | 431 | case MIPI_BKLT_EN_1: |
| | 432 | case MIPI_BKLT_EN_2: |
| | 433 | index = gpio == MIPI_AVDD_EN_1 ? 0 : 1; |
| | 434 | |
| | 435 | intel_de_rmw(dev_priv, PP_CONTROL(index), EDP_BLC_ENABLE, |
| | 436 | value ? EDP_BLC_ENABLE : 0); |
| | 437 | break; |
| | 438 | case MIPI_AVEE_EN_1: |
| | 439 | case MIPI_AVEE_EN_2: |
| | 440 | index = gpio == MIPI_AVEE_EN_1 ? 1 : 2; |
| | 441 | |
| | 442 | intel_de_rmw(dev_priv, GPIO(dev_priv, index), |
| | 443 | GPIO_CLOCK_VAL_OUT, |
| | 444 | GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_DIR_OUT | |
| | 445 | GPIO_CLOCK_VAL_MASK | (value ? GPIO_CLOCK_VAL_OUT : 0)); |
| | 446 | break; |
| | 447 | case MIPI_VIO_EN_1: |
| | 448 | case MIPI_VIO_EN_2: |
| | 449 | index = gpio == MIPI_VIO_EN_1 ? 1 : 2; |
| | 450 | |
| | 451 | intel_de_rmw(dev_priv, GPIO(dev_priv, index), |
| | 452 | GPIO_DATA_VAL_OUT, |
| | 453 | GPIO_DATA_DIR_MASK | GPIO_DATA_DIR_OUT | |
| | 454 | GPIO_DATA_VAL_MASK | (value ? GPIO_DATA_VAL_OUT : 0)); |
| | 455 | break; |
| | 456 | default: |
| | 457 | MISSING_CASE(gpio); |
| | 458 | } |
| | 459 | } |
| | 460 | |
| 380 | static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) | 461 | static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) |
| 381 | { | 462 | { |
| 382 | struct drm_device *dev = intel_dsi->base.base.dev; | 463 | struct drm_device *dev = intel_dsi->base.base.dev; |
| @@ -384,8 +465,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) · 1 unmodified line |
| 384 | struct intel_connector *connector = intel_dsi->attached_connector; | 465 | struct intel_connector *connector = intel_dsi->attached_connector; |
| 385 | u8 gpio_source, gpio_index = 0, gpio_number; | 466 | u8 gpio_source, gpio_index = 0, gpio_number; |
| 386 | bool value; | 467 | bool value; |
| 387 | | 468 | bool native = DISPLAY_VER(dev_priv) >= 11; |
| 388 | drm_dbg_kms(&dev_priv->drm, "\n"); | | |
| 389 | | 469 | |
| 390 | if (connector->panel.vbt.dsi.seq_version >= 3) | 470 | if (connector->panel.vbt.dsi.seq_version >= 3) |
| 391 | gpio_index = *data++; | 471 | gpio_index = *data++; |
| @@ -398,10 +478,18 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) · 6 unmodified lines |
| 398 | else | 478 | else |
| 399 | gpio_source = 0; | 479 | gpio_source = 0; |
| 400 | | 480 | |
| | 481 | if (connector->panel.vbt.dsi.seq_version >= 4 && *data & BIT(1)) |
| | 482 | native = false; |
| | 483 | |
| 401 | /* pull up/down */ | 484 | /* pull up/down */ |
| 402 | value = *data++ & 1; | 485 | value = *data++ & 1; |
| 403 | | 486 | |
| 404 | if (DISPLAY_VER(dev_priv) >= 11) | 487 | drm_dbg_kms(&dev_priv->drm, "GPIO index %u, number %u, source %u, native %s, set to %s\n", |
| | 488 | gpio_index, gpio_number, gpio_source, str_yes_no(native), str_on_off(value)); |
| | 489 | |
| | 490 | if (native) |
| | 491 | icl_native_gpio_set_value(dev_priv, gpio_number, value); |
| | 492 | else if (DISPLAY_VER(dev_priv) >= 11) |
| 405 | icl_exec_gpio(connector, gpio_source, gpio_index, value); | 493 | icl_exec_gpio(connector, gpio_source, gpio_index, value); |
| 406 | else if (IS_VALLEYVIEW(dev_priv)) | 494 | else if (IS_VALLEYVIEW(dev_priv)) |
| 407 | vlv_exec_gpio(connector, gpio_source, gpio_number, value); | 495 | vlv_exec_gpio(connector, gpio_source, gpio_number, value); |