Skip to content

Commit

Permalink
drivers: serial: pl011: Remove busy wait in Ambiq UART initiate
Browse files Browse the repository at this point in the history
Ambiq UART requires specific busy wait during initialization for
propagating powering control registers, original k_busy_wait()
used here generated a dead loop because k_busy_wait() relays on
timer, who's driver is initialized after UART(UART init in
PRE_KERNEL_1, timer init in PRE_KERNEL_2), replace k_busy_wait()
with checking power status register is more suitable here.

(cherry picked from commit 3e456e8)

Original-Signed-off-by: Bryan Zhu <[email protected]>
GitOrigin-RevId: 3e456e8
Change-Id: I5dda348631135cd91afc4eddbb6fad4bce941333
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/zephyr/+/5109849
Tested-by: ChromeOS Prod (Robot) <[email protected]>
Reviewed-by: Fabio Baltieri <[email protected]>
Commit-Queue: Fabio Baltieri <[email protected]>
Tested-by: Fabio Baltieri <[email protected]>
  • Loading branch information
BryanZhuAM authored and Chromeos LUCI committed Dec 11, 2023
1 parent 2f7efae commit bd745c2
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions drivers/serial/uart_pl011_ambiq.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,22 @@ static inline int clk_enable_ambiq_uart(const struct device *dev, uint32_t clk)
return pl011_ambiq_clk_set(dev, clk);
}

/* Problem: writes to pwrcfg reg take at most PWCTRL_MAX_WAIT_US time to propagate.
* Solution: busy wait for PWCTRL_MAX_WAIT_US microseconds to ensure that register
* writes have propagated.
/* Problem: writes to power configure register takes some time to take effective.
* Solution: Check device's power status to ensure that register has taken effective.
* Note: busy wait is not allowed to use here due to UART is initiated before timer starts.
*/

#define QUIRK_AMBIQ_UART_DEFINE(n) \
static int pwr_on_ambiq_uart_##n(void) \
{ \
uint32_t addr = DT_REG_ADDR(DT_INST_PHANDLE(n, ambiq_pwrcfg)) + \
DT_INST_PHA(n, ambiq_pwrcfg, offset); \
uint32_t pwr_status_addr = addr + 4; \
sys_write32((sys_read32(addr) | DT_INST_PHA(n, ambiq_pwrcfg, mask)), addr); \
k_busy_wait(PWRCTRL_MAX_WAIT_US); \
while ((sys_read32(pwr_status_addr) & DT_INST_PHA(n, ambiq_pwrcfg, mask)) != \
DT_INST_PHA(n, ambiq_pwrcfg, mask)) { \
arch_nop(); \
}; \
return 0; \
}

Expand Down

0 comments on commit bd745c2

Please sign in to comment.