diff options
author | Jes B. Klinke <jbk@chromium.org> | 2023-05-16 15:07:36 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-05-17 16:34:57 +0000 |
commit | 6ce23606728a59d2ebe0a1f8a24bdce840a21ade (patch) | |
tree | 93020a64d462bce1fdca30c84224185544b2641e | |
parent | 7ce45f8de9a0a91b1bbd1402acb3132abcd16cc3 (diff) | |
download | chrome-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.c | 23 | ||||
-rw-r--r-- | chip/stm32/registers-stm32l4.h | 12 | ||||
-rw-r--r-- | chip/stm32/registers-stm32l5.h | 6 | ||||
-rw-r--r-- | chip/stm32/registers.h | 8 |
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) |