clk: renesas: rcar-gen3: Factor out CPG library

R-Car V3U has a CPG different enough to not be a generic Gen3 CPG but
similar enough to reuse code. Introduce a new CPG library, factor out
the SD clock and RPC clock handling and hook them to the generic Gen3
CPG driver so we have an equal state.

Based on Linux commit [1] and [2] by Wolfram Sang

[1] 8bb67d87346a ("clk: renesas: rcar-gen3: Factor out CPG library")
[2] 6f21d145b90f ("clk: renesas: cpg-lib: Move RPC clock registration to
the library")

Signed-off-by: Hai Pham <hai.pham.ud@renesas.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Marek: - Add rcar_clk_* prefix to all functions
       - Rebase on changes to
         clk: renesas: Introduce and use rcar_clk_get_rate64_div_table function
       - Use u32_encode_bits/GENMASK bitfield ops
diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c
index f8a2362..d778db6 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -29,34 +29,16 @@
 
 #include "renesas-cpg-mssr.h"
 #include "rcar-gen3-cpg.h"
+#include "rcar-cpg-lib.h"
 
 #define CPG_PLL0CR		0x00d8
 #define CPG_PLL2CR		0x002c
 #define CPG_PLL4CR		0x01f4
 
-#define SDnSRCFC_SHIFT		2
-#define STPnHCK_TABLE		(CPG_SDCKCR_STPnHCK >> SDnSRCFC_SHIFT)
-
-/* Non-constant mask variant of FIELD_GET/FIELD_PREP */
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-
 static const struct clk_div_table cpg_rpcsrc_div_table[] = {
 	{ 2, 5 }, { 3, 6 }, { 0, 0 },
 };
 
-static const struct clk_div_table cpg_rpc_div_table[] = {
-	{ 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 },
-};
-
-static const struct clk_div_table cpg_sdh_div_table[] = {
-	{ 0, 1 }, { 1, 2 }, { STPnHCK_TABLE | 2, 4 }, { STPnHCK_TABLE | 3, 8 },
-	{ STPnHCK_TABLE | 4, 16 }, { 0, 0 },
-};
-
-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 },
@@ -69,48 +51,6 @@
 	{  0,  0 },
 };
 
