static int altera_cvp_write_init()

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;
}