drivers/gpu/drm/loongson/lsdc_output_7a2000.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/loongson/lsdc_output_7a2000.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/loongson/lsdc_output_7a2000.c
Extension
.c
Size
16926 bytes
Lines
553
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 (val & HDMI_PLL_LOCKED) {
			drm_dbg(ddev, "Setting HDMI-%u PLL take %d cycles\n",
				index, count);
			break;
		}
		++count;
	} while (count < 1000);

	lsdc_pipe_wreg32(ldev, LSDC_HDMI0_PHY_CAL_REG, index, 0x0f000ff0);

	if (count >= 1000)
		drm_err(ddev, "Setting HDMI-%u PLL failed\n", index);
}

static void ls7a2000_hdmi_atomic_mode_set(struct drm_encoder *encoder,
					  struct drm_crtc_state *crtc_state,
					  struct drm_connector_state *conn_state)
{
	struct lsdc_output *output = encoder_to_lsdc_output(encoder);
	struct lsdc_display_pipe *dispipe = output_to_display_pipe(output);
	unsigned int index = dispipe->index;
	struct drm_device *ddev = encoder->dev;
	struct lsdc_device *ldev = to_lsdc(ddev);
	struct drm_display_mode *mode = &crtc_state->mode;

	ls7a2000_hdmi_phy_pll_config(ldev, mode->clock, index);

	ls7a2000_hdmi_set_avi_infoframe(encoder, mode);

	drm_dbg(ddev, "%s modeset finished\n", encoder->name);
}

static const struct drm_encoder_helper_funcs ls7a2000_encoder_helper_funcs = {
	.atomic_disable = ls7a2000_hdmi_atomic_disable,
	.atomic_enable = ls7a2000_hdmi_atomic_enable,
	.atomic_mode_set = ls7a2000_hdmi_atomic_mode_set,
};

/*
 * For LS7A2000:
 *
 * 1) Most of board export one vga + hdmi output interface.
 * 2) Yet, Some boards export double hdmi output interface.
 * 3) Still have boards export three output(2 hdmi + 1 vga).
 *
 * So let's hook hdmi helper funcs to all display pipe, don't miss.
 * writing hdmi register do no harms.
 */
int ls7a2000_output_init(struct drm_device *ddev,
			 struct lsdc_display_pipe *dispipe,
			 struct i2c_adapter *ddc,
			 unsigned int pipe)
{
	struct lsdc_output *output = &dispipe->output;
	struct drm_encoder *encoder = &output->encoder;
	struct drm_connector *connector = &output->connector;
	int ret;

	ret = drm_encoder_init(ddev, encoder, &ls7a2000_encoder_funcs[pipe],
			       DRM_MODE_ENCODER_TMDS, "encoder-%u", pipe);
	if (ret)
		return ret;

	encoder->possible_crtcs = BIT(pipe);

	drm_encoder_helper_add(encoder, &ls7a2000_encoder_helper_funcs);

	ret = drm_connector_init_with_ddc(ddev, connector,
					  &ls7a2000_hdmi_connector_funcs[pipe],
					  DRM_MODE_CONNECTOR_HDMIA, ddc);
	if (ret)
		return ret;

	drm_info(ddev, "display pipe-%u has HDMI %s\n", pipe, pipe ? "" : "and/or VGA");

	drm_connector_helper_add(connector, &ls7a2000_connector_helpers);

	drm_connector_attach_encoder(connector, encoder);

	connector->polled = DRM_CONNECTOR_POLL_CONNECT |
			    DRM_CONNECTOR_POLL_DISCONNECT;

	connector->interlace_allowed = 0;
	connector->doublescan_allowed = 0;

	return 0;
}

Annotation

Implementation Notes