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.m...@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:
-- 
2.34.1

Reply via email to