linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Multiple Mantis devices gives me glitches
@ 2011-12-12 22:39 Vidar Tyldum
  2011-12-13  7:48 ` Ninja
  2011-12-13 16:55 ` Vidar Tyldum
  0 siblings, 2 replies; 8+ messages in thread
From: Vidar Tyldum @ 2011-12-12 22:39 UTC (permalink / raw)
  To: linux-media

Hello,

I have three  Cinergy C (DVB-C cards) like this:
05:04.0 Multimedia controller: Twinhan Technology Co. Ltd Mantis DTV PCI
Bridge Controller [Ver 1.0] (rev 01)
        Subsystem: TERRATEC Electronic GmbH Device 1178
        Flags: bus master, medium devsel, latency 128, IRQ 20
        Memory at fdcfe000 (32-bit, prefetchable) [size=4K]
        Kernel driver in use: Mantis
        Kernel modules: mantis

Kernel: 2.6.38-13-generic-pae (Ubuntu Natty stock)
Motherboard: P43-ES3G
CPU: Intel(R) Core(TM)2 Quad CPU    Q8400

At some point i started having glitches (I would from time to time get an
'old' frame displayed and sometimes audio noise when this happened). I tried
pretty much every trick I could find:
 * CPU affinity
 * Dedicated IRQ for each card (only shared with USB, which has no units
attached)
 * Various process priorities (also for the kdvb-processes)
 * pci latency (from 0x20 to 0xff)

I have quite decent results when I only have 2 DVB cards present, and the
results became even better when running the irqbalancer-dæmon as well.
The glitches are not completely gone, but much more manageble now.

So the problem seems to be caused by too many interrupts for my system to
handle, however this is where I am in over my head.

I know 2.6.38 isn't the freshest brew, but I could not find any changes to
the driver since then that seemed relevant (which could just be my lack of
source-fu).

So, any ideas on how to improve the performance? I am suffering from some
hardware incompatibility or is the driver this resource hungry?



-- 
Vidar Tyldum
                              vidar@tyldum.com               PGP: 0x3110AA98

^ permalink raw reply	[flat|nested] 8+ messages in thread
* Re: Multiple Mantis devices gives me glitches
@ 2011-12-13  7:31 Marko Ristola
  2011-12-13 13:55 ` Vidar Tyldum
  2011-12-13 18:11 ` Vidar Tyldum
  0 siblings, 2 replies; 8+ messages in thread
From: Marko Ristola @ 2011-12-13  7:31 UTC (permalink / raw)
  To: vidar; +Cc: Linux Media Mailing List


Hi

Here is a patch that went into Linus GIT this year.
It reduces the number of DMA transfer interrupts into one third.
Linus released 2.6.38.8 doesn't seem to have this patch yet.

I had a single Mantis card and a single CPU.
I used VDR to deliver HDTV channel via network
into a faster computer for viewing.

One known latency point with Mantis is I2C transfer.
With my measure, latency is about 0.33ms per I2C transfer byte.
Basic read / write (address+value) minimal latency is thus 0.66ms.
Latency amount depends on I2C bus speed on the card.
I don't have a working patch to fix this yet though.

Regards, Marko Ristola

-----------------------------------------------------------------------

Refactor Mantis DMA transfer to deliver 16Kb TS data per interrupt


https://patchwork.kernel.org/patch/107036/

With VDR streaming HDTV into network, generating an interrupt once per 16kb,
implemented in this patch, seems to support more robust throughput with HDTV.

Fix leaking almost 64kb data from the previous TS after changing the TS.
One effect of the old version was, that the DMA transfer and driver's
DMA buffer access might happen at the same time - a race condition.

Signed-off-by: Marko M. Ristola <marko.ristola@kolumbus.fi>

Regards,
Marko Ristola

diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 09e9fc7..3b7e376 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -126,7 +126,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
  	}
  	if (stat & MANTIS_INT_RISCI) {
  		dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
-		mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
+		mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
  		tasklet_schedule(&mantis->tasklet);
  	}
  	if (stat & MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index cf4b39f..8f048d5 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -134,7 +134,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
  	}
  	if (stat & MANTIS_INT_RISCI) {
  		dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
-		mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
+		mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
  		tasklet_schedule(&mantis->tasklet);
  	}
  	if (stat & MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h
index d0b645a..23b23b7 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -122,11 +122,8 @@ struct mantis_pci {
  	unsigned int		num;
  
  	/*	RISC Core		*/
-	u32			finished_block;
+	u32			busy_block;
  	u32			last_block;
-	u32			line_bytes;
-	u32			line_count;
-	u32			risc_pos;
  	u8			*buf_cpu;
  	dma_addr_t		buf_dma;
  	u32			*risc_cpu;
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
index 46202a4..c61ca7d 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -43,13 +43,17 @@
  #define RISC_IRQ		(0x01 << 24)
  
  #define RISC_STATUS(status)	((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16))
-#define RISC_FLUSH()		(mantis->risc_pos = 0)
-#define RISC_INSTR(opcode)	(mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode))
+#define RISC_FLUSH(risc_pos)		(risc_pos = 0)
+#define RISC_INSTR(risc_pos, opcode)	(mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode))
  
  #define MANTIS_BUF_SIZE		(64 * 1024)
-#define MANTIS_BLOCK_BYTES	(MANTIS_BUF_SIZE >> 4)
-#define MANTIS_BLOCK_COUNT	(1 << 4)
-#define MANTIS_RISC_SIZE	PAGE_SIZE
+#define MANTIS_BLOCK_BYTES      (MANTIS_BUF_SIZE / 4)
+#define MANTIS_DMA_TR_BYTES     (2 * 1024) /* upper limit: 4095 bytes. */
+#define MANTIS_BLOCK_COUNT	(MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES)
+
+#define MANTIS_DMA_TR_UNITS     (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES)
+/* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */
+#define MANTIS_RISC_SIZE	PAGE_SIZE /* RISC program must fit here. */
  
  int mantis_dma_exit(struct mantis_pci *mantis)
  {
@@ -124,27 +128,6 @@ err:
  	return -ENOMEM;
  }
  
-static inline int mantis_calc_lines(struct mantis_pci *mantis)
-{
-	mantis->line_bytes = MANTIS_BLOCK_BYTES;
-	mantis->line_count = MANTIS_BLOCK_COUNT;
-
-	while (mantis->line_bytes > 4095) {
-		mantis->line_bytes >>= 1;
-		mantis->line_count <<= 1;
-	}
-
-	dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]",
-		MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count);
-
-	if (mantis->line_count > 255) {
-		dprintk(MANTIS_ERROR, 1, "Buffer size error");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
  int mantis_dma_init(struct mantis_pci *mantis)
  {
  	int err = 0;
@@ -158,12 +141,6 @@ int mantis_dma_init(struct mantis_pci *mantis)
  
  		goto err;
  	}
-	err = mantis_calc_lines(mantis);
-	if (err < 0) {
-		dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed");
-
-		goto err;
-	}
  
  	return 0;
  err:
@@ -174,31 +151,32 @@ EXPORT_SYMBOL_GPL(mantis_dma_init);
  static inline void mantis_risc_program(struct mantis_pci *mantis)
  {
  	u32 buf_pos = 0;
-	u32 line;
+	u32 line, step;
+	u32 risc_pos;
  
  	dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program");
-	RISC_FLUSH();
-
-	dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u",
-		mantis->line_count, mantis->line_bytes);
-
-	for (line = 0; line < mantis->line_count; line++) {
-		dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line);
-		if (!(buf_pos % MANTIS_BLOCK_BYTES)) {
-			RISC_INSTR(RISC_WRITE	|
-				   RISC_IRQ	|
-				   RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) +
-				   (MANTIS_BLOCK_COUNT - 1)) %
-				    MANTIS_BLOCK_COUNT) |
-				    mantis->line_bytes);
-		} else {
-			RISC_INSTR(RISC_WRITE	| mantis->line_bytes);
-		}
-		RISC_INSTR(mantis->buf_dma + buf_pos);
-		buf_pos += mantis->line_bytes;
+	RISC_FLUSH(risc_pos);
+
+	dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u",
+		MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES);
+
+	for (line = 0; line < MANTIS_BLOCK_COUNT; line++) {
+		for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) {
+			dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step);
+			if (step == 0) {
+				RISC_INSTR(risc_pos, RISC_WRITE	|
+					   RISC_IRQ	|
+					   RISC_STATUS(line) |
+					   MANTIS_DMA_TR_BYTES);
+			} else {
+				RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES);
+			}
+			RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos);
+			buf_pos += MANTIS_DMA_TR_BYTES;
+		  }
  	}
-	RISC_INSTR(RISC_JUMP);
-	RISC_INSTR(mantis->risc_dma);
+	RISC_INSTR(risc_pos, RISC_JUMP);
+	RISC_INSTR(risc_pos, mantis->risc_dma);
  }
  
  void mantis_dma_start(struct mantis_pci *mantis)
@@ -210,7 +188,7 @@ void mantis_dma_start(struct mantis_pci *mantis)
  	mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
  
  	mmwrite(0, MANTIS_DMA_CTL);
-	mantis->last_block = mantis->finished_block = 0;
+	mantis->last_block = mantis->busy_block = 0;
  
  	mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK);
  
@@ -245,9 +223,9 @@ void mantis_dma_xfer(unsigned long data)
  	struct mantis_pci *mantis = (struct mantis_pci *) data;
  	struct mantis_hwconfig *config = mantis->hwconfig;
  
-	while (mantis->last_block != mantis->finished_block) {
+	while (mantis->last_block != mantis->busy_block) {
  		dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
-			mantis->last_block, mantis->finished_block);
+			mantis->last_block, mantis->busy_block);
  
  		(config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
  		(&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES);


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-12-14 18:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-12 22:39 Multiple Mantis devices gives me glitches Vidar Tyldum
2011-12-13  7:48 ` Ninja
2011-12-13 16:55 ` Vidar Tyldum
  -- strict thread matches above, loose matches on Subject: below --
2011-12-13  7:31 Marko Ristola
2011-12-13 13:55 ` Vidar Tyldum
2011-12-13 18:11 ` Vidar Tyldum
2011-12-13 21:56   ` Marko Ristola
2011-12-14 18:23     ` Vidar Tyldum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).