mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Jules Maselbas <jmaselbas@kalray.eu>
To: Barebox List <barebox@lists.infradead.org>
Cc: Jules Maselbas <jmaselbas@kalray.eu>
Subject: [PATCH v3 03/14] usb: dwc2: host: Read dr_mode from device tree
Date: Tue, 21 Jul 2020 14:05:49 +0200	[thread overview]
Message-ID: <20200721120600.15114-4-jmaselbas@kalray.eu> (raw)
In-Reply-To: <20200721120600.15114-1-jmaselbas@kalray.eu>

Signed-off-by: Jules Maselbas <jmaselbas@kalray.eu>
---
 drivers/usb/dwc2/core.c | 95 +++++++++++++++++++++++++++++++++++++++++
 drivers/usb/dwc2/dwc2.c |  2 +
 drivers/usb/dwc2/dwc2.h |  1 +
 3 files changed, 98 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 0046e955f..6e8d30c22 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -1,6 +1,33 @@
 // SPDX-License-Identifier: GPL-2.0+
 #include "dwc2.h"
 
+/* Returns the controller's GHWCFG2.OTG_MODE. */
+static unsigned int dwc2_op_mode(struct dwc2 *dwc2)
+{
+	u32 ghwcfg2 = dwc2_readl(dwc2, GHWCFG2);
+
+	return (ghwcfg2 & GHWCFG2_OP_MODE_MASK) >>
+		GHWCFG2_OP_MODE_SHIFT;
+}
+
+/* Returns true if the controller is host-only. */
+static bool dwc2_hw_is_host(struct dwc2 *dwc2)
+{
+	unsigned int op_mode = dwc2_op_mode(dwc2);
+
+	return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_HOST) ||
+		(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST);
+}
+
+/* Returns true if the controller is device-only. */
+static bool dwc2_hw_is_device(struct dwc2 *dwc2)
+{
+	unsigned int op_mode = dwc2_op_mode(dwc2);
+
+	return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
+		(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE);
+}
+
 void dwc2_set_param_otg_cap(struct dwc2 *dwc2)
 {
 	u8 val;
@@ -493,6 +520,74 @@ void dwc2_gusbcfg_init(struct dwc2 *dwc2)
 	dwc2_writel(dwc2, usbcfg, GUSBCFG);
 }
 
+/*
+ * Check the dr_mode against the module configuration and hardware
+ * capabilities.
+ *
+ * The hardware, module, and dr_mode, can each be set to host, device,
+ * or otg. Check that all these values are compatible and adjust the
+ * value of dr_mode if possible.
+ *
+ *                      actual
+ *    HW  MOD dr_mode   dr_mode
+ *  ------------------------------
+ *   HST  HST  any    :  HST
+ *   HST  DEV  any    :  ---
+ *   HST  OTG  any    :  HST
+ *
+ *   DEV  HST  any    :  ---
+ *   DEV  DEV  any    :  DEV
+ *   DEV  OTG  any    :  DEV
+ *
+ *   OTG  HST  any    :  HST
+ *   OTG  DEV  any    :  DEV
+ *   OTG  OTG  any    :  dr_mode
+ */
+int dwc2_get_dr_mode(struct dwc2 *dwc2)
+{
+	enum usb_dr_mode mode;
+
+	mode = of_usb_get_dr_mode(dwc2->dev->device_node, NULL);
+	dwc2->dr_mode = mode;
+
+	if (dwc2_hw_is_device(dwc2)) {
+		dwc2_dbg(dwc2, "Controller is device only\n");
+		if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) {
+			dwc2_err(dwc2,
+				"Controller does not support host mode.\n");
+			return -EINVAL;
+		}
+		mode = USB_DR_MODE_PERIPHERAL;
+	} else if (dwc2_hw_is_host(dwc2)) {
+		dwc2_dbg(dwc2, "Controller is host only\n");
+		if (IS_ENABLED(CONFIG_USB_DWC2_GADGET)) {
+			dwc2_err(dwc2,
+				"Controller does not support device mode.\n");
+			return -EINVAL;
+		}
+		mode = USB_DR_MODE_HOST;
+	} else {
+		dwc2_dbg(dwc2, "Controller is otg\n");
+		if (IS_ENABLED(CONFIG_USB_DWC2_HOST) &&
+		    IS_ENABLED(CONFIG_USB_DWC2_GADGET))
+			mode = dwc2->dr_mode;
+		else if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
+			mode = USB_DR_MODE_HOST;
+		else if (IS_ENABLED(CONFIG_USB_DWC2_GADGET))
+			mode = USB_DR_MODE_PERIPHERAL;
+	}
+
+	if (mode != dwc2->dr_mode) {
+		dwc2_warn(dwc2,
+			 "Configuration mismatch. dr_mode forced to %s\n",
+			mode == USB_DR_MODE_HOST ? "host" : "device");
+
+		dwc2->dr_mode = mode;
+	}
+
+	return 0;
+}
+
 /*
  * Do core a soft reset of the core.  Be careful with this because it
  * resets all the internal state machines of the core.
diff --git a/drivers/usb/dwc2/dwc2.c b/drivers/usb/dwc2/dwc2.c
index 52a790468..e058cb257 100644
--- a/drivers/usb/dwc2/dwc2.c
+++ b/drivers/usb/dwc2/dwc2.c
@@ -58,6 +58,8 @@ static int dwc2_probe(struct device_d *dev)
 	/* Detect config values from hardware */
 	dwc2_get_hwparams(dwc2);
 
