* [PATCH 1/3] phy: stm32: sync with upstream
@ 2021-03-16 8:59 Ahmad Fatoum
2021-03-16 8:59 ` [PATCH 2/3] ARM: stm32mp: add support for STM32MP157-EV1 board Ahmad Fatoum
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2021-03-16 8:59 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
This imports following Linux patches by Amelie Delaunay
<amelie.delaunay@foss.st.com>:
phy: stm32: manage 1v1 and 1v8 supplies at pll activation/deactivation
phy: stm32: replace regulator_bulk* by multiple regulator_*
phy: stm32: ensure pll is disabled before phys creation
phy: stm32: ensure phy are no more active when removing the driver
phy: stm32: rework PLL Lock detection
ARM: dts: stm32: add usbphyc vdda1v1 and vdda1v8 supplies on stm32mp151
This makes barebox compatible to the new device tree binding,
reduces our differences to the upstream driver and removes
the power_on, power_off callbacks which are now integrated
into init/exit.
The device tree override is necessary, because unlike with Linux,
barebox regulator core doesn't descend into child nodes to enable
their regulators, but that's a fix for another day.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Sascha, could this be ordered before the dts sync? That one changes
the device tree to use the binding implemented here
---
arch/arm/dts/stm32mp151.dtsi | 5 +
drivers/phy/phy-stm32-usbphyc.c | 231 +++++++++++++++++++++-----------
2 files changed, 156 insertions(+), 80 deletions(-)
diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi
index b82227fa206e..f1fd888fa1c6 100644
--- a/arch/arm/dts/stm32mp151.dtsi
+++ b/arch/arm/dts/stm32mp151.dtsi
@@ -66,3 +66,8 @@
&vrefbuf {
regulator-name = "vref";
};
+
+&usbphyc {
+ vdda1v1-supply = <®11>;
+ vdda1v8-supply = <®18>;
+};
diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c
index d1e064440e73..a50eae94d459 100644
--- a/drivers/phy/phy-stm32-usbphyc.c
+++ b/drivers/phy/phy-stm32-usbphyc.c
@@ -10,6 +10,7 @@
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <io.h>
+#include <linux/iopoll.h>
#include <linux/phy/phy.h>
#include <linux/reset.h>
#include <linux/math64.h>
@@ -17,6 +18,7 @@
#define STM32_USBPHYC_PLL 0x0
#define STM32_USBPHYC_MISC 0x8
+#define STM32_USBPHYC_MONITOR(X) (0x108 + ((X) * 0x100))
#define STM32_USBPHYC_VERSION 0x3F4
/* STM32_USBPHYC_PLL bit fields */
@@ -32,19 +34,16 @@
/* STM32_USBPHYC_MISC bit fields */
#define SWITHOST BIT(0)
+/* STM32_USBPHYC_MONITOR bit fields */
+#define STM32_USBPHYC_MON_OUT GENMASK(3, 0)
+#define STM32_USBPHYC_MON_SEL GENMASK(8, 4)
+#define STM32_USBPHYC_MON_SEL_LOCKP 0x1F
+#define STM32_USBPHYC_MON_OUT_LOCKP BIT(3)
+
/* STM32_USBPHYC_VERSION bit fields */
#define MINREV GENMASK(3, 0)
#define MAJREV GENMASK(7, 4)
-static const char * const supplies_names[] = {
- "vdda1v1", /* 1V1 */
- "vdda1v8", /* 1V8 */
-};
-
-#define NUM_SUPPLIES ARRAY_SIZE(supplies_names)
-
-#define PLL_LOCK_TIME_US 100
-#define PLL_PWR_DOWN_TIME_US 5
#define PLL_FVCO_MHZ 2880
#define PLL_INFF_MIN_RATE_HZ 19200000
#define PLL_INFF_MAX_RATE_HZ 38400000
@@ -58,7 +57,6 @@ struct pll_params {
struct stm32_usbphyc_phy {
struct phy *phy;
struct stm32_usbphyc *usbphyc;
- struct regulator_bulk_data supplies[NUM_SUPPLIES];
u32 index;
bool active;
};
@@ -69,6 +67,9 @@ struct stm32_usbphyc {
struct clk *clk;
struct stm32_usbphyc_phy **phys;
int nphys;
+ struct regulator *vdda1v1;
+ struct regulator *vdda1v8;
+ int n_pll_cons;
int switch_setup;
};
@@ -82,6 +83,41 @@ static inline void stm32_usbphyc_clr_bits(void __iomem *reg, u32 bits)
writel(readl(reg) & ~bits, reg);
}
+static int stm32_usbphyc_regulators_enable(struct stm32_usbphyc *usbphyc)
+{
+ int ret;
+
+ ret = regulator_enable(usbphyc->vdda1v1);
+ if (ret)
+ return ret;
+
+ ret = regulator_enable(usbphyc->vdda1v8);
+ if (ret)
+ goto vdda1v1_disable;
+
+ return 0;
+
+vdda1v1_disable:
+ regulator_disable(usbphyc->vdda1v1);
+
+ return ret;
+}
+
+static int stm32_usbphyc_regulators_disable(struct stm32_usbphyc *usbphyc)
+{
+ int ret;
+
+ ret = regulator_disable(usbphyc->vdda1v8);
+ if (ret)
+ return ret;
+
+ ret = regulator_disable(usbphyc->vdda1v1);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static void stm32_usbphyc_get_pll_params(u32 clk_rate,
struct pll_params *pll_params)
{
@@ -141,83 +177,106 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc)
return 0;
}
-static bool stm32_usbphyc_has_one_phy_active(struct stm32_usbphyc *usbphyc)
+static int __stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
{
- int i;
+ void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL;
+ u32 pllen;
+
+ stm32_usbphyc_clr_bits(pll_reg, PLLEN);
+
+ /* Wait for minimum width of powerdown pulse (ENABLE = Low) */
+ if (readl_poll_timeout(pll_reg, pllen, !(pllen & PLLEN), 50))
+ dev_err(usbphyc->dev, "PLL not reset\n");
- for (i = 0; i < usbphyc->nphys; i++)
- if (usbphyc->phys[i]->active)
- return true;
+ return stm32_usbphyc_regulators_disable(usbphyc);
+}
+
+static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
+{
+ /* Check if a phy port is still active or clk48 in use */
+ if (--usbphyc->n_pll_cons > 0)
+ return 0;
- return false;
+ return __stm32_usbphyc_pll_disable(usbphyc);
}
static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
{
void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL;
- bool pllen = (readl(pll_reg) & PLLEN);
+ bool pllen = readl(pll_reg) & PLLEN;
int ret;
- /* Check if one phy port has already configured the pll */
- if (pllen && stm32_usbphyc_has_one_phy_active(usbphyc))
+ /*
+ * Check if a phy port or clk48 prepare has configured the pll
+ * and ensure the PLL is enabled
+ */
+ if (++usbphyc->n_pll_cons > 1 && pllen)
return 0;
if (pllen) {
- stm32_usbphyc_clr_bits(pll_reg, PLLEN);
- /* Wait for minimum width of powerdown pulse (ENABLE = Low) */
- udelay(PLL_PWR_DOWN_TIME_US);
+ /*
+ * PLL shouldn't be enabled without known consumer,
+ * disable it and reinit n_pll_cons
+ */
+ dev_warn(usbphyc->dev, "PLL enabled without known consumers\n");
+
+ ret = __stm32_usbphyc_pll_disable(usbphyc);
+ if (ret)
+ return ret;
}
+ ret = stm32_usbphyc_regulators_enable(usbphyc);
+ if (ret)
+ goto dec_n_pll_cons;
+
ret = stm32_usbphyc_pll_init(usbphyc);
if (ret)
- return ret;
+ goto reg_disable;
stm32_usbphyc_set_bits(pll_reg, PLLEN);
- /* Wait for maximum lock time */
- udelay(PLL_LOCK_TIME_US);
-
- if (!(readl(pll_reg) & PLLEN)) {
- dev_err(usbphyc->dev, "PLLEN not set\n");
- return -EIO;
- }
-
return 0;
-}
-
-static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
-{
- void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL;
-
- /* Check if other phy port active */
- if (stm32_usbphyc_has_one_phy_active(usbphyc))
- return 0;
- stm32_usbphyc_clr_bits(pll_reg, PLLEN);
- /* Wait for minimum width of powerdown pulse (ENABLE = Low) */
- udelay(PLL_PWR_DOWN_TIME_US);
+reg_disable:
+ stm32_usbphyc_regulators_disable(usbphyc);
- if (readl(pll_reg) & PLLEN) {
- dev_err(usbphyc->dev, "PLL not reset\n");
- return -EIO;
- }
+dec_n_pll_cons:
+ usbphyc->n_pll_cons--;
- return 0;
+ return ret;
}
static int stm32_usbphyc_phy_init(struct phy *phy)
{
struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
struct stm32_usbphyc *usbphyc = usbphyc_phy->usbphyc;
+ u32 reg_mon = STM32_USBPHYC_MONITOR(usbphyc_phy->index);
+ u32 monsel = FIELD_PREP(STM32_USBPHYC_MON_SEL,
+ STM32_USBPHYC_MON_SEL_LOCKP);
+ u32 monout;
int ret;
ret = stm32_usbphyc_pll_enable(usbphyc);
if (ret)
return ret;
+ /* Check that PLL Lock input to PHY is High */
+ writel(monsel, usbphyc->base + reg_mon);
+ ret = readl_poll_timeout(usbphyc->base + reg_mon, monout,
+ (monout & STM32_USBPHYC_MON_OUT_LOCKP),
+ 1000);
+ if (ret) {
+ dev_err(usbphyc->dev, "PLL Lock input to PHY is Low (val=%x)\n",
+ (u32)(monout & STM32_USBPHYC_MON_OUT));
+ goto pll_disable;
+ }
+
usbphyc_phy->active = true;
return 0;
+
+pll_disable:
+ return stm32_usbphyc_pll_disable(usbphyc);
}
static int stm32_usbphyc_phy_exit(struct phy *phy)
@@ -230,25 +289,9 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
return stm32_usbphyc_pll_disable(usbphyc);
}
-static int stm32_usbphyc_phy_power_on(struct phy *phy)
-{
- struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
-
- return regulator_bulk_enable(NUM_SUPPLIES, usbphyc_phy->supplies);
-}
-
-static int stm32_usbphyc_phy_power_off(struct phy *phy)
-{
- struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
-
- return regulator_bulk_disable(NUM_SUPPLIES, usbphyc_phy->supplies);
-}
-
static const struct phy_ops stm32_usbphyc_phy_ops = {
.init = stm32_usbphyc_phy_init,
.exit = stm32_usbphyc_phy_exit,
- .power_on = stm32_usbphyc_phy_power_on,
- .power_off = stm32_usbphyc_phy_power_off,
};
static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc,
@@ -311,7 +354,7 @@ static int stm32_usbphyc_probe(struct device_d *dev)
struct device_node *child, *np = dev->device_node;
struct resource *iores;
struct phy_provider *phy_provider;
- u32 version;
+ u32 pllen, version;
int ret, port = 0;
usbphyc = xzalloc(sizeof(*usbphyc));
@@ -337,17 +380,51 @@ static int stm32_usbphyc_probe(struct device_d *dev)
goto release_region;
}
- device_reset_us(dev, 2);
+ ret = device_reset_us(dev, 2);
+ if (ret == -EPROBE_DEFER)
+ goto clk_disable;
+ if (ret)
+ stm32_usbphyc_clr_bits(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
+
+ /*
+ * Wait for minimum width of powerdown pulse (ENABLE = Low):
+ * we have to ensure the PLL is disabled before phys initialization.
+ */
+ if (readl_poll_timeout(usbphyc->base + STM32_USBPHYC_PLL,
+ pllen, !(pllen & PLLEN), 50)) {
+ dev_warn(usbphyc->dev, "PLL not reset\n");
+ ret = -EPROBE_DEFER;
+ goto clk_disable;
+ }
usbphyc->switch_setup = -EINVAL;
usbphyc->nphys = of_get_child_count(np);
- usbphyc->phys = xzalloc(usbphyc->nphys * sizeof(*usbphyc->phys));
+ usbphyc->phys = calloc(usbphyc->nphys, sizeof(*usbphyc->phys));
+ if (!usbphyc->phys) {
+ ret = -ENOMEM;
+ goto clk_disable;
+ }
+
+ usbphyc->vdda1v1 = regulator_get(dev, "vdda1v1");
+ if (IS_ERR(usbphyc->vdda1v1)) {
+ ret = PTR_ERR(usbphyc->vdda1v1);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to get vdda1v1 supply: %d\n", ret);
+ goto clk_disable;
+ }
+
+ usbphyc->vdda1v8 = regulator_get(dev, "vdda1v8");
+ if (IS_ERR(usbphyc->vdda1v8)) {
+ ret = PTR_ERR(usbphyc->vdda1v8);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to get vdda1v8 supply: %d\n", ret);
+ goto clk_disable;
+ }
for_each_child_of_node(np, child) {
struct stm32_usbphyc_phy *usbphyc_phy;
struct phy *phy;
u32 index;
- int i;
phy = phy_create(dev, child, &stm32_usbphyc_phy_ops);
if (IS_ERR(phy)) {
@@ -360,18 +437,6 @@ static int stm32_usbphyc_probe(struct device_d *dev)
usbphyc_phy = xzalloc(sizeof(*usbphyc_phy));
- for (i = 0; i < NUM_SUPPLIES; i++)
- usbphyc_phy->supplies[i].supply = supplies_names[i];
-
- ret = regulator_bulk_get(&phy->dev, NUM_SUPPLIES,
- usbphyc_phy->supplies);
- if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(&phy->dev,
- "failed to get regulators: %d\n", ret);
- goto clk_disable;
- }
-
ret = of_property_read_u32(child, "reg", &index);
if (ret || index > usbphyc->nphys) {
dev_err(&phy->dev, "invalid reg property: %d\n", ret);
@@ -417,6 +482,12 @@ release_region:
static void stm32_usbphyc_remove(struct device_d *dev)
{
struct stm32_usbphyc *usbphyc = dev->priv;
+ int port;
+
+ /* Ensure PHYs are not active, to allow PLL disabling */
+ for (port = 0; port < usbphyc->nphys; port++)
+ if (usbphyc->phys[port]->active)
+ stm32_usbphyc_phy_exit(usbphyc->phys[port]->phy);
clk_disable(usbphyc->clk);
}
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/3] ARM: stm32mp: add support for STM32MP157-EV1 board
2021-03-16 8:59 [PATCH 1/3] phy: stm32: sync with upstream Ahmad Fatoum
@ 2021-03-16 8:59 ` Ahmad Fatoum
2021-03-16 8:59 ` [PATCH 3/3] ARM: stm32mp: defconfig: enable DWC2 USB OTG controller Ahmad Fatoum
2021-03-17 8:39 ` [PATCH 1/3] phy: stm32: sync with upstream Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2021-03-16 8:59 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The STM32MP157A-EV1 and STM32MP157C-EV1 Evaluation boards are the
full-feature demonstration and development platforms for
STMicroelectronics Arm®-based dual Cortex®-A7 32 bits and
Cortex®-M4 32 bits MPUs in the STM32MP1 Series.
Add support for running barebox as SSBL on either of them.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Documentation/boards/stm32mp.rst | 35 ++++++++++++++++++--
arch/arm/boards/Makefile | 1 +
arch/arm/boards/stm32mp15x-ev1/Makefile | 2 ++
arch/arm/boards/stm32mp15x-ev1/board.c | 39 +++++++++++++++++++++++
arch/arm/boards/stm32mp15x-ev1/lowlevel.c | 26 +++++++++++++++
arch/arm/configs/stm32mp_defconfig | 1 +
arch/arm/dts/Makefile | 1 +
arch/arm/dts/stm32mp157c-ev1.dts | 20 ++++++++++++
arch/arm/mach-stm32mp/Kconfig | 8 +++++
images/Makefile.stm32mp | 5 +++
10 files changed, 136 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/boards/stm32mp15x-ev1/Makefile
create mode 100644 arch/arm/boards/stm32mp15x-ev1/board.c
create mode 100644 arch/arm/boards/stm32mp15x-ev1/lowlevel.c
create mode 100644 arch/arm/dts/stm32mp157c-ev1.dts
diff --git a/Documentation/boards/stm32mp.rst b/Documentation/boards/stm32mp.rst
index 87fff7d1259b..24b7a19ceb96 100644
--- a/Documentation/boards/stm32mp.rst
+++ b/Documentation/boards/stm32mp.rst
@@ -32,6 +32,7 @@ The resulting images will be placed under ``images/``:
barebox-stm32mp15xx-dkx.img # both DK1 and DK2
barebox-stm32mp157c-lxa-mc1.img
barebox-stm32mp157c-seeed-odyssey.img
+ barebox-stm32mp15x-ev1.img # stm32mp157c-ev1 and friends
Flashing barebox
@@ -94,8 +95,38 @@ acknowledge.
Boot source selection
---------------------
-The STM32MP BootROM samples three boot pins at reset. Usually BOOT1 is
-pulled down and BOOT0 and BOOT2 are connected to a 2P DIP switch::
+The STM32MP BootROM samples three boot pins at reset. On official
+eval kit, they are either connected to a 3P DIP switch or 2P (with
+BOOT1 pulled down).
+
+EV-1
+^^^^
+SW1 on the DK boards sets boot mode as follows::
+
+ +-------+
+ | --- |
+ BOOT2 | O-- |
+ BOOT1 | O --O |
+ BOOT0 | N O-- | <---- SD-Card
+ +-------+
+
+ +-------+
+ | --- |
+ BOOT2 | --O |
+ BOOT1 | O O-- |
+ BOOT0 | N --O | <---- eMMC
+ +-------+
+
+ +-------+
+ | --- |
+ BOOT2 | --O |
+ BOOT1 | O --O |
+ BOOT0 | N --O | <---- DFU on UART and USB OTG
+ +-------+
+
+DK-1/DK-2
+^^^^^^^^^
+Boot mode on the DK board is set as follows::
+-------+
BOOT2 | O O-- |
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index f8cdd90ed6e6..732936bad63e 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -134,6 +134,7 @@ obj-$(CONFIG_MACH_SOLIDRUN_CUBOX) += solidrun-cubox/
obj-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += solidrun-microsom/
obj-$(CONFIG_MACH_STM32MP15XX_DKX) += stm32mp15xx-dkx/
obj-$(CONFIG_MACH_LXA_MC1) += lxa-mc1/
+obj-$(CONFIG_MACH_STM32MP15X_EV1) += stm32mp15x-ev1/
obj-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += technexion-pico-hobbit/
obj-$(CONFIG_MACH_TECHNEXION_WANDBOARD) += technexion-wandboard/
obj-$(CONFIG_MACH_TNY_A9260) += tny-a926x/
diff --git a/arch/arm/boards/stm32mp15x-ev1/Makefile b/arch/arm/boards/stm32mp15x-ev1/Makefile
new file mode 100644
index 000000000000..092c31d6b28d
--- /dev/null
+++ b/arch/arm/boards/stm32mp15x-ev1/Makefile
@@ -0,0 +1,2 @@
+lwl-y += lowlevel.o
+obj-y += board.o
diff --git a/arch/arm/boards/stm32mp15x-ev1/board.c b/arch/arm/boards/stm32mp15x-ev1/board.c
new file mode 100644
index 000000000000..b8e26cd37b3d
--- /dev/null
+++ b/arch/arm/boards/stm32mp15x-ev1/board.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <bootsource.h>
+#include <common.h>
+#include <init.h>
+#include <mach/bbu.h>
+
+static int ed1_probe(struct device_d *dev)
+{
+ int flags;
+
+ flags = bootsource_get_instance() == 0 ? BBU_HANDLER_FLAG_DEFAULT : 0;
+ stm32mp_bbu_mmc_register_handler("sd", "/dev/mmc0.ssbl", flags);
+
+ flags = bootsource_get_instance() == 1 ? BBU_HANDLER_FLAG_DEFAULT : 0;
+ stm32mp_bbu_mmc_register_handler("emmc", "/dev/mmc1.ssbl", flags);
+
+ if (bootsource_get_instance() == 0)
+ of_device_enable_path("/chosen/environment-sd");
+ else
+ of_device_enable_path("/chosen/environment-emmc");
+
+ barebox_set_model("STM32MP157C-ED1");
+
+ return 0;
+}
+
+/* ED1 is the SoM on top of the EV1 */
+static const struct of_device_id ed1_of_match[] = {
+ { .compatible = "st,stm32mp157c-ed1" },
+ { /* sentinel */ },
+};
+
+static struct driver_d ed1_board_driver = {
+ .name = "board-stm32mp15x-ed1",
+ .probe = ed1_probe,
+ .of_compatible = ed1_of_match,
+};
+postcore_platform_driver(ed1_board_driver);
diff --git a/arch/arm/boards/stm32mp15x-ev1/lowlevel.c b/arch/arm/boards/stm32mp15x-ev1/lowlevel.c
new file mode 100644
index 000000000000..06ff6291b8b4
--- /dev/null
+++ b/arch/arm/boards/stm32mp15x-ev1/lowlevel.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <common.h>
+#include <mach/entry.h>
+#include <debug_ll.h>
+
+extern char __dtb_z_stm32mp157c_ev1_start[];
+
+static void setup_uart(void)
+{
+ /* first stage has set up the UART, so nothing to do here */
+ putc_ll('>');
+}
+
+ENTRY_FUNCTION(start_stm32mp15x_ev1, r0, r1, r2)
+{
+ void *fdt;
+
+ stm32mp_cpu_lowlevel_init();
+
+ if (IS_ENABLED(CONFIG_DEBUG_LL))
+ setup_uart();
+
+ fdt = __dtb_z_stm32mp157c_ev1_start + get_runtime_offset();
+
+ stm32mp1_barebox_entry(fdt);
+}
diff --git a/arch/arm/configs/stm32mp_defconfig b/arch/arm/configs/stm32mp_defconfig
index e1ee4ec08205..7b90002f8796 100644
--- a/arch/arm/configs/stm32mp_defconfig
+++ b/arch/arm/configs/stm32mp_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARCH_STM32MP=y
CONFIG_MACH_STM32MP15XX_DKX=y
CONFIG_MACH_LXA_MC1=y
CONFIG_MACH_SEEED_ODYSSEY=y
+CONFIG_MACH_STM32MP15X_EV1=y
CONFIG_THUMB2_BAREBOX=y
CONFIG_ARM_BOARD_APPEND_ATAG=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 63bd73dfaa5d..d5f61768a5b5 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -113,6 +113,7 @@ lwl-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += imx6dl-hummingboard.dtb.o imx6q-hummingb
lwl-$(CONFIG_MACH_SEEED_ODYSSEY) += stm32mp157c-odyssey.dtb.o
lwl-$(CONFIG_MACH_STM32MP15XX_DKX) += stm32mp157c-dk2.dtb.o stm32mp157a-dk1.dtb.o
lwl-$(CONFIG_MACH_LXA_MC1) += stm32mp157c-lxa-mc1.dtb.o
+lwl-$(CONFIG_MACH_STM32MP15X_EV1) += stm32mp157c-ev1.dtb.o
lwl-$(CONFIG_MACH_SCB9328) += imx1-scb9328.dtb.o
lwl-$(CONFIG_MACH_TECHNEXION_WANDBOARD) += imx6q-wandboard.dtb.o imx6dl-wandboard.dtb.o
lwl-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += imx6ul-pico-hobbit.dtb.o
diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts
new file mode 100644
index 000000000000..742eca7a33c9
--- /dev/null
+++ b/arch/arm/dts/stm32mp157c-ev1.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR X11)
+
+#include <arm/stm32mp157c-ev1.dts>
+#include "stm32mp151.dtsi"
+
+/ {
+ chosen {
+ environment-sd {
+ compatible = "barebox,environment";
+ device-path = &sdmmc1, "partname:barebox-environment";
+ status = "disabled";
+ };
+
+ environment-emmc {
+ compatible = "barebox,environment";
+ device-path = &sdmmc2, "partname:barebox-environment";
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index b8ccbaab6702..95d3dc510d12 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -23,4 +23,12 @@ config MACH_SEEED_ODYSSEY
select ARCH_STM32MP157
bool "Seeed Studio Odyssey"
+config MACH_STM32MP15X_EV1
+ select ARCH_STM32MP157
+ bool "STM32MP15X-EV1 board"
+ help
+ builds a single barebox-stm32mp15x-ev1.img that can be deployed
+ as SSBL on any STM32MP15X-EVAL platform, like the
+ STM32MP157C-EV1
+
endif
diff --git a/images/Makefile.stm32mp b/images/Makefile.stm32mp
index eafe84a72185..3384f5014bb1 100644
--- a/images/Makefile.stm32mp
+++ b/images/Makefile.stm32mp
@@ -27,3 +27,8 @@ pblb-$(CONFIG_MACH_SEEED_ODYSSEY) += start_stm32mp157c_seeed_odyssey
FILE_barebox-stm32mp157c-seeed-odyssey.img = start_stm32mp157c_seeed_odyssey.pblb.stm32
OPTS_start_stm32mp157c_seeed_odyssey.pblb.stm32 = $(STM32MP1_OPTS)
image-$(CONFIG_MACH_SEEED_ODYSSEY) += barebox-stm32mp157c-seeed-odyssey.img
+
+pblb-$(CONFIG_MACH_STM32MP15X_EV1) += start_stm32mp15x_ev1
+FILE_barebox-stm32mp15x-ev1.img = start_stm32mp15x_ev1.pblb.stm32
+OPTS_start_stm32mp15x_ev1.pblb.stm32 = $(STM32MP1_OPTS)
+image-$(CONFIG_MACH_STM32MP15X_EV1) += barebox-stm32mp15x-ev1.img
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 3/3] ARM: stm32mp: defconfig: enable DWC2 USB OTG controller
2021-03-16 8:59 [PATCH 1/3] phy: stm32: sync with upstream Ahmad Fatoum
2021-03-16 8:59 ` [PATCH 2/3] ARM: stm32mp: add support for STM32MP157-EV1 board Ahmad Fatoum
@ 2021-03-16 8:59 ` Ahmad Fatoum
2021-03-17 8:39 ` [PATCH 1/3] phy: stm32: sync with upstream Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2021-03-16 8:59 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
We have had all parts in place to use the OTG port on the STM32MP1
boards for a while now. Enable it in the defconfig. USB EHCI
has a driver, but still needs some glue, however.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/configs/stm32mp_defconfig | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm/configs/stm32mp_defconfig b/arch/arm/configs/stm32mp_defconfig
index 7b90002f8796..49041b1f48f3 100644
--- a/arch/arm/configs/stm32mp_defconfig
+++ b/arch/arm/configs/stm32mp_defconfig
@@ -93,7 +93,6 @@ CONFIG_CMD_TIME=y
CONFIG_NET=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_FASTBOOT=y
-CONFIG_OFDEVICE=y
CONFIG_OF_BAREBOX_DRIVERS=y
CONFIG_AIODEV=y
CONFIG_STM32_ADC=y
@@ -106,6 +105,13 @@ CONFIG_REALTEK_PHY=y
# CONFIG_SPI is not set
CONFIG_I2C=y
CONFIG_I2C_STM32=y
+CONFIG_USB_HOST=y
+CONFIG_USB_DWC2_HOST=y
+CONFIG_USB_DWC2_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DFU=y
+CONFIG_USB_GADGET_SERIAL=y
+CONFIG_USB_GADGET_FASTBOOT=y
CONFIG_VIDEO=y
CONFIG_DRIVER_VIDEO_BACKLIGHT=y
CONFIG_DRIVER_VIDEO_SIMPLE_PANEL=y
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/3] phy: stm32: sync with upstream
2021-03-16 8:59 [PATCH 1/3] phy: stm32: sync with upstream Ahmad Fatoum
2021-03-16 8:59 ` [PATCH 2/3] ARM: stm32mp: add support for STM32MP157-EV1 board Ahmad Fatoum
2021-03-16 8:59 ` [PATCH 3/3] ARM: stm32mp: defconfig: enable DWC2 USB OTG controller Ahmad Fatoum
@ 2021-03-17 8:39 ` Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2021-03-17 8:39 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Tue, Mar 16, 2021 at 09:59:03AM +0100, Ahmad Fatoum wrote:
> This imports following Linux patches by Amelie Delaunay
> <amelie.delaunay@foss.st.com>:
>
> phy: stm32: manage 1v1 and 1v8 supplies at pll activation/deactivation
> phy: stm32: replace regulator_bulk* by multiple regulator_*
> phy: stm32: ensure pll is disabled before phys creation
> phy: stm32: ensure phy are no more active when removing the driver
> phy: stm32: rework PLL Lock detection
> ARM: dts: stm32: add usbphyc vdda1v1 and vdda1v8 supplies on stm32mp151
>
> This makes barebox compatible to the new device tree binding,
> reduces our differences to the upstream driver and removes
> the power_on, power_off callbacks which are now integrated
> into init/exit.
>
> The device tree override is necessary, because unlike with Linux,
> barebox regulator core doesn't descend into child nodes to enable
> their regulators, but that's a fix for another day.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> Sascha, could this be ordered before the dts sync? That one changes
> the device tree to use the binding implemented here
Did that. Applied, thanks
Sascha
> ---
> arch/arm/dts/stm32mp151.dtsi | 5 +
> drivers/phy/phy-stm32-usbphyc.c | 231 +++++++++++++++++++++-----------
> 2 files changed, 156 insertions(+), 80 deletions(-)
>
> diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi
> index b82227fa206e..f1fd888fa1c6 100644
> --- a/arch/arm/dts/stm32mp151.dtsi
> +++ b/arch/arm/dts/stm32mp151.dtsi
> @@ -66,3 +66,8 @@
> &vrefbuf {
> regulator-name = "vref";
> };
> +
> +&usbphyc {
> + vdda1v1-supply = <®11>;
> + vdda1v8-supply = <®18>;
> +};
> diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c
> index d1e064440e73..a50eae94d459 100644
> --- a/drivers/phy/phy-stm32-usbphyc.c
> +++ b/drivers/phy/phy-stm32-usbphyc.c
> @@ -10,6 +10,7 @@
> #include <linux/bitfield.h>
> #include <linux/clk.h>
> #include <io.h>
> +#include <linux/iopoll.h>
> #include <linux/phy/phy.h>
> #include <linux/reset.h>
> #include <linux/math64.h>
> @@ -17,6 +18,7 @@
>
> #define STM32_USBPHYC_PLL 0x0
> #define STM32_USBPHYC_MISC 0x8
> +#define STM32_USBPHYC_MONITOR(X) (0x108 + ((X) * 0x100))
> #define STM32_USBPHYC_VERSION 0x3F4
>
> /* STM32_USBPHYC_PLL bit fields */
> @@ -32,19 +34,16 @@
> /* STM32_USBPHYC_MISC bit fields */
> #define SWITHOST BIT(0)
>
> +/* STM32_USBPHYC_MONITOR bit fields */
> +#define STM32_USBPHYC_MON_OUT GENMASK(3, 0)
> +#define STM32_USBPHYC_MON_SEL GENMASK(8, 4)
> +#define STM32_USBPHYC_MON_SEL_LOCKP 0x1F
> +#define STM32_USBPHYC_MON_OUT_LOCKP BIT(3)
> +
> /* STM32_USBPHYC_VERSION bit fields */
> #define MINREV GENMASK(3, 0)
> #define MAJREV GENMASK(7, 4)
>
> -static const char * const supplies_names[] = {
> - "vdda1v1", /* 1V1 */
> - "vdda1v8", /* 1V8 */
> -};
> -
> -#define NUM_SUPPLIES ARRAY_SIZE(supplies_names)
> -
> -#define PLL_LOCK_TIME_US 100
> -#define PLL_PWR_DOWN_TIME_US 5
> #define PLL_FVCO_MHZ 2880
> #define PLL_INFF_MIN_RATE_HZ 19200000
> #define PLL_INFF_MAX_RATE_HZ 38400000
> @@ -58,7 +57,6 @@ struct pll_params {
> struct stm32_usbphyc_phy {
> struct phy *phy;
> struct stm32_usbphyc *usbphyc;
> - struct regulator_bulk_data supplies[NUM_SUPPLIES];
> u32 index;
> bool active;
> };
> @@ -69,6 +67,9 @@ struct stm32_usbphyc {
> struct clk *clk;
> struct stm32_usbphyc_phy **phys;
> int nphys;
> + struct regulator *vdda1v1;
> + struct regulator *vdda1v8;
> + int n_pll_cons;
> int switch_setup;
> };
>
> @@ -82,6 +83,41 @@ static inline void stm32_usbphyc_clr_bits(void __iomem *reg, u32 bits)
> writel(readl(reg) & ~bits, reg);
> }
>
> +static int stm32_usbphyc_regulators_enable(struct stm32_usbphyc *usbphyc)
> +{
> + int ret;
> +
> + ret = regulator_enable(usbphyc->vdda1v1);
> + if (ret)
> + return ret;
> +
> + ret = regulator_enable(usbphyc->vdda1v8);
> + if (ret)
> + goto vdda1v1_disable;
> +
> + return 0;
> +
> +vdda1v1_disable:
> + regulator_disable(usbphyc->vdda1v1);
> +
> + return ret;
> +}
> +
> +static int stm32_usbphyc_regulators_disable(struct stm32_usbphyc *usbphyc)
> +{
> + int ret;
> +
> + ret = regulator_disable(usbphyc->vdda1v8);
> + if (ret)
> + return ret;
> +
> + ret = regulator_disable(usbphyc->vdda1v1);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> static void stm32_usbphyc_get_pll_params(u32 clk_rate,
> struct pll_params *pll_params)
> {
> @@ -141,83 +177,106 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc)
> return 0;
> }
>
> -static bool stm32_usbphyc_has_one_phy_active(struct stm32_usbphyc *usbphyc)
> +static int __stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
> {
> - int i;
> + void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL;
> + u32 pllen;
> +
> + stm32_usbphyc_clr_bits(pll_reg, PLLEN);
> +
> + /* Wait for minimum width of powerdown pulse (ENABLE = Low) */
> + if (readl_poll_timeout(pll_reg, pllen, !(pllen & PLLEN), 50))
> + dev_err(usbphyc->dev, "PLL not reset\n");
>
> - for (i = 0; i < usbphyc->nphys; i++)
> - if (usbphyc->phys[i]->active)
> - return true;
> + return stm32_usbphyc_regulators_disable(usbphyc);
> +}
> +
> +static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
> +{
> + /* Check if a phy port is still active or clk48 in use */
> + if (--usbphyc->n_pll_cons > 0)
> + return 0;
>
> - return false;
> + return __stm32_usbphyc_pll_disable(usbphyc);
> }
>
> static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
> {
> void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL;
> - bool pllen = (readl(pll_reg) & PLLEN);
> + bool pllen = readl(pll_reg) & PLLEN;
> int ret;
>
> - /* Check if one phy port has already configured the pll */
> - if (pllen && stm32_usbphyc_has_one_phy_active(usbphyc))
> + /*
> + * Check if a phy port or clk48 prepare has configured the pll
> + * and ensure the PLL is enabled
> + */
> + if (++usbphyc->n_pll_cons > 1 && pllen)
> return 0;
>
> if (pllen) {
> - stm32_usbphyc_clr_bits(pll_reg, PLLEN);
> - /* Wait for minimum width of powerdown pulse (ENABLE = Low) */
> - udelay(PLL_PWR_DOWN_TIME_US);
> + /*
> + * PLL shouldn't be enabled without known consumer,
> + * disable it and reinit n_pll_cons
> + */
> + dev_warn(usbphyc->dev, "PLL enabled without known consumers\n");
> +
> + ret = __stm32_usbphyc_pll_disable(usbphyc);
> + if (ret)
> + return ret;
> }
>
> + ret = stm32_usbphyc_regulators_enable(usbphyc);
> + if (ret)
> + goto dec_n_pll_cons;
> +
> ret = stm32_usbphyc_pll_init(usbphyc);
> if (ret)
> - return ret;
> + goto reg_disable;
>
> stm32_usbphyc_set_bits(pll_reg, PLLEN);
>
> - /* Wait for maximum lock time */
> - udelay(PLL_LOCK_TIME_US);
> -
> - if (!(readl(pll_reg) & PLLEN)) {
> - dev_err(usbphyc->dev, "PLLEN not set\n");
> - return -EIO;
> - }
> -
> return 0;
> -}
> -
> -static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
> -{
> - void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL;
> -
> - /* Check if other phy port active */
> - if (stm32_usbphyc_has_one_phy_active(usbphyc))
> - return 0;
>
> - stm32_usbphyc_clr_bits(pll_reg, PLLEN);
> - /* Wait for minimum width of powerdown pulse (ENABLE = Low) */
> - udelay(PLL_PWR_DOWN_TIME_US);
> +reg_disable:
> + stm32_usbphyc_regulators_disable(usbphyc);
>
> - if (readl(pll_reg) & PLLEN) {
> - dev_err(usbphyc->dev, "PLL not reset\n");
> - return -EIO;
> - }
> +dec_n_pll_cons:
> + usbphyc->n_pll_cons--;
>
> - return 0;
> + return ret;
> }
>
> static int stm32_usbphyc_phy_init(struct phy *phy)
> {
> struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
> struct stm32_usbphyc *usbphyc = usbphyc_phy->usbphyc;
> + u32 reg_mon = STM32_USBPHYC_MONITOR(usbphyc_phy->index);
> + u32 monsel = FIELD_PREP(STM32_USBPHYC_MON_SEL,
> + STM32_USBPHYC_MON_SEL_LOCKP);
> + u32 monout;
> int ret;
>
> ret = stm32_usbphyc_pll_enable(usbphyc);
> if (ret)
> return ret;
>
> + /* Check that PLL Lock input to PHY is High */
> + writel(monsel, usbphyc->base + reg_mon);
> + ret = readl_poll_timeout(usbphyc->base + reg_mon, monout,
> + (monout & STM32_USBPHYC_MON_OUT_LOCKP),
> + 1000);
> + if (ret) {
> + dev_err(usbphyc->dev, "PLL Lock input to PHY is Low (val=%x)\n",
> + (u32)(monout & STM32_USBPHYC_MON_OUT));
> + goto pll_disable;
> + }
> +
> usbphyc_phy->active = true;
>
> return 0;
> +
> +pll_disable:
> + return stm32_usbphyc_pll_disable(usbphyc);
> }
>
> static int stm32_usbphyc_phy_exit(struct phy *phy)
> @@ -230,25 +289,9 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
> return stm32_usbphyc_pll_disable(usbphyc);
> }
>
> -static int stm32_usbphyc_phy_power_on(struct phy *phy)
> -{
> - struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
> -
> - return regulator_bulk_enable(NUM_SUPPLIES, usbphyc_phy->supplies);
> -}
> -
> -static int stm32_usbphyc_phy_power_off(struct phy *phy)
> -{
> - struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
> -
> - return regulator_bulk_disable(NUM_SUPPLIES, usbphyc_phy->supplies);
> -}
> -
> static const struct phy_ops stm32_usbphyc_phy_ops = {
> .init = stm32_usbphyc_phy_init,
> .exit = stm32_usbphyc_phy_exit,
> - .power_on = stm32_usbphyc_phy_power_on,
> - .power_off = stm32_usbphyc_phy_power_off,
> };
>
> static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc,
> @@ -311,7 +354,7 @@ static int stm32_usbphyc_probe(struct device_d *dev)
> struct device_node *child, *np = dev->device_node;
> struct resource *iores;
> struct phy_provider *phy_provider;
> - u32 version;
> + u32 pllen, version;
> int ret, port = 0;
>
> usbphyc = xzalloc(sizeof(*usbphyc));
> @@ -337,17 +380,51 @@ static int stm32_usbphyc_probe(struct device_d *dev)
> goto release_region;
> }
>
> - device_reset_us(dev, 2);
> + ret = device_reset_us(dev, 2);
> + if (ret == -EPROBE_DEFER)
> + goto clk_disable;
> + if (ret)
> + stm32_usbphyc_clr_bits(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
> +
> + /*
> + * Wait for minimum width of powerdown pulse (ENABLE = Low):
> + * we have to ensure the PLL is disabled before phys initialization.
> + */
> + if (readl_poll_timeout(usbphyc->base + STM32_USBPHYC_PLL,
> + pllen, !(pllen & PLLEN), 50)) {
> + dev_warn(usbphyc->dev, "PLL not reset\n");
> + ret = -EPROBE_DEFER;
> + goto clk_disable;
> + }
>
> usbphyc->switch_setup = -EINVAL;
> usbphyc->nphys = of_get_child_count(np);
> - usbphyc->phys = xzalloc(usbphyc->nphys * sizeof(*usbphyc->phys));
> + usbphyc->phys = calloc(usbphyc->nphys, sizeof(*usbphyc->phys));
> + if (!usbphyc->phys) {
> + ret = -ENOMEM;
> + goto clk_disable;
> + }
> +
> + usbphyc->vdda1v1 = regulator_get(dev, "vdda1v1");
> + if (IS_ERR(usbphyc->vdda1v1)) {
> + ret = PTR_ERR(usbphyc->vdda1v1);
> + if (ret != -EPROBE_DEFER)
> + dev_err(dev, "failed to get vdda1v1 supply: %d\n", ret);
> + goto clk_disable;
> + }
> +
> + usbphyc->vdda1v8 = regulator_get(dev, "vdda1v8");
> + if (IS_ERR(usbphyc->vdda1v8)) {
> + ret = PTR_ERR(usbphyc->vdda1v8);
> + if (ret != -EPROBE_DEFER)
> + dev_err(dev, "failed to get vdda1v8 supply: %d\n", ret);
> + goto clk_disable;
> + }
>
> for_each_child_of_node(np, child) {
> struct stm32_usbphyc_phy *usbphyc_phy;
> struct phy *phy;
> u32 index;
> - int i;
>
> phy = phy_create(dev, child, &stm32_usbphyc_phy_ops);
> if (IS_ERR(phy)) {
> @@ -360,18 +437,6 @@ static int stm32_usbphyc_probe(struct device_d *dev)
>
> usbphyc_phy = xzalloc(sizeof(*usbphyc_phy));
>
> - for (i = 0; i < NUM_SUPPLIES; i++)
> - usbphyc_phy->supplies[i].supply = supplies_names[i];
> -
> - ret = regulator_bulk_get(&phy->dev, NUM_SUPPLIES,
> - usbphyc_phy->supplies);
> - if (ret) {
> - if (ret != -EPROBE_DEFER)
> - dev_err(&phy->dev,
> - "failed to get regulators: %d\n", ret);
> - goto clk_disable;
> - }
> -
> ret = of_property_read_u32(child, "reg", &index);
> if (ret || index > usbphyc->nphys) {
> dev_err(&phy->dev, "invalid reg property: %d\n", ret);
> @@ -417,6 +482,12 @@ release_region:
> static void stm32_usbphyc_remove(struct device_d *dev)
> {
> struct stm32_usbphyc *usbphyc = dev->priv;
> + int port;
> +
> + /* Ensure PHYs are not active, to allow PLL disabling */
> + for (port = 0; port < usbphyc->nphys; port++)
> + if (usbphyc->phys[port]->active)
> + stm32_usbphyc_phy_exit(usbphyc->phys[port]->phy);
>
> clk_disable(usbphyc->clk);
> }
> --
> 2.29.2
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-03-17 8:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-16 8:59 [PATCH 1/3] phy: stm32: sync with upstream Ahmad Fatoum
2021-03-16 8:59 ` [PATCH 2/3] ARM: stm32mp: add support for STM32MP157-EV1 board Ahmad Fatoum
2021-03-16 8:59 ` [PATCH 3/3] ARM: stm32mp: defconfig: enable DWC2 USB OTG controller Ahmad Fatoum
2021-03-17 8:39 ` [PATCH 1/3] phy: stm32: sync with upstream Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox