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__ */ 269