PDK-6945: Board: am64x evm eeprom test validated for board ID read
[processor-sdk/pdk.git] / packages / ti / board / src / am64x_evm / board_info.c
1 /******************************************************************************\r
2  * Copyright (c) 2020 Texas Instruments Incorporated - http://www.ti.com\r
3  *\r
4  *  Redistribution and use in source and binary forms, with or without\r
5  *  modification, are permitted provided that the following conditions\r
6  *  are met:\r
7  *\r
8  *    Redistributions of source code must retain the above copyright\r
9  *    notice, this list of conditions and the following disclaimer.\r
10  *\r
11  *    Redistributions in binary form must reproduce the above copyright\r
12  *    notice, this list of conditions and the following disclaimer in the\r
13  *    documentation and/or other materials provided with the\r
14  *    distribution.\r
15  *\r
16  *    Neither the name of Texas Instruments Incorporated nor the names of\r
17  *    its contributors may be used to endorse or promote products derived\r
18  *    from this software without specific prior written permission.\r
19  *\r
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31  *\r
32  *****************************************************************************/\r
33 \r
34 /**\r
35  *  \file board_info.c\r
36  *\r
37  *  \brief This file contains the functions to read/write board info data \r
38  *\r
39  */\r
40 \r
41 #include "board_utils.h"\r
42 #include "board_internal.h"\r
43 #include "board_cfg.h"\r
44 #include <stdio.h>\r
45 #include <string.h>\r
46 \r
47 extern Board_I2cInitCfg_t gBoardI2cInitCfg;\r
48 \r
49 /**\r
50  *  @brief  This function is not supported by this platform.\r
51  *\r
52  *  Function implementation for build backward compatibilty.\r
53  *  Always returns 'BOARD_UNSUPPORTED_FEATURE'\r
54  *\r
55  */\r
56 Board_STATUS Board_getIDInfo(Board_IDInfo *info)\r
57 {\r
58     return BOARD_UNSUPPORTED_FEATURE;\r
59 }\r
60 \r
61 /**\r
62  *  @brief      Get board information.\r
63  *  \r
64  *  This function requires the information of I2C instance and domain\r
65  *  to which board ID EEPROM is connected. This need to be set using\r
66  *  Board_setI2cInitConfig() before calling this function.\r
67  *\r
68  *  @param[out] Board_STATUS\r
69  *    Returns status on API call\r
70  *  @param[out] info\r
71  *    This structure will have board information on return\r
72  *  @param[in] slaveAddress\r
73  *    I2C slave address of EEPROM to be read\r
74  *\r
75  */\r
76 Board_STATUS Board_getIDInfo_v2(Board_IDInfo_v2 *info, uint8_t slaveAddress)\r
77 {\r
78     Board_STATUS ret = BOARD_SOK;\r
79     I2C_Transaction i2cTransaction;\r
80     I2C_Handle handle = NULL;\r
81     uint16_t offsetAddress = BOARD_EEPROM_HEADER_ADDR;\r
82     uint8_t rdBuff[3];\r
83     char txBuf[2] = {0x00, 0x00};\r
84     bool status;\r
85 \r
86     handle = Board_getI2CHandle(gBoardI2cInitCfg.socDomain,\r
87                                 gBoardI2cInitCfg.i2cInst);\r
88     if(handle == NULL)\r
89     {\r
90         ret = BOARD_I2C_OPEN_FAIL;\r
91     }\r
92 \r
93     I2C_transactionInit(&i2cTransaction);\r
94 \r
95     i2cTransaction.slaveAddress = slaveAddress;\r
96     i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];\r
97     i2cTransaction.writeCount = 2;\r
98 \r
99     /* Get header info */\r
100     txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress)>>8);\r
101     txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
102     i2cTransaction.readBuf = &info->headerInfo;\r
103     i2cTransaction.readCount = BOARD_EEPROM_HEADER_FIELD_SIZE;\r
104 \r
105     status = I2C_transfer(handle, &i2cTransaction);\r
106     if (status == false)\r
107     {\r
108         ret = BOARD_I2C_TRANSFER_FAIL;\r
109         Board_i2cDeInit();\r
110         return ret;\r
111     }\r
112 \r
113     /* Checking whether the board contents are flashed or not */\r
114     if (info->headerInfo.magicNumber == BOARD_EEPROM_MAGIC_NUMBER)\r
115     {\r
116         offsetAddress = offsetAddress + i2cTransaction.readCount;\r
117         txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
118         txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
119         i2cTransaction.readBuf = &info->boardInfo;\r
120         i2cTransaction.readCount = BOARD_EEPROM_TYPE_SIZE +\r
121                                     BOARD_EEPROM_STRUCT_LENGTH_SIZE;\r
122         status = I2C_transfer(handle, &i2cTransaction);\r
123         if (status == false)\r
124         {\r
125             ret = BOARD_I2C_TRANSFER_FAIL;\r
126             Board_i2cDeInit();\r
127             return ret;\r
128         }\r
129 \r
130         offsetAddress = offsetAddress + i2cTransaction.readCount;\r
131         txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
132         txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
133         i2cTransaction.readBuf = info->boardInfo.boardName;\r
134         i2cTransaction.readCount = info->boardInfo.boardInfoLength;\r
135 \r
136         status = I2C_transfer(handle, &i2cTransaction);\r
137         if (status == false)\r
138         {\r
139             ret = BOARD_I2C_TRANSFER_FAIL;\r
140             Board_i2cDeInit();\r
141             return ret;\r
142         }\r
143 \r
144         offsetAddress = offsetAddress + i2cTransaction.readCount;\r
145         txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
146         txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
147         i2cTransaction.readBuf = &rdBuff[0];\r
148         i2cTransaction.readCount = BOARD_EEPROM_TYPE_SIZE +\r
149                                     BOARD_EEPROM_STRUCT_LENGTH_SIZE;\r
150 \r
151         status = I2C_transfer(handle, &i2cTransaction);\r
152         if (status == false)\r
153         {\r
154             ret = BOARD_I2C_TRANSFER_FAIL;\r
155             Board_i2cDeInit();\r
156             return ret;\r
157         }\r
158 \r
159         /* Checking whether DDR field is present or not */\r
160         if (rdBuff[0] == BOARD_DDR_FIELD_TYPE)\r
161         {\r
162             memcpy(&info->ddrInfo, &rdBuff[0], sizeof(rdBuff));\r
163 \r
164             offsetAddress = offsetAddress + i2cTransaction.readCount;\r
165             txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress)>>8);\r
166             txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
167             i2cTransaction.readBuf = &info->ddrInfo.ddrCtrl;\r
168             i2cTransaction.readCount = info->ddrInfo.ddrStructLen;\r
169 \r
170             status = I2C_transfer(handle, &i2cTransaction);\r
171             if (status == false)\r
172             {\r
173                 ret = BOARD_I2C_TRANSFER_FAIL;\r
174                 Board_i2cDeInit();\r
175                 return ret;\r
176             }\r
177 \r
178             offsetAddress = offsetAddress + i2cTransaction.readCount;\r
179             txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
180             txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
181             i2cTransaction.readBuf = &rdBuff[0];\r
182             i2cTransaction.readCount = BOARD_EEPROM_TYPE_SIZE +\r
183                                         BOARD_EEPROM_STRUCT_LENGTH_SIZE;\r
184             status = I2C_transfer(handle, &i2cTransaction);\r
185             if (status == false)\r
186             {\r
187                 ret = BOARD_I2C_TRANSFER_FAIL;\r
188                 Board_i2cDeInit();\r
189                 return ret;\r
190             }\r
191         }\r
192 \r
193         /* Checking whether MAC id field is present or not */\r
194         if(rdBuff[0] == BOARD_MACINFO_FIELD_TYPE)\r
195         {\r
196             memcpy(&info->macInfo, &rdBuff[0], sizeof(rdBuff));\r
197 \r
198             offsetAddress = offsetAddress + i2cTransaction.readCount;\r
199             txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
200             txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
201             i2cTransaction.readBuf = &info->macInfo.macControl;\r
202             i2cTransaction.readCount = info->macInfo.macLength;\r
203 \r
204             status = I2C_transfer(handle, &i2cTransaction);\r
205             if (status == false)\r
206             {\r
207                 ret = BOARD_I2C_TRANSFER_FAIL;\r
208                 Board_i2cDeInit();\r
209                 return ret;\r
210             }\r
211 \r
212             offsetAddress = offsetAddress + i2cTransaction.readCount;\r
213             txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress)>>8);\r
214             txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
215             i2cTransaction.readBuf = &rdBuff[0];\r
216             i2cTransaction.readCount = BOARD_EEPROM_TYPE_SIZE;\r
217 \r
218             status = I2C_transfer(handle, &i2cTransaction);\r
219             if (status == false)\r
220             {\r
221                 ret = BOARD_I2C_TRANSFER_FAIL;\r
222                 Board_i2cDeInit();\r
223                 return ret;\r
224             }\r
225         }\r
226 \r
227         if(rdBuff[0] == BOARD_ENDLIST)\r
228         {\r
229             info->endList = rdBuff[0];\r
230         }\r
231     }\r
232     else\r
233     {\r
234         ret = BOARD_INVALID_PARAM;\r
235         Board_i2cDeInit();\r
236         return ret;\r
237     }\r
238 \r
239     Board_i2cDeInit();\r
240 \r
241     return ret;\r
242 }\r
243 \r
244 /**\r
245  *  @brief  This function is not supported by this platform.\r
246  *\r
247  *  Function implementation for build backward compatibilty.\r
248  *  Always returns 'BOARD_UNSUPPORTED_FEATURE'\r
249  *\r
250  */\r
251 Board_STATUS Board_writeIDInfo(Board_IDInfo *info)\r
252 {\r
253     return BOARD_UNSUPPORTED_FEATURE;\r
254 }\r
255 \r
256 /**\r
257  *  @brief  Write board id contents to specific EEPROM.\r
258  *\r
259  *  This function requires the information of I2C instance and domain\r
260  *  to which board ID EEPROM is connected. This need to be set using\r
261  *  Board_setI2cInitConfig() before calling this function.\r
262  *\r
263  *  @param[out] Board_STATUS\r
264  *    Returns status on API call\r
265  * @param[out] info\r
266  *    Structure contain board id contents to write\r
267  *  @param[in] slaveAddress\r
268  *    Address of eeprom\r
269  *\r
270  */\r
271 Board_STATUS Board_writeIDInfo_v2(Board_IDInfo_v2 *info, uint8_t slaveAddress)\r
272 {\r
273     Board_STATUS ret = BOARD_SOK;\r
274     I2C_Transaction i2cTransaction;\r
275     I2C_Handle handle = NULL;\r
276     uint16_t offsetSize = 2;\r
277     uint16_t offsetAddress = BOARD_EEPROM_HEADER_ADDR;\r
278     char txBuf[BOARD_EEPROM_MAX_BUFF_LENGTH + 2 + 1];\r
279     bool status;\r
280 \r
281     /* Checking the structure is valid or not */\r
282     if (info->headerInfo.magicNumber != BOARD_EEPROM_MAGIC_NUMBER)\r
283     {\r
284         ret = BOARD_INVALID_PARAM;\r
285         return ret;\r
286     }\r
287 \r
288     handle = Board_getI2CHandle(gBoardI2cInitCfg.socDomain,\r
289                                 gBoardI2cInitCfg.i2cInst);\r
290     if(handle == NULL)\r
291     {\r
292         ret = BOARD_I2C_OPEN_FAIL;\r
293     }\r
294 \r
295     I2C_transactionInit(&i2cTransaction);\r
296 \r
297     /* Transferring Header and Board Info field */\r
298     i2cTransaction.slaveAddress = slaveAddress;\r
299     i2cTransaction.writeBuf = &txBuf[0];\r
300     i2cTransaction.writeCount = BOARD_EEPROM_HEADER_FIELD_SIZE +\r
301                                 BOARD_EEPROM_TYPE_SIZE +\r
302                                 BOARD_EEPROM_STRUCT_LENGTH_SIZE +\r
303                                 info->boardInfo.boardInfoLength +\r
304                                 offsetSize;\r
305     txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
306     txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
307     memcpy(&txBuf[2], &info->headerInfo, i2cTransaction.writeCount);\r
308 \r
309     i2cTransaction.readBuf = NULL;\r
310     i2cTransaction.readCount = 0;\r
311 \r
312     status = I2C_transfer(handle, &i2cTransaction);\r
313     if (status == false)\r
314     {\r
315         ret = BOARD_I2C_TRANSFER_FAIL;\r
316         Board_i2cDeInit();\r
317         return ret;\r
318     }\r
319 \r
320     /* Checking whether DDR field is included or not */\r
321     if (info->ddrInfo.ddrStructType == BOARD_DDR_FIELD_TYPE)\r
322     {\r
323         offsetAddress = offsetAddress + i2cTransaction.writeCount;\r
324         i2cTransaction.writeCount = info->ddrInfo.ddrStructLen +\r
325                                      BOARD_EEPROM_TYPE_SIZE +\r
326                                      BOARD_EEPROM_STRUCT_LENGTH_SIZE +\r
327                                      offsetSize;\r
328         txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
329         txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
330         memcpy(&txBuf[2], &info->ddrInfo, i2cTransaction.writeCount);\r
331 \r
332         status = I2C_transfer(handle, &i2cTransaction);\r
333         if (status == false)\r
334         {\r
335             ret = BOARD_I2C_TRANSFER_FAIL;\r
336             Board_i2cDeInit();\r
337             return ret;\r
338         }\r
339     }\r
340 \r
341     /* Checking whether MAC id field is included or not */\r
342     if (info->macInfo.macStructType == BOARD_MACINFO_FIELD_TYPE)\r
343     {\r
344         offsetAddress = offsetAddress + i2cTransaction.writeCount;\r
345         i2cTransaction.writeCount = info->macInfo.macLength +\r
346                                      BOARD_EEPROM_TYPE_SIZE +\r
347                                      BOARD_EEPROM_STRUCT_LENGTH_SIZE +\r
348                                      offsetSize;\r
349         txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress) >> 8);\r
350         txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
351         memcpy(&txBuf[2], &info->macInfo, i2cTransaction.writeCount);\r
352 \r
353         status = I2C_transfer(handle, &i2cTransaction);\r
354         if (status == false)\r
355         {\r
356             ret = BOARD_I2C_TRANSFER_FAIL;\r
357             Board_i2cDeInit();\r
358             return ret;\r
359         }\r
360     }\r
361 \r
362     offsetAddress = offsetAddress + i2cTransaction.writeCount;\r
363     i2cTransaction.writeCount = BOARD_EEPROM_TYPE_SIZE + offsetSize;\r
364     txBuf[0] = (char)(((uint32_t) 0xFF00 & offsetAddress)>>8);\r
365     txBuf[1] = (char)((uint32_t) 0xFF & offsetAddress);\r
366     memcpy(&txBuf[2], &info->endList, i2cTransaction.writeCount);\r
367 \r
368     status = I2C_transfer(handle, &i2cTransaction);\r
369     if (status == false)\r
370     {\r
371         ret = BOARD_I2C_TRANSFER_FAIL;\r
372         Board_i2cDeInit();\r
373         return ret;\r
374     }\r
375 \r
376     Board_i2cDeInit();\r
377     return ret;\r
378 }\r