/* * struct a10_fpga_priv - private data for fpga manager * @regmap: regmap for register access * @fpga_data_addr: iomap for single address data register to FPGA * @clk: clock
*/ struct a10_fpga_priv { struct regmap *regmap; void __iomem *fpga_data_addr; struct clk *clk;
};
staticbool socfpga_a10_fpga_writeable_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case A10_FPGAMGR_DCLKCNT_OFST: case A10_FPGAMGR_DCLKSTAT_OFST: case A10_FPGAMGR_IMGCFG_CTL_00_OFST: case A10_FPGAMGR_IMGCFG_CTL_01_OFST: case A10_FPGAMGR_IMGCFG_CTL_02_OFST: returntrue;
} returnfalse;
}
staticbool socfpga_a10_fpga_readable_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case A10_FPGAMGR_DCLKCNT_OFST: case A10_FPGAMGR_DCLKSTAT_OFST: case A10_FPGAMGR_IMGCFG_CTL_00_OFST: case A10_FPGAMGR_IMGCFG_CTL_01_OFST: case A10_FPGAMGR_IMGCFG_CTL_02_OFST: case A10_FPGAMGR_IMGCFG_STAT_OFST: returntrue;
} returnfalse;
}
/* 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);
/* 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);
}
/* * write data to the FPGA data register
*/ staticint socfpga_a10_fpga_write(struct fpga_manager *mgr, constchar *buf,
size_t count)
{ struct a10_fpga_priv *priv = mgr->priv;
u32 *buffer_32 = (u32 *)buf;
size_t i = 0;
if (count <= 0) return -EINVAL;
/* Write out the complete 32-bit chunks */ while (count >= sizeof(u32)) {
writel(buffer_32[i++], priv->fpga_data_addr);
count -= sizeof(u32);
}
/* Write out remaining non 32-bit chunks */ switch (count) { case 3:
writel(buffer_32[i++] & 0x00ffffff, priv->fpga_data_addr); break; case 2:
writel(buffer_32[i++] & 0x0000ffff, priv->fpga_data_addr); break; case 1:
writel(buffer_32[i++] & 0x000000ff, priv->fpga_data_addr); break; case 0: break; default: /* This will never happen */ return -EFAULT;
}
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
/* First mmio base is for register access */
reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(reg_base)) return PTR_ERR(reg_base);
/* Second mmio base is for writing FPGA image data */
priv->fpga_data_addr = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(priv->fpga_data_addr)) return PTR_ERR(priv->fpga_data_addr);
/* regmap for register access */
priv->regmap = devm_regmap_init_mmio(dev, reg_base,
&socfpga_a10_fpga_regmap_config); if (IS_ERR(priv->regmap)) return -ENODEV;
priv->clk = devm_clk_get(dev, NULL); if (IS_ERR(priv->clk)) {
dev_err(dev, "no clock specified\n"); return PTR_ERR(priv->clk);
}
ret = clk_prepare_enable(priv->clk); if (ret) {
dev_err(dev, "could not enable clock\n"); return -EBUSY;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.