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