Page MenuHomeFreeBSD

D51449.diff
No OneTemporary

D51449.diff

diff --git a/sys/dev/mii/mcommphy.c b/sys/dev/mii/mcommphy.c
--- a/sys/dev/mii/mcommphy.c
+++ b/sys/dev/mii/mcommphy.c
@@ -76,17 +76,29 @@
#define RXC_DLY_EN (1 << 8)
#define YT8531_PAD_DRSTR_CFG 0xa010
-#define PAD_RXC_MASK 0x7
-#define PAD_RXC_SHIFT 13
-#define JH7110_RGMII_RXC_STRENGTH 6
+#define PAD_RXCLK_MASK 0x7
+#define PAD_RXCLK_SHIFT 13
+#define PAD_VOL_DEFAULT 0x3
+#define PAD_VOL_MASK 0x30
+#define PAD_VOL_SHIFT 4
+#define PAD_VOL_1V8_MARKER 0x2
+#define PAD_VOLTABLE_LEN 8
+#define PAD_RXDATA_DRV_PROP_HI_MASK 0x4
+#define PAD_RXDATA_DRV_PROP_LOW_MASK 0x3
+#define PAD_RXDATA_DRV_HI_SHIFT 10
+#define PAD_RXDATA_DRV_LOW_SHIFT 4
+#define PAD_RXDATA_MASK (PAD_RXDATA_DRV_PROP_HI_MASK << \
+ PAD_RXDATA_DRV_HI_SHIFT | \
+ PAD_RXDATA_DRV_PROP_LOW_MASK << \
+ PAD_RXDATA_DRV_LOW_SHIFT)
#define YT8531_RGMII_CONFIG1 0xa003
-#define RX_DELAY_SEL_SHIFT 10
+#define RXTX_DELAY_DEFAULT 13
+#define RX_DELAY_MAX 4150
#define RX_DELAY_SEL_MASK 0xf
-#define RXC_DLY_THRESH 2250
+#define RX_DELAY_SEL_SHIFT 10
#define RXC_DLY_ADDON 1900
-#define TX_DELAY_SEL_FE_MASK 0xf
-#define TX_DELAY_SEL_FE_SHIFT 4
+#define TX_DELAY_MAX 2250
#define TX_DELAY_SEL_MASK 0xf
#define TX_DELAY_SEL_SHIFT 0
#define TX_CLK_SEL (1 << 14)
@@ -95,6 +107,14 @@
#define YT8531_SYNCE_CFG 0xa012
#define EN_SYNC_E (1 << 6)
+#define DEFAULT_PHY_MODE MII_CONTYPE_RGMII_ID
+
+static const int yt8531_1v8_voltable[] = {1200, 2100, 2700, 2910, 3110, 3600,
+ 3970, 4350};
+
+static const int yt8531_3v3_voltable[] = {3070, 4080, 4370, 4680, 5020, 5450,
+ 5740, 6140};
+
#define LOWEST_SET_BIT(mask) ((((mask) - 1) & (mask)) ^ (mask))
#define SHIFTIN(x, mask) ((x) * LOWEST_SET_BIT(mask))
@@ -107,8 +127,11 @@
struct mcommphy_softc {
mii_softc_t mii_sc;
device_t dev;
+ mii_contype_t phy_mode;
u_int rx_delay_ps;
u_int tx_delay_ps;
+ u_int rx_clk_drv;
+ u_int rx_data_drv;
bool tx_10_inv;
bool tx_100_inv;
bool tx_1000_inv;
@@ -250,27 +273,58 @@
struct mcommphy_softc *mcomm_sc = (struct mcommphy_softc *)sc;
uint16_t reg, oldaddr;
int rx_delay = 0, tx_delay = 0;
- bool rxc_dly_en_off = false;
-
- if (mcomm_sc->rx_delay_ps > RXC_DLY_THRESH) {
- rx_delay = (mcomm_sc->rx_delay_ps - RXC_DLY_ADDON) /
- INTERNAL_DLY_DIV;
- } else if (mcomm_sc->rx_delay_ps > 0) {
- rx_delay = mcomm_sc->rx_delay_ps / INTERNAL_DLY_DIV;
- rxc_dly_en_off = true;
+ bool rxc_dly_en = true;
+
+ /* The first set of rx_delay values is divisible by three */
+ if (mcomm_sc->phy_mode == MII_CONTYPE_RGMII_ID ||
+ mcomm_sc->phy_mode == MII_CONTYPE_RGMII_RXID) {
+ if (mcomm_sc->rx_delay_ps % 3 == 0) {
+ rxc_dly_en = false;
+ rx_delay = mcomm_sc->rx_delay_ps / INTERNAL_DLY_DIV;
+ } else {
+ rx_delay = (mcomm_sc->rx_delay_ps - RXC_DLY_ADDON)
+ / INTERNAL_DLY_DIV;
+ }
+ }
+
+ /* Checking that rx_delay value is in either range */
+ if ((mcomm_sc->rx_delay_ps % INTERNAL_DLY_DIV != 0 &&
+ (mcomm_sc->rx_delay_ps - RXC_DLY_ADDON) % INTERNAL_DLY_DIV != 0) ||
+ mcomm_sc->rx_delay_ps > RX_DELAY_MAX) {
+ device_printf(mcomm_sc->dev,
+ "warning: invalid rx_delay val: %u\n",
+ mcomm_sc->rx_delay_ps);
+ rx_delay = RXTX_DELAY_DEFAULT;
+ }
+
+ if (mcomm_sc->phy_mode == MII_CONTYPE_RGMII_ID ||
+ mcomm_sc->phy_mode == MII_CONTYPE_RGMII_TXID) {
+ if (mcomm_sc->tx_delay_ps > 0)
+ tx_delay = mcomm_sc->tx_delay_ps / INTERNAL_DLY_DIV;
}
- if (mcomm_sc->tx_delay_ps > 0) {
- tx_delay = mcomm_sc->tx_delay_ps / INTERNAL_DLY_DIV;
+ /* Checking that tx_delay value is in the range */
+ if ((mcomm_sc->tx_delay_ps % INTERNAL_DLY_DIV != 0) ||
+ mcomm_sc->tx_delay_ps > TX_DELAY_MAX) {
+ device_printf(mcomm_sc->dev,
+ "warning: invalid tx_delay val: %u\n",
+ mcomm_sc->tx_delay_ps);
+ tx_delay = RXTX_DELAY_DEFAULT;
}
oldaddr = PHY_READ(sc, EXT_REG_ADDR);
+ if (mcomm_sc->phy_mode == MII_CONTYPE_RGMII ||
+ mcomm_sc->phy_mode == MII_CONTYPE_RGMII_TXID)
+ rxc_dly_en = false;
+
/* Modifying Chip Config register */
PHY_WRITE(sc, EXT_REG_ADDR, YT8531_CHIP_CONFIG);
reg = PHY_READ(sc, EXT_REG_DATA);
- if (rxc_dly_en_off)
- reg &= ~(RXC_DLY_EN);
+ if (rxc_dly_en == true)
+ reg |= RXC_DLY_EN;
+ else
+ reg &= ~RXC_DLY_EN;
PHY_WRITE(sc, EXT_REG_DATA, reg);
/* Modifying RGMII Config1 register */
@@ -288,18 +342,50 @@
}
#endif
+static int
+mcommphy_yt8531_fetch_dsvol(struct mcommphy_softc *mcomm_sc,
+ uint16_t vol, u_int microamp)
+{
+ if (vol >= PAD_VOL_1V8_MARKER) {
+ for (int i = 0; i != PAD_VOLTABLE_LEN; i++) {
+ if (yt8531_1v8_voltable[i] == microamp)
+ return (i);
+ }
+ } else {
+ for (int i = 0; i != PAD_VOLTABLE_LEN; i++) {
+ if (yt8531_3v3_voltable[i] == microamp)
+ return (i);
+ }
+ }
+ device_printf(mcomm_sc->dev, "warning: invalid RX pad strength value");
+
+ return (PAD_VOL_DEFAULT);
+}
+
static int
mcommphy_yt8531_setup(struct mii_softc *sc)
{
- uint16_t reg, oldaddr;
+ struct mcommphy_softc *mcomm_sc = (struct mcommphy_softc *)sc;
+ uint16_t reg, val, vol, oldaddr;
oldaddr = PHY_READ(sc, EXT_REG_ADDR);
/* Modifying Pad Drive Strength register */
+ PHY_WRITE(sc, EXT_REG_ADDR, YT8531_CHIP_CONFIG);
+ vol = (PHY_READ(sc, EXT_REG_DATA) & PAD_VOL_MASK) >> PAD_VOL_SHIFT;
+
PHY_WRITE(sc, EXT_REG_ADDR, YT8531_PAD_DRSTR_CFG);
reg = PHY_READ(sc, EXT_REG_DATA);
- reg &= ~(PAD_RXC_MASK << PAD_RXC_SHIFT);
- reg |= (JH7110_RGMII_RXC_STRENGTH << PAD_RXC_SHIFT);
+
+ reg &= ~(PAD_RXCLK_MASK << PAD_RXCLK_SHIFT);
+ val = mcommphy_yt8531_fetch_dsvol(mcomm_sc, vol, mcomm_sc->rx_clk_drv);
+ reg |= (val << PAD_RXCLK_SHIFT);
+
+ reg &= ~(PAD_RXDATA_MASK);
+ val = mcommphy_yt8531_fetch_dsvol(mcomm_sc, vol, mcomm_sc->rx_data_drv);
+ reg |= (val & PAD_RXDATA_DRV_PROP_HI_MASK) << PAD_RXDATA_DRV_HI_SHIFT |
+ (val & PAD_RXDATA_DRV_PROP_LOW_MASK) << PAD_RXDATA_DRV_LOW_SHIFT;
+
PHY_WRITE(sc, EXT_REG_DATA, reg);
/* Modifying SyncE Config register */
@@ -327,6 +413,13 @@
cfg = mii_fdt_get_config(sc->dev);
+ sc->phy_mode = mii_fdt_get_contype(cfg->macnode);
+ if (sc->phy_mode < MII_CONTYPE_RGMII ||
+ sc->phy_mode > MII_CONTYPE_RGMII_TXID) {
+ device_printf(sc->dev, "warning: unsupported phy-mode\n");
+ sc->phy_mode = DEFAULT_PHY_MODE;
+ }
+
if (OF_hasprop(cfg->phynode, "motorcomm,tx-clk-10-inverted"))
sc->tx_10_inv = true;
if (OF_hasprop(cfg->phynode, "motorcomm,tx-clk-100-inverted"))
@@ -344,6 +437,16 @@
sc->tx_delay_ps = val;
}
+ /* Grab data for RGMII drive pad strength (microamperes) */
+ if (OF_getencprop(cfg->phynode, "motorcomm,rx-clk-drv-microamp", &val,
+ sizeof(val)) > 0) {
+ sc->rx_clk_drv = val;
+ }
+ if (OF_getencprop(cfg->phynode, "motorcomm,rx-data-drv-microamp", &val,
+ sizeof(val)) > 0) {
+ sc->rx_data_drv = val;
+ }
+
mii_fdt_free_config(cfg);
}
#endif

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 21, 4:04 PM (3 h, 23 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27115576
Default Alt Text
D51449.diff (6 KB)

Event Timeline