bcm27xx: add support for linux v5.15
[openwrt/staging/ldir.git] / target / linux / bcm27xx / patches-5.15 / 950-0740-drm-vc4-hvs-Fix-frame-count-register-readout.patch
1 From 77579d5ba35bf6e13f0ed09097c475f178d3c270 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Thu, 17 Feb 2022 10:55:26 +0100
4 Subject: [PATCH] drm/vc4: hvs: Fix frame count register readout
5
6 In order to get the field currently being output, the driver has been
7 using the display FIFO frame count in the HVS, reading a 6-bit field at
8 the offset 12 in the DISPSTATx register.
9
10 While that field is indeed at that location for the FIFO 1 and 2, the
11 one for the FIFO0 is actually in the DISPSTAT1 register, at the offset
12 18.
13
14 Fixes: e538092cb15c ("drm/vc4: Enable precise vblank timestamping for interlaced modes.")
15 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
16 ---
17 drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
18 drivers/gpu/drm/vc4/vc4_drv.h | 1 +
19 drivers/gpu/drm/vc4/vc4_hvs.c | 23 +++++++++++++++++++++++
20 drivers/gpu/drm/vc4/vc4_regs.h | 12 ++++++++++--
21 4 files changed, 35 insertions(+), 3 deletions(-)
22
23 --- a/drivers/gpu/drm/vc4/vc4_crtc.c
24 +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
25 @@ -123,7 +123,7 @@ static bool vc4_crtc_get_scanout_positio
26 *vpos /= 2;
27
28 /* Use hpos to correct for field offset in interlaced mode. */
29 - if (VC4_GET_FIELD(val, SCALER_DISPSTATX_FRAME_COUNT) % 2)
30 + if (vc4_hvs_get_fifo_frame_count(dev, vc4_crtc_state->assigned_channel) % 2)
31 *hpos += mode->crtc_htotal / 2;
32 }
33
34 --- a/drivers/gpu/drm/vc4/vc4_drv.h
35 +++ b/drivers/gpu/drm/vc4/vc4_drv.h
36 @@ -967,6 +967,7 @@ void vc4_irq_reset(struct drm_device *de
37 extern struct platform_driver vc4_hvs_driver;
38 void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output);
39 int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output);
40 +u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo);
41 int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state);
42 void vc4_hvs_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state);
43 void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state);
44 --- a/drivers/gpu/drm/vc4/vc4_hvs.c
45 +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
46 @@ -388,6 +388,29 @@ static void vc5_hvs_update_gamma_lut(str
47 vc5_hvs_lut_load(crtc);
48 }
49
50 +u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo)
51 +{
52 + struct vc4_dev *vc4 = to_vc4_dev(dev);
53 + u8 field = 0;
54 +
55 + switch (fifo) {
56 + case 0:
57 + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT1),
58 + SCALER_DISPSTAT1_FRCNT0);
59 + break;
60 + case 1:
61 + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT1),
62 + SCALER_DISPSTAT1_FRCNT1);
63 + break;
64 + case 2:
65 + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT2),
66 + SCALER_DISPSTAT2_FRCNT2);
67 + break;
68 + }
69 +
70 + return field;
71 +}
72 +
73 int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output)
74 {
75 struct vc4_dev *vc4 = to_vc4_dev(dev);
76 --- a/drivers/gpu/drm/vc4/vc4_regs.h
77 +++ b/drivers/gpu/drm/vc4/vc4_regs.h
78 @@ -379,8 +379,6 @@
79 # define SCALER_DISPSTATX_MODE_EOF 3
80 # define SCALER_DISPSTATX_FULL BIT(29)
81 # define SCALER_DISPSTATX_EMPTY BIT(28)
82 -# define SCALER_DISPSTATX_FRAME_COUNT_MASK VC4_MASK(17, 12)
83 -# define SCALER_DISPSTATX_FRAME_COUNT_SHIFT 12
84 # define SCALER_DISPSTATX_LINE_MASK VC4_MASK(11, 0)
85 # define SCALER_DISPSTATX_LINE_SHIFT 0
86
87 @@ -403,9 +401,15 @@
88 (x) * (SCALER_DISPBKGND1 - \
89 SCALER_DISPBKGND0))
90 #define SCALER_DISPSTAT1 0x00000058
91 +# define SCALER_DISPSTAT1_FRCNT0_MASK VC4_MASK(23, 18)
92 +# define SCALER_DISPSTAT1_FRCNT0_SHIFT 18
93 +# define SCALER_DISPSTAT1_FRCNT1_MASK VC4_MASK(17, 12)
94 +# define SCALER_DISPSTAT1_FRCNT1_SHIFT 12
95 +
96 #define SCALER_DISPSTATX(x) (SCALER_DISPSTAT0 + \
97 (x) * (SCALER_DISPSTAT1 - \
98 SCALER_DISPSTAT0))
99 +
100 #define SCALER_DISPBASE1 0x0000005c
101 #define SCALER_DISPBASEX(x) (SCALER_DISPBASE0 + \
102 (x) * (SCALER_DISPBASE1 - \
103 @@ -415,7 +419,11 @@
104 (x) * (SCALER_DISPCTRL1 - \
105 SCALER_DISPCTRL0))
106 #define SCALER_DISPBKGND2 0x00000064
107 +
108 #define SCALER_DISPSTAT2 0x00000068
109 +# define SCALER_DISPSTAT2_FRCNT2_MASK VC4_MASK(17, 12)
110 +# define SCALER_DISPSTAT2_FRCNT2_SHIFT 12
111 +
112 #define SCALER_DISPBASE2 0x0000006c
113 #define SCALER_DISPALPHA2 0x00000070
114 #define SCALER_GAMADDR 0x00000078