From: Kishon Vijay Abraham I <kishon@ti.com>
To: Ray Jui <rjui@broadcom.com>
Cc: <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 2/5] phy: iproc-mdio: Initial iProc MDC/MDIO support
Date: Thu, 21 May 2015 18:42:53 +0530 [thread overview]
Message-ID: <555DD9D5.3000206@ti.com> (raw)
In-Reply-To: <1432085014-20758-3-git-send-email-rjui@broadcom.com>
Hi,
On Wednesday 20 May 2015 06:53 AM, Ray Jui wrote:
> This adds the support for the iProc MDC/MDIO interface. Multiple iProc
> SoCs contain the MDC/MDIO interface that can be used for the host to
> communicate with various Serdes/PHYs including Ethernet, PCIe, USB, etc.
the term phy used in this driver is misleading. It's not a PHY actually.
This sounds more like a bus driver to me and should be present in drivers/bus?
Thanks
Kishon
>
> 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>
> ---
> drivers/phy/Kconfig | 12 ++
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-iproc-mdio.c | 249 ++++++++++++++++++++++++++++++++++++
> include/linux/phy/iproc_mdio_phy.h | 22 ++++
> 4 files changed, 284 insertions(+)
> create mode 100644 drivers/phy/phy-iproc-mdio.c
> create mode 100644 include/linux/phy/iproc_mdio_phy.h
>
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index a53bd5b..2664285 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -52,6 +52,18 @@ config PHY_EXYNOS_MIPI_VIDEO
> Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
> and EXYNOS SoCs.
>
> +config PHY_IPROC_MDIO
> + bool "Broadcom iProc MDC/MDIO driver"
> + depends on ARCH_BCM_IPROC
> + default ARCH_BCM_IPROC
> + help
> + Enable this to support the iProc generic MDC/MDIO interface found
> + in various iProc based SoCs. The generic MDC/MDIO interface can be
> + used to communicate with various types of Serdes/PHYs including
> + Ethernet, PCIe, USB, and etc.
> +
> + If unsure, say N.
> +
> config PHY_MVEBU_SATA
> def_bool y
> depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index f126251..d989dd7b 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
> obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
> obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o
> obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o
> +obj-$(CONFIG_PHY_IPROC_MDIO) += phy-iproc-mdio.o
> obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
> obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
> obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
> diff --git a/drivers/phy/phy-iproc-mdio.c b/drivers/phy/phy-iproc-mdio.c
> new file mode 100644
> index 0000000..a37e92f
> --- /dev/null
> +++ b/drivers/phy/phy-iproc-mdio.c
> @@ -0,0 +1,249 @@
> +/*
> + * 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/clk.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/phy/iproc_mdio_phy.h>
> +
> +#define MDIO_TIMEOUT_MSEC 10
> +
> +#define MDC_CTRL_OFFSET 0x000
> +
> +#define MDC_CTRL_DIV_SHIFT 0
> +#define MDC_CTRL_DIV_WIDTH 7
> +#define MDC_MAX_DIV (BIT(MDC_CTRL_DIV_WIDTH) - 1)
> +#define MDC_CTRL_PRE_SHIFT 7
> +#define MDC_CTRL_BUSY_SHIFT 8
> +#define MDC_CTRL_EXT_SHIFT 9
> +#define MDC_CTRL_BTP_SHIFT 10
> +
> +#define MDC_DATA_OFFSET 0x004
> +
> +#define MDC_DATA_SHIFT 0
> +#define MDC_DATA_MASK 0xffff
> +
> +#define MDC_DATA_TA_SHIFT 16
> +#define MDC_DATA_TA_VAL 2
> +
> +#define MDC_DATA_RA_SHIFT 18
> +#define MDC_DATA_RA_WIDTH 5
> +#define MDC_MAX_RA (BIT(MDC_DATA_RA_WIDTH) - 1)
> +
> +#define MDC_DATA_PA_SHIFT 23
> +#define MDC_DATA_PA_WIDTH 5
> +#define MDC_MAX_PA (BIT(MDC_DATA_PA_WIDTH) - 1)
> +
> +#define MDC_DATA_OP_SHIFT 28
> +#define MDC_DATA_OP_WRITE 1
> +#define MDC_DATA_OP_READ 2
> +
> +#define MDC_DATA_SB_SHIFT 30
> +
> +/**
> + * struct iproc_mdc - iProc MDC/MDIO device
> + * @dev: pointer to device
> + * @base: MDC controller register base pointer
> + * @lock: mutex to protect access to the MDC device
> + * @is_ready: flag to indicate the driver has been initialized and is ready for
> + * use
> + */
> +struct iproc_mdc {
> + struct device *dev;
> + void __iomem *base;
> + struct mutex lock;
> + bool is_ready;
> +};
> +
> +static struct iproc_mdc iproc_mdc;
> +
> +static inline int iproc_mdio_check_params(unsigned clk_div, unsigned pa,
> + unsigned ra)
> +{
> + if (clk_div > MDC_MAX_DIV || pa > MDC_MAX_PA || ra > MDC_MAX_RA)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static inline int iproc_mdio_wait_for_idle(void __iomem *base)
> +{
> + u32 val;
> + unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT_MSEC);
> +
> + while (!time_after(jiffies, timeout)) {
> + val = readl(base + MDC_CTRL_OFFSET);
> + if ((val & BIT(MDC_CTRL_BUSY_SHIFT)) == 0)
> + return 0;
> +
> + cpu_relax();
> + }
> +
> + return -ETIMEDOUT;
> +}
> +
> +static inline void iproc_mdio_config_clk(void __iomem *base, unsigned clk_div)
> +{
> + u32 val;
> +
> + val = (clk_div << MDC_CTRL_DIV_SHIFT) | BIT(MDC_CTRL_PRE_SHIFT);
> + writel(val, base + MDC_CTRL_OFFSET);
> +}
> +
> +static int iproc_mdio_read_write(void __iomem *base, bool dir_is_write,
> + unsigned clk_div, unsigned pa, unsigned ra,
> + u16 *data)
> +{
> + int ret;
> + u32 val;
> +
> + ret = iproc_mdio_check_params(clk_div, pa, ra);
> + if (ret)
> + return ret;
> +
> + ret = iproc_mdio_wait_for_idle(base);
> + if (ret)
> + return ret;
> +
> + iproc_mdio_config_clk(base, clk_div);
> +
> + ret = iproc_mdio_wait_for_idle(base);
> + if (ret)
> + return ret;
> +
> + val = (MDC_DATA_TA_VAL << MDC_DATA_TA_SHIFT) |
> + (ra << MDC_DATA_RA_SHIFT) |
> + (pa << MDC_DATA_PA_SHIFT) |
> + BIT(MDC_DATA_SB_SHIFT);
> +
> + if (dir_is_write) {
> + val |= (MDC_DATA_OP_WRITE << MDC_DATA_OP_SHIFT);
> + val |= ((u32)(*data) & MDC_DATA_MASK);
> + } else {
> + val |= (MDC_DATA_OP_READ << MDC_DATA_OP_SHIFT);
> + }
> +
> + writel(val, base + MDC_DATA_OFFSET);
> +
> + ret = iproc_mdio_wait_for_idle(base);
> + if (ret)
> + return ret;
> +
> + if (!dir_is_write) {
> + val = readl(base + MDC_DATA_OFFSET) & MDC_DATA_MASK;
> + *data = (u16)val;
> + }
> +
> + return 0;
> +}
> +
> +
> +/**
> + * iproc_mdio_read() - read from a PHY register through the MDC interface
> + *
> + * @clk_div: MDC clock divisor
> + * @phy_addr: MDC PHY address
> + * @reg_addr: PHY register address
> + * @data: pointer to the memory where data will be stored
> + */
> +int iproc_mdio_read(unsigned clk_div, unsigned phy_addr, unsigned reg_addr,
> + u16 *data)
> +{
> + int ret;
> + struct iproc_mdc *mdc = &iproc_mdc;
> +
> + if (!mdc->is_ready)
> + return -ENODEV;
> +
> + mutex_lock(&mdc->lock);
> + ret = iproc_mdio_read_write(mdc->base, false, clk_div, phy_addr,
> + reg_addr, data);
> + if (ret)
> + dev_err(mdc->dev, "mdio read failed\n");
> + mutex_unlock(&mdc->lock);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(iproc_mdio_read);
> +
> +/**
> + * iproc_mdio_write() - write to a PHY register through the MDC interface
> + *
> + * @clk_div: MDC clock divisor
> + * @phy_addr: MDC PHY address
> + * @reg_addr: PHY register address
> + * @data: data value to be written to the PHY register
> + */
> +int iproc_mdio_write(unsigned clk_div, unsigned phy_addr, unsigned reg_addr,
> + u16 data)
> +{
> + int ret;
> + struct iproc_mdc *mdc = &iproc_mdc;
> +
> + if (!mdc->is_ready)
> + return -ENODEV;
> +
> + mutex_lock(&mdc->lock);
> + ret = iproc_mdio_read_write(mdc->base, true, clk_div, phy_addr,
> + reg_addr, &data);
> + if (ret)
> + dev_err(mdc->dev, "mdio write failed\n");
> + mutex_unlock(&mdc->lock);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(iproc_mdio_write);
> +
> +static int iproc_mdio_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct iproc_mdc *mdc = &iproc_mdc;
> + struct resource *res;
> +
> + mdc->dev = dev;
> + mutex_init(&mdc->lock);
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + mdc->base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(mdc->base))
> + return PTR_ERR(mdc->base);
> +
> + mdc->is_ready = true;
> + return 0;
> +}
> +
> +static const struct of_device_id iproc_mdio_match_table[] = {
> + { .compatible = "brcm,iproc-mdio" },
> + { }
> +};
> +
> +static struct platform_driver iproc_mdio_driver = {
> + .driver = {
> + .name = "iproc-mdio",
> + .of_match_table = iproc_mdio_match_table,
> + .suppress_bind_attrs = true,
> + },
> + .probe = iproc_mdio_probe,
> +};
> +
> +static int __init iproc_mdio_init(void)
> +{
> + return platform_driver_register(&iproc_mdio_driver);
> +}
> +arch_initcall_sync(iproc_mdio_init);
> +
> +MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
> +MODULE_DESCRIPTION("Broadcom iPROC MDC/MDIO driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/phy/iproc_mdio_phy.h b/include/linux/phy/iproc_mdio_phy.h
> new file mode 100644
> index 0000000..d3e88ce
> --- /dev/null
> +++ b/include/linux/phy/iproc_mdio_phy.h
> @@ -0,0 +1,22 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef __IPROC_MDIO_PHY_H
> +#define __IPROC_MDIO_PHY_H
> +
> +int iproc_mdio_read(unsigned clk_div, unsigned phy_addr, unsigned reg_addr,
> + u16 *data);
> +int iproc_mdio_write(unsigned clk_div, unsigned phy_addr, unsigned reg_addr,
> + u16 data);
> +
> +#endif /* __IPROC_MDIO_PHY_H */
>
next prev parent reply other threads:[~2015-05-21 13:13 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-20 1:23 [PATCH 0/5] Add Cygnus PCIe PHY support Ray Jui
2015-05-20 1:23 ` [PATCH 1/5] phy: iproc-mdio: Define DT binding Ray Jui
2015-05-21 13:07 ` Kishon Vijay Abraham I
2015-05-21 21:29 ` Ray Jui
2015-05-20 1:23 ` [PATCH 2/5] phy: iproc-mdio: Initial iProc MDC/MDIO support Ray Jui
2015-05-21 7:41 ` Paul Bolle
2015-05-21 23:52 ` Ray Jui
2015-05-22 8:39 ` Paul Bolle
2015-05-21 13:12 ` Kishon Vijay Abraham I [this message]
2015-05-21 21:35 ` Ray Jui
2015-05-21 21:51 ` Florian Fainelli
2015-05-21 22:02 ` Ray Jui
2015-05-20 1:23 ` [PATCH 3/5] phy: cygnus: pcie: Define DT binding Ray Jui
2015-05-21 13:14 ` Kishon Vijay Abraham I
2015-05-21 21:59 ` Ray Jui
2015-05-21 23:36 ` Ray Jui
2015-05-20 1:23 ` [PATCH 4/5] phy: cygnus: pcie: Add Cygnus PCIe PHY support Ray Jui
2015-05-21 7:52 ` Paul Bolle
2015-05-21 23:53 ` Ray Jui
2015-05-22 8:47 ` Paul Bolle
2015-05-21 13:19 ` Kishon Vijay Abraham I
2015-05-20 1:23 ` [PATCH 5/5] ARM: dts: enable PCIe PHY support for Cygnus Ray Jui
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=555DD9D5.3000206@ti.com \
--to=kishon@ti.com \
--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.