作者
QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118
SRA
SRA初始化SRIO代码,
for (i = 0; i < port_num; i++)
if (fsl_srio_port_connected(sriodev) & (0x1 << i)) {
fsl_srio_set_obwin(sriodev, i, 1,
port_data[i].port_info.range_start,
SRIO_SYS_ADDR, LAWAR_SIZE_2M);
fsl_srio_set_ibwin(sriodev, i, 1,
port_data[i].phys.write_recv_data,
SRIO_SYS_ADDR, LAWAR_SIZE_2M);
fsl_srio_set_seg_num(sriodev, i, 1, 0);
fsl_srio_set_subseg_num(sriodev, i, 1, 0);
}
初始化Outbound ATMU属性,
if (i < ARRAY_SIZE(srio_test_win_attrv) - 2)
fsl_srio_set_obwin_attr(sriodev, port, 1, 0,
srio_test_win_attrv[i]);
else if (i == 3)
fsl_srio_set_obwin_attr(sriodev, port, 1,
srio_test_win_attrv[i],
0);
读属性主要是NREAD,SRA的Test只测试了NREAD,RDTYP=4,写类型主要是SWRITE,NWRITE,NWRITE_R,WDTYP=3,4,5,SRA的Test对SWRITE,NWRITE,NWRITE_R进行了测试,当使用memcopy或DMA访问某段内存命中SRIO的窗,数据将会以对应的包类型发送出去,
上述核心代码的实现,
/* This function sets the outbound window protocol type attributes */
int fsl_srio_set_obwin_attr(struct srio_dev *sriodev, uint8_t port_id,
uint8_t win_id, uint32_t rd_attr, uint32_t wr_attr)
{
struct rio_atmu *atmu;
if (!sriodev || win_id >= SRIO_OB_WIN_NUM ||
port_id >= SRIO_PORT_MAX_NUM)
return -EINVAL;
atmu = &sriodev->rio_regs->atmu;
out_be32(&atmu->port[port_id].outbw[win_id].rowar,
(in_be32(&atmu->port[port_id].outbw[win_id].rowar)
& ~SRIO_ROWAR_WR_MASK) |
(rd_attr << SRIO_ROWAR_RDTYP_SHIFT) |
(wr_attr << SRIO_ROWAR_WRTYP_SHIFT));
return 0;
}
/* This function initializes the outbound window all parameters */
int fsl_srio_set_obwin(struct srio_dev *sriodev, uint8_t port_id,
uint8_t win_id, uint64_t ob_win_phys,
uint64_t ob_win_sys, size_t win_size)
{
struct rio_atmu *atmu;
if (!sriodev || win_id >= SRIO_OB_WIN_NUM ||
port_id >= SRIO_PORT_MAX_NUM)
return -EINVAL;
atmu = &sriodev->rio_regs->atmu;
out_be32(&atmu->port[port_id].outbw[win_id].rowbar,
ob_win_phys >> SRIO_ADDR_SHIFT);
out_be32(&atmu->port[port_id].outbw[win_id].rowtar,
ob_win_sys >> SRIO_ADDR_SHIFT);
out_be32(&atmu->port[port_id].outbw[win_id].rowtear, 0);
out_be32(&atmu->port[port_id].outbw[win_id].rowar,
(in_be32(&atmu->port[port_id].outbw[win_id].rowar) &
~SRIO_ROWBAR_SIZE_MASK) | SRIO_ROWAR_EN_WIN | win_size);
return 0;
}
/* This function initializes the inbound window all parameters */
int fsl_srio_set_ibwin(struct srio_dev *sriodev, uint8_t port_id,
uint8_t win_id, uint64_t ib_win_phys,
uint64_t ib_win_sys, size_t win_size)
{
struct rio_atmu *atmu;
if (!sriodev || win_id >= SRIO_IB_WIN_NUM ||
port_id >= SRIO_PORT_MAX_NUM)
return -EINVAL;
atmu = &sriodev->rio_regs->atmu;
out_be32(&atmu->port[port_id].inbw[win_id].riwbar,
ib_win_sys >> SRIO_ADDR_SHIFT);
out_be32(&atmu->port[port_id].inbw[win_id].riwtar,
ib_win_phys >> SRIO_ADDR_SHIFT);
out_be32(&atmu->port[port_id].inbw[win_id].riwar,
SRIO_RIWAR_MEM | win_size);
return 0;
}
/* This function sets the number of segments divided from a srio port window.
* The parameter - seg_num. seg_num can be 1/2/4
*/
int fsl_srio_set_seg_num(struct srio_dev *sriodev, uint8_t port_id,
uint8_t win_id, uint8_t seg_num)
{
struct rio_atmu *atmu;
uint32_t nseg = 0;
if (!sriodev || (win_id > SRIO_IB_WIN_NUM) ||
(seg_num > SRIO_MAX_SEG_NUM))
return -EINVAL;
atmu = &sriodev->rio_regs->atmu;
if (seg_num)
nseg = (uint32_t)log2(seg_num);
else
nseg = 0;
out_be32(&atmu->port[port_id].outbw[win_id].rowar,
(in_be32(&atmu->port[port_id].outbw[win_id].rowar) &
~SRIO_ROWAR_NSEG_MASK) | (nseg << SRIO_ROWAR_NSGE_SHIFT));
return 0;
}
/* This function sets the number of sub segments divided from a segment.
The paremeter - subseg_num can be 1/2/4/8 */
int fsl_srio_set_subseg_num(struct srio_dev *sriodev, uint8_t port_id,
uint8_t win_id, uint8_t subseg_num)
{
struct rio_atmu *atmu;
uint32_t nsseg = 0;
if (!sriodev || (win_id > SRIO_IB_WIN_NUM) ||
(subseg_num > SRIO_MAX_SUBSEG_NUM))
return -EINVAL;
atmu = &sriodev->rio_regs->atmu;
if (subseg_num)
nsseg = (uint32_t)log2(subseg_num);
else
nsseg = 0;
out_be32(&atmu->port[port_id].outbw[win_id].rowar,
(in_be32(&atmu->port[port_id].outbw[win_id].rowar) &
~SRIO_ROWAR_NSSEG_MASK) | (nsseg << SRIO_ROWAR_NSSEG_SHIFT));
return 0;
}