|
@@ -9,6 +9,9 @@
|
|
|
#include <dm.h>
|
|
|
#include <asm/arch/clock_manager.h>
|
|
|
|
|
|
+static const struct socfpga_clock_manager *clock_manager_base =
|
|
|
+ (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
|
|
|
+
|
|
|
static u32 eosc1_hz;
|
|
|
static u32 cb_intosc_hz;
|
|
|
static u32 f2s_free_hz;
|
|
@@ -64,89 +67,150 @@ struct perpll_cfg {
|
|
|
u32 cntr8clk_cnt;
|
|
|
u32 cntr8clk_src;
|
|
|
u32 cntr9clk_cnt;
|
|
|
+ u32 cntr9clk_src;
|
|
|
u32 emacctl_emac0sel;
|
|
|
u32 emacctl_emac1sel;
|
|
|
u32 emacctl_emac2sel;
|
|
|
u32 gpiodiv_gpiodbclk;
|
|
|
};
|
|
|
|
|
|
-struct alteragrp_cfg {
|
|
|
- u32 nocclk;
|
|
|
- u32 mpuclk;
|
|
|
+struct strtou32 {
|
|
|
+ const char *str;
|
|
|
+ const u32 val;
|
|
|
};
|
|
|
|
|
|
-static const struct socfpga_clock_manager *clock_manager_base =
|
|
|
- (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
|
|
|
+static const struct strtou32 mainpll_cfg_tab[] = {
|
|
|
+ { "vco0-psrc", offsetof(struct mainpll_cfg, vco0_psrc) },
|
|
|
+ { "vco1-denom", offsetof(struct mainpll_cfg, vco1_denom) },
|
|
|
+ { "vco1-numer", offsetof(struct mainpll_cfg, vco1_numer) },
|
|
|
+ { "mpuclk-cnt", offsetof(struct mainpll_cfg, mpuclk_cnt) },
|
|
|
+ { "mpuclk-src", offsetof(struct mainpll_cfg, mpuclk_src) },
|
|
|
+ { "nocclk-cnt", offsetof(struct mainpll_cfg, nocclk_cnt) },
|
|
|
+ { "nocclk-src", offsetof(struct mainpll_cfg, nocclk_src) },
|
|
|
+ { "cntr2clk-cnt", offsetof(struct mainpll_cfg, cntr2clk_cnt) },
|
|
|
+ { "cntr3clk-cnt", offsetof(struct mainpll_cfg, cntr3clk_cnt) },
|
|
|
+ { "cntr4clk-cnt", offsetof(struct mainpll_cfg, cntr4clk_cnt) },
|
|
|
+ { "cntr5clk-cnt", offsetof(struct mainpll_cfg, cntr5clk_cnt) },
|
|
|
+ { "cntr6clk-cnt", offsetof(struct mainpll_cfg, cntr6clk_cnt) },
|
|
|
+ { "cntr7clk-cnt", offsetof(struct mainpll_cfg, cntr7clk_cnt) },
|
|
|
+ { "cntr7clk-src", offsetof(struct mainpll_cfg, cntr7clk_src) },
|
|
|
+ { "cntr8clk-cnt", offsetof(struct mainpll_cfg, cntr8clk_cnt) },
|
|
|
+ { "cntr9clk-cnt", offsetof(struct mainpll_cfg, cntr9clk_cnt) },
|
|
|
+ { "cntr9clk-src", offsetof(struct mainpll_cfg, cntr9clk_src) },
|
|
|
+ { "cntr15clk-cnt", offsetof(struct mainpll_cfg, cntr15clk_cnt) },
|
|
|
+ { "nocdiv-l4mainclk", offsetof(struct mainpll_cfg, nocdiv_l4mainclk) },
|
|
|
+ { "nocdiv-l4mpclk", offsetof(struct mainpll_cfg, nocdiv_l4mpclk) },
|
|
|
+ { "nocdiv-l4spclk", offsetof(struct mainpll_cfg, nocdiv_l4spclk) },
|
|
|
+ { "nocdiv-csatclk", offsetof(struct mainpll_cfg, nocdiv_csatclk) },
|
|
|
+ { "nocdiv-cstraceclk", offsetof(struct mainpll_cfg, nocdiv_cstraceclk) },
|
|
|
+ { "nocdiv-cspdbgclk", offsetof(struct mainpll_cfg, nocdiv_cspdbclk) },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct strtou32 perpll_cfg_tab[] = {
|
|
|
+ { "vco0-psrc", offsetof(struct perpll_cfg, vco0_psrc) },
|
|
|
+ { "vco1-denom", offsetof(struct perpll_cfg, vco1_denom) },
|
|
|
+ { "vco1-numer", offsetof(struct perpll_cfg, vco1_numer) },
|
|
|
+ { "cntr2clk-cnt", offsetof(struct perpll_cfg, cntr2clk_cnt) },
|
|
|
+ { "cntr2clk-src", offsetof(struct perpll_cfg, cntr2clk_src) },
|
|
|
+ { "cntr3clk-cnt", offsetof(struct perpll_cfg, cntr3clk_cnt) },
|
|
|
+ { "cntr3clk-src", offsetof(struct perpll_cfg, cntr3clk_src) },
|
|
|
+ { "cntr4clk-cnt", offsetof(struct perpll_cfg, cntr4clk_cnt) },
|
|
|
+ { "cntr4clk-src", offsetof(struct perpll_cfg, cntr4clk_src) },
|
|
|
+ { "cntr5clk-cnt", offsetof(struct perpll_cfg, cntr5clk_cnt) },
|
|
|
+ { "cntr5clk-src", offsetof(struct perpll_cfg, cntr5clk_src) },
|
|
|
+ { "cntr6clk-cnt", offsetof(struct perpll_cfg, cntr6clk_cnt) },
|
|
|
+ { "cntr6clk-src", offsetof(struct perpll_cfg, cntr6clk_src) },
|
|
|
+ { "cntr7clk-cnt", offsetof(struct perpll_cfg, cntr7clk_cnt) },
|
|
|
+ { "cntr8clk-cnt", offsetof(struct perpll_cfg, cntr8clk_cnt) },
|
|
|
+ { "cntr8clk-src", offsetof(struct perpll_cfg, cntr8clk_src) },
|
|
|
+ { "cntr9clk-cnt", offsetof(struct perpll_cfg, cntr9clk_cnt) },
|
|
|
+ { "emacctl-emac0sel", offsetof(struct perpll_cfg, emacctl_emac0sel) },
|
|
|
+ { "emacctl-emac1sel", offsetof(struct perpll_cfg, emacctl_emac1sel) },
|
|
|
+ { "emacctl-emac2sel", offsetof(struct perpll_cfg, emacctl_emac2sel) },
|
|
|
+ { "gpiodiv-gpiodbclk", offsetof(struct perpll_cfg, gpiodiv_gpiodbclk) },
|
|
|
+};
|
|
|
+
|
|
|
+static const struct strtou32 alteragrp_cfg_tab[] = {
|
|
|
+ { "nocclk", offsetof(struct mainpll_cfg, nocclk) },
|
|
|
+ { "mpuclk", offsetof(struct mainpll_cfg, mpuclk) },
|
|
|
+};
|
|
|
+
|
|
|
+struct strtopu32 {
|
|
|
+ const char *str;
|
|
|
+ u32 *p;
|
|
|
+};
|
|
|
+
|
|
|
+const struct strtopu32 dt_to_val[] = {
|
|
|
+ { "/clocks/altera_arria10_hps_eosc1", &eosc1_hz},
|
|
|
+ { "/clocks/altera_arria10_hps_cb_intosc_ls", &cb_intosc_hz},
|
|
|
+ { "/clocks/altera_arria10_hps_f2h_free", &f2s_free_hz},
|
|
|
+};
|
|
|
|
|
|
-static int of_to_struct(const void *blob, int node, int cfg_len, void *cfg)
|
|
|
+static int of_to_struct(const void *blob, int node, const struct strtou32 *cfg_tab,
|
|
|
+ int cfg_tab_len, void *cfg)
|
|
|
{
|
|
|
- if (fdtdec_get_int_array(blob, node, "altr,of_reg_value",
|
|
|
- (u32 *)cfg, cfg_len)) {
|
|
|
- /* could not find required property */
|
|
|
- return -EINVAL;
|
|
|
+ int i;
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ for (i = 0; i < cfg_tab_len; i++) {
|
|
|
+ if (fdtdec_get_int_array(blob, node, cfg_tab[i].str, &val, 1)) {
|
|
|
+ /* could not find required property */
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ *(u32 *)(cfg + cfg_tab[i].val) = val;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int of_get_input_clks(const void *blob, int node, u32 *val)
|
|
|
+static void of_get_input_clks(const void *blob)
|
|
|
{
|
|
|
- *val = fdtdec_get_uint(blob, node, "clock-frequency", 0);
|
|
|
- if (!*val)
|
|
|
- return -EINVAL;
|
|
|
+ int node, i;
|
|
|
|
|
|
- return 0;
|
|
|
+ for (i = 0; i < ARRAY_SIZE(dt_to_val); i++) {
|
|
|
+ node = fdt_path_offset(blob, dt_to_val[i].str);
|
|
|
+
|
|
|
+ if (node < 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ fdtdec_get_int_array(blob, node, "clock-frequency",
|
|
|
+ dt_to_val[i].p, 1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg,
|
|
|
- struct perpll_cfg *per_cfg,
|
|
|
- struct alteragrp_cfg *altrgrp_cfg)
|
|
|
+ struct perpll_cfg *per_cfg)
|
|
|
{
|
|
|
int node, child, len;
|
|
|
const char *node_name;
|
|
|
|
|
|
- node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK);
|
|
|
+ of_get_input_clks(blob);
|
|
|
+
|
|
|
+ node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK_INIT);
|
|
|
+
|
|
|
if (node < 0)
|
|
|
return -EINVAL;
|
|
|
|
|
|
child = fdt_first_subnode(blob, node);
|
|
|
- if (child < 0)
|
|
|
- return -EINVAL;
|
|
|
|
|
|
- child = fdt_first_subnode(blob, child);
|
|
|
if (child < 0)
|
|
|
return -EINVAL;
|
|
|
|
|
|
node_name = fdt_get_name(blob, child, &len);
|
|
|
|
|
|
while (node_name) {
|
|
|
- if (!strcmp(node_name, "osc1")) {
|
|
|
- if (of_get_input_clks(blob, child, &eosc1_hz))
|
|
|
+ if (!strcmp(node_name, "mainpll")) {
|
|
|
+ if (of_to_struct(blob, child, mainpll_cfg_tab,
|
|
|
+ ARRAY_SIZE(mainpll_cfg_tab), main_cfg))
|
|
|
return -EINVAL;
|
|
|
- } else if (!strcmp(node_name, "cb_intosc_ls_clk")) {
|
|
|
- if (of_get_input_clks(blob, child, &cb_intosc_hz))
|
|
|
+ } else if (!strcmp(node_name, "perpll")) {
|
|
|
+ if (of_to_struct(blob, child, perpll_cfg_tab,
|
|
|
+ ARRAY_SIZE(perpll_cfg_tab), per_cfg))
|
|
|
return -EINVAL;
|
|
|
- } else if (!strcmp(node_name, "f2s_free_clk")) {
|
|
|
- if (of_get_input_clks(blob, child, &f2s_free_hz))
|
|
|
+ } else if (!strcmp(node_name, "alteragrp")) {
|
|
|
+ if (of_to_struct(blob, child, alteragrp_cfg_tab,
|
|
|
+ ARRAY_SIZE(alteragrp_cfg_tab), main_cfg))
|
|
|
return -EINVAL;
|
|
|
- } else if (!strcmp(node_name, "main_pll")) {
|
|
|
- if (of_to_struct(blob, child,
|
|
|
- sizeof(*main_cfg)/sizeof(u32),
|
|
|
- main_cfg))
|
|
|
- return -EINVAL;
|
|
|
- } else if (!strcmp(node_name, "periph_pll")) {
|
|
|
- if (of_to_struct(blob, child,
|
|
|
- sizeof(*per_cfg)/sizeof(u32),
|
|
|
- per_cfg))
|
|
|
- return -EINVAL;
|
|
|
- } else if (!strcmp(node_name, "altera")) {
|
|
|
- if (of_to_struct(blob, child,
|
|
|
- sizeof(*altrgrp_cfg)/sizeof(u32),
|
|
|
- altrgrp_cfg))
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- main_cfg->mpuclk = altrgrp_cfg->mpuclk;
|
|
|
- main_cfg->nocclk = altrgrp_cfg->nocclk;
|
|
|
}
|
|
|
child = fdt_next_subnode(blob, child);
|
|
|
|
|
@@ -878,15 +942,13 @@ int cm_basic_init(const void *blob)
|
|
|
{
|
|
|
struct mainpll_cfg main_cfg;
|
|
|
struct perpll_cfg per_cfg;
|
|
|
- struct alteragrp_cfg altrgrp_cfg;
|
|
|
int rval;
|
|
|
|
|
|
/* initialize to zero for use case of optional node */
|
|
|
memset(&main_cfg, 0, sizeof(main_cfg));
|
|
|
memset(&per_cfg, 0, sizeof(per_cfg));
|
|
|
- memset(&altrgrp_cfg, 0, sizeof(altrgrp_cfg));
|
|
|
|
|
|
- rval = of_get_clk_cfg(blob, &main_cfg, &per_cfg, &altrgrp_cfg);
|
|
|
+ rval = of_get_clk_cfg(blob, &main_cfg, &per_cfg);
|
|
|
if (rval)
|
|
|
return rval;
|
|
|
|