PCIe driver: generalize code to load things from host memory

This commit is contained in:
2023-11-18 16:16:16 +01:00
parent b7e09f20ac
commit 95058de3ca
+16 -101
View File
@@ -304,10 +304,10 @@ void jfjoch_clr_net_counters(struct jfjoch_drvdata *drvdata) {
iowrite32(0, drvdata->bar0 + ACTION_CONFIG_OFFSET);
}
int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct DataCollectionConfig *config) {
int jfjoch_load_from_host(struct jfjoch_drvdata *drvdata, struct DataCollectionConfig *config,
u32 destination, u32 cell_count) {
struct device *const dev = &drvdata->pdev->dev;
u32 i, tmp, hls_ctrl_reg;
u32 cell_count = config->nmodules * (3 + 3 * config->nstorage_cells);
hls_ctrl_reg = ioread32(drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL);
if ((hls_ctrl_reg & (1<<2)) == 0) {
@@ -334,7 +334,7 @@ int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct DataCollectio
iowrite32(config->nmodules, drvdata->bar0 + ADDR_LOAD_CALIBRATION_MOD);
iowrite32(config->nstorage_cells, drvdata->bar0 + ADDR_LOAD_CALIBRATION_SC);
iowrite32(LOAD_CALIBRATION_DEST_CALIB, drvdata->bar0 + ADDR_LOAD_CALIBRATION_DEST);
iowrite32(destination, drvdata->bar0 + ADDR_LOAD_CALIBRATION_DEST);
iowrite32(0x1, drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL);
i = 0;
@@ -344,19 +344,18 @@ int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct DataCollectio
break;
msleep(10);
i++;
dev_info(dev, "Load calibration status 0x%x", tmp);
}
// STOP H2C channel
iowrite32(0, drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0x04);
if (i == 1000) {
dev_err(dev, "Load calibration didn't finish in 10 seconds\n");
dev_err(dev, "Loading didn't finish in 10 seconds\n");
return -ETIMEDOUT;
} else {
u32 ret = ioread32(drvdata->bar0 + ADDR_LOAD_CALIBRATION_RETURN);
if (ret != 0) {
dev_err(dev, "Load calibration error\n");
dev_err(dev, "Loading error\n");
return -EINVAL;
}
}
@@ -364,107 +363,23 @@ int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct DataCollectio
return 0;
}
int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct DataCollectionConfig *config) {
struct device *const dev = &drvdata->pdev->dev;
dev_info(dev, "Loading calibration for %d module(s) and %d storage cell(s)", config->nmodules, config->nstorage_cells);
return jfjoch_load_from_host(drvdata, config, LOAD_CALIBRATION_DEST_CALIB,
config->nmodules * (3 + 3 * config->nstorage_cells));
}
int jfjoch_load_integration_map(struct jfjoch_drvdata *drvdata, struct DataCollectionConfig *config) {
struct device *const dev = &drvdata->pdev->dev;
u32 i;
u32 cell_count = config->nmodules * 2;
if (cell_count > drvdata->nbuf) {
dev_err(dev, "Not enough buffers to support this card\n");
return -EINVAL;
}
for (i = 0; i < cell_count; i++) {
u64 addr = drvdata->bufs[i].dma_address;
iowrite32(PCI_DMA_L(addr), drvdata->bar0 + ADDR_LOAD_CALIBRATION_MEM + i * 2 * 4);
iowrite32(PCI_DMA_H(addr), drvdata->bar0 + ADDR_LOAD_CALIBRATION_MEM + (i * 2 + 1) * 4);
}
// Start DMA
// Clear counters and RUN H2C
iowrite32((1 << 1), drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0xC0);
iowrite32((1 << 2), drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0xC0);
iowrite32(JFJOCH_DMA_SETTINGS, drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0x04);
iowrite32(config->nmodules, drvdata->bar0 + ADDR_LOAD_CALIBRATION_MOD);
iowrite32(LOAD_CALIBRATION_DEST_INTEGRATION, drvdata->bar0 + ADDR_LOAD_CALIBRATION_DEST);
iowrite32(0x1, drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL);
i = 0;
while (i < 1000) {
if (ioread32(drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL) & (1 << 1))
break;
msleep(10);
i++;
}
// STOP H2C channel
iowrite32(0, drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0x04);
if (i == 1000) {
dev_err(dev, "Load integration map didn't finish in 10 seconds\n");
return -ETIMEDOUT;
} else {
u32 ret = ioread32(drvdata->bar0 + ADDR_LOAD_CALIBRATION_RETURN);
if (ret != 0) {
dev_err(dev, "Load integration map error\n");
return -EINVAL;
}
}
return 0;
dev_info(dev, "Loading integration map for %d module(s)", config->nmodules);
return jfjoch_load_from_host(drvdata, config, LOAD_CALIBRATION_DEST_INTEGRATION, config->nmodules * 2);
}
int jfjoch_load_internal_generator_frame(struct jfjoch_drvdata *drvdata, struct DataCollectionConfig *config) {
struct device *const dev = &drvdata->pdev->dev;
u32 i;
u32 cell_count = config->nmodules;
if (cell_count > drvdata->nbuf) {
dev_err(dev, "Not enough buffers to support this card\n");
return -EINVAL;
}
for (i = 0; i < cell_count; i++) {
u64 addr = drvdata->bufs[i].dma_address;
iowrite32(PCI_DMA_L(addr), drvdata->bar0 + ADDR_LOAD_CALIBRATION_MEM + i * 2 * 4);
iowrite32(PCI_DMA_H(addr), drvdata->bar0 + ADDR_LOAD_CALIBRATION_MEM + (i * 2 + 1) * 4);
}
// Start DMA
// Clear counters and RUN H2C
iowrite32((1 << 1), drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0xC0);
iowrite32((1 << 2), drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0xC0);
iowrite32(JFJOCH_DMA_SETTINGS, drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0x04);
iowrite32(config->nmodules, drvdata->bar0 + ADDR_LOAD_CALIBRATION_MOD);
iowrite32(LOAD_CALIBRATION_DEST_FRAME_GEN, drvdata->bar0 + ADDR_LOAD_CALIBRATION_DEST);
iowrite32(0x1, drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL);
i = 0;
while (i < 1000) {
if (ioread32(drvdata->bar0 + ADDR_LOAD_CALIBRATION_CTRL) & (1 << 1))
break;
msleep(10);
i++;
}
// STOP H2C channel
iowrite32(0, drvdata->bar0 + PCIE_OFFSET + (0<<12) + 0x04);
if (i == 1000) {
dev_err(dev, "Load generator frame didn't finish in 10 seconds\n");
return -ETIMEDOUT;
} else {
u32 ret = ioread32(drvdata->bar0 + ADDR_LOAD_CALIBRATION_RETURN);
if (ret != 0) {
dev_err(dev, "Load generator frame error\n");
return -EINVAL;
}
}
return 0;
dev_info(dev, "Loading igenerator frame for %d module(s)", config->nmodules);
return jfjoch_load_from_host(drvdata, config, LOAD_CALIBRATION_DEST_FRAME_GEN, config->nmodules);
}
int jfjoch_run_frame_gen(struct jfjoch_drvdata *drvdata, struct FrameGeneratorConfig *config) {