aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/arm/hdlcd_crtc.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2019-05-17 12:37:21 -0400
committerLiviu Dudau <Liviu.Dudau@arm.com>2019-06-04 10:12:44 -0400
commitb96151edced4edb6a18aa89a5fa02c7066efff45 (patch)
tree6be6878505c7fa48f980c91160df4a05fbdc46f2 /drivers/gpu/drm/arm/hdlcd_crtc.c
parent6a88e0c14813d00f8520d0e16cd4136c6cf8b4d4 (diff)
drm/arm/hdlcd: Actually validate CRTC modes
Rather than allowing any old mode through, then subsequently refusing unmatchable clock rates in atomic_check when it's too late to back out and pick a different mode, let's do that validation up-front where it will cause unsupported modes to be correctly pruned in the first place. This also eliminates an issue whereby a perceived clock rate of 0 would cause atomic disable to fail and prevent the module from being unloaded. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
Diffstat (limited to 'drivers/gpu/drm/arm/hdlcd_crtc.c')
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 0b2b62f8fa3c..ecac6fe0b213 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -186,20 +186,19 @@ static void hdlcd_crtc_atomic_disable(struct drm_crtc *crtc,
186 clk_disable_unprepare(hdlcd->clk); 186 clk_disable_unprepare(hdlcd->clk);
187} 187}
188 188
189static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, 189static enum drm_mode_status hdlcd_crtc_mode_valid(struct drm_crtc *crtc,
190 struct drm_crtc_state *state) 190 const struct drm_display_mode *mode)
191{ 191{
192 struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); 192 struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
193 struct drm_display_mode *mode = &state->adjusted_mode;
194 long rate, clk_rate = mode->clock * 1000; 193 long rate, clk_rate = mode->clock * 1000;
195 194
196 rate = clk_round_rate(hdlcd->clk, clk_rate); 195 rate = clk_round_rate(hdlcd->clk, clk_rate);
197 if (rate != clk_rate) { 196 if (rate != clk_rate) {
198 /* clock required by mode not supported by hardware */ 197 /* clock required by mode not supported by hardware */
199 return -EINVAL; 198 return MODE_NOCLOCK;
200 } 199 }
201 200
202 return 0; 201 return MODE_OK;
203} 202}
204 203
205static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, 204static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
@@ -220,7 +219,7 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
220} 219}
221 220
222static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { 221static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
223 .atomic_check = hdlcd_crtc_atomic_check, 222 .mode_valid = hdlcd_crtc_mode_valid,
224 .atomic_begin = hdlcd_crtc_atomic_begin, 223 .atomic_begin = hdlcd_crtc_atomic_begin,
225 .atomic_enable = hdlcd_crtc_atomic_enable, 224 .atomic_enable = hdlcd_crtc_atomic_enable,
226 .atomic_disable = hdlcd_crtc_atomic_disable, 225 .atomic_disable = hdlcd_crtc_atomic_disable,