Nico Huber has submitted this change. ( https://review.coreboot.org/c/coreboot/+/44476 )
Change subject: ec/kontron/kempld: add option to configure I2C frequency ......................................................................
ec/kontron/kempld: add option to configure I2C frequency
Allows to change the I2C bus frequency by overriding i2c_frequency option from the board devicetree. Thus, the I2C controller can use Fast-mode (Fm), with a bit rate up to 400 kbit/s and Fast-mode Plus (Fm+), with a bit rate up to 1 Mbit/s [1].
Tested on Kontron mAL10 COMe module with T10-TNI carrierboard [2].
[1] I2C-bus specification and user manual, doc #UM10204, Rev. 6, 4 April 2014. [2] https://review.coreboot.org/c/coreboot/+/39133
Change-Id: If0eb477af10d00eb4f17f9c01209f170b746ad3d Signed-off-by: Maxim Polyakov max.senia.poliak@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/44476 Reviewed-by: Angel Pons th3fanbus@gmail.com Reviewed-by: Nico Huber nico.h@gmx.de Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/ec/kontron/kempld/chip.h M src/ec/kontron/kempld/kempld_i2c.c 2 files changed, 25 insertions(+), 6 deletions(-)
Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved Angel Pons: Looks good to me, approved
diff --git a/src/ec/kontron/kempld/chip.h b/src/ec/kontron/kempld/chip.h index 8ca8d24..30f40fe 100644 --- a/src/ec/kontron/kempld/chip.h +++ b/src/ec/kontron/kempld/chip.h @@ -12,6 +12,13 @@ KEMPLD_UART_2E8 = 3, };
+enum kempld_i2c_frequency { + KEMPLD_I2C_FREQ_STANDARD_MODE_100KHZ = 100, + KEMPLD_I2C_FREQ_FAST_MODE_400KHZ = 400, + KEMPLD_I2C_FREQ_FAST_PLUS_MODE_1MHZ = 1000, + KEMPLD_I2C_FREQ_MAX = 2700, +}; + struct kempld_uart { enum kempld_uart_io io; unsigned int irq; @@ -19,6 +26,7 @@
struct ec_kontron_kempld_config { struct kempld_uart uart[KEMPLD_NUM_UARTS]; + unsigned short i2c_frequency; };
#endif /* EC_KONTRON_KEMPLD_CHIP_H */ diff --git a/src/ec/kontron/kempld/kempld_i2c.c b/src/ec/kontron/kempld/kempld_i2c.c index 296cf76..8abbb4b 100644 --- a/src/ec/kontron/kempld/kempld_i2c.c +++ b/src/ec/kontron/kempld/kempld_i2c.c @@ -13,6 +13,7 @@ #include <timer.h> #include <delay.h>
+#include "chip.h" #include "kempld.h" #include "kempld_internal.h"
@@ -40,9 +41,6 @@ #define I2C_CMD_READ_NACK 0x29 #define I2C_CMD_IACK 0x01
-#define KEMPLD_I2C_FREQ_MAX 2700 /* 2.7 mHz */ -#define KEMPLD_I2C_FREQ_STD 100 /* 100 kHz */ - #define EIO 5 #define ENXIO 6 #define EAGAIN 11 @@ -230,7 +228,8 @@
void kempld_i2c_device_init(struct device *const dev) { - u16 prescale_corr; + const struct ec_kontron_kempld_config *const config = dev->chip_info; + u16 prescale_corr, frequency; long prescale; u8 ctrl; u8 stat; @@ -244,11 +243,23 @@ ctrl &= ~(I2C_CTRL_EN | I2C_CTRL_IEN); kempld_write8(KEMPLD_I2C_CTRL, ctrl);
+ frequency = KEMPLD_I2C_FREQ_STANDARD_MODE_100KHZ; + if (config && config->i2c_frequency) { + if (config->i2c_frequency <= KEMPLD_I2C_FREQ_MAX) { + frequency = config->i2c_frequency; + } else { + printk(BIOS_NOTICE, + "kempld_i2c: %d kHz is too high!\n", + config->i2c_frequency); + } + } + printk(BIOS_INFO, "kempld_i2c: Use frequency %d\n", frequency); + const u8 spec_major = KEMPLD_SPEC_GET_MAJOR(kempld_read8(KEMPLD_SPEC)); if (spec_major == 1) - prescale = KEMPLD_CLK / (KEMPLD_I2C_FREQ_STD * 5) - 1000; + prescale = KEMPLD_CLK / (frequency * 5) - 1000; else - prescale = KEMPLD_CLK / (KEMPLD_I2C_FREQ_STD * 4) - 3000; + prescale = KEMPLD_CLK / (frequency * 4) - 3000;
if (prescale < 0) prescale = 0;