]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/sm750fb/ddk750_mode.c
Merge remote-tracking branches 'spi/topic/loopback', 'spi/topic/omap2-mcspi', 'spi...
[karo-tx-linux.git] / drivers / staging / sm750fb / ddk750_mode.c
1
2 #include "ddk750_reg.h"
3 #include "ddk750_mode.h"
4 #include "ddk750_chip.h"
5
6 /*
7  * SM750LE only:
8  * This function takes care extra registers and bit fields required to set
9  * up a mode in SM750LE
10  *
11  * Explanation about Display Control register:
12  * HW only supports 7 predefined pixel clocks, and clock select is
13  * in bit 29:27 of Display Control register.
14  */
15 static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl)
16 {
17         unsigned long x, y;
18
19         x = pModeParam->horizontal_display_end;
20         y = pModeParam->vertical_display_end;
21
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, 0);
29
30         poke32(CRT_AUTO_CENTERING_BR,
31                 (((y - 1) << CRT_AUTO_CENTERING_BR_BOTTOM_SHIFT) &
32                         CRT_AUTO_CENTERING_BR_BOTTOM_MASK) |
33                 ((x - 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK));
34
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 &= ~CRT_DISPLAY_CTRL_CLK_MASK;
43
44         /* Set bit 29:27 of display control register for the right clock */
45         /* Note that SM750LE only need to supported 7 resolutions. */
46         if (x == 800 && y == 600)
47                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL41;
48         else if (x == 1024 && y == 768)
49                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL65;
50         else if (x == 1152 && y == 864)
51                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
52         else if (x == 1280 && y == 768)
53                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
54         else if (x == 1280 && y == 720)
55                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL74;
56         else if (x == 1280 && y == 960)
57                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
58         else if (x == 1280 && y == 1024)
59                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
60         else /* default to VGA clock */
61                 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL25;
62
63         /* Set bit 25:24 of display controller */
64         dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT);
65
66         /* Set bit 14 of display controller */
67         dispControl |= DISPLAY_CTRL_CLOCK_PHASE;
68
69         poke32(CRT_DISPLAY_CTRL, dispControl);
70
71         return dispControl;
72 }
73
74
75
76 /* only timing related registers will be  programed */
77 static int programModeRegisters(mode_parameter_t *pModeParam,
78                                                 struct pll_value *pll)
79 {
80         int ret = 0;
81         int cnt = 0;
82         unsigned int tmp, reg;
83
84         if (pll->clockType == SECONDARY_PLL) {
85                 /* programe secondary pixel clock */
86                 poke32(CRT_PLL_CTRL, sm750_format_pll_reg(pll));
87                 poke32(CRT_HORIZONTAL_TOTAL,
88                         (((pModeParam->horizontal_total - 1) <<
89                                 CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
90                                 CRT_HORIZONTAL_TOTAL_TOTAL_MASK) |
91                         ((pModeParam->horizontal_display_end - 1) &
92                                 CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK));
93
94                 poke32(CRT_HORIZONTAL_SYNC,
95                         ((pModeParam->horizontal_sync_width <<
96                                 CRT_HORIZONTAL_SYNC_WIDTH_SHIFT) &
97                                 CRT_HORIZONTAL_SYNC_WIDTH_MASK) |
98                         ((pModeParam->horizontal_sync_start - 1) &
99                                 CRT_HORIZONTAL_SYNC_START_MASK));
100
101                 poke32(CRT_VERTICAL_TOTAL,
102                         (((pModeParam->vertical_total - 1) <<
103                                 CRT_VERTICAL_TOTAL_TOTAL_SHIFT) &
104                                 CRT_VERTICAL_TOTAL_TOTAL_MASK) |
105                         ((pModeParam->vertical_display_end - 1) &
106                                 CRT_VERTICAL_TOTAL_DISPLAY_END_MASK));
107
108                 poke32(CRT_VERTICAL_SYNC,
109                         ((pModeParam->vertical_sync_height <<
110                                 CRT_VERTICAL_SYNC_HEIGHT_SHIFT) &
111                                 CRT_VERTICAL_SYNC_HEIGHT_MASK) |
112                         ((pModeParam->vertical_sync_start - 1) &
113                                 CRT_VERTICAL_SYNC_START_MASK));
114
115
116                 tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
117                 if (pModeParam->vertical_sync_polarity)
118                         tmp |= DISPLAY_CTRL_VSYNC_PHASE;
119                 if (pModeParam->horizontal_sync_polarity)
120                         tmp |= DISPLAY_CTRL_HSYNC_PHASE;
121
122                 if (sm750_get_chip_type() == SM750LE) {
123                         displayControlAdjust_SM750LE(pModeParam, tmp);
124                 } else {
125                         reg = peek32(CRT_DISPLAY_CTRL) &
126                                 ~(DISPLAY_CTRL_VSYNC_PHASE |
127                                   DISPLAY_CTRL_HSYNC_PHASE |
128                                   DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE);
129
130                          poke32(CRT_DISPLAY_CTRL, tmp | reg);
131                 }
132
133         } else if (pll->clockType == PRIMARY_PLL) {
134                 unsigned int reserved;
135
136                 poke32(PANEL_PLL_CTRL, sm750_format_pll_reg(pll));
137
138                 reg = ((pModeParam->horizontal_total - 1) <<
139                         PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
140                         PANEL_HORIZONTAL_TOTAL_TOTAL_MASK;
141                 reg |= ((pModeParam->horizontal_display_end - 1) &
142                         PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK);
143                 poke32(PANEL_HORIZONTAL_TOTAL, reg);
144
145                 poke32(PANEL_HORIZONTAL_SYNC,
146                         ((pModeParam->horizontal_sync_width <<
147                                 PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT) &
148                                 PANEL_HORIZONTAL_SYNC_WIDTH_MASK) |
149                         ((pModeParam->horizontal_sync_start - 1) &
150                                 PANEL_HORIZONTAL_SYNC_START_MASK));
151
152                 poke32(PANEL_VERTICAL_TOTAL,
153                         (((pModeParam->vertical_total - 1) <<
154                                 PANEL_VERTICAL_TOTAL_TOTAL_SHIFT) &
155                                 PANEL_VERTICAL_TOTAL_TOTAL_MASK) |
156                         ((pModeParam->vertical_display_end - 1) &
157                                 PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK));
158
159                 poke32(PANEL_VERTICAL_SYNC,
160                         ((pModeParam->vertical_sync_height <<
161                                 PANEL_VERTICAL_SYNC_HEIGHT_SHIFT) &
162                                 PANEL_VERTICAL_SYNC_HEIGHT_MASK) |
163                         ((pModeParam->vertical_sync_start - 1) &
164                                 PANEL_VERTICAL_SYNC_START_MASK));
165
166                 tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
167                 if (pModeParam->vertical_sync_polarity)
168                         tmp |= DISPLAY_CTRL_VSYNC_PHASE;
169                 if (pModeParam->horizontal_sync_polarity)
170                         tmp |= DISPLAY_CTRL_HSYNC_PHASE;
171                 if (pModeParam->clock_phase_polarity)
172                         tmp |= DISPLAY_CTRL_CLOCK_PHASE;
173
174                 reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK |
175                         PANEL_DISPLAY_CTRL_VSYNC;
176
177                 reg = (peek32(PANEL_DISPLAY_CTRL) & ~reserved) &
178                         ~(DISPLAY_CTRL_CLOCK_PHASE | DISPLAY_CTRL_VSYNC_PHASE |
179                           DISPLAY_CTRL_HSYNC_PHASE | DISPLAY_CTRL_TIMING |
180                           DISPLAY_CTRL_PLANE);
181
182                 /*
183                  * May a hardware bug or just my test chip (not confirmed).
184                  * PANEL_DISPLAY_CTRL register seems requiring few writes
185                  * before a value can be successfully written in.
186                  * Added some masks to mask out the reserved bits.
187                  * Note: This problem happens by design. The hardware will wait
188                  *       for the next vertical sync to turn on/off the plane.
189                  */
190                 poke32(PANEL_DISPLAY_CTRL, tmp | reg);
191
192                 while ((peek32(PANEL_DISPLAY_CTRL) & ~reserved) !=
193                         (tmp | reg)) {
194                         cnt++;
195                         if (cnt > 1000)
196                                 break;
197                         poke32(PANEL_DISPLAY_CTRL, tmp | reg);
198                 }
199         } else {
200                 ret = -1;
201         }
202         return ret;
203 }
204
205 int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
206 {
207         struct pll_value pll;
208         unsigned int uiActualPixelClk;
209
210         pll.inputFreq = DEFAULT_INPUT_CLOCK;
211         pll.clockType = clock;
212
213         uiActualPixelClk = sm750_calc_pll_value(parm->pixel_clock, &pll);
214         if (sm750_get_chip_type() == SM750LE) {
215                 /* set graphic mode via IO method */
216                 outb_p(0x88, 0x3d4);
217                 outb_p(0x06, 0x3d5);
218         }
219         programModeRegisters(parm, &pll);
220         return 0;
221 }
222
223