Aaron Williams | 4fd1e55 | 2021-04-23 19:56:32 +0200 | [diff] [blame^] | 1 | /* 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 | |
| 9 | struct phy_device; |
| 10 | |
| 11 | /** Type of GPIO pin */ |
| 12 | enum 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 | */ |
| 57 | int 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 | */ |
| 90 | int 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 | */ |
| 98 | void 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 | */ |
| 105 | void 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 | */ |
| 112 | void octeon_fixup_fdt_memory(void); |
| 113 | |
| 114 | int board_fixup_fdt(void); |
| 115 | |
| 116 | void 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 | */ |
| 126 | int 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 | */ |
| 145 | int 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 | */ |
| 155 | int 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 | */ |
| 166 | int 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 | */ |
| 175 | int 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 | */ |
| 187 | int 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 | */ |
| 199 | int 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 | */ |
| 212 | int 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 | */ |
| 226 | int 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 | */ |
| 240 | int 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 | */ |
| 256 | int 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 | */ |
| 267 | struct phy_device *octeon_fdt_get_phy_gpio_info(int fdt_node, enum octeon_gpio_type *type); |
| 268 | #endif /* __OCTEON_FDT_H__ */ |