Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140131084
D51449.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D51449.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D51449: Extending mcommphy YT8531 functionality
Attached
Detach File
Event Timeline
Log In to Comment