in altera-cvp.c [318:429]
static int altera_cvp_write_init(struct fpga_manager *mgr,
struct fpga_image_info *info,
const char *buf, size_t count)
{
struct altera_cvp_conf *conf = mgr->priv;
u32 iflags, val;
int ret;
iflags = info ? info->flags : 0;
if (iflags & FPGA_MGR_PARTIAL_RECONFIG) {
dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
return -EINVAL;
}
/* Determine allowed clock to data ratio */
if (iflags & FPGA_MGR_COMPRESSED_BITSTREAM)
conf->numclks = 8; /* ratio for all compressed images */
else if (iflags & FPGA_MGR_ENCRYPTED_BITSTREAM)
conf->numclks = 4; /* for uncompressed and encrypted images */
else
conf->numclks = 1; /* for uncompressed and unencrypted images */
/* STEP 1 - read CVP status and check CVP_EN flag */
altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
if (!(val & VSE_CVP_STATUS_CVP_EN)) {
dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val);
return -ENODEV;
}
if (val & VSE_CVP_STATUS_CFG_RDY) {
dev_warn(&mgr->dev, "CvP already started, tear down first\n");
ret = altera_cvp_teardown(mgr, info);
if (ret)
return ret;
}
/*
* STEP 2
* - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned)
*/
/* switch from fabric to PMA clock */
altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
/* set CVP mode */
altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
val |= VSE_CVP_MODE_CTRL_CVP_MODE;
altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
/*
* STEP 3
* - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
*/
if (conf->priv->switch_clk)
conf->priv->switch_clk(conf);
if (conf->priv->clear_state) {
ret = conf->priv->clear_state(conf);
if (ret) {
dev_err(&mgr->dev, "Problem clearing out state\n");
return ret;
}
}
conf->sent_packets = 0;
/* STEP 4 - set CVP_CONFIG bit */
altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
/* request control block to begin transfer using CVP */
val |= VSE_CVP_PROG_CTRL_CONFIG;
altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
/* STEP 5 - poll CVP_CONFIG READY for 1 with timeout */
ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY,
VSE_CVP_STATUS_CFG_RDY,
conf->priv->poll_time_us);
if (ret) {
dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n");
return ret;
}
/*
* STEP 6
* - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
*/
if (conf->priv->switch_clk)
conf->priv->switch_clk(conf);
if (altera_cvp_chkcfg) {
ret = altera_cvp_chk_error(mgr, 0);
if (ret) {
dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n");
return ret;
}
}
/* STEP 7 - set START_XFER */
altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
val |= VSE_CVP_PROG_CTRL_START_XFER;
altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
/* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */
if (conf->priv->switch_clk) {
altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
}
return 0;
}