mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-25 13:14:19 +08:00
dwc3: move phy operation to core.c
Those operations can be used for peripheral operation as well as host operation. Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> # Conflicts: # drivers/usb/dwc3/core.c # drivers/usb/host/xhci-dwc3.c
This commit is contained in:
parent
20bebd8666
commit
d648a50c0a
@ -19,7 +19,7 @@
|
|||||||
#include <asm/dma-mapping.h>
|
#include <asm/dma-mapping.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <generic-phy.h>
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
#include <linux/usb/gadget.h>
|
#include <linux/usb/gadget.h>
|
||||||
|
|
||||||
@ -789,6 +789,91 @@ MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
|
|||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
|
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
|
||||||
|
int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys)
|
||||||
|
{
|
||||||
|
int i, ret, count;
|
||||||
|
struct phy *usb_phys;
|
||||||
|
|
||||||
|
/* Return if no phy declared */
|
||||||
|
if (!dev_read_prop(dev, "phys", NULL))
|
||||||
|
return 0;
|
||||||
|
count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
|
||||||
|
if (count <= 0)
|
||||||
|
return count;
|
||||||
|
|
||||||
|
usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!usb_phys)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
ret = generic_phy_get_by_index(dev, i, &usb_phys[i]);
|
||||||
|
if (ret && ret != -ENOENT) {
|
||||||
|
pr_err("Failed to get USB PHY%d for %s\n",
|
||||||
|
i, dev->name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
ret = generic_phy_init(&usb_phys[i]);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Can't init USB PHY%d for %s\n",
|
||||||
|
i, dev->name);
|
||||||
|
goto phys_init_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
ret = generic_phy_power_on(&usb_phys[i]);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Can't power USB PHY%d for %s\n",
|
||||||
|
i, dev->name);
|
||||||
|
goto phys_poweron_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*array = usb_phys;
|
||||||
|
*num_phys = count;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
phys_poweron_err:
|
||||||
|
for (i = count - 1; i >= 0; i--)
|
||||||
|
generic_phy_power_off(&usb_phys[i]);
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
generic_phy_exit(&usb_phys[i]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
phys_init_err:
|
||||||
|
for (; i >= 0; i--)
|
||||||
|
generic_phy_exit(&usb_phys[i]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
for (i = 0; i < num_phys; i++) {
|
||||||
|
if (!generic_phy_valid(&usb_phys[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = generic_phy_power_off(&usb_phys[i]);
|
||||||
|
ret |= generic_phy_exit(&usb_phys[i]);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Can't shutdown USB PHY%d for %s\n",
|
||||||
|
i, dev->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
|
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
|
||||||
int dwc3_init(struct dwc3 *dwc)
|
int dwc3_init(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
@ -840,5 +925,4 @@ void dwc3_remove(struct dwc3 *dwc)
|
|||||||
dwc3_core_exit(dwc);
|
dwc3_core_exit(dwc);
|
||||||
kfree(dwc->mem);
|
kfree(dwc->mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <generic-phy.h>
|
#include <generic-phy.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
#include <dwc3-uboot.h>
|
||||||
|
|
||||||
#include "xhci.h"
|
#include "xhci.h"
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@ -110,105 +111,21 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(DM_USB)
|
#if CONFIG_IS_ENABLED(DM_USB)
|
||||||
static int xhci_dwc3_setup_phy(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
|
|
||||||
int i, ret, count;
|
|
||||||
|
|
||||||
/* Return if no phy declared */
|
|
||||||
if (!dev_read_prop(dev, "phys", NULL))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
|
|
||||||
if (count <= 0)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!plat->usb_phys)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
|
|
||||||
if (ret && ret != -ENOENT) {
|
|
||||||
pr_err("Failed to get USB PHY%d for %s\n",
|
|
||||||
i, dev->name);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
++plat->num_phys;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < plat->num_phys; i++) {
|
|
||||||
ret = generic_phy_init(&plat->usb_phys[i]);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Can't init USB PHY%d for %s\n",
|
|
||||||
i, dev->name);
|
|
||||||
goto phys_init_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < plat->num_phys; i++) {
|
|
||||||
ret = generic_phy_power_on(&plat->usb_phys[i]);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Can't power USB PHY%d for %s\n",
|
|
||||||
i, dev->name);
|
|
||||||
goto phys_poweron_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
phys_poweron_err:
|
|
||||||
for (; i >= 0; i--)
|
|
||||||
generic_phy_power_off(&plat->usb_phys[i]);
|
|
||||||
|
|
||||||
for (i = 0; i < plat->num_phys; i++)
|
|
||||||
generic_phy_exit(&plat->usb_phys[i]);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
phys_init_err:
|
|
||||||
for (; i >= 0; i--)
|
|
||||||
generic_phy_exit(&plat->usb_phys[i]);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xhci_dwc3_shutdown_phy(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
|
|
||||||
int i, ret;
|
|
||||||
|
|
||||||
for (i = 0; i < plat->num_phys; i++) {
|
|
||||||
if (!generic_phy_valid(&plat->usb_phys[i]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = generic_phy_power_off(&plat->usb_phys[i]);
|
|
||||||
ret |= generic_phy_exit(&plat->usb_phys[i]);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Can't shutdown USB PHY%d for %s\n",
|
|
||||||
i, dev->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xhci_dwc3_probe(struct udevice *dev)
|
static int xhci_dwc3_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct xhci_hcor *hcor;
|
struct xhci_hcor *hcor;
|
||||||
struct xhci_hccr *hccr;
|
struct xhci_hccr *hccr;
|
||||||
struct dwc3 *dwc3_reg;
|
struct dwc3 *dwc3_reg;
|
||||||
enum usb_dr_mode dr_mode;
|
enum usb_dr_mode dr_mode;
|
||||||
|
struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev));
|
hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev));
|
||||||
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
|
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
|
||||||
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
|
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
|
||||||
|
|
||||||
ret = xhci_dwc3_setup_phy(dev);
|
ret = dwc3_setup_phy(dev, &plat->usb_phys, &plat->num_phys);
|
||||||
if (ret)
|
if (ret && (ret != -ENOTSUPP))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
|
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
|
||||||
@ -227,7 +144,9 @@ static int xhci_dwc3_probe(struct udevice *dev)
|
|||||||
|
|
||||||
static int xhci_dwc3_remove(struct udevice *dev)
|
static int xhci_dwc3_remove(struct udevice *dev)
|
||||||
{
|
{
|
||||||
xhci_dwc3_shutdown_phy(dev);
|
struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
dwc3_shutdown_phy(dev, plat->usb_phys, plat->num_phys);
|
||||||
|
|
||||||
return xhci_deregister(dev);
|
return xhci_deregister(dev);
|
||||||
}
|
}
|
||||||
|
@ -38,4 +38,23 @@ struct dwc3_device {
|
|||||||
int dwc3_uboot_init(struct dwc3_device *dev);
|
int dwc3_uboot_init(struct dwc3_device *dev);
|
||||||
void dwc3_uboot_exit(int index);
|
void dwc3_uboot_exit(int index);
|
||||||
void dwc3_uboot_handle_interrupt(int index);
|
void dwc3_uboot_handle_interrupt(int index);
|
||||||
|
|
||||||
|
struct phy;
|
||||||
|
#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
|
||||||
|
int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys);
|
||||||
|
int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys);
|
||||||
|
#else
|
||||||
|
static inline int dwc3_setup_phy(struct udevice *dev, struct phy **array,
|
||||||
|
int *num_phys)
|
||||||
|
{
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys,
|
||||||
|
int num_phys)
|
||||||
|
{
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __DWC3_UBOOT_H_ */
|
#endif /* __DWC3_UBOOT_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user