blob: 11d3616497697b7003bba4b2e3006d6d1b6d6d15 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Hannes Schmelzerda494602017-03-23 15:11:43 +01002/*
3 * Fixed-Link phy
4 *
5 * Copyright 2017 Bernecker & Rainer Industrieelektronik GmbH
Hannes Schmelzerda494602017-03-23 15:11:43 +01006 */
7
8#include <config.h>
Simon Glass9bc15642020-02-03 07:36:16 -07009#include <malloc.h>
Hannes Schmelzerda494602017-03-23 15:11:43 +010010#include <phy.h>
11#include <dm.h>
12#include <fdt_support.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060013#include <asm/global_data.h>
Hannes Schmelzerda494602017-03-23 15:11:43 +010014
15DECLARE_GLOBAL_DATA_PTR;
16
Bin Meng7d2129b2021-03-14 20:14:53 +080017static int fixedphy_probe(struct phy_device *phydev)
Hannes Schmelzerda494602017-03-23 15:11:43 +010018{
Vladimir Oltean6ca194a2021-03-14 20:14:48 +080019 /* fixed-link phy must not be reset by core phy code */
20 phydev->flags |= PHY_FLAG_BROKEN_RESET;
21
22 return 0;
23}
24
Bin Meng7d2129b2021-03-14 20:14:53 +080025static int fixedphy_config(struct phy_device *phydev)
Vladimir Oltean6ca194a2021-03-14 20:14:48 +080026{
27 ofnode node = phy_get_ofnode(phydev);
Hannes Schmelzerda494602017-03-23 15:11:43 +010028 struct fixed_link *priv;
Bin Meng13462672021-03-14 20:14:55 +080029 bool old_binding = false;
30 u32 old_val[5];
Hannes Schmelzerda494602017-03-23 15:11:43 +010031 u32 val;
32
Vladimir Oltean6ca194a2021-03-14 20:14:48 +080033 if (!ofnode_valid(node))
34 return -EINVAL;
35
Hannes Schmelzerda494602017-03-23 15:11:43 +010036 /* check for mandatory properties within fixed-link node */
Vladimir Oltean6ca194a2021-03-14 20:14:48 +080037 val = ofnode_read_u32_default(node, "speed", 0);
Bin Meng13462672021-03-14 20:14:55 +080038
39 if (!val) {
40 /* try old binding */
41 old_binding = true;
42 if (ofnode_read_u32_array(node, "fixed-link", old_val,
43 ARRAY_SIZE(old_val))) {
44 printf("ERROR: no/invalid <fixed-link> property!\n");
45 return -ENOENT;
46 }
47 val = old_val[2];
48 }
49
Vladimir Oltean312e15b2021-01-25 14:23:51 +020050 if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000 &&
51 val != SPEED_2500 && val != SPEED_10000) {
Bin Mengfbe5aea2021-03-14 20:14:54 +080052 printf("ERROR: no/invalid speed given in fixed-link node!\n");
Hannes Schmelzerda494602017-03-23 15:11:43 +010053 return -EINVAL;
54 }
55
56 priv = malloc(sizeof(*priv));
57 if (!priv)
58 return -ENOMEM;
59 memset(priv, 0, sizeof(*priv));
60
61 phydev->priv = priv;
Hannes Schmelzerda494602017-03-23 15:11:43 +010062
63 priv->link_speed = val;
Bin Meng13462672021-03-14 20:14:55 +080064 if (!old_binding) {
65 priv->duplex = ofnode_read_bool(node, "full-duplex");
66 priv->pause = ofnode_read_bool(node, "pause");
67 priv->asym_pause = ofnode_read_bool(node, "asym-pause");
68 } else {
69 priv->duplex = old_val[1];
70 priv->pause = old_val[3];
71 priv->asym_pause = old_val[4];
72 }
Hannes Schmelzerda494602017-03-23 15:11:43 +010073
74 return 0;
75}
76
Bin Meng7d2129b2021-03-14 20:14:53 +080077static int fixedphy_startup(struct phy_device *phydev)
Hannes Schmelzerda494602017-03-23 15:11:43 +010078{
79 struct fixed_link *priv = phydev->priv;
80
81 phydev->asym_pause = priv->asym_pause;
82 phydev->pause = priv->pause;
83 phydev->duplex = priv->duplex;
84 phydev->speed = priv->link_speed;
85 phydev->link = 1;
86
87 return 0;
88}
89
Bin Meng7d2129b2021-03-14 20:14:53 +080090static int fixedphy_shutdown(struct phy_device *phydev)
Hannes Schmelzerda494602017-03-23 15:11:43 +010091{
92 return 0;
93}
94
Marek Vasutfa976d92023-03-19 18:03:09 +010095U_BOOT_PHY_DRIVER(fixedphy) = {
Hannes Schmelzerda494602017-03-23 15:11:43 +010096 .uid = PHY_FIXED_ID,
97 .mask = 0xffffffff,
98 .name = "Fixed PHY",
99 .features = PHY_GBIT_FEATURES | SUPPORTED_MII,
100 .probe = fixedphy_probe,
Vladimir Oltean6ca194a2021-03-14 20:14:48 +0800101 .config = fixedphy_config,
Hannes Schmelzerda494602017-03-23 15:11:43 +0100102 .startup = fixedphy_startup,
103 .shutdown = fixedphy_shutdown,
104};