Commit e8817de7 authored by Gustavo Pimentel's avatar Gustavo Pimentel Committed by Lorenzo Pieralisi
Browse files

pci-epf-test/pci_endpoint_test: Cleanup PCI_ENDPOINT_TEST memspace



Cleanup PCI_ENDPOINT_TEST memspace (by moving the interrupt number away
from command section).

Add IRQ_TYPE register to identify the triggered ID interrupt required
for the READ/WRITE/COPY tests and raise IRQ test commands.

Update documentation accordingly.

Signed-off-by: default avatarGustavo Pimentel <gustavo.pimentel@synopsys.com>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent cb22d40b
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ The PCI endpoint test device has the following registers:
	5) PCI_ENDPOINT_TEST_DST_ADDR
	6) PCI_ENDPOINT_TEST_SIZE
	7) PCI_ENDPOINT_TEST_CHECKSUM
	8) PCI_ENDPOINT_TEST_IRQ_TYPE
	9) PCI_ENDPOINT_TEST_IRQ_NUMBER

*) PCI_ENDPOINT_TEST_MAGIC

@@ -34,10 +36,10 @@ that the endpoint device must perform.
Bitfield Description:
  Bit 0		: raise legacy IRQ
  Bit 1		: raise MSI IRQ
  Bit 2 - 7	: MSI interrupt number
  Bit 8		: read command (read data from RC buffer)
  Bit 9		: write command (write data to RC buffer)
  Bit 10	: copy command (copy data from one RC buffer to another
  Bit 2		: raise MSI-X IRQ (reserved for future implementation)
  Bit 3		: read command (read data from RC buffer)
  Bit 4		: write command (write data to RC buffer)
  Bit 5		: copy command (copy data from one RC buffer to another
		  RC buffer)

*) PCI_ENDPOINT_TEST_STATUS
@@ -64,3 +66,20 @@ COPY/READ command.

This register contains the destination address (RC buffer address) for
the COPY/WRITE command.

*) PCI_ENDPOINT_TEST_IRQ_TYPE

This register contains the interrupt type (Legacy/MSI) triggered
for the READ/WRITE/COPY and raise IRQ (Legacy/MSI) commands.

Possible types:
 - Legacy	: 0
 - MSI		: 1

*) PCI_ENDPOINT_TEST_IRQ_NUMBER

This register contains the triggered ID interrupt.

Admissible values:
 - Legacy	: 0
 - MSI		: [1 .. 32]
+50 −31
Original line number Diff line number Diff line
@@ -37,16 +37,18 @@

#define DRV_MODULE_NAME				"pci-endpoint-test"

#define IRQ_TYPE_LEGACY				0
#define IRQ_TYPE_MSI				1

#define PCI_ENDPOINT_TEST_MAGIC			0x0

#define PCI_ENDPOINT_TEST_COMMAND		0x4
#define COMMAND_RAISE_LEGACY_IRQ		BIT(0)
#define COMMAND_RAISE_MSI_IRQ			BIT(1)
#define MSI_NUMBER_SHIFT		2
/* 6 bits for MSI number */
#define COMMAND_READ                    BIT(8)
#define COMMAND_WRITE                   BIT(9)
#define COMMAND_COPY                    BIT(10)
/* BIT(2) is reserved for raising MSI-X IRQ command */
#define COMMAND_READ				BIT(3)
#define COMMAND_WRITE				BIT(4)
#define COMMAND_COPY				BIT(5)

#define PCI_ENDPOINT_TEST_STATUS		0x8
#define STATUS_READ_SUCCESS			BIT(0)
@@ -59,7 +61,7 @@
#define STATUS_SRC_ADDR_INVALID			BIT(7)
#define STATUS_DST_ADDR_INVALID			BIT(8)

#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR	0xc
#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR	0x0c
#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR	0x10

#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR	0x14
@@ -68,6 +70,9 @@
#define PCI_ENDPOINT_TEST_SIZE			0x1c
#define PCI_ENDPOINT_TEST_CHECKSUM		0x20

#define PCI_ENDPOINT_TEST_IRQ_TYPE		0x24
#define PCI_ENDPOINT_TEST_IRQ_NUMBER		0x28

static DEFINE_IDA(pci_endpoint_test_ida);

#define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
@@ -179,6 +184,9 @@ static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
{
	u32 val;

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
				 IRQ_TYPE_LEGACY);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 COMMAND_RAISE_LEGACY_IRQ);
	val = wait_for_completion_timeout(&test->irq_raised,
@@ -195,8 +203,10 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
	u32 val;
	struct pci_dev *pdev = test->pdev;

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
				 IRQ_TYPE_MSI);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 msi_num << MSI_NUMBER_SHIFT |
				 COMMAND_RAISE_MSI_IRQ);
	val = wait_for_completion_timeout(&test->irq_raised,
					  msecs_to_jiffies(1000));
@@ -281,8 +291,11 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
				 size);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
				 no_msi ? IRQ_TYPE_LEGACY : IRQ_TYPE_MSI);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 1 << MSI_NUMBER_SHIFT | COMMAND_COPY);
				 COMMAND_COPY);

	wait_for_completion(&test->irq_raised);

