aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshish Chaudhari <ashish@ettus.com>2015-09-13 00:47:20 -0700
committerAshish Chaudhari <ashish@ettus.com>2015-09-16 17:21:52 -0700
commitde907d20e6f6f5b0fb6f3876126abdfcecc2fc67 (patch)
tree21538680428cf005b5f4791024c6e2ec439aa4ce
parentea52a8d8e71aae5cf341b72083575dda3c8f6353 (diff)
downloaduhd-de907d20e6f6f5b0fb6f3876126abdfcecc2fc67.tar.gz
uhd-de907d20e6f6f5b0fb6f3876126abdfcecc2fc67.tar.bz2
uhd-de907d20e6f6f5b0fb6f3876126abdfcecc2fc67.zip
x300: Added DMA FIFO support to X300
- Added HG vs HGS detection logic - Added DMA FIFO configuration code
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp68
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp11
-rw-r--r--host/lib/usrp/x300/x300_io_impl.cpp10
-rw-r--r--host/lib/usrp/x300/x300_regs.hpp4
4 files changed, 75 insertions, 18 deletions
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 1e424414e..cb13cdbb8 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -50,20 +50,34 @@ using namespace uhd::niusrprio;
using namespace uhd::usrp::x300;
namespace asio = boost::asio;
-/***********************************************************************
- * Discovery over the udp and pcie transport
- **********************************************************************/
+static bool has_dram_buff(wb_iface::sptr zpu_ctrl) {
+ bool dramR0 = dma_fifo_core_3000::check(
+ zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO0), SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO0));
+ bool dramR1 = dma_fifo_core_3000::check(
+ zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO1), SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO1));
+ return (dramR0 and dramR1);
+}
+
static std::string get_fpga_option(wb_iface::sptr zpu_ctrl) {
- //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM
- //HGS = {0:1G, 1:10G} w/ SRAM, XGS = {0:10G, 1:10G} w/ SRAM
+ //Possible options:
+ //1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/ DRAM
+ //1GS = {0:1G, 1:1G} w/ SRAM, HGS = {0:1G, 1:10G} w/ SRAM, XGS = {0:10G, 1:10G} w/ SRAM
- //In the default configuration, UHD does not support the HG and XG images so
- //they are never autodetected.
+ std::string option;
bool eth0XG = (zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_ETH_TYPE0)) == 0x1);
bool eth1XG = (zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_ETH_TYPE1)) == 0x1);
- return (eth0XG && eth1XG) ? "XGS" : (eth1XG ? "HGS" : "1G");
+ option = (eth0XG && eth1XG) ? "XG" : (eth1XG ? "HG" : "1G");
+
+ if (not has_dram_buff(zpu_ctrl)) {
+ option += "S";
+ }
+ return option;
}
+/***********************************************************************
+ * Discovery over the udp and pcie transport
+ **********************************************************************/
+
//@TODO: Refactor the find functions to collapse common code for ethernet and PCIe
static device_addrs_t x300_find_with_addr(const device_addr_t &hint)
{
@@ -729,6 +743,34 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
}
////////////////////////////////////////////////////////////////////
+ // DRAM FIFO initialization
+ ////////////////////////////////////////////////////////////////////
+ mb.has_dram_buff = has_dram_buff(mb.zpu_ctrl);
+ if (mb.has_dram_buff) {
+ for (size_t i = 0; i < mboard_members_t::NUM_RADIOS; i++) {
+ static const size_t NUM_REGS = 8;
+ mb.dram_buff_ctrl[i] = dma_fifo_core_3000::make(
+ mb.zpu_ctrl,
+ SR_ADDR(SET0_BASE, ZPU_SR_DRAM_FIFO0+(i*NUM_REGS)),
+ SR_ADDR(SET0_BASE, ZPU_RB_DRAM_FIFO0+i));
+ if (mb.dram_buff_ctrl[i]->ext_bist_supported()) {
+ UHD_MSG(status) << boost::format("Running BIST for DRAM FIFO %d... ") % i;
+ boost::uint32_t bisterr = mb.dram_buff_ctrl[i]->run_bist();
+ if (bisterr != 0) {
+ throw uhd::runtime_error(str(boost::format("DRAM FIFO BIST failed! (code: %d)\n") % bisterr));
+ } else {
+ double throughput = mb.dram_buff_ctrl[i]->get_bist_throughput(X300_BUS_CLOCK_RATE);
+ UHD_MSG(status) << (boost::format("pass (Throughput: %.1fMB/s)") % (throughput/1e6)) << std::endl;
+ }
+ } else {
+ if (mb.dram_buff_ctrl[i]->run_bist() != 0) {
+ throw uhd::runtime_error(str(boost::format("DRAM FIFO %d BIST failed! (code: %d)\n") % i));
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////
// setup radios
////////////////////////////////////////////////////////////////////
this->setup_radio(mb_i, "A", dev_addr);
@@ -940,7 +982,10 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con
perif.framer = rx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::RX_CTRL));
perif.ddc = rx_dsp_core_3000::make(perif.ctrl, radio::sr_addr(radio::RX_DSP));
perif.ddc->set_link_rate(10e9/8); //whatever
- perif.deframer = tx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_CTRL));
+ //The DRAM FIFO is treated as in internal radio FIFO for flow control purposes
+ tx_vita_core_3000::fc_monitor_loc fc_loc =
+ mb.has_dram_buff ? tx_vita_core_3000::FC_PRE_FIFO : tx_vita_core_3000::FC_PRE_RADIO;
+ perif.deframer = tx_vita_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_CTRL), fc_loc);
perif.duc = tx_dsp_core_3000::make(perif.ctrl, radio::sr_addr(radio::TX_DSP));
perif.duc->set_link_rate(10e9/8); //whatever
@@ -1143,7 +1188,7 @@ x300_impl::both_xports_t x300_impl::make_transport(
* connection type.*/
size_t eth_data_rec_frame_size = 0;
- if (mb.loaded_fpga_image == "HGS") {
+ if (mb.loaded_fpga_image.substr(0,2) == "HG") {
if (mb.router_dst_here == X300_XB_DST_E0) {
eth_data_rec_frame_size = X300_1GE_DATA_FRAME_MAX_SIZE;
_tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_1GIGE);
@@ -1151,7 +1196,7 @@ x300_impl::both_xports_t x300_impl::make_transport(
eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE;
_tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE);
}
- } else if (mb.loaded_fpga_image == "XGS") {
+ } else if (mb.loaded_fpga_image.substr(0,2) == "XG") {
eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE;
_tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE);
}
@@ -1314,7 +1359,6 @@ void x300_impl::set_tick_rate(mboard_members_t &mb, const double rate)
perif.time64->set_tick_rate(rate);
perif.framer->set_tick_rate(rate);
perif.ddc->set_tick_rate(rate);
- perif.deframer->set_tick_rate(rate);
perif.duc->set_tick_rate(rate);
}
}
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 1630047af..a71540e8b 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -41,6 +41,7 @@
#include "radio_ctrl_core_3000.hpp"
#include "rx_frontend_core_200.hpp"
#include "tx_frontend_core_200.hpp"
+#include "dma_fifo_core_3000.hpp"
#include "gpio_core_200.hpp"
#include <boost/weak_ptr.hpp>
#include <uhd/usrp/gps_ctrl.hpp>
@@ -56,8 +57,10 @@ static const std::string X300_FW_FILE_NAME = "usrp_x300_fw.bin";
static const double X300_DEFAULT_TICK_RATE = 200e6; //Hz
static const double X300_BUS_CLOCK_RATE = 166.666667e6; //Hz
-static const size_t X300_TX_HW_BUFF_SIZE = 520*1024; //512K SRAM buffer + 8K 2Clk FIFO
-static const size_t X300_TX_FC_RESPONSE_FREQ = 8; //per flow-control window
+static const size_t X300_TX_HW_BUFF_SIZE_SRAM = 520*1024; //512K SRAM buffer + 8K 2Clk FIFO
+static const size_t X300_TX_FC_RESPONSE_FREQ_SRAM = 8; //per flow-control window
+static const size_t X300_TX_HW_BUFF_SIZE_DRAM = 128*1024;
+static const size_t X300_TX_FC_RESPONSE_FREQ_DRAM = 32;
static const size_t X300_RX_SW_BUFF_SIZE_ETH = 0x2000000;//32MiB For an ~8k frame size any size >32MiB is just wasted buffer space
static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib
@@ -226,6 +229,10 @@ private:
return slot_name == "A" ? 0 : 1;
}
+ bool has_dram_buff;
+ dma_fifo_core_3000::sptr dram_buff_ctrl[NUM_RADIOS];
+
+
//other perifs on mboard
x300_clock_ctrl::sptr clock;
uhd::gps_ctrl::sptr gps;
diff --git a/host/lib/usrp/x300/x300_io_impl.cpp b/host/lib/usrp/x300/x300_io_impl.cpp
index e3515af0c..1356daec5 100644
--- a/host/lib/usrp/x300/x300_io_impl.cpp
+++ b/host/lib/usrp/x300/x300_io_impl.cpp
@@ -216,9 +216,10 @@ struct x300_tx_fc_guts_t
* FC credit we have is C = F + M - N (i.e. we can send C more packets
* before getting another ack).
*/
-static size_t get_tx_flow_control_window(size_t frame_size, const device_addr_t& tx_args)
+static size_t get_tx_flow_control_window(size_t frame_size, const bool dram_buff, const device_addr_t& tx_args)
{
- double hw_buff_size = tx_args.cast<double>("send_buff_size", X300_TX_HW_BUFF_SIZE);
+ double default_buff_size = dram_buff ? X300_TX_HW_BUFF_SIZE_DRAM : X300_TX_HW_BUFF_SIZE_SRAM;
+ double hw_buff_size = tx_args.cast<double>("send_buff_size", default_buff_size);
size_t window_in_pkts = (static_cast<size_t>(hw_buff_size) / frame_size);
if (window_in_pkts == 0) {
throw uhd::value_error("send_buff_size must be larger than the send_frame_size.");
@@ -580,8 +581,9 @@ tx_streamer::sptr x300_impl::get_tx_stream(const uhd::stream_args_t &args_)
perif.duc->setup(args);
//flow control setup
- size_t fc_window = get_tx_flow_control_window(xport.send->get_send_frame_size(), device_addr); //In packets
- const size_t fc_handle_window = std::max<size_t>(1, fc_window/X300_TX_FC_RESPONSE_FREQ);
+ size_t fc_window = get_tx_flow_control_window(xport.send->get_send_frame_size(), mb.has_dram_buff, device_addr); //In packets
+ const size_t fc_handle_window = std::max<size_t>(1,
+ fc_window/ (mb.has_dram_buff ? X300_TX_FC_RESPONSE_FREQ_DRAM : X300_TX_FC_RESPONSE_FREQ_SRAM));
UHD_LOG << "TX Flow Control Window = " << fc_window << ", TX Flow Control Handler Window = " << fc_handle_window << std::endl;
diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp
index eba30abb5..7173c0660 100644
--- a/host/lib/usrp/x300/x300_regs.hpp
+++ b/host/lib/usrp/x300/x300_regs.hpp
@@ -77,6 +77,8 @@ localparam ZPU_SR_XB_LOCAL = 03;
localparam ZPU_SR_SPI = 32;
localparam ZPU_SR_ETHINT0 = 40;
localparam ZPU_SR_ETHINT1 = 56;
+localparam ZPU_SR_DRAM_FIFO0 = 72;
+localparam ZPU_SR_DRAM_FIFO1 = 80;
//reset bits
#define ZPU_SR_SW_RST_ETH_PHY (1<<0)
@@ -89,6 +91,8 @@ localparam ZPU_RB_CLK_STATUS = 3;
localparam ZPU_RB_COMPAT_NUM = 6;
localparam ZPU_RB_ETH_TYPE0 = 4;
localparam ZPU_RB_ETH_TYPE1 = 5;
+localparam ZPU_RB_DRAM_FIFO0 = 10;
+localparam ZPU_RB_DRAM_FIFO1 = 11;
//spi slaves on radio
#define DB_DAC_SEN (1 << 7)