1c2e86691STristram Ha /* SPDX-License-Identifier: GPL-2.0 2c2e86691STristram Ha * Microchip switch driver common header 3c2e86691STristram Ha * 47c6ff470STristram Ha * Copyright (C) 2017-2019 Microchip Technology Inc. 5c2e86691STristram Ha */ 6c2e86691STristram Ha 7c2e86691STristram Ha #ifndef __KSZ_COMMON_H 8c2e86691STristram Ha #define __KSZ_COMMON_H 9c2e86691STristram Ha 10ee394feaSMarek Vasut #include <linux/regmap.h> 11ee394feaSMarek Vasut 127049f9b5STristram Ha void ksz_port_cleanup(struct ksz_device *dev, int port); 13c2e86691STristram Ha void ksz_update_port_member(struct ksz_device *dev, int port); 147c6ff470STristram Ha void ksz_init_mib_timer(struct ksz_device *dev); 15c2e86691STristram Ha 16c2e86691STristram Ha /* Common DSA access functions */ 17c2e86691STristram Ha 18c2e86691STristram Ha int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg); 19c2e86691STristram Ha int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val); 20c30d894bSTristram Ha void ksz_adjust_link(struct dsa_switch *ds, int port, 21c30d894bSTristram Ha struct phy_device *phydev); 22c2e86691STristram Ha int ksz_sset_count(struct dsa_switch *ds, int port, int sset); 237c6ff470STristram Ha void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf); 24c2e86691STristram Ha int ksz_port_bridge_join(struct dsa_switch *ds, int port, 25c2e86691STristram Ha struct net_device *br); 26c2e86691STristram Ha void ksz_port_bridge_leave(struct dsa_switch *ds, int port, 27c2e86691STristram Ha struct net_device *br); 28c2e86691STristram Ha void ksz_port_fast_age(struct dsa_switch *ds, int port); 29c2e86691STristram Ha int ksz_port_vlan_prepare(struct dsa_switch *ds, int port, 30c2e86691STristram Ha const struct switchdev_obj_port_vlan *vlan); 31c2e86691STristram Ha int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb, 32c2e86691STristram Ha void *data); 33c2e86691STristram Ha int ksz_port_mdb_prepare(struct dsa_switch *ds, int port, 34c2e86691STristram Ha const struct switchdev_obj_port_mdb *mdb); 35c2e86691STristram Ha void ksz_port_mdb_add(struct dsa_switch *ds, int port, 36c2e86691STristram Ha const struct switchdev_obj_port_mdb *mdb); 37c2e86691STristram Ha int ksz_port_mdb_del(struct dsa_switch *ds, int port, 38c2e86691STristram Ha const struct switchdev_obj_port_mdb *mdb); 39c2e86691STristram Ha int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy); 4075104db0SAndrew Lunn void ksz_disable_port(struct dsa_switch *ds, int port); 41c2e86691STristram Ha 42c2e86691STristram Ha /* Common register access functions */ 43c2e86691STristram Ha 44c2e86691STristram Ha static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) 45c2e86691STristram Ha { 46ee394feaSMarek Vasut unsigned int value; 47ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[0], reg, &value); 48c2e86691STristram Ha 49ee394feaSMarek Vasut *val = value; 50c2e86691STristram Ha return ret; 51c2e86691STristram Ha } 52c2e86691STristram Ha 53c2e86691STristram Ha static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) 54c2e86691STristram Ha { 55ee394feaSMarek Vasut unsigned int value; 56ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[1], reg, &value); 57c2e86691STristram Ha 58ee394feaSMarek Vasut *val = value; 59c2e86691STristram Ha return ret; 60c2e86691STristram Ha } 61c2e86691STristram Ha 62c2e86691STristram Ha static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val) 63c2e86691STristram Ha { 64ee394feaSMarek Vasut unsigned int value; 65ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[2], reg, &value); 66c2e86691STristram Ha 67ee394feaSMarek Vasut *val = value; 68c2e86691STristram Ha return ret; 69c2e86691STristram Ha } 70c2e86691STristram Ha 71*e66f840cSTristram Ha static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) 72*e66f840cSTristram Ha { 73*e66f840cSTristram Ha u32 value[2]; 74*e66f840cSTristram Ha int ret; 75*e66f840cSTristram Ha 76*e66f840cSTristram Ha ret = regmap_bulk_read(dev->regmap[2], reg, value, 2); 77*e66f840cSTristram Ha if (!ret) { 78*e66f840cSTristram Ha /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */ 79*e66f840cSTristram Ha value[0] = swab32(value[0]); 80*e66f840cSTristram Ha value[1] = swab32(value[1]); 81*e66f840cSTristram Ha *val = swab64((u64)*value); 82*e66f840cSTristram Ha } 83*e66f840cSTristram Ha 84*e66f840cSTristram Ha return ret; 85*e66f840cSTristram Ha } 86*e66f840cSTristram Ha 87c2e86691STristram Ha static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value) 88c2e86691STristram Ha { 89ee394feaSMarek Vasut return regmap_write(dev->regmap[0], reg, value); 90c2e86691STristram Ha } 91c2e86691STristram Ha 92c2e86691STristram Ha static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value) 93c2e86691STristram Ha { 94ee394feaSMarek Vasut return regmap_write(dev->regmap[1], reg, value); 95c2e86691STristram Ha } 96c2e86691STristram Ha 97c2e86691STristram Ha static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value) 98c2e86691STristram Ha { 99ee394feaSMarek Vasut return regmap_write(dev->regmap[2], reg, value); 100c2e86691STristram Ha } 101c2e86691STristram Ha 102*e66f840cSTristram Ha static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value) 103*e66f840cSTristram Ha { 104*e66f840cSTristram Ha u32 val[2]; 105*e66f840cSTristram Ha 106*e66f840cSTristram Ha /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */ 107*e66f840cSTristram Ha value = swab64(value); 108*e66f840cSTristram Ha val[0] = swab32(value & 0xffffffffULL); 109*e66f840cSTristram Ha val[1] = swab32(value >> 32ULL); 110*e66f840cSTristram Ha 111*e66f840cSTristram Ha return regmap_bulk_write(dev->regmap[2], reg, val, 2); 112*e66f840cSTristram Ha } 113*e66f840cSTristram Ha 114c2e86691STristram Ha static inline void ksz_pread8(struct ksz_device *dev, int port, int offset, 115c2e86691STristram Ha u8 *data) 116c2e86691STristram Ha { 117c2e86691STristram Ha ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data); 118c2e86691STristram Ha } 119c2e86691STristram Ha 120c2e86691STristram Ha static inline void ksz_pread16(struct ksz_device *dev, int port, int offset, 121c2e86691STristram Ha u16 *data) 122c2e86691STristram Ha { 123c2e86691STristram Ha ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data); 124c2e86691STristram Ha } 125c2e86691STristram Ha 126c2e86691STristram Ha static inline void ksz_pread32(struct ksz_device *dev, int port, int offset, 127c2e86691STristram Ha u32 *data) 128c2e86691STristram Ha { 129c2e86691STristram Ha ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data); 130c2e86691STristram Ha } 131c2e86691STristram Ha 132c2e86691STristram Ha static inline void ksz_pwrite8(struct ksz_device *dev, int port, int offset, 133c2e86691STristram Ha u8 data) 134c2e86691STristram Ha { 135c2e86691STristram Ha ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data); 136c2e86691STristram Ha } 137c2e86691STristram Ha 138c2e86691STristram Ha static inline void ksz_pwrite16(struct ksz_device *dev, int port, int offset, 139c2e86691STristram Ha u16 data) 140c2e86691STristram Ha { 141c2e86691STristram Ha ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), data); 142c2e86691STristram Ha } 143c2e86691STristram Ha 144c2e86691STristram Ha static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset, 145c2e86691STristram Ha u32 data) 146c2e86691STristram Ha { 147c2e86691STristram Ha ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data); 148c2e86691STristram Ha } 149c2e86691STristram Ha 150255b59adSMarek Vasut /* Regmap tables generation */ 151255b59adSMarek Vasut #define KSZ_SPI_OP_RD 3 152255b59adSMarek Vasut #define KSZ_SPI_OP_WR 2 153255b59adSMarek Vasut 154255b59adSMarek Vasut #define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad) \ 155255b59adSMarek Vasut swab##swp((opcode) << ((regbits) + (regpad))) 156255b59adSMarek Vasut 157255b59adSMarek Vasut #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign) \ 158255b59adSMarek Vasut { \ 159255b59adSMarek Vasut .val_bits = (width), \ 160255b59adSMarek Vasut .reg_stride = (width) / 8, \ 161255b59adSMarek Vasut .reg_bits = (regbits) + (regalign), \ 162255b59adSMarek Vasut .pad_bits = (regpad), \ 163255b59adSMarek Vasut .max_register = BIT(regbits) - 1, \ 164255b59adSMarek Vasut .cache_type = REGCACHE_NONE, \ 165255b59adSMarek Vasut .read_flag_mask = \ 166255b59adSMarek Vasut KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp, \ 167255b59adSMarek Vasut regbits, regpad), \ 168255b59adSMarek Vasut .write_flag_mask = \ 169255b59adSMarek Vasut KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \ 170255b59adSMarek Vasut regbits, regpad), \ 171255b59adSMarek Vasut .reg_format_endian = REGMAP_ENDIAN_BIG, \ 172255b59adSMarek Vasut .val_format_endian = REGMAP_ENDIAN_BIG \ 173255b59adSMarek Vasut } 174255b59adSMarek Vasut 175255b59adSMarek Vasut #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \ 176255b59adSMarek Vasut static const struct regmap_config ksz##_regmap_config[] = { \ 177255b59adSMarek Vasut KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \ 178255b59adSMarek Vasut KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \ 179255b59adSMarek Vasut KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \ 180255b59adSMarek Vasut } 181255b59adSMarek Vasut 182c2e86691STristram Ha #endif 183