]> Git Repo - J-u-boot.git/commitdiff
Merge patch series "Bug-fixes for a few boards"
authorTom Rini <[email protected]>
Mon, 5 Aug 2024 18:15:44 +0000 (12:15 -0600)
committerTom Rini <[email protected]>
Mon, 5 Aug 2024 18:17:02 +0000 (12:17 -0600)
Simon Glass <[email protected]> says:

This series includes fixes to get some rockchip and nvidia boards
working again. It also drops the broken Beaglebone Black config and
provides a devicetree fix for coral (x86).

41 files changed:
MAINTAINERS
arch/arm/dts/Makefile
arch/arm/dts/imx7s-warp.dts [deleted file]
arch/arm/mach-imx/mx7/Kconfig
cmd/cpu.c
common/Kconfig
common/Makefile
configs/imx8mm-phygate-tauri-l_defconfig
configs/imx8mm_evk_defconfig
configs/imx8mn_evk_defconfig
configs/imx8mp_evk_defconfig
configs/imx93_11x11_evk_defconfig
configs/phycore-imx8mm_defconfig
configs/phycore-imx8mp_defconfig
configs/warp7_bl33_defconfig
configs/warp7_defconfig
doc/usage/cmd/cpu.rst [new file with mode: 0644]
doc/usage/index.rst
drivers/clk/clk-uclass.c
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-imx8mn.c
drivers/clk/imx/clk-imx8mp.c
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-mtk.h
drivers/cpu/cpu-uclass.c
drivers/cpu/cpu_sandbox.c
drivers/cpu/imx8_cpu.c
drivers/net/dwc_eth_qos.c
drivers/net/dwc_eth_qos.h
drivers/serial/sandbox.c
drivers/video/Kconfig
drivers/video/video-uclass.c
drivers/watchdog/Kconfig
include/asm-generic/global_data.h
include/clk.h
include/cpu.h
include/cyclic.h
include/video.h
net/eth_internal.h
net/tftp.c
test/dm/cpu.c

index c2832345ab18a1d8fe329230e11221a56e56bfd1..ddcb7128db4e70591f3bbb069500117061169685 100644 (file)
@@ -997,6 +997,13 @@ F: arch/m68k/
 F:     doc/arch/m68k.rst
 F:     drivers/watchdog/mcf_wdt.c
 
+CPU
+M:     Simon Glass <[email protected]>
+M:     Hou Zhiqiang <[email protected]>
+S:     Maintained
+F:     cmd/cpu.c
+F:     doc/usage/cpu.rst
+
 CYCLIC
 M:     Stefan Roese <[email protected]>
 S:     Maintained
index 3ae4110d6040b08f418717f320ebdead8c9d8fdd..82d37adae3fff0b84eb3a0d500d6c8611cfe6a86 100644 (file)
@@ -883,7 +883,6 @@ dtb-$(CONFIG_MX7) += imx7d-sdb.dtb \
        imx7-cm.dtb \
        imx7d-colibri-emmc-eval-v3.dtb \
        imx7d-colibri-eval-v3.dtb \
-       imx7s-warp.dtb \
        imx7d-meerkat96.dtb \
        imx7d-pico-pi.dtb \
        imx7d-pico-hobbit.dtb \
diff --git a/arch/arm/dts/imx7s-warp.dts b/arch/arm/dts/imx7s-warp.dts
deleted file mode 100644 (file)
index e8734d2..0000000
+++ /dev/null
@@ -1,500 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2016 NXP Semiconductors.
- * Author: Fabio Estevam <[email protected]>
- */
-
-/dts-v1/;
-
-#include <dt-bindings/input/input.h>
-#include "imx7s.dtsi"
-
-/ {
-       model = "Element14 Warp i.MX7 Board";
-       compatible = "element14,imx7s-warp", "fsl,imx7s";
-
-       memory@80000000 {
-               device_type = "memory";
-               reg = <0x80000000 0x20000000>;
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-               pinctrl-0 = <&pinctrl_gpio>;
-               autorepeat;
-
-               back {
-                       label = "Back";
-                       gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
-                       linux,code = <KEY_BACK>;
-                       wakeup-source;
-               };
-       };
-
-       reg_brcm: regulator-brcm {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_brcm_reg>;
-               regulator-name = "brcm_reg";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               startup-delay-us = <200000>;
-       };
-
-       reg_bt: regulator-bt {
-               compatible = "regulator-fixed";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_bt_reg>;
-               enable-active-high;
-               gpio = <&gpio5 17 GPIO_ACTIVE_HIGH>;
-               regulator-name = "bt_reg";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-       };
-
-       reg_peri_3p15v: regulator-peri-3p15v {
-               compatible = "regulator-fixed";
-               regulator-name = "peri_3p15v_reg";
-               regulator-min-microvolt = <3150000>;
-               regulator-max-microvolt = <3150000>;
-               regulator-always-on;
-       };
-
-       sound {
-               compatible = "simple-audio-card";
-               simple-audio-card,name = "imx7-sgtl5000";
-               simple-audio-card,format = "i2s";
-               simple-audio-card,bitclock-master = <&dailink_master>;
-               simple-audio-card,frame-master = <&dailink_master>;
-               simple-audio-card,cpu {
-                       sound-dai = <&sai1>;
-               };
-
-               dailink_master: simple-audio-card,codec {
-                       sound-dai = <&codec>;
-                       clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
-               };
-       };
-};
-
-&clks {
-       assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
-       assigned-clock-rates = <884736000>;
-};
-
-&csi {
-       status = "okay";
-};
-
-&i2c1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1>;
-       status = "okay";
-
-       pmic: pfuze3000@8 {
-               compatible = "fsl,pfuze3000";
-               reg = <0x08>;
-
-               regulators {
-                       sw1a_reg: sw1a {
-                               regulator-min-microvolt = <700000>;
-                               regulator-max-microvolt = <1475000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                               regulator-ramp-delay = <6250>;
-                       };
-
-                       /* use sw1c_reg to align with pfuze100/pfuze200 */
-                       sw1c_reg: sw1b {
-                               regulator-min-microvolt = <700000>;
-                               regulator-max-microvolt = <1475000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                               regulator-ramp-delay = <6250>;
-                       };
-
-                       sw2_reg: sw2 {
-                               regulator-min-microvolt = <1500000>;
-                               regulator-max-microvolt = <1850000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       sw3a_reg: sw3 {
-                               regulator-min-microvolt = <900000>;
-                               regulator-max-microvolt = <1650000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       swbst_reg: swbst {
-                               regulator-min-microvolt = <5000000>;
-                               regulator-max-microvolt = <5150000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       snvs_reg: vsnvs {
-                               regulator-min-microvolt = <1000000>;
-                               regulator-max-microvolt = <3000000>;
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       vref_reg: vrefddr {
-                               regulator-boot-on;
-                               regulator-always-on;
-                       };
-
-                       vgen1_reg: vldo1 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                       };
-
-                       vgen2_reg: vldo2 {
-                               regulator-min-microvolt = <800000>;
-                               regulator-max-microvolt = <1550000>;
-                       };
-
-                       vgen3_reg: vccsd {
-                               regulator-min-microvolt = <2850000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                       };
-
-                       vgen4_reg: v33 {
-                               regulator-min-microvolt = <2850000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                       };
-
-                       vgen5_reg: vldo3 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                       };
-
-                       vgen6_reg: vldo4 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                       };
-               };
-       };
-};
-
-&i2c2 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2>;
-       status = "okay";
-
-       ov2680: camera@36 {
-               compatible = "ovti,ov2680";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ov2680>;
-               reg = <0x36>;
-               clocks = <&osc>;
-               clock-names = "xvclk";
-               reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
-               DOVDD-supply = <&sw2_reg>;
-               DVDD-supply = <&sw2_reg>;
-               AVDD-supply = <&reg_peri_3p15v>;
-
-               port {
-                       ov2680_to_mipi: endpoint {
-                               remote-endpoint = <&mipi_from_sensor>;
-                               clock-lanes = <0>;
-                               data-lanes = <1>;
-                       };
-               };
-       };
-};
-
-&i2c3 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3>;
-       status = "okay";
-};
-
-&i2c4 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c4>;
-       status = "okay";
-
-       codec: sgtl5000@a {
-               #sound-dai-cells = <0>;
-               reg = <0x0a>;
-               compatible = "fsl,sgtl5000";
-               clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_sai1_mclk>;
-               VDDA-supply = <&vgen4_reg>;
-               VDDIO-supply = <&vgen4_reg>;
-               VDDD-supply = <&vgen2_reg>;
-       };
-
-       mpl3115@60 {
-               compatible = "fsl,mpl3115";
-               reg = <0x60>;
-       };
-};
-
-&mipi_csi {
-       clock-frequency = <166000000>;
-       status = "okay";
-
-       ports {
-               port@0 {
-                       reg = <0>;
-
-                       mipi_from_sensor: endpoint {
-                               remote-endpoint = <&ov2680_to_mipi>;
-                               data-lanes = <1>;
-                       };
-               };
-       };
-};
-
-&sai1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_sai1>;
-       assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>,
-                         <&clks IMX7D_SAI1_ROOT_CLK>;
-       assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
-       assigned-clock-rates = <0>, <36864000>;
-       status = "okay";
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1>;
-       assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
-       assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
-       status = "okay";
-};
-
-&uart3  {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3>;
-       assigned-clocks = <&clks IMX7D_UART3_ROOT_SRC>;
-       assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
-       uart-has-rtscts;
-       status = "okay";
-};
-
-&uart6 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart6>;
-       assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
-       assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
-       fsl,dte-mode;
-       status = "okay";
-};
-
-&usbotg1 {
-       dr_mode = "peripheral";
-       status = "okay";
-};
-
-&usdhc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc1>;
-       bus-width = <4>;
-       keep-power-in-suspend;
-       no-1-8-v;
-       non-removable;
-       vmmc-supply = <&reg_brcm>;
-       status = "okay";
-};
-
-&usdhc3 {
-       pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc3>;
-       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
-       assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
-       assigned-clock-rates = <400000000>;
-       bus-width = <8>;
-       no-1-8-v;
-       fsl,tuning-step = <2>;
-       non-removable;
-       status = "okay";
-};
-
-&video_mux {
-       status = "okay";
-};
-
-&wdog1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_wdog>;
-       fsl,ext-reset-output;
-       status = "okay";
-};
-
-&iomuxc {
-       pinctrl_brcm_reg: brcmreggrp {
-               fsl,pins = <
-                       MX7D_PAD_SD2_WP__GPIO5_IO10     0x14 /* WL_REG_ON */
-               >;
-       };
-
-       pinctrl_bt_reg: btreggrp {
-               fsl,pins = <
-                       MX7D_PAD_SD2_DATA3__GPIO5_IO17  0x14 /* BT_REG_ON */
-               >;
-       };
-
-       pinctrl_gpio: gpiogrp {
-               fsl,pins = <
-                       MX7D_PAD_ENET1_RGMII_RD1__GPIO7_IO1     0x14
-               >;
-       };
-
-       pinctrl_i2c1: i2c1grp {
-               fsl,pins = <
-                       MX7D_PAD_I2C1_SDA__I2C1_SDA             0x4000007f
-                       MX7D_PAD_I2C1_SCL__I2C1_SCL             0x4000007f
-               >;
-       };
-
-       pinctrl_i2c2: i2c2grp {
-               fsl,pins = <
-                       MX7D_PAD_I2C2_SDA__I2C2_SDA     0x4000007f
-                       MX7D_PAD_I2C2_SCL__I2C2_SCL     0x4000007f
-               >;
-       };
-
-       pinctrl_i2c3: i2c3grp {
-               fsl,pins = <
-                       MX7D_PAD_I2C3_SDA__I2C3_SDA     0x4000007f
-                       MX7D_PAD_I2C3_SCL__I2C3_SCL     0x4000007f
-               >;
-       };
-
-       pinctrl_i2c4: i2c4grp {
-               fsl,pins = <
-                       MX7D_PAD_I2C4_SCL__I2C4_SCL     0x4000007f
-                       MX7D_PAD_I2C4_SDA__I2C4_SDA     0x4000007f
-               >;
-       };
-
-       pinctrl_ov2680: ov2660grp {
-               fsl,pins = <
-                       MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3     0x14
-               >;
-       };
-
-       pinctrl_sai1: sai1grp {
-               fsl,pins = <
-                       MX7D_PAD_SAI1_RX_DATA__SAI1_RX_DATA0    0x1f
-                       MX7D_PAD_SAI1_TX_BCLK__SAI1_TX_BCLK     0x1f
-                       MX7D_PAD_SAI1_TX_SYNC__SAI1_TX_SYNC     0x1f
-                       MX7D_PAD_SAI1_TX_DATA__SAI1_TX_DATA0    0x30
-               >;
-       };
-
-       pinctrl_sai1_mclk: sai1mclkgrp {
-               fsl,pins = <
-                       MX7D_PAD_SAI1_MCLK__SAI1_MCLK           0x1f
-               >;
-       };
-
-       pinctrl_uart1: uart1grp {
-               fsl,pins = <
-                       MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX    0x79
-                       MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX    0x79
-               >;
-       };
-
-       pinctrl_uart3: uart3grp {
-               fsl,pins = <
-                       MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX    0x79
-                       MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX    0x79
-                       MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS     0x79
-                       MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS     0x79
-               >;
-       };
-
-       pinctrl_uart6: uart6grp {
-               fsl,pins = <
-                       MX7D_PAD_ECSPI1_MOSI__UART6_DTE_RX      0x79
-                       MX7D_PAD_ECSPI1_SCLK__UART6_DTE_TX      0x79
-               >;
-       };
-
-       pinctrl_usdhc1: usdhc1grp {
-               fsl,pins = <
-                       MX7D_PAD_SD1_CMD__SD1_CMD       0x59
-                       MX7D_PAD_SD1_CLK__SD1_CLK       0x19
-                       MX7D_PAD_SD1_DATA0__SD1_DATA0   0x59
-                       MX7D_PAD_SD1_DATA1__SD1_DATA1   0x59
-                       MX7D_PAD_SD1_DATA2__SD1_DATA2   0x59
-                       MX7D_PAD_SD1_DATA3__SD1_DATA3   0x59
-                       MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x14 /* WL_HOST_WAKE */
-               >;
-       };
-
-       pinctrl_usdhc3: usdhc3grp {
-               fsl,pins = <
-                       MX7D_PAD_SD3_CMD__SD3_CMD               0x59
-                       MX7D_PAD_SD3_CLK__SD3_CLK               0x19
-                       MX7D_PAD_SD3_DATA0__SD3_DATA0           0x59
-                       MX7D_PAD_SD3_DATA1__SD3_DATA1           0x59
-                       MX7D_PAD_SD3_DATA2__SD3_DATA2           0x59
-                       MX7D_PAD_SD3_DATA3__SD3_DATA3           0x59
-                       MX7D_PAD_SD3_DATA4__SD3_DATA4           0x59
-                       MX7D_PAD_SD3_DATA5__SD3_DATA5           0x59
-                       MX7D_PAD_SD3_DATA6__SD3_DATA6           0x59
-                       MX7D_PAD_SD3_DATA7__SD3_DATA7           0x59
-                       MX7D_PAD_SD3_RESET_B__SD3_RESET_B       0x19
-               >;
-       };
-
-       pinctrl_usdhc3_100mhz: usdhc3grp_100mhz {
-               fsl,pins = <
-                       MX7D_PAD_SD3_CMD__SD3_CMD               0x5a
-                       MX7D_PAD_SD3_CLK__SD3_CLK               0x1a
-                       MX7D_PAD_SD3_DATA0__SD3_DATA0           0x5a
-                       MX7D_PAD_SD3_DATA1__SD3_DATA1           0x5a
-                       MX7D_PAD_SD3_DATA2__SD3_DATA2           0x5a
-                       MX7D_PAD_SD3_DATA3__SD3_DATA3           0x5a
-                       MX7D_PAD_SD3_DATA4__SD3_DATA4           0x5a
-                       MX7D_PAD_SD3_DATA5__SD3_DATA5           0x5a
-                       MX7D_PAD_SD3_DATA6__SD3_DATA6           0x5a
-                       MX7D_PAD_SD3_DATA7__SD3_DATA7           0x5a
-                       MX7D_PAD_SD3_RESET_B__SD3_RESET_B       0x1a
-               >;
-       };
-
-       pinctrl_usdhc3_200mhz: usdhc3grp_200mhz {
-               fsl,pins = <
-                       MX7D_PAD_SD3_CMD__SD3_CMD               0x5b
-                       MX7D_PAD_SD3_CLK__SD3_CLK               0x1b
-                       MX7D_PAD_SD3_DATA0__SD3_DATA0           0x5b
-                       MX7D_PAD_SD3_DATA1__SD3_DATA1           0x5b
-                       MX7D_PAD_SD3_DATA2__SD3_DATA2           0x5b
-                       MX7D_PAD_SD3_DATA3__SD3_DATA3           0x5b
-                       MX7D_PAD_SD3_DATA4__SD3_DATA4           0x5b
-                       MX7D_PAD_SD3_DATA5__SD3_DATA5           0x5b
-                       MX7D_PAD_SD3_DATA6__SD3_DATA6           0x5b
-                       MX7D_PAD_SD3_DATA7__SD3_DATA7           0x5b
-                       MX7D_PAD_SD3_RESET_B__SD3_RESET_B       0x1b
-               >;
-       };
-};
-
-&iomuxc_lpsr {
-       pinctrl_wdog: wdoggrp {
-               fsl,pins = <
-                       MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B  0x74
-               >;
-       };
-};
index 3c0208e13ddabcd30dd263931389cd1f7b29c741..2e68557d6a90585bca5a2470dcd2ed3dd1acc7a3 100644 (file)
@@ -87,6 +87,7 @@ config TARGET_WARP7
        select DM_THERMAL
        select MX7D
        imply CMD_DM
+       imply OF_UPSTREAM
 
 config TARGET_COLIBRI_IMX7
        bool "Support Colibri iMX7S/iMX7D modules"
index 9e323069b9e8652f0291201052ffb24625f69747..27552507564ed9adc610ea8f89d1c650fa9497cb 100644 (file)
--- a/cmd/cpu.c
+++ b/cmd/cpu.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015 Google, Inc
  * Written by Simon Glass <[email protected]>
  * Copyright (c) 2017 Álvaro Fernández Rojas <[email protected]>
+ * Copyright 2024 NXP
  */
 
 #include <command.h>
@@ -18,6 +19,19 @@ static const char *cpu_feature_name[CPU_FEAT_COUNT] = {
        "Device ID",
 };
 
+static struct udevice *cpu_find_device(unsigned long cpu_id)
+{
+       struct udevice *dev;
+
+       for (uclass_first_device(UCLASS_CPU, &dev); dev;
+            uclass_next_device(&dev)) {
+               if (cpu_id == dev_seq(dev))
+                       return dev;
+       }
+
+       return NULL;
+}
+
 static int print_cpu_list(bool detail)
 {
        struct udevice *dev;
@@ -82,10 +96,36 @@ static int do_cpu_detail(struct cmd_tbl *cmdtp, int flag, int argc,
        return 0;
 }
 
+static int do_cpu_release(struct cmd_tbl *cmdtp, int flag, int argc,
+                         char *const argv[])
+{
+       struct udevice *dev;
+       unsigned long cpu_id;
+       unsigned long long boot_addr;
+
+       if (argc != 3)
+               return CMD_RET_USAGE;
+
+       cpu_id = dectoul(argv[1], NULL);
+       dev = cpu_find_device(cpu_id);
+       if (!dev)
+               return CMD_RET_FAILURE;
+
+       boot_addr = simple_strtoull(argv[2], NULL, 16);
+
+       if (cpu_release_core(dev, boot_addr))
+               return CMD_RET_FAILURE;
+
+       return 0;
+}
+
 U_BOOT_LONGHELP(cpu,
        "list   - list available CPUs\n"
-       "cpu detail     - show CPU detail");
+       "cpu detail     - show CPU detail\n"
+       "cpu release <core ID> <addr>   - Release CPU <core ID> at <addr>\n"
+       "            <core ID>: the sequence number in list subcommand outputs");
 
 U_BOOT_CMD_WITH_SUBCMDS(cpu, "display information about CPUs", cpu_help_text,
        U_BOOT_SUBCMD_MKENT(list, 1, 1, do_cpu_list),
-       U_BOOT_SUBCMD_MKENT(detail, 1, 0, do_cpu_detail));
+       U_BOOT_SUBCMD_MKENT(detail, 1, 0, do_cpu_detail),
+       U_BOOT_SUBCMD_MKENT(release, 3, 0, do_cpu_release));
index 4bb9f08977aafa69aa165071f1da5a4060c957a2..83c81edac20f87e3c567e9c33cadc3e144bcb341 100644 (file)
@@ -626,8 +626,17 @@ config CYCLIC
 
 if CYCLIC
 
+config SPL_CYCLIC
+       bool "General-purpose cyclic execution mechanism (SPL)"
+       help
+         This enables a general-purpose cyclic execution infrastructure in SPL,
+         to allow "small" (run-time wise) functions to be executed at
+         a specified frequency. Things like LED blinking or watchdog
+         triggering are examples for such tasks.
+
 config CYCLIC_MAX_CPU_TIME_US
        int "Sets the max allowed time for a cyclic function in us"
+       default 100000 if SANDBOX  # sandbox video is quite slow
        default 5000
        help
          The max allowed time for a cyclic function in us. If a functions
index e9835473420668e5f77a8ef185942cc348d57c51..d871113cbb97654ba980b9ca8dd710b33b598f10 100644 (file)
@@ -79,7 +79,7 @@ obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-y += dlmalloc.o
 obj-$(CONFIG_$(SPL_TPL_)SYS_MALLOC_F) += malloc_simple.o
 
