drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
Extension
.c
Size
17854 bytes
Lines
717
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 (!dce110_timing_generator_v_is_counter_moving(tg)) {
			/* error - no point to wait if counter is not moving */
			break;
		}
	}

	while (!dce110_timing_generator_v_is_in_vertical_blank(tg)) {
		if (!dce110_timing_generator_v_is_counter_moving(tg)) {
			/* error - no point to wait if counter is not moving */
			break;
		}
	}
}

/*
 * Wait till we are in VActive (anywhere in VActive)
 */
static void dce110_timing_generator_v_wait_for_vactive(struct timing_generator *tg)
{
	while (dce110_timing_generator_v_is_in_vertical_blank(tg)) {
		if (!dce110_timing_generator_v_is_counter_moving(tg)) {
			/* error - no point to wait if counter is not moving */
			break;
		}
	}
}

static void dce110_timing_generator_v_wait_for_state(struct timing_generator *tg,
	enum crtc_state state)
{
	switch (state) {
	case CRTC_STATE_VBLANK:
		dce110_timing_generator_v_wait_for_vblank(tg);
		break;

	case CRTC_STATE_VACTIVE:
		dce110_timing_generator_v_wait_for_vactive(tg);
		break;

	default:
		break;
	}
}

static void dce110_timing_generator_v_program_blanking(
	struct timing_generator *tg,
	const struct dc_crtc_timing *timing)
{
	uint32_t vsync_offset = timing->v_border_bottom +
			timing->v_front_porch;
	uint32_t v_sync_start = timing->v_addressable + vsync_offset;

	uint32_t hsync_offset = timing->h_border_right +
			timing->h_front_porch;
	uint32_t h_sync_start = timing->h_addressable + hsync_offset;

	struct dc_context *ctx = tg->ctx;
	uint32_t value = 0;
	uint32_t addr = 0;
	uint32_t tmp = 0;

	addr = mmCRTCV_H_TOTAL;
	value = dm_read_reg(ctx, addr);
	set_reg_field_value(
		value,
		timing->h_total - 1,
		CRTCV_H_TOTAL,
		CRTC_H_TOTAL);
	dm_write_reg(ctx, addr, value);

	addr = mmCRTCV_V_TOTAL;
	value = dm_read_reg(ctx, addr);
	set_reg_field_value(
		value,
		timing->v_total - 1,
		CRTCV_V_TOTAL,
		CRTC_V_TOTAL);
	dm_write_reg(ctx, addr, value);

	addr = mmCRTCV_H_BLANK_START_END;
	value = dm_read_reg(ctx, addr);

	tmp = timing->h_total -
		(h_sync_start + timing->h_border_left);

	set_reg_field_value(
		value,
		tmp,
		CRTCV_H_BLANK_START_END,
		CRTC_H_BLANK_END);

Annotation

Implementation Notes