board: stm32mp1: gt9147 IRQ before reset on EV1
[oweals/u-boot.git] / board / corscience / tricorder / tricorder-eeprom.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2013
4  * Corscience GmbH & Co. KG, <www.corscience.de>
5  * Andreas Bießmann <andreas.biessmann@corscience.de>
6  */
7 #include <common.h>
8 #include <eeprom.h>
9 #include <i2c.h>
10 #include <u-boot/crc.h>
11
12 #include "tricorder-eeprom.h"
13
14 static inline void warn_wrong_value(const char *msg, unsigned int a,
15                 unsigned int b)
16 {
17         printf("Expected EEPROM %s %08x, got %08x\n", msg, a, b);
18 }
19
20 static int handle_eeprom_v0(struct tricorder_eeprom *eeprom)
21 {
22         struct tricorder_eeprom_v0 {
23                 uint32_t magic;
24                 uint16_t length;
25                 uint16_t version;
26                 char board_name[TRICORDER_BOARD_NAME_LENGTH];
27                 char board_version[TRICORDER_BOARD_VERSION_LENGTH];
28                 char board_serial[TRICORDER_BOARD_SERIAL_LENGTH];
29                 uint32_t crc32;
30         } __packed eepromv0;
31         uint32_t crc;
32
33         printf("Old EEPROM (v0), consider rewrite!\n");
34
35         if (be16_to_cpu(eeprom->length) != sizeof(eepromv0)) {
36                 warn_wrong_value("length", sizeof(eepromv0),
37                                  be16_to_cpu(eeprom->length));
38                 return 1;
39         }
40
41         memcpy(&eepromv0, eeprom, sizeof(eepromv0));
42
43         crc = crc32(0L, (unsigned char *)&eepromv0,
44                     sizeof(eepromv0) - sizeof(eepromv0.crc32));
45         if (be32_to_cpu(eepromv0.crc32) != crc) {
46                 warn_wrong_value("CRC", be32_to_cpu(eepromv0.crc32),
47                                  crc);
48                 return 1;
49         }
50
51         /* Ok the content is correct, do the conversion */
52         memset(eeprom->interface_version, 0x0,
53                TRICORDER_INTERFACE_VERSION_LENGTH);
54         crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
55         eeprom->crc32 = cpu_to_be32(crc);
56
57         return 0;
58 }
59
60 static int handle_eeprom_v1(struct tricorder_eeprom *eeprom)
61 {
62         uint32_t crc;
63
64         if (be16_to_cpu(eeprom->length) != TRICORDER_EEPROM_SIZE) {
65                 warn_wrong_value("length", TRICORDER_EEPROM_SIZE,
66                                  be16_to_cpu(eeprom->length));
67                 return 1;
68         }
69
70         crc = crc32(0L, (unsigned char *)eeprom, TRICORDER_EEPROM_CRC_SIZE);
71         if (be32_to_cpu(eeprom->crc32) != crc) {
72                 warn_wrong_value("CRC", be32_to_cpu(eeprom->crc32), crc);
73                 return 1;
74         }
75
76         return 0;
77 }
78
79 int tricorder_get_eeprom(int addr, struct tricorder_eeprom *eeprom)
80 {
81         unsigned int bus = i2c_get_bus_num();
82         i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
83
84         memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
85
86         i2c_read(addr, 0, 2, (unsigned char *)eeprom, TRICORDER_EEPROM_SIZE);
87         i2c_set_bus_num(bus);
88
89         if (be32_to_cpu(eeprom->magic) != TRICORDER_EEPROM_MAGIC) {
90                 warn_wrong_value("magic", TRICORDER_EEPROM_MAGIC,
91                                  be32_to_cpu(eeprom->magic));
92                 return 1;
93         }
94
95         switch (be16_to_cpu(eeprom->version)) {
96         case 0:
97                 return handle_eeprom_v0(eeprom);
98         case 1:
99                 return handle_eeprom_v1(eeprom);
100         default:
101                 warn_wrong_value("version", TRICORDER_EEPROM_VERSION,
102                                  be16_to_cpu(eeprom->version));
103                 return 1;
104         }
105 }
106
107 #if !defined(CONFIG_SPL)
108 int tricorder_eeprom_read(unsigned devaddr)
109 {
110         struct tricorder_eeprom eeprom;
111         int ret = tricorder_get_eeprom(devaddr, &eeprom);
112
113         if (ret)
114                 return ret;
115
116         printf("Board type:               %.*s\n",
117                sizeof(eeprom.board_name), eeprom.board_name);
118         printf("Board version:            %.*s\n",
119                sizeof(eeprom.board_version), eeprom.board_version);
120         printf("Board serial:             %.*s\n",
121                sizeof(eeprom.board_serial), eeprom.board_serial);
122         printf("Board interface version:  %.*s\n",
123                sizeof(eeprom.interface_version),
124                eeprom.interface_version);
125
126         return ret;
127 }
128
129 int tricorder_eeprom_write(unsigned devaddr, const char *name,
130                 const char *version, const char *serial, const char *interface)
131 {
132         struct tricorder_eeprom eeprom, eeprom_verify;
133         size_t length;
134         uint32_t crc;
135         int ret;
136         unsigned char *p;
137         int i;
138
139         memset(eeprom, 0, TRICORDER_EEPROM_SIZE);
140         memset(eeprom_verify, 0, TRICORDER_EEPROM_SIZE);
141
142         eeprom.magic = cpu_to_be32(TRICORDER_EEPROM_MAGIC);
143         eeprom.length = cpu_to_be16(TRICORDER_EEPROM_SIZE);
144         eeprom.version = cpu_to_be16(TRICORDER_EEPROM_VERSION);
145
146         length = min(sizeof(eeprom.board_name), strlen(name));
147         strncpy(eeprom.board_name, name, length);
148
149         length = min(sizeof(eeprom.board_version), strlen(version));
150         strncpy(eeprom.board_version, version, length);
151
152         length = min(sizeof(eeprom.board_serial), strlen(serial));
153         strncpy(eeprom.board_serial, serial, length);
154
155         if (interface) {
156                 length = min(sizeof(eeprom.interface_version),
157                                 strlen(interface));
158                 strncpy(eeprom.interface_version, interface, length);
159         }
160
161         crc = crc32(0L, (unsigned char *)&eeprom, TRICORDER_EEPROM_CRC_SIZE);
162         eeprom.crc32 = cpu_to_be32(crc);
163
164 #if defined(DEBUG)
165         puts("Tricorder EEPROM content:\n");
166         print_buffer(0, &eeprom, 1, sizeof(eeprom), 16);
167 #endif
168
169         eeprom_init(CONFIG_SYS_EEPROM_BUS_NUM);
170
171         ret = eeprom_write(devaddr, 0, (unsigned char *)&eeprom,
172                         TRICORDER_EEPROM_SIZE);
173         if (ret)
174                 printf("Tricorder: Could not write EEPROM content!\n");
175
176         ret = eeprom_read(devaddr, 0, (unsigned char *)&eeprom_verify,
177                         TRICORDER_EEPROM_SIZE);
178         if (ret)
179                 printf("Tricorder: Could not read EEPROM content!\n");
180
181         if (memcmp(&eeprom, &eeprom_verify, sizeof(eeprom)) != 0) {
182                 printf("Tricorder: Could not verify EEPROM content!\n");
183                 ret = 1;
184         }
185
186         return ret;
187 }
188
189 int do_tricorder_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
190 {
191         if (argc == 3) {
192                 ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
193
194                 if (strcmp(argv[1], "read") == 0)
195                         return tricorder_eeprom_read(dev_addr);
196         } else if (argc == 6 || argc == 7) {
197                 ulong dev_addr = simple_strtoul(argv[2], NULL, 16);
198                 char *name = argv[3];
199                 char *version = argv[4];
200                 char *serial = argv[5];
201                 char *interface = NULL;
202
203                 if (argc == 7)
204                         interface = argv[6];
205
206                 if (strcmp(argv[1], "write") == 0)
207                         return tricorder_eeprom_write(dev_addr, name, version,
208                                                       serial, interface);
209         }
210
211         return CMD_RET_USAGE;
212 }
213
214 U_BOOT_CMD(
215         tricordereeprom,        7,      1,      do_tricorder_eeprom,
216         "Tricorder EEPROM",
217         "read  devaddr\n"
218         "       - read Tricorder EEPROM at devaddr and print content\n"
219         "tricordereeprom write devaddr name version serial [interface]\n"
220         "       - write Tricorder EEPROM at devaddr with 'name', 'version'"
221         "and 'serial'\n"
222         "         optional add an HW interface parameter"
223 );
224 #endif /* CONFIG_SPL */