Commit e51fbc55 authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-rockchip', 'clk-amlogic', 'clk-yaml', 'clk-zynq' and...

Merge branches 'clk-rockchip', 'clk-amlogic', 'clk-yaml', 'clk-zynq' and 'clk-socfpga' into clk-next

* clk-rockchip:
  clk: rockchip: export ACLK_VCODEC for RK3036
  clk: rockchip: fix rk3568 cpll clk gate bits
  clk: rockchip: Optimize PLL table memory usage

* clk-amlogic:
  clk: meson: g12a: Add missing NNA source clocks for g12b
  clk: meson: axg-audio: improve deferral handling
  clk: meson: g12a: fix gp0 and hifi ranges
  clk: meson: pll: switch to determine_rate for the PLL ops

* clk-yaml:
  dt-bindings: clock: gpio-mux-clock: Convert to json-schema

* clk-zynq:
  clk: zynqmp: Handle divider specific read only flag
  clk: zynqmp: Use firmware specific mux clock flags
  clk: zynqmp: Use firmware specific divider clock flags
  clk: zynqmp: Use firmware specific common clock flags
  clk: zynqmp: pll: Remove some dead code
  clk: zynqmp: fix compile testing without ZYNQMP_FIRMWARE

* clk-socfpga:
  clk: socfpga: clk-pll: Remove unused variable 'rc'
  clk: agilex/stratix10/n5x: fix how the bypass_reg is handled
  clk: agilex/stratix10: add support for the 2nd bypass
  clk: agilex/stratix10: fix bypass representation
  clk: agilex/stratix10: remove noc_clk
