drivers/gpu/drm/gma500/oaktrail_hdmi.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/gma500/oaktrail_hdmi.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/gma500/oaktrail_hdmi.c
Extension
.c
Size
24464 bytes
Lines
845
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 intel_range {
	int	min, max;
};

struct oaktrail_hdmi_limit {
	struct intel_range vco, np, nr, nf;
};

struct oaktrail_hdmi_clock {
	int np;
	int nr;
	int nf;
	int dot;
};

#define VCO_MIN		320000
#define VCO_MAX		1650000
#define	NP_MIN		1
#define	NP_MAX		15
#define	NR_MIN		1
#define	NR_MAX		64
#define NF_MIN		2
#define NF_MAX		4095

static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
	.vco = { .min = VCO_MIN,		.max = VCO_MAX },
	.np  = { .min = NP_MIN,			.max = NP_MAX  },
	.nr  = { .min = NR_MIN,			.max = NR_MAX  },
	.nf  = { .min = NF_MIN,			.max = NF_MAX  },
};

static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;

	HDMI_WRITE(HDMI_HCR, 0x67);
	HDMI_READ(HDMI_HCR);

	HDMI_WRITE(0x51a8, 0x10);
	HDMI_READ(0x51a8);

	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
	HDMI_READ(HDMI_AUDIO_CTRL);
}

static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
	struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;

	HDMI_WRITE(0x51a8, 0x0);
	HDMI_READ(0x51a8);

	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
	HDMI_READ(HDMI_AUDIO_CTRL);

	HDMI_WRITE(HDMI_HCR, 0x47);
	HDMI_READ(HDMI_HCR);
}

static unsigned int htotal_calculate(struct drm_display_mode *mode)
{
	u32 new_crtc_htotal;

	/*
	 * 1024 x 768  new_crtc_htotal = 0x1024;
	 * 1280 x 1024 new_crtc_htotal = 0x0c34;
	 */
	new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;

	DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
	return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
}

static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
				int refclk, struct oaktrail_hdmi_clock *best_clock)
{
	int np_min, np_max, nr_min, nr_max;
	int np, nr, nf;

	np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
	np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
	if (np_min < oaktrail_hdmi_limit.np.min)
		np_min = oaktrail_hdmi_limit.np.min;
	if (np_max > oaktrail_hdmi_limit.np.max)
		np_max = oaktrail_hdmi_limit.np.max;

	nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
	nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));

Annotation

Implementation Notes