mq200machdep.c revision 1.3 1 /* $NetBSD: mq200machdep.c,v 1.3 2003/10/04 18:05:09 imp Exp $ */
2
3 /*-
4 * Copyright (c) 2001 TAKEMURA Shin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 */
31
32 #ifdef _KERNEL
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: mq200machdep.c,v 1.3 2003/10/04 18:05:09 imp Exp $");
35
36 #include <sys/param.h>
37 #include <sys/kernel.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #else
41 #include <stdio.h>
42 #endif
43 #include <sys/types.h>
44
45 #include <machine/platid.h>
46 #include <machine/platid_mask.h>
47
48 #include "opt_mq200.h"
49 #include "mq200var.h"
50 #include "mq200reg.h"
51 #include "mq200priv.h"
52
53 #if MQ200_SETUPREGS
54 #define OP_(n) (((n) << 2) | 1)
55 #define OP_END OP_(1)
56 #define OP_MASK OP_(2)
57 #define OP_LOADPLLPARAM OP_(3)
58 #define OP_LOADFROMREG OP_(4)
59 #define OP_STORETOREG OP_(5)
60 #define OP_LOADIMM OP_(6)
61 #define OP_OR OP_(7)
62
63 static void mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops);
64
65 static u_int32_t mcr530_init_ops[] = {
66 MQ200_PMCR, 0, /* power management control */
67 MQ200_DCMISCR, MQ200_DCMISC_OSC_ENABLE |
68 MQ200_DCMISC_FASTPOWSEQ_DISABLE |
69 MQ200_DCMISC_OSCFREQ_12_25,
70 OP_END
71 };
72 #endif /* MQ200_SETUPREGS */
73
74 static struct mq200_clock_setting mcr530_clocks[] = {
75 /* CRT: off FP: off */
76 {
77 MQ200_CLOCK_PLL1, /* memory clock */
78 MQ200_CLOCK_PLL1, /* graphics engine clock */
79 {
80 0, /* GC1(CRT) clock */
81 0, /* GC2(FP) clock */
82 },
83 30000, /* PLL1 30MHz */
84 0, /* PLL2 disable */
85 0, /* PLL3 disable */
86 },
87 /* CRT: on FP: off */
88 {
89 MQ200_CLOCK_PLL1, /* memory clock */
90 MQ200_CLOCK_PLL2, /* graphics engine clock */
91 {
92 MQ200_CLOCK_PLL3, /* GC1(CRT) clock */
93 0, /* GC2(FP) clock */
94 },
95 83000, /* PLL1 83MHz */
96 30000, /* PLL2 30MHz */
97 -1, /* PLL3 will be set by GC1 */
98 },
99 /* CRT: off FP: on */
100 {
101 MQ200_CLOCK_PLL1, /* memory clock */
102 MQ200_CLOCK_PLL2, /* graphics engine clock */
103 {
104 0, /* GC1(CRT) clock */
105 MQ200_CLOCK_PLL2, /* GC2(FP) clock */
106 },
107 30000, /* PLL1 30MHz */
108 18800, /* PLL2 18.8MHz */
109 0, /* PLL3 disable */
110 },
111 /* CRT: on FP: on */
112 {
113 MQ200_CLOCK_PLL1, /* memory clock */
114 MQ200_CLOCK_PLL2, /* graphics engine clock */
115 {
116 MQ200_CLOCK_PLL3, /* GC1(CRT) clock */
117 MQ200_CLOCK_PLL2, /* GC2(FP) clock */
118 },
119 83000, /* PLL1 83MHz */
120 18800, /* PLL2 18.8MHz */
121 -1, /* PLL3 will be set by GC1 */
122 },
123 };
124
125 static struct mq200_md_param machdep_params[] = {
126 {
127 &platid_mask_MACH_NEC_MCR_530,
128 640, 240, /* flat panel size */
129 12288, /* base clock is 12.288 MHz */
130 MQ200_MD_HAVECRT | MQ200_MD_HAVEFP,
131 #if MQ200_SETUPREGS
132 mcr530_init_ops,
133 #else
134 NULL,
135 #endif /* MQ200_SETUPREGS */
136 mcr530_clocks,
137 /* DCMISC */
138 MQ200_DCMISC_OSC_ENABLE |
139 MQ200_DCMISC_FASTPOWSEQ_DISABLE |
140 MQ200_DCMISC_OSCFREQ_12_25,
141 /* PMC */
142 0,
143 /* MM01 */
144 MQ200_MM01_DRAM_AUTO_REFRESH_EN |
145 MQ200_MM01_GE_PB_EN |
146 MQ200_MM01_CPU_PB_EN |
147 MQ200_MM01_SLOW_REFRESH_EN |
148 (0x143e << MQ200_MM01_REFRESH_SHIFT),
149 },
150 {
151 &platid_mask_MACH_NEC_MCR_530A,
152 640, 240, /* flat panel size */
153 12288, /* base clock is 12.288 MHz */
154 MQ200_MD_HAVECRT | MQ200_MD_HAVEFP,
155 #if MQ200_SETUPREGS
156 mcr530_init_ops,
157 #else
158 NULL,
159 #endif /* MQ200_SETUPREGS */
160 mcr530_clocks,
161 /* DCMISC */
162 MQ200_DCMISC_OSC_ENABLE |
163 MQ200_DCMISC_FASTPOWSEQ_DISABLE |
164 MQ200_DCMISC_OSCFREQ_12_25,
165 /* PMC */
166 0,
167 /* MM01 */
168 MQ200_MM01_DRAM_AUTO_REFRESH_EN |
169 MQ200_MM01_GE_PB_EN |
170 MQ200_MM01_CPU_PB_EN |
171 MQ200_MM01_SLOW_REFRESH_EN |
172 (0x143e << MQ200_MM01_REFRESH_SHIFT),
173 },
174 };
175
176 void
177 mq200_mdsetup(struct mq200_softc *sc)
178 {
179 const struct mq200_md_param *mdp;
180
181 sc->sc_md = NULL;
182 for (mdp = machdep_params; mdp->md_platform != NULL; mdp++) {
183 platid_mask_t mask;
184 mask = PLATID_DEREF(mdp->md_platform);
185 if (platid_match(&platid, &mask)) {
186 sc->sc_md = mdp;
187 break;
188 }
189 }
190
191 if (sc->sc_md) {
192 sc->sc_width[MQ200_GC2] = mdp->md_fp_width;
193 sc->sc_height[MQ200_GC2] = mdp->md_fp_height;
194 sc->sc_baseclock = mdp->md_baseclock;
195
196 sc->sc_regctxs[MQ200_I_DCMISC ].val = mdp->md_init_dcmisc;
197 sc->sc_regctxs[MQ200_I_PMC ].val = mdp->md_init_pmc;
198 sc->sc_regctxs[MQ200_I_MM01 ].val = mdp->md_init_mm01;
199
200 #if MQ200_SETUPREGS
201 mq200_setupregs(sc, mdp->md_init_ops);
202 #endif
203 }
204 }
205
206 #if MQ200_SETUPREGS
207 static void
208 mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops)
209 {
210 u_int32_t reg, mask, accum;
211
212 while (1) {
213 switch (ops[0] & 0x3) {
214 case 0:
215 if (mask == ~0) {
216 mq200_write(sc, ops[0], ops[1]);
217 } else {
218 reg = mq200_read(sc, ops[0]);
219 reg = (reg & ~mask) | (ops[1] & mask);
220 mq200_write(sc, ops[0], reg);
221 }
222 break;
223 case 1:
224 switch (ops[0]) {
225 case OP_END:
226 return;
227 case OP_MASK:
228 mask = ops[1];
229 break;
230 case OP_LOADPLLPARAM:
231 mq200_pllparam(ops[1], &accum);
232 break;
233 case OP_LOADFROMREG:
234 reg = mq200_read(sc, ops[1]);
235 accum = (accum & ~mask) | (reg & mask);
236 break;
237 case OP_STORETOREG:
238 if (mask == ~0) {
239 mq200_write(sc, ops[1], accum);
240 } else {
241 reg = mq200_read(sc, ops[1]);
242 reg = (reg & ~mask) | (accum & mask);
243 mq200_write(sc, ops[1], reg);
244 }
245 break;
246 case OP_LOADIMM:
247 accum = (accum & ~mask) | (ops[1] & mask);
248 break;
249 case OP_OR:
250 accum = (accum | ops[1]);
251 break;
252 }
253 break;
254 }
255 if (ops[0] != OP_MASK)
256 mask = ~0;
257 ops += 2;
258 }
259 }
260 #endif /* MQ200_SETUPREGS */
261