summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/clk-uclass.c27
-rw-r--r--drivers/clk/rockchip/clk_rk3308.c2
-rw-r--r--drivers/core/device.c2
-rw-r--r--drivers/net/gmac_rockchip.c2
-rw-r--r--include/clk.h30
5 files changed, 46 insertions, 17 deletions
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 3d2344f009..cac0f6a012 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -207,7 +207,8 @@ static struct clk *clk_set_default_get_by_id(struct clk *clk)
return c;
}
-static int clk_set_default_parents(struct udevice *dev, int stage)
+static int clk_set_default_parents(struct udevice *dev,
+ enum clk_defaults_stage stage)
{
struct clk clk, parent_clk, *c, *p;
int index;
@@ -260,10 +261,10 @@ static int clk_set_default_parents(struct udevice *dev, int stage)
* It cannot be done right now but need to wait after the
* device is probed
*/
- if (stage == 0 && clk.dev == dev)
+ if (stage == CLK_DEFAULTS_PRE && clk.dev == dev)
continue;
- if (stage > 0 && clk.dev != dev)
+ if (stage != CLK_DEFAULTS_PRE && clk.dev != dev)
/* do not setup twice the parent clocks */
continue;
@@ -289,7 +290,8 @@ static int clk_set_default_parents(struct udevice *dev, int stage)
return 0;
}
-static int clk_set_default_rates(struct udevice *dev, int stage)
+static int clk_set_default_rates(struct udevice *dev,
+ enum clk_defaults_stage stage)
{
struct clk clk, *c;
int index;
@@ -338,10 +340,10 @@ static int clk_set_default_rates(struct udevice *dev, int stage)
* It cannot be done right now but need to wait after the
* device is probed
*/
- if (stage == 0 && clk.dev == dev)
+ if (stage == CLK_DEFAULTS_PRE && clk.dev == dev)
continue;
- if (stage > 0 && clk.dev != dev)
+ if (stage != CLK_DEFAULTS_PRE && clk.dev != dev)
/* do not setup twice the parent clocks */
continue;
@@ -364,16 +366,21 @@ fail:
return ret;
}
-int clk_set_defaults(struct udevice *dev, int stage)
+int clk_set_defaults(struct udevice *dev, enum clk_defaults_stage stage)
{
int ret;
if (!dev_has_ofnode(dev))
return 0;
- /* If this not in SPL and pre-reloc state, don't take any action. */
+ /*
+ * To avoid setting defaults twice, don't set them before relocation.
+ * However, still set them for SPL. And still set them if explicitly
+ * asked.
+ */
if (!(IS_ENABLED(CONFIG_SPL_BUILD) || (gd->flags & GD_FLG_RELOC)))
- return 0;
+ if (stage != CLK_DEFAULTS_POST_FORCE)
+ return 0;
debug("%s(%s)\n", __func__, dev_read_name(dev));
@@ -844,7 +851,7 @@ int clk_uclass_post_probe(struct udevice *dev)
* where the DT is used to setup default parents and rates
* using assigned-clocks
*/
- clk_set_defaults(dev, 1);
+ clk_set_defaults(dev, CLK_DEFAULTS_POST);
return 0;
}
diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c
index 5a838b9e9a..5248e59685 100644
--- a/drivers/clk/rockchip/clk_rk3308.c
+++ b/drivers/clk/rockchip/clk_rk3308.c
@@ -1014,7 +1014,7 @@ static int rk3308_clk_probe(struct udevice *dev)
rk3308_clk_init(dev);
/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
- ret = clk_set_defaults(dev, 1);
+ ret = clk_set_defaults(dev, CLK_DEFAULTS_POST);
if (ret)
debug("%s clk_set_defaults failed %d\n", __func__, ret);
diff --git a/drivers/core/device.c b/drivers/core/device.c
index cb960f8ec4..9f1400768d 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -561,7 +561,7 @@ int device_probe(struct udevice *dev)
* Process 'assigned-{clocks/clock-parents/clock-rates}'
* properties
*/
- ret = clk_set_defaults(dev, 0);
+ ret = clk_set_defaults(dev, CLK_DEFAULTS_PRE);
if (ret)
goto fail;
}
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index f909660484..04008d2b19 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -565,7 +565,7 @@ static int gmac_rockchip_probe(struct udevice *dev)
ulong rate;
int ret;
- ret = clk_set_defaults(dev, 0);
+ ret = clk_set_defaults(dev, CLK_DEFAULTS_PRE);
if (ret)
debug("%s clk_set_defaults failed %d\n", __func__, ret);
diff --git a/include/clk.h b/include/clk.h
index ca6b85fa6f..f3c88fe68a 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -277,19 +277,41 @@ static inline int clk_release_all(struct clk *clk, int count)
}
#endif
+/**
+ * enum clk_defaults_stage - What stage clk_set_defaults() is called at
+ * @CLK_DEFAULTS_PRE: Called before probe. Setting of defaults for clocks owned
+ * by this clock driver will be defered until after probing.
+ * @CLK_DEFAULTS_POST: Called after probe. Only defaults for clocks owned by
+ * this clock driver will be set.
+ * @CLK_DEFAULTS_POST_FORCE: Called after probe, and always set defaults, even
+ * before relocation. Usually, defaults are not set
+ * pre-relocation to avoid setting them twice (when
+ * the device is probed again post-relocation). This
+ * may incur a performance cost as device tree
+ * properties must be parsed for a second time.
+ * However, when not using SPL, pre-relocation may be
+ * the only time we can set defaults for some clocks
+ * (such as those used for the RAM we will relocate
+ * into).
+ */
+enum clk_defaults_stage {
+ CLK_DEFAULTS_PRE = 0,
+ CLK_DEFAULTS_POST = 1,
+ CLK_DEFAULTS_POST_FORCE,
+};
+
#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \
CONFIG_IS_ENABLED(CLK)
+
/**
* clk_set_defaults - Process 'assigned-{clocks/clock-parents/clock-rates}'
* properties to configure clocks
*
* @dev: A device to process (the ofnode associated with this device
* will be processed).
- * @stage: A integer. 0 indicates that this is called before the device
- * is probed. 1 indicates that this is called just after the
- * device has been probed
+ * @stage: The stage of the probing process this function is called during.
*/
-int clk_set_defaults(struct udevice *dev, int stage);
+int clk_set_defaults(struct udevice *dev, enum clk_defaults_stage stage);
#else
static inline int clk_set_defaults(struct udevice *dev, int stage)
{