Skip to content

Commit

Permalink
dts: include: arm: st: usb: Add USB PHY clock rate support for STM32U…
Browse files Browse the repository at this point in the history
…5xxx

The existing code assumes that the HSE clock is a 16MHz crystal, however
the hardware allows for a list of possible HSE clock values.

Add them here as an enum, configure it for the STM32U595 chipset
(which is the only device I have access to for testing).

This addresses Issue #79825 .

* Add a list of possible values to use in the DT bindings directory
* Add a new PHY (st,stm32-otghs-phy) with an enum list matching the
  above list
* Add support in the USB driver for checking the clock-cfg entry
  and compiling in the correct clock rate.
* And also handle an out of enum configuration by failing compilation.

Signed-off-by: Adrian Chadd <[email protected]>
  • Loading branch information
Adrian Chadd authored and Adrian Chadd committed Oct 23, 2024
1 parent a8bd569 commit 8e7537c
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
46 changes: 45 additions & 1 deletion drivers/usb/device/usb_dc_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <zephyr/usb/usb_device.h>
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include <zephyr/sys/util.h>
#include <zephyr/dt-bindings/phy/stm32u5_otg_hs_phy.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pinctrl.h>
#include "stm32_hsem.h"
Expand All @@ -36,6 +37,49 @@ LOG_MODULE_REGISTER(usb_dc_stm32);
#error "Only one interface should be enabled at a time, OTG FS or OTG HS"
#endif

/*
* Some STM32U5xx parts support a USB HS PHY which is clocked by the HSE clock or PLL1_P
* clock directly. This requires specific configuration.
*/
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) && defined(CONFIG_SOC_SERIES_STM32U5X)

#define IS_EQ_PROP(inst, prop, compare_value) IS_EQ(DT_PROP(inst, prop), compare_value)

#define HAVE_CLKCFG_NODE() \
DT_NODE_HAS_PROP(DT_PHANDLE_BY_IDX(DT_NODELABEL(usbotg_hs), phys, 0), clock_cfg)

#define CHECK_NODE(inst, prop, value) IS_EQ_PROP(inst, prop, value)

#define CHECK_CLKCFG_NODE(value) \
HAVE_CLKCFG_NODE() && \
CHECK_NODE(DT_PHANDLE_BY_IDX(DT_NODELABEL(usbotg_hs), phys, 0), clock_cfg, value)

#if HAVE_CLKCFG_NODE()
/*
* If we have a clock-cfg node in the PHY then figure out what the clock
* frequency should be. Default to 16MHz if it's not present.
*/
#if CHECK_CLKCFG_NODE(STM32U5_OTGHS_PHY_CLKSEL_16MHZ)
#define OTG_HS_PHY_REFERENCE_CLOCK SYSCFG_OTG_HS_PHY_CLK_SELECT_1
#elif CHECK_CLKCFG_NODE(STM32U5_OTGHS_PHY_CLKSEL_19P2MHZ)
#define OTG_HS_PHY_REFERENCE_CLOCK SYSCFG_OTG_HS_PHY_CLK_SELECT_2
#elif CHECK_CLKCFG_NODE(STM32U5_OTGHS_PHY_CLKSEL_20MHZ)
#define OTG_HS_PHY_REFERENCE_CLOCK SYSCFG_OTG_HS_PHY_CLK_SELECT_3
#elif CHECK_CLKCFG_NODE(STM32U5_OTGHS_PHY_CLKSEL_24MHZ)
#define OTG_HS_PHY_REFERENCE_CLOCK SYSCFG_OTG_HS_PHY_CLK_SELECT_4
#elif CHECK_CLKCFG_NODE(STM32U5_OTGHS_PHY_CLKSEL_26MHZ)
#define OTG_HS_PHY_REFERENCE_CLOCK SYSCFG_OTG_HS_PHY_CLK_SELECT_5
#elif CHECK_CLKCFG_NODE(STM32U5_OTGHS_PHY_CLKSEL_32MHZ)
#define OTG_HS_PHY_REFERENCE_CLOCK SYSCFG_OTG_HS_PHY_CLK_SELECT_6
#else
#error Unsupported clock_cfg value in the usbotg_hs PHY node.
#endif
#else /* HAVE_CLKCFG_NODE() */
#define OTG_HS_PHY_REFERENCE_CLOCK SYSCFG_OTG_HS_PHY_CLK_SELECT_1
#endif /* HAVE_CLKCFG_NODE() */

#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) && defined(CONFIG_SOC_SERIES_STM32U5X) */

/*
* Vbus sensing is determined based on the presence of the hardware detection
* pin(s) in the device tree. E.g: pinctrl-0 = <&usb_otg_fs_vbus_pa9 ...>;
Expand Down Expand Up @@ -246,7 +290,7 @@ static int usb_dc_stm32_clock_enable(void)

/* Set the OTG PHY reference clock selection (through SYSCFG) block */
LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_SYSCFG);
HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1);
HAL_SYSCFG_SetOTGPHYReferenceClockSelection(OTG_HS_PHY_REFERENCE_CLOCK);
/* Configuring the SYSCFG registers OTG_HS PHY : OTG_HS PHY enable*/
HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE);
#elif defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV)
Expand Down
1 change: 1 addition & 0 deletions dts/arm/st/u5/stm32u5.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <zephyr/dt-bindings/memory-controller/stm32-fmc-nor-psram.h>
#include <zephyr/dt-bindings/adc/stm32u5_adc.h>
#include <zephyr/dt-bindings/power/stm32_pwr.h>
#include <zephyr/dt-bindings/phy/stm32u5_otg_hs_phy.h>
#include <freq.h>

/ {
Expand Down
4 changes: 2 additions & 2 deletions dts/arm/st/u5/stm32u595.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@
};

otghs_phy: otghs_phy {
/* Clock source defined by USBPHYC_SEL in */
compatible = "usb-nop-xceiv";
/* Clock source defined by ICKLK_SEL() in usbotg_hs `clocks` */
compatible = "st,stm32u5-otghs-phy";
#phy-cells = <0>;
};

Expand Down
26 changes: 26 additions & 0 deletions dts/bindings/phy/st,stm32u5-otghs-phy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2024 Meta
# SPDX-License-Identifier: Apache-2.0

description: |
This binding is to be used by the STM32U5xx transceivers which are built-in
with USB HS PHY IP and a configurable HSE clock source.
compatible: "st,stm32u5-otghs-phy"

include: phy-controller.yaml

properties:
"#phy-cells":
const: 0

clock-cfg:
type: int
enum:
- 0 # STM32U5_OTGHS_PHY_CLKSEL_16MHZ
- 1 # STM32U5_OTGHS_PHY_CLKSEL_19P2MHZ
- 2 # STM32U5_OTGHS_PHY_CLKSEL_20MHZ
- 3 # STM32U5_OTGHS_PHY_CLKSEL_24MHZ
- 4 # STM32U5_OTGHS_PHY_CLKSEL_26MHZ
- 5 # STM32U5_OTGHS_PHY_CLKSEL_32MHZ
description: |
The clock source speed configuration for this PHY.
21 changes: 21 additions & 0 deletions include/zephyr/dt-bindings/phy/stm32u5_otg_hs_phy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2024 Meta
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PHY_STM32U5_OTG_HS_PHY_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_PHY_STM32U5_OTG_HS_PHY_H_

/* Ideally we'd generate this list to match what's coming out of the YAML.
* Make sure it's kept up to date with the yaml file in question.
* (dts/bindings/phy/st,stm32-otghs-phy.yaml)
*/

#define STM32U5_OTGHS_PHY_CLKSEL_16MHZ 0
#define STM32U5_OTGHS_PHY_CLKSEL_19P2MHZ 1
#define STM32U5_OTGHS_PHY_CLKSEL_20MHZ 2
#define STM32U5_OTGHS_PHY_CLKSEL_24MHZ 3
#define STM32U5_OTGHS_PHY_CLKSEL_26MHZ 4
#define STM32U5_OTGHS_PHY_CLKSEL_32MHZ 5

#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PHY_STM32U5_OTG_HS_PHY_H_ */

0 comments on commit 8e7537c

Please sign in to comment.