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

- Various fastboot, dwc2/stm32 updates
This commit is contained in:
Tom Rini 2019-04-21 19:00:04 -04:00
commit 6c5f8dd540
39 changed files with 688 additions and 259 deletions

View File

@ -375,6 +375,13 @@
};
};
stusb1600_pins_a: stusb1600-0 {
pins {
pinmux = <STM32_PINMUX('I', 11, ANALOG)>;
bias-pull-up;
};
};
uart4_pins_a: uart4-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */

View File

@ -11,6 +11,7 @@
aliases {
i2c3 = &i2c4;
mmc0 = &sdmmc1;
usb0 = &usbotg_hs;
};
config {
u-boot,boot-led = "heartbeat";
@ -190,7 +191,7 @@
};
&usbotg_hs {
usb1600;
u-boot,force-b-session-valid;
hnp-srp-disable;
};

View File

@ -67,6 +67,24 @@
/delete-property/dmas;
/delete-property/dma-names;
typec: stusb1600@28 {
compatible = "st,stusb1600";
reg = <0x28>;
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpioi>;
pinctrl-names = "default";
pinctrl-0 = <&stusb1600_pins_a>;
status = "okay";
typec_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
power-role = "sink";
power-opmode = "default";
};
};
pmic: stpmic@33 {
compatible = "st,stpmic1";
reg = <0x33>;
@ -249,11 +267,25 @@
status = "okay";
};
&usbphyc {
vdd3v3-supply = <&vdd_usb>;
&usbotg_hs {
dr_mode = "peripheral";
phys = <&usbphyc_port1 0>;
phy-names = "usb2-phy";
status = "okay";
};
&usbphyc {
status = "okay";
};
&usbphyc_port0 {
phy-supply = <&vdd_usb>;
};
&usbphyc_port1 {
phy-supply = <&vdd_usb>;
};
&vrefbuf {
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;

View File

@ -382,18 +382,10 @@
status = "okay";
};
&usbotg_hs {
usb33d-supply = <&usb33>;
};
&usbphyc_port0 {
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
vdda1v8-supply = <&reg18>;
};
&usbphyc_port1 {
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
vdda1v8-supply = <&reg18>;
};

View File

@ -12,6 +12,7 @@
i2c4 = &i2c5;
pinctrl2 = &stmfx_pinctrl;
spi0 = &qspi;
usb0 = &usbotg_hs;
};
};

View File

