diff mbox series

[02/11] MIPS: OCTEON: octeon-usb: use bitfields for control register

Message ID ZJC2f5R6u4lWCUSo@lenoch
State New
Headers show
Series [01/11] MIPS: OCTEON: octeon-usb: add all register offsets | expand

Commit Message

Ladislav Michl June 19, 2023, 8:11 p.m. UTC
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 mbox series

Patch

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)