Skip to content

Commit

Permalink
Merge branch 'main' into mod_carrier
Browse files Browse the repository at this point in the history
  • Loading branch information
canisLupus1313 authored Dec 3, 2024
2 parents 28cc4fd + 7c7950a commit 5a094fa
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 79 deletions.
10 changes: 8 additions & 2 deletions drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,9 +834,10 @@ static void usbd_dmareq_process(void)
{
if ((m_ep_dma_waiting & m_ep_ready) &&
(k_sem_take(&dma_available, K_NO_WAIT) == 0)) {
const bool low_power = nrf_usbd_common_suspend_check();
uint32_t req;

while (0 != (req = m_ep_dma_waiting & m_ep_ready)) {
while (!low_power && 0 != (req = m_ep_dma_waiting & m_ep_ready)) {
uint8_t pos;

if (NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST &&
Expand Down Expand Up @@ -1310,7 +1311,11 @@ bool nrf_usbd_common_is_started(void)
bool nrf_usbd_common_suspend(void)
{
bool suspended = false;
unsigned int irq_lock_key = irq_lock();
unsigned int irq_lock_key;

/* DMA doesn't work in Low Power mode, ensure there is no active DMA */
k_sem_take(&dma_available, K_FOREVER);
irq_lock_key = irq_lock();

if (m_bus_suspend) {
if (!(NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_RESUME_Msk)) {
Expand All @@ -1327,6 +1332,7 @@ bool nrf_usbd_common_suspend(void)
}

irq_unlock(irq_lock_key);
k_sem_give(&dma_available);

return suspended;
}
Expand Down
24 changes: 21 additions & 3 deletions drivers/usb/udc/udc_dwc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1387,11 +1387,12 @@ static void udc_dwc2_ep_disable(const struct device *dev,
uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
mem_addr_t dxepctl_reg;
uint32_t dxepctl;
const bool is_iso = dwc2_ep_is_iso(cfg);

dxepctl_reg = dwc2_get_dxepctl_reg(dev, cfg->addr);
dxepctl = sys_read32(dxepctl_reg);

if (dxepctl & USB_DWC2_DEPCTL_NAKSTS) {
if (!is_iso && (dxepctl & USB_DWC2_DEPCTL_NAKSTS)) {
/* Endpoint already sends forced NAKs. STALL if necessary. */
if (stall) {
dxepctl |= USB_DWC2_DEPCTL_STALL;
Expand All @@ -1401,6 +1402,19 @@ static void udc_dwc2_ep_disable(const struct device *dev,
return;
}

/* FIXME: This function needs to be changed to not synchronously wait
* for the events to happen because the actions here are racing against
* the USB host packets. It is possible that the IN token or OUT DATA
* gets sent shortly before this function disables the endpoint. If this
* happens, the XferCompl would be set and driver will incorrectly think
* that either:
* * never queued transfer finished, OR
* * transfer queued in incompisoin handler finished (before it really
* does and then it'll "double"-finish when it actually finishes)
*
* For the time being XferCompl is cleared as a workaround.
*/

if (USB_EP_DIR_IS_OUT(cfg->addr)) {
mem_addr_t dctl_reg, gintsts_reg, doepint_reg;
uint32_t dctl;
Expand Down Expand Up @@ -1439,7 +1453,7 @@ static void udc_dwc2_ep_disable(const struct device *dev,
}

/* Clear Endpoint Disabled interrupt */
sys_write32(USB_DWC2_DIEPINT_EPDISBLD, doepint_reg);
sys_write32(USB_DWC2_DOEPINT_EPDISBLD | USB_DWC2_DOEPINT_XFERCOMPL, doepint_reg);

dctl |= USB_DWC2_DCTL_CGOUTNAK;
sys_write32(dctl, dctl_reg);
Expand All @@ -1463,7 +1477,7 @@ static void udc_dwc2_ep_disable(const struct device *dev,
dwc2_wait_for_bit(dev, diepint_reg, USB_DWC2_DIEPINT_EPDISBLD);

/* Clear Endpoint Disabled interrupt */
sys_write32(USB_DWC2_DIEPINT_EPDISBLD, diepint_reg);
sys_write32(USB_DWC2_DIEPINT_EPDISBLD | USB_DWC2_DIEPINT_XFERCOMPL, diepint_reg);

/* TODO: Read DIEPTSIZn here? Programming Guide suggest it to
* let application know how many bytes of interrupted transfer
Expand Down Expand Up @@ -2571,7 +2585,11 @@ static void dwc2_handle_incompisoin(const struct device *dev)

buf = udc_buf_get(dev, cfg->addr);
if (buf) {
/* Data is no longer relevant */
udc_submit_ep_event(dev, buf, 0);

/* Try to queue next packet before SOF */
dwc2_handle_xfer_next(dev, cfg);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/udc/udc_dwc2_vendor_quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ static inline int usbhs_enable_core(const struct device *dev)
wrapper->ENABLE = USBHS_ENABLE_PHY_Msk | USBHS_ENABLE_CORE_Msk;
wrapper->TASKS_START = 1UL;

/* Wait for clock to start to avoid hang on too early register read */
k_busy_wait(1);

/* Enable interrupts */
wrapper->INTENSET = 1UL;

Expand Down
35 changes: 19 additions & 16 deletions drivers/usb/udc/udc_nrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,22 @@ static void udc_nrf_thread(void *p1, void *p2, void *p3)
case UDC_NRF_EVT_HAL:
ep = evt.hal_evt.data.eptransfer.ep;
switch (evt.hal_evt.type) {
case NRF_USBD_COMMON_EVT_SUSPEND:
LOG_INF("SUSPEND state detected");
nrf_usbd_common_suspend();
udc_set_suspended(udc_nrf_dev, true);
udc_submit_event(udc_nrf_dev, UDC_EVT_SUSPEND, 0);
break;
case NRF_USBD_COMMON_EVT_RESUME:
LOG_INF("RESUMING from suspend");
udc_set_suspended(udc_nrf_dev, false);
udc_submit_event(udc_nrf_dev, UDC_EVT_RESUME, 0);
break;
case NRF_USBD_COMMON_EVT_WUREQ:
LOG_INF("Remote wakeup initiated");
udc_set_suspended(udc_nrf_dev, false);
udc_submit_event(udc_nrf_dev, UDC_EVT_RESUME, 0);
break;
case NRF_USBD_COMMON_EVT_EPTRANSFER:
start_xfer = true;
if (USB_EP_DIR_IS_IN(ep)) {
Expand Down Expand Up @@ -499,22 +515,6 @@ static void udc_sof_check_iso_out(const struct device *dev)
static void usbd_event_handler(nrf_usbd_common_evt_t const *const hal_evt)
{
switch (hal_evt->type) {
case NRF_USBD_COMMON_EVT_SUSPEND:
LOG_INF("SUSPEND state detected");
nrf_usbd_common_suspend();
udc_set_suspended(udc_nrf_dev, true);
udc_submit_event(udc_nrf_dev, UDC_EVT_SUSPEND, 0);
break;
case NRF_USBD_COMMON_EVT_RESUME:
LOG_INF("RESUMING from suspend");
udc_set_suspended(udc_nrf_dev, false);
udc_submit_event(udc_nrf_dev, UDC_EVT_RESUME, 0);
break;
case NRF_USBD_COMMON_EVT_WUREQ:
LOG_INF("Remote wakeup initiated");
udc_set_suspended(udc_nrf_dev, false);
udc_submit_event(udc_nrf_dev, UDC_EVT_RESUME, 0);
break;
case NRF_USBD_COMMON_EVT_RESET:
LOG_INF("Reset");
udc_submit_event(udc_nrf_dev, UDC_EVT_RESET, 0);
Expand All @@ -523,6 +523,9 @@ static void usbd_event_handler(nrf_usbd_common_evt_t const *const hal_evt)
udc_submit_event(udc_nrf_dev, UDC_EVT_SOF, 0);
udc_sof_check_iso_out(udc_nrf_dev);
break;
case NRF_USBD_COMMON_EVT_SUSPEND:
case NRF_USBD_COMMON_EVT_RESUME:
case NRF_USBD_COMMON_EVT_WUREQ:
case NRF_USBD_COMMON_EVT_EPTRANSFER:
case NRF_USBD_COMMON_EVT_SETUP: {
struct udc_nrf_evt evt = {
Expand Down
78 changes: 78 additions & 0 deletions dts/common/nordic/nrf54l20.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,84 @@
status = "disabled";
};

i2c23: i2c@ed000 {
compatible = "nordic,nrf-twim";
#address-cells = <1>;
#size-cells = <0>;
reg = <0xed000 0x1000>;
interrupts = <237 NRF_DEFAULT_IRQ_PRIORITY>;
easydma-maxcnt-bits = <16>;
status = "disabled";
zephyr,pm-device-runtime-auto;
};

spi23: spi@ed000 {
/*
* This spi node can be either SPIM or SPIS,
* for the user to pick:
* compatible = "nordic,nrf-spim" or
* "nordic,nrf-spis".
*/
compatible = "nordic,nrf-spim";
#address-cells = <1>;
#size-cells = <0>;
reg = <0xed000 0x1000>;
interrupts = <237 NRF_DEFAULT_IRQ_PRIORITY>;
max-frequency = <DT_FREQ_M(8)>;
easydma-maxcnt-bits = <16>;
rx-delay-supported;
rx-delay = <1>;
status = "disabled";
};

uart23: uart@ed000 {
compatible = "nordic,nrf-uarte";
reg = <0xed000 0x1000>;
interrupts = <237 NRF_DEFAULT_IRQ_PRIORITY>;
status = "disabled";
endtx-stoptx-supported;
frame-timeout-supported;
};

i2c24: i2c@ee000 {
compatible = "nordic,nrf-twim";
#address-cells = <1>;
#size-cells = <0>;
reg = <0xee000 0x1000>;
interrupts = <238 NRF_DEFAULT_IRQ_PRIORITY>;
easydma-maxcnt-bits = <16>;
status = "disabled";
zephyr,pm-device-runtime-auto;
};

spi24: spi@ee000 {
/*
* This spi node can be either SPIM or SPIS,
* for the user to pick:
* compatible = "nordic,nrf-spim" or
* "nordic,nrf-spis".
*/
compatible = "nordic,nrf-spim";
#address-cells = <1>;
#size-cells = <0>;
reg = <0xee000 0x1000>;
interrupts = <238 NRF_DEFAULT_IRQ_PRIORITY>;
max-frequency = <DT_FREQ_M(8)>;
easydma-maxcnt-bits = <16>;
rx-delay-supported;
rx-delay = <1>;
status = "disabled";
};

uart24: uart@ee000 {
compatible = "nordic,nrf-uarte";
reg = <0xee000 0x1000>;
interrupts = <238 NRF_DEFAULT_IRQ_PRIORITY>;
status = "disabled";
endtx-stoptx-supported;
frame-timeout-supported;
};

dppic30: dppic@102000 {
compatible = "nordic,nrf-dppic";
reg = <0x102000 0x808>;
Expand Down
6 changes: 4 additions & 2 deletions modules/hal_nordic/nrfx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_CPUPPR NRF54H20_XXAA
NRF_PPR)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_CPUFLPR NRF54H20_XXAA
NRF_FLPR)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05 NRF54L05_XXAA)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05 NRF54L05_XXAA
DEVELOP_IN_NRF54L15)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05_CPUAPP NRF_APPLICATION)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05_CPUFLPR NRF_FLPR)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10 NRF54L10_XXAA)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10 NRF54L10_XXAA
DEVELOP_IN_NRF54L15)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10_CPUAPP NRF_APPLICATION)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10_CPUFLPR NRF_FLPR)
zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L15 NRF54L15_XXAA)
Expand Down
1 change: 1 addition & 0 deletions soc/nordic/common/soc_lrcconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ void soc_lrcconf_poweron_request(sys_snode_t *node, nrf_lrcconf_power_domain_mas
} else {
return;
}

K_SPINLOCK(&lock) {
if (sys_slist_len(poweron_list) == 0) {
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, domain, true);
Expand Down
36 changes: 11 additions & 25 deletions soc/nordic/nrf54h/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
#include "soc.h"
#include "pm_s2ram.h"

extern sys_snode_t soc_node;

static void common_suspend(void)
{
sys_snode_t *node;

node = soc_pd_sys_snode_get();

if (IS_ENABLED(CONFIG_DCACHE)) {
/* Flush, disable and power down DCACHE */
sys_cache_data_flush_all();
Expand All @@ -37,15 +35,11 @@ static void common_suspend(void)
RAMBLOCK_CONTROL_BIT_ICACHE, false);
}

soc_lrcconf_poweron_release(node, NRF_LRCCONF_POWER_DOMAIN_0);
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
}

static void common_resume(void)
{
sys_snode_t *node;

node = soc_pd_sys_snode_get();

if (IS_ENABLED(CONFIG_ICACHE)) {
/* Power up and re-enable ICACHE */
nrf_memconf_ramblock_control_enable_set(NRF_MEMCONF, RAMBLOCK_POWER_ID,
Expand All @@ -60,15 +54,15 @@ static void common_resume(void)
sys_cache_data_enable();
}

soc_lrcconf_poweron_request(node, NRF_LRCCONF_POWER_DOMAIN_0);
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0);
}

void nrf_poweroff(void)
{
nrf_resetinfo_resetreas_local_set(NRF_RESETINFO, 0);
nrf_resetinfo_restore_valid_set(NRF_RESETINFO, false);

#if !defined(NRF_RADIOCORE)
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
/* Disable retention */
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, false);
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, false);
Expand All @@ -87,19 +81,15 @@ void nrf_poweroff(void)

static void s2idle_enter(uint8_t substate_id)
{
sys_snode_t *node;

node = soc_pd_sys_snode_get();

switch (substate_id) {
case 0:
/* Substate for idle with cache powered on - not implemented yet. */
break;
case 1: /* Substate for idle with cache retained - not implemented yet. */
break;
case 2: /* Substate for idle with cache disabled. */
#if !defined(NRF_RADIOCORE)
soc_lrcconf_poweron_request(node, NRF_LRCCONF_POWER_MAIN);
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_MAIN);
#endif
common_suspend();
break;
Expand All @@ -115,10 +105,6 @@ static void s2idle_enter(uint8_t substate_id)

static void s2idle_exit(uint8_t substate_id)
{
sys_snode_t *node;

node = soc_pd_sys_snode_get();

switch (substate_id) {
case 0:
/* Substate for idle with cache powered on - not implemented yet. */
Expand All @@ -127,8 +113,8 @@ static void s2idle_exit(uint8_t substate_id)
break;
case 2: /* Substate for idle with cache disabled. */
common_resume();
#if !defined(NRF_RADIOCORE)
soc_lrcconf_poweron_release(node, NRF_LRCCONF_POWER_MAIN);
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN);
#endif
default: /* Unknown substate. */
return;
Expand All @@ -140,7 +126,7 @@ static void s2idle_exit(uint8_t substate_id)
static void s2ram_exit(void)
{
common_resume();
#if !defined(NRF_RADIOCORE)
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
/* Re-enable domain retention. */
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true);
#endif
Expand All @@ -156,7 +142,7 @@ static int sys_suspend_to_ram(void)
NRF_RESETINFO_RESETREAS_LOCAL_UNRETAINED_MASK);
nrf_resetinfo_restore_valid_set(NRF_RESETINFO, true);

#if !defined(NRF_RADIOCORE)
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
/* Disable retention */
nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, false);
#endif
Expand Down
Loading

0 comments on commit 5a094fa

Please sign in to comment.