mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
phy: phy-imx8mq-usb: Add support for i.MX95 USB3 PHY
Add initial support for i.MX95 USB.30 PHY, which is similar to the i.MX8MQ and i.MX8MP USB PHY. The i.MX95 USB3 PHY has a Type-C Assist block (TCA) consisting of two functional blocks (XBar assist and VBus assist) and is documented in the i.MX95 RM Chapter 163.3.8 Type-C assist (TCA) block. Instead of relying on an external MUX for Type-C plug orientation the XBar can handle the flip internally. Add initial support for i.MX95 by: - allowing the driver to be enabled i.MX95 - resetting the XBar - configuring the TCA in System Configuration mode (which was determined to be necessary to enable the PHY in device-mode) Follow-on support will need to be added to steer the XBar based on either board design (if only one pair is brought out) or if used with a Type-C controller. Signed-off-by: Tim Harvey <tharvey@gateworks.com> Tested-by: Alice Guo <alice.guo@nxp.com>
This commit is contained in:
@@ -289,11 +289,11 @@ config PHY_NPCM_USB
|
||||
Support the USB PHY in NPCM SoCs
|
||||
|
||||
config PHY_IMX8MQ_USB
|
||||
bool "NXP i.MX8MQ/i.MX8MP USB PHY Driver"
|
||||
bool "NXP i.MX8MQ/i.MX8MP/i.MX95 USB PHY Driver"
|
||||
depends on PHY
|
||||
depends on IMX8MQ || IMX8MP
|
||||
depends on IMX8MQ || IMX8MP || IMX95
|
||||
help
|
||||
Support the USB3.0 PHY in NXP i.MX8MQ or i.MX8MP SoC
|
||||
Support the USB3.0 PHY in NXP i.MX8MQ, i.MX8MP, and i.MX95 SoC
|
||||
|
||||
config PHY_IMX8M_PCIE
|
||||
bool "NXP i.MX8MM/i.MX8MP PCIe PHY Driver"
|
||||
|
||||
@@ -71,9 +71,57 @@
|
||||
#define PHY_STS0_FSVPLUS BIT(3)
|
||||
#define PHY_STS0_FSVMINUS BIT(2)
|
||||
|
||||
#define TCA_CLK_RST 0x00
|
||||
#define TCA_CLK_RST_SW BIT(9)
|
||||
#define TCA_CLK_RST_REF_CLK_EN BIT(1)
|
||||
#define TCA_CLK_RST_SUSPEND_CLK_EN BIT(0)
|
||||
|
||||
#define TCA_INTR_EN 0x04
|
||||
#define TCA_INTR_STS 0x08
|
||||
|
||||
#define TCA_GCFG 0x10
|
||||
#define TCA_GCFG_ROLE_HSTDEV BIT(4)
|
||||
#define TCA_GCFG_OP_MODE GENMASK(1, 0)
|
||||
#define TCA_GCFG_OP_MODE_SYSMODE 0
|
||||
#define TCA_GCFG_OP_MODE_SYNCMODE 1
|
||||
|
||||
#define TCA_TCPC 0x14
|
||||
#define TCA_TCPC_VALID BIT(4)
|
||||
#define TCA_TCPC_LOW_POWER_EN BIT(3)
|
||||
#define TCA_TCPC_ORIENTATION_NORMAL BIT(2)
|
||||
#define TCA_TCPC_MUX_CONTRL GENMASK(1, 0)
|
||||
#define TCA_TCPC_MUX_CONTRL_NO_CONN 0
|
||||
#define TCA_TCPC_MUX_CONTRL_USB_CONN 1
|
||||
|
||||
#define TCA_SYSMODE_CFG 0x18
|
||||
#define TCA_SYSMODE_TCPC_DISABLE BIT(3)
|
||||
#define TCA_SYSMODE_TCPC_FLIP BIT(2)
|
||||
|
||||
#define TCA_CTRLSYNCMODE_CFG0 0x20
|
||||
#define TCA_CTRLSYNCMODE_CFG1 0x20
|
||||
|
||||
#define TCA_PSTATE 0x30
|
||||
#define TCA_PSTATE_CM_STS BIT(4)
|
||||
#define TCA_PSTATE_TX_STS BIT(3)
|
||||
#define TCA_PSTATE_RX_PLL_STS BIT(2)
|
||||
#define TCA_PSTATE_PIPE0_POWER_DOWN GENMASK(1, 0)
|
||||
|
||||
#define TCA_GEN_STATUS 0x34
|
||||
#define TCA_GEN_DEV_POR BIT(12)
|
||||
#define TCA_GEN_REF_CLK_SEL BIT(8)
|
||||
#define TCA_GEN_TYPEC_FLIP_INVERT BIT(4)
|
||||
#define TCA_GEN_PHY_TYPEC_DISABLE BIT(3)
|
||||
#define TCA_GEN_PHY_TYPEC_FLIP BIT(2)
|
||||
|
||||
#define TCA_VBUS_CTRL 0x40
|
||||
#define TCA_VBUS_STATUS 0x44
|
||||
|
||||
#define TCA_INFO 0xfc
|
||||
|
||||
enum imx8mpq_phy_type {
|
||||
IMX8MQ_PHY,
|
||||
IMX8MP_PHY,
|
||||
IMX95_PHY,
|
||||
};
|
||||
|
||||
struct imx8mq_usb_phy {
|
||||
@@ -81,14 +129,49 @@ struct imx8mq_usb_phy {
|
||||
void __iomem *base;
|
||||
enum imx8mpq_phy_type type;
|
||||
struct udevice *vbus_supply;
|
||||
void __iomem *tca_base;
|
||||
};
|
||||
|
||||
static const struct udevice_id imx8mq_usb_phy_of_match[] = {
|
||||
{ .compatible = "fsl,imx8mq-usb-phy", .data = IMX8MQ_PHY },
|
||||
{ .compatible = "fsl,imx8mp-usb-phy", .data = IMX8MP_PHY },
|
||||
{ .compatible = "fsl,imx95-usb-phy", .data = IMX95_PHY },
|
||||
{},
|
||||
};
|
||||
|
||||
static void tca_blk_init(struct phy *usb_phy)
|
||||
{
|
||||
struct udevice *dev = usb_phy->dev;
|
||||
struct imx8mq_usb_phy *imx_phy = dev_get_priv(dev);
|
||||
void __iomem *base = imx_phy->tca_base;
|
||||
u32 val;
|
||||
|
||||
/* reset XBar block */
|
||||
val = readl(base + TCA_CLK_RST);
|
||||
val &= ~TCA_CLK_RST_SW;
|
||||
writel(val, base + TCA_CLK_RST);
|
||||
|
||||
udelay(100);
|
||||
|
||||
/* clear reset */
|
||||
val |= TCA_CLK_RST_SW;
|
||||
writel(val, base + TCA_CLK_RST);
|
||||
|
||||
/*
|
||||
* use Controller Synced Mode for TCA low power enable and
|
||||
* put PHY to USB safe state.
|
||||
*/
|
||||
val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYNCMODE);
|
||||
writel(val, base + TCA_GCFG);
|
||||
|
||||
val = TCA_TCPC_VALID | TCA_TCPC_LOW_POWER_EN;
|
||||
writel(val, base + TCA_TCPC);
|
||||
|
||||
/* use System Configuration Mode for TCA mux control. */
|
||||
val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYSMODE);
|
||||
writel(val, base + TCA_GCFG);
|
||||
}
|
||||
|
||||
static int imx8mq_usb_phy_init(struct phy *usb_phy)
|
||||
{
|
||||
struct udevice *dev = usb_phy->dev;
|
||||
@@ -154,6 +237,9 @@ static int imx8mp_usb_phy_init(struct phy *usb_phy)
|
||||
value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET);
|
||||
writel(value, imx_phy->base + PHY_CTRL1);
|
||||
|
||||
if (imx_phy->tca_base)
|
||||
tca_blk_init(usb_phy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -162,7 +248,7 @@ static int imx8mpq_usb_phy_init(struct phy *usb_phy)
|
||||
struct udevice *dev = usb_phy->dev;
|
||||
struct imx8mq_usb_phy *imx_phy = dev_get_priv(dev);
|
||||
|
||||
if (imx_phy->type == IMX8MP_PHY)
|
||||
if (imx_phy->type == IMX8MP_PHY || imx_phy->type == IMX95_PHY)
|
||||
return imx8mp_usb_phy_init(usb_phy);
|
||||
else
|
||||
return imx8mq_usb_phy_init(usb_phy);
|
||||
@@ -264,6 +350,9 @@ int imx8mq_usb_phy_probe(struct udevice *dev)
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->type == IMX95_PHY)
|
||||
priv->tca_base = dev_read_addr_index_ptr(dev, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user