linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Samuel Holland <samuel@sholland.org>
To: "Heiko Stübner" <heiko@sntech.de>,
	"Sandy Huang" <hjc@rock-chips.com>,
	dri-devel@lists.freedesktop.org
Cc: linux-rockchip@lists.infradead.org,
	"Alistair Francis" <alistair@alistair23.me>,
	"Ondřej Jirman" <x@xff.cz>,
	"Andreas Kemnade" <andreas@kemnade.info>,
	"Daniel Vetter" <daniel@ffwll.ch>,
	"David Airlie" <airlied@linux.ie>,
	"Geert Uytterhoeven" <geert@linux-m68k.org>,
	"Samuel Holland" <samuel@sholland.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Liang Chen" <cl@rock-chips.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Michael Riesch" <michael.riesch@wolfvision.net>,
	"Nicolas Frattaroli" <frattaroli.nicolas@gmail.com>,
	"Peter Geis" <pgwipeout@gmail.com>,
	"Rob Herring" <robh+dt@kernel.org>,
	"Sam Ravnborg" <sam@ravnborg.org>,
	"Thierry Reding" <thierry.reding@gmail.com>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	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	[thread overview]
Message-ID: <20220413221916.50995-6-samuel@sholland.org> (raw)
In-Reply-To: <20220413221916.50995-1-samuel@sholland.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 <samuel@sholland.org>
---

 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


  parent reply	other threads:[~2022-04-13 22:20 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-13 22:19 [RFC PATCH 00/16] drm/rockchip: Rockchip EBC ("E-Book Controller") display driver Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 01/16] drm: Add a helper library for EPD drivers Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 02/16] dt-bindings: display: rockchip: Add EBC binding Samuel Holland
2022-04-14  8:15   ` Andreas Kemnade
2022-04-15  3:00     ` Samuel Holland
2022-04-15 11:45       ` Andreas Kemnade
2022-04-13 22:19 ` [RFC PATCH 03/16] drm/rockchip: Add EBC platform driver skeleton Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 04/16] drm/rockchip: ebc: Add DRM " Samuel Holland
2022-04-13 22:19 ` Samuel Holland [this message]
2022-04-13 22:19 ` [RFC PATCH 06/16] drm/rockchip: ebc: Add CRTC refresh thread Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 07/16] drm/rockchip: ebc: Add CRTC buffer management Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 08/16] drm/rockchip: ebc: Add LUT loading Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 09/16] drm/rockchip: ebc: Implement global refreshes Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 10/16] drm/rockchip: ebc: Implement partial refreshes Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 11/16] drm/rockchip: ebc: Enable diff mode for " Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 12/16] drm/rockchip: ebc: Add support for direct mode Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 13/16] drm/rockchip: ebc: Add a panel reflection option Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 14/16] drm/panel-simple: Add eInk ED103TC2 Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 15/16] arm64: dts: rockchip: rk356x: Add EBC node Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 16/16] [DO NOT MERGE] arm64: dts: rockchip: pinenote: Enable EBC display pipeline Samuel Holland
2022-04-14  8:50 ` [RFC PATCH 00/16] drm/rockchip: Rockchip EBC ("E-Book Controller") display driver Maxime Ripard
2022-05-25 17:18   ` Daniel Vetter
2022-05-31  8:58     ` Maxime Ripard
2022-06-01 12:35       ` Daniel Vetter
2022-06-08 14:48         ` Maxime Ripard
2022-06-08 15:34           ` Daniel Vetter
2022-04-21  6:43 ` Andreas Kemnade
2022-04-21  7:10   ` Nicolas Frattaroli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220413221916.50995-6-samuel@sholland.org \
    --to=samuel@sholland.org \
    --cc=airlied@linux.ie \
    --cc=alistair@alistair23.me \
    --cc=andreas@kemnade.info \
    --cc=cl@rock-chips.com \
    --cc=daniel@ffwll.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=frattaroli.nicolas@gmail.com \
    --cc=geert@linux-m68k.org \
    --cc=heiko@sntech.de \
    --cc=hjc@rock-chips.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=michael.riesch@wolfvision.net \
    --cc=mripard@kernel.org \
    --cc=pgwipeout@gmail.com \
    --cc=robh+dt@kernel.org \
    --cc=sam@ravnborg.org \
    --cc=thierry.reding@gmail.com \
    --cc=tzimmermann@suse.de \
    --cc=x@xff.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).