| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * dwmac-sun8i.c - Allwinner sun8i DWMAC specific glue layer |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2017 Corentin Labbe <clabbe.montjoie@gmail.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | | - * GNU General Public License for more details. |
|---|
| 15 | 6 | */ |
|---|
| 16 | 7 | |
|---|
| 17 | 8 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 149 | 140 | .tx_delay_max = 7, |
|---|
| 150 | 141 | }; |
|---|
| 151 | 142 | |
|---|
| 143 | +static const struct emac_variant emac_variant_h6 = { |
|---|
| 144 | + .default_syscon_value = 0x50000, |
|---|
| 145 | + .syscon_field = &sun8i_syscon_reg_field, |
|---|
| 146 | + /* The "Internal PHY" of H6 is not on the die. It's on the |
|---|
| 147 | + * co-packaged AC200 chip instead. |
|---|
| 148 | + */ |
|---|
| 149 | + .soc_has_internal_phy = false, |
|---|
| 150 | + .support_mii = true, |
|---|
| 151 | + .support_rmii = true, |
|---|
| 152 | + .support_rgmii = true, |
|---|
| 153 | + .rx_delay_max = 31, |
|---|
| 154 | + .tx_delay_max = 7, |
|---|
| 155 | +}; |
|---|
| 156 | + |
|---|
| 152 | 157 | #define EMAC_BASIC_CTL0 0x00 |
|---|
| 153 | 158 | #define EMAC_BASIC_CTL1 0x04 |
|---|
| 154 | 159 | #define EMAC_INT_STA 0x08 |
|---|
| .. | .. |
|---|
| 189 | 194 | |
|---|
| 190 | 195 | /* Used in RX_CTL1*/ |
|---|
| 191 | 196 | #define EMAC_RX_MD BIT(1) |
|---|
| 192 | | -#define EMAC_RX_TH_MASK GENMASK(4, 5) |
|---|
| 197 | +#define EMAC_RX_TH_MASK GENMASK(5, 4) |
|---|
| 193 | 198 | #define EMAC_RX_TH_32 0 |
|---|
| 194 | 199 | #define EMAC_RX_TH_64 (0x1 << 4) |
|---|
| 195 | 200 | #define EMAC_RX_TH_96 (0x2 << 4) |
|---|
| .. | .. |
|---|
| 200 | 205 | /* Used in TX_CTL1*/ |
|---|
| 201 | 206 | #define EMAC_TX_MD BIT(1) |
|---|
| 202 | 207 | #define EMAC_TX_NEXT_FRM BIT(2) |
|---|
| 203 | | -#define EMAC_TX_TH_MASK GENMASK(8, 10) |
|---|
| 208 | +#define EMAC_TX_TH_MASK GENMASK(10, 8) |
|---|
| 204 | 209 | #define EMAC_TX_TH_64 0 |
|---|
| 205 | 210 | #define EMAC_TX_TH_128 (0x1 << 8) |
|---|
| 206 | 211 | #define EMAC_TX_TH_192 (0x2 << 8) |
|---|
| .. | .. |
|---|
| 286 | 291 | |
|---|
| 287 | 292 | static void sun8i_dwmac_dma_init_rx(void __iomem *ioaddr, |
|---|
| 288 | 293 | struct stmmac_dma_cfg *dma_cfg, |
|---|
| 289 | | - u32 dma_rx_phy, u32 chan) |
|---|
| 294 | + dma_addr_t dma_rx_phy, u32 chan) |
|---|
| 290 | 295 | { |
|---|
| 291 | 296 | /* Write RX descriptors address */ |
|---|
| 292 | | - writel(dma_rx_phy, ioaddr + EMAC_RX_DESC_LIST); |
|---|
| 297 | + writel(lower_32_bits(dma_rx_phy), ioaddr + EMAC_RX_DESC_LIST); |
|---|
| 293 | 298 | } |
|---|
| 294 | 299 | |
|---|
| 295 | 300 | static void sun8i_dwmac_dma_init_tx(void __iomem *ioaddr, |
|---|
| 296 | 301 | struct stmmac_dma_cfg *dma_cfg, |
|---|
| 297 | | - u32 dma_tx_phy, u32 chan) |
|---|
| 302 | + dma_addr_t dma_tx_phy, u32 chan) |
|---|
| 298 | 303 | { |
|---|
| 299 | 304 | /* Write TX descriptors address */ |
|---|
| 300 | | - writel(dma_tx_phy, ioaddr + EMAC_TX_DESC_LIST); |
|---|
| 305 | + writel(lower_32_bits(dma_tx_phy), ioaddr + EMAC_TX_DESC_LIST); |
|---|
| 301 | 306 | } |
|---|
| 302 | 307 | |
|---|
| 303 | 308 | /* sun8i_dwmac_dump_regs() - Dump EMAC address space |
|---|
| .. | .. |
|---|
| 332 | 337 | } |
|---|
| 333 | 338 | } |
|---|
| 334 | 339 | |
|---|
| 335 | | -static void sun8i_dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan) |
|---|
| 340 | +static void sun8i_dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, |
|---|
| 341 | + bool rx, bool tx) |
|---|
| 336 | 342 | { |
|---|
| 337 | | - writel(EMAC_RX_INT | EMAC_TX_INT, ioaddr + EMAC_INT_EN); |
|---|
| 343 | + u32 value = readl(ioaddr + EMAC_INT_EN); |
|---|
| 344 | + |
|---|
| 345 | + if (rx) |
|---|
| 346 | + value |= EMAC_RX_INT; |
|---|
| 347 | + if (tx) |
|---|
| 348 | + value |= EMAC_TX_INT; |
|---|
| 349 | + |
|---|
| 350 | + writel(value, ioaddr + EMAC_INT_EN); |
|---|
| 338 | 351 | } |
|---|
| 339 | 352 | |
|---|
| 340 | | -static void sun8i_dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan) |
|---|
| 353 | +static void sun8i_dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan, |
|---|
| 354 | + bool rx, bool tx) |
|---|
| 341 | 355 | { |
|---|
| 342 | | - writel(0, ioaddr + EMAC_INT_EN); |
|---|
| 356 | + u32 value = readl(ioaddr + EMAC_INT_EN); |
|---|
| 357 | + |
|---|
| 358 | + if (rx) |
|---|
| 359 | + value &= ~EMAC_RX_INT; |
|---|
| 360 | + if (tx) |
|---|
| 361 | + value &= ~EMAC_TX_INT; |
|---|
| 362 | + |
|---|
| 363 | + writel(value, ioaddr + EMAC_INT_EN); |
|---|
| 343 | 364 | } |
|---|
| 344 | 365 | |
|---|
| 345 | 366 | static void sun8i_dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan) |
|---|
| .. | .. |
|---|
| 663 | 684 | } |
|---|
| 664 | 685 | } |
|---|
| 665 | 686 | } else { |
|---|
| 666 | | - netdev_info(dev, "Too many address, switching to promiscuous\n"); |
|---|
| 687 | + if (!(readl(ioaddr + EMAC_RX_FRM_FLT) & EMAC_FRM_FLT_RXALL)) |
|---|
| 688 | + netdev_info(dev, "Too many address, switching to promiscuous\n"); |
|---|
| 667 | 689 | v = EMAC_FRM_FLT_RXALL; |
|---|
| 668 | 690 | } |
|---|
| 669 | 691 | |
|---|
| .. | .. |
|---|
| 873 | 895 | |
|---|
| 874 | 896 | ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn, |
|---|
| 875 | 897 | &gmac->mux_handle, priv, priv->mii); |
|---|
| 898 | + of_node_put(mdio_mux); |
|---|
| 876 | 899 | return ret; |
|---|
| 877 | 900 | } |
|---|
| 878 | 901 | |
|---|
| 879 | | -static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) |
|---|
| 902 | +static int sun8i_dwmac_set_syscon(struct device *dev, |
|---|
| 903 | + struct plat_stmmacenet_data *plat) |
|---|
| 880 | 904 | { |
|---|
| 881 | | - struct sunxi_priv_data *gmac = priv->plat->bsp_priv; |
|---|
| 882 | | - struct device_node *node = priv->device->of_node; |
|---|
| 905 | + struct sunxi_priv_data *gmac = plat->bsp_priv; |
|---|
| 906 | + struct device_node *node = dev->of_node; |
|---|
| 883 | 907 | int ret; |
|---|
| 884 | 908 | u32 reg, val; |
|---|
| 885 | 909 | |
|---|
| 886 | | - regmap_field_read(gmac->regmap_field, &val); |
|---|
| 910 | + ret = regmap_field_read(gmac->regmap_field, &val); |
|---|
| 911 | + if (ret) { |
|---|
| 912 | + dev_err(dev, "Fail to read from regmap field.\n"); |
|---|
| 913 | + return ret; |
|---|
| 914 | + } |
|---|
| 915 | + |
|---|
| 887 | 916 | reg = gmac->variant->default_syscon_value; |
|---|
| 888 | 917 | if (reg != val) |
|---|
| 889 | | - dev_warn(priv->device, |
|---|
| 918 | + dev_warn(dev, |
|---|
| 890 | 919 | "Current syscon value is not the default %x (expect %x)\n", |
|---|
| 891 | 920 | val, reg); |
|---|
| 892 | 921 | |
|---|
| .. | .. |
|---|
| 899 | 928 | /* Force EPHY xtal frequency to 24MHz. */ |
|---|
| 900 | 929 | reg |= H3_EPHY_CLK_SEL; |
|---|
| 901 | 930 | |
|---|
| 902 | | - ret = of_mdio_parse_addr(priv->device, priv->plat->phy_node); |
|---|
| 931 | + ret = of_mdio_parse_addr(dev, plat->phy_node); |
|---|
| 903 | 932 | if (ret < 0) { |
|---|
| 904 | | - dev_err(priv->device, "Could not parse MDIO addr\n"); |
|---|
| 933 | + dev_err(dev, "Could not parse MDIO addr\n"); |
|---|
| 905 | 934 | return ret; |
|---|
| 906 | 935 | } |
|---|
| 907 | 936 | /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY |
|---|
| .. | .. |
|---|
| 917 | 946 | |
|---|
| 918 | 947 | if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { |
|---|
| 919 | 948 | if (val % 100) { |
|---|
| 920 | | - dev_err(priv->device, "tx-delay must be a multiple of 100\n"); |
|---|
| 949 | + dev_err(dev, "tx-delay must be a multiple of 100\n"); |
|---|
| 921 | 950 | return -EINVAL; |
|---|
| 922 | 951 | } |
|---|
| 923 | 952 | val /= 100; |
|---|
| 924 | | - dev_dbg(priv->device, "set tx-delay to %x\n", val); |
|---|
| 953 | + dev_dbg(dev, "set tx-delay to %x\n", val); |
|---|
| 925 | 954 | if (val <= gmac->variant->tx_delay_max) { |
|---|
| 926 | 955 | reg &= ~(gmac->variant->tx_delay_max << |
|---|
| 927 | 956 | SYSCON_ETXDC_SHIFT); |
|---|
| 928 | 957 | reg |= (val << SYSCON_ETXDC_SHIFT); |
|---|
| 929 | 958 | } else { |
|---|
| 930 | | - dev_err(priv->device, "Invalid TX clock delay: %d\n", |
|---|
| 959 | + dev_err(dev, "Invalid TX clock delay: %d\n", |
|---|
| 931 | 960 | val); |
|---|
| 932 | 961 | return -EINVAL; |
|---|
| 933 | 962 | } |
|---|
| .. | .. |
|---|
| 935 | 964 | |
|---|
| 936 | 965 | if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) { |
|---|
| 937 | 966 | if (val % 100) { |
|---|
| 938 | | - dev_err(priv->device, "rx-delay must be a multiple of 100\n"); |
|---|
| 967 | + dev_err(dev, "rx-delay must be a multiple of 100\n"); |
|---|
| 939 | 968 | return -EINVAL; |
|---|
| 940 | 969 | } |
|---|
| 941 | 970 | val /= 100; |
|---|
| 942 | | - dev_dbg(priv->device, "set rx-delay to %x\n", val); |
|---|
| 971 | + dev_dbg(dev, "set rx-delay to %x\n", val); |
|---|
| 943 | 972 | if (val <= gmac->variant->rx_delay_max) { |
|---|
| 944 | 973 | reg &= ~(gmac->variant->rx_delay_max << |
|---|
| 945 | 974 | SYSCON_ERXDC_SHIFT); |
|---|
| 946 | 975 | reg |= (val << SYSCON_ERXDC_SHIFT); |
|---|
| 947 | 976 | } else { |
|---|
| 948 | | - dev_err(priv->device, "Invalid RX clock delay: %d\n", |
|---|
| 977 | + dev_err(dev, "Invalid RX clock delay: %d\n", |
|---|
| 949 | 978 | val); |
|---|
| 950 | 979 | return -EINVAL; |
|---|
| 951 | 980 | } |
|---|
| .. | .. |
|---|
| 956 | 985 | if (gmac->variant->support_rmii) |
|---|
| 957 | 986 | reg &= ~SYSCON_RMII_EN; |
|---|
| 958 | 987 | |
|---|
| 959 | | - switch (priv->plat->interface) { |
|---|
| 988 | + switch (plat->interface) { |
|---|
| 960 | 989 | case PHY_INTERFACE_MODE_MII: |
|---|
| 961 | 990 | /* default */ |
|---|
| 962 | 991 | break; |
|---|
| .. | .. |
|---|
| 970 | 999 | reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII; |
|---|
| 971 | 1000 | break; |
|---|
| 972 | 1001 | default: |
|---|
| 973 | | - dev_err(priv->device, "Unsupported interface mode: %s", |
|---|
| 974 | | - phy_modes(priv->plat->interface)); |
|---|
| 1002 | + dev_err(dev, "Unsupported interface mode: %s", |
|---|
| 1003 | + phy_modes(plat->interface)); |
|---|
| 975 | 1004 | return -EINVAL; |
|---|
| 976 | 1005 | } |
|---|
| 977 | 1006 | |
|---|
| .. | .. |
|---|
| 996 | 1025 | sun8i_dwmac_unpower_internal_phy(gmac); |
|---|
| 997 | 1026 | } |
|---|
| 998 | 1027 | |
|---|
| 999 | | - sun8i_dwmac_unset_syscon(gmac); |
|---|
| 1000 | | - |
|---|
| 1001 | 1028 | clk_disable_unprepare(gmac->tx_clk); |
|---|
| 1002 | 1029 | |
|---|
| 1003 | 1030 | if (gmac->regulator) |
|---|
| 1004 | 1031 | regulator_disable(gmac->regulator); |
|---|
| 1032 | +} |
|---|
| 1033 | + |
|---|
| 1034 | +static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable) |
|---|
| 1035 | +{ |
|---|
| 1036 | + u32 value = readl(ioaddr + EMAC_BASIC_CTL0); |
|---|
| 1037 | + |
|---|
| 1038 | + if (enable) |
|---|
| 1039 | + value |= EMAC_LOOPBACK; |
|---|
| 1040 | + else |
|---|
| 1041 | + value &= ~EMAC_LOOPBACK; |
|---|
| 1042 | + |
|---|
| 1043 | + writel(value, ioaddr + EMAC_BASIC_CTL0); |
|---|
| 1005 | 1044 | } |
|---|
| 1006 | 1045 | |
|---|
| 1007 | 1046 | static const struct stmmac_ops sun8i_dwmac_ops = { |
|---|
| .. | .. |
|---|
| 1013 | 1052 | .flow_ctrl = sun8i_dwmac_flow_ctrl, |
|---|
| 1014 | 1053 | .set_umac_addr = sun8i_dwmac_set_umac_addr, |
|---|
| 1015 | 1054 | .get_umac_addr = sun8i_dwmac_get_umac_addr, |
|---|
| 1055 | + .set_mac_loopback = sun8i_dwmac_set_mac_loopback, |
|---|
| 1016 | 1056 | }; |
|---|
| 1017 | 1057 | |
|---|
| 1018 | 1058 | static struct mac_device_info *sun8i_dwmac_setup(void *ppriv) |
|---|
| 1019 | 1059 | { |
|---|
| 1020 | 1060 | struct mac_device_info *mac; |
|---|
| 1021 | 1061 | struct stmmac_priv *priv = ppriv; |
|---|
| 1022 | | - int ret; |
|---|
| 1023 | 1062 | |
|---|
| 1024 | 1063 | mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); |
|---|
| 1025 | 1064 | if (!mac) |
|---|
| 1026 | | - return NULL; |
|---|
| 1027 | | - |
|---|
| 1028 | | - ret = sun8i_dwmac_set_syscon(priv); |
|---|
| 1029 | | - if (ret) |
|---|
| 1030 | 1065 | return NULL; |
|---|
| 1031 | 1066 | |
|---|
| 1032 | 1067 | mac->pcsr = priv->ioaddr; |
|---|
| .. | .. |
|---|
| 1094 | 1129 | struct stmmac_resources stmmac_res; |
|---|
| 1095 | 1130 | struct sunxi_priv_data *gmac; |
|---|
| 1096 | 1131 | struct device *dev = &pdev->dev; |
|---|
| 1132 | + phy_interface_t interface; |
|---|
| 1097 | 1133 | int ret; |
|---|
| 1098 | 1134 | struct stmmac_priv *priv; |
|---|
| 1099 | 1135 | struct net_device *ndev; |
|---|
| .. | .. |
|---|
| 1102 | 1138 | ret = stmmac_get_platform_resources(pdev, &stmmac_res); |
|---|
| 1103 | 1139 | if (ret) |
|---|
| 1104 | 1140 | return ret; |
|---|
| 1105 | | - |
|---|
| 1106 | | - plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); |
|---|
| 1107 | | - if (IS_ERR(plat_dat)) |
|---|
| 1108 | | - return PTR_ERR(plat_dat); |
|---|
| 1109 | 1141 | |
|---|
| 1110 | 1142 | gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL); |
|---|
| 1111 | 1143 | if (!gmac) |
|---|
| .. | .. |
|---|
| 1167 | 1199 | return ret; |
|---|
| 1168 | 1200 | } |
|---|
| 1169 | 1201 | |
|---|
| 1170 | | - plat_dat->interface = of_get_phy_mode(dev->of_node); |
|---|
| 1202 | + ret = of_get_phy_mode(dev->of_node, &interface); |
|---|
| 1203 | + if (ret) |
|---|
| 1204 | + return -EINVAL; |
|---|
| 1205 | + |
|---|
| 1206 | + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); |
|---|
| 1207 | + if (IS_ERR(plat_dat)) |
|---|
| 1208 | + return PTR_ERR(plat_dat); |
|---|
| 1171 | 1209 | |
|---|
| 1172 | 1210 | /* platform data specifying hardware features and callbacks. |
|---|
| 1173 | 1211 | * hardware features were copied from Allwinner drivers. |
|---|
| 1174 | 1212 | */ |
|---|
| 1213 | + plat_dat->interface = interface; |
|---|
| 1175 | 1214 | plat_dat->rx_coe = STMMAC_RX_COE_TYPE2; |
|---|
| 1176 | 1215 | plat_dat->tx_coe = 1; |
|---|
| 1177 | 1216 | plat_dat->has_sun8i = true; |
|---|
| .. | .. |
|---|
| 1182 | 1221 | plat_dat->tx_fifo_size = 4096; |
|---|
| 1183 | 1222 | plat_dat->rx_fifo_size = 16384; |
|---|
| 1184 | 1223 | |
|---|
| 1224 | + ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat); |
|---|
| 1225 | + if (ret) |
|---|
| 1226 | + goto dwmac_deconfig; |
|---|
| 1227 | + |
|---|
| 1185 | 1228 | ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv); |
|---|
| 1186 | 1229 | if (ret) |
|---|
| 1187 | | - return ret; |
|---|
| 1230 | + goto dwmac_syscon; |
|---|
| 1188 | 1231 | |
|---|
| 1189 | 1232 | ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); |
|---|
| 1190 | 1233 | if (ret) |
|---|
| .. | .. |
|---|
| 1198 | 1241 | if (gmac->variant->soc_has_internal_phy) { |
|---|
| 1199 | 1242 | ret = get_ephy_nodes(priv); |
|---|
| 1200 | 1243 | if (ret) |
|---|
| 1201 | | - goto dwmac_exit; |
|---|
| 1244 | + goto dwmac_remove; |
|---|
| 1202 | 1245 | ret = sun8i_dwmac_register_mdio_mux(priv); |
|---|
| 1203 | 1246 | if (ret) { |
|---|
| 1204 | 1247 | dev_err(&pdev->dev, "Failed to register mux\n"); |
|---|
| .. | .. |
|---|
| 1207 | 1250 | } else { |
|---|
| 1208 | 1251 | ret = sun8i_dwmac_reset(priv); |
|---|
| 1209 | 1252 | if (ret) |
|---|
| 1210 | | - goto dwmac_exit; |
|---|
| 1253 | + goto dwmac_remove; |
|---|
| 1211 | 1254 | } |
|---|
| 1212 | 1255 | |
|---|
| 1213 | 1256 | return ret; |
|---|
| 1214 | 1257 | dwmac_mux: |
|---|
| 1215 | 1258 | reset_control_put(gmac->rst_ephy); |
|---|
| 1216 | 1259 | clk_put(gmac->ephy_clk); |
|---|
| 1217 | | - sun8i_dwmac_unset_syscon(gmac); |
|---|
| 1260 | +dwmac_remove: |
|---|
| 1261 | + stmmac_dvr_remove(&pdev->dev); |
|---|
| 1218 | 1262 | dwmac_exit: |
|---|
| 1219 | | - stmmac_pltfr_remove(pdev); |
|---|
| 1220 | | -return ret; |
|---|
| 1263 | + sun8i_dwmac_exit(pdev, gmac); |
|---|
| 1264 | +dwmac_syscon: |
|---|
| 1265 | + sun8i_dwmac_unset_syscon(gmac); |
|---|
| 1266 | +dwmac_deconfig: |
|---|
| 1267 | + stmmac_remove_config_dt(pdev, plat_dat); |
|---|
| 1268 | + |
|---|
| 1269 | + return ret; |
|---|
| 1221 | 1270 | } |
|---|
| 1222 | 1271 | |
|---|
| 1223 | 1272 | static int sun8i_dwmac_remove(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 1234 | 1283 | } |
|---|
| 1235 | 1284 | |
|---|
| 1236 | 1285 | stmmac_pltfr_remove(pdev); |
|---|
| 1286 | + sun8i_dwmac_unset_syscon(gmac); |
|---|
| 1237 | 1287 | |
|---|
| 1238 | 1288 | return 0; |
|---|
| 1239 | 1289 | } |
|---|
| .. | .. |
|---|
| 1249 | 1299 | .data = &emac_variant_r40 }, |
|---|
| 1250 | 1300 | { .compatible = "allwinner,sun50i-a64-emac", |
|---|
| 1251 | 1301 | .data = &emac_variant_a64 }, |
|---|
| 1302 | + { .compatible = "allwinner,sun50i-h6-emac", |
|---|
| 1303 | + .data = &emac_variant_h6 }, |
|---|
| 1252 | 1304 | { } |
|---|
| 1253 | 1305 | }; |
|---|
| 1254 | 1306 | MODULE_DEVICE_TABLE(of, sun8i_dwmac_match); |
|---|