Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp702565pxb; Fri, 15 Apr 2022 09:14:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyG1yiyBboD8pvCtzprt78ICywOamSTuSyBoThWG+74Lg5trZZx8A7foh/u7XMRdJ2E8aVS X-Received: by 2002:a17:90b:1e08:b0:1c7:585c:9034 with SMTP id pg8-20020a17090b1e0800b001c7585c9034mr4888894pjb.184.1650039292502; Fri, 15 Apr 2022 09:14:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650039292; cv=none; d=google.com; s=arc-20160816; b=v8MktJoWm7uKtQBQuP2PbxDkEGptV6e/tslLmywiwWCoPdDeSb6+LgQSyMdYtHJsju oBvSlQ8//wxK09sM9X+hnHrAOGS/kynQhhaDEOAU3rvwujOE6VDXlKVM8606uXIOBL/r 5BznjnFRVGj94wDgIAR3ZD0h3Wk3c3tJ1JMaUjdancZeBx+KYnjkwvNexidj6oSlP8L+ qx1h0fzNJZH2RQPc86Sa4rrMtKcseIqXj+GNem2Ao37euaMriRDe/Au0xLaqbq6VEYYN H5IJtEfxglIVQ/jFi6+hvUo/3+q3uJ9q2QU1wbWDpZauGsbOFd0PN0WMO24NCZgQVpBD 0Wgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=ngrt2MEr4z8GI4+zoah18/U0+SvzTpZZW+sSchHQgqw=; b=K6OAzSJWn3XqfJVd+XAje4eNP6y+li4UPi42RRKj/2JL9egQKt3bu3e4IsVc/KX26T wmCBa87exZADA3CMeeUyZk5q2qQPk065TXdxc7YeotQerzmjEFULOZs62SlSI7bhWqFB kSMutmM31oUnRrfx6k5fQQ8D9QGRox2FoZRaihM5nD7alcQJPhfWdMQgQMD2rkRTAVB7 q4la2t6WLYMYm4RnPxEvPaghWRUKi/fwvCfQFEWl73N9E7sYdfbOkUjSJuhiH9nmnDgK zzjpvvK/I8MxWocYVSIchIrNgqUcBWWaaoTkwyk0f3Ddmtu58sVVTPaYtC/96Z73P2s2 CVJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (expired) header.i=@sholland.org header.s=fm2; dkim=neutral (expired) header.i=@messagingengine.com header.s=fm1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n17-20020a6563d1000000b0039cbfcd3b1dsi1900295pgv.830.2022.04.15.09.14.37; Fri, 15 Apr 2022 09:14:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=neutral (expired) header.i=@sholland.org header.s=fm2; dkim=neutral (expired) header.i=@messagingengine.com header.s=fm1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237209AbiDMWWT (ORCPT + 99 others); Wed, 13 Apr 2022 18:22:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236367AbiDMWVz (ORCPT ); Wed, 13 Apr 2022 18:21:55 -0400 Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com [66.111.4.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02478201A8; Wed, 13 Apr 2022 15:19:32 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 5BB705C0323; Wed, 13 Apr 2022 18:19:32 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Wed, 13 Apr 2022 18:19:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sholland.org; h= cc:cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; t=1649888372; x=1649974772; bh=ng rt2MEr4z8GI4+zoah18/U0+SvzTpZZW+sSchHQgqw=; b=wawPN8qUvHr63z4xdi brOCkbGn2zalS6uDCaKgPSyte/dRJ5M30t8pB3soZGxm3Q1h6DflqbxxneDl+cCb MdM0gCdoqQpbpLJONcBljJpxDxh5LpR/B571L928u/BxOpXHenoWiiUkUhb3/A5m pXxoBndI3JhFE06UuaXws8gre97ife0VMXwvBdDI9QQwMg4UdqfD+4RGHUz5a0pl jAzukMjW8P5O15FjbGKZvDtkx5B2eUBulw9wyV17Jh9bM6e7mcQd20oBTTejBTot wlRCuyq80MbfCloxCIqQ97aRYL+a2fv8yVV5w0/dMT9bUIinnPwNEOeoKZenKTuu JQ3A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t= 1649888372; x=1649974772; bh=ngrt2MEr4z8GI4+zoah18/U0+SvzTpZZW+s SchHQgqw=; b=BingKrHdYkk6l9I/ljL5wiPGYo5TN6UWOXSYOg66m6kAnXSSYg/ 8NhLba5YrkIbhocG+K7iwKgAuxJMdJU52X0sS74aokKeccgNCwRN+m26K4kVWk3i FRFtuNPClNOZCjC8J28EYWzwmKaj3PMD+1fruHcMDXFjKVvatAMG8yTDUfhmEP2E fYxx9sfimHFAlFLkUaM3/ZT5y1l7XzzQ4BNy9qU4lZp7+eimCTV4gJdwQJBRvw9I nkEPWhJhHoM5xwFUjc1NUvopJVPs5EooLKJgKj17kY4pyem3XuIng9VdN536NQGL ERxfB18fO9Cj9NxH6F/oc6k99JyuIroxA1w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrudelvddguddtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefurghmuhgv lhcujfholhhlrghnugcuoehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhgqeenucggtf frrghtthgvrhhnpeduhfejfedvhffgfeehtefghfeiiefgfeehgfdvvdevfeegjeehjedv gfejheeuieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhroh hmpehsrghmuhgvlhesshhhohhllhgrnhgurdhorhhg X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 13 Apr 2022 18:19:31 -0400 (EDT) From: Samuel Holland To: =?UTF-8?q?Heiko=20St=C3=BCbner?= , Sandy Huang , dri-devel@lists.freedesktop.org Cc: linux-rockchip@lists.infradead.org, Alistair Francis , =?UTF-8?q?Ond=C5=99ej=20Jirman?= , Andreas Kemnade , Daniel Vetter , David Airlie , Geert Uytterhoeven , Samuel Holland , Krzysztof Kozlowski , Liang Chen , Maarten Lankhorst , Maxime Ripard , Michael Riesch , Nicolas Frattaroli , Peter Geis , Rob Herring , Sam Ravnborg , Thierry Reding , Thomas Zimmermann , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 05/16] drm/rockchip: ebc: Add CRTC mode setting Date: Wed, 13 Apr 2022 17:19:05 -0500 Message-Id: <20220413221916.50995-6-samuel@sholland.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220413221916.50995-1-samuel@sholland.org> References: <20220413221916.50995-1-samuel@sholland.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org EPDs require some additional timing data beyond what is normally provided by drm_display_mode, as that struct is designed for CRTs/LCDs. For example, EPDs care about the width and position of the gate driver (vertical) clock pulse within a line. EPDs also update some number of pixels in parallel, based on the interface width, which of course varies by panel. Only two data bits are used for each pixel, to choose between driving it positive, negative, or neither direction. Color depth is thus not limited by interface width, but by time (the number of phases in the active waveform). This additional timing information is packed inside drm_display_mode as hskew and DRM_MODE_FLAG_CLKDIV2. This allows getting the complete mode from a DRM bridge. Signed-off-by: Samuel Holland --- drivers/gpu/drm/rockchip/rockchip_ebc.c | 102 ++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_ebc.c b/drivers/gpu/drm/rockchip/rockchip_ebc.c index f75fd23adda2..5f9502313657 100644 --- a/drivers/gpu/drm/rockchip/rockchip_ebc.c +++ b/drivers/gpu/drm/rockchip/rockchip_ebc.c @@ -135,6 +135,7 @@ struct rockchip_ebc { struct drm_plane plane; struct regmap *regmap; struct regulator_bulk_data supplies[EBC_NUM_SUPPLIES]; + u32 dsp_start; }; DEFINE_DRM_GEM_FOPS(rockchip_ebc_fops); @@ -178,11 +179,112 @@ static inline struct rockchip_ebc *crtc_to_ebc(struct drm_crtc *crtc) static void rockchip_ebc_crtc_mode_set_nofb(struct drm_crtc *crtc) { + struct rockchip_ebc *ebc = crtc_to_ebc(crtc); + struct drm_display_mode mode = crtc->state->adjusted_mode; + struct drm_display_mode sdck; + u16 hsync_width, vsync_width; + u16 hact_start, vact_start; + u16 pixels_per_sdck; + bool bus_16bit; + + /* + * Hardware needs horizontal timings in SDCK (source driver clock) + * cycles, not pixels. Bus width is either 8 bits (normal) or 16 bits + * (DRM_MODE_FLAG_CLKDIV2), and each pixel uses two data bits. + */ + bus_16bit = !!(mode.flags & DRM_MODE_FLAG_CLKDIV2); + pixels_per_sdck = bus_16bit ? 8 : 4; + sdck.hdisplay = mode.hdisplay / pixels_per_sdck; + sdck.hsync_start = mode.hsync_start / pixels_per_sdck; + sdck.hsync_end = mode.hsync_end / pixels_per_sdck; + sdck.htotal = mode.htotal / pixels_per_sdck; + sdck.hskew = mode.hskew / pixels_per_sdck; + + /* + * Linux timing order is display/fp/sync/bp. Hardware timing order is + * sync/bp/display/fp, aka sync/start/display/end. + */ + hact_start = sdck.htotal - sdck.hsync_start; + vact_start = mode.vtotal - mode.vsync_start; + + hsync_width = sdck.hsync_end - sdck.hsync_start; + vsync_width = mode.vsync_end - mode.vsync_start; + + clk_set_rate(ebc->dclk, mode.clock * 1000); + + ebc->dsp_start = EBC_DSP_START_DSP_SDCE_WIDTH(sdck.hdisplay) | + EBC_DSP_START_SW_BURST_CTRL; + regmap_write(ebc->regmap, EBC_EPD_CTRL, + EBC_EPD_CTRL_DSP_GD_END(sdck.htotal - sdck.hskew) | + EBC_EPD_CTRL_DSP_GD_ST(hsync_width + sdck.hskew) | + EBC_EPD_CTRL_DSP_SDDW_MODE * bus_16bit); + regmap_write(ebc->regmap, EBC_DSP_CTRL, + /* no swap */ + EBC_DSP_CTRL_DSP_SWAP_MODE(bus_16bit ? 2 : 3) | + EBC_DSP_CTRL_DSP_SDCLK_DIV(pixels_per_sdck - 1)); + regmap_write(ebc->regmap, EBC_DSP_HTIMING0, + EBC_DSP_HTIMING0_DSP_HTOTAL(sdck.htotal) | + /* sync end == sync width */ + EBC_DSP_HTIMING0_DSP_HS_END(hsync_width)); + regmap_write(ebc->regmap, EBC_DSP_HTIMING1, + EBC_DSP_HTIMING1_DSP_HACT_END(hact_start + sdck.hdisplay) | + /* minus 1 for fixed delay in timing sequence */ + EBC_DSP_HTIMING1_DSP_HACT_ST(hact_start - 1)); + regmap_write(ebc->regmap, EBC_DSP_VTIMING0, + EBC_DSP_VTIMING0_DSP_VTOTAL(mode.vtotal) | + /* sync end == sync width */ + EBC_DSP_VTIMING0_DSP_VS_END(vsync_width)); + regmap_write(ebc->regmap, EBC_DSP_VTIMING1, + EBC_DSP_VTIMING1_DSP_VACT_END(vact_start + mode.vdisplay) | + EBC_DSP_VTIMING1_DSP_VACT_ST(vact_start)); + regmap_write(ebc->regmap, EBC_DSP_ACT_INFO, + EBC_DSP_ACT_INFO_DSP_HEIGHT(mode.vdisplay) | + EBC_DSP_ACT_INFO_DSP_WIDTH(mode.hdisplay)); + regmap_write(ebc->regmap, EBC_WIN_CTRL, + /* FIFO depth - 16 */ + EBC_WIN_CTRL_WIN2_FIFO_THRESHOLD(496) | + EBC_WIN_CTRL_WIN_EN | + /* INCR16 */ + EBC_WIN_CTRL_AHB_BURST_REG(7) | + /* FIFO depth - 16 */ + EBC_WIN_CTRL_WIN_FIFO_THRESHOLD(240) | + EBC_WIN_CTRL_WIN_FMT_Y4); + + /* To keep things simple, always use a window size matching the CRTC. */ + regmap_write(ebc->regmap, EBC_WIN_VIR, + EBC_WIN_VIR_WIN_VIR_HEIGHT(mode.vdisplay) | + EBC_WIN_VIR_WIN_VIR_WIDTH(mode.hdisplay)); + regmap_write(ebc->regmap, EBC_WIN_ACT, + EBC_WIN_ACT_WIN_ACT_HEIGHT(mode.vdisplay) | + EBC_WIN_ACT_WIN_ACT_WIDTH(mode.hdisplay)); + regmap_write(ebc->regmap, EBC_WIN_DSP, + EBC_WIN_DSP_WIN_DSP_HEIGHT(mode.vdisplay) | + EBC_WIN_DSP_WIN_DSP_WIDTH(mode.hdisplay)); + regmap_write(ebc->regmap, EBC_WIN_DSP_ST, + EBC_WIN_DSP_ST_WIN_DSP_YST(vact_start) | + EBC_WIN_DSP_ST_WIN_DSP_XST(hact_start)); } static int rockchip_ebc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct rockchip_ebc *ebc = crtc_to_ebc(crtc); + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (!crtc_state->mode_changed) + return 0; + + if (crtc_state->enable) { + struct drm_display_mode *mode = &crtc_state->adjusted_mode; + long rate = mode->clock * 1000; + + rate = clk_round_rate(ebc->dclk, rate); + if (rate < 0) + return rate; + mode->clock = rate / 1000; + } + return 0; } -- 2.35.1