1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2009-2016 Cavium, Inc.
4 */
5
6enum 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
30union 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
47union 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
60union 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
69union 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
80union 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
91struct 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
101static inline void oct_mdio_writeq(u64 val, void __iomem *addr)
102{
103	cvmx_write_csr((u64 __force)addr, val);
104}
105
106static 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
117int cavium_mdiobus_read_c22(struct mii_bus *bus, int phy_id, int regnum);
118int cavium_mdiobus_write_c22(struct mii_bus *bus, int phy_id, int regnum,
119			     u16 val);
120int cavium_mdiobus_read_c45(struct mii_bus *bus, int phy_id, int devad,
121			    int regnum);
122int cavium_mdiobus_write_c45(struct mii_bus *bus, int phy_id, int devad,
123			     int regnum, u16 val);
124