phy: Add USB HSIC PHY driver for Marvell MMP3 SoC

Add PHY driver for the HSICs found on Marvell MMP3 SoC. The driver is
rather straightforward -- the PHY essentially just needs to be enabled.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Link: https://lore.kernel.org/r/20200925235828.228626-4-lkundrak@v3.sk
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Lubomir Rintel 2020-09-26 01:58:29 +02:00 committed by Vinod Koul
parent a1b87f1aac
commit 0347c69214
3 changed files with 95 additions and 0 deletions

View File

@ -116,3 +116,15 @@ config PHY_MMP3_USB
The PHY driver will be used by Marvell udc/ehci/otg driver.
To compile this driver as a module, choose M here.
config PHY_MMP3_HSIC
tristate "Marvell MMP3 USB HSIC PHY Driver"
depends on MACH_MMP3_DT || COMPILE_TEST
select GENERIC_PHY
help
Enable this to support Marvell MMP3 USB HSIC PHY driver for
Marvell MMP3 SoC. This driver will be used my the Marvell EHCI
driver to initialize the interface to internal USB HSIC
components on MMP3-based boards.
To compile this driver as a module, choose M here.

View File

@ -3,6 +3,7 @@ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
obj-$(CONFIG_PHY_MMP3_USB) += phy-mmp3-usb.o
obj-$(CONFIG_PHY_MMP3_HSIC) += phy-mmp3-hsic.o
obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o
obj-$(CONFIG_PHY_MVEBU_A3700_UTMI) += phy-mvebu-a3700-utmi.o
obj-$(CONFIG_PHY_MVEBU_A38X_COMPHY) += phy-armada38x-comphy.o

View File

@ -0,0 +1,82 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#define HSIC_CTRL 0x08
#define HSIC_ENABLE BIT(7)
#define PLL_BYPASS BIT(4)
static int mmp3_hsic_phy_init(struct phy *phy)
{
void __iomem *base = (void __iomem *)phy_get_drvdata(phy);
u32 hsic_ctrl;
hsic_ctrl = readl_relaxed(base + HSIC_CTRL);
hsic_ctrl |= HSIC_ENABLE;
hsic_ctrl |= PLL_BYPASS;
writel_relaxed(hsic_ctrl, base + HSIC_CTRL);
return 0;
}
static const struct phy_ops mmp3_hsic_phy_ops = {
.init = mmp3_hsic_phy_init,
.owner = THIS_MODULE,
};
static const struct of_device_id mmp3_hsic_phy_of_match[] = {
{ .compatible = "marvell,mmp3-hsic-phy", },
{ },
};
MODULE_DEVICE_TABLE(of, mmp3_hsic_phy_of_match);
static int mmp3_hsic_phy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct phy_provider *provider;
struct resource *resource;
void __iomem *base;
struct phy *phy;
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, resource);
if (IS_ERR(base)) {
dev_err(dev, "failed to remap PHY regs\n");
return PTR_ERR(base);
}
phy = devm_phy_create(dev, NULL, &mmp3_hsic_phy_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create PHY\n");
return PTR_ERR(phy);
}
phy_set_drvdata(phy, (void *)base);
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);
}
return 0;
}
static struct platform_driver mmp3_hsic_phy_driver = {
.probe = mmp3_hsic_phy_probe,
.driver = {
.name = "mmp3-hsic-phy",
.of_match_table = mmp3_hsic_phy_of_match,
},
};
module_platform_driver(mmp3_hsic_phy_driver);
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
MODULE_DESCRIPTION("Marvell MMP3 USB HSIC PHY Driver");
MODULE_LICENSE("GPL");