From 5da39118172811a2fe32a4eeaee7193f8cb413ed Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Wed, 6 Apr 2016 18:04:57 +0200 Subject: sunxi: Support GbE controller (GMAC) for sun9i (A80) * board/sunxi/gmac.c(eth_init_board): Add support for configuring sun9i (A80) for Ethernet support in RGMII mode. * arch/arm/include/asm/arch-sunxi/gpio.h (SUN9I_GPA_GMAC): Define. * arch/arm/include/asm/arch-sunxi/clock_sun9i.h: Add Ethernet support for sun9i (A80), defining struct sunxi_sysctl_reg (which contains the GMAC clock control on sun9i) and AHB_{GATE,RESET}_OFFSET_GMAC * arch/arm/include/asm/arch-sunxi/cpu_sun9i.h(SUNXI_SYSCTL_BASE): Define. * arch/arm/dts/sun9i-a80.dtsi: add device-tree support for GMAC on sun9i (A80). --- arch/arm/dts/sun9i-a80.dtsi | 66 +++++++++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/clock_sun9i.h | 20 ++++++++ arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 1 + arch/arm/include/asm/arch-sunxi/gpio.h | 1 + 4 files changed, 88 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/sun9i-a80.dtsi b/arch/arm/dts/sun9i-a80.dtsi index f68b3242b3..f9e277015c 100644 --- a/arch/arm/dts/sun9i-a80.dtsi +++ b/arch/arm/dts/sun9i-a80.dtsi @@ -51,6 +51,10 @@ / { interrupt-parent = <&gic>; + aliases { + ethernet0 = &gmac; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -438,6 +442,37 @@ clocks = <&osc32k>, <&osc24M>; clock-output-names = "r_ir"; }; + + /* + * The following two are dummy clocks, placeholders + * used in the gmac_tx clock. The gmac driver will + * choose one parent depending on the PHY interface + * mode, using clk_set_rate auto-reparenting. + * + * The actual TX clock rate is not controlled by the + * gmac_tx clock. + */ + mii_phy_tx_clk: clk@1 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <25000000>; + clock-output-names = "mii_phy_tx"; + }; + + gmac_int_tx_clk: clk@2 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac_int_tx"; + }; + + gmac_tx_clk: clk@00800030 { + #clock-cells = <0>; + compatible = "allwinner,sun9i-a80-gmac-clk"; + reg = <0x00800030 0x4>; + clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>; + clock-output-names = "gmac_tx"; + }; }; soc { @@ -652,6 +687,23 @@ reg = <0x060005b4 0x4>; }; + gmac: ethernet@00830000 { + compatible = "allwinner,sun7i-a20-gmac"; + reg = <0x00830000 0x1054>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&ahb1_gates 17>, <&gmac_tx_clk>; + clock-names = "stmmaceth", "allwinner_gmac_tx"; + resets = <&ahb1_resets 17>; + reset-names = "stmmaceth"; + snps,pbl = <2>; + snps,fixed-burst; + snps,force_sf_dma_mode; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + timer@06000c00 { compatible = "allwinner,sun4i-a10-timer"; reg = <0x06000c00 0xa0>; @@ -724,6 +776,20 @@ allwinner,drive = ; allwinner,pull = ; }; + + gmac_pins_rgmii_a: gmac_rgmii@0 { + allwinner,pins = "PA0", "PA1", "PA2", "PA3", + "PA9", "PA10", + "PA12", "PA13", "PA19", + "PA20", "PA25", "PA26", "PA27"; + allwinner,function = "gmac"; + /* + * data lines in RGMII mode use DDR mode + * and need a higher signal drive strength + */ + allwinner,drive = ; + allwinner,pull = ; + }; }; uart0: serial@07000000 { diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h index 810313c5c3..1e73d7dd6a 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h @@ -96,6 +96,15 @@ struct sunxi_ccm_reg { u32 apb1_reset_cfg; /* 0x5b4 Bus Software Reset Register 4 */ }; +struct sunxi_sysctl_reg { + u8 reserved1[0x24]; /* 0x00 */ + u32 version; /* 0x24 system version (and boot select) */ + u8 reserved2[0x8]; /* 0x28 */ + u32 gmac_clk_cfg; /* 0x30 GMAC clock control */ + u8 reserved3[0x4]; /* 0x34 */ + u32 disp_mux_cfg; /* 0x38 display MUX control */ +}; + /* pll4_periph0_cfg */ #define PLL4_CFG_DEFAULT 0x90002800 /* 960 MHz */ @@ -116,6 +125,7 @@ struct sunxi_ccm_reg { #define CCM_MMC_CTRL_ENABLE (1 << 31) /* ahb_gate0 fields */ +#define AHB_GATE_OFFSET_GMAC 17 #define AHB_GATE_OFFSET_MCTL 14 /* On sun9i all sdc-s share their ahb gate, so ignore (x) */ @@ -132,6 +142,7 @@ struct sunxi_ccm_reg { #define APB1_GATE_TWI_MASK (0xf << APB1_GATE_TWI_SHIFT) /* ahb_reset0_cfg fields */ +#define AHB_RESET_OFFSET_GMAC 17 #define AHB_RESET_OFFSET_MCTL 14 /* On sun9i all sdc-s share their ahb reset, so ignore (x) */ @@ -143,6 +154,15 @@ struct sunxi_ccm_reg { #define APB1_RESET_TWI_SHIFT 0 #define APB1_RESET_TWI_MASK (0xf << APB1_RESET_TWI_SHIFT) +/* gmac_clk_cfg (in SYSCTL) fields ... these need to be misnamed as CCM_GMAC_CTRL + so we can reuse the same code as for sun6i in board/sunxi/gmac.c */ +#define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 +#define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 +#define CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII 0x2 +#define CCM_GMAC_CTRL_GPIT_MII (0x0 << 2) +#define CCM_GMAC_CTRL_GPIT_RGMII (0x1 << 2) +#define CCM_GMAC_CTRL_RX_CLK_DELAY(x) ((x) << 5) +#define CCM_GMAC_CTRL_TX_CLK_DELAY(x) ((x) << 10) #ifndef __ASSEMBLY__ unsigned int clock_get_pll4_periph0(void); diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h index 8ace4e7cb0..ec37bb9afb 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h @@ -47,6 +47,7 @@ #define SUNXI_DRAM_PHY1_BASE (REGS_AHB0_BASE + 0x66000) /* AHB1 Module */ +#define SUNXI_SYSCTL_BASE (REGS_AHB1_BASE + 0x000000) #define SUNXI_DMA_BASE (REGS_AHB1_BASE + 0x002000) #define SUNXI_USBOTG_BASE (REGS_AHB1_BASE + 0x100000) #define SUNXI_USBEHCI0_BASE (REGS_AHB1_BASE + 0x200000) diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 98c00d84aa..46ca759255 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -145,6 +145,7 @@ enum sunxi_gpio_number { #define SUNXI_GPA_EMAC 2 #define SUN6I_GPA_GMAC 2 #define SUN7I_GPA_GMAC 5 +#define SUN9I_GPA_GMAC 2 #define SUN6I_GPA_SDC2 5 #define SUN6I_GPA_SDC3 4 #define SUN8I_H3_GPA_UART0 2 -- cgit v1.2.3