drivers/video/fbdev/core/fbcvt.c

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/core/fbcvt.c

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/core/fbcvt.c
Extension
.c
Size
9416 bytes
Lines
369
Domain
Driver Families
Bucket
drivers/video
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 fb_cvt_data {
	u32 xres;
	u32 yres;
	u32 refresh;
	u32 f_refresh;
	u32 pixclock;
	u32 hperiod;
	u32 hblank;
	u32 hfreq;
	u32 htotal;
	u32 vtotal;
	u32 vsync;
	u32 hsync;
	u32 h_front_porch;
	u32 h_back_porch;
	u32 v_front_porch;
	u32 v_back_porch;
	u32 h_margin;
	u32 v_margin;
	u32 interlace;
	u32 aspect_ratio;
	u32 active_pixels;
	u32 flags;
	u32 status;
};

static const unsigned char fb_cvt_vbi_tab[] = {
	4,        /* 4:3      */
	5,        /* 16:9     */
	6,        /* 16:10    */
	7,        /* 5:4      */
	7,        /* 15:9     */
	8,        /* reserved */
	9,        /* reserved */
	10        /* custom   */
};

/* returns hperiod * 1000 */
static u32 fb_cvt_hperiod(struct fb_cvt_data *cvt)
{
	u32 num = 1000000000/cvt->f_refresh;
	u32 den;

	if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
		num -= FB_CVT_RB_MIN_VBLANK * 1000;
		den = 2 * (cvt->yres/cvt->interlace + 2 * cvt->v_margin);
	} else {
		num -= FB_CVT_MIN_VSYNC_BP * 1000;
		den = 2 * (cvt->yres/cvt->interlace + cvt->v_margin * 2
			   + FB_CVT_MIN_VPORCH + cvt->interlace/2);
	}

	return 2 * (num/den);
}

/* returns ideal duty cycle * 1000 */
static u32 fb_cvt_ideal_duty_cycle(struct fb_cvt_data *cvt)
{
	u32 c_prime = (FB_CVT_GTF_C - FB_CVT_GTF_J) *
		(FB_CVT_GTF_K) + 256 * FB_CVT_GTF_J;
	u32 m_prime = (FB_CVT_GTF_K * FB_CVT_GTF_M);
	u32 h_period_est = cvt->hperiod;

	return (1000 * c_prime  - ((m_prime * h_period_est)/1000))/256;
}

static u32 fb_cvt_hblank(struct fb_cvt_data *cvt)
{
	u32 hblank = 0;

	if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
		hblank = FB_CVT_RB_HBLANK;
	else {
		u32 ideal_duty_cycle = fb_cvt_ideal_duty_cycle(cvt);
		u32 active_pixels = cvt->active_pixels;

		if (ideal_duty_cycle < 20000)
			hblank = (active_pixels * 20000)/
				(100000 - 20000);
		else {
			hblank = (active_pixels * ideal_duty_cycle)/
				(100000 - ideal_duty_cycle);
		}
	}

	hblank &= ~((2 * FB_CVT_CELLSIZE) - 1);

	return hblank;
}

Annotation

Implementation Notes