1 
2 #include "ddk750_help.h"
3 #include "ddk750_reg.h"
4 #include "ddk750_mode.h"
5 #include "ddk750_chip.h"
6 
7 /*
8 	SM750LE only:
9     This function takes care extra registers and bit fields required to set
10     up a mode in SM750LE
11 
12 	Explanation about Display Control register:
13     HW only supports 7 predefined pixel clocks, and clock select is
14     in bit 29:27 of	Display Control register.
15 */
displayControlAdjust_SM750LE(mode_parameter_t * pModeParam,unsigned long dispControl)16 static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl)
17 {
18 	unsigned long x, y;
19 
20 	x = pModeParam->horizontal_display_end;
21 	y = pModeParam->vertical_display_end;
22 
23 	/* SM750LE has to set up the top-left and bottom-right
24 	   registers as well.
25 	   Note that normal SM750/SM718 only use those two register for
26 	   auto-centering mode.
27 	 */
28 	POKE32(CRT_AUTO_CENTERING_TL,
29 	FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0)
30 	| FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0));
31 
32 	POKE32(CRT_AUTO_CENTERING_BR,
33 	FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1)
34 	| FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1));
35 
36 	/* Assume common fields in dispControl have been properly set before
37 	   calling this function.
38 	   This function only sets the extra fields in dispControl.
39 	 */
40 
41 	/* Clear bit 29:27 of display control register */
42 	dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK);
43 
44 	/* Set bit 29:27 of display control register for the right clock */
45 	/* Note that SM750LE only need to supported 7 resoluitons. */
46 	if (x == 800 && y == 600)
47 		dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41);
48 	else if (x == 1024 && y == 768)
49 		dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65);
50 	else if (x == 1152 && y == 864)
51 		dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80);
52 	else if (x == 1280 && y == 768)
53 		dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80);
54 	else if (x == 1280 && y == 720)
55 		dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74);
56 	else if (x == 1280 && y == 960)
57 		dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108);
58 	else if (x == 1280 && y == 1024)
59 		dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108);
60 	else /* default to VGA clock */
61 	dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25);
62 
63 	/* Set bit 25:24 of display controller */
64 	dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT);
65 	dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT);
66 
67 	/* Set bit 14 of display controller */
68 	dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW);
69 
70 	POKE32(CRT_DISPLAY_CTRL, dispControl);
71 
72 	return dispControl;
73 }
74 
75 
76 
77 /* only timing related registers will be  programed */
programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll)78 static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll)
79 {
80 	int ret = 0;
81 	int cnt = 0;
82 	unsigned int ulTmpValue, ulReg;
83 
84 	if (pll->clockType == SECONDARY_PLL) {
85 		/* programe secondary pixel clock */
86 		POKE32(CRT_PLL_CTRL, formatPllReg(pll));
87 		POKE32(CRT_HORIZONTAL_TOTAL,
88 		FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1)
89 		| FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1));
90 
91 		POKE32(CRT_HORIZONTAL_SYNC,
92 		FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width)
93 		| FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1));
94 
95 		POKE32(CRT_VERTICAL_TOTAL,
96 		FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1)
97 		| FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1));
98 
99 		POKE32(CRT_VERTICAL_SYNC,
100 		FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height)
101 		| FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1));
102 
103 
104 		ulTmpValue = FIELD_VALUE(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)|
105 					  FIELD_VALUE(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)|
106 					  FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE)|
107 					  FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE);
108 
109 
110 		if (getChipType() == SM750LE) {
111 			displayControlAdjust_SM750LE(pModeParam, ulTmpValue);
112 		} else {
113 			ulReg = PEEK32(CRT_DISPLAY_CTRL)
114 					& FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE)
115 					& FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE)
116 					& FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING)
117 					& FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE);
118 
119 			 POKE32(CRT_DISPLAY_CTRL, ulTmpValue|ulReg);
120 		}
121 
122 	} else if (pll->clockType == PRIMARY_PLL) {
123 		unsigned int ulReservedBits;
124 
125 		POKE32(PANEL_PLL_CTRL, formatPllReg(pll));
126 
127 		POKE32(PANEL_HORIZONTAL_TOTAL,
128 		FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1)
129 		| FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1));
130 
131 		POKE32(PANEL_HORIZONTAL_SYNC,
132 		FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width)
133 		| FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1));
134 
135 		POKE32(PANEL_VERTICAL_TOTAL,
136 		FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1)
137 			| FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1));
138 
139 		POKE32(PANEL_VERTICAL_SYNC,
140 		FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height)
141 		| FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1));
142 
143 		ulTmpValue = FIELD_VALUE(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)|
144 			     FIELD_VALUE(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)|
145 			     FIELD_VALUE(0, PANEL_DISPLAY_CTRL, CLOCK_PHASE, pModeParam->clock_phase_polarity)|
146 			     FIELD_SET(0, PANEL_DISPLAY_CTRL, TIMING, ENABLE)|
147 			     FIELD_SET(0, PANEL_DISPLAY_CTRL, PLANE, ENABLE);
148 
149 		ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
150 				 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
151 				 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)|
152 				 FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC, ACTIVE_LOW);
153 
154 		ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits)
155 			& FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE)
156 			& FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE)
157 			& FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE)
158 			& FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING)
159 			& FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE);
160 
161 
162 		/* May a hardware bug or just my test chip (not confirmed).
163 		* PANEL_DISPLAY_CTRL register seems requiring few writes
164 		* before a value can be successfully written in.
165 		* Added some masks to mask out the reserved bits.
166 		* Note: This problem happens by design. The hardware will wait for the
167 		*       next vertical sync to turn on/off the plane.
168 		*/
169 
170 		POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
171 
172 		while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) {
173 			cnt++;
174 			if (cnt > 1000)
175 				break;
176 			POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
177 		}
178 	} else {
179 		ret = -1;
180 	}
181 	return ret;
182 }
183 
ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock)184 int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
185 {
186 	pll_value_t pll;
187 	unsigned int uiActualPixelClk;
188 
189 	pll.inputFreq = DEFAULT_INPUT_CLOCK;
190 	pll.clockType = clock;
191 
192 	uiActualPixelClk = calcPllValue(parm->pixel_clock, &pll);
193 	if (getChipType() == SM750LE) {
194 		/* set graphic mode via IO method */
195 		outb_p(0x88, 0x3d4);
196 		outb_p(0x06, 0x3d5);
197 	}
198 	programModeRegisters(parm, &pll);
199 	return 0;
200 }
201 
202 
203