From: Svyatoslav Ryhel Date: Fri, 13 Dec 2024 14:53:18 +0000 (+0200) Subject: driver: clk: tegra: partially support PLL clocks X-Git-Url: http://git.dujemihanovic.xyz/img/static/%7B%7B%20%24.Site.BaseURL%20%7D%7Dposts/static/gitweb.css?a=commitdiff_plain;h=1db256a3473645ed12de980355f6089baf544bf4;p=u-boot.git driver: clk: tegra: partially support PLL clocks 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 --- diff --git a/drivers/clk/tegra/tegra-car-clk.c b/drivers/clk/tegra/tegra-car-clk.c index 1d61f8dc37..ec89d4b2b2 100644 --- a/drivers/clk/tegra/tegra-car-clk.c +++ b/drivers/clk/tegra/tegra-car-clk.c @@ -10,6 +10,9 @@ #include #include +#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,24 +23,41 @@ 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; - 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); + if (clk->data & TEGRA_CAR_CLK_PLL) + return clock_get_rate(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); + } + + return -1U; } static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate) @@ -47,6 +67,9 @@ static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate) debug("%s(clk=%p, rate=%lu) (dev=%p, id=%lu)\n", __func__, clk, rate, clk->dev, clk->id); + if (clk->data & TEGRA_CAR_CLK_PLL) + return 0; + parent = clock_get_periph_parent(clk->id); return clock_adjust_periph_pll_div(clk->id, parent, rate, NULL); } @@ -56,6 +79,9 @@ static int tegra_car_clk_enable(struct clk *clk) debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id); + if (clk->data & TEGRA_CAR_CLK_PLL) + return 0; + clock_enable(clk->id); return 0; @@ -66,6 +92,9 @@ static int tegra_car_clk_disable(struct clk *clk) debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, clk->id); + if (clk->data & TEGRA_CAR_CLK_PLL) + return 0; + clock_disable(clk->id); return 0;