blob: ee6d2bb0016ac9aa2b5bfebf09f509d8c6a7bb5e [file] [log] [blame]
Fabio Estevamd2692092022-04-12 13:05:35 -03001// SPDX-License-Identifier: GPL-2.0+
2/* (C) Copyright 2019 CompuLab, Ltd. <www.compulab.co.il> */
3
4#include <common.h>
5#include <i2c.h>
6#include <linux/kernel.h>
7#include <asm/arch/imx8mq_pins.h>
8#include <asm/mach-imx/gpio.h>
9#include <asm-generic/gpio.h>
10#include <asm/setup.h>
11#include <linux/delay.h>
12
13#ifdef CONFIG_SPL_BUILD
14
15#define CONFIG_SYS_I2C_EEPROM_ADDR_P1 0x51
16#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
17
18static iomux_v3_cfg_t const eeprom_pads[] = {
19 IMX8MQ_PAD_GPIO1_IO13__GPIO1_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
20};
21
22#define EEPROM_WP_GPIO IMX_GPIO_NR(1, 13)
23
24static void cl_eeprom_we(int enable)
25{
26 static int done;
27
28 if (done) {
29 gpio_direction_output(EEPROM_WP_GPIO, enable);
30 return;
31 }
32
33 imx_iomux_v3_setup_multiple_pads(eeprom_pads, ARRAY_SIZE(eeprom_pads));
34 gpio_request(EEPROM_WP_GPIO, "eeprom_wp");
35 gpio_direction_output(EEPROM_WP_GPIO, enable);
36 done = 1;
37}
38
39static int cl_eeprom_read(uint offset, uchar *buf, int len)
40{
41 struct udevice *dev;
42 int ret;
43
44 ret = i2c_get_chip_for_busnum(1, CONFIG_SYS_I2C_EEPROM_ADDR_P1,
45 CONFIG_SYS_I2C_EEPROM_ADDR_LEN, &dev);
46 if (ret) {
47 printf("%s: Cannot find EEPROM: %d\n", __func__, ret);
48 return ret;
49 }
50
51 return dm_i2c_read(dev, offset, buf, len);
52}
53
54static int cl_eeprom_write(uint offset, uchar *buf, int len)
55{
56 struct udevice *dev;
57 int ret;
58
59 cl_eeprom_we(1);
60
61 ret = i2c_get_chip_for_busnum(1, CONFIG_SYS_I2C_EEPROM_ADDR_P1,
62 CONFIG_SYS_I2C_EEPROM_ADDR_LEN, &dev);
63 if (ret) {
64 printf("%s: Cannot find EEPROM: %d\n", __func__, ret);
65 return ret;
66 }
67
68 return dm_i2c_write(dev, offset, buf, len);
69}
70
71/* Reserved for fututre use area */
72#define BOARD_DDRINFO_OFFSET 0x40
73#define BOARD_DDR_SIZE 4
74static u32 board_ddrinfo = 0xdeadbeef;
75
76#define BOARD_DDRSUBIND_OFFSET 0x44
77#define BOARD_DDRSUBIND_SIZE 1
78static u8 board_ddrsubind = 0xff;
79
80#define BOARD_OSIZE_OFFSET 0x80
81#define BOARD_OSIZE_SIZE 4
82static u32 board_osize = 0xdeadbeef;
83
84#define BOARD_DDRINFO_VALID(A) ((A) != 0xdeadbeef)
85
86u32 cl_eeprom_get_ddrinfo(void)
87{
88 if (!BOARD_DDRINFO_VALID(board_ddrinfo)) {
89 if (cl_eeprom_read(BOARD_DDRINFO_OFFSET, (uchar *)&board_ddrinfo, BOARD_DDR_SIZE))
90 return 0;
91 }
92 return board_ddrinfo;
93};
94
95u32 cl_eeprom_set_ddrinfo(u32 ddrinfo)
96{
97 if (cl_eeprom_write(BOARD_DDRINFO_OFFSET, (uchar *)&ddrinfo, BOARD_DDR_SIZE))
98 return 0;
99
100 board_ddrinfo = ddrinfo;
101
102 return board_ddrinfo;
103};
104
105u8 cl_eeprom_get_subind(void)
106{
107 if (cl_eeprom_read(BOARD_DDRSUBIND_OFFSET, (uchar *)&board_ddrsubind, BOARD_DDRSUBIND_SIZE))
108 return 0xff;
109
110 return board_ddrsubind;
111};
112
113u8 cl_eeprom_set_subind(u8 ddrsubind)
114{
115 if (cl_eeprom_write(BOARD_DDRSUBIND_OFFSET, (uchar *)&ddrsubind, BOARD_DDRSUBIND_SIZE))
116 return 0xff;
117 board_ddrsubind = ddrsubind;
118
119 return board_ddrsubind;
120};
121
122/* override-size ifaces */
123u32 cl_eeprom_get_osize(void)
124{
125 if (cl_eeprom_read(BOARD_OSIZE_OFFSET, (uchar *)&board_osize, BOARD_OSIZE_SIZE))
126 return 0;
127
128 return board_osize;
129};
130#endif