drivers/fpga/socfpga-a10.c

Source file repositories/reference/linux-study-clean/drivers/fpga/socfpga-a10.c

File Facts

System
Linux kernel
Corpus path
drivers/fpga/socfpga-a10.c
Extension
.c
Size
15439 bytes
Lines
550
Domain
Driver Families
Bucket
drivers/fpga
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct a10_fpga_priv {
	struct regmap *regmap;
	void __iomem *fpga_data_addr;
	struct clk *clk;
};

static bool socfpga_a10_fpga_writeable_reg(struct device *dev, unsigned int 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:
		return true;
	}
	return false;
}

static bool socfpga_a10_fpga_readable_reg(struct device *dev, unsigned int 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:
		return true;
	}
	return false;
}

static const struct regmap_config socfpga_a10_fpga_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.writeable_reg = socfpga_a10_fpga_writeable_reg,
	.readable_reg = socfpga_a10_fpga_readable_reg,
	.max_register = A10_FPGAMGR_IMGCFG_STAT_OFST,
	.cache_type = REGCACHE_NONE,
};

/*
 * from the register map description of cdratio in imgcfg_ctrl_02:
 *  Normal Configuration    : 32bit Passive Parallel
 *  Partial Reconfiguration : 16bit Passive Parallel
 */
static void socfpga_a10_fpga_set_cfg_width(struct a10_fpga_priv *priv,
					   int width)
{
	width <<= A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT;

	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
			   A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, width);
}

static void socfpga_a10_fpga_generate_dclks(struct a10_fpga_priv *priv,
					    u32 count)
{
	u32 val;

	/* Clear any existing DONE status. */
	regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
		     A10_FPGAMGR_DCLKSTAT_DCLKDONE);

	/* Issue the DCLK regmap. */
	regmap_write(priv->regmap, A10_FPGAMGR_DCLKCNT_OFST, count);

	/* wait till the dclkcnt done */
	regmap_read_poll_timeout(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, val,
				 val, 1, 100);

	/* Clear DONE status. */
	regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
		     A10_FPGAMGR_DCLKSTAT_DCLKDONE);
}

#define RBF_ENCRYPTION_MODE_OFFSET		69
#define RBF_DECOMPRESS_OFFSET			229

static int socfpga_a10_fpga_encrypted(u32 *buf32, size_t buf32_size)
{
	if (buf32_size < RBF_ENCRYPTION_MODE_OFFSET + 1)
		return -EINVAL;

	/* Is the bitstream encrypted? */
	return ((buf32[RBF_ENCRYPTION_MODE_OFFSET] >> 2) & 3) != 0;
}

Annotation

Implementation Notes