Author: jmcneill
Date: Wed Sep  7 01:10:16 2016
New Revision: 305512
URL: https://svnweb.freebsd.org/changeset/base/305512

Log:
  Add support for Allwinner A83T CPU frequency scaling.

Modified:
  head/sys/arm/allwinner/clk/aw_cpuclk.c
  head/sys/arm/allwinner/clk/aw_pll.c
  head/sys/boot/fdt/dts/arm/a83t.dtsi
  head/sys/boot/fdt/dts/arm/sinovoip-bpi-m3.dts

Modified: head/sys/arm/allwinner/clk/aw_cpuclk.c
==============================================================================
--- head/sys/arm/allwinner/clk/aw_cpuclk.c      Wed Sep  7 01:09:25 2016        
(r305511)
+++ head/sys/arm/allwinner/clk/aw_cpuclk.c      Wed Sep  7 01:10:16 2016        
(r305512)
@@ -47,8 +47,42 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/extres/clk/clk_mux.h>
 
-#define        CPU_CLK_SRC_SEL_WIDTH   2
-#define        CPU_CLK_SRC_SEL_SHIFT   16
+#define        A10_CPU_CLK_SRC_SEL_WIDTH       2
+#define        A10_CPU_CLK_SRC_SEL_SHIFT       16
+
+#define        A83T_Cx_CLK_SRC_SEL_WIDTH       1
+#define        A83T_C0_CLK_SRC_SEL_SHIFT       12
+#define        A83T_C1_CLK_SRC_SEL_SHIFT       28
+
+struct aw_cpuclk_config {
+       u_int           width;
+       u_int           shift;
+};
+
+static struct aw_cpuclk_config a10_config = {
+       .width = A10_CPU_CLK_SRC_SEL_WIDTH,
+       .shift = A10_CPU_CLK_SRC_SEL_SHIFT,
+};
+
+static struct aw_cpuclk_config a83t_c0_config = {
+       .width = A83T_Cx_CLK_SRC_SEL_WIDTH,
+       .shift = A83T_C0_CLK_SRC_SEL_SHIFT,
+};
+
+static struct aw_cpuclk_config a83t_c1_config = {
+       .width = A83T_Cx_CLK_SRC_SEL_WIDTH,
+       .shift = A83T_C1_CLK_SRC_SEL_SHIFT,
+};
+
+static struct ofw_compat_data compat_data[] = {
+       { "allwinner,sun4i-a10-cpu-clk",        (uintptr_t)&a10_config },
+       { "allwinner,sun8i-a83t-c0cpu-clk",     (uintptr_t)&a83t_c0_config },
+       { "allwinner,sun8i-a83t-c1cpu-clk",     (uintptr_t)&a83t_c1_config },
+       { NULL,                                 (uintptr_t)NULL }
+};
+
+#define        CPUCLK_CONF(d)          \
+       (void *)ofw_bus_search_compatible((d), compat_data)->ocd_data
 
 static int
 aw_cpuclk_probe(device_t dev)
@@ -56,7 +90,7 @@ aw_cpuclk_probe(device_t dev)
        if (!ofw_bus_status_okay(dev))
                return (ENXIO);
 
-       if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-cpu-clk"))
+       if (CPUCLK_CONF(dev) == NULL)
                return (ENXIO);
 
        device_set_desc(dev, "Allwinner CPU Clock");
@@ -68,6 +102,7 @@ aw_cpuclk_attach(device_t dev)
 {
        struct clk_mux_def def;
        struct clkdom *clkdom;
+       struct aw_cpuclk_config *conf;
        bus_addr_t paddr;
        bus_size_t psize;
        phandle_t node;
@@ -75,6 +110,7 @@ aw_cpuclk_attach(device_t dev)
        clk_t clk;
 
        node = ofw_bus_get_node(dev);
+       conf = CPUCLK_CONF(dev);
 
        if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
                device_printf(dev, "cannot parse 'reg' property\n");
@@ -105,8 +141,8 @@ aw_cpuclk_attach(device_t dev)
        }
        def.clkdef.parent_cnt = ncells;
        def.offset = paddr;
