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

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
...@@ -20,6 +20,8 @@ The PCI endpoint test device has the following registers: ...@@ -20,6 +20,8 @@ The PCI endpoint test device has the following registers:
5) PCI_ENDPOINT_TEST_DST_ADDR 5) PCI_ENDPOINT_TEST_DST_ADDR
6) PCI_ENDPOINT_TEST_SIZE 6) PCI_ENDPOINT_TEST_SIZE
7) PCI_ENDPOINT_TEST_CHECKSUM 7) PCI_ENDPOINT_TEST_CHECKSUM
8) PCI_ENDPOINT_TEST_IRQ_TYPE
9) PCI_ENDPOINT_TEST_IRQ_NUMBER
*) PCI_ENDPOINT_TEST_MAGIC *) PCI_ENDPOINT_TEST_MAGIC
...@@ -34,10 +36,10 @@ that the endpoint device must perform. ...@@ -34,10 +36,10 @@ that the endpoint device must perform.
Bitfield Description: Bitfield Description:
Bit 0 : raise legacy IRQ Bit 0 : raise legacy IRQ
Bit 1 : raise MSI IRQ Bit 1 : raise MSI IRQ
Bit 2 - 7 : MSI interrupt number Bit 2 : raise MSI-X IRQ (reserved for future implementation)
Bit 8 : read command (read data from RC buffer) Bit 3 : read command (read data from RC buffer)
Bit 9 : write command (write data to RC buffer) Bit 4 : write command (write data to RC buffer)
Bit 10 : copy command (copy data from one RC buffer to another Bit 5 : copy command (copy data from one RC buffer to another
RC buffer) RC buffer)
*) PCI_ENDPOINT_TEST_STATUS *) PCI_ENDPOINT_TEST_STATUS
...@@ -64,3 +66,20 @@ COPY/READ command. ...@@ -64,3 +66,20 @@ COPY/READ command.
This register contains the destination address (RC buffer address) for This register contains the destination address (RC buffer address) for
the COPY/WRITE command. 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]
...@@ -35,38 +35,43 @@ ...@@ -35,38 +35,43 @@
#include <uapi/linux/pcitest.h> #include <uapi/linux/pcitest.h>
#define DRV_MODULE_NAME "pci-endpoint-test" #define DRV_MODULE_NAME "pci-endpoint-test"
#define PCI_ENDPOINT_TEST_MAGIC 0x0 #define IRQ_TYPE_LEGACY 0
#define IRQ_TYPE_MSI 1
#define PCI_ENDPOINT_TEST_COMMAND 0x4
#define COMMAND_RAISE_LEGACY_IRQ BIT(0) #define PCI_ENDPOINT_TEST_MAGIC 0x0
#define COMMAND_RAISE_MSI_IRQ BIT(1)
#define MSI_NUMBER_SHIFT 2 #define PCI_ENDPOINT_TEST_COMMAND 0x4
/* 6 bits for MSI number */ #define COMMAND_RAISE_LEGACY_IRQ BIT(0)
#define COMMAND_READ BIT(8) #define COMMAND_RAISE_MSI_IRQ BIT(1)
#define COMMAND_WRITE BIT(9) /* BIT(2) is reserved for raising MSI-X IRQ command */
#define COMMAND_COPY BIT(10) #define COMMAND_READ BIT(3)
#define COMMAND_WRITE BIT(4)
#define PCI_ENDPOINT_TEST_STATUS 0x8 #define COMMAND_COPY BIT(5)
#define STATUS_READ_SUCCESS BIT(0)
#define STATUS_READ_FAIL BIT(1) #define PCI_ENDPOINT_TEST_STATUS 0x8
#define STATUS_WRITE_SUCCESS BIT(2) #define STATUS_READ_SUCCESS BIT(0)
#define STATUS_WRITE_FAIL BIT(3) #define STATUS_READ_FAIL BIT(1)
#define STATUS_COPY_SUCCESS BIT(4) #define STATUS_WRITE_SUCCESS BIT(2)
#define STATUS_COPY_FAIL BIT(5) #define STATUS_WRITE_FAIL BIT(3)
#define STATUS_IRQ_RAISED BIT(6) #define STATUS_COPY_SUCCESS BIT(4)
#define STATUS_SRC_ADDR_INVALID BIT(7) #define STATUS_COPY_FAIL BIT(5)
#define STATUS_DST_ADDR_INVALID BIT(8) #define STATUS_IRQ_RAISED BIT(6)
#define STATUS_SRC_ADDR_INVALID BIT(7)
#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0xc #define STATUS_DST_ADDR_INVALID BIT(8)
#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0x0c
#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14 #define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14
#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18 #define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18
#define PCI_ENDPOINT_TEST_SIZE 0x1c #define PCI_ENDPOINT_TEST_SIZE 0x1c
#define PCI_ENDPOINT_TEST_CHECKSUM 0x20 #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); static DEFINE_IDA(pci_endpoint_test_ida);
...@@ -179,6 +184,9 @@ static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test) ...@@ -179,6 +184,9 @@ static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
{ {
u32 val; 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, pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
COMMAND_RAISE_LEGACY_IRQ); COMMAND_RAISE_LEGACY_IRQ);
val = wait_for_completion_timeout(&test->irq_raised, val = wait_for_completion_timeout(&test->irq_raised,
...@@ -195,8 +203,10 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, ...@@ -195,8 +203,10 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
u32 val; u32 val;
struct pci_dev *pdev = test->pdev; 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, pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
msi_num << MSI_NUMBER_SHIFT |
COMMAND_RAISE_MSI_IRQ); COMMAND_RAISE_MSI_IRQ);
val = wait_for_completion_timeout(&test->irq_raised, val = wait_for_completion_timeout(&test->irq_raised,
msecs_to_jiffies(1000)); msecs_to_jiffies(1000));
...@@ -281,8 +291,11 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) ...@@ -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, pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
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, pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
1 << MSI_NUMBER_SHIFT | COMMAND_COPY); COMMAND_COPY);
wait_for_completion(&test->irq_raised); wait_for_completion(&test->irq_raised);
...@@ -348,8 +361,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) ...@@ -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_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, pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
1 << MSI_NUMBER_SHIFT | COMMAND_READ); COMMAND_READ);
wait_for_completion(&test->irq_raised); wait_for_completion(&test->irq_raised);
...@@ -403,8 +419,11 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) ...@@ -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_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, pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
1 << MSI_NUMBER_SHIFT | COMMAND_WRITE); COMMAND_WRITE);
wait_for_completion(&test->irq_raised); wait_for_completion(&test->irq_raised);
......
...@@ -18,13 +18,15 @@ ...@@ -18,13 +18,15 @@
#include <linux/pci-epf.h> #include <linux/pci-epf.h>
#include <linux/pci_regs.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_LEGACY_IRQ BIT(0)
#define COMMAND_RAISE_MSI_IRQ BIT(1) #define COMMAND_RAISE_MSI_IRQ BIT(1)
#define MSI_NUMBER_SHIFT 2 /* BIT(2) is reserved for raising MSI-X IRQ command */
#define MSI_NUMBER_MASK (0x3f << MSI_NUMBER_SHIFT) #define COMMAND_READ BIT(3)
#define COMMAND_READ BIT(8) #define COMMAND_WRITE BIT(4)
#define COMMAND_WRITE BIT(9) #define COMMAND_COPY BIT(5)
#define COMMAND_COPY BIT(10)
#define STATUS_READ_SUCCESS BIT(0) #define STATUS_READ_SUCCESS BIT(0)
#define STATUS_READ_FAIL BIT(1) #define STATUS_READ_FAIL BIT(1)
...@@ -56,6 +58,8 @@ struct pci_epf_test_reg { ...@@ -56,6 +58,8 @@ struct pci_epf_test_reg {
u64 dst_addr; u64 dst_addr;
u32 size; u32 size;
u32 checksum; u32 checksum;
u32 irq_type;
u32 irq_number;
} __packed; } __packed;
static struct pci_epf_header test_header = { static struct pci_epf_header test_header = {
...@@ -244,31 +248,39 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) ...@@ -244,31 +248,39 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
return ret; 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 pci_epf *epf = epf_test->epf;
struct device *dev = &epf->dev;
struct pci_epc *epc = epf->epc; struct pci_epc *epc = epf->epc;
enum pci_barno test_reg_bar = epf_test->test_reg_bar; enum pci_barno test_reg_bar = epf_test->test_reg_bar;
struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
reg->status |= STATUS_IRQ_RAISED; 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); 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); 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) static void pci_epf_test_cmd_handler(struct work_struct *work)
{ {
int ret; int ret;
u8 irq; int count;
u8 msi_count;
u32 command; u32 command;
struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test, struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
cmd_handler.work); cmd_handler.work);
struct pci_epf *epf = epf_test->epf; struct pci_epf *epf = epf_test->epf;
struct device *dev = &epf->dev;
struct pci_epc *epc = epf->epc; struct pci_epc *epc = epf->epc;
enum pci_barno test_reg_bar = epf_test->test_reg_bar; enum pci_barno test_reg_bar = epf_test->test_reg_bar;
struct pci_epf_test_reg *reg = epf_test->reg[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) ...@@ -280,7 +292,10 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
reg->command = 0; reg->command = 0;
reg->status = 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) { if (command & COMMAND_RAISE_LEGACY_IRQ) {
reg->status = STATUS_IRQ_RAISED; reg->status = STATUS_IRQ_RAISED;
...@@ -294,7 +309,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) ...@@ -294,7 +309,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
reg->status |= STATUS_WRITE_FAIL; reg->status |= STATUS_WRITE_FAIL;
else else
reg->status |= STATUS_WRITE_SUCCESS; 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; goto reset_handler;
} }
...@@ -304,7 +320,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) ...@@ -304,7 +320,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
reg->status |= STATUS_READ_SUCCESS; reg->status |= STATUS_READ_SUCCESS;
else else
reg->status |= STATUS_READ_FAIL; 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; goto reset_handler;
} }
...@@ -314,16 +331,18 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) ...@@ -314,16 +331,18 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
reg->status |= STATUS_COPY_SUCCESS; reg->status |= STATUS_COPY_SUCCESS;
else else
reg->status |= STATUS_COPY_FAIL; 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; goto reset_handler;
} }
if (command & COMMAND_RAISE_MSI_IRQ) { if (command & COMMAND_RAISE_MSI_IRQ) {
msi_count = pci_epc_get_msi(epc, epf->func_no); count = pci_epc_get_msi(epc, epf->func_no);
if (irq > msi_count || msi_count <= 0) if (reg->irq_number > count || count <= 0)
goto reset_handler; goto reset_handler;
reg->status = STATUS_IRQ_RAISED; 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; goto reset_handler;
} }
...@@ -457,8 +476,10 @@ static int pci_epf_test_bind(struct pci_epf *epf) ...@@ -457,8 +476,10 @@ static int pci_epf_test_bind(struct pci_epf *epf)
return ret; return ret;
ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); 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; return ret;
}
if (!epf_test->linkup_notifier) if (!epf_test->linkup_notifier)
queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
......
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