clk: JZ4780: Add function for enable the second core.
author周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Thu, 20 Feb 2020 16:24:43 +0000 (00:24 +0800)
committerStephen Boyd <sboyd@kernel.org>
Sat, 21 Mar 2020 00:02:03 +0000 (17:02 -0700)
Add "jz4780_core1_enable()" for enable the second core of JZ4780,
prepare for later commits.

Tested-by: H. Nikolaus Schaller <hns@goldelico.com>
Tested-by: Paul Boddie <paul@boddie.org.uk>
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Link: https://lkml.kernel.org/r/1582215889-113034-3-git-send-email-zhouyanjie@wanyeetech.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/clk/ingenic/jz4780-cgu.c

index ea905ff..c758f16 100644 (file)
@@ -9,14 +9,16 @@
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/of.h>
+
 #include <dt-bindings/clock/jz4780-cgu.h>
 #include "cgu.h"
 #include "pm.h"
 
 /* CGU register offsets */
 #define CGU_REG_CLOCKCONTROL   0x00
-#define CGU_REG_PLLCONTROL     0x0c
+#define CGU_REG_LCR                    0x04
 #define CGU_REG_APLL           0x10
 #define CGU_REG_MPLL           0x14
 #define CGU_REG_EPLL           0x18
@@ -46,8 +48,8 @@
 #define CGU_REG_CLOCKSTATUS    0xd4
 
 /* bits within the OPCR register */
-#define OPCR_SPENDN0           (1 << 7)
-#define OPCR_SPENDN1           (1 << 6)
+#define OPCR_SPENDN0           BIT(7)
+#define OPCR_SPENDN1           BIT(6)
 
 /* bits within the USBPCR register */
 #define USBPCR_USB_MODE                BIT(31)
 #define USBVBFIL_IDDIGFIL_MASK (0xffff << USBVBFIL_IDDIGFIL_SHIFT)
 #define USBVBFIL_USBVBFIL_MASK (0xffff)
 
+/* bits within the LCR register */
+#define LCR_PD_SCPU                    BIT(31)
+#define LCR_SCPUS                      BIT(27)
+
+/* bits within the CLKGR1 register */
+#define CLKGR1_CORE1           BIT(15)
+
 static struct ingenic_cgu *cgu;
 
 static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
@@ -205,6 +214,42 @@ static const struct clk_ops jz4780_otg_phy_ops = {
        .set_rate = jz4780_otg_phy_set_rate,
 };
 
+static int jz4780_core1_enable(struct clk_hw *hw)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const unsigned int timeout = 5000;
+       unsigned long flags;
+       int retval;
+       u32 lcr, clkgr1;
+
+       spin_lock_irqsave(&cgu->lock, flags);
+
+       lcr = readl(cgu->base + CGU_REG_LCR);
+       lcr &= ~LCR_PD_SCPU;
+       writel(lcr, cgu->base + CGU_REG_LCR);
+
+       clkgr1 = readl(cgu->base + CGU_REG_CLKGR1);
+       clkgr1 &= ~CLKGR1_CORE1;
+       writel(clkgr1, cgu->base + CGU_REG_CLKGR1);
+
+       spin_unlock_irqrestore(&cgu->lock, flags);
+
+       /* wait for the CPU to be powered up */
+       retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr,
+                                !(lcr & LCR_SCPUS), 10, timeout);
+       if (retval == -ETIMEDOUT) {
+               pr_err("%s: Wait for power up core1 timeout\n", __func__);
+               return retval;
+       }
+
+       return 0;
+}
+
+static const struct clk_ops jz4780_core1_ops = {
+       .enable = jz4780_core1_enable,
+};
+
 static const s8 pll_od_encoding[16] = {
        0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
        0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
@@ -699,9 +744,9 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
        },
 
        [JZ4780_CLK_CORE1] = {
-               "core1", CGU_CLK_GATE,
+               "core1", CGU_CLK_CUSTOM,
                .parents = { JZ4780_CLK_CPU, -1, -1, -1 },
-               .gate = { CGU_REG_CLKGR1, 15 },
+               .custom = { &jz4780_core1_ops },
        },
 
 };