this has been sitting in my tree too long:

- device_t-ify
- sanitize debugging #ifdefs
- deal with firmwares setting up modes using other clocks than #0
- get rid of sparc and macppc-specific code, use device properties instead
- while there, use alternate box drawing font if needed
This commit is contained in:
macallan 2010-05-04 05:07:14 +00:00
parent 9fae8e4448
commit d87e1bf08e

View File

@ -1,7 +1,8 @@
/* $NetBSD: machfb.c,v 1.58 2010/03/11 04:00:36 mrg Exp $ */
/* $NetBSD: machfb.c,v 1.59 2010/05/04 05:07:14 macallan Exp $ */
/*
* Copyright (c) 2002 Bang Jun-Young
* Copyright (c) 2005, 2006, 2007 Michael Lorenz
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,7 +34,7 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0,
"$NetBSD: machfb.c,v 1.58 2010/03/11 04:00:36 mrg Exp $");
"$NetBSD: machfb.c,v 1.59 2010/05/04 05:07:14 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -41,18 +42,11 @@ __KERNEL_RCSID(0,
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/callout.h>
#include <sys/lwp.h>
#include <sys/kauth.h>
#ifdef __sparc__
#include <machine/promlib.h>
#endif
#ifdef __powerpc__
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
#endif
#include <dev/videomode/videomode.h>
#include <dev/videomode/edidvar.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@ -74,6 +68,9 @@ __KERNEL_RCSID(0,
#include <dev/wscons/wsdisplay_vconsvar.h>
#include "opt_wsemul.h"
#include "opt_machfb.h"
#define MACH64_REG_SIZE 1024
#define MACH64_REG_OFF 0x7ffc00
@ -88,7 +85,7 @@ struct vga_bar {
};
struct mach64_softc {
struct device sc_dev;
device_t sc_dev;
#ifdef __sparc__
struct fbdevice sc_fb;
#endif
@ -111,6 +108,7 @@ struct mach64_softc {
bus_space_tag_t sc_regt;
bus_space_tag_t sc_memt;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_regh;
bus_space_handle_t sc_memh;
void *sc_aperture; /* mapped aperture vaddr */
@ -142,8 +140,12 @@ struct mach64_softc {
int vclk_fb_div;
int mclk_post_div;
int mclk_fb_div;
int sc_clock; /* which clock to use */
struct videomode *sc_my_mode;
int sc_edid_size;
uint8_t sc_edid_data[1024];
u_char sc_cmap_red[256];
u_char sc_cmap_green[256];
u_char sc_cmap_blue[256];
@ -174,6 +176,7 @@ static struct {
{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_P, 230000 },
{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_L, 230000 },
{ PCI_PRODUCT_ATI_RAGE_XL_PCI, 230000 },
{ PCI_PRODUCT_ATI_RAGE_XL_PCI66, 230000 },
{ PCI_PRODUCT_ATI_RAGE_II, 135000 },
{ PCI_PRODUCT_ATI_RAGE_IIP, 200000 },
{ PCI_PRODUCT_ATI_RAGE_IIC_PCI, 230000 },
@ -183,11 +186,12 @@ static struct {
{ PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 },
{ PCI_PRODUCT_ATI_RAGE_MOB_M3_PCI, 230000 },
{ PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
{ PCI_PRODUCT_ATI_RAGE_MOBILITY, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
#endif
{ PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
{ PCI_PRODUCT_ATI_MACH64_VT, 170000 },
{ PCI_PRODUCT_ATI_MACH64_VTB, 200000 },
{ PCI_PRODUCT_ATI_MACH64_VT4, 230000 }
@ -224,7 +228,7 @@ extern const u_char rasops_cmap[768];
static int mach64_match(device_t, cfdata_t, void *);
static void mach64_attach(device_t, device_t, void *);
CFATTACH_DECL(machfb, sizeof(struct mach64_softc), mach64_match, mach64_attach,
CFATTACH_DECL_NEW(machfb, sizeof(struct mach64_softc), mach64_match, mach64_attach,
NULL, NULL);
static void mach64_init(struct mach64_softc *);
@ -254,7 +258,7 @@ static void mach64_init_lut(struct mach64_softc *);
static void mach64_init_screen(void *, struct vcons_screen *, int, long *);
static int mach64_set_screentype(struct mach64_softc *,
const struct wsscreen_descr *);
static int mach64_is_console(struct pci_attach_args *);
static int mach64_is_console(struct mach64_softc *);
static void mach64_cursor(void *, int, int, int);
#if 0
@ -265,7 +269,6 @@ static void mach64_copycols(void *, int, int, int, int);
static void mach64_erasecols(void *, int, int, int, long);
static void mach64_copyrows(void *, int, int, int);
static void mach64_eraserows(void *, int, int, long);
static int mach64_allocattr(void *, int, int, int, long *);
static void mach64_clearscreen(struct mach64_softc *);
static int mach64_putcmap(struct mach64_softc *, struct wsdisplay_cmap *);
@ -284,19 +287,7 @@ static void mach64_showpal(struct mach64_softc *);
static void set_address(struct rasops_info *, void *);
static void machfb_blank(struct mach64_softc *, int);
#if 0
static const struct wsdisplay_emulops mach64_emulops = {
mach64_cursor,
mach64_mapchar,
mach64_putchar,
mach64_copycols,
mach64_erasecols,
mach64_copyrows,
mach64_eraserows,
mach64_allocattr,
};
#endif
static int machfb_drm_print(void *, const char *);
static struct wsscreen_descr mach64_defaultscreen = {
"default",
@ -449,9 +440,26 @@ regwb(struct mach64_softc *sc, uint32_t index, uint8_t data)
static inline void
regwb_pll(struct mach64_softc *sc, uint32_t index, uint8_t data)
{
regwb(sc, CLOCK_CNTL + 1, (index << 2) | PLL_WR_EN);
regwb(sc, CLOCK_CNTL + 2, data);
regwb(sc, CLOCK_CNTL + 1, (index << 2) & ~PLL_WR_EN);
uint32_t reg;
reg = regr(sc, CLOCK_CNTL);
reg |= PLL_WR_EN;
regw(sc, CLOCK_CNTL, reg);
reg &= ~(PLL_ADDR | PLL_DATA);
reg |= (index & 0x3f) << PLL_ADDR_SHIFT;
reg |= data << PLL_DATA_SHIFT;
reg |= CLOCK_STROBE;
regw(sc, CLOCK_CNTL, reg);
reg &= ~PLL_WR_EN;
regw(sc, CLOCK_CNTL, reg);
}
static inline uint8_t
regrb_pll(struct mach64_softc *sc, uint32_t index)
{
regwb(sc, CLOCK_CNTL + 1, index << 2);
return regrb(sc, CLOCK_CNTL + 2);
}
static inline void
@ -495,13 +503,17 @@ mach64_attach(device_t parent, device_t self, void *aux)
struct mach64_softc *sc = device_private(self);
struct pci_attach_args *pa = aux;
struct rasops_info *ri;
prop_data_t edid_data;
const struct videomode *mode = NULL;
char devinfo[256];
int bar, reg, id;
int bar, id;
struct wsemuldisplaydev_attach_args aa;
long defattr;
int setmode;
int setmode, width, height;
pcireg_t screg;
uint32_t reg;
sc->sc_dev = self;
sc->sc_pc = pa->pa_pc;
sc->sc_pcitag = pa->pa_tag;
sc->sc_dacw = -1;
@ -510,16 +522,24 @@ mach64_attach(device_t parent, device_t self, void *aux)
sc->sc_ndev = pa->pa_device;
sc->sc_nfunc = pa->pa_function;
sc->sc_locked = 0;
sc->sc_iot = pa->pa_iot;
pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
aprint_normal(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
aprint_normal(": %s (rev. 0x%02x)\n", devinfo,
PCI_REVISION(pa->pa_class));
aprint_naive(": Graphics processor\n");
#ifdef DEBUG
printf(prop_dictionary_externalize(device_properties(self)));
#endif
/* enable memory and IO access */
/* enable memory and disable IO access */
screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
screg |= PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
pci_conf_write(sc->sc_pc, sc->sc_pcitag,PCI_COMMAND_STATUS_REG,screg);
if ((screg & PCI_FLAGS_MEM_ENABLED) == 0) {
screg |= PCI_FLAGS_IO_ENABLED;
screg |= PCI_FLAGS_MEM_ENABLED;
pci_conf_write(sc->sc_pc, sc->sc_pcitag,
PCI_COMMAND_STATUS_REG, screg);
}
for (bar = 0; bar < NBARS; bar++) {
reg = PCI_MAPREG_START + (bar * 4);
sc->sc_bars[bar].vb_type = pci_mapreg_type(sc->sc_pc,
@ -530,16 +550,63 @@ mach64_attach(device_t parent, device_t self, void *aux)
sc->sc_bars[bar].vb_busaddr = pci_conf_read(sc->sc_pc,
sc->sc_pcitag, reg) & 0xfffffff0;
}
printf("%s: aperture size %08x\n", device_xname(sc->sc_dev),
(uint32_t)sc->sc_apersize);
sc->sc_rom.vb_type = PCI_MAPREG_TYPE_ROM;
pci_mapreg_info(sc->sc_pc, sc->sc_pcitag, PCI_MAPREG_ROM,
sc->sc_rom.vb_type, &sc->sc_rom.vb_base,
&sc->sc_rom.vb_size, &sc->sc_rom.vb_flags);
sc->sc_memt = pa->pa_memt;
if (bus_space_map(sc->sc_memt, sc->sc_aperbase, sc->sc_apersize,
BUS_SPACE_MAP_LINEAR, &sc->sc_memh)) {
panic("%s: failed to map aperture", device_xname(sc->sc_dev));
}
sc->sc_aperture = (void *)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
sc->sc_regt = sc->sc_memt;
bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
sc->sc_regsize, &sc->sc_regh);
sc->sc_registers = (char *)sc->sc_aperture + 0x7ffc00;
mach64_init(sc);
aprint_normal_dev(&sc->sc_dev,
aprint_normal_dev(sc->sc_dev,
"%d MB aperture at 0x%08x, %d KB registers at 0x%08x\n",
(u_int)(sc->sc_apersize / (1024 * 1024)),
(u_int)sc->sc_aperphys, (u_int)(sc->sc_regsize / 1024),
(u_int)sc->sc_regphys);
printf("%s: %d KB ROM at 0x%08x\n", device_xname(sc->sc_dev),
(int)sc->sc_rom.vb_size >> 10, (uint32_t)sc->sc_rom.vb_base);
prop_dictionary_get_uint32(device_properties(self), "width", &width);
prop_dictionary_get_uint32(device_properties(self), "height", &height);
if ((edid_data = prop_dictionary_get(device_properties(self), "EDIDDD"))
!= NULL) {
struct edid_info ei;
sc->sc_edid_size = min(1024, prop_data_size(edid_data));
memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data));
memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data),
sc->sc_edid_size);
edid_parse(sc->sc_edid_data, &ei);
#ifdef DEBUG
edid_print(&ei);
#endif
if (ei.edid_have_range) {
/* ei has dotclock in MHz, struct videomode in kHz */
mode = pick_mode_by_dotclock(width, height,
ei.edid_range.er_max_clock * 1000);
if (mode != NULL)
printf("mode: %s\n", mode->name);
}
}
if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_CT ||
((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
@ -559,21 +626,26 @@ mach64_attach(device_t parent, device_t self, void *aux)
if ((mach64_chip_id == PCI_PRODUCT_ATI_RAGE_XL_PCI) ||
((mach64_chip_id >= PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI) &&
(mach64_chip_id <= PCI_PRODUCT_ATI_RAGE_LT_PRO))) {
aprint_normal_dev(&sc->sc_dev, "ref_freq=29.498MHz\n");
aprint_normal_dev(sc->sc_dev, "ref_freq=29.498MHz\n");
sc->ref_freq = 29498;
} else
sc->ref_freq = 14318;
regwb(sc, CLOCK_CNTL + 1, PLL_REF_DIV << 2);
sc->ref_div = regrb(sc, CLOCK_CNTL + 2);
regwb(sc, CLOCK_CNTL + 1, MCLK_FB_DIV << 2);
sc->mclk_fb_div = regrb(sc, CLOCK_CNTL + 2);
reg = regr(sc, CLOCK_CNTL);
printf("CLOCK_CNTL: %08x\n", reg);
sc->sc_clock = reg & 3;
printf("using clock %d\n", sc->sc_clock);
sc->ref_div = regrb_pll(sc, PLL_REF_DIV);
printf("ref_div: %d\n", sc->ref_div);
sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV);
printf("mclk_fb_div: %d\n", sc->mclk_fb_div);
sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) /
(sc->ref_div * 2);
sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) /
(sc->mem_freq * sc->ref_div);
sc->ramdac_freq = mach64_get_max_ramdac(sc);
aprint_normal_dev(&sc->sc_dev,
aprint_normal_dev(sc->sc_dev,
"%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n",
(u_long)sc->memsize,
mach64_memtype_names[sc->memtype],
@ -582,19 +654,24 @@ mach64_attach(device_t parent, device_t self, void *aux)
id = regr(sc, CONFIG_CHIP_ID) & 0xffff;
if (id != mach64_chip_id) {
aprint_error_dev(&sc->sc_dev,
aprint_error_dev(sc->sc_dev,
"chip ID mismatch, 0x%x != 0x%x\n", id, mach64_chip_id);
return;
}
sc->sc_console = mach64_is_console(pa);
sc->sc_console = mach64_is_console(sc);
#ifdef DIAGNOSTIC
aprint_normal("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL));
#endif
#if defined(__sparc__) || defined(__powerpc__)
if (sc->sc_console) {
if (mode != NULL) {
memcpy(&default_mode, mode, sizeof(struct videomode));
setmode = 1;
} else {
mach64_get_mode(sc, &default_mode);
setmode = 0;
}
sc->sc_my_mode = &default_mode;
} else {
/* fill in default_mode if it's empty */
@ -625,13 +702,16 @@ mach64_attach(device_t parent, device_t self, void *aux)
sc->color_depth = CRTC_PIX_WIDTH_8BPP;
mach64_init_engine(sc);
if (setmode)
mach64_modeswitch(sc, sc->sc_my_mode);
#if 0
mach64_adjust_frame(0, 0);
if (sc->bits_per_pixel == 8)
mach64_init_lut(sc);
#endif
aprint_normal_dev(&sc->sc_dev,
aprint_normal_dev(sc->sc_dev,
"initial resolution %dx%d at %d bpp\n",
sc->sc_my_mode->hdisplay, sc->sc_my_mode->vdisplay,
sc->bits_per_pixel);
@ -646,6 +726,10 @@ mach64_attach(device_t parent, device_t self, void *aux)
vcons_init(&sc->vd, sc, &mach64_defaultscreen, &mach64_accessops);
sc->vd.init_screen = mach64_init_screen;
mach64_init_lut(sc);
mach64_clearscreen(sc);
machfb_blank(sc, 0); /* unblank the screen */
if (sc->sc_console) {
vcons_init_screen(&sc->vd, &mach64_console_screen, 1,
&defattr);
@ -657,6 +741,7 @@ mach64_attach(device_t parent, device_t self, void *aux)
mach64_defaultscreen.nrows = ri->ri_rows;
mach64_defaultscreen.ncols = ri->ri_cols;
wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr);
vcons_replay_msgbuf(&mach64_console_screen);
} else {
/*
* since we're not the console we can postpone the rest
@ -665,16 +750,22 @@ mach64_attach(device_t parent, device_t self, void *aux)
mach64_modeswitch(sc, sc->sc_my_mode);
}
mach64_init_lut(sc);
mach64_clearscreen(sc);
machfb_blank(sc, 0); /* unblank the screen */
aa.console = sc->sc_console;
aa.scrdata = &mach64_screenlist;
aa.accessops = &mach64_accessops;
aa.accesscookie = &sc->vd;
config_found(self, &aa, wsemuldisplaydevprint);
config_found_ia(self, "drm", aux, machfb_drm_print);
}
static int
machfb_drm_print(void *aux, const char *pnp)
{
if (pnp)
aprint_normal("direct rendering for %s", pnp);
return (UNSUPP);
}
static void
@ -698,7 +789,7 @@ mach64_init_screen(void *cookie, struct vcons_screen *scr, int existing,
ri->ri_flg |= RI_CLEAR;
if (setmode && mach64_set_screentype(sc, scr->scr_type)) {
panic("%s: failed to switch video mode",
device_xname(&sc->sc_dev));
device_xname(sc->sc_dev));
}
}
@ -717,7 +808,6 @@ mach64_init_screen(void *cookie, struct vcons_screen *scr, int existing,
ri->ri_ops.erasecols = mach64_erasecols;
ri->ri_ops.cursor = mach64_cursor;
ri->ri_ops.putchar = mach64_putchar;
ri->ri_ops.allocattr = mach64_allocattr;
}
static void
@ -727,17 +817,6 @@ mach64_init(struct mach64_softc *sc)
uint8_t *p;
int need_swap;
if (bus_space_map(sc->sc_memt, sc->sc_aperbase, sc->sc_apersize,
BUS_SPACE_MAP_LINEAR, &sc->sc_memh)) {
panic("%s: failed to map aperture", device_xname(&sc->sc_dev));
}
sc->sc_aperture = (void *)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
sc->sc_regt = sc->sc_memt;
bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
sc->sc_regsize, &sc->sc_regh);
sc->sc_registers = (char *)sc->sc_aperture + 0x7ffc00;
/*
* Test wether the aperture is byte swapped or not
*/
@ -751,8 +830,11 @@ mach64_init(struct mach64_softc *sc)
need_swap = 1;
if (need_swap) {
sc->sc_aperture = (char *)sc->sc_aperture + 0x800000;
#if 0
/* what the fsck is this for? */
sc->sc_aperbase += 0x800000;
sc->sc_apersize -= 0x800000;
#endif
}
*p32 = saved_value;
@ -768,7 +850,7 @@ mach64_get_memsize(struct mach64_softc *sc)
};
tmp = regr(sc, MEM_CNTL);
#ifdef DIAGNOSTIC
aprint_debug_dev(&sc->sc_dev, "memctl %08x\n", tmp);
aprint_debug_dev(sc->sc_dev, "memctl %08x\n", tmp);
#endif
if (sc->has_dsp) {
tmp &= 0x0000000f;
@ -890,7 +972,7 @@ mach64_set_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc)
if (sc->has_dsp)
mach64_set_dsp(sc);
#if 1
regw(sc, CRTC_H_TOTAL_DISP, crtc->h_total_disp);
regw(sc, CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
regw(sc, CRTC_V_TOTAL_DISP, crtc->v_total_disp);
@ -906,6 +988,7 @@ mach64_set_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc)
CRTC_CSYNC_EN |
#endif
CRTC_EXT_DISP_EN | CRTC_EXT_EN);
#endif
}
static int
@ -917,7 +1000,12 @@ mach64_modeswitch(struct mach64_softc *sc, struct videomode *mode)
if (mach64_calc_crtcregs(sc, &crtc, mode))
return 1;
aprint_debug("crtc dot clock: %d\n", crtc.dot_clock);
if (crtc.dot_clock == 0) {
aprint_error("%s: preposterous dot clock (%d)\n",
device_xname(sc->sc_dev), crtc.dot_clock);
return 1;
}
mach64_set_crtcregs(sc, &crtc);
return 0;
}
@ -1006,13 +1094,11 @@ mach64_init_engine(struct mach64_softc *sc)
/* We want 8 bit per channel */
regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
break;
#if 0
case 32:
regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP);
regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP);
regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
break;
#endif
}
wait_for_fifo(sc, 5);
@ -1043,7 +1129,8 @@ mach64_set_dsp(struct mach64_softc *sc)
uint32_t xclks_per_qw, y;
uint32_t fifo_off, fifo_on;
aprint_normal_dev(&sc->sc_dev, "initializing the DSP\n");
aprint_normal_dev(sc->sc_dev, "initializing the DSP\n");
if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II ||
mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIP ||
@ -1108,7 +1195,7 @@ mach64_set_dsp(struct mach64_softc *sc)
dsp_on = fifo_on >> dsp_precision;
dsp_off = fifo_off >> dsp_precision;
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n"
"dsp_precision = %d, dsp_loop_latency = %d,\n"
"mclk_fb_div = %d, vclk_fb_div = %d,\n"
@ -1127,10 +1214,12 @@ mach64_set_dsp(struct mach64_softc *sc)
static void
mach64_set_pll(struct mach64_softc *sc, int clock)
{
int q;
uint32_t q, clockreg;
int clockshift = sc->sc_clock << 1;
uint8_t reg, vclk_ctl;
q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq);
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
printf("q = %d\n", q);
#endif
if (q > 25500) {
@ -1156,10 +1245,27 @@ mach64_set_pll(struct mach64_softc *sc, int clock)
sc->log2_vclk_post_div = 3;
}
sc->vclk_fb_div = q * sc->vclk_post_div / 100;
printf("post_div: %d log2_post_div: %d mclk_div: %d\n", sc->vclk_post_div, sc->log2_vclk_post_div, sc->mclk_fb_div);
vclk_ctl = regrb_pll(sc, PLL_VCLK_CNTL);
printf("vclk_ctl: %02x\n", vclk_ctl);
vclk_ctl |= PLL_VCLK_RESET;
regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl);
regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div);
regwb_pll(sc, VCLK_POST_DIV, sc->log2_vclk_post_div);
regwb_pll(sc, VCLK0_FB_DIV, sc->vclk_fb_div);
reg = regrb_pll(sc, VCLK_POST_DIV);
reg &= ~(3 << clockshift);
reg |= (sc->log2_vclk_post_div << clockshift);
regwb_pll(sc, VCLK_POST_DIV, reg);
regwb_pll(sc, VCLK0_FB_DIV + sc->sc_clock, sc->vclk_fb_div);
vclk_ctl &= ~PLL_VCLK_RESET;
regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl);
clockreg = regr(sc, CLOCK_CNTL);
clockreg &= ~CLOCK_SEL;
clockreg |= sc->sc_clock | CLOCK_STROBE;
regw(sc, CLOCK_CNTL, clockreg);
}
static void
@ -1273,28 +1379,13 @@ mach64_set_screentype(struct mach64_softc *sc, const struct wsscreen_descr *des)
}
static int
mach64_is_console(struct pci_attach_args *pa)
mach64_is_console(struct mach64_softc *sc)
{
#ifdef __sparc__
int node;
bool console = 0;
node = PCITAG_NODE(pa->pa_tag);
if (node == -1)
return 0;
return (node == prom_instance_to_package(prom_stdout()));
#elif defined(__powerpc__)
/* check if we're the /chosen console device */
int chosen, stdout, node, us;
us = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "stdout", &stdout, 4);
node = OF_instance_to_package(stdout);
return (us == node);
#else
return 1;
#endif
prop_dictionary_get_bool(device_properties(sc->sc_dev),
"is_console", &console);
return console;
}
/*
@ -1348,6 +1439,7 @@ static void
mach64_putchar(void *cookie, int row, int col, u_int c, long attr)
{
struct rasops_info *ri = cookie;
struct wsdisplay_font *font = PICK_FONT(ri, c);
struct vcons_screen *scr = ri->ri_hw;
struct mach64_softc *sc = scr->scr_cookie;
@ -1355,20 +1447,20 @@ mach64_putchar(void *cookie, int row, int col, u_int c, long attr)
int fg, bg, uc;
uint8_t *data;
int x, y, wi, he;
wi = ri->ri_font->fontwidth;
he = ri->ri_font->fontheight;
wi = font->fontwidth;
he = font->fontheight;
if (!CHAR_IN_FONT(c, ri->ri_font))
if (!CHAR_IN_FONT(c, font))
return;
bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0x0f];
fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0x0f];
x = ri->ri_xorigin + col * wi;
y = ri->ri_yorigin + row * he;
if (c == 0x20) {
mach64_rectfill(sc, x, y, wi, he, bg);
} else {
uc = c-ri->ri_font->firstchar;
data = (uint8_t *)ri->ri_font->data + uc *
uc = c - font->firstchar;
data = (uint8_t *)font->data + uc *
ri->ri_fontscale;
mach64_setup_mono(sc, x, y, wi, he, fg, bg);
@ -1573,18 +1665,6 @@ mach64_showpal(struct mach64_softc *sc)
}
#endif
static int
mach64_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
{
if ((fg == 0) && (bg == 0))
{
fg = WS_DEFAULT_FG;
bg = WS_DEFAULT_BG;
}
*attrp = (fg & 0xf) << 24 | (bg & 0xf) << 16 | (flags & 0xff) << 8;
return 0;
}
/*
* wsdisplay_accessops
*/
@ -1640,6 +1720,11 @@ mach64_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
if ((new_mode == WSDISPLAYIO_MODE_EMUL)
&& (ms != NULL))
{
/* restore initial video mode */
mach64_init(sc);
mach64_init_engine(sc);
mach64_init_lut(sc);
mach64_modeswitch(sc, sc->sc_my_mode);
vcons_redraw_screen(ms);
}
}
@ -1679,9 +1764,6 @@ mach64_mmap(void *v, void *vs, off_t offset, int prot)
*/
if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER,
NULL) != 0) {
#if 0
printf("%s: mmap() rejected.\n", device_xname(&sc->sc_dev));
#endif
return -1;
}
@ -1689,7 +1771,7 @@ mach64_mmap(void *v, void *vs, off_t offset, int prot)
if (reg != sc->sc_regphys) {
#ifdef DIAGNOSTIC
printf("%s: BAR 0x18 changed! (%x %x)\n",
device_xname(&sc->sc_dev), (uint32_t)sc->sc_regphys,
device_xname(sc->sc_dev), (uint32_t)sc->sc_regphys,
(uint32_t)reg);
#endif
sc->sc_regphys = reg;
@ -1699,21 +1781,12 @@ mach64_mmap(void *v, void *vs, off_t offset, int prot)
if (reg != sc->sc_aperphys) {
#ifdef DIAGNOSTIC
printf("%s: BAR 0x10 changed! (%x %x)\n",
device_xname(&sc->sc_dev), (uint32_t)sc->sc_aperphys,
device_xname(sc->sc_dev), (uint32_t)sc->sc_aperphys,
(uint32_t)reg);
#endif
sc->sc_aperphys = reg;
}
#if 0
/* evil hack to allow mmap()ing other devices as well */
if ((offset > 0x80000000) && (offset <= 0xffffffff)) {
pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
BUS_SPACE_MAP_LINEAR);
return pa;
}
#endif
if ((offset >= sc->sc_aperphys) &&
(offset < (sc->sc_aperphys + sc->sc_apersize))) {
pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
@ -1728,6 +1801,21 @@ mach64_mmap(void *v, void *vs, off_t offset, int prot)
return pa;
}
if ((offset >= sc->sc_rom.vb_base) &&
(offset < (sc->sc_rom.vb_base + sc->sc_rom.vb_size))) {
pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
BUS_SPACE_MAP_LINEAR);
return pa;
}
#ifdef PCI_MAGIC_IO_RANGE
if ((offset >= PCI_MAGIC_IO_RANGE) &&
(offset <= PCI_MAGIC_IO_RANGE + 0x10000)) {
return bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE,
0, prot, BUS_SPACE_MAP_LINEAR);
}
#endif
return -1;
}
@ -1791,14 +1879,14 @@ machfb_fbattach(struct mach64_softc *sc)
{
struct fbdevice *fb = &sc->sc_fb;
fb->fb_device = &sc->sc_dev;
fb->fb_device = sc->sc_dev;
fb->fb_driver = &machfb_fbdriver;
fb->fb_type.fb_cmsize = 256;
fb->fb_type.fb_size = sc->memsize;
fb->fb_type.fb_type = FBTYPE_GENERIC_PCI;
fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags & FB_USERMASK;
fb->fb_flags = sc->sc_dev->dv_cfdata->cf_flags & FB_USERMASK;
fb->fb_type.fb_depth = sc->bits_per_pixel;
fb->fb_type.fb_width = sc->virt_x;
fb->fb_type.fb_height = sc->virt_y;
@ -1817,7 +1905,7 @@ machfb_fbopen(dev_t dev, int flags, int mode, struct lwp *l)
return ENXIO;
sc->sc_locked = 1;
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
printf("machfb_fbopen(%d)\n", minor(dev));
#endif
return 0;
@ -1828,7 +1916,7 @@ machfb_fbclose(dev_t dev, int flags, int mode, struct lwp *l)
{
struct mach64_softc *sc = device_lookup_private(&machfb_cd, minor(dev));
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
printf("machfb_fbclose()\n");
#endif
mach64_init_engine(sc);
@ -1842,7 +1930,7 @@ machfb_fbioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
{
struct mach64_softc *sc = device_lookup_private(&machfb_cd, minor(dev));
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
printf("machfb_fbioctl(%d, %lx)\n", minor(dev), cmd);
#endif
switch (cmd) {
@ -1919,19 +2007,19 @@ machfb_fbioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
ret = pci_devioctl(sc->sc_pc, sc->sc_pcitag,
cmd, data, flags, l);
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
printf("pci_devioctl: %d\n", ret);
#endif
return ret;
}
default:
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
log(LOG_NOTICE, "machfb_fbioctl(0x%lx) (%s[%d])\n", cmd,
p->p_comm, p->p_pid);
#endif
return ENOTTY;
}
#ifdef DEBUG_MACHFB
#ifdef MACHFB_DEBUG
printf("machfb_fbioctl done\n");
#endif
return 0;