Commit f70bb809 authored by Ronald Bultje's avatar Ronald Bultje Committed by Linus Torvalds

[PATCH] zr36067 driver - ppc/be port

Attached patch adds some host<->le conversion functions for 32-bit integers.
The hardware expects 32-bit integers, which the host does not always provide. 
With the attached patch, the hardware runs fine on PPC hardware as well.

Original patch by Ben Capper <benandeve@optusnet.com.au>.
Signed-off-by: default avatarRonald S. Bultje <rbultje@ronald.bitfreak.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 236bbb1b
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/byteorder/generic.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
...@@ -758,7 +759,7 @@ init_jpeg_queue (struct zoran *zr) ...@@ -758,7 +759,7 @@ init_jpeg_queue (struct zoran *zr)
zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
} }
for (i = 0; i < BUZ_NUM_STAT_COM; i++) { for (i = 0; i < BUZ_NUM_STAT_COM; i++) {
zr->stat_com[i] = 1; /* mark as unavailable to zr36057 */ zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
} }
} }
...@@ -1163,20 +1164,20 @@ zoran_feed_stat_com (struct zoran *zr) ...@@ -1163,20 +1164,20 @@ zoran_feed_stat_com (struct zoran *zr)
/* fill 1 stat_com entry */ /* fill 1 stat_com entry */
i = (zr->jpg_dma_head - i = (zr->jpg_dma_head -
zr->jpg_err_shift) & BUZ_MASK_STAT_COM; zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
if (!(zr->stat_com[i] & 1)) if (!(zr->stat_com[i] & cpu_to_le32(1)))
break; break;
zr->stat_com[i] = zr->stat_com[i] =
zr->jpg_buffers.buffer[frame].frag_tab_bus; cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
} else { } else {
/* fill 2 stat_com entries */ /* fill 2 stat_com entries */
i = ((zr->jpg_dma_head - i = ((zr->jpg_dma_head -
zr->jpg_err_shift) & 1) * 2; zr->jpg_err_shift) & 1) * 2;
if (!(zr->stat_com[i] & 1)) if (!(zr->stat_com[i] & cpu_to_le32(1)))
break; break;
zr->stat_com[i] = zr->stat_com[i] =
zr->jpg_buffers.buffer[frame].frag_tab_bus; cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
zr->stat_com[i + 1] = zr->stat_com[i + 1] =
zr->jpg_buffers.buffer[frame].frag_tab_bus; cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
} }
zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA; zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
zr->jpg_dma_head++; zr->jpg_dma_head++;
...@@ -1213,7 +1214,7 @@ zoran_reap_stat_com (struct zoran *zr) ...@@ -1213,7 +1214,7 @@ zoran_reap_stat_com (struct zoran *zr)
i = ((zr->jpg_dma_tail - i = ((zr->jpg_dma_tail -
zr->jpg_err_shift) & 1) * 2 + 1; zr->jpg_err_shift) & 1) * 2 + 1;
stat_com = zr->stat_com[i]; stat_com = le32_to_cpu(zr->stat_com[i]);
if ((stat_com & 1) == 0) { if ((stat_com & 1) == 0) {
return; return;
...@@ -1309,7 +1310,7 @@ error_handler (struct zoran *zr, ...@@ -1309,7 +1310,7 @@ error_handler (struct zoran *zr,
for (i = 0; for (i = 0;
i < zr->jpg_buffers.num_buffers; i < zr->jpg_buffers.num_buffers;
i++) { i++) {
if (zr->stat_com[j] == if (le32_to_cpu(zr->stat_com[j]) ==
zr->jpg_buffers. zr->jpg_buffers.
buffer[i]. buffer[i].
frag_tab_bus) { frag_tab_bus) {
...@@ -1321,7 +1322,6 @@ error_handler (struct zoran *zr, ...@@ -1321,7 +1322,6 @@ error_handler (struct zoran *zr,
printk("\n"); printk("\n");
} }
} }
/* Find an entry in stat_com and rotate contents */ /* Find an entry in stat_com and rotate contents */
{ {
int i; int i;
...@@ -1334,9 +1334,9 @@ error_handler (struct zoran *zr, ...@@ -1334,9 +1334,9 @@ error_handler (struct zoran *zr,
zr->jpg_err_shift) & 1) * 2; zr->jpg_err_shift) & 1) * 2;
if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
/* Mimic zr36067 operation */ /* Mimic zr36067 operation */
zr->stat_com[i] |= 1; zr->stat_com[i] |= cpu_to_le32(1);
if (zr->jpg_settings.TmpDcm != 1) if (zr->jpg_settings.TmpDcm != 1)
zr->stat_com[i + 1] |= 1; zr->stat_com[i + 1] |= cpu_to_le32(1);
/* Refill */ /* Refill */
zoran_reap_stat_com(zr); zoran_reap_stat_com(zr);
zoran_feed_stat_com(zr); zoran_feed_stat_com(zr);
...@@ -1355,12 +1355,17 @@ error_handler (struct zoran *zr, ...@@ -1355,12 +1355,17 @@ error_handler (struct zoran *zr,
int j; int j;
u32 bus_addr[BUZ_NUM_STAT_COM]; u32 bus_addr[BUZ_NUM_STAT_COM];
/* Here we are copying the stat_com array, which
* is already in little endian format, so
* no endian conversions here
*/
memcpy(bus_addr, zr->stat_com, memcpy(bus_addr, zr->stat_com,
sizeof(bus_addr)); sizeof(bus_addr));
for (j = 0; j < BUZ_NUM_STAT_COM; j++) { for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
zr->stat_com[j] = zr->stat_com[j] =
bus_addr[(i + j) & bus_addr[(i + j) &
BUZ_MASK_STAT_COM]; BUZ_MASK_STAT_COM];
} }
zr->jpg_err_shift += i; zr->jpg_err_shift += i;
zr->jpg_err_shift &= BUZ_MASK_STAT_COM; zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
...@@ -1564,7 +1569,7 @@ zoran_irq (int irq, ...@@ -1564,7 +1569,7 @@ zoran_irq (int irq,
int i; int i;
strcpy(sv, sc); strcpy(sv, sc);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (zr->stat_com[i] & 1) if (le32_to_cpu(zr->stat_com[i]) & 1)
sv[i] = '1'; sv[i] = '1';
} }
sv[4] = 0; sv[4] = 0;
...@@ -1592,7 +1597,7 @@ zoran_irq (int irq, ...@@ -1592,7 +1597,7 @@ zoran_irq (int irq,
ZR_DEVNAME(zr), zr->jpg_seq_num); ZR_DEVNAME(zr), zr->jpg_seq_num);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
printk(" %08x", printk(" %08x",
zr->stat_com[i]); le32_to_cpu(zr->stat_com[i]));
} }
printk("\n"); printk("\n");
} }
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/byteorder/generic.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -516,6 +517,16 @@ v4l_fbuffer_free (struct file *file) ...@@ -516,6 +517,16 @@ v4l_fbuffer_free (struct file *file)
* virtual addresses) and then again have to make a lot of efforts * virtual addresses) and then again have to make a lot of efforts
* to get the physical address. * to get the physical address.
* *
* Ben Capper:
* On big-endian architectures (such as ppc) some extra steps
* are needed. When reading and writing to the stat_com array
* and fragment buffers, the device expects to see little-
* endian values. The use of cpu_to_le32() and le32_to_cpu()
* in this function (and one or two others in zoran_device.c)
* ensure that these values are always stored in little-endian
* form, regardless of architecture. The zr36057 does Very Bad
* Things on big endian architectures if the stat_com array
* and fragment buffers are not little-endian.
*/ */
static int static int
...@@ -569,9 +580,9 @@ jpg_fbuffer_alloc (struct file *file) ...@@ -569,9 +580,9 @@ jpg_fbuffer_alloc (struct file *file)
return -ENOBUFS; return -ENOBUFS;
} }
fh->jpg_buffers.buffer[i].frag_tab[0] = fh->jpg_buffers.buffer[i].frag_tab[0] =
virt_to_bus((void *) mem); cpu_to_le32(virt_to_bus((void *) mem));
fh->jpg_buffers.buffer[i].frag_tab[1] = fh->jpg_buffers.buffer[i].frag_tab[1] =
((fh->jpg_buffers.buffer_size / 4) << 1) | 1; cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
for (off = 0; off < fh->jpg_buffers.buffer_size; for (off = 0; off < fh->jpg_buffers.buffer_size;
off += PAGE_SIZE) off += PAGE_SIZE)
SetPageReserved(MAP_NR(mem + off)); SetPageReserved(MAP_NR(mem + off));
...@@ -591,14 +602,14 @@ jpg_fbuffer_alloc (struct file *file) ...@@ -591,14 +602,14 @@ jpg_fbuffer_alloc (struct file *file)
} }
fh->jpg_buffers.buffer[i].frag_tab[2 * j] = fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
virt_to_bus((void *) mem); cpu_to_le32(virt_to_bus((void *) mem));
fh->jpg_buffers.buffer[i].frag_tab[2 * j + fh->jpg_buffers.buffer[i].frag_tab[2 * j +
1] = 1] =
(PAGE_SIZE / 4) << 1; cpu_to_le32((PAGE_SIZE / 4) << 1);
SetPageReserved(MAP_NR(mem)); SetPageReserved(MAP_NR(mem));
} }
fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= 1; fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
} }
} }
...@@ -631,13 +642,8 @@ jpg_fbuffer_free (struct file *file) ...@@ -631,13 +642,8 @@ jpg_fbuffer_free (struct file *file)
//if (alloc_contig) { //if (alloc_contig) {
if (fh->jpg_buffers.need_contiguous) { if (fh->jpg_buffers.need_contiguous) {
if (fh->jpg_buffers.buffer[i].frag_tab[0]) { if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
mem = mem = (unsigned char *) bus_to_virt(le32_to_cpu(
(unsigned char *) bus_to_virt(fh-> fh->jpg_buffers.buffer[i].frag_tab[0]));
jpg_buffers.
buffer
[i].
frag_tab
[0]);
for (off = 0; for (off = 0;
off < fh->jpg_buffers.buffer_size; off < fh->jpg_buffers.buffer_size;
off += PAGE_SIZE) off += PAGE_SIZE)
...@@ -656,13 +662,16 @@ jpg_fbuffer_free (struct file *file) ...@@ -656,13 +662,16 @@ jpg_fbuffer_free (struct file *file)
break; break;
ClearPageReserved(MAP_NR ClearPageReserved(MAP_NR
(bus_to_virt (bus_to_virt
(le32_to_cpu
(fh->jpg_buffers. (fh->jpg_buffers.
buffer[i].frag_tab[2 * buffer[i].frag_tab[2 *
j]))); j]))));
free_page((unsigned long) free_page((unsigned long)
bus_to_virt(fh->jpg_buffers. bus_to_virt
(le32_to_cpu
(fh->jpg_buffers.
buffer[i]. buffer[i].
frag_tab[2 * j])); frag_tab[2 * j])));
fh->jpg_buffers.buffer[i].frag_tab[2 * j] = fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
0; 0;
fh->jpg_buffers.buffer[i].frag_tab[2 * j + fh->jpg_buffers.buffer[i].frag_tab[2 * j +
...@@ -4539,14 +4548,14 @@ zoran_mmap (struct file *file, ...@@ -4539,14 +4548,14 @@ zoran_mmap (struct file *file,
j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
j++) { j++) {
fraglen = fraglen =
(fh->jpg_buffers.buffer[i]. (le32_to_cpu(fh->jpg_buffers.buffer[i].
frag_tab[2 * j + 1] & ~1) << 1; frag_tab[2 * j + 1]) & ~1) << 1;
todo = size; todo = size;
if (todo > fraglen) if (todo > fraglen)
todo = fraglen; todo = fraglen;
pos = pos =
(unsigned long) fh->jpg_buffers. le32_to_cpu((unsigned long) fh->jpg_buffers.
buffer[i].frag_tab[2 * j]; buffer[i].frag_tab[2 * j]);
/* should just be pos on i386 */ /* should just be pos on i386 */
page = virt_to_phys(bus_to_virt(pos)) page = virt_to_phys(bus_to_virt(pos))
>> PAGE_SHIFT; >> PAGE_SHIFT;
...@@ -4563,8 +4572,8 @@ zoran_mmap (struct file *file, ...@@ -4563,8 +4572,8 @@ zoran_mmap (struct file *file,
start += todo; start += todo;
if (size == 0) if (size == 0)
break; break;
if (fh->jpg_buffers.buffer[i]. if (le32_to_cpu(fh->jpg_buffers.buffer[i].
frag_tab[2 * j + 1] & 1) frag_tab[2 * j + 1]) & 1)
break; /* was last fragment */ break; /* was last fragment */
} }
fh->jpg_buffers.buffer[i].map = map; fh->jpg_buffers.buffer[i].map = map;
...@@ -4689,3 +4698,4 @@ struct video_device zoran_template __devinitdata = { ...@@ -4689,3 +4698,4 @@ struct video_device zoran_template __devinitdata = {
.release = &zoran_vdev_release, .release = &zoran_vdev_release,
.minor = -1 .minor = -1
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment