public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Bin Meng <bmeng.cn@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 03/20] usb: xhci: Initialize scratchpad buffer array and scratchpad buffers
Date: Fri, 16 Jun 2017 06:31:32 -0700	[thread overview]
Message-ID: <1497619909-29454-4-git-send-email-bmeng.cn@gmail.com> (raw)
In-Reply-To: <1497619909-29454-1-git-send-email-bmeng.cn@gmail.com>

The scratchpad buffer array is used to define the locations of
statically allocated memory pages that are available for the
private use of the xHC. The xHCI spec explicitly mentions that
system software shall allocate the scratchpad buffers before
placing the xHC in to Run mode (Run/Stop (R/S) = ‘1’), however
U-Boot is missing this part.

This causes xHC on Intel platform does not respond the very first
'enable slot' command that is given to xHC and the 'enable slot'
command completion event TRB is never generated and xHC seems to
hang forever.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 drivers/usb/host/xhci-mem.c | 87 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/xhci.h     | 10 ++++--
 2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 62db51d..12e277a 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -96,6 +96,25 @@ static void xhci_ring_free(struct xhci_ring *ring)
 }
 
 /**
+ * Free the scratchpad buffer array and scratchpad buffers
+ *
+ * @ctrl	host controller data structure
+ * @return	none
+ */
+static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
+{
+	if (!ctrl->scratchpad)
+		return;
+
+	ctrl->dcbaa->dev_context_ptrs[0] = 0;
+
+	free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]);
+	free(ctrl->scratchpad->sp_array);
+	free(ctrl->scratchpad);
+	ctrl->scratchpad = NULL;
+}
+
+/**
  * frees the "xhci_container_ctx" pointer passed
  *
  * @param ptr	pointer to "xhci_container_ctx" to be freed
@@ -155,6 +174,7 @@ void xhci_cleanup(struct xhci_ctrl *ctrl)
 {
 	xhci_ring_free(ctrl->event_ring);
 	xhci_ring_free(ctrl->cmd_ring);
+	xhci_scratchpad_free(ctrl);
 	xhci_free_virt_devices(ctrl);
 	free(ctrl->erst.entries);
 	free(ctrl->dcbaa);
@@ -320,6 +340,70 @@ struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs)
 }
 
 /**
+ * Set up the scratchpad buffer array and scratchpad buffers
+ *
+ * @ctrl	host controller data structure
+ * @return	-ENOMEM if buffer allocation fails, 0 on success
+ */
+static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
+{
+	struct xhci_hccr *hccr = ctrl->hccr;
+	struct xhci_hcor *hcor = ctrl->hcor;
+	struct xhci_scratchpad *scratchpad;
+	int num_sp;
+	uint32_t page_size;
+	void *buf;
+	int i;
+
+	num_sp = HCS_MAX_SCRATCHPAD(xhci_readl(&hccr->cr_hcsparams2));
+	if (!num_sp)
+		return 0;
+
+	scratchpad = malloc(sizeof(*scratchpad));
+	if (!scratchpad)
+		goto fail_sp;
+	ctrl->scratchpad = scratchpad;
+
+	scratchpad->sp_array = xhci_malloc(num_sp * sizeof(u64));
+	if (!scratchpad->sp_array)
+		goto fail_sp2;
+	ctrl->dcbaa->dev_context_ptrs[0] =
+		cpu_to_le64((uintptr_t)scratchpad->sp_array);
+
+	page_size = xhci_readl(&hcor->or_pagesize) & 0xffff;
+	for (i = 0; i < 16; i++) {
+		if ((0x1 & page_size) != 0)
+			break;
+		page_size = page_size >> 1;
+	}
+	BUG_ON(i == 16);
+
+	page_size = 1 << (i + 12);
+	buf = memalign(page_size, num_sp * page_size);
+	if (!buf)
+		goto fail_sp3;
+	memset(buf, '\0', num_sp * page_size);
+	xhci_flush_cache((uintptr_t)buf, num_sp * page_size);
+
+	for (i = 0; i < num_sp; i++) {
+		uintptr_t ptr = (uintptr_t)buf + i * page_size;
+		scratchpad->sp_array[i] = cpu_to_le64(ptr);
+	}
+
+	return 0;
+
+fail_sp3:
+	free(scratchpad->sp_array);
+
+fail_sp2:
+	free(scratchpad);
+	ctrl->scratchpad = NULL;
+
+fail_sp:
+	return -ENOMEM;
+}
+
+/**
  * Allocates the Container context
  *
  * @param ctrl	Host controller data structure
@@ -499,6 +583,9 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
 
 	xhci_writeq(&ctrl->ir_set->erst_base, val_64);
 
+	/* set up the scratchpad buffer array and scratchpad buffers */
+	xhci_scratchpad_alloc(ctrl);
+
 	/* initializing the virtual devices to NULL */
 	for (i = 0; i < MAX_HC_SLOTS; ++i)
 		ctrl->devs[i] = NULL;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 431afd8..32dd611 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -111,9 +111,10 @@ struct xhci_hccr {
 #define HCS_IST(p)		(((p) >> 0) & 0xf)
 /* bits 4:7, max number of Event Ring segments */
 #define HCS_ERST_MAX(p)		(((p) >> 4) & 0xf)
+/* bits 21:25 Hi 5 bits of Scratchpad buffers SW must allocate for the HW */
 /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */
-/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */
-#define HCS_MAX_SCRATCHPAD(p)   (((p) >> 27) & 0x1f)
+/* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */
+#define HCS_MAX_SCRATCHPAD(p)	((((p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f))
 
 /* HCSPARAMS3 - hcs_params3 - bitmasks */
 /* bits 0:7, Max U1 to U0 latency for the roothub ports */
@@ -1037,6 +1038,10 @@ struct xhci_erst {
 	unsigned int		erst_size;
 };
 
+struct xhci_scratchpad {
+	u64 *sp_array;
+};
+
 /*
  * Each segment table entry is 4*32bits long.  1K seems like an ok size:
  * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
@@ -1224,6 +1229,7 @@ struct xhci_ctrl {
 	struct xhci_intr_reg *ir_set;
 	struct xhci_erst erst;
 	struct xhci_erst_entry entry[ERST_NUM_SEGS];
+	struct xhci_scratchpad *scratchpad;
 	struct xhci_virt_device *devs[MAX_HC_SLOTS];
 	int rootdev;
 };
-- 
2.9.2

  parent reply	other threads:[~2017-06-16 13:31 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-16 13:31 [U-Boot] [PATCH 00/20] usb: xhci: Fix USB xHCI support on Intel platform Bin Meng
2017-06-16 13:31 ` [U-Boot] [PATCH 01/20] usb: xhci: Remove incorrect comments for struct xhci_container_ctx Bin Meng
2017-06-17  3:43   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 02/20] usb: xhci: Correct command TRB 4th dword initialization Bin Meng
2017-06-17  3:43   ` Simon Glass
2017-06-16 13:31 ` Bin Meng [this message]
2017-06-17  3:43   ` [U-Boot] [PATCH 03/20] usb: xhci: Initialize scratchpad buffer array and scratchpad buffers Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 04/20] usb: xhci: Add input slot context in xhci_set_configuration() Bin Meng
2017-06-17  3:43   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 05/20] usb: hub: Update handling connect status/change in usb_scan_port() Bin Meng
2017-06-16 14:19   ` Marek Vasut
2017-06-20 15:18     ` Dinh Nguyen
2017-06-16 13:31 ` [U-Boot] [PATCH 06/20] usb: hub: Send correct wValue to get hub descriptor of a USB 3.0 hub Bin Meng
2017-06-17  3:43   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 07/20] usb: hub: Revise wLength for 'get port status' request Bin Meng
2017-06-17  3:43   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 08/20] usb: hub: Change USB hub descriptor to match USB 3.0 hubs Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 09/20] usb: hub: Add 3.0 hub port status mask of 2.0 hub Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 10/20] usb: xhci: Change MAX_HC_PORTS to 255 Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 11/20] usb: xhci: Get rid of CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 12/20] configs: Remove CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS in all boards Bin Meng
2017-06-16 14:06   ` Bin Meng
2017-06-21 12:13     ` Stefan Roese
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 13/20] usb: ehci: Get rid of CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 14/20] configs: Remove CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS in all boards Bin Meng
2017-06-16 14:09   ` Bin Meng
2017-06-21 12:13     ` Stefan Roese
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 15/20] usb: cmd: Print actual packet size for super speed devices Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 16/20] usb: xhci: Convert CONFIG_USB_XHCI_PCI to Kconfig Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 17/20] x86: minnowmax: Configure GPIO pins to turn on USB ports VBUS Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-17 13:41     ` Bin Meng
2017-06-22  6:44     ` Bin Meng
2017-06-16 13:31 ` [U-Boot] [PATCH 18/20] x86: minnowmax: Add a environment variable for USB power-on delay Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-16 13:31 ` [U-Boot] [PATCH 19/20] x86: minnowmax: Enable USB xHCI support Bin Meng
2017-06-17  3:44   ` Simon Glass
2017-06-17 13:43     ` Bin Meng
2017-06-16 13:31 ` [U-Boot] [PATCH 20/20] x86: Remove CONFIG_USB_MAX_CONTROLLER_COUNT Bin Meng
2017-06-17  3:45   ` Simon Glass
2017-06-22  6:44     ` Bin Meng
2017-06-16 13:42 ` [U-Boot] [PATCH 00/20] usb: xhci: Fix USB xHCI support on Intel platform Bin Meng
2017-06-16 14:21 ` Marek Vasut
2017-06-16 14:29   ` Stefan Roese
2017-06-21  9:28 ` Stefan Roese
2017-06-21 10:24   ` Bin Meng
2017-06-21 12:07     ` Stefan Roese
2017-06-21 12:44       ` Bin Meng
2017-06-22  6:32         ` Bin Meng
2017-06-21 12:10 ` Stefan Roese

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1497619909-29454-4-git-send-email-bmeng.cn@gmail.com \
    --to=bmeng.cn@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox