blob: 11342df1c5a89bd2f7af795d4025aabb8593a96c [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +01002/*
3 * Fixed-Link phy
4 *
5 * Copyright 2017 Bernecker & Rainer Industrieelektronik GmbH
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +01006 */
7
8#include <config.h>
9#include <common.h>
Simon Glass336d4612020-02-03 07:36:16 -070010#include <malloc.h>
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010011#include <phy.h>
12#include <dm.h>
13#include <fdt_support.h>
Simon Glass401d1c42020-10-30 21:38:53 -060014#include <asm/global_data.h>
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010015
16DECLARE_GLOBAL_DATA_PTR;
17
18int fixedphy_probe(struct phy_device *phydev)
19{
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +080020 /* fixed-link phy must not be reset by core phy code */
21 phydev->flags |= PHY_FLAG_BROKEN_RESET;
22
23 return 0;
24}
25
26int fixedphy_config(struct phy_device *phydev)
27{
28 ofnode node = phy_get_ofnode(phydev);
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010029 struct fixed_link *priv;
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010030 u32 val;
31
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +080032 if (!ofnode_valid(node))
33 return -EINVAL;
34
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010035 /* check for mandatory properties within fixed-link node */
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +080036 val = ofnode_read_u32_default(node, "speed", 0);
Vladimir Oltean56a55882021-01-25 14:23:51 +020037 if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000 &&
38 val != SPEED_2500 && val != SPEED_10000) {
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010039 printf("ERROR: no/invalid speed given in fixed-link node!");
40 return -EINVAL;
41 }
42
43 priv = malloc(sizeof(*priv));
44 if (!priv)
45 return -ENOMEM;
46 memset(priv, 0, sizeof(*priv));
47
48 phydev->priv = priv;
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010049
50 priv->link_speed = val;
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +080051 priv->duplex = ofnode_read_bool(node, "full-duplex");
52 priv->pause = ofnode_read_bool(node, "pause");
53 priv->asym_pause = ofnode_read_bool(node, "asym-pause");
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010054
55 return 0;
56}
57
58int fixedphy_startup(struct phy_device *phydev)
59{
60 struct fixed_link *priv = phydev->priv;
61
62 phydev->asym_pause = priv->asym_pause;
63 phydev->pause = priv->pause;
64 phydev->duplex = priv->duplex;
65 phydev->speed = priv->link_speed;
66 phydev->link = 1;
67
68 return 0;
69}
70
71int fixedphy_shutdown(struct phy_device *phydev)
72{
73 return 0;
74}
75
76static struct phy_driver fixedphy_driver = {
77 .uid = PHY_FIXED_ID,
78 .mask = 0xffffffff,
79 .name = "Fixed PHY",
80 .features = PHY_GBIT_FEATURES | SUPPORTED_MII,
81 .probe = fixedphy_probe,
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +080082 .config = fixedphy_config,
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +010083 .startup = fixedphy_startup,
84 .shutdown = fixedphy_shutdown,
85};
86
87int phy_fixed_init(void)
88{
89 phy_register(&fixedphy_driver);
90 return 0;
91}