From patchwork Tue May 22 14:52:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 136560 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp1734925lji; Tue, 22 May 2018 07:53:14 -0700 (PDT) X-Google-Smtp-Source: AB8JxZr1BdSnyGwnXuyISSCH/09YzeNlQUZqTGwG4ywcVY/BWyFjKmoVgXSoBtkaHTUSfywBmQsd X-Received: by 2002:a62:5d99:: with SMTP id n25-v6mr24516445pfj.143.1527000793927; Tue, 22 May 2018 07:53:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527000793; cv=none; d=google.com; s=arc-20160816; b=vmcp2AFVRYp98/uy9S3Xj7qpHJvTkv6ki/0q0ViPJ116eCHj4YkrwWFXW7I+1vwK4r lBNFVF1D0FjKUfU9I5bcsTzup6EYEguN4ssaNHe0kKAD4XvrswdFaNCzdXXVbFXDJ5ck Pj2KE1/ei/z5gyYpHMHz+AbVdTtI00jzAYhcWHu7gNbWFGrcW4JgrD75CKrpFyNO63Nq T80Q9dZ75NNAYTSouQlSpQkVELuocaYPKIwW18Odtb61xGvEoI+1So5bncmv5ZidX3pX gCMIp8MyLY6z5wCTRZhBS7kZK2tnfM1xRccMKpYAIwbFG5SRuC5ltbWPhEI2vQutCjX2 E1uQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=TdkjyvUyStpTehaDjesfb0Ew7CAkD5bRt6cwK8UOePA=; b=j3EBD+XaJhMERKD0z5ujKZsi8SXjEVhcc9wUUQezB3CGeSewMsQGue0bV+STJaB92P 4zdj1HPO6aTNsc0LFssRNmP5Y2YoAjdZycppe3uR7DFtiLnBb28LKYCelU0VBK8w8XjZ Dl/e2t9wFCaOlbxZi3tgG2DnSQT+OLMoJbgMdHOFe2DFBUeQtSpdXFQ+CaAbPCSe3c7p PVXnOc5TMP1KcALWmU89KCNa7Dnqi5t066eTLNqvgTuQ/M3cVVQpvq8CWXu1c7gwWXPa IzCiRl6OXC080ES37ANd1Dl+5GEs2ozwCjX/4Vcry6JFEZK9m700xhanOmlsryJ2pvI+ 7cbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HChg+c9/; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q28-v6si16922041pfl.317.2018.05.22.07.53.13; Tue, 22 May 2018 07:53:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HChg+c9/; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751687AbeEVOxL (ORCPT + 5 others); Tue, 22 May 2018 10:53:11 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:44359 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751582AbeEVOxG (ORCPT ); Tue, 22 May 2018 10:53:06 -0400 Received: by mail-wr0-f193.google.com with SMTP id y15-v6so20723460wrg.11 for ; Tue, 22 May 2018 07:53:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pS6Rx3kBUcKWOdokvVZXMtrf8Zr9rmMslSxt/Wt4F6Y=; b=HChg+c9/hq/d9HzW9GqY8F6wWymY0LlZkuBMXCEzmbL4ArrGZTrQGihK0i2iq12fHc Ij12SnEhNwA/Y3IK91MdQKt8cCveYLIXnG5CB4Couy1ARTxeBhvByThnElsBk37sNljE uvNnjduHPpQhXzVsxe8KS+1Xnut30CDwfmMOI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pS6Rx3kBUcKWOdokvVZXMtrf8Zr9rmMslSxt/Wt4F6Y=; b=Cf/aiufZmCEU3vaMQUm45nqNfE/z/gvaXqD1tg3e+asLXUtN+r/xIyWAL3unkcPiMN pjB29LBvix1lVY16hDZWFtIAKdEcpSqEoLIc/8ma6SJKgP/qMergwNkAyPyDjzcnVlFN 7X+gD9FioOmdkjRRQQmjdLSVX8CX09Piou3w6fXPECW9KDgy2g+GYuaGEltZ2J8HOL52 6J1qAbHpUDCsD5+vMQGsVIYO10lt2o2rVkTh/hU/XqWHDIp9Nmptf3Q+RwP1kSZ7VRDS 2Rw42aLEwCTay1UB/2vL5qGgQXl71ZcCe48DI3UO74rdcwyMA1A0vUAKLa9oOEuIineG 9yCw== X-Gm-Message-State: ALKqPwdQWpneHpjFis0jkEqvKL3liWpBUlPAri/APzKEOtL/mT7tDcGv TpppwyYdp8c6gpJWUSjcp0WBZw== X-Received: by 2002:adf:c884:: with SMTP id k4-v6mr18084268wrh.6.1527000784019; Tue, 22 May 2018 07:53:04 -0700 (PDT) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 75-v6sm76878wmw.37.2018.05.22.07.53.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 07:53:03 -0700 (PDT) From: Rui Miguel Silva To: mchehab@kernel.org, sakari.ailus@linux.intel.com, Steve Longerbeam , Philipp Zabel , Rob Herring Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, Shawn Guo , Fabio Estevam , devicetree@vger.kernel.org, Greg Kroah-Hartman , Ryan Harkin , linux-clk@vger.kernel.org, Rui Miguel Silva Subject: [PATCH v6 03/13] media: staging/imx7: add imx7 CSI subdev driver Date: Tue, 22 May 2018 15:52:35 +0100 Message-Id: <20180522145245.3143-4-rui.silva@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180522145245.3143-1-rui.silva@linaro.org> References: <20180522145245.3143-1-rui.silva@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This add the media entity subdevice and control driver for the i.MX7 CMOS Sensor Interface. Signed-off-by: Rui Miguel Silva --- drivers/staging/media/imx/Kconfig | 9 +- drivers/staging/media/imx/Makefile | 2 + drivers/staging/media/imx/imx7-media-csi.c | 1352 ++++++++++++++++++++ 3 files changed, 1362 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/media/imx/imx7-media-csi.c -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig index bfc17de56b17..40a11f988fc6 100644 --- a/drivers/staging/media/imx/Kconfig +++ b/drivers/staging/media/imx/Kconfig @@ -11,7 +11,7 @@ config VIDEO_IMX_MEDIA driver for the i.MX5/6 SOC. if VIDEO_IMX_MEDIA -menu "i.MX5/6 Media Sub devices" +menu "i.MX5/6/7 Media Sub devices" config VIDEO_IMX_CSI tristate "i.MX5/6 Camera Sensor Interface driver" @@ -20,5 +20,12 @@ config VIDEO_IMX_CSI ---help--- A video4linux camera sensor interface driver for i.MX5/6. +config VIDEO_IMX7_CSI + tristate "i.MX7 Camera Sensor Interface driver" + depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C + default y + ---help--- + A video4linux camera sensor interface driver for i.MX7. + endmenu endif diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile index a30b3033f9a3..074f016d3519 100644 --- a/drivers/staging/media/imx/Makefile +++ b/drivers/staging/media/imx/Makefile @@ -12,3 +12,5 @@ obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-ic.o obj-$(CONFIG_VIDEO_IMX_CSI) += imx-media-csi.o obj-$(CONFIG_VIDEO_IMX_CSI) += imx6-mipi-csi2.o + +obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-media-csi.o diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c new file mode 100644 index 000000000000..7facb7fcbc67 --- /dev/null +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -0,0 +1,1352 @@ +// SPDX-License-Identifier: GPL +/* + * V4L2 Capture CSI Subdev for Freescale i.MX7 SOC + * + * Copyright (c) 2018 Linaro Ltd + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "imx-media.h" + +#define IMX7_CSI_PAD_SINK 0 +#define IMX7_CSI_PAD_SRC 1 +#define IMX7_CSI_PADS_NUM 2 + +/* reset values */ +#define CSICR1_RESET_VAL 0x40000800 +#define CSICR2_RESET_VAL 0x0 +#define CSICR3_RESET_VAL 0x0 + +/* csi control reg 1 */ +#define BIT_SWAP16_EN BIT(31) +#define BIT_EXT_VSYNC BIT(30) +#define BIT_EOF_INT_EN BIT(29) +#define BIT_PRP_IF_EN BIT(28) +#define BIT_CCIR_MODE BIT(27) +#define BIT_COF_INT_EN BIT(26) +#define BIT_SF_OR_INTEN BIT(25) +#define BIT_RF_OR_INTEN BIT(24) +#define BIT_SFF_DMA_DONE_INTEN BIT(22) +#define BIT_STATFF_INTEN BIT(21) +#define BIT_FB2_DMA_DONE_INTEN BIT(20) +#define BIT_FB1_DMA_DONE_INTEN BIT(19) +#define BIT_RXFF_INTEN BIT(18) +#define BIT_SOF_POL BIT(17) +#define BIT_SOF_INTEN BIT(16) +#define BIT_MCLKDIV (0xF << 12) +#define BIT_HSYNC_POL BIT(11) +#define BIT_CCIR_EN BIT(10) +#define BIT_MCLKEN BIT(9) +#define BIT_FCC BIT(8) +#define BIT_PACK_DIR BIT(7) +#define BIT_CLR_STATFIFO BIT(6) +#define BIT_CLR_RXFIFO BIT(5) +#define BIT_GCLK_MODE BIT(4) +#define BIT_INV_DATA BIT(3) +#define BIT_INV_PCLK BIT(2) +#define BIT_REDGE BIT(1) +#define BIT_PIXEL_BIT BIT(0) + +#define SHIFT_MCLKDIV 12 + +/* control reg 3 */ +#define BIT_FRMCNT (0xFFFF << 16) +#define BIT_FRMCNT_RST BIT(15) +#define BIT_DMA_REFLASH_RFF BIT(14) +#define BIT_DMA_REFLASH_SFF BIT(13) +#define BIT_DMA_REQ_EN_RFF BIT(12) +#define BIT_DMA_REQ_EN_SFF BIT(11) +#define BIT_STATFF_LEVEL (0x7 << 8) +#define BIT_HRESP_ERR_EN BIT(7) +#define BIT_RXFF_LEVEL (0x7 << 4) +#define BIT_TWO_8BIT_SENSOR BIT(3) +#define BIT_ZERO_PACK_EN BIT(2) +#define BIT_ECC_INT_EN BIT(1) +#define BIT_ECC_AUTO_EN BIT(0) + +#define SHIFT_FRMCNT 16 +#define SHIFT_RXFIFO_LEVEL 4 + +/* csi status reg */ +#define BIT_ADDR_CH_ERR_INT BIT(28) +#define BIT_FIELD0_INT BIT(27) +#define BIT_FIELD1_INT BIT(26) +#define BIT_SFF_OR_INT BIT(25) +#define BIT_RFF_OR_INT BIT(24) +#define BIT_DMA_TSF_DONE_SFF BIT(22) +#define BIT_STATFF_INT BIT(21) +#define BIT_DMA_TSF_DONE_FB2 BIT(20) +#define BIT_DMA_TSF_DONE_FB1 BIT(19) +#define BIT_RXFF_INT BIT(18) +#define BIT_EOF_INT BIT(17) +#define BIT_SOF_INT BIT(16) +#define BIT_F2_INT BIT(15) +#define BIT_F1_INT BIT(14) +#define BIT_COF_INT BIT(13) +#define BIT_HRESP_ERR_INT BIT(7) +#define BIT_ECC_INT BIT(1) +#define BIT_DRDY BIT(0) + +/* csi control reg 18 */ +#define BIT_CSI_HW_ENABLE BIT(31) +#define BIT_MIPI_DATA_FORMAT_RAW8 (0x2a << 25) +#define BIT_MIPI_DATA_FORMAT_RAW10 (0x2b << 25) +#define BIT_MIPI_DATA_FORMAT_RAW12 (0x2c << 25) +#define BIT_MIPI_DATA_FORMAT_RAW14 (0x2d << 25) +#define BIT_MIPI_DATA_FORMAT_YUV422_8B (0x1e << 25) +#define BIT_MIPI_DATA_FORMAT_MASK (0x3F << 25) +#define BIT_MIPI_DATA_FORMAT_OFFSET 25 +#define BIT_DATA_FROM_MIPI BIT(22) +#define BIT_MIPI_YU_SWAP BIT(21) +#define BIT_MIPI_DOUBLE_CMPNT BIT(20) +#define BIT_BASEADDR_CHG_ERR_EN BIT(9) +#define BIT_BASEADDR_SWITCH_SEL BIT(5) +#define BIT_BASEADDR_SWITCH_EN BIT(4) +#define BIT_PARALLEL24_EN BIT(3) +#define BIT_DEINTERLACE_EN BIT(2) +#define BIT_TVDECODER_IN_EN BIT(1) +#define BIT_NTSC_EN BIT(0) + +#define CSI_MCLK_VF 1 +#define CSI_MCLK_ENC 2 +#define CSI_MCLK_RAW 4 +#define CSI_MCLK_I2C 8 + +#define CSI_CSICR1 0x0 +#define CSI_CSICR2 0x4 +#define CSI_CSICR3 0x8 +#define CSI_STATFIFO 0xC +#define CSI_CSIRXFIFO 0x10 +#define CSI_CSIRXCNT 0x14 +#define CSI_CSISR 0x18 + +#define CSI_CSIDBG 0x1C +#define CSI_CSIDMASA_STATFIFO 0x20 +#define CSI_CSIDMATS_STATFIFO 0x24 +#define CSI_CSIDMASA_FB1 0x28 +#define CSI_CSIDMASA_FB2 0x2C +#define CSI_CSIFBUF_PARA 0x30 +#define CSI_CSIIMAG_PARA 0x34 + +#define CSI_CSICR18 0x48 +#define CSI_CSICR19 0x4c + +struct imx7_csi { + struct device *dev; + struct imx_media_dev *md; + struct v4l2_subdev sd; + struct imx_media_video_dev *vdev; + struct imx_media_dev *imxmd; + struct media_pad pad[IMX7_CSI_PADS_NUM]; + + struct mutex lock; + spinlock_t irqlock; + + struct v4l2_subdev *src_sd; + + struct media_entity *sink; + + struct v4l2_fwnode_endpoint upstream_ep; + + struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM]; + const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM]; + struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM]; + + struct v4l2_ctrl_handler ctrl_hdlr; + + void __iomem *regbase; + int irq; + + struct clk *clk_disp_axi; + struct clk *clk_disp_dcic; + struct clk *clk_csi_mclk; + + /* active vb2 buffers to send to video dev sink */ + struct imx_media_buffer *active_vb2_buf[2]; + struct imx_media_dma_buf underrun_buf; + + int buf_num; + u32 frame_sequence; + + bool last_eof; + bool is_init; + bool is_streaming; + bool is_csi2; + + struct completion last_eof_completion; +}; + +#define imx7_csi_reg_read(_csi, _offset) __raw_readl(_csi->regbase + _offset) +#define imx7_csi_reg_write(_csi, _val, _offset) \ + __raw_writel(_val, _csi->regbase + _offset) + +static void imx7_csi_clk_enable(struct imx7_csi *csi) +{ + clk_prepare_enable(csi->clk_disp_axi); + clk_prepare_enable(csi->clk_disp_dcic); + clk_prepare_enable(csi->clk_csi_mclk); +} + +static void imx7_csi_clk_disable(struct imx7_csi *csi) +{ + clk_disable_unprepare(csi->clk_csi_mclk); + clk_disable_unprepare(csi->clk_disp_dcic); + clk_disable_unprepare(csi->clk_disp_axi); +} + +static void imx7_csi_hw_reset(struct imx7_csi *csi) +{ + imx7_csi_reg_write(csi, + imx7_csi_reg_read(csi, CSI_CSICR3) | BIT_FRMCNT_RST, + CSI_CSICR3); + + imx7_csi_reg_write(csi, CSICR1_RESET_VAL, CSI_CSICR1); + imx7_csi_reg_write(csi, CSICR2_RESET_VAL, CSI_CSICR2); + imx7_csi_reg_write(csi, CSICR3_RESET_VAL, CSI_CSICR3); +} + +static unsigned long imx7_csi_irq_clear(struct imx7_csi *csi) +{ + unsigned long isr; + + isr = imx7_csi_reg_read(csi, CSI_CSISR); + imx7_csi_reg_write(csi, isr, CSI_CSISR); + + return isr; +} + +static void imx7_csi_init_interface(struct imx7_csi *csi) +{ + unsigned int val = 0; + unsigned int imag_para; + + val = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL | + BIT_FCC | 1 << SHIFT_MCLKDIV | BIT_MCLKEN; + imx7_csi_reg_write(csi, val, CSI_CSICR1); + + imag_para = (800 << 16) | 600; + imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA); + + val = BIT_DMA_REFLASH_RFF; + imx7_csi_reg_write(csi, val, CSI_CSICR3); +} + +static void imx7_csi_hw_enable_irq(struct imx7_csi *csi) +{ + unsigned long cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + + cr1 |= BIT_SOF_INTEN; + cr1 |= BIT_RFF_OR_INT; + + /* still capture needs DMA interrupt */ + cr1 |= BIT_FB1_DMA_DONE_INTEN; + cr1 |= BIT_FB2_DMA_DONE_INTEN; + + cr1 |= BIT_EOF_INT_EN; + + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); +} + +static void imx7_csi_hw_disable_irq(struct imx7_csi *csi) +{ + unsigned long cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + + cr1 &= ~BIT_SOF_INTEN; + cr1 &= ~BIT_RFF_OR_INT; + cr1 &= ~BIT_FB1_DMA_DONE_INTEN; + cr1 &= ~BIT_FB2_DMA_DONE_INTEN; + cr1 &= ~BIT_EOF_INT_EN; + + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); +} + +static void imx7_csi_hw_enable(struct imx7_csi *csi) +{ + unsigned long cr = imx7_csi_reg_read(csi, CSI_CSICR18); + + cr |= BIT_CSI_HW_ENABLE; + + imx7_csi_reg_write(csi, cr, CSI_CSICR18); +} + +static void imx7_csi_hw_disable(struct imx7_csi *csi) +{ + unsigned long cr = imx7_csi_reg_read(csi, CSI_CSICR18); + + cr &= ~BIT_CSI_HW_ENABLE; + + imx7_csi_reg_write(csi, cr, CSI_CSICR18); +} + +static void imx7_csi_dma_reflash(struct imx7_csi *csi) +{ + unsigned long cr3 = imx7_csi_reg_read(csi, CSI_CSICR18); + + cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); + cr3 |= BIT_DMA_REFLASH_RFF; + imx7_csi_reg_write(csi, cr3, CSI_CSICR3); +} + +static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi) +{ + unsigned long cr1; + + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + imx7_csi_reg_write(csi, cr1 & ~BIT_FCC, CSI_CSICR1); + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1); + + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1); +} + +static void imx7_csi_buf_stride_set(struct imx7_csi *csi, u32 stride) +{ + imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA); +} + +static void imx7_csi_deinterlace_enable(struct imx7_csi *csi, bool enable) +{ + unsigned long cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); + + if (enable) + cr18 |= BIT_DEINTERLACE_EN; + else + cr18 &= ~BIT_DEINTERLACE_EN; + + imx7_csi_reg_write(csi, cr18, CSI_CSICR18); +} + +static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi) +{ + unsigned long cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); + unsigned long cr2 = imx7_csi_reg_read(csi, CSI_CSICR2); + + /* Burst Type of DMA Transfer from RxFIFO. INCR16 */ + cr2 |= 0xC0000000; + + cr3 |= BIT_DMA_REQ_EN_RFF; + cr3 |= BIT_HRESP_ERR_EN; + cr3 &= ~BIT_RXFF_LEVEL; + cr3 |= 0x2 << 4; + + imx7_csi_reg_write(csi, cr3, CSI_CSICR3); + imx7_csi_reg_write(csi, cr2, CSI_CSICR2); +} + +static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi) +{ + unsigned long cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); + + cr3 &= ~BIT_DMA_REQ_EN_RFF; + cr3 &= ~BIT_HRESP_ERR_EN; + imx7_csi_reg_write(csi, cr3, CSI_CSICR3); +} + +static void imx7_csi_set_imagpara(struct imx7_csi *csi, int width, int height) +{ + int imag_para; + int rx_count; + + rx_count = (width * height) >> 2; + imx7_csi_reg_write(csi, rx_count, CSI_CSIRXCNT); + + imag_para = (width << 16) | height; + imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA); + + /* reflash the embedded DMA controller */ + imx7_csi_dma_reflash(csi); +} + +static void imx7_csi_sw_reset(struct imx7_csi *csi) +{ + imx7_csi_hw_disable(csi); + + imx7_csi_rx_fifo_clear(csi); + + imx7_csi_dma_reflash(csi); + + usleep_range(2000, 3000); + + imx7_csi_irq_clear(csi); + + imx7_csi_hw_enable(csi); +} + +static void imx7_csi_error_recovery(struct imx7_csi *csi) +{ + imx7_csi_hw_disable(csi); + + imx7_csi_rx_fifo_clear(csi); + + imx7_csi_dma_reflash(csi); + + imx7_csi_hw_enable(csi); +} + +static void imx7_csi_init(struct imx7_csi *csi) +{ + if (csi->is_init) + return; + + imx7_csi_clk_enable(csi); + imx7_csi_hw_reset(csi); + imx7_csi_init_interface(csi); + imx7_csi_dmareq_rff_enable(csi); + + csi->is_init = true; +} + +static void imx7_csi_deinit(struct imx7_csi *csi) +{ + if (!csi->is_init) + return; + + imx7_csi_hw_reset(csi); + imx7_csi_init_interface(csi); + imx7_csi_dmareq_rff_disable(csi); + imx7_csi_clk_disable(csi); + + csi->is_init = false; +} + +static int imx7_csi_get_upstream_endpoint(struct imx7_csi *csi, + struct v4l2_fwnode_endpoint *ep, + bool skip_mux) +{ + struct device_node *endpoint, *port; + struct media_entity *src; + struct v4l2_subdev *sd; + struct media_pad *pad; + + if (!csi->src_sd) + return -EPIPE; + + src = &csi->src_sd->entity; + +skip_video_mux: + /* get source pad of entity directly upstream from src */ + pad = imx_media_find_upstream_pad(csi->md, src, 0); + if (IS_ERR(pad)) + return PTR_ERR(pad); + + sd = media_entity_to_v4l2_subdev(pad->entity); + + /* To get bus type we may need to skip video mux */ + if (skip_mux && src->function == MEDIA_ENT_F_VID_MUX) { + src = &sd->entity; + goto skip_video_mux; + } + + /* + * NOTE: this assumes an OF-graph port id is the same as a + * media pad index. + */ + port = of_graph_get_port_by_id(sd->dev->of_node, pad->index); + if (!port) + return -ENODEV; + + endpoint = of_get_next_child(port, NULL); + of_node_put(port); + if (!endpoint) + return -ENODEV; + + v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep); + of_node_put(endpoint); + + return 0; +} + +static int imx7_csi_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_subdev *remote_sd; + int ret = 0; + + dev_dbg(csi->dev, "link setup %s -> %s\n", remote->entity->name, + local->entity->name); + + mutex_lock(&csi->lock); + + if (local->flags & MEDIA_PAD_FL_SINK) { + if (!is_media_entity_v4l2_subdev(remote->entity)) { + ret = -EINVAL; + goto unlock; + } + + remote_sd = media_entity_to_v4l2_subdev(remote->entity); + + if (flags & MEDIA_LNK_FL_ENABLED) { + if (csi->src_sd) { + ret = -EBUSY; + goto unlock; + } + csi->src_sd = remote_sd; + } else { + csi->src_sd = NULL; + } + + goto init; + } + + /* source pad */ + if (flags & MEDIA_LNK_FL_ENABLED) { + if (csi->sink) { + ret = -EBUSY; + goto unlock; + } + csi->sink = remote->entity; + } else { + v4l2_ctrl_handler_free(&csi->ctrl_hdlr); + v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0); + csi->sink = NULL; + } + +init: + if (csi->sink || csi->src_sd) + imx7_csi_init(csi); + else + imx7_csi_deinit(csi); + +unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_fwnode_endpoint upstream_ep; + int ret; + + ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt); + if (ret) + return ret; + + ret = imx7_csi_get_upstream_endpoint(csi, &upstream_ep, true); + if (ret) { + v4l2_err(&csi->sd, "failed to find upstream endpoint\n"); + return ret; + } + + mutex_lock(&csi->lock); + + csi->upstream_ep = upstream_ep; + csi->is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2); + + mutex_unlock(&csi->lock); + + return 0; +} + +static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys, + int buf_num) +{ + if (buf_num == 1) + imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2); + else + imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1); +} + +static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct imx_media_buffer *buf; + struct vb2_buffer *vb2_buf; + dma_addr_t phys[2]; + int i; + + for (i = 0; i < 2; i++) { + buf = imx_media_capture_device_next_buf(vdev); + if (buf) { + csi->active_vb2_buf[i] = buf; + vb2_buf = &buf->vbuf.vb2_buf; + phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0); + } else { + csi->active_vb2_buf[i] = NULL; + phys[i] = csi->underrun_buf.phys; + } + + imx7_csi_update_buf(csi, phys[i], i); + } +} + +static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi, + enum vb2_buffer_state return_status) +{ + struct imx_media_buffer *buf; + int i; + + /* return any remaining active frames with return_status */ + for (i = 0; i < 2; i++) { + buf = csi->active_vb2_buf[i]; + if (buf) { + struct vb2_buffer *vb = &buf->vbuf.vb2_buf; + + vb->timestamp = ktime_get_ns(); + vb2_buffer_done(vb, return_status); + } + } +} + +static void imx7_csi_vb2_buf_done(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct imx_media_buffer *done, *next; + struct vb2_buffer *vb; + dma_addr_t phys; + + done = csi->active_vb2_buf[csi->buf_num]; + if (done) { + done->vbuf.field = vdev->fmt.fmt.pix.field; + done->vbuf.sequence = csi->frame_sequence; + vb = &done->vbuf.vb2_buf; + vb->timestamp = ktime_get_ns(); + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + } + csi->frame_sequence++; + + /* get next queued buffer */ + next = imx_media_capture_device_next_buf(vdev); + if (next) { + phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0); + csi->active_vb2_buf[csi->buf_num] = next; + } else { + phys = csi->underrun_buf.phys; + csi->active_vb2_buf[csi->buf_num] = NULL; + } + + imx7_csi_update_buf(csi, phys, csi->buf_num); +} + +static irqreturn_t imx7_csi_irq_handler(int irq, void *data) +{ + struct imx7_csi *csi = data; + unsigned long status; + + spin_lock(&csi->irqlock); + + status = imx7_csi_irq_clear(csi); + + if (status & BIT_RFF_OR_INT) { + dev_warn(csi->dev, "Rx fifo overflow\n"); + imx7_csi_error_recovery(csi); + } + + if (status & BIT_HRESP_ERR_INT) { + dev_warn(csi->dev, "Hresponse error detected\n"); + imx7_csi_error_recovery(csi); + } + + if (status & BIT_ADDR_CH_ERR_INT) { + imx7_csi_hw_disable(csi); + + imx7_csi_dma_reflash(csi); + + imx7_csi_hw_enable(csi); + } + + if ((status & BIT_DMA_TSF_DONE_FB1) && + (status & BIT_DMA_TSF_DONE_FB2)) { + /* + * For both FB1 and FB2 interrupter bits set case, + * CSI DMA is work in one of FB1 and FB2 buffer, + * but software can not know the state. + * Skip it to avoid base address updated + * when csi work in field0 and field1 will write to + * new base address. + */ + } else if (status & BIT_DMA_TSF_DONE_FB1) { + csi->buf_num = 0; + } else if (status & BIT_DMA_TSF_DONE_FB2) { + csi->buf_num = 1; + } + + if ((status & BIT_DMA_TSF_DONE_FB1) || + (status & BIT_DMA_TSF_DONE_FB2)) { + imx7_csi_vb2_buf_done(csi); + + if (csi->last_eof) { + complete(&csi->last_eof_completion); + csi->last_eof = false; + } + } + + + spin_unlock(&csi->irqlock); + + return IRQ_HANDLED; +} + +static int imx7_csi_dma_start(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix; + int ret; + + ret = imx_media_alloc_dma_buf(csi->md, &csi->underrun_buf, + out_pix->sizeimage); + if (ret < 0) { + v4l2_warn(&csi->sd, "consider increasing the CMA area\n"); + return ret; + } + + csi->frame_sequence = 0; + csi->last_eof = false; + init_completion(&csi->last_eof_completion); + + imx7_csi_setup_vb2_buf(csi); + + return 0; +} + +static void imx7_csi_dma_stop(struct imx7_csi *csi) +{ + unsigned long flags; + int ret; + + /* mark next EOF interrupt as the last before stream off */ + spin_lock_irqsave(&csi->irqlock, flags); + csi->last_eof = true; + spin_unlock_irqrestore(&csi->irqlock, flags); + + /* + * and then wait for interrupt handler to mark completion. + */ + ret = wait_for_completion_timeout(&csi->last_eof_completion, + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT)); + if (ret == 0) + v4l2_warn(&csi->sd, "wait last EOF timeout\n"); + + imx7_csi_hw_disable_irq(csi); + + imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR); + + imx_media_free_dma_buf(csi->md, &csi->underrun_buf); +} + +static int imx7_csi_configure(struct imx7_csi *csi) +{ + struct imx_media_video_dev *vdev = csi->vdev; + struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix; + __u32 in_code = csi->format_mbus[IMX7_CSI_PAD_SINK].code; + u32 cr1, cr18; + + if (out_pix->field == V4L2_FIELD_INTERLACED) { + imx7_csi_deinterlace_enable(csi, true); + imx7_csi_buf_stride_set(csi, out_pix->width); + } else { + imx7_csi_deinterlace_enable(csi, false); + imx7_csi_buf_stride_set(csi, 0); + } + + imx7_csi_set_imagpara(csi, out_pix->width, out_pix->height); + + if (!csi->is_csi2) + return 0; + + cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + cr1 &= ~BIT_GCLK_MODE; + + cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); + cr18 &= BIT_MIPI_DATA_FORMAT_MASK; + cr18 |= BIT_DATA_FROM_MIPI; + + switch (out_pix->pixelformat) { + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B; + break; + case V4L2_PIX_FMT_SBGGR8: + cr18 |= BIT_MIPI_DATA_FORMAT_RAW8; + break; + case V4L2_PIX_FMT_SBGGR16: + if (in_code == MEDIA_BUS_FMT_SBGGR10_1X10) + cr18 |= BIT_MIPI_DATA_FORMAT_RAW10; + else if (in_code == MEDIA_BUS_FMT_SBGGR12_1X12) + cr18 |= BIT_MIPI_DATA_FORMAT_RAW12; + else if (in_code == MEDIA_BUS_FMT_SBGGR14_1X14) + cr18 |= BIT_MIPI_DATA_FORMAT_RAW14; + cr1 |= BIT_PIXEL_BIT; + break; + default: + return -EINVAL; + } + + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); + imx7_csi_reg_write(csi, cr18, CSI_CSICR18); + + return 0; +} + +static int imx7_csi_enable(struct imx7_csi *csi) +{ + imx7_csi_sw_reset(csi); + + if (csi->is_csi2) { + imx7_csi_dmareq_rff_enable(csi); + imx7_csi_hw_enable_irq(csi); + imx7_csi_hw_enable(csi); + return 0; + } + + return 0; +} + +static void imx7_csi_disable(struct imx7_csi *csi) +{ + imx7_csi_dmareq_rff_disable(csi); + + imx7_csi_hw_disable_irq(csi); + + imx7_csi_buf_stride_set(csi, 0); + + imx7_csi_hw_disable(csi); +} + +static int imx7_csi_streaming_start(struct imx7_csi *csi) +{ + int ret; + + ret = imx7_csi_dma_start(csi); + if (ret < 0) + return ret; + + ret = imx7_csi_configure(csi); + if (ret < 0) + goto dma_stop; + + imx7_csi_enable(csi); + + return 0; + +dma_stop: + imx7_csi_dma_stop(csi); + + return ret; +} + +static int imx7_csi_streaming_stop(struct imx7_csi *csi) +{ + imx7_csi_dma_stop(csi); + + imx7_csi_disable(csi); + + return 0; +} + +static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + int ret = 0; + + mutex_lock(&csi->lock); + + if (!csi->src_sd || !csi->sink) { + ret = -EPIPE; + goto out_unlock; + } + + if (csi->is_streaming == !!enable) + goto out_unlock; + + if (enable) { + ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1); + if (ret < 0) + goto out_unlock; + + ret = imx7_csi_streaming_start(csi); + if (ret < 0) { + v4l2_subdev_call(csi->src_sd, video, s_stream, 0); + goto out_unlock; + } + } else { + imx7_csi_streaming_stop(csi); + + v4l2_subdev_call(csi->src_sd, video, s_stream, 0); + } + + csi->is_streaming = !!enable; + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static struct v4l2_mbus_framefmt *imx7_csi_get_format(struct imx7_csi *csi, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&csi->sd, cfg, pad); + + return &csi->format_mbus[pad]; +} + +static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + const struct imx_media_pixfmt *in_cc; + struct v4l2_mbus_framefmt *in_fmt; + int ret = 0; + + mutex_lock(&csi->lock); + + in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK, code->which); + + in_cc = imx_media_find_mbus_format(in_fmt->code, CS_SEL_ANY, true); + + switch (code->pad) { + case IMX7_CSI_PAD_SINK: + ret = imx_media_enum_mbus_format(&code->code, code->index, + CS_SEL_ANY, true); + break; + case IMX7_CSI_PAD_SRC: + if (code->index != 0) { + ret = -EINVAL; + goto out_unlock; + } + + code->code = in_fmt->code; + break; + default: + ret = -EINVAL; + } + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static int imx7_csi_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *fmt; + int ret = 0; + + if (sdformat->pad >= IMX7_CSI_PADS_NUM) + return -EINVAL; + + mutex_lock(&csi->lock); + + fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); + if (!fmt) { + ret = -EINVAL; + goto out_unlock; + } + + sdformat->format = *fmt; + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static void imx7_csi_try_fmt(struct imx7_csi *csi, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat, + const struct imx_media_pixfmt **cc) +{ + const struct imx_media_pixfmt *in_cc; + struct v4l2_mbus_framefmt *in_fmt; + u32 code; + + in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK, + sdformat->which); + if (!in_fmt) + return; + + switch (sdformat->pad) { + case IMX7_CSI_PAD_SRC: + in_cc = imx_media_find_mbus_format(in_fmt->code, CS_SEL_ANY, + true); + + sdformat->format.width = in_fmt->width; + sdformat->format.height = in_fmt->height; + sdformat->format.code = in_fmt->code; + *cc = in_cc; + + sdformat->format.colorspace = in_fmt->colorspace; + sdformat->format.xfer_func = in_fmt->xfer_func; + sdformat->format.quantization = in_fmt->quantization; + sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc; + break; + case IMX7_CSI_PAD_SINK: + *cc = imx_media_find_mbus_format(sdformat->format.code, + CS_SEL_ANY, true); + if (!*cc) { + imx_media_enum_mbus_format(&code, 0, CS_SEL_ANY, false); + *cc = imx_media_find_mbus_format(code, CS_SEL_ANY, + false); + sdformat->format.code = (*cc)->codes[0]; + } + + imx_media_fill_default_mbus_fields(&sdformat->format, in_fmt, + false); + break; + default: + break; + } +} + +static int imx7_csi_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct imx_media_video_dev *vdev = csi->vdev; + const struct imx_media_pixfmt *outcc; + struct v4l2_mbus_framefmt *outfmt; + struct v4l2_pix_format vdev_fmt; + const struct imx_media_pixfmt *cc; + struct v4l2_mbus_framefmt *fmt; + struct v4l2_subdev_format format; + int ret = 0; + + if (sdformat->pad >= IMX7_CSI_PADS_NUM) + return -EINVAL; + + mutex_lock(&csi->lock); + + if (csi->is_streaming) { + ret = -EBUSY; + goto out_unlock; + } + + imx7_csi_try_fmt(csi, cfg, sdformat, &cc); + + fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); + if (!fmt) { + ret = -EINVAL; + goto out_unlock; + } + + *fmt = sdformat->format; + + if (sdformat->pad == IMX7_CSI_PAD_SINK) { + /* propagate format to source pads */ + format.pad = IMX7_CSI_PAD_SRC; + format.which = sdformat->which; + format.format = sdformat->format; + imx7_csi_try_fmt(csi, cfg, &format, &outcc); + + outfmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SRC, + sdformat->which); + *outfmt = format.format; + + if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) + csi->cc[IMX7_CSI_PAD_SRC] = outcc; + } + + if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) + goto out_unlock; + + csi->cc[sdformat->pad] = cc; + + /* propagate output pad format to capture device */ + imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt, + &csi->format_mbus[IMX7_CSI_PAD_SRC], + csi->cc[IMX7_CSI_PAD_SRC]); + mutex_unlock(&csi->lock); + imx_media_capture_device_set_format(vdev, &vdev_fmt); + + return 0; + +out_unlock: + mutex_unlock(&csi->lock); + + return ret; +} + +static int imx7_csi_registered(struct v4l2_subdev *sd) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + int ret; + int i; + + csi->md = dev_get_drvdata(sd->v4l2_dev->dev); + + for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { + csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ? + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; + + /* set a default mbus format */ + ret = imx_media_init_mbus_fmt(&csi->format_mbus[i], + 800, 600, 0, V4L2_FIELD_NONE, + &csi->cc[i]); + if (ret < 0) + return ret; + + /* init default frame interval */ + csi->frame_interval[i].numerator = 1; + csi->frame_interval[i].denominator = 30; + } + + ret = media_entity_pads_init(&sd->entity, IMX7_CSI_PADS_NUM, csi->pad); + if (ret < 0) + return ret; + + ret = imx_media_capture_device_register(csi->vdev); + if (ret < 0) + return ret; + + ret = imx_media_add_video_device(csi->md, csi->vdev); + if (ret < 0) { + imx_media_capture_device_unregister(csi->vdev); + return ret; + } + + return 0; +} + +static void imx7_csi_unregistered(struct v4l2_subdev *sd) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + + imx_media_capture_device_unregister(csi->vdev); +} + +static int imx7_csi_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *mf; + int ret; + int i; + + for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { + mf = v4l2_subdev_get_try_format(sd, cfg, i); + + ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE, + &csi->cc[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +static const struct media_entity_operations imx7_csi_entity_ops = { + .link_setup = imx7_csi_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +static const struct v4l2_subdev_video_ops imx7_csi_video_ops = { + .s_stream = imx7_csi_s_stream, +}; + +static const struct v4l2_subdev_pad_ops imx7_csi_pad_ops = { + .init_cfg = imx7_csi_init_cfg, + .enum_mbus_code = imx7_csi_enum_mbus_code, + .get_fmt = imx7_csi_get_fmt, + .set_fmt = imx7_csi_set_fmt, + .link_validate = imx7_csi_pad_link_validate, +}; + +static const struct v4l2_subdev_ops imx7_csi_subdev_ops = { + .video = &imx7_csi_video_ops, + .pad = &imx7_csi_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = { + .registered = imx7_csi_registered, + .unregistered = imx7_csi_unregistered, +}; + +static int imx7_csi_parse_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd) +{ + return fwnode_device_is_available(asd->match.fwnode) ? 0 : -EINVAL; +} + +static int imx7_csi_parse_dt(struct imx7_csi *csi) +{ + struct device *dev = csi->dev; + + csi->clk_disp_axi = devm_clk_get(dev, "axi"); + if (IS_ERR(csi->clk_disp_axi)) { + dev_err(dev, "Could not get csi axi clock\n"); + return -ENODEV; + } + + csi->clk_disp_dcic = devm_clk_get(dev, "dcic"); + if (IS_ERR(csi->clk_disp_dcic)) { + dev_err(dev, "Could not get disp dcic clock\n"); + return -ENODEV; + } + + csi->clk_csi_mclk = devm_clk_get(dev, "mclk"); + if (IS_ERR(csi->clk_csi_mclk)) { + dev_err(dev, "Could not get csi mclk clock\n"); + return -ENODEV; + } + + return 0; +} + +static int imx7_csi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct imx7_csi *csi; + struct resource *res; + int ret; + + csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL); + if (!csi) + return -ENOMEM; + + platform_set_drvdata(pdev, &csi->sd); + csi->dev = dev; + + ret = imx7_csi_parse_dt(csi); + if (ret < 0) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + csi->irq = platform_get_irq(pdev, 0); + if (!res || csi->irq < 0) { + dev_err(dev, "Missing platform resources data\n"); + return -ENODEV; + } + + csi->regbase = devm_ioremap_resource(dev, res); + if (IS_ERR(csi->regbase)) { + dev_err(dev, "Failed platform resources map\n"); + return -ENODEV; + } + + spin_lock_init(&csi->irqlock); + mutex_init(&csi->lock); + + /* install interrupt handler */ + ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi", + (void *)csi); + if (ret < 0) { + dev_err(dev, "Request CSI IRQ failed.\n"); + return -ENODEV; + } + + /* add media device */ + csi->imxmd = imx_media_dev_init(dev); + if (IS_ERR(csi->imxmd)) + return PTR_ERR(csi->imxmd); + + ret = imx_media_of_add_csi(csi->imxmd, node); + if (ret < 0) + goto media_cleanup; + + ret = imx_media_dev_notifier_register(csi->imxmd); + if (ret < 0) + goto media_cleanup; + + v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops); + v4l2_set_subdevdata(&csi->sd, csi); + csi->sd.internal_ops = &imx7_csi_internal_ops; + csi->sd.entity.ops = &imx7_csi_entity_ops; + csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + csi->sd.dev = &pdev->dev; + csi->sd.owner = THIS_MODULE; + csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + csi->sd.grp_id = IMX_MEDIA_GRP_ID_CSI; + snprintf(csi->sd.name, sizeof(csi->sd.name), "csi"); + + csi->vdev = imx_media_capture_device_init(&csi->sd, IMX7_CSI_PAD_SRC); + if (IS_ERR(csi->vdev)) + return PTR_ERR(csi->vdev); + + v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0); + csi->sd.ctrl_handler = &csi->ctrl_hdlr; + + ret = v4l2_async_register_fwnode_subdev(&csi->sd, + sizeof(struct v4l2_async_subdev), + NULL, 0, imx7_csi_parse_endpoint); + if (ret) + goto free; + + return 0; + +free: + v4l2_ctrl_handler_free(&csi->ctrl_hdlr); + mutex_destroy(&csi->lock); + imx_media_capture_device_remove(csi->vdev); + +media_cleanup: + imx_media_dev_cleanup(csi->imxmd); + + return ret; +} + +static int imx7_csi_remove(struct platform_device *pdev) +{ + struct v4l2_subdev *sd = platform_get_drvdata(pdev); + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + + v4l2_ctrl_handler_free(&csi->ctrl_hdlr); + mutex_destroy(&csi->lock); + imx_media_capture_device_remove(csi->vdev); + imx_media_dev_notifier_unregister(csi->imxmd); + imx_media_dev_cleanup(csi->imxmd); + media_entity_cleanup(&sd->entity); + v4l2_async_unregister_subdev(sd); + + return 0; +} + +static const struct of_device_id imx7_csi_of_match[] = { + { .compatible = "fsl,imx7-csi" }, + { }, +}; +MODULE_DEVICE_TABLE(of, imx7_csi_of_match); + +static struct platform_driver imx7_csi_driver = { + .probe = imx7_csi_probe, + .remove = imx7_csi_remove, + .driver = { + .of_match_table = imx7_csi_of_match, + .name = "imx7-csi", + }, +}; +module_platform_driver(imx7_csi_driver); + +MODULE_DESCRIPTION("i.MX7 CSI subdev driver"); +MODULE_AUTHOR("Rui Miguel Silva "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:imx7-csi"); From patchwork Tue May 22 14:52:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 136562 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp1735010lji; Tue, 22 May 2018 07:53:18 -0700 (PDT) X-Google-Smtp-Source: AB8JxZp8WGtNIsi2/802Tfn4ikiUYKUwZndE4/a441PXOjaeSYznUoWD8B8I/oeTlbJeCBH4GeZs X-Received: by 2002:a65:590d:: with SMTP id f13-v6mr13077175pgu.313.1527000798083; Tue, 22 May 2018 07:53:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527000798; cv=none; d=google.com; s=arc-20160816; b=ivz6JvIdMrw5tByIARFuffER6BFqTT6yafQPVE6BaFn8eu6r3zTjZ52Lxcpup5ao0H R+xURJkVJkIARgG9VdDZpzkK7os6Ss+HKQSsCf/dof42q3HRTTw81VMC+VH8lkI4XTlc R1pvs5NCq/DgvkAMC+10JlD6AAo1SZuYJAkvvSDQ4oPyAdE00WXazdwFgKblN0fi1IRL idihzBZis0/YouBxDGuN7GjDPp7GYbBYdNHe3yXGMTMctM6A0yqvCE8WKIkiaGuv2osb aTtP6GzMDaa9axtNuz09FhwGeOL0wakk2hNKxQe7WfGLoIbu0Y4Q2v0Bu7PsR0zM6gnK KiSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=a5Nzm/PlIa+x1DZueAOEUXeNo4zY7zJzesOFKn4ZzCY=; b=khpUB6xcWllW4opQNWFjtyn8sB3qRsoSotmaaTEvloUzAzni2W27Qnr5GEgpQZUYnv jVJCNYEVp28U0A+cwxQXPzWVC7mezTErI1uM5HM0ZMrxpu5HzBM+tXvzHx51+i1xcm7q XdN40KdBqXXmnB7GVlqpytyg7SBojUjiB1f9LqnFzZUDqh363w/h8NqelDCVCY6mUPKD DWoxB0x2k0skq3ZkovUCTWmwD7pL+day/K6XLFEkKvkIh96nLTRBJVGi8odMMEF98sjM 7FKm3SRRVypp/gtpk86otuQTyk2GQPc+YG3FHsNAEVkN3ONDVnL7LaLBwHAfj3yCD1RG fJPg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=a3pyY/Fo; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q28-v6si16922041pfl.317.2018.05.22.07.53.17; Tue, 22 May 2018 07:53:18 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=a3pyY/Fo; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751724AbeEVOxQ (ORCPT + 5 others); Tue, 22 May 2018 10:53:16 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:53036 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751637AbeEVOxL (ORCPT ); Tue, 22 May 2018 10:53:11 -0400 Received: by mail-wm0-f68.google.com with SMTP id w194-v6so564518wmf.2 for ; Tue, 22 May 2018 07:53:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+GivAHxNif/Lo/d+/LTBZpU07EAf+f1M3F3+8RpbDnE=; b=a3pyY/FoOzPJhczcQFPNH53E2Ak6GiP4JuF7qzAHr9/bB0KbeSMpSG8C1JKPUBujVQ A8NmmrWmyifxxVz3WxnOAKKoXuuC2W+zmTTjuIFj4eTjw7GlP2oVqbwI7mRYBJYXHUG8 qFDdYihvPtDE4EBAxcZvhEXR/395AVjdt1t8c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+GivAHxNif/Lo/d+/LTBZpU07EAf+f1M3F3+8RpbDnE=; b=ruiJLZppK8rrTbtYcuH/yCpA0hvg9Ot9Cqqfqc/lthdWz32oiz+95L21MGKW3aSePE fUDfsFtLolt+PUzonXCbs7nwQgVVkfuOg63Jwp0Zx7o8d6+hT7crri6VBmf1ZpzuC2VN 3K4CYSuQohOubpfIj/Efh+rbRrQkREKaT4abuFMB+fXuhZjm4+49xDgn0+oX8cOQa2Iv piKOvsCjVjUnhnnOuRPIC0xkO2Az0WhDnfDyO8zla+rfvHQ6+RyCNCHM3xgb2oblHY8R 4NkpUv/MA8u6yecBKmXe6EXB8gL7b7jzFGvDzek5QlqCENUir72WPql5tol8t9PYO0JD K3cA== X-Gm-Message-State: ALKqPweBx8r4NMmZHHrgynPMGfYfmFSYbS/4zuIVUODB+y6q1rl9gNf1 lVsoLREYErJK6WKF1JSYkowVgA== X-Received: by 2002:a1c:4584:: with SMTP id l4-v6mr1457500wmi.142.1527000790042; Tue, 22 May 2018 07:53:10 -0700 (PDT) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 75-v6sm76878wmw.37.2018.05.22.07.53.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 07:53:09 -0700 (PDT) From: Rui Miguel Silva To: mchehab@kernel.org, sakari.ailus@linux.intel.com, Steve Longerbeam , Philipp Zabel , Rob Herring Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, Shawn Guo , Fabio Estevam , devicetree@vger.kernel.org, Greg Kroah-Hartman , Ryan Harkin , linux-clk@vger.kernel.org, Rui Miguel Silva Subject: [PATCH v6 05/13] clk: imx7d: reset parent for mipi csi root Date: Tue, 22 May 2018 15:52:37 +0100 Message-Id: <20180522145245.3143-6-rui.silva@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180522145245.3143-1-rui.silva@linaro.org> References: <20180522145245.3143-1-rui.silva@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org To guarantee that we do not get Overflow in image FIFO the outer bandwidth has to be faster than inputer bandwidth. For that it must be possible to set a faster frequency clock. So set new parent to sys_pfd3 clock for the mipi csi block. Acked-by: Shawn Guo Signed-off-by: Rui Miguel Silva --- drivers/clk/imx/clk-imx7d.c | 2 ++ 1 file changed, 2 insertions(+) -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index f7f4db2e6fa6..27877d05faa2 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -891,6 +891,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]); clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]); + clk_set_parent(clks[IMX7D_MIPI_CSI_ROOT_SRC], clks[IMX7D_PLL_SYS_PFD3_CLK]); + /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); From patchwork Tue May 22 14:52:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 136563 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp1735070lji; Tue, 22 May 2018 07:53:20 -0700 (PDT) X-Google-Smtp-Source: AB8JxZoZrwCtKpXJ5yCnpM10M+v39ePeIUiAv1EklBotxFbiMhCjoTL14ad4vkORyfq2r72BEp9/ X-Received: by 2002:a17:902:265:: with SMTP id 92-v6mr24457810plc.368.1527000800520; Tue, 22 May 2018 07:53:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527000800; cv=none; d=google.com; s=arc-20160816; b=gGZtmLAykeLYdQWbDCoRPwIMNu3JwAIB7pZuadF12KcxHfEUyOV0TJXSi+EDEZmX73 8Ipq52MvJAymUEuNcZobYgRv8mpt/b8SZso/lbps0pw6W01fY/eOg2IF70GWQif5PE2R Kt2uPWIGskfi30hM3kXSC+Owid+arx63Wzh5XDKqMyyN0RXoqfdXap+G5SUDO6uxb5Bd LLC1n7IMM/rkpwKl3JuB5/fk6tMEv3UAqOfef+G7N5MdJQcKFVDbOalHfie2KaK2rY9L 3Ryj6VW3pmZKpovxIxKiEPw8hvV8a5+jjhy+6xpt902sr96NCsv9zd5KRaMhPus2vV/8 gBeg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=e8+DpPwCpyuU3ySVcq/NR+10wwIpeECKXC8X262M770=; b=F8ufKaX16HGmLFa40hxubA+l4lgXYxvVxVbD6H92tCV8wTXQLhui2RNkhZg0jeP1mv no5kf7NGyp8niXbr11aSYKLcmNw/EhAFSYoo04Yv+bNMc9r/QwE3Av1s4Kg949F5pA7d jmGVflXxynNu7CjOhJk54cXeW62h5rolL/wMmG8EfZyXjciZEuiGphcZ4ah9XhVr4dz7 TsWCFExUGWDaLiu5lwVLWkP4qOHNTG70TjVwbGUENNnlZUR7WKY6kHQsDqS60mhZ6Mfs kQ3085zKycrXKs52CJQAek5XQcQF6cOc+hgHTAeZREvpk6SQQ+puC2yv5RF7sNcNWojv SCVg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=i8Ce6I93; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q28-v6si16922041pfl.317.2018.05.22.07.53.20; Tue, 22 May 2018 07:53:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=i8Ce6I93; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751730AbeEVOxT (ORCPT + 5 others); Tue, 22 May 2018 10:53:19 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:50197 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751236AbeEVOxQ (ORCPT ); Tue, 22 May 2018 10:53:16 -0400 Received: by mail-wm0-f67.google.com with SMTP id t11-v6so607002wmt.0 for ; Tue, 22 May 2018 07:53:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hQq4Vaw6zFi0fIf8PV4IBbqetBVRr7pDmc/oK85IFas=; b=i8Ce6I93PtF8JXfuMYdXl6z60+3bd6MDKo/7zgSZtkhNrADtOT2o/AkHpwqHM1Vu5Q IcwMfWt7hQQgRyPzHlbL3qfsRp+qkb+LNT5EV+fhKQ21YmLKx2D6UU2aoFhCVl6LPY1Y f9c1bSq7jTy73/oY3Gxq7CvJY96fnZ2ELuacE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hQq4Vaw6zFi0fIf8PV4IBbqetBVRr7pDmc/oK85IFas=; b=ondenvZ7hX5ntOtoGRHs2BIAekWwSjv267iEW7R2q/WqJpidquwsla9OHfIrOXQecR Vb4Gh6HPNBWw3L15o6QYsZzyDWReUCBjnWrNLDAtrNPuG+W86R3u486W8NpQ5g7qd7lm fsImH23S27WTEwUy66p6sSJE92IrXaqPjbRDTQmZtrmoCXzzVM2LQDvvZZB2hY+726ga 4Xhx++PNpz51ugQ6mVZbCDe7iQiWkByDhGe919iYZAG9enZV0Ekjlo9T+Kw0Ftu9L80+ j9lPiZxytzmvKXTiXOke4vCrCpq8QdurY8UoAJKssi2Fj1+0BzHX222KvFAO4G5h8n6T ERUw== X-Gm-Message-State: ALKqPwfQG+ftjxGzl5KBxBY/8ulcrbJi/OvKENe8ysPNCMY5xKHYe709 qiBuuMRcgWaheigtZSQPvqVVwA== X-Received: by 2002:a1c:d53:: with SMTP id 80-v6mr1621850wmn.138.1527000795289; Tue, 22 May 2018 07:53:15 -0700 (PDT) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 75-v6sm76878wmw.37.2018.05.22.07.53.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 07:53:14 -0700 (PDT) From: Rui Miguel Silva To: mchehab@kernel.org, sakari.ailus@linux.intel.com, Steve Longerbeam , Philipp Zabel , Rob Herring Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, Shawn Guo , Fabio Estevam , devicetree@vger.kernel.org, Greg Kroah-Hartman , Ryan Harkin , linux-clk@vger.kernel.org, Rui Miguel Silva Subject: [PATCH v6 07/13] media: dt-bindings: add bindings for i.MX7 media driver Date: Tue, 22 May 2018 15:52:39 +0100 Message-Id: <20180522145245.3143-8-rui.silva@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180522145245.3143-1-rui.silva@linaro.org> References: <20180522145245.3143-1-rui.silva@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add bindings documentation for i.MX7 media drivers. The imx7 MIPI CSI2 and imx7 CMOS Sensor Interface. Signed-off-by: Rui Miguel Silva --- .../devicetree/bindings/media/imx7-csi.txt | 44 ++++++++++ .../bindings/media/imx7-mipi-csi2.txt | 82 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/imx7-csi.txt create mode 100644 Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Rob Herring diff --git a/Documentation/devicetree/bindings/media/imx7-csi.txt b/Documentation/devicetree/bindings/media/imx7-csi.txt new file mode 100644 index 000000000000..aab4f5d72390 --- /dev/null +++ b/Documentation/devicetree/bindings/media/imx7-csi.txt @@ -0,0 +1,44 @@ +Freescale i.MX7 CMOS Sensor Interface +===================================== + +csi node +-------- + +This is device node for the CMOS Sensor Interface (CSI) which enables the chip +to connect directly to external CMOS image sensors. + +Required properties: + +- compatible : "fsl,imx7-csi"; +- reg : base address and length of the register set for the device; +- interrupts : should contain CSI interrupt; +- clocks : list of clock specifiers, see + Documentation/devicetree/bindings/clock/clock-bindings.txt for details; +- clock-names : must contain "axi", "mclk" and "dcic" entries, matching + entries in the clock property; + +The device node should contain one 'port' child node with one child 'endpoint' +node, according to the bindings defined in Documentation/devicetree/bindings/ +media/video-interfaces.txt. In the following example a remote endpoint is a +video multiplexer. + +example: + + csi: csi@30710000 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "fsl,imx7-csi"; + reg = <0x30710000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_CLK_DUMMY>, + <&clks IMX7D_CSI_MCLK_ROOT_CLK>, + <&clks IMX7D_CLK_DUMMY>; + clock-names = "axi", "mclk", "dcic"; + + port { + csi_from_csi_mux: endpoint { + remote-endpoint = <&csi_mux_to_csi>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt b/Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt new file mode 100644 index 000000000000..7c5f20863724 --- /dev/null +++ b/Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt @@ -0,0 +1,82 @@ +Freescale i.MX7 Mipi CSI2 +========================= + +mipi_csi2 node +-------------- + +This is the device node for the MIPI CSI-2 receiver core in i.MX7 SoC. It is +compatible with previous version of Samsung D-phy. + +Required properties: + +- compatible : "fsl,imx7-mipi-csi2"; +- reg : base address and length of the register set for the device; +- interrupts : should contain MIPI CSIS interrupt; +- clocks : list of clock specifiers, see + Documentation/devicetree/bindings/clock/clock-bindings.txt for details; +- clock-names : must contain "pclk", "wrap" and "phy" entries, matching + entries in the clock property; +- power-domains : a phandle to the power domain, see + Documentation/devicetree/bindings/power/power_domain.txt for details. +- reset-names : should include following entry "mrst"; +- resets : a list of phandle, should contain reset entry of + reset-names; +- phy-supply : from the generic phy bindings, a phandle to a regulator that + provides power to MIPI CSIS core; + +Optional properties: + +- clock-frequency : The IP's main (system bus) clock frequency in Hz, default + value when this property is not specified is 166 MHz; +- fsl,csis-hs-settle : differential receiver (HS-RX) settle time; + +port node +--------- + +- reg : (required) can take the values 0 or 1, where 0 is the + related sink port and port 1 should be the source one; + +endpoint node +------------- + +- data-lanes : (required) an array specifying active physical MIPI-CSI2 + data input lanes and their mapping to logical lanes; the + array's content is unused, only its length is meaningful; + +example: + + mipi_csi: mipi-csi@30750000 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "fsl,imx7-mipi-csi2"; + reg = <0x30750000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_MIPI_CSI_ROOT_CLK>, + <&clks IMX7D_MIPI_DPHY_ROOT_CLK>; + clock-names = "pclk", "wrap", "phy"; + clock-frequency = <166000000>; + power-domains = <&pgc_mipi_phy>; + phy-supply = <®_1p0d>; + resets = <&src IMX7_RESET_MIPI_PHY_MRST>; + reset-names = "mrst"; + fsl,csis-hs-settle = <3>; + + port@0 { + reg = <0>; + + mipi_from_sensor: endpoint { + remote-endpoint = <&ov2680_to_mipi>; + data-lanes = <1>; + }; + }; + + port@1 { + reg = <1>; + + mipi_vc0_to_csi_mux: endpoint { + remote-endpoint = <&csi_mux_from_mipi_vc0>; + }; + }; + }; From patchwork Tue May 22 14:52:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 136569 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp1735369lji; Tue, 22 May 2018 07:53:38 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpSLXmsq6Z2Kd0y61QHC9KkcMxcqszECjjHM/sZ2NLSz+L4yHElfNw+L1Ovz8tA0FHfd/he X-Received: by 2002:a65:6395:: with SMTP id h21-v6mr10040026pgv.267.1527000817970; Tue, 22 May 2018 07:53:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527000817; cv=none; d=google.com; s=arc-20160816; b=R61dKwAYfECY90exOfL9C8TXg/aMpmgxTskEvP3xC4nHxXptp8sihT8LAkXO1cnHvQ 94PEmaVo3y1Ufpd+EOIWgFiiZyyKgq4v54x72Edpw15xzqM0tNtw7a+bXwYOMV2EB3HN FdHGIoPGmIl9h3zibtZ6kxVy8IGzDDaRlx1VKkwnkv98SZMWE9A+uqMDzWOcNDfBoSmN EHIrMczmGRBHTmZEXLfJVMy1jocSONQr1/MqkMK+bximPhz0fgweyLpgdaRSIYB+Jlfl nbrwgrIvxGge7foZvBys2aGCmPMj+CNj50VeZCQ/P4RCrn9i3gUFwH1M9t6xwpeKaoEg UhkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=Na8yGQwybofyINhBtxyXEOHJS/4Nrqeu0vcobLJDPiE=; b=x1JVrekSRiw2cMmtnTQwK5HhAh/eCLcS2UEJfxMLiZ0gM2gcRp8NBrOCB3CGx0O5xh HWBJb0heoiAq/6JIzXpDjSLP9ZY587hv/9d4oepboD8GpZhZIz6AqTN7tFmiZhVdMiSE 1KGWfciukHLc/NWKEGO0S8SBDcD1VeSutGYOdfDS3l4sZ3hQAmRYa7CSmApX1MlCFsPX pCoBdu9m7jRhmK1FADIELxsRoj+JD/aAdnlJAssUrv8dhMldlac/AZAjCzNhuTFUcueS 3MhxxVWOMEDuQmEFm3KoleBC6C8svKh26YHJ17/N/jLCErNZnZo1DFxVdk5zGeYRQVFD CoMg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=SjXCCS1T; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q28-v6si16922041pfl.317.2018.05.22.07.53.37; Tue, 22 May 2018 07:53:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=SjXCCS1T; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751342AbeEVOxg (ORCPT + 5 others); Tue, 22 May 2018 10:53:36 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:33663 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751741AbeEVOxV (ORCPT ); Tue, 22 May 2018 10:53:21 -0400 Received: by mail-wm0-f68.google.com with SMTP id x12-v6so16881106wmc.0 for ; Tue, 22 May 2018 07:53:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1zgdnFVbj038JWyMCDb+h6Opcf6Eu56fMLZ7HX6VQ5c=; b=SjXCCS1TjwiE4ZJEwX39HmjR7qV781W2XI50v97xHkrb+Rx7QDKvdS2XvaKbnBiK6o 8hpXtW/x9kH/tLTZ1pofskeJcZX/kKn/s7GNclCOoXTwOTp/aDd4tnOOypVqZXyLSLDW J63FWQPP7fOI3DAx+rbRtniffDXJ3dIomoR88= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1zgdnFVbj038JWyMCDb+h6Opcf6Eu56fMLZ7HX6VQ5c=; b=Uk5rxmnl6GkTCoC/nZNoKpOGoIIB6leF6Z5vKf4aoUNeiHNEEl3JzZAW3wvEsVeTQa e/zq6zx7sTaZsU18KNNcSAtApwvdpYbGb4pY0QNIe0tKq05vo34qVOUBfst7ksiRbDa1 1qYUAs/OGEye0+mpxW6tOIDXvXvsKYhEi6g9etHEcZmvr3CjtxcSEL/6Wx2t9UfHl94H olYZ1gON101/rZuiYZTa0NkjX3QvwJYGLJngNcfHznNApKGeL+7iYkkJtSy5x2yliaxM i+Y8TkD1jE2pVkAVQXhVIpQm5YK6e4jlncPvOnVL2oyCSDzmMwCQd09V7qPZdSM2bv2y AGQw== X-Gm-Message-State: ALKqPwfOz9vU2MBOg6pp6YcJ0J/ncLRhxFS70BzODhCzfchjI56s1qsj KWqGshHhgd0cg4c+RAQLUj9zIA== X-Received: by 2002:a1c:4294:: with SMTP id k20-v6mr1386895wmi.7.1527000800470; Tue, 22 May 2018 07:53:20 -0700 (PDT) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 75-v6sm76878wmw.37.2018.05.22.07.53.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 07:53:19 -0700 (PDT) From: Rui Miguel Silva To: mchehab@kernel.org, sakari.ailus@linux.intel.com, Steve Longerbeam , Philipp Zabel , Rob Herring Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, Shawn Guo , Fabio Estevam , devicetree@vger.kernel.org, Greg Kroah-Hartman , Ryan Harkin , linux-clk@vger.kernel.org, Rui Miguel Silva Subject: [PATCH v6 09/13] ARM: dts: imx7s: add multiplexer controls Date: Tue, 22 May 2018 15:52:41 +0100 Message-Id: <20180522145245.3143-10-rui.silva@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180522145245.3143-1-rui.silva@linaro.org> References: <20180522145245.3143-1-rui.silva@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The IOMUXC General Purpose Register has bitfield to control video bus multiplexer to control the CSI input between the MIPI-CSI2 and parallel interface. Add that register and mask. Signed-off-by: Rui Miguel Silva Reviewed-by: Philipp Zabel --- arch/arm/boot/dts/imx7s.dtsi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 5e6d2063b143..0b0b85438869 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -520,8 +520,14 @@ gpr: iomuxc-gpr@30340000 { compatible = "fsl,imx7d-iomuxc-gpr", - "fsl,imx6q-iomuxc-gpr", "syscon"; + "fsl,imx6q-iomuxc-gpr", "syscon", "simple-mfd"; reg = <0x30340000 0x10000>; + + mux: mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <0>; + mux-reg-masks = <0x14 0x00000010>; + }; }; ocotp: ocotp-ctrl@30350000 { From patchwork Tue May 22 14:52:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 136566 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp1735208lji; Tue, 22 May 2018 07:53:28 -0700 (PDT) X-Google-Smtp-Source: AB8JxZr4w9+/oRBSDHoikNZR9N8CwOiP3/VI0hmST2rJ4d24kwiX4bvR6O8NKjuIsuWzdNmIDvBm X-Received: by 2002:a63:6f89:: with SMTP id k131-v6mr19333227pgc.237.1527000808866; Tue, 22 May 2018 07:53:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527000808; cv=none; d=google.com; s=arc-20160816; b=PYQ566iHXkYvPa+FpEA72dNft082ufumtws1GWp+eQCEB8aW3CJAWcPKPFCWdZtyVY 4GFcA5Zpd5o2GxiEs1cfiw7YJADc/sADsDNFcgkXuUH8Df5mvA9Yw3mp2RYH0T80KoAc IwORLZyc1AyOg43/yYNJwqggTVneK/w/ejtFgFljCy5TDz8gm6V3VOD6Pys9sMGjb1Ui bIOq/tzvi/B31PvM5wAR700i4wyCuHkJgFFuR7Ez3ncGJj9RG3GsNKWE/lSCA+ySgCfP icEWrXT85Z9nEIFHQRDXvO/xZQ6RKsypvZiX4NCQHYg6QScYZJlhY6vaDMjZYmZc1xc2 5f+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=qBB9aFtbHEapx3Td+C8vQ0m+r/W7bsoQEQAcwGoQhc4=; b=gSkJPqPbtdaFjMyRQGTz+gltKkzkhP6zpwslTt3jaO8Ca/h2LwhLDkDFwcN3gNqEym CBqyJjQneV8yZhZSJe6K2KIN/u2NWiI3osJm+EG3vEHObsvODIdSYt2MIxGNhiNY7Htd 6DRBgtxBTsrQX474HPUtTDUowlZCYZ2v1ovWBraypa81Kf4wrnJtR9nkLXUE2CWdEwp0 lYdsGHiw6P29OhRh6IhF00E8OH8nKRspR/9cGxNv9x6B3hqQx5YwB+TRy7OYfBnBEgyt LLJImvcPCUpPgAuyG0f6TSDDfqNrKWs6MP4DUBsL4sbll7UZM2P9B7JmaHjqUdqP0J1n gp4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=KNYmMfgc; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q28-v6si16922041pfl.317.2018.05.22.07.53.28; Tue, 22 May 2018 07:53:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=KNYmMfgc; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751801AbeEVOx1 (ORCPT + 5 others); Tue, 22 May 2018 10:53:27 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:36473 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751713AbeEVOxY (ORCPT ); Tue, 22 May 2018 10:53:24 -0400 Received: by mail-wm0-f68.google.com with SMTP id n10-v6so606146wmc.1 for ; Tue, 22 May 2018 07:53:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zQedFqdWKosarK3EAU9NBJ1Z6CrFguyJO5a8vN1G6F8=; b=KNYmMfgcJ6fcB5Uk6FPBYHT9ZD20oSzQyvnpNZUa71A9p3kw+4HjC6eUa+m9okuHV+ 5zVaXKCg4M6wb3Uhd9sCpf5gAqY9MofWpghdKbMGTjW0nhA+u/px/lqN8wsYtIfY4Hbo 2SGPS5gcust6j/+un+D89QU72y4kwncWgRFXI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zQedFqdWKosarK3EAU9NBJ1Z6CrFguyJO5a8vN1G6F8=; b=UIdrEnI789lwzf8Gp8azTFuFQX1bD5Y3cAcHi14TLCfDUzzuiLzix4kausWtvKLB7O 0l93Tp820JfxKHvGBUcCK+q4/U4zPcj6VquHrLCORvx08CQhFCCp3C9zLVDYW3W9n0uv S4MTcQAXfyIyioLNSKVgBmEVWy1vfPOdjFPkTvhpnEypGWmtz62fKlWk3s8cl46XdjYr 2c7g4LZXMdD8+6o6SOJiDelQ1Wgv6lMabgUf3ONWYkuTGqtfFwEtl+3yMzrEHEhXGIO7 GTJhdH8LMqihYQgcWvHZYnS3fLJV7rLRlrTJfQk8i2ofyR2dhlca4hcPZQBQvLj+MsvJ yLgQ== X-Gm-Message-State: ALKqPwfN0GgvXaqqdz+jOWGD7ZBGfcHz80BlkIzduLRuCQbXDtYGlGaV t/O+lDLyMHJ/jl4GBYZttIksMg== X-Received: by 2002:a1c:904b:: with SMTP id s72-v6mr1445202wmd.85.1527000802850; Tue, 22 May 2018 07:53:22 -0700 (PDT) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 75-v6sm76878wmw.37.2018.05.22.07.53.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 07:53:22 -0700 (PDT) From: Rui Miguel Silva To: mchehab@kernel.org, sakari.ailus@linux.intel.com, Steve Longerbeam , Philipp Zabel , Rob Herring Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, Shawn Guo , Fabio Estevam , devicetree@vger.kernel.org, Greg Kroah-Hartman , Ryan Harkin , linux-clk@vger.kernel.org, Rui Miguel Silva Subject: [PATCH v6 10/13] ARM: dts: imx7: Add video mux, csi and mipi_csi and connections Date: Tue, 22 May 2018 15:52:42 +0100 Message-Id: <20180522145245.3143-11-rui.silva@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180522145245.3143-1-rui.silva@linaro.org> References: <20180522145245.3143-1-rui.silva@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch adds the device tree nodes for csi, video multiplexer and mipi-csi besides the graph connecting the necessary endpoints to make the media capture entities to work in imx7 Warp board. Signed-off-by: Rui Miguel Silva --- arch/arm/boot/dts/imx7s-warp.dts | 51 ++++++++++++++++++++++++++++++++ arch/arm/boot/dts/imx7s.dtsi | 27 +++++++++++++++++ 2 files changed, 78 insertions(+) -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/arm/boot/dts/imx7s-warp.dts b/arch/arm/boot/dts/imx7s-warp.dts index 8a30b148534d..cb175ee2fc9d 100644 --- a/arch/arm/boot/dts/imx7s-warp.dts +++ b/arch/arm/boot/dts/imx7s-warp.dts @@ -310,6 +310,57 @@ status = "okay"; }; +&gpr { + csi_mux { + compatible = "video-mux"; + mux-controls = <&mux 0>; + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + csi_mux_from_mipi_vc0: endpoint { + remote-endpoint = <&mipi_vc0_to_csi_mux>; + }; + }; + + port@2 { + reg = <2>; + + csi_mux_to_csi: endpoint { + remote-endpoint = <&csi_from_csi_mux>; + }; + }; + }; +}; + +&csi { + status = "okay"; + + port { + csi_from_csi_mux: endpoint { + remote-endpoint = <&csi_mux_to_csi>; + }; + }; +}; + +&mipi_csi { + clock-frequency = <166000000>; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + fsl,csis-hs-settle = <3>; + + port@1 { + reg = <1>; + + mipi_vc0_to_csi_mux: endpoint { + remote-endpoint = <&csi_mux_from_mipi_vc0>; + }; + }; +}; + &wdog1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_wdog>; diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 0b0b85438869..4fce2f46c766 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -46,6 +46,7 @@ #include #include #include +#include #include "imx7d-pinfunc.h" / { @@ -738,6 +739,17 @@ status = "disabled"; }; + csi: csi@30710000 { + compatible = "fsl,imx7-csi"; + reg = <0x30710000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_CLK_DUMMY>, + <&clks IMX7D_CSI_MCLK_ROOT_CLK>, + <&clks IMX7D_CLK_DUMMY>; + clock-names = "axi", "mclk", "dcic"; + status = "disabled"; + }; + lcdif: lcdif@30730000 { compatible = "fsl,imx7d-lcdif", "fsl,imx28-lcdif"; reg = <0x30730000 0x10000>; @@ -747,6 +759,21 @@ clock-names = "pix", "axi"; status = "disabled"; }; + + mipi_csi: mipi-csi@30750000 { + compatible = "fsl,imx7-mipi-csi2"; + reg = <0x30750000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_MIPI_CSI_ROOT_CLK>, + <&clks IMX7D_MIPI_DPHY_ROOT_CLK>; + clock-names = "pclk", "wrap", "phy"; + power-domains = <&pgc_mipi_phy>; + phy-supply = <®_1p0d>; + resets = <&src IMX7_RESET_MIPI_PHY_MRST>; + reset-names = "mrst"; + status = "disabled"; + }; }; aips3: aips-bus@30800000 { From patchwork Tue May 22 14:52:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 136568 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp1735365lji; Tue, 22 May 2018 07:53:37 -0700 (PDT) X-Google-Smtp-Source: AB8JxZreFfybok2nJFytJMzFp2GYNicr66a+i92mkEyug64tDrMSq+xHUjWMCgjqRLnWDwoCZ/Zv X-Received: by 2002:a62:4708:: with SMTP id u8-v6mr24688434pfa.89.1527000817690; Tue, 22 May 2018 07:53:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527000817; cv=none; d=google.com; s=arc-20160816; b=djWxGq8ELM7skrMh9m6GsUgS5ccrA7j+ijRMH98ZpBhxry3eN6bAu0bNkrmbFRyY9s Jkue80DdNHKJATa6zy+oXn50xS6BS2hyYJU3bVG5HB3DjecIFfi75gzdaxawVC7ZxS9w 0/8Jl4TCIItK+Y0TlypNcALz8dok6w4jv6CiGbe3O6rBrUISLPfcaTj1ZqkxEX7sBiiF 5A6bRffnAHb6IjuZaKkzJW+RtBEWTjHbltzv02Koeza0Q79lUIzUsUQDI8RgVJxQagxk yIVX+ETOkjTZUhkby/GUkiIdQEIlEottstr5D9kMOlJD/QUI19bRzRUiqxnK7/Bg05gX lShw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=MSHQrc2C8dfRzCAz/RZ6XCvziw34AnL0/aSrrNDxSiE=; b=UM21GkHCeqO2PwLtQ/61W6RgpormnlpCSaftwGuerf7o0EWWlUg/ehzBrxkVnloF47 bZSJI8tn4orUUxETToiNwJ21xCYC6f01UIb3CeRR49ylLr+m++4LcFQNvFbEL/+Uo9XU 7H02Qoomv1ko/H80zGQfp7lwuxBadf+XjOMSLh+mfCe3dBlAg3rNpc7bT6qh3DQKNc/s MZoxJS/9JRA+KAYJ70ET5Exk+s1VX6iu+oIQZ2mDuR7ABi6DbUUE8bToL0fHM32RdZEY f/kfEjUA9qilaAA8mNFcSV/CmudgI6jlOFi9mcBtzxVjZUGcTjzsDS5aWHALDDIQ6n+A tFlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=SXNOaIYc; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q28-v6si16922041pfl.317.2018.05.22.07.53.37; Tue, 22 May 2018 07:53:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=SXNOaIYc; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751870AbeEVOxd (ORCPT + 5 others); Tue, 22 May 2018 10:53:33 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:38440 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751716AbeEVOx3 (ORCPT ); Tue, 22 May 2018 10:53:29 -0400 Received: by mail-wr0-f195.google.com with SMTP id 94-v6so20721041wrf.5 for ; Tue, 22 May 2018 07:53:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=upUz86uDGdqlDx0xJz09Q/xu5MofVHeUnOYE96kb03Q=; b=SXNOaIYcR8BglOLydNNrhGRbxbOFB1UgKr8nR5Efrah/W9kTt0Ybmkes1dRVXODoVt TKm0KD44oLPUFoR3798Lecc3ptEUyhXZ/CVTKD3BzskIXBq9hVj7KYDMVX1JUkWvKaEF uvCtmV0N/r339tsmAgxCrsileHPnrWeWPv924= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=upUz86uDGdqlDx0xJz09Q/xu5MofVHeUnOYE96kb03Q=; b=Tyu79kICr3JGJpCaFwXHrwJfIA4vk9c/kxNa8QrVhdAHozVv70dgn8PysNQ5l1IJ34 GJPyHhSxLl/2aFlTn+SUt3RcskrYfaF2QWA7QBWGqk+Xd1OV2CTnPHSLOrI0pV/FczTj 7llTYXnzCYFsQUuG5NBnFxBxapKsOyo0cvygxDxNQVmdECYLUB85IXSLS3HNpjbrPxfG 8tIporLy9bkSerYf2afcZXmuM+x1gOohKDXdSYrDT2yBxwbiL5URgsohkRn2ywrfWl89 xPlizcaxoFNWu2uHw8nVPS/CGtJMXk1nJXem8FbIjE4RQd4r4G8SgrMxmgZ/IxKmaTbP BDJw== X-Gm-Message-State: ALKqPwdnJM/PEfuWF2VwjVS2jWRGwWhkCofp9rzuA6nrzM43WKUNbbQg NLSNMVtPkd+vYblzq/FuYVJKIA== X-Received: by 2002:adf:b509:: with SMTP id a9-v6mr19141017wrd.191.1527000808020; Tue, 22 May 2018 07:53:28 -0700 (PDT) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 75-v6sm76878wmw.37.2018.05.22.07.53.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 07:53:27 -0700 (PDT) From: Rui Miguel Silva To: mchehab@kernel.org, sakari.ailus@linux.intel.com, Steve Longerbeam , Philipp Zabel , Rob Herring Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, Shawn Guo , Fabio Estevam , devicetree@vger.kernel.org, Greg Kroah-Hartman , Ryan Harkin , linux-clk@vger.kernel.org, Rui Miguel Silva Subject: [PATCH v6 12/13] media: imx7.rst: add documentation for i.MX7 media driver Date: Tue, 22 May 2018 15:52:44 +0100 Message-Id: <20180522145245.3143-13-rui.silva@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180522145245.3143-1-rui.silva@linaro.org> References: <20180522145245.3143-1-rui.silva@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add rst document to describe the i.MX7 media driver and also a working example from the Warp7 board usage with a OV2680 sensor. Signed-off-by: Rui Miguel Silva --- Documentation/media/v4l-drivers/imx7.rst | 157 ++++++++++++++++++++++ Documentation/media/v4l-drivers/index.rst | 1 + 2 files changed, 158 insertions(+) create mode 100644 Documentation/media/v4l-drivers/imx7.rst -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/media/v4l-drivers/imx7.rst b/Documentation/media/v4l-drivers/imx7.rst new file mode 100644 index 000000000000..cd1195d391c5 --- /dev/null +++ b/Documentation/media/v4l-drivers/imx7.rst @@ -0,0 +1,157 @@ +i.MX7 Video Capture Driver +========================== + +Introduction +------------ + +The i.MX7 contrary to the i.MX5/6 family does not contain an Image Processing +Unit (IPU); because of that the capabilities to perform operations or +manipulation of the capture frames are less feature rich. + +For image capture the i.MX7 has three units: +- CMOS Sensor Interface (CSI) +- Video Multiplexer +- MIPI CSI-2 Receiver + +:: + |\ + MIPI Camera Input ---> MIPI CSI-2 --- > | \ + | \ + | M | + | U | ------> CSI ---> Capture + | X | + | / + Parallel Camera Input ----------------> | / + |/ + +For additional information, please refer to the latest versions of the i.MX7 +reference manual [#f1]_. + +Entities +-------- + +imx7-mipi-csi2 +-------------- + +This is the MIPI CSI-2 receiver entity. It has one sink pad to receive the pixel +data from MIPI CSI-2 camera sensor. It has one source pad, corresponding to the +virtual channel 0. This module is compliant to previous version of Samsung +D-phy, and supports two D-PHY Rx Data lanes. + +csi_mux +------- + +This is the video multiplexer. It has two sink pads to select from either camera +sensor with a parallel interface or from MIPI CSI-2 virtual channel 0. It has +a single source pad that routes to the CSI. + +csi +--- + +The CSI enables the chip to connect directly to external CMOS image sensor. CSI +can interface directly with Parallel and MIPI CSI-2 buses. It has 256 x 64 FIFO +to store received image pixel data and embedded DMA controllers to transfer data +from the FIFO through AHB bus. + +This entity has one sink pad that receives from the csi_mux entity and a single +source pad that routes video frames directly to memory buffers. This pad is +routed to a capture device node. + +Usage Notes +----------- + +To aid in configuration and for backward compatibility with V4L2 applications +that access controls only from video device nodes, the capture device interfaces +inherit controls from the active entities in the current pipeline, so controls +can be accessed either directly from the subdev or from the active capture +device interface. For example, the sensor controls are available either from the +sensor subdevs or from the active capture device. + +Warp7 with OV2680 +----------------- + +On this platform an OV2680 MIPI CSI-2 module is connected to the internal MIPI +CSI-2 receiver. The following example configures a video capture pipeline with +an output of 800x600, and BGGR 10 bit bayer format: + +.. code-block:: none + # Setup links + media-ctl -l "'ov2680 1-0036':0 -> 'imx7-mipi-csis.0':0[1]" + media-ctl -l "'imx7-mipi-csis.0':1 -> 'csi_mux':1[1]" + media-ctl -l "'csi_mux':2 -> 'csi':0[1]" + media-ctl -l "'csi':1 -> 'csi capture':0[1]" + + # Configure pads for pipeline + media-ctl -V "'ov2680 1-0036':0 [fmt:SBGGR10_1X10/800x600 field:none]" + media-ctl -V "'csi_mux':1 [fmt:SBGGR10_1X10/800x600 field:none]" + media-ctl -V "'csi_mux':2 [fmt:SBGGR10_1X10/800x600 field:none]" + media-ctl -V "'imx7-mipi-csis.0':0 [fmt:SBGGR10_1X10/800x600 field:none]" + media-ctl -V "'csi':0 [fmt:SBGGR10_1X10/800x600 field:none]" + +After this streaming can start. The v4l2-ctl tool can be used to select any of +the resolutions supported by the sensor. + +.. code-block:: none + root@imx7s-warp:~# media-ctl -p + Media controller API version 4.17.0 + + Media device information + ------------------------ + driver imx-media + model imx-media + serial + bus info + hw revision 0x0 + driver version 4.17.0 + + Device topology + - entity 1: csi (2 pads, 2 links) + type V4L2 subdev subtype Unknown flags 0 + device node name /dev/v4l-subdev0 + pad0: Sink + [fmt:SBGGR10_1X10/800x600 field:none] + <- "csi_mux":2 [ENABLED] + pad1: Source + [fmt:SBGGR10_1X10/800x600 field:none] + -> "csi capture":0 [ENABLED] + + - entity 4: csi capture (1 pad, 1 link) + type Node subtype V4L flags 0 + device node name /dev/video0 + pad0: Sink + <- "csi":1 [ENABLED] + + - entity 10: csi_mux (3 pads, 2 links) + type V4L2 subdev subtype Unknown flags 0 + device node name /dev/v4l-subdev1 + pad0: Sink + [fmt:unknown/0x0] + pad1: Sink + [fmt:unknown/800x600 field:none] + <- "imx7-mipi-csis.0":1 [ENABLED] + pad2: Source + [fmt:unknown/800x600 field:none] + -> "csi":0 [ENABLED] + + - entity 14: imx7-mipi-csis.0 (2 pads, 2 links) + type V4L2 subdev subtype Unknown flags 0 + device node name /dev/v4l-subdev2 + pad0: Sink + [fmt:SBGGR10_1X10/800x600 field:none] + <- "ov2680 1-0036":0 [ENABLED] + pad1: Source + [fmt:SBGGR10_1X10/800x600 field:none] + -> "csi_mux":1 [ENABLED] + + - entity 17: ov2680 1-0036 (1 pad, 1 link) + type V4L2 subdev subtype Sensor flags 0 + device node name /dev/v4l-subdev3 + pad0: Source + [fmt:SBGGR10_1X10/800x600 field:none] + -> "imx7-mipi-csis.0":0 [ENABLED] + + +References +---------- + +.. [#f1] https://www.nxp.com/docs/en/reference-manual/IMX7SRM.pdf diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst index 679238e786a7..693295bbc53f 100644 --- a/Documentation/media/v4l-drivers/index.rst +++ b/Documentation/media/v4l-drivers/index.rst @@ -44,6 +44,7 @@ For more details see the file COPYING in the source distribution of Linux. davinci-vpbe fimc imx + imx7 ivtv max2175 meye