Skip to content

Commit 266875e

Browse files
ibirnbaumcarlescufi
authored andcommitted
drivers: ethernet: xlnx_gem: Zynq-7000 support for the Xilinx GEM driver
Add support for the Xilinx Zynq-7000 SoC family to this driver. This includes some SoC-specific register accesses when setting an updated TX clock divider, also, the device tree binding now supports higher MDC clock divisor values when the current target SoC is a Zynq rather than a ZynqMP. With regards to the use of this driver in a QEMU simulation of the Zynq-7000, the Kconfig file is modified so that the driver is not enabled unless QEMU networking is set to Ethernet mode. Signed-off-by: Immo Birnbaum <[email protected]>
1 parent f668474 commit 266875e

File tree

4 files changed

+84
-12
lines changed

4 files changed

+84
-12
lines changed

drivers/ethernet/Kconfig.xlnx_gem

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ DT_COMPAT_XLNX_GEM := xlnx,gem
1111
menuconfig ETH_XLNX_GEM
1212
bool "Xilinx GEM Ethernet driver"
1313
default $(dt_compat_enabled,$(DT_COMPAT_XLNX_GEM))
14-
depends on SOC_XILINX_ZYNQMP_RPU
14+
depends on SOC_XILINX_ZYNQMP_RPU || SOC_SERIES_XILINX_ZYNQ7000
15+
depends on !QEMU_TARGET || (QEMU_TARGET && NET_QEMU_ETHERNET)
1516
help
1617
Enable Xilinx GEM Ethernet driver.
1718

drivers/ethernet/eth_xlnx_gem.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,18 @@ static int eth_xlnx_gem_dev_init(const struct device *dev)
114114
"%s invalid max./nominal link speed value %u",
115115
dev->name, (uint32_t)dev_conf->max_link_speed);
116116

117-
/* MDC clock divider validity check */
117+
/* MDC clock divider validity check, SoC dependent */
118+
#if defined(CONFIG_SOC_XILINX_ZYNQMP)
118119
__ASSERT(dev_conf->mdc_divider <= MDC_DIVIDER_48,
119120
"%s invalid MDC clock divider value %u, must be in "
120121
"range 0 to %u", dev->name, dev_conf->mdc_divider,
121122
(uint32_t)MDC_DIVIDER_48);
123+
#elif defined(CONFIG_SOC_SERIES_XILINX_ZYNQ7000)
124+
__ASSERT(dev_conf->mdc_divider <= MDC_DIVIDER_224,
125+
"%s invalid MDC clock divider value %u, must be in "
126+
"range 0 to %u", dev->name, dev_conf->mdc_divider,
127+
(uint32_t)MDC_DIVIDER_224);
128+
#endif
122129

123130
/* AMBA AHB configuration options */
124131
__ASSERT((dev_conf->amba_dbus_width == AMBA_AHB_DBUS_WIDTH_32BIT ||
@@ -775,6 +782,7 @@ static void eth_xlnx_gem_configure_clocks(const struct device *dev)
775782
}
776783
}
777784

785+
#if defined(CONFIG_SOC_XILINX_ZYNQMP)
778786
/*
779787
* ZynqMP register crl_apb.GEMx_REF_CTRL:
780788
* RX_CLKACT bit [26]
@@ -808,6 +816,27 @@ static void eth_xlnx_gem_configure_clocks(const struct device *dev)
808816
if ((tmp & ETH_XLNX_CRL_APB_WPROT_BIT) > 0) {
809817
sys_write32(tmp, ETH_XLNX_CRL_APB_WPROT_REGISTER_ADDRESS);
810818
}
819+
# elif defined(CONFIG_SOC_SERIES_XILINX_ZYNQ7000)
820+
clk_ctrl_reg = sys_read32(dev_conf->clk_ctrl_reg_address);
821+
clk_ctrl_reg &= ~((ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK <<
822+
ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR0_SHIFT) |
823+
(ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK <<
824+
ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR1_SHIFT));
825+
clk_ctrl_reg |= ((div0 & ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK) <<
826+
ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR0_SHIFT) |
827+
((div1 & ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK) <<
828+
ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR1_SHIFT);
829+
830+
/*
831+
* SLCR must be unlocked prior to and locked after writing to
832+
* the clock configuration register.
833+
*/
834+
sys_write32(ETH_XLNX_SLCR_UNLOCK_KEY,
835+
ETH_XLNX_SLCR_UNLOCK_REGISTER_ADDRESS);
836+
sys_write32(clk_ctrl_reg, dev_conf->clk_ctrl_reg_address);
837+
sys_write32(ETH_XLNX_SLCR_LOCK_KEY,
838+
ETH_XLNX_SLCR_LOCK_REGISTER_ADDRESS);
839+
#endif /* CONFIG_SOC_XILINX_ZYNQMP / CONFIG_SOC_SERIES_XILINX_ZYNQ7000 */
811840

812841
LOG_DBG("%s set clock dividers div0/1 %u/%u for target "
813842
"frequency %u Hz", dev->name, div0, div1, target);

drivers/ethernet/eth_xlnx_gem_priv.h

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,30 @@
110110
#define ETH_XLNX_GEM_CKSUM_NOT_TCP_OR_UDP_ERROR 0x00000006
111111
#define ETH_XLNX_GEM_CKSUM_PREMATURE_END_ERROR 0x00000007
112112

113+
#if defined(CONFIG_SOC_SERIES_XILINX_ZYNQ7000)
113114
/*
114-
* TX clock configuration: comp.
115+
* Zynq-7000 TX clock configuration:
116+
*
117+
* SLCR unlock & lock registers, magic words:
118+
* comp. Zynq-7000 TRM, chapter B.28, registers SLCR_LOCK and SLCR_UNLOCK,
119+
* p. 1576f.
120+
*
121+
* GEMx_CLK_CTRL (SLCR) registers:
122+
* [25 .. 20] Reference clock divisor 1
123+
* [13 .. 08] Reference clock divisor 0
124+
* [00] Clock active bit
125+
*/
126+
#define ETH_XLNX_SLCR_LOCK_REGISTER_ADDRESS 0xF8000004
127+
#define ETH_XLNX_SLCR_UNLOCK_REGISTER_ADDRESS 0xF8000008
128+
#define ETH_XLNX_SLCR_LOCK_KEY 0x767B
129+
#define ETH_XLNX_SLCR_UNLOCK_KEY 0xDF0D
130+
#define ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK 0x0000003F
131+
#define ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR1_SHIFT 20
132+
#define ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR0_SHIFT 8
133+
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_CLKACT_BIT 0x02000000
134+
#elif defined(CONFIG_SOC_XILINX_ZYNQMP)
135+
/*
136+
* UltraScale TX clock configuration: comp.
115137
* https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
116138
*
117139
* CRL_WPROT (CRL_APB) register:
@@ -130,6 +152,7 @@
130152
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR0_SHIFT 8
131153
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_RX_CLKACT_BIT 0x04000000
132154
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_CLKACT_BIT 0x02000000
155+
#endif /* CONFIG_SOC_SERIES_XILINX_ZYNQ7000 || CONFIG_SOC_XILINX_ZYNQMP */
133156

134157
/*
135158
* Register offsets within the respective GEM's address space:
@@ -495,9 +518,15 @@ struct eth_xlnx_dma_area_gem##port {\
495518
};
496519

497520
/* DMA memory area instantiation macro */
521+
#ifdef CONFIG_SOC_SERIES_XILINX_ZYNQ7000
522+
#define ETH_XLNX_GEM_DMA_AREA_INST(port) \
523+
static struct eth_xlnx_dma_area_gem##port eth_xlnx_gem##port##_dma_area\
524+
__ocm_bss_section __aligned(4096);
525+
#else
498526
#define ETH_XLNX_GEM_DMA_AREA_INST(port) \
499-
static struct eth_xlnx_dma_area_gem##port eth_xlnx_gem##port##_dma_area \
527+
static struct eth_xlnx_dma_area_gem##port eth_xlnx_gem##port##_dma_area\
500528
__aligned(4096);
529+
#endif
501530

502531
/* Interrupt configuration function macro */
503532
#define ETH_XLNX_GEM_CONFIG_IRQ_FUNC(port) \
@@ -564,16 +593,23 @@ enum eth_xlnx_amba_dbus_width {
564593
* @brief MDC clock divider configuration enumeration type.
565594
*
566595
* Enumeration type containing the supported clock divider values
567-
* used to generate the MDIO interface clock (MDC) from the ZynqMP's
568-
* LPD LSBUS clock. This is a configuration item in the controller's
569-
* net_cfg register.
596+
* used to generate the MDIO interface clock (MDC) from either the
597+
* cpu_1x clock (Zynq-7000) or the LPD LSBUS clock (UltraScale).
598+
* This is a configuration item in the controller's net_cfg register.
570599
*/
571600
enum eth_xlnx_mdc_clock_divider {
572601
/* The values of this enum are consecutively numbered */
573602
MDC_DIVIDER_8 = 0,
574603
MDC_DIVIDER_16,
575604
MDC_DIVIDER_32,
576-
MDC_DIVIDER_48
605+
MDC_DIVIDER_48,
606+
#ifdef CONFIG_SOC_SERIES_XILINX_ZYNQ7000
607+
/* Dividers > 48 are only available in the Zynq-7000 */
608+
MDC_DIVIDER_64,
609+
MDC_DIVIDER_96,
610+
MDC_DIVIDER_128,
611+
MDC_DIVIDER_224
612+
#endif
577613
};
578614

579615
/**

include/dt-bindings/ethernet/xlnx_gem.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@
1010
#define XLNX_GEM_PHY_AUTO_DETECT 0
1111

1212
/* MDC divider values */
13-
#define XLNX_GEM_MDC_DIVIDER_8 0 /* LPD_LSBUS_CLK < 20 MHz */
14-
#define XLNX_GEM_MDC_DIVIDER_16 1 /* LPD_LSBUS_CLK 20 - 40 MHz */
15-
#define XLNX_GEM_MDC_DIVIDER_32 2 /* LPD_LSBUS_CLK 40 - 80 MHz */
13+
/* The following values are supported by both the Zynq-7000 and the ZynqMP */
14+
#define XLNX_GEM_MDC_DIVIDER_8 0 /* cpu_1x or LPD_LSBUS_CLK < 20 MHz */
15+
#define XLNX_GEM_MDC_DIVIDER_16 1 /* cpu_1x or LPD_LSBUS_CLK 20 - 40 MHz */
16+
#define XLNX_GEM_MDC_DIVIDER_32 2 /* cpu_1x or LPD_LSBUS_CLK 40 - 80 MHz */
1617
/*
1718
* According to the ZynqMP's gem.network_config register documentation,
1819
* divider /32 is to be used for a 100 MHz LPD LSBUS clock.
1920
*/
20-
#define XLNX_GEM_MDC_DIVIDER_48 3 /* LPD_LSBUS_CLK 80 - 120 MHz */
21+
/* The following values are supported by the Zynq-7000 only */
22+
#define XLNX_GEM_MDC_DIVIDER_48 3 /* cpu_1x 80 - 120 MHz */
23+
#define XLNX_GEM_MDC_DIVIDER_64 4 /* cpu_1x 120 - 160 MHz */
24+
#define XLNX_GEM_MDC_DIVIDER_96 5 /* cpu_1x 160 - 240 MHz */
25+
#define XLNX_GEM_MDC_DIVIDER_128 6 /* cpu_1x 240 - 320 MHz */
26+
#define XLNX_GEM_MDC_DIVIDER_224 7 /* cpu_1x 320 - 540 MHz */
2127

2228
/* Link speed values */
2329
#define XLNX_GEM_LINK_SPEED_10MBIT 1

0 commit comments

Comments
 (0)