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)