Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2292887imm; Thu, 7 Jun 2018 08:18:06 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIIFoxW6DsSdFzfh4oOfe/79XjBsjffGMzXr/RaS77m5WbUDe20R2zu6k+HTqly+tML1Lab X-Received: by 2002:a65:528c:: with SMTP id y12-v6mr1946548pgp.157.1528384686807; Thu, 07 Jun 2018 08:18:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528384686; cv=none; d=google.com; s=arc-20160816; b=x2XYfHFaLZ7OEVdnnY8NTYqBKHgE5waNzcd9Ywv6T+gGGVeS3qbX7FZNYCktdDMlZQ MU40Rs28flfDEp2AmlYNGpZF64XhAAXxdQjstrd0filvh3zSLae2QgcXGJxu5fgwZK2Q NpTi/oXcGdsBIMXRS22tOAMixndqoPElXYF6hY+Hx6LHc0K2mD3KUAUOtZyRTQdL6j1z 98PVE5D3MfWZH+hkUhelHSLPoKzlVovtD08KDNleOmCnX2MfiMIGl0LtLbZ7iSgrdBCE JqumxHjT6UX2kHg4ByjCf2VBX7XjHNkXmux5Hs5NcFD/9PivLqZHzbW1Xt96XhGhl3FK ZCWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=WfegHGkuTaB5zC94j/J+gEKYChr3kJfbDFMQhgNHiO8=; b=SofCfjnS3TqJAZybNpfihNG/lEMM3dT9z+xcHEj5go+quqjVeqnq95cmHIV3UM2N6p 0ozTgE6JAwNWAC1Itq4txdI7cO3OZHeavC/2eow1MBmDcmB4N7jHPrAsFKHAmIvp+0eb AvwGO7GPTgSaXqcrYcyLwl7GRFp4p0JUU5MZrrmagsNIqgHGogDydBoCFkQNlRS3OSHc iHRET+y6wmz5NxyCEUALoMPywJWPF0uck9fUVpZtaOOqct6UICS3RDTwlcol4bofEMM9 8/Z3MMRDO0kX8C7y0rAnPiHxh6Did8zDn++iqpGdYsOzOjHH+I4ON4wDGnAWH3+DTBlc Ah+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 31-v6si54097247plz.364.2018.06.07.08.17.51; Thu, 07 Jun 2018 08:18:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936018AbeFGPPq (ORCPT + 99 others); Thu, 7 Jun 2018 11:15:46 -0400 Received: from 212.199.177.27.static.012.net.il ([212.199.177.27]:33499 "EHLO herzl.nuvoton.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S934841AbeFGPBc (ORCPT ); Thu, 7 Jun 2018 11:01:32 -0400 Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id w57EwNa0019458; Thu, 7 Jun 2018 17:58:24 +0300 Received: by taln60.nuvoton.co.il (Postfix, from userid 8441) id A428962FC8; Thu, 7 Jun 2018 17:58:23 +0300 (IDT) From: avifishman70@gmail.com To: gregkh@linuxfoundation.org, stern@rowland.harvard.edu Cc: avifishman70@gmail.com, tmaimon77@gmail.com, venture@google.com, yuenn@google.com, brendanhiggins@google.com, mathias.nyman@linux.intel.com, bjorn.andersson@linaro.org, jhogan@kernel.org, albeu@free.fr, chunfeng.yun@mediatek.com, tony@atomide.com, baolu.lu@linux.intel.com, elder@linaro.org, digetx@gmail.com, kstewart@linuxfoundation.org, hdegoede@redhat.com, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, openbmc@lists.ozlabs.org, robh+dt@kernel.org, mark.rutland@arm.com, devicetree@vger.kernel.org, Avi Fishman Subject: [PATCH v4 1/3] USB host: Add USB ehci support for nuvoton npcm7xx platform Date: Thu, 7 Jun 2018 17:58:19 +0300 Message-Id: <20180607145821.322979-2-avifishman70@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180607145821.322979-1-avifishman70@gmail.com> References: <20180607145821.322979-1-avifishman70@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Avi Fishman This patch adds support for ehci controller for the Nuvoton npcm7xx platform. Most of the code was taken from ehci-spear.c + specific initialization code Signed-off-by: Avi Fishman --- drivers/usb/host/Kconfig | 8 ++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-npcm7xx.c | 212 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 drivers/usb/host/ehci-npcm7xx.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 9f0aeb068acb..e3100b249f0f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -185,6 +185,14 @@ config USB_EHCI_MXC ---help--- Variation of ARC USB block used in some Freescale chips. +config USB_EHCI_HCD_NPCM7XX + tristate "Support for Nuvoton NPCM7XX on-chip EHCI USB controller" + depends on (USB_EHCI_HCD && ARCH_NPCM7XX) || COMPILE_TEST + default y + help + Enables support for the on-chip EHCI controller on + Nuvoton NPCM7XX chips. + config USB_EHCI_HCD_OMAP tristate "EHCI support for OMAP3 and later chips" depends on ARCH_OMAP diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 8a8cffe0b445..fcf5dab5efa4 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o obj-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o +obj-$(CONFIG_USB_EHCI_HCD_NPCM7XX) += ehci-npcm7xx.o obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o obj-$(CONFIG_USB_EHCI_HCD_ORION) += ehci-orion.o obj-$(CONFIG_USB_EHCI_HCD_SPEAR) += ehci-spear.o diff --git a/drivers/usb/host/ehci-npcm7xx.c b/drivers/usb/host/ehci-npcm7xx.c new file mode 100644 index 000000000000..c80a8792d3b0 --- /dev/null +++ b/drivers/usb/host/ehci-npcm7xx.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Nuvoton NPCM7xx driver for EHCI HCD + * + * Copyright (C) 2018 Nuvoton Technologies, + * Avi Fishman + * Tomer Maimon + * + * Based on various ehci-spear.c driver + */ + + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ehci.h" + +#include +#include + +#define DRIVER_DESC "EHCI npcm7xx driver" + +static const char hcd_name[] = "npcm7xx-ehci"; + +#define USB2PHYCTL_OFFSET 0x144 + +#define IPSRST2_OFFSET 0x24 +#define IPSRST3_OFFSET 0x34 + + +static struct hc_driver __read_mostly ehci_npcm7xx_hc_driver; + +#ifdef CONFIG_PM_SLEEP +static int ehci_npcm7xx_drv_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + bool do_wakeup = device_may_wakeup(dev); + + return ehci_suspend(hcd, do_wakeup); +} + +static int ehci_npcm7xx_drv_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + + ehci_resume(hcd, false); + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(ehci_npcm7xx_pm_ops, ehci_npcm7xx_drv_suspend, + ehci_npcm7xx_drv_resume); + +static int npcm7xx_ehci_hcd_drv_probe(struct platform_device *pdev) +{ + struct usb_hcd *hcd; + struct resource *res; + struct regmap *gcr_regmap; + struct regmap *rst_regmap; + const struct hc_driver *driver = &ehci_npcm7xx_hc_driver; + int irq; + int retval; + + dev_dbg(&pdev->dev, "initializing npcm7xx ehci USB Controller\n"); + + gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr"); + if (IS_ERR(gcr_regmap)) { + dev_err(&pdev->dev, "%s: failed to find nuvoton,npcm750-gcr\n", + __func__); + return IS_ERR(gcr_regmap); + } + + rst_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-rst"); + if (IS_ERR(rst_regmap)) { + dev_err(&pdev->dev, "%s: failed to find nuvoton,npcm750-rst\n", + __func__); + return IS_ERR(rst_regmap); + } + + /********* phy init ******/ + // reset usb host + regmap_update_bits(rst_regmap, IPSRST2_OFFSET, + (0x1 << 26), (0x1 << 26)); + regmap_update_bits(rst_regmap, IPSRST3_OFFSET, + (0x1 << 25), (0x1 << 25)); + regmap_update_bits(gcr_regmap, USB2PHYCTL_OFFSET, + (0x1 << 28), 0); + + udelay(1); + + // enable phy + regmap_update_bits(rst_regmap, IPSRST3_OFFSET, + (0x1 << 25), 0); + + udelay(50); // enable phy + + regmap_update_bits(gcr_regmap, USB2PHYCTL_OFFSET, + (0x1 << 28), (0x1 << 28)); + + // enable host + regmap_update_bits(rst_regmap, IPSRST2_OFFSET, + (0x1 << 26), 0); + + if (usb_disabled()) + return -ENODEV; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + retval = irq; + goto fail; + } + + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (retval) + goto fail; + + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); + if (!hcd) { + retval = -ENOMEM; + goto fail; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hcd->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(hcd->regs)) { + retval = PTR_ERR(hcd->regs); + goto err_put_hcd; + } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + + /* registers start at offset 0x0 */ + hcd_to_ehci(hcd)->caps = hcd->regs; + + retval = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (retval) + goto err_put_hcd; + + device_wakeup_enable(hcd->self.controller); + return retval; + +err_put_hcd: + usb_put_hcd(hcd); +fail: + dev_err(&pdev->dev, "init fail, %d\n", retval); + + return retval; +} + +static int npcm7xx_ehci_hcd_drv_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + usb_remove_hcd(hcd); + + usb_put_hcd(hcd); + + return 0; +} + +static const struct of_device_id npcm7xx_ehci_id_table[] = { + { .compatible = "nuvoton,npcm750-ehci" }, + { }, +}; +MODULE_DEVICE_TABLE(of, npcm7xx_ehci_id_table); + +static struct platform_driver npcm7xx_ehci_hcd_driver = { + .probe = npcm7xx_ehci_hcd_drv_probe, + .remove = npcm7xx_ehci_hcd_drv_remove, + .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "npcm7xx-ehci", + .bus = &platform_bus_type, + .pm = &ehci_npcm7xx_pm_ops, + .of_match_table = npcm7xx_ehci_id_table, + } +}; + +static int __init ehci_npcm7xx_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + pr_info("%s: " DRIVER_DESC "\n", hcd_name); + + ehci_init_driver(&ehci_npcm7xx_hc_driver, NULL); + return platform_driver_register(&npcm7xx_ehci_hcd_driver); +} +module_init(ehci_npcm7xx_init); + +static void __exit ehci_npcm7xx_cleanup(void) +{ + platform_driver_unregister(&npcm7xx_ehci_hcd_driver); +} +module_exit(ehci_npcm7xx_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_ALIAS("platform:npcm7xx-ehci"); +MODULE_AUTHOR("Avi Fishman"); +MODULE_LICENSE("GPL v2"); -- 2.14.1