mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 01:10:04 +00:00
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: John Youn <johnyoun@synopsys.com> Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com> Signed-off-by: Gregory Herrero <gregory.herrero@intel.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
75f5c434c3
commit
fbb9e22b15
6 changed files with 84 additions and 3 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -59,6 +59,7 @@ static const struct dwc2_core_params params_bcm2835 = {
|
|||
.otg_ver = 0, /* 1.3 */
|
||||
.dma_enable = 1,
|
||||
.dma_desc_enable = 0,
|
||||
.dma_desc_fs_enable = 0,
|
||||
.speed = 0, /* High Speed */
|
||||
.enable_dynamic_fifo = 1,
|
||||
.en_multiple_tx_fifo = 1,
|
||||
|
@ -89,6 +90,7 @@ static const struct dwc2_core_params params_rk3066 = {
|
|||
.otg_ver = -1,
|
||||
.dma_enable = -1,
|
||||
.dma_desc_enable = 0,
|
||||
.dma_desc_fs_enable = 0,
|
||||
.speed = -1,
|
||||
.enable_dynamic_fifo = 1,
|
||||
.en_multiple_tx_fifo = -1,
|
||||
|
@ -348,8 +350,10 @@ static int dwc2_driver_probe(struct platform_device *dev)
|
|||
/*
|
||||
* Disable descriptor dma mode by default as the HW can support
|
||||
* it, but does not support it for SPLIT transactions.
|
||||
* Disable it for FS devices as well.
|
||||
*/
|
||||
defparams.dma_desc_enable = 0;
|
||||
defparams.dma_desc_fs_enable = 0;
|
||||
}
|
||||
|
||||
hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL);
|
||||
|
|
Loading…
Reference in a new issue