All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kishon Vijay Abraham I <kishon@ti.com>
To: Ray Jui <rjui@broadcom.com>
Cc: Arnd Bergmann <arnd@arndb.de>, <linux-kernel@vger.kernel.org>,
	"JD (Jiandong) Zheng" <jdzheng@broadcom.com>,
	Arun Parameswaran <arunp@broadcom.com>,
	<bcm-kernel-feedback-list@broadcom.com>
Subject: Re: [PATCH v5 2/2] phy: cygnus: pcie: Add Cygnus PCIe PHY support
Date: Tue, 6 Oct 2015 19:55:53 +0530	[thread overview]
Message-ID: <5613D9F1.2040502@ti.com> (raw)
In-Reply-To: <1442855838-23042-3-git-send-email-rjui@broadcom.com>

Hi,

On Monday 21 September 2015 10:47 PM, Ray Jui wrote:
> This patch adds the PCIe PHY support for the Broadcom PCIe RC interface
> on Cygnus
> 
> Signed-off-by: Ray Jui <rjui@broadcom.com>
> Reviewed-by: Arun Parameswaran <aparames@broadcom.com>
> Reviewed-by: JD (Jiandong) Zheng <jdzheng@broadcom.com>
> Reviewed-by: Scott Branden <sbranden@broadcom.com>


merged this driver to linux-phy tree. Can you send a separate patch
adding yourself as the maintainer of this driver?

Thanks
Kishon

