mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-08 06:04:34 +00:00
e7bc6eabd1
Import misc cvmx-helper header files from 2013 U-Boot. They will be used by the later added drivers to support PCIe and networking on the MIPS Octeon II / III platforms. Signed-off-by: Aaron Williams <awilliams@marvell.com> Signed-off-by: Stefan Roese <sr@denx.de>
568 lines
16 KiB
C
568 lines
16 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2020 Marvell International Ltd.
|
|
*
|
|
* FDT Helper functions similar to those provided to U-Boot.
|
|
* If compiled for U-Boot, just provide wrappers to the equivalent U-Boot
|
|
* functions.
|
|
*/
|
|
|
|
#ifndef __CVMX_HELPER_FDT_H__
|
|
#define __CVMX_HELPER_FDT_H__
|
|
|
|
#include <fdt_support.h>
|
|
#include <fdtdec.h>
|
|
#include <time.h>
|
|
#include <asm/global_data.h>
|
|
#include <linux/libfdt.h>
|
|
|
|
#include <mach/cvmx-helper-sfp.h>
|
|
|
|
enum cvmx_i2c_bus_type {
|
|
CVMX_I2C_BUS_OCTEON,
|
|
CVMX_I2C_MUX_PCA9540,
|
|
CVMX_I2C_MUX_PCA9542,
|
|
CVMX_I2C_MUX_PCA9543,
|
|
CVMX_I2C_MUX_PCA9544,
|
|
CVMX_I2C_MUX_PCA9545,
|
|
CVMX_I2C_MUX_PCA9546,
|
|
CVMX_I2C_MUX_PCA9547,
|
|
CVMX_I2C_MUX_PCA9548,
|
|
CVMX_I2C_MUX_OTHER
|
|
};
|
|
|
|
struct cvmx_sfp_mod_info; /** Defined in cvmx-helper-sfp.h */
|
|
struct cvmx_phy_info; /** Defined in cvmx-helper-board.h */
|
|
|
|
/**
|
|
* This data structure holds information about various I2C muxes and switches
|
|
* that may be between a device and the Octeon chip.
|
|
*/
|
|
struct cvmx_fdt_i2c_bus_info {
|
|
/** Parent I2C bus, NULL if root */
|
|
struct cvmx_fdt_i2c_bus_info *parent;
|
|
/** Child I2C bus or NULL if last entry in the chain */
|
|
struct cvmx_fdt_i2c_bus_info *child;
|
|
/** Offset in device tree */
|
|
int of_offset;
|
|
/** Type of i2c bus or mux */
|
|
enum cvmx_i2c_bus_type type;
|
|
/** I2C address of mux */
|
|
u8 i2c_addr;
|
|
/** Mux channel number */
|
|
u8 channel;
|
|
/** For muxes, the bit(s) to set to enable them */
|
|
u8 enable_bit;
|
|
/** True if mux, false if switch */
|
|
bool is_mux;
|
|
};
|
|
|
|
/**
|
|
* Data structure containing information about SFP/QSFP slots
|
|
*/
|
|
struct cvmx_fdt_sfp_info {
|
|
/** Used for a linked list of slots */
|
|
struct cvmx_fdt_sfp_info *next, *prev;
|
|
/** Used when multiple SFP ports share the same IPD port */
|
|
struct cvmx_fdt_sfp_info *next_iface_sfp;
|
|
/** Name from device tree of slot */
|
|
const char *name;
|
|
/** I2C bus for slot EEPROM */
|
|
struct cvmx_fdt_i2c_bus_info *i2c_bus;
|
|
/** Data from SFP or QSFP EEPROM */
|
|
struct cvmx_sfp_mod_info sfp_info;
|
|
/** Data structure with PHY information */
|
|
struct cvmx_phy_info *phy_info;
|
|
/** IPD port(s) slot is connected to */
|
|
int ipd_port[4];
|
|
/** Offset in device tree of slot */
|
|
int of_offset;
|
|
/** EEPROM address of SFP module (usually 0x50) */
|
|
u8 i2c_eeprom_addr;
|
|
/** Diagnostic address of SFP module (usually 0x51) */
|
|
u8 i2c_diag_addr;
|
|
/** True if QSFP module */
|
|
bool is_qsfp;
|
|
/** True if EEPROM data is valid */
|
|
bool valid;
|
|
/** SFP tx_disable GPIO descriptor */
|
|
struct cvmx_fdt_gpio_info *tx_disable;
|
|
/** SFP mod_abs/QSFP mod_prs GPIO descriptor */
|
|
struct cvmx_fdt_gpio_info *mod_abs;
|
|
/** SFP tx_error GPIO descriptor */
|
|
struct cvmx_fdt_gpio_info *tx_error;
|
|
/** SFP rx_los GPIO discriptor */
|
|
struct cvmx_fdt_gpio_info *rx_los;
|
|
/** QSFP select GPIO descriptor */
|
|
struct cvmx_fdt_gpio_info *select;
|
|
/** QSFP reset GPIO descriptor */
|
|
struct cvmx_fdt_gpio_info *reset;
|
|
/** QSFP interrupt GPIO descriptor */
|
|
struct cvmx_fdt_gpio_info *interrupt;
|
|
/** QSFP lp_mode GPIO descriptor */
|
|
struct cvmx_fdt_gpio_info *lp_mode;
|
|
/** Last mod_abs value */
|
|
int last_mod_abs;
|
|
/** Last rx_los value */
|
|
int last_rx_los;
|
|
/** Function to call to check mod_abs */
|
|
int (*check_mod_abs)(struct cvmx_fdt_sfp_info *sfp_info, void *data);
|
|
/** User-defined data to pass to check_mod_abs */
|
|
void *mod_abs_data;
|
|
/** Function to call when mod_abs changes */
|
|
int (*mod_abs_changed)(struct cvmx_fdt_sfp_info *sfp_info, int val, void *data);
|
|
/** User-defined data to pass to mod_abs_changed */
|
|
void *mod_abs_changed_data;
|
|
/** Function to call when rx_los changes */
|
|
int (*rx_los_changed)(struct cvmx_fdt_sfp_info *sfp_info, int val, void *data);
|
|
/** User-defined data to pass to rx_los_changed */
|
|
void *rx_los_changed_data;
|
|
/** True if we're connected to a Microsemi VSC7224 reclocking chip */
|
|
bool is_vsc7224;
|
|
/** Data structure for first vsc7224 channel we're attached to */
|
|
struct cvmx_vsc7224_chan *vsc7224_chan;
|
|
/** True if we're connected to a Avago AVSP5410 phy */
|
|
bool is_avsp5410;
|
|
/** Data structure for avsp5410 phy we're attached to */
|
|
struct cvmx_avsp5410 *avsp5410;
|
|
/** xinterface we're on */
|
|
int xiface;
|
|
/** port index */
|
|
int index;
|
|
};
|
|
|
|
/**
|
|
* Look up a phandle and follow it to its node then return the offset of that
|
|
* node.
|
|
*
|
|
* @param[in] fdt_addr pointer to FDT blob
|
|
* @param node node to read phandle from
|
|
* @param[in] prop_name name of property to find
|
|
* @param[in,out] lenp Number of phandles, input max number
|
|
* @param[out] nodes Array of phandle nodes
|
|
*
|
|
* @return -ve error code on error or 0 for success
|
|
*/
|
|
int cvmx_fdt_lookup_phandles(const void *fdt_addr, int node, const char *prop_name, int *lenp,
|
|
int *nodes);
|
|
|
|
/**
|
|
* Helper to return the address property
|
|
*
|
|
* @param[in] fdt_addr pointer to FDT blob
|
|
* @param node node to read address from
|
|
* @param prop_name property name to read
|
|
*
|
|
* @return address of property or FDT_ADDR_T_NONE if not found
|
|
*/
|
|
static inline fdt_addr_t cvmx_fdt_get_addr(const void *fdt_addr, int node, const char *prop_name)
|
|
{
|
|
return fdtdec_get_addr(fdt_addr, node, prop_name);
|
|
}
|
|
|
|
/**
|
|
* Helper function to return an integer property
|
|
*
|
|
* @param[in] fdt_addr pointer to FDT blob
|
|
* @param node node to read integer from
|
|
* @param[in] prop_name property name to read
|
|
* @param default_val default value to return if property doesn't exist
|
|
*
|
|
* @return integer value of property or default_val if it doesn't exist.
|
|
*/
|
|
static inline int cvmx_fdt_get_int(const void *fdt_addr, int node, const char *prop_name,
|
|
int default_val)
|
|
{
|
|
return fdtdec_get_int(fdt_addr, node, prop_name, default_val);
|
|
}
|
|
|
|
static inline bool cvmx_fdt_get_bool(const void *fdt_addr, int node, const char *prop_name)
|
|
{
|
|
return fdtdec_get_bool(fdt_addr, node, prop_name);
|
|
}
|
|
|
|
static inline u64 cvmx_fdt_get_uint64(const void *fdt_addr, int node, const char *prop_name,
|
|
u64 default_val)
|
|
{
|
|
return fdtdec_get_uint64(fdt_addr, node, prop_name, default_val);
|
|
}
|
|
|
|
/**
|
|
* Look up a phandle and follow it to its node then return the offset of that
|
|
* node.
|
|
*
|
|
* @param[in] fdt_addr pointer to FDT blob
|
|
* @param node node to read phandle from
|
|
* @param[in] prop_name name of property to find
|
|
*
|
|
* @return node offset if found, -ve error code on error
|
|
*/
|
|
static inline int cvmx_fdt_lookup_phandle(const void *fdt_addr, int node, const char *prop_name)
|
|
{
|
|
return fdtdec_lookup_phandle(fdt_addr, node, prop_name);
|
|
}
|
|
|
|
/**
|
|
* Translate an address from the device tree into a CPU physical address by
|
|
* walking up the device tree and applying bus mappings along the way.
|
|
*
|
|
* This uses #size-cells and #address-cells.
|
|
*
|
|
* @param[in] fdt_addr Address of flat device tree
|
|
* @param node node to start translating from
|
|
* @param[in] in_addr Address to translate
|
|
* NOTE: in_addr must be in the native ENDIAN
|
|
* format.
|
|
*
|
|
* @return Translated address or FDT_ADDR_T_NONE if address cannot be
|
|
* translated.
|
|
*/
|
|
static inline u64 cvmx_fdt_translate_address(const void *fdt_addr, int node, const u32 *in_addr)
|
|
{
|
|
return fdt_translate_address((void *)fdt_addr, node, in_addr);
|
|
}
|
|
|
|
/**
|
|
* Compare compatibile strings in the flat device tree.
|
|
*
|
|
* @param[in] s1 First string to compare
|
|
* @param[in] sw Second string to compare
|
|
*
|
|
* @return 0 if no match
|
|
* 1 if only the part number matches and not the manufacturer
|
|
* 2 if both the part number and manufacturer match
|
|
*/
|
|
int cvmx_fdt_compat_match(const char *s1, const char *s2);
|
|
|
|
/**
|
|
* Returns whether a list of strings contains the specified string
|
|
*
|
|
* @param[in] slist String list
|
|
* @param llen string list total length
|
|
* @param[in] str string to search for
|
|
*
|
|
* @return 1 if string list contains string, 0 if it does not.
|
|
*/
|
|
int cvmx_fdt_compat_list_contains(const char *slist, int llen, const char *str);
|
|
|
|
/**
|
|
* Check if a node is compatible with the specified compat string
|
|
*
|
|
* @param[in] fdt_addr FDT address
|
|
* @param node node offset to check
|
|
* @param[in] compat compatible string to check
|
|
*
|
|
* @return 0 if compatible, 1 if not compatible, error if negative
|
|
*/
|
|
int cvmx_fdt_node_check_compatible(const void *fdt_addr, int node, const char *compat);
|
|
|
|
/**
|
|
* @INTERNAL
|
|
* Compares a string to a compatible field.
|
|
*
|
|
* @param[in] compat compatible string
|
|
* @param[in] str string to check
|
|
*
|
|
* @return 0 if not compatible, 1 if manufacturer compatible, 2 if
|
|
* part is compatible, 3 if both part and manufacturer are
|
|
* compatible.
|
|
*/
|
|
int __cvmx_fdt_compat_match(const char *compat, const char *str);
|
|
|
|
/**
|
|
* Given a phandle to a GPIO device return the type of GPIO device it is.
|
|
*
|
|
* @param[in] fdt_addr Address of flat device tree
|
|
* @param phandle phandle to GPIO
|
|
* @param[out] size Number of pins (optional, may be NULL)
|
|
*
|
|
* @return Type of GPIO device or PIN_ERROR if error
|
|
*/
|
|
enum cvmx_gpio_type cvmx_fdt_get_gpio_type(const void *fdt_addr, int phandle, int *size);
|
|
|
|
/**
|
|
* Given a phandle to a GPIO node output the i2c bus and address
|
|
*
|
|
* @param[in] fdt_addr Address of FDT
|
|
* @param phandle phandle of GPIO device
|
|
* @param[out] bus TWSI bus number with node in bits 1-3, can be
|
|
* NULL for none.
|
|
* @param[out] addr TWSI address number, can be NULL for none
|
|
*
|
|
* @return 0 for success, error otherwise
|
|
*/
|
|
int cvmx_fdt_get_twsi_gpio_bus_addr(const void *fdt_addr, int phandle, int *bus, int *addr);
|
|
|
|
/**
|
|
* Given a FDT node return the CPU node number
|
|
*
|
|
* @param[in] fdt_addr Address of FDT
|
|
* @param node FDT node number
|
|
*
|
|
* @return CPU node number or error if negative
|
|
*/
|
|
int cvmx_fdt_get_cpu_node(const void *fdt_addr, int node);
|
|
|
|
/**
|
|
* Get the total size of the flat device tree
|
|
*
|
|
* @param[in] fdt_addr Address of FDT
|
|
*
|
|
* @return Size of flat device tree in bytes or -1 if error.
|
|
*/
|
|
int cvmx_fdt_get_fdt_size(const void *fdt_addr);
|
|
|
|
/**
|
|
* Returns if a node is compatible with one of the items in the string list
|
|
*
|
|
* @param[in] fdt_addr Pointer to flat device tree
|
|
* @param node Node offset to check
|
|
* @param[in] strlist Array of FDT device compatibility strings,
|
|
* must end with NULL or empty string.
|
|
*
|
|
* @return 0 if at least one item matches, 1 if no matches
|
|
*/
|
|
int cvmx_fdt_node_check_compatible_list(const void *fdt_addr, int node, const char *const *strlist);
|
|
|
|
/**
|
|
* Given a FDT node, return the next compatible node.
|
|
*
|
|
* @param[in] fdt_addr Pointer to flat device tree
|
|
* @param start_offset Starting node offset or -1 to find the first
|
|
* @param strlist Array of FDT device compatibility strings, must
|
|
* end with NULL or empty string.
|
|
*
|
|
* @return next matching node or -1 if no more matches.
|
|
*/
|
|
int cvmx_fdt_node_offset_by_compatible_list(const void *fdt_addr, int startoffset,
|
|
const char *const *strlist);
|
|
|
|
/**
|
|
* Given the parent offset of an i2c device build up a list describing the bus
|
|
* which can contain i2c muxes and switches.
|
|
*
|
|
* @param[in] fdt_addr address of device tree
|
|
* @param of_offset Offset of the parent node of a GPIO device in
|
|
* the device tree.
|
|
*
|
|
* @return pointer to list of i2c devices starting from the root which
|
|
* can include i2c muxes and switches or NULL if error. Note that
|
|
* all entries are allocated on the heap.
|
|
*
|
|
* @see cvmx_fdt_free_i2c_bus()
|
|
*/
|
|
struct cvmx_fdt_i2c_bus_info *cvmx_fdt_get_i2c_bus(const void *fdt_addr, int of_offset);
|
|
|
|
/**
|
|
* Return the Octeon bus number for a bus descriptor
|
|
*
|
|
* @param[in] bus bus descriptor
|
|
*
|
|
* @return Octeon twsi bus number or -1 on error
|
|
*/
|
|
int cvmx_fdt_i2c_get_root_bus(const struct cvmx_fdt_i2c_bus_info *bus);
|
|
|
|
/**
|
|
* Frees all entries for an i2c bus descriptor
|
|
*
|
|
* @param bus bus to free
|
|
*
|
|
* @return 0
|
|
*/
|
|
int cvmx_fdt_free_i2c_bus(struct cvmx_fdt_i2c_bus_info *bus);
|
|
|
|
/**
|
|
* Given the bus to a device, enable it.
|
|
*
|
|
* @param[in] bus i2c bus descriptor to enable or disable
|
|
* @param enable set to true to enable, false to disable
|
|
*
|
|
* @return 0 for success or -1 for invalid bus
|
|
*
|
|
* This enables the entire bus including muxes and switches in the path.
|
|
*/
|
|
int cvmx_fdt_enable_i2c_bus(const struct cvmx_fdt_i2c_bus_info *bus, bool enable);
|
|
|
|
/**
|
|
* Return a GPIO handle given a GPIO phandle of the form <&gpio pin flags>
|
|
*
|
|
* @param[in] fdt_addr Address of flat device tree
|
|
* @param of_offset node offset for property
|
|
* @param prop_name name of property
|
|
*
|
|
* @return pointer to GPIO handle or NULL if error
|
|
*/
|
|
struct cvmx_fdt_gpio_info *cvmx_fdt_gpio_get_info_phandle(const void *fdt_addr, int of_offset,
|
|
const char *prop_name);
|
|
|
|
/**
|
|
* Sets a GPIO pin given the GPIO descriptor
|
|
*
|
|
* @param pin GPIO pin descriptor
|
|
* @param value value to set it to, 0 or 1
|
|
*
|
|
* @return 0 on success, -1 on error.
|
|
*
|
|
* NOTE: If the CVMX_GPIO_ACTIVE_LOW flag is set then the output value will be
|
|
* inverted.
|
|
*/
|
|
int cvmx_fdt_gpio_set(struct cvmx_fdt_gpio_info *pin, int value);
|
|
|
|
/**
|
|
* Given a GPIO pin descriptor, input the value of that pin
|
|
*
|
|
* @param pin GPIO pin descriptor
|
|
*
|
|
* @return 0 if low, 1 if high, -1 on error. Note that the input will be
|
|
* inverted if the CVMX_GPIO_ACTIVE_LOW flag bit is set.
|
|
*/
|
|
int cvmx_fdt_gpio_get(struct cvmx_fdt_gpio_info *pin);
|
|
|
|
/**
|
|
* Assigns an IPD port to a SFP slot
|
|
*
|
|
* @param sfp Handle to SFP data structure
|
|
* @param ipd_port Port to assign it to
|
|
*
|
|
* @return 0 for success, -1 on error
|
|
*/
|
|
int cvmx_sfp_set_ipd_port(struct cvmx_fdt_sfp_info *sfp, int ipd_port);
|
|
|
|
/**
|
|
* Get the IPD port of a SFP slot
|
|
*
|
|
* @param[in] sfp Handle to SFP data structure
|
|
*
|
|
* @return IPD port number for SFP slot
|
|
*/
|
|
static inline int cvmx_sfp_get_ipd_port(const struct cvmx_fdt_sfp_info *sfp)
|
|
{
|
|
return sfp->ipd_port[0];
|
|
}
|
|
|
|
/**
|
|
* Get the IPD ports for a QSFP port
|
|
*
|
|
* @param[in] sfp Handle to SFP data structure
|
|
* @param[out] ipd_ports IPD ports for each lane, if running as 40G then
|
|
* only ipd_ports[0] is valid and the others will
|
|
* be set to -1.
|
|
*/
|
|
static inline void cvmx_qsfp_get_ipd_ports(const struct cvmx_fdt_sfp_info *sfp, int ipd_ports[4])
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
ipd_ports[i] = sfp->ipd_port[i];
|
|
}
|
|
|
|
/**
|
|
* Attaches a PHY to a SFP or QSFP.
|
|
*
|
|
* @param sfp sfp to attach PHY to
|
|
* @param phy_info phy descriptor to attach or NULL to detach
|
|
*/
|
|
void cvmx_sfp_attach_phy(struct cvmx_fdt_sfp_info *sfp, struct cvmx_phy_info *phy_info);
|
|
|
|
/**
|
|
* Returns a phy descriptor for a SFP slot
|
|
*
|
|
* @param[in] sfp SFP to get phy info from
|
|
*
|
|
* @return phy descriptor or NULL if none.
|
|
*/
|
|
static inline struct cvmx_phy_info *cvmx_sfp_get_phy_info(const struct cvmx_fdt_sfp_info *sfp)
|
|
{
|
|
return sfp->phy_info;
|
|
}
|
|
|
|
/**
|
|
* @INTERNAL
|
|
* Parses all instances of the Vitesse VSC7224 reclocking chip
|
|
*
|
|
* @param[in] fdt_addr Address of flat device tree
|
|
*
|
|
* @return 0 for success, error otherwise
|
|
*/
|
|
int __cvmx_fdt_parse_vsc7224(const void *fdt_addr);
|
|
|
|
/**
|
|
* @INTERNAL
|
|
* Parses all instances of the Avago AVSP5410 gearbox phy
|
|
*
|
|
* @param[in] fdt_addr Address of flat device tree
|
|
*
|
|
* @return 0 for success, error otherwise
|
|
*/
|
|
int __cvmx_fdt_parse_avsp5410(const void *fdt_addr);
|
|
|
|
/**
|
|
* Parse SFP information from device tree
|
|
*
|
|
* @param[in] fdt_addr Address of flat device tree
|
|
*
|
|
* @return pointer to sfp info or NULL if error
|
|
*/
|
|
struct cvmx_fdt_sfp_info *cvmx_helper_fdt_parse_sfp_info(const void *fdt_addr, int of_offset);
|
|
|
|
/**
|
|
* @INTERNAL
|
|
* Parses either a CS4343 phy or a slice of the phy from the device tree
|
|
* @param[in] fdt_addr Address of FDT
|
|
* @param of_offset offset of slice or phy in device tree
|
|
* @param phy_info phy_info data structure to fill in
|
|
*
|
|
* @return 0 for success, -1 on error
|
|
*/
|
|
int cvmx_fdt_parse_cs4343(const void *fdt_addr, int of_offset, struct cvmx_phy_info *phy_info);
|
|
|
|
/**
|
|
* Given an i2c bus and device address, write an 8 bit value
|
|
*
|
|
* @param bus i2c bus number
|
|
* @param addr i2c device address (7 bits)
|
|
* @param val 8-bit value to write
|
|
*
|
|
* This is just an abstraction to ease support in both U-Boot and SE.
|
|
*/
|
|
void cvmx_fdt_i2c_reg_write(int bus, int addr, u8 val);
|
|
|
|
/**
|
|
* Read an 8-bit value from an i2c bus and device address
|
|
*
|
|
* @param bus i2c bus number
|
|
* @param addr i2c device address (7 bits)
|
|
*
|
|
* @return 8-bit value or error if negative
|
|
*/
|
|
int cvmx_fdt_i2c_reg_read(int bus, int addr);
|
|
|
|
/**
|
|
* Write an 8-bit value to a register indexed i2c device
|
|
*
|
|
* @param bus i2c bus number to write to
|
|
* @param addr i2c device address (7 bits)
|
|
* @param reg i2c 8-bit register address
|
|
* @param val 8-bit value to write
|
|
*
|
|
* @return 0 for success, otherwise error
|
|
*/
|
|
int cvmx_fdt_i2c_write8(int bus, int addr, int reg, u8 val);
|
|
|
|
/**
|
|
* Read an 8-bit value from a register indexed i2c device
|
|
*
|
|
* @param bus i2c bus number to write to
|
|
* @param addr i2c device address (7 bits)
|
|
* @param reg i2c 8-bit register address
|
|
*
|
|
* @return value or error if negative
|
|
*/
|
|
int cvmx_fdt_i2c_read8(int bus, int addr, int reg);
|
|
|
|
int cvmx_sfp_vsc7224_mod_abs_changed(struct cvmx_fdt_sfp_info *sfp_info,
|
|
int val, void *data);
|
|
int cvmx_sfp_avsp5410_mod_abs_changed(struct cvmx_fdt_sfp_info *sfp_info,
|
|
int val, void *data);
|
|
|
|
#endif /* CVMX_HELPER_FDT_H__ */
|