drivers/gpu/drm/msm/msm_mdss.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/msm_mdss.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/msm/msm_mdss.c
Extension
.c
Size
15472 bytes
Lines
582
Domain
Driver Families
Bucket
drivers/gpu
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 msm_mdss_data {
	u32 reg_bus_bw;
};

struct msm_mdss {
	struct device *dev;

	void __iomem *mmio;
	struct clk_bulk_data *clocks;
	size_t num_clocks;
	bool is_mdp5;
	struct {
		unsigned long enabled_mask;
		struct irq_domain *domain;
	} irq_controller;
	const struct qcom_ubwc_cfg_data *mdss_data;
	u32 reg_bus_bw;
	struct icc_path *mdp_path[2];
	u32 num_mdp_paths;
	struct icc_path *reg_bus_path;
};

static int msm_mdss_parse_data_bus_icc_path(struct device *dev,
					    struct msm_mdss *msm_mdss)
{
	struct icc_path *path0;
	struct icc_path *path1;
	struct icc_path *reg_bus_path;

	path0 = devm_of_icc_get(dev, "mdp0-mem");
	if (IS_ERR_OR_NULL(path0))
		return PTR_ERR_OR_ZERO(path0);

	msm_mdss->mdp_path[0] = path0;
	msm_mdss->num_mdp_paths = 1;

	path1 = devm_of_icc_get(dev, "mdp1-mem");
	if (!IS_ERR_OR_NULL(path1)) {
		msm_mdss->mdp_path[1] = path1;
		msm_mdss->num_mdp_paths++;
	}

	reg_bus_path = of_icc_get(dev, "cpu-cfg");
	if (!IS_ERR_OR_NULL(reg_bus_path))
		msm_mdss->reg_bus_path = reg_bus_path;

	return 0;
}

static void msm_mdss_irq(struct irq_desc *desc)
{
	struct msm_mdss *msm_mdss = irq_desc_get_handler_data(desc);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	u32 interrupts;

	chained_irq_enter(chip, desc);

	interrupts = readl_relaxed(msm_mdss->mmio + REG_MDSS_HW_INTR_STATUS);

	while (interrupts) {
		irq_hw_number_t hwirq = fls(interrupts) - 1;
		int rc;

		rc = generic_handle_domain_irq(msm_mdss->irq_controller.domain,
					       hwirq);
		if (rc < 0) {
			dev_err(msm_mdss->dev, "handle irq fail: irq=%lu rc=%d\n",
				  hwirq, rc);
			break;
		}

		interrupts &= ~(1 << hwirq);
	}

	chained_irq_exit(chip, desc);
}

static void msm_mdss_irq_mask(struct irq_data *irqd)
{
	struct msm_mdss *msm_mdss = irq_data_get_irq_chip_data(irqd);

	/* memory barrier */
	smp_mb__before_atomic();
	clear_bit(irqd->hwirq, &msm_mdss->irq_controller.enabled_mask);
	/* memory barrier */
	smp_mb__after_atomic();
}

static void msm_mdss_irq_unmask(struct irq_data *irqd)
{

Annotation

Implementation Notes