1 /*        $NetBSD: mq200machdep.c,v 1.6 2007/10/17 19:54:28 garbled 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.6 2007/10/17 19:54:28 garbled 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                     NULL                /* md_platform */
176           }
177 };
178 
179 void
mq200_mdsetup(struct mq200_softc * sc)180 mq200_mdsetup(struct mq200_softc *sc)
181 {
182           const struct mq200_md_param *mdp;
183 
184           sc->sc_md = NULL;
185           for (mdp = machdep_params; mdp->md_platform != NULL; mdp++) {
186                     platid_mask_t mask;
187                     mask = PLATID_DEREF(mdp->md_platform);
188                     if (platid_match(&platid, &mask)) {
189                               sc->sc_md = mdp;
190                               break;
191                     }
192           }
193 
194           if (sc->sc_md) {
195                     sc->sc_width[MQ200_GC2] = mdp->md_fp_width;
196                     sc->sc_height[MQ200_GC2] = mdp->md_fp_height;
197                     sc->sc_baseclock = mdp->md_baseclock;
198 
199                     sc->sc_regctxs[MQ200_I_DCMISC ].val = mdp->md_init_dcmisc;
200                     sc->sc_regctxs[MQ200_I_PMC    ].val = mdp->md_init_pmc;
201                     sc->sc_regctxs[MQ200_I_MM01   ].val = mdp->md_init_mm01;
202 
203 #if MQ200_SETUPREGS
204                     mq200_setupregs(sc, mdp->md_init_ops);
205 #endif
206           }
207 }
208 
209 #if MQ200_SETUPREGS
210 static void
mq200_setupregs(struct mq200_softc * sc,u_int32_t * ops)211 mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops)
212 {
213           u_int32_t reg, mask, accum;
214 
215           while (1) {
216                     switch (ops[0] & 0x3) {
217                     case 0:
218                               if (mask == ~0) {
219                                         mq200_write(sc, ops[0], ops[1]);
220                               } else {
221                                         reg = mq200_read(sc, ops[0]);
222                                         reg = (reg & ~mask) | (ops[1] & mask);
223                                         mq200_write(sc, ops[0], reg);
224                               }
225                               break;
226                     case 1:
227                               switch (ops[0]) {
228                               case OP_END:
229                                         return;
230                               case OP_MASK:
231                                         mask = ops[1];
232                                         break;
233                               case OP_LOADPLLPARAM:
234                                         mq200_pllparam(ops[1], &accum);
235                                         break;
236                               case OP_LOADFROMREG:
237                                         reg = mq200_read(sc, ops[1]);
238                                         accum = (accum & ~mask) | (reg & mask);
239                                         break;
240                               case OP_STORETOREG:
241                                         if (mask == ~0) {
242                                                   mq200_write(sc, ops[1], accum);
243                                         } else {
244                                                   reg = mq200_read(sc, ops[1]);
245                                                   reg = (reg & ~mask) | (accum & mask);
246                                                   mq200_write(sc, ops[1], reg);
247                                         }
248                                         break;
249                               case OP_LOADIMM:
250                                         accum = (accum & ~mask) | (ops[1] & mask);
251                                         break;
252                               case OP_OR:
253                                         accum = (accum | ops[1]);
254                                         break;
255                               }
256                               break;
257                     }
258                     if (ops[0] != OP_MASK)
259                               mask = ~0;
260                     ops += 2;
261           }
262 }
263 #endif /* MQ200_SETUPREGS */
264