-       def.shift = CPU_CLK_SRC_SEL_SHIFT;
-       def.width = CPU_CLK_SRC_SEL_WIDTH;
+       def.shift = conf->shift;
+       def.width = conf->width;
 
        error = clk_parse_ofw_clk_name(dev, node, &def.clkdef.name);
        if (error != 0) {

Modified: head/sys/arm/allwinner/clk/aw_pll.c
==============================================================================
--- head/sys/arm/allwinner/clk/aw_pll.c Wed Sep  7 01:09:25 2016        
(r305511)
+++ head/sys/arm/allwinner/clk/aw_pll.c Wed Sep  7 01:10:16 2016        
(r305512)
@@ -157,6 +157,17 @@ __FBSDID("$FreeBSD$");
 #define        A80_PLL4_FACTOR_N               (0xff << 8)
 #define        A80_PLL4_FACTOR_N_SHIFT         8
 
+#define        A83T_PLLCPUX_LOCK_TIME          (0x7 << 24)
+#define        A83T_PLLCPUX_LOCK_TIME_SHIFT    24
+#define        A83T_PLLCPUX_CLOCK_OUTPUT_DIS   (1 << 20)
+#define        A83T_PLLCPUX_OUT_EXT_DIVP       (1 << 16)
+#define        A83T_PLLCPUX_FACTOR_N           (0xff << 8)
+#define        A83T_PLLCPUX_FACTOR_N_SHIFT     8
+#define        A83T_PLLCPUX_FACTOR_N_MIN       12
+#define        A83T_PLLCPUX_FACTOR_N_MAX       125
+#define        A83T_PLLCPUX_POSTDIV_M          (0x3 << 0)
+#define        A83T_PLLCPUX_POSTDIV_M_SHIFT    0
+
 #define        CLKID_A10_PLL3_1X               0
 #define        CLKID_A10_PLL3_2X               1
 
@@ -202,6 +213,7 @@ enum aw_pll_type {
        AWPLL_A31_PLL6,
        AWPLL_A64_PLLHSIC,
        AWPLL_A80_PLL4,
+       AWPLL_A83T_PLLCPUX,
        AWPLL_H3_PLL1,
 };
 
@@ -824,6 +836,46 @@ a64_pllhsic_init(device_t dev, bus_addr_
        return (0);
 }
 
+static int
+a83t_pllcpux_recalc(struct aw_pll_sc *sc, uint64_t *freq)
+{
+       uint32_t val, n, p;
+
+       DEVICE_LOCK(sc);
+       PLL_READ(sc, &val);
+       DEVICE_UNLOCK(sc);
+
+       n = (val & A83T_PLLCPUX_FACTOR_N) >> A83T_PLLCPUX_FACTOR_N_SHIFT;
+       p = (val & A83T_PLLCPUX_OUT_EXT_DIVP) ? 4 : 1;
+
+       *freq = (*freq * n) / p;
+
+       return (0);
+}
+
+static int
+a83t_pllcpux_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
+    int flags)
+{
+       uint32_t val;
+       u_int n;
+
+       n = *fout / fin;
+
+       if (n < A83T_PLLCPUX_FACTOR_N_MIN || n > A83T_PLLCPUX_FACTOR_N_MAX)
+               return (EINVAL);
+
+       DEVICE_LOCK(sc);
+       PLL_READ(sc, &val);
+       val &= ~A83T_PLLCPUX_FACTOR_N;
+       val |= (n << A83T_PLLCPUX_FACTOR_N_SHIFT);
+       val &= ~A83T_PLLCPUX_CLOCK_OUTPUT_DIS;
+       PLL_WRITE(sc, val);
+       DEVICE_UNLOCK(sc);
+
+       return (0);
+}
+
 #define        PLL(_type, _recalc, _set_freq, _init)   \
        [(_type)] = {                           \
                .recalc = (_recalc),            \
@@ -842,6 +894,7 @@ static struct aw_pll_funcs aw_pll_func[]
        PLL(AWPLL_A31_PLL1, a31_pll1_recalc, NULL, NULL),
        PLL(AWPLL_A31_PLL6, a31_pll6_recalc, NULL, a31_pll6_init),
        PLL(AWPLL_A80_PLL4, a80_pll4_recalc, NULL, NULL),
+       PLL(AWPLL_A83T_PLLCPUX, a83t_pllcpux_recalc, a83t_pllcpux_set_freq, 
NULL),
        PLL(AWPLL_A64_PLLHSIC, a64_pllhsic_recalc, NULL, a64_pllhsic_init),
        PLL(AWPLL_H3_PLL1, a23_pll1_recalc, h3_pll1_set_freq, NULL),
 };
