drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.c
Extension
.c
Size
7181 bytes
Lines
220
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 (panel_cntl->stored_backlight_registers.BL_PWM_CNTL != 0) {
			REG_WRITE(BL_PWM_CNTL,
					panel_cntl->stored_backlight_registers.BL_PWM_CNTL);
			REG_WRITE(BL_PWM_CNTL2,
					panel_cntl->stored_backlight_registers.BL_PWM_CNTL2);
			REG_WRITE(BL_PWM_PERIOD_CNTL,
					panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
			REG_UPDATE(PWRSEQ_REF_DIV,
				BL_PWM_REF_DIV,
				panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
		} else {
			/* TODO: Note: This should not really happen since VBIOS
			 * should have initialized PWM registers on boot.
			 */
			REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
			REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
		}
	} else {
		panel_cntl->stored_backlight_registers.BL_PWM_CNTL =
				REG_READ(BL_PWM_CNTL);
		panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 =
				REG_READ(BL_PWM_CNTL2);
		panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
				REG_READ(BL_PWM_PERIOD_CNTL);

		REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
				&panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
	}

	// Enable the backlight output
	REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);

	// Unlock group 2 backlight registers
	REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
			BL_PWM_GRP1_REG_LOCK, 0);

	current_backlight = dcn301_get_16_bit_backlight_from_pwm(panel_cntl);

	return current_backlight;
}

static void dcn301_panel_cntl_destroy(struct panel_cntl **panel_cntl)
{
	struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(*panel_cntl);

	kfree(dcn301_panel_cntl);
	*panel_cntl = NULL;
}

static bool dcn301_is_panel_backlight_on(struct panel_cntl *panel_cntl)
{
	struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl);
	uint32_t value;

	REG_GET(PWRSEQ_CNTL, PANEL_BLON, &value);

	return value;
}

static bool dcn301_is_panel_powered_on(struct panel_cntl *panel_cntl)
{
	struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl);
	uint32_t pwr_seq_state, dig_on, dig_on_ovrd;

	REG_GET(PWRSEQ_STATE, PANEL_PWRSEQ_TARGET_STATE_R, &pwr_seq_state);

	REG_GET_2(PWRSEQ_CNTL, PANEL_DIGON, &dig_on, PANEL_DIGON_OVRD, &dig_on_ovrd);

	return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1);
}

static void dcn301_store_backlight_level(struct panel_cntl *panel_cntl)
{
	struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl);

	panel_cntl->stored_backlight_registers.BL_PWM_CNTL =
		REG_READ(BL_PWM_CNTL);
	panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 =
		REG_READ(BL_PWM_CNTL2);
	panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
		REG_READ(BL_PWM_PERIOD_CNTL);

	REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
		&panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
}

static const struct panel_cntl_funcs dcn301_link_panel_cntl_funcs = {
	.destroy = dcn301_panel_cntl_destroy,
	.hw_init = dcn301_panel_cntl_hw_init,
	.is_panel_backlight_on = dcn301_is_panel_backlight_on,

Annotation

Implementation Notes