Home | History | Annotate | Line # | Download | only in dev
mq200machdep.c revision 1.1
      1 /*	$NetBSD: mq200machdep.c,v 1.1 2001/03/25 13:06:53 takemura 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/param.h>
     34 #include <sys/kernel.h>
     35 #include <sys/systm.h>
     36 #include <sys/device.h>
     37 #else
     38 #include <stdio.h>
     39 #endif
     40 #include <sys/types.h>
     41 
     42 #include <machine/platid.h>
     43 #include <machine/platid_mask.h>
     44 
     45 #include "opt_mq200.h"
     46 #include "mq200var.h"
     47 #include "mq200reg.h"
     48 #include "mq200priv.h"
     49 
     50 #if MQ200_SETUPREGS
     51 #define OP_(n)          (((n) << 2) | 1)
     52 #define OP_END		OP_(1)
     53 #define OP_MASK		OP_(2)
     54 #define OP_LOADPLLPARAM	OP_(3)
     55 #define OP_LOADFROMREG	OP_(4)
     56 #define OP_STORETOREG	OP_(5)
     57 #define OP_LOADIMM	OP_(6)
     58 #define OP_OR		OP_(7)
     59 
     60 static void mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops);
     61 
     62 static u_int32_t mcr530_init_ops[] = {
     63 	MQ200_PMCR,	0,	/* power management control */
     64 	MQ200_DCMISCR,	MQ200_DCMISC_OSC_ENABLE |
     65 			MQ200_DCMISC_FASTPOWSEQ_DISABLE |
     66 			MQ200_DCMISC_OSCFREQ_12_25,
     67 	OP_END
     68 };
     69 #endif /* MQ200_SETUPREGS */
     70 
     71 static struct mq200_clock_setting mcr530_clocks[] = {
     72 	/* CRT: off	FP: off	*/
     73 	{
     74 		MQ200_CLOCK_PLL1,	/* memory clock			*/
     75 		MQ200_CLOCK_PLL1,	/* graphics engine clock	*/
     76 		{
     77 		0,			/* GC1(CRT)	clock		*/
     78 		0,			/* GC2(FP)	clock		*/
     79 		},
     80 		30000,			/* PLL1	30MHz			*/
     81 		0,			/* PLL2	disable			*/
     82 		0,			/* PLL3	disable			*/
     83 	},
     84 	/* CRT: on	FP: off	*/
     85 	{
     86 		MQ200_CLOCK_PLL1,	/* memory clock			*/
     87 		MQ200_CLOCK_PLL2,	/* graphics engine clock	*/
     88 		{
     89 		MQ200_CLOCK_PLL3,	/* GC1(CRT)	clock		*/
     90 		0,			/* GC2(FP)	clock		*/
     91 		},
     92 		83000,			/* PLL1	83MHz			*/
     93 		30000,			/* PLL2	30MHz			*/
     94 		-1,			/* PLL3	will be set by GC1	*/
     95 	},
     96 	/* CRT: off	FP: on	*/
     97 	{
     98 		MQ200_CLOCK_PLL1,	/* memory clock			*/
     99 		MQ200_CLOCK_PLL2,	/* graphics engine clock	*/
    100 		{
    101 		0,			/* GC1(CRT)	clock		*/
    102 		MQ200_CLOCK_PLL2,	/* GC2(FP)	clock		*/
    103 		},
    104 		30000,			/* PLL1	30MHz			*/
    105 		18800,			/* PLL2	18.8MHz			*/
    106 		0,			/* PLL3	disable			*/
    107 	},
    108 	/* CRT: on	FP: on	*/
    109 	{
    110 		MQ200_CLOCK_PLL1,	/* memory clock			*/
    111 		MQ200_CLOCK_PLL2,	/* graphics engine clock	*/
    112 		{
    113 		MQ200_CLOCK_PLL3,	/* GC1(CRT)	clock		*/
    114 		MQ200_CLOCK_PLL2,	/* GC2(FP)	clock		*/
    115 		},
    116 		83000,			/* PLL1	83MHz			*/
    117 		18800,			/* PLL2	18.8MHz			*/
    118 		-1,			/* PLL3	will be set by GC1	*/
    119 	},
    120 };
    121 
    122 static struct mq200_md_param machdep_params[] = {
    123 	{
    124 		&platid_mask_MACH_NEC_MCR_530,
    125 		640, 240,	/* flat panel size		*/
    126 		12288,		/* base clock is 12.288 MHz	*/
    127 		MQ200_MD_HAVECRT | MQ200_MD_HAVEFP,
    128 #if MQ200_SETUPREGS
    129 		mcr530_init_ops,
    130 #else
    131 		NULL,
    132 #endif /* MQ200_SETUPREGS */
    133 		mcr530_clocks,
    134 		/* DCMISC	*/
    135 		MQ200_DCMISC_OSC_ENABLE |
    136 		MQ200_DCMISC_FASTPOWSEQ_DISABLE |
    137 		MQ200_DCMISC_OSCFREQ_12_25,
    138 		/* PMC		*/
    139 		0,
    140 		/* MM01		*/
    141 		MQ200_MM01_DRAM_AUTO_REFRESH_EN |
    142 		MQ200_MM01_GE_PB_EN |
    143 		MQ200_MM01_CPU_PB_EN |
    144 		MQ200_MM01_SLOW_REFRESH_EN |
    145 		(0x143e << MQ200_MM01_REFRESH_SHIFT),
    146 	},
    147 };
    148 
    149 void
    150 mq200_mdsetup(struct mq200_softc *sc)
    151 {
    152 	const struct mq200_md_param *mdp;
    153 
    154 	sc->sc_md = NULL;
    155 	for (mdp = machdep_params; mdp->md_platform != NULL; mdp++) {
    156 		platid_mask_t mask;
    157 		mask = PLATID_DEREF(mdp->md_platform);
    158 		if (platid_match(&platid, &mask)) {
    159 			sc->sc_md = mdp;
    160 			break;
    161 		}
    162 	}
    163 
    164 	if (sc->sc_md) {
    165 		sc->sc_width[MQ200_GC2] = mdp->md_fp_width;
    166 		sc->sc_height[MQ200_GC2] = mdp->md_fp_height;
    167 		sc->sc_baseclock = mdp->md_baseclock;
    168 
    169 		sc->sc_regctxs[MQ200_I_DCMISC	].val = mdp->md_init_dcmisc;
    170 		sc->sc_regctxs[MQ200_I_PMC	].val = mdp->md_init_pmc;
    171 		sc->sc_regctxs[MQ200_I_MM01	].val = mdp->md_init_mm01;
    172 
    173 #if MQ200_SETUPREGS
    174 		mq200_setupregs(sc, mdp->md_init_ops);
    175 #endif
    176 	}
    177 }
    178 
    179 #if MQ200_SETUPREGS
    180 static void
    181 mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops)
    182 {
    183 	u_int32_t reg, mask, accum;
    184 
    185 	while (1) {
    186 		switch (ops[0] & 0x3) {
    187 		case 0:
    188 			if (mask == ~0) {
    189 				mq200_write(sc, ops[0], ops[1]);
    190 			} else {
    191 				reg = mq200_read(sc, ops[0]);
    192 				reg = (reg & ~mask) | (ops[1] & mask);
    193 				mq200_write(sc, ops[0], reg);
    194 			}
    195 			break;
    196 		case 1:
    197 			switch (ops[0]) {
    198 			case OP_END:
    199 				return;
    200 			case OP_MASK:
    201 				mask = ops[1];
    202 				break;
    203 			case OP_LOADPLLPARAM:
    204 				mq200_pllparam(ops[1], &accum);
    205 				break;
    206 			case OP_LOADFROMREG:
    207 				reg = mq200_read(sc, ops[1]);
    208 				accum = (accum & ~mask) | (reg & mask);
    209 				break;
    210 			case OP_STORETOREG:
    211 				if (mask == ~0) {
    212 					mq200_write(sc, ops[1], accum);
    213 				} else {
    214 					reg = mq200_read(sc, ops[1]);
    215 					reg = (reg & ~mask) | (accum & mask);
    216 					mq200_write(sc, ops[1], reg);
    217 				}
    218 				break;
    219 			case OP_LOADIMM:
    220 				accum = (accum & ~mask) | (ops[1] & mask);
    221 				break;
    222 			case OP_OR:
    223 				accum = (accum | ops[1]);
    224 				break;
    225 			}
    226 			break;
    227 		}
    228 		if (ops[0] != OP_MASK)
    229 			mask = ~0;
    230 		ops += 2;
    231 	}
    232 }
    233 #endif /* MQ200_SETUPREGS */
    234