lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 289/879] drm/vc4: hvs: Fix frame count register readout
    Date
    From: Maxime Ripard <maxime@cerno.tech>

    [ Upstream commit b51cd7ad143d2eb31a6df81c2183128920e47c2b ]

    In order to get the field currently being output, the driver has been
    using the display FIFO frame count in the HVS, reading a 6-bit field at
    the offset 12 in the DISPSTATx register.

    While that field is indeed at that location for the FIFO 1 and 2, the
    one for the FIFO0 is actually in the DISPSTAT1 register, at the offset
    18.

    Fixes: e538092cb15c ("drm/vc4: Enable precise vblank timestamping for interlaced modes.")
    Signed-off-by: Maxime Ripard <maxime@cerno.tech>
    Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
    Link: https://lore.kernel.org/r/20220331143744.777652-3-maxime@cerno.tech
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
    drivers/gpu/drm/vc4/vc4_drv.h | 1 +
    drivers/gpu/drm/vc4/vc4_hvs.c | 23 +++++++++++++++++++++++
    drivers/gpu/drm/vc4/vc4_regs.h | 12 ++++++++++--
    4 files changed, 35 insertions(+), 3 deletions(-)

    diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
    index 783890e8d43a..477b3c5ad089 100644
    --- a/drivers/gpu/drm/vc4/vc4_crtc.c
    +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
    @@ -123,7 +123,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc,
    *vpos /= 2;

    /* Use hpos to correct for field offset in interlaced mode. */
    - if (VC4_GET_FIELD(val, SCALER_DISPSTATX_FRAME_COUNT) % 2)
    + if (vc4_hvs_get_fifo_frame_count(dev, vc4_crtc_state->assigned_channel) % 2)
    *hpos += mode->crtc_htotal / 2;
    }

    diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
    index 4329e09d357c..801da3e8ebdb 100644
    --- a/drivers/gpu/drm/vc4/vc4_drv.h
    +++ b/drivers/gpu/drm/vc4/vc4_drv.h
    @@ -935,6 +935,7 @@ void vc4_irq_reset(struct drm_device *dev);
    extern struct platform_driver vc4_hvs_driver;
    void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output);
    int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output);
    +u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo);
    int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void vc4_hvs_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state);
    void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state);
    diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
    index 604933e20e6a..c8cae10500b9 100644
    --- a/drivers/gpu/drm/vc4/vc4_hvs.c
    +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
    @@ -197,6 +197,29 @@ static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc)
    vc4_hvs_lut_load(crtc);
    }

    +u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo)
    +{
    + struct vc4_dev *vc4 = to_vc4_dev(dev);
    + u8 field = 0;
    +
    + switch (fifo) {
    + case 0:
    + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT1),
    + SCALER_DISPSTAT1_FRCNT0);
    + break;
    + case 1:
    + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT1),
    + SCALER_DISPSTAT1_FRCNT1);
    + break;
    + case 2:
    + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT2),
    + SCALER_DISPSTAT2_FRCNT2);
    + break;
    + }
    +
    + return field;
    +}
    +
    int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output)
    {
    struct vc4_dev *vc4 = to_vc4_dev(dev);
    diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
    index 33410718089e..bae8c9cd6f7c 100644
    --- a/drivers/gpu/drm/vc4/vc4_regs.h
    +++ b/drivers/gpu/drm/vc4/vc4_regs.h
    @@ -379,8 +379,6 @@
    # define SCALER_DISPSTATX_MODE_EOF 3
    # define SCALER_DISPSTATX_FULL BIT(29)
    # define SCALER_DISPSTATX_EMPTY BIT(28)
    -# define SCALER_DISPSTATX_FRAME_COUNT_MASK VC4_MASK(17, 12)
    -# define SCALER_DISPSTATX_FRAME_COUNT_SHIFT 12
    # define SCALER_DISPSTATX_LINE_MASK VC4_MASK(11, 0)
    # define SCALER_DISPSTATX_LINE_SHIFT 0

    @@ -403,9 +401,15 @@
    (x) * (SCALER_DISPBKGND1 - \
    SCALER_DISPBKGND0))
    #define SCALER_DISPSTAT1 0x00000058
    +# define SCALER_DISPSTAT1_FRCNT0_MASK VC4_MASK(23, 18)
    +# define SCALER_DISPSTAT1_FRCNT0_SHIFT 18
    +# define SCALER_DISPSTAT1_FRCNT1_MASK VC4_MASK(17, 12)
    +# define SCALER_DISPSTAT1_FRCNT1_SHIFT 12
    +
    #define SCALER_DISPSTATX(x) (SCALER_DISPSTAT0 + \
    (x) * (SCALER_DISPSTAT1 - \
    SCALER_DISPSTAT0))
    +
    #define SCALER_DISPBASE1 0x0000005c
    #define SCALER_DISPBASEX(x) (SCALER_DISPBASE0 + \
    (x) * (SCALER_DISPBASE1 - \
    @@ -415,7 +419,11 @@
    (x) * (SCALER_DISPCTRL1 - \
    SCALER_DISPCTRL0))
    #define SCALER_DISPBKGND2 0x00000064
    +
    #define SCALER_DISPSTAT2 0x00000068
    +# define SCALER_DISPSTAT2_FRCNT2_MASK VC4_MASK(17, 12)
    +# define SCALER_DISPSTAT2_FRCNT2_SHIFT 12
    +
    #define SCALER_DISPBASE2 0x0000006c
    #define SCALER_DISPALPHA2 0x00000070
    #define SCALER_GAMADDR 0x00000078
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-08 00:38    [W:2.205 / U:0.256 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site