1*d974db0aSgarbled /* $NetBSD: mq200machdep.c,v 1.6 2007/10/17 19:54:28 garbled Exp $ */
244e4c533Stakemura
344e4c533Stakemura /*-
444e4c533Stakemura * Copyright (c) 2001 TAKEMURA Shin
544e4c533Stakemura * All rights reserved.
644e4c533Stakemura *
744e4c533Stakemura * Redistribution and use in source and binary forms, with or without
844e4c533Stakemura * modification, are permitted provided that the following conditions
944e4c533Stakemura * are met:
1044e4c533Stakemura * 1. Redistributions of source code must retain the above copyright
1144e4c533Stakemura * notice, this list of conditions and the following disclaimer.
1244e4c533Stakemura * 2. Redistributions in binary form must reproduce the above copyright
1344e4c533Stakemura * notice, this list of conditions and the following disclaimer in the
1444e4c533Stakemura * documentation and/or other materials provided with the distribution.
1544e4c533Stakemura * 3. The name of the author may not be used to endorse or promote products
1644e4c533Stakemura * derived from this software without specific prior written permission.
1744e4c533Stakemura *
1844e4c533Stakemura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1944e4c533Stakemura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2044e4c533Stakemura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2144e4c533Stakemura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2244e4c533Stakemura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2344e4c533Stakemura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2444e4c533Stakemura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2544e4c533Stakemura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2644e4c533Stakemura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2744e4c533Stakemura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2844e4c533Stakemura * SUCH DAMAGE.
2944e4c533Stakemura *
3044e4c533Stakemura */
3144e4c533Stakemura
3244e4c533Stakemura #ifdef _KERNEL
330c82163cSlukem #include <sys/cdefs.h>
34*d974db0aSgarbled __KERNEL_RCSID(0, "$NetBSD: mq200machdep.c,v 1.6 2007/10/17 19:54:28 garbled Exp $");
350c82163cSlukem
3644e4c533Stakemura #include <sys/param.h>
3744e4c533Stakemura #include <sys/kernel.h>
3844e4c533Stakemura #include <sys/systm.h>
3944e4c533Stakemura #include <sys/device.h>
4044e4c533Stakemura #else
4144e4c533Stakemura #include <stdio.h>
4244e4c533Stakemura #endif
4344e4c533Stakemura #include <sys/types.h>
4444e4c533Stakemura
4544e4c533Stakemura #include <machine/platid.h>
4644e4c533Stakemura #include <machine/platid_mask.h>
4744e4c533Stakemura
4844e4c533Stakemura #include "opt_mq200.h"
4944e4c533Stakemura #include "mq200var.h"
5044e4c533Stakemura #include "mq200reg.h"
5144e4c533Stakemura #include "mq200priv.h"
5244e4c533Stakemura
5344e4c533Stakemura #if MQ200_SETUPREGS
5444e4c533Stakemura #define OP_(n) (((n) << 2) | 1)
5544e4c533Stakemura #define OP_END OP_(1)
5644e4c533Stakemura #define OP_MASK OP_(2)
5744e4c533Stakemura #define OP_LOADPLLPARAM OP_(3)
5844e4c533Stakemura #define OP_LOADFROMREG OP_(4)
5944e4c533Stakemura #define OP_STORETOREG OP_(5)
6044e4c533Stakemura #define OP_LOADIMM OP_(6)
6144e4c533Stakemura #define OP_OR OP_(7)
6244e4c533Stakemura
6344e4c533Stakemura static void mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops);
6444e4c533Stakemura
6544e4c533Stakemura static u_int32_t mcr530_init_ops[] = {
6644e4c533Stakemura MQ200_PMCR, 0, /* power management control */
6744e4c533Stakemura MQ200_DCMISCR, MQ200_DCMISC_OSC_ENABLE |
6844e4c533Stakemura MQ200_DCMISC_FASTPOWSEQ_DISABLE |
6944e4c533Stakemura MQ200_DCMISC_OSCFREQ_12_25,
7044e4c533Stakemura OP_END
7144e4c533Stakemura };
7244e4c533Stakemura #endif /* MQ200_SETUPREGS */
7344e4c533Stakemura
7444e4c533Stakemura static struct mq200_clock_setting mcr530_clocks[] = {
7544e4c533Stakemura /* CRT: off FP: off */
7644e4c533Stakemura {
7744e4c533Stakemura MQ200_CLOCK_PLL1, /* memory clock */
7844e4c533Stakemura MQ200_CLOCK_PLL1, /* graphics engine clock */
7944e4c533Stakemura {
8044e4c533Stakemura 0, /* GC1(CRT) clock */
8144e4c533Stakemura 0, /* GC2(FP) clock */
8244e4c533Stakemura },
8344e4c533Stakemura 30000, /* PLL1 30MHz */
8444e4c533Stakemura 0, /* PLL2 disable */
8544e4c533Stakemura 0, /* PLL3 disable */
8644e4c533Stakemura },
8744e4c533Stakemura /* CRT: on FP: off */
8844e4c533Stakemura {
8944e4c533Stakemura MQ200_CLOCK_PLL1, /* memory clock */
9044e4c533Stakemura MQ200_CLOCK_PLL2, /* graphics engine clock */
9144e4c533Stakemura {
9244e4c533Stakemura MQ200_CLOCK_PLL3, /* GC1(CRT) clock */
9344e4c533Stakemura 0, /* GC2(FP) clock */
9444e4c533Stakemura },
9544e4c533Stakemura 83000, /* PLL1 83MHz */
9644e4c533Stakemura 30000, /* PLL2 30MHz */
9744e4c533Stakemura -1, /* PLL3 will be set by GC1 */
9844e4c533Stakemura },
9944e4c533Stakemura /* CRT: off FP: on */
10044e4c533Stakemura {
10144e4c533Stakemura MQ200_CLOCK_PLL1, /* memory clock */
10244e4c533Stakemura MQ200_CLOCK_PLL2, /* graphics engine clock */
10344e4c533Stakemura {
10444e4c533Stakemura 0, /* GC1(CRT) clock */
10544e4c533Stakemura MQ200_CLOCK_PLL2, /* GC2(FP) clock */
10644e4c533Stakemura },
10744e4c533Stakemura 30000, /* PLL1 30MHz */
10844e4c533Stakemura 18800, /* PLL2 18.8MHz */
10944e4c533Stakemura 0, /* PLL3 disable */
11044e4c533Stakemura },
11144e4c533Stakemura /* CRT: on FP: on */
11244e4c533Stakemura {
11344e4c533Stakemura MQ200_CLOCK_PLL1, /* memory clock */
11444e4c533Stakemura MQ200_CLOCK_PLL2, /* graphics engine clock */
11544e4c533Stakemura {
11644e4c533Stakemura MQ200_CLOCK_PLL3, /* GC1(CRT) clock */
11744e4c533Stakemura MQ200_CLOCK_PLL2, /* GC2(FP) clock */
11844e4c533Stakemura },
11944e4c533Stakemura 83000, /* PLL1 83MHz */
12044e4c533Stakemura 18800, /* PLL2 18.8MHz */
12144e4c533Stakemura -1, /* PLL3 will be set by GC1 */
12244e4c533Stakemura },
12344e4c533Stakemura };
12444e4c533Stakemura
12544e4c533Stakemura static struct mq200_md_param machdep_params[] = {
12644e4c533Stakemura {
12744e4c533Stakemura &platid_mask_MACH_NEC_MCR_530,
12844e4c533Stakemura 640, 240, /* flat panel size */
12944e4c533Stakemura 12288, /* base clock is 12.288 MHz */
13044e4c533Stakemura MQ200_MD_HAVECRT | MQ200_MD_HAVEFP,
13144e4c533Stakemura #if MQ200_SETUPREGS
13244e4c533Stakemura mcr530_init_ops,
13344e4c533Stakemura #else
13444e4c533Stakemura NULL,
13544e4c533Stakemura #endif /* MQ200_SETUPREGS */
13644e4c533Stakemura mcr530_clocks,
13744e4c533Stakemura /* DCMISC */
13844e4c533Stakemura MQ200_DCMISC_OSC_ENABLE |
13944e4c533Stakemura MQ200_DCMISC_FASTPOWSEQ_DISABLE |
14044e4c533Stakemura MQ200_DCMISC_OSCFREQ_12_25,
14144e4c533Stakemura /* PMC */
14244e4c533Stakemura 0,
14344e4c533Stakemura /* MM01 */
14444e4c533Stakemura MQ200_MM01_DRAM_AUTO_REFRESH_EN |
14544e4c533Stakemura MQ200_MM01_GE_PB_EN |
14644e4c533Stakemura MQ200_MM01_CPU_PB_EN |
14744e4c533Stakemura MQ200_MM01_SLOW_REFRESH_EN |
14844e4c533Stakemura (0x143e << MQ200_MM01_REFRESH_SHIFT),
14944e4c533Stakemura },
1506be55c30Simp {
1516be55c30Simp &platid_mask_MACH_NEC_MCR_530A,
1526be55c30Simp 640, 240, /* flat panel size */
1536be55c30Simp 12288, /* base clock is 12.288 MHz */
1546be55c30Simp MQ200_MD_HAVECRT | MQ200_MD_HAVEFP,
1556be55c30Simp #if MQ200_SETUPREGS
1566be55c30Simp mcr530_init_ops,
1576be55c30Simp #else
1586be55c30Simp NULL,
1596be55c30Simp #endif /* MQ200_SETUPREGS */
1606be55c30Simp mcr530_clocks,
1616be55c30Simp /* DCMISC */
1626be55c30Simp MQ200_DCMISC_OSC_ENABLE |
1636be55c30Simp MQ200_DCMISC_FASTPOWSEQ_DISABLE |
1646be55c30Simp MQ200_DCMISC_OSCFREQ_12_25,
1656be55c30Simp /* PMC */
1666be55c30Simp 0,
1676be55c30Simp /* MM01 */
1686be55c30Simp MQ200_MM01_DRAM_AUTO_REFRESH_EN |
1696be55c30Simp MQ200_MM01_GE_PB_EN |
1706be55c30Simp MQ200_MM01_CPU_PB_EN |
1716be55c30Simp MQ200_MM01_SLOW_REFRESH_EN |
1726be55c30Simp (0x143e << MQ200_MM01_REFRESH_SHIFT),
1736be55c30Simp },
1748e5eb16fSkiyohara {
1758e5eb16fSkiyohara NULL /* md_platform */
1768e5eb16fSkiyohara }
17744e4c533Stakemura };
17844e4c533Stakemura
17944e4c533Stakemura void
mq200_mdsetup(struct mq200_softc * sc)18044e4c533Stakemura mq200_mdsetup(struct mq200_softc *sc)
18144e4c533Stakemura {
18244e4c533Stakemura const struct mq200_md_param *mdp;
18344e4c533Stakemura
18444e4c533Stakemura sc->sc_md = NULL;
18544e4c533Stakemura for (mdp = machdep_params; mdp->md_platform != NULL; mdp++) {
18644e4c533Stakemura platid_mask_t mask;
18744e4c533Stakemura mask = PLATID_DEREF(mdp->md_platform);
18844e4c533Stakemura if (platid_match(&platid, &mask)) {
18944e4c533Stakemura sc->sc_md = mdp;
19044e4c533Stakemura break;
19144e4c533Stakemura }
19244e4c533Stakemura }
19344e4c533Stakemura
19444e4c533Stakemura if (sc->sc_md) {
19544e4c533Stakemura sc->sc_width[MQ200_GC2] = mdp->md_fp_width;
19644e4c533Stakemura sc->sc_height[MQ200_GC2] = mdp->md_fp_height;
19744e4c533Stakemura sc->sc_baseclock = mdp->md_baseclock;
19844e4c533Stakemura
19944e4c533Stakemura sc->sc_regctxs[MQ200_I_DCMISC ].val = mdp->md_init_dcmisc;
20044e4c533Stakemura sc->sc_regctxs[MQ200_I_PMC ].val = mdp->md_init_pmc;
20144e4c533Stakemura sc->sc_regctxs[MQ200_I_MM01 ].val = mdp->md_init_mm01;
20244e4c533Stakemura
20344e4c533Stakemura #if MQ200_SETUPREGS
20444e4c533Stakemura mq200_setupregs(sc, mdp->md_init_ops);
20544e4c533Stakemura #endif
20644e4c533Stakemura }
20744e4c533Stakemura }
20844e4c533Stakemura
20944e4c533Stakemura #if MQ200_SETUPREGS
21044e4c533Stakemura static void
mq200_setupregs(struct mq200_softc * sc,u_int32_t * ops)21144e4c533Stakemura mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops)
21244e4c533Stakemura {
21344e4c533Stakemura u_int32_t reg, mask, accum;
21444e4c533Stakemura
21544e4c533Stakemura while (1) {
21644e4c533Stakemura switch (ops[0] & 0x3) {
21744e4c533Stakemura case 0:
21844e4c533Stakemura if (mask == ~0) {
21944e4c533Stakemura mq200_write(sc, ops[0], ops[1]);
22044e4c533Stakemura } else {
22144e4c533Stakemura reg = mq200_read(sc, ops[0]);
22244e4c533Stakemura reg = (reg & ~mask) | (ops[1] & mask);
22344e4c533Stakemura mq200_write(sc, ops[0], reg);
22444e4c533Stakemura }
22544e4c533Stakemura break;
22644e4c533Stakemura case 1:
22744e4c533Stakemura switch (ops[0]) {
22844e4c533Stakemura case OP_END:
22944e4c533Stakemura return;
23044e4c533Stakemura case OP_MASK:
23144e4c533Stakemura mask = ops[1];
23244e4c533Stakemura break;
23344e4c533Stakemura case OP_LOADPLLPARAM:
23444e4c533Stakemura mq200_pllparam(ops[1], &accum);
23544e4c533Stakemura break;
23644e4c533Stakemura case OP_LOADFROMREG:
23744e4c533Stakemura reg = mq200_read(sc, ops[1]);
23844e4c533Stakemura accum = (accum & ~mask) | (reg & mask);
23944e4c533Stakemura break;
24044e4c533Stakemura case OP_STORETOREG:
24144e4c533Stakemura if (mask == ~0) {
24244e4c533Stakemura mq200_write(sc, ops[1], accum);
24344e4c533Stakemura } else {
24444e4c533Stakemura reg = mq200_read(sc, ops[1]);
24544e4c533Stakemura reg = (reg & ~mask) | (accum & mask);
24644e4c533Stakemura mq200_write(sc, ops[1], reg);
24744e4c533Stakemura }
24844e4c533Stakemura break;
24944e4c533Stakemura case OP_LOADIMM:
25044e4c533Stakemura accum = (accum & ~mask) | (ops[1] & mask);
25144e4c533Stakemura break;
25244e4c533Stakemura case OP_OR:
25344e4c533Stakemura accum = (accum | ops[1]);
25444e4c533Stakemura break;
25544e4c533Stakemura }
25644e4c533Stakemura break;
25744e4c533Stakemura }
25844e4c533Stakemura if (ops[0] != OP_MASK)
25944e4c533Stakemura mask = ~0;
26044e4c533Stakemura ops += 2;
26144e4c533Stakemura }
26244e4c533Stakemura }
26344e4c533Stakemura #endif /* MQ200_SETUPREGS */
264