[gnome-build-meta/jjardon/robjh/icicle: 2/4] Add u-boot for the icicle boards.
- From: Javier Jardón <jjardon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-build-meta/jjardon/robjh/icicle: 2/4] Add u-boot for the icicle boards.
- Date: Tue, 12 Oct 2021 15:05:56 +0000 (UTC)
commit 1b775ad4636d3925c42abb9878f24e8a6103ab1f
Author: Robin J. Heywood <robin heywood codethink co uk>
Date: Tue Oct 12 13:56:56 2021 +0100
Add u-boot for the icicle boards.
These are the sources (along with patches) that are built from the
polarfire buildroot bsp.
https://github.com/polarfire-soc/polarfire-soc-buildroot-sdk
elements/boards/icicle-kit/u-boot.bst | 32 +
.../icicle-kit/u-boot/conf/configs/smode_defconfig | 21 +
.../boards/icicle-kit/u-boot/conf/uEnv_s-mode.txt | 14 +
.../0001-riscv-icicle-kit-add-i2c-support.patch | 1165 ++++++++++++++++++++
4 files changed, 1232 insertions(+)
---
diff --git a/elements/boards/icicle-kit/u-boot.bst b/elements/boards/icicle-kit/u-boot.bst
new file mode 100644
index 000000000..f3ec1208d
--- /dev/null
+++ b/elements/boards/icicle-kit/u-boot.bst
@@ -0,0 +1,32 @@
+kind: manual
+
+sources:
+- kind: tar
+ url: ftp://ftp.denx.de/pub/u-boot/u-boot-2021.04.tar.bz2
+- kind: local
+ path: files/boards/icicle-kit/u-boot/conf/
+- kind: patch
+ path: files/boards/icicle-kit/u-boot/patch/0001-riscv-icicle-kit-add-i2c-support.patch
+
+depends:
+- freedesktop-sdk.bst:bootstrap-import.bst
+
+build-depends:
+- freedesktop-sdk.bst:components/bison.bst
+- freedesktop-sdk.bst:components/flex.bst
+- freedesktop-sdk.bst:components/gzip.bst
+- freedesktop-sdk.bst:components/bc.bst
+
+variables:
+ board: smode
+
+config:
+ configure-commands:
+ - make "%{board}_defconfig"
+
+ build-commands:
+ - make V=1 all
+
+ install-commands:
+ - install -Dm644 -t "%{install-root}%{indep-libdir}/u-boot/%{board}" u-boot.bin
+ - install -Dm755 -t "%{install-root}%{bindir}" tools/mkimage
diff --git a/files/boards/icicle-kit/u-boot/conf/configs/smode_defconfig
b/files/boards/icicle-kit/u-boot/conf/configs/smode_defconfig
new file mode 100644
index 000000000..a2ccc7685
--- /dev/null
+++ b/files/boards/icicle-kit/u-boot/conf/configs/smode_defconfig
@@ -0,0 +1,21 @@
+CONFIG_RISCV=y
+CONFIG_ENV_SIZE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit"
+CONFIG_TARGET_MICROCHIP_ICICLE=y
+CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_SBI_V01=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_BOOTP_SEND_HOSTNAME=y
+CONFIG_DM_MTD=y
+CONFIG_BOOTCOMMAND="setenv fileaddr 0x90000000; load mmc 0:2 ${fileaddr} boot.scr; source ${fileaddr};"
+CONFIG_SYS_BOOT_RAMDISK_HIGH=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MICROCHIP=y
+CONFIG_CMD_I2C=y
+CONFIG_SYS_I2C_SPEED=100000
\ No newline at end of file
diff --git a/files/boards/icicle-kit/u-boot/conf/uEnv_s-mode.txt
b/files/boards/icicle-kit/u-boot/conf/uEnv_s-mode.txt
new file mode 100644
index 000000000..7c4b2a1cf
--- /dev/null
+++ b/files/boards/icicle-kit/u-boot/conf/uEnv_s-mode.txt
@@ -0,0 +1,14 @@
+# This is the s-mode U-Boot script for the {,lc-}mpfs development kits.
+
+# this assumes ${fileaddr} is already set!!
+
+load mmc 0:2 ${fileaddr} fitImage.fit;
+bootm start 0x90000000;
+bootm loados 0x90000000;
+bootm ramdisk;
+bootm fdt;
+fdt addr 0x82200000;
+bootm prep;
+fdt set /soc/ethernet@20112000 mac-address ${icicle_mac_addr0};
+fdt set /soc/ethernet@20110000 mac-address ${icicle_mac_addr1}
+bootm go;
diff --git a/files/boards/icicle-kit/u-boot/patch/0001-riscv-icicle-kit-add-i2c-support.patch
b/files/boards/icicle-kit/u-boot/patch/0001-riscv-icicle-kit-add-i2c-support.patch
new file mode 100644
index 000000000..e3c1c54f6
--- /dev/null
+++ b/files/boards/icicle-kit/u-boot/patch/0001-riscv-icicle-kit-add-i2c-support.patch
@@ -0,0 +1,1165 @@
+From 3bb0dcb60edbb4df34a21371142020f7f8686838 Mon Sep 17 00:00:00 2001
+From: Conor Dooley <conor dooley microchip com>
+Date: Fri, 16 Jul 2021 12:56:29 +0100
+Subject: [PATCH] riscv: icicle kit: add i2c support
+
+---
+ arch/riscv/dts/microchip-mpfs-icicle-kit.dts | 4 +-
+ configs/microchip_mpfs_icicle_defconfig | 4 +
+ drivers/i2c/Kconfig | 8 +
+ drivers/i2c/Makefile | 2 +-
+ drivers/i2c/i2c-microchip.c | 511 ++++++++++++++++++
+ drivers/i2c/i2c-microsemi.c | 537 +++++++++++++++++++
+ include/configs/microchip_mpfs_icicle.h | 2 +
+ 7 files changed, 1065 insertions(+), 3 deletions(-)
+ create mode 100755 drivers/i2c/i2c-microchip.c
+ create mode 100755 drivers/i2c/i2c-microsemi.c
+
+diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit.dts b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts
+index e2b9decc94..82a946a3ae 100644
+--- a/arch/riscv/dts/microchip-mpfs-icicle-kit.dts
++++ b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts
+@@ -328,7 +328,7 @@
+ interrupt-parent = <&plic>;
+ interrupts = <58>;
+ clocks = <&clkcfg CLK_I2C0>;
+- status = "disabled";
++ status = "okay";
+ };
+ i2c1: i2c@2010b000 {
+ #address-cells = <1>;
+@@ -338,7 +338,7 @@
+ interrupt-parent = <&plic>;
+ interrupts = <61>;
+ clocks = <&clkcfg CLK_I2C1>;
+- status = "disabled";
++ status = "okay";
+ pac193x@10 {
+ compatible = "microchip,pac1934";
+ reg = <0x10>;
+diff --git a/configs/microchip_mpfs_icicle_defconfig b/configs/microchip_mpfs_icicle_defconfig
+index 0c15c3bd38..463601e79c 100644
+--- a/configs/microchip_mpfs_icicle_defconfig
++++ b/configs/microchip_mpfs_icicle_defconfig
+@@ -13,3 +13,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
+ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+ CONFIG_BOOTP_SEND_HOSTNAME=y
+ CONFIG_DM_MTD=y
++CONFIG_DM_I2C=y
++CONFIG_SYS_I2C_MICROCHIP=y
++CONFIG_CMD_I2C=y
++CONFIG_SYS_I2C_SPEED=100000
+diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
+index 1844941eb2..6e09a698c4 100644
+--- a/drivers/i2c/Kconfig
++++ b/drivers/i2c/Kconfig
+@@ -180,6 +180,14 @@ config SYS_I2C_MESON
+ internal buffer holding up to 8 bytes for transfers and supports
+ both 7-bit and 10-bit addresses.
+
++
++config SYS_I2C_MICROCHIP
++ bool "Microchip I2C"
++ help
++ If you say yes to this option, support will be included for the
++ Microchip I2C interface.
++
++
+ config SYS_I2C_MXC
+ bool "NXP MXC I2C driver"
+ help
+diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
+index acd27ac29d..d803fcbd06 100644
+--- a/drivers/i2c/Makefile
++++ b/drivers/i2c/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_SYS_I2C_IPROC) += iproc_i2c.o
+ obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o
+ obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o
+ obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o
++obj-y += i2c-microchip.o
+ obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
+ obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
+ obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
+@@ -51,5 +52,4 @@ obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o
+ obj-$(CONFIG_SYS_I2C_VERSATILE) += i2c-versatile.o
+ obj-$(CONFIG_SYS_I2C_XILINX_XIIC) += xilinx_xiic.o
+ obj-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o
+-
+ obj-$(CONFIG_$(SPL_)I2C_MUX) += muxes/
+diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c
+new file mode 100755
+index 0000000000..95eaccef4d
+--- /dev/null
++++ b/drivers/i2c/i2c-microchip.c
+@@ -0,0 +1,511 @@
++#define DEBUG
++#undef CONFIG_LOGLEVEL
++#define CONFIG_LOGLEVEL 8
++
++#include <common.h>
++#include <asm/global_data.h>
++#include <asm/io.h>
++#include <clk.h>
++#include <dm.h>
++#include <dm/device_compat.h>
++#include <i2c.h>
++#include <linux/io.h>
++#include <linux/compat.h>
++#include <linux/log2.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++
++// #define MICROCHIP_I2C_TIMEOUT (msecs_to_jiffies(1000))
++#define MICROCHIP_I2C_TIMEOUT (60)
++
++#define MPFS_I2C_CTRL (0x00)
++#define CTRL_CR0 (0x00)
++#define CTRL_CR1 (0x01)
++#define CTRL_AA (0x02)
++#define CTRL_SI (0x03)
++#define CTRL_STO (0x04)
++#define CTRL_STA (0x05)
++#define CTRL_ENS1 (0x06)
++#define CTRL_CR2 (0x07)
++#define MPFS_I2C_STATUS (0x04)
++#define STATUS_BUS_ERROR (0x00)
++#define STATUS_M_START_SENT (0x08)
++#define STATUS_M_REPEATED_START_SENT (0x10)
++#define STATUS_M_SLAW_ACK (0x18)
++#define STATUS_M_SLAW_NACK (0x20)
++#define STATUS_M_TX_DATA_ACK (0x28)
++#define STATUS_M_TX_DATA_NACK (0x30)
++#define STATUS_M_ARB_LOST (0x38)
++#define STATUS_M_SLAR_ACK (0x40)
++#define STATUS_M_SLAR_NACK (0x48)
++#define STATUS_M_RX_DATA_ACKED (0x50)
++#define STATUS_M_RX_DATA_NACKED (0x58)
++#define STATUS_S_SLAW_ACKED (0x60)
++#define STATUS_S_ARB_LOST_SLAW_ACKED (0x68)
++#define STATUS_S_GENERAL_CALL_ACKED (0x70)
++#define STATUS_S_ARB_LOST_GENERAL_CALL_ACKED (0x78)
++#define STATUS_S_RX_DATA_ACKED (0x80)
++#define STATUS_S_RX_DATA_NACKED (0x88)
++#define STATUS_S_GENERAL_CALL_RX_DATA_ACKED (0x90)
++#define STATUS_S_GENERAL_CALL_RX_DATA_NACKED (0x98)
++#define STATUS_S_RX_STOP (0xA0)
++#define STATUS_S_SLAR_ACKED (0xA8)
++#define STATUS_S_ARB_LOST_SLAR_ACKED (0xB0)
++#define STATUS_S_TX_DATA_ACK (0xb8)
++#define STATUS_S_TX_DATA_NACK (0xC0)
++#define STATUS_LAST_DATA_ACK (0xC8)
++#define STATUS_M_SMB_MASTER_RESET (0xD0)
++#define STATUS_S_SCL_LOW_TIMEOUT (0xD8) /* 25 ms */
++#define STATUS_NO_STATE_INFO (0xF8)
++#define MPFS_I2C_DATA (0x08)
++#define WRITE_BIT (0)
++#define READ_BIT BIT(0)
++#define SLAVE_ADDR_SHIFT (1)
++#define MPFS_I2C_SLAVE0_ADDR (0x0c)
++#define GENERAL_CALL_BIT BIT(0)
++#define MPFS_I2C_SMBUS (0x10)
++#define SMBALERT_INT_ENB (0)
++#define SMBSUS_INT_ENB (1)
++#define SMBUS_ENB (2)
++#define SMBALERT_NI_STATUS (3)
++#define SMBALERT_NO_CTRL (4)
++#define SMBSUS_NI_STATUS (5)
++#define SMBSUS_NO_CTRL (6)
++#define SMBUS_RESET (7)
++#define MPFS_I2C_FREQ (0x14)
++#define MPFS_I2C_GLITCHREG (0x18)
++#define MPFS_I2C_SLAVE1_ADDR (0x1c)
++
++#define PCLK_DIV_256 ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_224 ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_192 ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_160 ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_960 ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
++#define PCLK_DIV_120 ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
++#define PCLK_DIV_60 ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
++#define BCLK_DIV_8 ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
++#define CLK_MASK ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
++
++struct mpfs_i2c_bus
++{
++ void __iomem *base;
++ size_t msg_len;
++ int msg_err;
++ struct completion msg_complete;
++ struct device *dev;
++ // struct i2c_adapter adapter;
++ struct clk *i2c_clk;
++ u32 bus_clk_rate;
++ u8 *buf;
++ u8 addr;
++ u32 msg_read;
++ u32 isr_status;
++ // spinlock_t lock; /* IRQ synchronization */
++};
++
++static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
++{
++ return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
++}
++
++static void mpfs_i2c_int_clear(struct mpfs_i2c_bus *bus)
++{
++ u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
++
++ ctrl &= ~(1 << CTRL_SI);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++}
++
++static void mpfs_i2c_core_disable(struct mpfs_i2c_bus *bus)
++{
++ u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
++
++ ctrl &= ~(1 << CTRL_ENS1);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++}
++
++static void mpfs_i2c_core_enable(struct mpfs_i2c_bus *bus)
++{
++ u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
++
++ ctrl |= (1 << CTRL_ENS1);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++}
++
++static void mpfs_i2c_reset(struct mpfs_i2c_bus *bus)
++{
++ mpfs_i2c_core_disable(bus);
++ mpfs_i2c_core_enable(bus);
++}
++
++static inline void mpfs_i2c_stop(struct mpfs_i2c_bus *bus)
++{
++ u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
++
++ ctrl |= (1 << CTRL_STO);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++}
++
++static inline int mpfs_generate_divisor(u32 rate, u8 *code)
++{
++ int ret = 0;
++ if (rate >= 960)
++ *code = PCLK_DIV_960;
++ else if (rate >= 256)
++ *code = PCLK_DIV_256;
++ else if (rate >= 224)
++ *code = PCLK_DIV_224;
++ else if (rate >= 192)
++ *code = PCLK_DIV_192;
++ else if (rate >= 160)
++ *code = PCLK_DIV_160;
++ else if (rate >= 120)
++ *code = PCLK_DIV_120;
++ else if (rate >= 60)
++ *code = PCLK_DIV_60;
++ else if (rate >= 8)
++ *code = BCLK_DIV_8;
++ else
++ ret = -1;
++
++ return ret;
++}
++
++static int mpfs_i2c_init(struct mpfs_i2c_bus *bus, struct udevice *dev)
++{
++ u32 clk_rate;
++ int ret;
++
++ ret = clk_get_by_index(dev, 0, (struct clk *) &bus->i2c_clk);
++ if (ret)
++ return -EINVAL;
++
++ ret = clk_enable((struct clk *) &bus->i2c_clk);
++ if (ret)
++ return ret;
++
++ clk_rate = clk_get_rate((struct clk *) &bus->i2c_clk);
++ if (!clk_rate)
++ return -EINVAL;
++
++ clk_free((struct clk *) &bus->i2c_clk);
++
++ u32 divisor = clk_rate / bus->bus_clk_rate;
++ u8 clkval;
++ u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
++
++ ctrl &= ~CLK_MASK;
++
++ ret = mpfs_generate_divisor(divisor, &clkval);
++
++ if (ret)
++ return -1;
++
++ ctrl |= clkval;
++
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++
++ ctrl = readl(bus->base + MPFS_I2C_CTRL);
++
++ /* Reset controller */
++ mpfs_i2c_reset(bus);
++
++ return 0;
++}
++
++static void mpfs_i2c_transfer(struct mpfs_i2c_bus *bus, u32 data)
++{
++ if (bus->msg_len > 0)
++ writel(data, bus->base + MPFS_I2C_DATA);
++}
++
++static void mpfs_i2c_empty_rx(struct mpfs_i2c_bus *bus)
++{
++ u8 ctrl;
++ u8 test;
++
++ if (bus->msg_len > 0)
++ {
++ test= readl(bus->base + MPFS_I2C_DATA);
++ *bus->buf++ = test;
++ bus->msg_len--;
++
++ }
++
++ if (bus->msg_len == 0)
++ {
++ ctrl = readl(bus->base + MPFS_I2C_CTRL);
++ ctrl &= ~(1 << CTRL_AA);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++ }
++}
++
++static int mpfs_i2c_fill_tx(struct mpfs_i2c_bus *bus)
++{
++ mpfs_i2c_transfer(bus, *bus->buf++);
++ bus->msg_len--;
++
++ return 0;
++}
++
++static irqreturn_t mpfs_i2c_handle_isr(int irq, void *_dev)
++{
++ bool read, finish = false;
++ struct mpfs_i2c_bus *bus = _dev;
++ u32 status = bus->isr_status;
++ u8 ctrl;
++
++ if (!bus->buf)
++ {
++ dev_warn(bus->dev, "unexpected interrupt\n");
++ return IRQ_NONE;
++ }
++
++ read = bus->msg_read ? 1 : 0;
++
++ switch (status)
++ {
++ case STATUS_M_START_SENT:
++ case STATUS_M_REPEATED_START_SENT:
++ ctrl = readl(bus->base + MPFS_I2C_CTRL);
++ ctrl &= ~(1 << CTRL_STA);
++ writel(bus->addr, bus->base + MPFS_I2C_DATA);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++ if (bus->msg_len <= 0)
++ finish = true;
++ break;
++ case STATUS_M_ARB_LOST:
++ /* handle Lost Arbitration */
++ bus->msg_err = -EAGAIN;
++ finish = true;
++ break;
++ case STATUS_M_SLAW_ACK:
++ if (bus->msg_len > 0)
++ {
++ mpfs_i2c_fill_tx(bus);
++ }
++ else
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(bus);
++ finish = true;
++ }
++ break;
++ case STATUS_M_TX_DATA_NACK:
++ case STATUS_M_RX_DATA_NACKED:
++ case STATUS_M_SLAR_NACK:
++ case STATUS_M_SLAW_NACK:
++ bus->msg_err = -ENXIO;
++ mpfs_i2c_stop(bus);
++ finish = true;
++ break;
++ case STATUS_M_TX_DATA_ACK:
++ if (bus->msg_len > 0)
++ {
++ mpfs_i2c_fill_tx(bus);
++ }
++ else
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(bus);
++ finish = true;
++ }
++ break;
++ case STATUS_M_SLAR_ACK:
++ ctrl = readl(bus->base + MPFS_I2C_CTRL);
++ ctrl |= (1 << CTRL_AA);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++ if (bus->msg_len == 0)
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(bus);
++ finish = true;
++ }
++ break;
++ case STATUS_M_RX_DATA_ACKED:
++ mpfs_i2c_empty_rx(bus);
++ if (bus->msg_len == 0)
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(bus);
++ finish = true;
++ }
++ break;
++ default:
++ break;
++ }
++
++ if (finish)
++ {
++ ctrl = readl(bus->base + MPFS_I2C_CTRL);
++ ctrl &= ~(1 << CTRL_AA);
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++ // complete(&bus->msg_complete);
++ return IRQ_NONE;
++ }
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t mpfs_i2c_isr(int irq, void *_dev)
++{
++ struct mpfs_i2c_bus *bus = _dev;
++ irqreturn_t ret = IRQ_NONE;
++ int si_bit = 0;
++
++ si_bit = readl(bus->base + MPFS_I2C_CTRL);
++ if (si_bit & (1 << CTRL_SI))
++ {
++ bus->isr_status = readl(bus->base + MPFS_I2C_STATUS);
++ ret = mpfs_i2c_handle_isr(irq, bus);
++ }
++
++ // Clear the si flag
++ mpfs_i2c_int_clear(bus);
++ si_bit = readl(bus->base + MPFS_I2C_CTRL);
++
++ return ret;
++}
++
++static int mpfs_i2c_int_check(struct mpfs_i2c_bus *bus)
++{
++ u8 ctrl;
++ u32 count = 0;
++
++ while (1)
++ {
++ ctrl = readl(bus->base + MPFS_I2C_CTRL);
++ if (ctrl & (1 << CTRL_SI))
++ break;
++ udelay(1);
++ count += 1;
++ if (count == (1000 * 60))
++ return -ETIMEDOUT;
++ }
++ return 0;
++}
++
++static int mpfs_i2c_poll_device(struct mpfs_i2c_bus *bus)
++{
++ while (1)
++ {
++ irqreturn_t irq_ret;
++ int ret;
++
++ ret = mpfs_i2c_int_check(bus);
++ if (ret)
++ return ret;
++
++ irq_ret = mpfs_i2c_isr(-1, bus);
++ if (irq_ret == IRQ_NONE)
++ {
++ return 0; /* all messages have been transferred */
++ }
++ }
++}
++
++static int mpfs_i2c_xfer_msg(struct mpfs_i2c_bus *bus, struct i2c_msg *msg)
++{
++ u8 ctrl;
++ int ret;
++
++ if (msg->len == 0)
++ return -EINVAL;
++
++ bus->addr = i2c_8bit_addr_from_msg(msg);
++ bus->msg_len = msg->len;
++ bus->buf = msg->buf;
++ bus->msg_err = 0;
++ bus->msg_read = (msg->flags & I2C_M_RD);
++
++ mpfs_i2c_core_enable(bus);
++
++ ctrl = readl(bus->base + MPFS_I2C_CTRL);
++
++ ctrl |= (1 << CTRL_STA);
++
++ writel(ctrl, bus->base + MPFS_I2C_CTRL);
++
++ ret = mpfs_i2c_poll_device(bus);
++ if (ret)
++ {
++ return ret;
++ }
++ else
++ {
++ return bus->msg_err;
++ }
++}
++
++static int mpfs_i2c_xfer(struct udevice *dev, struct i2c_msg *msgs, int num)
++{
++ int i, ret;
++ struct mpfs_i2c_bus *bus = dev_get_priv(dev);
++
++ for (i = 0; i < num; i++)
++ {
++ ret = mpfs_i2c_xfer_msg(bus, msgs++);
++ if (ret)
++ return ret;
++ }
++
++ return num;
++}
++
++static int mpfs_i2c_probe(struct udevice *dev)
++{
++ struct mpfs_i2c_bus *bus = dev_get_priv(dev);
++ u32 val;
++ int ret;
++
++ bus->base = (void __iomem *)devfdt_get_addr(dev);
++
++ if (dev_read_u32(dev, "clock-frequency", &val))
++ {
++ bus->bus_clk_rate = 100000;
++ }
++ else
++ {
++ bus->bus_clk_rate = val;
++ }
++
++ init_completion(&bus->msg_complete);
++ ret = mpfs_i2c_init(bus, dev);
++ if (ret)
++ {
++ return ret;
++ }
++
++#ifdef DEBUG_PACTEST
++ u8 chip_rev_info[3];
++ u8 reg_addr = 0xfd;
++ struct i2c_msg msgs[2] = {
++ {.addr = 0x10, .len = 1, .buf = (u8 *)®_addr, .flags = 0},
++ {.addr = 0x10, .len = 3, .buf = (u8 *)chip_rev_info, .flags = I2C_M_RD}};
++ mpfs_i2c_xfer(dev, msgs, 2);
++ debug("i2c-mpfs: msg.buf:\n");
++ debug("i2c-mpfs: PID is 0x%x (pac1934 is 0x5b)\n", chip_rev_info[0]);
++ debug("i2c-mpfs: MID is 0x%x (MCHP is 0x5d)\n", chip_rev_info[1]);
++ debug("i2c-mpfs: chip revision is 0x%u\n", chip_rev_info[2]);
++#endif
++ return 0;
++}
++
++static const struct dm_i2c_ops mpfs_i2c_ops = {
++ .xfer = mpfs_i2c_xfer,
++// .set_bus_speed = mpfs_i2c_set_bus_speed,
++// .get_bus_speed = mpfs_i2c_get_bus_speed,
++};
++
++static const struct udevice_id mpfs_i2c_ids[] = {
++ {.compatible = "microchip,mpfs-mss-i2c"},
++};
++
++U_BOOT_DRIVER(mpfs_i2c) = {
++ .name = "mpfs_i2c",
++ .id = UCLASS_I2C,
++ .of_match = mpfs_i2c_ids,
++ .probe = mpfs_i2c_probe,
++ .priv_auto = sizeof(struct mpfs_i2c_bus),
++ .ops = &mpfs_i2c_ops,
++};
+\ No newline at end of file
+diff --git a/drivers/i2c/i2c-microsemi.c b/drivers/i2c/i2c-microsemi.c
+new file mode 100755
+index 0000000000..689389a52d
+--- /dev/null
++++ b/drivers/i2c/i2c-microsemi.c
+@@ -0,0 +1,537 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Microchip I2C controller driver
++ *
++ * Copyright (c) 2018 - 2021 Microchip Corporation. All rights reserved.
++ *
++ * Author: Daire McNamara <daire mcnamara microchip com>
++ */
++#include <linux/clk-provider.h>
++//#include <linux/clkdev.h>
++#include <linux/err.h>
++#include <i2c.h>
++#include <linux/iopoll.h>
++// #include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#define MICROCHIP_I2C_TIMEOUT (msecs_to_jiffies(1000))
++
++#define MPFS_I2C_CTRL (0x00)
++#define CTRL_CR0 (0x00)
++#define CTRL_CR1 (0x01)
++#define CTRL_AA (0x02)
++#define CTRL_SI (0x03)
++#define CTRL_STO (0x04)
++#define CTRL_STA (0x05)
++#define CTRL_ENS1 (0x06)
++#define CTRL_CR2 (0x07)
++#define MPFS_I2C_STATUS (0x04)
++#define STATUS_BUS_ERROR (0x00)
++#define STATUS_M_START_SENT (0x08)
++#define STATUS_M_REPEATED_START_SENT (0x10)
++#define STATUS_M_SLAW_ACK (0x18)
++#define STATUS_M_SLAW_NACK (0x20)
++#define STATUS_M_TX_DATA_ACK (0x28)
++#define STATUS_M_TX_DATA_NACK (0x30)
++#define STATUS_M_ARB_LOST (0x38)
++#define STATUS_M_SLAR_ACK (0x40)
++#define STATUS_M_SLAR_NACK (0x48)
++#define STATUS_M_RX_DATA_ACKED (0x50)
++#define STATUS_M_RX_DATA_NACKED (0x58)
++#define STATUS_S_SLAW_ACKED (0x60)
++#define STATUS_S_ARB_LOST_SLAW_ACKED (0x68)
++#define STATUS_S_GENERAL_CALL_ACKED (0x70)
++#define STATUS_S_ARB_LOST_GENERAL_CALL_ACKED (0x78)
++#define STATUS_S_RX_DATA_ACKED (0x80)
++#define STATUS_S_RX_DATA_NACKED (0x88)
++#define STATUS_S_GENERAL_CALL_RX_DATA_ACKED (0x90)
++#define STATUS_S_GENERAL_CALL_RX_DATA_NACKED (0x98)
++#define STATUS_S_RX_STOP (0xA0)
++#define STATUS_S_SLAR_ACKED (0xA8)
++#define STATUS_S_ARB_LOST_SLAR_ACKED (0xB0)
++#define STATUS_S_TX_DATA_ACK (0xb8)
++#define STATUS_S_TX_DATA_NACK (0xC0)
++#define STATUS_LAST_DATA_ACK (0xC8)
++#define STATUS_M_SMB_MASTER_RESET (0xD0)
++#define STATUS_S_SCL_LOW_TIMEOUT (0xD8) /* 25 ms */
++#define STATUS_NO_STATE_INFO (0xF8)
++#define MPFS_I2C_DATA (0x08)
++#define WRITE_BIT (0)
++#define READ_BIT BIT(0)
++#define SLAVE_ADDR_SHIFT (1)
++#define MPFS_I2C_SLAVE0_ADDR (0x0c)
++#define GENERAL_CALL_BIT BIT(0)
++#define MPFS_I2C_SMBUS (0x10)
++#define SMBALERT_INT_ENB (0)
++#define SMBSUS_INT_ENB (1)
++#define SMBUS_ENB (2)
++#define SMBALERT_NI_STATUS (3)
++#define SMBALERT_NO_CTRL (4)
++#define SMBSUS_NI_STATUS (5)
++#define SMBSUS_NO_CTRL (6)
++#define SMBUS_RESET (7)
++#define MPFS_I2C_FREQ (0x14)
++#define MPFS_I2C_GLITCHREG (0x18)
++#define MPFS_I2C_SLAVE1_ADDR (0x1c)
++
++#define PCLK_DIV_256 ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_224 ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_192 ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_160 ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
++#define PCLK_DIV_960 ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
++#define PCLK_DIV_120 ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
++#define PCLK_DIV_60 ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
++#define BCLK_DIV_8 ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
++#define CLK_MASK ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
++
++/*
++ * mpfs_i2c_dev - I2C device context
++ * @base: pointer to register struct
++ * @msg: pointer to current message
++ * @msg_len: number of bytes transferred in msg
++ * @msg_err: error code for completed message
++ * @msg_complete: xfer completion object
++ * @dev: device reference
++ * @adapter: core i2c abstraction
++ * @i2c_clk: clock reference for i2c input clock
++ * @bus_clk_rate: current i2c bus clock rate
++ * @buf: ptr to msg buffer for easier use.
++ * @isr_status: cached copy of local ISR status.
++ * @lock: spinlock for IRQ synchronization.
++ */
++struct mpfs_i2c_dev
++{
++ void __iomem *base;
++ size_t msg_len;
++ int msg_err;
++ struct completion msg_complete;
++ struct device *dev;
++ struct i2c_adapter adapter;
++ struct clk *i2c_clk;
++ u32 bus_clk_rate;
++ u8 *buf;
++ u8 addr;
++ u32 msg_read;
++ u32 isr_status;
++ spinlock_t lock; /* IRQ synchronization */
++};
++
++static void mpfs_i2c_int_clear(struct mpfs_i2c_dev *idev)
++{
++ u8 ctrl = readl(idev->base + MPFS_I2C_CTRL);
++
++ ctrl &= ~(1 << CTRL_SI);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++}
++
++static void mpfs_i2c_core_disable(struct mpfs_i2c_dev *idev)
++{
++ u8 ctrl = readl(idev->base + MPFS_I2C_CTRL);
++
++ ctrl &= ~(1 << CTRL_ENS1);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++}
++
++static void mpfs_i2c_core_enable(struct mpfs_i2c_dev *idev)
++{
++ u8 ctrl = readl(idev->base + MPFS_I2C_CTRL);
++
++ ctrl |= (1 << CTRL_ENS1);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++}
++
++static void mpfs_i2c_reset(struct mpfs_i2c_dev *idev)
++{
++ mpfs_i2c_core_disable(idev);
++ mpfs_i2c_core_enable(idev);
++}
++
++static inline void mpfs_i2c_stop(struct mpfs_i2c_dev *idev)
++{
++ u8 ctrl = readl(idev->base + MPFS_I2C_CTRL);
++
++ ctrl |= (1 << CTRL_STO);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++}
++
++static inline int mpfs_generate_divisor(u32 rate, u8 *code)
++{
++ int ret = 0;
++
++ if (rate >= 960)
++ *code = PCLK_DIV_960;
++ else if (rate >= 256)
++ *code = PCLK_DIV_256;
++ else if (rate >= 224)
++ *code = PCLK_DIV_224;
++ else if (rate >= 192)
++ *code = PCLK_DIV_192;
++ else if (rate >= 160)
++ *code = PCLK_DIV_160;
++ else if (rate >= 120)
++ *code = PCLK_DIV_120;
++ else if (rate >= 60)
++ *code = PCLK_DIV_60;
++ else if (rate >= 8)
++ *code = BCLK_DIV_8;
++ else
++ ret = -1;
++
++ return ret;
++}
++
++static int mpfs_i2c_init(struct mpfs_i2c_dev *idev)
++{
++ u32 clk_rate = clk_get_rate(idev->i2c_clk);
++ u32 divisor = clk_rate / idev->bus_clk_rate;
++ u8 clkval;
++ int ret;
++ u8 ctrl = readl(idev->base + MPFS_I2C_CTRL);
++
++ ctrl &= ~CLK_MASK;
++
++ ret = mpfs_generate_divisor(divisor, &clkval);
++
++ if (ret)
++ return -1;
++
++ ctrl |= clkval;
++
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++
++ ctrl = readl(idev->base + MPFS_I2C_CTRL);
++
++ /* Reset controller */
++ mpfs_i2c_reset(idev);
++
++ return 0;
++}
++
++static void mpfs_i2c_transfer(struct mpfs_i2c_dev *idev, u32 data)
++{
++ if (idev->msg_len > 0)
++ writel(data, idev->base + MPFS_I2C_DATA);
++}
++
++static void mpfs_i2c_empty_rx(struct mpfs_i2c_dev *idev)
++{
++ u8 ctrl;
++
++ if (idev->msg_len > 0)
++ {
++ *idev->buf++ = readl(idev->base + MPFS_I2C_DATA);
++ idev->msg_len--;
++ }
++
++ if (idev->msg_len == 0)
++ {
++ ctrl = readl(idev->base + MPFS_I2C_CTRL);
++ ctrl &= ~(1 << CTRL_AA);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++ }
++}
++
++static int mpfs_i2c_fill_tx(struct mpfs_i2c_dev *idev)
++{
++ mpfs_i2c_transfer(idev, *idev->buf++);
++ idev->msg_len--;
++
++ return 0;
++}
++
++static irqreturn_t mpfs_i2c_handle_isr(int irq, void *_dev)
++{
++ bool read, finish = false;
++ struct mpfs_i2c_dev *idev = _dev;
++ u32 status = idev->isr_status;
++ u8 ctrl;
++
++ if (!idev->buf)
++ {
++ dev_warn(idev->dev, "unexpected interrupt\n");
++ return IRQ_HANDLED;
++ }
++
++ read = idev->msg_read ? 1 : 0;
++
++ switch (status)
++ {
++ case STATUS_M_START_SENT:
++ case STATUS_M_REPEATED_START_SENT:
++ ctrl = readl(idev->base + MPFS_I2C_CTRL);
++ ctrl &= ~(1 << CTRL_STA);
++ writel(idev->addr, idev->base + MPFS_I2C_DATA);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++ if (idev->msg_len <= 0)
++ finish = true;
++ break;
++ case STATUS_M_ARB_LOST:
++ /* handle Lost Arbitration */
++ idev->msg_err = -EAGAIN;
++ finish = true;
++ break;
++ case STATUS_M_SLAW_ACK:
++ if (idev->msg_len > 0)
++ {
++ mpfs_i2c_fill_tx(idev);
++ }
++ else
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(idev);
++ finish = true;
++ }
++ break;
++ case STATUS_M_TX_DATA_NACK:
++ case STATUS_M_RX_DATA_NACKED:
++ case STATUS_M_SLAR_NACK:
++ case STATUS_M_SLAW_NACK:
++ idev->msg_err = -ENXIO;
++ mpfs_i2c_stop(idev);
++ finish = true;
++ break;
++ case STATUS_M_TX_DATA_ACK:
++ if (idev->msg_len > 0)
++ {
++ mpfs_i2c_fill_tx(idev);
++ }
++ else
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(idev);
++ finish = true;
++ }
++ break;
++ case STATUS_M_SLAR_ACK:
++ ctrl = readl(idev->base + MPFS_I2C_CTRL);
++ ctrl |= (1 << CTRL_AA);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++ if (idev->msg_len == 0)
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(idev);
++ finish = true;
++ }
++ break;
++ case STATUS_M_RX_DATA_ACKED:
++ mpfs_i2c_empty_rx(idev);
++ if (idev->msg_len == 0)
++ {
++ /* On the last byte to be transmitted, send STOP */
++ mpfs_i2c_stop(idev);
++ finish = true;
++ }
++ break;
++ default:
++ break;
++ }
++
++ if (finish)
++ {
++ ctrl = readl(idev->base + MPFS_I2C_CTRL);
++ ctrl &= ~(1 << CTRL_AA);
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++ complete(&idev->msg_complete);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t mpfs_i2c_isr(int irq, void *_dev)
++{
++ struct mpfs_i2c_dev *idev = _dev;
++ irqreturn_t ret = IRQ_NONE;
++ int si_bit = 0;
++
++ si_bit = readl(idev->base + MPFS_I2C_CTRL);
++ if (si_bit & (1 << CTRL_SI))
++ {
++ idev->isr_status = readl(idev->base + MPFS_I2C_STATUS);
++ ret = mpfs_i2c_handle_isr(irq, idev);
++ }
++
++ // Clear the si flag
++ mpfs_i2c_int_clear(idev);
++
++ return ret;
++}
++
++static int mpfs_i2c_xfer_msg(struct mpfs_i2c_dev *idev, struct i2c_msg *msg)
++{
++ u8 ctrl;
++ unsigned long time_left;
++
++ if (msg->len == 0)
++ return -EINVAL;
++
++ idev->addr = i2c_8bit_addr_from_msg(msg);
++ idev->msg_len = msg->len;
++ idev->buf = msg->buf;
++ idev->msg_err = 0;
++ idev->msg_read = (msg->flags & I2C_M_RD);
++
++ reinit_completion(&idev->msg_complete);
++
++ mpfs_i2c_core_enable(idev);
++
++ ctrl = readl(idev->base + MPFS_I2C_CTRL);
++
++ ctrl |= (1 << CTRL_STA);
++
++ writel(ctrl, idev->base + MPFS_I2C_CTRL);
++
++ time_left = wait_for_completion_timeout(&idev->msg_complete,
++ MICROCHIP_I2C_TIMEOUT);
++
++ if (time_left == 0)
++ return -ETIMEDOUT;
++
++ return idev->msg_err;
++}
++
++static int mpfs_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
++{
++ struct mpfs_i2c_dev *idev = i2c_get_adapdata(adap);
++ int i, ret;
++
++ for (i = 0; i < num; i++)
++ {
++ ret = mpfs_i2c_xfer_msg(idev, msgs++);
++ if (ret)
++ return ret;
++ }
++
++ return num;
++}
++
++static u32 mpfs_i2c_func(struct i2c_adapter *adap)
++{
++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
++}
++
++static const struct i2c_algorithm mpfs_i2c_algo = {
++ .master_xfer = mpfs_i2c_xfer,
++ .functionality = mpfs_i2c_func,
++};
++
++static int mpfs_i2c_probe(struct platform_device *pdev)
++{
++ struct mpfs_i2c_dev *idev = NULL;
++ struct resource *res;
++ int irq, ret;
++ u32 val;
++
++ idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
++ if (!idev)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ idev->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(idev->base))
++ return PTR_ERR(idev->base);
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ {
++ dev_err(&pdev->dev, "missing interrupt resource\n");
++ return irq;
++ }
++
++ idev->i2c_clk = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(idev->i2c_clk))
++ {
++ dev_err(&pdev->dev, "missing clock\n");
++ return PTR_ERR(idev->i2c_clk);
++ }
++
++ idev->dev = &pdev->dev;
++ init_completion(&idev->msg_complete);
++ spin_lock_init(&idev->lock);
++
++ val = device_property_read_u32(idev->dev, "clock-frequency",
++ &idev->bus_clk_rate);
++ if (val)
++ {
++ dev_info(&pdev->dev, "default to 100kHz\n");
++ idev->bus_clk_rate = 100000; /* default clock rate */
++ }
++
++ if (idev->bus_clk_rate > 400000)
++ {
++ dev_err(&pdev->dev, "invalid clock-frequency %d\n",
++ idev->bus_clk_rate);
++ return -EINVAL;
++ }
++
++ ret = devm_request_irq(&pdev->dev, irq, mpfs_i2c_isr,
++ IRQF_SHARED, pdev->name, idev);
++ if (ret)
++ {
++ dev_err(&pdev->dev, "failed to claim irq %d\n", irq);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(idev->i2c_clk);
++ if (ret)
++ {
++ dev_err(&pdev->dev, "failed to enable clock\n");
++ return ret;
++ }
++
++ ret = mpfs_i2c_init(idev);
++ if (ret)
++ {
++ dev_err(&pdev->dev, "failed to program clock divider\n");
++ return ret;
++ }
++
++ i2c_set_adapdata(&idev->adapter, idev);
++ snprintf(idev->adapter.name, sizeof(idev->adapter.name),
++ "Microchip I2C hw bus");
++ idev->adapter.owner = THIS_MODULE;
++ idev->adapter.algo = &mpfs_i2c_algo;
++ idev->adapter.dev.parent = &pdev->dev;
++ idev->adapter.dev.of_node = pdev->dev.of_node;
++
++ platform_set_drvdata(pdev, idev);
++
++ ret = i2c_add_adapter(&idev->adapter);
++ if (ret)
++ {
++ clk_disable_unprepare(idev->i2c_clk);
++ return ret;
++ }
++
++ dev_info(&pdev->dev, "Microchip I2C Probe Complete\n");
++
++ return 0;
++}
++
++static int mpfs_i2c_remove(struct platform_device *pdev)
++{
++ struct mpfs_i2c_dev *idev = platform_get_drvdata(pdev);
++
++ clk_disable_unprepare(idev->i2c_clk);
++ i2c_del_adapter(&idev->adapter);
++
++ return 0;
++}
++
++/* Match table for of_platform binding */
++static const struct of_device_id mpfs_i2c_of_match[] = {
++ {.compatible = "microchip,mpfs-i2c"},
++ {},
++};
++
++U_BOOT_DRIVER(microchip_mpfs_i2c) = {
++ .name = "microchip-mpfs-i2c",
++ .id = UCLASS_I2C,
++ .of_match = mpfs_i2c_of_match,
++ .of_to_plat = iproc_i2c_of_to_plat,
++ .probe = mpfs_i2c_probe,
++ .remove = mpfs_i2c_remove,
++ .priv_auto = sizeof(struct mpfs_i2c_dev),
++ .ops = &mpfs_i2c_algo,
++};
+diff --git a/include/configs/microchip_mpfs_icicle.h b/include/configs/microchip_mpfs_icicle.h
+index 24990370cf..17f7358ffe 100644
+--- a/include/configs/microchip_mpfs_icicle.h
++++ b/include/configs/microchip_mpfs_icicle.h
+@@ -18,6 +18,8 @@
+
+ #define CONFIG_SYS_BOOTM_LEN SZ_64M
+
++#define CONFIG_SYS_I2C_SPEED 100000
++
+ #define CONFIG_STANDALONE_LOAD_ADDR 0x80200000
+
+ /* Environment options */
+--
+2.31.1
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]