@ -825,7 +825,7 @@
};
usbotg_hs: usb-otg@49000000 {
compatible = "snps,dwc2";
compatible = "st,stm32mp1-hsotg", "snps,dwc2";
reg = <0x49000000 0x10000>;
clocks = <&rcc USBO_K>;
clock-names = "otg";
@ -836,6 +836,7 @@
g-np-tx-fifo-size = <32>;
g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
dr_mode = "otg";
usb33d-supply = <&usb33>;
status = "disabled";
};
@ -1161,6 +1162,8 @@
reg = <0x5a006000 0x1000>;
clocks = <&rcc USBPHY_K>;
resets = <&rcc USBPHY_R>;
vdda1v1-supply = <&reg11>;
vdda1v8-supply = <&reg18>;
status = "disabled";
usbphyc_port0: usb-phy@0 {

View File

@ -7,7 +7,9 @@
#include <config.h>
#include <clk.h>
#include <dm.h>
#include <g_dnl.h>
#include <generic-phy.h>
#include <i2c.h>
#include <led.h>
#include <misc.h>
#include <phy.h>
@ -58,11 +60,6 @@
*/
DECLARE_GLOBAL_DATA_PTR;
#define STM32MP_GUSBCFG 0x40002407
#define STM32MP_GGPIO 0x38
#define STM32MP_GGPIO_VBUS_SENSING BIT(21)
#define USB_WARNING_LOW_THRESHOLD_UV 660000
#define USB_START_LOW_THRESHOLD_UV 1230000
#define USB_START_HIGH_THRESHOLD_UV 2100000
@ -155,150 +152,76 @@ static void board_key_check(void)
#endif
}
static struct dwc2_plat_otg_data stm32mp_otg_data = {
.usb_gusbcfg = STM32MP_GUSBCFG,
};
#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
static struct reset_ctl usbotg_reset;
/* STMicroelectronics STUSB1600 Type-C controller */
#define STUSB1600_CC_CONNECTION_STATUS 0x0E
int board_usb_init(int index, enum usb_init_type init)
/* STUSB1600_CC_CONNECTION_STATUS bitfields */
#define STUSB1600_CC_ATTACH BIT(0)
static int stusb1600_init(struct udevice **dev_stusb1600)
{
struct fdtdec_phandle_args args;
struct udevice *dev;
const void *blob = gd->fdt_blob;
struct clk clk;
struct phy phy;
int node;
int phy_provider;
ofnode node;
struct udevice *dev, *bus;
int ret;
u32 chip_addr;
/* find the usb otg node */
node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
if (node < 0) {
debug("Not found usb_otg device\n");
*dev_stusb1600 = NULL;
/* if node stusb1600 is present, means DK1 or DK2 board */
node = ofnode_by_compatible(ofnode_null(), "st,stusb1600");
if (!ofnode_valid(node))
return -ENODEV;
}
if (!fdtdec_get_is_enabled(blob, node)) {
debug("stm32 usbotg is disabled in the device tree\n");
return -ENODEV;
}
/* Enable clock */
ret = fdtdec_parse_phandle_with_args(blob, node, "clocks",
"#clock-cells", 0, 0, &args);
if (ret) {
debug("usbotg has no clocks defined in the device tree\n");
return ret;
}
ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev);
ret = ofnode_read_u32(node, "reg", &chip_addr);
if (ret)
return ret;
return -EINVAL;
if (args.args_count != 1) {
debug("Can't find clock ID in the device tree\n");
return -ENODATA;
}
clk.dev = dev;
clk.id = args.args[0];
ret = clk_enable(&clk);
ret = uclass_get_device_by_ofnode(UCLASS_I2C, ofnode_get_parent(node),
&bus);
if (ret) {
debug("Failed to enable usbotg clock\n");
return ret;
printf("bus for stusb1600 not found\n");
return -ENODEV;
}
/* Reset */
ret = fdtdec_parse_phandle_with_args(blob, node, "resets",
"#reset-cells", 0, 0, &args);
if (ret) {
debug("usbotg has no resets defined in the device tree\n");
goto clk_err;
}
ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev);
if (ret || args.args_count != 1)
goto clk_err;
usbotg_reset.dev = dev;
usbotg_reset.id = args.args[0];
reset_assert(&usbotg_reset);
udelay(2);
reset_deassert(&usbotg_reset);
/* Get USB PHY */
ret = fdtdec_parse_phandle_with_args(blob, node, "phys",
"#phy-cells", 0, 0, &args);
if (!ret) {
phy_provider = fdt_parent_offset(blob, args.node);
ret = uclass_get_device_by_of_offset(UCLASS_PHY,
phy_provider, &dev);
if (ret)
goto clk_err;
phy.dev = dev;
phy.id = fdtdec_get_uint(blob, args.node, "reg", -1);
ret = generic_phy_power_on(&phy);
if (ret) {
debug("unable to power on the phy\n");
goto clk_err;
}
ret = generic_phy_init(&phy);
if (ret) {
debug("failed to init usb phy\n");
goto phy_power_err;
}
}
/* Parse and store data needed for gadget */
stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) {
debug("usbotg: can't get base address\n");
ret = -ENODATA;
goto phy_init_err;
}
stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node,
"g-rx-fifo-size", 0);
stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node,
"g-np-tx-fifo-size", 0);
stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node,
"g-tx-fifo-size", 0);
/* Enable voltage level detector */
if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply",
NULL, 0, 0, &args))) {
if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR,
args.node, &dev)) {
ret = regulator_set_enable(dev, true);
if (ret) {
debug("Failed to enable usb33d\n");
goto phy_init_err;
}
}
}
/* Enable vbus sensing */
setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO,
STM32MP_GGPIO_VBUS_SENSING);
return dwc2_udc_probe(&stm32mp_otg_data);
phy_init_err:
generic_phy_exit(&phy);
phy_power_err:
generic_phy_power_off(&phy);
clk_err:
clk_disable(&clk);
ret = dm_i2c_probe(bus, chip_addr, 0, &dev);
if (!ret)
*dev_stusb1600 = dev;
return ret;
}
static int stusb1600_cable_connected(struct udevice *dev)
{
u8 status;
if (dm_i2c_read(dev, STUSB1600_CC_CONNECTION_STATUS, &status, 1))
return 0;
return status & STUSB1600_CC_ATTACH;
}
#include <usb/dwc2_udc.h>
int g_dnl_board_usb_cable_connected(void)
{
struct udevice *stusb1600;
struct udevice *dwc2_udc_otg;
int ret;
if (!stusb1600_init(&stusb1600))
return stusb1600_cable_connected(stusb1600);
ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC,
DM_GET_DRIVER(dwc2_udc_otg),
&dwc2_udc_otg);
if (!ret)
debug("dwc2_udc_otg init failed\n");
return dwc2_udc_B_session_valid(dwc2_udc_otg);
}
#endif /* CONFIG_USB_GADGET */
static int get_led(struct udevice **dev, char *led_string)
{
char *led_name;
@ -438,16 +361,6 @@ static int board_check_usb_power(void)
return 0;
}
int board_usb_cleanup(int index, enum usb_init_type init)
{
/* Reset usbotg */
reset_assert(&usbotg_reset);
udelay(2);
reset_deassert(&usbotg_reset);
return 0;
}
static void sysconf_init(void)
{
#ifndef CONFIG_STM32MP1_TRUSTED

View File

@ -27,8 +27,10 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_DFU_OVER_USB
char *usb_controller = argv[1];
#endif
#if defined(CONFIG_DFU_OVER_USB) || defined(CONFIG_DFU_OVER_TFTP)
char *interface = argv[2];
char *devstring = argv[3];
#endif
int ret = 0;
#ifdef CONFIG_DFU_OVER_TFTP
@ -63,6 +65,7 @@ done:
U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
"Device Firmware Upgrade",
""
#ifdef CONFIG_DFU_OVER_USB
"<USB_controller> <interface> <dev> [list]\n"
" - device firmware upgrade via <USB_controller>\n"

View File

@ -14,6 +14,7 @@
#include <part.h>
#include <usb.h>
#include <usb_mass_storage.h>
#include <watchdog.h>
static int ums_read_sector(struct ums *ums_dev,
ulong start, lbaint_t blkcnt, void *buf)
@ -226,6 +227,8 @@ static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
rc = CMD_RET_SUCCESS;
goto cleanup_register;
}
WATCHDOG_RESET();
}
cleanup_register:

View File

@ -56,7 +56,6 @@ CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451

View File

@ -64,7 +64,6 @@ CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451

View File

@ -60,7 +60,6 @@ CONFIG_DM_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451

View File

@ -62,7 +62,6 @@ CONFIG_DM_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451

View File

@ -84,7 +84,6 @@ CONFIG_DM_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_FAT_WRITE=y

View File

@ -88,7 +88,6 @@ CONFIG_DM_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_FAT_WRITE=y

View File

@ -99,7 +99,6 @@ CONFIG_DM_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_FAT_WRITE=y

View File

@ -50,6 +50,5 @@ CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_TI=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_FAT_WRITE=y
CONFIG_LZO=y

View File

@ -69,9 +69,9 @@ CONFIG_SERIAL_RX_BUFFER=y
CONFIG_STM32_SERIAL=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC2=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
CONFIG_USB_GADGET_VENDOR_NUM=0x0483

View File

@ -60,9 +60,9 @@ CONFIG_SERIAL_RX_BUFFER=y
CONFIG_STM32_SERIAL=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC2=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
CONFIG_USB_GADGET_VENDOR_NUM=0x0483

View File

@ -23,6 +23,8 @@ Required properties:
- compatible: must be "st,stm32mp1-usbphyc"
- reg: address and length of the usb phy control register set
- clocks: phandle + clock specifier for the PLL phy clock
- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY
- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY
- #address-cells: number of address cells for phys sub-nodes, must be <1>
- #size-cells: number of size cells for phys sub-nodes, must be <0>
@ -40,8 +42,6 @@ Required properties:
- reg: phy port index
- phy-supply: phandle to the regulator providing 3V3 power to the PHY,
see phy-bindings.txt in the same directory.
- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY
- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY
- #phy-cells: see phy-bindings.txt in the same directory, must be <0> for PHY
port#1 and must be <1> for PHY port#2, to select USB controller

View File

@ -0,0 +1,58 @@
Platform DesignWare HS OTG USB 2.0 controller
-----------------------------------------------------
Required properties:
- compatible : One of:
- brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC.
- hisilicon,hi6220-usb: The DWC2 USB controller instance in the hi6220 SoC.
- rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc;
- "rockchip,px30-usb", "rockchip,rk3066-usb", "snps,dwc2": for px30 Soc;
- "rockchip,rk3188-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3188 Soc;
- "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc;
- "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs;
- "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs;
- "amlogic,meson8-usb": The DWC2 USB controller instance in Amlogic Meson8 SoCs;
- "amlogic,meson8b-usb": The DWC2 USB controller instance in Amlogic Meson8b SoCs;
- "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs;
- "amcc,dwc-otg": The DWC2 USB controller instance in AMCC Canyonlands 460EX SoCs;
- snps,dwc2: A generic DWC2 USB controller with default parameters.
- "st,stm32f4x9-fsotg": The DWC2 USB FS/HS controller instance in STM32F4x9 SoCs
configured in FS mode;
- "st,stm32f4x9-hsotg": The DWC2 USB HS controller instance in STM32F4x9 SoCs
configured in HS mode;
- "st,stm32f7-hsotg": The DWC2 USB HS controller instance in STM32F7 SoCs
configured in HS mode;
- reg : Should contain 1 register range (address and length)
- interrupts : Should contain 1 interrupt
- clocks: clock provider specifier
- clock-names: shall be "otg"
Refer to clk/clock-bindings.txt for generic clock consumer properties
Optional properties:
- phys: phy provider specifier
- phy-names: shall be "usb2-phy"
Refer to phy/phy-bindings.txt for generic phy consumer properties
- dr_mode: shall be one of "host", "peripheral" and "otg"
Refer to usb/generic.txt
- g-rx-fifo-size: size of rx fifo size in gadget mode.
- g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode.
- g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode.
- usb33d-supply: external VBUS and ID sensing comparators supply, in order to
perform OTG operation, used on STM32MP1 SoCs.
- u-boot,force-b-session-valid: force B-peripheral session instead of relying on
VBUS sensing (only valid when dr_mode = "peripheral" and for u-boot).
Deprecated properties:
- g-use-dma: gadget DMA mode is automatically detected
Example:
usb@101c0000 {
compatible = "ralink,rt3050-usb, snps,dwc2";
reg = <0x101c0000 40000>;
interrupts = <18>;
clocks = <&usb_otg_ahb_clk>;
clock-names = "otg";
phys = <&usbphy>;
phy-names = "usb2-phy";
};

View File

@ -17,6 +17,7 @@ static void getvar_downloadsize(char *var_parameter, char *response);
static void getvar_serialno(char *var_parameter, char *response);
static void getvar_version_baseband(char *var_parameter, char *response);
static void getvar_product(char *var_parameter, char *response);
static void getvar_platform(char *var_parameter, char *response);
static void getvar_current_slot(char *var_parameter, char *response);
static void getvar_slot_suffixes(char *var_parameter, char *response);
static void getvar_has_slot(char *var_parameter, char *response);
@ -55,6 +56,9 @@ static const struct {
}, {
.variable = "product",
.dispatch = getvar_product
}, {
.variable = "platform",
.dispatch = getvar_platform
}, {
.variable = "current-slot",
.dispatch = getvar_current_slot
@ -62,7 +66,7 @@ static const struct {
.variable = "slot-suffixes",
.dispatch = getvar_slot_suffixes
}, {
.variable = "has_slot",
.variable = "has-slot",
.dispatch = getvar_has_slot
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
}, {
@ -117,6 +121,16 @@ static void getvar_product(char *var_parameter, char *response)
fastboot_fail("Board not set", response);
}
static void getvar_platform(char *var_parameter, char *response)
{
const char *p = env_get("platform");
if (p)
fastboot_okay(p, response);
else
fastboot_fail("platform not set", response);
}
static void getvar_current_slot(char *var_parameter, char *response)
{
/* A/B not implemented, for now always return _a */

View File

@ -31,13 +31,13 @@ static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
ret = part_get_info_by_name(dev_desc, name, info);
if (ret < 0) {
/* strlen("fastboot_partition_alias_") + 32(part_name) + 1 */
char env_alias_name[25 + 32 + 1];
/* strlen("fastboot_partition_alias_") + PART_NAME_LEN + 1 */
char env_alias_name[25 + PART_NAME_LEN + 1];
char *aliased_part_name;
/* check for alias */
strcpy(env_alias_name, "fastboot_partition_alias_");
strncat(env_alias_name, name, 32);
strncat(env_alias_name, name, PART_NAME_LEN);
aliased_part_name = env_get(env_alias_name);
if (aliased_part_name != NULL)
ret = part_get_info_by_name(dev_desc,
@ -308,8 +308,8 @@ int fastboot_mmc_get_part_info(char *part_name, struct blk_desc **dev_desc,
fastboot_fail("block device not found", response);
return -ENOENT;
}
if (!part_name) {
fastboot_fail("partition not found", response);
if (!part_name || !strcmp(part_name, "")) {
fastboot_fail("partition not given", response);
return -ENOENT;
}

View File

@ -37,7 +37,8 @@
#define MAX_PHYS 2
#define PLL_LOCK_TIME_US 100
/* max 100 us for PLL lock and 100 us for PHY init */
#define PLL_INIT_TIME_US 200
#define PLL_PWR_DOWN_TIME_US 5
#define PLL_FVCO 2880 /* in MHz */
#define PLL_INFF_MIN_RATE 19200000 /* in Hz */
@ -51,17 +52,17 @@ struct pll_params {
struct stm32_usbphyc {
fdt_addr_t base;
struct clk clk;
struct udevice *vdda1v1;
struct udevice *vdda1v8;
struct stm32_usbphyc_phy {
struct udevice *vdd;
struct udevice *vdda1v1;
struct udevice *vdda1v8;
int index;
bool init;
bool powered;
} phys[MAX_PHYS];
};
void stm32_usbphyc_get_pll_params(u32 clk_rate, struct pll_params *pll_params)
static void stm32_usbphyc_get_pll_params(u32 clk_rate,
struct pll_params *pll_params)
{
unsigned long long fvco, ndiv, frac;
@ -154,6 +155,18 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
if (pllen && stm32_usbphyc_is_init(usbphyc))
goto initialized;
if (usbphyc->vdda1v1) {
ret = regulator_set_enable(usbphyc->vdda1v1, true);
if (ret)
return ret;
}
if (usbphyc->vdda1v8) {
ret = regulator_set_enable(usbphyc->vdda1v8, true);
if (ret)
return ret;
}
if (pllen) {
clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
udelay(PLL_PWR_DOWN_TIME_US);
@ -165,11 +178,8 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
/*
* We must wait PLL_LOCK_TIME_US before checking that PLLEN
* bit is still set
*/
udelay(PLL_LOCK_TIME_US);
/* We must wait PLL_INIT_TIME_US before using PHY */
udelay(PLL_INIT_TIME_US);
if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
return -EIO;
@ -184,6 +194,7 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
{
struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
int ret;
pr_debug("%s phy ID = %lu\n", __func__, phy->id);
usbphyc_phy->init = false;
@ -203,6 +214,18 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
if (readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)
return -EIO;
if (usbphyc->vdda1v1) {
ret = regulator_set_enable(usbphyc->vdda1v1, false);
if (ret)
return ret;
}
if (usbphyc->vdda1v8) {
ret = regulator_set_enable(usbphyc->vdda1v8, false);
if (ret)
return ret;
}
return 0;
}
@ -213,17 +236,6 @@ static int stm32_usbphyc_phy_power_on(struct phy *phy)
int ret;
pr_debug("%s phy ID = %lu\n", __func__, phy->id);
if (usbphyc_phy->vdda1v1) {
ret = regulator_set_enable(usbphyc_phy->vdda1v1, true);
if (ret)
return ret;
}
if (usbphyc_phy->vdda1v8) {
ret = regulator_set_enable(usbphyc_phy->vdda1v8, true);
if (ret)
return ret;
}
if (usbphyc_phy->vdd) {
ret = regulator_set_enable(usbphyc_phy->vdd, true);
if (ret)
@ -247,18 +259,6 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy)
if (stm32_usbphyc_is_powered(usbphyc))
return 0;
if (usbphyc_phy->vdda1v1) {
ret = regulator_set_enable(usbphyc_phy->vdda1v1, false);
if (ret)
return ret;
}
if (usbphyc_phy->vdda1v8) {
ret = regulator_set_enable(usbphyc_phy->vdda1v8, false);
if (ret)
return ret;
}
if (usbphyc_phy->vdd) {
ret = regulator_set_enable(usbphyc_phy->vdd, false);
if (ret)
@ -298,19 +298,20 @@ static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
static int stm32_usbphyc_of_xlate(struct phy *phy,
struct ofnode_phandle_args *args)
{
if (args->args_count > 1) {
pr_debug("%s: invalid args_count: %d\n", __func__,
args->args_count);
return -EINVAL;
}
if (args->args_count < 1)
return -ENODEV;
if (args->args[0] >= MAX_PHYS)
return -ENODEV;
if (args->args_count)
phy->id = args->args[0];
else
phy->id = 0;
phy->id = args->args[0];
if ((phy->id == 0 && args->args_count != 1) ||
(phy->id == 1 && args->args_count != 2)) {
dev_err(dev, "invalid number of cells for phy port%ld\n",
phy->id);
return -EINVAL;
}
return 0;
}
@ -351,6 +352,21 @@ static int stm32_usbphyc_probe(struct udevice *dev)
reset_deassert(&reset);
}
/* get usbphyc regulator */
ret = device_get_supply_regulator(dev, "vdda1v1-supply",
&usbphyc->vdda1v1);
if (ret) {
dev_err(dev, "Can't get vdda1v1-supply regulator\n");
return ret;
}
ret = device_get_supply_regulator(dev, "vdda1v8-supply",
&usbphyc->vdda1v8);
if (ret) {
dev_err(dev, "Can't get vdda1v8-supply regulator\n");
return ret;
}
/*
* parse all PHY subnodes in order to populate regulator associated
* to each PHY port
@ -359,7 +375,6 @@ static int stm32_usbphyc_probe(struct udevice *dev)
for (i = 0; i < MAX_PHYS; i++) {
struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + i;
usbphyc_phy->index = i;
usbphyc_phy->init = false;
usbphyc_phy->powered = false;
ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply",
@ -367,16 +382,6 @@ static int stm32_usbphyc_probe(struct udevice *dev)
if (ret)
return ret;
ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v1-supply",
&usbphyc_phy->vdda1v1);
if (ret)
return ret;
ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v8-supply",
&usbphyc_phy->vdda1v8);
if (ret)
return ret;
node = dev_read_next_subnode(node);
}

View File

@ -18,11 +18,17 @@
*/
#undef DEBUG
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <generic-phy.h>
#include <malloc.h>
#include <reset.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <malloc.h>
#include <linux/usb/ch9.h>
#include <linux/usb/otg.h>
#include <linux/usb/gadget.h>
#include <asm/byteorder.h>
@ -31,6 +37,8 @@
#include <asm/mach-types.h>
#include <power/regulator.h>
#include "dwc2_udc_otg_regs.h"
#include "dwc2_udc_otg_priv.h"
@ -140,7 +148,6 @@ static struct usb_ep_ops dwc2_ep_ops = {
/***********************************************************/
void __iomem *regs_otg;
struct dwc2_usbotg_reg *reg;
bool dfu_usb_get_reset(void)
@ -223,6 +230,7 @@ static int udc_enable(struct dwc2_udc *dev)
return 0;
}
#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
/*
Register entry point for the peripheral controller driver.
*/
@ -297,6 +305,54 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc_disable(dev);
return 0;
}
#else /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */
static int dwc2_gadget_start(struct usb_gadget *g,
struct usb_gadget_driver *driver)
{
struct dwc2_udc *dev = the_controller;
debug_cond(DEBUG_SETUP != 0, "%s: %s\n", __func__, "no name");
if (!driver ||
(driver->speed != USB_SPEED_FULL &&
driver->speed != USB_SPEED_HIGH) ||
!driver->bind || !driver->disconnect || !driver->setup)
return -EINVAL;
if (!dev)
return -ENODEV;
if (dev->driver)
return -EBUSY;
/* first hook up the driver ... */
dev->driver = driver;
debug_cond(DEBUG_SETUP != 0,
"Registered gadget driver %s\n", dev->gadget.name);
return udc_enable(dev);
}
static int dwc2_gadget_stop(struct usb_gadget *g)
{
struct dwc2_udc *dev = the_controller;
if (!dev)
return -ENODEV;
if (!dev->driver)
return -EINVAL;
dev->driver = 0;
stop_activity(dev, dev->driver);
udc_disable(dev);
return 0;
}
#endif /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */
/*
* done - retire a request; caller blocked irqs
@ -400,6 +456,8 @@ static void reconfig_usbd(struct dwc2_udc *dev)
unsigned int uTemp = writel(CORE_SOFT_RESET, &reg->grstctl);
uint32_t dflt_gusbcfg;
uint32_t rx_fifo_sz, tx_fifo_sz, np_tx_fifo_sz;
u32 max_hw_ep;
int pdata_hw_ep;
debug("Reseting OTG controller\n");
@ -482,10 +540,23 @@ static void reconfig_usbd(struct dwc2_udc *dev)
writel((np_tx_fifo_sz << 16) | rx_fifo_sz,
&reg->gnptxfsiz);
for (i = 1; i < DWC2_MAX_HW_ENDPOINTS; i++)
writel((rx_fifo_sz + np_tx_fifo_sz + tx_fifo_sz*(i-1)) |
tx_fifo_sz << 16, &reg->dieptxf[i-1]);
/* retrieve the number of IN Endpoints (excluding ep0) */
max_hw_ep = (readl(&reg->ghwcfg4) & GHWCFG4_NUM_IN_EPS_MASK) >>
GHWCFG4_NUM_IN_EPS_SHIFT;
pdata_hw_ep = dev->pdata->tx_fifo_sz_nb;
/* tx_fifo_sz_nb should equal to number of IN Endpoint */
if (pdata_hw_ep && max_hw_ep != pdata_hw_ep)
pr_warn("Got %d hw endpoint but %d tx-fifo-size in array !!\n",
max_hw_ep, pdata_hw_ep);
for (i = 0; i < max_hw_ep; i++) {
if (pdata_hw_ep)
tx_fifo_sz = dev->pdata->tx_fifo_sz_array[i];
writel((rx_fifo_sz + np_tx_fifo_sz + (tx_fifo_sz * i)) |
tx_fifo_sz << 16, &reg->dieptxf[i]);
}
/* Flush the RX FIFO */
writel(RX_FIFO_FLUSH, &reg->grstctl);
while (readl(&reg->grstctl) & RX_FIFO_FLUSH)
@ -731,6 +802,10 @@ static void dwc2_fifo_flush(struct usb_ep *_ep)
static const struct usb_gadget_ops dwc2_udc_ops = {
/* current versions must always be self-powered */
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
.udc_start = dwc2_gadget_start,
.udc_stop = dwc2_gadget_stop,
#endif
};
static struct dwc2_udc memory = {
@ -818,8 +893,6 @@ int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata)
reg = (struct dwc2_usbotg_reg *)pdata->regs_otg;
/* regs_otg = (void *)pdata->regs_otg; */
dev->gadget.is_dualspeed = 1; /* Hack only*/
dev->gadget.is_otg = 0;
dev->gadget.is_a_peripheral = 0;
@ -844,12 +917,311 @@ int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata)
return retval;
}
int usb_gadget_handle_interrupts(int index)
int dwc2_udc_handle_interrupt(void)
{
u32 intr_status = readl(&reg->gintsts);
u32 gintmsk = readl(&reg->gintmsk);
if (intr_status & gintmsk)
return dwc2_udc_irq(1, (void *)the_controller);
return 0;
}
#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
int usb_gadget_handle_interrupts(int index)
{
return dwc2_udc_handle_interrupt();
}
#else /* CONFIG_IS_ENABLED(DM_USB_GADGET) */
struct dwc2_priv_data {
struct clk_bulk clks;
struct reset_ctl_bulk resets;
struct phy *phys;
int num_phys;
struct udevice *usb33d_supply;
};
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
{
return dwc2_udc_handle_interrupt();
}
int dwc2_phy_setup(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) {
dev_err(dev, "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) {
dev_err(dev, "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) {
dev_err(dev, "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;
}
void dwc2_phy_shutdown(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) {
dev_err(dev, "Can't shutdown USB PHY%d for %s\n",
i, dev->name);
}
}
}
static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev)
{
struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
int node = dev_of_offset(dev);
ulong drvdata;
void (*set_params)(struct dwc2_plat_otg_data *data);
if (usb_get_dr_mode(node) != USB_DR_MODE_PERIPHERAL) {
dev_dbg(dev, "Invalid mode\n");
return -ENODEV;
}
platdata->regs_otg = dev_read_addr(dev);
platdata->rx_fifo_sz = dev_read_u32_default(dev, "g-rx-fifo-size", 0);
platdata->np_tx_fifo_sz = dev_read_u32_default(dev,
"g-np-tx-fifo-size", 0);
platdata->tx_fifo_sz = dev_read_u32_default(dev, "g-tx-fifo-size", 0);
platdata->force_b_session_valid =
dev_read_bool(dev, "u-boot,force-b-session-valid");
/* force platdata according compatible */
drvdata = dev_get_driver_data(dev);
if (drvdata) {
set_params = (void *)drvdata;
set_params(platdata);
}
return 0;
}
static void dwc2_set_stm32mp1_hsotg_params(struct dwc2_plat_otg_data *p)
{
p->activate_stm_id_vb_detection = true;
p->usb_gusbcfg =
0 << 15 /* PHY Low Power Clock sel*/
| 0x9 << 10 /* USB Turnaround time (0x9 for HS phy) */
| 0 << 9 /* [0:HNP disable,1:HNP enable]*/
| 0 << 8 /* [0:SRP disable 1:SRP enable]*/
| 0 << 6 /* 0: high speed utmi+, 1: full speed serial*/
| 0x7 << 0; /* FS timeout calibration**/
if (p->force_b_session_valid)
p->usb_gusbcfg |= 1 << 30; /* FDMOD: Force device mode */
}
static int dwc2_udc_otg_reset_init(struct udevice *dev,
struct reset_ctl_bulk *resets)
{
int ret;
ret = reset_get_bulk(dev, resets);
if (ret == -ENOTSUPP)
return 0;
if (ret)
return ret;
ret = reset_assert_bulk(resets);
if (!ret) {
udelay(2);
ret = reset_deassert_bulk(resets);
}
if (ret) {
reset_release_bulk(resets);
return ret;
}
return 0;
}
static int dwc2_udc_otg_clk_init(struct udevice *dev,
struct clk_bulk *clks)
{
int ret;
ret = clk_get_bulk(dev, clks);
if (ret == -ENOSYS)
return 0;
if (ret)
return ret;
ret = clk_enable_bulk(clks);
if (ret) {
clk_release_bulk(clks);
return ret;
}
return 0;
}
static int dwc2_udc_otg_probe(struct udevice *dev)
{
struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
struct dwc2_priv_data *priv = dev_get_priv(dev);
struct dwc2_usbotg_reg *usbotg_reg =
(struct dwc2_usbotg_reg *)platdata->regs_otg;
int ret;
ret = dwc2_udc_otg_clk_init(dev, &priv->clks);
if (ret)
return ret;
ret = dwc2_udc_otg_reset_init(dev, &priv->resets);
if (ret)
return ret;
ret = dwc2_phy_setup(dev, &priv->phys, &priv->num_phys);
if (ret)
return ret;
if (CONFIG_IS_ENABLED(DM_REGULATOR) &&
platdata->activate_stm_id_vb_detection &&
!platdata->force_b_session_valid) {
ret = device_get_supply_regulator(dev, "usb33d-supply",
&priv->usb33d_supply);
if (ret) {
dev_err(dev, "can't get voltage level detector supply\n");
return ret;
}
ret = regulator_set_enable(priv->usb33d_supply, true);
if (ret) {
dev_err(dev, "can't enable voltage level detector supply\n");
return ret;
}
/* Enable vbus sensing */
setbits_le32(&usbotg_reg->ggpio,
GGPIO_STM32_OTG_GCCFG_VBDEN |
GGPIO_STM32_OTG_GCCFG_IDEN);
}
if (platdata->force_b_session_valid)
/* Override B session bits : value and enable */
setbits_le32(&usbotg_reg->gotgctl,
A_VALOEN | A_VALOVAL | B_VALOEN | B_VALOVAL);
ret = dwc2_udc_probe(platdata);
if (ret)
return ret;
the_controller->driver = 0;
ret = usb_add_gadget_udc((struct device *)dev, &the_controller->gadget);
return ret;
}
static int dwc2_udc_otg_remove(struct udevice *dev)
{
struct dwc2_priv_data *priv = dev_get_priv(dev);
usb_del_gadget_udc(&the_controller->gadget);
reset_release_bulk(&priv->resets);
clk_release_bulk(&priv->clks);
dwc2_phy_shutdown(dev, priv->phys, priv->num_phys);
return dm_scan_fdt_dev(dev);
}
static const struct udevice_id dwc2_udc_otg_ids[] = {
{ .compatible = "snps,dwc2" },
{ .compatible = "st,stm32mp1-hsotg",
.data = (ulong)dwc2_set_stm32mp1_hsotg_params },
{},
};
U_BOOT_DRIVER(dwc2_udc_otg) = {
.name = "dwc2-udc-otg",
.id = UCLASS_USB_GADGET_GENERIC,
.of_match = dwc2_udc_otg_ids,
.ofdata_to_platdata = dwc2_udc_otg_ofdata_to_platdata,
.probe = dwc2_udc_otg_probe,
.remove = dwc2_udc_otg_remove,
.platdata_auto_alloc_size = sizeof(struct dwc2_plat_otg_data),
.priv_auto_alloc_size = sizeof(struct dwc2_priv_data),
};
int dwc2_udc_B_session_valid(struct udevice *dev)
{
struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
struct dwc2_usbotg_reg *usbotg_reg =
(struct dwc2_usbotg_reg *)platdata->regs_otg;
return readl(&usbotg_reg->gotgctl) & B_SESSION_VALID;
}
#endif /* CONFIG_IS_ENABLED(DM_USB_GADGET) */

View File

@ -23,7 +23,6 @@
#define EP_FIFO_SIZE2 1024
/* ep0-control, ep1in-bulk, ep2out-bulk, ep3in-int */
#define DWC2_MAX_ENDPOINTS 4
#define DWC2_MAX_HW_ENDPOINTS 16
#define WAIT_FOR_SETUP 0
#define DATA_STATE_XMIT 1

View File

@ -60,22 +60,26 @@ struct dwc2_usbotg_reg {
u32 grxstsp; /* Receive Status Debug Pop/Status Pop */
u32 grxfsiz; /* Receive FIFO Size */
u32 gnptxfsiz; /* Non-Periodic Transmit FIFO Size */
u8 res1[216];
u8 res0[12];
u32 ggpio; /* 0x038 */
u8 res1[20];
u32 ghwcfg4; /* User HW Config4 */
u8 res2[176];
u32 dieptxf[15]; /* Device Periodic Transmit FIFO size register */
u8 res2[1728];
u8 res3[1728];
/* Device Configuration */
u32 dcfg; /* Device Configuration Register */
u32 dctl; /* Device Control */
u32 dsts; /* Device Status */
u8 res3[4];
u8 res4[4];
u32 diepmsk; /* Device IN Endpoint Common Interrupt Mask */
u32 doepmsk; /* Device OUT Endpoint Common Interrupt Mask */
u32 daint; /* Device All Endpoints Interrupt */
u32 daintmsk; /* Device All Endpoints Interrupt Mask */
u8 res4[224];
u8 res5[224];
struct dwc2_dev_in_endp in_endp[16];
struct dwc2_dev_out_endp out_endp[16];
u8 res5[768];
u8 res6[768];
struct ep_fifo ep[16];
};
@ -83,8 +87,15 @@ struct dwc2_usbotg_reg {
/*definitions related to CSR setting */
/* DWC2_UDC_OTG_GOTGCTL */
#define B_SESSION_VALID (0x1<<19)
#define A_SESSION_VALID (0x1<<18)
#define B_SESSION_VALID BIT(19)
#define A_SESSION_VALID BIT(18)
#define B_VALOVAL BIT(7)
#define B_VALOEN BIT(6)
#define A_VALOVAL BIT(5)
#define A_VALOEN BIT(4)
/* DWC2_UDC_OTG_GOTINT */
#define GOTGINT_SES_END_DET (1<<2)
/* DWC2_UDC_OTG_GAHBCFG */
#define PTXFE_HALF (0<<8)
@ -118,6 +129,7 @@ struct dwc2_usbotg_reg {
#define INT_NP_TX_FIFO_EMPTY (0x1<<5)
#define INT_RX_FIFO_NOT_EMPTY (0x1<<4)
#define INT_SOF (0x1<<3)
#define INT_OTG (0x1<<2)
#define INT_DEV_MODE (0x0<<0)
#define INT_HOST_MODE (0x1<<1)
#define INT_GOUTNakEff (0x01<<7)
@ -246,7 +258,7 @@ struct dwc2_usbotg_reg {
/* Masks definitions */
#define GINTMSK_INIT (INT_OUT_EP | INT_IN_EP | INT_RESUME | INT_ENUMDONE\
| INT_RESET | INT_SUSPEND)
| INT_RESET | INT_SUSPEND | INT_OTG)
#define DOEPMSK_INIT (CTRL_OUT_EP_SETUP_PHASE_DONE | AHB_ERROR|TRANSFER_DONE)
#define DIEPMSK_INIT (NON_ISO_IN_EP_TIMEOUT|AHB_ERROR|TRANSFER_DONE)
#define GAHBCFG_INIT (PTXFE_HALF | NPTXFE_HALF | MODE_DMA | BURST_INCR4\
@ -269,4 +281,13 @@ struct dwc2_usbotg_reg {
/* Device ALL Endpoints Interrupt Register (DAINT) */
#define DAINT_IN_EP_INT(x) (x << 0)
#define DAINT_OUT_EP_INT(x) (x << 16)
/* User HW Config4 */
#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26)
#define GHWCFG4_NUM_IN_EPS_SHIFT 26
/* OTG general core configuration register (OTG_GCCFG:0x38) for STM32MP1 */
#define GGPIO_STM32_OTG_GCCFG_VBDEN BIT(21)
#define GGPIO_STM32_OTG_GCCFG_IDEN BIT(22)
#endif

View File

@ -467,7 +467,7 @@ static void process_ep_out_intr(struct dwc2_udc *dev)
static int dwc2_udc_irq(int irq, void *_dev)
{
struct dwc2_udc *dev = _dev;
u32 intr_status;
u32 intr_status, gotgint;
u32 usb_status, gintmsk;
unsigned long flags = 0;
@ -521,14 +521,24 @@ static int dwc2_udc_irq(int irq, void *_dev)
&& dev->driver) {
if (dev->driver->suspend)
dev->driver->suspend(&dev->gadget);
}
}
/* HACK to let gadget detect disconnected state */
if (intr_status & INT_OTG) {
gotgint = readl(&reg->gotgint);
debug_cond(DEBUG_ISR,
"\tOTG interrupt: (GOTGINT):0x%x\n", gotgint);
if (gotgint & GOTGINT_SES_END_DET) {
debug_cond(DEBUG_ISR, "\t\tSession End Detected\n");
/* Let gadget detect disconnected state */
if (dev->driver->disconnect) {
spin_unlock_irqrestore(&dev->lock, flags);
dev->driver->disconnect(&dev->gadget);
spin_lock_irqsave(&dev->lock, flags);
}
}
writel(gotgint, &reg->gotgint);
}
if (intr_status & INT_RESUME) {

View File

@ -21,6 +21,7 @@ config USB_MUSB_GADGET
config USB_MUSB_TI
bool "Enable TI OTG USB controller"
depends on DM_USB
select USB_MUSB_DSPS
default n
help
Say y here to enable support for the dual role high
@ -54,6 +55,15 @@ config USB_MUSB_SUNXI
Say y here to enable support for the sunxi OTG / DRC USB controller
used on almost all sunxi boards.
config USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
bool "Disable MUSB bulk split/combine"
default y
help
On TI AM335x devices, MUSB has bulk split/combine feature enabled
in the ConfigData register, but the current MUSB driver does not
support it yet. Select this option to disable the feature until the
driver adds the support.
endif
config USB_MUSB_PIO_ONLY

View File

@ -240,7 +240,6 @@
* add mass storage support and for gadget we add both RNDIS ethernet
* and DFU.
*/
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
#define CONFIG_AM335X_USB1

View File

@ -251,7 +251,6 @@
* add mass storage support and for gadget we add both RNDIS ethernet
* and DFU.
*/
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_HOST
#define CONFIG_AM335X_USB1

View File

@ -387,7 +387,6 @@ DEFAULT_LINUX_BOOT_ENV \
* add mass storage support and for gadget we add both RNDIS ethernet
* and DFU.
*/
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
#define CONFIG_AM335X_USB1

View File

@ -182,9 +182,6 @@ NANDTGTS \
#define CONFIG_NAND_OMAP_GPMC_WSCFG 1
#endif /* CONFIG_NAND */
/* USB configuration */
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#if defined(CONFIG_SPI)
/* SPI Flash */
#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x40000

View File

@ -68,9 +68,6 @@ BUR_COMMON_ENV \
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
/* USB configuration */
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
/* Environment */
#define CONFIG_SYS_MMC_ENV_DEV 1
#define CONFIG_SYS_MMC_ENV_PART 2

View File

@ -148,7 +148,6 @@
/* USB configuration */
#define CONFIG_ARCH_MISC_INIT
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB1
#define CONFIG_AM335X_USB1_MODE MUSB_HOST

View File

@ -157,7 +157,6 @@
* board schematic and physical port wired to each. Then for host we
* add mass storage support.
*/
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
#define CONFIG_AM335X_USB1

View File

@ -150,8 +150,6 @@
/*
* USB configuration
*/
#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_AM335X_USB0
#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL
#define CONFIG_AM335X_USB1

View File

@ -9,6 +9,7 @@
#define __DWC2_USB_GADGET
#define PHY0_SLEEP (1 << 5)
#define DWC2_MAX_HW_ENDPOINTS 16
struct dwc2_plat_otg_data {
void *priv;
@ -22,8 +23,14 @@ struct dwc2_plat_otg_data {
unsigned int rx_fifo_sz;
unsigned int np_tx_fifo_sz;
unsigned int tx_fifo_sz;
unsigned int tx_fifo_sz_array[DWC2_MAX_HW_ENDPOINTS];
unsigned char tx_fifo_sz_nb;
bool force_b_session_valid;
bool activate_stm_id_vb_detection;
};
int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata);
int dwc2_udc_B_session_valid(struct udevice *dev);
#endif /* __DWC2_USB_GADGET */

View File

@ -4537,7 +4537,6 @@ CONFIG_USB_GADGET_SUPERH
CONFIG_USB_INVENTRA_DMA
CONFIG_USB_ISP1301_I2C_ADDR
CONFIG_USB_MAX_CONTROLLER_COUNT
CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT
CONFIG_USB_MUSB_TIMEOUT
CONFIG_USB_MUSB_TUSB6010
CONFIG_USB_OHCI_EP93XX