From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6099C4363A for ; Mon, 26 Oct 2020 15:40:50 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4CD5322400 for ; Mon, 26 Oct 2020 15:40:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="eIbls/3n"; dkim=temperror (0-bit key) header.d=cerno.tech header.i=@cerno.tech header.b="u9MTbBUH"; dkim=temperror (0-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="NO1rDqBn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4CD5322400 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=cerno.tech Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Type:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: In-Reply-To:MIME-Version:References:Message-ID:Subject:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=kfNlz/D7OBflW+VaSXpNL4QAq8AhFbUwDRbzYgS7RIc=; b=eIbls/3nu7Oekwm58i5bHErs6 dIJb585Hx07JeBTxNM2UjfHKSOh2OGUqPrh8Wejz/TuGMxgjEUi+YFQAlfpmUjLcylnjkvfpgrBml tZxrt+QGgAUlkIIKhT/iFcP6djQqM7RoWTB05eBYZ6i5/WaJZ1//hakH4bBJFhgA0rLClps7ISa/+ +FilQBnNbMYQ6rq4OObKZbaapcFIibDLre0664rvVmh4FjPd4GH3c545wM/kL1XagmSycv2fIYtSv LGEPoltyNmqDF8qU78FVfdgxvkf9NcpiwMCWB5F/+YnZLH4w36G1+by/UGTfE6Qeqd14bOdgYzR2O OnhGUCwIw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kX4aW-0005vt-KI; Mon, 26 Oct 2020 15:39:12 +0000 Received: from new3-smtp.messagingengine.com ([66.111.4.229]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kX4aT-0005uh-U3 for linux-arm-kernel@lists.infradead.org; Mon, 26 Oct 2020 15:39:10 +0000 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailnew.nyi.internal (Postfix) with ESMTP id C001E58050A; Mon, 26 Oct 2020 11:39:06 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Mon, 26 Oct 2020 11:39:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h= date:from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm1; bh=T3QTLn2mB7EXSOCvp51wp2tsbsv 7df3RtrrozDyp/kE=; b=u9MTbBUHC0wqSxiad7fcHOM2OENhPLZiLSpURW9d7pR 38h8zkZBjcI/Zhwj13D77Chkfavtqyq5rL+Lyn6nam9+lUoqi8BM63nIUnBbi4Mq eIzFgk+Qcn7BRdOqhwRjh2XOme3GWmuba4GaLChfw9MfStO0VITv13NXm+qXndHl MSDEyXW0OlVHke5W1O2VG1K3W/YbTtYUdKg1ylsQ00xDk4A9kDA9apEKlHDHIKWG IoU7K4mv/wrk/jUkymjm7MjhUJQmgXzuHXWcuRLQMpPejw4unea6GRnU+/QY4Pyk B2Pwgk3iRWPFr9TCxh4tw9tue6IiSB4uGQoE2fT5T0w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=T3QTLn 2mB7EXSOCvp51wp2tsbsv7df3RtrrozDyp/kE=; b=NO1rDqBn04f+S6O1itifDt lrmSChP0lFhQMDUz1sZdadgEqcLTImqGIU5c+WYPJ5LwPBdQy12duX9Ji2FMnLD+ TajntyIAv0PZ9tU0jdrvH92sbY54HCmSqHuM8OZ36/mg28vorZJAv/Dt2pwUgmqC YQwZoviHMChki2R/WF+iYwKMBroZKd4Fsz05Q0CxclpTQsfI4WcWJGFCuOD1CFGp CwZbQ2XrKNdUwe1f+fSCT1w3rtb0aLZzPPFu98tWYjJ2gMhk2MNRYPGfpy/H1h3j v7RU05YEuTVCYDBu8OlOvK+9MH41pspAAvIxqoF2EEMrH5/A6U2pnmgH3uVzIa2g == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrkeejgdegvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomhepofgrgihimhgv ucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtth gvrhhnpeelkeeghefhuddtleejgfeljeffheffgfeijefhgfeufefhtdevteegheeiheeg udenucfkphepledtrdekledrieekrdejieenucevlhhushhtvghrufhiiigvpedtnecurf grrhgrmhepmhgrihhlfhhrohhmpehmrgigihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: from localhost (lfbn-tou-1-1502-76.w90-89.abo.wanadoo.fr [90.89.68.76]) by mail.messagingengine.com (Postfix) with ESMTPA id 154463280059; Mon, 26 Oct 2020 11:38:58 -0400 (EDT) Date: Mon, 26 Oct 2020 16:38:57 +0100 From: Maxime Ripard To: Paul Kocialkowski Subject: Re: [PATCH 02/14] phy: allwinner: phy-sun6i-mipi-dphy: Support D-PHY Rx mode for MIPI CSI-2 Message-ID: <20201026153857.iwkn4iusi2jy2yf4@gilmour.lan> References: <20201023174546.504028-1-paul.kocialkowski@bootlin.com> <20201023174546.504028-3-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 In-Reply-To: <20201023174546.504028-3-paul.kocialkowski@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201026_113910_031275_51BE9238 X-CRM114-Status: GOOD ( 30.78 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devel@driverdev.osuosl.org, devicetree@vger.kernel.org, Philipp Zabel , Kishon Vijay Abraham I , Thomas Petazzoni , Greg Kroah-Hartman , Helen Koike , linux-kernel@vger.kernel.org, Chen-Yu Tsai , Hans Verkuil , linux-sunxi@googlegroups.com, Rob Herring , Vinod Koul , Yong Deng , Sakari Ailus , Hans Verkuil , Mauro Carvalho Chehab , kevin.lhopital@hotmail.com, linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org Content-Type: multipart/mixed; boundary="===============5206625075869366783==" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org --===============5206625075869366783== Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="5cvkpdcapo7wtm7b" Content-Disposition: inline --5cvkpdcapo7wtm7b Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Oct 23, 2020 at 07:45:34PM +0200, Paul Kocialkowski wrote: > The Allwinner A31 D-PHY supports both Rx and Tx modes. While the latter > is already supported and used for MIPI DSI this adds support for the > former, to be used with MIPI CSI-2. >=20 > This implementation is inspired by the Allwinner BSP implementation. Mentionning which BSP you took this from would be helpful > Signed-off-by: Paul Kocialkowski > --- > drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 164 +++++++++++++++++++- > 1 file changed, 160 insertions(+), 4 deletions(-) >=20 > diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/al= lwinner/phy-sun6i-mipi-dphy.c > index 1fa761ba6cbb..8bcd4bb79f60 100644 > --- a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c > +++ b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c > @@ -24,6 +24,14 @@ > #define SUN6I_DPHY_TX_CTL_REG 0x04 > #define SUN6I_DPHY_TX_CTL_HS_TX_CLK_CONT BIT(28) > =20 > +#define SUN6I_DPHY_RX_CTL_REG 0x08 > +#define SUN6I_DPHY_RX_CTL_EN_DBC BIT(31) > +#define SUN6I_DPHY_RX_CTL_RX_CLK_FORCE BIT(24) > +#define SUN6I_DPHY_RX_CTL_RX_D3_FORCE BIT(23) > +#define SUN6I_DPHY_RX_CTL_RX_D2_FORCE BIT(22) > +#define SUN6I_DPHY_RX_CTL_RX_D1_FORCE BIT(21) > +#define SUN6I_DPHY_RX_CTL_RX_D0_FORCE BIT(20) > + It's hard to tell from the diff, but it looks like you aligned the BIT(..) with the register? If so, you should follow the what the rest of this driver (ie, one more indentation for register values). > #define SUN6I_DPHY_TX_TIME0_REG 0x10 > #define SUN6I_DPHY_TX_TIME0_HS_TRAIL(n) (((n) & 0xff) << 24) > #define SUN6I_DPHY_TX_TIME0_HS_PREPARE(n) (((n) & 0xff) << 16) > @@ -44,12 +52,29 @@ > #define SUN6I_DPHY_TX_TIME4_HS_TX_ANA1(n) (((n) & 0xff) << 8) > #define SUN6I_DPHY_TX_TIME4_HS_TX_ANA0(n) ((n) & 0xff) > =20 > +#define SUN6I_DPHY_RX_TIME0_REG 0x30 > +#define SUN6I_DPHY_RX_TIME0_HS_RX_SYNC(n) (((n) & 0xff) << 24) > +#define SUN6I_DPHY_RX_TIME0_HS_RX_CLK_MISS(n) (((n) & 0xff) << 16) > +#define SUN6I_DPHY_RX_TIME0_LP_RX(n) (((n) & 0xff) << 8) > + > +#define SUN6I_DPHY_RX_TIME1_REG 0x34 > +#define SUN6I_DPHY_RX_TIME1_RX_DLY(n) (((n) & 0xfff) << 20) > +#define SUN6I_DPHY_RX_TIME1_LP_RX_ULPS_WP(n) ((n) & 0xfffff) > + > +#define SUN6I_DPHY_RX_TIME2_REG 0x38 > +#define SUN6I_DPHY_RX_TIME2_HS_RX_ANA1(n) (((n) & 0xff) << 8) > +#define SUN6I_DPHY_RX_TIME2_HS_RX_ANA0(n) ((n) & 0xff) > + > +#define SUN6I_DPHY_RX_TIME3_REG 0x40 > +#define SUN6I_DPHY_RX_TIME3_LPRST_DLY(n) (((n) & 0xffff) << 16) > + > #define SUN6I_DPHY_ANA0_REG 0x4c > #define SUN6I_DPHY_ANA0_REG_PWS BIT(31) > #define SUN6I_DPHY_ANA0_REG_DMPC BIT(28) > #define SUN6I_DPHY_ANA0_REG_DMPD(n) (((n) & 0xf) << 24) > #define SUN6I_DPHY_ANA0_REG_SLV(n) (((n) & 7) << 12) > #define SUN6I_DPHY_ANA0_REG_DEN(n) (((n) & 0xf) << 8) > +#define SUN6I_DPHY_ANA0_REG_SFB(n) (((n) & 3) << 2) > =20 > #define SUN6I_DPHY_ANA1_REG 0x50 > #define SUN6I_DPHY_ANA1_REG_VTTMODE BIT(31) > @@ -92,6 +117,8 @@ struct sun6i_dphy { > =20 > struct phy *phy; > struct phy_configure_opts_mipi_dphy config; > + > + int submode; > }; > =20 > static int sun6i_dphy_init(struct phy *phy) > @@ -105,6 +132,18 @@ static int sun6i_dphy_init(struct phy *phy) > return 0; > } > =20 > +static int sun6i_dphy_set_mode(struct phy *phy, enum phy_mode mode, int = submode) > +{ > + struct sun6i_dphy *dphy =3D phy_get_drvdata(phy); > + > + if (mode !=3D PHY_MODE_MIPI_DPHY) > + return -EINVAL; > + > + dphy->submode =3D submode; > + > + return 0; > +} > + > static int sun6i_dphy_configure(struct phy *phy, union phy_configure_opt= s *opts) > { > struct sun6i_dphy *dphy =3D phy_get_drvdata(phy); > @@ -119,9 +158,8 @@ static int sun6i_dphy_configure(struct phy *phy, unio= n phy_configure_opts *opts) > return 0; > } > =20 > -static int sun6i_dphy_power_on(struct phy *phy) > +static int sun6i_dphy_tx_power_on(struct sun6i_dphy *dphy) > { > - struct sun6i_dphy *dphy =3D phy_get_drvdata(phy); > u8 lanes_mask =3D GENMASK(dphy->config.lanes - 1, 0); > =20 > regmap_write(dphy->regs, SUN6I_DPHY_TX_CTL_REG, > @@ -211,12 +249,129 @@ static int sun6i_dphy_power_on(struct phy *phy) > return 0; > } > =20 > +static int sun6i_dphy_rx_power_on(struct sun6i_dphy *dphy) > +{ > + /* Physical clock rate is actually half of symbol rate with DDR. */ > + unsigned long mipi_symbol_rate =3D dphy->config.hs_clk_rate; > + unsigned long dphy_clk_rate; > + unsigned int rx_dly; > + unsigned int lprst_dly; > + u32 value; > + > + dphy_clk_rate =3D clk_get_rate(dphy->mod_clk); > + if (!dphy_clk_rate) > + return -1; Returning -1 is weird here? > + > + /* Hardcoded timing parameters from the Allwinner BSP. */ > + regmap_write(dphy->regs, SUN6I_DPHY_RX_TIME0_REG, > + SUN6I_DPHY_RX_TIME0_HS_RX_SYNC(255) | > + SUN6I_DPHY_RX_TIME0_HS_RX_CLK_MISS(255) | > + SUN6I_DPHY_RX_TIME0_LP_RX(255)); > + > + /* > + * Formula from the Allwinner BSP, with hardcoded coefficients > + * (probably internal divider/multiplier). > + */ > + rx_dly =3D 8 * (unsigned int)(dphy_clk_rate / (mipi_symbol_rate / 8)); > + > + /* > + * The Allwinner BSP has an alternative formula for LP_RX_ULPS_WP: > + * lp_ulps_wp_cnt =3D lp_ulps_wp_ms * lp_clk / 1000 > + * but does not use it and hardcodes 255 instead. > + */ > + regmap_write(dphy->regs, SUN6I_DPHY_RX_TIME1_REG, > + SUN6I_DPHY_RX_TIME1_RX_DLY(rx_dly) | > + SUN6I_DPHY_RX_TIME1_LP_RX_ULPS_WP(255)); > + > + /* HS_RX_ANA0 value is hardcoded in the Allwinner BSP. */ > + regmap_write(dphy->regs, SUN6I_DPHY_RX_TIME2_REG, > + SUN6I_DPHY_RX_TIME2_HS_RX_ANA0(4)); > + > + /* > + * Formula from the Allwinner BSP, with hardcoded coefficients > + * (probably internal divider/multiplier). > + */ > + lprst_dly =3D 4 * (unsigned int)(dphy_clk_rate / (mipi_symbol_rate / 2)= ); > + > + regmap_write(dphy->regs, SUN6I_DPHY_RX_TIME3_REG, > + SUN6I_DPHY_RX_TIME3_LPRST_DLY(lprst_dly)); > + > + /* Analog parameters are hardcoded in the Allwinner BSP. */ > + regmap_write(dphy->regs, SUN6I_DPHY_ANA0_REG, > + SUN6I_DPHY_ANA0_REG_PWS | > + SUN6I_DPHY_ANA0_REG_SLV(7) | > + SUN6I_DPHY_ANA0_REG_SFB(2)); > + > + regmap_write(dphy->regs, SUN6I_DPHY_ANA1_REG, > + SUN6I_DPHY_ANA1_REG_SVTT(4)); > + > + regmap_write(dphy->regs, SUN6I_DPHY_ANA4_REG, > + SUN6I_DPHY_ANA4_REG_DMPLVC | > + SUN6I_DPHY_ANA4_REG_DMPLVD(1)); > + > + regmap_write(dphy->regs, SUN6I_DPHY_ANA2_REG, > + SUN6I_DPHY_ANA2_REG_ENIB); > + > + regmap_write(dphy->regs, SUN6I_DPHY_ANA3_REG, > + SUN6I_DPHY_ANA3_EN_LDOR | > + SUN6I_DPHY_ANA3_EN_LDOC | > + SUN6I_DPHY_ANA3_EN_LDOD); > + > + /* > + * Delay comes from the Allwinner BSP, likely for internal regulator > + * ramp-up. > + */ > + udelay(3); > + > + value =3D SUN6I_DPHY_RX_CTL_EN_DBC | SUN6I_DPHY_RX_CTL_RX_CLK_FORCE; > + > + /* > + * Rx data lane force-enable bits are used as regular RX enable by the > + * Allwinner BSP. > + */ > + if (dphy->config.lanes >=3D 1) > + value |=3D SUN6I_DPHY_RX_CTL_RX_D0_FORCE; > + if (dphy->config.lanes >=3D 2) > + value |=3D SUN6I_DPHY_RX_CTL_RX_D1_FORCE; > + if (dphy->config.lanes >=3D 3) > + value |=3D SUN6I_DPHY_RX_CTL_RX_D2_FORCE; > + if (dphy->config.lanes =3D=3D 4) > + value |=3D SUN6I_DPHY_RX_CTL_RX_D3_FORCE; > + > + regmap_write(dphy->regs, SUN6I_DPHY_RX_CTL_REG, value); > + > + regmap_write(dphy->regs, SUN6I_DPHY_GCTL_REG, > + SUN6I_DPHY_GCTL_LANE_NUM(dphy->config.lanes) | > + SUN6I_DPHY_GCTL_EN); > + > + return 0; > +} > + > +static int sun6i_dphy_power_on(struct phy *phy) > +{ > + struct sun6i_dphy *dphy =3D phy_get_drvdata(phy); > + > + switch (dphy->submode) { > + case PHY_MIPI_DPHY_SUBMODE_TX: > + return sun6i_dphy_tx_power_on(dphy); > + case PHY_MIPI_DPHY_SUBMODE_RX: > + return sun6i_dphy_rx_power_on(dphy); > + default: > + return -EINVAL; > + } > +} > + Can one call power_on before set_mode? > static int sun6i_dphy_power_off(struct phy *phy) > { > struct sun6i_dphy *dphy =3D phy_get_drvdata(phy); > =20 > - regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA1_REG, > - SUN6I_DPHY_ANA1_REG_VTTMODE, 0); > + regmap_write(dphy->regs, SUN6I_DPHY_GCTL_REG, 0); > + > + regmap_write(dphy->regs, SUN6I_DPHY_ANA0_REG, 0); > + regmap_write(dphy->regs, SUN6I_DPHY_ANA1_REG, 0); This looks like a change that should be mentioned (or in a separate patch). Maxime --5cvkpdcapo7wtm7b Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCX5btkQAKCRDj7w1vZxhR xUBHAQChkEAS41mkyzjme9DrIAAnuGBkUb1ivp9fGoZl+ff1nAEAglHnjwBwlYQA KOlYq7HcCAtaryTr7AUZPBR1RIqxuwc= =vZ2X -----END PGP SIGNATURE----- --5cvkpdcapo7wtm7b-- --===============5206625075869366783== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel --===============5206625075869366783==--