From patchwork Mon Oct 12 06:23:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 317613 Delivered-To: patch@linaro.org Received: by 2002:a92:d603:0:0:0:0:0 with SMTP id w3csp4324702ilm; Sun, 11 Oct 2020 22:58:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx0wfUt7tORNW4C6xgnWR/q82zbZsIBaaHJrfazLeol5IYMKAV4+r/TuvEVQMh7Yrd9NzZ2 X-Received: by 2002:a17:906:3e48:: with SMTP id t8mr25769308eji.104.1602482326340; Sun, 11 Oct 2020 22:58:46 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1602482326; cv=pass; d=google.com; s=arc-20160816; b=GXwWuzhvN+9s/10JLN6WICJPG+dTeRhY65Gl0zUmNQ7OhcNmMPqFkhnNOiBxAaTT16 yNNGTQVH1yJ/uL3wBxmJnaCaNpAniiLUk76/zkhUgwsidetAZJB4mwTxg1ZvbLEHTC65 Sd1BQIuYL91LeokE0PKjqnaZWxXti6inyZshm5eGv73jwh7nmVukv50vPKRxqpGFcRoQ S3ajMsahiDh4e8SybHmH90rTCUZooog1dnYbg/9OVssJe8pEjhtudvM7Mu4c1v4W6ofJ uMk19sRFm7Gl4k1wiM1wD16wepYLJC8LN8WA897AjKzyIhMNKpUuVpE3z2y6hsSyAn+X GQtQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mime-version :content-transfer-encoding:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=n4b25VT84T3JuaHW422EpKbwl6OQCemfSJ4pdQlf9X4=; b=z5cAEP45UA1Ht0gtlzfmb8Ilx7ghPcw5+EImj0ilxwmkJHUEoXSAagn5aenK+sPYtV xpxpVzUNlaKnoDIDZaIOIJFIkLb5GBHarpvB7OFe8FK5pcUOeWqCOPbWhGugDuTNOfZF aXK0qymCutl3+oWNPQyyq6ZmfPadWbapPeRgFfNuB52Q+QaEtf3I6JsrQcZ6R1jqyzUz r8nFx3eBf86hbr29h0swmYxB0fxVg5PWijeqgrLx8DYzmTLjsbOeUVv0KodpI/NWxq4i ZYvZtn3OrBEOhdraqbCNWw9GS2KbU3oCr6LaxEp8s/IJfCQsm7/sNWJ5pU5ECulrKk1+ jDpg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@nxp.com header.s=selector2 header.b=pGgNwQtE; arc=pass (i=1 spf=pass spfdomain=nxp.com dkim=pass dkdomain=nxp.com dmarc=pass fromdomain=nxp.com); spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id jr15si11942732ejb.183.2020.10.11.22.58.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 11 Oct 2020 22:58:46 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@nxp.com header.s=selector2 header.b=pGgNwQtE; arc=pass (i=1 spf=pass spfdomain=nxp.com dkim=pass dkdomain=nxp.com dmarc=pass fromdomain=nxp.com); spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4C0D7824C9; Mon, 12 Oct 2020 07:57:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=nxp.com header.i=@nxp.com header.b="pGgNwQtE"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 30CB0824B8; Mon, 12 Oct 2020 07:57:39 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FORGED_SPF_HELO,MSGID_FROM_MTA_HEADER, SPF_HELO_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on062d.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe02::62d]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 39D83824B8 for ; Mon, 12 Oct 2020 07:57:36 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=peng.fan@nxp.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=j4CRhkmudIl7jobukn15PYD32WnTb/VnN72V13VHabdFf4c5DrXJCm4PKFZpbn+CrBVzRQJ4VMJ066wCUsIJxNAyyy0F47Y65TFkyFicIwcNbbMVzfD/WugaZuSCDj6niFBf0/6oDVOJboJIqkEx6eJUAROQAN2we2jfrfOwDWqmac5kE3+GAW7LR6RrDxCUzTfG0W5s7LREjRll05UxlaaExzO64rbCT9YpYUe5SgAgvlI1KSAGcyxUl4qCmPkPvxU94YumnfTNdetTgqn6HI6J0aASaSOb7g4PF9SwPCc3hJNe3p1Iezg/a4xsrRUcjQmpXiRvWdaGJpvMYOqiJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=n4b25VT84T3JuaHW422EpKbwl6OQCemfSJ4pdQlf9X4=; b=QQslAhblS71Ah6l73BMb2vVZQEXgIIhe05q5MW3kkxDZeG5O5v97Myvoe/ufAsp6kRw/lDixG/hIh3n8NijIqv/w7aAvNkioPLmfofbxo4Veb0Rrwhsh4HGU1l9a1SZmP4/lihYURZVLCjjHmfFtlgdbaD74KOQ8Y4gzAeYieggcIRB/ug77cf8n+XFEvHi3jrmz/87PANlmMMfnn84LmQiH+XoNKNkfKerZmsb2lBd3IDHFQtG/d97wsG1+GyBy+uLM82ayapBCbN1bOWACvY73YxsKjfmQGC8G5SnfryA8mN3r2BPd+fR9ubwM944iRBUUhgbdrVXFSh94ANUkFg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=n4b25VT84T3JuaHW422EpKbwl6OQCemfSJ4pdQlf9X4=; b=pGgNwQtEyhY6c4qz2ZHo9crmfCIzQvEDZwYQRPBGa6TdU3WiaQWJbwBRwjbFvsn2Ek2Nj7QQt4P0624UJEOGlecJ3hoLTvO+2wM+QivokZpGdgnl4MYBAsG+sxGvyY2pN4mDOIQEF4991WJTN87h1kU5bfxQBCPTswYbd33Rbgg= Authentication-Results: denx.de; dkim=none (message not signed) header.d=none;denx.de; dmarc=none action=none header.from=nxp.com; Received: from DB6PR0402MB2760.eurprd04.prod.outlook.com (2603:10a6:4:a1::14) by DB7PR04MB4235.eurprd04.prod.outlook.com (2603:10a6:5:22::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.26; Mon, 12 Oct 2020 05:57:33 +0000 Received: from DB6PR0402MB2760.eurprd04.prod.outlook.com ([fe80::35c5:8c71:91f3:6bc6]) by DB6PR0402MB2760.eurprd04.prod.outlook.com ([fe80::35c5:8c71:91f3:6bc6%12]) with mapi id 15.20.3455.029; Mon, 12 Oct 2020 05:57:33 +0000 From: Peng Fan To: sbabic@denx.de, festevam@gmail.com, marex@denx.de, lukma@denx.de Cc: uboot-imx@nxp.com, u-boot@lists.denx.de, Sherry Sun , Ye Li , Peng Fan Subject: [PATCH 7/8] usb: ci_udc: Convert driver to DM_USB_GADGET Date: Mon, 12 Oct 2020 14:23:53 +0800 Message-Id: <20201012062354.3743-8-peng.fan@nxp.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201012062354.3743-1-peng.fan@nxp.com> References: <20201012062354.3743-1-peng.fan@nxp.com> X-Originating-IP: [119.31.174.71] X-ClientProxiedBy: SG2PR01CA0105.apcprd01.prod.exchangelabs.com (2603:1096:3:15::31) To DB6PR0402MB2760.eurprd04.prod.outlook.com (2603:10a6:4:a1::14) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from linux-1xn6.ap.freescale.net (119.31.174.71) by SG2PR01CA0105.apcprd01.prod.exchangelabs.com (2603:1096:3:15::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.22 via Frontend Transport; Mon, 12 Oct 2020 05:57:30 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: ec12ea5c-75af-4d25-53ee-08d86e73b668 X-MS-TrafficTypeDiagnostic: DB7PR04MB4235: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6430; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: sNWOgqDiS+OW3bRTeloKq+Svye0v5UZlyfPbPBOBfW7OpHFNbUIBZa0O2ASsQFW7uzhPjVgi3kNFgRK8uLckDI/T+QxJ0pws8bfkEGVKlBUNGdQ8J9R5w/h40mOF31JBPGlz5n3Xt7J6Y3cbiFNKcWdMFjYATyVf7w5auK+s4r4X0BKdh1fQ23A+aDXVoiJRV8rKuoU2cKfmTyE76s0bETyCetQyzeIJe08YrqMXPV1gAvv4vo+rV0+IHA91F9L/4lEwGiGg0M/C81BEmfp8DW7Za3mpbD4+vQfhC3+ze6b1VBc01+Slz1mfArJd/95ra+Udj8Qays/SP3ayfdnK5g== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DB6PR0402MB2760.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(396003)(39860400002)(376002)(346002)(366004)(136003)(52116002)(83380400001)(8936002)(6506007)(4326008)(8676002)(44832011)(30864003)(6512007)(1076003)(6486002)(86362001)(5660300002)(6666004)(66476007)(66946007)(66556008)(316002)(36756003)(54906003)(2616005)(956004)(2906002)(186003)(26005)(478600001)(16526019); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: X2eNAw1Q95rtHAbR1+s0Ztrw9c7GBAJq4JnE2tJi5XYvfJPGuxOKiaIPofGsaUMrs3DoSnOelE1ji2tLRkb0mre0ClrvycoZ6JsDgzEeTuoZDBHNSdGByOLzRTUxUJ+WZ2jN/HgoxiQSzsQAcyL4rXUqr1TX942kvxAwyCpmD7ep5h3oRz6Z9m1XyMxg+VyvXAkBI/+qvtymTdeseBjeJ0Q9zFXPiujVctEuySzxWx98uAm297EIOX/PzkParKr1JlPVqBN0Sr4wt+X+Xc3EHfD0xq4bowmCYEy7f5uw7Z+BVjXc4fonyNs/CnpTDUDBZM8/vhS0viU/rVN0xrS1AXXiqE8Wt4fsdIJPr2iwhda7mT/fVBJ1zYm9MHy7sJmyMX3cY+B3mMoQzFlbMz/uq40Kx+W776CVAFwOIYU3B5ePsPr5v0zq4IBLSu/JPJLGo7h2GtYceh3lGY8Abv77SiMOMaxsxRC6aAUXFes2ws9EUvZpahVdGhRXe4MrLYNTuZPvQSoGQFDfiA8GPPI8vZ35p8LjgXtNsD5/b79k9GvkhYHZjU3L3Wcep3jh+Fi48fo13Oao6bt1INNuPk80TdE/EvwJJo0XWo3T7Ib1QAN0plSObdvchI7LA3CtCPq1wbDEue9zVW2rJHNJ5Btslw== X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: ec12ea5c-75af-4d25-53ee-08d86e73b668 X-MS-Exchange-CrossTenant-AuthSource: DB6PR0402MB2760.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Oct 2020 05:57:33.6868 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ws0hpxpVwTslc/TOYis6viwdvTfNy95i6h3iCOQVa/5rIWOup3iD60o3x58TGC7tbZhn6J5dElQw28FDfdq6XA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB7PR04MB4235 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean From: Sherry Sun Convert the ci_udc driver to driver model by using the uclass UCLASS_USB_GADGET_GENERIC. The clk and power of USB controller and USB PHY both are initialized by parsing the device tree nodes. If CONFIG_DM_USB_GADGET is defined, we use the ci_udc driver in DM way, if it does not defined, we can use ci_udc driver in its original Non-DM way. Signed-off-by: Sherry Sun Reviewed-by: Ye Li [Peng: need to extract common code from host and gadget driver(TODO)] Signed-off-by: Peng Fan --- drivers/usb/gadget/ci_udc.c | 305 +++++++++++++++++++++++++++++++++++- drivers/usb/host/ehci-mx6.c | 15 +- include/usb/ci_udc.h | 3 + 3 files changed, 305 insertions(+), 18 deletions(-) -- 2.28.0 diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index 226a9e6d67..6f2e38ffd8 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -13,16 +13,25 @@ #include #include #include +#include +#include +#include #include #include #include #include #include #include +#include +#include +#include #include #include #include +#include +#include #include +#include #include "../host/ehci.h" #include "ci_udc.h" @@ -93,9 +102,18 @@ static int ci_ep_dequeue(struct usb_ep *ep, struct usb_request *req); static struct usb_request * ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags); static void ci_ep_free_request(struct usb_ep *ep, struct usb_request *_req); +#if CONFIG_IS_ENABLED(DM_USB_GADGET) +static int ci_udc_gadget_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int ci_udc_gadget_stop(struct usb_gadget *g); +#endif static struct usb_gadget_ops ci_udc_ops = { .pullup = ci_pullup, +#if CONFIG_IS_ENABLED(DM_USB_GADGET) + .udc_start = ci_udc_gadget_start, + .udc_stop = ci_udc_gadget_stop, +#endif }; static struct usb_ep_ops ci_ep_ops = { @@ -866,7 +884,7 @@ void udc_irq(void) } } -int usb_gadget_handle_interrupts(int index) +int ci_udc_handle_interrupts(void) { u32 value; struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; @@ -1010,6 +1028,19 @@ static int ci_udc_probe(void) return 0; } +bool dfu_usb_get_reset(void) +{ + struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; + + return !!(readl(&udc->usbsts) & STS_URI); +} + +#if !CONFIG_IS_ENABLED(DM_USB_GADGET) +int usb_gadget_handle_interrupts(int index) +{ + return ci_udc_handle_interrupts(); +} + int usb_gadget_register_driver(struct usb_gadget_driver *driver) { int ret; @@ -1063,10 +1094,276 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) return 0; } +#else /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */ -bool dfu_usb_get_reset(void) +static int ci_udc_gadget_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; + if (!driver) + return -EINVAL; + if (!driver->bind || !driver->setup || !driver->disconnect) + return -EINVAL; - return !!(readl(&udc->usbsts) & STS_URI); + controller.driver = driver; + return 0; +} + +static int ci_udc_gadget_stop(struct usb_gadget *g) +{ + controller.driver = NULL; + + ci_ep_free_request(&controller.ep[0].ep, &controller.ep0_req->req); + free(controller.items_mem); + free(controller.epts); + return 0; +} + +struct ci_udc_priv_data { + struct ehci_ctrl ctrl; + struct udevice otgdev; + struct clk_bulk clks; + int phy_off; + struct power_domain otg_pd; + struct clk phy_clk; + struct power_domain phy_pd; +}; + +int dm_usb_gadget_handle_interrupts(struct udevice *dev) +{ + return ci_udc_handle_interrupts(); +} + +static int ci_udc_phy_setup(struct udevice *dev, struct ci_udc_priv_data *priv) +{ + struct udevice __maybe_unused phy_dev; + priv->phy_off = fdtdec_lookup_phandle(gd->fdt_blob, + dev_of_offset(dev), + "fsl,usbphy"); + if (priv->phy_off < 0) + return -EINVAL; + + phy_dev.node = offset_to_ofnode(priv->phy_off); + +#if CONFIG_IS_ENABLED(POWER_DOMAIN) + /* Need to power on the PHY before access it */ + if (!power_domain_get(&phy_dev, &priv->phy_pd)) { + if (power_domain_on(&priv->phy_pd)) + return -EINVAL; + } +#endif + +#if CONFIG_IS_ENABLED(CLK) + int ret; + + ret = clk_get_by_index(&phy_dev, 0, &priv->phy_clk); + if (ret) { + printf("Failed to get phy_clk\n"); + return ret; + } + + ret = clk_enable(&priv->phy_clk); + if (ret) { + printf("Failed to enable phy_clk\n"); + return ret; + } +#endif + + return 0; +} + +static int ci_udc_phy_shutdown(struct ci_udc_priv_data *priv) +{ + int ret = 0; + +#if CONFIG_IS_ENABLED(CLK) + if (priv->phy_clk.dev) { + ret = clk_disable(&priv->phy_clk); + if (ret) + return ret; + + ret = clk_free(&priv->phy_clk); + if (ret) + return ret; + } +#endif + +#if CONFIG_IS_ENABLED(POWER_DOMAIN) + ret = power_domain_off(&priv->phy_pd); + if (ret) + printf("Power down USB PHY failed! (error = %d)\n", ret); +#endif + return ret; +} + +static int ci_udc_otg_clk_init(struct udevice *dev, + struct clk_bulk *clks) +{ + int ret; + + ret = clk_get_bulk(dev, clks); + if (ret == -ENOSYS) + return 0; + + if (ret) + return ret; + +#if CONFIG_IS_ENABLED(CLK) + ret = clk_enable_bulk(clks); + if (ret) { + clk_release_bulk(clks); + return ret; + } +#endif + + return 0; +} + +static int ci_udc_otg_phy_mode(struct udevice *dev) +{ + struct ci_udc_priv_data *priv = dev_get_priv(dev); + + void *__iomem phy_ctrl, *__iomem phy_status; + void *__iomem phy_base = (void *__iomem)devfdt_get_addr(&priv->otgdev); + u32 val; + + if (is_mx6() || is_mx7ulp() || is_imx8()) { + phy_base = (void __iomem *)fdtdec_get_addr(gd->fdt_blob, + priv->phy_off, + "reg"); + if ((fdt_addr_t)phy_base == FDT_ADDR_T_NONE) + return -EINVAL; + + phy_ctrl = (void __iomem *)(phy_base + USBPHY_CTRL); + val = readl(phy_ctrl); + if (val & USBPHY_CTRL_OTG_ID) + return USB_INIT_DEVICE; + else + return USB_INIT_HOST; + } else if (is_mx7() || is_imx8mm() || is_imx8mn()) { + phy_status = (void __iomem *)(phy_base + + USBNC_PHY_STATUS_OFFSET); + val = readl(phy_status); + if (val & USBNC_PHYSTATUS_ID_DIG) + return USB_INIT_DEVICE; + else + return USB_INIT_HOST; + } else { + return -EINVAL; + } +} + +static int ci_udc_otg_ofdata_to_platdata(struct udevice *dev) +{ + struct ci_udc_priv_data *priv = dev_get_priv(dev); + int node = dev_of_offset(dev); + int usbotg_off; + + if (usb_get_dr_mode(dev_ofnode(dev)) != USB_DR_MODE_PERIPHERAL) { + dev_dbg(dev, "Invalid mode\n"); + return -ENODEV; + } + + usbotg_off = fdtdec_lookup_phandle(gd->fdt_blob, + node, + "chipidea,usb"); + if (usbotg_off < 0) + return -EINVAL; + priv->otgdev.node = offset_to_ofnode(usbotg_off); + priv->otgdev.parent = dev->parent; + + return 0; +} + +static int ci_udc_otg_probe(struct udevice *dev) +{ + struct ci_udc_priv_data *priv = dev_get_priv(dev); + struct usb_ehci *ehci; + int ret; + + ehci = (struct usb_ehci *)devfdt_get_addr(&priv->otgdev); + + pinctrl_select_state(&priv->otgdev, "default"); + +#if defined(CONFIG_MX6) + if (mx6_usb_fused((u32)ehci)) { + printf("USB@0x%x is fused, disable it\n", (u32)ehci); + return -ENODEV; + } +#endif + + ret = board_usb_init(dev->seq, USB_INIT_DEVICE); + if (ret) { + printf("Failed to initialize board for USB\n"); + return ret; + } + +#if CONFIG_IS_ENABLED(POWER_DOMAIN) + if (!power_domain_get(&priv->otgdev, &priv->otg_pd)) { + if (power_domain_on(&priv->otg_pd)) + return -EINVAL; + } +#endif + + ret = ci_udc_phy_setup(&priv->otgdev, priv); + if (ret) + return ret; + + ret = ci_udc_otg_clk_init(&priv->otgdev, &priv->clks); + if (ret) + return ret; + + if (ci_udc_otg_phy_mode(dev) != USB_INIT_DEVICE) + return -ENODEV; + + priv->ctrl.hccr = (struct ehci_hccr *)((ulong)&ehci->caplength); + priv->ctrl.hcor = (struct ehci_hcor *)((ulong)priv->ctrl.hccr + + HC_LENGTH(ehci_readl(&(priv->ctrl.hccr)->cr_capbase))); + controller.ctrl = &priv->ctrl; + + ret = ci_udc_probe(); + if (ret) { + DBG("udc probe failed, returned %d\n", ret); + return ret; + } + + ret = usb_add_gadget_udc((struct device *)dev, &controller.gadget); + + return ret; +} + +static int ci_udc_otg_remove(struct udevice *dev) +{ + struct ci_udc_priv_data *priv = dev_get_priv(dev); + + usb_del_gadget_udc(&controller.gadget); + + clk_release_bulk(&priv->clks); + ci_udc_phy_shutdown(priv); +#if CONFIG_IS_ENABLED(POWER_DOMAIN) + if (power_domain_off(&priv->otg_pd)) { + printf("Power down USB controller failed!\n"); + return -EINVAL; + } +#endif + board_usb_cleanup(dev->seq, USB_INIT_DEVICE); + + controller.ctrl = NULL; + return 0; } + +static const struct udevice_id ci_udc_otg_ids[] = { + { .compatible = "fsl,imx27-usb-gadget" }, + { } +}; + +U_BOOT_DRIVER(ci_udc_otg) = { + .name = "ci-udc-otg", + .id = UCLASS_USB_GADGET_GENERIC, + .of_match = ci_udc_otg_ids, + .ofdata_to_platdata = ci_udc_otg_ofdata_to_platdata, + .probe = ci_udc_otg_probe, + .remove = ci_udc_otg_remove, + .priv_auto_alloc_size = sizeof(struct ci_udc_priv_data), +}; + +#endif /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */ diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 20617850f3..2bfae1f661 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -37,18 +38,6 @@ DECLARE_GLOBAL_DATA_PTR; #define USB_H1_CTRL_OFFSET 0x04 -#define USBPHY_CTRL 0x00000030 -#define USBPHY_CTRL_SET 0x00000034 -#define USBPHY_CTRL_CLR 0x00000038 -#define USBPHY_CTRL_TOG 0x0000003c - -#define USBPHY_PWD 0x00000000 -#define USBPHY_CTRL_SFTRST 0x80000000 -#define USBPHY_CTRL_CLKGATE 0x40000000 -#define USBPHY_CTRL_ENUTMILEVEL3 0x00008000 -#define USBPHY_CTRL_ENUTMILEVEL2 0x00004000 -#define USBPHY_CTRL_OTG_ID 0x08000000 - #define ANADIG_USB2_CHRG_DETECT_EN_B 0x00100000 #define ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B 0x00080000 @@ -58,8 +47,6 @@ DECLARE_GLOBAL_DATA_PTR; #define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS 0x00000040 #define USBNC_OFFSET 0x200 -#define USBNC_PHY_STATUS_OFFSET 0x23C -#define USBNC_PHYSTATUS_ID_DIG (1 << 4) /* otg_id status */ #define USBNC_PHYCFG2_ACAENB (1 << 4) /* otg_id detection enable */ #define UCTRL_PWR_POL (1 << 9) /* OTG Polarity of Power Pin */ #define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */ diff --git a/include/usb/ci_udc.h b/include/usb/ci_udc.h index 06adb2bb4d..ddae8e178b 100644 --- a/include/usb/ci_udc.h +++ b/include/usb/ci_udc.h @@ -7,7 +7,10 @@ #ifndef __CI_UDC_H__ #define __CI_UDC_H__ +#include #define EP_MAX_PACKET_SIZE 0x200 #define EP0_MAX_PACKET_SIZE 64 + +int ehci_mx6_common_init(struct usb_ehci *ehci, int index); #endif /* __CI_UDC_H__ */