summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/compulab/imx8mm-cl-iot-gate/Makefile2
-rw-r--r--board/compulab/imx8mm-cl-iot-gate/eeprom_spl.c130
2 files changed, 131 insertions, 1 deletions
diff --git a/board/compulab/imx8mm-cl-iot-gate/Makefile b/board/compulab/imx8mm-cl-iot-gate/Makefile
index 3a2bfc4dc4..3800b21a6f 100644
--- a/board/compulab/imx8mm-cl-iot-gate/Makefile
+++ b/board/compulab/imx8mm-cl-iot-gate/Makefile
@@ -8,6 +8,6 @@
obj-y += imx8mm-cl-iot-gate.o
ifdef CONFIG_SPL_BUILD
-obj-y += spl.o
+obj-y += spl.o eeprom_spl.o
obj-y += ddr/
endif
diff --git a/board/compulab/imx8mm-cl-iot-gate/eeprom_spl.c b/board/compulab/imx8mm-cl-iot-gate/eeprom_spl.c
new file mode 100644
index 0000000000..ee6d2bb001
--- /dev/null
+++ b/board/compulab/imx8mm-cl-iot-gate/eeprom_spl.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* (C) Copyright 2019 CompuLab, Ltd. <www.compulab.co.il> */
+
+#include <common.h>
+#include <i2c.h>
+#include <linux/kernel.h>
+#include <asm/arch/imx8mq_pins.h>
+#include <asm/mach-imx/gpio.h>
+#include <asm-generic/gpio.h>
+#include <asm/setup.h>
+#include <linux/delay.h>
+
+#ifdef CONFIG_SPL_BUILD
+
+#define CONFIG_SYS_I2C_EEPROM_ADDR_P1 0x51
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
+
+static iomux_v3_cfg_t const eeprom_pads[] = {
+ IMX8MQ_PAD_GPIO1_IO13__GPIO1_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+#define EEPROM_WP_GPIO IMX_GPIO_NR(1, 13)
+
+static void cl_eeprom_we(int enable)
+{
+ static int done;
+
+ if (done) {
+ gpio_direction_output(EEPROM_WP_GPIO, enable);
+ return;
+ }
+
+ imx_iomux_v3_setup_multiple_pads(eeprom_pads, ARRAY_SIZE(eeprom_pads));
+ gpio_request(EEPROM_WP_GPIO, "eeprom_wp");
+ gpio_direction_output(EEPROM_WP_GPIO, enable);
+ done = 1;
+}
+
+static int cl_eeprom_read(uint offset, uchar *buf, int len)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = i2c_get_chip_for_busnum(1, CONFIG_SYS_I2C_EEPROM_ADDR_P1,
+ CONFIG_SYS_I2C_EEPROM_ADDR_LEN, &dev);
+ if (ret) {
+ printf("%s: Cannot find EEPROM: %d\n", __func__, ret);
+ return ret;
+ }
+
+ return dm_i2c_read(dev, offset, buf, len);
+}
+
+static int cl_eeprom_write(uint offset, uchar *buf, int len)
+{
+ struct udevice *dev;
+ int ret;
+
+ cl_eeprom_we(1);
+
+ ret = i2c_get_chip_for_busnum(1, CONFIG_SYS_I2C_EEPROM_ADDR_P1,
+ CONFIG_SYS_I2C_EEPROM_ADDR_LEN, &dev);
+ if (ret) {
+ printf("%s: Cannot find EEPROM: %d\n", __func__, ret);
+ return ret;
+ }
+
+ return dm_i2c_write(dev, offset, buf, len);
+}
+
+/* Reserved for fututre use area */
+#define BOARD_DDRINFO_OFFSET 0x40
+#define BOARD_DDR_SIZE 4
+static u32 board_ddrinfo = 0xdeadbeef;
+
+#define BOARD_DDRSUBIND_OFFSET 0x44
+#define BOARD_DDRSUBIND_SIZE 1
+static u8 board_ddrsubind = 0xff;
+
+#define BOARD_OSIZE_OFFSET 0x80
+#define BOARD_OSIZE_SIZE 4
+static u32 board_osize = 0xdeadbeef;
+
+#define BOARD_DDRINFO_VALID(A) ((A) != 0xdeadbeef)
+
+u32 cl_eeprom_get_ddrinfo(void)
+{
+ if (!BOARD_DDRINFO_VALID(board_ddrinfo)) {
+ if (cl_eeprom_read(BOARD_DDRINFO_OFFSET, (uchar *)&board_ddrinfo, BOARD_DDR_SIZE))
+ return 0;
+ }
+ return board_ddrinfo;
+};
+
+u32 cl_eeprom_set_ddrinfo(u32 ddrinfo)
+{
+ if (cl_eeprom_write(BOARD_DDRINFO_OFFSET, (uchar *)&ddrinfo, BOARD_DDR_SIZE))
+ return 0;
+
+ board_ddrinfo = ddrinfo;
+
+ return board_ddrinfo;
+};
+
+u8 cl_eeprom_get_subind(void)
+{
+ if (cl_eeprom_read(BOARD_DDRSUBIND_OFFSET, (uchar *)&board_ddrsubind, BOARD_DDRSUBIND_SIZE))
+ return 0xff;
+
+ return board_ddrsubind;
+};
+
+u8 cl_eeprom_set_subind(u8 ddrsubind)
+{
+ if (cl_eeprom_write(BOARD_DDRSUBIND_OFFSET, (uchar *)&ddrsubind, BOARD_DDRSUBIND_SIZE))
+ return 0xff;
+ board_ddrsubind = ddrsubind;
+
+ return board_ddrsubind;
+};
+
+/* override-size ifaces */
+u32 cl_eeprom_get_osize(void)
+{
+ if (cl_eeprom_read(BOARD_OSIZE_OFFSET, (uchar *)&board_osize, BOARD_OSIZE_SIZE))
+ return 0;
+
+ return board_osize;
+};
+#endif