Commit e48836b8 authored by Steven Toth's avatar Steven Toth Committed by Mauro Carvalho Chehab
Browse files

[media] saa7164: add firmware debug message collection and procfs changes



Check for PROCFS and dynamically adjust code.
Cache some PCIe values in the device context.
Provide a mechanism to collect the debug messages
coming from the firmware.

Signed-off-by: default avatarSteven Toth <stoth@kernellabs.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e8ce2f21
Loading
Loading
Loading
Loading
+81 −2
Original line number Diff line number Diff line
@@ -24,13 +24,69 @@

#include "saa7164.h"

int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m)
{
	tmComResDebugGetData_t d;
	u8 more = 255;
	int ret;

	dprintk(DBGLVL_API, "%s()\n", __func__);

	while (more--) {

		memset(&d, 0, sizeof(d));

		ret = saa7164_cmd_send(dev, 0, GET_CUR,
			GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
		if (ret != SAA_OK) {
			printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
		}

		if (d.dwResult != SAA_OK)
			break;

		seq_printf(m, "%s", d.ucDebugData);

	}

	return 0;
}

int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
{
	tmComResDebugSetLevel_t lvl;
	int ret;

	dprintk(DBGLVL_API, "%s(level=%d)\n", __func__, level);

	/* Retrieve current state */
	ret = saa7164_cmd_send(dev, 0, GET_CUR,
		SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
	if (ret != SAA_OK) {
		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
	}
	dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);

	lvl.dwDebugLevel = level;

	/* set new state */
	ret = saa7164_cmd_send(dev, 0, SET_CUR,
		SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
	if (ret != SAA_OK) {
		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
	}

	return ret;
}

int saa7164_api_set_vbi_format(struct saa7164_port *port)
{
	struct saa7164_dev *dev = port->dev;
	tmComResProbeCommit_t fmt, rsp;
	int ret;

	dprintk(DBGLVL_API, "%s(nr=%d)\n", __func__, port->nr);
	dprintk(DBGLVL_API, "%s(nr=%d, unitid=0x%x)\n", __func__,
		port->nr, port->hwcfg.unitid);

	fmt.bmHint = 0;
	fmt.bFormatIndex = 1;
@@ -50,6 +106,8 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
	} else {
		/* Compare requested vs received, should be same */
		if (memcmp(&fmt, &rsp, sizeof(rsp)) == 0) {
			dprintk(DBGLVL_API, "SET/PROBE Verified\n");

			/* Ask the device to select the negotiated format */
			ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid,
				SET_CUR, SAA_COMMIT_CONTROL, sizeof(fmt), &fmt);
@@ -63,9 +121,11 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
				printk(KERN_ERR "%s() GET commit error, ret = 0x%x\n",
					__func__, ret);

			if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0)
			if (memcmp(&fmt, &rsp, sizeof(rsp)) != 0) {
				printk(KERN_ERR "%s() memcmp error, ret = 0x%x\n",
					__func__, ret);
			} else
				dprintk(DBGLVL_API, "SET/COMMIT Verified\n");

			dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
			dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);
@@ -723,6 +783,25 @@ int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
	dprintk(DBGLVL_API, "    EndLine       = %d\n", fmt->EndLine);
	dprintk(DBGLVL_API, "    FieldRate     = %d\n", fmt->FieldRate);
	dprintk(DBGLVL_API, "    bNumLines     = %d\n", fmt->bNumLines);

	/* Cache the hardware configuration in the port */

	port->bufcounter = port->hwcfg.BARLocation;
	port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
	port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
	port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
	port->bufptr32l = port->hwcfg.BARLocation +
		(4 * sizeof(u32)) +
		(sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
	port->bufptr32h = port->hwcfg.BARLocation +
		(4 * sizeof(u32)) +
		(sizeof(u32) * port->hwcfg.buffercount);
	port->bufptr64 = port->hwcfg.BARLocation +
		(4 * sizeof(u32)) +
		(sizeof(u32) * port->hwcfg.buffercount);
	dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
		port->hwcfg.BARLocation);

	dprintk(DBGLVL_API, "   = VS_FORMAT_VBI (becomes dev->en[%d])\n",
		port->nr);

+75 −1
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@
#include <linux/delay.h>
#include <asm/div64.h>

#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#endif
#include "saa7164.h"

MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
@@ -49,6 +52,10 @@ unsigned int saa_debug;
module_param_named(debug, saa_debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");

unsigned int fw_debug = 2;
module_param(fw_debug, int, 0644);
MODULE_PARM_DESC(fw_debug, "Firware debug level def:2");

unsigned int encoder_buffers = SAA7164_MAX_ENCODER_BUFFERS;
module_param(encoder_buffers, int, 0644);
MODULE_PARM_DESC(encoder_buffers, "Total buffers in read queue 16-512 def:64");
@@ -1067,6 +1074,63 @@ static void saa7164_dev_unregister(struct saa7164_dev *dev)
	return;
}

#ifdef CONFIG_PROC_FS
static int saa7164_proc_show(struct seq_file *m, void *v)
{
	struct saa7164_dev *dev;
	tmComResBusInfo_t *b;
	struct list_head *list;
	int i, c;

	if (saa7164_devcount == 0)
		return 0;

	list_for_each(list, &saa7164_devlist) {
		dev = list_entry(list, struct saa7164_dev, devlist);
		seq_printf(m, "%s = %p\n", dev->name, dev);

		if (dev->board != SAA7164_BOARD_UNKNOWN) {
			seq_printf(m, "Firmware messages ----->\n");
			saa7164_api_collect_debug(dev, m);
			seq_printf(m, "<---- Firmware messages\n");
		}

		/* Lock the bus from any other access */
		b = &dev->bus;
		mutex_lock(&b->lock);


		mutex_unlock(&b->lock);

	}

	return 0;
}

static int saa7164_proc_open(struct inode *inode, struct file *filp)
{
	return single_open(filp, saa7164_proc_show, NULL);
}

static struct file_operations saa7164_proc_fops = {
	.open		= saa7164_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int saa7164_proc_create(void)
{
	struct proc_dir_entry *pe;

	pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops);
	if (!pe)
		return -ENOMEM;

	return 0;
}
#endif

static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
				     const struct pci_device_id *pci_id)
{
@@ -1226,7 +1290,7 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
					"vbi device\n", __func__);
			}
		}

		saa7164_api_set_debug(dev, fw_debug);

	} /* != BOARD_UNKNOWN */
	else