-obj-$(CONFIG_CYCLIC) += cyclic.o
+obj-$(CONFIG_$(SPL_TPL_)CYCLIC) += cyclic.o
 obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o
 
 obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o
index 41765f1ddc55102f5547ecdc2bbce15293af7c28..16ba7d4b4f116e63c0d877285de9241e5bfeb18b 100644 (file)
@@ -46,6 +46,7 @@ CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="u-boot=> "
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_EEPROM=y
 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
index ff33d1532a0da7e5e5b366951c8119862ac425de..8b04586f8617ec8503e38e9fc95df678748c069d 100644 (file)
@@ -118,3 +118,6 @@ CONFIG_SDP_LOADADDR=0x40400000
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_SPL_USB_SDP_SUPPORT=y
 CONFIG_IMX_WATCHDOG=y
+CONFIG_CPU=y
+CONFIG_CPU_IMX=y
+CONFIG_CMD_CPU=y
index 2402e9e8bfb13ac0cf178206725b167ab483dc54..ee7a5e908836d4a6c093345be8674f87ff18ca52 100644 (file)
@@ -105,3 +105,6 @@ CONFIG_SYSRESET_PSCI=y
 CONFIG_SYSRESET_WATCHDOG=y
 CONFIG_DM_THERMAL=y
 CONFIG_IMX_WATCHDOG=y
+CONFIG_CPU=y
+CONFIG_CPU_IMX=y
+CONFIG_CMD_CPU=y
index f5ba022b07599bd586898dc33836e348723242e4..31760699916b86c0a726a51f154e9a78195de9f8 100644 (file)
@@ -137,3 +137,6 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0525
 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
 CONFIG_IMX_WATCHDOG=y
+CONFIG_CPU=y
+CONFIG_CPU_IMX=y
+CONFIG_CMD_CPU=y
index 2246715d822d787bd416bf5edec082a81598e02f..93ab0b9aa3076995c9a5506d263347688cfdf53b 100644 (file)
@@ -52,6 +52,7 @@ CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_CLK=y
+CONFIG_CMD_CPU=y
 CONFIG_CMD_DFU=y
 CONFIG_CMD_FUSE=y
 CONFIG_CMD_GPIO=y
index f9fd7255df76154c5130a753fcd44813b8830d4e..6748e6fafbc4e2be02efbf8c2cbded05c7d1029f 100644 (file)
@@ -12,6 +12,7 @@ CONFIG_DM_GPIO=y
 CONFIG_DEFAULT_DEVICE_TREE="freescale/imx8mm-phyboard-polis-rdk"
 CONFIG_SPL_TEXT_BASE=0x7E1000
 CONFIG_TARGET_PHYCORE_IMX8MM=y
+CONFIG_DM_RESET=y
 CONFIG_SYS_MONITOR_LEN=524288
 CONFIG_SPL_MMC=y
 CONFIG_SPL_SERIAL=y
@@ -23,6 +24,7 @@ CONFIG_SPL_BSS_MAX_SIZE=0x2000
 CONFIG_SPL=y
 CONFIG_ENV_OFFSET_REDUND=0x3E0000
 CONFIG_SYS_LOAD_ADDR=0x40480000
+CONFIG_PCI=y
 CONFIG_FIT=y
 CONFIG_FIT_EXTERNAL_OFFSET=0x3000
 CONFIG_SPL_LOAD_FIT=y
@@ -48,6 +50,7 @@ CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="u-boot=> "
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_EEPROM=y
 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
@@ -59,6 +62,7 @@ CONFIG_CMD_FUSE=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
 CONFIG_CMD_SF_TEST=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
@@ -110,10 +114,15 @@ CONFIG_PHY_TI_DP83867=y
 CONFIG_PHY_GIGE=y
 CONFIG_FEC_MXC=y
 CONFIG_MII=y
+CONFIG_NVME_PCI=y
+CONFIG_PCIE_DW_IMX=y
+CONFIG_PHY=y
+CONFIG_PHY_IMX8M_PCIE=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 CONFIG_PINCTRL_IMX8M=y
-CONFIG_DM_REGULATOR=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_IMX8M_POWER_DOMAIN=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_DM_SERIAL=y
index da7fe612ca03e7bf2a0409fda8b4c6765a8c2d8f..63f8a80ba9942cfcf8c0197be06dd0abbefaad0c 100644 (file)
@@ -52,6 +52,7 @@ CONFIG_SPL_POWER=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_EEPROM=y
 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
index 51e52007efcdbee267256b8ef80e480878e18ea4..6b68681553ce22fbc69939717bdfde4bbbb67f15 100644 (file)
@@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x2300000
 CONFIG_ENV_SIZE=0x2000
 CONFIG_ENV_OFFSET=0x80000
 CONFIG_DM_GPIO=y
-CONFIG_DEFAULT_DEVICE_TREE="imx7s-warp"
+CONFIG_DEFAULT_DEVICE_TREE="nxp/imx/imx7s-warp"
 CONFIG_TARGET_WARP7=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
index 48042b702c226f482d9378df21bf04e4871febd5..679b6e8997ee3603dcf6dff53a6ddb7d626ba1b9 100644 (file)
@@ -5,7 +5,7 @@ CONFIG_NR_DRAM_BANKS=1
 CONFIG_ENV_SIZE=0x2000
 CONFIG_ENV_OFFSET=0xC0000
 CONFIG_DM_GPIO=y
-CONFIG_DEFAULT_DEVICE_TREE="imx7s-warp"
+CONFIG_DEFAULT_DEVICE_TREE="nxp/imx/imx7s-warp"
 CONFIG_TARGET_WARP7=y
 CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
 # CONFIG_ARMV7_VIRT is not set
diff --git a/doc/usage/cmd/cpu.rst b/doc/usage/cmd/cpu.rst
new file mode 100644 (file)
index 0000000..8b0b7d5
--- /dev/null
@@ -0,0 +1,101 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2024 NXP
+
+.. index::
+   single: cpu (command)
+
+cpu command
+===========
+
+Synopsis
+--------
+
+::
+
+    cpu list
+    cpu detail
+    cpu release <core ID> <addr>
+
+Description
+-----------
+
+The *cpu* command prints information about the CPUs, and release a CPU core
+to a given address to run applications.
+
+
+cpu list
+~~~~~~~~
+
+The 'list' subcommand lists and prints brief information of all the CPU cores,
+the CPU information is provided by vendors' CPU driver.
+
+cpu detail
+~~~~~~~~~~
+
+The 'detail' subcommand prints more details about the CPU cores, including
+CPU ID, core frequency and feature list.
+
+cpu release
+~~~~~~~~~~~
+
+The 'release' subcommand is used to release a CPU core to run a baremetal or
+RTOS applications.
+The parameter <core ID> is the sequence number of the CPU core to release.
+The parameter <addr> is the address to run of the specified core after release.
+
+
+Examples
+--------
+
+cpu list
+~~~~~~~~
+
+This example lists all the CPU cores On i.MX8M Plus EVK:
+::
+
+    u-boot=> cpu list
+      0: cpu@0      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+      1: cpu@1      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 30C
+      2: cpu@2      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+      3: cpu@3      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+
+cpu detail
+~~~~~~~~~~
+
+This example prints the details of the CPU cores On i.MX8M Plus EVK:
+::
+
+    u-boot=> cpu detail
+      0: cpu@0      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+      1: cpu@1      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 30C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+      2: cpu@2      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+      3: cpu@3      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+
+cpu release
+~~~~~~~~~~~
+
+This example shows release the LAST CPU core to run a RTOS application, on
+i.MX8M Plus EVK:
+::
+
+     u-boot=> load mmc 1:2 c0000000 /hello_world.bin
+     66008 bytes read in 5 ms (12.6 MiB/s)
+     u-boot=> dcache flush; icache flush
+     u-boot=> cpu release 3 c0000000
+     Released CPU core (mpidr: 0x3) to address 0xc0000000
+
+
+Configuration
+-------------
+
+The cpu command is available if CONFIG_CMD_CPU=y.
+
+Return code
+-----------
+
+The return value $? is set to 0 (true) if the command is successful,
+1 (false) otherwise.
index 49b354e6ffd28f5dfdd536cca21726c2008a284a..1f6518b77c4b44fe83d24abbd11a0de5f2d3d5db 100644 (file)
@@ -50,6 +50,7 @@ Shell commands
    cmd/coninfo
    cmd/conitrace
    cmd/cp
+   cmd/cpu
    cmd/cyclic
    cmd/dm
    cmd/ebtupdate
index c48a62ba099bc5e23e14285f599212ebf491f97b..16169dac23409fc8b49289be22f5783a7024a791 100644 (file)
@@ -178,7 +178,7 @@ int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
 bulk_get_err:
        err = clk_release_all(bulk->clks, bulk->count);
        if (err)
-               debug("%s: could release all clocks for %p\n",
+               debug("%s: could not release all clocks for %p\n",
                      __func__, dev);
 
        return ret;
@@ -609,7 +609,7 @@ int clk_enable(struct clk *clk)
        struct clk *clkp = NULL;
        int ret;
 
-       debug("%s(clk=%p)\n", __func__, clk);
+       debug("%s(clk=%p name=%s)\n", __func__, clk, clk->dev->name);
        if (!clk_valid(clk))
                return 0;
        ops = clk_dev_ops(clk->dev);
@@ -670,7 +670,7 @@ int clk_disable(struct clk *clk)
        struct clk *clkp = NULL;
        int ret;
 
-       debug("%s(clk=%p)\n", __func__, clk);
+       debug("%s(clk=%p name=%s)\n", __func__, clk, clk->dev->name);
        if (!clk_valid(clk))
                return 0;
        ops = clk_dev_ops(clk->dev);
index e538f047b31099e78e9a0d6ae240e68f295fa854..a91c6767fac5834ed0841aaf5ab1f8976c46ef5a 100644 (file)
@@ -21,6 +21,8 @@ static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_se
 static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
 static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
 
+static const char * const imx8mm_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", };
+
 static const char * const imx8mm_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m",
                                               "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
                                               "audio_pll1_out", "sys_pll3_out", };
@@ -417,6 +419,12 @@ static int imx8mm_clk_probe(struct udevice *dev)
               imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
 #endif
 
+       clk_dm(IMX8MM_CLK_ARM,
+              imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1,
+                                 imx8mm_arm_core_sels,
+                                 ARRAY_SIZE(imx8mm_arm_core_sels),
+                                 CLK_IS_CRITICAL));
+
        return 0;
 }
 
index 8911e342f18bd6dfe8b10a8afad313f64c3f5301..125215e84f41c952eb55259820d52d9865cc468b 100644 (file)
@@ -23,6 +23,8 @@ static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_se
 static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
 static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
 
+static const char * const imx8mn_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", };
+
 static const char * const imx8mn_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m",
                                               "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
                                               "audio_pll1_out", "sys_pll3_out", };
@@ -403,6 +405,12 @@ static int imx8mn_clk_probe(struct udevice *dev)
               imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0));
 #endif
 
