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 ---