diff options
32 files changed, 437 insertions, 387 deletions
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 6c6e81a9eaf4..a8669330b456 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl | |||
@@ -1579,194 +1579,6 @@ void intel_crt_init(struct drm_device *dev) | |||
1579 | entities. | 1579 | entities. |
1580 | </para> | 1580 | </para> |
1581 | <sect2> | 1581 | <sect2> |
1582 | <title>Legacy CRTC Helper Operations</title> | ||
1583 | <itemizedlist> | ||
1584 | <listitem id="drm-helper-crtc-mode-fixup"> | ||
1585 | <synopsis>bool (*mode_fixup)(struct drm_crtc *crtc, | ||
1586 | const struct drm_display_mode *mode, | ||
1587 | struct drm_display_mode *adjusted_mode);</synopsis> | ||
1588 | <para> | ||
1589 | Let CRTCs adjust the requested mode or reject it completely. This | ||
1590 | operation returns true if the mode is accepted (possibly after being | ||
1591 | adjusted) or false if it is rejected. | ||
1592 | </para> | ||
1593 | <para> | ||
1594 | The <methodname>mode_fixup</methodname> operation should reject the | ||
1595 | mode if it can't reasonably use it. The definition of "reasonable" | ||
1596 | is currently fuzzy in this context. One possible behaviour would be | ||
1597 | to set the adjusted mode to the panel timings when a fixed-mode | ||
1598 | panel is used with hardware capable of scaling. Another behaviour | ||
1599 | would be to accept any input mode and adjust it to the closest mode | ||
1600 | supported by the hardware (FIXME: This needs to be clarified). | ||
1601 | </para> | ||
1602 | </listitem> | ||
1603 | <listitem> | ||
1604 | <synopsis>int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, | ||
1605 | struct drm_framebuffer *old_fb)</synopsis> | ||
1606 | <para> | ||
1607 | Move the CRTC on the current frame buffer (stored in | ||
1608 | <literal>crtc->fb</literal>) to position (x,y). Any of the frame | ||
1609 | buffer, x position or y position may have been modified. | ||
1610 | </para> | ||
1611 | <para> | ||
1612 | This helper operation is optional. If not provided, the | ||
1613 | <function>drm_crtc_helper_set_config</function> function will fall | ||
1614 | back to the <methodname>mode_set</methodname> helper operation. | ||
1615 | </para> | ||
1616 | <note><para> | ||
1617 | FIXME: Why are x and y passed as arguments, as they can be accessed | ||
1618 | through <literal>crtc->x</literal> and | ||
1619 | <literal>crtc->y</literal>? | ||
1620 | </para></note> | ||
1621 | </listitem> | ||
1622 | <listitem> | ||
1623 | <synopsis>void (*prepare)(struct drm_crtc *crtc);</synopsis> | ||
1624 | <para> | ||
1625 | Prepare the CRTC for mode setting. This operation is called after | ||
1626 | validating the requested mode. Drivers use it to perform | ||
1627 | device-specific operations required before setting the new mode. | ||
1628 | </para> | ||
1629 | </listitem> | ||
1630 | <listitem> | ||
1631 | <synopsis>int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, | ||
1632 | struct drm_display_mode *adjusted_mode, int x, int y, | ||
1633 | struct drm_framebuffer *old_fb);</synopsis> | ||
1634 | <para> | ||
1635 | Set a new mode, position and frame buffer. Depending on the device | ||
1636 | requirements, the mode can be stored internally by the driver and | ||
1637 | applied in the <methodname>commit</methodname> operation, or | ||
1638 | programmed to the hardware immediately. | ||
1639 | </para> | ||
1640 | <para> | ||
1641 | The <methodname>mode_set</methodname> operation returns 0 on success | ||
1642 | or a negative error code if an error occurs. | ||
1643 | </para> | ||
1644 | </listitem> | ||
1645 | <listitem> | ||
1646 | <synopsis>void (*commit)(struct drm_crtc *crtc);</synopsis> | ||
1647 | <para> | ||
1648 | Commit a mode. This operation is called after setting the new mode. | ||
1649 | Upon return the device must use the new mode and be fully | ||
1650 | operational. | ||
1651 | </para> | ||
1652 | </listitem> | ||
1653 | </itemizedlist> | ||
1654 | </sect2> | ||
1655 | <sect2> | ||
1656 | <title>Encoder Helper Operations</title> | ||
1657 | <itemizedlist> | ||
1658 | <listitem> | ||
1659 | <synopsis>bool (*mode_fixup)(struct drm_encoder *encoder, | ||
1660 | const struct drm_display_mode *mode, | ||
1661 | struct drm_display_mode *adjusted_mode);</synopsis> | ||
1662 | <para> | ||
1663 | Let encoders adjust the requested mode or reject it completely. This | ||
1664 | operation returns true if the mode is accepted (possibly after being | ||
1665 | adjusted) or false if it is rejected. See the | ||
1666 | <link linkend="drm-helper-crtc-mode-fixup">mode_fixup CRTC helper | ||
1667 | operation</link> for an explanation of the allowed adjustments. | ||
1668 | </para> | ||
1669 | </listitem> | ||
1670 | <listitem> | ||
1671 | <synopsis>void (*prepare)(struct drm_encoder *encoder);</synopsis> | ||
1672 | <para> | ||
1673 | Prepare the encoder for mode setting. This operation is called after | ||
1674 | validating the requested mode. Drivers use it to perform | ||
1675 | device-specific operations required before setting the new mode. | ||
1676 | </para> | ||
1677 | </listitem> | ||
1678 | <listitem> | ||
1679 | <synopsis>void (*mode_set)(struct drm_encoder *encoder, | ||
1680 | struct drm_display_mode *mode, | ||
1681 | struct drm_display_mode *adjusted_mode);</synopsis> | ||
1682 | <para> | ||
1683 | Set a new mode. Depending on the device requirements, the mode can | ||
1684 | be stored internally by the driver and applied in the | ||
1685 | <methodname>commit</methodname> operation, or programmed to the | ||
1686 | hardware immediately. | ||
1687 | </para> | ||
1688 | </listitem> | ||
1689 | <listitem> | ||
1690 | <synopsis>void (*commit)(struct drm_encoder *encoder);</synopsis> | ||
1691 | <para> | ||
1692 | Commit a mode. This operation is called after setting the new mode. | ||
1693 | Upon return the device must use the new mode and be fully | ||
1694 | operational. | ||
1695 | </para> | ||
1696 | </listitem> | ||
1697 | </itemizedlist> | ||
1698 | </sect2> | ||
1699 | <sect2> | ||
1700 | <title>Connector Helper Operations</title> | ||
1701 | <itemizedlist> | ||
1702 | <listitem> | ||
1703 | <synopsis>struct drm_encoder *(*best_encoder)(struct drm_connector *connector);</synopsis> | ||
1704 | <para> | ||
1705 | Return a pointer to the best encoder for the connecter. Device that | ||
1706 | map connectors to encoders 1:1 simply return the pointer to the | ||
1707 | associated encoder. This operation is mandatory. | ||
1708 | </para> | ||
1709 | </listitem> | ||
1710 | <listitem> | ||
1711 | <synopsis>int (*get_modes)(struct drm_connector *connector);</synopsis> | ||
1712 | <para> | ||
1713 | Fill the connector's <structfield>probed_modes</structfield> list | ||
1714 | by parsing EDID data with <function>drm_add_edid_modes</function>, | ||
1715 | adding standard VESA DMT modes with <function>drm_add_modes_noedid</function>, | ||
1716 | or calling <function>drm_mode_probed_add</function> directly for every | ||
1717 | supported mode and return the number of modes it has detected. This | ||
1718 | operation is mandatory. | ||
1719 | </para> | ||
1720 | <para> | ||
1721 | Note that the caller function will automatically add standard VESA | ||
1722 | DMT modes up to 1024x768 if the <methodname>get_modes</methodname> | ||
1723 | helper operation returns no mode and if the connector status is | ||
1724 | connector_status_connected. There is no need to call | ||
1725 | <function>drm_add_edid_modes</function> manually in that case. | ||
1726 | </para> | ||
1727 | <para> | ||
1728 | The <structfield>vrefresh</structfield> value is computed by | ||
1729 | <function>drm_helper_probe_single_connector_modes</function>. | ||
1730 | </para> | ||
1731 | <para> | ||
1732 | When parsing EDID data, <function>drm_add_edid_modes</function> fills the | ||
1733 | connector <structfield>display_info</structfield> | ||
1734 | <structfield>width_mm</structfield> and | ||
1735 | <structfield>height_mm</structfield> fields. When creating modes | ||
1736 | manually the <methodname>get_modes</methodname> helper operation must | ||
1737 | set the <structfield>display_info</structfield> | ||
1738 | <structfield>width_mm</structfield> and | ||
1739 | <structfield>height_mm</structfield> fields if they haven't been set | ||
1740 | already (for instance at initialization time when a fixed-size panel is | ||
1741 | attached to the connector). The mode <structfield>width_mm</structfield> | ||
1742 | and <structfield>height_mm</structfield> fields are only used internally | ||
1743 | during EDID parsing and should not be set when creating modes manually. | ||
1744 | </para> | ||
1745 | </listitem> | ||
1746 | <listitem> | ||
1747 | <synopsis>int (*mode_valid)(struct drm_connector *connector, | ||
1748 | struct drm_display_mode *mode);</synopsis> | ||
1749 | <para> | ||
1750 | Verify whether a mode is valid for the connector. Return MODE_OK for | ||
1751 | supported modes and one of the enum drm_mode_status values (MODE_*) | ||
1752 | for unsupported modes. This operation is optional. | ||
1753 | </para> | ||
1754 | <para> | ||
1755 | As the mode rejection reason is currently not used beside for | ||
1756 | immediately removing the unsupported mode, an implementation can | ||
1757 | return MODE_BAD regardless of the exact reason why the mode is not | ||
1758 | valid. | ||
1759 | </para> | ||
1760 | <note><para> | ||
1761 | Note that the <methodname>mode_valid</methodname> helper operation is | ||
1762 | only called for modes detected by the device, and | ||
1763 | <emphasis>not</emphasis> for modes set by the user through the CRTC | ||
1764 | <methodname>set_config</methodname> operation. | ||
1765 | </para></note> | ||
1766 | </listitem> | ||
1767 | </itemizedlist> | ||
1768 | </sect2> | ||
1769 | <sect2> | ||
1770 | <title>Atomic Modeset Helper Functions Reference</title> | 1582 | <title>Atomic Modeset Helper Functions Reference</title> |
1771 | <sect3> | 1583 | <sect3> |
1772 | <title>Overview</title> | 1584 | <title>Overview</title> |
@@ -3625,41 +3437,63 @@ int num_ioctls;</synopsis> | |||
3625 | 3437 | ||
3626 | <chapter id="modes_of_use"> | 3438 | <chapter id="modes_of_use"> |
3627 | <title>Modes of Use</title> | 3439 | <title>Modes of Use</title> |
3628 | <sect1> | 3440 | <sect1> |
3629 | <title>Manual switching and manual power control</title> | 3441 | <title>Manual switching and manual power control</title> |
3630 | !Pdrivers/gpu/vga/vga_switcheroo.c Manual switching and manual power control | 3442 | !Pdrivers/gpu/vga/vga_switcheroo.c Manual switching and manual power control |
3631 | </sect1> | 3443 | </sect1> |
3632 | <sect1> | 3444 | <sect1> |
3633 | <title>Driver power control</title> | 3445 | <title>Driver power control</title> |
3634 | !Pdrivers/gpu/vga/vga_switcheroo.c Driver power control | 3446 | !Pdrivers/gpu/vga/vga_switcheroo.c Driver power control |
3635 | </sect1> | 3447 | </sect1> |
3636 | </chapter> | 3448 | </chapter> |
3637 | 3449 | ||
3638 | <chapter id="pubfunctions"> | 3450 | <chapter id="api"> |
3639 | <title>Public functions</title> | 3451 | <title>API</title> |
3452 | <sect1> | ||
3453 | <title>Public functions</title> | ||
3640 | !Edrivers/gpu/vga/vga_switcheroo.c | 3454 | !Edrivers/gpu/vga/vga_switcheroo.c |
3641 | </chapter> | 3455 | </sect1> |
3642 | 3456 | <sect1> | |
3643 | <chapter id="pubstructures"> | 3457 | <title>Public structures</title> |
3644 | <title>Public structures</title> | ||
3645 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_handler | 3458 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_handler |
3646 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_ops | 3459 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_ops |
3647 | </chapter> | 3460 | </sect1> |
3648 | 3461 | <sect1> | |
3649 | <chapter id="pubconstants"> | 3462 | <title>Public constants</title> |
3650 | <title>Public constants</title> | ||
3651 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id | 3463 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id |
3652 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_state | 3464 | !Finclude/linux/vga_switcheroo.h vga_switcheroo_state |
3653 | </chapter> | 3465 | </sect1> |
3654 | 3466 | <sect1> | |
3655 | <chapter id="privstructures"> | 3467 | <title>Private structures</title> |
3656 | <title>Private structures</title> | ||
3657 | !Fdrivers/gpu/vga/vga_switcheroo.c vgasr_priv | 3468 | !Fdrivers/gpu/vga/vga_switcheroo.c vgasr_priv |
3658 | !Fdrivers/gpu/vga/vga_switcheroo.c vga_switcheroo_client | 3469 | !Fdrivers/gpu/vga/vga_switcheroo.c vga_switcheroo_client |
3470 | </sect1> | ||
3471 | </chapter> | ||
3472 | |||
3473 | <chapter id="handlers"> | ||
3474 | <title>Handlers</title> | ||
3475 | <sect1> | ||
3476 | <title>apple-gmux Handler</title> | ||
3477 | !Pdrivers/platform/x86/apple-gmux.c Overview | ||
3478 | !Pdrivers/platform/x86/apple-gmux.c Interrupt | ||
3479 | <sect2> | ||
3480 | <title>Graphics mux</title> | ||
3481 | !Pdrivers/platform/x86/apple-gmux.c Graphics mux | ||
3482 | </sect2> | ||
3483 | <sect2> | ||
3484 | <title>Power control</title> | ||
3485 | !Pdrivers/platform/x86/apple-gmux.c Power control | ||
3486 | </sect2> | ||
3487 | <sect2> | ||
3488 | <title>Backlight control</title> | ||
3489 | !Pdrivers/platform/x86/apple-gmux.c Backlight control | ||
3490 | </sect2> | ||
3491 | </sect1> | ||
3659 | </chapter> | 3492 | </chapter> |
3660 | 3493 | ||
3661 | !Cdrivers/gpu/vga/vga_switcheroo.c | 3494 | !Cdrivers/gpu/vga/vga_switcheroo.c |
3662 | !Cinclude/linux/vga_switcheroo.h | 3495 | !Cinclude/linux/vga_switcheroo.h |
3496 | !Cdrivers/platform/x86/apple-gmux.c | ||
3663 | </part> | 3497 | </part> |
3664 | 3498 | ||
3665 | </book> | 3499 | </book> |
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index 6fbec99e59c2..b0aac4733020 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c | |||
@@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) | |||
1667 | &dw_hdmi_connector_funcs, | 1667 | &dw_hdmi_connector_funcs, |
1668 | DRM_MODE_CONNECTOR_HDMIA); | 1668 | DRM_MODE_CONNECTOR_HDMIA); |
1669 | 1669 | ||
1670 | hdmi->connector.encoder = encoder; | ||
1671 | |||
1672 | drm_mode_connector_attach_encoder(&hdmi->connector, encoder); | 1670 | drm_mode_connector_attach_encoder(&hdmi->connector, encoder); |
1673 | 1671 | ||
1674 | return 0; | 1672 | return 0; |
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 6a21e5c378c1..3f74193885f1 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -508,6 +508,22 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc, | |||
508 | return -EINVAL; | 508 | return -EINVAL; |
509 | } | 509 | } |
510 | 510 | ||
511 | /* | ||
512 | * Reject event generation for when a CRTC is off and stays off. | ||
513 | * It wouldn't be hard to implement this, but userspace has a track | ||
514 | * record of happily burning through 100% cpu (or worse, crash) when the | ||
515 | * display pipe is suspended. To avoid all that fun just reject updates | ||
516 | * that ask for events since likely that indicates a bug in the | ||
517 | * compositor's drawing loop. This is consistent with the vblank IOCTL | ||
518 | * and legacy page_flip IOCTL which also reject service on a disabled | ||
519 | * pipe. | ||
520 | */ | ||
521 | if (state->event && !state->active && !crtc->state->active) { | ||
522 | DRM_DEBUG_ATOMIC("[CRTC:%d] requesting event but off\n", | ||
523 | crtc->base.id); | ||
524 | return -EINVAL; | ||
525 | } | ||
526 | |||
511 | return 0; | 527 | return 0; |
512 | } | 528 | } |
513 | 529 | ||
@@ -1063,10 +1079,21 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, | |||
1063 | { | 1079 | { |
1064 | struct drm_crtc_state *crtc_state; | 1080 | struct drm_crtc_state *crtc_state; |
1065 | 1081 | ||
1082 | if (conn_state->crtc && conn_state->crtc != crtc) { | ||
1083 | crtc_state = drm_atomic_get_existing_crtc_state(conn_state->state, | ||
1084 | conn_state->crtc); | ||
1085 | |||
1086 | crtc_state->connector_mask &= | ||
1087 | ~(1 << drm_connector_index(conn_state->connector)); | ||
1088 | } | ||
1089 | |||
1066 | if (crtc) { | 1090 | if (crtc) { |
1067 | crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); | 1091 | crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); |
1068 | if (IS_ERR(crtc_state)) | 1092 | if (IS_ERR(crtc_state)) |
1069 | return PTR_ERR(crtc_state); | 1093 | return PTR_ERR(crtc_state); |
1094 | |||
1095 | crtc_state->connector_mask |= | ||
1096 | 1 << drm_connector_index(conn_state->connector); | ||
1070 | } | 1097 | } |
1071 | 1098 | ||
1072 | conn_state->crtc = crtc; | 1099 | conn_state->crtc = crtc; |
@@ -1172,36 +1199,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state, | |||
1172 | EXPORT_SYMBOL(drm_atomic_add_affected_planes); | 1199 | EXPORT_SYMBOL(drm_atomic_add_affected_planes); |
1173 | 1200 | ||
1174 | /** | 1201 | /** |
1175 | * drm_atomic_connectors_for_crtc - count number of connected outputs | ||
1176 | * @state: atomic state | ||
1177 | * @crtc: DRM crtc | ||
1178 | * | ||
1179 | * This function counts all connectors which will be connected to @crtc | ||
1180 | * according to @state. Useful to recompute the enable state for @crtc. | ||
1181 | */ | ||
1182 | int | ||
1183 | drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, | ||
1184 | struct drm_crtc *crtc) | ||
1185 | { | ||
1186 | struct drm_connector *connector; | ||
1187 | struct drm_connector_state *conn_state; | ||
1188 | |||
1189 | int i, num_connected_connectors = 0; | ||
1190 | |||
1191 | for_each_connector_in_state(state, connector, conn_state, i) { | ||
1192 | if (conn_state->crtc == crtc) | ||
1193 | num_connected_connectors++; | ||
1194 | } | ||
1195 | |||
1196 | DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d:%s]\n", | ||
1197 | state, num_connected_connectors, | ||
1198 | crtc->base.id, crtc->name); | ||
1199 | |||
1200 | return num_connected_connectors; | ||
1201 | } | ||
1202 | EXPORT_SYMBOL(drm_atomic_connectors_for_crtc); | ||
1203 | |||
1204 | /** | ||
1205 | * drm_atomic_legacy_backoff - locking backoff for legacy ioctls | 1202 | * drm_atomic_legacy_backoff - locking backoff for legacy ioctls |
1206 | * @state: atomic state | 1203 | * @state: atomic state |
1207 | * | 1204 | * |
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 268d37f26960..57cccd68ca52 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
@@ -463,7 +463,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, | |||
463 | * crtc only changed its mode but has the same set of connectors. | 463 | * crtc only changed its mode but has the same set of connectors. |
464 | */ | 464 | */ |
465 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | 465 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
466 | int num_connectors; | 466 | bool has_connectors = |
467 | !!crtc_state->connector_mask; | ||
467 | 468 | ||
468 | /* | 469 | /* |
469 | * We must set ->active_changed after walking connectors for | 470 | * We must set ->active_changed after walking connectors for |
@@ -492,10 +493,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, | |||
492 | if (ret != 0) | 493 | if (ret != 0) |
493 | return ret; | 494 | return ret; |
494 | 495 | ||
495 | num_connectors = drm_atomic_connectors_for_crtc(state, | 496 | if (crtc_state->enable != has_connectors) { |
496 | crtc); | ||
497 | |||
498 | if (crtc_state->enable != !!num_connectors) { | ||
499 | DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n", | 497 | DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n", |
500 | crtc->base.id, crtc->name); | 498 | crtc->base.id, crtc->name); |
501 | 499 | ||
@@ -1754,7 +1752,7 @@ static int update_output_state(struct drm_atomic_state *state, | |||
1754 | if (crtc == set->crtc) | 1752 | if (crtc == set->crtc) |
1755 | continue; | 1753 | continue; |
1756 | 1754 | ||
1757 | if (!drm_atomic_connectors_for_crtc(state, crtc)) { | 1755 | if (!crtc_state->connector_mask) { |
1758 | ret = drm_atomic_set_mode_prop_for_crtc(crtc_state, | 1756 | ret = drm_atomic_set_mode_prop_for_crtc(crtc_state, |
1759 | NULL); | 1757 | NULL); |
1760 | if (ret < 0) | 1758 | if (ret < 0) |
@@ -2284,6 +2282,15 @@ retry: | |||
2284 | goto fail; | 2282 | goto fail; |
2285 | drm_atomic_set_fb_for_plane(plane_state, fb); | 2283 | drm_atomic_set_fb_for_plane(plane_state, fb); |
2286 | 2284 | ||
2285 | /* Make sure we don't accidentally do a full modeset. */ | ||
2286 | state->allow_modeset = false; | ||
2287 | if (!crtc_state->active) { | ||
2288 | DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n", | ||
2289 | crtc->base.id); | ||
2290 | ret = -EINVAL; | ||
2291 | goto fail; | ||
2292 | } | ||
2293 | |||
2287 | ret = drm_atomic_async_commit(state); | 2294 | ret = drm_atomic_async_commit(state); |
2288 | if (ret != 0) | 2295 | if (ret != 0) |
2289 | goto fail; | 2296 | goto fail; |
@@ -2606,6 +2613,28 @@ void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, | |||
2606 | EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); | 2613 | EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); |
2607 | 2614 | ||
2608 | /** | 2615 | /** |
2616 | * __drm_atomic_helper_connector_reset - reset state on connector | ||
2617 | * @connector: drm connector | ||
2618 | * @conn_state: connector state to assign | ||
2619 | * | ||
2620 | * Initializes the newly allocated @conn_state and assigns it to | ||
2621 | * #connector ->state, usually required when initializing the drivers | ||
2622 | * or when called from the ->reset hook. | ||
2623 | * | ||
2624 | * This is useful for drivers that subclass the connector state. | ||
2625 | */ | ||
2626 | void | ||
2627 | __drm_atomic_helper_connector_reset(struct drm_connector *connector, | ||
2628 | struct drm_connector_state *conn_state) | ||
2629 | { | ||
2630 | if (conn_state) | ||
2631 | conn_state->connector = connector; | ||
2632 | |||
2633 | connector->state = conn_state; | ||
2634 | } | ||
2635 | EXPORT_SYMBOL(__drm_atomic_helper_connector_reset); | ||
2636 | |||
2637 | /** | ||
2609 | * drm_atomic_helper_connector_reset - default ->reset hook for connectors | 2638 | * drm_atomic_helper_connector_reset - default ->reset hook for connectors |
2610 | * @connector: drm connector | 2639 | * @connector: drm connector |
2611 | * | 2640 | * |
@@ -2615,11 +2644,11 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); | |||
2615 | */ | 2644 | */ |
2616 | void drm_atomic_helper_connector_reset(struct drm_connector *connector) | 2645 | void drm_atomic_helper_connector_reset(struct drm_connector *connector) |
2617 | { | 2646 | { |
2618 | kfree(connector->state); | 2647 | struct drm_connector_state *conn_state = |
2619 | connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL); | 2648 | kzalloc(sizeof(*conn_state), GFP_KERNEL); |
2620 | 2649 | ||
2621 | if (connector->state) | 2650 | kfree(connector->state); |
2622 | connector->state->connector = connector; | 2651 | __drm_atomic_helper_connector_reset(connector, conn_state); |
2623 | } | 2652 | } |
2624 | EXPORT_SYMBOL(drm_atomic_helper_connector_reset); | 2653 | EXPORT_SYMBOL(drm_atomic_helper_connector_reset); |
2625 | 2654 | ||
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 62fa95fa5471..d40bab29747e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -5054,6 +5054,20 @@ int drm_mode_connector_attach_encoder(struct drm_connector *connector, | |||
5054 | { | 5054 | { |
5055 | int i; | 5055 | int i; |
5056 | 5056 | ||
5057 | /* | ||
5058 | * In the past, drivers have attempted to model the static association | ||
5059 | * of connector to encoder in simple connector/encoder devices using a | ||
5060 | * direct assignment of connector->encoder = encoder. This connection | ||
5061 | * is a logical one and the responsibility of the core, so drivers are | ||
5062 | * expected not to mess with this. | ||
5063 | * | ||
5064 | * Note that the error return should've been enough here, but a large | ||
5065 | * majority of drivers ignores the return value, so add in a big WARN | ||
5066 | * to get people's attention. | ||
5067 | */ | ||
5068 | if (WARN_ON(connector->encoder)) | ||
5069 | return -EINVAL; | ||
5070 | |||
5057 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 5071 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
5058 | if (connector->encoder_ids[i] == 0) { | 5072 | if (connector->encoder_ids[i] == 0) { |
5059 | connector->encoder_ids[i] = encoder->base.id; | 5073 | connector->encoder_ids[i] = encoder->base.id; |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index bf934cdea21c..167c8d3d4a31 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -44,10 +44,6 @@ MODULE_AUTHOR(CORE_AUTHOR); | |||
44 | MODULE_DESCRIPTION(CORE_DESC); | 44 | MODULE_DESCRIPTION(CORE_DESC); |
45 | MODULE_LICENSE("GPL and additional rights"); | 45 | MODULE_LICENSE("GPL and additional rights"); |
46 | MODULE_PARM_DESC(debug, "Enable debug output"); | 46 | MODULE_PARM_DESC(debug, "Enable debug output"); |
47 | MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)"); | ||
48 | MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); | ||
49 | MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); | ||
50 | |||
51 | module_param_named(debug, drm_debug, int, 0600); | 47 | module_param_named(debug, drm_debug, int, 0600); |
52 | 48 | ||
53 | static DEFINE_SPINLOCK(drm_minor_lock); | 49 | static DEFINE_SPINLOCK(drm_minor_lock); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c214f1246cb4..04cb4877fabd 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -637,8 +637,12 @@ static const struct minimode extra_modes[] = { | |||
637 | /* | 637 | /* |
638 | * Probably taken from CEA-861 spec. | 638 | * Probably taken from CEA-861 spec. |
639 | * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. | 639 | * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. |
640 | * | ||
641 | * Index using the VIC. | ||
640 | */ | 642 | */ |
641 | static const struct drm_display_mode edid_cea_modes[] = { | 643 | static const struct drm_display_mode edid_cea_modes[] = { |
644 | /* 0 - dummy, VICs start at 1 */ | ||
645 | { }, | ||
642 | /* 1 - 640x480@60Hz */ | 646 | /* 1 - 640x480@60Hz */ |
643 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, | 647 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, |
644 | 752, 800, 0, 480, 490, 492, 525, 0, | 648 | 752, 800, 0, 480, 490, 492, 525, 0, |
@@ -987,9 +991,11 @@ static const struct drm_display_mode edid_cea_modes[] = { | |||
987 | }; | 991 | }; |
988 | 992 | ||
989 | /* | 993 | /* |
990 | * HDMI 1.4 4k modes. | 994 | * HDMI 1.4 4k modes. Index using the VIC. |
991 | */ | 995 | */ |
992 | static const struct drm_display_mode edid_4k_modes[] = { | 996 | static const struct drm_display_mode edid_4k_modes[] = { |
997 | /* 0 - dummy, VICs start at 1 */ | ||
998 | { }, | ||
993 | /* 1 - 3840x2160@30Hz */ | 999 | /* 1 - 3840x2160@30Hz */ |
994 | { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, | 1000 | { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, |
995 | 3840, 4016, 4104, 4400, 0, | 1001 | 3840, 4016, 4104, 4400, 0, |
@@ -2548,13 +2554,13 @@ cea_mode_alternate_clock(const struct drm_display_mode *cea_mode) | |||
2548 | static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match, | 2554 | static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match, |
2549 | unsigned int clock_tolerance) | 2555 | unsigned int clock_tolerance) |
2550 | { | 2556 | { |
2551 | u8 mode; | 2557 | u8 vic; |
2552 | 2558 | ||
2553 | if (!to_match->clock) | 2559 | if (!to_match->clock) |
2554 | return 0; | 2560 | return 0; |
2555 | 2561 | ||
2556 | for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) { | 2562 | for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) { |
2557 | const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; | 2563 | const struct drm_display_mode *cea_mode = &edid_cea_modes[vic]; |
2558 | unsigned int clock1, clock2; | 2564 | unsigned int clock1, clock2; |
2559 | 2565 | ||
2560 | /* Check both 60Hz and 59.94Hz */ | 2566 | /* Check both 60Hz and 59.94Hz */ |
@@ -2566,7 +2572,7 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m | |||
2566 | continue; | 2572 | continue; |
2567 | 2573 | ||
2568 | if (drm_mode_equal_no_clocks(to_match, cea_mode)) | 2574 | if (drm_mode_equal_no_clocks(to_match, cea_mode)) |
2569 | return mode + 1; | 2575 | return vic; |
2570 | } | 2576 | } |
2571 | 2577 | ||
2572 | return 0; | 2578 | return 0; |
@@ -2581,13 +2587,13 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m | |||
2581 | */ | 2587 | */ |
2582 | u8 drm_match_cea_mode(const struct drm_display_mode *to_match) | 2588 | u8 drm_match_cea_mode(const struct drm_display_mode *to_match) |
2583 | { | 2589 | { |
2584 | u8 mode; | 2590 | u8 vic; |
2585 | 2591 | ||
2586 | if (!to_match->clock) | 2592 | if (!to_match->clock) |
2587 | return 0; | 2593 | return 0; |
2588 | 2594 | ||
2589 | for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) { | 2595 | for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) { |
2590 | const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; | 2596 | const struct drm_display_mode *cea_mode = &edid_cea_modes[vic]; |
2591 | unsigned int clock1, clock2; | 2597 | unsigned int clock1, clock2; |
2592 | 2598 | ||
2593 | /* Check both 60Hz and 59.94Hz */ | 2599 | /* Check both 60Hz and 59.94Hz */ |
@@ -2597,12 +2603,17 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) | |||
2597 | if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || | 2603 | if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || |
2598 | KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && | 2604 | KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && |
2599 | drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode)) | 2605 | drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode)) |
2600 | return mode + 1; | 2606 | return vic; |
2601 | } | 2607 | } |
2602 | return 0; | 2608 | return 0; |
2603 | } | 2609 | } |
2604 | EXPORT_SYMBOL(drm_match_cea_mode); | 2610 | EXPORT_SYMBOL(drm_match_cea_mode); |
2605 | 2611 | ||
2612 | static bool drm_valid_cea_vic(u8 vic) | ||
2613 | { | ||
2614 | return vic > 0 && vic < ARRAY_SIZE(edid_cea_modes); | ||
2615 | } | ||
2616 | |||
2606 | /** | 2617 | /** |
2607 | * drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to | 2618 | * drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to |
2608 | * the input VIC from the CEA mode list | 2619 | * the input VIC from the CEA mode list |
@@ -2612,10 +2623,7 @@ EXPORT_SYMBOL(drm_match_cea_mode); | |||
2612 | */ | 2623 | */ |
2613 | enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code) | 2624 | enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code) |
2614 | { | 2625 | { |
2615 | /* return picture aspect ratio for video_code - 1 to access the | 2626 | return edid_cea_modes[video_code].picture_aspect_ratio; |
2616 | * right array element | ||
2617 | */ | ||
2618 | return edid_cea_modes[video_code-1].picture_aspect_ratio; | ||
2619 | } | 2627 | } |
2620 | EXPORT_SYMBOL(drm_get_cea_aspect_ratio); | 2628 | EXPORT_SYMBOL(drm_get_cea_aspect_ratio); |
2621 | 2629 | ||
@@ -2639,13 +2647,13 @@ hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode) | |||
2639 | static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match, | 2647 | static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match, |
2640 | unsigned int clock_tolerance) | 2648 | unsigned int clock_tolerance) |
2641 | { | 2649 | { |
2642 | u8 mode; | 2650 | u8 vic; |
2643 | 2651 | ||
2644 | if (!to_match->clock) | 2652 | if (!to_match->clock) |
2645 | return 0; | 2653 | return 0; |
2646 | 2654 | ||
2647 | for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) { | 2655 | for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) { |
2648 | const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode]; | 2656 | const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic]; |
2649 | unsigned int clock1, clock2; | 2657 | unsigned int clock1, clock2; |
2650 | 2658 | ||
2651 | /* Make sure to also match alternate clocks */ | 2659 | /* Make sure to also match alternate clocks */ |
@@ -2657,7 +2665,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_ | |||
2657 | continue; | 2665 | continue; |
2658 | 2666 | ||
2659 | if (drm_mode_equal_no_clocks(to_match, hdmi_mode)) | 2667 | if (drm_mode_equal_no_clocks(to_match, hdmi_mode)) |
2660 | return mode + 1; | 2668 | return vic; |
2661 | } | 2669 | } |
2662 | 2670 | ||
2663 | return 0; | 2671 | return 0; |
@@ -2673,13 +2681,13 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_ | |||
2673 | */ | 2681 | */ |
2674 | static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) | 2682 | static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) |
2675 | { | 2683 | { |
2676 | u8 mode; | 2684 | u8 vic; |
2677 | 2685 | ||
2678 | if (!to_match->clock) | 2686 | if (!to_match->clock) |
2679 | return 0; | 2687 | return 0; |
2680 | 2688 | ||
2681 | for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) { | 2689 | for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) { |
2682 | const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode]; | 2690 | const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic]; |
2683 | unsigned int clock1, clock2; | 2691 | unsigned int clock1, clock2; |
2684 | 2692 | ||
2685 | /* Make sure to also match alternate clocks */ | 2693 | /* Make sure to also match alternate clocks */ |
@@ -2689,11 +2697,16 @@ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) | |||
2689 | if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || | 2697 | if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || |
2690 | KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && | 2698 | KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && |
2691 | drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode)) | 2699 | drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode)) |
2692 | return mode + 1; | 2700 | return vic; |
2693 | } | 2701 | } |
2694 | return 0; | 2702 | return 0; |
2695 | } | 2703 | } |
2696 | 2704 | ||
2705 | static bool drm_valid_hdmi_vic(u8 vic) | ||
2706 | { | ||
2707 | return vic > 0 && vic < ARRAY_SIZE(edid_4k_modes); | ||
2708 | } | ||
2709 | |||
2697 | static int | 2710 | static int |
2698 | add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) | 2711 | add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) |
2699 | { | 2712 | { |
@@ -2713,16 +2726,16 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) | |||
2713 | list_for_each_entry(mode, &connector->probed_modes, head) { | 2726 | list_for_each_entry(mode, &connector->probed_modes, head) { |
2714 | const struct drm_display_mode *cea_mode = NULL; | 2727 | const struct drm_display_mode *cea_mode = NULL; |
2715 | struct drm_display_mode *newmode; | 2728 | struct drm_display_mode *newmode; |
2716 | u8 mode_idx = drm_match_cea_mode(mode) - 1; | 2729 | u8 vic = drm_match_cea_mode(mode); |
2717 | unsigned int clock1, clock2; | 2730 | unsigned int clock1, clock2; |
2718 | 2731 | ||
2719 | if (mode_idx < ARRAY_SIZE(edid_cea_modes)) { | 2732 | if (drm_valid_cea_vic(vic)) { |
2720 | cea_mode = &edid_cea_modes[mode_idx]; | 2733 | cea_mode = &edid_cea_modes[vic]; |
2721 | clock2 = cea_mode_alternate_clock(cea_mode); | 2734 | clock2 = cea_mode_alternate_clock(cea_mode); |
2722 | } else { | 2735 | } else { |
2723 | mode_idx = drm_match_hdmi_mode(mode) - 1; | 2736 | vic = drm_match_hdmi_mode(mode); |
2724 | if (mode_idx < ARRAY_SIZE(edid_4k_modes)) { | 2737 | if (drm_valid_hdmi_vic(vic)) { |
2725 | cea_mode = &edid_4k_modes[mode_idx]; | 2738 | cea_mode = &edid_4k_modes[vic]; |
2726 | clock2 = hdmi_mode_alternate_clock(cea_mode); | 2739 | clock2 = hdmi_mode_alternate_clock(cea_mode); |
2727 | } | 2740 | } |
2728 | } | 2741 | } |
@@ -2773,17 +2786,17 @@ drm_display_mode_from_vic_index(struct drm_connector *connector, | |||
2773 | { | 2786 | { |
2774 | struct drm_device *dev = connector->dev; | 2787 | struct drm_device *dev = connector->dev; |
2775 | struct drm_display_mode *newmode; | 2788 | struct drm_display_mode *newmode; |
2776 | u8 cea_mode; | 2789 | u8 vic; |
2777 | 2790 | ||
2778 | if (video_db == NULL || video_index >= video_len) | 2791 | if (video_db == NULL || video_index >= video_len) |
2779 | return NULL; | 2792 | return NULL; |
2780 | 2793 | ||
2781 | /* CEA modes are numbered 1..127 */ | 2794 | /* CEA modes are numbered 1..127 */ |
2782 | cea_mode = (video_db[video_index] & 127) - 1; | 2795 | vic = (video_db[video_index] & 127); |
2783 | if (cea_mode >= ARRAY_SIZE(edid_cea_modes)) | 2796 | if (!drm_valid_cea_vic(vic)) |
2784 | return NULL; | 2797 | return NULL; |
2785 | 2798 | ||
2786 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); | 2799 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[vic]); |
2787 | if (!newmode) | 2800 | if (!newmode) |
2788 | return NULL; | 2801 | return NULL; |
2789 | 2802 | ||
@@ -2878,8 +2891,7 @@ static int add_hdmi_mode(struct drm_connector *connector, u8 vic) | |||
2878 | struct drm_device *dev = connector->dev; | 2891 | struct drm_device *dev = connector->dev; |
2879 | struct drm_display_mode *newmode; | 2892 | struct drm_display_mode *newmode; |
2880 | 2893 | ||
2881 | vic--; /* VICs start at 1 */ | 2894 | if (!drm_valid_hdmi_vic(vic)) { |
2882 | if (vic >= ARRAY_SIZE(edid_4k_modes)) { | ||
2883 | DRM_ERROR("Unknown HDMI VIC: %d\n", vic); | 2895 | DRM_ERROR("Unknown HDMI VIC: %d\n", vic); |
2884 | return 0; | 2896 | return 0; |
2885 | } | 2897 | } |
@@ -3170,24 +3182,24 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode) | |||
3170 | { | 3182 | { |
3171 | const struct drm_display_mode *cea_mode; | 3183 | const struct drm_display_mode *cea_mode; |
3172 | int clock1, clock2, clock; | 3184 | int clock1, clock2, clock; |
3173 | u8 mode_idx; | 3185 | u8 vic; |
3174 | const char *type; | 3186 | const char *type; |
3175 | 3187 | ||
3176 | /* | 3188 | /* |
3177 | * allow 5kHz clock difference either way to account for | 3189 | * allow 5kHz clock difference either way to account for |
3178 | * the 10kHz clock resolution limit of detailed timings. | 3190 | * the 10kHz clock resolution limit of detailed timings. |
3179 | */ | 3191 | */ |
3180 | mode_idx = drm_match_cea_mode_clock_tolerance(mode, 5) - 1; | 3192 | vic = drm_match_cea_mode_clock_tolerance(mode, 5); |
3181 | if (mode_idx < ARRAY_SIZE(edid_cea_modes)) { | 3193 | if (drm_valid_cea_vic(vic)) { |
3182 | type = "CEA"; | 3194 | type = "CEA"; |
3183 | cea_mode = &edid_cea_modes[mode_idx]; | 3195 | cea_mode = &edid_cea_modes[vic]; |
3184 | clock1 = cea_mode->clock; | 3196 | clock1 = cea_mode->clock; |
3185 | clock2 = cea_mode_alternate_clock(cea_mode); | 3197 | clock2 = cea_mode_alternate_clock(cea_mode); |
3186 | } else { | 3198 | } else { |
3187 | mode_idx = drm_match_hdmi_mode_clock_tolerance(mode, 5) - 1; | 3199 | vic = drm_match_hdmi_mode_clock_tolerance(mode, 5); |
3188 | if (mode_idx < ARRAY_SIZE(edid_4k_modes)) { | 3200 | if (drm_valid_hdmi_vic(vic)) { |
3189 | type = "HDMI"; | 3201 | type = "HDMI"; |
3190 | cea_mode = &edid_4k_modes[mode_idx]; | 3202 | cea_mode = &edid_4k_modes[vic]; |
3191 | clock1 = cea_mode->clock; | 3203 | clock1 = cea_mode->clock; |
3192 | clock2 = hdmi_mode_alternate_clock(cea_mode); | 3204 | clock2 = hdmi_mode_alternate_clock(cea_mode); |
3193 | } else { | 3205 | } else { |
@@ -3205,7 +3217,7 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode) | |||
3205 | return; | 3217 | return; |
3206 | 3218 | ||
3207 | DRM_DEBUG("detailed mode matches %s VIC %d, adjusting clock %d -> %d\n", | 3219 | DRM_DEBUG("detailed mode matches %s VIC %d, adjusting clock %d -> %d\n", |
3208 | type, mode_idx + 1, mode->clock, clock); | 3220 | type, vic, mode->clock, clock); |
3209 | mode->clock = clock; | 3221 | mode->clock = clock; |
3210 | } | 3222 | } |
3211 | 3223 | ||
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 5543fa806aec..c895b6fddbd8 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
@@ -348,9 +348,6 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, | |||
348 | 348 | ||
349 | } | 349 | } |
350 | 350 | ||
351 | /* disable all the possible outputs/crtcs before entering KMS mode */ | ||
352 | drm_helper_disable_unused_functions(dev); | ||
353 | |||
354 | ret = drm_fb_helper_initial_config(helper, preferred_bpp); | 351 | ret = drm_fb_helper_initial_config(helper, preferred_bpp); |
355 | if (ret < 0) { | 352 | if (ret < 0) { |
356 | dev_err(dev->dev, "Failed to set initial hw configuration.\n"); | 353 | dev_err(dev->dev, "Failed to set initial hw configuration.\n"); |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 69cbab5e5c81..1e103c4c6ee0 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -1251,7 +1251,7 @@ retry: | |||
1251 | goto fail; | 1251 | goto fail; |
1252 | 1252 | ||
1253 | plane = mode_set->crtc->primary; | 1253 | plane = mode_set->crtc->primary; |
1254 | plane_mask |= drm_plane_index(plane); | 1254 | plane_mask |= (1 << drm_plane_index(plane)); |
1255 | plane->old_fb = plane->fb; | 1255 | plane->old_fb = plane->fb; |
1256 | } | 1256 | } |
1257 | 1257 | ||
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 2e10bba4468b..2e8c77e71e1f 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -220,6 +220,9 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj) | |||
220 | static void | 220 | static void |
221 | drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) | 221 | drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) |
222 | { | 222 | { |
223 | struct drm_device *dev = obj->dev; | ||
224 | bool final = false; | ||
225 | |||
223 | if (WARN_ON(obj->handle_count == 0)) | 226 | if (WARN_ON(obj->handle_count == 0)) |
224 | return; | 227 | return; |
225 | 228 | ||
@@ -229,14 +232,39 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) | |||
229 | * checked for a name | 232 | * checked for a name |
230 | */ | 233 | */ |
231 | 234 | ||
232 | mutex_lock(&obj->dev->object_name_lock); | 235 | mutex_lock(&dev->object_name_lock); |
233 | if (--obj->handle_count == 0) { | 236 | if (--obj->handle_count == 0) { |
234 | drm_gem_object_handle_free(obj); | 237 | drm_gem_object_handle_free(obj); |
235 | drm_gem_object_exported_dma_buf_free(obj); | 238 | drm_gem_object_exported_dma_buf_free(obj); |
239 | final = true; | ||
236 | } | 240 | } |
237 | mutex_unlock(&obj->dev->object_name_lock); | 241 | mutex_unlock(&dev->object_name_lock); |
238 | 242 | ||
239 | drm_gem_object_unreference_unlocked(obj); | 243 | if (final) |
244 | drm_gem_object_unreference_unlocked(obj); | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * Called at device or object close to release the file's | ||
249 | * handle references on objects. | ||
250 | */ | ||
251 | static int | ||
252 | drm_gem_object_release_handle(int id, void *ptr, void *data) | ||
253 | { | ||
254 | struct drm_file *file_priv = data; | ||
255 | struct drm_gem_object *obj = ptr; | ||
256 | struct drm_device *dev = obj->dev; | ||
257 | |||
258 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | ||
259 | drm_gem_remove_prime_handles(obj, file_priv); | ||
260 | drm_vma_node_revoke(&obj->vma_node, file_priv->filp); | ||
261 | |||
262 | if (dev->driver->gem_close_object) | ||
263 | dev->driver->gem_close_object(obj, file_priv); | ||
264 | |||
265 | drm_gem_object_handle_unreference_unlocked(obj); | ||
266 | |||
267 | return 0; | ||
240 | } | 268 | } |
241 | 269 | ||
242 | /** | 270 | /** |
@@ -277,14 +305,7 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) | |||
277 | idr_remove(&filp->object_idr, handle); | 305 | idr_remove(&filp->object_idr, handle); |
278 | spin_unlock(&filp->table_lock); | 306 | spin_unlock(&filp->table_lock); |
279 | 307 | ||
280 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | 308 | drm_gem_object_release_handle(handle, obj, filp); |
281 | drm_gem_remove_prime_handles(obj, filp); | ||
282 | drm_vma_node_revoke(&obj->vma_node, filp->filp); | ||
283 | |||
284 | if (dev->driver->gem_close_object) | ||
285 | dev->driver->gem_close_object(obj, filp); | ||
286 | drm_gem_object_handle_unreference_unlocked(obj); | ||
287 | |||
288 | return 0; | 309 | return 0; |
289 | } | 310 | } |
290 | EXPORT_SYMBOL(drm_gem_handle_delete); | 311 | EXPORT_SYMBOL(drm_gem_handle_delete); |
@@ -326,9 +347,12 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, | |||
326 | u32 *handlep) | 347 | u32 *handlep) |
327 | { | 348 | { |
328 | struct drm_device *dev = obj->dev; | 349 | struct drm_device *dev = obj->dev; |
350 | u32 handle; | ||
329 | int ret; | 351 | int ret; |
330 | 352 | ||
331 | WARN_ON(!mutex_is_locked(&dev->object_name_lock)); | 353 | WARN_ON(!mutex_is_locked(&dev->object_name_lock)); |
354 | if (obj->handle_count++ == 0) | ||
355 | drm_gem_object_reference(obj); | ||
332 | 356 | ||
333 | /* | 357 | /* |
334 | * Get the user-visible handle using idr. Preload and perform | 358 | * Get the user-visible handle using idr. Preload and perform |
@@ -338,32 +362,38 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, | |||
338 | spin_lock(&file_priv->table_lock); | 362 | spin_lock(&file_priv->table_lock); |
339 | 363 | ||
340 | ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT); | 364 | ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT); |
341 | drm_gem_object_reference(obj); | 365 | |
342 | obj->handle_count++; | ||
343 | spin_unlock(&file_priv->table_lock); | 366 | spin_unlock(&file_priv->table_lock); |
344 | idr_preload_end(); | 367 | idr_preload_end(); |
368 | |||
345 | mutex_unlock(&dev->object_name_lock); | 369 | mutex_unlock(&dev->object_name_lock); |
346 | if (ret < 0) { | 370 | if (ret < 0) |
347 | drm_gem_object_handle_unreference_unlocked(obj); | 371 | goto err_unref; |
348 | return ret; | 372 | |
349 | } | 373 | handle = ret; |
350 | *handlep = ret; | ||
351 | 374 | ||
352 | ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp); | 375 | ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp); |
353 | if (ret) { | 376 | if (ret) |
354 | drm_gem_handle_delete(file_priv, *handlep); | 377 | goto err_remove; |
355 | return ret; | ||
356 | } | ||
357 | 378 | ||
358 | if (dev->driver->gem_open_object) { | 379 | if (dev->driver->gem_open_object) { |
359 | ret = dev->driver->gem_open_object(obj, file_priv); | 380 | ret = dev->driver->gem_open_object(obj, file_priv); |
360 | if (ret) { | 381 | if (ret) |
361 | drm_gem_handle_delete(file_priv, *handlep); | 382 | goto err_revoke; |
362 | return ret; | ||
363 | } | ||
364 | } | 383 | } |
365 | 384 | ||
385 | *handlep = handle; | ||
366 | return 0; | 386 | return 0; |
387 | |||
388 | err_revoke: | ||
389 | drm_vma_node_revoke(&obj->vma_node, file_priv->filp); | ||
390 | err_remove: | ||
391 | spin_lock(&file_priv->table_lock); | ||
392 | idr_remove(&file_priv->object_idr, handle); | ||
393 | spin_unlock(&file_priv->table_lock); | ||
394 | err_unref: | ||
395 | drm_gem_object_handle_unreference_unlocked(obj); | ||
396 | return ret; | ||
367 | } | 397 | } |
368 | 398 | ||
369 | /** | 399 | /** |
@@ -630,7 +660,6 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, | |||
630 | return -ENOENT; | 660 | return -ENOENT; |
631 | 661 | ||
632 | mutex_lock(&dev->object_name_lock); | 662 | mutex_lock(&dev->object_name_lock); |
633 | idr_preload(GFP_KERNEL); | ||
634 | /* prevent races with concurrent gem_close. */ | 663 | /* prevent races with concurrent gem_close. */ |
635 | if (obj->handle_count == 0) { | 664 | if (obj->handle_count == 0) { |
636 | ret = -ENOENT; | 665 | ret = -ENOENT; |
@@ -638,7 +667,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, | |||
638 | } | 667 | } |
639 | 668 | ||
640 | if (!obj->name) { | 669 | if (!obj->name) { |
641 | ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT); | 670 | ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_KERNEL); |
642 | if (ret < 0) | 671 | if (ret < 0) |
643 | goto err; | 672 | goto err; |
644 | 673 | ||
@@ -649,7 +678,6 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, | |||
649 | ret = 0; | 678 | ret = 0; |
650 | 679 | ||
651 | err: | 680 | err: |
652 | idr_preload_end(); | ||
653 | mutex_unlock(&dev->object_name_lock); | 681 | mutex_unlock(&dev->object_name_lock); |
654 | drm_gem_object_unreference_unlocked(obj); | 682 | drm_gem_object_unreference_unlocked(obj); |
655 | return ret; | 683 | return ret; |
@@ -714,29 +742,6 @@ drm_gem_open(struct drm_device *dev, struct drm_file *file_private) | |||
714 | spin_lock_init(&file_private->table_lock); | 742 | spin_lock_init(&file_private->table_lock); |
715 | } | 743 | } |
716 | 744 | ||
717 | /* | ||
718 | * Called at device close to release the file's | ||
719 | * handle references on objects. | ||
720 | */ | ||
721 | static int | ||
722 | drm_gem_object_release_handle(int id, void *ptr, void *data) | ||
723 | { | ||
724 | struct drm_file *file_priv = data; | ||
725 | struct drm_gem_object *obj = ptr; | ||
726 | struct drm_device *dev = obj->dev; | ||
727 | |||
728 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | ||
729 | drm_gem_remove_prime_handles(obj, file_priv); | ||
730 | drm_vma_node_revoke(&obj->vma_node, file_priv->filp); | ||
731 | |||
732 | if (dev->driver->gem_close_object) | ||
733 | dev->driver->gem_close_object(obj, file_priv); | ||
734 | |||
735 | drm_gem_object_handle_unreference_unlocked(obj); | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | /** | 745 | /** |
741 | * drm_gem_release - release file-private GEM resources | 746 | * drm_gem_release - release file-private GEM resources |
742 | * @dev: drm_device which is being closed by userspace | 747 | * @dev: drm_device which is being closed by userspace |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 607f493ae801..d12a4efa651b 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -73,6 +73,9 @@ static int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ | |||
73 | module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); | 73 | module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); |
74 | module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); | 74 | module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); |
75 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); | 75 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); |
76 | MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)"); | ||
77 | MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); | ||
78 | MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); | ||
76 | 79 | ||
77 | static void store_vblank(struct drm_device *dev, unsigned int pipe, | 80 | static void store_vblank(struct drm_device *dev, unsigned int pipe, |
78 | u32 vblank_count_inc, | 81 | u32 vblank_count_inc, |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 0ca64106a97b..d503f8e8c2d1 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -240,7 +240,7 @@ static ssize_t edid_show(struct file *filp, struct kobject *kobj, | |||
240 | struct bin_attribute *attr, char *buf, loff_t off, | 240 | struct bin_attribute *attr, char *buf, loff_t off, |
241 | size_t count) | 241 | size_t count) |
242 | { | 242 | { |
243 | struct device *connector_dev = container_of(kobj, struct device, kobj); | 243 | struct device *connector_dev = kobj_to_dev(kobj); |
244 | struct drm_connector *connector = to_drm_connector(connector_dev); | 244 | struct drm_connector *connector = to_drm_connector(connector_dev); |
245 | unsigned char *edid; | 245 | unsigned char *edid; |
246 | size_t size; | 246 | size_t size; |
diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c index b6b135fcd59c..bea8578846d1 100644 --- a/drivers/gpu/drm/gma500/power.c +++ b/drivers/gpu/drm/gma500/power.c | |||
@@ -187,7 +187,7 @@ static bool gma_resume_pci(struct pci_dev *pdev) | |||
187 | */ | 187 | */ |
188 | int gma_power_suspend(struct device *_dev) | 188 | int gma_power_suspend(struct device *_dev) |
189 | { | 189 | { |
190 | struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev); | 190 | struct pci_dev *pdev = to_pci_dev(_dev); |
191 | struct drm_device *dev = pci_get_drvdata(pdev); | 191 | struct drm_device *dev = pci_get_drvdata(pdev); |
192 | struct drm_psb_private *dev_priv = dev->dev_private; | 192 | struct drm_psb_private *dev_priv = dev->dev_private; |
193 | 193 | ||
@@ -214,7 +214,7 @@ int gma_power_suspend(struct device *_dev) | |||
214 | */ | 214 | */ |
215 | int gma_power_resume(struct device *_dev) | 215 | int gma_power_resume(struct device *_dev) |
216 | { | 216 | { |
217 | struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev); | 217 | struct pci_dev *pdev = to_pci_dev(_dev); |
218 | struct drm_device *dev = pci_get_drvdata(pdev); | 218 | struct drm_device *dev = pci_get_drvdata(pdev); |
219 | 219 | ||
220 | mutex_lock(&power_mutex); | 220 | mutex_lock(&power_mutex); |
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 012d36d9a75b..34e38749a817 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
@@ -1446,7 +1446,6 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) | |||
1446 | if (ret) | 1446 | if (ret) |
1447 | goto err_sysfs; | 1447 | goto err_sysfs; |
1448 | 1448 | ||
1449 | priv->connector.encoder = &priv->encoder; | ||
1450 | drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); | 1449 | drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); |
1451 | 1450 | ||
1452 | return 0; | 1451 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 988a3806512a..d70d96fe553b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -406,6 +406,8 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
406 | if (ret) | 406 | if (ret) |
407 | goto cleanup_gem_stolen; | 407 | goto cleanup_gem_stolen; |
408 | 408 | ||
409 | intel_setup_gmbus(dev); | ||
410 | |||
409 | /* Important: The output setup functions called by modeset_init need | 411 | /* Important: The output setup functions called by modeset_init need |
410 | * working irqs for e.g. gmbus and dp aux transfers. */ | 412 | * working irqs for e.g. gmbus and dp aux transfers. */ |
411 | intel_modeset_init(dev); | 413 | intel_modeset_init(dev); |
@@ -455,6 +457,7 @@ cleanup_gem: | |||
455 | cleanup_irq: | 457 | cleanup_irq: |
456 | intel_guc_ucode_fini(dev); | 458 | intel_guc_ucode_fini(dev); |
457 | drm_irq_uninstall(dev); | 459 | drm_irq_uninstall(dev); |
460 | intel_teardown_gmbus(dev); | ||
458 | cleanup_gem_stolen: | 461 | cleanup_gem_stolen: |
459 | i915_gem_cleanup_stolen(dev); | 462 | i915_gem_cleanup_stolen(dev); |
460 | cleanup_vga_switcheroo: | 463 | cleanup_vga_switcheroo: |
@@ -1028,7 +1031,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1028 | 1031 | ||
1029 | /* Try to make sure MCHBAR is enabled before poking at it */ | 1032 | /* Try to make sure MCHBAR is enabled before poking at it */ |
1030 | intel_setup_mchbar(dev); | 1033 | intel_setup_mchbar(dev); |
1031 | intel_setup_gmbus(dev); | ||
1032 | intel_opregion_setup(dev); | 1034 | intel_opregion_setup(dev); |
1033 | 1035 | ||
1034 | i915_gem_load(dev); | 1036 | i915_gem_load(dev); |
@@ -1101,7 +1103,6 @@ out_gem_unload: | |||
1101 | if (dev->pdev->msi_enabled) | 1103 | if (dev->pdev->msi_enabled) |
1102 | pci_disable_msi(dev->pdev); | 1104 | pci_disable_msi(dev->pdev); |
1103 | 1105 | ||
1104 | intel_teardown_gmbus(dev); | ||
1105 | intel_teardown_mchbar(dev); | 1106 | intel_teardown_mchbar(dev); |
1106 | pm_qos_remove_request(&dev_priv->pm_qos); | 1107 | pm_qos_remove_request(&dev_priv->pm_qos); |
1107 | destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); | 1108 | destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); |
@@ -1203,7 +1204,6 @@ int i915_driver_unload(struct drm_device *dev) | |||
1203 | 1204 | ||
1204 | intel_csr_ucode_fini(dev_priv); | 1205 | intel_csr_ucode_fini(dev_priv); |
1205 | 1206 | ||
1206 | intel_teardown_gmbus(dev); | ||
1207 | intel_teardown_mchbar(dev); | 1207 | intel_teardown_mchbar(dev); |
1208 | 1208 | ||
1209 | destroy_workqueue(dev_priv->hotplug.dp_wq); | 1209 | destroy_workqueue(dev_priv->hotplug.dp_wq); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 02f6ccb848a9..ceaea7a3641a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -6492,13 +6492,11 @@ static void intel_connector_check_state(struct intel_connector *connector) | |||
6492 | 6492 | ||
6493 | int intel_connector_init(struct intel_connector *connector) | 6493 | int intel_connector_init(struct intel_connector *connector) |
6494 | { | 6494 | { |
6495 | struct drm_connector_state *connector_state; | 6495 | drm_atomic_helper_connector_reset(&connector->base); |
6496 | 6496 | ||
6497 | connector_state = kzalloc(sizeof *connector_state, GFP_KERNEL); | 6497 | if (!connector->base.state) |
6498 | if (!connector_state) | ||
6499 | return -ENOMEM; | 6498 | return -ENOMEM; |
6500 | 6499 | ||
6501 | connector->base.state = connector_state; | ||
6502 | return 0; | 6500 | return 0; |
6503 | } | 6501 | } |
6504 | 6502 | ||
@@ -15446,6 +15444,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) | |||
15446 | WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, NULL) < 0); | 15444 | WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, NULL) < 0); |
15447 | crtc->base.state->active = crtc->active; | 15445 | crtc->base.state->active = crtc->active; |
15448 | crtc->base.enabled = crtc->active; | 15446 | crtc->base.enabled = crtc->active; |
15447 | crtc->base.state->connector_mask = 0; | ||
15449 | 15448 | ||
15450 | /* Because we only establish the connector -> encoder -> | 15449 | /* Because we only establish the connector -> encoder -> |
15451 | * crtc links if something is active, this means the | 15450 | * crtc links if something is active, this means the |
@@ -15648,7 +15647,21 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
15648 | for_each_intel_connector(dev, connector) { | 15647 | for_each_intel_connector(dev, connector) { |
15649 | if (connector->get_hw_state(connector)) { | 15648 | if (connector->get_hw_state(connector)) { |
15650 | connector->base.dpms = DRM_MODE_DPMS_ON; | 15649 | connector->base.dpms = DRM_MODE_DPMS_ON; |
15651 | connector->base.encoder = &connector->encoder->base; | 15650 | |
15651 | encoder = connector->encoder; | ||
15652 | connector->base.encoder = &encoder->base; | ||
15653 | |||
15654 | if (encoder->base.crtc && | ||
15655 | encoder->base.crtc->state->active) { | ||
15656 | /* | ||
15657 | * This has to be done during hardware readout | ||
15658 | * because anything calling .crtc_disable may | ||
15659 | * rely on the connector_mask being accurate. | ||
15660 | */ | ||
15661 | encoder->base.crtc->state->connector_mask |= | ||
15662 | 1 << drm_connector_index(&connector->base); | ||
15663 | } | ||
15664 | |||
15652 | } else { | 15665 | } else { |
15653 | connector->base.dpms = DRM_MODE_DPMS_OFF; | 15666 | connector->base.dpms = DRM_MODE_DPMS_OFF; |
15654 | connector->base.encoder = NULL; | 15667 | connector->base.encoder = NULL; |
@@ -15893,6 +15906,8 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
15893 | mutex_lock(&dev->struct_mutex); | 15906 | mutex_lock(&dev->struct_mutex); |
15894 | intel_cleanup_gt_powersave(dev); | 15907 | intel_cleanup_gt_powersave(dev); |
15895 | mutex_unlock(&dev->struct_mutex); | 15908 | mutex_unlock(&dev->struct_mutex); |
15909 | |||
15910 | intel_teardown_gmbus(dev); | ||
15896 | } | 15911 | } |
15897 | 15912 | ||
15898 | /* | 15913 | /* |
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index e2f515d3816f..fa0dabf578dc 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
@@ -534,7 +534,7 @@ static void intel_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | |||
534 | drm_kms_helper_hotplug_event(dev); | 534 | drm_kms_helper_hotplug_event(dev); |
535 | } | 535 | } |
536 | 536 | ||
537 | static struct drm_dp_mst_topology_cbs mst_cbs = { | 537 | static const struct drm_dp_mst_topology_cbs mst_cbs = { |
538 | .add_connector = intel_dp_add_mst_connector, | 538 | .add_connector = intel_dp_add_mst_connector, |
539 | .register_connector = intel_dp_register_mst_connector, | 539 | .register_connector = intel_dp_register_mst_connector, |
540 | .destroy_connector = intel_dp_destroy_mst_connector, | 540 | .destroy_connector = intel_dp_destroy_mst_connector, |
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 7be7ac808304..2f57d7967417 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |||
@@ -305,6 +305,7 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) | |||
305 | dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n"); | 305 | dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n"); |
306 | legacyfb_depth = 16; | 306 | legacyfb_depth = 16; |
307 | } | 307 | } |
308 | drm_helper_disable_unused_functions(drm); | ||
308 | imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, | 309 | imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, |
309 | drm->mode_config.num_crtc, MAX_CRTC); | 310 | drm->mode_config.num_crtc, MAX_CRTC); |
310 | if (IS_ERR(imxdrm->fbhelper)) { | 311 | if (IS_ERR(imxdrm->fbhelper)) { |
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index b74bf8e334f5..0ffef172afb4 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c | |||
@@ -204,8 +204,6 @@ static int imx_pd_register(struct drm_device *drm, | |||
204 | 204 | ||
205 | drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); | 205 | drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); |
206 | 206 | ||
207 | imxpd->connector.encoder = &imxpd->encoder; | ||
208 | |||
209 | return 0; | 207 | return 0; |
210 | } | 208 | } |
211 | 209 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index c236f6fec245..df7a1719c841 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c | |||
@@ -329,7 +329,7 @@ static void radeon_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | |||
329 | drm_kms_helper_hotplug_event(dev); | 329 | drm_kms_helper_hotplug_event(dev); |
330 | } | 330 | } |
331 | 331 | ||
332 | struct drm_dp_mst_topology_cbs mst_cbs = { | 332 | const struct drm_dp_mst_topology_cbs mst_cbs = { |
333 | .add_connector = radeon_dp_add_mst_connector, | 333 | .add_connector = radeon_dp_add_mst_connector, |
334 | .register_connector = radeon_dp_register_mst_connector, | 334 | .register_connector = radeon_dp_register_mst_connector, |
335 | .destroy_connector = radeon_dp_destroy_mst_connector, | 335 | .destroy_connector = radeon_dp_destroy_mst_connector, |
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c index b80802f55143..db0763794edc 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c | |||
@@ -739,8 +739,6 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev, | |||
739 | if (ret < 0) | 739 | if (ret < 0) |
740 | goto err_backlight; | 740 | goto err_backlight; |
741 | 741 | ||
742 | connector->encoder = encoder; | ||
743 | |||
744 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 742 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); |
745 | drm_object_property_set_value(&connector->base, | 743 | drm_object_property_set_value(&connector->base, |
746 | sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); | 744 | sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); |
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index 1469987949d8..506b5626f3ed 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c | |||
@@ -160,6 +160,7 @@ static int sti_load(struct drm_device *dev, unsigned long flags) | |||
160 | 160 | ||
161 | drm_mode_config_reset(dev); | 161 | drm_mode_config_reset(dev); |
162 | 162 | ||
163 | drm_helper_disable_unused_functions(dev); | ||
163 | drm_fbdev_cma_init(dev, 32, | 164 | drm_fbdev_cma_init(dev, 32, |
164 | dev->mode_config.num_crtc, | 165 | dev->mode_config.num_crtc, |
165 | dev->mode_config.num_connector); | 166 | dev->mode_config.num_connector); |
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 50d46ae3786b..44e102799195 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
@@ -745,14 +745,13 @@ static void tegra_dsi_soft_reset(struct tegra_dsi *dsi) | |||
745 | 745 | ||
746 | static void tegra_dsi_connector_reset(struct drm_connector *connector) | 746 | static void tegra_dsi_connector_reset(struct drm_connector *connector) |
747 | { | 747 | { |
748 | struct tegra_dsi_state *state; | 748 | struct tegra_dsi_state *state = |
749 | 749 | kzalloc(sizeof(*state), GFP_KERNEL); | |
750 | kfree(connector->state); | ||
751 | connector->state = NULL; | ||
752 | 750 | ||
753 | state = kzalloc(sizeof(*state), GFP_KERNEL); | 751 | if (state) { |
754 | if (state) | 752 | kfree(connector->state); |
755 | connector->state = &state->base; | 753 | __drm_atomic_helper_connector_reset(connector, &state->base); |
754 | } | ||
756 | } | 755 | } |
757 | 756 | ||
758 | static struct drm_connector_state * | 757 | static struct drm_connector_state * |
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 4ddb21e7f52f..d7f5b897c6c5 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c | |||
@@ -294,6 +294,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) | |||
294 | break; | 294 | break; |
295 | } | 295 | } |
296 | 296 | ||
297 | drm_helper_disable_unused_functions(dev); | ||
297 | priv->fbdev = drm_fbdev_cma_init(dev, bpp, | 298 | priv->fbdev = drm_fbdev_cma_init(dev, bpp, |
298 | dev->mode_config.num_crtc, | 299 | dev->mode_config.num_crtc, |
299 | dev->mode_config.num_connector); | 300 | dev->mode_config.num_connector); |
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 8d0d70e51ef2..018145e0b87d 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
@@ -328,7 +328,7 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc, | |||
328 | /* The pixelvalve can only feed one encoder (and encoders are | 328 | /* The pixelvalve can only feed one encoder (and encoders are |
329 | * 1:1 with connectors.) | 329 | * 1:1 with connectors.) |
330 | */ | 330 | */ |
331 | if (drm_atomic_connectors_for_crtc(state->state, crtc) > 1) | 331 | if (hweight32(state->connector_mask) > 1) |
332 | return -EINVAL; | 332 | return -EINVAL; |
333 | 333 | ||
334 | drm_atomic_crtc_state_for_each_plane(plane, state) { | 334 | drm_atomic_crtc_state_for_each_plane(plane, state) { |
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 41edd5a3f100..d64d9058bce5 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
@@ -63,7 +63,7 @@ | |||
63 | * for the inactive GPU.) Also, muxes are often used to cut power to the | 63 | * for the inactive GPU.) Also, muxes are often used to cut power to the |
64 | * discrete GPU while it is not used. | 64 | * discrete GPU while it is not used. |
65 | * | 65 | * |
66 | * DRM drivers register GPUs with vga_switcheroo, these are heretoforth called | 66 | * DRM drivers register GPUs with vga_switcheroo, these are henceforth called |
67 | * clients. The mux is called the handler. Muxless machines also register a | 67 | * clients. The mux is called the handler. Muxless machines also register a |
68 | * handler to control the power state of the discrete GPU, its ->switchto | 68 | * handler to control the power state of the discrete GPU, its ->switchto |
69 | * callback is a no-op for obvious reasons. The discrete GPU is often equipped | 69 | * callback is a no-op for obvious reasons. The discrete GPU is often equipped |
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 976efeb3f2ba..2b921dea10f4 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> | 4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> |
5 | * Copyright (C) 2010-2012 Andreas Heider <andreas@meetr.de> | 5 | * Copyright (C) 2010-2012 Andreas Heider <andreas@meetr.de> |
6 | * Copyright (C) 2015 Lukas Wunner <lukas@wunner.de> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -26,6 +27,24 @@ | |||
26 | #include <acpi/video.h> | 27 | #include <acpi/video.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | 29 | ||
30 | /** | ||
31 | * DOC: Overview | ||
32 | * | ||
33 | * :1: http://www.latticesemi.com/en/Products/FPGAandCPLD/LatticeXP2.aspx | ||
34 | * :2: http://www.renesas.com/products/mpumcu/h8s/h8s2100/h8s2113/index.jsp | ||
35 | * | ||
36 | * gmux is a microcontroller built into the MacBook Pro to support dual GPUs: | ||
37 | * A {1}[Lattice XP2] on pre-retinas, a {2}[Renesas R4F2113] on retinas. | ||
38 | * | ||
39 | * (The MacPro6,1 2013 also has a gmux, however it is unclear why since it has | ||
40 | * dual GPUs but no built-in display.) | ||
41 | * | ||
42 | * gmux is connected to the LPC bus of the southbridge. Its I/O ports are | ||
43 | * accessed differently depending on the microcontroller: Driver functions | ||
44 | * to access a pre-retina gmux are infixed `_pio_`, those for a retina gmux | ||
45 | * are infixed `_index_`. | ||
46 | */ | ||
47 | |||
29 | struct apple_gmux_data { | 48 | struct apple_gmux_data { |
30 | unsigned long iostart; | 49 | unsigned long iostart; |
31 | unsigned long iolen; | 50 | unsigned long iolen; |
@@ -247,6 +266,20 @@ static bool gmux_is_indexed(struct apple_gmux_data *gmux_data) | |||
247 | return false; | 266 | return false; |
248 | } | 267 | } |
249 | 268 | ||
269 | /** | ||
270 | * DOC: Backlight control | ||
271 | * | ||
272 | * :3: http://www.ti.com/lit/ds/symlink/lp8543.pdf | ||
273 | * :4: http://www.ti.com/lit/ds/symlink/lp8545.pdf | ||
274 | * | ||
275 | * On single GPU MacBooks, the PWM signal for the backlight is generated by | ||
276 | * the GPU. On dual GPU MacBook Pros by contrast, either GPU may be suspended | ||
277 | * to conserve energy. Hence the PWM signal needs to be generated by a separate | ||
278 | * backlight driver which is controlled by gmux. The earliest generation | ||
279 | * MBP5 2008/09 uses a {3}[TI LP8543] backlight driver. All newer models | ||
280 | * use a {4}[TI LP8545]. | ||
281 | */ | ||
282 | |||
250 | static int gmux_get_brightness(struct backlight_device *bd) | 283 | static int gmux_get_brightness(struct backlight_device *bd) |
251 | { | 284 | { |
252 | struct apple_gmux_data *gmux_data = bl_get_data(bd); | 285 | struct apple_gmux_data *gmux_data = bl_get_data(bd); |
@@ -273,6 +306,68 @@ static const struct backlight_ops gmux_bl_ops = { | |||
273 | .update_status = gmux_update_status, | 306 | .update_status = gmux_update_status, |
274 | }; | 307 | }; |
275 | 308 | ||
309 | /** | ||
310 | * DOC: Graphics mux | ||
311 | * | ||
312 | * :5: http://pimg-fpiw.uspto.gov/fdd/07/870/086/0.pdf | ||
313 | * :6: http://www.nxp.com/documents/data_sheet/CBTL06141.pdf | ||
314 | * :7: http://www.ti.com/lit/ds/symlink/hd3ss212.pdf | ||
315 | * :8: https://www.pericom.com/assets/Datasheets/PI3VDP12412.pdf | ||
316 | * :9: http://www.ti.com/lit/ds/symlink/sn74lv4066a.pdf | ||
317 | * :10: http://pdf.datasheetarchive.com/indexerfiles/Datasheets-SW16/DSASW00308511.pdf | ||
318 | * :11: http://www.ti.com/lit/ds/symlink/ts3ds10224.pdf | ||
319 | * | ||
320 | * On pre-retinas, the LVDS outputs of both GPUs feed into gmux which muxes | ||
321 | * either of them to the panel. One of the tricks gmux has up its sleeve is | ||
322 | * to lengthen the blanking interval of its output during a switch to | ||
323 | * synchronize it with the GPU switched to. This allows for a flicker-free | ||
324 | * switch that is imperceptible by the user ({5}[US 8,687,007 B2]). | ||
325 | * | ||
326 | * On retinas, muxing is no longer done by gmux itself, but by a separate | ||
327 | * chip which is controlled by gmux. The chip is triple sourced, it is | ||
328 | * either an {6}[NXP CBTL06142], {7}[TI HD3SS212] or {8}[Pericom PI3VDP12412]. | ||
329 | * The panel is driven with eDP instead of LVDS since the pixel clock | ||
330 | * required for retina resolution exceeds LVDS' limits. | ||
331 | * | ||
332 | * Pre-retinas are able to switch the panel's DDC pins separately. | ||
333 | * This is handled by a {9}[TI SN74LV4066A] which is controlled by gmux. | ||
334 | * The inactive GPU can thus probe the panel's EDID without switching over | ||
335 | * the entire panel. Retinas lack this functionality as the chips used for | ||
336 | * eDP muxing are incapable of switching the AUX channel separately (see | ||
337 | * the linked data sheets, Pericom would be capable but this is unused). | ||
338 | * However the retina panel has the NO_AUX_HANDSHAKE_LINK_TRAINING bit set | ||
339 | * in its DPCD, allowing the inactive GPU to skip the AUX handshake and | ||
340 | * set up the output with link parameters pre-calibrated by the active GPU. | ||
341 | * | ||
342 | * The external DP port is only fully switchable on the first two unibody | ||
343 | * MacBook Pro generations, MBP5 2008/09 and MBP6 2010. This is done by an | ||
344 | * {6}[NXP CBTL06141] which is controlled by gmux. It's the predecessor of the | ||
345 | * eDP mux on retinas, the difference being support for 2.7 versus 5.4 Gbit/s. | ||
346 | * | ||
347 | * The following MacBook Pro generations replaced the external DP port with a | ||
348 | * combined DP/Thunderbolt port and lost the ability to switch it between GPUs, | ||
349 | * connecting it either to the discrete GPU or the Thunderbolt controller. | ||
350 | * Oddly enough, while the full port is no longer switchable, AUX and HPD | ||
351 | * are still switchable by way of an {10}[NXP CBTL03062] (on pre-retinas | ||
352 | * MBP8 2011 and MBP9 2012) or two {11}[TI TS3DS10224] (on retinas) under the | ||
353 | * control of gmux. Since the integrated GPU is missing the main link, | ||
354 | * external displays appear to it as phantoms which fail to link-train. | ||
355 | * | ||
356 | * gmux receives the HPD signal of all display connectors and sends an | ||
357 | * interrupt on hotplug. On generations which cannot switch external ports, | ||
358 | * the discrete GPU can then be woken to drive the newly connected display. | ||
359 | * The ability to switch AUX on these generations could be used to improve | ||
360 | * reliability of hotplug detection by having the integrated GPU poll the | ||
361 | * ports while the discrete GPU is asleep, but currently we do not make use | ||
362 | * of this feature. | ||
363 | * | ||
364 | * gmux' initial switch state on bootup is user configurable via the EFI | ||
365 | * variable `gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9` (5th byte, | ||
366 | * 1 = IGD, 0 = DIS). Based on this setting, the EFI firmware tells gmux to | ||
367 | * switch the panel and the external DP connector and allocates a framebuffer | ||
368 | * for the selected GPU. | ||
369 | */ | ||
370 | |||
276 | static int gmux_switchto(enum vga_switcheroo_client_id id) | 371 | static int gmux_switchto(enum vga_switcheroo_client_id id) |
277 | { | 372 | { |
278 | if (id == VGA_SWITCHEROO_IGD) { | 373 | if (id == VGA_SWITCHEROO_IGD) { |
@@ -288,6 +383,14 @@ static int gmux_switchto(enum vga_switcheroo_client_id id) | |||
288 | return 0; | 383 | return 0; |
289 | } | 384 | } |
290 | 385 | ||
386 | /** | ||
387 | * DOC: Power control | ||
388 | * | ||
389 | * gmux is able to cut power to the discrete GPU. It automatically takes care | ||
390 | * of the correct sequence to tear down and bring up the power rails for | ||
391 | * core voltage, VRAM and PCIe. | ||
392 | */ | ||
393 | |||
291 | static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, | 394 | static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, |
292 | enum vga_switcheroo_state state) | 395 | enum vga_switcheroo_state state) |
293 | { | 396 | { |
@@ -352,6 +455,16 @@ static const struct vga_switcheroo_handler gmux_handler = { | |||
352 | .get_client_id = gmux_get_client_id, | 455 | .get_client_id = gmux_get_client_id, |
353 | }; | 456 | }; |
354 | 457 | ||
458 | /** | ||
459 | * DOC: Interrupt | ||
460 | * | ||
461 | * gmux is also connected to a GPIO pin of the southbridge and thereby is able | ||
462 | * to trigger an ACPI GPE. On the MBP5 2008/09 it's GPIO pin 22 of the Nvidia | ||
463 | * MCP79, on all following generations it's GPIO pin 6 of the Intel PCH. | ||
464 | * The GPE merely signals that an interrupt occurred, the actual type of event | ||
465 | * is identified by reading a gmux register. | ||
466 | */ | ||
467 | |||
355 | static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data) | 468 | static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data) |
356 | { | 469 | { |
357 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, | 470 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, |
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index d8576ac55693..d3eaa5df187a 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h | |||
@@ -130,10 +130,6 @@ int __must_check | |||
130 | drm_atomic_add_affected_planes(struct drm_atomic_state *state, | 130 | drm_atomic_add_affected_planes(struct drm_atomic_state *state, |
131 | struct drm_crtc *crtc); | 131 | struct drm_crtc *crtc); |
132 | 132 | ||
133 | int | ||
134 | drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, | ||
135 | struct drm_crtc *crtc); | ||
136 | |||
137 | void drm_atomic_legacy_backoff(struct drm_atomic_state *state); | 133 | void drm_atomic_legacy_backoff(struct drm_atomic_state *state); |
138 | 134 | ||
139 | void | 135 | void |
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index a286cce98720..89d008dc08e2 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h | |||
@@ -126,6 +126,8 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, | |||
126 | void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, | 126 | void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, |
127 | struct drm_plane_state *state); | 127 | struct drm_plane_state *state); |
128 | 128 | ||
129 | void __drm_atomic_helper_connector_reset(struct drm_connector *connector, | ||
130 | struct drm_connector_state *conn_state); | ||
129 | void drm_atomic_helper_connector_reset(struct drm_connector *connector); | 131 | void drm_atomic_helper_connector_reset(struct drm_connector *connector); |
130 | void | 132 | void |
131 | __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, | 133 | __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 3b040b355472..c65a212db77e 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -306,6 +306,7 @@ struct drm_plane_helper_funcs; | |||
306 | * @active_changed: crtc_state->active has been toggled. | 306 | * @active_changed: crtc_state->active has been toggled. |
307 | * @connectors_changed: connectors to this crtc have been updated | 307 | * @connectors_changed: connectors to this crtc have been updated |
308 | * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes | 308 | * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes |
309 | * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors | ||
309 | * @last_vblank_count: for helpers and drivers to capture the vblank of the | 310 | * @last_vblank_count: for helpers and drivers to capture the vblank of the |
310 | * update to ensure framebuffer cleanup isn't done too early | 311 | * update to ensure framebuffer cleanup isn't done too early |
311 | * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings | 312 | * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings |
@@ -339,6 +340,8 @@ struct drm_crtc_state { | |||
339 | */ | 340 | */ |
340 | u32 plane_mask; | 341 | u32 plane_mask; |
341 | 342 | ||
343 | u32 connector_mask; | ||
344 | |||
342 | /* last_vblank_count: for vblank waits before cleanup */ | 345 | /* last_vblank_count: for vblank waits before cleanup */ |
343 | u32 last_vblank_count; | 346 | u32 last_vblank_count; |
344 | 347 | ||
@@ -548,7 +551,8 @@ struct drm_crtc_funcs { | |||
548 | * ->page_flip() operation is already pending the callback should return | 551 | * ->page_flip() operation is already pending the callback should return |
549 | * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode | 552 | * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode |
550 | * or just runtime disabled through DPMS respectively the new atomic | 553 | * or just runtime disabled through DPMS respectively the new atomic |
551 | * "ACTIVE" state) should result in an -EINVAL error code. | 554 | * "ACTIVE" state) should result in an -EINVAL error code. Note that |
555 | * drm_atomic_helper_page_flip() checks this already for atomic drivers. | ||
552 | */ | 556 | */ |
553 | int (*page_flip)(struct drm_crtc *crtc, | 557 | int (*page_flip)(struct drm_crtc *crtc, |
554 | struct drm_framebuffer *fb, | 558 | struct drm_framebuffer *fb, |
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 4fc55a87dfee..24ab1787b771 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h | |||
@@ -421,7 +421,7 @@ struct drm_dp_payload { | |||
421 | struct drm_dp_mst_topology_mgr { | 421 | struct drm_dp_mst_topology_mgr { |
422 | 422 | ||
423 | struct device *dev; | 423 | struct device *dev; |
424 | struct drm_dp_mst_topology_cbs *cbs; | 424 | const struct drm_dp_mst_topology_cbs *cbs; |
425 | int max_dpcd_transaction_bytes; | 425 | int max_dpcd_transaction_bytes; |
426 | struct drm_dp_aux *aux; /* auxch for this topology mgr to use */ | 426 | struct drm_dp_aux *aux; /* auxch for this topology mgr to use */ |
427 | int max_payloads; | 427 | int max_payloads; |
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 29e0dc50031d..a126a0d7aed4 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h | |||
@@ -131,6 +131,20 @@ struct drm_crtc_helper_funcs { | |||
131 | * Atomic drivers which need to inspect and adjust more state should | 131 | * Atomic drivers which need to inspect and adjust more state should |
132 | * instead use the @atomic_check callback. | 132 | * instead use the @atomic_check callback. |
133 | * | 133 | * |
134 | * Also beware that neither core nor helpers filter modes before | ||
135 | * passing them to the driver: While the list of modes that is | ||
136 | * advertised to userspace is filtered using the connector's | ||
137 | * ->mode_valid() callback, neither the core nor the helpers do any | ||
138 | * filtering on modes passed in from userspace when setting a mode. It | ||
139 | * is therefore possible for userspace to pass in a mode that was | ||
140 | * previously filtered out using ->mode_valid() or add a custom mode | ||
141 | * that wasn't probed from EDID or similar to begin with. Even though | ||
142 | * this is an advanced feature and rarely used nowadays, some users rely | ||
143 | * on being able to specify modes manually so drivers must be prepared | ||
144 | * to deal with it. Specifically this means that all drivers need not | ||
145 | * only validate modes in ->mode_valid() but also in ->mode_fixup() to | ||
146 | * make sure invalid modes passed in from userspace are rejected. | ||
147 | * | ||
134 | * RETURNS: | 148 | * RETURNS: |
135 | * | 149 | * |
136 | * True if an acceptable configuration is possible, false if the modeset | 150 | * True if an acceptable configuration is possible, false if the modeset |
@@ -188,7 +202,9 @@ struct drm_crtc_helper_funcs { | |||
188 | * This callback is used by the legacy CRTC helpers to set a new | 202 | * This callback is used by the legacy CRTC helpers to set a new |
189 | * framebuffer and scanout position. It is optional and used as an | 203 | * framebuffer and scanout position. It is optional and used as an |
190 | * optimized fast-path instead of a full mode set operation with all the | 204 | * optimized fast-path instead of a full mode set operation with all the |
191 | * resulting flickering. Since it can't update other planes it's | 205 | * resulting flickering. If it is not present |
206 | * drm_crtc_helper_set_config() will fall back to a full modeset, using | ||
207 | * the ->mode_set() callback. Since it can't update other planes it's | ||
192 | * incompatible with atomic modeset support. | 208 | * incompatible with atomic modeset support. |
193 | * | 209 | * |
194 | * This callback is only used by the CRTC helpers and deprecated. | 210 | * This callback is only used by the CRTC helpers and deprecated. |
@@ -439,6 +455,20 @@ struct drm_encoder_helper_funcs { | |||
439 | * Atomic drivers which need to inspect and adjust more state should | 455 | * Atomic drivers which need to inspect and adjust more state should |
440 | * instead use the @atomic_check callback. | 456 | * instead use the @atomic_check callback. |
441 | * | 457 | * |
458 | * Also beware that neither core nor helpers filter modes before | ||
459 | * passing them to the driver: While the list of modes that is | ||
460 | * advertised to userspace is filtered using the connector's | ||
461 | * ->mode_valid() callback, neither the core nor the helpers do any | ||
462 | * filtering on modes passed in from userspace when setting a mode. It | ||
463 | * is therefore possible for userspace to pass in a mode that was | ||
464 | * previously filtered out using ->mode_valid() or add a custom mode | ||
465 | * that wasn't probed from EDID or similar to begin with. Even though | ||
466 | * this is an advanced feature and rarely used nowadays, some users rely | ||
467 | * on being able to specify modes manually so drivers must be prepared | ||
468 | * to deal with it. Specifically this means that all drivers need not | ||
469 | * only validate modes in ->mode_valid() but also in ->mode_fixup() to | ||
470 | * make sure invalid modes passed in from userspace are rejected. | ||
471 | * | ||
442 | * RETURNS: | 472 | * RETURNS: |
443 | * | 473 | * |
444 | * True if an acceptable configuration is possible, false if the modeset | 474 | * True if an acceptable configuration is possible, false if the modeset |
@@ -640,8 +670,16 @@ struct drm_connector_helper_funcs { | |||
640 | * In this function drivers then parse the modes in the EDID and add | 670 | * In this function drivers then parse the modes in the EDID and add |
641 | * them by calling drm_add_edid_modes(). But connectors that driver a | 671 | * them by calling drm_add_edid_modes(). But connectors that driver a |
642 | * fixed panel can also manually add specific modes using | 672 | * fixed panel can also manually add specific modes using |
643 | * drm_mode_probed_add(). Finally drivers that support audio probably | 673 | * drm_mode_probed_add(). Drivers which manually add modes should also |
644 | * want to update the ELD data, too, using drm_edid_to_eld(). | 674 | * make sure that the @display_info, @width_mm and @height_mm fields of the |
675 | * struct #drm_connector are filled in. | ||
676 | * | ||
677 | * Virtual drivers that just want some standard VESA mode with a given | ||
678 | * resolution can call drm_add_modes_noedid(), and mark the preferred | ||
679 | * one using drm_set_preferred_mode(). | ||
680 | * | ||
681 | * Finally drivers that support audio probably want to update the ELD | ||
682 | * data, too, using drm_edid_to_eld(). | ||
645 | * | 683 | * |
646 | * This function is only called after the ->detect() hook has indicated | 684 | * This function is only called after the ->detect() hook has indicated |
647 | * that a sink is connected and when the EDID isn't overridden through | 685 | * that a sink is connected and when the EDID isn't overridden through |