Add MQ200_USECRT option, which enables CRT output on MC/R530.
This is kernel configuration option and you can't enable and disable CRT dynamically for now.
This commit is contained in:
parent
ffc1577812
commit
44e4c53338
|
@ -2,11 +2,11 @@
|
|||
# Distribution kernel (NEC VR based model) kernel config file
|
||||
|
||||
#
|
||||
# $NetBSD: GENERIC,v 1.82 2001/03/24 15:56:59 sato Exp $
|
||||
# $NetBSD: GENERIC,v 1.83 2001/03/25 13:06:52 takemura Exp $
|
||||
#
|
||||
include "arch/hpcmips/conf/std.hpcmips"
|
||||
|
||||
#ident "GENERIC-$Revision: 1.82 $"
|
||||
#ident "GENERIC-$Revision: 1.83 $"
|
||||
|
||||
maxusers 8
|
||||
|
||||
|
@ -127,6 +127,8 @@ vrdsu* at vrip? addr 0x0b0000e0 size 0x08
|
|||
vrpiu* at vrip? addr 0x0b000120 size 0x1a0 intr 5
|
||||
vrled* at vrip? addr 0x0b000240 size 0x10 intr 17
|
||||
|
||||
options MQ200_DEBUG
|
||||
#options MQ200_USECRT
|
||||
mqvideo0 at vrip? addr 0x0a000000 size 0x800000 # MQ200 video controller
|
||||
hpcfb* at mqvideo?
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.hpcmips,v 1.52 2001/02/26 09:34:22 sato Exp $
|
||||
# $NetBSD: files.hpcmips,v 1.53 2001/03/25 13:06:53 takemura Exp $
|
||||
|
||||
# maxpartitions must be first item in files.${ARCH}.
|
||||
maxpartitions 8
|
||||
|
@ -149,10 +149,14 @@ file arch/hpcmips/vr/vrpiu.c vrpiu
|
|||
attach ohci at vrip with ohci_vrip
|
||||
file arch/hpcmips/dev/ohci_vrip.c ohci_vrip
|
||||
|
||||
defopt opt_mq200.h MQ200_DEBUG MQ200_USECRT
|
||||
device mqvideo: hpcfbif
|
||||
attach mqvideo at vrip with mqvideo_vrip
|
||||
file arch/hpcmips/vr/mq200_vrip.c mqvideo_vrip
|
||||
file arch/hpcmips/dev/mq200.c mqvideo
|
||||
file arch/hpcmips/dev/mq200subr.c mqvideo
|
||||
file arch/hpcmips/dev/mq200debug.c mqvideo
|
||||
file arch/hpcmips/dev/mq200machdep.c mqvideo
|
||||
|
||||
device ite8181video: hpcfbif
|
||||
attach ite8181video at vrip with ite8181video_vrip
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: mq200.c,v 1.12 2001/03/12 08:54:26 sato Exp $ */
|
||||
/* $NetBSD: mq200.c,v 1.13 2001/03/25 13:06:53 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Takemura Shin
|
||||
* Copyright (c) 2000, 2001 TAKEMURA Shin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -46,30 +46,16 @@
|
|||
#include <machine/platid.h>
|
||||
#include <machine/platid_mask.h>
|
||||
|
||||
#include "opt_mq200.h"
|
||||
#include <hpcmips/dev/mq200reg.h>
|
||||
#include <hpcmips/dev/mq200var.h>
|
||||
#include <hpcmips/dev/mq200priv.h>
|
||||
|
||||
#include "bivideo.h"
|
||||
#if NBIVIDEO > 0
|
||||
#include <dev/hpc/bivideovar.h>
|
||||
#endif
|
||||
|
||||
#define MQ200DEBUG
|
||||
#ifdef MQ200DEBUG
|
||||
#ifndef MQ200DEBUG_CONF
|
||||
#define MQ200DEBUG_CONF 0
|
||||
#endif
|
||||
int mq200_debug = MQ200DEBUG_CONF;
|
||||
#define DPRINTF(arg) do { if (mq200_debug) printf arg; } while(0);
|
||||
#define DPRINTFN(n, arg) do { if (mq200_debug > (n)) printf arg; } while (0);
|
||||
#define VPRINTF(arg) do { if (bootverbose || mq200_debug) printf arg; } while(0);
|
||||
#define VPRINTFN(n, arg) do { if (bootverbose || mq200_debug > (n)) printf arg; } while (0);
|
||||
#else
|
||||
#define DPRINTF(arg) do { } while (0);
|
||||
#define DPRINTFN(n, arg) do { } while (0);
|
||||
#define VPRINTF(arg) do { if (bootverbose) printf arg; } while(0);
|
||||
#define VPRINTFN(n, arg) do { if (bootverbose) printf arg; } while (0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
|
@ -92,6 +78,10 @@ struct hpcfb_accessops mq200_ha = {
|
|||
mq200_ioctl, mq200_mmap
|
||||
};
|
||||
|
||||
#ifdef MQ200_DEBUG
|
||||
int mq200_debug = MQ200DEBUG_CONF;
|
||||
#endif
|
||||
|
||||
int
|
||||
mq200_probe(iot, ioh)
|
||||
bus_space_tag_t iot;
|
||||
|
@ -105,8 +95,8 @@ mq200_probe(iot, ioh)
|
|||
#endif /* NBIVIDEO > 0 */
|
||||
|
||||
regval = bus_space_read_4(iot, ioh, MQ200_PC00R);
|
||||
VPRINTF(("mq200 probe: vendor id=%04lx product id=%04lx\n",
|
||||
regval & 0xffff, (regval >> 16) & 0xffff));
|
||||
VPRINTF("probe: vendor id=%04lx product id=%04lx\n",
|
||||
regval & 0xffff, (regval >> 16) & 0xffff);
|
||||
if (regval != ((MQ200_PRODUCT_ID << 16) | MQ200_VENDOR_ID))
|
||||
return (0);
|
||||
|
||||
|
@ -130,10 +120,10 @@ mq200_attach(sc)
|
|||
sc->sc_fbconf.hf_baseaddr = (u_long)bootinfo->fb_addr;
|
||||
sc->sc_fbconf.hf_offset = (u_long)sc->sc_fbconf.hf_baseaddr -
|
||||
MIPS_PHYS_TO_KSEG1(mips_ptob(mips_btop(sc->sc_baseaddr)));
|
||||
DPRINTF(("hf_baseaddr=%lx\n", sc->sc_fbconf.hf_baseaddr));
|
||||
DPRINTF(("hf_offset=%lx\n", sc->sc_fbconf.hf_offset));
|
||||
DPRINTF("hf_baseaddr=%lx\n", sc->sc_fbconf.hf_baseaddr);
|
||||
DPRINTF("hf_offset=%lx\n", sc->sc_fbconf.hf_offset);
|
||||
|
||||
regval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MQ200_PC08R);
|
||||
regval = mq200_read(sc, MQ200_PC08R);
|
||||
printf("MQ200 Rev.%02lx video controller", regval & 0xff);
|
||||
if (console) {
|
||||
printf(", console");
|
||||
|
@ -141,6 +131,57 @@ mq200_attach(sc)
|
|||
printf("\n");
|
||||
printf("%s: framebuffer address: 0x%08lx\n",
|
||||
sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
|
||||
|
||||
/*
|
||||
* setup registers
|
||||
*/
|
||||
sc->sc_flags = 0;
|
||||
sc->sc_baseclock = 12288; /* 12.288 MHz */
|
||||
#ifdef MQ200_DEBUG
|
||||
if (bootverbose) {
|
||||
/* dump current setting */
|
||||
mq200_dump_all(sc);
|
||||
mq200_dump_pll(sc);
|
||||
}
|
||||
#endif
|
||||
mq200_setup_regctx(sc);
|
||||
mq200_mdsetup(sc);
|
||||
if (sc->sc_md) {
|
||||
if (sc->sc_md->md_flags & MQ200_MD_HAVEFP) {
|
||||
sc->sc_flags |= MQ200_SC_GC2_ENABLE; /* FP */
|
||||
}
|
||||
#if MQ200_USECRT
|
||||
if (sc->sc_md->md_flags & MQ200_MD_HAVECRT) {
|
||||
int i;
|
||||
sc->sc_flags |= MQ200_SC_GC1_ENABLE; /* CRT */
|
||||
for (i = 0; i < mq200_crt_nparams; i++) {
|
||||
sc->sc_crt = &mq200_crt_params[i];
|
||||
if (sc->sc_md->md_fp_width <=
|
||||
mq200_crt_params[i].width &&
|
||||
sc->sc_md->md_fp_height <=
|
||||
mq200_crt_params[i].height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mq200_setup(sc);
|
||||
|
||||
if (sc->sc_flags & MQ200_SC_GC2_ENABLE) /* FP */
|
||||
mq200_win_enable(sc, MQ200_GC2, MQ200_GCC_16BPP_DIRECT,
|
||||
0x00080100,
|
||||
sc->sc_md->md_fp_width, sc->sc_md->md_fp_height,
|
||||
1280);
|
||||
if (sc->sc_flags & MQ200_SC_GC1_ENABLE) /* CRT */
|
||||
mq200_win_enable(sc, MQ200_GC1, MQ200_GCC_16BPP_DIRECT,
|
||||
0x00080100,
|
||||
sc->sc_md->md_fp_width, sc->sc_md->md_fp_height,
|
||||
1280);
|
||||
}
|
||||
#ifdef MQ200_DEBUG
|
||||
if (sc->sc_md == NULL || bootverbose) {
|
||||
mq200_dump_pll(sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add a power hook to power saving */
|
||||
sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
|
||||
|
@ -462,7 +503,7 @@ mq200_ioctl(v, cmd, data, flag, p)
|
|||
dispparam = (struct wsdisplay_param*)data;
|
||||
switch (dispparam->param) {
|
||||
case WSDISPLAYIO_PARAM_BACKLIGHT:
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:BACKLIGHT call\n"));
|
||||
VPRINTF("ioctl: GETPARAM:BACKLIGHT call\n");
|
||||
if (sc->sc_max_brightness == -1)
|
||||
mq200_init_brightness(sc);
|
||||
mq200_get_backlight(sc);
|
||||
|
@ -473,37 +514,37 @@ mq200_ioctl(v, cmd, data, flag, p)
|
|||
else
|
||||
dispparam->curval =
|
||||
(sc->sc_powerstate&PWRSTAT_BACKLIGHT) ? 1 : 0;
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:BACKLIGHT:%d\n",
|
||||
dispparam->curval));
|
||||
VPRINTF("ioctl: GETPARAM:BACKLIGHT:%d\n",
|
||||
dispparam->curval);
|
||||
return 0;
|
||||
break;
|
||||
case WSDISPLAYIO_PARAM_CONTRAST:
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:CONTRAST call\n"));
|
||||
VPRINTF("ioctl: GETPARAM:CONTRAST call\n");
|
||||
if (sc->sc_max_contrast == -1)
|
||||
mq200_init_contrast(sc);
|
||||
if (sc->sc_max_contrast > 0) {
|
||||
dispparam->min = 0;
|
||||
dispparam->max = sc->sc_max_contrast;
|
||||
dispparam->curval = sc->sc_contrast;
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:CONTRAST max=%d, current=%d\n", sc->sc_max_contrast, sc->sc_contrast));
|
||||
VPRINTF("ioctl: GETPARAM:CONTRAST max=%d, current=%d\n", sc->sc_max_contrast, sc->sc_contrast);
|
||||
return 0;
|
||||
} else {
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:CONTRAST ret\n"));
|
||||
VPRINTF("ioctl: GETPARAM:CONTRAST ret\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
case WSDISPLAYIO_PARAM_BRIGHTNESS:
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:BRIGHTNESS call\n"));
|
||||
VPRINTF("ioctl: GETPARAM:BRIGHTNESS call\n");
|
||||
if (sc->sc_max_brightness == -1)
|
||||
mq200_init_brightness(sc);
|
||||
if (sc->sc_max_brightness > 0) {
|
||||
dispparam->min = 0;
|
||||
dispparam->max = sc->sc_max_brightness;
|
||||
dispparam->curval = sc->sc_brightness;
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:BRIGHTNESS max=%d, current=%d\n", sc->sc_max_brightness, sc->sc_brightness));
|
||||
VPRINTF("ioctl: GETPARAM:BRIGHTNESS max=%d, current=%d\n", sc->sc_max_brightness, sc->sc_brightness);
|
||||
return 0;
|
||||
} else {
|
||||
VPRINTF(("mq200_ioctl: GETPARAM:BRIGHTNESS ret\n"));
|
||||
VPRINTF("ioctl: GETPARAM:BRIGHTNESS ret\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
return (EINVAL);
|
||||
|
@ -516,13 +557,13 @@ mq200_ioctl(v, cmd, data, flag, p)
|
|||
dispparam = (struct wsdisplay_param*)data;
|
||||
switch (dispparam->param) {
|
||||
case WSDISPLAYIO_PARAM_BACKLIGHT:
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:BACKLIGHT call\n"));
|
||||
VPRINTF("ioctl: SETPARAM:BACKLIGHT call\n");
|
||||
if (dispparam->curval < 0 ||
|
||||
1 < dispparam->curval)
|
||||
return (EINVAL);
|
||||
if (sc->sc_max_brightness == -1)
|
||||
mq200_init_brightness(sc);
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:max brightness=%d\n", sc->sc_max_brightness));
|
||||
VPRINTF("ioctl: SETPARAM:max brightness=%d\n", sc->sc_max_brightness);
|
||||
if (sc->sc_max_brightness > 0) { /* dimmer */
|
||||
if (dispparam->curval == 0){
|
||||
sc->sc_brightness_save = sc->sc_brightness;
|
||||
|
@ -532,22 +573,22 @@ mq200_ioctl(v, cmd, data, flag, p)
|
|||
sc->sc_brightness_save = sc->sc_max_brightness;
|
||||
mq200_set_brightness(sc, sc->sc_brightness_save);
|
||||
}
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:BACKLIGHT: brightness=%d\n", sc->sc_brightness));
|
||||
VPRINTF("ioctl: SETPARAM:BACKLIGHT: brightness=%d\n", sc->sc_brightness);
|
||||
} else { /* off */
|
||||
if (dispparam->curval == 0)
|
||||
sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
|
||||
else
|
||||
sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:BACKLIGHT: powerstate %d\n",
|
||||
(sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
|
||||
VPRINTF("ioctl: SETPARAM:BACKLIGHT: powerstate %d\n",
|
||||
(sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0);
|
||||
mq200_update_powerstate(sc, PWRSTAT_BACKLIGHT);
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:BACKLIGHT:%d\n",
|
||||
(sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
|
||||
VPRINTF("ioctl: SETPARAM:BACKLIGHT:%d\n",
|
||||
(sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0);
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
case WSDISPLAYIO_PARAM_CONTRAST:
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:CONTRAST call\n"));
|
||||
VPRINTF("ioctl: SETPARAM:CONTRAST call\n");
|
||||
if (sc->sc_max_contrast == -1)
|
||||
mq200_init_contrast(sc);
|
||||
if (dispparam->curval < 0 ||
|
||||
|
@ -556,15 +597,15 @@ mq200_ioctl(v, cmd, data, flag, p)
|
|||
if (sc->sc_max_contrast > 0) {
|
||||
int org = sc->sc_contrast;
|
||||
mq200_set_contrast(sc, dispparam->curval);
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast));
|
||||
VPRINTF("ioctl: SETPARAM:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast);
|
||||
return 0;
|
||||
} else {
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:CONTRAST ret\n"));
|
||||
VPRINTF("ioctl: SETPARAM:CONTRAST ret\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
case WSDISPLAYIO_PARAM_BRIGHTNESS:
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:BRIGHTNESS call\n"));
|
||||
VPRINTF("ioctl: SETPARAM:BRIGHTNESS call\n");
|
||||
if (sc->sc_max_brightness == -1)
|
||||
mq200_init_brightness(sc);
|
||||
if (dispparam->curval < 0 ||
|
||||
|
@ -573,10 +614,10 @@ mq200_ioctl(v, cmd, data, flag, p)
|
|||
if (sc->sc_max_brightness > 0) {
|
||||
int org = sc->sc_brightness;
|
||||
mq200_set_brightness(sc, dispparam->curval);
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:BRIGHTNESS org=%d, current=%d\n", org, sc->sc_brightness));
|
||||
VPRINTF("ioctl: SETPARAM:BRIGHTNESS org=%d, current=%d\n", org, sc->sc_brightness);
|
||||
return 0;
|
||||
} else {
|
||||
VPRINTF(("mq200_ioctl: SETPARAM:BRIGHTNESS ret\n"));
|
||||
VPRINTF("ioctl: SETPARAM:BRIGHTNESS ret\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
|
@ -674,7 +715,7 @@ mq200_init_brightness(sc)
|
|||
{
|
||||
int val = -1;
|
||||
|
||||
VPRINTF(("mq200_init_brightness\n"));
|
||||
VPRINTF("init_brightness\n");
|
||||
if (config_hook_call(CONFIG_HOOK_GET,
|
||||
CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
|
||||
sc->sc_brightness_save = sc->sc_brightness = val;
|
||||
|
@ -694,7 +735,7 @@ mq200_init_contrast(sc)
|
|||
{
|
||||
int val = -1;
|
||||
|
||||
VPRINTF(("mq200_init_contrast\n"));
|
||||
VPRINTF("init_contrast\n");
|
||||
if (config_hook_call(CONFIG_HOOK_GET,
|
||||
CONFIG_HOOK_CONTRAST, &val) != -1) {
|
||||
sc->sc_contrast = val;
|
||||
|
|
|
@ -0,0 +1,547 @@
|
|||
/* $NetBSD: mq200debug.c,v 1.1 2001/03/25 13:06:53 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 TAKEMURA Shin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <machine/platid.h>
|
||||
#include <machine/platid_mask.h>
|
||||
|
||||
#include "opt_mq200.h"
|
||||
#include "mq200var.h"
|
||||
#include "mq200reg.h"
|
||||
#include "mq200priv.h"
|
||||
|
||||
#define ENABLE(b) ((b)?"enable":"disable")
|
||||
|
||||
#ifdef MQ200_DEBUG
|
||||
|
||||
char *mq200_clknames[] = { "BUS", "PLL1", "PLL2", "PLL3" };
|
||||
|
||||
void
|
||||
mq200_dump_pll(struct mq200_softc *sc)
|
||||
{
|
||||
int n, m;
|
||||
u_int32_t reg, pm00r;
|
||||
int clocks[4];
|
||||
int memclock, geclock;
|
||||
static char *clknames[] = { "BUS", "PLL1", "PLL2", "PLL3" };
|
||||
static char *fd_names[] = { "1", "1.5", "2.5", "3.5", "4.5", "5.5", "6.5" };
|
||||
static int fd_vals[] = { 10, 15, 25, 35, 45, 55, 65 };
|
||||
#define FIXEDFLOAT1000(a) (a)/1000, (a)%1000
|
||||
|
||||
/* PM00R */
|
||||
pm00r = mq200_read(sc, MQ200_PMCR);
|
||||
geclock = (pm00r&MQ200_PMC_GE_CLK_MASK)>>MQ200_PMC_GE_CLK_SHIFT;
|
||||
|
||||
/* MM01R */
|
||||
reg = mq200_read(sc, MQ200_MMR(1));
|
||||
memclock = (reg & MQ200_MM01_CLK_PLL2) ? 2 : 1;
|
||||
|
||||
/* bus clock */
|
||||
clocks[0] = 0;
|
||||
|
||||
/* PLL1 */
|
||||
reg = mq200_read(sc, MQ200_DCMISCR);
|
||||
m = ((reg & MQ200_PLL_M_MASK) >> MQ200_PLL_M_SHIFT) + 1;
|
||||
n = ((((reg & MQ200_PLL_N_MASK) >> MQ200_PLL_N_SHIFT) + 1) |
|
||||
((pm00r & MQ200_PMC_PLL1_N) << MQ200_PMC_PLL1_N_SHIFT));
|
||||
n <<= ((reg & MQ200_PLL_P_MASK) >> MQ200_PLL_P_SHIFT);
|
||||
printf(" PLL1:%3d.%03dMHz(0x%08x, %d.%03dMHzx%3d/%3d)\n",
|
||||
FIXEDFLOAT1000(sc->sc_baseclock*m/n),
|
||||
reg, FIXEDFLOAT1000(sc->sc_baseclock), m, n);
|
||||
clocks[1] = sc->sc_baseclock*m/n;
|
||||
|
||||
/* PLL2 */
|
||||
if (pm00r & MQ200_PMC_PLL2_ENABLE) {
|
||||
reg = mq200_read(sc, MQ200_PLL2R);
|
||||
m = ((reg & MQ200_PLL_M_MASK) >> MQ200_PLL_M_SHIFT) + 1;
|
||||
n = ((((reg & MQ200_PLL_N_MASK) >> MQ200_PLL_N_SHIFT) +1) <<
|
||||
((reg & MQ200_PLL_P_MASK) >> MQ200_PLL_P_SHIFT));
|
||||
clocks[2] = sc->sc_baseclock*m/n;
|
||||
printf(" PLL2:%3d.%03dMHz(0x%08x, %d.%03dMHzx%3d/%3d)\n",
|
||||
FIXEDFLOAT1000(sc->sc_baseclock*m/n),
|
||||
reg, FIXEDFLOAT1000(sc->sc_baseclock), m, n);
|
||||
} else {
|
||||
printf(" PLL2: disable\n");
|
||||
clocks[2] = 0;
|
||||
}
|
||||
|
||||
/* PLL3 */
|
||||
if (pm00r & MQ200_PMC_PLL3_ENABLE) {
|
||||
reg = mq200_read(sc, MQ200_PLL3R);
|
||||
m = (((reg & MQ200_PLL_M_MASK) >> MQ200_PLL_M_SHIFT) + 1);
|
||||
n = ((((reg & MQ200_PLL_N_MASK) >> MQ200_PLL_N_SHIFT) + 1) <<
|
||||
((reg & MQ200_PLL_P_MASK) >> MQ200_PLL_P_SHIFT));
|
||||
clocks[3] = sc->sc_baseclock*m/n;
|
||||
printf(" PLL3:%3d.%03dMHz(0x%08x, %d.%03dMHzx%3d/%3d)\n",
|
||||
FIXEDFLOAT1000(sc->sc_baseclock*m/n),
|
||||
reg, FIXEDFLOAT1000(sc->sc_baseclock), m, n);
|
||||
} else {
|
||||
printf(" PLL3: disable\n");
|
||||
clocks[3] = 0;
|
||||
}
|
||||
|
||||
printf(" MEM:%3d.%03dMHz(%s)\n",
|
||||
FIXEDFLOAT1000(clocks[memclock]),
|
||||
clknames[memclock]);
|
||||
printf(" GE:%3d.%03dMHz(%s)\n",
|
||||
FIXEDFLOAT1000(clocks[geclock]),
|
||||
clknames[geclock]);
|
||||
|
||||
/* GC1 */
|
||||
reg = mq200_read(sc, MQ200_GCCR(MQ200_GC1));
|
||||
if (reg & MQ200_GCC_ENABLE) {
|
||||
int fd, sd, rc;
|
||||
rc = (reg&MQ200_GCC_RCLK_MASK)>>MQ200_GCC_RCLK_SHIFT;
|
||||
fd = (reg&MQ200_GCC_MCLK_FD_MASK)>>MQ200_GCC_MCLK_FD_SHIFT;
|
||||
sd = (reg&MQ200_GCC_MCLK_SD_MASK)>>MQ200_GCC_MCLK_SD_SHIFT;
|
||||
printf(" GC1:%3d.%03dMHz(%s/%s/%d)",
|
||||
FIXEDFLOAT1000(clocks[rc]*10/fd_vals[fd]/sd),
|
||||
clknames[rc], fd_names[fd], sd);
|
||||
/* GC01R */
|
||||
reg = mq200_read(sc, MQ200_GC1CRTCR);
|
||||
if (reg&MQ200_GC1CRTC_DACEN)
|
||||
printf(", CRT");
|
||||
reg = mq200_read(sc, MQ200_FPCR);
|
||||
if ((reg & MQ200_FPC_ENABLE) && !(reg & MQ200_FPC_GC2))
|
||||
printf(", LCD");
|
||||
printf("\n");
|
||||
} else {
|
||||
printf(" GC1: disable\n");
|
||||
}
|
||||
|
||||
/* GC2 */
|
||||
reg = mq200_read(sc, MQ200_GCCR(MQ200_GC2));
|
||||
if (reg & MQ200_GCC_ENABLE) {
|
||||
int fd, sd, rc;
|
||||
rc = (reg&MQ200_GCC_RCLK_MASK)>>MQ200_GCC_RCLK_SHIFT;
|
||||
fd = (reg&MQ200_GCC_MCLK_FD_MASK)>>MQ200_GCC_MCLK_FD_SHIFT;
|
||||
sd = (reg&MQ200_GCC_MCLK_SD_MASK)>>MQ200_GCC_MCLK_SD_SHIFT;
|
||||
printf(" GC2:%3d.%03dMHz(%s/%s/%d)",
|
||||
FIXEDFLOAT1000(clocks[rc]*10/fd_vals[fd]/sd),
|
||||
clknames[rc], fd_names[fd], sd);
|
||||
reg = mq200_read(sc, MQ200_FPCR);
|
||||
if ((reg & MQ200_FPC_ENABLE) && (reg & MQ200_FPC_GC2))
|
||||
printf(", FP");
|
||||
printf("\n");
|
||||
} else {
|
||||
printf(" GC2: disable\n");
|
||||
}
|
||||
}
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
u_int32_t base;
|
||||
int start, end;
|
||||
} regs[] = {
|
||||
{ "GC", MQ200_GCR(0), 0x00, 0x13 },
|
||||
{ "GC", MQ200_GCR(0), 0x20, 0x33 },
|
||||
{ "FP", MQ200_FP, 0x00, 0x0f },
|
||||
{ "CC", MQ200_CC, 0x00, 0x01 },
|
||||
{ "PC", MQ200_PC, 0x00, 0x05 },
|
||||
{ "MM", MQ200_MM, 0x00, 0x04 },
|
||||
{ "DC", MQ200_DC, 0x00, 0x03 },
|
||||
{ "PM", MQ200_PM, 0x00, 0x03 },
|
||||
{ "PM", MQ200_PM, 0x06, 0x07 },
|
||||
{ "IN", MQ200_IN, 0x00, 0x03 },
|
||||
};
|
||||
|
||||
char *
|
||||
mq200_regname(struct mq200_softc *sc, int offset, char *buf, int bufsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(regs)/sizeof(*regs); i++)
|
||||
if (regs[i].base + regs[i].start * 4 <= offset &&
|
||||
offset <= regs[i].base + regs[i].end * 4) {
|
||||
sprintf(buf, "%s%02XR", regs[i].name,
|
||||
(offset - regs[i].base) / 4);
|
||||
return (buf);
|
||||
}
|
||||
sprintf(buf, "OFFSET %02X", offset);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
void
|
||||
mq200_dump_all(struct mq200_softc *sc)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < sizeof(regs)/sizeof(*regs); i++)
|
||||
for (j = regs[i].start; j <= regs[i].end; j++)
|
||||
printf("%s%02XR: %08x\n",
|
||||
regs[i].name, j,
|
||||
mq200_read(sc, regs[i].base + (j * 4)));
|
||||
}
|
||||
|
||||
void
|
||||
mq200_write(struct mq200_softc *sc, int offset, u_int32_t data)
|
||||
{
|
||||
int i;
|
||||
char buf[32];
|
||||
|
||||
for (i = 0; i < MQ200_I_MAX; i++) {
|
||||
if (sc->sc_regctxs[i].offset == offset)
|
||||
printf("mq200_write: WARNING: raw access %s\n",
|
||||
mq200_regname(sc, offset, buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
mq200_writex(sc, offset, data);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
mq200_dump_gc(struct mq200_softc *sc, int gc)
|
||||
{
|
||||
u_int32_t reg;
|
||||
char *depth_names[] = {
|
||||
"1bpp with CLUT",
|
||||
"2bpp with CLUT",
|
||||
"4bpp with CLUT",
|
||||
"8bpp with CLUT",
|
||||
"16bpp with CLUT",
|
||||
"24bpp with CLUT",
|
||||
"32bpp(RGB) with CLUT",
|
||||
"32bpp(BGR) with CLUT",
|
||||
"1bpp w/o CLUT",
|
||||
"2bpp w/o CLUT",
|
||||
"4bpp w/o CLUT",
|
||||
"8bpp w/o CLUT",
|
||||
"16bpp w/o CLUT",
|
||||
"24bpp w/o CLUT",
|
||||
"32bpp(RGB) w/o CLUT",
|
||||
"32bpp(BGR) w/o CLUT",
|
||||
};
|
||||
char *rc_names[] = { "BUS", "PLL1", "PLL2", "PLL3" };
|
||||
char *fd_names[] = { "1", "1.5", "2.5", "3.5", "4.5", "5.5", "6.5" };
|
||||
|
||||
/*
|
||||
* GC00R Graphics Controller Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCCR(gc));
|
||||
printf("GC00R=0x%08x: ", reg);
|
||||
printf("%s %s%s%s%s%s\n",
|
||||
ENABLE(reg & MQ200_GCC_ENABLE),
|
||||
(reg & MQ200_GCC_HCRESET)?"HC_reset ":"",
|
||||
(reg & MQ200_GCC_VCRESET)?"VC_reset ":"",
|
||||
(reg & MQ200_GCC_HCEN)?"cursor_enable ":"",
|
||||
(reg & MQ200_GCC_TESTMODE0)?"test_mode0 ":"",
|
||||
(reg & MQ200_GCC_TESTMODE1)?"test_mode1 ":"");
|
||||
printf(" window: %s %s\n",
|
||||
ENABLE(reg & MQ200_GCC_WINEN),
|
||||
depth_names[(reg&MQ200_GCC_DEPTH_MASK)>>MQ200_GCC_DEPTH_SHIFT]);
|
||||
printf(" altwin: %s %s\n",
|
||||
ENABLE(reg & MQ200_GCC_ALTEN),
|
||||
depth_names[(reg&MQ200_GCC_ALTDEPTH_MASK)>>MQ200_GCC_ALTDEPTH_SHIFT]);
|
||||
printf(" clock: root_clock/first_div/second_div = %s/%s/%d\n",
|
||||
rc_names[(reg&MQ200_GCC_RCLK_MASK)>>MQ200_GCC_RCLK_SHIFT],
|
||||
fd_names[(reg&MQ200_GCC_MCLK_FD_MASK)>>MQ200_GCC_MCLK_FD_SHIFT],
|
||||
(reg&MQ200_GCC_MCLK_SD_MASK)>>MQ200_GCC_MCLK_SD_SHIFT);
|
||||
|
||||
if (gc == 0) {
|
||||
/*
|
||||
* GC01R Graphics Controller CRT Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GC1CRTCR);
|
||||
printf("GC01R=0x%08x:\n", reg);
|
||||
printf(" CRT DAC: %s\n",
|
||||
ENABLE(reg&MQ200_GC1CRTC_DACEN));
|
||||
|
||||
printf(" power down mode: H-sync=");
|
||||
switch (reg & MQ200_GC1CRTC_HSYNC_PMMASK) {
|
||||
case MQ200_GC1CRTC_HSYNC_PMNORMAL:
|
||||
if (reg & MQ200_GC1CRTC_HSYNC_PMCLK)
|
||||
printf("PMCLK");
|
||||
else
|
||||
printf("LOW");
|
||||
break;
|
||||
case MQ200_GC1CRTC_HSYNC_PMLOW:
|
||||
printf("LOW");
|
||||
break;
|
||||
case MQ200_GC1CRTC_HSYNC_PMHIGH:
|
||||
printf("HIGH");
|
||||
break;
|
||||
default:
|
||||
printf("???");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" V-sync=");
|
||||
switch (reg & MQ200_GC1CRTC_VSYNC_PMMASK) {
|
||||
case MQ200_GC1CRTC_VSYNC_PMNORMAL:
|
||||
if (reg & MQ200_GC1CRTC_VSYNC_PMCLK)
|
||||
printf("PMCLK");
|
||||
else
|
||||
printf("LOW");
|
||||
break;
|
||||
case MQ200_GC1CRTC_VSYNC_PMLOW:
|
||||
printf("LOW");
|
||||
break;
|
||||
case MQ200_GC1CRTC_VSYNC_PMHIGH:
|
||||
printf("HIGH");
|
||||
break;
|
||||
default:
|
||||
printf("???");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf(" sync active: H=%s V=%s\n",
|
||||
(reg & MQ200_GC1CRTC_HSYNC_ACTVLOW)?"low":"high",
|
||||
(reg & MQ200_GC1CRTC_VSYNC_ACTVLOW)?"low":"high");
|
||||
printf(" other: ");
|
||||
if (reg & MQ200_GC1CRTC_SYNC_PEDESTAL_EN)
|
||||
printf("Sync_pedestal ");
|
||||
if (reg & MQ200_GC1CRTC_BLANK_PEDESTAL_EN)
|
||||
printf("Blank_pedestal ");
|
||||
if (reg & MQ200_GC1CRTC_COMPOSITE_SYNC_EN)
|
||||
printf("Conposite_sync ");
|
||||
if (reg & MQ200_GC1CRTC_VREF_EXTR)
|
||||
printf("External_VREF ");
|
||||
if (reg & MQ200_GC1CRTC_MONITOR_SENCE_EN) {
|
||||
if (reg & MQ200_GC1CRTC_CONSTANT_OUTPUT_EN)
|
||||
printf("Monitor_sence=%s%s%s/- ",
|
||||
(reg & MQ200_GC1CRTC_BLUE_NOTLOADED)?"":"B",
|
||||
(reg & MQ200_GC1CRTC_RED_NOTLOADED)?"":"R",
|
||||
(reg & MQ200_GC1CRTC_GREEN_NOTLOADED)?"":"G");
|
||||
else
|
||||
printf("Monitor_sence=%s%s%s/0x%02x ",
|
||||
(reg & MQ200_GC1CRTC_BLUE_NOTLOADED)?"":"B",
|
||||
(reg & MQ200_GC1CRTC_RED_NOTLOADED)?"":"R",
|
||||
(reg & MQ200_GC1CRTC_GREEN_NOTLOADED)?"":"G",
|
||||
(reg & MQ200_GC1CRTC_OUTPUT_LEVEL_MASK)>>MQ200_GC1CRTC_OUTPUT_LEVEL_SHIFT);
|
||||
}
|
||||
if (reg & MQ200_GC1CRTC_MONO)
|
||||
printf("Mono_monitor ");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* GC02R Horizontal Display Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCHDCR(gc));
|
||||
if (gc == 0) {
|
||||
printf("GC02R=0x%08x: Horizontal display total=%03d end=%03d\n", reg,
|
||||
(reg&MQ200_GC1HDC_TOTAL_MASK)>>MQ200_GC1HDC_TOTAL_SHIFT,
|
||||
(reg&MQ200_GCHDC_END_MASK)>>MQ200_GCHDC_END_SHIFT);
|
||||
} else {
|
||||
printf("GC02R=0x%08x: Horizontal display end=%03d\n", reg,
|
||||
(reg&MQ200_GCHDC_END_MASK)>>MQ200_GCHDC_END_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* GC03R Vertical Display Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCVDCR(gc));
|
||||
if (gc == 0) {
|
||||
printf("GC03R=0x%08x: Vertical display total=%03d end=%03d\n", reg,
|
||||
(reg&MQ200_GC1VDC_TOTAL_MASK)>>MQ200_GC1VDC_TOTAL_SHIFT,
|
||||
(reg&MQ200_GCVDC_END_MASK)>>MQ200_GCVDC_END_SHIFT);
|
||||
} else {
|
||||
printf("GC03R=0x%08x: Vertical display end=%03d\n", reg,
|
||||
(reg&MQ200_GCVDC_END_MASK)>>MQ200_GCVDC_END_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* GC04R Horizontal Sync Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCHSCR(gc));
|
||||
printf("GC04R=0x%08x: Horizontal sync start=%03d end=%03d\n", reg,
|
||||
(reg&MQ200_GCHSC_START_MASK)>>MQ200_GCHSC_START_SHIFT,
|
||||
(reg&MQ200_GCHSC_END_MASK)>>MQ200_GCHSC_END_SHIFT);
|
||||
|
||||
/*
|
||||
* GC05R Vertical Sync Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCVSCR(gc));
|
||||
printf("GC05R=0x%08x: Vertical sync start=%03d end=%03d\n", reg,
|
||||
(reg&MQ200_GCVSC_START_MASK)>>MQ200_GCVSC_START_SHIFT,
|
||||
(reg&MQ200_GCVSC_END_MASK)>>MQ200_GCVSC_END_SHIFT);
|
||||
|
||||
if (gc == 0) {
|
||||
/*
|
||||
* GC07R Vertical Display Count
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GC1VDCNTR);
|
||||
printf("GC07R=0x%08x: Vertical Display Count=%d\n", reg,
|
||||
(reg&MQ200_GC1VDCNT_MASK));
|
||||
}
|
||||
|
||||
/*
|
||||
* GC08R Window Horizontal Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCWHCR(gc));
|
||||
printf("GC08R=0x%08x: Window Horizontal start=%03d width=%03d",
|
||||
reg,
|
||||
(reg&MQ200_GCWHC_START_MASK)>> MQ200_GCWHC_START_SHIFT,
|
||||
(reg&MQ200_GCWHC_WIDTH_MASK)>> MQ200_GCWHC_WIDTH_SHIFT);
|
||||
if (gc == 0) {
|
||||
printf(" add=%03x",
|
||||
(reg&MQ200_GC1WHC_ALD_MASK)>> MQ200_GC1WHC_ALD_SHIFT);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* GC09R Window Vertical Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCWVCR(gc));
|
||||
printf("GC09R=0x%08x: Window Vertical start=%03d hight=%03d\n",
|
||||
reg,
|
||||
(reg&MQ200_GCWVC_START_MASK)>> MQ200_GCWVC_START_SHIFT,
|
||||
(reg&MQ200_GCWVC_HEIGHT_MASK)>> MQ200_GCWVC_HEIGHT_SHIFT);
|
||||
|
||||
/*
|
||||
* GC0AR Alternate Window Horizontal Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCAWHCR(gc));
|
||||
printf("GC0AR=0x%08x: Altwin Horizontal start=%03d width=%03d",
|
||||
reg,
|
||||
(reg&MQ200_GCAWHC_START_MASK)>> MQ200_GCAWHC_START_SHIFT,
|
||||
(reg&MQ200_GCAWHC_WIDTH_MASK)>> MQ200_GCAWHC_WIDTH_SHIFT);
|
||||
if (gc == 0) {
|
||||
printf(" add=%03d",
|
||||
(reg&MQ200_GC1AWHC_ALD_MASK)>> MQ200_GC1AWHC_ALD_SHIFT);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* GC0BR Alternate Window Vertical Control
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCAWVCR(gc));
|
||||
printf("GC0BR=0x%08x: Altwin Vertical start=%03d hight=%03d\n",
|
||||
reg,
|
||||
(reg&MQ200_GCAWVC_START_MASK)>> MQ200_GCAWVC_START_SHIFT,
|
||||
(reg&MQ200_GCAWVC_HEIGHT_MASK)>> MQ200_GCAWVC_HEIGHT_SHIFT);
|
||||
|
||||
/*
|
||||
* GC0CR Window Start Address
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCWSAR(gc));
|
||||
printf("GC0CR=0x%08x: Window start address=0x%08x\n",
|
||||
reg, (reg&MQ200_GCWSA_MASK));
|
||||
|
||||
/*
|
||||
* GC0DR Alternate Window Start Address
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCAWSAR(gc));
|
||||
printf("GC0DR=0x%08x: Altwin start address=0x%08x palette_index=%02d\n",
|
||||
reg, (reg&MQ200_GCAWSA_MASK),
|
||||
(reg&MQ200_GCAWPI_MASK)>>MQ200_GCAWPI_SHIFT);
|
||||
|
||||
/*
|
||||
* GC0ER Windows Stride
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCWSTR(gc));
|
||||
printf("GC0ER=0x%08x: Stride window=%04d altwin=%04d\n",
|
||||
reg,
|
||||
(reg&MQ200_GCWST_MASK)>>MQ200_GCWST_SHIFT,
|
||||
(reg&MQ200_GCAWST_MASK)>>MQ200_GCAWST_SHIFT);
|
||||
|
||||
/*
|
||||
* GC10R Hardware Cursor Position
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCHCPR(gc));
|
||||
printf("GC10R=0x%08x: Hardware Cursor Position %d,%d\n",
|
||||
reg,
|
||||
(reg&MQ200_GCHCP_HSTART_MASK)>>MQ200_GCHCP_HSTART_SHIFT,
|
||||
(reg&MQ200_GCHCP_VSTART_MASK)>>MQ200_GCHCP_VSTART_SHIFT);
|
||||
|
||||
/*
|
||||
* GC11R Hardware Cursor Start Address and Offset
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCHCAOR(gc));
|
||||
printf("GC11R=0x%08x: Hardware Cursor Start Address and Offset\n",
|
||||
reg);
|
||||
|
||||
/*
|
||||
* GC12R Hardware Cursor Foreground Color
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCHCFCR(gc));
|
||||
printf("GC12R=0x%08x: Hardware Cursor Foreground Color\n", reg);
|
||||
|
||||
/*
|
||||
* GC13R Hardware Cursor Background Color
|
||||
*/
|
||||
reg = mq200_read(sc, MQ200_GCHCBCR(gc));
|
||||
printf("GC13R=0x%08x: Hardware Cursor Background Color\n", reg);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
mq200_dump_fp(struct mq200_softc *sc)
|
||||
{
|
||||
u_int32_t reg;
|
||||
#define I(type) ((type)>>MQ200_FPC_TYPE_SHIFT)
|
||||
static char *panel_type_names[64] = {
|
||||
[I(MQ200_FPC_TFT4MONO)] = "TFT 4bit mono",
|
||||
[I(MQ200_FPC_TFT12)] = "TFT 12bit color",
|
||||
[I(MQ200_FPC_SSTN4)] = "S-STN 4bit color",
|
||||
[I(MQ200_FPC_DSTN8)] = "D-STN 8bit color",
|
||||
[I(MQ200_FPC_TFT6MONO)] = "TFT 6bit mono",
|
||||
[I(MQ200_FPC_TFT18)] = "TFT 18bit color",
|
||||
[I(MQ200_FPC_SSTN8)] = "S-STN 8bit color",
|
||||
[I(MQ200_FPC_DSTN16)] = "D-STN 16bit color",
|
||||
[I(MQ200_FPC_TFT8MONO)] = "TFT 8bit mono",
|
||||
[I(MQ200_FPC_TFT24)] = "TFT 24bit color",
|
||||
[I(MQ200_FPC_SSTN12)] = "S-STN 12bit color",
|
||||
[I(MQ200_FPC_DSTN24)] = "D-STN 24bit color",
|
||||
[I(MQ200_FPC_SSTN16)] = "S-STN 16bit color",
|
||||
[I(MQ200_FPC_SSTN24)] = "S-STN 24bit color",
|
||||
};
|
||||
|
||||
reg = mq200_read(sc, MQ200_FPCR);
|
||||
printf("FP00R=0x%08x: Flat Panel Control\n", reg);
|
||||
printf(" %s, driven by %s, %s\n",
|
||||
ENABLE(reg & MQ200_FPC_ENABLE),
|
||||
(reg & MQ200_FPC_GC2) ? "GC2" : "GC1",
|
||||
panel_type_names[(reg & MQ200_FPC_TYPE_MASK) >> MQ200_FPC_TYPE_SHIFT]);
|
||||
reg = mq200_read(sc, MQ200_FPPCR);
|
||||
printf("FP01R=0x%08x: Flat Panel Output Pin Control\n", reg);
|
||||
}
|
||||
|
||||
void
|
||||
mq200_dump_dc(struct mq200_softc *sc)
|
||||
{
|
||||
u_int32_t reg;
|
||||
|
||||
reg = 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
#endif /* MQ200_DEBUG */
|
|
@ -0,0 +1,233 @@
|
|||
/* $NetBSD: mq200machdep.c,v 1.1 2001/03/25 13:06:53 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 TAKEMURA Shin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <machine/platid.h>
|
||||
#include <machine/platid_mask.h>
|
||||
|
||||
#include "opt_mq200.h"
|
||||
#include "mq200var.h"
|
||||
#include "mq200reg.h"
|
||||
#include "mq200priv.h"
|
||||
|
||||
#if MQ200_SETUPREGS
|
||||
#define OP_(n) (((n) << 2) | 1)
|
||||
#define OP_END OP_(1)
|
||||
#define OP_MASK OP_(2)
|
||||
#define OP_LOADPLLPARAM OP_(3)
|
||||
#define OP_LOADFROMREG OP_(4)
|
||||
#define OP_STORETOREG OP_(5)
|
||||
#define OP_LOADIMM OP_(6)
|
||||
#define OP_OR OP_(7)
|
||||
|
||||
static void mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops);
|
||||
|
||||
static u_int32_t mcr530_init_ops[] = {
|
||||
MQ200_PMCR, 0, /* power management control */
|
||||
MQ200_DCMISCR, MQ200_DCMISC_OSC_ENABLE |
|
||||
MQ200_DCMISC_FASTPOWSEQ_DISABLE |
|
||||
MQ200_DCMISC_OSCFREQ_12_25,
|
||||
OP_END
|
||||
};
|
||||
#endif /* MQ200_SETUPREGS */
|
||||
|
||||
static struct mq200_clock_setting mcr530_clocks[] = {
|
||||
/* CRT: off FP: off */
|
||||
{
|
||||
MQ200_CLOCK_PLL1, /* memory clock */
|
||||
MQ200_CLOCK_PLL1, /* graphics engine clock */
|
||||
{
|
||||
0, /* GC1(CRT) clock */
|
||||
0, /* GC2(FP) clock */
|
||||
},
|
||||
30000, /* PLL1 30MHz */
|
||||
0, /* PLL2 disable */
|
||||
0, /* PLL3 disable */
|
||||
},
|
||||
/* CRT: on FP: off */
|
||||
{
|
||||
MQ200_CLOCK_PLL1, /* memory clock */
|
||||
MQ200_CLOCK_PLL2, /* graphics engine clock */
|
||||
{
|
||||
MQ200_CLOCK_PLL3, /* GC1(CRT) clock */
|
||||
0, /* GC2(FP) clock */
|
||||
},
|
||||
83000, /* PLL1 83MHz */
|
||||
30000, /* PLL2 30MHz */
|
||||
-1, /* PLL3 will be set by GC1 */
|
||||
},
|
||||
/* CRT: off FP: on */
|
||||
{
|
||||
MQ200_CLOCK_PLL1, /* memory clock */
|
||||
MQ200_CLOCK_PLL2, /* graphics engine clock */
|
||||
{
|
||||
0, /* GC1(CRT) clock */
|
||||
MQ200_CLOCK_PLL2, /* GC2(FP) clock */
|
||||
},
|
||||
30000, /* PLL1 30MHz */
|
||||
18800, /* PLL2 18.8MHz */
|
||||
0, /* PLL3 disable */
|
||||
},
|
||||
/* CRT: on FP: on */
|
||||
{
|
||||
MQ200_CLOCK_PLL1, /* memory clock */
|
||||
MQ200_CLOCK_PLL2, /* graphics engine clock */
|
||||
{
|
||||
MQ200_CLOCK_PLL3, /* GC1(CRT) clock */
|
||||
MQ200_CLOCK_PLL2, /* GC2(FP) clock */
|
||||
},
|
||||
83000, /* PLL1 83MHz */
|
||||
18800, /* PLL2 18.8MHz */
|
||||
-1, /* PLL3 will be set by GC1 */
|
||||
},
|
||||
};
|
||||
|
||||
static struct mq200_md_param machdep_params[] = {
|
||||
{
|
||||
&platid_mask_MACH_NEC_MCR_530,
|
||||
640, 240, /* flat panel size */
|
||||
12288, /* base clock is 12.288 MHz */
|
||||
MQ200_MD_HAVECRT | MQ200_MD_HAVEFP,
|
||||
#if MQ200_SETUPREGS
|
||||
mcr530_init_ops,
|
||||
#else
|
||||
NULL,
|
||||
#endif /* MQ200_SETUPREGS */
|
||||
mcr530_clocks,
|
||||
/* DCMISC */
|
||||
MQ200_DCMISC_OSC_ENABLE |
|
||||
MQ200_DCMISC_FASTPOWSEQ_DISABLE |
|
||||
MQ200_DCMISC_OSCFREQ_12_25,
|
||||
/* PMC */
|
||||
0,
|
||||
/* MM01 */
|
||||
MQ200_MM01_DRAM_AUTO_REFRESH_EN |
|
||||
MQ200_MM01_GE_PB_EN |
|
||||
MQ200_MM01_CPU_PB_EN |
|
||||
MQ200_MM01_SLOW_REFRESH_EN |
|
||||
(0x143e << MQ200_MM01_REFRESH_SHIFT),
|
||||
},
|
||||
};
|
||||
|
||||
void
|
||||
mq200_mdsetup(struct mq200_softc *sc)
|
||||
{
|
||||
const struct mq200_md_param *mdp;
|
||||
|
||||
sc->sc_md = NULL;
|
||||
for (mdp = machdep_params; mdp->md_platform != NULL; mdp++) {
|
||||
platid_mask_t mask;
|
||||
mask = PLATID_DEREF(mdp->md_platform);
|
||||
if (platid_match(&platid, &mask)) {
|
||||
sc->sc_md = mdp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->sc_md) {
|
||||
sc->sc_width[MQ200_GC2] = mdp->md_fp_width;
|
||||
sc->sc_height[MQ200_GC2] = mdp->md_fp_height;
|
||||
sc->sc_baseclock = mdp->md_baseclock;
|
||||
|
||||
sc->sc_regctxs[MQ200_I_DCMISC ].val = mdp->md_init_dcmisc;
|
||||
sc->sc_regctxs[MQ200_I_PMC ].val = mdp->md_init_pmc;
|
||||
sc->sc_regctxs[MQ200_I_MM01 ].val = mdp->md_init_mm01;
|
||||
|
||||
#if MQ200_SETUPREGS
|
||||
mq200_setupregs(sc, mdp->md_init_ops);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if MQ200_SETUPREGS
|
||||
static void
|
||||
mq200_setupregs(struct mq200_softc *sc, u_int32_t *ops)
|
||||
{
|
||||
u_int32_t reg, mask, accum;
|
||||
|
||||
while (1) {
|
||||
switch (ops[0] & 0x3) {
|
||||
case 0:
|
||||
if (mask == ~0) {
|
||||
mq200_write(sc, ops[0], ops[1]);
|
||||
} else {
|
||||
reg = mq200_read(sc, ops[0]);
|
||||
reg = (reg & ~mask) | (ops[1] & mask);
|
||||
mq200_write(sc, ops[0], reg);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (ops[0]) {
|
||||
case OP_END:
|
||||
return;
|
||||
case OP_MASK:
|
||||
mask = ops[1];
|
||||
break;
|
||||
case OP_LOADPLLPARAM:
|
||||
mq200_pllparam(ops[1], &accum);
|
||||
break;
|
||||
case OP_LOADFROMREG:
|
||||
reg = mq200_read(sc, ops[1]);
|
||||
accum = (accum & ~mask) | (reg & mask);
|
||||
break;
|
||||
case OP_STORETOREG:
|
||||
if (mask == ~0) {
|
||||
mq200_write(sc, ops[1], accum);
|
||||
} else {
|
||||
reg = mq200_read(sc, ops[1]);
|
||||
reg = (reg & ~mask) | (accum & mask);
|
||||
mq200_write(sc, ops[1], reg);
|
||||
}
|
||||
break;
|
||||
case OP_LOADIMM:
|
||||
accum = (accum & ~mask) | (ops[1] & mask);
|
||||
break;
|
||||
case OP_OR:
|
||||
accum = (accum | ops[1]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ops[0] != OP_MASK)
|
||||
mask = ~0;
|
||||
ops += 2;
|
||||
}
|
||||
}
|
||||
#endif /* MQ200_SETUPREGS */
|
|
@ -0,0 +1,156 @@
|
|||
/* $NetBSD: mq200priv.h,v 1.1 2001/03/25 13:06:53 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 TAKEMURA Shin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
struct mq200_crt_param {
|
||||
u_int16_t width, height, clock;
|
||||
u_int16_t hdtotal;
|
||||
u_int16_t vdtotal;
|
||||
u_int16_t hsstart, hsend;
|
||||
u_int16_t vsstart, vsend;
|
||||
u_int32_t opt;
|
||||
};
|
||||
#define MQ200_CRT_640x480_60Hz 0
|
||||
#define MQ200_CRT_800x600_60Hz 1
|
||||
#define MQ200_CRT_1024x768_60Hz 2
|
||||
|
||||
struct mq200_clock_setting {
|
||||
u_int8_t mem, ge, gc[2];
|
||||
int pll1, pll2, pll3;
|
||||
};
|
||||
|
||||
struct mq200_md_param {
|
||||
platid_t *md_platform;
|
||||
short md_fp_width, md_fp_height;
|
||||
int md_baseclock;
|
||||
int md_flags;
|
||||
#define MQ200_MD_HAVECRT (1<<0)
|
||||
#define MQ200_MD_HAVEFP (1<<1)
|
||||
u_int32_t *md_init_ops;
|
||||
const struct mq200_clock_setting *md_clock_settings;
|
||||
u_int32_t md_init_dcmisc;
|
||||
u_int32_t md_init_pmc;
|
||||
u_int32_t md_init_mm01;
|
||||
};
|
||||
|
||||
extern struct mq200_crt_param mq200_crt_params[];
|
||||
extern int mq200_crt_nparams;
|
||||
extern char *mq200_clknames[];
|
||||
|
||||
void mq200_pllparam(int reqout, u_int32_t *res);
|
||||
void mq200_set_pll(struct mq200_softc *, int, int);
|
||||
void mq200_setup_regctx(struct mq200_softc *sc);
|
||||
void mq200_setup(struct mq200_softc *sc);
|
||||
void mq200_win_enable(struct mq200_softc *sc, int gc,
|
||||
u_int32_t depth, u_int32_t start,
|
||||
int width, int height, int stride);
|
||||
void mq200_win_disable(struct mq200_softc *sc, int gc);
|
||||
void mq200_setupmd(struct mq200_softc *sc);
|
||||
void mq200_mdsetup(struct mq200_softc *sc);
|
||||
|
||||
void mq200_dump_gc(struct mq200_softc *sc, int gc);
|
||||
void mq200_dump_fp(struct mq200_softc *sc);
|
||||
void mq200_dump_dc(struct mq200_softc *sc);
|
||||
void mq200_dump_pll(struct mq200_softc *sc);
|
||||
void mq200_dump_all(struct mq200_softc *sc);
|
||||
char* mq200_regname(struct mq200_softc *sc, int offset, char *buf, int size);
|
||||
|
||||
#ifdef MQ200_DEBUG
|
||||
#ifndef MQ200DEBUG_CONF
|
||||
#define MQ200DEBUG_CONF 0
|
||||
#endif
|
||||
extern int mq200_debug;
|
||||
#define DPRINTF(fmt, args...) do { if (mq200_debug) printf("mq200: " fmt, ##args); } while(0)
|
||||
#define VPRINTF(fmt, args...) do { if (bootverbose || mq200_debug) printf("mq200: " fmt, ##args); } while(0)
|
||||
#else
|
||||
#define DPRINTF(fmt, args...) do { } while (0)
|
||||
#define VPRINTF(fmt, args...) do { if (bootverbose) printf("mq200: " fmt, ##args); } while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* register access wrappers
|
||||
*/
|
||||
static inline void
|
||||
mq200_writex(struct mq200_softc *sc, int offset, u_int32_t data)
|
||||
{
|
||||
#ifdef _KERNEL
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, offset, data);
|
||||
#else
|
||||
*(volatile unsigned long*)(sc->sc_baseaddr + offset) = data;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MQ200_DEBUG
|
||||
void
|
||||
mq200_write(struct mq200_softc *sc, int offset, u_int32_t data);
|
||||
#else
|
||||
static inline void
|
||||
mq200_write(struct mq200_softc *sc, int offset, u_int32_t data)
|
||||
{
|
||||
mq200_writex(sc, offset, data);
|
||||
}
|
||||
#endif /* MQ200_DEBUG */
|
||||
|
||||
static inline void
|
||||
mq200_write2(struct mq200_softc *sc, struct mq200_regctx *reg, u_int32_t data)
|
||||
{
|
||||
reg->val = data;
|
||||
mq200_writex(sc, reg->offset, reg->val);
|
||||
}
|
||||
|
||||
static inline u_int32_t
|
||||
mq200_read(struct mq200_softc *sc, int offset)
|
||||
{
|
||||
#ifdef _KERNEL
|
||||
return bus_space_read_4(sc->sc_iot, sc->sc_ioh, offset);
|
||||
#else
|
||||
return *(volatile unsigned long*)(sc->sc_baseaddr + offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
mq200_mod(struct mq200_softc *sc, struct mq200_regctx *reg, u_int32_t mask, u_int32_t data)
|
||||
{
|
||||
reg->val &= ~mask;
|
||||
reg->val |= data;
|
||||
mq200_writex(sc, reg->offset, reg->val);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mq200_on(struct mq200_softc *sc, struct mq200_regctx *reg, unsigned long data)
|
||||
{
|
||||
mq200_mod(sc, reg, data, data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mq200_off(struct mq200_softc *sc, struct mq200_regctx *reg, unsigned long data)
|
||||
{
|
||||
mq200_mod(sc, reg, data, 0);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: mq200reg.h,v 1.5 2001/03/11 13:53:31 takemura Exp $ */
|
||||
/* $NetBSD: mq200reg.h,v 1.6 2001/03/25 13:06:53 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Takemura Shin
|
||||
* Copyright (c) 2000, 2001 TAKEMURA Shin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -68,11 +68,24 @@
|
|||
*/
|
||||
#define MQ200_MMR(n) (MQ200_MM+(n)*4)
|
||||
# define MQ200_MM00_ENABLE (1<<0)
|
||||
# define MQ200_MM00_RESET (1<<1)
|
||||
# define MQ200_MM00_DRAM_RESET (1<<2)
|
||||
# define MQ200_MM01_CLK_PLL1 (0<<0)
|
||||
# define MQ200_MM01_CLK_BUS (1<<0)
|
||||
# define MQ200_MM01_CLK_PLL2 (1<<0)
|
||||
# define MQ200_MM00_RESET (1<<1)
|
||||
# define MQ200_MM00_DRAM_RESET (1<<2)
|
||||
# define MQ200_MM01_CLK_PLL1 (0<<0)
|
||||
# define MQ200_MM01_CLK_BUS (1<<0)
|
||||
# define MQ200_MM01_CLK_PLL2 (1<<0)
|
||||
# define MQ200_MM01_SLOW_REFRESH_EN (1<<1)
|
||||
# define MQ200_MM01_CPU_PB_EN (1<<2)
|
||||
# define MQ200_MM01_GC1_PB_EN (1<<3)
|
||||
# define MQ200_MM01_GC2_PB_EN (1<<4)
|
||||
# define MQ200_MM01_STN_READ_PB_EN (1<<5)
|
||||
# define MQ200_MM01_STN_WRITE_PB_EN (1<<6)
|
||||
# define MQ200_MM01_GE_PB_EN (1<<7)
|
||||
/* bits 11-8 is reserved */
|
||||
# define MQ200_MM01_REFRESH_SHIFT 12
|
||||
# define MQ200_MM01_REFRESH_MASK 0x03fff000
|
||||
/* bits 29 is reserved */
|
||||
# define MQ200_MM01_DRAM_AUTO_REFRESH_EN (1<<30)
|
||||
# define MQ200_MM01_DRAM_STANDBY_EN (1<<31)
|
||||
|
||||
/*
|
||||
* Interrupt Controller
|
||||
|
@ -617,6 +630,7 @@
|
|||
*/
|
||||
#define MQ200_PMCR (MQ200_PM + 0x00)
|
||||
# define MQ200_PMC_PLL1_N (1<<0)
|
||||
# define MQ200_PMC_PLL1_N_SHIFT 5
|
||||
# define MQ200_PMC_PLL2_ENABLE (1<<2)
|
||||
# define MQ200_PMC_PLL3_ENABLE (1<<3)
|
||||
# define MQ200_PMC_IMMEDIATELY (1<<5)
|
||||
|
|
|
@ -0,0 +1,371 @@
|
|||
/* $NetBSD: mq200subr.c,v 1.1 2001/03/25 13:06:53 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 TAKEMURA Shin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <machine/platid.h>
|
||||
#include <machine/platid_mask.h>
|
||||
|
||||
#include "opt_mq200.h"
|
||||
#include "mq200var.h"
|
||||
#include "mq200reg.h"
|
||||
#include "mq200priv.h"
|
||||
|
||||
#define ABS(a) ((a) < 0 ? -(a) : (a))
|
||||
|
||||
int mq200_depth_table[] = {
|
||||
[MQ200_GCC_1BPP] = 1,
|
||||
[MQ200_GCC_2BPP] = 2,
|
||||
[MQ200_GCC_4BPP] = 4,
|
||||
[MQ200_GCC_8BPP] = 8,
|
||||
[MQ200_GCC_16BPP] = 16,
|
||||
[MQ200_GCC_24BPP] = 32,
|
||||
[MQ200_GCC_ARGB888] = 32,
|
||||
[MQ200_GCC_ABGR888] = 32,
|
||||
[MQ200_GCC_16BPP_DIRECT] = 16,
|
||||
[MQ200_GCC_24BPP_DIRECT] = 32,
|
||||
[MQ200_GCC_ARGB888_DIRECT] = 32,
|
||||
[MQ200_GCC_ABGR888_DIRECT] = 32,
|
||||
};
|
||||
|
||||
struct mq200_crt_param mq200_crt_params[] = {
|
||||
[MQ200_CRT_640x480_60Hz] =
|
||||
{ 640, 480, 25175, /* width, height, dot clock */
|
||||
800, /* HD Total */
|
||||
525, /* VD Total */
|
||||
656, 752, /* HS Start, HS End */
|
||||
490, 492, /* VS Start, VS End */
|
||||
(MQ200_GC1CRTC_HSYNC_ACTVLOW |
|
||||
MQ200_GC1CRTC_VSYNC_ACTVLOW |
|
||||
MQ200_GC1CRTC_BLANK_PEDESTAL_EN),
|
||||
},
|
||||
[MQ200_CRT_800x600_60Hz] =
|
||||
{ 800, 600, 40000, /* width, height, dot clock */
|
||||
1054, /* HD Total */
|
||||
628, /* VD Total */
|
||||
839, 967, /* HS Start, HS End */
|
||||
601, 605, /* VS Start, VS End */
|
||||
MQ200_GC1CRTC_BLANK_PEDESTAL_EN,
|
||||
},
|
||||
[MQ200_CRT_1024x768_60Hz] =
|
||||
{ 1024, 768, 65000, /* width, height, dot clock */
|
||||
1344, /* HD Total */
|
||||
806, /* VD Total */
|
||||
1048, 1184, /* HS Start, HS End */
|
||||
771, 777, /* VS Start, VS End */
|
||||
(MQ200_GC1CRTC_HSYNC_ACTVLOW |
|
||||
MQ200_GC1CRTC_VSYNC_ACTVLOW |
|
||||
MQ200_GC1CRTC_BLANK_PEDESTAL_EN),
|
||||
},
|
||||
};
|
||||
|
||||
int mq200_crt_nparams = sizeof(mq200_crt_params)/sizeof(*mq200_crt_params);
|
||||
|
||||
/*
|
||||
* get PLL setting register value for given frequency
|
||||
*/
|
||||
void
|
||||
mq200_pllparam(int reqout, u_int32_t *res)
|
||||
{
|
||||
int n, m, p, out;
|
||||
int ref = 12288;
|
||||
int bn, bm, bp, e;
|
||||
|
||||
e = ref;
|
||||
for (p = 0; p <= 4; p++) {
|
||||
for (n = 0; n < (1<<5); n++) {
|
||||
m = (reqout * ((n + 1) << p)) / ref - 1;
|
||||
out = ref * (m + 1) / ((n + 1) << p);
|
||||
if (0xff < m)
|
||||
break;
|
||||
if (40 <= m &&
|
||||
1000 <= ref/(n + 1) &&
|
||||
170000 <= ref*(m+1)/(n+1) &&
|
||||
ref*(m+1)/(n+1) <= 340000 &&
|
||||
ABS(reqout - out) <= e) {
|
||||
e = ABS(reqout - out);
|
||||
bn = n;
|
||||
bm = m;
|
||||
bp = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
out = ref * (bm + 1) / ((bn + 1) << bp);
|
||||
printf("PLL: %d.%03d x (%d+1) / (%d+1) / %d = %d.%03d\n",
|
||||
ref / 1000, ref % 1000, bm, bn, (1<<bp),
|
||||
out / 1000, out % 1000);
|
||||
#endif
|
||||
*res = ((bm << MQ200_PLL_M_SHIFT) |
|
||||
(bn << MQ200_PLL_N_SHIFT) |
|
||||
(bp << MQ200_PLL_P_SHIFT));
|
||||
}
|
||||
|
||||
void
|
||||
mq200_set_pll(struct mq200_softc *sc, int pll, int clock)
|
||||
{
|
||||
struct mq200_regctx *paramreg, *enreg;
|
||||
u_int32_t param, enbit;
|
||||
|
||||
switch (pll) {
|
||||
case MQ200_CLOCK_PLL1:
|
||||
paramreg = &sc->sc_regctxs[MQ200_I_PLL(1)];
|
||||
enreg = &sc->sc_regctxs[MQ200_I_DCMISC];
|
||||
enbit = MQ200_DCMISC_PLL1_ENABLE;
|
||||
break;
|
||||
case MQ200_CLOCK_PLL2:
|
||||
paramreg = &sc->sc_regctxs[MQ200_I_PLL(2)];
|
||||
enreg = &sc->sc_regctxs[MQ200_I_PMC];
|
||||
enbit = MQ200_PMC_PLL2_ENABLE;
|
||||
break;
|
||||
case MQ200_CLOCK_PLL3:
|
||||
paramreg = &sc->sc_regctxs[MQ200_I_PLL(3)];
|
||||
enreg = &sc->sc_regctxs[MQ200_I_PMC];
|
||||
enbit = MQ200_PMC_PLL3_ENABLE;
|
||||
break;
|
||||
default:
|
||||
printf("mq200: invalid PLL: %d\n", pll);
|
||||
return;
|
||||
}
|
||||
if (clock != 0 && clock != -1) {
|
||||
/* PLL Programming */
|
||||
mq200_pllparam(clock, ¶m);
|
||||
mq200_mod(sc, paramreg, MQ200_PLL_PARAM_MASK, param);
|
||||
/* enable PLL */
|
||||
mq200_on(sc, enreg, enbit);
|
||||
}
|
||||
|
||||
DPRINTF("%s %d.%03dMHz\n",
|
||||
mq200_clknames[pll], clock/1000, clock%1000);
|
||||
}
|
||||
|
||||
void
|
||||
mq200_setup_regctx(struct mq200_softc *sc)
|
||||
{
|
||||
int i;
|
||||
static int offsets[MQ200_I_MAX] = {
|
||||
[MQ200_I_DCMISC] = MQ200_DCMISCR,
|
||||
[MQ200_I_PLL(2)] = MQ200_PLL2R,
|
||||
[MQ200_I_PLL(3)] = MQ200_PLL3R,
|
||||
[MQ200_I_PMC] = MQ200_PMCR,
|
||||
[MQ200_I_MM01] = MQ200_MMR(1),
|
||||
[MQ200_I_GCC(MQ200_GC1)] = MQ200_GCCR(MQ200_GC1),
|
||||
[MQ200_I_GCC(MQ200_GC2)] = MQ200_GCCR(MQ200_GC2),
|
||||
};
|
||||
|
||||
for (i = 0; i < sizeof(offsets)/sizeof(*offsets); i++) {
|
||||
if (offsets[i] == 0)
|
||||
#ifdef MQ200_DEBUG
|
||||
panic("%s(%d): register context %d is empty\n",
|
||||
__FILE__, __LINE__, i);
|
||||
#endif
|
||||
sc->sc_regctxs[i].offset = offsets[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mq200_setup(struct mq200_softc *sc)
|
||||
{
|
||||
const struct mq200_clock_setting *clock;
|
||||
const struct mq200_crt_param *crt;
|
||||
|
||||
clock = &sc->sc_md->md_clock_settings[sc->sc_flags & MQ200_SC_GC_MASK];
|
||||
crt = sc->sc_crt;
|
||||
|
||||
/* disable GC1 and GC2 */
|
||||
//mq200_write(sc, MQ200_GCCR(MQ200_GC1), 0);
|
||||
mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC1)], 0);
|
||||
mq200_write(sc, MQ200_GC1CRTCR, 0);
|
||||
//mq200_write(sc, MQ200_GCCR(MQ200_GC2), 0);
|
||||
mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC2)], 0);
|
||||
|
||||
while (mq200_read(sc, MQ200_PMCR) & MQ200_PMC_SEQPROGRESS)
|
||||
/* busy wait */;
|
||||
|
||||
/*
|
||||
* setup around clock
|
||||
*/
|
||||
/* setup eatch PLLs */
|
||||
mq200_set_pll(sc, MQ200_CLOCK_PLL1, clock->pll1);
|
||||
mq200_set_pll(sc, MQ200_CLOCK_PLL2, clock->pll2);
|
||||
mq200_set_pll(sc, MQ200_CLOCK_PLL3, clock->pll3);
|
||||
if (sc->sc_flags & MQ200_SC_GC1_ENABLE)
|
||||
mq200_set_pll(sc, clock->gc[MQ200_GC1], crt->clock);
|
||||
|
||||
/* setup MEMORY clock */
|
||||
if (clock->mem == MQ200_CLOCK_PLL2)
|
||||
mq200_on(sc, &sc->sc_regctxs[MQ200_I_MM01],
|
||||
MQ200_MM01_CLK_PLL2);
|
||||
else
|
||||
mq200_off(sc, &sc->sc_regctxs[MQ200_I_MM01],
|
||||
MQ200_MM01_CLK_PLL2);
|
||||
DPRINTF("MEM: PLL%d\n", (clock->mem == MQ200_CLOCK_PLL2)?2:1);
|
||||
|
||||
/* setup GE clock */
|
||||
mq200_mod(sc, &sc->sc_regctxs[MQ200_I_PMC],
|
||||
MQ200_PMC_GE_CLK_MASK | MQ200_PMC_GE_ENABLE,
|
||||
(clock->ge << MQ200_PMC_GE_CLK_SHIFT) | MQ200_PMC_GE_ENABLE);
|
||||
DPRINTF(" GE: PLL%d\n", clock->ge);
|
||||
|
||||
/*
|
||||
* setup GC1 (CRT contoller)
|
||||
*/
|
||||
if (sc->sc_flags & MQ200_SC_GC1_ENABLE) {
|
||||
/* GC03R Horizontal Display Control */
|
||||
mq200_write(sc, MQ200_GCHDCR(MQ200_GC1),
|
||||
(((u_int32_t)crt->hdtotal-2)<<MQ200_GC1HDC_TOTAL_SHIFT) |
|
||||
((u_int32_t)crt->width << MQ200_GCHDC_END_SHIFT));
|
||||
|
||||
/* GC03R Vertical Display Control */
|
||||
mq200_write(sc, MQ200_GCVDCR(MQ200_GC1),
|
||||
(((u_int32_t)crt->vdtotal-1)<<MQ200_GC1VDC_TOTAL_SHIFT) |
|
||||
(((u_int32_t)crt->height - 1) << MQ200_GCVDC_END_SHIFT));
|
||||
|
||||
/* GC04R Horizontal Sync Control */
|
||||
mq200_write(sc, MQ200_GCHSCR(MQ200_GC1),
|
||||
((u_int32_t)crt->hsstart << MQ200_GCHSC_START_SHIFT) |
|
||||
((u_int32_t)crt->hsend << MQ200_GCHSC_END_SHIFT));
|
||||
|
||||
/* GC05R Vertical Sync Control */
|
||||
mq200_write(sc, MQ200_GCVSCR(MQ200_GC1),
|
||||
((u_int32_t)crt->vsstart << MQ200_GCVSC_START_SHIFT) |
|
||||
((u_int32_t)crt->vsend << MQ200_GCVSC_END_SHIFT));
|
||||
|
||||
/* GC00R GC1 Control */
|
||||
//mq200_write(sc, MQ200_GCCR(MQ200_GC1),
|
||||
mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC1)],
|
||||
(MQ200_GCC_ENABLE |
|
||||
(clock->gc[MQ200_GC1] << MQ200_GCC_RCLK_SHIFT) |
|
||||
MQ200_GCC_MCLK_FD_1 |
|
||||
(1 << MQ200_GCC_MCLK_SD_SHIFT)));
|
||||
|
||||
/* GC01R CRT Control */
|
||||
mq200_write(sc, MQ200_GC1CRTCR,
|
||||
MQ200_GC1CRTC_DACEN | crt->opt);
|
||||
|
||||
sc->sc_width[MQ200_GC1] = crt->width;
|
||||
sc->sc_height[MQ200_GC1] = crt->height;
|
||||
|
||||
DPRINTF("GC1: %s\n",
|
||||
mq200_clknames[clock->gc[MQ200_GC1]]);
|
||||
}
|
||||
|
||||
while (mq200_read(sc, MQ200_PMCR) & MQ200_PMC_SEQPROGRESS)
|
||||
/* busy wait */;
|
||||
|
||||
/*
|
||||
* setup GC2 (FP contoller)
|
||||
*/
|
||||
if (sc->sc_flags & MQ200_SC_GC2_ENABLE) {
|
||||
//mq200_write(sc, MQ200_GCCR(MQ200_GC2),
|
||||
mq200_write2(sc, &sc->sc_regctxs[MQ200_I_GCC(MQ200_GC2)],
|
||||
MQ200_GCC_ENABLE |
|
||||
(clock->gc[MQ200_GC2] << MQ200_GCC_RCLK_SHIFT) |
|
||||
MQ200_GCC_MCLK_FD_1 | (1 << MQ200_GCC_MCLK_SD_SHIFT));
|
||||
DPRINTF("GC2: %s\n",
|
||||
mq200_clknames[clock->gc[MQ200_GC2]]);
|
||||
}
|
||||
|
||||
while (mq200_read(sc, MQ200_PMCR) & MQ200_PMC_SEQPROGRESS)
|
||||
/* busy wait */;
|
||||
|
||||
/*
|
||||
* disable unused PLLs
|
||||
*/
|
||||
if (clock->pll1 == 0) {
|
||||
DPRINTF("PLL1 disable\n");
|
||||
mq200_off(sc, &sc->sc_regctxs[MQ200_I_DCMISC],
|
||||
MQ200_DCMISC_PLL1_ENABLE);
|
||||
}
|
||||
if (clock->pll2 == 0) {
|
||||
DPRINTF("PLL2 disable\n");
|
||||
mq200_off(sc, &sc->sc_regctxs[MQ200_I_PMC],
|
||||
MQ200_PMC_PLL2_ENABLE);
|
||||
}
|
||||
if (clock->pll3 == 0) {
|
||||
DPRINTF("PLL3 disable\n");
|
||||
mq200_off(sc, &sc->sc_regctxs[MQ200_I_PMC],
|
||||
MQ200_PMC_PLL3_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mq200_win_enable(struct mq200_softc *sc, int gc,
|
||||
u_int32_t depth, u_int32_t start,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
|
||||
DPRINTF("enable window on GC%d: %dx%d(%dx%d)\n",
|
||||
gc + 1, width, height, sc->sc_width[gc], sc->sc_height[gc]);
|
||||
|
||||
if (sc->sc_width[gc] < width) {
|
||||
if (mq200_depth_table[depth])
|
||||
start += (height - sc->sc_height[gc]) *
|
||||
mq200_depth_table[depth] / 8;
|
||||
width = sc->sc_width[gc];
|
||||
}
|
||||
|
||||
if (sc->sc_height[gc] < height) {
|
||||
start += (height - sc->sc_height[gc]) * stride;
|
||||
height = sc->sc_height[gc];
|
||||
}
|
||||
|
||||
/* GC08R Window Horizontal Control */
|
||||
mq200_write(sc, MQ200_GCWHCR(gc),
|
||||
(((u_int32_t)width - 1) << MQ200_GCWHC_WIDTH_SHIFT) |
|
||||
((sc->sc_width[gc] - width)/2));
|
||||
|
||||
/* GC09R Window Vertical Control */
|
||||
mq200_write(sc, MQ200_GCWVCR(gc),
|
||||
(((u_int32_t)height - 1) << MQ200_GCWVC_HEIGHT_SHIFT) |
|
||||
((sc->sc_height[gc] - height)/2));
|
||||
|
||||
/* GC00R GC Control */
|
||||
mq200_mod(sc, &sc->sc_regctxs[MQ200_I_GCC(gc)],
|
||||
(MQ200_GCC_WINEN | MQ200_GCC_DEPTH_MASK),
|
||||
(MQ200_GCC_WINEN | (depth << MQ200_GCC_DEPTH_SHIFT)));
|
||||
}
|
||||
|
||||
void
|
||||
mq200_win_disable(struct mq200_softc *sc, int gc)
|
||||
{
|
||||
/* GC00R GC Control */
|
||||
mq200_off(sc, &sc->sc_regctxs[MQ200_I_GCC(gc)], MQ200_GCC_WINEN);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: mq200var.h,v 1.4 2001/03/09 08:54:19 sato Exp $ */
|
||||
/* $NetBSD: mq200var.h,v 1.5 2001/03/25 13:06:53 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Takemura Shin
|
||||
* Copyright (c) 2000, 2001 TAKEMURA Shin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -59,6 +59,26 @@ struct mq200_softc {
|
|||
int sc_mq200pwstate; /* mq200 power state */
|
||||
struct hpcfb_fbconf sc_fbconf;
|
||||
struct hpcfb_dspconf sc_dspconf;
|
||||
|
||||
int sc_baseclock;
|
||||
#define MQ200_SC_GC1_ENABLE (1<<0) /* XXX, You can't change this */
|
||||
#define MQ200_SC_GC2_ENABLE (1<<1) /* XXX, You can't change this */
|
||||
#define MQ200_SC_GC_MASK (MQ200_SC_GC1_ENABLE|MQ200_SC_GC2_ENABLE)
|
||||
char sc_flags;
|
||||
int sc_width[2], sc_height[2];
|
||||
const struct mq200_md_param *sc_md;
|
||||
const struct mq200_crt_param *sc_crt;
|
||||
|
||||
#define MQ200_I_DCMISC 0
|
||||
#define MQ200_I_PLL(n) (MQ200_I_DCMISC + (n) - 1) /* 1, 2 */
|
||||
#define MQ200_I_PMC 3
|
||||
#define MQ200_I_MM01 4
|
||||
#define MQ200_I_GCC(n) (5 + (n)) /* 5, 6 */
|
||||
#define MQ200_I_MAX 7
|
||||
struct mq200_regctx {
|
||||
int offset;
|
||||
u_int32_t val;
|
||||
} sc_regctxs[MQ200_I_MAX];
|
||||
};
|
||||
|
||||
int mq200_probe __P((bus_space_tag_t, bus_space_handle_t));
|
||||
|
|
Loading…
Reference in New Issue