[PATCH v2 0/2] Tegra: fix clock init

This should fix https://lore.kernel.org/all/20241201164810.GT3600562@bill-the-cat/T/#m2b62b4...
--- Changes from v1 - added partially support PLL clocks commit ---
Svyatoslav Ryhel (2): driver: clk: tegra: partially support PLL clocks driver: clk: tegra: init basic clocks on probe
drivers/clk/tegra/tegra-car-clk.c | 52 +++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 10 deletions(-)

Return PLL id into struct clk if PLL is parsed from device tree instead of throwing an error. Allow requesting PLL clock rate via get_rate op.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- drivers/clk/tegra/tegra-car-clk.c | 49 ++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/tegra/tegra-car-clk.c b/drivers/clk/tegra/tegra-car-clk.c index 1d61f8dc378..dd4d7791120 100644 --- a/drivers/clk/tegra/tegra-car-clk.c +++ b/drivers/clk/tegra/tegra-car-clk.c @@ -10,6 +10,9 @@ #include <asm/arch/clock.h> #include <asm/arch-tegra/clk_rst.h>
+#define TEGRA_CAR_CLK_PLL BIT(0) +#define TEGRA_CAR_CLK_PERIPH BIT(1) + static int tegra_car_clk_request(struct clk *clk) { debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, @@ -20,30 +23,50 @@ static int tegra_car_clk_request(struct clk *clk) * varies per SoC) are the peripheral clocks, which use a numbering * scheme that matches HW registers 1:1. There are other clock IDs * beyond this that are assigned arbitrarily by the Tegra CAR DT - * binding. Due to the implementation of this driver, it currently - * only supports the peripheral IDs. + * binding. */ - if (clk->id >= PERIPH_ID_COUNT) - return -EINVAL; + if (!(clk->id >= PERIPH_ID_COUNT)) { + clk->data |= TEGRA_CAR_CLK_PERIPH; + return 0; + }
- return 0; + /* If check for periph failed, then check for PLL clock id */ + int id = clk_id_to_pll_id(clk->id); + + if (clock_id_is_pll(id)) { + clk->id = id; + clk->data |= TEGRA_CAR_CLK_PLL; + return 0; + } + + return -EINVAL; }
static ulong tegra_car_clk_get_rate(struct clk *clk) { - enum clock_id parent; + if (clk->data & TEGRA_CAR_CLK_PLL) + return clock_get_rate(clk->id);
- debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, - clk->id); + if (clk->data & TEGRA_CAR_CLK_PERIPH) { + enum clock_id parent;
- parent = clock_get_periph_parent(clk->id); - return clock_get_periph_rate(clk->id, parent); + debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, + clk, clk->dev, clk->id); + + parent = clock_get_periph_parent(clk->id); + return clock_get_periph_rate(clk->id, parent); + } + + return -1U; }
static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate) { enum clock_id parent;
+ if (clk->data & TEGRA_CAR_CLK_PLL) + return 0; + debug("%s(clk=%p, rate=%lu) (dev=%p, id=%lu)\n", __func__, clk, rate, clk->dev, clk->id);
@@ -53,6 +76,9 @@ static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate)
static int tegra_car_clk_enable(struct clk *clk) { + if (clk->data & TEGRA_CAR_CLK_PLL) + return 0; + debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id);
@@ -63,6 +89,9 @@ static int tegra_car_clk_enable(struct clk *clk)
static int tegra_car_clk_disable(struct clk *clk) { + if (clk->data & TEGRA_CAR_CLK_PLL) + return 0; + debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id);

