^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * USB Glue for Amlogic G12A SoCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2019 BayLibre, SAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Neil Armstrong <narmstrong@baylibre.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * The USB is organized with a glue around the DWC3 Controller IP as :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * - Control registers for each USB2 Ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * - Control registers for the USB PHY layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * - SuperSpeed PHY can be enabled only if port is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * - Dynamic OTG switching with ID change interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/usb/otg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/usb/role.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* USB2 Ports Control Registers, offsets are per-port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define U2P_REG_SIZE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define U2P_R0 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define U2P_R0_HOST_DEVICE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define U2P_R0_POWER_OK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define U2P_R0_HAST_MODE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define U2P_R0_POWER_ON_RESET BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define U2P_R0_ID_PULLUP BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define U2P_R0_DRV_VBUS BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define U2P_R1 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define U2P_R1_PHY_READY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define U2P_R1_ID_DIG BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define U2P_R1_OTG_SESSION_VALID BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define U2P_R1_VBUS_VALID BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* USB Glue Control Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define G12A_GLUE_OFFSET 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define USB_R0 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define USB_R0_U2D_ACT BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define USB_R1 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define USB_R1_U3H_BIGENDIAN_GS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define USB_R1_U3H_PME_ENABLE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(4, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK GENMASK(9, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK GENMASK(13, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define USB_R1_U3H_HOST_U3_PORT_DISABLE BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define USB_R1_U3H_HOST_MSI_ENABLE BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define USB_R2 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define USB_R3 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define USB_R3_P30_SSC_ENABLE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define USB_R3_P30_REF_SSP_EN BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define USB_R4 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define USB_R4_P21_PORT_RESET_0 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define USB_R4_P21_SLEEP_M0 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define USB_R4_MEM_PD_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define USB_R4_P21_ONLY BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define USB_R5 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define USB_R5_ID_DIG_SYNC BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define USB_R5_ID_DIG_REG BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define USB_R5_ID_DIG_EN_0 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define USB_R5_ID_DIG_EN_1 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define USB_R5_ID_DIG_CURR BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define USB_R5_ID_DIG_IRQ BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define USB_R5_ID_DIG_TH_MASK GENMASK(15, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define USB_R5_ID_DIG_CNT_MASK GENMASK(23, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define PHY_COUNT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define USB2_OTG_PHY 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static struct clk_bulk_data meson_gxl_clocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) { .id = "usb_ctrl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) { .id = "ddr" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static struct clk_bulk_data meson_g12a_clocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) { .id = NULL },
^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) static struct clk_bulk_data meson_a1_clocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { .id = "usb_ctrl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { .id = "usb_bus" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { .id = "xtal_usb_ctrl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static const char * const meson_gxm_phy_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) "usb2-phy0", "usb2-phy1", "usb2-phy2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static const char * const meson_g12a_phy_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "usb2-phy0", "usb2-phy1", "usb3-phy0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Amlogic A1 has a single physical PHY, in slot 1, but still has the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * two U2 PHY controls register blocks like G12A.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * AXG has the similar scheme, thus needs the same tweak.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Handling the first PHY on slot 1 would need a large amount of code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * changes, and the current management is generic enough to handle it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * correctly when only the "usb2-phy1" phy is specified on-par with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * DT bindings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static const char * const meson_a1_phy_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "usb2-phy0", "usb2-phy1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct dwc3_meson_g12a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct dwc3_meson_g12a_drvdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) bool otg_switch_supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) bool otg_phy_host_port_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct clk_bulk_data *clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) const char * const *phy_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int num_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int (*setup_regmaps)(struct dwc3_meson_g12a *priv, void __iomem *base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int (*usb2_init_phy)(struct dwc3_meson_g12a *priv, int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum phy_mode mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int (*set_phy_mode)(struct dwc3_meson_g12a *priv, int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) enum phy_mode mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int (*usb_init)(struct dwc3_meson_g12a *priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int (*usb_post_init)(struct dwc3_meson_g12a *priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int dwc3_meson_gxl_setup_regmaps(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) void __iomem *base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) void __iomem *base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int dwc3_meson_g12a_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) enum phy_mode mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int dwc3_meson_gxl_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) enum phy_mode mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static int dwc3_meson_g12a_set_phy_mode(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int i, enum phy_mode mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int dwc3_meson_gxl_set_phy_mode(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int i, enum phy_mode mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int dwc3_meson_gxl_usb_init(struct dwc3_meson_g12a *priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int dwc3_meson_gxl_usb_post_init(struct dwc3_meson_g12a *priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * For GXL and GXM SoCs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * USB Phy muxing between the DWC2 Device controller and the DWC3 Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * controller is buggy when switching from Device to Host when USB port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * is unpopulated, it causes the DWC3 to hard crash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * When populated (including OTG switching with ID pin), the switch works
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * like a charm like on the G12A platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * In order to still switch from Host to Device on an USB Type-A port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * an U2_PORT_DISABLE bit has been added to disconnect the DWC3 Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * controller from the port, but when used the DWC3 controller must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * reset to recover usage of the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static struct dwc3_meson_g12a_drvdata gxl_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .otg_switch_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .otg_phy_host_port_disable = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .clks = meson_gxl_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .num_clks = ARRAY_SIZE(meson_g12a_clocks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .phy_names = meson_a1_phy_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .num_phys = ARRAY_SIZE(meson_a1_phy_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .setup_regmaps = dwc3_meson_gxl_setup_regmaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .usb2_init_phy = dwc3_meson_gxl_usb2_init_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .set_phy_mode = dwc3_meson_gxl_set_phy_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .usb_init = dwc3_meson_gxl_usb_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .usb_post_init = dwc3_meson_gxl_usb_post_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static struct dwc3_meson_g12a_drvdata gxm_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .otg_switch_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .otg_phy_host_port_disable = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .clks = meson_gxl_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .num_clks = ARRAY_SIZE(meson_g12a_clocks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .phy_names = meson_gxm_phy_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .num_phys = ARRAY_SIZE(meson_gxm_phy_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .setup_regmaps = dwc3_meson_gxl_setup_regmaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .usb2_init_phy = dwc3_meson_gxl_usb2_init_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .set_phy_mode = dwc3_meson_gxl_set_phy_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .usb_init = dwc3_meson_gxl_usb_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .usb_post_init = dwc3_meson_gxl_usb_post_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static struct dwc3_meson_g12a_drvdata axg_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .otg_switch_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .clks = meson_gxl_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .num_clks = ARRAY_SIZE(meson_gxl_clocks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .phy_names = meson_a1_phy_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .num_phys = ARRAY_SIZE(meson_a1_phy_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .setup_regmaps = dwc3_meson_gxl_setup_regmaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .usb2_init_phy = dwc3_meson_gxl_usb2_init_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .set_phy_mode = dwc3_meson_gxl_set_phy_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .usb_init = dwc3_meson_g12a_usb_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .usb_post_init = dwc3_meson_gxl_usb_post_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static struct dwc3_meson_g12a_drvdata g12a_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .otg_switch_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .clks = meson_g12a_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .num_clks = ARRAY_SIZE(meson_g12a_clocks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .phy_names = meson_g12a_phy_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .num_phys = ARRAY_SIZE(meson_g12a_phy_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .setup_regmaps = dwc3_meson_g12a_setup_regmaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .usb2_init_phy = dwc3_meson_g12a_usb2_init_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .set_phy_mode = dwc3_meson_g12a_set_phy_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .usb_init = dwc3_meson_g12a_usb_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static struct dwc3_meson_g12a_drvdata a1_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .otg_switch_supported = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .clks = meson_a1_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .num_clks = ARRAY_SIZE(meson_a1_clocks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .phy_names = meson_a1_phy_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .num_phys = ARRAY_SIZE(meson_a1_phy_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .setup_regmaps = dwc3_meson_g12a_setup_regmaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .usb2_init_phy = dwc3_meson_g12a_usb2_init_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .set_phy_mode = dwc3_meson_g12a_set_phy_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .usb_init = dwc3_meson_g12a_usb_init,
^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) struct dwc3_meson_g12a {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct regmap *u2p_regmap[PHY_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct regmap *usb_glue_regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct reset_control *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct phy *phys[PHY_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) enum usb_dr_mode otg_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) enum phy_mode otg_phy_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned int usb2_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned int usb3_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct regulator *vbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct usb_role_switch_desc switch_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct usb_role_switch *role_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) const struct dwc3_meson_g12a_drvdata *drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int dwc3_meson_gxl_set_phy_mode(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int i, enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return phy_set_mode(priv->phys[i], mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int dwc3_meson_gxl_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* On GXL PHY must be started in device mode for DWC2 init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return priv->drvdata->set_phy_mode(priv, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) (i == USB2_OTG_PHY) ? PHY_MODE_USB_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) : PHY_MODE_USB_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static int dwc3_meson_g12a_set_phy_mode(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int i, enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (mode == PHY_MODE_USB_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) U2P_R0_HOST_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) U2P_R0_HOST_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) U2P_R0_HOST_DEVICE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int dwc3_meson_g12a_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) U2P_R0_POWER_ON_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) U2P_R0_POWER_ON_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = priv->drvdata->set_phy_mode(priv, i, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ret = priv->drvdata->set_phy_mode(priv, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) PHY_MODE_USB_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) U2P_R0_POWER_ON_RESET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) for (i = 0; i < priv->drvdata->num_phys; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (!priv->phys[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!strstr(priv->drvdata->phy_names[i], "usb2"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ret = priv->drvdata->usb2_init_phy(priv, i, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 0;
^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) static void dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) regmap_update_bits(priv->usb_glue_regmap, USB_R3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) USB_R3_P30_SSC_RANGE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) USB_R3_P30_REF_SSP_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) USB_R3_P30_SSC_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) FIELD_PREP(USB_R3_P30_SSC_RANGE_MASK, 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) USB_R3_P30_REF_SSP_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) udelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) regmap_update_bits(priv->usb_glue_regmap, USB_R2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 0x15));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) regmap_update_bits(priv->usb_glue_regmap, USB_R2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 0x20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) udelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) regmap_update_bits(priv->usb_glue_regmap, USB_R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) regmap_update_bits(priv->usb_glue_regmap, USB_R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) USB_R1_P30_PCS_TX_SWING_FULL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) FIELD_PREP(USB_R1_P30_PCS_TX_SWING_FULL_MASK, 127));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static void dwc3_meson_g12a_usb_otg_apply_mode(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (mode == PHY_MODE_USB_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (priv->otg_mode != USB_DR_MODE_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) priv->drvdata->otg_phy_host_port_disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* Isolate the OTG PHY port from the Host Controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) regmap_update_bits(priv->usb_glue_regmap, USB_R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) FIELD_PREP(USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) BIT(USB2_OTG_PHY)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) regmap_update_bits(priv->usb_glue_regmap, USB_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) USB_R0_U2D_ACT, USB_R0_U2D_ACT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) regmap_update_bits(priv->usb_glue_regmap, USB_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) USB_R0_U2D_SS_SCALEDOWN_MODE_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) regmap_update_bits(priv->usb_glue_regmap, USB_R4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) USB_R4_P21_SLEEP_M0, USB_R4_P21_SLEEP_M0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (priv->otg_mode != USB_DR_MODE_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) priv->drvdata->otg_phy_host_port_disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) regmap_update_bits(priv->usb_glue_regmap, USB_R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) regmap_update_bits(priv->usb_glue_regmap, USB_R0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) USB_R0_U2D_ACT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) regmap_update_bits(priv->usb_glue_regmap, USB_R4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) USB_R4_P21_SLEEP_M0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static int dwc3_meson_g12a_usb_init_glue(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ret = dwc3_meson_g12a_usb2_init(priv, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) regmap_update_bits(priv->usb_glue_regmap, USB_R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) USB_R1_U3H_FLADJ_30MHZ_REG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) regmap_update_bits(priv->usb_glue_regmap, USB_R5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) USB_R5_ID_DIG_EN_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) USB_R5_ID_DIG_EN_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) regmap_update_bits(priv->usb_glue_regmap, USB_R5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) USB_R5_ID_DIG_EN_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) USB_R5_ID_DIG_EN_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) regmap_update_bits(priv->usb_glue_regmap, USB_R5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) USB_R5_ID_DIG_TH_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* If we have an actual SuperSpeed port, initialize it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (priv->usb3_ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) dwc3_meson_g12a_usb3_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) dwc3_meson_g12a_usb_otg_apply_mode(priv, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static const struct regmap_config phy_meson_g12a_usb_glue_regmap_conf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .name = "usb-glue",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .max_register = USB_R5,
^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) static int dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) const char *phy_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) for (i = 0 ; i < priv->drvdata->num_phys ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) phy_name = priv->drvdata->phy_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) priv->phys[i] = devm_phy_optional_get(priv->dev, phy_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!priv->phys[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (IS_ERR(priv->phys[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return PTR_ERR(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (strstr(phy_name, "usb3"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) priv->usb3_ports++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) priv->usb2_ports++;
^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) dev_info(priv->dev, "USB2 ports: %d\n", priv->usb2_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) dev_info(priv->dev, "USB3 ports: %d\n", priv->usb3_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static enum phy_mode dwc3_meson_g12a_get_id(struct dwc3_meson_g12a *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) regmap_read(priv->usb_glue_regmap, USB_R5, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (reg & (USB_R5_ID_DIG_SYNC | USB_R5_ID_DIG_REG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return PHY_MODE_USB_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return PHY_MODE_USB_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static int dwc3_meson_g12a_otg_mode_set(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) enum phy_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!priv->drvdata->otg_switch_supported || !priv->phys[USB2_OTG_PHY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (mode == PHY_MODE_USB_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) dev_info(priv->dev, "switching to Host Mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) dev_info(priv->dev, "switching to Device Mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (priv->vbus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (mode == PHY_MODE_USB_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ret = regulator_disable(priv->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ret = regulator_enable(priv->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) priv->otg_phy_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) dwc3_meson_g12a_usb_otg_apply_mode(priv, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int dwc3_meson_g12a_role_set(struct usb_role_switch *sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) enum usb_role role)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct dwc3_meson_g12a *priv = usb_role_switch_get_drvdata(sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) enum phy_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (role == USB_ROLE_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) mode = (role == USB_ROLE_HOST) ? PHY_MODE_USB_HOST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) : PHY_MODE_USB_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (mode == priv->otg_phy_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (priv->drvdata->otg_phy_host_port_disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) dev_warn_once(priv->dev, "Broken manual OTG switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return dwc3_meson_g12a_otg_mode_set(priv, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static enum usb_role dwc3_meson_g12a_role_get(struct usb_role_switch *sw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct dwc3_meson_g12a *priv = usb_role_switch_get_drvdata(sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return priv->otg_phy_mode == PHY_MODE_USB_HOST ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) USB_ROLE_HOST : USB_ROLE_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static irqreturn_t dwc3_meson_g12a_irq_thread(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct dwc3_meson_g12a *priv = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) enum phy_mode otg_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) otg_id = dwc3_meson_g12a_get_id(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (otg_id != priv->otg_phy_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (dwc3_meson_g12a_otg_mode_set(priv, otg_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) dev_warn(priv->dev, "Failed to switch OTG mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) regmap_update_bits(priv->usb_glue_regmap, USB_R5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) USB_R5_ID_DIG_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static struct device *dwc3_meson_g12_find_child(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) const char *compatible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) np = of_get_compatible_child(dev->of_node, compatible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) pdev = of_find_device_by_node(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int dwc3_meson_g12a_otg_init(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct dwc3_meson_g12a *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) enum phy_mode otg_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (!priv->drvdata->otg_switch_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (priv->otg_mode == USB_DR_MODE_OTG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Ack irq before registering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) regmap_update_bits(priv->usb_glue_regmap, USB_R5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) USB_R5_ID_DIG_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dwc3_meson_g12a_irq_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) IRQF_ONESHOT, pdev->name, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* Setup OTG mode corresponding to the ID pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (priv->otg_mode == USB_DR_MODE_OTG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) otg_id = dwc3_meson_g12a_get_id(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (otg_id != priv->otg_phy_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (dwc3_meson_g12a_otg_mode_set(priv, otg_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dev_warn(dev, "Failed to switch OTG mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* Setup role switcher */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) priv->switch_desc.usb2_port = dwc3_meson_g12_find_child(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) "snps,dwc3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) priv->switch_desc.udc = dwc3_meson_g12_find_child(dev, "snps,dwc2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) priv->switch_desc.allow_userspace_control = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) priv->switch_desc.set = dwc3_meson_g12a_role_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) priv->switch_desc.get = dwc3_meson_g12a_role_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) priv->switch_desc.driver_data = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) priv->role_switch = usb_role_switch_register(dev, &priv->switch_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (IS_ERR(priv->role_switch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dev_warn(dev, "Unable to register Role Switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int dwc3_meson_gxl_setup_regmaps(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* GXL controls the PHY mode in the PHY registers unlike G12A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) &phy_meson_g12a_usb_glue_regmap_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return PTR_ERR_OR_ZERO(priv->usb_glue_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) base + G12A_GLUE_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) &phy_meson_g12a_usb_glue_regmap_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (IS_ERR(priv->usb_glue_regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return PTR_ERR(priv->usb_glue_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* Create a regmap for each USB2 PHY control register set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) for (i = 0; i < priv->drvdata->num_phys; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct regmap_config u2p_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .max_register = U2P_R1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (!strstr(priv->drvdata->phy_names[i], "usb2"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) u2p_regmap_config.name = devm_kasprintf(priv->dev, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) "u2p-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!u2p_regmap_config.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) priv->u2p_regmap[i] = devm_regmap_init_mmio(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) base + (i * U2P_REG_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) &u2p_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (IS_ERR(priv->u2p_regmap[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return PTR_ERR(priv->u2p_regmap[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return dwc3_meson_g12a_usb_init_glue(priv, priv->otg_phy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static int dwc3_meson_gxl_usb_init(struct dwc3_meson_g12a *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return dwc3_meson_g12a_usb_init_glue(priv, PHY_MODE_USB_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int dwc3_meson_gxl_usb_post_init(struct dwc3_meson_g12a *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) priv->otg_phy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dwc3_meson_g12a_usb_otg_apply_mode(priv, priv->otg_phy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int dwc3_meson_g12a_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct dwc3_meson_g12a *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (IS_ERR(base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) priv->drvdata = of_device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) priv->vbus = devm_regulator_get_optional(dev, "vbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (IS_ERR(priv->vbus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (PTR_ERR(priv->vbus) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return PTR_ERR(priv->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) priv->vbus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ret = devm_clk_bulk_get(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) priv->drvdata->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) priv->drvdata->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret = clk_bulk_prepare_enable(priv->drvdata->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) priv->drvdata->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) platform_set_drvdata(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) priv->reset = devm_reset_control_get_shared(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (IS_ERR(priv->reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) ret = PTR_ERR(priv->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) dev_err(dev, "failed to get device reset, err=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) goto err_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) ret = reset_control_reset(priv->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) goto err_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = dwc3_meson_g12a_get_phys(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) goto err_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ret = priv->drvdata->setup_regmaps(priv, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) goto err_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (priv->vbus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ret = regulator_enable(priv->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) goto err_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* Get dr_mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) priv->otg_mode = usb_get_dr_mode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (priv->otg_mode == USB_DR_MODE_PERIPHERAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) priv->otg_phy_mode = PHY_MODE_USB_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) priv->otg_phy_mode = PHY_MODE_USB_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ret = priv->drvdata->usb_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) goto err_disable_regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /* Init PHYs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) for (i = 0 ; i < PHY_COUNT ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ret = phy_init(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) goto err_disable_regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* Set PHY Power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) for (i = 0 ; i < PHY_COUNT ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ret = phy_power_on(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) goto err_phys_exit;
^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) if (priv->drvdata->usb_post_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ret = priv->drvdata->usb_post_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) goto err_phys_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret = of_platform_populate(np, NULL, NULL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) goto err_phys_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) ret = dwc3_meson_g12a_otg_init(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) goto err_phys_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) err_phys_power:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) for (i = 0 ; i < PHY_COUNT ; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) phy_power_off(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) err_phys_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) for (i = 0 ; i < PHY_COUNT ; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) phy_exit(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) err_disable_regulator:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (priv->vbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) regulator_disable(priv->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) err_disable_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) clk_bulk_disable_unprepare(priv->drvdata->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) priv->drvdata->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static int dwc3_meson_g12a_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct dwc3_meson_g12a *priv = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (priv->drvdata->otg_switch_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) usb_role_switch_unregister(priv->role_switch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) of_platform_depopulate(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) for (i = 0 ; i < PHY_COUNT ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) phy_power_off(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) phy_exit(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) pm_runtime_put_noidle(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) pm_runtime_set_suspended(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) clk_bulk_disable_unprepare(priv->drvdata->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) priv->drvdata->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static int __maybe_unused dwc3_meson_g12a_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) clk_bulk_disable_unprepare(priv->drvdata->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) priv->drvdata->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static int __maybe_unused dwc3_meson_g12a_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return clk_bulk_prepare_enable(priv->drvdata->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) priv->drvdata->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ret = regulator_disable(priv->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) for (i = 0 ; i < PHY_COUNT ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) phy_power_off(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) phy_exit(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) reset_control_assert(priv->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) reset_control_deassert(priv->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = priv->drvdata->usb_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* Init PHYs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) for (i = 0 ; i < PHY_COUNT ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ret = phy_init(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* Set PHY Power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) for (i = 0 ; i < PHY_COUNT ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) ret = phy_power_on(priv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ret = regulator_enable(priv->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static const struct dev_pm_ops dwc3_meson_g12a_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) SET_SYSTEM_SLEEP_PM_OPS(dwc3_meson_g12a_suspend, dwc3_meson_g12a_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) SET_RUNTIME_PM_OPS(dwc3_meson_g12a_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) dwc3_meson_g12a_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static const struct of_device_id dwc3_meson_g12a_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .compatible = "amlogic,meson-gxl-usb-ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .data = &gxl_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .compatible = "amlogic,meson-gxm-usb-ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) .data = &gxm_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .compatible = "amlogic,meson-axg-usb-ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .data = &axg_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .compatible = "amlogic,meson-g12a-usb-ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .data = &g12a_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .compatible = "amlogic,meson-a1-usb-ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .data = &a1_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) { /* Sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) MODULE_DEVICE_TABLE(of, dwc3_meson_g12a_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static struct platform_driver dwc3_meson_g12a_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .probe = dwc3_meson_g12a_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .remove = dwc3_meson_g12a_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .name = "dwc3-meson-g12a",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .of_match_table = dwc3_meson_g12a_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .pm = &dwc3_meson_g12a_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) module_platform_driver(dwc3_meson_g12a_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) MODULE_DESCRIPTION("Amlogic Meson G12A USB Glue Layer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");