aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2018-11-14 11:30:07 -0500
committerTom Rini <trini@konsulko.com>2018-11-14 11:30:07 -0500
commit208ecbad2ea83333e8f3c9933213867addf16f4a (patch)
tree7af7000318ac1987179fc398a267caf1cac13af8
parent0157013f4a4945bbdb70bb4d98d680e0845fd784 (diff)
parent9e2a90280939fd896eb7af5db49c0410d5bd8420 (diff)
downloadu-boot-208ecbad2ea83333e8f3c9933213867addf16f4a.zip
u-boot-208ecbad2ea83333e8f3c9933213867addf16f4a.tar.gz
u-boot-208ecbad2ea83333e8f3c9933213867addf16f4a.tar.bz2
Merge branch 'next'
This brings in the u-boot-net PR from Joe.
-rw-r--r--arch/arm/dts/ast2500-evb.dts23
-rw-r--r--arch/arm/dts/ast2500.dtsi1949
-rw-r--r--arch/arm/include/asm/ti-common/keystone_net.h27
-rw-r--r--arch/arm/mach-davinci/dp83848.c2
-rw-r--r--arch/arm/mach-davinci/et1011c.c2
-rw-r--r--arch/arm/mach-davinci/ksz8873.c2
-rw-r--r--arch/arm/mach-davinci/lxt972.c2
-rw-r--r--board/ti/ks2_evm/board.c53
-rw-r--r--board/ti/ks2_evm/board.h3
-rw-r--r--board/ti/ks2_evm/board_k2e.c74
-rw-r--r--board/ti/ks2_evm/board_k2g.c18
-rw-r--r--board/ti/ks2_evm/board_k2hk.c42
-rw-r--r--board/ti/ks2_evm/board_k2l.c42
-rw-r--r--configs/evb-ast2500_defconfig8
-rw-r--r--configs/k2e_evm_defconfig1
-rw-r--r--configs/k2e_hs_evm_defconfig1
-rw-r--r--configs/k2g_evm_defconfig1
-rw-r--r--configs/k2g_hs_evm_defconfig1
-rw-r--r--configs/k2hk_evm_defconfig1
-rw-r--r--configs/k2hk_hs_evm_defconfig1
-rw-r--r--configs/k2l_evm_defconfig1
-rw-r--r--configs/k2l_hs_evm_defconfig1
-rw-r--r--doc/device-tree-bindings/net/mediatek,mt7628-eth.txt17
-rw-r--r--drivers/clk/aspeed/clk_ast2500.c39
-rw-r--r--drivers/net/Kconfig45
-rw-r--r--drivers/net/Makefile5
-rw-r--r--drivers/net/ftgmac100.c732
-rw-r--r--drivers/net/ftgmac100.h158
-rw-r--r--drivers/net/mt7628-eth.c644
-rw-r--r--drivers/net/phy/mscc.c995
-rw-r--r--drivers/net/ti/Kconfig20
-rw-r--r--drivers/net/ti/Makefile7
-rw-r--r--drivers/net/ti/cpsw-common.c (renamed from drivers/net/cpsw-common.c)0
-rw-r--r--drivers/net/ti/cpsw.c (renamed from drivers/net/cpsw.c)146
-rw-r--r--drivers/net/ti/cpsw_mdio.c203
-rw-r--r--drivers/net/ti/cpsw_mdio.h18
-rw-r--r--drivers/net/ti/davinci_emac.c (renamed from drivers/net/davinci_emac.c)0
-rw-r--r--drivers/net/ti/davinci_emac.h (renamed from drivers/net/davinci_emac.h)0
-rw-r--r--drivers/net/ti/keystone_net.c (renamed from drivers/net/keystone_net.c)401
-rw-r--r--include/configs/ti_armv7_keystone2.h1
-rw-r--r--include/netdev.h1
41 files changed, 3657 insertions, 2030 deletions
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index 723941a..ebf44fd 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -11,6 +11,11 @@
chosen {
stdout-path = &uart5;
};
+
+ aliases {
+ ethernet0 = &mac0;
+ ethernet1 = &mac1;
+ };
};
&uart5 {
@@ -36,3 +41,21 @@
u-boot,dm-pre-reloc;
status = "okay";
};
+
+&mac0 {
+ status = "okay";
+
+ phy-mode = "rgmii";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mac1link_default &pinctrl_mdio1_default>;
+};
+
+&mac1 {
+ status = "okay";
+
+ phy-mode = "rgmii";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mac2link_default &pinctrl_mdio2_default>;
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
index 7e0ad3a..98359bf 100644
--- a/arch/arm/dts/ast2500.dtsi
+++ b/arch/arm/dts/ast2500.dtsi
@@ -11,6 +11,29 @@
#size-cells = <1>;
interrupt-parent = <&vic>;
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ i2c7 = &i2c7;
+ i2c8 = &i2c8;
+ i2c9 = &i2c9;
+ i2c10 = &i2c10;
+ i2c11 = &i2c11;
+ i2c12 = &i2c12;
+ i2c13 = &i2c13;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &vuart;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -22,12 +45,80 @@
};
};
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
+ fmc: flash-controller@1e620000 {
+ reg = < 0x1e620000 0xc4
+ 0x20000000 0x10000000 >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "aspeed,ast2500-fmc";
+ status = "disabled";
+ interrupts = <19>;
+ flash@0 {
+ reg = < 0 >;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ flash@1 {
+ reg = < 1 >;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ flash@2 {
+ reg = < 2 >;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ };
+
+ spi1: flash-controller@1e630000 {
+ reg = < 0x1e630000 0xc4
+ 0x30000000 0x08000000 >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "aspeed,ast2500-spi";
+ status = "disabled";
+ flash@0 {
+ reg = < 0 >;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ flash@1 {
+ reg = < 1 >;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ };
+
+ spi2: flash-controller@1e631000 {
+ reg = < 0x1e631000 0xc4
+ 0x38000000 0x08000000 >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "aspeed,ast2500-spi";
+ status = "disabled";
+ flash@0 {
+ reg = < 0 >;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ flash@1 {
+ reg = < 1 >;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ };
+
vic: interrupt-controller@1e6c0080 {
compatible = "aspeed,ast2400-vic";
interrupt-controller;
@@ -37,18 +128,38 @@
};
mac0: ethernet@1e660000 {
- compatible = "faraday,ftgmac100";
+ compatible = "aspeed,ast2500-mac", "faraday,ftgmac100";
reg = <0x1e660000 0x180>;
interrupts = <2>;
- no-hw-checksum;
status = "disabled";
};
mac1: ethernet@1e680000 {
- compatible = "faraday,ftgmac100";
+ compatible = "aspeed,ast2500-mac", "faraday,ftgmac100";
reg = <0x1e680000 0x180>;
interrupts = <3>;
- no-hw-checksum;
+ status = "disabled";
+ };
+
+ ehci0: usb@1e6a1000 {
+ compatible = "aspeed,ast2500-ehci", "generic-ehci";
+ reg = <0x1e6a1000 0x100>;
+ interrupts = <5>;
+ status = "disabled";
+ };
+
+ ehci1: usb@1e6a3000 {
+ compatible = "aspeed,ast2500-ehci", "generic-ehci";
+ reg = <0x1e6a3000 0x100>;
+ interrupts = <13>;
+ status = "disabled";
+ };
+
+ uhci: usb@1e6b0000 {
+ compatible = "aspeed,ast2500-uhci", "generic-uhci";
+ reg = <0x1e6b0000 0x100>;
+ interrupts = <14>;
+ #ports = <2>;
status = "disabled";
};
@@ -58,996 +169,1242 @@
#size-cells = <1>;
ranges;
- clk_clkin: clk_clkin@1e6e2070 {
- #clock-cells = <0>;
- compatible = "aspeed,g5-clkin-clock";
- reg = <0x1e6e2070 0x04>;
- };
-
syscon: syscon@1e6e2000 {
compatible = "aspeed,g5-scu", "syscon", "simple-mfd";
reg = <0x1e6e2000 0x1a8>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
pinctrl: pinctrl {
compatible = "aspeed,g5-pinctrl";
aspeed,external-nodes = <&gfx &lhc>;
- pinctrl_acpi_default: acpi_default {
- function = "ACPI";
- groups = "ACPI";
- };
+ };
+ };
- pinctrl_adc0_default: adc0_default {
- function = "ADC0";
- groups = "ADC0";
- };
+ rng: hwrng@1e6e2078 {
+ compatible = "timeriomem_rng";
+ reg = <0x1e6e2078 0x4>;
+ period = <1>;
+ quality = <100>;
+ };
- pinctrl_adc1_default: adc1_default {
- function = "ADC1";
- groups = "ADC1";
- };
+ gfx: display@1e6e6000 {
+ compatible = "aspeed,ast2500-gfx", "syscon";
+ reg = <0x1e6e6000 0x1000>;
+ reg-io-width = <4>;
+ };
- pinctrl_adc10_default: adc10_default {
- function = "ADC10";
- groups = "ADC10";
- };
+ adc: adc@1e6e9000 {
+ compatible = "aspeed,ast2500-adc";
+ reg = <0x1e6e9000 0xb0>;
+ #io-channel-cells = <1>;
+ status = "disabled";
+ };
- pinctrl_adc11_default: adc11_default {
- function = "ADC11";
- groups = "ADC11";
- };
+ sram@1e720000 {
+ compatible = "mmio-sram";
+ reg = <0x1e720000 0x9000>; // 36K
+ };
- pinctrl_adc12_default: adc12_default {
- function = "ADC12";
- groups = "ADC12";
- };
+ gpio: gpio@1e780000 {
+ #gpio-cells = <2>;
+ gpio-controller;
+ compatible = "aspeed,ast2500-gpio";
+ reg = <0x1e780000 0x1000>;
+ interrupts = <20>;
+ gpio-ranges = <&pinctrl 0 0 220>;
+ interrupt-controller;
+ };
- pinctrl_adc13_default: adc13_default {
- function = "ADC13";
- groups = "ADC13";
- };
+ timer: timer@1e782000 {
+ /* This timer is a Faraday FTTMR010 derivative */
+ compatible = "aspeed,ast2400-timer";
+ reg = <0x1e782000 0x90>;
+ };
- pinctrl_adc14_default: adc14_default {
- function = "ADC14";
- groups = "ADC14";
- };
+ uart1: serial@1e783000 {
+ compatible = "ns16550a";
+ reg = <0x1e783000 0x20>;
+ reg-shift = <2>;
+ interrupts = <9>;
+ no-loopback-test;
+ status = "disabled";
+ };
- pinctrl_adc15_default: adc15_default {
- function = "ADC15";
- groups = "ADC15";
- };
+ uart5: serial@1e784000 {
+ compatible = "ns16550a";
+ reg = <0x1e784000 0x20>;
+ reg-shift = <2>;
+ interrupts = <10>;
+ no-loopback-test;
+ status = "disabled";
+ };
- pinctrl_adc2_default: adc2_default {
- function = "ADC2";
- groups = "ADC2";
- };
+ wdt1: watchdog@1e785000 {
+ compatible = "aspeed,wdt";
+ reg = <0x1e785000 0x1c>;
+ interrupts = <27>;
+ };
- pinctrl_adc3_default: adc3_default {
- function = "ADC3";
- groups = "ADC3";
- };
+ wdt2: watchdog@1e785020 {
+ compatible = "aspeed,wdt";
+ reg = <0x1e785020 0x1c>;
+ interrupts = <27>;
+ status = "disabled";
+ };
- pinctrl_adc4_default: adc4_default {
- function = "ADC4";
- groups = "ADC4";
- };
+ wdt3: watchdog@1e785040 {
+ compatible = "aspeed,wdt";
+ reg = <0x1e785040 0x1c>;
+ status = "disabled";
+ };
- pinctrl_adc5_default: adc5_default {
- function = "ADC5";
- groups = "ADC5";
- };
+ pwm_tacho: pwm-tacho-controller@1e786000 {
+ compatible = "aspeed,ast2500-pwm-tacho";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1e786000 0x1000>;
+ status = "disabled";
+ };
- pinctrl_adc6_default: adc6_default {
- function = "ADC6";
- groups = "ADC6";
- };
+ vuart: serial@1e787000 {
+ compatible = "aspeed,ast2500-vuart";
+ reg = <0x1e787000 0x40>;
+ reg-shift = <2>;
+ interrupts = <8>;
+ no-loopback-test;
+ status = "disabled";
+ };
- pinctrl_adc7_default: adc7_default {
- function = "ADC7";
- groups = "ADC7";
- };
+ lpc: lpc@1e789000 {
+ compatible = "aspeed,ast2500-lpc", "simple-mfd";
+ reg = <0x1e789000 0x1000>;
- pinctrl_adc8_default: adc8_default {
- function = "ADC8";
- groups = "ADC8";
- };
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1e789000 0x1000>;
- pinctrl_adc9_default: adc9_default {
- function = "ADC9";
- groups = "ADC9";
- };
+ lpc_bmc: lpc-bmc@0 {
+ compatible = "aspeed,ast2500-lpc-bmc";
+ reg = <0x0 0x80>;
+ };
- pinctrl_bmcint_default: bmcint_default {
- function = "BMCINT";
- groups = "BMCINT";
- };
+ lpc_host: lpc-host@80 {
+ compatible = "aspeed,ast2500-lpc-host", "simple-mfd", "syscon";
+ reg = <0x80 0x1e0>;
+ reg-io-width = <4>;
- pinctrl_ddcclk_default: ddcclk_default {
- function = "DDCCLK";
- groups = "DDCCLK";
- };
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x80 0x1e0>;
- pinctrl_ddcdat_default: ddcdat_default {
- function = "DDCDAT";
- groups = "DDCDAT";
+ lpc_ctrl: lpc-ctrl@0 {
+ compatible = "aspeed,ast2500-lpc-ctrl";
+ reg = <0x0 0x80>;
+ status = "disabled";
};
- pinctrl_espi_default: espi_default {
- function = "ESPI";
- groups = "ESPI";
+ lpc_snoop: lpc-snoop@0 {
+ compatible = "aspeed,ast2500-lpc-snoop";
+ reg = <0x0 0x80>;
+ interrupts = <8>;
+ status = "disabled";
};
- pinctrl_fwspics1_default: fwspics1_default {
- function = "FWSPICS1";
- groups = "FWSPICS1";
+ lhc: lhc@20 {
+ compatible = "aspeed,ast2500-lhc";
+ reg = <0x20 0x24 0x48 0x8>;
};
- pinctrl_fwspics2_default: fwspics2_default {
- function = "FWSPICS2";
- groups = "FWSPICS2";
+ lpc_reset: reset-controller@18 {
+ compatible = "aspeed,ast2500-lpc-reset";
+ reg = <0x18 0x4>;
+ #reset-cells = <1>;
};
- pinctrl_gpid0_default: gpid0_default {
- function = "GPID0";
- groups = "GPID0";
+ ibt: ibt@c0 {
+ compatible = "aspeed,ast2500-ibt-bmc";
+ reg = <0xc0 0x18>;
+ interrupts = <8>;
+ status = "disabled";
};
+ };
+ };
- pinctrl_gpid2_default: gpid2_default {
- function = "GPID2";
- groups = "GPID2";
- };
+ uart2: serial@1e78d000 {
+ compatible = "ns16550a";
+ reg = <0x1e78d000 0x20>;
+ reg-shift = <2>;
+ interrupts = <32>;
+ no-loopback-test;
+ status = "disabled";
+ };
- pinctrl_gpid4_default: gpid4_default {
- function = "GPID4";
- groups = "GPID4";
- };
+ uart3: serial@1e78e000 {
+ compatible = "ns16550a";
+ reg = <0x1e78e000 0x20>;
+ reg-shift = <2>;
+ interrupts = <33>;
+ no-loopback-test;
+ status = "disabled";
+ };
- pinctrl_gpid6_default: gpid6_default {
- function = "GPID6";
- groups = "GPID6";
- };
+ uart4: serial@1e78f000 {
+ compatible = "ns16550a";
+ reg = <0x1e78f000 0x20>;
+ reg-shift = <2>;
+ interrupts = <34>;
+ no-loopback-test;
+ status = "disabled";
+ };
- pinctrl_gpie0_default: gpie0_default {
- function = "GPIE0";
- groups = "GPIE0";
- };
+ i2c: i2c@1e78a000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x1e78a000 0x1000>;
+ };
+ };
+ };
+};
- pinctrl_gpie2_default: gpie2_default {
- function = "GPIE2";
- groups = "GPIE2";
- };
+&i2c {
+ i2c_ic: interrupt-controller@0 {
+ #interrupt-cells = <1>;
+ compatible = "aspeed,ast2500-i2c-ic";
+ reg = <0x0 0x40>;
+ interrupts = <12>;
+ interrupt-controller;
+ };
- pinctrl_gpie4_default: gpie4_default {
- function = "GPIE4";
- groups = "GPIE4";
- };
+ i2c0: i2c-bus@40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x40 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <0>;
+ interrupt-parent = <&i2c_ic>;
+ status = "disabled";
+ /* Does not need pinctrl properties */
+ };
- pinctrl_gpie6_default: gpie6_default {
- function = "GPIE6";
- groups = "GPIE6";
- };
+ i2c1: i2c-bus@80 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x80 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <1>;
+ interrupt-parent = <&i2c_ic>;
+ status = "disabled";
+ /* Does not need pinctrl properties */
+ };
- pinctrl_i2c10_default: i2c10_default {
- function = "I2C10";
- groups = "I2C10";
- };
+ i2c2: i2c-bus@c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0xc0 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <2>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_default>;
+ status = "disabled";
+ };
- pinctrl_i2c11_default: i2c11_default {
- function = "I2C11";
- groups = "I2C11";
- };
+ i2c3: i2c-bus@100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x100 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <3>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4_default>;
+ status = "disabled";
+ };
- pinctrl_i2c12_default: i2c12_default {
- function = "I2C12";
- groups = "I2C12";
- };
+ i2c4: i2c-bus@140 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x140 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <4>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c5_default>;
+ status = "disabled";
+ };
- pinctrl_i2c13_default: i2c13_default {
- function = "I2C13";
- groups = "I2C13";
- };
+ i2c5: i2c-bus@180 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x180 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <5>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c6_default>;
+ status = "disabled";
+ };
- pinctrl_i2c14_default: i2c14_default {
- function = "I2C14";
- groups = "I2C14";
- };
+ i2c6: i2c-bus@1c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x1c0 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <6>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c7_default>;
+ status = "disabled";
+ };
- pinctrl_i2c3_default: i2c3_default {
- function = "I2C3";
- groups = "I2C3";
- };
+ i2c7: i2c-bus@300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x300 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <7>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c8_default>;
+ status = "disabled";
+ };
- pinctrl_i2c4_default: i2c4_default {
- function = "I2C4";
- groups = "I2C4";
- };
+ i2c8: i2c-bus@340 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x340 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <8>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c9_default>;
+ status = "disabled";
+ };
- pinctrl_i2c5_default: i2c5_default {
- function = "I2C5";
- groups = "I2C5";
- };
+ i2c9: i2c-bus@380 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x380 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <9>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c10_default>;
+ status = "disabled";
+ };
- pinctrl_i2c6_default: i2c6_default {
- function = "I2C6";
- groups = "I2C6";
- };
+ i2c10: i2c-bus@3c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x3c0 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <10>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c11_default>;
+ status = "disabled";
+ };
- pinctrl_i2c7_default: i2c7_default {
- function = "I2C7";
- groups = "I2C7";
- };
+ i2c11: i2c-bus@400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x400 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <11>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c12_default>;
+ status = "disabled";
+ };
- pinctrl_i2c8_default: i2c8_default {
- function = "I2C8";
- groups = "I2C8";
- };
+ i2c12: i2c-bus@440 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x440 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <12>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c13_default>;
+ status = "disabled";
+ };
- pinctrl_i2c9_default: i2c9_default {
- function = "I2C9";
- groups = "I2C9";
- };
+ i2c13: i2c-bus@480 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+
+ reg = <0x480 0x40>;
+ compatible = "aspeed,ast2500-i2c-bus";
+ bus-frequency = <100000>;
+ interrupts = <13>;
+ interrupt-parent = <&i2c_ic>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c14_default>;
+ status = "disabled";
+ };
+};
- pinctrl_lad0_default: lad0_default {
- function = "LAD0";
- groups = "LAD0";
- };
+&pinctrl {
+ pinctrl_acpi_default: acpi_default {
+ function = "ACPI";
+ groups = "ACPI";
+ };
- pinctrl_lad1_default: lad1_default {
- function = "LAD1";
- groups = "LAD1";
- };
+ pinctrl_adc0_default: adc0_default {
+ function = "ADC0";
+ groups = "ADC0";
+ };
- pinctrl_lad2_default: lad2_default {
- function = "LAD2";
- groups = "LAD2";
- };
+ pinctrl_adc1_default: adc1_default {
+ function = "ADC1";
+ groups = "ADC1";
+ };
- pinctrl_lad3_default: lad3_default {
- function = "LAD3";
- groups = "LAD3";
- };
+ pinctrl_adc10_default: adc10_default {
+ function = "ADC10";
+ groups = "ADC10";
+ };
- pinctrl_lclk_default: lclk_default {
- function = "LCLK";
- groups = "LCLK";
- };
+ pinctrl_adc11_default: adc11_default {
+ function = "ADC11";
+ groups = "ADC11";
+ };
- pinctrl_lframe_default: lframe_default {
- function = "LFRAME";
- groups = "LFRAME";
- };
+ pinctrl_adc12_default: adc12_default {
+ function = "ADC12";
+ groups = "ADC12";
+ };
- pinctrl_lpchc_default: lpchc_default {
- function = "LPCHC";
- groups = "LPCHC";
- };
+ pinctrl_adc13_default: adc13_default {
+ function = "ADC13";
+ groups = "ADC13";
+ };
- pinctrl_lpcpd_default: lpcpd_default {
- function = "LPCPD";
- groups = "LPCPD";
- };
+ pinctrl_adc14_default: adc14_default {
+ function = "ADC14";
+ groups = "ADC14";
+ };
- pinctrl_lpcplus_default: lpcplus_default {
- function = "LPCPLUS";
- groups = "LPCPLUS";
- };
+ pinctrl_adc15_default: adc15_default {
+ function = "ADC15";
+ groups = "ADC15";
+ };
- pinctrl_lpcpme_default: lpcpme_default {
- function = "LPCPME";
- groups = "LPCPME";
- };
+ pinctrl_adc2_default: adc2_default {
+ function = "ADC2";
+ groups = "ADC2";
+ };
- pinctrl_lpcrst_default: lpcrst_default {
- function = "LPCRST";
- groups = "LPCRST";
- };
+ pinctrl_adc3_default: adc3_default {
+ function = "ADC3";
+ groups = "ADC3";
+ };
- pinctrl_lpcsmi_default: lpcsmi_default {
- function = "LPCSMI";
- groups = "LPCSMI";
- };
+ pinctrl_adc4_default: adc4_default {
+ function = "ADC4";
+ groups = "ADC4";
+ };
- pinctrl_lsirq_default: lsirq_default {
- function = "LSIRQ";
- groups = "LSIRQ";
- };
+ pinctrl_adc5_default: adc5_default {
+ function = "ADC5";
+ groups = "ADC5";
+ };
- pinctrl_mac1link_default: mac1link_default {
- function = "MAC1LINK";
- groups = "MAC1LINK";
- };
+ pinctrl_adc6_default: adc6_default {
+ function = "ADC6";
+ groups = "ADC6";
+ };
- pinctrl_mac2link_default: mac2link_default {
- function = "MAC2LINK";
- groups = "MAC2LINK";
- };
+ pinctrl_adc7_default: adc7_default {
+ function = "ADC7";
+ groups = "ADC7";
+ };
- pinctrl_mdio1_default: mdio1_default {
- function = "MDIO1";
- groups = "MDIO1";
- };
+ pinctrl_adc8_default: adc8_default {
+ function = "ADC8";
+ groups = "ADC8";
+ };
- pinctrl_mdio2_default: mdio2_default {
- function = "MDIO2";
- groups = "MDIO2";
- };
+ pinctrl_adc9_default: adc9_default {
+ function = "ADC9";
+ groups = "ADC9";
+ };
- pinctrl_ncts1_default: ncts1_default {
- function = "NCTS1";
- groups = "NCTS1";
- };
+ pinctrl_bmcint_default: bmcint_default {
+ function = "BMCINT";
+ groups = "BMCINT";
+ };
- pinctrl_ncts2_default: ncts2_default {
- function = "NCTS2";
- groups = "NCTS2";
- };
+ pinctrl_ddcclk_default: ddcclk_default {
+ function = "DDCCLK";
+ groups = "DDCCLK";
+ };
- pinctrl_ncts3_default: ncts3_default {
- function = "NCTS3";
- groups = "NCTS3";
- };
+ pinctrl_ddcdat_default: ddcdat_default {
+ function = "DDCDAT";
+ groups = "DDCDAT";
+ };
- pinctrl_ncts4_default: ncts4_default {
- function = "NCTS4";
- groups = "NCTS4";
- };
+ pinctrl_espi_default: espi_default {
+ function = "ESPI";
+ groups = "ESPI";
+ };
- pinctrl_ndcd1_default: ndcd1_default {
- function = "NDCD1";
- groups = "NDCD1";
- };
+ pinctrl_fwspics1_default: fwspics1_default {
+ function = "FWSPICS1";
+ groups = "FWSPICS1";
+ };
- pinctrl_ndcd2_default: ndcd2_default {
- function = "NDCD2";
- groups = "NDCD2";
- };
+ pinctrl_fwspics2_default: fwspics2_default {
+ function = "FWSPICS2";
+ groups = "FWSPICS2";
+ };
- pinctrl_ndcd3_default: ndcd3_default {
- function = "NDCD3";
- groups = "NDCD3";
- };
+ pinctrl_gpid0_default: gpid0_default {
+ function = "GPID0";
+ groups = "GPID0";
+ };
- pinctrl_ndcd4_default: ndcd4_default {
- function = "NDCD4";
- groups = "NDCD4";
- };
+ pinctrl_gpid2_default: gpid2_default {
+ function = "GPID2";
+ groups = "GPID2";
+ };
- pinctrl_ndsr1_default: ndsr1_default {
- function = "NDSR1";
- groups = "NDSR1";
- };
+ pinctrl_gpid4_default: gpid4_default {
+ function = "GPID4";
+ groups = "GPID4";
+ };
- pinctrl_ndsr2_default: ndsr2_default {
- function = "NDSR2";
- groups = "NDSR2";
- };
+ pinctrl_gpid6_default: gpid6_default {
+ function = "GPID6";
+ groups = "GPID6";
+ };
- pinctrl_ndsr3_default: ndsr3_default {
- function = "NDSR3";
- groups = "NDSR3";
- };
+ pinctrl_gpie0_default: gpie0_default {
+ function = "GPIE0";
+ groups = "GPIE0";
+ };
- pinctrl_ndsr4_default: ndsr4_default {
- function = "NDSR4";
- groups = "NDSR4";
- };
+ pinctrl_gpie2_default: gpie2_default {
+ function = "GPIE2";
+ groups = "GPIE2";
+ };
- pinctrl_ndtr1_default: ndtr1_default {
- function = "NDTR1";
- groups = "NDTR1";
- };
+ pinctrl_gpie4_default: gpie4_default {
+ function = "GPIE4";
+ groups = "GPIE4";
+ };
- pinctrl_ndtr2_default: ndtr2_default {
- function = "NDTR2";
- groups = "NDTR2";
- };
+ pinctrl_gpie6_default: gpie6_default {
+ function = "GPIE6";
+ groups = "GPIE6";
+ };
- pinctrl_ndtr3_default: ndtr3_default {
- function = "NDTR3";
- groups = "NDTR3";
- };
+ pinctrl_i2c10_default: i2c10_default {
+ function = "I2C10";
+ groups = "I2C10";
+ };
- pinctrl_ndtr4_default: ndtr4_default {
- function = "NDTR4";
- groups = "NDTR4";
- };
+ pinctrl_i2c11_default: i2c11_default {
+ function = "I2C11";
+ groups = "I2C11";
+ };
- pinctrl_nri1_default: nri1_default {
- function = "NRI1";
- groups = "NRI1";
- };
+ pinctrl_i2c12_default: i2c12_default {
+ function = "I2C12";
+ groups = "I2C12";
+ };
- pinctrl_nri2_default: nri2_default {
- function = "NRI2";
- groups = "NRI2";
- };
+ pinctrl_i2c13_default: i2c13_default {
+ function = "I2C13";
+ groups = "I2C13";
+ };
- pinctrl_nri3_default: nri3_default {
- function = "NRI3";
- groups = "NRI3";
- };
+ pinctrl_i2c14_default: i2c14_default {
+ function = "I2C14";
+ groups = "I2C14";
+ };
- pinctrl_nri4_default: nri4_default {
- function = "NRI4";
- groups = "NRI4";
- };
+ pinctrl_i2c3_default: i2c3_default {
+ function = "I2C3";
+ groups = "I2C3";
+ };
- pinctrl_nrts1_default: nrts1_default {
- function = "NRTS1";
- groups = "NRTS1";
- };
+ pinctrl_i2c4_default: i2c4_default {
+ function = "I2C4";
+ groups = "I2C4";
+ };
- pinctrl_nrts2_default: nrts2_default {
- function = "NRTS2";
- groups = "NRTS2";
- };
+ pinctrl_i2c5_default: i2c5_default {
+ function = "I2C5";
+ groups = "I2C5";
+ };
- pinctrl_nrts3_default: nrts3_default {
- function = "NRTS3";
- groups = "NRTS3";
- };
+ pinctrl_i2c6_default: i2c6_default {
+ function = "I2C6";
+ groups = "I2C6";
+ };
- pinctrl_nrts4_default: nrts4_default {
- function = "NRTS4";
- groups = "NRTS4";
- };
+ pinctrl_i2c7_default: i2c7_default {
+ function = "I2C7";
+ groups = "I2C7";
+ };
- pinctrl_oscclk_default: oscclk_default {
- function = "OSCCLK";
- groups = "OSCCLK";
- };
+ pinctrl_i2c8_default: i2c8_default {
+ function = "I2C8";
+ groups = "I2C8";
+ };
- pinctrl_pewake_default: pewake_default {
- function = "PEWAKE";
- groups = "PEWAKE";
- };
+ pinctrl_i2c9_default: i2c9_default {
+ function = "I2C9";
+ groups = "I2C9";
+ };
- pinctrl_pnor_default: pnor_default {
- function = "PNOR";
- groups = "PNOR";
- };
+ pinctrl_lad0_default: lad0_default {
+ function = "LAD0";
+ groups = "LAD0";
+ };
- pinctrl_pwm0_default: pwm0_default {
- function = "PWM0";
- groups = "PWM0";
- };
+ pinctrl_lad1_default: lad1_default {
+ function = "LAD1";
+ groups = "LAD1";
+ };
- pinctrl_pwm1_default: pwm1_default {
- function = "PWM1";
- groups = "PWM1";
- };
+ pinctrl_lad2_default: lad2_default {
+ function = "LAD2";
+ groups = "LAD2";
+ };
- pinctrl_pwm2_default: pwm2_default {
- function = "PWM2";
- groups = "PWM2";
- };
+ pinctrl_lad3_default: lad3_default {
+ function = "LAD3";
+ groups = "LAD3";
+ };
- pinctrl_pwm3_default: pwm3_default {
- function = "PWM3";
- groups = "PWM3";
- };
+ pinctrl_lclk_default: lclk_default {
+ function = "LCLK";
+ groups = "LCLK";
+ };
- pinctrl_pwm4_default: pwm4_default {
- function = "PWM4";
- groups = "PWM4";
- };
+ pinctrl_lframe_default: lframe_default {
+ function = "LFRAME";
+ groups = "LFRAME";
+ };
- pinctrl_pwm5_default: pwm5_default {
- function = "PWM5";
- groups = "PWM5";
- };
+ pinctrl_lpchc_default: lpchc_default {
+ function = "LPCHC";
+ groups = "LPCHC";
+ };
- pinctrl_pwm6_default: pwm6_default {
- function = "PWM6";
- groups = "PWM6";
- };
+ pinctrl_lpcpd_default: lpcpd_default {
+ function = "LPCPD";
+ groups = "LPCPD";
+ };
- pinctrl_pwm7_default: pwm7_default {
- function = "PWM7";
- groups = "PWM7";
- };
+ pinctrl_lpcplus_default: lpcplus_default {
+ function = "LPCPLUS";
+ groups = "LPCPLUS";
+ };
- pinctrl_rgmii1_default: rgmii1_default {
- function = "RGMII1";
- groups = "RGMII1";
- };
+ pinctrl_lpcpme_default: lpcpme_default {
+ function = "LPCPME";
+ groups = "LPCPME";
+ };
- pinctrl_rgmii2_default: rgmii2_default {
- function = "RGMII2";
- groups = "RGMII2";
- };
+ pinctrl_lpcrst_default: lpcrst_default {
+ function = "LPCRST";
+ groups = "LPCRST";
+ };
- pinctrl_rmii1_default: rmii1_default {
- function = "RMII1";
- groups = "RMII1";
- };
+ pinctrl_lpcsmi_default: lpcsmi_default {
+ function = "LPCSMI";
+ groups = "LPCSMI";
+ };
- pinctrl_rmii2_default: rmii2_default {
- function = "RMII2";
- groups = "RMII2";
- };
+ pinctrl_lsirq_default: lsirq_default {
+ function = "LSIRQ";
+ groups = "LSIRQ";
+ };
- pinctrl_rxd1_default: rxd1_default {
- function = "RXD1";
- groups = "RXD1";
- };
+ pinctrl_mac1link_default: mac1link_default {
+ function = "MAC1LINK";
+ groups = "MAC1LINK";
+ };
- pinctrl_rxd2_default: rxd2_default {
- function = "RXD2";
- groups = "RXD2";
- };
+ pinctrl_mac2link_default: mac2link_default {
+ function = "MAC2LINK";
+ groups = "MAC2LINK";
+ };
- pinctrl_rxd3_default: rxd3_default {
- function = "RXD3";
- groups = "RXD3";
- };
+ pinctrl_mdio1_default: mdio1_default {
+ function = "MDIO1";
+ groups = "MDIO1";
+ };
- pinctrl_rxd4_default: rxd4_default {
- function = "RXD4";
- groups = "RXD4";
- };
+ pinctrl_mdio2_default: mdio2_default {
+ function = "MDIO2";
+ groups = "MDIO2";
+ };
- pinctrl_salt1_default: salt1_default {
- function = "SALT1";
- groups = "SALT1";
- };
+ pinctrl_ncts1_default: ncts1_default {
+ function = "NCTS1";
+ groups = "NCTS1";
+ };
- pinctrl_salt10_default: salt10_default {
- function = "SALT10";
- groups = "SALT10";
- };
+ pinctrl_ncts2_default: ncts2_default {
+ function = "NCTS2";
+ groups = "NCTS2";
+ };
- pinctrl_salt11_default: salt11_default {
- function = "SALT11";
- groups = "SALT11";
- };
+ pinctrl_ncts3_default: ncts3_default {
+ function = "NCTS3";
+ groups = "NCTS3";
+ };
- pinctrl_salt12_default: salt12_default {
- function = "SALT12";
- groups = "SALT12";
- };
+ pinctrl_ncts4_default: ncts4_default {
+ function = "NCTS4";
+ groups = "NCTS4";
+ };
- pinctrl_salt13_default: salt13_default {
- function = "SALT13";
- groups = "SALT13";
- };
+ pinctrl_ndcd1_default: ndcd1_default {
+ function = "NDCD1";
+ groups = "NDCD1";
+ };
- pinctrl_salt14_default: salt14_default {
- function = "SALT14";
- groups = "SALT14";
- };
+ pinctrl_ndcd2_default: ndcd2_default {
+ function = "NDCD2";
+ groups = "NDCD2";
+ };
- pinctrl_salt2_default: salt2_default {
- function = "SALT2";
- groups = "SALT2";
- };
+ pinctrl_ndcd3_default: ndcd3_default {
+ function = "NDCD3";
+ groups = "NDCD3";
+ };
- pinctrl_salt3_default: salt3_default {
- function = "SALT3";
- groups = "SALT3";
- };
+ pinctrl_ndcd4_default: ndcd4_default {
+ function = "NDCD4";
+ groups = "NDCD4";
+ };
- pinctrl_salt4_default: salt4_default {
- function = "SALT4";
- groups = "SALT4";
- };
+ pinctrl_ndsr1_default: ndsr1_default {
+ function = "NDSR1";
+ groups = "NDSR1";
+ };
- pinctrl_salt5_default: salt5_default {
- function = "SALT5";
- groups = "SALT5";
- };
+ pinctrl_ndsr2_default: ndsr2_default {
+ function = "NDSR2";
+ groups = "NDSR2";
+ };
- pinctrl_salt6_default: salt6_default {
- function = "SALT6";
- groups = "SALT6";
- };
+ pinctrl_ndsr3_default: ndsr3_default {
+ function = "NDSR3";
+ groups = "NDSR3";
+ };
- pinctrl_salt7_default: salt7_default {
- function = "SALT7";
- groups = "SALT7";
- };
+ pinctrl_ndsr4_default: ndsr4_default {
+ function = "NDSR4";
+ groups = "NDSR4";
+ };
- pinctrl_salt8_default: salt8_default {
- function = "SALT8";
- groups = "SALT8";
- };
+ pinctrl_ndtr1_default: ndtr1_default {
+ function = "NDTR1";
+ groups = "NDTR1";
+ };
- pinctrl_salt9_default: salt9_default {
- function = "SALT9";
- groups = "SALT9";
- };
+ pinctrl_ndtr2_default: ndtr2_default {
+ function = "NDTR2";
+ groups = "NDTR2";
+ };
- pinctrl_scl1_default: scl1_default {
- function = "SCL1";
- groups = "SCL1";
- };
+ pinctrl_ndtr3_default: ndtr3_default {
+ function = "NDTR3";
+ groups = "NDTR3";
+ };
- pinctrl_scl2_default: scl2_default {
- function = "SCL2";
- groups = "SCL2";
- };
+ pinctrl_ndtr4_default: ndtr4_default {
+ function = "NDTR4";
+ groups = "NDTR4";
+ };
- pinctrl_sd1_default: sd1_default {
- function = "SD1";
- groups = "SD1";
- };
+ pinctrl_nri1_default: nri1_default {
+ function = "NRI1";
+ groups = "NRI1";
+ };
- pinctrl_sd2_default: sd2_default {
- function = "SD2";
- groups = "SD2";
- };
+ pinctrl_nri2_default: nri2_default {
+ function = "NRI2";
+ groups = "NRI2";
+ };
- pinctrl_sda1_default: sda1_default {
- function = "SDA1";
- groups = "SDA1";
- };
+ pinctrl_nri3_default: nri3_default {
+ function = "NRI3";
+ groups = "NRI3";
+ };
- pinctrl_sda2_default: sda2_default {
- function = "SDA2";
- groups = "SDA2";
- };
+ pinctrl_nri4_default: nri4_default {
+ function = "NRI4";
+ groups = "NRI4";
+ };
- pinctrl_sgps1_default: sgps1_default {
- function = "SGPS1";
- groups = "SGPS1";
- };
+ pinctrl_nrts1_default: nrts1_default {
+ function = "NRTS1";
+ groups = "NRTS1";
+ };
- pinctrl_sgps2_default: sgps2_default {
- function = "SGPS2";
- groups = "SGPS2";
- };
+ pinctrl_nrts2_default: nrts2_default {
+ function = "NRTS2";
+ groups = "NRTS2";
+ };
- pinctrl_sioonctrl_default: sioonctrl_default {
- function = "SIOONCTRL";
- groups = "SIOONCTRL";
- };
+ pinctrl_nrts3_default: nrts3_default {
+ function = "NRTS3";
+ groups = "NRTS3";
+ };
- pinctrl_siopbi_default: siopbi_default {
- function = "SIOPBI";
- groups = "SIOPBI";
- };
+ pinctrl_nrts4_default: nrts4_default {
+ function = "NRTS4";
+ groups = "NRTS4";
+ };
- pinctrl_siopbo_default: siopbo_default {
- function = "SIOPBO";
- groups = "SIOPBO";
- };
+ pinctrl_oscclk_default: oscclk_default {
+ function = "OSCCLK";
+ groups = "OSCCLK";
+ };
- pinctrl_siopwreq_default: siopwreq_default {
- function = "SIOPWREQ";
- groups = "SIOPWREQ";
- };
+ pinctrl_pewake_default: pewake_default {
+ function = "PEWAKE";
+ groups = "PEWAKE";
+ };
- pinctrl_siopwrgd_default: siopwrgd_default {
- function = "SIOPWRGD";
- groups = "SIOPWRGD";
- };
+ pinctrl_pnor_default: pnor_default {
+ function = "PNOR";
+ groups = "PNOR";
+ };
- pinctrl_sios3_default: sios3_default {
- function = "SIOS3";
- groups = "SIOS3";
- };
+ pinctrl_pwm0_default: pwm0_default {
+ function = "PWM0";
+ groups = "PWM0";
+ };
- pinctrl_sios5_default: sios5_default {
- function = "SIOS5";
- groups = "SIOS5";
- };
+ pinctrl_pwm1_default: pwm1_default {
+ function = "PWM1";
+ groups = "PWM1";
+ };
- pinctrl_siosci_default: siosci_default {
- function = "SIOSCI";
- groups = "SIOSCI";
- };
+ pinctrl_pwm2_default: pwm2_default {
+ function = "PWM2";
+ groups = "PWM2";
+ };
- pinctrl_spi1_default: spi1_default {
- function = "SPI1";
- groups = "SPI1";
- };
+ pinctrl_pwm3_default: pwm3_default {
+ function = "PWM3";
+ groups = "PWM3";
+ };
- pinctrl_spi1cs1_default: spi1cs1_default {
- function = "SPI1CS1";
- groups = "SPI1CS1";
- };
+ pinctrl_pwm4_default: pwm4_default {
+ function = "PWM4";
+ groups = "PWM4";
+ };
- pinctrl_spi1debug_default: spi1debug_default {
- function = "SPI1DEBUG";
- groups = "SPI1DEBUG";
- };
+ pinctrl_pwm5_default: pwm5_default {
+ function = "PWM5";
+ groups = "PWM5";
+ };
- pinctrl_spi1passthru_default: spi1passthru_default {
- function = "SPI1PASSTHRU";
- groups = "SPI1PASSTHRU";
- };
+ pinctrl_pwm6_default: pwm6_default {
+ function = "PWM6";
+ groups = "PWM6";
+ };
- pinctrl_spi2ck_default: spi2ck_default {
- function = "SPI2CK";
- groups = "SPI2CK";
- };
+ pinctrl_pwm7_default: pwm7_default {
+ function = "PWM7";
+ groups = "PWM7";
+ };
- pinctrl_spi2cs0_default: spi2cs0_default {
- function = "SPI2CS0";
- groups = "SPI2CS0";
- };
+ pinctrl_rgmii1_default: rgmii1_default {
+ function = "RGMII1";
+ groups = "RGMII1";
+ };
- pinctrl_spi2cs1_default: spi2cs1_default {
- function = "SPI2CS1";
- groups = "SPI2CS1";
- };
+ pinctrl_rgmii2_default: rgmii2_default {
+ function = "RGMII2";
+ groups = "RGMII2";
+ };
- pinctrl_spi2miso_default: spi2miso_default {
- function = "SPI2MISO";
- groups = "SPI2MISO";
- };
+ pinctrl_rmii1_default: rmii1_default {
+ function = "RMII1";
+ groups = "RMII1";
+ };
- pinctrl_spi2mosi_default: spi2mosi_default {
- function = "SPI2MOSI";
- groups = "SPI2MOSI";
- };
+ pinctrl_rmii2_default: rmii2_default {
+ function = "RMII2";
+ groups = "RMII2";
+ };
- pinctrl_timer3_default: timer3_default {
- function = "TIMER3";
- groups = "TIMER3";
- };
+ pinctrl_rxd1_default: rxd1_default {
+ function = "RXD1";
+ groups = "RXD1";
+ };
- pinctrl_timer4_default: timer4_default {
- function = "TIMER4";
- groups = "TIMER4";
- };
+ pinctrl_rxd2_default: rxd2_default {
+ function = "RXD2";
+ groups = "RXD2";
+ };
- pinctrl_timer5_default: timer5_default {
- function = "TIMER5";
- groups = "TIMER5";
- };
+ pinctrl_rxd3_default: rxd3_default {
+ function = "RXD3";
+ groups = "RXD3";
+ };
- pinctrl_timer6_default: timer6_default {
- function = "TIMER6";
- groups = "TIMER6";
- };
+ pinctrl_rxd4_default: rxd4_default {
+ function = "RXD4";
+ groups = "RXD4";
+ };
- pinctrl_timer7_default: timer7_default {
- function = "TIMER7";
- groups = "TIMER7";
- };
+ pinctrl_salt1_default: salt1_default {
+ function = "SALT1";
+ groups = "SALT1";
+ };
- pinctrl_timer8_default: timer8_default {
- function = "TIMER8";
- groups = "TIMER8";
- };
+ pinctrl_salt10_default: salt10_default {
+ function = "SALT10";
+ groups = "SALT10";
+ };
- pinctrl_txd1_default: txd1_default {
- function = "TXD1";
- groups = "TXD1";
- };
+ pinctrl_salt11_default: salt11_default {
+ function = "SALT11";
+ groups = "SALT11";
+ };
- pinctrl_txd2_default: txd2_default {
- function = "TXD2";
- groups = "TXD2";
- };
+ pinctrl_salt12_default: salt12_default {
+ function = "SALT12";
+ groups = "SALT12";
+ };
- pinctrl_txd3_default: txd3_default {
- function = "TXD3";
- groups = "TXD3";
- };
+ pinctrl_salt13_default: salt13_default {
+ function = "SALT13";
+ groups = "SALT13";
+ };
- pinctrl_txd4_default: txd4_default {
- function = "TXD4";
- groups = "TXD4";
- };
+ pinctrl_salt14_default: salt14_default {
+ function = "SALT14";
+ groups = "SALT14";
+ };
- pinctrl_uart6_default: uart6_default {
- function = "UART6";
- groups = "UART6";
- };
+ pinctrl_salt2_default: salt2_default {
+ function = "SALT2";
+ groups = "SALT2";
+ };
- pinctrl_usbcki_default: usbcki_default {
- function = "USBCKI";
- groups = "USBCKI";
- };
+ pinctrl_salt3_default: salt3_default {
+ function = "SALT3";
+ groups = "SALT3";
+ };
- pinctrl_vgabiosrom_default: vgabiosrom_default {
- function = "VGABIOSROM";
- groups = "VGABIOSROM";
- };
+ pinctrl_salt4_default: salt4_default {
+ function = "SALT4";
+ groups = "SALT4";
+ };
- pinctrl_vgahs_default: vgahs_default {
- function = "VGAHS";
- groups = "VGAHS";
- };
+ pinctrl_salt5_default: salt5_default {
+ function = "SALT5";
+ groups = "SALT5";
+ };
- pinctrl_vgavs_default: vgavs_default {
- function = "VGAVS";
- groups = "VGAVS";
- };
+ pinctrl_salt6_default: salt6_default {
+ function = "SALT6";
+ groups = "SALT6";
+ };
- pinctrl_vpi24_default: vpi24_default {
- function = "VPI24";
- groups = "VPI24";
- };
+ pinctrl_salt7_default: salt7_default {
+ function = "SALT7";
+ groups = "SALT7";
+ };
- pinctrl_vpo_default: vpo_default {
- function = "VPO";
- groups = "VPO";
- };
+ pinctrl_salt8_default: salt8_default {
+ function = "SALT8";
+ groups = "SALT8";
+ };
- pinctrl_wdtrst1_default: wdtrst1_default {
- function = "WDTRST1";
- groups = "WDTRST1";
- };
+ pinctrl_salt9_default: salt9_default {
+ function = "SALT9";
+ groups = "SALT9";
+ };
- pinctrl_wdtrst2_default: wdtrst2_default {
- function = "WDTRST2";
- groups = "WDTRST2";
- };
+ pinctrl_scl1_default: scl1_default {
+ function = "SCL1";
+ groups = "SCL1";
+ };
- };
- };
+ pinctrl_scl2_default: scl2_default {
+ function = "SCL2";
+ groups = "SCL2";
+ };
- clk_hpll: clk_hpll@1e6e2024 {
- #clock-cells = <0>;
- compatible = "aspeed,g5-hpll-clock";
- reg = <0x1e6e2024 0x4>;
- clocks = <&clk_clkin>;
- };
+ pinctrl_sd1_default: sd1_default {
+ function = "SD1";
+ groups = "SD1";
+ };
- clk_ahb: clk_ahb@1e6e2070 {
- #clock-cells = <0>;
- compatible = "aspeed,g5-ahb-clock";
- reg = <0x1e6e2070 0x4>;
- clocks = <&clk_hpll>;
- };
+ pinctrl_sd2_default: sd2_default {
+ function = "SD2";
+ groups = "SD2";
+ };
- clk_apb: clk_apb@1e6e2008 {
- #clock-cells = <0>;
- compatible = "aspeed,g5-apb-clock";
- reg = <0x1e6e2008 0x4>;
- clocks = <&clk_hpll>;
- };
+ pinctrl_sda1_default: sda1_default {
+ function = "SDA1";
+ groups = "SDA1";
+ };
- clk_uart: clk_uart@1e6e2008 {
- #clock-cells = <0>;
- compatible = "aspeed,uart-clock";
- reg = <0x1e6e202c 0x4>;
- };
+ pinctrl_sda2_default: sda2_default {
+ function = "SDA2";
+ groups = "SDA2";
+ };
- gfx: display@1e6e6000 {
- compatible = "aspeed,ast2500-gfx", "syscon";
- reg = <0x1e6e6000 0x1000>;
- reg-io-width = <4>;
- };
+ pinctrl_sgps1_default: sgps1_default {
+ function = "SGPS1";
+ groups = "SGPS1";
+ };
- sram@1e720000 {
- compatible = "mmio-sram";
- reg = <0x1e720000 0x9000>; // 36K
- };
+ pinctrl_sgps2_default: sgps2_default {
+ function = "SGPS2";
+ groups = "SGPS2";
+ };
- gpio: gpio@1e780000 {
- #gpio-cells = <2>;
- gpio-controller;
- compatible = "aspeed,ast2500-gpio";
- reg = <0x1e780000 0x1000>;
- interrupts = <20>;
- gpio-ranges = <&pinctrl 0 0 220>;
- interrupt-controller;
- };
+ pinctrl_sioonctrl_default: sioonctrl_default {
+ function = "SIOONCTRL";
+ groups = "SIOONCTRL";
+ };
- timer: timer@1e782000 {
- compatible = "aspeed,ast2400-timer";
- reg = <0x1e782000 0x90>;
- // The moxart_timer driver registers only one
- // interrupt and assumes it's for timer 1
- //interrupts = <16 17 18 35 36 37 38 39>;
- interrupts = <16>;
- clocks = <&clk_apb>;
- };
+ pinctrl_siopbi_default: siopbi_default {
+ function = "SIOPBI";
+ groups = "SIOPBI";
+ };
+ pinctrl_siopbo_default: siopbo_default {
+ function = "SIOPBO";
+ groups = "SIOPBO";
+ };
- wdt1: wdt@1e785000 {
- compatible = "aspeed,wdt";
- reg = <0x1e785000 0x1c>;
- interrupts = <27>;
- };
+ pinctrl_siopwreq_default: siopwreq_default {
+ function = "SIOPWREQ";
+ groups = "SIOPWREQ";
+ };
- wdt2: wdt@1e785020 {
- compatible = "aspeed,wdt";
- reg = <0x1e785020 0x1c>;
- interrupts = <27>;
- status = "disabled";
- };
+ pinctrl_siopwrgd_default: siopwrgd_default {
+ function = "SIOPWRGD";
+ groups = "SIOPWRGD";
+ };
- wdt3: wdt@1e785040 {
- compatible = "aspeed,wdt";
- reg = <0x1e785074 0x1c>;
- status = "disabled";
- };
+ pinctrl_sios3_default: sios3_default {
+ function = "SIOS3";
+ groups = "SIOS3";
+ };
- uart1: serial@1e783000 {
- compatible = "ns16550a";
- reg = <0x1e783000 0x1000>;
- reg-shift = <2>;
- interrupts = <9>;
- clocks = <&clk_uart>;
- no-loopback-test;
- status = "disabled";
- };
+ pinctrl_sios5_default: sios5_default {
+ function = "SIOS5";
+ groups = "SIOS5";
+ };
- lpc: lpc@1e789000 {
- compatible = "aspeed,ast2500-lpc", "simple-mfd";
- reg = <0x1e789000 0x1000>;
+ pinctrl_siosci_default: siosci_default {
+ function = "SIOSCI";
+ groups = "SIOSCI";
+ };
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x1e789000 0x1000>;
+ pinctrl_spi1_default: spi1_default {
+ function = "SPI1";
+ groups = "SPI1";
+ };
- lpc_bmc: lpc-bmc@0 {
- compatible = "aspeed,ast2500-lpc-bmc";
- reg = <0x0 0x80>;
- };
+ pinctrl_spi1cs1_default: spi1cs1_default {
+ function = "SPI1CS1";
+ groups = "SPI1CS1";
+ };
- lpc_host: lpc-host@80 {
- compatible = "aspeed,ast2500-lpc-host", "simple-mfd", "syscon";
- reg = <0x80 0x1e0>;
+ pinctrl_spi1debug_default: spi1debug_default {
+ function = "SPI1DEBUG";
+ groups = "SPI1DEBUG";
+ };
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x80 0x1e0>;
+ pinctrl_spi1passthru_default: spi1passthru_default {
+ function = "SPI1PASSTHRU";
+ groups = "SPI1PASSTHRU";
+ };
- reg-io-width = <4>;
+ pinctrl_spi2ck_default: spi2ck_default {
+ function = "SPI2CK";
+ groups = "SPI2CK";
+ };
- lhc: lhc@20 {
- compatible = "aspeed,ast2500-lhc";
- reg = <0x20 0x24 0x48 0x8>;
- };
- };
- };
+ pinctrl_spi2cs0_default: spi2cs0_default {
+ function = "SPI2CS0";
+ groups = "SPI2CS0";
+ };
- uart2: serial@1e78d000 {
- compatible = "ns16550a";
- reg = <0x1e78d000 0x1000>;
- reg-shift = <2>;
- interrupts = <32>;
- clocks = <&clk_uart>;
- no-loopback-test;
- status = "disabled";
- };
+ pinctrl_spi2cs1_default: spi2cs1_default {
+ function = "SPI2CS1";
+ groups = "SPI2CS1";
+ };
- uart3: serial@1e78e000 {
- compatible = "ns16550a";
- reg = <0x1e78e000 0x1000>;
- reg-shift = <2>;
- interrupts = <33>;
- clocks = <&clk_uart>;
- no-loopback-test;
- status = "disabled";
- };
+ pinctrl_spi2miso_default: spi2miso_default {
+ function = "SPI2MISO";
+ groups = "SPI2MISO";
+ };
- uart4: serial@1e78f000 {
- compatible = "ns16550a";
- reg = <0x1e78f000 0x1000>;
- reg-shift = <2>;
- interrupts = <34>;
- clocks = <&clk_uart>;
- no-loopback-test;
- status = "disabled";
- };
+ pinctrl_spi2mosi_default: spi2mosi_default {
+ function = "SPI2MOSI";
+ groups = "SPI2MOSI";
+ };
- uart5: serial@1e784000 {
- compatible = "ns16550a";
- reg = <0x1e784000 0x1000>;
- reg-shift = <2>;
- interrupts = <10>;
- clocks = <&clk_uart>;
- current-speed = <38400>;
- no-loopback-test;
- status = "disabled";
- };
+ pinctrl_timer3_default: timer3_default {
+ function = "TIMER3";
+ groups = "TIMER3";
+ };
- uart6: serial@1e787000 {
- compatible = "ns16550a";
- reg = <0x1e787000 0x1000>;
- reg-shift = <2>;
- interrupts = <10>;
- clocks = <&clk_uart>;
- no-loopback-test;
- status = "disabled";
- };
- };
+ pinctrl_timer4_default: timer4_default {
+ function = "TIMER4";
+ groups = "TIMER4";
+ };
+
+ pinctrl_timer5_default: timer5_default {
+ function = "TIMER5";
+ groups = "TIMER5";
+ };
+
+ pinctrl_timer6_default: timer6_default {
+ function = "TIMER6";
+ groups = "TIMER6";
+ };
+
+ pinctrl_timer7_default: timer7_default {
+ function = "TIMER7";
+ groups = "TIMER7";
+ };
+
+ pinctrl_timer8_default: timer8_default {
+ function = "TIMER8";
+ groups = "TIMER8";
+ };
+
+ pinctrl_txd1_default: txd1_default {
+ function = "TXD1";
+ groups = "TXD1";
+ };
+
+ pinctrl_txd2_default: txd2_default {
+ function = "TXD2";
+ groups = "TXD2";
+ };
+
+ pinctrl_txd3_default: txd3_default {
+ function = "TXD3";
+ groups = "TXD3";
+ };
+
+ pinctrl_txd4_default: txd4_default {
+ function = "TXD4";
+ groups = "TXD4";
+ };
+
+ pinctrl_uart6_default: uart6_default {
+ function = "UART6";
+ groups = "UART6";
+ };
+
+ pinctrl_usbcki_default: usbcki_default {
+ function = "USBCKI";
+ groups = "USBCKI";
+ };
+
+ pinctrl_usb2ah_default: usb2ah_default {
+ function = "USB2AH";
+ groups = "USB2AH";
+ };
+
+ pinctrl_usb11bhid_default: usb11bhid_default {
+ function = "USB11BHID";
+ groups = "USB11BHID";
+ };
+
+ pinctrl_usb2bh_default: usb2bh_default {
+ function = "USB2BH";
+ groups = "USB2BH";
+ };
+
+ pinctrl_vgabiosrom_default: vgabiosrom_default {
+ function = "VGABIOSROM";
+ groups = "VGABIOSROM";
+ };
+
+ pinctrl_vgahs_default: vgahs_default {
+ function = "VGAHS";
+ groups = "VGAHS";
+ };
+
+ pinctrl_vgavs_default: vgavs_default {
+ function = "VGAVS";
+ groups = "VGAVS";
+ };
+
+ pinctrl_vpi24_default: vpi24_default {
+ function = "VPI24";
+ groups = "VPI24";
+ };
+
+ pinctrl_vpo_default: vpo_default {
+ function = "VPO";
+ groups = "VPO";
+ };
+
+ pinctrl_wdtrst1_default: wdtrst1_default {
+ function = "WDTRST1";
+ groups = "WDTRST1";
+ };
+
+ pinctrl_wdtrst2_default: wdtrst2_default {
+ function = "WDTRST2";
+ groups = "WDTRST2";
};
};
diff --git a/arch/arm/include/asm/ti-common/keystone_net.h b/arch/arm/include/asm/ti-common/keystone_net.h
index f89e043..bba1048 100644
--- a/arch/arm/include/asm/ti-common/keystone_net.h
+++ b/arch/arm/include/asm/ti-common/keystone_net.h
@@ -57,19 +57,6 @@
/* MDIO clock output frequency */
#define EMAC_MDIO_CLOCK_FREQ 2500000 /* 2.5 MHz */
-/* MII Status Register */
-#define MII_STATUS_REG 1
-#define MII_STATUS_LINK_MASK 0x4
-
-#define MDIO_CONTROL_IDLE 0x80000000
-#define MDIO_CONTROL_ENABLE 0x40000000
-#define MDIO_CONTROL_FAULT_ENABLE 0x40000
-#define MDIO_CONTROL_FAULT 0x80000
-#define MDIO_USERACCESS0_GO 0x80000000
-#define MDIO_USERACCESS0_WRITE_READ 0x0
-#define MDIO_USERACCESS0_WRITE_WRITE 0x40000000
-#define MDIO_USERACCESS0_ACK 0x20000000
-
#define EMAC_MACCONTROL_MIIEN_ENABLE 0x20
#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE 0x1
#define EMAC_MACCONTROL_GIGABIT_ENABLE BIT(7)
@@ -242,18 +229,4 @@ struct mdio_regs {
u32 userphysel1;
};
-struct eth_priv_t {
- char int_name[32];
- int rx_flow;
- int phy_addr;
- int slave_port;
- int sgmii_link_type;
- phy_interface_t phy_if;
- struct phy_device *phy_dev;
-};
-
-int keystone2_emac_initialize(struct eth_priv_t *eth_priv);
-void sgmii_serdes_setup_156p25mhz(void);
-void sgmii_serdes_shutdown(void);
-
#endif /* _KEYSTONE_NET_H_ */
diff --git a/arch/arm/mach-davinci/dp83848.c b/arch/arm/mach-davinci/dp83848.c
index 595e3ca..7115d7b 100644
--- a/arch/arm/mach-davinci/dp83848.c
+++ b/arch/arm/mach-davinci/dp83848.c
@@ -12,7 +12,7 @@
#include <net.h>
#include <dp83848.h>
#include <asm/arch/emac_defs.h>
-#include "../../../drivers/net/davinci_emac.h"
+#include "../../../drivers/net/ti/davinci_emac.h"
#ifdef CONFIG_DRIVER_TI_EMAC
diff --git a/arch/arm/mach-davinci/et1011c.c b/arch/arm/mach-davinci/et1011c.c
index 3d02274..bfb7ff2 100644
--- a/arch/arm/mach-davinci/et1011c.c
+++ b/arch/arm/mach-davinci/et1011c.c
@@ -9,7 +9,7 @@
#include <net.h>
#include <miiphy.h>
#include <asm/arch/emac_defs.h>
-#include "../../../drivers/net/davinci_emac.h"
+#include "../../../drivers/net/ti/davinci_emac.h"
#ifdef CONFIG_DRIVER_TI_EMAC
diff --git a/arch/arm/mach-davinci/ksz8873.c b/arch/arm/mach-davinci/ksz8873.c
index 899cff0..85b0c26 100644
--- a/arch/arm/mach-davinci/ksz8873.c
+++ b/arch/arm/mach-davinci/ksz8873.c
@@ -19,7 +19,7 @@
#include <net.h>
#include <asm/arch/emac_defs.h>
#include <asm/io.h>
-#include "../../../drivers/net/davinci_emac.h"
+#include "../../../drivers/net/ti/davinci_emac.h"
int ksz8873_is_phy_connected(int phy_addr)
{
diff --git a/arch/arm/mach-davinci/lxt972.c b/arch/arm/mach-davinci/lxt972.c
index 170e4a5..b54f67d 100644
--- a/arch/arm/mach-davinci/lxt972.c
+++ b/arch/arm/mach-davinci/lxt972.c
@@ -13,7 +13,7 @@
#include <miiphy.h>
#include <lxt971a.h>
#include <asm/arch/emac_defs.h>
-#include "../../../drivers/net/davinci_emac.h"
+#include "../../../drivers/net/ti/davinci_emac.h"
#ifdef CONFIG_DRIVER_TI_EMAC
diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c
index d81c8e6..72709c0 100644
--- a/board/ti/ks2_evm/board.c
+++ b/board/ti/ks2_evm/board.c
@@ -66,59 +66,6 @@ int board_init(void)
return 0;
}
-#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
-#ifndef CONFIG_DM_ETH
-int get_eth_env_param(char *env_name)
-{
- char *env;
- int res = -1;
-
- env = env_get(env_name);
- if (env)
- res = simple_strtol(env, NULL, 0);
-
- return res;
-}
-
-int board_eth_init(bd_t *bis)
-{
- int j;
- int res;
- int port_num;
- char link_type_name[32];
-
- if (cpu_is_k2g())
- writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG);
-
- /* By default, select PA PLL clock as PA clock source */
-#ifndef CONFIG_SOC_K2G
- if (psc_enable_module(KS2_LPSC_PA))
- return -1;
-#endif
- if (psc_enable_module(KS2_LPSC_CPGMAC))
- return -1;
- if (psc_enable_module(KS2_LPSC_CRYPTO))
- return -1;
-
- if (cpu_is_k2e() || cpu_is_k2l())
- pll_pa_clk_sel();
-
- port_num = get_num_eth_ports();
-
- for (j = 0; j < port_num; j++) {
- sprintf(link_type_name, "sgmii%d_link_type", j);
- res = get_eth_env_param(link_type_name);
- if (res >= 0)
- eth_priv_cfg[j].sgmii_link_type = res;
-
- keystone2_emac_initialize(&eth_priv_cfg[j]);
- }
-
- return 0;
-}
-#endif
-#endif
-
#ifdef CONFIG_SPL_BUILD
void spl_board_init(void)
{
diff --git a/board/ti/ks2_evm/board.h b/board/ti/ks2_evm/board.h
index 250b649..d0cfbf5 100644
--- a/board/ti/ks2_evm/board.h
+++ b/board/ti/ks2_evm/board.h
@@ -12,8 +12,6 @@
#include <asm/ti-common/keystone_net.h>
#include "../common/board_detect.h"
-extern struct eth_priv_t eth_priv_cfg[];
-
#if defined(CONFIG_TI_I2C_BOARD_DETECT)
static inline int board_is_k2g_gp(void)
{
@@ -38,7 +36,6 @@ static inline int board_is_k2g_ice(void)
}
#endif
-int get_num_eth_ports(void);
void spl_init_keystone_plls(void);
#endif
diff --git a/board/ti/ks2_evm/board_k2e.c b/board/ti/ks2_evm/board_k2e.c
index f86a836..ecd4a42 100644
--- a/board/ti/ks2_evm/board_k2e.c
+++ b/board/ti/ks2_evm/board_k2e.c
@@ -89,80 +89,6 @@ struct pll_init_data *get_pll_init_data(int pll)
return data;
}
-#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
-struct eth_priv_t eth_priv_cfg[] = {
- {
- .int_name = "K2E_EMAC0",
- .rx_flow = 0,
- .phy_addr = 0,
- .slave_port = 1,
- .sgmii_link_type = SGMII_LINK_MAC_PHY,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2E_EMAC1",
- .rx_flow = 8,
- .phy_addr = 1,
- .slave_port = 2,
- .sgmii_link_type = SGMII_LINK_MAC_PHY,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2E_EMAC2",
- .rx_flow = 16,
- .phy_addr = 2,
- .slave_port = 3,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2E_EMAC3",
- .rx_flow = 24,
- .phy_addr = 3,
- .slave_port = 4,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2E_EMAC4",
- .rx_flow = 32,
- .phy_addr = 4,
- .slave_port = 5,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2E_EMAC5",
- .rx_flow = 40,
- .phy_addr = 5,
- .slave_port = 6,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2E_EMAC6",
- .rx_flow = 48,
- .phy_addr = 6,
- .slave_port = 7,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2E_EMAC7",
- .rx_flow = 56,
- .phy_addr = 7,
- .slave_port = 8,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
-};
-
-int get_num_eth_ports(void)
-{
- return sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t);
-}
-#endif
-
#if defined(CONFIG_MULTI_DTB_FIT)
int board_fit_config_name_match(const char *name)
{
diff --git a/board/ti/ks2_evm/board_k2g.c b/board/ti/ks2_evm/board_k2g.c
index 9bc94fb..87dc4d0 100644
--- a/board/ti/ks2_evm/board_k2g.c
+++ b/board/ti/ks2_evm/board_k2g.c
@@ -354,24 +354,6 @@ void spl_init_keystone_plls(void)
}
#endif
-#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
-struct eth_priv_t eth_priv_cfg[] = {
- {
- .int_name = "K2G_EMAC",
- .rx_flow = 0,
- .phy_addr = 0,
- .slave_port = 1,
- .sgmii_link_type = SGMII_LINK_MAC_PHY,
- .phy_if = PHY_INTERFACE_MODE_RGMII,
- },
-};
-
-int get_num_eth_ports(void)
-{
- return sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t);
-}
-#endif
-
#ifdef CONFIG_TI_SECURE_DEVICE
void board_pmmc_image_process(ulong pmmc_image, size_t pmmc_size)
{
diff --git a/board/ti/ks2_evm/board_k2hk.c b/board/ti/ks2_evm/board_k2hk.c
index abc89d8..4c0acd6 100644
--- a/board/ti/ks2_evm/board_k2hk.c
+++ b/board/ti/ks2_evm/board_k2hk.c
@@ -96,48 +96,6 @@ struct pll_init_data *get_pll_init_data(int pll)
return data;
}
-#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
-struct eth_priv_t eth_priv_cfg[] = {
- {
- .int_name = "K2HK_EMAC",
- .rx_flow = 22,
- .phy_addr = 0,
- .slave_port = 1,
- .sgmii_link_type = SGMII_LINK_MAC_PHY,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2HK_EMAC1",
- .rx_flow = 23,
- .phy_addr = 1,
- .slave_port = 2,
- .sgmii_link_type = SGMII_LINK_MAC_PHY,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2HK_EMAC2",
- .rx_flow = 24,
- .phy_addr = 2,
- .slave_port = 3,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2HK_EMAC3",
- .rx_flow = 25,
- .phy_addr = 3,
- .slave_port = 4,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
-};
-
-int get_num_eth_ports(void)
-{
- return sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t);
-}
-#endif
-
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
diff --git a/board/ti/ks2_evm/board_k2l.c b/board/ti/ks2_evm/board_k2l.c
index c28fad5..e49d8b3 100644
--- a/board/ti/ks2_evm/board_k2l.c
+++ b/board/ti/ks2_evm/board_k2l.c
@@ -84,48 +84,6 @@ struct pll_init_data *get_pll_init_data(int pll)
return data;
}
-#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
-struct eth_priv_t eth_priv_cfg[] = {
- {
- .int_name = "K2L_EMAC",
- .rx_flow = 0,
- .phy_addr = 0,
- .slave_port = 1,
- .sgmii_link_type = SGMII_LINK_MAC_PHY,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2L_EMAC1",
- .rx_flow = 8,
- .phy_addr = 1,
- .slave_port = 2,
- .sgmii_link_type = SGMII_LINK_MAC_PHY,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2L_EMAC2",
- .rx_flow = 16,
- .phy_addr = 2,
- .slave_port = 3,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
- {
- .int_name = "K2L_EMAC3",
- .rx_flow = 32,
- .phy_addr = 3,
- .slave_port = 4,
- .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
- .phy_if = PHY_INTERFACE_MODE_SGMII,
- },
-};
-
-int get_num_eth_ports(void)
-{
- return sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t);
-}
-#endif
-
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 88230f4..32581f5 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -25,3 +25,11 @@ CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_TIMER=y
CONFIG_WDT=y
+CONFIG_NETDEVICES=y
+CONFIG_PHY=y
+CONFIG_DM_ETH=y
+CONFIG_FTGMAC100=y
+CONFIG_PHY_REALTEK=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig
index d744cb1..67b1f30 100644
--- a/configs/k2e_evm_defconfig
+++ b/configs/k2e_evm_defconfig
@@ -56,3 +56,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/configs/k2e_hs_evm_defconfig b/configs/k2e_hs_evm_defconfig
index 87faf3d..1abda84 100644
--- a/configs/k2e_hs_evm_defconfig
+++ b/configs/k2e_hs_evm_defconfig
@@ -49,3 +49,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig
index a96029c..bc4b92b 100644
--- a/configs/k2g_evm_defconfig
+++ b/configs/k2g_evm_defconfig
@@ -60,3 +60,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/configs/k2g_hs_evm_defconfig b/configs/k2g_hs_evm_defconfig
index 9e75500..66d8220 100644
--- a/configs/k2g_hs_evm_defconfig
+++ b/configs/k2g_hs_evm_defconfig
@@ -53,3 +53,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig
index 8c7d362..f66d922 100644
--- a/configs/k2hk_evm_defconfig
+++ b/configs/k2hk_evm_defconfig
@@ -56,3 +56,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/configs/k2hk_hs_evm_defconfig b/configs/k2hk_hs_evm_defconfig
index c8f4bbe..dd91a51 100644
--- a/configs/k2hk_hs_evm_defconfig
+++ b/configs/k2hk_hs_evm_defconfig
@@ -49,3 +49,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig
index dd91aa5..4f04caa 100644
--- a/configs/k2l_evm_defconfig
+++ b/configs/k2l_evm_defconfig
@@ -56,3 +56,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/configs/k2l_hs_evm_defconfig b/configs/k2l_hs_evm_defconfig
index ac400e4..9ce23de 100644
--- a/configs/k2l_hs_evm_defconfig
+++ b/configs/k2l_hs_evm_defconfig
@@ -48,3 +48,4 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_STORAGE=y
+CONFIG_DRIVER_TI_KEYSTONE_NET=y
diff --git a/doc/device-tree-bindings/net/mediatek,mt7628-eth.txt b/doc/device-tree-bindings/net/mediatek,mt7628-eth.txt
new file mode 100644
index 0000000..ec97504
--- /dev/null
+++ b/doc/device-tree-bindings/net/mediatek,mt7628-eth.txt
@@ -0,0 +1,17 @@
+* MediaTek Frame Engine Ethernet controller
+
+Required properties:
+- compatible: should be "mediatek,mt7628-eth"
+- reg: address and length of the register set for the frame
+ engine ethernet controller and the internal switch.
+- syscon: phandle to the system controller
+
+Example:
+
+eth@10100000 {
+ compatible = "mediatek,mt7628-eth";
+ reg = <0x10100000 0x10000
+ 0x10110000 0x8000>;
+
+ syscon = <&sysc>;
+};
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index 5264700..dbee13a 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -165,6 +165,35 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
return rate;
}
+struct ast2500_clock_config {
+ ulong input_rate;
+ ulong rate;
+ struct ast2500_div_config cfg;
+};
+
+static const struct ast2500_clock_config ast2500_clock_config_defaults[] = {
+ { 24000000, 250000000, { .num = 124, .denum = 1, .post_div = 5 } },
+};
+
+static bool ast2500_get_clock_config_default(ulong input_rate,
+ ulong requested_rate,
+ struct ast2500_div_config *cfg)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ast2500_clock_config_defaults); i++) {
+ const struct ast2500_clock_config *default_cfg =
+ &ast2500_clock_config_defaults[i];
+ if (default_cfg->input_rate == input_rate &&
+ default_cfg->rate == requested_rate) {
+ *cfg = default_cfg->cfg;
+ return true;
+ }
+ }
+
+ return false;
+}
+
/*
* @input_rate - the rate of input clock in Hz
* @requested_rate - desired output rate in Hz
@@ -189,6 +218,12 @@ static ulong ast2500_calc_clock_config(ulong input_rate, ulong requested_rate,
ulong delta = rate_khz;
ulong new_rate_khz = 0;
+ /*
+ * Look for a well known frequency first.
+ */
+ if (ast2500_get_clock_config_default(input_rate, requested_rate, cfg))
+ return requested_rate;
+
for (; it.denum <= max_vals.denum; ++it.denum) {
for (it.post_div = 0; it.post_div <= max_vals.post_div;
++it.post_div) {
@@ -318,6 +353,9 @@ static ulong ast2500_configure_d2pll(struct ast2500_scu *scu, ulong rate)
/*
* The values and the meaning of the next three
* parameters are undocumented. Taken from Aspeed SDK.
+ *
+ * TODO(clg@kaod.org): the SIP and SIC values depend on the
+ * Numerator value
*/
const u32 d2_pll_ext_param = 0x2c;
const u32 d2_pll_sip = 0x11;
@@ -411,6 +449,7 @@ static int ast2500_clk_enable(struct clk *clk)
break;
case PLL_D2PLL:
ast2500_configure_d2pll(priv->scu, D2PLL_DEFAULT_RATE);
+ break;
default:
return -ENOENT;
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3968743..8fb365f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -11,13 +11,6 @@ config DM_ETH
This is currently implemented in net/eth-uclass.c
Look in include/net.h for details.
-config DRIVER_TI_CPSW
- bool "TI Common Platform Ethernet Switch"
- select PHYLIB
- help
- This driver supports the TI three port switch gigabit ethernet
- subsystem found in the TI SoCs.
-
menuconfig NETDEVICES
bool "Network device support"
depends on NET
@@ -186,6 +179,32 @@ config FTMAC100
help
This MAC is present in Andestech SoCs.
+config FTGMAC100
+ bool "Ftgmac100 Ethernet Support"
+ depends on DM_ETH
+ select PHYLIB
+ help
+ This driver supports the Faraday's FTGMAC100 Gigabit SoC
+ Ethernet controller that can be found on Aspeed SoCs (which
+ include NCSI).
+
+ It is fully compliant with IEEE 802.3 specification for
+ 10/100 Mbps Ethernet and IEEE 802.3z specification for 1000
+ Mbps Ethernet and includes Reduced Media Independent
+ Interface (RMII) and Reduced Gigabit Media Independent
+ Interface (RGMII) interfaces. It adopts an AHB bus interface
+ and integrates a link list DMA engine with direct M-Bus
+ accesses for transmitting and receiving packets. It has
+ independent TX/RX fifos, supports half and full duplex (1000
+ Mbps mode only supports full duplex), flow control for full
+ duplex and backpressure for half duplex.
+
+ The FTGMAC100 also implements IP, TCP, UDP checksum offloads
+ and supports IEEE 802.1Q VLAN tag insertion and removal. It
+ offers high-priority transmit queue for QoS and CoS
+ applications.
+
+
config MVGBE
bool "Marvell Orion5x/Kirkwood network interface support"
depends on KIRKWOOD || ORION5X
@@ -227,6 +246,13 @@ config MACB_ZYNQ
The Cadence MACB ethernet interface was used on Zynq platform.
Say Y to enable support for the MACB/GEM in Zynq chip.
+config MT7628_ETH
+ bool "MediaTek MT7628 Ethernet Interface"
+ depends on ARCH_MT7620
+ help
+ The MediaTek MT7628 ethernet interface is used on MT7628 and
+ MT7688 based boards.
+
config PCH_GBE
bool "Intel Platform Controller Hub EG20T GMAC driver"
depends on DM_ETH && DM_PCI
@@ -322,10 +348,7 @@ config SH_ETHER
help
This driver supports the Ethernet for Renesas SH and ARM SoCs.
-config DRIVER_TI_EMAC
- bool "TI Davinci EMAC"
- help
- Support for davinci emac
+source "drivers/net/ti/Kconfig"
config XILINX_AXIEMAC
depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 48a2878..99056aa 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -30,13 +30,13 @@ obj-$(CONFIG_FTGMAC100) += ftgmac100.o
obj-$(CONFIG_FTMAC110) += ftmac110.o
obj-$(CONFIG_FTMAC100) += ftmac100.o
obj-$(CONFIG_GMAC_ROCKCHIP) += gmac_rockchip.o
-obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o
obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
obj-$(CONFIG_LAN91C96) += lan91c96.o
obj-$(CONFIG_LPC32XX_ETH) += lpc32xx_eth.o
obj-$(CONFIG_MACB) += macb.o
obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o
+obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o
obj-$(CONFIG_MVGBE) += mvgbe.o
obj-$(CONFIG_MVNETA) += mvneta.o
obj-$(CONFIG_MVPP2) += mvpp2.o
@@ -56,9 +56,7 @@ obj-$(CONFIG_SH_ETHER) += sh_eth.o
obj-$(CONFIG_RENESAS_RAVB) += ravb.o
obj-$(CONFIG_SMC91111) += smc91111.o
obj-$(CONFIG_SMC911X) += smc911x.o
-obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o
-obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o cpsw-common.o
obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o
obj-$(CONFIG_ULI526X) += uli526x.o
obj-$(CONFIG_VSC7385_ENET) += vsc7385.o
@@ -73,3 +71,4 @@ obj-$(CONFIG_PIC32_ETH) += pic32_mdio.o pic32_eth.o
obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
obj-$(CONFIG_FSL_PFE) += pfe_eth/
obj-$(CONFIG_SNI_AVE) += sni_ave.o
+obj-y += ti/
diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index c996f5f..92c38a8 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -7,321 +7,239 @@
*
* (C) Copyright 2010 Andes Technology
* Macpaul Lin <macpaul@andestech.com>
+ *
+ * Copyright (C) 2018, IBM Corporation.
*/
-#include <config.h>
-#include <common.h>
-#include <malloc.h>
+#include <clk.h>
+#include <dm.h>
+#include <miiphy.h>
#include <net.h>
-#include <asm/io.h>
-#include <asm/dma-mapping.h>
-#include <linux/mii.h>
+#include <wait_bit.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
#include "ftgmac100.h"
-#define ETH_ZLEN 60
-#define CFG_XBUF_SIZE 1536
+/* Min frame ethernet frame size without FCS */
+#define ETH_ZLEN 60
-/* RBSR - hw default init value is also 0x640 */
-#define RBSR_DEFAULT_VALUE 0x640
+/* Receive Buffer Size Register - HW default is 0x640 */
+#define FTGMAC100_RBSR_DEFAULT 0x640
/* PKTBUFSTX/PKTBUFSRX must both be power of 2 */
#define PKTBUFSTX 4 /* must be power of 2 */
+/* Timeout for transmit */
+#define FTGMAC100_TX_TIMEOUT_MS 1000
+
+/* Timeout for a mdio read/write operation */
+#define FTGMAC100_MDIO_TIMEOUT_USEC 10000
+
+/*
+ * MDC clock cycle threshold
+ *
+ * 20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
+ */
+#define MDC_CYCTHR 0x34
+
+/*
+ * ftgmac100 model variants
+ */
+enum ftgmac100_model {
+ FTGMAC100_MODEL_FARADAY,
+ FTGMAC100_MODEL_ASPEED,
+};
+
+/**
+ * struct ftgmac100_data - private data for the FTGMAC100 driver
+ *
+ * @iobase: The base address of the hardware registers
+ * @txdes: The array of transmit descriptors
+ * @rxdes: The array of receive descriptors
+ * @tx_index: Transmit descriptor index in @txdes
+ * @rx_index: Receive descriptor index in @rxdes
+ * @phy_addr: The PHY interface address to use
+ * @phydev: The PHY device backing the MAC
+ * @bus: The mdio bus
+ * @phy_mode: The mode of the PHY interface (rgmii, rmii, ...)
+ * @max_speed: Maximum speed of Ethernet connection supported by MAC
+ * @clks: The bulk of clocks assigned to the device in the DT
+ * @rxdes0_edorr_mask: The bit number identifying the end of the RX ring buffer
+ * @txdes0_edotr_mask: The bit number identifying the end of the TX ring buffer
+ */
struct ftgmac100_data {
- ulong txdes_dma;
- struct ftgmac100_txdes *txdes;
- ulong rxdes_dma;
- struct ftgmac100_rxdes *rxdes;
+ struct ftgmac100 *iobase;
+
+ struct ftgmac100_txdes txdes[PKTBUFSTX];
+ struct ftgmac100_rxdes rxdes[PKTBUFSRX];
int tx_index;
int rx_index;
- int phy_addr;
+
+ u32 phy_addr;
+ struct phy_device *phydev;
+ struct mii_dev *bus;
+ u32 phy_mode;
+ u32 max_speed;
+
+ struct clk_bulk clks;
+
+ /* End of RX/TX ring buffer bits. Depend on model */
+ u32 rxdes0_edorr_mask;
+ u32 txdes0_edotr_mask;
};
/*
* struct mii_bus functions
*/
-static int ftgmac100_mdiobus_read(struct eth_device *dev, int phy_addr,
- int regnum)
+static int ftgmac100_mdio_read(struct mii_dev *bus, int phy_addr, int dev_addr,
+ int reg_addr)
{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+ struct ftgmac100_data *priv = bus->priv;
+ struct ftgmac100 *ftgmac100 = priv->iobase;
int phycr;
- int i;
-
- phycr = readl(&ftgmac100->phycr);
-
- /* preserve MDC cycle threshold */
- phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
-
- phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
- | FTGMAC100_PHYCR_REGAD(regnum)
- | FTGMAC100_PHYCR_MIIRD;
+ int data;
+ int ret;
+ phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
+ FTGMAC100_PHYCR_PHYAD(phy_addr) |
+ FTGMAC100_PHYCR_REGAD(reg_addr) |
+ FTGMAC100_PHYCR_MIIRD;
writel(phycr, &ftgmac100->phycr);
- for (i = 0; i < 10; i++) {
- phycr = readl(&ftgmac100->phycr);
-
- if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) {
- int data;
-
- data = readl(&ftgmac100->phydata);
- return FTGMAC100_PHYDATA_MIIRDATA(data);
- }
-
- mdelay(10);
+ ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
+ !(phycr & FTGMAC100_PHYCR_MIIRD),
+ FTGMAC100_MDIO_TIMEOUT_USEC);
+ if (ret) {
+ pr_err("%s: mdio read failed (phy:%d reg:%x)\n",
+ priv->phydev->dev->name, phy_addr, reg_addr);
+ return ret;
}
- debug("mdio read timed out\n");
- return -1;
+ data = readl(&ftgmac100->phydata);
+
+ return FTGMAC100_PHYDATA_MIIRDATA(data);
}
-static int ftgmac100_mdiobus_write(struct eth_device *dev, int phy_addr,
- int regnum, u16 value)
+static int ftgmac100_mdio_write(struct mii_dev *bus, int phy_addr, int dev_addr,
+ int reg_addr, u16 value)
{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+ struct ftgmac100_data *priv = bus->priv;
+ struct ftgmac100 *ftgmac100 = priv->iobase;
int phycr;
int data;
- int i;
-
- phycr = readl(&ftgmac100->phycr);
-
- /* preserve MDC cycle threshold */
- phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
-
- phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
- | FTGMAC100_PHYCR_REGAD(regnum)
- | FTGMAC100_PHYCR_MIIWR;
+ int ret;
+ phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
+ FTGMAC100_PHYCR_PHYAD(phy_addr) |
+ FTGMAC100_PHYCR_REGAD(reg_addr) |
+ FTGMAC100_PHYCR_MIIWR;
data = FTGMAC100_PHYDATA_MIIWDATA(value);
writel(data, &ftgmac100->phydata);
writel(phycr, &ftgmac100->phycr);
- for (i = 0; i < 10; i++) {
- phycr = readl(&ftgmac100->phycr);
-
- if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) {
- debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \
- "phy_addr: %x\n", phy_addr);
- return 0;
- }
-
- mdelay(1);
+ ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
+ !(phycr & FTGMAC100_PHYCR_MIIWR),
+ FTGMAC100_MDIO_TIMEOUT_USEC);
+ if (ret) {
+ pr_err("%s: mdio write failed (phy:%d reg:%x)\n",
+ priv->phydev->dev->name, phy_addr, reg_addr);
}
- debug("mdio write timed out\n");
- return -1;
-}
-
-int ftgmac100_phy_read(struct eth_device *dev, int addr, int reg, u16 *value)
-{
- *value = ftgmac100_mdiobus_read(dev , addr, reg);
-
- if (*value == -1)
- return -1;
-
- return 0;
+ return ret;
}
-int ftgmac100_phy_write(struct eth_device *dev, int addr, int reg, u16 value)
+static int ftgmac100_mdio_init(struct udevice *dev)
{
- if (ftgmac100_mdiobus_write(dev, addr, reg, value) == -1)
- return -1;
-
- return 0;
-}
-
-static int ftgmac100_phy_reset(struct eth_device *dev)
-{
- struct ftgmac100_data *priv = dev->priv;
- int i;
- u16 status, adv;
-
- adv = ADVERTISE_CSMA | ADVERTISE_ALL;
-
- ftgmac100_phy_write(dev, priv->phy_addr, MII_ADVERTISE, adv);
-
- printf("%s: Starting autonegotiation...\n", dev->name);
-
- ftgmac100_phy_write(dev, priv->phy_addr,
- MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
-
- for (i = 0; i < 100000 / 100; i++) {
- ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
-
- if (status & BMSR_ANEGCOMPLETE)
- break;
- mdelay(1);
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ struct mii_dev *bus;
+ int ret;
+
+ bus = mdio_alloc();
+ if (!bus)
+ return -ENOMEM;
+
+ bus->read = ftgmac100_mdio_read;
+ bus->write = ftgmac100_mdio_write;
+ bus->priv = priv;
+
+ ret = mdio_register_seq(bus, dev->seq);
+ if (ret) {
+ free(bus);
+ return ret;
}
- if (status & BMSR_ANEGCOMPLETE) {
- printf("%s: Autonegotiation complete\n", dev->name);
- } else {
- printf("%s: Autonegotiation timed out (status=0x%04x)\n",
- dev->name, status);
- return 0;
- }
+ priv->bus = bus;
- return 1;
+ return 0;
}
-static int ftgmac100_phy_init(struct eth_device *dev)
+static int ftgmac100_phy_adjust_link(struct ftgmac100_data *priv)
{
- struct ftgmac100_data *priv = dev->priv;
-
- int phy_addr;
- u16 phy_id, status, adv, lpa, stat_ge;
- int media, speed, duplex;
- int i;
+ struct ftgmac100 *ftgmac100 = priv->iobase;
+ struct phy_device *phydev = priv->phydev;
+ u32 maccr;
- /* Check if the PHY is up to snuff... */
- for (phy_addr = 0; phy_addr < CONFIG_PHY_MAX_ADDR; phy_addr++) {
-
- ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id);
-
- /*
- * When it is unable to found PHY,
- * the interface usually return 0xffff or 0x0000
- */
- if (phy_id != 0xffff && phy_id != 0x0) {
- printf("%s: found PHY at 0x%02x\n",
- dev->name, phy_addr);
- priv->phy_addr = phy_addr;
- break;
- }
+ if (!phydev->link) {
+ dev_err(phydev->dev, "No link\n");
+ return -EREMOTEIO;
}
- if (phy_id == 0xffff || phy_id == 0x0) {
- printf("%s: no PHY present\n", dev->name);
- return 0;
- }
-
- ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
-
- if (!(status & BMSR_LSTATUS)) {
- /* Try to re-negotiate if we don't have link already. */
- ftgmac100_phy_reset(dev);
-
- for (i = 0; i < 100000 / 100; i++) {
- ftgmac100_phy_read(dev, priv->phy_addr,
- MII_BMSR, &status);
- if (status & BMSR_LSTATUS)
- break;
- udelay(100);
- }
- }
-
- if (!(status & BMSR_LSTATUS)) {
- printf("%s: link down\n", dev->name);
- return 0;
- }
-
-#ifdef CONFIG_FTGMAC100_EGIGA
- /* 1000 Base-T Status Register */
- ftgmac100_phy_read(dev, priv->phy_addr,
- MII_STAT1000, &stat_ge);
-
- speed = (stat_ge & (LPA_1000FULL | LPA_1000HALF)
- ? 1 : 0);
-
- duplex = ((stat_ge & LPA_1000FULL)
- ? 1 : 0);
-
- if (speed) { /* Speed is 1000 */
- printf("%s: link up, 1000bps %s-duplex\n",
- dev->name, duplex ? "full" : "half");
- return 0;
- }
-#endif
-
- ftgmac100_phy_read(dev, priv->phy_addr, MII_ADVERTISE, &adv);
- ftgmac100_phy_read(dev, priv->phy_addr, MII_LPA, &lpa);
-
- media = mii_nway_result(lpa & adv);
- speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0);
- duplex = (media & ADVERTISE_FULL) ? 1 : 0;
-
- printf("%s: link up, %sMbps %s-duplex\n",
- dev->name, speed ? "100" : "10", duplex ? "full" : "half");
-
- return 1;
-}
-
-static int ftgmac100_update_link_speed(struct eth_device *dev)
-{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
- struct ftgmac100_data *priv = dev->priv;
-
- unsigned short stat_fe;
- unsigned short stat_ge;
- unsigned int maccr;
-
-#ifdef CONFIG_FTGMAC100_EGIGA
- /* 1000 Base-T Status Register */
- ftgmac100_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge);
-#endif
-
- ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &stat_fe);
-
- if (!(stat_fe & BMSR_LSTATUS)) /* link status up? */
- return 0;
-
/* read MAC control register and clear related bits */
maccr = readl(&ftgmac100->maccr) &
~(FTGMAC100_MACCR_GIGA_MODE |
FTGMAC100_MACCR_FAST_MODE |
FTGMAC100_MACCR_FULLDUP);
-#ifdef CONFIG_FTGMAC100_EGIGA
- if (stat_ge & LPA_1000FULL) {
- /* set gmac for 1000BaseTX and Full Duplex */
- maccr |= FTGMAC100_MACCR_GIGA_MODE | FTGMAC100_MACCR_FULLDUP;
- }
-
- if (stat_ge & LPA_1000HALF) {
- /* set gmac for 1000BaseTX and Half Duplex */
+ if (phy_interface_is_rgmii(phydev) && phydev->speed == 1000)
maccr |= FTGMAC100_MACCR_GIGA_MODE;
- }
-#endif
-
- if (stat_fe & BMSR_100FULL) {
- /* set MII for 100BaseTX and Full Duplex */
- maccr |= FTGMAC100_MACCR_FAST_MODE | FTGMAC100_MACCR_FULLDUP;
- }
- if (stat_fe & BMSR_10FULL) {
- /* set MII for 10BaseT and Full Duplex */
- maccr |= FTGMAC100_MACCR_FULLDUP;
- }
-
- if (stat_fe & BMSR_100HALF) {
- /* set MII for 100BaseTX and Half Duplex */
+ if (phydev->speed == 100)
maccr |= FTGMAC100_MACCR_FAST_MODE;
- }
- if (stat_fe & BMSR_10HALF) {
- /* set MII for 10BaseT and Half Duplex */
- /* we have already clear these bits, do nothing */
- ;
- }
+ if (phydev->duplex)
+ maccr |= FTGMAC100_MACCR_FULLDUP;
/* update MII config into maccr */
writel(maccr, &ftgmac100->maccr);
- return 1;
+ return 0;
+}
+
+static int ftgmac100_phy_init(struct udevice *dev)
+{
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ struct phy_device *phydev;
+ int ret;
+
+ phydev = phy_connect(priv->bus, priv->phy_addr, dev, priv->phy_mode);
+ if (!phydev)
+ return -ENODEV;
+
+ phydev->supported &= PHY_GBIT_FEATURES;
+ if (priv->max_speed) {
+ ret = phy_set_supported(phydev, priv->max_speed);
+ if (ret)
+ return ret;
+ }
+ phydev->advertising = phydev->supported;
+ priv->phydev = phydev;
+ phy_config(phydev);
+
+ return 0;
}
/*
* Reset MAC
*/
-static void ftgmac100_reset(struct eth_device *dev)
+static void ftgmac100_reset(struct ftgmac100_data *priv)
{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+ struct ftgmac100 *ftgmac100 = priv->iobase;
debug("%s()\n", __func__);
- writel(FTGMAC100_MACCR_SW_RST, &ftgmac100->maccr);
+ setbits_le32(&ftgmac100->maccr, FTGMAC100_MACCR_SW_RST);
while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST)
;
@@ -330,10 +248,10 @@ static void ftgmac100_reset(struct eth_device *dev)
/*
* Set MAC address
*/
-static void ftgmac100_set_mac(struct eth_device *dev,
- const unsigned char *mac)
+static int ftgmac100_set_mac(struct ftgmac100_data *priv,
+ const unsigned char *mac)
{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+ struct ftgmac100 *ftgmac100 = priv->iobase;
unsigned int maddr = mac[0] << 8 | mac[1];
unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
@@ -341,61 +259,42 @@ static void ftgmac100_set_mac(struct eth_device *dev,
writel(maddr, &ftgmac100->mac_madr);
writel(laddr, &ftgmac100->mac_ladr);
-}
-
-static void ftgmac100_set_mac_from_env(struct eth_device *dev)
-{
- eth_env_get_enetaddr("ethaddr", dev->enetaddr);
- ftgmac100_set_mac(dev, dev->enetaddr);
+ return 0;
}
/*
* disable transmitter, receiver
*/
-static void ftgmac100_halt(struct eth_device *dev)
+static void ftgmac100_stop(struct udevice *dev)
{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ struct ftgmac100 *ftgmac100 = priv->iobase;
debug("%s()\n", __func__);
writel(0, &ftgmac100->maccr);
+
+ phy_shutdown(priv->phydev);
}
-static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
+static int ftgmac100_start(struct udevice *dev)
{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
- struct ftgmac100_data *priv = dev->priv;
- struct ftgmac100_txdes *txdes;
- struct ftgmac100_rxdes *rxdes;
+ struct eth_pdata *plat = dev_get_platdata(dev);
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ struct ftgmac100 *ftgmac100 = priv->iobase;
+ struct phy_device *phydev = priv->phydev;
unsigned int maccr;
- void *buf;
+ ulong start, end;
+ int ret;
int i;
debug("%s()\n", __func__);
- if (!priv->txdes) {
- txdes = dma_alloc_coherent(
- sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma);
- if (!txdes)
- panic("ftgmac100: out of memory\n");
- memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX);
- priv->txdes = txdes;
- }
- txdes = priv->txdes;
-
- if (!priv->rxdes) {
- rxdes = dma_alloc_coherent(
- sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma);
- if (!rxdes)
- panic("ftgmac100: out of memory\n");
- memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX);
- priv->rxdes = rxdes;
- }
- rxdes = priv->rxdes;
+ ftgmac100_reset(priv);
/* set the ethernet address */
- ftgmac100_set_mac_from_env(dev);
+ ftgmac100_set_mac(priv, plat->enetaddr);
/* disable all interrupts */
writel(0, &ftgmac100->ier);
@@ -404,42 +303,37 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
priv->tx_index = 0;
priv->rx_index = 0;
- txdes[PKTBUFSTX - 1].txdes0 = FTGMAC100_TXDES0_EDOTR;
- rxdes[PKTBUFSRX - 1].rxdes0 = FTGMAC100_RXDES0_EDORR;
-
for (i = 0; i < PKTBUFSTX; i++) {
- /* TXBUF_BADR */
- if (!txdes[i].txdes2) {
- buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE);
- if (!buf)
- panic("ftgmac100: out of memory\n");
- txdes[i].txdes3 = virt_to_phys(buf);
- txdes[i].txdes2 = (uint)buf;
- }
- txdes[i].txdes1 = 0;
+ priv->txdes[i].txdes3 = 0;
+ priv->txdes[i].txdes0 = 0;
}
+ priv->txdes[PKTBUFSTX - 1].txdes0 = priv->txdes0_edotr_mask;
+
+ start = (ulong)&priv->txdes[0];
+ end = start + roundup(sizeof(priv->txdes), ARCH_DMA_MINALIGN);
+ flush_dcache_range(start, end);
for (i = 0; i < PKTBUFSRX; i++) {
- /* RXBUF_BADR */
- if (!rxdes[i].rxdes2) {
- buf = net_rx_packets[i];
- rxdes[i].rxdes3 = virt_to_phys(buf);
- rxdes[i].rxdes2 = (uint)buf;
- }
- rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+ priv->rxdes[i].rxdes3 = (unsigned int)net_rx_packets[i];
+ priv->rxdes[i].rxdes0 = 0;
}
+ priv->rxdes[PKTBUFSRX - 1].rxdes0 = priv->rxdes0_edorr_mask;
+
+ start = (ulong)&priv->rxdes[0];
+ end = start + roundup(sizeof(priv->rxdes), ARCH_DMA_MINALIGN);
+ flush_dcache_range(start, end);
/* transmit ring */
- writel(priv->txdes_dma, &ftgmac100->txr_badr);
+ writel((u32)priv->txdes, &ftgmac100->txr_badr);
/* receive ring */
- writel(priv->rxdes_dma, &ftgmac100->rxr_badr);
+ writel((u32)priv->rxdes, &ftgmac100->rxr_badr);
/* poll receive descriptor automatically */
writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
/* config receive buffer size register */
- writel(FTGMAC100_RBSR_SIZE(RBSR_DEFAULT_VALUE), &ftgmac100->rbsr);
+ writel(FTGMAC100_RBSR_SIZE(FTGMAC100_RBSR_DEFAULT), &ftgmac100->rbsr);
/* enable transmitter, receiver */
maccr = FTGMAC100_MACCR_TXMAC_EN |
@@ -453,34 +347,67 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
writel(maccr, &ftgmac100->maccr);
- if (!ftgmac100_phy_init(dev)) {
- if (!ftgmac100_update_link_speed(dev))
- return -1;
+ ret = phy_startup(phydev);
+ if (ret) {
+ dev_err(phydev->dev, "Could not start PHY\n");
+ return ret;
}
+ ret = ftgmac100_phy_adjust_link(priv);
+ if (ret) {
+ dev_err(phydev->dev, "Could not adjust link\n");
+ return ret;
+ }
+
+ printf("%s: link up, %d Mbps %s-duplex mac:%pM\n", phydev->dev->name,
+ phydev->speed, phydev->duplex ? "full" : "half", plat->enetaddr);
+
+ return 0;
+}
+
+static int ftgmac100_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
+ ulong des_start = (ulong)curr_des;
+ ulong des_end = des_start +
+ roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
+
+ /* Release buffer to DMA and flush descriptor */
+ curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+ flush_dcache_range(des_start, des_end);
+
+ /* Move to next descriptor */
+ priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
+
return 0;
}
/*
* Get a data block via Ethernet
*/
-static int ftgmac100_recv(struct eth_device *dev)
+static int ftgmac100_recv(struct udevice *dev, int flags, uchar **packetp)
{
- struct ftgmac100_data *priv = dev->priv;
- struct ftgmac100_rxdes *curr_des;
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
unsigned short rxlen;
+ ulong des_start = (ulong)curr_des;
+ ulong des_end = des_start +
+ roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
+ ulong data_start = curr_des->rxdes3;
+ ulong data_end;
- curr_des = &priv->rxdes[priv->rx_index];
+ invalidate_dcache_range(des_start, des_end);
if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY))
- return -1;
+ return -EAGAIN;
if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR |
FTGMAC100_RXDES0_CRC_ERR |
FTGMAC100_RXDES0_FTL |
FTGMAC100_RXDES0_RUNT |
FTGMAC100_RXDES0_RX_ODD_NB)) {
- return -1;
+ return -EAGAIN;
}
rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0);
@@ -488,95 +415,194 @@ static int ftgmac100_recv(struct eth_device *dev)
debug("%s(): RX buffer %d, %x received\n",
__func__, priv->rx_index, rxlen);
- /* invalidate d-cache */
- dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE);
+ /* Invalidate received data */
+ data_end = data_start + roundup(rxlen, ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(data_start, data_end);
+ *packetp = (uchar *)data_start;
- /* pass the packet up to the protocol layers. */
- net_process_received_packet((void *)curr_des->rxdes2, rxlen);
+ return rxlen;
+}
- /* release buffer to DMA */
- curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+static u32 ftgmac100_read_txdesc(const void *desc)
+{
+ const struct ftgmac100_txdes *txdes = desc;
+ ulong des_start = (ulong)txdes;
+ ulong des_end = des_start + roundup(sizeof(*txdes), ARCH_DMA_MINALIGN);
- priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
+ invalidate_dcache_range(des_start, des_end);
- return 0;
+ return txdes->txdes0;
}
+BUILD_WAIT_FOR_BIT(ftgmac100_txdone, u32, ftgmac100_read_txdesc)
+
/*
* Send a data block via Ethernet
*/
-static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
+static int ftgmac100_send(struct udevice *dev, void *packet, int length)
{
- struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
- struct ftgmac100_data *priv = dev->priv;
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ struct ftgmac100 *ftgmac100 = priv->iobase;
struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
+ ulong des_start = (ulong)curr_des;
+ ulong des_end = des_start +
+ roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
+ ulong data_start;
+ ulong data_end;
+ int rc;
+
+ invalidate_dcache_range(des_start, des_end);
if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
- debug("%s(): no TX descriptor available\n", __func__);
- return -1;
+ dev_err(dev, "no TX descriptor available\n");
+ return -EPERM;
}
debug("%s(%x, %x)\n", __func__, (int)packet, length);
length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
- memcpy((void *)curr_des->txdes2, (void *)packet, length);
- dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE);
+ curr_des->txdes3 = (unsigned int)packet;
- /* only one descriptor on TXBUF */
- curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR;
+ /* Flush data to be sent */
+ data_start = curr_des->txdes3;
+ data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
+ flush_dcache_range(data_start, data_end);
+
+ /* Only one segment on TXBUF */
+ curr_des->txdes0 &= priv->txdes0_edotr_mask;
curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
FTGMAC100_TXDES0_LTS |
FTGMAC100_TXDES0_TXBUF_SIZE(length) |
FTGMAC100_TXDES0_TXDMA_OWN ;
- /* start transmit */
+ /* Flush modified buffer descriptor */
+ flush_dcache_range(des_start, des_end);
+
+ /* Start transmit */
writel(1, &ftgmac100->txpd);
+ rc = wait_for_bit_ftgmac100_txdone(curr_des,
+ FTGMAC100_TXDES0_TXDMA_OWN, false,
+ FTGMAC100_TX_TIMEOUT_MS, true);
+ if (rc)
+ return rc;
+
debug("%s(): packet sent\n", __func__);
+ /* Move to next descriptor */
priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
return 0;
}
-int ftgmac100_initialize(bd_t *bd)
+static int ftgmac100_write_hwaddr(struct udevice *dev)
{
- struct eth_device *dev;
- struct ftgmac100_data *priv;
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct ftgmac100_data *priv = dev_get_priv(dev);
- dev = malloc(sizeof *dev);
- if (!dev) {
- printf("%s(): failed to allocate dev\n", __func__);
- goto out;
+ return ftgmac100_set_mac(priv, pdata->enetaddr);
+}
+
+static int ftgmac100_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ const char *phy_mode;
+
+ pdata->iobase = devfdt_get_addr(dev);
+ pdata->phy_interface = -1;
+ phy_mode = dev_read_string(dev, "phy-mode");
+ if (phy_mode)
+ pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+ if (pdata->phy_interface == -1) {
+ dev_err(dev, "Invalid PHY interface '%s'\n", phy_mode);
+ return -EINVAL;
}
- /* Transmit and receive descriptors should align to 16 bytes */
- priv = memalign(16, sizeof(struct ftgmac100_data));
- if (!priv) {
- printf("%s(): failed to allocate priv\n", __func__);
- goto free_dev;
+ pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
+
+ if (dev_get_driver_data(dev) == FTGMAC100_MODEL_ASPEED) {
+ priv->rxdes0_edorr_mask = BIT(30);
+ priv->txdes0_edotr_mask = BIT(30);
+ } else {
+ priv->rxdes0_edorr_mask = BIT(15);
+ priv->txdes0_edotr_mask = BIT(15);
}
- memset(dev, 0, sizeof(*dev));
- memset(priv, 0, sizeof(*priv));
+ return clk_get_bulk(dev, &priv->clks);
+}
- strcpy(dev->name, "FTGMAC100");
- dev->iobase = CONFIG_FTGMAC100_BASE;
- dev->init = ftgmac100_init;
- dev->halt = ftgmac100_halt;
- dev->send = ftgmac100_send;
- dev->recv = ftgmac100_recv;
- dev->priv = priv;
+static int ftgmac100_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->iobase = (struct ftgmac100 *)pdata->iobase;
+ priv->phy_mode = pdata->phy_interface;
+ priv->max_speed = pdata->max_speed;
+ priv->phy_addr = 0;
- eth_register(dev);
+ ret = clk_enable_bulk(&priv->clks);
+ if (ret)
+ goto out;
- ftgmac100_reset(dev);
+ ret = ftgmac100_mdio_init(dev);
+ if (ret) {
+ dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
+ goto out;
+ }
- return 1;
+ ret = ftgmac100_phy_init(dev);
+ if (ret) {
+ dev_err(dev, "Failed to initialize PHY: %d\n", ret);
+ goto out;
+ }
-free_dev:
- free(dev);
out:
+ if (ret)
+ clk_release_bulk(&priv->clks);
+
+ return ret;
+}
+
+static int ftgmac100_remove(struct udevice *dev)
+{
+ struct ftgmac100_data *priv = dev_get_priv(dev);
+
+ free(priv->phydev);
+ mdio_unregister(priv->bus);
+ mdio_free(priv->bus);
+ clk_release_bulk(&priv->clks);
+
return 0;
}
+
+static const struct eth_ops ftgmac100_ops = {
+ .start = ftgmac100_start,
+ .send = ftgmac100_send,
+ .recv = ftgmac100_recv,
+ .stop = ftgmac100_stop,
+ .free_pkt = ftgmac100_free_pkt,
+ .write_hwaddr = ftgmac100_write_hwaddr,
+};
+
+static const struct udevice_id ftgmac100_ids[] = {
+ { .compatible = "faraday,ftgmac100", .data = FTGMAC100_MODEL_FARADAY },
+ { .compatible = "aspeed,ast2500-mac", .data = FTGMAC100_MODEL_ASPEED },
+ { }
+};
+
+U_BOOT_DRIVER(ftgmac100) = {
+ .name = "ftgmac100",
+ .id = UCLASS_ETH,
+ .of_match = ftgmac100_ids,
+ .ofdata_to_platdata = ftgmac100_ofdata_to_platdata,
+ .probe = ftgmac100_probe,
+ .remove = ftgmac100_remove,
+ .ops = &ftgmac100_ops,
+ .priv_auto_alloc_size = sizeof(struct ftgmac100_data),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/net/ftgmac100.h b/drivers/net/ftgmac100.h
index ffbe1f3..9a789e4 100644
--- a/drivers/net/ftgmac100.h
+++ b/drivers/net/ftgmac100.h
@@ -70,48 +70,48 @@ struct ftgmac100 {
/*
* Interrupt status register & interrupt enable register
*/
-#define FTGMAC100_INT_RPKT_BUF (1 << 0)
-#define FTGMAC100_INT_RPKT_FIFO (1 << 1)
-#define FTGMAC100_INT_NO_RXBUF (1 << 2)
-#define FTGMAC100_INT_RPKT_LOST (1 << 3)
-#define FTGMAC100_INT_XPKT_ETH (1 << 4)
-#define FTGMAC100_INT_XPKT_FIFO (1 << 5)
-#define FTGMAC100_INT_NO_NPTXBUF (1 << 6)
-#define FTGMAC100_INT_XPKT_LOST (1 << 7)
-#define FTGMAC100_INT_AHB_ERR (1 << 8)
-#define FTGMAC100_INT_PHYSTS_CHG (1 << 9)
-#define FTGMAC100_INT_NO_HPTXBUF (1 << 10)
+#define FTGMAC100_INT_RPKT_BUF BIT(0)
+#define FTGMAC100_INT_RPKT_FIFO BIT(1)
+#define FTGMAC100_INT_NO_RXBUF BIT(2)
+#define FTGMAC100_INT_RPKT_LOST BIT(3)
+#define FTGMAC100_INT_XPKT_ETH BIT(4)
+#define FTGMAC100_INT_XPKT_FIFO BIT(5)
+#define FTGMAC100_INT_NO_NPTXBUF BIT(6)
+#define FTGMAC100_INT_XPKT_LOST BIT(7)
+#define FTGMAC100_INT_AHB_ERR BIT(8)
+#define FTGMAC100_INT_PHYSTS_CHG BIT(9)
+#define FTGMAC100_INT_NO_HPTXBUF BIT(10)
/*
* Interrupt timer control register
*/
#define FTGMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0)
#define FTGMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4)
-#define FTGMAC100_ITC_RXINT_TIME_SEL (1 << 7)
+#define FTGMAC100_ITC_RXINT_TIME_SEL BIT(7)
#define FTGMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8)
#define FTGMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12)
-#define FTGMAC100_ITC_TXINT_TIME_SEL (1 << 15)
+#define FTGMAC100_ITC_TXINT_TIME_SEL BIT(15)
/*
* Automatic polling timer control register
*/
#define FTGMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0)
-#define FTGMAC100_APTC_RXPOLL_TIME_SEL (1 << 4)
+#define FTGMAC100_APTC_RXPOLL_TIME_SEL BIT(4)
#define FTGMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8)
-#define FTGMAC100_APTC_TXPOLL_TIME_SEL (1 << 12)
+#define FTGMAC100_APTC_TXPOLL_TIME_SEL BIT(12)
/*
* DMA burst length and arbitration control register
*/
#define FTGMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 0)
#define FTGMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 3)
-#define FTGMAC100_DBLAC_RX_THR_EN (1 << 6)
+#define FTGMAC100_DBLAC_RX_THR_EN BIT(6)
#define FTGMAC100_DBLAC_RXBURST_SIZE(x) (((x) & 0x3) << 8)
#define FTGMAC100_DBLAC_TXBURST_SIZE(x) (((x) & 0x3) << 10)
#define FTGMAC100_DBLAC_RXDES_SIZE(x) (((x) & 0xf) << 12)
#define FTGMAC100_DBLAC_TXDES_SIZE(x) (((x) & 0xf) << 16)
#define FTGMAC100_DBLAC_IFG_CNT(x) (((x) & 0x7) << 20)
-#define FTGMAC100_DBLAC_IFG_INC (1 << 23)
+#define FTGMAC100_DBLAC_IFG_INC BIT(23)
/*
* DMA FIFO status register
@@ -122,12 +122,12 @@ struct ftgmac100 {
#define FTGMAC100_DMAFIFOS_TXDMA1_SM(dmafifos) (((dmafifos) >> 12) & 0xf)
#define FTGMAC100_DMAFIFOS_TXDMA2_SM(dmafifos) (((dmafifos) >> 16) & 0x3)
#define FTGMAC100_DMAFIFOS_TXDMA3_SM(dmafifos) (((dmafifos) >> 18) & 0xf)
-#define FTGMAC100_DMAFIFOS_RXFIFO_EMPTY (1 << 26)
-#define FTGMAC100_DMAFIFOS_TXFIFO_EMPTY (1 << 27)
-#define FTGMAC100_DMAFIFOS_RXDMA_GRANT (1 << 28)
-#define FTGMAC100_DMAFIFOS_TXDMA_GRANT (1 << 29)
-#define FTGMAC100_DMAFIFOS_RXDMA_REQ (1 << 30)
-#define FTGMAC100_DMAFIFOS_TXDMA_REQ (1 << 31)
+#define FTGMAC100_DMAFIFOS_RXFIFO_EMPTY BIT(26)
+#define FTGMAC100_DMAFIFOS_TXFIFO_EMPTY BIT(27)
+#define FTGMAC100_DMAFIFOS_RXDMA_GRANT BIT(28)
+#define FTGMAC100_DMAFIFOS_TXDMA_GRANT BIT(29)
+#define FTGMAC100_DMAFIFOS_RXDMA_REQ BIT(30)
+#define FTGMAC100_DMAFIFOS_TXDMA_REQ BIT(31)
/*
* Receive buffer size register
@@ -137,26 +137,26 @@ struct ftgmac100 {
/*
* MAC control register
*/
-#define FTGMAC100_MACCR_TXDMA_EN (1 << 0)
-#define FTGMAC100_MACCR_RXDMA_EN (1 << 1)
-#define FTGMAC100_MACCR_TXMAC_EN (1 << 2)
-#define FTGMAC100_MACCR_RXMAC_EN (1 << 3)
-#define FTGMAC100_MACCR_RM_VLAN (1 << 4)
-#define FTGMAC100_MACCR_HPTXR_EN (1 << 5)
-#define FTGMAC100_MACCR_LOOP_EN (1 << 6)
-#define FTGMAC100_MACCR_ENRX_IN_HALFTX (1 << 7)
-#define FTGMAC100_MACCR_FULLDUP (1 << 8)
-#define FTGMAC100_MACCR_GIGA_MODE (1 << 9)
-#define FTGMAC100_MACCR_CRC_APD (1 << 10)
-#define FTGMAC100_MACCR_RX_RUNT (1 << 12)
-#define FTGMAC100_MACCR_JUMBO_LF (1 << 13)
-#define FTGMAC100_MACCR_RX_ALL (1 << 14)
-#define FTGMAC100_MACCR_HT_MULTI_EN (1 << 15)
-#define FTGMAC100_MACCR_RX_MULTIPKT (1 << 16)
-#define FTGMAC100_MACCR_RX_BROADPKT (1 << 17)
-#define FTGMAC100_MACCR_DISCARD_CRCERR (1 << 18)
-#define FTGMAC100_MACCR_FAST_MODE (1 << 19)
-#define FTGMAC100_MACCR_SW_RST (1 << 31)
+#define FTGMAC100_MACCR_TXDMA_EN BIT(0)
+#define FTGMAC100_MACCR_RXDMA_EN BIT(1)
+#define FTGMAC100_MACCR_TXMAC_EN BIT(2)
+#define FTGMAC100_MACCR_RXMAC_EN BIT(3)
+#define FTGMAC100_MACCR_RM_VLAN BIT(4)
+#define FTGMAC100_MACCR_HPTXR_EN BIT(5)
+#define FTGMAC100_MACCR_LOOP_EN BIT(6)
+#define FTGMAC100_MACCR_ENRX_IN_HALFTX BIT(7)
+#define FTGMAC100_MACCR_FULLDUP BIT(8)
+#define FTGMAC100_MACCR_GIGA_MODE BIT(9)
+#define FTGMAC100_MACCR_CRC_APD BIT(10)
+#define FTGMAC100_MACCR_RX_RUNT BIT(12)
+#define FTGMAC100_MACCR_JUMBO_LF BIT(13)
+#define FTGMAC100_MACCR_RX_ALL BIT(14)
+#define FTGMAC100_MACCR_HT_MULTI_EN BIT(15)
+#define FTGMAC100_MACCR_RX_MULTIPKT BIT(16)
+#define FTGMAC100_MACCR_RX_BROADPKT BIT(17)
+#define FTGMAC100_MACCR_DISCARD_CRCERR BIT(18)
+#define FTGMAC100_MACCR_FAST_MODE BIT(19)
+#define FTGMAC100_MACCR_SW_RST BIT(31)
/*
* PHY control register
@@ -165,8 +165,8 @@ struct ftgmac100 {
#define FTGMAC100_PHYCR_MDC_CYCTHR(x) ((x) & 0x3f)
#define FTGMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16)
#define FTGMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21)
-#define FTGMAC100_PHYCR_MIIRD (1 << 26)
-#define FTGMAC100_PHYCR_MIIWR (1 << 27)
+#define FTGMAC100_PHYCR_MIIRD BIT(26)
+#define FTGMAC100_PHYCR_MIIWR BIT(27)
/*
* PHY data register
@@ -182,23 +182,23 @@ struct ftgmac100_txdes {
unsigned int txdes1;
unsigned int txdes2; /* not used by HW */
unsigned int txdes3; /* TXBUF_BADR */
-} __attribute__ ((aligned(16)));
+} __aligned(16);
#define FTGMAC100_TXDES0_TXBUF_SIZE(x) ((x) & 0x3fff)
-#define FTGMAC100_TXDES0_EDOTR (1 << 15)
-#define FTGMAC100_TXDES0_CRC_ERR (1 << 19)
-#define FTGMAC100_TXDES0_LTS (1 << 28)
-#define FTGMAC100_TXDES0_FTS (1 << 29)
-#define FTGMAC100_TXDES0_TXDMA_OWN (1 << 31)
+#define FTGMAC100_TXDES0_EDOTR BIT(15)
+#define FTGMAC100_TXDES0_CRC_ERR BIT(19)
+#define FTGMAC100_TXDES0_LTS BIT(28)
+#define FTGMAC100_TXDES0_FTS BIT(29)
+#define FTGMAC100_TXDES0_TXDMA_OWN BIT(31)
#define FTGMAC100_TXDES1_VLANTAG_CI(x) ((x) & 0xffff)
-#define FTGMAC100_TXDES1_INS_VLANTAG (1 << 16)
-#define FTGMAC100_TXDES1_TCP_CHKSUM (1 << 17)
-#define FTGMAC100_TXDES1_UDP_CHKSUM (1 << 18)
-#define FTGMAC100_TXDES1_IP_CHKSUM (1 << 19)
-#define FTGMAC100_TXDES1_LLC (1 << 22)
-#define FTGMAC100_TXDES1_TX2FIC (1 << 30)
-#define FTGMAC100_TXDES1_TXIC (1 << 31)
+#define FTGMAC100_TXDES1_INS_VLANTAG BIT(16)
+#define FTGMAC100_TXDES1_TCP_CHKSUM BIT(17)
+#define FTGMAC100_TXDES1_UDP_CHKSUM BIT(18)
+#define FTGMAC100_TXDES1_IP_CHKSUM BIT(19)
+#define FTGMAC100_TXDES1_LLC BIT(22)
+#define FTGMAC100_TXDES1_TX2FIC BIT(30)
+#define FTGMAC100_TXDES1_TXIC BIT(31)
/*
* Receive descriptor, aligned to 16 bytes
@@ -208,23 +208,23 @@ struct ftgmac100_rxdes {
unsigned int rxdes1;
unsigned int rxdes2; /* not used by HW */
unsigned int rxdes3; /* RXBUF_BADR */
-} __attribute__ ((aligned(16)));
+} __aligned(16);
#define FTGMAC100_RXDES0_VDBC(x) ((x) & 0x3fff)
-#define FTGMAC100_RXDES0_EDORR (1 << 15)
-#define FTGMAC100_RXDES0_MULTICAST (1 << 16)
-#define FTGMAC100_RXDES0_BROADCAST (1 << 17)
-#define FTGMAC100_RXDES0_RX_ERR (1 << 18)
-#define FTGMAC100_RXDES0_CRC_ERR (1 << 19)
-#define FTGMAC100_RXDES0_FTL (1 << 20)
-#define FTGMAC100_RXDES0_RUNT (1 << 21)
-#define FTGMAC100_RXDES0_RX_ODD_NB (1 << 22)
-#define FTGMAC100_RXDES0_FIFO_FULL (1 << 23)
-#define FTGMAC100_RXDES0_PAUSE_OPCODE (1 << 24)
-#define FTGMAC100_RXDES0_PAUSE_FRAME (1 << 25)
-#define FTGMAC100_RXDES0_LRS (1 << 28)
-#define FTGMAC100_RXDES0_FRS (1 << 29)
-#define FTGMAC100_RXDES0_RXPKT_RDY (1 << 31)
+#define FTGMAC100_RXDES0_EDORR BIT(15)
+#define FTGMAC100_RXDES0_MULTICAST BIT(16)
+#define FTGMAC100_RXDES0_BROADCAST BIT(17)
+#define FTGMAC100_RXDES0_RX_ERR BIT(18)
+#define FTGMAC100_RXDES0_CRC_ERR BIT(19)
+#define FTGMAC100_RXDES0_FTL BIT(20)
+#define FTGMAC100_RXDES0_RUNT BIT(21)
+#define FTGMAC100_RXDES0_RX_ODD_NB BIT(22)
+#define FTGMAC100_RXDES0_FIFO_FULL BIT(23)
+#define FTGMAC100_RXDES0_PAUSE_OPCODE BIT(24)
+#define FTGMAC100_RXDES0_PAUSE_FRAME BIT(25)
+#define FTGMAC100_RXDES0_LRS BIT(28)
+#define FTGMAC100_RXDES0_FRS BIT(29)
+#define FTGMAC100_RXDES0_RXPKT_RDY BIT(31)
#define FTGMAC100_RXDES1_VLANTAG_CI 0xffff
#define FTGMAC100_RXDES1_PROT_MASK (0x3 << 20)
@@ -232,11 +232,11 @@ struct ftgmac100_rxdes {
#define FTGMAC100_RXDES1_PROT_IP (0x1 << 20)
#define FTGMAC100_RXDES1_PROT_TCPIP (0x2 << 20)
#define FTGMAC100_RXDES1_PROT_UDPIP (0x3 << 20)
-#define FTGMAC100_RXDES1_LLC (1 << 22)
-#define FTGMAC100_RXDES1_DF (1 << 23)
-#define FTGMAC100_RXDES1_VLANTAG_AVAIL (1 << 24)
-#define FTGMAC100_RXDES1_TCP_CHKSUM_ERR (1 << 25)
-#define FTGMAC100_RXDES1_UDP_CHKSUM_ERR (1 << 26)
-#define FTGMAC100_RXDES1_IP_CHKSUM_ERR (1 << 27)
+#define FTGMAC100_RXDES1_LLC BIT(22)
+#define FTGMAC100_RXDES1_DF BIT(23)
+#define FTGMAC100_RXDES1_VLANTAG_AVAIL BIT(24)
+#define FTGMAC100_RXDES1_TCP_CHKSUM_ERR BIT(25)
+#define FTGMAC100_RXDES1_UDP_CHKSUM_ERR BIT(26)
+#define FTGMAC100_RXDES1_IP_CHKSUM_ERR BIT(27)
#endif /* __FTGMAC100_H */
diff --git a/drivers/net/mt7628-eth.c b/drivers/net/mt7628-eth.c
new file mode 100644
index 0000000..7833b2f
--- /dev/null
+++ b/drivers/net/mt7628-eth.c
@@ -0,0 +1,644 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MediaTek ethernet IP driver for U-Boot
+ *
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ *
+ * This code is mostly based on the code extracted from this MediaTek
+ * github repository:
+ *
+ * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
+ *
+ * I was not able to find a specific license or other developers
+ * copyrights here, so I can't add them here.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <net.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+#include <linux/bitfield.h>
+#include <linux/err.h>
+
+/* System controller register */
+#define MT7628_RSTCTRL_REG 0x34
+#define RSTCTRL_EPHY_RST BIT(24)
+
+#define MT7628_AGPIO_CFG_REG 0x3c
+#define MT7628_EPHY_GPIO_AIO_EN GENMASK(20, 17)
+#define MT7628_EPHY_P0_DIS BIT(16)
+
+#define MT7628_GPIO2_MODE_REG 0x64
+
+/* Ethernet frame engine register */
+#define PDMA_RELATED 0x0800
+
+#define TX_BASE_PTR0 (PDMA_RELATED + 0x000)
+#define TX_MAX_CNT0 (PDMA_RELATED + 0x004)
+#define TX_CTX_IDX0 (PDMA_RELATED + 0x008)
+#define TX_DTX_IDX0 (PDMA_RELATED + 0x00c)
+
+#define RX_BASE_PTR0 (PDMA_RELATED + 0x100)
+#define RX_MAX_CNT0 (PDMA_RELATED + 0x104)
+#define RX_CALC_IDX0 (PDMA_RELATED + 0x108)
+
+#define PDMA_GLO_CFG (PDMA_RELATED + 0x204)
+#define PDMA_RST_IDX (PDMA_RELATED + 0x208)
+#define DLY_INT_CFG (PDMA_RELATED + 0x20c)
+
+#define SDM_RELATED 0x0c00
+
+#define SDM_MAC_ADRL (SDM_RELATED + 0x0c) /* MAC address LSB */
+#define SDM_MAC_ADRH (SDM_RELATED + 0x10) /* MAC Address MSB */
+
+#define RST_DTX_IDX0 BIT(0)
+#define RST_DRX_IDX0 BIT(16)
+
+#define TX_DMA_EN BIT(0)
+#define TX_DMA_BUSY BIT(1)
+#define RX_DMA_EN BIT(2)
+#define RX_DMA_BUSY BIT(3)
+#define TX_WB_DDONE BIT(6)
+
+/* Ethernet switch register */
+#define MT7628_SWITCH_FCT0 0x0008
+#define MT7628_SWITCH_PFC1 0x0014
+#define MT7628_SWITCH_FPA 0x0084
+#define MT7628_SWITCH_SOCPC 0x008c
+#define MT7628_SWITCH_POC0 0x0090
+#define MT7628_SWITCH_POC2 0x0098
+#define MT7628_SWITCH_SGC 0x009c
+#define MT7628_SWITCH_PCR0 0x00c0
+#define PCR0_PHY_ADDR GENMASK(4, 0)
+#define PCR0_PHY_REG GENMASK(12, 8)
+#define PCR0_WT_PHY_CMD BIT(13)
+#define PCR0_RD_PHY_CMD BIT(14)
+#define PCR0_WT_DATA GENMASK(31, 16)
+
+#define MT7628_SWITCH_PCR1 0x00c4
+#define PCR1_WT_DONE BIT(0)
+#define PCR1_RD_RDY BIT(1)
+#define PCR1_RD_DATA GENMASK(31, 16)
+
+#define MT7628_SWITCH_FPA1 0x00c8
+#define MT7628_SWITCH_FCT2 0x00cc
+#define MT7628_SWITCH_SGC2 0x00e4
+#define MT7628_SWITCH_BMU_CTRL 0x0110
+
+/* rxd2 */
+#define RX_DMA_DONE BIT(31)
+#define RX_DMA_LSO BIT(30)
+#define RX_DMA_PLEN0 GENMASK(29, 16)
+#define RX_DMA_TAG BIT(15)
+
+struct fe_rx_dma {
+ unsigned int rxd1;
+ unsigned int rxd2;
+ unsigned int rxd3;
+ unsigned int rxd4;
+} __packed __aligned(4);
+
+#define TX_DMA_PLEN0 GENMASK(29, 16)
+#define TX_DMA_LS1 BIT(14)
+#define TX_DMA_LS0 BIT(30)
+#define TX_DMA_DONE BIT(31)
+
+#define TX_DMA_INS_VLAN_MT7621 BIT(16)
+#define TX_DMA_INS_VLAN BIT(7)
+#define TX_DMA_INS_PPPOE BIT(12)
+#define TX_DMA_PN GENMASK(26, 24)
+
+struct fe_tx_dma {
+ unsigned int txd1;
+ unsigned int txd2;
+ unsigned int txd3;
+ unsigned int txd4;
+} __packed __aligned(4);
+
+#define NUM_RX_DESC 256
+#define NUM_TX_DESC 4
+
+#define PADDING_LENGTH 60
+
+#define MTK_QDMA_PAGE_SIZE 2048
+
+#define CONFIG_MDIO_TIMEOUT 100
+#define CONFIG_DMA_STOP_TIMEOUT 100
+#define CONFIG_TX_DMA_TIMEOUT 100
+
+#define LINK_DELAY_TIME 500 /* 500 ms */
+#define LINK_TIMEOUT 10000 /* 10 seconds */
+
+struct mt7628_eth_dev {
+ void __iomem *base; /* frame engine base address */
+ void __iomem *eth_sw_base; /* switch base address */
+ struct regmap *sysctrl_regmap; /* system-controller reg-map */
+
+ struct mii_dev *bus;
+
+ struct fe_tx_dma *tx_ring;
+ struct fe_rx_dma *rx_ring;
+
+ u8 *rx_buf[NUM_RX_DESC];
+
+ /* Point to the next RXD DMA wants to use in RXD Ring0 */
+ int rx_dma_idx;
+ /* Point to the next TXD in TXD Ring0 CPU wants to use */
+ int tx_dma_idx;
+};
+
+static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set)
+{
+ void __iomem *base = priv->eth_sw_base;
+ int ret;
+
+ ret = wait_for_bit_le32(base + MT7628_SWITCH_PCR1, mask, mask_set,
+ CONFIG_MDIO_TIMEOUT, false);
+ if (ret) {
+ printf("MDIO operation timeout!\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int mii_mgr_read(struct mt7628_eth_dev *priv,
+ u32 phy_addr, u32 phy_register, u32 *read_data)
+{
+ void __iomem *base = priv->eth_sw_base;
+ u32 status = 0;
+ u32 ret;
+
+ *read_data = 0xffff;
+ /* Make sure previous read operation is complete */
+ ret = mdio_wait_read(priv, PCR1_RD_RDY, false);
+ if (ret)
+ return ret;
+
+ writel(PCR0_RD_PHY_CMD |
+ FIELD_PREP(PCR0_PHY_REG, phy_register) |
+ FIELD_PREP(PCR0_PHY_ADDR, phy_addr),
+ base + MT7628_SWITCH_PCR0);
+
+ /* Make sure previous read operation is complete */
+ ret = mdio_wait_read(priv, PCR1_RD_RDY, true);
+ if (ret)
+ return ret;
+
+ status = readl(base + MT7628_SWITCH_PCR1);
+ *read_data = FIELD_GET(PCR1_RD_DATA, status);
+
+ return 0;
+}
+
+static int mii_mgr_write(struct mt7628_eth_dev *priv,
+ u32 phy_addr, u32 phy_register, u32 write_data)
+{
+ void __iomem *base = priv->eth_sw_base;
+ u32 data;
+ int ret;
+
+ /* Make sure previous write operation is complete */
+ ret = mdio_wait_read(priv, PCR1_WT_DONE, false);
+ if (ret)
+ return ret;
+
+ data = FIELD_PREP(PCR0_WT_DATA, write_data) |
+ FIELD_PREP(PCR0_PHY_REG, phy_register) |
+ FIELD_PREP(PCR0_PHY_ADDR, phy_addr) |
+ PCR0_WT_PHY_CMD;
+ writel(data, base + MT7628_SWITCH_PCR0);
+
+ return mdio_wait_read(priv, PCR1_WT_DONE, true);
+}
+
+static int mt7628_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ u32 val;
+ int ret;
+
+ ret = mii_mgr_read(bus->priv, addr, reg, &val);
+ if (ret)
+ return ret;
+
+ return val;
+}
+
+static int mt7628_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 value)
+{
+ return mii_mgr_write(bus->priv, addr, reg, value);
+}
+
+static void mt7628_ephy_init(struct mt7628_eth_dev *priv)
+{
+ int i;
+
+ mii_mgr_write(priv, 0, 31, 0x2000); /* change G2 page */
+ mii_mgr_write(priv, 0, 26, 0x0000);
+
+ for (i = 0; i < 5; i++) {
+ mii_mgr_write(priv, i, 31, 0x8000); /* change L0 page */
+ mii_mgr_write(priv, i, 0, 0x3100);
+
+ /* EEE disable */
+ mii_mgr_write(priv, i, 30, 0xa000);
+ mii_mgr_write(priv, i, 31, 0xa000); /* change L2 page */
+ mii_mgr_write(priv, i, 16, 0x0606);
+ mii_mgr_write(priv, i, 23, 0x0f0e);
+ mii_mgr_write(priv, i, 24, 0x1610);
+ mii_mgr_write(priv, i, 30, 0x1f15);
+ mii_mgr_write(priv, i, 28, 0x6111);
+ }
+
+ /* 100Base AOI setting */
+ mii_mgr_write(priv, 0, 31, 0x5000); /* change G5 page */
+ mii_mgr_write(priv, 0, 19, 0x004a);
+ mii_mgr_write(priv, 0, 20, 0x015a);
+ mii_mgr_write(priv, 0, 21, 0x00ee);
+ mii_mgr_write(priv, 0, 22, 0x0033);
+ mii_mgr_write(priv, 0, 23, 0x020a);
+ mii_mgr_write(priv, 0, 24, 0x0000);
+ mii_mgr_write(priv, 0, 25, 0x024a);
+ mii_mgr_write(priv, 0, 26, 0x035a);
+ mii_mgr_write(priv, 0, 27, 0x02ee);
+ mii_mgr_write(priv, 0, 28, 0x0233);
+ mii_mgr_write(priv, 0, 29, 0x000a);
+ mii_mgr_write(priv, 0, 30, 0x0000);
+
+ /* Fix EPHY idle state abnormal behavior */
+ mii_mgr_write(priv, 0, 31, 0x4000); /* change G4 page */
+ mii_mgr_write(priv, 0, 29, 0x000d);
+ mii_mgr_write(priv, 0, 30, 0x0500);
+}
+
+static void rt305x_esw_init(struct mt7628_eth_dev *priv)
+{
+ void __iomem *base = priv->eth_sw_base;
+
+ /*
+ * FC_RLS_TH=200, FC_SET_TH=160
+ * DROP_RLS=120, DROP_SET_TH=80
+ */
+ writel(0xc8a07850, base + MT7628_SWITCH_FCT0);
+ writel(0x00000000, base + MT7628_SWITCH_SGC2);
+ writel(0x00405555, base + MT7628_SWITCH_PFC1);
+ writel(0x00007f7f, base + MT7628_SWITCH_POC0);
+ writel(0x00007f7f, base + MT7628_SWITCH_POC2); /* disable VLAN */
+ writel(0x0002500c, base + MT7628_SWITCH_FCT2);
+ /* hashing algorithm=XOR48, aging interval=300sec */
+ writel(0x0008a301, base + MT7628_SWITCH_SGC);
+ writel(0x02404040, base + MT7628_SWITCH_SOCPC);
+
+ /* Ext PHY Addr=0x1f */
+ writel(0x3f502b28, base + MT7628_SWITCH_FPA1);
+ writel(0x00000000, base + MT7628_SWITCH_FPA);
+ /* 1us cycle number=125 (FE's clock=125Mhz) */
+ writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
+
+ /* Configure analog GPIO setup */
+ regmap_update_bits(priv->sysctrl_regmap, MT7628_AGPIO_CFG_REG,
+ MT7628_EPHY_P0_DIS, MT7628_EPHY_GPIO_AIO_EN);
+
+ /* Reset PHY */
+ regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
+ 0, RSTCTRL_EPHY_RST);
+ regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
+ RSTCTRL_EPHY_RST, 0);
+ mdelay(10);
+
+ /* Set P0 EPHY LED mode */
+ regmap_update_bits(priv->sysctrl_regmap, MT7628_GPIO2_MODE_REG,
+ 0x0ffc0ffc, 0x05540554);
+ mdelay(10);
+
+ mt7628_ephy_init(priv);
+}
+
+static void eth_dma_start(struct mt7628_eth_dev *priv)
+{
+ void __iomem *base = priv->base;
+
+ setbits_le32(base + PDMA_GLO_CFG, TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
+}
+
+static void eth_dma_stop(struct mt7628_eth_dev *priv)
+{
+ void __iomem *base = priv->base;
+ int ret;
+
+ clrbits_le32(base + PDMA_GLO_CFG, TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
+
+ /* Wait for DMA to stop */
+ ret = wait_for_bit_le32(base + PDMA_GLO_CFG,
+ RX_DMA_BUSY | TX_DMA_BUSY, false,
+ CONFIG_DMA_STOP_TIMEOUT, false);
+ if (ret)
+ printf("DMA stop timeout error!\n");
+}
+
+static int mt7628_eth_write_hwaddr(struct udevice *dev)
+{
+ struct mt7628_eth_dev *priv = dev_get_priv(dev);
+ void __iomem *base = priv->base;
+ u8 *addr = ((struct eth_pdata *)dev_get_platdata(dev))->enetaddr;
+ u32 val;
+
+ /* Set MAC address. */
+ val = addr[0];
+ val = (val << 8) | addr[1];
+ writel(val, base + SDM_MAC_ADRH);
+
+ val = addr[2];
+ val = (val << 8) | addr[3];
+ val = (val << 8) | addr[4];
+ val = (val << 8) | addr[5];
+ writel(val, base + SDM_MAC_ADRL);
+
+ return 0;
+}
+
+static int mt7628_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct mt7628_eth_dev *priv = dev_get_priv(dev);
+ void __iomem *base = priv->base;
+ int ret;
+ int idx;
+ int i;
+
+ idx = priv->tx_dma_idx;
+
+ /* Pad message to a minimum length */
+ if (length < PADDING_LENGTH) {
+ char *p = (char *)packet;
+
+ for (i = 0; i < PADDING_LENGTH - length; i++)
+ p[length + i] = 0;
+ length = PADDING_LENGTH;
+ }
+
+ /* Check if buffer is ready for next TX DMA */
+ ret = wait_for_bit_le32(&priv->tx_ring[idx].txd2, TX_DMA_DONE, true,
+ CONFIG_TX_DMA_TIMEOUT, false);
+ if (ret) {
+ printf("TX: DMA still busy on buffer %d\n", idx);
+ return ret;
+ }
+
+ flush_dcache_range((u32)packet, (u32)packet + length);
+
+ priv->tx_ring[idx].txd1 = CPHYSADDR(packet);
+ priv->tx_ring[idx].txd2 &= ~TX_DMA_PLEN0;
+ priv->tx_ring[idx].txd2 |= FIELD_PREP(TX_DMA_PLEN0, length);
+ priv->tx_ring[idx].txd2 &= ~TX_DMA_DONE;
+
+ idx = (idx + 1) % NUM_TX_DESC;
+
+ /* Make sure the writes executed at this place */
+ wmb();
+ writel(idx, base + TX_CTX_IDX0);
+
+ priv->tx_dma_idx = idx;
+
+ return 0;
+}
+
+static int mt7628_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct mt7628_eth_dev *priv = dev_get_priv(dev);
+ u32 rxd_info;
+ int length;
+ int idx;
+
+ idx = priv->rx_dma_idx;
+
+ rxd_info = priv->rx_ring[idx].rxd2;
+ if ((rxd_info & RX_DMA_DONE) == 0)
+ return -EAGAIN;
+
+ length = FIELD_GET(RX_DMA_PLEN0, priv->rx_ring[idx].rxd2);
+ if (length == 0 || length > MTK_QDMA_PAGE_SIZE) {
+ printf("%s: invalid length (%d bytes)\n", __func__, length);
+ return -EIO;
+ }
+
+ *packetp = priv->rx_buf[idx];
+ invalidate_dcache_range((u32)*packetp, (u32)*packetp + length);
+
+ priv->rx_ring[idx].rxd4 = 0;
+ priv->rx_ring[idx].rxd2 = RX_DMA_LSO;
+
+ /* Make sure the writes executed at this place */
+ wmb();
+
+ return length;
+}
+
+static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+ struct mt7628_eth_dev *priv = dev_get_priv(dev);
+ void __iomem *base = priv->base;
+ int idx;
+
+ idx = priv->rx_dma_idx;
+
+ /* Move point to next RXD which wants to alloc */
+ writel(idx, base + RX_CALC_IDX0);
+
+ /* Update to Next packet point that was received */
+ idx = (idx + 1) % NUM_RX_DESC;
+
+ priv->rx_dma_idx = idx;
+
+ return 0;
+}
+
+static int phy_link_up(struct mt7628_eth_dev *priv)
+{
+ u32 val;
+
+ mii_mgr_read(priv, 0x00, MII_BMSR, &val);
+ return !!(val & BMSR_LSTATUS);
+}
+
+static int mt7628_eth_start(struct udevice *dev)
+{
+ struct mt7628_eth_dev *priv = dev_get_priv(dev);
+ void __iomem *base = priv->base;
+ uchar packet[MTK_QDMA_PAGE_SIZE];
+ uchar *packetp;
+ int i;
+
+ for (i = 0; i < NUM_RX_DESC; i++) {
+ memset((void *)&priv->rx_ring[i], 0, sizeof(priv->rx_ring[0]));
+ priv->rx_ring[i].rxd2 |= RX_DMA_LSO;
+ priv->rx_ring[i].rxd1 = CPHYSADDR(priv->rx_buf[i]);
+ }
+
+ for (i = 0; i < NUM_TX_DESC; i++) {
+ memset((void *)&priv->tx_ring[i], 0, sizeof(priv->tx_ring[0]));
+ priv->tx_ring[i].txd2 = TX_DMA_LS0 | TX_DMA_DONE;
+ priv->tx_ring[i].txd4 = FIELD_PREP(TX_DMA_PN, 1);
+ }
+
+ priv->rx_dma_idx = 0;
+ priv->tx_dma_idx = 0;
+
+ /* Make sure the writes executed at this place */
+ wmb();
+
+ /* disable delay interrupt */
+ writel(0, base + DLY_INT_CFG);
+
+ clrbits_le32(base + PDMA_GLO_CFG, 0xffff0000);
+
+ /* Tell the adapter where the TX/RX rings are located. */
+ writel(CPHYSADDR(&priv->rx_ring[0]), base + RX_BASE_PTR0);
+ writel(CPHYSADDR((u32)&priv->tx_ring[0]), base + TX_BASE_PTR0);
+
+ writel(NUM_RX_DESC, base + RX_MAX_CNT0);
+ writel(NUM_TX_DESC, base + TX_MAX_CNT0);
+
+ writel(priv->tx_dma_idx, base + TX_CTX_IDX0);
+ writel(RST_DTX_IDX0, base + PDMA_RST_IDX);
+
+ writel(NUM_RX_DESC - 1, base + RX_CALC_IDX0);
+ writel(RST_DRX_IDX0, base + PDMA_RST_IDX);
+
+ /* Make sure the writes executed at this place */
+ wmb();
+ eth_dma_start(priv);
+
+ /* Check if link is not up yet */
+ if (!phy_link_up(priv)) {
+ /* Wait for link to come up */
+
+ printf("Waiting for link to come up .");
+ for (i = 0; i < (LINK_TIMEOUT / LINK_DELAY_TIME); i++) {
+ mdelay(LINK_DELAY_TIME);
+ if (phy_link_up(priv)) {
+ mdelay(100); /* Ensure all is ready */
+ break;
+ }
+
+ printf(".");
+ }
+
+ if (phy_link_up(priv))
+ printf(" done\n");
+ else
+ printf(" timeout! Trying anyways\n");
+ }
+
+ /*
+ * The integrated switch seems to queue some received ethernet
+ * packets in some FIFO. Lets read the already queued packets
+ * out by using the receive routine, so that these old messages
+ * are dropped before the new xfer starts.
+ */
+ packetp = &packet[0];
+ while (mt7628_eth_recv(dev, 0, &packetp) != -EAGAIN)
+ mt7628_eth_free_pkt(dev, packetp, 0);
+
+ return 0;
+}
+
+static void mt7628_eth_stop(struct udevice *dev)
+{
+ struct mt7628_eth_dev *priv = dev_get_priv(dev);
+
+ eth_dma_stop(priv);
+}
+
+static int mt7628_eth_probe(struct udevice *dev)
+{
+ struct mt7628_eth_dev *priv = dev_get_priv(dev);
+ struct udevice *syscon;
+ struct mii_dev *bus;
+ int ret;
+ int i;
+
+ /* Save frame-engine base address for later use */
+ priv->base = dev_remap_addr_index(dev, 0);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ /* Save switch base address for later use */
+ priv->eth_sw_base = dev_remap_addr_index(dev, 1);
+ if (IS_ERR(priv->eth_sw_base))
+ return PTR_ERR(priv->eth_sw_base);
+
+ /* Get system controller regmap */
+ ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+ "syscon", &syscon);
+ if (ret) {
+ pr_err("unable to find syscon device\n");
+ return ret;
+ }
+
+ priv->sysctrl_regmap = syscon_get_regmap(syscon);
+ if (!priv->sysctrl_regmap) {
+ pr_err("unable to find regmap\n");
+ return -ENODEV;
+ }
+
+ /* Put rx and tx rings into KSEG1 area (uncached) */
+ priv->tx_ring = (struct fe_tx_dma *)
+ KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,
+ sizeof(*priv->tx_ring) * NUM_TX_DESC));
+ priv->rx_ring = (struct fe_rx_dma *)
+ KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,
+ sizeof(*priv->rx_ring) * NUM_RX_DESC));
+
+ for (i = 0; i < NUM_RX_DESC; i++)
+ priv->rx_buf[i] = memalign(PKTALIGN, MTK_QDMA_PAGE_SIZE);
+
+ bus = mdio_alloc();
+ if (!bus) {
+ printf("Failed to allocate MDIO bus\n");
+ return -ENOMEM;
+ }
+
+ bus->read = mt7628_mdio_read;
+ bus->write = mt7628_mdio_write;
+ snprintf(bus->name, sizeof(bus->name), dev->name);
+ bus->priv = (void *)priv;
+
+ ret = mdio_register(bus);
+ if (ret)
+ return ret;
+
+ /* Switch configuration */
+ rt305x_esw_init(priv);
+
+ return 0;
+}
+
+static const struct eth_ops mt7628_eth_ops = {
+ .start = mt7628_eth_start,
+ .send = mt7628_eth_send,
+ .recv = mt7628_eth_recv,
+ .free_pkt = mt7628_eth_free_pkt,
+ .stop = mt7628_eth_stop,
+ .write_hwaddr = mt7628_eth_write_hwaddr,
+};
+
+static const struct udevice_id mt7628_eth_ids[] = {
+ { .compatible = "mediatek,mt7628-eth" },
+ { }
+};
+
+U_BOOT_DRIVER(mt7628_eth) = {
+ .name = "mt7628_eth",
+ .id = UCLASS_ETH,
+ .of_match = mt7628_eth_ids,
+ .probe = mt7628_eth_probe,
+ .ops = &mt7628_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct mt7628_eth_dev),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index 6f102f1..72bbda5 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -11,12 +11,16 @@
#include <miiphy.h>
#include <bitfield.h>
+#include <time.h>
+#include <linux/delay.h>
/* Microsemi PHY ID's */
#define PHY_ID_VSC8530 0x00070560
#define PHY_ID_VSC8531 0x00070570
#define PHY_ID_VSC8540 0x00070760
#define PHY_ID_VSC8541 0x00070770
+#define PHY_ID_VSC8574 0x000704a0
+#define PHY_ID_VSC8584 0x000707c0
/* Microsemi VSC85xx PHY Register Pages */
#define MSCC_EXT_PAGE_ACCESS 31 /* Page Access Register */
@@ -29,6 +33,17 @@
#define MSCC_PHY_PAGE_TEST 0x2A30 /* TEST Page registers */
#define MSCC_PHY_PAGE_TR 0x52B5 /* Token Ring Page registers */
+/* Std Page Register 18 */
+#define MSCC_PHY_BYPASS_CONTROL 18
+#define PARALLEL_DET_IGNORE_ADVERTISED BIT(3)
+
+/* Std Page Register 22 */
+#define MSCC_PHY_EXT_CNTL_STATUS 22
+#define SMI_BROADCAST_WR_EN BIT(0)
+
+/* Std Page Register 24 */
+#define MSCC_PHY_EXT_PHY_CNTL_2 24
+
/* Std Page Register 28 - PHY AUX Control/Status */
#define MIIM_AUX_CNTRL_STAT_REG 28
#define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO (0x0004)
@@ -47,6 +62,37 @@
#define MAC_IF_SELECTION_RGMII (2)
#define MAC_IF_SELECTION_POS (11)
#define MAC_IF_SELECTION_WIDTH (2)
+#define VSC8584_MAC_IF_SELECTION_MASK BIT(12)
+#define VSC8584_MAC_IF_SELECTION_SGMII 0
+#define VSC8584_MAC_IF_SELECTION_1000BASEX 1
+#define VSC8584_MAC_IF_SELECTION_POS 12
+#define MEDIA_OP_MODE_MASK GENMASK(10, 8)
+#define MEDIA_OP_MODE_COPPER 0
+#define MEDIA_OP_MODE_SERDES 1
+#define MEDIA_OP_MODE_1000BASEX 2
+#define MEDIA_OP_MODE_100BASEFX 3
+#define MEDIA_OP_MODE_AMS_COPPER_SERDES 5
+#define MEDIA_OP_MODE_AMS_COPPER_1000BASEX 6
+#define MEDIA_OP_MODE_AMS_COPPER_100BASEFX 7
+#define MEDIA_OP_MODE_POS 8
+
+/* Extended Page 1 Register 20E1 */
+#define MSCC_PHY_ACTIPHY_CNTL 20
+#define PHY_ADDR_REVERSED BIT(9)
+
+/* Extended Page 1 Register 23E1 */
+
+#define MSCC_PHY_EXT_PHY_CNTL_4 23
+#define PHY_CNTL_4_ADDR_POS 11
+
+/* Extended Page 1 Register 25E1 */
+#define MSCC_PHY_VERIPHY_CNTL_2 25
+
+/* Extended Page 1 Register 26E1 */
+#define MSCC_PHY_VERIPHY_CNTL_3 26
+
+/* Extended Page 2 Register 16E2 */
+#define MSCC_PHY_CU_PMD_TX_CNTL 16
/* Extended Page 2 Register 20E2 */
#define MSCC_PHY_RGMII_CNTL_REG 20
@@ -72,6 +118,85 @@
#define RMII_CLK_OUT_ENABLE_WIDTH (1)
#define RMII_CLK_OUT_ENABLE_MASK (0x10)
+/* Extended Page 3 Register 22E3 */
+#define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22
+
+/* Extended page GPIO register 00G */
+#define MSCC_DW8051_CNTL_STATUS 0
+#define MICRO_NSOFT_RESET BIT(15)
+#define RUN_FROM_INT_ROM BIT(14)
+#define AUTOINC_ADDR BIT(13)
+#define PATCH_RAM_CLK BIT(12)
+#define MICRO_PATCH_EN BIT(7)
+#define DW8051_CLK_EN BIT(4)
+#define MICRO_CLK_EN BIT(3)
+#define MICRO_CLK_DIVIDE(x) ((x) >> 1)
+#define MSCC_DW8051_VLD_MASK 0xf1ff
+
+/* Extended page GPIO register 09G */
+#define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1)
+#define MSCC_TRAP_ROM_ADDR_SERDES_INIT 0x3eb7
+
+/* Extended page GPIO register 10G */
+#define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2)
+#define MSCC_PATCH_RAM_ADDR_SERDES_INIT 0x4012
+
+/* Extended page GPIO register 11G */
+#define MSCC_INT_MEM_ADDR 11
+
+/* Extended page GPIO register 12G */
+#define MSCC_INT_MEM_CNTL 12
+#define READ_SFR (BIT(14) | BIT(13))
+#define READ_PRAM BIT(14)
+#define READ_ROM BIT(13)
+#define READ_RAM (0x00 << 13)
+#define INT_MEM_WRITE_EN BIT(12)
+#define EN_PATCH_RAM_TRAP_ADDR(x) BIT((x) + 7)
+#define INT_MEM_DATA_M GENMASK(7, 0)
+#define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
+
+/* Extended page GPIO register 18G */
+#define MSCC_PHY_PROC_CMD 18
+#define PROC_CMD_NCOMPLETED BIT(15)
+#define PROC_CMD_FAILED BIT(14)
+#define PROC_CMD_SGMII_PORT(x) ((x) << 8)
+#define PROC_CMD_FIBER_PORT(x) BIT(8 + (x) % 4)
+#define PROC_CMD_QSGMII_PORT (BIT(11) | BIT(10))
+#define PROC_CMD_RST_CONF_PORT BIT(7)
+#define PROC_CMD_RECONF_PORT (0 << 7)
+#define PROC_CMD_READ_MOD_WRITE_PORT BIT(6)
+#define PROC_CMD_WRITE BIT(6)
+#define PROC_CMD_READ (0 << 6)
+#define PROC_CMD_FIBER_DISABLE BIT(5)
+#define PROC_CMD_FIBER_100BASE_FX BIT(4)
+#define PROC_CMD_FIBER_1000BASE_X (0 << 4)
+#define PROC_CMD_SGMII_MAC (BIT(5) | BIT(4))
+#define PROC_CMD_QSGMII_MAC BIT(5)
+#define PROC_CMD_NO_MAC_CONF (0x00 << 4)
+#define PROC_CMD_1588_DEFAULT_INIT BIT(4)
+#define PROC_CMD_NOP GENMASK(3, 0)
+#define PROC_CMD_PHY_INIT (BIT(3) | BIT(1))
+#define PROC_CMD_CRC16 BIT(3)
+#define PROC_CMD_FIBER_MEDIA_CONF BIT(0)
+#define PROC_CMD_MCB_ACCESS_MAC_CONF (0x0000 << 0)
+#define PROC_CMD_NCOMPLETED_TIMEOUT_MS 500
+
+/* Extended page GPIO register 19G */
+#define MSCC_PHY_MAC_CFG_FASTLINK 19
+#define MAC_CFG_MASK GENMASK(15, 14)
+#define MAC_CFG_SGMII (0x00 << 14)
+#define MAC_CFG_QSGMII BIT(14)
+
+/* Test Registers */
+#define MSCC_PHY_TEST_PAGE_5 5
+
+#define MSCC_PHY_TEST_PAGE_8 8
+#define TR_CLK_DISABLE BIT(15)
+
+#define MSCC_PHY_TEST_PAGE_9 9
+#define MSCC_PHY_TEST_PAGE_20 20
+#define MSCC_PHY_TEST_PAGE_24 24
+
/* Token Ring Page 0x52B5 Registers */
#define MSCC_PHY_REG_TR_ADDR_16 16
#define MSCC_PHY_REG_TR_DATA_17 17
@@ -110,6 +235,15 @@
#define MSCC_PHY_RESET_TIMEOUT (100)
#define MSCC_PHY_MICRO_TIMEOUT (500)
+#define VSC8584_REVB 0x0001
+#define MSCC_DEV_REV_MASK GENMASK(3, 0)
+
+#define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000
+#define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8
+
+#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
+#define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48
+
/* RGMII/GMII Clock Delay (Skew) Options */ enum vsc_phy_rgmii_skew {
VSC_PHY_RGMII_DELAY_200_PS,
VSC_PHY_RGMII_DELAY_800_PS,
@@ -133,6 +267,743 @@ vsc_phy_clk_slew {
VSC_PHY_CLK_SLEW_RATE_7,
};
+struct vsc85xx_priv {
+ int (*config_pre)(struct phy_device *phydev);
+};
+
+static void vsc8584_csr_write(struct mii_dev *bus, int phy0, u16 addr, u32 val)
+{
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18,
+ val >> 16);
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17,
+ val & GENMASK(15, 0));
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
+ MSCC_PHY_TR_16_WRITE | addr);
+}
+
+static int vsc8584_cmd(struct mii_dev *bus, int phy, u16 val)
+{
+ unsigned long deadline;
+ u16 reg_val;
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
+ PROC_CMD_NCOMPLETED | val);
+
+ deadline = timer_get_us() + PROC_CMD_NCOMPLETED_TIMEOUT_MS * 1000;
+ do {
+ reg_val = bus->read(bus, phy, MDIO_DEVAD_NONE,
+ MSCC_PHY_PROC_CMD);
+ } while (timer_get_us() <= deadline &&
+ (reg_val & PROC_CMD_NCOMPLETED) &&
+ !(reg_val & PROC_CMD_FAILED));
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ if (reg_val & PROC_CMD_FAILED)
+ return -EIO;
+ if (reg_val & PROC_CMD_NCOMPLETED)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int vsc8584_micro_deassert_reset(struct mii_dev *bus, int phy,
+ bool patch_en)
+{
+ u32 enable, release;
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
+ release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
+ MICRO_CLK_EN;
+
+ if (patch_en) {
+ enable |= MICRO_PATCH_EN;
+ release |= MICRO_PATCH_EN;
+
+ /* Clear all patches */
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
+ READ_RAM);
+ }
+
+ /*
+ * Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
+ * override and addr. auto-incr; operate at 125 MHz
+ */
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, enable);
+ /* Release 8051 Micro SW reset */
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, release);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return 0;
+}
+
+static int vsc8584_micro_assert_reset(struct mii_dev *bus, int phy)
+{
+ int ret;
+ u16 reg;
+
+ ret = vsc8584_cmd(bus, phy, PROC_CMD_NOP);
+ if (ret)
+ return ret;
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
+ reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(4), 0x005b);
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(4), 0x005b);
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
+ reg |= EN_PATCH_RAM_TRAP_ADDR(4);
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
+ reg &= ~MICRO_NSOFT_RESET;
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, reg);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
+ PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_SGMII_PORT(0) |
+ PROC_CMD_NO_MAC_CONF | PROC_CMD_READ);
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
+ reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return 0;
+}
+
+static const u8 fw_patch_vsc8574[] = {
+ 0x46, 0x4a, 0x02, 0x43, 0x37, 0x02, 0x46, 0x26, 0x02, 0x46, 0x77, 0x02,
+ 0x45, 0x60, 0x02, 0x45, 0xaf, 0xed, 0xff, 0xe5, 0xfc, 0x54, 0x38, 0x64,
+ 0x20, 0x70, 0x08, 0x65, 0xff, 0x70, 0x04, 0xed, 0x44, 0x80, 0xff, 0x22,
+ 0x8f, 0x19, 0x7b, 0xbb, 0x7d, 0x0e, 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0xef,
+ 0x4e, 0x60, 0x03, 0x02, 0x41, 0xf9, 0xe4, 0xf5, 0x1a, 0x74, 0x01, 0x7e,
+ 0x00, 0xa8, 0x1a, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8,
+ 0xf9, 0xff, 0xef, 0x55, 0x19, 0x70, 0x03, 0x02, 0x41, 0xed, 0x85, 0x1a,
+ 0xfb, 0x7b, 0xbb, 0xe4, 0xfd, 0xff, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
+ 0x03, 0x02, 0x41, 0xed, 0xe5, 0x1a, 0x54, 0x02, 0x75, 0x1d, 0x00, 0x25,
+ 0xe0, 0x25, 0xe0, 0xf5, 0x1c, 0xe4, 0x78, 0xc5, 0xf6, 0xd2, 0x0a, 0x12,
+ 0x41, 0xfa, 0x7b, 0xff, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef,
+ 0x4e, 0x60, 0x03, 0x02, 0x41, 0xe7, 0xc2, 0x0a, 0x74, 0xc7, 0x25, 0x1a,
+ 0xf9, 0x74, 0xe7, 0x25, 0x1a, 0xf8, 0xe6, 0x27, 0xf5, 0x1b, 0xe5, 0x1d,
+ 0x24, 0x5b, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x7b, 0xfc, 0x7d, 0x11,
+ 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x78, 0xcc, 0xef, 0xf6, 0x78, 0xc1, 0xe6,
+ 0xfe, 0xef, 0xd3, 0x9e, 0x40, 0x06, 0x78, 0xcc, 0xe6, 0x78, 0xc1, 0xf6,
+ 0x12, 0x41, 0xfa, 0x7b, 0xec, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7,
+ 0x78, 0xcb, 0xef, 0xf6, 0xbf, 0x07, 0x06, 0x78, 0xc3, 0x76, 0x1a, 0x80,
+ 0x1f, 0x78, 0xc5, 0xe6, 0xff, 0x60, 0x0f, 0xc3, 0xe5, 0x1b, 0x9f, 0xff,
+ 0x78, 0xcb, 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x2f, 0x80, 0x07, 0x78, 0xcb,
+ 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x78, 0xc3, 0xf6, 0xe4, 0x78, 0xc2, 0xf6,
+ 0x78, 0xc2, 0xe6, 0xff, 0xc3, 0x08, 0x96, 0x40, 0x03, 0x02, 0x41, 0xd1,
+ 0xef, 0x54, 0x03, 0x60, 0x33, 0x14, 0x60, 0x46, 0x24, 0xfe, 0x60, 0x42,
+ 0x04, 0x70, 0x4b, 0xef, 0x24, 0x02, 0xff, 0xe4, 0x33, 0xfe, 0xef, 0x78,
+ 0x02, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0xff, 0xe5, 0x1d,
+ 0x24, 0x5c, 0xcd, 0xe5, 0x1c, 0x34, 0xf0, 0xcd, 0x2f, 0xff, 0xed, 0x3e,
+ 0xfe, 0x12, 0x46, 0x0d, 0x7d, 0x11, 0x80, 0x0b, 0x78, 0xc2, 0xe6, 0x70,
+ 0x04, 0x7d, 0x11, 0x80, 0x02, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3e, 0x9a,
+ 0x8e, 0x1e, 0x8f, 0x1f, 0x80, 0x03, 0xe5, 0x1e, 0xff, 0x78, 0xc5, 0xe6,
+ 0x06, 0x24, 0xcd, 0xf8, 0xa6, 0x07, 0x78, 0xc2, 0x06, 0xe6, 0xb4, 0x1a,
+ 0x0a, 0xe5, 0x1d, 0x24, 0x5c, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x78,
+ 0xc5, 0xe6, 0x65, 0x1b, 0x70, 0x82, 0x75, 0xdb, 0x20, 0x75, 0xdb, 0x28,
+ 0x12, 0x46, 0x02, 0x12, 0x46, 0x02, 0xe5, 0x1a, 0x12, 0x45, 0xf5, 0xe5,
+ 0x1a, 0xc3, 0x13, 0x12, 0x45, 0xf5, 0x78, 0xc5, 0x16, 0xe6, 0x24, 0xcd,
+ 0xf8, 0xe6, 0xff, 0x7e, 0x08, 0x1e, 0xef, 0xa8, 0x06, 0x08, 0x80, 0x02,
+ 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0xef,
+ 0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33,
+ 0x54, 0xe0, 0x44, 0x08, 0xf5, 0xdb, 0xee, 0x70, 0xd8, 0x78, 0xc5, 0xe6,
+ 0x70, 0xc8, 0x75, 0xdb, 0x10, 0x02, 0x40, 0xfd, 0x78, 0xc2, 0xe6, 0xc3,
+ 0x94, 0x17, 0x50, 0x0e, 0xe5, 0x1d, 0x24, 0x62, 0x12, 0x42, 0x08, 0xe5,
+ 0x1d, 0x24, 0x5c, 0x12, 0x42, 0x08, 0x20, 0x0a, 0x03, 0x02, 0x40, 0x76,
+ 0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x02, 0x40, 0x3a,
+ 0x22, 0xe5, 0x1d, 0x24, 0x5c, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12,
+ 0x46, 0x0d, 0x22, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12, 0x46, 0x0d,
+ 0x22, 0xe4, 0xf5, 0x19, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x1e, 0x7b, 0xfe,
+ 0x12, 0x42, 0xf9, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0, 0x07,
+ 0x7b, 0x54, 0x12, 0x42, 0xf9, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a, 0x25,
+ 0x19, 0xf8, 0xa6, 0x07, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x03, 0x02, 0x42,
+ 0xdf, 0x54, 0x03, 0x64, 0x03, 0x70, 0x03, 0x02, 0x42, 0xcf, 0x7b, 0xcb,
+ 0x12, 0x43, 0x2c, 0x8f, 0xfb, 0x7b, 0x30, 0x7d, 0x03, 0xe4, 0xff, 0x12,
+ 0x3d, 0xd7, 0xc3, 0xef, 0x94, 0x02, 0xee, 0x94, 0x00, 0x50, 0x2a, 0x12,
+ 0x42, 0xec, 0xef, 0x4e, 0x70, 0x23, 0x12, 0x43, 0x04, 0x60, 0x0a, 0x12,
+ 0x43, 0x12, 0x70, 0x0c, 0x12, 0x43, 0x1f, 0x70, 0x07, 0x12, 0x46, 0x39,
+ 0x7b, 0x03, 0x80, 0x07, 0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0xfb, 0x7a,
+ 0x00, 0x7d, 0x54, 0x80, 0x3e, 0x12, 0x42, 0xec, 0xef, 0x4e, 0x70, 0x24,
+ 0x12, 0x43, 0x04, 0x60, 0x0a, 0x12, 0x43, 0x12, 0x70, 0x0f, 0x12, 0x43,
+ 0x1f, 0x70, 0x0a, 0x12, 0x46, 0x39, 0xe4, 0xfb, 0xfa, 0x7d, 0xee, 0x80,
+ 0x1e, 0x12, 0x46, 0x39, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x80, 0x13,
+ 0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0x54, 0x40, 0xfe, 0xc4, 0x13, 0x13,
+ 0x54, 0x03, 0xfb, 0x7a, 0x00, 0x7d, 0xee, 0x12, 0x38, 0xbd, 0x7b, 0xff,
+ 0x12, 0x43, 0x2c, 0xef, 0x4e, 0x70, 0x07, 0x74, 0x2a, 0x25, 0x19, 0xf8,
+ 0xe4, 0xf6, 0x05, 0x19, 0xe5, 0x19, 0xc3, 0x94, 0x02, 0x50, 0x03, 0x02,
+ 0x42, 0x15, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7b, 0x20, 0x7f, 0x04,
+ 0x12, 0x3d, 0xd7, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12,
+ 0x3d, 0xd7, 0x22, 0x7b, 0x22, 0x7d, 0x18, 0x7f, 0x06, 0x12, 0x3d, 0xd7,
+ 0xef, 0x64, 0x01, 0x4e, 0x22, 0x7d, 0x1c, 0xe4, 0xff, 0x12, 0x3e, 0x9a,
+ 0xef, 0x54, 0x1b, 0x64, 0x0a, 0x22, 0x7b, 0xcc, 0x7d, 0x10, 0xff, 0x12,
+ 0x3d, 0xd7, 0xef, 0x64, 0x01, 0x4e, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd,
+ 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0x22, 0xd2, 0x08, 0x75, 0xfb, 0x03, 0xab,
+ 0x7e, 0xaa, 0x7d, 0x7d, 0x19, 0x7f, 0x03, 0x12, 0x3e, 0xda, 0xe5, 0x7e,
+ 0x54, 0x0f, 0x24, 0xf3, 0x60, 0x03, 0x02, 0x43, 0xe9, 0x12, 0x46, 0x5a,
+ 0x12, 0x46, 0x61, 0xd8, 0xfb, 0xff, 0x20, 0xe2, 0x35, 0x13, 0x92, 0x0c,
+ 0xef, 0xa2, 0xe1, 0x92, 0x0b, 0x30, 0x0c, 0x2a, 0xe4, 0xf5, 0x10, 0x7b,
+ 0xfe, 0x12, 0x43, 0xff, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0,
+ 0x07, 0x7b, 0x54, 0x12, 0x43, 0xff, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a,
+ 0x25, 0x10, 0xf8, 0xa6, 0x07, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94, 0x02,
+ 0x40, 0xd9, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb, 0x54, 0x05,
+ 0x64, 0x04, 0x70, 0x27, 0x78, 0xc4, 0xe6, 0x78, 0xc6, 0xf6, 0xe5, 0x7d,
+ 0xff, 0x33, 0x95, 0xe0, 0xef, 0x54, 0x0f, 0x78, 0xc4, 0xf6, 0x12, 0x44,
+ 0x0a, 0x20, 0x0c, 0x0c, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb,
+ 0x13, 0x92, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0x12, 0x46, 0x5a, 0x12, 0x46,
+ 0x61, 0xd8, 0xfb, 0x54, 0x05, 0x64, 0x05, 0x70, 0x1e, 0x78, 0xc4, 0x7d,
+ 0xb8, 0x12, 0x43, 0xf5, 0x78, 0xc1, 0x7d, 0x74, 0x12, 0x43, 0xf5, 0xe4,
+ 0x78, 0xc1, 0xf6, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f, 0x92,
+ 0x12, 0x38, 0xbd, 0x22, 0xe6, 0xfb, 0x7a, 0x00, 0x7f, 0x92, 0x12, 0x38,
+ 0xbd, 0x22, 0xe5, 0x10, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12, 0x3d, 0xd7,
+ 0x22, 0x78, 0xc1, 0xe6, 0xfb, 0x7a, 0x00, 0x7d, 0x74, 0x7f, 0x92, 0x12,
+ 0x38, 0xbd, 0xe4, 0x78, 0xc1, 0xf6, 0xf5, 0x11, 0x74, 0x01, 0x7e, 0x00,
+ 0xa8, 0x11, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9,
+ 0xff, 0x78, 0xc4, 0xe6, 0xfd, 0xef, 0x5d, 0x60, 0x44, 0x85, 0x11, 0xfb,
+ 0xe5, 0x11, 0x54, 0x02, 0x25, 0xe0, 0x25, 0xe0, 0xfe, 0xe4, 0x24, 0x5b,
+ 0xfb, 0xee, 0x12, 0x45, 0xed, 0x12, 0x3e, 0xda, 0x7b, 0x40, 0x7d, 0x11,
+ 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x74, 0xc7, 0x25, 0x11, 0xf8, 0xa6, 0x07,
+ 0x7b, 0x11, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
+ 0x09, 0x74, 0xe7, 0x25, 0x11, 0xf8, 0x76, 0x04, 0x80, 0x07, 0x74, 0xe7,
+ 0x25, 0x11, 0xf8, 0x76, 0x0a, 0x05, 0x11, 0xe5, 0x11, 0xc3, 0x94, 0x04,
+ 0x40, 0x9a, 0x78, 0xc6, 0xe6, 0x70, 0x15, 0x78, 0xc4, 0xe6, 0x60, 0x10,
+ 0x75, 0xd9, 0x38, 0x75, 0xdb, 0x10, 0x7d, 0xfe, 0x12, 0x44, 0xb8, 0x7d,
+ 0x76, 0x12, 0x44, 0xb8, 0x79, 0xc6, 0xe7, 0x78, 0xc4, 0x66, 0xff, 0x60,
+ 0x03, 0x12, 0x40, 0x25, 0x78, 0xc4, 0xe6, 0x70, 0x09, 0xfb, 0xfa, 0x7d,
+ 0xfe, 0x7f, 0x8e, 0x12, 0x38, 0xbd, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7f,
+ 0x8e, 0x12, 0x38, 0xbd, 0x22, 0xe4, 0xf5, 0xfb, 0x7d, 0x1c, 0xe4, 0xff,
+ 0x12, 0x3e, 0x9a, 0xad, 0x07, 0xac, 0x06, 0xec, 0x54, 0xc0, 0xff, 0xed,
+ 0x54, 0x3f, 0x4f, 0xf5, 0x20, 0x30, 0x06, 0x2c, 0x30, 0x01, 0x08, 0xa2,
+ 0x04, 0x72, 0x03, 0x92, 0x07, 0x80, 0x21, 0x30, 0x04, 0x06, 0x7b, 0xcc,
+ 0x7d, 0x11, 0x80, 0x0d, 0x30, 0x03, 0x06, 0x7b, 0xcc, 0x7d, 0x10, 0x80,
+ 0x04, 0x7b, 0x66, 0x7d, 0x16, 0xe4, 0xff, 0x12, 0x3d, 0xd7, 0xee, 0x4f,
+ 0x24, 0xff, 0x92, 0x07, 0xaf, 0xfb, 0x74, 0x26, 0x2f, 0xf8, 0xe6, 0xff,
+ 0xa6, 0x20, 0x20, 0x07, 0x39, 0x8f, 0x20, 0x30, 0x07, 0x34, 0x30, 0x00,
+ 0x31, 0x20, 0x04, 0x2e, 0x20, 0x03, 0x2b, 0xe4, 0xf5, 0xff, 0x75, 0xfc,
+ 0xc2, 0xe5, 0xfc, 0x30, 0xe0, 0xfb, 0xaf, 0xfe, 0xef, 0x20, 0xe3, 0x1a,
+ 0xae, 0xfd, 0x44, 0x08, 0xf5, 0xfe, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
+ 0xe0, 0xfb, 0x8f, 0xfe, 0x8e, 0xfd, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
+ 0xe0, 0xfb, 0x05, 0xfb, 0xaf, 0xfb, 0xef, 0xc3, 0x94, 0x04, 0x50, 0x03,
+ 0x02, 0x44, 0xc5, 0xe4, 0xf5, 0xfb, 0x22, 0xe5, 0x7e, 0x54, 0x0f, 0x64,
+ 0x01, 0x70, 0x23, 0xe5, 0x7e, 0x30, 0xe4, 0x1e, 0x90, 0x47, 0xd0, 0xe0,
+ 0x44, 0x02, 0xf0, 0x54, 0xfb, 0xf0, 0x90, 0x47, 0xd4, 0xe0, 0x44, 0x04,
+ 0xf0, 0x7b, 0x03, 0x7d, 0x5b, 0x7f, 0x5d, 0x12, 0x36, 0x29, 0x7b, 0x0e,
+ 0x80, 0x1c, 0x90, 0x47, 0xd0, 0xe0, 0x54, 0xfd, 0xf0, 0x44, 0x04, 0xf0,
+ 0x90, 0x47, 0xd4, 0xe0, 0x54, 0xfb, 0xf0, 0x7b, 0x02, 0x7d, 0x5b, 0x7f,
+ 0x5d, 0x12, 0x36, 0x29, 0x7b, 0x06, 0x7d, 0x60, 0x7f, 0x63, 0x12, 0x36,
+ 0x29, 0x22, 0xe5, 0x7e, 0x30, 0xe5, 0x35, 0x30, 0xe4, 0x0b, 0x7b, 0x02,
+ 0x7d, 0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x80, 0x10, 0x7b, 0x01, 0x7d,
+ 0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x90, 0x47, 0xd2, 0xe0, 0x44, 0x04,
+ 0xf0, 0x90, 0x47, 0xd2, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x47, 0xd1, 0xe0,
+ 0x44, 0x10, 0xf0, 0x7b, 0x05, 0x7d, 0x84, 0x7f, 0x86, 0x12, 0x36, 0x29,
+ 0x22, 0xfb, 0xe5, 0x1c, 0x34, 0xf0, 0xfa, 0x7d, 0x10, 0x7f, 0x07, 0x22,
+ 0x54, 0x01, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0x44, 0x08, 0xf5, 0xdb,
+ 0x22, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0x22,
+ 0xab, 0x07, 0xaa, 0x06, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3e, 0xda, 0x7b,
+ 0xff, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60, 0xf3,
+ 0x22, 0x12, 0x44, 0xc2, 0x30, 0x0c, 0x03, 0x12, 0x42, 0x12, 0x78, 0xc4,
+ 0xe6, 0xff, 0x60, 0x03, 0x12, 0x40, 0x25, 0x22, 0xe5, 0x19, 0x24, 0x17,
+ 0x54, 0x1f, 0x44, 0x80, 0xff, 0x22, 0x74, 0x2a, 0x25, 0x19, 0xf8, 0xe6,
+ 0x22, 0x12, 0x46, 0x72, 0x12, 0x46, 0x68, 0x90, 0x47, 0xfa, 0xe0, 0x54,
+ 0xf8, 0x44, 0x02, 0xf0, 0x22, 0xe5, 0x7e, 0xae, 0x7d, 0x78, 0x04, 0x22,
+ 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0x22, 0xe4, 0x78, 0xc4, 0xf6, 0xc2,
+ 0x0d, 0x78, 0xc1, 0xf6, 0x22, 0xc2, 0x0c, 0xc2, 0x0b, 0x22, 0x22,
+};
+
+static const u8 fw_patch_vsc8584[] = {
+ 0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02,
+ 0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60,
+ 0x27, 0x24, 0xfc, 0x60, 0x23, 0x24, 0x08, 0x70, 0x14, 0xe5, 0x69, 0xae,
+ 0x68, 0x78, 0x04, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0x7e,
+ 0x00, 0x54, 0x0f, 0x80, 0x00, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f,
+ 0x92, 0x12, 0x50, 0xee, 0x22, 0xe4, 0xf5, 0x10, 0x85, 0x10, 0xfb, 0x7d,
+ 0x1c, 0xe4, 0xff, 0x12, 0x59, 0xea, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94,
+ 0x04, 0x40, 0xed, 0x22, 0x22, 0x22, 0x22, 0x22,
+};
+
+static int vsc8584_get_fw_crc(struct mii_dev *bus, int phy, u16 start,
+ u16 *crc, const u8 *fw_patch, int fw_size)
+{
+ int ret;
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT1);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2, start);
+ /* Add one byte to size for the one added by the patch_fw function */
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_3,
+ fw_size + 1);
+
+ ret = vsc8584_cmd(bus, phy, PROC_CMD_CRC16);
+ if (ret)
+ goto out;
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT1);
+
+ *crc = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2);
+
+out:
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return ret;
+}
+
+static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch,
+ int fw_size)
+{
+ int i, ret;
+
+ ret = vsc8584_micro_assert_reset(bus, phy);
+ if (ret) {
+ pr_err("%s: failed to assert reset of micro\n", __func__);
+ return ret;
+ }
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ /*
+ * Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
+ * Disable the 8051 Micro clock
+ */
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS,
+ RUN_FROM_INT_ROM | AUTOINC_ADDR | PATCH_RAM_CLK |
+ MICRO_CLK_EN | MICRO_CLK_DIVIDE(2));
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_PRAM |
+ INT_MEM_WRITE_EN | INT_MEM_DATA(2));
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_ADDR, 0x0000);
+
+ for (i = 0; i < fw_size; i++)
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
+ READ_PRAM | INT_MEM_WRITE_EN | fw_patch[i]);
+
+ /* Clear internal memory access */
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_RAM);
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return 0;
+}
+
+static bool vsc8574_is_serdes_init(struct mii_dev *bus, int phy)
+{
+ u16 reg;
+ bool ret;
+
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1));
+ if (reg != MSCC_TRAP_ROM_ADDR_SERDES_INIT) {
+ ret = false;
+ goto out;
+ }
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1));
+ if (reg != MSCC_PATCH_RAM_ADDR_SERDES_INIT) {
+ ret = false;
+ goto out;
+ }
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
+ if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
+ ret = false;
+ goto out;
+ }
+
+ reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
+ if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
+ MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
+ ret = false;
+ goto out;
+ }
+
+ ret = true;
+
+out:
+ bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ return ret;
+}
+
+static int vsc8574_config_pre_init(struct phy_device *phydev)
+{
+ struct mii_dev *bus = phydev->bus;
+ u16 crc, reg, phy0, addr;
+ bool serdes_init;
+ int ret;
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT1);
+ addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
+ addr >>= PHY_CNTL_4_ADDR_POS;
+
+ reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
+ if (reg & PHY_ADDR_REVERSED)
+ phy0 = phydev->addr + addr;
+ else
+ phy0 = phydev->addr - addr;
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ /* all writes below are broadcasted to all PHYs in the same package */
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
+ reg |= SMI_BROADCAST_WR_EN;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+ /*
+ * The below register writes are tweaking analog and electrical
+ * configuration that were determined through characterization by PHY
+ * engineers. These don't mean anything more than "these are the best
+ * values".
+ */
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TEST);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_20, 0x4320);
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_24, 0x0c00);
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_9, 0x18ca);
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1b20);
+
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
+ reg |= TR_CLK_DISABLE;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TR);
+
+ vsc8584_csr_write(bus, phy0, 0x0fae, 0x000401bd);
+ vsc8584_csr_write(bus, phy0, 0x0fac, 0x000f000f);
+ vsc8584_csr_write(bus, phy0, 0x17a0, 0x00a0f147);
+ vsc8584_csr_write(bus, phy0, 0x0fe4, 0x00052f54);
+ vsc8584_csr_write(bus, phy0, 0x1792, 0x0027303d);
+ vsc8584_csr_write(bus, phy0, 0x07fe, 0x00000704);
+ vsc8584_csr_write(bus, phy0, 0x0fe0, 0x00060150);
+ vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b00a);
+ vsc8584_csr_write(bus, phy0, 0x0f80, 0x00000d74);
+ vsc8584_csr_write(bus, phy0, 0x02e0, 0x00000012);
+ vsc8584_csr_write(bus, phy0, 0x03a2, 0x00050208);
+ vsc8584_csr_write(bus, phy0, 0x03b2, 0x00009186);
+ vsc8584_csr_write(bus, phy0, 0x0fb0, 0x000e3700);
+ vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
+ vsc8584_csr_write(bus, phy0, 0x0fd2, 0x0000ffff);
+ vsc8584_csr_write(bus, phy0, 0x168a, 0x00039fa2);
+ vsc8584_csr_write(bus, phy0, 0x1690, 0x0020640b);
+ vsc8584_csr_write(bus, phy0, 0x0258, 0x00002220);
+ vsc8584_csr_write(bus, phy0, 0x025a, 0x00002a20);
+ vsc8584_csr_write(bus, phy0, 0x025c, 0x00003060);
+ vsc8584_csr_write(bus, phy0, 0x025e, 0x00003fa0);
+ vsc8584_csr_write(bus, phy0, 0x03a6, 0x0000e0f0);
+ vsc8584_csr_write(bus, phy0, 0x0f92, 0x00001489);
+ vsc8584_csr_write(bus, phy0, 0x16a2, 0x00007000);
+ vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
+ vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
+ vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
+ vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
+ vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
+ vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
+ vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
+ vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
+ vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
+ vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
+ vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
+ vsc8584_csr_write(bus, phy0, 0x0796, 0x00000003);
+ vsc8584_csr_write(bus, phy0, 0x07f8, 0x00c3ff98);
+ vsc8584_csr_write(bus, phy0, 0x0fa4, 0x0018292a);
+ vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
+ vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
+ vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
+ vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
+ vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
+ vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901c09);
+ vsc8584_csr_write(bus, phy0, 0x0fee, 0x0004a6a1);
+ vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01807);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT2);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TR);
+
+ vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
+ vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
+ vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
+ vsc8584_csr_write(bus, phy0, 0x048e, 0x00000db6);
+ vsc8584_csr_write(bus, phy0, 0x049c, 0x00596596);
+ vsc8584_csr_write(bus, phy0, 0x049e, 0x00000514);
+ vsc8584_csr_write(bus, phy0, 0x04a2, 0x00410280);
+ vsc8584_csr_write(bus, phy0, 0x04a4, 0x00000000);
+ vsc8584_csr_write(bus, phy0, 0x04a6, 0x00000000);
+ vsc8584_csr_write(bus, phy0, 0x04a8, 0x00000000);
+ vsc8584_csr_write(bus, phy0, 0x04aa, 0x00000000);
+ vsc8584_csr_write(bus, phy0, 0x04ae, 0x007df7dd);
+ vsc8584_csr_write(bus, phy0, 0x04b0, 0x006d95d4);
+ vsc8584_csr_write(bus, phy0, 0x04b2, 0x00492410);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TEST);
+
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
+ reg &= ~TR_CLK_DISABLE;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ /* end of write broadcasting */
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
+ reg &= ~SMI_BROADCAST_WR_EN;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+ ret = vsc8584_get_fw_crc(bus, phy0,
+ MSCC_VSC8574_REVB_INT8051_FW_START_ADDR, &crc,
+ fw_patch_vsc8574,
+ ARRAY_SIZE(fw_patch_vsc8574));
+ if (ret)
+ goto out;
+
+ if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
+ serdes_init = vsc8574_is_serdes_init(bus, phy0);
+
+ if (!serdes_init) {
+ ret = vsc8584_micro_assert_reset(bus, phy0);
+ if (ret) {
+ pr_err("failed to assert reset of micro\n");
+ return ret;
+ }
+ }
+ } else {
+ pr_debug("FW CRC is not the expected one, patching FW\n");
+
+ serdes_init = false;
+
+ if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8574,
+ ARRAY_SIZE(fw_patch_vsc8574)))
+ pr_warn("failed to patch FW, expect non-optimal device\n");
+ }
+
+ if (!serdes_init) {
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1),
+ MSCC_TRAP_ROM_ADDR_SERDES_INIT);
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1),
+ MSCC_PATCH_RAM_ADDR_SERDES_INIT);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
+ EN_PATCH_RAM_TRAP_ADDR(1));
+
+ vsc8584_micro_deassert_reset(bus, phy0, false);
+
+ ret = vsc8584_get_fw_crc(bus, phy0,
+ MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
+ &crc, fw_patch_vsc8574,
+ ARRAY_SIZE(fw_patch_vsc8574));
+ if (ret)
+ goto out;
+
+ if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
+ pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
+ }
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ ret = vsc8584_cmd(bus, phy0, PROC_CMD_1588_DEFAULT_INIT |
+ PROC_CMD_PHY_INIT);
+
+out:
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return ret;
+}
+
+static int vsc8584_config_pre_init(struct phy_device *phydev)
+{
+ struct mii_dev *bus = phydev->bus;
+ u16 reg, crc, phy0, addr;
+ int ret;
+
+ if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
+ pr_warn("VSC8584 revA not officially supported, skipping firmware patching. Use at your own risk.\n");
+ return 0;
+ }
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT1);
+ addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
+ addr >>= PHY_CNTL_4_ADDR_POS;
+
+ reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
+ if (reg & PHY_ADDR_REVERSED)
+ phy0 = phydev->addr + addr;
+ else
+ phy0 = phydev->addr - addr;
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ /* all writes below are broadcasted to all PHYs in the same package */
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
+ reg |= SMI_BROADCAST_WR_EN;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+ /*
+ * The below register writes are tweaking analog and electrical
+ * configuration that were determined through characterization by PHY
+ * engineers. These don't mean anything more than "these are the best
+ * values".
+ */
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL);
+ reg |= PARALLEL_DET_IGNORE_ADVERTISED;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL, reg);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT3);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
+ 0x2000);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TEST);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1f20);
+
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
+ reg |= TR_CLK_DISABLE;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TR);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xafa4);
+
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
+ reg &= ~0x007f;
+ reg |= 0x0019;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x8fa4);
+
+ vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
+ vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
+ vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
+ vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
+ vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
+ vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b002);
+ vsc8584_csr_write(bus, phy0, 0x1686, 0x00000004);
+ vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
+ vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
+ vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
+ vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
+ vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
+ vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
+ vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
+ vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
+ vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
+ vsc8584_csr_write(bus, phy0, 0x0f80, 0x00fffaff);
+ vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901809);
+ vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01007);
+ vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
+ vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
+ vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT2);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TR);
+
+ vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
+ vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
+ vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_TEST);
+
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
+ reg &= ~TR_CLK_DISABLE;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
+
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ /* end of write broadcasting */
+ reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
+ reg &= ~SMI_BROADCAST_WR_EN;
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+ ret = vsc8584_get_fw_crc(bus, phy0,
+ MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
+ fw_patch_vsc8584,
+ ARRAY_SIZE(fw_patch_vsc8584));
+ if (ret)
+ goto out;
+
+ if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
+ debug("FW CRC is not the expected one, patching FW...\n");
+ if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8584,
+ ARRAY_SIZE(fw_patch_vsc8584)))
+ pr_warn("failed to patch FW, expect non-optimal device\n");
+ }
+
+ vsc8584_micro_deassert_reset(bus, phy0, false);
+
+ ret = vsc8584_get_fw_crc(bus, phy0,
+ MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
+ fw_patch_vsc8584,
+ ARRAY_SIZE(fw_patch_vsc8584));
+ if (ret)
+ goto out;
+
+ if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
+ pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
+
+ ret = vsc8584_micro_assert_reset(bus, phy0);
+ if (ret)
+ goto out;
+
+ vsc8584_micro_deassert_reset(bus, phy0, true);
+
+out:
+ bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return ret;
+}
static int mscc_vsc8531_vsc8541_init_scripts(struct phy_device *phydev)
{
@@ -457,6 +1328,108 @@ static int vsc8541_config(struct phy_device *phydev)
return genphy_config_aneg(phydev);
}
+static int vsc8584_config_init(struct phy_device *phydev)
+{
+ struct vsc85xx_priv *priv = phydev->priv;
+ int ret;
+ u16 addr;
+ u16 reg_val;
+ u16 val;
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT1);
+ addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
+ addr >>= PHY_CNTL_4_ADDR_POS;
+
+ ret = priv->config_pre(phydev);
+ if (ret)
+ return ret;
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
+ val = MAC_CFG_QSGMII;
+ else
+ val = MAC_CFG_SGMII;
+
+ reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK);
+ reg_val &= ~MAC_CFG_MASK;
+ reg_val |= val;
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK,
+ reg_val);
+ if (ret)
+ return ret;
+
+ reg_val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
+ PROC_CMD_READ_MOD_WRITE_PORT;
+ if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
+ reg_val |= PROC_CMD_QSGMII_MAC;
+ else
+ reg_val |= PROC_CMD_SGMII_MAC;
+
+ ret = vsc8584_cmd(phydev->bus, phydev->addr, reg_val);
+ if (ret)
+ return ret;
+
+ mdelay(10);
+
+ /* Disable SerDes for 100Base-FX */
+ ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
+ PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
+ PROC_CMD_READ_MOD_WRITE_PORT |
+ PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
+ if (ret)
+ return ret;
+
+ /* Disable SerDes for 1000Base-X */
+ ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
+ PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
+ PROC_CMD_READ_MOD_WRITE_PORT |
+ PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
+ if (ret)
+ return ret;
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+ reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
+ MSCC_PHY_EXT_PHY_CNTL_1_REG);
+ reg_val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
+ reg_val |= MEDIA_OP_MODE_COPPER |
+ (VSC8584_MAC_IF_SELECTION_SGMII <<
+ VSC8584_MAC_IF_SELECTION_POS);
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1_REG,
+ reg_val);
+
+ ret = mscc_phy_soft_reset(phydev);
+ if (ret != 0)
+ return ret;
+
+ return genphy_config(phydev);
+}
+
+static struct vsc85xx_priv vsc8574_priv = {
+ .config_pre = vsc8574_config_pre_init,
+};
+
+static int vsc8574_config(struct phy_device *phydev)
+{
+ phydev->priv = &vsc8574_priv;
+
+ return vsc8584_config_init(phydev);
+}
+
+static struct vsc85xx_priv vsc8584_priv = {
+ .config_pre = vsc8584_config_pre_init,
+};
+
+static int vsc8584_config(struct phy_device *phydev)
+{
+ phydev->priv = &vsc8584_priv;
+
+ return vsc8584_config_init(phydev);
+}
+
static struct phy_driver VSC8530_driver = {
.name = "Microsemi VSC8530",
.uid = PHY_ID_VSC8530,
@@ -497,12 +1470,34 @@ static struct phy_driver VSC8541_driver = {
.shutdown = &genphy_shutdown,
};
+static struct phy_driver VSC8574_driver = {
+ .name = "Microsemi VSC8574",
+ .uid = PHY_ID_VSC8574,
+ .mask = 0x000ffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &vsc8574_config,
+ .startup = &mscc_startup,
+ .shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8584_driver = {
+ .name = "Microsemi VSC8584",
+ .uid = PHY_ID_VSC8584,
+ .mask = 0x000ffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &vsc8584_config,
+ .startup = &mscc_startup,
+ .shutdown = &genphy_shutdown,
+};
+
int phy_mscc_init(void)
{
phy_register(&VSC8530_driver);
phy_register(&VSC8531_driver);
phy_register(&VSC8540_driver);
phy_register(&VSC8541_driver);
+ phy_register(&VSC8574_driver);
+ phy_register(&VSC8584_driver);
return 0;
}
diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
new file mode 100644
index 0000000..82bc9f5
--- /dev/null
+++ b/drivers/net/ti/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+
+config DRIVER_TI_CPSW
+ bool "TI Common Platform Ethernet Switch"
+ select PHYLIB
+ help
+ This driver supports the TI three port switch gigabit ethernet
+ subsystem found in the TI SoCs.
+
+config DRIVER_TI_EMAC
+ bool "TI Davinci EMAC"
+ help
+ Support for davinci emac
+
+config DRIVER_TI_KEYSTONE_NET
+ bool "TI Keystone 2 Ethernet"
+ help
+ This driver supports the TI Keystone 2 Ethernet subsystem
diff --git a/drivers/net/ti/Makefile b/drivers/net/ti/Makefile
new file mode 100644
index 0000000..ee3e4eb
--- /dev/null
+++ b/drivers/net/ti/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+
+obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o cpsw-common.o cpsw_mdio.o
+obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
+obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o cpsw_mdio.o
diff --git a/drivers/net/cpsw-common.c b/drivers/net/ti/cpsw-common.c
index 6c8ddbd..6c8ddbd 100644
--- a/drivers/net/cpsw-common.c
+++ b/drivers/net/ti/cpsw-common.c
diff --git a/drivers/net/cpsw.c b/drivers/net/ti/cpsw.c
index 8e2a48c..f5fd02e 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/ti/cpsw.c
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* CPSW Ethernet Switch Driver
*
- * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Copyright (C) 2010-2018 Texas Instruments Incorporated - http://www.ti.com/
*/
#include <common.h>
@@ -29,11 +21,11 @@
#include <dm.h>
#include <fdt_support.h>
+#include "cpsw_mdio.h"
+
DECLARE_GLOBAL_DATA_PTR;
#define BITMASK(bits) (BIT(bits) - 1)
-#define PHY_REG_MASK 0x1f
-#define PHY_ID_MASK 0x1f
#define NUM_DESCS (PKTBUFSRX * 2)
#define PKT_MIN 60
#define PKT_MAX (1500 + 14 + 4 + 4)
@@ -84,37 +76,8 @@ DECLARE_GLOBAL_DATA_PTR;
* unexpected controller lock ups. Ideally, we should never ever hit this
* scenario in practice.
*/
-#define MDIO_TIMEOUT 100 /* msecs */
#define CPDMA_TIMEOUT 100 /* msecs */
-struct cpsw_mdio_regs {
- u32 version;
- u32 control;
-#define CONTROL_IDLE BIT(31)
-#define CONTROL_ENABLE BIT(30)
-
- u32 alive;
- u32 link;
- u32 linkintraw;
- u32 linkintmasked;
- u32 __reserved_0[2];
- u32 userintraw;
- u32 userintmasked;
- u32 userintmaskset;
- u32 userintmaskclr;
- u32 __reserved_1[20];
-
- struct {
- u32 access;
- u32 physel;
-#define USERACCESS_GO BIT(31)
-#define USERACCESS_WRITE BIT(30)
-#define USERACCESS_ACK BIT(29)
-#define USERACCESS_READ (0)
-#define USERACCESS_DATA (0xffff)
- } user[0];
-};
-
struct cpsw_regs {
u32 id_ver;
u32 control;
@@ -492,100 +455,6 @@ static inline void cpsw_ale_port_state(struct cpsw_priv *priv, int port,
__raw_writel(tmp, priv->ale_regs + offset);
}
-static struct cpsw_mdio_regs *mdio_regs;
-
-/* wait until hardware is ready for another user access */
-static inline u32 wait_for_user_access(void)
-{
- u32 reg = 0;
- int timeout = MDIO_TIMEOUT;
-
- while (timeout-- &&
- ((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO))
- udelay(10);
-
- if (timeout == -1) {
- printf("wait_for_user_access Timeout\n");
- return -ETIMEDOUT;
- }
- return reg;
-}
-
-/* wait until hardware state machine is idle */
-static inline void wait_for_idle(void)
-{
- int timeout = MDIO_TIMEOUT;
-
- while (timeout-- &&
- ((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0))
- udelay(10);
-
- if (timeout == -1)
- printf("wait_for_idle Timeout\n");
-}
-
-static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
- int dev_addr, int phy_reg)
-{
- int data;
- u32 reg;
-
- if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
- return -EINVAL;
-
- wait_for_user_access();
- reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
- (phy_id << 16));
- __raw_writel(reg, &mdio_regs->user[0].access);
- reg = wait_for_user_access();
-
- data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
- return data;
-}
-
-static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
- int phy_reg, u16 data)
-{
- u32 reg;
-
- if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
- return -EINVAL;
-
- wait_for_user_access();
- reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
- (phy_id << 16) | (data & USERACCESS_DATA));
- __raw_writel(reg, &mdio_regs->user[0].access);
- wait_for_user_access();
-
- return 0;
-}
-
-static void cpsw_mdio_init(const char *name, u32 mdio_base, u32 div)
-{
- struct mii_dev *bus = mdio_alloc();
-
- mdio_regs = (struct cpsw_mdio_regs *)mdio_base;
-
- /* set enable and clock divider */
- __raw_writel(div | CONTROL_ENABLE, &mdio_regs->control);
-
- /*
- * wait for scan logic to settle:
- * the scan time consists of (a) a large fixed component, and (b) a
- * small component that varies with the mii bus frequency. These
- * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
- * silicon. Since the effect of (b) was found to be largely
- * negligible, we keep things simple here.
- */
- udelay(1000);
-
- bus->read = cpsw_mdio_read;
- bus->write = cpsw_mdio_write;
- strcpy(bus->name, name);
-
- mdio_register(bus);
-}
-
/* Set a self-clearing bit in a register, and wait for it to clear */
static inline void setbit_and_wait_for_clear32(void *addr)
{
@@ -1011,7 +880,7 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
static void cpsw_phy_addr_update(struct cpsw_priv *priv)
{
struct cpsw_platform_data *data = &priv->data;
- u16 alive = mdio_regs->alive & GENMASK(15, 0);
+ u16 alive = cpsw_mdio_get_alive(priv->bus);
int active = data->active_slave;
int new_addr = ffs(alive) - 1;
@@ -1052,11 +921,12 @@ int _cpsw_register(struct cpsw_priv *priv)
idx = idx + 1;
}
- cpsw_mdio_init(priv->dev->name, data->mdio_base, data->mdio_div);
+ priv->bus = cpsw_mdio_init(priv->dev->name, data->mdio_base, 0, 0);
+ if (!priv->bus)
+ return -EFAULT;
cpsw_phy_addr_update(priv);
- priv->bus = miiphy_get_dev_by_name(priv->dev->name);
for_active_slave(slave, priv)
cpsw_phy_init(priv, slave);
diff --git a/drivers/net/ti/cpsw_mdio.c b/drivers/net/ti/cpsw_mdio.c
new file mode 100644
index 0000000..70f547e
--- /dev/null
+++ b/drivers/net/ti/cpsw_mdio.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CPSW MDIO generic driver for TI AMxx/K2x/EMAC devices.
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <miiphy.h>
+#include <wait_bit.h>
+
+struct cpsw_mdio_regs {
+ u32 version;
+ u32 control;
+#define CONTROL_IDLE BIT(31)
+#define CONTROL_ENABLE BIT(30)
+#define CONTROL_FAULT BIT(19)
+#define CONTROL_FAULT_ENABLE BIT(18)
+#define CONTROL_DIV_MASK GENMASK(15, 0)
+
+ u32 alive;
+ u32 link;
+ u32 linkintraw;
+ u32 linkintmasked;
+ u32 __reserved_0[2];
+ u32 userintraw;
+ u32 userintmasked;
+ u32 userintmaskset;
+ u32 userintmaskclr;
+ u32 __reserved_1[20];
+
+ struct {
+ u32 access;
+ u32 physel;
+#define USERACCESS_GO BIT(31)
+#define USERACCESS_WRITE BIT(30)
+#define USERACCESS_ACK BIT(29)
+#define USERACCESS_READ (0)
+#define USERACCESS_PHY_REG_SHIFT (21)
+#define USERACCESS_PHY_ADDR_SHIFT (16)
+#define USERACCESS_DATA GENMASK(15, 0)
+ } user[0];
+};
+
+#define CPSW_MDIO_DIV_DEF 0xff
+#define PHY_REG_MASK 0x1f
+#define PHY_ID_MASK 0x1f
+
+/*
+ * This timeout definition is a worst-case ultra defensive measure against
+ * unexpected controller lock ups. Ideally, we should never ever hit this
+ * scenario in practice.
+ */
+#define CPSW_MDIO_TIMEOUT 100 /* msecs */
+
+struct cpsw_mdio {
+ struct cpsw_mdio_regs *regs;
+ struct mii_dev *bus;
+ int div;
+};
+
+/* wait until hardware is ready for another user access */
+static int cpsw_mdio_wait_for_user_access(struct cpsw_mdio *mdio)
+{
+ return wait_for_bit_le32(&mdio->regs->user[0].access,
+ USERACCESS_GO, false,
+ CPSW_MDIO_TIMEOUT, false);
+}
+
+static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
+ int dev_addr, int phy_reg)
+{
+ struct cpsw_mdio *mdio = bus->priv;
+ int data, ret;
+ u32 reg;
+
+ if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
+ return -EINVAL;
+
+ ret = cpsw_mdio_wait_for_user_access(mdio);
+ if (ret)
+ return ret;
+ reg = (USERACCESS_GO | USERACCESS_READ |
+ (phy_reg << USERACCESS_PHY_REG_SHIFT) |
+ (phy_id << USERACCESS_PHY_ADDR_SHIFT));
+ writel(reg, &mdio->regs->user[0].access);
+ ret = cpsw_mdio_wait_for_user_access(mdio);
+ if (ret)
+ return ret;
+
+ reg = readl(&mdio->regs->user[0].access);
+ data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
+ return data;
+}
+
+static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
+ int phy_reg, u16 data)
+{
+ struct cpsw_mdio *mdio = bus->priv;
+ u32 reg;
+ int ret;
+
+ if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
+ return -EINVAL;
+
+ ret = cpsw_mdio_wait_for_user_access(mdio);
+ if (ret)
+ return ret;
+ reg = (USERACCESS_GO | USERACCESS_WRITE |
+ (phy_reg << USERACCESS_PHY_REG_SHIFT) |
+ (phy_id << USERACCESS_PHY_ADDR_SHIFT) |
+ (data & USERACCESS_DATA));
+ writel(reg, &mdio->regs->user[0].access);
+
+ return cpsw_mdio_wait_for_user_access(mdio);
+}
+
+u32 cpsw_mdio_get_alive(struct mii_dev *bus)
+{
+ struct cpsw_mdio *mdio = bus->priv;
+ u32 val;
+
+ val = readl(&mdio->regs->control);
+ return val & GENMASK(15, 0);
+}
+
+struct mii_dev *cpsw_mdio_init(const char *name, u32 mdio_base,
+ u32 bus_freq, int fck_freq)
+{
+ struct cpsw_mdio *cpsw_mdio;
+ int ret;
+
+ cpsw_mdio = calloc(1, sizeof(*cpsw_mdio));
+ if (!cpsw_mdio) {
+ debug("failed to alloc cpsw_mdio\n");
+ return NULL;
+ }
+
+ cpsw_mdio->bus = mdio_alloc();
+ if (!cpsw_mdio->bus) {
+ debug("failed to alloc mii bus\n");
+ free(cpsw_mdio);
+ return NULL;
+ }
+
+ cpsw_mdio->regs = (struct cpsw_mdio_regs *)mdio_base;
+
+ if (!bus_freq || !fck_freq)
+ cpsw_mdio->div = CPSW_MDIO_DIV_DEF;
+ else
+ cpsw_mdio->div = (fck_freq / bus_freq) - 1;
+ cpsw_mdio->div &= CONTROL_DIV_MASK;
+
+ /* set enable and clock divider */
+ writel(cpsw_mdio->div | CONTROL_ENABLE | CONTROL_FAULT |
+ CONTROL_FAULT_ENABLE, &cpsw_mdio->regs->control);
+ wait_for_bit_le32(&cpsw_mdio->regs->control,
+ CONTROL_IDLE, false, CPSW_MDIO_TIMEOUT, true);
+
+ /*
+ * wait for scan logic to settle:
+ * the scan time consists of (a) a large fixed component, and (b) a
+ * small component that varies with the mii bus frequency. These
+ * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
+ * silicon. Since the effect of (b) was found to be largely
+ * negligible, we keep things simple here.
+ */
+ mdelay(1);
+
+ cpsw_mdio->bus->read = cpsw_mdio_read;
+ cpsw_mdio->bus->write = cpsw_mdio_write;
+ cpsw_mdio->bus->priv = cpsw_mdio;
+ snprintf(cpsw_mdio->bus->name, sizeof(cpsw_mdio->bus->name), name);
+
+ ret = mdio_register(cpsw_mdio->bus);
+ if (ret < 0) {
+ debug("failed to register mii bus\n");
+ goto free_bus;
+ }
+
+ return cpsw_mdio->bus;
+
+free_bus:
+ mdio_free(cpsw_mdio->bus);
+ free(cpsw_mdio);
+ return NULL;
+}
+
+void cpsw_mdio_free(struct mii_dev *bus)
+{
+ struct cpsw_mdio *mdio = bus->priv;
+ u32 reg;
+
+ /* disable mdio */
+ reg = readl(&mdio->regs->control);
+ reg &= ~CONTROL_ENABLE;
+ writel(reg, &mdio->regs->control);
+
+ mdio_unregister(bus);
+ mdio_free(bus);
+ free(mdio);
+}
diff --git a/drivers/net/ti/cpsw_mdio.h b/drivers/net/ti/cpsw_mdio.h
new file mode 100644
index 0000000..4a76d4e
--- /dev/null
+++ b/drivers/net/ti/cpsw_mdio.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * CPSW MDIO generic driver API for TI AMxx/K2x/EMAC devices.
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#ifndef CPSW_MDIO_H_
+#define CPSW_MDIO_H_
+
+struct cpsw_mdio;
+
+struct mii_dev *cpsw_mdio_init(const char *name, u32 mdio_base,
+ u32 bus_freq, int fck_freq);
+void cpsw_mdio_free(struct mii_dev *bus);
+u32 cpsw_mdio_get_alive(struct mii_dev *bus);
+
+#endif /* CPSW_MDIO_H_ */
diff --git a/drivers/net/davinci_emac.c b/drivers/net/ti/davinci_emac.c
index bb879d8..bb879d8 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/ti/davinci_emac.c
diff --git a/drivers/net/davinci_emac.h b/drivers/net/ti/davinci_emac.h
index 695855b..695855b 100644
--- a/drivers/net/davinci_emac.h
+++ b/drivers/net/ti/davinci_emac.h
diff --git a/drivers/net/keystone_net.c b/drivers/net/ti/keystone_net.c
index d4d909b..a3ba91c 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/ti/keystone_net.c
@@ -22,13 +22,9 @@
#include <asm/ti-common/keystone_serdes.h>
#include <asm/arch/psc_defs.h>
-DECLARE_GLOBAL_DATA_PTR;
+#include "cpsw_mdio.h"
-#ifndef CONFIG_DM_ETH
-unsigned int emac_open;
-static struct mii_dev *mdio_bus;
-static unsigned int sys_has_mdio = 1;
-#endif
+DECLARE_GLOBAL_DATA_PTR;
#ifdef KEYSTONE2_EMAC_GIG_ENABLE
#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x)
@@ -43,17 +39,6 @@ static unsigned int sys_has_mdio = 1;
static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
-#ifndef CONFIG_DM_ETH
-struct rx_buff_desc net_rx_buffs = {
- .buff_ptr = rx_buffs,
- .num_buffs = RX_BUFF_NUMS,
- .buff_len = RX_BUFF_LEN,
- .rx_flow = 22,
-};
-#endif
-
-#ifdef CONFIG_DM_ETH
-
enum link_type {
LINK_TYPE_SGMII_MAC_TO_MAC_AUTO = 0,
LINK_TYPE_SGMII_MAC_TO_PHY_MODE = 1,
@@ -83,7 +68,7 @@ enum link_type {
#define DEVICE_EMACSW_BASE(base, x) ((base) + EMAC_EMACSW_PORT_BASE_OFS + \
(x) * 0x30)
-#elif defined CONFIG_KSNET_NETCP_V1_5
+#elif defined(CONFIG_KSNET_NETCP_V1_5)
#define EMAC_EMACSW_PORT_BASE_OFS 0x222000
@@ -113,126 +98,26 @@ struct ks2_eth_priv {
bool emac_open;
bool has_mdio;
};
-#endif
-
-/* MDIO */
-
-static int keystone2_mdio_reset(struct mii_dev *bus)
-{
- u_int32_t clkdiv;
- struct mdio_regs *adap_mdio = bus->priv;
-
- clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
-
- writel((clkdiv & 0xffff) | MDIO_CONTROL_ENABLE |
- MDIO_CONTROL_FAULT | MDIO_CONTROL_FAULT_ENABLE,
- &adap_mdio->control);
-
- while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE)
- ;
-
- return 0;
-}
-
-/**
- * keystone2_mdio_read - read a PHY register via MDIO interface.
- * Blocks until operation is complete.
- */
-static int keystone2_mdio_read(struct mii_dev *bus,
- int addr, int devad, int reg)
-{
- int tmp;
- struct mdio_regs *adap_mdio = bus->priv;
-
- while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
- ;
-
- writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_READ |
- ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16),
- &adap_mdio->useraccess0);
-
- /* Wait for command to complete */
- while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO)
- ;
-
- if (tmp & MDIO_USERACCESS0_ACK)
- return tmp & 0xffff;
- return -1;
-}
-
-/**
- * keystone2_mdio_write - write to a PHY register via MDIO interface.
- * Blocks until operation is complete.
- */
-static int keystone2_mdio_write(struct mii_dev *bus,
- int addr, int devad, int reg, u16 val)
-{
- struct mdio_regs *adap_mdio = bus->priv;
-
- while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
- ;
-
- writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_WRITE |
- ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16) |
- (val & 0xffff), &adap_mdio->useraccess0);
-
- /* Wait for command to complete */
- while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
- ;
-
- return 0;
-}
-
-#ifndef CONFIG_DM_ETH
static void __attribute__((unused))
- keystone2_eth_gigabit_enable(struct eth_device *dev)
+ keystone2_eth_gigabit_enable(struct udevice *dev)
{
- u_int16_t data;
- struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
-
- if (sys_has_mdio) {
- data = keystone2_mdio_read(mdio_bus, eth_priv->phy_addr,
- MDIO_DEVAD_NONE, 0);
- /* speed selection MSB */
- if (!(data & (1 << 6)))
- return;
- }
+ struct ks2_eth_priv *priv = dev_get_priv(dev);
/*
* Check if link detected is giga-bit
* If Gigabit mode detected, enable gigbit in MAC
*/
- writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) +
- CPGMACSL_REG_CTL) |
- EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
- DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL);
-}
-#else
-static void __attribute__((unused))
- keystone2_eth_gigabit_enable(struct udevice *dev)
-{
- struct ks2_eth_priv *priv = dev_get_priv(dev);
- u_int16_t data;
-
if (priv->has_mdio) {
- data = keystone2_mdio_read(priv->mdio_bus, priv->phy_addr,
- MDIO_DEVAD_NONE, 0);
- /* speed selection MSB */
- if (!(data & (1 << 6)))
+ if (priv->phydev->speed != 1000)
return;
}
- /*
- * Check if link detected is giga-bit
- * If Gigabit mode detected, enable gigbit in MAC
- */
writel(readl(DEVICE_EMACSL_BASE(priv->slave_port - 1) +
CPGMACSL_REG_CTL) |
EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
DEVICE_EMACSL_BASE(priv->slave_port - 1) + CPGMACSL_REG_CTL);
}
-#endif
#ifdef CONFIG_SOC_K2G
int keystone_rgmii_config(struct phy_device *phy_dev)
@@ -497,246 +382,6 @@ static void keystone2_net_serdes_setup(void)
}
#endif
-#ifndef CONFIG_DM_ETH
-
-int keystone2_eth_read_mac_addr(struct eth_device *dev)
-{
- struct eth_priv_t *eth_priv;
- u32 maca = 0;
- u32 macb = 0;
-
- eth_priv = (struct eth_priv_t *)dev->priv;
-
- /* Read the e-fuse mac address */
- if (eth_priv->slave_port == 1) {
- maca = __raw_readl(MAC_ID_BASE_ADDR);
- macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
- }
-
- dev->enetaddr[0] = (macb >> 8) & 0xff;
- dev->enetaddr[1] = (macb >> 0) & 0xff;
- dev->enetaddr[2] = (maca >> 24) & 0xff;
- dev->enetaddr[3] = (maca >> 16) & 0xff;
- dev->enetaddr[4] = (maca >> 8) & 0xff;
- dev->enetaddr[5] = (maca >> 0) & 0xff;
-
- return 0;
-}
-
-int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
-{
- if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
- num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
-
- return ksnav_send(&netcp_pktdma, buffer,
- num_bytes, (slave_port_num) << 16);
-}
-
-/* Eth device open */
-static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
-{
- struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
- struct phy_device *phy_dev = eth_priv->phy_dev;
-
- debug("+ emac_open\n");
-
- net_rx_buffs.rx_flow = eth_priv->rx_flow;
-
- sys_has_mdio =
- (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
-
- if (sys_has_mdio)
- keystone2_mdio_reset(mdio_bus);
-
-#ifdef CONFIG_SOC_K2G
- keystone_rgmii_config(phy_dev);
-#else
- keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1,
- eth_priv->sgmii_link_type);
-#endif
-
- udelay(10000);
-
- /* On chip switch configuration */
- ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
-
- /* TODO: add error handling code */
- if (qm_init()) {
- printf("ERROR: qm_init()\n");
- return -1;
- }
- if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) {
- qm_close();
- printf("ERROR: netcp_init()\n");
- return -1;
- }
-
- /*
- * Streaming switch configuration. If not present this
- * statement is defined to void in target.h.
- * If present this is usually defined to a series of register writes
- */
- hw_config_streaming_switch();
-
- if (sys_has_mdio) {
- keystone2_mdio_reset(mdio_bus);
-
- phy_startup(phy_dev);
- if (phy_dev->link == 0) {
- ksnav_close(&netcp_pktdma);
- qm_close();
- return -1;
- }
- }
-
- emac_gigabit_enable(dev);
-
- ethss_start();
-
- debug("- emac_open\n");
-
- emac_open = 1;
-
- return 0;
-}
-
-/* Eth device close */
-void keystone2_eth_close(struct eth_device *dev)
-{
- struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
- struct phy_device *phy_dev = eth_priv->phy_dev;
-
- debug("+ emac_close\n");
-
- if (!emac_open)
- return;
-
- ethss_stop();
-
- ksnav_close(&netcp_pktdma);
- qm_close();
- phy_shutdown(phy_dev);
-
- emac_open = 0;
-
- debug("- emac_close\n");
-}
-
-/*
- * This function sends a single packet on the network and returns
- * positive number (number of bytes transmitted) or negative for error
- */
-static int keystone2_eth_send_packet(struct eth_device *dev,
- void *packet, int length)
-{
- int ret_status = -1;
- struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
- struct phy_device *phy_dev = eth_priv->phy_dev;
-
- genphy_update_link(phy_dev);
- if (phy_dev->link == 0)
- return -1;
-
- if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
- return ret_status;
-
- return length;
-}
-
-/*
- * This function handles receipt of a packet from the network
- */
-static int keystone2_eth_rcv_packet(struct eth_device *dev)
-{
- void *hd;
- int pkt_size;
- u32 *pkt;
-
- hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size);
- if (hd == NULL)
- return 0;
-
- net_process_received_packet((uchar *)pkt, pkt_size);
-
- ksnav_release_rxhd(&netcp_pktdma, hd);
-
- return pkt_size;
-}
-
-#ifdef CONFIG_MCAST_TFTP
-static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set)
-{
- return 0;
-}
-#endif
-
-/*
- * This function initializes the EMAC hardware.
- */
-int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
-{
- int res;
- struct eth_device *dev;
- struct phy_device *phy_dev;
- struct mdio_regs *adap_mdio = (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
-
- dev = malloc(sizeof(struct eth_device));
- if (dev == NULL)
- return -1;
-
- memset(dev, 0, sizeof(struct eth_device));
-
- strcpy(dev->name, eth_priv->int_name);
- dev->priv = eth_priv;
-
- keystone2_eth_read_mac_addr(dev);
-
- dev->iobase = 0;
- dev->init = keystone2_eth_open;
- dev->halt = keystone2_eth_close;
- dev->send = keystone2_eth_send_packet;
- dev->recv = keystone2_eth_rcv_packet;
-#ifdef CONFIG_MCAST_TFTP
- dev->mcast = keystone2_eth_bcast_addr;
-#endif
-
- eth_register(dev);
-
- /* Register MDIO bus if it's not registered yet */
- if (!mdio_bus) {
- mdio_bus = mdio_alloc();
- mdio_bus->read = keystone2_mdio_read;
- mdio_bus->write = keystone2_mdio_write;
- mdio_bus->reset = keystone2_mdio_reset;
- mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR;
- strcpy(mdio_bus->name, "ethernet-mdio");
-
- res = mdio_register(mdio_bus);
- if (res)
- return res;
- }
-
-#ifndef CONFIG_SOC_K2G
- keystone2_net_serdes_setup();
-#endif
-
- /* Create phy device and bind it with driver */
-#ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
- phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr,
- dev, eth_priv->phy_if);
- phy_config(phy_dev);
-#else
- phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr,
- eth_priv->phy_if);
- phy_dev->dev = dev;
-#endif
- eth_priv->phy_dev = phy_dev;
-
- return 0;
-}
-
-#else
-
static int ks2_eth_start(struct udevice *dev)
{
struct ks2_eth_priv *priv = dev_get_priv(dev);
@@ -768,8 +413,6 @@ static int ks2_eth_start(struct udevice *dev)
hw_config_streaming_switch();
if (priv->has_mdio) {
- keystone2_mdio_reset(priv->mdio_bus);
-
phy_startup(priv->phydev);
if (priv->phydev->link == 0) {
pr_err("phy startup failed\n");
@@ -889,9 +532,9 @@ static int ks2_eth_probe(struct udevice *dev)
{
struct ks2_eth_priv *priv = dev_get_priv(dev);
struct mii_dev *mdio_bus;
- int ret;
priv->dev = dev;
+ priv->emac_open = false;
/* These clock enables has to be moved to common location */
if (cpu_is_k2g())
@@ -910,45 +553,36 @@ static int ks2_eth_probe(struct udevice *dev)
if (cpu_is_k2e() || cpu_is_k2l())
pll_pa_clk_sel();
-
priv->net_rx_buffs.buff_ptr = rx_buffs;
priv->net_rx_buffs.num_buffs = RX_BUFF_NUMS;
priv->net_rx_buffs.buff_len = RX_BUFF_LEN;
if (priv->slave_port == 1) {
+#ifndef CONFIG_SOC_K2G
+ keystone2_net_serdes_setup();
+#endif
/*
* Register MDIO bus for slave 0 only, other slave have
* to re-use the same
*/
- mdio_bus = mdio_alloc();
+ mdio_bus = cpsw_mdio_init("ethernet-mdio",
+ (u32)priv->mdio_base,
+ EMAC_MDIO_CLOCK_FREQ,
+ EMAC_MDIO_BUS_FREQ);
if (!mdio_bus) {
pr_err("MDIO alloc failed\n");
return -ENOMEM;
}
priv->mdio_bus = mdio_bus;
- mdio_bus->read = keystone2_mdio_read;
- mdio_bus->write = keystone2_mdio_write;
- mdio_bus->reset = keystone2_mdio_reset;
- mdio_bus->priv = priv->mdio_base;
- sprintf(mdio_bus->name, "ethernet-mdio");
-
- ret = mdio_register(mdio_bus);
- if (ret) {
- pr_err("MDIO bus register failed\n");
- return ret;
- }
} else {
/* Get the MDIO bus from slave 0 device */
struct ks2_eth_priv *parent_priv;
parent_priv = dev_get_priv(dev->parent);
priv->mdio_bus = parent_priv->mdio_bus;
+ priv->mdio_base = parent_priv->mdio_base;
}
-#ifndef CONFIG_SOC_K2G
- keystone2_net_serdes_setup();
-#endif
-
priv->netcp_pktdma = &netcp_pktdma;
if (priv->has_mdio) {
@@ -964,9 +598,7 @@ int ks2_eth_remove(struct udevice *dev)
{
struct ks2_eth_priv *priv = dev_get_priv(dev);
- free(priv->phydev);
- mdio_unregister(priv->mdio_bus);
- mdio_free(priv->mdio_bus);
+ cpsw_mdio_free(priv->mdio_bus);
return 0;
}
@@ -1167,4 +799,3 @@ U_BOOT_DRIVER(eth_ks2) = {
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
-#endif
diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h
index cc823c5..5e504f6 100644
--- a/include/configs/ti_armv7_keystone2.h
+++ b/include/configs/ti_armv7_keystone2.h
@@ -128,7 +128,6 @@
#define CONFIG_KSNAV_NETCP_PDMA_TX_SND_QUEUE KS2_NETCP_PDMA_TX_SND_QUEUE
/* Keystone net */
-#define CONFIG_DRIVER_TI_KEYSTONE_NET
#define CONFIG_KSNET_MAC_ID_BASE KS2_MAC_ID_BASE_ADDR
#define CONFIG_KSNET_NETCP_BASE KS2_NETCP_BASE
#define CONFIG_KSNET_SERDES_SGMII_BASE KS2_SGMII_SERDES_BASE
diff --git a/include/netdev.h b/include/netdev.h
index 5500162..0a1a3a2 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -43,7 +43,6 @@ int ethoc_initialize(u8 dev_num, int base_addr);
int fec_initialize (bd_t *bis);
int fecmxc_initialize(bd_t *bis);
int fecmxc_initialize_multi(bd_t *bis, int dev_id, int phy_id, uint32_t addr);
-int ftgmac100_initialize(bd_t *bits);
int ftmac100_initialize(bd_t *bits);
int ftmac110_initialize(bd_t *bits);
void gt6426x_eth_initialize(bd_t *bis);