drivers/gpu/drm/sun4i/sun8i_tcon_top.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/sun4i/sun8i_tcon_top.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/sun4i/sun8i_tcon_top.c
Extension
.c
Size
8099 bytes
Lines
313
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 sun8i_tcon_top_quirks {
	bool has_tcon_tv1;
	bool has_dsi;
};

static bool sun8i_tcon_top_node_is_tcon_top(struct device_node *node)
{
	return !!of_match_node(sun8i_tcon_top_of_table, node);
}

int sun8i_tcon_top_set_hdmi_src(struct device *dev, int tcon)
{
	struct sun8i_tcon_top *tcon_top = dev_get_drvdata(dev);
	unsigned long flags;
	u32 val;

	if (!sun8i_tcon_top_node_is_tcon_top(dev->of_node)) {
		dev_err(dev, "Device is not TCON TOP!\n");
		return -EINVAL;
	}

	if (tcon < 2 || tcon > 3) {
		dev_err(dev, "TCON index must be 2 or 3!\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&tcon_top->reg_lock, flags);

	val = readl(tcon_top->regs + TCON_TOP_GATE_SRC_REG);
	val &= ~TCON_TOP_HDMI_SRC_MSK;
	val |= FIELD_PREP(TCON_TOP_HDMI_SRC_MSK, tcon - 1);
	writel(val, tcon_top->regs + TCON_TOP_GATE_SRC_REG);

	spin_unlock_irqrestore(&tcon_top->reg_lock, flags);

	return 0;
}
EXPORT_SYMBOL(sun8i_tcon_top_set_hdmi_src);

int sun8i_tcon_top_de_config(struct device *dev, int mixer, int tcon)
{
	struct sun8i_tcon_top *tcon_top = dev_get_drvdata(dev);
	unsigned long flags;
	u32 reg;

	if (!sun8i_tcon_top_node_is_tcon_top(dev->of_node)) {
		dev_err(dev, "Device is not TCON TOP!\n");
		return -EINVAL;
	}

	if (mixer > 1) {
		dev_err(dev, "Mixer index is too high!\n");
		return -EINVAL;
	}

	if (tcon > 3) {
		dev_err(dev, "TCON index is too high!\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&tcon_top->reg_lock, flags);

	reg = readl(tcon_top->regs + TCON_TOP_PORT_SEL_REG);
	if (mixer == 0) {
		reg &= ~TCON_TOP_PORT_DE0_MSK;
		reg |= FIELD_PREP(TCON_TOP_PORT_DE0_MSK, tcon);
	} else {
		reg &= ~TCON_TOP_PORT_DE1_MSK;
		reg |= FIELD_PREP(TCON_TOP_PORT_DE1_MSK, tcon);
	}
	writel(reg, tcon_top->regs + TCON_TOP_PORT_SEL_REG);

	spin_unlock_irqrestore(&tcon_top->reg_lock, flags);

	return 0;
}
EXPORT_SYMBOL(sun8i_tcon_top_de_config);


static struct clk_hw *sun8i_tcon_top_register_gate(struct device *dev,
						   const char *parent,
						   void __iomem *regs,
						   spinlock_t *lock,
						   u8 bit, int name_index)
{
	const char *clk_name, *parent_name;
	int ret, index;

	index = of_property_match_string(dev->of_node, "clock-names", parent);
	if (index < 0)

Annotation

Implementation Notes