drivers/gpu/drm/omapdrm/dss/hdmi5.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/omapdrm/dss/hdmi5.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/omapdrm/dss/hdmi5.c
Extension
.c
Size
18430 bytes
Lines
823
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 (ret) {
			DSSERR("Error restoring audio configuration: %d", ret);
			hdmi->audio_abort_cb(&hdmi->pdev->dev);
			hdmi->audio_configured = false;
		}
	}

	spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
	if (hdmi->audio_configured && hdmi->audio_playing)
		hdmi_start_audio_stream(hdmi);
	hdmi->display_enabled = true;
	spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);

done:
	mutex_unlock(&hdmi->lock);
}

static void hdmi5_bridge_disable(struct drm_bridge *bridge,
				 struct drm_atomic_commit *state)
{
	struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
	unsigned long flags;

	mutex_lock(&hdmi->lock);

	spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
	hdmi_stop_audio_stream(hdmi);
	hdmi->display_enabled = false;
	spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);

	hdmi_power_off_full(hdmi);

	mutex_unlock(&hdmi->lock);
}

static const struct drm_edid *hdmi5_bridge_edid_read(struct drm_bridge *bridge,
						     struct drm_connector *connector)
{
	struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
	const struct drm_edid *drm_edid;
	bool need_enable;
	int idlemode;
	int r;

	need_enable = hdmi->core_enabled == false;

	if (need_enable) {
		r = hdmi_core_enable(hdmi);
		if (r)
			return NULL;
	}

	mutex_lock(&hdmi->lock);
	r = hdmi_runtime_get(hdmi);
	BUG_ON(r);

	idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
	/* No-idle mode */
	REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);

	hdmi5_core_ddc_init(&hdmi->core);

	drm_edid = drm_edid_read_custom(connector, hdmi5_core_ddc_read, &hdmi->core);

	hdmi5_core_ddc_uninit(&hdmi->core);

	REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);

	hdmi_runtime_put(hdmi);
	mutex_unlock(&hdmi->lock);

	if (need_enable)
		hdmi_core_disable(hdmi);

	return drm_edid;
}

static const struct drm_bridge_funcs hdmi5_bridge_funcs = {
	.attach = hdmi5_bridge_attach,
	.mode_set = hdmi5_bridge_mode_set,
	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
	.atomic_reset = drm_atomic_helper_bridge_reset,
	.atomic_enable = hdmi5_bridge_enable,
	.atomic_disable = hdmi5_bridge_disable,
	.edid_read = hdmi5_bridge_edid_read,
};

static void hdmi5_bridge_init(struct omap_hdmi *hdmi)
{

Annotation

Implementation Notes