| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: machfb.c,v 1.97 2019/02/05 06:12:39 mrg Exp $ */ | | 1 | /* $NetBSD: machfb.c,v 1.97.4.1 2020/04/16 14:02:36 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2002 Bang Jun-Young | | 4 | * Copyright (c) 2002 Bang Jun-Young |
5 | * Copyright (c) 2005, 2006, 2007 Michael Lorenz | | 5 | * Copyright (c) 2005, 2006, 2007 Michael Lorenz |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -24,27 +24,27 @@ | | | @@ -24,27 +24,27 @@ |
24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | */ | | 29 | */ |
30 | | | 30 | |
31 | /* | | 31 | /* |
32 | * Some code is derived from ATI Rage Pro and Derivatives Programmer's Guide. | | 32 | * Some code is derived from ATI Rage Pro and Derivatives Programmer's Guide. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | __KERNEL_RCSID(0, | | 36 | __KERNEL_RCSID(0, |
37 | "$NetBSD: machfb.c,v 1.97 2019/02/05 06:12:39 mrg Exp $"); | | 37 | "$NetBSD: machfb.c,v 1.97.4.1 2020/04/16 14:02:36 martin Exp $"); |
38 | | | 38 | |
39 | #include <sys/param.h> | | 39 | #include <sys/param.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/kernel.h> | | 41 | #include <sys/kernel.h> |
42 | #include <sys/device.h> | | 42 | #include <sys/device.h> |
43 | #include <sys/malloc.h> | | 43 | #include <sys/malloc.h> |
44 | #include <sys/callout.h> | | 44 | #include <sys/callout.h> |
45 | #include <sys/lwp.h> | | 45 | #include <sys/lwp.h> |
46 | #include <sys/kauth.h> | | 46 | #include <sys/kauth.h> |
47 | | | 47 | |
48 | #include <dev/videomode/videomode.h> | | 48 | #include <dev/videomode/videomode.h> |
49 | #include <dev/videomode/edidvar.h> | | 49 | #include <dev/videomode/edidvar.h> |
50 | | | 50 | |
| @@ -58,26 +58,32 @@ __KERNEL_RCSID(0, | | | @@ -58,26 +58,32 @@ __KERNEL_RCSID(0, |
58 | | | 58 | |
59 | #include <dev/wscons/wsconsio.h> | | 59 | #include <dev/wscons/wsconsio.h> |
60 | #include <dev/wsfont/wsfont.h> | | 60 | #include <dev/wsfont/wsfont.h> |
61 | #include <dev/rasops/rasops.h> | | 61 | #include <dev/rasops/rasops.h> |
62 | #include <dev/pci/wsdisplay_pci.h> | | 62 | #include <dev/pci/wsdisplay_pci.h> |
63 | | | 63 | |
64 | #include <dev/wscons/wsdisplay_vconsvar.h> | | 64 | #include <dev/wscons/wsdisplay_vconsvar.h> |
65 | #include <dev/wscons/wsdisplay_glyphcachevar.h> | | 65 | #include <dev/wscons/wsdisplay_glyphcachevar.h> |
66 | | | 66 | |
67 | #include "opt_wsemul.h" | | 67 | #include "opt_wsemul.h" |
68 | #include "opt_machfb.h" | | 68 | #include "opt_machfb.h" |
69 | #include "opt_glyphcache.h" | | 69 | #include "opt_glyphcache.h" |
70 | | | 70 | |
| | | 71 | #ifdef MACHFB_DEBUG |
| | | 72 | #define DPRINTF printf |
| | | 73 | #else |
| | | 74 | #define DPRINTF while (0) printf |
| | | 75 | #endif |
| | | 76 | |
71 | #define MACH64_REG_SIZE 0x800 | | 77 | #define MACH64_REG_SIZE 0x800 |
72 | #define MACH64_REG_OFF 0x7ff800 | | 78 | #define MACH64_REG_OFF 0x7ff800 |
73 | | | 79 | |
74 | #define NBARS 3 /* number of Mach64 PCI BARs */ | | 80 | #define NBARS 3 /* number of Mach64 PCI BARs */ |
75 | | | 81 | |
76 | struct vga_bar { | | 82 | struct vga_bar { |
77 | bus_addr_t vb_base; | | 83 | bus_addr_t vb_base; |
78 | bus_size_t vb_size; | | 84 | bus_size_t vb_size; |
79 | pcireg_t vb_type; | | 85 | pcireg_t vb_type; |
80 | int vb_flags; | | 86 | int vb_flags; |
81 | }; | | 87 | }; |
82 | | | 88 | |
83 | struct mach64_softc { | | 89 | struct mach64_softc { |
| @@ -130,26 +136,27 @@ struct mach64_softc { | | | @@ -130,26 +136,27 @@ struct mach64_softc { |
130 | int ref_div; | | 136 | int ref_div; |
131 | int log2_vclk_post_div; | | 137 | int log2_vclk_post_div; |
132 | int vclk_post_div; | | 138 | int vclk_post_div; |
133 | int vclk_fb_div; | | 139 | int vclk_fb_div; |
134 | int mclk_post_div; | | 140 | int mclk_post_div; |
135 | int mclk_fb_div; | | 141 | int mclk_fb_div; |
136 | int sc_clock; /* which clock to use */ | | 142 | int sc_clock; /* which clock to use */ |
137 | int minref, m; | | 143 | int minref, m; |
138 | | | 144 | |
139 | struct videomode *sc_my_mode; | | 145 | struct videomode *sc_my_mode; |
140 | int sc_edid_size; | | 146 | int sc_edid_size; |
141 | uint8_t sc_edid_data[1024]; | | 147 | uint8_t sc_edid_data[1024]; |
142 | struct edid_info sc_ei; | | 148 | struct edid_info sc_ei; |
| | | 149 | int sc_setmode; |
143 | | | 150 | |
144 | u_char sc_cmap_red[256]; | | 151 | u_char sc_cmap_red[256]; |
145 | u_char sc_cmap_green[256]; | | 152 | u_char sc_cmap_green[256]; |
146 | u_char sc_cmap_blue[256]; | | 153 | u_char sc_cmap_blue[256]; |
147 | int sc_dacw, sc_blanked, sc_console; | | 154 | int sc_dacw, sc_blanked, sc_console; |
148 | struct vcons_data vd; | | 155 | struct vcons_data vd; |
149 | struct wsdisplay_accessops sc_accessops; | | 156 | struct wsdisplay_accessops sc_accessops; |
150 | glyphcache sc_gc; | | 157 | glyphcache sc_gc; |
151 | }; | | 158 | }; |
152 | | | 159 | |
153 | struct mach64_crtcregs { | | 160 | struct mach64_crtcregs { |
154 | uint32_t h_total_disp; | | 161 | uint32_t h_total_disp; |
155 | uint32_t h_sync_strt_wid; | | 162 | uint32_t h_sync_strt_wid; |
| @@ -211,27 +218,29 @@ static const char *mach64_memtype_names[ | | | @@ -211,27 +218,29 @@ static const char *mach64_memtype_names[ |
211 | | | 218 | |
212 | extern const u_char rasops_cmap[768]; | | 219 | extern const u_char rasops_cmap[768]; |
213 | | | 220 | |
214 | static int mach64_match(device_t, cfdata_t, void *); | | 221 | static int mach64_match(device_t, cfdata_t, void *); |
215 | static void mach64_attach(device_t, device_t, void *); | | 222 | static void mach64_attach(device_t, device_t, void *); |
216 | | | 223 | |
217 | CFATTACH_DECL_NEW(machfb, sizeof(struct mach64_softc), mach64_match, | | 224 | CFATTACH_DECL_NEW(machfb, sizeof(struct mach64_softc), mach64_match, |
218 | mach64_attach, NULL, NULL); | | 225 | mach64_attach, NULL, NULL); |
219 | | | 226 | |
220 | static void mach64_init(struct mach64_softc *); | | 227 | static void mach64_init(struct mach64_softc *); |
221 | static int mach64_get_memsize(struct mach64_softc *); | | 228 | static int mach64_get_memsize(struct mach64_softc *); |
222 | static int mach64_get_max_ramdac(struct mach64_softc *); | | 229 | static int mach64_get_max_ramdac(struct mach64_softc *); |
223 | | | 230 | |
| | | 231 | #if 0 |
224 | static void mach64_get_mode(struct mach64_softc *, struct videomode *); | | 232 | static void mach64_get_mode(struct mach64_softc *, struct videomode *); |
| | | 233 | #endif |
225 | | | 234 | |
226 | static int mach64_calc_crtcregs(struct mach64_softc *, | | 235 | static int mach64_calc_crtcregs(struct mach64_softc *, |
227 | struct mach64_crtcregs *, | | 236 | struct mach64_crtcregs *, |
228 | struct videomode *); | | 237 | struct videomode *); |
229 | static void mach64_set_crtcregs(struct mach64_softc *, | | 238 | static void mach64_set_crtcregs(struct mach64_softc *, |
230 | struct mach64_crtcregs *); | | 239 | struct mach64_crtcregs *); |
231 | | | 240 | |
232 | static int mach64_modeswitch(struct mach64_softc *, struct videomode *); | | 241 | static int mach64_modeswitch(struct mach64_softc *, struct videomode *); |
233 | static void mach64_set_dsp(struct mach64_softc *); | | 242 | static void mach64_set_dsp(struct mach64_softc *); |
234 | static void mach64_set_pll(struct mach64_softc *, int); | | 243 | static void mach64_set_pll(struct mach64_softc *, int); |
235 | static void mach64_reset_engine(struct mach64_softc *); | | 244 | static void mach64_reset_engine(struct mach64_softc *); |
236 | static void mach64_init_engine(struct mach64_softc *); | | 245 | static void mach64_init_engine(struct mach64_softc *); |
237 | #if 0 | | 246 | #if 0 |
| @@ -398,44 +407,45 @@ mach64_match(device_t parent, cfdata_t m | | | @@ -398,44 +407,45 @@ mach64_match(device_t parent, cfdata_t m |
398 | static void | | 407 | static void |
399 | mach64_attach(device_t parent, device_t self, void *aux) | | 408 | mach64_attach(device_t parent, device_t self, void *aux) |
400 | { | | 409 | { |
401 | struct mach64_softc *sc = device_private(self); | | 410 | struct mach64_softc *sc = device_private(self); |
402 | struct pci_attach_args *pa = aux; | | 411 | struct pci_attach_args *pa = aux; |
403 | struct rasops_info *ri; | | 412 | struct rasops_info *ri; |
404 | prop_data_t edid_data; | | 413 | prop_data_t edid_data; |
405 | const struct videomode *mode = NULL; | | 414 | const struct videomode *mode = NULL; |
406 | int bar, id, expected_id; | | 415 | int bar, id, expected_id; |
407 | int is_gx; | | 416 | int is_gx; |
408 | const char **memtype_names; | | 417 | const char **memtype_names; |
409 | struct wsemuldisplaydev_attach_args aa; | | 418 | struct wsemuldisplaydev_attach_args aa; |
410 | long defattr; | | 419 | long defattr; |
411 | int setmode = 0, width, height; | | 420 | int width = 1024, height = 768; |
412 | pcireg_t screg; | | 421 | pcireg_t screg; |
413 | uint32_t reg; | | 422 | uint32_t reg; |
414 | const pcireg_t enables = PCI_COMMAND_MEM_ENABLE; | | 423 | const pcireg_t enables = PCI_COMMAND_MEM_ENABLE; |
415 | int use_mmio = FALSE; | | 424 | int use_mmio = FALSE; |
416 | | | 425 | |
417 | sc->sc_dev = self; | | 426 | sc->sc_dev = self; |
418 | sc->sc_pc = pa->pa_pc; | | 427 | sc->sc_pc = pa->pa_pc; |
419 | sc->sc_pcitag = pa->pa_tag; | | 428 | sc->sc_pcitag = pa->pa_tag; |
420 | sc->sc_dacw = -1; | | 429 | sc->sc_dacw = -1; |
421 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | | 430 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; |
422 | sc->sc_nbus = pa->pa_bus; | | 431 | sc->sc_nbus = pa->pa_bus; |
423 | sc->sc_ndev = pa->pa_device; | | 432 | sc->sc_ndev = pa->pa_device; |
424 | sc->sc_nfunc = pa->pa_function; | | 433 | sc->sc_nfunc = pa->pa_function; |
425 | sc->sc_locked = 0; | | 434 | sc->sc_locked = 0; |
426 | sc->sc_iot = pa->pa_iot; | | 435 | sc->sc_iot = pa->pa_iot; |
427 | sc->sc_accessops.ioctl = mach64_ioctl; | | 436 | sc->sc_accessops.ioctl = mach64_ioctl; |
428 | sc->sc_accessops.mmap = mach64_mmap; | | 437 | sc->sc_accessops.mmap = mach64_mmap; |
| | | 438 | sc->sc_setmode = 0; |
429 | | | 439 | |
430 | pci_aprint_devinfo(pa, "Graphics processor"); | | 440 | pci_aprint_devinfo(pa, "Graphics processor"); |
431 | #ifdef MACHFB_DEBUG | | 441 | #ifdef MACHFB_DEBUG |
432 | printf(prop_dictionary_externalize(device_properties(self))); | | 442 | printf(prop_dictionary_externalize(device_properties(self))); |
433 | #endif | | 443 | #endif |
434 | | | 444 | |
435 | /* enable memory access */ | | 445 | /* enable memory access */ |
436 | screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); | | 446 | screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); |
437 | if ((screg & enables) != enables) { | | 447 | if ((screg & enables) != enables) { |
438 | screg |= enables; | | 448 | screg |= enables; |
439 | pci_conf_write(sc->sc_pc, sc->sc_pcitag, | | 449 | pci_conf_write(sc->sc_pc, sc->sc_pcitag, |
440 | PCI_COMMAND_STATUS_REG, screg); | | 450 | PCI_COMMAND_STATUS_REG, screg); |
441 | } | | 451 | } |
| @@ -488,42 +498,44 @@ mach64_attach(device_t parent, device_t | | | @@ -488,42 +498,44 @@ mach64_attach(device_t parent, device_t |
488 | | | 498 | |
489 | aprint_normal_dev(sc->sc_dev, | | 499 | aprint_normal_dev(sc->sc_dev, |
490 | "%d MB aperture at 0x%08x, %d KB registers at 0x%08x\n", | | 500 | "%d MB aperture at 0x%08x, %d KB registers at 0x%08x\n", |
491 | (u_int)(sc->sc_apersize / (1024 * 1024)), | | 501 | (u_int)(sc->sc_apersize / (1024 * 1024)), |
492 | (u_int)sc->sc_aperbase, (u_int)(sc->sc_regsize / 1024), | | 502 | (u_int)sc->sc_aperbase, (u_int)(sc->sc_regsize / 1024), |
493 | (u_int)sc->sc_regbase); | | 503 | (u_int)sc->sc_regbase); |
494 | | | 504 | |
495 | printf("%s: %d KB ROM at 0x%08x\n", device_xname(sc->sc_dev), | | 505 | printf("%s: %d KB ROM at 0x%08x\n", device_xname(sc->sc_dev), |
496 | (int)sc->sc_rom.vb_size >> 10, (uint32_t)sc->sc_rom.vb_base); | | 506 | (int)sc->sc_rom.vb_size >> 10, (uint32_t)sc->sc_rom.vb_base); |
497 | | | 507 | |
498 | prop_dictionary_get_uint32(device_properties(self), "width", &width); | | 508 | prop_dictionary_get_uint32(device_properties(self), "width", &width); |
499 | prop_dictionary_get_uint32(device_properties(self), "height", &height); | | 509 | prop_dictionary_get_uint32(device_properties(self), "height", &height); |
500 | | | 510 | |
| | | 511 | default_mode.hdisplay = width; |
| | | 512 | default_mode.vdisplay = height; |
| | | 513 | |
501 | memset(&sc->sc_ei, 0, sizeof(sc->sc_ei)); | | 514 | memset(&sc->sc_ei, 0, sizeof(sc->sc_ei)); |
502 | if ((edid_data = prop_dictionary_get(device_properties(self), "EDID")) | | 515 | if ((edid_data = prop_dictionary_get(device_properties(self), "EDID")) |
503 | != NULL) { | | 516 | != NULL) { |
504 | | | 517 | |
505 | sc->sc_edid_size = uimin(1024, prop_data_size(edid_data)); | | 518 | sc->sc_edid_size = uimin(1024, prop_data_size(edid_data)); |
506 | memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data)); | | 519 | memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data)); |
507 | memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data), | | 520 | memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data), |
508 | sc->sc_edid_size); | | 521 | sc->sc_edid_size); |
509 | | | 522 | |
510 | edid_parse(sc->sc_edid_data, &sc->sc_ei); | | 523 | edid_parse(sc->sc_edid_data, &sc->sc_ei); |
511 | | | 524 | |
512 | #ifdef MACHFB_DEBUG | | 525 | #ifdef MACHFB_DEBUG |
513 | edid_print(&sc->sc_ei); | | 526 | edid_print(&sc->sc_ei); |
514 | #endif | | 527 | #endif |
515 | } | | 528 | } |
516 | | | | |
517 | is_gx = 0; | | 529 | is_gx = 0; |
518 | switch(mach64_chip_id) { | | 530 | switch(mach64_chip_id) { |
519 | case PCI_PRODUCT_ATI_MACH64_GX: | | 531 | case PCI_PRODUCT_ATI_MACH64_GX: |
520 | case PCI_PRODUCT_ATI_MACH64_CX: | | 532 | case PCI_PRODUCT_ATI_MACH64_CX: |
521 | is_gx = 1; | | 533 | is_gx = 1; |
522 | /* FALLTHROUGH */ | | 534 | /* FALLTHROUGH */ |
523 | case PCI_PRODUCT_ATI_MACH64_CT: | | 535 | case PCI_PRODUCT_ATI_MACH64_CT: |
524 | sc->has_dsp = 0; | | 536 | sc->has_dsp = 0; |
525 | break; | | 537 | break; |
526 | case PCI_PRODUCT_ATI_MACH64_VT: | | 538 | case PCI_PRODUCT_ATI_MACH64_VT: |
527 | case PCI_PRODUCT_ATI_RAGE_II: | | 539 | case PCI_PRODUCT_ATI_RAGE_II: |
528 | if((mach64_chip_rev & 0x07) == 0) { | | 540 | if((mach64_chip_rev & 0x07) == 0) { |
529 | sc->has_dsp = 0; | | 541 | sc->has_dsp = 0; |
| @@ -551,38 +563,38 @@ mach64_attach(device_t parent, device_t | | | @@ -551,38 +563,38 @@ mach64_attach(device_t parent, device_t |
551 | ((mach64_chip_id >= PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI) && | | 563 | ((mach64_chip_id >= PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI) && |
552 | (mach64_chip_id <= PCI_PRODUCT_ATI_RAGE_LT_PRO))) { | | 564 | (mach64_chip_id <= PCI_PRODUCT_ATI_RAGE_LT_PRO))) { |
553 | aprint_normal_dev(sc->sc_dev, "ref_freq=29.498MHz\n"); | | 565 | aprint_normal_dev(sc->sc_dev, "ref_freq=29.498MHz\n"); |
554 | sc->ref_freq = 29498; | | 566 | sc->ref_freq = 29498; |
555 | } else | | 567 | } else |
556 | sc->ref_freq = 14318; | | 568 | sc->ref_freq = 14318; |
557 | | | 569 | |
558 | reg = regr(sc, CLOCK_CNTL); | | 570 | reg = regr(sc, CLOCK_CNTL); |
559 | aprint_debug("CLOCK_CNTL: %08x\n", reg); | | 571 | aprint_debug("CLOCK_CNTL: %08x\n", reg); |
560 | sc->sc_clock = reg & 3; | | 572 | sc->sc_clock = reg & 3; |
561 | aprint_debug("using clock %d\n", sc->sc_clock); | | 573 | aprint_debug("using clock %d\n", sc->sc_clock); |
562 | | | 574 | |
563 | sc->ref_div = regrb_pll(sc, PLL_REF_DIV); | | 575 | sc->ref_div = regrb_pll(sc, PLL_REF_DIV); |
564 | aprint_error("ref_div: %d\n", sc->ref_div); | | 576 | DPRINTF("ref_div: %d\n", sc->ref_div); |
565 | sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV); | | 577 | sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV); |
566 | aprint_error("mclk_fb_div: %d\n", sc->mclk_fb_div); | | 578 | DPRINTF("mclk_fb_div: %d\n", sc->mclk_fb_div); |
567 | sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) / | | 579 | sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) / |
568 | (sc->ref_div * 2); | | 580 | (sc->ref_div * 2); |
569 | sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) / | | 581 | sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) / |
570 | (sc->mem_freq * sc->ref_div); | | 582 | (sc->mem_freq * sc->ref_div); |
571 | sc->ramdac_freq = mach64_get_max_ramdac(sc); | | 583 | sc->ramdac_freq = mach64_get_max_ramdac(sc); |
572 | { | | 584 | { |
573 | sc->minref = sc->ramdac_freq / 510; | | 585 | sc->minref = sc->ramdac_freq / 510; |
574 | sc->m = sc->ref_freq / sc->minref; | | 586 | sc->m = sc->ref_freq / sc->minref; |
575 | aprint_error("minref: %d m: %d\n", sc->minref, sc->m); | | 587 | DPRINTF("minref: %d m: %d\n", sc->minref, sc->m); |
576 | } | | 588 | } |
577 | aprint_normal_dev(sc->sc_dev, | | 589 | aprint_normal_dev(sc->sc_dev, |
578 | "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n", | | 590 | "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n", |
579 | (u_long)sc->memsize, | | 591 | (u_long)sc->memsize, |
580 | memtype_names[sc->memtype], | | 592 | memtype_names[sc->memtype], |
581 | sc->mem_freq / 1000, sc->mem_freq % 1000, | | 593 | sc->mem_freq / 1000, sc->mem_freq % 1000, |
582 | sc->ramdac_freq / 1000); | | 594 | sc->ramdac_freq / 1000); |
583 | | | 595 | |
584 | id = regr(sc, CONFIG_CHIP_ID) & 0xffff; | | 596 | id = regr(sc, CONFIG_CHIP_ID) & 0xffff; |
585 | switch(mach64_chip_id) { | | 597 | switch(mach64_chip_id) { |
586 | case PCI_PRODUCT_ATI_MACH64_GX: | | 598 | case PCI_PRODUCT_ATI_MACH64_GX: |
587 | expected_id = 0x00d7; | | 599 | expected_id = 0x00d7; |
588 | break; | | 600 | break; |
| @@ -594,102 +606,109 @@ mach64_attach(device_t parent, device_t | | | @@ -594,102 +606,109 @@ mach64_attach(device_t parent, device_t |
594 | expected_id = mach64_chip_id; | | 606 | expected_id = mach64_chip_id; |
595 | } | | 607 | } |
596 | | | 608 | |
597 | if (id != expected_id) { | | 609 | if (id != expected_id) { |
598 | aprint_error_dev(sc->sc_dev, | | 610 | aprint_error_dev(sc->sc_dev, |
599 | "chip ID mismatch, 0x%x != 0x%x\n", id, expected_id); | | 611 | "chip ID mismatch, 0x%x != 0x%x\n", id, expected_id); |
600 | return; | | 612 | return; |
601 | } | | 613 | } |
602 | | | 614 | |
603 | sc->sc_console = mach64_is_console(sc); | | 615 | sc->sc_console = mach64_is_console(sc); |
604 | aprint_debug("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL)); | | 616 | aprint_debug("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL)); |
605 | | | 617 | |
606 | #define MODE_IS_VALID(m) ((sc->ramdac_freq >= (m)->dot_clock) && \ | | 618 | #define MODE_IS_VALID(m) ((sc->ramdac_freq >= (m)->dot_clock) && \ |
607 | ((m)->hdisplay <= 11280)) | | 619 | ((m)->hdisplay <= 1280)) |
608 | | | 620 | |
609 | /* no mode setting support on ancient chips with external clocks */ | | 621 | /* no mode setting support on ancient chips with external clocks */ |
610 | setmode = 0; | | 622 | sc->sc_setmode = 0; |
611 | if (!is_gx) { | | 623 | if (!is_gx) { |
612 | /* | | 624 | /* |
613 | * Now pick a mode. | | 625 | * Now pick a mode. |
614 | */ | | 626 | */ |
615 | if ((sc->sc_ei.edid_preferred_mode != NULL)) { | | 627 | if ((sc->sc_ei.edid_preferred_mode != NULL)) { |
616 | struct videomode *m = sc->sc_ei.edid_preferred_mode; | | 628 | struct videomode *m = sc->sc_ei.edid_preferred_mode; |
617 | if (MODE_IS_VALID(m)) { | | 629 | if (MODE_IS_VALID(m)) { |
618 | memcpy(&default_mode, m, | | 630 | memcpy(&default_mode, m, |
619 | sizeof(struct videomode)); | | 631 | sizeof(struct videomode)); |
620 | setmode = 1; | | 632 | sc->sc_setmode = 1; |
621 | } else { | | 633 | } else { |
622 | aprint_error_dev(sc->sc_dev, | | 634 | aprint_error_dev(sc->sc_dev, |
623 | "unable to use preferred mode\n"); | | 635 | "unable to use preferred mode\n"); |
624 | } | | 636 | } |
625 | } | | 637 | } |
626 | /* | | 638 | /* |
627 | * if we can't use the preferred mode go look for the | | 639 | * if we can't use the preferred mode go look for the |
628 | * best one we can support | | 640 | * best one we can support |
629 | */ | | 641 | */ |
630 | if (setmode == 0) { | | 642 | if (sc->sc_setmode == 0) { |
631 | struct videomode *m = sc->sc_ei.edid_modes; | | 643 | struct videomode *m = sc->sc_ei.edid_modes; |
632 | | | 644 | |
633 | mode = NULL; | | 645 | mode = NULL; |
634 | sort_modes(sc->sc_ei.edid_modes, | | 646 | sort_modes(sc->sc_ei.edid_modes, |
635 | &sc->sc_ei.edid_preferred_mode, | | 647 | &sc->sc_ei.edid_preferred_mode, |
636 | sc->sc_ei.edid_nmodes); | | 648 | sc->sc_ei.edid_nmodes); |
637 | for (int n = 0; n < sc->sc_ei.edid_nmodes; n++) | | 649 | for (int n = 0; n < sc->sc_ei.edid_nmodes; n++) |
638 | if (MODE_IS_VALID(&m[n])) { | | 650 | if (MODE_IS_VALID(&m[n])) { |
639 | mode = &m[n]; | | 651 | mode = &m[n]; |
640 | break; | | 652 | break; |
641 | } | | 653 | } |
642 | if (mode != NULL) { | | 654 | if (mode != NULL) { |
643 | memcpy(&default_mode, mode, | | 655 | memcpy(&default_mode, mode, |
644 | sizeof(struct videomode)); | | 656 | sizeof(struct videomode)); |
645 | setmode = 1; | | 657 | sc->sc_setmode = 1; |
646 | } | | 658 | } |
647 | } | | 659 | } |
648 | /* got nothing? try to pick one based on firmware parameters */ | | 660 | } |
649 | if (setmode == 0 && width > 0 && height > 0) { | | 661 | |
650 | /* no EDID data? */ | | 662 | /* make sure my_mode points at something sensible if the above fails */ |
651 | mode = pick_mode_by_ref(width, height, 60); | | 663 | if (default_mode.dot_clock == 0) { |
652 | memcpy(&default_mode, mode, sizeof(struct videomode)); | | 664 | sc->sc_setmode = 0; |
653 | setmode = 1; | | 665 | mode = pick_mode_by_ref(width, height, 60); |
654 | } | | 666 | if (mode != NULL) { |
655 | /* still nothing? Grab the default */ | | 667 | memcpy(&default_mode, mode, sizeof(default_mode)); |
656 | if (setmode == 0) { | | 668 | } else if ((width > 0) && (height > 0)) { |
| | | 669 | default_mode.hdisplay = width; |
| | | 670 | default_mode.vdisplay = height; |
| | | 671 | } else { |
| | | 672 | /* |
| | | 673 | * if we end up here we're probably dealing with |
| | | 674 | * uninitialized hardware - try to set 1024x768@60 and |
| | | 675 | * hope for the best... |
| | | 676 | */ |
657 | mode = pick_mode_by_ref(1024, 768, 60); | | 677 | mode = pick_mode_by_ref(1024, 768, 60); |
658 | memcpy(&default_mode, mode, sizeof(struct videomode)); | | 678 | if (mode == NULL) return; |
659 | setmode = 1; | | 679 | memcpy(&default_mode, mode, sizeof(default_mode)); |
660 | } | | 680 | if (!is_gx) sc->sc_setmode = 1; |
661 | } else { | | 681 | } |
662 | /* make sure my_mode points at something sensible */ | | | |
663 | mach64_get_mode(sc, &default_mode); | | | |
664 | if (default_mode.dot_clock == 0) { | | | |
665 | memcpy(&default_mode, pick_mode_by_ref(width, height, 60), | | | |
666 | sizeof(default_mode)); | | | |
667 | } | | | |
668 | } | | 682 | } |
| | | 683 | |
669 | sc->sc_my_mode = &default_mode; | | 684 | sc->sc_my_mode = &default_mode; |
670 | | | 685 | |
| | | 686 | if ((width == sc->sc_my_mode->hdisplay) && |
| | | 687 | (height == sc->sc_my_mode->vdisplay)) |
| | | 688 | sc->sc_setmode = 0; |
| | | 689 | |
671 | sc->bits_per_pixel = 8; | | 690 | sc->bits_per_pixel = 8; |
672 | sc->virt_x = sc->sc_my_mode->hdisplay; | | 691 | sc->virt_x = sc->sc_my_mode->hdisplay; |
673 | sc->virt_y = sc->sc_my_mode->vdisplay; | | 692 | sc->virt_y = sc->sc_my_mode->vdisplay; |
674 | sc->max_x = sc->virt_x - 1; | | 693 | sc->max_x = sc->virt_x - 1; |
675 | sc->max_y = (sc->memsize * 1024) / | | 694 | sc->max_y = (sc->memsize * 1024) / |
676 | (sc->virt_x * (sc->bits_per_pixel / 8)) - 1; | | 695 | (sc->virt_x * (sc->bits_per_pixel / 8)) - 1; |
677 | | | 696 | |
678 | sc->color_depth = CRTC_PIX_WIDTH_8BPP; | | 697 | sc->color_depth = CRTC_PIX_WIDTH_8BPP; |
679 | | | 698 | |
680 | mach64_init_engine(sc); | | 699 | mach64_init_engine(sc); |
681 | | | 700 | |
682 | if (setmode) | | 701 | if (sc->sc_setmode) |
683 | mach64_modeswitch(sc, sc->sc_my_mode); | | 702 | mach64_modeswitch(sc, sc->sc_my_mode); |
684 | | | 703 | |
685 | aprint_normal_dev(sc->sc_dev, | | 704 | aprint_normal_dev(sc->sc_dev, |
686 | "initial resolution %dx%d at %d bpp\n", | | 705 | "initial resolution %dx%d at %d bpp\n", |
687 | sc->sc_my_mode->hdisplay, sc->sc_my_mode->vdisplay, | | 706 | sc->sc_my_mode->hdisplay, sc->sc_my_mode->vdisplay, |
688 | sc->bits_per_pixel); | | 707 | sc->bits_per_pixel); |
689 | | | 708 | |
690 | wsfont_init(); | | 709 | wsfont_init(); |
691 | | | 710 | |
692 | #ifdef GLYPHCACHE_DEBUG | | 711 | #ifdef GLYPHCACHE_DEBUG |
693 | /* shrink the screen so we can see part of the glyph cache */ | | 712 | /* shrink the screen so we can see part of the glyph cache */ |
694 | sc->sc_my_mode->vdisplay -= 200; | | 713 | sc->sc_my_mode->vdisplay -= 200; |
695 | #endif | | 714 | #endif |
| @@ -717,27 +736,26 @@ mach64_attach(device_t parent, device_t | | | @@ -717,27 +736,26 @@ mach64_attach(device_t parent, device_t |
717 | glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, | | 736 | glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, |
718 | ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) - | | 737 | ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) - |
719 | sc->sc_my_mode->vdisplay - 5, | | 738 | sc->sc_my_mode->vdisplay - 5, |
720 | sc->sc_my_mode->hdisplay, | | 739 | sc->sc_my_mode->hdisplay, |
721 | ri->ri_font->fontwidth, | | 740 | ri->ri_font->fontwidth, |
722 | ri->ri_font->fontheight, | | 741 | ri->ri_font->fontheight, |
723 | defattr); | | 742 | defattr); |
724 | wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr); | | 743 | wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr); |
725 | } else { | | 744 | } else { |
726 | /* | | 745 | /* |
727 | * since we're not the console we can postpone the rest | | 746 | * since we're not the console we can postpone the rest |
728 | * until someone actually allocates a screen for us | | 747 | * until someone actually allocates a screen for us |
729 | */ | | 748 | */ |
730 | mach64_modeswitch(sc, sc->sc_my_mode); | | | |
731 | if (mach64_console_screen.scr_ri.ri_rows == 0) { | | 749 | if (mach64_console_screen.scr_ri.ri_rows == 0) { |
732 | /* do some minimal setup to avoid weirdnesses later */ | | 750 | /* do some minimal setup to avoid weirdnesses later */ |
733 | vcons_init_screen(&sc->vd, &mach64_console_screen, 1, | | 751 | vcons_init_screen(&sc->vd, &mach64_console_screen, 1, |
734 | &defattr); | | 752 | &defattr); |
735 | } else | | 753 | } else |
736 | (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); | | 754 | (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); |
737 | | | 755 | |
738 | glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, | | 756 | glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, |
739 | ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) - | | 757 | ((sc->memsize * 1024) / sc->sc_my_mode->hdisplay) - |
740 | sc->sc_my_mode->vdisplay - 5, | | 758 | sc->sc_my_mode->vdisplay - 5, |
741 | sc->sc_my_mode->hdisplay, | | 759 | sc->sc_my_mode->hdisplay, |
742 | ri->ri_font->fontwidth, | | 760 | ri->ri_font->fontwidth, |
743 | ri->ri_font->fontheight, | | 761 | ri->ri_font->fontheight, |
| @@ -872,52 +890,54 @@ mach64_get_max_ramdac(struct mach64_soft | | | @@ -872,52 +890,54 @@ mach64_get_max_ramdac(struct mach64_soft |
872 | (mach64_chip_rev & 0x07)) | | 890 | (mach64_chip_rev & 0x07)) |
873 | return 170000; | | 891 | return 170000; |
874 | | | 892 | |
875 | for (i = 0; i < __arraycount(mach64_info); i++) | | 893 | for (i = 0; i < __arraycount(mach64_info); i++) |
876 | if (mach64_chip_id == mach64_info[i].chip_id) | | 894 | if (mach64_chip_id == mach64_info[i].chip_id) |
877 | return mach64_info[i].ramdac_freq; | | 895 | return mach64_info[i].ramdac_freq; |
878 | | | 896 | |
879 | if (sc->bits_per_pixel == 8) | | 897 | if (sc->bits_per_pixel == 8) |
880 | return 135000; | | 898 | return 135000; |
881 | else | | 899 | else |
882 | return 80000; | | 900 | return 80000; |
883 | } | | 901 | } |
884 | | | 902 | |
| | | 903 | #if 0 |
885 | static void | | 904 | static void |
886 | mach64_get_mode(struct mach64_softc *sc, struct videomode *mode) | | 905 | mach64_get_mode(struct mach64_softc *sc, struct videomode *mode) |
887 | { | | 906 | { |
888 | struct mach64_crtcregs crtc; | | 907 | struct mach64_crtcregs crtc; |
889 | | | 908 | |
890 | crtc.h_total_disp = regr(sc, CRTC_H_TOTAL_DISP); | | 909 | crtc.h_total_disp = regr(sc, CRTC_H_TOTAL_DISP); |
891 | crtc.h_sync_strt_wid = regr(sc, CRTC_H_SYNC_STRT_WID); | | 910 | crtc.h_sync_strt_wid = regr(sc, CRTC_H_SYNC_STRT_WID); |
892 | crtc.v_total_disp = regr(sc, CRTC_V_TOTAL_DISP); | | 911 | crtc.v_total_disp = regr(sc, CRTC_V_TOTAL_DISP); |
893 | crtc.v_sync_strt_wid = regr(sc, CRTC_V_SYNC_STRT_WID); | | 912 | crtc.v_sync_strt_wid = regr(sc, CRTC_V_SYNC_STRT_WID); |
894 | | | 913 | |
895 | mode->htotal = ((crtc.h_total_disp & 0xffff) + 1) << 3; | | 914 | mode->htotal = ((crtc.h_total_disp & 0xffff) + 1) << 3; |
896 | mode->hdisplay = ((crtc.h_total_disp >> 16) + 1) << 3; | | 915 | mode->hdisplay = ((crtc.h_total_disp >> 16) + 1) << 3; |
897 | mode->hsync_start = ((crtc.h_sync_strt_wid & 0xffff) + 1) << 3; | | 916 | mode->hsync_start = ((crtc.h_sync_strt_wid & 0xffff) + 1) << 3; |
898 | mode->hsync_end = ((crtc.h_sync_strt_wid >> 16) << 3) + | | 917 | mode->hsync_end = ((crtc.h_sync_strt_wid >> 16) << 3) + |
899 | mode->hsync_start; | | 918 | mode->hsync_start; |
900 | mode->vtotal = (crtc.v_total_disp & 0xffff) + 1; | | 919 | mode->vtotal = (crtc.v_total_disp & 0xffff) + 1; |
901 | mode->vdisplay = (crtc.v_total_disp >> 16) + 1; | | 920 | mode->vdisplay = (crtc.v_total_disp >> 16) + 1; |
902 | mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1; | | 921 | mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1; |
903 | mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start; | | 922 | mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start; |
904 | | | 923 | |
905 | #ifdef MACHFB_DEBUG | | 924 | #ifdef MACHFB_DEBUG |
906 | printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n", | | 925 | printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n", |
907 | mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, | | 926 | mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, |
908 | mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal); | | 927 | mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal); |
909 | #endif | | 928 | #endif |
910 | } | | 929 | } |
| | | 930 | #endif |
911 | | | 931 | |
912 | static int | | 932 | static int |
913 | mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc, | | 933 | mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc, |
914 | struct videomode *mode) | | 934 | struct videomode *mode) |
915 | { | | 935 | { |
916 | | | 936 | |
917 | if (mode->dot_clock > sc->ramdac_freq) | | 937 | if (mode->dot_clock > sc->ramdac_freq) |
918 | /* Clock too high. */ | | 938 | /* Clock too high. */ |
919 | return 1; | | 939 | return 1; |
920 | | | 940 | |
921 | crtc->h_total_disp = (((mode->hdisplay >> 3) - 1) << 16) | | | 941 | crtc->h_total_disp = (((mode->hdisplay >> 3) - 1) << 16) | |
922 | ((mode->htotal >> 3) - 1); | | 942 | ((mode->htotal >> 3) - 1); |
923 | crtc->h_sync_strt_wid = | | 943 | crtc->h_sync_strt_wid = |
| @@ -1137,27 +1157,30 @@ mach64_set_dsp(struct mach64_softc *sc) | | | @@ -1137,27 +1157,30 @@ mach64_set_dsp(struct mach64_softc *sc) |
1137 | fifo_depth = 24; | | 1157 | fifo_depth = 24; |
1138 | } else { | | 1158 | } else { |
1139 | dsp_loop_latency = 2; | | 1159 | dsp_loop_latency = 2; |
1140 | fifo_depth = 32; | | 1160 | fifo_depth = 32; |
1141 | } | | 1161 | } |
1142 | | | 1162 | |
1143 | dsp_precision = 0; | | 1163 | dsp_precision = 0; |
1144 | | | 1164 | |
1145 | xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) / | | 1165 | xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) / |
1146 | (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel); | | 1166 | (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel); |
1147 | | | 1167 | |
1148 | xclks_per_qw_m = (sc->mem_freq * 64 << 4) / | | 1168 | xclks_per_qw_m = (sc->mem_freq * 64 << 4) / |
1149 | (sc->vclk_freq * sc->bits_per_pixel); | | 1169 | (sc->vclk_freq * sc->bits_per_pixel); |
1150 | printf("xclks_per_qw %d %d\n", xclks_per_qw >> 7, xclks_per_qw_m); | | 1170 | |
| | | 1171 | DPRINTF("xclks_per_qw %d %d\n", xclks_per_qw >> 7, xclks_per_qw_m); |
| | | 1172 | DPRINTF("mem %dkHz v %dkHz\n", sc->mem_freq, sc->vclk_freq); |
| | | 1173 | |
1151 | y = (xclks_per_qw * fifo_depth) >> 11; | | 1174 | y = (xclks_per_qw * fifo_depth) >> 11; |
1152 | | | 1175 | |
1153 | while (y) { | | 1176 | while (y) { |
1154 | y >>= 1; | | 1177 | y >>= 1; |
1155 | dsp_precision++; | | 1178 | dsp_precision++; |
1156 | } | | 1179 | } |
1157 | dsp_precision -= 5; | | 1180 | dsp_precision -= 5; |
1158 | fifo_off = ((xclks_per_qw * (fifo_depth - 1)) >> 5) + (3 << 6); | | 1181 | fifo_off = ((xclks_per_qw * (fifo_depth - 1)) >> 5) + (3 << 6); |
1159 | | | 1182 | |
1160 | switch (sc->memtype) { | | 1183 | switch (sc->memtype) { |
1161 | case DRAM: | | 1184 | case DRAM: |
1162 | case EDO_DRAM: | | 1185 | case EDO_DRAM: |
1163 | case PSEUDO_EDO: | | 1186 | case PSEUDO_EDO: |
| @@ -1199,31 +1222,34 @@ mach64_set_dsp(struct mach64_softc *sc) | | | @@ -1199,31 +1222,34 @@ mach64_set_dsp(struct mach64_softc *sc) |
1199 | dsp_xclks_per_qw = xclks_per_qw >> dsp_precision; | | 1222 | dsp_xclks_per_qw = xclks_per_qw >> dsp_precision; |
1200 | dsp_on = fifo_on >> dsp_precision; | | 1223 | dsp_on = fifo_on >> dsp_precision; |
1201 | dsp_off = fifo_off >> dsp_precision; | | 1224 | dsp_off = fifo_off >> dsp_precision; |
1202 | | | 1225 | |
1203 | #ifdef MACHFB_DEBUG | | 1226 | #ifdef MACHFB_DEBUG |
1204 | printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n" | | 1227 | printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n" |
1205 | "dsp_precision = %d, dsp_loop_latency = %d,\n" | | 1228 | "dsp_precision = %d, dsp_loop_latency = %d,\n" |
1206 | "mclk_fb_div = %d, vclk_fb_div = %d,\n" | | 1229 | "mclk_fb_div = %d, vclk_fb_div = %d,\n" |
1207 | "mclk_post_div = %d, vclk_post_div = %d\n", | | 1230 | "mclk_post_div = %d, vclk_post_div = %d\n", |
1208 | dsp_xclks_per_qw, dsp_on, dsp_off, dsp_precision, dsp_loop_latency, | | 1231 | dsp_xclks_per_qw, dsp_on, dsp_off, dsp_precision, dsp_loop_latency, |
1209 | sc->mclk_fb_div, sc->vclk_fb_div, | | 1232 | sc->mclk_fb_div, sc->vclk_fb_div, |
1210 | sc->mclk_post_div, sc->vclk_post_div); | | 1233 | sc->mclk_post_div, sc->vclk_post_div); |
1211 | #endif | | 1234 | #endif |
1212 | | | 1235 | DPRINTF("DSP_ON_OFF %08x\n", regr(sc, DSP_ON_OFF)); |
| | | 1236 | DPRINTF("DSP_CONFIG %08x\n", regr(sc, DSP_CONFIG)); |
1213 | regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF)); | | 1237 | regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF)); |
1214 | regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) | | | 1238 | regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) | |
1215 | ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) | | | 1239 | ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) | |
1216 | (dsp_xclks_per_qw & DSP_XCLKS_PER_QW)); | | 1240 | (dsp_xclks_per_qw & DSP_XCLKS_PER_QW)); |
| | | 1241 | DPRINTF("DSP_ON_OFF %08x\n", regr(sc, DSP_ON_OFF)); |
| | | 1242 | DPRINTF("DSP_CONFIG %08x\n", regr(sc, DSP_CONFIG)); |
1217 | } | | 1243 | } |
1218 | | | 1244 | |
1219 | static void | | 1245 | static void |
1220 | mach64_set_pll(struct mach64_softc *sc, int clock) | | 1246 | mach64_set_pll(struct mach64_softc *sc, int clock) |
1221 | { | | 1247 | { |
1222 | uint32_t q, clockreg; | | 1248 | uint32_t q, clockreg; |
1223 | int clockshift = sc->sc_clock << 1; | | 1249 | int clockshift = sc->sc_clock << 1; |
1224 | uint8_t reg, vclk_ctl; | | 1250 | uint8_t reg, vclk_ctl; |
1225 | | | 1251 | |
1226 | q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq); | | 1252 | q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq); |
1227 | #ifdef MACHFB_DEBUG | | 1253 | #ifdef MACHFB_DEBUG |
1228 | printf("q = %d\n", q); | | 1254 | printf("q = %d\n", q); |
1229 | #endif | | 1255 | #endif |
| @@ -1240,35 +1266,35 @@ mach64_set_pll(struct mach64_softc *sc, | | | @@ -1240,35 +1266,35 @@ mach64_set_pll(struct mach64_softc *sc, |
1240 | sc->log2_vclk_post_div = 1; | | 1266 | sc->log2_vclk_post_div = 1; |
1241 | } else if (q > 3150) { | | 1267 | } else if (q > 3150) { |
1242 | sc->vclk_post_div = 4; | | 1268 | sc->vclk_post_div = 4; |
1243 | sc->log2_vclk_post_div = 2; | | 1269 | sc->log2_vclk_post_div = 2; |
1244 | } else if (q >= 1600) { | | 1270 | } else if (q >= 1600) { |
1245 | sc->vclk_post_div = 8; | | 1271 | sc->vclk_post_div = 8; |
1246 | sc->log2_vclk_post_div = 3; | | 1272 | sc->log2_vclk_post_div = 3; |
1247 | } else { | | 1273 | } else { |
1248 | aprint_error_dev(sc->sc_dev, "Warning: q < 1600\n"); | | 1274 | aprint_error_dev(sc->sc_dev, "Warning: q < 1600\n"); |
1249 | sc->vclk_post_div = 8; | | 1275 | sc->vclk_post_div = 8; |
1250 | sc->log2_vclk_post_div = 3; | | 1276 | sc->log2_vclk_post_div = 3; |
1251 | } | | 1277 | } |
1252 | sc->vclk_fb_div = q * sc->vclk_post_div / 100; | | 1278 | sc->vclk_fb_div = q * sc->vclk_post_div / 100; |
1253 | aprint_error("post_div: %d log2_post_div: %d mclk_div: %d\n", | | 1279 | DPRINTF("post_div: %d log2_post_div: %d mclk_div: %d\n", |
1254 | sc->vclk_post_div, sc->log2_vclk_post_div, sc->mclk_fb_div); | | 1280 | sc->vclk_post_div, sc->log2_vclk_post_div, sc->mclk_fb_div); |
1255 | | | 1281 | |
1256 | vclk_ctl = regrb_pll(sc, PLL_VCLK_CNTL); | | 1282 | vclk_ctl = regrb_pll(sc, PLL_VCLK_CNTL); |
1257 | aprint_debug("vclk_ctl: %02x\n", vclk_ctl); | | 1283 | aprint_debug("vclk_ctl: %02x\n", vclk_ctl); |
1258 | vclk_ctl |= PLL_VCLK_RESET; | | 1284 | vclk_ctl |= PLL_VCLK_RESET; |
1259 | regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl); | | 1285 | regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl); |
1260 | | | 1286 | |
1261 | aprint_error("target: %d output: %d\n", clock, | | 1287 | DPRINTF("target: %d output: %d\n", clock, |
1262 | (2 * sc->ref_freq * sc->vclk_fb_div) / | | 1288 | (2 * sc->ref_freq * sc->vclk_fb_div) / |
1263 | (sc->ref_div * sc->vclk_post_div)); | | 1289 | (sc->ref_div * sc->vclk_post_div)); |
1264 | | | 1290 | |
1265 | regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div); | | 1291 | regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div); |
1266 | reg = regrb_pll(sc, VCLK_POST_DIV); | | 1292 | reg = regrb_pll(sc, VCLK_POST_DIV); |
1267 | reg &= ~(3 << clockshift); | | 1293 | reg &= ~(3 << clockshift); |
1268 | reg |= (sc->log2_vclk_post_div << clockshift); | | 1294 | reg |= (sc->log2_vclk_post_div << clockshift); |
1269 | regwb_pll(sc, VCLK_POST_DIV, reg); | | 1295 | regwb_pll(sc, VCLK_POST_DIV, reg); |
1270 | regwb_pll(sc, VCLK0_FB_DIV + sc->sc_clock, sc->vclk_fb_div); | | 1296 | regwb_pll(sc, VCLK0_FB_DIV + sc->sc_clock, sc->vclk_fb_div); |
1271 | | | 1297 | |
1272 | vclk_ctl &= ~PLL_VCLK_RESET; | | 1298 | vclk_ctl &= ~PLL_VCLK_RESET; |
1273 | regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl); | | 1299 | regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl); |
1274 | | | 1300 | |
| @@ -1841,27 +1867,28 @@ mach64_ioctl(void *v, void *vs, u_long c | | | @@ -1841,27 +1867,28 @@ mach64_ioctl(void *v, void *vs, u_long c |
1841 | sc->sc_pcitag, data); | | 1867 | sc->sc_pcitag, data); |
1842 | | | 1868 | |
1843 | case WSDISPLAYIO_SMODE: { | | 1869 | case WSDISPLAYIO_SMODE: { |
1844 | int new_mode = *(int*)data; | | 1870 | int new_mode = *(int*)data; |
1845 | if (new_mode != sc->sc_mode) { | | 1871 | if (new_mode != sc->sc_mode) { |
1846 | sc->sc_mode = new_mode; | | 1872 | sc->sc_mode = new_mode; |
1847 | if ((new_mode == WSDISPLAYIO_MODE_EMUL) | | 1873 | if ((new_mode == WSDISPLAYIO_MODE_EMUL) |
1848 | && (ms != NULL)) | | 1874 | && (ms != NULL)) |
1849 | { | | 1875 | { |
1850 | /* restore initial video mode */ | | 1876 | /* restore initial video mode */ |
1851 | mach64_init(sc); | | 1877 | mach64_init(sc); |
1852 | mach64_init_engine(sc); | | 1878 | mach64_init_engine(sc); |
1853 | mach64_init_lut(sc); | | 1879 | mach64_init_lut(sc); |
1854 | mach64_modeswitch(sc, sc->sc_my_mode); | | 1880 | if (sc->sc_setmode) |
| | | 1881 | mach64_modeswitch(sc, sc->sc_my_mode); |
1855 | mach64_clearscreen(sc); | | 1882 | mach64_clearscreen(sc); |
1856 | glyphcache_wipe(&sc->sc_gc); | | 1883 | glyphcache_wipe(&sc->sc_gc); |
1857 | vcons_redraw_screen(ms); | | 1884 | vcons_redraw_screen(ms); |
1858 | } | | 1885 | } |
1859 | } | | 1886 | } |
1860 | } | | 1887 | } |
1861 | return 0; | | 1888 | return 0; |
1862 | case WSDISPLAYIO_GET_EDID: { | | 1889 | case WSDISPLAYIO_GET_EDID: { |
1863 | struct wsdisplayio_edid_info *d = data; | | 1890 | struct wsdisplayio_edid_info *d = data; |
1864 | return wsdisplayio_get_edid(sc->sc_dev, d); | | 1891 | return wsdisplayio_get_edid(sc->sc_dev, d); |
1865 | } | | 1892 | } |
1866 | | | 1893 | |
1867 | case WSDISPLAYIO_GET_FBINFO: { | | 1894 | case WSDISPLAYIO_GET_FBINFO: { |