drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
Extension
.c
Size
12187 bytes
Lines
476
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_pxl2dpi {
	struct regmap *regmap;
	struct drm_bridge bridge;
	struct drm_bridge *companion;
	struct device *dev;
	struct imx_sc_ipc *ipc_handle;
	u32 sc_resource;
	u32 in_bus_format;
	u32 out_bus_format;
	u32 pl_sel;
};

#define bridge_to_p2d(b)	container_of(b, struct imx8qxp_pxl2dpi, bridge)

static int imx8qxp_pxl2dpi_bridge_attach(struct drm_bridge *bridge,
					 struct drm_encoder *encoder,
					 enum drm_bridge_attach_flags flags)
{
	struct imx8qxp_pxl2dpi *p2d = bridge->driver_private;

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

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

static void imx8qxp_pxl2dpi_bridge_destroy(struct drm_bridge *bridge)
{
	struct imx8qxp_pxl2dpi *p2d = bridge->driver_private;

	if (!p2d)
		return;

	drm_bridge_put(p2d->companion);
}

static int
imx8qxp_pxl2dpi_bridge_atomic_check(struct drm_bridge *bridge,
				    struct drm_bridge_state *bridge_state,
				    struct drm_crtc_state *crtc_state,
				    struct drm_connector_state *conn_state)
{
	struct imx8qxp_pxl2dpi *p2d = bridge->driver_private;

	p2d->in_bus_format = bridge_state->input_bus_cfg.format;
	p2d->out_bus_format = bridge_state->output_bus_cfg.format;

	return 0;
}

static void
imx8qxp_pxl2dpi_bridge_mode_set(struct drm_bridge *bridge,
				const struct drm_display_mode *mode,
				const struct drm_display_mode *adjusted_mode)
{
	struct imx8qxp_pxl2dpi *p2d = bridge->driver_private;
	struct imx8qxp_pxl2dpi *companion_p2d;
	int ret;

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

	ret = imx_sc_misc_set_control(p2d->ipc_handle, p2d->sc_resource,
				      IMX_SC_C_PXL_LINK_SEL, p2d->pl_sel);
	if (ret)
		DRM_DEV_ERROR(p2d->dev,
			      "failed to set pixel link selection(%u): %d\n",
							p2d->pl_sel, ret);

	switch (p2d->out_bus_format) {
	case MEDIA_BUS_FMT_RGB888_1X24:
		regmap_write(p2d->regmap, PXL2DPI_CTRL, CFG_24BIT);
		break;
	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
		regmap_write(p2d->regmap, PXL2DPI_CTRL, CFG2_18BIT);
		break;
	default:
		DRM_DEV_ERROR(p2d->dev,
			      "unsupported output bus format 0x%08x\n",
							p2d->out_bus_format);
	}

	if (p2d->companion) {

Annotation

Implementation Notes