Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/rockchip Add RK3188/RK3188+ CPU frequency setti...



details:   https://anonhg.NetBSD.org/src/rev/8480e60cac90
branches:  trunk
changeset: 335317:8480e60cac90
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Fri Jan 02 21:59:29 2015 +0000

description:
Add RK3188/RK3188+ CPU frequency setting support.

diffstat:

 sys/arch/arm/rockchip/files.rockchip     |    3 +-
 sys/arch/arm/rockchip/obio.c             |    5 +-
 sys/arch/arm/rockchip/rockchip_board.c   |  236 ++--------------
 sys/arch/arm/rockchip/rockchip_cpufreq.c |  443 +++++++++++++++++++++++++++++++
 sys/arch/arm/rockchip/rockchip_var.h     |    6 +-
 5 files changed, 481 insertions(+), 212 deletions(-)

diffs (truncated from 799 to 300 lines):

diff -r ca931dbb419c -r 8480e60cac90 sys/arch/arm/rockchip/files.rockchip
--- a/sys/arch/arm/rockchip/files.rockchip      Fri Jan 02 21:58:03 2015 +0000
+++ b/sys/arch/arm/rockchip/files.rockchip      Fri Jan 02 21:59:29 2015 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.rockchip,v 1.5 2014/12/30 18:57:36 jmcneill Exp $
+#      $NetBSD: files.rockchip,v 1.6 2015/01/02 21:59:29 jmcneill Exp $
 #
 # Configuration info for Rockchip ARM Peripherals
 #
@@ -12,6 +12,7 @@
 file   arch/arm/arm32/irq_dispatch.S
 
 file   arch/arm/rockchip/rockchip_board.c
+file   arch/arm/rockchip/rockchip_cpufreq.c
 file   arch/arm/rockchip/rockchip_space.c      obio
 #file  arch/arm/rockchip/rockchip_a4x_space.c  obio
 file   arch/arm/rockchip/rockchip_dma.c
