MIPS: Alchemy: fix Au1000/Au1500 LRCLK calculation
authorManuel Lauss <manuel.lauss@gmail.com>
Thu, 29 Jan 2015 15:06:42 +0000 (16:06 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 20 Feb 2015 12:00:08 +0000 (13:00 +0100)
The Au1000 and Au1500 calculate the LRCLK a bit differently than
newer models: a single bit in MEM_STCFG0 selects if pclk is divided
by 4 or 5.

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
Cc: Linux-MIPS <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/9148/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/alchemy/common/clock.c

index 48a9dfc55b51aa4a3819bae6c686b0cd5f38a7f0..ade73375ede6a9a6b2d042b37916b957a10794b3 100644 (file)
@@ -315,17 +315,26 @@ static struct clk __init *alchemy_clk_setup_mem(const char *pn, int ct)
 
 /* lrclk: external synchronous static bus clock ***********************/
 
-static struct clk __init *alchemy_clk_setup_lrclk(const char *pn)
+static struct clk __init *alchemy_clk_setup_lrclk(const char *pn, int t)
 {
-       /* MEM_STCFG0[15:13] = divisor.
+       /* Au1000, Au1500: MEM_STCFG0[11]: If bit is set, lrclk=pclk/5,
+        * otherwise lrclk=pclk/4.
+        * All other variants: MEM_STCFG0[15:13] = divisor.
         * L/RCLK = periph_clk / (divisor + 1)
         * On Au1000, Au1500, Au1100 it's called LCLK,
         * on later models it's called RCLK, but it's the same thing.
         */
        struct clk *c;
-       unsigned long v = alchemy_rdsmem(AU1000_MEM_STCFG0) >> 13;
+       unsigned long v = alchemy_rdsmem(AU1000_MEM_STCFG0);
 
-       v = (v & 7) + 1;
+       switch (t) {
+       case ALCHEMY_CPU_AU1000:
+       case ALCHEMY_CPU_AU1500:
+               v = 4 + ((v >> 11) & 1);
+               break;
+       default:        /* all other models */
+               v = ((v >> 13) & 7) + 1;
+       }
        c = clk_register_fixed_factor(NULL, ALCHEMY_LR_CLK,
                                      pn, 0, 1, v);
        if (!IS_ERR(c))
@@ -1060,7 +1069,7 @@ static int __init alchemy_clk_init(void)
        ERRCK(c)
 
        /* L/RCLK: external static bus clock for synchronous mode */
-       c = alchemy_clk_setup_lrclk(ALCHEMY_PERIPH_CLK);
+       c = alchemy_clk_setup_lrclk(ALCHEMY_PERIPH_CLK, ctype);
        ERRCK(c)
 
        /* Frequency dividers 0-5 */