blob: 31878cb233d877e190d76f49764ef59dbee675fc [file] [log] [blame]
Aaron Williams4fd1e552021-04-23 19:56:32 +02001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 Marvell International Ltd.
4 */
5
6#ifndef __OCTEON_FDT_H__
7#define __OCTEON_FDT_H__
8
9struct phy_device;
10
11/** Type of GPIO pin */
12enum octeon_gpio_type {
13 GPIO_TYPE_OCTEON, /** Native Octeon */
14 GPIO_TYPE_PCA953X, /** PCA953X i2c GPIO expander */
15 GPIO_TYPE_PCA9554, /** PCA9554 i2c GPIO expander */
16 GPIO_TYPE_PCA9555, /** PCA9555 i2c GPIO expander */
17 GPIO_TYPE_PCA9698, /** PCA9698 i2c GPIO expander */
18#ifdef CONFIG_PHY_VITESSE
19 GPIO_TYPE_VSC8488, /** Vitesse VSC8488 or related PHY GPIO */
20#endif
21 GPIO_TYPE_UNKNOWN /** Unknown GPIO type */
22};
23
24/**
25 * Trims nodes from the flat device tree.
26 *
27 * @param fdt - pointer to working FDT, usually in gd->fdt_blob
28 * @param fdt_key - key to preserve. All non-matching keys are removed
29 * @param trim_name - name of property to look for. If NULL use
30 * 'cavium,qlm-trim'
31 * @param rename - set to TRUE to rename interfaces.
32 * @param callback - function to call on matched nodes.
33 * @param cbarg - passed to callback.
34 *
35 * The key should look something like device #, type where device # is a
36 * number from 0-9 and type is a string describing the type. For QLM
37 * operations this would typically contain the QLM number followed by
38 * the type in the device tree, like "0,xaui", "0,sgmii", etc. This function
39 * will trim all items in the device tree which match the device number but
40 * have a type which does not match. For example, if a QLM has a xaui module
41 * installed on QLM 0 and "0,xaui" is passed as a key, then all FDT nodes that
42 * have "0,xaui" will be preserved but all others, i.e. "0,sgmii" will be
43 * removed.
44 *
45 * Note that the trim_name must also match. If trim_name is NULL then it
46 * looks for the property "cavium,qlm-trim".
47 *
48 * Also, when the trim_name is "cavium,qlm-trim" or NULL that the interfaces
49 * will also be renamed based on their register values.
50 *
51 * For example, if a PIP interface is named "interface@W" and has the property
52 * reg = <0> then the interface will be renamed after this function to
53 * interface@0.
54 *
55 * @return 0 for success.
56 */
57int octeon_fdt_patch_rename(void *fdt, const char *fdt_key, const char *trim_name, bool rename,
58 void (*callback)(void *fdt, int offset, void *arg), void *cbarg);
59
60/**
61 * Trims nodes from the flat device tree.
62 *
63 * @param fdt - pointer to working FDT, usually in gd->fdt_blob
64 * @param fdt_key - key to preserve. All non-matching keys are removed
65 * @param trim_name - name of property to look for. If NULL use
66 * 'cavium,qlm-trim'
67 *
68 * The key should look something like device #, type where device # is a
69 * number from 0-9 and type is a string describing the type. For QLM
70 * operations this would typically contain the QLM number followed by
71 * the type in the device tree, like "0,xaui", "0,sgmii", etc. This function
72 * will trim all items in the device tree which match the device number but
73 * have a type which does not match. For example, if a QLM has a xaui module
74 * installed on QLM 0 and "0,xaui" is passed as a key, then all FDT nodes that
75 * have "0,xaui" will be preserved but all others, i.e. "0,sgmii" will be
76 * removed.
77 *
78 * Note that the trim_name must also match. If trim_name is NULL then it
79 * looks for the property "cavium,qlm-trim".
80 *
81 * Also, when the trim_name is "cavium,qlm-trim" or NULL that the interfaces
82 * will also be renamed based on their register values.
83 *
84 * For example, if a PIP interface is named "interface@W" and has the property
85 * reg = <0> then the interface will be renamed after this function to
86 * interface@0.
87 *
88 * @return 0 for success.
89 */
90int octeon_fdt_patch(void *fdt, const char *fdt_key, const char *trim_name);
91
92/**
93 * Fix up the MAC address in the flat device tree based on the MAC address
94 * stored in ethaddr or in the board descriptor.
95 *
96 * NOTE: This function is weak and an alias for __octeon_fixup_fdt_mac_addr.
97 */
98void octeon_fixup_fdt_mac_addr(void);
99
100/**
101 * This function fixes the clock-frequency in the flat device tree for the UART.
102 *
103 * NOTE: This function is weak and an alias for __octeon_fixup_fdt_uart.
104 */
105void octeon_fixup_fdt_uart(void);
106
107/**
108 * This function fills in the /memory portion of the flat device tree.
109 *
110 * NOTE: This function is weak and aliased to __octeon_fixup_fdt_memory.
111 */
112void octeon_fixup_fdt_memory(void);
113
114int board_fixup_fdt(void);
115
116void octeon_fixup_fdt(void);
117
118/**
119 * This is a helper function to find the offset of a PHY device given
120 * an Ethernet device.
121 *
122 * @param[in] eth - Ethernet device to search for PHY offset
123 *
124 * @returns offset of phy info in device tree or -1 if not found
125 */
126int octeon_fdt_find_phy(const struct udevice *eth);
127
128/**
129 * This helper function returns if a node contains the specified vendor name.
130 *
131 * @param[in] fdt pointer to device tree blob
132 * @param nodeoffset offset of the tree node
133 * @param[in] vendor name of vendor to check
134 *
135 * returns:
136 * 0, if the node has a compatible vendor string property
137 * 1, if the node does not contain the vendor string property
138 * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
139 * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
140 * -FDT_ERR_BADMAGIC,
141 * -FDT_ERR_BADVERSION,
142 * -FDT_BADSTATE,
143 * -FDT_ERR_BADSTRUCTURE, standard meanings
144 */
145int octeon_fdt_compat_vendor(const void *fdt, int nodeoffset, const char *vendor);
146
147/**
148 * Given a node in the device tree get the OCTEON OCX node number
149 *
150 * @param fdt pointer to flat device tree
151 * @param nodeoffset node offset to get OCX node for
152 *
153 * @return the Octeon OCX node number
154 */
155int octeon_fdt_get_soc_node(const void *fdt, int nodeoffset);
156
157/**
158 * Given a FDT node, check if it is compatible with a list of devices
159 *
160 * @param[in] fdt Flat device tree pointer
161 * @param node_offset Node offset in device tree
162 * @param[in] strlist Array of FDT devices to check, end must be NULL
163 *
164 * @return 0 if at least one device is compatible, 1 if not compatible.
165 */
166int octeon_fdt_node_check_compatible(const void *fdt, int node_offset, const char *const *strlist);
167/**
168 * Given a node offset, find the i2c bus number for that node
169 *
170 * @param[in] fdt Pointer to flat device tree
171 * @param node_offset Node offset in device tree
172 *
173 * @return i2c bus number or -1 if error
174 */
175int octeon_fdt_i2c_get_bus(const void *fdt, int node_offset);
176
177/**
178 * Given an offset into the fdt, output the i2c bus and address of the device
179 *
180 * @param[in] fdt fdt blob pointer
181 * @param node offset in FDT of device
182 * @param[out] bus i2c bus number of device
183 * @param[out] addr address of device on i2c bus
184 *
185 * @return 0 for success, -1 on error
186 */
187int octeon_fdt_get_i2c_bus_addr(const void *fdt, int node, int *bus, int *addr);
188
189/**
190 * Reads a GPIO pin given the node of the GPIO device in the device tree and
191 * the pin number.
192 *
193 * @param[in] fdt fdt blob pointer
194 * @param phandle phandle of GPIO node
195 * @param pin pin number to read
196 *
197 * @return 0 = pin is low, 1 = pin is high, -1 = error
198 */
199int octeon_fdt_read_gpio(const void *fdt, int phandle, int pin);
200
201/**
202 * Reads a GPIO pin given the node of the GPIO device in the device tree and
203 * the pin number.
204 *
205 * @param[in] fdt fdt blob pointer
206 * @param phandle phandle of GPIO node
207 * @param pin pin number to read
208 * @param val value to write (1 = high, 0 = low)
209 *
210 * @return 0 = success, -1 = error
211 */
212int octeon_fdt_set_gpio(const void *fdt, int phandle, int pin, int val);
213
214/**
215 * Given the node to a MAC entry in the device tree, output the i2c bus, address
216 * and if the module is absent.
217 *
218 * @param[in] fdt flat device tree pointer
219 * @param mac_node node of Ethernet port in the FDT
220 * @param[out] bus i2c bus address of SFP EEPROM
221 * @param[out] addr i2c address of SFP EEPROM
222 * @param[out] mod_abs Set true if module is absent, false if present
223 *
224 * @return 0 for success, -1 if there are problems with the device tree
225 */
226int octeon_fdt_get_sfp_eeprom(const void *fdt, int mac_node, int *bus, int *addr, bool *mod_abs);
227
228/**
229 * Given a node to a MAC entry in the device tree, output the i2c bus, address
230 * and if the module is absent
231 *
232 * @param[in] fdt flat device tree pointer
233 * @param mac_node node of QSFP Ethernet port in FDT
234 * @param[out] bus i2c bus address of SFP EEPROM
235 * @param[out] addr i2c address of SFP eeprom
236 * @param[out] mod_abs Set true if module is absent, false if present
237 *
238 * @return 0 for success, -1 if there are problems with the device tree
239 */
240int octeon_fdt_get_qsfp_eeprom(const void *fdt, int mac_node, int *bus, int *addr, bool *mod_abs);
241
242/**
243 * Given the node of a GPIO entry output the GPIO type, i2c bus and i2c
244 * address.
245 *
246 * @param fdt_node node of GPIO in device tree, generally
247 * derived from a phandle.
248 * @param[out] type Type of GPIO detected
249 * @param[out] i2c_bus For i2c GPIO expanders, the i2c bus number
250 * @param[out] i2c_addr For i2c GPIO expanders, the i2c address
251 *
252 * @return 0 for success, -1 for errors
253 *
254 * NOTE: It is up to the caller to determine the pin number.
255 */
256int octeon_fdt_get_gpio_info(int fdt_node, enum octeon_gpio_type *type, int *i2c_bus,
257 int *i2c_addr);
258
259/**
260 * Get the PHY data structure for the specified FDT node and output the type
261 *
262 * @param fdt_node FDT node of phy
263 * @param[out] type Type of GPIO
264 *
265 * @return pointer to phy device or NULL if no match found.
266 */
267struct phy_device *octeon_fdt_get_phy_gpio_info(int fdt_node, enum octeon_gpio_type *type);
268#endif /* __OCTEON_FDT_H__ */