Example #1
0
/**
 * md_mic_dma_chan_unmask_intr - Unmask or enable interrupts
 * @chan: The DMA channel handle
 */
void md_mic_dma_chan_unmask_intr(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan)
{
	uint32_t dcar;
	uint32_t chan_num;
	CHECK_CHAN(chan);
	chan_num = chan->ch_num;

	dcar = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCAR);

	if (MIC_DMA_CHAN_MIC_OWNED == chan->owner)
		dcar &= ~SBOX_DCAR_IM0;
	else
		dcar &= ~SBOX_DCAR_IM1;

	md_mic_dma_write_mmio(dma_dev, chan_num, REG_DCAR, dcar);
	/*
	 * This read is completed only after previous write is completed.
	 * It guarantees that, interrupts has been acknowledged to SBOX DMA
	 * This read forces previous write to be commited in memory.
	 * This is the actual fix for HSD# 3497216 based on theoretical
	 * hypothesis that somehow previous write is not truly completed
	 * since for writes as long as transactions are accepted by SBOX
	 * ( not necessarily commited in memory) those write transactions
	 * reported as complete.
	 */
	dcar = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCAR);
}
Example #2
0
/**
 * md_mic_dma_chan_get_dstatwb_phys - Compute the value of the DSTAT write back
 * physical address.
 * @dma_dev: DMA device.
 * @chan: The DMA channel handle
 */
phys_addr_t md_mic_dma_chan_get_dstatwb_phys(struct mic_dma_device *dma_dev,
			struct md_mic_dma_chan *chan)
{
	uint32_t reg, chan_num;
	phys_addr_t phys;

	CHECK_CHAN(chan);
	chan_num = chan->ch_num;
	reg = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTATWB_HI);
	phys = reg;
	reg = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTATWB_LO);

	phys = phys << 32 | reg;
	return phys;
}
Example #3
0
/**
 * md_mic_dma_chan_get_desc_ring_phys - Compute the value of the descriptor ring
 * base physical address from the descriptor ring attributes register.
 * @dma_dev: DMA device.
 * @chan: The DMA channel handle
 */
phys_addr_t
md_mic_dma_chan_get_desc_ring_phys(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan)
{
	phys_addr_t phys, phys_hi;
	uint32_t phys_lo, chan_num, drar_hi;

	CHECK_CHAN(chan);
	chan_num = chan->ch_num;
	phys_lo = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_LO);
	drar_hi = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_HI);
	phys_hi = drar_hi_to_ba_bits(drar_hi);
	phys_hi |= drar_hi_to_smpt(drar_hi, chan_num) << 2;

	phys = phys_lo | (phys_hi << 32);
	return phys;
}
Example #4
0
void md_mic_dma_chan_set_dcherr(struct mic_dma_device *dma_dev,
				struct md_mic_dma_chan *chan, uint32_t value)
{
	CHECK_CHAN(chan);
	md_mic_dma_write_mmio(dma_dev, chan->ch_num, REG_DCHERR, value);
	printk("dcherr = %d\n", md_mic_dma_read_mmio(dma_dev, chan->ch_num, REG_DCHERR));
}
Example #5
0
/**
 * md_mic_dma_chan_intr_pending - Reads interrupt status to figure out
 *                              if an interrupt is pending.
 * @chan: The DMA channel handle.
 */
bool md_mic_dma_chan_intr_pending(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan)
{
	uint32_t dcar;
	CHECK_CHAN(chan);

	dcar = md_mic_dma_read_mmio(dma_dev, chan->ch_num, REG_DCAR);
	return (dcar >> 26) & 0x1;
}
Example #6
0
/**
 * md_mic_dma_print_debug - Print channel debug information
 * @chan: The DMA channel handle
 * @sbuf: Print to an sbuf if not NULL else prints to console
 */
void md_mic_dma_print_debug(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan)
{
	uint32_t dcr;
	uint32_t dcar;
	uint32_t dtpr;
	uint32_t dhpr;
	uint32_t drar_lo;
	uint32_t drar_hi;
	uint32_t dstat;
	uint32_t chan_num = chan->ch_num;

	dcr  = mic_sbox_read_mmio(dma_dev->mm_sbox, SBOX_DCR);
	dcar = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCAR);
	dtpr = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DTPR);
	dhpr = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DHPR);
	drar_lo = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_LO);
	drar_hi = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_HI);
	dstat = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTAT);
	pr_debug(PR_PREFIX "Chan_Num 0x%x DCR 0x%x DCAR 0x%x DTPR 0x%x" 
			      "DHPR 0x%x DRAR_HI 0x%x DRAR_LO 0x%x DSTAT 0x%x\n", 
			      chan_num, dcr, dcar, dtpr, dhpr, drar_hi, drar_lo, dstat);
	pr_debug(PR_PREFIX "DCR 0x%x\n", dcr);
}
Example #7
0
static int mic_dma_reg_show(struct seq_file *m, void *v)
{
	int i, j, chan_num, size, dtpr;
	struct mic_dma_ctx_t *dma_ctx = m->private;
	struct mic_dma_device *dma_dev = &dma_ctx->dma_dev;
	struct dma_channel *curr_chan;
	union md_mic_dma_desc desc;

	seq_printf(m, "========================================"
				"=======================================\n");
	seq_printf(m, "SBOX_DCR: %#x\n",
				mic_sbox_read_mmio(dma_dev->mm_sbox, SBOX_DCR));
	seq_printf(m, "DMA Channel Registers\n");
	seq_printf(m, "========================================"
				"=======================================\n");
	seq_printf(m, "%-10s| %-10s %-10s %-10s %-10s %-10s %-10s"
#ifdef CONFIG_MK1OM
				  " %-10s %-11s %-14s %-10s"
#endif
				"\n", "Channel", "DCAR", "DTPR", "DHPR",
					"DRAR_HI", "DRAR_LO",
#ifdef CONFIG_MK1OM
					"DSTATWB_LO", "DSTATWB_HI", "DSTAT_CHERR", "DSTAT_CHERRMSK",
#endif
					"DSTAT");
	seq_printf(m, "========================================"
				"=======================================\n");

#ifdef _MIC_SCIF_
	for (i = 0; i < MAX_NUM_DMA_CHAN; i++) {
#else
	for (i = first_dma_chan(); i <= last_dma_chan(); i++) {
#endif
		curr_chan = &dma_ctx->dma_channels[i];
		chan_num = curr_chan->ch_num;
		seq_printf(m, "%-10i| %-#10x %-#10x %-#10x %-#10x"
			" %-#10x"
#ifdef CONFIG_MK1OM
			" %-#10x %-#11x %-#10x %-#14x"
#endif
			" %-#10x\n", chan_num,
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCAR),
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DTPR),
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DHPR),
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_HI),
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DRAR_LO),
#ifdef CONFIG_MK1OM
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTATWB_LO),
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTATWB_HI),
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCHERR),
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DCHERRMSK),
#endif
			md_mic_dma_read_mmio(dma_dev, chan_num, REG_DSTAT));
	}

	seq_printf(m, "\nDMA Channel Descriptor Rings\n");
	seq_printf(m, "========================================"
				"=======================================\n");

	for (i = first_dma_chan(); i <= last_dma_chan(); i++) {
		curr_chan = &dma_ctx->dma_channels[i];
		chan_num = curr_chan->ch_num;
		dtpr = md_mic_dma_read_mmio(dma_dev, chan_num, REG_DTPR);
		seq_printf(m,  "Channel %i: [", chan_num);
		size = ((int) md_mic_dma_read_mmio(dma_dev, chan_num, REG_DHPR)
			- dtpr) % curr_chan->chan->num_desc_in_ring;
		/*
		 * In KNC B0, empty condition is tail = head -1
		 */
		if (mic_hw_family(dma_ctx->device_num) == FAMILY_KNC &&
			mic_hw_stepping(dma_ctx->device_num) >= KNC_B0_STEP)
			size -= 1;

		for (j = 0; j < size; j++) {
			desc = curr_chan->desc_ring[(j+dtpr) % 
				curr_chan->chan->num_desc_in_ring];	

			switch (desc.desc.nop.type){
			case NOP:
				seq_printf(m," {Type: NOP, 0x%#llx"
					" %#llx} ",  desc.qwords.qw0,
						   desc.qwords.qw1);
			case MEMCOPY:
				seq_printf(m," {Type: MEMCOPY, SAP:"
					" 0x%#llx, DAP: %#llx, length: %#llx} ",
					  (uint64_t) desc.desc.memcopy.sap,
					  (uint64_t) desc.desc.memcopy.dap,
					  (uint64_t) desc.desc.memcopy.length);
				break;
			case STATUS:
				seq_printf(m," {Type: STATUS, data:"
					" 0x%#llx, DAP: %#llx, intr: %lli} ",
					(uint64_t) desc.desc.status.data,
					(uint64_t) desc.desc.status.dap,
					(uint64_t) desc.desc.status.intr);
				break;
			case GENERAL:
				seq_printf(m," {Type: GENERAL, "
					"DAP: %#llx, dword: %#llx} ",
					(uint64_t) desc.desc.general.dap,
					(uint64_t) desc.desc.general.data);
				break;
			case KEYNONCECNT:
				seq_printf(m," {Type: KEYNONCECNT, sel: "
					"%lli, h: %lli, index: %lli, cs: %lli,"
					" value: %#llx} ",
						(uint64_t) desc.desc.keynoncecnt.sel,
						(uint64_t) desc.desc.keynoncecnt.h,
						(uint64_t) desc.desc.keynoncecnt.index,
						(uint64_t) desc.desc.keynoncecnt.cs,
						(uint64_t) desc.desc.keynoncecnt.data);
				break;
			case KEY:
				seq_printf(m," {Type: KEY, dest_ind"
					   "ex: %lli, ski: %lli, skap: %#llx ",
						(uint64_t) desc.desc.key.di,
						(uint64_t) desc.desc.key.ski,
						(uint64_t) desc.desc.key.skap);
				break;
			default:
				seq_printf(m," {Uknown Type=%lli ,"
				 "%#llx %#llx} ",(uint64_t)  desc.desc.nop.type,
						(uint64_t) desc.qwords.qw0,
						(uint64_t) desc.qwords.qw1);
			}
		}
		seq_printf(m,  "]\n");
		if (mic_hw_family(dma_ctx->device_num) == FAMILY_KNC &&
		    mic_hw_stepping(dma_ctx->device_num) >= KNC_B0_STEP &&
		    curr_chan->chan->dstat_wb_loc)
			seq_printf(m, "DSTAT_WB = 0x%x\n",
				*((uint32_t*)curr_chan->chan->dstat_wb_loc));
	}
	return 0;
}