+       clk_dm(IMX8MN_CLK_ARM,
+              imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1,
+                                 imx8mn_arm_core_sels,
+                                 ARRAY_SIZE(imx8mn_arm_core_sels),
+                                 CLK_IS_CRITICAL));
+
        return 0;
 }
 
index 6b18483c81425f6271856e8f34ca6173a270f132..34d91cd68808e7c9855dbaf3904d3d64c6814c7c 100644 (file)
@@ -21,6 +21,8 @@ static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_se
 static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
 static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
 
+static const char * const imx8mp_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", };
+
 static const char * const imx8mp_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m",
                                               "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
                                               "audio_pll1_out", "sys_pll3_out", };
@@ -354,6 +356,12 @@ static int imx8mp_clk_probe(struct udevice *dev)
 
        clk_dm(IMX8MP_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
 
+       clk_dm(IMX8MP_CLK_ARM,
+              imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1,
+                                 imx8mp_arm_core_sels,
+                                 ARRAY_SIZE(imx8mp_arm_core_sels),
+                                 CLK_IS_CRITICAL));
+
        return 0;
 }
 
index d2c45be30decb552ce3bb435c6468919c3832b8b..66683aeb2d72027cd3a2c2d36f7d199a13027411 100644 (file)
 
 /* shared functions */
 
