1a605ea7eSDirk Eibach /*
2a605ea7eSDirk Eibach * (C) Copyright 2010
3a605ea7eSDirk Eibach * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
4a605ea7eSDirk Eibach *
5*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
6a605ea7eSDirk Eibach */
7a605ea7eSDirk Eibach
8a605ea7eSDirk Eibach #include <common.h>
9a605ea7eSDirk Eibach #include <miiphy.h>
10a605ea7eSDirk Eibach
11a605ea7eSDirk Eibach #include <asm/io.h>
12a605ea7eSDirk Eibach
13255ef4d9SDirk Eibach struct io_bb_pinset {
14255ef4d9SDirk Eibach int mdio;
15255ef4d9SDirk Eibach int mdc;
16255ef4d9SDirk Eibach };
17255ef4d9SDirk Eibach
io_bb_mii_init(struct bb_miiphy_bus * bus)18a605ea7eSDirk Eibach static int io_bb_mii_init(struct bb_miiphy_bus *bus)
19a605ea7eSDirk Eibach {
20a605ea7eSDirk Eibach return 0;
21a605ea7eSDirk Eibach }
22a605ea7eSDirk Eibach
io_bb_mdio_active(struct bb_miiphy_bus * bus)23a605ea7eSDirk Eibach static int io_bb_mdio_active(struct bb_miiphy_bus *bus)
24a605ea7eSDirk Eibach {
25255ef4d9SDirk Eibach struct io_bb_pinset *pins = bus->priv;
26255ef4d9SDirk Eibach
27a605ea7eSDirk Eibach out_be32((void *)GPIO0_TCR,
28255ef4d9SDirk Eibach in_be32((void *)GPIO0_TCR) | pins->mdio);
29a605ea7eSDirk Eibach
30a605ea7eSDirk Eibach return 0;
31a605ea7eSDirk Eibach }
32a605ea7eSDirk Eibach
io_bb_mdio_tristate(struct bb_miiphy_bus * bus)33a605ea7eSDirk Eibach static int io_bb_mdio_tristate(struct bb_miiphy_bus *bus)
34a605ea7eSDirk Eibach {
35255ef4d9SDirk Eibach struct io_bb_pinset *pins = bus->priv;
36255ef4d9SDirk Eibach
37a605ea7eSDirk Eibach out_be32((void *)GPIO0_TCR,
38255ef4d9SDirk Eibach in_be32((void *)GPIO0_TCR) & ~pins->mdio);
39a605ea7eSDirk Eibach
40a605ea7eSDirk Eibach return 0;
41a605ea7eSDirk Eibach }
42a605ea7eSDirk Eibach
io_bb_set_mdio(struct bb_miiphy_bus * bus,int v)43a605ea7eSDirk Eibach static int io_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
44a605ea7eSDirk Eibach {
45255ef4d9SDirk Eibach struct io_bb_pinset *pins = bus->priv;
46255ef4d9SDirk Eibach
47a605ea7eSDirk Eibach if (v)
48a605ea7eSDirk Eibach out_be32((void *)GPIO0_OR,
49255ef4d9SDirk Eibach in_be32((void *)GPIO0_OR) | pins->mdio);
50a605ea7eSDirk Eibach else
51a605ea7eSDirk Eibach out_be32((void *)GPIO0_OR,
52255ef4d9SDirk Eibach in_be32((void *)GPIO0_OR) & ~pins->mdio);
53a605ea7eSDirk Eibach
54a605ea7eSDirk Eibach return 0;
55a605ea7eSDirk Eibach }
56a605ea7eSDirk Eibach
io_bb_get_mdio(struct bb_miiphy_bus * bus,int * v)57a605ea7eSDirk Eibach static int io_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
58a605ea7eSDirk Eibach {
59255ef4d9SDirk Eibach struct io_bb_pinset *pins = bus->priv;
60255ef4d9SDirk Eibach
61255ef4d9SDirk Eibach *v = ((in_be32((void *)GPIO0_IR) & pins->mdio) != 0);
62a605ea7eSDirk Eibach
63a605ea7eSDirk Eibach return 0;
64a605ea7eSDirk Eibach }
65a605ea7eSDirk Eibach
io_bb_set_mdc(struct bb_miiphy_bus * bus,int v)66a605ea7eSDirk Eibach static int io_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
67a605ea7eSDirk Eibach {
68255ef4d9SDirk Eibach struct io_bb_pinset *pins = bus->priv;
69255ef4d9SDirk Eibach
70a605ea7eSDirk Eibach if (v)
71a605ea7eSDirk Eibach out_be32((void *)GPIO0_OR,
72255ef4d9SDirk Eibach in_be32((void *)GPIO0_OR) | pins->mdc);
73a605ea7eSDirk Eibach else
74a605ea7eSDirk Eibach out_be32((void *)GPIO0_OR,
75255ef4d9SDirk Eibach in_be32((void *)GPIO0_OR) & ~pins->mdc);
76a605ea7eSDirk Eibach
77a605ea7eSDirk Eibach return 0;
78a605ea7eSDirk Eibach }
79a605ea7eSDirk Eibach
io_bb_delay(struct bb_miiphy_bus * bus)80a605ea7eSDirk Eibach static int io_bb_delay(struct bb_miiphy_bus *bus)
81a605ea7eSDirk Eibach {
82a605ea7eSDirk Eibach udelay(1);
83a605ea7eSDirk Eibach
84a605ea7eSDirk Eibach return 0;
85a605ea7eSDirk Eibach }
86a605ea7eSDirk Eibach
87255ef4d9SDirk Eibach struct io_bb_pinset io_bb_pinsets[] = {
88255ef4d9SDirk Eibach {
89255ef4d9SDirk Eibach .mdio = CONFIG_SYS_MDIO_PIN,
90255ef4d9SDirk Eibach .mdc = CONFIG_SYS_MDC_PIN,
91255ef4d9SDirk Eibach },
92255ef4d9SDirk Eibach #ifdef CONFIG_SYS_GBIT_MII1_BUSNAME
93255ef4d9SDirk Eibach {
94255ef4d9SDirk Eibach .mdio = CONFIG_SYS_MDIO1_PIN,
95255ef4d9SDirk Eibach .mdc = CONFIG_SYS_MDC1_PIN,
96255ef4d9SDirk Eibach },
97255ef4d9SDirk Eibach #endif
98255ef4d9SDirk Eibach };
99255ef4d9SDirk Eibach
100a605ea7eSDirk Eibach struct bb_miiphy_bus bb_miiphy_buses[] = {
101a605ea7eSDirk Eibach {
102a605ea7eSDirk Eibach .name = CONFIG_SYS_GBIT_MII_BUSNAME,
103a605ea7eSDirk Eibach .init = io_bb_mii_init,
104a605ea7eSDirk Eibach .mdio_active = io_bb_mdio_active,
105a605ea7eSDirk Eibach .mdio_tristate = io_bb_mdio_tristate,
106a605ea7eSDirk Eibach .set_mdio = io_bb_set_mdio,
107a605ea7eSDirk Eibach .get_mdio = io_bb_get_mdio,
108a605ea7eSDirk Eibach .set_mdc = io_bb_set_mdc,
109a605ea7eSDirk Eibach .delay = io_bb_delay,
110255ef4d9SDirk Eibach .priv = &io_bb_pinsets[0],
111255ef4d9SDirk Eibach },
112255ef4d9SDirk Eibach #ifdef CONFIG_SYS_GBIT_MII1_BUSNAME
113255ef4d9SDirk Eibach {
114255ef4d9SDirk Eibach .name = CONFIG_SYS_GBIT_MII1_BUSNAME,
115255ef4d9SDirk Eibach .init = io_bb_mii_init,
116255ef4d9SDirk Eibach .mdio_active = io_bb_mdio_active,
117255ef4d9SDirk Eibach .mdio_tristate = io_bb_mdio_tristate,
118255ef4d9SDirk Eibach .set_mdio = io_bb_set_mdio,
119255ef4d9SDirk Eibach .get_mdio = io_bb_get_mdio,
120255ef4d9SDirk Eibach .set_mdc = io_bb_set_mdc,
121255ef4d9SDirk Eibach .delay = io_bb_delay,
122255ef4d9SDirk Eibach .priv = &io_bb_pinsets[1],
123255ef4d9SDirk Eibach },
124255ef4d9SDirk Eibach #endif
125a605ea7eSDirk Eibach };
126a605ea7eSDirk Eibach
127a605ea7eSDirk Eibach int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
128a605ea7eSDirk Eibach sizeof(bb_miiphy_buses[0]);
129