-static unsigned int rcar_clk_get_table_div(const struct clk_div_table *table,
-					   const u32 value)
-{
-	const struct clk_div_table *clkt;
-
-	for (clkt = table; clkt->div; clkt++)
-		if (clkt->val == value)
-			return clkt->div;
-	return 0;
-}
-
-static int rcar_clk_get_table_val(const struct clk_div_table *table,
-				  unsigned int div)
-{
-	const struct clk_div_table *clkt;
-
-	for (clkt = table; clkt->div; clkt++)
-		if (clkt->div == div)
-			return clkt->val;
-	return -EINVAL;
-}
-
-static __always_inline s64
-rcar_clk_get_rate64_div_table(unsigned int parent, u64 parent_rate,
-			      void __iomem *reg, const u32 mask,
-			      const struct clk_div_table *table, char *name)
-{
-	u32 value, div;
-	u64 rate;
-
-	value = field_get(mask, readl(reg));
-	div = rcar_clk_get_table_div(table, value);
-	if (!div)
-		return -EINVAL;
-
-	rate = parent_rate / div;
-	debug("%s[%i] %s clk: parent=%i div=%u => rate=%llu\n",
-	      __func__, __LINE__, name, parent, div, rate);
-
-	return rate;
-}
-
 static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk,
 			       struct cpg_mssr_info *info, struct clk *parent)
 {
@@ -156,7 +96,6 @@
 	const struct cpg_core_clk *core;
 	struct clk parent, grandparent;
 	int ret;
-	u32 value = 0, div = 0;
 
 	/*
 	 * The clk may be either CPG_MOD or core clock, in case this is MOD
@@ -191,45 +130,23 @@
 	case CLK_TYPE_GEN3_SDH:
 		fallthrough;
 	case CLK_TYPE_GEN4_SDH:
-		div = DIV_ROUND_CLOSEST(gen3_clk_get_rate64(&grandparent), rate);
-		value = rcar_clk_get_table_val(cpg_sdh_div_table, div);
-		if (value < 0)
-			return value;
-
-		clrsetbits_le32(priv->base + core->offset,
-				GENMASK(9, 2), value << 2);
-
-		debug("%s[%i] SDH clk: parent=%i offset=%x div=%u rate=%lu => val=%u\n",
-		      __func__, __LINE__, core->parent, core->offset, div, rate, value);
-		break;
+		return rcar_clk_set_rate64_sdh(core->parent,
+					       gen3_clk_get_rate64(&grandparent),
+					       rate, priv->base + core->offset);
 
 	case CLK_TYPE_GEN3_SD:
 		fallthrough;
 	case CLK_TYPE_GEN4_SD:
-		div = DIV_ROUND_CLOSEST(gen3_clk_get_rate64(&grandparent), rate);
-		value = rcar_clk_get_table_val(cpg_sd_div_table, div);
-		if (value < 0)
-			return value;
-
-		clrsetbits_le32(priv->base + core->offset,
-				GENMASK(1, 0), value);
-
-		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 rcar_clk_set_rate64_sd(core->parent,
+					      gen3_clk_get_rate64(&grandparent),
+					      rate, priv->base + core->offset);
 
 	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 rcar_clk_set_rate64_div_table(core->parent,
+						     gen3_clk_get_rate64(&grandparent),
+						     rate, priv->base + core->offset,
+						     CPG_SDCKCR_SD0FC_MASK,
+						     r8a77970_cpg_sd0_div_table, "SD");
 	}
 
 	return 0;
@@ -371,17 +288,9 @@
 	case CLK_TYPE_GEN3_SDH:	/* Fixed factor 1:1 */
 		fallthrough;
 	case CLK_TYPE_GEN4_SDH:	/* Fixed factor 1:1 */
-		/*
-		 * This takes STPnHCK and STPnCK bits into consideration
-		 * in the table look up too, hence the inobvious GENMASK
-		 * below. Bits [7:5] always read zero, so this is OKish.
-		 */
-		return rcar_clk_get_rate64_div_table(core->parent,
-						     gen3_clk_get_rate64(&parent),
-						     priv->base + core->offset,
-						     CPG_SDCKCR_SRCFC_MASK |
-						     GENMASK(9, 5),
-						     cpg_sdh_div_table, "SDH");
+		return rcar_clk_get_rate64_sdh(core->parent,
+					       gen3_clk_get_rate64(&parent),
+					       priv->base + core->offset);
 
 	case CLK_TYPE_R8A77970_SD0H:
 		return rcar_clk_get_rate64_div_table(core->parent,
@@ -393,11 +302,9 @@
 	case CLK_TYPE_GEN3_SD:
 		fallthrough;
 	case CLK_TYPE_GEN4_SD:
-		return rcar_clk_get_rate64_div_table(core->parent,
-						     gen3_clk_get_rate64(&parent),
-						     priv->base + core->offset,
-						     CPG_SDCKCR_FC_MASK,
-						     cpg_sd_div_table, "SD");
+		return rcar_clk_get_rate64_sd(core->parent,
+					      gen3_clk_get_rate64(&parent),
+					      priv->base + core->offset);
 
 	case CLK_TYPE_R8A77970_SD0:
 		return rcar_clk_get_rate64_div_table(core->parent,
@@ -446,20 +353,14 @@
 
 	case CLK_TYPE_GEN3_RPC:
 	case CLK_TYPE_GEN4_RPC:
-		return rcar_clk_get_rate64_div_table(core->parent,
-						     gen3_clk_get_rate64(&parent),
-						     priv->base + CPG_RPCCKCR,
-						     CPG_RPCCKCR_DIV_PRE_MASK,
-						     cpg_rpc_div_table, "RPC");
+		return rcar_clk_get_rate64_rpc(core->parent,
+					       gen3_clk_get_rate64(&parent),
+					       priv->base + CPG_RPCCKCR);
 
 	case CLK_TYPE_GEN3_RPCD2:
 	case CLK_TYPE_GEN4_RPCD2:
-		rate = gen3_clk_get_rate64(&parent) / 2;
-
-		debug("%s[%i] RPCD2 clk: parent=%i => rate=%llu\n",
-		      __func__, __LINE__, core->parent, rate);
-
-		return rate;
+		return rcar_clk_get_rate64_rpcd2(core->parent,
+						 gen3_clk_get_rate64(&parent));
 
 	}