disp.c (34508f9d260cbd7b91f988c858f50ad956750ee3) | disp.c (53e0a3e70de69dc9f498d26c6b5495b2771ee374) |
---|---|
1/* 2 * Copyright 2011 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the --- 1568 unchanged lines hidden (view full) --- 1577 return 0; 1578} 1579 1580/****************************************************************************** 1581 * Atomic 1582 *****************************************************************************/ 1583 1584static void | 1/* 2 * Copyright 2011 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the --- 1568 unchanged lines hidden (view full) --- 1577 return 0; 1578} 1579 1580/****************************************************************************** 1581 * Atomic 1582 *****************************************************************************/ 1583 1584static void |
1585nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock) | 1585nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock) |
1586{ 1587 struct nv50_disp *disp = nv50_disp(drm->dev); 1588 struct nv50_core *core = disp->core; 1589 struct nv50_mstm *mstm; 1590 struct drm_encoder *encoder; 1591 | 1586{ 1587 struct nv50_disp *disp = nv50_disp(drm->dev); 1588 struct nv50_core *core = disp->core; 1589 struct nv50_mstm *mstm; 1590 struct drm_encoder *encoder; 1591 |
1592 NV_ATOMIC(drm, "commit core %08x\n", interlock); | 1592 NV_ATOMIC(drm, "commit core %08x\n", interlock[NV50_DISP_INTERLOCK_BASE]); |
1593 1594 drm_for_each_encoder(encoder, drm->dev) { 1595 if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { 1596 mstm = nouveau_encoder(encoder)->dp.mstm; 1597 if (mstm && mstm->modified) 1598 nv50_mstm_prepare(mstm); 1599 } 1600 } --- 20 unchanged lines hidden (view full) --- 1621 struct drm_crtc_state *new_crtc_state, *old_crtc_state; 1622 struct drm_crtc *crtc; 1623 struct drm_plane_state *new_plane_state; 1624 struct drm_plane *plane; 1625 struct nouveau_drm *drm = nouveau_drm(dev); 1626 struct nv50_disp *disp = nv50_disp(dev); 1627 struct nv50_atom *atom = nv50_atom(state); 1628 struct nv50_outp_atom *outp, *outt; | 1593 1594 drm_for_each_encoder(encoder, drm->dev) { 1595 if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { 1596 mstm = nouveau_encoder(encoder)->dp.mstm; 1597 if (mstm && mstm->modified) 1598 nv50_mstm_prepare(mstm); 1599 } 1600 } --- 20 unchanged lines hidden (view full) --- 1621 struct drm_crtc_state *new_crtc_state, *old_crtc_state; 1622 struct drm_crtc *crtc; 1623 struct drm_plane_state *new_plane_state; 1624 struct drm_plane *plane; 1625 struct nouveau_drm *drm = nouveau_drm(dev); 1626 struct nv50_disp *disp = nv50_disp(dev); 1627 struct nv50_atom *atom = nv50_atom(state); 1628 struct nv50_outp_atom *outp, *outt; |
1629 u32 interlock_core = 0; 1630 u32 interlock_chan = 0; | 1629 u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {}; |
1631 int i; 1632 1633 NV_ATOMIC(drm, "commit %d %d\n", atom->lock_core, atom->flush_disable); 1634 drm_atomic_helper_wait_for_fences(dev, state, false); 1635 drm_atomic_helper_wait_for_dependencies(state); 1636 drm_atomic_helper_update_legacy_modeset_state(dev, state); 1637 1638 if (atom->lock_core) --- 6 unchanged lines hidden (view full) --- 1645 1646 NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name, 1647 asyh->clr.mask, asyh->set.mask); 1648 if (old_crtc_state->active && !new_crtc_state->active) 1649 drm_crtc_vblank_off(crtc); 1650 1651 if (asyh->clr.mask) { 1652 nv50_head_flush_clr(head, asyh, atom->flush_disable); | 1630 int i; 1631 1632 NV_ATOMIC(drm, "commit %d %d\n", atom->lock_core, atom->flush_disable); 1633 drm_atomic_helper_wait_for_fences(dev, state, false); 1634 drm_atomic_helper_wait_for_dependencies(state); 1635 drm_atomic_helper_update_legacy_modeset_state(dev, state); 1636 1637 if (atom->lock_core) --- 6 unchanged lines hidden (view full) --- 1644 1645 NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name, 1646 asyh->clr.mask, asyh->set.mask); 1647 if (old_crtc_state->active && !new_crtc_state->active) 1648 drm_crtc_vblank_off(crtc); 1649 1650 if (asyh->clr.mask) { 1651 nv50_head_flush_clr(head, asyh, atom->flush_disable); |
1653 interlock_core |= 1; | 1652 interlock[NV50_DISP_INTERLOCK_CORE] |= 1; |
1654 } 1655 } 1656 1657 /* Disable plane(s). */ 1658 for_each_new_plane_in_state(state, plane, new_plane_state, i) { 1659 struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); 1660 struct nv50_wndw *wndw = nv50_wndw(plane); 1661 1662 NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", plane->name, 1663 asyw->clr.mask, asyw->set.mask); 1664 if (!asyw->clr.mask) 1665 continue; 1666 | 1653 } 1654 } 1655 1656 /* Disable plane(s). */ 1657 for_each_new_plane_in_state(state, plane, new_plane_state, i) { 1658 struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); 1659 struct nv50_wndw *wndw = nv50_wndw(plane); 1660 1661 NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", plane->name, 1662 asyw->clr.mask, asyw->set.mask); 1663 if (!asyw->clr.mask) 1664 continue; 1665 |
1667 interlock_chan |= nv50_wndw_flush_clr(wndw, interlock_core, 1668 atom->flush_disable, 1669 asyw); | 1666 nv50_wndw_flush_clr(wndw, interlock, atom->flush_disable, asyw); |
1670 } 1671 1672 /* Disable output path(s). */ 1673 list_for_each_entry(outp, &atom->outp, head) { 1674 const struct drm_encoder_helper_funcs *help; 1675 struct drm_encoder *encoder; 1676 1677 encoder = outp->encoder; 1678 help = encoder->helper_private; 1679 1680 NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", encoder->name, 1681 outp->clr.mask, outp->set.mask); 1682 1683 if (outp->clr.mask) { 1684 help->disable(encoder); | 1667 } 1668 1669 /* Disable output path(s). */ 1670 list_for_each_entry(outp, &atom->outp, head) { 1671 const struct drm_encoder_helper_funcs *help; 1672 struct drm_encoder *encoder; 1673 1674 encoder = outp->encoder; 1675 help = encoder->helper_private; 1676 1677 NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", encoder->name, 1678 outp->clr.mask, outp->set.mask); 1679 1680 if (outp->clr.mask) { 1681 help->disable(encoder); |
1685 interlock_core |= 1; | 1682 interlock[NV50_DISP_INTERLOCK_CORE] |= 1; |
1686 if (outp->flush_disable) { | 1683 if (outp->flush_disable) { |
1687 nv50_disp_atomic_commit_core(drm, interlock_chan); 1688 interlock_core = 0; 1689 interlock_chan = 0; | 1684 nv50_disp_atomic_commit_core(drm, interlock); 1685 memset(interlock, 0x00, sizeof(interlock)); |
1690 } 1691 } 1692 } 1693 1694 /* Flush disable. */ | 1686 } 1687 } 1688 } 1689 1690 /* Flush disable. */ |
1695 if (interlock_core) { | 1691 if (interlock[NV50_DISP_INTERLOCK_CORE]) { |
1696 if (atom->flush_disable) { | 1692 if (atom->flush_disable) { |
1697 nv50_disp_atomic_commit_core(drm, interlock_chan); 1698 interlock_core = 0; 1699 interlock_chan = 0; | 1693 nv50_disp_atomic_commit_core(drm, interlock); 1694 memset(interlock, 0x00, sizeof(interlock)); |
1700 } 1701 } 1702 1703 /* Update output path(s). */ 1704 list_for_each_entry_safe(outp, outt, &atom->outp, head) { 1705 const struct drm_encoder_helper_funcs *help; 1706 struct drm_encoder *encoder; 1707 1708 encoder = outp->encoder; 1709 help = encoder->helper_private; 1710 1711 NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", encoder->name, 1712 outp->set.mask, outp->clr.mask); 1713 1714 if (outp->set.mask) { 1715 help->enable(encoder); | 1695 } 1696 } 1697 1698 /* Update output path(s). */ 1699 list_for_each_entry_safe(outp, outt, &atom->outp, head) { 1700 const struct drm_encoder_helper_funcs *help; 1701 struct drm_encoder *encoder; 1702 1703 encoder = outp->encoder; 1704 help = encoder->helper_private; 1705 1706 NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", encoder->name, 1707 outp->set.mask, outp->clr.mask); 1708 1709 if (outp->set.mask) { 1710 help->enable(encoder); |
1716 interlock_core = 1; | 1711 interlock[NV50_DISP_INTERLOCK_CORE] = 1; |
1717 } 1718 1719 list_del(&outp->head); 1720 kfree(outp); 1721 } 1722 1723 /* Update head(s). */ 1724 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 1725 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state); 1726 struct nv50_head *head = nv50_head(crtc); 1727 1728 NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name, 1729 asyh->set.mask, asyh->clr.mask); 1730 1731 if (asyh->set.mask) { 1732 nv50_head_flush_set(head, asyh); | 1712 } 1713 1714 list_del(&outp->head); 1715 kfree(outp); 1716 } 1717 1718 /* Update head(s). */ 1719 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 1720 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state); 1721 struct nv50_head *head = nv50_head(crtc); 1722 1723 NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name, 1724 asyh->set.mask, asyh->clr.mask); 1725 1726 if (asyh->set.mask) { 1727 nv50_head_flush_set(head, asyh); |
1733 interlock_core = 1; | 1728 interlock[NV50_DISP_INTERLOCK_CORE] = 1; |
1734 } 1735 1736 if (new_crtc_state->active) { 1737 if (!old_crtc_state->active) 1738 drm_crtc_vblank_on(crtc); 1739 if (new_crtc_state->event) 1740 drm_crtc_vblank_get(crtc); 1741 } --- 5 unchanged lines hidden (view full) --- 1747 struct nv50_wndw *wndw = nv50_wndw(plane); 1748 1749 NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", plane->name, 1750 asyw->set.mask, asyw->clr.mask); 1751 if ( !asyw->set.mask && 1752 (!asyw->clr.mask || atom->flush_disable)) 1753 continue; 1754 | 1729 } 1730 1731 if (new_crtc_state->active) { 1732 if (!old_crtc_state->active) 1733 drm_crtc_vblank_on(crtc); 1734 if (new_crtc_state->event) 1735 drm_crtc_vblank_get(crtc); 1736 } --- 5 unchanged lines hidden (view full) --- 1742 struct nv50_wndw *wndw = nv50_wndw(plane); 1743 1744 NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", plane->name, 1745 asyw->set.mask, asyw->clr.mask); 1746 if ( !asyw->set.mask && 1747 (!asyw->clr.mask || atom->flush_disable)) 1748 continue; 1749 |
1755 interlock_chan |= nv50_wndw_flush_set(wndw, interlock_core, asyw); | 1750 nv50_wndw_flush_set(wndw, interlock, asyw); |
1756 } 1757 1758 /* Flush update. */ | 1751 } 1752 1753 /* Flush update. */ |
1759 if (interlock_core) { 1760 if (interlock_chan || !atom->state.legacy_cursor_update) 1761 nv50_disp_atomic_commit_core(drm, interlock_chan); | 1754 if (interlock[NV50_DISP_INTERLOCK_CORE]) { 1755 if (interlock[NV50_DISP_INTERLOCK_BASE] || 1756 !atom->state.legacy_cursor_update) 1757 nv50_disp_atomic_commit_core(drm, interlock); |
1762 else | 1758 else |
1763 disp->core->func->update(disp->core, 0, false); | 1759 disp->core->func->update(disp->core, interlock, false); |
1764 } 1765 1766 if (atom->lock_core) 1767 mutex_unlock(&disp->mutex); 1768 1769 /* Wait for HW to signal completion. */ 1770 for_each_new_plane_in_state(state, plane, new_plane_state, i) { 1771 struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); --- 438 unchanged lines hidden --- | 1760 } 1761 1762 if (atom->lock_core) 1763 mutex_unlock(&disp->mutex); 1764 1765 /* Wait for HW to signal completion. */ 1766 for_each_new_plane_in_state(state, plane, new_plane_state, i) { 1767 struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); --- 438 unchanged lines hidden --- |