Index: sys/riscv/sifive/fu540_prci.c =================================================================== --- sys/riscv/sifive/fu540_prci.c +++ sys/riscv/sifive/fu540_prci.c @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -119,6 +120,17 @@ PLL(PRCI_CLK_COREPLL, "gemgxclk", PRCI_GEMGXLPLL_CFG0), }; +/* Fixed divisor clock TLCLK. */ +struct clk_fixed_def tlclk_def = { + .clkdef.id = PRCI_CLK_TLCLK, + .clkdef.name = "tlclk", + .clkdef.parent_names = (const char *[]){"coreclk"}, + .clkdef.parent_cnt = 1, + .clkdef.flags = CLK_NODE_STATIC_STRINGS, + .mult = 1, + .div = 2, +}; + static int prci_clk_pll_init(struct clknode *clk, device_t dev) { @@ -271,6 +283,18 @@ prci_pll_register(sc, &clkdef, pll_clks[i].reg); } + /* + * If an older device tree is being used, tlclk may appear as its own + * entity in the device tree, under soc/tlclk. If this is the case it + * will be detected and registered by the fixed_clk driver. + * + * Otherwise, if we are using upstream's device tree, tlclk is a child + * of the PRCI block, and we should register it here as a fixed clock. + */ + node = OF_finddevice("/soc/tlclk"); + if (node == -1) + clknode_fixed_register(sc->clkdom, &tlclk_def); + error = clkdom_finit(sc->clkdom); if (error) panic("Couldn't finalise clock domain");