Home | History | Annotate | Line # | Download | only in pci
machfb.c revision 1.14.2.5
      1  1.14.2.5     skrll /*	$NetBSD: machfb.c,v 1.14.2.5 2005/01/17 19:31:25 skrll Exp $	*/
      2       1.1  junyoung 
      3       1.1  junyoung /*
      4       1.1  junyoung  * Copyright (c) 2002 Bang Jun-Young
      5       1.1  junyoung  * All rights reserved.
      6       1.1  junyoung  *
      7       1.1  junyoung  * Redistribution and use in source and binary forms, with or without
      8       1.1  junyoung  * modification, are permitted provided that the following conditions
      9       1.1  junyoung  * are met:
     10       1.1  junyoung  * 1. Redistributions of source code must retain the above copyright
     11       1.1  junyoung  *    notice, this list of conditions and the following disclaimer.
     12       1.1  junyoung  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  junyoung  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  junyoung  *    documentation and/or other materials provided with the distribution.
     15       1.1  junyoung  * 3. The name of the author may not be used to endorse or promote products
     16      1.10  junyoung  *    derived from this software without specific prior written permission.
     17       1.1  junyoung  *
     18       1.1  junyoung  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19       1.1  junyoung  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20       1.1  junyoung  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21       1.1  junyoung  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22       1.1  junyoung  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23       1.1  junyoung  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24       1.1  junyoung  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25       1.1  junyoung  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26       1.1  junyoung  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27       1.1  junyoung  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28       1.1  junyoung  */
     29       1.1  junyoung 
     30       1.1  junyoung /*
     31       1.1  junyoung  * Some code is derived from ATI Rage Pro and Derivatives Programmer's Guide.
     32       1.1  junyoung  */
     33       1.1  junyoung 
     34       1.1  junyoung #include <sys/cdefs.h>
     35  1.14.2.5     skrll __KERNEL_RCSID(0, "$NetBSD: machfb.c,v 1.14.2.5 2005/01/17 19:31:25 skrll Exp $");
     36       1.1  junyoung 
     37       1.1  junyoung #include <sys/param.h>
     38       1.1  junyoung #include <sys/systm.h>
     39       1.1  junyoung #include <sys/kernel.h>
     40       1.1  junyoung #include <sys/device.h>
     41       1.1  junyoung #include <sys/malloc.h>
     42       1.1  junyoung #include <sys/callout.h>
     43       1.1  junyoung 
     44       1.3    martin #ifdef __sparc__
     45  1.14.2.2     skrll #include <machine/promlib.h>
     46       1.3    martin #endif
     47       1.3    martin 
     48       1.1  junyoung #include <dev/ic/videomode.h>
     49       1.1  junyoung 
     50       1.1  junyoung #include <dev/pci/pcivar.h>
     51       1.1  junyoung #include <dev/pci/pcireg.h>
     52       1.1  junyoung #include <dev/pci/pcidevs.h>
     53       1.1  junyoung #include <dev/pci/pciio.h>
     54       1.1  junyoung #include <dev/pci/machfbreg.h>
     55       1.1  junyoung 
     56       1.1  junyoung #include <dev/wscons/wsdisplayvar.h>
     57       1.1  junyoung #include <dev/wscons/wsconsio.h>
     58       1.1  junyoung #include <dev/wsfont/wsfont.h>
     59       1.1  junyoung #include <dev/rasops/rasops.h>
     60       1.1  junyoung 
     61  1.14.2.5     skrll #include "opt_wsemul.h"
     62  1.14.2.5     skrll 
     63       1.1  junyoung #define MACH64_REG_SIZE		1024
     64       1.3    martin #define MACH64_REG_OFF		0x7ffc00
     65       1.1  junyoung 
     66       1.1  junyoung #define	NBARS		3	/* number of Mach64 PCI BARs */
     67       1.1  junyoung 
     68       1.1  junyoung struct vga_bar {
     69       1.1  junyoung 	bus_addr_t vb_base;
     70       1.1  junyoung 	bus_size_t vb_size;
     71       1.1  junyoung 	pcireg_t vb_type;
     72       1.1  junyoung 	int vb_flags;
     73       1.1  junyoung };
     74       1.1  junyoung 
     75       1.1  junyoung struct mach64_softc {
     76       1.1  junyoung 	struct device sc_dev;
     77       1.1  junyoung 	pci_chipset_tag_t sc_pc;
     78       1.1  junyoung 	pcitag_t sc_pcitag;
     79       1.1  junyoung 
     80       1.1  junyoung 	struct vga_bar sc_bars[NBARS];
     81       1.1  junyoung 	struct vga_bar sc_rom;
     82       1.1  junyoung 
     83       1.1  junyoung #define sc_aperbase 	sc_bars[0].vb_base
     84       1.1  junyoung #define sc_apersize	sc_bars[0].vb_size
     85       1.1  junyoung 
     86       1.1  junyoung #define sc_iobase	sc_bars[1].vb_base
     87       1.1  junyoung #define sc_iosize	sc_bars[1].vb_size
     88       1.1  junyoung 
     89       1.1  junyoung #define sc_regbase	sc_bars[2].vb_base
     90       1.1  junyoung #define sc_regsize	sc_bars[2].vb_size
     91       1.1  junyoung 
     92       1.4  junyoung 	bus_space_tag_t sc_regt;
     93       1.3    martin 	bus_space_tag_t sc_memt;
     94       1.4  junyoung 	bus_space_handle_t sc_regh;
     95       1.1  junyoung 	bus_space_handle_t sc_memh;
     96       1.1  junyoung 
     97       1.1  junyoung 	size_t memsize;
     98       1.1  junyoung 	int memtype;
     99       1.1  junyoung 
    100       1.1  junyoung 	int has_dsp;
    101       1.1  junyoung 	int bits_per_pixel;
    102       1.1  junyoung 	int max_x, max_y;
    103       1.1  junyoung 	int virt_x, virt_y;
    104       1.1  junyoung 	int color_depth;
    105       1.1  junyoung 
    106       1.1  junyoung 	int mem_freq;
    107       1.1  junyoung 	int ramdac_freq;
    108       1.1  junyoung 	int ref_freq;
    109       1.1  junyoung 
    110       1.1  junyoung 	int ref_div;
    111       1.1  junyoung 	int log2_vclk_post_div;
    112       1.1  junyoung 	int vclk_post_div;
    113       1.1  junyoung 	int vclk_fb_div;
    114       1.1  junyoung 	int mclk_post_div;
    115       1.1  junyoung 	int mclk_fb_div;
    116       1.1  junyoung 
    117       1.1  junyoung 	struct mach64screen *wanted;
    118       1.1  junyoung 	struct mach64screen *active;
    119       1.1  junyoung 	void (*switchcb)(void *, int, int);
    120       1.1  junyoung 	void *switchcbarg;
    121       1.1  junyoung 	struct callout switch_callout;
    122       1.1  junyoung 	LIST_HEAD(, mach64screen) screens;
    123       1.1  junyoung 	const struct wsscreen_descr *currenttype;
    124  1.14.2.5     skrll 	u_char sc_cmap_red[256];
    125  1.14.2.5     skrll 	u_char sc_cmap_green[256];
    126  1.14.2.5     skrll 	u_char sc_cmap_blue[256];
    127  1.14.2.5     skrll 	int sc_dacw;
    128       1.1  junyoung };
    129       1.1  junyoung 
    130       1.1  junyoung struct mach64screen {
    131       1.7    martin 	struct rasops_info ri;
    132       1.1  junyoung 	LIST_ENTRY(mach64screen) next;
    133       1.1  junyoung 	struct mach64_softc *sc;
    134       1.1  junyoung 	const struct wsscreen_descr *type;
    135       1.1  junyoung 	int active;
    136       1.1  junyoung 	u_int16_t *mem;
    137       1.1  junyoung 	int dispoffset;
    138       1.1  junyoung 	int mindispoffset;
    139       1.1  junyoung 	int maxdispoffset;
    140       1.1  junyoung 
    141       1.1  junyoung 	int cursoron;
    142       1.1  junyoung 	int cursorcol;
    143       1.1  junyoung 	int cursorrow;
    144       1.1  junyoung 	u_int16_t cursortmp;
    145       1.1  junyoung };
    146       1.1  junyoung 
    147       1.1  junyoung struct mach64_crtcregs {
    148       1.1  junyoung 	u_int32_t h_total_disp;
    149       1.1  junyoung 	u_int32_t h_sync_strt_wid;
    150       1.1  junyoung 	u_int32_t v_total_disp;
    151       1.1  junyoung 	u_int32_t v_sync_strt_wid;
    152       1.1  junyoung 	u_int32_t gen_cntl;
    153       1.1  junyoung 	u_int32_t clock_cntl;
    154       1.1  junyoung 	u_int32_t color_depth;
    155       1.1  junyoung 	u_int32_t dot_clock;
    156       1.1  junyoung };
    157       1.1  junyoung 
    158       1.1  junyoung struct {
    159       1.1  junyoung 	u_int16_t chip_id;
    160       1.1  junyoung 	u_int32_t ramdac_freq;
    161       1.1  junyoung } mach64_info[] = {
    162       1.1  junyoung 	{ PCI_PRODUCT_ATI_MACH64_CT, 135000 },
    163       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_PRO_AGP, 230000 },
    164       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_PRO_AGP1X, 230000 },
    165       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_B, 230000 },
    166       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_XL_AGP, 230000 },
    167       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_P, 230000 },
    168       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_L, 230000 },
    169       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_XL_PCI, 230000 },
    170       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_II, 135000 },
    171       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_IIP, 200000 },
    172       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_IIC_PCI, 230000 },
    173       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_IIC_AGP_B, 230000 },
    174       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_IIC_AGP_P, 230000 },
    175       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 },
    176       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_MOB_M3_PCI, 230000 },
    177       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP, 230000 },
    178       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_LT, 230000 },
    179       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
    180       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_MOBILITY, 230000 },
    181       1.1  junyoung 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
    182       1.1  junyoung 	{ PCI_PRODUCT_ATI_MACH64_VT, 170000 },
    183       1.1  junyoung 	{ PCI_PRODUCT_ATI_MACH64_VTB, 200000 },
    184       1.1  junyoung 	{ PCI_PRODUCT_ATI_MACH64_VT4, 230000 }
    185       1.1  junyoung };
    186       1.1  junyoung 
    187       1.1  junyoung static int mach64_chip_id, mach64_chip_rev;
    188       1.1  junyoung static struct videomode default_mode;
    189       1.1  junyoung static struct mach64screen mach64_console_screen;
    190       1.1  junyoung 
    191       1.1  junyoung static char *mach64_memtype_names[] = {
    192       1.1  junyoung 	"(N/A)", "DRAM", "EDO DRAM", "EDO DRAM", "SDRAM", "SGRAM", "WRAM",
    193       1.1  junyoung 	"(unknown type)"
    194       1.1  junyoung };
    195       1.1  junyoung 
    196       1.1  junyoung struct videomode mach64_modes[] = {
    197       1.1  junyoung 	/* 640x400 @ 70 Hz, 31.5 kHz */
    198       1.1  junyoung 	{ 25175, 640, 664, 760, 800, 400, 409, 411, 450, 0 },
    199       1.1  junyoung 	/* 640x480 @ 72 Hz, 36.5 kHz */
    200       1.1  junyoung 	{ 25175, 640, 664, 760, 800, 480, 491, 493, 525, 0 },
    201       1.1  junyoung 	/* 800x600 @ 72 Hz, 48.0 kHz */
    202       1.1  junyoung 	{ 50000, 800, 856, 976, 1040, 600, 637, 643, 666,
    203       1.1  junyoung 	  VID_PHSYNC | VID_PVSYNC },
    204       1.1  junyoung 	/* 1024x768 @ 70 Hz, 56.5 kHz */
    205       1.1  junyoung 	{ 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806,
    206       1.1  junyoung 	  VID_NHSYNC | VID_NVSYNC },
    207       1.1  junyoung 	/* 1152x864 @ 70 Hz, 62.4 kHz */
    208       1.1  junyoung 	{ 92000, 1152, 1208, 1368, 1474, 864, 865, 875, 895, 0 },
    209       1.1  junyoung 	/* 1280x1024 @ 70 Hz, 74.59 kHz */
    210       1.1  junyoung 	{ 126500, 1280, 1312, 1472, 1696, 1024, 1032, 1040, 1068,
    211       1.1  junyoung 	  VID_NHSYNC | VID_NVSYNC }
    212       1.1  junyoung };
    213       1.1  junyoung 
    214  1.14.2.5     skrll /* Macallan: let the terminal emulator program the palette, it should be in the softc anyway */
    215  1.14.2.5     skrll #if 1
    216       1.1  junyoung /* FIXME values are wrong! */
    217       1.1  junyoung const u_char mach64_cmap[16 * 3] = {
    218       1.1  junyoung 	0x00, 0x00, 0x00, /* black */
    219       1.1  junyoung 	0x7f, 0x00, 0x00, /* red */
    220       1.1  junyoung 	0x00, 0x7f, 0x00, /* green */
    221       1.1  junyoung 	0x7f, 0x7f, 0x00, /* brown */
    222       1.1  junyoung 	0x00, 0x00, 0x7f, /* blue */
    223       1.1  junyoung 	0x7f, 0x00, 0x7f, /* magenta */
    224       1.1  junyoung 	0x00, 0x7f, 0x7f, /* cyan */
    225  1.14.2.5     skrll 	0xc8, 0xc8, 0xc8, /* white */
    226       1.1  junyoung 
    227       1.1  junyoung 	0x7f, 0x7f, 0x7f, /* black */
    228       1.1  junyoung 	0xff, 0x00, 0x00, /* red */
    229       1.1  junyoung 	0x00, 0xff, 0x00, /* green */
    230       1.1  junyoung 	0xff, 0xff, 0x00, /* brown */
    231       1.1  junyoung 	0x00, 0x00, 0xff, /* blue */
    232       1.1  junyoung 	0xff, 0x00, 0xff, /* magenta */
    233       1.1  junyoung 	0x00, 0xff, 0xff, /* cyan */
    234       1.1  junyoung 	0xff, 0xff, 0xff, /* white */
    235       1.1  junyoung };
    236  1.14.2.5     skrll #endif
    237  1.14.2.5     skrll 
    238  1.14.2.5     skrll #ifdef WSEMUL_VT100
    239  1.14.2.5     skrll extern const u_char rasops_cmap[768];
    240  1.14.2.5     skrll #endif
    241       1.1  junyoung 
    242       1.1  junyoung int	mach64_match(struct device *, struct cfdata *, void *);
    243       1.1  junyoung void	mach64_attach(struct device *, struct device *, void *);
    244       1.1  junyoung 
    245       1.1  junyoung CFATTACH_DECL(machfb, sizeof(struct mach64_softc), mach64_match, mach64_attach,
    246       1.1  junyoung     NULL, NULL);
    247       1.1  junyoung 
    248       1.3    martin void	mach64_init(struct mach64_softc *);
    249       1.1  junyoung int	mach64_get_memsize(struct mach64_softc *);
    250       1.1  junyoung int	mach64_get_max_ramdac(struct mach64_softc *);
    251       1.1  junyoung void	mach64_get_mode(struct mach64_softc *, struct videomode *);
    252       1.1  junyoung int	mach64_calc_crtcregs(struct mach64_softc *, struct mach64_crtcregs *,
    253       1.1  junyoung 	    struct videomode *);
    254       1.1  junyoung void	mach64_set_crtcregs(struct mach64_softc *, struct mach64_crtcregs *);
    255       1.1  junyoung int	mach64_modeswitch(struct mach64_softc *, struct videomode *);
    256       1.1  junyoung void	mach64_set_dsp(struct mach64_softc *);
    257       1.1  junyoung void	mach64_set_pll(struct mach64_softc *, int);
    258       1.1  junyoung void	mach64_reset_engine(struct mach64_softc *);
    259       1.1  junyoung void	mach64_init_engine(struct mach64_softc *);
    260       1.1  junyoung void	mach64_adjust_frame(struct mach64_softc *, int, int);
    261       1.1  junyoung void	mach64_init_lut(struct mach64_softc *);
    262       1.1  junyoung void	mach64_switch_screen(struct mach64_softc *);
    263       1.1  junyoung void	mach64_init_screen(struct mach64_softc *, struct mach64screen *,
    264       1.6  junyoung 	    const struct wsscreen_descr *, int, long *, int);
    265       1.1  junyoung void	mach64_restore_screen(struct mach64screen *,
    266       1.1  junyoung 	    const struct wsscreen_descr *, u_int16_t *);
    267       1.6  junyoung int 	mach64_set_screentype(struct mach64_softc *,
    268       1.1  junyoung 	    const struct wsscreen_descr *);
    269       1.5  junyoung int	mach64_is_console(struct pci_attach_args *);
    270       1.1  junyoung 
    271       1.1  junyoung void	mach64_cursor(void *, int, int, int);
    272       1.1  junyoung int	mach64_mapchar(void *, int, u_int *);
    273       1.1  junyoung void	mach64_putchar(void *, int, int, u_int, long);
    274       1.1  junyoung void	mach64_copycols(void *, int, int, int, int);
    275       1.1  junyoung void	mach64_erasecols(void *, int, int, int, long);
    276       1.1  junyoung void	mach64_copyrows(void *, int, int, int);
    277       1.1  junyoung void	mach64_eraserows(void *, int, int, long);
    278       1.1  junyoung int	mach64_allocattr(void *, int, int, int, long *);
    279       1.1  junyoung 
    280  1.14.2.5     skrll void	mach64_scroll(void *, void *, int);
    281  1.14.2.5     skrll 
    282  1.14.2.5     skrll int mach64_putcmap(struct mach64_softc *, struct wsdisplay_cmap *);
    283  1.14.2.5     skrll int mach64_getcmap(struct mach64_softc *, struct wsdisplay_cmap *);
    284  1.14.2.5     skrll int mach64_putpalreg(struct mach64_softc *, uint8_t, uint8_t, uint8_t, uint8_t);
    285  1.14.2.5     skrll void mach64_bitblt(struct mach64_softc *, int, int, int, int, int, int, int, int) ;
    286  1.14.2.5     skrll void mach64_rectfill(struct mach64_softc *, int, int, int, int, int);
    287  1.14.2.5     skrll void mach64_showpal(struct mach64_softc *);
    288  1.14.2.5     skrll 
    289       1.7    martin #if 0
    290       1.1  junyoung const struct wsdisplay_emulops mach64_emulops = {
    291       1.1  junyoung 	mach64_cursor,
    292       1.1  junyoung 	mach64_mapchar,
    293       1.1  junyoung 	mach64_putchar,
    294       1.1  junyoung 	mach64_copycols,
    295       1.1  junyoung 	mach64_erasecols,
    296       1.1  junyoung 	mach64_copyrows,
    297       1.1  junyoung 	mach64_eraserows,
    298       1.1  junyoung 	mach64_allocattr,
    299       1.1  junyoung };
    300       1.7    martin #endif
    301       1.1  junyoung 
    302       1.1  junyoung struct wsscreen_descr mach64_defaultscreen = {
    303       1.1  junyoung 	"default",
    304       1.1  junyoung 	0, 0,
    305       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    306       1.1  junyoung 	8, 16,
    307       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    308       1.1  junyoung 	&default_mode
    309       1.1  junyoung }, mach64_80x25_screen = {
    310       1.1  junyoung 	"80x25", 80, 25,
    311       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    312       1.1  junyoung 	8, 16,
    313       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    314       1.1  junyoung 	&mach64_modes[0]
    315       1.1  junyoung }, mach64_80x30_screen = {
    316       1.1  junyoung 	"80x30", 80, 30,
    317       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    318       1.1  junyoung 	8, 16,
    319       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    320       1.1  junyoung 	&mach64_modes[1]
    321       1.1  junyoung }, mach64_80x40_screen = {
    322       1.1  junyoung 	"80x40", 80, 40,
    323       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    324       1.1  junyoung 	8, 10,
    325       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    326       1.1  junyoung 	&mach64_modes[0]
    327       1.1  junyoung }, mach64_80x50_screen = {
    328       1.1  junyoung 	"80x50", 80, 50,
    329       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    330       1.1  junyoung 	8, 8,
    331       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    332       1.1  junyoung 	&mach64_modes[0]
    333       1.1  junyoung }, mach64_100x37_screen = {
    334       1.1  junyoung 	"100x37", 100, 37,
    335       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    336       1.1  junyoung 	8, 16,
    337       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    338       1.1  junyoung 	&mach64_modes[2]
    339       1.1  junyoung }, mach64_128x48_screen = {
    340       1.1  junyoung 	"128x48", 128, 48,
    341       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    342       1.1  junyoung 	8, 16,
    343       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    344       1.1  junyoung 	&mach64_modes[3]
    345       1.1  junyoung }, mach64_144x54_screen = {
    346       1.1  junyoung 	"144x54", 144, 54,
    347       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    348       1.1  junyoung 	8, 16,
    349       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    350       1.1  junyoung 	&mach64_modes[4]
    351       1.1  junyoung }, mach64_160x64_screen = {
    352       1.1  junyoung 	"160x54", 160, 64,
    353       1.7    martin 	&mach64_console_screen.ri.ri_ops,
    354       1.1  junyoung 	8, 16,
    355       1.1  junyoung 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    356       1.1  junyoung 	&mach64_modes[5]
    357       1.1  junyoung };
    358       1.1  junyoung 
    359       1.1  junyoung const struct wsscreen_descr *_mach64_scrlist[] = {
    360       1.1  junyoung 	&mach64_defaultscreen,
    361       1.1  junyoung 	&mach64_80x25_screen,
    362       1.1  junyoung 	&mach64_80x30_screen,
    363       1.1  junyoung 	&mach64_80x40_screen,
    364       1.1  junyoung 	&mach64_80x50_screen,
    365       1.1  junyoung 	&mach64_100x37_screen,
    366       1.1  junyoung 	&mach64_128x48_screen,
    367       1.1  junyoung 	&mach64_144x54_screen,
    368       1.1  junyoung 	&mach64_160x64_screen
    369       1.1  junyoung };
    370       1.1  junyoung 
    371       1.1  junyoung struct wsscreen_list mach64_screenlist = {
    372       1.1  junyoung 	sizeof(_mach64_scrlist) / sizeof(struct wsscreen_descr *),
    373       1.1  junyoung 	_mach64_scrlist
    374       1.1  junyoung };
    375       1.1  junyoung 
    376  1.14.2.4     skrll int	mach64_ioctl(void *, u_long, caddr_t, int, struct lwp *);
    377       1.1  junyoung paddr_t	mach64_mmap(void *, off_t, int);
    378       1.1  junyoung int	mach64_alloc_screen(void *, const struct wsscreen_descr *, void **,
    379       1.1  junyoung 	    int *, int *, long *);
    380       1.1  junyoung void	mach64_free_screen(void *, void *);
    381       1.1  junyoung int	mach64_show_screen(void *, void *, int, void (*)(void *, int, int),
    382       1.1  junyoung 	    void *);
    383       1.1  junyoung int	mach64_load_font(void *, void *, struct wsdisplay_font *);
    384       1.1  junyoung 
    385       1.1  junyoung struct wsdisplay_accessops mach64_accessops = {
    386       1.1  junyoung 	mach64_ioctl,
    387       1.1  junyoung 	mach64_mmap,
    388       1.1  junyoung 	mach64_alloc_screen,
    389       1.1  junyoung 	mach64_free_screen,
    390       1.1  junyoung 	mach64_show_screen,
    391  1.14.2.5     skrll 	NULL,	/* load_font */
    392  1.14.2.5     skrll 	NULL,	/* polls */
    393  1.14.2.5     skrll 	NULL,	/* getwschar */
    394  1.14.2.5     skrll 	NULL,	/* putwschar */
    395  1.14.2.5     skrll 	NULL,	/* scroll */
    396  1.14.2.5     skrll 	NULL,	/* getborder */
    397  1.14.2.5     skrll 	NULL	/* setborder */
    398       1.1  junyoung };
    399       1.1  junyoung 
    400       1.1  junyoung /*
    401       1.1  junyoung  * Inline functions for getting access to register aperture.
    402       1.1  junyoung  */
    403       1.1  junyoung static inline u_int32_t regr(struct mach64_softc *, u_int32_t);
    404       1.1  junyoung static inline u_int8_t regrb(struct mach64_softc *, u_int32_t);
    405       1.1  junyoung static inline void regw(struct mach64_softc *, u_int32_t, u_int32_t);
    406       1.1  junyoung static inline void regwb(struct mach64_softc *, u_int32_t, u_int8_t);
    407       1.1  junyoung static inline void regwb_pll(struct mach64_softc *, u_int32_t, u_int8_t);
    408       1.1  junyoung 
    409       1.1  junyoung static inline u_int32_t
    410       1.1  junyoung regr(struct mach64_softc *sc, u_int32_t index)
    411       1.1  junyoung {
    412       1.1  junyoung 
    413       1.4  junyoung 	return bus_space_read_4(sc->sc_regt, sc->sc_regh, index);
    414       1.1  junyoung }
    415       1.1  junyoung 
    416       1.1  junyoung static inline u_int8_t
    417       1.1  junyoung regrb(struct mach64_softc *sc, u_int32_t index)
    418       1.1  junyoung {
    419       1.1  junyoung 
    420       1.4  junyoung 	return bus_space_read_1(sc->sc_regt, sc->sc_regh, index);
    421       1.1  junyoung }
    422       1.1  junyoung 
    423       1.1  junyoung static inline void
    424       1.1  junyoung regw(struct mach64_softc *sc, u_int32_t index, u_int32_t data)
    425       1.1  junyoung {
    426       1.1  junyoung 
    427       1.4  junyoung 	bus_space_write_4(sc->sc_regt, sc->sc_regh, index, data);
    428  1.14.2.5     skrll 	bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 4, BUS_SPACE_BARRIER_WRITE);
    429       1.1  junyoung }
    430       1.1  junyoung 
    431       1.1  junyoung static inline void
    432       1.1  junyoung regwb(struct mach64_softc *sc, u_int32_t index, u_int8_t data)
    433       1.1  junyoung {
    434       1.1  junyoung 
    435       1.4  junyoung 	bus_space_write_1(sc->sc_regt, sc->sc_regh, index, data);
    436  1.14.2.5     skrll 	bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 1, BUS_SPACE_BARRIER_WRITE);
    437       1.1  junyoung }
    438       1.1  junyoung 
    439       1.1  junyoung static inline void
    440       1.1  junyoung regwb_pll(struct mach64_softc *sc, u_int32_t index, u_int8_t data)
    441       1.1  junyoung {
    442       1.1  junyoung 
    443       1.1  junyoung 	regwb(sc, CLOCK_CNTL + 1, (index << 2) | PLL_WR_EN);
    444       1.1  junyoung 	regwb(sc, CLOCK_CNTL + 2, data);
    445       1.1  junyoung 	regwb(sc, CLOCK_CNTL + 1, (index << 2) & ~PLL_WR_EN);
    446       1.1  junyoung }
    447       1.1  junyoung 
    448       1.1  junyoung static inline void
    449       1.1  junyoung wait_for_fifo(struct mach64_softc *sc, u_int8_t v)
    450       1.1  junyoung {
    451       1.1  junyoung 
    452       1.1  junyoung 	while ((regr(sc, FIFO_STAT) & 0xffff) > (0x8000 >> v))
    453       1.1  junyoung 		;
    454       1.1  junyoung }
    455       1.1  junyoung 
    456       1.1  junyoung static inline void
    457       1.1  junyoung wait_for_idle(struct mach64_softc *sc)
    458       1.1  junyoung {
    459       1.1  junyoung 
    460       1.1  junyoung 	wait_for_fifo(sc, 16);
    461       1.1  junyoung 	while ((regr(sc, GUI_STAT) & 1) != 0)
    462       1.1  junyoung 		;
    463       1.1  junyoung }
    464       1.1  junyoung 
    465       1.1  junyoung int
    466       1.1  junyoung mach64_match(struct device *parent, struct cfdata *match, void *aux)
    467       1.1  junyoung {
    468       1.1  junyoung 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
    469       1.1  junyoung 	int i;
    470       1.1  junyoung 
    471       1.1  junyoung 	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
    472       1.1  junyoung 	    PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
    473       1.1  junyoung 		return 0;
    474       1.1  junyoung 
    475       1.1  junyoung 	for (i = 0; i < sizeof(mach64_info) / sizeof(mach64_info[0]); i++)
    476       1.1  junyoung 		if (PCI_PRODUCT(pa->pa_id) == mach64_info[i].chip_id) {
    477       1.1  junyoung 			mach64_chip_id = PCI_PRODUCT(pa->pa_id);
    478       1.1  junyoung 			mach64_chip_rev = PCI_REVISION(pa->pa_class);
    479       1.1  junyoung 			return 1;
    480       1.1  junyoung 		}
    481       1.1  junyoung 
    482       1.1  junyoung 	return 0;
    483       1.1  junyoung }
    484       1.1  junyoung 
    485       1.1  junyoung void
    486       1.1  junyoung mach64_attach(struct device *parent, struct device *self, void *aux)
    487       1.1  junyoung {
    488       1.1  junyoung 	struct mach64_softc *sc = (void *)self;
    489       1.1  junyoung 	struct pci_attach_args *pa = aux;
    490       1.1  junyoung 	char devinfo[256];
    491       1.1  junyoung 	int bar, reg, id;
    492       1.1  junyoung 	struct wsemuldisplaydev_attach_args aa;
    493       1.1  junyoung 	long defattr;
    494       1.7    martin 	int setmode, console;
    495       1.1  junyoung 
    496       1.1  junyoung 	sc->sc_pc = pa->pa_pc;
    497       1.1  junyoung 	sc->sc_pcitag = pa->pa_tag;
    498  1.14.2.5     skrll 	sc->sc_dacw=-1;
    499  1.14.2.2     skrll 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
    500       1.1  junyoung 	printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
    501       1.1  junyoung 
    502       1.1  junyoung 	for (bar = 0; bar < NBARS; bar++) {
    503       1.1  junyoung 		reg = PCI_MAPREG_START + (bar * 4);
    504       1.1  junyoung 		sc->sc_bars[bar].vb_type = pci_mapreg_type(sc->sc_pc,
    505       1.1  junyoung 		    sc->sc_pcitag, reg);
    506       1.1  junyoung 		(void)pci_mapreg_info(sc->sc_pc, sc->sc_pcitag, reg,
    507       1.1  junyoung 		    sc->sc_bars[bar].vb_type, &sc->sc_bars[bar].vb_base,
    508       1.1  junyoung 		    &sc->sc_bars[bar].vb_size, &sc->sc_bars[bar].vb_flags);
    509       1.1  junyoung 	}
    510       1.3    martin 	sc->sc_memt = pa->pa_memt;
    511       1.1  junyoung 
    512       1.3    martin 	mach64_init(sc);
    513       1.1  junyoung 
    514       1.1  junyoung 	printf("%s: %d MB aperture at 0x%08x, %d KB registers at 0x%08x\n",
    515       1.4  junyoung 	    sc->sc_dev.dv_xname, (u_int)(sc->sc_apersize / (1024 * 1024)),
    516       1.4  junyoung 	    (u_int)sc->sc_aperbase, (u_int)(sc->sc_regsize / 1024),
    517       1.4  junyoung 	    (u_int)sc->sc_regbase);
    518       1.1  junyoung 
    519       1.1  junyoung 	if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_CT ||
    520       1.1  junyoung 	    ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
    521       1.1  junyoung 	      mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
    522       1.1  junyoung 	      (mach64_chip_rev & 0x07) == 0))
    523       1.1  junyoung 		sc->has_dsp = 0;
    524       1.1  junyoung 	else
    525       1.1  junyoung 		sc->has_dsp = 1;
    526       1.1  junyoung 
    527       1.1  junyoung 	sc->memsize = mach64_get_memsize(sc);
    528       1.1  junyoung 	if (sc->memsize == 8192)
    529       1.1  junyoung 		/* The last page is used as register aperture. */
    530       1.1  junyoung 		sc->memsize -= 4;
    531       1.1  junyoung 	sc->memtype = regr(sc, CONFIG_STAT0) & 0x07;
    532       1.1  junyoung 
    533       1.1  junyoung 	/* XXX is there any way to calculate reference frequency from
    534       1.1  junyoung 	   known values? */
    535       1.1  junyoung 	if (mach64_chip_id == PCI_PRODUCT_ATI_RAGE_XL_PCI)
    536       1.1  junyoung 		sc->ref_freq = 29498;
    537       1.1  junyoung 	else
    538       1.1  junyoung 		sc->ref_freq = 14318;
    539       1.1  junyoung 
    540       1.1  junyoung 	regwb(sc, CLOCK_CNTL + 1, PLL_REF_DIV << 2);
    541       1.1  junyoung 	sc->ref_div = regrb(sc, CLOCK_CNTL + 2);
    542       1.1  junyoung 	regwb(sc, CLOCK_CNTL + 1, MCLK_FB_DIV << 2);
    543       1.1  junyoung 	sc->mclk_fb_div = regrb(sc, CLOCK_CNTL + 2);
    544       1.1  junyoung 	sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) /
    545       1.1  junyoung 	    (sc->ref_div * 2);
    546       1.1  junyoung 	sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) /
    547       1.1  junyoung 	    (sc->mem_freq * sc->ref_div);
    548       1.1  junyoung 	sc->ramdac_freq = mach64_get_max_ramdac(sc);
    549       1.2    martin 	printf("%s: %ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n",
    550       1.4  junyoung 	    sc->sc_dev.dv_xname, (u_long)sc->memsize,
    551       1.1  junyoung 	    mach64_memtype_names[sc->memtype],
    552       1.1  junyoung 	    sc->mem_freq / 1000, sc->mem_freq % 1000,
    553       1.1  junyoung 	    sc->ramdac_freq / 1000);
    554       1.1  junyoung 
    555       1.1  junyoung 	id = regr(sc, CONFIG_CHIP_ID) & 0xffff;
    556       1.1  junyoung 	if (id != mach64_chip_id) {
    557       1.1  junyoung 		printf("%s: chip ID mismatch, 0x%x != 0x%x\n",
    558       1.1  junyoung 		    sc->sc_dev.dv_xname, id, mach64_chip_id);
    559       1.1  junyoung 		return;
    560       1.1  junyoung 	}
    561       1.1  junyoung 
    562       1.7    martin 	console = mach64_is_console(pa);
    563       1.7    martin 
    564       1.1  junyoung #ifdef __sparc__
    565       1.7    martin 	if (console) {
    566       1.7    martin 		mach64_get_mode(sc, &default_mode);
    567       1.7    martin 		setmode = 0;
    568       1.7    martin 	} else {
    569       1.8    martin 		memcpy(&default_mode, &mach64_modes[4], sizeof(struct videomode));
    570       1.7    martin 		setmode = 1;
    571       1.7    martin 	}
    572       1.1  junyoung #else
    573       1.6  junyoung 	memcpy(&default_mode, &mach64_modes[0], sizeof(struct videomode));
    574       1.6  junyoung 	setmode = 1;
    575       1.1  junyoung #endif
    576       1.1  junyoung 
    577       1.1  junyoung 	sc->bits_per_pixel = 8;
    578       1.1  junyoung 	sc->virt_x = default_mode.hdisplay;
    579       1.1  junyoung 	sc->virt_y = default_mode.vdisplay;
    580       1.1  junyoung 	sc->max_x = sc->virt_x - 1;
    581       1.1  junyoung 	sc->max_y = (sc->memsize * 1024) /
    582       1.1  junyoung 	    (sc->virt_x * (sc->bits_per_pixel / 8)) - 1;
    583       1.1  junyoung 
    584       1.1  junyoung 	sc->color_depth = CRTC_PIX_WIDTH_8BPP;
    585       1.1  junyoung 
    586       1.1  junyoung 	mach64_init_engine(sc);
    587       1.1  junyoung #if 0
    588       1.1  junyoung 	mach64_adjust_frame(0, 0);
    589       1.1  junyoung 	if (sc->bits_per_pixel == 8)
    590       1.1  junyoung 		mach64_init_lut(sc);
    591       1.1  junyoung #endif
    592       1.1  junyoung 
    593       1.1  junyoung 	printf("%s: initial resolution %dx%d at %d bpp\n", sc->sc_dev.dv_xname,
    594       1.1  junyoung 	    default_mode.hdisplay, default_mode.vdisplay,
    595       1.1  junyoung 	    sc->bits_per_pixel);
    596       1.1  junyoung 
    597       1.7    martin 	mach64_console_screen.ri.ri_hw = sc;
    598       1.7    martin 	mach64_console_screen.ri.ri_depth = sc->bits_per_pixel;
    599       1.8    martin 	mach64_console_screen.ri.ri_bits = (void*)(u_long)sc->sc_aperbase;
    600       1.7    martin 	mach64_console_screen.ri.ri_width = default_mode.hdisplay;
    601       1.7    martin 	mach64_console_screen.ri.ri_height = default_mode.vdisplay;
    602       1.7    martin 	mach64_console_screen.ri.ri_stride = mach64_console_screen.ri.ri_width;
    603  1.14.2.5     skrll 
    604  1.14.2.5     skrll 	mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER;
    605  1.14.2.5     skrll 
    606  1.14.2.5     skrll #ifdef WSEMUL_SUN
    607  1.14.2.5     skrll 	mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER|RI_FORCEMONO;
    608  1.14.2.5     skrll #endif
    609       1.1  junyoung 
    610       1.7    martin 	rasops_init(&mach64_console_screen.ri, mach64_console_screen.ri.ri_height / 16,
    611  1.14.2.5     skrll 	    mach64_console_screen.ri.ri_width / 8);	/* XXX width/height are nonsense */
    612  1.14.2.5     skrll 
    613  1.14.2.5     skrll 	/* enable acceleration */
    614  1.14.2.5     skrll 	mach64_console_screen.ri.ri_ops.copyrows=mach64_copyrows;
    615  1.14.2.5     skrll 	mach64_console_screen.ri.ri_ops.eraserows=mach64_eraserows;
    616  1.14.2.5     skrll 	mach64_console_screen.ri.ri_ops.copycols=mach64_copycols;
    617  1.14.2.5     skrll 	mach64_console_screen.ri.ri_ops.erasecols=mach64_erasecols;
    618       1.1  junyoung 
    619       1.7    martin 	mach64_defaultscreen.nrows = mach64_console_screen.ri.ri_rows;
    620       1.7    martin 	mach64_defaultscreen.ncols = mach64_console_screen.ri.ri_cols;
    621       1.1  junyoung 
    622       1.7    martin 	mach64_console_screen.ri.ri_ops.allocattr(&mach64_console_screen.ri, 0, 0, 0,
    623       1.1  junyoung 	    &defattr);
    624  1.14.2.5     skrll 
    625  1.14.2.5     skrll 	/* really necessary? */
    626  1.14.2.5     skrll 	mach64_defaultscreen.capabilities=mach64_console_screen.ri.ri_caps;
    627  1.14.2.5     skrll 	mach64_defaultscreen.textops=&mach64_console_screen.ri.ri_ops;
    628  1.14.2.5     skrll 
    629       1.7    martin 	/* Initialize fonts */
    630  1.14.2.5     skrll 	/* XXX Macallan: shouldn't that happen /before/ we call rasops_init()? */
    631       1.7    martin 	wsfont_init();
    632  1.14.2.5     skrll 
    633       1.7    martin 	if (console) {
    634       1.7    martin 		mach64_init_screen(sc, &mach64_console_screen,
    635       1.7    martin 		    &mach64_defaultscreen, 1, &defattr, setmode);
    636       1.7    martin 		wsdisplay_cnattach(&mach64_defaultscreen, &mach64_console_screen.ri,
    637       1.3    martin 		    0, 0, defattr);
    638       1.7    martin 	}
    639  1.14.2.5     skrll 
    640  1.14.2.5     skrll 	mach64_init_lut(sc);
    641       1.4  junyoung 
    642  1.14.2.5     skrll #ifdef DEBUG
    643  1.14.2.5     skrll 	mach64_showpal(sc);
    644  1.14.2.5     skrll 	delay(4000000);
    645  1.14.2.5     skrll #endif
    646       1.1  junyoung 	aa.console = console;
    647       1.1  junyoung 	aa.scrdata = &mach64_screenlist;
    648       1.1  junyoung 	aa.accessops = &mach64_accessops;
    649       1.1  junyoung 	aa.accesscookie = sc;
    650       1.1  junyoung 
    651       1.1  junyoung 	config_found(self, &aa, wsemuldisplaydevprint);
    652       1.1  junyoung }
    653       1.1  junyoung 
    654       1.1  junyoung void
    655       1.1  junyoung mach64_init_screen(struct mach64_softc *sc, struct mach64screen *scr,
    656       1.6  junyoung     const struct wsscreen_descr *type, int existing, long *attrp, int setmode)
    657       1.1  junyoung {
    658       1.1  junyoung 
    659       1.1  junyoung 	scr->sc = sc;
    660       1.1  junyoung 	scr->type = type;
    661       1.1  junyoung 	scr->mindispoffset = 0;
    662       1.1  junyoung 	scr->maxdispoffset = sc->memsize * 1024;
    663       1.1  junyoung 	scr->dispoffset = 0;
    664       1.1  junyoung 	scr->cursorcol = 0;
    665       1.1  junyoung 	scr->cursorrow = 0;
    666       1.1  junyoung 
    667       1.7    martin 	scr->mem = (u_int16_t *)malloc(type->nrows * type->ncols * 2,
    668       1.7    martin 	    M_DEVBUF, M_WAITOK);
    669       1.1  junyoung 	if (existing) {
    670       1.1  junyoung 		scr->active = 1;
    671       1.1  junyoung 
    672       1.6  junyoung 		if (setmode && mach64_set_screentype(sc, type)) {
    673       1.1  junyoung 			panic("%s: failed to switch video mode",
    674       1.1  junyoung 			    sc->sc_dev.dv_xname);
    675       1.1  junyoung 		}
    676       1.1  junyoung 	} else {
    677       1.1  junyoung 		scr->active = 0;
    678       1.1  junyoung 	}
    679       1.1  junyoung 
    680       1.1  junyoung 	LIST_INSERT_HEAD(&sc->screens, scr, next);
    681       1.1  junyoung }
    682       1.1  junyoung 
    683       1.1  junyoung void
    684       1.3    martin mach64_init(struct mach64_softc *sc)
    685       1.1  junyoung {
    686       1.9    martin 	u_int32_t *p32, saved_value;
    687       1.9    martin 	u_int8_t *p;
    688       1.9    martin 	int need_swap;
    689       1.4  junyoung 
    690       1.3    martin 	if (bus_space_map(sc->sc_memt, sc->sc_aperbase, sc->sc_apersize,
    691       1.1  junyoung 		BUS_SPACE_MAP_LINEAR, &sc->sc_memh)) {
    692       1.1  junyoung 		panic("%s: failed to map aperture", sc->sc_dev.dv_xname);
    693       1.1  junyoung 	}
    694       1.4  junyoung 	sc->sc_aperbase = (vaddr_t)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
    695       1.4  junyoung 
    696       1.4  junyoung 	sc->sc_regt = sc->sc_memt;
    697       1.4  junyoung 	bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
    698       1.4  junyoung 	    sc->sc_regsize, &sc->sc_regh);
    699       1.4  junyoung 	sc->sc_regbase = sc->sc_aperbase + 0x7ffc00;
    700       1.4  junyoung 
    701       1.9    martin 	/*
    702       1.9    martin 	 * Test wether the aperture is byte swapped or not
    703       1.9    martin 	 */
    704      1.12    martin 	p32 = (u_int32_t*)(u_long)sc->sc_aperbase;
    705       1.9    martin 	saved_value = *p32;
    706      1.12    martin 	p = (u_int8_t*)(u_long)sc->sc_aperbase;
    707       1.9    martin 	*p32 = 0x12345678;
    708       1.9    martin 	if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78)
    709       1.9    martin 		need_swap = 0;
    710       1.9    martin 	else
    711       1.9    martin 		need_swap = 1;
    712       1.9    martin 	if (need_swap) {
    713       1.9    martin 		sc->sc_aperbase += 0x800000;
    714       1.9    martin 		sc->sc_apersize -= 0x800000;
    715       1.9    martin 	}
    716       1.9    martin 	*p32 = saved_value;
    717       1.1  junyoung 
    718       1.1  junyoung 	LIST_INIT(&sc->screens);
    719       1.1  junyoung 	sc->active = NULL;
    720       1.1  junyoung 	sc->currenttype = &mach64_defaultscreen;
    721       1.1  junyoung 	callout_init(&sc->switch_callout);
    722       1.1  junyoung }
    723       1.1  junyoung 
    724       1.1  junyoung int
    725       1.1  junyoung mach64_get_memsize(struct mach64_softc *sc)
    726       1.1  junyoung {
    727       1.1  junyoung 	int tmp, memsize;
    728       1.1  junyoung 	int mem_tab[] = {
    729       1.1  junyoung 		512, 1024, 2048, 4096, 6144, 8192, 12288, 16384
    730       1.1  junyoung 	};
    731       1.1  junyoung 
    732       1.1  junyoung 	tmp = regr(sc, MEM_CNTL);
    733       1.1  junyoung 	if (sc->has_dsp) {
    734       1.1  junyoung 		tmp &= 0x0000000f;
    735       1.1  junyoung 		if (tmp < 8)
    736       1.1  junyoung 			memsize = (tmp + 1) * 512;
    737       1.1  junyoung 		else if (tmp < 12)
    738       1.1  junyoung 			memsize = (tmp - 3) * 1024;
    739       1.1  junyoung 		else
    740       1.1  junyoung 			memsize = (tmp - 7) * 2048;
    741       1.1  junyoung 	} else {
    742       1.1  junyoung 		memsize = mem_tab[tmp & 0x07];
    743       1.1  junyoung 	}
    744       1.1  junyoung 
    745       1.1  junyoung 	return memsize;
    746       1.1  junyoung }
    747       1.1  junyoung 
    748       1.1  junyoung int
    749       1.1  junyoung mach64_get_max_ramdac(struct mach64_softc *sc)
    750       1.1  junyoung {
    751       1.1  junyoung 	int i;
    752       1.1  junyoung 
    753       1.1  junyoung 	if ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
    754       1.1  junyoung 	     mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
    755       1.1  junyoung 	     (mach64_chip_rev & 0x07))
    756       1.1  junyoung 		return 170000;
    757       1.1  junyoung 
    758       1.1  junyoung 	for (i = 0; i < sizeof(mach64_info) / sizeof(mach64_info[0]); i++)
    759       1.1  junyoung 		if (mach64_chip_id == mach64_info[i].chip_id)
    760       1.1  junyoung 			return mach64_info[i].ramdac_freq;
    761       1.1  junyoung 
    762       1.1  junyoung 	if (sc->bits_per_pixel == 8)
    763       1.1  junyoung 		return 135000;
    764       1.1  junyoung 	else
    765       1.1  junyoung 		return 80000;
    766       1.1  junyoung }
    767       1.1  junyoung 
    768       1.1  junyoung void
    769       1.1  junyoung mach64_get_mode(struct mach64_softc *sc, struct videomode *mode)
    770       1.1  junyoung {
    771       1.1  junyoung 	struct mach64_crtcregs crtc;
    772       1.1  junyoung 
    773       1.1  junyoung 	crtc.h_total_disp = regr(sc, CRTC_H_TOTAL_DISP);
    774       1.1  junyoung 	crtc.h_sync_strt_wid = regr(sc, CRTC_H_SYNC_STRT_WID);
    775       1.1  junyoung 	crtc.v_total_disp = regr(sc, CRTC_V_TOTAL_DISP);
    776       1.1  junyoung 	crtc.v_sync_strt_wid = regr(sc, CRTC_V_SYNC_STRT_WID);
    777       1.1  junyoung 
    778       1.1  junyoung 	mode->htotal = ((crtc.h_total_disp & 0xffff) + 1) << 3;
    779       1.1  junyoung 	mode->hdisplay = ((crtc.h_total_disp >> 16) + 1) << 3;
    780       1.1  junyoung 	mode->hsync_start = ((crtc.h_sync_strt_wid & 0xffff) + 1) << 3;
    781       1.1  junyoung 	mode->hsync_end = ((crtc.h_sync_strt_wid >> 16) << 3) +
    782       1.1  junyoung 	    mode->hsync_start;
    783       1.1  junyoung 	mode->vtotal = (crtc.v_total_disp & 0xffff) + 1;
    784       1.1  junyoung 	mode->vdisplay = (crtc.v_total_disp >> 16) + 1;
    785       1.1  junyoung 	mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1;
    786       1.1  junyoung 	mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start;
    787       1.1  junyoung 
    788       1.1  junyoung #ifdef MACH64_DEBUG
    789       1.1  junyoung 	printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n",
    790       1.1  junyoung 	    mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
    791       1.1  junyoung 	    mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal);
    792       1.1  junyoung #endif
    793       1.1  junyoung }
    794       1.1  junyoung 
    795       1.1  junyoung int
    796       1.1  junyoung mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc,
    797       1.1  junyoung     struct videomode *mode)
    798       1.1  junyoung {
    799       1.1  junyoung 
    800       1.1  junyoung 	if (mode->dot_clock > sc->ramdac_freq)
    801       1.1  junyoung 		/* Clock too high. */
    802       1.1  junyoung 		return 1;
    803       1.1  junyoung 
    804       1.1  junyoung 	crtc->h_total_disp = (((mode->hdisplay >> 3) - 1) << 16) |
    805       1.1  junyoung 	    ((mode->htotal >> 3) - 1);
    806       1.1  junyoung 	crtc->h_sync_strt_wid =
    807       1.1  junyoung 	    (((mode->hsync_end - mode->hsync_start) >> 3) << 16) |
    808       1.1  junyoung 	    ((mode->hsync_start >> 3) - 1);
    809       1.1  junyoung 
    810       1.1  junyoung 	crtc->v_total_disp = ((mode->vdisplay - 1) << 16) |
    811       1.1  junyoung 	    (mode->vtotal - 1);
    812       1.1  junyoung 	crtc->v_sync_strt_wid =
    813       1.1  junyoung 	    ((mode->vsync_end - mode->vsync_start) << 16) |
    814       1.1  junyoung 	    (mode->vsync_start - 1);
    815       1.1  junyoung 
    816       1.1  junyoung 	if (mode->flags & VID_NVSYNC)
    817       1.1  junyoung 		crtc->v_sync_strt_wid |= CRTC_VSYNC_NEG;
    818       1.1  junyoung 
    819       1.1  junyoung 	switch (sc->bits_per_pixel) {
    820       1.1  junyoung 	case 8:
    821       1.1  junyoung 		crtc->color_depth = CRTC_PIX_WIDTH_8BPP;
    822       1.1  junyoung 		break;
    823       1.1  junyoung 	case 16:
    824       1.1  junyoung 		crtc->color_depth = CRTC_PIX_WIDTH_16BPP;
    825       1.1  junyoung 		break;
    826       1.1  junyoung 	case 32:
    827       1.1  junyoung 		crtc->color_depth = CRTC_PIX_WIDTH_32BPP;
    828       1.1  junyoung 		break;
    829       1.1  junyoung 	}
    830       1.1  junyoung 
    831       1.1  junyoung 	crtc->gen_cntl = 0;
    832       1.1  junyoung 	if (mode->flags & VID_INTERLACE)
    833       1.1  junyoung 		crtc->gen_cntl |= CRTC_INTERLACE_EN;
    834       1.1  junyoung 	if (mode->flags & VID_CSYNC)
    835       1.1  junyoung 		crtc->gen_cntl |= CRTC_CSYNC_EN;
    836       1.1  junyoung 
    837       1.1  junyoung 	crtc->dot_clock = mode->dot_clock;
    838       1.1  junyoung 
    839       1.1  junyoung 	return 0;
    840       1.1  junyoung }
    841       1.1  junyoung 
    842       1.1  junyoung void
    843       1.1  junyoung mach64_set_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc)
    844       1.1  junyoung {
    845       1.1  junyoung 
    846       1.1  junyoung 	mach64_set_pll(sc, crtc->dot_clock);
    847       1.1  junyoung 
    848       1.1  junyoung 	if (sc->has_dsp)
    849       1.1  junyoung 		mach64_set_dsp(sc);
    850       1.1  junyoung 
    851       1.1  junyoung 	regw(sc, CRTC_H_TOTAL_DISP, crtc->h_total_disp);
    852       1.1  junyoung 	regw(sc, CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
    853       1.1  junyoung 	regw(sc, CRTC_V_TOTAL_DISP, crtc->v_total_disp);
    854       1.1  junyoung 	regw(sc, CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
    855       1.1  junyoung 
    856       1.1  junyoung 	regw(sc, CRTC_VLINE_CRNT_VLINE, 0);
    857       1.1  junyoung 
    858       1.1  junyoung 	regw(sc, CRTC_OFF_PITCH, (sc->virt_x >> 3) << 22);
    859       1.1  junyoung 
    860       1.1  junyoung 	regw(sc, CRTC_GEN_CNTL, crtc->gen_cntl | crtc->color_depth |
    861       1.1  junyoung 	    CRTC_EXT_DISP_EN | CRTC_EXT_EN);
    862       1.1  junyoung }
    863       1.1  junyoung 
    864       1.1  junyoung int
    865       1.1  junyoung mach64_modeswitch(struct mach64_softc *sc, struct videomode *mode)
    866       1.1  junyoung {
    867       1.1  junyoung 	struct mach64_crtcregs crtc;
    868       1.1  junyoung 
    869       1.1  junyoung 	if (mach64_calc_crtcregs(sc, &crtc, mode))
    870       1.1  junyoung 		return 1;
    871       1.1  junyoung 
    872       1.1  junyoung 	mach64_set_crtcregs(sc, &crtc);
    873       1.1  junyoung 	return 0;
    874       1.1  junyoung }
    875       1.1  junyoung 
    876       1.1  junyoung void
    877       1.1  junyoung mach64_reset_engine(struct mach64_softc *sc)
    878       1.1  junyoung {
    879       1.1  junyoung 
    880       1.1  junyoung 	/* Reset engine.*/
    881       1.1  junyoung 	regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) & ~GUI_ENGINE_ENABLE);
    882       1.1  junyoung 
    883       1.1  junyoung 	/* Enable engine. */
    884       1.1  junyoung 	regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) | GUI_ENGINE_ENABLE);
    885       1.1  junyoung 
    886       1.1  junyoung 	/* Ensure engine is not locked up by clearing any FIFO or
    887       1.1  junyoung 	   host errors. */
    888       1.1  junyoung 	regw(sc, BUS_CNTL, regr(sc, BUS_CNTL) | BUS_HOST_ERR_ACK |
    889       1.1  junyoung 	    BUS_FIFO_ERR_ACK);
    890       1.1  junyoung }
    891       1.1  junyoung 
    892       1.1  junyoung void
    893       1.1  junyoung mach64_init_engine(struct mach64_softc *sc)
    894       1.1  junyoung {
    895       1.1  junyoung 	u_int32_t pitch_value;
    896       1.1  junyoung 
    897       1.1  junyoung 	pitch_value = sc->virt_x;
    898       1.1  junyoung 
    899       1.1  junyoung 	if (sc->bits_per_pixel == 24)
    900       1.1  junyoung 		pitch_value *= 3;
    901       1.1  junyoung 
    902       1.1  junyoung 	mach64_reset_engine(sc);
    903       1.1  junyoung 
    904       1.1  junyoung 	wait_for_fifo(sc, 14);
    905       1.1  junyoung 
    906       1.1  junyoung 	regw(sc, CONTEXT_MASK, 0xffffffff);
    907       1.1  junyoung 
    908       1.1  junyoung 	regw(sc, DST_OFF_PITCH, (pitch_value / 8) << 22);
    909       1.1  junyoung 
    910       1.1  junyoung 	regw(sc, DST_Y_X, 0);
    911       1.1  junyoung 	regw(sc, DST_HEIGHT, 0);
    912       1.1  junyoung 	regw(sc, DST_BRES_ERR, 0);
    913       1.1  junyoung 	regw(sc, DST_BRES_INC, 0);
    914       1.1  junyoung 	regw(sc, DST_BRES_DEC, 0);
    915       1.1  junyoung 
    916       1.1  junyoung 	regw(sc, DST_CNTL, DST_LAST_PEL | DST_X_LEFT_TO_RIGHT |
    917       1.1  junyoung 	    DST_Y_TOP_TO_BOTTOM);
    918       1.1  junyoung 
    919       1.1  junyoung 	regw(sc, SRC_OFF_PITCH, (pitch_value / 8) << 22);
    920       1.1  junyoung 
    921       1.1  junyoung 	regw(sc, SRC_Y_X, 0);
    922       1.1  junyoung 	regw(sc, SRC_HEIGHT1_WIDTH1, 1);
    923       1.1  junyoung 	regw(sc, SRC_Y_X_START, 0);
    924       1.1  junyoung 	regw(sc, SRC_HEIGHT2_WIDTH2, 1);
    925       1.1  junyoung 
    926       1.1  junyoung 	regw(sc, SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
    927       1.1  junyoung 
    928       1.1  junyoung 	wait_for_fifo(sc, 13);
    929       1.1  junyoung 	regw(sc, HOST_CNTL, 0);
    930       1.1  junyoung 
    931       1.1  junyoung 	regw(sc, PAT_REG0, 0);
    932       1.1  junyoung 	regw(sc, PAT_REG1, 0);
    933       1.1  junyoung 	regw(sc, PAT_CNTL, 0);
    934       1.1  junyoung 
    935       1.1  junyoung 	regw(sc, SC_LEFT, 0);
    936       1.1  junyoung 	regw(sc, SC_TOP, 0);
    937       1.1  junyoung 	regw(sc, SC_BOTTOM, default_mode.vdisplay - 1);
    938       1.1  junyoung 	regw(sc, SC_RIGHT, pitch_value - 1);
    939       1.1  junyoung 
    940       1.1  junyoung 	regw(sc, DP_BKGD_CLR, 0);
    941       1.1  junyoung 	regw(sc, DP_FRGD_CLR, 0xffffffff);
    942       1.1  junyoung 	regw(sc, DP_WRITE_MASK, 0xffffffff);
    943       1.1  junyoung 	regw(sc, DP_MIX, (MIX_SRC << 16) | MIX_DST);
    944       1.1  junyoung 
    945       1.1  junyoung 	regw(sc, DP_SRC, FRGD_SRC_FRGD_CLR);
    946       1.1  junyoung 
    947       1.1  junyoung 	wait_for_fifo(sc, 3);
    948       1.1  junyoung 	regw(sc, CLR_CMP_CLR, 0);
    949       1.1  junyoung 	regw(sc, CLR_CMP_MASK, 0xffffffff);
    950       1.1  junyoung 	regw(sc, CLR_CMP_CNTL, 0);
    951       1.1  junyoung 
    952       1.1  junyoung 	wait_for_fifo(sc, 2);
    953       1.1  junyoung 	switch (sc->bits_per_pixel) {
    954       1.1  junyoung 	case 8:
    955       1.1  junyoung 		regw(sc, DP_PIX_WIDTH, HOST_8BPP | SRC_8BPP | DST_8BPP);
    956       1.1  junyoung 		regw(sc, DP_CHAIN_MASK, DP_CHAIN_8BPP);
    957  1.14.2.5     skrll 		/* XXX Macallan: huh? We /want/ an 8 bit per channel palette! */
    958  1.14.2.5     skrll 		/*regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) & ~DAC_8BIT_EN);*/
    959  1.14.2.5     skrll 		regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
    960       1.1  junyoung 		break;
    961       1.1  junyoung #if 0
    962       1.1  junyoung 	case 32:
    963       1.1  junyoung 		regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP);
    964       1.1  junyoung 		regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP);
    965       1.1  junyoung 		regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
    966       1.1  junyoung 		break;
    967       1.1  junyoung #endif
    968       1.1  junyoung 	}
    969       1.1  junyoung 
    970       1.1  junyoung 	wait_for_fifo(sc, 5);
    971       1.1  junyoung 	regw(sc, CRTC_INT_CNTL, regr(sc, CRTC_INT_CNTL) & ~0x20);
    972       1.1  junyoung 	regw(sc, GUI_TRAJ_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
    973       1.1  junyoung 
    974       1.1  junyoung 	wait_for_idle(sc);
    975       1.1  junyoung }
    976       1.1  junyoung 
    977       1.1  junyoung void
    978       1.1  junyoung mach64_adjust_frame(struct mach64_softc *sc, int x, int y)
    979       1.1  junyoung {
    980       1.1  junyoung 	int offset;
    981       1.1  junyoung 
    982       1.1  junyoung 	offset = ((x + y * sc->virt_x) * (sc->bits_per_pixel >> 3)) >> 3;
    983       1.1  junyoung 
    984       1.1  junyoung 	regw(sc, CRTC_OFF_PITCH, (regr(sc, CRTC_OFF_PITCH) & 0xfff00000) |
    985       1.1  junyoung 	     offset);
    986       1.1  junyoung }
    987       1.1  junyoung 
    988       1.1  junyoung void
    989       1.1  junyoung mach64_set_dsp(struct mach64_softc *sc)
    990       1.1  junyoung {
    991       1.1  junyoung 	u_int32_t fifo_depth, page_size, dsp_precision, dsp_loop_latency;
    992       1.1  junyoung 	u_int32_t dsp_off, dsp_on, dsp_xclks_per_qw;
    993       1.1  junyoung 	u_int32_t xclks_per_qw, y;
    994       1.1  junyoung 	u_int32_t fifo_off, fifo_on;
    995       1.1  junyoung 
    996       1.1  junyoung 	if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
    997       1.1  junyoung 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II ||
    998       1.1  junyoung 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIP ||
    999       1.1  junyoung 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_PCI ||
   1000       1.1  junyoung 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_AGP_B ||
   1001       1.1  junyoung 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_AGP_P) {
   1002       1.1  junyoung 		dsp_loop_latency = 0;
   1003       1.1  junyoung 		fifo_depth = 24;
   1004       1.1  junyoung 	} else {
   1005       1.1  junyoung 		dsp_loop_latency = 2;
   1006       1.1  junyoung 		fifo_depth = 32;
   1007       1.1  junyoung 	}
   1008       1.1  junyoung 
   1009       1.1  junyoung 	dsp_precision = 0;
   1010       1.1  junyoung 	xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) /
   1011       1.1  junyoung 	    (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel);
   1012       1.1  junyoung 	y = (xclks_per_qw * fifo_depth) >> 11;
   1013       1.1  junyoung 	while (y) {
   1014       1.1  junyoung 		y >>= 1;
   1015       1.1  junyoung 		dsp_precision++;
   1016       1.1  junyoung 	}
   1017       1.1  junyoung 	dsp_precision -= 5;
   1018       1.1  junyoung 	fifo_off = ((xclks_per_qw * (fifo_depth - 1)) >> 5) + (3 << 6);
   1019       1.1  junyoung 
   1020       1.1  junyoung 	switch (sc->memtype) {
   1021       1.1  junyoung 	case DRAM:
   1022       1.1  junyoung 	case EDO_DRAM:
   1023       1.1  junyoung 	case PSEUDO_EDO:
   1024       1.1  junyoung 		if (sc->memsize > 1024) {
   1025       1.1  junyoung 			page_size = 9;
   1026       1.1  junyoung 			dsp_loop_latency += 6;
   1027       1.1  junyoung 		} else {
   1028       1.1  junyoung 			page_size = 10;
   1029       1.1  junyoung 			if (sc->memtype == DRAM)
   1030       1.1  junyoung 				dsp_loop_latency += 8;
   1031       1.1  junyoung 			else
   1032       1.1  junyoung 				dsp_loop_latency += 7;
   1033       1.1  junyoung 		}
   1034       1.1  junyoung 		break;
   1035       1.1  junyoung 	case SDRAM:
   1036       1.1  junyoung 	case SGRAM:
   1037       1.1  junyoung 		if (sc->memsize > 1024) {
   1038       1.1  junyoung 			page_size = 8;
   1039       1.1  junyoung 			dsp_loop_latency += 8;
   1040       1.1  junyoung 		} else {
   1041       1.1  junyoung 			page_size = 10;
   1042       1.1  junyoung 			dsp_loop_latency += 9;
   1043       1.1  junyoung 		}
   1044       1.1  junyoung 		break;
   1045       1.1  junyoung 	default:
   1046       1.1  junyoung 		page_size = 10;
   1047       1.1  junyoung 		dsp_loop_latency += 9;
   1048       1.1  junyoung 		break;
   1049       1.1  junyoung 	}
   1050       1.1  junyoung 
   1051       1.1  junyoung 	if (xclks_per_qw >= (page_size << 11))
   1052       1.1  junyoung 		fifo_on = ((2 * page_size + 1) << 6) + (xclks_per_qw >> 5);
   1053       1.1  junyoung 	else
   1054       1.1  junyoung 		fifo_on = (3 * page_size + 2) << 6;
   1055       1.1  junyoung 
   1056       1.1  junyoung 	dsp_xclks_per_qw = xclks_per_qw >> dsp_precision;
   1057       1.1  junyoung 	dsp_on = fifo_on >> dsp_precision;
   1058       1.1  junyoung 	dsp_off = fifo_off >> dsp_precision;
   1059       1.1  junyoung 
   1060       1.1  junyoung #ifdef MACH64_DEBUG
   1061       1.1  junyoung 	printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n"
   1062       1.1  junyoung 	    "dsp_precision = %d, dsp_loop_latency = %d,\n"
   1063       1.1  junyoung 	    "mclk_fb_div = %d, vclk_fb_div = %d,\n"
   1064       1.1  junyoung 	    "mclk_post_div = %d, vclk_post_div = %d\n",
   1065       1.1  junyoung 	    dsp_xclks_per_qw, dsp_on, dsp_off, dsp_precision, dsp_loop_latency,
   1066       1.1  junyoung 	    sc->mclk_fb_div, sc->vclk_fb_div,
   1067       1.1  junyoung 	    sc->mclk_post_div, sc->vclk_post_div);
   1068       1.1  junyoung #endif
   1069       1.1  junyoung 
   1070       1.1  junyoung 	regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF));
   1071       1.1  junyoung 	regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) |
   1072       1.1  junyoung 	    ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) |
   1073       1.1  junyoung 	    (dsp_xclks_per_qw & DSP_XCLKS_PER_QW));
   1074       1.1  junyoung }
   1075       1.1  junyoung 
   1076       1.1  junyoung void
   1077       1.1  junyoung mach64_set_pll(struct mach64_softc *sc, int clock)
   1078       1.1  junyoung {
   1079       1.1  junyoung 	int q;
   1080       1.1  junyoung 
   1081       1.1  junyoung 	q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq);
   1082       1.1  junyoung #ifdef MACH64_DEBUG
   1083       1.1  junyoung 	printf("q = %d\n", q);
   1084       1.1  junyoung #endif
   1085       1.1  junyoung 	if (q > 25500) {
   1086       1.1  junyoung 		printf("Warning: q > 25500\n");
   1087       1.1  junyoung 		q = 25500;
   1088       1.1  junyoung 		sc->vclk_post_div = 1;
   1089       1.1  junyoung 		sc->log2_vclk_post_div = 0;
   1090       1.1  junyoung 	} else if (q > 12750) {
   1091       1.1  junyoung 		sc->vclk_post_div = 1;
   1092       1.1  junyoung 		sc->log2_vclk_post_div = 0;
   1093       1.1  junyoung 	} else if (q > 6350) {
   1094       1.1  junyoung 		sc->vclk_post_div = 2;
   1095       1.1  junyoung 		sc->log2_vclk_post_div = 1;
   1096       1.1  junyoung 	} else if (q > 3150) {
   1097       1.1  junyoung 		sc->vclk_post_div = 4;
   1098       1.1  junyoung 		sc->log2_vclk_post_div = 2;
   1099       1.1  junyoung 	} else if (q >= 1600) {
   1100       1.1  junyoung 		sc->vclk_post_div = 8;
   1101       1.1  junyoung 		sc->log2_vclk_post_div = 3;
   1102       1.1  junyoung 	} else {
   1103       1.1  junyoung 		printf("Warning: q < 1600\n");
   1104       1.1  junyoung 		sc->vclk_post_div = 8;
   1105       1.1  junyoung 		sc->log2_vclk_post_div = 3;
   1106       1.1  junyoung 	}
   1107       1.1  junyoung 	sc->vclk_fb_div = q * sc->vclk_post_div / 100;
   1108       1.1  junyoung 
   1109       1.1  junyoung 	regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div);
   1110       1.1  junyoung 	regwb_pll(sc, VCLK_POST_DIV, sc->log2_vclk_post_div);
   1111       1.1  junyoung 	regwb_pll(sc, VCLK0_FB_DIV, sc->vclk_fb_div);
   1112       1.1  junyoung }
   1113       1.1  junyoung 
   1114       1.1  junyoung void
   1115       1.1  junyoung mach64_init_lut(struct mach64_softc *sc)
   1116       1.1  junyoung {
   1117  1.14.2.5     skrll 	/* XXX this is pretty dodgy since it's perfectly possible that
   1118  1.14.2.5     skrll 	   both terminal emulations are compiled into the kernel, in this
   1119  1.14.2.5     skrll 	   case we'd install the VT100 colour map which may be wrong */
   1120  1.14.2.5     skrll #ifdef WSEMUL_SUN
   1121  1.14.2.5     skrll 	mach64_putpalreg(sc,0,255,255,255);
   1122  1.14.2.5     skrll 	mach64_putpalreg(sc,1,0,0,0);
   1123  1.14.2.5     skrll 	mach64_putpalreg(sc,255,0,0,0);
   1124  1.14.2.5     skrll #endif
   1125  1.14.2.5     skrll #ifdef WSEMUL_VT100
   1126  1.14.2.5     skrll 	{
   1127  1.14.2.5     skrll 		int i,idx;
   1128  1.14.2.5     skrll 		idx=0;
   1129  1.14.2.5     skrll 		for(i=0;i<256;i++) {
   1130  1.14.2.5     skrll 			mach64_putpalreg(sc,i,rasops_cmap[idx],rasops_cmap[idx+1],rasops_cmap[idx+2]);
   1131  1.14.2.5     skrll 			idx+=3;
   1132  1.14.2.5     skrll 		}
   1133  1.14.2.5     skrll 	}
   1134  1.14.2.5     skrll #endif
   1135  1.14.2.5     skrll }
   1136       1.1  junyoung 
   1137  1.14.2.5     skrll int mach64_putpalreg(struct mach64_softc *sc, uint8_t index, uint8_t r, uint8_t g, uint8_t b)
   1138  1.14.2.5     skrll {
   1139  1.14.2.5     skrll 	sc->sc_cmap_red[index]=r;
   1140  1.14.2.5     skrll 	sc->sc_cmap_green[index]=g;
   1141  1.14.2.5     skrll 	sc->sc_cmap_blue[index]=b;
   1142  1.14.2.5     skrll 	/* writing the dac index takes a while, in theory we can poll some register
   1143  1.14.2.5     skrll 	   to see when it's ready - but we better avoid writing it unnecessarily */
   1144  1.14.2.5     skrll 	if(index!=sc->sc_dacw)
   1145  1.14.2.5     skrll 	{
   1146  1.14.2.5     skrll 		regwb(sc, DAC_MASK, 0xff);
   1147  1.14.2.5     skrll 		regwb(sc, DAC_WINDEX, index);
   1148  1.14.2.5     skrll 	}
   1149  1.14.2.5     skrll 	sc->sc_dacw=index+1;
   1150  1.14.2.5     skrll 	regwb(sc, DAC_DATA, r);
   1151  1.14.2.5     skrll 	regwb(sc, DAC_DATA, g);
   1152  1.14.2.5     skrll 	regwb(sc, DAC_DATA, b);
   1153  1.14.2.5     skrll 	return 0;
   1154  1.14.2.5     skrll }
   1155       1.1  junyoung 
   1156  1.14.2.5     skrll int mach64_putcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
   1157  1.14.2.5     skrll {
   1158  1.14.2.5     skrll 	u_int index = cm->index;
   1159  1.14.2.5     skrll 	u_int count = cm->count;
   1160  1.14.2.5     skrll 	int i, error;
   1161  1.14.2.5     skrll 	u_char rbuf[256], gbuf[256], bbuf[256];
   1162  1.14.2.5     skrll 	u_char *r, *g, *b;
   1163  1.14.2.5     skrll 
   1164  1.14.2.5     skrll 	printf("putcmap: %d %d\n",index, count);
   1165  1.14.2.5     skrll 	if (cm->index >= 256 || cm->count > 256 ||
   1166  1.14.2.5     skrll 	    (cm->index + cm->count) > 256)
   1167  1.14.2.5     skrll 		return EINVAL;
   1168  1.14.2.5     skrll 	error = copyin(cm->red, &rbuf[index], count);
   1169  1.14.2.5     skrll 	if (error)
   1170  1.14.2.5     skrll 		return error;
   1171  1.14.2.5     skrll 	error = copyin(cm->green, &gbuf[index], count);
   1172  1.14.2.5     skrll 	if (error)
   1173  1.14.2.5     skrll 		return error;
   1174  1.14.2.5     skrll 	error = copyin(cm->blue, &bbuf[index], count);
   1175  1.14.2.5     skrll 	if (error)
   1176  1.14.2.5     skrll 		return error;
   1177  1.14.2.5     skrll 
   1178  1.14.2.5     skrll 	memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
   1179  1.14.2.5     skrll 	memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
   1180  1.14.2.5     skrll 	memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
   1181  1.14.2.5     skrll 
   1182  1.14.2.5     skrll 	r = &sc->sc_cmap_red[index];
   1183  1.14.2.5     skrll 	g = &sc->sc_cmap_green[index];
   1184  1.14.2.5     skrll 	b = &sc->sc_cmap_blue[index];
   1185  1.14.2.5     skrll 
   1186  1.14.2.5     skrll 	for (i = 0; i < count; i++) {
   1187  1.14.2.5     skrll 		mach64_putpalreg(sc,index,*r, *g, *b);
   1188  1.14.2.5     skrll 		index++;
   1189  1.14.2.5     skrll 		r++, g++, b++;
   1190       1.1  junyoung 	}
   1191  1.14.2.5     skrll 	return 0;
   1192  1.14.2.5     skrll }
   1193  1.14.2.5     skrll 
   1194  1.14.2.5     skrll int mach64_getcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
   1195  1.14.2.5     skrll {
   1196  1.14.2.5     skrll 	u_int index = cm->index;
   1197  1.14.2.5     skrll 	u_int count = cm->count;
   1198  1.14.2.5     skrll 	int error;
   1199  1.14.2.5     skrll 
   1200  1.14.2.5     skrll 	if (index >= 255 || count > 256 || index + count > 256)
   1201  1.14.2.5     skrll 		return EINVAL;
   1202  1.14.2.5     skrll 
   1203  1.14.2.5     skrll 	error = copyout(&sc->sc_cmap_red[index],   cm->red,   count);
   1204  1.14.2.5     skrll 	if (error)
   1205  1.14.2.5     skrll 		return error;
   1206  1.14.2.5     skrll 	error = copyout(&sc->sc_cmap_green[index], cm->green, count);
   1207  1.14.2.5     skrll 	if (error)
   1208  1.14.2.5     skrll 		return error;
   1209  1.14.2.5     skrll 	error = copyout(&sc->sc_cmap_blue[index],  cm->blue,  count);
   1210  1.14.2.5     skrll 	if (error)
   1211  1.14.2.5     skrll 		return error;
   1212  1.14.2.5     skrll 
   1213  1.14.2.5     skrll 	return 0;
   1214       1.1  junyoung }
   1215       1.1  junyoung 
   1216       1.1  junyoung void
   1217       1.1  junyoung mach64_switch_screen(struct mach64_softc *sc)
   1218       1.1  junyoung {
   1219       1.1  junyoung 	struct mach64screen *scr, *oldscr;
   1220       1.1  junyoung 	const struct wsscreen_descr *type;
   1221       1.1  junyoung 
   1222       1.1  junyoung 	scr = sc->wanted;
   1223       1.1  junyoung 	if (!scr) {
   1224       1.1  junyoung 		printf("mach64_switch_screen: disappeared\n");
   1225       1.1  junyoung 		(*sc->switchcb)(sc->switchcbarg, EIO, 0);
   1226       1.1  junyoung 		return;
   1227       1.1  junyoung 	}
   1228       1.1  junyoung 	type = scr->type;
   1229       1.1  junyoung 	oldscr = sc->active; /* can be NULL! */
   1230       1.1  junyoung #ifdef DIAGNOSTIC
   1231       1.1  junyoung 	if (oldscr) {
   1232       1.1  junyoung 		if (!oldscr->active)
   1233       1.1  junyoung 			panic("mach64_switch_screen: not active");
   1234      1.11    martin 		if (oldscr->type != sc->currenttype)
   1235       1.1  junyoung 			panic("mach64_switch_screen: bad type");
   1236       1.1  junyoung 	}
   1237       1.1  junyoung #endif
   1238       1.1  junyoung 	if (scr == oldscr)
   1239       1.1  junyoung 		return;
   1240       1.1  junyoung 
   1241       1.1  junyoung #ifdef DIAGNOSTIC
   1242  1.14.2.5     skrll /* XXX Macallan: this one bites us at reboot */
   1243  1.14.2.5     skrll /*	if (scr->active)
   1244  1.14.2.5     skrll 		panic("mach64_switch_screen: active");*/
   1245       1.1  junyoung #endif
   1246       1.1  junyoung 
   1247       1.1  junyoung 	if (oldscr)
   1248       1.1  junyoung 		oldscr->active = 0;
   1249       1.1  junyoung 
   1250       1.1  junyoung 	if (sc->currenttype != type) {
   1251       1.1  junyoung 		mach64_set_screentype(sc, type);
   1252       1.1  junyoung 		sc->currenttype = type;
   1253       1.1  junyoung 	}
   1254       1.1  junyoung 
   1255       1.1  junyoung 	scr->dispoffset = scr->mindispoffset;
   1256       1.1  junyoung 
   1257       1.1  junyoung 	if (!oldscr || (scr->dispoffset != oldscr->dispoffset)) {
   1258       1.1  junyoung 
   1259       1.1  junyoung 	}
   1260       1.1  junyoung 
   1261       1.1  junyoung 	/* Clear the entire screen. */
   1262       1.1  junyoung 
   1263       1.1  junyoung 	scr->active = 1;
   1264       1.1  junyoung 	mach64_restore_screen(scr, type, scr->mem);
   1265       1.1  junyoung 
   1266       1.1  junyoung 	sc->active = scr;
   1267       1.1  junyoung 
   1268       1.1  junyoung 	mach64_cursor(scr, scr->cursoron, scr->cursorrow, scr->cursorcol);
   1269       1.1  junyoung 
   1270       1.1  junyoung 	sc->wanted = 0;
   1271       1.1  junyoung 	if (sc->switchcb)
   1272       1.1  junyoung 		(*sc->switchcb)(sc->switchcbarg, 0, 0);
   1273       1.1  junyoung }
   1274       1.1  junyoung 
   1275       1.1  junyoung void
   1276       1.1  junyoung mach64_restore_screen(struct mach64screen *scr,
   1277       1.1  junyoung     const struct wsscreen_descr *type, u_int16_t *mem)
   1278       1.1  junyoung {
   1279       1.1  junyoung 
   1280       1.1  junyoung }
   1281       1.1  junyoung 
   1282       1.6  junyoung int
   1283       1.1  junyoung mach64_set_screentype(struct mach64_softc *sc, const struct wsscreen_descr *des)
   1284       1.1  junyoung {
   1285       1.6  junyoung 	struct mach64_crtcregs regs;
   1286       1.1  junyoung 
   1287       1.6  junyoung 	if (mach64_calc_crtcregs(sc, &regs,
   1288       1.6  junyoung 	    (struct videomode *)des->modecookie))
   1289       1.6  junyoung 		return 1;
   1290       1.6  junyoung 
   1291       1.6  junyoung 	mach64_set_crtcregs(sc, &regs);
   1292       1.6  junyoung 	return 0;
   1293       1.1  junyoung }
   1294       1.1  junyoung 
   1295       1.5  junyoung int
   1296       1.5  junyoung mach64_is_console(struct pci_attach_args *pa)
   1297       1.5  junyoung {
   1298       1.5  junyoung #ifdef __sparc__
   1299       1.5  junyoung 	int node;
   1300       1.5  junyoung 
   1301       1.5  junyoung 	node = PCITAG_NODE(pa->pa_tag);
   1302       1.5  junyoung 	if (node == -1)
   1303       1.5  junyoung 		return 0;
   1304       1.5  junyoung 
   1305  1.14.2.2     skrll 	return (node == prom_instance_to_package(prom_stdout()));
   1306       1.5  junyoung #else
   1307       1.5  junyoung 	return 1;
   1308       1.5  junyoung #endif
   1309       1.5  junyoung }
   1310       1.5  junyoung 
   1311       1.1  junyoung /*
   1312       1.1  junyoung  * wsdisplay_emulops
   1313       1.1  junyoung  */
   1314       1.1  junyoung 
   1315       1.1  junyoung void
   1316       1.1  junyoung mach64_cursor(void *cookie, int on, int row, int col)
   1317       1.1  junyoung {
   1318       1.1  junyoung 
   1319       1.1  junyoung }
   1320       1.1  junyoung 
   1321       1.7    martin #if 0
   1322       1.1  junyoung int
   1323       1.1  junyoung mach64_mapchar(void *cookie, int uni, u_int *index)
   1324       1.1  junyoung {
   1325       1.1  junyoung 
   1326       1.1  junyoung 	return 0;
   1327       1.1  junyoung }
   1328       1.1  junyoung 
   1329       1.1  junyoung void
   1330       1.1  junyoung mach64_putchar(void *cookie, int row, int col, u_int c, long attr)
   1331       1.1  junyoung {
   1332       1.1  junyoung 
   1333       1.1  junyoung }
   1334  1.14.2.5     skrll #endif
   1335       1.1  junyoung 
   1336       1.1  junyoung void
   1337       1.1  junyoung mach64_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
   1338       1.1  junyoung {
   1339  1.14.2.5     skrll 	struct rasops_info *ri=cookie;
   1340  1.14.2.5     skrll 	struct mach64_softc *sc=ri->ri_hw;
   1341  1.14.2.5     skrll 	int32_t xs,xd,y,width,height;
   1342  1.14.2.5     skrll 
   1343  1.14.2.5     skrll 	xs=ri->ri_xorigin+ri->ri_font->fontwidth*srccol;
   1344  1.14.2.5     skrll 	xd=ri->ri_xorigin+ri->ri_font->fontwidth*dstcol;
   1345  1.14.2.5     skrll 	y=ri->ri_yorigin+ri->ri_font->fontheight*row;
   1346  1.14.2.5     skrll 	width=ri->ri_font->fontwidth*ncols;
   1347  1.14.2.5     skrll 	height=ri->ri_font->fontheight;
   1348  1.14.2.5     skrll 	mach64_bitblt(sc,xs,y,xd,y,width,height,MIX_SRC,0xff);
   1349       1.1  junyoung }
   1350       1.1  junyoung 
   1351       1.1  junyoung void
   1352       1.1  junyoung mach64_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
   1353       1.1  junyoung {
   1354  1.14.2.5     skrll 	struct rasops_info *ri=cookie;
   1355  1.14.2.5     skrll 	struct mach64_softc *sc=ri->ri_hw;
   1356  1.14.2.5     skrll 	int32_t x,y,width,height,fg,bg,ul;;
   1357  1.14.2.5     skrll 
   1358  1.14.2.5     skrll 	x=ri->ri_xorigin+ri->ri_font->fontwidth*startcol;
   1359  1.14.2.5     skrll 	y=ri->ri_yorigin+ri->ri_font->fontheight*row;
   1360  1.14.2.5     skrll 	width=ri->ri_font->fontwidth*ncols;
   1361  1.14.2.5     skrll 	height=ri->ri_font->fontheight;
   1362  1.14.2.5     skrll 	rasops_unpack_attr(fillattr,&fg,&bg,&ul);
   1363  1.14.2.5     skrll 
   1364  1.14.2.5     skrll 	mach64_rectfill(sc,x,y,width,height,bg);
   1365       1.1  junyoung 
   1366       1.1  junyoung }
   1367       1.1  junyoung 
   1368       1.1  junyoung void
   1369       1.1  junyoung mach64_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
   1370       1.1  junyoung {
   1371  1.14.2.5     skrll 	struct rasops_info *ri=cookie;
   1372  1.14.2.5     skrll 	struct mach64_softc *sc=ri->ri_hw;
   1373  1.14.2.5     skrll 	int32_t x,ys,yd,width,height;
   1374  1.14.2.5     skrll 
   1375  1.14.2.5     skrll 	x=ri->ri_xorigin;
   1376  1.14.2.5     skrll 	ys=ri->ri_yorigin+ri->ri_font->fontheight*srcrow;
   1377  1.14.2.5     skrll 	yd=ri->ri_yorigin+ri->ri_font->fontheight*dstrow;
   1378  1.14.2.5     skrll 	width=ri->ri_emuwidth;
   1379  1.14.2.5     skrll 	height=ri->ri_font->fontheight*nrows;
   1380  1.14.2.5     skrll 	mach64_bitblt(sc,x,ys,x,yd,width,height,MIX_SRC,0xff);
   1381  1.14.2.5     skrll }
   1382  1.14.2.5     skrll 
   1383  1.14.2.5     skrll void mach64_bitblt(struct mach64_softc *sc, int xs, int ys, int xd, int yd, int width, int height, int rop,
   1384  1.14.2.5     skrll int mask)
   1385  1.14.2.5     skrll {
   1386  1.14.2.5     skrll 	uint32_t dest_ctl=0;
   1387  1.14.2.5     skrll 	wait_for_idle(sc);
   1388  1.14.2.5     skrll 	regw(sc,DP_WRITE_MASK,mask);	/* XXX only good for 8 bit */
   1389  1.14.2.5     skrll 	regw(sc,DP_PIX_WIDTH,DST_8BPP|SRC_8BPP|HOST_8BPP);
   1390  1.14.2.5     skrll 	regw(sc,DP_SRC,FRGD_SRC_BLIT);
   1391  1.14.2.5     skrll 	regw(sc,DP_MIX,(rop&0xffff)<<16);
   1392  1.14.2.5     skrll 	regw(sc,CLR_CMP_CNTL,0);	/* no transparency */
   1393  1.14.2.5     skrll 	if(yd<ys) {
   1394  1.14.2.5     skrll 		dest_ctl=DST_Y_TOP_TO_BOTTOM;
   1395  1.14.2.5     skrll 	} else {
   1396  1.14.2.5     skrll 		ys+=height-1;
   1397  1.14.2.5     skrll 		yd+=height-1;
   1398  1.14.2.5     skrll 		dest_ctl=DST_Y_BOTTOM_TO_TOP;
   1399  1.14.2.5     skrll 	}
   1400  1.14.2.5     skrll 	if(xd<xs) {
   1401  1.14.2.5     skrll 		dest_ctl|=DST_X_LEFT_TO_RIGHT;
   1402  1.14.2.5     skrll 		regw(sc,SRC_CNTL,SRC_LINE_X_LEFT_TO_RIGHT);
   1403  1.14.2.5     skrll 	} else {
   1404  1.14.2.5     skrll 		dest_ctl|=DST_X_RIGHT_TO_LEFT;
   1405  1.14.2.5     skrll 		xs+=width-1;
   1406  1.14.2.5     skrll 		xd+=width-1;
   1407  1.14.2.5     skrll 		regw(sc,SRC_CNTL,SRC_LINE_X_RIGHT_TO_LEFT);
   1408  1.14.2.5     skrll 	}
   1409  1.14.2.5     skrll 	regw(sc,DST_CNTL,dest_ctl);
   1410  1.14.2.5     skrll 
   1411  1.14.2.5     skrll 	regw(sc,SRC_Y_X,(xs<<16)|ys);
   1412  1.14.2.5     skrll 	regw(sc,SRC_WIDTH1,width);
   1413  1.14.2.5     skrll 	regw(sc,DST_Y_X,(xd<<16)|yd);
   1414  1.14.2.5     skrll 	regw(sc,DST_HEIGHT_WIDTH,(width<<16)|height);
   1415  1.14.2.5     skrll 	/* as long as the other rasops* functions aren't aware of the blitter we must wait here
   1416  1.14.2.5     skrll 	   or the blitter might not be done when someone else draws the next line */
   1417  1.14.2.5     skrll 	wait_for_idle(sc);
   1418  1.14.2.5     skrll }
   1419  1.14.2.5     skrll 
   1420  1.14.2.5     skrll void mach64_rectfill(struct mach64_softc *sc, int x, int y, int width, int height, int colour)
   1421  1.14.2.5     skrll {
   1422  1.14.2.5     skrll 	wait_for_idle(sc);
   1423  1.14.2.5     skrll 	regw(sc,DP_WRITE_MASK,0xff);
   1424  1.14.2.5     skrll 	regw(sc,DP_FRGD_CLR,colour);
   1425  1.14.2.5     skrll 	regw(sc,DP_PIX_WIDTH,DST_8BPP|SRC_8BPP|HOST_8BPP);
   1426  1.14.2.5     skrll 	regw(sc,DP_SRC,FRGD_SRC_FRGD_CLR);
   1427  1.14.2.5     skrll 	regw(sc,DP_MIX,(MIX_SRC)<<16);
   1428  1.14.2.5     skrll 	regw(sc,CLR_CMP_CNTL,0);	/* no transparency */
   1429  1.14.2.5     skrll 	regw(sc,SRC_CNTL,SRC_LINE_X_LEFT_TO_RIGHT);
   1430  1.14.2.5     skrll 	regw(sc,DST_CNTL,DST_X_LEFT_TO_RIGHT|DST_Y_TOP_TO_BOTTOM);
   1431  1.14.2.5     skrll 
   1432  1.14.2.5     skrll 	regw(sc,SRC_Y_X,(x<<16)|y);
   1433  1.14.2.5     skrll 	regw(sc,SRC_WIDTH1,width);
   1434  1.14.2.5     skrll 	regw(sc,DST_Y_X,(x<<16)|y);
   1435  1.14.2.5     skrll 	regw(sc,DST_HEIGHT_WIDTH,(width<<16)|height);
   1436  1.14.2.5     skrll 	wait_for_idle(sc);
   1437       1.1  junyoung }
   1438       1.1  junyoung 
   1439  1.14.2.5     skrll void mach64_showpal(struct mach64_softc *sc)
   1440  1.14.2.5     skrll {
   1441  1.14.2.5     skrll 	int i,x=0;
   1442  1.14.2.5     skrll 	for (i=0;i<16;i++) {
   1443  1.14.2.5     skrll 		mach64_rectfill(sc,x,0,64,64,i);
   1444  1.14.2.5     skrll 		x+=64;
   1445  1.14.2.5     skrll 	}
   1446  1.14.2.5     skrll }
   1447  1.14.2.5     skrll 
   1448       1.7    martin int
   1449       1.7    martin mach64_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
   1450       1.1  junyoung {
   1451       1.1  junyoung 
   1452       1.7    martin 	return 0;
   1453       1.1  junyoung }
   1454       1.1  junyoung 
   1455       1.7    martin void
   1456       1.7    martin mach64_eraserows(void *cookie, int row, int nrows, long fillattr)
   1457       1.1  junyoung {
   1458  1.14.2.5     skrll 	struct rasops_info *ri=cookie;
   1459  1.14.2.5     skrll 	struct mach64_softc *sc=ri->ri_hw;
   1460  1.14.2.5     skrll 	int32_t x,y,width,height,fg,bg,ul;
   1461  1.14.2.5     skrll 
   1462  1.14.2.5     skrll 	x=ri->ri_xorigin;
   1463  1.14.2.5     skrll 	y=ri->ri_yorigin+ri->ri_font->fontheight*row;
   1464  1.14.2.5     skrll 	width=ri->ri_emuwidth;
   1465  1.14.2.5     skrll 	height=ri->ri_font->fontheight*nrows;
   1466  1.14.2.5     skrll 	rasops_unpack_attr(fillattr,&fg,&bg,&ul);
   1467  1.14.2.5     skrll 
   1468  1.14.2.5     skrll 	mach64_rectfill(sc,x,y,width,height,bg);
   1469       1.1  junyoung }
   1470       1.1  junyoung 
   1471       1.1  junyoung /*
   1472       1.1  junyoung  * wsdisplay_accessops
   1473       1.1  junyoung  */
   1474       1.1  junyoung 
   1475       1.1  junyoung int
   1476  1.14.2.4     skrll mach64_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct lwp *l)
   1477       1.1  junyoung {
   1478  1.14.2.5     skrll 	/* we'll probably need to add more stuff here */
   1479  1.14.2.5     skrll 	struct mach64_softc *sc = v;
   1480  1.14.2.5     skrll 	struct wsdisplay_fbinfo *wdf;
   1481  1.14.2.5     skrll 	struct mach64screen *ms=sc->active;
   1482  1.14.2.5     skrll 	switch (cmd) {
   1483  1.14.2.5     skrll 		case WSDISPLAYIO_GTYPE:
   1484  1.14.2.5     skrll 			*(u_int *)data = WSDISPLAY_TYPE_PCIMISC;	/* XXX ? */
   1485  1.14.2.5     skrll 			return 0;
   1486  1.14.2.5     skrll 
   1487  1.14.2.5     skrll 		case WSDISPLAYIO_GINFO:
   1488  1.14.2.5     skrll 			wdf = (void *)data;
   1489  1.14.2.5     skrll 			wdf->height = ms->ri.ri_height;
   1490  1.14.2.5     skrll 			wdf->width = ms->ri.ri_width;
   1491  1.14.2.5     skrll 			wdf->depth = ms->ri.ri_depth;
   1492  1.14.2.5     skrll 			wdf->cmsize = 256;
   1493  1.14.2.5     skrll 			return 0;
   1494  1.14.2.5     skrll 		case WSDISPLAYIO_GETCMAP:
   1495  1.14.2.5     skrll 			return mach64_getcmap(sc, (struct wsdisplay_cmap *)data);
   1496  1.14.2.5     skrll 
   1497  1.14.2.5     skrll 		case WSDISPLAYIO_PUTCMAP:
   1498  1.14.2.5     skrll 			return mach64_putcmap(sc, (struct wsdisplay_cmap *)data);
   1499  1.14.2.5     skrll 		/* PCI config read/write passthrough. */
   1500  1.14.2.5     skrll 		case PCI_IOC_CFGREAD:
   1501  1.14.2.5     skrll 		case PCI_IOC_CFGWRITE:
   1502  1.14.2.5     skrll 			return (pci_devioctl(sc->sc_pc, sc->sc_pcitag,
   1503  1.14.2.5     skrll 			    cmd, data, flag, p));
   1504  1.14.2.5     skrll #ifdef notyet
   1505  1.14.2.5     skrll 		case WSDISPLAYIO_SMODE:
   1506  1.14.2.5     skrll 			{
   1507  1.14.2.5     skrll 				int new_mode=*(int*)data;
   1508  1.14.2.5     skrll 				if(new_mode!=sc->sc_mode)
   1509  1.14.2.5     skrll 				{
   1510  1.14.2.5     skrll 					sc->sc_mode=new_mode;
   1511  1.14.2.5     skrll 					if(new_mode==WSDISPLAYIO_MODE_EMUL)
   1512  1.14.2.5     skrll 					{
   1513  1.14.2.5     skrll 						/* we'll probably want to reset the console into a known state here
   1514  1.14.2.5     skrll 						   just in case the Xserver crashed or didn't properly clean up after
   1515  1.14.2.5     skrll 						   itself for whetever reason */
   1516  1.14.2.5     skrll 					}
   1517  1.14.2.5     skrll 				}
   1518  1.14.2.5     skrll 			}
   1519  1.14.2.5     skrll #endif
   1520  1.14.2.5     skrll 	}
   1521  1.14.2.5     skrll 	return EPASSTHROUGH;
   1522       1.1  junyoung }
   1523       1.1  junyoung 
   1524       1.1  junyoung paddr_t
   1525       1.1  junyoung mach64_mmap(void *v, off_t offset, int prot)
   1526       1.1  junyoung {
   1527  1.14.2.5     skrll 	struct mach64_softc *sc = v;
   1528  1.14.2.5     skrll 	paddr_t pa;
   1529  1.14.2.5     skrll 	/* 'regular' framebuffer mmap()ing */
   1530  1.14.2.5     skrll 	if(offset<sc->sc_apersize) {
   1531  1.14.2.5     skrll 		pa = bus_space_mmap(sc->sc_memt,sc->sc_aperbase+offset,0,prot,BUS_SPACE_MAP_LINEAR);
   1532  1.14.2.5     skrll 		return pa;
   1533  1.14.2.5     skrll 	}
   1534  1.14.2.5     skrll 	/* allow XFree86 to mmap() PCI space as if the BARs contain physical addresses */
   1535  1.14.2.5     skrll 	if((offset>0x80000000) && (offset<=0xffffffff)) {
   1536  1.14.2.5     skrll 		pa = bus_space_mmap(sc->sc_memt,offset,0,prot,BUS_SPACE_MAP_LINEAR);
   1537  1.14.2.5     skrll 		return pa;
   1538  1.14.2.5     skrll 	}
   1539       1.1  junyoung 	return -1;
   1540       1.1  junyoung }
   1541       1.1  junyoung 
   1542       1.1  junyoung int
   1543       1.1  junyoung mach64_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
   1544       1.1  junyoung     int *curxp, int *curyp, long *defattrp)
   1545       1.1  junyoung {
   1546       1.1  junyoung 	struct mach64_softc *sc = v;
   1547       1.1  junyoung 	struct mach64screen *scr;
   1548       1.1  junyoung 
   1549       1.7    martin 	scr = malloc(sizeof(struct mach64screen), M_DEVBUF, M_WAITOK|M_ZERO);
   1550       1.7    martin 	mach64_init_screen(sc, scr, type, 0, defattrp, sc->active == NULL);
   1551       1.7    martin 	rasops_init(&scr->ri, mach64_console_screen.ri.ri_height / 16,
   1552       1.7    martin 	    mach64_console_screen.ri.ri_width / 8);
   1553       1.7    martin 
   1554       1.7    martin 	scr->mem = malloc(type->ncols * type->nrows * 2, M_DEVBUF,
   1555       1.7    martin 	     M_WAITOK);
   1556       1.7    martin 	mach64_eraserows(sc, 0, type->nrows, *defattrp);
   1557       1.7    martin 	if (sc->active == NULL) {
   1558       1.1  junyoung 		scr->active = 1;
   1559       1.1  junyoung 		sc->active = scr;
   1560       1.1  junyoung 		sc->currenttype = type;
   1561       1.1  junyoung 	}
   1562       1.1  junyoung 
   1563       1.1  junyoung 	*cookiep = scr;
   1564       1.1  junyoung 	*curxp = scr->cursorcol;
   1565       1.1  junyoung 	*curyp = scr->cursorrow;
   1566       1.1  junyoung 
   1567       1.1  junyoung 	return 0;
   1568       1.1  junyoung }
   1569       1.1  junyoung 
   1570       1.1  junyoung void
   1571       1.1  junyoung mach64_free_screen(void *v, void *cookie)
   1572       1.1  junyoung {
   1573       1.1  junyoung 	struct mach64_softc *sc = v;
   1574       1.1  junyoung 	struct mach64screen *scr = cookie;
   1575       1.1  junyoung 
   1576       1.1  junyoung 	LIST_REMOVE(scr, next);
   1577       1.1  junyoung 	if (scr != &mach64_console_screen)
   1578       1.1  junyoung 		free(scr, M_DEVBUF);
   1579       1.1  junyoung 	else
   1580       1.1  junyoung 		panic("mach64_free_screen: console");
   1581       1.1  junyoung 
   1582       1.1  junyoung 	if (sc->active == scr)
   1583       1.1  junyoung 		sc->active = 0;
   1584       1.1  junyoung }
   1585       1.1  junyoung 
   1586       1.1  junyoung int
   1587       1.1  junyoung mach64_show_screen(void *v, void *cookie, int waitok,
   1588       1.1  junyoung     void (*cb)(void *, int, int), void *cbarg)
   1589       1.1  junyoung {
   1590       1.1  junyoung 	struct mach64_softc *sc = v;
   1591       1.1  junyoung 	struct mach64screen *scr, *oldscr;
   1592       1.1  junyoung 
   1593       1.1  junyoung 	scr = cookie;
   1594       1.1  junyoung 	oldscr = sc->active;
   1595       1.1  junyoung 	if (scr == oldscr)
   1596       1.1  junyoung 		return 0;
   1597       1.1  junyoung 
   1598       1.1  junyoung 	sc->wanted = scr;
   1599       1.1  junyoung 	sc->switchcb = cb;
   1600       1.1  junyoung 	sc->switchcbarg = cbarg;
   1601       1.1  junyoung 	if (cb) {
   1602       1.1  junyoung 		callout_reset(&sc->switch_callout, 0,
   1603       1.1  junyoung 		    (void(*)(void *))mach64_switch_screen, sc);
   1604       1.1  junyoung 		return EAGAIN;
   1605       1.1  junyoung 	}
   1606       1.1  junyoung 
   1607       1.1  junyoung 	mach64_switch_screen(sc);
   1608       1.1  junyoung 
   1609       1.1  junyoung 	return 0;
   1610       1.1  junyoung }
   1611       1.1  junyoung 
   1612       1.7    martin #if 0
   1613       1.1  junyoung int
   1614       1.1  junyoung mach64_load_font(void *v, void *cookie, struct wsdisplay_font *data)
   1615       1.1  junyoung {
   1616       1.1  junyoung 
   1617       1.1  junyoung 	return 0;
   1618       1.1  junyoung }
   1619       1.7    martin #endif
   1620