Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8db3c5c authored by Dov Levenglick's avatar Dov Levenglick Committed by Matt Wagantall
Browse files

usb: dwc: allow pre-configuration of DCTL[HIRD_Thresh]



Allows the user to set a value for DCTL[HIRD_Thresh] (which controls
the UTMI sleep mechanism vs. the PHY) in the DT.
This goes towards two benefits:
1. Fixes a long-standing TODO in dwc3/gadget.c (originally
introduced in 1a947746)
2. Allows compliance to the HPG for Link Power Management

Change-Id: Id6aab40836de29994d1dcb6344efa5fae56724d1
Signed-off-by: default avatarDov Levenglick <dovl@codeaurora.org>
parent c342ad67
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ Optional properties:
 - snps,nominal-elastic-buffer: When set, the nominal elastic buffer setting
	is used. By default, the half-full setting is used.
 - snps,usb3-u1u2-disable: If present, disable u1u2 low power modes for DWC3 core controller in SS mode.
 - snps,hird_thresh: If present, will determine the value of DCTL[HIRD_Thresh] which, in turn,
	controls the UTMI sleep mechanism vs. the PHY. Default value is 12.
 - snps,bus-suspend-enable: If present then controller supports low power mode
	during bus suspend.

+9 −0
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@

#include "debug.h"

#define DWC3_DCTL_HIRD_THRES_DEFAULT	12

/* -------------------------------------------------------------------------- */

void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
@@ -780,6 +782,8 @@ static int dwc3_probe(struct platform_device *pdev)
	void __iomem		*regs;
	void			*mem;

	u32			hird_thresh;

	mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
	if (!mem)
		return -ENOMEM;
@@ -841,6 +845,11 @@ static int dwc3_probe(struct platform_device *pdev)
				"snps,usb3-u1u2-disable");
		dwc->enable_bus_suspend = of_property_read_bool(node,
						"snps,bus-suspend-enable");
		ret = of_property_read_u32(node, "snps,hird_thresh", &hird_thresh);
		if (!ret)
			dwc->hird_thresh = (u8) hird_thresh;
		else
			dwc->hird_thresh = DWC3_DCTL_HIRD_THRES_DEFAULT;
	} else if (pdata) {
		dwc->maximum_speed = pdata->maximum_speed;

+4 −1
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@
#define DWC3_DCTL_LSFTRST	(1 << 29)

#define DWC3_DCTL_HIRD_THRES_MASK	(0x1f << 24)
#define DWC3_DCTL_HIRD_THRES(n)	((n) << 24)
#define DWC3_DCTL_HIRD_THRES(n)	(((n) << 24) & DWC3_DCTL_HIRD_THRES_MASK)

#define DWC3_DCTL_APPL1RES	(1 << 23)

@@ -781,6 +781,8 @@ struct dwc3_scratchpad_array {
 * @three_stage_setup: set if we perform a three phase setup
 * @err_evt_seen: previous event in queue was erratic error
 * @usb3_u1u2_disable: if true, disable U1U2 low power modes in Superspeed mode.
 * @hird_thresh: value to configure in DCTL[HIRD_Thresh]
 * @in_lpm: if 1, indicates that the controller is in low power mode (no clocks)
 */
struct dwc3 {
	struct usb_ctrlrequest	*ctrl_req;
@@ -903,6 +905,7 @@ struct dwc3 {

	struct dwc3_gadget_events	dbg_gadget_events;

	u8			hird_thresh;
	atomic_t		in_lpm;
};

+1 −7
Original line number Diff line number Diff line
@@ -2572,13 +2572,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)

		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
		reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);

		/*
		 * TODO: This should be configurable. For now using
		 * maximum allowed HIRD threshold value of 0b1100
		 */
		reg |= DWC3_DCTL_HIRD_THRES(12);

		reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_thresh);
		dwc3_writel(dwc->regs, DWC3_DCTL, reg);
	} else {
		reg = dwc3_readl(dwc->regs, DWC3_DCTL);