
In order for some of the functionalities, such as the USB clocks, to work properly we need some clocks to be properly initialised at the very beginning of booting.
Signed-off-by: Sergiu Moga sergiu.moga@microchip.com --- drivers/clk/at91/sam9x60.c | 62 +++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c index eaf70c4668..4336148f73 100644 --- a/drivers/clk/at91/sam9x60.c +++ b/drivers/clk/at91/sam9x60.c @@ -380,6 +380,36 @@ static const struct { { .n = "dbgu_gclk", .id = 47, }, };
+/** + * Clock setup description + * @cid: clock id corresponding to clock subsystem + * @pid: parent clock id corresponding to clock subsystem + * @rate: clock rate + * @prate: parent rate + */ +static const struct pmc_clk_setup { + unsigned int cid; + unsigned int pid; + unsigned long rate; + unsigned long prate; +} sam9x60_clk_setup[] = { + { + .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_FRAC), + .rate = 960000000, + }, + + { + .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV), + .rate = 480000000, + }, + + { + .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_USBCK), + .pid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV), + .rate = 48000000, + }, +}; + #define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label) \ do { \ int _i; \ @@ -399,7 +429,7 @@ static int sam9x60_clk_probe(struct udevice *dev) unsigned int *clkmuxallocs[64], *muxallocs[64]; const char *p[10]; unsigned int cm[10], m[10], *tmpclkmux, *tmpmux; - struct clk clk, *c; + struct clk clk, *c, *parent; int ret, muxallocindex = 0, clkmuxallocindex = 0, i; static const struct clk_range r = { 0, 0 };
@@ -672,6 +702,36 @@ static int sam9x60_clk_probe(struct udevice *dev) clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sam9x60_gck[i].id), c); }
+ /* Setup clocks. */ + for (i = 0; i < ARRAY_SIZE(sam9x60_clk_setup); i++) { + ret = clk_get_by_id(sam9x60_clk_setup[i].cid, &c); + if (ret) + goto fail; + + if (sam9x60_clk_setup[i].pid) { + ret = clk_get_by_id(sam9x60_clk_setup[i].pid, &parent); + if (ret) + goto fail; + + ret = clk_set_parent(c, parent); + if (ret) + goto fail; + + if (sam9x60_clk_setup[i].prate) { + ret = clk_set_rate(parent, + sam9x60_clk_setup[i].prate); + if (ret < 0) + goto fail; + } + } + + if (sam9x60_clk_setup[i].rate) { + ret = clk_set_rate(c, sam9x60_clk_setup[i].rate); + if (ret < 0) + goto fail; + } + } + return 0;
fail: