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*/
16static 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 */
78static 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	if(pll->clockType == SECONDARY_PLL)
84	{
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	}
123	else if(pll->clockType == PRIMARY_PLL)
124	{
125		unsigned int ulReservedBits;
126		POKE32(PANEL_PLL_CTRL,formatPllReg(pll));
127
128        POKE32(PANEL_HORIZONTAL_TOTAL,
129              FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1)
130            | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1));
131
132        POKE32(PANEL_HORIZONTAL_SYNC,
133              FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width)
134            | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1));
135
136        POKE32(PANEL_VERTICAL_TOTAL,
137              FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1)
138            | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1));
139
140        POKE32(PANEL_VERTICAL_SYNC,
141              FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height)
142            | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1));
143
144		ulTmpValue = FIELD_VALUE(0,PANEL_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)|
145					FIELD_VALUE(0,PANEL_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)|
146					FIELD_VALUE(0,PANEL_DISPLAY_CTRL,CLOCK_PHASE,pModeParam->clock_phase_polarity)|
147					FIELD_SET(0,PANEL_DISPLAY_CTRL,TIMING,ENABLE)|
148					FIELD_SET(0,PANEL_DISPLAY_CTRL,PLANE,ENABLE);
149
150        ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
151                         FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
152                         FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)|
153                         FIELD_SET(0,PANEL_DISPLAY_CTRL,VSYNC,ACTIVE_LOW);
154
155        ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits)
156              & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE)
157              & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE)
158              & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE)
159              & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING)
160              & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE);
161
162
163		/* May a hardware bug or just my test chip (not confirmed).
164		* PANEL_DISPLAY_CTRL register seems requiring few writes
165		* before a value can be succesfully written in.
166		* Added some masks to mask out the reserved bits.
167		* Note: This problem happens by design. The hardware will wait for the
168		*       next vertical sync to turn on/off the plane.
169		*/
170
171		POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg);
172#if 1
173		while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg))
174		{
175			cnt++;
176			if(cnt > 1000)
177				break;
178			POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg);
179		}
180#endif
181	}
182	else{
183		ret = -1;
184	}
185	return ret;
186}
187
188int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock)
189{
190	pll_value_t pll;
191	unsigned int uiActualPixelClk;
192	pll.inputFreq = DEFAULT_INPUT_CLOCK;
193	pll.clockType = clock;
194
195	uiActualPixelClk = calcPllValue(parm->pixel_clock,&pll);
196	if(getChipType() == SM750LE){
197		/* set graphic mode via IO method */
198		outb_p(0x88,0x3d4);
199		outb_p(0x06,0x3d5);
200	}
201	programModeRegisters(parm,&pll);
202	return 0;
203}
204
205
206