drivers/usb/dwc3/dwc3-st.c

Source file repositories/reference/linux-study-clean/drivers/usb/dwc3/dwc3-st.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/dwc3/dwc3-st.c
Extension
.c
Size
9949 bytes
Lines
370
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct st_dwc3 {
	struct device *dev;
	void __iomem *glue_base;
	struct regmap *regmap;
	int syscfg_reg_off;
	enum usb_dr_mode dr_mode;
	struct reset_control *rstc_pwrdn;
	struct reset_control *rstc_rst;
};

static inline u32 st_dwc3_readl(void __iomem *base, u32 offset)
{
	return readl_relaxed(base + offset);
}

static inline void st_dwc3_writel(void __iomem *base, u32 offset, u32 value)
{
	writel_relaxed(value, base + offset);
}

/**
 * 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!
 */
static int 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:

		val &= ~(USB3_DELAY_VBUSVALID
			| USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3)
			| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
			| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);

		/*
		 * USB3_PORT2_FORCE_VBUSVALID When '1' and when
		 * USB3_PORT2_DEVICE_NOT_HOST = 1, forces VBUSVLDEXT2 input
		 * of the pico PHY to 1.
		 */

		val |= USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID;
		break;

	case USB_DR_MODE_HOST:

		val &= ~(USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID
			| USB3_SEL_FORCE_OPMODE	| USB3_FORCE_OPMODE(0x3)
			| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
			| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);

		/*
		 * 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'.
		 */

		val |= USB3_DELAY_VBUSVALID;
		break;

	default:
		dev_err(dwc3_data->dev, "Unsupported mode of operation %d\n",
			dwc3_data->dr_mode);
		return -EINVAL;
	}

	return regmap_write(dwc3_data->regmap, dwc3_data->syscfg_reg_off, val);
}

/**
 * st_dwc3_init: init the controller via glue logic
 * @dwc3_data: driver private structure
 */
static void st_dwc3_init(struct st_dwc3 *dwc3_data)
{
	u32 reg = st_dwc3_readl(dwc3_data->glue_base, CLKRST_CTRL);

	reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION;

Annotation

Implementation Notes