soc: nxp_lpc: Add USBFS support
1. Add support for the USB Full Speed controller
2. Add a Kconfig to specify if a dedicated USB
RAM is available in the SoC.
Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
diff --git a/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt b/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt
index a4cbcf2..22bb1ed 100644
--- a/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt
+++ b/soc/arm/nxp_lpc/lpc55xxx/CMakeLists.txt
@@ -11,11 +11,12 @@
${ZEPHYR_BASE}/kernel/include
${ZEPHYR_BASE}/arch/${ARCH}/include
)
-
+if(DEFINED CONFIG_LPC55XXX_USB_RAM)
zephyr_linker_sources_ifdef(CONFIG_USB_DEVICE_DRIVER
SECTIONS usb.ld)
zephyr_compile_definitions_ifdef(CONFIG_USB_DEVICE_DRIVER USB_STACK_USE_DEDICATED_RAM=1)
+endif()
# CMSIS SystemInit allows us to skip enabling clock to SRAM banks via
# this compiler definition
diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S06 b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S06
index 3a8f9b3..94f479b 100644
--- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S06
+++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S06
@@ -8,4 +8,7 @@
config SOC
default "lpc55S06"
+config LPC55XXX_USB_RAM
+ default n
+
endif # SOC_LPC55S06
diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S36 b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S36
index ce22f74..a83bdf5 100644
--- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S36
+++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S36
@@ -8,4 +8,11 @@
config SOC
default "lpc55S36"
+choice USB_MCUX_CONTROLLER_TYPE
+ default USB_DC_NXP_LPCIP3511
+endchoice
+
+config LPC55XXX_USB_RAM
+ default n
+
endif # SOC_LPC55S36
diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc
index 4cc64d4..cc65f3b 100644
--- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc
+++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc
@@ -151,4 +151,12 @@
By default, CMSIS SystemInit will enable the clock to these RAM banks.
Disable this Kconfig to leave the ram banks untouched out of reset.
+config LPC55XXX_USB_RAM
+ bool
+ default y
+ help
+ Some SoC's in the LPC5500 Series do have a dedicated USB RAM.
+ By default, USB RAM is assumed to be present.
+ Disable this Kconfig in case there is no dedicated USB RAM.
+
endif # SOC_SERIES_LPC55XXX
diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c
index 6aff3a7..ba7a55a 100644
--- a/soc/arm/nxp_lpc/lpc55xxx/soc.c
+++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c
@@ -155,6 +155,39 @@
#endif
#if CONFIG_USB_DC_NXP_LPCIP3511
+
+#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(usbfs), nxp_mcux_usbd, okay)
+ /*< Turn on USB Phy */
+#if defined(CONFIG_SOC_LPC55S36)
+ POWER_DisablePD(kPDRUNCFG_PD_USBFSPHY);
+#else
+ POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY);
+#endif
+ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
+#if defined(CONFIG_SOC_LPC55S36)
+ CLOCK_AttachClk(kFRO_HF_to_USB0);
+#else
+ CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
+#endif
+ /* enable usb0 host clock */
+ CLOCK_EnableClock(kCLOCK_Usbhsl0);
+ /*
+ * According to reference mannual, device mode setting has to be set by access
+ * usb host register
+ */
+ *((uint32_t *)(USBFSH_BASE + 0x5C)) |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
+ /* disable usb0 host clock */
+ CLOCK_DisableClock(kCLOCK_Usbhsl0);
+
+ /* enable USB IP clock */
+ CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFroHfFreq());
+#if defined(FSL_FEATURE_USB_USB_RAM) && (FSL_FEATURE_USB_USB_RAM)
+ memset((uint8_t *)FSL_FEATURE_USB_USB_RAM_BASE_ADDRESS, 0, FSL_FEATURE_USB_USB_RAM);
+#endif
+
+#endif /* USB_DEVICE_TYPE_FS */
+
+#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(usbhs), nxp_mcux_usbd, okay)
/* enable usb1 host clock */
CLOCK_EnableClock(kCLOCK_Usbh1);
/* Put PHY powerdown under software control */
@@ -164,7 +197,7 @@
* access usb host register
*/
*((uint32_t *)(USBHSH_BASE + 0x50)) |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
- /* enable usb1 host clock */
+ /* disable usb1 host clock */
CLOCK_DisableClock(kCLOCK_Usbh1);
/* enable USB IP clock */
@@ -172,12 +205,12 @@
CLOCK_EnableUsbhs0DeviceClock(kCLOCK_UsbSrcUnused, 0U);
USB_EhciPhyInit(kUSB_ControllerLpcIp3511Hs0, CLK_CLK_IN, NULL);
#if defined(FSL_FEATURE_USBHSD_USB_RAM) && (FSL_FEATURE_USBHSD_USB_RAM)
- for (int i = 0; i < FSL_FEATURE_USBHSD_USB_RAM; i++) {
- ((uint8_t *)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
- }
+ memset((uint8_t *)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS, 0, FSL_FEATURE_USBHSD_USB_RAM);
#endif
-#endif
+#endif /* USB_DEVICE_TYPE_HS */
+
+#endif /* CONFIG_USB_DC_NXP_LPCIP3511 */
DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP)