mips: octeon: Misc changes to existing headers for upcoming eth support
authorStefan Roese <sr@denx.de>
Thu, 7 Apr 2022 07:11:10 +0000 (09:11 +0200)
committerStefan Roese <sr@denx.de>
Wed, 4 May 2022 01:38:20 +0000 (03:38 +0200)
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 <sr@denx.de>
arch/mips/mach-octeon/include/mach/cvmx-bootmem.h
arch/mips/mach-octeon/include/mach/cvmx-fpa.h
arch/mips/mach-octeon/include/mach/cvmx-fpa3.h
arch/mips/mach-octeon/include/mach/cvmx-helper-board.h
arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h
arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h
arch/mips/mach-octeon/include/mach/cvmx-helper.h
arch/mips/mach-octeon/include/mach/cvmx-regs.h
arch/mips/mach-octeon/include/mach/octeon_eth.h

index 283ac5c..d5c004d 100644 (file)
@@ -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)
index aa238a8..0660c31 100644 (file)
@@ -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);
+       }
 }
 
 /**
index b3e04d7..9bab03f 100644 (file)
@@ -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__ */
index 5837592..9cc61b1 100644 (file)
@@ -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 */
 };
 
index 3328845..c3ce359 100644 (file)
 #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
@@ -497,15 +506,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
  * @param[in]  fdt_addr        Address of FDT
index 806102d..e1eb824 100644 (file)
@@ -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
index caa0c69..2a7b133 100644 (file)
@@ -128,6 +128,26 @@ enum cvmx_pko_padding {
 };
 
 /**
+ * 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
  * IPD.  This should be called by the user program after any additional
index dbb7723..f97c1e9 100644 (file)
@@ -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)
 #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))
        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")
 
 #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
@@ -406,6 +435,30 @@ static inline unsigned int cvmx_get_local_core_num(void)
 }
 
 /**
+ * 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__ */
index 096fcfb..83e6207 100644 (file)
@@ -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__ */