Skip to content

Commit

Permalink
atf: fix i2c bus flushing
Browse files Browse the repository at this point in the history
  • Loading branch information
Josua-SR committed Mar 1, 2025
1 parent bea4a51 commit b6c6923
Show file tree
Hide file tree
Showing 3 changed files with 270 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
From 0e9be06ffe73b74a5a0593112cbac2ab38acd66f Mon Sep 17 00:00:00 2001
From: Josua Mayer <josua@solid-run.com>
Date: Sat, 1 Mar 2025 12:32:03 +0100
Subject: [PATCH 20/22] plat: nxp: layerscape: mmap dynamic configuration
region in bl2

Even before DDR configuration BL2 may wish to modify dynamic
configuration registers e.g. for changing pinmux and implementing an
unstucking procedure on i2c bus.

Add mapping for DCFG area in BL2 and increment MAX_MMAP_REGIONS by one.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
plat/nxp/common/include/default/plat_default_def.h | 2 +-
plat/nxp/common/setup/ls_common.c | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/plat/nxp/common/include/default/plat_default_def.h b/plat/nxp/common/include/default/plat_default_def.h
index 7f3298006..5669cbad9 100644
--- a/plat/nxp/common/include/default/plat_default_def.h
+++ b/plat/nxp/common/include/default/plat_default_def.h
@@ -147,7 +147,7 @@
/* Check if this size can be determined from array size */
#if defined(IMAGE_BL2)
#ifndef MAX_MMAP_REGIONS
-#define MAX_MMAP_REGIONS 8
+#define MAX_MMAP_REGIONS 9
#endif
#ifndef MAX_XLAT_TABLES
#define MAX_XLAT_TABLES 6
diff --git a/plat/nxp/common/setup/ls_common.c b/plat/nxp/common/setup/ls_common.c
index 28d6b7266..bb9b3f565 100644
--- a/plat/nxp/common/setup/ls_common.c
+++ b/plat/nxp/common/setup/ls_common.c
@@ -31,6 +31,9 @@ const mmap_region_t *plat_ls_get_mmap(void);
#ifdef IMAGE_BL2
const mmap_region_t plat_ls_mmap[] = {
LS_MAP_CCSR,
+#ifdef NXP_DCSR_ADDR
+ LS_MAP_DCSR,
+#endif
{0}
};
#endif
--
2.43.0

51 changes: 51 additions & 0 deletions patches/atf/0021-lx2160a-fix-i2c-bus-flushing-glitch.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
From ad6bf95a2f593a0b85af1a3e336a18ddea03423e Mon Sep 17 00:00:00 2001
From: Ahmad Shtewe <ahmad.shtewe@solid-run.com>
Date: Sat, 1 Mar 2025 12:49:01 +0100
Subject: [PATCH 21/22] lx2160a: fix i2c bus flushing glitch

There is an unintended glitch when setting gpio direction register
before data register.

Reorder the gpio initialisation to set direction last during setup, and
first during cleanup before restoring original values.

