示例#1
0
文件: fec.c 项目: CSCLOG/beaglebone
int
bcom_fec_tx_reset(struct bcom_task *tsk)
{
	struct bcom_fec_priv *priv = tsk->priv;
	struct bcom_fec_tx_var *var;
	struct bcom_fec_tx_inc *inc;

	/* Shutdown the task */
	bcom_disable_task(tsk->tasknum);

	/* Reset the microcode */
	var = (struct bcom_fec_tx_var *) bcom_task_var(tsk->tasknum);
	inc = (struct bcom_fec_tx_inc *) bcom_task_inc(tsk->tasknum);

	if (bcom_load_image(tsk->tasknum, bcom_fec_tx_task))
		return -1;

	var->enable	= bcom_eng->regs_base +
				offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
	var->fifo	= (u32) priv->fifo;
	var->DRD	= bcom_sram_va2pa(self_modified_drd(tsk->tasknum));
	var->bd_base	= tsk->bd_pa;
	var->bd_last	= tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
	var->bd_start	= tsk->bd_pa;

	inc->incr_bytes	= -(s16)sizeof(u32);	/* These should be in the   */
	inc->incr_src	= sizeof(u32);		/* task image, but we stick */
	inc->incr_src_ma= sizeof(u8);		/* to the official ones     */

	/* Reset the BDs */
	tsk->index = 0;
	tsk->outdex = 0;

	memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);

	/* Configure some stuff */
	bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_TX_BD_PRAGMA);
	bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);

	out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_TX], BCOM_IPR_FEC_TX);

	out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum);	/* Clear ints */

	return 0;
}
示例#2
0
int
bcom_gen_bd_tx_reset(struct bcom_task *tsk)
{
	struct bcom_gen_bd_priv *priv = tsk->priv;
	struct bcom_gen_bd_tx_var *var;
	struct bcom_gen_bd_tx_inc *inc;

	/* Shutdown the task */
	bcom_disable_task(tsk->tasknum);

	/* Reset the microcode */
	var = (struct bcom_gen_bd_tx_var *) bcom_task_var(tsk->tasknum);
	inc = (struct bcom_gen_bd_tx_inc *) bcom_task_inc(tsk->tasknum);

	if (bcom_load_image(tsk->tasknum, bcom_gen_bd_tx_task))
		return -1;

	var->enable	= bcom_eng->regs_base +
				offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
	var->fifo	= (u32) priv->fifo;
	var->bd_base	= tsk->bd_pa;
	var->bd_last	= tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
	var->bd_start	= tsk->bd_pa;

	inc->incr_bytes	= -(s16)sizeof(u32);
	inc->incr_src	= sizeof(u32);
	inc->incr_src_ma = sizeof(u8);

	/* Reset the BDs */
	tsk->index = 0;
	tsk->outdex = 0;

	memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);

	/* Configure some stuff */
	bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA);
	bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);

	out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
	bcom_set_initiator(tsk->tasknum, priv->initiator);

	out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum);	/* Clear ints */

	return 0;
}
int
bcom_load_image(int task, u32 *task_image)
{
	struct bcom_task_header *hdr = (struct bcom_task_header *)task_image;
	struct bcom_tdt *tdt;
	u32 *desc, *var, *inc;
	u32 *desc_src, *var_src, *inc_src;

	/* Safety checks */
	if (hdr->magic != BCOM_TASK_MAGIC) {
		printk(KERN_ERR DRIVER_NAME
			": Trying to load invalid microcode\n");
		return -EINVAL;
	}

	if ((task < 0) || (task >= BCOM_MAX_TASKS)) {
		printk(KERN_ERR DRIVER_NAME
			": Trying to load invalid task %d\n", task);
		return -EINVAL;
	}

	/* Initial load or reload */
	tdt = &bcom_eng->tdt[task];

	if (tdt->start) {
		desc = bcom_task_desc(task);
		if (hdr->desc_size != bcom_task_num_descs(task)) {
			printk(KERN_ERR DRIVER_NAME
				": Trying to reload wrong task image "
				"(%d size %d/%d)!\n",
				task,
				hdr->desc_size,
				bcom_task_num_descs(task));
			return -EINVAL;
		}
	} else {
		phys_addr_t start_pa;

		desc = bcom_sram_alloc(hdr->desc_size * sizeof(u32), 4, &start_pa);
		if (!desc)
			return -ENOMEM;

		tdt->start = start_pa;
		tdt->stop = start_pa + ((hdr->desc_size-1) * sizeof(u32));
	}

	var = bcom_task_var(task);
	inc = bcom_task_inc(task);

	/* Clear & copy */
	memset(var, 0x00, BCOM_VAR_SIZE);
	memset(inc, 0x00, BCOM_INC_SIZE);

	desc_src = (u32 *)(hdr + 1);
	var_src = desc_src + hdr->desc_size;
	inc_src = var_src + hdr->var_size;

	memcpy(desc, desc_src, hdr->desc_size * sizeof(u32));
	memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32));
	memcpy(inc, inc_src, hdr->inc_size * sizeof(u32));

	return 0;
}