From 98036b0d70364cb62d9b1937b30d5994ed83f7b5 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 7 Apr 2022 09:11:10 +0200 Subject: [PATCH] mips: octeon: Misc changes to existing headers for upcoming eth support 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 --- .../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 283ac5c6bb..d5c004d017 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 aa238a8850..0660c31b4f 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 b3e04d7f02..9bab03f59a 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 5837592d21..9cc61b1a35 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 + #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 3328845570..c3ce359583 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 #include #include +#include +#include #include #include +/* 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 806102df22..e1eb824c93 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 caa0c69fc0..2a7b13322d 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 dbb77232e2..f97c1e907f 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 #include #include #include @@ -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 096fcfbfcf..83e62075ed 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 -#include - #include #include -#include 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.39.5