svn commit: r305512 - in head/sys: arm/allwinner/clk boot/fdt/dts/arm
Jared McNeill
jmcneill at FreeBSD.org
Wed Sep 7 01:10:18 UTC 2016
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 at 0 {
+ clocks = <&c0_cpux_clk>;
+ clock-latency = <2000000>;
+ };
+
+ cpu at 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 at 01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a83t-pllcpux-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll_c0cpux";
+ };
+
+ pll_c1cpux: clk at 01c20004 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a83t-pllcpux-clk";
+ reg = <0x01c20004 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll_c1cpux";
+ };
+
+ c0_cpux_clk: c0clk at 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 at 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 at 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 at 0 {
+ cpu-supply = <®_dcdc2>;
+ operating-points = <
+ /* kHz uV */
+ 1200000 840000
+ 1008000 840000
+ 648000 840000
+ 408000 840000
+ >;
+ };
+
+ cpu at 100 {
+ cpu-supply = <®_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";
+ };
+ };
};
};
More information about the svn-src-head
mailing list