drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c
Extension
.c
Size
11361 bytes
Lines
440
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 imx8qxp_pc_channel {
	struct drm_bridge bridge;
	struct imx8qxp_pc *pc;
	unsigned int stream_id;
};

struct imx8qxp_pc {
	struct device *dev;
	struct imx8qxp_pc_channel *ch[2];
	struct clk *clk_apb;
	void __iomem *base;
};

static inline u32 imx8qxp_pc_read(struct imx8qxp_pc *pc, unsigned int offset)
{
	return readl(pc->base + offset);
}

static inline void
imx8qxp_pc_write(struct imx8qxp_pc *pc, unsigned int offset, u32 value)
{
	writel(value, pc->base + offset);
}

static inline void
imx8qxp_pc_write_set(struct imx8qxp_pc *pc, unsigned int offset, u32 value)
{
	imx8qxp_pc_write(pc, offset + PC_REG_SET, value);
}

static inline void
imx8qxp_pc_write_clr(struct imx8qxp_pc *pc, unsigned int offset, u32 value)
{
	imx8qxp_pc_write(pc, offset + PC_REG_CLR, value);
}

static enum drm_mode_status
imx8qxp_pc_bridge_mode_valid(struct drm_bridge *bridge,
			     const struct drm_display_info *info,
			     const struct drm_display_mode *mode)
{
	if (mode->hdisplay > 2560)
		return MODE_BAD_HVALUE;

	return MODE_OK;
}

static int imx8qxp_pc_bridge_attach(struct drm_bridge *bridge,
				    struct drm_encoder *encoder,
				    enum drm_bridge_attach_flags flags)
{
	struct imx8qxp_pc_channel *ch = bridge->driver_private;
	struct imx8qxp_pc *pc = ch->pc;

	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
		DRM_DEV_ERROR(pc->dev,
			      "do not support creating a drm_connector\n");
		return -EINVAL;
	}

	return drm_bridge_attach(encoder,
				 ch->bridge.next_bridge, bridge,
				 DRM_BRIDGE_ATTACH_NO_CONNECTOR);
}

static void
imx8qxp_pc_bridge_mode_set(struct drm_bridge *bridge,
			   const struct drm_display_mode *mode,
			   const struct drm_display_mode *adjusted_mode)
{
	struct imx8qxp_pc_channel *ch = bridge->driver_private;
	struct imx8qxp_pc *pc = ch->pc;
	u32 val;
	int ret;

	ret = pm_runtime_get_sync(pc->dev);
	if (ret < 0)
		DRM_DEV_ERROR(pc->dev,
			      "failed to get runtime PM sync: %d\n", ret);

	ret = clk_prepare_enable(pc->clk_apb);
	if (ret)
		DRM_DEV_ERROR(pc->dev, "%s: failed to enable apb clock: %d\n",
			      __func__,  ret);

	/* HSYNC to pixel link is active low. */
	imx8qxp_pc_write_clr(pc, PC_CTRL_REG,
			     PC_DISP_HSYNC_POLARITY(ch->stream_id));

	/* VSYNC to pixel link is active low. */

Annotation

Implementation Notes