+static int mtk_clk_get_id(struct clk *clk)
+{
+       struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+       int id = clk->id;
+
+       /* Remap the clk ID to the one expected by driver */
+       if (priv->tree->id_offs_map)
+               id = priv->tree->id_offs_map[id];
+
+       return id;
+}
+
+static int mtk_gate_enable(void __iomem *base, const struct mtk_gate *gate)
+{
+       u32 bit = BIT(gate->shift);
+
+       switch (gate->flags & CLK_GATE_MASK) {
+       case CLK_GATE_SETCLR:
+               writel(bit, base + gate->regs->clr_ofs);
+               break;
+       case CLK_GATE_SETCLR_INV:
+               writel(bit, base + gate->regs->set_ofs);
+               break;
+       case CLK_GATE_NO_SETCLR:
+               clrsetbits_le32(base + gate->regs->sta_ofs, bit, 0);
+               break;
+       case CLK_GATE_NO_SETCLR_INV:
+               clrsetbits_le32(base + gate->regs->sta_ofs, bit, bit);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int mtk_gate_disable(void __iomem *base, const struct mtk_gate *gate)
+{
+       u32 bit = BIT(gate->shift);
+
+       switch (gate->flags & CLK_GATE_MASK) {
+       case CLK_GATE_SETCLR:
+               writel(bit, base + gate->regs->set_ofs);
+               break;
+       case CLK_GATE_SETCLR_INV:
+               writel(bit, base + gate->regs->clr_ofs);
+               break;
+       case CLK_GATE_NO_SETCLR:
+               clrsetbits_le32(base + gate->regs->sta_ofs, bit, bit);
+               break;
+       case CLK_GATE_NO_SETCLR_INV:
+               clrsetbits_le32(base + gate->regs->sta_ofs, bit, 0);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 /*
  * In case the rate change propagation to parent clocks is undesirable,
  * this function is recursively called to find the parent to calculate
@@ -54,13 +116,27 @@ static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
 }
 
 static int mtk_clk_mux_set_parent(void __iomem *base, u32 parent,
+                                 u32 parent_type,
                                  const struct mtk_composite *mux)
 {
        u32 val, index = 0;
 
-       while (mux->parent[index] != parent)
-               if (++index == mux->num_parents)
-                       return -EINVAL;
+       if (mux->flags & CLK_PARENT_MIXED) {
+               /*
+                * Assume parent_type in clk_tree to be always set with
+                * CLK_PARENT_MIXED implementation. If it's not, assume
+                * not parent clk ID clash is possible.
+                */
+               while (mux->parent_flags[index].id != parent ||
+                      (parent_type && (mux->parent_flags[index].flags & CLK_PARENT_MASK) !=
+                       parent_type))
+                       if (++index == mux->num_parents)
+                               return -EINVAL;
+       } else {
+               while (mux->parent[index] != parent)
+                       if (++index == mux->num_parents)
+                               return -EINVAL;
+       }
 
        if (mux->flags & CLK_MUX_SETCLR_UPD) {
                val = (mux->mux_mask << mux->mux_shift);
@@ -117,12 +193,14 @@ static unsigned long __mtk_pll_recalc_rate(const struct mtk_pll_data *pll,
  * for the integer part and the remaining bits (if present) for the
  * fractional part. Also they have a 3 bit power-of-two post divider.
  */
-static void mtk_pll_set_rate_regs(struct clk *clk, u32 pcw, int postdiv)
+static void mtk_pll_set_rate_regs(struct mtk_clk_priv *priv, u32 id,
+                                 u32 pcw, int postdiv)
 {
-       struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+       const struct mtk_pll_data *pll;
        u32 val, chg;
 
+       pll = &priv->tree->plls[id];
+
        /* set postdiv */
        val = readl(priv->base + pll->pd_reg);
        val &= ~(POSTDIV_MASK << pll->pd_shift);
@@ -153,21 +231,24 @@ static void mtk_pll_set_rate_regs(struct clk *clk, u32 pcw, int postdiv)
 
 /**
  * mtk_pll_calc_values - calculate good values for a given input frequency.
- * @clk:       The clk
+ * @priv:      The mtk priv struct
+ * @id:                The clk id
  * @pcw:       The pcw value (output)
  * @postdiv:   The post divider (output)
  * @freq:      The desired target frequency
  */
-static void mtk_pll_calc_values(struct clk *clk, u32 *pcw, u32 *postdiv,
-                               u32 freq)
+static void mtk_pll_calc_values(struct mtk_clk_priv *priv, u32 id,
+                               u32 *pcw, u32 *postdiv, u32 freq)
 {
-       struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
-       unsigned long fmin = pll->fmin ? pll->fmin : 1000 * MHZ;
+       const struct mtk_pll_data *pll;
+       unsigned long fmin;
        u64 _pcw;
        int ibits;
        u32 val;
 
+       pll = &priv->tree->plls[id];
+       fmin = pll->fmin ? pll->fmin : 1000 * MHZ;
+
        if (freq > pll->fmax)
                freq = pll->fmax;
 
@@ -187,11 +268,16 @@ static void mtk_pll_calc_values(struct clk *clk, u32 *pcw, u32 *postdiv,
 
 static ulong mtk_apmixedsys_set_rate(struct clk *clk, ulong rate)
 {
+       struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+       int id = mtk_clk_get_id(clk);
        u32 pcw = 0;
        u32 postdiv;
 
-       mtk_pll_calc_values(clk, &pcw, &postdiv, rate);
-       mtk_pll_set_rate_regs(clk, pcw, postdiv);
+       if (priv->tree->gates && id >= priv->tree->gates_offs)
+               return -EINVAL;
+
+       mtk_pll_calc_values(priv, id, &pcw, &postdiv, rate);
+       mtk_pll_set_rate_regs(priv, id, pcw, postdiv);
 
        return 0;
 }
@@ -199,10 +285,20 @@ static ulong mtk_apmixedsys_set_rate(struct clk *clk, ulong rate)
 static ulong mtk_apmixedsys_get_rate(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+       const struct mtk_pll_data *pll;
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
        u32 postdiv;
        u32 pcw;
 
+       /* GATE handling */
+       if (priv->tree->gates && id >= priv->tree->gates_offs) {
+               gate = &priv->tree->gates[id - priv->tree->gates_offs];
+               return mtk_clk_find_parent_rate(clk, gate->parent, NULL);
+       }
+
+       pll = &priv->tree->plls[id];
+
        postdiv = (readl(priv->base + pll->pd_reg) >> pll->pd_shift) &
                   POSTDIV_MASK;
        postdiv = 1 << postdiv;
@@ -217,9 +313,19 @@ static ulong mtk_apmixedsys_get_rate(struct clk *clk)
 static int mtk_apmixedsys_enable(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+       const struct mtk_pll_data *pll;
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
        u32 r;
 
+       /* GATE handling */
+       if (priv->tree->gates && id >= priv->tree->gates_offs) {
+               gate = &priv->tree->gates[id - priv->tree->gates_offs];
+               return mtk_gate_enable(priv->base, gate);
+       }
+
+       pll = &priv->tree->plls[id];
+
        r = readl(priv->base + pll->pwr_reg) | CON0_PWR_ON;
        writel(r, priv->base + pll->pwr_reg);
        udelay(1);
@@ -246,9 +352,19 @@ static int mtk_apmixedsys_enable(struct clk *clk)
 static int mtk_apmixedsys_disable(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+       const struct mtk_pll_data *pll;
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
        u32 r;
 
+       /* GATE handling */
+       if (priv->tree->gates && id >= priv->tree->gates_offs) {
+               gate = &priv->tree->gates[id - priv->tree->gates_offs];
+               return mtk_gate_disable(priv->base, gate);
+       }
+
+       pll = &priv->tree->plls[id];
+
        if (pll->flags & HAVE_RST_BAR) {
                r = readl(priv->base + pll->reg + REG_CON0);
                r &= ~pll->rst_bar_mask;
@@ -324,6 +440,19 @@ static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off)
        return mtk_factor_recalc_rate(fdiv, rate);
 }
 
+static ulong mtk_topckgen_find_parent_rate(struct mtk_clk_priv *priv, struct clk *clk,
+                                          const int parent, u16 flags)
+{
+       switch (flags & CLK_PARENT_MASK) {
+       case CLK_PARENT_XTAL:
+               return priv->tree->xtal_rate;
+       case CLK_PARENT_APMIXED:
+               return mtk_clk_find_parent_rate(clk, parent, priv->parent);
+       default:
+               return mtk_clk_find_parent_rate(clk, parent, NULL);
+       }
+}
+
 static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
@@ -334,22 +463,40 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
        index &= mux->mux_mask << mux->mux_shift;
        index = index >> mux->mux_shift;
 
-       if (mux->parent[index] > 0 ||
-           (mux->parent[index] == CLK_XTAL &&
-            priv->tree->flags & CLK_BYPASS_XTAL)) {
-               switch (mux->flags & CLK_PARENT_MASK) {
-               case CLK_PARENT_APMIXED:
-                       return mtk_clk_find_parent_rate(clk, mux->parent[index],
-                                                       priv->parent);
-                       break;
-               default:
-                       return mtk_clk_find_parent_rate(clk, mux->parent[index],
-                                                       NULL);
-                       break;
-               }
+       /*
+        * Parents can be either from APMIXED or TOPCKGEN,
+        * inspect the mtk_parent struct to check the source
+        */
+       if (mux->flags & CLK_PARENT_MIXED) {
+               const struct mtk_parent *parent = &mux->parent_flags[index];
+
+               return mtk_topckgen_find_parent_rate(priv, clk, parent->id,
+                                                    parent->flags);
        }
 
-       return priv->tree->xtal_rate;
+       if (mux->parent[index] == CLK_XTAL &&
+           !(priv->tree->flags & CLK_BYPASS_XTAL))
+               return priv->tree->xtal_rate;
+
+       return mtk_topckgen_find_parent_rate(priv, clk, mux->parent[index],
+                                            mux->flags);
+}
+
+static ulong mtk_find_parent_rate(struct mtk_clk_priv *priv, struct clk *clk,
+                                 const int parent, u16 flags)
+{
+       switch (flags & CLK_PARENT_MASK) {
+       case CLK_PARENT_XTAL:
+               return priv->tree->xtal_rate;
+       /* Assume the second level parent is always APMIXED */
+       case CLK_PARENT_APMIXED:
+               priv = dev_get_priv(priv->parent);
+               fallthrough;
+       case CLK_PARENT_TOPCKGEN:
+               return mtk_clk_find_parent_rate(clk, parent, priv->parent);
+       default:
+               return mtk_clk_find_parent_rate(clk, parent, NULL);
+       }
 }
 
 static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off)
@@ -362,51 +509,69 @@ static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off)
        index &= mux->mux_mask << mux->mux_shift;
        index = index >> mux->mux_shift;
 
-       if (mux->parent[index] > 0 ||
-           (mux->parent[index] == CLK_XTAL &&
-            priv->tree->flags & CLK_BYPASS_XTAL)) {
-               switch (mux->flags & CLK_PARENT_MASK) {
-               case CLK_PARENT_TOPCKGEN:
-                       return mtk_clk_find_parent_rate(clk, mux->parent[index],
-                                                       priv->parent);
-                       break;
-               default:
-                       return mtk_clk_find_parent_rate(clk, mux->parent[index],
-                                                       NULL);
-                       break;
-               }
+       /*
+        * Parents can be either from TOPCKGEN or INFRACFG,
+        * inspect the mtk_parent struct to check the source
+        */
+       if (mux->flags & CLK_PARENT_MIXED) {
+               const struct mtk_parent *parent = &mux->parent_flags[index];
+
+               return mtk_find_parent_rate(priv, clk, parent->id, parent->flags);
        }
-       return 0;
+
+       if (mux->parent[index] == CLK_XTAL &&
+           !(priv->tree->flags & CLK_BYPASS_XTAL))
+               return priv->tree->xtal_rate;
+
+       return mtk_find_parent_rate(priv, clk, mux->parent[index], mux->flags);
 }
 
 static ulong mtk_topckgen_get_rate(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+       int id = mtk_clk_get_id(clk);
 
-       if (clk->id < priv->tree->fdivs_offs)
-               return priv->tree->fclks[clk->id].rate;
-       else if (clk->id < priv->tree->muxes_offs)
-               return mtk_topckgen_get_factor_rate(clk, clk->id -
+       if (id < priv->tree->fdivs_offs)
+               return priv->tree->fclks[id].rate;
+       else if (id < priv->tree->muxes_offs)
+               return mtk_topckgen_get_factor_rate(clk, id -
                                                    priv->tree->fdivs_offs);
        else
-               return mtk_topckgen_get_mux_rate(clk, clk->id -
+               return mtk_topckgen_get_mux_rate(clk, id -
                                                 priv->tree->muxes_offs);
 }
 
 static ulong mtk_infrasys_get_rate(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-
+       int id = mtk_clk_get_id(clk);
        ulong rate;
 
-       if (clk->id < priv->tree->fdivs_offs) {
-               rate = priv->tree->fclks[clk->id].rate;
-       } else if (clk->id < priv->tree->muxes_offs) {
-               rate = mtk_infrasys_get_factor_rate(clk, clk->id -
+       if (id < priv->tree->fdivs_offs) {
+               rate = priv->tree->fclks[id].rate;
+       } else if (id < priv->tree->muxes_offs) {
+               rate = mtk_infrasys_get_factor_rate(clk, id -
                                                    priv->tree->fdivs_offs);
-       } else {
-               rate = mtk_infrasys_get_mux_rate(clk, clk->id -
+       /* No gates defined or ID is a MUX */
+       } else if (!priv->tree->gates || id < priv->tree->gates_offs) {
+               rate = mtk_infrasys_get_mux_rate(clk, id -
                                                 priv->tree->muxes_offs);
+       /* Only valid with muxes + gates implementation */
+       } else {
+               struct udevice *parent = NULL;
+               const struct mtk_gate *gate;
+
+               gate = &priv->tree->gates[id - priv->tree->gates_offs];
+               if (gate->flags & CLK_PARENT_TOPCKGEN)
+                       parent = priv->parent;
+               /*
+                * Assume xtal_rate to be declared if some gates have
+                * XTAL as parent
+                */
+               else if (gate->flags & CLK_PARENT_XTAL)
+                       return priv->tree->xtal_rate;
+
+               rate = mtk_clk_find_parent_rate(clk, gate->parent, parent);
        }
 
        return rate;
@@ -416,12 +581,13 @@ static int mtk_clk_mux_enable(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
        const struct mtk_composite *mux;
+       int id = mtk_clk_get_id(clk);
        u32 val;
 
-       if (clk->id < priv->tree->muxes_offs)
+       if (id < priv->tree->muxes_offs)
                return 0;
 
-       mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+       mux = &priv->tree->muxes[id - priv->tree->muxes_offs];
        if (mux->gate_shift < 0)
                return 0;
 
@@ -449,12 +615,13 @@ static int mtk_clk_mux_disable(struct clk *clk)
 {
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
        const struct mtk_composite *mux;
+       int id = mtk_clk_get_id(clk);
        u32 val;
 
-       if (clk->id < priv->tree->muxes_offs)
+       if (id < priv->tree->muxes_offs)
                return 0;
 
-       mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+       mux = &priv->tree->muxes[id - priv->tree->muxes_offs];
        if (mux->gate_shift < 0)
                return 0;
 
@@ -473,13 +640,20 @@ static int mtk_clk_mux_disable(struct clk *clk)
 
 static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent)
 {
+       struct mtk_clk_priv *parent_priv = dev_get_priv(parent->dev);
        struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+       int id = mtk_clk_get_id(clk);
+       u32 parent_type;
+
+       if (id < priv->tree->muxes_offs)
+               return 0;
 
-       if (clk->id < priv->tree->muxes_offs)
+       if (!parent_priv)
                return 0;
 
-       return mtk_clk_mux_set_parent(priv->base, parent->id,
-                       &priv->tree->muxes[clk->id - priv->tree->muxes_offs]);
+       parent_type = parent_priv->tree->flags & CLK_PARENT_MASK;
+       return mtk_clk_mux_set_parent(priv->base, parent->id, parent_type,
+                       &priv->tree->muxes[id - priv->tree->muxes_offs]);
 }
 
 /* CG functions */
@@ -487,63 +661,88 @@ static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent)
 static int mtk_clk_gate_enable(struct clk *clk)
 {
        struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_gate *gate = &priv->gates[clk->id];
-       u32 bit = BIT(gate->shift);
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
 
-       switch (gate->flags & CLK_GATE_MASK) {
-       case CLK_GATE_SETCLR:
-               writel(bit, priv->base + gate->regs->clr_ofs);
-               break;
-       case CLK_GATE_SETCLR_INV:
-               writel(bit, priv->base + gate->regs->set_ofs);
-               break;
-       case CLK_GATE_NO_SETCLR:
-               clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, 0);
-               break;
-       case CLK_GATE_NO_SETCLR_INV:
-               clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, bit);
-               break;
-
-       default:
+       if (id < priv->tree->gates_offs)
                return -EINVAL;
-       }
 
-       return 0;
+       gate = &priv->gates[id - priv->tree->gates_offs];
+       return mtk_gate_enable(priv->base, gate);
 }
 
-static int mtk_clk_gate_disable(struct clk *clk)
+static int mtk_clk_infrasys_enable(struct clk *clk)
 {
        struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_gate *gate = &priv->gates[clk->id];
-       u32 bit = BIT(gate->shift);
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
 
-       switch (gate->flags & CLK_GATE_MASK) {
-       case CLK_GATE_SETCLR:
-               writel(bit, priv->base + gate->regs->set_ofs);
-               break;
-       case CLK_GATE_SETCLR_INV:
-               writel(bit, priv->base + gate->regs->clr_ofs);
-               break;
-       case CLK_GATE_NO_SETCLR:
-               clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, bit);
-               break;
-       case CLK_GATE_NO_SETCLR_INV:
-               clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, 0);
-               break;
+       /* MUX handling */
+       if (!priv->tree->gates || id < priv->tree->gates_offs)
+               return mtk_clk_mux_enable(clk);
 
-       default:
+       gate = &priv->tree->gates[id - priv->tree->gates_offs];
+       return mtk_gate_enable(priv->base, gate);
+}
+
+static int mtk_clk_gate_disable(struct clk *clk)
+{
+       struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
+
+       if (id < priv->tree->gates_offs)
                return -EINVAL;
-       }
 
-       return 0;
+       gate = &priv->gates[id - priv->tree->gates_offs];
+       return mtk_gate_disable(priv->base, gate);
+}
+
+static int mtk_clk_infrasys_disable(struct clk *clk)
+{
+       struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
+
+       /* MUX handling */
+       if (!priv->tree->gates || id < priv->tree->gates_offs)
+               return mtk_clk_mux_disable(clk);
+
+       gate = &priv->tree->gates[id - priv->tree->gates_offs];
+       return mtk_gate_disable(priv->base, gate);
 }
 
 static ulong mtk_clk_gate_get_rate(struct clk *clk)
 {
        struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
-       const struct mtk_gate *gate = &priv->gates[clk->id];
+       struct udevice *parent = priv->parent;
+       int id = mtk_clk_get_id(clk);
+       const struct mtk_gate *gate;
+
+       if (id < priv->tree->gates_offs)
+               return -EINVAL;
+
+       gate = &priv->gates[id - priv->tree->gates_offs];
+       /*
+        * With requesting a TOPCKGEN parent, make sure the dev parent
+        * is actually topckgen. This might not be the case for an
+        * infracfg-ao implementation where:
+        * parent = infracfg
+        * parent->parent = topckgen
+        */
+       if (gate->flags & CLK_PARENT_TOPCKGEN &&
+           parent->driver != DM_DRIVER_GET(mtk_clk_topckgen)) {
+               priv = dev_get_priv(parent);
+               parent = priv->parent;
+       /*
+        * Assume xtal_rate to be declared if some gates have
+        * XTAL as parent
+        */
+       } else if (gate->flags & CLK_PARENT_XTAL) {
+               return priv->tree->xtal_rate;
+       }
 
-       return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent);
+       return mtk_clk_find_parent_rate(clk, gate->parent, parent);
 }
 
 const struct clk_ops mtk_clk_apmixedsys_ops = {
@@ -561,8 +760,8 @@ const struct clk_ops mtk_clk_topckgen_ops = {
 };
 
 const struct clk_ops mtk_clk_infrasys_ops = {
-       .enable = mtk_clk_mux_enable,
-       .disable = mtk_clk_mux_disable,
+       .enable = mtk_clk_infrasys_enable,
+       .disable = mtk_clk_infrasys_disable,
        .get_rate = mtk_infrasys_get_rate,
        .set_parent = mtk_common_clk_set_parent,
 };
@@ -573,8 +772,9 @@ const struct clk_ops mtk_clk_gate_ops = {
        .get_rate = mtk_clk_gate_get_rate,
 };
 
-int mtk_common_clk_init(struct udevice *dev,
-                       const struct mtk_clk_tree *tree)
+static int mtk_common_clk_init_drv(struct udevice *dev,
+                                  const struct mtk_clk_tree *tree,
+                                  const struct driver *drv)
 {
        struct mtk_clk_priv *priv = dev_get_priv(dev);
        struct udevice *parent;
@@ -586,8 +786,7 @@ int mtk_common_clk_init(struct udevice *dev,
 
        ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
        if (ret || !parent) {
-               ret = uclass_get_device_by_driver(UCLASS_CLK,
-                               DM_DRIVER_GET(mtk_clk_apmixedsys), &parent);
+               ret = uclass_get_device_by_driver(UCLASS_CLK, drv, &parent);
                if (ret || !parent)
                        return -ENOENT;
        }
@@ -598,6 +797,20 @@ int mtk_common_clk_init(struct udevice *dev,
        return 0;
 }
 
+int mtk_common_clk_init(struct udevice *dev,
+                       const struct mtk_clk_tree *tree)
+{
+       return mtk_common_clk_init_drv(dev, tree,
+                                      DM_DRIVER_GET(mtk_clk_apmixedsys));
+}
+
+int mtk_common_clk_infrasys_init(struct udevice *dev,
+                                const struct mtk_clk_tree *tree)
+{
+       return mtk_common_clk_init_drv(dev, tree,
+                                      DM_DRIVER_GET(mtk_clk_topckgen));
+}
+
 int mtk_common_clk_gate_init(struct udevice *dev,
                             const struct mtk_clk_tree *tree,
                             const struct mtk_gate *gates)
index 48ce16484ec2a414b111bd6acac03d8ad4cd32ef..c1d9901c10bcdd13ba43a8709d56514d2febf05f 100644 (file)
 
 /* flags in struct mtk_clk_tree */
 
-/* clk id == 0 doesn't mean it's xtal clk */
+/* clk id == 0 doesn't mean it's xtal clk
+ * This doesn't apply when CLK_PARENT_MIXED is defined.
+ * With CLK_PARENT_MIXED declare CLK_PARENT_XTAL for the
+ * relevant parent.
+ */
 #define CLK_BYPASS_XTAL                        BIT(0)
 
 #define HAVE_RST_BAR                   BIT(0)
 #define CLK_PARENT_TOPCKGEN            BIT(5)
 #define CLK_PARENT_INFRASYS            BIT(6)
 #define CLK_PARENT_XTAL                        BIT(7)
-#define CLK_PARENT_MASK                        GENMASK(7, 4)
+/*
+ * For CLK_PARENT_MIXED to correctly work, is required to
+ * define in clk_tree flags the clk type using the alias.
+ */
+#define CLK_PARENT_MIXED               BIT(8)
+#define CLK_PARENT_MASK                        GENMASK(8, 4)
+
+/* alias to reference clk type */
+#define CLK_APMIXED                    CLK_PARENT_APMIXED
+#define CLK_TOPCKGEN                   CLK_PARENT_TOPCKGEN
+#define CLK_INFRASYS                   CLK_PARENT_INFRASYS
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS     0x34
 
@@ -97,11 +111,31 @@ struct mtk_fixed_factor {
                .flags = _flags,                        \
        }
 
+/**
+ * struct mtk_parent -  clock parent with flags. Needed for MUX that
+ *                     parent with mixed infracfg and topckgen.
+ *
+ * @id:                        index of parent clocks
+ * @flags:             hardware-specific flags (parent location,
+ *                     infracfg, topckgen, APMIXED, xtal ...)
+ */
+struct mtk_parent {
+       const int id;
+       u16 flags;
+};
+
+#define PARENT(_id, _flags) {                          \
+               .id = _id,                              \
+               .flags = _flags,                        \
+       }
+
 /**
  * struct mtk_composite - aggregate clock of mux, divider and gate clocks
  *
  * @id:                        index of clocks
  * @parent:            index of parnet clocks
+ * @parent:            index of parnet clocks
+ * @parent_flags:      table of parent clocks with flags
  * @mux_reg:           hardware-specific mux register
  * @gate_reg:          hardware-specific gate register
  * @mux_mask:          mask to the mux bit field
@@ -112,7 +146,10 @@ struct mtk_fixed_factor {
  */
 struct mtk_composite {
        const int id;
-       const int *parent;
+       union {
+               const int *parent;
+               const struct mtk_parent *parent_flags;
+       };
        u32 mux_reg;
        u32 mux_set_reg;
        u32 mux_clr_reg;
@@ -142,7 +179,20 @@ struct mtk_composite {
 #define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate)           \
        MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
 
-#define MUX(_id, _parents, _reg, _shift, _width) {                     \
+#define MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, _flags) { \
+               .id = _id,                                              \
+               .mux_reg = _reg,                                        \
+               .mux_shift = _shift,                                    \
+               .mux_mask = BIT(_width) - 1,                            \
+               .gate_shift = -1,                                       \
+               .parent_flags = _parents,                               \
+               .num_parents = ARRAY_SIZE(_parents),                    \
+               .flags = CLK_PARENT_MIXED | (_flags),                   \
+       }
+#define MUX_MIXED(_id, _parents, _reg, _shift, _width)                 \
+       MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, 0)
+
+#define MUX_FLAGS(_id, _parents, _reg, _shift, _width, _flags) {       \
                .id = _id,                                              \
                .mux_reg = _reg,                                        \
                .mux_shift = _shift,                                    \
@@ -150,8 +200,10 @@ struct mtk_composite {
                .gate_shift = -1,                                       \
                .parent = _parents,                                     \
                .num_parents = ARRAY_SIZE(_parents),                    \
-               .flags = 0,                                             \
+               .flags = _flags,                                        \
        }
+#define MUX(_id, _parents, _reg, _shift, _width)                       \
+       MUX_FLAGS(_id, _parents, _reg, _shift, _width, 0)
 
 #define MUX_CLR_SET_UPD_FLAGS(_id, _parents, _mux_ofs, _mux_set_ofs,\
                        _mux_clr_ofs, _shift, _width, _gate,            \
@@ -198,12 +250,22 @@ struct mtk_gate {
 struct mtk_clk_tree {
        unsigned long xtal_rate;
        unsigned long xtal2_rate;
+       /*
+        * Clock ID offset are remapped with an auxiliary table.
+        * Enable this by defining .id_offs_map.
+        * This is needed for upstream linux kernel <soc>-clk.h that
+        * have mixed clk ID and doesn't have clear distinction between
+        * ID for factor, mux and gates.
+        */
+       const int *id_offs_map; /* optional, table clk.h to driver ID */
        const int fdivs_offs;
        const int muxes_offs;
+       const int gates_offs;
        const struct mtk_pll_data *plls;
        const struct mtk_fixed_clk *fclks;
        const struct mtk_fixed_factor *fdivs;
        const struct mtk_composite *muxes;
+       const struct mtk_gate *gates;
        u32 flags;
 };
 
@@ -227,6 +289,8 @@ extern const struct clk_ops mtk_clk_gate_ops;
 
 int mtk_common_clk_init(struct udevice *dev,
                        const struct mtk_clk_tree *tree);
+int mtk_common_clk_infrasys_init(struct udevice *dev,
+                                const struct mtk_clk_tree *tree);
 int mtk_common_clk_gate_init(struct udevice *dev,
                             const struct mtk_clk_tree *tree,
                             const struct mtk_gate *gates);
index 16f8f2e52194a33869ad733a33cb0b9297f8d3ee..2c8e46c05e39259e2d0a3e018f2ca26e3f8e1479 100644 (file)
@@ -104,6 +104,16 @@ int cpu_get_vendor(const struct udevice *dev, char *buf, int size)
        return ops->get_vendor(dev, buf, size);
 }
 
+int cpu_release_core(const struct udevice *dev, phys_addr_t addr)
+{
+       struct cpu_ops *ops = cpu_get_ops(dev);
+
+       if (!ops->release_core)
+               return -ENOSYS;
+
+       return ops->release_core(dev, addr);
+}
+
 U_BOOT_DRIVER(cpu_bus) = {
        .name   = "cpu_bus",
        .id     = UCLASS_SIMPLE_BUS,
index e65e1bdc51bfafe93b303c12ae8aabb8503eb267..b15279578315c486d53ad1f278f469bd7a874922 100644 (file)
@@ -44,6 +44,11 @@ void cpu_sandbox_set_current(const char *name)
        cpu_current = name;
 }
 
+static int cpu_sandbox_release_core(const struct udevice *dev, phys_addr_t addr)
+{
+       return 0;
+}
+
 static int cpu_sandbox_is_current(struct udevice *dev)
 {
        if (!strcmp(dev->name, cpu_current))
@@ -58,6 +63,7 @@ static const struct cpu_ops cpu_sandbox_ops = {
        .get_count = cpu_sandbox_get_count,
        .get_vendor = cpu_sandbox_get_vendor,
        .is_current = cpu_sandbox_is_current,
+       .release_core = cpu_sandbox_release_core,
 };
 
 static int cpu_sandbox_bind(struct udevice *dev)
index 4781a565547a15e032038fb49060666867ffbe44..60deca963a6733f4e9ad4404cc891619cab601dd 100644 (file)
@@ -1,12 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright 2019 NXP
+ * Copyright 2019, 2024 NXP
  */
 
 #include <cpu.h>
 #include <dm.h>
 #include <thermal.h>
 #include <asm/global_data.h>
+#include <asm/ptrace.h>
 #include <asm/system.h>
 #include <firmware/imx/sci/sci.h>
 #include <asm/arch/sys_proto.h>
@@ -15,6 +16,7 @@
 #include <imx_thermal.h>
 #include <linux/bitops.h>
 #include <linux/clk-provider.h>
+#include <linux/psci.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -31,6 +33,12 @@ struct cpu_imx_plat {
 static const char *get_imx_type_str(u32 imxtype)
 {
        switch (imxtype) {
+       case MXC_CPU_IMX8MM:
+               return "8MM";
+       case MXC_CPU_IMX8MN:
+               return "8MN";
+       case MXC_CPU_IMX8MP:
+               return "8MP";
        case MXC_CPU_IMX8QXP:
        case MXC_CPU_IMX8QXP_A0:
                return "8QXP";
@@ -184,8 +192,6 @@ static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size)
                        ret = snprintf(buf, size, " - invalid sensor data");
        }
 
-       snprintf(buf + ret, size - ret, "\n");
-
        return 0;
 }
 
@@ -193,7 +199,7 @@ static int cpu_imx_get_info(const struct udevice *dev, struct cpu_info *info)
 {
        struct cpu_imx_plat *plat = dev_get_plat(dev);
 
-       info->cpu_freq = plat->freq_mhz * 1000;
+       info->cpu_freq = plat->freq_mhz * 1000000;
        info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
        return 0;
 }
@@ -236,12 +242,34 @@ static int cpu_imx_is_current(struct udevice *dev)
        return 0;
 }
 
+static int cpu_imx_release_core(const struct udevice *dev, phys_addr_t addr)
+{
+       struct cpu_imx_plat *plat = dev_get_plat(dev);
+       struct pt_regs regs;
+
+       regs.regs[0] = PSCI_0_2_FN64_CPU_ON;
+       regs.regs[1] = plat->mpidr;
+       regs.regs[2] = addr;
+       regs.regs[3] = 0;
+
+       smc_call(&regs);
+       if (regs.regs[0]) {
+               printf("Failed to release CPU core (mpidr: 0x%x)\n", plat->mpidr);
+               return -1;
+       }
+
+       printf("Released CPU core (mpidr: 0x%x) to address 0x%llx\n", plat->mpidr, addr);
+
+       return 0;
+}
+
 static const struct cpu_ops cpu_imx_ops = {
        .get_desc       = cpu_imx_get_desc,
        .get_info       = cpu_imx_get_info,
        .get_count      = cpu_imx_get_count,
        .get_vendor     = cpu_imx_get_vendor,
        .is_current     = cpu_imx_is_current,
+       .release_core   = cpu_imx_release_core,
 };
 
 static const struct udevice_id cpu_imx_ids[] = {
@@ -287,7 +315,7 @@ static int imx_cpu_probe(struct udevice *dev)
        cpurev = get_cpu_rev();
        plat->cpurev = cpurev;
        plat->rev = get_imx_rev_str(cpurev & 0xFFF);
-       plat->type = get_imx_type_str((cpurev & 0xFF000) >> 12);
+       plat->type = get_imx_type_str((cpurev & 0x1FF000) >> 12);
        plat->freq_mhz = imx_get_cpu_rate(dev) / 1000000;
        plat->mpidr = dev_read_addr(dev);
        if (plat->mpidr == FDT_ADDR_T_NONE) {
index 67ac86f82bcd1dd1aae2d966e6ce98f25d1f03e5..43f0ec7637d803a650a2f98194b60728b75e7ca1 100644 (file)
@@ -50,6 +50,7 @@
 #include <asm/arch/clock.h>
 #include <asm/mach-imx/sys_proto.h>
 #endif
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/printk.h>
 
@@ -146,6 +147,25 @@ static int eqos_mdio_wait_idle(struct eqos_priv *eqos)
                                 1000000, true);
 }
 
+/* Bitmask common for mdio_read and mdio_write */
+#define EQOS_MDIO_BITFIELD(pa, rda, cr) \
+       FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_PA_MASK, pa)   | \
+       FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_RDA_MASK, rda) | \
+       FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_CR_MASK, cr)   | \
+       EQOS_MAC_MDIO_ADDRESS_GB
+
+static u32 eqos_mdio_bitfield(struct eqos_priv *eqos, int addr, int devad, int reg)
+{
+       int cr = eqos->config->config_mac_mdio;
+       bool c22 = devad == MDIO_DEVAD_NONE ? true : false;
+
+       if (c22)
+               return EQOS_MDIO_BITFIELD(addr, reg, cr);
+       else
+               return EQOS_MDIO_BITFIELD(addr, devad, cr) |
+                      EQOS_MAC_MDIO_ADDRESS_C45E;
+}
+
 static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
                          int mdio_reg)
 {
@@ -163,15 +183,17 @@ static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
        }
 
        val = readl(&eqos->mac_regs->mdio_address);
-       val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
-               EQOS_MAC_MDIO_ADDRESS_C45E;
-       val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
-               (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
-               (eqos->config->config_mac_mdio <<
-                EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
-               (EQOS_MAC_MDIO_ADDRESS_GOC_READ <<
-                EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
-               EQOS_MAC_MDIO_ADDRESS_GB;
+       val &= EQOS_MAC_MDIO_ADDRESS_SKAP;
+
+       val |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) |
+              FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_GOC_MASK,
+                         EQOS_MAC_MDIO_ADDRESS_GOC_READ);
+
+       if (val & EQOS_MAC_MDIO_ADDRESS_C45E) {
+               writel(FIELD_PREP(EQOS_MAC_MDIO_DATA_RA_MASK, mdio_reg),
+                      &eqos->mac_regs->mdio_data);
+       }
+
        writel(val, &eqos->mac_regs->mdio_address);
 
        udelay(eqos->config->mdio_wait);
@@ -194,7 +216,8 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
                           int mdio_reg, u16 mdio_val)
 {
        struct eqos_priv *eqos = bus->priv;
-       u32 val;
+       u32 v_addr;
+       u32 v_data;
        int ret;
 
        debug("%s(dev=%p, addr=%x, reg=%d, val=%x):\n", __func__, eqos->dev,
@@ -206,20 +229,19 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
                return ret;
        }
 
-       writel(mdio_val, &eqos->mac_regs->mdio_data);
+       v_addr = readl(&eqos->mac_regs->mdio_address);
+       v_addr &= EQOS_MAC_MDIO_ADDRESS_SKAP;
 
-       val = readl(&eqos->mac_regs->mdio_address);
-       val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
-               EQOS_MAC_MDIO_ADDRESS_C45E;
-       val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
-               (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
-               (eqos->config->config_mac_mdio <<
-                EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
-               (EQOS_MAC_MDIO_ADDRESS_GOC_WRITE <<
-                EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
-               EQOS_MAC_MDIO_ADDRESS_GB;
-       writel(val, &eqos->mac_regs->mdio_address);
+       v_addr |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) |
+              FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_GOC_MASK,
+                         EQOS_MAC_MDIO_ADDRESS_GOC_WRITE);
+
+       v_data = mdio_val;
+       if (v_addr & EQOS_MAC_MDIO_ADDRESS_C45E)
+               v_data |= FIELD_PREP(EQOS_MAC_MDIO_DATA_RA_MASK, mdio_reg);
 
+       writel(v_data, &eqos->mac_regs->mdio_data);
+       writel(v_addr, &eqos->mac_regs->mdio_address);
        udelay(eqos->config->mdio_wait);
 
        ret = eqos_mdio_wait_idle(eqos);
index 8b3d0d464d352c5874f7786d10c27034c59028bc..a06390a6982fd115ca81a19a01177e5f006cf79d 100644 (file)
@@ -79,19 +79,20 @@ struct eqos_mac_regs {
 #define EQOS_MAC_HW_FEATURE3_ASP_SHIFT                 28
 #define EQOS_MAC_HW_FEATURE3_ASP_MASK                  0x3
 
-#define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT                 21
-#define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT                        16
-#define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT                 8
+#define EQOS_MAC_MDIO_ADDRESS_PA_MASK                  GENMASK(25, 21)
+#define EQOS_MAC_MDIO_ADDRESS_RDA_MASK                 GENMASK(20, 16)
+#define EQOS_MAC_MDIO_ADDRESS_CR_MASK                  GENMASK(11, 8)
 #define EQOS_MAC_MDIO_ADDRESS_CR_100_150               1
 #define EQOS_MAC_MDIO_ADDRESS_CR_20_35                 2
 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300               5
 #define EQOS_MAC_MDIO_ADDRESS_SKAP                     BIT(4)
-#define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT                        2
+#define EQOS_MAC_MDIO_ADDRESS_GOC_MASK                 GENMASK(3, 2)
 #define EQOS_MAC_MDIO_ADDRESS_GOC_READ                 3
 #define EQOS_MAC_MDIO_ADDRESS_GOC_WRITE                        1
 #define EQOS_MAC_MDIO_ADDRESS_C45E                     BIT(1)
 #define EQOS_MAC_MDIO_ADDRESS_GB                       BIT(0)
 
+#define EQOS_MAC_MDIO_DATA_RA_MASK                     GENMASK(31, 16)
 #define EQOS_MAC_MDIO_DATA_GD_MASK                     0xffff
 
 #define EQOS_MTL_REGS_BASE 0xd00
index ec0068e33d34696db5416cf2912ec0f9f5387d1b..77a1558db688f15d7a231a50f0fbc47e7729e210 100644 (file)
@@ -138,8 +138,6 @@ static int sandbox_serial_pending(struct udevice *dev, bool input)
                return 0;
 
        os_usleep(100);
-       if (IS_ENABLED(CONFIG_VIDEO) && !IS_ENABLED(CONFIG_SPL_BUILD))
-               video_sync_all();
        avail = membuff_putraw(&priv->buf, 100, false, &data);
        if (!avail)
                return 1;       /* buffer full */
index 7808ae7919e073fa125a488ce5e8fc5cc2b9e14a..6e79694fd192bed12bd01853bcb0d15df40dfcad 100644 (file)
@@ -7,6 +7,7 @@ menu "Graphics support"
 config VIDEO
        bool "Enable driver model support for LCD/video"
        depends on DM
+       imply CYCLIC
        help
          This enables driver model for LCD and video devices. These support
          a bitmap display of various sizes and depths which can be drawn on
@@ -14,6 +15,11 @@ config VIDEO
          option compiles in the video uclass and routes all LCD/video access
          through this.
 
+         If CYCLIC is enabled (which it is by default), the cyclic subsystem
+         is used to flush pending output to the display periodically, rather
+         than this happening with every chunk of output. This allows for more
+         efficient operation and faster display output.
+
 if VIDEO
 
 config VIDEO_FONT_4X6
@@ -232,6 +238,35 @@ config NO_FB_CLEAR
          loads takes over the screen.  This, for example, can be used to
          keep splash image on screen until grub graphical boot menu starts.
 
+config VIDEO_SYNC_MS
+       int "Video-sync period in milliseconds for foreground processing"
+       default 300 if SANDBOX
+       default 100
+       help
+         This sets the requested, maximum time before a video sync will take
+         place, in milliseconds. Note that the time between video syncs
+         may be longer than this, since syncs only happen when the video system
+         is used, e.g. by outputting a character to the console.
+
+         It may also be shorter, since the video uclass will automatically
+         force a sync in certain situations.
+
+         Many video-output systems require a sync operation before any output
+         is visible. This may flush the CPU cache or perhaps copy the
+         display contents to a hardware framebuffer. Without this, change to
+         the video may never be displayed.
+
+config VIDEO_SYNC_CYCLIC_MS
+       int "Video-sync period in milliseconds for cyclic processing"
+       depends on CYCLIC
+       default 100 if SANDBOX
+       default 10
+       help
+         This sets the frequency of cyclic video syncs. The cyclic system is
+         used to ensure that when U-Boot is idle, it syncs the video. This
+         improves the responsiveness of the command line to new characters
+         being entered.
+
 config PANEL
        bool "Enable panel uclass support"
        default y
index ff1382f4a43b76869956ca971f5c77fe9c3e871a..a5aa8dd52954af81df9adb44111ccd8b523d0e64 100644 (file)
@@ -8,6 +8,7 @@
 #include <bloblist.h>
 #include <console.h>
 #include <cpu_func.h>
+#include <cyclic.h>
 #include <dm.h>
 #include <log.h>
 #include <malloc.h>
@@ -52,6 +53,8 @@
  */
 DECLARE_GLOBAL_DATA_PTR;
 
+struct cyclic_info;
+
 /**
  * struct video_uc_priv - Information for the video uclass
  *
@@ -60,9 +63,12 @@ DECLARE_GLOBAL_DATA_PTR;
  *     available address to use for a device's framebuffer. It starts at
  *     gd->video_top and works downwards, running out of space when it hits
  *     gd->video_bottom.
+ * @cyc: handle for cyclic-execution function, or NULL if none
  */
 struct video_uc_priv {
        ulong video_ptr;
+       bool cyc_active;
+       struct cyclic_info cyc;
 };
 
 /** struct vid_rgb - Describes a video colour */
@@ -349,6 +355,7 @@ void video_set_default_colors(struct udevice *dev, bool invert)
 /* Flush video activity to the caches */
 int video_sync(struct udevice *vid, bool force)
 {
+       struct video_priv *priv = dev_get_uclass_priv(vid);
        struct video_ops *ops = video_get_ops(vid);
        int ret;
 
@@ -358,28 +365,26 @@ int video_sync(struct udevice *vid, bool force)
                        return ret;
        }
 
+       if (CONFIG_IS_ENABLED(CYCLIC) && !force &&
+           get_timer(priv->last_sync) < CONFIG_VIDEO_SYNC_MS)
+               return 0;
+
        /*
         * flush_dcache_range() is declared in common.h but it seems that some
         * architectures do not actually implement it. Is there a way to find
         * out whether it exists? For now, ARM is safe.
         */
 #if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-       struct video_priv *priv = dev_get_uclass_priv(vid);
-
        if (priv->flush_dcache) {
                flush_dcache_range((ulong)priv->fb,
                                   ALIGN((ulong)priv->fb + priv->fb_size,
                                         CONFIG_SYS_CACHELINE_SIZE));
        }
 #elif defined(CONFIG_VIDEO_SANDBOX_SDL)
-       struct video_priv *priv = dev_get_uclass_priv(vid);
-       static ulong last_sync;
-
-       if (force || get_timer(last_sync) > 100) {
-               sandbox_sdl_sync(priv->fb);
-               last_sync = get_timer(0);
-       }
+       sandbox_sdl_sync(priv->fb);
 #endif
+       priv->last_sync = get_timer(0);
+
        return 0;
 }
 
@@ -528,10 +533,16 @@ int video_default_font_height(struct udevice *dev)
        return vc_priv->y_charsize;
 }
 
+static void video_idle(struct cyclic_info *cyc)
+{
+       video_sync_all();
+}
+
 /* Set up the display ready for use */
 static int video_post_probe(struct udevice *dev)
 {
        struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+       struct video_uc_priv *uc_priv = uclass_get_priv(dev->uclass);
        struct video_priv *priv = dev_get_uclass_priv(dev);
        char name[30], drv[15], *str;
        const char *drv_name = drv;
@@ -622,6 +633,16 @@ static int video_post_probe(struct udevice *dev)
                }
        }
 
+       /* register cyclic as soon as the first video device is probed */
+       if (CONFIG_IS_ENABLED(CYCLIC) && (gd->flags && GD_FLG_RELOC) &&
+           !uc_priv->cyc_active) {
+               uint ms = CONFIG_IF_ENABLED_INT(CYCLIC, VIDEO_SYNC_CYCLIC_MS);
+
+               cyclic_register(&uc_priv->cyc, video_idle, ms * 1000,
+                               "video_init");
+               uc_priv->cyc_active = true;
+       }
+
        return 0;
 };
 
@@ -661,6 +682,18 @@ static int video_post_bind(struct udevice *dev)
        return 0;
 }
 
+__maybe_unused static int video_destroy(struct uclass *uc)
+{
+       struct video_uc_priv *uc_priv = uclass_get_priv(uc);
+
+       if (uc_priv->cyc_active) {
+               cyclic_unregister(&uc_priv->cyc);
+               uc_priv->cyc_active = false;
+       }
+
+       return 0;
+}
+
 UCLASS_DRIVER(video) = {
        .id             = UCLASS_VIDEO,
        .name           = "video",
@@ -670,4 +703,5 @@ UCLASS_DRIVER(video) = {
        .priv_auto      = sizeof(struct video_uc_priv),
        .per_device_auto        = sizeof(struct video_priv),
        .per_device_plat_auto   = sizeof(struct video_uc_plat),
+       CONFIG_IS_ENABLED(CYCLIC, (.destroy = video_destroy, ))
 };
index 8318fd77a32a1b037c6b084b26a2c1aafd4d5aaa..0c3e991331867bb90148a7349625f6887795c0a9 100644 (file)
@@ -4,6 +4,7 @@ config WATCHDOG
        bool "Enable U-Boot watchdog reset"
        depends on !HW_WATCHDOG
        select CYCLIC
+       imply SPL_CYCLIC if SPL
        help
          This option enables U-Boot watchdog support where U-Boot is using
          watchdog_reset function to service watchdog device in U-Boot. Enable
@@ -408,6 +409,7 @@ config WDT_ARM_SMC
 config SPL_WDT
        bool "Enable driver model for watchdog timer drivers in SPL"
        depends on SPL_DM
+       select SPL_CYCLIC if CYCLIC
        help
          Enable driver model for watchdog timer in SPL.
          This is similar to CONFIG_WDT in U-Boot.
index aa336d63e3af39e5b79bdd0e0abfa0f9d5e8a954..27aa75e703696a6c1baa88b1000a370d9fdcd4f7 100644 (file)
@@ -481,7 +481,7 @@ struct global_data {
         */
        struct event_state event_state;
 #endif
-#ifdef CONFIG_CYCLIC
+#if CONFIG_IS_ENABLED(CYCLIC)
        /**
         * @cyclic_list: list of registered cyclic functions
         */
index af23e4f347533b0426053685bf11714fd2d0620e..045e923a529be0e195c6763da1c809f5000b24d8 100644 (file)
@@ -444,7 +444,7 @@ ulong clk_get_rate(struct clk *clk);
 struct clk *clk_get_parent(struct clk *clk);
 
 /**
- * clk_get_parent_rate() - Get parent of current clock rate.
+ * clk_get_parent_rate() - Get rate of current clock's parent.
  * @clk:       A clock struct that was previously successfully requested by
  *             clk_request/get_by_*().
  *
index 2077ff30634baa3f398daafcc61548c221d045e4..0018910d61fa4e7f83f3a9403c325b75967ed674 100644 (file)
@@ -102,6 +102,15 @@ struct cpu_ops {
         *         if not.
         */
        int (*is_current)(struct udevice *dev);
+
+       /**
+        * release_core() - Relase a CPU core to the given address to run application
+        *
+        * @dev:        Device to check (UCLASS_CPU)
+        * @addr:       Address to relese the CPU core
+        * @return 0 if OK, -ve on error
+        */
+       int (*release_core)(const struct udevice *dev, phys_addr_t addr);
 };
 
 #define cpu_get_ops(dev)        ((struct cpu_ops *)(dev)->driver->ops)
@@ -164,4 +173,10 @@ int cpu_is_current(struct udevice *cpu);
  */
 struct udevice *cpu_get_current_dev(void);
 
+/**
+ * cpu_release_core() - Relase a CPU core to the given address to run application
+ *
+ * @return 0 if OK, -ve on error
+ */
+int cpu_release_core(const struct udevice *dev, phys_addr_t addr);
 #endif
index 2c3d383c5ef4af678e83097cff2e7091e238cf74..cd95b691d485ef218c4868bc2c89c64ce30df73d 100644 (file)
@@ -46,7 +46,8 @@ struct cyclic_info {
 /** Function type for cyclic functions */
 typedef void (*cyclic_func_t)(struct cyclic_info *c);
 
-#if defined(CONFIG_CYCLIC)
+#if CONFIG_IS_ENABLED(CYCLIC)
+
 /**
  * cyclic_register - Register a new cyclic function
  *
@@ -123,6 +124,6 @@ static inline int cyclic_unregister_all(void)
 {
        return 0;
 }
-#endif
+#endif /* CYCLIC */
 
 #endif
index 4d8df9baaada799bda781e554f1660013fb2332f..4013a949983feffd1bcdad64a0a2533ba51c0aaa 100644 (file)
@@ -97,6 +97,7 @@ enum video_format {
  *             the LCD is updated
  * @fg_col_idx:        Foreground color code (bit 3 = bold, bit 0-2 = color)
  * @bg_col_idx:        Background color code (bit 3 = bold, bit 0-2 = color)
+ * @last_sync: Monotonic time of last video sync
  */
 struct video_priv {
        /* Things set up by the driver: */
@@ -121,6 +122,7 @@ struct video_priv {
        bool flush_dcache;
        u8 fg_col_idx;
        u8 bg_col_idx;
+       ulong last_sync;
 };
 
 /**
index 0b829a8d3883428763a3ccfe7dfd2553bb679b44..cb302c157b5f7379c3b5afe2c954db4677ce735e 100644 (file)
 /* Do init that is common to driver model and legacy networking */
 void eth_common_init(void);
 
-/**
- * eth_env_set_enetaddr_by_index() - set the MAC address environment variable
- *
- * This sets up an environment variable with the given MAC address (@enetaddr).
- * The environment variable to be set is defined by <@base_name><@index>addr.
- * If @index is 0 it is omitted. For common Ethernet this means ethaddr,
- * eth1addr, etc.
- *
- * @base_name: Base name for variable, typically "eth"
- * @index:     Index of interface being updated (>=0)
- * @enetaddr:  Pointer to MAC address to put into the variable
- * Return: 0 if OK, other value on error
- */
-int eth_env_set_enetaddr_by_index(const char *base_name, int index,
-                                uchar *enetaddr);
-
 int eth_mac_skip(int index);
 void eth_current_changed(void);
 void eth_set_dev(struct udevice *dev);
index 65c39d7fb7089abbf989b5213da26667ee0f3d62..2e073183d5ab8a0a08a6c59e4e11f4e52eb9a8b8 100644 (file)
@@ -493,8 +493,15 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                                tftp_prev_block = tftp_cur_block;
                                tftp_cur_block = (unsigned short)(block + 1);
                                update_block_number();
-                               if (ack_ok)
+                               if (ack_ok) {
+                                       if (block == 0 &&
+                                           tftp_state == STATE_SEND_WRQ){
+                                               /* connection's first ACK */
+                                               tftp_state = STATE_DATA;
+                                               tftp_remote_port = src;
+                                       }
                                        tftp_send(); /* Send next data block */
+                               }
                        }
                }
 #endif
index acba810599666944682ee0bd8f10d545325632e5..8af25316ceac9b3e2377ec496b05cfe6b329f380 100644 (file)
@@ -43,6 +43,8 @@ static int dm_test_cpu(struct unit_test_state *uts)
        ut_assertok(cpu_get_vendor(dev, text, sizeof(text)));
        ut_assertok(strcmp(text, "Languid Example Garbage Inc."));
 
+       ut_assertok(cpu_release_core(dev, 0));
+
        return 0;
 }
 
This page took 0.132539 seconds and 4 git commands to generate.