1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2009-2016 Cavium, Inc. 4 */ 5 6 enum cavium_mdiobus_mode { 7 UNINIT = 0, 8 C22, 9 C45 10 }; 11 12 #define SMI_CMD 0x0 13 #define SMI_WR_DAT 0x8 14 #define SMI_RD_DAT 0x10 15 #define SMI_CLK 0x18 16 #define SMI_EN 0x20 17 18 #ifdef __BIG_ENDIAN_BITFIELD 19 #define OCT_MDIO_BITFIELD_FIELD(field, more) \ 20 field; \ 21 more 22 23 #else 24 #define OCT_MDIO_BITFIELD_FIELD(field, more) \ 25 more \ 26 field; 27 28 #endif 29 30 union cvmx_smix_clk { 31 u64 u64; 32 struct cvmx_smix_clk_s { 33 OCT_MDIO_BITFIELD_FIELD(u64 reserved_25_63:39, 34 OCT_MDIO_BITFIELD_FIELD(u64 mode:1, 35 OCT_MDIO_BITFIELD_FIELD(u64 reserved_21_23:3, 36 OCT_MDIO_BITFIELD_FIELD(u64 sample_hi:5, 37 OCT_MDIO_BITFIELD_FIELD(u64 sample_mode:1, 38 OCT_MDIO_BITFIELD_FIELD(u64 reserved_14_14:1, 39 OCT_MDIO_BITFIELD_FIELD(u64 clk_idle:1, 40 OCT_MDIO_BITFIELD_FIELD(u64 preamble:1, 41 OCT_MDIO_BITFIELD_FIELD(u64 sample:4, 42 OCT_MDIO_BITFIELD_FIELD(u64 phase:8, 43 ;)))))))))) 44 } s; 45 }; 46 47 union cvmx_smix_cmd { 48 u64 u64; 49 struct cvmx_smix_cmd_s { 50 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46, 51 OCT_MDIO_BITFIELD_FIELD(u64 phy_op:2, 52 OCT_MDIO_BITFIELD_FIELD(u64 reserved_13_15:3, 53 OCT_MDIO_BITFIELD_FIELD(u64 phy_adr:5, 54 OCT_MDIO_BITFIELD_FIELD(u64 reserved_5_7:3, 55 OCT_MDIO_BITFIELD_FIELD(u64 reg_adr:5, 56 ;)))))) 57 } s; 58 }; 59 60 union cvmx_smix_en { 61 u64 u64; 62 struct cvmx_smix_en_s { 63 OCT_MDIO_BITFIELD_FIELD(u64 reserved_1_63:63, 64 OCT_MDIO_BITFIELD_FIELD(u64 en:1, 65 ;)) 66 } s; 67 }; 68 69 union cvmx_smix_rd_dat { 70 u64 u64; 71 struct cvmx_smix_rd_dat_s { 72 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46, 73 OCT_MDIO_BITFIELD_FIELD(u64 pending:1, 74 OCT_MDIO_BITFIELD_FIELD(u64 val:1, 75 OCT_MDIO_BITFIELD_FIELD(u64 dat:16, 76 ;)))) 77 } s; 78 }; 79 80 union cvmx_smix_wr_dat { 81 u64 u64; 82 struct cvmx_smix_wr_dat_s { 83 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46, 84 OCT_MDIO_BITFIELD_FIELD(u64 pending:1, 85 OCT_MDIO_BITFIELD_FIELD(u64 val:1, 86 OCT_MDIO_BITFIELD_FIELD(u64 dat:16, 87 ;)))) 88 } s; 89 }; 90 91 struct cavium_mdiobus { 92 struct mii_bus *mii_bus; 93 void __iomem *register_base; 94 enum cavium_mdiobus_mode mode; 95 }; 96 97 #ifdef CONFIG_CAVIUM_OCTEON_SOC 98 99 #include <asm/octeon/octeon.h> 100 101 static inline void oct_mdio_writeq(u64 val, void __iomem *addr) 102 { 103 cvmx_write_csr((u64 __force)addr, val); 104 } 105 106 static inline u64 oct_mdio_readq(void __iomem *addr) 107 { 108 return cvmx_read_csr((u64 __force)addr); 109 } 110 #else 111 #include <linux/io-64-nonatomic-lo-hi.h> 112 113 #define oct_mdio_writeq(val, addr) writeq(val, addr) 114 #define oct_mdio_readq(addr) readq(addr) 115 #endif 116 117 int cavium_mdiobus_read_c22(struct mii_bus *bus, int phy_id, int regnum); 118 int cavium_mdiobus_write_c22(struct mii_bus *bus, int phy_id, int regnum, 119 u16 val); 120 int cavium_mdiobus_read_c45(struct mii_bus *bus, int phy_id, int devad, 121 int regnum); 122 int cavium_mdiobus_write_c45(struct mii_bus *bus, int phy_id, int devad, 123 int regnum, u16 val); 124