drivers/gpu/ipu-v3/ipu-smfc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/ipu-v3/ipu-smfc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/ipu-v3/ipu-smfc.c
Extension
.c
Size
4164 bytes
Lines
203
Domain
Driver Families
Bucket
drivers/gpu
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 ipu_smfc {
	struct ipu_smfc_priv *priv;
	int chno;
	bool inuse;
};

struct ipu_smfc_priv {
	void __iomem *base;
	spinlock_t lock;
	struct ipu_soc *ipu;
	struct ipu_smfc channel[4];
	int use_count;
};

/*SMFC Registers */
#define SMFC_MAP	0x0000
#define SMFC_WMC	0x0004
#define SMFC_BS		0x0008

int ipu_smfc_set_burstsize(struct ipu_smfc *smfc, int burstsize)
{
	struct ipu_smfc_priv *priv = smfc->priv;
	unsigned long flags;
	u32 val, shift;

	spin_lock_irqsave(&priv->lock, flags);

	shift = smfc->chno * 4;
	val = readl(priv->base + SMFC_BS);
	val &= ~(0xf << shift);
	val |= burstsize << shift;
	writel(val, priv->base + SMFC_BS);

	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(ipu_smfc_set_burstsize);

int ipu_smfc_map_channel(struct ipu_smfc *smfc, int csi_id, int mipi_id)
{
	struct ipu_smfc_priv *priv = smfc->priv;
	unsigned long flags;
	u32 val, shift;

	spin_lock_irqsave(&priv->lock, flags);

	shift = smfc->chno * 3;
	val = readl(priv->base + SMFC_MAP);
	val &= ~(0x7 << shift);
	val |= ((csi_id << 2) | mipi_id) << shift;
	writel(val, priv->base + SMFC_MAP);

	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(ipu_smfc_map_channel);

int ipu_smfc_set_watermark(struct ipu_smfc *smfc, u32 set_level, u32 clr_level)
{
	struct ipu_smfc_priv *priv = smfc->priv;
	unsigned long flags;
	u32 val, shift;

	spin_lock_irqsave(&priv->lock, flags);

	shift = smfc->chno * 6 + (smfc->chno > 1 ? 4 : 0);
	val = readl(priv->base + SMFC_WMC);
	val &= ~(0x3f << shift);
	val |= ((clr_level << 3) | set_level) << shift;
	writel(val, priv->base + SMFC_WMC);

	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(ipu_smfc_set_watermark);

int ipu_smfc_enable(struct ipu_smfc *smfc)
{
	struct ipu_smfc_priv *priv = smfc->priv;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	if (!priv->use_count)
		ipu_module_enable(priv->ipu, IPU_CONF_SMFC_EN);

	priv->use_count++;

Annotation

Implementation Notes