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