Rev 6104 | Rev 6938 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6104 | Rev 6321 | ||
---|---|---|---|
Line 1447... | Line 1447... | ||
1447 | * an optional accurate timestamp of when query happened. |
1447 | * an optional accurate timestamp of when query happened. |
1448 | * |
1448 | * |
1449 | * \param dev Device to query. |
1449 | * \param dev Device to query. |
1450 | * \param crtc Crtc to query. |
1450 | * \param crtc Crtc to query. |
1451 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). |
1451 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). |
- | 1452 | * For driver internal use only also supports these flags: |
|
- | 1453 | * |
|
- | 1454 | * USE_REAL_VBLANKSTART to use the real start of vblank instead |
|
- | 1455 | * of a fudged earlier start of vblank. |
|
- | 1456 | * |
|
- | 1457 | * GET_DISTANCE_TO_VBLANKSTART to return distance to the |
|
- | 1458 | * fudged earlier start of vblank in *vpos and the distance |
|
- | 1459 | * to true start of vblank in *hpos. |
|
- | 1460 | * |
|
1452 | * \param *vpos Location where vertical scanout position should be stored. |
1461 | * \param *vpos Location where vertical scanout position should be stored. |
1453 | * \param *hpos Location where horizontal scanout position should go. |
1462 | * \param *hpos Location where horizontal scanout position should go. |
1454 | * \param *stime Target location for timestamp taken immediately before |
1463 | * \param *stime Target location for timestamp taken immediately before |
1455 | * scanout position query. Can be NULL to skip timestamp. |
1464 | * scanout position query. Can be NULL to skip timestamp. |
1456 | * \param *etime Target location for timestamp taken immediately after |
1465 | * \param *etime Target location for timestamp taken immediately after |
Line 1590... | Line 1599... | ||
1590 | /* No: Fake something reasonable which gives at least ok results. */ |
1599 | /* No: Fake something reasonable which gives at least ok results. */ |
1591 | vbl_start = mode->crtc_vdisplay; |
1600 | vbl_start = mode->crtc_vdisplay; |
1592 | vbl_end = 0; |
1601 | vbl_end = 0; |
1593 | } |
1602 | } |
Line -... | Line 1603... | ||
- | 1603 | ||
- | 1604 | /* Called from driver internal vblank counter query code? */ |
|
- | 1605 | if (flags & GET_DISTANCE_TO_VBLANKSTART) { |
|
- | 1606 | /* Caller wants distance from real vbl_start in *hpos */ |
|
- | 1607 | *hpos = *vpos - vbl_start; |
|
- | 1608 | } |
|
- | 1609 | ||
- | 1610 | /* Fudge vblank to start a few scanlines earlier to handle the |
|
- | 1611 | * problem that vblank irqs fire a few scanlines before start |
|
- | 1612 | * of vblank. Some driver internal callers need the true vblank |
|
- | 1613 | * start to be used and signal this via the USE_REAL_VBLANKSTART flag. |
|
- | 1614 | * |
|
- | 1615 | * The cause of the "early" vblank irq is that the irq is triggered |
|
- | 1616 | * by the line buffer logic when the line buffer read position enters |
|
- | 1617 | * the vblank, whereas our crtc scanout position naturally lags the |
|
- | 1618 | * line buffer read position. |
|
- | 1619 | */ |
|
- | 1620 | if (!(flags & USE_REAL_VBLANKSTART)) |
|
- | 1621 | vbl_start -= rdev->mode_info.crtcs[pipe]->lb_vblank_lead_lines; |
|
1594 | 1622 | ||
1595 | /* Test scanout position against vblank region. */ |
1623 | /* Test scanout position against vblank region. */ |
1596 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) |
1624 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) |
Line -... | Line 1625... | ||
- | 1625 | in_vbl = false; |
|
- | 1626 | ||
- | 1627 | /* In vblank? */ |
|
- | 1628 | if (in_vbl) |
|
- | 1629 | ret |= DRM_SCANOUTPOS_IN_VBLANK; |
|
- | 1630 | ||
- | 1631 | /* Called from driver internal vblank counter query code? */ |
|
- | 1632 | if (flags & GET_DISTANCE_TO_VBLANKSTART) { |
|
- | 1633 | /* Caller wants distance from fudged earlier vbl_start */ |
|
- | 1634 | *vpos -= vbl_start; |
|
- | 1635 | return ret; |
|
1597 | in_vbl = false; |
1636 | } |
1598 | 1637 | ||
1599 | /* Check if inside vblank area and apply corrective offsets: |
1638 | /* Check if inside vblank area and apply corrective offsets: |
1600 | * vpos will then be >=0 in video scanout area, but negative |
1639 | * vpos will then be >=0 in video scanout area, but negative |
1601 | * within vblank area, counting down the number of lines until |
1640 | * within vblank area, counting down the number of lines until |
Line 1609... | Line 1648... | ||
1609 | } |
1648 | } |
Line 1610... | Line 1649... | ||
1610 | 1649 | ||
1611 | /* Correct for shifted end of vbl at vbl_end. */ |
1650 | /* Correct for shifted end of vbl at vbl_end. */ |
Line 1612... | Line -... | ||
1612 | *vpos = *vpos - vbl_end; |
- | |
1613 | - | ||
1614 | /* In vblank? */ |
- | |
1615 | if (in_vbl) |
- | |
1616 | ret |= DRM_SCANOUTPOS_IN_VBLANK; |
- | |
1617 | - | ||
1618 | /* Is vpos outside nominal vblank area, but less than |
- | |
1619 | * 1/100 of a frame height away from start of vblank? |
- | |
1620 | * If so, assume this isn't a massively delayed vblank |
- | |
1621 | * interrupt, but a vblank interrupt that fired a few |
- | |
1622 | * microseconds before true start of vblank. Compensate |
- | |
1623 | * by adding a full frame duration to the final timestamp. |
- | |
1624 | * Happens, e.g., on ATI R500, R600. |
- | |
1625 | * |
- | |
1626 | * We only do this if DRM_CALLED_FROM_VBLIRQ. |
- | |
1627 | */ |
- | |
1628 | if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { |
- | |
1629 | vbl_start = mode->crtc_vdisplay; |
- | |
1630 | vtotal = mode->crtc_vtotal; |
- | |
1631 | - | ||
1632 | if (vbl_start - *vpos < vtotal / 100) { |
- | |
1633 | *vpos -= vtotal; |
- | |
1634 | - | ||
1635 | /* Signal this correction as "applied". */ |
- | |
1636 | ret |= 0x8; |
- | |
1637 | } |
- | |
1638 | } |
1651 | *vpos = *vpos - vbl_end; |
1639 | 1652 |