From deb26b6c29670dee743dfb54b8f69866339580bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Fri, 20 Dec 2024 11:37:51 +0100 Subject: [PATCH 1/4] powerpc: mpc83xx: Fix timer value calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TBU and TBL are specified as two 32-bit registers that form a 64-bit value, but the calculation only shifted TBU by 16 bits. Fix this by actually shifting 32 bits. Reviewed-by: Sinan Akman Signed-off-by: J. Neuschäfer --- drivers/timer/mpc83xx_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c index 9da74479aaa..f92009e4ccc 100644 --- a/drivers/timer/mpc83xx_timer.c +++ b/drivers/timer/mpc83xx_timer.c @@ -206,7 +206,7 @@ static u64 mpc83xx_timer_get_count(struct udevice *dev) tbl = mftb(); } while (tbu != mftbu()); - return (tbu * 0x10000ULL) + tbl; + return (uint64_t)tbu << 32 | tbl; } static int mpc83xx_timer_probe(struct udevice *dev) From b3e8c67a91b6e614fa84db270010da4faa702a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Fri, 20 Dec 2024 11:37:52 +0100 Subject: [PATCH 2/4] powerpc: mpc83xx: Allow including initreg.h into multiple files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Globals defined in headers can result in multiple-definition errors while linking, if they are visible beyond the current translation unit. This hasn't been a problem for initreg.h so far, but would become a problem in the next patch, where I use a constant from initreg.h in a second C file. Reviewed-by: Sinan Akman Signed-off-by: J. Neuschäfer --- arch/powerpc/cpu/mpc83xx/initreg/initreg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/cpu/mpc83xx/initreg/initreg.h b/arch/powerpc/cpu/mpc83xx/initreg/initreg.h index 63aa5c94669..ea1176e7fe1 100644 --- a/arch/powerpc/cpu/mpc83xx/initreg/initreg.h +++ b/arch/powerpc/cpu/mpc83xx/initreg/initreg.h @@ -13,7 +13,7 @@ #define SPCR_TSECBDP_MASK 0x00000C00 #define SPCR_TSECEP_MASK 0x00000300 - const __be32 spcr_mask = + static const __be32 spcr_mask = #if defined(CONFIG_SPCR_OPT) && !defined(CONFIG_SPCR_OPT_UNSET) SPCR_OPT_MASK | #endif @@ -27,7 +27,7 @@ SPCR_TSEC2EP_MASK | #endif 0; - const __be32 spcr_val = + static const __be32 spcr_val = #if defined(CONFIG_SPCR_OPT) && !defined(CONFIG_SPCR_OPT_UNSET) CONFIG_SPCR_OPT | #endif @@ -42,7 +42,7 @@ #endif 0; - const __be32 lcrr_mask = + static const __be32 lcrr_mask = #if defined(CONFIG_LCRR_DBYP) && !defined(CONFIG_LCRR_DBYP_UNSET) LCRR_DBYP | #endif @@ -60,7 +60,7 @@ #endif 0; - const __be32 lcrr_val = + static const __be32 lcrr_val = #if defined(CONFIG_LCRR_DBYP) && !defined(CONFIG_LCRR_DBYP_UNSET) CONFIG_LCRR_DBYP | #endif From ba26b1d0fb923c0b145f15d132dc7561267bb8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Fri, 20 Dec 2024 11:37:53 +0100 Subject: [PATCH 3/4] powerpc: mpc83xx: Use defined constant for SPCR[TBEN] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To increase readability, use the defined constant instead of specifying SPCR[TBEN] as a number. Reviewed-by: Sinan Akman Signed-off-by: J. Neuschäfer --- arch/powerpc/cpu/mpc83xx/interrupts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/cpu/mpc83xx/interrupts.c b/arch/powerpc/cpu/mpc83xx/interrupts.c index af517213f17..bb37a1332c8 100644 --- a/arch/powerpc/cpu/mpc83xx/interrupts.c +++ b/arch/powerpc/cpu/mpc83xx/interrupts.c @@ -12,6 +12,7 @@ #include #include #include +#include "initreg/initreg.h" DECLARE_GLOBAL_DATA_PTR; @@ -29,7 +30,7 @@ void interrupt_init_cpu (unsigned *decrementer_count) /* Enable e300 time base */ - immr->sysconf.spcr |= 0x00400000; + immr->sysconf.spcr |= SPCR_TBEN_MASK; } /* From 880374542845c0f7cdc4e60a913a987e6ff06b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Fri, 20 Dec 2024 11:37:54 +0100 Subject: [PATCH 4/4] gpio: mpc8xxx: Preserve pre-init state of outputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mpc8xxx_gpio driver contains a workaround for certain chips where the previously written state of outputs cannot be read back from the GPIO data (GPDAT) register (MPC8572/MPC8536). This workaround consists of tracking the state of GPDAT in a "shadow register" (i.e. a software variable). The shadow register is initialized to zero. This results in a problem w.r.t. outputs that are configured to a high (1) state before U-Boot runs, but not touched by U-Boot itself: Due to the zero-initialization, these GPIOs end up being set to zero, the first time that any other output is set. To avoid such issues initialize the GPDAT shadow register to the value previously held by any outputs, if possible. On MPC8572/MPC8536 this should make no difference, i.e. the shadow register should be initialized to zero on these chips. This patch has been tested on a MPC8314E-based board. Reviewed-by: Sinan Akman Signed-off-by: J. Neuschäfer --- drivers/gpio/mpc8xxx_gpio.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c index e9bd38f162c..709d04017d1 100644 --- a/drivers/gpio/mpc8xxx_gpio.c +++ b/drivers/gpio/mpc8xxx_gpio.c @@ -204,7 +204,17 @@ static int mpc8xxx_gpio_plat_to_priv(struct udevice *dev) return -ENOMEM; priv->gpio_count = plat->ngpios; - priv->dat_shadow = 0; + + /* + * On platforms that do support reading back output values, we want to + * try preserving them, so that we don't accidentally set unrelated + * GPIOs to zero in mpc8xxx_gpio_set_value. + */ + if (priv->little_endian) + priv->dat_shadow = in_le32(&priv->base->gpdat) & in_le32(&priv->base->gpdir); + else + priv->dat_shadow = in_be32(&priv->base->gpdat) & in_be32(&priv->base->gpdir); + priv->type = driver_data;