> ---
>  drivers/phy/Kconfig               |   9 ++
>  drivers/phy/Makefile              |   1 +
>  drivers/phy/phy-bcm-cygnus-pcie.c | 213 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 223 insertions(+)
>  create mode 100644 drivers/phy/phy-bcm-cygnus-pcie.c
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 47da573..947bae2 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -371,4 +371,13 @@ config PHY_BRCMSTB_SATA
>  	  Enable this to support the SATA3 PHY on 28nm Broadcom STB SoCs.
>  	  Likely useful only with CONFIG_SATA_BRCMSTB enabled.
>  
> +config PHY_CYGNUS_PCIE
> +	tristate "Broadcom Cygnus PCIe PHY driver"
> +	depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST)
> +	select GENERIC_PHY
> +	default ARCH_BCM_CYGNUS
> +	help
> +	  Enable this to support the Broadcom Cygnus PCIe PHY.
> +	  If unsure, say N.
> +
>  endmenu
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index a5b18c1..fdce78d 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -46,3 +46,4 @@ obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
>  obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
>  obj-$(CONFIG_PHY_BRCMSTB_SATA)		+= phy-brcmstb-sata.o
>  obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
> +obj-$(CONFIG_PHY_CYGNUS_PCIE)		+= phy-bcm-cygnus-pcie.o
> diff --git a/drivers/phy/phy-bcm-cygnus-pcie.c b/drivers/phy/phy-bcm-cygnus-pcie.c
> new file mode 100644
> index 0000000..7ad72b7
> --- /dev/null
> +++ b/drivers/phy/phy-bcm-cygnus-pcie.c
> @@ -0,0 +1,213 @@
> +/*
> + * Copyright (C) 2015 Broadcom Corporation
> + *
> + * 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 version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +
> +#define PCIE_CFG_OFFSET         0x00
> +#define PCIE1_PHY_IDDQ_SHIFT    10
> +#define PCIE0_PHY_IDDQ_SHIFT    2
> +
> +enum cygnus_pcie_phy_id {
> +	CYGNUS_PHY_PCIE0 = 0,
> +	CYGNUS_PHY_PCIE1,
> +	MAX_NUM_PHYS,
> +};
> +
> +struct cygnus_pcie_phy_core;
> +
> +/**
> + * struct cygnus_pcie_phy - Cygnus PCIe PHY device
> + * @core: pointer to the Cygnus PCIe PHY core control
> + * @id: internal ID to identify the Cygnus PCIe PHY
> + * @phy: pointer to the kernel PHY device
> + */
> +struct cygnus_pcie_phy {
> +	struct cygnus_pcie_phy_core *core;
> +	enum cygnus_pcie_phy_id id;
> +	struct phy *phy;
> +};
> +
> +/**
> + * struct cygnus_pcie_phy_core - Cygnus PCIe PHY core control
> + * @dev: pointer to device
> + * @base: base register
> + * @lock: mutex to protect access to individual PHYs
> + * @phys: pointer to Cygnus PHY device
> + */
> +struct cygnus_pcie_phy_core {
> +	struct device *dev;
> +	void __iomem *base;
> +	struct mutex lock;
> +	struct cygnus_pcie_phy phys[MAX_NUM_PHYS];
> +};
> +
> +static int cygnus_pcie_power_config(struct cygnus_pcie_phy *phy, bool enable)
> +{
> +	struct cygnus_pcie_phy_core *core = phy->core;
> +	unsigned shift;
> +	u32 val;
> +
> +	mutex_lock(&core->lock);
> +
> +	switch (phy->id) {
> +	case CYGNUS_PHY_PCIE0:
> +		shift = PCIE0_PHY_IDDQ_SHIFT;
> +		break;
> +
> +	case CYGNUS_PHY_PCIE1:
> +		shift = PCIE1_PHY_IDDQ_SHIFT;
> +		break;
> +
> +	default:
> +		mutex_unlock(&core->lock);
> +		dev_err(core->dev, "PCIe PHY %d invalid\n", phy->id);
> +		return -EINVAL;
> +	}
> +
> +	if (enable) {
> +		val = readl(core->base + PCIE_CFG_OFFSET);
> +		val &= ~BIT(shift);
> +		writel(val, core->base + PCIE_CFG_OFFSET);
> +		/*
> +		 * Wait 50 ms for the PCIe Serdes to stabilize after the analog
> +		 * front end is brought up
> +		 */
> +		msleep(50);
> +	} else {
> +		val = readl(core->base + PCIE_CFG_OFFSET);
> +		val |= BIT(shift);
> +		writel(val, core->base + PCIE_CFG_OFFSET);
> +	}
> +
> +	mutex_unlock(&core->lock);
> +	dev_dbg(core->dev, "PCIe PHY %d %s\n", phy->id,
> +		enable ? "enabled" : "disabled");
> +	return 0;
> +}
> +
> +static int cygnus_pcie_phy_power_on(struct phy *p)
> +{
> +	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);
> +
> +	return cygnus_pcie_power_config(phy, true);
> +}
> +
> +static int cygnus_pcie_phy_power_off(struct phy *p)
> +{
> +	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);
> +
> +	return cygnus_pcie_power_config(phy, false);
> +}
> +
> +static struct phy_ops cygnus_pcie_phy_ops = {
> +	.power_on = cygnus_pcie_phy_power_on,
> +	.power_off = cygnus_pcie_phy_power_off,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int cygnus_pcie_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->of_node, *child;
> +	struct cygnus_pcie_phy_core *core;
> +	struct phy_provider *provider;
> +	struct resource *res;
> +	unsigned cnt = 0;
> +
> +	if (of_get_child_count(node) == 0) {
> +		dev_err(dev, "PHY no child node\n");
> +		return -ENODEV;
> +	}
> +
> +	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
> +	if (!core)
> +		return -ENOMEM;
> +
> +	core->dev = dev;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	core->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(core->base))
> +		return PTR_ERR(core->base);
> +
> +	mutex_init(&core->lock);
> +
> +	for_each_available_child_of_node(node, child) {
> +		unsigned int id;
> +		struct cygnus_pcie_phy *p;
> +
> +		if (of_property_read_u32(child, "reg", &id)) {
> +			dev_err(dev, "missing reg property for %s\n",
> +				child->name);
> +			return -EINVAL;
> +		}
> +
> +		if (id >= MAX_NUM_PHYS) {
> +			dev_err(dev, "invalid PHY id: %u\n", id);
> +			return -EINVAL;
> +		}
> +
> +		if (core->phys[id].phy) {
> +			dev_err(dev, "duplicated PHY id: %u\n", id);
> +			return -EINVAL;
> +		}
> +
> +		p = &core->phys[id];
> +		p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
> +		if (IS_ERR(p->phy)) {
> +			dev_err(dev, "failed to create PHY\n");
> +			return PTR_ERR(p->phy);
> +		}
> +
> +		p->core = core;
> +		p->id = id;
> +		phy_set_drvdata(p->phy, p);
> +		cnt++;
> +	}
> +
> +	dev_set_drvdata(dev, core);
> +
> +	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	if (IS_ERR(provider)) {
> +		dev_err(dev, "failed to register PHY provider\n");
> +		return PTR_ERR(provider);
> +	}
> +
> +	dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id cygnus_pcie_phy_match_table[] = {
> +	{ .compatible = "brcm,cygnus-pcie-phy" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, cygnus_pcie_phy_match_table);
> +
> +static struct platform_driver cygnus_pcie_phy_driver = {
> +	.driver = {
> +		.name = "cygnus-pcie-phy",
> +		.of_match_table = cygnus_pcie_phy_match_table,
> +	},
> +	.probe = cygnus_pcie_phy_probe,
> +};
> +module_platform_driver(cygnus_pcie_phy_driver);
> +
> +MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
> +MODULE_DESCRIPTION("Broadcom Cygnus PCIe PHY driver");
> +MODULE_LICENSE("GPL v2");
> 

  reply	other threads:[~2015-10-06 14:26 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-21 17:17 [PATCH v5 0/2] Add Cygnus PCIe Serdes/PHY support Ray Jui
2015-09-21 17:17 ` [PATCH v5 1/2] dt-bindings: Add Cygnus PCIe PHY binding doc Ray Jui
2015-09-21 17:17 ` [PATCH v5 2/2] phy: cygnus: pcie: Add Cygnus PCIe PHY support Ray Jui
2015-10-06 14:25   ` Kishon Vijay Abraham I [this message]
2015-10-06 17:13     ` Ray Jui
2015-10-06 19:20       ` Kishon Vijay Abraham I
2015-10-06 19:23         ` Florian Fainelli
2015-10-06 19:25           ` Kishon Vijay Abraham I
2015-10-06 19:23         ` Ray Jui
2015-10-06 19:25           ` Kishon Vijay Abraham I
2015-09-28 16:03 ` [PATCH v5 0/2] Add Cygnus PCIe Serdes/PHY support Ray Jui
2015-09-29 13:24   ` Kishon Vijay Abraham I

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5613D9F1.2040502@ti.com \
    --to=kishon@ti.com \
    --cc=arnd@arndb.de \
    --cc=arunp@broadcom.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=jdzheng@broadcom.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rjui@broadcom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.