0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009
0010 #include "saa7164.h"
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 void saa7164_buffer_display(struct saa7164_buffer *buf)
0056 {
0057 struct saa7164_dev *dev = buf->port->dev;
0058 int i;
0059
0060 dprintk(DBGLVL_BUF, "%s() buffer @ 0x%p nr=%d\n",
0061 __func__, buf, buf->idx);
0062 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08llx len = 0x%x\n",
0063 buf->cpu, (long long)buf->dma, buf->pci_size);
0064 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n",
0065 buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size);
0066
0067
0068 for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
0069
0070 dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
0071 i, buf->pt_cpu, (u64)*(buf->pt_cpu));
0072
0073 }
0074 }
0075
0076
0077
0078 struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
0079 u32 len)
0080 {
0081 struct tmHWStreamParameters *params = &port->hw_streamingparams;
0082 struct saa7164_buffer *buf = NULL;
0083 struct saa7164_dev *dev = port->dev;
0084 int i;
0085
0086 if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
0087 log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
0088 goto ret;
0089 }
0090
0091 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
0092 if (!buf)
0093 goto ret;
0094
0095 buf->idx = -1;
0096 buf->port = port;
0097 buf->flags = SAA7164_BUFFER_FREE;
0098 buf->pos = 0;
0099 buf->actual_size = params->pitch * params->numberoflines;
0100 buf->crc = 0;
0101
0102 buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
0103 buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
0104
0105
0106 buf->cpu = dma_alloc_coherent(&port->dev->pci->dev, buf->pci_size,
0107 &buf->dma, GFP_KERNEL);
0108 if (!buf->cpu)
0109 goto fail1;
0110
0111 buf->pt_cpu = dma_alloc_coherent(&port->dev->pci->dev, buf->pt_size,
0112 &buf->pt_dma, GFP_KERNEL);
0113 if (!buf->pt_cpu)
0114 goto fail2;
0115
0116
0117 memset(buf->cpu, 0xff, buf->pci_size);
0118 buf->crc = crc32(0, buf->cpu, buf->actual_size);
0119 memset(buf->pt_cpu, 0xff, buf->pt_size);
0120
0121 dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n",
0122 __func__, buf, params->numpagetables);
0123 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n",
0124 buf->cpu, (long)buf->dma, buf->pci_size);
0125 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
0126 buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
0127
0128
0129 for (i = 0 ; i < params->numpagetables; i++) {
0130
0131 *(buf->pt_cpu + i) = buf->dma + (i * 0x1000);
0132 dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
0133 i, buf->pt_cpu, (u64)*(buf->pt_cpu));
0134
0135 }
0136
0137 goto ret;
0138
0139 fail2:
0140 dma_free_coherent(&port->dev->pci->dev, buf->pci_size, buf->cpu,
0141 buf->dma);
0142 fail1:
0143 kfree(buf);
0144
0145 buf = NULL;
0146 ret:
0147 return buf;
0148 }
0149
0150 int saa7164_buffer_dealloc(struct saa7164_buffer *buf)
0151 {
0152 struct saa7164_dev *dev;
0153
0154 if (!buf || !buf->port)
0155 return SAA_ERR_BAD_PARAMETER;
0156 dev = buf->port->dev;
0157
0158 dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n",
0159 __func__, buf);
0160
0161 if (buf->flags != SAA7164_BUFFER_FREE)
0162 log_warn(" freeing a non-free buffer\n");
0163
0164 dma_free_coherent(&dev->pci->dev, buf->pci_size, buf->cpu, buf->dma);
0165 dma_free_coherent(&dev->pci->dev, buf->pt_size, buf->pt_cpu,
0166 buf->pt_dma);
0167
0168 kfree(buf);
0169
0170 return SAA_OK;
0171 }
0172
0173 int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i)
0174 {
0175 struct saa7164_dev *dev = port->dev;
0176
0177 if ((i < 0) || (i >= port->hwcfg.buffercount))
0178 return -EINVAL;
0179
0180 dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
0181
0182 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
0183
0184 return 0;
0185 }
0186
0187
0188 int saa7164_buffer_activate(struct saa7164_buffer *buf, int i)
0189 {
0190 struct saa7164_port *port = buf->port;
0191 struct saa7164_dev *dev = port->dev;
0192
0193 if ((i < 0) || (i >= port->hwcfg.buffercount))
0194 return -EINVAL;
0195
0196 dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
0197
0198 buf->idx = i;
0199 buf->flags = SAA7164_BUFFER_BUSY;
0200 buf->pos = 0;
0201
0202
0203 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
0204 saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma);
0205 saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
0206
0207 dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) buf 0x%llx/%llx (0x%x/%x) nr=%d\n",
0208 buf->idx,
0209 (u64)port->bufoffset + (i * sizeof(u32)),
0210 saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
0211 (u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
0212 (u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
0213 saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)),
0214 saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)),
0215 buf->idx);
0216
0217 return 0;
0218 }
0219
0220 int saa7164_buffer_cfg_port(struct saa7164_port *port)
0221 {
0222 struct tmHWStreamParameters *params = &port->hw_streamingparams;
0223 struct saa7164_dev *dev = port->dev;
0224 struct saa7164_buffer *buf;
0225 struct list_head *c, *n;
0226 int i = 0;
0227
0228 dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr);
0229
0230 saa7164_writel(port->bufcounter, 0);
0231 saa7164_writel(port->pitch, params->pitch);
0232 saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
0233
0234 dprintk(DBGLVL_BUF, " configured:\n");
0235 dprintk(DBGLVL_BUF, " lmmio 0x%p\n", dev->lmmio);
0236 dprintk(DBGLVL_BUF, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
0237 saa7164_readl(port->bufcounter));
0238
0239 dprintk(DBGLVL_BUF, " pitch 0x%x = %d\n", port->pitch,
0240 saa7164_readl(port->pitch));
0241
0242 dprintk(DBGLVL_BUF, " bufsize 0x%x = %d\n", port->bufsize,
0243 saa7164_readl(port->bufsize));
0244
0245 dprintk(DBGLVL_BUF, " buffercount = %d\n", port->hwcfg.buffercount);
0246 dprintk(DBGLVL_BUF, " bufoffset = 0x%x\n", port->bufoffset);
0247 dprintk(DBGLVL_BUF, " bufptr32h = 0x%x\n", port->bufptr32h);
0248 dprintk(DBGLVL_BUF, " bufptr32l = 0x%x\n", port->bufptr32l);
0249
0250
0251 mutex_lock(&port->dmaqueue_lock);
0252 list_for_each_safe(c, n, &port->dmaqueue.list) {
0253 buf = list_entry(c, struct saa7164_buffer, list);
0254
0255 BUG_ON(buf->flags != SAA7164_BUFFER_FREE);
0256
0257
0258 saa7164_buffer_activate(buf, i);
0259
0260
0261 BUG_ON(i > port->hwcfg.buffercount);
0262 i++;
0263
0264 }
0265 mutex_unlock(&port->dmaqueue_lock);
0266
0267 return 0;
0268 }
0269
0270 struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
0271 u32 len)
0272 {
0273 struct saa7164_user_buffer *buf;
0274
0275 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
0276 if (!buf)
0277 return NULL;
0278
0279 buf->data = kzalloc(len, GFP_KERNEL);
0280
0281 if (!buf->data) {
0282 kfree(buf);
0283 return NULL;
0284 }
0285
0286 buf->actual_size = len;
0287 buf->pos = 0;
0288 buf->crc = 0;
0289
0290 dprintk(DBGLVL_BUF, "%s() allocated user buffer @ 0x%p\n",
0291 __func__, buf);
0292
0293 return buf;
0294 }
0295
0296 void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
0297 {
0298 if (!buf)
0299 return;
0300
0301 kfree(buf->data);
0302 buf->data = NULL;
0303
0304 kfree(buf);
0305 }