static int socfpga_a10_fpga_write_init()

in socfpga-a10.c [272:349]


static int socfpga_a10_fpga_write_init(struct fpga_manager *mgr,
				       struct fpga_image_info *info,
				       const char *buf, size_t count)
{
	struct a10_fpga_priv *priv = mgr->priv;
	unsigned int cfg_width;
	u32 msel, stat, mask;
	int ret;

	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG)
		cfg_width = CFGWDTH_16;
	else
		return -EINVAL;

	/* Check for passive parallel (msel == 000 or 001) */
	msel = socfpga_a10_fpga_read_stat(priv);
	msel &= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK;
	msel >>= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT;
	if ((msel != 0) && (msel != 1)) {
		dev_dbg(&mgr->dev, "Fail: invalid msel=%d\n", msel);
		return -EINVAL;
	}

	/* Make sure no external devices are interfering */
	stat = socfpga_a10_fpga_read_stat(priv);
	mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN |
	       A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN;
	if ((stat & mask) != mask)
		return -EINVAL;

	/* Set cfg width */
	socfpga_a10_fpga_set_cfg_width(priv, cfg_width);

	/* Determine cd ratio from bitstream header and set cd ratio */
	ret = socfpga_a10_fpga_set_cdratio(mgr, cfg_width, buf, count);
	if (ret)
		return ret;

	/*
	 * Clear s2f_nce to enable chip select.  Leave pr_request
	 * unasserted and override disabled.
	 */
	regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
		     A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);

	/* Set cfg_ctrl to enable s2f dclk and data */
	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL,
			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL);

	/*
	 * Disable overrides not needed for pr.
	 * s2f_config==1 leaves reset deasseted.
	 */
	regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_00_OFST,
		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG |
		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS |
		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE |
		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG);

	/* Enable override for data, dclk, nce, and pr_request to CSS */
	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0);

	/* Send some clocks to clear out any errors */
	socfpga_a10_fpga_generate_dclks(priv, 256);

	/* Assert pr_request */
	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST,
			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST);

	/* Provide 2048 DCLKs before starting the config data streaming. */
	socfpga_a10_fpga_generate_dclks(priv, 0x7ff);

	/* Wait for pr_ready */
	return socfpga_a10_fpga_wait_for_pr_ready(priv);
}