aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/arm/malidp_crtc.c
diff options
context:
space:
mode:
authorMihail Atanassov <mihail.atanassov@arm.com>2017-02-13 15:09:01 +0000
committerLiviu Dudau <Liviu.Dudau@arm.com>2017-04-24 13:28:09 +0100
commitc2e7f82d336a451ebb904b8bf9a5a558cf16c39b (patch)
tree7a589b812cf505c31464b2e6628b1eb846600aad /drivers/gpu/drm/arm/malidp_crtc.c
parentdrm: mali-dp: Enable image enhancement when scaling (diff)
downloadlinux-dev-c2e7f82d336a451ebb904b8bf9a5a558cf16c39b.tar.xz
linux-dev-c2e7f82d336a451ebb904b8bf9a5a558cf16c39b.zip
drm: mali-dp: Check the mclk rate and allow up/down scaling
When downscaling, mclk needs to be sufficiently higher than pxlclk in order to be able to fetch the higher-resolution data and produce output pixels. When not scaling, or when upscaling, mclk can be equal to pxlclk. Since the driver doesn't control mclk, just ensure that the requirement is satisfied with the current clock rate. Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Diffstat (limited to 'drivers/gpu/drm/arm/malidp_crtc.c')
-rw-r--r--drivers/gpu/drm/arm/malidp_crtc.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c
index b0f0365efd23..19f1f3b34691 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -36,13 +36,6 @@ static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc,
long rate, req_rate = mode->crtc_clock * 1000;
if (req_rate) {
- rate = clk_round_rate(hwdev->mclk, req_rate);
- if (rate < req_rate) {
- DRM_DEBUG_DRIVER("mclk clock unable to reach %d kHz\n",
- mode->crtc_clock);
- return false;
- }
-
rate = clk_round_rate(hwdev->pxlclk, req_rate);
if (rate != req_rate) {
DRM_DEBUG_DRIVER("pxlclk doesn't support %ld Hz\n",
@@ -250,17 +243,21 @@ static int malidp_crtc_atomic_check_ctm(struct drm_crtc *crtc,
static int malidp_crtc_atomic_check_scaling(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
+ struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
+ struct malidp_hw_device *hwdev = malidp->dev;
struct malidp_crtc_state *cs = to_malidp_crtc_state(state);
struct malidp_se_config *s = &cs->scaler_config;
struct drm_plane *plane;
+ struct videomode vm;
const struct drm_plane_state *pstate;
u32 h_upscale_factor = 0; /* U16.16 */
u32 v_upscale_factor = 0; /* U16.16 */
u8 scaling = cs->scaled_planes_mask;
+ int ret;
if (!scaling) {
s->scale_enable = false;
- return 0;
+ goto mclk_calc;
}
/* The scaling engine can only handle one plane at a time. */
@@ -284,10 +281,6 @@ static int malidp_crtc_atomic_check_scaling(struct drm_crtc *crtc,
h_upscale_factor = (u32)(crtc_w / pstate->src_w);
v_upscale_factor = (u32)(crtc_h / pstate->src_h);
- /* Downscaling won't work when mclk == pxlclk. */
- if (!(h_upscale_factor >> 16) || !(v_upscale_factor >> 16))
- return -EINVAL;
-
s->enhancer_enable = ((h_upscale_factor >> 16) >= 2 ||
(v_upscale_factor >> 16) >= 2);
@@ -323,6 +316,12 @@ static int malidp_crtc_atomic_check_scaling(struct drm_crtc *crtc,
s->scale_enable = true;
s->hcoeff = malidp_se_select_coeffs(h_upscale_factor);
s->vcoeff = malidp_se_select_coeffs(v_upscale_factor);
+
+mclk_calc:
+ drm_display_mode_to_videomode(&state->adjusted_mode, &vm);
+ ret = hwdev->se_calc_mclk(hwdev, s, &vm);
+ if (ret < 0)
+ return -EINVAL;
return 0;
}