drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
Extension
.c
Size
19298 bytes
Lines
670
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

struct rockchip_hdmi_qp {
	struct device *dev;
	struct regmap *regmap;
	struct regmap *vo_regmap;
	struct rockchip_encoder encoder;
	struct dw_hdmi_qp *hdmi;
	struct phy *phy;
	struct gpio_desc *frl_enable_gpio;
	struct delayed_work hpd_work;
	int port_id;
	const struct rockchip_hdmi_qp_ctrl_ops *ctrl_ops;
	unsigned long long tmds_char_rate;
};

struct rockchip_hdmi_qp_ctrl_ops {
	void (*io_init)(struct rockchip_hdmi_qp *hdmi);
	void (*enc_init)(struct rockchip_hdmi_qp *hdmi, struct rockchip_crtc_state *state);
	irqreturn_t (*irq_callback)(int irq, void *dev_id);
	irqreturn_t (*hardirq_callback)(int irq, void *dev_id);
};

static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder)
{
	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);

	return container_of(rkencoder, struct rockchip_hdmi_qp, encoder);
}

static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder)
{
	struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
	struct drm_crtc *crtc = encoder->crtc;

	/* Unconditionally switch to TMDS as FRL is not yet supported */
	gpiod_set_value_cansleep(hdmi->frl_enable_gpio, 0);

	if (!crtc || !crtc->state)
		return;

	if (hdmi->ctrl_ops->enc_init)
		hdmi->ctrl_ops->enc_init(hdmi, to_rockchip_crtc_state(crtc->state));
}

static int
dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
					 struct drm_crtc_state *crtc_state,
					 struct drm_connector_state *conn_state)
{
	struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
	union phy_configure_opts phy_cfg = {};
	int ret;

	if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
	    s->output_bpc == conn_state->hdmi.output_bpc)
		return 0;

	phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
	phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;

	ret = phy_configure(hdmi->phy, &phy_cfg);
	if (!ret) {
		hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
		s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
		s->output_type = DRM_MODE_CONNECTOR_HDMIA;
		s->output_bpc = conn_state->hdmi.output_bpc;
	} else {
		dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret);
	}

	return ret;
}

static const struct
drm_encoder_helper_funcs dw_hdmi_qp_rockchip_encoder_helper_funcs = {
	.enable		= dw_hdmi_qp_rockchip_encoder_enable,
	.atomic_check	= dw_hdmi_qp_rockchip_encoder_atomic_check,
};

static int dw_hdmi_qp_rk3588_phy_init(struct dw_hdmi_qp *dw_hdmi, void *data)
{
	struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;

	return phy_power_on(hdmi->phy);
}

static void dw_hdmi_qp_rk3588_phy_disable(struct dw_hdmi_qp *dw_hdmi,
					  void *data)
{
	struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;

Annotation

Implementation Notes