drivers/gpu/drm/stm/ltdc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/stm/ltdc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/stm/ltdc.c
Extension
.c
Size
64825 bytes
Lines
2115
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

if (en_iter->crtc == crtc) {
			encoder = en_iter;
			break;
		}

	if (encoder) {
		/* get bridge from encoder */
		list_for_each_entry(br_iter, &encoder->bridge_chain, chain_node)
			if (br_iter->encoder == encoder) {
				bridge = br_iter;
				break;
			}

		/* Get the connector from encoder */
		drm_connector_list_iter_begin(ddev, &iter);
		drm_for_each_connector_iter(connector, &iter)
			if (connector->encoder == encoder)
				break;
		drm_connector_list_iter_end(&iter);
	}

	if (bridge && bridge->timings) {
		bus_flags = bridge->timings->input_bus_flags;
	} else if (connector) {
		bus_flags = connector->display_info.bus_flags;
		if (connector->display_info.num_bus_formats)
			bus_formats = connector->display_info.bus_formats[0];
	}

	if (!pm_runtime_active(ddev->dev)) {
		ret = pm_runtime_get_sync(ddev->dev);
		if (ret) {
			drm_err(crtc->dev, "Failed to set mode, cannot get sync\n");
			return;
		}
	}

	drm_dbg_driver(crtc->dev, "CRTC:%d mode:%s\n", crtc->base.id, mode->name);
	drm_dbg_driver(crtc->dev, "Video mode: %dx%d", mode->hdisplay, mode->vdisplay);
	drm_dbg_driver(crtc->dev, " hfp %d hbp %d hsl %d vfp %d vbp %d vsl %d\n",
		       mode->hsync_start - mode->hdisplay,
		       mode->htotal - mode->hsync_end,
		       mode->hsync_end - mode->hsync_start,
		       mode->vsync_start - mode->vdisplay,
		       mode->vtotal - mode->vsync_end,
		       mode->vsync_end - mode->vsync_start);

	/* Convert video timings to ltdc timings */
	hsync = mode->hsync_end - mode->hsync_start - 1;
	vsync = mode->vsync_end - mode->vsync_start - 1;
	accum_hbp = mode->htotal - mode->hsync_start - 1;
	accum_vbp = mode->vtotal - mode->vsync_start - 1;
	accum_act_w = accum_hbp + mode->hdisplay;
	accum_act_h = accum_vbp + mode->vdisplay;
	total_width = mode->htotal - 1;
	total_height = mode->vtotal - 1;

	/* Configures the HS, VS, DE and PC polarities. Default Active Low */
	val = 0;

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

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

	if (bus_flags & DRM_BUS_FLAG_DE_LOW)
		val |= GCR_DEPOL;

	if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
		val |= GCR_PCPOL;

	regmap_update_bits(ldev->regmap, LTDC_GCR,
			   GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);

	/* Set Synchronization size */
	val = (hsync << 16) | vsync;
	regmap_update_bits(ldev->regmap, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);

	/* Set Accumulated Back porch */
	val = (accum_hbp << 16) | accum_vbp;
	regmap_update_bits(ldev->regmap, LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);

	/* Set Accumulated Active Width */
	val = (accum_act_w << 16) | accum_act_h;
	regmap_update_bits(ldev->regmap, LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);

	/* Set total width & height */
	val = (total_width << 16) | total_height;
	regmap_update_bits(ldev->regmap, LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);

Annotation

Implementation Notes