Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 1/2] Documentation: devicetree: Add document bindings for mtk-cir
From: sean.wang @ 2017-01-10  9:13 UTC (permalink / raw)
  To: mchehab, hdegoede, hkallweit1, robh+dt, mark.rutland,
	matthias.bgg
  Cc: devicetree, ivo.g.dimitrov.75, keyhaede, sean, Sean Wang,
	linux-kernel, andi.shyti, hverkuil, linux-mediatek,
	linux-arm-kernel, linux-media
In-Reply-To: <1484039631-25120-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

This patch adds documentation for devicetree bindings for
Mediatek consumer IR controller.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 .../devicetree/bindings/media/mtk-cir.txt          | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mtk-cir.txt

diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt
new file mode 100644
index 0000000..3850cbd
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mtk-cir.txt
@@ -0,0 +1,24 @@
+Device-Tree bindings for Mediatek consumer IR controller found in
+Mediatek SoC family
+
+Required properties:
+- compatible	    : "mediatek,mt7623-cir"
+- clocks	    : list of clock specifiers, corresponding to
+		      entries in clock-names property;
+- clock-names	    : should contain "clk" entries;
+- interrupts	    : should contain IR IRQ number;
+- reg		    : should contain IO map address for IR.
+
+Optional properties:
+- linux,rc-map-name : Remote control map name.
+
+Example:
+
+cir: cir@10013000 {
+	compatible = "mediatek,mt7623-cir";
+	reg = <0 0x10013000 0 0x1000>;
+	interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
+	clocks = <&infracfg CLK_INFRA_IRRX>;
+	clock-names = "clk";
+	linux,rc-map-name = "rc-rc6-mce";
+};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
From: sean.wang @ 2017-01-10  9:13 UTC (permalink / raw)
  To: mchehab, hdegoede, hkallweit1, robh+dt, mark.rutland,
	matthias.bgg
  Cc: devicetree, ivo.g.dimitrov.75, keyhaede, sean, Sean Wang,
	linux-kernel, andi.shyti, hverkuil, linux-mediatek,
	linux-arm-kernel, linux-media
In-Reply-To: <1484039631-25120-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

This patch adds driver for IR controller on MT7623 SoC.
and should also work on similar Mediatek SoC. Currently
testing successfully on NEC and SONY remote controller
only but it should work on others (lirc, rc-5 and rc-6).

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Reviewed-by: Sean Young <sean@mess.org>
---
 drivers/media/rc/Kconfig   |  11 ++
 drivers/media/rc/Makefile  |   1 +
 drivers/media/rc/mtk-cir.c | 326 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 338 insertions(+)
 create mode 100644 drivers/media/rc/mtk-cir.c

diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 629e8ca..9228479 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -235,6 +235,17 @@ config IR_MESON
 	   To compile this driver as a module, choose M here: the
 	   module will be called meson-ir.
 
+config IR_MTK
+	tristate "Mediatek IR remote receiver"
+	depends on RC_CORE
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	---help---
+	   Say Y if you want to use the IR remote receiver available
+	   on Mediatek SoCs.
+
+	   To compile this driver as a module, choose M here: the
+	   module will be called mtk-cir.
+
 config IR_NUVOTON
 	tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
 	depends on PNP
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 3a984ee..a78570b 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_RC_ST) += st_rc.o
 obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
 obj-$(CONFIG_IR_IMG) += img-ir/
 obj-$(CONFIG_IR_SERIAL) += serial_ir.o
+obj-$(CONFIG_IR_MTK) += mtk-cir.o
diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
new file mode 100644
index 0000000..f752f63
--- /dev/null
+++ b/drivers/media/rc/mtk-cir.c
@@ -0,0 +1,326 @@
+/*
+ * Driver for Mediatek IR Receiver Controller
+ *
+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+#include <media/rc-core.h>
+
+#define MTK_IR_DEV KBUILD_MODNAME
+
+/* Register to enable PWM and IR */
+#define MTK_CONFIG_HIGH_REG       0x0c
+/* Enable IR pulse width detection */
+#define MTK_PWM_EN		  BIT(13)
+/* Enable IR hardware function */
+#define MTK_IR_EN		  BIT(0)
+
+/* Register to setting sample period */
+#define MTK_CONFIG_LOW_REG        0x10
+/* Field to set sample period */
+#define CHK_PERIOD		  DIV_ROUND_CLOSEST(MTK_IR_SAMPLE,  \
+						    MTK_IR_CLK_PERIOD)
+#define MTK_CHK_PERIOD            (((CHK_PERIOD) << 8) & (GENMASK(20, 8)))
+#define MTK_CHK_PERIOD_MASK	  (GENMASK(20, 8))
+
+/* Register to clear state of state machine */
+#define MTK_IRCLR_REG             0x20
+/* Bit to restart IR receiving */
+#define MTK_IRCLR		  BIT(0)
+
+/* Register containing pulse width data */
+#define MTK_CHKDATA_REG(i)        (0x88 + 4 * (i))
+#define MTK_WIDTH_MASK		  (GENMASK(7, 0))
+
+/* Register to enable IR interrupt */
+#define MTK_IRINT_EN_REG          0xcc
+/* Bit to enable interrupt */
+#define MTK_IRINT_EN		  BIT(0)
+
+/* Register to ack IR interrupt */
+#define MTK_IRINT_CLR_REG         0xd0
+/* Bit to clear interrupt status */
+#define MTK_IRINT_CLR		  BIT(0)
+
+/* Maximum count of samples */
+#define MTK_MAX_SAMPLES		  0xff
+/* Indicate the end of IR message */
+#define MTK_IR_END(v, p)	  ((v) == MTK_MAX_SAMPLES && (p) == 0)
+/* Number of registers to record the pulse width */
+#define MTK_CHKDATA_SZ		  17
+/* Source clock frequency */
+#define MTK_IR_BASE_CLK		  273000000
+/* Frequency after IR internal divider */
+#define MTK_IR_CLK_FREQ		  (MTK_IR_BASE_CLK / 4)
+/* Period for MTK_IR_CLK in ns*/
+#define MTK_IR_CLK_PERIOD	  DIV_ROUND_CLOSEST(1000000000ul,  \
+						    MTK_IR_CLK_FREQ)
+/* Sample period in ns */
+#define MTK_IR_SAMPLE		  (MTK_IR_CLK_PERIOD * 0xc00)
+
+/* struct mtk_ir -	This is the main datasructure for holding the state
+ *			of the driver
+ * @dev:		The device pointer
+ * @rc:			The rc instrance
+ * @irq:		The IRQ that we are using
+ * @base:		The mapped register i/o base
+ * @clk:		The clock that we are using
+ */
+struct mtk_ir {
+	struct device	*dev;
+	struct rc_dev	*rc;
+	void __iomem	*base;
+	int		irq;
+	struct clk	*clk;
+};
+
+static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
+{
+	u32 tmp;
+
+	tmp = __raw_readl(ir->base + reg);
+	tmp = (tmp & ~mask) | val;
+	__raw_writel(tmp, ir->base + reg);
+}
+
+static void mtk_w32(struct mtk_ir *ir, u32 val, unsigned int reg)
+{
+	__raw_writel(val, ir->base + reg);
+}
+
+static u32 mtk_r32(struct mtk_ir *ir, unsigned int reg)
+{
+	return __raw_readl(ir->base + reg);
+}
+
+static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
+{
+	u32 val;
+
+	val = mtk_r32(ir, MTK_IRINT_EN_REG);
+	mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG);
+}
+
+static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
+{
+	u32 val;
+
+	val = mtk_r32(ir, MTK_IRINT_EN_REG);
+	mtk_w32(ir, val | mask, MTK_IRINT_EN_REG);
+}
+
+static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
+{
+	struct mtk_ir *ir = dev_id;
+	u8  wid = 0;
+	u32 i, j, val;
+	DEFINE_IR_RAW_EVENT(rawir);
+
+	mtk_irq_disable(ir, MTK_IRINT_EN);
+
+	/* Reset decoder state machine */
+	ir_raw_event_reset(ir->rc);
+
+	/* First message must be pulse */
+	rawir.pulse = false;
+
+	/* Handle all pulse and space IR controller captures */
+	for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
+		val = mtk_r32(ir, MTK_CHKDATA_REG(i));
+		dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);
+
+		for (j = 0 ; j < 4 ; j++) {
+			wid = (val & (MTK_WIDTH_MASK << j * 8)) >> j * 8;
+			rawir.pulse = !rawir.pulse;
+			rawir.duration = wid * (MTK_IR_SAMPLE + 1);
+			ir_raw_event_store_with_filter(ir->rc, &rawir);
+		}
+	}
+
+	/* The maximum number of edges the IR controller can
+	 * hold is MTK_CHKDATA_SZ * 4. So if received IR messages
+	 * is over the limit, the last incomplete IR message would
+	 * be appended trailing space and still would be sent into
+	 * ir-rc-raw to decode. That helps it is possible that it
+	 * has enough information to decode a scancode even if the
+	 * trailing end of the message is missing.
+	 */
+	if (!MTK_IR_END(wid, rawir.pulse)) {
+		rawir.pulse = false;
+		rawir.duration = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
+		ir_raw_event_store_with_filter(ir->rc, &rawir);
+	}
+
+	ir_raw_event_handle(ir->rc);
+
+	/* Restart controller for the next receive */
+	mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG);
+
+	/* Clear interrupt status */
+	mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG);
+
+	/* Enable interrupt */
+	mtk_irq_enable(ir, MTK_IRINT_EN);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_ir_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *dn = dev->of_node;
+	struct resource *res;
+	struct mtk_ir *ir;
+	u32 val;
+	int ret = 0;
+	const char *map_name;
+
+	ir = devm_kzalloc(dev, sizeof(struct mtk_ir), GFP_KERNEL);
+	if (!ir)
+		return -ENOMEM;
+
+	ir->dev = dev;
+
+	if (!of_device_is_compatible(dn, "mediatek,mt7623-cir"))
+		return -ENODEV;
+
+	ir->clk = devm_clk_get(dev, "clk");
+	if (IS_ERR(ir->clk)) {
+		dev_err(dev, "failed to get a ir clock.\n");
+		return PTR_ERR(ir->clk);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ir->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ir->base)) {
+		dev_err(dev, "failed to map registers\n");
+		return PTR_ERR(ir->base);
+	}
+
+	ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
+	if (!ir->rc) {
+		dev_err(dev, "failed to allocate device\n");
+		return -ENOMEM;
+	}
+
+	ir->rc->priv = ir;
+	ir->rc->input_name = MTK_IR_DEV;
+	ir->rc->input_phys = MTK_IR_DEV "/input0";
+	ir->rc->input_id.bustype = BUS_HOST;
+	ir->rc->input_id.vendor = 0x0001;
+	ir->rc->input_id.product = 0x0001;
+	ir->rc->input_id.version = 0x0001;
+	map_name = of_get_property(dn, "linux,rc-map-name", NULL);
+	ir->rc->map_name = map_name ?: RC_MAP_EMPTY;
+	ir->rc->dev.parent = dev;
+	ir->rc->driver_name = MTK_IR_DEV;
+	ir->rc->allowed_protocols = RC_BIT_ALL;
+	ir->rc->rx_resolution = MTK_IR_SAMPLE;
+	ir->rc->timeout = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
+
+	ret = devm_rc_register_device(dev, ir->rc);
+	if (ret) {
+		dev_err(dev, "failed to register rc device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, ir);
+
+	ir->irq = platform_get_irq(pdev, 0);
+	if (ir->irq < 0) {
+		dev_err(dev, "no irq resource\n");
+		return -ENODEV;
+	}
+
+	/* Enable interrupt after proper hardware
+	 * setup and IRQ handler registration
+	 */
+	if (clk_prepare_enable(ir->clk)) {
+		dev_err(dev, "try to enable ir_clk failed\n");
+		ret = -EINVAL;
+		goto exit_clkdisable_clk;
+	}
+
+	mtk_irq_disable(ir, MTK_IRINT_EN);
+
+	ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
+	if (ret) {
+		dev_err(dev, "failed request irq\n");
+		goto exit_clkdisable_clk;
+	}
+
+	/* Enable IR and PWM */
+	val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
+	val |= MTK_PWM_EN | MTK_IR_EN;
+	mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);
+
+	/* Setting sample period */
+	mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK,
+		     MTK_CONFIG_LOW_REG);
+
+	mtk_irq_enable(ir, MTK_IRINT_EN);
+
+	dev_info(dev, "Initialized MT7623 IR driver, sample period = %luus\n",
+		 DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000));
+
+	return 0;
+
+exit_clkdisable_clk:
+	clk_disable_unprepare(ir->clk);
+
+	return ret;
+}
+
+static int mtk_ir_remove(struct platform_device *pdev)
+{
+	struct mtk_ir *ir = platform_get_drvdata(pdev);
+
+	/* Avoid contention between remove handler and
+	 * IRQ handler so that disabling IR interrupt and
+	 * waiting for pending IRQ handler to complete
+	 */
+	mtk_irq_disable(ir, MTK_IRINT_EN);
+	synchronize_irq(ir->irq);
+
+	clk_disable_unprepare(ir->clk);
+
+	rc_unregister_device(ir->rc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_ir_match[] = {
+	{ .compatible = "mediatek,mt7623-cir" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_ir_match);
+
+static struct platform_driver mtk_ir_driver = {
+	.probe          = mtk_ir_probe,
+	.remove         = mtk_ir_remove,
+	.driver = {
+		.name = MTK_IR_DEV,
+		.of_match_table = mtk_ir_match,
+	},
+};
+
+module_platform_driver(mtk_ir_driver);
+
+MODULE_DESCRIPTION("Mediatek IR Receiver Controller Driver");
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH v7 1/2] mtd: arasan: Add device tree binding documentation
From: Boris Brezillon @ 2017-01-10  9:16 UTC (permalink / raw)
  To: Punnaiah Choudary Kalluri
  Cc: Rob Herring, dwmw2@infradead.org, computersforpeace@gmail.com,
	marek.vasut@gmail.com, richard@nod.at, cyrille.pitchen@atmel.com,
	mark.rutland@arm.com, linux-kernel@vger.kernel.org,
	linux-mtd@lists.infradead.org, devicetree@vger.kernel.org,
	Michal Simek, kalluripunnaiahchoudary@gmail.com, kpc528@gmail.com
In-Reply-To: <03CA77BA8AF6F1469AEDFBDA1322A7B76424EDC1@XAP-PVEXMBX02.xlnx.xilinx.com>

On Tue, 10 Jan 2017 08:48:09 +0000
Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri@xilinx.com> wrote:

> Hi Boris,
> 
>   Thanks. I will implement these changes and send the next series.

Please wait a bit. I still need to review the driver.

> 
> Regards,
> Punnaiah
> 
> > -----Original Message-----
> > From: Boris Brezillon [mailto:boris.brezillon@free-electrons.com]
> > Sent: Tuesday, January 10, 2017 1:36 PM
> > To: Punnaiah Choudary Kalluri <punnaia@xilinx.com>
> > Cc: Rob Herring <robh@kernel.org>; dwmw2@infradead.org;
> > computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
> > cyrille.pitchen@atmel.com; mark.rutland@arm.com; linux-
> > kernel@vger.kernel.org; linux-mtd@lists.infradead.org;
> > devicetree@vger.kernel.org; Michal Simek <michals@xilinx.com>;
> > kalluripunnaiahchoudary@gmail.com; kpc528@gmail.com
> > Subject: Re: [PATCH v7 1/2] mtd: arasan: Add device tree binding
> > documentation
> > 
> > Hi Punnaiah,
> > 
> > On Tue, 10 Jan 2017 06:03:25 +0000
> > Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri@xilinx.com> wrote:
> >   
> > > Hi Rob,
> > >
> > >    Thanks for the review.
> > >  
> > > > -----Original Message-----
> > > > From: Rob Herring [mailto:robh@kernel.org]
> > > > Sent: Tuesday, January 10, 2017 11:06 AM
> > > > To: Punnaiah Choudary Kalluri <punnaia@xilinx.com>
> > > > Cc: dwmw2@infradead.org; computersforpeace@gmail.com;
> > > > boris.brezillon@free-electrons.com; marek.vasut@gmail.com;
> > > > richard@nod.at; cyrille.pitchen@atmel.com; mark.rutland@arm.com;  
> > linux-  
> > > > kernel@vger.kernel.org; linux-mtd@lists.infradead.org;
> > > > devicetree@vger.kernel.org; Michal Simek <michals@xilinx.com>;
> > > > kalluripunnaiahchoudary@gmail.com; kpc528@gmail.com; Punnaiah
> > > > Choudary Kalluri <punnaia@xilinx.com>
> > > > Subject: Re: [PATCH v7 1/2] mtd: arasan: Add device tree binding
> > > > documentation
> > > >
> > > > On Mon, Jan 09, 2017 at 08:28:53AM +0530, Punnaiah Choudary Kalluri  
> > wrote:  
> > > > > This patch adds the dts binding document for arasan nand flash
> > > > > controller.
> > > > >
> > > > > Signed-off-by: Punnaiah Choudary Kalluri <punnaia@xilinx.com>
> > > > > ---
> > > > > Changes in v7:
> > > > > - Corrected the acronyms those should be in caps
> > > > > changes in v6:
> > > > > - Removed num-cs property
> > > > > - Separated nandchip from nand controller
> > > > > changes in v5:
> > > > > - None
> > > > > Changes in v4:
> > > > > - Added num-cs property
> > > > > - Added clock support
> > > > > Changes in v3:
> > > > > - None
> > > > > Changes in v2:
> > > > > - None
> > > > > ---
> > > > >  .../devicetree/bindings/mtd/arasan_nfc.txt         | 38  
> > > > ++++++++++++++++++++++  
> > > > >  1 file changed, 38 insertions(+)
> > > > >  create mode 100644  
> > > > Documentation/devicetree/bindings/mtd/arasan_nfc.txt  
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/mtd/arasan_nfc.txt  
> > > > b/Documentation/devicetree/bindings/mtd/arasan_nfc.txt  
> > > > > new file mode 100644
> > > > > index 0000000..f20adfc
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/mtd/arasan_nfc.txt
> > > > > @@ -0,0 +1,38 @@
> > > > > +Arasan NAND Flash Controller with ONFI 3.1 support
> > > > > +
> > > > > +Required properties:
> > > > > +- compatible: Should be "arasan,nfc-v3p10"  
> > > >
> > > > Needs a note that it must also have an SoC specific compatible string.
> > > >  
> > >   Sorry, I couldn't understand this comment. Could you elaborate it?  
> > 
> > Arasan is an IP vendor, and those IPs are usually embedded in specific
> > SoCs. I guess Rob was suggesting to define something like:
> > 
> >   compatible = "<soc-vendor>,<ip-revision>", "arasan,<ip-revision>";
> > 
> > This way you can differentiate minor changes/tweaks between each SoC
> > (each SoC vendor usually enable/disable specific features based on
> > their needs).
> >   
> > >  
> > > > > +- reg: Memory map for module access
> > > > > +- interrupt-parent: Interrupt controller the interrupt is routed through
> > > > > +- interrupts: Should contain the interrupt for the device
> > > > > +- clock-name: List of input clocks - "clk_sys", "clk_flash"  
> > > >
> > > > clk_ is redundant.
> > > >  
> > >
> > >  I have defined these clock names as per the controller data sheet.
> > >  So, I feel it is fine to have them in sync with the datasheet.
> > >   Please let me know if you still want me to change this.  
> > 
> > We already know this is a clock, hence the unneeded clk_ prefix. Please
> > drop it.
> > 
> > Thanks,
> > 
> > Boris  

^ permalink raw reply

* Re: [PATCH 1/3] arm64: dts: Pine64: add MMC support
From: kbuild test robot @ 2017-01-10  9:24 UTC (permalink / raw)
  To: Andre Przywara
  Cc: kbuild-all-JC7UmRfGjtg, Maxime Ripard, Chen-Yu Tsai, Rob Herring,
	Mark Rutland, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484011353-21480-2-git-send-email-andre.przywara-5wv7dgnIgG8@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1152 bytes --]

Hi Andre,

[auto build test ERROR on mripard/sunxi/for-next]
[also build test ERROR on next-20170110]
[cannot apply to robh/for-next v4.10-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Andre-Przywara/arm64-dts-A64-board-MMC-support/20170110-124554
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git sunxi/for-next
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm64 

All errors (new ones prefixed by >>):

>> Error: arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts:83.1-6 Label or path mmc0 not found
>> FATAL ERROR: Syntax error parsing input tree

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33694 bytes --]

^ permalink raw reply

* Re: [PATCH v8 0/5] Add support for the STM32F4 I2C
From: Linus Walleij @ 2017-01-10  9:26 UTC (permalink / raw)
  To: M'boumba Cedric Madianga
  Cc: Wolfram Sang, Rob Herring, Maxime Coquelin, Alexandre TORGUE,
	Patrice CHOTARD, Russell King,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Uwe Kleine-König
In-Reply-To: <1483607246-14771-1-git-send-email-cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Thu, Jan 5, 2017 at 10:07 AM, M'boumba Cedric Madianga
<cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> This patchset adds support for the I2C controller embedded in STM32F4xx SoC.
> It enables I2C transfer in interrupt mode with Standard-mode and Fast-mode bus
> speed.

The whole series:
Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Looks perfect from my point of view now.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v5 1/2] ARM: dts: at91: add devicetree for the Axentia TSE-850
From: Alexandre Belloni @ 2017-01-10  9:29 UTC (permalink / raw)
  To: Peter Rosin
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Russell King, Nicolas Ferre, Jean-Christophe Plagniol-Villard,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484035732-31635-2-git-send-email-peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>