@@ -1255,6 +1319,9 @@ static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
{
	struct saa7164_dev *dev = pci_get_drvdata(pci_dev);

	if (dev->board != SAA7164_BOARD_UNKNOWN)
		saa7164_api_set_debug(dev, 0x00);

	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
		&dev->ports[ SAA7164_PORT_ENC1 ].irq_interval);
	saa7164_histogram_print(&dev->ports[ SAA7164_PORT_ENC1 ],
@@ -1334,11 +1401,18 @@ static struct pci_driver saa7164_pci_driver = {
static int __init saa7164_init(void)
{
	printk(KERN_INFO "saa7164 driver loaded\n");

#ifdef CONFIG_PROC_FS
	saa7164_proc_create();
#endif
	return pci_register_driver(&saa7164_pci_driver);
}

static void __exit saa7164_fini(void)
{
#ifdef CONFIG_PROC_FS
	remove_proc_entry("saa7164", NULL);
#endif
	pci_unregister_driver(&saa7164_pci_driver);
}

+3 −0
Original line number Diff line number Diff line
@@ -213,3 +213,6 @@
#define EU_AUDIO_FORMAT_CONTROL		0x0C
#define EU_AUDIO_BIT_RATE_CONTROL	0x0D

/* Firmware Debugging */
#define SET_DEBUG_LEVEL_CONTROL	0x0B
#define GET_DEBUG_DATA_CONTROL	0x0C
+12 −0
Original line number Diff line number Diff line
@@ -434,3 +434,15 @@ typedef struct
	u8	bFormatIndex;
	u8	bFrameIndex;
} __attribute__((packed)) tmComResProbeCommit_t;

typedef struct
{
	u32	dwDebugLevel;
} __attribute__((packed)) tmComResDebugSetLevel_t;

typedef struct
{
	u32	dwResult;
	u8	ucDebugData[256];
} __attribute__((packed)) tmComResDebugGetData_t;
+2 −0
Original line number Diff line number Diff line
@@ -541,6 +541,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port);
int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect);
int saa7164_api_get_videomux(struct saa7164_port *port);
int saa7164_api_set_vbi_format(struct saa7164_port *port);
int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
int saa7164_api_collect_debug(struct saa7164_dev *dev, struct seq_file *m);

/* ----------------------------------------------------------- */
/* saa7164-cards.c                                             */