Re: [PATCH v2 16/28] clk: rockchip: Add rv1126 clk support

2022-09-28 Thread Kever Yang



On 2022/8/18 22:52, Jagan Teki wrote:

Add clock driver support for Rockchip RV1126 SoC.

Signed-off-by: Joseph Chen 
Signed-off-by: Jagan Teki 

Reviewed-by: Kever Yang 

Thanks,
- Kever

---
Changes for v2:
- update cru header

  drivers/clk/rockchip/Makefile |1 +
  drivers/clk/rockchip/clk_rv1126.c | 1889 +
  2 files changed, 1890 insertions(+)
  create mode 100644 drivers/clk/rockchip/clk_rv1126.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index a72d8fe58a..f719f4e379 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o
  obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
  obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o
  obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
+obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o
diff --git a/drivers/clk/rockchip/clk_rv1126.c 
b/drivers/clk/rockchip/clk_rv1126.c
new file mode 100644
index 00..3ed29364de
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rv1126.c
@@ -0,0 +1,1889 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ * Author: Finley Xiao 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define RV1126_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)\
+{  \
+   .rate   = _rate##U, \
+   .aclk_div = _aclk_div,  \
+   .pclk_div = _pclk_div,  \
+}
+
+#define DIV_TO_RATE(input_rate, div)((input_rate) / ((div) + 1))
+
+static struct rockchip_cpu_rate_table rv1126_cpu_rates[] = {
+   RV1126_CPUCLK_RATE(12, 1, 5),
+   RV1126_CPUCLK_RATE(100800, 1, 5),
+   RV1126_CPUCLK_RATE(81600, 1, 3),
+   RV1126_CPUCLK_RATE(6, 1, 3),
+   RV1126_CPUCLK_RATE(40800, 1, 1),
+};
+
+static struct rockchip_pll_rate_table rv1126_pll_rates[] = {
+   /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+   RK3036_PLL_RATE(16, 3, 200, 1, 1, 1, 0),
+   RK3036_PLL_RATE(14, 3, 350, 2, 1, 1, 0),
+   RK3036_PLL_RATE(12, 1, 100, 2, 1, 1, 0),
+   RK3036_PLL_RATE(118800, 1, 99, 2, 1, 1, 0),
+   RK3036_PLL_RATE(11, 3, 275, 2, 1, 1, 0),
+   RK3036_PLL_RATE(100800, 1, 84, 2, 1, 1, 0),
+   RK3036_PLL_RATE(10, 3, 250, 2, 1, 1, 0),
+   RK3036_PLL_RATE(81600, 1, 68, 2, 1, 1, 0),
+   RK3036_PLL_RATE(8, 3, 200, 2, 1, 1, 0),
+   RK3036_PLL_RATE(6, 1, 100, 4, 1, 1, 0),
+   RK3036_PLL_RATE(59400, 1, 99, 4, 1, 1, 0),
+   RK3036_PLL_RATE(5, 1, 125, 6, 1, 1, 0),
+   RK3036_PLL_RATE(2, 1, 100, 6, 2, 1, 0),
+   RK3036_PLL_RATE(1, 1, 100, 6, 4, 1, 0),
+   { /* sentinel */ },
+};
+
+static struct rockchip_pll_clock rv1126_pll_clks[] = {
+   [APLL] = PLL(pll_rk3328, PLL_APLL, RV1126_PLL_CON(0),
+RV1126_MODE_CON, 0, 10, 0, rv1126_pll_rates),
+   [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1126_PLL_CON(8),
+RV1126_MODE_CON, 2, 10, 0, NULL),
+   [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126_PLL_CON(16),
+RV1126_MODE_CON, 4, 10, 0, rv1126_pll_rates),
+   [HPLL] = PLL(pll_rk3328, PLL_HPLL, RV1126_PLL_CON(24),
+RV1126_MODE_CON, 6, 10, 0, rv1126_pll_rates),
+   [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126_PMU_PLL_CON(0),
+RV1126_PMU_MODE, 0, 10, 0, rv1126_pll_rates),
+};
+
+static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
+ struct rv1126_pmuclk_priv *pmu_priv,
+ ulong rate);
+/*
+ *
+ * rational_best_approximation(31415, 1,
+ * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+   unsigned long given_denominator,
+   unsigned long max_numerator,
+   unsigned long max_denominator,
+   unsigned long *best_numerator,
+   unsigned long *best_denominator)
+{
+   unsigned long n, d, n0, d0, n1, d1;
+
+   n = given_numerator;
+   d = given_denominator;
+   n0 = 0;
+   d1 = 0;
+   n1 = 1;
+   d0 = 1;
+   for (;;) {
+   unsigned lon

[PATCH v2 16/28] clk: rockchip: Add rv1126 clk support

2022-08-18 Thread Jagan Teki
Add clock driver support for Rockchip RV1126 SoC.

Signed-off-by: Joseph Chen 
Signed-off-by: Jagan Teki 
---
Changes for v2:
- update cru header

 drivers/clk/rockchip/Makefile |1 +
 drivers/clk/rockchip/clk_rv1126.c | 1889 +
 2 files changed, 1890 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk_rv1126.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index a72d8fe58a..f719f4e379 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
 obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o
 obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
+obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o
diff --git a/drivers/clk/rockchip/clk_rv1126.c 
b/drivers/clk/rockchip/clk_rv1126.c
new file mode 100644
index 00..3ed29364de
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rv1126.c
@@ -0,0 +1,1889 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ * Author: Finley Xiao 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define RV1126_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)\
+{  \
+   .rate   = _rate##U, \
+   .aclk_div = _aclk_div,  \
+   .pclk_div = _pclk_div,  \
+}
+
+#define DIV_TO_RATE(input_rate, div)((input_rate) / ((div) + 1))
+
+static struct rockchip_cpu_rate_table rv1126_cpu_rates[] = {
+   RV1126_CPUCLK_RATE(12, 1, 5),
+   RV1126_CPUCLK_RATE(100800, 1, 5),
+   RV1126_CPUCLK_RATE(81600, 1, 3),
+   RV1126_CPUCLK_RATE(6, 1, 3),
+   RV1126_CPUCLK_RATE(40800, 1, 1),
+};
+
+static struct rockchip_pll_rate_table rv1126_pll_rates[] = {
+   /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+   RK3036_PLL_RATE(16, 3, 200, 1, 1, 1, 0),
+   RK3036_PLL_RATE(14, 3, 350, 2, 1, 1, 0),
+   RK3036_PLL_RATE(12, 1, 100, 2, 1, 1, 0),
+   RK3036_PLL_RATE(118800, 1, 99, 2, 1, 1, 0),
+   RK3036_PLL_RATE(11, 3, 275, 2, 1, 1, 0),
+   RK3036_PLL_RATE(100800, 1, 84, 2, 1, 1, 0),
+   RK3036_PLL_RATE(10, 3, 250, 2, 1, 1, 0),
+   RK3036_PLL_RATE(81600, 1, 68, 2, 1, 1, 0),
+   RK3036_PLL_RATE(8, 3, 200, 2, 1, 1, 0),
+   RK3036_PLL_RATE(6, 1, 100, 4, 1, 1, 0),
+   RK3036_PLL_RATE(59400, 1, 99, 4, 1, 1, 0),
+   RK3036_PLL_RATE(5, 1, 125, 6, 1, 1, 0),
+   RK3036_PLL_RATE(2, 1, 100, 6, 2, 1, 0),
+   RK3036_PLL_RATE(1, 1, 100, 6, 4, 1, 0),
+   { /* sentinel */ },
+};
+
+static struct rockchip_pll_clock rv1126_pll_clks[] = {
+   [APLL] = PLL(pll_rk3328, PLL_APLL, RV1126_PLL_CON(0),
+RV1126_MODE_CON, 0, 10, 0, rv1126_pll_rates),
+   [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1126_PLL_CON(8),
+RV1126_MODE_CON, 2, 10, 0, NULL),
+   [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126_PLL_CON(16),
+RV1126_MODE_CON, 4, 10, 0, rv1126_pll_rates),
+   [HPLL] = PLL(pll_rk3328, PLL_HPLL, RV1126_PLL_CON(24),
+RV1126_MODE_CON, 6, 10, 0, rv1126_pll_rates),
+   [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126_PMU_PLL_CON(0),
+RV1126_PMU_MODE, 0, 10, 0, rv1126_pll_rates),
+};
+
+static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
+ struct rv1126_pmuclk_priv *pmu_priv,
+ ulong rate);
+/*
+ *
+ * rational_best_approximation(31415, 1,
+ * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+   unsigned long given_denominator,
+   unsigned long max_numerator,
+   unsigned long max_denominator,
+   unsigned long *best_numerator,
+   unsigned long *best_denominator)
+{
+   unsigned long n, d, n0, d0, n1, d1;
+
+   n = given_numerator;
+   d = given_denominator;
+   n0 = 0;
+   d1 = 0;
+   n1 = 1;
+   d0 = 1;
+   for (;;) {
+   unsigned long t, a;
+
+   if (n1 > max_numerator || d1 > max_denominator) {
+