From patchwork Mon Nov 27 20:57:44 2017 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: 10078101 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EA37760353 for ; Mon, 27 Nov 2017 21:02:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC5B828D5D for ; Mon, 27 Nov 2017 21:02:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D10F529062; Mon, 27 Nov 2017 21:02: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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 54B3528D5D for ; Mon, 27 Nov 2017 21:02:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=GzFkNYAtl1WfKz1DPTXB95A+kJ3dZ0+wMfEwMbKlSDQ=; b=tOil4VcbH0Aad5o8iQlUDM+dRD 4JRFGg/jH9TBJkiuXXDhEoUA8FSlntHWMPJDJh298i7uCh2GjDUG5uuOj3S97LM8SB6bTI+6KqPm3 U4ozFhP+OG7aqgjkbspTCFdy3U/n7Lq7SwHhVRaFyxBPyIUaj90uPCJBzrdDdjLVlNyYnsikx11QZ CpVsLDFRGYFC96+yfujARtk2WjEnm/pxAiLfOLosYMO/zIMIzWArSHbHH/FVm/y8IMdxjk/xANHVW +OvghnptODvghLA7jtmJLuLB2ZfxKSpYy4efijMSBMNaOAiENBlUnPLFySM/Qc3BWtBmyn5EQsDxA HwMaUt0A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eJQXQ-0005ZO-Gj; Mon, 27 Nov 2017 21:02:00 +0000 Received: from mailoutvs2.siol.net ([213.250.19.135] helo=mail.siol.net) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eJQUI-0001CB-Pl for linux-arm-kernel@lists.infradead.org; Mon, 27 Nov 2017 20:59:02 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTP id AA691521753; Mon, 27 Nov 2017 21:58:24 +0100 (CET) X-Virus-Scanned: amavisd-new at psrvmta09.zcs-production.pri Received: from mail.siol.net ([127.0.0.1]) by localhost (psrvmta09.zcs-production.pri [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id Prml2nnDyNhI; Mon, 27 Nov 2017 21:58:23 +0100 (CET) Received: from mail.siol.net (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTPS id C836E52174D; Mon, 27 Nov 2017 21:58:23 +0100 (CET) Received: from localhost.localdomain (cpe-86-58-68-135.ftth.triera.net [86.58.68.135]) (Authenticated sender: 031275009) by mail.siol.net (Postfix) with ESMTPSA id 7B449521751; Mon, 27 Nov 2017 21:58:21 +0100 (CET) From: Jernej Skrabec To: maxime.ripard@free-electrons.com Subject: [PATCH 11/17] drm/sun4i: Wire in DE2 scaler support Date: Mon, 27 Nov 2017 21:57:44 +0100 Message-Id: <20171127205750.19277-12-jernej.skrabec@siol.net> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171127205750.19277-1-jernej.skrabec@siol.net> References: <20171127205750.19277-1-jernej.skrabec@siol.net> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171127_125847_660507_F6A269E6 X-CRM114-Status: GOOD ( 13.88 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: airlied@linux.ie, linux-sunxi@googlegroups.com, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, wens@csie.org, linux-arm-kernel@lists.infradead.org, icenowy@aosc.io MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Calculate scaling parameters and call appropriate scaler set up function. Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/sun4i/sun8i_layer.c | 12 +++- drivers/gpu/drm/sun4i/sun8i_mixer.c | 115 +++++++++++++++++++++++++----------- drivers/gpu/drm/sun4i/sun8i_mixer.h | 4 -- 3 files changed, 90 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun8i_layer.c b/drivers/gpu/drm/sun4i/sun8i_layer.c index e1b6ad82145e..6860271e5415 100644 --- a/drivers/gpu/drm/sun4i/sun8i_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_layer.c @@ -25,8 +25,11 @@ static int sun8i_mixer_layer_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { + struct sun8i_layer *layer = plane_to_sun8i_layer(plane); struct drm_crtc *crtc = state->crtc; struct drm_crtc_state *crtc_state; + int min_scale, max_scale; + bool scaler_supported; struct drm_rect clip; if (!crtc) @@ -41,9 +44,14 @@ static int sun8i_mixer_layer_atomic_check(struct drm_plane *plane, clip.x2 = crtc_state->adjusted_mode.hdisplay; clip.y2 = crtc_state->adjusted_mode.vdisplay; + scaler_supported = !!(layer->mixer->cfg->scaler_mask & BIT(layer->id)); + + min_scale = scaler_supported ? 1 : DRM_PLANE_HELPER_NO_SCALING; + max_scale = scaler_supported ? (1UL << 20) - 1 : + DRM_PLANE_HELPER_NO_SCALING; + return drm_plane_helper_check_state(state, &clip, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, + min_scale, max_scale, true, true); } diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 291dd8806444..7c9c87a0535b 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -28,6 +28,7 @@ #include "sun8i_mixer.h" #include "sun8i_layer.h" #include "sunxi_engine.h" +#include "sun8i_scaler.h" struct de2_fmt_info { u32 drm_fmt; @@ -194,29 +195,34 @@ int sun8i_mixer_update_ui_layer_coord(struct sun8i_mixer *mixer, int layer, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; - u32 width, height, size; + u32 src_w, src_h, dst_w, dst_h; + u32 outsize, insize; + u32 hphase, vphase; - DRM_DEBUG_DRIVER("Updating layer %d\n", layer); + DRM_DEBUG_DRIVER("Updating UI layer %d\n", layer); - /* - * Same source and destination width and height are guaranteed - * by atomic check function. - */ - width = drm_rect_width(&state->dst); - height = drm_rect_height(&state->dst); - size = SUN8I_MIXER_SIZE(width, height); + src_w = drm_rect_width(&state->src) >> 16; + src_h = drm_rect_height(&state->src) >> 16; + dst_w = drm_rect_width(&state->dst); + dst_h = drm_rect_height(&state->dst); + + hphase = state->src.x1 & 0xffff; + vphase = state->src.y1 & 0xffff; + + insize = SUN8I_MIXER_SIZE(src_w, src_h); + outsize = SUN8I_MIXER_SIZE(dst_w, dst_h); if (plane->type == DRM_PLANE_TYPE_PRIMARY) { bool interlaced = false; u32 val; DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", - width, height); + dst_w, dst_h); regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, - size); + outsize); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE, - size); + outsize); if (state->crtc) interlaced = state->crtc->state->adjusted_mode.flags @@ -237,23 +243,40 @@ int sun8i_mixer_update_ui_layer_coord(struct sun8i_mixer *mixer, } /* Set height and width */ - DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", width, height); + DRM_DEBUG_DRIVER("Layer source offset X: %d Y: %d\n", + state->src.x1 >> 16, state->src.y1 >> 16); + DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_LAYER_SIZE(layer, 0), - size); + SUN8I_MIXER_CHAN_UI_LAYER_SIZE(layer, 0), insize); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_UI_OVL_SIZE(layer), - size); + SUN8I_MIXER_CHAN_UI_OVL_SIZE(layer), insize); + + if (insize != outsize || hphase || vphase) { + u32 hscale, vscale; + + DRM_DEBUG_DRIVER("HW scaling is enabled\n"); + + hscale = state->src_w / state->crtc_w; + vscale = state->src_h / state->crtc_h; + + sun8i_scaler_gsu_setup(mixer, layer, src_w, src_h, dst_w, dst_h, + hscale, vscale, hphase, vphase); + sun8i_scaler_gsu_enable(mixer, layer, true); + } else { + DRM_DEBUG_DRIVER("HW scaling is not needed\n"); + sun8i_scaler_gsu_enable(mixer, layer, false); + } /* Set base coordinates */ - DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n", + DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n", state->dst.x1, state->dst.y1); + DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_COORD(layer), SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_INSIZE(layer), - size); + outsize); return 0; } @@ -262,36 +285,58 @@ int sun8i_mixer_update_vi_layer_coord(struct sun8i_mixer *mixer, int layer, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; - u32 width, height, size; + u32 src_w, src_h, dst_w, dst_h; + u32 outsize, insize; + u32 hphase, vphase; - DRM_DEBUG_DRIVER("Updating layer %d\n", layer); + DRM_DEBUG_DRIVER("Updating VI layer %d\n", layer); - /* - * Same source and destination width and height are guaranteed - * by atomic check function. - */ - width = drm_rect_width(&state->dst); - height = drm_rect_height(&state->dst); - size = SUN8I_MIXER_SIZE(width, height); + src_w = drm_rect_width(&state->src) >> 16; + src_h = drm_rect_height(&state->src) >> 16; + dst_w = drm_rect_width(&state->dst); + dst_h = drm_rect_height(&state->dst); + + hphase = state->src.x1 & 0xffff; + vphase = state->src.y1 & 0xffff; + + insize = SUN8I_MIXER_SIZE(src_w, src_h); + outsize = SUN8I_MIXER_SIZE(dst_w, dst_h); /* Set height and width */ - DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", width, height); + DRM_DEBUG_DRIVER("Layer source offset X: %d Y: %d\n", + state->src.x1 >> 16, state->src.y1 >> 16); + DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_VI_LAYER_SIZE(layer, 0), - size); + SUN8I_MIXER_CHAN_VI_LAYER_SIZE(layer, 0), insize); regmap_write(mixer->engine.regs, - SUN8I_MIXER_CHAN_VI_OVL_SIZE(layer), - size); + SUN8I_MIXER_CHAN_VI_OVL_SIZE(layer), insize); + + if (insize != outsize || hphase || vphase) { + u32 hscale, vscale; + + DRM_DEBUG_DRIVER("HW scaling is enabled\n"); + + hscale = state->src_w / state->crtc_w; + vscale = state->src_h / state->crtc_h; + + sun8i_scaler_vsu_setup(mixer, layer, src_w, src_h, dst_w, dst_h, + hscale, vscale, hphase, vphase); + sun8i_scaler_vsu_enable(mixer, layer, true); + } else { + DRM_DEBUG_DRIVER("HW scaling is not needed\n"); + sun8i_scaler_vsu_enable(mixer, layer, false); + } /* Set base coordinates */ - DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n", + DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n", state->dst.x1, state->dst.y1); + DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_COORD(layer), SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_INSIZE(layer), - size); + outsize); return 0; } diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h index ad5aef5846ae..355a45e6cfb4 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h @@ -124,10 +124,6 @@ * These sub-engines are still unknown now, the EN registers are here only to * be used to disable these sub-engines. */ -#define SUN8I_MIXER_VSU_EN 0x20000 -#define SUN8I_MIXER_GSU1_EN 0x30000 -#define SUN8I_MIXER_GSU2_EN 0x40000 -#define SUN8I_MIXER_GSU3_EN 0x50000 #define SUN8I_MIXER_FCE_EN 0xa0000 #define SUN8I_MIXER_BWS_EN 0xa2000 #define SUN8I_MIXER_LTI_EN 0xa4000