drivers/gpu/drm/sun4i/sun4i_tcon.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/sun4i/sun4i_tcon.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/sun4i/sun4i_tcon.c
Extension
.c
Size
45520 bytes
Lines
1582
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (connector->encoder == encoder) {
			drm_connector_list_iter_end(&iter);
			return connector;
		}
	drm_connector_list_iter_end(&iter);

	return NULL;
}

static int sun4i_tcon_get_pixel_depth(const struct drm_encoder *encoder)
{
	struct drm_connector *connector;
	struct drm_display_info *info;

	connector = sun4i_tcon_get_connector(encoder);
	if (!connector)
		return -EINVAL;

	info = &connector->display_info;
	if (info->num_bus_formats != 1)
		return -EINVAL;

	switch (info->bus_formats[0]) {
	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
		return 18;

	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
		return 24;
	}

	return -EINVAL;
}

static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
					  bool enabled)
{
	struct clk *clk;

	switch (channel) {
	case 0:
		WARN_ON(!tcon->quirks->has_channel_0);
		regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
				   SUN4I_TCON0_CTL_TCON_ENABLE,
				   enabled ? SUN4I_TCON0_CTL_TCON_ENABLE : 0);
		clk = tcon->dclk;
		break;
	case 1:
		WARN_ON(!tcon->quirks->has_channel_1);
		regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
				   SUN4I_TCON1_CTL_TCON_ENABLE,
				   enabled ? SUN4I_TCON1_CTL_TCON_ENABLE : 0);
		clk = tcon->sclk1;
		break;
	default:
		DRM_WARN("Unknown channel... doing nothing\n");
		return;
	}

	if (enabled) {
		clk_prepare_enable(clk);
		clk_rate_exclusive_get(clk);
	} else {
		clk_rate_exclusive_put(clk);
		clk_disable_unprepare(clk);
	}
}

static void sun4i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
				      const struct drm_encoder *encoder)
{
	regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
		     SUN4I_TCON0_LVDS_ANA0_CK_EN |
		     SUN4I_TCON0_LVDS_ANA0_REG_V |
		     SUN4I_TCON0_LVDS_ANA0_REG_C |
		     SUN4I_TCON0_LVDS_ANA0_EN_MB |
		     SUN4I_TCON0_LVDS_ANA0_PD |
		     SUN4I_TCON0_LVDS_ANA0_DCHS);

	udelay(2); /* delay at least 1200 ns */
	regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
			   SUN4I_TCON0_LVDS_ANA1_INIT,
			   SUN4I_TCON0_LVDS_ANA1_INIT);
	udelay(1); /* delay at least 120 ns */
	regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
			   SUN4I_TCON0_LVDS_ANA1_UPDATE,
			   SUN4I_TCON0_LVDS_ANA1_UPDATE);
	regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
			   SUN4I_TCON0_LVDS_ANA0_EN_MB,
			   SUN4I_TCON0_LVDS_ANA0_EN_MB);

Annotation

Implementation Notes