Hi,

This needs a commit message, please add one.

On 10/01/2017 at 09:08:51 +0100, Peter Rosin wrote :
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/arm/axentia.txt |  19 ++
>  MAINTAINERS                                       |   8 +
>  arch/arm/boot/dts/Makefile                        |   1 +
>  arch/arm/boot/dts/at91-linea.dtsi                 |  53 +++++
>  arch/arm/boot/dts/at91-tse850-3.dts               | 274 ++++++++++++++++++++++
>  5 files changed, 355 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/axentia.txt
>  create mode 100644 arch/arm/boot/dts/at91-linea.dtsi
>  create mode 100644 arch/arm/boot/dts/at91-tse850-3.dts
> 
> diff --git a/Documentation/devicetree/bindings/arm/axentia.txt b/Documentation/devicetree/bindings/arm/axentia.txt
> new file mode 100644
> index 000000000000..ea3fb96ae465
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/axentia.txt
> @@ -0,0 +1,19 @@
> +Device tree bindings for Axentia ARM devices
> +============================================
> +
> +Linea CPU module
> +----------------
> +
> +Required root node properties:
> +compatible = "axentia,linea",
> +	     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
> +and following the rules from atmel-at91.txt for a sama5d31 SoC.
> +
> +
> +TSE-850 v3 board
> +----------------
> +
> +Required root node properties:
> +compatible = "axentia,tse850v3", "axentia,linea",
> +	     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
> +and following the rules from above for the axentia,linea CPU module.
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 97b78cc5aa51..5c2ea6e9cd7f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2346,6 +2346,14 @@ S:	Maintained
>  F:	Documentation/devicetree/bindings/sound/axentia,*
>  F:	sound/soc/atmel/tse850-pcm5142.c
>  
> +AXENTIA ARM DEVICES
> +M:	Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
> +L:	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/arm/axentia.txt
> +F:	arch/arm/boot/dts/at91-linea.dtsi
> +F:	arch/arm/boot/dts/at91-tse850-3.dts
> +

I don't think you need to add yourself to MAINTAINERS for two DTs if
that is just to keep checkpatch happy, don't bother.

>  AZ6007 DVB DRIVERV
>  M:	Mauro Carvalho Chehab <mchehab-JsYNTwtnfakRB7SZvlqPiA@public.gmane.org>
>  M:	Mauro Carvalho Chehab <mchehab-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 9a7375c388a8..7632849866de 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -48,6 +48,7 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
>  	at91-kizbox2.dtb \
>  	at91-sama5d2_xplained.dtb \
>  	at91-sama5d3_xplained.dtb \
> +	at91-tse850-3.dtb \
>  	sama5d31ek.dtb \
>  	sama5d33ek.dtb \
>  	sama5d34ek.dtb \
> diff --git a/arch/arm/boot/dts/at91-linea.dtsi b/arch/arm/boot/dts/at91-linea.dtsi
> new file mode 100644
> index 000000000000..646feb0daa81
> --- /dev/null
> +++ b/arch/arm/boot/dts/at91-linea.dtsi
> @@ -0,0 +1,53 @@
> +/*
> + * at91-linea.dtsi - Device Tree Include file for the Axentia Linea Module.
> + *
> + * Copyright (C) 2017 Axentia Technologies AB
> + *
> + * Author: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
> + *
> + * Licensed under GPLv2 or later.
> + */
> +
> +#include "sama5d31.dtsi"
> +
> +/ {
> +	compatible = "axentia,linea",
> +		     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
> +
> +	memory {
> +		reg = <0x20000000 0x4000000>;
> +	};
> +};
> +
> +&slow_xtal {
> +	clock-frequency = <32768>;
> +};
> +
> +&main_xtal {
> +	clock-frequency = <12000000>;
> +};
> +
> +&main {
> +	clock-frequency = <12000000>;
> +};
> +

I don't think this is needed


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH v2 6/7] dt-bindings: media: Add Renesas R-Car DRIF binding
From: Ramesh Shanmugasundaram @ 2017-01-10  9:31 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: Geert Uytterhoeven, Rob Herring, Mark Rutland,
	Mauro Carvalho Chehab, Sakari Ailus, Antti Palosaari,
	Chris Paterson, Geert Uytterhoeven, Linux Media Mailing List,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux-Renesas
In-Reply-To: <4506041.7mPt4W6j0m@avalon>

Hi Laurent,

> > >>> On Wednesday 21 Dec 2016 08:10:37 Ramesh Shanmugasundaram wrote:
> > >>>> Add binding documentation for Renesas R-Car Digital Radio
> > >>>> Interface
> > >>>> (DRIF) controller.
> > >>>>
> > >>>> Signed-off-by: Ramesh Shanmugasundaram
> > >>>> <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> ---
> > >>>>
> > >>>>  .../devicetree/bindings/media/renesas,drif.txt     | 202
> +++++++++++++
> > >>>>  1 file changed, 202 insertions(+)  create mode 100644
> > >>>>
> > >>>> Documentation/devicetree/bindings/media/renesas,drif.txt
> > >>>>
> > >>>> diff --git
> > >>>> a/Documentation/devicetree/bindings/media/renesas,drif.txt
> > >>>> b/Documentation/devicetree/bindings/media/renesas,drif.txt new
> > >>>> file mode 100644 index 0000000..1f3feaf
> > >>>> --- /dev/null
> > >>>> +++ b/Documentation/devicetree/bindings/media/renesas,drif.txt
> > >>>>
> > >>>> +Optional properties of an internal channel when:
> > >>>> +     - It is the only enabled channel of the bond (or)
> > >>>> +     - If it acts as primary among enabled bonds
> > >>>> +--------------------------------------------------------
> > >>>> +- renesas,syncmd       : sync mode
> > >>>> +                      0 (Frame start sync pulse mode. 1-bit
> > >>>> +width
> > >>>> pulse
> > >>>> +                         indicates start of a frame)
> > >>>> +                      1 (L/R sync or I2S mode) (default)
> > >>>> +- renesas,lsb-first    : empty property indicates lsb bit is
> received
> > >>>> first.
> > >>>> +                      When not defined msb bit is received first
> > >>>> +(default)
> > >>>> +- renesas,syncac-active: Indicates sync signal polarity, 0/1 for
> > >>>> low/high
> >
> > Shouldn't this be 'renesas,sync-active' instead of syncac-active?
> >
> > I'm not sure if syncac is intended or if it is a typo.
> >
> > >>>> +                      respectively. The default is 1 (active high)
> > >>>> +- renesas,dtdl         : delay between sync signal and start of
> > >>>> reception.
> > >>>> +                      The possible values are represented in 0.5
> clock
> > >>>> +                      cycle units and the range is 0 to 4. The
> default
> > >>>> +                      value is 2 (i.e.) 1 clock cycle delay.
> > >>>> +- renesas,syncdl       : delay between end of reception and sync
> > >>>> signal edge.
> > >>>> +                      The possible values are represented in 0.5
> clock
> > >>>> +                      cycle units and the range is 0 to 4 & 6.
> > >>>> + The
> > >>>> default
> > >>>> +                      value is 0 (i.e.) no delay.
> > >>>
> > >>> Most of these properties are pretty similar to the video bus
> > >>> properties defined at the endpoint level in
> > >>> Documentation/devicetree/bindings/media/video-interfaces.txt. I
> > >>> believe it would make sense to use OF graph and try to standardize
> > >>> these properties similarly.
> >
> > Other than sync-active, is there really anything else that is similar?
> > And even the sync-active isn't a good fit since here there is only one
> > sync signal instead of two for video (h and vsync).
> 
> That's why I said similar, not identical :-) My point is that, if we
> consider that we could connect multiple sources to the DRIF, using OF
> graph would make sense, and the above properties should then be defined
> per endpoint.

Thanks for the clarifications. I have some questions.

- Assuming two devices are interfaced with DRIF and they are represented using two endpoints, the control signal related properties of DRIF might still need to be same for both endpoints? For e.g. syncac-active cannot be different in both endpoints?

- I suppose "lsb-first", "dtdl" & "syncdl" may be defined per endpoint. However, h/w manual says same register values needs to be programmed for both the internal channels of a channel. Same with "syncmd" property.

We could still define them as per endpoint property with a note that they need to be same. But I am not sure if that is what you intended?

 If we define them per endpoint we should then also try
> standardize the ones that are not really Renesas-specific (that's at least
> syncac-active).

OK. I will call it "sync-active".

 For the syncmd and lsb-first properties, it could also
> make sense to query them from the connected subdev at runtime, as they're
> similar in purpose to formats and media bus configuration (struct
> v4l2_mbus_config).

May I know in bit more detail about what you had in mind? Please correct me if my understanding is wrong here but when I looked at the code

1) mbus_config is part of subdev_video_ops only. I assume we don't want to support this as part of tuner subdev. The next closest is pad_ops with "struct v4l2_mbus_framefmt" but it is fully video specific config unless I come up with new MEDIA_BUS_FMT_xxxx in media-bus-format.h and use the code field? For e.g.
	
#define MEDIA_BUS_FMT_SDR_I2S_PADHI_BE       0x7001
#define MEDIA_BUS_FMT_SDR_I2S_PADHI_LE       0x7002

2) The framework does not seem to mandate pad ops for all subdev. As the tuner can be any third party subdev, is it fair to assume that these properties can be queried from subdev?

3) Assuming pad ops is not available on the subdev shouldn't we still need a way to define these properties on DRIF DT?

> 
> I'm not an SDR expert, so I'd like to have your opinion on this.
> 
> > >> Note that the last two properties match the those in
> > >> Documentation/devicetree/bindings/spi/sh-msiof.txt.
> > >> We may want to use one DRIF channel as a plain SPI slave with the
> > >> (modified) MSIOF driver in the future.
> > >
> > > Should I leave it as it is or modify these as in video-interfaces.txt?
> > > Shall we conclude on this please?
> 

Thanks,
Ramesh

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 08/11] dmaengine: cppi41: Implement the glue for da8xx
From: Alexandre Bailon @ 2017-01-10  9:38 UTC (permalink / raw)
  To: Grygorii Strashko, vinod.koul-ral2JQCrhuEAvxtiuMwx3w
  Cc: dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, nsekhar-l0cyMroinI0,
	khilman-rdvid1DuHRBWk0Htik3J/w, ptitiano-rdvid1DuHRBWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	b-liu-l0cyMroinI0
In-Reply-To: <fbc7f9f3-9b14-bc7f-0b40-15a6fedd48ea-l0cyMroinI0@public.gmane.org>

