This patch includes misc changes to already present Octeon MIPS header files, which are necessary for the upcoming ethernet support.
The changes are mostly: - DM GPIO & I2C infrastructure - Coding style cleanup while reworking the headers Signed-off-by: Stefan Roese <s...@denx.de> --- .../mach-octeon/include/mach/cvmx-bootmem.h | 3 +- arch/mips/mach-octeon/include/mach/cvmx-fpa.h | 3 +- .../mips/mach-octeon/include/mach/cvmx-fpa3.h | 37 ------- .../include/mach/cvmx-helper-board.h | 6 +- .../include/mach/cvmx-helper-fdt.h | 40 +++---- .../include/mach/cvmx-helper-pko.h | 2 +- .../mach-octeon/include/mach/cvmx-helper.h | 20 ++++ .../mips/mach-octeon/include/mach/cvmx-regs.h | 100 ++++++++++++++++-- .../mach-octeon/include/mach/octeon_eth.h | 54 +++++----- 9 files changed, 166 insertions(+), 99 deletions(-) diff --git a/arch/mips/mach-octeon/include/mach/cvmx-bootmem.h b/arch/mips/mach-octeon/include/mach/cvmx-bootmem.h index 283ac5c6bb56..d5c004d017ef 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-bootmem.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-bootmem.h @@ -26,7 +26,8 @@ /* Real physical addresses of memory regions */ #define OCTEON_DDR0_BASE (0x0ULL) -#define OCTEON_DDR0_SIZE (0x010000000ULL) +/* Use 16MiB here, as 256 leads to overwriting U-Boot reloc space */ +#define OCTEON_DDR0_SIZE (0x001000000ULL) #define OCTEON_DDR1_BASE ((OCTEON_IS_OCTEON2() || OCTEON_IS_OCTEON3()) \ ? 0x20000000ULL : 0x410000000ULL) #define OCTEON_DDR1_SIZE (0x010000000ULL) diff --git a/arch/mips/mach-octeon/include/mach/cvmx-fpa.h b/arch/mips/mach-octeon/include/mach/cvmx-fpa.h index aa238a885072..0660c31b4f59 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-fpa.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-fpa.h @@ -104,8 +104,9 @@ static inline void *cvmx_fpa_alloc(u64 pool) /* FPA3 is handled differently */ if ((octeon_has_feature(OCTEON_FEATURE_FPA3))) { return cvmx_fpa3_alloc(cvmx_fpa1_pool_to_fpa3_aura(pool)); - } else + } else { return cvmx_fpa1_alloc(pool); + } } /** diff --git a/arch/mips/mach-octeon/include/mach/cvmx-fpa3.h b/arch/mips/mach-octeon/include/mach/cvmx-fpa3.h index b3e04d7f02a1..9bab03f59a09 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-fpa3.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-fpa3.h @@ -526,41 +526,4 @@ const char *cvmx_fpa3_get_pool_name(cvmx_fpa3_pool_t pool); int cvmx_fpa3_get_pool_buf_size(cvmx_fpa3_pool_t pool); const char *cvmx_fpa3_get_aura_name(cvmx_fpa3_gaura_t aura); -/* FIXME: Need a different macro for stage2 of u-boot */ - -static inline void cvmx_fpa3_stage2_init(int aura, int pool, u64 stack_paddr, int stacklen, - int buffer_sz, int buf_cnt) -{ - cvmx_fpa_poolx_cfg_t pool_cfg; - - /* Configure pool stack */ - cvmx_write_csr_node(0, CVMX_FPA_POOLX_STACK_BASE(pool), stack_paddr); - cvmx_write_csr_node(0, CVMX_FPA_POOLX_STACK_ADDR(pool), stack_paddr); - cvmx_write_csr_node(0, CVMX_FPA_POOLX_STACK_END(pool), stack_paddr + stacklen); - - /* Configure pool with buffer size */ - pool_cfg.u64 = 0; - pool_cfg.cn78xx.nat_align = 1; - pool_cfg.cn78xx.buf_size = buffer_sz >> 7; - pool_cfg.cn78xx.l_type = 0x2; - pool_cfg.cn78xx.ena = 0; - cvmx_write_csr_node(0, CVMX_FPA_POOLX_CFG(pool), pool_cfg.u64); - /* Reset pool before starting */ - pool_cfg.cn78xx.ena = 1; - cvmx_write_csr_node(0, CVMX_FPA_POOLX_CFG(pool), pool_cfg.u64); - - cvmx_write_csr_node(0, CVMX_FPA_AURAX_CFG(aura), 0); - cvmx_write_csr_node(0, CVMX_FPA_AURAX_CNT_ADD(aura), buf_cnt); - cvmx_write_csr_node(0, CVMX_FPA_AURAX_POOL(aura), (u64)pool); -} - -static inline void cvmx_fpa3_stage2_disable(int aura, int pool) -{ - cvmx_write_csr_node(0, CVMX_FPA_AURAX_POOL(aura), 0); - cvmx_write_csr_node(0, CVMX_FPA_POOLX_CFG(pool), 0); - cvmx_write_csr_node(0, CVMX_FPA_POOLX_STACK_BASE(pool), 0); - cvmx_write_csr_node(0, CVMX_FPA_POOLX_STACK_ADDR(pool), 0); - cvmx_write_csr_node(0, CVMX_FPA_POOLX_STACK_END(pool), 0); -} - #endif /* __CVMX_FPA3_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-board.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-board.h index 5837592d21aa..9cc61b1a350e 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-helper-board.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-board.h @@ -9,6 +9,8 @@ #ifndef __CVMX_HELPER_BOARD_H__ #define __CVMX_HELPER_BOARD_H__ +#include <asm-generic/gpio.h> + #define CVMX_VSC7224_NAME_LEN 16 typedef enum { @@ -185,8 +187,8 @@ struct cvmx_vsc7224 { struct cvmx_fdt_i2c_bus_info *i2c_bus; /** Address of VSC7224 on i2c bus */ int i2c_addr; - struct cvmx_fdt_gpio_info *los_gpio; /** LoS GPIO pin */ - struct cvmx_fdt_gpio_info *reset_gpio; /** Reset GPIO pin */ + struct gpio_desc los_gpio; /** LoS GPIO pin */ + struct gpio_desc reset_gpio; /** Reset GPIO pin */ int of_offset; /** Offset in device tree */ }; diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h index 332884557031..c3ce35958372 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h @@ -14,10 +14,13 @@ #include <fdtdec.h> #include <time.h> #include <asm/global_data.h> +#include <asm-generic/gpio.h> +#include <dm/device.h> #include <linux/libfdt.h> #include <mach/cvmx-helper-sfp.h> +/* todo: this is deprecated and some of it can be removed at some time */ enum cvmx_i2c_bus_type { CVMX_I2C_BUS_OCTEON, CVMX_I2C_MUX_PCA9540, @@ -55,6 +58,8 @@ struct cvmx_fdt_i2c_bus_info { u8 enable_bit; /** True if mux, false if switch */ bool is_mux; + + struct udevice *i2c_bus; }; /** @@ -85,22 +90,24 @@ struct cvmx_fdt_sfp_info { bool is_qsfp; /** True if EEPROM data is valid */ bool valid; + /** SFP tx_disable GPIO descriptor */ - struct cvmx_fdt_gpio_info *tx_disable; + struct gpio_desc tx_disable; /** SFP mod_abs/QSFP mod_prs GPIO descriptor */ - struct cvmx_fdt_gpio_info *mod_abs; + struct gpio_desc mod_abs; /** SFP tx_error GPIO descriptor */ - struct cvmx_fdt_gpio_info *tx_error; + struct gpio_desc tx_error; /** SFP rx_los GPIO discriptor */ - struct cvmx_fdt_gpio_info *rx_los; + struct gpio_desc rx_los; /** QSFP select GPIO descriptor */ - struct cvmx_fdt_gpio_info *select; + struct gpio_desc select; /** QSFP reset GPIO descriptor */ - struct cvmx_fdt_gpio_info *reset; + struct gpio_desc reset; /** QSFP interrupt GPIO descriptor */ - struct cvmx_fdt_gpio_info *interrupt; + struct gpio_desc interrupt; /** QSFP lp_mode GPIO descriptor */ - struct cvmx_fdt_gpio_info *lp_mode; + struct gpio_desc lp_mode; + /** Last mod_abs value */ int last_mod_abs; /** Last rx_los value */ @@ -146,6 +153,9 @@ struct cvmx_fdt_sfp_info { int cvmx_fdt_lookup_phandles(const void *fdt_addr, int node, const char *prop_name, int *lenp, int *nodes); +int cvmx_ofnode_lookup_phandles(ofnode node, const char *prop_name, + int *lenp, ofnode *nodes); + /** * Helper to return the address property * @@ -341,8 +351,7 @@ int cvmx_fdt_node_offset_by_compatible_list(const void *fdt_addr, int startoffse * 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 + * @param[in] node ofnode of the parent node of a GPIO device in * the device tree. * * Return: pointer to list of i2c devices starting from the root which @@ -351,7 +360,7 @@ int cvmx_fdt_node_offset_by_compatible_list(const void *fdt_addr, int startoffse * * @see cvmx_fdt_free_i2c_bus() */ -struct cvmx_fdt_i2c_bus_info *cvmx_fdt_get_i2c_bus(const void *fdt_addr, int of_offset); +struct cvmx_fdt_i2c_bus_info *cvmx_ofnode_get_i2c_bus(ofnode node); /** * Return the Octeon bus number for a bus descriptor @@ -496,15 +505,6 @@ int __cvmx_fdt_parse_vsc7224(const void *fdt_addr); */ 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 diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h index 806102df2243..e1eb824c9346 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h @@ -17,7 +17,7 @@ * number. Users should set this pointer to a function before * calling any cvmx-helper operations. */ -void (*cvmx_override_pko_queue_priority)(int ipd_port, u8 *priorities); +extern void (*cvmx_override_pko_queue_priority)(int ipd_port, u8 *priorities); /** * Gets the fpa pool number of pko pool diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper.h b/arch/mips/mach-octeon/include/mach/cvmx-helper.h index caa0c69fc05e..2a7b13322db2 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-helper.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper.h @@ -127,6 +127,26 @@ enum cvmx_pko_padding { CVMX_PKO_PADDING_60 = 1, }; +/** + * cvmx_override_iface_phy_mode(int interface, int index) is a function pointer. + * It is meant to allow customization of interfaces which do not have a PHY. + * + * @returns 0 if MAC decides TX_CONFIG_REG or 1 if PHY decides TX_CONFIG_REG. + * + * If this function pointer is NULL then it defaults to the MAC. + */ +extern int (*cvmx_override_iface_phy_mode) (int interface, int index); + +/** + * cvmx_override_ipd_port_setup(int ipd_port) is a function + * pointer. It is meant to allow customization of the IPD port/port kind + * setup before packet input/output comes online. It is called + * after cvmx-helper does the default IPD configuration, but + * before IPD is enabled. Users should set this pointer to a + * function before calling any cvmx-helper operations. + */ +extern void (*cvmx_override_ipd_port_setup) (int ipd_port); + /** * This function enables the IPD and also enables the packet interfaces. * The packet interfaces (RGMII and SPI) must be enabled after the diff --git a/arch/mips/mach-octeon/include/mach/cvmx-regs.h b/arch/mips/mach-octeon/include/mach/cvmx-regs.h index dbb77232e262..f97c1e907f0b 100644 --- a/arch/mips/mach-octeon/include/mach/cvmx-regs.h +++ b/arch/mips/mach-octeon/include/mach/cvmx-regs.h @@ -6,6 +6,7 @@ #ifndef __CVMX_REGS_H__ #define __CVMX_REGS_H__ +#include <log.h> #include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/io.h> @@ -32,6 +33,7 @@ /* Regs */ #define CVMX_CIU3_NMI 0x0001010000000160ULL +#define CVMX_CIU3_ISCX_W1C(x) (0x0001010090000000ull + ((x) & 1048575) * 8) #define CVMX_MIO_BOOT_LOC_CFGX(x) (0x0001180000000080ULL + ((x) & 1) * 8) #define MIO_BOOT_LOC_CFG_BASE GENMASK_ULL(27, 3) @@ -55,11 +57,19 @@ #define CVMX_RNM_CTL_STATUS 0x0001180040000000ULL #define RNM_CTL_STATUS_EER_VAL BIT_ULL(9) +/* IOBDMA/LMTDMA IO addresses */ +#define CVMX_LMTDMA_ORDERED_IO_ADDR 0xffffffffffffa400ull #define CVMX_IOBDMA_ORDERED_IO_ADDR 0xffffffffffffa200ull /* turn the variable name into a string */ #define CVMX_TMP_STR(x) CVMX_TMP_STR2(x) #define CVMX_TMP_STR2(x) #x +#define VASTR(...) #__VA_ARGS__ + +#define CVMX_PKO_LMTLINE 2ull +#define CVMX_SCRATCH_BASE (-32768l) /* 0xffffffffffff8000 */ + +#define COP0_CVMMEMCTL $11,7 /* Cavium memory control */ #define CVMX_RDHWR(result, regstr) \ asm volatile("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d"(result)) @@ -67,6 +77,13 @@ asm("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d"(result)) #define CVMX_POP(result, input) \ asm("pop %[rd],%[rs]" : [rd] "=d"(result) : [rs] "d"(input)) +#define CVMX_MF_COP0(val, cop0) \ + asm("dmfc0 %[rt]," VASTR(cop0) : [rt] "=d" (val)) +#define CVMX_MT_COP0(val, cop0) \ + asm("dmtc0 %[rt]," VASTR(cop0) : : [rt] "d" (val)) + +#define CVMX_MF_CVM_MEM_CTL(val) CVMX_MF_COP0(val, COP0_CVMMEMCTL) +#define CVMX_MT_CVM_MEM_CTL(val) CVMX_MT_COP0(val, COP0_CVMMEMCTL) #define CVMX_SYNC asm volatile("sync\n" : : : "memory") #define CVMX_SYNCW asm volatile("syncw\nsyncw\n" : : : "memory") @@ -81,6 +98,18 @@ #define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30) +#define CVMX_PREFETCH0(address) CVMX_PREFETCH(address, 0) +#define CVMX_PREFETCH128(address) CVMX_PREFETCH(address, 128) + +/** a normal prefetch */ +#define CVMX_PREFETCH(address, offset) CVMX_PREFETCH_PREF0(address, offset) + +/** normal prefetches that use the pref instruction */ +#define CVMX_PREFETCH_PREFX(X, address, offset) \ + asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (X)) +#define CVMX_PREFETCH_PREF0(address, offset) \ + CVMX_PREFETCH_PREFX(0, address, offset) + /* * The macros cvmx_likely and cvmx_unlikely use the * __builtin_expect GCC operation to control branch @@ -405,6 +434,30 @@ static inline unsigned int cvmx_get_local_core_num(void) return core_num & core_mask; } +/** + * Given a CSR address return the node number of that address + * + * @param addr Address to extract node number from + * + * @return node number + */ +static inline u8 cvmx_csr_addr_to_node(u64 addr) +{ + return (addr >> CVMX_NODE_IO_SHIFT) & CVMX_NODE_MASK; +} + +/** + * Strip the node address bits from a CSR address + * + * @param addr CSR address to strip the node bits from + * + * @return CSR address with the node bits set to zero + */ +static inline u64 cvmx_csr_addr_strip_node(u64 addr) +{ + return addr & ~((u64)CVMX_NODE_MASK << CVMX_NODE_IO_SHIFT); +} + /** * Returns the number of bits set in the provided value. * Simple wrapper for POP instruction. @@ -428,14 +481,45 @@ static inline u32 cvmx_pop(u32 val) #define cvmx_printf printf #define cvmx_vprintf vprintf -#if defined(DEBUG) -void cvmx_warn(const char *format, ...) __printf(1, 2); -#else -void cvmx_warn(const char *format, ...); -#endif +/* Use common debug macros */ +#define cvmx_warn debug +#define cvmx_warn_if debug_cond + +/** + * Atomically adds a signed value to a 32 bit (aligned) memory location, + * and returns previous value. + * + * Memory access ordering is enforced before/after the atomic operation, + * so no additional 'sync' instructions are required. + * + * @param ptr address in memory to add incr to + * @param incr amount to increment memory location by (signed) + * + * @return Value of memory location before increment + */ +static inline int32_t cvmx_atomic_fetch_and_add32(int32_t * ptr, int32_t incr) +{ + int32_t val; -#define cvmx_warn_if(expression, format, ...) \ - if (expression) \ - cvmx_warn(format, ##__VA_ARGS__) + val = *ptr; + *ptr += incr; + return val; +} + +/** + * Atomically adds a signed value to a 32 bit (aligned) memory location. + * + * This version does not perform 'sync' operations to enforce memory + * operations. This should only be used when there are no memory operation + * ordering constraints. (This should NOT be used for reference counting - + * use the standard version instead.) + * + * @param ptr address in memory to add incr to + * @param incr amount to increment memory location by (signed) + */ +static inline void cvmx_atomic_add32_nosync(int32_t * ptr, int32_t incr) +{ + *ptr += incr; +} #endif /* __CVMX_REGS_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/octeon_eth.h b/arch/mips/mach-octeon/include/mach/octeon_eth.h index 096fcfbfcfaa..83e62075ed9f 100644 --- a/arch/mips/mach-octeon/include/mach/octeon_eth.h +++ b/arch/mips/mach-octeon/include/mach/octeon_eth.h @@ -1,17 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (C) 2020 Marvell International Ltd. + * Copyright (C) 2020-2022 Marvell International Ltd. */ #ifndef __OCTEON_ETH_H__ #define __OCTEON_ETH_H__ -#include <phy.h> -#include <miiphy.h> - #include <mach/cvmx-helper.h> #include <mach/cvmx-helper-board.h> -#include <mach/octeon_fdt.h> struct eth_device; @@ -27,33 +23,25 @@ struct octeon_eth_info { struct phy_device *phydev; /** PHY device */ struct eth_device *ethdev; /** Eth device this priv is part of */ int mii_addr; - int phy_fdt_offset; /** Offset of PHY info in device tree */ - int fdt_offset; /** Offset of Eth interface in DT */ - int phy_offset; /** Offset of PHY dev in device tree */ + int phy_fdt_offset; /** Offset of PHY info in device tree */ + int fdt_offset; /** Offset of Eth interface in DT */ + int phy_offset; /** Offset of PHY device in device tree */ enum cvmx_phy_type phy_device_type; /** Type of PHY */ /* current link status, use to reconfigure on status changes */ u64 packets_sent; u64 packets_received; - u32 link_speed : 2; - u32 link_duplex : 1; - u32 link_status : 1; - u32 loopback : 1; - u32 enabled : 1; - u32 is_c45 : 1; /** Set if we need to use clause 45 */ - u32 vitesse_sfp_config : 1; /** Need Vitesse SFP config */ - u32 ti_gpio_config : 1; /** Need TI GPIO config */ - u32 bgx_mac_set : 1; /** Has the BGX MAC been set already */ - u64 last_bgx_mac; /** Last BGX MAC address set */ - u64 gmx_base; /** Base address to access GMX CSRs */ - bool mod_abs; /** True if module is absent */ - - /** - * User defined function to check if a SFP+ module is absent or not. - * - * @param dev Ethernet device - * @param data User supplied data - */ - int (*check_mod_abs)(struct eth_device *dev, void *data); + uint32_t link_speed : 2; + uint32_t link_duplex : 1; + uint32_t link_status : 1; + uint32_t loopback : 1; + uint32_t enabled : 1; + uint32_t is_c45 : 1; /** Set if we need to use clause 45 */ + uint32_t vitesse_sfp_config : 1; /** Need Vitesse SFP config */ + uint32_t ti_gpio_config : 1; /** Need TI GPIO configuration */ + uint32_t bgx_mac_set : 1; /** Has the BGX MAC been set already */ + u64 last_bgx_mac; /** Last BGX MAC address set */ + u64 gmx_base; /** Base address to access GMX CSRs */ + bool mod_abs; /** True if module is absent */ /** User supplied data for check_mod_abs */ void *mod_abs_data; @@ -71,12 +59,20 @@ struct octeon_eth_info { * @return 0 for success, otherwise error */ int (*mod_abs_changed)(struct eth_device *dev, bool mod_abs); + /** SDK phy information data structure */ cvmx_phy_info_t phy_info; + + struct udevice *mdio_dev; + struct mii_dev *bus; + struct phy_device *phy_dev; + #ifdef CONFIG_OCTEON_SFP /** Information about connected SFP/SFP+/SFP28/QSFP+/QSFP28 module */ struct octeon_sfp_info sfp; #endif + + cvmx_wqe_t *work; }; /** @@ -136,6 +132,6 @@ void octeon_eth_register_mod_abs_changed(struct eth_device *dev, * * NOTE: If the module state is changed then the module callback is called. */ -void octeon_phy_port_check(struct eth_device *dev); +void octeon_phy_port_check(struct udevice *dev); #endif /* __OCTEON_ETH_H__ */ -- 2.35.1