NXP(Freescale) QorIQ T2080 SRIO SRA程序分析

作者

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值