From e93efaf9cc8e2b529c6184f5680640e669318616 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 5 Dec 2022 12:10:40 +0100 Subject: [PATCH 01/21] arm: dts: ti: k3-am64-mcu: Add pinctrl Add the definition of the pinctrl for the MCU domain. Same as kernel commit 500e6dfbb465531150ac6e2ff0856dd357ddc8a4 Signed-off-by: Christian Gmeiner Reviewed-by: Nishanth Menon --- arch/arm/dts/k3-am64-mcu.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/dts/k3-am64-mcu.dtsi b/arch/arm/dts/k3-am64-mcu.dtsi index 59cc58f7d0..2bb5c9ff17 100644 --- a/arch/arm/dts/k3-am64-mcu.dtsi +++ b/arch/arm/dts/k3-am64-mcu.dtsi @@ -97,4 +97,12 @@ clocks = <&k3_clks 79 0>; clock-names = "gpio"; }; + + mcu_pmx0: pinctrl@4084000 { + compatible = "pinctrl-single"; + reg = <0x00 0x4084000 0x00 0x84>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; }; From 6136c85ed04e715fe03e3df0dbd5ad54e46f046f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Dec 2022 10:16:29 -0600 Subject: [PATCH 02/21] dts: synquacer: Drop CPU 'arm,armv8' compatibles 'arm,armv8' compatible is for software models only. so drop it from cpu nodes. Signed-off-by: Rob Herring --- arch/arm/dts/synquacer-sc2a11.dtsi | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/arm/dts/synquacer-sc2a11.dtsi b/arch/arm/dts/synquacer-sc2a11.dtsi index 1fe7d214b9..1f8cd9d257 100644 --- a/arch/arm/dts/synquacer-sc2a11.dtsi +++ b/arch/arm/dts/synquacer-sc2a11.dtsi @@ -41,168 +41,168 @@ CPU0: cpu@0 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x0>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU1: cpu@1 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x1>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU2: cpu@100 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x100>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU3: cpu@101 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x101>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU4: cpu@200 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x200>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU5: cpu@201 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x201>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU6: cpu@300 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x300>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU7: cpu@301 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x301>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU8: cpu@400 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x400>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU9: cpu@401 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x401>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU10: cpu@500 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x500>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU11: cpu@501 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x501>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU12: cpu@600 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x600>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU13: cpu@601 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x601>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU14: cpu@700 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x700>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU15: cpu@701 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x701>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU16: cpu@800 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x800>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU17: cpu@801 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x801>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU18: cpu@900 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x900>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU19: cpu@901 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0x901>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU20: cpu@a00 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0xa00>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU21: cpu@a01 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0xa01>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU22: cpu@b00 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0xb00>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; CPU23: cpu@b01 { device_type = "cpu"; - compatible = "arm,cortex-a53","arm,armv8"; + compatible = "arm,cortex-a53"; reg = <0xb01>; enable-method = "psci"; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; From cc891c41f2c8a70351da69028df8d262004044e0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Dec 2022 10:16:30 -0600 Subject: [PATCH 03/21] dts: synquacer: Use generic node names DT node names should follow generic names defined in the DT spec. These are also now checked by dtschema tools. Signed-off-by: Rob Herring --- arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi | 2 +- arch/arm/dts/synquacer-sc2a11-developerbox.dts | 2 +- arch/arm/dts/synquacer-sc2a11.dtsi | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi index 7a56116d6f..6b85c05458 100644 --- a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi +++ b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi @@ -23,7 +23,7 @@ active_clk_edges; chipselect_num = <1>; - spi-flash@0 { + flash@0 { #address-cells = <1>; #size-cells = <1>; compatible = "jedec,spi-nor"; diff --git a/arch/arm/dts/synquacer-sc2a11-developerbox.dts b/arch/arm/dts/synquacer-sc2a11-developerbox.dts index 42b6cbbb82..c8087b99a7 100644 --- a/arch/arm/dts/synquacer-sc2a11-developerbox.dts +++ b/arch/arm/dts/synquacer-sc2a11-developerbox.dts @@ -18,7 +18,7 @@ compatible = "gpio-keys"; interrupt-parent = <&exiu>; - power { + power-button { label = "Power Button"; linux,code = ; interrupts = ; diff --git a/arch/arm/dts/synquacer-sc2a11.dtsi b/arch/arm/dts/synquacer-sc2a11.dtsi index 1f8cd9d257..0e1bc16454 100644 --- a/arch/arm/dts/synquacer-sc2a11.dtsi +++ b/arch/arm/dts/synquacer-sc2a11.dtsi @@ -344,7 +344,7 @@ interrupt-controller; interrupts = ; - its: gic-its@30020000 { + its: msi-controller@30020000 { compatible = "arm,gic-v3-its"; reg = <0x0 0x30020000 0x0 0x20000>; #msi-cells = <1>; @@ -361,7 +361,7 @@ ; // HYP }; - mmio-timer@2a810000 { + timer@2a810000 { compatible = "arm,armv7-timer-mem"; reg = <0x0 0x2a810000 0x0 0x10000>; #address-cells = <2>; @@ -398,7 +398,7 @@ clock-output-names = "apb_pclk"; }; - soc_uart0: uart@2a400000 { + soc_uart0: serial@2a400000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0x2a400000 0x0 0x1000>; interrupts = ; @@ -406,7 +406,7 @@ clock-names = "uartclk", "apb_pclk"; }; - fuart: uart@51040000 { + fuart: serial@51040000 { compatible = "snps,dw-apb-uart"; reg = <0x0 0x51040000 0x0 0x1000>; interrupts = ; @@ -523,7 +523,7 @@ clock-output-names = "sd_sd4clk"; }; - sdhci: sdhci@52300000 { + sdhci: mmc@52300000 { compatible = "socionext,synquacer-sdhci", "fujitsu,mb86s70-sdhci-3.0"; reg = <0 0x52300000 0x0 0x1000>; interrupts = , From 563f238b6714bbd150a2e96cb1d7434e1e9d0e49 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Dec 2022 10:16:31 -0600 Subject: [PATCH 04/21] dts: synquacer: Fix "arm, armv7-timer-mem" node address sizes The "arm,armv7-timer-mem" schema defines the address sizes for child nodes to be 32-bit as there's no need for 64-bit offsets and sizes of the child 'frame' nodes. Signed-off-by: Rob Herring --- arch/arm/dts/synquacer-sc2a11.dtsi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/dts/synquacer-sc2a11.dtsi b/arch/arm/dts/synquacer-sc2a11.dtsi index 0e1bc16454..049afcb0af 100644 --- a/arch/arm/dts/synquacer-sc2a11.dtsi +++ b/arch/arm/dts/synquacer-sc2a11.dtsi @@ -364,13 +364,13 @@ timer@2a810000 { compatible = "arm,armv7-timer-mem"; reg = <0x0 0x2a810000 0x0 0x10000>; - #address-cells = <2>; - #size-cells = <2>; - ranges; - frame@2a830000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x2a810000 0x30000>; + frame@20000 { frame-number = <0>; interrupts = ; - reg = <0x0 0x2a830000 0x0 0x10000>; + reg = <0x20000 0x10000>; }; }; From 00723684e4680446d13e054fae7ecd85306a373b Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Dec 2022 10:16:32 -0600 Subject: [PATCH 05/21] dts: synquacer: Fix idle-states 'entry-method' value The correct value for 'entry-method' in the idle-states binding is 'psci', not 'arm,psci'. It hasn't mattered because it isn't used by the OS. Signed-off-by: Rob Herring --- arch/arm/dts/synquacer-sc2a11.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/synquacer-sc2a11.dtsi b/arch/arm/dts/synquacer-sc2a11.dtsi index 049afcb0af..0dd2969b5e 100644 --- a/arch/arm/dts/synquacer-sc2a11.dtsi +++ b/arch/arm/dts/synquacer-sc2a11.dtsi @@ -309,7 +309,7 @@ }; idle-states { - entry-method = "arm,psci"; + entry-method = "psci"; CPU_SLEEP_0: cpu-sleep-0 { compatible = "arm,idle-state"; From 499fe577c8011dd8a9184548c419db42aef079a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 3 Aug 2022 13:20:49 +0200 Subject: [PATCH 06/21] powerpc: dts: keymile: Deduplicate binman code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kmcent2-u-boot.dtsi file contains copy of powerpc u-boot.dtsi binman file. So remove code duplication and replace it by including u-boot.dtsi file. Signed-off-by: Pali Rohár Reviewed-by: Christophe Leroy --- arch/powerpc/dts/kmcent2-u-boot.dtsi | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/dts/kmcent2-u-boot.dtsi b/arch/powerpc/dts/kmcent2-u-boot.dtsi index 53bac5533f..d027762764 100644 --- a/arch/powerpc/dts/kmcent2-u-boot.dtsi +++ b/arch/powerpc/dts/kmcent2-u-boot.dtsi @@ -74,24 +74,6 @@ compatible = "fsl,pcie-t104x"; law_trgt_if = <0>; }; - - binman { - filename = "u-boot.bin"; - skip-at-start = ; - sort-by-offset; - pad-byte = <0xff>; - size = ; - - u-boot-with-ucode-ptr { - offset = ; - optional-ucode; - }; - - u-boot-dtb-with-ucode { - align = <256>; - }; - powerpc-mpc85xx-bootpg-resetvec { - offset = <(CFG_RESET_VECTOR_ADDRESS - 0xffc)>; - }; - }; }; + +#include "u-boot.dtsi" From 36ee37632c5c61ce5cd67b9b0f0ea3cd2280e5d2 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 8 Dec 2022 20:45:08 -0600 Subject: [PATCH 07/21] dts: synquacer: Drop unused and undocumented SPI properties 'active_clk_edges' and 'chipselect_num' SPI controller properties are unused in u-boot and Linux. They are also not documented in the binding. So drop them. Signed-off-by: Rob Herring Reviewed-by: Masahisa Kojima Acked-by: Ilias Apalodimas Acked-by: Jassi Brar --- arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi index 6b85c05458..9f9837b33b 100644 --- a/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi +++ b/arch/arm/dts/synquacer-sc2a11-developerbox-u-boot.dtsi @@ -20,8 +20,6 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; - active_clk_edges; - chipselect_num = <1>; flash@0 { #address-cells = <1>; From bd8851c5b4984ffb26f55872c4e086d91989bc9a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 8 Dec 2022 20:45:09 -0600 Subject: [PATCH 08/21] dts: synquacer: Drop unused and undocumented GPIO 'base' property The 'base' GPIO controller property is unused in u-boot and Linux. It is also not documented in the binding. So drop it. Signed-off-by: Rob Herring Reviewed-by: Masahisa Kojima Acked-by: Ilias Apalodimas Acked-by: Jassi Brar --- arch/arm/dts/synquacer-sc2a11.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/dts/synquacer-sc2a11.dtsi b/arch/arm/dts/synquacer-sc2a11.dtsi index 0dd2969b5e..7ba1cd1bee 100644 --- a/arch/arm/dts/synquacer-sc2a11.dtsi +++ b/arch/arm/dts/synquacer-sc2a11.dtsi @@ -497,7 +497,6 @@ gpio-controller; #gpio-cells = <2>; clocks = <&clk_apb>; - base = <0>; }; exiu: interrupt-controller@510c0000 { From 1e91a0ea326f2005d34921c4bc37a35eeccad368 Mon Sep 17 00:00:00 2001 From: Dai Okamura Date: Fri, 9 Dec 2022 20:33:46 +0900 Subject: [PATCH 09/21] pinctrl: uniphier: add check if pins are valid The pinctrl datas of uniphier SoCs are the minimal subsets of kernel's one, and some tables has no data to save the footprint size. If the board dts tries to match a pin name on no pins defined SoC, the footprint magic code causes "Synchronous Abort". This checks if the 'pins' data is valid, and if empty, avoids the abort with the warning as follows: WARNING at drivers/pinctrl/uniphier/pinctrl-uniphier-core.c:36/uniphier_pinctrl_get_pins_count()! pinctrl_select_state_full: pinctrl_config_one: err=-38 Signed-off-by: Dai Okamura --- drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c index 631bb1f963..bdca3f2f71 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c @@ -33,6 +33,9 @@ static int uniphier_pinctrl_get_pins_count(struct udevice *dev) const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; int pins_count = priv->socdata->pins_count; + if (WARN_ON(!pins_count)) + return 0; /* no table of pins */ + /* * We do not list all pins in the pin table to save memory footprint. * Report the max pin number + 1 to fake the framework. From ef75d482aa9d75d41305e5dddcbc8632f528e6f5 Mon Sep 17 00:00:00 2001 From: Dai Okamura Date: Fri, 9 Dec 2022 20:33:47 +0900 Subject: [PATCH 10/21] pinctrl: uniphier: add ethernet TX pin data for PXs3 PXs3 Ref boards need to change the strength of ethernet ports for stability, like LD20's one. This adds the table data and fixes the boot issue on PXs3 Ref board. Fixes: 0852033309 ("ARM: uniphier: sync with Linux 5.8-rc4") Signed-off-by: Dai Okamura --- .../pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c index 1fc7bdb5c8..8a8f1269bb 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2017 Socionext Inc. + * Copyright (C) 2017-2021 Socionext Inc. * Author: Masahiro Yamada + * Author: Dai Okamura */ #include @@ -10,6 +11,21 @@ #include "pinctrl-uniphier.h" +static const struct uniphier_pinctrl_pin uniphier_pxs3_pins[] = { + UNIPHIER_PINCTRL_PIN(62, "RGMII0_TXCLK", 28, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(63, "RGMII0_TXD0", 29, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(64, "RGMII0_TXD1", 30, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(65, "RGMII0_TXD2", 31, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(66, "RGMII0_TXD3", 32, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(67, "RGMII0_TXCTL", 33, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(78, "RGMII1_TXCLK", 44, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(79, "RGMII1_TXD0", 45, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(80, "RGMII1_TXD1", 46, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(81, "RGMII1_TXD2", 47, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(82, "RGMII1_TXD3", 48, UNIPHIER_PIN_DRV_2BIT), + UNIPHIER_PINCTRL_PIN(83, "RGMII1_TXCTL", 49, UNIPHIER_PIN_DRV_2BIT), +}; + static const unsigned emmc_pins[] = {31, 32, 33, 34, 35, 36, 37, 38}; static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned emmc_dat8_pins[] = {39, 40, 41, 42}; @@ -121,6 +137,8 @@ static const char * const uniphier_pxs3_functions[] = { }; static struct uniphier_pinctrl_socdata uniphier_pxs3_pinctrl_socdata = { + .pins = uniphier_pxs3_pins, + .pins_count = ARRAY_SIZE(uniphier_pxs3_pins), .groups = uniphier_pxs3_groups, .groups_count = ARRAY_SIZE(uniphier_pxs3_groups), .functions = uniphier_pxs3_functions, From 872413bb0a03831ffe6f060b40cdb8bcc76f9867 Mon Sep 17 00:00:00 2001 From: Dai Okamura Date: Fri, 9 Dec 2022 20:33:48 +0900 Subject: [PATCH 11/21] arm: uniphier: use DM_TIMER of arm a9 global timer All uniphier v7 SoCs have cortex-a9 and use cortex-a9 global timer in a simple implementation. Now DM_TIMER of it is available on 35751c7f3f ("timer: sti: convert sti-timer to arm a9 global timer"), so let's switch to it. The old driver reads the lower 32bits of counter field and sets the prescaler as 50 with PERIPHCLK(=50MHz), so the global timer works as a 32-bit 1MHz timer. The DM_TIMER uses the whole 64bits with no prescaler, so the global timer works as a 64-bit PERIPHCLK timer. CONFIG_SYS_HZ_CLOCK is set as the default PERIPHCLK frequency, if there is no 'clocks' property in devicetree. Signed-off-by: Dai Okamura --- arch/arm/dts/uniphier-v7-u-boot.dtsi | 4 +++ arch/arm/mach-uniphier/Kconfig | 1 + arch/arm/mach-uniphier/arm32/Makefile | 2 -- arch/arm/mach-uniphier/arm32/timer.c | 39 --------------------------- configs/uniphier_ld4_sld8_defconfig | 2 ++ configs/uniphier_v7_defconfig | 2 ++ include/configs/uniphier.h | 3 +-- 7 files changed, 10 insertions(+), 43 deletions(-) delete mode 100644 arch/arm/mach-uniphier/arm32/timer.c diff --git a/arch/arm/dts/uniphier-v7-u-boot.dtsi b/arch/arm/dts/uniphier-v7-u-boot.dtsi index 9459bf0377..603b33dd2b 100644 --- a/arch/arm/dts/uniphier-v7-u-boot.dtsi +++ b/arch/arm/dts/uniphier-v7-u-boot.dtsi @@ -2,6 +2,10 @@ soc { u-boot,dm-pre-reloc; + timer@60000200 { + u-boot,dm-pre-reloc; + }; + serial@54006800 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig index 3a8eee7b84..c570fb3294 100644 --- a/arch/arm/mach-uniphier/Kconfig +++ b/arch/arm/mach-uniphier/Kconfig @@ -12,6 +12,7 @@ config ARCH_UNIPHIER_V7_MULTI select ARMV7_NONSEC select CPU_V7A select CPU_V7_HAS_NONSEC + select ARM_GLOBAL_TIMER if TIMER config ARCH_UNIPHIER_V8_MULTI bool "UniPhier V8 SoCs" diff --git a/arch/arm/mach-uniphier/arm32/Makefile b/arch/arm/mach-uniphier/arm32/Makefile index 3cd00b7e5e..b41aba7e29 100644 --- a/arch/arm/mach-uniphier/arm32/Makefile +++ b/arch/arm/mach-uniphier/arm32/Makefile @@ -8,5 +8,3 @@ obj-y += late_lowlevel_init.o obj-y += cache-uniphier.o obj-$(CONFIG_ARMV7_PSCI) += psci.o psci_smp.o endif - -obj-y += timer.o diff --git a/arch/arm/mach-uniphier/arm32/timer.c b/arch/arm/mach-uniphier/arm32/timer.c deleted file mode 100644 index 58247c2738..0000000000 --- a/arch/arm/mach-uniphier/arm32/timer.c +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2012-2015 Masahiro Yamada - */ - -#include -#include -#include - -#include "arm-mpcore.h" - -#define PERIPHCLK (50 * 1000 * 1000) /* 50 MHz */ -#define PRESCALER ((PERIPHCLK) / (CFG_SYS_TIMER_RATE) - 1) - -static void *get_global_timer_base(void) -{ - void *val; - - asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (val) : : "memory"); - - return val + GLOBAL_TIMER_OFFSET; -} - -unsigned long timer_read_counter(void) -{ - /* - * ARM 64bit Global Timer is too much for our purpose. - * We use only lower 32 bit of the timer counter. - */ - return readl(get_global_timer_base() + GTIMER_CNT_L); -} - -int timer_init(void) -{ - /* enable timer */ - writel(PRESCALER << 8 | 1, get_global_timer_base() + GTIMER_CTRL); - - return 0; -} diff --git a/configs/uniphier_ld4_sld8_defconfig b/configs/uniphier_ld4_sld8_defconfig index b361e3f403..b11dea593a 100644 --- a/configs/uniphier_ld4_sld8_defconfig +++ b/configs/uniphier_ld4_sld8_defconfig @@ -13,6 +13,8 @@ CONFIG_SYS_LOAD_ADDR=0x85000000 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x84000000 CONFIG_SYS_MONITOR_LEN=2097152 +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y CONFIG_TIMESTAMP=y # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set CONFIG_BOOTCOMMAND="run ${bootdev}script; run ${bootdev}boot" diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig index 765d42a3e6..d626968c76 100644 --- a/configs/uniphier_v7_defconfig +++ b/configs/uniphier_v7_defconfig @@ -13,6 +13,8 @@ CONFIG_SYS_LOAD_ADDR=0x85000000 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x84000000 CONFIG_SYS_MONITOR_LEN=2097152 +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y CONFIG_TIMESTAMP=y # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set CONFIG_BOOTCOMMAND="run ${bootdev}script; run ${bootdev}boot" diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index ecf0d2ac44..0a14d0448c 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -36,8 +36,7 @@ BOOT_TARGET_DEVICE_USB(func) #if !defined(CONFIG_ARM64) -/* Time clock 1MHz */ -#define CFG_SYS_TIMER_RATE 1000000 +#define CFG_SYS_HZ_CLOCK 50000000 #endif #define CFG_SYS_NAND_REGS_BASE 0x68100000 From fcb624be476e76d5043377a0f0a3c3589bfb4b5f Mon Sep 17 00:00:00 2001 From: Sergei Antonov Date: Fri, 9 Dec 2022 19:15:30 +0300 Subject: [PATCH 12/21] rtc: add ht1380 driver Support Holtek HT1380/HT1381 Serial Timekeeper Chip. It provides seconds , minutes, hours, day of the week, date, month and year information. Datasheet: https://www.holtek.com.tw/documents/10179/11842/ht1380_1v130.pdf Signed-off-by: Sergei Antonov Reviewed-by: Simon Glass --- configs/sandbox_defconfig | 1 + drivers/rtc/Kconfig | 9 ++ drivers/rtc/Makefile | 1 + drivers/rtc/ht1380.c | 329 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 340 insertions(+) create mode 100644 drivers/rtc/ht1380.c diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 404e4a3324..f9c996b429 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -334,3 +334,4 @@ CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y CONFIG_IPV6=y +CONFIG_RTC_HT1380=y diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b698722569..35b6ed4d7c 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -260,4 +260,13 @@ config RTC_ZYNQMP Say "yes" here to support the on chip real time clock present on Xilinx ZynqMP SoC. +config RTC_HT1380 + bool "Enable Holtek HT1380/HT1381 RTC driver" + depends on DM_RTC && DM_GPIO + help + Say "yes" here to get support for Holtek HT1380/HT1381 + Serial Timekeeper IC which provides seconds, minutes, hours, + day of the week, date, month and year information. It is to be + connected via 3 GPIO pins which work as reset, clock, and data. + endmenu diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 2089086551..acfd130bbc 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_RTC_DS3231) += ds3231.o obj-$(CONFIG_RTC_DS3232) += ds3232.o obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o +obj-$(CONFIG_RTC_HT1380) += ht1380.o obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o obj-$(CONFIG_RTC_IMXDI) += imxdi.o obj-$(CONFIG_RTC_ISL1208) += isl1208.o diff --git a/drivers/rtc/ht1380.c b/drivers/rtc/ht1380.c new file mode 100644 index 0000000000..85fcee3e71 --- /dev/null +++ b/drivers/rtc/ht1380.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Holtek HT1380/HT1381 Serial Timekeeper Chip + * + * Communication with the chip is vendor-specific. + * It is done via 3 GPIO pins: reset, clock, and data. + * Describe in .dts this way: + * + * rtc { + * compatible = "holtek,ht1380"; + * rst-gpios = <&gpio 19 GPIO_ACTIVE_LOW>; + * clk-gpios = <&gpio 20 GPIO_ACTIVE_HIGH>; + * dat-gpios = <&gpio 21 GPIO_ACTIVE_HIGH>; + * }; + * + */ + +#include +#include +#include +#include +#include +#include + +struct ht1380_priv { + struct gpio_desc rst_desc; + struct gpio_desc clk_desc; + struct gpio_desc dat_desc; +}; + +enum registers { + SEC, + MIN, + HOUR, + MDAY, + MONTH, + WDAY, + YEAR, + WP, + N_REGS +}; + +enum hour_mode { + AMPM_MODE = 0x80, /* RTC is in AM/PM mode */ + PM_NOW = 0x20, /* set if PM, clear if AM */ +}; + +static const int BURST = 0xbe; +static const int READ = 1; + +static void ht1380_half_period_delay(void) +{ + /* + * Delay for half a period. 1 us complies with the 500 KHz maximum + * input serial clock limit given by the datasheet. + */ + udelay(1); +} + +static int ht1380_send_byte(struct ht1380_priv *priv, int byte) +{ + int ret; + + for (int bit = 0; bit < 8; bit++) { + ret = dm_gpio_set_value(&priv->dat_desc, byte >> bit & 1); + if (ret) + break; + ht1380_half_period_delay(); + + ret = dm_gpio_set_value(&priv->clk_desc, 1); + if (ret) + break; + ht1380_half_period_delay(); + + ret = dm_gpio_set_value(&priv->clk_desc, 0); + if (ret) + break; + } + + return ret; +} + +/* + * Leave reset state. The transfer operation can then be started. + */ +static int ht1380_reset_off(struct ht1380_priv *priv) +{ + const unsigned int T_CC = 4; /* us, Reset to Clock Setup */ + int ret; + + /* + * Leave RESET state. + * Make sure we make the minimal delay required by the datasheet. + */ + ret = dm_gpio_set_value(&priv->rst_desc, 0); + udelay(T_CC); + + return ret; +} + +/* + * Enter reset state. Completes the transfer operation. + */ +static int ht1380_reset_on(struct ht1380_priv *priv) +{ + const unsigned int T_CWH = 4; /* us, Reset Inactive Time */ + int ret; + + /* + * Enter RESET state. + * Make sure we make the minimal delay required by the datasheet. + */ + ret = dm_gpio_set_value(&priv->rst_desc, 1); + udelay(T_CWH); + + return ret; +} + +static int ht1380_rtc_get(struct udevice *dev, struct rtc_time *tm) +{ + struct ht1380_priv *priv = dev_get_priv(dev); + int ret, i, bit, reg[N_REGS]; + + ret = dm_gpio_set_value(&priv->clk_desc, 0); + if (ret) + return ret; + + ret = dm_gpio_set_dir_flags(&priv->dat_desc, GPIOD_IS_OUT); + if (ret) + return ret; + + ret = ht1380_reset_off(priv); + if (ret) + goto exit; + + ret = ht1380_send_byte(priv, BURST + READ); + if (ret) + goto exit; + + ret = dm_gpio_set_dir_flags(&priv->dat_desc, GPIOD_IS_IN); + if (ret) + goto exit; + + for (i = 0; i < N_REGS; i++) { + reg[i] = 0; + + for (bit = 0; bit < 8; bit++) { + ht1380_half_period_delay(); + + ret = dm_gpio_set_value(&priv->clk_desc, 1); + if (ret) + goto exit; + ht1380_half_period_delay(); + + reg[i] |= dm_gpio_get_value(&priv->dat_desc) << bit; + ret = dm_gpio_set_value(&priv->clk_desc, 0); + if (ret) + goto exit; + } + } + + ret = -EINVAL; + + /* Correctness check: some bits are always zero */ + if (reg[MIN] & 0x80 || reg[HOUR] & 0x40 || reg[MDAY] & 0xc0 || + reg[MONTH] & 0xe0 || reg[WDAY] & 0xf8 || reg[WP] & 0x7f) + goto exit; + + /* Correctness check: some registers are always non-zero */ + if (!reg[MDAY] || !reg[MONTH] || !reg[WDAY]) + goto exit; + + tm->tm_sec = bcd2bin(reg[SEC]); + tm->tm_min = bcd2bin(reg[MIN]); + if (reg[HOUR] & AMPM_MODE) { + /* AM-PM Mode, range is 01-12 */ + tm->tm_hour = bcd2bin(reg[HOUR] & 0x1f) % 12; + if (reg[HOUR] & PM_NOW) { + /* it is PM (otherwise AM) */ + tm->tm_hour += 12; + } + } else { + /* 24-hour Mode, range is 0-23 */ + tm->tm_hour = bcd2bin(reg[HOUR]); + } + tm->tm_mday = bcd2bin(reg[MDAY]); + tm->tm_mon = bcd2bin(reg[MONTH]); + tm->tm_year = 2000 + bcd2bin(reg[YEAR]); + tm->tm_wday = bcd2bin(reg[WDAY]) - 1; + tm->tm_yday = 0; + tm->tm_isdst = 0; + + ret = 0; + +exit: + ht1380_reset_on(priv); + + return ret; +} + +static int ht1380_write_protection_off(struct ht1380_priv *priv) +{ + int ret; + const int PROTECT = 0x8e; + + ret = ht1380_reset_off(priv); + if (ret) + return ret; + + ret = ht1380_send_byte(priv, PROTECT); + if (ret) + return ret; + ret = ht1380_send_byte(priv, 0); /* WP bit is 0 */ + if (ret) + return ret; + + return ht1380_reset_on(priv); +} + +static int ht1380_rtc_set(struct udevice *dev, const struct rtc_time *tm) +{ + struct ht1380_priv *priv = dev_get_priv(dev); + int ret, i, reg[N_REGS]; + + ret = dm_gpio_set_value(&priv->clk_desc, 0); + if (ret) + return ret; + + ret = dm_gpio_set_dir_flags(&priv->dat_desc, GPIOD_IS_OUT); + if (ret) + goto exit; + + ret = ht1380_write_protection_off(priv); + if (ret) + goto exit; + + reg[SEC] = bin2bcd(tm->tm_sec); + reg[MIN] = bin2bcd(tm->tm_min); + reg[HOUR] = bin2bcd(tm->tm_hour); + reg[MDAY] = bin2bcd(tm->tm_mday); + reg[MONTH] = bin2bcd(tm->tm_mon); + reg[WDAY] = bin2bcd(tm->tm_wday) + 1; + reg[YEAR] = bin2bcd(tm->tm_year - 2000); + reg[WP] = 0x80; /* WP bit is 1 */ + + ret = ht1380_reset_off(priv); + if (ret) + goto exit; + + ret = ht1380_send_byte(priv, BURST); + for (i = 0; i < N_REGS && ret; i++) + ret = ht1380_send_byte(priv, reg[i]); + +exit: + ht1380_reset_on(priv); + + return ret; +} + +static int ht1380_probe(struct udevice *dev) +{ + int ret; + struct ht1380_priv *priv; + + priv = dev_get_priv(dev); + if (!priv) + return -EINVAL; + + ret = gpio_request_by_name(dev, "rst-gpios", 0, + &priv->rst_desc, GPIOD_IS_OUT); + if (ret) + goto fail_rst; + + ret = gpio_request_by_name(dev, "clk-gpios", 0, + &priv->clk_desc, GPIOD_IS_OUT); + if (ret) + goto fail_clk; + + ret = gpio_request_by_name(dev, "dat-gpios", 0, + &priv->dat_desc, 0); + if (ret) + goto fail_dat; + + ret = ht1380_reset_on(priv); + if (ret) + goto fail; + + return 0; + +fail: + dm_gpio_free(dev, &priv->dat_desc); +fail_dat: + dm_gpio_free(dev, &priv->clk_desc); +fail_clk: + dm_gpio_free(dev, &priv->rst_desc); +fail_rst: + return ret; +} + +static int ht1380_remove(struct udevice *dev) +{ + struct ht1380_priv *priv = dev_get_priv(dev); + + dm_gpio_free(dev, &priv->rst_desc); + dm_gpio_free(dev, &priv->clk_desc); + dm_gpio_free(dev, &priv->dat_desc); + + return 0; +} + +static const struct rtc_ops ht1380_rtc_ops = { + .get = ht1380_rtc_get, + .set = ht1380_rtc_set, +}; + +static const struct udevice_id ht1380_rtc_ids[] = { + { .compatible = "holtek,ht1380" }, + { } +}; + +U_BOOT_DRIVER(rtc_ht1380) = { + .name = "rtc-ht1380", + .id = UCLASS_RTC, + .probe = ht1380_probe, + .remove = ht1380_remove, + .of_match = ht1380_rtc_ids, + .ops = &ht1380_rtc_ops, + .priv_auto = sizeof(struct ht1380_priv), +}; From 59440d83d38bfed31931d11aa06a3fb56acbd2f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 11 Dec 2022 00:27:44 +0100 Subject: [PATCH 13/21] serial: Do not write additional \r before \n for dm_serial drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit serial-uclass.c code already puts \r before \n for all dm_serial drivers. Signed-off-by: Pali Rohár Reviewed-by: Stefan Roese Reviewed-by: Simon Glass --- drivers/serial/serial_lpuart.c | 3 --- drivers/serial/serial_mpc8xx.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index ff576da516..07941c29ed 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -349,9 +349,6 @@ static void _lpuart32_serial_putc(struct lpuart_serial_plat *plat, struct lpuart_fsl_reg32 *base = plat->reg; u32 stat; - if (c == '\n') - serial_putc('\r'); - while (true) { lpuart_read32(plat->flags, &base->stat, &stat); diff --git a/drivers/serial/serial_mpc8xx.c b/drivers/serial/serial_mpc8xx.c index aeae6ae6cd..808a40f503 100644 --- a/drivers/serial/serial_mpc8xx.c +++ b/drivers/serial/serial_mpc8xx.c @@ -176,9 +176,6 @@ static int serial_mpc8xx_putc(struct udevice *dev, const char c) cpm8xx_t __iomem *cpmp = &(im->im_cpm); struct serialbuffer __iomem *rtx; - if (c == '\n') - serial_mpc8xx_putc(dev, '\r'); - rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE]; /* Wait for last character to go. */ From 1138bbe05e617034cf542ac0bc13cfa804cb09f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 11 Dec 2022 00:31:21 +0100 Subject: [PATCH 14/21] serial: Use -EAGAIN in getc and putc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit U-Boot serial code already handles -EAGAIN value from getc and putc callbacks. So change drivers code to return -EAGAIN when HW is busy instead of doing its own busy loop and waiting until HW is ready. Signed-off-by: Pali Rohár --- drivers/serial/serial_arc.c | 8 +++---- drivers/serial/serial_lpuart.c | 36 ++++++++++++----------------- drivers/serial/serial_mpc8xx.c | 12 ++++------ drivers/serial/serial_mvebu_a3700.c | 8 +++---- 4 files changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c index b2d95bdbe1..c2fc8a901e 100644 --- a/drivers/serial/serial_arc.c +++ b/drivers/serial/serial_arc.c @@ -53,8 +53,8 @@ static int arc_serial_putc(struct udevice *dev, const char c) struct arc_serial_plat *plat = dev_get_plat(dev); struct arc_serial_regs *const regs = plat->reg; - while (!(readb(®s->status) & UART_TXEMPTY)) - ; + if (!(readb(®s->status) & UART_TXEMPTY)) + return -EAGAIN; writeb(c, ®s->data); @@ -83,8 +83,8 @@ static int arc_serial_getc(struct udevice *dev) struct arc_serial_plat *plat = dev_get_plat(dev); struct arc_serial_regs *const regs = plat->reg; - while (!arc_serial_tstc(regs)) - ; + if (!arc_serial_tstc(regs)) + return -EAGAIN; /* Check for overflow errors */ if (readb(®s->status) & UART_OVERFLOW_ERR) diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index 07941c29ed..51e66abdbc 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -168,23 +168,24 @@ static void _lpuart_serial_setbrg(struct udevice *dev, static int _lpuart_serial_getc(struct lpuart_serial_plat *plat) { struct lpuart_fsl *base = plat->reg; - while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR))) - schedule(); + if (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR))) + return -EAGAIN; barrier(); return __raw_readb(&base->ud); } -static void _lpuart_serial_putc(struct lpuart_serial_plat *plat, +static int _lpuart_serial_putc(struct lpuart_serial_plat *plat, const char c) { struct lpuart_fsl *base = plat->reg; - while (!(__raw_readb(&base->us1) & US1_TDRE)) - schedule(); + if (!(__raw_readb(&base->us1) & US1_TDRE)) + return -EAGAIN; __raw_writeb(c, &base->ud); + return 0; } /* Test whether a character is in the RX buffer */ @@ -328,10 +329,9 @@ static int _lpuart32_serial_getc(struct lpuart_serial_plat *plat) u32 stat, val; lpuart_read32(plat->flags, &base->stat, &stat); - while ((stat & STAT_RDRF) == 0) { + if ((stat & STAT_RDRF) == 0) { lpuart_write32(plat->flags, &base->stat, STAT_FLAGS); - schedule(); - lpuart_read32(plat->flags, &base->stat, &stat); + return -EAGAIN; } lpuart_read32(plat->flags, &base->data, &val); @@ -343,22 +343,18 @@ static int _lpuart32_serial_getc(struct lpuart_serial_plat *plat) return val & 0x3ff; } -static void _lpuart32_serial_putc(struct lpuart_serial_plat *plat, +static int _lpuart32_serial_putc(struct lpuart_serial_plat *plat, const char c) { struct lpuart_fsl_reg32 *base = plat->reg; u32 stat; - while (true) { - lpuart_read32(plat->flags, &base->stat, &stat); - - if ((stat & STAT_TDRE)) - break; - - schedule(); - } + lpuart_read32(plat->flags, &base->stat, &stat); + if (!(stat & STAT_TDRE)) + return -EAGAIN; lpuart_write32(plat->flags, &base->data, c); + return 0; } /* Test whether a character is in the RX buffer */ @@ -453,11 +449,9 @@ static int lpuart_serial_putc(struct udevice *dev, const char c) struct lpuart_serial_plat *plat = dev_get_plat(dev); if (is_lpuart32(dev)) - _lpuart32_serial_putc(plat, c); - else - _lpuart_serial_putc(plat, c); + return _lpuart32_serial_putc(plat, c); - return 0; + return _lpuart_serial_putc(plat, c); } static int lpuart_serial_pending(struct udevice *dev, bool input) diff --git a/drivers/serial/serial_mpc8xx.c b/drivers/serial/serial_mpc8xx.c index 808a40f503..b8d6a81b65 100644 --- a/drivers/serial/serial_mpc8xx.c +++ b/drivers/serial/serial_mpc8xx.c @@ -178,14 +178,13 @@ static int serial_mpc8xx_putc(struct udevice *dev, const char c) rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE]; - /* Wait for last character to go. */ + if (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY) + return -EAGAIN; + out_8(&rtx->txbuf, c); out_be16(&rtx->txbd.cbd_datlen, 1); setbits_be16(&rtx->txbd.cbd_sc, BD_SC_READY); - while (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY) - schedule(); - return 0; } @@ -199,9 +198,8 @@ static int serial_mpc8xx_getc(struct udevice *dev) rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE]; - /* Wait for character to show up. */ - while (in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY) - schedule(); + if (in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY) + return -EAGAIN; /* the characters are read one by one, * use the rxindex to know the next char to deliver diff --git a/drivers/serial/serial_mvebu_a3700.c b/drivers/serial/serial_mvebu_a3700.c index 0fcd7e88ac..b2017c6455 100644 --- a/drivers/serial/serial_mvebu_a3700.c +++ b/drivers/serial/serial_mvebu_a3700.c @@ -40,8 +40,8 @@ static int mvebu_serial_putc(struct udevice *dev, const char ch) struct mvebu_plat *plat = dev_get_plat(dev); void __iomem *base = plat->base; - while (readl(base + UART_STATUS_REG) & UART_STATUS_TXFIFO_FULL) - ; + if (readl(base + UART_STATUS_REG) & UART_STATUS_TXFIFO_FULL) + return -EAGAIN; writel(ch, base + UART_TX_REG); @@ -53,8 +53,8 @@ static int mvebu_serial_getc(struct udevice *dev) struct mvebu_plat *plat = dev_get_plat(dev); void __iomem *base = plat->base; - while (!(readl(base + UART_STATUS_REG) & UART_STATUS_RX_RDY)) - ; + if (!(readl(base + UART_STATUS_REG) & UART_STATUS_RX_RDY)) + return -EAGAIN; return readl(base + UART_RX_REG) & 0xff; } From 357c352cdccbd09a92924b1a5c0cb841a18aa832 Mon Sep 17 00:00:00 2001 From: "Lokanathan, Raaj" Date: Sun, 11 Dec 2022 23:37:42 +0800 Subject: [PATCH 15/21] Add CONFIG_SYS_NAND_SELF_INIT to Kconfig for NAND DENALI driver Add the CONFIG_SYS_NAND_SELF_INIT to the Kconfig to follow the changes from mainline. Signed-off-by: Lokanathan, Raaj Signed-off-by: Jit Loon Lim --- drivers/mtd/nand/raw/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 1e4e5c9206..f8b79e5456 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -197,6 +197,7 @@ config NAND_DENALI config NAND_DENALI_DT bool "Support Denali NAND controller as a DT device" select NAND_DENALI + select SPL_SYS_NAND_SELF_INIT depends on OF_CONTROL && DM_MTD help Enable the driver for NAND flash on platforms using a Denali NAND From 9f393a2d7af89fa1be076e79091e5481f96c3c3f Mon Sep 17 00:00:00 2001 From: Neha Malcom Francis Date: Tue, 13 Dec 2022 11:57:34 +0530 Subject: [PATCH 16/21] board: ti: common: board_detect: Fix EEPROM read quirk for 2-byte EEPROM detection logic in ti_i2c_eeprom_get() involves figuring out whether addressing is 1-byte or 2-byte. There are currently different behaviours seen across boards as documented in commit bf6376642fe8 ("board: ti: common: board_detect: Fix EEPROM read quirk"). Adding to the list, we see that there are 2-byte EEPROMs that read properly with 1-byte addressing with no offset. For ti_i2c_eeprom_am6_get where eeprom parse operation is dynamic, the earlier commit d2ab2a2bafd5 ("board: ti: common: board_detect: Fix EEPROM read quirk for AM6 style data") tried to resolve this by running ti_i2c_eeprom_get() twice. However this commit along with its former commit fails on J7 platforms where EEPROM successfully return back the header on 1-byte addressing and continues to do so until an offset is introduced. So the second read incorrectly determines the EEPROM as 1-byte addressing. A more generic solution is introduced here to solve this issue: 1-byte read without offset and 1-byte read with offset. If both passes, it follows 1-byte addressing else we proceed with 2-byte addressing check. Tested on J721E, J7200, DRA7xx, AM64x Signed-off-by: Neha Malcom Francis Fixes: d2ab2a2bafd5 (board: ti: common: board_detect: Fix EEPROM read quirk for AM6 style data) Fixes: bf6376642fe8 (board: ti: common: board_detect: Fix EEPROM read quirk) Tested-By: Matwey V. Kornilov --- board/ti/common/board_detect.c | 46 +++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c index c37629fe8a..9a53884c98 100644 --- a/board/ti/common/board_detect.c +++ b/board/ti/common/board_detect.c @@ -87,6 +87,8 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, u32 header, u32 size, uint8_t *ep) { int rc; + uint8_t offset_test; + bool one_byte_addressing = true; #if CONFIG_IS_ENABLED(DM_I2C) struct udevice *dev; @@ -114,8 +116,23 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, */ (void)dm_i2c_read(dev, 0, ep, size); + if (*((u32 *)ep) != header) + one_byte_addressing = false; + + /* + * Handle case of bad 2 byte eeproms that responds to 1 byte addressing + * but gets stuck in const addressing when read requests are performed + * on offsets. We perform an offset test to make sure it is not a 2 byte + * eeprom that works with 1 byte addressing but just without an offset + */ + + rc = dm_i2c_read(dev, 0x1, &offset_test, sizeof(offset_test)); + + if (*((u32 *)ep) != (header & 0xFF)) + one_byte_addressing = false; + /* Corrupted data??? */ - if (*((u32 *)ep) != header) { + if (!one_byte_addressing) { /* * read the eeprom header using i2c again, but use only a * 2 byte address (some newer boards need this..) @@ -151,8 +168,23 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, */ (void)i2c_read(dev_addr, 0x0, byte, ep, size); + if (*((u32 *)ep) != header) + one_byte_addressing = false; + + /* + * Handle case of bad 2 byte eeproms that responds to 1 byte addressing + * but gets stuck in const addressing when read requests are performed + * on offsets. We perform an offset test to make sure it is not a 2 byte + * eeprom that works with 1 byte addressing but just without an offset + */ + + rc = i2c_read(dev_addr, 0x1, byte, &offset_test, sizeof(offset_test)); + + if (*((u32 *)ep) != (header & 0xFF)) + one_byte_addressing = false; + /* Corrupted data??? */ - if (*((u32 *)ep) != header) { + if (!one_byte_addressing) { /* * read the eeprom header using i2c again, but use only a * 2 byte address (some newer boards need this..) @@ -444,16 +476,6 @@ int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr, if (rc) return rc; - /* - * Handle case of bad 2 byte eeproms that responds to 1 byte addressing - * but gets stuck in const addressing when read requests are performed - * on offsets. We re-read the board ID to ensure we have sane data back - */ - rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC, - sizeof(board_id), (uint8_t *)&board_id); - if (rc) - return rc; - if (board_id.header.id != TI_AM6_EEPROM_RECORD_BOARD_ID) { pr_err("%s: Invalid board ID record!\n", __func__); return -EINVAL; From bfd4e660dec103a69e7a6dd9f856581ba6e57954 Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Wed, 14 Dec 2022 11:30:07 +0100 Subject: [PATCH 17/21] board/pg_wcom: rework defconfig Switch off SCSI related config options to get rid of the board removal warning. We don't use this interface. Also disable UBIFS to decrease the image size, as this is also not used. Signed-off-by: Holger Brunck --- configs/pg_wcom_expu1_defconfig | 6 ++++-- configs/pg_wcom_expu1_update_defconfig | 6 ++++-- configs/pg_wcom_seli8_defconfig | 6 ++++-- configs/pg_wcom_seli8_update_defconfig | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/configs/pg_wcom_expu1_defconfig b/configs/pg_wcom_expu1_defconfig index b7c0b0d1e8..acbef25d04 100644 --- a/configs/pg_wcom_expu1_defconfig +++ b/configs/pg_wcom_expu1_defconfig @@ -17,7 +17,6 @@ CONFIG_SYS_CLK_FREQ=66666666 # CONFIG_HAS_ARMV7_SECURE_BASE is not set CONFIG_SYS_LOAD_ADDR=0x82000000 CONFIG_ENV_ADDR=0x60060000 -CONFIG_AHCI=y # CONFIG_DEEP_SLEEP is not set CONFIG_LAYERSCAPE_NS_ACCESS=y CONFIG_KM_COMMON_ETH_INIT=y @@ -62,6 +61,7 @@ CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=60000000.nor,nand0=68000000.flash" CONFIG_MTDPARTS_DEFAULT="mtdparts=60000000.nor:128k(rcw),128k(qe),128k(envred),128k(env),512k(res),1m(u-boot),128k(redenvred),128k(redenv),1m(redu-boot),-(ubi0);68000000.flash:-(ubi1)" CONFIG_CMD_UBI=y +# CONFIG_CMD_UBIFS is not set CONFIG_OF_CONTROL=y CONFIG_ENV_SOURCE_FILE="pg-wcom-expu1" CONFIG_ENV_OVERWRITE=y @@ -73,6 +73,7 @@ CONFIG_ETHPRIME="ethernet@2d90000" CONFIG_USE_HOSTNAME=y CONFIG_HOSTNAME="EXPU1" CONFIG_VERSION_VARIABLE=y +# CONFIG_SCSI_AHCI is not set CONFIG_BOOTCOUNT_LIMIT=y CONFIG_SYS_BOOTCOUNT_BE=y CONFIG_DDR_CLK_FREQ=50000000 @@ -98,8 +99,9 @@ CONFIG_PHY_GIGE=y CONFIG_MII=y CONFIG_TSEC_ENET=y CONFIG_SYS_QE_FW_ADDR=0x60020000 -CONFIG_SCSI_AHCI_PLAT=y +# CONFIG_SCSI is not set CONFIG_SPECIFY_CONSOLE_INDEX=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_POST=y +CONFIG_LZO=y diff --git a/configs/pg_wcom_expu1_update_defconfig b/configs/pg_wcom_expu1_update_defconfig index a5193cb463..3d9581abd6 100644 --- a/configs/pg_wcom_expu1_update_defconfig +++ b/configs/pg_wcom_expu1_update_defconfig @@ -16,7 +16,6 @@ CONFIG_SYS_BOOTCOUNT_ADDR=0x70000020 # CONFIG_HAS_ARMV7_SECURE_BASE is not set CONFIG_SYS_LOAD_ADDR=0x82000000 CONFIG_ENV_ADDR=0x60220000 -CONFIG_AHCI=y # CONFIG_DEEP_SLEEP is not set CONFIG_LAYERSCAPE_NS_ACCESS=y CONFIG_KM_COMMON_ETH_INIT=y @@ -60,6 +59,7 @@ CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=60000000.nor,nand0=68000000.flash" CONFIG_MTDPARTS_DEFAULT="mtdparts=60000000.nor:128k(rcw),128k(qe),128k(envred),128k(env),512k(res),1m(u-boot),128k(redenvred),128k(redenv),1m(redu-boot),-(ubi0);68000000.flash:-(ubi1)" CONFIG_CMD_UBI=y +# CONFIG_CMD_UBIFS is not set CONFIG_OF_CONTROL=y CONFIG_ENV_SOURCE_FILE="pg-wcom-expu1" CONFIG_ENV_OVERWRITE=y @@ -71,6 +71,7 @@ CONFIG_ETHPRIME="ethernet@2d90000" CONFIG_USE_HOSTNAME=y CONFIG_HOSTNAME="EXPU1" CONFIG_VERSION_VARIABLE=y +# CONFIG_SCSI_AHCI is not set CONFIG_BOOTCOUNT_LIMIT=y CONFIG_SYS_BOOTCOUNT_BE=y CONFIG_DDR_CLK_FREQ=50000000 @@ -96,8 +97,9 @@ CONFIG_PHY_GIGE=y CONFIG_MII=y CONFIG_TSEC_ENET=y CONFIG_SYS_QE_FW_ADDR=0x60020000 -CONFIG_SCSI_AHCI_PLAT=y +# CONFIG_SCSI is not set CONFIG_SPECIFY_CONSOLE_INDEX=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_POST=y +CONFIG_LZO=y diff --git a/configs/pg_wcom_seli8_defconfig b/configs/pg_wcom_seli8_defconfig index 1b9e0b6c91..0d7299efad 100644 --- a/configs/pg_wcom_seli8_defconfig +++ b/configs/pg_wcom_seli8_defconfig @@ -17,7 +17,6 @@ CONFIG_SYS_CLK_FREQ=66666666 # CONFIG_HAS_ARMV7_SECURE_BASE is not set CONFIG_SYS_LOAD_ADDR=0x82000000 CONFIG_ENV_ADDR=0x60060000 -CONFIG_AHCI=y # CONFIG_DEEP_SLEEP is not set CONFIG_LAYERSCAPE_NS_ACCESS=y CONFIG_KM_COMMON_ETH_INIT=y @@ -62,6 +61,7 @@ CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=60000000.nor,nand0=68000000.flash" CONFIG_MTDPARTS_DEFAULT="mtdparts=60000000.nor:128k(rcw),128k(qe),128k(envred),128k(env),512k(res),1m(u-boot),128k(redenvred),128k(redenv),1m(redu-boot),-(ubi0);68000000.flash:-(ubi1)" CONFIG_CMD_UBI=y +# CONFIG_CMD_UBIFS is not set CONFIG_OF_CONTROL=y CONFIG_ENV_SOURCE_FILE="pg-wcom-seli8" CONFIG_ENV_OVERWRITE=y @@ -73,6 +73,7 @@ CONFIG_ETHPRIME="ethernet@2d90000" CONFIG_USE_HOSTNAME=y CONFIG_HOSTNAME="SELI8" CONFIG_VERSION_VARIABLE=y +# CONFIG_SCSI_AHCI is not set CONFIG_BOOTCOUNT_LIMIT=y CONFIG_SYS_BOOTCOUNT_BE=y CONFIG_DDR_CLK_FREQ=50000000 @@ -98,8 +99,9 @@ CONFIG_PHY_GIGE=y CONFIG_MII=y CONFIG_TSEC_ENET=y CONFIG_SYS_QE_FW_ADDR=0x60020000 -CONFIG_SCSI_AHCI_PLAT=y +# CONFIG_SCSI is not set CONFIG_SPECIFY_CONSOLE_INDEX=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_POST=y +CONFIG_LZO=y diff --git a/configs/pg_wcom_seli8_update_defconfig b/configs/pg_wcom_seli8_update_defconfig index c193f7bb40..d677b13a59 100644 --- a/configs/pg_wcom_seli8_update_defconfig +++ b/configs/pg_wcom_seli8_update_defconfig @@ -16,7 +16,6 @@ CONFIG_SYS_BOOTCOUNT_ADDR=0x70000020 # CONFIG_HAS_ARMV7_SECURE_BASE is not set CONFIG_SYS_LOAD_ADDR=0x82000000 CONFIG_ENV_ADDR=0x60220000 -CONFIG_AHCI=y # CONFIG_DEEP_SLEEP is not set CONFIG_LAYERSCAPE_NS_ACCESS=y CONFIG_KM_COMMON_ETH_INIT=y @@ -60,6 +59,7 @@ CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=60000000.nor,nand0=68000000.flash" CONFIG_MTDPARTS_DEFAULT="mtdparts=60000000.nor:128k(rcw),128k(qe),128k(envred),128k(env),512k(res),1m(u-boot),128k(redenvred),128k(redenv),1m(redu-boot),-(ubi0);68000000.flash:-(ubi1)" CONFIG_CMD_UBI=y +# CONFIG_CMD_UBIFS is not set CONFIG_OF_CONTROL=y CONFIG_ENV_SOURCE_FILE="pg-wcom-seli8" CONFIG_ENV_OVERWRITE=y @@ -71,6 +71,7 @@ CONFIG_ETHPRIME="ethernet@2d90000" CONFIG_USE_HOSTNAME=y CONFIG_HOSTNAME="SELI8" CONFIG_VERSION_VARIABLE=y +# CONFIG_SCSI_AHCI is not set CONFIG_BOOTCOUNT_LIMIT=y CONFIG_SYS_BOOTCOUNT_BE=y CONFIG_DDR_CLK_FREQ=50000000 @@ -96,8 +97,9 @@ CONFIG_PHY_GIGE=y CONFIG_MII=y CONFIG_TSEC_ENET=y CONFIG_SYS_QE_FW_ADDR=0x60020000 -CONFIG_SCSI_AHCI_PLAT=y +# CONFIG_SCSI is not set CONFIG_SPECIFY_CONSOLE_INDEX=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_POST=y +CONFIG_LZO=y From 5ec6cbcc7fb9604fd70587215123b77fdc326032 Mon Sep 17 00:00:00 2001 From: Stefan Bosch Date: Sun, 18 Dec 2022 12:20:49 +0000 Subject: [PATCH 18/21] arm: s5p4418: dm_serial: add driver source code Add dm_serial driver source code for S5P4418 SOC. Extend the "arm,pl011" driver by init of UART-clock and UART-reset. Signed-off-by: Stefan Bosch --- MAINTAINERS | 1 + drivers/serial/serial_s5p4418_pl011.c | 94 +++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 drivers/serial/serial_s5p4418_pl011.c diff --git a/MAINTAINERS b/MAINTAINERS index 3fc4cd0f12..5f9636f4e1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -436,6 +436,7 @@ F: drivers/gpio/nx_gpio.c F: drivers/i2c/nx_i2c.c F: drivers/mmc/nexell_dw_mmc_dm.c F: drivers/pinctrl/nexell/ +F: drivers/serial/serial_s5p4418_pl011.c F: drivers/video/nexell/ F: drivers/video/nexell_display.c F: include/configs/s5p4418_nanopi2.h diff --git a/drivers/serial/serial_s5p4418_pl011.c b/drivers/serial/serial_s5p4418_pl011.c new file mode 100644 index 0000000000..e4492e662e --- /dev/null +++ b/drivers/serial/serial_s5p4418_pl011.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Stefan Bosch + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "serial_pl01x_internal.h" + +int s5p4418_pl011_serial_probe(struct udevice *dev) +{ + struct pl01x_serial_plat *plat = dev_get_plat(dev); + struct clk *nx_clk; + ulong rate_act; + char uart_clk_name[10]; + int uart_num = -1; + int rst_id, ret; + + if (!plat->skip_init) { + uart_num = dev->seq_; + rst_id = RESET_ID_UART0 + uart_num; + + if (uart_num < 0 || rst_id > RESET_ID_UART5) { + /* invalid UART-number */ + debug("%s: sequence/uart number %d is invalid!\n", __func__, uart_num); + return -ENODEV; + } + + sprintf(uart_clk_name, "nx-uart.%d", uart_num); + nx_clk = clk_get(uart_clk_name); + if (!nx_clk) { + debug("%s: clk_get('%s') failed!\n", __func__, uart_clk_name); + return -ENODEV; + } + + /* wait to make sure all pending characters have been sent */ + mdelay(100); + } + + /* + * Note: Unless !plat->skip_init, the UART is disabled here, so printf() + * or debug() must not be used until pl01x_serial_setbrg() has been called + * (enables the UART). Otherwise u-boot is hanging! + */ + ret = pl01x_serial_probe(dev); + if (ret) + return ret; + + if (!plat->skip_init) { + /* do reset UART */ + nx_rstcon_setrst(rst_id, RSTCON_ASSERT); + udelay(10); + nx_rstcon_setrst(rst_id, RSTCON_NEGATE); + udelay(10); + clk_disable(nx_clk); + + rate_act = clk_set_rate(nx_clk, plat->clock); + clk_enable(nx_clk); + + plat->clock = rate_act; + } + + return 0; +} + +static const struct dm_serial_ops s5p4418_pl011_serial_ops = { + .putc = pl01x_serial_putc, + .pending = pl01x_serial_pending, + .getc = pl01x_serial_getc, + .setbrg = pl01x_serial_setbrg, +}; + +static const struct udevice_id s5p4418_pl011_serial_id[] = { + {.compatible = "nexell,s5p4418-pl011", .data = TYPE_PL011}, + {} +}; + +U_BOOT_DRIVER(s5p4418_pl011_uart) = { + .name = "s5p4418_pl011", + .id = UCLASS_SERIAL, + .of_match = of_match_ptr(s5p4418_pl011_serial_id), + .of_to_plat = of_match_ptr(pl01x_serial_of_to_plat), + .plat_auto = sizeof(struct pl01x_serial_plat), + .probe = s5p4418_pl011_serial_probe, + .ops = &s5p4418_pl011_serial_ops, + .flags = DM_FLAG_PRE_RELOC, + .priv_auto = sizeof(struct pl01x_priv), +}; From c8ba27f7603df729cffcb656112fdf3ba0f8a20c Mon Sep 17 00:00:00 2001 From: Stefan Bosch Date: Sun, 18 Dec 2022 12:24:33 +0000 Subject: [PATCH 19/21] arm: s5p4418: dm_serial: add uarts to dts Add S5P4418 UARTs and appropriate pinctrl to dts. Add UART to s5p4418-nanopi2.dts. Signed-off-by: Stefan Bosch --- arch/arm/dts/s5p4418-nanopi2.dts | 6 +++ arch/arm/dts/s5p4418-pinctrl.dtsi | 71 +++++++++++++++++++++++++++++++ arch/arm/dts/s5p4418.dtsi | 40 +++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/arch/arm/dts/s5p4418-nanopi2.dts b/arch/arm/dts/s5p4418-nanopi2.dts index 4deaf10a1c..42251e0a05 100644 --- a/arch/arm/dts/s5p4418-nanopi2.dts +++ b/arch/arm/dts/s5p4418-nanopi2.dts @@ -25,6 +25,7 @@ i2c0 = "/i2c@c00a4000"; i2c1 = "/i2c@c00a5000"; i2c2 = "/i2c@c00a6000"; + serial0 = "/uart@c00a1000"; }; mmc0:mmc@c0062000 { @@ -107,4 +108,9 @@ }; }; }; + + uart0:uart@c00a1000 { + skip-init; + status = "okay"; + }; }; diff --git a/arch/arm/dts/s5p4418-pinctrl.dtsi b/arch/arm/dts/s5p4418-pinctrl.dtsi index a7e1c2c381..0768d80fc9 100644 --- a/arch/arm/dts/s5p4418-pinctrl.dtsi +++ b/arch/arm/dts/s5p4418-pinctrl.dtsi @@ -132,4 +132,75 @@ pinctrl@C0010000 { pin-pull = <2>; pin-strength = <0>; }; + + /* UART */ + uart0_rx:uart0-rx { + pins = "gpiod-14"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart0_tx:uart0-tx { + pins = "gpiod-18"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart1_rx:uart1-rx { + pins = "gpiod-15"; + pin-function = <2>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart1_tx:uart1-tx { + pins = "gpiod-19"; + pin-function = <2>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart2_rx:uart2-rx { + pins = "gpiod-16"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart2_tx:uart2-tx { + pins = "gpiod-20"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart3_rx:uart3-rx { + pins = "gpiod-17"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart3_tx:uart3-tx { + pins = "gpiod-21"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart4_rx:uart4-rx { + pins = "gpiob-28"; + pin-function = <3>; + pin-pull = <2>; + pin-strength = <0>; + }; + + uart4_tx:uart4-tx { + pins = "gpiob-29"; + pin-function = <3>; + pin-pull = <2>; + pin-strength = <0>; + }; }; diff --git a/arch/arm/dts/s5p4418.dtsi b/arch/arm/dts/s5p4418.dtsi index a4d1a1bd03..3027cd4bb9 100644 --- a/arch/arm/dts/s5p4418.dtsi +++ b/arch/arm/dts/s5p4418.dtsi @@ -167,4 +167,44 @@ reg = <0xc0010000 0xf000>; u-boot,dm-pre-reloc; }; + + uart0:uart@c00a1000 { + compatible = "nexell,s5p4418-pl011", "arm,primecell"; + reg = <0xc00a1000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_rx>, <&uart0_tx>; + status = "disabled"; + }; + + uart1:uart@c00a0000 { + compatible = "nexell,s5p4418-pl011", "arm,primecell"; + reg = <0xc00a0000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_rx>, <&uart1_tx>; + status = "disabled"; + }; + + uart2:uart@c00a2000 { + compatible = "nexell,s5p4418-pl011", "arm,primecell"; + reg = <0xc00a2000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_rx>, <&uart2_tx>; + status = "disabled"; + }; + + uart3:uart@c00a3000 { + compatible = "nexell,s5p4418-pl011", "arm,primecell"; + reg = <0xc00a3000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&uart3_rx>, <&uart3_tx>; + status = "disabled"; + }; + + uart4:uart@c006d000 { + compatible = "nexell,s5p4418-pl011", "arm,primecell"; + reg = <0xc006d000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&uart4_rx>, <&uart4_tx>; + status = "disabled"; + }; }; From 5745de2c9d4beec60ffd6aa74beef9e4ac415ba5 Mon Sep 17 00:00:00 2001 From: Stefan Bosch Date: Sun, 18 Dec 2022 12:25:33 +0000 Subject: [PATCH 20/21] arm: s5p4418: dm_serial: switch to DM_SERIAL Switch the S5P4418-SOC and therefore the s5p4418_nanopi2 board to DM_SERIAL. Signed-off-by: Stefan Bosch --- arch/arm/mach-nexell/Kconfig | 4 ++-- drivers/serial/Kconfig | 9 +++++++++ drivers/serial/Makefile | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-nexell/Kconfig b/arch/arm/mach-nexell/Kconfig index 86a2398637..16324e1520 100644 --- a/arch/arm/mach-nexell/Kconfig +++ b/arch/arm/mach-nexell/Kconfig @@ -6,8 +6,8 @@ config ARCH_S5P4418 select OF_CONTROL select OF_SEPARATE select NX_GPIO - select PL011_SERIAL - select PL011_SERIAL_FLUSH_ON_INIT + select DM_SERIAL + select PL01X_SERIAL help Enable support for Nexell S5P4418 SoC. diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 14b0febd1a..bb5083201b 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -827,6 +827,15 @@ config S5P_SERIAL help Select this to enable Samsung S5P UART support. +config S5P4418_PL011_SERIAL + bool "Extended PL011 driver for S5P4418" + depends on DM_SERIAL && PL01X_SERIAL && ARCH_NEXELL + default y + help + Select this to enable support of the PL011 UARTs in the S5P4418 SOC. + With this driver the UART-clocks are set to the appropriate rate + (if not 'skip-init'). + config SANDBOX_SERIAL bool "Sandbox UART support" depends on SANDBOX diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 37d3f82dbd..01fef3f323 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_MT7620_SERIAL) += serial_mt7620.o obj-$(CONFIG_HTIF_CONSOLE) += serial_htif.o obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o obj-$(CONFIG_XEN_SERIAL) += serial_xen.o +obj-$(CONFIG_S5P4418_PL011_SERIAL) += serial_s5p4418_pl011.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_TTY) += usbtty.o From 28663622cf0767d0c5f31629ab50e34069bf0267 Mon Sep 17 00:00:00 2001 From: Stefan Bosch Date: Sun, 18 Dec 2022 12:26:47 +0000 Subject: [PATCH 21/21] arm: s5p4418: dm_serial: remove old code / add DEBUG_UART Remove init of UART-clock and UART-reset in arch_cpu_init(). Add DEBUG_UART to s5p4418_nanopi2_defconfig. Signed-off-by: Stefan Bosch --- arch/arm/cpu/armv7/s5p4418/cpu.c | 29 ----------------------------- arch/arm/mach-nexell/clock.c | 2 +- configs/s5p4418_nanopi2_defconfig | 6 +++++- include/configs/s5p4418_nanopi2.h | 8 +++----- 4 files changed, 9 insertions(+), 36 deletions(-) diff --git a/arch/arm/cpu/armv7/s5p4418/cpu.c b/arch/arm/cpu/armv7/s5p4418/cpu.c index 7ba9c0b032..fcaafc0ff7 100644 --- a/arch/arm/cpu/armv7/s5p4418/cpu.c +++ b/arch/arm/cpu/armv7/s5p4418/cpu.c @@ -13,10 +13,8 @@ #include #include #include -#include #include #include -#include DECLARE_GLOBAL_DATA_PTR; @@ -45,39 +43,12 @@ static void cpu_soc_init(void) nx_tieoff_set(NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_1, 1); } -#ifdef CONFIG_PL011_SERIAL -static void serial_device_init(void) -{ - char dev[10]; - int id; - - sprintf(dev, "nx-uart.%d", CONFIG_CONS_INDEX); - id = RESET_ID_UART0 + CONFIG_CONS_INDEX; - - struct clk *clk = clk_get((const char *)dev); - - /* reset control: Low active ___|--- */ - nx_rstcon_setrst(id, RSTCON_ASSERT); - udelay(10); - nx_rstcon_setrst(id, RSTCON_NEGATE); - udelay(10); - - /* set clock */ - clk_disable(clk); - clk_set_rate(clk, CFG_PL011_CLOCK); - clk_enable(clk); -} -#endif - int arch_cpu_init(void) { flush_dcache_all(); cpu_soc_init(); clk_init(); - if (IS_ENABLED(CONFIG_PL011_SERIAL)) - serial_device_init(); - return 0; } diff --git a/arch/arm/mach-nexell/clock.c b/arch/arm/mach-nexell/clock.c index 24fa204ccd..59ffa26255 100644 --- a/arch/arm/mach-nexell/clock.c +++ b/arch/arm/mach-nexell/clock.c @@ -856,7 +856,7 @@ void __init clk_init(void) } /* prevent uart clock disable for low step debug message */ - #ifndef CONFIG_DEBUG_NX_UART + #ifndef CONFIG_DEBUG_UART if (peri->dev_name) { #ifdef CONFIG_BACKLIGHT_PWM if (!strcmp(peri->dev_name, DEV_NAME_PWM)) diff --git a/configs/s5p4418_nanopi2_defconfig b/configs/s5p4418_nanopi2_defconfig index 35e7c88059..0645b09f78 100644 --- a/configs/s5p4418_nanopi2_defconfig +++ b/configs/s5p4418_nanopi2_defconfig @@ -11,12 +11,15 @@ CONFIG_ENV_OFFSET=0x2E0200 CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="s5p4418-nanopi2" CONFIG_SYS_PROMPT="nanopi2# " +CONFIG_DEBUG_UART_BASE=0xC00A1000 +CONFIG_DEBUG_UART_CLOCK=150000000 CONFIG_TARGET_NANOPI2=y CONFIG_S5P4418_ONEWIRE=y CONFIG_ROOT_DEV=1 CONFIG_BOOT_PART=1 CONFIG_ROOT_PART=2 CONFIG_SYS_LOAD_ADDR=0x71080000 +CONFIG_DEBUG_UART=y CONFIG_SYS_MEMTEST_START=0x71000000 CONFIG_SYS_MEMTEST_END=0xb0000000 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -54,7 +57,8 @@ CONFIG_MMC_DW=y CONFIG_PINCTRL=y CONFIG_DM_PMIC=y CONFIG_DM_REGULATOR=y -CONFIG_CONS_INDEX=0 +CONFIG_DEBUG_UART_PL011=y +CONFIG_DEBUG_UART_SKIP_INIT=y CONFIG_VIDEO=y CONFIG_VIDEO_LOGO=y CONFIG_DISPLAY=y diff --git a/include/configs/s5p4418_nanopi2.h b/include/configs/s5p4418_nanopi2.h index 2fa44e65fc..fec1bfd50e 100644 --- a/include/configs/s5p4418_nanopi2.h +++ b/include/configs/s5p4418_nanopi2.h @@ -76,11 +76,9 @@ /*----------------------------------------------------------------------- * serial console configuration */ -#define CFG_PL011_CLOCK 50000000 -#define CFG_PL01x_PORTS {(void *)PHY_BASEADDR_UART0, \ - (void *)PHY_BASEADDR_UART1, \ - (void *)PHY_BASEADDR_UART2, \ - (void *)PHY_BASEADDR_UART3} + +/* 150MHz is the clock rate set by SPL (uart0) */ +#define CFG_PL011_CLOCK 150000000 /*----------------------------------------------------------------------- * BACKLIGHT