drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
Extension
.c
Size
5911 bytes
Lines
207
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 imx8mp_hdmi_pvi {
	struct drm_bridge	bridge;
	struct device		*dev;
	void __iomem		*regs;
};

static inline struct imx8mp_hdmi_pvi *
to_imx8mp_hdmi_pvi(struct drm_bridge *bridge)
{
	return container_of(bridge, struct imx8mp_hdmi_pvi, bridge);
}

static int imx8mp_hdmi_pvi_bridge_attach(struct drm_bridge *bridge,
					 struct drm_encoder *encoder,
					 enum drm_bridge_attach_flags flags)
{
	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);

	return drm_bridge_attach(encoder, pvi->bridge.next_bridge,
				 bridge, flags);
}

static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
					  struct drm_atomic_commit *state)
{
	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
	struct drm_connector_state *conn_state;
	struct drm_bridge_state *bridge_state;
	const struct drm_display_mode *mode;
	struct drm_crtc_state *crtc_state;
	struct drm_connector *connector;
	u32 bus_flags = 0, val;

	bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
	conn_state = drm_atomic_get_new_connector_state(state, connector);
	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);

	if (WARN_ON(pm_runtime_resume_and_get(pvi->dev)))
		return;

	mode = &crtc_state->adjusted_mode;

	val = FIELD_PREP(PVI_CTRL_MODE_MASK, PVI_CTRL_MODE_LCDIF) | PVI_CTRL_EN;

	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
		val |= PVI_CTRL_OP_VSYNC_POL | PVI_CTRL_INP_VSYNC_POL;

	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
		val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL;

	if (pvi->bridge.next_bridge->timings)
		bus_flags = pvi->bridge.next_bridge->timings->input_bus_flags;
	else if (bridge_state)
		bus_flags = bridge_state->input_bus_cfg.flags;

	if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
		val |= PVI_CTRL_OP_DE_POL | PVI_CTRL_INP_DE_POL;

	writel(val, pvi->regs + HTX_PVI_CTRL);
}

static void imx8mp_hdmi_pvi_bridge_disable(struct drm_bridge *bridge,
					   struct drm_atomic_commit *state)
{
	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);

	writel(0x0, pvi->regs + HTX_PVI_CTRL);

	pm_runtime_put(pvi->dev);
}

static u32 *
imx8mp_hdmi_pvi_bridge_get_input_bus_fmts(struct drm_bridge *bridge,
					  struct drm_bridge_state *bridge_state,
					  struct drm_crtc_state *crtc_state,
					  struct drm_connector_state *conn_state,
					  u32 output_fmt,
					  unsigned int *num_input_fmts)
{
	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
	struct drm_bridge *next_bridge = pvi->bridge.next_bridge;
	struct drm_bridge_state *next_state;

	if (!next_bridge->funcs->atomic_get_input_bus_fmts)
		return NULL;

	next_state = drm_atomic_get_new_bridge_state(crtc_state->state,
						     next_bridge);

Annotation

Implementation Notes