From patchwork Thu Feb 28 20:03:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Jernej_=C5=A0krabec?= X-Patchwork-Id: 10833653 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7B86B1390 for ; Thu, 28 Feb 2019 20:09:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6BB402E27A for ; Thu, 28 Feb 2019 20:09:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5D8EC2E296; Thu, 28 Feb 2019 20:09:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2BD9F2E27A for ; Thu, 28 Feb 2019 20:09:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387577AbfB1UJB (ORCPT ); Thu, 28 Feb 2019 15:09:01 -0500 Received: from mailoutvs51.siol.net ([185.57.226.242]:40928 "EHLO mail.siol.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726087AbfB1UJB (ORCPT ); Thu, 28 Feb 2019 15:09:01 -0500 X-Greylist: delayed 319 seconds by postgrey-1.27 at vger.kernel.org; Thu, 28 Feb 2019 15:08:59 EST Received: from localhost (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTP id CD12B522467; Thu, 28 Feb 2019 21:03:45 +0100 (CET) X-Virus-Scanned: amavisd-new at psrvmta11.zcs-production.pri Received: from mail.siol.net ([127.0.0.1]) by localhost (psrvmta11.zcs-production.pri [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id zvu3CY22wvHV; Thu, 28 Feb 2019 21:03:45 +0100 (CET) Received: from mail.siol.net (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTPS id 53362521852; Thu, 28 Feb 2019 21:03:45 +0100 (CET) Received: from localhost.localdomain (cpe-86-58-52-202.static.triera.net [86.58.52.202]) (Authenticated sender: 031275009) by mail.siol.net (Postfix) with ESMTPSA id 00B6552246B; Thu, 28 Feb 2019 21:03:42 +0100 (CET) From: Jernej Skrabec To: maxime.ripard@bootlin.com, wens@csie.org Cc: mturquette@baylibre.com, sboyd@kernel.org, airlied@linux.ie, daniel@ffwll.ch, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-sunxi@googlegroups.com Subject: [PATCH 3/3] drm/sun4i: Improve VI scaling for DE2/DE3 Date: Thu, 28 Feb 2019 21:03:29 +0100 Message-Id: <20190228200329.11128-4-jernej.skrabec@siol.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190228200329.11128-1-jernej.skrabec@siol.net> References: <20190228200329.11128-1-jernej.skrabec@siol.net> MIME-Version: 1.0 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP VI planes support coarse scaling which helps to overcome VI scaler limitations. While exact working of coarse scaling isn't known, it seems that it just skips programmed amount of rows and columns. This is especially useful for downscaling very big planes (4K down to 1080p). Horizontal coarse scaling is currently used to fit one line to VI scaler buffer. Vertical coarse scaling is used to assure that VI scaler is actually capable of processing framebuffer in one frame time. Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 54 ++++++++++++++++++++++++-- drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 11 ++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index 8a0616238467..bb8e026d6405 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c @@ -80,6 +80,8 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, u32 bld_base, ch_base; u32 outsize, insize; u32 hphase, vphase; + u32 hn = 0, hm = 0; + u32 vn = 0, vm = 0; bool subsampled; DRM_DEBUG_DRIVER("Updating VI channel %d overlay %d\n", @@ -137,12 +139,41 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, subsampled = format->hsub > 1 || format->vsub > 1; if (insize != outsize || subsampled || hphase || vphase) { - u32 hscale, vscale; + unsigned int scanline, required; + struct drm_display_mode *mode; + u32 hscale, vscale, fps; + u64 ability; DRM_DEBUG_DRIVER("HW scaling is enabled\n"); - hscale = state->src_w / state->crtc_w; - vscale = state->src_h / state->crtc_h; + mode = &plane->state->crtc->state->mode; + fps = (mode->clock * 1000) / (mode->vtotal * mode->htotal); + ability = clk_get_rate(mixer->mod_clk); + /* BSP algorithm assumes 80% efficiency of VI scaler unit */ + ability *= 80; + do_div(ability, mode->vdisplay * fps * max(src_w, dst_w)); + + required = src_h * 100 / dst_h; + + if (ability < required) { + DRM_DEBUG_DRIVER("Using vertical coarse scaling\n"); + vm = src_h; + vn = (u32)ability * dst_h / 100; + src_h = vn; + } + + /* it seems that every RGB scaler has buffer for 2048 pixels */ + scanline = subsampled ? mixer->cfg->scanline_yuv : 2048; + + if (src_w > scanline) { + DRM_DEBUG_DRIVER("Using horizontal coarse scaling\n"); + hm = src_w; + hn = scanline; + src_w = hn; + } + + hscale = (src_w << 16) / dst_w; + vscale = (src_h << 16) / dst_h; sun8i_vi_scaler_setup(mixer, channel, src_w, src_h, dst_w, dst_h, hscale, vscale, hphase, vphase, @@ -153,6 +184,23 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, sun8i_vi_scaler_enable(mixer, channel, false); } + regmap_write(mixer->engine.regs, + SUN8I_MIXER_CHAN_VI_HDS_Y(ch_base), + SUN8I_MIXER_CHAN_VI_DS_N(hn) | + SUN8I_MIXER_CHAN_VI_DS_M(hm)); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_CHAN_VI_HDS_UV(ch_base), + SUN8I_MIXER_CHAN_VI_DS_N(hn) | + SUN8I_MIXER_CHAN_VI_DS_M(hm)); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_CHAN_VI_VDS_Y(ch_base), + SUN8I_MIXER_CHAN_VI_DS_N(vn) | + SUN8I_MIXER_CHAN_VI_DS_M(vm)); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_CHAN_VI_VDS_UV(ch_base), + SUN8I_MIXER_CHAN_VI_DS_N(vn) | + SUN8I_MIXER_CHAN_VI_DS_M(vm)); + /* Set base coordinates */ DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n", state->dst.x1, state->dst.y1); diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h index 8a5e6d01c85d..a223a4839f45 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h @@ -24,6 +24,14 @@ ((base) + 0x30 * (layer) + 0x18 + 4 * (plane)) #define SUN8I_MIXER_CHAN_VI_OVL_SIZE(base) \ ((base) + 0xe8) +#define SUN8I_MIXER_CHAN_VI_HDS_Y(base) \ + ((base) + 0xf0) +#define SUN8I_MIXER_CHAN_VI_HDS_UV(base) \ + ((base) + 0xf4) +#define SUN8I_MIXER_CHAN_VI_VDS_Y(base) \ + ((base) + 0xf8) +#define SUN8I_MIXER_CHAN_VI_VDS_UV(base) \ + ((base) + 0xfc) #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN BIT(0) /* RGB mode should be set for RGB formats and cleared for YCbCr */ @@ -33,6 +41,9 @@ #define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK GENMASK(31, 24) #define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x) ((x) << 24) +#define SUN8I_MIXER_CHAN_VI_DS_N(x) ((x) << 16) +#define SUN8I_MIXER_CHAN_VI_DS_M(x) ((x) << 0) + struct sun8i_mixer; struct sun8i_vi_layer {