* [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx
@ 2023-04-21 10:06 Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 1/5] asm-generic: atomic: implement atomic_inc/dec_return stubs Ahmad Fatoum
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2023-04-21 10:06 UTC (permalink / raw)
To: barebox
I am not sure this worked for a while, but the DT binding changed.
Let's sync with the kernel driver and enable the necessary config
options and some other stuff noticed as well.
Ahmad Fatoum (5):
asm-generic: atomic: implement atomic_inc/dec_return stubs
phy: stm32-usphyc: sync with Linux v6.3-rc5
ARM: stm32mp: defconfig: enable use of DKx USB hubs
clk: bulk: return -EPROBE_DEFER in silence
ARM: stm32mp: dkx: enable deep probe
arch/arm/boards/stm32mp15xx-dkx/board.c | 2 +
arch/arm/configs/stm32mp_defconfig | 3 +
drivers/clk/clk-bulk.c | 5 +-
drivers/phy/phy-stm32-usbphyc.c | 321 ++++++++++++++++++++++--
include/asm-generic/atomic.h | 11 +-
include/linux/units.h | 111 ++++++++
6 files changed, 421 insertions(+), 32 deletions(-)
create mode 100644 include/linux/units.h
--
2.39.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/5] asm-generic: atomic: implement atomic_inc/dec_return stubs
2023-04-21 10:06 [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Ahmad Fatoum
@ 2023-04-21 10:06 ` Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 2/5] phy: stm32-usphyc: sync with Linux v6.3-rc5 Ahmad Fatoum
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2023-04-21 10:06 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
We don't have forced preemption in barebox, so we can implement these
functions with normal increment/decrement operators.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
include/asm-generic/atomic.h | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index 6e63b8e8e7b9..45fc5da57594 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -77,16 +77,19 @@ static inline void atomic_sub(int i, volatile atomic_t *v)
v->counter -= i;
}
-static inline void atomic_inc(volatile atomic_t *v)
+static inline int atomic_inc_return(volatile atomic_t *v)
{
- v->counter += 1;
+ return ++v->counter;
}
-static inline void atomic_dec(volatile atomic_t *v)
+static inline int atomic_dec_return(volatile atomic_t *v)
{
- v->counter -= 1;
+ return --v->counter;
}
+#define atomic_inc(v) ((void)atomic_inc_return(v))
+#define atomic_dec(v) ((void)atomic_dec_return(v))
+
static inline int atomic_dec_and_test(volatile atomic_t *v)
{
int val;
--
2.39.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/5] phy: stm32-usphyc: sync with Linux v6.3-rc5
2023-04-21 10:06 [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 1/5] asm-generic: atomic: implement atomic_inc/dec_return stubs Ahmad Fatoum
@ 2023-04-21 10:06 ` Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 3/5] ARM: stm32mp: defconfig: enable use of DKx USB hubs Ahmad Fatoum
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2023-04-21 10:06 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
DT binding changed in the meantime and the PHY is now clock provider
to the EHCI. Sync the driver to enable use of the EHCI.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/phy/phy-stm32-usbphyc.c | 321 +++++++++++++++++++++++++++++---
include/linux/units.h | 111 +++++++++++
2 files changed, 406 insertions(+), 26 deletions(-)
create mode 100644 include/linux/units.h
diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c
index 3ccbc7b9027a..ac82b019f44c 100644
--- a/drivers/phy/phy-stm32-usbphyc.c
+++ b/drivers/phy/phy-stm32-usbphyc.c
@@ -14,11 +14,14 @@
#include <linux/phy/phy.h>
#include <linux/reset.h>
#include <linux/math64.h>
+#include <asm-generic/atomic.h>
#include <linux/usb/phy.h>
+#include <linux/units.h>
#define STM32_USBPHYC_PLL 0x0
#define STM32_USBPHYC_MISC 0x8
#define STM32_USBPHYC_MONITOR(X) (0x108 + ((X) * 0x100))
+#define STM32_USBPHYC_TUNE(X) (0x10C + ((X) * 0x100))
#define STM32_USBPHYC_VERSION 0x3F4
/* STM32_USBPHYC_PLL bit fields */
@@ -40,6 +43,83 @@
#define STM32_USBPHYC_MON_SEL_LOCKP 0x1F
#define STM32_USBPHYC_MON_OUT_LOCKP BIT(3)
+/* STM32_USBPHYC_TUNE bit fields */
+#define INCURREN BIT(0)
+#define INCURRINT BIT(1)
+#define LFSCAPEN BIT(2)
+#define HSDRVSLEW BIT(3)
+#define HSDRVDCCUR BIT(4)
+#define HSDRVDCLEV BIT(5)
+#define HSDRVCURINCR BIT(6)
+#define FSDRVRFADJ BIT(7)
+#define HSDRVRFRED BIT(8)
+#define HSDRVCHKITRM GENMASK(12, 9)
+#define HSDRVCHKZTRM GENMASK(14, 13)
+#define OTPCOMP GENMASK(19, 15)
+#define SQLCHCTL GENMASK(21, 20)
+#define HDRXGNEQEN BIT(22)
+#define HSRXOFF GENMASK(24, 23)
+#define HSFALLPREEM BIT(25)
+#define SHTCCTCTLPROT BIT(26)
+#define STAGSEL BIT(27)
+
+enum boosting_vals {
+ BOOST_1000_UA = 1000,
+ BOOST_2000_UA = 2000,
+};
+
+enum dc_level_vals {
+ DC_NOMINAL,
+ DC_PLUS_5_TO_7_MV,
+ DC_PLUS_10_TO_14_MV,
+ DC_MINUS_5_TO_7_MV,
+ DC_MAX,
+};
+
+enum current_trim {
+ CUR_NOMINAL,
+ CUR_PLUS_1_56_PCT,
+ CUR_PLUS_3_12_PCT,
+ CUR_PLUS_4_68_PCT,
+ CUR_PLUS_6_24_PCT,
+ CUR_PLUS_7_8_PCT,
+ CUR_PLUS_9_36_PCT,
+ CUR_PLUS_10_92_PCT,
+ CUR_PLUS_12_48_PCT,
+ CUR_PLUS_14_04_PCT,
+ CUR_PLUS_15_6_PCT,
+ CUR_PLUS_17_16_PCT,
+ CUR_PLUS_19_01_PCT,
+ CUR_PLUS_20_58_PCT,
+ CUR_PLUS_22_16_PCT,
+ CUR_PLUS_23_73_PCT,
+ CUR_MAX,
+};
+
+enum impedance_trim {
+ IMP_NOMINAL,
+ IMP_MINUS_2_OHMS,
+ IMP_MINUS_4_OMHS,
+ IMP_MINUS_6_OHMS,
+ IMP_MAX,
+};
+
+enum squelch_level {
+ SQLCH_NOMINAL,
+ SQLCH_PLUS_7_MV,
+ SQLCH_MINUS_5_MV,
+ SQLCH_PLUS_14_MV,
+ SQLCH_MAX,
+};
+
+enum rx_offset {
+ NO_RX_OFFSET,
+ RX_OFFSET_PLUS_5_MV,
+ RX_OFFSET_PLUS_10_MV,
+ RX_OFFSET_MINUS_5_MV,
+ RX_OFFSET_MAX,
+};
+
/* STM32_USBPHYC_VERSION bit fields */
#define MINREV GENMASK(3, 0)
#define MAJREV GENMASK(7, 4)
@@ -47,7 +127,6 @@
#define PLL_FVCO_MHZ 2880
#define PLL_INFF_MIN_RATE_HZ 19200000
#define PLL_INFF_MAX_RATE_HZ 38400000
-#define HZ_PER_MHZ 1000000L
struct pll_params {
u8 ndiv;
@@ -57,30 +136,34 @@ struct pll_params {
struct stm32_usbphyc_phy {
struct phy *phy;
struct stm32_usbphyc *usbphyc;
+ struct regulator *vbus;
u32 index;
bool active;
+ u32 tune;
};
struct stm32_usbphyc {
struct device *dev;
void __iomem *base;
struct clk *clk;
+ struct reset_control *rst;
struct stm32_usbphyc_phy **phys;
int nphys;
struct regulator *vdda1v1;
struct regulator *vdda1v8;
- int n_pll_cons;
+ atomic_t n_pll_cons;
+ struct clk_hw clk48_hw;
int switch_setup;
};
static inline void stm32_usbphyc_set_bits(void __iomem *reg, u32 bits)
{
- writel(readl(reg) | bits, reg);
+ writel_relaxed(readl_relaxed(reg) | bits, reg);
}
static inline void stm32_usbphyc_clr_bits(void __iomem *reg, u32 bits)
{
- writel(readl(reg) & ~bits, reg);
+ writel_relaxed(readl_relaxed(reg) & ~bits, reg);
}
static int stm32_usbphyc_regulators_enable(struct stm32_usbphyc *usbphyc)
@@ -168,7 +251,7 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc)
if (pll_params.frac)
usbphyc_pll |= PLLFRACCTL | frac;
- writel(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL);
+ writel_relaxed(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL);
dev_dbg(usbphyc->dev, "input clk freq=%dHz, ndiv=%lu, frac=%lu\n",
clk_rate, FIELD_GET(PLLNDIV, usbphyc_pll),
@@ -185,7 +268,7 @@ static int __stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
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))
+ if (readl_relaxed_poll_timeout(pll_reg, pllen, !(pllen & PLLEN), 50))
dev_err(usbphyc->dev, "PLL not reset\n");
return stm32_usbphyc_regulators_disable(usbphyc);
@@ -194,7 +277,7 @@ static int __stm32_usbphyc_pll_disable(struct stm32_usbphyc *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)
+ if (atomic_dec_return(&usbphyc->n_pll_cons) > 0)
return 0;
return __stm32_usbphyc_pll_disable(usbphyc);
@@ -203,14 +286,14 @@ static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *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_relaxed(pll_reg) & PLLEN;
int ret;
/*
* 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)
+ if (atomic_inc_return(&usbphyc->n_pll_cons) > 1 && pllen)
return 0;
if (pllen) {
@@ -222,7 +305,7 @@ static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
ret = __stm32_usbphyc_pll_disable(usbphyc);
if (ret)
- return ret;
+ goto dec_n_pll_cons;
}
ret = stm32_usbphyc_regulators_enable(usbphyc);
@@ -241,7 +324,7 @@ reg_disable:
stm32_usbphyc_regulators_disable(usbphyc);
dec_n_pll_cons:
- usbphyc->n_pll_cons--;
+ atomic_dec(&usbphyc->n_pll_cons);
return ret;
}
@@ -261,10 +344,10 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
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);
+ writel_relaxed(monsel, usbphyc->base + reg_mon);
+ ret = readl_relaxed_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));
@@ -285,7 +368,9 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
return 0;
pll_disable:
- return stm32_usbphyc_pll_disable(usbphyc);
+ stm32_usbphyc_pll_disable(usbphyc);
+
+ return ret;
}
static int stm32_usbphyc_phy_exit(struct phy *phy)
@@ -298,11 +383,177 @@ 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);
+
+ if (usbphyc_phy->vbus)
+ return regulator_enable(usbphyc_phy->vbus);
+
+ return 0;
+}
+
+static int stm32_usbphyc_phy_power_off(struct phy *phy)
+{
+ struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
+
+ if (usbphyc_phy->vbus)
+ return regulator_disable(usbphyc_phy->vbus);
+
+ return 0;
+}
+
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 int stm32_usbphyc_clk48_prepare(struct clk_hw *hw)
+{
+ struct stm32_usbphyc *usbphyc = container_of(hw, struct stm32_usbphyc, clk48_hw);
+
+ return stm32_usbphyc_pll_enable(usbphyc);
+}
+
+static void stm32_usbphyc_clk48_unprepare(struct clk_hw *hw)
+{
+ struct stm32_usbphyc *usbphyc = container_of(hw, struct stm32_usbphyc, clk48_hw);
+
+ stm32_usbphyc_pll_disable(usbphyc);
+}
+
+static unsigned long stm32_usbphyc_clk48_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ return 48000000;
+}
+
+static const struct clk_ops usbphyc_clk48_ops = {
+ .enable = stm32_usbphyc_clk48_prepare,
+ .disable = stm32_usbphyc_clk48_unprepare,
+ .recalc_rate = stm32_usbphyc_clk48_recalc_rate,
+};
+
+static int stm32_usbphyc_clk48_register(struct stm32_usbphyc *usbphyc)
+{
+ struct device_node *node = usbphyc->dev->of_node;
+ struct clk_init_data init = { };
+ int ret = 0;
+
+ init.name = "ck_usbo_48m";
+ init.ops = &usbphyc_clk48_ops;
+
+ usbphyc->clk48_hw.init = &init;
+
+ ret = clk_hw_register(usbphyc->dev, &usbphyc->clk48_hw);
+ if (ret)
+ return ret;
+
+ return of_clk_add_hw_provider(node, of_clk_hw_simple_get, &usbphyc->clk48_hw);
+}
+
+static void stm32_usbphyc_phy_tuning(struct stm32_usbphyc *usbphyc,
+ struct device_node *np, u32 index)
+{
+ struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys[index];
+ u32 reg = STM32_USBPHYC_TUNE(index);
+ u32 otpcomp, val;
+ int ret;
+
+ /* Backup OTP compensation code */
+ otpcomp = FIELD_GET(OTPCOMP, readl_relaxed(usbphyc->base + reg));
+
+ ret = of_property_read_u32(np, "st,current-boost-microamp", &val);
+ if (ret != -EINVAL) {
+ if (!ret && (val == BOOST_1000_UA || val == BOOST_2000_UA)) {
+ val = (val == BOOST_2000_UA) ? 1 : 0;
+ usbphyc_phy->tune |= INCURREN | FIELD_PREP(INCURRINT, val);
+ } else {
+ dev_warn(usbphyc->dev, "phy%d: invalid st,current-boost-microamp\n", index);
+ }
+ }
+
+ if (!of_property_read_bool(np, "st,no-lsfs-fb-cap"))
+ usbphyc_phy->tune |= LFSCAPEN;
+
+ if (of_property_read_bool(np, "st,decrease-hs-slew-rate"))
+ usbphyc_phy->tune |= HSDRVSLEW;
+
+ ret = of_property_read_u32(np, "st,tune-hs-dc-level", &val);
+ if (ret != -EINVAL) {
+ if (!ret && val < DC_MAX) {
+ if (val == DC_MINUS_5_TO_7_MV) {/* Decreases HS driver DC level */
+ usbphyc_phy->tune |= HSDRVDCCUR;
+ } else if (val > 0) { /* Increases HS driver DC level */
+ val = (val == DC_PLUS_10_TO_14_MV) ? 1 : 0;
+ usbphyc_phy->tune |= HSDRVCURINCR | FIELD_PREP(HSDRVDCLEV, val);
+ }
+ } else {
+ dev_warn(usbphyc->dev, "phy%d: invalid st,tune-hs-dc-level\n", index);
+ }
+ }
+
+ if (of_property_read_bool(np, "st,enable-fs-rftime-tuning"))
+ usbphyc_phy->tune |= FSDRVRFADJ;
+
+ if (of_property_read_bool(np, "st,enable-hs-rftime-reduction"))
+ usbphyc_phy->tune |= HSDRVRFRED;
+
+ ret = of_property_read_u32(np, "st,trim-hs-current", &val);
+ if (ret != -EINVAL) {
+ if (!ret && val < CUR_MAX)
+ usbphyc_phy->tune |= FIELD_PREP(HSDRVCHKITRM, val);
+ else
+ dev_warn(usbphyc->dev, "phy%d: invalid st,trim-hs-current\n", index);
+ }
+
+ ret = of_property_read_u32(np, "st,trim-hs-impedance", &val);
+ if (ret != -EINVAL) {
+ if (!ret && val < IMP_MAX)
+ usbphyc_phy->tune |= FIELD_PREP(HSDRVCHKZTRM, val);
+ else
+ dev_warn(usbphyc->dev, "phy%d: invalid st,trim-hs-impedance\n", index);
+ }
+
+ ret = of_property_read_u32(np, "st,tune-squelch-level", &val);
+ if (ret != -EINVAL) {
+ if (!ret && val < SQLCH_MAX)
+ usbphyc_phy->tune |= FIELD_PREP(SQLCHCTL, val);
+ else
+ dev_warn(usbphyc->dev, "phy%d: invalid st,tune-squelch\n", index);
+ }
+
+ if (of_property_read_bool(np, "st,enable-hs-rx-gain-eq"))
+ usbphyc_phy->tune |= HDRXGNEQEN;
+
+ ret = of_property_read_u32(np, "st,tune-hs-rx-offset", &val);
+ if (ret != -EINVAL) {
+ if (!ret && val < RX_OFFSET_MAX)
+ usbphyc_phy->tune |= FIELD_PREP(HSRXOFF, val);
+ else
+ dev_warn(usbphyc->dev, "phy%d: invalid st,tune-hs-rx-offset\n", index);
+ }
+
+ if (of_property_read_bool(np, "st,no-hs-ftime-ctrl"))
+ usbphyc_phy->tune |= HSFALLPREEM;
+
+ if (!of_property_read_bool(np, "st,no-lsfs-sc"))
+ usbphyc_phy->tune |= SHTCCTCTLPROT;
+
+ if (of_property_read_bool(np, "st,enable-hs-tx-staggering"))
+ usbphyc_phy->tune |= STAGSEL;
+
+ /* Restore OTP compensation code */
+ usbphyc_phy->tune |= FIELD_PREP(OTPCOMP, otpcomp);
+
+ /*
+ * By default, if no st,xxx tuning property is used, usbphyc_phy->tune is equal to
+ * STM32_USBPHYC_TUNE reset value (LFSCAPEN | SHTCCTCTLPROT | OTPCOMP).
+ */
+ writel_relaxed(usbphyc_phy->tune, usbphyc->base + reg);
+}
+
static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc,
u32 utmi_switch)
{
@@ -399,8 +650,8 @@ static int stm32_usbphyc_probe(struct device *dev)
* 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)) {
+ if (readl_relaxed_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;
@@ -416,17 +667,15 @@ static int stm32_usbphyc_probe(struct device *dev)
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);
+ ret = dev_err_probe(dev, PTR_ERR(usbphyc->vdda1v1),
+ "failed to get vdda1v1 supply\n");
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);
+ ret = dev_err_probe(dev, PTR_ERR(usbphyc->vdda1v8),
+ "failed to get vdda1v8 supply\n");
goto clk_disable;
}
@@ -456,6 +705,8 @@ static int stm32_usbphyc_probe(struct device *dev)
ret = of_property_read_u32(child, "reg", &index);
if (ret || index > usbphyc->nphys) {
dev_err(&phy->dev, "invalid reg property: %d\n", ret);
+ if (!ret)
+ ret = -EINVAL;
goto clk_disable;
}
@@ -468,6 +719,17 @@ static int stm32_usbphyc_probe(struct device *dev)
usbphyc->phys[port]->index = index;
usbphyc->phys[port]->active = false;
+ usbphyc->phys[port]->vbus = regulator_get(&phy->dev, "vbus");
+ if (IS_ERR(usbphyc->phys[port]->vbus)) {
+ ret = PTR_ERR(usbphyc->phys[port]->vbus);
+ if (ret == -EPROBE_DEFER)
+ goto clk_disable;
+ usbphyc->phys[port]->vbus = NULL;
+ }
+
+ /* Configure phy tuning */
+ stm32_usbphyc_phy_tuning(usbphyc, child, index);
+
port++;
}
@@ -478,8 +740,14 @@ static int stm32_usbphyc_probe(struct device *dev)
goto clk_disable;
}
- version = readl(usbphyc->base + STM32_USBPHYC_VERSION);
- dev_info(dev, "registered rev: %lu.%lu\n",
+ ret = stm32_usbphyc_clk48_register(usbphyc);
+ if (ret) {
+ dev_err(dev, "failed to register ck_usbo_48m clock: %d\n", ret);
+ goto clk_disable;
+ }
+
+ version = readl_relaxed(usbphyc->base + STM32_USBPHYC_VERSION);
+ dev_info(dev, "registered rev:%lu.%lu\n",
FIELD_GET(MAJREV, version), FIELD_GET(MINREV, version));
return 0;
@@ -512,6 +780,7 @@ static const struct of_device_id stm32_usbphyc_of_match[] = {
{ .compatible = "st,stm32mp1-usbphyc", },
{ /* sentinel */ },
};
+MODULE_DEVICE_TABLE(of, stm32_usbphyc_of_match);
static struct driver stm32_usbphyc_driver = {
.name = "stm32-usbphyc",
diff --git a/include/linux/units.h b/include/linux/units.h
new file mode 100644
index 000000000000..120a2fc87b13
--- /dev/null
+++ b/include/linux/units.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_UNITS_H
+#define _LINUX_UNITS_H
+
+#include <linux/kernel.h>
+
+/* Metric prefixes in accordance with Système international (d'unités) */
+#define PETA 1000000000000000ULL
+#define TERA 1000000000000ULL
+#define GIGA 1000000000UL
+#define MEGA 1000000UL
+#define KILO 1000UL
+#define HECTO 100UL
+#define DECA 10UL
+#define DECI 10UL
+#define CENTI 100UL
+#define MILLI 1000UL
+#define MICRO 1000000UL
+#define NANO 1000000000UL
+#define PICO 1000000000000ULL
+#define FEMTO 1000000000000000ULL
+
+#define NANOHZ_PER_HZ 1000000000UL
+#define MICROHZ_PER_HZ 1000000UL
+#define MILLIHZ_PER_HZ 1000UL
+#define HZ_PER_KHZ 1000UL
+#define KHZ_PER_MHZ 1000UL
+#define HZ_PER_MHZ 1000000UL
+
+#define MILLIWATT_PER_WATT 1000UL
+#define MICROWATT_PER_MILLIWATT 1000UL
+#define MICROWATT_PER_WATT 1000000UL
+
+#define ABSOLUTE_ZERO_MILLICELSIUS -273150
+
+static inline long milli_kelvin_to_millicelsius(long t)
+{
+ return t + ABSOLUTE_ZERO_MILLICELSIUS;
+}
+
+static inline long millicelsius_to_milli_kelvin(long t)
+{
+ return t - ABSOLUTE_ZERO_MILLICELSIUS;
+}
+
+#define MILLIDEGREE_PER_DEGREE 1000
+#define MILLIDEGREE_PER_DECIDEGREE 100
+
+static inline long kelvin_to_millicelsius(long t)
+{
+ return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DEGREE);
+}
+
+static inline long millicelsius_to_kelvin(long t)
+{
+ t = millicelsius_to_milli_kelvin(t);
+
+ return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE);
+}
+
+static inline long deci_kelvin_to_celsius(long t)
+{
+ t = milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE);
+
+ return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE);
+}
+
+static inline long celsius_to_deci_kelvin(long t)
+{
+ t = millicelsius_to_milli_kelvin(t * MILLIDEGREE_PER_DEGREE);
+
+ return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE);
+}
+
+/**
+ * deci_kelvin_to_millicelsius_with_offset - convert Kelvin to Celsius
+ * @t: temperature value in decidegrees Kelvin
+ * @offset: difference between Kelvin and Celsius in millidegrees
+ *
+ * Return: temperature value in millidegrees Celsius
+ */
+static inline long deci_kelvin_to_millicelsius_with_offset(long t, long offset)
+{
+ return t * MILLIDEGREE_PER_DECIDEGREE - offset;
+}
+
+static inline long deci_kelvin_to_millicelsius(long t)
+{
+ return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE);
+}
+
+static inline long millicelsius_to_deci_kelvin(long t)
+{
+ t = millicelsius_to_milli_kelvin(t);
+
+ return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE);
+}
+
+static inline long kelvin_to_celsius(long t)
+{
+ return t + DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS,
+ MILLIDEGREE_PER_DEGREE);
+}
+
+static inline long celsius_to_kelvin(long t)
+{
+ return t - DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS,
+ MILLIDEGREE_PER_DEGREE);
+}
+
+#endif /* _LINUX_UNITS_H */
--
2.39.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/5] ARM: stm32mp: defconfig: enable use of DKx USB hubs
2023-04-21 10:06 [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 1/5] asm-generic: atomic: implement atomic_inc/dec_return stubs Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 2/5] phy: stm32-usphyc: sync with Linux v6.3-rc5 Ahmad Fatoum
@ 2023-04-21 10:06 ` Ahmad Fatoum
2023-04-21 10:36 ` Marco Felsch
2023-04-21 10:06 ` [PATCH 4/5] clk: bulk: return -EPROBE_DEFER in silence Ahmad Fatoum
` (2 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Ahmad Fatoum @ 2023-04-21 10:06 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The DK1/DK2 boards have an on-board USB-Hub with togglable power supply,
which is connected to the SoC's EHCI. Enable the necessary options to
make it usable. This was tested with the mass storage support (barebox
being host, not gadget), so enable that as well.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/configs/stm32mp_defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/configs/stm32mp_defconfig b/arch/arm/configs/stm32mp_defconfig
index f6c6ca71b15c..df73102ba1c0 100644
--- a/arch/arm/configs/stm32mp_defconfig
+++ b/arch/arm/configs/stm32mp_defconfig
@@ -115,6 +115,9 @@ CONFIG_MTD_SST25L=y
CONFIG_USB_HOST=y
CONFIG_USB_DWC2_HOST=y
CONFIG_USB_DWC2_GADGET=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_ONBOARD_HUB=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DFU=y
CONFIG_USB_GADGET_SERIAL=y
--
2.39.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/5] clk: bulk: return -EPROBE_DEFER in silence
2023-04-21 10:06 [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Ahmad Fatoum
` (2 preceding siblings ...)
2023-04-21 10:06 ` [PATCH 3/5] ARM: stm32mp: defconfig: enable use of DKx USB hubs Ahmad Fatoum
@ 2023-04-21 10:06 ` Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 5/5] ARM: stm32mp: dkx: enable deep probe Ahmad Fatoum
2023-05-02 11:36 ` [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Sascha Hauer
5 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2023-04-21 10:06 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
-EPROBE_DEFER is only an error if driver core doesn't expect it. Change
it, so error message is only printed for other kinds of errors.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/clk/clk-bulk.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
index 37982db9aa55..db775dc40b39 100644
--- a/drivers/clk/clk-bulk.c
+++ b/drivers/clk/clk-bulk.c
@@ -88,8 +88,9 @@ static int __must_check of_clk_bulk_get(struct device_node *np, int num_clks,
clks[i].clk = of_clk_get(np, i);
if (IS_ERR(clks[i].clk)) {
ret = PTR_ERR(clks[i].clk);
- pr_err("%s: Failed to get clk index: %d ret: %pe\n",
- np->name, i, clks[i].clk);
+ if (ret != -EPROBE_DEFER)
+ pr_err("%s: Failed to get clk index: %d ret: %pe\n",
+ np->name, i, clks[i].clk);
clks[i].clk = NULL;
goto err;
}
--
2.39.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/5] ARM: stm32mp: dkx: enable deep probe
2023-04-21 10:06 [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Ahmad Fatoum
` (3 preceding siblings ...)
2023-04-21 10:06 ` [PATCH 4/5] clk: bulk: return -EPROBE_DEFER in silence Ahmad Fatoum
@ 2023-04-21 10:06 ` Ahmad Fatoum
2023-05-02 11:36 ` [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Sascha Hauer
5 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2023-04-21 10:06 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
This wasn't enabled before, because the USB parts needed some love to be
deep probe compatible. This has been done in the meantime, so let's
enable it. No functional change expected, except that probe deferral
shouldn't happen anymore.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/boards/stm32mp15xx-dkx/board.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boards/stm32mp15xx-dkx/board.c b/arch/arm/boards/stm32mp15xx-dkx/board.c
index b00781769ba5..1783c5ca17af 100644
--- a/arch/arm/boards/stm32mp15xx-dkx/board.c
+++ b/arch/arm/boards/stm32mp15xx-dkx/board.c
@@ -2,6 +2,7 @@
#include <common.h>
#include <init.h>
#include <mach/stm32mp/bbu.h>
+#include <deep-probe.h>
static int dkx_probe(struct device *dev)
{
@@ -23,6 +24,7 @@ static const struct of_device_id dkx_of_match[] = {
{ .compatible = "st,stm32mp157c-dk2", .data = "STM32MP157C-DK2" },
{ /* sentinel */ },
};
+BAREBOX_DEEP_PROBE_ENABLE(dkx_of_match);
static struct driver dkx_board_driver = {
.name = "board-stm32mp15xx-dkx",
--
2.39.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/5] ARM: stm32mp: defconfig: enable use of DKx USB hubs
2023-04-21 10:06 ` [PATCH 3/5] ARM: stm32mp: defconfig: enable use of DKx USB hubs Ahmad Fatoum
@ 2023-04-21 10:36 ` Marco Felsch
2023-04-21 10:51 ` Ahmad Fatoum
0 siblings, 1 reply; 9+ messages in thread
From: Marco Felsch @ 2023-04-21 10:36 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
Hi Ahmad,
On 23-04-21, Ahmad Fatoum wrote:
> The DK1/DK2 boards have an on-board USB-Hub with togglable power supply,
> which is connected to the SoC's EHCI. Enable the necessary options to
> make it usable. This was tested with the mass storage support (barebox
> being host, not gadget), so enable that as well.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> arch/arm/configs/stm32mp_defconfig | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/arm/configs/stm32mp_defconfig b/arch/arm/configs/stm32mp_defconfig
> index f6c6ca71b15c..df73102ba1c0 100644
> --- a/arch/arm/configs/stm32mp_defconfig
> +++ b/arch/arm/configs/stm32mp_defconfig
> @@ -115,6 +115,9 @@ CONFIG_MTD_SST25L=y
> CONFIG_USB_HOST=y
> CONFIG_USB_DWC2_HOST=y
> CONFIG_USB_DWC2_GADGET=y
> +CONFIG_USB_EHCI=y
> +CONFIG_USB_STORAGE=y
> +CONFIG_USB_ONBOARD_HUB=y
While USB_EHCI and USB_STORAGE is already part of the the
mulit_v7_defconfig, USB_ONBOARD_HUB isn't. Can you please enable it
there as well?
Regards,
Marco
> CONFIG_USB_GADGET=y
> CONFIG_USB_GADGET_DFU=y
> CONFIG_USB_GADGET_SERIAL=y
> --
> 2.39.2
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/5] ARM: stm32mp: defconfig: enable use of DKx USB hubs
2023-04-21 10:36 ` Marco Felsch
@ 2023-04-21 10:51 ` Ahmad Fatoum
0 siblings, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2023-04-21 10:51 UTC (permalink / raw)
To: Marco Felsch; +Cc: barebox
Hello Marco,
On 21.04.23 12:36, Marco Felsch wrote:
> Hi Ahmad,
>
> On 23-04-21, Ahmad Fatoum wrote:
>> The DK1/DK2 boards have an on-board USB-Hub with togglable power supply,
>> which is connected to the SoC's EHCI. Enable the necessary options to
>> make it usable. This was tested with the mass storage support (barebox
>> being host, not gadget), so enable that as well.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> arch/arm/configs/stm32mp_defconfig | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/arch/arm/configs/stm32mp_defconfig b/arch/arm/configs/stm32mp_defconfig
>> index f6c6ca71b15c..df73102ba1c0 100644
>> --- a/arch/arm/configs/stm32mp_defconfig
>> +++ b/arch/arm/configs/stm32mp_defconfig
>> @@ -115,6 +115,9 @@ CONFIG_MTD_SST25L=y
>> CONFIG_USB_HOST=y
>> CONFIG_USB_DWC2_HOST=y
>> CONFIG_USB_DWC2_GADGET=y
>> +CONFIG_USB_EHCI=y
>> +CONFIG_USB_STORAGE=y
>> +CONFIG_USB_ONBOARD_HUB=y
>
> While USB_EHCI and USB_STORAGE is already part of the the
> mulit_v7_defconfig, USB_ONBOARD_HUB isn't. Can you please enable it
> there as well?
I just sent a separate patch to that effect.
Cheers,
Ahmad
>
> Regards,
> Marco
>
>> CONFIG_USB_GADGET=y
>> CONFIG_USB_GADGET_DFU=y
>> CONFIG_USB_GADGET_SERIAL=y
>> --
>> 2.39.2
>>
>>
>>
>
--
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 |
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx
2023-04-21 10:06 [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Ahmad Fatoum
` (4 preceding siblings ...)
2023-04-21 10:06 ` [PATCH 5/5] ARM: stm32mp: dkx: enable deep probe Ahmad Fatoum
@ 2023-05-02 11:36 ` Sascha Hauer
5 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2023-05-02 11:36 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Fri, Apr 21, 2023 at 12:06:37PM +0200, Ahmad Fatoum wrote:
> I am not sure this worked for a while, but the DT binding changed.
> Let's sync with the kernel driver and enable the necessary config
> options and some other stuff noticed as well.
>
> Ahmad Fatoum (5):
> asm-generic: atomic: implement atomic_inc/dec_return stubs
> phy: stm32-usphyc: sync with Linux v6.3-rc5
> ARM: stm32mp: defconfig: enable use of DKx USB hubs
> clk: bulk: return -EPROBE_DEFER in silence
> ARM: stm32mp: dkx: enable deep probe
Applied, thanks
Sascha
>
> arch/arm/boards/stm32mp15xx-dkx/board.c | 2 +
> arch/arm/configs/stm32mp_defconfig | 3 +
> drivers/clk/clk-bulk.c | 5 +-
> drivers/phy/phy-stm32-usbphyc.c | 321 ++++++++++++++++++++++--
> include/asm-generic/atomic.h | 11 +-
> include/linux/units.h | 111 ++++++++
> 6 files changed, 421 insertions(+), 32 deletions(-)
> create mode 100644 include/linux/units.h
>
> --
> 2.39.2
>
>
>
--
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 |
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-05-02 11:37 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-21 10:06 [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 1/5] asm-generic: atomic: implement atomic_inc/dec_return stubs Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 2/5] phy: stm32-usphyc: sync with Linux v6.3-rc5 Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 3/5] ARM: stm32mp: defconfig: enable use of DKx USB hubs Ahmad Fatoum
2023-04-21 10:36 ` Marco Felsch
2023-04-21 10:51 ` Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 4/5] clk: bulk: return -EPROBE_DEFER in silence Ahmad Fatoum
2023-04-21 10:06 ` [PATCH 5/5] ARM: stm32mp: dkx: enable deep probe Ahmad Fatoum
2023-05-02 11:36 ` [PATCH 0/5] ARM: stm32mp: enable UBS hubs on DKx Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox