^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * platform.c - DesignWare HS OTG Controller platform driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) Matthijs Kooijman <matthijs@stdin.nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * notice, this list of conditions, and the following disclaimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * without modification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * 3. The names of the above-listed copyright holders may not be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * to endorse or promote products derived from this software without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * ALTERNATIVELY, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * GNU General Public License ("GPL") as published by the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Foundation; either version 2 of the License, or (at your option) any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/platform_data/s3c-hsotg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/usb/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "hcd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const char dwc2_driver_name[] = "dwc2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Check the dr_mode against the module configuration and hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * The hardware, module, and dr_mode, can each be set to host, device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * or otg. Check that all these values are compatible and adjust the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * value of dr_mode if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * HW MOD dr_mode dr_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * ------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * HST HST any : HST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * HST DEV any : ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * HST OTG any : HST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * DEV HST any : ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * DEV DEV any : DEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * DEV OTG any : DEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * OTG HST any : HST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * OTG DEV any : DEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * OTG OTG any : dr_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) enum usb_dr_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) hsotg->dr_mode = usb_get_dr_mode(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (hsotg->dr_mode == USB_DR_MODE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) hsotg->dr_mode = USB_DR_MODE_OTG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mode = hsotg->dr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (dwc2_hw_is_device(hsotg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dev_err(hsotg->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) "Controller does not support host mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mode = USB_DR_MODE_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) } else if (dwc2_hw_is_host(hsotg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) dev_err(hsotg->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) "Controller does not support device mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mode = USB_DR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mode = USB_DR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) mode = USB_DR_MODE_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (mode != hsotg->dr_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) dev_warn(hsotg->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) "Configuration mismatch. dr_mode forced to %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) mode == USB_DR_MODE_HOST ? "host" : "device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) hsotg->dr_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void __dwc2_disable_regulators(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct dwc2_hsotg *hsotg = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int __dwc2_lowlevel_phy_enable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct platform_device *pdev = to_platform_device(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (hsotg->uphy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = usb_phy_init(hsotg->uphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } else if (hsotg->plat && hsotg->plat->phy_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ret = phy_power_on(hsotg->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = phy_init(hsotg->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * dwc2_lowlevel_phy_enable - enable lowlevel PHY resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * @hsotg: The driver state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * A wrapper for platform code responsible for controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * low-level PHY resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int dwc2_lowlevel_phy_enable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int ret = __dwc2_lowlevel_phy_enable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) hsotg->ll_phy_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int __dwc2_lowlevel_phy_disable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct platform_device *pdev = to_platform_device(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (hsotg->uphy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) usb_phy_shutdown(hsotg->uphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) } else if (hsotg->plat && hsotg->plat->phy_exit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ret = phy_exit(hsotg->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ret = phy_power_off(hsotg->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * dwc2_lowlevel_phy_disable - disable lowlevel PHY resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * @hsotg: The driver state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * A wrapper for platform code responsible for controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * low-level PHY platform resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int dwc2_lowlevel_phy_disable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int ret = __dwc2_lowlevel_phy_disable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) hsotg->ll_phy_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct platform_device *pdev = to_platform_device(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) hsotg->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ret = devm_add_action_or_reset(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) __dwc2_disable_regulators, hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = clk_bulk_prepare_enable(hsotg->num_clks, hsotg->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (!hsotg->ll_phy_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = dwc2_lowlevel_phy_enable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * dwc2_lowlevel_hw_enable - enable platform lowlevel hw resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * @hsotg: The driver state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * A wrapper for platform code responsible for controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * low-level USB platform resources (phy, clock, regulators)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int ret = __dwc2_lowlevel_hw_enable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) hsotg->ll_hw_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (hsotg->ll_phy_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = dwc2_lowlevel_phy_disable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) clk_bulk_disable_unprepare(hsotg->num_clks, hsotg->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * dwc2_lowlevel_hw_disable - disable platform lowlevel hw resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @hsotg: The driver state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * A wrapper for platform code responsible for controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * low-level USB platform resources (phy, clock, regulators)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int ret = __dwc2_lowlevel_hw_disable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) hsotg->ll_hw_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (IS_ERR(hsotg->reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ret = PTR_ERR(hsotg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) dev_err(hsotg->dev, "error getting reset control %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) reset_control_deassert(hsotg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) hsotg->reset_ecc = devm_reset_control_get_optional(hsotg->dev, "dwc2-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (IS_ERR(hsotg->reset_ecc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ret = PTR_ERR(hsotg->reset_ecc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_err(hsotg->dev, "error getting reset control for ecc %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) reset_control_deassert(hsotg->reset_ecc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * Attempt to find a generic PHY, then look for an old style
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * USB PHY and then fall back to pdata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (IS_ERR(hsotg->phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ret = PTR_ERR(hsotg->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case -ENOSYS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) hsotg->phy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case -EPROBE_DEFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dev_err(hsotg->dev, "error getting phy %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!hsotg->phy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (IS_ERR(hsotg->uphy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = PTR_ERR(hsotg->uphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case -ENXIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) hsotg->uphy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) case -EPROBE_DEFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dev_err(hsotg->dev, "error getting usb phy %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) hsotg->plat = dev_get_platdata(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (hsotg->dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = devm_clk_bulk_get_all(hsotg->dev, &hsotg->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ret == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * Clocks are optional, but new DT platforms should support all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * clocks as required by the DT-binding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) hsotg->num_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) hsotg->num_clks = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Regulators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) hsotg->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dev_err(hsotg->dev, "failed to request supplies: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * DWC_otg driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @dev: Platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * This routine is called, for example, when the rmmod command is executed. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * device may or may not be electrically present. If it is present, the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * stops device processing. Any resources used on behalf of this device are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static int dwc2_driver_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dwc2_debugfs_exit(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (hsotg->hcd_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dwc2_hcd_remove(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (hsotg->gadget_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) dwc2_hsotg_remove(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dwc2_drd_exit(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (hsotg->params.activate_stm_id_vb_detection)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) regulator_disable(hsotg->usb33d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pm_runtime_put_sync(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pm_runtime_disable(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (hsotg->ll_hw_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dwc2_lowlevel_hw_disable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) reset_control_assert(hsotg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) reset_control_assert(hsotg->reset_ecc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * dwc2_driver_shutdown() - Called on device shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * @dev: Platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * In specific conditions (involving usb hubs) dwc2 devices can create a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * lot of interrupts, even to the point of overwhelming devices running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * at low frequencies. Some devices need to do special clock handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * at shutdown-time which may bring the system clock below the threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * of being able to handle the dwc2 interrupts. Disabling dwc2-irqs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * prevents reboots/poweroffs from getting stuck in such cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static void dwc2_driver_shutdown(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dwc2_disable_global_interrupts(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) synchronize_irq(hsotg->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * dwc2_check_core_endianness() - Returns true if core and AHB have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * opposite endianness.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * @hsotg: Programming view of the DWC_otg controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static bool dwc2_check_core_endianness(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) u32 snpsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) snpsid = ioread32(hsotg->regs + GSNPSID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if ((snpsid & GSNPSID_ID_MASK) == DWC2_OTG_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) (snpsid & GSNPSID_ID_MASK) == DWC2_FS_IOT_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) (snpsid & GSNPSID_ID_MASK) == DWC2_HS_IOT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * Check core version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * @hsotg: Programming view of the DWC_otg controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int dwc2_check_core_version(struct dwc2_hsotg *hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct dwc2_hw_params *hw = &hsotg->hw_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * Attempt to ensure this device is really a DWC_otg Controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * Read and verify the GSNPSID register contents. The value should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * 0x45f4xxxx, 0x5531xxxx or 0x5532xxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) hw->snpsid = dwc2_readl(hsotg, GSNPSID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if ((hw->snpsid & GSNPSID_ID_MASK) != DWC2_OTG_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) (hw->snpsid & GSNPSID_ID_MASK) != DWC2_FS_IOT_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) (hw->snpsid & GSNPSID_ID_MASK) != DWC2_HS_IOT_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) hw->snpsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x (snpsid=%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * @dev: Platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * This routine creates the driver components required to control the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * (core, HCD, and PCD) and initializes the device. The driver components are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * stored in a dwc2_hsotg structure. A reference to the dwc2_hsotg is saved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * in the device private data. This allows the driver to access the dwc2_hsotg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * structure on subsequent calls to driver methods for this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int dwc2_driver_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct dwc2_hsotg *hsotg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (!hsotg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) hsotg->dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * Use reasonable defaults so platforms don't have to provide these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!dev->dev.dma_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) retval = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) dev_err(&dev->dev, "can't set coherent DMA mask: %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) hsotg->regs = devm_platform_get_and_ioremap_resource(dev, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (IS_ERR(hsotg->regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return PTR_ERR(hsotg->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) (unsigned long)res->start, hsotg->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) retval = dwc2_lowlevel_hw_init(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) spin_lock_init(&hsotg->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) hsotg->irq = platform_get_irq(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (hsotg->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return hsotg->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) hsotg->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) retval = devm_request_irq(hsotg->dev, hsotg->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) dwc2_handle_common_intr, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dev_name(hsotg->dev), hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (IS_ERR(hsotg->vbus_supply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) retval = PTR_ERR(hsotg->vbus_supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) hsotg->vbus_supply = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (retval != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) retval = dwc2_lowlevel_hw_enable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) pm_runtime_enable(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) retval = pm_runtime_get_sync(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) retval = dwc2_get_dr_mode(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) hsotg->need_phy_for_wake =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) of_property_read_bool(dev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) "snps,need-phy-for-wake");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * Before performing any core related operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * check core version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) retval = dwc2_check_core_version(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * Reset before dwc2_get_hwparams() then it could get power-on real
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * reset value form registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) retval = dwc2_core_reset(hsotg, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* Detect config values from hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) retval = dwc2_get_hwparams(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * For OTG cores, set the force mode bits to reflect the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * of dr_mode. Force mode bits should not be touched at any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * other time after this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) dwc2_force_dr_mode(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) retval = dwc2_init_params(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (hsotg->params.activate_stm_id_vb_detection) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u32 ggpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) hsotg->usb33d = devm_regulator_get(hsotg->dev, "usb33d");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (IS_ERR(hsotg->usb33d)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) retval = PTR_ERR(hsotg->usb33d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (retval != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) dev_err(hsotg->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) "failed to request usb33d supply: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) retval = regulator_enable(hsotg->usb33d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dev_err(hsotg->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) "failed to enable usb33d supply: %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ggpio = dwc2_readl(hsotg, GGPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ggpio |= GGPIO_STM32_OTG_GCCFG_IDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) dwc2_writel(hsotg, ggpio, GGPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* ID/VBUS detection startup time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) usleep_range(5000, 7000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) retval = dwc2_drd_init(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (retval != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) dev_err(hsotg->dev, "failed to initialize dual-role\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) goto error_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (hsotg->dr_mode != USB_DR_MODE_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) retval = dwc2_gadget_init(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) goto error_drd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) hsotg->gadget_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * If we need PHY for wakeup we must be wakeup capable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * When we have a device that can wake without the PHY we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * can adjust this condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (hsotg->need_phy_for_wake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) device_set_wakeup_capable(&dev->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) hsotg->reset_phy_on_wake =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) of_property_read_bool(dev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) "snps,reset-phy-on-wake");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (hsotg->reset_phy_on_wake && !hsotg->phy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dev_warn(hsotg->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) "Quirk reset-phy-on-wake only supports generic PHYs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) hsotg->reset_phy_on_wake = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) retval = dwc2_hcd_init(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (hsotg->gadget_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dwc2_hsotg_remove(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) goto error_drd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) hsotg->hcd_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) platform_set_drvdata(dev, hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) hsotg->hibernated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dwc2_debugfs_init(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* Gadget code manages lowlevel hw on its own */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) dwc2_lowlevel_hw_disable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (hsotg->ll_phy_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) dwc2_lowlevel_phy_disable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* Postponed adding a new gadget to the udc class driver list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (hsotg->gadget_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) retval = usb_add_gadget_udc(hsotg->dev, &hsotg->gadget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) hsotg->gadget.udc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) dwc2_hsotg_remove(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) goto error_debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) error_debugfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) dwc2_debugfs_exit(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (hsotg->hcd_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) dwc2_hcd_remove(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) error_drd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) dwc2_drd_exit(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) error_init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (hsotg->params.activate_stm_id_vb_detection)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) regulator_disable(hsotg->usb33d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) pm_runtime_put_sync(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) pm_runtime_disable(hsotg->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dwc2_lowlevel_hw_disable(hsotg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static int __maybe_unused dwc2_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) bool is_device_mode = dwc2_is_device_mode(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (is_device_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) dwc2_hsotg_suspend(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) dwc2_drd_suspend(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (dwc2->params.activate_stm_id_vb_detection) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) u32 ggpio, gotgctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * Need to force the mode to the current mode to avoid Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Mismatch Interrupt when ID detection will be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) dwc2_force_mode(dwc2, !is_device_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) spin_lock_irqsave(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) gotgctl = dwc2_readl(dwc2, GOTGCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* bypass debounce filter, enable overrides */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) gotgctl |= GOTGCTL_DBNCE_FLTR_BYPASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) gotgctl |= GOTGCTL_BVALOEN | GOTGCTL_AVALOEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* Force A / B session if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (gotgctl & GOTGCTL_ASESVLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) gotgctl |= GOTGCTL_AVALOVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (gotgctl & GOTGCTL_BSESVLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) gotgctl |= GOTGCTL_BVALOVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) dwc2_writel(dwc2, gotgctl, GOTGCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) spin_unlock_irqrestore(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) ggpio = dwc2_readl(dwc2, GGPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ggpio &= ~GGPIO_STM32_OTG_GCCFG_IDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ggpio &= ~GGPIO_STM32_OTG_GCCFG_VBDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dwc2_writel(dwc2, ggpio, GGPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) regulator_disable(dwc2->usb33d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (dwc2->ll_hw_enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) (is_device_mode || dwc2_host_can_poweroff_phy(dwc2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ret = __dwc2_lowlevel_hw_disable(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) dwc2->phy_off_for_suspend = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static int __maybe_unused dwc2_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ret = __dwc2_lowlevel_hw_enable(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) dwc2->phy_off_for_suspend = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (dwc2->params.activate_stm_id_vb_detection) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) u32 ggpio, gotgctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ret = regulator_enable(dwc2->usb33d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ggpio = dwc2_readl(dwc2, GGPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ggpio |= GGPIO_STM32_OTG_GCCFG_IDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dwc2_writel(dwc2, ggpio, GGPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* ID/VBUS detection startup time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) usleep_range(5000, 7000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) spin_lock_irqsave(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) gotgctl = dwc2_readl(dwc2, GOTGCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) gotgctl &= ~GOTGCTL_DBNCE_FLTR_BYPASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) gotgctl &= ~(GOTGCTL_BVALOEN | GOTGCTL_AVALOEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) GOTGCTL_BVALOVAL | GOTGCTL_AVALOVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) dwc2_writel(dwc2, gotgctl, GOTGCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) spin_unlock_irqrestore(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* Need to restore FORCEDEVMODE/FORCEHOSTMODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dwc2_force_dr_mode(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) dwc2_drd_resume(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (dwc2->dr_mode == USB_DR_MODE_HOST && dwc2_is_device_mode(dwc2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* Reinit for Host mode if lost power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dwc2_force_mode(dwc2, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) spin_lock_irqsave(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) dwc2_hsotg_disconnect(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) spin_unlock_irqrestore(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) dwc2->op_state = OTG_STATE_A_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* Initialize the Core for Host mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dwc2_core_init(dwc2, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dwc2_enable_global_interrupts(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dwc2_hcd_start(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) } else if (dwc2->dr_mode == USB_DR_MODE_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) dwc2->op_state == OTG_STATE_A_HOST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) !(dwc2_readl(dwc2, HPRT0) & HPRT0_PWR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * Reinit the core to device mode, and later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * after do dwc2_hsotg_resume, it can trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * the ID status change interrupt if the OTG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * cable is still connected, then we can init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * for Host mode in the ID status change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) spin_lock_irqsave(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) dwc2_hcd_disconnect(dwc2, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) dwc2->op_state = OTG_STATE_B_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) dwc2->lx_state = DWC2_L3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (!dwc2->driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dwc2_hsotg_core_init_disconnected(dwc2, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) spin_unlock_irqrestore(&dwc2->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ret = dwc2_hsotg_resume(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) } else if (dwc2_is_device_mode(dwc2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) (dwc2_is_host_mode(dwc2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) dwc2->dr_mode == USB_DR_MODE_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dwc2->op_state == OTG_STATE_B_PERIPHERAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ret = dwc2_hsotg_resume(dwc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static const struct dev_pm_ops dwc2_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) SET_SYSTEM_SLEEP_PM_OPS(dwc2_suspend, dwc2_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static struct platform_driver dwc2_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .name = dwc2_driver_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .of_match_table = dwc2_of_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .pm = &dwc2_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .probe = dwc2_driver_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .remove = dwc2_driver_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .shutdown = dwc2_driver_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) module_platform_driver(dwc2_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) MODULE_DESCRIPTION("DESIGNWARE HS OTG Platform Glue");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) MODULE_AUTHOR("Matthijs Kooijman <matthijs@stdin.nl>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) MODULE_LICENSE("Dual BSD/GPL");