| 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 | |