diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 149 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 4 |
3 files changed, 195 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5e58a44c5fe3..56cb79d4a980 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1779,6 +1779,47 @@ | |||
1779 | #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) | 1779 | #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) |
1780 | #define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B) | 1780 | #define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B) |
1781 | 1781 | ||
1782 | /* HSW eDP PSR registers */ | ||
1783 | #define EDP_PSR_CTL 0x64800 | ||
1784 | #define EDP_PSR_ENABLE (1<<31) | ||
1785 | #define EDP_PSR_LINK_DISABLE (0<<27) | ||
1786 | #define EDP_PSR_LINK_STANDBY (1<<27) | ||
1787 | #define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3<<25) | ||
1788 | #define EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES (0<<25) | ||
1789 | #define EDP_PSR_MIN_LINK_ENTRY_TIME_4_LINES (1<<25) | ||
1790 | #define EDP_PSR_MIN_LINK_ENTRY_TIME_2_LINES (2<<25) | ||
1791 | #define EDP_PSR_MIN_LINK_ENTRY_TIME_0_LINES (3<<25) | ||
1792 | #define EDP_PSR_MAX_SLEEP_TIME_SHIFT 20 | ||
1793 | #define EDP_PSR_SKIP_AUX_EXIT (1<<12) | ||
1794 | #define EDP_PSR_TP1_TP2_SEL (0<<11) | ||
1795 | #define EDP_PSR_TP1_TP3_SEL (1<<11) | ||
1796 | #define EDP_PSR_TP2_TP3_TIME_500us (0<<8) | ||
1797 | #define EDP_PSR_TP2_TP3_TIME_100us (1<<8) | ||
1798 | #define EDP_PSR_TP2_TP3_TIME_2500us (2<<8) | ||
1799 | #define EDP_PSR_TP2_TP3_TIME_0us (3<<8) | ||
1800 | #define EDP_PSR_TP1_TIME_500us (0<<4) | ||
1801 | #define EDP_PSR_TP1_TIME_100us (1<<4) | ||
1802 | #define EDP_PSR_TP1_TIME_2500us (2<<4) | ||
1803 | #define EDP_PSR_TP1_TIME_0us (3<<4) | ||
1804 | #define EDP_PSR_IDLE_FRAME_SHIFT 0 | ||
1805 | |||
1806 | #define EDP_PSR_AUX_CTL 0x64810 | ||
1807 | #define EDP_PSR_AUX_DATA1 0x64814 | ||
1808 | #define EDP_PSR_DPCD_COMMAND 0x80060000 | ||
1809 | #define EDP_PSR_AUX_DATA2 0x64818 | ||
1810 | #define EDP_PSR_DPCD_NORMAL_OPERATION (1<<24) | ||
1811 | #define EDP_PSR_AUX_DATA3 0x6481c | ||
1812 | #define EDP_PSR_AUX_DATA4 0x64820 | ||
1813 | #define EDP_PSR_AUX_DATA5 0x64824 | ||
1814 | |||
1815 | #define EDP_PSR_STATUS_CTL 0x64840 | ||
1816 | #define EDP_PSR_STATUS_STATE_MASK (7<<29) | ||
1817 | |||
1818 | #define EDP_PSR_DEBUG_CTL 0x64860 | ||
1819 | #define EDP_PSR_DEBUG_MASK_LPSP (1<<27) | ||
1820 | #define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) | ||
1821 | #define EDP_PSR_DEBUG_MASK_HPD (1<<25) | ||
1822 | |||
1782 | /* VGA port control */ | 1823 | /* VGA port control */ |
1783 | #define ADPA 0x61100 | 1824 | #define ADPA 0x61100 |
1784 | #define PCH_ADPA 0xe1100 | 1825 | #define PCH_ADPA 0xe1100 |
@@ -2048,6 +2089,7 @@ | |||
2048 | * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte | 2089 | * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte |
2049 | * of the infoframe structure specified by CEA-861. */ | 2090 | * of the infoframe structure specified by CEA-861. */ |
2050 | #define VIDEO_DIP_DATA_SIZE 32 | 2091 | #define VIDEO_DIP_DATA_SIZE 32 |
2092 | #define VIDEO_DIP_VSC_DATA_SIZE 36 | ||
2051 | #define VIDEO_DIP_CTL 0x61170 | 2093 | #define VIDEO_DIP_CTL 0x61170 |
2052 | /* Pre HSW: */ | 2094 | /* Pre HSW: */ |
2053 | #define VIDEO_DIP_ENABLE (1 << 31) | 2095 | #define VIDEO_DIP_ENABLE (1 << 31) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1ef83dc26de0..bb3593db42e9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1378,6 +1378,153 @@ static bool is_edp_psr(struct intel_dp *intel_dp) | |||
1378 | intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; | 1378 | intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; |
1379 | } | 1379 | } |
1380 | 1380 | ||
1381 | static bool intel_edp_is_psr_enabled(struct drm_device *dev) | ||
1382 | { | ||
1383 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1384 | |||
1385 | if (!IS_HASWELL(dev)) | ||
1386 | return false; | ||
1387 | |||
1388 | return I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE; | ||
1389 | } | ||
1390 | |||
1391 | static void intel_edp_psr_write_vsc(struct intel_dp *intel_dp, | ||
1392 | struct edp_vsc_psr *vsc_psr) | ||
1393 | { | ||
1394 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | ||
1395 | struct drm_device *dev = dig_port->base.base.dev; | ||
1396 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1397 | struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); | ||
1398 | u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder); | ||
1399 | u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder); | ||
1400 | uint32_t *data = (uint32_t *) vsc_psr; | ||
1401 | unsigned int i; | ||
1402 | |||
1403 | /* As per BSPec (Pipe Video Data Island Packet), we need to disable | ||
1404 | the video DIP being updated before program video DIP data buffer | ||
1405 | registers for DIP being updated. */ | ||
1406 | I915_WRITE(ctl_reg, 0); | ||
1407 | POSTING_READ(ctl_reg); | ||
1408 | |||
1409 | for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) { | ||
1410 | if (i < sizeof(struct edp_vsc_psr)) | ||
1411 | I915_WRITE(data_reg + i, *data++); | ||
1412 | else | ||
1413 | I915_WRITE(data_reg + i, 0); | ||
1414 | } | ||
1415 | |||
1416 | I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW); | ||
1417 | POSTING_READ(ctl_reg); | ||
1418 | } | ||
1419 | |||
1420 | static void intel_edp_psr_setup(struct intel_dp *intel_dp) | ||
1421 | { | ||
1422 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
1423 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1424 | struct edp_vsc_psr psr_vsc; | ||
1425 | |||
1426 | if (intel_dp->psr_setup_done) | ||
1427 | return; | ||
1428 | |||
1429 | /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ | ||
1430 | memset(&psr_vsc, 0, sizeof(psr_vsc)); | ||
1431 | psr_vsc.sdp_header.HB0 = 0; | ||
1432 | psr_vsc.sdp_header.HB1 = 0x7; | ||
1433 | psr_vsc.sdp_header.HB2 = 0x2; | ||
1434 | psr_vsc.sdp_header.HB3 = 0x8; | ||
1435 | intel_edp_psr_write_vsc(intel_dp, &psr_vsc); | ||
1436 | |||
1437 | /* Avoid continuous PSR exit by masking memup and hpd */ | ||
1438 | I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP | | ||
1439 | EDP_PSR_DEBUG_MASK_HPD); | ||
1440 | |||
1441 | intel_dp->psr_setup_done = true; | ||
1442 | } | ||
1443 | |||
1444 | static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) | ||
1445 | { | ||
1446 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
1447 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1448 | uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp); | ||
1449 | int precharge = 0x3; | ||
1450 | int msg_size = 5; /* Header(4) + Message(1) */ | ||
1451 | |||
1452 | /* Enable PSR in sink */ | ||
1453 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) | ||
1454 | intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, | ||
1455 | DP_PSR_ENABLE & | ||
1456 | ~DP_PSR_MAIN_LINK_ACTIVE); | ||
1457 | else | ||
1458 | intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, | ||
1459 | DP_PSR_ENABLE | | ||
1460 | DP_PSR_MAIN_LINK_ACTIVE); | ||
1461 | |||
1462 | /* Setup AUX registers */ | ||
1463 | I915_WRITE(EDP_PSR_AUX_DATA1, EDP_PSR_DPCD_COMMAND); | ||
1464 | I915_WRITE(EDP_PSR_AUX_DATA2, EDP_PSR_DPCD_NORMAL_OPERATION); | ||
1465 | I915_WRITE(EDP_PSR_AUX_CTL, | ||
1466 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
1467 | (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
1468 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
1469 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); | ||
1470 | } | ||
1471 | |||
1472 | static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) | ||
1473 | { | ||
1474 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
1475 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1476 | uint32_t max_sleep_time = 0x1f; | ||
1477 | uint32_t idle_frames = 1; | ||
1478 | uint32_t val = 0x0; | ||
1479 | |||
1480 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) { | ||
1481 | val |= EDP_PSR_LINK_STANDBY; | ||
1482 | val |= EDP_PSR_TP2_TP3_TIME_0us; | ||
1483 | val |= EDP_PSR_TP1_TIME_0us; | ||
1484 | val |= EDP_PSR_SKIP_AUX_EXIT; | ||
1485 | } else | ||
1486 | val |= EDP_PSR_LINK_DISABLE; | ||
1487 | |||
1488 | I915_WRITE(EDP_PSR_CTL, val | | ||
1489 | EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES | | ||
1490 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | | ||
1491 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | | ||
1492 | EDP_PSR_ENABLE); | ||
1493 | } | ||
1494 | |||
1495 | void intel_edp_psr_enable(struct intel_dp *intel_dp) | ||
1496 | { | ||
1497 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
1498 | |||
1499 | if (!is_edp_psr(intel_dp) || intel_edp_is_psr_enabled(dev)) | ||
1500 | return; | ||
1501 | |||
1502 | /* Setup PSR once */ | ||
1503 | intel_edp_psr_setup(intel_dp); | ||
1504 | |||
1505 | /* Enable PSR on the panel */ | ||
1506 | intel_edp_psr_enable_sink(intel_dp); | ||
1507 | |||
1508 | /* Enable PSR on the host */ | ||
1509 | intel_edp_psr_enable_source(intel_dp); | ||
1510 | } | ||
1511 | |||
1512 | void intel_edp_psr_disable(struct intel_dp *intel_dp) | ||
1513 | { | ||
1514 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
1515 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1516 | |||
1517 | if (!intel_edp_is_psr_enabled(dev)) | ||
1518 | return; | ||
1519 | |||
1520 | I915_WRITE(EDP_PSR_CTL, I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE); | ||
1521 | |||
1522 | /* Wait till PSR is idle */ | ||
1523 | if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) & | ||
1524 | EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) | ||
1525 | DRM_ERROR("Timed out waiting for PSR Idle State\n"); | ||
1526 | } | ||
1527 | |||
1381 | static void intel_disable_dp(struct intel_encoder *encoder) | 1528 | static void intel_disable_dp(struct intel_encoder *encoder) |
1382 | { | 1529 | { |
1383 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 1530 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
@@ -3189,6 +3336,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | |||
3189 | WARN(error, "intel_dp_i2c_init failed with error %d for port %c\n", | 3336 | WARN(error, "intel_dp_i2c_init failed with error %d for port %c\n", |
3190 | error, port_name(port)); | 3337 | error, port_name(port)); |
3191 | 3338 | ||
3339 | intel_dp->psr_setup_done = false; | ||
3340 | |||
3192 | if (!intel_edp_init_connector(intel_dp, intel_connector)) { | 3341 | if (!intel_edp_init_connector(intel_dp, intel_connector)) { |
3193 | i2c_del_adapter(&intel_dp->adapter); | 3342 | i2c_del_adapter(&intel_dp->adapter); |
3194 | if (is_edp(intel_dp)) { | 3343 | if (is_edp(intel_dp)) { |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d25726d5307f..ff36a40103eb 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -499,6 +499,7 @@ struct intel_dp { | |||
499 | int backlight_off_delay; | 499 | int backlight_off_delay; |
500 | struct delayed_work panel_vdd_work; | 500 | struct delayed_work panel_vdd_work; |
501 | bool want_panel_vdd; | 501 | bool want_panel_vdd; |
502 | bool psr_setup_done; | ||
502 | struct intel_connector *attached_connector; | 503 | struct intel_connector *attached_connector; |
503 | }; | 504 | }; |
504 | 505 | ||
@@ -834,4 +835,7 @@ extern bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, | |||
834 | enum transcoder pch_transcoder, | 835 | enum transcoder pch_transcoder, |
835 | bool enable); | 836 | bool enable); |
836 | 837 | ||
838 | extern void intel_edp_psr_enable(struct intel_dp *intel_dp); | ||
839 | extern void intel_edp_psr_disable(struct intel_dp *intel_dp); | ||
840 | |||
837 | #endif /* __INTEL_DRV_H__ */ | 841 | #endif /* __INTEL_DRV_H__ */ |