* [PATCH 00/11] Cleanup Octeon DWC3 glue code
@ 2023-06-19 20:09 Ladislav Michl
2023-06-19 20:11 ` [PATCH 01/11] MIPS: OCTEON: octeon-usb: add all register offsets Ladislav Michl
` (11 more replies)
0 siblings, 12 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:09 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
Hi,
primary motivation was to fix issue Id 29206 as described in
OCTEON III CN70XX/CN71XX Known Issues, version: 1.9.
Said document is marked as Marvell Proprietary and Confidential,
therefore I'm not sure if I can cite from it.
This probably does not matter too much as the root of the information
listed there is a workaround being implemented in OCTEON SDK 3.1.2
patch 7 and later in
u-boot/drivers/usb/host/xhci-octeon.c:dwc3_uphy_pll_reset()
My coleague ported that patch to linux-4.9 and it is appended to
this cover letter for a reference.
The glue code currently lives in arch/mips/cavium-octeon/octeon-usb.c
and loops for each "cavium,octeon-7130-usb-uctl" compatible.
However there is no bond with dwc3 core code, so if anything goes
wrong in glue code, the loop breaks, leaving dwc3 in reset.
Later on when dwc3 core tries to read any device register, bus error
is emited, leading to kernel panic.
Therefore glue code is cleaned-up first, then moved to drivers/usb/dwc3
and modified to match current state of art.
Now it is easier to properly implement said errata. Does it belong
to core code as a quirk? Comments and suggestions welcome.
Ladislav Michl (11):
MIPS: OCTEON: octeon-usb: add all register offsets
MIPS: OCTEON: octeon-usb: use bitfields for control register
MIPS: OCTEON: octeon-usb: use bitfields for host config register
MIPS: OCTEON: octeon-usb: use bitfields for shim register
MIPS: OCTEON: octeon-usb: move gpio config to separate function
MIPS: OCTEON: octeon-usb: introduce dwc3_octeon_{read,write}q
MIPS: OCTEON: octeon-usb: cleanup divider calculation
usb: dwc3: Move Octeon glue code from arch/mips
usb: dwc3: dwc3-octeon: Convert to glue driver
usb: dwc3: dwc3-octeon: Move node parsing into driver probe
usb: dwc3: Add SPDX header and copyright
arch/mips/cavium-octeon/Makefile | 1 -
arch/mips/cavium-octeon/octeon-platform.c | 1 -
arch/mips/cavium-octeon/octeon-usb.c | 548 ----------------------
drivers/usb/dwc3/Kconfig | 9 +
drivers/usb/dwc3/Makefile | 1 +
drivers/usb/dwc3/dwc3-octeon.c | 545 +++++++++++++++++++++
drivers/usb/dwc3/dwc3-of-simple.c | 1 -
7 files changed, 555 insertions(+), 551 deletions(-)
delete mode 100644 arch/mips/cavium-octeon/octeon-usb.c
create mode 100644 drivers/usb/dwc3/dwc3-octeon.c
---
arch/mips/cavium-octeon/octeon-usb.c | 592 +++++++++++++++++++++++++++
1 file changed, 592 insertions(+)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index 514af27e23ff..544c2db6c6c3 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -14,7 +14,9 @@
#include <linux/delay.h>
#include <linux/of_platform.h>
#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <asm/octeon/cvmx-usbdrdx-defs.h>
#include <asm/octeon/octeon.h>
/* USB Control Register */
@@ -225,6 +227,371 @@ static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
+/**
+ * Reset PLL source on driver probe.
+ * Patch taken from: u-boot/drivers/usb/host/xhci-octeon.c:octeon3_usb_clocks_start
+ */
+
+/** Internal indirect UPHY register that controls the power to the UPHY PLL. */
+#define DWC3_INT_IND_UPHY_PLL_PU 0x2012
+/** Internal indirect UPHY PLL register */
+#define DWC3_INT_IND_UPHY_PLL_RESET 0x201C
+/**
+ * Internal indirect register that reports if the phy PLL has lock. This will
+ * be 1 if lock, 0 if no lock.
+ */
+#define DWC3_INT_IND_PLL_LOCK_REG 0x200b
+
+/** Write enable bit */
+#define DWC3_INT_IND_UPHY_PLL_RESET_WE (1 << 4)
+/** VCO reset bit */
+#define DWC3_INT_IND_UPHY_PLL_RESET_VCO_RST (1 << 0)
+/** Write enable bit for DWC3_INT_IND_PLL_POWER_CTL */
+#define DWC3_INT_IND_UPHY_PLL_PU_WE 0x20
+/** Power enable bit for DWC3_INT_IND_PLL_POWER_CTL */
+#define DWC3_INT_IND_UPHY_PLL_PU_POWER_EN 0x02
+
+
+/**
+ * Indirectly read internal DWC3 UPHY registers
+ *
+ * @param node CPU node number
+ * @param index Port index
+ * @param addr Address of register to read
+ *
+ * @return 16-bit register value
+ */
+uint32_t dwc3_uphy_indirect_read(struct device *dev, int node, int index, uint32_t addr)
+{
+ union cvmx_usbdrdx_uctl_portx_cr_dbg_cfg dbg_cfg;
+ union cvmx_usbdrdx_uctl_portx_cr_dbg_status status;
+ unsigned long start;
+ uint16_t data = 0xffff;
+
+
+ /* 1 */
+ dbg_cfg.u64 = 0;
+ dbg_cfg.s.data_in = addr;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 2 */
+ dbg_cfg.s.cap_addr = 1;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 3 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 1 && jiffies< (start + HZ));
+ if (status.s.ack != 1) {
+ dev_warn(dev, "%s(%d, %d, 0x%x): status ack = 1 timeout\n", __func__,
+ node, index, addr);
+ return data;
+ }
+
+ /* 4 */
+ dbg_cfg.u64 = 0;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 5 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 0 && jiffies< (start + HZ));
+ if (status.s.ack) {
+ dev_warn(dev, "%s(%d, %d, 0x%x): status ack = 0 timeout\n", __func__,
+ node, index, addr);
+ return data;
+ }
+
+ /* 6 */
+ dbg_cfg.s.read = 1;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 7 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 1 && jiffies< (start + HZ));
+ if (status.s.ack != 1) {
+ dev_warn(dev, "%s(%d, %d, 0x%x): Status ack = 0 get data timeout\n",
+ __func__, node, index, addr);
+ return 0xffff;
+ }
+ /* 8 */
+ data = status.s.data_out;
+ /* 9 */
+ dbg_cfg.u64 = 0;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 10 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 0 && jiffies< (start + HZ));
+ if (status.s.ack != 0) {
+ dev_warn(dev, "%s(%d, %d, 0x%x): Final ack timeout\n", __func__,
+ node, index, addr);
+ return 0xffff;
+ }
+
+ return data;
+}
+
+/**
+ * Indirectly write internal DWC3 UPHY registers
+ *
+ * @param node CPU node number
+ * @param index Port index
+ * @param addr Address of register to read
+ *
+ * @return 0 for success
+ */
+static uint32_t dwc3_uphy_indirect_write(struct device *dev, int node, int index,
+ uint32_t addr, uint16_t value)
+{
+ union cvmx_usbdrdx_uctl_portx_cr_dbg_cfg dbg_cfg;
+ union cvmx_usbdrdx_uctl_portx_cr_dbg_status status;
+ unsigned long start;
+
+ /* 1 */
+ dbg_cfg.u64 = 0;
+ dbg_cfg.s.data_in = addr;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 2 */
+ dbg_cfg.s.cap_addr = 1;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 3 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 1 && jiffies< (start + HZ));
+ if (status.s.ack != 1) {
+ dev_warn(dev, "%s(%d, %d, 0x%x, 0x%x): setting address timed out\n",
+ __func__, node, index, addr, value);
+ return -1;
+ }
+ /* 4 */
+ dbg_cfg.u64 = 0;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 5 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 0 && jiffies< (start + HZ));
+ if (status.s.ack != 0) {
+ dev_dbg(dev, "%s(%d, %d, 0x%x, 0x%x): Timeout waiting for ack = 0\n",
+ __func__, node, index, addr, value);
+ return -1;
+ }
+
+ /* 6 */
+ dbg_cfg.u64 = 0;
+ dbg_cfg.s.data_in = value;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 7 */
+ dbg_cfg.s.cap_data = 1;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 8 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 1 && jiffies< (start + HZ));
+ if (status.s.ack != 1) {
+ dev_dbg(dev, "%s(%d, %d, 0x%x, 0x%x): Timeout setting data, waiting for ack = 1\n",
+ __func__, node, index, addr, value);
+ return -1;
+ }
+ /* 9 */
+ dbg_cfg.u64 = 0;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 10 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 0 && jiffies< (start + HZ));
+ if (status.s.ack != 0) {
+ dev_dbg(dev, "%s(%d, %d, 0x%x, 0x%x): Timeout waiting for ack = 0\n",
+ __func__, node, index, addr, value);
+ return -1;
+ }
+ /* 11 */
+ dbg_cfg.u64 = 0;
+ dbg_cfg.s.write = 1;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 12 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 1 && jiffies< (start + HZ));
+ if (status.s.ack != 1) {
+ dev_warn(dev, "%s(%d, %d, 0x%x, 0x%x): Timeout waiting for write ack = 1\n",
+ __func__, node, index, addr, value);
+ return -1;
+ }
+ /* 13 */
+ dbg_cfg.u64 = 0;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_PORTX_CR_DBG_CFG(0, index),
+ dbg_cfg.u64);
+ /* 14 */
+ start = jiffies;
+ do {
+ status.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_PORTX_CR_DBG_STATUS(0, index));
+ } while (status.s.ack != 0 && jiffies< (start + HZ));
+ if (status.s.ack != 0) {
+ dev_warn(dev, "%s(%d, %d, 0x%x, 0x%x): Timeout waiting for write ack = 0\n",
+ __func__, node, index, addr, value);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Performs a full reset of the UPHY PLL. Note that this is normally done
+ * internally by a state machine when the UPHY is brought out of reset but this
+ * version gives far more time for things to settle before continuing.
+ *
+ * @param node CPU node
+ * @param index XHCI controller index
+ *
+ * @return 0 for success, 1 if UPHY PLL does not have lock.
+ */
+static int dwc3_uphy_pll_reset(struct device *dev, int node, int index)
+{
+ const uint16_t pwr_reg = DWC3_INT_IND_UPHY_PLL_PU;
+ const uint16_t ctrl_reg = DWC3_INT_IND_UPHY_PLL_RESET;
+ const uint16_t lock_reg = DWC3_INT_IND_PLL_LOCK_REG;
+ uint16_t ctrl_val, pwr_val;
+
+ dev_dbg(dev, "%s(%d, %d)\n", __func__, node, index);
+
+ /* 1. Turn on write enable so we can assert reset to the PLL VCO */
+ ctrl_val = dwc3_uphy_indirect_read(dev, node, index, ctrl_reg);
+ ctrl_val |= DWC3_INT_IND_UPHY_PLL_RESET_WE;
+ dwc3_uphy_indirect_write(dev, node, index, ctrl_reg, ctrl_val);
+ mdelay(1);
+
+ /* 2. Turn on write enable for PLL power control */
+ pwr_val = dwc3_uphy_indirect_read(dev, node, index, pwr_reg);
+ pwr_val |= DWC3_INT_IND_UPHY_PLL_PU_WE;
+ dwc3_uphy_indirect_write(dev, node, index, pwr_reg, pwr_val);
+ mdelay(1);
+
+ /* 3. Assert VCO reset */
+ ctrl_val |= DWC3_INT_IND_UPHY_PLL_RESET_VCO_RST;
+ dwc3_uphy_indirect_write(dev, node, index, ctrl_reg, ctrl_val);
+
+ mdelay(1);
+
+ /* 4. Power down the PLL */
+ pwr_val &= ~DWC3_INT_IND_UPHY_PLL_PU_POWER_EN;
+ dwc3_uphy_indirect_write(dev, node, index, pwr_reg, pwr_val);
+ mdelay(1);
+
+ /* 5. Power on the PLL while VCO is held in reset */
+ pwr_val |= DWC3_INT_IND_UPHY_PLL_PU_POWER_EN;
+ dwc3_uphy_indirect_write(dev, node, index, pwr_reg, pwr_val);
+
+ /* Wait for things to stabilize before taking VCO out of reset */
+ mdelay(1);
+
+ /* 6. Take the VCO out of reset */
+ ctrl_val &= ~DWC3_INT_IND_UPHY_PLL_RESET_VCO_RST;
+ dwc3_uphy_indirect_write(dev, node, index, ctrl_reg, ctrl_val);
+ mdelay(1);
+
+ /* 7. Put the VCO back in reset */
+ ctrl_val |= ~DWC3_INT_IND_UPHY_PLL_RESET_VCO_RST;
+ dwc3_uphy_indirect_write(dev, node, index, ctrl_reg, ctrl_val);
+ mdelay(1);
+
+ /* 8. Power down the PLL */
+ pwr_val &= ~DWC3_INT_IND_UPHY_PLL_PU_POWER_EN;
+ dwc3_uphy_indirect_write(dev, node, index, pwr_reg, pwr_val);
+ mdelay(1);
+
+ /* 9. Power on the PLL while VCO is held in reset */
+ pwr_val |= DWC3_INT_IND_UPHY_PLL_PU_POWER_EN;
+ dwc3_uphy_indirect_write(dev, node, index, pwr_reg, pwr_val);
+ mdelay(1);
+
+ /* 10. Take the VCO out of reset */
+ ctrl_val &= ~DWC3_INT_IND_UPHY_PLL_RESET_VCO_RST;
+ dwc3_uphy_indirect_write(dev, node, index, ctrl_reg, ctrl_val);
+ mdelay(1);
+
+ /* 11. Turn off write enables */
+ pwr_val &= ~DWC3_INT_IND_UPHY_PLL_PU_WE;
+ dwc3_uphy_indirect_write(dev, node, index, pwr_reg, pwr_val);
+
+ ctrl_val &= DWC3_INT_IND_UPHY_PLL_RESET_WE;
+ dwc3_uphy_indirect_write(dev, node, index, ctrl_reg, ctrl_val);
+
+ mdelay(1);
+
+ /* Return if we have lock or not */
+ return !(dwc3_uphy_indirect_read(dev, node, index, lock_reg) & 1);
+}
+
+/**
+ * Converts a CPU NODE and CSR address to a new address
+ *
+ * @param node CPU node number
+ * @param addr CSR address
+ *
+ * @return New CSR address for the specified CPU node
+ */
+static uint64_t node_to_addr(int node, uint64_t addr)
+{
+ return (addr & ~CVMX_NODE_IO_MASK) |
+ ((uint64_t)node & CVMX_NODE_MASK) << CVMX_NODE_IO_SHIFT;
+}
+
+/**
+ * Writes to a USBDRDX_UAHC register, taking care of any endian conversions.
+ *
+ * @param addr Address of register to write to
+ * @param val Value to write to register
+ */
+static void write_uahc_reg(int node, uint64_t addr, uint32_t val)
+{
+ uint64_t addr64 = node_to_addr(node, addr);
+ cvmx_write64_uint32(addr64, cpu_to_le32(val));
+}
+
+/**
+ * Reads from a USBDRDX_UAHC register. All UAHC registers are in little-endian
+ * format.
+ *
+ * @param addr Address of register to read
+ * @return value of register
+ */
+static uint32_t read_uahc_reg(int node, uint64_t addr)
+{
+ uint64_t addr64 = node_to_addr(node, addr);
+ return le32_to_cpu(cvmx_read64_uint32(addr64));
+}
+
+#endif
+
static int dwc3_octeon_config_power(struct device *dev, u64 base)
{
#define UCTL_HOST_CFG 0xe0
@@ -481,6 +848,7 @@ static void __init dwc3_octeon_set_endian_mode(u64 base)
#define CVMX_USBDRDX_UCTL_CTL(index) \
(CVMX_ADD_IO_SEG(0x0001180068000000ull) + \
((index & 1) * 0x1000000ull))
+
static void __init dwc3_octeon_phy_reset(u64 base)
{
union cvm_usbdrd_uctl_ctl uctl_ctl;
@@ -491,6 +859,224 @@ static void __init dwc3_octeon_phy_reset(u64 base)
cvmx_write_csr(CVMX_USBDRDX_UCTL_CTL(index), uctl_ctl.u64);
}
+static int __init dwc3_octeon_device_pll_lock(struct device *dev, u64 base)
+{
+ union cvmx_usbdrdx_uctl_ctl uctl_ctl;
+ union cvmx_usbdrdx_uahc_gusb2phycfgx phycfg;
+ union cvmx_usbdrdx_uahc_gusb3pipectlx pipectl;
+ union cvmx_usbdrdx_uahc_gctl gctl;
+ union cvmx_usbdrdx_uahc_gsts gsts;
+ union cvmx_usbdrdx_uahc_portscx portsc;
+
+ uint64_t phycfg_addr;
+ uint64_t pipectl_addr;
+ uint64_t gctl_addr;
+ uint64_t gsts_addr;
+
+ int index, ret;
+ int node = 0;
+
+ switch(base) {
+ case 0x8001180068000000ull:
+ index = 0;
+ break;
+ case 0x8001180069000000ull:
+ index = 1;
+ break;
+ default:
+ dev_err(dev, "Invalid base address 0x%llx for node %d.", base, node);
+ return -1;
+ }
+
+ /* From previous steps */
+ /* Step 13, wait 10uS for the PHY to complete its reset */
+ udelay(10);
+
+ /* 14. Deassert UPHY reset */
+ uctl_ctl.u64 = cvmx_read_csr_node(node,
+ CVMX_USBDRDX_UCTL_CTL(index));
+ uctl_ctl.s.uphy_rst = 0;
+ cvmx_write_csr_node(node, CVMX_USBDRDX_UCTL_CTL(index),
+ uctl_ctl.u64);
+ /* Setp 15, wait for at least 45us for UPHY to output stable
+ * PHYCLOCK
+ */
+ udelay(50);
+
+ /* Step 16: Initialize any other strap signals necessary and
+ * make sure they propagate by reading back the last register
+ * written.
+ *
+ * a. UCTL:
+ * uctl_port0_cfg_*[*_tune]
+ * uctl_port0_cfg_*[pcs_*]
+ * uctl_port0_cfg_*[lane0_tx_term_offset]
+ * uctl_port0_cfg_*[tx_vboost_lvl]
+ * uctl_port0_cfg_*[los_bias]
+ * uctl_host_cfg
+ * uctl_shim_cfg
+ */
+ /* b. UAHC: only the following UAHC registers are accessible
+ * during CoreSoftReset.
+ * - USBDRDX_UAHC_GCTL
+ * - USBDRDX_UAHC_GUCTL
+ * - USBDRDX_UAHC_GSTS
+ * - USBDRDX_UAHC_GUID
+ * - USBDRDX_UAHC_GUSB2PHYCFG
+ * - USBDRDX_UAHC_GUSB3PIPECTL
+ */
+
+ /* 17. Release soft reset the UPHY and UAHC logic via the UAHC
+ * controls.
+ */
+
+ phycfg_addr = CVMX_USBDRDX_UAHC_GUSB2PHYCFGX(0, index);
+ pipectl_addr = node_to_addr(node,
+ CVMX_USBDRDX_UAHC_GUSB3PIPECTLX(0, index));
+ gctl_addr = CVMX_USBDRDX_UAHC_GCTL(index);
+ gsts_addr = CVMX_USBDRDX_UAHC_GSTS(index);
+
+ phycfg.u32 = read_uahc_reg(node, phycfg_addr);
+ phycfg.s.physoftrst = 1;
+ /* Disable low power mode due to mcbuggin 29646 */
+ phycfg.s.enblslpm = 0;
+ write_uahc_reg(node, phycfg_addr, phycfg.u32);
+
+ pipectl.u32 = read_uahc_reg(node, pipectl_addr);
+ pipectl.s.physoftrst = 1;
+ /* Disable low power mode due to mcbuggin 29646 */
+ pipectl.s.suspend_en = 0;
+ write_uahc_reg(node, pipectl_addr, pipectl.u32);
+
+ udelay(100);
+
+ gctl.u32 = read_uahc_reg(node, gctl_addr);
+ gctl.s.coresoftreset = 1;
+ write_uahc_reg(node, gctl_addr, gctl.u32);
+
+#ifdef DEBUG
+ if (!dwc3_uphy_indirect_read(dev, node, index,
+ DWC3_INT_IND_PLL_LOCK_REG))
+ dev_warn(dev, "Detected no lock on USB 2 PHY PLL\n");
+#endif
+
+ dev_warn(dev, "DWC3: usb pll locked %u.",
+ dwc3_uphy_indirect_read(dev, node, index, DWC3_INT_IND_PLL_LOCK_REG));
+ /* 19. Reset the USB PHY PLL. This phy is reset during the
+ * UPHY reset process but the internal state machine seems
+ * to be too fast and sometimes the PLL Does not come up.
+ * The software reset sequence has much longer delays
+ * which allows things to settle properly before proceeding.
+ */
+
+ dev_warn(dev, "%s: Resetting USB PHY PLL\n", __func__);
+ ret = dwc3_uphy_pll_reset(dev, node, index);
+ if (ret) {
+ dev_warn(dev, "%s: UPHY PLL on node: %d, interface: %d not locked after reset.\n",
+ __func__, node, index);
+ }
+ mdelay(1);
+
+ /* 18. Configure the remaining UAHC_G* registers including any
+ * that were not configured in step 16.-b
+ */
+#ifdef DEBUG
+ if (!dwc3_uphy_indirect_read(dev, node, index,
+ DWC3_INT_IND_PLL_LOCK_REG))
+ dev_warn(dev, "Detected no lock on USB 2 PHY PLL\n");
+#endif
+
+ /* 19. Reset the USB PHY PLL. This phy is reset during the
+ * UPHY reset process but the internal state machine seems
+ * to be too fast and sometimes the PLL Does not come up.
+ * The software reset sequence has much longer delays
+ * which allows things to settle properly before proceeding.
+ */
+
+ dev_info(dev, "%s: Resetting USB PHY PLL\n", __func__);
+ ret = dwc3_uphy_pll_reset(dev, node, index);
+ if (ret) {
+ dev_warn(dev, "%s: UPHY PLL on node: %d, interface: %d not locked after reset.\n",
+ __func__, node, index);
+ return -1;
+ }
+
+ dev_warn(dev, "DWC3: usb pll locked %u after reset.",
+ dwc3_uphy_indirect_read(dev, node, index, DWC3_INT_IND_PLL_LOCK_REG));
+
+ pipectl.u32 = read_uahc_reg(node, pipectl_addr);
+ dev_info(dev, "%s: GUSB3PIPECTL: 0x%x\n", __func__, pipectl.u32);
+
+ pipectl.s.physoftrst = 0;
+ /* Disable low power mode due to mcbuggin 29646 */
+ pipectl.s.suspend_en = 0;
+ write_uahc_reg(node, pipectl_addr, pipectl.u32);
+ udelay(100);
+ phycfg.u32 = read_uahc_reg(node, phycfg_addr);
+ phycfg.s.physoftrst = 0;
+ /* Disable low power mode due to mcbuggin 29646 */
+ phycfg.s.enblslpm = 0;
+ write_uahc_reg(node, phycfg_addr, phycfg.u32);
+
+ gctl.u32 = read_uahc_reg(node, gctl_addr);
+ gctl.s.coresoftreset = 0;
+ write_uahc_reg(node, gctl_addr, gctl.u32);
+ udelay(100);
+
+ /* Clear any previous bits set */
+ gsts.u32 = read_uahc_reg(node, gsts_addr);
+ write_uahc_reg(node, gsts_addr, gsts.u32);
+
+ /* We test that there hasn't been a PLL issue during
+ * initialization. If we detect this then we retry.
+ *
+ * On octeon, the wce bit basically shouldn't do anything. If
+ * a PLL failed to come up then we will see a CSR timeout.
+ */
+ portsc.u32 = read_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(0, index));
+ portsc.s.wce = 1;
+ write_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(0, index), portsc.u32);
+ gsts.u32 = read_uahc_reg(node, gsts_addr);
+ write_uahc_reg(node, gsts_addr, gsts.u32);
+ if (gsts.s.csrtimeout) {
+ dev_err(dev, "%s: Detected CSR tmout 0, can't continue...\n", __func__);
+ return -1;
+ }
+ udelay(100);
+ portsc.u32 = read_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(1, index));
+ portsc.s.wce = 1;
+ write_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(1, index), portsc.u32);
+ gsts.u32 = read_uahc_reg(node, gsts_addr);
+ write_uahc_reg(node, gsts_addr, gsts.u32);
+ if (gsts.s.csrtimeout) {
+ dev_err(dev, "%s: Detected CSR tmout 1, can't continue...\n", __func__);
+ return -1;
+ }
+
+ udelay(100);
+ portsc.u32 = read_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(0, index));
+ portsc.s.wce = 0;
+ write_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(0, index), portsc.u32);
+ gsts.u32 = read_uahc_reg(node, gsts_addr);
+ write_uahc_reg(node, gsts_addr, gsts.u32);
+ if (gsts.s.csrtimeout) {
+ dev_err(dev, "%s: Detected CSR tmout 2, can't continue...\n", __func__);
+ return -1;
+ }
+ udelay(100);
+ portsc.u32 = read_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(0, index));
+ portsc.s.wce = 0;
+ write_uahc_reg(node, CVMX_USBDRDX_UAHC_PORTSCX(0, index), portsc.u32);
+ gsts.u32 = read_uahc_reg(node, gsts_addr);
+ write_uahc_reg(node, gsts_addr, gsts.u32);
+ if (gsts.s.csrtimeout) {
+ dev_err(dev, "%s: Detected CSR tmout 4, can't continue...\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
static int __init dwc3_octeon_device_init(void)
{
const char compat_node_name[] = "cavium,octeon-7130-usb-uctl";
@@ -531,6 +1117,12 @@ static int __init dwc3_octeon_device_init(void)
dev_info(&pdev->dev, "clocks initialized.\n");
dwc3_octeon_set_endian_mode((u64)base);
dwc3_octeon_phy_reset((u64)base);
+ if (dwc3_octeon_device_pll_lock(&pdev->dev, (u64)base) != 0) {
+ dev_err(&pdev->dev, "Failed to initialize clocks.");
+ mutex_unlock(&dwc3_octeon_clocks_mutex);
+ put_device(&pdev->dev);
+ return -EINVAL;
+ }
mutex_unlock(&dwc3_octeon_clocks_mutex);
devm_iounmap(&pdev->dev, base);
devm_release_mem_region(&pdev->dev, res->start,
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 01/11] MIPS: OCTEON: octeon-usb: add all register offsets
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
@ 2023-06-19 20:11 ` Ladislav Michl
2023-06-19 20:11 ` [PATCH 02/11] MIPS: OCTEON: octeon-usb: use bitfields for control register Ladislav Michl
` (10 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:11 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Glue code uses a mix of offset and absolute address register
definition. Define all of them as offsets and use them
consistently.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-usb.c | 35 +++++++++++++++++-----------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index 28677c615175..4d22eaa8a644 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -17,6 +17,19 @@
#include <asm/octeon/octeon.h>
+#define USBDRD_UCTL_CTL 0x00
+#define USBDRD_UCTL_BIST_STATUS 0x08
+#define USBDRD_UCTL_SPARE0 0x10
+#define USBDRD_UCTL_INTSTAT 0x30
+#define USBDRD_UCTL_PORT_CFG_HS(port) (0x40 + (0x20 * port))
+#define USBDRD_UCTL_PORT_CFG_SS(port) (0x48 + (0x20 * port))
+#define USBDRD_UCTL_PORT_CR_DBG_CFG(port) (0x50 + (0x20 * port))
+#define USBDRD_UCTL_PORT_CR_DBG_STATUS(port) (0x58 + (0x20 * port))
+#define USBDRD_UCTL_HOST_CFG 0xe0
+#define USBDRD_UCTL_SHIM_CFG 0xe8
+#define USBDRD_UCTL_ECC 0xf0
+#define USBDRD_UCTL_SPARE1 0xf8
+
/* USB Control Register */
union cvm_usbdrd_uctl_ctl {
uint64_t u64;
@@ -227,7 +240,6 @@ static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
static int dwc3_octeon_config_power(struct device *dev, u64 base)
{
-#define UCTL_HOST_CFG 0xe0
union cvm_usbdrd_uctl_host_cfg uctl_host_cfg;
union cvmx_gpio_bit_cfgx gpio_bit;
uint32_t gpio_pwr[3];
@@ -268,16 +280,16 @@ static int dwc3_octeon_config_power(struct device *dev, u64 base)
}
/* Enable XHCI power control and set if active high or low. */
- uctl_host_cfg.u64 = cvmx_read_csr(base + UCTL_HOST_CFG);
+ uctl_host_cfg.u64 = cvmx_read_csr(base + USBDRD_UCTL_HOST_CFG);
uctl_host_cfg.s.ppc_en = 1;
uctl_host_cfg.s.ppc_active_high_en = !power_active_low;
- cvmx_write_csr(base + UCTL_HOST_CFG, uctl_host_cfg.u64);
+ cvmx_write_csr(base + USBDRD_UCTL_HOST_CFG, uctl_host_cfg.u64);
} else {
/* Disable XHCI power control and set if active high. */
- uctl_host_cfg.u64 = cvmx_read_csr(base + UCTL_HOST_CFG);
+ uctl_host_cfg.u64 = cvmx_read_csr(base + USBDRD_UCTL_HOST_CFG);
uctl_host_cfg.s.ppc_en = 0;
uctl_host_cfg.s.ppc_active_high_en = 0;
- cvmx_write_csr(base + UCTL_HOST_CFG, uctl_host_cfg.u64);
+ cvmx_write_csr(base + USBDRD_UCTL_HOST_CFG, uctl_host_cfg.u64);
dev_info(dev, "power control disabled\n");
}
return 0;
@@ -464,10 +476,9 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
static void __init dwc3_octeon_set_endian_mode(u64 base)
{
-#define UCTL_SHIM_CFG 0xe8
union cvm_usbdrd_uctl_shim_cfg shim_cfg;
- shim_cfg.u64 = cvmx_read_csr(base + UCTL_SHIM_CFG);
+ shim_cfg.u64 = cvmx_read_csr(base + USBDRD_UCTL_SHIM_CFG);
#ifdef __BIG_ENDIAN
shim_cfg.s.dma_endian_mode = 1;
shim_cfg.s.csr_endian_mode = 1;
@@ -475,20 +486,16 @@ static void __init dwc3_octeon_set_endian_mode(u64 base)
shim_cfg.s.dma_endian_mode = 0;
shim_cfg.s.csr_endian_mode = 0;
#endif
- cvmx_write_csr(base + UCTL_SHIM_CFG, shim_cfg.u64);
+ cvmx_write_csr(base + USBDRD_UCTL_SHIM_CFG, shim_cfg.u64);
}
-#define CVMX_USBDRDX_UCTL_CTL(index) \
- (CVMX_ADD_IO_SEG(0x0001180068000000ull) + \
- ((index & 1) * 0x1000000ull))
static void __init dwc3_octeon_phy_reset(u64 base)
{
union cvm_usbdrd_uctl_ctl uctl_ctl;
- int index = (base >> 24) & 1;
- uctl_ctl.u64 = cvmx_read_csr(CVMX_USBDRDX_UCTL_CTL(index));
+ uctl_ctl.u64 = cvmx_read_csr(base + USBDRD_UCTL_CTL);
uctl_ctl.s.uphy_rst = 0;
- cvmx_write_csr(CVMX_USBDRDX_UCTL_CTL(index), uctl_ctl.u64);
+ cvmx_write_csr(base + USBDRD_UCTL_CTL, uctl_ctl.u64);
}
static int __init dwc3_octeon_device_init(void)
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/11] MIPS: OCTEON: octeon-usb: use bitfields for control register
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
2023-06-19 20:11 ` [PATCH 01/11] MIPS: OCTEON: octeon-usb: add all register offsets Ladislav Michl
@ 2023-06-19 20:11 ` Ladislav Michl
2023-06-19 20:12 ` [PATCH 03/11] MIPS: OCTEON: octeon-usb: use bitfields for host config register Ladislav Michl
` (9 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:11 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Code needs to compile for all platforms in order to move it to
drivers/usb/dwc3. Use Linux standard bitfield access macros
to manipulate control register.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-usb.c | 330 +++++++++++++--------------
1 file changed, 159 insertions(+), 171 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index 4d22eaa8a644..e8e57d0c3b14 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -8,16 +8,117 @@
* for more details.
*/
-#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
#include <linux/device.h>
-#include <linux/mutex.h>
#include <linux/delay.h>
-#include <linux/of_platform.h>
#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_platform.h>
#include <asm/octeon/octeon.h>
+/*
+ * USB Control Register
+ */
#define USBDRD_UCTL_CTL 0x00
+/* BIST fast-clear mode select. A BIST run with this bit set
+ * clears all entries in USBH RAMs to 0x0.
+ */
+# define USBDRD_UCTL_CTL_CLEAR_BIST BIT(63)
+/* 1 = Start BIST and cleared by hardware */
+# define USBDRD_UCTL_CTL_START_BIST BIT(62)
+/* Reference clock select for SuperSpeed and HighSpeed PLLs:
+ * 0x0 = Both PLLs use DLMC_REF_CLK0 for reference clock
+ * 0x1 = Both PLLs use DLMC_REF_CLK1 for reference clock
+ * 0x2 = SuperSpeed PLL uses DLMC_REF_CLK0 for reference clock &
+ * HighSpeed PLL uses PLL_REF_CLK for reference clck
+ * 0x3 = SuperSpeed PLL uses DLMC_REF_CLK1 for reference clock &
+ * HighSpeed PLL uses PLL_REF_CLK for reference clck
+ */
+# define USBDRD_UCTL_CTL_REF_CLK_SEL GENMASK(61, 60)
+/* 1 = Spread-spectrum clock enable, 0 = SS clock disable */
+# define USBDRD_UCTL_CTL_SSC_EN BIT(59)
+/* Spread-spectrum clock modulation range:
+ * 0x0 = -4980 ppm downspread
+ * 0x1 = -4492 ppm downspread
+ * 0x2 = -4003 ppm downspread
+ * 0x3 - 0x7 = Reserved
+ */
+# define USBDRD_UCTL_CTL_SSC_RANGE GENMASK(58, 56)
+/* Enable non-standard oscillator frequencies:
+ * [55:53] = modules -1
+ * [52:47] = 2's complement push amount, 0 = Feature disabled
+ */
+# define USBDRD_UCTL_CTL_SSC_REF_CLK_SEL GENMASK(55, 47)
+/* Reference clock multiplier for non-standard frequencies:
+ * 0x19 = 100MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
+ * 0x28 = 125MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
+ * 0x32 = 50MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
+ * Other Values = Reserved
+ */
+# define USBDRD_UCTL_CTL_MPLL_MULTIPLIER GENMASK(46, 40)
+/* Enable reference clock to prescaler for SuperSpeed functionality.
+ * Should always be set to "1"
+ */
+# define USBDRD_UCTL_CTL_REF_SSP_EN BIT(39)
+/* Divide the reference clock by 2 before entering the
+ * REF_CLK_FSEL divider:
+ * If REF_CLK_SEL = 0x0 or 0x1, then only 0x0 is legal
+ * If REF_CLK_SEL = 0x2 or 0x3, then:
+ * 0x1 = DLMC_REF_CLK* is 125MHz
+ * 0x0 = DLMC_REF_CLK* is another supported frequency
+ */
+# define USBDRD_UCTL_CTL_REF_CLK_DIV2 BIT(38)
+/* Select reference clock freqnuency for both PLL blocks:
+ * 0x27 = REF_CLK_SEL is 0x0 or 0x1
+ * 0x07 = REF_CLK_SEL is 0x2 or 0x3
+ */
+# define USBDRD_UCTL_CTL_REF_CLK_FSEL GENMASK(37, 32)
+/* Controller clock enable. */
+# define USBDRD_UCTL_CTL_H_CLK_EN BIT(30)
+/* Select bypass input to controller clock divider:
+ * 0x0 = Use divided coprocessor clock from H_CLKDIV
+ * 0x1 = Use clock from GPIO pins
+ */
+# define USBDRD_UCTL_CTL_H_CLK_BYP_SEL BIT(29)
+/* Reset controller clock divider. */
+# define USBDRD_UCTL_CTL_H_CLKDIV_RST BIT(28)
+/* Clock divider select:
+ * 0x0 = divide by 1
+ * 0x1 = divide by 2
+ * 0x2 = divide by 4
+ * 0x3 = divide by 6
+ * 0x4 = divide by 8
+ * 0x5 = divide by 16
+ * 0x6 = divide by 24
+ * 0x7 = divide by 32
+ */
+# define USBDRD_UCTL_CTL_H_CLKDIV_SEL GENMASK(26, 24)
+/* USB3 port permanently attached: 0x0 = No, 0x1 = Yes */
+# define USBDRD_UCTL_CTL_USB3_PORT_PERM_ATTACH BIT(21)
+/* USB2 port permanently attached: 0x0 = No, 0x1 = Yes */
+# define USBDRD_UCTL_CTL_USB2_PORT_PERM_ATTACH BIT(20)
+/* Disable SuperSpeed PHY: 0x0 = No, 0x1 = Yes */
+# define USBDRD_UCTL_CTL_USB3_PORT_DISABLE BIT(18)
+/* Disable HighSpeed PHY: 0x0 = No, 0x1 = Yes */
+# define USBDRD_UCTL_CTL_USB2_PORT_DISABLE BIT(16)
+/* Enable PHY SuperSpeed block power: 0x0 = No, 0x1 = Yes */
+# define USBDRD_UCTL_CTL_SS_POWER_EN BIT(14)
+/* Enable PHY HighSpeed block power: 0x0 = No, 0x1 = Yes */
+# define USBDRD_UCTL_CTL_HS_POWER_EN BIT(12)
+/* Enable USB UCTL interface clock: 0xx = No, 0x1 = Yes */
+# define USBDRD_UCTL_CTL_CSCLK_EN BIT(4)
+/* Controller mode: 0x0 = Host, 0x1 = Device */
+# define USBDRD_UCTL_CTL_DRD_MODE BIT(3)
+/* PHY reset */
+# define USBDRD_UCTL_CTL_UPHY_RST BIT(2)
+/* Software reset UAHC */
+# define USBDRD_UCTL_CTL_UAHC_RST BIT(1)
+/* Software resets UCTL */
+# define USBDRD_UCTL_CTL_UCTL_RST BIT(0)
+
#define USBDRD_UCTL_BIST_STATUS 0x08
#define USBDRD_UCTL_SPARE0 0x10
#define USBDRD_UCTL_INTSTAT 0x30
@@ -30,123 +131,6 @@
#define USBDRD_UCTL_ECC 0xf0
#define USBDRD_UCTL_SPARE1 0xf8
-/* USB Control Register */
-union cvm_usbdrd_uctl_ctl {
- uint64_t u64;
- struct cvm_usbdrd_uctl_ctl_s {
- /* 1 = BIST and set all USB RAMs to 0x0, 0 = BIST */
- __BITFIELD_FIELD(uint64_t clear_bist:1,
- /* 1 = Start BIST and cleared by hardware */
- __BITFIELD_FIELD(uint64_t start_bist:1,
- /* Reference clock select for SuperSpeed and HighSpeed PLLs:
- * 0x0 = Both PLLs use DLMC_REF_CLK0 for reference clock
- * 0x1 = Both PLLs use DLMC_REF_CLK1 for reference clock
- * 0x2 = SuperSpeed PLL uses DLMC_REF_CLK0 for reference clock &
- * HighSpeed PLL uses PLL_REF_CLK for reference clck
- * 0x3 = SuperSpeed PLL uses DLMC_REF_CLK1 for reference clock &
- * HighSpeed PLL uses PLL_REF_CLK for reference clck
- */
- __BITFIELD_FIELD(uint64_t ref_clk_sel:2,
- /* 1 = Spread-spectrum clock enable, 0 = SS clock disable */
- __BITFIELD_FIELD(uint64_t ssc_en:1,
- /* Spread-spectrum clock modulation range:
- * 0x0 = -4980 ppm downspread
- * 0x1 = -4492 ppm downspread
- * 0x2 = -4003 ppm downspread
- * 0x3 - 0x7 = Reserved
- */
- __BITFIELD_FIELD(uint64_t ssc_range:3,
- /* Enable non-standard oscillator frequencies:
- * [55:53] = modules -1
- * [52:47] = 2's complement push amount, 0 = Feature disabled
- */
- __BITFIELD_FIELD(uint64_t ssc_ref_clk_sel:9,
- /* Reference clock multiplier for non-standard frequencies:
- * 0x19 = 100MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
- * 0x28 = 125MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
- * 0x32 = 50MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
- * Other Values = Reserved
- */
- __BITFIELD_FIELD(uint64_t mpll_multiplier:7,
- /* Enable reference clock to prescaler for SuperSpeed functionality.
- * Should always be set to "1"
- */
- __BITFIELD_FIELD(uint64_t ref_ssp_en:1,
- /* Divide the reference clock by 2 before entering the
- * REF_CLK_FSEL divider:
- * If REF_CLK_SEL = 0x0 or 0x1, then only 0x0 is legal
- * If REF_CLK_SEL = 0x2 or 0x3, then:
- * 0x1 = DLMC_REF_CLK* is 125MHz
- * 0x0 = DLMC_REF_CLK* is another supported frequency
- */
- __BITFIELD_FIELD(uint64_t ref_clk_div2:1,
- /* Select reference clock freqnuency for both PLL blocks:
- * 0x27 = REF_CLK_SEL is 0x0 or 0x1
- * 0x07 = REF_CLK_SEL is 0x2 or 0x3
- */
- __BITFIELD_FIELD(uint64_t ref_clk_fsel:6,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_31_31:1,
- /* Controller clock enable. */
- __BITFIELD_FIELD(uint64_t h_clk_en:1,
- /* Select bypass input to controller clock divider:
- * 0x0 = Use divided coprocessor clock from H_CLKDIV
- * 0x1 = Use clock from GPIO pins
- */
- __BITFIELD_FIELD(uint64_t h_clk_byp_sel:1,
- /* Reset controller clock divider. */
- __BITFIELD_FIELD(uint64_t h_clkdiv_rst:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_27_27:1,
- /* Clock divider select:
- * 0x0 = divide by 1
- * 0x1 = divide by 2
- * 0x2 = divide by 4
- * 0x3 = divide by 6
- * 0x4 = divide by 8
- * 0x5 = divide by 16
- * 0x6 = divide by 24
- * 0x7 = divide by 32
- */
- __BITFIELD_FIELD(uint64_t h_clkdiv_sel:3,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_22_23:2,
- /* USB3 port permanently attached: 0x0 = No, 0x1 = Yes */
- __BITFIELD_FIELD(uint64_t usb3_port_perm_attach:1,
- /* USB2 port permanently attached: 0x0 = No, 0x1 = Yes */
- __BITFIELD_FIELD(uint64_t usb2_port_perm_attach:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_19_19:1,
- /* Disable SuperSpeed PHY: 0x0 = No, 0x1 = Yes */
- __BITFIELD_FIELD(uint64_t usb3_port_disable:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_17_17:1,
- /* Disable HighSpeed PHY: 0x0 = No, 0x1 = Yes */
- __BITFIELD_FIELD(uint64_t usb2_port_disable:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_15_15:1,
- /* Enable PHY SuperSpeed block power: 0x0 = No, 0x1 = Yes */
- __BITFIELD_FIELD(uint64_t ss_power_en:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_13_13:1,
- /* Enable PHY HighSpeed block power: 0x0 = No, 0x1 = Yes */
- __BITFIELD_FIELD(uint64_t hs_power_en:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_5_11:7,
- /* Enable USB UCTL interface clock: 0xx = No, 0x1 = Yes */
- __BITFIELD_FIELD(uint64_t csclk_en:1,
- /* Controller mode: 0x0 = Host, 0x1 = Device */
- __BITFIELD_FIELD(uint64_t drd_mode:1,
- /* PHY reset */
- __BITFIELD_FIELD(uint64_t uphy_rst:1,
- /* Software reset UAHC */
- __BITFIELD_FIELD(uint64_t uahc_rst:1,
- /* Software resets UCTL */
- __BITFIELD_FIELD(uint64_t uctl_rst:1,
- ;)))))))))))))))))))))))))))))))))
- } s;
-};
-
/* UAHC Configuration Register */
union cvm_usbdrd_uctl_host_cfg {
uint64_t u64;
@@ -297,14 +281,10 @@ static int dwc3_octeon_config_power(struct device *dev, u64 base)
static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
{
- union cvm_usbdrd_uctl_ctl uctl_ctl;
- int ref_clk_sel = 2;
- u64 div;
+ int i, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
u32 clock_rate;
- int mpll_mul;
- int i;
- u64 h_clk_rate;
- u64 uctl_ctl_reg = base;
+ u64 div, h_clk_rate, val;
+ u64 uctl_ctl_reg = base + USBDRD_UCTL_CTL;
if (dev->of_node) {
const char *ss_clock_type;
@@ -368,16 +348,16 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
/* Step 2: Select GPIO for overcurrent indication, if desired. SKIP */
/* Step 3: Assert all resets. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.uphy_rst = 1;
- uctl_ctl.s.uahc_rst = 1;
- uctl_ctl.s.uctl_rst = 1;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val |= USBDRD_UCTL_CTL_UPHY_RST |
+ USBDRD_UCTL_CTL_UAHC_RST |
+ USBDRD_UCTL_CTL_UCTL_RST;
+ cvmx_write_csr(uctl_ctl_reg, val);
/* Step 4a: Reset the clock dividers. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.h_clkdiv_rst = 1;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val |= USBDRD_UCTL_CTL_H_CLKDIV_RST;
+ cvmx_write_csr(uctl_ctl_reg, val);
/* Step 4b: Select controller clock frequency. */
for (div = 0; div < OCTEON_H_CLKDIV_SEL; div++) {
@@ -386,26 +366,29 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
h_clk_rate >= OCTEON_MIN_H_CLK_RATE)
break;
}
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.h_clkdiv_sel = div;
- uctl_ctl.s.h_clk_en = 1;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- if ((div != uctl_ctl.s.h_clkdiv_sel) || (!uctl_ctl.s.h_clk_en)) {
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val &= ~USBDRD_UCTL_CTL_H_CLKDIV_SEL;
+ val |= FIELD_PREP(USBDRD_UCTL_CTL_H_CLKDIV_SEL, div);
+ val |= USBDRD_UCTL_CTL_H_CLK_EN;
+ cvmx_write_csr(uctl_ctl_reg, val);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ if ((div != FIELD_GET(USBDRD_UCTL_CTL_H_CLKDIV_SEL, val)) ||
+ (!(FIELD_GET(USBDRD_UCTL_CTL_H_CLK_EN, val)))) {
dev_err(dev, "dwc3 controller clock init failure.\n");
return -EINVAL;
}
/* Step 4c: Deassert the controller clock divider reset. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.h_clkdiv_rst = 0;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val &= ~USBDRD_UCTL_CTL_H_CLKDIV_RST;
+ cvmx_write_csr(uctl_ctl_reg, val);
/* Step 5a: Reference clock configuration. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.ref_clk_sel = ref_clk_sel;
- uctl_ctl.s.ref_clk_fsel = 0x07;
- uctl_ctl.s.ref_clk_div2 = 0;
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val &= ~USBDRD_UCTL_CTL_REF_CLK_DIV2;
+ val &= ~USBDRD_UCTL_CTL_REF_CLK_SEL;
+ val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_SEL, ref_clk_sel);
+
+ ref_clk_fsel = 0x07;
switch (clock_rate) {
default:
dev_warn(dev, "Invalid ref_clk %u, using 100000000 instead\n",
@@ -414,7 +397,7 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
case 100000000:
mpll_mul = 0x19;
if (ref_clk_sel < 2)
- uctl_ctl.s.ref_clk_fsel = 0x27;
+ ref_clk_fsel = 0x27;
break;
case 50000000:
mpll_mul = 0x32;
@@ -423,28 +406,32 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
mpll_mul = 0x28;
break;
}
- uctl_ctl.s.mpll_multiplier = mpll_mul;
+ val &= ~USBDRD_UCTL_CTL_REF_CLK_FSEL;
+ val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_FSEL, ref_clk_fsel);
+
+ val &= ~USBDRD_UCTL_CTL_MPLL_MULTIPLIER;
+ val |= FIELD_PREP(USBDRD_UCTL_CTL_MPLL_MULTIPLIER, mpll_mul);
/* Step 5b: Configure and enable spread-spectrum for SuperSpeed. */
- uctl_ctl.s.ssc_en = 1;
+ val |= USBDRD_UCTL_CTL_SSC_EN;
/* Step 5c: Enable SuperSpeed. */
- uctl_ctl.s.ref_ssp_en = 1;
+ val |= USBDRD_UCTL_CTL_REF_SSP_EN;
/* Step 5d: Configure PHYs. SKIP */
/* Step 6a & 6b: Power up PHYs. */
- uctl_ctl.s.hs_power_en = 1;
- uctl_ctl.s.ss_power_en = 1;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val |= USBDRD_UCTL_CTL_HS_POWER_EN;
+ val |= USBDRD_UCTL_CTL_SS_POWER_EN;
+ cvmx_write_csr(uctl_ctl_reg, val);
/* Step 7: Wait 10 controller-clock cycles to take effect. */
udelay(10);
/* Step 8a: Deassert UCTL reset signal. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.uctl_rst = 0;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val &= ~USBDRD_UCTL_CTL_UCTL_RST;
+ cvmx_write_csr(uctl_ctl_reg, val);
/* Step 8b: Wait 10 controller-clock cycles. */
udelay(10);
@@ -454,22 +441,22 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
return -EINVAL;
/* Step 8d: Deassert UAHC reset signal. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.uahc_rst = 0;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val &= ~USBDRD_UCTL_CTL_UAHC_RST;
+ cvmx_write_csr(uctl_ctl_reg, val);
/* Step 8e: Wait 10 controller-clock cycles. */
udelay(10);
/* Step 9: Enable conditional coprocessor clock of UCTL. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.csclk_en = 1;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val |= USBDRD_UCTL_CTL_CSCLK_EN;
+ cvmx_write_csr(uctl_ctl_reg, val);
/*Step 10: Set for host mode only. */
- uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
- uctl_ctl.s.drd_mode = 0;
- cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val &= ~USBDRD_UCTL_CTL_DRD_MODE;
+ cvmx_write_csr(uctl_ctl_reg, val);
return 0;
}
@@ -491,11 +478,12 @@ static void __init dwc3_octeon_set_endian_mode(u64 base)
static void __init dwc3_octeon_phy_reset(u64 base)
{
- union cvm_usbdrd_uctl_ctl uctl_ctl;
+ u64 val;
+ u64 uctl_ctl_reg = base + USBDRD_UCTL_CTL;
- uctl_ctl.u64 = cvmx_read_csr(base + USBDRD_UCTL_CTL);
- uctl_ctl.s.uphy_rst = 0;
- cvmx_write_csr(base + USBDRD_UCTL_CTL, uctl_ctl.u64);
+ val = cvmx_read_csr(uctl_ctl_reg);
+ val &= ~USBDRD_UCTL_CTL_UPHY_RST;
+ cvmx_write_csr(uctl_ctl_reg, val);
}
static int __init dwc3_octeon_device_init(void)
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 03/11] MIPS: OCTEON: octeon-usb: use bitfields for host config register
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
2023-06-19 20:11 ` [PATCH 01/11] MIPS: OCTEON: octeon-usb: add all register offsets Ladislav Michl
2023-06-19 20:11 ` [PATCH 02/11] MIPS: OCTEON: octeon-usb: use bitfields for control register Ladislav Michl
@ 2023-06-19 20:12 ` Ladislav Michl
2023-06-19 20:12 ` [PATCH 04/11] MIPS: OCTEON: octeon-usb: use bitfields for shim register Ladislav Michl
` (8 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:12 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Use Linux standard bitfield access macros to manipulate
host config register.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-usb.c | 83 +++++++++++++---------------
1 file changed, 38 insertions(+), 45 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index e8e57d0c3b14..17051aee491d 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -126,47 +126,36 @@
#define USBDRD_UCTL_PORT_CFG_SS(port) (0x48 + (0x20 * port))
#define USBDRD_UCTL_PORT_CR_DBG_CFG(port) (0x50 + (0x20 * port))
#define USBDRD_UCTL_PORT_CR_DBG_STATUS(port) (0x58 + (0x20 * port))
+
+/*
+ * UCTL Configuration Register
+ */
#define USBDRD_UCTL_HOST_CFG 0xe0
+/* Indicates minimum value of all received BELT values */
+# define USBDRD_UCTL_HOST_CFG_HOST_CURRENT_BELT GENMASK(59, 48)
+/* HS jitter adjustment */
+# define USBDRD_UCTL_HOST_CFG_FLA GENMASK(37, 32)
+/* Bus-master enable: 0x0 = Disabled (stall DMAs), 0x1 = enabled */
+# define USBDRD_UCTL_HOST_CFG_BME BIT(28)
+/* Overcurrent protection enable: 0x0 = unavailable, 0x1 = available */
+# define USBDRD_UCTL_HOST_OCI_EN BIT(27)
+/* Overcurrent sene selection:
+ * 0x0 = Overcurrent indication from off-chip is active-low
+ * 0x1 = Overcurrent indication from off-chip is active-high
+ */
+# define USBDRD_UCTL_HOST_OCI_ACTIVE_HIGH_EN BIT(26)
+/* Port power control enable: 0x0 = unavailable, 0x1 = available */
+# define USBDRD_UCTL_HOST_PPC_EN BIT(25)
+/* Port power control sense selection:
+ * 0x0 = Port power to off-chip is active-low
+ * 0x1 = Port power to off-chip is active-high
+ */
+# define USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN BIT(24)
+
#define USBDRD_UCTL_SHIM_CFG 0xe8
#define USBDRD_UCTL_ECC 0xf0
#define USBDRD_UCTL_SPARE1 0xf8
-/* UAHC Configuration Register */
-union cvm_usbdrd_uctl_host_cfg {
- uint64_t u64;
- struct cvm_usbdrd_uctl_host_cfg_s {
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_60_63:4,
- /* Indicates minimum value of all received BELT values */
- __BITFIELD_FIELD(uint64_t host_current_belt:12,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_38_47:10,
- /* HS jitter adjustment */
- __BITFIELD_FIELD(uint64_t fla:6,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_29_31:3,
- /* Bus-master enable: 0x0 = Disabled (stall DMAs), 0x1 = enabled */
- __BITFIELD_FIELD(uint64_t bme:1,
- /* Overcurrent protection enable: 0x0 = unavailable, 0x1 = available */
- __BITFIELD_FIELD(uint64_t oci_en:1,
- /* Overcurrent sene selection:
- * 0x0 = Overcurrent indication from off-chip is active-low
- * 0x1 = Overcurrent indication from off-chip is active-high
- */
- __BITFIELD_FIELD(uint64_t oci_active_high_en:1,
- /* Port power control enable: 0x0 = unavailable, 0x1 = available */
- __BITFIELD_FIELD(uint64_t ppc_en:1,
- /* Port power control sense selection:
- * 0x0 = Port power to off-chip is active-low
- * 0x1 = Port power to off-chip is active-high
- */
- __BITFIELD_FIELD(uint64_t ppc_active_high_en:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_0_23:24,
- ;)))))))))))
- } s;
-};
-
/* UCTL Shim Features Register */
union cvm_usbdrd_uctl_shim_cfg {
uint64_t u64;
@@ -224,12 +213,13 @@ static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
static int dwc3_octeon_config_power(struct device *dev, u64 base)
{
- union cvm_usbdrd_uctl_host_cfg uctl_host_cfg;
union cvmx_gpio_bit_cfgx gpio_bit;
uint32_t gpio_pwr[3];
int gpio, len, power_active_low;
struct device_node *node = dev->of_node;
int index = (base >> 24) & 1;
+ u64 val;
+ u64 uctl_host_cfg_reg = base + USBDRD_UCTL_HOST_CFG;
if (of_find_property(node, "power", &len) != NULL) {
if (len == 12) {
@@ -264,16 +254,19 @@ static int dwc3_octeon_config_power(struct device *dev, u64 base)
}
/* Enable XHCI power control and set if active high or low. */
- uctl_host_cfg.u64 = cvmx_read_csr(base + USBDRD_UCTL_HOST_CFG);
- uctl_host_cfg.s.ppc_en = 1;
- uctl_host_cfg.s.ppc_active_high_en = !power_active_low;
- cvmx_write_csr(base + USBDRD_UCTL_HOST_CFG, uctl_host_cfg.u64);
+ val = cvmx_read_csr(uctl_host_cfg_reg);
+ val |= USBDRD_UCTL_HOST_PPC_EN;
+ if (power_active_low)
+ val &= ~USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
+ else
+ val |= USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
+ cvmx_write_csr(uctl_host_cfg_reg, val);
} else {
/* Disable XHCI power control and set if active high. */
- uctl_host_cfg.u64 = cvmx_read_csr(base + USBDRD_UCTL_HOST_CFG);
- uctl_host_cfg.s.ppc_en = 0;
- uctl_host_cfg.s.ppc_active_high_en = 0;
- cvmx_write_csr(base + USBDRD_UCTL_HOST_CFG, uctl_host_cfg.u64);
+ val = cvmx_read_csr(uctl_host_cfg_reg);
+ val &= ~USBDRD_UCTL_HOST_PPC_EN;
+ val &= ~USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
+ cvmx_write_csr(uctl_host_cfg_reg, val);
dev_info(dev, "power control disabled\n");
}
return 0;
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/11] MIPS: OCTEON: octeon-usb: use bitfields for shim register
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (2 preceding siblings ...)
2023-06-19 20:12 ` [PATCH 03/11] MIPS: OCTEON: octeon-usb: use bitfields for host config register Ladislav Michl
@ 2023-06-19 20:12 ` Ladislav Michl
2023-06-19 20:13 ` [PATCH 05/11] MIPS: OCTEON: octeon-usb: move gpio config to separate function Ladislav Michl
` (7 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:12 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Use Linux standard bitfield access macros to manipulate
shim register.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-usb.c | 96 ++++++++++++----------------
1 file changed, 41 insertions(+), 55 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index 17051aee491d..1c48ee77125a 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -152,57 +152,43 @@
*/
# define USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN BIT(24)
+/*
+ * UCTL Shim Features Register
+ */
#define USBDRD_UCTL_SHIM_CFG 0xe8
+/* Out-of-bound UAHC register access: 0 = read, 1 = write */
+# define USBDRD_UCTL_SHIM_CFG_XS_NCB_OOB_WRN BIT(63)
+/* SRCID error log for out-of-bound UAHC register access:
+ * [59:58] = chipID
+ * [57] = Request source: 0 = core, 1 = NCB-device
+ * [56:51] = Core/NCB-device number, [56] always 0 for NCB devices
+ * [50:48] = SubID
+ */
+# define USBDRD_UCTL_SHIM_CFG_XS_NCB_OOB_OSRC GENMASK(59, 48)
+/* Error log for bad UAHC DMA access: 0 = Read log, 1 = Write log */
+# define USBDRD_UCTL_SHIM_CFG_XM_BAD_DMA_WRN BIT(47)
+/* Encoded error type for bad UAHC DMA */
+# define USBDRD_UCTL_SHIM_CFG_XM_BAD_DMA_TYPE GENMASK(43, 40)
+/* Select the IOI read command used by DMA accesses */
+# define USBDRD_UCTL_SHIM_CFG_DMA_READ_CMD BIT(12)
+/* Select endian format for DMA accesses to the L2C:
+ * 0x0 = Little endian
+ * 0x1 = Big endian
+ * 0x2 = Reserved
+ * 0x3 = Reserved
+ */
+# define USBDRD_UCTL_SHIM_CFG_DMA_ENDIAN_MODE GENMASK(9, 8)
+/* Select endian format for IOI CSR access to UAHC:
+ * 0x0 = Little endian
+ * 0x1 = Big endian
+ * 0x2 = Reserved
+ * 0x3 = Reserved
+ */
+# define USBDRD_UCTL_SHIM_CFG_CSR_ENDIAN_MODE GENMASK(1, 0)
+
#define USBDRD_UCTL_ECC 0xf0
#define USBDRD_UCTL_SPARE1 0xf8
-/* UCTL Shim Features Register */
-union cvm_usbdrd_uctl_shim_cfg {
- uint64_t u64;
- struct cvm_usbdrd_uctl_shim_cfg_s {
- /* Out-of-bound UAHC register access: 0 = read, 1 = write */
- __BITFIELD_FIELD(uint64_t xs_ncb_oob_wrn:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_60_62:3,
- /* SRCID error log for out-of-bound UAHC register access:
- * [59:58] = chipID
- * [57] = Request source: 0 = core, 1 = NCB-device
- * [56:51] = Core/NCB-device number, [56] always 0 for NCB devices
- * [50:48] = SubID
- */
- __BITFIELD_FIELD(uint64_t xs_ncb_oob_osrc:12,
- /* Error log for bad UAHC DMA access: 0 = Read log, 1 = Write log */
- __BITFIELD_FIELD(uint64_t xm_bad_dma_wrn:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_44_46:3,
- /* Encoded error type for bad UAHC DMA */
- __BITFIELD_FIELD(uint64_t xm_bad_dma_type:4,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_13_39:27,
- /* Select the IOI read command used by DMA accesses */
- __BITFIELD_FIELD(uint64_t dma_read_cmd:1,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_10_11:2,
- /* Select endian format for DMA accesses to the L2c:
- * 0x0 = Little endian
- *` 0x1 = Big endian
- * 0x2 = Reserved
- * 0x3 = Reserved
- */
- __BITFIELD_FIELD(uint64_t dma_endian_mode:2,
- /* Reserved */
- __BITFIELD_FIELD(uint64_t reserved_2_7:6,
- /* Select endian format for IOI CSR access to UAHC:
- * 0x0 = Little endian
- *` 0x1 = Big endian
- * 0x2 = Reserved
- * 0x3 = Reserved
- */
- __BITFIELD_FIELD(uint64_t csr_endian_mode:2,
- ;))))))))))))
- } s;
-};
-
#define OCTEON_H_CLKDIV_SEL 8
#define OCTEON_MIN_H_CLK_RATE 150000000
#define OCTEON_MAX_H_CLK_RATE 300000000
@@ -456,17 +442,17 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
static void __init dwc3_octeon_set_endian_mode(u64 base)
{
- union cvm_usbdrd_uctl_shim_cfg shim_cfg;
+ u64 val;
+ u64 uctl_shim_cfg_reg = base + USBDRD_UCTL_SHIM_CFG;
- shim_cfg.u64 = cvmx_read_csr(base + USBDRD_UCTL_SHIM_CFG);
+ val = cvmx_read_csr(uctl_shim_cfg_reg);
+ val &= ~USBDRD_UCTL_SHIM_CFG_DMA_ENDIAN_MODE;
+ val &= ~USBDRD_UCTL_SHIM_CFG_CSR_ENDIAN_MODE;
#ifdef __BIG_ENDIAN
- shim_cfg.s.dma_endian_mode = 1;
- shim_cfg.s.csr_endian_mode = 1;
-#else
- shim_cfg.s.dma_endian_mode = 0;
- shim_cfg.s.csr_endian_mode = 0;
+ val |= FIELD_PREP(USBDRD_UCTL_SHIM_CFG_DMA_ENDIAN_MODE, 1);
+ val |= FIELD_PREP(USBDRD_UCTL_SHIM_CFG_CSR_ENDIAN_MODE, 1);
#endif
- cvmx_write_csr(base + USBDRD_UCTL_SHIM_CFG, shim_cfg.u64);
+ cvmx_write_csr(uctl_shim_cfg_reg, val);
}
static void __init dwc3_octeon_phy_reset(u64 base)
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 05/11] MIPS: OCTEON: octeon-usb: move gpio config to separate function
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (3 preceding siblings ...)
2023-06-19 20:12 ` [PATCH 04/11] MIPS: OCTEON: octeon-usb: use bitfields for shim register Ladislav Michl
@ 2023-06-19 20:13 ` Ladislav Michl
2023-06-19 20:13 ` [PATCH 06/11] MIPS: OCTEON: octeon-usb: introduce dwc3_octeon_{read,write}q Ladislav Michl
` (6 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:13 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
Power gpio configuration is using Octeon specific code, so
move it to separate function, that can later be guarded
with ifdefs.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-usb.c | 45 +++++++++++++++-------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index 1c48ee77125a..0f9800b3d373 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -197,13 +197,35 @@ static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
-static int dwc3_octeon_config_power(struct device *dev, u64 base)
+static void dwc3_octeon_config_gpio(int index, int gpio)
{
union cvmx_gpio_bit_cfgx gpio_bit;
+
+ if ((OCTEON_IS_MODEL(OCTEON_CN73XX) ||
+ OCTEON_IS_MODEL(OCTEON_CNF75XX))
+ && gpio <= 31) {
+ gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(gpio));
+ gpio_bit.s.tx_oe = 1;
+ gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x15);
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(gpio), gpio_bit.u64);
+ } else if (gpio <= 15) {
+ gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(gpio));
+ gpio_bit.s.tx_oe = 1;
+ gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x19);
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(gpio), gpio_bit.u64);
+ } else {
+ gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_XBIT_CFGX(gpio));
+ gpio_bit.s.tx_oe = 1;
+ gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x19);
+ cvmx_write_csr(CVMX_GPIO_XBIT_CFGX(gpio), gpio_bit.u64);
+ }
+}
+
+static int dwc3_octeon_config_power(struct device *dev, u64 base)
+{
uint32_t gpio_pwr[3];
int gpio, len, power_active_low;
struct device_node *node = dev->of_node;
- int index = (base >> 24) & 1;
u64 val;
u64 uctl_host_cfg_reg = base + USBDRD_UCTL_HOST_CFG;
@@ -220,24 +242,7 @@ static int dwc3_octeon_config_power(struct device *dev, u64 base)
dev_err(dev, "invalid power configuration\n");
return -EINVAL;
}
- if ((OCTEON_IS_MODEL(OCTEON_CN73XX) ||
- OCTEON_IS_MODEL(OCTEON_CNF75XX))
- && gpio <= 31) {
- gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(gpio));
- gpio_bit.s.tx_oe = 1;
- gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x15);
- cvmx_write_csr(CVMX_GPIO_BIT_CFGX(gpio), gpio_bit.u64);
- } else if (gpio <= 15) {
- gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(gpio));
- gpio_bit.s.tx_oe = 1;
- gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x19);
- cvmx_write_csr(CVMX_GPIO_BIT_CFGX(gpio), gpio_bit.u64);
- } else {
- gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_XBIT_CFGX(gpio));
- gpio_bit.s.tx_oe = 1;
- gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x19);
- cvmx_write_csr(CVMX_GPIO_XBIT_CFGX(gpio), gpio_bit.u64);
- }
+ dwc3_octeon_config_gpio((base >> 24) & 1, gpio);
/* Enable XHCI power control and set if active high or low. */
val = cvmx_read_csr(uctl_host_cfg_reg);
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 06/11] MIPS: OCTEON: octeon-usb: introduce dwc3_octeon_{read,write}q
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (4 preceding siblings ...)
2023-06-19 20:13 ` [PATCH 05/11] MIPS: OCTEON: octeon-usb: move gpio config to separate function Ladislav Michl
@ 2023-06-19 20:13 ` Ladislav Michl
2023-06-19 20:14 ` [PATCH 07/11] MIPS: OCTEON: octeon-usb: cleanup divider calculation Ladislav Michl
` (5 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:13 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Move all register access code into separate functions and
provide their no-op version for non Octeon platforms.
Later it might be possible to replace them with standard
Linux functions, however datasheets are not publicly available
and I have only one Octeon board to test, so lets stay on safe
side for now.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-usb.c | 99 +++++++++++++++++-----------
1 file changed, 59 insertions(+), 40 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index 0f9800b3d373..aaddc874f0ca 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -17,8 +17,6 @@
#include <linux/mutex.h>
#include <linux/of_platform.h>
-#include <asm/octeon/octeon.h>
-
/*
* USB Control Register
*/
@@ -196,6 +194,17 @@
static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
+#ifdef CONFIG_CAVIUM_OCTEON_SOC
+#include <asm/octeon/octeon.h>
+static inline uint64_t dwc3_octeon_readq(void __iomem *addr)
+{
+ return cvmx_readq_csr(addr);
+}
+
+static inline void dwc3_octeon_writeq(void __iomem *base, uint64_t val)
+{
+ cvmx_writeq_csr(base, val);
+}
static void dwc3_octeon_config_gpio(int index, int gpio)
{
@@ -220,14 +229,24 @@ static void dwc3_octeon_config_gpio(int index, int gpio)
cvmx_write_csr(CVMX_GPIO_XBIT_CFGX(gpio), gpio_bit.u64);
}
}
+#else
+static inline uint64_t dwc3_octeon_readq(void __iomem *addr)
+{
+ return 0;
+}
+
+static inline void dwc3_octeon_writeq(void __iomem *base, uint64_t val) { }
+
+static inline void dwc3_octeon_config_gpio(int index, int gpio) { }
+#endif
-static int dwc3_octeon_config_power(struct device *dev, u64 base)
+static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
{
uint32_t gpio_pwr[3];
int gpio, len, power_active_low;
struct device_node *node = dev->of_node;
u64 val;
- u64 uctl_host_cfg_reg = base + USBDRD_UCTL_HOST_CFG;
+ void __iomem *uctl_host_cfg_reg = base + USBDRD_UCTL_HOST_CFG;
if (of_find_property(node, "power", &len) != NULL) {
if (len == 12) {
@@ -242,33 +261,33 @@ static int dwc3_octeon_config_power(struct device *dev, u64 base)
dev_err(dev, "invalid power configuration\n");
return -EINVAL;
}
- dwc3_octeon_config_gpio((base >> 24) & 1, gpio);
+ dwc3_octeon_config_gpio(((u64)base >> 24) & 1, gpio);
/* Enable XHCI power control and set if active high or low. */
- val = cvmx_read_csr(uctl_host_cfg_reg);
+ val = dwc3_octeon_readq(uctl_host_cfg_reg);
val |= USBDRD_UCTL_HOST_PPC_EN;
if (power_active_low)
val &= ~USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
else
val |= USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
- cvmx_write_csr(uctl_host_cfg_reg, val);
+ dwc3_octeon_writeq(uctl_host_cfg_reg, val);
} else {
/* Disable XHCI power control and set if active high. */
- val = cvmx_read_csr(uctl_host_cfg_reg);
+ val = dwc3_octeon_readq(uctl_host_cfg_reg);
val &= ~USBDRD_UCTL_HOST_PPC_EN;
val &= ~USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
- cvmx_write_csr(uctl_host_cfg_reg, val);
+ dwc3_octeon_writeq(uctl_host_cfg_reg, val);
dev_info(dev, "power control disabled\n");
}
return 0;
}
-static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
+static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
{
int i, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
u32 clock_rate;
u64 div, h_clk_rate, val;
- u64 uctl_ctl_reg = base + USBDRD_UCTL_CTL;
+ void __iomem *uctl_ctl_reg = base + USBDRD_UCTL_CTL;
if (dev->of_node) {
const char *ss_clock_type;
@@ -332,16 +351,16 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
/* Step 2: Select GPIO for overcurrent indication, if desired. SKIP */
/* Step 3: Assert all resets. */
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val |= USBDRD_UCTL_CTL_UPHY_RST |
USBDRD_UCTL_CTL_UAHC_RST |
USBDRD_UCTL_CTL_UCTL_RST;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 4a: Reset the clock dividers. */
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val |= USBDRD_UCTL_CTL_H_CLKDIV_RST;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 4b: Select controller clock frequency. */
for (div = 0; div < OCTEON_H_CLKDIV_SEL; div++) {
@@ -350,12 +369,12 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
h_clk_rate >= OCTEON_MIN_H_CLK_RATE)
break;
}
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_H_CLKDIV_SEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_H_CLKDIV_SEL, div);
val |= USBDRD_UCTL_CTL_H_CLK_EN;
- cvmx_write_csr(uctl_ctl_reg, val);
- val = cvmx_read_csr(uctl_ctl_reg);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
if ((div != FIELD_GET(USBDRD_UCTL_CTL_H_CLKDIV_SEL, val)) ||
(!(FIELD_GET(USBDRD_UCTL_CTL_H_CLK_EN, val)))) {
dev_err(dev, "dwc3 controller clock init failure.\n");
@@ -364,10 +383,10 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
/* Step 4c: Deassert the controller clock divider reset. */
val &= ~USBDRD_UCTL_CTL_H_CLKDIV_RST;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 5a: Reference clock configuration. */
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_REF_CLK_DIV2;
val &= ~USBDRD_UCTL_CTL_REF_CLK_SEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_SEL, ref_clk_sel);
@@ -407,15 +426,15 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
/* Step 6a & 6b: Power up PHYs. */
val |= USBDRD_UCTL_CTL_HS_POWER_EN;
val |= USBDRD_UCTL_CTL_SS_POWER_EN;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 7: Wait 10 controller-clock cycles to take effect. */
udelay(10);
/* Step 8a: Deassert UCTL reset signal. */
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_UCTL_RST;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 8b: Wait 10 controller-clock cycles. */
udelay(10);
@@ -425,49 +444,49 @@ static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
return -EINVAL;
/* Step 8d: Deassert UAHC reset signal. */
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_UAHC_RST;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 8e: Wait 10 controller-clock cycles. */
udelay(10);
/* Step 9: Enable conditional coprocessor clock of UCTL. */
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val |= USBDRD_UCTL_CTL_CSCLK_EN;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
/*Step 10: Set for host mode only. */
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_DRD_MODE;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
return 0;
}
-static void __init dwc3_octeon_set_endian_mode(u64 base)
+static void __init dwc3_octeon_set_endian_mode(void __iomem *base)
{
u64 val;
- u64 uctl_shim_cfg_reg = base + USBDRD_UCTL_SHIM_CFG;
+ void __iomem *uctl_shim_cfg_reg = base + USBDRD_UCTL_SHIM_CFG;
- val = cvmx_read_csr(uctl_shim_cfg_reg);
+ val = dwc3_octeon_readq(uctl_shim_cfg_reg);
val &= ~USBDRD_UCTL_SHIM_CFG_DMA_ENDIAN_MODE;
val &= ~USBDRD_UCTL_SHIM_CFG_CSR_ENDIAN_MODE;
#ifdef __BIG_ENDIAN
val |= FIELD_PREP(USBDRD_UCTL_SHIM_CFG_DMA_ENDIAN_MODE, 1);
val |= FIELD_PREP(USBDRD_UCTL_SHIM_CFG_CSR_ENDIAN_MODE, 1);
#endif
- cvmx_write_csr(uctl_shim_cfg_reg, val);
+ dwc3_octeon_writeq(uctl_shim_cfg_reg, val);
}
-static void __init dwc3_octeon_phy_reset(u64 base)
+static void __init dwc3_octeon_phy_reset(void __iomem *base)
{
u64 val;
- u64 uctl_ctl_reg = base + USBDRD_UCTL_CTL;
+ void __iomem *uctl_ctl_reg = base + USBDRD_UCTL_CTL;
- val = cvmx_read_csr(uctl_ctl_reg);
+ val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_UPHY_RST;
- cvmx_write_csr(uctl_ctl_reg, val);
+ dwc3_octeon_writeq(uctl_ctl_reg, val);
}
static int __init dwc3_octeon_device_init(void)
@@ -506,10 +525,10 @@ static int __init dwc3_octeon_device_init(void)
}
mutex_lock(&dwc3_octeon_clocks_mutex);
- if (dwc3_octeon_clocks_start(&pdev->dev, (u64)base) == 0)
+ if (dwc3_octeon_clocks_start(&pdev->dev, base) == 0)
dev_info(&pdev->dev, "clocks initialized.\n");
- dwc3_octeon_set_endian_mode((u64)base);
- dwc3_octeon_phy_reset((u64)base);
+ dwc3_octeon_set_endian_mode(base);
+ dwc3_octeon_phy_reset(base);
mutex_unlock(&dwc3_octeon_clocks_mutex);
devm_iounmap(&pdev->dev, base);
devm_release_mem_region(&pdev->dev, res->start,
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 07/11] MIPS: OCTEON: octeon-usb: cleanup divider calculation
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (5 preceding siblings ...)
2023-06-19 20:13 ` [PATCH 06/11] MIPS: OCTEON: octeon-usb: introduce dwc3_octeon_{read,write}q Ladislav Michl
@ 2023-06-19 20:14 ` Ladislav Michl
2023-06-19 20:14 ` [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips Ladislav Michl
` (4 subsequent siblings)
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:14 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Simple self-contained function is easier to review.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-usb.c | 31 ++++++++++++++++------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index aaddc874f0ca..2add435ad038 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -187,12 +187,7 @@
#define USBDRD_UCTL_ECC 0xf0
#define USBDRD_UCTL_SPARE1 0xf8
-#define OCTEON_H_CLKDIV_SEL 8
-#define OCTEON_MIN_H_CLK_RATE 150000000
-#define OCTEON_MAX_H_CLK_RATE 300000000
-
static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
-static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
#ifdef CONFIG_CAVIUM_OCTEON_SOC
#include <asm/octeon/octeon.h>
@@ -240,6 +235,21 @@ static inline void dwc3_octeon_writeq(void __iomem *base, uint64_t val) { }
static inline void dwc3_octeon_config_gpio(int index, int gpio) { }
#endif
+static int dwc3_octeon_get_divider(void)
+{
+ static const uint8_t clk_div[] = { 1, 2, 4, 6, 8, 16, 24, 32 };
+ int div = 0;
+
+ while (div < ARRAY_SIZE(clk_div)) {
+ uint64_t rate = octeon_get_io_clock_rate() / clk_div[div];
+ if (rate <= 300000000 && rate >= 150000000)
+ break;
+ div++;
+ }
+
+ return div;
+}
+
static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
{
uint32_t gpio_pwr[3];
@@ -284,9 +294,9 @@ static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
{
- int i, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
+ int i, div, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
u32 clock_rate;
- u64 div, h_clk_rate, val;
+ u64 val;
void __iomem *uctl_ctl_reg = base + USBDRD_UCTL_CTL;
if (dev->of_node) {
@@ -363,12 +373,7 @@ static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 4b: Select controller clock frequency. */
- for (div = 0; div < OCTEON_H_CLKDIV_SEL; div++) {
- h_clk_rate = octeon_get_io_clock_rate() / clk_div[div];
- if (h_clk_rate <= OCTEON_MAX_H_CLK_RATE &&
- h_clk_rate >= OCTEON_MIN_H_CLK_RATE)
- break;
- }
+ div = dwc3_octeon_get_divider();
val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_H_CLKDIV_SEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_H_CLKDIV_SEL, div);
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (6 preceding siblings ...)
2023-06-19 20:14 ` [PATCH 07/11] MIPS: OCTEON: octeon-usb: cleanup divider calculation Ladislav Michl
@ 2023-06-19 20:14 ` Ladislav Michl
2023-06-23 13:15 ` Thomas Bogendoerfer
2023-06-30 22:32 ` Thinh Nguyen
2023-06-19 20:15 ` [PATCH 09/11] usb: dwc3: dwc3-octeon: Convert to glue driver Ladislav Michl
` (3 subsequent siblings)
11 siblings, 2 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:14 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Octeon DWC3 glue code now compiles on all platforms, so move
it to drivers/usb/dwc3. No functional changes.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/Makefile | 1 -
drivers/usb/dwc3/Kconfig | 9 +++++++++
drivers/usb/dwc3/Makefile | 1 +
.../octeon-usb.c => drivers/usb/dwc3/dwc3-octeon.c | 0
4 files changed, 10 insertions(+), 1 deletion(-)
rename arch/mips/cavium-octeon/octeon-usb.c => drivers/usb/dwc3/dwc3-octeon.c (100%)
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 7c02e542959a..2a5926578841 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -18,4 +18,3 @@ obj-y += crypto/
obj-$(CONFIG_MTD) += flash_setup.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o
-obj-$(CONFIG_USB) += octeon-usb.o
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index be954a9abbe0..8fc7b7ff7f16 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -168,4 +168,13 @@ config USB_DWC3_AM62
The Designware Core USB3 IP is programmed to operate in
in USB 2.0 mode only.
Say 'Y' or 'M' here if you have one such device
+
+config USB_DWC3_OCTEON
+ tristate "Cavium Octeon Platforms"
+ depends on CAVIUM_OCTEON_SOC || COMPILE_TEST
+ default USB_DWC3
+ help
+ Support Cavium Octeon platforms with DesignWare Core USB3 IP.
+ Say 'Y' or 'M' here if you have one such device.
+
endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 9f66bd82b639..fe1493d4bbe5 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o
obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o
obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o
+obj-$(CONFIG_USB_DWC3_OCTEON) += dwc3-octeon.o
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/drivers/usb/dwc3/dwc3-octeon.c
similarity index 100%
rename from arch/mips/cavium-octeon/octeon-usb.c
rename to drivers/usb/dwc3/dwc3-octeon.c
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 09/11] usb: dwc3: dwc3-octeon: Convert to glue driver
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (7 preceding siblings ...)
2023-06-19 20:14 ` [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips Ladislav Michl
@ 2023-06-19 20:15 ` Ladislav Michl
2023-06-30 23:25 ` Thinh Nguyen
2023-06-19 20:15 ` [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe Ladislav Michl
` (2 subsequent siblings)
11 siblings, 1 reply; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:15 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Use Octeon specific DWC3 glue instead of dwc3-of-simple.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/mips/cavium-octeon/octeon-platform.c | 1 -
drivers/usb/dwc3/dwc3-octeon.c | 100 +++++++++++-----------
drivers/usb/dwc3/dwc3-of-simple.c | 1 -
3 files changed, 52 insertions(+), 50 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index ce05c0dd3acd..235c77ce7b18 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -450,7 +450,6 @@ static const struct of_device_id octeon_ids[] __initconst = {
{ .compatible = "cavium,octeon-3860-bootbus", },
{ .compatible = "cavium,mdio-mux", },
{ .compatible = "gpio-leds", },
- { .compatible = "cavium,octeon-7130-usb-uctl", },
{},
};
diff --git a/drivers/usb/dwc3/dwc3-octeon.c b/drivers/usb/dwc3/dwc3-octeon.c
index 2add435ad038..3ebcf2a61233 100644
--- a/drivers/usb/dwc3/dwc3-octeon.c
+++ b/drivers/usb/dwc3/dwc3-octeon.c
@@ -187,7 +187,10 @@
#define USBDRD_UCTL_ECC 0xf0
#define USBDRD_UCTL_SPARE1 0xf8
-static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
+struct dwc3_data {
+ struct device *dev;
+ void __iomem *base;
+};
#ifdef CONFIG_CAVIUM_OCTEON_SOC
#include <asm/octeon/octeon.h>
@@ -494,58 +499,57 @@ static void __init dwc3_octeon_phy_reset(void __iomem *base)
dwc3_octeon_writeq(uctl_ctl_reg, val);
}
-static int __init dwc3_octeon_device_init(void)
+static int dwc3_octeon_probe(struct platform_device *pdev)
{
- const char compat_node_name[] = "cavium,octeon-7130-usb-uctl";
- struct platform_device *pdev;
- struct device_node *node;
- struct resource *res;
- void __iomem *base;
+ struct device *dev = &pdev->dev;
+ struct dwc3_data *data;
+ int err;
- /*
- * There should only be three universal controllers, "uctl"
- * in the device tree. Two USB and a SATA, which we ignore.
- */
- node = NULL;
- do {
- node = of_find_node_by_name(node, "uctl");
- if (!node)
- return -ENODEV;
-
- if (of_device_is_compatible(node, compat_node_name)) {
- pdev = of_find_device_by_node(node);
- if (!pdev)
- return -ENODEV;
-
- /*
- * The code below maps in the registers necessary for
- * setting up the clocks and reseting PHYs. We must
- * release the resources so the dwc3 subsystem doesn't
- * know the difference.
- */
- base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(base)) {
- put_device(&pdev->dev);
- return PTR_ERR(base);
- }
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- mutex_lock(&dwc3_octeon_clocks_mutex);
- if (dwc3_octeon_clocks_start(&pdev->dev, base) == 0)
- dev_info(&pdev->dev, "clocks initialized.\n");
- dwc3_octeon_set_endian_mode(base);
- dwc3_octeon_phy_reset(base);
- mutex_unlock(&dwc3_octeon_clocks_mutex);
- devm_iounmap(&pdev->dev, base);
- devm_release_mem_region(&pdev->dev, res->start,
- resource_size(res));
- put_device(&pdev->dev);
- }
- } while (node != NULL);
+ data->dev = dev;
+ platform_set_drvdata(pdev, data);
- return 0;
+ data->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(data->base))
+ return PTR_ERR(data->base);
+
+ err = dwc3_octeon_clocks_start(dev, data->base);
+ if (err)
+ return err;
+
+ dwc3_octeon_set_endian_mode(data->base);
+ dwc3_octeon_phy_reset(data->base);
+
+ return of_platform_populate(node, NULL, NULL, dev);
+}
+
+static void dwc3_octeon_remove(struct platform_device *pdev)
+{
+ struct dwc3_data *data = platform_get_drvdata(pdev);
+
+ of_platform_depopulate(data->dev);
}
-device_initcall(dwc3_octeon_device_init);
+static const struct of_device_id dwc3_octeon_of_match[] = {
+ { .compatible = "cavium,octeon-7130-usb-uctl" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, dwc3_octeon_of_match);
+
+static struct platform_driver dwc3_octeon_driver = {
+ .probe = dwc3_octeon_probe,
+ .remove_new = dwc3_octeon_remove,
+ .driver = {
+ .name = "dwc3-octeon",
+ .of_match_table = dwc3_octeon_of_match,
+ },
+};
+module_platform_driver(dwc3_octeon_driver);
+
+MODULE_ALIAS("platform:dwc3-octeon");
MODULE_AUTHOR("David Daney <david.daney@cavium.com>");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("USB driver for OCTEON III SoC");
+MODULE_DESCRIPTION("DesignWare USB3 OCTEON III Glue Layer");
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c
index 71fd620c5161..e3423fbea3ed 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
static const struct of_device_id of_dwc3_simple_match[] = {
{ .compatible = "rockchip,rk3399-dwc3" },
- { .compatible = "cavium,octeon-7130-usb-uctl" },
{ .compatible = "sprd,sc9860-dwc3" },
{ .compatible = "allwinner,sun50i-h6-dwc3" },
{ .compatible = "hisilicon,hi3670-dwc3" },
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (8 preceding siblings ...)
2023-06-19 20:15 ` [PATCH 09/11] usb: dwc3: dwc3-octeon: Convert to glue driver Ladislav Michl
@ 2023-06-19 20:15 ` Ladislav Michl
2023-06-30 23:27 ` Thinh Nguyen
2023-07-01 5:49 ` kernel test robot
2023-06-19 20:16 ` [PATCH 11/11] usb: dwc3: Add SPDX header and copyright Ladislav Michl
2023-06-22 23:01 ` [PATCH 00/11] Cleanup Octeon DWC3 glue code Thinh Nguyen
11 siblings, 2 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:15 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
Make dwc3_octeon_clocks_start just start the clocks.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
drivers/usb/dwc3/dwc3-octeon.c | 150 ++++++++++++++++-----------------
1 file changed, 71 insertions(+), 79 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-octeon.c b/drivers/usb/dwc3/dwc3-octeon.c
index 3ebcf2a61233..4ad2d8887cf0 100644
--- a/drivers/usb/dwc3/dwc3-octeon.c
+++ b/drivers/usb/dwc3/dwc3-octeon.c
@@ -295,67 +295,14 @@ static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
return 0;
}
-static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
+static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base,
+ int ref_clk_sel, int ref_clk_fsel,
+ int mpll_mul)
{
- int i, div, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
- u32 clock_rate;
+ int div;
u64 val;
void __iomem *uctl_ctl_reg = base + USBDRD_UCTL_CTL;
- if (dev->of_node) {
- const char *ss_clock_type;
- const char *hs_clock_type;
-
- i = of_property_read_u32(dev->of_node,
- "refclk-frequency", &clock_rate);
- if (i) {
- dev_err(dev, "No UCTL \"refclk-frequency\"\n");
- return -EINVAL;
- }
- i = of_property_read_string(dev->of_node,
- "refclk-type-ss", &ss_clock_type);
- if (i) {
- dev_err(dev, "No UCTL \"refclk-type-ss\"\n");
- return -EINVAL;
- }
- i = of_property_read_string(dev->of_node,
- "refclk-type-hs", &hs_clock_type);
- if (i) {
- dev_err(dev, "No UCTL \"refclk-type-hs\"\n");
- return -EINVAL;
- }
- if (strcmp("dlmc_ref_clk0", ss_clock_type) == 0) {
- if (strcmp(hs_clock_type, "dlmc_ref_clk0") == 0)
- ref_clk_sel = 0;
- else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
- ref_clk_sel = 2;
- else
- dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
- hs_clock_type);
- } else if (strcmp(ss_clock_type, "dlmc_ref_clk1") == 0) {
- if (strcmp(hs_clock_type, "dlmc_ref_clk1") == 0)
- ref_clk_sel = 1;
- else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
- ref_clk_sel = 3;
- else {
- dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
- hs_clock_type);
- ref_clk_sel = 3;
- }
- } else
- dev_warn(dev, "Invalid SS clock type %s, using dlmc_ref_clk0 instead\n",
- ss_clock_type);
-
- if ((ref_clk_sel == 0 || ref_clk_sel == 1) &&
- (clock_rate != 100000000))
- dev_warn(dev, "Invalid UCTL clock rate of %u, using 100000000 instead\n",
- clock_rate);
-
- } else {
- dev_err(dev, "No USB UCTL device node\n");
- return -EINVAL;
- }
-
/*
* Step 1: Wait for all voltages to be stable...that surely
* happened before starting the kernel. SKIP
@@ -399,24 +346,6 @@ static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
val &= ~USBDRD_UCTL_CTL_REF_CLK_SEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_SEL, ref_clk_sel);
- ref_clk_fsel = 0x07;
- switch (clock_rate) {
- default:
- dev_warn(dev, "Invalid ref_clk %u, using 100000000 instead\n",
- clock_rate);
- fallthrough;
- case 100000000:
- mpll_mul = 0x19;
- if (ref_clk_sel < 2)
- ref_clk_fsel = 0x27;
- break;
- case 50000000:
- mpll_mul = 0x32;
- break;
- case 125000000:
- mpll_mul = 0x28;
- break;
- }
val &= ~USBDRD_UCTL_CTL_REF_CLK_FSEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_FSEL, ref_clk_fsel);
@@ -502,8 +429,72 @@ static void __init dwc3_octeon_phy_reset(void __iomem *base)
static int dwc3_octeon_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
struct dwc3_data *data;
- int err;
+ int err, ref_clk_sel, ref_clk_fsel, mpll_mul;
+ uint32_t clock_rate;
+ const char *hs_clock_type, *ss_clock_type;
+
+ if (!node) {
+ dev_err(dev, "No USB UCTL device node\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(node, "refclk-frequency", &clock_rate)) {
+ dev_err(dev, "No UCTL \"refclk-frequency\"\n");
+ return -EINVAL;
+ }
+ if (of_property_read_string(node, "refclk-type-ss", &ss_clock_type)) {
+ dev_err(dev, "No UCTL \"refclk-type-ss\"\n");
+ return -EINVAL;
+ }
+ if (of_property_read_string(node, "refclk-type-hs", &hs_clock_type)) {
+ dev_err(dev, "No UCTL \"refclk-type-hs\"\n");
+ return -EINVAL;
+ }
+
+ ref_clk_sel = 2;
+ if (strcmp("dlmc_ref_clk0", ss_clock_type) == 0) {
+ if (strcmp(hs_clock_type, "dlmc_ref_clk0") == 0)
+ ref_clk_sel = 0;
+ else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
+ ref_clk_sel = 2;
+ else
+ dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
+ hs_clock_type);
+ } else if (strcmp(ss_clock_type, "dlmc_ref_clk1") == 0) {
+ if (strcmp(hs_clock_type, "dlmc_ref_clk1") == 0)
+ ref_clk_sel = 1;
+ else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
+ ref_clk_sel = 3;
+ else {
+ dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
+ hs_clock_type);
+ ref_clk_sel = 3;
+ }
+ } else {
+ dev_warn(dev, "Invalid SS clock type %s, using dlmc_ref_clk0 instead\n",
+ ss_clock_type);
+ }
+
+ ref_clk_fsel = 0x07;
+ switch (clock_rate) {
+ default:
+ dev_warn(dev, "Invalid ref_clk %u, using 100000000 instead\n",
+ clock_rate);
+ fallthrough;
+ case 100000000:
+ mpll_mul = 0x19;
+ if (ref_clk_sel < 2)
+ ref_clk_fsel = 0x27;
+ break;
+ case 50000000:
+ mpll_mul = 0x32;
+ break;
+ case 125000000:
+ mpll_mul = 0x28;
+ break;
+ }
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -516,7 +507,8 @@ static int dwc3_octeon_probe(struct platform_device *pdev)
if (IS_ERR(data->base))
return PTR_ERR(data->base);
- err = dwc3_octeon_clocks_start(dev, data->base);
+ err = dwc3_octeon_clocks_start(dev, data->base,
+ ref_clk_sel, ref_clk_fsel, mpll_mul);
if (err)
return err;
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 11/11] usb: dwc3: Add SPDX header and copyright
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (9 preceding siblings ...)
2023-06-19 20:15 ` [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe Ladislav Michl
@ 2023-06-19 20:16 ` Ladislav Michl
2023-06-22 23:01 ` [PATCH 00/11] Cleanup Octeon DWC3 glue code Thinh Nguyen
11 siblings, 0 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-19 20:16 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb, linux-mips
From: Ladislav Michl <ladis@linux-mips.org>
As driver is rewritten and David no longer works for Marvell (Cavium),
I'm to blame for breakage.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
drivers/usb/dwc3/dwc3-octeon.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-octeon.c b/drivers/usb/dwc3/dwc3-octeon.c
index 4ad2d8887cf0..1776bbaf28c0 100644
--- a/drivers/usb/dwc3/dwc3-octeon.c
+++ b/drivers/usb/dwc3/dwc3-octeon.c
@@ -1,11 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
- * XHCI HCD glue for Cavium Octeon III SOCs.
+ * DWC3 glue for Cavium Octeon III SOCs.
*
* Copyright (C) 2010-2017 Cavium Networks
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
+ * Copyright (C) 2023 Ladislav Michl <ladis@linux-mips.org>
*/
#include <linux/bitfield.h>
@@ -542,6 +540,6 @@ static struct platform_driver dwc3_octeon_driver = {
module_platform_driver(dwc3_octeon_driver);
MODULE_ALIAS("platform:dwc3-octeon");
-MODULE_AUTHOR("David Daney <david.daney@cavium.com>");
+MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("DesignWare USB3 OCTEON III Glue Layer");
--
2.39.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
` (10 preceding siblings ...)
2023-06-19 20:16 ` [PATCH 11/11] usb: dwc3: Add SPDX header and copyright Ladislav Michl
@ 2023-06-22 23:01 ` Thinh Nguyen
2023-06-23 7:57 ` Ladislav Michl
11 siblings, 1 reply; 27+ messages in thread
From: Thinh Nguyen @ 2023-06-22 23:01 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
Hi,
On Mon, Jun 19, 2023, Ladislav Michl wrote:
> Hi,
>
> primary motivation was to fix issue Id 29206 as described in
> OCTEON III CN70XX/CN71XX Known Issues, version: 1.9.
> Said document is marked as Marvell Proprietary and Confidential,
> therefore I'm not sure if I can cite from it.
>
> This probably does not matter too much as the root of the information
> listed there is a workaround being implemented in OCTEON SDK 3.1.2
> patch 7 and later in
> u-boot/drivers/usb/host/xhci-octeon.c:dwc3_uphy_pll_reset()
>
> My coleague ported that patch to linux-4.9 and it is appended to
> this cover letter for a reference.
>
> The glue code currently lives in arch/mips/cavium-octeon/octeon-usb.c
> and loops for each "cavium,octeon-7130-usb-uctl" compatible.
> However there is no bond with dwc3 core code, so if anything goes
> wrong in glue code, the loop breaks, leaving dwc3 in reset.
>
> Later on when dwc3 core tries to read any device register, bus error
> is emited, leading to kernel panic.
>
> Therefore glue code is cleaned-up first, then moved to drivers/usb/dwc3
> and modified to match current state of art.
>
> Now it is easier to properly implement said errata. Does it belong
> to core code as a quirk? Comments and suggestions welcome.
>
> Ladislav Michl (11):
> MIPS: OCTEON: octeon-usb: add all register offsets
> MIPS: OCTEON: octeon-usb: use bitfields for control register
> MIPS: OCTEON: octeon-usb: use bitfields for host config register
> MIPS: OCTEON: octeon-usb: use bitfields for shim register
> MIPS: OCTEON: octeon-usb: move gpio config to separate function
> MIPS: OCTEON: octeon-usb: introduce dwc3_octeon_{read,write}q
> MIPS: OCTEON: octeon-usb: cleanup divider calculation
> usb: dwc3: Move Octeon glue code from arch/mips
> usb: dwc3: dwc3-octeon: Convert to glue driver
> usb: dwc3: dwc3-octeon: Move node parsing into driver probe
> usb: dwc3: Add SPDX header and copyright
>
> arch/mips/cavium-octeon/Makefile | 1 -
> arch/mips/cavium-octeon/octeon-platform.c | 1 -
> arch/mips/cavium-octeon/octeon-usb.c | 548 ----------------------
> drivers/usb/dwc3/Kconfig | 9 +
> drivers/usb/dwc3/Makefile | 1 +
> drivers/usb/dwc3/dwc3-octeon.c | 545 +++++++++++++++++++++
> drivers/usb/dwc3/dwc3-of-simple.c | 1 -
> 7 files changed, 555 insertions(+), 551 deletions(-)
> delete mode 100644 arch/mips/cavium-octeon/octeon-usb.c
> create mode 100644 drivers/usb/dwc3/dwc3-octeon.c
>
> ---
Please use get_maintainer.pl to get all the proper maintainers to review
the changes.
Since this is a large change involving different subsystems, if
possible, please split the changes related to MIPS and try to upstream
those first as they will affect how dwc3 glue driver will look.
Thanks,
Thinh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-22 23:01 ` [PATCH 00/11] Cleanup Octeon DWC3 glue code Thinh Nguyen
@ 2023-06-23 7:57 ` Ladislav Michl
2023-06-23 13:14 ` Thomas Bogendoerfer
2023-06-23 23:24 ` Thinh Nguyen
0 siblings, 2 replies; 27+ messages in thread
From: Ladislav Michl @ 2023-06-23 7:57 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb@vger.kernel.org, linux-mips@vger.kernel.org
Hi,
On Thu, Jun 22, 2023 at 11:01:54PM +0000, Thinh Nguyen wrote:
> Hi,
[snip]
> Please use get_maintainer.pl to get all the proper maintainers to review
> the changes.
That's what I did. Thomas, MIPS maintainer is reading linux-mips list,
Greg is reading linux-usb list, you were the one who receives changes,
hence all patcheset was sent to you in a hope you provide some comments
about actual code changes.
> Since this is a large change involving different subsystems, if
> possible, please split the changes related to MIPS and try to upstream
> those first as they will affect how dwc3 glue driver will look.
That's pretty straightforward as patchset is arranged exactly this way,
so MIPS maintainer is free to apply patches till driver move.
However, any actual feedback would be still usefull. In case it gets
some acks I'll add them and rebase patches to the latest -next.
> Thanks,
> Thinh
Thanks,
ladis
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-23 7:57 ` Ladislav Michl
@ 2023-06-23 13:14 ` Thomas Bogendoerfer
2023-06-23 23:24 ` Thinh Nguyen
1 sibling, 0 replies; 27+ messages in thread
From: Thomas Bogendoerfer @ 2023-06-23 13:14 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
On Fri, Jun 23, 2023 at 09:57:07AM +0200, Ladislav Michl wrote:
> That's pretty straightforward as patchset is arranged exactly this way,
> so MIPS maintainer is free to apply patches till driver move.
just to get things moving I've applied patch 1-7 to mips-next.
If I should take the whole thing I need ACKs for it, otherwise
I'm going to add an Acked-by for the moving patch (patch 8), which
then could be accepted after next merge window.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips
2023-06-19 20:14 ` [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips Ladislav Michl
@ 2023-06-23 13:15 ` Thomas Bogendoerfer
2023-06-30 22:32 ` Thinh Nguyen
1 sibling, 0 replies; 27+ messages in thread
From: Thomas Bogendoerfer @ 2023-06-23 13:15 UTC (permalink / raw)
To: Ladislav Michl; +Cc: Thinh Nguyen, linux-usb, linux-mips
On Mon, Jun 19, 2023 at 10:14:36PM +0200, Ladislav Michl wrote:
> From: Ladislav Michl <ladis@linux-mips.org>
>
> Octeon DWC3 glue code now compiles on all platforms, so move
> it to drivers/usb/dwc3. No functional changes.
>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
> arch/mips/cavium-octeon/Makefile | 1 -
> drivers/usb/dwc3/Kconfig | 9 +++++++++
> drivers/usb/dwc3/Makefile | 1 +
> .../octeon-usb.c => drivers/usb/dwc3/dwc3-octeon.c | 0
> 4 files changed, 10 insertions(+), 1 deletion(-)
> rename arch/mips/cavium-octeon/octeon-usb.c => drivers/usb/dwc3/dwc3-octeon.c (100%)
Acked-By: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-23 7:57 ` Ladislav Michl
2023-06-23 13:14 ` Thomas Bogendoerfer
@ 2023-06-23 23:24 ` Thinh Nguyen
2023-06-24 13:04 ` Ladislav Michl
1 sibling, 1 reply; 27+ messages in thread
From: Thinh Nguyen @ 2023-06-23 23:24 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
On Fri, Jun 23, 2023, Ladislav Michl wrote:
> Hi,
>
> On Thu, Jun 22, 2023 at 11:01:54PM +0000, Thinh Nguyen wrote:
> > Hi,
> [snip]
> > Please use get_maintainer.pl to get all the proper maintainers to review
> > the changes.
>
> That's what I did. Thomas, MIPS maintainer is reading linux-mips list,
> Greg is reading linux-usb list, you were the one who receives changes,
> hence all patcheset was sent to you in a hope you provide some comments
> about actual code changes.
I can take a look at the changes. However, the patches were sent
directly To: me for patches related MIPS and no one else except the
linux-usb linux-mips (without Thomas), which doesn't look right.
I'm not familiar with the MIPS subsystem, but typically for the USB
mailing list, we capture all the emails generated from get_maintainer.pl
and include them To: and Cc: should they need attention to the changes.
Often we filter our emails based on whether it's directed toward us, at
least I do that. Also, we can't be sure if everyone still subscribes to
the corresponding mailing list.
>
> > Since this is a large change involving different subsystems, if
> > possible, please split the changes related to MIPS and try to upstream
> > those first as they will affect how dwc3 glue driver will look.
>
> That's pretty straightforward as patchset is arranged exactly this way,
> so MIPS maintainer is free to apply patches till driver move.
> However, any actual feedback would be still usefull. In case it gets
> some acks I'll add them and rebase patches to the latest -next.
>
Then that's good. If the MIPS maintainer approves all the MIPS related
changes and already pick them up, there should be no problem.
Thanks,
Thinh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-23 23:24 ` Thinh Nguyen
@ 2023-06-24 13:04 ` Ladislav Michl
2023-06-26 23:17 ` Thinh Nguyen
0 siblings, 1 reply; 27+ messages in thread
From: Ladislav Michl @ 2023-06-24 13:04 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb@vger.kernel.org, linux-mips@vger.kernel.org
Hi,
On Fri, Jun 23, 2023 at 11:24:24PM +0000, Thinh Nguyen wrote:
> On Fri, Jun 23, 2023, Ladislav Michl wrote:
> > Hi,
> >
> > On Thu, Jun 22, 2023 at 11:01:54PM +0000, Thinh Nguyen wrote:
> > > Hi,
> > [snip]
> > > Please use get_maintainer.pl to get all the proper maintainers to review
> > > the changes.
> >
> > That's what I did. Thomas, MIPS maintainer is reading linux-mips list,
> > Greg is reading linux-usb list, you were the one who receives changes,
> > hence all patcheset was sent to you in a hope you provide some comments
> > about actual code changes.
>
> I can take a look at the changes. However, the patches were sent
> directly To: me for patches related MIPS and no one else except the
> linux-usb linux-mips (without Thomas), which doesn't look right.
>
> I'm not familiar with the MIPS subsystem, but typically for the USB
> mailing list, we capture all the emails generated from get_maintainer.pl
> and include them To: and Cc: should they need attention to the changes.
> Often we filter our emails based on whether it's directed toward us, at
> least I do that. Also, we can't be sure if everyone still subscribes to
> the corresponding mailing list.
Did you run get_maintainer.pl yourself? Because here (for v6.3) I get:
$ ./scripts/get_maintainer.pl -f arch/mips/cavium-octeon/octeon-usb.c
Thomas Bogendoerfer <tsbogend@alpha.franken.de> (maintainer:MIPS,commit_signer:1/1=100%)
Ladislav Michl <ladis@linux-mips.org> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:20/20=100%,removed_lines:22/22=100%)
linux-mips@vger.kernel.org (open list:MIPS)
linux-kernel@vger.kernel.org (open list)
$ ./scripts/get_maintainer.pl -f drivers/usb/dwc3
Thinh Nguyen <Thinh.Nguyen@synopsys.com> (maintainer:DESIGNWARE USB3 DRD IP DRIVER)
Greg Kroah-Hartman <gregkh@linuxfoundation.org> (supporter:USB SUBSYSTEM)
linux-usb@vger.kernel.org (open list:DESIGNWARE USB3 DRD IP DRIVER)
linux-kernel@vger.kernel.org (open list)
So I have no clue who else should I add to Cc list...
> >
> > > Since this is a large change involving different subsystems, if
> > > possible, please split the changes related to MIPS and try to upstream
> > > those first as they will affect how dwc3 glue driver will look.
> >
> > That's pretty straightforward as patchset is arranged exactly this way,
> > so MIPS maintainer is free to apply patches till driver move.
> > However, any actual feedback would be still usefull. In case it gets
> > some acks I'll add them and rebase patches to the latest -next.
> >
>
> Then that's good. If the MIPS maintainer approves all the MIPS related
> changes and already pick them up, there should be no problem.
Well, remaining question is how to make it comfortable for you to take
changes. Patches 1-7 are in mips-next already, so I propose to wait until
they propagate upstream then I rebase remaining patches to whatever is
in linux-next.
Please note I added glue driver into Makefile and Kconfig at random
locations as I failed to find any logic here. If you have any preference
or want to sort those files alphabetically first for example, just let
me know and I'll add some cleanup patches before sending v2.
Also coleagues of mine meanwhile found that PLL indeed ocassionally
fails to lock, so workaround attached to cover letter is really needed.
Naturally it cannot sneak in as it is, so unless you have better idea
I'll just port it to recent driver state and we can start discussion
from there in a separate thread.
Thank you,
ladis
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-24 13:04 ` Ladislav Michl
@ 2023-06-26 23:17 ` Thinh Nguyen
2023-06-30 10:40 ` Ladislav Michl
0 siblings, 1 reply; 27+ messages in thread
From: Thinh Nguyen @ 2023-06-26 23:17 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
Hi,
On Sat, Jun 24, 2023, Ladislav Michl wrote:
> Hi,
>
> On Fri, Jun 23, 2023 at 11:24:24PM +0000, Thinh Nguyen wrote:
> > On Fri, Jun 23, 2023, Ladislav Michl wrote:
> > > Hi,
> > >
> > > On Thu, Jun 22, 2023 at 11:01:54PM +0000, Thinh Nguyen wrote:
> > > > Hi,
> > > [snip]
> > > > Please use get_maintainer.pl to get all the proper maintainers to review
> > > > the changes.
> > >
> > > That's what I did. Thomas, MIPS maintainer is reading linux-mips list,
> > > Greg is reading linux-usb list, you were the one who receives changes,
> > > hence all patcheset was sent to you in a hope you provide some comments
> > > about actual code changes.
> >
> > I can take a look at the changes. However, the patches were sent
> > directly To: me for patches related MIPS and no one else except the
> > linux-usb linux-mips (without Thomas), which doesn't look right.
> >
> > I'm not familiar with the MIPS subsystem, but typically for the USB
> > mailing list, we capture all the emails generated from get_maintainer.pl
> > and include them To: and Cc: should they need attention to the changes.
> > Often we filter our emails based on whether it's directed toward us, at
> > least I do that. Also, we can't be sure if everyone still subscribes to
> > the corresponding mailing list.
>
> Did you run get_maintainer.pl yourself? Because here (for v6.3) I get:
> $ ./scripts/get_maintainer.pl -f arch/mips/cavium-octeon/octeon-usb.c
> Thomas Bogendoerfer <tsbogend@alpha.franken.de> (maintainer:MIPS,commit_signer:1/1=100%)
> Ladislav Michl <ladis@linux-mips.org> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:20/20=100%,removed_lines:22/22=100%)
> linux-mips@vger.kernel.org (open list:MIPS)
> linux-kernel@vger.kernel.org (open list)
> $ ./scripts/get_maintainer.pl -f drivers/usb/dwc3
> Thinh Nguyen <Thinh.Nguyen@synopsys.com> (maintainer:DESIGNWARE USB3 DRD IP DRIVER)
> Greg Kroah-Hartman <gregkh@linuxfoundation.org> (supporter:USB SUBSYSTEM)
> linux-usb@vger.kernel.org (open list:DESIGNWARE USB3 DRD IP DRIVER)
> linux-kernel@vger.kernel.org (open list)
>
> So I have no clue who else should I add to Cc list...
For each patch, please include all the emails returned from
get_maintainer.pl including Greg's and Thomas's.
>
> > >
> > > > Since this is a large change involving different subsystems, if
> > > > possible, please split the changes related to MIPS and try to upstream
> > > > those first as they will affect how dwc3 glue driver will look.
> > >
> > > That's pretty straightforward as patchset is arranged exactly this way,
> > > so MIPS maintainer is free to apply patches till driver move.
> > > However, any actual feedback would be still usefull. In case it gets
> > > some acks I'll add them and rebase patches to the latest -next.
> > >
> >
> > Then that's good. If the MIPS maintainer approves all the MIPS related
> > changes and already pick them up, there should be no problem.
>
> Well, remaining question is how to make it comfortable for you to take
> changes. Patches 1-7 are in mips-next already, so I propose to wait until
> they propagate upstream then I rebase remaining patches to whatever is
> in linux-next.
Yes. Please rebase the remaining patches and resend them.
>
> Please note I added glue driver into Makefile and Kconfig at random
> locations as I failed to find any logic here. If you have any preference
> or want to sort those files alphabetically first for example, just let
> me know and I'll add some cleanup patches before sending v2.
Unfortunately there isn't really an order to them. What you did is fine.
>
> Also coleagues of mine meanwhile found that PLL indeed ocassionally
> fails to lock, so workaround attached to cover letter is really needed.
> Naturally it cannot sneak in as it is, so unless you have better idea
> I'll just port it to recent driver state and we can start discussion
> from there in a separate thread.
If this causes a regression, then please fix it before sending it in. If
it's a new found issue, you can create a fix patch at a later point.
Thanks,
Thinh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-26 23:17 ` Thinh Nguyen
@ 2023-06-30 10:40 ` Ladislav Michl
2023-06-30 21:45 ` Thinh Nguyen
0 siblings, 1 reply; 27+ messages in thread
From: Ladislav Michl @ 2023-06-30 10:40 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb@vger.kernel.org, linux-mips@vger.kernel.org
Hi,
On Mon, Jun 26, 2023 at 11:17:57PM +0000, Thinh Nguyen wrote:
> Hi,
[snip]
> For each patch, please include all the emails returned from
> get_maintainer.pl including Greg's and Thomas's.
I already explained why is Cc list constructed the way it is. Despite
formal rules, time is a scarce resource, so let's not draw people's
attention too early. Anyway, if you think there's something that
needs someone's special attention, you can still extend Cc list
yourself.
Before sending v2, maintainer's review or ack is needed. I already
collected Thomas' ack for a move, but have not read a single world
from you. Do you plan to do some actual review, so we can take next
step or are you willing to wait for a v2 which will add only
octeon_get_io_clock_rate stub for non Octeon builds (having clk api
would be nice here, but that's different story)?
Also, perhaps it would be reasonable to squash patches 8 and 9.
Which tree to you want it to be rebased against? Currently I'm at
linux.git master and changes were retested here.
I'd prefer to send fewer version if possible, so actual comments
on code would certainly help.
[snip]
> > Also coleagues of mine meanwhile found that PLL indeed ocassionally
> > fails to lock, so workaround attached to cover letter is really needed.
> > Naturally it cannot sneak in as it is, so unless you have better idea
> > I'll just port it to recent driver state and we can start discussion
> > from there in a separate thread.
>
> If this causes a regression, then please fix it before sending it in. If
> it's a new found issue, you can create a fix patch at a later point.
There are few problems with Octeon's DWC3 implementation and none of them
can be really solved without documentation. Here I come in trouble as
Sysnopsys tech support pointed to SoC manufacturer which no longer exists.
Cavium was bought by Marvell, dumped almost all the staff and those
still providing technical support were unable to find any revelant
documentation in past few months.
So unless that changes I can send only hackish patches which kinda
overcome issues found, but I do not think it is viable solution. That's
something I'll do at later point as you suggested and we'll see if an
acceptable solution pops up.
Thank you,
ladis
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/11] Cleanup Octeon DWC3 glue code
2023-06-30 10:40 ` Ladislav Michl
@ 2023-06-30 21:45 ` Thinh Nguyen
0 siblings, 0 replies; 27+ messages in thread
From: Thinh Nguyen @ 2023-06-30 21:45 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
Hi,
On Fri, Jun 30, 2023, Ladislav Michl wrote:
> Hi,
>
> On Mon, Jun 26, 2023 at 11:17:57PM +0000, Thinh Nguyen wrote:
> > Hi,
> [snip]
> > For each patch, please include all the emails returned from
> > get_maintainer.pl including Greg's and Thomas's.
>
> I already explained why is Cc list constructed the way it is. Despite
> formal rules, time is a scarce resource, so let's not draw people's
Now that doesn't sound fair that you think my resource is more
expendable. :)
> attention too early. Anyway, if you think there's something that
> needs someone's special attention, you can still extend Cc list
> yourself.
I'm just asking you to follow the submitting patch process and add the
appropriate maintainers on any code that they maintain. You just ignored
the get_maintainer.pl output and only added what you feel needed.
>
> Before sending v2, maintainer's review or ack is needed. I already
> collected Thomas' ack for a move, but have not read a single world
> from you. Do you plan to do some actual review, so we can take next
> step or are you willing to wait for a v2 which will add only
Please be patient, I'll get to your changes when I can, and I'm not the
only reviewer here. Your series isn't exactly small or easy to
understand for me to review quickly.
> octeon_get_io_clock_rate stub for non Octeon builds (having clk api
> would be nice here, but that's different story)?
>
> Also, perhaps it would be reasonable to squash patches 8 and 9.
> Which tree to you want it to be rebased against? Currently I'm at
> linux.git master and changes were retested here.
>
> I'd prefer to send fewer version if possible, so actual comments
> on code would certainly help.
Well, you can help me and other reviewers by submitting v2 with your
rebased changes. I think it's appropriate here given that this series
touches on 2 separate subsystems.
>
> [snip]
> > > Also coleagues of mine meanwhile found that PLL indeed ocassionally
> > > fails to lock, so workaround attached to cover letter is really needed.
> > > Naturally it cannot sneak in as it is, so unless you have better idea
> > > I'll just port it to recent driver state and we can start discussion
> > > from there in a separate thread.
> >
> > If this causes a regression, then please fix it before sending it in. If
> > it's a new found issue, you can create a fix patch at a later point.
>
> There are few problems with Octeon's DWC3 implementation and none of them
> can be really solved without documentation. Here I come in trouble as
> Sysnopsys tech support pointed to SoC manufacturer which no longer exists.
> Cavium was bought by Marvell, dumped almost all the staff and those
> still providing technical support were unable to find any revelant
> documentation in past few months.
This can be problematic...
>
> So unless that changes I can send only hackish patches which kinda
> overcome issues found, but I do not think it is viable solution. That's
> something I'll do at later point as you suggested and we'll see if an
> acceptable solution pops up.
>
If it's hackish because of the lacking of documentation, then just note
how you came to the solution in your patch is totally fine. There's
nothing else we can do in that case.
I notice that there are many magic numbers in your changes. I hope you
have documentations for them. I may need to make some assumption/skip
reviewing some areas because of that.
Thanks,
Thinh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips
2023-06-19 20:14 ` [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips Ladislav Michl
2023-06-23 13:15 ` Thomas Bogendoerfer
@ 2023-06-30 22:32 ` Thinh Nguyen
1 sibling, 0 replies; 27+ messages in thread
From: Thinh Nguyen @ 2023-06-30 22:32 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
On Mon, Jun 19, 2023, Ladislav Michl wrote:
> From: Ladislav Michl <ladis@linux-mips.org>
>
> Octeon DWC3 glue code now compiles on all platforms, so move
> it to drivers/usb/dwc3. No functional changes.
>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
> arch/mips/cavium-octeon/Makefile | 1 -
> drivers/usb/dwc3/Kconfig | 9 +++++++++
> drivers/usb/dwc3/Makefile | 1 +
> .../octeon-usb.c => drivers/usb/dwc3/dwc3-octeon.c | 0
> 4 files changed, 10 insertions(+), 1 deletion(-)
> rename arch/mips/cavium-octeon/octeon-usb.c => drivers/usb/dwc3/dwc3-octeon.c (100%)
>
> diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
> index 7c02e542959a..2a5926578841 100644
> --- a/arch/mips/cavium-octeon/Makefile
> +++ b/arch/mips/cavium-octeon/Makefile
> @@ -18,4 +18,3 @@ obj-y += crypto/
> obj-$(CONFIG_MTD) += flash_setup.o
> obj-$(CONFIG_SMP) += smp.o
> obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o
> -obj-$(CONFIG_USB) += octeon-usb.o
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index be954a9abbe0..8fc7b7ff7f16 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -168,4 +168,13 @@ config USB_DWC3_AM62
> The Designware Core USB3 IP is programmed to operate in
> in USB 2.0 mode only.
> Say 'Y' or 'M' here if you have one such device
> +
> +config USB_DWC3_OCTEON
> + tristate "Cavium Octeon Platforms"
> + depends on CAVIUM_OCTEON_SOC || COMPILE_TEST
> + default USB_DWC3
> + help
> + Support Cavium Octeon platforms with DesignWare Core USB3 IP.
> + Say 'Y' or 'M' here if you have one such device.
Is this for device, host, or DRD mode? Which IP (DWC_usb3 or DWC_usb31?)
and version is it? The more description the better.
Thanks,
Thinh
> +
> endif
> diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
> index 9f66bd82b639..fe1493d4bbe5 100644
> --- a/drivers/usb/dwc3/Makefile
> +++ b/drivers/usb/dwc3/Makefile
> @@ -54,3 +54,4 @@ obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o
> obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
> obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o
> obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o
> +obj-$(CONFIG_USB_DWC3_OCTEON) += dwc3-octeon.o
> diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/drivers/usb/dwc3/dwc3-octeon.c
> similarity index 100%
> rename from arch/mips/cavium-octeon/octeon-usb.c
> rename to drivers/usb/dwc3/dwc3-octeon.c
> --
> 2.39.2
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 09/11] usb: dwc3: dwc3-octeon: Convert to glue driver
2023-06-19 20:15 ` [PATCH 09/11] usb: dwc3: dwc3-octeon: Convert to glue driver Ladislav Michl
@ 2023-06-30 23:25 ` Thinh Nguyen
0 siblings, 0 replies; 27+ messages in thread
From: Thinh Nguyen @ 2023-06-30 23:25 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
On Mon, Jun 19, 2023, Ladislav Michl wrote:
> From: Ladislav Michl <ladis@linux-mips.org>
>
> Use Octeon specific DWC3 glue instead of dwc3-of-simple.
>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
> arch/mips/cavium-octeon/octeon-platform.c | 1 -
> drivers/usb/dwc3/dwc3-octeon.c | 100 +++++++++++-----------
> drivers/usb/dwc3/dwc3-of-simple.c | 1 -
> 3 files changed, 52 insertions(+), 50 deletions(-)
>
> diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
> index ce05c0dd3acd..235c77ce7b18 100644
> --- a/arch/mips/cavium-octeon/octeon-platform.c
> +++ b/arch/mips/cavium-octeon/octeon-platform.c
> @@ -450,7 +450,6 @@ static const struct of_device_id octeon_ids[] __initconst = {
> { .compatible = "cavium,octeon-3860-bootbus", },
> { .compatible = "cavium,mdio-mux", },
> { .compatible = "gpio-leds", },
> - { .compatible = "cavium,octeon-7130-usb-uctl", },
> {},
> };
>
> diff --git a/drivers/usb/dwc3/dwc3-octeon.c b/drivers/usb/dwc3/dwc3-octeon.c
> index 2add435ad038..3ebcf2a61233 100644
> --- a/drivers/usb/dwc3/dwc3-octeon.c
> +++ b/drivers/usb/dwc3/dwc3-octeon.c
> @@ -187,7 +187,10 @@
> #define USBDRD_UCTL_ECC 0xf0
> #define USBDRD_UCTL_SPARE1 0xf8
>
> -static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
> +struct dwc3_data {
> + struct device *dev;
> + void __iomem *base;
> +};
>
> #ifdef CONFIG_CAVIUM_OCTEON_SOC
> #include <asm/octeon/octeon.h>
> @@ -494,58 +499,57 @@ static void __init dwc3_octeon_phy_reset(void __iomem *base)
> dwc3_octeon_writeq(uctl_ctl_reg, val);
> }
>
> -static int __init dwc3_octeon_device_init(void)
> +static int dwc3_octeon_probe(struct platform_device *pdev)
> {
> - const char compat_node_name[] = "cavium,octeon-7130-usb-uctl";
> - struct platform_device *pdev;
> - struct device_node *node;
> - struct resource *res;
> - void __iomem *base;
> + struct device *dev = &pdev->dev;
> + struct dwc3_data *data;
> + int err;
>
> - /*
> - * There should only be three universal controllers, "uctl"
> - * in the device tree. Two USB and a SATA, which we ignore.
> - */
> - node = NULL;
> - do {
> - node = of_find_node_by_name(node, "uctl");
> - if (!node)
> - return -ENODEV;
> -
> - if (of_device_is_compatible(node, compat_node_name)) {
> - pdev = of_find_device_by_node(node);
> - if (!pdev)
> - return -ENODEV;
> -
> - /*
> - * The code below maps in the registers necessary for
> - * setting up the clocks and reseting PHYs. We must
> - * release the resources so the dwc3 subsystem doesn't
> - * know the difference.
> - */
> - base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> - if (IS_ERR(base)) {
> - put_device(&pdev->dev);
> - return PTR_ERR(base);
> - }
> + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
>
> - mutex_lock(&dwc3_octeon_clocks_mutex);
> - if (dwc3_octeon_clocks_start(&pdev->dev, base) == 0)
> - dev_info(&pdev->dev, "clocks initialized.\n");
> - dwc3_octeon_set_endian_mode(base);
> - dwc3_octeon_phy_reset(base);
> - mutex_unlock(&dwc3_octeon_clocks_mutex);
> - devm_iounmap(&pdev->dev, base);
> - devm_release_mem_region(&pdev->dev, res->start,
> - resource_size(res));
> - put_device(&pdev->dev);
> - }
> - } while (node != NULL);
> + data->dev = dev;
Set private data at the end of this probe function.
> + platform_set_drvdata(pdev, data);
>
> - return 0;
> + data->base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(data->base))
> + return PTR_ERR(data->base);
> +
> + err = dwc3_octeon_clocks_start(dev, data->base);
> + if (err)
> + return err;
> +
> + dwc3_octeon_set_endian_mode(data->base);
> + dwc3_octeon_phy_reset(data->base);
> +
> + return of_platform_populate(node, NULL, NULL, dev);
> +}
> +
> +static void dwc3_octeon_remove(struct platform_device *pdev)
> +{
> + struct dwc3_data *data = platform_get_drvdata(pdev);
> +
> + of_platform_depopulate(data->dev);
Clear private data here:
platform_set_drvdata(pdev, NULL);
> }
> -device_initcall(dwc3_octeon_device_init);
>
> +static const struct of_device_id dwc3_octeon_of_match[] = {
> + { .compatible = "cavium,octeon-7130-usb-uctl" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, dwc3_octeon_of_match);
> +
> +static struct platform_driver dwc3_octeon_driver = {
> + .probe = dwc3_octeon_probe,
> + .remove_new = dwc3_octeon_remove,
> + .driver = {
> + .name = "dwc3-octeon",
> + .of_match_table = dwc3_octeon_of_match,
> + },
> +};
> +module_platform_driver(dwc3_octeon_driver);
> +
> +MODULE_ALIAS("platform:dwc3-octeon");
> MODULE_AUTHOR("David Daney <david.daney@cavium.com>");
> MODULE_LICENSE("GPL");
> -MODULE_DESCRIPTION("USB driver for OCTEON III SoC");
> +MODULE_DESCRIPTION("DesignWare USB3 OCTEON III Glue Layer");
> diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c
> index 71fd620c5161..e3423fbea3ed 100644
> --- a/drivers/usb/dwc3/dwc3-of-simple.c
> +++ b/drivers/usb/dwc3/dwc3-of-simple.c
> @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
>
> static const struct of_device_id of_dwc3_simple_match[] = {
> { .compatible = "rockchip,rk3399-dwc3" },
> - { .compatible = "cavium,octeon-7130-usb-uctl" },
> { .compatible = "sprd,sc9860-dwc3" },
> { .compatible = "allwinner,sun50i-h6-dwc3" },
> { .compatible = "hisilicon,hi3670-dwc3" },
> --
> 2.39.2
>
BR,
Thinh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe
2023-06-19 20:15 ` [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe Ladislav Michl
@ 2023-06-30 23:27 ` Thinh Nguyen
2023-07-02 0:13 ` Ladislav Michl
2023-07-01 5:49 ` kernel test robot
1 sibling, 1 reply; 27+ messages in thread
From: Thinh Nguyen @ 2023-06-30 23:27 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
On Mon, Jun 19, 2023, Ladislav Michl wrote:
> From: Ladislav Michl <ladis@linux-mips.org>
>
> Make dwc3_octeon_clocks_start just start the clocks.
>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
> drivers/usb/dwc3/dwc3-octeon.c | 150 ++++++++++++++++-----------------
> 1 file changed, 71 insertions(+), 79 deletions(-)
>
> diff --git a/drivers/usb/dwc3/dwc3-octeon.c b/drivers/usb/dwc3/dwc3-octeon.c
> index 3ebcf2a61233..4ad2d8887cf0 100644
> --- a/drivers/usb/dwc3/dwc3-octeon.c
> +++ b/drivers/usb/dwc3/dwc3-octeon.c
> @@ -295,67 +295,14 @@ static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
> return 0;
> }
>
> -static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
> +static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base,
> + int ref_clk_sel, int ref_clk_fsel,
> + int mpll_mul)
> {
> - int i, div, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
> - u32 clock_rate;
> + int div;
> u64 val;
> void __iomem *uctl_ctl_reg = base + USBDRD_UCTL_CTL;
>
> - if (dev->of_node) {
> - const char *ss_clock_type;
> - const char *hs_clock_type;
> -
> - i = of_property_read_u32(dev->of_node,
> - "refclk-frequency", &clock_rate);
> - if (i) {
> - dev_err(dev, "No UCTL \"refclk-frequency\"\n");
> - return -EINVAL;
> - }
> - i = of_property_read_string(dev->of_node,
> - "refclk-type-ss", &ss_clock_type);
> - if (i) {
> - dev_err(dev, "No UCTL \"refclk-type-ss\"\n");
> - return -EINVAL;
> - }
> - i = of_property_read_string(dev->of_node,
> - "refclk-type-hs", &hs_clock_type);
> - if (i) {
> - dev_err(dev, "No UCTL \"refclk-type-hs\"\n");
> - return -EINVAL;
> - }
> - if (strcmp("dlmc_ref_clk0", ss_clock_type) == 0) {
> - if (strcmp(hs_clock_type, "dlmc_ref_clk0") == 0)
> - ref_clk_sel = 0;
> - else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
> - ref_clk_sel = 2;
> - else
> - dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
> - hs_clock_type);
> - } else if (strcmp(ss_clock_type, "dlmc_ref_clk1") == 0) {
> - if (strcmp(hs_clock_type, "dlmc_ref_clk1") == 0)
> - ref_clk_sel = 1;
> - else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
> - ref_clk_sel = 3;
> - else {
> - dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
> - hs_clock_type);
> - ref_clk_sel = 3;
> - }
> - } else
> - dev_warn(dev, "Invalid SS clock type %s, using dlmc_ref_clk0 instead\n",
> - ss_clock_type);
> -
> - if ((ref_clk_sel == 0 || ref_clk_sel == 1) &&
> - (clock_rate != 100000000))
> - dev_warn(dev, "Invalid UCTL clock rate of %u, using 100000000 instead\n",
> - clock_rate);
> -
> - } else {
> - dev_err(dev, "No USB UCTL device node\n");
> - return -EINVAL;
> - }
> -
> /*
> * Step 1: Wait for all voltages to be stable...that surely
> * happened before starting the kernel. SKIP
> @@ -399,24 +346,6 @@ static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
> val &= ~USBDRD_UCTL_CTL_REF_CLK_SEL;
> val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_SEL, ref_clk_sel);
>
> - ref_clk_fsel = 0x07;
> - switch (clock_rate) {
> - default:
> - dev_warn(dev, "Invalid ref_clk %u, using 100000000 instead\n",
> - clock_rate);
> - fallthrough;
> - case 100000000:
> - mpll_mul = 0x19;
> - if (ref_clk_sel < 2)
> - ref_clk_fsel = 0x27;
> - break;
> - case 50000000:
> - mpll_mul = 0x32;
> - break;
> - case 125000000:
> - mpll_mul = 0x28;
> - break;
> - }
> val &= ~USBDRD_UCTL_CTL_REF_CLK_FSEL;
> val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_FSEL, ref_clk_fsel);
>
> @@ -502,8 +429,72 @@ static void __init dwc3_octeon_phy_reset(void __iomem *base)
> static int dwc3_octeon_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> + struct device_node *node = dev->of_node;
> struct dwc3_data *data;
> - int err;
> + int err, ref_clk_sel, ref_clk_fsel, mpll_mul;
> + uint32_t clock_rate;
> + const char *hs_clock_type, *ss_clock_type;
> +
> + if (!node) {
> + dev_err(dev, "No USB UCTL device node\n");
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32(node, "refclk-frequency", &clock_rate)) {
> + dev_err(dev, "No UCTL \"refclk-frequency\"\n");
> + return -EINVAL;
> + }
> + if (of_property_read_string(node, "refclk-type-ss", &ss_clock_type)) {
> + dev_err(dev, "No UCTL \"refclk-type-ss\"\n");
> + return -EINVAL;
> + }
> + if (of_property_read_string(node, "refclk-type-hs", &hs_clock_type)) {
> + dev_err(dev, "No UCTL \"refclk-type-hs\"\n");
> + return -EINVAL;
> + }
> +
> + ref_clk_sel = 2;
Can we use macro instead of magic numbers?
> + if (strcmp("dlmc_ref_clk0", ss_clock_type) == 0) {
> + if (strcmp(hs_clock_type, "dlmc_ref_clk0") == 0)
> + ref_clk_sel = 0;
> + else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
> + ref_clk_sel = 2;
> + else
> + dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
> + hs_clock_type);
> + } else if (strcmp(ss_clock_type, "dlmc_ref_clk1") == 0) {
> + if (strcmp(hs_clock_type, "dlmc_ref_clk1") == 0)
> + ref_clk_sel = 1;
> + else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
> + ref_clk_sel = 3;
Please run checkpatch and fix minor formatting issues such as bracket
here.
> + else {
> + dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
> + hs_clock_type);
> + ref_clk_sel = 3;
> + }
> + } else {
> + dev_warn(dev, "Invalid SS clock type %s, using dlmc_ref_clk0 instead\n",
> + ss_clock_type);
> + }
> +
> + ref_clk_fsel = 0x07;
> + switch (clock_rate) {
> + default:
> + dev_warn(dev, "Invalid ref_clk %u, using 100000000 instead\n",
> + clock_rate);
> + fallthrough;
> + case 100000000:
> + mpll_mul = 0x19;
> + if (ref_clk_sel < 2)
> + ref_clk_fsel = 0x27;
> + break;
> + case 50000000:
> + mpll_mul = 0x32;
> + break;
> + case 125000000:
> + mpll_mul = 0x28;
> + break;
> + }
>
> data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> if (!data)
> @@ -516,7 +507,8 @@ static int dwc3_octeon_probe(struct platform_device *pdev)
> if (IS_ERR(data->base))
> return PTR_ERR(data->base);
>
> - err = dwc3_octeon_clocks_start(dev, data->base);
> + err = dwc3_octeon_clocks_start(dev, data->base,
> + ref_clk_sel, ref_clk_fsel, mpll_mul);
> if (err)
> return err;
>
> --
> 2.39.2
>
Thanks,
Thinh
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe
2023-06-19 20:15 ` [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe Ladislav Michl
2023-06-30 23:27 ` Thinh Nguyen
@ 2023-07-01 5:49 ` kernel test robot
1 sibling, 0 replies; 27+ messages in thread
From: kernel test robot @ 2023-07-01 5:49 UTC (permalink / raw)
To: Ladislav Michl, Thinh Nguyen; +Cc: oe-kbuild-all, linux-usb, linux-mips
Hi Ladislav,
kernel test robot noticed the following build warnings:
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on usb/usb-next usb/usb-linus westeri-thunderbolt/next v6.4]
[cannot apply to linus/master next-20230630]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ladislav-Michl/MIPS-OCTEON-octeon-usb-add-all-register-offsets/20230620-041822
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link: https://lore.kernel.org/r/ZJC3eK8QMxShyZDt%40lenoch
patch subject: [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe
config: mips-randconfig-r083-20230701 (https://download.01.org/0day-ci/archive/20230701/202307011354.M9asTVJw-lkp@intel.com/config)
compiler: mips64-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230701/202307011354.M9asTVJw-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202307011354.M9asTVJw-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> drivers/usb/dwc3/dwc3-octeon.c:277:43: sparse: sparse: cast removes address space '__iomem' of expression
vim +/__iomem +277 drivers/usb/dwc3/dwc3-octeon.c
d83bf20c53410d arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 255
3c47bbb8f554f8 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 256 static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 257 {
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 258 uint32_t gpio_pwr[3];
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 259 int gpio, len, power_active_low;
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 260 struct device_node *node = dev->of_node;
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 261 u64 val;
3c47bbb8f554f8 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 262 void __iomem *uctl_host_cfg_reg = base + USBDRD_UCTL_HOST_CFG;
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 263
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 264 if (of_find_property(node, "power", &len) != NULL) {
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 265 if (len == 12) {
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 266 of_property_read_u32_array(node, "power", gpio_pwr, 3);
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 267 power_active_low = gpio_pwr[2] & 0x01;
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 268 gpio = gpio_pwr[1];
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 269 } else if (len == 8) {
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 270 of_property_read_u32_array(node, "power", gpio_pwr, 2);
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 271 power_active_low = 0;
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 272 gpio = gpio_pwr[1];
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 273 } else {
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 274 dev_err(dev, "invalid power configuration\n");
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 275 return -EINVAL;
06df6469e3e1a1 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 276 }
3c47bbb8f554f8 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 @277 dwc3_octeon_config_gpio(((u64)base >> 24) & 1, gpio);
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 278
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 279 /* Enable XHCI power control and set if active high or low. */
3c47bbb8f554f8 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 280 val = dwc3_octeon_readq(uctl_host_cfg_reg);
52245e391fcf6c arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 281 val |= USBDRD_UCTL_HOST_PPC_EN;
52245e391fcf6c arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 282 if (power_active_low)
52245e391fcf6c arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 283 val &= ~USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
52245e391fcf6c arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 284 else
52245e391fcf6c arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 285 val |= USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
3c47bbb8f554f8 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 286 dwc3_octeon_writeq(uctl_host_cfg_reg, val);
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 287 } else {
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 288 /* Disable XHCI power control and set if active high. */
3c47bbb8f554f8 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 289 val = dwc3_octeon_readq(uctl_host_cfg_reg);
52245e391fcf6c arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 290 val &= ~USBDRD_UCTL_HOST_PPC_EN;
52245e391fcf6c arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 291 val &= ~USBDRD_UCTL_HOST_PPC_ACTIVE_HIGH_EN;
3c47bbb8f554f8 arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2023-06-19 292 dwc3_octeon_writeq(uctl_host_cfg_reg, val);
4a24f6e0cc17ba arch/mips/cavium-octeon/octeon-usb.c Ladislav Michl 2022-12-21 293 dev_info(dev, "power control disabled\n");
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 294 }
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 295 return 0;
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 296 }
93e502b3c2d44d arch/mips/cavium-octeon/octeon-usb.c Steven J. Hill 2017-01-25 297
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe
2023-06-30 23:27 ` Thinh Nguyen
@ 2023-07-02 0:13 ` Ladislav Michl
2023-07-05 22:55 ` Thinh Nguyen
0 siblings, 1 reply; 27+ messages in thread
From: Ladislav Michl @ 2023-07-02 0:13 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: linux-usb@vger.kernel.org, linux-mips@vger.kernel.org
Hi,
thank you for review, v2 is about to be sent, here just let
me anwer issue I didn't address there.
On Fri, Jun 30, 2023 at 11:27:37PM +0000, Thinh Nguyen wrote:
> On Mon, Jun 19, 2023, Ladislav Michl wrote:
[snip]
> > + ref_clk_sel = 2;
>
> Can we use macro instead of magic numbers?
This is a bit problematic, comment above USBDRD_UCTL_CTL_REF_CLK_SEL
says:
/* Reference clock select for SuperSpeed and HighSpeed PLLs:
* 0x0 = Both PLLs use DLMC_REF_CLK0 for reference clock
* 0x1 = Both PLLs use DLMC_REF_CLK1 for reference clock
* 0x2 = SuperSpeed PLL uses DLMC_REF_CLK0 for reference clock &
* HighSpeed PLL uses PLL_REF_CLK for reference clck
* 0x3 = SuperSpeed PLL uses DLMC_REF_CLK1 for reference clock &
* HighSpeed PLL uses PLL_REF_CLK for reference clck
*/
So I really cannot imagine sane name. Also please note, that field
and register names were created to match documentation. Values,
however, have no defined names, so I would need to invent them.
That is something I'd like to avoid as it might be confusing.
And last, but to least: Octeon would deserve proper clock api
(clk driver to be implemented). So hopefully that code get
replaced with more sane one. For now, I just kept compatibility
with current DT.
Thanks,
ladis
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe
2023-07-02 0:13 ` Ladislav Michl
@ 2023-07-05 22:55 ` Thinh Nguyen
0 siblings, 0 replies; 27+ messages in thread
From: Thinh Nguyen @ 2023-07-05 22:55 UTC (permalink / raw)
To: Ladislav Michl
Cc: Thinh Nguyen, linux-usb@vger.kernel.org,
linux-mips@vger.kernel.org
On Sun, Jul 02, 2023, Ladislav Michl wrote:
> Hi,
>
> thank you for review, v2 is about to be sent, here just let
> me anwer issue I didn't address there.
>
> On Fri, Jun 30, 2023 at 11:27:37PM +0000, Thinh Nguyen wrote:
> > On Mon, Jun 19, 2023, Ladislav Michl wrote:
> [snip]
> > > + ref_clk_sel = 2;
> >
> > Can we use macro instead of magic numbers?
>
> This is a bit problematic, comment above USBDRD_UCTL_CTL_REF_CLK_SEL
> says:
> /* Reference clock select for SuperSpeed and HighSpeed PLLs:
> * 0x0 = Both PLLs use DLMC_REF_CLK0 for reference clock
> * 0x1 = Both PLLs use DLMC_REF_CLK1 for reference clock
> * 0x2 = SuperSpeed PLL uses DLMC_REF_CLK0 for reference clock &
> * HighSpeed PLL uses PLL_REF_CLK for reference clck
> * 0x3 = SuperSpeed PLL uses DLMC_REF_CLK1 for reference clock &
> * HighSpeed PLL uses PLL_REF_CLK for reference clck
> */
> So I really cannot imagine sane name. Also please note, that field
> and register names were created to match documentation. Values,
> however, have no defined names, so I would need to invent them.
> That is something I'd like to avoid as it might be confusing.
>
> And last, but to least: Octeon would deserve proper clock api
> (clk driver to be implemented). So hopefully that code get
> replaced with more sane one. For now, I just kept compatibility
> with current DT.
>
> Thanks,
> ladis
Sure. That's reasonable.
Thanks,
Thinh
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2023-07-05 22:56 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-19 20:09 [PATCH 00/11] Cleanup Octeon DWC3 glue code Ladislav Michl
2023-06-19 20:11 ` [PATCH 01/11] MIPS: OCTEON: octeon-usb: add all register offsets Ladislav Michl
2023-06-19 20:11 ` [PATCH 02/11] MIPS: OCTEON: octeon-usb: use bitfields for control register Ladislav Michl
2023-06-19 20:12 ` [PATCH 03/11] MIPS: OCTEON: octeon-usb: use bitfields for host config register Ladislav Michl
2023-06-19 20:12 ` [PATCH 04/11] MIPS: OCTEON: octeon-usb: use bitfields for shim register Ladislav Michl
2023-06-19 20:13 ` [PATCH 05/11] MIPS: OCTEON: octeon-usb: move gpio config to separate function Ladislav Michl
2023-06-19 20:13 ` [PATCH 06/11] MIPS: OCTEON: octeon-usb: introduce dwc3_octeon_{read,write}q Ladislav Michl
2023-06-19 20:14 ` [PATCH 07/11] MIPS: OCTEON: octeon-usb: cleanup divider calculation Ladislav Michl
2023-06-19 20:14 ` [PATCH 08/11] usb: dwc3: Move Octeon glue code from arch/mips Ladislav Michl
2023-06-23 13:15 ` Thomas Bogendoerfer
2023-06-30 22:32 ` Thinh Nguyen
2023-06-19 20:15 ` [PATCH 09/11] usb: dwc3: dwc3-octeon: Convert to glue driver Ladislav Michl
2023-06-30 23:25 ` Thinh Nguyen
2023-06-19 20:15 ` [PATCH 10/11] usb: dwc3: dwc3-octeon: Move node parsing into driver probe Ladislav Michl
2023-06-30 23:27 ` Thinh Nguyen
2023-07-02 0:13 ` Ladislav Michl
2023-07-05 22:55 ` Thinh Nguyen
2023-07-01 5:49 ` kernel test robot
2023-06-19 20:16 ` [PATCH 11/11] usb: dwc3: Add SPDX header and copyright Ladislav Michl
2023-06-22 23:01 ` [PATCH 00/11] Cleanup Octeon DWC3 glue code Thinh Nguyen
2023-06-23 7:57 ` Ladislav Michl
2023-06-23 13:14 ` Thomas Bogendoerfer
2023-06-23 23:24 ` Thinh Nguyen
2023-06-24 13:04 ` Ladislav Michl
2023-06-26 23:17 ` Thinh Nguyen
2023-06-30 10:40 ` Ladislav Michl
2023-06-30 21:45 ` Thinh Nguyen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).