// SPDX-License-Identifier: GPL-2.0-or-later /* * Driver for the NXP SAA7164 PCIe bridge * * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
*/
#include <linux/slab.h>
#include"saa7164.h"
/* The PCI address space for buffer handling looks like this: * * +-u32 wide-------------+ * | + * +-u64 wide------------------------------------+ * + + * +----------------------+ * | CurrentBufferPtr + Pointer to current PCI buffer >-+ * +----------------------+ | * | Unused + | * +----------------------+ | * | Pitch + = 188 (bytes) | * +----------------------+ | * | PCI buffer size + = pitch * number of lines (312) | * +----------------------+ | * |0| Buf0 Write Offset + | * +----------------------+ v * |1| Buf1 Write Offset + | * +----------------------+ | * |2| Buf2 Write Offset + | * +----------------------+ | * |3| Buf3 Write Offset + | * +----------------------+ | * ... More write offsets | * +---------------------------------------------+ | * +0| set of ptrs to PCI pagetables + | * +---------------------------------------------+ | * +1| set of ptrs to PCI pagetables + <--------+ * +---------------------------------------------+ * +2| set of ptrs to PCI pagetables + * +---------------------------------------------+ * +3| set of ptrs to PCI pagetables + >--+ * +---------------------------------------------+ | * ... More buffer pointers | +----------------+ * +->| pt[0] TS data | * | +----------------+ * | * | +----------------+ * +->| pt[1] TS data | * | +----------------+ * | etc
*/
/* Allocate a new buffer structure and associated PCI space in bytes. * len must be a multiple of sizeof(u64)
*/ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
u32 len)
{ struct tmHWStreamParameters *params = &port->hw_streamingparams; struct saa7164_buffer *buf = NULL; struct saa7164_dev *dev = port->dev; int i;
buf->pt_cpu = dma_alloc_coherent(&port->dev->pci->dev, buf->pt_size,
&buf->pt_dma, GFP_KERNEL); if (!buf->pt_cpu) goto fail2;
/* init the buffers to a known pattern, easier during debugging */
memset(buf->cpu, 0xff, buf->pci_size);
buf->crc = crc32(0, buf->cpu, buf->actual_size);
memset(buf->pt_cpu, 0xff, buf->pt_size);
/* Write a buffer into the hardware */ int saa7164_buffer_activate(struct saa7164_buffer *buf, int i)
{ struct saa7164_port *port = buf->port; struct saa7164_dev *dev = port->dev;
if ((i < 0) || (i >= port->hwcfg.buffercount)) return -EINVAL;
/* Poke the buffers and offsets into PCI space */
mutex_lock(&port->dmaqueue_lock);
list_for_each_safe(c, n, &port->dmaqueue.list) {
buf = list_entry(c, struct saa7164_buffer, list);
BUG_ON(buf->flags != SAA7164_BUFFER_FREE);
/* Place the buffer in the h/w queue */
saa7164_buffer_activate(buf, i);
/* Don't exceed the device maximum # bufs */
BUG_ON(i > port->hwcfg.buffercount);
i++;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.