aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-07 16:51:22 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-07 16:51:22 -0400
commitc1a58d6a8d31ce133ff992e602655c29deb13e60 (patch)
treeade90e43e866c92f4dc09594a13115d1511c2af4
parent698365fa1874aa7635d51667a34a2842228e9837 (diff)
parent6e4b82730c7525504fc485b370c7f09e594e2e96 (diff)
Merge branch 'micrel_ksz9031'
Hubert Chaumette says: ==================== net/phy: micrel: Add DT configuration support and documentation for KSZ9031 - Adds DT configuration support for ksz9031 - Renames micrel-ksz9021.txt to micrel-ksz90x1.txt and adds ksz9031 binding documentation Changes since v3: - Rebased on net-next Changes since v2: - Merged together ksz9031_load_{clk,data,ctrl}_skew_values() - Added field length and number of fields prameter to account for registers specificities - Added binding documentation Changes since v1: - Removed ksz9021 and ksz9031 fixup deletions from arch/arm/mach-imx/mach-imx6q.c Hubert Chaumette (2): Update Micrel KSZ90x1 binding documentation ARM: i.MX6: Add OF configuration support for ksz9031 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/micrel-ksz9021.txt49
-rw-r--r--Documentation/devicetree/bindings/net/micrel-ksz90x1.txt83
-rw-r--r--drivers/net/phy/micrel.c106
3 files changed, 188 insertions, 50 deletions
diff --git a/Documentation/devicetree/bindings/net/micrel-ksz9021.txt b/Documentation/devicetree/bindings/net/micrel-ksz9021.txt
deleted file mode 100644
index 997a63f1aea1..000000000000
--- a/Documentation/devicetree/bindings/net/micrel-ksz9021.txt
+++ /dev/null
@@ -1,49 +0,0 @@
1Micrel KSZ9021 Gigabit Ethernet PHY
2
3Some boards require special tuning values, particularly when it comes to
4clock delays. You can specify clock delay values by adding
5micrel-specific properties to an Ethernet OF device node.
6
7All skew control options are specified in picoseconds. The minimum
8value is 0, and the maximum value is 3000.
9
10Optional properties:
11 - rxc-skew-ps : Skew control of RXC pad
12 - rxdv-skew-ps : Skew control of RX CTL pad
13 - txc-skew-ps : Skew control of TXC pad
14 - txen-skew-ps : Skew control of TX_CTL pad
15 - rxd0-skew-ps : Skew control of RX data 0 pad
16 - rxd1-skew-ps : Skew control of RX data 1 pad
17 - rxd2-skew-ps : Skew control of RX data 2 pad
18 - rxd3-skew-ps : Skew control of RX data 3 pad
19 - txd0-skew-ps : Skew control of TX data 0 pad
20 - txd1-skew-ps : Skew control of TX data 1 pad
21 - txd2-skew-ps : Skew control of TX data 2 pad
22 - txd3-skew-ps : Skew control of TX data 3 pad
23
24Examples:
25
26 /* Attach to an Ethernet device with autodetected PHY */
27 &enet {
28 rxc-skew-ps = <3000>;
29 rxdv-skew-ps = <0>;
30 txc-skew-ps = <3000>;
31 txen-skew-ps = <0>;
32 status = "okay";
33 };
34
35 /* Attach to an explicitly-specified PHY */
36 mdio {
37 phy0: ethernet-phy@0 {
38 rxc-skew-ps = <3000>;
39 rxdv-skew-ps = <0>;
40 txc-skew-ps = <3000>;
41 txen-skew-ps = <0>;
42 reg = <0>;
43 };
44 };
45 ethernet@70000 {
46 status = "okay";
47 phy = <&phy0>;
48 phy-mode = "rgmii-id";
49 };
diff --git a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt
new file mode 100644
index 000000000000..692076fda0e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt
@@ -0,0 +1,83 @@
1Micrel KSZ9021/KSZ9031 Gigabit Ethernet PHY
2
3Some boards require special tuning values, particularly when it comes to
4clock delays. You can specify clock delay values by adding
5micrel-specific properties to an Ethernet OF device node.
6
7Note that these settings are applied after any phy-specific fixup from
8phy_fixup_list (see phy_init_hw() from drivers/net/phy/phy_device.c),
9and therefore may overwrite them.
10
11KSZ9021:
12
13 All skew control options are specified in picoseconds. The minimum
14 value is 0, the maximum value is 3000, and it is incremented by 200ps
15 steps.
16
17 Optional properties:
18
19 - rxc-skew-ps : Skew control of RXC pad
20 - rxdv-skew-ps : Skew control of RX CTL pad
21 - txc-skew-ps : Skew control of TXC pad
22 - txen-skew-ps : Skew control of TX CTL pad
23 - rxd0-skew-ps : Skew control of RX data 0 pad
24 - rxd1-skew-ps : Skew control of RX data 1 pad
25 - rxd2-skew-ps : Skew control of RX data 2 pad
26 - rxd3-skew-ps : Skew control of RX data 3 pad
27 - txd0-skew-ps : Skew control of TX data 0 pad
28 - txd1-skew-ps : Skew control of TX data 1 pad
29 - txd2-skew-ps : Skew control of TX data 2 pad
30 - txd3-skew-ps : Skew control of TX data 3 pad
31
32KSZ9031:
33
34 All skew control options are specified in picoseconds. The minimum
35 value is 0, and the maximum is property-dependent. The increment
36 step is 60ps.
37
38 Optional properties:
39
40 Maximum value of 1860:
41
42 - rxc-skew-ps : Skew control of RX clock pad
43 - txc-skew-ps : Skew control of TX clock pad
44
45 Maximum value of 900:
46
47 - rxdv-skew-ps : Skew control of RX CTL pad
48 - txen-skew-ps : Skew control of TX CTL pad
49 - rxd0-skew-ps : Skew control of RX data 0 pad
50 - rxd1-skew-ps : Skew control of RX data 1 pad
51 - rxd2-skew-ps : Skew control of RX data 2 pad
52 - rxd3-skew-ps : Skew control of RX data 3 pad
53 - txd0-skew-ps : Skew control of TX data 0 pad
54 - txd1-skew-ps : Skew control of TX data 1 pad
55 - txd2-skew-ps : Skew control of TX data 2 pad
56 - txd3-skew-ps : Skew control of TX data 3 pad
57
58Examples:
59
60 /* Attach to an Ethernet device with autodetected PHY */
61 &enet {
62 rxc-skew-ps = <3000>;
63 rxdv-skew-ps = <0>;
64 txc-skew-ps = <3000>;
65 txen-skew-ps = <0>;
66 status = "okay";
67 };
68
69 /* Attach to an explicitly-specified PHY */
70 mdio {
71 phy0: ethernet-phy@0 {
72 rxc-skew-ps = <3000>;
73 rxdv-skew-ps = <0>;
74 txc-skew-ps = <3000>;
75 txen-skew-ps = <0>;
76 reg = <0>;
77 };
78 };
79 ethernet@70000 {
80 status = "okay";
81 phy = <&phy0>;
82 phy-mode = "rgmii-id";
83 };
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index d849684231c1..bc7c7d2f75f2 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -283,6 +283,110 @@ static int ksz9021_config_init(struct phy_device *phydev)
283 return 0; 283 return 0;
284} 284}
285 285
286#define MII_KSZ9031RN_MMD_CTRL_REG 0x0d
287#define MII_KSZ9031RN_MMD_REGDATA_REG 0x0e
288#define OP_DATA 1
289#define KSZ9031_PS_TO_REG 60
290
291/* Extended registers */
292#define MII_KSZ9031RN_CONTROL_PAD_SKEW 4
293#define MII_KSZ9031RN_RX_DATA_PAD_SKEW 5
294#define MII_KSZ9031RN_TX_DATA_PAD_SKEW 6
295#define MII_KSZ9031RN_CLK_PAD_SKEW 8
296
297static int ksz9031_extended_write(struct phy_device *phydev,
298 u8 mode, u32 dev_addr, u32 regnum, u16 val)
299{
300 phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
301 phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
302 phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
303 return phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, val);
304}
305
306static int ksz9031_extended_read(struct phy_device *phydev,
307 u8 mode, u32 dev_addr, u32 regnum)
308{
309 phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
310 phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
311 phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
312 return phy_read(phydev, MII_KSZ9031RN_MMD_REGDATA_REG);
313}
314
315static int ksz9031_of_load_skew_values(struct phy_device *phydev,
316 struct device_node *of_node,
317 u16 reg, size_t field_sz,
318 char *field[], u8 numfields)
319{
320 int val[4] = {-1, -2, -3, -4};
321 int matches = 0;
322 u16 mask;
323 u16 maxval;
324 u16 newval;
325 int i;
326
327 for (i = 0; i < numfields; i++)
328 if (!of_property_read_u32(of_node, field[i], val + i))
329 matches++;
330
331 if (!matches)
332 return 0;
333
334 if (matches < numfields)
335 newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg);
336 else
337 newval = 0;
338
339 maxval = (field_sz == 4) ? 0xf : 0x1f;
340 for (i = 0; i < numfields; i++)
341 if (val[i] != -(i + 1)) {
342 mask = 0xffff;
343 mask ^= maxval << (field_sz * i);
344 newval = (newval & mask) |
345 (((val[i] / KSZ9031_PS_TO_REG) & maxval)
346 << (field_sz * i));
347 }
348
349 return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval);
350}
351
352static int ksz9031_config_init(struct phy_device *phydev)
353{
354 struct device *dev = &phydev->dev;
355 struct device_node *of_node = dev->of_node;
356 char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"};
357 char *rx_data_skews[4] = {
358 "rxd0-skew-ps", "rxd1-skew-ps",
359 "rxd2-skew-ps", "rxd3-skew-ps"
360 };
361 char *tx_data_skews[4] = {
362 "txd0-skew-ps", "txd1-skew-ps",
363 "txd2-skew-ps", "txd3-skew-ps"
364 };
365 char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"};
366
367 if (!of_node && dev->parent->of_node)
368 of_node = dev->parent->of_node;
369
370 if (of_node) {
371 ksz9031_of_load_skew_values(phydev, of_node,
372 MII_KSZ9031RN_CLK_PAD_SKEW, 5,
373 clk_skews, 2);
374
375 ksz9031_of_load_skew_values(phydev, of_node,
376 MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
377 control_skews, 2);
378
379 ksz9031_of_load_skew_values(phydev, of_node,
380 MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
381 rx_data_skews, 4);
382
383 ksz9031_of_load_skew_values(phydev, of_node,
384 MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
385 tx_data_skews, 4);
386 }
387 return 0;
388}
389
286#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 390#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
287#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6) 391#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6)
288#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4) 392#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4)
@@ -469,7 +573,7 @@ static struct phy_driver ksphy_driver[] = {
469 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause 573 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause
470 | SUPPORTED_Asym_Pause), 574 | SUPPORTED_Asym_Pause),
471 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 575 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
472 .config_init = kszphy_config_init, 576 .config_init = ksz9031_config_init,
473 .config_aneg = genphy_config_aneg, 577 .config_aneg = genphy_config_aneg,
474 .read_status = genphy_read_status, 578 .read_status = genphy_read_status,
475 .ack_interrupt = kszphy_ack_interrupt, 579 .ack_interrupt = kszphy_ack_interrupt,