@@ -348,8 +361,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
				 no_msi ? IRQ_TYPE_LEGACY : IRQ_TYPE_MSI);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 1 << MSI_NUMBER_SHIFT | COMMAND_READ);
				 COMMAND_READ);

	wait_for_completion(&test->irq_raised);

@@ -403,8 +419,11 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
				 no_msi ? IRQ_TYPE_LEGACY : IRQ_TYPE_MSI);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 1 << MSI_NUMBER_SHIFT | COMMAND_WRITE);
				 COMMAND_WRITE);

	wait_for_completion(&test->irq_raised);

+41 −20
Original line number Diff line number Diff line
@@ -18,13 +18,15 @@
#include <linux/pci-epf.h>
#include <linux/pci_regs.h>

#define IRQ_TYPE_LEGACY			0
#define IRQ_TYPE_MSI			1

#define COMMAND_RAISE_LEGACY_IRQ	BIT(0)
#define COMMAND_RAISE_MSI_IRQ		BIT(1)
#define MSI_NUMBER_SHIFT		2
#define MSI_NUMBER_MASK			(0x3f << MSI_NUMBER_SHIFT)
#define COMMAND_READ			BIT(8)
#define COMMAND_WRITE			BIT(9)
#define COMMAND_COPY			BIT(10)
/* BIT(2) is reserved for raising MSI-X IRQ command */
#define COMMAND_READ			BIT(3)
#define COMMAND_WRITE			BIT(4)
#define COMMAND_COPY			BIT(5)

#define STATUS_READ_SUCCESS		BIT(0)
#define STATUS_READ_FAIL		BIT(1)
@@ -56,6 +58,8 @@ struct pci_epf_test_reg {
	u64	dst_addr;
	u32	size;
	u32	checksum;
	u32	irq_type;
	u32	irq_number;
} __packed;

static struct pci_epf_header test_header = {
@@ -244,31 +248,39 @@ err:
	return ret;
}

static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq)
static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type,
				   u16 irq)
{
	u8 msi_count;
	struct pci_epf *epf = epf_test->epf;
	struct device *dev = &epf->dev;
	struct pci_epc *epc = epf->epc;
	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];

	reg->status |= STATUS_IRQ_RAISED;
	msi_count = pci_epc_get_msi(epc, epf->func_no);
	if (irq > msi_count || msi_count <= 0)

	switch (irq_type) {
	case IRQ_TYPE_LEGACY:
		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
	else
		break;
	case IRQ_TYPE_MSI:
		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
		break;
	default:
		dev_err(dev, "Failed to raise IRQ, unknown type\n");
		break;
	}
}

static void pci_epf_test_cmd_handler(struct work_struct *work)
{
	int ret;
	u8 irq;
	u8 msi_count;
	int count;
	u32 command;
	struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
						     cmd_handler.work);
	struct pci_epf *epf = epf_test->epf;
	struct device *dev = &epf->dev;
	struct pci_epc *epc = epf->epc;
	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
@@ -280,7 +292,10 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
	reg->command = 0;
	reg->status = 0;

	irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
	if (reg->irq_type > IRQ_TYPE_MSI) {
		dev_err(dev, "Failed to detect IRQ type\n");
		goto reset_handler;
	}

	if (command & COMMAND_RAISE_LEGACY_IRQ) {
		reg->status = STATUS_IRQ_RAISED;
@@ -294,7 +309,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
			reg->status |= STATUS_WRITE_FAIL;
		else
			reg->status |= STATUS_WRITE_SUCCESS;
		pci_epf_test_raise_irq(epf_test, irq);
		pci_epf_test_raise_irq(epf_test, reg->irq_type,
				       reg->irq_number);
		goto reset_handler;
	}

@@ -304,7 +320,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
			reg->status |= STATUS_READ_SUCCESS;
		else
			reg->status |= STATUS_READ_FAIL;
		pci_epf_test_raise_irq(epf_test, irq);
		pci_epf_test_raise_irq(epf_test, reg->irq_type,
				       reg->irq_number);
		goto reset_handler;
	}

@@ -314,16 +331,18 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
			reg->status |= STATUS_COPY_SUCCESS;
		else
			reg->status |= STATUS_COPY_FAIL;
		pci_epf_test_raise_irq(epf_test, irq);
		pci_epf_test_raise_irq(epf_test, reg->irq_type,
				       reg->irq_number);
		goto reset_handler;
	}

	if (command & COMMAND_RAISE_MSI_IRQ) {
		msi_count = pci_epc_get_msi(epc, epf->func_no);
		if (irq > msi_count || msi_count <= 0)
		count = pci_epc_get_msi(epc, epf->func_no);
		if (reg->irq_number > count || count <= 0)
			goto reset_handler;
		reg->status = STATUS_IRQ_RAISED;
		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI,
				  reg->irq_number);
		goto reset_handler;
	}

@@ -457,8 +476,10 @@ static int pci_epf_test_bind(struct pci_epf *epf)
		return ret;

	ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
	if (ret)
	if (ret) {
		dev_err(dev, "MSI configuration failed\n");
		return ret;
	}

	if (!epf_test->linkup_notifier)
		queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);