Пример #1
0
void mite_dma_disarm(struct mite_channel *mite_chan)
{
	struct mite_struct *mite = mite_chan->mite;
	unsigned chor;

	/* disarm */
	chor = CHOR_ABORT;
	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
}
Пример #2
0
void mite_dump_regs(struct mite_channel *mite_chan)
{
    unsigned long mite_io_addr =
        (unsigned long)mite_chan->mite->mite_io_addr;
    unsigned long addr = 0;
    unsigned long temp = 0;

    printk(KERN_DEBUG "mite_dump_regs ch%i\n", mite_chan->channel);
    printk(KERN_DEBUG "mite address is  =0x%08lx\n", mite_io_addr);

    addr = mite_io_addr + MITE_CHOR(channel);
    printk(KERN_DEBUG "mite status[CHOR]at 0x%08lx =0x%08lx\n", addr,
           temp = readl(addr));
    mite_decode(mite_CHOR_strings, temp);
    addr = mite_io_addr + MITE_CHCR(channel);
    printk(KERN_DEBUG "mite status[CHCR]at 0x%08lx =0x%08lx\n", addr,
           temp = readl(addr));
    mite_decode(mite_CHCR_strings, temp);
    addr = mite_io_addr + MITE_TCR(channel);
    printk(KERN_DEBUG "mite status[TCR] at 0x%08lx =0x%08x\n", addr,
           readl(addr));
    addr = mite_io_addr + MITE_MCR(channel);
    printk(KERN_DEBUG "mite status[MCR] at 0x%08lx =0x%08lx\n", addr,
           temp = readl(addr));
    mite_decode(mite_MCR_strings, temp);

    addr = mite_io_addr + MITE_MAR(channel);
    printk(KERN_DEBUG "mite status[MAR] at 0x%08lx =0x%08x\n", addr,
           readl(addr));
    addr = mite_io_addr + MITE_DCR(channel);
    printk(KERN_DEBUG "mite status[DCR] at 0x%08lx =0x%08lx\n", addr,
           temp = readl(addr));
    mite_decode(mite_DCR_strings, temp);
    addr = mite_io_addr + MITE_DAR(channel);
    printk(KERN_DEBUG "mite status[DAR] at 0x%08lx =0x%08x\n", addr,
           readl(addr));
    addr = mite_io_addr + MITE_LKCR(channel);
    printk(KERN_DEBUG "mite status[LKCR]at 0x%08lx =0x%08lx\n", addr,
           temp = readl(addr));
    mite_decode(mite_LKCR_strings, temp);
    addr = mite_io_addr + MITE_LKAR(channel);
    printk(KERN_DEBUG "mite status[LKAR]at 0x%08lx =0x%08x\n", addr,
           readl(addr));
    addr = mite_io_addr + MITE_CHSR(channel);
    printk(KERN_DEBUG "mite status[CHSR]at 0x%08lx =0x%08lx\n", addr,
           temp = readl(addr));
    mite_decode(mite_CHSR_strings, temp);
    addr = mite_io_addr + MITE_FCR(channel);
    printk(KERN_DEBUG "mite status[FCR] at 0x%08lx =0x%08x\n\n", addr,
           readl(addr));
}
Пример #3
0
void mite_dump_regs(struct mite_channel *mite_chan)
{
	void __iomem *mite_io_addr = mite_chan->mite->mite_io_addr;
	unsigned int offset;
	unsigned int value;
	int channel = mite_chan->channel;

	pr_debug("mite_dump_regs ch%i\n", channel);
	pr_debug("mite address is  =%p\n", mite_io_addr);

	offset = MITE_CHOR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[CHOR] at 0x%08x =0x%08x\n", offset, value);
	mite_decode(mite_CHOR_strings, value);
	offset = MITE_CHCR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[CHCR] at 0x%08x =0x%08x\n", offset, value);
	mite_decode(mite_CHCR_strings, value);
	offset = MITE_TCR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[TCR] at 0x%08x =0x%08x\n", offset, value);
	offset = MITE_MCR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[MCR] at 0x%08x =0x%08x\n", offset, value);
	mite_decode(mite_MCR_strings, value);
	offset = MITE_MAR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[MAR] at 0x%08x =0x%08x\n", offset, value);
	offset = MITE_DCR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[DCR] at 0x%08x =0x%08x\n", offset, value);
	mite_decode(mite_DCR_strings, value);
	offset = MITE_DAR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[DAR] at 0x%08x =0x%08x\n", offset, value);
	offset = MITE_LKCR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[LKCR] at 0x%08x =0x%08x\n", offset, value);
	mite_decode(mite_LKCR_strings, value);
	offset = MITE_LKAR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[LKAR] at 0x%08x =0x%08x\n", offset, value);
	offset = MITE_CHSR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[CHSR] at 0x%08x =0x%08x\n", offset, value);
	mite_decode(mite_CHSR_strings, value);
	offset = MITE_FCR(channel);
	value = readl(mite_io_addr + offset);
	pr_debug("mite status[FCR] at 0x%08x =0x%08x\n", offset, value);
}
Пример #4
0
void mite_dma_arm(struct mite_channel *mite_chan)
{
	struct mite_struct *mite = mite_chan->mite;
	int chor;
	unsigned long flags;

	MDPRINTK("mite_dma_arm ch%i\n", channel);
	smp_mb();
	
	chor = CHOR_START;
	spin_lock_irqsave(&mite->lock, flags);
	mite_chan->done = 0;
	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
	mmiowb();
	spin_unlock_irqrestore(&mite->lock, flags);
}
Пример #5
0
unsigned mite_get_status(struct mite_channel *mite_chan)
{
	struct mite_struct *mite = mite_chan->mite;
	unsigned status;
	unsigned long flags;

	comedi_spin_lock_irqsave(&mite->lock, flags);
	status = readl(mite->mite_io_addr + MITE_CHSR(mite_chan->channel));
	if (status & CHSR_DONE) {
		mite_chan->done = 1;
		writel(CHOR_CLRDONE,
			mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
	}
	mmiowb();
	comedi_spin_unlock_irqrestore(&mite->lock, flags);
	return status;
}
Пример #6
0
void ni_tio_handle_interrupt(struct ni_gpct *counter,
			     struct comedi_subdevice *s)
{
	unsigned cidx = counter->counter_index;
	unsigned gpct_mite_status;
	unsigned long flags;
	int gate_error;
	int tc_error;
	int perm_stale_data;

	ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
				       &perm_stale_data, NULL);
	if (gate_error) {
		dev_notice(counter->counter_dev->dev->class_dev,
			   "%s: Gi_Gate_Error detected.\n", __func__);
		s->async->events |= COMEDI_CB_OVERFLOW;
	}
	if (perm_stale_data)
		s->async->events |= COMEDI_CB_ERROR;
	switch (counter->counter_dev->variant) {
	case ni_gpct_variant_m_series:
	case ni_gpct_variant_660x:
		if (read_register(counter, NITIO_DMA_STATUS_REG(cidx)) &
		    Gi_DRQ_Error_Bit) {
			dev_notice(counter->counter_dev->dev->class_dev,
				   "%s: Gi_DRQ_Error detected.\n", __func__);
			s->async->events |= COMEDI_CB_OVERFLOW;
		}
		break;
	case ni_gpct_variant_e_series:
		break;
	}
	spin_lock_irqsave(&counter->lock, flags);
	if (counter->mite_chan == NULL) {
		spin_unlock_irqrestore(&counter->lock, flags);
		return;
	}
	gpct_mite_status = mite_get_status(counter->mite_chan);
	if (gpct_mite_status & CHSR_LINKC) {
		writel(CHOR_CLRLC,
		       counter->mite_chan->mite->mite_io_addr +
		       MITE_CHOR(counter->mite_chan->channel));
	}
	mite_sync_input_dma(counter->mite_chan, s->async);
	spin_unlock_irqrestore(&counter->lock, flags);
}
Пример #7
0
void mite_dma_arm(struct mite_channel *mite_chan)
{
	struct mite_struct *mite = mite_chan->mite;
	int chor;
	unsigned long flags;

	MDPRINTK("mite_dma_arm ch%i\n", channel);
	/* memory barrier is intended to insure any twiddling with the buffer
	   is done before writing to the mite to arm dma transfer */
	smp_mb();
	/* arm */
	chor = CHOR_START;
	comedi_spin_lock_irqsave(&mite->lock, flags);
	mite_chan->done = 0;
	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
	mmiowb();
	comedi_spin_unlock_irqrestore(&mite->lock, flags);
//      mite_dma_tcr(mite, channel);
}
Пример #8
0
void mite_prep_dma(struct mite_channel *mite_chan,
	unsigned int num_device_bits, unsigned int num_memory_bits)
{
	unsigned int chor, chcr, mcr, dcr, lkcr;
	struct mite_struct *mite = mite_chan->mite;

	MDPRINTK("mite_prep_dma ch%i\n", mite_chan->channel);

	/* reset DMA and FIFO */
	chor = CHOR_DMARESET | CHOR_FRESET;
	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));

	/* short link chaining mode */
	chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE |
		CHCR_BURSTEN;
	/*
	 * Link Complete Interrupt: interrupt every time a link
	 * in MITE_RING is completed. This can generate a lot of
	 * extra interrupts, but right now we update the values
	 * of buf_int_ptr and buf_int_count at each interrupt.  A
	 * better method is to poll the MITE before each user
	 * "read()" to calculate the number of bytes available.
	 */
	chcr |= CHCR_SET_LC_IE;
	if (num_memory_bits == 32 && num_device_bits == 16) {
		/* Doing a combined 32 and 16 bit byteswap gets the 16 bit samples into the fifo in the right order.
		   Tested doing 32 bit memory to 16 bit device transfers to the analog out of a pxi-6281,
		   which has mite version = 1, type = 4.  This also works for dma reads from the counters
		   on e-series boards.  */
		chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
	}
	if (mite_chan->dir == COMEDI_INPUT) {
		chcr |= CHCR_DEV_TO_MEM;
	}
	writel(chcr, mite->mite_io_addr + MITE_CHCR(mite_chan->channel));

	/* to/from memory */
	mcr = CR_RL(64) | CR_ASEQUP;
	switch (num_memory_bits) {
	case 8:
		mcr |= CR_PSIZE8;
		break;
	case 16:
		mcr |= CR_PSIZE16;
		break;
	case 32:
		mcr |= CR_PSIZE32;
		break;
	default:
		rt_printk
			("mite: bug! invalid mem bit width for dma transfer\n");
		break;
	}
	writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel));

	/* from/to device */
	dcr = CR_RL(64) | CR_ASEQUP;
	dcr |= CR_PORTIO | CR_AMDEVICE | CR_REQSDRQ(mite_chan->channel);
	switch (num_device_bits) {
	case 8:
		dcr |= CR_PSIZE8;
		break;
	case 16:
		dcr |= CR_PSIZE16;
		break;
	case 32:
		dcr |= CR_PSIZE32;
		break;
	default:
		rt_printk
			("mite: bug! invalid dev bit width for dma transfer\n");
		break;
	}
	writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel));

	/* reset the DAR */
	writel(0, mite->mite_io_addr + MITE_DAR(mite_chan->channel));

	/* the link is 32bits */
	lkcr = CR_RL(64) | CR_ASEQUP | CR_PSIZE32;
	writel(lkcr, mite->mite_io_addr + MITE_LKCR(mite_chan->channel));

	/* starting address for link chaining */
	writel(mite_chan->ring->descriptors_dma_addr,
		mite->mite_io_addr + MITE_LKAR(mite_chan->channel));

	MDPRINTK("exit mite_prep_dma\n");
}
Пример #9
0
int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
{
	unsigned long length;
	resource_size_t addr;
	int i;
	u32 csigr_bits;
	unsigned unknown_dma_burst_bits;

	if (comedi_pci_enable(mite->pcidev, "mite")) {
		printk("error enabling mite and requesting io regions\n");
		return -EIO;
	}
	pci_set_master(mite->pcidev);

	addr = pci_resource_start(mite->pcidev, 0);
	mite->mite_phys_addr = addr;
	mite->mite_io_addr = ioremap(addr, PCI_MITE_SIZE);
	if (!mite->mite_io_addr) {
		printk("failed to remap mite io memory address\n");
		return -ENOMEM;
	}
	printk("MITE:0x%08llx mapped to %p ",
		(unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);

	addr = pci_resource_start(mite->pcidev, 1);
	mite->daq_phys_addr = addr;
	length = pci_resource_len(mite->pcidev, 1);
	// In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output)
	mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
	if (!mite->daq_io_addr) {
		printk("failed to remap daq io memory address\n");
		return -ENOMEM;
	}
	printk("DAQ:0x%08llx mapped to %p\n",
		(unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);

	if (use_iodwbsr_1) {
		writel(0, mite->mite_io_addr + MITE_IODWBSR);
		printk("mite: using I/O Window Base Size register 1\n");
		writel(mite->
			daq_phys_addr | WENAB |
			MITE_IODWBSR_1_WSIZE_bits(length),
			mite->mite_io_addr + MITE_IODWBSR_1);
		writel(0, mite->mite_io_addr + MITE_IODWCR_1);
	} else {
		writel(mite->daq_phys_addr | WENAB,
			mite->mite_io_addr + MITE_IODWBSR);
	}
	/* make sure dma bursts work.  I got this from running a bus analyzer
	   on a pxi-6281 and a pxi-6713.  6713 powered up with register value
	   of 0x61f and bursts worked.  6281 powered up with register value of
	   0x1f and bursts didn't work.  The NI windows driver reads the register,
	   then does a bitwise-or of 0x600 with it and writes it back.
	 */
	unknown_dma_burst_bits =
		readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
	unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS;
	writel(unknown_dma_burst_bits,
		mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);

	csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
	mite->num_channels = mite_csigr_dmac(csigr_bits);
	if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
		printk("mite: bug? chip claims to have %i dma channels.  Setting to %i.\n", mite->num_channels, MAX_MITE_DMA_CHANNELS);
		mite->num_channels = MAX_MITE_DMA_CHANNELS;
	}
	dump_chip_signature(csigr_bits);
	for (i = 0; i < mite->num_channels; i++) {
		writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i));
		/* disable interrupts */
		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
			CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
			CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
			mite->mite_io_addr + MITE_CHCR(i));
	}
	mite->fifo_size = mite_fifo_size(mite, 0);
	printk("mite: fifo size is %i.\n", mite->fifo_size);
	mite->used = 1;

	return 0;
}
Пример #10
0
static irqreturn_t nidio_interrupt(int irq, void *d)
{
	struct comedi_device *dev = d;
	struct comedi_subdevice *s = dev->subdevices;
	struct comedi_async *async = s->async;
	struct mite_struct *mite = devpriv->mite;

	
	long int AuxData = 0;
	short data1 = 0;
	short data2 = 0;
	int flags;
	int status;
	int work = 0;
	unsigned int m_status = 0;
	unsigned long irq_flags;

	
	if (dev->attached == 0) {
		
		return IRQ_NONE;
	}

	status = readb(devpriv->mite->daq_io_addr +
		       Interrupt_And_Window_Status);
	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);

	DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
		status, flags);
	ni_pcidio_print_flags(flags);
	ni_pcidio_print_status(status);

	
	

	spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
	if (devpriv->di_mite_chan)
		m_status = mite_get_status(devpriv->di_mite_chan);
#ifdef MITE_DEBUG
	mite_print_chsr(m_status);
#endif
	
	
	if (m_status & CHSR_INT) {
		if (m_status & CHSR_LINKC) {
			writel(CHOR_CLRLC,
			       mite->mite_io_addr +
			       MITE_CHOR(devpriv->di_mite_chan->channel));
			mite_sync_input_dma(devpriv->di_mite_chan, s->async);
			
		}
		if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
				 CHSR_DRQ1 | CHSR_MRDY)) {
			DPRINTK("unknown mite interrupt, disabling IRQ\n");
			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
			disable_irq(dev->irq);
		}
	}
	spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);

	while (status & DataLeft) {
		work++;
		if (work > 20) {
			DPRINTK("too much work in interrupt\n");
			writeb(0x00,
			       devpriv->mite->daq_io_addr +
			       Master_DMA_And_Interrupt_Control);
			break;
		}

		flags &= IntEn;

		if (flags & TransferReady) {
			
			while (flags & TransferReady) {
				work++;
				if (work > 100) {
					DPRINTK("too much work in interrupt\n");
					writeb(0x00,
					       devpriv->mite->daq_io_addr +
					       Master_DMA_And_Interrupt_Control);
					goto out;
				}
				AuxData =
				    readl(devpriv->mite->daq_io_addr +
					  Group_1_FIFO);
				data1 = AuxData & 0xffff;
				data2 = (AuxData & 0xffff0000) >> 16;
				comedi_buf_put(async, data1);
				comedi_buf_put(async, data2);
				
				flags = readb(devpriv->mite->daq_io_addr +
					      Group_1_Flags);
			}
			
			
			
			
			async->events |= COMEDI_CB_BLOCK;
		}

		if (flags & CountExpired) {
			DPRINTK("CountExpired\n");
			writeb(ClearExpired,
			       devpriv->mite->daq_io_addr +
			       Group_1_Second_Clear);
			async->events |= COMEDI_CB_EOA;

			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
			break;
		} else if (flags & Waited) {
			DPRINTK("Waited\n");
			writeb(ClearWaited,
			       devpriv->mite->daq_io_addr +
			       Group_1_First_Clear);
			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
			break;
		} else if (flags & PrimaryTC) {
			DPRINTK("PrimaryTC\n");
			writeb(ClearPrimaryTC,
			       devpriv->mite->daq_io_addr +
			       Group_1_First_Clear);
			async->events |= COMEDI_CB_EOA;
		} else if (flags & SecondaryTC) {
			DPRINTK("SecondaryTC\n");
			writeb(ClearSecondaryTC,
			       devpriv->mite->daq_io_addr +
			       Group_1_First_Clear);
			async->events |= COMEDI_CB_EOA;
		}
#if 0
		else {
			printk("ni_pcidio: unknown interrupt\n");
			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
			writeb(0x00,
			       devpriv->mite->daq_io_addr +
			       Master_DMA_And_Interrupt_Control);
		}
#endif
		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
		status = readb(devpriv->mite->daq_io_addr +
			       Interrupt_And_Window_Status);
		
		
		
		
	}