On Thu, Dec 12, 2024 at 12:06:45PM +0200, Svyatoslav Ryhel wrote:
Return PLL id into struct clk if PLL is parsed from device tree instead of throwing an error. Allow requesting PLL clock rate via get_rate op.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com
drivers/clk/tegra/tegra-car-clk.c | 49 ++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/tegra/tegra-car-clk.c b/drivers/clk/tegra/tegra-car-clk.c index 1d61f8dc378..dd4d7791120 100644 --- a/drivers/clk/tegra/tegra-car-clk.c +++ b/drivers/clk/tegra/tegra-car-clk.c @@ -10,6 +10,9 @@ #include <asm/arch/clock.h> #include <asm/arch-tegra/clk_rst.h>
+#define TEGRA_CAR_CLK_PLL BIT(0) +#define TEGRA_CAR_CLK_PERIPH BIT(1)
static int tegra_car_clk_request(struct clk *clk) { debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, @@ -20,30 +23,50 @@ static int tegra_car_clk_request(struct clk *clk) * varies per SoC) are the peripheral clocks, which use a numbering * scheme that matches HW registers 1:1. There are other clock IDs * beyond this that are assigned arbitrarily by the Tegra CAR DT
* binding. Due to the implementation of this driver, it currently
* only supports the peripheral IDs.
*/* binding.
- if (clk->id >= PERIPH_ID_COUNT)
return -EINVAL;
- if (!(clk->id >= PERIPH_ID_COUNT)) {
Maybe just do clk->id < PERIPH_ID_COUNT and get rid of the negation? Seems a bit more straightforward.
clk->data |= TEGRA_CAR_CLK_PERIPH;
return 0;
- }
- return 0;
- /* If check for periph failed, then check for PLL clock id */
- int id = clk_id_to_pll_id(clk->id);
- if (clock_id_is_pll(id)) {
clk->id = id;
clk->data |= TEGRA_CAR_CLK_PLL;
return 0;
- }
- return -EINVAL;
}
static ulong tegra_car_clk_get_rate(struct clk *clk) {
- enum clock_id parent;
- if (clk->data & TEGRA_CAR_CLK_PLL)
return clock_get_rate(clk->id);
- debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev,
clk->id);
- if (clk->data & TEGRA_CAR_CLK_PERIPH) {
enum clock_id parent;
- parent = clock_get_periph_parent(clk->id);
- return clock_get_periph_rate(clk->id, parent);
debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__,
clk, clk->dev, clk->id);
Is there any specific reason why you moved the debug() call into the branch? It looks like it was supposed to be a simple function tracing message, so it would probably be useful to have for PLL clocks as well.
parent = clock_get_periph_parent(clk->id);
return clock_get_periph_rate(clk->id, parent);
- }
- return -1U;
}
static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate) { enum clock_id parent;
- if (clk->data & TEGRA_CAR_CLK_PLL)
return 0;
- debug("%s(clk=%p, rate=%lu) (dev=%p, id=%lu)\n", __func__, clk, rate, clk->dev, clk->id);
Same here.
@@ -53,6 +76,9 @@ static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate)
static int tegra_car_clk_enable(struct clk *clk) {
- if (clk->data & TEGRA_CAR_CLK_PLL)
return 0;
- debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id);
And here.
@@ -63,6 +89,9 @@ static int tegra_car_clk_enable(struct clk *clk)
static int tegra_car_clk_disable(struct clk *clk) {
- if (clk->data & TEGRA_CAR_CLK_PLL)
return 0;
- debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id);
And here, too.
Thierry

пт, 13 груд. 2024 р. о 16:33 Thierry Reding thierry.reding@gmail.com пише:
On Thu, Dec 12, 2024 at 12:06:45PM +0200, Svyatoslav Ryhel wrote:
Return PLL id into struct clk if PLL is parsed from device tree instead of throwing an error. Allow requesting PLL clock rate via get_rate op.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com
drivers/clk/tegra/tegra-car-clk.c | 49 ++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/tegra/tegra-car-clk.c b/drivers/clk/tegra/tegra-car-clk.c index 1d61f8dc378..dd4d7791120 100644 --- a/drivers/clk/tegra/tegra-car-clk.c +++ b/drivers/clk/tegra/tegra-car-clk.c @@ -10,6 +10,9 @@ #include <asm/arch/clock.h> #include <asm/arch-tegra/clk_rst.h>
+#define TEGRA_CAR_CLK_PLL BIT(0) +#define TEGRA_CAR_CLK_PERIPH BIT(1)
static int tegra_car_clk_request(struct clk *clk) { debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, @@ -20,30 +23,50 @@ static int tegra_car_clk_request(struct clk *clk) * varies per SoC) are the peripheral clocks, which use a numbering * scheme that matches HW registers 1:1. There are other clock IDs * beyond this that are assigned arbitrarily by the Tegra CAR DT
* binding. Due to the implementation of this driver, it currently
* only supports the peripheral IDs.
* binding. */
if (clk->id >= PERIPH_ID_COUNT)
return -EINVAL;
if (!(clk->id >= PERIPH_ID_COUNT)) {
Maybe just do clk->id < PERIPH_ID_COUNT and get rid of the negation? Seems a bit more straightforward.
Agreed.
clk->data |= TEGRA_CAR_CLK_PERIPH;
return 0;
}
return 0;
/* If check for periph failed, then check for PLL clock id */
int id = clk_id_to_pll_id(clk->id);
if (clock_id_is_pll(id)) {
clk->id = id;
clk->data |= TEGRA_CAR_CLK_PLL;
return 0;
}
return -EINVAL;
}
static ulong tegra_car_clk_get_rate(struct clk *clk) {
enum clock_id parent;
if (clk->data & TEGRA_CAR_CLK_PLL)
return clock_get_rate(clk->id);
debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev,
clk->id);
if (clk->data & TEGRA_CAR_CLK_PERIPH) {
enum clock_id parent;
parent = clock_get_periph_parent(clk->id);
return clock_get_periph_rate(clk->id, parent);
debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__,
clk, clk->dev, clk->id);
Is there any specific reason why you moved the debug() call into the branch? It looks like it was supposed to be a simple function tracing message, so it would probably be useful to have for PLL clocks as well.
I will check if this debug can be applied to plls as well as it is. If yes, I will move it higher. Thanks
parent = clock_get_periph_parent(clk->id);
return clock_get_periph_rate(clk->id, parent);
}
return -1U;
}
static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate) { enum clock_id parent;
if (clk->data & TEGRA_CAR_CLK_PLL)
return 0;
debug("%s(clk=%p, rate=%lu) (dev=%p, id=%lu)\n", __func__, clk, rate, clk->dev, clk->id);
Same here.
@@ -53,6 +76,9 @@ static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate)
static int tegra_car_clk_enable(struct clk *clk) {
if (clk->data & TEGRA_CAR_CLK_PLL)
return 0;
debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id);
And here.
@@ -63,6 +89,9 @@ static int tegra_car_clk_enable(struct clk *clk)
static int tegra_car_clk_disable(struct clk *clk) {
if (clk->data & TEGRA_CAR_CLK_PLL)
return 0;
debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id);
And here, too.
Thierry

