Module Name: src Committed By: macallan Date: Tue May 4 05:07:14 UTC 2010
Modified Files: src/sys/dev/pci: machfb.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.59 src/sys/dev/pci/machfb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/machfb.c diff -u src/sys/dev/pci/machfb.c:1.58 src/sys/dev/pci/machfb.c:1.59 --- src/sys/dev/pci/machfb.c:1.58 Thu Mar 11 04:00:36 2010 +++ src/sys/dev/pci/machfb.c Tue May 4 05:07:14 2010 @@ -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 @@ #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 @@ #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 mach64_softc { - struct device sc_dev; + device_t sc_dev; #ifdef __sparc__ struct fbdevice sc_fb; #endif @@ -111,6 +108,7 @@ 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 @@ 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 @@ { 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 @@ { 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 @@ 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_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_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 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 @@ 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 @@ 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 @@ 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, @@ -528,18 +548,65 @@ sc->sc_bars[bar].vb_type, &sc->sc_bars[bar].vb_base, &sc->sc_bars[bar].vb_size, &sc->sc_bars[bar].vb_flags); sc->sc_bars[bar].vb_busaddr = pci_conf_read(sc->sc_pc, - sc->sc_pcitag, reg)&0xfffffff0; + 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 @@ 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 @@ 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) { - mach64_get_mode(sc, &default_mode); - setmode = 0; + 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 @@ 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 @@ 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_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 @@ -664,17 +749,23 @@ */ 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,12 +789,12 @@ 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)); } } - rasops_init(ri, sc->sc_my_mode->vdisplay/8, - sc->sc_my_mode->hdisplay/8); + rasops_init(ri, sc->sc_my_mode->vdisplay / 8, + sc->sc_my_mode->hdisplay / 8); ri->ri_caps = WSSCREEN_WSCOLORS; rasops_reconfig(ri, sc->sc_my_mode->vdisplay / ri->ri_font->fontheight, @@ -717,7 +808,6 @@ 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 @@ 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 @@ 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 @@ }; 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 @@ 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 @@ CRTC_CSYNC_EN | #endif CRTC_EXT_DISP_EN | CRTC_EXT_EN); +#endif } static int @@ -917,7 +1000,12 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } static int -mach64_is_console(struct pci_attach_args *pa) +mach64_is_console(struct mach64_softc *sc) { -#ifdef __sparc__ - int node; - - node = PCITAG_NODE(pa->pa_tag); - if (node == -1) - return 0; + bool console = 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 @@ 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 @@ 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 @@ } #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 @@ 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 @@ */ 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 @@ 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,35 +1781,41 @@ 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)) { + if ((offset >= sc->sc_aperphys) && + (offset < (sc->sc_aperphys + sc->sc_apersize))) { 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))) { + if ((offset >= sc->sc_regphys) && + (offset < (sc->sc_regphys + sc->sc_regsize))) { pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, BUS_SPACE_MAP_LINEAR); return pa; } - if ((offset >= sc->sc_regphys) && - (offset < (sc->sc_regphys + sc->sc_regsize))) { + 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 @@ { 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 @@ 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 @@ { 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 @@ { 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 @@ 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;