Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &reg);
^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>");