out:
	ni_pcidio_event(dev, s);
#if 0
	if (!tag) {
		writeb(0x03,
		       devpriv->mite->daq_io_addr +
		       Master_DMA_And_Interrupt_Control);
	}
#endif
	return IRQ_HANDLED;
}
Пример #11
0
int mite_setup2(struct comedi_device *dev,
		struct mite_struct *mite, bool use_win1)
{
	unsigned long length;
	int i;
	u32 csigr_bits;
	unsigned unknown_dma_burst_bits;

	pci_set_master(mite->pcidev);

	mite->mite_io_addr = pci_ioremap_bar(mite->pcidev, 0);
	if (!mite->mite_io_addr) {
		dev_err(dev->class_dev,
			"Failed to remap mite io memory address\n");
		return -ENOMEM;
	}
	mite->mite_phys_addr = pci_resource_start(mite->pcidev, 0);

	dev->mmio = pci_ioremap_bar(mite->pcidev, 1);
	if (!dev->mmio) {
		dev_err(dev->class_dev,
			"Failed to remap daq io memory address\n");
		return -ENOMEM;
	}
	mite->daq_phys_addr = pci_resource_start(mite->pcidev, 1);
	length = pci_resource_len(mite->pcidev, 1);

	if (use_win1) {
		writel(0, mite->mite_io_addr + MITE_IODWBSR);
		dev_info(dev->class_dev,
			 "using I/O Window Base Size register 1\n");
		writel(mite->daq_phys_addr | WENAB |
		       MITE_IODWBSR_1_WSIZE_bits(length),
		       mite->mite_io_addr + MITE_IODWBSR_1);
		writel(0, mite->mite_io_addr + MITE_IODWCR_1);
	} else {
		writel(mite->daq_phys_addr | WENAB,
		       mite->mite_io_addr + MITE_IODWBSR);
	}
	/*
	 * Make sure dma bursts work. I got this from running a bus analyzer
	 * on a pxi-6281 and a pxi-6713. 6713 powered up with register value
	 * of 0x61f and bursts worked. 6281 powered up with register value of
	 * 0x1f and bursts didn't work. The NI windows driver reads the
	 * register, then does a bitwise-or of 0x600 with it and writes it back.
	 */
	unknown_dma_burst_bits =
	    readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
	unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS;
	writel(unknown_dma_burst_bits,
	       mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);

	csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
	mite->num_channels = mite_csigr_dmac(csigr_bits);
	if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
		dev_warn(dev->class_dev,
			 "mite: bug? chip claims to have %i dma channels. Setting to %i.\n",
			 mite->num_channels, MAX_MITE_DMA_CHANNELS);
		mite->num_channels = MAX_MITE_DMA_CHANNELS;
	}
	dump_chip_signature(csigr_bits);
	for (i = 0; i < mite->num_channels; i++) {
		writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i));
		/* disable interrupts */
		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
		       CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
		       CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
		       mite->mite_io_addr + MITE_CHCR(i));
	}
	mite->fifo_size = mite_fifo_size(mite, 0);
	dev_info(dev->class_dev, "fifo size is %i.\n", mite->fifo_size);
	return 0;
}
Пример #12
0
static irqreturn_t nidio_interrupt(int irq, void *d)
{
	struct comedi_device *dev = d;
	struct comedi_subdevice *s = dev->subdevices;
	struct comedi_async *async = s->async;
	struct mite_struct *mite = devpriv->mite;

	/* int i, j; */
	long int AuxData = 0;
	short data1 = 0;
	short data2 = 0;
	int flags;
	int status;
	int work = 0;
	unsigned int m_status = 0;
	unsigned long irq_flags;

	/* interrupcions parasites */
	if (dev->attached == 0) {
		/* assume it's from another card */
		return IRQ_NONE;
	}

	status = readb(devpriv->mite->daq_io_addr +
		       Interrupt_And_Window_Status);
	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);

	DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
		status, flags);
	ni_pcidio_print_flags(flags);
	ni_pcidio_print_status(status);

	/* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */
	/* printk("buf[4096]=%08x\n",
	       *(unsigned int *)(async->prealloc_buf+4096)); */

	spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
	if (devpriv->di_mite_chan)
		m_status = mite_get_status(devpriv->di_mite_chan);