On 01/09/2017 07:08 PM, Grygorii Strashko wrote:
> 
> 
> On 01/09/2017 10:06 AM, Alexandre Bailon wrote:
>> The da8xx has a cppi41 dma controller.
>> This is add the glue layer required to make it work on da8xx,
>> as well some changes in driver (e.g to manage clock).
>>
>> Signed-off-by: Alexandre Bailon <abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>> ---
>>  drivers/dma/cppi41.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 95 insertions(+)
>>
>> diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
>> index 939398e..4318e53 100644
>> --- a/drivers/dma/cppi41.c
>> +++ b/drivers/dma/cppi41.c
>> @@ -1,3 +1,4 @@
>> +#include <linux/clk.h>
>>  #include <linux/delay.h>
>>  #include <linux/dmaengine.h>
>>  #include <linux/dma-mapping.h>
>> @@ -86,10 +87,19 @@
>>  
>>  #define USBSS_IRQ_PD_COMP	(1 <<  2)
>>  
>> +/* USB DA8XX */
>> +#define DA8XX_INTR_SRC_MASKED	0x38
>> +#define DA8XX_END_OF_INTR	0x3c
>> +
>> +#define DA8XX_QMGR_PENDING_MASK	(0xf << 24)
>> +
>> +
>> +
>>  /* Packet Descriptor */
>>  #define PD2_ZERO_LENGTH		(1 << 19)
>>  
>>  #define AM335X_CPPI41		0
>> +#define DA8XX_CPPI41		1
>>  
>>  struct cppi41_channel {
>>  	struct dma_chan chan;
>> @@ -158,6 +168,9 @@ struct cppi41_dd {
>>  
>>  	/* context for suspend/resume */
>>  	unsigned int dma_tdfdq;
>> +
>> +	/* da8xx clock */
>> +	struct clk *clk;
>>  };
>>  
>>  static struct chan_queues am335x_usb_queues_tx[] = {
>> @@ -232,6 +245,20 @@ static const struct chan_queues am335x_usb_queues_rx[] = {
>>  	[29] = { .submit = 30, .complete = 155},
>>  };
>>  
>> +static const struct chan_queues da8xx_usb_queues_tx[] = {
>> +	[0] = { .submit =  16, .complete = 24},
>> +	[1] = { .submit =  18, .complete = 24},
>> +	[2] = { .submit =  20, .complete = 24},
>> +	[3] = { .submit =  22, .complete = 24},
>> +};
>> +
>> +static const struct chan_queues da8xx_usb_queues_rx[] = {
>> +	[0] = { .submit =  1, .complete = 26},
>> +	[1] = { .submit =  3, .complete = 26},
>> +	[2] = { .submit =  5, .complete = 26},
>> +	[3] = { .submit =  7, .complete = 26},
>> +};
>> +
>>  struct cppi_glue_infos {
>>  	irqreturn_t (*isr)(int irq, void *data);
>>  	const struct chan_queues *queues_rx;
>> @@ -366,6 +393,26 @@ static irqreturn_t am335x_cppi41_irq(int irq, void *data)
>>  	return cppi41_irq(cdd);
>>  }
>>  
>> +static irqreturn_t da8xx_cppi41_irq(int irq, void *data)
>> +{
>> +	struct cppi41_dd *cdd = data;
>> +	u32 status;
>> +	u32 usbss_status;
>> +
>> +	status = cppi_readl(cdd->qmgr_mem + QMGR_PEND(0));
>> +	if (status & DA8XX_QMGR_PENDING_MASK)
>> +		cppi41_irq(cdd);
>> +	else
>> +		return IRQ_NONE;
>> +
>> +	/* Re-assert IRQ if there no usb core interrupts pending */
>> +	usbss_status = cppi_readl(cdd->usbss_mem + DA8XX_INTR_SRC_MASKED);
>> +	if (!usbss_status)
>> +		cppi_writel(0, cdd->usbss_mem + DA8XX_END_OF_INTR);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>>  static dma_cookie_t cppi41_tx_submit(struct dma_async_tx_descriptor *tx)
>>  {
>>  	dma_cookie_t cookie;
>> @@ -972,8 +1019,19 @@ static const struct cppi_glue_infos am335x_usb_infos = {
>>  	.platform = AM335X_CPPI41,
>>  };
>>  
>> +static const struct cppi_glue_infos da8xx_usb_infos = {
>> +	.isr = da8xx_cppi41_irq,
>> +	.queues_rx = da8xx_usb_queues_rx,
>> +	.queues_tx = da8xx_usb_queues_tx,
>> +	.td_queue = { .submit = 31, .complete = 0 },
>> +	.first_completion_queue = 24,
>> +	.qmgr_num_pend = 2,
>> +	.platform = DA8XX_CPPI41,
>> +};
>> +
>>  static const struct of_device_id cppi41_dma_ids[] = {
>>  	{ .compatible = "ti,am3359-cppi41", .data = &am335x_usb_infos},
>> +	{ .compatible = "ti,da8xx-cppi41", .data = &da8xx_usb_infos},
>>  	{},
>>  };
>>  MODULE_DEVICE_TABLE(of, cppi41_dma_ids);
>> @@ -995,6 +1053,13 @@ static int is_am335x_cppi41(struct device *dev)
>>  	return cdd->platform == AM335X_CPPI41;
>>  }
>>  
>> +static int is_da8xx_cppi41(struct device *dev)
>> +{
>> +	struct cppi41_dd *cdd = dev_get_drvdata(dev);
>> +
>> +	return cdd->platform == DA8XX_CPPI41;
>> +}
>> +
>>  #define CPPI41_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
>>  				BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
>>  				BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
>> @@ -1058,6 +1123,21 @@ static int cppi41_dma_probe(struct platform_device *pdev)
>>  	cdd->first_completion_queue = glue_info->first_completion_queue;
>>  	cdd->platform = glue_info->platform;
>>  
>> +	if (is_da8xx_cppi41(dev)) {
>> +		cdd->clk = devm_clk_get(&pdev->dev, "usb20");
>> +		ret = PTR_ERR_OR_ZERO(cdd->clk);
>> +		if (ret) {
>> +			dev_err(&pdev->dev, "failed to get clock\n");
>> +			goto err_clk_en;
>> +		}
>> +
>> +		ret = clk_prepare_enable(cdd->clk);
>> +		if (ret) {
>> +			dev_err(dev, "failed to enable clock\n");
>> +			goto err_clk_en;
>> +		}
>> +	}
> 
> if this is functional clock then why not to use ./arch/arm/mach-davinci/pm_domain.c ?
> wouldn't it work for use if you will just rename "usb20" -> "fck" -
> so PM runtime should manage this clock for you?
As is, I don't think it will work.
The usb20 is shared by the cppi41 and the usb otg.
So, if we rename "usb20" to "fck", clk_get() won't be able to find the
clock.
But may be adding "usb20" to "con_ids" in
arch/arm/mach-davinci/pm_domain.c could work.
But I think it will require some changes in da8xx musb driver.
I will take look.

Thanks,
Alexandre
> 
>> +
>>  	ret = of_property_read_u32(dev->of_node,
>>  				   "#dma-channels", &cdd->n_chans);
>>  	if (ret)
>> @@ -1112,6 +1192,9 @@ static int cppi41_dma_probe(struct platform_device *pdev)
>>  err_init_cppi:
>>  	pm_runtime_dont_use_autosuspend(dev);
>>  err_get_n_chans:
>> +	if (is_da8xx_cppi41(dev))
>> +		clk_disable_unprepare(cdd->clk);
>> +err_clk_en:
>>  err_get_sync:
>>  	pm_runtime_put_sync(dev);
>>  	pm_runtime_disable(dev);
>> @@ -1146,6 +1229,8 @@ static int cppi41_dma_remove(struct platform_device *pdev)
>>  	pm_runtime_dont_use_autosuspend(&pdev->dev);
>>  	pm_runtime_put_sync(&pdev->dev);
>>  	pm_runtime_disable(&pdev->dev);
>> +	if (is_da8xx_cppi41(&pdev->dev))
>> +		clk_disable_unprepare(cdd->clk);
>>  	return 0;
>>  }
>>  
>> @@ -1158,6 +1243,9 @@ static int __maybe_unused cppi41_suspend(struct device *dev)
>>  		cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR);
>>  	disable_sched(cdd);
>>  
>> +	if (is_da8xx_cppi41(dev))
>> +		clk_disable_unprepare(cdd->clk);
>> +
>>  	return 0;
>>  }
>>  
>> @@ -1165,8 +1253,15 @@ static int __maybe_unused cppi41_resume(struct device *dev)
>>  {
>>  	struct cppi41_dd *cdd = dev_get_drvdata(dev);
>>  	struct cppi41_channel *c;
>> +	int ret;
>>  	int i;
>>  
>> +	if (is_da8xx_cppi41(dev)) {
>> +		ret = clk_prepare_enable(cdd->clk);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>>  	for (i = 0; i < DESCS_AREAS; i++)
>>  		cppi_writel(cdd->descs_phys, cdd->qmgr_mem + QMGR_MEMBASE(i));
>>  
>>
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 0/4] ARM: dts: mt7623: Add initial Geek Force support
From: Andreas Färber @ 2017-01-10  9:48 UTC (permalink / raw)
  To: John Crispin, linux-mediatek
  Cc: devicetree, Paul Lai, linux-kernel, Matthias Brugger,
	linux-arm-kernel
In-Reply-To: <91f5ec74-1aa1-f2ad-24e9-14267cbe8498@phrozen.org>

Hi,

Am 10.01.2017 um 08:00 schrieb John Crispin:
> On 08/01/2017 14:30, Andreas Färber wrote:
>>
>> Andreas Färber (4):
>>   Documentation: devicetree: Add vendor prefix for AsiaRF
>>   Documentation: devicetree: arm: mediatek: Add Geek Force board
>>   ARM: dts: mt7623: Add Geek Force config
>>   MAINTAINERS: Extend ARM/Mediatek SoC support section
>>
> 
> Hi,
> 
> i need to NAK this series. the asiarf board is nothing more than the
> official MTK EVB with AsiaRF written on it. this board is already
> supported by linux (arch/arm/boot/dts/mt7623-evb.dts) please extend the
> EVB dts file nstead of adding a duplicate and letting the original bitrot.

Well, I disagree.

First of all I'm not letting "the original" bitrot, because I have
nothing to do with that .dts! If anyone is to blame for letting it
bitrot since February 2016, pick your own nose:

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/log/arch/arm/boot/dts/mt7623-evb.dts

Second, I have no Mediatek documentation or even picture to identify any
similarities between my board and that Mediatek EVB, so no, I can't hack
on the -evb.dts file. I wrote my .dts from scratch, not even having
access to /proc/device-tree on its 3.10 kernel for comparison.

Third, by your argumentation we shouldn't be adding, e.g., Odroid .dts
files either because they were based on a Samsung SMDK, or .dts files
for Amlogic TV boxes because they're almost identical to reference
designs, etc.
Users need to know which .dts file to choose, so having a sane .dts
filename is warranted. Depending on how similar they are, one could
either #include the -evb.dts or factor out a shared .dtsi, but that
takes us back to the previous point of hardly anyone having access to
EVB information to identify such a subset. Therefore duplicating trivial
nodes is the method of choice for all practical purposes - mt7623.dtsi
is getting reused just fine.

Comparing our two .dts files, mine has two more UART nodes enabled, the
U-Boot bootloader's baudrate set to actually get serial output, a
different board compatible string for identification, and I chose the
new dual-licensing header that is being requested for new DT files.

For lack of schematics I figured out UART1 by testing - continuity tests
for GND, console=ttySx,115200n8 and trial-and-error for RX/TX. Obviously
I can't do that for a board I don't have access to.
UART2 and UART0 pins were clear, but only UART2 was obvious from ttyMT2.

Do you actually have access to a Geek Force board yourself, or what are
you basing your claims on? Mine looks different from the Indiegogo
picture and thus has different identification from that on
https://wikidevi.com/wiki/AsiaRF_WS2977 (WS3301, MT7623N RFB_V10).

If you confirm the EVB's baudrate I can happily send that part your way.
I've seen 921600 on the Helio X20 96board for instance.

Also, none of what you've said justifies NAK'ing patch 4/4, which
applies to any mt7* and arm64 .dts, including yours.

While we're at it, I noticed that mainline has a "mediatek,mt7623-eth"
network driver but no corresponding .dtsi node. Talk about bitrot...

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply

* Re: [PATCH v5 1/2] ARM: dts: at91: add devicetree for the Axentia TSE-850
From: Peter Rosin @ 2017-01-10  9:52 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Russell King, Nicolas Ferre, Jean-Christophe Plagniol-Villard,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170110092928.hwd4l4k3eyagepco-m++hUPXGwpdeoWH0uzbU5w@public.gmane.org>

On 2017-01-10 10:29, Alexandre Belloni wrote:
> Hi,
> 
> This needs a commit message, please add one.

There's not all that much to say, but ok, I'll add something.

> On 10/01/2017 at 09:08:51 +0100, Peter Rosin wrote :
>> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/arm/axentia.txt |  19 ++
>>  MAINTAINERS                                       |   8 +
>>  arch/arm/boot/dts/Makefile                        |   1 +
>>  arch/arm/boot/dts/at91-linea.dtsi                 |  53 +++++
>>  arch/arm/boot/dts/at91-tse850-3.dts               | 274 ++++++++++++++++++++++
>>  5 files changed, 355 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/arm/axentia.txt
>>  create mode 100644 arch/arm/boot/dts/at91-linea.dtsi
>>  create mode 100644 arch/arm/boot/dts/at91-tse850-3.dts
>>
>> diff --git a/Documentation/devicetree/bindings/arm/axentia.txt b/Documentation/devicetree/bindings/arm/axentia.txt
>> new file mode 100644
>> index 000000000000..ea3fb96ae465
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/axentia.txt
>> @@ -0,0 +1,19 @@
>> +Device tree bindings for Axentia ARM devices
>> +============================================
>> +
>> +Linea CPU module
>> +----------------
>> +
>> +Required root node properties:
>> +compatible = "axentia,linea",
>> +	     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
>> +and following the rules from atmel-at91.txt for a sama5d31 SoC.
>> +
>> +
>> +TSE-850 v3 board
>> +----------------
>> +
>> +Required root node properties:
>> +compatible = "axentia,tse850v3", "axentia,linea",
>> +	     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
>> +and following the rules from above for the axentia,linea CPU module.
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 97b78cc5aa51..5c2ea6e9cd7f 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2346,6 +2346,14 @@ S:	Maintained
>>  F:	Documentation/devicetree/bindings/sound/axentia,*
>>  F:	sound/soc/atmel/tse850-pcm5142.c
>>  
>> +AXENTIA ARM DEVICES
>> +M:	Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
>> +L:	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
>> +S:	Maintained
>> +F:	Documentation/devicetree/bindings/arm/axentia.txt
>> +F:	arch/arm/boot/dts/at91-linea.dtsi
>> +F:	arch/arm/boot/dts/at91-tse850-3.dts
>> +
> 
> I don't think you need to add yourself to MAINTAINERS for two DTs if
> that is just to keep checkpatch happy, don't bother.

There's also the benefit of the increased chances of me getting
notified of changes. I don't mind...

>>  AZ6007 DVB DRIVERV
>>  M:	Mauro Carvalho Chehab <mchehab-JsYNTwtnfakRB7SZvlqPiA@public.gmane.org>
>>  M:	Mauro Carvalho Chehab <mchehab-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index 9a7375c388a8..7632849866de 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -48,6 +48,7 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
>>  	at91-kizbox2.dtb \
>>  	at91-sama5d2_xplained.dtb \
>>  	at91-sama5d3_xplained.dtb \
>> +	at91-tse850-3.dtb \
>>  	sama5d31ek.dtb \
>>  	sama5d33ek.dtb \
>>  	sama5d34ek.dtb \
>> diff --git a/arch/arm/boot/dts/at91-linea.dtsi b/arch/arm/boot/dts/at91-linea.dtsi
>> new file mode 100644
>> index 000000000000..646feb0daa81
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/at91-linea.dtsi
>> @@ -0,0 +1,53 @@
>> +/*
>> + * at91-linea.dtsi - Device Tree Include file for the Axentia Linea Module.
>> + *
>> + * Copyright (C) 2017 Axentia Technologies AB
>> + *
>> + * Author: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +
>> +#include "sama5d31.dtsi"
>> +
>> +/ {
>> +	compatible = "axentia,linea",
>> +		     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
>> +
>> +	memory {
>> +		reg = <0x20000000 0x4000000>;
>> +	};
>> +};
>> +
>> +&slow_xtal {
>> +	clock-frequency = <32768>;
>> +};
>> +
>> +&main_xtal {
>> +	clock-frequency = <12000000>;
>> +};
>> +
>> +&main {
>> +	clock-frequency = <12000000>;
>> +};
>> +
> 
> I don't think this is needed
> 
> 

"this"? The &main frequency, or all of them?

Cheers,
peda

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 08/11] dmaengine: cppi41: Implement the glue for da8xx
From: Sekhar Nori @ 2017-01-10 10:05 UTC (permalink / raw)
  To: Alexandre Bailon, Grygorii Strashko,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w
  Cc: dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, khilman-rdvid1DuHRBWk0Htik3J/w,
	ptitiano-rdvid1DuHRBWk0Htik3J/w, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	b-liu-l0cyMroinI0
In-Reply-To: <b3f902e0-ed08-dbee-52b8-e81afda082ac-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

On Tuesday 10 January 2017 03:08 PM, Alexandre Bailon wrote:
> On 01/09/2017 07:08 PM, Grygorii Strashko wrote:
>>
>>
>> On 01/09/2017 10:06 AM, Alexandre Bailon wrote:
>>> The da8xx has a cppi41 dma controller.
>>> This is add the glue layer required to make it work on da8xx,
>>> as well some changes in driver (e.g to manage clock).
>>>
>>> Signed-off-by: Alexandre Bailon <abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>>> ---
>>>  drivers/dma/cppi41.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 95 insertions(+)
>>>
>>> diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
>>> index 939398e..4318e53 100644
>>> --- a/drivers/dma/cppi41.c
>>> +++ b/drivers/dma/cppi41.c
>>> @@ -1,3 +1,4 @@
>>> +#include <linux/clk.h>
>>>  #include <linux/delay.h>
>>>  #include <linux/dmaengine.h>
>>>  #include <linux/dma-mapping.h>
>>> @@ -86,10 +87,19 @@
>>>  
>>>  #define USBSS_IRQ_PD_COMP	(1 <<  2)
>>>  
>>> +/* USB DA8XX */
>>> +#define DA8XX_INTR_SRC_MASKED	0x38
>>> +#define DA8XX_END_OF_INTR	0x3c
>>> +
>>> +#define DA8XX_QMGR_PENDING_MASK	(0xf << 24)
>>> +
>>> +
>>> +
>>>  /* Packet Descriptor */
>>>  #define PD2_ZERO_LENGTH		(1 << 19)
>>>  
>>>  #define AM335X_CPPI41		0
>>> +#define DA8XX_CPPI41		1
>>>  
>>>  struct cppi41_channel {
>>>  	struct dma_chan chan;
>>> @@ -158,6 +168,9 @@ struct cppi41_dd {
>>>  
>>>  	/* context for suspend/resume */
>>>  	unsigned int dma_tdfdq;
>>> +
>>> +	/* da8xx clock */
>>> +	struct clk *clk;
>>>  };
>>>  
>>>  static struct chan_queues am335x_usb_queues_tx[] = {
>>> @@ -232,6 +245,20 @@ static const struct chan_queues am335x_usb_queues_rx[] = {
>>>  	[29] = { .submit = 30, .complete = 155},
>>>  };
>>>  
>>> +static const struct chan_queues da8xx_usb_queues_tx[] = {
>>> +	[0] = { .submit =  16, .complete = 24},
>>> +	[1] = { .submit =  18, .complete = 24},
>>> +	[2] = { .submit =  20, .complete = 24},
>>> +	[3] = { .submit =  22, .complete = 24},
>>> +};
>>> +
>>> +static const struct chan_queues da8xx_usb_queues_rx[] = {
>>> +	[0] = { .submit =  1, .complete = 26},
>>> +	[1] = { .submit =  3, .complete = 26},
>>> +	[2] = { .submit =  5, .complete = 26},
>>> +	[3] = { .submit =  7, .complete = 26},
>>> +};
>>> +
>>>  struct cppi_glue_infos {
>>>  	irqreturn_t (*isr)(int irq, void *data);
>>>  	const struct chan_queues *queues_rx;
>>> @@ -366,6 +393,26 @@ static irqreturn_t am335x_cppi41_irq(int irq, void *data)
>>>  	return cppi41_irq(cdd);
>>>  }
>>>  
>>> +static irqreturn_t da8xx_cppi41_irq(int irq, void *data)
>>> +{
>>> +	struct cppi41_dd *cdd = data;
>>> +	u32 status;
>>> +	u32 usbss_status;
>>> +
>>> +	status = cppi_readl(cdd->qmgr_mem + QMGR_PEND(0));
>>> +	if (status & DA8XX_QMGR_PENDING_MASK)
>>> +		cppi41_irq(cdd);
>>> +	else
>>> +		return IRQ_NONE;
>>> +
>>> +	/* Re-assert IRQ if there no usb core interrupts pending */
>>> +	usbss_status = cppi_readl(cdd->usbss_mem + DA8XX_INTR_SRC_MASKED);
>>> +	if (!usbss_status)
>>> +		cppi_writel(0, cdd->usbss_mem + DA8XX_END_OF_INTR);
>>> +
>>> +	return IRQ_HANDLED;
>>> +}
>>> +
>>>  static dma_cookie_t cppi41_tx_submit(struct dma_async_tx_descriptor *tx)
>>>  {
>>>  	dma_cookie_t cookie;
>>> @@ -972,8 +1019,19 @@ static const struct cppi_glue_infos am335x_usb_infos = {
>>>  	.platform = AM335X_CPPI41,
>>>  };
>>>  
>>> +static const struct cppi_glue_infos da8xx_usb_infos = {
>>> +	.isr = da8xx_cppi41_irq,
>>> +	.queues_rx = da8xx_usb_queues_rx,
>>> +	.queues_tx = da8xx_usb_queues_tx,
>>> +	.td_queue = { .submit = 31, .complete = 0 },
>>> +	.first_completion_queue = 24,
>>> +	.qmgr_num_pend = 2,
>>> +	.platform = DA8XX_CPPI41,
>>> +};
>>> +
>>>  static const struct of_device_id cppi41_dma_ids[] = {
>>>  	{ .compatible = "ti,am3359-cppi41", .data = &am335x_usb_infos},
>>> +	{ .compatible = "ti,da8xx-cppi41", .data = &da8xx_usb_infos},
>>>  	{},
>>>  };
>>>  MODULE_DEVICE_TABLE(of, cppi41_dma_ids);
>>> @@ -995,6 +1053,13 @@ static int is_am335x_cppi41(struct device *dev)
>>>  	return cdd->platform == AM335X_CPPI41;
>>>  }
>>>  
>>> +static int is_da8xx_cppi41(struct device *dev)
>>> +{
>>> +	struct cppi41_dd *cdd = dev_get_drvdata(dev);
>>> +
>>> +	return cdd->platform == DA8XX_CPPI41;
>>> +}
>>> +
>>>  #define CPPI41_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
>>>  				BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
>>>  				BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
>>> @@ -1058,6 +1123,21 @@ static int cppi41_dma_probe(struct platform_device *pdev)
>>>  	cdd->first_completion_queue = glue_info->first_completion_queue;
>>>  	cdd->platform = glue_info->platform;
>>>  
>>> +	if (is_da8xx_cppi41(dev)) {
>>> +		cdd->clk = devm_clk_get(&pdev->dev, "usb20");
>>> +		ret = PTR_ERR_OR_ZERO(cdd->clk);
>>> +		if (ret) {
>>> +			dev_err(&pdev->dev, "failed to get clock\n");
>>> +			goto err_clk_en;
>>> +		}
>>> +
>>> +		ret = clk_prepare_enable(cdd->clk);
>>> +		if (ret) {
>>> +			dev_err(dev, "failed to enable clock\n");
>>> +			goto err_clk_en;
>>> +		}
>>> +	}
>>
>> if this is functional clock then why not to use ./arch/arm/mach-davinci/pm_domain.c ?
>> wouldn't it work for use if you will just rename "usb20" -> "fck" -
>> so PM runtime should manage this clock for you?
> As is, I don't think it will work.
> The usb20 is shared by the cppi41 and the usb otg.
> So, if we rename "usb20" to "fck", clk_get() won't be able to find the
> clock.
> But may be adding "usb20" to "con_ids" in
> arch/arm/mach-davinci/pm_domain.c could work.
> But I think it will require some changes in da8xx musb driver.
> I will take look.

On DA8xx, CPPI 4.1 DMAengine is not an independent system resource, but
embedded within the USB 2.0 controller. So, I think all that is needed
is for MUSB DA8xx glue to trigger probe of CPPI 4.1 dmaengine driver
when it is ready. I am not sure all this DA850-specific clock handling
is really necessary.

Even in DT, the CPPI 4.1 node should be a child node of USB 2.0 node.

Thanks,
sekhar
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 1/9] clk: stm32f4: Update DT bindings documentation
From: Alexandre Torgue @ 2017-01-10 10:08 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Mark Rutland, devicetree@vger.kernel.org,
	daniel.thompson@linaro.org, radoslaw.pietrzyk@gmail.com,
	kernel@stlinux.com, Arnd Bergmann, Nicolas Pitre,
	andrea.merello@gmail.com, Michael Turquette, Olivier BIDEAU,
	linux-clk@vger.kernel.org, Russell King,
	linux-kernel@vger.kernel.org, Rob Herring, Ludovic BARRE,
	Maxime Coquelin, Amelie DELAUNAY, Gabriel FERNANDEZ,
	"linux-arm-kernel@lists.infradead.org" <linux-arm-kern>
In-Reply-To: <20170109193312.GN17126@codeaurora.org>



On 01/09/2017 08:33 PM, Stephen Boyd wrote:
> On 01/09, Alexandre Torgue wrote:
>> Hi Stephen,
>>
>> On 12/22/2016 01:10 AM, Stephen Boyd wrote:
>>> On 12/13, gabriel.fernandez@st.com wrote:
>>>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>>>
>>>> Creation of dt include file for specific stm32f4 clocks.
>>>> These specific clocks are not derived from system clock (SYSCLOCK)
>>>> We should use index 1 to use these clocks in DT.
>>>> e.g. <&rcc 1 CLK_LSI>
>>>>
>>>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>>>> Acked-by: Rob Herring <robh@kernel.org>
>>>> ---
>>>
>>> Applied to clk-stm32f4 and merged into clk-next.
>>>
>>
>> I'm preparing pull request branch for STM32 DT part. This patch is
>> also requested to build correctly DT patches. Do you know how could
>> we synchronize our pull request ?
>>
>
> clk-stm32f4 is stable and not going to be rebased, so you're good
> to base patches on it and send it off to arm-soc if the arm-soc
> maintainers agree to it. You can also base off an earlier part of
> the branch if you only need this first patch for example.
>
I will base my DT branch from 4.10-rc1 + this commit (seen with Arnd)

Thanks

^ permalink raw reply

* Re: [PATCH 4/4] usb: musb: musb_cppi41: Workaround dma stall issue during teardown
From: Alexandre Bailon @ 2017-01-10 10:12 UTC (permalink / raw)
  To: Sergei Shtylyov, b-liu-l0cyMroinI0
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, nsekhar-l0cyMroinI0,
	khilman-rdvid1DuHRBWk0Htik3J/w, ptitiano-rdvid1DuHRBWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	david-nq/r/kbU++upp/zk7JDF2g
In-Reply-To: <511a1b59-82d8-4f29-98ce-273e3cc65797-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>

On 01/09/2017 07:34 PM, Sergei Shtylyov wrote:
> Hello!
> 
> On 01/09/2017 07:39 PM, Alexandre Bailon wrote:
> 
>> The dma may hung up if a teardown is initiated while an endpoint is still
> 
>    The DMA may hang up...
> 
>> active (Advisory 2.3.27 of da8xx errata).
>> To workaround this issue, add a delay before to initiate the teardown.
>>
>> Signed-off-by: Alexandre Bailon <abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> [...]
>> diff --git a/drivers/usb/musb/musb_cppi41.c
>> b/drivers/usb/musb/musb_cppi41.c
>> index 1636385..8fdbc17 100644
>> --- a/drivers/usb/musb/musb_cppi41.c
>> +++ b/drivers/usb/musb/musb_cppi41.c
>> @@ -547,6 +547,10 @@ static int cppi41_dma_channel_abort(struct
>> dma_channel *channel)
>>          }
>>      }
>>
>> +    /* DA8xx Advisory 2.3.27: wait 250 ms before to start the
>> teardown */
>> +    if (musb->io.quirks & MUSB_DA8XX)
>> +        mdelay(250);
> 
>    This is a horrible workaround, not even msleep()...
Indeed, that's a bad workaround but have not found a better one.
cppi41_dma_channel_abort() is called from atomic context,
so we can't use msleep().
And update the musb driver to call cppi41_dma_channel_abort()
from process context would require too many changes.

Best Regards,
Alexandre
> 
> [...]
> 
> MBR, Sergei
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 3/4] ARM: dts: stm32: stm32f7: Enable clocks for STM32F746 boards
From: Alexandre Torgue @ 2017-01-10 10:14 UTC (permalink / raw)
  To: gabriel.fernandez, Rob Herring, Mark Rutland, Russell King,
	Maxime Coquelin, Michael Turquette, Stephen Boyd, Nicolas Pitre,
	Arnd Bergmann, daniel.thompson, andrea.merello, radoslaw.pietrzyk
  Cc: devicetree, amelie.delaunay, kernel, olivier.bideau, linux-kernel,
	linux-arm-kernel, linux-clk, ludovic.barre
