forked from Minki/linux
0b56e9a7e8
Adding vendor specific directories in phy to group phy drivers under their respective vendor umbrella. Also updated the MAINTAINERS file to reflect the correct directory structure for phy drivers. Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org> Acked-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Krzysztof Kozlowski <krzk@kernel.org> Acked-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com> Cc: Kishon Vijay Abraham I <kishon@ti.com> Cc: David S. Miller <davem@davemloft.net> Cc: Geert Uytterhoeven <geert+renesas@glider.be> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Cc: Guenter Roeck <linux@roeck-us.net> Cc: Heiko Stuebner <heiko@sntech.de> Cc: Viresh Kumar <viresh.kumar@linaro.org> Cc: Maxime Ripard <maxime.ripard@free-electrons.com> Cc: Chen-Yu Tsai <wens@csie.org> Cc: Sylwester Nawrocki <s.nawrocki@samsung.com> Cc: Krzysztof Kozlowski <krzk@kernel.org> Cc: Jaehoon Chung <jh80.chung@samsung.com> Cc: Stephen Boyd <stephen.boyd@linaro.org> Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-arm-msm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-omap@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org Cc: linux-rockchip@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org Cc: linux-usb@vger.kernel.org Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
139 lines
3.4 KiB
C
139 lines
3.4 KiB
C
/*
|
|
* phy-mvebu-sata.c: SATA Phy driver for the Marvell mvebu SoCs.
|
|
*
|
|
* Copyright (C) 2013 Andrew Lunn <andrew@lunn.ch>
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/phy/phy.h>
|
|
#include <linux/io.h>
|
|
#include <linux/platform_device.h>
|
|
|
|
struct priv {
|
|
struct clk *clk;
|
|
void __iomem *base;
|
|
};
|
|
|
|
#define SATA_PHY_MODE_2 0x0330
|
|
#define MODE_2_FORCE_PU_TX BIT(0)
|
|
#define MODE_2_FORCE_PU_RX BIT(1)
|
|
#define MODE_2_PU_PLL BIT(2)
|
|
#define MODE_2_PU_IVREF BIT(3)
|
|
#define SATA_IF_CTRL 0x0050
|
|
#define CTRL_PHY_SHUTDOWN BIT(9)
|
|
|
|
static int phy_mvebu_sata_power_on(struct phy *phy)
|
|
{
|
|
struct priv *priv = phy_get_drvdata(phy);
|
|
u32 reg;
|
|
|
|
clk_prepare_enable(priv->clk);
|
|
|
|
/* Enable PLL and IVREF */
|
|
reg = readl(priv->base + SATA_PHY_MODE_2);
|
|
reg |= (MODE_2_FORCE_PU_TX | MODE_2_FORCE_PU_RX |
|
|
MODE_2_PU_PLL | MODE_2_PU_IVREF);
|
|
writel(reg , priv->base + SATA_PHY_MODE_2);
|
|
|
|
/* Enable PHY */
|
|
reg = readl(priv->base + SATA_IF_CTRL);
|
|
reg &= ~CTRL_PHY_SHUTDOWN;
|
|
writel(reg, priv->base + SATA_IF_CTRL);
|
|
|
|
clk_disable_unprepare(priv->clk);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int phy_mvebu_sata_power_off(struct phy *phy)
|
|
{
|
|
struct priv *priv = phy_get_drvdata(phy);
|
|
u32 reg;
|
|
|
|
clk_prepare_enable(priv->clk);
|
|
|
|
/* Disable PLL and IVREF */
|
|
reg = readl(priv->base + SATA_PHY_MODE_2);
|
|
reg &= ~(MODE_2_FORCE_PU_TX | MODE_2_FORCE_PU_RX |
|
|
MODE_2_PU_PLL | MODE_2_PU_IVREF);
|
|
writel(reg, priv->base + SATA_PHY_MODE_2);
|
|
|
|
/* Disable PHY */
|
|
reg = readl(priv->base + SATA_IF_CTRL);
|
|
reg |= CTRL_PHY_SHUTDOWN;
|
|
writel(reg, priv->base + SATA_IF_CTRL);
|
|
|
|
clk_disable_unprepare(priv->clk);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct phy_ops phy_mvebu_sata_ops = {
|
|
.power_on = phy_mvebu_sata_power_on,
|
|
.power_off = phy_mvebu_sata_power_off,
|
|
.owner = THIS_MODULE,
|
|
};
|
|
|
|
static int phy_mvebu_sata_probe(struct platform_device *pdev)
|
|
{
|
|
struct phy_provider *phy_provider;
|
|
struct resource *res;
|
|
struct priv *priv;
|
|
struct phy *phy;
|
|
|
|
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
|
if (!priv)
|
|
return -ENOMEM;
|
|
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
priv->base = devm_ioremap_resource(&pdev->dev, res);
|
|
if (IS_ERR(priv->base))
|
|
return PTR_ERR(priv->base);
|
|
|
|
priv->clk = devm_clk_get(&pdev->dev, "sata");
|
|
if (IS_ERR(priv->clk))
|
|
return PTR_ERR(priv->clk);
|
|
|
|
phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops);
|
|
if (IS_ERR(phy))
|
|
return PTR_ERR(phy);
|
|
|
|
phy_set_drvdata(phy, priv);
|
|
|
|
phy_provider = devm_of_phy_provider_register(&pdev->dev,
|
|
of_phy_simple_xlate);
|
|
if (IS_ERR(phy_provider))
|
|
return PTR_ERR(phy_provider);
|
|
|
|
/* The boot loader may of left it on. Turn it off. */
|
|
phy_mvebu_sata_power_off(phy);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct of_device_id phy_mvebu_sata_of_match[] = {
|
|
{ .compatible = "marvell,mvebu-sata-phy" },
|
|
{ },
|
|
};
|
|
MODULE_DEVICE_TABLE(of, phy_mvebu_sata_of_match);
|
|
|
|
static struct platform_driver phy_mvebu_sata_driver = {
|
|
.probe = phy_mvebu_sata_probe,
|
|
.driver = {
|
|
.name = "phy-mvebu-sata",
|
|
.of_match_table = phy_mvebu_sata_of_match,
|
|
}
|
|
};
|
|
module_platform_driver(phy_mvebu_sata_driver);
|
|
|
|
MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
|
|
MODULE_DESCRIPTION("Marvell MVEBU SATA PHY driver");
|
|
MODULE_LICENSE("GPL v2");
|