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 2, 2025
1 parent 37d25bc commit 18abe7b
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 813d4b6e5deaadd9ba3a4a1fb13fc652cc3db7da 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 13/15] 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 6e0db6d84..e7b5455c1 100644
--- a/plat/nxp/common/include/default/plat_default_def.h
+++ b/plat/nxp/common/include/default/plat_default_def.h
@@ -159,7 +159,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 6d9b6c9aa..7bc641e7b 100644
--- a/plat/nxp/common/setup/ls_common.c
+++ b/plat/nxp/common/setup/ls_common.c
@@ -32,6 +32,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

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
From e25af4d0a6bb534a1bb9636774e810033f6c30ae 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 14/15] 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 76dfd3376..591ede2f7 100644
--- a/plat/nxp/common/setup/ls_i2c_init.c
+++ b/plat/nxp/common/setup/ls_i2c_init.c
@@ -221,9 +221,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
@@ -242,9 +245,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 50c086624c9f2de9c48c60deb756c6755d51e00f 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 15/15] 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 591ede2f7..232f52c99 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
@@ -105,7 +108,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;
@@ -113,7 +117,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,
@@ -121,7 +126,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,
@@ -129,7 +135,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,
@@ -137,7 +144,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,
@@ -145,7 +153,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,
@@ -153,7 +162,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,
@@ -161,7 +171,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,
@@ -169,7 +180,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,
@@ -208,14 +220,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;
@@ -248,7 +260,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 18abe7b

Please sign in to comment.