In-Reply-To: <1483711165-17149-4-git-send-email-gabriel.fernandez@st.com>

Hi Gabriel

On 01/06/2017 02:59 PM, gabriel.fernandez@st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch enables clocks for STM32F746 boards.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---

In commit header, "stm32f7" is not usefull.


>  arch/arm/boot/dts/stm32f746.dtsi | 29 +++++++++++++++++++++++++++--
>  1 file changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
> index f321ffe..e05e131 100644
> --- a/arch/arm/boot/dts/stm32f746.dtsi
> +++ b/arch/arm/boot/dts/stm32f746.dtsi
> @@ -43,6 +43,7 @@
>  #include "skeleton.dtsi"
>  #include "armv7-m.dtsi"
>  #include <dt-bindings/pinctrl/stm32f746-pinfunc.h>
> +#include <dt-bindings/clock/stm32fx-clock.h>

This patch depends on another series not yet merged (maybe "[PATCH-next 
... is a better header ?

>
>  / {
>  	clocks {
> @@ -51,6 +52,24 @@
>  			compatible = "fixed-clock";
>  			clock-frequency = <0>;
>  		};
> +
> +		clk-lse {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <32768>;
> +		};
> +
> +		clk-lsi {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <32000>;
> +		};
> +
> +		clk_i2s_ckin: clk-i2s-ckin {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <48000000>;
> +		};
>  	};
>
>  	soc {
> @@ -178,6 +197,11 @@
>  			interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
>  		};
>
> +		pwrcfg: power-config@40007000 {
> +			compatible = "syscon";
> +			reg = <0x40007000 0x400>;
> +		};
> +
>  		pin-controller {
>  			#address-cells = <1>;
>  			#size-cells = <1>;
> @@ -291,9 +315,10 @@
>
>  		rcc: rcc@40023800 {
>  			#clock-cells = <2>;
> -			compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
> +			compatible = "st,stm32f746-rcc", "st,stm32-rcc";
>  			reg = <0x40023800 0x400>;
> -			clocks = <&clk_hse>;
> +			clocks = <&clk_hse>, <&clk_i2s_ckin>;
> +			st,syscfg = <&pwrcfg>;
>  		};
>  	};
>  };
>

^ permalink raw reply

* Re: [PATCH 0/4] ARM: dts: mt7623: Add initial Geek Force support
From: John Crispin @ 2017-01-10 10:18 UTC (permalink / raw)
  To: Andreas Färber,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Matthias Brugger, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Paul Lai,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <d6bd3783-d124-9871-d3b4-93e366517895-l3A5Bk7waGM@public.gmane.org>

(resend, hit the wrong reply button)

On 10/01/2017 10:48, Andreas Färber wrote:
> Hi,
>
> Am 10.01.2017 um 08:00 schrieb John Crispin:
>> On 08/01/2017 14:30, Andreas Färber wrote:
>>>
>>> Andreas Färber (4):
>>>   Documentation: devicetree: Add vendor prefix for AsiaRF
>>>   Documentation: devicetree: arm: mediatek: Add Geek Force board
>>>   ARM: dts: mt7623: Add Geek Force config
>>>   MAINTAINERS: Extend ARM/Mediatek SoC support section
>>>
>>
>> Hi,
>>
>> i need to NAK this series. the asiarf board is nothing more than the
>> official MTK EVB with AsiaRF written on it. this board is already
>> supported by linux (arch/arm/boot/dts/mt7623-evb.dts) please extend the
>> EVB dts file nstead of adding a duplicate and letting the original
bitrot.
>
> Well, I disagree.

reading the rest of the email you seem to be quite agro about this.

>
> First of all I'm not letting "the original" bitrot, because I have
> nothing to do with that .dts! If anyone is to blame for letting it
> bitrot since February 2016, pick your own nose:
>
>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/log/arch/arm/boot/dts/mt7623-evb.dts

what should i pick my nose about ? i made mt7623 work, then waited for
4.10-rc1 to be out for clk-mt2701 so that i can continue adding the
missing support


> Second, I have no Mediatek documentation or even picture to identify any
> similarities between my board and that Mediatek EVB, so no, I can't hack
> on the -evb.dts file. I wrote my .dts from scratch, not even having
> access to /proc/device-tree on its 3.10 kernel for comparison.

ok, that info is most likely under NDA

>
> Third, by your argumentation we shouldn't be adding, e.g., Odroid .dts
> files either because they were based on a Samsung SMDK, or .dts files
> for Amlogic TV boxes because they're almost identical to reference
> designs, etc.
> Users need to know which .dts file to choose, so having a sane .dts
> filename is warranted. Depending on how similar they are, one could
> either #include the -evb.dts or factor out a shared .dtsi, but that
> takes us back to the previous point of hardly anyone having access to
> EVB information to identify such a subset. Therefore duplicating trivial
> nodes is the method of choice for all practical purposes - mt7623.dtsi
> is getting reused just fine.
>

in that case add a dtsi file for the EVB and include it in your geek
board.dts and only update the compat string.

> Comparing our two .dts files, mine has two more UART nodes enabled, the
> U-Boot bootloader's baudrate set to actually get serial output, a
> different board compatible string for identification, and I chose the
> new dual-licensing header that is being requested for new DT files.

1) at the time we adde this the uart support was not ready
2) the bootloader i am using is a custom built one hence the random baudrate
3) you can just updae the license if you want to, no problem

> For lack of schematics I figured out UART1 by testing - continuity tests
> for GND, console=ttySx,115200n8 and trial-and-error for RX/TX. Obviously
> I can't do that for a board I don't have access to.
> UART2 and UART0 pins were clear, but only UART2 was obvious from ttyMT2.

you do have the EVB directly in front of you

> Do you actually have access to a Geek Force board yourself, or what are
> you basing your claims on? Mine looks different from the Indiegogo
> picture and thus has different identification from that on
> https://wikidevi.com/wiki/AsiaRF_WS2977 (WS3301, MT7623N RFB_V10).

i dont need the geek board as i have the EVB and they are identical
according to MTK

> If you confirm the EVB's baudrate I can happily send that part your way.
> I've seen 921600 on the Helio X20 96board for instance.

see above

> Also, none of what you've said justifies NAK'ing patch 4/4, which
> applies to any mt7* and arm64 .dts, including yours.

agreed, i never even mentioned 4/4

> While we're at it, I noticed that mainline has a "mediatek,mt7623-eth"
> network driver but no corresponding .dtsi node. Talk about bitrot...

the idea is that we work together to make thins optimal. this is not a
you or is right. this is about the FOSS peer review process. please dont
be so agro.

to me it seems suboptimal to support 2 dts files for the same board.

	John


>
> Regards,
> Andreas
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 4/4] dt-bindings: mfd: Add STM32F7 RCC numeric constants into DT include file
From: Alexandre Torgue @ 2017-01-10 10:21 UTC (permalink / raw)
  To: gabriel.fernandez, Rob Herring, Mark Rutland, Russell King,
	Maxime Coquelin, Michael Turquette, Stephen Boyd, Nicolas Pitre,
	Arnd Bergmann, daniel.thompson, andrea.merello, radoslaw.pietrzyk
  Cc: devicetree, amelie.delaunay, kernel, olivier.bideau, linux-kernel,
	linux-arm-kernel, linux-clk, ludovic.barre
In-Reply-To: <1483711165-17149-5-git-send-email-gabriel.fernandez@st.com>

Hi Gabriel

On 01/06/2017 02:59 PM, gabriel.fernandez@st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch lists STM32F7's RCC numeric constants.
> It will be used by clock and reset drivers, and DT bindings.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>

can you please split this commit ? (one part for binding and another for DT)

Thanks in advance
Alex


> ---
>  arch/arm/boot/dts/stm32f746.dtsi      |  51 ++++++++--------
>  include/dt-bindings/mfd/stm32f7-rcc.h | 112 ++++++++++++++++++++++++++++++++++
>  2 files changed, 138 insertions(+), 25 deletions(-)
>  create mode 100644 include/dt-bindings/mfd/stm32f7-rcc.h
>
> diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
> index e05e131..09d6649 100644
> --- a/arch/arm/boot/dts/stm32f746.dtsi
> +++ b/arch/arm/boot/dts/stm32f746.dtsi
> @@ -44,6 +44,7 @@
>  #include "armv7-m.dtsi"
>  #include <dt-bindings/pinctrl/stm32f746-pinfunc.h>
>  #include <dt-bindings/clock/stm32fx-clock.h>
> +#include <dt-bindings/mfd/stm32f7-rcc.h>
>
>  / {
>  	clocks {
> @@ -77,7 +78,7 @@
>  			compatible = "st,stm32-timer";
>  			reg = <0x40000000 0x400>;
>  			interrupts = <28>;
> -			clocks = <&rcc 0 128>;
> +			clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM2)>;
>  			status = "disabled";
>  		};
>
> @@ -85,7 +86,7 @@
>  			compatible = "st,stm32-timer";
>  			reg = <0x40000400 0x400>;
>  			interrupts = <29>;
> -			clocks = <&rcc 0 129>;
> +			clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM3)>;
>  			status = "disabled";
>  		};
>
> @@ -93,7 +94,7 @@
>  			compatible = "st,stm32-timer";
>  			reg = <0x40000800 0x400>;
>  			interrupts = <30>;
> -			clocks = <&rcc 0 130>;
> +			clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM4)>;
>  			status = "disabled";
>  		};
>
> @@ -101,14 +102,14 @@
>  			compatible = "st,stm32-timer";
>  			reg = <0x40000c00 0x400>;
>  			interrupts = <50>;
> -			clocks = <&rcc 0 131>;
> +			clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM5)>;
>  		};
>
>  		timer6: timer@40001000 {
>  			compatible = "st,stm32-timer";
>  			reg = <0x40001000 0x400>;
>  			interrupts = <54>;
> -			clocks = <&rcc 0 132>;
> +			clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM6)>;
>  			status = "disabled";
>  		};
>
> @@ -116,7 +117,7 @@
>  			compatible = "st,stm32-timer";
>  			reg = <0x40001400 0x400>;
>  			interrupts = <55>;
> -			clocks = <&rcc 0 133>;
> +			clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM7)>;
>  			status = "disabled";
>  		};
>
> @@ -124,7 +125,7 @@
>  			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
>  			reg = <0x40004400 0x400>;
>  			interrupts = <38>;
> -			clocks =  <&rcc 0 145>;
> +			clocks = <&rcc 1 CLK_USART2>;
>  			status = "disabled";
>  		};
>
> @@ -132,7 +133,7 @@
>  			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
>  			reg = <0x40004800 0x400>;
>  			interrupts = <39>;
> -			clocks = <&rcc 0 146>;
> +			clocks = <&rcc 1 CLK_USART3>;
>  			status = "disabled";
>  		};
>
> @@ -140,7 +141,7 @@
>  			compatible = "st,stm32f7-uart";
>  			reg = <0x40004c00 0x400>;
>  			interrupts = <52>;
> -			clocks = <&rcc 0 147>;
> +			clocks = <&rcc 1 CLK_UART4>;
>  			status = "disabled";
>  		};
>
> @@ -148,7 +149,7 @@
>  			compatible = "st,stm32f7-uart";
>  			reg = <0x40005000 0x400>;
>  			interrupts = <53>;
> -			clocks = <&rcc 0 148>;
> +			clocks = <&rcc 1 CLK_UART5>;
>  			status = "disabled";
>  		};
>
> @@ -156,7 +157,7 @@
>  			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
>  			reg = <0x40007800 0x400>;
>  			interrupts = <82>;
> -			clocks = <&rcc 0 158>;
> +			clocks = <&rcc 1 CLK_UART7>;
>  			status = "disabled";
>  		};
>
> @@ -164,7 +165,7 @@
>  			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
>  			reg = <0x40007c00 0x400>;
>  			interrupts = <83>;
> -			clocks = <&rcc 0 159>;
> +			clocks = <&rcc 1 CLK_UART8>;
>  			status = "disabled";
>  		};
>
> @@ -172,7 +173,7 @@
>  			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
>  			reg = <0x40011000 0x400>;
>  			interrupts = <37>;
> -			clocks = <&rcc 0 164>;
> +			clocks = <&rcc 1 CLK_USART1>;
>  			status = "disabled";
>  		};
>
> @@ -180,7 +181,7 @@
>  			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
>  			reg = <0x40011400 0x400>;
>  			interrupts = <71>;
> -			clocks = <&rcc 0 165>;
> +			clocks = <&rcc 1 CLK_USART6>;
>  			status = "disabled";
>  		};
>
> @@ -215,7 +216,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x0 0x400>;
> -				clocks = <&rcc 0 256>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>;
>  				st,bank-name = "GPIOA";
>  			};
>
> @@ -223,7 +224,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x400 0x400>;
> -				clocks = <&rcc 0 257>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>;
>  				st,bank-name = "GPIOB";
>  			};
>
> @@ -231,7 +232,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x800 0x400>;
> -				clocks = <&rcc 0 258>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>;
>  				st,bank-name = "GPIOC";
>  			};
>
> @@ -239,7 +240,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0xc00 0x400>;
> -				clocks = <&rcc 0 259>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>;
>  				st,bank-name = "GPIOD";
>  			};
>
> @@ -247,7 +248,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x1000 0x400>;
> -				clocks = <&rcc 0 260>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>;
>  				st,bank-name = "GPIOE";
>  			};
>
> @@ -255,7 +256,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x1400 0x400>;
> -				clocks = <&rcc 0 261>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>;
>  				st,bank-name = "GPIOF";
>  			};
>
> @@ -263,7 +264,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x1800 0x400>;
> -				clocks = <&rcc 0 262>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>;
>  				st,bank-name = "GPIOG";
>  			};
>
> @@ -271,7 +272,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x1c00 0x400>;
> -				clocks = <&rcc 0 263>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>;
>  				st,bank-name = "GPIOH";
>  			};
>
> @@ -279,7 +280,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x2000 0x400>;
> -				clocks = <&rcc 0 264>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>;
>  				st,bank-name = "GPIOI";
>  			};
>
> @@ -287,7 +288,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x2400 0x400>;
> -				clocks = <&rcc 0 265>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>;
>  				st,bank-name = "GPIOJ";
>  			};
>
> @@ -295,7 +296,7 @@
>  				gpio-controller;
>  				#gpio-cells = <2>;
>  				reg = <0x2800 0x400>;
> -				clocks = <&rcc 0 266>;
> +				clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>;
>  				st,bank-name = "GPIOK";
>  			};
>
> diff --git a/include/dt-bindings/mfd/stm32f7-rcc.h b/include/dt-bindings/mfd/stm32f7-rcc.h
> new file mode 100644
> index 0000000..e36cc69
> --- /dev/null
> +++ b/include/dt-bindings/mfd/stm32f7-rcc.h
> @@ -0,0 +1,112 @@
> +/*
> + * This header provides constants for the STM32F7 RCC IP
> + */
> +
> +#ifndef _DT_BINDINGS_MFD_STM32F7_RCC_H
> +#define _DT_BINDINGS_MFD_STM32F7_RCC_H
> +
> +/* AHB1 */
> +#define STM32F7_RCC_AHB1_GPIOA		0
> +#define STM32F7_RCC_AHB1_GPIOB		1
> +#define STM32F7_RCC_AHB1_GPIOC		2
> +#define STM32F7_RCC_AHB1_GPIOD		3
> +#define STM32F7_RCC_AHB1_GPIOE		4
> +#define STM32F7_RCC_AHB1_GPIOF		5
> +#define STM32F7_RCC_AHB1_GPIOG		6
> +#define STM32F7_RCC_AHB1_GPIOH		7
> +#define STM32F7_RCC_AHB1_GPIOI		8
> +#define STM32F7_RCC_AHB1_GPIOJ		9
> +#define STM32F7_RCC_AHB1_GPIOK		10
> +#define STM32F7_RCC_AHB1_CRC		12
> +#define STM32F7_RCC_AHB1_BKPSRAM	18
> +#define STM32F7_RCC_AHB1_DTCMRAM	20
> +#define STM32F7_RCC_AHB1_DMA1		21
> +#define STM32F7_RCC_AHB1_DMA2		22
> +#define STM32F7_RCC_AHB1_DMA2D		23
> +#define STM32F7_RCC_AHB1_ETHMAC		25
> +#define STM32F7_RCC_AHB1_ETHMACTX	26
> +#define STM32F7_RCC_AHB1_ETHMACRX	27
> +#define STM32FF_RCC_AHB1_ETHMACPTP	28
> +#define STM32F7_RCC_AHB1_OTGHS		29
> +#define STM32F7_RCC_AHB1_OTGHSULPI	30
> +
> +#define STM32F7_AHB1_RESET(bit) (STM32F7_RCC_AHB1_##bit + (0x10 * 8))
> +#define STM32F7_AHB1_CLOCK(bit) (STM32F7_RCC_AHB1_##bit)
> +
> +
> +/* AHB2 */
> +#define STM32F7_RCC_AHB2_DCMI		0
> +#define STM32F7_RCC_AHB2_CRYP		4
> +#define STM32F7_RCC_AHB2_HASH		5
> +#define STM32F7_RCC_AHB2_RNG		6
> +#define STM32F7_RCC_AHB2_OTGFS		7
> +
> +#define STM32F7_AHB2_RESET(bit)	(STM32F7_RCC_AHB2_##bit + (0x14 * 8))
> +#define STM32F7_AHB2_CLOCK(bit)	(STM32F7_RCC_AHB2_##bit + 0x20)
> +
> +/* AHB3 */
> +#define STM32F7_RCC_AHB3_FMC		0
> +#define STM32F7_RCC_AHB3_QSPI		1
> +
> +#define STM32F7_AHB3_RESET(bit)	(STM32F7_RCC_AHB3_##bit + (0x18 * 8))
> +#define STM32F7_AHB3_CLOCK(bit)	(STM32F7_RCC_AHB3_##bit + 0x40)
> +
> +/* APB1 */
> +#define STM32F7_RCC_APB1_TIM2		0
> +#define STM32F7_RCC_APB1_TIM3		1
> +#define STM32F7_RCC_APB1_TIM4		2
> +#define STM32F7_RCC_APB1_TIM5		3
> +#define STM32F7_RCC_APB1_TIM6		4
> +#define STM32F7_RCC_APB1_TIM7		5
> +#define STM32F7_RCC_APB1_TIM12		6
> +#define STM32F7_RCC_APB1_TIM13		7
> +#define STM32F7_RCC_APB1_TIM14		8
> +#define STM32F7_RCC_APB1_LPTIM1		9
> +#define STM32F7_RCC_APB1_WWDG		11
> +#define STM32F7_RCC_APB1_SPI2		14
> +#define STM32F7_RCC_APB1_SPI3		15
> +#define STM32F7_RCC_APB1_SPDIFRX	16
> +#define STM32F7_RCC_APB1_UART2		17
> +#define STM32F7_RCC_APB1_UART3		18
> +#define STM32F7_RCC_APB1_UART4		19
> +#define STM32F7_RCC_APB1_UART5		20
> +#define STM32F7_RCC_APB1_I2C1		21
> +#define STM32F7_RCC_APB1_I2C2		22
> +#define STM32F7_RCC_APB1_I2C3		23
> +#define STM32F7_RCC_APB1_I2C4		24
> +#define STM32F7_RCC_APB1_CAN1		25
> +#define STM32F7_RCC_APB1_CAN2		26
> +#define STM32F7_RCC_APB1_CEC		27
> +#define STM32F7_RCC_APB1_PWR		28
> +#define STM32F7_RCC_APB1_DAC		29
> +#define STM32F7_RCC_APB1_UART7		30
> +#define STM32F7_RCC_APB1_UART8		31
> +
> +#define STM32F7_APB1_RESET(bit)	(STM32F7_RCC_APB1_##bit + (0x20 * 8))
> +#define STM32F7_APB1_CLOCK(bit)	(STM32F7_RCC_APB1_##bit + 0x80)
> +
> +/* APB2 */
> +#define STM32F7_RCC_APB2_TIM1		0
> +#define STM32F7_RCC_APB2_TIM8		1
> +#define STM32F7_RCC_APB2_USART1		4
> +#define STM32F7_RCC_APB2_USART6		5
> +#define STM32F7_RCC_APB2_ADC1		8
> +#define STM32F7_RCC_APB2_ADC2		9
> +#define STM32F7_RCC_APB2_ADC3		10
> +#define STM32F7_RCC_APB2_SDMMC1		11
> +#define STM32F7_RCC_APB2_SPI1		12
> +#define STM32F7_RCC_APB2_SPI4		13
> +#define STM32F7_RCC_APB2_SYSCFG		14
> +#define STM32F7_RCC_APB2_TIM9		16
> +#define STM32F7_RCC_APB2_TIM10		17
> +#define STM32F7_RCC_APB2_TIM11		18
> +#define STM32F7_RCC_APB2_SPI5		20
> +#define STM32F7_RCC_APB2_SPI6		21
> +#define STM32F7_RCC_APB2_SAI1		22
> +#define STM32F7_RCC_APB2_SAI2		23
> +#define STM32F7_RCC_APB2_LTDC		26
> +
> +#define STM32F7_APB2_RESET(bit)	(STM32F7_RCC_APB2_##bit + (0x24 * 8))
> +#define STM32F7_APB2_CLOCK(bit)	(STM32F7_RCC_APB2_##bit + 0xA0)
> +
> +#endif /* _DT_BINDINGS_MFD_STM32F7_RCC_H */
>

