From patchwork Sat Feb 5 18:53:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E077C433F5 for ; Sat, 5 Feb 2022 18:54:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381072AbiBESyu (ORCPT ); Sat, 5 Feb 2022 13:54:50 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:55507 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381048AbiBESyp (ORCPT ); Sat, 5 Feb 2022 13:54:45 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 2F5F3240003; Sat, 5 Feb 2022 18:54:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087283; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MdNte4sN/MUAO5c6piyw/+F9bIGGex5gsZiLTGbQSck=; b=mv5VwDSlYn/pVjUom3rpRYcRFbdr7D+YYIJxxfTnpGY9Cl9p0/JkjeQs7fh6apCzg17pBR E7mIBwqlbrnz3kTTKuy8k7acZPKQXymfhvNiDhaDAj6ciYFFUWqy+tNiMZc7yrk2Z7163V UG6pEdB7klVMqDKfkl23yTx4l6KDxW4+rI4kvjj8KQ7SyWa/wH8q47lzHYt5hQqLXi2dP3 CBqDoKQEKKPjqGZbwYGxSz7pz18z3dtMGt4GBTheVn702FABUcdJSoJNQ2hdRt8I+q/6xB Kljst51Gao+mApuQNO3yGr2DI7pRMJIRZTAQFOHd0tVJ1/Ldmez3uS+1Qq5lgw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 02/66] dt-bindings: interconnect: sunxi: Add V3s mbus compatible Date: Sat, 5 Feb 2022 19:53:25 +0100 Message-Id: <20220205185429.2278860-3-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Since the V3s uses the internal mbus, document its compatible. Signed-off-by: Paul Kocialkowski --- .../devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml b/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml index 29c9961ee2d8..b67bf9261a6a 100644 --- a/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml +++ b/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml @@ -31,6 +31,7 @@ properties: - allwinner,sun5i-a13-mbus - allwinner,sun8i-h3-mbus - allwinner,sun8i-r40-mbus + - allwinner,sun8i-v3s-mbus - allwinner,sun50i-a64-mbus reg: From patchwork Sat Feb 5 18:53:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540172 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1A5FC4332F for ; Sat, 5 Feb 2022 18:54:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381121AbiBESyz (ORCPT ); Sat, 5 Feb 2022 13:54:55 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:38719 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381085AbiBESyw (ORCPT ); Sat, 5 Feb 2022 13:54:52 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id E8D0F240007; Sat, 5 Feb 2022 18:54:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087285; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rrHhQG98XjZGaFVSafcd5TS6lrLI7/LjgMEMco8ughE=; b=VyKk4OhmysKmQckNz1/RaX4q49SQLj0nMp5B52oNIoAFAYBOd5GrFL0dp/FCh7EkvqHSJH CU3qWKCK0SH5OH4jcn9pzQqrl8/XW4p2Ns6EndDH0pSLqPs3axmFic9jWrS/q0by4cwBNR ZPym4GV36bZouyoDHF3Lqd4O3WI6jGbQC4RNJTqmYBoUDlpALBtU4gB2M4w0pkoWajBACX xP5GITANtPwuifCu0FpBa4svfz9Kr0BX0aFLwnyiADNF5VvRWpwV4rxGAXHQwoK3V7Szss SYDVLSBmaA5p+zkKjd41aZrHIWPSRy2PDYa9vHlZaWN0geXgjWtlNmkWZOdtLQ== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 03/66] clk: sunxi-ng: v3s: Export the MBUS clock to the public header Date: Sat, 5 Feb 2022 19:53:26 +0100 Message-Id: <20220205185429.2278860-4-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In order to declare a mbus node for the v3s, expose its dedicated clock to the public header. Signed-off-by: Paul Kocialkowski --- drivers/clk/sunxi-ng/ccu-sun8i-v3s.h | 2 -- include/dt-bindings/clock/sun8i-v3s-ccu.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h index 108eeeedcbf7..e99c4a8431c9 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h @@ -45,8 +45,6 @@ /* Some more module clocks are exported */ -#define CLK_MBUS 72 - /* And the GPU module clock is exported */ #define CLK_PLL_DDR1 74 diff --git a/include/dt-bindings/clock/sun8i-v3s-ccu.h b/include/dt-bindings/clock/sun8i-v3s-ccu.h index 014ac6123d17..ff4d49d6a740 100644 --- a/include/dt-bindings/clock/sun8i-v3s-ccu.h +++ b/include/dt-bindings/clock/sun8i-v3s-ccu.h @@ -101,7 +101,7 @@ #define CLK_VE 69 #define CLK_AC_DIG 70 #define CLK_AVS 71 - +#define CLK_MBUS 72 #define CLK_MIPI_CSI 73 /* Clocks not available on V3s */ From patchwork Sat Feb 5 18:53:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540170 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4E3A2C433F5 for ; Sat, 5 Feb 2022 18:55:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381109AbiBESzC (ORCPT ); Sat, 5 Feb 2022 13:55:02 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:43385 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381102AbiBESyz (ORCPT ); Sat, 5 Feb 2022 13:54:55 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id E84E324000A; Sat, 5 Feb 2022 18:54:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087290; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=29+cdXhI7L+2Gxc8tUO/DTtQnEvp3UwBUI/8lM2KtFc=; b=SX+D04eBXLLpgWObpYKueWwe0B+Xy4hJcCDJP+JF14LGOpZvh7uLA+XUvjKGB72NDJyt6R 7yWWL2ol3So3g52bmaRFY6EhwGrS1AqaQzIKXkKDqKEerDrSgpDTlVoDYCA7IQozkxlDri E88zpaPD6vUSnAkDrWqyYLtPw7yZ4g7D9zPPpgCkLmotUnKJNaD6w9ydMyQhZb9/BCxNjN kcP2es4/UoXdErLs+pjU9OjCUxdze9PyOFSVhhIKyM6PHU+kihzVxmE+DLIZDhOAegWiuX e4NqadwyGN7uXkj6oC54J8MdSZc87fhGVCzJaZx06fQxDPAtt6xHGzne8RcExw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 06/66] phy: allwinner: phy-sun6i-mipi-dphy: Support D-PHY Rx mode for MIPI CSI-2 Date: Sat, 5 Feb 2022 19:53:29 +0100 Message-Id: <20220205185429.2278860-7-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org 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. This implementation is inspired by Allwinner's V3s Linux SDK implementation, which was used as a documentation base. It uses the direction dt property to distinguish between tx and rx directions. Signed-off-by: Paul Kocialkowski --- drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 166 +++++++++++++++++++- 1 file changed, 162 insertions(+), 4 deletions(-) diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c index f0bc87d654d4..3900f1650851 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) +#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) + #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) +#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) #define SUN6I_DPHY_ANA1_REG 0x50 #define SUN6I_DPHY_ANA1_REG_VTTMODE BIT(31) @@ -84,6 +109,11 @@ #define SUN6I_DPHY_DBG5_REG 0xf4 +enum sun6i_dphy_direction { + SUN6I_DPHY_DIRECTION_TX, + SUN6I_DPHY_DIRECTION_RX, +}; + struct sun6i_dphy { struct clk *bus_clk; struct clk *mod_clk; @@ -92,6 +122,8 @@ struct sun6i_dphy { struct phy *phy; struct phy_configure_opts_mipi_dphy config; + + enum sun6i_dphy_direction direction; }; static int sun6i_dphy_init(struct phy *phy) @@ -119,9 +151,8 @@ static int sun6i_dphy_configure(struct phy *phy, union phy_configure_opts *opts) return 0; } -static int sun6i_dphy_power_on(struct phy *phy) +static int sun6i_dphy_tx_power_on(struct sun6i_dphy *dphy) { - struct sun6i_dphy *dphy = phy_get_drvdata(phy); u8 lanes_mask = GENMASK(dphy->config.lanes - 1, 0); regmap_write(dphy->regs, SUN6I_DPHY_TX_CTL_REG, @@ -211,12 +242,129 @@ static int sun6i_dphy_power_on(struct phy *phy) return 0; } +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 = dphy->config.hs_clk_rate; + unsigned long dphy_clk_rate; + unsigned int rx_dly; + unsigned int lprst_dly; + u32 value; + + dphy_clk_rate = clk_get_rate(dphy->mod_clk); + if (!dphy_clk_rate) + return -EINVAL; + + /* 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 = 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 = 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 = 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 = 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 >= 1) + value |= SUN6I_DPHY_RX_CTL_RX_D0_FORCE; + if (dphy->config.lanes >= 2) + value |= SUN6I_DPHY_RX_CTL_RX_D1_FORCE; + if (dphy->config.lanes >= 3) + value |= SUN6I_DPHY_RX_CTL_RX_D2_FORCE; + if (dphy->config.lanes == 4) + value |= 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 = phy_get_drvdata(phy); + + switch (dphy->direction) { + case SUN6I_DPHY_DIRECTION_TX: + return sun6i_dphy_tx_power_on(dphy); + case SUN6I_DPHY_DIRECTION_RX: + return sun6i_dphy_rx_power_on(dphy); + default: + return -EINVAL; + } +} + static int sun6i_dphy_power_off(struct phy *phy) { struct sun6i_dphy *dphy = phy_get_drvdata(phy); - 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); + regmap_write(dphy->regs, SUN6I_DPHY_ANA2_REG, 0); + regmap_write(dphy->regs, SUN6I_DPHY_ANA3_REG, 0); + regmap_write(dphy->regs, SUN6I_DPHY_ANA4_REG, 0); return 0; } @@ -253,7 +401,9 @@ static int sun6i_dphy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct sun6i_dphy *dphy; + const char *direction; void __iomem *regs; + int ret; dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); if (!dphy) @@ -290,6 +440,14 @@ static int sun6i_dphy_probe(struct platform_device *pdev) return PTR_ERR(dphy->phy); } + dphy->direction = SUN6I_DPHY_DIRECTION_TX; + + ret = of_property_read_string(pdev->dev.of_node, "allwinner,direction", + &direction); + + if (!ret && !strncmp(direction, "rx", 2)) + dphy->direction = SUN6I_DPHY_DIRECTION_RX; + phy_set_drvdata(dphy->phy, dphy); phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); From patchwork Sat Feb 5 18:53:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E891FC43219 for ; Sat, 5 Feb 2022 18:55:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381137AbiBESy7 (ORCPT ); Sat, 5 Feb 2022 13:54:59 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:49837 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381062AbiBESyx (ORCPT ); Sat, 5 Feb 2022 13:54:53 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 9ADEC240009; Sat, 5 Feb 2022 18:54:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087292; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PYHTZKqj0x0O/vJOFCxW3AwpA9ajkrs61CKkByxlSfY=; b=dR6U3nGVfoZM8vXisu6jKz0ldY5QaRrqMCaS7JtFLZ7PgD8shwIZwbkZJUymE4AVLIQic9 uIX2rWIuED2LDgUzMGMnk1PzWXprX0XKs1QnWmhEpTlmdYHVRrDUKaXmT5D674/R6Q+SP2 HI5Bpgz94SgVIS3n5Gz8t0i5tj/1m09H+SeFOuEDf1qPSwBhRMWlHj1jMcaan8N3z1lp3c QbBxfgoi3cVsZXB0ZqpH1yQknf5rrCkfSi9ylhXCm9uf2Px9seeMt84fNpVgpseqengYaZ FhbInBNu3n1NQfbGNQlIXLCWlC4R4XRtZlJJkkf5PtEigaZeySzun5HHJa/Ovg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni , Rob Herring Subject: [PATCH v2 07/66] dt-bindings: media: sun6i-a31-csi: Add MIPI CSI-2 input port Date: Sat, 5 Feb 2022 19:53:30 +0100 Message-Id: <20220205185429.2278860-8-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The A31 CSI controller supports two distinct input interfaces: parallel and an external MIPI CSI-2 bridge. The parallel interface is often connected to a set of hardware pins while the MIPI CSI-2 bridge is an internal FIFO-ish link. As a result, these two inputs are distinguished as two different ports. Note that only one of the two may be present on a controller instance. For example, the V3s has one controller dedicated to MIPI-CSI2 and one dedicated to parallel. Update the binding with an explicit ports node that holds two distinct port nodes: one for parallel input and one for MIPI CSI-2. This is backward-compatible with the single-port approach that was previously taken for representing the parallel interface port, which stays enumerated as fwnode port 0. Note that additional ports may be added in the future, especially to support feeding the CSI controller's output to the ISP. Signed-off-by: Paul Kocialkowski Reviewed-by: Rob Herring Acked-by: Maxime Ripard --- .../media/allwinner,sun6i-a31-csi.yaml | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml index 8b568072a069..3cc61866ea89 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml @@ -61,6 +61,34 @@ properties: additionalProperties: false + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: "#/properties/port" + unevaluatedProperties: false + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + description: MIPI CSI-2 bridge input port + + properties: + reg: + const: 1 + + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + additionalProperties: false + + anyOf: + - required: + - port@0 + - required: + - port@1 + required: - compatible - reg @@ -89,19 +117,25 @@ examples: "ram"; resets = <&ccu RST_BUS_CSI>; - port { - /* Parallel bus endpoint */ - csi1_ep: endpoint { - remote-endpoint = <&adv7611_ep>; - bus-width = <16>; - - /* - * If hsync-active/vsync-active are missing, - * embedded BT.656 sync is used. - */ - hsync-active = <0>; /* Active low */ - vsync-active = <0>; /* Active low */ - pclk-sample = <1>; /* Rising */ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + /* Parallel bus endpoint */ + csi1_ep: endpoint { + remote-endpoint = <&adv7611_ep>; + bus-width = <16>; + + /* + * If hsync-active/vsync-active are missing, + * embedded BT.656 sync is used. + */ + hsync-active = <0>; /* Active low */ + vsync-active = <0>; /* Active low */ + pclk-sample = <1>; /* Rising */ + }; }; }; }; From patchwork Sat Feb 5 18:53:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C7B5C433F5 for ; Sat, 5 Feb 2022 18:55:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381105AbiBESzU (ORCPT ); Sat, 5 Feb 2022 13:55:20 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:60835 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381149AbiBESzC (ORCPT ); Sat, 5 Feb 2022 13:55:02 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id C4C91240004; Sat, 5 Feb 2022 18:54:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087297; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AkCUFwi2J94S15k7JkU9goJLycFgn6HTv5Orvy3MRa0=; b=ZLQdaBZwYXCBbqHkCDF3izo/hbLxX+IM2FQgeAc0oXwkSxqQB7NFNtscrT8M1Tg9XS0nsH OFG5oKC3xe81ceoLlBOcRNa2vuYXuBOUP+XgzbucAwwC1qusTMbbyLxH8H6lHRvCfpsj1b XU+QwJK0bHbAYadoBzLgJvfRdsHDsxaONgYezB7TausHVH4rvvYDYGtXyRBLL5Iwwt94my 8J95GDe9YU1ujtN8EMxgf92uJrPZIIlfF/RHJW61AY4WqAPvfn38N04Eox0Mpm1lUWHbBS jBaGNSV7xkA7sbpNrerGzFjGjArITjsp9//nLL0BAn/sz74pFMDRmQ8Uze3W9g== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 10/66] MAINTAINERS: Add entry for the Allwinner A31 MIPI CSI-2 bridge driver Date: Sat, 5 Feb 2022 19:53:33 +0100 Message-Id: <20220205185429.2278860-11-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add myself as maintainer of the Allwinner A31 MIPI CSI-2 bridge media driver. Signed-off-by: Paul Kocialkowski --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 79fd8a012893..040c54b2d767 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -751,6 +751,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml F: drivers/media/platform/sunxi/sun4i-csi/ +ALLWINNER A31 MIPI CSI-2 BRIDGE DRIVER +M: Paul Kocialkowski +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-mipi-csi2.yaml +F: drivers/media/platform/sunxi/sun6i-mipi-csi2/ + ALLWINNER CPUFREQ DRIVER M: Yangtao Li L: linux-pm@vger.kernel.org From patchwork Sat Feb 5 18:53:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540168 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4AB9C4321E for ; Sat, 5 Feb 2022 18:55:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376771AbiBESzV (ORCPT ); Sat, 5 Feb 2022 13:55:21 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:57977 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381106AbiBESzF (ORCPT ); Sat, 5 Feb 2022 13:55:05 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 164F8240008; Sat, 5 Feb 2022 18:54:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087300; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SJXIIRPiADrOm3fQioZmJ3XdeC3XcqI9oqKCgUuUrW0=; b=gjAdfkBv+tmtjny4VpBQ/toS7Rnvq/8JcLvrC/oZfQS1WJbCWOTLMxT/icVT2LxbaURbik NDrDPnSXetJhY/doi64OhpUiGHklacNe0/MyKfKETmtmAxVzJSVbDdT3BmzG8Z7UUluZ98 /NDxA433DL5OiF8sjraNL75w9yY2QmoJlVnHUk+f3nSDP9W9vYeeTui/B0ZBXzssaejMun mfFqpXQo2/1qGbgZV3xFLba9Ktey6w61D1hHbt/MRdcFaNXPehJCSjcwgbFw72ar2/8lCh 03A+uWS0W2tGH2Fva4UJek1OpvLWOOLw2FoyGwYPDMo+AnnOv5tFQE4y9/O8Zw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni , Rob Herring Subject: [PATCH v2 12/66] dt-bindings: media: Add Allwinner A83T MIPI CSI-2 bindings documentation Date: Sat, 5 Feb 2022 19:53:35 +0100 Message-Id: <20220205185429.2278860-13-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This introduces YAML bindings documentation for the Allwinner A83T MIPI CSI-2 controller. Signed-off-by: Paul Kocialkowski Reviewed-by: Rob Herring --- .../media/allwinner,sun8i-a83t-mipi-csi2.yaml | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-mipi-csi2.yaml diff --git a/Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-mipi-csi2.yaml new file mode 100644 index 000000000000..0d41681bb8b2 --- /dev/null +++ b/Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-mipi-csi2.yaml @@ -0,0 +1,133 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/allwinner,sun8i-a83t-mipi-csi2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Allwinner A83T MIPI CSI-2 Device Tree Bindings + +maintainers: + - Paul Kocialkowski + +properties: + compatible: + const: allwinner,sun8i-a83t-mipi-csi2 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Bus Clock + - description: Module Clock + - description: MIPI-specific Clock + - description: Misc CSI Clock + + clock-names: + items: + - const: bus + - const: mod + - const: mipi + - const: misc + + resets: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + description: Input port, connect to a MIPI CSI-2 sensor + + properties: + reg: + const: 0 + + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + maxItems: 1 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + + additionalProperties: false + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + description: Output port, connect to a CSI controller + + properties: + reg: + const: 1 + + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + +additionalProperties: false + +examples: + - | + #include + #include + #include + + mipi_csi2: csi@1cb1000 { + compatible = "allwinner,sun8i-a83t-mipi-csi2"; + reg = <0x01cb1000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_CSI>, + <&ccu CLK_CSI_SCLK>, + <&ccu CLK_MIPI_CSI>, + <&ccu CLK_CSI_MISC>; + clock-names = "bus", "mod", "mipi", "misc"; + resets = <&ccu RST_BUS_CSI>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mipi_csi2_in: port@0 { + reg = <0>; + + mipi_csi2_in_ov8865: endpoint { + data-lanes = <1 2 3 4>; + + remote-endpoint = <&ov8865_out_mipi_csi2>; + }; + }; + + mipi_csi2_out: port@1 { + reg = <1>; + + mipi_csi2_out_csi: endpoint { + remote-endpoint = <&csi_in_mipi_csi2>; + }; + }; + }; + }; + +... From patchwork Sat Feb 5 18:53:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540162 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD093C433FE for ; Sat, 5 Feb 2022 18:56:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381222AbiBES4E (ORCPT ); Sat, 5 Feb 2022 13:56:04 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:36681 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381062AbiBESzG (ORCPT ); Sat, 5 Feb 2022 13:55:06 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 5B9A524000D; Sat, 5 Feb 2022 18:55:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087305; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MhiHRsL0yzLC6uTSUm3nvN8Ru2hsN0kI74zny5+cDl8=; b=j+3HtCvcG9gSCcg2FQRozNh5VNadHeSPWdGynVvoRq8tSj5LmTNEggJ61PRSFeRslMjQu+ yjetcJBiAB4PUlt0tb0UyO6snuYkvIVYLWhxKtAnlvtfK4VB2Whg5aoEXRgByjwfLAV1l0 rcL7sC2dTBE3Ga7b/MfH7J9ph/i52qHypEBt/LIcMznV39pCFHIbFBgwf9gTR3yGpj+wri EaEPmsCIYrO1vaG820iUdMiuvLYOk0SHRaRwXeotZ+GKs/ebBdQ3Brl7O6DdFCcLxjvs6J o5/bPYt0f7qx3Y+T7Kp8DqF4JBZI2qD8rl0xLqOHifeVNKMU67oAOSoFZeE6iQ== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 15/66] ARM: dts: sun8i: a83t: Add MIPI CSI-2 controller node Date: Sat, 5 Feb 2022 19:53:38 +0100 Message-Id: <20220205185429.2278860-16-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org MIPI CSI-2 is supported on the A83T with a dedicated controller that covers both the protocol and D-PHY. It can be connected to the CSI interface as a V4L2 subdev through the fwnode graph. This is not done by default since connecting the bridge without a subdev attached to it will cause a failure on the CSI driver. Signed-off-by: Paul Kocialkowski --- arch/arm/boot/dts/sun8i-a83t.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 82fdb04122ca..ecf9f3b2c0c0 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -1064,6 +1064,32 @@ csi: camera@1cb0000 { status = "disabled"; }; + mipi_csi2: csi@1cb1000 { + compatible = "allwinner,sun8i-a83t-mipi-csi2"; + reg = <0x01cb1000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_CSI>, + <&ccu CLK_CSI_SCLK>, + <&ccu CLK_MIPI_CSI>, + <&ccu CLK_CSI_MISC>; + clock-names = "bus", "mod", "mipi", "misc"; + resets = <&ccu RST_BUS_CSI>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + mipi_csi2_in: port@0 { + reg = <0>; + }; + + mipi_csi2_out: port@1 { + reg = <1>; + }; + }; + }; + hdmi: hdmi@1ee0000 { compatible = "allwinner,sun8i-a83t-dw-hdmi"; reg = <0x01ee0000 0x10000>; From patchwork Sat Feb 5 18:53:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CE75C43217 for ; Sat, 5 Feb 2022 18:56:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381236AbiBES4F (ORCPT ); Sat, 5 Feb 2022 13:56:05 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:52873 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381207AbiBESzK (ORCPT ); Sat, 5 Feb 2022 13:55:10 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id DB76E24000B; Sat, 5 Feb 2022 18:55:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087309; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=thQFXb+Mbfog5Wu3+RYgHAOHMpkNUMkaPZldQzKOFCI=; b=POBS8qNGo79IGw+1tA4WMVk+b2+4QVJqDCBrSuj64Npk2IBHMtMxSOuXgberW/bWGUnYQs 6dOtimeBK873korpK0pFVujnFlTcnAQJNJb+mbPJMI3xa84kbKYi576E2ZK+L3zy2o4H/C JEA3fN0QjWE0rTOAbQwoXalgUb11YtWpaov5Z2pRMw/yuZKyL1vBkQAXa9gKBUDvpjdcDx bvV1tzVMZQuMFoz7uMl5F6WZocWujfhIK731EeRTO6uGqB+IKnUDFg7wCY2IGKg8uTk5K+ S9i2NLavH3Hue1GGIZBGLMH16UAej4HkKMUBm9PoilD0yqaiFGZM94+7xitXbg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 17/66] media: sun6i-csi: Define and use driver name and (reworked) description Date: Sat, 5 Feb 2022 19:53:40 +0100 Message-Id: <20220205185429.2278860-18-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add proper defines for driver name and description instead of MODULE_NAME and hardcoding (cosmetics). Also rework the description while at it to mention the hardware generation that the driver supports and remove the video capture mentions since it applies to the whole media device. Signed-off-by: Paul Kocialkowski --- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 14 ++++++-------- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h | 3 +++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index fc96921b0583..43dcd8117d3f 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -27,8 +27,6 @@ #include "sun6i_csi.h" #include "sun6i_csi_reg.h" -#define MODULE_NAME "sun6i-csi" - struct sun6i_csi_dev { struct sun6i_csi csi; struct device *dev; @@ -730,7 +728,7 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) int ret; csi->media_dev.dev = csi->dev; - strscpy(csi->media_dev.model, "Allwinner Video Capture Device", + strscpy(csi->media_dev.model, SUN6I_CSI_DESCRIPTION, sizeof(csi->media_dev.model)); csi->media_dev.hw_revision = 0; snprintf(csi->media_dev.bus_info, sizeof(csi->media_dev.bus_info), @@ -755,7 +753,7 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) goto free_ctrl; } - ret = sun6i_video_init(&csi->video, csi, "sun6i-csi"); + ret = sun6i_video_init(&csi->video, csi, SUN6I_CSI_NAME); if (ret) goto unreg_v4l2; @@ -870,8 +868,8 @@ static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev, if (irq < 0) return -ENXIO; - ret = devm_request_irq(&pdev->dev, irq, sun6i_csi_isr, 0, MODULE_NAME, - sdev); + ret = devm_request_irq(&pdev->dev, irq, sun6i_csi_isr, 0, + SUN6I_CSI_NAME, sdev); if (ret) { dev_err(&pdev->dev, "Cannot request csi IRQ\n"); return ret; @@ -924,12 +922,12 @@ static struct platform_driver sun6i_csi_platform_driver = { .probe = sun6i_csi_probe, .remove = sun6i_csi_remove, .driver = { - .name = MODULE_NAME, + .name = SUN6I_CSI_NAME, .of_match_table = of_match_ptr(sun6i_csi_of_match), }, }; module_platform_driver(sun6i_csi_platform_driver); -MODULE_DESCRIPTION("Allwinner V3s Camera Sensor Interface driver"); +MODULE_DESCRIPTION("Allwinner A31 Camera Sensor Interface driver"); MODULE_AUTHOR("Yong Deng "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index 3a38d107ae3f..e04f3c3fa27b 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -14,6 +14,9 @@ #include "sun6i_video.h" +#define SUN6I_CSI_NAME "sun6i-csi" +#define SUN6I_CSI_DESCRIPTION "Allwinner A31 CSI Device" + struct sun6i_csi; /** From patchwork Sat Feb 5 18:53:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540167 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1163C41535 for ; Sat, 5 Feb 2022 18:55:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381213AbiBESz0 (ORCPT ); Sat, 5 Feb 2022 13:55:26 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:60835 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381264AbiBESzO (ORCPT ); Sat, 5 Feb 2022 13:55:14 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 5413E240002; Sat, 5 Feb 2022 18:55:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087312; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+quzXmSLeW/9z2A42DWsC3K4J4WvAIG77KmdgY3FlMc=; b=l2E6lWMvXovhrV8hWwAJ9nrKTfPV85a2fG26zRZ1s/Rr4BuFmvT7/BDMrQmvOTMNlFjEH+ 2U8QbzkGsIoYOzVR/YEcJooneNpZb0PQwa4QeOcnM0VfPcQF5voVS60Xx6HCpFfq+bdJnN 7e/KPxnripLy/3TZT8hyZGXtl1alM07429u0vsz1u2+ag0q0f5qTS6GEJmFE1Eu6KYhZNk RW/kFUEaAUOzfUsfHgpOUZcwwPivHCdOyAZCdvYAhsKthXFGUMBrwEMwLSvY92zRDYaFNz 5TcE+JoT0MgunoW5G83mK/+rhn32K3sWkV7RnDBuYLwzqh+wE2fVUgI5w4Owxw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 19/66] media: sun6i-csi: Grab bus clock instead of passing it to regmap Date: Sat, 5 Feb 2022 19:53:42 +0100 Message-Id: <20220205185429.2278860-20-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Since the bus clock alone is not enough to get access to the registers, don't pass it to regmap and manage it instead just like the other clocks. Signed-off-by: Paul Kocialkowski --- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 10 ++++++++-- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 5fbaa1e99412..dc79f3c14336 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -827,13 +827,19 @@ static int sun6i_csi_resource_request(struct sun6i_csi_device *csi_dev, if (IS_ERR(io_base)) return PTR_ERR(io_base); - csi_dev->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", io_base, - &sun6i_csi_regmap_config); + csi_dev->regmap = devm_regmap_init_mmio(&pdev->dev, io_base, + &sun6i_csi_regmap_config); if (IS_ERR(csi_dev->regmap)) { dev_err(&pdev->dev, "Failed to init register map\n"); return PTR_ERR(csi_dev->regmap); } + csi_dev->clk_bus = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(csi_dev->clk_bus)) { + dev_err(&pdev->dev, "Unable to acquire bus clock\n"); + return PTR_ERR(csi_dev->clk_bus); + } + csi_dev->clk_mod = devm_clk_get(&pdev->dev, "mod"); if (IS_ERR(csi_dev->clk_mod)) { dev_err(&pdev->dev, "Unable to acquire csi clock\n"); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index e4e7ac6c869f..356661b413f8 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -51,6 +51,7 @@ struct sun6i_csi_device { struct sun6i_video video; struct regmap *regmap; + struct clk *clk_bus; struct clk *clk_mod; struct clk *clk_ram; struct reset_control *reset; From patchwork Sat Feb 5 18:53:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540165 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8F3BC433F5 for ; Sat, 5 Feb 2022 18:55:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381224AbiBESzi (ORCPT ); Sat, 5 Feb 2022 13:55:38 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:34435 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381298AbiBESzP (ORCPT ); Sat, 5 Feb 2022 13:55:15 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 0EA6A240005; Sat, 5 Feb 2022 18:55:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087314; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AeQJoNjubf2CY4+FRw73J3db9TTnuJgIzuiaD3WR1Fo=; b=OH8ZfBQrSGdrJpcAR1ZqzUV4CXso9sfRgEZRYGXHfn40a9iksBschAikqH1Ckpcqg8+weX TUaC09vfQkyz0oGerGw1cmLeMwEHhmwmfq+iHhv21UbfuOhIRE7k6w+k9a/He5Z/kAI5by u8vLIPWFvez080k9R4DHhYGYVNrmq8Q+syir39O+YTfGGWrw+0jeEuB+MyY0bs6Jtuoovi GIKHpuWS+cj9x6nRqsdHiWEW1nZoK1CDVzIvnZOoqGJgrz4/Q2lEWaX94d/7ko1joy8uZq 23irKs0CcGt7sGMpLpKPZ0slsvroHumCPsZJryTf8l/4RAykG025Ty/cCG4CFQ== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 20/66] media: sun6i-csi: Tidy up platform code Date: Sat, 5 Feb 2022 19:53:43 +0100 Message-Id: <20220205185429.2278860-21-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Various renames, variables lowering and other cosmetic changes in the platform-support code. No functional change intended. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 76 +++++++++++-------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index dc79f3c14336..8155e9560164 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -776,12 +776,11 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi_device *csi_dev) return ret; } -/* ----------------------------------------------------------------------------- - * Resources and IRQ - */ -static irqreturn_t sun6i_csi_isr(int irq, void *dev_id) +/* Platform */ + +static irqreturn_t sun6i_csi_isr(int irq, void *private) { - struct sun6i_csi_device *csi_dev = (struct sun6i_csi_device *)dev_id; + struct sun6i_csi_device *csi_dev = private; struct regmap *regmap = csi_dev->regmap; u32 status; @@ -816,79 +815,88 @@ static const struct regmap_config sun6i_csi_regmap_config = { .max_register = 0x9c, }; -static int sun6i_csi_resource_request(struct sun6i_csi_device *csi_dev, - struct platform_device *pdev) +static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev, + struct platform_device *platform_dev) { + struct device *dev = csi_dev->dev; void __iomem *io_base; int ret; int irq; - io_base = devm_platform_ioremap_resource(pdev, 0); + /* Registers */ + + io_base = devm_platform_ioremap_resource(platform_dev, 0); if (IS_ERR(io_base)) return PTR_ERR(io_base); - csi_dev->regmap = devm_regmap_init_mmio(&pdev->dev, io_base, + csi_dev->regmap = devm_regmap_init_mmio(dev, io_base, &sun6i_csi_regmap_config); if (IS_ERR(csi_dev->regmap)) { - dev_err(&pdev->dev, "Failed to init register map\n"); + dev_err(dev, "failed to init register map\n"); return PTR_ERR(csi_dev->regmap); } - csi_dev->clk_bus = devm_clk_get(&pdev->dev, "bus"); + /* Clocks */ + + csi_dev->clk_bus = devm_clk_get(dev, "bus"); if (IS_ERR(csi_dev->clk_bus)) { - dev_err(&pdev->dev, "Unable to acquire bus clock\n"); + dev_err(dev, "failed to acquire bus clock\n"); return PTR_ERR(csi_dev->clk_bus); } - csi_dev->clk_mod = devm_clk_get(&pdev->dev, "mod"); + csi_dev->clk_mod = devm_clk_get(dev, "mod"); if (IS_ERR(csi_dev->clk_mod)) { - dev_err(&pdev->dev, "Unable to acquire csi clock\n"); + dev_err(dev, "failed to acquire module clock\n"); return PTR_ERR(csi_dev->clk_mod); } - csi_dev->clk_ram = devm_clk_get(&pdev->dev, "ram"); + csi_dev->clk_ram = devm_clk_get(dev, "ram"); if (IS_ERR(csi_dev->clk_ram)) { - dev_err(&pdev->dev, "Unable to acquire dram-csi clock\n"); + dev_err(dev, "failed to acquire ram clock\n"); return PTR_ERR(csi_dev->clk_ram); } - csi_dev->reset = devm_reset_control_get_shared(&pdev->dev, NULL); + /* Reset */ + + csi_dev->reset = devm_reset_control_get_shared(dev, NULL); if (IS_ERR(csi_dev->reset)) { - dev_err(&pdev->dev, "Cannot get reset controller\n"); + dev_err(dev, "failed to acquire reset\n"); return PTR_ERR(csi_dev->reset); } - irq = platform_get_irq(pdev, 0); + /* Interrupt */ + + irq = platform_get_irq(platform_dev, 0); if (irq < 0) return -ENXIO; - ret = devm_request_irq(&pdev->dev, irq, sun6i_csi_isr, 0, - SUN6I_CSI_NAME, csi_dev); + ret = devm_request_irq(dev, irq, sun6i_csi_isr, 0, SUN6I_CSI_NAME, + csi_dev); if (ret) { - dev_err(&pdev->dev, "Cannot request csi IRQ\n"); + dev_err(dev, "failed to request interrupt\n"); return ret; } return 0; } -static int sun6i_csi_probe(struct platform_device *pdev) +static int sun6i_csi_probe(struct platform_device *platform_dev) { struct sun6i_csi_device *csi_dev; + struct device *dev = &platform_dev->dev; int ret; - csi_dev = devm_kzalloc(&pdev->dev, sizeof(*csi_dev), GFP_KERNEL); + csi_dev = devm_kzalloc(dev, sizeof(*csi_dev), GFP_KERNEL); if (!csi_dev) return -ENOMEM; - csi_dev->dev = &pdev->dev; + csi_dev->dev = &platform_dev->dev; + platform_set_drvdata(platform_dev, csi_dev); - ret = sun6i_csi_resource_request(csi_dev, pdev); + ret = sun6i_csi_resources_setup(csi_dev, platform_dev); if (ret) return ret; - platform_set_drvdata(pdev, csi_dev); - return sun6i_csi_v4l2_init(csi_dev); } @@ -909,16 +917,18 @@ static const struct of_device_id sun6i_csi_of_match[] = { { .compatible = "allwinner,sun50i-a64-csi", }, {}, }; + MODULE_DEVICE_TABLE(of, sun6i_csi_of_match); static struct platform_driver sun6i_csi_platform_driver = { - .probe = sun6i_csi_probe, - .remove = sun6i_csi_remove, - .driver = { - .name = SUN6I_CSI_NAME, - .of_match_table = of_match_ptr(sun6i_csi_of_match), + .probe = sun6i_csi_probe, + .remove = sun6i_csi_remove, + .driver = { + .name = SUN6I_CSI_NAME, + .of_match_table = of_match_ptr(sun6i_csi_of_match), }, }; + module_platform_driver(sun6i_csi_platform_driver); MODULE_DESCRIPTION("Allwinner A31 Camera Sensor Interface driver"); From patchwork Sat Feb 5 18:53:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540166 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8ECFBC35272 for ; Sat, 5 Feb 2022 18:55:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381316AbiBESz1 (ORCPT ); Sat, 5 Feb 2022 13:55:27 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:38919 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381359AbiBESzU (ORCPT ); Sat, 5 Feb 2022 13:55:20 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id ABDDD240010; Sat, 5 Feb 2022 18:55:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087316; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MOYYdmVl8pCa6416mpF3NEna8HLFfUDBAwcaSrt2+2M=; b=VxQtLVgU7ACEeiDt3hx/cbGZ1AzOweLSU9e+y4s2LlMlq8/5opiUlHwE0nSMgNYvcnbC7u QFFsVOxQFb5I4Q8fTCjDKHpWsa1vkE0SnTO0SsApqbLF1/GmuvN6ekjO2Vjq+phdUuB4rc McgSwydexepQqEaYPYE2cibSrPb83lu6grZJ3lC3HE8PaCCy2PVyrhWqzAAUVorqJFRx5a 48wNZ5W+mdWRTfKdNS2VqQLVA/MLD34FCBB9VQKkT5jbBu7eHIEiU7UWnscsDa1msBLryN c1f8Cv+eEoUvHmE1Sp91XN+qPKBSkF+GpanFtUKoAW4m6T5C2DhKvL5TmZCMPA== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 21/66] media: sun6i-csi: Always set exclusive module clock rate Date: Sat, 5 Feb 2022 19:53:44 +0100 Message-Id: <20220205185429.2278860-22-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In some situations the default rate of the module clock is not the required one for operation (for example when reconfiguring the clock tree to use a different parent). As a result, always set the correct rate for the clock (and take care of cleanup). Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 54 ++++++++++++++----- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 8155e9560164..2355088fdc37 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -154,9 +154,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable) regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, 0); clk_disable_unprepare(csi_dev->clk_ram); - if (of_device_is_compatible(dev->of_node, - "allwinner,sun50i-a64-csi")) - clk_rate_exclusive_put(csi_dev->clk_mod); clk_disable_unprepare(csi_dev->clk_mod); reset_control_assert(csi_dev->reset); return 0; @@ -168,9 +165,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable) return ret; } - if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi")) - clk_set_rate_exclusive(csi_dev->clk_mod, 300000000); - ret = clk_prepare_enable(csi_dev->clk_ram); if (ret) { dev_err(csi_dev->dev, "Enable clk_dram_csi clk err %d\n", ret); @@ -190,8 +184,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable) clk_ram_disable: clk_disable_unprepare(csi_dev->clk_ram); clk_mod_disable: - if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi")) - clk_rate_exclusive_put(csi_dev->clk_mod); clk_disable_unprepare(csi_dev->clk_mod); return ret; } @@ -819,6 +811,7 @@ static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev, struct platform_device *platform_dev) { struct device *dev = csi_dev->dev; + unsigned long clk_mod_rate; void __iomem *io_base; int ret; int irq; @@ -856,28 +849,53 @@ static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev, return PTR_ERR(csi_dev->clk_ram); } + if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi")) + clk_mod_rate = 300000000; + else + clk_mod_rate = 297000000; + + ret = clk_set_rate_exclusive(csi_dev->clk_mod, clk_mod_rate); + if (ret) { + dev_err(dev, "failed to set mod clock rate\n"); + return ret; + } + /* Reset */ csi_dev->reset = devm_reset_control_get_shared(dev, NULL); if (IS_ERR(csi_dev->reset)) { dev_err(dev, "failed to acquire reset\n"); - return PTR_ERR(csi_dev->reset); + ret = PTR_ERR(csi_dev->reset); + goto error_clk_rate_exclusive; } /* Interrupt */ irq = platform_get_irq(platform_dev, 0); - if (irq < 0) - return -ENXIO; + if (irq < 0) { + dev_err(dev, "failed to get interrupt\n"); + ret = -ENXIO; + goto error_clk_rate_exclusive; + } ret = devm_request_irq(dev, irq, sun6i_csi_isr, 0, SUN6I_CSI_NAME, csi_dev); if (ret) { dev_err(dev, "failed to request interrupt\n"); - return ret; + goto error_clk_rate_exclusive; } return 0; + +error_clk_rate_exclusive: + clk_rate_exclusive_put(csi_dev->clk_mod); + + return ret; +} + +static void sun6i_csi_resources_cleanup(struct sun6i_csi_device *csi_dev) +{ + clk_rate_exclusive_put(csi_dev->clk_mod); } static int sun6i_csi_probe(struct platform_device *platform_dev) @@ -897,7 +915,16 @@ static int sun6i_csi_probe(struct platform_device *platform_dev) if (ret) return ret; - return sun6i_csi_v4l2_init(csi_dev); + ret = sun6i_csi_v4l2_init(csi_dev); + if (ret) + goto error_resources; + + return 0; + +error_resources: + sun6i_csi_resources_cleanup(csi_dev); + + return ret; } static int sun6i_csi_remove(struct platform_device *pdev) @@ -905,6 +932,7 @@ static int sun6i_csi_remove(struct platform_device *pdev) struct sun6i_csi_device *csi_dev = platform_get_drvdata(pdev); sun6i_csi_v4l2_cleanup(csi_dev); + sun6i_csi_resources_cleanup(csi_dev); return 0; } From patchwork Sat Feb 5 18:53:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540164 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 885AEC433F5 for ; Sat, 5 Feb 2022 18:55:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381437AbiBESzn (ORCPT ); Sat, 5 Feb 2022 13:55:43 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:60835 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381154AbiBESzY (ORCPT ); Sat, 5 Feb 2022 13:55:24 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 8ED6724000C; Sat, 5 Feb 2022 18:55:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087323; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=keKy5EHW+RNCxVUArqLdVQQAYfW9/70q2yReTVOCE1A=; b=QMd0wCGtmHtepGaxogFllgVoC7dg8Fh2otoYcBXZJSEl1jUT6jTpoDGMzqjGsIPizUnA5P eBKUGR7RwnpGAfJPq1lZSrBlw38lDUgenihdFdjdxGxbjSyi/Ku3hkjCrhwrsLOrR5Xwdw f54l6uzOY9PBB5yDI6cP9BRtPI8d38mMxWCuEfxTEKu7aRf9r7cCxpW8O3MIGJ8Fw8Wa4d JQzwZmcTmrhQVZ1Vc5L93GrZh2c7LmBNIaEAknI/V37TQOyqTGOVXDfcWjQy12RfArqnKW BdSi4s6K3SW5lTVkcGK2qefV29o2J56nkWW1XfEBk/xzoZ1em3B4TqVIYZ91Xw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 25/66] media: sun6i-csi: Pass and store csi device directly in video code Date: Sat, 5 Feb 2022 19:53:48 +0100 Message-Id: <20220205185429.2278860-26-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The video structure is part of the main csi device structure, so pass pointers to that top-level structure directly. This makes it easier to navigate and access other elements. No functional change intended. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 8 +- .../platform/sunxi/sun6i-csi/sun6i_video.c | 91 ++++++++++--------- .../platform/sunxi/sun6i-csi/sun6i_video.h | 9 +- 3 files changed, 57 insertions(+), 51 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 9ff02f3d8037..688288afae68 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -708,7 +708,7 @@ static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) /* Video */ - ret = sun6i_video_setup(&csi_dev->video, csi_dev); + ret = sun6i_video_setup(csi_dev); if (ret) goto error_v4l2_device; @@ -737,7 +737,7 @@ static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) v4l2_async_nf_cleanup(notifier); error_video: - sun6i_video_cleanup(&csi_dev->video); + sun6i_video_cleanup(csi_dev); error_v4l2_device: v4l2_device_unregister(&v4l2->v4l2_dev); @@ -758,7 +758,7 @@ static void sun6i_csi_v4l2_cleanup(struct sun6i_csi_device *csi_dev) media_device_unregister(&v4l2->media_dev); v4l2_async_nf_unregister(&v4l2->notifier); v4l2_async_nf_cleanup(&v4l2->notifier); - sun6i_video_cleanup(&csi_dev->video); + sun6i_video_cleanup(csi_dev); v4l2_device_unregister(&v4l2->v4l2_dev); v4l2_ctrl_handler_free(&v4l2->ctrl_handler); media_device_cleanup(&v4l2->media_dev); @@ -789,7 +789,7 @@ static irqreturn_t sun6i_csi_isr(int irq, void *private) } if (status & CSI_CH_INT_STA_FD_PD) - sun6i_video_frame_done(&csi_dev->video); + sun6i_video_frame_done(csi_dev); regmap_write(regmap, CSI_CH_INT_STA_REG, status); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c index 427b23184a15..178dddb0eaf1 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c @@ -100,7 +100,8 @@ static int sun6i_video_queue_setup(struct vb2_queue *queue, unsigned int sizes[], struct device *alloc_devs[]) { - struct sun6i_video *video = vb2_get_drv_priv(queue); + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); + struct sun6i_video *video = &csi_dev->video; unsigned int size = video->format.fmt.pix.sizeimage; if (*planes_count) @@ -114,8 +115,8 @@ static int sun6i_video_queue_setup(struct vb2_queue *queue, static int sun6i_video_buffer_prepare(struct vb2_buffer *buffer) { - struct sun6i_video *video = vb2_get_drv_priv(buffer->vb2_queue); - struct sun6i_csi_device *csi_dev = video->csi_dev; + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); + struct sun6i_video *video = &csi_dev->video; struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); struct sun6i_csi_buffer *csi_buffer = @@ -138,7 +139,8 @@ static int sun6i_video_buffer_prepare(struct vb2_buffer *buffer) static void sun6i_video_buffer_queue(struct vb2_buffer *buffer) { - struct sun6i_video *video = vb2_get_drv_priv(buffer->vb2_queue); + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); + struct sun6i_video *video = &csi_dev->video; struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); struct sun6i_csi_buffer *csi_buffer = container_of(v4l2_buffer, struct sun6i_csi_buffer, v4l2_buffer); @@ -153,7 +155,8 @@ static void sun6i_video_buffer_queue(struct vb2_buffer *buffer) static int sun6i_video_start_streaming(struct vb2_queue *queue, unsigned int count) { - struct sun6i_video *video = vb2_get_drv_priv(queue); + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); + struct sun6i_video *video = &csi_dev->video; struct video_device *video_dev = &video->video_dev; struct sun6i_csi_buffer *buf; struct sun6i_csi_buffer *next_buf; @@ -185,7 +188,7 @@ static int sun6i_video_start_streaming(struct vb2_queue *queue, config.width = video->format.fmt.pix.width; config.height = video->format.fmt.pix.height; - ret = sun6i_csi_update_config(video->csi_dev, &config); + ret = sun6i_csi_update_config(csi_dev, &config); if (ret < 0) goto error_media_pipeline; @@ -194,9 +197,9 @@ static int sun6i_video_start_streaming(struct vb2_queue *queue, buf = list_first_entry(&video->dma_queue, struct sun6i_csi_buffer, list); buf->queued_to_csi = true; - sun6i_csi_update_buf_addr(video->csi_dev, buf->dma_addr); + sun6i_csi_update_buf_addr(csi_dev, buf->dma_addr); - sun6i_csi_set_stream(video->csi_dev, true); + sun6i_csi_set_stream(csi_dev, true); /* * CSI will lookup the next dma buffer for next frame before the @@ -217,7 +220,7 @@ static int sun6i_video_start_streaming(struct vb2_queue *queue, */ next_buf = list_next_entry(buf, list); next_buf->queued_to_csi = true; - sun6i_csi_update_buf_addr(video->csi_dev, next_buf->dma_addr); + sun6i_csi_update_buf_addr(csi_dev, next_buf->dma_addr); spin_unlock_irqrestore(&video->dma_queue_lock, flags); @@ -228,7 +231,7 @@ static int sun6i_video_start_streaming(struct vb2_queue *queue, return 0; error_stream: - sun6i_csi_set_stream(video->csi_dev, false); + sun6i_csi_set_stream(csi_dev, false); error_media_pipeline: media_pipeline_stop(&video_dev->entity); @@ -246,7 +249,8 @@ static int sun6i_video_start_streaming(struct vb2_queue *queue, static void sun6i_video_stop_streaming(struct vb2_queue *queue) { - struct sun6i_video *video = vb2_get_drv_priv(queue); + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); + struct sun6i_video *video = &csi_dev->video; struct v4l2_subdev *subdev; unsigned long flags; struct sun6i_csi_buffer *buf; @@ -255,7 +259,7 @@ static void sun6i_video_stop_streaming(struct vb2_queue *queue) if (subdev) v4l2_subdev_call(subdev, video, s_stream, 0); - sun6i_csi_set_stream(video->csi_dev, false); + sun6i_csi_set_stream(csi_dev, false); media_pipeline_stop(&video->video_dev.entity); @@ -267,8 +271,9 @@ static void sun6i_video_stop_streaming(struct vb2_queue *queue) spin_unlock_irqrestore(&video->dma_queue_lock, flags); } -void sun6i_video_frame_done(struct sun6i_video *video) +void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev) { + struct sun6i_video *video = &csi_dev->video; struct sun6i_csi_buffer *buf; struct sun6i_csi_buffer *next_buf; struct vb2_v4l2_buffer *v4l2_buffer; @@ -278,7 +283,7 @@ void sun6i_video_frame_done(struct sun6i_video *video) buf = list_first_entry(&video->dma_queue, struct sun6i_csi_buffer, list); if (list_is_last(&buf->list, &video->dma_queue)) { - dev_dbg(video->csi_dev->dev, "Frame dropped!\n"); + dev_dbg(csi_dev->dev, "Frame dropped!\n"); goto complete; } @@ -290,8 +295,8 @@ void sun6i_video_frame_done(struct sun6i_video *video) */ if (!next_buf->queued_to_csi) { next_buf->queued_to_csi = true; - sun6i_csi_update_buf_addr(video->csi_dev, next_buf->dma_addr); - dev_dbg(video->csi_dev->dev, "Frame dropped!\n"); + sun6i_csi_update_buf_addr(csi_dev, next_buf->dma_addr); + dev_dbg(csi_dev->dev, "Frame dropped!\n"); goto complete; } @@ -305,9 +310,9 @@ void sun6i_video_frame_done(struct sun6i_video *video) if (!list_is_last(&next_buf->list, &video->dma_queue)) { next_buf = list_next_entry(next_buf, list); next_buf->queued_to_csi = true; - sun6i_csi_update_buf_addr(video->csi_dev, next_buf->dma_addr); + sun6i_csi_update_buf_addr(csi_dev, next_buf->dma_addr); } else { - dev_dbg(video->csi_dev->dev, "Next frame will be dropped!\n"); + dev_dbg(csi_dev->dev, "Next frame will be dropped!\n"); } complete: @@ -330,9 +335,8 @@ static const struct vb2_ops sun6i_video_queue_ops = { static int sun6i_video_querycap(struct file *file, void *private, struct v4l2_capability *capability) { - struct sun6i_video *video = video_drvdata(file); - struct sun6i_csi_device *csi_dev = video->csi_dev; - struct video_device *video_dev = &video->video_dev; + struct sun6i_csi_device *csi_dev = video_drvdata(file); + struct video_device *video_dev = &csi_dev->video.video_dev; strscpy(capability->driver, SUN6I_CSI_NAME, sizeof(capability->driver)); strscpy(capability->card, video_dev->name, sizeof(capability->card)); @@ -358,7 +362,8 @@ static int sun6i_video_enum_fmt(struct file *file, void *private, static int sun6i_video_g_fmt(struct file *file, void *private, struct v4l2_format *format) { - struct sun6i_video *video = video_drvdata(file); + struct sun6i_csi_device *csi_dev = video_drvdata(file); + struct sun6i_video *video = &csi_dev->video; *format = video->format; @@ -409,7 +414,8 @@ static int sun6i_video_format_set(struct sun6i_video *video, static int sun6i_video_s_fmt(struct file *file, void *private, struct v4l2_format *format) { - struct sun6i_video *video = video_drvdata(file); + struct sun6i_csi_device *csi_dev = video_drvdata(file); + struct sun6i_video *video = &csi_dev->video; if (vb2_is_busy(&video->queue)) return -EBUSY; @@ -420,7 +426,8 @@ static int sun6i_video_s_fmt(struct file *file, void *private, static int sun6i_video_try_fmt(struct file *file, void *private, struct v4l2_format *format) { - struct sun6i_video *video = video_drvdata(file); + struct sun6i_csi_device *csi_dev = video_drvdata(file); + struct sun6i_video *video = &csi_dev->video; return sun6i_video_format_try(video, format); } @@ -485,7 +492,8 @@ static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { static int sun6i_video_open(struct file *file) { - struct sun6i_video *video = video_drvdata(file); + struct sun6i_csi_device *csi_dev = video_drvdata(file); + struct sun6i_video *video = &csi_dev->video; int ret = 0; if (mutex_lock_interruptible(&video->lock)) @@ -501,7 +509,7 @@ static int sun6i_video_open(struct file *file) /* Power on at first open. */ if (v4l2_fh_is_singular_file(file)) { - ret = sun6i_csi_set_power(video->csi_dev, true); + ret = sun6i_csi_set_power(csi_dev, true); if (ret < 0) goto error_v4l2_fh; } @@ -521,7 +529,8 @@ static int sun6i_video_open(struct file *file) static int sun6i_video_close(struct file *file) { - struct sun6i_video *video = video_drvdata(file); + struct sun6i_csi_device *csi_dev = video_drvdata(file); + struct sun6i_video *video = &csi_dev->video; bool last_close; mutex_lock(&video->lock); @@ -533,7 +542,7 @@ static int sun6i_video_close(struct file *file) /* Power off at last close. */ if (last_close) - sun6i_csi_set_power(video->csi_dev, false); + sun6i_csi_set_power(csi_dev, false); mutex_unlock(&video->lock); @@ -570,15 +579,16 @@ static int sun6i_video_link_validate(struct media_link *link) { struct video_device *vdev = container_of(link->sink->entity, struct video_device, entity); - struct sun6i_video *video = video_get_drvdata(vdev); + struct sun6i_csi_device *csi_dev = video_get_drvdata(vdev); + struct sun6i_video *video = &csi_dev->video; struct v4l2_subdev_format source_fmt; int ret; video->mbus_code = 0; if (!media_entity_remote_pad(link->sink->entity->pads)) { - dev_info(video->csi_dev->dev, - "video node %s pad not connected\n", vdev->name); + dev_info(csi_dev->dev, "video node %s pad not connected\n", + vdev->name); return -ENOLINK; } @@ -586,10 +596,10 @@ static int sun6i_video_link_validate(struct media_link *link) if (ret < 0) return ret; - if (!sun6i_csi_is_format_supported(video->csi_dev, + if (!sun6i_csi_is_format_supported(csi_dev, video->format.fmt.pix.pixelformat, source_fmt.format.code)) { - dev_err(video->csi_dev->dev, + dev_err(csi_dev->dev, "Unsupported pixformat: 0x%x with mbus code: 0x%x!\n", video->format.fmt.pix.pixelformat, source_fmt.format.code); @@ -598,7 +608,7 @@ static int sun6i_video_link_validate(struct media_link *link) if (source_fmt.format.width != video->format.fmt.pix.width || source_fmt.format.height != video->format.fmt.pix.height) { - dev_err(video->csi_dev->dev, + dev_err(csi_dev->dev, "Wrong width or height %ux%u (%ux%u expected)\n", video->format.fmt.pix.width, video->format.fmt.pix.height, source_fmt.format.width, source_fmt.format.height); @@ -616,9 +626,9 @@ static const struct media_entity_operations sun6i_video_media_ops = { /* Video */ -int sun6i_video_setup(struct sun6i_video *video, - struct sun6i_csi_device *csi_dev) +int sun6i_video_setup(struct sun6i_csi_device *csi_dev) { + struct sun6i_video *video = &csi_dev->video; struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; struct video_device *video_dev = &video->video_dev; struct vb2_queue *queue = &video->queue; @@ -627,8 +637,6 @@ int sun6i_video_setup(struct sun6i_video *video, struct v4l2_pix_format *pix_format = &format.fmt.pix; int ret; - video->csi_dev = csi_dev; - /* Media Entity */ video_dev->entity.ops = &sun6i_video_media_ops; @@ -660,7 +668,7 @@ int sun6i_video_setup(struct sun6i_video *video, queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; queue->lock = &video->lock; queue->dev = csi_dev->dev; - queue->drv_priv = video; + queue->drv_priv = csi_dev; /* Make sure non-dropped frame. */ queue->min_buffers_needed = 3; @@ -693,7 +701,7 @@ int sun6i_video_setup(struct sun6i_video *video, video_dev->queue = queue; video_dev->lock = &video->lock; - video_set_drvdata(video_dev, video); + video_set_drvdata(video_dev, csi_dev); ret = video_register_device(video_dev, VFL_TYPE_VIDEO, -1); if (ret < 0) { @@ -715,8 +723,9 @@ int sun6i_video_setup(struct sun6i_video *video, return ret; } -void sun6i_video_cleanup(struct sun6i_video *video) +void sun6i_video_cleanup(struct sun6i_csi_device *csi_dev) { + struct sun6i_video *video = &csi_dev->video; struct video_device *video_dev = &video->video_dev; vb2_video_unregister_device(video_dev); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h index 7864f062d05b..a917d2da6deb 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h @@ -14,8 +14,6 @@ struct sun6i_csi_device; struct sun6i_video { - struct sun6i_csi_device *csi_dev; - struct video_device video_dev; struct vb2_queue queue; struct mutex lock; /* Queue lock. */ @@ -29,10 +27,9 @@ struct sun6i_video { unsigned int sequence; }; -int sun6i_video_setup(struct sun6i_video *video, - struct sun6i_csi_device *csi_dev); -void sun6i_video_cleanup(struct sun6i_video *video); +int sun6i_video_setup(struct sun6i_csi_device *csi_dev); +void sun6i_video_cleanup(struct sun6i_csi_device *csi_dev); -void sun6i_video_frame_done(struct sun6i_video *video); +void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev); #endif /* __SUN6I_VIDEO_H__ */ From patchwork Sat Feb 5 18:53:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DDFDDC4332F for ; Sat, 5 Feb 2022 18:55:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381241AbiBESz6 (ORCPT ); Sat, 5 Feb 2022 13:55:58 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:39641 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381189AbiBESz0 (ORCPT ); Sat, 5 Feb 2022 13:55:26 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 46E76240002; Sat, 5 Feb 2022 18:55:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087324; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GwbC5gn4h2V2gFK4wGghF7MDfEkNG/IYlc1iEgQerj0=; b=L1JXL3Qty8YbjkBCLhJVJAw9Iqd4UQldBGCTyzEEJkgRDRu2AsUoq3UeW7TuMfbaxUNkwa m7infW20DxJQin+WbsuHe6ut42BABmKqYtmwLcdl+VBCTcFFktcTdJkK6v2rPxSxoBezmP pydAO11+Uh9weVgn9rbYVfZv2SeAv8i0y+pifvy7y8ZqW0/WAqPVzNd6F/RmlyN1lE5E2w bHH8ptkwgdHAqjiat3CtNSiwIVmPcBVI0DJFqBpSVVhvj8CZa4h/q5EuF/zkHeEiy3oQQw uIhGXLGdmytN6Udakwg1xk1B1D7pX6ghmO2Jpuv8BN+St7Tx755v3iKDpTnVzA== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 26/66] media: sun6i-csi: Register the media device after creation Date: Sat, 5 Feb 2022 19:53:49 +0100 Message-Id: <20220205185429.2278860-27-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org There is no particular need to register the media device in the subdev notify complete callback. Register it in the v4l2 code instead where it's more in-context. Signed-off-by: Paul Kocialkowski --- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 688288afae68..6f04f86504bf 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -638,7 +638,7 @@ static int sun6i_subdev_notify_complete(struct v4l2_async_notifier *notifier) if (ret < 0) return ret; - return media_device_register(&v4l2->media_dev); + return 0; } static const struct v4l2_async_notifier_operations sun6i_csi_async_ops = { @@ -687,6 +687,12 @@ static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) media_device_init(media_dev); + ret = media_device_register(media_dev); + if (ret) { + dev_err(dev, "failed to register media device: %d\n", ret); + goto error_media; + } + /* V4L2 Control Handler */ ret = v4l2_ctrl_handler_init(&v4l2->ctrl_handler, 0); @@ -746,6 +752,7 @@ static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) v4l2_ctrl_handler_free(&v4l2->ctrl_handler); error_media: + media_device_unregister(media_dev); media_device_cleanup(media_dev); return ret; From patchwork Sat Feb 5 18:53:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540160 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6ED12C433EF for ; Sat, 5 Feb 2022 18:56:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381705AbiBES4t (ORCPT ); Sat, 5 Feb 2022 13:56:49 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:52993 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381385AbiBESzb (ORCPT ); Sat, 5 Feb 2022 13:55:31 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id D4A28240007; Sat, 5 Feb 2022 18:55:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087326; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F9Du3GfYn3UOCDAPoYJILY6rh/Nnu6H6h0CX6Ze373Y=; b=IURtoySrYYi5eK3hSwO5N8qOIcyNqY4Cy9o1fdR/WiyFPmgHCLyFq8wKoxTKhGL6xsANsx xm1cbTBTPPQ6TXxGGaNrisAfka3YZIWme38mrdOqEcHmORcvVR602flt13CeUP+E6ncOTU ji5B6sD87d7B0xCq6ZGXVmVfJatT1cbVioyO4T5H/cF8/m+xrQVnGzpl3uHd+uculImZ8c f8OMnokOVHCeWE9k3ivHHTO0Xy1Ga42ZNdj7XXSAt44wSnOWzVX7RJohKDRdvrgWtabjIU YyZSMIlFT/91uMfBZMUtDDCY2GvcrqwbnwEF8257hD+CgINU6+eVuGTw+SrHVQ== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 27/66] media: sun6i-csi: Add media ops with link notify callback Date: Sat, 5 Feb 2022 19:53:50 +0100 Message-Id: <20220205185429.2278860-28-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In order to keep the power use count fields balanced when link changes happen between v4l2_pipeline_pm_get/set calls (in open/close), the link_notify media operation callback needs to be registered. Signed-off-by: Paul Kocialkowski --- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 6f04f86504bf..c8fe31cc38b5 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "sun6i_csi.h" #include "sun6i_csi_reg.h" @@ -574,6 +575,12 @@ void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable) CSI_CAP_CH0_VCAP_ON); } +/* Media */ + +static const struct media_device_ops sun6i_csi_media_ops = { + .link_notify = v4l2_pipeline_link_notify, +}; + /* V4L2 */ static int sun6i_csi_link_entity(struct sun6i_csi_device *csi_dev, @@ -683,6 +690,7 @@ static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) snprintf(media_dev->bus_info, sizeof(media_dev->bus_info), "platform:%s", dev_name(dev)); media_dev->hw_revision = 0; + media_dev->ops = &sun6i_csi_media_ops; media_dev->dev = dev; media_device_init(media_dev); From patchwork Sat Feb 5 18:53:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540159 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 389FAC433FE for ; Sat, 5 Feb 2022 18:56:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381410AbiBES44 (ORCPT ); Sat, 5 Feb 2022 13:56:56 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:37545 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381401AbiBESze (ORCPT ); Sat, 5 Feb 2022 13:55:34 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id A017324000E; Sat, 5 Feb 2022 18:55:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087333; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=x3NkFOlJ8d1xlWQdDn/IrtQNSdoZAyxJHgObyQS5x+c=; b=Sa2NgZo+jIGRafH87M276HyboTxPCFydZ2+8cWEV5NmbMUpMa/jtJXYCqkE+aUioeMHSt/ o7cPnTKjcuDLCsfDNlRInji78IYPbkajRZxV6xL3t1qlI1Hi0lv5DrhsbvkewdIvxUeNEw VG3AeKU1ICkBr8uVPqOiSlaGLflC5HikCNykCCArl6wvRFc1SUeye5+cOmRE43ofSSXvCZ yTZggWPY4ubdVhax+0CtE5c2psQcz82aKCsHnqXjktR92RGYrvy8ZlyPTdJPW14twR1p3N 8d8YGhh6RTADlRtblow/E2mHEEuFsowaLPQtkgYr9dIqx5PXRePTWls4TFqwvg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 31/66] media: sun6i-csi: Rename sun6i_video to sun6i_csi_capture Date: Sat, 5 Feb 2022 19:53:54 +0100 Message-Id: <20220205185429.2278860-32-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In an effort to distinguish between the core csi engine (to be represented as the bridge) and the dma engine (the capture video device), rename the video component to capture, with the appropriate prefix. No functional change intended. Signed-off-by: Paul Kocialkowski --- .../media/platform/sunxi/sun6i-csi/Makefile | 2 +- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 6 +- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 4 +- .../{sun6i_video.c => sun6i_csi_capture.c} | 344 +++++++++--------- .../{sun6i_video.h => sun6i_csi_capture.h} | 14 +- 5 files changed, 187 insertions(+), 183 deletions(-) rename drivers/media/platform/sunxi/sun6i-csi/{sun6i_video.c => sun6i_csi_capture.c} (58%) rename drivers/media/platform/sunxi/sun6i-csi/{sun6i_video.h => sun6i_csi_capture.h} (64%) diff --git a/drivers/media/platform/sunxi/sun6i-csi/Makefile b/drivers/media/platform/sunxi/sun6i-csi/Makefile index 7a699580a641..87e7a715140a 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/Makefile +++ b/drivers/media/platform/sunxi/sun6i-csi/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -sun6i-csi-y += sun6i_video.o sun6i_csi.o sun6i_csi_bridge.o +sun6i-csi-y += sun6i_csi.o sun6i_csi_bridge.o sun6i_csi_capture.o obj-$(CONFIG_VIDEO_SUN6I_CSI) += sun6i-csi.o diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index a1847ae3e88e..834fc8c17189 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -684,7 +684,7 @@ static irqreturn_t sun6i_csi_isr(int irq, void *private) } if (status & CSI_CH_INT_STA_FD_PD) - sun6i_video_frame_done(csi_dev); + sun6i_csi_capture_frame_done(csi_dev); regmap_write(regmap, CSI_CH_INT_STA_REG, status); @@ -879,7 +879,7 @@ static int sun6i_csi_probe(struct platform_device *platform_dev) if (ret) goto error_v4l2; - ret = sun6i_video_setup(csi_dev); + ret = sun6i_csi_capture_setup(csi_dev); if (ret) goto error_bridge; @@ -901,7 +901,7 @@ static int sun6i_csi_remove(struct platform_device *pdev) { struct sun6i_csi_device *csi_dev = platform_get_drvdata(pdev); - sun6i_video_cleanup(csi_dev); + sun6i_csi_capture_cleanup(csi_dev); sun6i_csi_bridge_cleanup(csi_dev); sun6i_csi_v4l2_cleanup(csi_dev); sun6i_csi_resources_cleanup(csi_dev); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index 576c7f10289e..a53c98507f37 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -14,7 +14,7 @@ #include #include "sun6i_csi_bridge.h" -#include "sun6i_video.h" +#include "sun6i_csi_capture.h" #define SUN6I_CSI_NAME "sun6i-csi" #define SUN6I_CSI_DESCRIPTION "Allwinner A31 CSI Device" @@ -59,7 +59,7 @@ struct sun6i_csi_device { struct sun6i_csi_config config; struct sun6i_csi_v4l2 v4l2; struct sun6i_csi_bridge bridge; - struct sun6i_video video; + struct sun6i_csi_capture capture; struct regmap *regmap; struct clk *clk_bus; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c similarity index 58% rename from drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c rename to drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index fa5bf3697ace..1ebc2d825838 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -15,7 +15,7 @@ #include #include "sun6i_csi.h" -#include "sun6i_video.h" +#include "sun6i_csi_capture.h" /* This is got from BSP sources. */ #define MIN_WIDTH (32) @@ -26,11 +26,11 @@ /* Helpers */ static struct v4l2_subdev * -sun6i_video_remote_subdev(struct sun6i_video *video, u32 *pad) +sun6i_csi_capture_remote_subdev(struct sun6i_csi_capture *capture, u32 *pad) { struct media_pad *remote; - remote = media_entity_remote_pad(&video->pad); + remote = media_entity_remote_pad(&capture->pad); if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) return NULL; @@ -43,7 +43,7 @@ sun6i_video_remote_subdev(struct sun6i_video *video, u32 *pad) /* Format */ -static const u32 sun6i_video_formats[] = { +static const u32 sun6i_csi_capture_formats[] = { V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SGBRG8, V4L2_PIX_FMT_SGRBG8, @@ -73,51 +73,52 @@ static const u32 sun6i_video_formats[] = { V4L2_PIX_FMT_JPEG, }; -static bool sun6i_video_format_check(u32 format) +static bool sun6i_csi_capture_format_check(u32 format) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(sun6i_video_formats); i++) - if (sun6i_video_formats[i] == format) + for (i = 0; i < ARRAY_SIZE(sun6i_csi_capture_formats); i++) + if (sun6i_csi_capture_formats[i] == format) return true; return false; } -/* Video */ +/* Capture */ -static void sun6i_video_buffer_configure(struct sun6i_csi_device *csi_dev, - struct sun6i_csi_buffer *csi_buffer) +static void +sun6i_csi_capture_buffer_configure(struct sun6i_csi_device *csi_dev, + struct sun6i_csi_buffer *csi_buffer) { csi_buffer->queued_to_csi = true; sun6i_csi_update_buf_addr(csi_dev, csi_buffer->dma_addr); } -static void sun6i_video_configure(struct sun6i_csi_device *csi_dev) +static void sun6i_csi_capture_configure(struct sun6i_csi_device *csi_dev) { - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; struct sun6i_csi_config config = { 0 }; - config.pixelformat = video->format.fmt.pix.pixelformat; - config.code = video->mbus_code; - config.field = video->format.fmt.pix.field; - config.width = video->format.fmt.pix.width; - config.height = video->format.fmt.pix.height; + config.pixelformat = capture->format.fmt.pix.pixelformat; + config.code = capture->mbus_code; + config.field = capture->format.fmt.pix.field; + config.width = capture->format.fmt.pix.width; + config.height = capture->format.fmt.pix.height; sun6i_csi_update_config(csi_dev, &config); } /* Queue */ -static int sun6i_video_queue_setup(struct vb2_queue *queue, - unsigned int *buffers_count, - unsigned int *planes_count, - unsigned int sizes[], - struct device *alloc_devs[]) +static int sun6i_csi_capture_queue_setup(struct vb2_queue *queue, + unsigned int *buffers_count, + unsigned int *planes_count, + unsigned int sizes[], + struct device *alloc_devs[]) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); - struct sun6i_video *video = &csi_dev->video; - unsigned int size = video->format.fmt.pix.sizeimage; + struct sun6i_csi_capture *capture = &csi_dev->capture; + unsigned int size = capture->format.fmt.pix.sizeimage; if (*planes_count) return sizes[0] < size ? -EINVAL : 0; @@ -128,15 +129,15 @@ static int sun6i_video_queue_setup(struct vb2_queue *queue, return 0; } -static int sun6i_video_buffer_prepare(struct vb2_buffer *buffer) +static int sun6i_csi_capture_buffer_prepare(struct vb2_buffer *buffer) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); struct sun6i_csi_buffer *csi_buffer = container_of(v4l2_buffer, struct sun6i_csi_buffer, v4l2_buffer); - unsigned long size = video->format.fmt.pix.sizeimage; + unsigned long size = capture->format.fmt.pix.sizeimage; if (vb2_plane_size(buffer, 0) < size) { v4l2_err(v4l2_dev, "buffer too small (%lu < %lu)\n", @@ -147,62 +148,62 @@ static int sun6i_video_buffer_prepare(struct vb2_buffer *buffer) vb2_set_plane_payload(buffer, 0, size); csi_buffer->dma_addr = vb2_dma_contig_plane_dma_addr(buffer, 0); - v4l2_buffer->field = video->format.fmt.pix.field; + v4l2_buffer->field = capture->format.fmt.pix.field; return 0; } -static void sun6i_video_buffer_queue(struct vb2_buffer *buffer) +static void sun6i_csi_capture_buffer_queue(struct vb2_buffer *buffer) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); struct sun6i_csi_buffer *csi_buffer = container_of(v4l2_buffer, struct sun6i_csi_buffer, v4l2_buffer); unsigned long flags; - spin_lock_irqsave(&video->dma_queue_lock, flags); + spin_lock_irqsave(&capture->dma_queue_lock, flags); csi_buffer->queued_to_csi = false; - list_add_tail(&csi_buffer->list, &video->dma_queue); - spin_unlock_irqrestore(&video->dma_queue_lock, flags); + list_add_tail(&csi_buffer->list, &capture->dma_queue); + spin_unlock_irqrestore(&capture->dma_queue_lock, flags); } -static int sun6i_video_start_streaming(struct vb2_queue *queue, - unsigned int count) +static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, + unsigned int count) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); - struct sun6i_video *video = &csi_dev->video; - struct video_device *video_dev = &video->video_dev; + struct sun6i_csi_capture *capture = &csi_dev->capture; + struct video_device *video_dev = &capture->video_dev; struct sun6i_csi_buffer *buf; struct sun6i_csi_buffer *next_buf; struct v4l2_subdev *subdev; unsigned long flags; int ret; - video->sequence = 0; + capture->sequence = 0; ret = media_pipeline_start(&video_dev->entity, &video_dev->pipe); if (ret < 0) goto error_dma_queue_flush; - if (video->mbus_code == 0) { + if (capture->mbus_code == 0) { ret = -EINVAL; goto error_media_pipeline; } - subdev = sun6i_video_remote_subdev(video, NULL); + subdev = sun6i_csi_capture_remote_subdev(capture, NULL); if (!subdev) { ret = -EINVAL; goto error_media_pipeline; } - sun6i_video_configure(csi_dev); + sun6i_csi_capture_configure(csi_dev); - spin_lock_irqsave(&video->dma_queue_lock, flags); + spin_lock_irqsave(&capture->dma_queue_lock, flags); - buf = list_first_entry(&video->dma_queue, + buf = list_first_entry(&capture->dma_queue, struct sun6i_csi_buffer, list); - sun6i_video_buffer_configure(csi_dev, buf); + sun6i_csi_capture_buffer_configure(csi_dev, buf); sun6i_csi_set_stream(csi_dev, true); @@ -224,9 +225,9 @@ static int sun6i_video_start_streaming(struct vb2_queue *queue, * would also drop frame when lacking of queued buffer. */ next_buf = list_next_entry(buf, list); - sun6i_video_buffer_configure(csi_dev, next_buf); + sun6i_csi_capture_buffer_configure(csi_dev, next_buf); - spin_unlock_irqrestore(&video->dma_queue_lock, flags); + spin_unlock_irqrestore(&capture->dma_queue_lock, flags); ret = v4l2_subdev_call(subdev, video, s_stream, 1); if (ret && ret != -ENOIOCTLCMD) @@ -241,52 +242,52 @@ static int sun6i_video_start_streaming(struct vb2_queue *queue, media_pipeline_stop(&video_dev->entity); error_dma_queue_flush: - spin_lock_irqsave(&video->dma_queue_lock, flags); - list_for_each_entry(buf, &video->dma_queue, list) + spin_lock_irqsave(&capture->dma_queue_lock, flags); + list_for_each_entry(buf, &capture->dma_queue, list) vb2_buffer_done(&buf->v4l2_buffer.vb2_buf, VB2_BUF_STATE_QUEUED); - INIT_LIST_HEAD(&video->dma_queue); - spin_unlock_irqrestore(&video->dma_queue_lock, flags); + INIT_LIST_HEAD(&capture->dma_queue); + spin_unlock_irqrestore(&capture->dma_queue_lock, flags); return ret; } -static void sun6i_video_stop_streaming(struct vb2_queue *queue) +static void sun6i_csi_capture_stop_streaming(struct vb2_queue *queue) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; struct v4l2_subdev *subdev; unsigned long flags; struct sun6i_csi_buffer *buf; - subdev = sun6i_video_remote_subdev(video, NULL); + subdev = sun6i_csi_capture_remote_subdev(capture, NULL); if (subdev) v4l2_subdev_call(subdev, video, s_stream, 0); sun6i_csi_set_stream(csi_dev, false); - media_pipeline_stop(&video->video_dev.entity); + media_pipeline_stop(&capture->video_dev.entity); /* Release all active buffers */ - spin_lock_irqsave(&video->dma_queue_lock, flags); - list_for_each_entry(buf, &video->dma_queue, list) + spin_lock_irqsave(&capture->dma_queue_lock, flags); + list_for_each_entry(buf, &capture->dma_queue, list) vb2_buffer_done(&buf->v4l2_buffer.vb2_buf, VB2_BUF_STATE_ERROR); - INIT_LIST_HEAD(&video->dma_queue); - spin_unlock_irqrestore(&video->dma_queue_lock, flags); + INIT_LIST_HEAD(&capture->dma_queue); + spin_unlock_irqrestore(&capture->dma_queue_lock, flags); } -void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev) +void sun6i_csi_capture_frame_done(struct sun6i_csi_device *csi_dev) { - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; struct sun6i_csi_buffer *buf; struct sun6i_csi_buffer *next_buf; struct vb2_v4l2_buffer *v4l2_buffer; - spin_lock(&video->dma_queue_lock); + spin_lock(&capture->dma_queue_lock); - buf = list_first_entry(&video->dma_queue, + buf = list_first_entry(&capture->dma_queue, struct sun6i_csi_buffer, list); - if (list_is_last(&buf->list, &video->dma_queue)) { + if (list_is_last(&buf->list, &capture->dma_queue)) { dev_dbg(csi_dev->dev, "Frame dropped!\n"); goto complete; } @@ -298,7 +299,7 @@ void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev) * for next ISR call. */ if (!next_buf->queued_to_csi) { - sun6i_video_buffer_configure(csi_dev, next_buf); + sun6i_csi_capture_buffer_configure(csi_dev, next_buf); dev_dbg(csi_dev->dev, "Frame dropped!\n"); goto complete; } @@ -306,39 +307,39 @@ void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev) list_del(&buf->list); v4l2_buffer = &buf->v4l2_buffer; v4l2_buffer->vb2_buf.timestamp = ktime_get_ns(); - v4l2_buffer->sequence = video->sequence; + v4l2_buffer->sequence = capture->sequence; vb2_buffer_done(&v4l2_buffer->vb2_buf, VB2_BUF_STATE_DONE); /* Prepare buffer for next frame but one. */ - if (!list_is_last(&next_buf->list, &video->dma_queue)) { + if (!list_is_last(&next_buf->list, &capture->dma_queue)) { next_buf = list_next_entry(next_buf, list); - sun6i_video_buffer_configure(csi_dev, next_buf); + sun6i_csi_capture_buffer_configure(csi_dev, next_buf); } else { dev_dbg(csi_dev->dev, "Next frame will be dropped!\n"); } complete: - video->sequence++; - spin_unlock(&video->dma_queue_lock); + capture->sequence++; + spin_unlock(&capture->dma_queue_lock); } -static const struct vb2_ops sun6i_video_queue_ops = { - .queue_setup = sun6i_video_queue_setup, - .buf_prepare = sun6i_video_buffer_prepare, - .buf_queue = sun6i_video_buffer_queue, - .start_streaming = sun6i_video_start_streaming, - .stop_streaming = sun6i_video_stop_streaming, +static const struct vb2_ops sun6i_csi_capture_queue_ops = { + .queue_setup = sun6i_csi_capture_queue_setup, + .buf_prepare = sun6i_csi_capture_buffer_prepare, + .buf_queue = sun6i_csi_capture_buffer_queue, + .start_streaming = sun6i_csi_capture_start_streaming, + .stop_streaming = sun6i_csi_capture_stop_streaming, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, }; /* V4L2 Device */ -static int sun6i_video_querycap(struct file *file, void *private, - struct v4l2_capability *capability) +static int sun6i_csi_capture_querycap(struct file *file, void *private, + struct v4l2_capability *capability) { struct sun6i_csi_device *csi_dev = video_drvdata(file); - struct video_device *video_dev = &csi_dev->video.video_dev; + struct video_device *video_dev = &csi_dev->capture.video_dev; strscpy(capability->driver, SUN6I_CSI_NAME, sizeof(capability->driver)); strscpy(capability->card, video_dev->name, sizeof(capability->card)); @@ -348,38 +349,38 @@ static int sun6i_video_querycap(struct file *file, void *private, return 0; } -static int sun6i_video_enum_fmt(struct file *file, void *private, - struct v4l2_fmtdesc *fmtdesc) +static int sun6i_csi_capture_enum_fmt(struct file *file, void *private, + struct v4l2_fmtdesc *fmtdesc) { u32 index = fmtdesc->index; - if (index >= ARRAY_SIZE(sun6i_video_formats)) + if (index >= ARRAY_SIZE(sun6i_csi_capture_formats)) return -EINVAL; - fmtdesc->pixelformat = sun6i_video_formats[index]; + fmtdesc->pixelformat = sun6i_csi_capture_formats[index]; return 0; } -static int sun6i_video_g_fmt(struct file *file, void *private, - struct v4l2_format *format) +static int sun6i_csi_capture_g_fmt(struct file *file, void *private, + struct v4l2_format *format) { struct sun6i_csi_device *csi_dev = video_drvdata(file); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; - *format = video->format; + *format = capture->format; return 0; } -static int sun6i_video_format_try(struct sun6i_video *video, - struct v4l2_format *format) +static int sun6i_csi_capture_format_try(struct sun6i_csi_capture *capture, + struct v4l2_format *format) { struct v4l2_pix_format *pix_format = &format->fmt.pix; int bpp; - if (!sun6i_video_format_check(pix_format->pixelformat)) - pix_format->pixelformat = sun6i_video_formats[0]; + if (!sun6i_csi_capture_format_check(pix_format->pixelformat)) + pix_format->pixelformat = sun6i_csi_capture_formats[0]; v4l_bound_align_image(&pix_format->width, MIN_WIDTH, MAX_WIDTH, 1, &pix_format->height, MIN_HEIGHT, MAX_WIDTH, 1, 1); @@ -399,43 +400,43 @@ static int sun6i_video_format_try(struct sun6i_video *video, return 0; } -static int sun6i_video_format_set(struct sun6i_video *video, - struct v4l2_format *format) +static int sun6i_csi_capture_format_set(struct sun6i_csi_capture *capture, + struct v4l2_format *format) { int ret; - ret = sun6i_video_format_try(video, format); + ret = sun6i_csi_capture_format_try(capture, format); if (ret) return ret; - video->format = *format; + capture->format = *format; return 0; } -static int sun6i_video_s_fmt(struct file *file, void *private, - struct v4l2_format *format) +static int sun6i_csi_capture_s_fmt(struct file *file, void *private, + struct v4l2_format *format) { struct sun6i_csi_device *csi_dev = video_drvdata(file); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; - if (vb2_is_busy(&video->queue)) + if (vb2_is_busy(&capture->queue)) return -EBUSY; - return sun6i_video_format_set(video, format); + return sun6i_csi_capture_format_set(capture, format); } -static int sun6i_video_try_fmt(struct file *file, void *private, - struct v4l2_format *format) +static int sun6i_csi_capture_try_fmt(struct file *file, void *private, + struct v4l2_format *format) { struct sun6i_csi_device *csi_dev = video_drvdata(file); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; - return sun6i_video_format_try(video, format); + return sun6i_csi_capture_format_try(capture, format); } -static int sun6i_video_enum_input(struct file *file, void *private, - struct v4l2_input *input) +static int sun6i_csi_capture_enum_input(struct file *file, void *private, + struct v4l2_input *input) { if (input->index != 0) return -EINVAL; @@ -446,16 +447,16 @@ static int sun6i_video_enum_input(struct file *file, void *private, return 0; } -static int sun6i_video_g_input(struct file *file, void *private, - unsigned int *index) +static int sun6i_csi_capture_g_input(struct file *file, void *private, + unsigned int *index) { *index = 0; return 0; } -static int sun6i_video_s_input(struct file *file, void *private, - unsigned int index) +static int sun6i_csi_capture_s_input(struct file *file, void *private, + unsigned int index) { if (index != 0) return -EINVAL; @@ -463,17 +464,17 @@ static int sun6i_video_s_input(struct file *file, void *private, return 0; } -static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { - .vidioc_querycap = sun6i_video_querycap, +static const struct v4l2_ioctl_ops sun6i_csi_capture_ioctl_ops = { + .vidioc_querycap = sun6i_csi_capture_querycap, - .vidioc_enum_fmt_vid_cap = sun6i_video_enum_fmt, - .vidioc_g_fmt_vid_cap = sun6i_video_g_fmt, - .vidioc_s_fmt_vid_cap = sun6i_video_s_fmt, - .vidioc_try_fmt_vid_cap = sun6i_video_try_fmt, + .vidioc_enum_fmt_vid_cap = sun6i_csi_capture_enum_fmt, + .vidioc_g_fmt_vid_cap = sun6i_csi_capture_g_fmt, + .vidioc_s_fmt_vid_cap = sun6i_csi_capture_s_fmt, + .vidioc_try_fmt_vid_cap = sun6i_csi_capture_try_fmt, - .vidioc_enum_input = sun6i_video_enum_input, - .vidioc_g_input = sun6i_video_g_input, - .vidioc_s_input = sun6i_video_s_input, + .vidioc_enum_input = sun6i_csi_capture_enum_input, + .vidioc_g_input = sun6i_csi_capture_g_input, + .vidioc_s_input = sun6i_csi_capture_s_input, .vidioc_create_bufs = vb2_ioctl_create_bufs, .vidioc_prepare_buf = vb2_ioctl_prepare_buf, @@ -492,20 +493,20 @@ static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { /* V4L2 File */ -static int sun6i_video_open(struct file *file) +static int sun6i_csi_capture_open(struct file *file) { struct sun6i_csi_device *csi_dev = video_drvdata(file); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; int ret = 0; - if (mutex_lock_interruptible(&video->lock)) + if (mutex_lock_interruptible(&capture->lock)) return -ERESTARTSYS; ret = v4l2_fh_open(file); if (ret < 0) goto error_lock; - ret = v4l2_pipeline_pm_get(&video->video_dev.entity); + ret = v4l2_pipeline_pm_get(&capture->video_dev.entity); if (ret < 0) goto error_v4l2_fh; @@ -516,7 +517,7 @@ static int sun6i_video_open(struct file *file) goto error_v4l2_fh; } - mutex_unlock(&video->lock); + mutex_unlock(&capture->lock); return 0; @@ -524,37 +525,37 @@ static int sun6i_video_open(struct file *file) v4l2_fh_release(file); error_lock: - mutex_unlock(&video->lock); + mutex_unlock(&capture->lock); return ret; } -static int sun6i_video_close(struct file *file) +static int sun6i_csi_capture_close(struct file *file) { struct sun6i_csi_device *csi_dev = video_drvdata(file); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; bool last_close; - mutex_lock(&video->lock); + mutex_lock(&capture->lock); last_close = v4l2_fh_is_singular_file(file); _vb2_fop_release(file, NULL); - v4l2_pipeline_pm_put(&video->video_dev.entity); + v4l2_pipeline_pm_put(&capture->video_dev.entity); /* Power off at last close. */ if (last_close) sun6i_csi_set_power(csi_dev, false); - mutex_unlock(&video->lock); + mutex_unlock(&capture->lock); return 0; } -static const struct v4l2_file_operations sun6i_video_fops = { +static const struct v4l2_file_operations sun6i_csi_capture_fops = { .owner = THIS_MODULE, - .open = sun6i_video_open, - .release = sun6i_video_close, + .open = sun6i_csi_capture_open, + .release = sun6i_csi_capture_close, .unlocked_ioctl = video_ioctl2, .mmap = vb2_fop_mmap, .poll = vb2_fop_poll @@ -562,8 +563,9 @@ static const struct v4l2_file_operations sun6i_video_fops = { /* Media Entity */ -static int sun6i_video_link_validate_get_format(struct media_pad *pad, - struct v4l2_subdev_format *fmt) +static int +sun6i_csi_capture_link_validate_get_format(struct media_pad *pad, + struct v4l2_subdev_format *fmt) { if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd = @@ -577,72 +579,74 @@ static int sun6i_video_link_validate_get_format(struct media_pad *pad, return -EINVAL; } -static int sun6i_video_link_validate(struct media_link *link) +static int sun6i_csi_capture_link_validate(struct media_link *link) { struct video_device *vdev = container_of(link->sink->entity, struct video_device, entity); struct sun6i_csi_device *csi_dev = video_get_drvdata(vdev); - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; struct v4l2_subdev_format source_fmt; int ret; - video->mbus_code = 0; + capture->mbus_code = 0; if (!media_entity_remote_pad(link->sink->entity->pads)) { - dev_info(csi_dev->dev, "video node %s pad not connected\n", + dev_info(csi_dev->dev, "capture node %s pad not connected\n", vdev->name); return -ENOLINK; } - ret = sun6i_video_link_validate_get_format(link->source, &source_fmt); + ret = sun6i_csi_capture_link_validate_get_format(link->source, + &source_fmt); if (ret < 0) return ret; if (!sun6i_csi_is_format_supported(csi_dev, - video->format.fmt.pix.pixelformat, + capture->format.fmt.pix.pixelformat, source_fmt.format.code)) { dev_err(csi_dev->dev, "Unsupported pixformat: 0x%x with mbus code: 0x%x!\n", - video->format.fmt.pix.pixelformat, + capture->format.fmt.pix.pixelformat, source_fmt.format.code); return -EPIPE; } - if (source_fmt.format.width != video->format.fmt.pix.width || - source_fmt.format.height != video->format.fmt.pix.height) { + if (source_fmt.format.width != capture->format.fmt.pix.width || + source_fmt.format.height != capture->format.fmt.pix.height) { dev_err(csi_dev->dev, "Wrong width or height %ux%u (%ux%u expected)\n", - video->format.fmt.pix.width, video->format.fmt.pix.height, + capture->format.fmt.pix.width, + capture->format.fmt.pix.height, source_fmt.format.width, source_fmt.format.height); return -EPIPE; } - video->mbus_code = source_fmt.format.code; + capture->mbus_code = source_fmt.format.code; return 0; } -static const struct media_entity_operations sun6i_video_media_ops = { - .link_validate = sun6i_video_link_validate +static const struct media_entity_operations sun6i_csi_capture_media_ops = { + .link_validate = sun6i_csi_capture_link_validate }; -/* Video */ +/* Capture */ -int sun6i_video_setup(struct sun6i_csi_device *csi_dev) +int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) { - struct sun6i_video *video = &csi_dev->video; + struct sun6i_csi_capture *capture = &csi_dev->capture; struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; struct v4l2_subdev *bridge_subdev = &csi_dev->bridge.subdev; - struct video_device *video_dev = &video->video_dev; - struct vb2_queue *queue = &video->queue; - struct media_pad *pad = &video->pad; + struct video_device *video_dev = &capture->video_dev; + struct vb2_queue *queue = &capture->queue; + struct media_pad *pad = &capture->pad; struct v4l2_format format = { 0 }; struct v4l2_pix_format *pix_format = &format.fmt.pix; int ret; /* Media Entity */ - video_dev->entity.ops = &sun6i_video_media_ops; + video_dev->entity.ops = &sun6i_csi_capture_media_ops; /* Media Pad */ @@ -654,22 +658,22 @@ int sun6i_video_setup(struct sun6i_csi_device *csi_dev) /* DMA queue */ - INIT_LIST_HEAD(&video->dma_queue); - spin_lock_init(&video->dma_queue_lock); + INIT_LIST_HEAD(&capture->dma_queue); + spin_lock_init(&capture->dma_queue_lock); - video->sequence = 0; + capture->sequence = 0; /* Queue */ - mutex_init(&video->lock); + mutex_init(&capture->lock); queue->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; queue->io_modes = VB2_MMAP | VB2_DMABUF; queue->buf_struct_size = sizeof(struct sun6i_csi_buffer); - queue->ops = &sun6i_video_queue_ops; + queue->ops = &sun6i_csi_capture_queue_ops; queue->mem_ops = &vb2_dma_contig_memops; queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - queue->lock = &video->lock; + queue->lock = &capture->lock; queue->dev = csi_dev->dev; queue->drv_priv = csi_dev; @@ -685,12 +689,12 @@ int sun6i_video_setup(struct sun6i_csi_device *csi_dev) /* V4L2 Format */ format.type = queue->type; - pix_format->pixelformat = sun6i_video_formats[0]; + pix_format->pixelformat = sun6i_csi_capture_formats[0]; pix_format->width = 1280; pix_format->height = 720; pix_format->field = V4L2_FIELD_NONE; - sun6i_video_format_set(video, &format); + sun6i_csi_capture_format_set(capture, &format); /* Video Device */ @@ -698,11 +702,11 @@ int sun6i_video_setup(struct sun6i_csi_device *csi_dev) video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; video_dev->vfl_dir = VFL_DIR_RX; video_dev->release = video_device_release_empty; - video_dev->fops = &sun6i_video_fops; - video_dev->ioctl_ops = &sun6i_video_ioctl_ops; + video_dev->fops = &sun6i_csi_capture_fops; + video_dev->ioctl_ops = &sun6i_csi_capture_ioctl_ops; video_dev->v4l2_dev = v4l2_dev; video_dev->queue = queue; - video_dev->lock = &video->lock; + video_dev->lock = &capture->lock; video_set_drvdata(video_dev, csi_dev); @@ -739,17 +743,17 @@ int sun6i_video_setup(struct sun6i_csi_device *csi_dev) error_media_entity: media_entity_cleanup(&video_dev->entity); - mutex_destroy(&video->lock); + mutex_destroy(&capture->lock); return ret; } -void sun6i_video_cleanup(struct sun6i_csi_device *csi_dev) +void sun6i_csi_capture_cleanup(struct sun6i_csi_device *csi_dev) { - struct sun6i_video *video = &csi_dev->video; - struct video_device *video_dev = &video->video_dev; + struct sun6i_csi_capture *capture = &csi_dev->capture; + struct video_device *video_dev = &capture->video_dev; vb2_video_unregister_device(video_dev); media_entity_cleanup(&video_dev->entity); - mutex_destroy(&video->lock); + mutex_destroy(&capture->lock); } diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h similarity index 64% rename from drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h rename to drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h index a917d2da6deb..36bba31fcb48 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h @@ -5,15 +5,15 @@ * Author: Yong Deng */ -#ifndef __SUN6I_VIDEO_H__ -#define __SUN6I_VIDEO_H__ +#ifndef __SUN6I_CAPTURE_H__ +#define __SUN6I_CAPTURE_H__ #include #include struct sun6i_csi_device; -struct sun6i_video { +struct sun6i_csi_capture { struct video_device video_dev; struct vb2_queue queue; struct mutex lock; /* Queue lock. */ @@ -27,9 +27,9 @@ struct sun6i_video { unsigned int sequence; }; -int sun6i_video_setup(struct sun6i_csi_device *csi_dev); -void sun6i_video_cleanup(struct sun6i_csi_device *csi_dev); +int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev); +void sun6i_csi_capture_cleanup(struct sun6i_csi_device *csi_dev); -void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev); +void sun6i_csi_capture_frame_done(struct sun6i_csi_device *csi_dev); -#endif /* __SUN6I_VIDEO_H__ */ +#endif /* __SUN6I_CAPTURE_H__ */ From patchwork Sat Feb 5 18:53:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67639C43217 for ; Sat, 5 Feb 2022 18:57:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381765AbiBES5C (ORCPT ); Sat, 5 Feb 2022 13:57:02 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:44849 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381417AbiBESzl (ORCPT ); Sat, 5 Feb 2022 13:55:41 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 552FF240011; Sat, 5 Feb 2022 18:55:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087335; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nAEGfQDJ0sLUOXQFQuKZ7RzdheNIg4Vw/eOZrL/G0qM=; b=J7J/7ad8perCvZH7629BPuOL3H5HnNNr+nM+/eAvAwsVNo/SlI9aWPHDWEbvHbRT5i5Ga7 Ac3TniUEOg+pPj6giMPcq6LBUS58lgHb4q5oAsK7VkF/uLRsq/MuzWv1/ZMLbbLwZiIlHD he4WeFMLipnNbFVtRmdaXkWzZHLyNbcKyOtDSq5qnrPkHZEo5NWW9MFH/q/uq6Vsdkj2Fb uBRh7+F/IZwT+maLNRGryiQYozSvQ6JrfqJUQiZbl88DQ/ZVzpIouEknSvFE3GgKjPDPxA h+1MjjdZKz+uOSdrhJq7sdLhLd/dgLfFu8l/kpFroigBRMRjcmjzsyM0ADjLIg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 32/66] media: sun6i-csi: Add capture state using vsync for page flip Date: Sat, 5 Feb 2022 19:53:55 +0100 Message-Id: <20220205185429.2278860-33-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This introduces a new state structure and associated helpers for capture, which handles the buffer queue and state for each submitted buffer. Besides from the code refactoring, this changes the page flip point to vsync instead of frame done, which allows working with only two buffers without losing frames. This is apparently a more appropriate thing to do with this controller. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 4 + .../platform/sunxi/sun6i-csi/sun6i_csi.h | 3 - .../sunxi/sun6i-csi/sun6i_csi_capture.c | 259 ++++++++++-------- .../sunxi/sun6i-csi/sun6i_csi_capture.h | 23 +- 4 files changed, 165 insertions(+), 124 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 834fc8c17189..1b5995e68be5 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -566,6 +566,7 @@ void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable) regmap_write(regmap, CSI_CH_INT_STA_REG, 0xFF); regmap_write(regmap, CSI_CH_INT_EN_REG, + CSI_CH_INT_EN_VS_INT_EN | CSI_CH_INT_EN_HB_OF_INT_EN | CSI_CH_INT_EN_FIFO2_OF_INT_EN | CSI_CH_INT_EN_FIFO1_OF_INT_EN | @@ -686,6 +687,9 @@ static irqreturn_t sun6i_csi_isr(int irq, void *private) if (status & CSI_CH_INT_STA_FD_PD) sun6i_csi_capture_frame_done(csi_dev); + if (status & CSI_CH_INT_STA_VS_PD) + sun6i_csi_capture_sync(csi_dev); + regmap_write(regmap, CSI_CH_INT_STA_REG, status); return IRQ_HANDLED; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index a53c98507f37..741cacaa43e1 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -26,9 +26,6 @@ enum sun6i_csi_port { struct sun6i_csi_buffer { struct vb2_v4l2_buffer v4l2_buffer; struct list_head list; - - dma_addr_t dma_addr; - bool queued_to_csi; }; /** diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 1ebc2d825838..bcbb4ffbb517 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -90,8 +90,13 @@ static void sun6i_csi_capture_buffer_configure(struct sun6i_csi_device *csi_dev, struct sun6i_csi_buffer *csi_buffer) { - csi_buffer->queued_to_csi = true; - sun6i_csi_update_buf_addr(csi_dev, csi_buffer->dma_addr); + struct vb2_buffer *vb2_buffer; + dma_addr_t address; + + vb2_buffer = &csi_buffer->v4l2_buffer.vb2_buf; + address = vb2_dma_contig_plane_dma_addr(vb2_buffer, 0); + + sun6i_csi_update_buf_addr(csi_dev, address); } static void sun6i_csi_capture_configure(struct sun6i_csi_device *csi_dev) @@ -108,6 +113,119 @@ static void sun6i_csi_capture_configure(struct sun6i_csi_device *csi_dev) sun6i_csi_update_config(csi_dev, &config); } +/* State */ + +static void sun6i_csi_capture_state_cleanup(struct sun6i_csi_device *csi_dev, + bool error) +{ + struct sun6i_csi_capture_state *state = &csi_dev->capture.state; + struct sun6i_csi_buffer **csi_buffer_states[] = { + &state->pending, &state->current, &state->complete, + }; + struct sun6i_csi_buffer *csi_buffer; + struct vb2_buffer *vb2_buffer; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&state->lock, flags); + + for (i = 0; i < ARRAY_SIZE(csi_buffer_states); i++) { + csi_buffer = *csi_buffer_states[i]; + if (!csi_buffer) + continue; + + vb2_buffer = &csi_buffer->v4l2_buffer.vb2_buf; + vb2_buffer_done(vb2_buffer, error ? VB2_BUF_STATE_ERROR : + VB2_BUF_STATE_QUEUED); + + *csi_buffer_states[i] = NULL; + } + + list_for_each_entry(csi_buffer, &state->queue, list) { + vb2_buffer = &csi_buffer->v4l2_buffer.vb2_buf; + vb2_buffer_done(vb2_buffer, error ? VB2_BUF_STATE_ERROR : + VB2_BUF_STATE_QUEUED); + } + + INIT_LIST_HEAD(&state->queue); + + spin_unlock_irqrestore(&state->lock, flags); +} + +static void sun6i_csi_capture_state_update(struct sun6i_csi_device *csi_dev) +{ + struct sun6i_csi_capture_state *state = &csi_dev->capture.state; + struct sun6i_csi_buffer *csi_buffer; + unsigned long flags; + + spin_lock_irqsave(&state->lock, flags); + + if (list_empty(&state->queue)) + goto complete; + + if (state->pending) + goto complete; + + csi_buffer = list_first_entry(&state->queue, struct sun6i_csi_buffer, + list); + + sun6i_csi_capture_buffer_configure(csi_dev, csi_buffer); + + list_del(&csi_buffer->list); + + state->pending = csi_buffer; + +complete: + spin_unlock_irqrestore(&state->lock, flags); +} + +static void sun6i_csi_capture_state_complete(struct sun6i_csi_device *csi_dev) +{ + struct sun6i_csi_capture_state *state = &csi_dev->capture.state; + unsigned long flags; + + spin_lock_irqsave(&state->lock, flags); + + if (!state->pending) + goto complete; + + state->complete = state->current; + state->current = state->pending; + state->pending = NULL; + + if (state->complete) { + struct sun6i_csi_buffer *csi_buffer = state->complete; + struct vb2_buffer *vb2_buffer = + &csi_buffer->v4l2_buffer.vb2_buf; + + vb2_buffer->timestamp = ktime_get_ns(); + csi_buffer->v4l2_buffer.sequence = state->sequence; + + vb2_buffer_done(vb2_buffer, VB2_BUF_STATE_DONE); + + state->complete = NULL; + } + +complete: + spin_unlock_irqrestore(&state->lock, flags); +} + +void sun6i_csi_capture_frame_done(struct sun6i_csi_device *csi_dev) +{ + struct sun6i_csi_capture_state *state = &csi_dev->capture.state; + unsigned long flags; + + spin_lock_irqsave(&state->lock, flags); + state->sequence++; + spin_unlock_irqrestore(&state->lock, flags); +} + +void sun6i_csi_capture_sync(struct sun6i_csi_device *csi_dev) +{ + sun6i_csi_capture_state_complete(csi_dev); + sun6i_csi_capture_state_update(csi_dev); +} + /* Queue */ static int sun6i_csi_capture_queue_setup(struct vb2_queue *queue, @@ -117,8 +235,7 @@ static int sun6i_csi_capture_queue_setup(struct vb2_queue *queue, struct device *alloc_devs[]) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); - struct sun6i_csi_capture *capture = &csi_dev->capture; - unsigned int size = capture->format.fmt.pix.sizeimage; + unsigned int size = csi_dev->capture.format.fmt.pix.sizeimage; if (*planes_count) return sizes[0] < size ? -EINVAL : 0; @@ -135,8 +252,6 @@ static int sun6i_csi_capture_buffer_prepare(struct vb2_buffer *buffer) struct sun6i_csi_capture *capture = &csi_dev->capture; struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); - struct sun6i_csi_buffer *csi_buffer = - container_of(v4l2_buffer, struct sun6i_csi_buffer, v4l2_buffer); unsigned long size = capture->format.fmt.pix.sizeimage; if (vb2_plane_size(buffer, 0) < size) { @@ -147,7 +262,6 @@ static int sun6i_csi_capture_buffer_prepare(struct vb2_buffer *buffer) vb2_set_plane_payload(buffer, 0, size); - csi_buffer->dma_addr = vb2_dma_contig_plane_dma_addr(buffer, 0); v4l2_buffer->field = capture->format.fmt.pix.field; return 0; @@ -156,16 +270,15 @@ static int sun6i_csi_capture_buffer_prepare(struct vb2_buffer *buffer) static void sun6i_csi_capture_buffer_queue(struct vb2_buffer *buffer) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); - struct sun6i_csi_capture *capture = &csi_dev->capture; + struct sun6i_csi_capture_state *state = &csi_dev->capture.state; struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); struct sun6i_csi_buffer *csi_buffer = container_of(v4l2_buffer, struct sun6i_csi_buffer, v4l2_buffer); unsigned long flags; - spin_lock_irqsave(&capture->dma_queue_lock, flags); - csi_buffer->queued_to_csi = false; - list_add_tail(&csi_buffer->list, &capture->dma_queue); - spin_unlock_irqrestore(&capture->dma_queue_lock, flags); + spin_lock_irqsave(&state->lock, flags); + list_add_tail(&csi_buffer->list, &state->queue); + spin_unlock_irqrestore(&state->lock, flags); } static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, @@ -173,18 +286,16 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); struct sun6i_csi_capture *capture = &csi_dev->capture; + struct sun6i_csi_capture_state *state = &capture->state; struct video_device *video_dev = &capture->video_dev; - struct sun6i_csi_buffer *buf; - struct sun6i_csi_buffer *next_buf; struct v4l2_subdev *subdev; - unsigned long flags; int ret; - capture->sequence = 0; + state->sequence = 0; ret = media_pipeline_start(&video_dev->entity, &video_dev->pipe); if (ret < 0) - goto error_dma_queue_flush; + goto error_state; if (capture->mbus_code == 0) { ret = -EINVAL; @@ -197,37 +308,17 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, goto error_media_pipeline; } + /* Configure */ + sun6i_csi_capture_configure(csi_dev); - spin_lock_irqsave(&capture->dma_queue_lock, flags); + /* State Update */ - buf = list_first_entry(&capture->dma_queue, - struct sun6i_csi_buffer, list); - sun6i_csi_capture_buffer_configure(csi_dev, buf); + sun6i_csi_capture_state_update(csi_dev); - sun6i_csi_set_stream(csi_dev, true); + /* Enable */ - /* - * CSI will lookup the next dma buffer for next frame before the - * the current frame done IRQ triggered. This is not documented - * but reported by Ondřej Jirman. - * The BSP code has workaround for this too. It skip to mark the - * first buffer as frame done for VB2 and pass the second buffer - * to CSI in the first frame done ISR call. Then in second frame - * done ISR call, it mark the first buffer as frame done for VB2 - * and pass the third buffer to CSI. And so on. The bad thing is - * that the first buffer will be written twice and the first frame - * is dropped even the queued buffer is sufficient. - * So, I make some improvement here. Pass the next buffer to CSI - * just follow starting the CSI. In this case, the first frame - * will be stored in first buffer, second frame in second buffer. - * This method is used to avoid dropping the first frame, it - * would also drop frame when lacking of queued buffer. - */ - next_buf = list_next_entry(buf, list); - sun6i_csi_capture_buffer_configure(csi_dev, next_buf); - - spin_unlock_irqrestore(&capture->dma_queue_lock, flags); + sun6i_csi_set_stream(csi_dev, true); ret = v4l2_subdev_call(subdev, video, s_stream, 1); if (ret && ret != -ENOIOCTLCMD) @@ -241,13 +332,8 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, error_media_pipeline: media_pipeline_stop(&video_dev->entity); -error_dma_queue_flush: - spin_lock_irqsave(&capture->dma_queue_lock, flags); - list_for_each_entry(buf, &capture->dma_queue, list) - vb2_buffer_done(&buf->v4l2_buffer.vb2_buf, - VB2_BUF_STATE_QUEUED); - INIT_LIST_HEAD(&capture->dma_queue); - spin_unlock_irqrestore(&capture->dma_queue_lock, flags); +error_state: + sun6i_csi_capture_state_cleanup(csi_dev, false); return ret; } @@ -257,8 +343,6 @@ static void sun6i_csi_capture_stop_streaming(struct vb2_queue *queue) struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); struct sun6i_csi_capture *capture = &csi_dev->capture; struct v4l2_subdev *subdev; - unsigned long flags; - struct sun6i_csi_buffer *buf; subdev = sun6i_csi_capture_remote_subdev(capture, NULL); if (subdev) @@ -268,59 +352,7 @@ static void sun6i_csi_capture_stop_streaming(struct vb2_queue *queue) media_pipeline_stop(&capture->video_dev.entity); - /* Release all active buffers */ - spin_lock_irqsave(&capture->dma_queue_lock, flags); - list_for_each_entry(buf, &capture->dma_queue, list) - vb2_buffer_done(&buf->v4l2_buffer.vb2_buf, VB2_BUF_STATE_ERROR); - INIT_LIST_HEAD(&capture->dma_queue); - spin_unlock_irqrestore(&capture->dma_queue_lock, flags); -} - -void sun6i_csi_capture_frame_done(struct sun6i_csi_device *csi_dev) -{ - struct sun6i_csi_capture *capture = &csi_dev->capture; - struct sun6i_csi_buffer *buf; - struct sun6i_csi_buffer *next_buf; - struct vb2_v4l2_buffer *v4l2_buffer; - - spin_lock(&capture->dma_queue_lock); - - buf = list_first_entry(&capture->dma_queue, - struct sun6i_csi_buffer, list); - if (list_is_last(&buf->list, &capture->dma_queue)) { - dev_dbg(csi_dev->dev, "Frame dropped!\n"); - goto complete; - } - - next_buf = list_next_entry(buf, list); - /* If a new buffer (#next_buf) had not been queued to CSI, the old - * buffer (#buf) is still holding by CSI for storing the next - * frame. So, we queue a new buffer (#next_buf) to CSI then wait - * for next ISR call. - */ - if (!next_buf->queued_to_csi) { - sun6i_csi_capture_buffer_configure(csi_dev, next_buf); - dev_dbg(csi_dev->dev, "Frame dropped!\n"); - goto complete; - } - - list_del(&buf->list); - v4l2_buffer = &buf->v4l2_buffer; - v4l2_buffer->vb2_buf.timestamp = ktime_get_ns(); - v4l2_buffer->sequence = capture->sequence; - vb2_buffer_done(&v4l2_buffer->vb2_buf, VB2_BUF_STATE_DONE); - - /* Prepare buffer for next frame but one. */ - if (!list_is_last(&next_buf->list, &capture->dma_queue)) { - next_buf = list_next_entry(next_buf, list); - sun6i_csi_capture_buffer_configure(csi_dev, next_buf); - } else { - dev_dbg(csi_dev->dev, "Next frame will be dropped!\n"); - } - -complete: - capture->sequence++; - spin_unlock(&capture->dma_queue_lock); + sun6i_csi_capture_state_cleanup(csi_dev, true); } static const struct vb2_ops sun6i_csi_capture_queue_ops = { @@ -635,6 +667,7 @@ static const struct media_entity_operations sun6i_csi_capture_media_ops = { int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) { struct sun6i_csi_capture *capture = &csi_dev->capture; + struct sun6i_csi_capture_state *state = &capture->state; struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; struct v4l2_subdev *bridge_subdev = &csi_dev->bridge.subdev; struct video_device *video_dev = &capture->video_dev; @@ -644,6 +677,11 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) struct v4l2_pix_format *pix_format = &format.fmt.pix; int ret; + /* State */ + + INIT_LIST_HEAD(&state->queue); + spin_lock_init(&state->lock); + /* Media Entity */ video_dev->entity.ops = &sun6i_csi_capture_media_ops; @@ -656,13 +694,6 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) if (ret < 0) return ret; - /* DMA queue */ - - INIT_LIST_HEAD(&capture->dma_queue); - spin_lock_init(&capture->dma_queue_lock); - - capture->sequence = 0; - /* Queue */ mutex_init(&capture->lock); @@ -672,14 +703,12 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) queue->buf_struct_size = sizeof(struct sun6i_csi_buffer); queue->ops = &sun6i_csi_capture_queue_ops; queue->mem_ops = &vb2_dma_contig_memops; + queue->min_buffers_needed = 2; queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; queue->lock = &capture->lock; queue->dev = csi_dev->dev; queue->drv_priv = csi_dev; - /* Make sure non-dropped frame. */ - queue->min_buffers_needed = 3; - ret = vb2_queue_init(queue); if (ret) { v4l2_err(v4l2_dev, "failed to initialize vb2 queue: %d\n", ret); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h index 36bba31fcb48..7fa66a2af5ec 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h @@ -13,23 +13,34 @@ struct sun6i_csi_device; +#undef current +struct sun6i_csi_capture_state { + struct list_head queue; + spinlock_t lock; /* Queue and buffers lock. */ + + struct sun6i_csi_buffer *pending; + struct sun6i_csi_buffer *current; + struct sun6i_csi_buffer *complete; + + unsigned int sequence; +}; + struct sun6i_csi_capture { + struct sun6i_csi_capture_state state; + struct video_device video_dev; struct vb2_queue queue; struct mutex lock; /* Queue lock. */ struct media_pad pad; - struct list_head dma_queue; - spinlock_t dma_queue_lock; /* DMA queue lock. */ - struct v4l2_format format; u32 mbus_code; - unsigned int sequence; }; +void sun6i_csi_capture_sync(struct sun6i_csi_device *csi_dev); +void sun6i_csi_capture_frame_done(struct sun6i_csi_device *csi_dev); + int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev); void sun6i_csi_capture_cleanup(struct sun6i_csi_device *csi_dev); -void sun6i_csi_capture_frame_done(struct sun6i_csi_device *csi_dev); - #endif /* __SUN6I_CAPTURE_H__ */ From patchwork Sat Feb 5 18:53:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540158 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C09E9C433EF for ; Sat, 5 Feb 2022 18:57:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381419AbiBES5B (ORCPT ); Sat, 5 Feb 2022 13:57:01 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:60835 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350926AbiBESzl (ORCPT ); Sat, 5 Feb 2022 13:55:41 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 78310240009; Sat, 5 Feb 2022 18:55:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087340; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EjzQGEu5uZtLWAl3LnvoaNwDma9Ro0WnTNllST1NPGE=; b=erisk26vtUM6RR1kyunZtADoxA0lzgjmtSN9ua+gkPoyZp38DFryUdFtM+n/UrCx4WXVyV OWRsYOauSvj0GFalibRWCeaRnQFtoXxBnTR6ZvzrnzBPTGr1sZWn5Rj+3i4j6mb5O46gtE es5TesTFloMSWAS415dIfLtIzWmqlgtPcQCU2wdNX4Nd9bPZREZf7cPIhOJsApzkOpaxP0 joCcHwnJdc1K3plQD56TlQrhYPGe7+6T0elaleoZmD/L4qNxI6gl6zEuECYLilsCzLyAWk 6IIyjhZhJWcBeMaLIU4nzRk5Lgua8qr+BYF5WX8py49uvD0Z0CvoeKowfZDbOw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 35/66] media: sun6i-csi: Implement address configuration without indirection Date: Sat, 5 Feb 2022 19:53:58 +0100 Message-Id: <20220205185429.2278860-36-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Instead of calculating the planar_offset at one point and using it later in a dedicated function, reimplement address configuration with v4l2 format info in the buffer_configure function. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 27 ---------------- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 10 ------ .../sunxi/sun6i-csi/sun6i_csi_capture.c | 32 ++++++++++++++++++- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index ee2d4df50481..5314497ad681 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -463,7 +463,6 @@ static void sun6i_csi_set_window(struct sun6i_csi_device *csi_dev) struct sun6i_csi_config *config = &csi_dev->config; u32 bytesperline_y; u32 bytesperline_c; - int *planar_offset = csi_dev->planar_offset; u32 width = config->width; u32 height = config->height; u32 hor_len = width; @@ -488,7 +487,6 @@ static void sun6i_csi_set_window(struct sun6i_csi_device *csi_dev) SUN6I_CSI_CH_VSIZE_LEN(height) | SUN6I_CSI_CH_VSIZE_START(0)); - planar_offset[0] = 0; switch (config->pixelformat) { case V4L2_PIX_FMT_NV12_16L16: case V4L2_PIX_FMT_NV12: @@ -497,23 +495,15 @@ static void sun6i_csi_set_window(struct sun6i_csi_device *csi_dev) case V4L2_PIX_FMT_NV61: bytesperline_y = width; bytesperline_c = width; - planar_offset[1] = bytesperline_y * height; - planar_offset[2] = -1; break; case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: bytesperline_y = width; bytesperline_c = width / 2; - planar_offset[1] = bytesperline_y * height; - planar_offset[2] = planar_offset[1] + - bytesperline_c * height / 2; break; case V4L2_PIX_FMT_YUV422P: bytesperline_y = width; bytesperline_c = width / 2; - planar_offset[1] = bytesperline_y * height; - planar_offset[2] = planar_offset[1] + - bytesperline_c * height; break; default: /* raw */ dev_dbg(csi_dev->dev, @@ -522,8 +512,6 @@ static void sun6i_csi_set_window(struct sun6i_csi_device *csi_dev) bytesperline_y = (sun6i_csi_get_bpp(config->pixelformat) * config->width) / 8; bytesperline_c = 0; - planar_offset[1] = -1; - planar_offset[2] = -1; break; } @@ -547,21 +535,6 @@ int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, return 0; } -void sun6i_csi_update_buf_addr(struct sun6i_csi_device *csi_dev, - dma_addr_t addr) -{ - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_FIFO0_ADDR_REG, - SUN6I_CSI_ADDR_VALUE(addr + csi_dev->planar_offset[0])); - if (csi_dev->planar_offset[1] != -1) - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_FIFO1_ADDR_REG, - SUN6I_CSI_ADDR_VALUE(addr + - csi_dev->planar_offset[1])); - if (csi_dev->planar_offset[2] != -1) - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_FIFO2_ADDR_REG, - SUN6I_CSI_ADDR_VALUE(addr + - csi_dev->planar_offset[2])); -} - void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable) { struct regmap *regmap = csi_dev->regmap; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index 741cacaa43e1..e16b3439a63c 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -63,8 +63,6 @@ struct sun6i_csi_device { struct clk *clk_mod; struct clk *clk_ram; struct reset_control *reset; - - int planar_offset[3]; }; /** @@ -91,14 +89,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable); int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, struct sun6i_csi_config *config); -/** - * sun6i_csi_update_buf_addr() - update the csi frame buffer address - * @csi: pointer to the csi - * @addr: frame buffer's physical address - */ -void sun6i_csi_update_buf_addr(struct sun6i_csi_device *csi_dev, - dma_addr_t addr); - /** * sun6i_csi_set_stream() - start/stop csi streaming * @csi: pointer to the csi diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 7b8556a25c61..f32beed0aaad 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -16,6 +17,7 @@ #include "sun6i_csi.h" #include "sun6i_csi_capture.h" +#include "sun6i_csi_reg.h" /* This is got from BSP sources. */ #define MIN_WIDTH (32) @@ -109,13 +111,41 @@ static void sun6i_csi_capture_buffer_configure(struct sun6i_csi_device *csi_dev, struct sun6i_csi_buffer *csi_buffer) { + struct regmap *regmap = csi_dev->regmap; + const struct v4l2_format_info *info; struct vb2_buffer *vb2_buffer; + unsigned int width, height; dma_addr_t address; + u32 pixelformat; vb2_buffer = &csi_buffer->v4l2_buffer.vb2_buf; address = vb2_dma_contig_plane_dma_addr(vb2_buffer, 0); - sun6i_csi_update_buf_addr(csi_dev, address); + regmap_write(regmap, SUN6I_CSI_CH_FIFO0_ADDR_REG, + SUN6I_CSI_ADDR_VALUE(address)); + + sun6i_csi_capture_dimensions(csi_dev, &width, &height); + sun6i_csi_capture_format(csi_dev, &pixelformat, NULL); + + info = v4l2_format_info(pixelformat); + /* Unsupported formats are single-plane, so we can stop here. */ + if (!info) + return; + + if (info->comp_planes > 1) { + address += info->bpp[0] * width * height; + + regmap_write(regmap, SUN6I_CSI_CH_FIFO1_ADDR_REG, + SUN6I_CSI_ADDR_VALUE(address)); + } + + if (info->comp_planes > 2) { + address += info->bpp[1] * DIV_ROUND_UP(width, info->hdiv) * + DIV_ROUND_UP(height, info->vdiv); + + regmap_write(regmap, SUN6I_CSI_CH_FIFO2_ADDR_REG, + SUN6I_CSI_ADDR_VALUE(address)); + } } static void sun6i_csi_capture_configure(struct sun6i_csi_device *csi_dev) From patchwork Sat Feb 5 18:53:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540156 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B407CC433EF for ; Sat, 5 Feb 2022 18:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381429AbiBES5T (ORCPT ); Sat, 5 Feb 2022 13:57:19 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:55521 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381428AbiBESzq (ORCPT ); Sat, 5 Feb 2022 13:55:46 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 1C3FE24000A; Sat, 5 Feb 2022 18:55:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087341; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KsW6dwZ6XY/Jd3tCcTrPW9sY6sNQwXsn1oDkb4n9lt8=; b=budOrhSW03+JLtgBO9IhoomOq125GQ/GwlLhnOSNgWef2yStBlAXSe8bigpcZ2L1FCIEGp OjaTIn9fg5VvZsUQuwXWS3xCERfVnSkjmUNmTwE/b/prHlrAh30j74khYAjBVVht1Eb+qe JEcBKOuz8ypNGUNpEZ8aVl7icd+YzLbvIqdrEgZ9sVCQV3rzWQm0iAe/zUHJlXvz7ohfbJ YyYBKr8XQylEyXEkHhsN9Wre2yRQW8RZSFUqrUBK1FCr/8p5mFOB7KIX31X4gyDL3oBoWW eh3GD2dzFhwx/zK2rU1yDpMkX1a2FvN1U44K5G0MpL8Cmh7ze6K6fUBwmHNHFg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 36/66] media: sun6i-csi: Split stream sequences and irq code in capture Date: Sat, 5 Feb 2022 19:53:59 +0100 Message-Id: <20220205185429.2278860-37-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Create minimal helpers that split the enable/disable flow, which will make it easier to move control over to the bridge later on. Generally speaking the goal is to move register configuration to the capture code and later split it with the bridge code. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 26 --------- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 7 --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 58 ++++++++++++++++++- 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 5314497ad681..22779baf8c09 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -535,32 +535,6 @@ int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, return 0; } -void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable) -{ - struct regmap *regmap = csi_dev->regmap; - - if (!enable) { - regmap_update_bits(regmap, SUN6I_CSI_CAP_REG, - SUN6I_CSI_CAP_VCAP_ON, 0); - regmap_write(regmap, SUN6I_CSI_CH_INT_EN_REG, 0); - return; - } - - regmap_write(regmap, SUN6I_CSI_CH_INT_STA_REG, - SUN6I_CSI_CH_INT_STA_CLEAR); - regmap_write(regmap, SUN6I_CSI_CH_INT_EN_REG, - SUN6I_CSI_CH_INT_EN_VS | - SUN6I_CSI_CH_INT_EN_HB_OF | - SUN6I_CSI_CH_INT_EN_FIFO2_OF | - SUN6I_CSI_CH_INT_EN_FIFO1_OF | - SUN6I_CSI_CH_INT_EN_FIFO0_OF | - SUN6I_CSI_CH_INT_EN_FD | - SUN6I_CSI_CH_INT_EN_CD); - - regmap_update_bits(regmap, SUN6I_CSI_CAP_REG, SUN6I_CSI_CAP_VCAP_ON, - SUN6I_CSI_CAP_VCAP_ON); -} - /* Media */ static const struct media_device_ops sun6i_csi_media_ops = { diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index e16b3439a63c..1f235b8e240c 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -89,13 +89,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable); int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, struct sun6i_csi_config *config); -/** - * sun6i_csi_set_stream() - start/stop csi streaming - * @csi: pointer to the csi - * @enable: start/stop - */ -void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable); - /* get bpp form v4l2 pixformat */ static inline int sun6i_csi_get_bpp(unsigned int pixformat) { diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index f32beed0aaad..ab6e298864ed 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -107,6 +107,51 @@ static bool sun6i_csi_capture_format_check(u32 format) /* Capture */ +static void sun6i_csi_capture_irq_enable(struct sun6i_csi_device *csi_dev) +{ + struct regmap *regmap = csi_dev->regmap; + + regmap_write(regmap, SUN6I_CSI_CH_INT_EN_REG, + SUN6I_CSI_CH_INT_EN_VS | + SUN6I_CSI_CH_INT_EN_HB_OF | + SUN6I_CSI_CH_INT_EN_FIFO2_OF | + SUN6I_CSI_CH_INT_EN_FIFO1_OF | + SUN6I_CSI_CH_INT_EN_FIFO0_OF | + SUN6I_CSI_CH_INT_EN_FD | + SUN6I_CSI_CH_INT_EN_CD); +} + +static void sun6i_csi_capture_irq_disable(struct sun6i_csi_device *csi_dev) +{ + struct regmap *regmap = csi_dev->regmap; + + regmap_write(regmap, SUN6I_CSI_CH_INT_EN_REG, 0); +} + +static void sun6i_csi_capture_irq_clear(struct sun6i_csi_device *csi_dev) +{ + struct regmap *regmap = csi_dev->regmap; + + regmap_write(regmap, SUN6I_CSI_CH_INT_EN_REG, 0); + regmap_write(regmap, SUN6I_CSI_CH_INT_STA_REG, + SUN6I_CSI_CH_INT_STA_CLEAR); +} + +static void sun6i_csi_capture_enable(struct sun6i_csi_device *csi_dev) +{ + struct regmap *regmap = csi_dev->regmap; + + regmap_update_bits(regmap, SUN6I_CSI_CAP_REG, SUN6I_CSI_CAP_VCAP_ON, + SUN6I_CSI_CAP_VCAP_ON); +} + +static void sun6i_csi_capture_disable(struct sun6i_csi_device *csi_dev) +{ + struct regmap *regmap = csi_dev->regmap; + + regmap_update_bits(regmap, SUN6I_CSI_CAP_REG, SUN6I_CSI_CAP_VCAP_ON, 0); +} + static void sun6i_csi_capture_buffer_configure(struct sun6i_csi_device *csi_dev, struct sun6i_csi_buffer *csi_buffer) @@ -357,6 +402,10 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, goto error_media_pipeline; } + /* Clear */ + + sun6i_csi_capture_irq_clear(csi_dev); + /* Configure */ sun6i_csi_capture_configure(csi_dev); @@ -367,7 +416,8 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, /* Enable */ - sun6i_csi_set_stream(csi_dev, true); + sun6i_csi_capture_irq_enable(csi_dev); + sun6i_csi_capture_enable(csi_dev); ret = v4l2_subdev_call(subdev, video, s_stream, 1); if (ret && ret != -ENOIOCTLCMD) @@ -376,7 +426,8 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, return 0; error_stream: - sun6i_csi_set_stream(csi_dev, false); + sun6i_csi_capture_disable(csi_dev); + sun6i_csi_capture_irq_disable(csi_dev); error_media_pipeline: media_pipeline_stop(&video_dev->entity); @@ -397,7 +448,8 @@ static void sun6i_csi_capture_stop_streaming(struct vb2_queue *queue) if (subdev) v4l2_subdev_call(subdev, video, s_stream, 0); - sun6i_csi_set_stream(csi_dev, false); + sun6i_csi_capture_disable(csi_dev); + sun6i_csi_capture_irq_disable(csi_dev); media_pipeline_stop(&capture->video_dev.entity); From patchwork Sat Feb 5 18:54:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540154 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCE6FC433EF for ; Sat, 5 Feb 2022 18:57:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381843AbiBES5h (ORCPT ); Sat, 5 Feb 2022 13:57:37 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:50607 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381246AbiBESzu (ORCPT ); Sat, 5 Feb 2022 13:55:50 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 647B624000B; Sat, 5 Feb 2022 18:55:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087344; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SqBKSJwvMk5IYLj8vexB6HDgjYXTnHXzm/kBQX/+E+Y=; b=BNfSaOCQAM3f9CkZJyWTvLIJzdGATk0AG5BxJAaGIKBODT+kFcnBkyoSMrjz56J9u03fPN to9vA9vhWBMYbqNHuV7GkP4W83UFOJjp7pOwMgkqIh0P/xH+baCwIqPQQXPTAvpiZUz2LQ tVHNWl4iJGpvhOMtd2CfhqEnHOMKmUb+gG1vj62Y08Kw4vCptfw1jYHcbkOlkLky4Z1fD6 lhIUNDWpsH1NcWgGVZWz/Lh8iySmeMXSJkwcN3878bSmoBOFrRjYKalCKMd6Sfqmr/IXRg J/bxa7yJVa2RLq4qGwbttFxEWNrpxuKF7ANPWlHtXP7+IwnRIpPzGa7MILasOw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 38/66] media: sun6i-csi: Move register configuration to capture Date: Sat, 5 Feb 2022 19:54:01 +0100 Message-Id: <20220205185429.2278860-39-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Continue moving things over to capture in tidy helpers. Also take the occasion to remove the config struct, which is unwelcome redundancy and use the capture helpers instead. The code is only adapted to reflect the removal of the config structure. No functional change intended. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 363 ----------------- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 25 -- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 364 +++++++++++++++++- 3 files changed, 356 insertions(+), 396 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 7e3727c86e7a..d934b4b466ef 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -148,369 +148,6 @@ bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev, return false; } -static enum csi_input_fmt get_csi_input_format(struct sun6i_csi_device *csi_dev, - u32 mbus_code, u32 pixformat) -{ - /* non-YUV */ - if ((mbus_code & 0xF000) != 0x2000) - return CSI_INPUT_FORMAT_RAW; - - switch (pixformat) { - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - return CSI_INPUT_FORMAT_RAW; - default: - break; - } - - /* not support YUV420 input format yet */ - dev_dbg(csi_dev->dev, "Select YUV422 as default input format of CSI.\n"); - return CSI_INPUT_FORMAT_YUV422; -} - -static enum csi_output_fmt -get_csi_output_format(struct sun6i_csi_device *csi_dev, u32 pixformat, - u32 field) -{ - bool buf_interlaced = false; - - if (field == V4L2_FIELD_INTERLACED - || field == V4L2_FIELD_INTERLACED_TB - || field == V4L2_FIELD_INTERLACED_BT) - buf_interlaced = true; - - switch (pixformat) { - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - return buf_interlaced ? CSI_FRAME_RAW_10 : CSI_FIELD_RAW_10; - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - return buf_interlaced ? CSI_FRAME_RAW_12 : CSI_FIELD_RAW_12; - - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; - - case V4L2_PIX_FMT_NV12_16L16: - return buf_interlaced ? CSI_FRAME_MB_YUV420 : - CSI_FIELD_MB_YUV420; - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - return buf_interlaced ? CSI_FRAME_UV_CB_YUV420 : - CSI_FIELD_UV_CB_YUV420; - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - return buf_interlaced ? CSI_FRAME_PLANAR_YUV420 : - CSI_FIELD_PLANAR_YUV420; - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - return buf_interlaced ? CSI_FRAME_UV_CB_YUV422 : - CSI_FIELD_UV_CB_YUV422; - case V4L2_PIX_FMT_YUV422P: - return buf_interlaced ? CSI_FRAME_PLANAR_YUV422 : - CSI_FIELD_PLANAR_YUV422; - - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB565X: - return buf_interlaced ? CSI_FRAME_RGB565 : CSI_FIELD_RGB565; - - case V4L2_PIX_FMT_JPEG: - return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; - - default: - dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x\n", pixformat); - break; - } - - return CSI_FIELD_RAW_8; -} - -static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_device *csi_dev, - u32 mbus_code, u32 pixformat) -{ - /* Input sequence does not apply to non-YUV formats */ - if ((mbus_code & 0xF000) != 0x2000) - return 0; - - switch (pixformat) { - case V4L2_PIX_FMT_NV12_16L16: - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YUV422P: - switch (mbus_code) { - case MEDIA_BUS_FMT_UYVY8_2X8: - case MEDIA_BUS_FMT_UYVY8_1X16: - return CSI_INPUT_SEQ_UYVY; - case MEDIA_BUS_FMT_VYUY8_2X8: - case MEDIA_BUS_FMT_VYUY8_1X16: - return CSI_INPUT_SEQ_VYUY; - case MEDIA_BUS_FMT_YUYV8_2X8: - case MEDIA_BUS_FMT_YUYV8_1X16: - return CSI_INPUT_SEQ_YUYV; - case MEDIA_BUS_FMT_YVYU8_1X16: - case MEDIA_BUS_FMT_YVYU8_2X8: - return CSI_INPUT_SEQ_YVYU; - default: - dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", - mbus_code); - break; - } - break; - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV61: - case V4L2_PIX_FMT_YVU420: - switch (mbus_code) { - case MEDIA_BUS_FMT_UYVY8_2X8: - case MEDIA_BUS_FMT_UYVY8_1X16: - return CSI_INPUT_SEQ_VYUY; - case MEDIA_BUS_FMT_VYUY8_2X8: - case MEDIA_BUS_FMT_VYUY8_1X16: - return CSI_INPUT_SEQ_UYVY; - case MEDIA_BUS_FMT_YUYV8_2X8: - case MEDIA_BUS_FMT_YUYV8_1X16: - return CSI_INPUT_SEQ_YVYU; - case MEDIA_BUS_FMT_YVYU8_1X16: - case MEDIA_BUS_FMT_YVYU8_2X8: - return CSI_INPUT_SEQ_YUYV; - default: - dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", - mbus_code); - break; - } - break; - - case V4L2_PIX_FMT_YUYV: - return CSI_INPUT_SEQ_YUYV; - - default: - dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x, defaulting to YUYV\n", - pixformat); - break; - } - - return CSI_INPUT_SEQ_YUYV; -} - -static void sun6i_csi_setup_bus(struct sun6i_csi_device *csi_dev) -{ - struct v4l2_fwnode_endpoint *endpoint = - &csi_dev->bridge.source->endpoint; - struct sun6i_csi_config *config = &csi_dev->config; - unsigned char bus_width; - u32 flags; - u32 cfg = 0; - bool input_interlaced = false; - - if (config->field == V4L2_FIELD_INTERLACED - || config->field == V4L2_FIELD_INTERLACED_TB - || config->field == V4L2_FIELD_INTERLACED_BT) - input_interlaced = true; - - bus_width = endpoint->bus.parallel.bus_width; - - if (input_interlaced) - cfg |= SUN6I_CSI_IF_CFG_SRC_TYPE_INTERLACED | - SUN6I_CSI_IF_CFG_FIELD_DT_PCLK_SHIFT(1) | - SUN6I_CSI_IF_CFG_FIELD_DT_FIELD_VSYNC; - else - cfg |= SUN6I_CSI_IF_CFG_SRC_TYPE_PROGRESSIVE; - - switch (endpoint->bus_type) { - case V4L2_MBUS_PARALLEL: - cfg |= SUN6I_CSI_IF_CFG_IF_CSI; - - flags = endpoint->bus.parallel.flags; - - if (bus_width == 16) - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_COMBINED; - else - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_RAW; - - if (flags & V4L2_MBUS_FIELD_EVEN_LOW) - cfg |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; - else - cfg |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; - - if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) - cfg |= SUN6I_CSI_IF_CFG_VREF_POL_NEGATIVE; - else - cfg |= SUN6I_CSI_IF_CFG_VREF_POL_POSITIVE; - - if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) - cfg |= SUN6I_CSI_IF_CFG_HREF_POL_NEGATIVE; - else - cfg |= SUN6I_CSI_IF_CFG_HREF_POL_POSITIVE; - - if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; - else - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; - break; - case V4L2_MBUS_BT656: - cfg |= SUN6I_CSI_IF_CFG_IF_CSI; - - flags = endpoint->bus.parallel.flags; - - if (bus_width == 16) - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_BT1120; - else - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_BT656; - - if (flags & V4L2_MBUS_FIELD_EVEN_LOW) - cfg |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; - else - cfg |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; - - if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; - else - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; - break; - default: - dev_warn(csi_dev->dev, "Unsupported bus type: %d\n", - endpoint->bus_type); - break; - } - - switch (bus_width) { - case 8: - cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_8; - break; - case 10: - cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_10; - break; - case 12: - cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_12; - break; - case 16: /* No need to configure DATA_WIDTH for 16bit */ - break; - default: - dev_warn(csi_dev->dev, "Unsupported bus width: %u\n", bus_width); - break; - } - - regmap_write(csi_dev->regmap, SUN6I_CSI_IF_CFG_REG, cfg); -} - -static void sun6i_csi_set_format(struct sun6i_csi_device *csi_dev) -{ - struct sun6i_csi_config *config = &csi_dev->config; - u32 cfg = 0; - u32 val; - - val = get_csi_input_format(csi_dev, config->code, - config->pixelformat); - cfg |= SUN6I_CSI_CH_CFG_INPUT_FMT(val); - - val = get_csi_output_format(csi_dev, config->pixelformat, - config->field); - cfg |= SUN6I_CSI_CH_CFG_OUTPUT_FMT(val); - - val = get_csi_input_seq(csi_dev, config->code, - config->pixelformat); - cfg |= SUN6I_CSI_CH_CFG_INPUT_YUV_SEQ(val); - - if (config->field == V4L2_FIELD_TOP) - cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD0; - else if (config->field == V4L2_FIELD_BOTTOM) - cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD1; - else - cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_EITHER; - - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_CFG_REG, cfg); -} - -static void sun6i_csi_set_window(struct sun6i_csi_device *csi_dev) -{ - struct sun6i_csi_config *config = &csi_dev->config; - u32 bytesperline_y; - u32 bytesperline_c; - u32 width = config->width; - u32 height = config->height; - u32 hor_len = width; - - switch (config->pixelformat) { - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - dev_dbg(csi_dev->dev, - "Horizontal length should be 2 times of width for packed YUV formats!\n"); - hor_len = width * 2; - break; - default: - break; - } - - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_HSIZE_REG, - SUN6I_CSI_CH_HSIZE_LEN(hor_len) | - SUN6I_CSI_CH_HSIZE_START(0)); - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_VSIZE_REG, - SUN6I_CSI_CH_VSIZE_LEN(height) | - SUN6I_CSI_CH_VSIZE_START(0)); - - switch (config->pixelformat) { - case V4L2_PIX_FMT_NV12_16L16: - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - bytesperline_y = width; - bytesperline_c = width; - break; - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - bytesperline_y = width; - bytesperline_c = width / 2; - break; - case V4L2_PIX_FMT_YUV422P: - bytesperline_y = width; - bytesperline_c = width / 2; - break; - default: /* raw */ - dev_dbg(csi_dev->dev, - "Calculating pixelformat(0x%x)'s bytesperline as a packed format\n", - config->pixelformat); - bytesperline_y = (sun6i_csi_get_bpp(config->pixelformat) * - config->width) / 8; - bytesperline_c = 0; - break; - } - - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_BUF_LEN_REG, - SUN6I_CSI_CH_BUF_LEN_CHROMA_LINE(bytesperline_c) | - SUN6I_CSI_CH_BUF_LEN_LUMA_LINE(bytesperline_y)); -} - -int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, - struct sun6i_csi_config *config) -{ - if (!config) - return -EINVAL; - - memcpy(&csi_dev->config, config, sizeof(csi_dev->config)); - - sun6i_csi_setup_bus(csi_dev); - sun6i_csi_set_format(csi_dev); - sun6i_csi_set_window(csi_dev); - - return 0; -} - /* Media */ static const struct media_device_ops sun6i_csi_media_ops = { diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index 0271587e8520..c37bbab93cd5 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -28,22 +28,6 @@ struct sun6i_csi_buffer { struct list_head list; }; -/** - * struct sun6i_csi_config - configs for sun6i csi - * @pixelformat: v4l2 pixel format (V4L2_PIX_FMT_*) - * @code: media bus format code (MEDIA_BUS_FMT_*) - * @field: used interlacing type (enum v4l2_field) - * @width: frame width - * @height: frame height - */ -struct sun6i_csi_config { - u32 pixelformat; - u32 code; - u32 field; - u32 width; - u32 height; -}; - struct sun6i_csi_v4l2 { struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; @@ -53,7 +37,6 @@ struct sun6i_csi_v4l2 { struct sun6i_csi_device { struct device *dev; - struct sun6i_csi_config config; struct sun6i_csi_v4l2 v4l2; struct sun6i_csi_bridge bridge; struct sun6i_csi_capture capture; @@ -74,14 +57,6 @@ struct sun6i_csi_device { bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev, u32 pixformat, u32 mbus_code); -/** - * sun6i_csi_update_config() - update the csi register settings - * @csi: pointer to the csi - * @config: see struct sun6i_csi_config - */ -int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, - struct sun6i_csi_config *config); - /* get bpp form v4l2 pixformat */ static inline int sun6i_csi_get_bpp(unsigned int pixformat) { diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 05eb9aae2975..23b13b26b580 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -198,18 +198,366 @@ sun6i_csi_capture_buffer_configure(struct sun6i_csi_device *csi_dev, } } -static void sun6i_csi_capture_configure(struct sun6i_csi_device *csi_dev) +static enum csi_input_fmt get_csi_input_format(struct sun6i_csi_device *csi_dev, + u32 mbus_code, u32 pixformat) +{ + /* non-YUV */ + if ((mbus_code & 0xF000) != 0x2000) + return CSI_INPUT_FORMAT_RAW; + + switch (pixformat) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + return CSI_INPUT_FORMAT_RAW; + default: + break; + } + + /* not support YUV420 input format yet */ + dev_dbg(csi_dev->dev, "Select YUV422 as default input format of CSI.\n"); + return CSI_INPUT_FORMAT_YUV422; +} + +static enum csi_output_fmt +get_csi_output_format(struct sun6i_csi_device *csi_dev, u32 pixformat, + u32 field) +{ + bool buf_interlaced = false; + + if (field == V4L2_FIELD_INTERLACED + || field == V4L2_FIELD_INTERLACED_TB + || field == V4L2_FIELD_INTERLACED_BT) + buf_interlaced = true; + + switch (pixformat) { + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: + case V4L2_PIX_FMT_SRGGB8: + return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; + case V4L2_PIX_FMT_SBGGR10: + case V4L2_PIX_FMT_SGBRG10: + case V4L2_PIX_FMT_SGRBG10: + case V4L2_PIX_FMT_SRGGB10: + return buf_interlaced ? CSI_FRAME_RAW_10 : CSI_FIELD_RAW_10; + case V4L2_PIX_FMT_SBGGR12: + case V4L2_PIX_FMT_SGBRG12: + case V4L2_PIX_FMT_SGRBG12: + case V4L2_PIX_FMT_SRGGB12: + return buf_interlaced ? CSI_FRAME_RAW_12 : CSI_FIELD_RAW_12; + + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; + + case V4L2_PIX_FMT_NV12_16L16: + return buf_interlaced ? CSI_FRAME_MB_YUV420 : + CSI_FIELD_MB_YUV420; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + return buf_interlaced ? CSI_FRAME_UV_CB_YUV420 : + CSI_FIELD_UV_CB_YUV420; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + return buf_interlaced ? CSI_FRAME_PLANAR_YUV420 : + CSI_FIELD_PLANAR_YUV420; + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + return buf_interlaced ? CSI_FRAME_UV_CB_YUV422 : + CSI_FIELD_UV_CB_YUV422; + case V4L2_PIX_FMT_YUV422P: + return buf_interlaced ? CSI_FRAME_PLANAR_YUV422 : + CSI_FIELD_PLANAR_YUV422; + + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_RGB565X: + return buf_interlaced ? CSI_FRAME_RGB565 : CSI_FIELD_RGB565; + + case V4L2_PIX_FMT_JPEG: + return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; + + default: + dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x\n", pixformat); + break; + } + + return CSI_FIELD_RAW_8; +} + +static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_device *csi_dev, + u32 mbus_code, u32 pixformat) +{ + /* Input sequence does not apply to non-YUV formats */ + if ((mbus_code & 0xF000) != 0x2000) + return 0; + + switch (pixformat) { + case V4L2_PIX_FMT_NV12_16L16: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YUV422P: + switch (mbus_code) { + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_1X16: + return CSI_INPUT_SEQ_UYVY; + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_1X16: + return CSI_INPUT_SEQ_VYUY; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_1X16: + return CSI_INPUT_SEQ_YUYV; + case MEDIA_BUS_FMT_YVYU8_1X16: + case MEDIA_BUS_FMT_YVYU8_2X8: + return CSI_INPUT_SEQ_YVYU; + default: + dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", + mbus_code); + break; + } + break; + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_YVU420: + switch (mbus_code) { + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_1X16: + return CSI_INPUT_SEQ_VYUY; + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_1X16: + return CSI_INPUT_SEQ_UYVY; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_1X16: + return CSI_INPUT_SEQ_YVYU; + case MEDIA_BUS_FMT_YVYU8_1X16: + case MEDIA_BUS_FMT_YVYU8_2X8: + return CSI_INPUT_SEQ_YUYV; + default: + dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", + mbus_code); + break; + } + break; + + case V4L2_PIX_FMT_YUYV: + return CSI_INPUT_SEQ_YUYV; + + default: + dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x, defaulting to YUYV\n", + pixformat); + break; + } + + return CSI_INPUT_SEQ_YUYV; +} + +static void +sun6i_csi_capture_configure_interface(struct sun6i_csi_device *csi_dev) +{ + struct v4l2_fwnode_endpoint *endpoint = + &csi_dev->bridge.source->endpoint; + u32 pixelformat, field; + unsigned char bus_width; + u32 flags; + u32 cfg = 0; + bool input_interlaced = false; + + sun6i_csi_capture_format(csi_dev, &pixelformat, &field); + + if (field == V4L2_FIELD_INTERLACED || + field == V4L2_FIELD_INTERLACED_TB || + field == V4L2_FIELD_INTERLACED_BT) + input_interlaced = true; + + bus_width = endpoint->bus.parallel.bus_width; + + if (input_interlaced) + cfg |= SUN6I_CSI_IF_CFG_SRC_TYPE_INTERLACED | + SUN6I_CSI_IF_CFG_FIELD_DT_PCLK_SHIFT(1) | + SUN6I_CSI_IF_CFG_FIELD_DT_FIELD_VSYNC; + else + cfg |= SUN6I_CSI_IF_CFG_SRC_TYPE_PROGRESSIVE; + + switch (endpoint->bus_type) { + case V4L2_MBUS_PARALLEL: + cfg |= SUN6I_CSI_IF_CFG_IF_CSI; + + flags = endpoint->bus.parallel.flags; + + if (bus_width == 16) + cfg |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_COMBINED; + else + cfg |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_RAW; + + if (flags & V4L2_MBUS_FIELD_EVEN_LOW) + cfg |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; + else + cfg |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; + + if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) + cfg |= SUN6I_CSI_IF_CFG_VREF_POL_NEGATIVE; + else + cfg |= SUN6I_CSI_IF_CFG_VREF_POL_POSITIVE; + + if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) + cfg |= SUN6I_CSI_IF_CFG_HREF_POL_NEGATIVE; + else + cfg |= SUN6I_CSI_IF_CFG_HREF_POL_POSITIVE; + + if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) + cfg |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; + else + cfg |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; + break; + case V4L2_MBUS_BT656: + cfg |= SUN6I_CSI_IF_CFG_IF_CSI; + + flags = endpoint->bus.parallel.flags; + + if (bus_width == 16) + cfg |= SUN6I_CSI_IF_CFG_IF_CSI_BT1120; + else + cfg |= SUN6I_CSI_IF_CFG_IF_CSI_BT656; + + if (flags & V4L2_MBUS_FIELD_EVEN_LOW) + cfg |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; + else + cfg |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; + + if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) + cfg |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; + else + cfg |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; + break; + default: + dev_warn(csi_dev->dev, "Unsupported bus type: %d\n", + endpoint->bus_type); + break; + } + + switch (bus_width) { + case 8: + cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_8; + break; + case 10: + cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_10; + break; + case 12: + cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_12; + break; + case 16: /* No need to configure DATA_WIDTH for 16bit */ + break; + default: + dev_warn(csi_dev->dev, "Unsupported bus width: %u\n", bus_width); + break; + } + + regmap_write(csi_dev->regmap, SUN6I_CSI_IF_CFG_REG, cfg); +} + +static void sun6i_csi_capture_configure_format(struct sun6i_csi_device *csi_dev) { struct sun6i_csi_capture *capture = &csi_dev->capture; - struct sun6i_csi_config config = { 0 }; + u32 pixelformat, field; + u32 cfg = 0; + u32 val; + + sun6i_csi_capture_format(csi_dev, &pixelformat, &field); + + val = get_csi_input_format(csi_dev, capture->mbus_code, pixelformat); + cfg |= SUN6I_CSI_CH_CFG_INPUT_FMT(val); + + val = get_csi_output_format(csi_dev, pixelformat, field); + cfg |= SUN6I_CSI_CH_CFG_OUTPUT_FMT(val); + + val = get_csi_input_seq(csi_dev, capture->mbus_code, pixelformat); + cfg |= SUN6I_CSI_CH_CFG_INPUT_YUV_SEQ(val); + + if (field == V4L2_FIELD_TOP) + cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD0; + else if (field == V4L2_FIELD_BOTTOM) + cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD1; + else + cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_EITHER; + + regmap_write(csi_dev->regmap, SUN6I_CSI_CH_CFG_REG, cfg); +} - config.pixelformat = capture->format.fmt.pix.pixelformat; - config.code = capture->mbus_code; - config.field = capture->format.fmt.pix.field; - config.width = capture->format.fmt.pix.width; - config.height = capture->format.fmt.pix.height; +static void sun6i_csi_capture_configure_window(struct sun6i_csi_device *csi_dev) +{ + u32 pixelformat, field; + u32 width, height; + u32 bytesperline_y; + u32 bytesperline_c; + u32 hor_len; + + sun6i_csi_capture_dimensions(csi_dev, &width, &height); + sun6i_csi_capture_format(csi_dev, &pixelformat, &field); + + hor_len = width; + + switch (pixelformat) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + dev_dbg(csi_dev->dev, + "Horizontal length should be 2 times of width for packed YUV formats!\n"); + hor_len = width * 2; + break; + default: + break; + } + + regmap_write(csi_dev->regmap, SUN6I_CSI_CH_HSIZE_REG, + SUN6I_CSI_CH_HSIZE_LEN(hor_len) | + SUN6I_CSI_CH_HSIZE_START(0)); + regmap_write(csi_dev->regmap, SUN6I_CSI_CH_VSIZE_REG, + SUN6I_CSI_CH_VSIZE_LEN(height) | + SUN6I_CSI_CH_VSIZE_START(0)); + + switch (pixelformat) { + case V4L2_PIX_FMT_NV12_16L16: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + bytesperline_y = width; + bytesperline_c = width; + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + bytesperline_y = width; + bytesperline_c = width / 2; + break; + case V4L2_PIX_FMT_YUV422P: + bytesperline_y = width; + bytesperline_c = width / 2; + break; + default: /* raw */ + dev_dbg(csi_dev->dev, + "Calculating pixelformat(0x%x)'s bytesperline as a packed format\n", + pixelformat); + bytesperline_y = (sun6i_csi_get_bpp(pixelformat) * + width) / 8; + bytesperline_c = 0; + break; + } + + regmap_write(csi_dev->regmap, SUN6I_CSI_CH_BUF_LEN_REG, + SUN6I_CSI_CH_BUF_LEN_CHROMA_LINE(bytesperline_c) | + SUN6I_CSI_CH_BUF_LEN_LUMA_LINE(bytesperline_y)); +} - sun6i_csi_update_config(csi_dev, &config); +static void sun6i_csi_capture_configure(struct sun6i_csi_device *csi_dev) +{ + sun6i_csi_capture_configure_interface(csi_dev); + sun6i_csi_capture_configure_format(csi_dev); + sun6i_csi_capture_configure_window(csi_dev); } /* State */ From patchwork Sat Feb 5 18:54:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540155 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E396C433FE for ; Sat, 5 Feb 2022 18:57:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381811AbiBES5a (ORCPT ); Sat, 5 Feb 2022 13:57:30 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:39013 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239403AbiBESzt (ORCPT ); Sat, 5 Feb 2022 13:55:49 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id BC4B5240010; Sat, 5 Feb 2022 18:55:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087348; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h75JqJgq6QG+QOajI+uXIxRh4Nj5dGBymygUtKmDRes=; b=JZzyEEQE91vY0aTTIZs5rZcxQDqtAH20J36gTZWsh2QwLca6y5yIY8WGY/o9R1gKx9gzO/ MsfPl91BGIxchRs9ARg8MjkM7QTHsN6yy8gwpP8pLg5mzJageBnvNaZYmagsyqj+K3gm7+ vOsSablNoBhsHHjBUmv9arVDe5toKXH+UNFMNr0SNgCnt7PpmI09Cqpz37loFoCVSvzBjZ jlK/DRN52VocOG74Oqw911gR2se7P4FtqzRnS+FwXlRPLcAovQQDm7zHontyyQM9xLWgpJ e8xxFAkxcc23j6b3O77MbmTREs+xwtuplWTPUHXXVqf6VAr6qKibg1cq24OoeA== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 40/66] media: sun6i-csi: Remove custom format helper and rework configure Date: Sat, 5 Feb 2022 19:54:03 +0100 Message-Id: <20220205185429.2278860-41-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Remove the custom sun6i_csi_get_bpp helper in favor of common v4l2 infrastructure and rework the related window configuration code. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 49 ------------- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 70 +++++++++---------- 2 files changed, 35 insertions(+), 84 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index c37bbab93cd5..c687213924d4 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -57,55 +57,6 @@ struct sun6i_csi_device { bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev, u32 pixformat, u32 mbus_code); -/* get bpp form v4l2 pixformat */ -static inline int sun6i_csi_get_bpp(unsigned int pixformat) -{ - switch (pixformat) { - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - case V4L2_PIX_FMT_JPEG: - return 8; - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - return 10; - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - case V4L2_PIX_FMT_NV12_16L16: - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - return 12; - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - case V4L2_PIX_FMT_YUV422P: - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB565X: - return 16; - case V4L2_PIX_FMT_RGB24: - case V4L2_PIX_FMT_BGR24: - return 24; - case V4L2_PIX_FMT_RGB32: - case V4L2_PIX_FMT_BGR32: - return 32; - default: - WARN(1, "Unsupported pixformat: 0x%x\n", pixformat); - break; - } - - return 0; -} - int sun6i_csi_v4l2_complete(struct sun6i_csi_device *csi_dev); #endif /* __SUN6I_CSI_H__ */ diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 9c8b33c7e59c..f977b89dcea2 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -483,68 +483,68 @@ static void sun6i_csi_capture_configure_format(struct sun6i_csi_device *csi_dev) static void sun6i_csi_capture_configure_window(struct sun6i_csi_device *csi_dev) { + struct regmap *regmap = csi_dev->regmap; + const struct v4l2_format_info *info; + u32 hsize_len, vsize_len; + u32 luma_line, chroma_line = 0; u32 pixelformat, field; u32 width, height; - u32 bytesperline_y; - u32 bytesperline_c; - u32 hor_len; sun6i_csi_capture_dimensions(csi_dev, &width, &height); sun6i_csi_capture_format(csi_dev, &pixelformat, &field); - hor_len = width; + hsize_len = width; + vsize_len = height; switch (pixelformat) { case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YVYU: case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_VYUY: - dev_dbg(csi_dev->dev, - "Horizontal length should be 2 times of width for packed YUV formats!\n"); - hor_len = width * 2; + /* + * Horizontal length should be 2 times of width for packed + * YUV formats. + */ + hsize_len *= 2; break; default: break; } - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_HSIZE_REG, - SUN6I_CSI_CH_HSIZE_LEN(hor_len) | + regmap_write(regmap, SUN6I_CSI_CH_HSIZE_REG, + SUN6I_CSI_CH_HSIZE_LEN(hsize_len) | SUN6I_CSI_CH_HSIZE_START(0)); - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_VSIZE_REG, - SUN6I_CSI_CH_VSIZE_LEN(height) | + + regmap_write(regmap, SUN6I_CSI_CH_VSIZE_REG, + SUN6I_CSI_CH_VSIZE_LEN(vsize_len) | SUN6I_CSI_CH_VSIZE_START(0)); switch (pixelformat) { - case V4L2_PIX_FMT_NV12_16L16: - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - bytesperline_y = width; - bytesperline_c = width; + case V4L2_PIX_FMT_RGB565X: + luma_line = width * 2; break; - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - bytesperline_y = width; - bytesperline_c = width / 2; + case V4L2_PIX_FMT_NV12_16L16: + luma_line = width; + chroma_line = width; break; - case V4L2_PIX_FMT_YUV422P: - bytesperline_y = width; - bytesperline_c = width / 2; + case V4L2_PIX_FMT_JPEG: + luma_line = width; break; - default: /* raw */ - dev_dbg(csi_dev->dev, - "Calculating pixelformat(0x%x)'s bytesperline as a packed format\n", - pixelformat); - bytesperline_y = (sun6i_csi_get_bpp(pixelformat) * - width) / 8; - bytesperline_c = 0; + default: + info = v4l2_format_info(pixelformat); + if (WARN_ON(!info)) + return; + + luma_line = width * info->bpp[0]; + + if (info->comp_planes > 1) + chroma_line = width * info->bpp[1] / info->hdiv; break; } - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_BUF_LEN_REG, - SUN6I_CSI_CH_BUF_LEN_CHROMA_LINE(bytesperline_c) | - SUN6I_CSI_CH_BUF_LEN_LUMA_LINE(bytesperline_y)); + regmap_write(regmap, SUN6I_CSI_CH_BUF_LEN_REG, + SUN6I_CSI_CH_BUF_LEN_CHROMA_LINE(chroma_line) | + SUN6I_CSI_CH_BUF_LEN_LUMA_LINE(luma_line)); } static void sun6i_csi_capture_configure(struct sun6i_csi_device *csi_dev) From patchwork Sat Feb 5 18:54:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540153 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6C56C433F5 for ; Sat, 5 Feb 2022 18:57:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381284AbiBES5j (ORCPT ); Sat, 5 Feb 2022 13:57:39 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:40687 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381450AbiBESzz (ORCPT ); Sat, 5 Feb 2022 13:55:55 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id C5EF9240012; Sat, 5 Feb 2022 18:55:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087353; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EdcRxpJAbZcmTkOGjKP8A1FFYnpAyrcNRPpVMCBYHH4=; b=Pfs4BdiTqhmSUfJ4ToAOTxipkafxWmQUTN20G6HERyZqhaL0psEng5qSxJHeqkYwXl2Kno hUmhfNAqxSTM9Mwvpy7AhawqRt4NzsNqtPJ6kkUabGjxLdRtPVEw4bwrFB6x6gIBT9DYlb 3tjecIGYmjjqV74R+/WqJluU1enUu9u8MCMEgUpEUyeIS2n6wzYnzCsgnYd74cSKHhx7K9 NppIabJ61OR935aI6tWp5HY+J4bUwOKS8Pi9xSHfiRTTlXkzsbd2pEk0CDUMaeKIzhlK7A 4lYebD7RXjdOJZuSeueh29kexkxFyRwAD6dS1Eed16UO1viGxI+iofP7bMST9w== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 43/66] media: sun6i-csi: Tidy capture configure code Date: Sat, 5 Feb 2022 19:54:06 +0100 Message-Id: <20220205185429.2278860-44-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Some misc code cleanups and preparation for upcoming changes. Signed-off-by: Paul Kocialkowski --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 105 ++++++++---------- 1 file changed, 46 insertions(+), 59 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 12c02408d18e..726416d98c46 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -353,133 +353,120 @@ static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_device *csi_dev, static void sun6i_csi_capture_configure_interface(struct sun6i_csi_device *csi_dev) { + struct device *dev = csi_dev->dev; + struct regmap *regmap = csi_dev->regmap; struct v4l2_fwnode_endpoint *endpoint = &csi_dev->bridge.source->endpoint; + unsigned char bus_width = endpoint->bus.parallel.bus_width; + unsigned int flags = endpoint->bus.parallel.flags; u32 pixelformat, field; - unsigned char bus_width; - u32 flags; - u32 cfg = 0; - bool input_interlaced = false; + u32 value = SUN6I_CSI_IF_CFG_IF_CSI; sun6i_csi_capture_format(csi_dev, &pixelformat, &field); if (field == V4L2_FIELD_INTERLACED || field == V4L2_FIELD_INTERLACED_TB || field == V4L2_FIELD_INTERLACED_BT) - input_interlaced = true; - - bus_width = endpoint->bus.parallel.bus_width; - - if (input_interlaced) - cfg |= SUN6I_CSI_IF_CFG_SRC_TYPE_INTERLACED | - SUN6I_CSI_IF_CFG_FIELD_DT_PCLK_SHIFT(1) | - SUN6I_CSI_IF_CFG_FIELD_DT_FIELD_VSYNC; + value |= SUN6I_CSI_IF_CFG_SRC_TYPE_INTERLACED | + SUN6I_CSI_IF_CFG_FIELD_DT_PCLK_SHIFT(1) | + SUN6I_CSI_IF_CFG_FIELD_DT_FIELD_VSYNC; else - cfg |= SUN6I_CSI_IF_CFG_SRC_TYPE_PROGRESSIVE; + value |= SUN6I_CSI_IF_CFG_SRC_TYPE_PROGRESSIVE; switch (endpoint->bus_type) { case V4L2_MBUS_PARALLEL: - cfg |= SUN6I_CSI_IF_CFG_IF_CSI; - - flags = endpoint->bus.parallel.flags; - if (bus_width == 16) - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_COMBINED; + value |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_COMBINED; else - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_RAW; + value |= SUN6I_CSI_IF_CFG_IF_CSI_YUV_RAW; if (flags & V4L2_MBUS_FIELD_EVEN_LOW) - cfg |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; + value |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; else - cfg |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; + value |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) - cfg |= SUN6I_CSI_IF_CFG_VREF_POL_NEGATIVE; + value |= SUN6I_CSI_IF_CFG_VREF_POL_NEGATIVE; else - cfg |= SUN6I_CSI_IF_CFG_VREF_POL_POSITIVE; + value |= SUN6I_CSI_IF_CFG_VREF_POL_POSITIVE; if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) - cfg |= SUN6I_CSI_IF_CFG_HREF_POL_NEGATIVE; + value |= SUN6I_CSI_IF_CFG_HREF_POL_NEGATIVE; else - cfg |= SUN6I_CSI_IF_CFG_HREF_POL_POSITIVE; + value |= SUN6I_CSI_IF_CFG_HREF_POL_POSITIVE; if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; + value |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; else - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; + value |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; break; case V4L2_MBUS_BT656: - cfg |= SUN6I_CSI_IF_CFG_IF_CSI; - - flags = endpoint->bus.parallel.flags; - if (bus_width == 16) - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_BT1120; + value |= SUN6I_CSI_IF_CFG_IF_CSI_BT1120; else - cfg |= SUN6I_CSI_IF_CFG_IF_CSI_BT656; + value |= SUN6I_CSI_IF_CFG_IF_CSI_BT656; if (flags & V4L2_MBUS_FIELD_EVEN_LOW) - cfg |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; + value |= SUN6I_CSI_IF_CFG_FIELD_NEGATIVE; else - cfg |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; + value |= SUN6I_CSI_IF_CFG_FIELD_POSITIVE; if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; + value |= SUN6I_CSI_IF_CFG_CLK_POL_RISING; else - cfg |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; + value |= SUN6I_CSI_IF_CFG_CLK_POL_FALLING; break; default: - dev_warn(csi_dev->dev, "Unsupported bus type: %d\n", - endpoint->bus_type); + dev_warn(dev, "unsupported bus type: %d\n", endpoint->bus_type); break; } switch (bus_width) { case 8: - cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_8; + /* 16-bit YUV formats use a doubled width in 8-bit mode. */ + case 16: + value |= SUN6I_CSI_IF_CFG_DATA_WIDTH_8; break; case 10: - cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_10; + value |= SUN6I_CSI_IF_CFG_DATA_WIDTH_10; break; case 12: - cfg |= SUN6I_CSI_IF_CFG_DATA_WIDTH_12; - break; - case 16: /* No need to configure DATA_WIDTH for 16bit */ + value |= SUN6I_CSI_IF_CFG_DATA_WIDTH_12; break; default: - dev_warn(csi_dev->dev, "Unsupported bus width: %u\n", bus_width); + dev_warn(dev, "unsupported bus width: %u\n", bus_width); break; } - regmap_write(csi_dev->regmap, SUN6I_CSI_IF_CFG_REG, cfg); + regmap_write(regmap, SUN6I_CSI_IF_CFG_REG, value); } static void sun6i_csi_capture_configure_format(struct sun6i_csi_device *csi_dev) { + struct regmap *regmap = csi_dev->regmap; u32 mbus_code, pixelformat, field; - u32 cfg = 0; - u32 val; + u8 input_format, input_yuv_seq, output_format; + u32 value = 0; sun6i_csi_capture_format(csi_dev, &pixelformat, &field); sun6i_csi_bridge_format(csi_dev, &mbus_code, NULL); - val = get_csi_input_format(csi_dev, mbus_code, pixelformat); - cfg |= SUN6I_CSI_CH_CFG_INPUT_FMT(val); - - val = get_csi_output_format(csi_dev, pixelformat, field); - cfg |= SUN6I_CSI_CH_CFG_OUTPUT_FMT(val); + input_format = get_csi_input_format(csi_dev, mbus_code, pixelformat); + input_yuv_seq = get_csi_input_seq(csi_dev, mbus_code, pixelformat); + output_format = get_csi_output_format(csi_dev, pixelformat, field); - val = get_csi_input_seq(csi_dev, mbus_code, pixelformat); - cfg |= SUN6I_CSI_CH_CFG_INPUT_YUV_SEQ(val); + value |= SUN6I_CSI_CH_CFG_OUTPUT_FMT(output_format); + value |= SUN6I_CSI_CH_CFG_INPUT_FMT(input_format); + value |= SUN6I_CSI_CH_CFG_INPUT_YUV_SEQ(input_yuv_seq); if (field == V4L2_FIELD_TOP) - cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD0; + value |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD0; else if (field == V4L2_FIELD_BOTTOM) - cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD1; + value |= SUN6I_CSI_CH_CFG_FIELD_SEL_FIELD1; else - cfg |= SUN6I_CSI_CH_CFG_FIELD_SEL_EITHER; + value |= SUN6I_CSI_CH_CFG_FIELD_SEL_EITHER; - regmap_write(csi_dev->regmap, SUN6I_CSI_CH_CFG_REG, cfg); + regmap_write(regmap, SUN6I_CSI_CH_CFG_REG, value); } static void sun6i_csi_capture_configure_window(struct sun6i_csi_device *csi_dev) From patchwork Sat Feb 5 18:54:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540148 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B594BC433FE for ; Sat, 5 Feb 2022 18:58:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381673AbiBES6n (ORCPT ); Sat, 5 Feb 2022 13:58:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381688AbiBES4o (ORCPT ); Sat, 5 Feb 2022 13:56:44 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 543F9C043184; Sat, 5 Feb 2022 10:55:58 -0800 (PST) Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 05E17240019; Sat, 5 Feb 2022 18:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087356; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3pZo7CxGMUTpS8CVYK3FcpDVneJImTFLbxbcBcVuMPM=; b=D9kN4GUEwLQkqHmYTTIIvVyzpKMYn+Ak44xrbBmd3hhGqxgHHAp4uIYFGvv+5GsSyrjGSw KGw8aywE6tFOQb39PfSMcbdudsBuL1OmArqytd2qZ16T1mLpX6W3yJGTu6pnAu17okbeIv HUMk0iVu31aMbdR5QtTy3h+/iAs27DYKWiZyZHhO2MsN+oZM0AD3pDhEhOXzjjW33iR3BR Vy2JI6bqUyQ5LwYisSnxkLC9e0G2I0Vqqx9yzAFsBrdA/MFQLZr+PabOo7staxf+x5cOlq Sgqbz9IBSEqDBQs9XwACsLwPMlfKyIgbEjV8y199hulb5xBarLv+9gVORcNaGA== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 45/66] media: sun6i-csi: Introduce capture format structure, list and helper Date: Sat, 5 Feb 2022 19:54:08 +0100 Message-Id: <20220205185429.2278860-46-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add a table that describes each pixel format and associated output register configuration with necessary tweaks. It will be used later on to configure the hardware. Signed-off-by: Paul Kocialkowski --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 199 ++++++++++++++---- .../sunxi/sun6i-csi/sun6i_csi_capture.h | 12 ++ 2 files changed, 175 insertions(+), 36 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 726416d98c46..8e71c81cd54f 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -60,45 +60,171 @@ sun6i_csi_capture_remote_subdev(struct sun6i_csi_capture *capture, u32 *pad) /* Format */ -static const u32 sun6i_csi_capture_formats[] = { - V4L2_PIX_FMT_SBGGR8, - V4L2_PIX_FMT_SGBRG8, - V4L2_PIX_FMT_SGRBG8, - V4L2_PIX_FMT_SRGGB8, - V4L2_PIX_FMT_SBGGR10, - V4L2_PIX_FMT_SGBRG10, - V4L2_PIX_FMT_SGRBG10, - V4L2_PIX_FMT_SRGGB10, - V4L2_PIX_FMT_SBGGR12, - V4L2_PIX_FMT_SGBRG12, - V4L2_PIX_FMT_SGRBG12, - V4L2_PIX_FMT_SRGGB12, - V4L2_PIX_FMT_YUYV, - V4L2_PIX_FMT_YVYU, - V4L2_PIX_FMT_UYVY, - V4L2_PIX_FMT_VYUY, - V4L2_PIX_FMT_NV12_16L16, - V4L2_PIX_FMT_NV12, - V4L2_PIX_FMT_NV21, - V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_YVU420, - V4L2_PIX_FMT_NV16, - V4L2_PIX_FMT_NV61, - V4L2_PIX_FMT_YUV422P, - V4L2_PIX_FMT_RGB565, - V4L2_PIX_FMT_RGB565X, - V4L2_PIX_FMT_JPEG, +static const struct sun6i_csi_capture_format sun6i_csi_capture_formats[] = { + /* Bayer */ + { + .pixelformat = V4L2_PIX_FMT_SBGGR8, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + }, + { + .pixelformat = V4L2_PIX_FMT_SGBRG8, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + }, + { + .pixelformat = V4L2_PIX_FMT_SGRBG8, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + }, + { + .pixelformat = V4L2_PIX_FMT_SRGGB8, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + }, + { + .pixelformat = V4L2_PIX_FMT_SBGGR10, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10, + }, + { + .pixelformat = V4L2_PIX_FMT_SGBRG10, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10, + }, + { + .pixelformat = V4L2_PIX_FMT_SGRBG10, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10, + }, + { + .pixelformat = V4L2_PIX_FMT_SRGGB10, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10, + }, + { + .pixelformat = V4L2_PIX_FMT_SBGGR12, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12, + }, + { + .pixelformat = V4L2_PIX_FMT_SGBRG12, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12, + }, + { + .pixelformat = V4L2_PIX_FMT_SGRBG12, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12, + }, + { + .pixelformat = V4L2_PIX_FMT_SRGGB12, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12, + }, + /* RGB */ + { + .pixelformat = V4L2_PIX_FMT_RGB565, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RGB565, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RGB565, + }, + { + .pixelformat = V4L2_PIX_FMT_RGB565X, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RGB565, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RGB565, + }, + /* YUV422 */ + { + .pixelformat = V4L2_PIX_FMT_YUYV, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + .input_format_raw = true, + .hsize_len_factor = 2, + }, + { + .pixelformat = V4L2_PIX_FMT_YVYU, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + .input_format_raw = true, + .hsize_len_factor = 2, + }, + { + .pixelformat = V4L2_PIX_FMT_UYVY, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + .input_format_raw = true, + .hsize_len_factor = 2, + }, + { + .pixelformat = V4L2_PIX_FMT_VYUY, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + .input_format_raw = true, + .hsize_len_factor = 2, + }, + { + .pixelformat = V4L2_PIX_FMT_NV16, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV422SP, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV422SP, + }, + { + .pixelformat = V4L2_PIX_FMT_NV61, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV422SP, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV422SP, + .input_yuv_seq_invert = true, + }, + { + .pixelformat = V4L2_PIX_FMT_YUV422P, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV422P, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV422P, + }, + /* YUV420 */ + { + .pixelformat = V4L2_PIX_FMT_NV12_16L16, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV420MB, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV420MB, + }, + { + .pixelformat = V4L2_PIX_FMT_NV12, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV420SP, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV420SP, + }, + { + .pixelformat = V4L2_PIX_FMT_NV21, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV420SP, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV420SP, + .input_yuv_seq_invert = true, + }, + + { + .pixelformat = V4L2_PIX_FMT_YUV420, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV420P, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV420P, + }, + { + .pixelformat = V4L2_PIX_FMT_YVU420, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV420P, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV420P, + .input_yuv_seq_invert = true, + }, + /* Compressed */ + { + .pixelformat = V4L2_PIX_FMT_JPEG, + .output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8, + .output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8, + }, }; -static bool sun6i_csi_capture_format_check(u32 format) +const +struct sun6i_csi_capture_format *sun6i_csi_capture_format_find(u32 pixelformat) { unsigned int i; for (i = 0; i < ARRAY_SIZE(sun6i_csi_capture_formats); i++) - if (sun6i_csi_capture_formats[i] == format) - return true; + if (sun6i_csi_capture_formats[i].pixelformat == pixelformat) + return &sun6i_csi_capture_formats[i]; - return false; + return NULL; } /* Capture */ @@ -820,8 +946,9 @@ static void sun6i_csi_capture_format_prepare(struct v4l2_format *format) &pix_format->height, SUN6I_CSI_CAPTURE_HEIGHT_MIN, SUN6I_CSI_CAPTURE_HEIGHT_MAX, 1, 0); - if (!sun6i_csi_capture_format_check(pix_format->pixelformat)) - pix_format->pixelformat = sun6i_csi_capture_formats[0]; + if (!sun6i_csi_capture_format_find(pix_format->pixelformat)) + pix_format->pixelformat = + sun6i_csi_capture_formats[0].pixelformat; width = pix_format->width; height = pix_format->height; @@ -872,7 +999,7 @@ static int sun6i_csi_capture_enum_fmt(struct file *file, void *private, if (index >= ARRAY_SIZE(sun6i_csi_capture_formats)) return -EINVAL; - fmtdesc->pixelformat = sun6i_csi_capture_formats[index]; + fmtdesc->pixelformat = sun6i_csi_capture_formats[index].pixelformat; return 0; } @@ -1144,7 +1271,7 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) /* V4L2 Format */ format->type = queue->type; - pix_format->pixelformat = sun6i_csi_capture_formats[0]; + pix_format->pixelformat = sun6i_csi_capture_formats[0].pixelformat; pix_format->width = 1280; pix_format->height = 720; pix_format->field = V4L2_FIELD_NONE; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h index 3b9759e1563d..4b1ff19edc2f 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h @@ -18,6 +18,15 @@ struct sun6i_csi_device; +struct sun6i_csi_capture_format { + u32 pixelformat; + u8 output_format_field; + u8 output_format_frame; + bool input_yuv_seq_invert; + bool input_format_raw; + u32 hsize_len_factor; +}; + #undef current struct sun6i_csi_capture_state { struct list_head queue; @@ -46,6 +55,9 @@ void sun6i_csi_capture_dimensions(struct sun6i_csi_device *csi_dev, void sun6i_csi_capture_format(struct sun6i_csi_device *csi_dev, u32 *pixelformat, u32 *field); +const +struct sun6i_csi_capture_format *sun6i_csi_capture_format_find(u32 pixelformat); + void sun6i_csi_capture_sync(struct sun6i_csi_device *csi_dev); void sun6i_csi_capture_frame_done(struct sun6i_csi_device *csi_dev); From patchwork Sat Feb 5 18:54:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540152 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F4BCC433F5 for ; Sat, 5 Feb 2022 18:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381194AbiBES55 (ORCPT ); Sat, 5 Feb 2022 13:57:57 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:39641 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234644AbiBESz7 (ORCPT ); Sat, 5 Feb 2022 13:55:59 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id A3FF3240003; Sat, 5 Feb 2022 18:55:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087358; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n3m3Og33Oaa0ifBzHUzds0NzafQ33b9Uc4yxcoylEos=; b=Hv1PwvwP2blMefIR+65AHAHxIwl791IZa7vdb4Ue9GN2DhTRULx6sjiob/b58t7EdpHWBO DcL6P/3qepEa5Zo0+mY6koecBuquH8YXQKJKhiZNjS915La9pq7v41P5lgnAOgdT6bcFgU HdDg22Qsz6iplRFDUO4NQMRJJpQMjbSddWFeI/8Yk4pl11EfYX4XGe54QW9VPvYgrMRTlM 1SwOIKl0f5o82R1eYhR73QLfwn2Ku73eokSBeJM+kW0jHaQL/WFIYOjXa3uBl496tFKXXs v251M87VU+JYYxOq4JJ/P7+RNlU+TsyZtdyI1Mqus3F9qoruwWLdQru5BR2pZw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 46/66] media: sun6i-csi: Configure registers from format tables Date: Sat, 5 Feb 2022 19:54:09 +0100 Message-Id: <20220205185429.2278860-47-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Switch over to using the static format table descriptions to configure registers. Rework the hardware configuration helpers to leverage information from the format structures and benefit from their logic. Remove the previous dedicated helpers. The intention is to make the interaction between the different formats and the hardware side more visible and clear. Signed-off-by: Paul Kocialkowski --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 210 +++--------------- .../platform/sunxi/sun6i-csi/sun6i_csi_reg.h | 55 ----- 2 files changed, 36 insertions(+), 229 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 8e71c81cd54f..1a5797454beb 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -319,163 +319,6 @@ sun6i_csi_capture_buffer_configure(struct sun6i_csi_device *csi_dev, } } -static enum csi_input_fmt get_csi_input_format(struct sun6i_csi_device *csi_dev, - u32 mbus_code, u32 pixformat) -{ - /* non-YUV */ - if ((mbus_code & 0xF000) != 0x2000) - return CSI_INPUT_FORMAT_RAW; - - switch (pixformat) { - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - return CSI_INPUT_FORMAT_RAW; - default: - break; - } - - /* not support YUV420 input format yet */ - dev_dbg(csi_dev->dev, "Select YUV422 as default input format of CSI.\n"); - return CSI_INPUT_FORMAT_YUV422; -} - -static enum csi_output_fmt -get_csi_output_format(struct sun6i_csi_device *csi_dev, u32 pixformat, - u32 field) -{ - bool buf_interlaced = false; - - if (field == V4L2_FIELD_INTERLACED - || field == V4L2_FIELD_INTERLACED_TB - || field == V4L2_FIELD_INTERLACED_BT) - buf_interlaced = true; - - switch (pixformat) { - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - return buf_interlaced ? CSI_FRAME_RAW_10 : CSI_FIELD_RAW_10; - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - return buf_interlaced ? CSI_FRAME_RAW_12 : CSI_FIELD_RAW_12; - - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; - - case V4L2_PIX_FMT_NV12_16L16: - return buf_interlaced ? CSI_FRAME_MB_YUV420 : - CSI_FIELD_MB_YUV420; - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - return buf_interlaced ? CSI_FRAME_UV_CB_YUV420 : - CSI_FIELD_UV_CB_YUV420; - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - return buf_interlaced ? CSI_FRAME_PLANAR_YUV420 : - CSI_FIELD_PLANAR_YUV420; - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - return buf_interlaced ? CSI_FRAME_UV_CB_YUV422 : - CSI_FIELD_UV_CB_YUV422; - case V4L2_PIX_FMT_YUV422P: - return buf_interlaced ? CSI_FRAME_PLANAR_YUV422 : - CSI_FIELD_PLANAR_YUV422; - - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_RGB565X: - return buf_interlaced ? CSI_FRAME_RGB565 : CSI_FIELD_RGB565; - - case V4L2_PIX_FMT_JPEG: - return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; - - default: - dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x\n", pixformat); - break; - } - - return CSI_FIELD_RAW_8; -} - -static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_device *csi_dev, - u32 mbus_code, u32 pixformat) -{ - /* Input sequence does not apply to non-YUV formats */ - if ((mbus_code & 0xF000) != 0x2000) - return 0; - - switch (pixformat) { - case V4L2_PIX_FMT_NV12_16L16: - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YUV422P: - switch (mbus_code) { - case MEDIA_BUS_FMT_UYVY8_2X8: - case MEDIA_BUS_FMT_UYVY8_1X16: - return CSI_INPUT_SEQ_UYVY; - case MEDIA_BUS_FMT_VYUY8_2X8: - case MEDIA_BUS_FMT_VYUY8_1X16: - return CSI_INPUT_SEQ_VYUY; - case MEDIA_BUS_FMT_YUYV8_2X8: - case MEDIA_BUS_FMT_YUYV8_1X16: - return CSI_INPUT_SEQ_YUYV; - case MEDIA_BUS_FMT_YVYU8_1X16: - case MEDIA_BUS_FMT_YVYU8_2X8: - return CSI_INPUT_SEQ_YVYU; - default: - dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", - mbus_code); - break; - } - break; - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV61: - case V4L2_PIX_FMT_YVU420: - switch (mbus_code) { - case MEDIA_BUS_FMT_UYVY8_2X8: - case MEDIA_BUS_FMT_UYVY8_1X16: - return CSI_INPUT_SEQ_VYUY; - case MEDIA_BUS_FMT_VYUY8_2X8: - case MEDIA_BUS_FMT_VYUY8_1X16: - return CSI_INPUT_SEQ_UYVY; - case MEDIA_BUS_FMT_YUYV8_2X8: - case MEDIA_BUS_FMT_YUYV8_1X16: - return CSI_INPUT_SEQ_YVYU; - case MEDIA_BUS_FMT_YVYU8_1X16: - case MEDIA_BUS_FMT_YVYU8_2X8: - return CSI_INPUT_SEQ_YUYV; - default: - dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", - mbus_code); - break; - } - break; - - case V4L2_PIX_FMT_YUYV: - return CSI_INPUT_SEQ_YUYV; - - default: - dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x, defaulting to YUYV\n", - pixformat); - break; - } - - return CSI_INPUT_SEQ_YUYV; -} - static void sun6i_csi_capture_configure_interface(struct sun6i_csi_device *csi_dev) { @@ -570,6 +413,8 @@ sun6i_csi_capture_configure_interface(struct sun6i_csi_device *csi_dev) static void sun6i_csi_capture_configure_format(struct sun6i_csi_device *csi_dev) { struct regmap *regmap = csi_dev->regmap; + const struct sun6i_csi_bridge_format *bridge_format; + const struct sun6i_csi_capture_format *capture_format; u32 mbus_code, pixelformat, field; u8 input_format, input_yuv_seq, output_format; u32 value = 0; @@ -577,9 +422,29 @@ static void sun6i_csi_capture_configure_format(struct sun6i_csi_device *csi_dev) sun6i_csi_capture_format(csi_dev, &pixelformat, &field); sun6i_csi_bridge_format(csi_dev, &mbus_code, NULL); - input_format = get_csi_input_format(csi_dev, mbus_code, pixelformat); - input_yuv_seq = get_csi_input_seq(csi_dev, mbus_code, pixelformat); - output_format = get_csi_output_format(csi_dev, pixelformat, field); + bridge_format = sun6i_csi_bridge_format_find(mbus_code); + if (WARN_ON(!bridge_format)) + return; + + input_format = bridge_format->input_format; + input_yuv_seq = bridge_format->input_yuv_seq; + + capture_format = sun6i_csi_capture_format_find(pixelformat); + if (WARN_ON(!capture_format)) + return; + + if (capture_format->input_format_raw) + input_format = SUN6I_CSI_INPUT_FMT_RAW; + + if (capture_format->input_yuv_seq_invert) + input_yuv_seq = bridge_format->input_yuv_seq_invert; + + if (field == V4L2_FIELD_INTERLACED || + field == V4L2_FIELD_INTERLACED_TB || + field == V4L2_FIELD_INTERLACED_BT) + output_format = capture_format->output_format_field; + else + output_format = capture_format->output_format_frame; value |= SUN6I_CSI_CH_CFG_OUTPUT_FMT(output_format); value |= SUN6I_CSI_CH_CFG_INPUT_FMT(input_format); @@ -598,6 +463,7 @@ static void sun6i_csi_capture_configure_format(struct sun6i_csi_device *csi_dev) static void sun6i_csi_capture_configure_window(struct sun6i_csi_device *csi_dev) { struct regmap *regmap = csi_dev->regmap; + const struct sun6i_csi_capture_format *format; const struct v4l2_format_info *info; u32 hsize_len, vsize_len; u32 luma_line, chroma_line = 0; @@ -607,23 +473,19 @@ static void sun6i_csi_capture_configure_window(struct sun6i_csi_device *csi_dev) sun6i_csi_capture_dimensions(csi_dev, &width, &height); sun6i_csi_capture_format(csi_dev, &pixelformat, &field); + format = sun6i_csi_capture_format_find(pixelformat); + if (WARN_ON(!format)) + return; + hsize_len = width; vsize_len = height; - switch (pixelformat) { - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - /* - * Horizontal length should be 2 times of width for packed - * YUV formats. - */ - hsize_len *= 2; - break; - default: - break; - } + /* + * When using 8-bit raw input/output (for packed YUV), we need to adapt + * the width to account for the difference in bpp when it's not 8-bit. + */ + if (format->hsize_len_factor) + hsize_len *= format->hsize_len_factor; regmap_write(regmap, SUN6I_CSI_CH_HSIZE_REG, SUN6I_CSI_CH_HSIZE_LEN(hsize_len) | diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_reg.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_reg.h index 9b0326d6ba3c..1e4a07f26d1d 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_reg.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_reg.h @@ -180,59 +180,4 @@ #define SUN6I_CSI_CH_FIFO_STAT_REG 0x98 #define SUN6I_CSI_CH_PCLK_STAT_REG 0x9c -/* - * csi input data format - */ -enum csi_input_fmt { - CSI_INPUT_FORMAT_RAW = 0, - CSI_INPUT_FORMAT_YUV422 = 3, - CSI_INPUT_FORMAT_YUV420 = 4, -}; - -/* - * csi output data format - */ -enum csi_output_fmt { - /* only when input format is RAW */ - CSI_FIELD_RAW_8 = 0, - CSI_FIELD_RAW_10 = 1, - CSI_FIELD_RAW_12 = 2, - CSI_FIELD_RGB565 = 4, - CSI_FIELD_RGB888 = 5, - CSI_FIELD_PRGB888 = 6, - CSI_FRAME_RAW_8 = 8, - CSI_FRAME_RAW_10 = 9, - CSI_FRAME_RAW_12 = 10, - CSI_FRAME_RGB565 = 12, - CSI_FRAME_RGB888 = 13, - CSI_FRAME_PRGB888 = 14, - - /* only when input format is YUV422 */ - CSI_FIELD_PLANAR_YUV422 = 0, - CSI_FIELD_PLANAR_YUV420 = 1, - CSI_FRAME_PLANAR_YUV420 = 2, - CSI_FRAME_PLANAR_YUV422 = 3, - CSI_FIELD_UV_CB_YUV422 = 4, - CSI_FIELD_UV_CB_YUV420 = 5, - CSI_FRAME_UV_CB_YUV420 = 6, - CSI_FRAME_UV_CB_YUV422 = 7, - CSI_FIELD_MB_YUV422 = 8, - CSI_FIELD_MB_YUV420 = 9, - CSI_FRAME_MB_YUV420 = 10, - CSI_FRAME_MB_YUV422 = 11, - CSI_FIELD_UV_CB_YUV422_10 = 12, - CSI_FIELD_UV_CB_YUV420_10 = 13, -}; - -/* - * csi YUV input data sequence - */ -enum csi_input_seq { - /* only when input format is YUV422 */ - CSI_INPUT_SEQ_YUYV = 0, - CSI_INPUT_SEQ_YVYU, - CSI_INPUT_SEQ_UYVY, - CSI_INPUT_SEQ_VYUY, -}; - #endif /* __SUN6I_CSI_REG_H__ */ From patchwork Sat Feb 5 18:54:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540147 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46F1EC433FE for ; Sat, 5 Feb 2022 18:58:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381354AbiBES6s (ORCPT ); Sat, 5 Feb 2022 13:58:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381383AbiBES4s (ORCPT ); Sat, 5 Feb 2022 13:56:48 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D1A4C03FEC7; Sat, 5 Feb 2022 10:56:01 -0800 (PST) Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 4CEB4240002; Sat, 5 Feb 2022 18:55:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087359; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3teMvj2/0J6vqS7vDs13BGjfypuWez4DHj0zODL6CDo=; b=oVE3bwIzAEg75wiSM891kwyPlir/edIS30QQql9jFFjb/8EUd9B2odJMglmvMoO6CG5Q9L ieY3mkxUdbJOTq2LRxnwkYF69fEDI0D5SZsdDFGuog7Jh5fJZf8na8Tkt4fZd1MJ2YwzoA kCvStHvp6y+LOauMjLzovFk/e3ckQtmgog1n4amOVRy1YCMaS5pa/DkrCkHTMXm1AI+svE 3+QCA+cfzo9Swks+b0ccYJtiiAIUD96jP2vsVOfHmSeR/qYnvomtggvOs8GkJlb6tW67gC VjfdsPpZ16OZAK5BAkl3NQk1cbFDD/NPZmhy+pFfA+3KUCKs2pKpfESrlTsokA== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 47/66] media: sun6i-csi: Introduce format match structure, list and helper Date: Sat, 5 Feb 2022 19:54:10 +0100 Message-Id: <20220205185429.2278860-48-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Introduce a list of mbus/pixel format combinations that need an exact match between the two sides. This is the case when using raw input configuration. The list will be used to replace the sun6i_csi_is_format_supported combinatory helper. Signed-off-by: Paul Kocialkowski --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 117 ++++++++++++++++++ .../sunxi/sun6i-csi/sun6i_csi_capture.h | 5 + 2 files changed, 122 insertions(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 1a5797454beb..91f2295cbdc6 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -227,6 +227,123 @@ struct sun6i_csi_capture_format *sun6i_csi_capture_format_find(u32 pixelformat) return NULL; } +/* RAW formats need an exact match between pixel and mbus formats. */ +static const +struct sun6i_csi_capture_format_match sun6i_csi_capture_format_matches[] = { + /* YUV420 */ + { + .pixelformat = V4L2_PIX_FMT_YUYV, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, + }, + { + .pixelformat = V4L2_PIX_FMT_YUYV, + .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16, + }, + { + .pixelformat = V4L2_PIX_FMT_YVYU, + .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, + }, + { + .pixelformat = V4L2_PIX_FMT_YVYU, + .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16, + }, + { + .pixelformat = V4L2_PIX_FMT_UYVY, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, + }, + { + .pixelformat = V4L2_PIX_FMT_UYVY, + .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, + }, + { + .pixelformat = V4L2_PIX_FMT_VYUY, + .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, + }, + { + .pixelformat = V4L2_PIX_FMT_VYUY, + .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16, + }, + /* RGB */ + { + .pixelformat = V4L2_PIX_FMT_RGB565, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, + }, + { + .pixelformat = V4L2_PIX_FMT_RGB565X, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_BE, + }, + /* Bayer */ + { + .pixelformat = V4L2_PIX_FMT_SBGGR8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + }, + { + .pixelformat = V4L2_PIX_FMT_SGBRG8, + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, + }, + { + .pixelformat = V4L2_PIX_FMT_SGRBG8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, + }, + { + .pixelformat = V4L2_PIX_FMT_SRGGB8, + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, + }, + { + .pixelformat = V4L2_PIX_FMT_SBGGR10, + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + }, + { + .pixelformat = V4L2_PIX_FMT_SGBRG10, + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + }, + { + .pixelformat = V4L2_PIX_FMT_SGRBG10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + }, + { + .pixelformat = V4L2_PIX_FMT_SRGGB10, + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + }, + { + .pixelformat = V4L2_PIX_FMT_SBGGR12, + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + }, + { + .pixelformat = V4L2_PIX_FMT_SGBRG12, + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, + }, + { + .pixelformat = V4L2_PIX_FMT_SGRBG12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, + }, + { + .pixelformat = V4L2_PIX_FMT_SRGGB12, + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, + }, + /* Compressed */ + { + .pixelformat = V4L2_PIX_FMT_JPEG, + .mbus_code = MEDIA_BUS_FMT_JPEG_1X8, + }, +}; + +static bool sun6i_csi_capture_format_match(u32 pixelformat, u32 mbus_code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sun6i_csi_capture_format_matches); i++) { + const struct sun6i_csi_capture_format_match *match = + &sun6i_csi_capture_format_matches[i]; + + if (match->pixelformat == pixelformat && + match->mbus_code == mbus_code) + return true; + } + + return false; +} + /* Capture */ static void sun6i_csi_capture_irq_enable(struct sun6i_csi_device *csi_dev) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h index 4b1ff19edc2f..2605b16f091c 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h @@ -27,6 +27,11 @@ struct sun6i_csi_capture_format { u32 hsize_len_factor; }; +struct sun6i_csi_capture_format_match { + u32 pixelformat; + u32 mbus_code; +}; + #undef current struct sun6i_csi_capture_state { struct list_head queue; From patchwork Sat Feb 5 18:54:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540146 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3717DC433F5 for ; Sat, 5 Feb 2022 18:58:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1382059AbiBES65 (ORCPT ); Sat, 5 Feb 2022 13:58:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381409AbiBES4x (ORCPT ); Sat, 5 Feb 2022 13:56:53 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD0EAC03FED0; Sat, 5 Feb 2022 10:56:04 -0800 (PST) Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 9830724001B; Sat, 5 Feb 2022 18:56:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087363; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=etLtVx+NvjIpMcjeeF7ghhjop4Bf25hBbVp6k42V6CA=; b=lXshYQg2ileb516TLVOqgC6dkGfWUETTE6X35nydfGSvokEA7IZXewO+vDSUs2IQ+5TnTW pGGUHb2herTsl89KrmSivcbdyQFcn3zwbeHR5qT0Sob4cZLWF4mArMYfhH8628q7GmT0EI 5826itNqlxUCY18/ty9W8a30MtW1lGrSK3l4Yo3lpvrJRZiYfUQ2k7zHSc+1MM5yBOPgUS ilbga8ongB01oOPx+9+czpOq4+znSdhv4NsgVUPOWc8xrsLRvKdCVN5IZ6WuMpedHqcT2W bjrby0mm24LO+K7xUHR76rU1uLAjpcSdOjUeLrw+MdVJqu+C34X1+we82+SJlg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 49/66] media: sun6i-csi: Get bridge subdev directly in capture stream ops Date: Sat, 5 Feb 2022 19:54:12 +0100 Message-Id: <20220205185429.2278860-50-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The remote subdev connected to the capture video device is always our bridge, so get the bridge subdev directly instead of using a dedicated helper (which is removed by this commit). Signed-off-by: Paul Kocialkowski --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 30 ++----------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index be1a4fe8fe5f..2f9bf75e4e39 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -42,22 +42,6 @@ void sun6i_csi_capture_format(struct sun6i_csi_device *csi_dev, *field = csi_dev->capture.format.fmt.pix.field; } -static struct v4l2_subdev * -sun6i_csi_capture_remote_subdev(struct sun6i_csi_capture *capture, u32 *pad) -{ - struct media_pad *remote; - - remote = media_entity_remote_pad(&capture->pad); - - if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) - return NULL; - - if (pad) - *pad = remote->index; - - return media_entity_to_v4l2_subdev(remote->entity); -} - /* Format */ static const struct sun6i_csi_capture_format sun6i_csi_capture_formats[] = { @@ -822,8 +806,8 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, struct sun6i_csi_capture *capture = &csi_dev->capture; struct sun6i_csi_capture_state *state = &capture->state; struct video_device *video_dev = &capture->video_dev; + struct v4l2_subdev *subdev = &csi_dev->bridge.subdev; struct device *dev = csi_dev->dev; - struct v4l2_subdev *subdev; int ret; state->sequence = 0; @@ -832,12 +816,6 @@ static int sun6i_csi_capture_start_streaming(struct vb2_queue *queue, if (ret < 0) goto error_state; - subdev = sun6i_csi_capture_remote_subdev(capture, NULL); - if (!subdev) { - ret = -EINVAL; - goto error_media_pipeline; - } - /* PM */ ret = pm_runtime_resume_and_get(dev); @@ -886,12 +864,10 @@ static void sun6i_csi_capture_stop_streaming(struct vb2_queue *queue) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); struct sun6i_csi_capture *capture = &csi_dev->capture; + struct v4l2_subdev *subdev = &csi_dev->bridge.subdev; struct device *dev = csi_dev->dev; - struct v4l2_subdev *subdev; - subdev = sun6i_csi_capture_remote_subdev(capture, NULL); - if (subdev) - v4l2_subdev_call(subdev, video, s_stream, 0); + v4l2_subdev_call(subdev, video, s_stream, 0); sun6i_csi_capture_disable(csi_dev); sun6i_csi_capture_irq_disable(csi_dev); From patchwork Sat Feb 5 18:54:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540144 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A9ECC43217 for ; Sat, 5 Feb 2022 18:59:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381778AbiBES7M (ORCPT ); Sat, 5 Feb 2022 13:59:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381406AbiBES47 (ORCPT ); Sat, 5 Feb 2022 13:56:59 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2EFBC03FED5; Sat, 5 Feb 2022 10:56:09 -0800 (PST) Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id CCC9124001C; Sat, 5 Feb 2022 18:56:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087368; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rw9sX0ixeheTtFNsdf6WOCL+54BUmmSHSVUGdB4RDWY=; b=JZG3DLBSe1WOJseOdbhvMI2+QyAx9DzMOf88qW29EJqFR1BMgH2H0w1nuA8nisUQ3zxaHE NnxgTU6ljN6QQXOsw80VzbB65fftZtKcFlGSsEkZuy3qILnH25VT3J9KF5qmN5c8RoLSiT Y+uCZKTkuQScRhx6/sN9Zx6DF0TM1ia8yoxwFtdmD2ysT/7YM/wpFvQoCWqu9V+fCLTsUL On/42aJxmggemfqjori0d5Hbw/8+wx8xDQEta5H/ealfk36sL8oYzCoSIj+/VbmIxCRXBv HiucwcZjUQcb0rbmc7t2IWqUkbQ7r5t49qdt7VarNJlkrW1TrNok3FF2m7ixGA== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 52/66] media: sun6i-csi: Rename the capture video device to sun6i-csi-capture Date: Sat, 5 Feb 2022 19:54:15 +0100 Message-Id: <20220205185429.2278860-53-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that the driver is properly split between bridge and capture, rename the video device to highlight its role and be in line with the bridge entity naming. Signed-off-by: Paul Kocialkowski --- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c | 3 ++- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 6033acaa9564..85ea7812e991 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -1020,7 +1020,8 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) /* Video Device */ - strscpy(video_dev->name, SUN6I_CSI_NAME, sizeof(video_dev->name)); + strscpy(video_dev->name, SUN6I_CSI_CAPTURE_NAME, + sizeof(video_dev->name)); video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; video_dev->vfl_dir = VFL_DIR_RX; video_dev->release = video_device_release_empty; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h index a61db3bc72e5..59c57bcefeec 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h @@ -11,6 +11,8 @@ #include #include +#define SUN6I_CSI_CAPTURE_NAME "sun6i-csi-capture" + #define SUN6I_CSI_CAPTURE_WIDTH_MIN 32 #define SUN6I_CSI_CAPTURE_WIDTH_MAX 4800 #define SUN6I_CSI_CAPTURE_HEIGHT_MIN 32 From patchwork Sat Feb 5 18:54:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540151 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E95AEC43219 for ; Sat, 5 Feb 2022 18:58:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381253AbiBES6I (ORCPT ); Sat, 5 Feb 2022 13:58:08 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:41349 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381539AbiBES4O (ORCPT ); Sat, 5 Feb 2022 13:56:14 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 35EE4240020; Sat, 5 Feb 2022 18:56:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087371; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=r7vkirzgla1o4VdWEyY7qc3mJDeawM6hQPmFQlwv7HE=; b=jI3xbAZGghrP+ZL330+omfHnhKuELkaMUHdbyt7gUXmhlbZTPJkbSq+9H1m1yb/I1c2FCZ r1EAw+FysCHBy8OkqrapX6KlNO9kRGvb7C+5r04TjW6gObLl899cpArENcJhNwXAAvNVcp wyJbRqJRr7oWFMen250ndy4oaBEEDhfzRQvF1Uk7XaO8FoF996Irb5hPRp5jTJIfmhhCfg 2BpVyx+ZlPAMAouZHotkpItDTrfIl/kRFSKPT2DISLfRKxXe9G2yvph0bYRAw86E4c7tgW o0WQGLukHP9T1KEKH/kT6qCzjVyV6PrPPJ2M+Wbn7OkHl2yt8nwUFLhPmycPGg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 54/66] media: sun6i-csi: Add support for MIPI CSI-2 to the bridge code Date: Sat, 5 Feb 2022 19:54:17 +0100 Message-Id: <20220205185429.2278860-55-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Introduce MIPI CSI-2 support to the bridge with a new port, source and hardware configuration helper. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 1 + .../sunxi/sun6i-csi/sun6i_csi_bridge.c | 35 +++++++++++++++++-- .../sunxi/sun6i-csi/sun6i_csi_bridge.h | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index d7082e951b06..3c08b2712215 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -21,6 +21,7 @@ enum sun6i_csi_port { SUN6I_CSI_PORT_PARALLEL = 0, + SUN6I_CSI_PORT_MIPI_CSI2 = 1, }; struct sun6i_csi_buffer { diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c index f5303842d169..b631220dd682 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c @@ -226,7 +226,7 @@ static void sun6i_csi_bridge_disable(struct sun6i_csi_device *csi_dev) } static void -sun6i_csi_bridge_configure_interface(struct sun6i_csi_device *csi_dev) +sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev) { struct device *dev = csi_dev->dev; struct regmap *regmap = csi_dev->regmap; @@ -316,6 +316,25 @@ sun6i_csi_bridge_configure_interface(struct sun6i_csi_device *csi_dev) regmap_write(regmap, SUN6I_CSI_IF_CFG_REG, value); } +static void +sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev) +{ + struct regmap *regmap = csi_dev->regmap; + u32 value = SUN6I_CSI_IF_CFG_IF_MIPI; + u32 field; + + sun6i_csi_bridge_format(csi_dev, NULL, &field); + + if (field == V4L2_FIELD_INTERLACED || + field == V4L2_FIELD_INTERLACED_TB || + field == V4L2_FIELD_INTERLACED_BT) + value |= SUN6I_CSI_IF_CFG_SRC_TYPE_INTERLACED; + else + value |= SUN6I_CSI_IF_CFG_SRC_TYPE_PROGRESSIVE; + + regmap_write(regmap, SUN6I_CSI_IF_CFG_REG, value); +} + static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev) { struct regmap *regmap = csi_dev->regmap; @@ -369,7 +388,11 @@ static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev) static void sun6i_csi_bridge_configure(struct sun6i_csi_device *csi_dev) { - sun6i_csi_bridge_configure_interface(csi_dev); + if (csi_dev->bridge.source == &csi_dev->bridge.source_parallel) + sun6i_csi_bridge_configure_parallel(csi_dev); + else if (csi_dev->bridge.source == &csi_dev->bridge.source_mipi_csi2) + sun6i_csi_bridge_configure_mipi_csi2(csi_dev); + sun6i_csi_bridge_configure_format(csi_dev); } @@ -552,6 +575,8 @@ static int sun6i_csi_bridge_link_validate(struct media_link *link) if (source_subdev == bridge->source_parallel.subdev) bridge->source = &bridge->source_parallel; + else if (source_subdev == bridge->source_mipi_csi2.subdev) + bridge->source = &bridge->source_mipi_csi2; else return -EINVAL; @@ -638,6 +663,10 @@ sun6i_csi_bridge_notifier_bound(struct v4l2_async_notifier *notifier, source = &bridge->source_parallel; enabled = true; break; + case SUN6I_CSI_PORT_MIPI_CSI2: + source = &bridge->source_mipi_csi2; + enabled = !bridge->source_parallel.expected; + break; default: break; } @@ -784,6 +813,8 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) sun6i_csi_bridge_source_setup(csi_dev, &bridge->source_parallel, SUN6I_CSI_PORT_PARALLEL, parallel_mbus_types); + sun6i_csi_bridge_source_setup(csi_dev, &bridge->source_mipi_csi2, + SUN6I_CSI_PORT_MIPI_CSI2, NULL); ret = v4l2_async_nf_register(v4l2_dev, notifier); if (ret) { diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h index 079227c02482..e59c40611872 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h @@ -40,6 +40,7 @@ struct sun6i_csi_bridge { struct v4l2_mbus_framefmt mbus_format; struct sun6i_csi_bridge_source source_parallel; + struct sun6i_csi_bridge_source source_mipi_csi2; struct sun6i_csi_bridge_source *source; }; From patchwork Sat Feb 5 18:54:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540150 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B616AC43217 for ; Sat, 5 Feb 2022 18:58:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381957AbiBES6M (ORCPT ); Sat, 5 Feb 2022 13:58:12 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:44207 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381159AbiBES4R (ORCPT ); Sat, 5 Feb 2022 13:56:17 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 9284924001B; Sat, 5 Feb 2022 18:56:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087375; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EndNmZca+VVvmr6LnUGh3p/snwLNh6qthIjCr+h8acE=; b=Msqlzw/UiMuePIAE9ELEdIs4DM8y7gUaomdiFQ80P+1LCnwHEWqAO+EJv4NSHYtvi2MtVo TczyyBV+AD5lRR6NIQnNTk4oDe4nIFjg25K2HNQdAHzvhEzp3ebewgECbb5aDITV9tdf+w tA5rVRswEYU1razwt/ZLsFj7DYDy0VMyIg1tDYjt5xvALujJhb/1D/Xc4uxEQBiMqsiP3a phEKsZ3UtVhBQXeTB8k59Us/OSYuMbBJSh/dwckR654Cw5yaOSALqsdupCw+/VL8ioR8ug cEf8O/97LS4CUKXcobw816ExFYHyjDJou8RaJ2Tx8ujEKjx2P1PWvZI3tXY3Ew== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 56/66] media: sun6i-csi: Add extra checks to the interrupt routine Date: Sat, 5 Feb 2022 19:54:19 +0100 Message-Id: <20220205185429.2278860-57-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Check against the enabled bits and make sure capture is running before serving an interrupt, to add extra safety in the process. Signed-off-by: Paul Kocialkowski --- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 8941104f611b..e3ac7dad86ae 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -111,13 +111,17 @@ static void sun6i_csi_v4l2_cleanup(struct sun6i_csi_device *csi_dev) static irqreturn_t sun6i_csi_isr(int irq, void *private) { struct sun6i_csi_device *csi_dev = private; + bool capture_streaming = csi_dev->capture.state.streaming; struct regmap *regmap = csi_dev->regmap; - u32 status; + u32 status = 0, enable = 0; regmap_read(regmap, SUN6I_CSI_CH_INT_STA_REG, &status); + regmap_read(regmap, SUN6I_CSI_CH_INT_EN_REG, &enable); - if (!(status & 0xFF)) + if (!status) return IRQ_NONE; + else if (!(status & enable) || !capture_streaming) + goto complete; if ((status & SUN6I_CSI_CH_INT_STA_FIFO0_OF) || (status & SUN6I_CSI_CH_INT_STA_FIFO1_OF) || @@ -138,6 +142,7 @@ static irqreturn_t sun6i_csi_isr(int irq, void *private) if (status & SUN6I_CSI_CH_INT_STA_VS) sun6i_csi_capture_sync(csi_dev); +complete: regmap_write(regmap, SUN6I_CSI_CH_INT_STA_REG, status); return IRQ_HANDLED; From patchwork Sat Feb 5 18:54:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540145 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B5EDC433FE for ; Sat, 5 Feb 2022 18:59:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1382106AbiBES7C (ORCPT ); Sat, 5 Feb 2022 13:59:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243650AbiBES47 (ORCPT ); Sat, 5 Feb 2022 13:56:59 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9E22C043181; Sat, 5 Feb 2022 10:56:19 -0800 (PST) Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 0175A240002; Sat, 5 Feb 2022 18:56:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087378; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=majeYqv001Hk/JLaXWth7OAGgt7K7pFuA9tBX2AQZdA=; b=abPysJQbp5jULxHX49048PYYBx4305nxRe5w5u+VzfslzR2LiQA83/qY67Eq4h8C67wpwA uxTAjeZvzPPuZvb7U/q0QmONjb5Mw2Ry2xiyGOlABIKzeN1DdSUHlYTA+TKHbmfvsAmnUB QMVIj8AMCDX+VcXHM2LRzwW+mZMzi6DE6EbEUmjbHL2kR0UNV0YKNZLF7k0bAQzR5LRTnn JM62yWhFlqv9uNgnImYII7167XJiepzIzHPXq8vTzPyIyKur6SjJQ0No8vpKjFd4RiGm0u laqRZILqkcha5m7G2Y3QcQTJZWtUyQOWrvw3VoKJ1jMN7GaG/mKjDYPwTWbmDw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 58/66] media: sun6i-csi: Detect the availability of the ISP Date: Sat, 5 Feb 2022 19:54:21 +0100 Message-Id: <20220205185429.2278860-59-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add a helper to detect whether the ISP is available and connected and store the indication in a driver-wide variable. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 33 +++++++++++++++++++ .../platform/sunxi/sun6i-csi/sun6i_csi.h | 3 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index b8e925f6bc09..70b2a8b95b40 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -24,6 +24,35 @@ #include "sun6i_csi_capture.h" #include "sun6i_csi_reg.h" +/* ISP */ + +static bool sun6i_csi_isp_detect(struct sun6i_csi_device *csi_dev) +{ + struct device *dev = csi_dev->dev; + struct fwnode_handle *handle = NULL; + + /* ISP is not available if disabled in kernel config. */ + if (!IS_ENABLED(CONFIG_VIDEO_SUN6I_ISP)) + return 0; + + /* + * ISP is not available if not connected via fwnode graph. + * This weill also check that the remote parent node is available. + */ + handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), + SUN6I_CSI_PORT_ISP, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (!handle) + return 0; + + fwnode_handle_put(handle); + + dev_info(dev, "ISP link is available\n"); + csi_dev->isp_available = true; + + return 0; +} + /* Media */ static const struct media_device_ops sun6i_csi_media_ops = { @@ -328,6 +357,10 @@ static int sun6i_csi_probe(struct platform_device *platform_dev) if (ret) return ret; + ret = sun6i_csi_isp_detect(csi_dev); + if (ret) + goto error_resources; + ret = sun6i_csi_v4l2_setup(csi_dev); if (ret) goto error_resources; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index 3c08b2712215..6cdaf98dc295 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -22,6 +22,7 @@ enum sun6i_csi_port { SUN6I_CSI_PORT_PARALLEL = 0, SUN6I_CSI_PORT_MIPI_CSI2 = 1, + SUN6I_CSI_PORT_ISP = 2, }; struct sun6i_csi_buffer { @@ -47,6 +48,8 @@ struct sun6i_csi_device { struct clk *clk_mod; struct clk *clk_ram; struct reset_control *reset; + + bool isp_available; }; /* V4L2 */ From patchwork Sat Feb 5 18:54:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540149 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 054D6C433FE for ; Sat, 5 Feb 2022 18:58:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381588AbiBES6S (ORCPT ); Sat, 5 Feb 2022 13:58:18 -0500 Received: from relay10.mail.gandi.net ([217.70.178.230]:58575 "EHLO relay10.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381579AbiBES4V (ORCPT ); Sat, 5 Feb 2022 13:56:21 -0500 Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 957E924001C; Sat, 5 Feb 2022 18:56:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087380; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5luBjbgwR8xInbAp7xEaH/avHqpBe9Vj+954q16ysFc=; b=edS+gwjAQrsobEVDamVq3zkxOhSV3VQ2nQgvsSLEPvKYIohO0ZYUzc+W9Jfq5Tbr/lhomG GWF/17rIpxAmOaWnNQ3Zy1avemgpZWdv8a4SC7NCZryBIx6qbe3CZb0Kcr6nRFEf4j60zE z0kCePiVG6k/Gl66Lw4d4da/aaQNSvHWdNqVP3thKt60iggZUhXZ7E4RDMMuxxR7Rf4HyZ 51QcIncC5VwVGEU+//zx8IfEiRglQJzqjab3Y3LOt/lGnUGY1QJyRe/MjSfUYRL+3Spdo3 4/2hKf2nsYmG9mvlttQnf1h+y0wAEVWLvGy96zjrGQJyQooQvZZXbGw1r4IPqw== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 59/66] media: sun6i-csi: Add support for hooking to the isp devices Date: Sat, 5 Feb 2022 19:54:22 +0100 Message-Id: <20220205185429.2278860-60-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In order to use the isp and csi together, both devices need to be parented to the same v4l2 and media devices. We use the isp as top-level device and let the csi code hook to its v4l2 and media devices when async subdev registration takes place. As a result v4l2/media device setup is only called when the ISP is missing and the capture device is registered after the devices are hooked. The bridge subdev and its notifier are registered without any device when the ISP is available. Top-level pointers for the devices are introduced to either redirect to the hooked ones (isp available) or the registered ones (isp missing). Also keep track of whether the capture node was setup or not to avoid cleaning up resources when it wasn't. Signed-off-by: Paul Kocialkowski --- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 55 ++++++++++++++----- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 7 +++ .../sunxi/sun6i-csi/sun6i_csi_bridge.c | 31 +++++++++-- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 19 ++++++- .../sunxi/sun6i-csi/sun6i_csi_capture.h | 1 + 5 files changed, 93 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 70b2a8b95b40..0c635b446fba 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -26,6 +26,18 @@ /* ISP */ +int sun6i_csi_isp_complete(struct sun6i_csi_device *csi_dev, + struct v4l2_device *v4l2_dev) +{ + if (csi_dev->v4l2_dev && csi_dev->v4l2_dev != v4l2_dev) + return -EINVAL; + + csi_dev->v4l2_dev = v4l2_dev; + csi_dev->media_dev = v4l2_dev->mdev; + + return sun6i_csi_capture_setup(csi_dev); +} + static bool sun6i_csi_isp_detect(struct sun6i_csi_device *csi_dev) { struct device *dev = csi_dev->dev; @@ -64,8 +76,17 @@ static const struct media_device_ops sun6i_csi_media_ops = { int sun6i_csi_v4l2_complete(struct sun6i_csi_device *csi_dev) { struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; + int ret; + + ret = v4l2_device_register_subdev_nodes(v4l2_dev); + if (ret) + return ret; - return v4l2_device_register_subdev_nodes(v4l2_dev); + ret = sun6i_csi_capture_setup(csi_dev); + if (ret) + return ret; + + return 0; } static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) @@ -113,6 +134,9 @@ static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) goto error_v4l2_ctrl; } + csi_dev->v4l2_dev = v4l2_dev; + csi_dev->media_dev = media_dev; + return 0; error_v4l2_ctrl: @@ -361,25 +385,27 @@ static int sun6i_csi_probe(struct platform_device *platform_dev) if (ret) goto error_resources; - ret = sun6i_csi_v4l2_setup(csi_dev); - if (ret) - goto error_resources; + /* + * Register our own v4l2 and media devices when there is no ISP around. + * Otherwise the ISP will use async subdev registration with our bridge, + * which will provide v4l2 and media devices that are used to register + * the video interface. + */ + if (!csi_dev->isp_available) { + ret = sun6i_csi_v4l2_setup(csi_dev); + if (ret) + goto error_resources; + } ret = sun6i_csi_bridge_setup(csi_dev); if (ret) goto error_v4l2; - ret = sun6i_csi_capture_setup(csi_dev); - if (ret) - goto error_bridge; - return 0; -error_bridge: - sun6i_csi_bridge_cleanup(csi_dev); - error_v4l2: - sun6i_csi_v4l2_cleanup(csi_dev); + if (!csi_dev->isp_available) + sun6i_csi_v4l2_cleanup(csi_dev); error_resources: sun6i_csi_resources_cleanup(csi_dev); @@ -393,7 +419,10 @@ static int sun6i_csi_remove(struct platform_device *pdev) sun6i_csi_capture_cleanup(csi_dev); sun6i_csi_bridge_cleanup(csi_dev); - sun6i_csi_v4l2_cleanup(csi_dev); + + if (!csi_dev->isp_available) + sun6i_csi_v4l2_cleanup(csi_dev); + sun6i_csi_resources_cleanup(csi_dev); return 0; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index 6cdaf98dc295..6f1ea2c55ecd 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -38,6 +38,8 @@ struct sun6i_csi_v4l2 { struct sun6i_csi_device { struct device *dev; + struct v4l2_device *v4l2_dev; + struct media_device *media_dev; struct sun6i_csi_v4l2 v4l2; struct sun6i_csi_bridge bridge; @@ -52,6 +54,11 @@ struct sun6i_csi_device { bool isp_available; }; +/* ISP */ + +int sun6i_csi_isp_complete(struct sun6i_csi_device *csi_dev, + struct v4l2_device *v4l2_dev); + /* V4L2 */ int sun6i_csi_v4l2_complete(struct sun6i_csi_device *csi_dev); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c index 9827486dc3cb..55a632c814b2 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c @@ -692,6 +692,16 @@ sun6i_csi_bridge_notifier_bound(struct v4l2_async_notifier *notifier, source->subdev = remote_subdev; + if (csi_dev->isp_available) { + /* + * Hook to the first available remote subdev to get v4l2 and + * media devices and register the capture device then. + */ + ret = sun6i_csi_isp_complete(csi_dev, remote_subdev->v4l2_dev); + if (ret) + return ret; + } + return sun6i_csi_bridge_link(csi_dev, SUN6I_CSI_BRIDGE_PAD_SINK, remote_subdev, enabled); } @@ -703,6 +713,9 @@ sun6i_csi_bridge_notifier_complete(struct v4l2_async_notifier *notifier) container_of(notifier, struct sun6i_csi_device, bridge.notifier); + if (csi_dev->isp_available) + return 0; + return sun6i_csi_v4l2_complete(csi_dev); } @@ -772,7 +785,7 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) { struct device *dev = csi_dev->dev; struct sun6i_csi_bridge *bridge = &csi_dev->bridge; - struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; + struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev; struct v4l2_subdev *subdev = &bridge->subdev; struct v4l2_async_notifier *notifier = &bridge->notifier; struct media_pad *pads = bridge->pads; @@ -811,7 +824,11 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) /* V4L2 Subdev */ - ret = v4l2_device_register_subdev(v4l2_dev, subdev); + if (csi_dev->isp_available) + ret = v4l2_async_register_subdev(subdev); + else + ret = v4l2_device_register_subdev(v4l2_dev, subdev); + if (ret) { dev_err(dev, "failed to register v4l2 subdev: %d\n", ret); goto error_media_entity; @@ -828,7 +845,10 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) sun6i_csi_bridge_source_setup(csi_dev, &bridge->source_mipi_csi2, SUN6I_CSI_PORT_MIPI_CSI2, NULL); - ret = v4l2_async_nf_register(v4l2_dev, notifier); + if (csi_dev->isp_available) + ret = v4l2_async_subdev_nf_register(subdev, notifier); + else + ret = v4l2_async_nf_register(v4l2_dev, notifier); if (ret) { dev_err(dev, "failed to register v4l2 async notifier: %d\n", ret); @@ -840,7 +860,10 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) error_v4l2_async_notifier: v4l2_async_nf_cleanup(notifier); - v4l2_device_unregister_subdev(subdev); + if (csi_dev->isp_available) + v4l2_async_unregister_subdev(subdev); + else + v4l2_device_unregister_subdev(subdev); error_media_entity: media_entity_cleanup(&subdev->entity); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index f6dac15af675..2ad38277633f 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -570,7 +570,7 @@ static int sun6i_csi_capture_buffer_prepare(struct vb2_buffer *buffer) { struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); struct sun6i_csi_capture *capture = &csi_dev->capture; - struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; + struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev; struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); unsigned long size = capture->format.fmt.pix.sizeimage; @@ -886,7 +886,7 @@ static int sun6i_csi_capture_link_validate(struct media_link *link) struct video_device *video_dev = media_entity_to_video_device(link->sink->entity); struct sun6i_csi_device *csi_dev = video_get_drvdata(video_dev); - struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; + struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev; const struct sun6i_csi_capture_format *capture_format; const struct sun6i_csi_bridge_format *bridge_format; unsigned int capture_width, capture_height; @@ -968,7 +968,7 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) { struct sun6i_csi_capture *capture = &csi_dev->capture; struct sun6i_csi_capture_state *state = &capture->state; - struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; + struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev; struct v4l2_subdev *bridge_subdev = &csi_dev->bridge.subdev; struct video_device *video_dev = &capture->video_dev; struct vb2_queue *queue = &capture->queue; @@ -977,6 +977,10 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) struct v4l2_pix_format *pix_format = &format->fmt.pix; int ret; + /* This may happen with multiple bridge notifier bound calls. */ + if (state->setup) + return 0; + /* State */ INIT_LIST_HEAD(&state->queue); @@ -1055,6 +1059,7 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) ret = media_create_pad_link(&bridge_subdev->entity, SUN6I_CSI_BRIDGE_PAD_SOURCE, &video_dev->entity, 0, + csi_dev->isp_available ? 0 : MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); if (ret < 0) { @@ -1065,6 +1070,8 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev) goto error_video_device; } + state->setup = true; + return 0; error_video_device: @@ -1083,7 +1090,13 @@ void sun6i_csi_capture_cleanup(struct sun6i_csi_device *csi_dev) struct sun6i_csi_capture *capture = &csi_dev->capture; struct video_device *video_dev = &capture->video_dev; + /* This may happen if async registration failed to complete. */ + if (!capture->state.setup) + return; + vb2_video_unregister_device(video_dev); media_entity_cleanup(&video_dev->entity); mutex_destroy(&capture->lock); + + capture->state.setup = false; } diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h index 29893cf96f6b..3ee5ccefbd10 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.h @@ -45,6 +45,7 @@ struct sun6i_csi_capture_state { unsigned int sequence; bool streaming; + bool setup; }; struct sun6i_csi_capture { From patchwork Sat Feb 5 18:54:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540143 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF0FEC4332F for ; Sat, 5 Feb 2022 18:59:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381878AbiBES7m (ORCPT ); Sat, 5 Feb 2022 13:59:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381465AbiBES5n (ORCPT ); Sat, 5 Feb 2022 13:57:43 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A010C03FEDB; Sat, 5 Feb 2022 10:56:23 -0800 (PST) Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 4002024001F; Sat, 5 Feb 2022 18:56:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087381; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lzYEV15xzku+y6IihxRZLFkuLWL8R00vJmdalNUtBmc=; b=MYkS4EhaaywVXqr2wgBxKHdx/kQZ2HQdCmK8qLCCc5LTYKSEh0/eFFI/ysJUseIUnkVU8f 9QEW6k2AqIzh4VqsMb4T9IPfIhukNT1DZm5Y2i1XglNeQCmEZUBOx6WgTzl1vCfaa7bCWU KwQZJvX0hRHYMpo3RFSmE2cb3/i0RMqQo/qvJm6s/MiRNgqw6fATmOJw31ZH4LvA05ookT AWoTsqWmqEz1/v3thLFYemWGg6Q+eFIboDpJ38BYdL0D2A4Ay1seVg5k5aiGUdlJV7kR8m Lb16LI9oLqpuMx8LIVY1pP8kYgVBI6BeB2KQgRCj/c/Tw/JP7Rl/dNZhzkeSNg== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 60/66] MAINTAINERS: Add myself as sun6i-csi maintainer and rename/move entry Date: Sat, 5 Feb 2022 19:54:23 +0100 Message-Id: <20220205185429.2278860-61-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Given the substantial rework of the driver that I carried out and the knowledge acquired about the hardware along the way, make myself a maintainer of the sun6i-csi driver. Also rename and move the entry while at it since the driver is not specific to the V3s. Signed-off-by: Paul Kocialkowski --- MAINTAINERS | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 46582119e767..0e65b9e5123f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -751,6 +751,15 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml F: drivers/media/platform/sunxi/sun4i-csi/ +ALLWINNER A31 CSI DRIVER +M: Yong Deng +M: Paul Kocialkowski +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml +F: drivers/media/platform/sunxi/sun6i-csi/ + ALLWINNER A31 MIPI CSI-2 BRIDGE DRIVER M: Paul Kocialkowski L: linux-media@vger.kernel.org @@ -5064,14 +5073,6 @@ M: Jaya Kumar S: Maintained F: sound/pci/cs5535audio/ -CSI DRIVERS FOR ALLWINNER V3s -M: Yong Deng -L: linux-media@vger.kernel.org -S: Maintained -T: git git://linuxtv.org/media_tree.git -F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml -F: drivers/media/platform/sunxi/sun6i-csi/ - CW1200 WLAN driver M: Solomon Peachy S: Maintained From patchwork Sat Feb 5 18:54:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 540142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A861BC433EF for ; Sat, 5 Feb 2022 19:00:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381939AbiBETAD (ORCPT ); Sat, 5 Feb 2022 14:00:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47176 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381536AbiBES6J (ORCPT ); Sat, 5 Feb 2022 13:58:09 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71B89C061348; Sat, 5 Feb 2022 10:56:31 -0800 (PST) Received: (Authenticated sender: paul.kocialkowski@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 81D90240016; Sat, 5 Feb 2022 18:56:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1644087390; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BGPb89WOSddQ2LNPo4TT2bb8qg/CXX1YR3gv+jnfrGQ=; b=SkjnM26hqnVzLVfhNi73bxyNlhycmm1+DwP6m6acmwmnS9Z4hHbV2ViEQtm9SigrCRv7Hj CPUro0Ymu2WVuAtN3vp/g2qGqaPyx73L8PAVrMriwMA/kNMA/w6LUuH+l5NOQ0sbaweko1 ExHNJ3nB0qjiZS4LxiGFtc6bqrtY9FlVUCYysIqE5rvIgwOkNugY8crIllZ+ocOMwNa0fR Kfs5QWbEv9NR+YwBI7jU83/GHrtfJ2DJWYCU1UaRknq62SJSU7I9j2+cUxtiGFVtw1EOy+ GZ7F/tzI5bjcCRzywdYMtBMRSTK3gC4oG7xjQUmsyK9XE0teiyEEwK/MMT35SQ== From: Paul Kocialkowski To: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-clk@vger.kernel.org, linux-staging@lists.linux.dev Cc: Yong Deng , Mauro Carvalho Chehab , Rob Herring , Maxime Ripard , Sakari Ailus , Hans Verkuil , Chen-Yu Tsai , Jernej Skrabec , Paul Kocialkowski , Greg Kroah-Hartman , Helen Koike , Laurent Pinchart , Thomas Petazzoni Subject: [PATCH v2 65/66] ARM: dts: sun8i: v3s: Add support for the ISP Date: Sat, 5 Feb 2022 19:54:28 +0100 Message-Id: <20220205185429.2278860-66-paul.kocialkowski@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> References: <20220205185429.2278860-1-paul.kocialkowski@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The V3s (and related platforms) come with an instance of the A31 ISP. Even though it is very close to the A31 ISP, it is not exactly register-compatible and a dedicated compatible only is used as a result. Just like most other blocks of the camera pipeline, the ISP uses the common CSI bus, module and ram clock as well as reset. A port connection to the ISP is added to CSI0 for convenience since CSI0 serves for MIPI CSI-2 interface support, which is likely to receive raw data that will need to be processed by the ISP to produce a final image. While the interconnects property is used to inherit the proper dma ranges, the associated index for the cell is set to 0 since no particular meaning is attached to it. This might need to be changed later on (when identifying a proper mbus channel becomes relevant, e.g. for things like QoS). Signed-off-by: Paul Kocialkowski --- arch/arm/boot/dts/sun8i-v3s.dtsi | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi index f5f7dfec49f9..c2e65679b9ed 100644 --- a/arch/arm/boot/dts/sun8i-v3s.dtsi +++ b/arch/arm/boot/dts/sun8i-v3s.dtsi @@ -638,6 +638,14 @@ csi0_in_mipi_csi2: endpoint { remote-endpoint = <&mipi_csi2_out_csi0>; }; }; + + port@2 { + reg = <2>; + + csi0_out_isp: endpoint { + remote-endpoint = <&isp_in_csi0>; + }; + }; }; }; @@ -696,5 +704,32 @@ csi1: camera@1cb4000 { resets = <&ccu RST_BUS_CSI>; status = "disabled"; }; + + isp: isp@1cb8000 { + compatible = "allwinner,sun8i-v3s-isp"; + reg = <0x01cb8000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_CSI>, + <&ccu CLK_CSI1_SCLK>, + <&ccu CLK_DRAM_CSI>; + clock-names = "bus", "mod", "ram"; + resets = <&ccu RST_BUS_CSI>; + interconnects = <&mbus 0>; + interconnect-names = "dma-mem"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + isp_in_csi0: endpoint { + remote-endpoint = <&csi0_out_isp>; + }; + }; + }; + }; }; };