Signed-off-by: Ahmad Shtewe <ahmad.shtewe@solid-run.com>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
plat/nxp/common/setup/ls_i2c_init.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/plat/nxp/common/setup/ls_i2c_init.c b/plat/nxp/common/setup/ls_i2c_init.c
index 5392b160d..4ef374c8f 100644
--- a/plat/nxp/common/setup/ls_i2c_init.c
+++ b/plat/nxp/common/setup/ls_i2c_init.c
@@ -244,9 +244,12 @@ static void ls_i2c_flush(uint8_t busno, const char *busname) {
gpdir |= scl_mask | sda_mask;
gpodr |= scl_mask | sda_mask;
gpdat |= scl_mask | sda_mask;
- mmio_write_32(gpdir_addr, gpdir);
- mmio_write_32(gpodr_addr, gpodr);
mmio_write_32(gpdat_addr, gpdat);
+ mmio_write_32(gpodr_addr, gpodr);
+ mmio_write_32(gpdir_addr, gpdir);
+
+ /* allow short delay for changes to propagate */
+ udelay(10);

/*
* reliable detection of blocked bus is hard
@@ -265,9 +268,9 @@ static void ls_i2c_flush(uint8_t busno, const char *busname) {
}

/* restore configuration registers */
- mmio_write_32(gpdat_addr, backup.gpdat);
- mmio_write_32(gpodr_addr, backup.gpodr);
mmio_write_32(gpdir_addr, backup.gpdir);
+ mmio_write_32(gpodr_addr, backup.gpodr);
+ mmio_write_32(gpdat_addr, backup.gpdat);
mmio_write_32(info->pinmux_addr, backup.pinmux);

return;
--
2.43.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
From 01bf691a886db9bef975bcbe2a984afcd40e24ea Mon Sep 17 00:00:00 2001
From: Ahmad Shtewe <ahmad.shtewe@solid-run.com>
Date: Fri, 28 Feb 2025 15:30:55 +0100
Subject: [PATCH 22/22] lx2160a: fix i2c bus flushing pinmux memory writes

The i2c bus flushing was broken by the previous commit in such a way
that the intended clock cycles never actually propagated to the physical
pads since changes to the memory location used did not actually impact
the pin muxing.

Update pinmux configuration to read startup settings from the RCW area,
then writing changes to the runtime configuration area.

Note that it is also required for this area to be properly mapped during
BL2.

Signed-off-by: Ahmad Shtewe <ahmad.shtewe@solid-run.com>
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
plat/nxp/common/setup/ls_i2c_init.c | 42 ++++++++++++++++++-----------
1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/plat/nxp/common/setup/ls_i2c_init.c b/plat/nxp/common/setup/ls_i2c_init.c
index 4ef374c8f..bbb59c476 100644
--- a/plat/nxp/common/setup/ls_i2c_init.c
+++ b/plat/nxp/common/setup/ls_i2c_init.c
@@ -17,7 +17,8 @@
#define NXP_IIC7_ADDR 0x02060000
#define NXP_IIC8_ADDR 0x02070000

-#define RCWSR12 0x01e0012c
+#define RCWSR12R 0x01e0012c
+#define RCWSR12W 0x70010012c
#define RCWSR12_IIC2_PMUX_MASK 0x00000007 /* [0..2] */
#define RCWSR12_IIC2_PMUX_IIC2 0x00000000
#define RCWSR12_IIC2_PMUX_GPIO 0x00000001
@@ -33,11 +34,13 @@
#define RCWSR12_IIC6_PMUX_MASK 0x00007000 /* [12..14] */
#define RCWSR12_IIC6_PMUX_IIC6 0x00000000
#define RCWSR12_IIC6_PMUX_GPIO 0x00001000
-#define RCWSR13 0x01e00130
+#define RCWSR13R 0x01e00130
+#define RCWSR13W 0x700100130
#define RCWSR12_SDHC2_DAT74_PMUX_MASK 0x00000003
#define RCWSR12_SDHC2_DAT74_PMUX_SDHC2 0x00000000
#define RCWSR12_SDHC2_DAT74_PMUX_IIC78 0x00000001
-#define RCWSR14 0x01e00134
+#define RCWSR14R 0x01e00134
+#define RCWSR14W 0x700100134
#define RCWSR14_IIC1_PMUX_MASK 0x00000400 /* [10] */
#define RCWSR14_IIC1_PMUX_IIC1 0x00000000
#define RCWSR14_IIC1_PMUX_GPIO 0x00000400
@@ -128,7 +131,8 @@ static void ls_i2c_flush_pca9547(uint8_t busno, const char *busname, uint8_t chi
}

static struct i2c_bus_info {
- uintptr_t pinmux_addr;
+ uintptr_t pinmux_addr_r;
+ uintptr_t pinmux_addr_w;
uint32_t pinmux_mask;
uint32_t pinmux_sel;
uintptr_t gpio_addr;
@@ -136,7 +140,8 @@ static struct i2c_bus_info {
uint8_t gpio_sda;
} ls_i2c_bus_info[] = {
{
- .pinmux_addr = RCWSR14,
+ .pinmux_addr_r = RCWSR14R,
+ .pinmux_addr_w = RCWSR14W,
.pinmux_mask = RCWSR14_IIC1_PMUX_MASK,
.pinmux_sel = RCWSR14_IIC1_PMUX_GPIO,
.gpio_addr = NXP_GPIO1_ADDR,
@@ -144,7 +149,8 @@ static struct i2c_bus_info {
.gpio_sda = 2, /* GPIO1_DAT02 */
},
{
- .pinmux_addr = RCWSR12,
+ .pinmux_addr_r = RCWSR12R,
+ .pinmux_addr_w = RCWSR12W,
.pinmux_mask = RCWSR12_IIC2_PMUX_MASK,
.pinmux_sel = RCWSR12_IIC2_PMUX_GPIO,
.gpio_addr = NXP_GPIO1_ADDR,
@@ -152,7 +158,8 @@ static struct i2c_bus_info {
.gpio_sda = 30, /* GPIO1_DAT30 */
},
{
- .pinmux_addr = RCWSR12,
+ .pinmux_addr_r = RCWSR12R,
+ .pinmux_addr_w = RCWSR12W,
.pinmux_mask = RCWSR12_IIC3_PMUX_MASK,
.pinmux_sel = RCWSR12_IIC3_PMUX_GPIO,
.gpio_addr = NXP_GPIO1_ADDR,
@@ -160,7 +167,8 @@ static struct i2c_bus_info {
.gpio_sda = 28, /* GPIO1_DAT28 */
},
{
- .pinmux_addr = RCWSR12,
+ .pinmux_addr_r = RCWSR12R,
+ .pinmux_addr_w = RCWSR12W,
.pinmux_mask = RCWSR12_IIC4_PMUX_MASK,
.pinmux_sel = RCWSR12_IIC4_PMUX_GPIO,
.gpio_addr = NXP_GPIO1_ADDR,
@@ -168,7 +176,8 @@ static struct i2c_bus_info {
.gpio_sda = 26, /* GPIO1_DAT26 */
},
{
- .pinmux_addr = RCWSR12,
+ .pinmux_addr_r = RCWSR12R,
+ .pinmux_addr_w = RCWSR12W,
.pinmux_mask = RCWSR12_IIC5_PMUX_MASK,
.pinmux_sel = RCWSR12_IIC5_PMUX_GPIO,
.gpio_addr = NXP_GPIO1_ADDR,
@@ -176,7 +185,8 @@ static struct i2c_bus_info {
.gpio_sda = 24, /* GPIO1_DAT24 */
},
{
- .pinmux_addr = RCWSR12,
+ .pinmux_addr_r = RCWSR12R,
+ .pinmux_addr_w = RCWSR12W,
.pinmux_mask = RCWSR12_IIC6_PMUX_MASK,
.pinmux_sel = RCWSR12_IIC6_PMUX_GPIO,
.gpio_addr = NXP_GPIO1_ADDR,
@@ -184,7 +194,8 @@ static struct i2c_bus_info {
.gpio_sda = 22, /* GPIO1_DAT22 */
},
{
- .pinmux_addr = RCWSR13,
+ .pinmux_addr_r = RCWSR13R,
+ .pinmux_addr_w = RCWSR13W,
.pinmux_mask = RCWSR12_SDHC2_DAT74_PMUX_MASK,
.pinmux_sel = RCWSR12_SDHC2_DAT74_PMUX_IIC78,
.gpio_addr = NXP_GPIO2_ADDR,
@@ -192,7 +203,8 @@ static struct i2c_bus_info {
.gpio_sda = 15, /* GPIO2_DAT15 */
},
{
- .pinmux_addr = RCWSR13,
+ .pinmux_addr_r = RCWSR13R,
+ .pinmux_addr_w = RCWSR13W,
.pinmux_mask = RCWSR12_SDHC2_DAT74_PMUX_MASK,
.pinmux_sel = RCWSR12_SDHC2_DAT74_PMUX_IIC78,
.gpio_addr = NXP_GPIO2_ADDR,
@@ -231,14 +243,14 @@ static void ls_i2c_flush(uint8_t busno, const char *busname) {
sda_mask = 0x80000000 >> info->gpio_sda;

/* backup configuration registers */
- pinmux = backup.pinmux = mmio_read_32(info->pinmux_addr);
+ pinmux = backup.pinmux = mmio_read_32(info->pinmux_addr_r);
gpdir = backup.gpdir = mmio_read_32(gpdir_addr);
gpodr = backup.gpodr = mmio_read_32(gpodr_addr);
gpdat = backup.gpdat = mmio_read_32(gpdat_addr);

/* configure SCL+SDA as GPIOs */
pinmux = (pinmux & ~info->pinmux_mask) | info->pinmux_sel;
- mmio_write_32(info->pinmux_addr, pinmux);
+ mmio_write_32(info->pinmux_addr_w, pinmux);

/* configure SCL+SDA as output open drain */
gpdir |= scl_mask | sda_mask;
@@ -271,7 +283,7 @@ static void ls_i2c_flush(uint8_t busno, const char *busname) {
mmio_write_32(gpdir_addr, backup.gpdir);
mmio_write_32(gpodr_addr, backup.gpodr);
mmio_write_32(gpdat_addr, backup.gpdat);
- mmio_write_32(info->pinmux_addr, backup.pinmux);
+ mmio_write_32(info->pinmux_addr_w, backup.pinmux);

return;
}
--
2.43.0

0 comments on commit b6c6923

Please sign in to comment.