drivers/video/fbdev/matrox/matroxfb_DAC1064.c

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/matrox/matroxfb_DAC1064.c

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/matrox/matroxfb_DAC1064.c
Extension
.c
Size
33947 bytes
Lines
1117
Domain
Driver Families
Bucket
drivers/video
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 (0 == ((videomnp ^ pixelmnp) & 0xFFFFFF00)) {
			/* PIXEL and VIDEO PLL must not use same frequency. We modify N
			   of PIXEL PLL in such case because of VIDEO PLL may be source
			   of TVO clocks, and chroma subcarrier is derived from its
			   pixel clocks */
			pixelmnp += 0x000100;
		}
		c2_ctl |=  0x0006;	/* Use video PLL */
		hw->DACreg[POS1064_XPWRCTRL] |= 0x02;

		outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
		matroxfb_g450_setpll_cond(minfo, videomnp, M_VIDEO_PLL);
	}

	hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP;
	if (pixelmnp >= 0) {
		hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP;

		outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
		matroxfb_g450_setpll_cond(minfo, pixelmnp, M_PIXEL_PLL_C);
	}
	if (c2_ctl != hw->crtc2.ctl) {
		hw->crtc2.ctl = c2_ctl;
		mga_outl(0x3C10, c2_ctl);
	}

	pxc = minfo->crtc1.pixclock;
	if (pxc == 0 || minfo->outputs[2].src == MATROXFB_SRC_CRTC2) {
		pxc = minfo->crtc2.pixclock;
	}
	if (minfo->chip == MGA_G550) {
		if (pxc < 45000) {
			hw->DACreg[POS1064_XPANMODE] = 0x00;	/* 0-50 */
		} else if (pxc < 55000) {
			hw->DACreg[POS1064_XPANMODE] = 0x08;	/* 34-62 */
		} else if (pxc < 70000) {
			hw->DACreg[POS1064_XPANMODE] = 0x10;	/* 42-78 */
		} else if (pxc < 85000) {
			hw->DACreg[POS1064_XPANMODE] = 0x18;	/* 62-92 */
		} else if (pxc < 100000) {
			hw->DACreg[POS1064_XPANMODE] = 0x20;	/* 74-108 */
		} else if (pxc < 115000) {
			hw->DACreg[POS1064_XPANMODE] = 0x28;	/* 94-122 */
		} else if (pxc < 125000) {
			hw->DACreg[POS1064_XPANMODE] = 0x30;	/* 108-132 */
		} else {
			hw->DACreg[POS1064_XPANMODE] = 0x38;	/* 120-168 */
		}
	} else {
		/* G450 */
		if (pxc < 45000) {
			hw->DACreg[POS1064_XPANMODE] = 0x00;	/* 0-54 */
		} else if (pxc < 65000) {
			hw->DACreg[POS1064_XPANMODE] = 0x08;	/* 38-70 */
		} else if (pxc < 85000) {
			hw->DACreg[POS1064_XPANMODE] = 0x10;	/* 56-96 */
		} else if (pxc < 105000) {
			hw->DACreg[POS1064_XPANMODE] = 0x18;	/* 80-114 */
		} else if (pxc < 135000) {
			hw->DACreg[POS1064_XPANMODE] = 0x20;	/* 102-144 */
		} else if (pxc < 160000) {
			hw->DACreg[POS1064_XPANMODE] = 0x28;	/* 132-166 */
		} else if (pxc < 175000) {
			hw->DACreg[POS1064_XPANMODE] = 0x30;	/* 154-182 */
		} else {
			hw->DACreg[POS1064_XPANMODE] = 0x38;	/* 170-204 */
		}
	}
}
#endif

void DAC1064_global_init(struct matrox_fb_info *minfo)
{
	struct matrox_hw_state *hw = &minfo->hw;

	hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
	hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
	hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
#ifdef CONFIG_FB_MATROX_G
	if (minfo->devflags.g450dac) {
		hw->DACreg[POS1064_XPWRCTRL] = 0x1F;	/* powerup everything */
		hw->DACreg[POS1064_XOUTPUTCONN] = 0x00;	/* disable outputs */
		hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
		switch (minfo->outputs[0].src) {
			case MATROXFB_SRC_CRTC1:
			case MATROXFB_SRC_CRTC2:
				hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01;	/* enable output; CRTC1/2 selection is in CRTC2 ctl */
				break;
			case MATROXFB_SRC_NONE:
				hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN;

Annotation

Implementation Notes