Binding for simple gpio clock multiplexer.
This binding uses the common clock binding[1].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be "gpio-mux-clock".
- clocks: list of two references to parent clocks.
- #clock-cells : from common clock binding; shall be set to 0.
- select-gpios : GPIO reference for selecting the parent clock.
Example:
clock {
compatible = "gpio-mux-clock";
clocks = <&parentclk1>, <&parentclk2>;
#clock-cells = <0>;
select-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/gpio-mux-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Simple GPIO clock multiplexer
maintainers:
- Sergej Sawazki <ce3a@gmx.de>
properties:
compatible:
const: gpio-mux-clock
clocks:
items:
- description: First parent clock
- description: Second parent clock
'#clock-cells':
const: 0
select-gpios:
description: GPIO reference for selecting the parent clock.
maxItems: 1
required:
- compatible
- clocks
- '#clock-cells'
- select-gpios
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
clock {
compatible = "gpio-mux-clock";
clocks = <&parentclk1>, <&parentclk2>;
#clock-cells = <0>;
select-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
};
...@@ -1665,8 +1665,7 @@ static int devm_clk_get_enable(struct device *dev, char *id) ...@@ -1665,8 +1665,7 @@ static int devm_clk_get_enable(struct device *dev, char *id)
clk = devm_clk_get(dev, id); clk = devm_clk_get(dev, id);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
if (ret != -EPROBE_DEFER) dev_err_probe(dev, ret, "failed to get %s", id);
dev_err(dev, "failed to get %s", id);
return ret; return ret;
} }
...@@ -1811,7 +1810,7 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) ...@@ -1811,7 +1810,7 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
ret = device_reset(dev); ret = device_reset(dev);
if (ret) { if (ret) {
dev_err(dev, "failed to reset device\n"); dev_err_probe(dev, ret, "failed to reset device\n");
return ret; return ret;
} }
......
...@@ -242,8 +242,8 @@ static int meson_clk_get_pll_settings(unsigned long rate, ...@@ -242,8 +242,8 @@ static int meson_clk_get_pll_settings(unsigned long rate,
return best ? 0 : -EINVAL; return best ? 0 : -EINVAL;
} }
static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, static int meson_clk_pll_determine_rate(struct clk_hw *hw,
unsigned long *parent_rate) struct clk_rate_request *req)
{ {
struct clk_regmap *clk = to_clk_regmap(hw); struct clk_regmap *clk = to_clk_regmap(hw);
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
...@@ -251,22 +251,26 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, ...@@ -251,22 +251,26 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long round; unsigned long round;
int ret; int ret;
ret = meson_clk_get_pll_settings(rate, *parent_rate, &m, &n, pll); ret = meson_clk_get_pll_settings(req->rate, req->best_parent_rate,
&m, &n, pll);
if (ret) if (ret)
return meson_clk_pll_recalc_rate(hw, *parent_rate); return ret;
round = __pll_params_to_rate(*parent_rate, m, n, 0, pll); round = __pll_params_to_rate(req->best_parent_rate, m, n, 0, pll);
if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round) if (!MESON_PARM_APPLICABLE(&pll->frac) || req->rate == round) {
return round; req->rate = round;
return 0;
}
/* /*
* The rate provided by the setting is not an exact match, let's * The rate provided by the setting is not an exact match, let's
* try to improve the result using the fractional parameter * try to improve the result using the fractional parameter
*/ */
frac = __pll_params_with_frac(rate, *parent_rate, m, n, pll); frac = __pll_params_with_frac(req->rate, req->best_parent_rate, m, n, pll);
req->rate = __pll_params_to_rate(req->best_parent_rate, m, n, frac, pll);
return __pll_params_to_rate(*parent_rate, m, n, frac, pll); return 0;
} }
static int meson_clk_pll_wait_lock(struct clk_hw *hw) static int meson_clk_pll_wait_lock(struct clk_hw *hw)
...@@ -419,7 +423,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -419,7 +423,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
*/ */
const struct clk_ops meson_clk_pcie_pll_ops = { const struct clk_ops meson_clk_pcie_pll_ops = {
.recalc_rate = meson_clk_pll_recalc_rate, .recalc_rate = meson_clk_pll_recalc_rate,
.round_rate = meson_clk_pll_round_rate, .determine_rate = meson_clk_pll_determine_rate,
.is_enabled = meson_clk_pll_is_enabled, .is_enabled = meson_clk_pll_is_enabled,
.enable = meson_clk_pcie_pll_enable, .enable = meson_clk_pcie_pll_enable,
.disable = meson_clk_pll_disable .disable = meson_clk_pll_disable
...@@ -429,7 +433,7 @@ EXPORT_SYMBOL_GPL(meson_clk_pcie_pll_ops); ...@@ -429,7 +433,7 @@ EXPORT_SYMBOL_GPL(meson_clk_pcie_pll_ops);
const struct clk_ops meson_clk_pll_ops = { const struct clk_ops meson_clk_pll_ops = {
.init = meson_clk_pll_init, .init = meson_clk_pll_init,
.recalc_rate = meson_clk_pll_recalc_rate, .recalc_rate = meson_clk_pll_recalc_rate,
.round_rate = meson_clk_pll_round_rate, .determine_rate = meson_clk_pll_determine_rate,
.set_rate = meson_clk_pll_set_rate, .set_rate = meson_clk_pll_set_rate,
.is_enabled = meson_clk_pll_is_enabled, .is_enabled = meson_clk_pll_is_enabled,
.enable = meson_clk_pll_enable, .enable = meson_clk_pll_enable,
......
...@@ -1603,7 +1603,7 @@ static struct clk_regmap g12b_cpub_clk_trace = { ...@@ -1603,7 +1603,7 @@ static struct clk_regmap g12b_cpub_clk_trace = {
}; };
static const struct pll_mult_range g12a_gp0_pll_mult_range = { static const struct pll_mult_range g12a_gp0_pll_mult_range = {
.min = 55, .min = 125,
.max = 255, .max = 255,
}; };
...@@ -4723,6 +4723,12 @@ static struct clk_hw_onecell_data g12b_hw_onecell_data = { ...@@ -4723,6 +4723,12 @@ static struct clk_hw_onecell_data g12b_hw_onecell_data = {
[CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw,
[CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw,
[CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw,
[CLKID_NNA_AXI_CLK_SEL] = &sm1_nna_axi_clk_sel.hw,
[CLKID_NNA_AXI_CLK_DIV] = &sm1_nna_axi_clk_div.hw,
[CLKID_NNA_AXI_CLK] = &sm1_nna_axi_clk.hw,
[CLKID_NNA_CORE_CLK_SEL] = &sm1_nna_core_clk_sel.hw,
[CLKID_NNA_CORE_CLK_DIV] = &sm1_nna_core_clk_div.hw,
[CLKID_NNA_CORE_CLK] = &sm1_nna_core_clk.hw,
[CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel.hw, [CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel.hw,
[CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div.hw, [CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div.hw,
[CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk.hw, [CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk.hw,
......
...@@ -259,7 +259,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { ...@@ -259,7 +259,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
RK2928_CLKGATE_CON(1), 13, GFLAGS, RK2928_CLKGATE_CON(1), 13, GFLAGS,
&rk3036_uart2_fracmux), &rk3036_uart2_fracmux),
COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0, COMPOSITE(ACLK_VCODEC, "aclk_vcodec", mux_pll_src_3plls_p, 0,
RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
RK2928_CLKGATE_CON(3), 11, GFLAGS), RK2928_CLKGATE_CON(3), 11, GFLAGS),
FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4, FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4,
......
...@@ -454,17 +454,17 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = { ...@@ -454,17 +454,17 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", CLK_IGNORE_UNUSED, COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(80), 0, 5, DFLAGS, RK3568_CLKSEL_CON(80), 0, 5, DFLAGS,
RK3568_CLKGATE_CON(35), 10, GFLAGS), RK3568_CLKGATE_CON(35), 10, GFLAGS),
COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(82), 0, 5, DFLAGS,
RK3568_CLKGATE_CON(35), 11, GFLAGS),
COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", CLK_IGNORE_UNUSED, COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(80), 8, 5, DFLAGS, RK3568_CLKSEL_CON(80), 8, 5, DFLAGS,
RK3568_CLKGATE_CON(35), 11, GFLAGS), RK3568_CLKGATE_CON(35), 12, GFLAGS),
COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", CLK_IGNORE_UNUSED, COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(81), 0, 5, DFLAGS, RK3568_CLKSEL_CON(81), 0, 5, DFLAGS,
RK3568_CLKGATE_CON(35), 12, GFLAGS), RK3568_CLKGATE_CON(35), 13, GFLAGS),
COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", CLK_IGNORE_UNUSED, COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(81), 8, 6, DFLAGS, RK3568_CLKSEL_CON(81), 8, 6, DFLAGS,
RK3568_CLKGATE_CON(35), 13, GFLAGS),
COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(82), 0, 5, DFLAGS,
RK3568_CLKGATE_CON(35), 14, GFLAGS), RK3568_CLKGATE_CON(35), 14, GFLAGS),
COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", CLK_IGNORE_UNUSED, COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(82), 8, 6, DFLAGS, RK3568_CLKSEL_CON(82), 8, 6, DFLAGS,
......
...@@ -271,17 +271,24 @@ struct rockchip_clk_provider { ...@@ -271,17 +271,24 @@ struct rockchip_clk_provider {
struct rockchip_pll_rate_table { struct rockchip_pll_rate_table {
unsigned long rate; unsigned long rate;
unsigned int nr; union {
unsigned int nf; struct {
unsigned int no; /* for RK3066 */
unsigned int nb; unsigned int nr;
/* for RK3036/RK3399 */ unsigned int nf;
unsigned int fbdiv; unsigned int no;
unsigned int postdiv1; unsigned int nb;
unsigned int refdiv; };
unsigned int postdiv2; struct {
unsigned int dsmpd; /* for RK3036/RK3399 */
unsigned int frac; unsigned int fbdiv;
unsigned int postdiv1;
unsigned int refdiv;
unsigned int postdiv2;
unsigned int dsmpd;
unsigned int frac;
};
};
}; };
/** /**
......
...@@ -177,6 +177,8 @@ static const struct clk_parent_data emac_mux[] = { ...@@ -177,6 +177,8 @@ static const struct clk_parent_data emac_mux[] = {
.name = "emaca_free_clk", }, .name = "emaca_free_clk", },
{ .fw_name = "emacb_free_clk", { .fw_name = "emacb_free_clk",
.name = "emacb_free_clk", }, .name = "emacb_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
}; };
static const struct clk_parent_data noc_mux[] = { static const struct clk_parent_data noc_mux[] = {
...@@ -186,6 +188,41 @@ static const struct clk_parent_data noc_mux[] = { ...@@ -186,6 +188,41 @@ static const struct clk_parent_data noc_mux[] = {
.name = "boot_clk", }, .name = "boot_clk", },
}; };
static const struct clk_parent_data sdmmc_mux[] = {
{ .fw_name = "sdmmc_free_clk",
.name = "sdmmc_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data s2f_user1_mux[] = {
{ .fw_name = "s2f_user1_free_clk",
.name = "s2f_user1_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data psi_mux[] = {
{ .fw_name = "psi_ref_free_clk",
.name = "psi_ref_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data gpio_db_mux[] = {
{ .fw_name = "gpio_db_free_clk",
.name = "gpio_db_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data emac_ptp_mux[] = {
{ .fw_name = "emac_ptp_free_clk",
.name = "emac_ptp_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
/* clocks in AO (always on) controller */ /* clocks in AO (always on) controller */
static const struct stratix10_pll_clock agilex_pll_clks[] = { static const struct stratix10_pll_clock agilex_pll_clks[] = {
{ AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
...@@ -222,11 +259,9 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { ...@@ -222,11 +259,9 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
{ AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
0, 0x3C, 0, 0, 0}, 0, 0x3C, 0, 0, 0},
{ AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
0, 0x40, 0, 0, 1}, 0, 0x40, 0, 0, 0},
{ AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
0, 4, 0, 0}, 0, 4, 0x30, 1},
{ AGILEX_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
0, 0, 0, 0x30, 1},
{ AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
0, 0xD4, 0, 0x88, 0}, 0, 0xD4, 0, 0x88, 0},
{ AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
...@@ -236,7 +271,7 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { ...@@ -236,7 +271,7 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
{ AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux, { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3}, ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3},
{ AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux, { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0x88, 4}, ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0},
{ AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux, { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0}, ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0},
{ AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux, { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
...@@ -252,24 +287,24 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { ...@@ -252,24 +287,24 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = {
0, 0, 0, 0, 0, 0, 4}, 0, 0, 0, 0, 0, 0, 4},
{ AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24, { AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24,
0, 0, 0, 0, 0, 0, 2}, 0, 0, 0, 0, 0, 0, 2},
{ AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24, { AGILEX_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
1, 0x44, 0, 2, 0, 0, 0}, 1, 0x44, 0, 2, 0x30, 1, 0},
{ AGILEX_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x24, { AGILEX_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
2, 0x44, 8, 2, 0, 0, 0}, 2, 0x44, 8, 2, 0x30, 1, 0},
/* /*
* The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them
* being the SP timers, thus cannot get gated. * being the SP timers, thus cannot get gated.
*/ */
{ AGILEX_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x24, { AGILEX_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x24,
3, 0x44, 16, 2, 0, 0, 0}, 3, 0x44, 16, 2, 0x30, 1, 0},
{ AGILEX_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x24, { AGILEX_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
4, 0x44, 24, 2, 0, 0, 0}, 4, 0x44, 24, 2, 0x30, 1, 0},
{ AGILEX_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x24, { AGILEX_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
4, 0x44, 26, 2, 0, 0, 0}, 4, 0x44, 26, 2, 0x30, 1, 0},
{ AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24, { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24,
4, 0x44, 28, 1, 0, 0, 0}, 4, 0x44, 28, 1, 0, 0, 0},
{ AGILEX_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x24, { AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
5, 0, 0, 0, 0, 0, 0}, 5, 0, 0, 0, 0x30, 1, 0},
{ AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24, { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24,
6, 0, 0, 0, 0, 0, 0}, 6, 0, 0, 0, 0, 0, 0},
{ AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
...@@ -278,16 +313,16 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { ...@@ -278,16 +313,16 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = {
1, 0, 0, 0, 0x94, 27, 0}, 1, 0, 0, 0, 0x94, 27, 0},
{ AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
2, 0, 0, 0, 0x94, 28, 0}, 2, 0, 0, 0, 0x94, 28, 0},
{ AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0x7C, { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0x7C,
3, 0, 0, 0, 0, 0, 0}, 3, 0, 0, 0, 0x88, 2, 0},
{ AGILEX_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0x7C, { AGILEX_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0x7C,
4, 0x98, 0, 16, 0, 0, 0}, 4, 0x98, 0, 16, 0x88, 3, 0},
{ AGILEX_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0x7C, { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C,
5, 0, 0, 0, 0, 0, 4}, 5, 0, 0, 0, 0x88, 4, 4},
{ AGILEX_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0x7C, { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C,
6, 0, 0, 0, 0, 0, 0}, 6, 0, 0, 0, 0x88, 5, 0},
{ AGILEX_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0x7C, { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C,
7, 0, 0, 0, 0, 0, 0}, 7, 0, 0, 0, 0x88, 6, 0},
{ AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
8, 0, 0, 0, 0, 0, 0}, 8, 0, 0, 0, 0, 0, 0},
{ AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
...@@ -366,7 +401,7 @@ static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks, ...@@ -366,7 +401,7 @@ static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks,
int i; int i;
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
hw_clk = s10_register_gate(&clks[i], base); hw_clk = agilex_register_gate(&clks[i], base);
if (IS_ERR(hw_clk)) { if (IS_ERR(hw_clk)) {
pr_err("%s: failed to register clock %s\n", pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name); __func__, clks[i].name);
......
...@@ -11,6 +11,13 @@ ...@@ -11,6 +11,13 @@
#define SOCFPGA_CS_PDBG_CLK "cs_pdbg_clk" #define SOCFPGA_CS_PDBG_CLK "cs_pdbg_clk"
#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) #define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
#define SOCFPGA_EMAC0_CLK "emac0_clk"
#define SOCFPGA_EMAC1_CLK "emac1_clk"
#define SOCFPGA_EMAC2_CLK "emac2_clk"
#define AGILEX_BYPASS_OFFSET 0xC
#define STRATIX10_BYPASS_OFFSET 0x2C
#define BOOTCLK_BYPASS 2
static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk, static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk,
unsigned long parent_rate) unsigned long parent_rate)
{ {
...@@ -44,14 +51,61 @@ static unsigned long socfpga_dbg_clk_recalc_rate(struct clk_hw *hwclk, ...@@ -44,14 +51,61 @@ static unsigned long socfpga_dbg_clk_recalc_rate(struct clk_hw *hwclk,
static u8 socfpga_gate_get_parent(struct clk_hw *hwclk) static u8 socfpga_gate_get_parent(struct clk_hw *hwclk)
{ {
struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
u32 mask; u32 mask, second_bypass;
u8 parent = 0;
const char *name = clk_hw_get_name(hwclk);
if (socfpgaclk->bypass_reg) {
mask = (0x1 << socfpgaclk->bypass_shift);
parent = ((readl(socfpgaclk->bypass_reg) & mask) >>
socfpgaclk->bypass_shift);
}
if (streq(name, SOCFPGA_EMAC0_CLK) ||
streq(name, SOCFPGA_EMAC1_CLK) ||
streq(name, SOCFPGA_EMAC2_CLK)) {
second_bypass = readl(socfpgaclk->bypass_reg -
STRATIX10_BYPASS_OFFSET);
/* EMACA bypass to bootclk @0xB0 offset */
if (second_bypass & 0x1)
if (parent == 0) /* only applicable if parent is maca */
parent = BOOTCLK_BYPASS;
if (second_bypass & 0x2)
if (parent == 1) /* only applicable if parent is macb */
parent = BOOTCLK_BYPASS;
}
return parent;
}
static u8 socfpga_agilex_gate_get_parent(struct clk_hw *hwclk)
{
struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
u32 mask, second_bypass;
u8 parent = 0; u8 parent = 0;
const char *name = clk_hw_get_name(hwclk);
if (socfpgaclk->bypass_reg) { if (socfpgaclk->bypass_reg) {
mask = (0x1 << socfpgaclk->bypass_shift); mask = (0x1 << socfpgaclk->bypass_shift);
parent = ((readl(socfpgaclk->bypass_reg) & mask) >> parent = ((readl(socfpgaclk->bypass_reg) & mask) >>
socfpgaclk->bypass_shift); socfpgaclk->bypass_shift);
} }
if (streq(name, SOCFPGA_EMAC0_CLK) ||
streq(name, SOCFPGA_EMAC1_CLK) ||
streq(name, SOCFPGA_EMAC2_CLK)) {
second_bypass = readl(socfpgaclk->bypass_reg -
AGILEX_BYPASS_OFFSET);
/* EMACA bypass to bootclk @0x88 offset */
if (second_bypass & 0x1)
if (parent == 0) /* only applicable if parent is maca */
parent = BOOTCLK_BYPASS;
if (second_bypass & 0x2)
if (parent == 1) /* only applicable if parent is macb */
parent = BOOTCLK_BYPASS;
}
return parent; return parent;
} }
...@@ -60,6 +114,11 @@ static struct clk_ops gateclk_ops = { ...@@ -60,6 +114,11 @@ static struct clk_ops gateclk_ops = {
.get_parent = socfpga_gate_get_parent, .get_parent = socfpga_gate_get_parent,
}; };
static const struct clk_ops agilex_gateclk_ops = {
.recalc_rate = socfpga_gate_clk_recalc_rate,
.get_parent = socfpga_agilex_gate_get_parent,
};
static const struct clk_ops dbgclk_ops = { static const struct clk_ops dbgclk_ops = {
.recalc_rate = socfpga_dbg_clk_recalc_rate, .recalc_rate = socfpga_dbg_clk_recalc_rate,
.get_parent = socfpga_gate_get_parent, .get_parent = socfpga_gate_get_parent,
...@@ -122,3 +181,61 @@ struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, void _ ...@@ -122,3 +181,61 @@ struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, void _
} }
return hw_clk; return hw_clk;
} }
struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase)
{
struct clk_hw *hw_clk;
struct socfpga_gate_clk *socfpga_clk;
struct clk_init_data init;
const char *parent_name = clks->parent_name;
int ret;
socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
if (!socfpga_clk)
return NULL;
socfpga_clk->hw.reg = regbase + clks->gate_reg;
socfpga_clk->hw.bit_idx = clks->gate_idx;
gateclk_ops.enable = clk_gate_ops.enable;
gateclk_ops.disable = clk_gate_ops.disable;
socfpga_clk->fixed_div = clks->fixed_div;
if (clks->div_reg)
socfpga_clk->div_reg = regbase + clks->div_reg;
else
socfpga_clk->div_reg = NULL;
socfpga_clk->width = clks->div_width;
socfpga_clk->shift = clks->div_offset;
if (clks->bypass_reg)
socfpga_clk->bypass_reg = regbase + clks->bypass_reg;
else
socfpga_clk->bypass_reg = NULL;
socfpga_clk->bypass_shift = clks->bypass_shift;
if (streq(clks->name, "cs_pdbg_clk"))
init.ops = &dbgclk_ops;
else
init.ops = &agilex_gateclk_ops;
init.name = clks->name;
init.flags = clks->flags;
init.num_parents = clks->num_parents;
init.parent_names = parent_name ? &parent_name : NULL;
if (init.parent_names == NULL)
init.parent_data = clks->parent_data;
socfpga_clk->hw.hw.init = &init;
hw_clk = &socfpga_clk->hw.hw;
ret = clk_hw_register(NULL, &socfpga_clk->hw.hw);
if (ret) {
kfree(socfpga_clk);
return ERR_PTR(ret);
}
return hw_clk;
}
...@@ -64,16 +64,21 @@ static u8 clk_periclk_get_parent(struct clk_hw *hwclk) ...@@ -64,16 +64,21 @@ static u8 clk_periclk_get_parent(struct clk_hw *hwclk)
{ {
struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk); struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk);
u32 clk_src, mask; u32 clk_src, mask;
u8 parent; u8 parent = 0;
/* handle the bypass first */
if (socfpgaclk->bypass_reg) { if (socfpgaclk->bypass_reg) {
mask = (0x1 << socfpgaclk->bypass_shift); mask = (0x1 << socfpgaclk->bypass_shift);
parent = ((readl(socfpgaclk->bypass_reg) & mask) >> parent = ((readl(socfpgaclk->bypass_reg) & mask) >>
socfpgaclk->bypass_shift); socfpgaclk->bypass_shift);
} else { if (parent)
return parent;
}
if (socfpgaclk->hw.reg) {
clk_src = readl(socfpgaclk->hw.reg); clk_src = readl(socfpgaclk->hw.reg);
parent = (clk_src >> CLK_MGR_FREE_SHIFT) & parent = (clk_src >> CLK_MGR_FREE_SHIFT) &
CLK_MGR_FREE_MASK; CLK_MGR_FREE_MASK;
} }
return parent; return parent;
} }
......
...@@ -80,7 +80,6 @@ static __init struct clk_hw *__socfpga_pll_init(struct device_node *node, ...@@ -80,7 +80,6 @@ static __init struct clk_hw *__socfpga_pll_init(struct device_node *node,
const char *parent_name[SOCFPGA_MAX_PARENTS]; const char *parent_name[SOCFPGA_MAX_PARENTS];
struct clk_init_data init; struct clk_init_data init;
struct device_node *clkmgr_np; struct device_node *clkmgr_np;
int rc;
int err; int err;
of_property_read_u32(node, "reg", &reg); of_property_read_u32(node, "reg", &reg);
...@@ -114,7 +113,7 @@ static __init struct clk_hw *__socfpga_pll_init(struct device_node *node, ...@@ -114,7 +113,7 @@ static __init struct clk_hw *__socfpga_pll_init(struct device_node *node,
kfree(pll_clk); kfree(pll_clk);
return ERR_PTR(err); return ERR_PTR(err);
} }
rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk); of_clk_add_provider(node, of_clk_src_simple_get, hw_clk);
return hw_clk; return hw_clk;
} }
......
...@@ -144,6 +144,41 @@ static const struct clk_parent_data mpu_free_mux[] = { ...@@ -144,6 +144,41 @@ static const struct clk_parent_data mpu_free_mux[] = {
.name = "f2s-free-clk", }, .name = "f2s-free-clk", },
}; };
static const struct clk_parent_data sdmmc_mux[] = {
{ .fw_name = "sdmmc_free_clk",
.name = "sdmmc_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data s2f_user1_mux[] = {
{ .fw_name = "s2f_user1_free_clk",
.name = "s2f_user1_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data psi_mux[] = {
{ .fw_name = "psi_ref_free_clk",
.name = "psi_ref_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data gpio_db_mux[] = {
{ .fw_name = "gpio_db_free_clk",
.name = "gpio_db_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
static const struct clk_parent_data emac_ptp_mux[] = {
{ .fw_name = "emac_ptp_free_clk",
.name = "emac_ptp_free_clk", },
{ .fw_name = "boot_clk",
.name = "boot_clk", },
};
/* clocks in AO (always on) controller */ /* clocks in AO (always on) controller */
static const struct stratix10_pll_clock s10_pll_clks[] = { static const struct stratix10_pll_clock s10_pll_clks[] = {
{ STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, { STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
...@@ -167,7 +202,7 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { ...@@ -167,7 +202,7 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = {
{ STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
0, 0x48, 0, 0, 0}, 0, 0x48, 0, 0, 0},
{ STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
0, 0x4C, 0, 0, 0}, 0, 0x4C, 0, 0x3C, 1},
{ STRATIX10_MAIN_EMACA_CLK, "main_emaca_clk", "main_noc_base_clk", NULL, 1, 0, { STRATIX10_MAIN_EMACA_CLK, "main_emaca_clk", "main_noc_base_clk", NULL, 1, 0,
0x50, 0, 0, 0}, 0x50, 0, 0, 0},
{ STRATIX10_MAIN_EMACB_CLK, "main_emacb_clk", "main_noc_base_clk", NULL, 1, 0, { STRATIX10_MAIN_EMACB_CLK, "main_emacb_clk", "main_noc_base_clk", NULL, 1, 0,
...@@ -200,10 +235,8 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { ...@@ -200,10 +235,8 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = {
0, 0xD4, 0, 0, 0}, 0, 0xD4, 0, 0, 0},
{ STRATIX10_PERI_PSI_REF_CLK, "peri_psi_ref_clk", "peri_noc_base_clk", NULL, 1, 0, { STRATIX10_PERI_PSI_REF_CLK, "peri_psi_ref_clk", "peri_noc_base_clk", NULL, 1, 0,
0xD8, 0, 0, 0}, 0xD8, 0, 0, 0},
{ STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
0, 4, 0, 0}, 0, 4, 0x3C, 1},
{ STRATIX10_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
0, 0, 0, 0x3C, 1},
{ STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), { STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
0, 0, 2, 0xB0, 0}, 0, 0, 2, 0xB0, 0},
{ STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), { STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
...@@ -227,20 +260,20 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { ...@@ -227,20 +260,20 @@ static const struct stratix10_gate_clock s10_gate_clks[] = {
0, 0, 0, 0, 0, 0, 4}, 0, 0, 0, 0, 0, 0, 4},
{ STRATIX10_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x30, { STRATIX10_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x30,
0, 0, 0, 0, 0, 0, 2}, 0, 0, 0, 0, 0, 0, 2},
{ STRATIX10_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x30, { STRATIX10_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
1, 0x70, 0, 2, 0, 0, 0}, 1, 0x70, 0, 2, 0x3C, 1, 0},
{ STRATIX10_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x30, { STRATIX10_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
2, 0x70, 8, 2, 0, 0, 0}, 2, 0x70, 8, 2, 0x3C, 1, 0},
{ STRATIX10_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x30, { STRATIX10_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x30,
3, 0x70, 16, 2, 0, 0, 0}, 3, 0x70, 16, 2, 0x3C, 1, 0},
{ STRATIX10_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x30, { STRATIX10_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
4, 0x70, 24, 2, 0, 0, 0}, 4, 0x70, 24, 2, 0x3C, 1, 0},
{ STRATIX10_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x30, { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
4, 0x70, 26, 2, 0, 0, 0}, 4, 0x70, 26, 2, 0x3C, 1, 0},
{ STRATIX10_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x30, { STRATIX10_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x30,
4, 0x70, 28, 1, 0, 0, 0}, 4, 0x70, 28, 1, 0, 0, 0},
{ STRATIX10_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x30, { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
5, 0, 0, 0, 0, 0, 0}, 5, 0, 0, 0, 0x3C, 1, 0},
{ STRATIX10_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x30, { STRATIX10_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x30,
6, 0, 0, 0, 0, 0, 0}, 6, 0, 0, 0, 0, 0, 0},
{ STRATIX10_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, { STRATIX10_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
...@@ -249,16 +282,16 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { ...@@ -249,16 +282,16 @@ static const struct stratix10_gate_clock s10_gate_clks[] = {
1, 0, 0, 0, 0xDC, 27, 0}, 1, 0, 0, 0, 0xDC, 27, 0},
{ STRATIX10_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, { STRATIX10_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
2, 0, 0, 0, 0xDC, 28, 0}, 2, 0, 0, 0, 0xDC, 28, 0},
{ STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0xA4, { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0xA4,
3, 0, 0, 0, 0, 0, 0}, 3, 0, 0, 0, 0xB0, 2, 0},
{ STRATIX10_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0xA4, { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0xA4,
4, 0xE0, 0, 16, 0, 0, 0}, 4, 0xE0, 0, 16, 0xB0, 3, 0},
{ STRATIX10_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0xA4, { STRATIX10_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0xA4,
5, 0, 0, 0, 0, 0, 4}, 5, 0, 0, 0, 0xB0, 4, 4},
{ STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0xA4, { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0xA4,
6, 0, 0, 0, 0, 0, 0}, 6, 0, 0, 0, 0xB0, 5, 0},
{ STRATIX10_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0xA4, { STRATIX10_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0xA4,
7, 0, 0, 0, 0, 0, 0}, 7, 0, 0, 0, 0xB0, 6, 0},
{ STRATIX10_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, { STRATIX10_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0xA4,
8, 0, 0, 0, 0, 0, 0}, 8, 0, 0, 0, 0, 0, 0},
{ STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, { STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4,
......
...@@ -85,4 +85,6 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c ...@@ -85,4 +85,6 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c
void __iomem *reg); void __iomem *reg);
struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks,
void __iomem *reg); void __iomem *reg);
struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks,
void __iomem *reg);
#endif /* __STRATIX10_CLK_H */ #endif /* __STRATIX10_CLK_H */
...@@ -121,7 +121,9 @@ struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id, ...@@ -121,7 +121,9 @@ struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
init.name = name; init.name = name;
init.ops = &zynqmp_clk_gate_ops; init.ops = &zynqmp_clk_gate_ops;
init.flags = nodes->flag;
init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);
init.parent_names = parents; init.parent_names = parents;
init.num_parents = 1; init.num_parents = 1;
......
...@@ -38,7 +38,7 @@ struct zynqmp_clk_mux { ...@@ -38,7 +38,7 @@ struct zynqmp_clk_mux {
* zynqmp_clk_mux_get_parent() - Get parent of clock * zynqmp_clk_mux_get_parent() - Get parent of clock
* @hw: handle between common and hardware-specific interfaces * @hw: handle between common and hardware-specific interfaces
* *
* Return: Parent index * Return: Parent index on success or number of parents in case of error
*/ */
static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
{ {
...@@ -50,9 +50,15 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) ...@@ -50,9 +50,15 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
ret = zynqmp_pm_clock_getparent(clk_id, &val); ret = zynqmp_pm_clock_getparent(clk_id, &val);
if (ret) if (ret) {
pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n", pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
__func__, clk_name, ret); __func__, clk_name, ret);
/*
* clk_core_get_parent_by_index() takes num_parents as incorrect
* index which is exactly what I want to return here
*/
return clk_hw_get_num_parents(hw);
}
return val; return val;
} }
...@@ -90,6 +96,27 @@ static const struct clk_ops zynqmp_clk_mux_ro_ops = { ...@@ -90,6 +96,27 @@ static const struct clk_ops zynqmp_clk_mux_ro_ops = {
.get_parent = zynqmp_clk_mux_get_parent, .get_parent = zynqmp_clk_mux_get_parent,
}; };
static inline unsigned long zynqmp_clk_map_mux_ccf_flags(
const u32 zynqmp_type_flag)
{
unsigned long ccf_flag = 0;
if (zynqmp_type_flag & ZYNQMP_CLK_MUX_INDEX_ONE)
ccf_flag |= CLK_MUX_INDEX_ONE;
if (zynqmp_type_flag & ZYNQMP_CLK_MUX_INDEX_BIT)
ccf_flag |= CLK_MUX_INDEX_BIT;
if (zynqmp_type_flag & ZYNQMP_CLK_MUX_HIWORD_MASK)
ccf_flag |= CLK_MUX_HIWORD_MASK;
if (zynqmp_type_flag & ZYNQMP_CLK_MUX_READ_ONLY)
ccf_flag |= CLK_MUX_READ_ONLY;
if (zynqmp_type_flag & ZYNQMP_CLK_MUX_ROUND_CLOSEST)
ccf_flag |= CLK_MUX_ROUND_CLOSEST;
if (zynqmp_type_flag & ZYNQMP_CLK_MUX_BIG_ENDIAN)
ccf_flag |= CLK_MUX_BIG_ENDIAN;
return ccf_flag;
}
/** /**
* zynqmp_clk_register_mux() - Register a mux table with the clock * zynqmp_clk_register_mux() - Register a mux table with the clock
* framework * framework
...@@ -120,10 +147,12 @@ struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id, ...@@ -120,10 +147,12 @@ struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id,
init.ops = &zynqmp_clk_mux_ro_ops; init.ops = &zynqmp_clk_mux_ro_ops;
else else
init.ops = &zynqmp_clk_mux_ops; init.ops = &zynqmp_clk_mux_ops;
init.flags = nodes->flag;
init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);
init.parent_names = parents; init.parent_names = parents;
init.num_parents = num_parents; init.num_parents = num_parents;
mux->flags = nodes->type_flag; mux->flags = zynqmp_clk_map_mux_ccf_flags(nodes->type_flag);
mux->hw.init = &init; mux->hw.init = &init;
mux->clk_id = clk_id; mux->clk_id = clk_id;
......
...@@ -10,6 +10,37 @@ ...@@ -10,6 +10,37 @@
#include <linux/firmware/xlnx-zynqmp.h> #include <linux/firmware/xlnx-zynqmp.h>
/* Common Flags */
/* must be gated across rate change */
#define ZYNQMP_CLK_SET_RATE_GATE BIT(0)
/* must be gated across re-parent */
#define ZYNQMP_CLK_SET_PARENT_GATE BIT(1)
/* propagate rate change up one level */
#define ZYNQMP_CLK_SET_RATE_PARENT BIT(2)
/* do not gate even if unused */
#define ZYNQMP_CLK_IGNORE_UNUSED BIT(3)
/* don't re-parent on rate change */
#define ZYNQMP_CLK_SET_RATE_NO_REPARENT BIT(7)
/* do not gate, ever */
#define ZYNQMP_CLK_IS_CRITICAL BIT(11)
/* Type Flags for divider clock */
#define ZYNQMP_CLK_DIVIDER_ONE_BASED BIT(0)
#define ZYNQMP_CLK_DIVIDER_POWER_OF_TWO BIT(1)
#define ZYNQMP_CLK_DIVIDER_ALLOW_ZERO BIT(2)
#define ZYNQMP_CLK_DIVIDER_HIWORD_MASK BIT(3)
#define ZYNQMP_CLK_DIVIDER_ROUND_CLOSEST BIT(4)
#define ZYNQMP_CLK_DIVIDER_READ_ONLY BIT(5)
#define ZYNQMP_CLK_DIVIDER_MAX_AT_ZERO BIT(6)
/* Type Flags for mux clock */
#define ZYNQMP_CLK_MUX_INDEX_ONE BIT(0)
#define ZYNQMP_CLK_MUX_INDEX_BIT BIT(1)
#define ZYNQMP_CLK_MUX_HIWORD_MASK BIT(2)
#define ZYNQMP_CLK_MUX_READ_ONLY BIT(3)
#define ZYNQMP_CLK_MUX_ROUND_CLOSEST BIT(4)
#define ZYNQMP_CLK_MUX_BIG_ENDIAN BIT(5)
enum topology_type { enum topology_type {
TYPE_INVALID, TYPE_INVALID,
TYPE_MUX, TYPE_MUX,
...@@ -33,6 +64,8 @@ struct clock_topology { ...@@ -33,6 +64,8 @@ struct clock_topology {
u8 custom_type_flag; u8 custom_type_flag;
}; };
unsigned long zynqmp_clk_map_common_ccf_flags(const u32 zynqmp_flag);
struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
const char * const *parents, const char * const *parents,
u8 num_parents, u8 num_parents,
......
...@@ -271,6 +271,26 @@ static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, ...@@ -271,6 +271,26 @@ static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index,
return ret; return ret;
} }
unsigned long zynqmp_clk_map_common_ccf_flags(const u32 zynqmp_flag)
{
unsigned long ccf_flag = 0;
if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_GATE)
ccf_flag |= CLK_SET_RATE_GATE;
if (zynqmp_flag & ZYNQMP_CLK_SET_PARENT_GATE)
ccf_flag |= CLK_SET_PARENT_GATE;
if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_PARENT)
ccf_flag |= CLK_SET_RATE_PARENT;
if (zynqmp_flag & ZYNQMP_CLK_IGNORE_UNUSED)
ccf_flag |= CLK_IGNORE_UNUSED;
if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_NO_REPARENT)
ccf_flag |= CLK_SET_RATE_NO_REPARENT;
if (zynqmp_flag & ZYNQMP_CLK_IS_CRITICAL)
ccf_flag |= CLK_IS_CRITICAL;
return ccf_flag;
}
/** /**
* zynqmp_clk_register_fixed_factor() - Register fixed factor with the * zynqmp_clk_register_fixed_factor() - Register fixed factor with the
* clock framework * clock framework
...@@ -292,6 +312,7 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id, ...@@ -292,6 +312,7 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
struct zynqmp_pm_query_data qdata = {0}; struct zynqmp_pm_query_data qdata = {0};
u32 ret_payload[PAYLOAD_ARG_CNT]; u32 ret_payload[PAYLOAD_ARG_CNT];
int ret; int ret;
unsigned long flag;
qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS; qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS;
qdata.arg1 = clk_id; qdata.arg1 = clk_id;
...@@ -303,9 +324,11 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id, ...@@ -303,9 +324,11 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
mult = ret_payload[1]; mult = ret_payload[1];
div = ret_payload[2]; div = ret_payload[2];
flag = zynqmp_clk_map_common_ccf_flags(nodes->flag);
hw = clk_hw_register_fixed_factor(NULL, name, hw = clk_hw_register_fixed_factor(NULL, name,
parents[0], parents[0],
nodes->flag, mult, flag, mult,
div); div);
return hw; return hw;
......
...@@ -256,6 +256,11 @@ static const struct clk_ops zynqmp_clk_divider_ops = { ...@@ -256,6 +256,11 @@ static const struct clk_ops zynqmp_clk_divider_ops = {
.set_rate = zynqmp_clk_divider_set_rate, .set_rate = zynqmp_clk_divider_set_rate,
}; };
static const struct clk_ops zynqmp_clk_divider_ro_ops = {
.recalc_rate = zynqmp_clk_divider_recalc_rate,
.round_rate = zynqmp_clk_divider_round_rate,
};
/** /**
* zynqmp_clk_get_max_divisor() - Get maximum supported divisor from firmware. * zynqmp_clk_get_max_divisor() - Get maximum supported divisor from firmware.
* @clk_id: Id of clock * @clk_id: Id of clock
...@@ -284,6 +289,29 @@ static u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type) ...@@ -284,6 +289,29 @@ static u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type)
return ret_payload[1]; return ret_payload[1];
} }
static inline unsigned long zynqmp_clk_map_divider_ccf_flags(
const u32 zynqmp_type_flag)
{
unsigned long ccf_flag = 0;
if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_ONE_BASED)
ccf_flag |= CLK_DIVIDER_ONE_BASED;
if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_POWER_OF_TWO)
ccf_flag |= CLK_DIVIDER_POWER_OF_TWO;
if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_ALLOW_ZERO)
ccf_flag |= CLK_DIVIDER_ALLOW_ZERO;
if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_POWER_OF_TWO)
ccf_flag |= CLK_DIVIDER_HIWORD_MASK;
if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_ROUND_CLOSEST)
ccf_flag |= CLK_DIVIDER_ROUND_CLOSEST;
if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_READ_ONLY)
ccf_flag |= CLK_DIVIDER_READ_ONLY;
if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_MAX_AT_ZERO)
ccf_flag |= CLK_DIVIDER_MAX_AT_ZERO;
return ccf_flag;
}
/** /**
* zynqmp_clk_register_divider() - Register a divider clock * zynqmp_clk_register_divider() - Register a divider clock
* @name: Name of this clock * @name: Name of this clock
...@@ -311,16 +339,20 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name, ...@@ -311,16 +339,20 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
init.name = name; init.name = name;
init.ops = &zynqmp_clk_divider_ops; if (nodes->type_flag & CLK_DIVIDER_READ_ONLY)
/* CLK_FRAC is not defined in the common clk framework */ init.ops = &zynqmp_clk_divider_ro_ops;
init.flags = nodes->flag & ~CLK_FRAC; else
init.ops = &zynqmp_clk_divider_ops;
init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);
init.parent_names = parents; init.parent_names = parents;
init.num_parents = 1; init.num_parents = 1;
/* struct clk_divider assignments */ /* struct clk_divider assignments */
div->is_frac = !!((nodes->flag & CLK_FRAC) | div->is_frac = !!((nodes->flag & CLK_FRAC) |
(nodes->custom_type_flag & CUSTOM_FLAG_CLK_FRAC)); (nodes->custom_type_flag & CUSTOM_FLAG_CLK_FRAC));
div->flags = nodes->type_flag; div->flags = zynqmp_clk_map_divider_ccf_flags(nodes->type_flag);
div->hw.init = &init; div->hw.init = &init;
div->clk_id = clk_id; div->clk_id = clk_id;
div->div_type = nodes->type; div->div_type = nodes->type;
......
...@@ -31,8 +31,9 @@ struct zynqmp_pll { ...@@ -31,8 +31,9 @@ struct zynqmp_pll {
#define PS_PLL_VCO_MAX 3000000000UL #define PS_PLL_VCO_MAX 3000000000UL
enum pll_mode { enum pll_mode {
PLL_MODE_INT, PLL_MODE_INT = 0,
PLL_MODE_FRAC, PLL_MODE_FRAC = 1,
PLL_MODE_ERROR = 2,
}; };
#define FRAC_OFFSET 0x8 #define FRAC_OFFSET 0x8
...@@ -54,9 +55,11 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw) ...@@ -54,9 +55,11 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
int ret; int ret;
ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload); ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
if (ret) if (ret) {
pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n", pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
__func__, clk_name, ret); __func__, clk_name, ret);
return PLL_MODE_ERROR;
}
return ret_payload[1]; return ret_payload[1];
} }
...@@ -126,7 +129,7 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, ...@@ -126,7 +129,7 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
* @hw: Handle between common and hardware-specific interfaces * @hw: Handle between common and hardware-specific interfaces
* @parent_rate: Clock frequency of parent clock * @parent_rate: Clock frequency of parent clock
* *
* Return: Current clock frequency * Return: Current clock frequency or 0 in case of error
*/ */
static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate) unsigned long parent_rate)
...@@ -138,14 +141,21 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, ...@@ -138,14 +141,21 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
unsigned long rate, frac; unsigned long rate, frac;
u32 ret_payload[PAYLOAD_ARG_CNT]; u32 ret_payload[PAYLOAD_ARG_CNT];
int ret; int ret;
enum pll_mode mode;
ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv); ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
if (ret) if (ret) {
pr_warn_once("%s() get divider failed for %s, ret = %d\n", pr_warn_once("%s() get divider failed for %s, ret = %d\n",
__func__, clk_name, ret); __func__, clk_name, ret);
return 0ul;
}
mode = zynqmp_pll_get_mode(hw);
if (mode == PLL_MODE_ERROR)
return 0ul;
rate = parent_rate * fbdiv; rate = parent_rate * fbdiv;
if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { if (mode == PLL_MODE_FRAC) {
zynqmp_pm_get_pll_frac_data(clk_id, ret_payload); zynqmp_pm_get_pll_frac_data(clk_id, ret_payload);
data = ret_payload[1]; data = ret_payload[1];
frac = (parent_rate * data) / FRAC_DIV; frac = (parent_rate * data) / FRAC_DIV;
...@@ -312,7 +322,9 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, ...@@ -312,7 +322,9 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
init.name = name; init.name = name;
init.ops = &zynqmp_pll_ops; init.ops = &zynqmp_pll_ops;
init.flags = nodes->flag;
init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);
init.parent_names = parents; init.parent_names = parents;
init.num_parents = 1; init.num_parents = 1;
...@@ -331,8 +343,6 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, ...@@ -331,8 +343,6 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
} }
clk_hw_set_rate_range(hw, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX); clk_hw_set_rate_range(hw, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX);
if (ret < 0)
pr_err("%s:ERROR clk_set_rate_range failed %d\n", name, ret);
return hw; return hw;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment