Skip to content

Commit d2f192f

Browse files
committed
Merge branch 'spinler-feat-i440-i2c' into 'devel'
feat: enable to have custom QSFP I2C controller on cards without dedicated QSFP I2C pins See merge request ndk/ndk-fpga!217
2 parents 4580ea6 + feb7b58 commit d2f192f

File tree

9 files changed

+242
-172
lines changed

9 files changed

+242
-172
lines changed

cards/bittware/ia-440i/config/card_const.tcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set DMA_MODULES 1
2727
set QSFP_CAGES 1
2828
# I2C address of each QSFP cage
2929
set QSFP_I2C_ADDR(0) "0xA0"
30+
set QSFP_I2C_CUSTOM_CTRLS [list "i2c_bmc"]
3031

3132
# ------------------------------------------------------------------------------
3233
# Checking of parameter compatibility

cards/bittware/ia-440i/src/DevTree.tcl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,11 @@ proc dts_card_specific {base} {
1212
append ret "reg = <$base 0x44>;"
1313
append ret "version = <0x00000003>;"
1414
append ret "};"
15+
16+
append ret "i2c_bmc: i2c_controller {"
17+
append ret "compatible = \"bittware,bmc\";"
18+
append ret "reg = <[expr $base + 256] 0x44>;"
19+
append ret "version = <0x00000003>;"
20+
append ret "};"
1521
return $ret
1622
}

cards/bittware/ia-440i/src/fpga.vhd

Lines changed: 173 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -231,20 +231,33 @@ architecture FULL of FPGA is
231231
constant AMM_FREQ_KHZ : natural := 400000;
232232

233233
constant QSFP_PORTS : natural := 1;
234+
constant DEVICE : string := "AGILEX";
235+
236+
constant bmc_mi_addr_base : slv_array_t(2-1 downto 0)(32-1 downto 0) := (X"00000100", X"00000000");
234237

235238
signal status_led_g : std_logic_vector(STATUS_LEDS-1 downto 0);
236239
signal status_led_r : std_logic_vector(STATUS_LEDS-1 downto 0);
237240

238241
signal bmc_mi_clk : std_logic;
239242
signal bmc_mi_reset : std_logic;
240-
signal bmc_mi_dwr : std_logic_vector(32-1 downto 0);
241-
signal bmc_mi_addr : std_logic_vector(32-1 downto 0);
242-
signal bmc_mi_rd : std_logic;
243-
signal bmc_mi_wr : std_logic;
244-
signal bmc_mi_be : std_logic_vector(4-1 downto 0);
245-
signal bmc_mi_drd : std_logic_vector(32-1 downto 0);
246-
signal bmc_mi_ardy : std_logic;
247-
signal bmc_mi_drdy : std_logic;
243+
244+
signal bmc_mi_addr : std_logic_vector(32-1 downto 0);
245+
signal bmc_mi_dwr : std_logic_vector(32-1 downto 0);
246+
signal bmc_mi_be : std_logic_vector(32/8-1 downto 0);
247+
signal bmc_mi_rd : std_logic;
248+
signal bmc_mi_wr : std_logic;
249+
signal bmc_mi_drd : std_logic_vector(32-1 downto 0);
250+
signal bmc_mi_ardy : std_logic;
251+
signal bmc_mi_drdy : std_logic;
252+
253+
signal axi_mi_addr : slv_array_t (2-1 downto 0)(32-1 downto 0);
254+
signal axi_mi_dwr : slv_array_t (2-1 downto 0)(32-1 downto 0);
255+
signal axi_mi_be : slv_array_t (2-1 downto 0)(32/8-1 downto 0);
256+
signal axi_mi_rd : std_logic_vector(2-1 downto 0);
257+
signal axi_mi_wr : std_logic_vector(2-1 downto 0);
258+
signal axi_mi_drd : slv_array_t (2-1 downto 0)(32-1 downto 0);
259+
signal axi_mi_ardy : std_logic_vector(2-1 downto 0);
260+
signal axi_mi_drdy : std_logic_vector(2-1 downto 0);
248261

249262
signal calbus_read : std_logic_vector(MEM_PORTS-1 downto 0);
250263
signal calbus_write : std_logic_vector(MEM_PORTS-1 downto 0);
@@ -279,36 +292,36 @@ architecture FULL of FPGA is
279292
signal qsfp_reset_n : std_logic_vector(QSFP_PORTS-1 downto 0);
280293
signal qsfp_lpmode : std_logic_vector(QSFP_PORTS-1 downto 0);
281294

282-
signal axi_awid : std_logic_vector(8-1 downto 0);
283-
signal axi_awaddr : std_logic_vector(8-1 downto 0);
284-
signal axi_awlen : std_logic_vector(8-1 downto 0);
285-
signal axi_awsize : std_logic_vector(3-1 downto 0);
286-
signal axi_awburst : std_logic_vector(2-1 downto 0);
287-
signal axi_awprot : std_logic_vector(3-1 downto 0);
288-
signal axi_awvalid : std_logic;
289-
signal axi_awready : std_logic;
290-
signal axi_wdata : std_logic_vector(32-1 downto 0);
291-
signal axi_wstrb : std_logic_vector((32/8)-1 downto 0);
292-
signal axi_wvalid : std_logic;
293-
signal axi_wready : std_logic;
294-
signal axi_bid : std_logic_vector(8-1 downto 0);
295-
signal axi_bresp : std_logic_vector(2-1 downto 0);
296-
signal axi_bvalid : std_logic;
297-
signal axi_bready : std_logic;
298-
signal axi_arid : std_logic_vector(8-1 downto 0);
299-
signal axi_araddr : std_logic_vector(8-1 downto 0);
300-
signal axi_arlen : std_logic_vector(8-1 downto 0);
301-
signal axi_arsize : std_logic_vector(3-1 downto 0);
302-
signal axi_arburst : std_logic_vector(2-1 downto 0);
303-
signal axi_arprot : std_logic_vector(3-1 downto 0);
304-
signal axi_arvalid : std_logic;
305-
signal axi_arready : std_logic;
306-
signal axi_rid : std_logic_vector(8-1 downto 0);
307-
signal axi_rdata : std_logic_vector(32-1 downto 0);
308-
signal axi_rresp : std_logic_vector(2-1 downto 0);
309-
signal axi_rlast : std_logic;
310-
signal axi_rvalid : std_logic;
311-
signal axi_rready : std_logic;
295+
signal axi_awid : slv_array_t(2-1 downto 0)(8-1 downto 0);
296+
signal axi_awaddr : slv_array_t(2-1 downto 0)(8-1 downto 0);
297+
signal axi_awlen : slv_array_t(2-1 downto 0)(8-1 downto 0);
298+
signal axi_awsize : slv_array_t(2-1 downto 0)(3-1 downto 0);
299+
signal axi_awburst : slv_array_t(2-1 downto 0)(2-1 downto 0);
300+
signal axi_awprot : slv_array_t(2-1 downto 0)(3-1 downto 0);
301+
signal axi_awvalid : std_logic_vector(2-1 downto 0);
302+
signal axi_awready : std_logic_vector(2-1 downto 0);
303+
signal axi_wdata : slv_array_t(2-1 downto 0)(32-1 downto 0);
304+
signal axi_wstrb : slv_array_t(2-1 downto 0)((32/8)-1 downto 0);
305+
signal axi_wvalid : std_logic_vector(2-1 downto 0);
306+
signal axi_wready : std_logic_vector(2-1 downto 0);
307+
signal axi_bid : slv_array_t(2-1 downto 0)(8-1 downto 0);
308+
signal axi_bresp : slv_array_t(2-1 downto 0)(2-1 downto 0);
309+
signal axi_bvalid : std_logic_vector(2-1 downto 0);
310+
signal axi_bready : std_logic_vector(2-1 downto 0);
311+
signal axi_arid : slv_array_t(2-1 downto 0)(8-1 downto 0);
312+
signal axi_araddr : slv_array_t(2-1 downto 0)(8-1 downto 0);
313+
signal axi_arlen : slv_array_t(2-1 downto 0)(8-1 downto 0);
314+
signal axi_arsize : slv_array_t(2-1 downto 0)(3-1 downto 0);
315+
signal axi_arburst : slv_array_t(2-1 downto 0)(2-1 downto 0);
316+
signal axi_arprot : slv_array_t(2-1 downto 0)(3-1 downto 0);
317+
signal axi_arvalid : std_logic_vector(2-1 downto 0);
318+
signal axi_arready : std_logic_vector(2-1 downto 0);
319+
signal axi_rid : slv_array_t(2-1 downto 0)(8-1 downto 0);
320+
signal axi_rdata : slv_array_t(2-1 downto 0)(32-1 downto 0);
321+
signal axi_rresp : slv_array_t(2-1 downto 0)(2-1 downto 0);
322+
signal axi_rlast : std_logic_vector(2-1 downto 0);
323+
signal axi_rvalid : std_logic_vector(2-1 downto 0);
324+
signal axi_rready : std_logic_vector(2-1 downto 0);
312325

313326
begin
314327

@@ -330,7 +343,7 @@ begin
330343

331344
QSFP_PORTS => QSFP_PORTS,
332345
QSFP_I2C_PORTS => 1,
333-
-- QSFP_I2C_TRISTATE => ??,
346+
QSFP_I2C_CTRL_EN => false,
334347

335348
STATUS_LEDS => STATUS_LEDS,
336349
MISC_IN_WIDTH => MISC_IN_WIDTH,
@@ -353,7 +366,7 @@ begin
353366
AMM_FREQ_KHZ => AMM_FREQ_KHZ,
354367

355368
BOARD => "IA-440I",
356-
DEVICE => "AGILEX"
369+
DEVICE => DEVICE
357370
)
358371
port map(
359372
SYSCLK => SYS_CLK_100M,
@@ -418,102 +431,140 @@ begin
418431
USER_LED_G <= status_led_g(0);
419432
USER_LED_R <= status_led_r(0);
420433

421-
mi2axi: entity work.MI2AXI4
434+
435+
mi_splitter_gls_i : entity work.MI_SPLITTER_PLUS_GEN
436+
generic map(
437+
ADDR_WIDTH => 32,
438+
DATA_WIDTH => 32,
439+
META_WIDTH => 0,
440+
PORTS => 2,
441+
PIPE_OUT => (others => false),
442+
ADDR_BASES => 2,
443+
ADDR_MASK => X"00000100",
444+
ADDR_BASE => bmc_mi_addr_base,
445+
DEVICE => DEVICE
446+
)
447+
port map(
448+
CLK => bmc_mi_clk,
449+
RESET => bmc_mi_reset,
450+
451+
RX_DWR => bmc_mi_dwr,
452+
RX_ADDR => bmc_mi_addr,
453+
RX_BE => bmc_mi_be,
454+
RX_RD => bmc_mi_rd,
455+
RX_WR => bmc_mi_wr,
456+
RX_ARDY => bmc_mi_ardy,
457+
RX_DRD => bmc_mi_drd,
458+
RX_DRDY => bmc_mi_drdy,
459+
460+
TX_DWR => axi_mi_dwr,
461+
TX_ADDR => axi_mi_addr,
462+
TX_BE => axi_mi_be,
463+
TX_RD => axi_mi_rd,
464+
TX_WR => axi_mi_wr,
465+
TX_ARDY => axi_mi_ardy,
466+
TX_DRD => axi_mi_drd,
467+
TX_DRDY => axi_mi_drdy
468+
);
469+
470+
mi2axi_g : for i in 0 to 2-1 generate
471+
mi2axi: entity work.MI2AXI4
422472
generic map(
423473
AXI_DATA_WIDTH => 32,
424474
ADDR_WIDTH => 8
425475
)
426476
port map(
427-
CLK => bmc_mi_clk,
428-
RESET => bmc_mi_reset,
429-
430-
MI_DWR => bmc_mi_dwr,
431-
MI_ADDR => bmc_mi_addr(7 downto 0),
432-
MI_RD => bmc_mi_rd,
433-
MI_WR => bmc_mi_wr,
434-
MI_BE => bmc_mi_be,
435-
MI_DRD => bmc_mi_drd,
436-
MI_ARDY => bmc_mi_ardy,
437-
MI_DRDY => bmc_mi_drdy,
438-
439-
AXI_AWID => axi_awid,
440-
AXI_AWADDR => axi_awaddr,
441-
AXI_AWLEN => axi_awlen,
442-
AXI_AWSIZE => axi_awsize,
443-
AXI_AWBURST => axi_awburst,
444-
AXI_AWPROT => axi_awprot,
445-
AXI_AWVALID => axi_awvalid,
446-
AXI_AWREADY => axi_awready,
447-
AXI_WDATA => axi_wdata,
448-
AXI_WSTRB => axi_wstrb,
449-
AXI_WVALID => axi_wvalid,
450-
AXI_WREADY => axi_wready,
451-
AXI_BID => axi_bid,
452-
AXI_BRESP => axi_bresp,
453-
AXI_BVALID => axi_bvalid,
454-
AXI_BREADY => axi_bready,
455-
AXI_ARID => axi_arid,
456-
AXI_ARADDR => axi_araddr,
457-
AXI_ARLEN => axi_arlen,
458-
AXI_ARSIZE => axi_arsize,
459-
AXI_ARBURST => axi_arburst,
460-
AXI_ARPROT => axi_arprot,
461-
AXI_ARVALID => axi_arvalid,
462-
AXI_ARREADY => axi_arready,
463-
AXI_RID => axi_rid,
464-
AXI_RDATA => axi_rdata,
465-
AXI_RRESP => axi_rresp,
466-
AXI_RLAST => axi_rlast,
467-
AXI_RVALID => axi_rvalid,
468-
AXI_RREADY => axi_rready
469-
);
477+
CLK => bmc_mi_clk,
478+
RESET => bmc_mi_reset,
479+
480+
MI_DWR => axi_mi_dwr(i),
481+
MI_ADDR => axi_mi_addr(i)(7 downto 0),
482+
MI_RD => axi_mi_rd(i),
483+
MI_WR => axi_mi_wr(i),
484+
MI_BE => axi_mi_be(i),
485+
MI_DRD => axi_mi_drd(i),
486+
MI_ARDY => axi_mi_ardy(i),
487+
MI_DRDY => axi_mi_drdy(i),
488+
489+
AXI_AWID => axi_awid(i),
490+
AXI_AWADDR => axi_awaddr(i),
491+
AXI_AWLEN => axi_awlen(i),
492+
AXI_AWSIZE => axi_awsize(i),
493+
AXI_AWBURST => axi_awburst(i),
494+
AXI_AWPROT => axi_awprot(i),
495+
AXI_AWVALID => axi_awvalid(i),
496+
AXI_AWREADY => axi_awready(i),
497+
AXI_WDATA => axi_wdata(i),
498+
AXI_WSTRB => axi_wstrb(i),
499+
AXI_WVALID => axi_wvalid(i),
500+
AXI_WREADY => axi_wready(i),
501+
AXI_BID => axi_bid(i),
502+
AXI_BRESP => axi_bresp(i),
503+
AXI_BVALID => axi_bvalid(i),
504+
AXI_BREADY => axi_bready(i),
505+
AXI_ARID => axi_arid(i),
506+
AXI_ARADDR => axi_araddr(i),
507+
AXI_ARLEN => axi_arlen(i),
508+
AXI_ARSIZE => axi_arsize(i),
509+
AXI_ARBURST => axi_arburst(i),
510+
AXI_ARPROT => axi_arprot(i),
511+
AXI_ARVALID => axi_arvalid(i),
512+
AXI_ARREADY => axi_arready(i),
513+
AXI_RID => axi_rid(i),
514+
AXI_RDATA => axi_rdata(i),
515+
AXI_RRESP => axi_rresp(i),
516+
AXI_RLAST => axi_rlast(i),
517+
AXI_RVALID => axi_rvalid(i),
518+
AXI_RREADY => axi_rready(i)
519+
);
520+
end generate;
470521

