in dfl-fme-mgr.c [165:218]
static int fme_mgr_write(struct fpga_manager *mgr,
const char *buf, size_t count)
{
struct device *dev = &mgr->dev;
struct fme_mgr_priv *priv = mgr->priv;
void __iomem *fme_pr = priv->ioaddr;
u64 pr_ctrl, pr_status, pr_data;
int delay = 0, pr_credit, i = 0;
dev_dbg(dev, "start request\n");
pr_ctrl = readq(fme_pr + FME_PR_CTRL);
pr_ctrl |= FME_PR_CTRL_PR_START;
writeq(pr_ctrl, fme_pr + FME_PR_CTRL);
dev_dbg(dev, "pushing data from bitstream to HW\n");
/*
* driver can push data to PR hardware using PR_DATA register once HW
* has enough pr_credit (> 1), pr_credit reduces one for every 32bit
* pr data write to PR_DATA register. If pr_credit <= 1, driver needs
* to wait for enough pr_credit from hardware by polling.
*/
pr_status = readq(fme_pr + FME_PR_STS);
pr_credit = FIELD_GET(FME_PR_STS_PR_CREDIT, pr_status);
while (count > 0) {
while (pr_credit <= 1) {
if (delay++ > PR_WAIT_TIMEOUT) {
dev_err(dev, "PR_CREDIT timeout\n");
return -ETIMEDOUT;
}
udelay(1);
pr_status = readq(fme_pr + FME_PR_STS);
pr_credit = FIELD_GET(FME_PR_STS_PR_CREDIT, pr_status);
}
if (count < 4) {
dev_err(dev, "Invalid PR bitstream size\n");
return -EINVAL;
}
pr_data = 0;
pr_data |= FIELD_PREP(FME_PR_DATA_PR_DATA_RAW,
*(((u32 *)buf) + i));
writeq(pr_data, fme_pr + FME_PR_DATA);
count -= 4;
pr_credit--;
i++;
}
return 0;
}