drivers/gpu/drm/radeon/dce6_afmt.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/dce6_afmt.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/radeon/dce6_afmt.c
Extension
.c
Size
10127 bytes
Lines
321
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 (rdev->audio.pin[i].connected) {
			pin = &rdev->audio.pin[i];
			pin_count = 0;

			list_for_each_entry(encoder, &rdev_to_drm(rdev)->mode_config.encoder_list, head) {
				if (radeon_encoder_is_digital(encoder)) {
					radeon_encoder = to_radeon_encoder(encoder);
					dig = radeon_encoder->enc_priv;
					if (dig->pin == pin)
						pin_count++;
				}
			}

			if (pin_count == 0)
				return pin;
		}
	}
	if (!pin)
		DRM_ERROR("No connected audio pins found!\n");
	return pin;
}

void dce6_afmt_select_pin(struct drm_encoder *encoder)
{
	struct radeon_device *rdev = encoder->dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;

	if (!dig || !dig->afmt || !dig->pin)
		return;

	WREG32(AFMT_AUDIO_SRC_CONTROL +  dig->afmt->offset,
	       AFMT_AUDIO_SRC_SELECT(dig->pin->id));
}

void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
				    struct drm_connector *connector,
				    struct drm_display_mode *mode)
{
	struct radeon_device *rdev = encoder->dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
	u32 tmp = 0;

	if (!dig || !dig->afmt || !dig->pin)
		return;

	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
		if (connector->latency_present[1])
			tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
				AUDIO_LIPSYNC(connector->audio_latency[1]);
		else
			tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
	} else {
		if (connector->latency_present[0])
			tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
				AUDIO_LIPSYNC(connector->audio_latency[0]);
		else
			tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
	}
	WREG32_ENDPOINT(dig->pin->offset,
			AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
}

void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
					     u8 *sadb, int sad_count)
{
	struct radeon_device *rdev = encoder->dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
	u32 tmp;

	if (!dig || !dig->afmt || !dig->pin)
		return;

	/* program the speaker allocation */
	tmp = RREG32_ENDPOINT(dig->pin->offset,
			      AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
	tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
	/* set HDMI mode */
	tmp |= HDMI_CONNECTION;
	if (sad_count)
		tmp |= SPEAKER_ALLOCATION(sadb[0]);
	else
		tmp |= SPEAKER_ALLOCATION(5); /* stereo */
	WREG32_ENDPOINT(dig->pin->offset,
			AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
}

void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,

Annotation

Implementation Notes