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

Commit fbb9e22b authored by Mian Yousaf Kaukab's avatar Mian Yousaf Kaukab Committed by Felipe Balbi
Browse files

usb: dwc2: host: enable descriptor dma for fs devices



As descriptor dma mode does not support split transfers, it can't be
enabled for high speed devices. Add a core parameter to enable it for
full speed devices.

Ensure frame list and descriptor list are correctly freed during
disconnect.

Acked-by: default avatarJohn Youn <johnyoun@synopsys.com>
Signed-off-by: default avatarMian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: default avatarGregory Herrero <gregory.herrero@intel.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 75f5c434
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -2485,6 +2485,29 @@ void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val)
	hsotg->core_params->dma_desc_enable = val;
}

void dwc2_set_param_dma_desc_fs_enable(struct dwc2_hsotg *hsotg, int val)
{
	int valid = 1;

	if (val > 0 && (hsotg->core_params->dma_enable <= 0 ||
			!hsotg->hw_params.dma_desc_enable))
		valid = 0;
	if (val < 0)
		valid = 0;

	if (!valid) {
		if (val >= 0)
			dev_err(hsotg->dev,
				"%d invalid for dma_desc_fs_enable parameter. Check HW configuration.\n",
				val);
		val = (hsotg->core_params->dma_enable > 0 &&
			hsotg->hw_params.dma_desc_enable);
	}

	hsotg->core_params->dma_desc_fs_enable = val;
	dev_dbg(hsotg->dev, "Setting dma_desc_fs_enable to %d\n", val);
}

void dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
						 int val)
{
@@ -3016,6 +3039,7 @@ void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
	dwc2_set_param_otg_cap(hsotg, params->otg_cap);
	dwc2_set_param_dma_enable(hsotg, params->dma_enable);
	dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable);
	dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable);
	dwc2_set_param_host_support_fs_ls_low_power(hsotg,
			params->host_support_fs_ls_low_power);
	dwc2_set_param_enable_dynamic_fifo(hsotg,
+20 −0
Original line number Diff line number Diff line
@@ -246,6 +246,13 @@ enum dwc2_ep0_state {
 *                      value for this if none is specified.
 *                       0 - Address DMA
 *                       1 - Descriptor DMA (default, if available)
 * @dma_desc_fs_enable: When DMA mode is enabled, specifies whether to use
 *                      address DMA mode or descriptor DMA mode for accessing
 *                      the data FIFOs in Full Speed mode only. The driver
 *                      will automatically detect the value for this if none is
 *                      specified.
 *                       0 - Address DMA
 *                       1 - Descriptor DMA in FS (default, if available)
 * @speed:              Specifies the maximum speed of operation in host and
 *                      device mode. The actual speed depends on the speed of
 *                      the attached device and the value of phy_type.
@@ -375,6 +382,7 @@ struct dwc2_core_params {
	int otg_ver;
	int dma_enable;
	int dma_desc_enable;
	int dma_desc_fs_enable;
	int speed;
	int enable_dynamic_fifo;
	int en_multiple_tx_fifo;
@@ -456,6 +464,7 @@ struct dwc2_hw_params {
	unsigned op_mode:3;
	unsigned arch:2;
	unsigned dma_desc_enable:1;
	unsigned dma_desc_fs_enable:1;
	unsigned enable_dynamic_fifo:1;
	unsigned en_multiple_tx_fifo:1;
	unsigned host_rx_fifo_size:16;
@@ -770,6 +779,7 @@ struct dwc2_hsotg {
	u16 frame_number;
	u16 periodic_qh_count;
	bool bus_suspended;
	bool new_connection;

#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
#define FRAME_NUM_ARRAY_SIZE 1000
@@ -941,6 +951,16 @@ extern void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val);
 */
extern void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val);

/*
 * When DMA mode is enabled specifies whether to use
 * address DMA or DMA Descritor mode with full speed devices
 * for accessing the data FIFOs in host mode.
 * 0 - address DMA
 * 1 - FS DMA Descriptor(default, if available)
 */
extern void dwc2_set_param_dma_desc_fs_enable(struct dwc2_hsotg *hsotg,
					      int val);

/*
 * Specifies the maximum speed of operation in host and device mode.
 * The actual speed depends on the speed of the attached device and
+22 −0
Original line number Diff line number Diff line
@@ -1734,6 +1734,28 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
			port_status |= USB_PORT_STAT_TEST;
		/* USB_PORT_FEAT_INDICATOR unsupported always 0 */

		if (hsotg->core_params->dma_desc_fs_enable) {
			/*
			 * Enable descriptor DMA only if a full speed
			 * device is connected.
			 */
			if (hsotg->new_connection &&
			    ((port_status &
			      (USB_PORT_STAT_CONNECTION |
			       USB_PORT_STAT_HIGH_SPEED |
			       USB_PORT_STAT_LOW_SPEED)) ==
			       USB_PORT_STAT_CONNECTION)) {
				u32 hcfg;

				dev_info(hsotg->dev, "Enabling descriptor DMA mode\n");
				hsotg->core_params->dma_desc_enable = 1;
				hcfg = dwc2_readl(hsotg->regs + HCFG);
				hcfg |= HCFG_DESCDMA;
				dwc2_writel(hcfg, hsotg->regs + HCFG);
				hsotg->new_connection = false;
			}
		}

		dev_vdbg(hsotg->dev, "port_status=%08x\n", port_status);
		*(__le32 *)buf = cpu_to_le32(port_status);
		break;
+13 −2
Original line number Diff line number Diff line
@@ -372,10 +372,21 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
			 "  --Port Interrupt HPRT0=0x%08x Port Enable Changed (now %d)--\n",
			 hprt0, !!(hprt0 & HPRT0_ENA));
		hprt0_modify |= HPRT0_ENACHG;
		if (hprt0 & HPRT0_ENA)
		if (hprt0 & HPRT0_ENA) {
			hsotg->new_connection = true;
			dwc2_hprt0_enable(hsotg, hprt0, &hprt0_modify);
		else
		} else {
			hsotg->flags.b.port_enable_change = 1;
			if (hsotg->core_params->dma_desc_fs_enable) {
				u32 hcfg;

				hsotg->core_params->dma_desc_enable = 0;
				hsotg->new_connection = false;
				hcfg = dwc2_readl(hsotg->regs + HCFG);
				hcfg &= ~HCFG_DESCDMA;
				dwc2_writel(hcfg, hsotg->regs + HCFG);
			}
		}
	}

	/* Overcurrent Change Interrupt */
+1 −1
Original line number Diff line number Diff line
@@ -232,7 +232,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
 */
void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
{
	if (hsotg->core_params->dma_desc_enable > 0) {
	if (qh->desc_list) {
		dwc2_hcd_qh_free_ddma(hsotg, qh);
	} else {
		/* kfree(NULL) is safe */
Loading