static int mic_dma_reg_open(struct inode *inode, struct file *file)
{
	return single_open(file, mic_dma_reg_show, PDE_DATA(inode));
}

static const struct file_operations mic_dma_reg_fops = {
	.owner   = THIS_MODULE,
	.open    = mic_dma_reg_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = single_release
};

static void
mic_dma_proc_init(struct mic_dma_ctx_t *dma_ctx)
{
	char name[64];
	snprintf(name, 63, "%s%d", proc_dma_ring, dma_ctx->device_num);
	proc_create_data(name,  S_IFREG | S_IRUGO, NULL, &mic_dma_ring_fops, dma_ctx);
	snprintf(name, 63, "%s%d", proc_dma_reg, dma_ctx->device_num);
	proc_create_data(name,  S_IFREG | S_IRUGO, NULL, &mic_dma_reg_fops, dma_ctx);
}
Example #8
0
uint32_t md_mic_dma_chan_read_tail(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan)
{
	CHECK_CHAN(chan);

	return md_mic_dma_read_mmio(dma_dev, chan->ch_num, REG_DTPR);
}
Example #9
0
uint32_t md_mic_dma_chan_get_dcherr(struct mic_dma_device *dma_dev,
				struct md_mic_dma_chan *chan)
{
	CHECK_CHAN(chan);
	return md_mic_dma_read_mmio(dma_dev, chan->ch_num, REG_DCHERR);
}
Example #10
0
uint32_t md_mic_dma_chan_read_completion_count(struct mic_dma_device *dma_dev, struct md_mic_dma_chan *chan)
{
	CHECK_CHAN(chan);

	return (md_mic_dma_read_mmio(dma_dev, chan->ch_num, REG_DSTAT) & 0xffff);
}