^ permalink raw reply

* Re: [PATCH 07/11] dt/bindings: da8xx-usb: Add binding for the cppi41 dma controller
From: Alexandre Bailon @ 2017-01-10 10:37 UTC (permalink / raw)
  To: Sergei Shtylyov, vinod.koul-ral2JQCrhuEAvxtiuMwx3w
  Cc: dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, nsekhar-l0cyMroinI0,
	khilman-rdvid1DuHRBWk0Htik3J/w, ptitiano-rdvid1DuHRBWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	b-liu-l0cyMroinI0
In-Reply-To: <6ae72fe4-ddb7-4dfc-8c8c-29b63636171b-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>

Hello,

On 01/09/2017 07:41 PM, Sergei Shtylyov wrote:
> Hello!
> 
> On 01/09/2017 07:06 PM, Alexandre Bailon wrote:
> 
>> DT binding for the TI DA8xx/OMAP-L1x/AM17xx/AM18xx cppi41 dma controller.
> 
>    It's called CPPI 4.1, not cppi41.
>    Let me introduce myself: I was the author of the 1st CPPI 4.1 drivers
> (never merged).
> 
>> Signed-off-by: Alexandre Bailon <abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>> ---
>>  .../devicetree/bindings/usb/da8xx-usb.txt          | 39
>> ++++++++++++++++++++++
>>  1 file changed, 39 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/da8xx-usb.txt
>> b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
>> index ccb844a..2a4d737 100644
>> --- a/Documentation/devicetree/bindings/usb/da8xx-usb.txt
>> +++ b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
>> @@ -18,10 +18,26 @@ Required properties:
> [...]
>>  Optional properties:
>>  ~~~~~~~~~~~~~~~~~~~~
>>   - vbus-supply: Phandle to a regulator providing the USB bus power.
>>
>> +DMA
>> +~~~
>> +- compatible: ti,da8xx-cppi41
>> +- reg: offset and length of the following register spaces: USBSS, USB
> 
>    I don't understand what you mean by USBSS and how it's related to
> CPPI 4.1.
I have kept the terminology used in the CPPI 4.1 driver.
USBSS is how the MUSB glue is named in AM335x datasheet.
The CPPI 4.1 driver need to access to few of this registers.
> 
>> +  CPPI DMA Controller, USB CPPI DMA Scheduler, USB Queue Manager
> 
>    I'd drop "USB" everywhere, the DMAC scheduler and queue manager are
> not a part of any USB logic.
Will do it.
> 
>> +- reg-names: glue, controller, scheduler, queuemgr
> 
>    Quoted, maybe?
> 
>> +- #dma-cells: should be set to 2. The first number represents the
>> +  endpoint number (0 … 3 for endpoints 1 … 4).
> 
>    Not sure why you need EPs here. Is that required by the DMA driver?
> The DMA controller operates with channels...
I have taken this from am335x-usb bindings and I kept it as is because
I don't think that's wrong.
I agree we should use DMA terminology but actually the CPPI 4.1 is only
used by USB in DA8xx (share the same clock, the same irq, etc).
In the case of DA8xx, I'm not sure that would make things more clear.

Best Regards,
Alexandre
> 
> [...]
> 
> MBR, Sergei
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v5 1/2] ARM: dts: at91: add devicetree for the Axentia TSE-850
From: Alexandre Belloni @ 2017-01-10 10:42 UTC (permalink / raw)
  To: Peter Rosin
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Russell King, Nicolas Ferre, Jean-Christophe Plagniol-Villard,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <b686fa42-bbfb-dec2-460f-ef00869bc12e-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>

On 10/01/2017 at 10:52:56 +0100, Peter Rosin wrote :
> On 2017-01-10 10:29, Alexandre Belloni wrote:
> > Hi,
> > 
> > This needs a commit message, please add one.
> 
> There's not all that much to say, but ok, I'll add something.
> 

It doesn't have to be long but it has to be present.

> > On 10/01/2017 at 09:08:51 +0100, Peter Rosin wrote :
> There's also the benefit of the increased chances of me getting
> notified of changes. I don't mind...
> 

Do you expect changes coming from third parties? I'm fine with it
anyway.

> >> +&main {
> >> +	clock-frequency = <12000000>;
> >> +};
> >> +
> > 
> > I don't think this is needed
> > 
> > 
> 
> "this"? The &main frequency, or all of them?
> 

I meant just main

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4 0/4] phy: USB and PCIe phy drivers for Qcom chipsets
From: Vivek Gautam @ 2017-01-10 10:51 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, kishon-l0cyMroinI0,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: mark.rutland-5wv7dgnIgG8, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
	srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Vivek Gautam

This patch series adds couple of PHY drivers for Qualcomm chipsets.
a) qcom-qusb2 phy driver: that provides High Speed USB functionality.
b) qcom-qmp phy driver: that is a combo phy providing support for
   USB3, PCIe, UFS and few other controllers.

The patches are based on next branch of linux-phy tree.

These have been tested on Dragon board db820c hardware with
required set of dt patches on integration tree maintained by
Linaro landing team for Qualcomm [1].

Couple of other patches [2,3,4] for nvmem are also pulled in for testing.
Patch series fixing DMA config for XHCI [5] is also pulled in for testing.

Changes since v3:
 - Addressed review comments given by Rob and Stephen for qusb2 phy
   and qmp phy bindings respectively.
 - Addressed review comments given by Stephen and Bjorn for qmp phy driver.

Changes since v2:
 - Addressed review comments given by Rob and Stephen for bindings.
 - Addressed the review comments given by Stephen for the qusb2 and qmp
   phy drivers.

Changes since v1:
 - Moved device tree binding documentation to separate patches, as suggested
   by Rob.
 - Addressed review comment regarding qfprom accesses by qusb2 phy driver,
   given by Rob.
 - Addressed review comments from Kishon.
 - Addressed review comments from Srinivas for QMP phy driver.
 - Addressed kbuild warning.

Please see individual patches for detailed changelogs.

[1] https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=integration-linux-qcomlt
[2] https://lkml.org/lkml/2016/11/17/21
[3] https://lkml.org/lkml/2016/12/19/18
[4] http://www.spinics.net/lists/linux-arm-msm/msg25483.html
[5] https://lkml.org/lkml/2016/11/17/339

Vivek Gautam (4):
  dt-bindings: phy: Add support for QUSB2 phy
  phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips
  dt-bindings: phy: Add support for QMP phy
  phy: qcom-qmp: new qmp phy driver for qcom-chipsets

 .../devicetree/bindings/phy/qcom-qmp-phy.txt       |   76 ++
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt     |   45 +
 drivers/phy/Kconfig                                |   18 +
 drivers/phy/Makefile                               |    2 +
 drivers/phy/phy-qcom-qmp.c                         | 1206 ++++++++++++++++++++
 drivers/phy/phy-qcom-qusb2.c                       |  539 +++++++++
 6 files changed, 1886 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
 create mode 100644 drivers/phy/phy-qcom-qmp.c
 create mode 100644 drivers/phy/phy-qcom-qusb2.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4 1/4] dt-bindings: phy: Add support for QUSB2 phy
From: Vivek Gautam @ 2017-01-10 10:51 UTC (permalink / raw)
  To: robh+dt, kishon, linux-kernel, devicetree
  Cc: mark.rutland, sboyd, bjorn.andersson, srinivas.kandagatla,
	linux-arm-msm, Vivek Gautam
In-Reply-To: <1484045519-19030-1-git-send-email-vivek.gautam@codeaurora.org>

Qualcomm chipsets have QUSB2 phy controller that provides
HighSpeed functionality for DWC3 controller.
Adding dt binding information for the same.

Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Acked-by: Rob Herring <robh@kernel.org>
---

Changes since v3:
 - Added 'Acked-by' from Rob.
 - Removed 'reset-names' and 'nvmem-cell-names' from the bindings
   since we use only one cell.

Changes since v2:
 - Removed binding for "ref_clk_src" since we don't request this
   clock in the driver.
 - Addressed s/vdda-phy-dpdm/vdda-phy-dpdm-supply.
 - Addressed s/ref_clk/ref. Don't need to add '_clk' suffix to clock names.
 - Addressed s/tune2_hstx_trim_efuse/tune2_hstx_trim. Don't need to add
   'efuse' suffix to nvmem cell.
 - Addressed s/qusb2phy/phy for the node name.

Changes since v1:
 - New patch, forked out of the original driver patch:
   "phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips"
 - Updated dt bindings to remove 'hstx-trim-bit-offset' and
   'hstx-trim-bit-len' bindings.

 .../devicetree/bindings/phy/qcom-qusb2-phy.txt     | 45 ++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
new file mode 100644
index 000000000000..218595fe8824
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -0,0 +1,45 @@
+Qualcomm QUSB2 phy controller
+=============================
+
+QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets.
+
+Required properties:
+ - compatible: compatible list, contains "qcom,msm8996-qusb2-phy".
+ - reg: offset and length of the PHY register set.
+ - #phy-cells: must be 0.
+
+ - clocks: a list of phandles and clock-specifier pairs,
+	   one for each entry in clock-names.
+ - clock-names: must be "cfg_ahb" for phy config clock,
+			"ref" for 19.2 MHz ref clk,
+			"iface" for phy interface clock (Optional).
+
+ - vdd-phy-supply: Phandle to a regulator supply to PHY core block.
+ - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block.
+ - vdda-phy-dpdm-supply: Phandle to 3.1V regulator supply to Dp/Dm port signals.
+
+ - resets: Phandle to reset to phy block.
+
+Optional properties:
+ - nvmem-cells: Phandle to nvmem cell that contains 'HS Tx trim'
+		tuning parameter value for qusb2 phy.
+
+ - qcom,tcsr-syscon: Phandle to TCSR syscon register region.
+
+Example:
+	hsusb_phy: phy@7411000 {
+		compatible = "qcom,msm8996-qusb2-phy";
+		reg = <0x07411000 0x180>;
+		#phy-cells = <0>;
+
+		clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+			<&gcc GCC_RX1_USB2_CLKREF_CLK>,
+		clock-names = "cfg_ahb", "ref";
+
+		vdd-phy-supply = <&pm8994_s2>;
+		vdda-pll-supply = <&pm8994_l12>;
+		vdda-phy-dpdm-supply = <&pm8994_l24>;
+
+		resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+		nvmem-cells = <&qusb2p_hstx_trim>;
+        };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH v4 2/4] phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips
From: Vivek Gautam @ 2017-01-10 10:51 UTC (permalink / raw)
  To: robh+dt, kishon, linux-kernel, devicetree
  Cc: mark.rutland, sboyd, bjorn.andersson, srinivas.kandagatla,
	linux-arm-msm, Vivek Gautam
In-Reply-To: <1484045519-19030-1-git-send-email-vivek.gautam@codeaurora.org>

PHY transceiver driver for QUSB2 phy controller that provides
HighSpeed functionality for DWC3 controller present on
Qualcomm chipsets.

Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---

Changes since v3:
 - Added 'Reviewed-by' from Stephen.
 - Fixed debug message for qusb2_phy_set_tune2_param().
 - Replaced devm_reset_control_get() with devm_reset_control_get_by_index()
   since we are requesting only one reset.
 - Updated devm_nvmem_cell_get() with a NULL cell id.
 - Made error labels more idiomatic.
 - Refactored qusb2_setbits() and qusb2_clrbits() a little bit to accept
   base address and register offset as two separate arguments.

Changes since v2:
 - Removed selecting 'RESET_CONTROLLER' config.
 - Added error handling for clk_prepare_enable paths.
 - Removed explicitly setting ref_clk rate to 19.2 MHz. Don't need to
   do that since 'xo' is modeled as parent to this clock.
 - Removed 'ref_clk_src' handling. Driver doesn't need to request and
   handle this clock.
 - Moved nvmem_cell_get() to probe function.
 - Simplified phy pll status handling.
 - Using of_device_get_match_data() to get match data.
 - Uniformly using lowercase for hex numbers.
 - Fixed sparse warnings.
 - Using shorter variable names in structure and in functions.
 - Handling various comment style shortcomings.

Changes since v1:
 - removed reference to clk_enabled/pwr_enabled.
 - moved clock and regulator enable code to phy_power_on/off() callbacks.
 - fixed return on EPROBE_DEFER in qusb2_phy_probe().
 - fixed phy create and phy register ordering.
 - removed references to non-lkml links from commit message.
 - took care of other minor nits.
 - Fixed coccinelle warnings -
   'PTR_ERR applied after initialization to constant'
 - Addressed review comment, regarding qfprom access for tune2 param value.
   This driver is now based on qfprom patch[1] that allows byte access now.

 drivers/phy/Kconfig          |  10 +
 drivers/phy/Makefile         |   1 +
 drivers/phy/phy-qcom-qusb2.c | 539 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 550 insertions(+)
 create mode 100644 drivers/phy/phy-qcom-qusb2.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index e8eb7f225a88..0ed53d018b23 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -430,6 +430,16 @@ config PHY_STIH407_USB
 	  Enable this support to enable the picoPHY device used by USB2
 	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
 
+config PHY_QCOM_QUSB2
+	tristate "Qualcomm QUSB2 PHY Driver"
+	depends on OF && (ARCH_QCOM || COMPILE_TEST)
+	select GENERIC_PHY
+	help
+	  Enable this to support the HighSpeed QUSB2 PHY transceiver for USB
+	  controllers on Qualcomm chips. This driver supports the high-speed
+	  PHY which is usually paired with either the ChipIdea or Synopsys DWC3
+	  USB IPs on MSM SOCs.
+
 config PHY_QCOM_UFS
 	tristate "Qualcomm UFS PHY driver"
 	depends on OF && ARCH_QCOM
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 65eb2f436a41..dad1682b80e3 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
 obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
 obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
