drivers/soc/fsl/qbman/bman_ccsr.c

Source file repositories/reference/linux-study-clean/drivers/soc/fsl/qbman/bman_ccsr.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/fsl/qbman/bman_ccsr.c
Extension
.c
Size
8829 bytes
Lines
304
Domain
Driver Families
Bucket
drivers/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 bman_hwerr_txt {
	u32 mask;
	const char *txt;
};

static const struct bman_hwerr_txt bman_hwerr_txts[] = {
	{ BM_EIRQ_IVCI, "Invalid Command Verb" },
	{ BM_EIRQ_FLWI, "FBPR Low Watermark" },
	{ BM_EIRQ_MBEI, "Multi-bit ECC Error" },
	{ BM_EIRQ_SBEI, "Single-bit ECC Error" },
	{ BM_EIRQ_BSCN, "Pool State Change Notification" },
};

/* Only trigger low water mark interrupt once only */
#define BMAN_ERRS_TO_DISABLE BM_EIRQ_FLWI

/* Pointer to the start of the BMan's CCSR space */
static u32 __iomem *bm_ccsr_start;

static inline u32 bm_ccsr_in(u32 offset)
{
	return ioread32be(bm_ccsr_start + offset/4);
}
static inline void bm_ccsr_out(u32 offset, u32 val)
{
	iowrite32be(val, bm_ccsr_start + offset/4);
}

static void bm_get_version(u16 *id, u8 *major, u8 *minor)
{
	u32 v = bm_ccsr_in(REG_IP_REV_1);
	*id = (v >> 16);
	*major = (v >> 8) & 0xff;
	*minor = v & 0xff;
}

/* signal transactions for FBPRs with higher priority */
#define FBPR_AR_RPRIO_HI BIT(30)

/* Track if probe has occurred and if cleanup is required */
static int __bman_probed;
static int __bman_requires_cleanup;


static int bm_set_memory(u64 ba, u32 size)
{
	u32 bar, bare;
	u32 exp = ilog2(size);
	/* choke if size isn't within range */
	DPAA_ASSERT(size >= 4096 && size <= 1024*1024*1024 &&
		   is_power_of_2(size));
	/* choke if '[e]ba' has lower-alignment than 'size' */
	DPAA_ASSERT(!(ba & (size - 1)));

	/* Check to see if BMan has already been initialized */
	bar = bm_ccsr_in(REG_FBPR_BAR);
	if (bar) {
		/* Maker sure ba == what was programmed) */
		bare = bm_ccsr_in(REG_FBPR_BARE);
		if (bare != upper_32_bits(ba) || bar != lower_32_bits(ba)) {
			pr_err("Attempted to reinitialize BMan with different BAR, got 0x%llx read BARE=0x%x BAR=0x%x\n",
			       ba, bare, bar);
			return -ENOMEM;
		}
		pr_info("BMan BAR already configured\n");
		__bman_requires_cleanup = 1;
		return 1;
	}

	bm_ccsr_out(REG_FBPR_BARE, upper_32_bits(ba));
	bm_ccsr_out(REG_FBPR_BAR, lower_32_bits(ba));
	bm_ccsr_out(REG_FBPR_AR, exp - 1);
	return 0;
}

/*
 * Location and size of BMan private memory
 *
 * Ideally we would use the DMA API to turn rmem->base into a DMA address
 * (especially if iommu translations ever get involved).  Unfortunately, the
 * DMA API currently does not allow mapping anything that is not backed with
 * a struct page.
 */
static dma_addr_t fbpr_a;
static size_t fbpr_sz;

static irqreturn_t bman_isr(int irq, void *ptr)
{
	u32 isr_val, ier_val, ecsr_val, isr_mask, i;
	struct device *dev = ptr;

Annotation

Implementation Notes