@ -67,6 +67,7 @@
/* IO mux settings */
# define SUN8I_IOMUX_H3 2
# define SUN8I_IOMUX_R40 5
# define SUN8I_IOMUX 4
/* H3/A64 EMAC Register's offset */
@ -97,6 +98,7 @@ enum emac_variant {
A83T_EMAC = 1 ,
H3_EMAC ,
A64_EMAC ,
R40_GMAC ,
} ;
struct emac_dma_desc {
@ -278,6 +280,9 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
reg = readl ( priv - > sysctl_reg + 0x30 ) ;
if ( priv - > variant = = R40_GMAC )
return 0 ;
if ( priv - > variant = = H3_EMAC ) {
ret = sun8i_emac_set_syscon_ephy ( priv , & reg ) ;
if ( ret )
@ -495,6 +500,8 @@ static int parse_phy_pins(struct udevice *dev)
if ( priv - > variant = = H3_EMAC )
sunxi_gpio_set_cfgpin ( pin , SUN8I_IOMUX_H3 ) ;
else if ( priv - > variant = = R40_GMAC )
sunxi_gpio_set_cfgpin ( pin , SUN8I_IOMUX_R40 ) ;
else
sunxi_gpio_set_cfgpin ( pin , SUN8I_IOMUX ) ;
@ -634,11 +641,26 @@ static void sun8i_emac_board_setup(struct emac_eth_dev *priv)
}
}
/* Set clock gating for emac */
setbits_le32 ( & ccm - > ahb_gate0 , BIT ( AHB_GATE_OFFSET_GMAC ) ) ;
/* De-assert EMAC */
setbits_le32 ( & ccm - > ahb_reset0_cfg , BIT ( AHB_RESET_OFFSET_GMAC ) ) ;
if ( priv - > variant = = R40_GMAC ) {
/* Set clock gating for emac */
setbits_le32 ( & ccm - > ahb_reset1_cfg , BIT ( AHB_RESET_OFFSET_GMAC ) ) ;
/* De-assert EMAC */
setbits_le32 ( & ccm - > ahb_gate1 , BIT ( AHB_GATE_OFFSET_GMAC ) ) ;
/* Select RGMII for R40 */
setbits_le32 ( & ccm - > gmac_clk_cfg ,
CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII |
CCM_GMAC_CTRL_GPIT_RGMII ) ;
setbits_le32 ( & ccm - > gmac_clk_cfg ,
CCM_GMAC_CTRL_TX_CLK_DELAY ( CONFIG_GMAC_TX_DELAY ) ) ;
} else {
/* Set clock gating for emac */
setbits_le32 ( & ccm - > ahb_gate0 , BIT ( AHB_GATE_OFFSET_GMAC ) ) ;
/* De-assert EMAC */
setbits_le32 ( & ccm - > ahb_reset0_cfg , BIT ( AHB_RESET_OFFSET_GMAC ) ) ;
}
}
# if defined(CONFIG_DM_GPIO)
@ -805,22 +827,32 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
return - EINVAL ;
}
offset = fdtdec_lookup_phandle ( gd - > fdt_blob , node , " syscon " ) ;
if ( offset < 0 ) {
debug ( " %s: cannot find syscon node \n " , __func__ ) ;
return - EINVAL ;
}
reg = fdt_getprop ( gd - > fdt_blob , offset , " reg " , NULL ) ;
if ( ! reg ) {
debug ( " %s: cannot find reg property in syscon node \n " ,
__func__ ) ;
priv - > variant = dev_get_driver_data ( dev ) ;
if ( ! priv - > variant ) {
printf ( " %s: Missing variant \n " , __func__ ) ;
return - EINVAL ;
}
priv - > sysctl_reg = fdt_translate_address ( ( void * ) gd - > fdt_blob ,
offset , reg ) ;
if ( priv - > sysctl_reg = = FDT_ADDR_T_NONE ) {
debug ( " %s: Cannot find syscon base address \n " , __func__ ) ;
return - EINVAL ;
if ( priv - > variant ! = R40_GMAC ) {
offset = fdtdec_lookup_phandle ( gd - > fdt_blob , node , " syscon " ) ;
if ( offset < 0 ) {
debug ( " %s: cannot find syscon node \n " , __func__ ) ;
return - EINVAL ;
}
reg = fdt_getprop ( gd - > fdt_blob , offset , " reg " , NULL ) ;
if ( ! reg ) {
debug ( " %s: cannot find reg property in syscon node \n " ,
__func__ ) ;
return - EINVAL ;
}
priv - > sysctl_reg = fdt_translate_address ( ( void * ) gd - > fdt_blob ,
offset , reg ) ;
if ( priv - > sysctl_reg = = FDT_ADDR_T_NONE ) {
debug ( " %s: Cannot find syscon base address \n " ,
__func__ ) ;
return - EINVAL ;
}
}
pdata - > phy_interface = - 1 ;
@ -845,13 +877,6 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
return - EINVAL ;
}
priv - > variant = dev_get_driver_data ( dev ) ;
if ( ! priv - > variant ) {
printf ( " %s: Missing variant \n " , __func__ ) ;
return - EINVAL ;
}
if ( priv - > variant = = H3_EMAC ) {
int parent = fdt_parent_offset ( gd - > fdt_blob , offset ) ;
@ -892,6 +917,8 @@ static const struct udevice_id sun8i_emac_eth_ids[] = {
. data = ( uintptr_t ) A64_EMAC } ,
{ . compatible = " allwinner,sun8i-a83t-emac " ,
. data = ( uintptr_t ) A83T_EMAC } ,
{ . compatible = " allwinner,sun8i-r40-gmac " ,
. data = ( uintptr_t ) R40_GMAC } ,
{ }
} ;