In case DM drivers probe earlier than board clock setup is done init of basic clocks should be done in CAR driver probe as well. Add it to avoid possible clock related problems.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com --- drivers/clk/tegra/tegra-car-clk.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/clk/tegra/tegra-car-clk.c b/drivers/clk/tegra/tegra-car-clk.c index dd4d7791120..a07c16c487a 100644 --- a/drivers/clk/tegra/tegra-car-clk.c +++ b/drivers/clk/tegra/tegra-car-clk.c @@ -112,6 +112,9 @@ static int tegra_car_clk_probe(struct udevice *dev) { debug("%s(dev=%p)\n", __func__, dev);
+ clock_init(); + clock_verify(); + return 0; }

On Thu, Dec 12, 2024 at 12:06:46PM +0200, Svyatoslav Ryhel wrote:
In case DM drivers probe earlier than board clock setup is done init of basic clocks should be done in CAR driver probe as well. Add it to avoid possible clock related problems.
Signed-off-by: Svyatoslav Ryhel clamor95@gmail.com
drivers/clk/tegra/tegra-car-clk.c | 3 +++ 1 file changed, 3 insertions(+)
Acked-by: Thierry Reding treding@nvidia.com

On Thu, Dec 12, 2024 at 12:06:44PM +0200, Svyatoslav Ryhel wrote:
This should fix https://lore.kernel.org/all/20241201164810.GT3600562@bill-the-cat/T/#m2b62b4...
Changes from v1
- added partially support PLL clocks commit
Svyatoslav Ryhel (2): driver: clk: tegra: partially support PLL clocks driver: clk: tegra: init basic clocks on probe
drivers/clk/tegra/tegra-car-clk.c | 52 +++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 10 deletions(-)
Thanks. Do you want to send me a PR for these, or should I apply them directly in a bit after time for further review / testing?

чт, 12 груд. 2024 р. о 17:55 Tom Rini trini@konsulko.com пише:
On Thu, Dec 12, 2024 at 12:06:44PM +0200, Svyatoslav Ryhel wrote:
This should fix https://lore.kernel.org/all/20241201164810.GT3600562@bill-the-cat/T/#m2b62b4...
Changes from v1
- added partially support PLL clocks commit
Svyatoslav Ryhel (2): driver: clk: tegra: partially support PLL clocks driver: clk: tegra: init basic clocks on probe
drivers/clk/tegra/tegra-car-clk.c | 52 +++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 10 deletions(-)
Thanks. Do you want to send me a PR for these, or should I apply them directly in a bit after time for further review / testing?
I have rushed previous patch since Simon responded that he is picking revert to some tree, which seems not to be official U-Boot repo.
I have send quite a bit of Tegra related patches today, and, if you are fine with that, I may pick them all after some a week or so to Tegra custodian repo and then ask for a PR. There is no urgency right now to apply clock patch tbh.
-- Tom
participants (3)
-
Svyatoslav Ryhel
-
Thierry Reding
-
Tom Rini