1 /*
2  * Copyright (c) 2016 Toradex, Inc.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <g_dnl.h>
9 #include <libfdt.h>
10 
11 #include "tdx-cfg-block.h"
12 #include "tdx-common.h"
13 
14 #ifdef CONFIG_TDX_CFG_BLOCK
15 static char tdx_serial_str[9];
16 static char tdx_board_rev_str[6];
17 
18 #ifdef CONFIG_REVISION_TAG
19 u32 get_board_rev(void)
20 {
21 	/* Check validity */
22 	if (!tdx_hw_tag.ver_major)
23 		return 0;
24 
25 	return ((tdx_hw_tag.ver_major & 0xff) << 8) |
26 		((tdx_hw_tag.ver_minor & 0xf) << 4) |
27 		((tdx_hw_tag.ver_assembly & 0xf) + 0xa);
28 }
29 #endif /* CONFIG_TDX_CFG_BLOCK */
30 
31 #ifdef CONFIG_SERIAL_TAG
32 void get_board_serial(struct tag_serialnr *serialnr)
33 {
34 	int array[8];
35 	unsigned int serial = tdx_serial;
36 	int i;
37 
38 	serialnr->low = 0;
39 	serialnr->high = 0;
40 
41 	/* Check validity */
42 	if (serial) {
43 		/*
44 		 * Convert to Linux serial number format (hexadecimal coded
45 		 * decimal)
46 		 */
47 		i = 7;
48 		while (serial) {
49 			array[i--] = serial % 10;
50 			serial /= 10;
51 		}
52 		while (i >= 0)
53 			array[i--] = 0;
54 		serial = array[0];
55 		for (i = 1; i < 8; i++) {
56 			serial *= 16;
57 			serial += array[i];
58 		}
59 
60 		serialnr->low = serial;
61 	}
62 }
63 #endif /* CONFIG_SERIAL_TAG */
64 
65 int show_board_info(void)
66 {
67 	unsigned char ethaddr[6];
68 
69 	if (read_tdx_cfg_block()) {
70 		printf("Missing Toradex config block\n");
71 		checkboard();
72 		return 0;
73 	}
74 
75 	/* board serial-number */
76 	sprintf(tdx_serial_str, "%08u", tdx_serial);
77 	sprintf(tdx_board_rev_str, "V%1d.%1d%c",
78 		tdx_hw_tag.ver_major,
79 		tdx_hw_tag.ver_minor,
80 		(char)tdx_hw_tag.ver_assembly + 'A');
81 
82 	setenv("serial#", tdx_serial_str);
83 
84 	/*
85 	 * Check if environment contains a valid MAC address,
86 	 * set the one from config block if not
87 	 */
88 	if (!eth_getenv_enetaddr("ethaddr", ethaddr))
89 		eth_setenv_enetaddr("ethaddr", (u8 *)&tdx_eth_addr);
90 
91 #ifdef CONFIG_TDX_CFG_BLOCK_2ND_ETHADDR
92 	if (!eth_getenv_enetaddr("eth1addr", ethaddr)) {
93 		/*
94 		 * Secondary MAC address is allocated from block
95 		 * 0x100000 higher then the first MAC address
96 		 */
97 		memcpy(ethaddr, &tdx_eth_addr, 6);
98 		ethaddr[3] += 0x10;
99 		eth_setenv_enetaddr("eth1addr", ethaddr);
100 	}
101 #endif
102 
103 	printf("Model: Toradex %s %s, Serial# %s\n",
104 	       toradex_modules[tdx_hw_tag.prodid],
105 	       tdx_board_rev_str,
106 	       tdx_serial_str);
107 
108 	return 0;
109 }
110 
111 #ifdef CONFIG_USB_GADGET_DOWNLOAD
112 int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
113 {
114 	unsigned short usb_pid;
115 
116 	usb_pid = TORADEX_USB_PRODUCT_NUM_OFFSET + tdx_hw_tag.prodid;
117 	put_unaligned(usb_pid, &dev->idProduct);
118 
119 	return 0;
120 }
121 #endif
122 
123 #if defined(CONFIG_OF_LIBFDT)
124 int ft_common_board_setup(void *blob, bd_t *bd)
125 {
126 	if (tdx_serial) {
127 		fdt_setprop(blob, 0, "serial-number", tdx_serial_str,
128 			    strlen(tdx_serial_str) + 1);
129 	}
130 
131 	if (tdx_hw_tag.ver_major) {
132 		char prod_id[5];
133 
134 		sprintf(prod_id, "%04u", tdx_hw_tag.prodid);
135 		fdt_setprop(blob, 0, "toradex,product-id", prod_id, 5);
136 
137 		fdt_setprop(blob, 0, "toradex,board-rev", tdx_board_rev_str,
138 			    strlen(tdx_board_rev_str) + 1);
139 	}
140 
141 	return 0;
142 }
143 #endif
144 
145 #else /* CONFIG_TDX_CFG_BLOCK */
146 
147 #ifdef CONFIG_REVISION_TAG
148 u32 get_board_rev(void)
149 {
150 	return 0;
151 }
152 #endif /* CONFIG_REVISION_TAG */
153 
154 #ifdef CONFIG_SERIAL_TAG
155 u32 get_board_serial(void)
156 {
157 	return 0;
158 }
159 #endif /* CONFIG_SERIAL_TAG */
160 
161 int ft_common_board_setup(void *blob, bd_t *bd)
162 {
163 	return 0;
164 }
165 
166 #endif /* CONFIG_TDX_CFG_BLOCK */
167