mirror of
https://xff.cz/git/u-boot/
synced 2025-09-01 08:42:12 +02:00
Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-usb into next
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <clk.h>
|
||||
#include <div64.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <fdtdec.h>
|
||||
#include <generic-phy.h>
|
||||
#include <malloc.h>
|
||||
@@ -31,8 +32,13 @@
|
||||
#define USB2_LINECTRL1 0x610
|
||||
#define USB2_ADPCTRL 0x630
|
||||
|
||||
/* INT_ENABLE */
|
||||
#define USB2_INT_ENABLE_UCOM_INTEN BIT(3)
|
||||
#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2)
|
||||
#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1)
|
||||
|
||||
/* USBCTR */
|
||||
#define USB2_USBCTR_PLL_RST BIT(1)
|
||||
#define USB2_USBCTR_PLL_RST BIT(1)
|
||||
|
||||
/* SPD_RSM_TIMSET */
|
||||
#define USB2_SPD_RSM_TIMSET_INIT 0x014e029b
|
||||
@@ -43,11 +49,23 @@
|
||||
/* COMMCTRL */
|
||||
#define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */
|
||||
|
||||
/* OBINTSTA and OBINTEN */
|
||||
#define USB2_OBINT_SESSVLDCHG BIT(12)
|
||||
#define USB2_OBINT_IDDIGCHG BIT(11)
|
||||
|
||||
/* VBCTRL */
|
||||
#define USB2_VBCTRL_DRVVBUSSEL BIT(8)
|
||||
|
||||
/* LINECTRL1 */
|
||||
#define USB2_LINECTRL1_DPRPD_EN BIT(19)
|
||||
#define USB2_LINECTRL1_DP_RPD BIT(18)
|
||||
#define USB2_LINECTRL1_DMRPD_EN BIT(17)
|
||||
#define USB2_LINECTRL1_DM_RPD BIT(16)
|
||||
|
||||
/* ADPCTRL */
|
||||
#define USB2_ADPCTRL_OTGSESSVLD BIT(20)
|
||||
#define USB2_ADPCTRL_IDDIG BIT(19)
|
||||
#define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */
|
||||
#define USB2_ADPCTRL_DRVVBUS BIT(4)
|
||||
|
||||
struct rcar_gen3_phy {
|
||||
@@ -65,12 +83,14 @@ static int rcar_gen3_phy_phy_init(struct phy *phy)
|
||||
writel(USB2_SPD_RSM_TIMSET_INIT, priv->regs + USB2_SPD_RSM_TIMSET);
|
||||
writel(USB2_OC_TIMSET_INIT, priv->regs + USB2_OC_TIMSET);
|
||||
|
||||
setbits_le32(priv->regs + USB2_LINECTRL1,
|
||||
USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
clrbits_le32(priv->regs + USB2_COMMCTRL, USB2_COMMCTRL_OTG_PERI);
|
||||
static int rcar_gen3_phy_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
|
||||
|
||||
setbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS);
|
||||
writel(0, priv->regs + USB2_INT_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -102,10 +122,70 @@ static int rcar_gen3_phy_phy_power_off(struct phy *phy)
|
||||
return regulator_set_enable(priv->vbus_supply, false);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_phy_set_mode(struct phy *phy, enum phy_mode mode,
|
||||
int submode)
|
||||
{
|
||||
const u32 adpdevmask = USB2_ADPCTRL_IDDIG | USB2_ADPCTRL_OTGSESSVLD;
|
||||
struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
|
||||
u32 adpctrl;
|
||||
|
||||
if (mode == PHY_MODE_USB_OTG) {
|
||||
if (submode) {
|
||||
/* OTG submode is used as initialization indicator */
|
||||
writel(USB2_INT_ENABLE_UCOM_INTEN |
|
||||
USB2_INT_ENABLE_USBH_INTB_EN |
|
||||
USB2_INT_ENABLE_USBH_INTA_EN,
|
||||
priv->regs + USB2_INT_ENABLE);
|
||||
setbits_le32(priv->regs + USB2_VBCTRL,
|
||||
USB2_VBCTRL_DRVVBUSSEL);
|
||||
writel(USB2_OBINT_SESSVLDCHG | USB2_OBINT_IDDIGCHG,
|
||||
priv->regs + USB2_OBINTSTA);
|
||||
setbits_le32(priv->regs + USB2_OBINTEN,
|
||||
USB2_OBINT_SESSVLDCHG |
|
||||
USB2_OBINT_IDDIGCHG);
|
||||
setbits_le32(priv->regs + USB2_ADPCTRL,
|
||||
USB2_ADPCTRL_IDPULLUP);
|
||||
clrsetbits_le32(priv->regs + USB2_LINECTRL1,
|
||||
USB2_LINECTRL1_DP_RPD |
|
||||
USB2_LINECTRL1_DM_RPD |
|
||||
USB2_LINECTRL1_DPRPD_EN |
|
||||
USB2_LINECTRL1_DMRPD_EN,
|
||||
USB2_LINECTRL1_DPRPD_EN |
|
||||
USB2_LINECTRL1_DMRPD_EN);
|
||||
}
|
||||
|
||||
adpctrl = readl(priv->regs + USB2_ADPCTRL);
|
||||
if ((adpctrl & adpdevmask) == adpdevmask)
|
||||
mode = PHY_MODE_USB_DEVICE;
|
||||
else
|
||||
mode = PHY_MODE_USB_HOST;
|
||||
}
|
||||
|
||||
if (mode == PHY_MODE_USB_HOST) {
|
||||
clrbits_le32(priv->regs + USB2_COMMCTRL, USB2_COMMCTRL_OTG_PERI);
|
||||
setbits_le32(priv->regs + USB2_LINECTRL1,
|
||||
USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
|
||||
setbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS);
|
||||
} else if (mode == PHY_MODE_USB_DEVICE) {
|
||||
setbits_le32(priv->regs + USB2_COMMCTRL, USB2_COMMCTRL_OTG_PERI);
|
||||
clrsetbits_le32(priv->regs + USB2_LINECTRL1,
|
||||
USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD,
|
||||
USB2_LINECTRL1_DM_RPD);
|
||||
clrbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS);
|
||||
} else {
|
||||
dev_err(phy->dev, "Unknown mode %d\n", mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops rcar_gen3_phy_phy_ops = {
|
||||
.init = rcar_gen3_phy_phy_init,
|
||||
.exit = rcar_gen3_phy_phy_exit,
|
||||
.power_on = rcar_gen3_phy_phy_power_on,
|
||||
.power_off = rcar_gen3_phy_phy_power_off,
|
||||
.set_mode = rcar_gen3_phy_phy_set_mode,
|
||||
};
|
||||
|
||||
static int rcar_gen3_phy_probe(struct udevice *dev)
|
||||
|
@@ -508,7 +508,8 @@ int generic_phy_power_off_bulk(struct phy_bulk *bulk)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int generic_setup_phy(struct udevice *dev, struct phy *phy, int index)
|
||||
int generic_setup_phy(struct udevice *dev, struct phy *phy, int index,
|
||||
enum phy_mode mode, int submode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -520,10 +521,18 @@ int generic_setup_phy(struct udevice *dev, struct phy *phy, int index)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = generic_phy_set_mode(phy, mode, submode);
|
||||
if (ret)
|
||||
goto phys_mode_err;
|
||||
|
||||
ret = generic_phy_power_on(phy);
|
||||
if (ret)
|
||||
generic_phy_exit(phy);
|
||||
goto phys_mode_err;
|
||||
|
||||
return 0;
|
||||
|
||||
phys_mode_err:
|
||||
generic_phy_exit(phy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -72,6 +72,18 @@ static int sandbox_phy_exit(struct phy *phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sandbox_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
|
||||
{
|
||||
if (submode)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (mode != PHY_MODE_USB_HOST)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_phy_bind(struct udevice *dev)
|
||||
{
|
||||
if (dev_get_driver_data(dev) != DRIVER_DATA)
|
||||
@@ -96,6 +108,7 @@ static struct phy_ops sandbox_phy_ops = {
|
||||
.power_off = sandbox_phy_power_off,
|
||||
.init = sandbox_phy_init,
|
||||
.exit = sandbox_phy_exit,
|
||||
.set_mode = sandbox_phy_set_mode,
|
||||
};
|
||||
|
||||
static const struct udevice_id sandbox_phy_ids[] = {
|
||||
|
@@ -94,7 +94,7 @@ static int ehci_usb_probe(struct udevice *dev)
|
||||
if (err)
|
||||
goto reset_err;
|
||||
|
||||
err = generic_setup_phy(dev, &priv->phy, 0);
|
||||
err = generic_setup_phy(dev, &priv->phy, 0, PHY_MODE_USB_HOST, 0);
|
||||
if (err)
|
||||
goto regulator_err;
|
||||
|
||||
|
@@ -80,7 +80,7 @@ static int ehci_usb_probe(struct udevice *dev)
|
||||
hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
|
||||
HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
|
||||
|
||||
ret = generic_setup_phy(dev, &p->phy, 0);
|
||||
ret = generic_setup_phy(dev, &p->phy, 0, PHY_MODE_USB_HOST, 0);
|
||||
if (ret)
|
||||
goto cleanup_iface;
|
||||
|
||||
|
@@ -703,7 +703,7 @@ static int ehci_usb_probe(struct udevice *dev)
|
||||
usb_phy_enable(ehci, priv->phy_addr);
|
||||
#endif
|
||||
#else
|
||||
ret = generic_setup_phy(dev, &priv->phy, 0);
|
||||
ret = generic_setup_phy(dev, &priv->phy, 0, PHY_MODE_USB_HOST, 0);
|
||||
if (ret)
|
||||
goto err_regulator;
|
||||
#endif
|
||||
|
@@ -30,7 +30,7 @@ static int ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr,
|
||||
int ret;
|
||||
u32 cmd;
|
||||
|
||||
ret = generic_setup_phy(dev, &priv->phy, 0);
|
||||
ret = generic_setup_phy(dev, &priv->phy, 0, PHY_MODE_USB_HOST, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@@ -50,7 +50,7 @@ static int ohci_usb_probe(struct udevice *dev)
|
||||
goto reset_err;
|
||||
}
|
||||
|
||||
err = generic_setup_phy(dev, &priv->phy, 0);
|
||||
err = generic_setup_phy(dev, &priv->phy, 0, PHY_MODE_USB_HOST, 0);
|
||||
if (err)
|
||||
goto reset_err;
|
||||
|
||||
|
@@ -415,10 +415,13 @@ int generic_phy_power_off_bulk(struct phy_bulk *bulk);
|
||||
* @dev: The consumer device.
|
||||
* @phy: A pointer to the PHY port
|
||||
* @index: The index in the list of available PHYs
|
||||
* @mode: PHY mode
|
||||
* @submode: PHY submode
|
||||
*
|
||||
* Return: 0 if OK, or negative error code.
|
||||
*/
|
||||
int generic_setup_phy(struct udevice *dev, struct phy *phy, int index);
|
||||
int generic_setup_phy(struct udevice *dev, struct phy *phy, int index,
|
||||
enum phy_mode mode, int submode);
|
||||
|
||||
/**
|
||||
* generic_shutdown_phy() - Power off and de-initialize phy.
|
||||
@@ -509,7 +512,8 @@ static inline int generic_phy_power_off_bulk(struct phy_bulk *bulk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int generic_setup_phy(struct udevice *dev, struct phy *phy, int index)
|
||||
static inline int generic_setup_phy(struct udevice *dev, struct phy *phy, int index,
|
||||
enum phy_mode mode, int submode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -243,20 +243,27 @@ static int dm_test_phy_setup(struct unit_test_state *uts)
|
||||
"gen_phy_user", &parent));
|
||||
|
||||
/* normal */
|
||||
ut_assertok(generic_setup_phy(parent, &phy, 0));
|
||||
ut_assertok(generic_setup_phy(parent, &phy, 0, PHY_MODE_USB_HOST, 0));
|
||||
ut_assertok(generic_shutdown_phy(&phy));
|
||||
|
||||
/* set_mode as USB Host passes, anything else is not supported */
|
||||
ut_assertok(generic_setup_phy(parent, &phy, 0, PHY_MODE_USB_HOST, 0));
|
||||
ut_assertok(generic_phy_set_mode(&phy, PHY_MODE_USB_HOST, 0));
|
||||
ut_asserteq(-EOPNOTSUPP, generic_phy_set_mode(&phy, PHY_MODE_USB_HOST, 1));
|
||||
ut_asserteq(-EINVAL, generic_phy_set_mode(&phy, PHY_MODE_USB_DEVICE, 0));
|
||||
ut_assertok(generic_shutdown_phy(&phy));
|
||||
|
||||
/* power_off fail with -EIO */
|
||||
ut_assertok(generic_setup_phy(parent, &phy, 1));
|
||||
ut_assertok(generic_setup_phy(parent, &phy, 1, PHY_MODE_USB_HOST, 0));
|
||||
ut_asserteq(-EIO, generic_shutdown_phy(&phy));
|
||||
|
||||
/* power_on fail with -EIO */
|
||||
ut_asserteq(-EIO, generic_setup_phy(parent, &phy, 2));
|
||||
ut_asserteq(-EIO, generic_setup_phy(parent, &phy, 2, PHY_MODE_USB_HOST, 0));
|
||||
ut_assertok(generic_shutdown_phy(&phy));
|
||||
|
||||
/* generic_phy_get_by_index fail with -ENOENT */
|
||||
ut_asserteq(-ENOENT, generic_phy_get_by_index(parent, 3, &phy));
|
||||
ut_assertok(generic_setup_phy(parent, &phy, 3));
|
||||
ut_assertok(generic_setup_phy(parent, &phy, 3, PHY_MODE_USB_HOST, 0));
|
||||
ut_assertok(generic_shutdown_phy(&phy));
|
||||
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user