• Mario Kleiner's avatar
    drm/vc4: Implement precise vblank timestamping. · 1bf59f1d
    Mario Kleiner authored
    Precise vblank timestamping is implemented via the
    usual scanout position based method. On VC4 the
    pixelvalves PV do not have a scanout position
    register. Only the hardware video scaler HVS has a
    similar register which describes which scanline for
    the output is currently composited and stored in the
    HVS fifo for later consumption by the PV.
    
    This causes a problem in that the HVS runs at a much
    faster clock (system clock / audio gate) than the PV
    which runs at video mode dot clock, so the unless the
    fifo between HVS and PV is full, the HVS will progress
    faster in its observable read line position than video
    scan rate, so the HVS position reading can't be directly
    translated into a scanout position for timestamp correction.
    
    Additionally when the PV is in vblank, it doesn't consume
    from the fifo, so the fifo gets full very quickly and then
    the HVS stops compositing until the PV enters active scanout
    and starts consuming scanlines from the fifo again, making
    new space for the HVS to composite.
    
    Therefore a simple translation of HVS read position into
    elapsed time since (or to) start of active scanout does
    not work, but for the most interesting cases we can still
    get useful and sufficiently accurate results:
    
    1. The PV enters active scanout of a new frame with the
       fifo of the HVS completely full, and the HVS can refill
       any fifo line which gets consumed and thereby freed up by
       the PV during active scanout very quickly. Therefore the
       PV and HVS work effectively in lock-step during active
       scanout with the fifo never having more than 1 scanline
       freed up by the PV before it gets refilled. The PV's
       real scanout position is therefore trailing the HVS
       compositing position as scanoutpos = hvspos - fifosize
       and we can get the true scanoutpos as HVS readpos minus
       fifo size, so precise timestamping works while in active
       scanout, except for the last few scanlines of the frame,
       when the HVS reaches end of frame, stops compositing and
       the PV catches up and drains the fifo. This special case
       would only introduce minor errors though.
    
    2. If we are in vblank, then we can only guess something
       reasonable. If called from vblank irq, we assume the irq is
       usually dispatched with minimum delay, so we can take a
       timestamp taken at entry into the vblank irq handler as a
       baseline and then add a full vblank duration until the
       guessed start of active scanout. As irq dispatch is usually
       pretty low latency this works with relatively low jitter and
       good results.
    
       If we aren't called from vblank then we could be anywhere
       within the vblank interval, so we return a neutral result,
       simply the current system timestamp, and hope for the best.
    
    Measurement shows the generated timestamps to be rather precise,
    and at least never off more than 1 vblank duration worst-case.
    
    Limitations: Doesn't work well yet for interlaced video modes,
                 therefore disabled in interlaced mode for now.
    
    v2: Use the DISPBASE registers to determine the FIFO size (changes
        by anholt)
    Signed-off-by: default avatarMario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: default avatarEric Anholt <eric@anholt.net>
    Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com> (v2)
    1bf59f1d
vc4_regs.h 25.1 KB