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

Commit 2637919e authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa
Browse files

USB: dwc3-msm: Disable Update xfer for DBM on ep disable or dequeue



Enable update xfer for DBM while configuring dbm endpoint
and also clear update xfer before queueing end xfer command as
part of endpoint disable as hardware programming guide.

CRs-Fixed: 965207
Change-Id: Ib5ec650884ad06394280416ccf877c1ccce1eaaf
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
parent b6a638f8
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -150,9 +150,9 @@ static int dwc3_core_reset(struct dwc3 *dwc)
		return ret;
	}

	dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT);
	dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT, 0);

	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT);
	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT, 0);

	return 0;
}
@@ -699,22 +699,22 @@ void dwc3_post_host_reset_core_init(struct dwc3 *dwc)
{
	dwc3_core_init(dwc);
	dwc3_gadget_restart(dwc);
	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_INITIALIZATION_EVENT);
	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_INITIALIZATION_EVENT, 0);
}

static void (*notify_event) (struct dwc3 *, unsigned);
void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned))
static void (*notify_event)(struct dwc3 *, unsigned, unsigned);
void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned, unsigned))
{
	notify_event = notify;
}
EXPORT_SYMBOL(dwc3_set_notifier);

int dwc3_notify_event(struct dwc3 *dwc, unsigned event)
int dwc3_notify_event(struct dwc3 *dwc, unsigned event, unsigned value)
{
	int ret = 0;

	if (dwc->notify_event)
		dwc->notify_event(dwc, event);
		dwc->notify_event(dwc, event, value);
	else
		ret = -ENODEV;

@@ -965,7 +965,7 @@ static int dwc3_probe(struct platform_device *pdev)
			goto err_gadget_exit;
		}
	}
	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_INITIALIZATION_EVENT);
	dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_INITIALIZATION_EVENT, 0);

	return 0;

@@ -1007,7 +1007,7 @@ static int dwc3_prepare(struct device *dev)
	unsigned long	flags;

	/* Check if platform glue driver handling PM, if not then handle here */
	if(!dwc3_notify_event(dwc, DWC3_CORE_PM_PREPARE_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_PREPARE_EVENT, 0))
		return 0;

	spin_lock_irqsave(&dwc->lock, flags);
@@ -1034,7 +1034,7 @@ static void dwc3_complete(struct device *dev)
	unsigned long	flags;

	/* Check if platform glue driver handling PM, if not then handle here */
	if(!dwc3_notify_event(dwc, DWC3_CORE_PM_COMPLETE_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_COMPLETE_EVENT, 0))
		return;

	spin_lock_irqsave(&dwc->lock, flags);
@@ -1059,7 +1059,7 @@ static int dwc3_suspend(struct device *dev)
	unsigned long	flags;

	/* Check if platform glue driver handling PM, if not then handle here */
	if(!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT, 0))
		return 0;

	spin_lock_irqsave(&dwc->lock, flags);
@@ -1093,7 +1093,7 @@ static int dwc3_resume(struct device *dev)
	int		ret;

	/* Check if platform glue driver handling PM, if not then handle here */
	if(!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
	if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0))
		return 0;

	usb_phy_init(dwc->usb3_phy);
