drivers/video/fbdev/matrox/matroxfb_Ti3026.c

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

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/matrox/matroxfb_Ti3026.c
Extension
.c
Size
26363 bytes
Lines
752
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 (minfo->fbcon.var.bits_per_pixel == 24) {
			loopfeed = 3;		/* set lm to any possible value */
			loopin = 3 * 32 / Bpp;
		} else {
			loopfeed = 4;
			loopin = 4 * 32 / Bpp;
		}
		z = (110000 * loopin) / (f_pll * loopfeed);
		loopdiv = 0; /* div 2 */
		if (z < 2)
			looppost = 0;
		else if (z < 4)
			looppost = 1;
		else if (z < 8)
			looppost = 2;
		else {
			looppost = 3;
			loopdiv = z/16;
		}
		if (minfo->fbcon.var.bits_per_pixel == 24) {
			hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
			hw->DACclk[4] = (65 - loopfeed) | 0x80;
			if (minfo->accel.ramdac_rev > 0x20) {
				if (isInterleave(minfo))
					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3;
				else {
					hw->DACclk[4] &= ~0xC0;
					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3;
				}
			} else {
				if (isInterleave(minfo))
					;	/* default... */
				else {
					hw->DACclk[4] ^= 0xC0;	/* change from 0x80 to 0x40 */
					hw->DACreg[POS3026_XLATCHCTRL] = TVP3026A_XLATCHCTRL_4_3;
				}
			}
			hw->DACclk[5] = looppost | 0xF8;
			if (minfo->devflags.mga_24bpp_fix)
				hw->DACclk[5] ^= 0x40;
		} else {
			hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
			hw->DACclk[4] = 65 - loopfeed;
			hw->DACclk[5] = looppost | 0xF0;
		}
		hw->DACreg[POS3026_XMEMPLLCTRL] = loopdiv | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL;
	}
	return 0;
}

static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m)
{
	u_int8_t muxctrl = isInterleave(minfo) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT;
	struct matrox_hw_state *hw = &minfo->hw;

	DBG(__func__)

	memcpy(hw->DACreg, MGADACbpp32, sizeof(MGADACbpp32));
	switch (minfo->fbcon.var.bits_per_pixel) {
		case 4:	hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1;	/* or _8_1, they are same */
			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT;
			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV8;
			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
			break;
		case 8: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;	/* or _4_1, they are same */
			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_8BIT;
			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
			break;
		case 16:
			/* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used every time) */
			hw->DACreg[POS3026_XTRUECOLORCTRL] = (minfo->fbcon.var.green.length == 5) ? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);
			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;
			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;
			break;
		case 24:
			/* XLATCHCTRL is: for (A) use _4_3 (?_8_3 is same? TBD), for (B) it is set in setpclk */
			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_888;
			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
			break;
		case 32:
			/* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used every time) */
			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
			break;
		default:
			return 1;	/* TODO: failed */
	}

Annotation

Implementation Notes