Skip to content

Commit 67a8976

Browse files
committed
Merge branch 'phy-motorcomm-driver-strength'
Samin Guo says: ==================== Add motorcomm phy pad-driver-strength-cfg support The motorcomm phy (YT8531) supports the ability to adjust the drive strength of the rx_clk/rx_data, and the default strength may not be suitable for all boards. So add configurable options to better match the boards.(e.g. StarFive VisionFive 2) The first patch adds a description of dt-bingding, and the second patch adds YT8531's parsing and settings for pad-driver-strength-cfg. Changes since v4: Patch 1: - Removed register-related DS(3b) values and added vol descriptions (by Andrew Lunn) - Dropped the type and added '-microamp' suffix. (by Rob Herring) Patch 2: - Return -EINVAL if the value in DT but it is invalid (by Andrew Lunn) Changes since v3: Patch 1: - Used current values instead of register values - Added units and numerical descriptions of driver-strength Patch 2: - Added a lookup table to listing the valid values in the schema (by Andrew Lunn) Changes since v2: Patch 2: - Readjusted the order of YT8531_RGMII_xxx to below YTPHY_PAD_DRIVE_STRENGTH_REG (by Frank Sae) - Reversed Christmas tree, sort these longest first, shortest last (by Andrew Lunn) - Rebased on tag v6.4 Changes since v1: Patch 1: - Renamed "rx-xxx-driver-strength" to "motorcomm,rx-xxx-driver-strength" (by Frank Sae) Patch 2: - Added default values for rxc/rxd driver strength (by Frank Sea/Andrew Lunn) - Added range checking when val is in DT (by Frank Sea/Andrew Lunn) Previous versions: v1 - https://patchwork.kernel.org/project/netdevbpf/cover/[email protected] v2 - https://patchwork.kernel.org/project/netdevbpf/cover/[email protected] v3 - https://patchwork.kernel.org/project/netdevbpf/cover/[email protected] v4 - https://patchwork.kernel.org/project/netdevbpf/cover/[email protected] ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f5f80e3 + 7a561e9 commit 67a8976

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,40 @@ properties:
5252
for a timer.
5353
type: boolean
5454

55+
motorcomm,rx-clk-drv-microamp:
56+
description: |
57+
drive strength of rx_clk rgmii pad.
58+
The YT8531 RGMII LDO voltage supports 1.8V/3.3V, and the LDO voltage can
59+
be configured with hardware pull-up resistors to match the SOC voltage
60+
(usually 1.8V).
61+
The software can read the registers to obtain the LDO voltage and configure
62+
the legal drive strength(curren).
63+
=====================================================
64+
| voltage | current Available (uA) |
65+
| 1.8v | 1200 2100 2700 2910 3110 3600 3970 4350 |
66+
| 3.3v | 3070 4080 4370 4680 5020 5450 5740 6140 |
67+
=====================================================
68+
enum: [ 1200, 2100, 2700, 2910, 3070, 3110, 3600, 3970,
69+
4080, 4350, 4370, 4680, 5020, 5450, 5740, 6140 ]
70+
default: 2910
71+
72+
motorcomm,rx-data-drv-microamp:
73+
description: |
74+
drive strength of rx_data/rx_ctl rgmii pad.
75+
The YT8531 RGMII LDO voltage supports 1.8V/3.3V, and the LDO voltage can
76+
be configured with hardware pull-up resistors to match the SOC voltage
77+
(usually 1.8V).
78+
The software can read the registers to obtain the LDO voltage and configure
79+
the legal drive strength(curren).
80+
=====================================================
81+
| voltage | current Available (uA) |
82+
| 1.8v | 1200 2100 2700 2910 3110 3600 3970 4350 |
83+
| 3.3v | 3070 4080 4370 4680 5020 5450 5740 6140 |
84+
=====================================================
85+
enum: [ 1200, 2100, 2700, 2910, 3070, 3110, 3600, 3970,
86+
4080, 4350, 4370, 4680, 5020, 5450, 5740, 6140 ]
87+
default: 2910
88+
5589
motorcomm,tx-clk-adj-enabled:
5690
description: |
5791
This configuration is mainly to adapt to VF2 with JH7110 SoC.

drivers/net/phy/motorcomm.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@
163163

164164
#define YT8521_CHIP_CONFIG_REG 0xA001
165165
#define YT8521_CCR_SW_RST BIT(15)
166+
#define YT8531_RGMII_LDO_VOL_MASK GENMASK(5, 4)
167+
#define YT8531_LDO_VOL_3V3 0x0
168+
#define YT8531_LDO_VOL_1V8 0x2
169+
166170
/* 1b0 disable 1.9ns rxc clock delay *default*
167171
* 1b1 enable 1.9ns rxc clock delay
168172
*/
@@ -236,6 +240,12 @@
236240
*/
237241
#define YTPHY_WCR_TYPE_PULSE BIT(0)
238242

243+
#define YTPHY_PAD_DRIVE_STRENGTH_REG 0xA010
244+
#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13)
245+
#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */
246+
#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
247+
#define YT8531_RGMII_RX_DS_DEFAULT 0x3
248+
239249
#define YTPHY_SYNCE_CFG_REG 0xA012
240250
#define YT8521_SCR_SYNCE_ENABLE BIT(5)
241251
/* 1b0 output 25m clock
@@ -834,6 +844,110 @@ static int ytphy_rgmii_clk_delay_config_with_lock(struct phy_device *phydev)
834844
return ret;
835845
}
836846

847+
/**
848+
* struct ytphy_ldo_vol_map - map a current value to a register value
849+
* @vol: ldo voltage
850+
* @ds: value in the register
851+
* @cur: value in device configuration
852+
*/
853+
struct ytphy_ldo_vol_map {
854+
u32 vol;
855+
u32 ds;
856+
u32 cur;
857+
};
858+
859+
static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
860+
{.vol = YT8531_LDO_VOL_1V8, .ds = 0, .cur = 1200},
861+
{.vol = YT8531_LDO_VOL_1V8, .ds = 1, .cur = 2100},
862+
{.vol = YT8531_LDO_VOL_1V8, .ds = 2, .cur = 2700},
863+
{.vol = YT8531_LDO_VOL_1V8, .ds = 3, .cur = 2910},
864+
{.vol = YT8531_LDO_VOL_1V8, .ds = 4, .cur = 3110},
865+
{.vol = YT8531_LDO_VOL_1V8, .ds = 5, .cur = 3600},
866+
{.vol = YT8531_LDO_VOL_1V8, .ds = 6, .cur = 3970},
867+
{.vol = YT8531_LDO_VOL_1V8, .ds = 7, .cur = 4350},
868+
{.vol = YT8531_LDO_VOL_3V3, .ds = 0, .cur = 3070},
869+
{.vol = YT8531_LDO_VOL_3V3, .ds = 1, .cur = 4080},
870+
{.vol = YT8531_LDO_VOL_3V3, .ds = 2, .cur = 4370},
871+
{.vol = YT8531_LDO_VOL_3V3, .ds = 3, .cur = 4680},
872+
{.vol = YT8531_LDO_VOL_3V3, .ds = 4, .cur = 5020},
873+
{.vol = YT8531_LDO_VOL_3V3, .ds = 5, .cur = 5450},
874+
{.vol = YT8531_LDO_VOL_3V3, .ds = 6, .cur = 5740},
875+
{.vol = YT8531_LDO_VOL_3V3, .ds = 7, .cur = 6140},
876+
};
877+
878+
static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
879+
{
880+
u32 val;
881+
882+
val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
883+
val = FIELD_GET(YT8531_RGMII_LDO_VOL_MASK, val);
884+
885+
return val <= YT8531_LDO_VOL_1V8 ? val : YT8531_LDO_VOL_1V8;
886+
}
887+
888+
static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
889+
{
890+
u32 vol;
891+
int i;
892+
893+
vol = yt8531_get_ldo_vol(phydev);
894+
for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
895+
if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
896+
return yt8531_ldo_vol[i].ds;
897+
}
898+
899+
return -EINVAL;
900+
}
901+
902+
static int yt8531_set_ds(struct phy_device *phydev)
903+
{
904+
struct device_node *node = phydev->mdio.dev.of_node;
905+
u32 ds_field_low, ds_field_hi, val;
906+
int ret, ds;
907+
908+
/* set rgmii rx clk driver strength */
909+
if (!of_property_read_u32(node, "motorcomm,rx-clk-drv-microamp", &val)) {
910+
ds = yt8531_get_ds_map(phydev, val);
911+
if (ds < 0)
912+
return dev_err_probe(&phydev->mdio.dev, ds,
913+
"No matching current value was found.\n");
914+
} else {
915+
ds = YT8531_RGMII_RX_DS_DEFAULT;
916+
}
917+
918+
ret = ytphy_modify_ext_with_lock(phydev,
919+
YTPHY_PAD_DRIVE_STRENGTH_REG,
920+
YT8531_RGMII_RXC_DS_MASK,
921+
FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
922+
if (ret < 0)
923+
return ret;
924+
925+
/* set rgmii rx data driver strength */
926+
if (!of_property_read_u32(node, "motorcomm,rx-data-drv-microamp", &val)) {
927+
ds = yt8531_get_ds_map(phydev, val);
928+
if (ds < 0)
929+
return dev_err_probe(&phydev->mdio.dev, ds,
930+
"No matching current value was found.\n");
931+
} else {
932+
ds = YT8531_RGMII_RX_DS_DEFAULT;
933+
}
934+
935+
ds_field_hi = FIELD_GET(BIT(2), ds);
936+
ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
937+
938+
ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
939+
ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
940+
941+
ret = ytphy_modify_ext_with_lock(phydev,
942+
YTPHY_PAD_DRIVE_STRENGTH_REG,
943+
YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
944+
ds_field_low | ds_field_hi);
945+
if (ret < 0)
946+
return ret;
947+
948+
return 0;
949+
}
950+
837951
/**
838952
* yt8521_probe() - read chip config then set suitable polling_mode
839953
* @phydev: a pointer to a &struct phy_device
@@ -1518,6 +1632,10 @@ static int yt8531_config_init(struct phy_device *phydev)
15181632
return ret;
15191633
}
15201634

1635+
ret = yt8531_set_ds(phydev);
1636+
if (ret < 0)
1637+
return ret;
1638+
15211639
return 0;
15221640
}
15231641

0 commit comments

Comments
 (0)