+obj-$(CONFIG_PHY_QCOM_QUSB2) 	+= phy-qcom-qusb2.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
diff --git a/drivers/phy/phy-qcom-qusb2.c b/drivers/phy/phy-qcom-qusb2.c
new file mode 100644
index 000000000000..c69118610164
--- /dev/null
+++ b/drivers/phy/phy-qcom-qusb2.c
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#define QUSB2PHY_PLL_TEST		0x04
+#define CLK_REF_SEL			BIT(7)
+
+#define QUSB2PHY_PLL_TUNE		0x08
+#define QUSB2PHY_PLL_USER_CTL1		0x0c
+#define QUSB2PHY_PLL_USER_CTL2		0x10
+#define QUSB2PHY_PLL_AUTOPGM_CTL1	0x1c
+#define QUSB2PHY_PLL_PWR_CTRL		0x18
+
+#define QUSB2PHY_PLL_STATUS		0x38
+#define PLL_LOCKED			BIT(5)
+
+#define QUSB2PHY_PORT_TUNE1		0x80
+#define QUSB2PHY_PORT_TUNE2		0x84
+#define QUSB2PHY_PORT_TUNE3		0x88
+#define QUSB2PHY_PORT_TUNE4		0x8c
+#define QUSB2PHY_PORT_TUNE5		0x90
+#define QUSB2PHY_PORT_TEST2		0x9c
+
+#define QUSB2PHY_PORT_POWERDOWN		0xb4
+#define CLAMP_N_EN			BIT(5)
+#define FREEZIO_N			BIT(1)
+#define POWER_DOWN			BIT(0)
+
+#define QUSB2PHY_REFCLK_ENABLE		BIT(0)
+
+#define PHY_CLK_SCHEME_SEL		BIT(0)
+
+struct qusb2_phy_init_tbl {
+	unsigned int offset;
+	unsigned int val;
+};
+#define QUSB2_PHY_INIT_CFG(o, v) \
+	{			\
+		.offset = o,	\
+		.val = v,	\
+	}
+
+static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = {
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE1, 0xf8),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE2, 0xb3),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE3, 0x83),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE4, 0xc0),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TEST2, 0x14),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
+};
+
+struct qusb2_phy_cfg {
+	const struct qusb2_phy_init_tbl *tbl;
+	/* number of entries in the table */
+	unsigned int tbl_num;
+	/* offset to PHY_CLK_SCHEME register in TCSR map */
+	unsigned int clk_scheme_offset;
+};
+
+static const struct qusb2_phy_cfg msm8996_phy_cfg = {
+	.tbl = msm8996_init_tbl,
+	.tbl_num = ARRAY_SIZE(msm8996_init_tbl),
+};
+
+/**
+ * struct qusb2_phy - structure holding qusb2 phy attributes
+ *
+ * @phy: generic phy
+ * @base: iomapped memory space for qubs2 phy
+ *
+ * @cfg_ahb_clk: AHB2PHY interface clock
+ * @ref_clk: phy reference clock
+ * @iface_clk: phy interface clock
+ *
+ * @phy_reset: phy reset control
+ *
+ * @vdda_phy: vdd supply to the phy core block
+ * @vdda_pll: 1.8V vdd supply to ref_clk block
+ * @vdda_phy_dpdm: 3.1V vdd supply to Dp/Dm port signals
+ * @tcsr: TCSR syscon register map
+ * @cell: nvmem cell containing phy tuning value
+ *
+ * @cfg: phy config data
+ * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
+ */
+struct qusb2_phy {
+	struct phy *phy;
+	void __iomem *base;
+
+	struct clk *cfg_ahb_clk;
+	struct clk *ref_clk;
+	struct clk *iface_clk;
+
+	struct reset_control *phy_reset;
+
+	struct regulator *vdd_phy;
+	struct regulator *vdda_pll;
+	struct regulator *vdda_phy_dpdm;
+
+	struct regmap *tcsr;
+	struct nvmem_cell *cell;
+
+	const struct qusb2_phy_cfg *cfg;
+	bool has_se_clk_scheme;
+};
+
+static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl_relaxed(base + offset);
+	reg |= val;
+	writel_relaxed(reg, base + offset);
+
+	/* Ensure above write is completed */
+	mb();
+}
+
+static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl_relaxed(base + offset);
+	reg &= ~val;
+	writel_relaxed(reg, base + offset);
+
+	/* Ensure above write is completed */
+	mb();
+}
+
+static inline void qcom_qusb2_phy_configure(void __iomem *base,
+				const struct qusb2_phy_init_tbl tbl[],
+				int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++)
+		writel_relaxed(tbl[i].val, base + tbl[i].offset);
+
+	/* flush buffered writes */
+	mb();
+}
+
+static int qusb2_phy_toggle_power(struct qusb2_phy *qphy, bool on)
+{
+	struct device *dev = &qphy->phy->dev;
+	int ret;
+
+	if (!on) {
+		ret = 0;
+		goto disable_vdda_phy_dpdm;
+	}
+
+	ret = regulator_enable(qphy->vdd_phy);
+	if (ret) {
+		dev_err(dev, "failed to enable vdd-phy, %d\n", ret);
+		goto err_vdd_phy;
+	}
+
+	ret = regulator_enable(qphy->vdda_pll);
+	if (ret) {
+		dev_err(dev, "failed to enable vdda-pll, %d\n", ret);
+		goto disable_vdd_phy;
+	}
+
+	ret = regulator_enable(qphy->vdda_phy_dpdm);
+	if (ret) {
+		dev_err(dev, "failed to enable vdda-phy-dpdm, %d\n", ret);
+		goto disable_vdda_pll;
+	}
+
+	dev_vdbg(dev, "%s(): regulators are turned on\n", __func__);
+
+	return ret;
+
+disable_vdda_phy_dpdm:
+	regulator_disable(qphy->vdda_phy_dpdm);
+disable_vdda_pll:
+	regulator_disable(qphy->vdda_pll);
+disable_vdd_phy:
+	regulator_disable(qphy->vdd_phy);
+err_vdd_phy:
+	dev_vdbg(dev, "%s(): regulators are turned off\n", __func__);
+	return ret;
+}
+
+/*
+ * Fetches HS Tx tuning value from nvmem and sets the
+ * QUSB2PHY_PORT_TUNE2 register.
+ * For error case, skip setting the value and use the default value.
+ */
+static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
+{
+	struct device *dev = &qphy->phy->dev;
+	u8 *val;
+
+	/*
+	 * Read efuse register having TUNE2 parameter's high nibble.
+	 * If efuse register shows value as 0x0, or if we fail to find
+	 * a valid efuse register settings, then use default value
+	 * as 0xB for high nibble that we have already set while
+	 * configuring phy.
+	 */
+	val = nvmem_cell_read(qphy->cell, NULL);
+	if (IS_ERR(val) || !val[0]) {
+		dev_dbg(dev, "failed to read a valid hs-tx trim value\n");
+		return;
+	}
+
+	/* Fused TUNE2 value is the higher nibble only */
+	qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
+}
+
+static int qusb2_phy_poweron(struct phy *phy)
+{
+	struct qusb2_phy *qphy = phy_get_drvdata(phy);
+	int ret;
+
+	dev_vdbg(&phy->dev, "%s(): Powering-on QUSB2 phy\n", __func__);
+
+	/* turn on regulator supplies */
+	ret = qusb2_phy_toggle_power(qphy, true);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(qphy->iface_clk);
+	if (ret)
+		dev_err(&phy->dev, "failed to enable iface_clk, %d\n", ret);
+
+	return ret;
+}
+
+static int qusb2_phy_poweroff(struct phy *phy)
+{
+	struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(qphy->iface_clk);
+
+	qusb2_phy_toggle_power(qphy, false);
+
+	return 0;
+}
+
+static int qusb2_phy_init(struct phy *phy)
+{
+	struct qusb2_phy *qphy = phy_get_drvdata(phy);
+	unsigned int val;
+	unsigned int clk_scheme;
+	int ret;
+
+	dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__);
+
+	/* enable ahb interface clock to program phy */
+	ret = clk_prepare_enable(qphy->cfg_ahb_clk);
+	if (ret) {
+		dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
+		return ret;
+	}
+
+	/* Perform phy reset */
+	ret = reset_control_assert(qphy->phy_reset);
+	if (ret) {
+		dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret);
+		goto disable_ahb_clk;
+	}
+
+	/* 100 us delay to keep PHY in reset mode */
+	usleep_range(100, 150);
+
+	ret = reset_control_deassert(qphy->phy_reset);
+	if (ret) {
+		dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret);
+		goto disable_ahb_clk;
+	}
+
+	/* Disable the PHY */
+	qusb2_setbits(qphy->base, QUSB2PHY_PORT_POWERDOWN,
+			CLAMP_N_EN | FREEZIO_N | POWER_DOWN);
+
+	/* save reset value to override reference clock scheme later */
+	val = readl_relaxed(qphy->base + QUSB2PHY_PLL_TEST);
+
+	qcom_qusb2_phy_configure(qphy->base, qphy->cfg->tbl,
+					qphy->cfg->tbl_num);
+
+	/* Set efuse value for tuning the PHY */
+	qusb2_phy_set_tune2_param(qphy);
+
+	/* Enable the PHY */
+	qusb2_clrbits(qphy->base, QUSB2PHY_PORT_POWERDOWN, POWER_DOWN);
+
+	/* Required to get phy pll lock successfully */
+	usleep_range(150, 160);
+
+	/* Default is single-ended clock on msm8996 */
+	qphy->has_se_clk_scheme = true;
+	/*
+	 * read TCSR_PHY_CLK_SCHEME register to check if single-ended
+	 * clock scheme is selected. If yes, then disable differential
+	 * ref_clk and use single-ended clock, otherwise use differential
+	 * ref_clk only.
+	 */
+	if (qphy->tcsr) {
+		ret = regmap_read(qphy->tcsr, qphy->cfg->clk_scheme_offset,
+							&clk_scheme);
+		if (ret) {
+			dev_err(&phy->dev, "failed to read clk scheme reg\n");
+			goto assert_phy_reset;
+		}
+
+		/* is it a differential clock scheme ? */
+		if (!(clk_scheme & PHY_CLK_SCHEME_SEL)) {
+			dev_vdbg(&phy->dev, "%s(): select differential clk\n",
+								__func__);
+			qphy->has_se_clk_scheme = false;
+		} else {
+			dev_vdbg(&phy->dev, "%s(): select single-ended clk\n",
+								__func__);
+		}
+	}
+
+	if (!qphy->has_se_clk_scheme) {
+		val &= ~CLK_REF_SEL;
+		ret = clk_prepare_enable(qphy->ref_clk);
+		if (ret) {
+			dev_err(&phy->dev, "failed to enable ref clk, %d\n",
+									ret);
+			goto assert_phy_reset;
+		}
+	} else {
+		val |= CLK_REF_SEL;
+	}
+
+	writel_relaxed(val, qphy->base + QUSB2PHY_PLL_TEST);
+
+	/* Make sure that above write is completed to get PLL source clock */
+	wmb();
+
+	/* Required to get phy pll lock successfully */
+	usleep_range(100, 110);
+
+	val = readb_relaxed(qphy->base + QUSB2PHY_PLL_STATUS);
+	if (!(val & PLL_LOCKED)) {
+		dev_err(&phy->dev,
+			"QUSB2PHY pll lock failed: status reg = %x\n", val);
+		ret = -EBUSY;
+		goto disable_ref_clk;
+	}
+
+	return 0;
+
+disable_ref_clk:
+	if (!qphy->has_se_clk_scheme)
+		clk_disable_unprepare(qphy->ref_clk);
+assert_phy_reset:
+	reset_control_assert(qphy->phy_reset);
+disable_ahb_clk:
+	clk_disable_unprepare(qphy->cfg_ahb_clk);
+	return ret;
+}
+
+static int qusb2_phy_exit(struct phy *phy)
+{
+	struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+	/* Disable the PHY */
+	qusb2_setbits(qphy->base, QUSB2PHY_PORT_POWERDOWN,
+			CLAMP_N_EN | FREEZIO_N | POWER_DOWN);
+
+	if (!qphy->has_se_clk_scheme)
+		clk_disable_unprepare(qphy->ref_clk);
+
+	reset_control_assert(qphy->phy_reset);
+
+	clk_disable_unprepare(qphy->cfg_ahb_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qusb2_phy_gen_ops = {
+	.init		= qusb2_phy_init,
+	.exit		= qusb2_phy_exit,
+	.power_on	= qusb2_phy_poweron,
+	.power_off	= qusb2_phy_poweroff,
+	.owner		= THIS_MODULE,
+};
+
+static const struct of_device_id qusb2_phy_of_match_table[] = {
+	{
+		.compatible	= "qcom,msm8996-qusb2-phy",
+		.data		= &msm8996_phy_cfg,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, qusb2_phy_of_match_table);
+
+static int qusb2_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct qusb2_phy *qphy;
+	struct phy_provider *phy_provider;
+	struct phy *generic_phy;
+	struct resource *res;
+	int ret;
+
+	qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
+	if (!qphy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	qphy->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(qphy->base))
+		return PTR_ERR(qphy->base);
+
+	qphy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb");
+	if (IS_ERR(qphy->cfg_ahb_clk)) {
+		ret = PTR_ERR(qphy->cfg_ahb_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to get cfg ahb clk, %d\n", ret);
+		return ret;
+	}
+
+	qphy->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(qphy->ref_clk)) {
+		ret = PTR_ERR(qphy->ref_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to get ref clk, %d\n", ret);
+		return ret;
+	}
+
+	qphy->iface_clk = devm_clk_get(dev, "iface");
+	if (IS_ERR(qphy->iface_clk)) {
+		ret = PTR_ERR(qphy->iface_clk);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+		qphy->iface_clk = NULL;
+		dev_dbg(dev, "failed to get iface clk, %d\n", ret);
+	}
+
+	qphy->phy_reset = devm_reset_control_get_by_index(&pdev->dev, 0);
+	if (IS_ERR(qphy->phy_reset)) {
+		dev_err(dev, "failed to get phy core reset\n");
+		return PTR_ERR(qphy->phy_reset);
+	}
+
+	qphy->vdd_phy = devm_regulator_get(dev, "vdd-phy");
+	if (IS_ERR(qphy->vdd_phy))
+		return PTR_ERR(qphy->vdd_phy);
+
+	qphy->vdda_pll = devm_regulator_get(dev, "vdda-pll");
+	if (IS_ERR(qphy->vdda_pll))
+		return PTR_ERR(qphy->vdda_pll);
+
+	qphy->vdda_phy_dpdm = devm_regulator_get(dev, "vdda-phy-dpdm");
+	if (IS_ERR(qphy->vdda_phy_dpdm))
+		return PTR_ERR(qphy->vdda_phy_dpdm);
+
+	/* Get the specific init parameters of QMP phy */
+	qphy->cfg = of_device_get_match_data(dev);
+
+	qphy->tcsr = syscon_regmap_lookup_by_phandle(dev->of_node,
+							"qcom,tcsr-syscon");
+	if (IS_ERR(qphy->tcsr)) {
+		dev_dbg(dev, "failed to lookup TCSR regmap\n");
+		qphy->tcsr = NULL;
+	}
+
+	qphy->cell = devm_nvmem_cell_get(dev, NULL);
+	if (IS_ERR(qphy->cell)) {
+		if (PTR_ERR(qphy->cell) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		qphy->cell = NULL;
+		dev_dbg(dev, "failed to lookup tune2 hstx trim value\n");
+	}
+
+	generic_phy = devm_phy_create(dev, NULL, &qusb2_phy_gen_ops);
+	if (IS_ERR(generic_phy)) {
+		ret = PTR_ERR(generic_phy);
+		dev_err(dev, "failed to create phy, %d\n", ret);
+		return ret;
+	}
+	qphy->phy = generic_phy;
+
+	dev_set_drvdata(dev, qphy);
+	phy_set_drvdata(generic_phy, qphy);
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		ret = PTR_ERR(phy_provider);
+		dev_err(dev, "failed to register phy, %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct platform_driver qusb2_phy_driver = {
+	.probe		= qusb2_phy_probe,
+	.driver = {
+		.name	= "qcom-qusb2-phy",
+		.of_match_table = of_match_ptr(qusb2_phy_of_match_table),
+	},
+};
+
+module_platform_driver(qusb2_phy_driver);
+
+MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
+MODULE_DESCRIPTION("Qualcomm QUSB2 PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH v4 3/4] dt-bindings: phy: Add support for QMP phy
From: Vivek Gautam @ 2017-01-10 10:51 UTC (permalink / raw)
  To: robh+dt, kishon, linux-kernel, devicetree
  Cc: mark.rutland, sboyd, bjorn.andersson, srinivas.kandagatla,
	linux-arm-msm, Vivek Gautam
In-Reply-To: <1484045519-19030-1-git-send-email-vivek.gautam@codeaurora.org>

Qualcomm chipsets have QMP phy controller that provides
support to a number of controller, viz. PCIe, UFS, and USB.
Adding dt binding information for the same.

Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Acked-by: Rob Herring <robh@kernel.org>
---

Changes since v3:
 - Added #clock-cells = <1>, indicating that phy is a clock provider.

Changes since v2:
 - Removed binding for "ref_clk_src" since we don't request this
   clock in the driver.
 - Addressed s/ref_clk/ref. Don't need to add '_clk' suffix to clock names.
 - Using 'phy' for the node name.

Changes since v1:
 - New patch, forked out of the original driver patch:
   "phy: qcom-qmp: new qmp phy driver for qcom-chipsets"
 - Added 'Acked-by' from Rob.
 - Updated bindings to include mem resource as a list of
   offset - length pair for serdes block and for each lane.
 - Added a new binding for 'lane-offsets' that contains offsets
   to tx, rx and pcs blocks from each lane base address.

 .../devicetree/bindings/phy/qcom-qmp-phy.txt       | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
new file mode 100644
index 000000000000..6f510fe48f46
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -0,0 +1,76 @@
+Qualcomm QMP PHY controller
+===========================
+
+QMP phy controller supports physical layer functionality for a number of
+controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
+
+Required properties:
+ - compatible: compatible list, contains:
+	       "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
+	       "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996.
+ - reg: list of offset and length pair of the PHY register sets.
+	at index 0: offset and length of register set for PHY common
+		    serdes block.
+	from index 1 - N: offset and length of register set for each lane,
+			  for N number of phy lanes (ports).
+ - lane-offsets: array of offsets to tx, rx and pcs blocks for phy lanes.
+ - #phy-cells: must be 1
+    - Cell after phy phandle should be the port (lane) number.
+ - #clock-cells: must be 1
+    - Phy pll outputs a bunch of clocks for Tx, Rx and Pipe
+      interface (for pipe based PHYs). These clock are then gate-controlled
+      by gcc.
+ - clocks: a list of phandles and clock-specifier pairs,
+	   one for each entry in clock-names.
+ - clock-names: must be "cfg_ahb" for phy config clock,
+			"aux" for phy aux clock,
+			"ref" for 19.2 MHz ref clk,
+			"pipe<port-number>" for pipe clock specific to
+			each port/lane (Optional).
+ - resets: a list of phandles and reset controller specifier pairs,
+	   one for each entry in reset-names.
+ - reset-names: must be "phy" for reset of phy block,
+			"common" for phy common block reset,
+			"cfg" for phy's ahb cfg block reset (Optional).
+			"port<port-number>" for reset specific to
+			each port/lane (Optional).
+ - vdda-phy-supply: Phandle to a regulator supply to PHY core block.
+ - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block.
+
+Optional properties:
+ - vddp-ref-clk-supply: Phandle to a regulator supply to any specific refclk
+			pll block.
+
+Example:
+	pcie_phy: phy@34000 {
+		compatible = "qcom,msm8996-qmp-pcie-phy";
+		reg = <0x034000 0x48f>,
+			<0x035000 0x5bf>,
+			<0x036000 0x5bf>,
+			<0x037000 0x5bf>;
+				/* tx, rx, pcs */
+		lane-offsets = <0x0 0x200 0x400>;
+		#phy-cells = <1>;
+		#clock-cells = <1>;
+
+		clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
+			<&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
+			<&gcc GCC_PCIE_CLKREF_CLK>,
+			<&gcc GCC_PCIE_0_PIPE_CLK>,
+			<&gcc GCC_PCIE_1_PIPE_CLK>,
+			<&gcc GCC_PCIE_2_PIPE_CLK>;
+		clock-names = "aux", "cfg_ahb", "ref",
+				"pipe0", "pipe1", "pipe2";
+
+		vdda-phy-supply = <&pm8994_l28>;
+		vdda-pll-supply = <&pm8994_l12>;
+
+		resets = <&gcc GCC_PCIE_PHY_BCR>,
+			<&gcc GCC_PCIE_PHY_COM_BCR>,
+			<&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>,
+			<&gcc GCC_PCIE_0_PHY_BCR>,
+			<&gcc GCC_PCIE_1_PHY_BCR>,
+			<&gcc GCC_PCIE_2_PHY_BCR>;
+		reset-names = "phy", "common", "cfg",
+				"lane0", "lane1", "lane2";
+	};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH v4 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets
From: Vivek Gautam @ 2017-01-10 10:51 UTC (permalink / raw)
  To: robh+dt, kishon, linux-kernel, devicetree
  Cc: mark.rutland, sboyd, bjorn.andersson, srinivas.kandagatla,
	linux-arm-msm, Vivek Gautam
In-Reply-To: <1484045519-19030-1-git-send-email-vivek.gautam@codeaurora.org>

Qualcomm SOCs have QMP phy controller that provides support
to a number of controller, viz. PCIe, UFS, and USB.
Add a new driver, based on generic phy framework, for this
phy controller.

Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---

Changes since v3:
 - Renamed 'struct qcom_qmp_phy' to 'struct qcom_qmp' and
   'struct qmp_phy_desc' to 'struct qmp_phy' to avoid any confusion
   in distinguishing between QMP phy block and per-lane phy which is
   the actual phy in Linux eyes (suggested by Bjorn Andersson).
 - Made error labels more idiomatic.
 - Modified status checking for phy pcs.
 - Fixed power_down_delay check.
 - Refactored phy_pipe_clk_register() to register the pipe clock source
   using devm_clk_hw_register() (suggested by Stephen).
 - qcom_qmp_phy_xlate() function:
   - Removed unnecessary 'for loop'.
   - Added additional check for '0' or -ve args_count.
 - Fixed the mixed tabs and spaces in pipe_clk_src diagram.
 - Removed instances of memset() since we use snprintf() for the
   buffers.
 - Refactored qphy_setbits() and qphy_clrbits() a little bit to accept
   base address and register offset as two separate arguments.

Changes since v2:
 - Removed selecting 'RESET_CONTROLLER' config.
 - Added error handling for clk_prepare_enable paths.
 - Removed 'ref_clk_src' handling. Driver doesn't need to request and
   handle this clock.
 - Using readl_poll_timeout() to simplify pcs ready status polling.
   Also fixed the polling condition for pcs block ready status:
   'Common block ready status bit is set on phy init completion, while
   PCS block ready status bit (PHYSTATUS) is reset on phy init
   completion.'
 - Moved out the per-lane phy creation from probe() to separate
   function.
 - Registering pipe clock source as a fixed rate clock that comes
   out of the PLL block of QMP phy. These source clocks serve as
   parent to 'pipe_clks' that are requested by pcie or usb3 phys.
 - Using of_device_get_match_data() to get match data.
 - Fixed sparse warnings for 'static' and 'const'.
 - Using shorter variable names in structure and in functions.
 - Handling various comment style shortcomings.

Changes since v1:
 - Fixed missing mutex_unlock() calls in error cases, reported by
   Julia Lawall.
 - Selecting CONFIG_RESET_CONTROLLER when this driver is enabled.
 - Added a boolean property to check if the phy has individual lane
   reset available.
 - Took care or EPROBE_DEFER, dev_vdbg() and other minor nits.
 - Removed references to non-lkml links from commit message.
 - Moved to use separate iomem resources for each lanes.
   Tx, Rx and PCS offsets per lane can now come from dt bindings.

 drivers/phy/Kconfig        |    8 +
 drivers/phy/Makefile       |    1 +
 drivers/phy/phy-qcom-qmp.c | 1206 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1215 insertions(+)
 create mode 100644 drivers/phy/phy-qcom-qmp.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 0ed53d018b23..54296397452c 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -430,6 +430,14 @@ config PHY_STIH407_USB
 	  Enable this support to enable the picoPHY device used by USB2
 	  and USB3 controllers on STMicroelectronics STiH407 SoC families.
 
+config PHY_QCOM_QMP
+	tristate "Qualcomm QMP PHY Driver"
+	depends on OF && (ARCH_QCOM || COMPILE_TEST)
+	select GENERIC_PHY
+	help
+	  Enable this to support the QMP PHY transceiver that is used
+	  with controllers such as PCIe, UFS, and USB on Qualcomm chips.
+
 config PHY_QCOM_QUSB2
 	tristate "Qualcomm QUSB2 PHY Driver"
 	depends on OF && (ARCH_QCOM || COMPILE_TEST)
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index dad1682b80e3..dbe7731bbca9 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
 obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
 obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
 obj-$(CONFIG_PHY_QCOM_QUSB2) 	+= phy-qcom-qusb2.o
+obj-$(CONFIG_PHY_QCOM_QMP) 	+= phy-qcom-qmp.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
diff --git a/drivers/phy/phy-qcom-qmp.c b/drivers/phy/phy-qcom-qmp.c
new file mode 100644
index 000000000000..cff01c815c20
--- /dev/null
+++ b/drivers/phy/phy-qcom-qmp.c
@@ -0,0 +1,1206 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/phy/phy.h>
+
+/* QMP PHY QSERDES COM registers */
+#define QSERDES_COM_BG_TIMER				0x00c
+#define QSERDES_COM_SSC_EN_CENTER			0x010
+#define QSERDES_COM_SSC_ADJ_PER1			0x014
+#define QSERDES_COM_SSC_ADJ_PER2			0x018
+#define QSERDES_COM_SSC_PER1				0x01c
+#define QSERDES_COM_SSC_PER2				0x020
+#define QSERDES_COM_SSC_STEP_SIZE1			0x024
+#define QSERDES_COM_SSC_STEP_SIZE2			0x028
+#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN			0x034
+#define QSERDES_COM_CLK_ENABLE1				0x038
+#define QSERDES_COM_SYS_CLK_CTRL			0x03c
+#define QSERDES_COM_SYSCLK_BUF_ENABLE			0x040
+#define QSERDES_COM_PLL_IVCO				0x048
+#define QSERDES_COM_LOCK_CMP1_MODE0			0x04c
+#define QSERDES_COM_LOCK_CMP2_MODE0			0x050
+#define QSERDES_COM_LOCK_CMP3_MODE0			0x054
+#define QSERDES_COM_LOCK_CMP1_MODE1			0x058
+#define QSERDES_COM_LOCK_CMP2_MODE1			0x05c
+#define QSERDES_COM_LOCK_CMP3_MODE1			0x060
+#define QSERDES_COM_BG_TRIM				0x070
+#define QSERDES_COM_CLK_EP_DIV				0x074
+#define QSERDES_COM_CP_CTRL_MODE0			0x078
+#define QSERDES_COM_CP_CTRL_MODE1			0x07c
+#define QSERDES_COM_PLL_RCTRL_MODE0			0x084
+#define QSERDES_COM_PLL_RCTRL_MODE1			0x088
+#define QSERDES_COM_PLL_CCTRL_MODE0			0x090
+#define QSERDES_COM_PLL_CCTRL_MODE1			0x094
+#define QSERDES_COM_SYSCLK_EN_SEL			0x0ac
+#define QSERDES_COM_RESETSM_CNTRL			0x0b4
+#define QSERDES_COM_RESTRIM_CTRL			0x0bc
+#define QSERDES_COM_RESCODE_DIV_NUM			0x0c4
+#define QSERDES_COM_LOCK_CMP_EN				0x0c8
+#define QSERDES_COM_LOCK_CMP_CFG			0x0cc
+#define QSERDES_COM_DEC_START_MODE0			0x0d0
+#define QSERDES_COM_DEC_START_MODE1			0x0d4
+#define QSERDES_COM_DIV_FRAC_START1_MODE0		0x0dc
+#define QSERDES_COM_DIV_FRAC_START2_MODE0		0x0e0
+#define QSERDES_COM_DIV_FRAC_START3_MODE0		0x0e4
+#define QSERDES_COM_DIV_FRAC_START1_MODE1		0x0e8
+#define QSERDES_COM_DIV_FRAC_START2_MODE1		0x0ec
+#define QSERDES_COM_DIV_FRAC_START3_MODE1		0x0f0
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0		0x108
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0		0x10c
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1		0x110
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1		0x114
+#define QSERDES_COM_VCO_TUNE_CTRL			0x124
+#define QSERDES_COM_VCO_TUNE_MAP			0x128
+#define QSERDES_COM_VCO_TUNE1_MODE0			0x12c
+#define QSERDES_COM_VCO_TUNE2_MODE0			0x130
+#define QSERDES_COM_VCO_TUNE1_MODE1			0x134
+#define QSERDES_COM_VCO_TUNE2_MODE1			0x138
+#define QSERDES_COM_VCO_TUNE_TIMER1			0x144
+#define QSERDES_COM_VCO_TUNE_TIMER2			0x148
+#define QSERDES_COM_BG_CTRL				0x170
+#define QSERDES_COM_CLK_SELECT				0x174
+#define QSERDES_COM_HSCLK_SEL				0x178
+#define QSERDES_COM_CORECLK_DIV				0x184
+#define QSERDES_COM_CORE_CLK_EN				0x18c
+#define QSERDES_COM_C_READY_STATUS			0x190
+#define QSERDES_COM_CMN_CONFIG				0x194
+#define QSERDES_COM_SVS_MODE_CLK_SEL			0x19c
+#define QSERDES_COM_DEBUG_BUS0				0x1a0
+#define QSERDES_COM_DEBUG_BUS1				0x1a4
+#define QSERDES_COM_DEBUG_BUS2				0x1a8
+#define QSERDES_COM_DEBUG_BUS3				0x1ac
+#define QSERDES_COM_DEBUG_BUS_SEL			0x1b0
+#define QSERDES_COM_CORECLK_DIV_MODE1			0x1bc
+
+/* QMP PHY TX registers */
+#define QSERDES_TX_RES_CODE_LANE_OFFSET			0x054
+#define QSERDES_TX_DEBUG_BUS_SEL			0x064
+#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN	0x068
+#define QSERDES_TX_LANE_MODE				0x094
+#define QSERDES_TX_RCV_DETECT_LVL_2			0x0ac
+
+/* QMP PHY RX registers */
+#define QSERDES_RX_UCDR_SO_GAIN_HALF			0x010
+#define QSERDES_RX_UCDR_SO_GAIN				0x01c
+#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN		0x040
+#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE	0x048
+#define QSERDES_RX_RX_TERM_BW				0x090
+#define QSERDES_RX_RX_EQ_GAIN1_LSB			0x0c4
+#define QSERDES_RX_RX_EQ_GAIN1_MSB			0x0c8
+#define QSERDES_RX_RX_EQ_GAIN2_LSB			0x0cc
+#define QSERDES_RX_RX_EQ_GAIN2_MSB			0x0d0
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2		0x0d8
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3		0x0dc
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4		0x0e0
+#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1		0x108
+#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2		0x10c
+#define QSERDES_RX_SIGDET_ENABLES			0x110
+#define QSERDES_RX_SIGDET_CNTRL				0x114
+#define QSERDES_RX_SIGDET_LVL				0x118
+#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL		0x11c
+#define QSERDES_RX_RX_BAND				0x120
+#define QSERDES_RX_RX_INTERFACE_MODE			0x12c
+
+/* QMP PHY PCS registers */
+#define QPHY_SW_RESET					0x00
+#define QPHY_POWER_DOWN_CONTROL				0x04
+#define QPHY_START_CTRL					0x08
+#define QPHY_TXDEEMPH_M6DB_V0				0x24
+#define QPHY_TXDEEMPH_M3P5DB_V0				0x28
+#define QPHY_ENDPOINT_REFCLK_DRIVE			0x54
+#define QPHY_RX_IDLE_DTCT_CNTRL				0x58
+#define QPHY_POWER_STATE_CONFIG1			0x60
+#define QPHY_POWER_STATE_CONFIG2			0x64
+#define QPHY_POWER_STATE_CONFIG4			0x6c
+#define QPHY_LOCK_DETECT_CONFIG1			0x80
+#define QPHY_LOCK_DETECT_CONFIG2			0x84
+#define QPHY_LOCK_DETECT_CONFIG3			0x88
+#define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK		0xa0
+#define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK			0xa4
+
+/* QPHY_SW_RESET bit */
+#define SW_RESET				BIT(0)
+/* QPHY_POWER_DOWN_CONTROL */
+#define SW_PWRDN				BIT(0)
+#define REFCLK_DRV_DSBL				BIT(1)
+/* QPHY_START_CONTROL bits */
+#define SERDES_START				BIT(0)
+#define PCS_START				BIT(1)
+#define PLL_READY_GATE_EN			BIT(3)
+/* QPHY_PCS_STATUS bit */
+#define PHYSTATUS				BIT(6)
+/* QPHY_COM_PCS_READY_STATUS bit */
+#define PCS_READY				BIT(0)
+
+#define PHY_INIT_COMPLETE_TIMEOUT		1000
+#define POWER_DOWN_DELAY_US_MIN			10
+#define POWER_DOWN_DELAY_US_MAX			11
+
+#define MAX_PROP_NAME				32
+
+struct qmp_phy_init_tbl {
+	unsigned int offset;
+	unsigned int val;
+	/*
+	 * register part of layout ?
+	 * if yes, then offset gives index in the reg-layout
+	 */
+	int in_layout;
+};
+#define QMP_PHY_INIT_CFG(o, v)		\
+	{				\
+		.offset = o,		\
+		.val = v,		\
+	}
+#define QMP_PHY_INIT_CFG_L(o, v)	\
+	{				\
+		.offset = o,		\
+		.val = v,		\
+		.in_layout = 1,		\
+	}
+
+/* set of registers with offsets different per-PHY */
+enum qphy_reg_layout {
+	/* Common block control registers */
+	QPHY_COM_SW_RESET,
+	QPHY_COM_POWER_DOWN_CONTROL,
+	QPHY_COM_START_CONTROL,
+	QPHY_COM_PCS_READY_STATUS,
+	/* PCS registers */
+	QPHY_PLL_LOCK_CHK_DLY_TIME,
+	QPHY_FLL_CNTRL1,
+	QPHY_FLL_CNTRL2,
+	QPHY_FLL_CNT_VAL_L,
+	QPHY_FLL_CNT_VAL_H_TOL,
+	QPHY_FLL_MAN_CODE,
+	QPHY_PCS_READY_STATUS,
+};
+
+static const unsigned int pciephy_regs_layout[] = {
+	[QPHY_COM_SW_RESET]		= 0x400,
+	[QPHY_COM_POWER_DOWN_CONTROL]	= 0x404,
+	[QPHY_COM_START_CONTROL]	= 0x408,
+	[QPHY_COM_PCS_READY_STATUS]	= 0x448,
+	[QPHY_PLL_LOCK_CHK_DLY_TIME]	= 0xa8,
+	[QPHY_FLL_CNTRL1]		= 0xc4,
+	[QPHY_FLL_CNTRL2]		= 0xc8,
+	[QPHY_FLL_CNT_VAL_L]		= 0xcc,
+	[QPHY_FLL_CNT_VAL_H_TOL]	= 0xd0,
+	[QPHY_FLL_MAN_CODE]		= 0xd4,
+	[QPHY_PCS_READY_STATUS]		= 0x174,
+};
+
+static const unsigned int usb3phy_regs_layout[] = {
+	[QPHY_FLL_CNTRL1]		= 0xc0,
+	[QPHY_FLL_CNTRL2]		= 0xc4,
+	[QPHY_FLL_CNT_VAL_L]		= 0xc8,
+	[QPHY_FLL_CNT_VAL_H_TOL]	= 0xcc,
+	[QPHY_FLL_MAN_CODE]		= 0xd0,
+	[QPHY_PCS_READY_STATUS]		= 0x17c,
+};
+
+static const struct qmp_phy_init_tbl pciephy_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x42),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x09),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x1a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x33),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
+	QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x15),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM, 0x40),
+};
+
+static const struct qmp_phy_init_tbl pciephy_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
+};
+
+static const struct qmp_phy_init_tbl pciephy_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND, 0x18),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x19),
+};
+
+static const struct qmp_phy_init_tbl pciephy_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL, 0x4c),
+	QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK, 0x01),
+
+	QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME, 0x05),
+
+	QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE, 0x05),
+	QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x02),
+	QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4, 0x00),
+	QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1, 0xa3),
+	QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0, 0x0e),
+};
+
+static const struct qmp_phy_init_tbl usb3phy_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x04),
+	/* PLL and Loop filter settings */
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
+	/* SSC settings */
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl usb3phy_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
+	QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
+};
+
+static const struct qmp_phy_init_tbl usb3phy_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xbb),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
+	QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x18),
+	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
+};
+
+static const struct qmp_phy_init_tbl usb3phy_pcs_tbl[] = {
+	/* FLL settings */
+	QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2, 0x03),
+	QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1, 0x02),
+	QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L, 0x09),
+	QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL, 0x42),
+	QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE, 0x85),
+
+	/* Lock Det settings */
+	QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1, 0xd1),
+	QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2, 0x1f),
+	QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3, 0x47),
+	QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
+};
+
+/* struct qmp_phy_cfg - per-PHY initialization config */
+struct qmp_phy_cfg {
+	/* phy-type - PCIE/UFS/USB */
+	unsigned int type;
+	/* number of lanes provided by phy */
+	int nlanes;
+
+	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
+	const struct qmp_phy_init_tbl *serdes_tbl;
+	int serdes_tbl_num;
+	const struct qmp_phy_init_tbl *tx_tbl;
+	int tx_tbl_num;
+	const struct qmp_phy_init_tbl *rx_tbl;
+	int rx_tbl_num;
+	const struct qmp_phy_init_tbl *pcs_tbl;
+	int pcs_tbl_num;
+
+	/* array of registers with different offsets */
+	const unsigned int *regs;
+
+	unsigned int start_ctrl;
+	unsigned int pwrdn_ctrl;
+	unsigned int mask_pcs_ready;
+	unsigned int mask_com_pcs_ready;
+
+	/* true, if PHY has a separate PHY_COM control block */
+	bool has_phy_com_ctrl;
+	/* true, if PHY has a reset for individual lanes */
+	bool has_lane_rst;
+	/* true, if PHY needs delay after POWER_DOWN */
+	bool has_pwrdn_delay;
+	/* power_down delay in usec */
+	int pwrdn_delay_min;
+	int pwrdn_delay_max;
+};
+
+/**
+ * struct qmp_phy - per-lane phy descriptor
+ *
+ * @phy: generic phy
+ * @tx: iomapped memory space for lane's tx
+ * @rx: iomapped memory space for lane's rx
+ * @pcs: iomapped memory space for lane's pcs
+ * @pipe_clk: pipe lock
+ * @index: lane index
+ * @qmp: QMP phy to which this lane belongs
+ * @lane_rst: lane's reset controller
+ */
+struct qmp_phy {
+	struct phy *phy;
+	void __iomem *tx;
+	void __iomem *rx;
+	void __iomem *pcs;
+	struct clk *pipe_clk;
+	unsigned int index;
+	struct qcom_qmp *qmp;
+	struct reset_control *lane_rst;
+};
+
+/**
+ * struct qcom_qmp - structure holding QMP phy block attributes
+ *
+ * @dev: device
+ * @serdes: iomapped memory space for phy's serdes
+ *
+ * @aux_clk: phy core clock
+ * @cfg_ahb_clk: AHB2PHY interface clock
+ * @ref_clk: reference clock
+ *
+ * @vdda_phy: vdd supply to the phy core block
+ * @vdda_pll: 1.8V vdd supply to ref_clk block
+ * @vddp_ref_clk: vdd supply to specific ref_clk block (Optional)
+ *
+ * @phy_rst: phy reset control
+ * @phycom_rst: phy common reset control
+ * @phycfg_rst: phy ahb cfg reset control (Optional)
+ *
+ * @cfg: phy specific configuration
+ * @phys: array of per-lane phy descriptors
+ * @phy_mutex: mutex lock for PHY common block initialization
+ * @init_count: phy common block initialization count
+ */
+struct qcom_qmp {
+	struct device *dev;
+	void __iomem *serdes;
+
+	struct clk *aux_clk;
+	struct clk *cfg_ahb_clk;
+	struct clk *ref_clk;
+
+	struct regulator *vdda_phy;
+	struct regulator *vdda_pll;
+	struct regulator *vddp_ref_clk;
+
+	struct reset_control *phy_rst;
+	struct reset_control *phycom_rst;
+	struct reset_control *phycfg_rst;
+
+	const struct qmp_phy_cfg *cfg;
+	struct qmp_phy **phys;
+
+	struct mutex phy_mutex;
+	int init_count;
+};
+
+static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl_relaxed(base + offset);
+	reg |= val;
+	writel_relaxed(reg, base + offset);
+
+	/* Make sure that above writes are completed */
+	mb();
+}
+
+static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl_relaxed(base + offset);
+	reg &= ~val;
+	writel_relaxed(reg, base + offset);
+
+	/* Make sure that above writes are completed */
+	mb();
+}
+
+static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
+	.type			= PHY_TYPE_PCIE,
+	.nlanes			= 3,
+
+	.serdes_tbl		= pciephy_serdes_tbl,
+	.serdes_tbl_num		= ARRAY_SIZE(pciephy_serdes_tbl),
+	.tx_tbl			= pciephy_tx_tbl,
+	.tx_tbl_num		= ARRAY_SIZE(pciephy_tx_tbl),
+	.rx_tbl			= pciephy_rx_tbl,
+	.rx_tbl_num		= ARRAY_SIZE(pciephy_rx_tbl),
+	.pcs_tbl		= pciephy_pcs_tbl,
+	.pcs_tbl_num		= ARRAY_SIZE(pciephy_pcs_tbl),
+	.regs			= pciephy_regs_layout,
+	.start_ctrl		= PCS_START | PLL_READY_GATE_EN,
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.mask_com_pcs_ready	= PCS_READY,
+
+	.has_phy_com_ctrl	= true,
+	.has_lane_rst		= true,
+	.has_pwrdn_delay	= true,
+	.pwrdn_delay_min	= POWER_DOWN_DELAY_US_MIN,
+	.pwrdn_delay_max	= POWER_DOWN_DELAY_US_MAX,
+};
+
+static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
+	.type			= PHY_TYPE_USB3,
+	.nlanes			= 1,
+
+	.serdes_tbl		= usb3phy_serdes_tbl,
+	.serdes_tbl_num		= ARRAY_SIZE(usb3phy_serdes_tbl),
+	.tx_tbl			= usb3phy_tx_tbl,
+	.tx_tbl_num		= ARRAY_SIZE(usb3phy_tx_tbl),
+	.rx_tbl			= usb3phy_rx_tbl,
+	.rx_tbl_num		= ARRAY_SIZE(usb3phy_rx_tbl),
+	.pcs_tbl		= usb3phy_pcs_tbl,
+	.pcs_tbl_num		= ARRAY_SIZE(usb3phy_pcs_tbl),
+	.regs			= usb3phy_regs_layout,
+	.start_ctrl		= SERDES_START | PCS_START,
+	.pwrdn_ctrl		= SW_PWRDN,
+	.mask_pcs_ready		= PHYSTATUS,
+};
+
+static void qcom_qmp_phy_configure(void __iomem *base,
+				const unsigned int *regs,
+				const struct qmp_phy_init_tbl tbl[],
+				int num)
+{
+	int i;
+	const struct qmp_phy_init_tbl *t = tbl;
+
+	for (i = 0; i < num; i++, t++) {
+		if (t->in_layout)
+			writel_relaxed(t->val, base + regs[t->offset]);
+		else
+			writel_relaxed(t->val, base + t->offset);
+	}
+
+	/* flush buffered writes */
+	mb();
+}
+
+static int qcom_qmp_phy_poweron(struct phy *phy)
+{
+	struct qmp_phy *qphy = phy_get_drvdata(phy);
+	struct qcom_qmp *qmp = qphy->qmp;
+	int ret;
+
+	dev_vdbg(&phy->dev, "Powering on QMP phy\n");
+
+	ret = regulator_enable(qmp->vdda_phy);
+	if (ret) {
+		dev_err(qmp->dev, "%s: vdda-phy enable failed, err=%d\n",
+				__func__, ret);
+		return ret;
+	}
+
+	ret = regulator_enable(qmp->vdda_pll);
+	if (ret) {
+		dev_err(qmp->dev, "%s: vdda-pll enable failed, err=%d\n",
+				__func__, ret);
+		goto disable_vdda_phy;
+	}
+
+	ret = regulator_enable(qmp->vddp_ref_clk);
+	if (ret) {
+		dev_err(qmp->dev,
+			"%s: vdda-ref-clk enable failed, err=%d\n",
+			__func__, ret);
+		goto disable_vdda_pll;
+	}
+
+	ret = clk_prepare_enable(qmp->ref_clk);
+	if (ret) {
+		dev_err(qmp->dev, "%s: ref_clk enable failed, err=%d\n",
+				__func__, ret);
+		goto disable_vddp_ref_clk;
+	}
+
+	ret = clk_prepare_enable(qphy->pipe_clk);
+	if (ret) {
+		dev_err(qmp->dev, "%s: pipe_clk enable failed, err=%d\n",
+				__func__, ret);
+		goto disable_ref_clk;
+	}
+
+	return 0;
+
+disable_ref_clk:
+	clk_disable_unprepare(qmp->ref_clk);
+disable_vddp_ref_clk:
+	regulator_disable(qmp->vddp_ref_clk);
+disable_vdda_pll:
+	regulator_disable(qmp->vdda_pll);
+disable_vdda_phy:
+	regulator_disable(qmp->vdda_phy);
+	return ret;
+}
+
+static int qcom_qmp_phy_poweroff(struct phy *phy)
+{
+	struct qmp_phy *qphy = phy_get_drvdata(phy);
+	struct qcom_qmp *qmp = qphy->qmp;
+
+	clk_disable_unprepare(qphy->pipe_clk);
+	clk_disable_unprepare(qmp->ref_clk);
+
+	regulator_disable(qmp->vddp_ref_clk);
+	regulator_disable(qmp->vdda_pll);
+	regulator_disable(qmp->vdda_phy);
+
+	return 0;
+}
+
+static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *serdes = qmp->serdes;
+	int ret;
+
+	mutex_lock(&qmp->phy_mutex);
+	if (qmp->init_count++) {
+		mutex_unlock(&qmp->phy_mutex);
+		return 0;
+	}
+
+	ret = reset_control_deassert(qmp->phy_rst);
+	if (ret) {
+		dev_err(qmp->dev, "phy reset deassert failed\n");
+		goto err_rst;
+	}
+
+	ret = reset_control_deassert(qmp->phycom_rst);
+	if (ret) {
+		dev_err(qmp->dev, "common reset deassert failed\n");
+		goto err_com_rst;
+	}
+
+	if (qmp->phycfg_rst) {
+		ret = reset_control_deassert(qmp->phycfg_rst);
+		if (ret) {
+			dev_err(qmp->dev, "ahb cfg reset deassert failed\n");
+			goto err_cfg_rst;
+		}
+	}
+
+	if (cfg->has_phy_com_ctrl)
+		qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
+				SW_PWRDN);
+
+	/* Serdes configuration */
+	qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl,
+				cfg->serdes_tbl_num);
+
+	if (cfg->has_phy_com_ctrl) {
+		void __iomem *status;
+		unsigned int mask, val;
+
+		qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
+				SW_RESET);
+		qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
+				SERDES_START | PCS_START);
+
+		status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS];
+		mask = cfg->mask_com_pcs_ready;
+
+		ret = readl_poll_timeout(status, val, (val & mask), 10,
+						PHY_INIT_COMPLETE_TIMEOUT);
+		if (ret) {
+			dev_err(qmp->dev,
+				"phy common block init timed-out\n");
+			goto err_com_init;
+		}
+	}
+
+	mutex_unlock(&qmp->phy_mutex);
+
+	return 0;
+
+err_com_init:
+	if (qmp->phycfg_rst)
+		reset_control_assert(qmp->phycfg_rst);
+err_cfg_rst:
+	reset_control_assert(qmp->phycom_rst);
+err_com_rst:
+	reset_control_assert(qmp->phy_rst);
+err_rst:
+	mutex_unlock(&qmp->phy_mutex);
+	return ret;
+}
+
+static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *serdes = qmp->serdes;
+
+	mutex_lock(&qmp->phy_mutex);
+	if (--qmp->init_count) {
+		mutex_unlock(&qmp->phy_mutex);
+		return 0;
+	}
+
+	if (cfg->has_phy_com_ctrl) {
+		qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
+				SERDES_START | PCS_START);
+		qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET],
+				SW_RESET);
+		qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
+				SW_PWRDN);
+	}
+
+	if (qmp->phycfg_rst)
+		reset_control_assert(qmp->phycfg_rst);
+
+	reset_control_assert(qmp->phycom_rst);
+	reset_control_assert(qmp->phy_rst);
+
+	mutex_unlock(&qmp->phy_mutex);
+
+	return 0;
+}
+
+/* PHY Initialization */
+static int qcom_qmp_phy_init(struct phy *phy)
+{
+	struct qmp_phy *qphy = phy_get_drvdata(phy);
+	struct qcom_qmp *qmp = qphy->qmp;
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *tx = qphy->tx;
+	void __iomem *rx = qphy->rx;
+	void __iomem *pcs = qphy->pcs;
+	void __iomem *status;
+	unsigned int mask, val;
+	int ret;
+
+	dev_vdbg(qmp->dev, "Initializing QMP phy\n");
+
+	/* enable interface clocks to program phy */
+	ret = clk_prepare_enable(qmp->aux_clk);
+	if (ret) {
+		dev_err(qmp->dev, "failed to enable aux clk, err=%d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(qmp->cfg_ahb_clk);
+	if (ret) {
+		dev_err(qmp->dev, "failed to enable cfg ahb clk, err=%d\n",
+									ret);
+		goto err;
+	}
+
+	ret = qcom_qmp_phy_com_init(qmp);
+	if (ret)
+		goto err_com_init;
+
+	if (cfg->has_lane_rst) {
+		ret = reset_control_deassert(qphy->lane_rst);
+		if (ret) {
+			dev_err(qmp->dev, "lane%d reset deassert failed\n",
+					qphy->index);
+			goto err_lane_rst;
+		}
+	}
+
+	/* Tx, Rx, and PCS configurations */
+	qcom_qmp_phy_configure(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num);
+	qcom_qmp_phy_configure(rx, cfg->regs, cfg->rx_tbl, cfg->rx_tbl_num);
+	qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+
+	/*
+	 * Pull out PHY from POWER DOWN state.
+	 * This is active low enable signal to power-down PHY.
+	 */
+	qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
+
+	if (cfg->has_pwrdn_delay)
+		usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
+
+	/* start SerDes and Phy-Coding-Sublayer */
+	qphy_setbits(pcs, QPHY_START_CTRL, cfg->start_ctrl);
+
+	/* Pull PHY out of reset state */
+	qphy_clrbits(pcs, QPHY_SW_RESET, SW_RESET);
+
+	status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
+	mask = cfg->mask_pcs_ready;
+
+	ret = readl_poll_timeout(status, val, !(val & mask), 1,
+					PHY_INIT_COMPLETE_TIMEOUT);
+	if (ret) {
+		dev_err(qmp->dev, "phy initialization timed-out\n");
+		goto err_pcs_ready;
+	}
+
+	return ret;
+
+err_pcs_ready:
+	if (cfg->has_lane_rst)
+		reset_control_assert(qphy->lane_rst);
+err_lane_rst:
+	qcom_qmp_phy_com_exit(qmp);
+err_com_init:
+	clk_disable_unprepare(qmp->cfg_ahb_clk);
+err:
+	clk_disable_unprepare(qmp->aux_clk);
+	return ret;
+}
+
+static int qcom_qmp_phy_exit(struct phy *phy)
+{
+	struct qmp_phy *qphy = phy_get_drvdata(phy);
+	struct qcom_qmp *qmp = qphy->qmp;
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+
+	/* PHY reset */
+	qphy_setbits(qphy->pcs, QPHY_SW_RESET, SW_RESET);
+
+	/* stop SerDes and Phy-Coding-Sublayer */
+	qphy_clrbits(qphy->pcs, QPHY_START_CTRL, cfg->start_ctrl);
+
+	/* Put PHY into POWER DOWN state: active low */
+	qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL,
+			cfg->pwrdn_ctrl);
+
+	if (cfg->has_lane_rst)
+		reset_control_assert(qphy->lane_rst);
+
+	qcom_qmp_phy_com_exit(qmp);
+
+	clk_disable_unprepare(qmp->aux_clk);
+	clk_disable_unprepare(qmp->cfg_ahb_clk);
+
+	return 0;
+}
+
+static int qcom_qmp_phy_regulator_init(struct device *dev)
+{
+	struct qcom_qmp *qmp = dev_get_drvdata(dev);
+	int ret;
+
+	qmp->vdda_phy = devm_regulator_get(dev, "vdda-phy");
+	if (IS_ERR(qmp->vdda_phy)) {
+		ret = PTR_ERR(qmp->vdda_phy);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to get vdda-phy, %d\n", ret);
+		return ret;
+	}
+
+	qmp->vdda_pll = devm_regulator_get(dev, "vdda-pll");
+	if (IS_ERR(qmp->vdda_pll)) {
+		ret = PTR_ERR(qmp->vdda_pll);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to get vdda-pll, %d\n", ret);
+		return ret;
+	}
+
+	/* optional regulator */
+	qmp->vddp_ref_clk = devm_regulator_get(dev, "vddp-ref-clk");
+	if (IS_ERR(qmp->vddp_ref_clk)) {
+		if (PTR_ERR(qmp->vddp_ref_clk) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		dev_dbg(dev, "failed to get vddp-ref-clk, %d\n", ret);
+	}
+
+	return 0;
+}
+
+static int qcom_qmp_phy_clk_init(struct device *dev)
+{
+	struct qcom_qmp *qmp = dev_get_drvdata(dev);
+	int ret;
+
+	qmp->aux_clk = devm_clk_get(dev, "aux");
+	if (IS_ERR(qmp->aux_clk)) {
+		ret = PTR_ERR(qmp->aux_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to get aux_clk, %d\n", ret);
+		return ret;
+	}
+
+	qmp->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb");
+	if (IS_ERR(qmp->cfg_ahb_clk)) {
+		ret = PTR_ERR(qmp->cfg_ahb_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to get cfg_ahb_clk, %d\n", ret);
+		return ret;
+	}
+
+	qmp->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(qmp->ref_clk)) {
+		ret = PTR_ERR(qmp->ref_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to get ref_clk, %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct phy *qcom_qmp_phy_xlate(struct device *dev,
+					struct of_phandle_args *args)
+{
+	struct qcom_qmp *qmp = dev_get_drvdata(dev);
+	int i;
+
+	if (WARN_ON(args->args_count <= 0))
+		return ERR_PTR(-EINVAL);
+	if (WARN_ON(args->args[0] >= qmp->cfg->nlanes))
+		return ERR_PTR(-EINVAL);
+
+	i = args->args[0];
+
+	return qmp->phys[i]->phy;
+}
+
+/*
+ * Register a fixed rate pipe clock.
+ *
+ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
+ * controls it. The <s>_pipe_clk coming out of the GCC is requested
+ * by the PHY driver for its operations.
+ * We register the <s>_pipe_clksrc here. The gcc driver takes care
+ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
+ * Below picture shows this relationship.
+ *
+ *         +---------------+
+ *         |   PHY block   |<<---------------------------------------+
+ *         |               |                                         |
+ *         |   +-------+   |                   +-----+               |
+ *   I/P---^-->|  PLL  |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
+ *    clk  |   +-------+   |                   +-----+
+ *         +---------------+
+ */
+static int phy_pipe_clk_register(struct qcom_qmp *qmp, int id)
+{
+	char name[24];
+	struct clk_fixed_rate *fixed;
+	struct clk_init_data init = { };
+	int ret;
+
+	switch (qmp->cfg->type) {
+	case PHY_TYPE_USB3:
+		snprintf(name, sizeof(name), "usb3_phy_pipe_clk_src");
+		break;
+	case PHY_TYPE_PCIE:
+		snprintf(name, sizeof(name), "pcie_%d_pipe_clk_src", id);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
+	if (!fixed)
+		return -ENOMEM;
+
+	init.name = name;
+	init.ops = &clk_fixed_rate_ops;
+
+	/* controllers using QMP phys use 125MHz pipe clock interface */
+	fixed->fixed_rate = 125000000;
+	fixed->hw.init = &init;
+
+	ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
+
+	return ret;
+}
+
+static const struct phy_ops qcom_qmp_phy_gen_ops = {
+	.init		= qcom_qmp_phy_init,
+	.exit		= qcom_qmp_phy_exit,
+	.power_on	= qcom_qmp_phy_poweron,
+	.power_off	= qcom_qmp_phy_poweroff,
+	.owner		= THIS_MODULE,
+};
+
+static
+struct qmp_phy *qcom_qmp_phy_create(struct platform_device *pdev, int id)
+{
+	struct device *dev = &pdev->dev;
+	struct qcom_qmp *qmp = dev_get_drvdata(dev);
+	struct phy *generic_phy;
+	struct qmp_phy *qphy;
+	struct resource *res;
+	void __iomem *base;
+	char prop_name[MAX_PROP_NAME];
+	unsigned int lane_offsets[3];
+	int ret;
+
+	/* mem resources from index 1 to N for N number of lanes */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return ERR_CAST(base);
+
+	qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
+	if (!qphy)
+		return ERR_PTR(-ENOMEM);
+
+	/*
+	 * read offsets to Tx, Rx, and PCS blocks into a u32 array:
+	 * +------------------------------------+
+	 * | tx offset | rx offset | pcs offset |
+	 * +------------------------------------+
+	 */
+	ret = of_property_read_u32_array(dev->of_node, "lane-offsets",
+						   lane_offsets, 3);
+	if (ret) {
+		dev_err(dev, "failed to get tx/rx/pcs offsets for lane%d\n",
+			id);
+		return ERR_PTR(ret);
+	}
+
+	qphy->tx = base + lane_offsets[0];
+	qphy->rx = base + lane_offsets[1];
+	qphy->pcs = base + lane_offsets[2];
+
+	/*
+	 * Get PHY's Pipe clock, if any; USB3 and PCIe are PIPE3
+	 * based phys, so they essentially have pipe clock. So,
+	 * we return error in case phy is USB3 or PIPE type.
+	 * Otherwise, we initialize pipe clock to NULL for
+	 * all phys that don't need this.
+	 */
+	snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
+	qphy->pipe_clk = devm_clk_get(dev, prop_name);
+	if (IS_ERR(qphy->pipe_clk)) {
+		if (qmp->cfg->type == PHY_TYPE_PCIE ||
+		    qmp->cfg->type == PHY_TYPE_USB3) {
+			ret = PTR_ERR(qphy->pipe_clk);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev,
+					"failed to get lane%d pipe_clk, %d\n",
+					id, ret);
+			return ERR_PTR(ret);
+		}
+		qphy->pipe_clk = NULL;
+	}
+
+	/* Get lane reset, if any */
+	if (qmp->cfg->has_lane_rst) {
+		snprintf(prop_name, sizeof(prop_name), "lane%d", id);
+		qphy->lane_rst = devm_reset_control_get(dev,
+							    prop_name);
+		if (IS_ERR(qphy->lane_rst)) {
+			dev_err(dev, "failed to get lane%d reset\n", id);
+			return ERR_CAST(qphy->lane_rst);
+		}
+	}
+
+	generic_phy = devm_phy_create(dev, NULL, &qcom_qmp_phy_gen_ops);
+	if (IS_ERR(generic_phy)) {
+		ret = PTR_ERR(generic_phy);
+		dev_err(dev, "failed to create qphy %d\n", ret);
+		return ERR_PTR(ret);
+	}
+
+	qphy->phy = generic_phy;
+	qphy->index = id;
+	qphy->qmp = qmp;
+	phy_set_drvdata(generic_phy, qphy);
+
+	return qphy;
+}
+
+static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
+	{
+		.compatible = "qcom,msm8996-qmp-pcie-phy",
+		.data = &msm8996_pciephy_cfg,
+	}, {
+		.compatible = "qcom,msm8996-qmp-usb3-phy",
+		.data = &msm8996_usb3phy_cfg,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
+
+static int qcom_qmp_phy_probe(struct platform_device *pdev)
+{
+	struct qcom_qmp *qmp;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	struct resource *res;
+	void __iomem *base;
+	int ret;
+	int id;
+
+	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
+	if (!qmp)
+		return -ENOMEM;
+
+	qmp->dev = dev;
+	dev_set_drvdata(dev, qmp);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	/* per PHY serdes; usually located at base address */
+	qmp->serdes = base;
+
+	mutex_init(&qmp->phy_mutex);
+
+	/* Get the specific init parameters of QMP phy */
+	qmp->cfg = of_device_get_match_data(dev);
+
+	ret = qcom_qmp_phy_clk_init(dev);
+	if (ret)
+		return ret;
+
+	ret = qcom_qmp_phy_regulator_init(dev);
+	if (ret)
+		return ret;
+
+	qmp->phy_rst = devm_reset_control_get(dev, "phy");
+	if (IS_ERR(qmp->phy_rst)) {
+		dev_err(dev, "failed to get phy core reset\n");
+		return PTR_ERR(qmp->phy_rst);
+	}
+
+	qmp->phycom_rst = devm_reset_control_get(dev, "common");
+	if (IS_ERR(qmp->phycom_rst)) {
+		dev_err(dev, "failed to get phy common reset\n");
+		return PTR_ERR(qmp->phycom_rst);
+	}
+
+	qmp->phycfg_rst = devm_reset_control_get(dev, "cfg");
+	if (IS_ERR(qmp->phycfg_rst)) {
+		dev_dbg(dev, "failed to get phy ahb cfg reset\n");
+		qmp->phycfg_rst = NULL;
+	}
+
+
+	qmp->phys = devm_kcalloc(dev, qmp->cfg->nlanes,
+					sizeof(*qmp->phys), GFP_KERNEL);
+	if (!qmp->phys)
+		return -ENOMEM;
+
+	for (id = 0; id < qmp->cfg->nlanes; id++) {
+		/* Create per-lane phy */
+		qmp->phys[id] = qcom_qmp_phy_create(pdev, id);
+		if (IS_ERR(qmp->phys[id])) {
+			dev_err(dev, "failed to create lane%d phy, %d\n",
+				id, ret);
+			return PTR_ERR(qmp->phys[id]);
+		}
+
+		/*
+		 * Register the pipe clock provided by phy.
+		 * See function description to see details of this pipe clock.
+		 */
+		ret = phy_pipe_clk_register(qmp, id);
+		if (ret) {
+			dev_err(qmp->dev,
+				"failed to register pipe clock source\n");
+			return ret;
+		}
+	}
+
+	phy_provider = devm_of_phy_provider_register(dev, qcom_qmp_phy_xlate);
+	if (IS_ERR(phy_provider)) {
+		ret = PTR_ERR(phy_provider);
+		dev_err(dev, "failed to register qphy, %d\n", ret);
+	}
+
+	return ret;
+}
+
+static struct platform_driver qcom_qmp_phy_driver = {
+	.probe		= qcom_qmp_phy_probe,
+	.driver = {
+		.name	= "qcom-qmp-phy",
+		.of_match_table = of_match_ptr(qcom_qmp_phy_of_match_table),
+	},
+};
+
+module_platform_driver(qcom_qmp_phy_driver);
+
+MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
+MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* Re: [PATCH v4 8/9] ARM: dts: stm32f4: Add external I2S clock
From: Alexandre Torgue @ 2017-01-10 10:59 UTC (permalink / raw)
  To: Gabriel FERNANDEZ, Rob Herring, Mark Rutland, Russell King,
	Maxime Coquelin, Michael Turquette, Stephen Boyd, Nicolas Pitre,
	Arnd Bergmann, daniel.thompson@linaro.org,
	andrea.merello@gmail.com, radoslaw.pietrzyk@gmail.com
  Cc: devicetree@vger.kernel.org, Amelie DELAUNAY, kernel@stlinux.com,
	Olivier BIDEAU, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
	Ludovic BARRE
In-Reply-To: <1481638820-29324-9-git-send-email-gabriel.fernandez@st.com>

Hi

On 12/13/2016 03:20 PM, Gabriel FERNANDEZ wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch adds an external I2S clock in the DT.
> The I2S clock could be derived from an external I2S clock or by I2S pll.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
>  arch/arm/boot/dts/stm32f429.dtsi | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
> index e4dae0e..7c7dfbd 100644
> --- a/arch/arm/boot/dts/stm32f429.dtsi
> +++ b/arch/arm/boot/dts/stm32f429.dtsi
> @@ -68,6 +68,12 @@
>  			compatible = "fixed-clock";
>  			clock-frequency = <32000>;
>  		};
> +
> +		clk_i2s_ckin: i2s-ckin {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <0>;
> +		};
>  	};
>
>  	soc {
> @@ -362,7 +368,7 @@
>  			#clock-cells = <2>;
>  			compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
>  			reg = <0x40023800 0x400>;
> -			clocks = <&clk_hse>;
> +			clocks = <&clk_hse>, <&clk_i2s_ckin>;
>  			st,syscfg = <&pwrcfg>;
>  		};
>
>
Applied on stm32-dt-for-v4.11

Thanks

^ permalink raw reply

* Re: [PATCH v4 9/9] ARM: dts: stm32f4: Include auxiliary stm32fx clock definition
From: Alexandre Torgue @ 2017-01-10 10:59 UTC (permalink / raw)
  To: Gabriel FERNANDEZ, Rob Herring, Mark Rutland, Russell King,
	Maxime Coquelin, Michael Turquette, Stephen Boyd, Nicolas Pitre,
	Arnd Bergmann, daniel.thompson@linaro.org,
	andrea.merello@gmail.com, radoslaw.pietrzyk@gmail.com
  Cc: devicetree@vger.kernel.org, Amelie DELAUNAY, kernel@stlinux.com,
	Olivier BIDEAU, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
	Ludovic BARRE
In-Reply-To: <1481638820-29324-10-git-send-email-gabriel.fernandez@st.com>

hi

On 12/13/2016 03:20 PM, Gabriel FERNANDEZ wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch include auxiliary clock definition (clocks which are not derived
> from system clock.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
>  arch/arm/boot/dts/stm32f429.dtsi | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
> index 7c7dfbd..041e3fc 100644
> --- a/arch/arm/boot/dts/stm32f429.dtsi
> +++ b/arch/arm/boot/dts/stm32f429.dtsi
> @@ -48,6 +48,7 @@
>  #include "skeleton.dtsi"
>  #include "armv7-m.dtsi"
>  #include <dt-bindings/pinctrl/stm32f429-pinfunc.h>
> +#include <dt-bindings/clock/stm32fx-clock.h>
>
>  / {
>  	clocks {
>
Applied on stm32-dt-for-v4.11

Thanks

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox