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