From patchwork Wed Jan 23 10:52:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 156357 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp576239jaa; Wed, 23 Jan 2019 02:52:57 -0800 (PST) X-Google-Smtp-Source: ALg8bN6k8HWNfsluTbMlM+E3B/85ZC2B27e3XQ65MZ1arbTdz9z8YEtDgFvP9PTnqqp37MyvTOZF X-Received: by 2002:a63:d34a:: with SMTP id u10mr1543277pgi.301.1548240777489; Wed, 23 Jan 2019 02:52:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548240777; cv=none; d=google.com; s=arc-20160816; b=H51ABj7Wb5dlnEdJfwq4mw4a9h0EViLhaKrlueDJQPQSy5cx/k3i/rHCxfoYvxgJbO DI0ZD2nIRDDZpPDOw7VRULo7ZtjdOrzsarbYoTXWI0W1zGpd4isZ+HlE5YLBtIDW2YdQ bYpJ65jWEelUmRjmaU+ZdkHI3kuCg7YpAOGFvxO1KwN3ik6mNjv/o59Fsb0plFpXPavG gliwJ2q4l8b3leU5kggdIi91vNVQRJGQHVAUwIX2y22/KIqLmZD0kIessOkJ2zHsycYP 0axWnut7cJtkfE1cNgNBKW7+o6PEXKrOx+1se3JOv7P6GPlvkOYH6c0jMx3N9WZEtx6S +Jtw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=rMqXeMdTsmQBRukkccJ6OzWO2HfnbotFKt0ltYd3kac=; b=NV0H9I4/VWbH3ER12KM3NyUPL3tu73XrXS+W1utTJAEZzLk1v23IgzQ6KscBGHVYCr olerZ2G9hbjvMkHBnUvgrrMeMPrmoX8NsNRkGeR6GEzsavAcEDizm2d+4OLWhNtZru36 Fpt2oUEkUDF5Ytw0u3btzcASULLzmQ87/lZi5/7dbWJBRLNASVLIrLssewMZxrXQBJRU 5ZoZPFh7MSZaDCydGmcMkhkqw5WdHV3omHYX2qD0F2okM2xbRR+P/0pdvQQyy3JJ0LWQ dPihmOgzvcERUrHSG/IQxLXwGmCKVItIPmL0hggMgNHYbqZBB/1NOyxWvO6xjhQkPn77 Qyvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jEzaJTpn; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (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 a6si18061494pfa.227.2019.01.23.02.52.57; Wed, 23 Jan 2019 02:52:57 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jEzaJTpn; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727469AbfAWKwz (ORCPT + 4 others); Wed, 23 Jan 2019 05:52:55 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:45155 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727404AbfAWKwy (ORCPT ); Wed, 23 Jan 2019 05:52:54 -0500 Received: by mail-wr1-f68.google.com with SMTP id t6so1816339wrr.12 for ; Wed, 23 Jan 2019 02:52:52 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=rMqXeMdTsmQBRukkccJ6OzWO2HfnbotFKt0ltYd3kac=; b=jEzaJTpnq7/9erX+gZoDDQX6BohJeqrAzewHL7aL7jDdQNPeVFbmg9OCLyd+b/Pb5Z 4IfMhW3e7S7HihTA+wHOlPLCxYWYQwRGrZbIcF0I1LcbQ0m+6ukrJTDZLj2pbEq1Dc+v Yp68+QmfwPNrUI1LNiXzgGjRK82MgcOFwKVTI= 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:mime-version:content-transfer-encoding; bh=rMqXeMdTsmQBRukkccJ6OzWO2HfnbotFKt0ltYd3kac=; b=DGdksVv6JLfVxpIGZoR6SDucAMkuWFC1c7FHc2cgABdLTV3XbTZLAHRCEHf5dzp1UJ dBS1uLBB5qs3OTp9LfZgr6KUfgH1Ufaddm9mGCvZAuScULyfSnhT0ecbYk2D0E37wM64 pBA5SA0Iy6krF1zfe3MphG30CUk5lmZf6hEH8UelJ3XbNg0cLmmYDSr2HRP9gUnWjxyW 81QvuUTGaHybfmaG54m3xAb/kZzM95uI5Bcp20lKOGm86i/0hV9Kc9Y2oqRWqdr3/EH+ VEPMlM+StfJxmBzFancXowR84znonTCkPt7tPdlkyiYBb3CL1SrNisS2lzXAjQctEkCf nCJQ== X-Gm-Message-State: AJcUukcLBoSnnBgWhm0QVsHrC8Ys6EJXmwHQXCSP2+1zOLnC+jy7/UAi WN81Gtzj2OIhzD4WK0H8cVgOmQ== X-Received: by 2002:adf:e3d0:: with SMTP id k16mr2220065wrm.223.1548240771895; Wed, 23 Jan 2019 02:52:51 -0800 (PST) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 143sm120717646wml.14.2019.01.23.02.52.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jan 2019 02:52:51 -0800 (PST) From: Rui Miguel Silva To: sakari.ailus@linux.intel.com, Steve Longerbeam , Hans Verkuil , Philipp Zabel Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, devicetree@vger.kernel.org, Greg Kroah-Hartman , Rui Miguel Silva , Rob Herring Subject: [PATCH v10 03/13] media: dt-bindings: add bindings for i.MX7 media driver Date: Wed, 23 Jan 2019 10:52:12 +0000 Message-Id: <20190123105222.2378-4-rui.silva@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190123105222.2378-1-rui.silva@linaro.org> References: <20190123105222.2378-1-rui.silva@linaro.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@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 Reviewed-by: Rob Herring Acked-by: Sakari Ailus --- .../devicetree/bindings/media/imx7-csi.txt | 45 ++++++++++ .../bindings/media/imx7-mipi-csi2.txt | 90 +++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/imx7-csi.txt create mode 100644 Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt -- 2.20.1 diff --git a/Documentation/devicetree/bindings/media/imx7-csi.txt b/Documentation/devicetree/bindings/media/imx7-csi.txt new file mode 100644 index 000000000000..3c07bc676bc3 --- /dev/null +++ b/Documentation/devicetree/bindings/media/imx7-csi.txt @@ -0,0 +1,45 @@ +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 shall 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..71fd74ed3ec8 --- /dev/null +++ b/Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt @@ -0,0 +1,90 @@ +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; + +The device node should contain two 'port' child nodes with one child 'endpoint' +node, according to the bindings defined in: + Documentation/devicetree/bindings/ media/video-interfaces.txt. + The following are properties specific to those nodes. + +port node +--------- + +- reg : (required) can take the values 0 or 1, where 0 shall be + related to the sink port and port 1 shall 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; this + shall only be applied to port 0 (sink port), the array's + content is unused only its length is meaningful, + in this case the maximum length supported is 2; + +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 Wed Jan 23 10:52:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 156359 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp576302jaa; Wed, 23 Jan 2019 02:53:01 -0800 (PST) X-Google-Smtp-Source: ALg8bN6u37euz4FtX4YGv2k/cDq4ydFxnfVjTXzv0pPw+YV1a6n7sT/nxWp7ETmb21I+xSWYhXhm X-Received: by 2002:a17:902:bf0c:: with SMTP id bi12mr1770860plb.0.1548240781551; Wed, 23 Jan 2019 02:53:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548240781; cv=none; d=google.com; s=arc-20160816; b=saJDT3+hly49pspTnVwPMiHwWPCzqPr+gVdUMYxz8XPTDbfZld2VixJSgZdREjRq/d IoDf4b72Ydu/j342pROsPJCovWrYtmSJlQN5sK3QCk5VYvxJJsPVaPZpl+WVGClSe+4t 5fzlVAP0bCbLJdSd2zfD2DcH9a3pCcyYbBDjf6IYxWIrtf0zO9YaESbFMml/cnVpwo3w iVuoDXTmiXdqqger1CFP3pbJClFXsTjUua4fj9dTcpy/O3yXkduIkvXOqs9N1vs+mmBz n6gwoy/lCnKyCDtSZbF7kHvrpea2FodH9k8/XQ/zpXhoK/jq2gcYe38YwTpJk/1DwuP2 H6tQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1G8sRhFjHRWTmnKWIyLzTXQMIUa19iM2x5PyJ8iHpUo=; b=lGsfHcEN936dGVrg85ArDZlzh38z1RpJMf3OL8jQrEpTt0prEwq3pPIFxV+w/WZV+D wxvj1kEIhGPBvtcGnRzMkbrWz7ZZzUc2uplQCjcza6AQWZZqiYRmcy2zhoB0ZkwgckGQ f2rdIQPOKTJHBDJGqqsNSc65vcYUWek5rluFT0kqCwoqB/ax/zX7UTSh238iv/l0V9Tp rUNxSoYG4Nr/KbXQPnXzTz5LavT/fUk75knnuFF/8ufTnGmnIP3Sr6cP5YmpPuui+ofC EeC/Y91PBo4gOUw5ZndmdTrIZ4ajWbyt/Q2Iz+CL9ru12XvDszGRptUvwpoYDdq45oK5 wqwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dBYJOGbJ; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (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 a6si18061494pfa.227.2019.01.23.02.53.01; Wed, 23 Jan 2019 02:53:01 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dBYJOGbJ; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727490AbfAWKxA (ORCPT + 4 others); Wed, 23 Jan 2019 05:53:00 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:40433 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727404AbfAWKxA (ORCPT ); Wed, 23 Jan 2019 05:53:00 -0500 Received: by mail-wr1-f67.google.com with SMTP id p4so1847414wrt.7 for ; Wed, 23 Jan 2019 02:52:57 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=1G8sRhFjHRWTmnKWIyLzTXQMIUa19iM2x5PyJ8iHpUo=; b=dBYJOGbJMUT8bA4HfUngDMRDc5MKkVEIENbSNDXpYst9BCL5MkkJF5YuUuuXEcJfnV Sii6IVEMxw4JmjFw4L97loPOg/xszwih9v5LQ7HqspmiBe6CADW5Xni1HzkjuWkVEtli lqEtBtFNwhAmF7tlMeGKQzK47bfd69L2lZxoU= 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:mime-version:content-transfer-encoding; bh=1G8sRhFjHRWTmnKWIyLzTXQMIUa19iM2x5PyJ8iHpUo=; b=kcJbl6xNAV4QiJyhCf7qybjvF7sDBSeA7xi+1y6+FU8n14OZUFTuks9qWsi5PiD62g EUjyiTOkn0zP+cLD4xvVvISDE9Hyugu/LgsBsnodvC2mexbkA7glueLb7/Lb++Os4w91 PCzT2mTh+MFM2GnEUfp3DQv+xp7AfwR679eF68G595QK2i17obOSlGKvaf+jtHoVeR58 aFsXSZBGCd4GnogmbUpuWaT/cGOSFPMBFTfLbrLrDiwVSjqJn4LDtPy0cWsq8jYDnVvU F4x9PpAYHztlMAIW45jlqLZR8hM2F1WCTOdTJn7aAURhiFKau1YkX3T73Lc1d5erXGpz PULw== X-Gm-Message-State: AJcUukeXHyEEZmIh5UgdzB0Gs5JuzuJBgbyHBQL8pFm5f+1sPMZTBLsQ OrXYI7t43g4CB0//OGb8orObvA== X-Received: by 2002:adf:891a:: with SMTP id s26mr2132101wrs.44.1548240776196; Wed, 23 Jan 2019 02:52:56 -0800 (PST) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 143sm120717646wml.14.2019.01.23.02.52.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jan 2019 02:52:55 -0800 (PST) From: Rui Miguel Silva To: sakari.ailus@linux.intel.com, Steve Longerbeam , Hans Verkuil , Philipp Zabel Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, devicetree@vger.kernel.org, Greg Kroah-Hartman , Rui Miguel Silva Subject: [PATCH v10 05/13] media: staging/imx7: add MIPI CSI-2 receiver subdev for i.MX7 Date: Wed, 23 Jan 2019 10:52:14 +0000 Message-Id: <20190123105222.2378-6-rui.silva@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190123105222.2378-1-rui.silva@linaro.org> References: <20190123105222.2378-1-rui.silva@linaro.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Adds MIPI CSI-2 subdev for i.MX7 to connect with sensors with a MIPI CSI-2 interface. Signed-off-by: Rui Miguel Silva --- drivers/staging/media/imx/Makefile | 1 + drivers/staging/media/imx/imx7-mipi-csis.c | 1184 ++++++++++++++++++++ 2 files changed, 1185 insertions(+) create mode 100644 drivers/staging/media/imx/imx7-mipi-csis.c -- 2.20.1 diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile index 074f016d3519..d2d909a36239 100644 --- a/drivers/staging/media/imx/Makefile +++ b/drivers/staging/media/imx/Makefile @@ -14,3 +14,4 @@ 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 +obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-mipi-csis.o diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c new file mode 100644 index 000000000000..2d54fc7b20a0 --- /dev/null +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -0,0 +1,1184 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Freescale i.MX7 SoC series MIPI-CSI V3.3 receiver driver + * + * Copyright (C) 2019 Linaro Ltd + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "imx-media.h" + +#define CSIS_DRIVER_NAME "imx7-mipi-csis" +#define CSIS_SUBDEV_NAME CSIS_DRIVER_NAME + +#define CSIS_PAD_SINK 0 +#define CSIS_PAD_SOURCE 1 +#define CSIS_PADS_NUM 2 + +#define MIPI_CSIS_DEF_PIX_WIDTH 640 +#define MIPI_CSIS_DEF_PIX_HEIGHT 480 + +/* Register map definition */ + +/* CSIS common control */ +#define MIPI_CSIS_CMN_CTRL 0x04 +#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW BIT(16) +#define MIPI_CSIS_CMN_CTRL_INTER_MODE BIT(10) +#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL BIT(2) +#define MIPI_CSIS_CMN_CTRL_RESET BIT(1) +#define MIPI_CSIS_CMN_CTRL_ENABLE BIT(0) + +#define MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET 8 +#define MIPI_CSIS_CMN_CTRL_LANE_NR_MASK (3 << 8) + +/* CSIS clock control */ +#define MIPI_CSIS_CLK_CTRL 0x08 +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH3(x) ((x) << 28) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH2(x) ((x) << 24) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH1(x) ((x) << 20) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(x) ((x) << 16) +#define MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK (0xf << 4) +#define MIPI_CSIS_CLK_CTRL_WCLK_SRC BIT(0) + +/* CSIS Interrupt mask */ +#define MIPI_CSIS_INTMSK 0x10 +#define MIPI_CSIS_INTMSK_EVEN_BEFORE BIT(31) +#define MIPI_CSIS_INTMSK_EVEN_AFTER BIT(30) +#define MIPI_CSIS_INTMSK_ODD_BEFORE BIT(29) +#define MIPI_CSIS_INTMSK_ODD_AFTER BIT(28) +#define MIPI_CSIS_INTMSK_FRAME_START BIT(24) +#define MIPI_CSIS_INTMSK_FRAME_END BIT(20) +#define MIPI_CSIS_INTMSK_ERR_SOT_HS BIT(16) +#define MIPI_CSIS_INTMSK_ERR_LOST_FS BIT(12) +#define MIPI_CSIS_INTMSK_ERR_LOST_FE BIT(8) +#define MIPI_CSIS_INTMSK_ERR_OVER BIT(4) +#define MIPI_CSIS_INTMSK_ERR_WRONG_CFG BIT(3) +#define MIPI_CSIS_INTMSK_ERR_ECC BIT(2) +#define MIPI_CSIS_INTMSK_ERR_CRC BIT(1) +#define MIPI_CSIS_INTMSK_ERR_UNKNOWN BIT(0) + +/* CSIS Interrupt source */ +#define MIPI_CSIS_INTSRC 0x14 +#define MIPI_CSIS_INTSRC_EVEN_BEFORE BIT(31) +#define MIPI_CSIS_INTSRC_EVEN_AFTER BIT(30) +#define MIPI_CSIS_INTSRC_EVEN BIT(30) +#define MIPI_CSIS_INTSRC_ODD_BEFORE BIT(29) +#define MIPI_CSIS_INTSRC_ODD_AFTER BIT(28) +#define MIPI_CSIS_INTSRC_ODD (0x3 << 28) +#define MIPI_CSIS_INTSRC_NON_IMAGE_DATA (0xf << 28) +#define MIPI_CSIS_INTSRC_FRAME_START BIT(24) +#define MIPI_CSIS_INTSRC_FRAME_END BIT(20) +#define MIPI_CSIS_INTSRC_ERR_SOT_HS BIT(16) +#define MIPI_CSIS_INTSRC_ERR_LOST_FS BIT(12) +#define MIPI_CSIS_INTSRC_ERR_LOST_FE BIT(8) +#define MIPI_CSIS_INTSRC_ERR_OVER BIT(4) +#define MIPI_CSIS_INTSRC_ERR_WRONG_CFG BIT(3) +#define MIPI_CSIS_INTSRC_ERR_ECC BIT(2) +#define MIPI_CSIS_INTSRC_ERR_CRC BIT(1) +#define MIPI_CSIS_INTSRC_ERR_UNKNOWN BIT(0) +#define MIPI_CSIS_INTSRC_ERRORS 0xfffff + +/* D-PHY status control */ +#define MIPI_CSIS_DPHYSTATUS 0x20 +#define MIPI_CSIS_DPHYSTATUS_ULPS_DAT BIT(8) +#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_DAT BIT(4) +#define MIPI_CSIS_DPHYSTATUS_ULPS_CLK BIT(1) +#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_CLK BIT(0) + +/* D-PHY common control */ +#define MIPI_CSIS_DPHYCTRL 0x24 +#define MIPI_CSIS_DPHYCTRL_HSS_MASK (0xff << 24) +#define MIPI_CSIS_DPHYCTRL_HSS_OFFSET 24 +#define MIPI_CSIS_DPHYCTRL_SCLKS_MASK (0x3 << 22) +#define MIPI_CSIS_DPHYCTRL_SCLKS_OFFSET 22 +#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_CLK BIT(6) +#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_DAT BIT(5) +#define MIPI_CSIS_DPHYCTRL_ENABLE_DAT BIT(1) +#define MIPI_CSIS_DPHYCTRL_ENABLE_CLK BIT(0) +#define MIPI_CSIS_DPHYCTRL_ENABLE (0x1f << 0) + +/* D-PHY Master and Slave Control register Low */ +#define MIPI_CSIS_DPHYBCTRL_L 0x30 +/* D-PHY Master and Slave Control register High */ +#define MIPI_CSIS_DPHYBCTRL_H 0x34 +/* D-PHY Slave Control register Low */ +#define MIPI_CSIS_DPHYSCTRL_L 0x38 +/* D-PHY Slave Control register High */ +#define MIPI_CSIS_DPHYSCTRL_H 0x3c + +/* ISP Configuration register */ +#define MIPI_CSIS_ISPCONFIG_CH0 0x40 +#define MIPI_CSIS_ISPCONFIG_CH1 0x50 +#define MIPI_CSIS_ISPCONFIG_CH2 0x60 +#define MIPI_CSIS_ISPCONFIG_CH3 0x70 + +#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK (0xff << 24) +#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x) ((x) << 24) +#define MIPI_CSIS_ISPCFG_DOUBLE_CMPNT BIT(12) +#define MIPI_CSIS_ISPCFG_ALIGN_32BIT BIT(11) +#define MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT (0x1e << 2) +#define MIPI_CSIS_ISPCFG_FMT_RAW8 (0x2a << 2) +#define MIPI_CSIS_ISPCFG_FMT_RAW10 (0x2b << 2) +#define MIPI_CSIS_ISPCFG_FMT_RAW12 (0x2c << 2) + +/* User defined formats, x = 1...4 */ +#define MIPI_CSIS_ISPCFG_FMT_USER(x) ((0x30 + (x) - 1) << 2) +#define MIPI_CSIS_ISPCFG_FMT_MASK (0x3f << 2) + +/* ISP Image Resolution register */ +#define MIPI_CSIS_ISPRESOL_CH0 0x44 +#define MIPI_CSIS_ISPRESOL_CH1 0x54 +#define MIPI_CSIS_ISPRESOL_CH2 0x64 +#define MIPI_CSIS_ISPRESOL_CH3 0x74 +#define CSIS_MAX_PIX_WIDTH 0xffff +#define CSIS_MAX_PIX_HEIGHT 0xffff + +/* ISP SYNC register */ +#define MIPI_CSIS_ISPSYNC_CH0 0x48 +#define MIPI_CSIS_ISPSYNC_CH1 0x58 +#define MIPI_CSIS_ISPSYNC_CH2 0x68 +#define MIPI_CSIS_ISPSYNC_CH3 0x78 + +#define MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET 18 +#define MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET 12 +#define MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET 0 + +/* Non-image packet data buffers */ +#define MIPI_CSIS_PKTDATA_ODD 0x2000 +#define MIPI_CSIS_PKTDATA_EVEN 0x3000 +#define MIPI_CSIS_PKTDATA_SIZE SZ_4K + +#define DEFAULT_SCLK_CSIS_FREQ 166000000UL + +enum { + ST_POWERED = 1, + ST_STREAMING = 2, + ST_SUSPENDED = 4, +}; + +struct mipi_csis_event { + u32 mask; + const char * const name; + unsigned int counter; +}; + +static const struct mipi_csis_event mipi_csis_events[] = { + /* Errors */ + { MIPI_CSIS_INTSRC_ERR_SOT_HS, "SOT Error" }, + { MIPI_CSIS_INTSRC_ERR_LOST_FS, "Lost Frame Start Error" }, + { MIPI_CSIS_INTSRC_ERR_LOST_FE, "Lost Frame End Error" }, + { MIPI_CSIS_INTSRC_ERR_OVER, "FIFO Overflow Error" }, + { MIPI_CSIS_INTSRC_ERR_WRONG_CFG, "Wrong Configuration Error" }, + { MIPI_CSIS_INTSRC_ERR_ECC, "ECC Error" }, + { MIPI_CSIS_INTSRC_ERR_CRC, "CRC Error" }, + { MIPI_CSIS_INTSRC_ERR_UNKNOWN, "Unknown Error" }, + /* Non-image data receive events */ + { MIPI_CSIS_INTSRC_EVEN_BEFORE, "Non-image data before even frame" }, + { MIPI_CSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" }, + { MIPI_CSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" }, + { MIPI_CSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" }, + /* Frame start/end */ + { MIPI_CSIS_INTSRC_FRAME_START, "Frame Start" }, + { MIPI_CSIS_INTSRC_FRAME_END, "Frame End" }, +}; + +#define MIPI_CSIS_NUM_EVENTS ARRAY_SIZE(mipi_csis_events) + +static const char * const mipi_csis_clk_id[] = {"pclk", "wrap", "phy"}; + +struct csis_hw_reset { + struct regmap *src; + u8 req_src; + u8 rst_bit; +}; + +struct csi_state { + /* lock elements below */ + struct mutex lock; + /* lock for event handler */ + spinlock_t slock; + struct device *dev; + struct media_pad pads[CSIS_PADS_NUM]; + struct v4l2_subdev mipi_sd; + struct v4l2_subdev *src_sd; + + u8 index; + struct platform_device *pdev; + struct phy *phy; + void __iomem *regs; + struct clk *wrap_clk; + int irq; + u32 flags; + + struct dentry *debugfs_root; + bool debug; + + int num_clks; + struct clk_bulk_data *clks; + + u32 clk_frequency; + u32 hs_settle; + + struct reset_control *mrst; + + const struct csis_pix_format *csis_fmt; + struct v4l2_mbus_framefmt format_mbus; + + struct v4l2_fwnode_bus_mipi_csi2 bus; + + struct mipi_csis_event events[MIPI_CSIS_NUM_EVENTS]; + + struct v4l2_async_notifier subdev_notifier; + + struct csis_hw_reset hw_reset; + struct regulator *mipi_phy_regulator; + bool sink_linked; +}; + +struct csis_pix_format { + unsigned int pix_width_alignment; + u32 code; + u32 fmt_reg; + u8 data_alignment; +}; + +static const struct csis_pix_format mipi_csis_formats[] = { + { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10, + .data_alignment = 16, + }, { + .code = MEDIA_BUS_FMT_VYUY8_2X8, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT, + .data_alignment = 16, + }, { + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8, + .data_alignment = 8, + }, { + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT, + .data_alignment = 16, + } +}; + +#define mipi_csis_write(__csis, __r, __v) writel(__v, (__csis)->regs + (__r)) +#define mipi_csis_read(__csis, __r) readl((__csis)->regs + (__r)) + +static int mipi_csis_dump_regs(struct csi_state *state) +{ + struct device *dev = &state->pdev->dev; + unsigned int i; + u32 cfg; + struct { + u32 offset; + const char * const name; + } registers[] = { + { 0x04, "CTRL" }, + { 0x24, "DPHYCTRL" }, + { 0x08, "CLKCTRL" }, + { 0x20, "DPHYSTS" }, + { 0x10, "INTMSK" }, + { 0x40, "CONFIG_CH0" }, + { 0xC0, "DBG_CONFIG" }, + { 0x38, "DPHYSLAVE_L" }, + { 0x3C, "DPHYSLAVE_H" }, + }; + + dev_info(dev, "--- REGISTERS ---\n"); + + for (i = 0; i < ARRAY_SIZE(registers); i++) { + cfg = mipi_csis_read(state, registers[i].offset); + dev_info(dev, "%12s: 0x%08x\n", registers[i].name, cfg); + } + + return 0; +} + +static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev) +{ + return container_of(sdev, struct csi_state, mipi_sd); +} + +static const struct csis_pix_format *find_csis_format(u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(mipi_csis_formats); i++) + if (code == mipi_csis_formats[i].code) + return &mipi_csis_formats[i]; + return NULL; +} + +static void mipi_csis_enable_interrupts(struct csi_state *state, bool on) +{ + mipi_csis_write(state, MIPI_CSIS_INTMSK, on ? 0xffffffff : 0); +} + +static void mipi_csis_sw_reset(struct csi_state *state) +{ + u32 val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, + val | MIPI_CSIS_CMN_CTRL_RESET); + usleep_range(10, 20); +} + +static int mipi_csis_phy_init(struct csi_state *state) +{ + state->mipi_phy_regulator = devm_regulator_get(state->dev, "phy"); + + return regulator_set_voltage(state->mipi_phy_regulator, 1000000, + 1000000); +} + +static void mipi_csis_phy_reset(struct csi_state *state) +{ + reset_control_assert(state->mrst); + + msleep(20); + + reset_control_deassert(state->mrst); +} + +static void mipi_csis_system_enable(struct csi_state *state, int on) +{ + u32 val, mask; + + val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + if (on) + val |= MIPI_CSIS_CMN_CTRL_ENABLE; + else + val &= ~MIPI_CSIS_CMN_CTRL_ENABLE; + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); + + val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL); + val &= ~MIPI_CSIS_DPHYCTRL_ENABLE; + if (on) { + mask = (1 << (state->bus.num_data_lanes + 1)) - 1; + val |= (mask & MIPI_CSIS_DPHYCTRL_ENABLE); + } + mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val); +} + +/* Called with the state.lock mutex held */ +static void __mipi_csis_set_format(struct csi_state *state) +{ + struct v4l2_mbus_framefmt *mf = &state->format_mbus; + u32 val; + + /* Color format */ + val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0); + val = (val & ~MIPI_CSIS_ISPCFG_FMT_MASK) | state->csis_fmt->fmt_reg; + mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val); + + /* Pixel resolution */ + val = mf->width | (mf->height << 16); + mipi_csis_write(state, MIPI_CSIS_ISPRESOL_CH0, val); +} + +static void mipi_csis_set_hsync_settle(struct csi_state *state, int hs_settle) +{ + u32 val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL); + + val = ((val & ~MIPI_CSIS_DPHYCTRL_HSS_MASK) | (hs_settle << 24)); + + mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val); +} + +static void mipi_csis_set_params(struct csi_state *state) +{ + int lanes = state->bus.num_data_lanes; + u32 val; + + val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK; + val |= (lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET; + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); + + __mipi_csis_set_format(state); + + mipi_csis_set_hsync_settle(state, state->hs_settle); + + val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0); + if (state->csis_fmt->data_alignment == 32) + val |= MIPI_CSIS_ISPCFG_ALIGN_32BIT; + else + val &= ~MIPI_CSIS_ISPCFG_ALIGN_32BIT; + mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val); + + val = (0 << MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET) | + (0 << MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET) | + (0 << MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET); + mipi_csis_write(state, MIPI_CSIS_ISPSYNC_CH0, val); + + val = mipi_csis_read(state, MIPI_CSIS_CLK_CTRL); + val &= ~MIPI_CSIS_CLK_CTRL_WCLK_SRC; + if (state->wrap_clk) + val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC; + else + val &= ~MIPI_CSIS_CLK_CTRL_WCLK_SRC; + + val |= MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(15); + val &= ~MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK; + mipi_csis_write(state, MIPI_CSIS_CLK_CTRL, val); + + mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_L, 0x1f4); + mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_H, 0); + + /* Update the shadow register. */ + val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, + val | MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW | + MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL); +} + +static void mipi_csis_clk_enable(struct csi_state *state) +{ + int ret; + + ret = clk_bulk_prepare_enable(state->num_clks, state->clks); + if (ret < 0) + dev_err(state->dev, "failed to enable clocks\n"); +} + +static void mipi_csis_clk_disable(struct csi_state *state) +{ + clk_bulk_disable_unprepare(state->num_clks, state->clks); +} + +static int mipi_csis_clk_get(struct csi_state *state) +{ + struct device *dev = &state->pdev->dev; + unsigned int i; + int ret; + + state->num_clks = ARRAY_SIZE(mipi_csis_clk_id); + state->clks = devm_kcalloc(dev, state->num_clks, sizeof(*state->clks), + GFP_KERNEL); + + if (!state->clks) + return -ENOMEM; + + for (i = 0; i < state->num_clks; i++) + state->clks[i].id = mipi_csis_clk_id[i]; + + ret = devm_clk_bulk_get(dev, state->num_clks, state->clks); + if (ret < 0) + return ret; + + state->wrap_clk = devm_clk_get(dev, "wrap"); + if (IS_ERR(state->wrap_clk)) + return IS_ERR(state->wrap_clk); + + /* Set clock rate */ + ret = clk_set_rate(state->wrap_clk, state->clk_frequency); + if (ret < 0) + dev_err(dev, "set rate=%d failed: %d\n", state->clk_frequency, + ret); + + return ret; +} + +static void mipi_csis_start_stream(struct csi_state *state) +{ + mipi_csis_sw_reset(state); + mipi_csis_set_params(state); + mipi_csis_system_enable(state, true); + mipi_csis_enable_interrupts(state, true); +} + +static void mipi_csis_stop_stream(struct csi_state *state) +{ + mipi_csis_enable_interrupts(state, false); + mipi_csis_system_enable(state, false); +} + +static void mipi_csis_clear_counters(struct csi_state *state) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&state->slock, flags); + for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) + state->events[i].counter = 0; + spin_unlock_irqrestore(&state->slock, flags); +} + +static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) +{ + int i = non_errors ? MIPI_CSIS_NUM_EVENTS : MIPI_CSIS_NUM_EVENTS - 4; + struct device *dev = &state->pdev->dev; + unsigned long flags; + + spin_lock_irqsave(&state->slock, flags); + + for (i--; i >= 0; i--) { + if (state->events[i].counter > 0 || state->debug) + dev_info(dev, "%s events: %d\n", state->events[i].name, + state->events[i].counter); + } + spin_unlock_irqrestore(&state->slock, flags); +} + +/* + * V4L2 subdev operations + */ +static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; + + if (enable) { + mipi_csis_clear_counters(state); + ret = pm_runtime_get_sync(&state->pdev->dev); + if (ret && ret != 1) + return ret; + ret = v4l2_subdev_call(state->src_sd, core, s_power, 1); + if (ret < 0) + return ret; + } + + mutex_lock(&state->lock); + if (enable) { + if (state->flags & ST_SUSPENDED) { + ret = -EBUSY; + goto unlock; + } + + mipi_csis_start_stream(state); + ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1); + if (ret < 0) + goto unlock; + + mipi_csis_log_counters(state, true); + + state->flags |= ST_STREAMING; + } else { + v4l2_subdev_call(state->src_sd, video, s_stream, 0); + ret = v4l2_subdev_call(state->src_sd, core, s_power, 1); + mipi_csis_stop_stream(state); + state->flags &= ~ST_STREAMING; + if (state->debug) + mipi_csis_log_counters(state, true); + } + +unlock: + mutex_unlock(&state->lock); + if (!enable) + pm_runtime_put(&state->pdev->dev); + + return ret; +} + +static int mipi_csis_link_setup(struct media_entity *entity, + const struct media_pad *local_pad, + const struct media_pad *remote_pad, u32 flags) +{ + struct v4l2_subdev *mipi_sd = media_entity_to_v4l2_subdev(entity); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_subdev *remote_sd; + int ret = 0; + + dev_dbg(state->dev, "link setup %s -> %s", remote_pad->entity->name, + local_pad->entity->name); + + remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); + + mutex_lock(&state->lock); + + if (local_pad->flags & MEDIA_PAD_FL_SOURCE) { + if (flags & MEDIA_LNK_FL_ENABLED) { + if (state->sink_linked) { + ret = -EBUSY; + goto out; + } + state->sink_linked = true; + } else { + state->sink_linked = false; + } + } else { + if (flags & MEDIA_LNK_FL_ENABLED) { + if (state->src_sd) { + ret = -EBUSY; + goto out; + } + state->src_sd = remote_sd; + } else { + state->src_sd = NULL; + } + } + +out: + mutex_unlock(&state->lock); + return ret; +} + +static int mipi_csis_init_cfg(struct v4l2_subdev *mipi_sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct v4l2_mbus_framefmt *mf; + unsigned int i; + int ret; + + for (i = 0; i < CSIS_PADS_NUM; i++) { + mf = v4l2_subdev_get_try_format(mipi_sd, cfg, i); + + ret = imx_media_init_mbus_fmt(mf, MIPI_CSIS_DEF_PIX_HEIGHT, + MIPI_CSIS_DEF_PIX_WIDTH, 0, + V4L2_FIELD_NONE, NULL); + if (ret < 0) + return ret; + } + + return 0; +} + +static struct csis_pix_format const *mipi_csis_try_format( + struct v4l2_subdev *mipi_sd, + struct v4l2_mbus_framefmt *mf) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csis_pix_format const *csis_fmt; + + csis_fmt = find_csis_format(mf->code); + if (!csis_fmt) + csis_fmt = &mipi_csis_formats[0]; + + v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH, + csis_fmt->pix_width_alignment, + &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1, + 0); + + state->format_mbus.code = csis_fmt->code; + state->format_mbus.width = mf->width; + state->format_mbus.height = mf->height; + + return csis_fmt; +} + +static struct v4l2_mbus_framefmt *mipi_csis_get_format(struct csi_state *state, + struct v4l2_subdev_pad_config *cfg, + enum v4l2_subdev_format_whence which, + unsigned int pad) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&state->mipi_sd, cfg, pad); + + return &state->format_mbus; +} + +static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csis_pix_format const *csis_fmt; + struct v4l2_mbus_framefmt *fmt; + + if (sdformat->pad >= CSIS_PADS_NUM) + return -EINVAL; + + fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + + mutex_lock(&state->lock); + if (fmt && sdformat->pad == CSIS_PAD_SOURCE) { + sdformat->format = *fmt; + goto unlock; + } + + csis_fmt = mipi_csis_try_format(mipi_sd, &sdformat->format); + + sdformat->format = *fmt; + + if (csis_fmt && sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) + state->csis_fmt = csis_fmt; + else + cfg->try_fmt = sdformat->format; + +unlock: + mutex_unlock(&state->lock); + + return 0; +} + +static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_mbus_framefmt *fmt; + + mutex_lock(&state->lock); + + fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + + sdformat->format = *fmt; + + mutex_unlock(&state->lock); + + return 0; +} + +static int mipi_csis_log_status(struct v4l2_subdev *mipi_sd) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + + mutex_lock(&state->lock); + mipi_csis_log_counters(state, true); + if (state->debug && (state->flags & ST_POWERED)) + mipi_csis_dump_regs(state); + mutex_unlock(&state->lock); + + return 0; +} + +static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) +{ + struct csi_state *state = dev_id; + unsigned long flags; + unsigned int i; + u32 status; + + status = mipi_csis_read(state, MIPI_CSIS_INTSRC); + + spin_lock_irqsave(&state->slock, flags); + + /* Update the event/error counters */ + if ((status & MIPI_CSIS_INTSRC_ERRORS) || state->debug) { + for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) { + if (!(status & state->events[i].mask)) + continue; + state->events[i].counter++; + } + } + spin_unlock_irqrestore(&state->slock, flags); + + mipi_csis_write(state, MIPI_CSIS_INTSRC, status); + + return IRQ_HANDLED; +} + +static int mipi_csi_registered(struct v4l2_subdev *mipi_sd) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + unsigned int i; + int ret; + + for (i = 0; i < CSIS_PADS_NUM; i++) { + state->pads[i].flags = (i == CSIS_PAD_SINK) ? + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; + } + + /* set a default mbus format */ + ret = imx_media_init_mbus_fmt(&state->format_mbus, + MIPI_CSIS_DEF_PIX_HEIGHT, + MIPI_CSIS_DEF_PIX_WIDTH, 0, + V4L2_FIELD_NONE, NULL); + if (ret) + return ret; + + return media_entity_pads_init(&mipi_sd->entity, CSIS_PADS_NUM, + state->pads); +} + +static const struct v4l2_subdev_core_ops mipi_csis_core_ops = { + .log_status = mipi_csis_log_status, +}; + +static const struct media_entity_operations mipi_csis_entity_ops = { + .link_setup = mipi_csis_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +static const struct v4l2_subdev_video_ops mipi_csis_video_ops = { + .s_stream = mipi_csis_s_stream, +}; + +static const struct v4l2_subdev_pad_ops mipi_csis_pad_ops = { + .init_cfg = mipi_csis_init_cfg, + .get_fmt = mipi_csis_get_fmt, + .set_fmt = mipi_csis_set_fmt, +}; + +static const struct v4l2_subdev_ops mipi_csis_subdev_ops = { + .core = &mipi_csis_core_ops, + .video = &mipi_csis_video_ops, + .pad = &mipi_csis_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops mipi_csis_internal_ops = { + .registered = mipi_csi_registered, +}; + +static int mipi_csis_parse_dt(struct platform_device *pdev, + struct csi_state *state) +{ + struct device_node *node = pdev->dev.of_node; + + if (of_property_read_u32(node, "clock-frequency", + &state->clk_frequency)) + state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; + + /* Get MIPI PHY resets */ + state->mrst = devm_reset_control_get_exclusive(&pdev->dev, "mrst"); + if (IS_ERR(state->mrst)) + return PTR_ERR(state->mrst); + + /* Get MIPI CSI-2 bus configration from the endpoint node. */ + of_property_read_u32(node, "fsl,csis-hs-settle", &state->hs_settle); + + return 0; +} + +static int mipi_csis_pm_resume(struct device *dev, bool runtime); + +static int mipi_csis_parse_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *ep, + struct v4l2_async_subdev *asd) +{ + struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + + if (ep->bus_type != V4L2_MBUS_CSI2_DPHY) { + dev_err(dev, "invalid bus type, must be MIPI CSI2\n"); + return -EINVAL; + } + + state->bus = ep->bus.mipi_csi2; + + dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes); + dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags); + + return 0; +} + +static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, + struct platform_device *pdev, + const struct v4l2_subdev_ops *ops) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + unsigned int sink_port = 0; + int ret; + + v4l2_subdev_init(mipi_sd, ops); + mipi_sd->owner = THIS_MODULE; + snprintf(mipi_sd->name, sizeof(mipi_sd->name), "%s.%d", + CSIS_SUBDEV_NAME, state->index); + + mipi_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + mipi_sd->ctrl_handler = NULL; + + mipi_sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + mipi_sd->entity.ops = &mipi_csis_entity_ops; + + mipi_sd->dev = &pdev->dev; + + state->csis_fmt = &mipi_csis_formats[0]; + state->format_mbus.code = mipi_csis_formats[0].code; + state->format_mbus.width = MIPI_CSIS_DEF_PIX_WIDTH; + state->format_mbus.height = MIPI_CSIS_DEF_PIX_HEIGHT; + state->format_mbus.field = V4L2_FIELD_NONE; + + v4l2_set_subdevdata(mipi_sd, &pdev->dev); + + ret = v4l2_async_register_fwnode_subdev(mipi_sd, + sizeof(struct v4l2_async_subdev), &sink_port, 1, + mipi_csis_parse_endpoint); + if (ret < 0) + dev_err(&pdev->dev, "async fwnode register failed: %d\n", ret); + + return ret; +} + +#ifdef CONFIG_DEBUG_FS +#include + +static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) +{ + struct csi_state *state = m->private; + + return mipi_csis_dump_regs(state); +} +DEFINE_SHOW_ATTRIBUTE(mipi_csis_dump_regs); + +static int __init_or_module mipi_csis_debugfs_init(struct csi_state *state) +{ + struct dentry *d; + + if (!debugfs_initialized()) + return -ENODEV; + + state->debugfs_root = debugfs_create_dir(dev_name(state->dev), NULL); + if (!state->debugfs_root) + return -ENOMEM; + + d = debugfs_create_bool("debug_enable", 0600, state->debugfs_root, + &state->debug); + if (!d) + goto remove_debugfs; + + d = debugfs_create_file("dump_regs", 0600, state->debugfs_root, + state, &mipi_csis_dump_regs_fops); + if (!d) + goto remove_debugfs; + + return 0; + +remove_debugfs: + debugfs_remove_recursive(state->debugfs_root); + + return -ENOMEM; +} + +static void __exit mipi_csis_debugfs_exit(struct csi_state *state) +{ + debugfs_remove_recursive(state->debugfs_root); +} + +#else +static int mipi_csis_debugfs_init(struct csi_state *state __maybe_unused) +{ + return 0; +} + +static void mipi_csis_debugfs_exit(struct csi_state *state __maybe_unused) +{ +} +#endif + +static int mipi_csis_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *mem_res; + struct csi_state *state; + int ret = -ENOMEM; + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + spin_lock_init(&state->slock); + + state->pdev = pdev; + state->dev = dev; + + ret = mipi_csis_parse_dt(pdev, state); + if (ret < 0) { + dev_err(dev, "Failed to parse device tree: %d\n", ret); + return ret; + } + + mipi_csis_phy_init(state); + mipi_csis_phy_reset(state); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + state->regs = devm_ioremap_resource(dev, mem_res); + if (IS_ERR(state->regs)) + return PTR_ERR(state->regs); + + state->irq = platform_get_irq(pdev, 0); + if (state->irq < 0) { + dev_err(dev, "Failed to get irq\n"); + return state->irq; + } + + ret = mipi_csis_clk_get(state); + if (ret < 0) + return ret; + + mipi_csis_clk_enable(state); + + ret = devm_request_irq(dev, state->irq, mipi_csis_irq_handler, + 0, dev_name(dev), state); + if (ret) { + dev_err(dev, "Interrupt request failed\n"); + goto disable_clock; + } + + platform_set_drvdata(pdev, &state->mipi_sd); + + mutex_init(&state->lock); + ret = mipi_csis_subdev_init(&state->mipi_sd, pdev, + &mipi_csis_subdev_ops); + if (ret < 0) + goto disable_clock; + + state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&state->mipi_sd.entity, CSIS_PADS_NUM, + state->pads); + if (ret < 0) + goto unregister_subdev; + + memcpy(state->events, mipi_csis_events, sizeof(state->events)); + + mipi_csis_debugfs_init(state); + pm_runtime_enable(dev); + if (!pm_runtime_enabled(dev)) { + ret = mipi_csis_pm_resume(dev, true); + if (ret < 0) + goto unregister_all; + } + + dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n", + state->bus.num_data_lanes, state->hs_settle, + state->wrap_clk ? 1 : 0, state->clk_frequency); + + return 0; + +unregister_all: + mipi_csis_debugfs_exit(state); + media_entity_cleanup(&state->mipi_sd.entity); +unregister_subdev: + v4l2_async_unregister_subdev(&state->mipi_sd); +disable_clock: + mipi_csis_clk_disable(state); + mutex_destroy(&state->lock); + + return ret; +} + +static int mipi_csis_pm_suspend(struct device *dev, bool runtime) +{ + struct platform_device *pdev = to_platform_device(dev); + struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; + + mutex_lock(&state->lock); + if (state->flags & ST_POWERED) { + mipi_csis_stop_stream(state); + ret = regulator_disable(state->mipi_phy_regulator); + if (ret) + goto unlock; + mipi_csis_clk_disable(state); + state->flags &= ~ST_POWERED; + if (!runtime) + state->flags |= ST_SUSPENDED; + } + + unlock: + mutex_unlock(&state->lock); + + return ret ? -EAGAIN : 0; +} + +static int mipi_csis_pm_resume(struct device *dev, bool runtime) +{ + struct platform_device *pdev = to_platform_device(dev); + struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; + + mutex_lock(&state->lock); + if (!runtime && !(state->flags & ST_SUSPENDED)) + goto unlock; + + if (!(state->flags & ST_POWERED)) { + ret = regulator_enable(state->mipi_phy_regulator); + if (ret) + goto unlock; + + state->flags |= ST_POWERED; + mipi_csis_clk_enable(state); + } + if (state->flags & ST_STREAMING) + mipi_csis_start_stream(state); + + state->flags &= ~ST_SUSPENDED; + + unlock: + mutex_unlock(&state->lock); + + return ret ? -EAGAIN : 0; +} + +static int mipi_csis_suspend(struct device *dev) +{ + return mipi_csis_pm_suspend(dev, false); +} + +static int mipi_csis_resume(struct device *dev) +{ + return mipi_csis_pm_resume(dev, false); +} + +static int mipi_csis_runtime_suspend(struct device *dev) +{ + return mipi_csis_pm_suspend(dev, true); +} + +static int mipi_csis_runtime_resume(struct device *dev) +{ + return mipi_csis_pm_resume(dev, true); +} + +static int mipi_csis_remove(struct platform_device *pdev) +{ + struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + + mipi_csis_debugfs_exit(state); + v4l2_async_unregister_subdev(&state->mipi_sd); + v4l2_async_notifier_unregister(&state->subdev_notifier); + + pm_runtime_disable(&pdev->dev); + mipi_csis_pm_suspend(&pdev->dev, true); + mipi_csis_clk_disable(state); + media_entity_cleanup(&state->mipi_sd.entity); + mutex_destroy(&state->lock); + pm_runtime_set_suspended(&pdev->dev); + + return 0; +} + +static const struct dev_pm_ops mipi_csis_pm_ops = { + SET_RUNTIME_PM_OPS(mipi_csis_runtime_suspend, mipi_csis_runtime_resume, + NULL) + SET_SYSTEM_SLEEP_PM_OPS(mipi_csis_suspend, mipi_csis_resume) +}; + +static const struct of_device_id mipi_csis_of_match[] = { + { .compatible = "fsl,imx7-mipi-csi2", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, mipi_csis_of_match); + +static struct platform_driver mipi_csis_driver = { + .probe = mipi_csis_probe, + .remove = mipi_csis_remove, + .driver = { + .of_match_table = mipi_csis_of_match, + .name = CSIS_DRIVER_NAME, + .pm = &mipi_csis_pm_ops, + }, +}; + +module_platform_driver(mipi_csis_driver); + +MODULE_DESCRIPTION("i.MX7 MIPI CSI-2 Receiver driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:imx7-mipi-csi2"); From patchwork Wed Jan 23 10:52:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 156360 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp576326jaa; Wed, 23 Jan 2019 02:53:03 -0800 (PST) X-Google-Smtp-Source: ALg8bN6SWOLzop4Ejf3HOddacAhKlWfHPUdgNP/XxvRTxLK6HvBC4J+/eFlIbFnHeefWsH0/l6c8 X-Received: by 2002:a63:cc4e:: with SMTP id q14mr1493193pgi.291.1548240782978; Wed, 23 Jan 2019 02:53:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548240782; cv=none; d=google.com; s=arc-20160816; b=w2XxNPy7eTYukm9zB8OREyFB7RdD3I9QOKT876zJFNMJ3fmvqZblMRng1Nrbrpxe5P 7Uml2CePnGxdur/iLz8rbfWV/wRIMvXhJAs0u3GdGlVxmFF/qOJDwiJ/MVD0BXA493mw G124lSpVXIePLabGz7+lwrKkq26a2Gtx3SQ2dZ1VwLyH2IEKUMmEcwbANEyWTtp2F0/8 yZ5F1blL8D8E6ZOONPN3L4vmlHFA4FiMM3TUmo1fse5KoNc74HJprpg6a/QMPqpE/wIS g6FWY+luVzC26eaJcpIh4EGl+0eyprQ0tKkPC12rg2Hbm0GKiZ3wOvxSswSoLYx3WA6V 2HYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=L5/ZatHVS6k0zuueuC+fG2FGCCYEwoOCEErHC/rO77Q=; b=ZWRHfsaPFMes9NfaBJIpDxQ1p1d1MjFu9tutoxvRY9kOEk2NG4WIQ8y3LICQbiTd/E DltJGmN02tCjT2R04jAgy8FzpLGDWWFHWjHdcyIwcEMbJpMGSrpOhuPy0Bf215bXEabi qywBDXjkSZaUqup4RPmSvIc97rIuhAnTUTgBupKWrSMYcICKhARvnQ07KL3/iFRYA6yb wHanP2T/TUlr1oT9+rw+0/4kF60zYDC7O3kCNhQrFMS7i48G8QFsSzNUxOWZSpqCgH4f JM9WA0FyvfPgFq5FA8aKwm0ebchxcxzaX5X+T8veG65RO36zEfw8vdM+LvLs6hLTZr5U k83g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WArNDcBc; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (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 a6si18061494pfa.227.2019.01.23.02.53.02; Wed, 23 Jan 2019 02:53:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WArNDcBc; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727488AbfAWKxB (ORCPT + 4 others); Wed, 23 Jan 2019 05:53:01 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:34554 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727468AbfAWKxA (ORCPT ); Wed, 23 Jan 2019 05:53:00 -0500 Received: by mail-wr1-f65.google.com with SMTP id f7so1886803wrp.1 for ; Wed, 23 Jan 2019 02:52:59 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=L5/ZatHVS6k0zuueuC+fG2FGCCYEwoOCEErHC/rO77Q=; b=WArNDcBczbN80s3h4ONU6lYVsZcXDqg0Iw2nLxwXnZY11KvLc46YyrmmG6M2QW1hXU ZrYLhBYy3bMBVGQrrvWRpsfi6L7BdzRL9qhT56syrmpzA3eny7iiw+P6NGfPHzHeIuMs vgutgcEmj1ZwM/qffRc/FDF2hwOzqz9qXVZuc= 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:mime-version:content-transfer-encoding; bh=L5/ZatHVS6k0zuueuC+fG2FGCCYEwoOCEErHC/rO77Q=; b=Z0bLmfDU/9o2UspXjpSWP6XJZ/E8RLJo8vYmgCsQVsxYWsuAcp74DODf7NyLSk6uG2 fcTVK5MPD86Sp/wJ77Dfnc19DsOrLSTg56Au+Ef7oVs/JOI9FpEtN4U30dsZaDQKzq70 RkVjpVsB0knuyE/x5cksVF9ChYE5nG6MsF1zPyH3HoIAj8spUh6DBgW4rYqkHWfB+QEm +jcVJcvEoe0s/mB+U+MPmVtVaRM7qFmwqKn9ODcaGflliB13kyMN+yBiY5UbL9ED44b7 DyjET3qsfrWMLw0groJZozsnIwoNXCC2IwVyqFxAnGvz3KwQiMZYohYiQPB8aPbTVECS Polg== X-Gm-Message-State: AJcUukdAUze7Qkyawrxo5jftEJmL++vBoT6F/40ypie15CtxKNyp0dcz YG/t3Bbkzrf7fU2dyt6hgChD6Q== X-Received: by 2002:adf:f984:: with SMTP id f4mr2157968wrr.234.1548240778537; Wed, 23 Jan 2019 02:52:58 -0800 (PST) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 143sm120717646wml.14.2019.01.23.02.52.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jan 2019 02:52:58 -0800 (PST) From: Rui Miguel Silva To: sakari.ailus@linux.intel.com, Steve Longerbeam , Hans Verkuil , Philipp Zabel Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, devicetree@vger.kernel.org, Greg Kroah-Hartman , Rui Miguel Silva Subject: [PATCH v10 06/13] ARM: dts: imx7s: add mipi phy power domain Date: Wed, 23 Jan 2019 10:52:15 +0000 Message-Id: <20190123105222.2378-7-rui.silva@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190123105222.2378-1-rui.silva@linaro.org> References: <20190123105222.2378-1-rui.silva@linaro.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add power domain index 0 related with mipi-phy to imx7s. While at it rename pcie power-domain node to remove pgc prefix. Signed-off-by: Rui Miguel Silva --- arch/arm/boot/dts/imx7s.dtsi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index e88f53a4c7f4..9a680d3d6424 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -606,7 +606,13 @@ #address-cells = <1>; #size-cells = <0>; - pgc_pcie_phy: pgc-power-domain@1 { + pgc_mipi_phy: power-domain@0 { + #power-domain-cells = <0>; + reg = <0>; + power-supply = <®_1p0d>; + }; + + pgc_pcie_phy: power-domain@1 { #power-domain-cells = <0>; reg = <1>; power-supply = <®_1p0d>; From patchwork Wed Jan 23 10:52:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 156361 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp576359jaa; Wed, 23 Jan 2019 02:53:05 -0800 (PST) X-Google-Smtp-Source: ALg8bN65gMFBFJGeamXv9VmCue3Jc2K+9Qy/OKYHMZ28k9W4Yr2IWZaZ0KZHQOQnO5pd4REMyuH4 X-Received: by 2002:a62:32c4:: with SMTP id y187mr1632154pfy.195.1548240784963; Wed, 23 Jan 2019 02:53:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548240784; cv=none; d=google.com; s=arc-20160816; b=lE6R2cp5OsLAGsVtReE+W55BdJNWj+UCwyXnZ6Z785SYeKM9rzu1faLp6zywUrjIk3 MyYXsN5eYR1KMHeFz+FFZ3C/YdZ11+2QixgCx1Jqvmna5KnNAjHsW79tlxhT3/HHellG 3qb/q8BgxDU353gEO8lz7nwsckGH37u2ya3kXiRJRMyj/jYufcR5Tcz3Q6TaXTkzpc4O UT6/e0UMp4q1xrSgNU00FDtwptbV43GUWgHlGY5ol0b+lrBrkgKI9RUKsf2jmdom7Onc ZL0Xrso7BDsN6RwwNXVYnA4KzlQtWeSCBwxZ2LmwfSHOSYd+aSim491I0asd57pU0Lcw 04Nw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=PZIgvxbRSp4W/ltSJos2CgWWjWg2sGcAUX9XqZxaGQg=; b=Butq5PTm5TKTztgb5KkiLa0R1x5il3r8vanBsBEGjaUQpILHGdHsMPX1Zr2kxpAUm4 wim73EIdlfRupdmmyzwcvCHNimx566AqILvd0ZRB8Se0lniMM91KbOeEbwOFHfhd+0AQ CGpiSy0aG+CzE22dwT3P2t+qgqCJOx/3xuYHQ6S6uDbJqe5JtfLHAOqEi5RHnvza9kSG TOAfGAj2MtKbCqnV1Xg6FknVrcz/LpAqj51rehzoOb83MEvFdEdpgWbSxrSaPPkMKSGt sICMu+ZZT7YfIuKx4dHOfHz4zYMORDsKJVZ/k8/yJpRnqLAwSIUIekEBssXVNr2KAG2n ZUnA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gI07MRMZ; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (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 a6si18061494pfa.227.2019.01.23.02.53.04; Wed, 23 Jan 2019 02:53:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gI07MRMZ; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727498AbfAWKxD (ORCPT + 4 others); Wed, 23 Jan 2019 05:53:03 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:37709 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727495AbfAWKxC (ORCPT ); Wed, 23 Jan 2019 05:53:02 -0500 Received: by mail-wr1-f68.google.com with SMTP id s12so1863626wrt.4 for ; Wed, 23 Jan 2019 02:53:01 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=PZIgvxbRSp4W/ltSJos2CgWWjWg2sGcAUX9XqZxaGQg=; b=gI07MRMZ38Q0EFDhZ3LKRqk9tDUhlMS2MoqS31K55ynwl+sQObP4Sv2/R6Qcocy8FC B12IZ/L2+/QydtfZSqFXK1Nz/SNPdEuMNXEHK/8QOcQXYxumC6RJgQjpvqRZ3WNXcyKO ra1mAxpAGZpa151ad1+Zj0WFhLzhedcD223fM= 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:mime-version:content-transfer-encoding; bh=PZIgvxbRSp4W/ltSJos2CgWWjWg2sGcAUX9XqZxaGQg=; b=aHntztokhqNfQjwMOYHCiL67F6nGMJ8npsyLTz5ucipr2iYLChzmWcaYqzdNK8Whuk QSxwsEwn/gIuuncRZ6LYQALNXDPtOgqIyFZyZxvHvoxRw+73H0ihpaf79EfdEo86H5ai z349EtckiSgPB62jxd5gmUCNSFND5shSEwtz2NtPVrYVroTIf1pAv4Xu3Sm3Ri3ZT8TC 7WnNs1bheBfDrmiPxKchb1VLfZhrVNFpTG9Ed94zuiRilxRXmuVoSZ7M5cSHGr1GKVEq 5CxKzj9q/3paqzs7/KI1QslvlBCPTE+wmQhLmvDSuhJM4Evrnx3BLzV1Dj/gcqO6mk9q lCNA== X-Gm-Message-State: AJcUukd7yVWopUktw789ninJyuzjGEwKqbdan/90U0H1AV3j4/tBz8+j 7mSZIGRLLplsbYonYqSluzxM1w== X-Received: by 2002:adf:fd81:: with SMTP id d1mr2191466wrr.105.1548240780763; Wed, 23 Jan 2019 02:53:00 -0800 (PST) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 143sm120717646wml.14.2019.01.23.02.52.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jan 2019 02:53:00 -0800 (PST) From: Rui Miguel Silva To: sakari.ailus@linux.intel.com, Steve Longerbeam , Hans Verkuil , Philipp Zabel Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, devicetree@vger.kernel.org, Greg Kroah-Hartman , Rui Miguel Silva Subject: [PATCH v10 07/13] ARM: dts: imx7s: add multiplexer controls Date: Wed, 23 Jan 2019 10:52:16 +0000 Message-Id: <20190123105222.2378-8-rui.silva@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190123105222.2378-1-rui.silva@linaro.org> References: <20190123105222.2378-1-rui.silva@linaro.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@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 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 9a680d3d6424..792efcd2caa1 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -497,8 +497,15 @@ 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 Wed Jan 23 10:52:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Miguel Silva X-Patchwork-Id: 156366 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp576473jaa; Wed, 23 Jan 2019 02:53:14 -0800 (PST) X-Google-Smtp-Source: ALg8bN40i5YnOy+EvlmX0JUWw4IMX01aoWyzv/j8h/2K/xir2HOA4+KI10ayklYPy/Pq9fWzfD2F X-Received: by 2002:a62:d206:: with SMTP id c6mr1560015pfg.245.1548240794859; Wed, 23 Jan 2019 02:53:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548240794; cv=none; d=google.com; s=arc-20160816; b=0+B6M++vCGKu8DYIDICSmXCtwsl+qNJBlL2Nd7CxpvKiKZY8rE5jUFbZh+7gr2nZts UKexYvWL+aB7Fvo3kwmR8T5fM5ttb71zRxNh4n5nFKAUsZuxcZqxfQOfKj3KVJnu6ZjF V5fGHfirw4u2vzQ7D5rZfKP1XFxwQ4lcdUuKcj2twK2nAwqMvhC1J/HZhschcTv7RYsM CK8fBtXmqTAxR8Jm8JTzO2ZZwnI3VrawJk0ICjgrmjU0lLtBnPH01HyGOZc6RevsSZfN HQS4xc65ibykaCDoeyCt8jPt69nPOt+KcuO6ZB0tz2KRx6292GUmSyvdiMU86WpEoWD/ aSyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gY2LNKMG7qpa54ba4CVP1G13ldcfqAPv/cqBQsiaTTo=; b=RlZpQPZLB9ZG/+g3RP/kNdlKPBIxcECSqxKMxMJ/umyVLsvl2IyTpJ5356ZdXJ4tda ymgaPRVwomMZMmBZJQrALxTjYW3uz9hABav8JUX6CuyNixMqU+OsL+gj2eCljpa+Q77p t9qcAvIn+afaq+kWzsNEcWCBQi6NktmZ1gBHYMmLc3oinZ8oEy00wWslxPkiMDBbidWc fF3gvQbI8ARWcpsZl6KYZYhEWhc3xZ3KzYX4s1qGMovZGf0WvIxCQGXdcr+0Rv24aOuQ KkBYTLy1MC8jgLRDLd58RPioUjuhupG7eq8brYuEn5j2raxwfb0M8PF0dO/cKtpBqtbZ ub7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KEvrarep; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (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 a6si18061494pfa.227.2019.01.23.02.53.14; Wed, 23 Jan 2019 02:53:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KEvrarep; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727529AbfAWKxO (ORCPT + 4 others); Wed, 23 Jan 2019 05:53:14 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:46232 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727527AbfAWKxN (ORCPT ); Wed, 23 Jan 2019 05:53:13 -0500 Received: by mail-wr1-f65.google.com with SMTP id l9so1820792wrt.13 for ; Wed, 23 Jan 2019 02:53:12 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=gY2LNKMG7qpa54ba4CVP1G13ldcfqAPv/cqBQsiaTTo=; b=KEvrarepuUMtTfXKBQ5nc9RMscwWNeKfB766QwHscfHjgRfsycibJ9sxGxt1zKpbCr CyIN+9/fy4ju6tmqZYqGEFFIqRXhgmeEEp8JfNCd1cpr/FnTDFvfb5lAM4Z3gxSwth9J HA9eylytnBQoDSDDH9WejPTSUj7lqHCYPPXsg= 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:mime-version:content-transfer-encoding; bh=gY2LNKMG7qpa54ba4CVP1G13ldcfqAPv/cqBQsiaTTo=; b=IgS0bnIU8/fHG8OWtkZrsCR3Op7aVcVTWD/Spp7RNAtijnTkSh38V3xBUyyZRdO2vB q5Yrfbjoov/Y4WS4l1P7NGsuLAc0c+d6vbxQVvbjcM/L0GXYWuRG0cW0+Gk/OWT9Ky+y wsBCv5VMvkS4pU3pPxL1/G/V6TEPvWbxxc0onm8bcsDKEEqy0yEwYd1Z1qRIXAmzurvS FradEFihTY0GJZrPt9qtehRZ8a75RLlp8mDBJO8l9O0vXFBcsLYBLvxLtGihV6nHS53J Fh3HB8jYi4XpbvCvnrBpt7/7AxiE+jv4zDNPmlf3kiG0MpeNaMnE2/H0d2rWwMx9Gb7D ghvg== X-Gm-Message-State: AJcUukfgTSSrahlgV0rnJz6cZBSwHGjlFCFlu2oUX22L1Wuqly9F+SP8 XkVCnC17+TvW5/EMAfgIMqf4Yg== X-Received: by 2002:adf:ed92:: with SMTP id c18mr2196486wro.194.1548240791418; Wed, 23 Jan 2019 02:53:11 -0800 (PST) Received: from arch-late.local (a109-49-46-234.cpe.netcabo.pt. [109.49.46.234]) by smtp.gmail.com with ESMTPSA id 143sm120717646wml.14.2019.01.23.02.53.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jan 2019 02:53:11 -0800 (PST) From: Rui Miguel Silva To: sakari.ailus@linux.intel.com, Steve Longerbeam , Hans Verkuil , Philipp Zabel Cc: linux-media@vger.kernel.org, devel@driverdev.osuosl.org, devicetree@vger.kernel.org, Greg Kroah-Hartman , Rui Miguel Silva Subject: [PATCH v10 12/13] media: video-mux: add bayer formats Date: Wed, 23 Jan 2019 10:52:21 +0000 Message-Id: <20190123105222.2378-13-rui.silva@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190123105222.2378-1-rui.silva@linaro.org> References: <20190123105222.2378-1-rui.silva@linaro.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add non vendor bayer formats to the allowed format array. Signed-off-by: Rui Miguel Silva --- drivers/media/platform/video-mux.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) -- 2.20.1 Reviewed-by: Philipp Zabel diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index c33900e3c23e..0ba30756e1e4 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -263,6 +263,26 @@ static int video_mux_set_format(struct v4l2_subdev *sd, case MEDIA_BUS_FMT_UYYVYY16_0_5X48: case MEDIA_BUS_FMT_JPEG_1X8: case MEDIA_BUS_FMT_AHSV8888_1X32: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SRGGB12_1X12: + case MEDIA_BUS_FMT_SBGGR14_1X14: + case MEDIA_BUS_FMT_SGBRG14_1X14: + case MEDIA_BUS_FMT_SGRBG14_1X14: + case MEDIA_BUS_FMT_SRGGB14_1X14: + case MEDIA_BUS_FMT_SBGGR16_1X16: + case MEDIA_BUS_FMT_SGBRG16_1X16: + case MEDIA_BUS_FMT_SGRBG16_1X16: + case MEDIA_BUS_FMT_SRGGB16_1X16: break; default: sdformat->format.code = MEDIA_BUS_FMT_Y8_1X8;