Skip to content

Commit 59702c7

Browse files
tmon-nordicnashif
authored andcommitted
drivers: udc_dwc2: Avoid unnecessary register accesses
Do not use sys_clear_bits() followed by sys_set_bits() on DCTL register to avoid writing to DCTL register twice - first with zeroed out address, and then with the new address. Change the code to write the address in one DCTL register write. Do not use sys_set_bits() to set test mode, but rather prepare the correct value first. Set DCFG and GUSBCFG registers in one go. There is no point in reading back the value or doing multiple subsequent writes to these registers. Signed-off-by: Tomasz Moń <[email protected]>
1 parent 2c9371e commit 59702c7

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

drivers/usb/udc/udc_dwc2.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,13 +1437,16 @@ static int udc_dwc2_set_address(const struct device *dev, const uint8_t addr)
14371437
{
14381438
struct usb_dwc2_reg *const base = dwc2_get_base(dev);
14391439
mem_addr_t dcfg_reg = (mem_addr_t)&base->dcfg;
1440+
uint32_t dcfg;
14401441

14411442
if (addr > (USB_DWC2_DCFG_DEVADDR_MASK >> USB_DWC2_DCFG_DEVADDR_POS)) {
14421443
return -EINVAL;
14431444
}
14441445

1445-
sys_clear_bits(dcfg_reg, USB_DWC2_DCFG_DEVADDR_MASK);
1446-
sys_set_bits(dcfg_reg, usb_dwc2_set_dcfg_devaddr(addr));
1446+
dcfg = sys_read32(dcfg_reg);
1447+
dcfg &= ~USB_DWC2_DCFG_DEVADDR_MASK;
1448+
dcfg |= usb_dwc2_set_dcfg_devaddr(addr);
1449+
sys_write32(dcfg, dcfg_reg);
14471450
LOG_DBG("Set new address %u for %p", addr, dev);
14481451

14491452
return 0;
@@ -1454,14 +1457,14 @@ static int udc_dwc2_test_mode(const struct device *dev,
14541457
{
14551458
struct usb_dwc2_reg *const base = dwc2_get_base(dev);
14561459
mem_addr_t dctl_reg = (mem_addr_t)&base->dctl;
1457-
uint32_t tstctl;
1460+
uint32_t dctl;
14581461

14591462
if (mode == 0U || mode > USB_DWC2_DCTL_TSTCTL_TESTFE) {
14601463
return -EINVAL;
14611464
}
14621465

1463-
tstctl = usb_dwc2_get_dctl_tstctl(sys_read32(dctl_reg));
1464-
if (tstctl != USB_DWC2_DCTL_TSTCTL_DISABLED) {
1466+
dctl = sys_read32(dctl_reg);
1467+
if (usb_dwc2_get_dctl_tstctl(dctl) != USB_DWC2_DCTL_TSTCTL_DISABLED) {
14651468
return -EALREADY;
14661469
}
14671470

@@ -1470,7 +1473,8 @@ static int udc_dwc2_test_mode(const struct device *dev,
14701473
return 0;
14711474
}
14721475

1473-
sys_set_bits(dctl_reg, usb_dwc2_set_dctl_tstctl(mode));
1476+
dctl |= usb_dwc2_set_dctl_tstctl(mode);
1477+
sys_write32(dctl, dctl_reg);
14741478
LOG_DBG("Enable Test Mode %u", mode);
14751479

14761480
return 0;
@@ -1548,6 +1552,7 @@ static int udc_dwc2_init_controller(const struct device *dev)
15481552
struct usb_dwc2_reg *const base = config->base;
15491553
mem_addr_t gusbcfg_reg = (mem_addr_t)&base->gusbcfg;
15501554
mem_addr_t dcfg_reg = (mem_addr_t)&base->dcfg;
1555+
uint32_t dcfg;
15511556
uint32_t gusbcfg;
15521557
uint32_t ghwcfg2;
15531558
uint32_t ghwcfg3;
@@ -1616,19 +1621,24 @@ static int udc_dwc2_init_controller(const struct device *dev)
16161621
LOG_DBG("LPM mode is %s",
16171622
(ghwcfg3 & USB_DWC2_GHWCFG3_LPMMODE) ? "enabled" : "disabled");
16181623

1624+
dcfg = sys_read32(dcfg_reg);
1625+
16191626
/* Configure PHY and device speed */
1627+
dcfg &= ~USB_DWC2_DCFG_DEVSPD_MASK;
16201628
switch (usb_dwc2_get_ghwcfg2_hsphytype(ghwcfg2)) {
16211629
case USB_DWC2_GHWCFG2_HSPHYTYPE_UTMIPLUSULPI:
16221630
__fallthrough;
16231631
case USB_DWC2_GHWCFG2_HSPHYTYPE_ULPI:
16241632
gusbcfg |= USB_DWC2_GUSBCFG_PHYSEL_USB20 |
16251633
USB_DWC2_GUSBCFG_ULPI_UTMI_SEL_ULPI;
1626-
sys_set_bits(dcfg_reg, USB_DWC2_DCFG_DEVSPD_USBHS20);
1634+
dcfg |= USB_DWC2_DCFG_DEVSPD_USBHS20
1635+
<< USB_DWC2_DCFG_DEVSPD_POS;
16271636
break;
16281637
case USB_DWC2_GHWCFG2_HSPHYTYPE_UTMIPLUS:
16291638
gusbcfg |= USB_DWC2_GUSBCFG_PHYSEL_USB20 |
16301639
USB_DWC2_GUSBCFG_ULPI_UTMI_SEL_UTMI;
1631-
sys_set_bits(dcfg_reg, USB_DWC2_DCFG_DEVSPD_USBHS20);
1640+
dcfg |= USB_DWC2_DCFG_DEVSPD_USBHS20
1641+
<< USB_DWC2_DCFG_DEVSPD_POS;
16321642
break;
16331643
case USB_DWC2_GHWCFG2_HSPHYTYPE_NO_HS:
16341644
__fallthrough;
@@ -1638,15 +1648,17 @@ static int udc_dwc2_init_controller(const struct device *dev)
16381648
gusbcfg |= USB_DWC2_GUSBCFG_PHYSEL_USB11;
16391649
}
16401650

1641-
sys_set_bits(dcfg_reg, USB_DWC2_DCFG_DEVSPD_USBFS1148);
1651+
dcfg |= USB_DWC2_DCFG_DEVSPD_USBFS1148
1652+
<< USB_DWC2_DCFG_DEVSPD_POS;
16421653
}
16431654

16441655
if (usb_dwc2_get_ghwcfg4_phydatawidth(ghwcfg4)) {
16451656
gusbcfg |= USB_DWC2_GUSBCFG_PHYIF_16_BIT;
16461657
}
16471658

16481659
/* Update PHY configuration */
1649-
sys_set_bits(gusbcfg_reg, gusbcfg);
1660+
sys_write32(gusbcfg, gusbcfg_reg);
1661+
sys_write32(dcfg, dcfg_reg);
16501662

16511663
priv->outeps = 0U;
16521664
for (uint8_t i = 0U; i < priv->numdeveps; i++) {

0 commit comments

Comments
 (0)