From: Hai Pham <hai.pham...@renesas.com>

On R-Car V3M (AKA R8A77970), the SD0CKCR is laid out differently than on
the other R-Car gen3 SoCs. Hence, new clock types are introduced
respectively.

Based on Linux commit 381081ffc294 ("clk: renesas: r8a77970: Add SD0H/SD0
clocks for SDHI") by Sergei Shtylyov <sergei.shtyl...@cogentembedded.com>

Signed-off-by: Hai Pham <hai.pham...@renesas.com>
Signed-off-by: Marek Vasut <marek.vasut+rene...@mailbox.org>
Marek: - Fix missing ~ in GENMASK(a, b), use clrsetbits_le32 instead
       - Do not modify r8a77970-cpg-mssr.c much, drop enum r8a77970_clk_types
         which is now part of common clock types in rcar-gen3-cpg.h instead
---
 drivers/clk/renesas/clk-rcar-gen3.c     | 39 +++++++++++++++++++++++++
 drivers/clk/renesas/r8a77970-cpg-mssr.c |  5 ----
 drivers/clk/renesas/rcar-gen3-cpg.h     |  5 ++++
 3 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/renesas/clk-rcar-gen3.c 
b/drivers/clk/renesas/clk-rcar-gen3.c
index 53f16dfb1e0..f8a23623223 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -57,6 +57,18 @@ static const struct clk_div_table cpg_sd_div_table[] = {
        { 0, 2 }, { 1, 4 }, { 0, 0 },
 };
 
+static const struct clk_div_table r8a77970_cpg_sd0h_div_table[] = {
+       {  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
+       {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+       {  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
+};
+
+static const struct clk_div_table r8a77970_cpg_sd0_div_table[] = {
+       {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+       {  8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 },
+       {  0,  0 },
+};
+
 static unsigned int rcar_clk_get_table_div(const struct clk_div_table *table,
                                           const u32 value)
 {
@@ -205,6 +217,19 @@ static int gen3_clk_setup_sdif_div(struct clk *clk, ulong 
rate)
                debug("%s[%i] SD clk: parent=%i offset=%x div=%u rate=%lu => 
val=%u\n",
                      __func__, __LINE__, core->parent, core->offset, div, 
rate, value);
                break;
+
+       case CLK_TYPE_R8A77970_SD0:
+               div = gen3_clk_get_rate64(&grandparent) / rate;
+               value = rcar_clk_get_table_val(cpg_sd_div_table, div);
+               if (!value)
+                       return -EINVAL;
+
+               clrsetbits_le32(priv->base + core->offset,
+                               GENMASK(7, 4), value << 4);
+
+               debug("%s[%i] SD clk: parent=%i offset=%x div=%u rate=%lu => 
val=%u\n",
+                     __func__, __LINE__, core->parent, core->offset, div, 
rate, value);
+               break;
        }
 
        return 0;
@@ -358,6 +383,13 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
                                                     GENMASK(9, 5),
                                                     cpg_sdh_div_table, "SDH");
 
+       case CLK_TYPE_R8A77970_SD0H:
+               return rcar_clk_get_rate64_div_table(core->parent,
+                                                    
gen3_clk_get_rate64(&parent),
+                                                    priv->base + core->offset,
+                                                    CPG_SDCKCR_SDHFC_MASK,
+                                                    
r8a77970_cpg_sd0h_div_table, "SDH");
+
        case CLK_TYPE_GEN3_SD:
                fallthrough;
        case CLK_TYPE_GEN4_SD:
@@ -367,6 +399,13 @@ static u64 gen3_clk_get_rate64(struct clk *clk)
                                                     CPG_SDCKCR_FC_MASK,
                                                     cpg_sd_div_table, "SD");
 
+       case CLK_TYPE_R8A77970_SD0:
+               return rcar_clk_get_rate64_div_table(core->parent,
+                                                    
gen3_clk_get_rate64(&parent),
+                                                    priv->base + core->offset,
+                                                    CPG_SDCKCR_SD0FC_MASK,
+                                                    
r8a77970_cpg_sd0_div_table, "SD");
+
        case CLK_TYPE_GEN3_RPCSRC:
                return rcar_clk_get_rate64_div_table(core->parent,
                                                     
gen3_clk_get_rate64(&parent),
diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c 
b/drivers/clk/renesas/r8a77970-cpg-mssr.c
index 4d72ec1fae8..f5d77df4233 100644
--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
@@ -22,11 +22,6 @@
 
 #define CPG_SD0CKCR            0x0074
 
-enum r8a77970_clk_types {
-       CLK_TYPE_R8A77970_SD0H = CLK_TYPE_GEN3_SOC_BASE,
-       CLK_TYPE_R8A77970_SD0,
-};
-
 enum clk_ids {
        /* Core Clock Outputs exported to DT */
        LAST_DT_CORE_CLK = R8A77970_CLK_OSC,
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h 
b/drivers/clk/renesas/rcar-gen3-cpg.h
index 008e8928e59..200e4adb906 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -18,7 +18,9 @@ enum rcar_gen3_clk_types {
        CLK_TYPE_GEN3_PLL3,
        CLK_TYPE_GEN3_PLL4,
        CLK_TYPE_GEN3_SDH,
+       CLK_TYPE_R8A77970_SD0H,
        CLK_TYPE_GEN3_SD,
+       CLK_TYPE_R8A77970_SD0,
        CLK_TYPE_GEN3_R,
        CLK_TYPE_GEN3_MDSEL,    /* Select parent/divider using mode pin */
        CLK_TYPE_GEN3_Z,
@@ -115,6 +117,9 @@ struct rcar_gen3_cpg_pll_config {
 #define CPG_SDCKCR_STPnCK              BIT(8)
 #define CPG_SDCKCR_SRCFC_MASK          GENMASK(4, 2)
 #define CPG_SDCKCR_FC_MASK             GENMASK(1, 0)
+/* V3M specifics */
+#define CPG_SDCKCR_SDHFC_MASK          GENMASK(11, 8)
+#define CPG_SDCKCR_SD0FC_MASK          GENMASK(7, 4)
 
 #define CPG_RPCCKCR    0x238
 #define CPG_RPCCKCR_DIV_POST_MASK      GENMASK(4, 3)
-- 
2.39.0

Reply via email to