From 250a9c2cc0206c586557f37bc3db820d3750da39 Mon Sep 17 00:00:00 2001 From: AGM1968 Date: Wed, 3 May 2023 09:35:53 +0200 Subject: [PATCH] h616 Cpu frequency scaling (#5123) * Add-h616-efuse_xlate-cpu-freq-scaling * series_additions_h616-cpu-freq-scaling * series_armbian_changes_h616-cpu-freq-scaling --------- Co-authored-by: AGM1968 --- ...616-Add-efuse_xlate-cpu-freq-scaling.patch | 340 ++++++++++++++++++ .../kernel/archive/sunxi-5.19/series.armbian | 1 + patch/kernel/archive/sunxi-5.19/series.conf | 1 + 3 files changed, 342 insertions(+) create mode 100644 patch/kernel/archive/sunxi-5.19/patches.armbian/arm64-dts-allwinner-h616-Add-efuse_xlate-cpu-freq-scaling.patch diff --git a/patch/kernel/archive/sunxi-5.19/patches.armbian/arm64-dts-allwinner-h616-Add-efuse_xlate-cpu-freq-scaling.patch b/patch/kernel/archive/sunxi-5.19/patches.armbian/arm64-dts-allwinner-h616-Add-efuse_xlate-cpu-freq-scaling.patch new file mode 100644 index 0000000000..8c1e73a5e3 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.19/patches.armbian/arm64-dts-allwinner-h616-Add-efuse_xlate-cpu-freq-scaling.patch @@ -0,0 +1,340 @@ +From d7cfa475141759ff8a2d082de3f275941e8e38cd Mon Sep 17 00:00:00 2001 +From: AGM1968 +Date: Fri, 27 Jan 2023 15:48:45 +0000 +Subject: [PATCH] Add-h616-efuse_xlate-cpu-freq-scaling + +Signed-off-by: AGM1968 +--- + .../dts/allwinner/sun50i-h616-cpu-opp.dtsi | 80 ++++++++++++++++ + .../allwinner/sun50i-h616-orangepi-zero2.dts | 10 +- + drivers/cpufreq/cpufreq-dt-platdev.c | 4 + + drivers/cpufreq/sun50i-cpufreq-nvmem.c | 96 ++++++++++++++----- + 4 files changed, 162 insertions(+), 28 deletions(-) + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi +new file mode 100644 +index 000000000..5ec3e5334 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi +@@ -0,0 +1,80 @@ ++//SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++//Testing version from: AGM1968@users.noreply.github.com ++//Noted: PLL_CPUX = 24 MHz*N/P (WIP) ++ ++/ { ++ cpu_opp_table: opp-table-cpu { ++ compatible = "allwinner,sun50i-h616-operating-points"; ++ nvmem-cells = <&cpu_speed_grade>; ++ opp-shared; ++ ++ opp-480000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <480000000>; ++ ++ opp-microvolt-speed0 = <820000 820000 1100000>; ++ opp-microvolt-speed1 = <880000 880000 1100000>; ++ opp-microvolt-speed2 = <880000 880000 1100000>; ++ }; ++ ++ opp-600000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <600000000>; ++ ++ opp-microvolt-speed0 = <820000 820000 1100000>; ++ opp-microvolt-speed1 = <880000 880000 1100000>; ++ opp-microvolt-speed2 = <880000 880000 1100000>; ++ }; ++ ++ opp-792000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <792000000>; ++ opp-microvolt-speed0 = <860000 860000 1100000>; ++ opp-microvolt-speed1 = <940000 940000 1100000>; ++ opp-microvolt-speed2 = <940000 940000 1100000>; ++ }; ++ ++ opp-1008000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1008000000>; ++ ++ opp-microvolt-speed0 = <900000 900000 1100000>; ++ opp-microvolt-speed1 = <1020000 1020000 1100000>; ++ opp-microvolt-speed2 = <1020000 1020000 1100000>; ++ }; ++ ++ opp-1200000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1200000000>; ++ ++ opp-microvolt-speed0 = <960000 960000 1100000>; ++ opp-microvolt-speed1 = <1100000 1100000 1100000>; ++ opp-microvolt-speed2 = <1100000 1100000 1100000>; ++ }; ++ ++ opp-1512000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1512000000>; ++ ++ opp-microvolt-speed0 = <1100000 1100000 1100000>; ++ opp-microvolt-speed1 = <1100000 1100000 1100000>; ++ opp-microvolt-speed2 = <1100000 1100000 1100000>; ++ }; ++ }; ++}; ++ ++&cpu0 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu1 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu2 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu3 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts +index 159ffe654..73ffe7f78 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts +@@ -6,6 +6,7 @@ + /dts-v1/; + + #include "sun50i-h616.dtsi" ++#include "sun50i-h616-cpu-opp.dtsi" + + #include + #include +@@ -178,14 +179,14 @@ cldo3 { + reg_dcdca: dcdca { + regulator-always-on; + regulator-min-microvolt = <810000>; +- regulator-max-microvolt = <1080000>; ++ regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpu"; + }; + + reg_dcdcc: dcdcc { + regulator-always-on; + regulator-min-microvolt = <810000>; +- regulator-max-microvolt = <1080000>; ++ regulator-max-microvolt = <990000>; + regulator-name = "vdd-gpu-sys"; + }; + +@@ -210,6 +211,11 @@ sw { + }; + }; + ++&cpu0 { ++ cpu-supply = <®_dcdca>; ++ status = "okay"; ++}; ++ + &spi0 { + status = "okay"; + +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 2c96de3f2..2ce6ebb90 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -2,6 +2,9 @@ + /* + * Copyright (C) 2016 Linaro. + * Viresh Kumar ++ * ++ * Add cpufreq nvmem for allwinner h616 SoC, known to be analagous to h6. ++ * AGM1968@users.noreply.github.com + */ + + #include +@@ -102,6 +105,7 @@ static const struct of_device_id allowlist[] __initconst = { + */ + static const struct of_device_id blocklist[] __initconst = { + { .compatible = "allwinner,sun50i-h6", }, ++ { .compatible = "allwinner,sun50i-h616", }, + + { .compatible = "arm,vexpress", }, + +diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c +index d079e5569..cca57d7ec 100644 +--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c ++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c +@@ -6,6 +6,9 @@ + * provide the OPP framework with required information. + * + * Copyright (C) 2019 Yangtao Li ++ * ++ * Add efuse_xlate to extract SoC version so that h6 and h616 can coexist. ++ * AGM1968@users.noreply.github.com + */ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +@@ -19,25 +22,63 @@ + + #define MAX_NAME_LEN 7 + +-#define NVMEM_MASK 0x7 +-#define NVMEM_SHIFT 5 ++#define SUN50I_H616_NVMEM_MASK 0x22 ++#define SUN50I_H616_NVMEM_SHIFT 5 ++#define SUN50I_H6_NVMEM_MASK 0x7 ++#define SUN50I_H6_NVMEM_SHIFT 5 ++ ++struct sunxi_cpufreq_soc_data { ++ u32 (*efuse_xlate) (void *efuse); ++}; + + static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev; + ++static u32 sun50i_h616_efuse_xlate(void *efuse) ++{ ++ u32 efuse_value = (*(u32 *)efuse >> SUN50I_H616_NVMEM_SHIFT) & ++ SUN50I_H616_NVMEM_MASK; ++ ++ /* Tested as h616 soc. Expected efuse values are 1 -3, ++ slowest to fastest */ ++ if (efuse_value >=1 && efuse_value <= 3) ++ return efuse_value - 1; ++ else ++ return 0; ++}; ++ ++static u32 sun50i_h6_efuse_xlate(void *efuse) ++{ ++ u32 efuse_value = (*(u32 *)efuse >> SUN50I_H6_NVMEM_SHIFT) & ++ SUN50I_H6_NVMEM_MASK; ++ ++ /* ++ * We treat unexpected efuse values as if the SoC was from ++ * the slowest bin. Expected efuse values are 1 -3, slowest ++ * to fastest. ++ */ ++ if (efuse_value >= 1 && efuse_value <= 3) ++ return efuse_value - 1; ++ else ++ return 0; ++ ++}; ++ + /** + * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value ++ * @soc_data: pointer to sunxi_cpufreq_soc_data context + * @versions: Set to the value parsed from efuse + * + * Returns 0 if success. + */ +-static int sun50i_cpufreq_get_efuse(u32 *versions) ++ ++static int sun50i_cpufreq_get_efuse(const struct sunxi_cpufreq_soc_data *soc_data, ++ u32 *versions) + { + struct nvmem_cell *speedbin_nvmem; + struct device_node *np; + struct device *cpu_dev; +- u32 *speedbin, efuse_value; ++ u32 *speedbin; + size_t len; +- int ret; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) +@@ -45,11 +86,11 @@ static int sun50i_cpufreq_get_efuse(u32 *versions) + + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev); + if (!np) +- return -ENOENT; ++ return -ENOENT; + +- ret = of_device_is_compatible(np, +- "allwinner,sun50i-h6-operating-points"); +- if (!ret) { ++ if (of_device_is_compatible(np, "allwinner,sun50i-h6-operating-points")) {} ++ else if (of_device_is_compatible(np, "allwinner,sun50i-h616-operating-points")) {} ++ else { + of_node_put(np); + return -ENOENT; + } +@@ -68,17 +109,7 @@ static int sun50i_cpufreq_get_efuse(u32 *versions) + if (IS_ERR(speedbin)) + return PTR_ERR(speedbin); + +- efuse_value = (*speedbin >> NVMEM_SHIFT) & NVMEM_MASK; +- +- /* +- * We treat unexpected efuse values as if the SoC was from +- * the slowest bin. Expected efuse values are 1-3, slowest +- * to fastest. +- */ +- if (efuse_value >= 1 && efuse_value <= 3) +- *versions = efuse_value - 1; +- else +- *versions = 0; ++ *versions = soc_data->efuse_xlate(speedbin); + + kfree(speedbin); + return 0; +@@ -86,18 +117,23 @@ static int sun50i_cpufreq_get_efuse(u32 *versions) + + static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) + { +- struct opp_table **opp_tables; ++ const struct of_device_id *match; ++ struct opp_table **opp_tables; + char name[MAX_NAME_LEN]; + unsigned int cpu; + u32 speed = 0; + int ret; + ++ match = dev_get_platdata(&pdev->dev); ++ if (!match) ++ return -EINVAL; ++ + opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables), + GFP_KERNEL); + if (!opp_tables) + return -ENOMEM; + +- ret = sun50i_cpufreq_get_efuse(&speed); ++ ret = sun50i_cpufreq_get_efuse(match->data, &speed); + if (ret) { + kfree(opp_tables); + return ret; +@@ -166,8 +202,17 @@ static struct platform_driver sun50i_cpufreq_driver = { + }, + }; + ++static const struct sunxi_cpufreq_soc_data sun50i_h616_data = { ++ .efuse_xlate = sun50i_h616_efuse_xlate, ++}; ++ ++static const struct sunxi_cpufreq_soc_data sun50i_h6_data = { ++ .efuse_xlate = sun50i_h6_efuse_xlate, ++}; ++ + static const struct of_device_id sun50i_cpufreq_match_list[] = { +- { .compatible = "allwinner,sun50i-h6" }, ++ { .compatible = "allwinner,sun50i-h6", .data = &sun50i_h6_data }, ++ { .compatible = "allwinner,sun50i-h616", .data = &sun50i_h616_data }, + {} + }; + MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list); +@@ -202,9 +247,8 @@ static int __init sun50i_cpufreq_init(void) + if (unlikely(ret < 0)) + return ret; + +- sun50i_cpufreq_pdev = +- platform_device_register_simple("sun50i-cpufreq-nvmem", +- -1, NULL, 0); ++ sun50i_cpufreq_pdev = platform_device_register_data(NULL, ++ "sun50i-cpufreq-nvmem", -1, match, sizeof(*match)); + ret = PTR_ERR_OR_ZERO(sun50i_cpufreq_pdev); + if (ret == 0) + return 0; +-- +Created with Armbian build tools https://github.com/armbian/build diff --git a/patch/kernel/archive/sunxi-5.19/series.armbian b/patch/kernel/archive/sunxi-5.19/series.armbian index 4f04d1d07a..8d201c88a8 100644 --- a/patch/kernel/archive/sunxi-5.19/series.armbian +++ b/patch/kernel/archive/sunxi-5.19/series.armbian @@ -140,6 +140,7 @@ patches.armbian/arm-dts-sun7i-a20-olimex-som-204-evb-olinuxino-micro-decrease-d.patch patches.armbian/arm-dts-sun8i-h3-add-thermal-zones.patch patches.armbian/arm64-dts-allwinner-h616-Add-device-node-for-SID.patch + patches.armbian/arm64-dts-allwinner-h616-Add-efuse_xlate-cpu-freq-scaling.patch patches.armbian/arm64-dts-allwinner-h616-Add-thermal-sensor-and-thermal-zones.patch patches.armbian/arm64-dts-sun50i-a64-olinuxino-add-boards.patch patches.armbian/arm64-dts-sun50i-a64-olinuxino-emmc-enable-bluetooth.patch diff --git a/patch/kernel/archive/sunxi-5.19/series.conf b/patch/kernel/archive/sunxi-5.19/series.conf index 510c80a354..afbcf06601 100644 --- a/patch/kernel/archive/sunxi-5.19/series.conf +++ b/patch/kernel/archive/sunxi-5.19/series.conf @@ -588,6 +588,7 @@ patches.armbian/arm-dts-sun7i-a20-olimex-som-204-evb-olinuxino-micro-decrease-d.patch patches.armbian/arm-dts-sun8i-h3-add-thermal-zones.patch patches.armbian/arm64-dts-allwinner-h616-Add-device-node-for-SID.patch + patches.armbian/arm64-dta-allwinner-h616-Add-efuse_xlate-cpu-freq-scaling.patch patches.armbian/arm64-dts-allwinner-h616-Add-thermal-sensor-and-thermal-zones.patch patches.armbian/arm64-dts-sun50i-a64-olinuxino-add-boards.patch patches.armbian/arm64-dts-sun50i-a64-olinuxino-emmc-enable-bluetooth.patch