[gnome-build-meta/jjardon/robjh/icicle: 2/4] Add u-boot for the icicle boards.




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 *)&reg_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]