diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index 575fd9f91e448..60f749dd72236 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -69,91 +69,6 @@ enum dwc2_drv_event_type { /* Percentage limit of how much SPRAM can be allocated for RxFIFO */ #define MAX_RXFIFO_GDFIFO_PERCENTAGE 25 -enum dwc2_suspend_type { - DWC2_SUSPEND_NO_POWER_SAVING, - DWC2_SUSPEND_HIBERNATION, -}; - -/* Registers that have to be stored before Partial Power Down or Hibernation */ -struct dwc2_reg_backup { - uint32_t gotgctl; - uint32_t gahbcfg; - uint32_t gusbcfg; - uint32_t gintmsk; - uint32_t grxfsiz; - uint32_t gnptxfsiz; - uint32_t gi2cctl; - uint32_t glpmcfg; - uint32_t gdfifocfg; - union { - uint32_t dptxfsiz[15]; - uint32_t dieptxf[15]; - }; - uint32_t dcfg; - uint32_t dctl; - uint32_t diepmsk; - uint32_t doepmsk; - uint32_t daintmsk; - uint32_t diepctl[16]; - uint32_t dieptsiz[16]; - uint32_t diepdma[16]; - uint32_t doepctl[16]; - uint32_t doeptsiz[16]; - uint32_t doepdma[16]; - uint32_t pcgcctl; -}; - -/* Driver private data per instance */ -struct udc_dwc2_data { - struct k_spinlock lock; - struct k_thread thread_data; - /* Main events the driver thread waits for */ - struct k_event drv_evt; - /* Endpoint is considered disabled when there is no active transfer */ - struct k_event ep_disabled; - /* Transfer triggers (IN on bits 0-15, OUT on bits 16-31) */ - atomic_t xfer_new; - /* Finished transactions (IN on bits 0-15, OUT on bits 16-31) */ - atomic_t xfer_finished; - struct dwc2_reg_backup backup; - uint32_t ghwcfg1; - uint32_t max_xfersize; - uint32_t max_pktcnt; - uint32_t tx_len[16]; - uint32_t rx_siz[16]; - /* Isochronous endpoint enabled (IN on bits 0-15, OUT on bits 16-31) */ - uint32_t iso_enabled; - uint16_t iso_in_rearm; - uint16_t iso_out_rearm; - uint16_t ep_out_disable; - uint16_t ep_out_stall; - uint16_t txf_set; - uint16_t pending_tx_flush; - uint16_t dfifodepth; - uint16_t rxfifo_depth; - uint16_t max_txfifo_depth[16]; - uint16_t sof_num; - /* Configuration flags */ - unsigned int dynfifosizing : 1; - unsigned int bufferdma : 1; - unsigned int syncrst : 1; - /* Defect workarounds */ - unsigned int wa_essregrestored : 1; - /* Runtime state flags */ - unsigned int hibernated : 1; - unsigned int enumdone : 1; - unsigned int enumspd : 2; - unsigned int ignore_ep0_nakeff : 1; - enum dwc2_suspend_type suspend_type; - /* Number of endpoints including control endpoint */ - uint8_t numdeveps; - /* Number of IN endpoints including control endpoint */ - uint8_t ineps; - /* Number of OUT endpoints including control endpoint */ - uint8_t outeps; - uint8_t setup[8]; -}; - static void udc_dwc2_ep_disable(const struct device *dev, struct udc_ep_config *const cfg, bool stall, bool wait); @@ -190,13 +105,6 @@ static int dwc2_init_pinctrl(const struct device *dev) } #endif -static inline struct usb_dwc2_reg *dwc2_get_base(const struct device *dev) -{ - const struct udc_dwc2_config *const config = dev->config; - - return config->base; -} - static void dwc2_wait_for_bit(const struct device *dev, mem_addr_t addr, uint32_t bit) { @@ -883,8 +791,7 @@ static int dwc2_handle_evt_din(const struct device *dev, static void dwc2_backup_registers(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); struct dwc2_reg_backup *backup = &priv->backup; @@ -940,8 +847,7 @@ static void dwc2_backup_registers(const struct device *dev) static void dwc2_restore_essential_registers(const struct device *dev, bool rwup, bool bus_reset) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); struct dwc2_reg_backup *backup = &priv->backup; uint32_t pcgcctl = backup->pcgcctl & USB_DWC2_PCGCCTL_RESTOREVALUE_MASK; @@ -995,8 +901,7 @@ static void dwc2_restore_essential_registers(const struct device *dev, static void dwc2_restore_device_registers(const struct device *dev, bool rwup) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); struct dwc2_reg_backup *backup = &priv->backup; @@ -1039,8 +944,7 @@ static void dwc2_restore_device_registers(const struct device *dev, bool rwup) static void dwc2_enter_hibernation(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); mem_addr_t gpwrdn_reg = (mem_addr_t)&base->gpwrdn; mem_addr_t pcgcctl_reg = (mem_addr_t)&base->pcgcctl; @@ -1087,8 +991,7 @@ static void dwc2_enter_hibernation(const struct device *dev) static void dwc2_exit_hibernation(const struct device *dev, bool rwup, bool bus_reset) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); mem_addr_t gpwrdn_reg = (mem_addr_t)&base->gpwrdn; mem_addr_t pcgcctl_reg = (mem_addr_t)&base->pcgcctl; @@ -1819,9 +1722,8 @@ static int dwc2_core_soft_reset(const struct device *dev) static int udc_dwc2_init_controller(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; struct udc_dwc2_data *const priv = udc_get_private(dev); - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); mem_addr_t grxfsiz_reg = (mem_addr_t)&base->grxfsiz; mem_addr_t gahbcfg_reg = (mem_addr_t)&base->gahbcfg; mem_addr_t gusbcfg_reg = (mem_addr_t)&base->gusbcfg; @@ -2228,6 +2130,8 @@ static int dwc2_driver_preinit(const struct device *dev) uint32_t ineps; int err; + DEVICE_MMIO_NAMED_MAP(dev, core, K_MEM_CACHE_NONE); + k_mutex_init(&data->mutex); k_event_init(&priv->drv_evt); @@ -2770,8 +2674,7 @@ static inline void dwc2_handle_oepint(const struct device *dev) */ static void dwc2_handle_incompisoin(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); mem_addr_t gintsts_reg = (mem_addr_t)&base->gintsts; const uint32_t mask = @@ -2819,8 +2722,7 @@ static void dwc2_handle_incompisoin(const struct device *dev) */ static void dwc2_handle_incompisoout(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); mem_addr_t gintsts_reg = (mem_addr_t)&base->gintsts; const uint32_t mask = @@ -2865,8 +2767,7 @@ static void dwc2_handle_incompisoout(const struct device *dev) static void dwc2_handle_goutnakeff(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); k_spinlock_key_t key; mem_addr_t doepctl_reg; @@ -2933,8 +2834,7 @@ static void dwc2_handle_goutnakeff(const struct device *dev) static void udc_dwc2_isr_handler(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); struct udc_dwc2_data *const priv = udc_get_private(dev); mem_addr_t gintsts_reg = (mem_addr_t)&base->gintsts; uint32_t int_status; @@ -3291,8 +3191,9 @@ static const struct udc_api udc_dwc2_api = { }; #define UDC_DWC2_DT_INST_REG_ADDR(n) \ - COND_CODE_1(DT_NUM_REGS(DT_DRV_INST(n)), (DT_INST_REG_ADDR(n)), \ - (DT_INST_REG_ADDR_BY_NAME(n, core))) + COND_CODE_1(DT_NUM_REGS(DT_DRV_INST(n)), \ + (DEVICE_MMIO_NAMED_ROM_INIT(core, DT_DRV_INST(n))), \ + (DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(core, DT_DRV_INST(n)))) #if !defined(UDC_DWC2_IRQ_DT_INST_DEFINE) #define UDC_DWC2_IRQ_FLAGS_TYPE0(n) 0 @@ -3363,12 +3264,12 @@ static const struct udc_api udc_dwc2_api = { static struct udc_ep_config ep_cfg_in[DT_INST_PROP(n, num_in_eps)]; \ \ static const struct udc_dwc2_config udc_dwc2_config_##n = { \ + UDC_DWC2_DT_INST_REG_ADDR(n), \ .num_out_eps = DT_INST_PROP(n, num_out_eps), \ .num_in_eps = DT_INST_PROP(n, num_in_eps), \ .ep_cfg_in = ep_cfg_in, \ .ep_cfg_out = ep_cfg_out, \ .make_thread = udc_dwc2_make_thread_##n, \ - .base = (struct usb_dwc2_reg *)UDC_DWC2_DT_INST_REG_ADDR(n), \ .pcfg = UDC_DWC2_PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .irq_enable_func = udc_dwc2_irq_enable_func_##n, \ .irq_disable_func = udc_dwc2_irq_disable_func_##n, \ diff --git a/drivers/usb/udc/udc_dwc2.h b/drivers/usb/udc/udc_dwc2.h index 77be96adaa5f8..932189488cbdb 100644 --- a/drivers/usb/udc/udc_dwc2.h +++ b/drivers/usb/udc/udc_dwc2.h @@ -12,6 +12,15 @@ #include #include +/* Required by DEVICE_MMIO_NAMED_* macros */ +#define DEV_CFG(_dev) ((const struct udc_dwc2_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct udc_dwc2_data *)(udc_get_private(_dev))) + +enum dwc2_suspend_type { + DWC2_SUSPEND_NO_POWER_SAVING, + DWC2_SUSPEND_HIBERNATION, +}; + /* Vendor quirks per driver instance */ struct dwc2_vendor_quirks { /* Called at the beginning of udc_dwc2_init() */ @@ -36,13 +45,94 @@ struct dwc2_vendor_quirks { int (*pre_hibernation_exit)(const struct device *dev); }; +/* Registers that have to be stored before Partial Power Down or Hibernation */ +struct dwc2_reg_backup { + uint32_t gotgctl; + uint32_t gahbcfg; + uint32_t gusbcfg; + uint32_t gintmsk; + uint32_t grxfsiz; + uint32_t gnptxfsiz; + uint32_t gi2cctl; + uint32_t glpmcfg; + uint32_t gdfifocfg; + union { + uint32_t dptxfsiz[15]; + uint32_t dieptxf[15]; + }; + uint32_t dcfg; + uint32_t dctl; + uint32_t diepmsk; + uint32_t doepmsk; + uint32_t daintmsk; + uint32_t diepctl[16]; + uint32_t dieptsiz[16]; + uint32_t diepdma[16]; + uint32_t doepctl[16]; + uint32_t doeptsiz[16]; + uint32_t doepdma[16]; + uint32_t pcgcctl; +}; + +/* Driver private data per instance */ +struct udc_dwc2_data { + DEVICE_MMIO_NAMED_RAM(core); + struct k_spinlock lock; + struct k_thread thread_data; + /* Main events the driver thread waits for */ + struct k_event drv_evt; + /* Endpoint is considered disabled when there is no active transfer */ + struct k_event ep_disabled; + /* Transfer triggers (IN on bits 0-15, OUT on bits 16-31) */ + atomic_t xfer_new; + /* Finished transactions (IN on bits 0-15, OUT on bits 16-31) */ + atomic_t xfer_finished; + struct dwc2_reg_backup backup; + uint32_t ghwcfg1; + uint32_t max_xfersize; + uint32_t max_pktcnt; + uint32_t tx_len[16]; + uint32_t rx_siz[16]; + /* Isochronous endpoint enabled (IN on bits 0-15, OUT on bits 16-31) */ + uint32_t iso_enabled; + uint16_t iso_in_rearm; + uint16_t iso_out_rearm; + uint16_t ep_out_disable; + uint16_t ep_out_stall; + uint16_t txf_set; + uint16_t pending_tx_flush; + uint16_t dfifodepth; + uint16_t rxfifo_depth; + uint16_t max_txfifo_depth[16]; + uint16_t sof_num; + /* Configuration flags */ + unsigned int dynfifosizing : 1; + unsigned int bufferdma : 1; + unsigned int syncrst : 1; + /* Defect workarounds */ + unsigned int wa_essregrestored : 1; + /* Runtime state flags */ + unsigned int hibernated : 1; + unsigned int enumdone : 1; + unsigned int enumspd : 2; + unsigned int ignore_ep0_nakeff : 1; + enum dwc2_suspend_type suspend_type; + /* Number of endpoints including control endpoint */ + uint8_t numdeveps; + /* Number of IN endpoints including control endpoint */ + uint8_t ineps; + /* Number of OUT endpoints including control endpoint */ + uint8_t outeps; + uint8_t setup[8]; +}; + /* Driver configuration per instance */ struct udc_dwc2_config { + DEVICE_MMIO_NAMED_ROM(core); size_t num_in_eps; size_t num_out_eps; struct udc_ep_config *ep_cfg_in; struct udc_ep_config *ep_cfg_out; - struct usb_dwc2_reg *const base; /* Pointer to pin control configuration or NULL */ struct pinctrl_dev_config *const pcfg; /* Pointer to vendor quirks or NULL */ @@ -55,6 +145,11 @@ struct udc_dwc2_config { uint32_t ghwcfg4; }; +static inline struct usb_dwc2_reg *dwc2_get_base(const struct device *dev) +{ + return (struct usb_dwc2_reg *)DEVICE_MMIO_NAMED_GET(dev, core); +} + #include "udc_dwc2_vendor_quirks.h" #define UDC_DWC2_VENDOR_QUIRK_GET(n) \ diff --git a/drivers/usb/udc/udc_dwc2_vendor_quirks.h b/drivers/usb/udc/udc_dwc2_vendor_quirks.h index 2236172709154..8a5a61863cd9d 100644 --- a/drivers/usb/udc/udc_dwc2_vendor_quirks.h +++ b/drivers/usb/udc/udc_dwc2_vendor_quirks.h @@ -60,8 +60,8 @@ static inline int stm32f4_fsotg_enable_clk(const struct usb_dw_stm32_clk *const static inline int stm32f4_fsotg_enable_phy(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - mem_addr_t ggpio_reg = (mem_addr_t)&config->base->ggpio; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); + mem_addr_t ggpio_reg = (mem_addr_t)&base->ggpio; sys_set_bits(ggpio_reg, USB_DWC2_GGPIO_STM32_PWRDWN | USB_DWC2_GGPIO_STM32_VBDEN); @@ -70,8 +70,8 @@ static inline int stm32f4_fsotg_enable_phy(const struct device *dev) static inline int stm32f4_fsotg_disable_phy(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - mem_addr_t ggpio_reg = (mem_addr_t)&config->base->ggpio; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); + mem_addr_t ggpio_reg = (mem_addr_t)&base->ggpio; sys_clear_bits(ggpio_reg, USB_DWC2_GGPIO_STM32_PWRDWN | USB_DWC2_GGPIO_STM32_VBDEN); @@ -278,8 +278,7 @@ static inline int usbhs_is_phy_clk_off(const struct device *dev) static inline int usbhs_post_hibernation_entry(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0); sys_set_bits((mem_addr_t)&base->pcgcctl, USB_DWC2_PCGCCTL_GATEHCLK); @@ -293,8 +292,7 @@ static inline int usbhs_post_hibernation_entry(const struct device *dev) static inline int usbhs_pre_hibernation_exit(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0); sys_clear_bits((mem_addr_t)&base->pcgcctl, USB_DWC2_PCGCCTL_GATEHCLK); @@ -488,8 +486,7 @@ static inline int usbhs_is_phy_clk_off(const struct device *dev) static inline int usbhs_post_hibernation_entry(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0); sys_set_bits((mem_addr_t)&base->pcgcctl, USB_DWC2_PCGCCTL_GATEHCLK); @@ -501,8 +498,7 @@ static inline int usbhs_post_hibernation_entry(const struct device *dev) static inline int usbhs_pre_hibernation_exit(const struct device *dev) { - const struct udc_dwc2_config *const config = dev->config; - struct usb_dwc2_reg *const base = config->base; + struct usb_dwc2_reg *const base = dwc2_get_base(dev); NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0); sys_clear_bits((mem_addr_t)&base->pcgcctl, USB_DWC2_PCGCCTL_GATEHCLK);