mq200subr.c revision 1.1.12.3 1 1.1.12.3 nathanw /* $NetBSD: mq200subr.c,v 1.1.12.3 2002/10/18 02:37:06 nathanw Exp $ */
2 1.1.12.2 nathanw
3 1.1.12.2 nathanw /*-
4 1.1.12.2 nathanw * Copyright (c) 2001 TAKEMURA Shin
5 1.1.12.2 nathanw * All rights reserved.
6 1.1.12.2 nathanw *
7 1.1.12.2 nathanw * Redistribution and use in source and binary forms, with or without
8 1.1.12.2 nathanw * modification, are permitted provided that the following conditions
9 1.1.12.2 nathanw * are met:
10 1.1.12.2 nathanw * 1. Redistributions of source code must retain the above copyright
11 1.1.12.2 nathanw * notice, this list of conditions and the following disclaimer.
12 1.1.12.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
13 1.1.12.2 nathanw * notice, this list of conditions and the following disclaimer in the
14 1.1.12.2 nathanw * documentation and/or other materials provided with the distribution.
15 1.1.12.2 nathanw * 3. The name of the author may not be used to endorse or promote products
16 1.1.12.2 nathanw * derived from this software without specific prior written permission.
17 1.1.12.2 nathanw *
18 1.1.12.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 1.1.12.2 nathanw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 1.1.12.2 nathanw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 1.1.12.2 nathanw * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 1.1.12.2 nathanw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 1.1.12.2 nathanw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 1.1.12.2 nathanw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 1.1.12.2 nathanw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 1.1.12.2 nathanw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 1.1.12.2 nathanw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 1.1.12.2 nathanw * SUCH DAMAGE.
29 1.1.12.2 nathanw *
30 1.1.12.2 nathanw */
31 1.1.12.2 nathanw
32 1.1.12.2 nathanw #ifdef _KERNEL
33 1.1.12.2 nathanw #include <sys/param.h>
34 1.1.12.2 nathanw #include <sys/kernel.h>
35 1.1.12.2 nathanw #include <sys/systm.h>
36 1.1.12.2 nathanw #include <sys/device.h>
37 1.1.12.2 nathanw #else
38 1.1.12.2 nathanw #include <stdio.h>
39 1.1.12.2 nathanw #endif
40 1.1.12.2 nathanw #include <sys/types.h>
41 1.1.12.2 nathanw
42 1.1.12.2 nathanw #include <machine/platid.h>
43 1.1.12.2 nathanw #include <machine/platid_mask.h>
44 1.1.12.2 nathanw
45 1.1.12.2 nathanw #include "opt_mq200.h"
46 1.1.12.2 nathanw #include "mq200var.h"
47 1.1.12.2 nathanw #include "mq200reg.h"
48 1.1.12.2 nathanw #include "mq200priv.h"
49 1.1.12.2 nathanw
50 1.1.12.2 nathanw #define ABS(a) ((a) < 0 ? -(a) : (a))
51 1.1.12.2 nathanw
52 1.1.12.2 nathanw int mq200_depth_table[] = {
53 1.1.12.2 nathanw [MQ200_GCC_1BPP] = 1,
54 1.1.12.2 nathanw [MQ200_GCC_2BPP] = 2,
55 1.1.12.2 nathanw [MQ200_GCC_4BPP] = 4,
56 1.1.12.2 nathanw [MQ200_GCC_8BPP] = 8,
57 1.1.12.2 nathanw [MQ200_GCC_16BPP] = 16,
58 1.1.12.2 nathanw [MQ200_GCC_24BPP] = 32,
59 1.1.12.2 nathanw [MQ200_GCC_ARGB888] = 32,
60 1.1.12.2 nathanw [MQ200_GCC_ABGR888] = 32,
61 1.1.12.2 nathanw [MQ200_GCC_16BPP_DIRECT] = 16,
62 1.1.12.2 nathanw [MQ200_GCC_24BPP_DIRECT] = 32,
63 1.1.12.2 nathanw [MQ200_GCC_ARGB888_DIRECT] = 32,
64 1.1.12.2 nathanw [MQ200_GCC_ABGR888_DIRECT] = 32,
65 1.1.12.2 nathanw };
66 1.1.12.2 nathanw
67 1.1.12.2 nathanw struct mq200_crt_param mq200_crt_params[] = {
68 1.1.12.2 nathanw [MQ200_CRT_640x480_60Hz] =
69 1.1.12.2 nathanw { 640, 480, 25175, /* width, height, dot clock */
70 1.1.12.2 nathanw 800, /* HD Total */
71 1.1.12.2 nathanw 525, /* VD Total */
72 1.1.12.2 nathanw 656, 752, /* HS Start, HS End */
73 1.1.12.2 nathanw 490, 492, /* VS Start, VS End */
74 1.1.12.2 nathanw (MQ200_GC1CRTC_HSYNC_ACTVLOW |
75 1.1.12.2 nathanw MQ200_GC1CRTC_VSYNC_ACTVLOW |
76 1.1.12.2 nathanw MQ200_GC1CRTC_BLANK_PEDESTAL_EN),
77 1.1.12.2 nathanw },
78 1.1.12.2 nathanw [MQ200_CRT_800x600_60Hz] =
79 1.1.12.2 nathanw { 800, 600, 40000, /* width, height, dot clock */
80 1.1.12.2 nathanw 1054, /* HD Total */
81 1.1.12.2 nathanw 628, /* VD Total */
82 1.1.12.2 nathanw 839, 967, /* HS Start, HS End */
83 1.1.12.2 nathanw 601, 605, /* VS Start, VS End */
84 1.1.12.2 nathanw MQ200_GC1CRTC_BLANK_PEDESTAL_EN,
85 1.1.12.2 nathanw },
86 1.1.12.2 nathanw [MQ200_CRT_1024x768_60Hz] =
87 1.1.12.2 nathanw { 1024, 768, 65000, /* width, height, dot clock */
88 1.1.12.2 nathanw 1344, /* HD Total */
89 1.1.12.2 nathanw 806, /* VD Total */
90 1.1.12.2 nathanw 1048, 1184, /* HS Start, HS End */
91 1.1.12.2 nathanw 771, 777, /* VS Start, VS End */
92 1.1.12.2 nathanw (MQ200_GC1CRTC_HSYNC_ACTVLOW |
93 1.1.12.2 nathanw MQ200_GC1CRTC_VSYNC_ACTVLOW |
94 1.1.12.2 nathanw MQ200_GC1CRTC_BLANK_PEDESTAL_EN),
95 1.1.12.2 nathanw },
96 1.1.12.2 nathanw };
97 1.1.12.2 nathanw
98 1.1.12.2 nathanw int mq200_crt_nparams = sizeof(mq200_crt_params)/sizeof(*mq200_crt_params);
99 1.1.12.2 nathanw
100 1.1.12.2 nathanw /*
101 1.1.12.2 nathanw * get PLL setting register value for given frequency
102 1.1.12.2 nathanw */
103 1.1.12.2 nathanw void
104 1.1.12.2 nathanw mq200_pllparam(int reqout, u_int32_t *res)
105 1.1.12.2 nathanw {
106 1.1.12.2 nathanw int n, m, p, out;
107 1.1.12.2 nathanw int ref = 12288;
108 1.1.12.2 nathanw int bn, bm, bp, e;
109 1.1.12.2 nathanw
110 1.1.12.2 nathanw e = ref;
111 1.1.12.2 nathanw for (p = 0; p <= 4; p++) {
112 1.1.12.2 nathanw for (n = 0; n < (1<<5); n++) {
113 1.1.12.2 nathanw m = (reqout * ((n + 1) << p)) / ref - 1;
114 1.1.12.2 nathanw out = ref * (m + 1) / ((n + 1) << p);
115 1.1.12.2 nathanw if (0xff < m)
116 1.1.12.2 nathanw break;
117 1.1.12.2 nathanw if (40 <= m &&
118 1.1.12.2 nathanw 1000 <= ref/(n + 1) &&
119 1.1.12.2 nathanw 170000 <= ref*(m+1)/(n+1) &&
120 1.1.12.2 nathanw ref*(m+1)/(n+1) <= 340000 &&
121 1.1.12.2 nathanw ABS(reqout - out) <= e) {
122 1.1.12.2 nathanw e = ABS(reqout - out);
123 1.1.12.2 nathanw bn = n;
124 1.1.12.2 nathanw bm = m;
125 1.1.12.2 nathanw bp = p;
126 1.1.12.2 nathanw }
127 1.1.12.2 nathanw }
128 1.1.12.2 nathanw }
129 1.1.12.2 nathanw
130 1.1.12.2 nathanw #if 0
131 1.1.12.2 nathanw out = ref * (bm + 1) / ((bn + 1) << bp);
132 1.1.12.2 nathanw printf("PLL: %d.%03d x (%d+1) / (%d+1) / %d = %d.%03d\n",
133 1.1.12.2 nathanw ref / 1000, ref % 1000, bm, bn, (1<<bp),
134 1.1.12.2 nathanw out / 1000, out % 1000);
135 1.1.12.2 nathanw #endif
136 1.1.12.2 nathanw *res = ((bm << MQ200_PLL_M_SHIFT) |
137 1.1.12.2 nathanw (bn << MQ200_PLL_N_SHIFT) |
138 1.1.12.2 nathanw (bp << MQ200_PLL_P_SHIFT));
139 1.1.12.2 nathanw }
140 1.1.12.2 nathanw
141 1.1.12.2 nathanw void
142 1.1.12.2 nathanw mq200_set_pll(struct mq200_softc *sc, int pll, int clock)
143 1.1.12.2 nathanw {
144 1.1.12.2 nathanw struct mq200_regctx *paramreg, *enreg;
145 1.1.12.2 nathanw u_int32_t param, enbit;
146 1.1.12.2 nathanw
147 1.1.12.2 nathanw switch (pll) {
148 1.1.12.2 nathanw case MQ200_CLOCK_PLL1:
149 1.1.12.2 nathanw paramreg = &sc->sc_regctxs[MQ200_I_PLL(1)];
150 1.1.12.2 nathanw enreg = &sc->sc_regctxs[MQ200_I_DCMISC];
151 1.1.12.2 nathanw enbit = MQ200_DCMISC_PLL1_ENABLE;
152 1.1.12.2 nathanw break;
153 1.1.12.2 nathanw case MQ200_CLOCK_PLL2:
154 1.1.12.2 nathanw paramreg = &sc->sc_regctxs[MQ200_I_PLL(2)];
155 1.1.12.2 nathanw enreg = &sc->sc_regctxs[MQ200_I_PMC];
156 1.1.12.2 nathanw enbit = MQ200_PMC_PLL2_ENABLE;
157 1.1.12.2 nathanw break;
158 1.1.12.2 nathanw case MQ200_CLOCK_PLL3:
159 1.1.12.2 nathanw paramreg = &sc->sc_regctxs[MQ200_I_PLL(3)];
160 1.1.12.2 nathanw enreg = &sc->sc_regctxs[MQ200_I_PMC];
161 1.1.12.2 nathanw enbit = MQ200_PMC_PLL3_ENABLE;
162 1.1.12.2 nathanw break;
163 1.1.12.2 nathanw default:
164 1.1.12.2 nathanw printf("mq200: invalid PLL: %d\n", pll);
165 1.1.12.2 nathanw return;
166 1.1.12.2 nathanw }
167 1.1.12.2 nathanw if (clock != 0 && clock != -1) {
168 1.1.12.2 nathanw /* PLL Programming */
169 1.1.12.2 nathanw mq200_pllparam(clock, ¶m);
170 1.1.12.2 nathanw mq200_mod(sc, paramreg, MQ200_PLL_PARAM_MASK, param);
171 1.1.12.2 nathanw /* enable PLL */
172 1.1.12.2 nathanw mq200_on(sc, enreg, enbit);
173 1.1.12.2 nathanw }
174 1.1.12.2 nathanw
175 1.1.12.2 nathanw DPRINTF("%s %d.%03dMHz\n",
176 1.1.12.2 nathanw mq200_clknames[pll], clock/1000, clock%1000);
177 1.1.12.2 nathanw }
178 1.1.12.2 nathanw
179 1.1.12.2 nathanw void
180 1.1.12.2 nathanw mq200_setup_regctx(struct mq200_softc *sc)
181 1.1.12.2 nathanw {
182 1.1.12.2 nathanw int i;
183 1.1.12.2 nathanw static int offsets[MQ200_I_MAX] = {
184 1.1.12.2 nathanw [MQ200_I_DCMISC] = MQ200_DCMISCR,
185 1.1.12.2 nathanw [MQ200_I_PLL(2)] = MQ200_PLL2R,
186 1.1.12.2 nathanw [MQ200_I_PLL(3)] = MQ200_PLL3R,
187 1.1.12.2 nathanw [MQ200_I_PMC] = MQ200_PMCR,
188 1.1.12.2 nathanw [MQ200_I_MM01] = MQ200_MMR(1),
189 1.1.12.2 nathanw [MQ200_I_GCC(MQ200_GC1)] = MQ200_GCCR(MQ200_GC1),
190 1.1.12.2 nathanw [MQ200_I_GCC(MQ200_GC2)] = MQ200_GCCR(MQ200_GC2),
191 1.1.12.2 nathanw };
192 1.1.12.2 nathanw
193 1.1.12.2 nathanw for (i = 0; i < sizeof(offsets)/sizeof(*offsets); i++) {
194 1.1.12.2 nathanw if (offsets[i] == 0)
195 1.1.12.2 nathanw #ifdef MQ200_DEBUG
196 1.1.12.2 nathanw if (i != MQ200_I_PMC)
197 1.1.12.3 nathanw panic("%s(%d): register context %d is empty",
198 1.1.12.2 nathanw __FILE__, __LINE__, i);
199 1.1.12.2 nathanw #endif
200 1.1.12.2 nathanw sc->sc_regctxs[i].offset = offsets[i];
201 1.1.12.2 nathanw }
202 1.1.12.2 nathanw }
203 1.1.12.2 nathanw
204 1.1.12.2 nathanw void
205 1.1.12.2 nathanw mq200_setup(struct mq200_softc *sc)
206 1.1.12.2 nathanw {
207 1.1.12.2 nathanw const struct mq200_clock_setting *clock;
208 1.1.12.2 nathanw const struct mq200_crt_param *crt;
209 1.1.12.2 nathanw
210 1.1.12.2 nathanw clock = &sc->sc_md->md_clock_settings[sc->sc_flags & MQ200_SC_GC_MASK];
211 1.1.12.2 nathanw crt = sc->sc_crt;
212 1.1.12.2 nathanw
213 1.1.12.2 nathanw /* disable GC1 and GC2 */
214 1.1.12.2 nathanw //mq200_write(sc, MQ200_GCCR(MQ200_GC1), 0);
215 1.1.12.2 nathanw mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC1)], 0);
216 1.1.12.2 nathanw mq200_write(sc, MQ200_GC1CRTCR, 0);
217 1.1.12.2 nathanw //mq200_write(sc, MQ200_GCCR(MQ200_GC2), 0);
218 1.1.12.2 nathanw mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC2)], 0);
219 1.1.12.2 nathanw
220 1.1.12.2 nathanw while (mq200_read(sc, MQ200_PMCR) & MQ200_PMC_SEQPROGRESS)
221 1.1.12.2 nathanw /* busy wait */;
222 1.1.12.2 nathanw
223 1.1.12.2 nathanw /*
224 1.1.12.2 nathanw * setup around clock
225 1.1.12.2 nathanw */
226 1.1.12.2 nathanw /* setup eatch PLLs */
227 1.1.12.2 nathanw mq200_set_pll(sc, MQ200_CLOCK_PLL1, clock->pll1);
228 1.1.12.2 nathanw mq200_set_pll(sc, MQ200_CLOCK_PLL2, clock->pll2);
229 1.1.12.2 nathanw mq200_set_pll(sc, MQ200_CLOCK_PLL3, clock->pll3);
230 1.1.12.2 nathanw if (sc->sc_flags & MQ200_SC_GC1_ENABLE)
231 1.1.12.2 nathanw mq200_set_pll(sc, clock->gc[MQ200_GC1], crt->clock);
232 1.1.12.2 nathanw
233 1.1.12.2 nathanw /* setup MEMORY clock */
234 1.1.12.2 nathanw if (clock->mem == MQ200_CLOCK_PLL2)
235 1.1.12.2 nathanw mq200_on(sc, &sc->sc_regctxs[MQ200_I_MM01],
236 1.1.12.2 nathanw MQ200_MM01_CLK_PLL2);
237 1.1.12.2 nathanw else
238 1.1.12.2 nathanw mq200_off(sc, &sc->sc_regctxs[MQ200_I_MM01],
239 1.1.12.2 nathanw MQ200_MM01_CLK_PLL2);
240 1.1.12.2 nathanw DPRINTF("MEM: PLL%d\n", (clock->mem == MQ200_CLOCK_PLL2)?2:1);
241 1.1.12.2 nathanw
242 1.1.12.2 nathanw /* setup GE clock */
243 1.1.12.2 nathanw mq200_mod(sc, &sc->sc_regctxs[MQ200_I_PMC],
244 1.1.12.2 nathanw MQ200_PMC_GE_CLK_MASK | MQ200_PMC_GE_ENABLE,
245 1.1.12.2 nathanw (clock->ge << MQ200_PMC_GE_CLK_SHIFT) | MQ200_PMC_GE_ENABLE);
246 1.1.12.2 nathanw DPRINTF(" GE: PLL%d\n", clock->ge);
247 1.1.12.2 nathanw
248 1.1.12.2 nathanw /*
249 1.1.12.2 nathanw * setup GC1 (CRT contoller)
250 1.1.12.2 nathanw */
251 1.1.12.2 nathanw if (sc->sc_flags & MQ200_SC_GC1_ENABLE) {
252 1.1.12.2 nathanw /* GC03R Horizontal Display Control */
253 1.1.12.2 nathanw mq200_write(sc, MQ200_GCHDCR(MQ200_GC1),
254 1.1.12.2 nathanw (((u_int32_t)crt->hdtotal-2)<<MQ200_GC1HDC_TOTAL_SHIFT) |
255 1.1.12.2 nathanw ((u_int32_t)crt->width << MQ200_GCHDC_END_SHIFT));
256 1.1.12.2 nathanw
257 1.1.12.2 nathanw /* GC03R Vertical Display Control */
258 1.1.12.2 nathanw mq200_write(sc, MQ200_GCVDCR(MQ200_GC1),
259 1.1.12.2 nathanw (((u_int32_t)crt->vdtotal-1)<<MQ200_GC1VDC_TOTAL_SHIFT) |
260 1.1.12.2 nathanw (((u_int32_t)crt->height - 1) << MQ200_GCVDC_END_SHIFT));
261 1.1.12.2 nathanw
262 1.1.12.2 nathanw /* GC04R Horizontal Sync Control */
263 1.1.12.2 nathanw mq200_write(sc, MQ200_GCHSCR(MQ200_GC1),
264 1.1.12.2 nathanw ((u_int32_t)crt->hsstart << MQ200_GCHSC_START_SHIFT) |
265 1.1.12.2 nathanw ((u_int32_t)crt->hsend << MQ200_GCHSC_END_SHIFT));
266 1.1.12.2 nathanw
267 1.1.12.2 nathanw /* GC05R Vertical Sync Control */
268 1.1.12.2 nathanw mq200_write(sc, MQ200_GCVSCR(MQ200_GC1),
269 1.1.12.2 nathanw ((u_int32_t)crt->vsstart << MQ200_GCVSC_START_SHIFT) |
270 1.1.12.2 nathanw ((u_int32_t)crt->vsend << MQ200_GCVSC_END_SHIFT));
271 1.1.12.2 nathanw
272 1.1.12.2 nathanw /* GC00R GC1 Control */
273 1.1.12.2 nathanw //mq200_write(sc, MQ200_GCCR(MQ200_GC1),
274 1.1.12.2 nathanw mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC1)],
275 1.1.12.2 nathanw (MQ200_GCC_ENABLE |
276 1.1.12.2 nathanw (clock->gc[MQ200_GC1] << MQ200_GCC_RCLK_SHIFT) |
277 1.1.12.2 nathanw MQ200_GCC_MCLK_FD_1 |
278 1.1.12.2 nathanw (1 << MQ200_GCC_MCLK_SD_SHIFT)));
279 1.1.12.2 nathanw
280 1.1.12.2 nathanw /* GC01R CRT Control */
281 1.1.12.2 nathanw mq200_write(sc, MQ200_GC1CRTCR,
282 1.1.12.2 nathanw MQ200_GC1CRTC_DACEN | crt->opt);
283 1.1.12.2 nathanw
284 1.1.12.2 nathanw sc->sc_width[MQ200_GC1] = crt->width;
285 1.1.12.2 nathanw sc->sc_height[MQ200_GC1] = crt->height;
286 1.1.12.2 nathanw
287 1.1.12.2 nathanw DPRINTF("GC1: %s\n",
288 1.1.12.2 nathanw mq200_clknames[clock->gc[MQ200_GC1]]);
289 1.1.12.2 nathanw }
290 1.1.12.2 nathanw
291 1.1.12.2 nathanw while (mq200_read(sc, MQ200_PMCR) & MQ200_PMC_SEQPROGRESS)
292 1.1.12.2 nathanw /* busy wait */;
293 1.1.12.2 nathanw
294 1.1.12.2 nathanw /*
295 1.1.12.2 nathanw * setup GC2 (FP contoller)
296 1.1.12.2 nathanw */
297 1.1.12.2 nathanw if (sc->sc_flags & MQ200_SC_GC2_ENABLE) {
298 1.1.12.2 nathanw //mq200_write(sc, MQ200_GCCR(MQ200_GC2),
299 1.1.12.2 nathanw mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC2)],
300 1.1.12.2 nathanw MQ200_GCC_ENABLE |
301 1.1.12.2 nathanw (clock->gc[MQ200_GC2] << MQ200_GCC_RCLK_SHIFT) |
302 1.1.12.2 nathanw MQ200_GCC_MCLK_FD_1 | (1 << MQ200_GCC_MCLK_SD_SHIFT));
303 1.1.12.2 nathanw DPRINTF("GC2: %s\n",
304 1.1.12.2 nathanw mq200_clknames[clock->gc[MQ200_GC2]]);
305 1.1.12.2 nathanw }
306 1.1.12.2 nathanw
307 1.1.12.2 nathanw while (mq200_read(sc, MQ200_PMCR) & MQ200_PMC_SEQPROGRESS)
308 1.1.12.2 nathanw /* busy wait */;
309 1.1.12.2 nathanw
310 1.1.12.2 nathanw /*
311 1.1.12.2 nathanw * disable unused PLLs
312 1.1.12.2 nathanw */
313 1.1.12.2 nathanw if (clock->pll1 == 0) {
314 1.1.12.2 nathanw DPRINTF("PLL1 disable\n");
315 1.1.12.2 nathanw mq200_off(sc, &sc->sc_regctxs[MQ200_I_DCMISC],
316 1.1.12.2 nathanw MQ200_DCMISC_PLL1_ENABLE);
317 1.1.12.2 nathanw }
318 1.1.12.2 nathanw if (clock->pll2 == 0) {
319 1.1.12.2 nathanw DPRINTF("PLL2 disable\n");
320 1.1.12.2 nathanw mq200_off(sc, &sc->sc_regctxs[MQ200_I_PMC],
321 1.1.12.2 nathanw MQ200_PMC_PLL2_ENABLE);
322 1.1.12.2 nathanw }
323 1.1.12.2 nathanw if (clock->pll3 == 0) {
324 1.1.12.2 nathanw DPRINTF("PLL3 disable\n");
325 1.1.12.2 nathanw mq200_off(sc, &sc->sc_regctxs[MQ200_I_PMC],
326 1.1.12.2 nathanw MQ200_PMC_PLL3_ENABLE);
327 1.1.12.2 nathanw }
328 1.1.12.2 nathanw }
329 1.1.12.2 nathanw
330 1.1.12.2 nathanw void
331 1.1.12.2 nathanw mq200_win_enable(struct mq200_softc *sc, int gc,
332 1.1.12.2 nathanw u_int32_t depth, u_int32_t start,
333 1.1.12.2 nathanw int width, int height, int stride)
334 1.1.12.2 nathanw {
335 1.1.12.2 nathanw
336 1.1.12.2 nathanw DPRINTF("enable window on GC%d: %dx%d(%dx%d)\n",
337 1.1.12.2 nathanw gc + 1, width, height, sc->sc_width[gc], sc->sc_height[gc]);
338 1.1.12.2 nathanw
339 1.1.12.2 nathanw if (sc->sc_width[gc] < width) {
340 1.1.12.2 nathanw if (mq200_depth_table[depth])
341 1.1.12.2 nathanw start += (height - sc->sc_height[gc]) *
342 1.1.12.2 nathanw mq200_depth_table[depth] / 8;
343 1.1.12.2 nathanw width = sc->sc_width[gc];
344 1.1.12.2 nathanw }
345 1.1.12.2 nathanw
346 1.1.12.2 nathanw if (sc->sc_height[gc] < height) {
347 1.1.12.2 nathanw start += (height - sc->sc_height[gc]) * stride;
348 1.1.12.2 nathanw height = sc->sc_height[gc];
349 1.1.12.2 nathanw }
350 1.1.12.2 nathanw
351 1.1.12.2 nathanw /* GC08R Window Horizontal Control */
352 1.1.12.2 nathanw mq200_write(sc, MQ200_GCWHCR(gc),
353 1.1.12.2 nathanw (((u_int32_t)width - 1) << MQ200_GCWHC_WIDTH_SHIFT) |
354 1.1.12.2 nathanw ((sc->sc_width[gc] - width)/2));
355 1.1.12.2 nathanw
356 1.1.12.2 nathanw /* GC09R Window Vertical Control */
357 1.1.12.2 nathanw mq200_write(sc, MQ200_GCWVCR(gc),
358 1.1.12.2 nathanw (((u_int32_t)height - 1) << MQ200_GCWVC_HEIGHT_SHIFT) |
359 1.1.12.2 nathanw ((sc->sc_height[gc] - height)/2));
360 1.1.12.2 nathanw
361 1.1.12.2 nathanw /* GC00R GC Control */
362 1.1.12.2 nathanw mq200_mod(sc, &sc->sc_regctxs[MQ200_I_GCC(gc)],
363 1.1.12.2 nathanw (MQ200_GCC_WINEN | MQ200_GCC_DEPTH_MASK),
364 1.1.12.2 nathanw (MQ200_GCC_WINEN | (depth << MQ200_GCC_DEPTH_SHIFT)));
365 1.1.12.2 nathanw }
366 1.1.12.2 nathanw
367 1.1.12.2 nathanw void
368 1.1.12.2 nathanw mq200_win_disable(struct mq200_softc *sc, int gc)
369 1.1.12.2 nathanw {
370 1.1.12.2 nathanw /* GC00R GC Control */
371 1.1.12.2 nathanw mq200_off(sc, &sc->sc_regctxs[MQ200_I_GCC(gc)], MQ200_GCC_WINEN);
372 1.1.12.2 nathanw }
373