diff -r ca931dbb419c -r 8480e60cac90 sys/arch/arm/rockchip/obio.c
--- a/sys/arch/arm/rockchip/obio.c      Fri Jan 02 21:58:03 2015 +0000
+++ b/sys/arch/arm/rockchip/obio.c      Fri Jan 02 21:59:29 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: obio.c,v 1.8 2015/01/01 18:59:03 jmcneill Exp $        */
+/*     $NetBSD: obio.c,v 1.9 2015/01/02 21:59:29 jmcneill Exp $        */
 
 /*
  * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
@@ -38,7 +38,7 @@
 #include "opt_rockchip.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.8 2015/01/01 18:59:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.9 2015/01/02 21:59:29 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -282,6 +282,7 @@
        printf("CPU: %u Hz\n", rockchip_cpu_get_rate());
        printf("AHB: %u Hz\n", rockchip_ahb_get_rate());
        printf("APB: %u Hz\n", rockchip_apb_get_rate());
+       printf("PCLK_CPU: %u Hz\n", rockchip_pclk_cpu_get_rate());
        printf("A9PERIPH: %u Hz\n", rockchip_a9periph_get_rate());
 }
 #endif
diff -r ca931dbb419c -r 8480e60cac90 sys/arch/arm/rockchip/rockchip_board.c
--- a/sys/arch/arm/rockchip/rockchip_board.c    Fri Jan 02 21:58:03 2015 +0000
+++ b/sys/arch/arm/rockchip/rockchip_board.c    Fri Jan 02 21:59:29 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rockchip_board.c,v 1.10 2014/12/31 18:14:14 jmcneill Exp $ */
+/* $NetBSD: rockchip_board.c,v 1.11 2015/01/02 21:59:29 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "opt_rockchip.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rockchip_board.c,v 1.10 2014/12/31 18:14:14 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rockchip_board.c,v 1.11 2015/01/02 21:59:29 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -83,13 +83,6 @@
            ROCKCHIP_CRU_OFFSET, ROCKCHIP_CRU_SIZE, pbsh);
 }
 
-static void
-rockchip_get_grf_bsh(bus_space_handle_t *pbsh)
-{
-       bus_space_subregion(&rockchip_bs_tag, rockchip_core1_bsh,
-           ROCKCHIP_GRF_OFFSET, ROCKCHIP_GRF_SIZE, pbsh);
-}
-
 static u_int
 rockchip_pll_get_rate(bus_size_t con0_reg, bus_size_t con1_reg)
 {
@@ -134,203 +127,6 @@
        return rockchip_pll_get_rate(CRU_APLL_CON0_REG, CRU_APLL_CON1_REG);
 }
 
-struct rk3188_apll_rate {
-       u_int rate;
-       u_int nr, nf, no;
-       u_int core_div, core_periph_div, core_axi_div;
-       u_int aclk_div, hclk_div, pclk_div, ahb2apb_div;
-};
-
-#define RK3188_RATE(_r, _nf, _no, _p, _a, _aclk, _hclk, _pclk, _ahb2apb) \
-       { .rate = (_r) * 1000000, .nr = 1, .nf = (_nf), .no = (_no),     \
-         .core_div = 1, .core_periph_div = (_p), .core_axi_div = (_a),  \
-         .aclk_div = (_aclk), .hclk_div = (_hclk), .pclk_div = (_pclk), \
-         .ahb2apb_div = (_ahb2apb) }
-
-static const struct rk3188_apll_rate rk3188_apll_rates[] = {
-       RK3188_RATE(1608, 67, 1, 8, 4, 4, 2, 4, 2),
-       RK3188_RATE(1416, 59, 1, 8, 4, 4, 2, 4, 2),
-       RK3188_RATE(1200, 50, 1, 8, 4, 4, 2, 4, 2),
-       RK3188_RATE(1008, 42, 1, 8, 4, 3, 2, 4, 2),
-       RK3188_RATE( 816, 68, 2, 8, 4, 3, 2, 4, 2),
-       RK3188_RATE( 600, 50, 2, 4, 4, 3, 2, 4, 2),
-};
-
-#define RK3188_GRF_STATUS0_REG         0x00ac
-#define RK3188_GRF_STATUS0_APLL_LOCK   __BIT(6)
-
-static u_int
-rk3188_apll_set_rate(u_int rate)
-{
-       const struct rk3188_apll_rate *r = NULL;
-       bus_space_tag_t bst = &rockchip_bs_tag;
-       bus_space_handle_t bsh, grf_bsh;
-       uint32_t apll_con0, apll_con1, apll_con2, clksel0_con, clksel1_con;
-       uint32_t reset_mask, reset;
-       u_int cpu_aclk_div_con;
-       const bool rk3188plus_p = rockchip_is_chip(ROCKCHIP_CHIPVER_RK3188PLUS);
-
-       rockchip_get_cru_bsh(&bsh);
-       rockchip_get_grf_bsh(&grf_bsh);
-
-#ifdef ROCKCHIP_CLOCK_DEBUG
-       printf("%s: rate=%u rk3188plus_p=%d\n", __func__, rate, rk3188plus_p);
-#endif
-
-       /* Pick the closest rate (nearest 100MHz increment) */
-       for (int i = 0; i < __arraycount(rk3188_apll_rates); i++) {
-               u_int trate = rate / 1000000;
-               u_int arate = ((rk3188_apll_rates[i].rate / 1000000) + 50)
-                   / 100 * 100;
-               if (arate <= trate) {
-                       r = &rk3188_apll_rates[i];
-                       break;
-               }
-       }
-       if (r == NULL) {
-#ifdef ROCKCHIP_CLOCK_DEBUG
-               printf("CPU: No matching rate found for %u MHz\n", rate);
-#endif
-               return ENOENT;
-       }
-
-       printf("CPU: Set frequency to %u MHz...\n", r->rate / 1000000);
-
-       if (rk3188plus_p) {
-               reset_mask = CRU_PLL_CON3_RESET_MASK;
-               reset = CRU_PLL_CON3_RESET;
-       } else {
-               reset_mask = CRU_PLL_CON3_POWER_DOWN_MASK;
-               reset = CRU_PLL_CON3_POWER_DOWN;
-       }
-
-       apll_con0 = CRU_PLL_CON0_CLKR_MASK | CRU_PLL_CON0_CLKOD_MASK;
-       apll_con0 |= __SHIFTIN(r->no - 1, CRU_PLL_CON0_CLKOD);
-       apll_con0 |= __SHIFTIN(r->nr - 1, CRU_PLL_CON0_CLKR);
-
-       apll_con1 = CRU_PLL_CON1_CLKF_MASK;
-       apll_con1 |= __SHIFTIN(r->nf - 1, CRU_PLL_CON1_CLKF);
-
-       if (rk3188plus_p) {
-               apll_con2 = CRU_PLL_CON2_BWADJ_MASK;
-               apll_con2 |= __SHIFTIN(r->nf >> 1, CRU_PLL_CON2_BWADJ);
-       } else {
-               apll_con2 = 0;
-       }
-
-       clksel0_con = RK3188_CRU_CLKSEL_CON0_A9_CORE_DIV_CON_MASK |
-                     CRU_CLKSEL_CON0_CORE_PERI_DIV_CON_MASK |
-                     CRU_CLKSEL_CON0_A9_CORE_DIV_CON_MASK;
-       clksel0_con |= __SHIFTIN(r->core_div - 1,
-                                RK3188_CRU_CLKSEL_CON0_A9_CORE_DIV_CON);
-       clksel0_con |= __SHIFTIN(ffs(r->core_periph_div) - 2,
-                                CRU_CLKSEL_CON0_CORE_PERI_DIV_CON);
-       clksel0_con |= __SHIFTIN(r->aclk_div - 1,
-                                CRU_CLKSEL_CON0_A9_CORE_DIV_CON);
-
-       clksel1_con = CRU_CLKSEL_CON1_AHB2APB_PCLKEN_DIV_CON_MASK |
-                     CRU_CLKSEL_CON1_CPU_PCLK_DIV_CON_MASK |
-                     CRU_CLKSEL_CON1_CPU_HCLK_DIV_CON_MASK |
-                     RK3188_CRU_CLKSEL_CON1_CPU_ACLK_DIV_CON_MASK;
-
-       switch (r->core_axi_div) {
-       case 1: cpu_aclk_div_con = 0; break;
-       case 2: cpu_aclk_div_con = 1; break;
-       case 3: cpu_aclk_div_con = 2; break;
-       case 4: cpu_aclk_div_con = 3; break;
-       case 8: cpu_aclk_div_con = 4; break;
-       default: panic("bad core_axi_div");
-       }
-       clksel1_con |= __SHIFTIN(ffs(r->ahb2apb_div) - 1,
-                                CRU_CLKSEL_CON1_AHB2APB_PCLKEN_DIV_CON);
-       clksel1_con |= __SHIFTIN(ffs(r->hclk_div) - 1,
-                                CRU_CLKSEL_CON1_CPU_HCLK_DIV_CON);
-       clksel1_con |= __SHIFTIN(ffs(r->pclk_div) - 1,
-                                CRU_CLKSEL_CON1_CPU_PCLK_DIV_CON);
-       clksel1_con |= __SHIFTIN(cpu_aclk_div_con,
-                                RK3188_CRU_CLKSEL_CON1_CPU_ACLK_DIV_CON);
-
-#ifdef ROCKCHIP_CLOCK_DEBUG
-       printf("before: APLL_CON0: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_APLL_CON0_REG));
-       printf("before: APLL_CON1: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_APLL_CON1_REG));
-       printf("before: CLKSEL0_CON: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_CLKSEL_CON_REG(0)));
-       printf("before: CLKSEL1_CON: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_CLKSEL_CON_REG(1)));
-#endif
-
-       bus_space_write_4(bst, bsh, CRU_MODE_CON_REG,
-           CRU_MODE_CON_APLL_WORK_MODE_MASK |
-           __SHIFTIN(CRU_MODE_CON_APLL_WORK_MODE_SLOW,
-                     CRU_MODE_CON_APLL_WORK_MODE));
-
-       /* Power down */
-       bus_space_write_4(bst, bsh, CRU_APLL_CON3_REG, reset_mask | reset);
-
-       /* Update APLL regs */
-       bus_space_write_4(bst, bsh, CRU_APLL_CON0_REG, apll_con0);
-       bus_space_write_4(bst, bsh, CRU_APLL_CON1_REG, apll_con1);
-       if (apll_con2)
-               bus_space_write_4(bst, bsh, CRU_APLL_CON2_REG, apll_con2);
-
-       for (volatile int i = 5000; i >= 0; i--)
-               ;
-
-       /* Power up */
-       bus_space_write_4(bst, bsh, CRU_APLL_CON3_REG, reset_mask);
-
-       /* Wait for PLL lock */
-       printf("CPU: Waiting for PLL lock...\n");
-       for (volatile int i = 50000; i >= 0; i--)
-               ;
-       int retry = ROCKCHIP_REF_FREQ;
-       while (--retry > 0) {
-               uint32_t status = bus_space_read_4(bst, grf_bsh,
-                   RK3188_GRF_STATUS0_REG);
-               if (status & RK3188_GRF_STATUS0_APLL_LOCK)
-                       break;
-               for (volatile int i = 1000; i >= 0; i--)
-                       ;
-       }
-       printf("CPU: PLL lock %s\n", retry == 0 ? "timeout!" : "OK");
-
-       /* Update CLKSEL regs */
-       bus_space_write_4(bst, bsh, CRU_CLKSEL_CON_REG(0), clksel0_con);
-       bus_space_write_4(bst, bsh, CRU_CLKSEL_CON_REG(1), clksel1_con);
-
-       /* Slow -> Normal mode */
-       bus_space_write_4(bst, bsh, CRU_MODE_CON_REG,
-           CRU_MODE_CON_APLL_WORK_MODE_MASK |
-           __SHIFTIN(CRU_MODE_CON_APLL_WORK_MODE_NORMAL,
-                     CRU_MODE_CON_APLL_WORK_MODE));
-
-#ifdef ROCKCHIP_CLOCK_DEBUG
-       printf("after: APLL_CON0: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_APLL_CON0_REG));
-       printf("after: APLL_CON1: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_APLL_CON1_REG));
-       printf("after: CLKSEL0_CON: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_CLKSEL_CON_REG(0)));
-       printf("after: CLKSEL1_CON: %#x\n",
-           bus_space_read_4(bst, bsh, CRU_CLKSEL_CON_REG(1)));
-#endif
-
-       return 0;
-}
-
-u_int
-rockchip_apll_set_rate(u_int rate)
-{
-       if (rockchip_is_chip(ROCKCHIP_CHIPVER_RK3188) ||
-           rockchip_is_chip(ROCKCHIP_CHIPVER_RK3188PLUS)) {
-               return rk3188_apll_set_rate(rate);
-       }
-
-       return ENODEV;
-}
-
 u_int
 rockchip_cpu_get_rate(void)
 {
@@ -384,6 +180,32 @@
 }
 
 u_int
+rockchip_pclk_cpu_get_rate(void)
+{
+       bus_space_tag_t bst = &rockchip_bs_tag;
+       bus_space_handle_t bsh;
+       uint32_t clksel_con1;
+       u_int core_axi_div, pclk_div;
+
+       rockchip_get_cru_bsh(&bsh);
+
+       clksel_con1 = bus_space_read_4(bst, bsh, CRU_CLKSEL_CON_REG(1));
+       switch (__SHIFTOUT(clksel_con1,
+                          RK3188_CRU_CLKSEL_CON1_CPU_ACLK_DIV_CON)) {
+       case 0: core_axi_div = 1; break;
+       case 1: core_axi_div = 2; break;
+       case 2: core_axi_div = 3; break;
+       case 3: core_axi_div = 4; break;
+       case 4: core_axi_div = 8; break;



Home | Main Index | Thread Index | Old Index