From c5be5a8537fd6ef3d8c515573dc6f06dabbf66e7 Mon Sep 17 00:00:00 2001 From: Patrick Yavitz Date: Tue, 16 Jul 2024 14:03:19 -0400 Subject: [PATCH] SpacemiT: BananaPi F3: `update to BL v1.0.8` Legacy: use TAG instead of BRANCH (gives us more control) Current: update DTS files Current: add needed patches up to v1.0.8 Fixup bluetooth node and disable by default (half broke anyway) Misc fixups to bananapif3.wip and spacemit.conf file Signed-off-by: Patrick Yavitz --- config/boards/bananapif3.wip | 2 - config/sources/families/spacemit.conf | 4 +- ...luetooth-btrtl-support-to-RTL8852BS.patch} | 0 ...ch => 055-add-minimal-hwmon-support.patch} | 0 ...1.0.3.patch => 057-update-to-v1.0.3.patch} | 0 ...1.0.5.patch => 058-update-to-v1.0.5.patch} | 0 .../spacemit-6.1/059-update-to-v1.0.7.patch | 2610 +++++++++++++++++ .../spacemit-6.1/060-update-to-v1.0.8.patch | 443 +++ .../061-REVERT-fixes-for-dtb-mapping.patch | 248 -- .../spacemit-6.1/dt/k1-bananapi-f3.dts | 7 +- .../dt/k1-x-camera-reserved-mm.dtsi | 17 + .../spacemit-6.1/dt/k1-x-camera-sdk.dtsi | 20 +- .../archive/spacemit-6.1/dt/k1-x-efuse.dtsi | 52 + .../kernel/archive/spacemit-6.1/dt/k1-x.dtsi | 289 +- .../archive/spacemit-6.1/dt/k1-x_deb1.dts | 44 +- .../spacemit-6.1/dt/k1-x_opp_table.dtsi | 110 + .../spacemit-6.1/dt/m1-x_opp_table.dtsi | 234 ++ .../spacemit-6.1/dt/spacemit-scmi.dtsi | 76 + .../spacemit-legacy-6.1/dt/k1-bananapi-f3.dts | 7 +- 19 files changed, 3694 insertions(+), 469 deletions(-) rename patch/kernel/archive/spacemit-6.1/{500-board-bpif3-Add-Bluetooth-btrtl-support-to-RTL8852BS.patch => 054-board-bpif3-Add-Bluetooth-btrtl-support-to-RTL8852BS.patch} (100%) rename patch/kernel/archive/spacemit-6.1/{101-add-minimal-hwmon-support.patch => 055-add-minimal-hwmon-support.patch} (100%) rename patch/kernel/archive/spacemit-6.1/{060-update-to-v1.0.3.patch => 057-update-to-v1.0.3.patch} (100%) rename patch/kernel/archive/spacemit-6.1/{070-update-to-v1.0.5.patch => 058-update-to-v1.0.5.patch} (100%) create mode 100644 patch/kernel/archive/spacemit-6.1/059-update-to-v1.0.7.patch create mode 100644 patch/kernel/archive/spacemit-6.1/060-update-to-v1.0.8.patch delete mode 100644 patch/kernel/archive/spacemit-6.1/061-REVERT-fixes-for-dtb-mapping.patch create mode 100644 patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-reserved-mm.dtsi create mode 100644 patch/kernel/archive/spacemit-6.1/dt/k1-x-efuse.dtsi create mode 100644 patch/kernel/archive/spacemit-6.1/dt/k1-x_opp_table.dtsi create mode 100644 patch/kernel/archive/spacemit-6.1/dt/m1-x_opp_table.dtsi create mode 100644 patch/kernel/archive/spacemit-6.1/dt/spacemit-scmi.dtsi diff --git a/config/boards/bananapif3.wip b/config/boards/bananapif3.wip index 788875388971..3159e9f4e256 100644 --- a/config/boards/bananapif3.wip +++ b/config/boards/bananapif3.wip @@ -28,8 +28,6 @@ function post_family_tweaks_bsp__bananapi_f3_extras() { display_alert "$BOARD" "Force load wireless" "info" - run_host_command_logged mkdir -pv "${destination}"/etc/modprobe.d - run_host_command_logged echo "options 8852bs rtw_drv_log_level=0 rtw_phl_log_level=0" > "${destination}"/etc/modprobe.d/50-8852bs.conf run_host_command_logged mkdir -pv "${destination}"/etc/modules-load.d run_host_command_logged echo "8852bs" > "${destination}"/etc/modules-load.d/${BOARD}.conf } diff --git a/config/sources/families/spacemit.conf b/config/sources/families/spacemit.conf index d4e994afc23c..65341176ad38 100644 --- a/config/sources/families/spacemit.conf +++ b/config/sources/families/spacemit.conf @@ -38,7 +38,7 @@ case "${BRANCH}" in legacy) # Kernel declare -g KERNELSOURCE='https://gitee.com/bianbu-linux/linux-6.1.git' - declare -g KERNELBRANCH='branch:bl-v1.0.y' + declare -g KERNELBRANCH='tag:v1.0.8' declare -g KERNEL_MAJOR_MINOR="6.1" declare -g LINUXCONFIG="linux-${LINUXFAMILY}-${BRANCH}" declare -g KERNELPATCHDIR="${LINUXFAMILY}-legacy-${KERNEL_MAJOR_MINOR}" # Needed as long as both legacy and current are 6.1 kernels @@ -65,7 +65,7 @@ function custom_kernel_config__spacemit_k1_firmware() { } pre_prepare_partitions() { - declare -g OFFSET="100" + declare -g OFFSET="4" declare -g IMAGE_PARTITION_TABLE="msdos" } diff --git a/patch/kernel/archive/spacemit-6.1/500-board-bpif3-Add-Bluetooth-btrtl-support-to-RTL8852BS.patch b/patch/kernel/archive/spacemit-6.1/054-board-bpif3-Add-Bluetooth-btrtl-support-to-RTL8852BS.patch similarity index 100% rename from patch/kernel/archive/spacemit-6.1/500-board-bpif3-Add-Bluetooth-btrtl-support-to-RTL8852BS.patch rename to patch/kernel/archive/spacemit-6.1/054-board-bpif3-Add-Bluetooth-btrtl-support-to-RTL8852BS.patch diff --git a/patch/kernel/archive/spacemit-6.1/101-add-minimal-hwmon-support.patch b/patch/kernel/archive/spacemit-6.1/055-add-minimal-hwmon-support.patch similarity index 100% rename from patch/kernel/archive/spacemit-6.1/101-add-minimal-hwmon-support.patch rename to patch/kernel/archive/spacemit-6.1/055-add-minimal-hwmon-support.patch diff --git a/patch/kernel/archive/spacemit-6.1/060-update-to-v1.0.3.patch b/patch/kernel/archive/spacemit-6.1/057-update-to-v1.0.3.patch similarity index 100% rename from patch/kernel/archive/spacemit-6.1/060-update-to-v1.0.3.patch rename to patch/kernel/archive/spacemit-6.1/057-update-to-v1.0.3.patch diff --git a/patch/kernel/archive/spacemit-6.1/070-update-to-v1.0.5.patch b/patch/kernel/archive/spacemit-6.1/058-update-to-v1.0.5.patch similarity index 100% rename from patch/kernel/archive/spacemit-6.1/070-update-to-v1.0.5.patch rename to patch/kernel/archive/spacemit-6.1/058-update-to-v1.0.5.patch diff --git a/patch/kernel/archive/spacemit-6.1/059-update-to-v1.0.7.patch b/patch/kernel/archive/spacemit-6.1/059-update-to-v1.0.7.patch new file mode 100644 index 000000000000..ddec30baee2c --- /dev/null +++ b/patch/kernel/archive/spacemit-6.1/059-update-to-v1.0.7.patch @@ -0,0 +1,2610 @@ +From 5f0bb67fb85257a83e59ebdbf57f378b1383e2d8 Mon Sep 17 00:00:00 2001 +From: Patrick Yavitz +Date: Thu, 11 Jul 2024 07:10:18 -0400 +Subject: [PATCH] update to v1.0.7 + +Signed-off-by: James Deng +Signed-off-by: Patrick Yavitz +--- + drivers/clk/spacemit/ccu-spacemit-k1x.c | 5 +- + drivers/clk/spacemit/ccu_pll.c | 11 +- + drivers/cpufreq/cpufreq-dt.c | 19 + + drivers/cpufreq/spacemit-cpufreq.c | 375 +++++++++++++++--- + drivers/crypto/spacemit/spacemit_ce_engine.c | 2 +- + drivers/gpio/gpio-k1x.c | 6 - + drivers/gpu/drm/spacemit/lt8911exb.c | 15 +- + .../spacemit/camera/cam_sensor/cam_sensor.c | 173 ++++++-- + .../spacemit/camera/cam_sensor/cam_sensor.h | 4 + + drivers/mtd/spi-nor/Makefile | 1 + + drivers/mtd/spi-nor/core.c | 1 + + drivers/mtd/spi-nor/core.h | 1 + + drivers/mtd/spi-nor/fmsh.c | 20 + + drivers/nvmem/Kconfig | 10 + + drivers/nvmem/Makefile | 2 + + drivers/nvmem/spacemit-efuse.c | 172 ++++++++ + drivers/opp/core.c | 113 ++++++ + drivers/pinctrl/pinctrl-single.c | 124 +++++- + drivers/soc/spacemit/Kconfig | 9 + + drivers/soc/spacemit/Makefile | 11 +- + .../soc/spacemit/pm_domain/k1x-pm_domain.c | 7 + + .../soc/spacemit/spacemit-rf/spacemit-wlan.c | 25 +- + drivers/soc/spacemit/spacemit-socinfo.c | 205 ++++++++++ + drivers/usb/dwc3/dwc3-spacemit.c | 98 ++++- + drivers/usb/host/ehci-k1x-ci.c | 188 +++++++-- + include/linux/pm_opp.h | 3 + + sound/soc/codecs/es8326.c | 76 +++- + 31 files changed, 1750 insertions(+), 304 deletions(-) + create mode 100644 drivers/mtd/spi-nor/fmsh.c + create mode 100644 drivers/nvmem/spacemit-efuse.c + create mode 100644 drivers/soc/spacemit/spacemit-socinfo.c + +diff --git a/drivers/clk/spacemit/ccu-spacemit-k1x.c b/drivers/clk/spacemit/ccu-spacemit-k1x.c +index cd8176a5ea79..05e6c40c8913 100644 +--- a/drivers/clk/spacemit/ccu-spacemit-k1x.c ++++ b/drivers/clk/spacemit/ccu-spacemit-k1x.c +@@ -186,6 +186,9 @@ static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { + }; + + static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { ++ PLL_RATE(1600000000UL, 0x61, 0xcd, 0x50, 0x00, 0x43, 0xeaaaab), ++ PLL_RATE(1800000000UL, 0x61, 0xcd, 0x50, 0x00, 0x4b, 0x000000), ++ PLL_RATE(2000000000UL, 0x62, 0xdd, 0x50, 0x00, 0x2a, 0xeaaaab), + PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000), + PLL_RATE(3200000000UL, 0x67, 0xdd, 0x50, 0x00, 0x43, 0xeaaaab), + PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd), +@@ -1124,7 +1127,7 @@ static SPACEMIT_CCU_GATE_NO_PARENT(rcan_bus_clk, "rcan_bus_clk", NULL, + BIT(2), BIT(2), 0x0, 0); + //rcpu2 + static const char *rpwm_parent_names[] = { +- "pll1_aud_245p7", "pll1_aud_24p5" ++ "pll1_aud_24p5", "pll1_aud_245p7" + }; + static SPACEMIT_CCU_DIV_MUX_GATE(rpwm_clk, "rpwm_clk", rpwm_parent_names, + BASE_TYPE_RCPU2, RCPU2_PWM_CLK_RST, +diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c +index 391498a28457..ecf5f265e219 100644 +--- a/drivers/clk/spacemit/ccu_pll.c ++++ b/drivers/clk/spacemit/ccu_pll.c +@@ -186,11 +186,11 @@ static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, + union pllx_swcr1 swcr1; + union pllx_swcr3 swcr3; + bool found = false; ++ bool pll_enabled = false; + + if (ccu_pll_is_enabled(hw)) { +- pr_err("%s %s is enabled, ignore the setrate!\n", +- __func__, __clk_get_name(hw->clk)); +- return 0; ++ pll_enabled = true; ++ ccu_pll_disable(hw); + } + + old_rate = __get_vco_freq(hw); +@@ -213,6 +213,8 @@ static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, + BUG_ON(!found); + } else { + pr_err("don't find freq table for pll\n"); ++ if (pll_enabled) ++ ccu_pll_enable(hw); + return -EINVAL; + } + +@@ -232,6 +234,9 @@ static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, + + spin_unlock_irqrestore(p->common.lock, flags); + ++ if (pll_enabled) ++ ccu_pll_enable(hw); ++ + pr_debug("%s %s rate %lu->%lu!\n", __func__, + __clk_get_name(hw->clk), old_rate, new_rate); + return 0; +diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c +index 4aec4b2a5225..957d2c2a58af 100644 +--- a/drivers/cpufreq/cpufreq-dt.c ++++ b/drivers/cpufreq/cpufreq-dt.c +@@ -42,6 +42,7 @@ static struct freq_attr *cpufreq_dt_attr[] = { + NULL, + }; + ++#ifndef CONFIG_SOC_SPACEMIT + static struct private_data *cpufreq_dt_find_data(int cpu) + { + struct private_data *priv; +@@ -53,6 +54,24 @@ static struct private_data *cpufreq_dt_find_data(int cpu) + + return NULL; + } ++#else ++struct private_data *cpufreq_dt_find_data(int cpu) ++{ ++ struct private_data *priv; ++ ++ list_for_each_entry(priv, &priv_list, node) { ++ if (cpumask_test_cpu(cpu, priv->cpus)) ++ return priv; ++ } ++ ++ return NULL; ++} ++ ++void cpufreq_dt_add_data(struct private_data *priv) ++{ ++ list_add(&priv->node, &priv_list); ++} ++#endif + + static int set_target(struct cpufreq_policy *policy, unsigned int index) + { +diff --git a/drivers/cpufreq/spacemit-cpufreq.c b/drivers/cpufreq/spacemit-cpufreq.c +index 5fd734cffa0a..52d40d7f25fe 100644 +--- a/drivers/cpufreq/spacemit-cpufreq.c ++++ b/drivers/cpufreq/spacemit-cpufreq.c +@@ -8,19 +8,25 @@ + #include + #include + #include ++#include + #include + #include ++#include ++#include ++#include ++#include + #include "../opp/opp.h" ++#include "cpufreq-dt.h" + +-struct per_device_qos { +- struct regulator *regulator; +- struct freq_qos_request qos; +-}; ++struct private_data { ++ struct list_head node; + +-static DEFINE_MUTEX(regulator_mutex); +-static struct notifier_block vol_constraints_notifier; +-static struct freq_constraints vol_constraints; +-static struct per_device_qos *vol_qos[CONFIG_NR_CPUS]; ++ cpumask_var_t cpus; ++ struct device *cpu_dev; ++ struct cpufreq_frequency_table *freq_table; ++ bool have_static_opps; ++ int opp_token; ++}; + + #ifdef CONFIG_CPU_HOTPLUG_THERMAL + struct thermal_cooling_device **ghotplug_cooling; +@@ -28,24 +34,22 @@ extern struct thermal_cooling_device ** + of_hotplug_cooling_register(struct cpufreq_policy *policy); + #endif + +-static int spacemit_vol_qos_notifier_call(struct notifier_block *nb, unsigned long action, void *data) +-{ +- regulator_set_voltage(vol_qos[0]->regulator, action * 1000, action * 1000); +- +- return 0; +-} ++#define TURBO_FREQUENCY (1600000000) ++#define STABLE_FREQUENCY (1200000000) ++#define FILTER_POINTS (140) ++#define FREQ_TABLE_0 (0) ++#define FREQ_TABLE_1 (1) + + static int spacemit_policy_notifier(struct notifier_block *nb, + unsigned long event, void *data) + { +- int cpu, err; ++ int cpu; + u64 rates; + static int cci_init; + struct clk *cci_clk; + struct device *cpu_dev; + struct cpufreq_policy *policy = data; + struct opp_table *opp_table; +- const char *strings; + + cpu = cpumask_first(policy->related_cpus); + cpu_dev = get_cpu_device(cpu); +@@ -57,32 +61,17 @@ static int spacemit_policy_notifier(struct notifier_block *nb, + clk_set_rate(cci_clk, rates); + clk_put(cci_clk); + cci_init = 1; +- } +- +- vol_qos[cpu] = devm_kzalloc(cpu_dev, sizeof(struct per_device_qos), GFP_KERNEL); +- if (!vol_qos[cpu]) +- return -ENOMEM; +- +- err = of_property_read_string_array(cpu_dev->of_node, "vin-supply-names", +- &strings, 1); +- if (err >= 0) { +- vol_qos[cpu]->regulator = devm_regulator_get(cpu_dev, strings); +- if (IS_ERR(vol_qos[cpu]->regulator)) { +- pr_err("regulator supply %s, get failed\n", strings); +- return PTR_ERR(vol_qos[cpu]->regulator); +- } + +- err = regulator_enable(vol_qos[cpu]->regulator); ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ if (policy->clk) ++ clk_put(policy->clk); + +- } else { +- /* using the same regulator */ +- vol_qos[cpu]->regulator = vol_qos[0]->regulator; ++ /* cover the policy->clk & opp_table->clk which has been set before */ ++ policy->clk = opp_table->clks[0]; ++ opp_table->clk = opp_table->clks[0]; ++#endif + } + +- if (vol_qos[cpu]->regulator) +- freq_qos_add_request(&vol_constraints, &vol_qos[cpu]->qos, FREQ_QOS_MIN, +- regulator_get_voltage(vol_qos[cpu]->regulator) / 1000); +- + #ifdef CONFIG_CPU_HOTPLUG_THERMAL + ghotplug_cooling = of_hotplug_cooling_register(policy); + if (!ghotplug_cooling) { +@@ -102,9 +91,10 @@ static int spacemit_processor_notifier(struct notifier_block *nb, + struct cpufreq_policy *policy = ( struct cpufreq_policy *)freqs->policy; + struct opp_table *opp_table; + struct device_node *np; +- struct clk *tcm_clk, *ace_clk; ++ struct clk *tcm_clk, *ace0_clk, *ace1_clk, *pll_clk; + u64 rates; + u32 microvol; ++ int i; + + cpu = cpumask_first(policy->related_cpus); + cpu_dev = get_cpu_device(cpu); +@@ -120,31 +110,42 @@ static int spacemit_processor_notifier(struct notifier_block *nb, + + /* get the tcm/ace clk handler */ + tcm_clk = of_clk_get_by_name(opp_table->np, "tcm"); +- ace_clk = of_clk_get_by_name(opp_table->np, "ace"); ++ ace0_clk = of_clk_get_by_name(opp_table->np, "ace0"); ++ ace1_clk = of_clk_get_by_name(opp_table->np, "ace1"); ++ pll_clk = of_clk_get_by_name(opp_table->np, "pll3"); + + if (event == CPUFREQ_PRECHANGE) { +- +- mutex_lock(®ulator_mutex); +- +- if (freqs->new > freqs->old) { +- /* increase voltage first */ +- if (vol_qos[cpu]->regulator) +- freq_qos_update_request(&vol_qos[cpu]->qos, microvol / 1000); +- } +- + /** + * change the tcm/ace's frequency first. + * binary division is safe + */ +- if (!IS_ERR(ace_clk)) { +- clk_set_rate(ace_clk, clk_get_rate(clk_get_parent(ace_clk)) / 2); +- clk_put(ace_clk); ++ if (!IS_ERR(ace0_clk)) { ++ clk_set_rate(ace0_clk, clk_get_rate(clk_get_parent(ace0_clk)) / 2); ++ clk_put(ace0_clk); ++ } ++ ++ if (!IS_ERR(ace1_clk)) { ++ clk_set_rate(ace1_clk, clk_get_rate(clk_get_parent(ace1_clk)) / 2); ++ clk_put(ace1_clk); + } + + if (!IS_ERR(tcm_clk)) { + clk_set_rate(tcm_clk, clk_get_rate(clk_get_parent(tcm_clk)) / 2); + clk_put(tcm_clk); + } ++ ++ if (freqs->new * 1000 >= TURBO_FREQUENCY) { ++ if (freqs->old * 1000 >= TURBO_FREQUENCY) { ++ for (i = 0; i < opp_table->clk_count; ++i) { ++ clk_set_rate(opp_table->clks[i], STABLE_FREQUENCY); ++ } ++ } ++ ++ /* change the frequency of pll3 first */ ++ clk_set_rate(pll_clk, freqs->new * 1000); ++ clk_put(pll_clk); ++ } ++ + } + + if (event == CPUFREQ_POSTCHANGE) { +@@ -158,22 +159,23 @@ static int spacemit_processor_notifier(struct notifier_block *nb, + clk_put(tcm_clk); + } + +- if (!IS_ERR(ace_clk)) { +- clk_get_rate(clk_get_parent(ace_clk)); ++ if (!IS_ERR(ace0_clk)) { ++ clk_get_rate(clk_get_parent(ace0_clk)); + /* get the ace-hz */ +- of_property_read_u64_array(np, "ace-hz", &rates, 1); ++ of_property_read_u64_array(np, "ace0-hz", &rates, 1); + /* then set rate */ +- clk_set_rate(ace_clk, rates); +- clk_put(ace_clk); ++ clk_set_rate(ace0_clk, rates); ++ clk_put(ace0_clk); + } + +- if (freqs->new < freqs->old) { +- /* decrease the voltage last */ +- if (vol_qos[cpu]->regulator) +- freq_qos_update_request(&vol_qos[cpu]->qos, microvol / 1000); ++ if (!IS_ERR(ace1_clk)) { ++ clk_get_rate(clk_get_parent(ace1_clk)); ++ /* get the ace-hz */ ++ of_property_read_u64_array(np, "ace1-hz", &rates, 1); ++ /* then set rate */ ++ clk_set_rate(ace1_clk, rates); ++ clk_put(ace1_clk); + } +- +- mutex_unlock(®ulator_mutex); + } + + dev_pm_opp_put_opp_table(opp_table); +@@ -189,6 +191,249 @@ static struct notifier_block spacemit_policy_notifier_block = { + .notifier_call = spacemit_policy_notifier, + }; + ++static int _dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, ++ struct cpumask *cpumask, int indexs) ++{ ++ struct device_node *np, *tmp_np, *cpu_np; ++ int cpu, ret = 0; ++ ++ /* Get OPP descriptor node */ ++ np = of_parse_phandle(cpu_dev->of_node, "operating-points-v2", indexs); ++ if (!np) { ++ dev_dbg(cpu_dev, "%s: Couldn't find opp node.\n", __func__); ++ return -ENOENT; ++ } ++ ++ cpumask_set_cpu(cpu_dev->id, cpumask); ++ ++ /* OPPs are shared ? */ ++ if (!of_property_read_bool(np, "opp-shared")) ++ goto put_cpu_node; ++ ++ for_each_possible_cpu(cpu) { ++ if (cpu == cpu_dev->id) ++ continue; ++ ++ cpu_np = of_cpu_device_node_get(cpu); ++ if (!cpu_np) { ++ dev_err(cpu_dev, "%s: failed to get cpu%d node\n", ++ __func__, cpu); ++ ret = -ENOENT; ++ goto put_cpu_node; ++ } ++ ++ /* Get OPP descriptor node */ ++ tmp_np = of_parse_phandle(cpu_np, "operating-points-v2", indexs); ++ of_node_put(cpu_np); ++ if (!tmp_np) { ++ pr_err("%pOF: Couldn't find opp node\n", cpu_np); ++ ret = -ENOENT; ++ goto put_cpu_node; ++ } ++ ++ /* CPUs are sharing opp node */ ++ if (np == tmp_np) ++ cpumask_set_cpu(cpu, cpumask); ++ ++ of_node_put(tmp_np); ++ } ++ ++put_cpu_node: ++ of_node_put(np); ++ return ret; ++} ++ ++/** ++ * dev_pm_opp_of_cpumask_add_table() - Adds OPP table for @cpumask ++ * @cpumask: cpumask for which OPP table needs to be added. ++ * ++ * This adds the OPP tables for CPUs present in the @cpumask. ++ */ ++static int _dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask, int indexs) ++{ ++ struct device *cpu_dev; ++ int cpu, ret; ++ ++ if (WARN_ON(cpumask_empty(cpumask))) ++ return -ENODEV; ++ ++ for_each_cpu(cpu, cpumask) { ++ cpu_dev = get_cpu_device(cpu); ++ if (!cpu_dev) { ++ pr_err("%s: failed to get cpu%d device\n", __func__, ++ cpu); ++ ret = -ENODEV; ++ goto remove_table; ++ } ++ ++ ret = dev_pm_opp_of_add_table_indexed(cpu_dev, indexs); ++ if (ret) { ++ /* ++ * OPP may get registered dynamically, don't print error ++ * message here. ++ */ ++ pr_debug("%s: couldn't find opp table for cpu:%d, %d\n", ++ __func__, cpu, ret); ++ ++ goto remove_table; ++ } ++ } ++ ++ return 0; ++ ++remove_table: ++ /* Free all other OPPs */ ++ _dev_pm_opp_cpumask_remove_table(cpumask, cpu); ++ ++ return ret; ++} ++ ++extern struct private_data *cpufreq_dt_find_data(int cpu); ++extern void cpufreq_dt_add_data(struct private_data *priv); ++ ++static int spacemit_dt_cpufreq_pre_early_init(struct device *dev, int cpu, int indexs) ++{ ++ struct private_data *priv; ++ struct device *cpu_dev; ++ const char *reg_name[] = { "clst", NULL }; ++ const char *clk_name[] = { "cls0", "cls1", NULL }; ++ struct dev_pm_opp_config config = { ++ .regulator_names = reg_name, ++ .clk_names = clk_name, ++ .config_clks = dev_pm_opp_config_clks_simple, ++ }; ++ int ret; ++ ++ /* Check if this CPU is already covered by some other policy */ ++ if (cpufreq_dt_find_data(cpu)) ++ return 0; ++ ++ cpu_dev = get_cpu_device(cpu); ++ if (!cpu_dev) ++ return -EPROBE_DEFER; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL)) ++ return -ENOMEM; ++ ++ cpumask_set_cpu(cpu, priv->cpus); ++ priv->cpu_dev = cpu_dev; ++ ++ /* ++ * OPP layer will be taking care of regulators now, but it needs to know ++ * the name of the regulator first. ++ */ ++ priv->opp_token = dev_pm_opp_set_config_indexed(cpu_dev, &config, indexs); ++ if (priv->opp_token < 0) { ++ ret = dev_err_probe(cpu_dev, priv->opp_token, ++ "failed to set regulators\n"); ++ goto free_cpumask; ++ } ++ ++ /* Get OPP-sharing information from "operating-points-v2" bindings */ ++ ret = _dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->cpus, indexs); ++ if (ret) ++ goto out; ++ ++ /* ++ * Initialize OPP tables for all priv->cpus. They will be shared by ++ * all CPUs which have marked their CPUs shared with OPP bindings. ++ * ++ * For platforms not using operating-points-v2 bindings, we do this ++ * before updating priv->cpus. Otherwise, we will end up creating ++ * duplicate OPPs for the CPUs. ++ * ++ * OPPs might be populated at runtime, don't fail for error here unless ++ * it is -EPROBE_DEFER. ++ */ ++ ret = _dev_pm_opp_of_cpumask_add_table(priv->cpus, indexs); ++ if (!ret) { ++ priv->have_static_opps = true; ++ } else if (ret == -EPROBE_DEFER) { ++ goto out; ++ } ++ ++ /* ++ * The OPP table must be initialized, statically or dynamically, by this ++ * point. ++ */ ++ ret = dev_pm_opp_get_opp_count(cpu_dev); ++ if (ret <= 0) { ++ dev_err(cpu_dev, "OPP table can't be empty\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &priv->freq_table); ++ if (ret) { ++ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); ++ goto out; ++ } ++ ++ cpufreq_dt_add_data(priv); ++ ++ return 0; ++ ++out: ++ if (priv->have_static_opps) ++ dev_pm_opp_of_cpumask_remove_table(priv->cpus); ++ dev_pm_opp_put_regulators(priv->opp_token); ++free_cpumask: ++ free_cpumask_var(priv->cpus); ++ return ret; ++} ++ ++static int spacemit_dt_cpufreq_pre_probe(struct platform_device *pdev) ++{ ++ int cpu; ++ struct device_node *cpus; ++ u32 prop = 0; ++ ++ if (strncmp(pdev->name, "cpufreq-dt", 10) != 0) ++ return 0; ++ ++ cpus = of_find_node_by_path("/cpus"); ++ if (!cpus || of_property_read_u32(cpus, "svt-dro", &prop)) { ++ pr_info("Spacemit Platform with no 'svt-dro' in DTS, using defualt frequency Table0\n"); ++ } ++ ++ for_each_possible_cpu(cpu) { ++ spacemit_dt_cpufreq_pre_early_init(&pdev->dev, cpu, prop >= FILTER_POINTS ? FREQ_TABLE_1 : FREQ_TABLE_0); ++ } ++ ++ return 0; ++} ++ ++static int __device_notifier_call(struct notifier_block *nb, ++ unsigned long event, void *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ ++ switch (event) { ++ case BUS_NOTIFY_REMOVED_DEVICE: ++ break; ++ case BUS_NOTIFY_UNBOUND_DRIVER: ++ break; ++ case BUS_NOTIFY_BIND_DRIVER: ++ /* here */ ++ spacemit_dt_cpufreq_pre_probe(pdev); ++ break; ++ case BUS_NOTIFY_ADD_DEVICE: ++ break; ++ default: ++ break; ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block spacemit_platform_nb = { ++ .notifier_call = __device_notifier_call, ++}; ++ + static int __init spacemit_processor_driver_init(void) + { + int ret; +@@ -205,9 +450,7 @@ static int __init spacemit_processor_driver_init(void) + return -EINVAL; + } + +- vol_constraints_notifier.notifier_call = spacemit_vol_qos_notifier_call; +- freq_constraints_init(&vol_constraints); +- freq_qos_add_notifier(&vol_constraints, FREQ_QOS_MIN, &vol_constraints_notifier); ++ bus_register_notifier(&platform_bus_type, &spacemit_platform_nb); + + return 0; + } +diff --git a/drivers/crypto/spacemit/spacemit_ce_engine.c b/drivers/crypto/spacemit/spacemit_ce_engine.c +index 0c3f78cf4b0d..8623eb4843dd 100644 +--- a/drivers/crypto/spacemit/spacemit_ce_engine.c ++++ b/drivers/crypto/spacemit/spacemit_ce_engine.c +@@ -1741,7 +1741,7 @@ static int crypto_engine_probe(struct platform_device *pdev) + return PTR_ERR(ctrl->clk); + clk_prepare_enable(ctrl->clk); + +- ctrl->reset = devm_reset_control_get_optional(&pdev->dev, NULL); ++ ctrl->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL); + if(IS_ERR(ctrl->reset)) + return PTR_ERR(ctrl->reset); + reset_control_deassert(ctrl->reset); +diff --git a/drivers/gpio/gpio-k1x.c b/drivers/gpio/gpio-k1x.c +index 185e2298fee2..d4609f679fed 100644 +--- a/drivers/gpio/gpio-k1x.c ++++ b/drivers/gpio/gpio-k1x.c +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + + #define GPLR 0x0 + #define GPDR 0xc +@@ -393,11 +392,6 @@ static int k1x_gpio_probe(struct platform_device *pdev) + goto err; + } + +-#ifdef CONFIG_PM +- dev_pm_set_wake_irq(&pdev->dev, irq); +- device_init_wakeup(&pdev->dev, true); +-#endif +- + gpiochip_add(&k1x_chip->chip); + + /* clear all GPIO edge detects */ +diff --git a/drivers/gpu/drm/spacemit/lt8911exb.c b/drivers/gpu/drm/spacemit/lt8911exb.c +index 143048ad3548..640ff46a90b2 100644 +--- a/drivers/gpu/drm/spacemit/lt8911exb.c ++++ b/drivers/gpu/drm/spacemit/lt8911exb.c +@@ -1153,10 +1153,6 @@ static int lt8911exb_panel_enable(struct drm_panel *panel) + + DRM_INFO("%s()\n", __func__); + +- gpiod_direction_output(lt8911exb->enable_gpio, 1); +- gpiod_direction_output(lt8911exb->standby_gpio, 1); +- usleep_range(50*1000, 100*1000); //100ms +- + schedule_delayed_work(<8911exb->init_work, + msecs_to_jiffies(500)); + lt8911exb->init_work_pending = true; +@@ -1171,10 +1167,11 @@ static int lt8911exb_panel_disable(struct drm_panel *panel) + DRM_INFO("%s()\n", __func__); + + gpiod_direction_output(lt8911exb->bl_gpio, 0); +- gpiod_direction_output(lt8911exb->standby_gpio, 0); + gpiod_direction_output(lt8911exb->enable_gpio, 0); + usleep_range(50*1000, 100*1000); //100ms + ++ gpiod_direction_output(lt8911exb->standby_gpio, 0); ++ + if (lt8911exb->init_work_pending) { + cancel_delayed_work_sync(<8911exb->init_work); + lt8911exb->init_work_pending = false; +@@ -1244,6 +1241,9 @@ static void init_work_func(struct work_struct *work) + + DRM_DEBUG(" %s() \n", __func__); + ++ gpiod_direction_output(lt8911exb->standby_gpio, 1); ++ usleep_range(50*1000, 100*1000); //100ms ++ + lt8911exb_reset(lt8911exb); + lt8911exb_chip_id(lt8911exb); + +@@ -1263,6 +1263,7 @@ static void init_work_func(struct work_struct *work) + + PCR_Status(lt8911exb); + ++ gpiod_direction_output(lt8911exb->enable_gpio, 1); + gpiod_direction_output(lt8911exb->bl_gpio, 1); + } + +@@ -1330,12 +1331,12 @@ static int lt8911exb_probe(struct i2c_client *client, + return PTR_ERR(lt8911exb->bl_gpio); + } + gpiod_direction_output(lt8911exb->bl_gpio, 0); ++ gpiod_direction_output(lt8911exb->enable_gpio, 0); ++ usleep_range(50*1000, 100*1000); //100ms + + //disable firstly + gpiod_direction_output(lt8911exb->standby_gpio, 0); +- gpiod_direction_output(lt8911exb->enable_gpio, 0); + usleep_range(50*1000, 100*1000); //100ms +- gpiod_direction_output(lt8911exb->enable_gpio, 1); + gpiod_direction_output(lt8911exb->standby_gpio, 1); + usleep_range(50*1000, 100*1000); //100ms + +diff --git a/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.c b/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.c +index 8635db4d48e8..be9b88194815 100644 +--- a/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.c ++++ b/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.c +@@ -1099,10 +1099,68 @@ static int camsnr_open(struct inode *inode, struct file *file) + { + struct cam_sensor_device *msnr_dev = + container_of(inode->i_cdev, struct cam_sensor_device, cdev); ++ u32 cell_id; ++ struct device *dev = NULL; ++ int ret; + +- cam_dbg("%s open %s%d, twsi_no %d\n", __func__, DRIVER_NAME, msnr_dev->id, +- msnr_dev->twsi_no); + file->private_data = msnr_dev; ++ ++ if (msnr_dev->is_pinmulti) { ++ dev = &msnr_dev->pdev->dev; ++ cell_id = msnr_dev->id; ++ ++ // msnr_dev->pinctrl = devm_pinctrl_get (dev); ++ msnr_dev->pinctrl = pinctrl_get_select (dev, "mclk_multi"); ++ if (IS_ERR(msnr_dev->pinctrl)) { ++ cam_err("unable to get sensor%d mclk pinctrl\n", cell_id); ++ return PTR_ERR(msnr_dev->pinctrl); ++ } ++ ++ msnr_dev->pinctrl_state = pinctrl_lookup_state(msnr_dev->pinctrl, "mclk_multi"); ++ if (IS_ERR(msnr_dev->pinctrl_state)) { ++ cam_err("unable to lookup sensor%d mclk pinctrl state\n", cell_id); ++ pinctrl_put(msnr_dev->pinctrl); ++ return PTR_ERR(msnr_dev->pinctrl_state); ++ } ++ ++ pinctrl_select_state(msnr_dev->pinctrl, msnr_dev->pinctrl_state); ++ ++ /* mclks */ ++ msnr_dev->mclk = clk_get(dev, msnr_dev->mclk_name); ++ if (IS_ERR(msnr_dev->mclk)) { ++ cam_err("unable to get cam_mclk%d\n", cell_id); ++ return PTR_ERR(msnr_dev->mclk); ++ } ++ ++ /* pwdn-gpios */ ++ msnr_dev->pwdn = gpiod_get(dev, "pwdn", GPIOD_OUT_HIGH); ++ if (IS_ERR(msnr_dev->pwdn)) { ++ cam_info("%s: unable to parse sensor%d pwdn gpio", __func__, cell_id); ++ return PTR_ERR(msnr_dev->pwdn); ++ } else { ++ ret = gpiod_direction_output(msnr_dev->pwdn, 0); ++ if (ret < 0) { ++ cam_err("%s: Failed to init sensor%d pwdn gpio", __func__, cell_id); ++ return ret; ++ } ++ } ++ ++ /* rst-gpios */ ++ msnr_dev->rst = gpiod_get(dev, "reset", GPIOD_OUT_HIGH); ++ if (IS_ERR(msnr_dev->rst)) { ++ cam_info("%s: unable to parse sensor%d reset gpio", __func__, cell_id); ++ return PTR_ERR(msnr_dev->rst); ++ } else { ++ ret = gpiod_direction_output(msnr_dev->rst, 0); ++ if (ret < 0) { ++ cam_err("%s: Failed to init sensor%d reset gpio", __func__, cell_id); ++ return ret; ++ } ++ } ++ } ++ cam_dbg("%s open %s%d, twsi_no %d, is_pinmulti %d\n", __func__, DRIVER_NAME, msnr_dev->id, ++ msnr_dev->twsi_no, msnr_dev->is_pinmulti); ++ + return 0; + } + +@@ -1110,8 +1168,29 @@ static int camsnr_release(struct inode *inode, struct file *file) + { + struct cam_sensor_device *msnr_dev = + container_of(inode->i_cdev, struct cam_sensor_device, cdev); +- cam_dbg("%s close %s%d, twsi_no %d\n", __func__, DRIVER_NAME, msnr_dev->id, +- msnr_dev->twsi_no); ++ ++ if (msnr_dev->is_pinmulti) { ++ pinctrl_put(msnr_dev->pinctrl); ++ ++ /* mclks */ ++ if (msnr_dev->mclk) ++ clk_put(msnr_dev->mclk); ++ msnr_dev->mclk = NULL; ++ ++ /* pwdn-gpios */ ++ if (msnr_dev->pwdn) ++ gpiod_put(msnr_dev->pwdn); ++ msnr_dev->pwdn = NULL; ++ ++ /* rst-gpios */ ++ if (msnr_dev->rst) ++ gpiod_put(msnr_dev->rst); ++ msnr_dev->rst = NULL; ++ } ++ ++ cam_dbg("%s close %s%d, twsi_no %d, is_pinmulti %d\n", __func__, DRIVER_NAME, msnr_dev->id, ++ msnr_dev->twsi_no, msnr_dev->is_pinmulti); ++ + return 0; + } + +@@ -1199,7 +1278,7 @@ static int camsnr_of_parse(struct cam_sensor_device *sensor) + struct device_node *of_node = NULL; + u32 cell_id, twsi_no, dphy_no; + int ret; +- const char *mclk_name; ++ //const char *mclk_name; + + SENSOR_DRIVER_CHECK_POINTER(sensor); + dev = &sensor->pdev->dev; +@@ -1239,25 +1318,6 @@ static int camsnr_of_parse(struct cam_sensor_device *sensor) + } + sensor->dphy_no = (u8) dphy_no; + +- ret = of_property_read_string(of_node, "clock-names", &mclk_name); +- if (!ret) { +- if (strcmp(mclk_name, "cam_mclk0") && strcmp(mclk_name, "cam_mclk1") && strcmp(mclk_name, "cam_mclk2")) { +- cam_err("%s: error! only support cam_mclk0~2!", __func__); +- return -EINVAL; +- } +- } else { +- cam_err("%s: clock-names read failed", __func__); +- return ret; +- } +- +- /* mclks */ +- sensor->mclk = devm_clk_get(dev, mclk_name); +- if (IS_ERR(sensor->mclk)) { +- cam_err("unable to get cam_mclk%d\n", cell_id); +- ret = PTR_ERR(sensor->mclk); +- goto st_err; +- } +- + sensor->afvdd = devm_regulator_get(dev, "af_2v8"); + if (IS_ERR(sensor->afvdd)) { + dev_warn(dev, "Failed to get regulator af_2v8\n"); +@@ -1282,31 +1342,56 @@ static int camsnr_of_parse(struct cam_sensor_device *sensor) + sensor->dvdd = NULL; + } + +- /* pwdn-gpios */ +- sensor->pwdn = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_HIGH); +- if (IS_ERR(sensor->pwdn)) { +- cam_info("%s: unable to parse sensor%d pwdn gpio", __func__, cell_id); +- ret = PTR_ERR(sensor->pwdn); +- } else { +- ret = gpiod_direction_output(sensor->pwdn, 0); +- if (ret < 0) { +- cam_err("%s: Failed to init sensor%d pwdn gpio", __func__, cell_id); +- goto st_err; ++ ret = of_property_read_string(of_node, "clock-names", &sensor->mclk_name); ++ if (!ret) { ++ if (strcmp(sensor->mclk_name, "cam_mclk0") && strcmp(sensor->mclk_name, "cam_mclk1") && strcmp(sensor->mclk_name, "cam_mclk2")) { ++ cam_err("%s: error! only support cam_mclk0~2!", __func__); ++ return -EINVAL; + } ++ } else { ++ cam_err("%s: clock-names read failed", __func__); ++ return ret; + } + +- /* rst-gpios */ +- sensor->rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); +- if (IS_ERR(sensor->rst)) { +- cam_info("%s: unable to parse sensor%d reset gpio", __func__, cell_id); +- ret = PTR_ERR(sensor->rst); +- } else { +- ret = gpiod_direction_output(sensor->rst, 0); +- if (ret < 0) { +- cam_err("%s: Failed to init sensor%d reset gpio", __func__, cell_id); ++ // mclk/pwdn/rst multiplex ++ sensor->is_pinmulti = of_property_read_bool(of_node, "pinmulti-enable"); ++ cam_info("cam_sensor%d is_pinmulti: %d\n", sensor->id, sensor->is_pinmulti); ++ if (!sensor->is_pinmulti) { ++ /* mclks */ ++ sensor->mclk = devm_clk_get(dev, sensor->mclk_name); ++ if (IS_ERR(sensor->mclk)) { ++ cam_err("unable to get cam_mclk%d\n", cell_id); ++ ret = PTR_ERR(sensor->mclk); + goto st_err; + } ++ ++ /* pwdn-gpios */ ++ sensor->pwdn = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_HIGH); ++ if (IS_ERR(sensor->pwdn)) { ++ cam_info("%s: unable to parse sensor%d pwdn gpio", __func__, cell_id); ++ ret = PTR_ERR(sensor->pwdn); ++ } else { ++ ret = gpiod_direction_output(sensor->pwdn, 0); ++ if (ret < 0) { ++ cam_err("%s: Failed to init sensor%d pwdn gpio", __func__, cell_id); ++ goto st_err; ++ } ++ } ++ ++ /* rst-gpios */ ++ sensor->rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); ++ if (IS_ERR(sensor->rst)) { ++ cam_info("%s: unable to parse sensor%d reset gpio", __func__, cell_id); ++ ret = PTR_ERR(sensor->rst); ++ } else { ++ ret = gpiod_direction_output(sensor->rst, 0); ++ if (ret < 0) { ++ cam_err("%s: Failed to init sensor%d reset gpio", __func__, cell_id); ++ goto st_err; ++ } ++ } + } ++ + #ifdef CONFIG_ARCH_ZYNQMP + cam_dbg("dptc-gpios,cell_id =0x%x",cell_id); + /* dptc-gpios */ +@@ -1375,7 +1460,7 @@ static int cam_sensor_probe(struct platform_device *pdev) + mutex_init(&msnr_dev->lock); + + g_sdev[msnr_dev->id] = msnr_dev; +- cam_dbg("camera sensor%d probed", msnr_dev->id); ++ cam_info("camera sensor%d probed", msnr_dev->id); + + return ret; + } +diff --git a/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.h b/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.h +index 7eb45f5d85e7..d70ed1bba223 100644 +--- a/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.h ++++ b/drivers/media/platform/spacemit/camera/cam_sensor/cam_sensor.h +@@ -34,6 +34,10 @@ struct cam_sensor_device { + struct gpio_desc *dptc; + #endif + struct clk *mclk; ++ const char *mclk_name; ++ bool is_pinmulti; ++ struct pinctrl *pinctrl; ++ struct pinctrl_state *pinctrl_state; + + atomic_t usr_cnt; + struct mutex lock; /* Protects streaming, format, interval */ +diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile +index e347b435a038..dfeacc89f407 100644 +--- a/drivers/mtd/spi-nor/Makefile ++++ b/drivers/mtd/spi-nor/Makefile +@@ -17,6 +17,7 @@ spi-nor-objs += sst.o + spi-nor-objs += winbond.o + spi-nor-objs += xilinx.o + spi-nor-objs += xmc.o ++spi-nor-objs += fmsh.o + spi-nor-$(CONFIG_DEBUG_FS) += debugfs.o + obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o + +diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c +index 5dbf52aa0355..23534c5154c5 100644 +--- a/drivers/mtd/spi-nor/core.c ++++ b/drivers/mtd/spi-nor/core.c +@@ -1633,6 +1633,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { + &spi_nor_winbond, + &spi_nor_xilinx, + &spi_nor_xmc, ++ &spi_nor_fmsh, + }; + + static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, +diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h +index 85b0cf254e97..6cae01a11605 100644 +--- a/drivers/mtd/spi-nor/core.h ++++ b/drivers/mtd/spi-nor/core.h +@@ -627,6 +627,7 @@ extern const struct spi_nor_manufacturer spi_nor_sst; + extern const struct spi_nor_manufacturer spi_nor_winbond; + extern const struct spi_nor_manufacturer spi_nor_xilinx; + extern const struct spi_nor_manufacturer spi_nor_xmc; ++extern const struct spi_nor_manufacturer spi_nor_fmsh; + + extern const struct attribute_group *spi_nor_sysfs_groups[]; + +diff --git a/drivers/mtd/spi-nor/fmsh.c b/drivers/mtd/spi-nor/fmsh.c +new file mode 100644 +index 000000000000..73004e94476e +--- /dev/null ++++ b/drivers/mtd/spi-nor/fmsh.c +@@ -0,0 +1,20 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2023, spacemit Corporation. ++ */ ++ ++#include ++ ++#include "core.h" ++ ++static const struct flash_info fmsh_nor_parts[] = { ++ { "FM25Q64AI3", INFO(0xa14017, 0, 4 * 1024, 2048) ++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ | ++ SPI_NOR_DUAL_READ) }, ++}; ++ ++const struct spi_nor_manufacturer spi_nor_fmsh = { ++ .name = "fmsh", ++ .parts = fmsh_nor_parts, ++ .nparts = ARRAY_SIZE(fmsh_nor_parts), ++}; +diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig +index ec8a49c04003..1841a2249806 100644 +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -271,6 +271,16 @@ config NVMEM_SNVS_LPGPR + This driver can also be built as a module. If so, the module + will be called nvmem-snvs-lpgpr. + ++config NVMEM_SPACEMIT_EFUSE ++ tristate "Spacemit SoCs efuse support" ++ depends on SOC_SPACEMIT || COMPILE_TEST ++ help ++ This is a simple efuse provider driver for Spacemit SoC ++ provide data from eFuse, such as chip-version. ++ ++ This driver can also be built as a module. If so, the module ++ will be called nvmem_spacemit_efuse. ++ + config NVMEM_SPMI_SDAM + tristate "SPMI SDAM Support" + depends on SPMI +diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile +index fa80fe17e567..fa86f9895c28 100644 +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -55,6 +55,8 @@ obj-$(CONFIG_NVMEM_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o + nvmem-sc27xx-efuse-y := sc27xx-efuse.o + obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o + nvmem_snvs_lpgpr-y := snvs_lpgpr.o ++obj-$(CONFIG_NVMEM_SPACEMIT_EFUSE) += nvmem_spacemit_efuse.o ++nvmem_spacemit_efuse-y := spacemit-efuse.o + obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o + nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o + obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o +diff --git a/drivers/nvmem/spacemit-efuse.c b/drivers/nvmem/spacemit-efuse.c +new file mode 100644 +index 000000000000..782dbf02a8ff +--- /dev/null ++++ b/drivers/nvmem/spacemit-efuse.c +@@ -0,0 +1,172 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit eFuse Driver ++ * ++ * Copyright (c) 2024 Spacemit Co. Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++struct spacemit_efuse_bank { ++ struct device *dev; ++ void __iomem *base; ++ struct clk *clk; ++ struct reset_control *reset; ++ struct nvmem_device *nvmem; ++ struct nvmem_config *econfig; ++ u8 *efuse_data; ++ u32 size; ++}; ++ ++ ++/* ++ * read efuse data to buffer for k1 soc. ++ */ ++static int spacemit_k1_efuse_read(struct spacemit_efuse_bank *efuse) ++{ ++ int i, ret; ++ u32 *buffer; ++ ++ ret = clk_prepare_enable(efuse->clk); ++ if (ret < 0) { ++ dev_err(efuse->dev, "failed to prepare/enable efuse clk\n"); ++ return ret; ++ } ++ ret = reset_control_deassert(efuse->reset); ++ if (ret < 0) { ++ dev_err(efuse->dev, "failed to deassert efuse\n"); ++ clk_disable_unprepare(efuse->clk); ++ return ret; ++ } ++ ++ /* ++ * efuse data has been load into register by uboot already, ++ * just get efuse data from register ++ */ ++ buffer = (u32 *)efuse->efuse_data; ++ for (i = 0; i < efuse->size/sizeof(u32); i++) { ++ buffer[i] = readl(efuse->base + i*4); ++ } ++ ++ reset_control_assert(efuse->reset); ++ clk_disable_unprepare(efuse->clk); ++ ++ return ret; ++} ++ ++ ++/* ++ * call-back function, just read data from buffer ++ */ ++static int spacemit_efuse_read(void *context, unsigned int offset, ++ void *val, size_t bytes) ++{ ++ int i; ++ u8 *buf = (u8 *)val; ++ struct spacemit_efuse_bank *efuse = context; ++ ++ /* check if data request is out of bound */ ++ for(i=0; iefuse_data[offset + i]; ++ } ++ ++ return 0; ++} ++ ++static int spacemit_efuse_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct resource *res; ++ struct nvmem_device *nvmem; ++ struct nvmem_config *econfig; ++ struct spacemit_efuse_bank *efuse; ++ struct device *dev = &pdev->dev; ++ int (*efuse_read)(struct spacemit_efuse_bank *efuse); ++ ++ efuse_read = of_device_get_match_data(dev); ++ if (!efuse_read) { ++ return -EINVAL; ++ } ++ ++ efuse = devm_kzalloc(dev, sizeof(struct spacemit_efuse_bank), ++ GFP_KERNEL); ++ if (!efuse) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ efuse->base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(efuse->base)) ++ return PTR_ERR(efuse->base); ++ ++ efuse->clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(efuse->clk)) ++ return PTR_ERR(efuse->clk); ++ ++ efuse->reset = devm_reset_control_get_optional_shared(dev, NULL); ++ if (IS_ERR(efuse->reset)) ++ return PTR_ERR(efuse->reset); ++ ++ /* try read efuse data to buffer */ ++ efuse->size = roundup(resource_size(res), sizeof(u32)); ++ efuse->efuse_data = devm_kzalloc(dev, efuse->size, GFP_KERNEL); ++ if (!efuse->efuse_data) ++ return -ENOMEM; ++ ++ ret = efuse_read(efuse); ++ if (ret < 0) ++ return -EBUSY; ++ efuse->dev = dev; ++ ++ econfig = devm_kzalloc(dev, sizeof(*econfig), GFP_KERNEL); ++ if (!econfig) ++ return -ENOMEM; ++ ++ efuse->econfig = econfig; ++ econfig->dev = dev; ++ econfig->name = dev_name(dev), ++ econfig->stride = 1; ++ econfig->word_size = 1; ++ econfig->read_only = true; ++ econfig->reg_read = spacemit_efuse_read; ++ econfig->size = resource_size(res); ++ econfig->priv = efuse; ++ ++ nvmem = devm_nvmem_register(dev, econfig); ++ efuse->nvmem = nvmem; ++ ++ platform_set_drvdata(pdev, efuse); ++ ++ return PTR_ERR_OR_ZERO(nvmem); ++} ++ ++static const struct of_device_id spacemit_efuse_match[] = { ++ { ++ .compatible = "spacemit,k1-efuse", ++ .data = (void *)&spacemit_k1_efuse_read, ++ }, ++ { /* sentinel */}, ++}; ++ ++static struct platform_driver spacemit_efuse_driver = { ++ .probe = spacemit_efuse_probe, ++ .driver = { ++ .name = "spacemit-efuse", ++ .of_match_table = spacemit_efuse_match, ++ }, ++}; ++module_platform_driver(spacemit_efuse_driver); ++ ++MODULE_DESCRIPTION("Spacemit eFuse driver"); ++MODULE_LICENSE("GPL v2"); ++ +diff --git a/drivers/opp/core.c b/drivers/opp/core.c +index e87567dbe99f..602c24e1303d 100644 +--- a/drivers/opp/core.c ++++ b/drivers/opp/core.c +@@ -624,8 +624,13 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); + static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table, + unsigned long *freq) + { ++#ifndef CONFIG_SOC_SPACEMIT + return _opp_table_find_key_ceil(opp_table, freq, 0, true, _read_freq, + assert_single_clk); ++#else ++ return _opp_table_find_key_ceil(opp_table, freq, 0, true, _read_freq, ++ NULL); ++#endif + } + + /** +@@ -649,7 +654,11 @@ static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table, + struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, + unsigned long *freq) + { ++#ifndef CONFIG_SOC_SPACEMIT + return _find_key_ceil(dev, freq, 0, true, _read_freq, assert_single_clk); ++#else ++ return _find_key_ceil(dev, freq, 0, true, _read_freq, NULL); ++#endif + } + EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); + +@@ -2549,6 +2558,110 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) + } + EXPORT_SYMBOL_GPL(dev_pm_opp_set_config); + ++#ifdef CONFIG_SOC_SPACEMIT ++int dev_pm_opp_set_config_indexed(struct device *dev, struct dev_pm_opp_config *config, int index) ++{ ++ struct opp_table *opp_table; ++ struct opp_config_data *data; ++ unsigned int id; ++ int ret; ++ ++ data = kmalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ opp_table = _add_opp_table_indexed(dev, index, false); ++ if (IS_ERR(opp_table)) { ++ kfree(data); ++ return PTR_ERR(opp_table); ++ } ++ ++ data->opp_table = opp_table; ++ data->flags = 0; ++ ++ /* This should be called before OPPs are initialized */ ++ if (WARN_ON(!list_empty(&opp_table->opp_list))) { ++ ret = -EBUSY; ++ goto err; ++ } ++ ++ /* Configure clocks */ ++ if (config->clk_names) { ++ ret = _opp_set_clknames(opp_table, dev, config->clk_names, ++ config->config_clks); ++ if (ret) ++ goto err; ++ ++ data->flags |= OPP_CONFIG_CLK; ++ } else if (config->config_clks) { ++ /* Don't allow config callback without clocks */ ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ /* Configure property names */ ++ if (config->prop_name) { ++ ret = _opp_set_prop_name(opp_table, config->prop_name); ++ if (ret) ++ goto err; ++ ++ data->flags |= OPP_CONFIG_PROP_NAME; ++ } ++ ++ /* Configure config_regulators helper */ ++ if (config->config_regulators) { ++ ret = _opp_set_config_regulators_helper(opp_table, dev, ++ config->config_regulators); ++ if (ret) ++ goto err; ++ ++ data->flags |= OPP_CONFIG_REGULATOR_HELPER; ++ } ++ ++ /* Configure supported hardware */ ++ if (config->supported_hw) { ++ ret = _opp_set_supported_hw(opp_table, config->supported_hw, ++ config->supported_hw_count); ++ if (ret) ++ goto err; ++ ++ data->flags |= OPP_CONFIG_SUPPORTED_HW; ++ } ++ ++ /* Configure supplies */ ++ if (config->regulator_names) { ++ ret = _opp_set_regulators(opp_table, dev, ++ config->regulator_names); ++ if (ret) ++ goto err; ++ ++ data->flags |= OPP_CONFIG_REGULATOR; ++ } ++ ++ /* Attach genpds */ ++ if (config->genpd_names) { ++ ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, ++ config->virt_devs); ++ if (ret) ++ goto err; ++ ++ data->flags |= OPP_CONFIG_GENPD; ++ } ++ ++ ret = xa_alloc(&opp_configs, &id, data, XA_LIMIT(1, INT_MAX), ++ GFP_KERNEL); ++ if (ret) ++ goto err; ++ ++ return id; ++ ++err: ++ _opp_clear_config(data); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(dev_pm_opp_set_config_indexed); ++#endif ++ + /** + * dev_pm_opp_clear_config() - Releases resources blocked for OPP configuration. + * @opp_table: OPP table returned from dev_pm_opp_set_config(). +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index d5d4fa84738e..91d02fad612c 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -29,6 +29,11 @@ + #include + + #include ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++#include ++#include ++#include ++#endif + + #include "core.h" + #include "devicetree.h" +@@ -38,6 +43,10 @@ + #define DRIVER_NAME "pinctrl-single" + #define PCS_OFF_DISABLED ~0U + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++#define EDGE_CLEAR 6 ++#endif ++ + /** + * struct pcs_func_vals - mux function register offset and value pair + * @reg: register virtual address +@@ -176,6 +185,11 @@ struct pcs_soc_data { + struct pcs_device { + struct resource *res; + void __iomem *base; ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ struct resource *gedge_flag_res; ++ void __iomem *gedge_flag_base; ++ unsigned gedge_flag_size; ++#endif + void *saved_vals; + unsigned size; + struct device *dev; +@@ -1431,8 +1445,11 @@ static inline void pcs_irq_set(struct pcs_soc_data *pcs_soc, + static void pcs_irq_mask(struct irq_data *d) + { + struct pcs_soc_data *pcs_soc = irq_data_get_irq_chip_data(d); +- ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ pcs_irq_set(pcs_soc, d->irq, true); ++#else + pcs_irq_set(pcs_soc, d->irq, false); ++#endif + } + + /** +@@ -1443,7 +1460,11 @@ static void pcs_irq_unmask(struct irq_data *d) + { + struct pcs_soc_data *pcs_soc = irq_data_get_irq_chip_data(d); + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ pcs_irq_set(pcs_soc, d->irq, false); ++#else + pcs_irq_set(pcs_soc, d->irq, true); ++#endif + } + + /** +@@ -1484,6 +1505,7 @@ static int pcs_irq_handle(struct pcs_soc_data *pcs_soc) + unsigned mask; + + pcswi = list_entry(pos, struct pcs_interrupt, node); ++#ifndef CONFIG_SOC_SPACEMIT_K1X + raw_spin_lock(&pcs->lock); + mask = pcs->read(pcswi->reg); + raw_spin_unlock(&pcs->lock); +@@ -1492,6 +1514,21 @@ static int pcs_irq_handle(struct pcs_soc_data *pcs_soc) + pcswi->hwirq); + count++; + } ++#else ++ unsigned reg_offset, bit_offset; ++ ++ reg_offset = (pcswi->hwirq / 4 - 1) / 32 * 4; ++ bit_offset = (pcswi->hwirq / 4 - 1) - reg_offset / 4 * 32; ++ ++ raw_spin_lock(&pcs->lock); ++ mask = pcs->read(pcs->gedge_flag_base + reg_offset); ++ raw_spin_unlock(&pcs->lock); ++ if (mask & (1 << bit_offset)) { ++ generic_handle_domain_irq(pcs->domain, ++ pcswi->hwirq); ++ count++; ++ } ++#endif + } + + return count; +@@ -1592,7 +1629,6 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs, + + if (PCS_QUIRK_HAS_SHARED_IRQ) { + int res; +- + res = request_irq(pcs_soc->irq, pcs_irq_handler, + IRQF_SHARED | IRQF_NO_SUSPEND | + IRQF_NO_THREAD, +@@ -1775,6 +1811,11 @@ static int pcs_quirk_missing_pinctrl_cells(struct pcs_device *pcs, + return error; + } + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++static struct clk *psc_clk; ++static struct reset_control *psc_rst; ++#endif ++ + static int pcs_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; +@@ -1783,11 +1824,44 @@ static int pcs_probe(struct platform_device *pdev) + struct pcs_device *pcs; + const struct pcs_soc_data *soc; + int ret; ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ unsigned val; ++ void __iomem *mem_base; ++#endif + + soc = of_device_get_match_data(&pdev->dev); + if (WARN_ON(!soc)) + return -EINVAL; + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ psc_rst = devm_reset_control_get_exclusive(&pdev->dev, "aib_rst"); ++ if (IS_ERR(psc_rst)) { ++ ret = PTR_ERR(psc_rst); ++ dev_err(&pdev->dev, "Failed to get reset: %d\n", ret); ++ return -EINVAL; ++ } ++ ++ /* deasser clk */ ++ ret = reset_control_deassert(psc_rst); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to deassert reset: %d\n", ret); ++ return -EINVAL; ++ } ++ ++ psc_clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(psc_clk)) { ++ dev_err(&pdev->dev, "Fail to get pinctrl clock, error %ld.\n", ++ PTR_ERR(psc_clk)); ++ return PTR_ERR(psc_clk); ++ } ++ ++ ret = clk_prepare_enable(psc_clk); ++ if (ret) { ++ dev_err(&pdev->dev, "Fail to enable pinctrl clock, error %d.\n", ret); ++ return ret; ++ } ++#endif ++ + pcs = devm_kzalloc(&pdev->dev, sizeof(*pcs), GFP_KERNEL); + if (!pcs) + return -ENOMEM; +@@ -1855,6 +1929,30 @@ static int pcs_probe(struct platform_device *pdev) + return -ENODEV; + } + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!res) { ++ dev_err(pcs->dev, "could not get resource\n"); ++ return -ENODEV; ++ } ++ ++ pcs->gedge_flag_res = devm_request_mem_region(pcs->dev, res->start, ++ resource_size(res), DRIVER_NAME); ++ if (!pcs->gedge_flag_res) { ++ dev_err(pcs->dev, "could not get mem_region\n"); ++ return -EBUSY; ++ } ++ ++ pcs->gedge_flag_size = resource_size(pcs->gedge_flag_res); ++ pcs->gedge_flag_base = devm_ioremap(pcs->dev, pcs->gedge_flag_res->start, ++ pcs->gedge_flag_size); ++ if (!pcs->gedge_flag_base) { ++ dev_err(pcs->dev, "could not ioremap\n"); ++ return -ENODEV; ++ } ++#endif ++ mem_base = pcs->base; ++ + platform_set_drvdata(pdev, pcs); + + switch (pcs->width) { +@@ -1918,6 +2016,11 @@ static int pcs_probe(struct platform_device *pdev) + + dev_info(pcs->dev, "%i pins, size %u\n", pcs->desc.npins, pcs->size); + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ dev_pm_set_wake_irq(&pdev->dev, pcs->socdata.irq ); ++ device_init_wakeup(&pdev->dev, true); ++#endif ++ + return pinctrl_enable(pcs->pctl); + + free: +@@ -1935,6 +2038,12 @@ static int pcs_remove(struct platform_device *pdev) + + pcs_free_resources(pcs); + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ clk_disable_unprepare(psc_clk); ++ ++ reset_control_assert(psc_rst); ++#endif ++ + return 0; + } + +@@ -1955,6 +2064,14 @@ static const struct pcs_soc_data pinctrl_single_am437x = { + .irq_status_mask = (1 << 30), /* OMAP_WAKEUP_EVENT */ + }; + ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++static const struct pcs_soc_data pinconf_single_aib = { ++ .flags = PCS_QUIRK_SHARED_IRQ, ++ .irq_enable_mask = (1 << EDGE_CLEAR), /* WAKEUPENABLE */ ++ .irq_status_mask = (1 << EDGE_CLEAR), /* WAKEUPSTATUS */ ++}; ++#endif ++ + static const struct pcs_soc_data pinctrl_single = { + }; + +@@ -1970,6 +2087,9 @@ static const struct of_device_id pcs_of_match[] = { + { .compatible = "ti,am437-padconf", .data = &pinctrl_single_am437x }, + { .compatible = "pinctrl-single", .data = &pinctrl_single }, + { .compatible = "pinconf-single", .data = &pinconf_single }, ++#ifdef CONFIG_SOC_SPACEMIT_K1X ++ { .compatible = "pinconf-single-aib", .data = &pinconf_single_aib }, ++#endif + { }, + }; + MODULE_DEVICE_TABLE(of, pcs_of_match); +diff --git a/drivers/soc/spacemit/Kconfig b/drivers/soc/spacemit/Kconfig +index c36e986f25bb..c1c3536488d8 100644 +--- a/drivers/soc/spacemit/Kconfig ++++ b/drivers/soc/spacemit/Kconfig +@@ -34,6 +34,15 @@ config SPACEMI_K1X_DMA_RANGE + This driver is an empty shell, in order to make the dma-ranges function + effective + ++config SPACEMI_SOCINFO ++ tristate "Socinfo driver for spacemit SoCs" ++ depends on SOC_SPACEMIT && NVMEM_SPACEMIT_EFUSE ++ select MFD_SYSCON ++ select SOC_BUS ++ help ++ Spacemit SoCs information driver, which get information from efuse and ++ report to userspace. ++ + source "drivers/soc/spacemit/jpu/Kconfig" + source "drivers/soc/spacemit/v2d/Kconfig" + source "drivers/soc/spacemit/spacemit-rf/Kconfig" +diff --git a/drivers/soc/spacemit/Makefile b/drivers/soc/spacemit/Makefile +index e5e23be15e73..523fe88365b9 100644 +--- a/drivers/soc/spacemit/Makefile ++++ b/drivers/soc/spacemit/Makefile +@@ -1,8 +1,9 @@ +-obj-$(CONFIG_SPACEMIT_PM_DOMAINS) += pm_domain/ +-obj-$(CONFIG_CHIP_MEDIA_JPU) += jpu/ +-obj-$(CONFIG_SPACEMIT_V2D) += v2d/ +-obj-$(CONFIG_SPACEMIT_RFKILL) += spacemit-rf/ +-obj-$(CONFIG_SPACEMIT_REBOOT_CONTROL) += spacemit_reboot.o + obj-$(CONFIG_SPACEMI_K1X_DMA_RANGE) += k1x-dma-range.o + obj-$(CONFIG_SPACEMIT_LID_CONTROL) += spacemit_lid.o ++obj-$(CONFIG_SPACEMIT_REBOOT_CONTROL) += spacemit_reboot.o ++obj-$(CONFIG_SPACEMI_SOCINFO) += spacemit-socinfo.o ++obj-$(CONFIG_CHIP_MEDIA_JPU) += jpu/ + obj-$(CONFIG_PM) += pm/ ++obj-$(CONFIG_SPACEMIT_PM_DOMAINS) += pm_domain/ ++obj-$(CONFIG_SPACEMIT_RFKILL) += spacemit-rf/ ++obj-$(CONFIG_SPACEMIT_V2D) += v2d/ +diff --git a/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c b/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c +index 4a2dd1b2e553..de03e2e2e5d9 100644 +--- a/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c ++++ b/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c +@@ -42,6 +42,8 @@ + /* pmic */ + #define WAKEUP_SOURCE_WAKEUP_7 7 + ++/* gpio */ ++#define WAKEUP_SOURCE_WAKEUP_2 2 + + #define PM_QOS_BLOCK_C1 0x0 /* core wfi */ + #define PM_QOS_BLOCK_C2 0x2 /* core power off */ +@@ -811,6 +813,11 @@ static int acpr_per_suspend(void) + apcr_per |= (1 << WAKEUP_SOURCE_WAKEUP_7); + regmap_write(gpmu->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, apcr_per); + ++ /* enable gpio wakeup */ ++ regmap_read(gpmu->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, &apcr_per); ++ apcr_per |= (1 << WAKEUP_SOURCE_WAKEUP_2); ++ regmap_write(gpmu->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, apcr_per); ++ + return 0; + } + +diff --git a/drivers/soc/spacemit/spacemit-rf/spacemit-wlan.c b/drivers/soc/spacemit/spacemit-rf/spacemit-wlan.c +index 2c6a5fa4d3e6..1e22a32dba65 100644 +--- a/drivers/soc/spacemit/spacemit-rf/spacemit-wlan.c ++++ b/drivers/soc/spacemit/spacemit-rf/spacemit-wlan.c +@@ -27,7 +27,7 @@ struct wlan_pwrseq { + u32 power_on_delay_ms; + + struct gpio_desc *regon; +- struct gpio_desc *hostwake; ++ int irq; + + struct mutex wlan_mutex; + }; +@@ -56,16 +56,15 @@ EXPORT_SYMBOL_GPL(spacemit_wlan_set_power); + int spacemit_wlan_get_oob_irq(void) + { + struct wlan_pwrseq *pwrseq = pdata; +- int host_oob_irq = 0; + +- if (!pwrseq || IS_ERR(pwrseq->hostwake)) ++ if (!pwrseq) + return 0; + +- host_oob_irq = gpiod_to_irq(pwrseq->hostwake); +- if (host_oob_irq < 0) +- dev_err(pwrseq->dev, "map hostwake gpio to virq failed\n"); +- +- return host_oob_irq; ++ if (pwrseq->irq <= 0){ ++ dev_err(pwrseq->dev, "get oob irq failed\n"); ++ return 0; ++ } ++ return pwrseq->irq; + } + EXPORT_SYMBOL_GPL(spacemit_wlan_get_oob_irq); + +@@ -77,7 +76,7 @@ int spacemit_wlan_get_oob_irq_flags(void) + if (!pwrseq) + return 0; + +- oob_irq_flags = (IRQF_TRIGGER_HIGH | IRQF_SHARED | IRQF_NO_SUSPEND); ++ oob_irq_flags = (IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND); + + return oob_irq_flags; + } +@@ -125,11 +124,9 @@ static int spacemit_wlan_probe(struct platform_device *pdev) + return PTR_ERR(pwrseq->regon); + } + +- pwrseq->hostwake = devm_gpiod_get(dev, "hostwake", GPIOD_IN); +- if (IS_ERR(pwrseq->hostwake) && +- PTR_ERR(pwrseq->hostwake) != -ENOENT && +- PTR_ERR(pwrseq->hostwake) != -ENOSYS) { +- return PTR_ERR(pwrseq->hostwake); ++ pwrseq->irq = platform_get_irq(pdev, 0); ++ if (pwrseq->irq < 0){ ++ dev_err(pwrseq->dev, "get hostwake irq failed, ignore wow\n"); + } + + if(device_property_read_u32(dev, "power-on-delay-ms", +diff --git a/drivers/soc/spacemit/spacemit-socinfo.c b/drivers/soc/spacemit/spacemit-socinfo.c +new file mode 100644 +index 000000000000..0dfec63b7a8d +--- /dev/null ++++ b/drivers/soc/spacemit/spacemit-socinfo.c +@@ -0,0 +1,205 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 Spacemit Co., Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* ++ * soc information ++ */ ++static struct spacemit_soc_info { ++ u32 die_id; /* die/wafer id */ ++ u32 ver_id; /* die/wafer version */ ++ u32 pack_id; /* package id */ ++ u32 svtdro; /* dro vaule */ ++ u64 chipid; /* chip serial number */ ++ u32 soc_id; /* soc id */ ++ char *name; /* chip name */ ++} soc_info; ++ ++ ++static const struct spacemit_soc_id { ++ const char *name; ++ unsigned int id; ++} soc_ids[] = { ++ { "unknown", 0x00000000 }, ++ ++ /* k1 serial soc */ ++ { "M1-8571", 0x36070000 }, ++ { "K1-6370", 0x36070009 }, ++ { "K1-6350", 0x36070012 }, ++ { "K1-6371", 0x36070040 }, ++ { "M103-6370", 0x36070109 }, ++ { "M103-6371", 0x36070140 }, ++}; ++ ++ ++static const char *soc_id_to_chip_name(u32 die_id, u32 ver_id, u32 pack_id) ++{ ++ int i; ++ u32 soc_id; ++ ++ soc_id = (die_id << 16) | (pack_id); ++ for (i = 0; i < ARRAY_SIZE(soc_ids); i++) ++ if (soc_id == soc_ids[i].id) ++ return soc_ids[i].name; ++ ++ /* the soc id is unkown */ ++ return soc_ids[0].name; ++} ++ ++static int socinfo_get_nvparam(struct device *dev, char *cell_name, char *val, size_t size) ++{ ++ size_t bytes; ++ void *buf; ++ struct nvmem_cell *cell; ++ ++ cell = devm_nvmem_cell_get(dev, cell_name); ++ if (IS_ERR(cell)) { ++ dev_err(dev, "devm_nvmem_cell_get %s failed\n", cell_name); ++ return PTR_ERR(cell); ++ } ++ buf = nvmem_cell_read(cell, &bytes); ++ if (IS_ERR(buf)) { ++ dev_err(dev, "nvmem_cell_read %s failed\n", cell_name); ++ return PTR_ERR(buf); ++ } ++ ++ WARN_ON(size < bytes); ++ if (bytes > size) { ++ dev_err(dev, "buffer size is not enough for get %s\n", cell_name); ++ bytes = size; ++ } ++ memcpy(val, buf, bytes); ++ ++ kfree(buf); ++ ++ return bytes; ++} ++ ++static int spacemit_get_soc_info(struct device *dev) ++{ ++ int size; ++ ++ memset(&soc_info, 0, sizeof(soc_info)); ++ size = socinfo_get_nvparam(dev, "soc_die_id", ++ (char *)&soc_info.die_id, sizeof(soc_info.die_id)); ++ if (size <= 0) { ++ dev_err(dev, "try to get soc_die_id from efuse failed\n"); ++ } ++ ++ size = socinfo_get_nvparam(dev, "soc_ver_id", ++ (char *)&soc_info.ver_id, sizeof(soc_info.ver_id)); ++ if (size <= 0) { ++ dev_err(dev, "try to get soc_ver_id from efuse failed\n"); ++ } ++ ++ size = socinfo_get_nvparam(dev, "soc_pack_id", ++ (char *)&soc_info.pack_id, sizeof(soc_info.pack_id)); ++ if (size <= 0) { ++ dev_err(dev, "try to get soc_pack_id from efuse failed\n"); ++ } ++ ++ size = socinfo_get_nvparam(dev, "soc_svt_dro", ++ (char *)&soc_info.svtdro, sizeof(soc_info.svtdro)); ++ if (size <= 0) { ++ dev_err(dev, "try to get soc_svt_dro from efuse failed\n"); ++ } ++ ++ size = socinfo_get_nvparam(dev, "soc_chip_id", ++ (char *)&soc_info.chipid, sizeof(soc_info.chipid)); ++ if (size <= 0) { ++ dev_err(dev, "try to get soc_chip_id from efuse failed\n"); ++ } ++ ++ soc_info.soc_id = (soc_info.die_id << 16) | soc_info.pack_id; ++ ++ return 0; ++} ++ ++ ++static int spacemit_socinfo_probe(struct platform_device *pdev) ++{ ++ struct soc_device_attribute *soc_dev_attr; ++ struct device *dev = &pdev->dev; ++ struct soc_device *soc_dev; ++ struct device_node *root; ++ int ret; ++ ++ ret = spacemit_get_soc_info(dev); ++ if (ret) { ++ dev_err(dev, "try to get soc info failed!\n"); ++ return -EINVAL; ++ } ++ ++ soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), ++ GFP_KERNEL); ++ if (!soc_dev_attr) { ++ return -ENOMEM; ++ } ++ ++ /* setup soc information */ ++ root = of_find_node_by_path("/"); ++ of_property_read_string(root, "model", &soc_dev_attr->machine); ++ of_node_put(root); ++ ++ soc_dev_attr->family = "spacemit socs"; ++ soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, ++ "%c", (soc_info.ver_id + 'A') & 0xff); ++ soc_dev_attr->soc_id = soc_id_to_chip_name(soc_info.die_id, ++ soc_info.ver_id, soc_info.pack_id); ++ soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", ++ soc_info.chipid); ++ ++ /* please note that the actual registration will be deferred */ ++ soc_dev = soc_device_register(soc_dev_attr); ++ if (IS_ERR(soc_dev)) { ++ return PTR_ERR(soc_dev); ++ } ++ platform_set_drvdata(pdev, soc_dev); ++ ++ dev_info(&pdev->dev, "Spacemit: CPU[%s] REV[%s] DRO[%u] Detected\n", ++ soc_dev_attr->soc_id, soc_dev_attr->revision, soc_info.svtdro); ++ ++ return 0; ++} ++ ++static int spacemit_socinfo_remove(struct platform_device *pdev) ++{ ++ struct soc_device *soc_dev = platform_get_drvdata(pdev); ++ ++ soc_device_unregister(soc_dev); ++ ++ return 0; ++} ++ ++static const struct of_device_id spacemit_socinfo_dt_match[] = { ++ { .compatible = "spacemit,socinfo-k1x", }, ++ { }, ++}; ++ ++static struct platform_driver spacemit_socinfo_driver = { ++ .driver = { ++ .name = "spacemit-socinfo", ++ .of_match_table = spacemit_socinfo_dt_match, ++ }, ++ ++ .probe = spacemit_socinfo_probe, ++ .remove = spacemit_socinfo_remove, ++}; ++module_platform_driver(spacemit_socinfo_driver); ++ ++MODULE_DESCRIPTION("Spacemit soc information driver"); ++MODULE_LICENSE("GPL v2"); +\ No newline at end of file +diff --git a/drivers/usb/dwc3/dwc3-spacemit.c b/drivers/usb/dwc3/dwc3-spacemit.c +index 9744c10731d1..eb9107e58ac8 100644 +--- a/drivers/usb/dwc3/dwc3-spacemit.c ++++ b/drivers/usb/dwc3/dwc3-spacemit.c +@@ -4,7 +4,6 @@ + * + * Copyright (c) 2023 Spacemit Co., Ltd. + * +- * Author: Wilson + */ + + #include +@@ -18,9 +17,33 @@ + #include + #include + #include ++#include ++ ++#define DWC3_LFPS_WAKE_STATUS (1 << 29) ++#define DWC3_CDWS_WAKE_STATUS (1 << 28) ++#define DWC3_ID_WAKE_STATUS (1 << 27) ++#define DWC3_VBUS_WAKE_STATUS (1 << 26) ++#define DWC3_LINS1_WAKE_STATUS (1 << 25) ++#define DWC3_LINS0_WAKE_STATUS (1 << 24) ++ ++#define DWC3_CDWS_WAKE_CLEAR (1 << 20) ++#define DWC3_ID_WAKE_CLEAR (1 << 19) ++#define DWC3_VBUS_WAKE_CLEAR (1 << 18) ++#define DWC3_LINS1_WAKE_CLEAR (1 << 17) ++#define DWC3_LINS0_WAKE_CLEAR (1 << 16) ++#define DWC3_LFPS_WAKE_CLEAR (1 << 14) ++ ++#define DWC3_WAKEUP_INT_MASK (1 << 15) ++#define DWC3_LFPS_WAKE_MASK (1 << 13) ++#define DWC3_CDWS_WAKE_MASK (1 << 12) ++#define DWC3_ID_WAKE_MASK (1 << 11) ++#define DWC3_VBUS_WAKE_MASK (1 << 10) ++#define DWC3_LINS1_WAKE_MASK (1 << 9) ++#define DWC3_LINS0_WAKE_MASK (1 << 8) + + #define DWC3_SPACEMIT_MAX_CLOCKS 4 + ++ + struct dwc3_spacemit_driverdata { + const char *clk_names[DWC3_SPACEMIT_MAX_CLOCKS]; + int num_clks; +@@ -44,8 +67,44 @@ struct dwc3_spacemit { + struct phy *usb3_generic_phy; + + bool need_notify_disconnect; ++ int irq; ++ void __iomem *wakeup_reg; + }; + ++static void dwc3_spacemit_enable_wakeup_irqs(struct dwc3_spacemit *spacemit) ++{ ++ u32 reg; ++ reg = readl(spacemit->wakeup_reg); ++ reg |= (DWC3_LFPS_WAKE_MASK | DWC3_LINS0_WAKE_MASK | DWC3_WAKEUP_INT_MASK); ++ writel(reg, spacemit->wakeup_reg); ++} ++ ++static void dwc3_spacemit_disable_wakeup_irqs(struct dwc3_spacemit *spacemit) ++{ ++ u32 reg; ++ reg = readl(spacemit->wakeup_reg); ++ reg &= ~(DWC3_LFPS_WAKE_MASK | DWC3_LINS0_WAKE_MASK | DWC3_WAKEUP_INT_MASK); ++ writel(reg, spacemit->wakeup_reg); ++} ++ ++static void dwc3_spacemit_clear_wakeup_irqs(struct dwc3_spacemit *spacemit) ++{ ++ u32 reg; ++ reg = readl(spacemit->wakeup_reg); ++ dev_dbg(spacemit->dev, "wakeup_reg: 0x%x\n", reg); ++ reg |= (DWC3_LFPS_WAKE_CLEAR | DWC3_LINS0_WAKE_CLEAR); ++ writel(reg, spacemit->wakeup_reg); ++} ++ ++static irqreturn_t dwc3_spacemit_wakeup_interrupt(int irq, void *_spacemit) ++{ ++ struct dwc3_spacemit *spacemit = _spacemit; ++ dwc3_spacemit_disable_wakeup_irqs(spacemit); ++ dwc3_spacemit_clear_wakeup_irqs(spacemit); ++ ++ return IRQ_HANDLED; ++} ++ + void dwc3_spacemit_clear_disconnect(struct device *dev) + { + struct platform_device *pdev; +@@ -184,6 +243,7 @@ static int dwc3_spacemit_probe(struct platform_device *pdev) + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + const struct dwc3_spacemit_driverdata *driver_data; ++ struct resource *res; + int i, ret; + + spacemit = devm_kzalloc(dev, sizeof(*spacemit), GFP_KERNEL); +@@ -200,6 +260,24 @@ static int dwc3_spacemit_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, spacemit); + ++ spacemit->irq = platform_get_irq(pdev, 0); ++ if (spacemit->irq < 0) { ++ dev_err(dev, "missing IRQ resource\n"); ++ return -EINVAL; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(dev, "missing wakeup base resource\n"); ++ return -ENODEV; ++ } ++ ++ spacemit->wakeup_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); ++ if (!spacemit->wakeup_reg) { ++ dev_err(dev, " wakeup reg ioremap failed\n"); ++ return -ENODEV; ++ } ++ + for (i = 0; i < spacemit->num_clks; i++) { + spacemit->clks[i] = devm_clk_get(dev, spacemit->clk_names[i]); + if (IS_ERR(spacemit->clks[i])) { +@@ -238,8 +316,20 @@ static int dwc3_spacemit_probe(struct platform_device *pdev) + goto populate_err; + } + ++ ret = devm_request_irq(dev, spacemit->irq, dwc3_spacemit_wakeup_interrupt, IRQF_NO_SUSPEND, ++ "dwc3-usb-wakeup", spacemit); ++ if (ret) { ++ dev_err(dev, "failed to request IRQ #%d --> %d\n", ++ spacemit->irq, ret); ++ goto irq_err; ++ } ++ ++ device_init_wakeup(dev, true); ++ dev_pm_set_wake_irq(dev, spacemit->irq); + return 0; + ++irq_err: ++ of_platform_depopulate(&pdev->dev); + populate_err: + dwc3_spacemit_exit(spacemit); + return ret; +@@ -249,6 +339,9 @@ static int dwc3_spacemit_remove(struct platform_device *pdev) + { + struct dwc3_spacemit *spacemit = platform_get_drvdata(pdev); + ++ dwc3_spacemit_disable_wakeup_irqs(spacemit); ++ dev_pm_clear_wake_irq(spacemit->dev); ++ device_init_wakeup(spacemit->dev, false); + of_platform_depopulate(&pdev->dev); + dwc3_spacemit_exit(spacemit); + +@@ -298,6 +391,8 @@ static int dwc3_spacemit_suspend(struct device *dev) + for (i = spacemit->num_clks - 1; i >= 0; i--) + clk_disable_unprepare(spacemit->clks[i]); + ++ dwc3_spacemit_clear_wakeup_irqs(spacemit); ++ dwc3_spacemit_enable_wakeup_irqs(spacemit); + return 0; + } + +@@ -346,6 +441,5 @@ static struct platform_driver dwc3_spacemit_driver = { + + module_platform_driver(dwc3_spacemit_driver); + +-MODULE_AUTHOR("Wilson "); + MODULE_LICENSE("GPL v2"); + MODULE_DESCRIPTION("DesignWare USB3 Spacemit Glue Layer"); +diff --git a/drivers/usb/host/ehci-k1x-ci.c b/drivers/usb/host/ehci-k1x-ci.c +index 57af956a24bd..dcea1a11306c 100644 +--- a/drivers/usb/host/ehci-k1x-ci.c ++++ b/drivers/usb/host/ehci-k1x-ci.c +@@ -22,23 +22,44 @@ + #include + #include + #include ++#include + +-#define CAPLENGTH_MASK (0xff) ++#define CAPLENGTH_MASK (0xff) ++ ++#define USB_CDWS_WAKE_STATUS (1 << 28) ++#define USB_ID_WAKE_STATUS (1 << 27) ++#define USB_VBUS_WAKE_STATUS (1 << 26) ++#define USB_LINS1_WAKE_STATUS (1 << 25) ++#define USB_LINS0_WAKE_STATUS (1 << 24) ++ ++#define USB_VBUS_DRV (1 << 21) ++ ++#define USB_CDWS_WAKE_CLEAR (1 << 20) ++#define USB_ID_WAKE_CLEAR (1 << 19) ++#define USB_VBUS_WAKE_CLEAR (1 << 18) ++#define USB_LINS1_WAKE_CLEAR (1 << 17) ++#define USB_LINS0_WAKE_CLEAR (1 << 16) ++ ++#define USB_WAKEUP_INT_MASK (1 << 15) ++#define USB_CDWS_WAKE_MASK (1 << 12) ++#define USB_ID_WAKE_MASK (1 << 11) ++#define USB_VBUS_WAKE_MASK (1 << 10) ++#define USB_LINS1_WAKE_MASK (1 << 9) ++#define USB_LINS0_WAKE_MASK (1 << 8) + +-#define PMU_SD_ROT_WAKE_CLR 0x7C +-#define PMU_SD_ROT_WAKE_CLR_VBUS_DRV (0x1 << 21) + + struct ehci_hcd_mv { + struct usb_hcd *hcd; + struct usb_phy *phy; ++ struct device *dev; + + /* Which mode does this ehci running OTG/Host ? */ + int mode; + + void __iomem *cap_regs; + void __iomem *op_regs; +- void __iomem *apmu_base; +- ++ void __iomem *wakeup_reg; ++ int irq; + struct usb_phy *otg; + + struct mv_usb_platform_data *pdata; +@@ -50,34 +71,88 @@ struct ehci_hcd_mv { + bool reset_on_resume; + }; + +-static int ehci_otg_enable(struct device *dev, struct ehci_hcd_mv *ehci_mv, bool enable) ++static void mv_ehci_enable_wakeup_irqs(struct ehci_hcd_mv *ehci_mv) + { +- uint32_t temp; ++ u32 reg; ++ reg = readl(ehci_mv->wakeup_reg); ++ reg |= (USB_LINS0_WAKE_MASK | USB_LINS1_WAKE_MASK); ++ writel(reg, ehci_mv->wakeup_reg); ++} + +- temp = readl(ehci_mv->apmu_base + PMU_SD_ROT_WAKE_CLR); +- if (enable) +- writel(PMU_SD_ROT_WAKE_CLR_VBUS_DRV | temp, ehci_mv->apmu_base + PMU_SD_ROT_WAKE_CLR); +- else +- writel(temp & ~PMU_SD_ROT_WAKE_CLR_VBUS_DRV , ehci_mv->apmu_base + PMU_SD_ROT_WAKE_CLR); ++static void mv_ehci_disable_wakeup_irqs(struct ehci_hcd_mv *ehci_mv) ++{ ++ u32 reg; ++ reg = readl(ehci_mv->wakeup_reg); ++ reg &= ~(USB_LINS0_WAKE_MASK | USB_LINS1_WAKE_MASK); ++ writel(reg, ehci_mv->wakeup_reg); ++} + +- return 0; ++static void mv_ehci_clear_wakeup_irqs(struct ehci_hcd_mv *ehci_mv) ++{ ++ u32 reg; ++ reg = readl(ehci_mv->wakeup_reg); ++ dev_dbg(ehci_mv->dev, "wakeup_reg: 0x%x\n", reg); ++ reg |= (USB_LINS0_WAKE_CLEAR | USB_LINS1_WAKE_CLEAR); ++ writel(reg, ehci_mv->wakeup_reg); + } + +-static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv) ++static irqreturn_t mv_ehci_wakeup_interrupt(int irq, void *_ehci_mv) + { +- clk_enable(ehci_mv->clk); ++ struct ehci_hcd_mv *ehci_mv = _ehci_mv; ++ mv_ehci_disable_wakeup_irqs(ehci_mv); ++ mv_ehci_clear_wakeup_irqs(ehci_mv); ++ ++ return IRQ_HANDLED; ++} ++ ++static int mv_ehci_setvbus(struct ehci_hcd_mv *ehci_mv, bool enable) ++{ ++ u32 reg; ++ reg = readl(ehci_mv->wakeup_reg); ++ if (enable) ++ reg |= USB_VBUS_DRV; ++ else ++ reg &= ~USB_VBUS_DRV; ++ writel(reg, ehci_mv->wakeup_reg); ++ return 0; + } + +-static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv) ++static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv) + { +- clk_disable(ehci_mv->clk); ++ int ret; ++ ++ ret = clk_prepare_enable(ehci_mv->clk); ++ if (ret){ ++ dev_err(ehci_mv->dev, "Failed to enable clock\n"); ++ return ret; ++ } ++ ++ ret = reset_control_deassert(ehci_mv->reset); ++ if (ret){ ++ dev_err(ehci_mv->dev, "Failed to deassert reset control\n"); ++ goto err_clk; ++ } ++ ++ ret = usb_phy_init(ehci_mv->phy); ++ if (ret) { ++ dev_err(ehci_mv->dev, "Failed to init phy\n"); ++ goto err_reset; ++ } ++ ++ return 0; ++ ++err_reset: ++ reset_control_assert(ehci_mv->reset); ++err_clk: ++ clk_disable_unprepare(ehci_mv->clk); ++ return ret; + } + + static void mv_ehci_disable(struct ehci_hcd_mv *ehci_mv) + { + usb_phy_shutdown(ehci_mv->phy); + reset_control_assert(ehci_mv->reset); +- ehci_clock_disable(ehci_mv); ++ clk_disable_unprepare(ehci_mv->clk); + } + + static int mv_ehci_reset(struct usb_hcd *hcd) +@@ -178,7 +253,6 @@ static int mv_ehci_probe(struct platform_device *pdev) + { + struct mv_usb_platform_data *pdata; + struct device *dev = &pdev->dev; +- struct device_node *node; + struct usb_hcd *hcd; + struct ehci_hcd *ehci; + struct ehci_hcd_mv *ehci_mv; +@@ -221,6 +295,7 @@ static int mv_ehci_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, ehci_mv); + ehci_mv->pdata = pdata; + ehci_mv->hcd = hcd; ++ ehci_mv->dev = dev; + ehci_mv->reset_on_resume = of_property_read_bool(pdev->dev.of_node, + "spacemit,reset-on-resume"); + +@@ -230,7 +305,6 @@ static int mv_ehci_probe(struct platform_device *pdev) + retval = PTR_ERR(ehci_mv->clk); + goto err_clear_drvdata; + } +- clk_prepare(ehci_mv->clk); + + ehci_mv->reset = devm_reset_control_array_get_optional_shared(&pdev->dev); + if (IS_ERR(ehci_mv->reset)) { +@@ -262,24 +336,15 @@ static int mv_ehci_probe(struct platform_device *pdev) + else { + kfree(hcd->bandwidth_mutex); + kfree(hcd); +- + return -EPROBE_DEFER; + } + goto err_clear_drvdata; + } + +- ehci_clock_enable(ehci_mv); +- +- retval = reset_control_deassert(ehci_mv->reset); +- if (retval) { +- dev_err(&pdev->dev, "reset error %d\n", retval); +- goto err_disable_clk_rst; +- } +- +- retval = usb_phy_init(ehci_mv->phy); ++ retval = mv_ehci_enable(ehci_mv); + if (retval) { +- dev_err(&pdev->dev, "init phy error %d\n", retval); +- goto err_disable_clk_rst; ++ dev_err(&pdev->dev, "enable ehci error: %d\n", retval); ++ goto err_clear_drvdata; + } + + offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK; +@@ -301,11 +366,17 @@ static int mv_ehci_probe(struct platform_device *pdev) + + ehci_mv->mode = pdata->mode; + +- node = of_find_compatible_node(NULL, NULL, "spacemit,spacemit-apmu"); +- BUG_ON(!node); +- ehci_mv->apmu_base = of_iomap(node, 0); +- if (ehci_mv->apmu_base == NULL) { +- dev_err(&pdev->dev, "failed to map apmu base memory\n"); ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!r) { ++ dev_err(dev, "missing wakeup base resource\n"); ++ retval = -ENODEV; ++ goto err_disable_clk_rst; ++ } ++ ++ ehci_mv->wakeup_reg = devm_ioremap(&pdev->dev, r->start, resource_size(r)); ++ if (!ehci_mv->wakeup_reg) { ++ dev_err(dev, " wakeup reg ioremap failed\n"); ++ retval = -ENODEV; + goto err_disable_clk_rst; + } + +@@ -314,7 +385,6 @@ static int mv_ehci_probe(struct platform_device *pdev) + ehci_mv->otg = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-otg", 0); + if (IS_ERR(ehci_mv->otg)) { + retval = PTR_ERR(ehci_mv->otg); +- + if (retval == -ENXIO) + dev_info(&pdev->dev, "MV_USB_MODE_OTG " + "must have CONFIG_USB_PHY enabled\n"); +@@ -334,7 +404,7 @@ static int mv_ehci_probe(struct platform_device *pdev) + /* otg will enable clock before use as host */ + mv_ehci_disable(ehci_mv); + } else { +- retval = ehci_otg_enable(dev, ehci_mv, 1); ++ retval = mv_ehci_setvbus(ehci_mv, 1); + if (retval) + goto err_disable_clk_rst; + +@@ -346,6 +416,24 @@ static int mv_ehci_probe(struct platform_device *pdev) + } + } + ++ ehci_mv->irq = platform_get_irq(pdev, 1); ++ if (!hcd->irq) { ++ dev_err(&pdev->dev, "Cannot get wake irq."); ++ retval = -ENODEV; ++ goto err_set_vbus; ++ } ++ ++ retval = devm_request_irq(dev, ehci_mv->irq, mv_ehci_wakeup_interrupt, IRQF_NO_SUSPEND, ++ "usb-wakeup", ehci_mv); ++ if (retval) { ++ dev_err(dev, "failed to request IRQ #%d --> %d\n", ++ ehci_mv->irq, retval); ++ goto err_set_vbus; ++ } ++ ++ device_init_wakeup(dev, true); ++ dev_pm_set_wake_irq(dev, ehci_mv->irq); ++ + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_suspend_ignore_children(dev, false); +@@ -359,7 +447,12 @@ static int mv_ehci_probe(struct platform_device *pdev) + return 0; + + err_set_vbus: +- ehci_otg_enable(dev, ehci_mv, 0); ++ if (!IS_ERR_OR_NULL(ehci_mv->otg)) ++ otg_set_host(ehci_mv->otg->otg, NULL); ++ if (ehci_mv->mode == MV_USB_MODE_HOST) { ++ usb_remove_hcd(hcd); ++ mv_ehci_setvbus(ehci_mv, 0); ++ } + err_disable_clk_rst: + mv_ehci_disable(ehci_mv); + err_clear_drvdata: +@@ -375,6 +468,10 @@ static int mv_ehci_remove(struct platform_device *pdev) + struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_mv->hcd; + ++ mv_ehci_disable_wakeup_irqs(ehci_mv); ++ dev_pm_clear_wake_irq(ehci_mv->dev); ++ device_init_wakeup(ehci_mv->dev, false); ++ + if (hcd->rh_registered) + usb_remove_hcd(hcd); + +@@ -382,11 +479,11 @@ static int mv_ehci_remove(struct platform_device *pdev) + otg_set_host(ehci_mv->otg->otg, NULL); + + if (ehci_mv->mode == MV_USB_MODE_HOST) { +- ehci_otg_enable(&pdev->dev, ehci_mv, 0); +- mv_ehci_disable(ehci_mv); +- clk_unprepare(ehci_mv->clk); ++ mv_ehci_setvbus(ehci_mv, 0); + } + ++ mv_ehci_disable(ehci_mv); ++ platform_set_drvdata(pdev, NULL); + usb_put_hcd(hcd); + + pm_runtime_disable(&pdev->dev); +@@ -439,6 +536,9 @@ static int mv_ehci_suspend(struct device *dev) + + clk_disable_unprepare(ehci_mv->clk); + dev_dbg(dev, "pm suspend: disable clks and phy\n"); ++ ++ mv_ehci_clear_wakeup_irqs(ehci_mv); ++ mv_ehci_enable_wakeup_irqs(ehci_mv); + return ret; + } + +@@ -465,7 +565,7 @@ static int mv_ehci_resume(struct device *dev) + ret = usb_phy_init(ehci_mv->phy); + if (ret) { + dev_err(dev, "Failed to init phy\n"); +- ehci_clock_disable(ehci_mv); ++ clk_disable_unprepare(ehci_mv->clk); + return ret; + } + dev_dbg(dev, "pm resume: do EHCI resume\n"); +diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h +index dc1fb5890792..b5618dd9b3b2 100644 +--- a/include/linux/pm_opp.h ++++ b/include/linux/pm_opp.h +@@ -157,6 +157,9 @@ int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb); + int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb); + + int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); ++#ifdef CONFIG_SOC_SPACEMIT ++int dev_pm_opp_set_config_indexed(struct device *dev, struct dev_pm_opp_config *config, int index); ++#endif + int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); + void dev_pm_opp_clear_config(int token); + int dev_pm_opp_config_clks_simple(struct device *dev, +diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c +index e2bebd53560e..6362e232f24b 100644 +--- a/sound/soc/codecs/es8326.c ++++ b/sound/soc/codecs/es8326.c +@@ -52,6 +52,7 @@ struct es8326_priv { + int mic_gpio; + int mic_irq; + struct delayed_work hpmic_detect_work; ++ unsigned int coeff; + #endif + }; + +@@ -264,6 +265,10 @@ static bool es8326_volatile_register(struct device *dev, unsigned int reg) + static const struct regmap_config es8326_regmap_config = { + .reg_bits = 8, + .val_bits = 8, ++#ifdef SPACEMIT_CONFIG_CODEC_ES8326 ++ .use_single_read = true, ++ .use_single_write = true, ++#endif + .max_register = 0xff, + .volatile_reg = es8326_volatile_register, + .cache_type = REGCACHE_RBTREE, +@@ -472,6 +477,9 @@ static int es8326_pcm_hw_params(struct snd_pcm_substream *substream, + } + + coeff = get_coeff(es8326->sysclk, params_rate(params), array, coeff_div); ++#ifdef SPACEMIT_CONFIG_CODEC_ES8326 ++ es8326->coeff = coeff; ++#endif + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: +@@ -520,6 +528,44 @@ static int es8326_pcm_hw_params(struct snd_pcm_substream *substream, + return 0; + } + ++#ifdef SPACEMIT_CONFIG_CODEC_ES8326 ++static int es8326_reset_clk(struct snd_soc_component *component) ++{ ++ const struct _coeff_div *coeff_div; ++ struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); ++ int coeff; ++ ++ if (es8326->version == 0) { ++ coeff_div = coeff_div_v0; ++ } else { ++ coeff_div = coeff_div_v3; ++ } ++ coeff = es8326->coeff; ++ if (coeff >= 0) { ++ regmap_write(es8326->regmap, ES8326_CLK_DIV1, ++ coeff_div[coeff].reg4); ++ regmap_write(es8326->regmap, ES8326_CLK_DIV2, ++ coeff_div[coeff].reg5); ++ regmap_write(es8326->regmap, ES8326_CLK_DLL, ++ coeff_div[coeff].reg6); ++ regmap_write(es8326->regmap, ES8326_CLK_MUX, ++ coeff_div[coeff].reg7); ++ regmap_write(es8326->regmap, ES8326_CLK_ADC_SEL, ++ coeff_div[coeff].reg8); ++ regmap_write(es8326->regmap, ES8326_CLK_DAC_SEL, ++ coeff_div[coeff].reg9); ++ regmap_write(es8326->regmap, ES8326_CLK_ADC_OSR, ++ coeff_div[coeff].rega); ++ regmap_write(es8326->regmap, ES8326_CLK_DAC_OSR, ++ coeff_div[coeff].regb); ++ } else { ++ dev_warn(component->dev, "Clock coefficients do not match"); ++ } ++ ++ return 0; ++} ++#endif ++ + static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) + { + struct snd_soc_component *component = dai->component; +@@ -819,7 +865,9 @@ static void es8326_jack_detect_handler(struct work_struct *work) + * Don't report jack status. + */ + regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); ++ #ifndef SPACEMIT_CONFIG_CODEC_ES8326 + es8326_enable_micbias(es8326->component); ++ #endif + usleep_range(50000, 70000); + regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); + regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x1f); +@@ -832,7 +880,11 @@ static void es8326_jack_detect_handler(struct work_struct *work) + #endif + goto exit; + } ++ #ifdef SPACEMIT_CONFIG_CODEC_ES8326 ++ if ((es8326->jack->status & SND_JACK_HEADSET) == SND_JACK_HEADSET) { ++ #else + if (es8326->jack->status & SND_JACK_HEADSET) { ++ #endif + /* detect button */ + dev_dbg(comp->dev, "button pressed\n"); + queue_delayed_work(system_wq, &es8326->button_press_work, 10); +@@ -909,7 +961,6 @@ static void es8326_hpmic_detect_handler(struct work_struct *work) + } else { + if (es8326->hp == 0) { + regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); +- es8326_enable_micbias(es8326->component); + usleep_range(50000, 70000); + regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); + regmap_write(es8326->regmap, ES8326_SYS_BIAS, 0x1f); +@@ -1090,18 +1141,37 @@ static int es8326_resume(struct snd_soc_component *component) + + regcache_cache_only(es8326->regmap, false); + regcache_sync(es8326->regmap); +- if (es8326->jack) +- es8326_irq(es8326->irq, es8326); ++ es8326_init(component); ++ es8326_reset_clk(component); ++ if (es8326->jack) { ++ snd_soc_jack_report(es8326->jack, 0, SND_JACK_HEADSET); ++ if (es8326->jd_inverted) { ++ snd_soc_component_update_bits(component, ES8326_HPDET_TYPE, ++ ES8326_HP_DET_JACK_POL, ~es8326->jack_pol); ++ } ++ es8326_disable_micbias(component); ++ if (es8326->irq > 0) ++ es8326_irq(es8326->irq, es8326); ++ else ++ es8326_irq_hpmic(es8326->irq, es8326); ++ } + return 0; + } ++ + static int es8326_suspend(struct snd_soc_component *component) + { + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + + cancel_delayed_work_sync(&es8326->jack_detect_work); ++ es8326->calibrated = false; ++ regmap_write(es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_OFF); + regcache_cache_only(es8326->regmap, true); + regcache_mark_dirty(es8326->regmap); + ++ /* reset register value to default */ ++ regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x01); ++ usleep_range(1000, 3000); ++ regmap_write(es8326->regmap, ES8326_CSM_I2C_STA, 0x00); + return 0; + } + #else +-- +2.39.2 + diff --git a/patch/kernel/archive/spacemit-6.1/060-update-to-v1.0.8.patch b/patch/kernel/archive/spacemit-6.1/060-update-to-v1.0.8.patch new file mode 100644 index 000000000000..15afc4b12390 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.1/060-update-to-v1.0.8.patch @@ -0,0 +1,443 @@ +From 05bebc19949413beb180f86c3efb10957713658a Mon Sep 17 00:00:00 2001 +From: Patrick Yavitz +Date: Tue, 16 Jul 2024 08:47:05 -0400 +Subject: [PATCH] update to v1.0.8 + +source: https://gitee.com/bianbu-linux/linux-6.1 + +Signed-off-by: James Deng +Signed-off-by: Patrick Yavitz +--- + drivers/cpufreq/spacemit-cpufreq.c | 35 +++- + drivers/crypto/spacemit/spacemit_ce_engine.c | 13 +- + drivers/i2c/busses/i2c-k1x.c | 5 +- + drivers/pwm/pwm-pxa.c | 6 +- + .../soc/spacemit/pm_domain/k1x-pm_domain.c | 8 + + drivers/usb/phy/Makefile | 2 +- + scripts/package/generic | 16 ++ + sound/soc/spacemit/spacemit-snd-pcm-dma.c | 150 +++++++----------- + 8 files changed, 124 insertions(+), 111 deletions(-) + create mode 100644 scripts/package/generic + +diff --git a/drivers/cpufreq/spacemit-cpufreq.c b/drivers/cpufreq/spacemit-cpufreq.c +index 52d40d7f25fe..ce81b344a1c6 100644 +--- a/drivers/cpufreq/spacemit-cpufreq.c ++++ b/drivers/cpufreq/spacemit-cpufreq.c +@@ -36,9 +36,15 @@ of_hotplug_cooling_register(struct cpufreq_policy *policy); + + #define TURBO_FREQUENCY (1600000000) + #define STABLE_FREQUENCY (1200000000) +-#define FILTER_POINTS (140) ++ ++#define FILTER_POINTS_0 (135) ++#define FILTER_POINTS_1 (142) ++ + #define FREQ_TABLE_0 (0) + #define FREQ_TABLE_1 (1) ++#define FREQ_TABLE_2 (2) ++ ++#define PRODUCT_ID_M1 (0x36070000) + + static int spacemit_policy_notifier(struct notifier_block *nb, + unsigned long event, void *data) +@@ -390,7 +396,9 @@ static int spacemit_dt_cpufreq_pre_probe(struct platform_device *pdev) + { + int cpu; + struct device_node *cpus; ++ struct device_node *product_id, *wafer_id; + u32 prop = 0; ++ u32 product_prop, wafer_prop; + + if (strncmp(pdev->name, "cpufreq-dt", 10) != 0) + return 0; +@@ -400,8 +408,29 @@ static int spacemit_dt_cpufreq_pre_probe(struct platform_device *pdev) + pr_info("Spacemit Platform with no 'svt-dro' in DTS, using defualt frequency Table0\n"); + } + +- for_each_possible_cpu(cpu) { +- spacemit_dt_cpufreq_pre_early_init(&pdev->dev, cpu, prop >= FILTER_POINTS ? FREQ_TABLE_1 : FREQ_TABLE_0); ++ product_id = of_find_node_by_path("/"); ++ if (!product_id || of_property_read_u32(product_id, "product-id", &product_prop)) { ++ pr_info("Spacemit Platform with no 'product-id' in DTS\n"); ++ } ++ ++ wafer_id = of_find_node_by_path("/"); ++ if (!wafer_id || of_property_read_u32(product_id, "wafer-id", &wafer_prop)) { ++ pr_info("Spacemit Platform with no 'product-id' in DTS\n"); ++ } ++ ++ if ((wafer_prop << 16 | product_prop) == PRODUCT_ID_M1) { ++ for_each_possible_cpu(cpu) { ++ if (prop <= FILTER_POINTS_0) ++ spacemit_dt_cpufreq_pre_early_init(&pdev->dev, cpu, FREQ_TABLE_0); ++ else if (prop <= FILTER_POINTS_1) ++ spacemit_dt_cpufreq_pre_early_init(&pdev->dev, cpu, FREQ_TABLE_1); ++ else ++ spacemit_dt_cpufreq_pre_early_init(&pdev->dev, cpu, FREQ_TABLE_2); ++ } ++ } else { ++ for_each_possible_cpu(cpu) { ++ spacemit_dt_cpufreq_pre_early_init(&pdev->dev, cpu, FREQ_TABLE_0); ++ } + } + + return 0; +diff --git a/drivers/crypto/spacemit/spacemit_ce_engine.c b/drivers/crypto/spacemit/spacemit_ce_engine.c +index 8623eb4843dd..8ebdd842532b 100644 +--- a/drivers/crypto/spacemit/spacemit_ce_engine.c ++++ b/drivers/crypto/spacemit/spacemit_ce_engine.c +@@ -1733,6 +1733,12 @@ static int crypto_engine_probe(struct platform_device *pdev) + return -ENODEV; + } + ++ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ dev_err(dev, "Unable to set dma mask\n"); ++ return ret; ++ } ++ + in_buffer = dma_alloc_noncoherent(dev, SPACEMIT_AES_BUFFER_LEN, &dma_addr_in, DMA_TO_DEVICE, GFP_KERNEL); + out_buffer = dma_alloc_noncoherent(dev, SPACEMIT_AES_BUFFER_LEN, &dma_addr_out, DMA_FROM_DEVICE, GFP_KERNEL); + ctrl = kmalloc(sizeof(struct aes_clk_reset_ctrl), GFP_KERNEL); +@@ -1829,13 +1835,6 @@ static int crypto_engine_probe(struct platform_device *pdev) + return ret; + } + +- +- ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); +- if (ret) { +- dev_err(dev, "Unable to set dma mask\n"); +- return ret; +- } +- + #ifdef CONFIG_SPACEMIT_CRYPTO_SELF_TEST + ce_aes_test(num_engines); + #endif +diff --git a/drivers/i2c/busses/i2c-k1x.c b/drivers/i2c/busses/i2c-k1x.c +index eda79cfb2422..f0b6e9d36fe3 100644 +--- a/drivers/i2c/busses/i2c-k1x.c ++++ b/drivers/i2c/busses/i2c-k1x.c +@@ -1245,15 +1245,12 @@ spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg msgs[], int num) + * software power down command to pmic via i2c interface + * with local irq disabled, so just enter PIO mode at once + */ +- if (unlikely(irqs_disabled() ++ if (unlikely(spacemit_i2c_restart_notify == true + #ifdef CONFIG_DEBUG_FS + || spacemit_i2c->dbgfs_mode == SPACEMIT_I2C_MODE_PIO + #endif + )) { + +- if(!spacemit_i2c_restart_notify) +- dev_warn(spacemit_i2c->dev, "%s: i2c transfer called with irq off!\n", __func__); +- + spacemit_i2c->msgs = msgs; + spacemit_i2c->num = num; + +diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c +index 4fd778f7a608..a571c207c1a9 100644 +--- a/drivers/pwm/pwm-pxa.c ++++ b/drivers/pwm/pwm-pxa.c +@@ -308,10 +308,6 @@ static struct platform_driver pwm_driver = { + .id_table = pwm_id_table, + }; + +-static int k1x_pwm_driver_init(void) +-{ +- return platform_driver_register(&pwm_driver); +-} +-late_initcall_sync(k1x_pwm_driver_init); ++module_platform_driver(pwm_driver); + + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c b/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c +index de03e2e2e5d9..5cb23eb36019 100644 +--- a/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c ++++ b/drivers/soc/spacemit/pm_domain/k1x-pm_domain.c +@@ -45,6 +45,9 @@ + /* gpio */ + #define WAKEUP_SOURCE_WAKEUP_2 2 + ++/* usb & others */ ++#define WAKEUP_SOURCE_WAKEUP_5 5 ++ + #define PM_QOS_BLOCK_C1 0x0 /* core wfi */ + #define PM_QOS_BLOCK_C2 0x2 /* core power off */ + #define PM_QOS_BLOCK_M2 0x6 /* core l2 off */ +@@ -818,6 +821,11 @@ static int acpr_per_suspend(void) + apcr_per |= (1 << WAKEUP_SOURCE_WAKEUP_2); + regmap_write(gpmu->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, apcr_per); + ++ /* enable usb/rcpu/ap2audio */ ++ regmap_read(gpmu->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, &apcr_per); ++ apcr_per |= (1 << WAKEUP_SOURCE_WAKEUP_5); ++ regmap_write(gpmu->regmap[MPMU_REGMAP_INDEX], MPMU_AWUCRM_REG, apcr_per); ++ + return 0; + } + +diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile +index 01b40aa3f8b7..b6d549df71f4 100644 +--- a/drivers/usb/phy/Makefile ++++ b/drivers/usb/phy/Makefile +@@ -25,5 +25,5 @@ obj-$(CONFIG_USB_ULPI) += phy-ulpi.o + obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o + obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o + obj-$(CONFIG_JZ4770_PHY) += phy-jz4770.o +-obj-$(CONFIG_USB_K1XCI_OTG) += phy-k1x-ci-otg.o + obj-$(CONFIG_K1XCI_USB2_PHY) += phy-k1x-ci-usb2.o ++obj-$(CONFIG_USB_K1XCI_OTG) += phy-k1x-ci-otg.o +diff --git a/scripts/package/generic b/scripts/package/generic +new file mode 100644 +index 000000000000..3b0286cd0e5a +--- /dev/null ++++ b/scripts/package/generic +@@ -0,0 +1,16 @@ ++#!/bin/bash ++full_version=`uname -r` ++ ++# First check for a fully qualified version. ++this="/usr/lib/linux-tools/$full_version/`basename $0`" ++if [ -f "$this" ]; then ++ exec "$this" "$@" ++fi ++ ++# Give them a hint as to what to install. ++echo "WARNING: `basename $0` not found for kernel $full_version" >&2 ++echo "" >&2 ++echo " You may need to install the following packages for this specific kernel:" >&2 ++echo " linux-tools-$full_version" >&2 ++ ++exit 2 +\ No newline at end of file +diff --git a/sound/soc/spacemit/spacemit-snd-pcm-dma.c b/sound/soc/spacemit/spacemit-snd-pcm-dma.c +index 4dbd81098f7f..192927837cf6 100644 +--- a/sound/soc/spacemit/spacemit-snd-pcm-dma.c ++++ b/sound/soc/spacemit/spacemit-snd-pcm-dma.c +@@ -34,32 +34,18 @@ + #define HDMI_TXDATA 0x80 + #define HDMI_PERIOD_SIZE 480 + +-#define L_CH 0 +-#define R_CH 1 + #define SAMPLE_PRESENT_FLAG_OFFSET 31 + #define AUDIO_FRAME_START_BIT_OFFSET 30 +-#define SAMPLE_FLAT_BIT_OFFSET 29 +-#define NOT_USED_OFFSET 28 + #define PARITY_BIT_OFFSET 27 + #define CHANNEL_STATUS_OFFSET 26 +-#define USER_DATA_OFFSET 25 + #define VALID_OFFSET 24 + +-#define IEC958_AES0_CONSUMER (0<<0) /* 0 = consumer, 1 = professional */ +-#define IEC958_AES0_AUDIO (0<<1) /* 0 = audio, 1 = non-audio */ +-#define IEC958_AES3_CON_FS_48000 (2<<0) /* 48kHz */ +-#define IEC958_AES0_CON_NOT_COPYRIGHT (1<<2) /* 0 = copyright, 1 = not copyright */ +-#define IEC958_AES0_CON_EMPHASIS_NONE (0<<3) /* none emphasis */ +-#define IEC958_AES1_CON_GENERAL (0x00) +-#define IEC958_AES2_CON_SOURCE_UNSPEC (0<<0) /* unspecified */ +-#define IEC958_AES2_CON_CHANNEL_UNSPEC (0<<4) /* unspecified */ +-#define IEC958_AES3_CON_CLOCK_1000PPM (0<<4) /* 1000 ppm */ +-#define IEC958_AES4_CON_WORDLEN_24_20 (5<<1) /* 24-bit or 20-bit */ +-#define IEC958_AES4_CON_MAX_WORDLEN_24 (1<<0) /* 0 = 20-bit, 1 = 24-bit */ +- + #define CS_CTRL1 ((1 << SAMPLE_PRESENT_FLAG_OFFSET) | (1 << AUDIO_FRAME_START_BIT_OFFSET)) + #define CS_CTRL2 ((1 << SAMPLE_PRESENT_FLAG_OFFSET) | (0 << AUDIO_FRAME_START_BIT_OFFSET)) + ++#define CS_SAMPLING_FREQUENCY 25 ++#define CS_MAX_SAMPLE_WORD 32 ++ + #define P2(n) n, n^1, n^1, n + #define P4(n) P2(n), P2(n^1), P2(n^1), P2(n) + #define P6(n) P4(n), P4(n^1), P4(n^1), P4(n) +@@ -96,11 +82,9 @@ struct hdmi_codec_priv { + uint32_t srate; + uint32_t channels; + uint8_t iec_offset; +- uint8_t ch_sn; +- uint8_t cs[24]; + }; + +-struct hdmi_codec_priv hdmi_ptr = {0}; ++static struct hdmi_codec_priv hdmi_ptr = {0}; + static const bool ParityTable256[256] = + { + P6(0), P6(1), P6(1), P6(0) +@@ -567,8 +551,12 @@ static int spacemit_snd_pcm_trigger(struct snd_soc_component *component, struct + case SNDRV_PCM_TRIGGER_SUSPEND: + if (runtime->info & SNDRV_PCM_INFO_PAUSE) + dmaengine_pause(dmadata->dma_chan); +- else ++ else { + dmaengine_terminate_async(dmadata->dma_chan); ++ dmadata->playback_data = 0; ++ dmadata->pos = 0; ++ spacemit_update_stream_status(dev, dmadata->stream, false); ++ } + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: +@@ -623,18 +611,7 @@ spacemit_snd_pcm_hdmi_pointer(struct snd_soc_component *component, struct snd_pc + struct spacemit_snd_dmadata *dmadata = substream->runtime->private_data; + return bytes_to_frames(substream->runtime, dmadata->pos); + } +-static void hdmi_create_cs(struct hdmi_codec_priv *hdmi_priv) +-{ +- uint8_t *cs; +- memset(hdmi_priv->cs, 0, sizeof(hdmi_priv->cs)); +- cs = hdmi_priv->cs; +- cs[0] = IEC958_AES0_CONSUMER | IEC958_AES0_AUDIO | IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE; +- cs[1] = IEC958_AES1_CON_GENERAL; +- cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC; +- cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | IEC958_AES3_CON_FS_48000; +- cs[4] = IEC958_AES4_CON_WORDLEN_24_20 | IEC958_AES4_CON_MAX_WORDLEN_24; //24bits + +-} + static int spacemit_snd_pcm_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) + { + int ret = 0; +@@ -677,10 +654,8 @@ static int spacemit_snd_pcm_open(struct snd_soc_component *component, struct snd + substream->runtime->private_data = dmadata; + + if (dmadata->dma_id == DMA_HDMI) { +- hdmi_ptr.ch_sn = L_CH; + hdmi_ptr.iec_offset = 0; + hdmi_ptr.srate = 48000; +- hdmi_create_cs(&hdmi_ptr); + } + unlock: + spin_unlock_irqrestore(&dev->lock, flags); +@@ -704,7 +679,6 @@ static int spacemit_snd_pcm_close(struct snd_soc_component *component, struct sn + } + dmaengine_terminate_all(chan); + if (dmadata->dma_id == DMA_HDMI) { +- hdmi_ptr.ch_sn = L_CH; + hdmi_ptr.iec_offset = 0; + } + unlock: +@@ -830,72 +804,66 @@ static void spacemit_snd_pcm_remove(struct snd_soc_component *component) + dev->dmadata[i].dma_chan = NULL; + } + } +-static void hdmi_set_cs_channel_sn(struct hdmi_codec_priv *hdmi_priv) +-{ +- hdmi_priv->cs[2] &= 0x0f; +- if (hdmi_priv->ch_sn == L_CH) { +- hdmi_priv->cs[2] |= (0x1 << 4); +- hdmi_priv->ch_sn = R_CH; +- } else if (hdmi_priv->ch_sn == R_CH) { +- hdmi_priv->cs[2] |= (0x2 << 4); +- hdmi_priv->ch_sn = L_CH; +- } +-} + +-static uint32_t get_cs_bit(struct hdmi_codec_priv *hdmi_priv) ++static uint32_t parity_even(uint32_t sample) + { +- unsigned long tmp = 0; +- int cs_idx; +- int bit_idx; +- cs_idx = hdmi_priv->iec_offset >> 3; +- bit_idx = hdmi_priv->iec_offset - (cs_idx << 3); +- +- tmp = hdmi_priv->cs[cs_idx] >> bit_idx; +- +- return (uint32_t)tmp&0x1; ++ bool parity = 0; ++ sample ^= sample >> 16; ++ sample ^= sample >> 8; ++ parity = ParityTable256[sample & 0xff]; ++ if (parity) ++ return 1; ++ else ++ return 0; + } + +-static uint32_t parity_even(uint32_t sample) ++static int32_t cal_cs_status_48kHz(int32_t offset) + { +- bool parity = 0; +- sample ^= sample >> 16; +- sample ^= sample >> 8; +- parity = ParityTable256[sample & 0xff]; +- if (parity) +- return 1; +- else +- return 0; ++ if ((offset == CS_SAMPLING_FREQUENCY) || (offset == CS_MAX_SAMPLE_WORD)) ++ { ++ return 1; ++ } else { ++ return 0; ++ } + } + + static void hdmi_reformat(void *dst, void *src, int len) + { +- uint32_t *dst32 = (uint32_t *)dst; +- uint16_t *src16 = (uint16_t *)src; +- struct hdmi_codec_priv *dw = &hdmi_ptr; +- uint16_t frm_cnt = len; +- uint32_t ctrl; +- uint32_t sample,parity; +- dw->channels = 2; +- while (frm_cnt--) { +- for (int i = 0; i < dw->channels; i++) { +- hdmi_set_cs_channel_sn(dw); +- if (dw->iec_offset == 0) { +- ctrl = CS_CTRL1 | (get_cs_bit(dw) << CHANNEL_STATUS_OFFSET); +- } else { +- ctrl = CS_CTRL2 | (get_cs_bit(dw) << CHANNEL_STATUS_OFFSET); +- } +- +- sample = ((uint32_t)(*src16++) << 8)| ctrl; +- parity = parity_even(sample); +- sample = sample | (parity << PARITY_BIT_OFFSET); +- *dst32++ = sample; +- } +- +- dw->iec_offset++; +- if (dw->iec_offset >= 192){ +- dw->iec_offset = 0; ++ uint32_t *dst32 = (uint32_t *)dst; ++ uint16_t *src16 = (uint16_t *)src; ++ struct hdmi_codec_priv *dw = &hdmi_ptr; ++ uint16_t frm_cnt = len; ++ uint32_t ctrl; ++ uint32_t sample,parity; ++ dw->channels = 2; ++ while (frm_cnt--) { ++ for (int i = 0; i < dw->channels; i++) { ++ //bit 0-23 ++ sample = ((uint32_t)(*src16++) << 8); ++ //bit 24 ++ sample = sample | (1 << VALID_OFFSET); ++ //bit 26 ++ sample = sample | (cal_cs_status_48kHz(dw->iec_offset) << CHANNEL_STATUS_OFFSET); ++ //bit 27 ++ parity = parity_even(sample); ++ sample = sample | (parity << PARITY_BIT_OFFSET); ++ ++ //bit 30 31 ++ if (dw->iec_offset == 0) { ++ ctrl = CS_CTRL1; ++ } else { ++ ctrl = CS_CTRL2; ++ } ++ sample = sample | ctrl; ++ ++ *dst32++ = sample; + } +- }; ++ ++ dw->iec_offset++; ++ if (dw->iec_offset >= 192){ ++ dw->iec_offset = 0; ++ } ++ } + } + + static int spacemit_snd_pcm_copy(struct snd_soc_component *component, struct snd_pcm_substream *substream, int channel, +-- +2.39.2 + diff --git a/patch/kernel/archive/spacemit-6.1/061-REVERT-fixes-for-dtb-mapping.patch b/patch/kernel/archive/spacemit-6.1/061-REVERT-fixes-for-dtb-mapping.patch deleted file mode 100644 index d9906a097327..000000000000 --- a/patch/kernel/archive/spacemit-6.1/061-REVERT-fixes-for-dtb-mapping.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Patrick Yavitz -Date: Sat, 22 Jun 2024 15:32:30 -0400 -Subject: REVERT: Fixes for dtb mapping - -This breaks PCIe on the BPI-F3 so lets revert it until a solution is found. - -https://lore.kernel.org/lkml/mhng-4113481b-4c71-4b5c-ab7e-6896058f074b@palmer-ri-x1c9a/T/ -https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/diff/?id=v6.1.27&id2=v6.1.26&dt=2 - -[ 2.854097] spacemit-pmic-pinctrl spacemit-pinctrl@spm8821: DMA mask not set -[ 2.861747] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4 -[ 2.862556] k1x-dwc-pcie ca400000.pcie: has no power on gpio. -[ 2.862764] k1x-dwc-pcie ca400000.pcie: host bridge /soc/pcie@ca400000 ranges: -[ 2.862801] k1x-dwc-pcie ca400000.pcie: IO 0x009f002000..0x009f101fff -> 0x009f002000 -[ 2.862823] k1x-dwc-pcie ca400000.pcie: MEM 0x0090000000..0x009effffff -> 0x0090000000 -[ 2.862865] k1x-dwc-pcie ca400000.pcie: resource collision: [mem 0x90000000-0x9effffff] conflicts with Reserved [mem 0x80000000-0xc07fffff] -[ 2.872584] k1x-dwc-pcie ca400000.pcie: failed to initialize host -[ 2.878747] k1x-dwc-pcie: probe of ca400000.pcie failed with error -12 -[ 2.885725] k1x-dwc-pcie ca800000.pcie: has no power on gpio. -[ 2.885912] k1x-dwc-pcie ca800000.pcie: host bridge /soc/pcie@ca800000 ranges: -[ 2.885948] k1x-dwc-pcie ca800000.pcie: IO 0x00b7002000..0x00b7101fff -> 0x00b7002000 -[ 2.885969] k1x-dwc-pcie ca800000.pcie: MEM 0x00a0000000..0x00b6ffffff -> 0x00a0000000 -[ 2.885987] k1x-dwc-pcie ca800000.pcie: resource collision: [mem 0xa0000000-0xb6ffffff] conflicts with Reserved [mem 0x80000000-0xc07fffff] -[ 2.897922] k1x-dwc-pcie ca800000.pcie: failed to initialize host -[ 2.904083] k1x-dwc-pcie: probe of ca800000.pcie failed with error -12 - -Signed-off-by: Patrick Yavitz ---- - arch/riscv/include/asm/fixmap.h | 8 - - arch/riscv/include/asm/pgtable.h | 8 +- - arch/riscv/kernel/setup.c | 6 +- - arch/riscv/mm/init.c | 78 ++++++---- - 4 files changed, 52 insertions(+), 48 deletions(-) - -diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h -index 111111111111..222222222222 100644 ---- a/arch/riscv/include/asm/fixmap.h -+++ b/arch/riscv/include/asm/fixmap.h -@@ -22,14 +22,6 @@ - */ - enum fixed_addresses { - FIX_HOLE, -- /* -- * The fdt fixmap mapping must be PMD aligned and will be mapped -- * using PMD entries in fixmap_pmd in 64-bit and a PGD entry in 32-bit. -- */ -- FIX_FDT_END, -- FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1, -- -- /* Below fixmaps will be mapped using fixmap_pte */ - FIX_PTE, - FIX_PMD, - FIX_PUD, -diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h -index 111111111111..222222222222 100644 ---- a/arch/riscv/include/asm/pgtable.h -+++ b/arch/riscv/include/asm/pgtable.h -@@ -87,13 +87,9 @@ - - #define FIXADDR_TOP PCI_IO_START - #ifdef CONFIG_64BIT --#define MAX_FDT_SIZE PMD_SIZE --#define FIX_FDT_SIZE (MAX_FDT_SIZE + SZ_2M) --#define FIXADDR_SIZE (PMD_SIZE + FIX_FDT_SIZE) -+#define FIXADDR_SIZE PMD_SIZE - #else --#define MAX_FDT_SIZE PGDIR_SIZE --#define FIX_FDT_SIZE MAX_FDT_SIZE --#define FIXADDR_SIZE (PGDIR_SIZE + FIX_FDT_SIZE) -+#define FIXADDR_SIZE PGDIR_SIZE - #endif - #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) - -diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c -index 111111111111..222222222222 100644 ---- a/arch/riscv/kernel/setup.c -+++ b/arch/riscv/kernel/setup.c -@@ -280,8 +280,12 @@ void __init setup_arch(char **cmdline_p) - #if IS_ENABLED(CONFIG_BUILTIN_DTB) - unflatten_and_copy_device_tree(); - #else -- unflatten_device_tree(); -+ if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa)))) -+ unflatten_device_tree(); -+ else -+ pr_err("No DTB found in kernel mappings\n"); - #endif -+ early_init_fdt_scan_reserved_mem(); - misc_mem_init(); - - init_resources(); -diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c -index 111111111111..222222222222 100644 ---- a/arch/riscv/mm/init.c -+++ b/arch/riscv/mm/init.c -@@ -57,6 +57,7 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] - EXPORT_SYMBOL(empty_zero_page); - - extern char _start[]; -+#define DTB_EARLY_BASE_VA PGDIR_SIZE - void *_dtb_early_va __initdata; - uintptr_t _dtb_early_pa __initdata; - -@@ -241,22 +242,31 @@ static void __init setup_bootmem(void) - set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET); - - reserve_initrd_mem(); -- -- /* -- * No allocation should be done before reserving the memory as defined -- * in the device tree, otherwise the allocation could end up in a -- * reserved region. -- */ -- early_init_fdt_scan_reserved_mem(); -- - /* - * If DTB is built in, no need to reserve its memblock. - * Otherwise, do reserve it but avoid using - * early_init_fdt_reserve_self() since __pa() does - * not work for DTB pointers that are fixmap addresses - */ -- if (!IS_ENABLED(CONFIG_BUILTIN_DTB)) -- memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va)); -+ if (!IS_ENABLED(CONFIG_BUILTIN_DTB)) { -+ /* -+ * In case the DTB is not located in a memory region we won't -+ * be able to locate it later on via the linear mapping and -+ * get a segfault when accessing it via __va(dtb_early_pa). -+ * To avoid this situation copy DTB to a memory region. -+ * Note that memblock_phys_alloc will also reserve DTB region. -+ */ -+ if (!memblock_is_memory(dtb_early_pa)) { -+ size_t fdt_size = fdt_totalsize(dtb_early_va); -+ phys_addr_t new_dtb_early_pa = memblock_phys_alloc(fdt_size, PAGE_SIZE); -+ void *new_dtb_early_va = early_memremap(new_dtb_early_pa, fdt_size); -+ -+ memcpy(new_dtb_early_va, dtb_early_va, fdt_size); -+ early_memunmap(new_dtb_early_va, fdt_size); -+ _dtb_early_pa = new_dtb_early_pa; -+ } else -+ memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va)); -+ } - - #ifdef CONFIG_ZONE_DMA32 - dma_contiguous_reserve(dma32_phys_limit); -@@ -279,6 +289,9 @@ pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss; - static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss; - - pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); -+static p4d_t __maybe_unused early_dtb_p4d[PTRS_PER_P4D] __initdata __aligned(PAGE_SIZE); -+static pud_t __maybe_unused early_dtb_pud[PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE); -+static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE); - - #ifdef CONFIG_XIP_KERNEL - #define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops)) -@@ -623,6 +636,9 @@ static void __init create_p4d_mapping(p4d_t *p4dp, - #define trampoline_pgd_next (pgtable_l5_enabled ? \ - (uintptr_t)trampoline_p4d : (pgtable_l4_enabled ? \ - (uintptr_t)trampoline_pud : (uintptr_t)trampoline_pmd)) -+#define early_dtb_pgd_next (pgtable_l5_enabled ? \ -+ (uintptr_t)early_dtb_p4d : (pgtable_l4_enabled ? \ -+ (uintptr_t)early_dtb_pud : (uintptr_t)early_dtb_pmd)) - #else - #define pgd_next_t pte_t - #define alloc_pgd_next(__va) pt_ops.alloc_pte(__va) -@@ -630,6 +646,7 @@ static void __init create_p4d_mapping(p4d_t *p4dp, - #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ - create_pte_mapping(__nextp, __va, __pa, __sz, __prot) - #define fixmap_pgd_next ((uintptr_t)fixmap_pte) -+#define early_dtb_pgd_next ((uintptr_t)early_dtb_pmd) - #define create_p4d_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0) - #define create_pud_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0) - #define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0) -@@ -852,27 +869,32 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early) - * this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR - * entry. - */ --static void __init create_fdt_early_page_table(uintptr_t fix_fdt_va, -- uintptr_t dtb_pa) -+static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa) - { - #ifndef CONFIG_BUILTIN_DTB - uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1); - -- /* Make sure the fdt fixmap address is always aligned on PMD size */ -- BUILD_BUG_ON(FIX_FDT % (PMD_SIZE / PAGE_SIZE)); -+ create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, -+ IS_ENABLED(CONFIG_64BIT) ? early_dtb_pgd_next : pa, -+ PGDIR_SIZE, -+ IS_ENABLED(CONFIG_64BIT) ? PAGE_TABLE : PAGE_KERNEL); - -- /* In 32-bit only, the fdt lies in its own PGD */ -- if (!IS_ENABLED(CONFIG_64BIT)) { -- create_pgd_mapping(early_pg_dir, fix_fdt_va, -- pa, MAX_FDT_SIZE, PAGE_KERNEL); -- } else { -- create_pmd_mapping(fixmap_pmd, fix_fdt_va, -+ if (pgtable_l5_enabled) -+ create_p4d_mapping(early_dtb_p4d, DTB_EARLY_BASE_VA, -+ (uintptr_t)early_dtb_pud, P4D_SIZE, PAGE_TABLE); -+ -+ if (pgtable_l4_enabled) -+ create_pud_mapping(early_dtb_pud, DTB_EARLY_BASE_VA, -+ (uintptr_t)early_dtb_pmd, PUD_SIZE, PAGE_TABLE); -+ -+ if (IS_ENABLED(CONFIG_64BIT)) { -+ create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA, - pa, PMD_SIZE, PAGE_KERNEL); -- create_pmd_mapping(fixmap_pmd, fix_fdt_va + PMD_SIZE, -+ create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE, - pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL); - } - -- dtb_early_va = (void *)fix_fdt_va + (dtb_pa & (PMD_SIZE - 1)); -+ dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1)); - #else - /* - * For 64-bit kernel, __va can't be used since it would return a linear -@@ -1042,7 +1064,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) - create_kernel_page_table(early_pg_dir, true); - - /* Setup early mapping for FDT early scan */ -- create_fdt_early_page_table(__fix_to_virt(FIX_FDT), dtb_pa); -+ create_fdt_early_page_table(early_pg_dir, dtb_pa); - - /* - * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap -@@ -1084,16 +1106,6 @@ static void __init setup_vm_final(void) - u64 i; - - /* Setup swapper PGD for fixmap */ --#if !defined(CONFIG_64BIT) -- /* -- * In 32-bit, the device tree lies in a pgd entry, so it must be copied -- * directly in swapper_pg_dir in addition to the pgd entry that points -- * to fixmap_pte. -- */ -- unsigned long idx = pgd_index(__fix_to_virt(FIX_FDT)); -- -- set_pgd(&swapper_pg_dir[idx], early_pg_dir[idx]); --#endif - create_pgd_mapping(swapper_pg_dir, FIXADDR_START, - __pa_symbol(fixmap_pgd_next), - PGDIR_SIZE, PAGE_TABLE); --- -Armbian - diff --git a/patch/kernel/archive/spacemit-6.1/dt/k1-bananapi-f3.dts b/patch/kernel/archive/spacemit-6.1/dt/k1-bananapi-f3.dts index cdb9c5a77668..3a4d530b9c8c 100644 --- a/patch/kernel/archive/spacemit-6.1/dt/k1-bananapi-f3.dts +++ b/patch/kernel/archive/spacemit-6.1/dt/k1-bananapi-f3.dts @@ -9,18 +9,13 @@ model = "BananaPi BPI-F3"; }; -&pcie2_rc { - num-lanes = <1>; -}; - &uart2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart2>; - status = "okay"; + status = "disabled"; bluetooth { compatible = "realtek,rtl8852bs-bt"; device-wake-gpios = <&gpio 64 GPIO_ACTIVE_HIGH>; - host-wake-gpios = <&gpio 65 GPIO_ACTIVE_HIGH>; }; }; diff --git a/patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-reserved-mm.dtsi b/patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-reserved-mm.dtsi new file mode 100644 index 000000000000..06b6ea8fa83e --- /dev/null +++ b/patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-reserved-mm.dtsi @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 SPACEMIT Micro Limited + */ + +/ { + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + spacemitzreserved: spacemit-mmz-@50000000 { + no-map; + reg = <0x0 0x50000000 0x0 0x28000000>; + }; + }; +}; diff --git a/patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-sdk.dtsi b/patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-sdk.dtsi index 97b5c24345cb..1e125109c061 100644 --- a/patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-sdk.dtsi +++ b/patch/kernel/archive/spacemit-6.1/dt/k1-x-camera-sdk.dtsi @@ -11,7 +11,7 @@ compatible = "spacemit,plat-cam", "simple-bus"; #address-cells = <2>; #size-cells = <2>; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -25,7 +25,7 @@ clock-names = "csi_dphy"; resets = <&reset RESET_CCIC1_PHY>; reset-names = "cphy_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -39,7 +39,7 @@ clock-names = "csi_dphy"; resets = <&reset RESET_CCIC2_PHY>; reset-names = "cphy_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -54,7 +54,7 @@ clock-names = "csi_dphy"; resets = <&reset RESET_CCIC3_PHY>; reset-names = "cphy_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -76,7 +76,7 @@ <&reset RESET_CCIC_4X>, <&reset RESET_ISP_CI>; reset-names = "isp_ahb_reset", "csi_reset", "ccic_4x_reset", "isp_ci_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -98,7 +98,7 @@ <&reset RESET_CCIC_4X>, <&reset RESET_ISP_CI>; reset-names = "isp_ahb_reset", "csi_reset", "ccic_4x_reset", "isp_ci_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -120,7 +120,7 @@ <&reset RESET_CCIC_4X>, <&reset RESET_ISP_CI>; reset-names = "isp_ahb_reset", "csi_reset", "ccic_4x_reset", "isp_ci_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -140,7 +140,7 @@ <&reset RESET_ISP_CI>, <&reset RESET_LCD_MCLK>; reset-names = "isp_ahb_reset", "isp_reset", "isp_ci_reset", "lcd_mclk_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -160,7 +160,7 @@ <&reset RESET_ISP_CI>, <&reset RESET_LCD_MCLK>; reset-names = "isp_ahb_reset", "isp_reset", "isp_ci_reset", "lcd_mclk_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; @@ -180,7 +180,7 @@ <&reset RESET_ISP_CI>, <&reset RESET_LCD_MCLK>; reset-names = "isp_ahb_reset", "isp_cpp_reset", "isp_ci_reset", "lcd_mclk_reset"; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "okay"; }; diff --git a/patch/kernel/archive/spacemit-6.1/dt/k1-x-efuse.dtsi b/patch/kernel/archive/spacemit-6.1/dt/k1-x-efuse.dtsi new file mode 100644 index 000000000000..5aee36ef11f6 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.1/dt/k1-x-efuse.dtsi @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2024 Spacemit, Inc */ + +&efuse { + status = "okay"; + + efuse_bank7: efuse_bank@7 { + compatible = "spacemit,k1-efuse"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x190 0x20>; + resets = <&reset RESET_AES>; + reset-names = "aes_reset"; + clocks = <&ccu CLK_AES>; + clock-names = "aes_core"; + status = "okay"; + + soc_die_id: bank7@11,3 { + reg = <0x11 3>; + bits = <3 16>; + }; + + soc_ver_id: bank7@1f,6 { + reg = <0x1F 1>; + bits = <6 2>; + }; + + soc_pack_id: bank7@16,6 { + reg = <0x16 2>; + bits = <6 9>; + }; + + soc_svt_dro: bank7@15,5 { + reg = <0x15 2>; + bits = <5 9>; + }; + + soc_chip_id: bank7@17,7 { + reg = <0x17 8>; + bits = <7 55>; + }; + }; +}; + +&socinfo { + nvmem-cells = <&soc_die_id>, <&soc_ver_id>, <&soc_pack_id>, + <&soc_svt_dro>, <&soc_chip_id>; + nvmem-cell-names = "soc_die_id", "soc_ver_id", "soc_pack_id", + "soc_svt_dro", "soc_chip_id"; + status = "okay"; +}; + diff --git a/patch/kernel/archive/spacemit-6.1/dt/k1-x.dtsi b/patch/kernel/archive/spacemit-6.1/dt/k1-x.dtsi index d18fef172d89..82d7e1cd8681 100644 --- a/patch/kernel/archive/spacemit-6.1/dt/k1-x.dtsi +++ b/patch/kernel/archive/spacemit-6.1/dt/k1-x.dtsi @@ -49,15 +49,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst0_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C0_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst0_core_opp_table>; #cooling-cells = <2>; cpu0_intc: interrupt-controller { @@ -77,15 +75,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst0_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C0_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst0_core_opp_table>; #cooling-cells = <2>; cpu1_intc: interrupt-controller { @@ -105,15 +101,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst0_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C0_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst0_core_opp_table>; #cooling-cells = <2>; cpu2_intc: interrupt-controller { @@ -133,15 +127,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst0_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C0_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst0_core_opp_table>; #cooling-cells = <2>; cpu3_intc: interrupt-controller { @@ -161,15 +153,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst1_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C1_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst1_core_opp_table>; #cooling-cells = <2>; cpu4_intc: interrupt-controller { @@ -189,15 +179,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst1_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C1_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst1_core_opp_table>; #cooling-cells = <2>; cpu5_intc: interrupt-controller { @@ -217,15 +205,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst1_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C1_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst1_core_opp_table>; #cooling-cells = <2>; cpu6_intc: interrupt-controller { @@ -245,15 +231,13 @@ riscv,cbom-block-size = <64>; i-cache-block-size = <64>; i-cache-size = <32768>; - i-cache-sets = <512>; + i-cache-sets = <128>; d-cache-block-size = <64>; d-cache-size = <32768>; - d-cache-sets = <512>; + d-cache-sets = <128>; next-level-cache = <&clst1_l2_cache>; mmu-type = "riscv,sv39"; - clocks = <&ccu CLK_CPU_C1_CORE>; cpu-idle-states = <&CPU_NONRET> /*, <&CLUSTER_NONRET>, <&TOP_NONRET> */; - operating-points-v2 = <&clst1_core_opp_table>; #cooling-cells = <2>; cpu7_intc: interrupt-controller { @@ -268,7 +252,7 @@ cache-block-size = <64>; cache-level = <2>; cache-size = <524288>; - cache-sets = <1024>; + cache-sets = <512>; cache-unified; }; @@ -277,7 +261,7 @@ cache-block-size = <64>; cache-level = <2>; cache-size = <524288>; - cache-sets = <1024>; + cache-sets = <512>; cache-unified; }; @@ -314,99 +298,6 @@ wakeup-latency-us = <1600>; }; }; - - clst0_core_opp_table: opp_table0 { - compatible = "operating-points-v2"; - opp-shared; - - clocks = <&ccu CLK_CPU_C0_ACE>, <&ccu CLK_CPU_C0_TCM>, <&ccu CLK_CCI550>; - clock-names = "ace","tcm", "cci"; - cci-hz = /bits/ 64 <614000000>; - - opp1600000000 { - opp-hz = /bits/ 64 <1600000000>; - tcm-hz = /bits/ 64 <800000000>; - ace-hz = /bits/ 64 <800000000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - - opp1228800000 { - opp-hz = /bits/ 64 <1228800000>; - tcm-hz = /bits/ 64 <614400000>; - ace-hz = /bits/ 64 <614400000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - - opp1000000000 { - opp-hz = /bits/ 64 <1000000000>; - tcm-hz = /bits/ 64 <500000000>; - ace-hz = /bits/ 64 <500000000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - - opp819000000 { - opp-hz = /bits/ 64 <819000000>; - opp-microvolt = <950000>; - tcm-hz = /bits/ 64 <409500000>; - ace-hz = /bits/ 64 <409500000>; - clock-latency-ns = <200000>; - }; - - opp614400000 { - opp-hz = /bits/ 64 <614400000>; - tcm-hz = /bits/ 64 <307200000>; - ace-hz = /bits/ 64 <307200000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - }; - - clst1_core_opp_table: opp_table1 { - compatible = "operating-points-v2"; - opp-shared; - - clocks = <&ccu CLK_CPU_C1_ACE>, <&ccu CLK_CCI550>; - clock-names = "ace", "cci"; - cci-hz = /bits/ 64 <614000000>; - - opp1600000000 { - opp-hz = /bits/ 64 <1600000000>; - ace-hz = /bits/ 64 <800000000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - - opp1228800000 { - opp-hz = /bits/ 64 <1228800000>; - ace-hz = /bits/ 64 <614400000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - - opp1000000000 { - opp-hz = /bits/ 64 <1000000000>; - ace-hz = /bits/ 64 <500000000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - - opp819000000 { - opp-hz = /bits/ 64 <819000000>; - ace-hz = /bits/ 64 <409500000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - - opp614400000 { - opp-hz = /bits/ 64 <614400000>; - ace-hz = /bits/ 64 <307200000>; - opp-microvolt = <950000>; - clock-latency-ns = <200000>; - }; - }; }; clocks { @@ -468,6 +359,7 @@ area_reserved@80000000 { /* dram area is 0~2GB, and 4GB~, the 2GB~4GB is io area */ reg = <0x0 0x80000000 0x0 0x40800000>; + no-map; }; /* sram area, used for rcpu code & data & heap space */ @@ -527,7 +419,7 @@ #size-cells = <2>; ranges; - /* dram mapping for dma/usb/sdh/audio/crypto for ex. */ + /* dram mapping for usb/sdh for ex. */ dram_range0: dram_range@0 { compatible = "spacemit-dram-bus"; #address-cells = <2>; @@ -537,7 +429,7 @@ status = "okay"; }; - /* dram mapping for vpu/gpu/v2d/jpu for ex. */ + /* dram mapping for vpu/gpu/dpu for ex. */ dram_range1: dram_range@1 { compatible = "spacemit-dram-bus"; #address-cells = <2>; @@ -548,6 +440,7 @@ status = "okay"; }; + /* dram mapping for pcie for ex. */ dram_range2: dram_range@2 { compatible = "spacemit-dram-bus"; #address-cells = <2>; @@ -558,6 +451,39 @@ status = "okay"; }; + /* dram mapping for v2d/isp/csi/vi/cpp for ex. */ + dram_range3: dram_range@3 { + compatible = "spacemit-dram-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0x80000000 0x1 0x00000000 0x1 0x80000000>; + #interconnect-cells = <0>; + status = "okay"; + }; + + /* dram mapping for dma&users for ex. */ + dram_range4: dram_range@4 { + compatible = "spacemit-dram-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x1 0x00000000 0x1 0x80000000 0x3 0x00000000>; + #interconnect-cells = <0>; + status = "okay"; + }; + + /* dram mapping for eth/crypto/jpu for ex. */ + dram_range5: dram_range@5 { + compatible = "spacemit-dram-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0x80000000 0x1 0x00000000 0x0 0x80000000>; + #interconnect-cells = <0>; + status = "okay"; + }; + clint0: clint@e4000000 { compatible = "riscv,clint0"; interrupts-extended = < @@ -632,8 +558,9 @@ }; pinctrl: pinctrl@d401e000 { - compatible = "pinconf-single"; - reg = <0x0 0xd401e000 0x0 0x400>; + compatible = "pinconf-single-aib"; + reg = <0x0 0xd401e000 0x0 0x400>, + <0x0 0xd4019800 0x0 0x10>; #address-cells = <1>; #size-cells = <1>; #pinctrl-cells = <2>; @@ -642,6 +569,16 @@ pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xff77>; + clocks = <&ccu CLK_AIB>; + clock-names = "clk_aib"; + resets = <&reset RESET_AIB>; + reset-names = "aib_rst"; + + interrupt-parent = <&intc>; + interrupts = <60>; + interrupt-controller; + #interrupt-cells = <1>; + range: gpio-range { #pinctrl-single,gpio-range-cells = <3>; }; @@ -796,7 +733,7 @@ dmas = <&pdma0 DMA_UART0_RX 1 &pdma0 DMA_UART0_TX 1>; dma-names = "rx", "tx"; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "ok"; }; @@ -813,7 +750,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -830,7 +767,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -847,7 +784,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -864,7 +801,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -881,7 +818,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -898,7 +835,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -915,7 +852,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -932,7 +869,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -980,7 +917,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "ok"; }; @@ -1012,7 +949,7 @@ resets = <&reset RESET_SSPA0>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1033,7 +970,7 @@ resets = <&reset RESET_SSPA1>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1052,7 +989,7 @@ resets = <&reset RESET_SEC_SSP2>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1073,7 +1010,7 @@ resets = <&reset RESET_SSP3>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1105,7 +1042,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1137,7 +1074,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1169,7 +1106,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1194,7 +1131,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1226,7 +1163,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1258,7 +1195,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1290,7 +1227,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1322,7 +1259,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1354,7 +1291,7 @@ spacemit,apb_clock = <52000000>; power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1649,8 +1586,6 @@ clock-names = "per","ipg"; resets = <&reset RESET_CAN0>; fsl,clk-source = <0>; - interconnects = <&dram_range0>; - interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1663,8 +1598,6 @@ clocks = <&ccu CLK_RCPU_CAN>,<&ccu CLK_RCPU_CAN_BUS>; clock-names = "per","ipg"; resets = <&reset RESET_RCPU_CAN>; - interconnects = <&dram_range0>; - interconnect-names = "dma-mem"; rcpu-can; status = "disabled"; }; @@ -1717,7 +1650,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range1>; + interconnects = <&dram_range5>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1741,7 +1674,7 @@ power-domains = <&power K1X_PMU_BUS_PWR_DOMAIN>; clk,pm-runtime,no-sleep; cpuidle,pm-runtime,sleep; - interconnects = <&dram_range1>; + interconnects = <&dram_range5>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -1796,8 +1729,9 @@ ehci: ehci@c0900100 { compatible = "spacemit,mv-ehci"; - reg = <0x0 0xc0900100 0x0 0x4000>; - interrupts = <105>; + reg = <0x0 0xc0900100 0x0 0x4000>, + <0x0 0xd428287c 0x0 0x4>; + interrupts = <105>,<106>; interrupt-parent = <&intc>; spacemit,ehci-name = "mv-ehci"; spacemit,otg-force-a-bus-req; @@ -1823,8 +1757,9 @@ ehci1: ehci1@c0980100 { compatible = "spacemit,mv-ehci"; - reg = <0x0 0xc0980100 0x0 0x4000>; - interrupts = <118>; + reg = <0x0 0xc0980100 0x0 0x4000>, + <0x0 0xd4282bc4 0x0 0x4>; + interrupts = <118>,<148>; interrupt-parent = <&intc>; spacemit,ehci-name = "mv-ehci"; spacemit,otg-force-a-bus-req; @@ -1868,6 +1803,7 @@ compatible = "spacemit,k1-x-dwc3"; #address-cells = <2>; #size-cells = <2>; + reg = <0x0 0xd4282bc8 0x0 0x4>; resets = <&reset RESET_USB3_0>; reset-names = "ctl_rst"; clocks = <&ccu CLK_USB30>; @@ -2127,7 +2063,7 @@ k1x,qspi-rx-dma = <1>; dmas = <&pdma0 45 1>; dma-names = "tx-dma"; - interconnects = <&dram_range0>; + interconnects = <&dram_range4>; interconnect-names = "dma-mem"; status = "disabled"; }; @@ -2306,7 +2242,7 @@ reset-names= "v2d_reset"; interrupt-parent = <&intc>; interrupts = <86>; - interconnects = <&dram_range1>; + interconnects = <&dram_range3>; interconnect-names = "dma-mem"; status = "ok"; }; @@ -2332,7 +2268,7 @@ jpu,cclk-min-frequency = <409000000>; jpu,cclk-default-frequency = <614000000>; page-size = <4>; - interconnects = <&dram_range1>; + interconnects = <&dram_range5>; interconnect-names = "dma-mem"; clk,pm-runtime,no-sleep; status = "okay"; @@ -2367,9 +2303,24 @@ num-engines = <1>; clocks = <&ccu CLK_AES>; resets = <&reset RESET_AES>; + interconnects = <&dram_range5>; + interconnect-names = "dma-mem"; status = "okay"; }; + efuse: fuse@f0702800 { + compatible = "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0xf0702800 0x400>; + status = "disabled"; + }; + + socinfo: socinfo@0 { + compatible = "spacemit,socinfo-k1x"; + status = "disabled"; + }; + ciu: ciu@d4282c00 { compatible = "spacemit,aquila-ciu", "spacemit,ciu", "syscon"; reg = <0x0 0xd4282c00 0x0 0x2d0>; @@ -2510,6 +2461,8 @@ compatible = "spacemit,simple-audio-card"; simple-audio-card,name = "snd-hdmi"; status = "disabled"; + interconnects = <&dram_range4>; + interconnect-names = "dma-mem"; simple-audio-card,cpu { sound-dai = <&hdmi_sspa>; }; @@ -2525,6 +2478,8 @@ compatible = "spacemit,simple-audio-card"; simple-audio-card,format = "i2s"; status = "disabled"; + interconnects = <&dram_range4>; + interconnect-names = "dma-mem"; spacemit,init-jack; simple-audio-card,cpu { sound-dai = <&i2s0>; diff --git a/patch/kernel/archive/spacemit-6.1/dt/k1-x_deb1.dts b/patch/kernel/archive/spacemit-6.1/dt/k1-x_deb1.dts index 5898fae7adb3..f82db05e7da3 100644 --- a/patch/kernel/archive/spacemit-6.1/dt/k1-x_deb1.dts +++ b/patch/kernel/archive/spacemit-6.1/dt/k1-x_deb1.dts @@ -4,11 +4,13 @@ /dts-v1/; #include "k1-x.dtsi" +#include "k1-x-efuse.dtsi" #include "k1-x_pinctrl.dtsi" #include "lcd_gx09inx101_mipi.dtsi" #include "k1-x-hdmi.dtsi" #include "k1-x-lcd.dtsi" #include "k1-x-camera-sdk.dtsi" +#include "k1-x_opp_table.dtsi" / { model = "spacemit k1-x deb1 board"; @@ -147,8 +149,11 @@ wlan_pwrseq: wlan-pwrseq { compatible = "spacemit,wlan-pwrseq"; - regon-gpios = <&gpio 116 0>; - hostwake-gpios = <&gpio 66 0>; + regon-gpios = <&gpio 116 0>; + interrupt-parent = <&pinctrl>; + interrupts = <268>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wlan_wakeup>; }; bt_pwrseq: bt-pwrseq { @@ -243,13 +248,6 @@ status = "okay"; }; -&i2c1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c1>; - spacemit,i2c-fast-mode; - status = "okay"; -}; - &i2c2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2_0>; @@ -551,7 +549,7 @@ &range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) &range GPIO_63 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) &range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) - &range GPIO_66 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) + &range GPIO_67 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) &range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) &range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) &range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) @@ -622,13 +620,20 @@ K1X_PADCONF(GPIO_46, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) /* gmac1_clk_ref */ >; }; + + pinctrl_wlan_wakeup: wlan_wakeup_grp { + pinctrl-single,pins =< + K1X_PADCONF(GPIO_66, MUX_MODE0, (EDGE_FALL | PULL_DOWN | PAD_3V_DS2)) /* wifi edge detect */ + >; + }; }; &gpio{ gpio-ranges = < &pinctrl 49 GPIO_49 2 &pinctrl 58 GPIO_58 1 - &pinctrl 63 GPIO_63 5 + &pinctrl 63 GPIO_63 3 + &pinctrl 67 GPIO_67 1 &pinctrl 70 PRI_TDI 4 &pinctrl 74 GPIO_74 1 &pinctrl 80 GPIO_80 4 @@ -994,23 +999,6 @@ power-domains = <&power K1X_PMU_ISP_PWR_DOMAIN>; }; -&cpu_0 { - clst0-supply = <&dcdc_1>; - vin-supply-names = "clst0"; -}; - -&clst0_core_opp_table { - opp1600000000 { - opp-microvolt = <1050000>; - }; -}; - -&clst1_core_opp_table { - opp1600000000 { - opp-microvolt = <1050000>; - }; -}; - &rcpu { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rcpu>; diff --git a/patch/kernel/archive/spacemit-6.1/dt/k1-x_opp_table.dtsi b/patch/kernel/archive/spacemit-6.1/dt/k1-x_opp_table.dtsi new file mode 100644 index 000000000000..6672b481625b --- /dev/null +++ b/patch/kernel/archive/spacemit-6.1/dt/k1-x_opp_table.dtsi @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2024 Spacemit, Inc */ + +&cpus { + clst_core_opp_table0: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + clocks = <&ccu CLK_CPU_C0_ACE>, <&ccu CLK_CPU_C1_ACE>, <&ccu CLK_CPU_C0_TCM>, + <&ccu CLK_CCI550>, <&ccu CLK_PLL3>; + clock-names = "ace0","ace1","tcm","cci","pll3"; + cci-hz = /bits/ 64 <614000000>; + + opp1600000000 { + opp-hz = /bits/ 64 <1600000000>, /bits/ 64 <1600000000>; + tcm-hz = /bits/ 64 <800000000>; + ace-hz = /bits/ 64 <800000000>; + opp-microvolt = <1050000>; + clock-latency-ns = <200000>; + }; + + opp1228800000 { + opp-hz = /bits/ 64 <1228800000>, /bits/ 64 <1228800000>; + tcm-hz = /bits/ 64 <614400000>; + ace-hz = /bits/ 64 <614400000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp1000000000 { + opp-hz = /bits/ 64 <1000000000>, /bits/ 64 <1000000000>; + tcm-hz = /bits/ 64 <500000000>; + ace-hz = /bits/ 64 <500000000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp819000000 { + opp-hz = /bits/ 64 <819000000>, /bits/ 64 <819000000>; + opp-microvolt = <950000>; + tcm-hz = /bits/ 64 <409500000>; + ace-hz = /bits/ 64 <409500000>; + clock-latency-ns = <200000>; + }; + + opp614400000 { + opp-hz = /bits/ 64 <614400000>, /bits/ 64 <614400000>; + tcm-hz = /bits/ 64 <307200000>; + ace-hz = /bits/ 64 <307200000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + }; +}; + +&cpu_0 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; + +&cpu_1 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; + +&cpu_2 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; + +&cpu_3 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; + +&cpu_4 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; + +&cpu_5 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; + +&cpu_6 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; + +&cpu_7 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>; +}; diff --git a/patch/kernel/archive/spacemit-6.1/dt/m1-x_opp_table.dtsi b/patch/kernel/archive/spacemit-6.1/dt/m1-x_opp_table.dtsi new file mode 100644 index 000000000000..af2458381b89 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.1/dt/m1-x_opp_table.dtsi @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2023 Spacemit, Inc */ + +&cpus { + clst_core_opp_table0: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + clocks = <&ccu CLK_CPU_C0_ACE>, <&ccu CLK_CPU_C1_ACE>, <&ccu CLK_CPU_C0_TCM>, + <&ccu CLK_CCI550>, <&ccu CLK_PLL3>; + clock-names = "ace0","ace1","tcm","cci","pll3"; + cci-hz = /bits/ 64 <614000000>; + + opp1800000000 { + opp-hz = /bits/ 64 <1800000000>, /bits/ 64 <1800000000>; + tcm-hz = /bits/ 64 <900000000>; + ace-hz = /bits/ 64 <900000000>; + opp-microvolt = <1160000>; + clock-latency-ns = <200000>; + }; + + opp1600000000 { + opp-hz = /bits/ 64 <1600000000>, /bits/ 64 <1600000000>; + tcm-hz = /bits/ 64 <800000000>; + ace-hz = /bits/ 64 <800000000>; + opp-microvolt = <1050000>; + clock-latency-ns = <200000>; + }; + + opp1228800000 { + opp-hz = /bits/ 64 <1228800000>, /bits/ 64 <1228800000>; + tcm-hz = /bits/ 64 <614400000>; + ace-hz = /bits/ 64 <614400000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp1000000000 { + opp-hz = /bits/ 64 <1000000000>, /bits/ 64 <1000000000>; + tcm-hz = /bits/ 64 <500000000>; + ace-hz = /bits/ 64 <500000000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp819000000 { + opp-hz = /bits/ 64 <819000000>, /bits/ 64 <819000000>; + opp-microvolt = <950000>; + tcm-hz = /bits/ 64 <409500000>; + ace-hz = /bits/ 64 <409500000>; + clock-latency-ns = <200000>; + }; + + opp614400000 { + opp-hz = /bits/ 64 <614400000>, /bits/ 64 <614400000>; + tcm-hz = /bits/ 64 <307200000>; + ace-hz = /bits/ 64 <307200000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + }; + + clst_core_opp_table1: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + clocks = <&ccu CLK_CPU_C0_ACE>, <&ccu CLK_CPU_C1_ACE>, <&ccu CLK_CPU_C0_TCM>, + <&ccu CLK_CCI550>, <&ccu CLK_PLL3>; + clock-names = "ace0","ace1","tcm","cci","pll3"; + cci-hz = /bits/ 64 <614000000>; + + opp1800000000 { + opp-hz = /bits/ 64 <1800000000>, /bits/ 64 <1800000000>; + tcm-hz = /bits/ 64 <900000000>; + ace-hz = /bits/ 64 <900000000>; + opp-microvolt = <1100000>; + clock-latency-ns = <200000>; + }; + + opp1600000000 { + opp-hz = /bits/ 64 <1600000000>, /bits/ 64 <1600000000>; + tcm-hz = /bits/ 64 <800000000>; + ace-hz = /bits/ 64 <800000000>; + opp-microvolt = <1050000>; + clock-latency-ns = <200000>; + }; + + opp1228800000 { + opp-hz = /bits/ 64 <1228800000>, /bits/ 64 <1228800000>; + tcm-hz = /bits/ 64 <614400000>; + ace-hz = /bits/ 64 <614400000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp1000000000 { + opp-hz = /bits/ 64 <1000000000>, /bits/ 64 <1000000000>; + tcm-hz = /bits/ 64 <500000000>; + ace-hz = /bits/ 64 <500000000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp819000000 { + opp-hz = /bits/ 64 <819000000>, /bits/ 64 <819000000>; + opp-microvolt = <950000>; + tcm-hz = /bits/ 64 <409500000>; + ace-hz = /bits/ 64 <409500000>; + clock-latency-ns = <200000>; + }; + + opp614400000 { + opp-hz = /bits/ 64 <614400000>, /bits/ 64 <614400000>; + tcm-hz = /bits/ 64 <307200000>; + ace-hz = /bits/ 64 <307200000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + }; + + clst_core_opp_table2: opp_table2 { + compatible = "operating-points-v2"; + opp-shared; + + clocks = <&ccu CLK_CPU_C0_ACE>, <&ccu CLK_CPU_C1_ACE>, <&ccu CLK_CPU_C0_TCM>, + <&ccu CLK_CCI550>, <&ccu CLK_PLL3>; + clock-names = "ace0","ace1","tcm","cci","pll3"; + cci-hz = /bits/ 64 <614000000>; + + opp1800000000 { + opp-hz = /bits/ 64 <1800000000>, /bits/ 64 <1800000000>; + tcm-hz = /bits/ 64 <900000000>; + ace-hz = /bits/ 64 <900000000>; + opp-microvolt = <1050000>; + clock-latency-ns = <200000>; + }; + + opp1600000000 { + opp-hz = /bits/ 64 <1600000000>, /bits/ 64 <1600000000>; + tcm-hz = /bits/ 64 <800000000>; + ace-hz = /bits/ 64 <800000000>; + opp-microvolt = <1050000>; + clock-latency-ns = <200000>; + }; + + opp1228800000 { + opp-hz = /bits/ 64 <1228800000>, /bits/ 64 <1228800000>; + tcm-hz = /bits/ 64 <614400000>; + ace-hz = /bits/ 64 <614400000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp1000000000 { + opp-hz = /bits/ 64 <1000000000>, /bits/ 64 <1000000000>; + tcm-hz = /bits/ 64 <500000000>; + ace-hz = /bits/ 64 <500000000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + + opp819000000 { + opp-hz = /bits/ 64 <819000000>, /bits/ 64 <819000000>; + opp-microvolt = <950000>; + tcm-hz = /bits/ 64 <409500000>; + ace-hz = /bits/ 64 <409500000>; + clock-latency-ns = <200000>; + }; + + opp614400000 { + opp-hz = /bits/ 64 <614400000>, /bits/ 64 <614400000>; + tcm-hz = /bits/ 64 <307200000>; + ace-hz = /bits/ 64 <307200000>; + opp-microvolt = <950000>; + clock-latency-ns = <200000>; + }; + }; +}; + +&cpu_0 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; + +&cpu_1 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; + +&cpu_2 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; + +&cpu_3 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; + +&cpu_4 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; + +&cpu_5 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; + +&cpu_6 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; + +&cpu_7 { + clst-supply = <&dcdc_1>; + clocks = <&ccu CLK_CPU_C0_CORE>, <&ccu CLK_CPU_C1_CORE>; + clock-names = "cls0", "cls1"; + operating-points-v2 = <&clst_core_opp_table0>, <&clst_core_opp_table1>, <&clst_core_opp_table2>; +}; diff --git a/patch/kernel/archive/spacemit-6.1/dt/spacemit-scmi.dtsi b/patch/kernel/archive/spacemit-6.1/dt/spacemit-scmi.dtsi new file mode 100644 index 000000000000..5f33e7f6a0f6 --- /dev/null +++ b/patch/kernel/archive/spacemit-6.1/dt/spacemit-scmi.dtsi @@ -0,0 +1,76 @@ +/ { + sram { + compatible = "mmio-sram"; + /* 256k */ + reg = <0x0 0x2f902000 0x0 0x3e000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x2f902000 0x3e000>; + + /* channel 0*/ + cpu_scp_lpri0: scp-sram@2f900000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x80>; + }; + + /* channel 1*/ + cpu_scp_lpri1: scp-sram@2f900080 { + compatible = "arm,scmi-shmem"; + reg = <0x80 0x80>; + }; + + /* channel 2*/ + cpu_scp_lpri2: scp-sram@2f900100 { + compatible = "arm,scmi-shmem"; + reg = <0x100 0x80>; + }; + + /* channel 3*/ + cpu_scp_lpri3: scp-sram@2f900180 { + compatible = "arm,scmi-shmem"; + reg = <0x180 0x80>; + }; + }; + + firmware { + scmi { + compatible = "arm,scmi"; + mbox-names = "tx", "rx"; + mboxes = <&mailbox 0 &mailbox 2>; + shmem = <&cpu_scp_lpri0 &cpu_scp_lpri0>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_vold: protocol@23 { + reg = <0x17>; + regulators { + #address-cells = <1>; + #size-cells = <0>; + + regulator_devlittle: regulator@0 { + reg = <0x0>; + regulator-min-microvolt = <820000>; + regulator-max-microvolt = <1000000>; + }; + + regulator_devgpu: regulator@1 { + reg = <0x1>; + regulator-min-microvolt = <820000>; + regulator-max-microvolt = <900000>; + }; + }; + }; + + scmi_devpd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + }; + }; + }; +}; + diff --git a/patch/kernel/spacemit-legacy-6.1/dt/k1-bananapi-f3.dts b/patch/kernel/spacemit-legacy-6.1/dt/k1-bananapi-f3.dts index cdb9c5a77668..3a4d530b9c8c 100644 --- a/patch/kernel/spacemit-legacy-6.1/dt/k1-bananapi-f3.dts +++ b/patch/kernel/spacemit-legacy-6.1/dt/k1-bananapi-f3.dts @@ -9,18 +9,13 @@ model = "BananaPi BPI-F3"; }; -&pcie2_rc { - num-lanes = <1>; -}; - &uart2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart2>; - status = "okay"; + status = "disabled"; bluetooth { compatible = "realtek,rtl8852bs-bt"; device-wake-gpios = <&gpio 64 GPIO_ACTIVE_HIGH>; - host-wake-gpios = <&gpio 65 GPIO_ACTIVE_HIGH>; }; };