diff options
author | David S. Miller <davem@davemloft.net> | 2015-10-29 23:21:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-29 23:21:57 -0400 |
commit | 65bdc43d2220bc97af037c87aba2407b46f13c2a (patch) | |
tree | 7b6bca0cfcf606f47d9b998cbc44cbc9b75b2729 | |
parent | b7af1472afa2228bd9fe8b4cea3b003b4027d72d (diff) | |
parent | 6ccbe6b248ef8cc31477a388ea9841b56030bea9 (diff) |
Merge branch 'xgene_txrx_delay'
Iyappan Subramanian says:
====================
drivers: xgene: Add support RGMII TX/RX delay configuration
X-Gene RGMII ethernet controller has a RGMII bridge that performs the
task of converting the RGMII signal {RX_CLK,RX_CTL, RX_DATA[3:0]} from
PHY to GMII signal {RX_DV,RX_ER,RX_DATA[7:0]} and vice versa. This
RGMII bridge has a provision to internally delay the input RX_CLK and
the output TX_CLK using configuration registers. This will help in
maintain the CLK-CTL delay relationship in various operating
conditions.
This patch adds support RGMII TX/RX delay configuration.
====================
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/apm-xgene-enet.txt | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 49 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 2 |
5 files changed, 69 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt index f55aa280d34f..078060a97f95 100644 --- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt +++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt | |||
@@ -37,6 +37,14 @@ Required properties for ethernet interfaces that have external PHY: | |||
37 | 37 | ||
38 | Optional properties: | 38 | Optional properties: |
39 | - status: Should be "ok" or "disabled" for enabled/disabled. Default is "ok". | 39 | - status: Should be "ok" or "disabled" for enabled/disabled. Default is "ok". |
40 | - tx-delay: Delay value for RGMII bridge TX clock. | ||
41 | Valid values are between 0 to 7, that maps to | ||
42 | 417, 717, 1020, 1321, 1611, 1913, 2215, 2514 ps | ||
43 | Default value is 4, which corresponds to 1611 ps | ||
44 | - rx-delay: Delay value for RGMII bridge RX clock. | ||
45 | Valid values are between 0 to 7, that maps to | ||
46 | 273, 589, 899, 1222, 1480, 1806, 2147, 2464 ps | ||
47 | Default value is 2, which corresponds to 899 ps | ||
40 | 48 | ||
41 | Example: | 49 | Example: |
42 | menetclk: menetclk { | 50 | menetclk: menetclk { |
@@ -72,5 +80,7 @@ Example: | |||
72 | 80 | ||
73 | /* Board-specific peripheral configurations */ | 81 | /* Board-specific peripheral configurations */ |
74 | &menet { | 82 | &menet { |
83 | tx-delay = <4>; | ||
84 | rx-delay = <2>; | ||
75 | status = "ok"; | 85 | status = "ok"; |
76 | }; | 86 | }; |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index 652f21889a48..33850a0f7e82 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | |||
@@ -461,6 +461,7 @@ static void xgene_gmac_reset(struct xgene_enet_pdata *pdata) | |||
461 | 461 | ||
462 | static void xgene_gmac_init(struct xgene_enet_pdata *pdata) | 462 | static void xgene_gmac_init(struct xgene_enet_pdata *pdata) |
463 | { | 463 | { |
464 | struct device *dev = &pdata->pdev->dev; | ||
464 | u32 value, mc2; | 465 | u32 value, mc2; |
465 | u32 intf_ctl, rgmii; | 466 | u32 intf_ctl, rgmii; |
466 | u32 icm0, icm2; | 467 | u32 icm0, icm2; |
@@ -490,7 +491,12 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) | |||
490 | default: | 491 | default: |
491 | ENET_INTERFACE_MODE2_SET(&mc2, 2); | 492 | ENET_INTERFACE_MODE2_SET(&mc2, 2); |
492 | intf_ctl |= ENET_GHD_MODE; | 493 | intf_ctl |= ENET_GHD_MODE; |
493 | CFG_TXCLK_MUXSEL0_SET(&rgmii, 4); | 494 | |
495 | if (dev->of_node) { | ||
496 | CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay); | ||
497 | CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay); | ||
498 | } | ||
499 | |||
494 | xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value); | 500 | xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value); |
495 | value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX; | 501 | value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX; |
496 | xgene_enet_wr_csr(pdata, DEBUG_REG_ADDR, value); | 502 | xgene_enet_wr_csr(pdata, DEBUG_REG_ADDR, value); |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h index ff05bbcff26d..6dee73c3c1e1 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | |||
@@ -144,6 +144,7 @@ enum xgene_enet_rm { | |||
144 | #define CFG_BYPASS_UNISEC_RX BIT(1) | 144 | #define CFG_BYPASS_UNISEC_RX BIT(1) |
145 | #define CFG_CLE_BYPASS_EN0 BIT(31) | 145 | #define CFG_CLE_BYPASS_EN0 BIT(31) |
146 | #define CFG_TXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 29, 3) | 146 | #define CFG_TXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 29, 3) |
147 | #define CFG_RXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 26, 3) | ||
147 | 148 | ||
148 | #define CFG_CLE_IP_PROTOCOL0_SET(dst, val) xgene_set_bits(dst, val, 16, 2) | 149 | #define CFG_CLE_IP_PROTOCOL0_SET(dst, val) xgene_set_bits(dst, val, 16, 2) |
149 | #define CFG_CLE_DSTQID0_SET(dst, val) xgene_set_bits(dst, val, 0, 12) | 150 | #define CFG_CLE_DSTQID0_SET(dst, val) xgene_set_bits(dst, val, 0, 12) |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 6b1846df7b0c..ce1068771b32 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c | |||
@@ -1118,6 +1118,47 @@ static int xgene_get_port_id_dt(struct device *dev, struct xgene_enet_pdata *pda | |||
1118 | return ret; | 1118 | return ret; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static int xgene_get_tx_delay(struct xgene_enet_pdata *pdata) | ||
1122 | { | ||
1123 | struct device *dev = &pdata->pdev->dev; | ||
1124 | int delay, ret; | ||
1125 | |||
1126 | ret = of_property_read_u32(dev->of_node, "tx-delay", &delay); | ||
1127 | if (ret) { | ||
1128 | pdata->tx_delay = 4; | ||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | if (delay < 0 || delay > 7) { | ||
1133 | dev_err(dev, "Invalid tx-delay specified\n"); | ||
1134 | return -EINVAL; | ||
1135 | } | ||
1136 | |||
1137 | pdata->tx_delay = delay; | ||
1138 | |||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1142 | static int xgene_get_rx_delay(struct xgene_enet_pdata *pdata) | ||
1143 | { | ||
1144 | struct device *dev = &pdata->pdev->dev; | ||
1145 | int delay, ret; | ||
1146 | |||
1147 | ret = of_property_read_u32(dev->of_node, "rx-delay", &delay); | ||
1148 | if (ret) { | ||
1149 | pdata->rx_delay = 2; | ||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | if (delay < 0 || delay > 7) { | ||
1154 | dev_err(dev, "Invalid rx-delay specified\n"); | ||
1155 | return -EINVAL; | ||
1156 | } | ||
1157 | |||
1158 | pdata->rx_delay = delay; | ||
1159 | |||
1160 | return 0; | ||
1161 | } | ||
1121 | 1162 | ||
1122 | static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) | 1163 | static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) |
1123 | { | 1164 | { |
@@ -1194,6 +1235,14 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) | |||
1194 | return -ENODEV; | 1235 | return -ENODEV; |
1195 | } | 1236 | } |
1196 | 1237 | ||
1238 | ret = xgene_get_tx_delay(pdata); | ||
1239 | if (ret) | ||
1240 | return ret; | ||
1241 | |||
1242 | ret = xgene_get_rx_delay(pdata); | ||
1243 | if (ret) | ||
1244 | return ret; | ||
1245 | |||
1197 | ret = platform_get_irq(pdev, 0); | 1246 | ret = platform_get_irq(pdev, 0); |
1198 | if (ret <= 0) { | 1247 | if (ret <= 0) { |
1199 | dev_err(dev, "Unable to get ENET Rx IRQ\n"); | 1248 | dev_err(dev, "Unable to get ENET Rx IRQ\n"); |
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h index ff89a5d98d01..a6e56b88c0a0 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h | |||
@@ -184,6 +184,8 @@ struct xgene_enet_pdata { | |||
184 | u8 bp_bufnum; | 184 | u8 bp_bufnum; |
185 | u16 ring_num; | 185 | u16 ring_num; |
186 | u32 mss; | 186 | u32 mss; |
187 | u8 tx_delay; | ||
188 | u8 rx_delay; | ||
187 | }; | 189 | }; |
188 | 190 | ||
189 | struct xgene_indirect_ctl { | 191 | struct xgene_indirect_ctl { |