+4 −3
Original line number Diff line number Diff line
@@ -744,6 +744,7 @@ struct dwc3_scratchpad_array {
#define DWC3_CONTROLLER_NOTIFY_OTG_EVENT		9
#define DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT		10
#define DWC3_CONTROLLER_RESTART_USB_SESSION		11
#define DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER		12

#define MAX_INTR_STATS					10
/**
@@ -926,7 +927,7 @@ struct dwc3 {
	u8			lpm_nyet_threshold;
	u8			hird_threshold;

	void (*notify_event)	(struct dwc3 *, unsigned);
	void (*notify_event)(struct dwc3 *, unsigned, unsigned);
	struct work_struct	wakeup_work;

	unsigned		delayed_status:1;
@@ -1211,7 +1212,7 @@ void dwc3_gadget_enable_irq(struct dwc3 *dwc);
void dwc3_gadget_disable_irq(struct dwc3 *dwc);

extern void dwc3_set_notifier(
		void (*notify) (struct dwc3 *dwc3, unsigned event));
extern int dwc3_notify_event(struct dwc3 *dwc3, unsigned event);
	void (*notify)(struct dwc3 *dwc3, unsigned event, unsigned value));
extern int dwc3_notify_event(struct dwc3 *dwc3, unsigned event, unsigned value);

#endif /* __DRIVERS_USB_DWC3_CORE_H */
+37 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -37,6 +37,7 @@ enum dbm_reg {
	DBM_HW_TRB2_EP,
	DBM_HW_TRB3_EP,
	DBM_PIPE_CFG,
	DBM_DISABLE_UPDXFER,
	DBM_SOFT_RESET,
	DBM_GEN_CFG,
	DBM_GEVNTADR_LSB,
@@ -103,6 +104,7 @@ static const struct dbm_reg_data dbm_1_5_regtable[] = {
	[DBM_HW_TRB2_EP]	= { 0x0240, 0x4 },
	[DBM_HW_TRB3_EP]	= { 0x0250, 0x4 },
	[DBM_PIPE_CFG]		= { 0x0274, 0x0 },
	[DBM_DISABLE_UPDXFER]	= { 0x0298, 0x0 },
	[DBM_SOFT_RESET]	= { 0x020C, 0x0 },
	[DBM_GEN_CFG]		= { 0x0210, 0x0 },
	[DBM_GEVNTADR_LSB]	= { 0x0260, 0x0 },
@@ -291,6 +293,7 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,
{
	int dbm_ep;
	u32 ep_cfg;
	u32 data;

	if (!dbm) {
		pr_err("%s: dbm pointer is NULL!\n", __func__);
@@ -337,6 +340,10 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,

	msm_dbm_write_ep_reg_field(dbm, DBM_EP_CFG, dbm_ep, DBM_EN_EP, 1);

	data = msm_dbm_read_reg(dbm, DBM_DISABLE_UPDXFER);
	data &= ~(0x1 << dbm_ep);
	msm_dbm_write_reg(dbm, DBM_DISABLE_UPDXFER, data);

	return dbm_ep;
}

@@ -449,6 +456,35 @@ int dbm_event_buffer_config(struct dbm *dbm, u32 addr_lo, u32 addr_hi, int size)
	return 0;
}

/**
 * Disable update xfer before queueing stop xfer command to USB3 core.
 *
 * @usb_ep - USB physical EP number.
 *
 */
int dwc3_dbm_disable_update_xfer(struct dbm *dbm, u8 usb_ep)
{
	u32 data;
	u8 dbm_ep;

	if (!dbm) {
		pr_err("%s: dbm pointer is NULL!\n", __func__);
		return -EPERM;
	}

	dbm_ep = find_matching_dbm_ep(dbm, usb_ep);

	if (dbm_ep < 0) {
		pr_err("usb ep index %d has no corresponding dbm ep\n", usb_ep);
		return -ENODEV;
	}

	data = msm_dbm_read_reg(dbm, DBM_DISABLE_UPDXFER);
	data |= (0x1 << dbm_ep);
	msm_dbm_write_reg(dbm, DBM_DISABLE_UPDXFER, data);

	return 0;
}

int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, phys_addr_t addr,
				u32 size, u8 dst_pipe_idx)
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -63,6 +63,7 @@ int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep);
int dbm_get_num_of_eps_configured(struct dbm *dbm);
int dbm_event_buffer_config(struct dbm *dbm, u32 addr_lo, u32 addr_hi,
				int size);
int dwc3_dbm_disable_update_xfer(struct dbm *dbm, u8 usb_ep);
int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, phys_addr_t addr,
				u32 size, u8 dst_pipe_idx);
void dbm_set_speed(struct dbm *dbm, bool speed);
+17 −2
Original line number Diff line number Diff line
@@ -391,6 +391,16 @@ static inline bool dwc3_msm_is_superspeed(struct dwc3_msm *mdwc)
	return dwc3_msm_is_dev_superspeed(mdwc);
}

int dwc3_msm_dbm_disable_updxfer(struct dwc3 *dwc, u8 usb_ep)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);

	dev_dbg(mdwc->dev, "%s\n", __func__);
	dwc3_dbm_disable_update_xfer(mdwc->dbm, usb_ep);

	return 0;
}

/**
 * Configure the DBM with the BAM's data fifo.
 * This function is called by the USB BAM Driver
@@ -1608,7 +1618,8 @@ static void dwc3_msm_qscratch_reg_init(struct dwc3_msm *mdwc)

}

static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned event)
static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned event,
							unsigned value)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
	u32 reg;
@@ -1700,6 +1711,9 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned event)
		dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESTART_USB_SESSION received\n");
		dwc3_restart_usb_work(&mdwc->restart_usb_work);
		break;
	case DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER:
		dwc3_msm_dbm_disable_updxfer(dwc, value);
		break;
	default:
		dev_dbg(mdwc->dev, "unknown dwc3 event\n");
		break;
@@ -1770,7 +1784,8 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc)
	dwc3_core_init(dwc);
	/* Re-configure event buffers */
	dwc3_event_buffers_setup(dwc);
	dwc3_msm_notify_event(dwc, DWC3_CONTROLLER_POST_INITIALIZATION_EVENT);
	dwc3_msm_notify_event(dwc,
				DWC3_CONTROLLER_POST_INITIALIZATION_EVENT, 0);
}

static int dwc3_msm_prepare_suspend(struct dwc3_msm *mdwc)
Loading