@@ -856,6 +909,7 @@ static struct ofw_compat_data compat_dat
        { "allwinner,sun6i-a31-pll1-clk",       AWPLL_A31_PLL1 },
        { "allwinner,sun6i-a31-pll6-clk",       AWPLL_A31_PLL6 },
        { "allwinner,sun8i-a23-pll1-clk",       AWPLL_A23_PLL1 },
+       { "allwinner,sun8i-a83t-pllcpux-clk",   AWPLL_A83T_PLLCPUX },
        { "allwinner,sun8i-h3-pll1-clk",        AWPLL_H3_PLL1 },
        { "allwinner,sun9i-a80-pll4-clk",       AWPLL_A80_PLL4 },
        { "allwinner,sun50i-a64-pllhsic-clk",   AWPLL_A64_PLLHSIC },

Modified: head/sys/boot/fdt/dts/arm/a83t.dtsi
==============================================================================
--- head/sys/boot/fdt/dts/arm/a83t.dtsi Wed Sep  7 01:09:25 2016        
(r305511)
+++ head/sys/boot/fdt/dts/arm/a83t.dtsi Wed Sep  7 01:10:16 2016        
(r305512)
@@ -27,6 +27,18 @@
  */
 
 / {
+       cpus {
+               cpu@0 {
+                       clocks = <&c0_cpux_clk>;
+                       clock-latency = <2000000>;
+               };
+
+               cpu@100 {
+                       clocks = <&c1_cpux_clk>;
+                       clock-latency = <2000000>;
+               };
+       };
+
        pmu {
                compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
 
@@ -38,6 +50,38 @@
        };
 
        clocks {
+               pll_c0cpux: clk@01c20000 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-a83t-pllcpux-clk";
+                       reg = <0x01c20000 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll_c0cpux";
+               };
+
+               pll_c1cpux: clk@01c20004 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-a83t-pllcpux-clk";
+                       reg = <0x01c20004 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll_c1cpux";
+               };
+
+               c0_cpux_clk: c0clk@01c20050 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-a83t-c0cpu-clk";
+                       reg = <0x01c20050 0x4>;
+                       clocks = <&osc24M>, <&pll_c0cpux>;
+                       clock-output-names = "c0_cpux";
+               };
+
+               c1_cpux_clk: c1clk@01c20050 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-a83t-c1cpu-clk";
+                       reg = <0x01c20050 0x4>;
+                       clocks = <&osc24M>, <&pll_c1cpux>;
+                       clock-output-names = "c1_cpux";
+               };
+
                /* cpus_clk compatible in gnu dt is incorrect */
                cpus_clk: clk@01f01400 {
                         compatible = "allwinner,sun8i-a83t-cpus-clk";

Modified: head/sys/boot/fdt/dts/arm/sinovoip-bpi-m3.dts
==============================================================================
--- head/sys/boot/fdt/dts/arm/sinovoip-bpi-m3.dts       Wed Sep  7 01:09:25 
2016        (r305511)
+++ head/sys/boot/fdt/dts/arm/sinovoip-bpi-m3.dts       Wed Sep  7 01:10:16 
2016        (r305512)
@@ -29,6 +29,32 @@
 #include "sun8i-a83t-sinovoip-bpi-m3.dts"
 #include "a83t.dtsi"
 
+/ {
+       cpus {
+               cpu@0 {
+                       cpu-supply = <&reg_dcdc2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 840000
+                               1008000 840000
+                               648000  840000
+                               408000  840000
+                               >;
+               };
+
+               cpu@100 {
+                       cpu-supply = <&reg_dcdc3>;
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 840000
+                               1008000 840000
+                               648000  840000
+                               408000  840000
+                               >;
+               };
+       };
+};
+
 &ehci0 {
        status = "okay";
 };
@@ -115,6 +141,16 @@
                interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
                gpio-controller;
                #gpio-cells = <1>;
+
+               regulators {
+                       reg_dcdc2: dcdc2 {
+                               regulator-name = "dcdc2";
+                       };
+
+                       reg_dcdc3: dcdc3 {
+                               regulator-name = "dcdc3";
+                       };
+               };
        };
 };
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to