Merge branch 'master' of git://git.denx.de/u-boot-usb

- DWC3 and UDC cleanup
This commit is contained in:
Tom Rini
2018-12-10 07:15:12 -05:00
39 changed files with 857 additions and 407 deletions
+2
View File
@@ -932,6 +932,7 @@ config ARCH_ZYNQMP_R5
select DM_SERIAL
select OF_CONTROL
imply CMD_DM
imply DM_USB_GADGET
config ARCH_ZYNQMP
bool "Xilinx ZynqMP based platform"
@@ -949,6 +950,7 @@ config ARCH_ZYNQMP
imply CMD_DM
imply FAT_WRITE
imply MP
imply DM_USB_GADGET
config TEGRA
bool "NVIDIA Tegra"
+4
View File
@@ -15,6 +15,10 @@
ocp {
u-boot,dm-spl;
ocp2scp@4a080000 {
compatible = "ti,omap-ocp2scp", "simple-bus";
};
ocp2scp@4a090000 {
compatible = "ti,omap-ocp2scp", "simple-bus";
};
+4 -2
View File
@@ -460,6 +460,8 @@
test4 {
compatible = "denx,u-boot-probe-test";
first-syscon = <&syscon0>;
second-sys-ctrl = <&another_system_controller>;
};
};
@@ -540,12 +542,12 @@
};
};
syscon@0 {
syscon0: syscon@0 {
compatible = "sandbox,syscon0";
reg = <0x10 16>;
};
syscon@1 {
another_system_controller: syscon@1 {
compatible = "sandbox,syscon1";
reg = <0x20 5
0x28 6
+1 -1
View File
@@ -665,7 +665,7 @@ int g_dnl_board_usb_cable_connected(void)
struct phy phy;
int ret;
ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev);
ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
if (ret) {
pr_err("%s: Cannot find USB device\n", __func__);
return ret;
+19 -87
View File
@@ -675,6 +675,19 @@ out:
return;
}
#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL)
static int device_okay(const char *path)
{
int node;
node = fdt_path_offset(gd->fdt_blob, path);
if (node < 0)
return 0;
return fdtdec_get_is_enabled(gd->fdt_blob, node);
}
#endif
int board_late_init(void)
{
setup_board_eeprom_env();
@@ -714,6 +727,12 @@ int board_late_init(void)
board_ti_set_ethaddr(2);
#endif
#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL)
if (device_okay("/ocp/omap_dwc3_1@48880000"))
enable_usb_clocks(0);
if (device_okay("/ocp/omap_dwc3_2@488c0000"))
enable_usb_clocks(1);
#endif
return 0;
}
@@ -864,93 +883,6 @@ int spl_start_uboot(void)
}
#endif
#ifdef CONFIG_USB_DWC3
static struct dwc3_device usb_otg_ss2 = {
.maximum_speed = USB_SPEED_HIGH,
.base = DRA7_USB_OTG_SS2_BASE,
.tx_fifo_resize = false,
.index = 1,
};
static struct dwc3_omap_device usb_otg_ss2_glue = {
.base = (void *)DRA7_USB_OTG_SS2_GLUE_BASE,
.utmi_mode = DWC3_OMAP_UTMI_MODE_SW,
.index = 1,
};
static struct ti_usb_phy_device usb_phy2_device = {
.usb2_phy_power = (void *)DRA7_USB2_PHY2_POWER,
.index = 1,
};
int usb_gadget_handle_interrupts(int index)
{
u32 status;
status = dwc3_omap_uboot_interrupt_status(index);
if (status)
dwc3_uboot_handle_interrupt(index);
return 0;
}
#endif /* CONFIG_USB_DWC3 */
#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
int board_usb_init(int index, enum usb_init_type init)
{
enable_usb_clocks(index);
switch (index) {
case 0:
if (init == USB_INIT_DEVICE) {
printf("port %d can't be used as device\n", index);
disable_usb_clocks(index);
return -EINVAL;
}
break;
case 1:
if (init == USB_INIT_DEVICE) {
#ifdef CONFIG_USB_DWC3
usb_otg_ss2.dr_mode = USB_DR_MODE_PERIPHERAL;
usb_otg_ss2_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID;
ti_usb_phy_uboot_init(&usb_phy2_device);
dwc3_omap_uboot_init(&usb_otg_ss2_glue);
dwc3_uboot_init(&usb_otg_ss2);
#endif
} else {
printf("port %d can't be used as host\n", index);
disable_usb_clocks(index);
return -EINVAL;
}
break;
default:
printf("Invalid Controller Index\n");
}
return 0;
}
int board_usb_cleanup(int index, enum usb_init_type init)
{
#ifdef CONFIG_USB_DWC3
switch (index) {
case 0:
case 1:
if (init == USB_INIT_DEVICE) {
ti_usb_phy_uboot_exit(index);
dwc3_uboot_exit(index);
dwc3_omap_uboot_exit(index);
}
break;
default:
printf("Invalid Controller Index\n");
}
#endif
disable_usb_clocks(index);
return 0;
}
#endif /* defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) */
#ifdef CONFIG_DRIVER_TI_CPSW
/* Delay value to add to calibrated value */
+19 -104
View File
@@ -646,6 +646,19 @@ int dram_init_banksize(void)
return 0;
}
#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL)
static int device_okay(const char *path)
{
int node;
node = fdt_path_offset(gd->fdt_blob, path);
if (node < 0)
return 0;
return fdtdec_get_is_enabled(gd->fdt_blob, node);
}
#endif
int board_late_init(void)
{
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
@@ -684,6 +697,12 @@ int board_late_init(void)
*/
if (board_is_dra71x_evm())
palmas_i2c_write_u8(LP873X_I2C_SLAVE_ADDR, 0x9, 0x7);
#endif
#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL)
if (device_okay("/ocp/omap_dwc3_1@48880000"))
enable_usb_clocks(0);
if (device_okay("/ocp/omap_dwc3_2@488c0000"))
enable_usb_clocks(1);
#endif
return 0;
}
@@ -896,110 +915,6 @@ const struct mmc_platform_fixups *platform_fixups_mmc(uint32_t addr)
}
#endif
#ifdef CONFIG_USB_DWC3
static struct dwc3_device usb_otg_ss1 = {
.maximum_speed = USB_SPEED_SUPER,
.base = DRA7_USB_OTG_SS1_BASE,
.tx_fifo_resize = false,
.index = 0,
};
static struct dwc3_omap_device usb_otg_ss1_glue = {
.base = (void *)DRA7_USB_OTG_SS1_GLUE_BASE,
.utmi_mode = DWC3_OMAP_UTMI_MODE_SW,
.index = 0,
};
static struct ti_usb_phy_device usb_phy1_device = {
.pll_ctrl_base = (void *)DRA7_USB3_PHY1_PLL_CTRL,
.usb2_phy_power = (void *)DRA7_USB2_PHY1_POWER,
.usb3_phy_power = (void *)DRA7_USB3_PHY1_POWER,
.index = 0,
};
static struct dwc3_device usb_otg_ss2 = {
.maximum_speed = USB_SPEED_SUPER,
.base = DRA7_USB_OTG_SS2_BASE,
.tx_fifo_resize = false,
.index = 1,
};
static struct dwc3_omap_device usb_otg_ss2_glue = {
.base = (void *)DRA7_USB_OTG_SS2_GLUE_BASE,
.utmi_mode = DWC3_OMAP_UTMI_MODE_SW,
.index = 1,
};
static struct ti_usb_phy_device usb_phy2_device = {
.usb2_phy_power = (void *)DRA7_USB2_PHY2_POWER,
.index = 1,
};
int board_usb_init(int index, enum usb_init_type init)
{
enable_usb_clocks(index);
switch (index) {
case 0:
if (init == USB_INIT_DEVICE) {
usb_otg_ss1.dr_mode = USB_DR_MODE_PERIPHERAL;
usb_otg_ss1_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID;
} else {
usb_otg_ss1.dr_mode = USB_DR_MODE_HOST;
usb_otg_ss1_glue.vbus_id_status = OMAP_DWC3_ID_GROUND;
}
ti_usb_phy_uboot_init(&usb_phy1_device);
dwc3_omap_uboot_init(&usb_otg_ss1_glue);
dwc3_uboot_init(&usb_otg_ss1);
break;
case 1:
if (init == USB_INIT_DEVICE) {
usb_otg_ss2.dr_mode = USB_DR_MODE_PERIPHERAL;
usb_otg_ss2_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID;
} else {
usb_otg_ss2.dr_mode = USB_DR_MODE_HOST;
usb_otg_ss2_glue.vbus_id_status = OMAP_DWC3_ID_GROUND;
}
ti_usb_phy_uboot_init(&usb_phy2_device);
dwc3_omap_uboot_init(&usb_otg_ss2_glue);
dwc3_uboot_init(&usb_otg_ss2);
break;
default:
printf("Invalid Controller Index\n");
}
return 0;
}
int board_usb_cleanup(int index, enum usb_init_type init)
{
switch (index) {
case 0:
case 1:
ti_usb_phy_uboot_exit(index);
dwc3_uboot_exit(index);
dwc3_omap_uboot_exit(index);
break;
default:
printf("Invalid Controller Index\n");
}
disable_usb_clocks(index);
return 0;
}
int usb_gadget_handle_interrupts(int index)
{
u32 status;
status = dwc3_omap_uboot_interrupt_status(index);
if (status)
dwc3_uboot_handle_interrupt(index);
return 0;
}
#endif
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_OS_BOOT)
int spl_start_uboot(void)
{
+2 -2
View File
@@ -51,7 +51,7 @@ static int do_fastboot_usb(int argc, char *const argv[],
return CMD_RET_FAILURE;
}
ret = board_usb_init(controller_index, USB_INIT_DEVICE);
ret = usb_gadget_initialize(controller_index);
if (ret) {
pr_err("USB init failed: %d\n", ret);
return CMD_RET_FAILURE;
@@ -82,7 +82,7 @@ static int do_fastboot_usb(int argc, char *const argv[],
exit:
g_dnl_unregister();
g_dnl_clear_detach();
board_usb_cleanup(controller_index, USB_INIT_DEVICE);
usb_gadget_release(controller_index);
return ret;
#else
+2 -2
View File
@@ -33,7 +33,7 @@ static int do_rockusb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
dev_index = simple_strtoul(devnum, NULL, 0);
rockusb_dev_init(devtype, dev_index);
ret = board_usb_init(controller_index, USB_INIT_DEVICE);
ret = usb_gadget_initialize(controller_index);
if (ret) {
printf("USB init failed: %d\n", ret);
return CMD_RET_FAILURE;
@@ -62,7 +62,7 @@ static int do_rockusb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
exit:
g_dnl_unregister();
g_dnl_clear_detach();
board_usb_cleanup(controller_index, USB_INIT_DEVICE);
usb_gadget_release(controller_index);
return ret;
}
+2 -2
View File
@@ -30,7 +30,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
goto done;
int controller_index = simple_strtoul(usb_controller, NULL, 0);
ret = board_usb_init(controller_index, USB_INIT_DEVICE);
ret = usb_gadget_initialize(controller_index);
if (ret) {
pr_err("USB init failed: %d\n", ret);
ret = CMD_RET_FAILURE;
@@ -55,7 +55,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
exit:
g_dnl_unregister();
board_usb_cleanup(controller_index, USB_INIT_DEVICE);
usb_gadget_release(controller_index);
done:
dfu_free_entities();
+2 -2
View File
@@ -20,7 +20,7 @@ static int do_sdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char *usb_controller = argv[1];
int controller_index = simple_strtoul(usb_controller, NULL, 0);
board_usb_init(controller_index, USB_INIT_DEVICE);
usb_gadget_initialize(controller_index);
g_dnl_clear_detach();
g_dnl_register("usb_dnl_sdp");
@@ -37,7 +37,7 @@ static int do_sdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
exit:
g_dnl_unregister();
board_usb_cleanup(controller_index, USB_INIT_DEVICE);
usb_gadget_release(controller_index);
return ret;
}
+2 -2
View File
@@ -160,7 +160,7 @@ static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
controller_index = (unsigned int)(simple_strtoul(
usb_controller, NULL, 0));
if (board_usb_init(controller_index, USB_INIT_DEVICE)) {
if (usb_gadget_initialize(controller_index)) {
pr_err("Couldn't init USB controller.\n");
rc = CMD_RET_FAILURE;
goto cleanup_ums_init;
@@ -231,7 +231,7 @@ static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
cleanup_register:
g_dnl_unregister();
cleanup_board:
board_usb_cleanup(controller_index, USB_INIT_DEVICE);
usb_gadget_release(controller_index);
cleanup_ums_init:
ums_fini();
+3 -3
View File
@@ -23,9 +23,9 @@ int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget)
bool dfu_reset = false;
int ret, i = 0;
ret = board_usb_init(usbctrl_index, USB_INIT_DEVICE);
ret = usb_gadget_initialize(usbctrl_index);
if (ret) {
pr_err("board usb init failed\n");
pr_err("usb_gadget_initialize failed\n");
return CMD_RET_FAILURE;
}
g_dnl_clear_detach();
@@ -84,7 +84,7 @@ int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget)
}
exit:
g_dnl_unregister();
board_usb_cleanup(usbctrl_index, USB_INIT_DEVICE);
usb_gadget_release(usbctrl_index);
if (dfu_reset)
do_reset(NULL, 0, 0, NULL);
+9 -3
View File
@@ -50,6 +50,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_OMAP_HS=y
CONFIG_DM_SPI_FLASH=y
@@ -61,6 +62,9 @@ CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_DM_ETH=y
CONFIG_DRIVER_TI_CPSW=y
CONFIG_MII=y
CONFIG_PHY=y
CONFIG_PIPE3_PHY=y
CONFIG_OMAP_USB2_PHY=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_PALMAS=y
CONFIG_DM_REGULATOR=y
@@ -70,13 +74,15 @@ CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_TI_QSPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_SPL_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
CONFIG_OMAP_USB_PHY=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+9 -3
View File
@@ -53,6 +53,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_OMAP_HS=y
CONFIG_DM_SPI_FLASH=y
@@ -64,6 +65,9 @@ CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_DM_ETH=y
CONFIG_DRIVER_TI_CPSW=y
CONFIG_MII=y
CONFIG_PHY=y
CONFIG_PIPE3_PHY=y
CONFIG_OMAP_USB2_PHY=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_PALMAS=y
CONFIG_DM_REGULATOR=y
@@ -73,13 +77,15 @@ CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_TI_QSPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_SPL_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
CONFIG_OMAP_USB_PHY=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+6 -4
View File
@@ -56,6 +56,7 @@ CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_PCF8575_GPIO=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
@@ -72,6 +73,7 @@ CONFIG_PHY_GIGE=y
CONFIG_MII=y
CONFIG_SPL_PHY=y
CONFIG_PIPE3_PHY=y
CONFIG_OMAP_USB2_PHY=y
CONFIG_PMIC_PALMAS=y
CONFIG_PMIC_LP873X=y
CONFIG_DM_REGULATOR_FIXED=y
@@ -87,14 +89,14 @@ CONFIG_TIMER=y
CONFIG_OMAP_TIMER=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_SPL_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_DRA7XX_INDEX=1
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
CONFIG_OMAP_USB_PHY=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+6 -4
View File
@@ -56,6 +56,7 @@ CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_PCF8575_GPIO=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
@@ -71,6 +72,7 @@ CONFIG_PHY_GIGE=y
CONFIG_MII=y
CONFIG_SPL_PHY=y
CONFIG_PIPE3_PHY=y
CONFIG_OMAP_USB2_PHY=y
CONFIG_PMIC_PALMAS=y
CONFIG_PMIC_LP873X=y
CONFIG_DM_REGULATOR_FIXED=y
@@ -86,14 +88,14 @@ CONFIG_TIMER=y
CONFIG_OMAP_TIMER=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_SPL_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_DRA7XX_INDEX=1
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_OMAP=y
CONFIG_USB_DWC3_PHY_OMAP=y
CONFIG_OMAP_USB_PHY=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+1
View File
@@ -49,6 +49,7 @@ CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_DWC3=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
+23
View File
@@ -53,6 +53,29 @@ static int syscon_pre_probe(struct udevice *dev)
#endif
}
struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev,
const char *name)
{
struct udevice *syscon;
struct regmap *r;
int err;
err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
name, &syscon);
if (err) {
dev_dbg(dev, "unable to find syscon device\n");
return ERR_PTR(err);
}
r = syscon_get_regmap(syscon);
if (!r) {
dev_dbg(dev, "unable to find regmap\n");
return ERR_PTR(-ENODEV);
}
return r;
}
int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp)
{
struct udevice *dev;
+9
View File
@@ -155,4 +155,13 @@ config MSM8916_USB_PHY
This PHY is found on qualcomm dragonboard410c development board.
config OMAP_USB2_PHY
bool "Support OMAP's USB2 PHY"
depends on PHY
depends on SYSCON
help
Support for the OMAP's USB2 PHY.
This PHY is found on OMAP devices supporting USB2.
endmenu
+1
View File
@@ -17,3 +17,4 @@ obj-$(CONFIG_PHY_RCAR_GEN3) += phy-rcar-gen3.o
obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o
obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o
obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o
+196
View File
@@ -0,0 +1,196 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* OMAP USB2 PHY LAYER
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
* Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
*/
#include <common.h>
#include <asm/io.h>
#include <dm.h>
#include <errno.h>
#include <generic-phy.h>
#include <regmap.h>
#include <syscon.h>
#define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT BIT(0)
#define OMAP_DEV_PHY_PD BIT(0)
#define OMAP_USB2_PHY_PD BIT(28)
#define USB2PHY_DISCON_BYP_LATCH BIT(31)
#define USB2PHY_ANA_CONFIG1 (0x4c)
DECLARE_GLOBAL_DATA_PTR;
struct omap_usb2_phy {
struct regmap *pwr_regmap;
ulong flags;
void *phy_base;
u32 pwr_reg_offset;
};
struct usb_phy_data {
const char *label;
u8 flags;
u32 mask;
u32 power_on;
u32 power_off;
};
static const struct usb_phy_data omap5_usb2_data = {
.label = "omap5_usb2",
.flags = 0,
.mask = OMAP_DEV_PHY_PD,
.power_off = OMAP_DEV_PHY_PD,
};
static const struct usb_phy_data dra7x_usb2_data = {
.label = "dra7x_usb2",
.flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT,
.mask = OMAP_DEV_PHY_PD,
.power_off = OMAP_DEV_PHY_PD,
};
static const struct usb_phy_data dra7x_usb2_phy2_data = {
.label = "dra7x_usb2_phy2",
.flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT,
.mask = OMAP_USB2_PHY_PD,
.power_off = OMAP_USB2_PHY_PD,
};
static const struct udevice_id omap_usb2_id_table[] = {
{
.compatible = "ti,omap5-usb2",
.data = (ulong)&omap5_usb2_data,
},
{
.compatible = "ti,dra7x-usb2",
.data = (ulong)&dra7x_usb2_data,
},
{
.compatible = "ti,dra7x-usb2-phy2",
.data = (ulong)&dra7x_usb2_phy2_data,
},
{},
};
static int omap_usb_phy_power(struct phy *usb_phy, bool on)
{
struct udevice *dev = usb_phy->dev;
const struct usb_phy_data *data;
const struct omap_usb2_phy *phy = dev_get_priv(dev);
u32 val;
int rc;
data = (const struct usb_phy_data *)dev_get_driver_data(dev);
if (!data)
return -EINVAL;
rc = regmap_read(phy->pwr_regmap, phy->pwr_reg_offset, &val);
if (rc)
return rc;
val &= ~data->mask;
if (on)
val |= data->power_on;
else
val |= data->power_off;
rc = regmap_write(phy->pwr_regmap, phy->pwr_reg_offset, val);
if (rc)
return rc;
return 0;
}
static int omap_usb2_phy_init(struct phy *usb_phy)
{
struct udevice *dev = usb_phy->dev;
struct omap_usb2_phy *priv = dev_get_priv(dev);
u32 val;
if (priv->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
/*
*
* Reduce the sensitivity of internal PHY by enabling the
* DISCON_BYP_LATCH of the USB2PHY_ANA_CONFIG1 register. This
* resolves issues with certain devices which can otherwise
* be prone to false disconnects.
*
*/
val = readl(priv->phy_base + USB2PHY_ANA_CONFIG1);
val |= USB2PHY_DISCON_BYP_LATCH;
writel(val, priv->phy_base + USB2PHY_ANA_CONFIG1);
}
return 0;
}
static int omap_usb2_phy_power_on(struct phy *usb_phy)
{
return omap_usb_phy_power(usb_phy, true);
}
static int omap_usb2_phy_power_off(struct phy *usb_phy)
{
return omap_usb_phy_power(usb_phy, false);
}
static int omap_usb2_phy_exit(struct phy *usb_phy)
{
return omap_usb_phy_power(usb_phy, false);
}
struct phy_ops omap_usb2_phy_ops = {
.init = omap_usb2_phy_init,
.power_on = omap_usb2_phy_power_on,
.power_off = omap_usb2_phy_power_off,
.exit = omap_usb2_phy_exit,
};
int omap_usb2_phy_probe(struct udevice *dev)
{
int rc;
struct regmap *regmap;
struct omap_usb2_phy *priv = dev_get_priv(dev);
const struct usb_phy_data *data;
u32 tmp[2];
data = (const struct usb_phy_data *)dev_get_driver_data(dev);
if (!data)
return -EINVAL;
if (data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
u32 base = dev_read_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
priv->phy_base = (void *)base;
priv->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT;
}
regmap = syscon_regmap_lookup_by_phandle(dev, "syscon-phy-power");
if (IS_ERR(regmap)) {
printf("can't get regmap (err %ld)\n", PTR_ERR(regmap));
return PTR_ERR(regmap);
}
priv->pwr_regmap = regmap;
rc = dev_read_u32_array(dev, "syscon-phy-power", tmp, 2);
if (rc) {
printf("couldn't get power reg. offset (err %d)\n", rc);
return rc;
}
priv->pwr_reg_offset = tmp[1];
return 0;
}
U_BOOT_DRIVER(omap_usb2_phy) = {
.name = "omap_usb2_phy",
.id = UCLASS_PHY,
.of_match = omap_usb2_id_table,
.probe = omap_usb2_phy_probe,
.ops = &omap_usb2_phy_ops,
.priv_auto_alloc_size = sizeof(struct omap_usb2_phy),
};
+24 -8
View File
@@ -141,7 +141,7 @@ static int omap_pipe3_dpll_program(struct omap_pipe3 *pipe3)
omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION1, val);
val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION2);
val &= ~PLL_SELFREQDCO_MASK;
val &= ~(PLL_SELFREQDCO_MASK | PLL_IDLE);
val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION2, val);
@@ -265,10 +265,13 @@ static int pipe3_exit(struct phy *phy)
return -EBUSY;
}
val = readl(pipe3->pll_reset_reg);
writel(val | SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg);
mdelay(1);
writel(val & ~SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg);
if (pipe3->pll_reset_reg) {
val = readl(pipe3->pll_reset_reg);
writel(val | SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg);
mdelay(1);
writel(val & ~SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg);
}
return 0;
}
@@ -331,9 +334,11 @@ static int pipe3_phy_probe(struct udevice *dev)
if (!pipe3->power_reg)
return -EINVAL;
pipe3->pll_reset_reg = get_reg(dev, "syscon-pllreset");
if (!pipe3->pll_reset_reg)
return -EINVAL;
if (device_is_compatible(dev, "ti,phy-pipe3-sata")) {
pipe3->pll_reset_reg = get_reg(dev, "syscon-pllreset");
if (!pipe3->pll_reset_reg)
return -EINVAL;
}
pipe3->dpll_map = (struct pipe3_dpll_map *)dev_get_driver_data(dev);
@@ -350,8 +355,19 @@ static struct pipe3_dpll_map dpll_map_sata[] = {
{ }, /* Terminator */
};
static struct pipe3_dpll_map dpll_map_usb[] = {
{12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */
{16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */
{19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */
{20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */
{26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */
{38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */
{ }, /* Terminator */
};
static const struct udevice_id pipe3_phy_ids[] = {
{ .compatible = "ti,phy-pipe3-sata", .data = (ulong)&dpll_map_sata },
{ .compatible = "ti,omap-usb3", .data = (ulong)&dpll_map_usb},
{ }
};
+14
View File
@@ -52,6 +52,20 @@ config SPL_DM_USB
depends on DM_USB
default y
config DM_USB_GADGET
bool "Enable driver model for USB Gadget"
depends on DM_USB
help
Enable driver model for USB Gadget (Peripheral
mode)
config SPL_DM_USB_GADGET
bool "Enable driver model for USB Gadget in sPL"
depends on SPL_DM_USB
help
Enable driver model for USB Gadget in SPL
(Peripheral mode)
source "drivers/usb/host/Kconfig"
source "drivers/usb/dwc3/Kconfig"
+4 -3
View File
@@ -38,10 +38,11 @@ config USB_DWC3_OMAP
Say 'Y' here if you have one such device
config USB_DWC3_GENERIC
bool "Xilinx ZynqMP and similar Platforms"
depends on DM_USB && USB_DWC3
bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
depends on DM_USB && USB_DWC3 && MISC
help
Some platforms can reuse this DWC3 generic implementation.
Select this for Xilinx ZynqMP and similar Platforms.
This wrapper supports Host and Peripheral operation modes.
config USB_DWC3_UNIPHIER
bool "DesignWare USB3 Host Support on UniPhier Platforms"
+86 -3
View File
@@ -19,7 +19,7 @@
#include <asm/dma-mapping.h>
#include <linux/ioport.h>
#include <dm.h>
#include <generic-phy.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -789,8 +789,92 @@ MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
#if CONFIG_IS_ENABLED(DM_USB)
#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)
int dwc3_init(struct dwc3 *dwc)
{
int ret;
@@ -841,5 +925,4 @@ void dwc3_remove(struct dwc3 *dwc)
dwc3_core_exit(dwc);
kfree(dwc->mem);
}
#endif
+247 -46
View File
@@ -8,72 +8,89 @@
*/
#include <common.h>
#include <asm-generic/io.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <linux/usb/otg.h>
#include <linux/compat.h>
#include <dwc3-uboot.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <malloc.h>
#include <usb.h>
#include "core.h"
#include "gadget.h"
#include "linux-compat.h"
#include <reset.h>
#include <clk.h>
DECLARE_GLOBAL_DATA_PTR;
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
struct dwc3_generic_peripheral {
struct dwc3 dwc3;
struct phy *phys;
int num_phys;
fdt_addr_t base;
};
int usb_gadget_handle_interrupts(int index)
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
{
struct dwc3 *priv;
struct udevice *dev;
int ret;
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev);
if (!dev || ret) {
pr_err("No USB device found\n");
return -ENODEV;
}
priv = dev_get_priv(dev);
dwc3_gadget_uboot_handle_interrupt(priv);
dwc3_gadget_uboot_handle_interrupt(dwc3);
return 0;
}
static int dwc3_generic_peripheral_probe(struct udevice *dev)
{
struct dwc3 *priv = dev_get_priv(dev);
int rc;
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
return dwc3_init(priv);
rc = dwc3_setup_phy(dev, &priv->phys, &priv->num_phys);
if (rc)
return rc;
dwc3->regs = map_physmem(priv->base, DWC3_OTG_REGS_END, MAP_NOCACHE);
dwc3->regs += DWC3_GLOBALS_REGS_START;
dwc3->dev = dev;
rc = dwc3_init(dwc3);
if (rc) {
unmap_physmem(dwc3->regs, MAP_NOCACHE);
return rc;
}
return 0;
}
static int dwc3_generic_peripheral_remove(struct udevice *dev)
{
struct dwc3 *priv = dev_get_priv(dev);
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
dwc3_remove(priv);
dwc3_remove(dwc3);
dwc3_shutdown_phy(dev, priv->phys, priv->num_phys);
unmap_physmem(dwc3->regs, MAP_NOCACHE);
return 0;
}
static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev)
{
struct dwc3 *priv = dev_get_priv(dev);
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
int node = dev_of_offset(dev);
priv->regs = (void *)devfdt_get_addr(dev);
priv->regs += DWC3_GLOBALS_REGS_START;
priv->base = devfdt_get_addr(dev);
priv->maximum_speed = usb_get_maximum_speed(node);
if (priv->maximum_speed == USB_SPEED_UNKNOWN) {
dwc3->maximum_speed = usb_get_maximum_speed(node);
if (dwc3->maximum_speed == USB_SPEED_UNKNOWN) {
pr_err("Invalid usb maximum speed\n");
return -ENODEV;
}
priv->dr_mode = usb_get_dr_mode(node);
if (priv->dr_mode == USB_DR_MODE_UNKNOWN) {
dwc3->dr_mode = usb_get_dr_mode(node);
if (dwc3->dr_mode == USB_DR_MODE_UNKNOWN) {
pr_err("Invalid usb mode setup\n");
return -ENODEV;
}
@@ -81,24 +98,112 @@ static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev)
return 0;
}
static int dwc3_generic_peripheral_bind(struct udevice *dev)
{
return device_probe(dev);
}
U_BOOT_DRIVER(dwc3_generic_peripheral) = {
.name = "dwc3-generic-peripheral",
.id = UCLASS_USB_DEV_GENERIC,
.id = UCLASS_USB_GADGET_GENERIC,
.ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata,
.probe = dwc3_generic_peripheral_probe,
.remove = dwc3_generic_peripheral_remove,
.bind = dwc3_generic_peripheral_bind,
.platdata_auto_alloc_size = sizeof(struct usb_platdata),
.priv_auto_alloc_size = sizeof(struct dwc3),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
.priv_auto_alloc_size = sizeof(struct dwc3_generic_peripheral),
};
#endif
struct dwc3_glue_data {
struct clk_bulk clks;
struct reset_ctl_bulk resets;
fdt_addr_t regs;
};
static int dwc3_generic_bind(struct udevice *parent)
struct dwc3_glue_ops {
void (*select_dr_mode)(struct udevice *dev, int index,
enum usb_dr_mode mode);
};
void dwc3_ti_select_dr_mode(struct udevice *dev, int index,
enum usb_dr_mode mode)
{
#define USBOTGSS_UTMI_OTG_STATUS 0x0084
#define USBOTGSS_UTMI_OTG_OFFSET 0x0480
/* UTMI_OTG_STATUS REGISTER */
#define USBOTGSS_UTMI_OTG_STATUS_SW_MODE BIT(31)
#define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT BIT(9)
#define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE BIT(8)
#define USBOTGSS_UTMI_OTG_STATUS_IDDIG BIT(4)
#define USBOTGSS_UTMI_OTG_STATUS_SESSEND BIT(3)
#define USBOTGSS_UTMI_OTG_STATUS_SESSVALID BIT(2)
#define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID BIT(1)
enum dwc3_omap_utmi_mode {
DWC3_OMAP_UTMI_MODE_UNKNOWN = 0,
DWC3_OMAP_UTMI_MODE_HW,
DWC3_OMAP_UTMI_MODE_SW,
};
u32 use_id_pin;
u32 host_mode;
u32 reg;
u32 utmi_mode;
u32 utmi_status_offset = USBOTGSS_UTMI_OTG_STATUS;
struct dwc3_glue_data *glue = dev_get_platdata(dev);
void *base = map_physmem(glue->regs, 0x10000, MAP_NOCACHE);
if (device_is_compatible(dev, "ti,am437x-dwc3"))
utmi_status_offset += USBOTGSS_UTMI_OTG_OFFSET;
utmi_mode = dev_read_u32_default(dev, "utmi-mode",
DWC3_OMAP_UTMI_MODE_UNKNOWN);
if (utmi_mode != DWC3_OMAP_UTMI_MODE_HW) {
debug("%s: OTG is not supported. defaulting to PERIPHERAL\n",
dev->name);
mode = USB_DR_MODE_PERIPHERAL;
}
switch (mode) {
case USB_DR_MODE_PERIPHERAL:
use_id_pin = 0;
host_mode = 0;
break;
case USB_DR_MODE_HOST:
use_id_pin = 0;
host_mode = 1;
break;
case USB_DR_MODE_OTG:
default:
use_id_pin = 1;
host_mode = 0;
break;
}
reg = readl(base + utmi_status_offset);
reg &= ~(USBOTGSS_UTMI_OTG_STATUS_SW_MODE);
if (!use_id_pin)
reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
writel(reg, base + utmi_status_offset);
reg &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSEND |
USBOTGSS_UTMI_OTG_STATUS_VBUSVALID |
USBOTGSS_UTMI_OTG_STATUS_IDDIG);
reg |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID |
USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT;
if (!host_mode)
reg |= USBOTGSS_UTMI_OTG_STATUS_IDDIG |
USBOTGSS_UTMI_OTG_STATUS_VBUSVALID;
writel(reg, base + utmi_status_offset);
unmap_physmem(base, MAP_NOCACHE);
}
struct dwc3_glue_ops ti_ops = {
.select_dr_mode = dwc3_ti_select_dr_mode,
};
static int dwc3_glue_bind(struct udevice *parent)
{
const void *fdt = gd->fdt_blob;
int node;
@@ -109,29 +214,32 @@ static int dwc3_generic_bind(struct udevice *parent)
const char *name = fdt_get_name(fdt, node, NULL);
enum usb_dr_mode dr_mode;
struct udevice *dev;
const char *driver;
const char *driver = NULL;
debug("%s: subnode name: %s\n", __func__, name);
if (strncmp(name, "dwc3@", 4))
continue;
dr_mode = usb_get_dr_mode(node);
switch (dr_mode) {
case USB_DR_MODE_PERIPHERAL:
case USB_DR_MODE_OTG:
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
debug("%s: dr_mode: OTG or Peripheral\n", __func__);
driver = "dwc3-generic-peripheral";
#endif
break;
case USB_DR_MODE_HOST:
debug("%s: dr_mode: HOST\n", __func__);
driver = "dwc3-generic-host";
driver = "xhci-dwc3";
break;
default:
debug("%s: unsupported dr_mode\n", __func__);
return -ENODEV;
};
if (!driver)
continue;
ret = device_bind_driver_to_node(parent, driver, name,
offset_to_ofnode(node), &dev);
if (ret) {
@@ -144,14 +252,107 @@ static int dwc3_generic_bind(struct udevice *parent)
return 0;
}
static const struct udevice_id dwc3_generic_ids[] = {
static int dwc3_glue_reset_init(struct udevice *dev,
struct dwc3_glue_data *glue)
{
int ret;
ret = reset_get_bulk(dev, &glue->resets);
if (ret == -ENOTSUPP)
return 0;
else if (ret)
return ret;
ret = reset_deassert_bulk(&glue->resets);
if (ret) {
reset_release_bulk(&glue->resets);
return ret;
}
return 0;
}
static int dwc3_glue_clk_init(struct udevice *dev,
struct dwc3_glue_data *glue)
{
int ret;
ret = clk_get_bulk(dev, &glue->clks);
if (ret == -ENOSYS)
return 0;
if (ret)
return ret;
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable_bulk(&glue->clks);
if (ret) {
clk_release_bulk(&glue->clks);
return ret;
}
#endif
return 0;
}
static int dwc3_glue_probe(struct udevice *dev)
{
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(dev);
struct dwc3_glue_data *glue = dev_get_platdata(dev);
struct udevice *child = NULL;
int index = 0;
int ret;
glue->regs = dev_read_addr(dev);
ret = dwc3_glue_clk_init(dev, glue);
if (ret)
return ret;
ret = dwc3_glue_reset_init(dev, glue);
if (ret)
return ret;
ret = device_find_first_child(dev, &child);
if (ret)
return ret;
while (child) {
enum usb_dr_mode dr_mode;
dr_mode = usb_get_dr_mode(dev_of_offset(child));
device_find_next_child(&child);
if (ops && ops->select_dr_mode)
ops->select_dr_mode(dev, index, dr_mode);
index++;
}
return 0;
}
static int dwc3_glue_remove(struct udevice *dev)
{
struct dwc3_glue_data *glue = dev_get_platdata(dev);
reset_release_bulk(&glue->resets);
clk_release_bulk(&glue->clks);
return dm_scan_fdt_dev(dev);
}
static const struct udevice_id dwc3_glue_ids[] = {
{ .compatible = "xlnx,zynqmp-dwc3" },
{ .compatible = "ti,dwc3", .data = (ulong)&ti_ops },
{ }
};
U_BOOT_DRIVER(dwc3_generic_wrapper) = {
.name = "dwc3-generic-wrapper",
.id = UCLASS_MISC,
.of_match = dwc3_generic_ids,
.bind = dwc3_generic_bind,
.of_match = dwc3_glue_ids,
.bind = dwc3_glue_bind,
.probe = dwc3_glue_probe,
.remove = dwc3_glue_remove,
.platdata_auto_alloc_size = sizeof(struct dwc3_glue_data),
};
+1 -1
View File
@@ -12,7 +12,7 @@
*
* commit c00552ebaf : Merge 3.18-rc7 into usb-next
*/
#include <common.h>
#include <linux/kernel.h>
#include <linux/list.h>
+6 -34
View File
@@ -100,9 +100,6 @@ struct eth_dev {
struct usb_gadget *gadget;
struct usb_request *req; /* for control responses */
struct usb_request *stat_req; /* for cdc & rndis status */
#if CONFIG_IS_ENABLED(DM_USB)
struct udevice *usb_udev;
#endif
u8 config;
struct usb_ep *in_ep, *out_ep, *status_ep;
@@ -2336,40 +2333,17 @@ fail:
}
/*-------------------------------------------------------------------------*/
#if CONFIG_IS_ENABLED(DM_USB)
int dm_usb_init(struct eth_dev *e_dev)
{
struct udevice *dev = NULL;
int ret;
ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev);
if (!dev || ret) {
pr_err("No USB device found\n");
return -ENODEV;
}
e_dev->usb_udev = dev;
return ret;
}
#endif
static int _usb_eth_init(struct ether_priv *priv)
{
struct eth_dev *dev = &priv->ethdev;
struct usb_gadget *gadget;
unsigned long ts;
int ret;
unsigned long timeout = USB_CONNECT_TIMEOUT;
#if CONFIG_IS_ENABLED(DM_USB)
if (dm_usb_init(dev)) {
pr_err("USB ether not found\n");
return -ENODEV;
}
#else
board_usb_init(0, USB_INIT_DEVICE);
#endif
ret = usb_gadget_initialize(0);
if (ret)
return ret;
/* Configure default mac-addresses for the USB ethernet device */
#ifdef CONFIG_USBNET_DEV_ADDR
@@ -2541,9 +2515,7 @@ void _usb_eth_halt(struct ether_priv *priv)
}
usb_gadget_unregister_driver(&priv->eth_driver);
#if !CONFIG_IS_ENABLED(DM_USB)
board_usb_cleanup(0, USB_INIT_DEVICE);
#endif
usb_gadget_release(0);
}
#ifndef CONFIG_DM_ETH
@@ -2699,7 +2671,7 @@ int usb_ether_init(void)
struct udevice *usb_dev;
int ret;
ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &usb_dev);
ret = uclass_first_device(UCLASS_USB_GADGET_GENERIC, &usb_dev);
if (!usb_dev || ret) {
pr_err("No USB device found\n");
return ret;
+4
View File
@@ -2,4 +2,8 @@
#
# USB peripheral controller drivers
ifndef CONFIG_$(SPL_)DM_USB_GADGET
obj-$(CONFIG_USB_DWC3_GADGET) += udc-core.o
endif
obj-$(CONFIG_$(SPL_)DM_USB_GADGET) += udc-uclass.o udc-core.o
+2 -1
View File
@@ -18,7 +18,8 @@
#include <asm/cache.h>
#include <asm/dma-mapping.h>
#include <common.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+58
View File
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
* Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
*/
#include <common.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <linux/usb/gadget.h>
#define MAX_UDC_DEVICES 4
static struct udevice *dev_array[MAX_UDC_DEVICES];
int usb_gadget_initialize(int index)
{
int ret;
struct udevice *dev = NULL;
if (index < 0 || index >= ARRAY_SIZE(dev_array))
return -EINVAL;
if (dev_array[index])
return 0;
ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, index, &dev);
if (!dev || ret) {
pr_err("No USB device found\n");
return -ENODEV;
}
dev_array[index] = dev;
return 0;
}
int usb_gadget_release(int index)
{
#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
int ret;
if (index < 0 || index >= ARRAY_SIZE(dev_array))
return -EINVAL;
ret = device_remove(dev_array[index], DM_REMOVE_NORMAL);
if (!ret)
dev_array[index] = NULL;
return ret;
#else
return -ENOTSUPP;
#endif
}
int usb_gadget_handle_interrupts(int index)
{
if (index < 0 || index >= ARRAY_SIZE(dev_array))
return -EINVAL;
return dm_usb_gadget_handle_interrupts(dev_array[index]);
}
UCLASS_DRIVER(usb_gadget_generic) = {
.id = UCLASS_USB_GADGET_GENERIC,
.name = "usb_gadget_generic",
};
+7 -88
View File
@@ -12,6 +12,7 @@
#include <fdtdec.h>
#include <generic-phy.h>
#include <usb.h>
#include <dwc3-uboot.h>
#include "xhci.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)
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)
{
struct xhci_hcor *hcor;
struct xhci_hccr *hccr;
struct dwc3 *dwc3_reg;
enum usb_dr_mode dr_mode;
struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
int ret;
hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev));
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
ret = xhci_dwc3_setup_phy(dev);
if (ret)
ret = dwc3_setup_phy(dev, &plat->usb_phys, &plat->num_phys);
if (ret && (ret != -ENOTSUPP))
return ret;
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)
{
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);
}
+1 -1
View File
@@ -263,7 +263,7 @@ U_BOOT_DRIVER(omap2430_musb) = {
#ifdef CONFIG_USB_MUSB_HOST
.id = UCLASS_USB,
#else
.id = UCLASS_USB_DEV_GENERIC,
.id = UCLASS_USB_GADGET_GENERIC,
#endif
.of_match = omap2430_musb_ids,
.ofdata_to_platdata = omap2430_musb_ofdata_to_platdata,
+1 -1
View File
@@ -535,7 +535,7 @@ U_BOOT_DRIVER(usb_musb) = {
#ifdef CONFIG_USB_MUSB_HOST
.id = UCLASS_USB,
#else
.id = UCLASS_USB_DEV_GENERIC,
.id = UCLASS_USB_GADGET_GENERIC,
#endif
.of_match = sunxi_musb_ids,
.probe = musb_usb_probe,
+1
View File
@@ -94,6 +94,7 @@ enum uclass_id {
UCLASS_USB, /* USB bus */
UCLASS_USB_DEV_GENERIC, /* USB generic device */
UCLASS_USB_HUB, /* USB hub */
UCLASS_USB_GADGET_GENERIC, /* USB generic device */
UCLASS_VIDEO, /* Video or LCD device */
UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */
UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */
+19
View File
@@ -38,4 +38,23 @@ struct dwc3_device {
int dwc3_uboot_init(struct dwc3_device *dev);
void dwc3_uboot_exit(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_ */
+18
View File
@@ -19,6 +19,7 @@
#define __LINUX_USB_GADGET_H
#include <errno.h>
#include <usb.h>
#include <linux/compat.h>
#include <linux/list.h>
@@ -926,4 +927,21 @@ extern void usb_ep_autoconfig_reset(struct usb_gadget *);
extern int usb_gadget_handle_interrupts(int index);
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
int usb_gadget_initialize(int index);
int usb_gadget_release(int index);
int dm_usb_gadget_handle_interrupts(struct udevice *dev);
#else
#include <usb.h>
static inline int usb_gadget_initialize(int index)
{
return board_usb_init(index, USB_INIT_DEVICE);
}
static inline int usb_gadget_release(int index)
{
return board_usb_cleanup(index, USB_INIT_DEVICE);
}
#endif
#endif /* __LINUX_USB_GADGET_H */
+13
View File
@@ -73,6 +73,19 @@ int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp);
*/
struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data);
/**
* syscon_regmap_lookup_by_phandle() - Look up a controller by a phandle
*
* This operates by looking up the given name in the device (device
* tree property) of the device using the system controller.
*
* @dev: Device using the system controller
* @name: Name of property referring to the system controller
* @return A pointer to the regmap if found, ERR_PTR(-ve) on error
*/
struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev,
const char *name);
/**
* syscon_get_first_range() - get the first memory range from a syscon regmap
*
+29
View File
@@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
#include <syscon.h>
#include <regmap.h>
#include <asm/test.h>
#include <dm/test.h>
#include <test/ut.h>
@@ -43,3 +44,31 @@ static int dm_test_syscon_by_driver_data(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_syscon_by_driver_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
/* Test system controller by phandle */
static int dm_test_syscon_by_phandle(struct unit_test_state *uts)
{
struct udevice *dev;
struct regmap *map;
ut_assertok(uclass_get_device_by_name(UCLASS_TEST_PROBE, "test4",
&dev));
ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev, "first-syscon"));
map = syscon_regmap_lookup_by_phandle(dev, "first-syscon");
ut_assert(map);
ut_assert(!IS_ERR(map));
ut_asserteq(1, map->range_count);
ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev,
"second-sys-ctrl"));
map = syscon_regmap_lookup_by_phandle(dev, "second-sys-ctrl");
ut_assert(map);
ut_assert(!IS_ERR(map));
ut_asserteq(4, map->range_count);
ut_assert(IS_ERR(syscon_regmap_lookup_by_phandle(dev, "not-present")));
return 0;
}
DM_TEST(dm_test_syscon_by_phandle, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);