471522
bmc_3v0_top_i : entity work.bmc_3v0_top
472523
port map (
473524
-- Host0 AXI Interface - MCTP
474525
host0_aclk => bmc_mi_clk,
475526
host0_areset => bmc_mi_reset,
476-
host0_awaddr => axi_awaddr,
477-
host0_awvalid => axi_awvalid,
478-
host0_awready => axi_awready,
479-
host0_awprot => axi_awprot,
480-
host0_wdata => axi_wdata,
481-
host0_wstrb => axi_wstrb,
482-
host0_wvalid => axi_wvalid,
483-
host0_wready => axi_wready,
484-
host0_bresp => axi_bresp,
485-
host0_bvalid => axi_bvalid,
486-
host0_bready => axi_bready,
487-
host0_araddr => axi_araddr,
488-
host0_arvalid => axi_arvalid,
489-
host0_arready => axi_arready,
490-
host0_arprot => axi_arprot,
491-
host0_rdata => axi_rdata,
492-
host0_rresp => axi_rresp,
493-
host0_rvalid => axi_rvalid,
494-
host0_rready => axi_rready,
527+
host0_awaddr => axi_awaddr(0),
528+
host0_awvalid => axi_awvalid(0),
529+
host0_awready => axi_awready(0),
530+
host0_awprot => axi_awprot(0),
531+
host0_wdata => axi_wdata(0),
532+
host0_wstrb => axi_wstrb(0),
533+
host0_wvalid => axi_wvalid(0),
534+
host0_wready => axi_wready(0),
535+
host0_bresp => axi_bresp(0),
536+
host0_bvalid => axi_bvalid(0),
537+
host0_bready => axi_bready(0),
538+
host0_araddr => axi_araddr(0),
539+
host0_arvalid => axi_arvalid(0),
540+
host0_arready => axi_arready(0),
541+
host0_arprot => axi_arprot(0),
542+
host0_rdata => axi_rdata(0),
543+
host0_rresp => axi_rresp(0),
544+
host0_rvalid => axi_rvalid(0),
545+
host0_rready => axi_rready(0),
495546
-- Host1 AXI Interface - I2C
496547
host1_aclk => bmc_mi_clk,
497548
host1_areset => bmc_mi_reset,
498-
host1_awaddr => (others => '0'),
499-
host1_awvalid => '0',
500-
host1_awready => open,
501-
host1_awprot => (others=> '0'),
502-
host1_wdata => (others => '0'),
503-
host1_wstrb => (others => '0'),
504-
host1_wvalid => '0',
505-
host1_wready => open,
506-
host1_bresp => open,
507-
host1_bvalid => open,
508-
host1_bready => '1',
509-
host1_araddr => (others => '0'),
510-
host1_arvalid => '0',
511-
host1_arready => open,
512-
host1_arprot => (others => '0'),
513-
host1_rdata => open,
514-
host1_rresp => open,
515-
host1_rvalid => open,
516-
host1_rready => '1',
549+
host1_awaddr => axi_awaddr(1),
550+
host1_awvalid => axi_awvalid(1),
551+
host1_awready => axi_awready(1),
552+
host1_awprot => axi_awprot(1),
553+
host1_wdata => axi_wdata(1),
554+
host1_wstrb => axi_wstrb(1),
555+
host1_wvalid => axi_wvalid(1),
556+
host1_wready => axi_wready(1),
557+
host1_bresp => axi_bresp(1),
558+
host1_bvalid => axi_bvalid(1),
559+
host1_bready => axi_bready(1),
560+
host1_araddr => axi_araddr(1),
561+
host1_arvalid => axi_arvalid(1),
562+
host1_arready => axi_arready(1),
563+
host1_arprot => axi_arprot(1),
564+
host1_rdata => axi_rdata(1),
565+
host1_rresp => axi_rresp(1),
566+
host1_rvalid => axi_rvalid(1),
567+
host1_rready => axi_rready(1),
517568
-- Capability ROM AXI Interface
518569
cap_rom_aclk => bmc_mi_clk,
519570
cap_rom_areset => bmc_mi_reset,

core/comp/eth/network_mod/DevTree.tcl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# 11. qsfp_cages - number of QSFP cages
1212
# 12. QSFP_I2C_ADDR - array of integer, I2C address for all QSFP cages
1313
# 13. card_name - name of the card
14-
proc dts_network_mod { base_mac base_pcs base_pmd ports ETH_PORT_SPEED ETH_PORT_CHAN ETH_PORT_LANES ETH_PORT_RX_MTU ETH_PORT_TX_MTU eth_ip_name qsfp_cages QSFP_I2C_ADDR card_name} {
14+
proc dts_network_mod { base_mac base_pcs base_pmd ports ETH_PORT_SPEED ETH_PORT_CHAN ETH_PORT_LANES ETH_PORT_RX_MTU ETH_PORT_TX_MTU eth_ip_name qsfp_cages QSFP_I2C_ADDR card_name {i2c_custom_ctrls {}}} {
1515

1616
# use upvar to pass an array
1717
upvar $ETH_PORT_SPEED port_speed
@@ -40,9 +40,14 @@ proc dts_network_mod { base_mac base_pcs base_pmd ports ETH_PORT_SPEED ETH_PORT_
4040
set ret ""
4141

4242
for {set p 0} {$p < $qsfp_cages} {incr p} {
43-
append ret "i2c$p:" [dts_i2c $p [expr $base_pmd + $PMD_PORT_OFF * $p + 0x10]]
43+
set i2c_node [lindex $i2c_custom_ctrls $p]
44+
# generate I2C controller node by default
45+
if {$i2c_node eq {}} {
46+
set i2c_node "i2c$p"
47+
append ret "$i2c_node:" [dts_i2c $p [expr $base_pmd + $PMD_PORT_OFF * $p + 0x10]]
48+
}
4449
append ret "pmdctrl$p:" [dts_pmd_ctrl $p [expr $base_pmd + $PMD_PORT_OFF * $p + 0x1c]]
45-
append ret "pmd$p:" [dts_eth_transciever $p "QSFP" "pmdctrl$p" "i2c$p" $pmd_i2c_addr($p)]
50+
append ret "pmd$p:" [dts_eth_transciever $p "QSFP" "pmdctrl$p" $i2c_node $pmd_i2c_addr($p)]
4651
}
4752

4853
set ports_per_qsfp [expr $ports / $qsfp_cages]

0 commit comments

Comments
 (0)