From patchwork Fri Aug 10 15:12:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrice CHOTARD X-Patchwork-Id: 956286 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=st.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41n7tQ1LCMz9ryt for ; Sat, 11 Aug 2018 01:13:34 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CB763C21D83; Fri, 10 Aug 2018 15:13:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 14F16C21DD9; Fri, 10 Aug 2018 15:12:45 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id C2905C21C27; Fri, 10 Aug 2018 15:12:42 +0000 (UTC) Received: from mx07-00178001.pphosted.com (mx08-00178001.pphosted.com [91.207.212.93]) by lists.denx.de (Postfix) with ESMTPS id 5D749C21BE5 for ; Fri, 10 Aug 2018 15:12:42 +0000 (UTC) Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w7AFAYr5008765; Fri, 10 Aug 2018 17:12:41 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2ksd45r090-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Fri, 10 Aug 2018 17:12:41 +0200 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id B323831; Fri, 10 Aug 2018 15:12:40 +0000 (GMT) Received: from Webmail-eu.st.com (sfhdag6node3.st.com [10.75.127.18]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 9FCB5504A; Fri, 10 Aug 2018 15:12:40 +0000 (GMT) Received: from localhost (10.75.127.46) by SFHDAG6NODE3.st.com (10.75.127.18) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Fri, 10 Aug 2018 17:12:39 +0200 From: Patrice Chotard To: Date: Fri, 10 Aug 2018 17:12:14 +0200 Message-ID: <1533913935-27058-5-git-send-email-patrice.chotard@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1533913935-27058-1-git-send-email-patrice.chotard@st.com> References: <1533913935-27058-1-git-send-email-patrice.chotard@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.46] X-ClientProxiedBy: SFHDAG3NODE1.st.com (10.75.127.7) To SFHDAG6NODE3.st.com (10.75.127.18) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-10_08:, , signatures=0 Cc: U-Boot STM32 Subject: [U-Boot] [PATCH v1 4/4] board: st: stm32mp1: Add usb gadget support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Enable USB gadget support using DWC2 driver Populate board_usb_init() to initialize clocks, phy, reset and data needed for DWC2 IP. Signed-off-by: Patrice Chotard --- board/st/stm32mp1/stm32mp1.c | 168 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index cc39fa6df9c3..a36ea228c7f4 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -4,13 +4,181 @@ */ #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include /* * Get a global data pointer */ DECLARE_GLOBAL_DATA_PTR; +#define STM32MP_GUSBCFG 0x40002407 + +#define STM32MP_GGPIO 0x38 +#define STM32MP_GGPIO_VBUS_SENSING BIT(21) + +static struct dwc2_plat_otg_data stm32mp_otg_data = { + .usb_gusbcfg = STM32MP_GUSBCFG, +}; + +static struct reset_ctl usbotg_reset; + +int board_usb_init(int index, enum usb_init_type init) +{ + struct fdtdec_phandle_args args; + struct udevice *dev; + const void *blob = gd->fdt_blob; + struct clk clk; + struct phy phy; + int node; + int phy_provider; + int ret; + + /* find the usb otg node */ + node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2"); + if (node < 0) { + debug("Not found usb_otg device\n"); + return -ENODEV; + } + + if (!fdtdec_get_is_enabled(blob, node)) { + debug("stm32 usbotg is disabled in the device tree\n"); + return -ENODEV; + } + + /* Enable clock */ + ret = fdtdec_parse_phandle_with_args(blob, node, "clocks", + "#clock-cells", 0, 0, &args); + if (ret) { + debug("usbotg has no clocks defined in the device tree\n"); + return ret; + } + + ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev); + if (ret) + return ret; + + if (args.args_count != 1) { + debug("Can't find clock ID in the device tree\n"); + return -ENODATA; + } + + clk.dev = dev; + clk.id = args.args[0]; + + ret = clk_enable(&clk); + if (ret) { + debug("Failed to enable usbotg clock\n"); + return ret; + } + + /* Reset */ + ret = fdtdec_parse_phandle_with_args(blob, node, "resets", + "#reset-cells", 0, 0, &args); + if (ret) { + debug("usbotg has no resets defined in the device tree\n"); + goto clk_err; + } + + ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev); + if (ret || args.args_count != 1) + goto clk_err; + + usbotg_reset.dev = dev; + usbotg_reset.id = args.args[0]; + + reset_assert(&usbotg_reset); + udelay(2); + reset_deassert(&usbotg_reset); + + /* Get USB PHY */ + ret = fdtdec_parse_phandle_with_args(blob, node, "phys", + "#phy-cells", 0, 0, &args); + if (!ret) { + phy_provider = fdt_parent_offset(blob, args.node); + ret = uclass_get_device_by_of_offset(UCLASS_PHY, + phy_provider, &dev); + if (ret) + goto clk_err; + + phy.dev = dev; + phy.id = fdtdec_get_uint(blob, args.node, "reg", -1); + + ret = generic_phy_power_on(&phy); + if (ret) { + debug("unable to power on the phy\n"); + goto clk_err; + } + + ret = generic_phy_init(&phy); + if (ret) { + debug("failed to init usb phy\n"); + goto phy_power_err; + } + } + + /* Parse and store data needed for gadget */ + stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); + if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) { + debug("usbotg: can't get base address\n"); + ret = -ENODATA; + goto phy_init_err; + } + + stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node, + "g-rx-fifo-size", 0); + stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node, + "g-np-tx-fifo-size", 0); + stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node, + "g-tx-fifo-size", 0); + /* Enable voltage level detector */ + if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply", + NULL, 0, 0, &args))) { + if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR, + args.node, &dev)) { + ret = regulator_set_enable(dev, true); + if (ret) { + debug("Failed to enable usb33d\n"); + goto phy_init_err; + } + } + } + /* Enable vbus sensing */ + setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO, + STM32MP_GGPIO_VBUS_SENSING); + + return dwc2_udc_probe(&stm32mp_otg_data); + +phy_init_err: + generic_phy_exit(&phy); + +phy_power_err: + generic_phy_power_off(&phy); + +clk_err: + clk_disable(&clk); + + return ret; +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + /* Reset usbotg */ + reset_assert(&usbotg_reset); + udelay(2); + reset_deassert(&usbotg_reset); + + return 0; +} + int board_late_init(void) { return 0;