forked from luck/tmp_suning_uos_patched
V4L/DVB (8913): cx18: Create cx18_ specific wrappers for all pci mmio accessesors.
cx18: Create cx18_ specific wrappers for all pci mmio accessesors. This is a first step in instrumenting all CX23418 PCI bus IO, to debug problems with accessing the CX23418's PCI memory mapped IO. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
4519064c1c
commit
b1526421ea
@ -2,7 +2,7 @@ cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.
|
||||
cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
|
||||
cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
|
||||
cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
|
||||
cx18-dvb.o
|
||||
cx18-dvb.o cx18-io.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_CX18) += cx18.o
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-i2c.h"
|
||||
#include "cx18-cards.h"
|
||||
#include "cx18-audio.h"
|
||||
@ -60,10 +61,10 @@ int cx18_audio_set_io(struct cx18 *cx)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val = read_reg(CX18_AUDIO_ENABLE) & ~0x30;
|
||||
val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
|
||||
val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
|
||||
(audio_input << 4);
|
||||
write_reg(val | 0xb00, CX18_AUDIO_ENABLE);
|
||||
cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE);
|
||||
cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,27 +22,29 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
|
||||
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
|
||||
{
|
||||
u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
|
||||
u32 reg = 0xc40000 + (addr & ~3);
|
||||
u32 mask = 0xff;
|
||||
int shift = (addr & 3) * 8;
|
||||
u32 x = cx18_read_reg(cx, reg);
|
||||
|
||||
x = (x & ~(mask << shift)) | ((u32)value << shift);
|
||||
writel(x, cx->reg_mem + 0xc40000 + (addr & ~3));
|
||||
cx18_write_reg(cx, x, reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
|
||||
{
|
||||
writel(value, cx->reg_mem + 0xc40000 + addr);
|
||||
cx18_write_reg(cx, value, 0xc40000 + addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 cx18_av_read(struct cx18 *cx, u16 addr)
|
||||
{
|
||||
u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
|
||||
u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3));
|
||||
int shift = (addr & 3) * 8;
|
||||
|
||||
return (x >> shift) & 0xff;
|
||||
@ -50,7 +52,7 @@ u8 cx18_av_read(struct cx18 *cx, u16 addr)
|
||||
|
||||
u32 cx18_av_read4(struct cx18 *cx, u16 addr)
|
||||
{
|
||||
return readl(cx->reg_mem + 0xc40000 + addr);
|
||||
return cx18_read_reg(cx, 0xc40000 + addr);
|
||||
}
|
||||
|
||||
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#define CX18_AUDIO_ENABLE 0xc72014
|
||||
@ -119,10 +120,10 @@ int cx18_av_loadfw(struct cx18 *cx)
|
||||
have a name in the spec. */
|
||||
cx18_av_write4(cx, 0x09CC, 1);
|
||||
|
||||
v = read_reg(CX18_AUDIO_ENABLE);
|
||||
/* If bit 11 is 1 */
|
||||
v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
|
||||
/* If bit 11 is 1, clear bit 10 */
|
||||
if (v & 0x800)
|
||||
write_reg(v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Clear bit 10 */
|
||||
cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE);
|
||||
|
||||
/* Enable WW auto audio standard detection */
|
||||
v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-version.h"
|
||||
#include "cx18-cards.h"
|
||||
#include "cx18-i2c.h"
|
||||
@ -651,7 +652,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
|
||||
goto free_mem;
|
||||
}
|
||||
cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
|
||||
devtype = read_reg(0xC72028);
|
||||
devtype = cx18_read_reg(cx, 0xC72028);
|
||||
switch (devtype & 0xff000000) {
|
||||
case 0xff000000:
|
||||
CX18_INFO("cx23418 revision %08x (A)\n", devtype);
|
||||
@ -897,8 +898,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
|
||||
cx18_stop_all_captures(cx);
|
||||
|
||||
/* Interrupts */
|
||||
sw1_irq_disable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
|
||||
sw2_irq_disable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
|
||||
cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
|
||||
cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
|
||||
|
||||
cx18_halt_firmware(cx);
|
||||
|
||||
|
@ -457,47 +457,4 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
|
||||
/* First-open initialization: load firmware, etc. */
|
||||
int cx18_init_on_first_open(struct cx18 *cx);
|
||||
|
||||
/* This is a PCI post thing, where if the pci register is not read, then
|
||||
the write doesn't always take effect right away. By reading back the
|
||||
register any pending PCI writes will be performed (in order), and so
|
||||
you can be sure that the writes are guaranteed to be done.
|
||||
|
||||
Rarely needed, only in some timing sensitive cases.
|
||||
Apparently if this is not done some motherboards seem
|
||||
to kill the firmware and get into the broken state until computer is
|
||||
rebooted. */
|
||||
#define write_sync(val, reg) \
|
||||
do { writel(val, reg); readl(reg); } while (0)
|
||||
|
||||
#define read_reg(reg) readl(cx->reg_mem + (reg))
|
||||
#define write_reg(val, reg) writel(val, cx->reg_mem + (reg))
|
||||
#define write_reg_sync(val, reg) \
|
||||
do { write_reg(val, reg); read_reg(reg); } while (0)
|
||||
|
||||
#define read_enc(addr) readl(cx->enc_mem + (u32)(addr))
|
||||
#define write_enc(val, addr) writel(val, cx->enc_mem + (u32)(addr))
|
||||
#define write_enc_sync(val, addr) \
|
||||
do { write_enc(val, addr); read_enc(addr); } while (0)
|
||||
|
||||
#define sw1_irq_enable(val) do { \
|
||||
write_reg(val, SW1_INT_STATUS); \
|
||||
write_reg(read_reg(SW1_INT_ENABLE_PCI) | (val), SW1_INT_ENABLE_PCI); \
|
||||
} while (0)
|
||||
|
||||
#define sw1_irq_disable(val) \
|
||||
write_reg(read_reg(SW1_INT_ENABLE_PCI) & ~(val), SW1_INT_ENABLE_PCI);
|
||||
|
||||
#define sw2_irq_enable(val) do { \
|
||||
write_reg(val, SW2_INT_STATUS); \
|
||||
write_reg(read_reg(SW2_INT_ENABLE_PCI) | (val), SW2_INT_ENABLE_PCI); \
|
||||
} while (0)
|
||||
|
||||
#define sw2_irq_disable(val) \
|
||||
write_reg(read_reg(SW2_INT_ENABLE_PCI) & ~(val), SW2_INT_ENABLE_PCI);
|
||||
|
||||
#define setup_page(addr) do { \
|
||||
u32 val = read_reg(0xD000F8) & ~0x1f00; \
|
||||
write_reg(val | (((addr) >> 17) & 0x1f00), 0xD000F8); \
|
||||
} while (0)
|
||||
|
||||
#endif /* CX18_DRIVER_H */
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "cx18-version.h"
|
||||
#include "cx18-dvb.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-streams.h"
|
||||
#include "cx18-cards.h"
|
||||
#include "s5h1409.h"
|
||||
@ -87,13 +88,13 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
|
||||
switch (cx->card->type) {
|
||||
case CX18_CARD_HVR_1600_ESMT:
|
||||
case CX18_CARD_HVR_1600_SAMSUNG:
|
||||
v = read_reg(CX18_REG_DMUX_NUM_PORT_0_CONTROL);
|
||||
v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
|
||||
v |= 0x00400000; /* Serial Mode */
|
||||
v |= 0x00002000; /* Data Length - Byte */
|
||||
v |= 0x00010000; /* Error - Polarity */
|
||||
v |= 0x00020000; /* Error - Passthru */
|
||||
v |= 0x000c0000; /* Error - Ignore */
|
||||
write_reg(v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
|
||||
cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-scb.h"
|
||||
#include "cx18-irq.h"
|
||||
#include "cx18-firmware.h"
|
||||
@ -113,11 +114,11 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
|
||||
src = (const u32 *)fw->data;
|
||||
|
||||
for (i = 0; i < fw->size; i += 4096) {
|
||||
setup_page(i);
|
||||
cx18_setup_page(cx, i);
|
||||
for (j = i; j < fw->size && j < i + 4096; j += 4) {
|
||||
/* no need for endianness conversion on the ppc */
|
||||
__raw_writel(*src, dst);
|
||||
if (__raw_readl(dst) != *src) {
|
||||
cx18_raw_writel(cx, *src, dst);
|
||||
if (cx18_raw_readl(cx, dst) != *src) {
|
||||
CX18_ERR("Mismatch at offset %x\n", i);
|
||||
release_firmware(fw);
|
||||
return -EIO;
|
||||
@ -170,12 +171,15 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
|
||||
if (offset + seghdr.size > sz)
|
||||
break;
|
||||
for (i = 0; i < seghdr.size; i += 4096) {
|
||||
setup_page(offset + i);
|
||||
cx18_setup_page(cx, offset + i);
|
||||
for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
|
||||
/* no need for endianness conversion on the ppc */
|
||||
__raw_writel(src[(offset + j) / 4], dst + seghdr.addr + j);
|
||||
if (__raw_readl(dst + seghdr.addr + j) != src[(offset + j) / 4]) {
|
||||
CX18_ERR("Mismatch at offset %x\n", offset + j);
|
||||
cx18_raw_writel(cx, src[(offset + j) / 4],
|
||||
dst + seghdr.addr + j);
|
||||
if (cx18_raw_readl(cx, dst + seghdr.addr + j)
|
||||
!= src[(offset + j) / 4]) {
|
||||
CX18_ERR("Mismatch at offset %x\n",
|
||||
offset + j);
|
||||
release_firmware(fw);
|
||||
return -EIO;
|
||||
}
|
||||
@ -189,43 +193,45 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
|
||||
size = fw->size;
|
||||
release_firmware(fw);
|
||||
/* Clear bit0 for APU to start from 0 */
|
||||
write_reg(read_reg(0xc72030) & ~1, 0xc72030);
|
||||
cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030);
|
||||
return size;
|
||||
}
|
||||
|
||||
void cx18_halt_firmware(struct cx18 *cx)
|
||||
{
|
||||
CX18_DEBUG_INFO("Preparing for firmware halt.\n");
|
||||
write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
|
||||
write_reg(0x00020002, CX18_ADEC_CONTROL);
|
||||
cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
|
||||
cx18_write_reg(cx, 0x00020002, CX18_ADEC_CONTROL);
|
||||
}
|
||||
|
||||
void cx18_init_power(struct cx18 *cx, int lowpwr)
|
||||
{
|
||||
/* power-down Spare and AOM PLLs */
|
||||
/* power-up fast, slow and mpeg PLLs */
|
||||
write_reg(0x00000008, CX18_PLL_POWER_DOWN);
|
||||
cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
|
||||
|
||||
/* ADEC out of sleep */
|
||||
write_reg(0x00020000, CX18_ADEC_CONTROL);
|
||||
cx18_write_reg(cx, 0x00020000, CX18_ADEC_CONTROL);
|
||||
|
||||
/* The fast clock is at 200/245 MHz */
|
||||
write_reg(lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
|
||||
write_reg(lowpwr ? 0x1EFBF37 : 0x038E3D7, CX18_FAST_CLOCK_PLL_FRAC);
|
||||
cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
|
||||
cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
|
||||
CX18_FAST_CLOCK_PLL_FRAC);
|
||||
|
||||
write_reg(2, CX18_FAST_CLOCK_PLL_POST);
|
||||
write_reg(1, CX18_FAST_CLOCK_PLL_PRESCALE);
|
||||
write_reg(4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
|
||||
cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
|
||||
cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
|
||||
cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
|
||||
|
||||
/* set slow clock to 125/120 MHz */
|
||||
write_reg(lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT);
|
||||
write_reg(lowpwr ? 0xEBAF05 : 0x18618A8, CX18_SLOW_CLOCK_PLL_FRAC);
|
||||
write_reg(4, CX18_SLOW_CLOCK_PLL_POST);
|
||||
cx18_write_reg(cx, lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT);
|
||||
cx18_write_reg(cx, lowpwr ? 0xEBAF05 : 0x18618A8,
|
||||
CX18_SLOW_CLOCK_PLL_FRAC);
|
||||
cx18_write_reg(cx, 4, CX18_SLOW_CLOCK_PLL_POST);
|
||||
|
||||
/* mpeg clock pll 54MHz */
|
||||
write_reg(0xF, CX18_MPEG_CLOCK_PLL_INT);
|
||||
write_reg(0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC);
|
||||
write_reg(8, CX18_MPEG_CLOCK_PLL_POST);
|
||||
cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
|
||||
cx18_write_reg(cx, 0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC);
|
||||
cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
|
||||
|
||||
/* Defaults */
|
||||
/* APU = SC or SC/2 = 125/62.5 */
|
||||
@ -242,81 +248,84 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
|
||||
/* VFC = disabled */
|
||||
/* USB = disabled */
|
||||
|
||||
write_reg(lowpwr ? 0xFFFF0020 : 0x00060004, CX18_CLOCK_SELECT1);
|
||||
write_reg(lowpwr ? 0xFFFF0004 : 0x00060006, CX18_CLOCK_SELECT2);
|
||||
cx18_write_reg(cx, lowpwr ? 0xFFFF0020 : 0x00060004,
|
||||
CX18_CLOCK_SELECT1);
|
||||
cx18_write_reg(cx, lowpwr ? 0xFFFF0004 : 0x00060006,
|
||||
CX18_CLOCK_SELECT2);
|
||||
|
||||
write_reg(0xFFFF0002, CX18_HALF_CLOCK_SELECT1);
|
||||
write_reg(0xFFFF0104, CX18_HALF_CLOCK_SELECT2);
|
||||
cx18_write_reg(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1);
|
||||
cx18_write_reg(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2);
|
||||
|
||||
write_reg(0xFFFF9026, CX18_CLOCK_ENABLE1);
|
||||
write_reg(0xFFFF3105, CX18_CLOCK_ENABLE2);
|
||||
cx18_write_reg(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1);
|
||||
cx18_write_reg(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2);
|
||||
}
|
||||
|
||||
void cx18_init_memory(struct cx18 *cx)
|
||||
{
|
||||
cx18_msleep_timeout(10, 0);
|
||||
write_reg(0x10000, CX18_DDR_SOFT_RESET);
|
||||
cx18_write_reg(cx, 0x10000, CX18_DDR_SOFT_RESET);
|
||||
cx18_msleep_timeout(10, 0);
|
||||
|
||||
write_reg(cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
|
||||
cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
|
||||
|
||||
cx18_msleep_timeout(10, 0);
|
||||
|
||||
write_reg(cx->card->ddr.refresh, CX18_DDR_REFRESH);
|
||||
write_reg(cx->card->ddr.timing1, CX18_DDR_TIMING1);
|
||||
write_reg(cx->card->ddr.timing2, CX18_DDR_TIMING2);
|
||||
cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
|
||||
cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
|
||||
cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);
|
||||
|
||||
cx18_msleep_timeout(10, 0);
|
||||
|
||||
/* Initialize DQS pad time */
|
||||
write_reg(cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
|
||||
write_reg(cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
|
||||
cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
|
||||
cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
|
||||
|
||||
cx18_msleep_timeout(10, 0);
|
||||
|
||||
write_reg(0x20000, CX18_DDR_SOFT_RESET);
|
||||
cx18_write_reg(cx, 0x20000, CX18_DDR_SOFT_RESET);
|
||||
cx18_msleep_timeout(10, 0);
|
||||
|
||||
/* use power-down mode when idle */
|
||||
write_reg(0x00000010, CX18_DDR_POWER_REG);
|
||||
cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
|
||||
|
||||
write_reg(0x10001, CX18_REG_BUS_TIMEOUT_EN);
|
||||
cx18_write_reg(cx, 0x10001, CX18_REG_BUS_TIMEOUT_EN);
|
||||
|
||||
write_reg(0x48, CX18_DDR_MB_PER_ROW_7);
|
||||
write_reg(0xE0000, CX18_DDR_BASE_63_ADDR);
|
||||
cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
|
||||
cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
|
||||
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT02); /* AO */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT09); /* AI2 */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT06); /* AI1 */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT10); /* ME */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT12); /* ENC */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT13); /* PK */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT11); /* RC */
|
||||
write_reg(0x00000101, CX18_WMB_CLIENT14); /* AVO */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */
|
||||
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
|
||||
}
|
||||
|
||||
int cx18_firmware_init(struct cx18 *cx)
|
||||
{
|
||||
/* Allow chip to control CLKRUN */
|
||||
write_reg(0x5, CX18_DSP0_INTERRUPT_MASK);
|
||||
cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
|
||||
|
||||
write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
|
||||
cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
|
||||
|
||||
cx18_msleep_timeout(1, 0);
|
||||
|
||||
sw1_irq_enable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
|
||||
sw2_irq_enable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
|
||||
cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
|
||||
cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
|
||||
|
||||
/* Only if the processor is not running */
|
||||
if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
|
||||
if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) {
|
||||
int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
|
||||
cx->enc_mem, cx);
|
||||
|
||||
write_enc(0xE51FF004, 0);
|
||||
write_enc(0xa00000, 4); /* todo: not hardcoded */
|
||||
write_reg(0x00010000, CX18_PROC_SOFT_RESET); /* Start APU */
|
||||
cx18_write_enc(cx, 0xE51FF004, 0);
|
||||
cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */
|
||||
/* Start APU */
|
||||
cx18_write_reg(cx, 0x00010000, CX18_PROC_SOFT_RESET);
|
||||
cx18_msleep_timeout(500, 0);
|
||||
|
||||
sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
|
||||
@ -326,9 +335,10 @@ int cx18_firmware_init(struct cx18 *cx)
|
||||
int retries = 0;
|
||||
|
||||
/* start the CPU */
|
||||
write_reg(0x00080000, CX18_PROC_SOFT_RESET);
|
||||
cx18_write_reg(cx, 0x00080000, CX18_PROC_SOFT_RESET);
|
||||
while (retries++ < 50) { /* Loop for max 500mS */
|
||||
if ((read_reg(CX18_PROC_SOFT_RESET) & 1) == 0)
|
||||
if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET)
|
||||
& 1) == 0)
|
||||
break;
|
||||
cx18_msleep_timeout(10, 0);
|
||||
}
|
||||
@ -342,6 +352,6 @@ int cx18_firmware_init(struct cx18 *cx)
|
||||
return -EIO;
|
||||
}
|
||||
/* initialize GPIO */
|
||||
write_reg(0x14001400, 0xC78110);
|
||||
cx18_write_reg(cx, 0x14001400, 0xC78110);
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-cards.h"
|
||||
#include "cx18-gpio.h"
|
||||
#include "tuner-xc2028.h"
|
||||
@ -49,11 +50,11 @@ static void gpio_write(struct cx18 *cx)
|
||||
u32 dir = cx->gpio_dir;
|
||||
u32 val = cx->gpio_val;
|
||||
|
||||
write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
|
||||
write_reg(((dir & 0xffff) << 16) | (val & 0xffff),
|
||||
cx18_write_reg(cx, (dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
|
||||
cx18_write_reg(cx, ((dir & 0xffff) << 16) | (val & 0xffff),
|
||||
CX18_REG_GPIO_OUT1);
|
||||
write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2);
|
||||
write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
|
||||
cx18_write_reg(cx, dir & 0xffff0000, CX18_REG_GPIO_DIR2);
|
||||
cx18_write_reg_sync(cx, (dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
|
||||
CX18_REG_GPIO_OUT2);
|
||||
}
|
||||
|
||||
@ -141,8 +142,10 @@ void cx18_gpio_init(struct cx18 *cx)
|
||||
}
|
||||
|
||||
CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
|
||||
read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
|
||||
read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
|
||||
cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
|
||||
cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
|
||||
cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
|
||||
cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
|
||||
|
||||
gpio_write(cx);
|
||||
mutex_unlock(&cx->gpio_lock);
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-cards.h"
|
||||
#include "cx18-gpio.h"
|
||||
#include "cx18-av-core.h"
|
||||
@ -156,12 +157,12 @@ static void cx18_setscl(void *data, int state)
|
||||
struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
|
||||
int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
|
||||
u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
|
||||
u32 r = read_reg(addr);
|
||||
u32 r = cx18_read_reg(cx, addr);
|
||||
|
||||
if (state)
|
||||
write_reg_sync(r | SETSCL_BIT, addr);
|
||||
cx18_write_reg_sync(cx, r | SETSCL_BIT, addr);
|
||||
else
|
||||
write_reg_sync(r & ~SETSCL_BIT, addr);
|
||||
cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr);
|
||||
}
|
||||
|
||||
static void cx18_setsda(void *data, int state)
|
||||
@ -169,12 +170,12 @@ static void cx18_setsda(void *data, int state)
|
||||
struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
|
||||
int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
|
||||
u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
|
||||
u32 r = read_reg(addr);
|
||||
u32 r = cx18_read_reg(cx, addr);
|
||||
|
||||
if (state)
|
||||
write_reg_sync(r | SETSDL_BIT, addr);
|
||||
cx18_write_reg_sync(cx, r | SETSDL_BIT, addr);
|
||||
else
|
||||
write_reg_sync(r & ~SETSDL_BIT, addr);
|
||||
cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr);
|
||||
}
|
||||
|
||||
static int cx18_getscl(void *data)
|
||||
@ -183,7 +184,7 @@ static int cx18_getscl(void *data)
|
||||
int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
|
||||
u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
|
||||
|
||||
return read_reg(addr) & GETSCL_BIT;
|
||||
return cx18_read_reg(cx, addr) & GETSCL_BIT;
|
||||
}
|
||||
|
||||
static int cx18_getsda(void *data)
|
||||
@ -192,7 +193,7 @@ static int cx18_getsda(void *data)
|
||||
int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
|
||||
u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
|
||||
|
||||
return read_reg(addr) & GETSDL_BIT;
|
||||
return cx18_read_reg(cx, addr) & GETSDL_BIT;
|
||||
}
|
||||
|
||||
/* template for i2c-bit-algo */
|
||||
@ -392,29 +393,33 @@ int init_cx18_i2c(struct cx18 *cx)
|
||||
cx->i2c_adap[i].dev.parent = &cx->dev->dev;
|
||||
}
|
||||
|
||||
if (read_reg(CX18_REG_I2C_2_WR) != 0x0003c02f) {
|
||||
if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
|
||||
/* Reset/Unreset I2C hardware block */
|
||||
write_reg(0x10000000, 0xc71004); /* Clock select 220MHz */
|
||||
write_reg_sync(0x10001000, 0xc71024); /* Clock Enable */
|
||||
/* Clock select 220MHz */
|
||||
cx18_write_reg(cx, 0x10000000, 0xc71004);
|
||||
/* Clock Enable */
|
||||
cx18_write_reg_sync(cx, 0x10001000, 0xc71024);
|
||||
}
|
||||
/* courtesy of Steven Toth <stoth@hauppauge.com> */
|
||||
write_reg_sync(0x00c00000, 0xc7001c);
|
||||
cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
|
||||
mdelay(10);
|
||||
write_reg_sync(0x00c000c0, 0xc7001c);
|
||||
cx18_write_reg_sync(cx, 0x00c000c0, 0xc7001c);
|
||||
mdelay(10);
|
||||
write_reg_sync(0x00c00000, 0xc7001c);
|
||||
cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
|
||||
mdelay(10);
|
||||
|
||||
write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */
|
||||
write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */
|
||||
/* Set to edge-triggered intrs. */
|
||||
cx18_write_reg_sync(cx, 0x00c00000, 0xc730c8);
|
||||
/* Clear any stale intrs */
|
||||
cx18_write_reg_sync(cx, 0x00c00000, 0xc730c4);
|
||||
|
||||
/* Hw I2C1 Clock Freq ~100kHz */
|
||||
write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_1_WR);
|
||||
cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
|
||||
cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
|
||||
cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
|
||||
|
||||
/* Hw I2C2 Clock Freq ~100kHz */
|
||||
write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_2_WR);
|
||||
cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
|
||||
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
|
||||
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
|
||||
|
||||
@ -428,8 +433,10 @@ void exit_cx18_i2c(struct cx18 *cx)
|
||||
{
|
||||
int i;
|
||||
CX18_DEBUG_I2C("i2c exit\n");
|
||||
write_reg(read_reg(CX18_REG_I2C_1_WR) | 4, CX18_REG_I2C_1_WR);
|
||||
write_reg(read_reg(CX18_REG_I2C_2_WR) | 4, CX18_REG_I2C_2_WR);
|
||||
cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4,
|
||||
CX18_REG_I2C_1_WR);
|
||||
cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4,
|
||||
CX18_REG_I2C_2_WR);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
i2c_del_adapter(&cx->i2c_adap[i]);
|
||||
|
142
drivers/media/video/cx18/cx18-io.c
Normal file
142
drivers/media/video/cx18/cx18-io.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* cx18 driver PCI memory mapped IO access routines
|
||||
*
|
||||
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
|
||||
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-irq.h"
|
||||
|
||||
void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
|
||||
{
|
||||
__raw_writel(val, addr);
|
||||
}
|
||||
|
||||
u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
|
||||
{
|
||||
return __raw_readl(addr);
|
||||
}
|
||||
|
||||
u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr)
|
||||
{
|
||||
writel(val, addr);
|
||||
return readl(addr);
|
||||
}
|
||||
|
||||
void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
|
||||
{
|
||||
writel(val, addr);
|
||||
}
|
||||
|
||||
u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
|
||||
{
|
||||
return readl(addr);
|
||||
}
|
||||
|
||||
|
||||
/* Access "register" region of CX23418 memory mapped I/O */
|
||||
u32 cx18_read_reg(struct cx18 *cx, u32 reg)
|
||||
{
|
||||
return readl(cx->reg_mem + reg);
|
||||
}
|
||||
|
||||
void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
|
||||
{
|
||||
writel(val, cx->reg_mem + reg);
|
||||
}
|
||||
|
||||
u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg)
|
||||
{
|
||||
return cx18_write_sync(cx, val, cx->reg_mem + reg);
|
||||
}
|
||||
|
||||
/* Access "encoder memory" region of CX23418 memory mapped I/O */
|
||||
u32 cx18_read_enc(struct cx18 *cx, u32 addr)
|
||||
{
|
||||
return readl(cx->enc_mem + addr);
|
||||
}
|
||||
|
||||
void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
|
||||
{
|
||||
writel(val, cx->enc_mem + addr);
|
||||
}
|
||||
|
||||
u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr)
|
||||
{
|
||||
return cx18_write_sync(cx, val, cx->enc_mem + addr);
|
||||
}
|
||||
|
||||
void cx18_memcpy_fromio(struct cx18 *cx, void *to,
|
||||
const void __iomem *from, unsigned int len)
|
||||
{
|
||||
memcpy_fromio(to, from, len);
|
||||
}
|
||||
|
||||
void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
|
||||
{
|
||||
memset_io(addr, val, count);
|
||||
}
|
||||
|
||||
void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
|
||||
{
|
||||
u32 r;
|
||||
cx18_write_reg(cx, val, SW1_INT_STATUS);
|
||||
r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
|
||||
cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI);
|
||||
}
|
||||
|
||||
void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
|
||||
{
|
||||
u32 r;
|
||||
r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
|
||||
cx18_write_reg(cx, r & ~val, SW1_INT_ENABLE_PCI);
|
||||
}
|
||||
|
||||
void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
|
||||
{
|
||||
u32 r;
|
||||
cx18_write_reg(cx, val, SW2_INT_STATUS);
|
||||
r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
|
||||
cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI);
|
||||
}
|
||||
|
||||
void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
|
||||
{
|
||||
u32 r;
|
||||
r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
|
||||
cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_PCI);
|
||||
}
|
||||
|
||||
void cx18_setup_page(struct cx18 *cx, u32 addr)
|
||||
{
|
||||
u32 val;
|
||||
val = cx18_read_reg(cx, 0xD000F8);
|
||||
val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00);
|
||||
cx18_write_reg(cx, val, 0xD000F8);
|
||||
}
|
||||
|
||||
/* Tries to recover from the CX23418 responding improperly on the PCI bus */
|
||||
int cx18_pci_try_recover(struct cx18 *cx)
|
||||
{
|
||||
u16 status;
|
||||
|
||||
pci_read_config_word(cx->dev, PCI_STATUS, &status);
|
||||
pci_write_config_word(cx->dev, PCI_STATUS, status);
|
||||
return 0;
|
||||
}
|
69
drivers/media/video/cx18/cx18-io.h
Normal file
69
drivers/media/video/cx18/cx18-io.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* cx18 driver PCI memory mapped IO access routines
|
||||
*
|
||||
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
|
||||
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef CX18_IO_H
|
||||
#define CX18_IO_H
|
||||
|
||||
#include "cx18-driver.h"
|
||||
|
||||
/* This is a PCI post thing, where if the pci register is not read, then
|
||||
the write doesn't always take effect right away. By reading back the
|
||||
register any pending PCI writes will be performed (in order), and so
|
||||
you can be sure that the writes are guaranteed to be done.
|
||||
|
||||
Rarely needed, only in some timing sensitive cases.
|
||||
Apparently if this is not done some motherboards seem
|
||||
to kill the firmware and get into the broken state until computer is
|
||||
rebooted. */
|
||||
u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr);
|
||||
|
||||
void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr);
|
||||
u32 cx18_readl(struct cx18 *cx, const void __iomem *addr);
|
||||
|
||||
/* No endiannes conversion calls */
|
||||
void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr);
|
||||
u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr);
|
||||
|
||||
/* Access "register" region of CX23418 memory mapped I/O */
|
||||
u32 cx18_read_reg(struct cx18 *cx, u32 reg);
|
||||
void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg);
|
||||
u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg);
|
||||
|
||||
/* Access "encoder memory" region of CX23418 memory mapped I/O */
|
||||
u32 cx18_read_enc(struct cx18 *cx, u32 addr);
|
||||
void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr);
|
||||
u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr);
|
||||
|
||||
void cx18_memcpy_fromio(struct cx18 *cx, void *to,
|
||||
const void __iomem *from, unsigned int len);
|
||||
void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
|
||||
|
||||
void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
|
||||
void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
|
||||
void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
|
||||
void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
|
||||
void cx18_setup_page(struct cx18 *cx, u32 addr);
|
||||
|
||||
/* Tries to recover from the CX23418 responding improperly on the PCI bus */
|
||||
int cx18_pci_try_recover(struct cx18 *cx);
|
||||
|
||||
#endif /* CX18_IO_H */
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-version.h"
|
||||
#include "cx18-mailbox.h"
|
||||
#include "cx18-i2c.h"
|
||||
@ -286,9 +287,9 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
|
||||
|
||||
spin_lock_irqsave(&cx18_cards_lock, flags);
|
||||
if (cmd == VIDIOC_DBG_G_REGISTER)
|
||||
regs->val = read_enc(regs->reg);
|
||||
regs->val = cx18_read_enc(cx, regs->reg);
|
||||
else
|
||||
write_enc(regs->val, regs->reg);
|
||||
cx18_write_enc(cx, regs->val, regs->reg);
|
||||
spin_unlock_irqrestore(&cx18_cards_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-firmware.h"
|
||||
#include "cx18-fileops.h"
|
||||
#include "cx18-queue.h"
|
||||
@ -60,8 +61,8 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
|
||||
if (mb->args[2] != 1)
|
||||
CX18_WARN("Ack struct = %d for %s\n",
|
||||
mb->args[2], s->name);
|
||||
id = read_enc(off);
|
||||
buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4));
|
||||
id = cx18_read_enc(cx, off);
|
||||
buf = cx18_queue_get_buf_irq(s, id, cx18_read_enc(cx, off + 4));
|
||||
CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
|
||||
if (buf) {
|
||||
cx18_buf_sync_for_cpu(s, buf);
|
||||
@ -81,7 +82,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
|
||||
set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
|
||||
} else {
|
||||
CX18_WARN("Could not find buf %d for stream %s\n",
|
||||
read_enc(off), s->name);
|
||||
cx18_read_enc(cx, off), s->name);
|
||||
}
|
||||
mb->error = 0;
|
||||
mb->cmd = 0;
|
||||
@ -97,8 +98,8 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
|
||||
char *p;
|
||||
|
||||
if (mb->args[1]) {
|
||||
setup_page(mb->args[1]);
|
||||
memcpy_fromio(str, cx->enc_mem + mb->args[1], 252);
|
||||
cx18_setup_page(cx, mb->args[1]);
|
||||
cx18_memcpy_fromio(cx, str, cx->enc_mem + mb->args[1], 252);
|
||||
str[252] = 0;
|
||||
}
|
||||
cx18_mb_ack(cx, mb);
|
||||
@ -113,7 +114,7 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1)
|
||||
struct cx18_mailbox mb;
|
||||
|
||||
if (sw1 & IRQ_CPU_TO_EPU) {
|
||||
memcpy_fromio(&mb, &cx->scb->cpu2epu_mb, sizeof(mb));
|
||||
cx18_memcpy_fromio(cx, &mb, &cx->scb->cpu2epu_mb, sizeof(mb));
|
||||
mb.error = 0;
|
||||
|
||||
switch (mb.cmd) {
|
||||
@ -141,16 +142,16 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
|
||||
|
||||
spin_lock(&cx->dma_reg_lock);
|
||||
|
||||
hw2_mask = read_reg(HW2_INT_MASK5_PCI);
|
||||
hw2 = read_reg(HW2_INT_CLR_STATUS) & hw2_mask;
|
||||
sw2_mask = read_reg(SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK;
|
||||
sw2 = read_reg(SW2_INT_STATUS) & sw2_mask;
|
||||
sw1_mask = read_reg(SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU;
|
||||
sw1 = read_reg(SW1_INT_STATUS) & sw1_mask;
|
||||
hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI);
|
||||
hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask;
|
||||
sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK;
|
||||
sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask;
|
||||
sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU;
|
||||
sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask;
|
||||
|
||||
write_reg(sw2&sw2_mask, SW2_INT_STATUS);
|
||||
write_reg(sw1&sw1_mask, SW1_INT_STATUS);
|
||||
write_reg(hw2&hw2_mask, HW2_INT_CLR_STATUS);
|
||||
cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS);
|
||||
cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS);
|
||||
cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS);
|
||||
|
||||
if (sw1 || sw2 || hw2)
|
||||
CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
|
||||
@ -161,15 +162,15 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
|
||||
*/
|
||||
|
||||
if (sw2) {
|
||||
if (sw2 & (readl(&cx->scb->cpu2hpu_irq_ack) |
|
||||
readl(&cx->scb->cpu2epu_irq_ack)))
|
||||
if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) |
|
||||
cx18_readl(cx, &cx->scb->cpu2epu_irq_ack)))
|
||||
wake_up(&cx->mb_cpu_waitq);
|
||||
if (sw2 & (readl(&cx->scb->apu2hpu_irq_ack) |
|
||||
readl(&cx->scb->apu2epu_irq_ack)))
|
||||
if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) |
|
||||
cx18_readl(cx, &cx->scb->apu2epu_irq_ack)))
|
||||
wake_up(&cx->mb_apu_waitq);
|
||||
if (sw2 & readl(&cx->scb->epu2hpu_irq_ack))
|
||||
if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack))
|
||||
wake_up(&cx->mb_epu_waitq);
|
||||
if (sw2 & readl(&cx->scb->hpu2epu_irq_ack))
|
||||
if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack))
|
||||
wake_up(&cx->mb_hpu_waitq);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-scb.h"
|
||||
#include "cx18-irq.h"
|
||||
#include "cx18-mailbox.h"
|
||||
@ -106,20 +107,20 @@ static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu
|
||||
switch (rpu) {
|
||||
case APU:
|
||||
mb = &cx->scb->epu2apu_mb;
|
||||
*state = readl(&cx->scb->apu_state);
|
||||
*irq = readl(&cx->scb->epu2apu_irq);
|
||||
*state = cx18_readl(cx, &cx->scb->apu_state);
|
||||
*irq = cx18_readl(cx, &cx->scb->epu2apu_irq);
|
||||
break;
|
||||
|
||||
case CPU:
|
||||
mb = &cx->scb->epu2cpu_mb;
|
||||
*state = readl(&cx->scb->cpu_state);
|
||||
*irq = readl(&cx->scb->epu2cpu_irq);
|
||||
*state = cx18_readl(cx, &cx->scb->cpu_state);
|
||||
*irq = cx18_readl(cx, &cx->scb->epu2cpu_irq);
|
||||
break;
|
||||
|
||||
case HPU:
|
||||
mb = &cx->scb->epu2hpu_mb;
|
||||
*state = readl(&cx->scb->hpu_state);
|
||||
*irq = readl(&cx->scb->epu2hpu_irq);
|
||||
*state = cx18_readl(cx, &cx->scb->hpu_state);
|
||||
*irq = cx18_readl(cx, &cx->scb->epu2hpu_irq);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -127,8 +128,8 @@ static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu
|
||||
return mb;
|
||||
|
||||
do {
|
||||
*req = readl(&mb->request);
|
||||
ack = readl(&mb->ack);
|
||||
*req = cx18_readl(cx, &mb->request);
|
||||
ack = cx18_readl(cx, &mb->ack);
|
||||
wait_count++;
|
||||
} while (*req != ack && wait_count < 600);
|
||||
|
||||
@ -173,9 +174,9 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
setup_page(SCB_OFFSET);
|
||||
write_sync(mb->request, &ack_mb->ack);
|
||||
write_reg(ack_irq, SW2_INT_SET);
|
||||
cx18_setup_page(cx, SCB_OFFSET);
|
||||
cx18_write_sync(cx, mb->request, &ack_mb->ack);
|
||||
cx18_write_reg(cx, ack_irq, SW2_INT_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -200,7 +201,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
|
||||
CX18_DEBUG_HI_API("%s\n", info->name);
|
||||
else
|
||||
CX18_DEBUG_API("%s\n", info->name);
|
||||
setup_page(SCB_OFFSET);
|
||||
cx18_setup_page(cx, SCB_OFFSET);
|
||||
mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req);
|
||||
|
||||
if (mb == NULL) {
|
||||
@ -209,11 +210,11 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
|
||||
}
|
||||
|
||||
oldreq = req - 1;
|
||||
writel(cmd, &mb->cmd);
|
||||
cx18_writel(cx, cmd, &mb->cmd);
|
||||
for (i = 0; i < args; i++)
|
||||
writel(data[i], &mb->args[i]);
|
||||
writel(0, &mb->error);
|
||||
writel(req, &mb->request);
|
||||
cx18_writel(cx, data[i], &mb->args[i]);
|
||||
cx18_writel(cx, 0, &mb->error);
|
||||
cx18_writel(cx, req, &mb->request);
|
||||
|
||||
switch (info->rpu) {
|
||||
case APU: waitq = &cx->mb_apu_waitq; break;
|
||||
@ -224,9 +225,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
|
||||
}
|
||||
if (info->flags & API_FAST)
|
||||
timeout /= 2;
|
||||
write_reg(irq, SW1_INT_SET);
|
||||
cx18_write_reg(cx, irq, SW1_INT_SET);
|
||||
|
||||
while (!sig && readl(&mb->ack) != readl(&mb->request) && cnt < 660) {
|
||||
while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request)
|
||||
&& cnt < 660) {
|
||||
if (cnt > 200 && !in_atomic())
|
||||
sig = cx18_msleep_timeout(10, 1);
|
||||
cnt++;
|
||||
@ -234,13 +236,13 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
|
||||
if (sig)
|
||||
return -EINTR;
|
||||
if (cnt == 660) {
|
||||
writel(oldreq, &mb->request);
|
||||
cx18_writel(cx, oldreq, &mb->request);
|
||||
CX18_ERR("mb %s failed\n", info->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < MAX_MB_ARGUMENTS; i++)
|
||||
data[i] = readl(&mb->args[i]);
|
||||
err = readl(&mb->error);
|
||||
data[i] = cx18_readl(cx, &mb->args[i]);
|
||||
err = cx18_readl(cx, &mb->error);
|
||||
if (!in_atomic() && (info->flags & API_SLOW))
|
||||
cx18_msleep_timeout(300, 0);
|
||||
if (err)
|
||||
|
@ -170,6 +170,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
|
||||
}
|
||||
buf->id = cx->buffer_id++;
|
||||
INIT_LIST_HEAD(&buf->list);
|
||||
/* FIXME - check for mmio */
|
||||
buf->dma_handle = pci_map_single(s->cx->dev,
|
||||
buf->buf, s->buf_size, s->dma);
|
||||
cx18_buf_sync_for_cpu(s, buf);
|
||||
@ -193,6 +194,7 @@ void cx18_stream_free(struct cx18_stream *s)
|
||||
|
||||
/* empty q_free */
|
||||
while ((buf = cx18_dequeue(s, &s->q_free))) {
|
||||
/* FIXME - check for mmio */
|
||||
pci_unmap_single(s->cx->dev, buf->dma_handle,
|
||||
s->buf_size, s->dma);
|
||||
kfree(buf->buf);
|
||||
|
@ -28,6 +28,7 @@
|
||||
static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
|
||||
struct cx18_buffer *buf)
|
||||
{
|
||||
/* FIXME check IO transfers */
|
||||
pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
|
||||
s->buf_size, s->dma);
|
||||
}
|
||||
@ -35,6 +36,7 @@ static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
|
||||
static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
|
||||
struct cx18_buffer *buf)
|
||||
{
|
||||
/* FIXME check IO transfers */
|
||||
pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
|
||||
s->buf_size, s->dma);
|
||||
}
|
||||
|
@ -20,102 +20,103 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-scb.h"
|
||||
|
||||
void cx18_init_scb(struct cx18 *cx)
|
||||
{
|
||||
setup_page(SCB_OFFSET);
|
||||
memset_io(cx->scb, 0, 0x10000);
|
||||
cx18_setup_page(cx, SCB_OFFSET);
|
||||
cx18_memset_io(cx, cx->scb, 0, 0x10000);
|
||||
|
||||
writel(IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
|
||||
writel(IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
|
||||
writel(IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
|
||||
writel(IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
|
||||
writel(IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
|
||||
writel(IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
|
||||
writel(IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
|
||||
writel(IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
|
||||
cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
|
||||
cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
|
||||
cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
|
||||
cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
|
||||
cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
|
||||
cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
|
||||
cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
|
||||
|
||||
writel(IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
|
||||
writel(IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
|
||||
writel(IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
|
||||
writel(IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
|
||||
writel(IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
|
||||
writel(IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
|
||||
writel(IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
|
||||
writel(IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
|
||||
cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
|
||||
cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
|
||||
cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
|
||||
cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
|
||||
cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
|
||||
cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
|
||||
|
||||
writel(IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
|
||||
writel(IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
|
||||
writel(IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
|
||||
writel(IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
|
||||
writel(IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
|
||||
writel(IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
|
||||
writel(IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
|
||||
writel(IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
|
||||
cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
|
||||
cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
|
||||
cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
|
||||
cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
|
||||
cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
|
||||
cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
|
||||
cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
|
||||
|
||||
writel(IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
|
||||
writel(IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
|
||||
writel(IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
|
||||
writel(IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
|
||||
writel(IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
|
||||
writel(IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
|
||||
writel(IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
|
||||
writel(IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
|
||||
cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
|
||||
cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
|
||||
cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
|
||||
cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
|
||||
cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
|
||||
cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
|
||||
|
||||
writel(IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
|
||||
writel(IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
|
||||
writel(IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
|
||||
writel(IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
|
||||
writel(IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
|
||||
writel(IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
|
||||
writel(IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
|
||||
writel(IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
|
||||
cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
|
||||
cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
|
||||
cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
|
||||
cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
|
||||
cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
|
||||
cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
|
||||
cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
|
||||
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
|
||||
&cx->scb->apu2cpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
|
||||
&cx->scb->hpu2cpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
|
||||
&cx->scb->ppu2cpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
|
||||
&cx->scb->epu2cpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
|
||||
&cx->scb->cpu2apu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
|
||||
&cx->scb->hpu2apu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
|
||||
&cx->scb->ppu2apu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
|
||||
&cx->scb->epu2apu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
|
||||
&cx->scb->cpu2hpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
|
||||
&cx->scb->apu2hpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
|
||||
&cx->scb->ppu2hpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
|
||||
&cx->scb->epu2hpu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
|
||||
&cx->scb->cpu2ppu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
|
||||
&cx->scb->apu2ppu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
|
||||
&cx->scb->hpu2ppu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
|
||||
&cx->scb->epu2ppu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
|
||||
&cx->scb->cpu2epu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
|
||||
&cx->scb->apu2epu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
|
||||
&cx->scb->hpu2epu_mb_offset);
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
|
||||
&cx->scb->ppu2epu_mb_offset);
|
||||
|
||||
writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
|
||||
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
|
||||
&cx->scb->ipc_offset);
|
||||
|
||||
writel(1, &cx->scb->hpu_state);
|
||||
writel(1, &cx->scb->epu_state);
|
||||
cx18_writel(cx, 1, &cx->scb->hpu_state);
|
||||
cx18_writel(cx, 1, &cx->scb->epu_state);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "cx18-driver.h"
|
||||
#include "cx18-io.h"
|
||||
#include "cx18-fileops.h"
|
||||
#include "cx18-mailbox.h"
|
||||
#include "cx18-i2c.h"
|
||||
@ -469,7 +470,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
|
||||
|
||||
if (atomic_read(&cx->tot_capturing) == 0) {
|
||||
clear_bit(CX18_F_I_EOS, &cx->i_flags);
|
||||
write_reg(7, CX18_DSP0_INTERRUPT_MASK);
|
||||
cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
|
||||
}
|
||||
|
||||
cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
|
||||
@ -479,8 +480,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
|
||||
list_for_each(p, &s->q_free.list) {
|
||||
struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list);
|
||||
|
||||
writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr);
|
||||
writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
|
||||
cx18_writel(cx, buf->dma_handle,
|
||||
&cx->scb->cpu_mdl[buf->id].paddr);
|
||||
cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
|
||||
cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
|
||||
(void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
|
||||
1, buf->id, s->buf_size);
|
||||
@ -563,7 +565,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
|
||||
if (atomic_read(&cx->tot_capturing) > 0)
|
||||
return 0;
|
||||
|
||||
write_reg(5, CX18_DSP0_INTERRUPT_MASK);
|
||||
cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
|
||||
wake_up(&s->waitq);
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user