#ifdef MITE_DEBUG
	mite_print_chsr(m_status);
#endif
	/* printk("mite_bytes_transferred: %d\n",
	       mite_bytes_transferred(mite,DI_DMA_CHAN)); */

	/* mite_dump_regs(mite); */
	if (m_status & CHSR_INT) {
		if (m_status & CHSR_LINKC) {
			writel(CHOR_CLRLC,
			       mite->mite_io_addr +
			       MITE_CHOR(devpriv->di_mite_chan->channel));
			mite_sync_input_dma(devpriv->di_mite_chan, s->async);
			/* XXX need to byteswap */
		}
		if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
				 CHSR_DRQ1 | CHSR_MRDY)) {
			DPRINTK("unknown mite interrupt, disabling IRQ\n");
			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
			disable_irq(dev->irq);
		}
	}
	spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);

	while (status & DataLeft) {
		work++;
		if (work > 20) {
			DPRINTK("too much work in interrupt\n");
			writeb(0x00,
			       devpriv->mite->daq_io_addr +
			       Master_DMA_And_Interrupt_Control);
			break;
		}

		flags &= IntEn;

		if (flags & TransferReady) {
			/* DPRINTK("TransferReady\n"); */
			while (flags & TransferReady) {
				work++;
				if (work > 100) {
					DPRINTK("too much work in interrupt\n");
					writeb(0x00,
					       devpriv->mite->daq_io_addr +
					       Master_DMA_And_Interrupt_Control
					      );
					goto out;
				}
				AuxData =
				    readl(devpriv->mite->daq_io_addr +
					  Group_1_FIFO);
				data1 = AuxData & 0xffff;
				data2 = (AuxData & 0xffff0000) >> 16;
				comedi_buf_put(async, data1);
				comedi_buf_put(async, data2);
				/* DPRINTK("read:%d, %d\n",data1,data2); */
				flags = readb(devpriv->mite->daq_io_addr +
					      Group_1_Flags);
			}
			/* DPRINTK("buf_int_count: %d\n",
				async->buf_int_count); */
			/* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
				IntEn,flags,status); */
			/* ni_pcidio_print_flags(flags); */
			/* ni_pcidio_print_status(status); */
			async->events |= COMEDI_CB_BLOCK;
		}

		if (flags & CountExpired) {
			DPRINTK("CountExpired\n");
			writeb(ClearExpired,
			       devpriv->mite->daq_io_addr +
			       Group_1_Second_Clear);
			async->events |= COMEDI_CB_EOA;

			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
			break;
		} else if (flags & Waited) {
			DPRINTK("Waited\n");
			writeb(ClearWaited,
			       devpriv->mite->daq_io_addr +
			       Group_1_First_Clear);
			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
			break;
		} else if (flags & PrimaryTC) {
			DPRINTK("PrimaryTC\n");
			writeb(ClearPrimaryTC,
			       devpriv->mite->daq_io_addr +
			       Group_1_First_Clear);
			async->events |= COMEDI_CB_EOA;
		} else if (flags & SecondaryTC) {
			DPRINTK("SecondaryTC\n");
			writeb(ClearSecondaryTC,
			       devpriv->mite->daq_io_addr +
			       Group_1_First_Clear);
			async->events |= COMEDI_CB_EOA;
		}
#if 0
		else {
			printk("ni_pcidio: unknown interrupt\n");
			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
			writeb(0x00,
			       devpriv->mite->daq_io_addr +
			       Master_DMA_And_Interrupt_Control);
		}
#endif
		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
		status = readb(devpriv->mite->daq_io_addr +
			       Interrupt_And_Window_Status);
		/* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
			"status=0x%02x\n", IntEn, flags, status); */
		/* ni_pcidio_print_flags(flags); */
		/* ni_pcidio_print_status(status); */
	}

out:
	ni_pcidio_event(dev, s);
#if 0
	if (!tag) {
		writeb(0x03,
		       devpriv->mite->daq_io_addr +
		       Master_DMA_And_Interrupt_Control);
	}
#endif
	return IRQ_HANDLED;
}
Пример #13
0
void mite_prep_dma(struct mite_channel *mite_chan,
		   unsigned int num_device_bits, unsigned int num_memory_bits)
{
	unsigned int chor, chcr, mcr, dcr, lkcr;
	struct mite_struct *mite = mite_chan->mite;

	MDPRINTK("mite_prep_dma ch%i\n", mite_chan->channel);

	
	chor = CHOR_DMARESET | CHOR_FRESET;
	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));

	
	chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE |
	    CHCR_BURSTEN;
	chcr |= CHCR_SET_LC_IE;
	if (num_memory_bits == 32 && num_device_bits == 16) {
		chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
	}
	if (mite_chan->dir == COMEDI_INPUT)
		chcr |= CHCR_DEV_TO_MEM;

	writel(chcr, mite->mite_io_addr + MITE_CHCR(mite_chan->channel));

	
	mcr = CR_RL(64) | CR_ASEQUP;
	switch (num_memory_bits) {
	case 8:
		mcr |= CR_PSIZE8;
		break;
	case 16:
		mcr |= CR_PSIZE16;
		break;
	case 32:
		mcr |= CR_PSIZE32;
		break;
	default:
		printk(KERN_WARNING "mite: bug! invalid mem bit width for dma "
		       "transfer\n");
		break;
	}
	writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel));

	
	dcr = CR_RL(64) | CR_ASEQUP;
	dcr |= CR_PORTIO | CR_AMDEVICE | CR_REQSDRQ(mite_chan->channel);
	switch (num_device_bits) {
	case 8:
		dcr |= CR_PSIZE8;
		break;
	case 16:
		dcr |= CR_PSIZE16;
		break;
	case 32:
		dcr |= CR_PSIZE32;
		break;
	default:
		printk(KERN_WARNING "mite: bug! invalid dev bit width for dma "
		       "transfer\n");
		break;
	}
	writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel));

	
	writel(0, mite->mite_io_addr + MITE_DAR(mite_chan->channel));

	
	lkcr = CR_RL(64) | CR_ASEQUP | CR_PSIZE32;
	writel(lkcr, mite->mite_io_addr + MITE_LKCR(mite_chan->channel));

	
	writel(mite_chan->ring->descriptors_dma_addr,
	       mite->mite_io_addr + MITE_LKAR(mite_chan->channel));

	MDPRINTK("exit mite_prep_dma\n");
}
Пример #14
0
int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
{
	unsigned long length;
	resource_size_t addr;
	int i;
	u32 csigr_bits;
	unsigned unknown_dma_burst_bits;

	if (comedi_pci_enable(mite->pcidev, "mite")) {
		printk(KERN_ERR "error enabling mite and requesting io regions\n");
		return -EIO;
	}
	pci_set_master(mite->pcidev);

	addr = pci_resource_start(mite->pcidev, 0);
	mite->mite_phys_addr = addr;
	mite->mite_io_addr = ioremap(addr, PCI_MITE_SIZE);
	if (!mite->mite_io_addr) {
		printk(KERN_ERR "Failed to remap mite io memory address\n");
		return -ENOMEM;
	}
	printk(KERN_INFO "MITE:0x%08llx mapped to %p ",
	       (unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);

	addr = pci_resource_start(mite->pcidev, 1);
	mite->daq_phys_addr = addr;
	length = pci_resource_len(mite->pcidev, 1);
	mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
	if (!mite->daq_io_addr) {
		printk(KERN_ERR "Failed to remap daq io memory address\n");
		return -ENOMEM;
	}
	printk(KERN_INFO "DAQ:0x%08llx mapped to %p\n",
	       (unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);

	if (use_iodwbsr_1) {
		writel(0, mite->mite_io_addr + MITE_IODWBSR);
		printk(KERN_INFO "mite: using I/O Window Base Size register 1\n");
		writel(mite->daq_phys_addr | WENAB |
		       MITE_IODWBSR_1_WSIZE_bits(length),
		       mite->mite_io_addr + MITE_IODWBSR_1);
		writel(0, mite->mite_io_addr + MITE_IODWCR_1);
	} else {
		writel(mite->daq_phys_addr | WENAB,
		       mite->mite_io_addr + MITE_IODWBSR);
	}
	unknown_dma_burst_bits =
	    readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
	unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS;
	writel(unknown_dma_burst_bits,
	       mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);

	csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
	mite->num_channels = mite_csigr_dmac(csigr_bits);
	if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
		printk(KERN_WARNING "mite: bug? chip claims to have %i dma "
		       "channels. Setting to %i.\n",
		       mite->num_channels, MAX_MITE_DMA_CHANNELS);
		mite->num_channels = MAX_MITE_DMA_CHANNELS;
	}
	dump_chip_signature(csigr_bits);
	for (i = 0; i < mite->num_channels; i++) {
		writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i));
		
		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
		       CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
		       CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
		       mite->mite_io_addr + MITE_CHCR(i));
	}
	mite->fifo_size = mite_fifo_size(mite, 0);
	printk(KERN_INFO "mite: fifo size is %i.\n", mite->fifo_size);
	mite->used = 1;

	return 0;
}