-
Notifications
You must be signed in to change notification settings - Fork 3
/
0001-Revert-drm-vblank-remove-drm_timestamp_monotonic-par.patch
133 lines (120 loc) · 5.26 KB
/
0001-Revert-drm-vblank-remove-drm_timestamp_monotonic-par.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
From 4c4eae91a1ce80097d0e860f518849edcb7a5a11 Mon Sep 17 00:00:00 2001
From: Satyeshwar Singh <[email protected]>
Date: Wed, 27 Oct 2021 15:17:42 -0700
Subject: [PATCH 1/1] Revert "drm: vblank: remove drm_timestamp_monotonic
parameter"
This reverts commit 25e1a79874eb3821d93310c908cc0a81b47af060.
---
drivers/gpu/drm/drm_internal.h | 1 +
drivers/gpu/drm/drm_ioctl.c | 2 +-
drivers/gpu/drm/drm_vblank.c | 33 ++++++++++++++++++++++++---------
3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index d7e023bbb0d5..95ac6349cdf1 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -91,6 +91,7 @@ static inline bool drm_vblank_passed(u64 seq, u64 ref)
return (seq - ref) <= (1 << 23);
}
+extern unsigned int drm_timestamp_monotonic;
void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
void drm_vblank_put(struct drm_device *dev, unsigned int pipe);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 5c98bf817ea5..4d465e3e6982 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -242,7 +242,7 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
/* Only some caps make sense with UMS/render-only drivers. */
switch (req->capability) {
case DRM_CAP_TIMESTAMP_MONOTONIC:
- req->value = 1;
+ req->value = drm_timestamp_monotonic;
return 0;
case DRM_CAP_PRIME:
req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 877e2067534f..e751735d1ad9 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -159,12 +159,20 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
+/*
+ * Default to use monotonic timestamps for wait-for-vblank and page-flip
+ * complete events.
+ */
+unsigned int drm_timestamp_monotonic = 1;
+
static int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
+module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)");
MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
+MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
static void store_vblank(struct drm_device *dev, unsigned int pipe,
u32 vblank_count_inc,
@@ -779,6 +787,9 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
delta_ns = div_s64(1000000LL * (vpos * mode->crtc_htotal + hpos),
mode->crtc_clock);
+ if (!drm_timestamp_monotonic)
+ etime = ktime_mono_to_real(etime);
+
/* Subtract time delta from raw timestamp to get final
* vblank_time timestamp for end of vblank.
*/
@@ -843,6 +854,11 @@ bool drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc,
}
EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp);
+static ktime_t get_drm_timestamp(void)
+{
+ return drm_timestamp_monotonic ? ktime_get() : ktime_get_real();
+}
+
/**
* drm_crtc_get_last_vbltimestamp - retrieve raw timestamp for the most
* recent vblank interval
@@ -882,7 +898,7 @@ drm_crtc_get_last_vbltimestamp(struct drm_crtc *crtc, ktime_t *tvblank,
* Return current monotonic/gettimeofday timestamp as best estimate.
*/
if (!ret)
- *tvblank = ktime_get();
+ *tvblank = get_drm_timestamp();
return ret;
}
@@ -1048,11 +1064,9 @@ static void send_vblank_event(struct drm_device *dev,
}
trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq);
/*
- * Use the same timestamp for any associated fence signal to avoid
- * mismatch in timestamps for vsync & fence events triggered by the
- * same HW event. Frameworks like SurfaceFlinger in Android expects the
- * retire-fence timestamp to match exactly with HW vsync as it uses it
- * for its software vsync modeling.
+ * e->event is a user space structure, with hardcoded unsigned
+ * 32-bit seconds/microseconds. This will overflow in 2106 for
+ * drm_timestamp_monotonic==0, but not with drm_timestamp_monotonic==1
*/
drm_send_event_timestamp_locked(dev, &e->base, now);
}
@@ -1133,7 +1147,7 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
} else {
seq = 0;
- now = ktime_get();
+ now = get_drm_timestamp();
}
e->pipe = pipe;
send_vblank_event(dev, e, seq, now);
@@ -1769,8 +1783,9 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
/*
* drm_wait_vblank_reply is a UAPI structure that uses 'long'
- * to store the seconds. This is safe as we always use monotonic
- * timestamps since linux-4.15.
+ * to store the seconds. This will overflow in y2038 on 32-bit
+ * architectures with drm_timestamp_monotonic==0, but not with
+ * drm_timestamp_monotonic==1 (the default).
*/
reply->sequence = drm_vblank_count_and_time(dev, pipe, &now);
ts = ktime_to_timespec64(now);
--
2.44.0