summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJes B. Klinke <jbk@chromium.org>2023-05-16 15:07:36 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-05-17 16:34:57 +0000
commit6ce23606728a59d2ebe0a1f8a24bdce840a21ade (patch)
tree93020a64d462bce1fdca30c84224185544b2641e
parent7ce45f8de9a0a91b1bbd1402acb3132abcd16cc3 (diff)
downloadchrome-ec-6ce23606728a59d2ebe0a1f8a24bdce840a21ade.tar.gz
chip/stm32: Support for I2C4 instance on STM32L4/5
The L4/L5 families have four I2C controllers. The fourth has its registers in a separate region, and enable bits are not contiguous with the first three. This CL adds a few if-statements in i2c driver code, in order to support all four controllers. BUG=b:282999020 TEST=Observe I2C activity on HyperDebug I2C4 Change-Id: If27eda73b3da32190bad7df5db8c6bb6c78b4c5c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4537011 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Jes Klinke <jbk@chromium.org> Tested-by: Jes Klinke <jbk@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--chip/stm32/i2c-stm32l4.c23
-rw-r--r--chip/stm32/registers-stm32l4.h12
-rw-r--r--chip/stm32/registers-stm32l5.h6
-rw-r--r--chip/stm32/registers.h8
4 files changed, 42 insertions, 7 deletions
diff --git a/chip/stm32/i2c-stm32l4.c b/chip/stm32/i2c-stm32l4.c
index a4b9452379..5d4e51e92e 100644
--- a/chip/stm32/i2c-stm32l4.c
+++ b/chip/stm32/i2c-stm32l4.c
@@ -150,15 +150,26 @@ static void i2c_init_port(const struct i2c_port_t *p)
enum i2c_freq freq;
/* Enable I2C clock */
- if (!(STM32_RCC_APB1ENR1 & (1 << (21 + port))))
+ if (port == 3) {
+ STM32_RCC_APB1ENR2 |= STM32_RCC_APB1ENR2_I2C4EN;
+ } else {
STM32_RCC_APB1ENR1 |= 1 << (21 + port);
+ }
/* Select HSI 16MHz as I2C clock source */
- val = STM32_RCC_CCIPR;
- val &= ~(STM32_RCC_CCIPR_I2C1SEL_MASK << (port * 2));
- val |= STM32_RCC_CCIPR_I2C_HSI16
- << (STM32_RCC_CCIPR_I2C1SEL_SHIFT + port * 2);
- STM32_RCC_CCIPR = val;
+ if (port == 3) {
+ val = STM32_RCC_CCIPR2;
+ val &= ~STM32_RCC_CCIPR2_I2C4SEL_MSK;
+ val |= STM32_RCC_CCIPR_I2C_HSI16
+ << STM32_RCC_CCIPR2_I2C4SEL_POS;
+ STM32_RCC_CCIPR2 = val;
+ } else {
+ val = STM32_RCC_CCIPR;
+ val &= ~(STM32_RCC_CCIPR_I2C1SEL_MASK << (port * 2));
+ val |= STM32_RCC_CCIPR_I2C_HSI16
+ << (STM32_RCC_CCIPR_I2C1SEL_SHIFT + port * 2);
+ STM32_RCC_CCIPR = val;
+ }
/* Configure GPIOs */
gpio_config_module(MODULE_I2C, 1);
diff --git a/chip/stm32/registers-stm32l4.h b/chip/stm32/registers-stm32l4.h
index b55204be5e..583f0a688a 100644
--- a/chip/stm32/registers-stm32l4.h
+++ b/chip/stm32/registers-stm32l4.h
@@ -151,6 +151,7 @@
#define STM32_OPAMP1_BASE (APB1PERIPH_BASE + 0x7800UL)
#define STM32_LPTIM1_BASE (APB1PERIPH_BASE + 0x7C00UL)
#define STM32_LPUART1_BASE (APB1PERIPH_BASE + 0x8000UL)
+#define STM32_I2C4_BASE (APB1PERIPH_BASE + 0x8400UL)
#define STM32_SWPMI1_BASE (APB1PERIPH_BASE + 0x8800UL)
#define STM32_LPTIM2_BASE (APB1PERIPH_BASE + 0x9400UL)
@@ -513,6 +514,7 @@
#define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x90)
#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x94)
#define STM32_RCC_CRRCR REG32(STM32_RCC_BASE + 0x98)
+#define STM32_RCC_CCIPR2 REG32(STM32_RCC_BASE + 0x9C)
#define STM32_RCC_PLLSAI1_SUPPORT
#define STM32_RCC_PLLP_SUPPORT
@@ -1278,6 +1280,9 @@
#define STM32_RCC_APB1ENR2_LPUART1EN_MSK \
(0x1UL << STM32_RCC_APB1ENR2_LPUART1EN_POS)
#define STM32_RCC_APB1ENR2_LPUART1EN STM32_RCC_APB1ENR2_LPUART1EN_MSK
+#define STM32_RCC_APB1ENR2_I2C4EN_POS 1U
+#define STM32_RCC_APB1ENR2_I2C4EN_MSK (0x1UL << STM32_RCC_APB1ENR2_I2C4EN_POS)
+#define STM32_RCC_APB1ENR2_I2C4EN STM32_RCC_APB1ENR2_I2C4EN_MSK
#define STM32_RCC_APB1ENR2_SWPMI1EN_POS 2U
#define STM32_RCC_APB1ENR2_SWPMI1EN_MSK \
(0x1UL << STM32_RCC_APB1ENR2_SWPMI1EN_POS)
@@ -1597,6 +1602,13 @@
#define STM32_RCC_CCIPR_SWPMI1SEL_MSK (0x1UL << STM32_RCC_CCIPR_SWPMI1SEL_POS)
#define STM32_RCC_CCIPR_SWPMI1SEL STM32_RCC_CCIPR_SWPMI1SEL_MSK
+/************** Bit definition for STM32_RCC_CCIPR2 register ****************/
+#define STM32_RCC_CCIPR2_I2C4SEL_POS 0U
+#define STM32_RCC_CCIPR2_I2C4SEL_MSK (0x3UL << STM32_RCC_CCIPR2_I2C4SEL_POS)
+#define STM32_RCC_CCIPR2_I2C4SEL STM32_RCC_CCIPR2_I2C4SEL_MSK
+#define STM32_RCC_CCIPR2_I2C4SEL_0 (0x1UL << STM32_RCC_CCIPR2_I2C4SEL_POS)
+#define STM32_RCC_CCIPR2_I2C4SEL_1 (0x2UL << STM32_RCC_CCIPR2_I2C4SEL_POS)
+
/************** BIT DEFINITION FOR STM32_RCC_BDCR REGISTER ******************/
#define STM32_RCC_BDCR_LSEBYP_POS 2U
#define STM32_RCC_BDCR_LSEBYP_MSK (0x1UL << STM32_RCC_BDCR_LSEBYP_POS)
diff --git a/chip/stm32/registers-stm32l5.h b/chip/stm32/registers-stm32l5.h
index 7af7eba888..f83802cf5f 100644
--- a/chip/stm32/registers-stm32l5.h
+++ b/chip/stm32/registers-stm32l5.h
@@ -1903,7 +1903,11 @@
/* TODO */
/************** Bit definition for STM32_RCC_CCIPR2 register ****************/
-/* TODO */
+#define STM32_RCC_CCIPR2_I2C4SEL_POS 0U
+#define STM32_RCC_CCIPR2_I2C4SEL_MSK (0x3UL << STM32_RCC_CCIPR2_I2C4SEL_POS)
+#define STM32_RCC_CCIPR2_I2C4SEL STM32_RCC_CCIPR2_I2C4SEL_MSK
+#define STM32_RCC_CCIPR2_I2C4SEL_0 (0x1UL << STM32_RCC_CCIPR2_I2C4SEL_POS)
+#define STM32_RCC_CCIPR2_I2C4SEL_1 (0x2UL << STM32_RCC_CCIPR2_I2C4SEL_POS)
/************** Bit definition for STM32_CRS_CR register ********************/
#define STM32_CRS_CR_SYNCOKIE_POS 0U
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index c4441315af..1ec4370ef1 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -190,8 +190,16 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_I2C3_PORT 2
#define STM32_FMPI2C4_PORT 3
+#if defined(CHIP_FAMILY_STM32L4) || defined(CHIP_FAMILY_STM32L5)
+#define stm32_i2c_reg(port, offset) \
+ ((uint16_t *)(((port) == 3 ? STM32_I2C4_BASE : \
+ (STM32_I2C1_BASE + ((port)*0x400))) + \
+ (offset)))
+#else
#define stm32_i2c_reg(port, offset) \
((uint16_t *)((STM32_I2C1_BASE + ((port)*0x400)) + (offset)))
+#endif
+
/* --- Power / Reset / Clocks --- */
#define STM32_PWR_CR REG32(STM32_PWR_BASE + 0x00)
#define STM32_PWR_CR_LPSDSR (1 << 0)