+	dwc2_get_dr_mode(dwc2);
+
 	dwc2_set_default_params(dwc2);
 
 	dma_set_mask(dev, DMA_BIT_MASK(32));
diff --git a/drivers/usb/dwc2/dwc2.h b/drivers/usb/dwc2/dwc2.h
index 35c0d1415..d18b10cbf 100644
--- a/drivers/usb/dwc2/dwc2.h
+++ b/drivers/usb/dwc2/dwc2.h
@@ -21,6 +21,7 @@ void dwc2_flush_all_fifo(struct dwc2 *dwc2);
 int dwc2_phy_init(struct dwc2 *dwc2, bool select_phy);
 int dwc2_gahbcfg_init(struct dwc2 *dwc2);
 void dwc2_gusbcfg_init(struct dwc2 *dwc2);
+int dwc2_get_dr_mode(struct dwc2 *dwc2);
 
 int dwc2_core_reset(struct dwc2 *dwc2);
 void dwc2_core_init(struct dwc2 *dwc2);
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2020-07-21 12:06 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-21 12:05 [PATCH v3 00/14] usb: dwc2: Add host and gadget driver Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 01/14] Revert "usb: Add dwc2 host driver" Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 02/14] usb: dwc2: Add host controller driver Jules Maselbas
2020-07-22  6:36   ` Ahmad Fatoum
2020-07-22  9:12     ` Jules Maselbas
2020-07-22  9:18       ` Ahmad Fatoum
2020-07-22  9:21         ` Jules Maselbas
2020-08-10 20:26   ` Sascha Hauer
2020-07-21 12:05 ` Jules Maselbas [this message]
2020-07-21 12:05 ` [PATCH v3 04/14] usb: dwc2: Rework roothub interface Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 05/14] usb: dwc2: Rework timeout Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 06/14] usb: dwc2: host: Handle dma mapping errors Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 07/14] usb: dwc2: host: Dynamic fifo size support from Linux Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 08/14] usb: dwc2: host: Fix toggle reset Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 09/14] usb: dwc2: host: Rewrite dwc2_hc_init Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 10/14] usb: dwc2: Add function to flush tx fifo Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 11/14] usb: dwc2: Add structure for gadget driver Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 12/14] usb: dwc2: Add " Jules Maselbas
2020-07-21 12:05 ` [PATCH v3 13/14] usb: dwc2: Use register_otg_device Jules Maselbas
2020-07-21 12:06 ` [PATCH v3 14/14] usb: dwc2: Add ulpi phy function Jules Maselbas
2020-08-10 20:34   ` Sascha Hauer
2020-08-11  9:31     ` Jules Maselbas
2020-08-10 20:23 ` [PATCH v3 00/14] usb: dwc2: Add host and gadget driver Sascha Hauer

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=20200721120600.15114-4-jmaselbas@kalray.eu \
    --to=jmaselbas@kalray.eu \
    --cc=barebox@lists.infradead.org \
    /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