// SPDX-License-Identifier: GPL-2.0+ /* * dwc3-st.c Support for dwc3 platform devices on ST Microelectronics platforms * * This is a small driver for the dwc3 to provide the glue logic * to configure the controller. Tested on STi platforms. * * Copyright (C) 2014 Stmicroelectronics * * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> * Contributors: Aymen Bouattay <aymen.bouattay@st.com> * Peter Griffin <peter.griffin@linaro.org> * * Inspired by dwc3-omap.c and dwc3-exynos.c.
*/
/* glue registers */ #define CLKRST_CTRL 0x00 #define AUX_CLK_EN BIT(0) #define SW_PIPEW_RESET_N BIT(4) #define EXT_CFG_RESET_N BIT(8) /* * 1'b0 : The host controller complies with the xHCI revision 0.96 * 1'b1 : The host controller complies with the xHCI revision 1.0
*/ #define XHCI_REVISION BIT(12)
#define USB2_VBUS_MNGMNT_SEL1 0x2C /* * For all fields in USB2_VBUS_MNGMNT_SEL1 * 2’b00 : Override value from Reg 0x30 is selected * 2’b01 : utmiotg_<signal_name> from usb3_top is selected * 2’b10 : pipew_<signal_name> from PIPEW instance is selected * 2’b11 : value is 1'b0
*/ #define USB2_VBUS_REG30 0x0 #define USB2_VBUS_UTMIOTG 0x1 #define USB2_VBUS_PIPEW 0x2 #define USB2_VBUS_ZERO 0x3
/** * st_dwc3_drd_init: program the port * @dwc3_data: driver private structure * Description: this function is to program the port as either host or device * according to the static configuration passed from devicetree. * OTG and dual role are not yet supported!
*/ staticint st_dwc3_drd_init(struct st_dwc3 *dwc3_data)
{
u32 val; int err;
err = regmap_read(dwc3_data->regmap, dwc3_data->syscfg_reg_off, &val); if (err) return err;
val &= USB3_CONTROL_MASK;
switch (dwc3_data->dr_mode) { case USB_DR_MODE_PERIPHERAL:
/* * USB3_DELAY_VBUSVALID is ANDed with USB_C_VBUSVALID. Thus, * when set to ‘0‘, it can delay the arrival of VBUSVALID * information to VBUSVLDEXT2 input of the pico PHY. * We don't want to do that so we set the bit to '1'.
*/
struct device_node *child __free(device_node) = of_get_compatible_child(node, "snps,dwc3"); if (!child) {
dev_err(dev, "failed to find dwc3 core node\n"); return -ENODEV;
}
dwc3_data->rstc_pwrdn =
devm_reset_control_get_exclusive(dev, "powerdown"); if (IS_ERR(dwc3_data->rstc_pwrdn)) return dev_err_probe(dev, PTR_ERR(dwc3_data->rstc_pwrdn), "could not get power controller\n");
dwc3_data->rstc_rst =
devm_reset_control_get_shared(dev, "softreset"); if (IS_ERR(dwc3_data->rstc_rst)) {
ret = dev_err_probe(dev, PTR_ERR(dwc3_data->rstc_rst), "could not get reset controller\n"); goto undo_powerdown;
}
/* Allocate and initialize the core */
ret = of_platform_populate(node, NULL, NULL, dev); if (ret) {
dev_err(dev, "failed to add dwc3 core\n"); goto undo_softreset;
}
child_pdev = of_find_device_by_node(child); if (!child_pdev) {
dev_err(dev, "failed to find dwc3 core device\n");
ret = -ENODEV; goto depopulate;
}
/* * Configure the USB port as device or host according to the static * configuration passed from DT. * DRD is the only mode currently supported so this will be enhanced * as soon as OTG is available.
*/
ret = st_dwc3_drd_init(dwc3_data); if (ret) {
dev_err(dev, "drd initialisation failed\n"); goto depopulate;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.