realtek: clock driver: care about locked register
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Tue, 6 Sep 2022 08:48:45 +0000 (10:48 +0200)
committerSander Vanheule <sander@svanheule.net>
Mon, 26 Dec 2022 19:29:36 +0000 (20:29 +0100)
some RTL838X devices are shipped with locked registers. Remove the locks
so we can read/write the required PLL registers.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.c
target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl83xx.h

index f35d61313bd5d162d9873e339e290f22fc474d4f..2e5b8c5441868878620e97d977e1dd7cb48c4d20 100644 (file)
@@ -373,9 +373,6 @@ static unsigned long rtcl_recalc_rate(struct clk_hw *hw, unsigned long parent_ra
 
        switch (rtcl_ccu->soc) {
        case RTCL_SOC838X:
-               if ((ctrl0 == 0) && (ctrl1 == 0) && (clk->idx == CLK_LXB))
-                       return 200000000;
-
                cmu_divn2_selb = RTL838X_PLL_CTRL1_CMU_DIVN2_SELB(ctrl1);
                cmu_divn3_sel = rtcl_divn3[RTL838X_PLL_CTRL1_CMU_DIVN3_SEL(ctrl1)];
                break;
@@ -484,6 +481,26 @@ static const struct clk_ops rtcl_clk_ops = {
        .recalc_rate = rtcl_recalc_rate,
 };
 
+static void rtcl_unlock_registers(void)
+{
+       u32 enable, reg;
+
+       if (rtcl_ccu->soc != RTCL_SOC838X)
+               return;
+/*
+ * Some RTL838X devices are shipped with register access locked. In this case
+ * we cannot read and/or write to LXB or SW PLL registers. As there is no real
+ * benefit of always unlocking/locking these registers just open up everything.
+ */
+       enable = RTL838X_INT_RW_CTRL_READ_EN | RTL838X_INT_RW_CTRL_WRITE_EN;
+       reg = ioread32((void *)RTL_SW_CORE_BASE + RTL838X_INT_RW_CTRL);
+       if ((reg & enable) != enable) {
+               reg |= enable;
+               iowrite32(reg, (void *)RTL_SW_CORE_BASE + RTL838X_INT_RW_CTRL);
+               pr_warn("%s: registers unlocked\n", __func__);
+       }
+}
+
 static int rtcl_ccu_create(struct device_node *np)
 {
        int soc;
@@ -714,6 +731,7 @@ static void __init rtcl_probe_early(struct device_node *np)
        if (rtcl_ccu_create(np))
                return;
 
+       rtcl_unlock_registers();
        if (rtcl_ccu_register_clocks())
                kfree(rtcl_ccu);
        else
index 22c7b4a3fc4d019151778706ebf6edf8b638ca36..5b2d58cbab8141f22517f628a8a02f24271a9e49 100644 (file)
@@ -10,6 +10,7 @@
 
 #define RTL_SW_CORE_BASE                       (0xbb000000)
 
+#define RTL838X_INT_RW_CTRL                    (0x0058)
 #define RTL838X_PLL_GLB_CTRL                   (0x0fc0)
 #define RTL838X_PLL_CPU_CTRL0                  (0x0fc4)
 #define RTL838X_PLL_CPU_CTRL1                  (0x0fc8)
@@ -31,6 +32,8 @@
 #define RTL_PLL_CTRL0_CMU_NCODE_IN(v)          (((v) >> 4) & 0xff)
 #define RTL_PLL_CTRL0_CMU_DIVN2(v)             (((v) >> 12) & 0xff)
 
+#define RTL838X_INT_RW_CTRL_READ_EN            (1 << 0)
+#define RTL838X_INT_RW_CTRL_WRITE_EN           (1 << 1)
 #define RTL838X_GLB_CTRL_EN_CPU_PLL_MASK       (1 << 0)
 #define RTL838X_GLB_CTRL_EN_LXB_PLL_MASK       (1 << 1)
 #define RTL838X_GLB_CTRL_EN_MEM_PLL_MASK       (1 << 2)