summaryrefslogtreecommitdiff
path: root/src/drivers/net/phy/m88e1512
diff options
context:
space:
mode:
authorMario Scheithauer <mario.scheithauer@siemens.com>2023-01-25 11:43:51 +0100
committerFelix Held <felix-coreboot@felixheld.de>2023-03-02 14:40:49 +0000
commit481bfe6a8b8ab500b10d1a7821796826c58e9e4a (patch)
tree25de5e16b889b1522cf213d4f0b35391ac351025 /src/drivers/net/phy/m88e1512
parent33ef5c4e3a6a36596ab20faf4b8edd3f32c189d3 (diff)
drivers/net/phy/m88e1512: Add a way to set output impedance manually
This patch provides the functionality to set the RGMII output impedance manually. To ensure that no race condition occurs, the driver strength values for PMOS and NMOS should be written to the RGMII output impedance calibration override register first and then the force bit should be enabled with a second write to this register. Link to the Marvell PHY 88E1512 datasheet: https://web.archive.org/web/20230125074158/https://www.marvell.com/content/dam/marvell/en/public-collateral/phys-transceivers/marvell-ethernet-phys-alaska-88e151x-datasheet.pdf Change-Id: I87fa03aa49514cdc33d2911d7f23386c8f69d95b Signed-off-by: Mario Scheithauer <mario.scheithauer@siemens.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/73018 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
Diffstat (limited to 'src/drivers/net/phy/m88e1512')
-rw-r--r--src/drivers/net/phy/m88e1512/chip.h3
-rw-r--r--src/drivers/net/phy/m88e1512/m88e1512.c19
-rw-r--r--src/drivers/net/phy/m88e1512/m88e1512.h6
3 files changed, 28 insertions, 0 deletions
diff --git a/src/drivers/net/phy/m88e1512/chip.h b/src/drivers/net/phy/m88e1512/chip.h
index 915001a7a1..f1e313ba97 100644
--- a/src/drivers/net/phy/m88e1512/chip.h
+++ b/src/drivers/net/phy/m88e1512/chip.h
@@ -11,4 +11,7 @@ struct drivers_net_phy_m88e1512_config {
/* 1x, 2x,...8x is the number of times the PHY attempts to establish Gigabit link
before the PHY downshifts to the next highest speed. */
unsigned char downshift_cnt;
+ bool force_mos; /* Force PMOS/NMOS manually */
+ unsigned char pmos_val; /* Set PMOS calibration value */
+ unsigned char nmos_val; /* Set NMOS calibration value */
};
diff --git a/src/drivers/net/phy/m88e1512/m88e1512.c b/src/drivers/net/phy/m88e1512/m88e1512.c
index 5ce9b40c55..2e8994c748 100644
--- a/src/drivers/net/phy/m88e1512/m88e1512.c
+++ b/src/drivers/net/phy/m88e1512/m88e1512.c
@@ -67,6 +67,25 @@ static void m88e1512_init(struct device *dev)
mdio_write(dev, LED_TIMER_CTRL_REG, reg);
}
+ /* Set RGMII output impedance manually. */
+ if (config->force_mos) {
+ printk(BIOS_DEBUG, "%s: Set RGMII driver strength manually for %s.\n",
+ dev_path(dev->bus->dev), dev->chip_ops->name);
+
+ /* Select page 2 to access RGMII output impedance calibration override
+ register. */
+ switch_page(dev, 2);
+
+ reg = mdio_read(dev, OUT_IMP_CAL_OVERRIDE_REG);
+ /* Set first only NMOS/PMOS values. */
+ clrsetbits16(&reg, MOS_VALUE_MASK, PMOS_VALUE(config->pmos_val) |
+ NMOS_VALUE(config->nmos_val));
+ mdio_write(dev, OUT_IMP_CAL_OVERRIDE_REG, reg);
+ /* Activate the new setting. */
+ setbits16(&reg, FORCE_MOS);
+ mdio_write(dev, OUT_IMP_CAL_OVERRIDE_REG, reg);
+ }
+
/* Switch back to page 0. */
switch_page(dev, 0);
}
diff --git a/src/drivers/net/phy/m88e1512/m88e1512.h b/src/drivers/net/phy/m88e1512/m88e1512.h
index 449cc57531..3310c8b994 100644
--- a/src/drivers/net/phy/m88e1512/m88e1512.h
+++ b/src/drivers/net/phy/m88e1512/m88e1512.h
@@ -13,6 +13,12 @@
#define DOWNSHIFT_CNT_MAX 8
#define DOWNSHIFT_CNT(cnt) ((cnt - 1) << 12)
#define DOWNSHIFT_EN (1 << 11)
+/* Page 2 registers */
+#define OUT_IMP_CAL_OVERRIDE_REG 0x18
+#define MOS_VALUE_MASK 0x0F4F
+#define PMOS_VALUE(pmos) (pmos << 8)
+#define FORCE_MOS (1 << 6)
+#define NMOS_VALUE(nmos) (nmos << 0)
/* Page 3 registers */
#define LED_FUNC_CTRL_REG 0x10
#define LED_FUNC_CTRL_MASK 0x0FFF