1 /* $NetBSD: radeonfb.c,v 1.24 2007/12/01 17:00:41 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Itronix Inc. 5 * All rights reserved. 6 * 7 * Written by Garrett D'Amore for Itronix Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of Itronix Inc. may not be used to endorse 18 * or promote products derived from this software without specific 19 * prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND ANY EXPRESS 22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * ATI Technologies Inc. ("ATI") has not assisted in the creation of, and 36 * does not endorse, this software. ATI will not be responsible or liable 37 * for any actual or alleged damage or loss caused by or in connection with 38 * the use of or reliance on this software. 39 */ 40 41 /* 42 * Portions of this code were taken from XFree86's Radeon driver, which bears 43 * this notice: 44 * 45 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and 46 * VA Linux Systems Inc., Fremont, California. 47 * 48 * All Rights Reserved. 49 * 50 * Permission is hereby granted, free of charge, to any person obtaining 51 * a copy of this software and associated documentation files (the 52 * "Software"), to deal in the Software without restriction, including 53 * without limitation on the rights to use, copy, modify, merge, 54 * publish, distribute, sublicense, and/or sell copies of the Software, 55 * and to permit persons to whom the Software is furnished to do so, 56 * subject to the following conditions: 57 * 58 * The above copyright notice and this permission notice (including the 59 * next paragraph) shall be included in all copies or substantial 60 * portions of the Software. 61 * 62 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 63 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 64 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 65 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR 66 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 67 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 68 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 69 * DEALINGS IN THE SOFTWARE. 70 */ 71 72 #include <sys/cdefs.h> 73 __KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.24 2007/12/01 17:00:41 ad Exp $"); 74 75 #define RADEONFB_DEFAULT_DEPTH 32 76 77 #include <sys/param.h> 78 #include <sys/systm.h> 79 #include <sys/device.h> 80 #include <sys/malloc.h> 81 #include <sys/bus.h> 82 #include <sys/kernel.h> 83 #include <sys/lwp.h> 84 #include <sys/kauth.h> 85 86 #include <dev/wscons/wsdisplayvar.h> 87 #include <dev/wscons/wsconsio.h> 88 #include <dev/wsfont/wsfont.h> 89 #include <dev/rasops/rasops.h> 90 #include <dev/videomode/videomode.h> 91 #include <dev/videomode/edidvar.h> 92 #include <dev/wscons/wsdisplay_vconsvar.h> 93 94 #include <dev/pci/pcidevs.h> 95 #include <dev/pci/pcireg.h> 96 #include <dev/pci/pcivar.h> 97 #include <dev/pci/radeonfbreg.h> 98 #include <dev/pci/radeonfbvar.h> 99 #include "opt_radeonfb.h" 100 101 static int radeonfb_match(struct device *, struct cfdata *, void *); 102 static void radeonfb_attach(struct device *, struct device *, void *); 103 static int radeonfb_ioctl(void *, void *, unsigned long, void *, int, 104 struct lwp *); 105 static paddr_t radeonfb_mmap(void *, void *, off_t, int); 106 static int radeonfb_scratch_test(struct radeonfb_softc *, int, uint32_t); 107 static void radeonfb_loadbios(struct radeonfb_softc *, 108 struct pci_attach_args *); 109 110 static uintmax_t radeonfb_getprop_num(struct radeonfb_softc *, const char *, 111 uintmax_t); 112 static int radeonfb_getclocks(struct radeonfb_softc *); 113 static int radeonfb_gettmds(struct radeonfb_softc *); 114 static int radeonfb_calc_dividers(struct radeonfb_softc *, uint32_t, 115 uint32_t *, uint32_t *); 116 static int radeonfb_getconnectors(struct radeonfb_softc *); 117 static const struct videomode *radeonfb_modelookup(const char *); 118 static void radeonfb_init_screen(void *, struct vcons_screen *, int, long *); 119 static void radeonfb_pllwriteupdate(struct radeonfb_softc *, int); 120 static void radeonfb_pllwaitatomicread(struct radeonfb_softc *, int); 121 static void radeonfb_program_vclk(struct radeonfb_softc *, int, int); 122 static void radeonfb_modeswitch(struct radeonfb_display *); 123 static void radeonfb_setcrtc(struct radeonfb_display *, int); 124 static void radeonfb_init_misc(struct radeonfb_softc *); 125 static void radeonfb_set_fbloc(struct radeonfb_softc *); 126 static void radeonfb_init_palette(struct radeonfb_softc *, int); 127 static void radeonfb_r300cg_workaround(struct radeonfb_softc *); 128 129 static int radeonfb_isblank(struct radeonfb_display *); 130 static void radeonfb_blank(struct radeonfb_display *, int); 131 static int radeonfb_set_cursor(struct radeonfb_display *, 132 struct wsdisplay_cursor *); 133 static int radeonfb_set_curpos(struct radeonfb_display *, 134 struct wsdisplay_curpos *); 135 136 /* acceleration support */ 137 static void radeonfb_rectfill(struct radeonfb_display *, int dstx, int dsty, 138 int width, int height, uint32_t color); 139 static void radeonfb_bitblt(struct radeonfb_display *, int srcx, int srcy, 140 int dstx, int dsty, int width, int height, int rop, uint32_t mask); 141 static void radeonfb_feed_bytes(struct radeonfb_display *, int, uint8_t *); 142 static void radeonfb_setup_mono(struct radeonfb_display *, int, int, int, 143 int, uint32_t, uint32_t); 144 145 /* hw cursor support */ 146 static void radeonfb_cursor_cmap(struct radeonfb_display *); 147 static void radeonfb_cursor_shape(struct radeonfb_display *); 148 static void radeonfb_cursor_position(struct radeonfb_display *); 149 static void radeonfb_cursor_visible(struct radeonfb_display *); 150 static void radeonfb_cursor_update(struct radeonfb_display *, unsigned); 151 152 static void radeonfb_wait_fifo(struct radeonfb_softc *, int); 153 static void radeonfb_engine_idle(struct radeonfb_softc *); 154 static void radeonfb_engine_flush(struct radeonfb_softc *); 155 static void radeonfb_engine_reset(struct radeonfb_softc *); 156 static void radeonfb_engine_init(struct radeonfb_display *); 157 static inline void radeonfb_unclip(struct radeonfb_softc *); 158 159 static void radeonfb_eraserows(void *, int, int, long); 160 static void radeonfb_erasecols(void *, int, int, int, long); 161 static void radeonfb_copyrows(void *, int, int, int); 162 static void radeonfb_copycols(void *, int, int, int, int); 163 static void radeonfb_cursor(void *, int, int, int); 164 static void radeonfb_putchar(void *, int, int, unsigned, long); 165 static int radeonfb_allocattr(void *, int, int, int, long *); 166 167 static int radeonfb_get_backlight(struct radeonfb_display *); 168 static int radeonfb_set_backlight(struct radeonfb_display *, int); 169 static void radeonfb_lvds_callout(void *); 170 171 static struct videomode *radeonfb_best_refresh(struct videomode *, 172 struct videomode *); 173 static void radeonfb_pickres(struct radeonfb_display *, uint16_t *, 174 uint16_t *, int); 175 static const struct videomode *radeonfb_port_mode(struct radeonfb_softc *, 176 struct radeonfb_port *, int, int); 177 178 static int radeonfb_drm_print(void *, const char *); 179 180 #ifdef RADEON_DEBUG 181 int radeon_debug = 1; 182 #define DPRINTF(x) \ 183 if (radeon_debug) printf x 184 #define PRINTREG(r) DPRINTF((#r " = %08x\n", GET32(sc, r))) 185 #define PRINTPLL(r) DPRINTF((#r " = %08x\n", GETPLL(sc, r))) 186 #else 187 #define DPRINTF(x) 188 #define PRINTREG(r) 189 #define PRINTPLL(r) 190 #endif 191 192 #define ROUNDUP(x,y) (((x) + ((y) - 1)) & ~((y) - 1)) 193 194 #ifndef RADEON_DEFAULT_MODE 195 /* any reasonably modern display should handle this */ 196 #define RADEON_DEFAULT_MODE "1024x768x60" 197 #endif 198 199 const char *radeonfb_default_mode = RADEON_DEFAULT_MODE; 200 201 static struct { 202 int size; /* minimum memory size (MB) */ 203 int maxx; /* maximum x dimension */ 204 int maxy; /* maximum y dimension */ 205 int maxbpp; /* maximum bpp */ 206 int maxdisp; /* maximum logical display count */ 207 } radeonfb_limits[] = { 208 { 32, 2048, 1536, 32, 2 }, 209 { 16, 1600, 1200, 32, 2 }, 210 { 8, 1600, 1200, 32, 1 }, 211 { 0, 0, 0, 0, 0 }, 212 }; 213 214 static struct wsscreen_descr radeonfb_stdscreen = { 215 "fb", /* name */ 216 0, 0, /* ncols, nrows */ 217 NULL, /* textops */ 218 8, 16, /* fontwidth, fontheight */ 219 WSSCREEN_WSCOLORS, /* capabilities */ 220 0, /* modecookie */ 221 }; 222 223 struct wsdisplay_accessops radeonfb_accessops = { 224 radeonfb_ioctl, 225 radeonfb_mmap, 226 NULL, /* vcons_alloc_screen */ 227 NULL, /* vcons_free_screen */ 228 NULL, /* vcons_show_screen */ 229 NULL, /* load_font */ 230 NULL, /* pollc */ 231 NULL, /* scroll */ 232 }; 233 234 static struct { 235 uint16_t devid; 236 uint16_t family; 237 uint16_t flags; 238 } radeonfb_devices[] = 239 { 240 /* R100 family */ 241 { PCI_PRODUCT_ATI_RADEON_R100_QD, RADEON_R100, 0 }, 242 { PCI_PRODUCT_ATI_RADEON_R100_QE, RADEON_R100, 0 }, 243 { PCI_PRODUCT_ATI_RADEON_R100_QF, RADEON_R100, 0 }, 244 { PCI_PRODUCT_ATI_RADEON_R100_QG, RADEON_R100, 0 }, 245 246 /* RV100 family */ 247 { PCI_PRODUCT_ATI_RADEON_RV100_LY, RADEON_RV100, RFB_MOB }, 248 { PCI_PRODUCT_ATI_RADEON_RV100_LZ, RADEON_RV100, RFB_MOB }, 249 { PCI_PRODUCT_ATI_RADEON_RV100_QY, RADEON_RV100, 0 }, 250 { PCI_PRODUCT_ATI_RADEON_RV100_QZ, RADEON_RV100, 0 }, 251 252 /* RS100 family */ 253 { PCI_PRODUCT_ATI_RADEON_RS100_4136, RADEON_RS100, 0 }, 254 { PCI_PRODUCT_ATI_RADEON_RS100_4336, RADEON_RS100, RFB_MOB }, 255 256 /* RS200/RS250 family */ 257 { PCI_PRODUCT_ATI_RADEON_RS200_4337, RADEON_RS200, RFB_MOB }, 258 { PCI_PRODUCT_ATI_RADEON_RS200_A7, RADEON_RS200, 0 }, 259 { PCI_PRODUCT_ATI_RADEON_RS250_B7, RADEON_RS200, RFB_MOB }, 260 { PCI_PRODUCT_ATI_RADEON_RS250_D7, RADEON_RS200, 0 }, 261 262 /* R200 family */ 263 /* add more R200 products? , 5148 */ 264 { PCI_PRODUCT_ATI_RADEON_R200_BB, RADEON_R200, 0 }, 265 { PCI_PRODUCT_ATI_RADEON_R200_BC, RADEON_R200, 0 }, 266 { PCI_PRODUCT_ATI_RADEON_R200_QH, RADEON_R200, 0 }, 267 { PCI_PRODUCT_ATI_RADEON_R200_QL, RADEON_R200, 0 }, 268 { PCI_PRODUCT_ATI_RADEON_R200_QM, RADEON_R200, 0 }, 269 270 /* RV200 family */ 271 { PCI_PRODUCT_ATI_RADEON_RV200_LW, RADEON_RV200, RFB_MOB }, 272 { PCI_PRODUCT_ATI_RADEON_RV200_LX, RADEON_RV200, RFB_MOB }, 273 { PCI_PRODUCT_ATI_RADEON_RV200_QW, RADEON_RV200, 0 }, 274 { PCI_PRODUCT_ATI_RADEON_RV200_QX, RADEON_RV200, 0 }, 275 276 /* RV250 family */ 277 { PCI_PRODUCT_ATI_RADEON_RV250_4966, RADEON_RV250, 0 }, 278 { PCI_PRODUCT_ATI_RADEON_RV250_4967, RADEON_RV250, 0 }, 279 { PCI_PRODUCT_ATI_RADEON_RV250_4C64, RADEON_RV250, RFB_MOB }, 280 { PCI_PRODUCT_ATI_RADEON_RV250_4C66, RADEON_RV250, RFB_MOB }, 281 { PCI_PRODUCT_ATI_RADEON_RV250_4C67, RADEON_RV250, RFB_MOB }, 282 283 /* RS300 family */ 284 { PCI_PRODUCT_ATI_RADEON_RS300_X5, RADEON_RS300, 0 }, 285 { PCI_PRODUCT_ATI_RADEON_RS300_X4, RADEON_RS300, 0 }, 286 { PCI_PRODUCT_ATI_RADEON_RS300_7834, RADEON_RS300, 0 }, 287 { PCI_PRODUCT_ATI_RADEON_RS300_7835, RADEON_RS300, RFB_MOB }, 288 289 /* RV280 family */ 290 { PCI_PRODUCT_ATI_RADEON_RV280_5960, RADEON_RV280, 0 }, 291 { PCI_PRODUCT_ATI_RADEON_RV280_5961, RADEON_RV280, 0 }, 292 { PCI_PRODUCT_ATI_RADEON_RV280_5962, RADEON_RV280, 0 }, 293 { PCI_PRODUCT_ATI_RADEON_RV280_5963, RADEON_RV280, 0 }, 294 { PCI_PRODUCT_ATI_RADEON_RV280_5964, RADEON_RV280, 0 }, 295 { PCI_PRODUCT_ATI_RADEON_RV280_5C61, RADEON_RV280, RFB_MOB }, 296 { PCI_PRODUCT_ATI_RADEON_RV280_5C63, RADEON_RV280, RFB_MOB }, 297 298 /* R300 family */ 299 { PCI_PRODUCT_ATI_RADEON_R300_AD, RADEON_R300, 0 }, 300 { PCI_PRODUCT_ATI_RADEON_R300_AE, RADEON_R300, 0 }, 301 { PCI_PRODUCT_ATI_RADEON_R300_AF, RADEON_R300, 0 }, 302 { PCI_PRODUCT_ATI_RADEON_R300_AG, RADEON_R300, 0 }, 303 { PCI_PRODUCT_ATI_RADEON_R300_ND, RADEON_R300, 0 }, 304 { PCI_PRODUCT_ATI_RADEON_R300_NE, RADEON_R300, 0 }, 305 { PCI_PRODUCT_ATI_RADEON_R300_NF, RADEON_R300, 0 }, 306 { PCI_PRODUCT_ATI_RADEON_R300_NG, RADEON_R300, 0 }, 307 308 /* RV350/RV360 family */ 309 { PCI_PRODUCT_ATI_RADEON_RV350_AP, RADEON_RV350, 0 }, 310 { PCI_PRODUCT_ATI_RADEON_RV350_AQ, RADEON_RV350, 0 }, 311 { PCI_PRODUCT_ATI_RADEON_RV360_AR, RADEON_RV350, 0 }, 312 { PCI_PRODUCT_ATI_RADEON_RV350_AS, RADEON_RV350, 0 }, 313 { PCI_PRODUCT_ATI_RADEON_RV350_AT, RADEON_RV350, 0 }, 314 { PCI_PRODUCT_ATI_RADEON_RV350_AV, RADEON_RV350, 0 }, 315 { PCI_PRODUCT_ATI_RADEON_RV350_NP, RADEON_RV350, RFB_MOB }, 316 { PCI_PRODUCT_ATI_RADEON_RV350_NQ, RADEON_RV350, RFB_MOB }, 317 { PCI_PRODUCT_ATI_RADEON_RV350_NR, RADEON_RV350, RFB_MOB }, 318 { PCI_PRODUCT_ATI_RADEON_RV350_NS, RADEON_RV350, RFB_MOB }, 319 { PCI_PRODUCT_ATI_RADEON_RV350_NT, RADEON_RV350, RFB_MOB }, 320 { PCI_PRODUCT_ATI_RADEON_RV350_NV, RADEON_RV350, RFB_MOB }, 321 322 /* R350/R360 family */ 323 { PCI_PRODUCT_ATI_RADEON_R350_AH, RADEON_R350, 0 }, 324 { PCI_PRODUCT_ATI_RADEON_R350_AI, RADEON_R350, 0 }, 325 { PCI_PRODUCT_ATI_RADEON_R350_AJ, RADEON_R350, 0 }, 326 { PCI_PRODUCT_ATI_RADEON_R350_AK, RADEON_R350, 0 }, 327 { PCI_PRODUCT_ATI_RADEON_R350_NH, RADEON_R350, 0 }, 328 { PCI_PRODUCT_ATI_RADEON_R350_NI, RADEON_R350, 0 }, 329 { PCI_PRODUCT_ATI_RADEON_R350_NK, RADEON_R350, 0 }, 330 { PCI_PRODUCT_ATI_RADEON_R360_NJ, RADEON_R350, 0 }, 331 332 /* RV380/RV370 family */ 333 { PCI_PRODUCT_ATI_RADEON_RV380_3150, RADEON_RV380, RFB_MOB }, 334 { PCI_PRODUCT_ATI_RADEON_RV380_3154, RADEON_RV380, RFB_MOB }, 335 { PCI_PRODUCT_ATI_RADEON_RV380_3E50, RADEON_RV380, 0 }, 336 { PCI_PRODUCT_ATI_RADEON_RV380_3E54, RADEON_RV380, 0 }, 337 { PCI_PRODUCT_ATI_RADEON_RV370_5460, RADEON_RV380, RFB_MOB }, 338 { PCI_PRODUCT_ATI_RADEON_RV370_5464, RADEON_RV380, RFB_MOB }, 339 { PCI_PRODUCT_ATI_RADEON_RV370_5B60, RADEON_RV380, 0 }, 340 { PCI_PRODUCT_ATI_RADEON_RV370_5B64, RADEON_RV380, 0 }, 341 { PCI_PRODUCT_ATI_RADEON_RV370_5B65, RADEON_RV380, 0 }, 342 343 /* R420/R423 family */ 344 { PCI_PRODUCT_ATI_RADEON_R420_JH, RADEON_R420, 0 }, 345 { PCI_PRODUCT_ATI_RADEON_R420_JI, RADEON_R420, 0 }, 346 { PCI_PRODUCT_ATI_RADEON_R420_JJ, RADEON_R420, 0 }, 347 { PCI_PRODUCT_ATI_RADEON_R420_JK, RADEON_R420, 0 }, 348 { PCI_PRODUCT_ATI_RADEON_R420_JL, RADEON_R420, 0 }, 349 { PCI_PRODUCT_ATI_RADEON_R420_JM, RADEON_R420, 0 }, 350 { PCI_PRODUCT_ATI_RADEON_R420_JN, RADEON_R420, RFB_MOB }, 351 { PCI_PRODUCT_ATI_RADEON_R420_JP, RADEON_R420, 0 }, 352 { PCI_PRODUCT_ATI_RADEON_R423_UH, RADEON_R420, 0 }, 353 { PCI_PRODUCT_ATI_RADEON_R423_UI, RADEON_R420, 0 }, 354 { PCI_PRODUCT_ATI_RADEON_R423_UJ, RADEON_R420, 0 }, 355 { PCI_PRODUCT_ATI_RADEON_R423_UK, RADEON_R420, 0 }, 356 { PCI_PRODUCT_ATI_RADEON_R423_UQ, RADEON_R420, 0 }, 357 { PCI_PRODUCT_ATI_RADEON_R423_UR, RADEON_R420, 0 }, 358 { PCI_PRODUCT_ATI_RADEON_R423_UT, RADEON_R420, 0 }, 359 { PCI_PRODUCT_ATI_RADEON_R423_5D57, RADEON_R420, 0 }, 360 { PCI_PRODUCT_ATI_RADEON_R430_554F, RADEON_R420, 0 }, 361 362 { 0, 0, 0 } 363 }; 364 365 static struct { 366 int divider; 367 int mask; 368 } radeonfb_dividers[] = { 369 { 1, 0 }, 370 { 2, 1 }, 371 { 3, 4 }, 372 { 4, 2 }, 373 { 6, 6 }, 374 { 8, 3 }, 375 { 12, 7 }, 376 { 0, 0 } 377 }; 378 379 /* 380 * This table taken from X11. 381 */ 382 static const struct { 383 int family; 384 struct radeon_tmds_pll plls[4]; 385 } radeonfb_tmds_pll[] = { 386 { RADEON_R100, {{12000, 0xa1b}, {-1, 0xa3f}}}, 387 { RADEON_RV100, {{12000, 0xa1b}, {-1, 0xa3f}}}, 388 { RADEON_RS100, {{0, 0}}}, 389 { RADEON_RV200, {{15000, 0xa1b}, {-1, 0xa3f}}}, 390 { RADEON_RS200, {{15000, 0xa1b}, {-1, 0xa3f}}}, 391 { RADEON_R200, {{15000, 0xa1b}, {-1, 0xa3f}}}, 392 { RADEON_RV250, {{15500, 0x81b}, {-1, 0x83f}}}, 393 { RADEON_RS300, {{0, 0}}}, 394 { RADEON_RV280, {{13000, 0x400f4}, {15000, 0x400f7}}}, 395 { RADEON_R300, {{-1, 0xb01cb}}}, 396 { RADEON_R350, {{-1, 0xb01cb}}}, 397 { RADEON_RV350, {{15000, 0xb0155}, {-1, 0xb01cb}}}, 398 { RADEON_RV380, {{15000, 0xb0155}, {-1, 0xb01cb}}}, 399 { RADEON_R420, {{-1, 0xb01cb}}}, 400 }; 401 402 #define RADEONFB_BACKLIGHT_MAX 255 /* Maximum backlight level. */ 403 404 405 CFATTACH_DECL(radeonfb, sizeof (struct radeonfb_softc), 406 radeonfb_match, radeonfb_attach, NULL, NULL); 407 408 static int 409 radeonfb_match(struct device *parent, struct cfdata *match, void *aux) 410 { 411 struct pci_attach_args *pa = aux; 412 int i; 413 414 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_ATI) 415 return 0; 416 417 for (i = 0; radeonfb_devices[i].devid; i++) { 418 if (PCI_PRODUCT(pa->pa_id) == radeonfb_devices[i].devid) 419 return 100; /* high to defeat VGA/VESA */ 420 } 421 422 return 0; 423 } 424 425 static void 426 radeonfb_attach(struct device *parent, struct device *dev, void *aux) 427 { 428 struct radeonfb_softc *sc = (struct radeonfb_softc *)dev; 429 struct pci_attach_args *pa = aux; 430 const char *mptr; 431 bus_size_t bsz; 432 pcireg_t screg; 433 int i, j, fg, bg, ul; 434 uint32_t v; 435 436 sc->sc_id = pa->pa_id; 437 for (i = 0; radeonfb_devices[i].devid; i++) { 438 if (PCI_PRODUCT(sc->sc_id) == radeonfb_devices[i].devid) 439 break; 440 } 441 442 pci_devinfo(sc->sc_id, pa->pa_class, 0, sc->sc_devinfo, 443 sizeof(sc->sc_devinfo)); 444 445 aprint_naive("\n"); 446 aprint_normal(": %s\n", sc->sc_devinfo); 447 448 DPRINTF((prop_dictionary_externalize(device_properties(dev)))); 449 450 KASSERT(radeonfb_devices[i].devid != 0); 451 sc->sc_pt = pa->pa_tag; 452 sc->sc_iot = pa->pa_iot; 453 sc->sc_pc = pa->pa_pc; 454 sc->sc_family = radeonfb_devices[i].family; 455 sc->sc_flags = radeonfb_devices[i].flags; 456 457 /* enable memory and IO access */ 458 screg = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 459 screg |= PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; 460 pci_conf_write(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG, screg); 461 462 /* 463 * Some flags are general to entire chip families, and rather 464 * than clutter up the table with them, we go ahead and set 465 * them here. 466 */ 467 switch (sc->sc_family) { 468 case RADEON_RS100: 469 case RADEON_RS200: 470 sc->sc_flags |= RFB_IGP | RFB_RV100; 471 break; 472 473 case RADEON_RV100: 474 case RADEON_RV200: 475 case RADEON_RV250: 476 case RADEON_RV280: 477 sc->sc_flags |= RFB_RV100; 478 break; 479 480 case RADEON_RS300: 481 sc->sc_flags |= RFB_SDAC | RFB_IGP | RFB_RV100; 482 break; 483 484 case RADEON_R300: 485 case RADEON_RV350: 486 case RADEON_R350: 487 case RADEON_RV380: 488 case RADEON_R420: 489 /* newer chips */ 490 sc->sc_flags |= RFB_R300; 491 break; 492 493 case RADEON_R100: 494 sc->sc_flags |= RFB_NCRTC2; 495 break; 496 } 497 498 if ((sc->sc_family == RADEON_RV200) || 499 (sc->sc_family == RADEON_RV250) || 500 (sc->sc_family == RADEON_RV280) || 501 (sc->sc_family == RADEON_RV350)) { 502 bool inverted = 0; 503 /* backlight level is linear */ 504 DPRINTF(("found RV* chip, backlight is supposedly linear\n")); 505 prop_dictionary_get_bool(device_properties(&sc->sc_dev), 506 "backlight_level_reverted", &inverted); 507 if (inverted) { 508 DPRINTF(("nope, it's inverted\n")); 509 sc->sc_flags |= RFB_INV_BLIGHT; 510 } 511 } else 512 sc->sc_flags |= RFB_INV_BLIGHT; 513 514 /* 515 * XXX: to support true multihead, this must change. 516 */ 517 sc->sc_ndisplays = 1; 518 519 /* XXX: */ 520 if (!HAS_CRTC2(sc)) { 521 sc->sc_ndisplays = 1; 522 } 523 524 if (pci_mapreg_map(pa, RADEON_MAPREG_MMIO, PCI_MAPREG_TYPE_MEM, 0, 525 &sc->sc_regt, &sc->sc_regh, &sc->sc_regaddr, 526 &sc->sc_regsz) != 0) { 527 aprint_error("%s: unable to map registers!\n", XNAME(sc)); 528 goto error; 529 } 530 531 /* scratch register test... */ 532 if (radeonfb_scratch_test(sc, RADEON_BIOS_0_SCRATCH, 0x55555555) || 533 radeonfb_scratch_test(sc, RADEON_BIOS_0_SCRATCH, 0xaaaaaaaa)) { 534 aprint_error("%s: scratch register test failed!\n", XNAME(sc)); 535 goto error; 536 } 537 538 PRINTREG(RADEON_BIOS_4_SCRATCH); 539 PRINTREG(RADEON_FP_GEN_CNTL); 540 PRINTREG(RADEON_FP2_GEN_CNTL); 541 PRINTREG(RADEON_TMDS_CNTL); 542 PRINTREG(RADEON_TMDS_TRANSMITTER_CNTL); 543 PRINTREG(RADEON_TMDS_PLL_CNTL); 544 PRINTREG(RADEON_LVDS_GEN_CNTL); 545 PRINTREG(RADEON_FP_HORZ_STRETCH); 546 PRINTREG(RADEON_FP_VERT_STRETCH); 547 548 /* XXX: RV100 specific */ 549 PUT32(sc, RADEON_TMDS_PLL_CNTL, 0xa27); 550 551 PATCH32(sc, RADEON_TMDS_TRANSMITTER_CNTL, 552 RADEON_TMDS_TRANSMITTER_PLLEN, 553 RADEON_TMDS_TRANSMITTER_PLLEN | RADEON_TMDS_TRANSMITTER_PLLRST); 554 555 radeonfb_i2c_init(sc); 556 557 radeonfb_loadbios(sc, pa); 558 559 #ifdef RADEON_BIOS_INIT 560 if (radeonfb_bios_init(sc)) { 561 aprint_error("%s: BIOS inititialization failed\n", XNAME(sc)); 562 goto error; 563 } 564 #endif 565 566 if (radeonfb_getclocks(sc)) { 567 aprint_error("%s: Unable to get reference clocks from BIOS\n", 568 XNAME(sc)); 569 goto error; 570 } 571 572 if (radeonfb_gettmds(sc)) { 573 aprint_error("%s: Unable to identify TMDS PLL settings\n", 574 XNAME(sc)); 575 goto error; 576 } 577 578 aprint_verbose("%s: refclk = %d.%03d MHz, refdiv = %d " 579 "minpll = %d, maxpll = %d\n", XNAME(sc), 580 (int)sc->sc_refclk / 1000, (int)sc->sc_refclk % 1000, 581 (int)sc->sc_refdiv, (int)sc->sc_minpll, (int)sc->sc_maxpll); 582 583 radeonfb_getconnectors(sc); 584 585 radeonfb_set_fbloc(sc); 586 587 for (i = 0; radeonfb_limits[i].size; i++) { 588 if (sc->sc_memsz >= radeonfb_limits[i].size) { 589 sc->sc_maxx = radeonfb_limits[i].maxx; 590 sc->sc_maxy = radeonfb_limits[i].maxy; 591 sc->sc_maxbpp = radeonfb_limits[i].maxbpp; 592 /* framebuffer offset, start at a 4K page */ 593 sc->sc_fboffset = sc->sc_memsz / 594 radeonfb_limits[i].maxdisp; 595 /* 596 * we use the fbsize to figure out where we can store 597 * things like cursor data. 598 */ 599 sc->sc_fbsize = 600 ROUNDUP(ROUNDUP(sc->sc_maxx * sc->sc_maxbpp / 8 , 601 RADEON_STRIDEALIGN) * sc->sc_maxy, 602 4096); 603 break; 604 } 605 } 606 607 608 radeonfb_init_misc(sc); 609 radeonfb_init_palette(sc, 0); 610 if (HAS_CRTC2(sc)) 611 radeonfb_init_palette(sc, 1); 612 613 /* program the DAC wirings */ 614 for (i = 0; i < (HAS_CRTC2(sc) ? 2 : 1); i++) { 615 switch (sc->sc_ports[i].rp_dac_type) { 616 case RADEON_DAC_PRIMARY: 617 PATCH32(sc, RADEON_DAC_CNTL2, 618 i ? RADEON_DAC2_DAC_CLK_SEL : 0, 619 ~RADEON_DAC2_DAC_CLK_SEL); 620 break; 621 case RADEON_DAC_TVDAC: 622 /* we always use the TVDAC to drive a secondary analog 623 * CRT for now. if we ever support TV-out this will 624 * have to change. 625 */ 626 SET32(sc, RADEON_DAC_CNTL2, 627 RADEON_DAC2_DAC2_CLK_SEL); 628 PATCH32(sc, RADEON_DISP_HW_DEBUG, 629 i ? 0 : RADEON_CRT2_DISP1_SEL, 630 ~RADEON_CRT2_DISP1_SEL); 631 break; 632 } 633 } 634 PRINTREG(RADEON_DAC_CNTL2); 635 PRINTREG(RADEON_DISP_HW_DEBUG); 636 637 /* other DAC programming */ 638 v = GET32(sc, RADEON_DAC_CNTL); 639 v &= (RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_BLANKING); 640 v |= RADEON_DAC_MASK_ALL | RADEON_DAC_8BIT_EN; 641 PUT32(sc, RADEON_DAC_CNTL, v); 642 PRINTREG(RADEON_DAC_CNTL); 643 644 /* XXX: this may need more investigation */ 645 PUT32(sc, RADEON_TV_DAC_CNTL, 0x00280203); 646 PRINTREG(RADEON_TV_DAC_CNTL); 647 648 /* enable TMDS */ 649 SET32(sc, RADEON_FP_GEN_CNTL, 650 RADEON_FP_TMDS_EN | 651 RADEON_FP_CRTC_DONT_SHADOW_VPAR | 652 RADEON_FP_CRTC_DONT_SHADOW_HEND); 653 CLR32(sc, RADEON_FP_GEN_CNTL, RADEON_FP_SEL_CRTC2); 654 if (HAS_CRTC2(sc)) 655 SET32(sc, RADEON_FP2_GEN_CNTL, RADEON_FP2_SRC_SEL_CRTC2); 656 657 /* 658 * we use bus_space_map instead of pci_mapreg, because we don't 659 * need the full aperature space. no point in wasting virtual 660 * address space we don't intend to use, right? 661 */ 662 if ((sc->sc_memsz < (4096 * 1024)) || 663 (pci_mapreg_info(sc->sc_pc, sc->sc_pt, RADEON_MAPREG_VRAM, 664 PCI_MAPREG_TYPE_MEM, &sc->sc_memaddr, &bsz, NULL) != 0) || 665 (bsz < sc->sc_memsz)) { 666 sc->sc_memsz = 0; 667 aprint_error("%s: Bad frame buffer configuration\n", 668 XNAME(sc)); 669 goto error; 670 } 671 672 /* 64 MB should be enough -- more just wastes map entries */ 673 if (sc->sc_memsz > (64 << 20)) 674 sc->sc_memsz = (64 << 20); 675 676 sc->sc_memt = pa->pa_memt; 677 if (bus_space_map(sc->sc_memt, sc->sc_memaddr, sc->sc_memsz, 678 BUS_SPACE_MAP_LINEAR, &sc->sc_memh) != 0) { 679 sc->sc_memsz = 0; 680 aprint_error("%s: Unable to map frame buffer\n", XNAME(sc)); 681 goto error; 682 } 683 684 aprint_normal("%s: %d MB aperture at 0x%08x, " 685 "%d KB registers at 0x%08x\n", XNAME(sc), 686 (int)sc->sc_memsz >> 20, (unsigned)sc->sc_memaddr, 687 (int)sc->sc_regsz >> 10, (unsigned)sc->sc_regaddr); 688 689 /* setup default video mode from devprop (allows PROM override) */ 690 sc->sc_defaultmode = radeonfb_default_mode; 691 if (prop_dictionary_get_cstring_nocopy(device_properties(&sc->sc_dev), 692 "videomode", &mptr)) { 693 694 strncpy(sc->sc_modebuf, mptr, sizeof(sc->sc_modebuf)); 695 sc->sc_defaultmode = sc->sc_modebuf; 696 } 697 698 /* initialize some basic display parameters */ 699 for (i = 0; i < sc->sc_ndisplays; i++) { 700 struct radeonfb_display *dp = &sc->sc_displays[i]; 701 struct rasops_info *ri; 702 long defattr; 703 struct wsemuldisplaydev_attach_args aa; 704 705 /* 706 * Figure out how many "displays" (desktops) we are going to 707 * support. If more than one, then each CRTC gets its own 708 * programming. 709 * 710 * XXX: this code needs to change to support mergedfb. 711 * XXX: would be nice to allow this to be overridden 712 */ 713 if (HAS_CRTC2(sc) && (sc->sc_ndisplays == 1)) { 714 DPRINTF(("dual crtcs!\n")); 715 dp->rd_ncrtcs = 2; 716 dp->rd_crtcs[0].rc_number = 0; 717 dp->rd_crtcs[1].rc_number = 1; 718 } else { 719 dp->rd_ncrtcs = 1; 720 dp->rd_crtcs[0].rc_number = i; 721 } 722 723 /* set up port pointer */ 724 for (j = 0; j < dp->rd_ncrtcs; j++) { 725 dp->rd_crtcs[j].rc_port = 726 &sc->sc_ports[dp->rd_crtcs[j].rc_number]; 727 } 728 729 dp->rd_softc = sc; 730 dp->rd_wsmode = WSDISPLAYIO_MODE_EMUL; 731 dp->rd_bg = WS_DEFAULT_BG; 732 #if 0 733 dp->rd_bpp = sc->sc_maxbpp; /* XXX: for now */ 734 #else 735 dp->rd_bpp = RADEONFB_DEFAULT_DEPTH; /* XXX */ 736 #endif 737 /* for text mode, we pick a resolution that won't 738 * require panning */ 739 radeonfb_pickres(dp, &dp->rd_virtx, &dp->rd_virty, 0); 740 741 aprint_normal("%s: display %d: " 742 "initial virtual resolution %dx%d at %d bpp\n", 743 XNAME(sc), i, dp->rd_virtx, dp->rd_virty, dp->rd_bpp); 744 745 /* now select the *video mode* that we will use */ 746 for (j = 0; j < dp->rd_ncrtcs; j++) { 747 const struct videomode *vmp; 748 vmp = radeonfb_port_mode(sc, dp->rd_crtcs[j].rc_port, 749 dp->rd_virtx, dp->rd_virty); 750 751 /* 752 * virtual resolution should be at least as high as 753 * physical 754 */ 755 if (dp->rd_virtx < vmp->hdisplay || 756 dp->rd_virty < vmp->vdisplay) { 757 dp->rd_virtx = vmp->hdisplay; 758 dp->rd_virty = vmp->vdisplay; 759 } 760 761 dp->rd_crtcs[j].rc_videomode = *vmp; 762 printf("%s: port %d: physical %dx%d %dHz\n", 763 XNAME(sc), j, vmp->hdisplay, vmp->vdisplay, 764 DIVIDE(DIVIDE(vmp->dot_clock * 1000, 765 vmp->htotal), vmp->vtotal)); 766 } 767 768 /* N.B.: radeon wants 64-byte aligned stride */ 769 dp->rd_stride = dp->rd_virtx * dp->rd_bpp / 8; 770 dp->rd_stride = ROUNDUP(dp->rd_stride, RADEON_STRIDEALIGN); 771 772 dp->rd_offset = sc->sc_fboffset * i; 773 dp->rd_fbptr = (vaddr_t)bus_space_vaddr(sc->sc_memt, 774 sc->sc_memh) + dp->rd_offset; 775 dp->rd_curoff = sc->sc_fbsize; 776 dp->rd_curptr = dp->rd_fbptr + dp->rd_curoff; 777 778 DPRINTF(("fpbtr = %p\n", (void *)dp->rd_fbptr)); 779 780 switch (dp->rd_bpp) { 781 case 8: 782 dp->rd_format = 2; 783 break; 784 case 32: 785 dp->rd_format = 6; 786 break; 787 default: 788 aprint_error("%s: bad depth %d\n", XNAME(sc), 789 dp->rd_bpp); 790 goto error; 791 } 792 793 printf("init engine\n"); 794 /* XXX: this seems suspicious - per display engine 795 initialization? */ 796 radeonfb_engine_init(dp); 797 798 /* copy the template into place */ 799 dp->rd_wsscreens_storage[0] = radeonfb_stdscreen; 800 dp->rd_wsscreens = dp->rd_wsscreens_storage; 801 802 /* and make up the list */ 803 dp->rd_wsscreenlist.nscreens = 1; 804 dp->rd_wsscreenlist.screens = 805 (const struct wsscreen_descr **)&dp->rd_wsscreens; 806 807 vcons_init(&dp->rd_vd, dp, dp->rd_wsscreens, 808 &radeonfb_accessops); 809 810 dp->rd_vd.init_screen = radeonfb_init_screen; 811 812 dp->rd_console = 1; 813 814 dp->rd_vscreen.scr_flags |= VCONS_SCREEN_IS_STATIC; 815 816 817 vcons_init_screen(&dp->rd_vd, &dp->rd_vscreen, 818 dp->rd_console, &defattr); 819 820 ri = &dp->rd_vscreen.scr_ri; 821 822 /* clear the screen */ 823 rasops_unpack_attr(defattr, &fg, &bg, &ul); 824 radeonfb_rectfill(dp, 0, 0, ri->ri_width, ri->ri_height, 825 ri->ri_devcmap[bg & 0xf]); 826 827 dp->rd_wsscreens->textops = &ri->ri_ops; 828 dp->rd_wsscreens->capabilities = ri->ri_caps; 829 dp->rd_wsscreens->nrows = ri->ri_rows; 830 dp->rd_wsscreens->ncols = ri->ri_cols; 831 832 #ifdef SPLASHSCREEN 833 dp->rd_splash.si_depth = ri->ri_depth; 834 dp->rd_splash.si_bits = ri->ri_bits; 835 dp->rd_splash.si_hwbits = ri->ri_hwbits; 836 dp->rd_splash.si_width = ri->ri_width; 837 dp->rd_splash.si_height = ri->ri_height; 838 dp->rd_splash.si_stride = ri->ri_stride; 839 dp->rd_splash.si_fillrect = NULL; 840 #endif 841 if (dp->rd_console) { 842 843 wsdisplay_cnattach(dp->rd_wsscreens, ri, 0, 0, 844 defattr); 845 #ifdef SPLASHSCREEN 846 splash_render(&dp->rd_splash, 847 SPLASH_F_CENTER|SPLASH_F_FILL); 848 #endif 849 850 #ifdef SPLASHSCREEN_PROGRESS 851 dp->rd_progress.sp_top = (dp->rd_virty / 8) * 7; 852 dp->rd_progress.sp_width = (dp->rd_virtx / 4) * 3; 853 dp->rd_progress.sp_left = (dp->rd_virtx - 854 dp->rd_progress.sp_width) / 2; 855 dp->rd_progress.sp_height = 20; 856 dp->rd_progress.sp_state = -1; 857 dp->rd_progress.sp_si = &dp->rd_splash; 858 splash_progress_init(&dp->rd_progress); 859 SCREEN_DISABLE_DRAWING(&dp->rd_vscreen); 860 #endif 861 862 } else { 863 864 /* 865 * since we're not the console we can postpone 866 * the rest until someone actually allocates a 867 * screen for us. but we do clear the screen 868 * at least. 869 */ 870 memset(ri->ri_bits, 0, 1024); 871 872 radeonfb_modeswitch(dp); 873 #ifdef SPLASHSCREEN 874 splash_render(&dp->rd_splash, 875 SPLASH_F_CENTER|SPLASH_F_FILL); 876 SCREEN_DISABLE_DRAWING(&dp->rd_vscreen); 877 #endif 878 } 879 880 aa.console = dp->rd_console; 881 aa.scrdata = &dp->rd_wsscreenlist; 882 aa.accessops = &radeonfb_accessops; 883 aa.accesscookie = &dp->rd_vd; 884 885 config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint); 886 radeonfb_blank(dp, 0); 887 888 /* Initialise delayed lvds operations for backlight. */ 889 callout_init(&dp->rd_bl_lvds_co, 0); 890 callout_setfunc(&dp->rd_bl_lvds_co, 891 radeonfb_lvds_callout, dp); 892 } 893 894 config_found_ia(dev, "drm", aux, radeonfb_drm_print); 895 896 return; 897 898 error: 899 if (sc->sc_biossz) 900 free(sc->sc_bios, M_DEVBUF); 901 902 if (sc->sc_regsz) 903 bus_space_unmap(sc->sc_regt, sc->sc_regh, sc->sc_regsz); 904 905 if (sc->sc_memsz) 906 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsz); 907 } 908 909 static int 910 radeonfb_drm_print(void *aux, const char *pnp) 911 { 912 if (pnp) 913 aprint_normal("direct rendering for %s", pnp); 914 return (UNSUPP); 915 } 916 917 int 918 radeonfb_ioctl(void *v, void *vs, 919 unsigned long cmd, void *d, int flag, struct lwp *l) 920 { 921 struct vcons_data *vd; 922 struct radeonfb_display *dp; 923 struct radeonfb_softc *sc; 924 struct wsdisplay_param *param; 925 926 vd = (struct vcons_data *)v; 927 dp = (struct radeonfb_display *)vd->cookie; 928 sc = dp->rd_softc; 929 930 switch (cmd) { 931 case WSDISPLAYIO_GTYPE: 932 *(unsigned *)d = WSDISPLAY_TYPE_PCIMISC; 933 return 0; 934 935 case WSDISPLAYIO_GINFO: 936 if (vd->active != NULL) { 937 struct wsdisplay_fbinfo *fb; 938 fb = (struct wsdisplay_fbinfo *)d; 939 fb->width = dp->rd_virtx; 940 fb->height = dp->rd_virty; 941 fb->depth = dp->rd_bpp; 942 fb->cmsize = 256; 943 return 0; 944 } else 945 return ENODEV; 946 case WSDISPLAYIO_GVIDEO: 947 if (radeonfb_isblank(dp)) 948 *(unsigned *)d = WSDISPLAYIO_VIDEO_OFF; 949 else 950 *(unsigned *)d = WSDISPLAYIO_VIDEO_ON; 951 return 0; 952 953 case WSDISPLAYIO_SVIDEO: 954 radeonfb_blank(dp, 955 (*(unsigned int *)d == WSDISPLAYIO_VIDEO_OFF)); 956 return 0; 957 958 case WSDISPLAYIO_GETCMAP: 959 #if 0 960 if (dp->rd_bpp == 8) 961 return radeonfb_getcmap(sc, 962 (struct wsdisplay_cmap *)d); 963 #endif 964 return EINVAL; 965 966 case WSDISPLAYIO_PUTCMAP: 967 #if 0 968 if (dp->rd_bpp == 8) 969 return radeonfb_putcmap(sc, 970 (struct wsdisplay_cmap *)d); 971 #endif 972 return EINVAL; 973 974 case WSDISPLAYIO_LINEBYTES: 975 *(unsigned *)d = dp->rd_stride; 976 return 0; 977 978 case WSDISPLAYIO_SMODE: 979 if (*(int *)d != dp->rd_wsmode) { 980 dp->rd_wsmode = *(int *)d; 981 if ((dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) && 982 (dp->rd_vd.active)) { 983 radeonfb_engine_init(dp); 984 radeonfb_modeswitch(dp); 985 vcons_redraw_screen(dp->rd_vd.active); 986 } 987 } 988 return 0; 989 990 case WSDISPLAYIO_GCURMAX: 991 ((struct wsdisplay_curpos *)d)->x = RADEON_CURSORMAXX; 992 ((struct wsdisplay_curpos *)d)->y = RADEON_CURSORMAXY; 993 return 0; 994 995 case WSDISPLAYIO_SCURSOR: 996 return radeonfb_set_cursor(dp, (struct wsdisplay_cursor *)d); 997 998 case WSDISPLAYIO_GCURSOR: 999 return EPASSTHROUGH; 1000 1001 case WSDISPLAYIO_GCURPOS: 1002 ((struct wsdisplay_curpos *)d)->x = dp->rd_cursor.rc_pos.x; 1003 ((struct wsdisplay_curpos *)d)->y = dp->rd_cursor.rc_pos.y; 1004 return 0; 1005 1006 case WSDISPLAYIO_SCURPOS: 1007 return radeonfb_set_curpos(dp, (struct wsdisplay_curpos *)d); 1008 1009 case WSDISPLAYIO_SSPLASH: 1010 #if defined(SPLASHSCREEN) 1011 if (*(int *)d == 1) { 1012 SCREEN_DISABLE_DRAWING(&dp->rd_vscreen); 1013 splash_render(&dp->rd_splash, 1014 SPLASH_F_CENTER|SPLASH_F_FILL); 1015 } else 1016 SCREEN_ENABLE_DRAWING(&dp->rd_vscreen); 1017 return 0; 1018 #else 1019 return ENODEV; 1020 #endif 1021 case WSDISPLAYIO_SPROGRESS: 1022 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS) 1023 dp->rd_progress.sp_force = 1; 1024 splash_progress_update(&dp->rd_progress); 1025 dp->rd_progress.sp_force = 0; 1026 return 0; 1027 #else 1028 return ENODEV; 1029 #endif 1030 case WSDISPLAYIO_GETPARAM: 1031 param = (struct wsdisplay_param *)d; 1032 if (param->param == WSDISPLAYIO_PARAM_BACKLIGHT) { 1033 param->min = 0; 1034 param->max = RADEONFB_BACKLIGHT_MAX; 1035 param->curval = radeonfb_get_backlight(dp); 1036 return 0; 1037 } 1038 return EPASSTHROUGH; 1039 1040 case WSDISPLAYIO_SETPARAM: 1041 param = (struct wsdisplay_param *)d; 1042 if (param->param == WSDISPLAYIO_PARAM_BACKLIGHT) { 1043 return radeonfb_set_backlight(dp, param->curval); 1044 } 1045 return EPASSTHROUGH; 1046 1047 default: 1048 return EPASSTHROUGH; 1049 } 1050 } 1051 1052 paddr_t 1053 radeonfb_mmap(void *v, void *vs, off_t offset, int prot) 1054 { 1055 struct vcons_data *vd; 1056 struct radeonfb_display *dp; 1057 struct radeonfb_softc *sc; 1058 #ifdef RADEONFB_MMAP_BARS 1059 struct lwp *me; 1060 #endif 1061 paddr_t pa; 1062 1063 vd = (struct vcons_data *)v; 1064 dp = (struct radeonfb_display *)vd->cookie; 1065 sc = dp->rd_softc; 1066 1067 /* XXX: note that we don't allow mapping of registers right now */ 1068 /* XXX: this means that the XFree86 radeon driver won't work */ 1069 1070 if ((offset >= 0) && (offset < (dp->rd_virty * dp->rd_stride))) { 1071 pa = bus_space_mmap(sc->sc_memt, 1072 sc->sc_memaddr + dp->rd_offset + offset, 0, 1073 prot, BUS_SPACE_MAP_LINEAR); 1074 return pa; 1075 } 1076 1077 #ifdef RADEONFB_MMAP_BARS 1078 /* 1079 * restrict all other mappings to processes with superuser privileges 1080 * or the kernel itself 1081 */ 1082 me = curlwp; 1083 if (me != NULL) { 1084 if (kauth_authorize_generic(me->l_cred, KAUTH_GENERIC_ISSUSER, 1085 NULL) != 0) { 1086 printf("%s: mmap() rejected.\n", sc->sc_dev.dv_xname); 1087 return -1; 1088 } 1089 } 1090 1091 if ((offset >= sc->sc_regaddr) && 1092 (offset < sc->sc_regaddr + sc->sc_regsz)) { 1093 return bus_space_mmap(sc->sc_regt, offset, 0, prot, 1094 BUS_SPACE_MAP_LINEAR); 1095 } 1096 1097 if ((offset >= sc->sc_memaddr) && 1098 (offset < sc->sc_memaddr + sc->sc_memsz)) { 1099 return bus_space_mmap(sc->sc_memt, offset, 0, prot, 1100 BUS_SPACE_MAP_LINEAR); 1101 } 1102 1103 #ifdef macppc 1104 /* allow mapping of IO space */ 1105 if ((offset >= 0xf2000000) && (offset < 0xf2800000)) { 1106 pa = bus_space_mmap(sc->sc_iot, offset - 0xf2000000, 0, prot, 1107 0); 1108 return pa; 1109 } 1110 #endif /* macppc */ 1111 1112 #endif /* RADEONFB_MMAP_BARS */ 1113 1114 return -1; 1115 } 1116 1117 static void 1118 radeonfb_loadbios(struct radeonfb_softc *sc, struct pci_attach_args *pa) 1119 { 1120 bus_space_tag_t romt; 1121 bus_space_handle_t romh, biosh; 1122 bus_size_t romsz; 1123 bus_addr_t ptr; 1124 1125 if (pci_mapreg_map(pa, PCI_MAPREG_ROM, PCI_MAPREG_TYPE_ROM, 1126 BUS_SPACE_MAP_PREFETCHABLE, &romt, &romh, NULL, &romsz) != 0) { 1127 aprint_verbose("%s: unable to map BIOS!\n", XNAME(sc)); 1128 return; 1129 } 1130 1131 pci_find_rom(pa, romt, romh, PCI_ROM_CODE_TYPE_X86, &biosh, 1132 &sc->sc_biossz); 1133 if (sc->sc_biossz == 0) { 1134 aprint_verbose("%s: Video BIOS not present\n", XNAME(sc)); 1135 return; 1136 } 1137 1138 sc->sc_bios = malloc(sc->sc_biossz, M_DEVBUF, M_WAITOK); 1139 bus_space_read_region_1(romt, biosh, 0, sc->sc_bios, sc->sc_biossz); 1140 1141 /* unmap the PCI expansion rom */ 1142 bus_space_unmap(romt, romh, romsz); 1143 1144 /* turn off rom decoder now */ 1145 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM, 1146 pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM) & 1147 ~PCI_MAPREG_ROM_ENABLE); 1148 1149 ptr = GETBIOS16(sc, 0x48); 1150 if ((GETBIOS32(sc, ptr + 4) == 0x41544f4d /* "ATOM" */) || 1151 (GETBIOS32(sc, ptr + 4) == 0x4d4f5441 /* "MOTA" */)) { 1152 sc->sc_flags |= RFB_ATOM; 1153 } 1154 1155 aprint_verbose("%s: Found %d KB %s BIOS\n", XNAME(sc), 1156 (unsigned)sc->sc_biossz >> 10, IS_ATOM(sc) ? "ATOM" : "Legacy"); 1157 } 1158 1159 1160 uint32_t 1161 radeonfb_get32(struct radeonfb_softc *sc, uint32_t reg) 1162 { 1163 1164 return bus_space_read_4(sc->sc_regt, sc->sc_regh, reg); 1165 } 1166 1167 void 1168 radeonfb_put32(struct radeonfb_softc *sc, uint32_t reg, uint32_t val) 1169 { 1170 1171 bus_space_write_4(sc->sc_regt, sc->sc_regh, reg, val); 1172 } 1173 1174 void 1175 radeonfb_mask32(struct radeonfb_softc *sc, uint32_t reg, 1176 uint32_t andmask, uint32_t ormask) 1177 { 1178 int s; 1179 uint32_t val; 1180 1181 s = splhigh(); 1182 val = radeonfb_get32(sc, reg); 1183 val = (val & andmask) | ormask; 1184 radeonfb_put32(sc, reg, val); 1185 splx(s); 1186 } 1187 1188 uint32_t 1189 radeonfb_getindex(struct radeonfb_softc *sc, uint32_t idx) 1190 { 1191 int s; 1192 uint32_t val; 1193 1194 s = splhigh(); 1195 radeonfb_put32(sc, RADEON_MM_INDEX, idx); 1196 val = radeonfb_get32(sc, RADEON_MM_DATA); 1197 splx(s); 1198 1199 return (val); 1200 } 1201 1202 void 1203 radeonfb_putindex(struct radeonfb_softc *sc, uint32_t idx, uint32_t val) 1204 { 1205 int s; 1206 1207 s = splhigh(); 1208 radeonfb_put32(sc, RADEON_MM_INDEX, idx); 1209 radeonfb_put32(sc, RADEON_MM_DATA, val); 1210 splx(s); 1211 } 1212 1213 void 1214 radeonfb_maskindex(struct radeonfb_softc *sc, uint32_t idx, 1215 uint32_t andmask, uint32_t ormask) 1216 { 1217 int s; 1218 uint32_t val; 1219 1220 s = splhigh(); 1221 radeonfb_put32(sc, RADEON_MM_INDEX, idx); 1222 val = radeonfb_get32(sc, RADEON_MM_DATA); 1223 val = (val & andmask) | ormask; 1224 radeonfb_put32(sc, RADEON_MM_DATA, val); 1225 splx(s); 1226 } 1227 1228 uint32_t 1229 radeonfb_getpll(struct radeonfb_softc *sc, uint32_t idx) 1230 { 1231 int s; 1232 uint32_t val; 1233 1234 s = splhigh(); 1235 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, idx & 0x3f); 1236 val = radeonfb_get32(sc, RADEON_CLOCK_CNTL_DATA); 1237 if (HAS_R300CG(sc)) 1238 radeonfb_r300cg_workaround(sc); 1239 splx(s); 1240 1241 return (val); 1242 } 1243 1244 void 1245 radeonfb_putpll(struct radeonfb_softc *sc, uint32_t idx, uint32_t val) 1246 { 1247 int s; 1248 1249 s = splhigh(); 1250 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, (idx & 0x3f) | 1251 RADEON_PLL_WR_EN); 1252 radeonfb_put32(sc, RADEON_CLOCK_CNTL_DATA, val); 1253 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, 0); 1254 splx(s); 1255 } 1256 1257 void 1258 radeonfb_maskpll(struct radeonfb_softc *sc, uint32_t idx, 1259 uint32_t andmask, uint32_t ormask) 1260 { 1261 int s; 1262 uint32_t val; 1263 1264 s = splhigh(); 1265 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, (idx & 0x3f) | 1266 RADEON_PLL_WR_EN); 1267 val = radeonfb_get32(sc, RADEON_CLOCK_CNTL_DATA); 1268 val = (val & andmask) | ormask; 1269 radeonfb_put32(sc, RADEON_CLOCK_CNTL_DATA, val); 1270 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, 0); 1271 splx(s); 1272 } 1273 1274 int 1275 radeonfb_scratch_test(struct radeonfb_softc *sc, int reg, uint32_t v) 1276 { 1277 uint32_t saved; 1278 1279 saved = GET32(sc, reg); 1280 PUT32(sc, reg, v); 1281 if (GET32(sc, reg) != v) { 1282 return -1; 1283 } 1284 PUT32(sc, reg, saved); 1285 return 0; 1286 } 1287 1288 uintmax_t 1289 radeonfb_getprop_num(struct radeonfb_softc *sc, const char *name, 1290 uintmax_t defval) 1291 { 1292 prop_number_t pn; 1293 pn = prop_dictionary_get(device_properties(&sc->sc_dev), name); 1294 if (pn == NULL) { 1295 return defval; 1296 } 1297 KASSERT(prop_object_type(pn) == PROP_TYPE_NUMBER); 1298 return (prop_number_integer_value(pn)); 1299 } 1300 1301 int 1302 radeonfb_getclocks(struct radeonfb_softc *sc) 1303 { 1304 bus_addr_t ptr; 1305 int refclk = 0; 1306 int refdiv = 0; 1307 int minpll = 0; 1308 int maxpll = 0; 1309 1310 /* load initial property values if port/board provides them */ 1311 refclk = radeonfb_getprop_num(sc, "refclk", 0) & 0xffff; 1312 refdiv = radeonfb_getprop_num(sc, "refdiv", 0) & 0xffff; 1313 minpll = radeonfb_getprop_num(sc, "minpll", 0) & 0xffffffffU; 1314 maxpll = radeonfb_getprop_num(sc, "maxpll", 0) & 0xffffffffU; 1315 1316 if (refclk && refdiv && minpll && maxpll) 1317 goto dontprobe; 1318 1319 if (!sc->sc_biossz) { 1320 /* no BIOS */ 1321 aprint_verbose("%s: No video BIOS, using default clocks\n", 1322 XNAME(sc)); 1323 if (IS_IGP(sc)) 1324 refclk = refclk ? refclk : 1432; 1325 else 1326 refclk = refclk ? refclk : 2700; 1327 refdiv = refdiv ? refdiv : 12; 1328 minpll = minpll ? minpll : 12500; 1329 maxpll = maxpll ? maxpll : 35000; 1330 } else if (IS_ATOM(sc)) { 1331 /* ATOM BIOS */ 1332 ptr = GETBIOS16(sc, 0x48); 1333 ptr = GETBIOS16(sc, ptr + 32); /* aka MasterDataStart */ 1334 ptr = GETBIOS16(sc, ptr + 12); /* pll info block */ 1335 refclk = refclk ? refclk : GETBIOS16(sc, ptr + 82); 1336 minpll = minpll ? minpll : GETBIOS16(sc, ptr + 78); 1337 maxpll = maxpll ? maxpll : GETBIOS16(sc, ptr + 32); 1338 /* 1339 * ATOM BIOS doesn't supply a reference divider, so we 1340 * have to probe for it. 1341 */ 1342 if (refdiv < 2) 1343 refdiv = GETPLL(sc, RADEON_PPLL_REF_DIV) & 1344 RADEON_PPLL_REF_DIV_MASK; 1345 /* 1346 * if probe is zero, just assume one that should work 1347 * for most parts 1348 */ 1349 if (refdiv < 2) 1350 refdiv = 12; 1351 1352 } else { 1353 /* Legacy BIOS */ 1354 ptr = GETBIOS16(sc, 0x48); 1355 ptr = GETBIOS16(sc, ptr + 0x30); 1356 refclk = refclk ? refclk : GETBIOS16(sc, ptr + 0x0E); 1357 refdiv = refdiv ? refdiv : GETBIOS16(sc, ptr + 0x10); 1358 minpll = minpll ? minpll : GETBIOS32(sc, ptr + 0x12); 1359 maxpll = maxpll ? maxpll : GETBIOS32(sc, ptr + 0x16); 1360 } 1361 1362 1363 dontprobe: 1364 sc->sc_refclk = refclk * 10; 1365 sc->sc_refdiv = refdiv; 1366 sc->sc_minpll = minpll * 10; 1367 sc->sc_maxpll = maxpll * 10; 1368 return 0; 1369 } 1370 1371 int 1372 radeonfb_calc_dividers(struct radeonfb_softc *sc, uint32_t dotclock, 1373 uint32_t *postdivbit, uint32_t *feedbackdiv) 1374 { 1375 int i; 1376 uint32_t outfreq; 1377 int div; 1378 1379 DPRINTF(("dot clock: %u\n", dotclock)); 1380 for (i = 0; (div = radeonfb_dividers[i].divider) != 0; i++) { 1381 outfreq = div * dotclock; 1382 if ((outfreq >= sc->sc_minpll) && 1383 (outfreq <= sc->sc_maxpll)) { 1384 DPRINTF(("outfreq: %u\n", outfreq)); 1385 *postdivbit = 1386 ((uint32_t)radeonfb_dividers[i].mask << 16); 1387 DPRINTF(("post divider: %d (mask %x)\n", div, 1388 *postdivbit)); 1389 break; 1390 } 1391 } 1392 1393 if (div == 0) 1394 return 1; 1395 1396 *feedbackdiv = DIVIDE(sc->sc_refdiv * outfreq, sc->sc_refclk); 1397 DPRINTF(("feedback divider: %d\n", *feedbackdiv)); 1398 return 0; 1399 } 1400 1401 #if 0 1402 #ifdef RADEON_DEBUG 1403 static void 1404 dump_buffer(const char *pfx, void *buffer, unsigned int size) 1405 { 1406 char asc[17]; 1407 unsigned ptr = (unsigned)buffer; 1408 char *start = (char *)(ptr & ~0xf); 1409 char *end = (char *)(ptr + size); 1410 1411 end = (char *)(((unsigned)end + 0xf) & ~0xf); 1412 1413 if (pfx == NULL) { 1414 pfx = ""; 1415 } 1416 1417 while (start < end) { 1418 unsigned offset = (unsigned)start & 0xf; 1419 if (offset == 0) { 1420 printf("%s%x: ", pfx, (unsigned)start); 1421 } 1422 if (((unsigned)start < ptr) || 1423 ((unsigned)start >= (ptr + size))) { 1424 printf(" "); 1425 asc[offset] = ' '; 1426 } else { 1427 printf("%02x", *(unsigned char *)start); 1428 if ((*start >= ' ') && (*start <= '~')) { 1429 asc[offset] = *start; 1430 } else { 1431 asc[offset] = '.'; 1432 } 1433 } 1434 asc[offset + 1] = 0; 1435 if (offset % 2) { 1436 printf(" "); 1437 } 1438 if (offset == 15) { 1439 printf(" %s\n", asc); 1440 } 1441 start++; 1442 } 1443 } 1444 #endif 1445 #endif 1446 1447 int 1448 radeonfb_getconnectors(struct radeonfb_softc *sc) 1449 { 1450 int i; 1451 int found = 0; 1452 1453 for (i = 0; i < 2; i++) { 1454 sc->sc_ports[i].rp_mon_type = RADEON_MT_UNKNOWN; 1455 sc->sc_ports[i].rp_ddc_type = RADEON_DDC_NONE; 1456 sc->sc_ports[i].rp_dac_type = RADEON_DAC_UNKNOWN; 1457 sc->sc_ports[i].rp_conn_type = RADEON_CONN_NONE; 1458 sc->sc_ports[i].rp_tmds_type = RADEON_TMDS_UNKNOWN; 1459 } 1460 1461 /* 1462 * This logic is borrowed from Xorg's radeon driver. 1463 */ 1464 if (!sc->sc_biossz) 1465 goto nobios; 1466 1467 if (IS_ATOM(sc)) { 1468 /* not done yet */ 1469 } else { 1470 uint16_t ptr; 1471 int port = 0; 1472 1473 ptr = GETBIOS16(sc, 0x48); 1474 ptr = GETBIOS16(sc, ptr + 0x50); 1475 for (i = 1; i < 4; i++) { 1476 uint16_t entry; 1477 uint8_t conn, ddc, dac, tmds; 1478 1479 /* 1480 * Parse the connector table. From reading the code, 1481 * it appears to made up of 16-bit entries for each 1482 * connector. The 16-bits are defined as: 1483 * 1484 * bits 12-15 - connector type (0 == end of table) 1485 * bits 8-11 - DDC type 1486 * bits 5-7 - ??? 1487 * bit 4 - TMDS type (1 = EXT, 0 = INT) 1488 * bits 1-3 - ??? 1489 * bit 0 - DAC, 1 = TVDAC, 0 = primary 1490 */ 1491 if (!GETBIOS8(sc, ptr + i * 2) && i > 1) 1492 break; 1493 entry = GETBIOS16(sc, ptr + i * 2); 1494 1495 conn = (entry >> 12) & 0xf; 1496 ddc = (entry >> 8) & 0xf; 1497 dac = (entry & 0x1) ? RADEON_DAC_TVDAC : 1498 RADEON_DAC_PRIMARY; 1499 tmds = ((entry >> 4) & 0x1) ? RADEON_TMDS_EXT : 1500 RADEON_TMDS_INT; 1501 1502 if (conn == RADEON_CONN_NONE) 1503 continue; /* no connector */ 1504 1505 if ((found > 0) && 1506 (sc->sc_ports[port].rp_ddc_type == ddc)) { 1507 /* duplicate entry for same connector */ 1508 continue; 1509 } 1510 1511 /* internal DDC_DVI port gets priority */ 1512 if ((ddc == RADEON_DDC_DVI) || (port == 1)) 1513 port = 0; 1514 else 1515 port = 1; 1516 1517 sc->sc_ports[port].rp_ddc_type = 1518 ddc > RADEON_DDC_CRT2 ? RADEON_DDC_NONE : ddc; 1519 sc->sc_ports[port].rp_dac_type = dac; 1520 sc->sc_ports[port].rp_conn_type = 1521 min(conn, RADEON_CONN_UNSUPPORTED) ; 1522 1523 sc->sc_ports[port].rp_tmds_type = tmds; 1524 1525 if ((conn != RADEON_CONN_DVI_I) && 1526 (conn != RADEON_CONN_DVI_D) && 1527 (tmds == RADEON_TMDS_INT)) 1528 sc->sc_ports[port].rp_tmds_type = 1529 RADEON_TMDS_UNKNOWN; 1530 1531 found += (port + 1); 1532 } 1533 } 1534 1535 nobios: 1536 if (!found) { 1537 DPRINTF(("No connector info in BIOS!\n")); 1538 /* default, port 0 = internal TMDS, port 1 = CRT */ 1539 sc->sc_ports[0].rp_mon_type = RADEON_MT_UNKNOWN; 1540 sc->sc_ports[0].rp_ddc_type = RADEON_DDC_DVI; 1541 sc->sc_ports[0].rp_dac_type = RADEON_DAC_TVDAC; 1542 sc->sc_ports[0].rp_conn_type = RADEON_CONN_DVI_D; 1543 sc->sc_ports[0].rp_tmds_type = RADEON_TMDS_INT; 1544 1545 sc->sc_ports[1].rp_mon_type = RADEON_MT_UNKNOWN; 1546 sc->sc_ports[1].rp_ddc_type = RADEON_DDC_VGA; 1547 sc->sc_ports[1].rp_dac_type = RADEON_DAC_PRIMARY; 1548 sc->sc_ports[1].rp_conn_type = RADEON_CONN_CRT; 1549 sc->sc_ports[1].rp_tmds_type = RADEON_TMDS_EXT; 1550 } 1551 1552 /* 1553 * Fixup for RS300/RS350/RS400 chips, that lack a primary DAC. 1554 * these chips should use TVDAC for the VGA port. 1555 */ 1556 if (HAS_SDAC(sc)) { 1557 if (sc->sc_ports[0].rp_conn_type == RADEON_CONN_CRT) { 1558 sc->sc_ports[0].rp_dac_type = RADEON_DAC_TVDAC; 1559 sc->sc_ports[1].rp_dac_type = RADEON_DAC_PRIMARY; 1560 } else { 1561 sc->sc_ports[1].rp_dac_type = RADEON_DAC_TVDAC; 1562 sc->sc_ports[0].rp_dac_type = RADEON_DAC_PRIMARY; 1563 } 1564 } else if (!HAS_CRTC2(sc)) { 1565 sc->sc_ports[0].rp_dac_type = RADEON_DAC_PRIMARY; 1566 } 1567 1568 for (i = 0; i < 2; i++) { 1569 char edid[128]; 1570 uint8_t ddc; 1571 struct edid_info *eip = &sc->sc_ports[i].rp_edid; 1572 prop_data_t edid_data; 1573 1574 DPRINTF(("Port #%d:\n", i)); 1575 DPRINTF((" conn = %d\n", sc->sc_ports[i].rp_conn_type)); 1576 DPRINTF((" ddc = %d\n", sc->sc_ports[i].rp_ddc_type)); 1577 DPRINTF((" dac = %d\n", sc->sc_ports[i].rp_dac_type)); 1578 DPRINTF((" tmds = %d\n", sc->sc_ports[i].rp_tmds_type)); 1579 1580 sc->sc_ports[i].rp_edid_valid = 0; 1581 /* first look for static EDID data */ 1582 if ((edid_data = prop_dictionary_get(device_properties( 1583 &sc->sc_dev), "EDID")) != NULL) { 1584 1585 aprint_normal("%s: using static EDID\n", 1586 sc->sc_dev.dv_xname); 1587 memcpy(edid, prop_data_data_nocopy(edid_data), 128); 1588 if (edid_parse(edid, eip) == 0) { 1589 1590 sc->sc_ports[i].rp_edid_valid = 1; 1591 edid_print(eip); 1592 } 1593 } 1594 /* if we didn't find any we'll try to talk to the monitor */ 1595 if (sc->sc_ports[i].rp_edid_valid != 1) { 1596 1597 ddc = sc->sc_ports[i].rp_ddc_type; 1598 if (ddc != RADEON_DDC_NONE) { 1599 if ((radeonfb_i2c_read_edid(sc, ddc, edid) 1600 == 0) && (edid_parse(edid, eip) == 0)) { 1601 1602 sc->sc_ports[i].rp_edid_valid = 1; 1603 edid_print(eip); 1604 } 1605 } 1606 } 1607 } 1608 1609 return found; 1610 } 1611 1612 int 1613 radeonfb_gettmds(struct radeonfb_softc *sc) 1614 { 1615 int i; 1616 1617 if (!sc->sc_biossz) { 1618 goto nobios; 1619 } 1620 1621 if (IS_ATOM(sc)) { 1622 /* XXX: not done yet */ 1623 } else { 1624 uint16_t ptr; 1625 int n; 1626 1627 ptr = GETBIOS16(sc, 0x48); 1628 ptr = GETBIOS16(sc, ptr + 0x34); 1629 DPRINTF(("DFP table revision %d\n", GETBIOS8(sc, ptr))); 1630 if (GETBIOS8(sc, ptr) == 3) { 1631 /* revision three table */ 1632 n = GETBIOS8(sc, ptr + 5) + 1; 1633 n = min(n, 4); 1634 1635 memset(sc->sc_tmds_pll, 0, sizeof (sc->sc_tmds_pll)); 1636 for (i = 0; i < n; i++) { 1637 sc->sc_tmds_pll[i].rtp_pll = GETBIOS32(sc, 1638 ptr + i * 10 + 8); 1639 sc->sc_tmds_pll[i].rtp_freq = GETBIOS16(sc, 1640 ptr + i * 10 + 0x10); 1641 DPRINTF(("TMDS_PLL dot clock %d pll %x\n", 1642 sc->sc_tmds_pll[i].rtp_freq, 1643 sc->sc_tmds_pll[i].rtp_pll)); 1644 } 1645 return 0; 1646 } 1647 } 1648 1649 nobios: 1650 DPRINTF(("no suitable DFP table present\n")); 1651 for (i = 0; 1652 i < sizeof (radeonfb_tmds_pll) / sizeof (radeonfb_tmds_pll[0]); 1653 i++) { 1654 int j; 1655 1656 if (radeonfb_tmds_pll[i].family != sc->sc_family) 1657 continue; 1658 1659 for (j = 0; j < 4; j++) { 1660 sc->sc_tmds_pll[j] = radeonfb_tmds_pll[i].plls[j]; 1661 DPRINTF(("TMDS_PLL dot clock %d pll %x\n", 1662 sc->sc_tmds_pll[j].rtp_freq, 1663 sc->sc_tmds_pll[j].rtp_pll)); 1664 } 1665 return 0; 1666 } 1667 1668 return -1; 1669 } 1670 1671 const struct videomode * 1672 radeonfb_modelookup(const char *name) 1673 { 1674 int i; 1675 1676 for (i = 0; i < videomode_count; i++) 1677 if (!strcmp(name, videomode_list[i].name)) 1678 return &videomode_list[i]; 1679 1680 return NULL; 1681 } 1682 1683 void 1684 radeonfb_pllwriteupdate(struct radeonfb_softc *sc, int crtc) 1685 { 1686 if (crtc) { 1687 while (GETPLL(sc, RADEON_P2PLL_REF_DIV) & 1688 RADEON_P2PLL_ATOMIC_UPDATE_R); 1689 SETPLL(sc, RADEON_P2PLL_REF_DIV, RADEON_P2PLL_ATOMIC_UPDATE_W); 1690 } else { 1691 while (GETPLL(sc, RADEON_PPLL_REF_DIV) & 1692 RADEON_PPLL_ATOMIC_UPDATE_R); 1693 SETPLL(sc, RADEON_PPLL_REF_DIV, RADEON_PPLL_ATOMIC_UPDATE_W); 1694 } 1695 } 1696 1697 void 1698 radeonfb_pllwaitatomicread(struct radeonfb_softc *sc, int crtc) 1699 { 1700 int i; 1701 1702 for (i = 10000; i; i--) { 1703 if (crtc) { 1704 if (GETPLL(sc, RADEON_P2PLL_REF_DIV) & 1705 RADEON_P2PLL_ATOMIC_UPDATE_R) 1706 break; 1707 } else { 1708 if (GETPLL(sc, RADEON_PPLL_REF_DIV) & 1709 RADEON_PPLL_ATOMIC_UPDATE_R) 1710 break; 1711 } 1712 } 1713 } 1714 1715 void 1716 radeonfb_program_vclk(struct radeonfb_softc *sc, int dotclock, int crtc) 1717 { 1718 uint32_t pbit = 0; 1719 uint32_t feed = 0; 1720 uint32_t data; 1721 #if 1 1722 int i; 1723 #endif 1724 1725 radeonfb_calc_dividers(sc, dotclock, &pbit, &feed); 1726 1727 if (crtc == 0) { 1728 1729 /* XXXX: mobility workaround missing */ 1730 /* XXXX: R300 stuff missing */ 1731 1732 PATCHPLL(sc, RADEON_VCLK_ECP_CNTL, 1733 RADEON_VCLK_SRC_SEL_CPUCLK, 1734 ~RADEON_VCLK_SRC_SEL_MASK); 1735 1736 /* put vclk into reset, use atomic updates */ 1737 SETPLL(sc, RADEON_PPLL_CNTL, 1738 RADEON_PPLL_REFCLK_SEL | 1739 RADEON_PPLL_FBCLK_SEL | 1740 RADEON_PPLL_RESET | 1741 RADEON_PPLL_ATOMIC_UPDATE_EN | 1742 RADEON_PPLL_VGA_ATOMIC_UPDATE_EN); 1743 1744 /* select clock 3 */ 1745 #if 0 1746 PATCH32(sc, RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_DIV_SEL, 1747 ~RADEON_PLL_DIV_SEL); 1748 #else 1749 PATCH32(sc, RADEON_CLOCK_CNTL_INDEX, 0, 1750 ~RADEON_PLL_DIV_SEL); 1751 #endif 1752 1753 /* XXX: R300 family -- program divider differently? */ 1754 1755 /* program reference divider */ 1756 PATCHPLL(sc, RADEON_PPLL_REF_DIV, sc->sc_refdiv, 1757 ~RADEON_PPLL_REF_DIV_MASK); 1758 PRINTPLL(RADEON_PPLL_REF_DIV); 1759 1760 #if 0 1761 data = GETPLL(sc, RADEON_PPLL_DIV_3); 1762 data &= ~(RADEON_PPLL_FB3_DIV_MASK | 1763 RADEON_PPLL_POST3_DIV_MASK); 1764 data |= pbit; 1765 data |= (feed & RADEON_PPLL_FB3_DIV_MASK); 1766 PUTPLL(sc, RADEON_PPLL_DIV_3, data); 1767 #else 1768 for (i = 0; i < 4; i++) { 1769 } 1770 #endif 1771 1772 /* use the atomic update */ 1773 radeonfb_pllwriteupdate(sc, crtc); 1774 1775 /* and wait for it to complete */ 1776 radeonfb_pllwaitatomicread(sc, crtc); 1777 1778 /* program HTOTAL (why?) */ 1779 PUTPLL(sc, RADEON_HTOTAL_CNTL, 0); 1780 1781 /* drop reset */ 1782 CLRPLL(sc, RADEON_PPLL_CNTL, 1783 RADEON_PPLL_RESET | RADEON_PPLL_SLEEP | 1784 RADEON_PPLL_ATOMIC_UPDATE_EN | 1785 RADEON_PPLL_VGA_ATOMIC_UPDATE_EN); 1786 1787 PRINTPLL(RADEON_PPLL_CNTL); 1788 1789 /* give clock time to lock */ 1790 delay(50000); 1791 1792 PATCHPLL(sc, RADEON_VCLK_ECP_CNTL, 1793 RADEON_VCLK_SRC_SEL_PPLLCLK, 1794 ~RADEON_VCLK_SRC_SEL_MASK); 1795 1796 } else { 1797 1798 PATCHPLL(sc, RADEON_PIXCLKS_CNTL, 1799 RADEON_PIX2CLK_SRC_SEL_CPUCLK, 1800 ~RADEON_PIX2CLK_SRC_SEL_MASK); 1801 1802 /* put vclk into reset, use atomic updates */ 1803 SETPLL(sc, RADEON_P2PLL_CNTL, 1804 RADEON_P2PLL_RESET | 1805 RADEON_P2PLL_ATOMIC_UPDATE_EN | 1806 RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN); 1807 1808 /* XXX: R300 family -- program divider differently? */ 1809 1810 /* program reference divider */ 1811 PATCHPLL(sc, RADEON_P2PLL_REF_DIV, sc->sc_refdiv, 1812 ~RADEON_P2PLL_REF_DIV_MASK); 1813 1814 /* program feedback and post dividers */ 1815 data = GETPLL(sc, RADEON_P2PLL_DIV_0); 1816 data &= ~(RADEON_P2PLL_FB0_DIV_MASK | 1817 RADEON_P2PLL_POST0_DIV_MASK); 1818 data |= pbit; 1819 data |= (feed & RADEON_P2PLL_FB0_DIV_MASK); 1820 PUTPLL(sc, RADEON_P2PLL_DIV_0, data); 1821 1822 /* use the atomic update */ 1823 radeonfb_pllwriteupdate(sc, crtc); 1824 1825 /* and wait for it to complete */ 1826 radeonfb_pllwaitatomicread(sc, crtc); 1827 1828 /* program HTOTAL (why?) */ 1829 PUTPLL(sc, RADEON_HTOTAL2_CNTL, 0); 1830 1831 /* drop reset */ 1832 CLRPLL(sc, RADEON_P2PLL_CNTL, 1833 RADEON_P2PLL_RESET | RADEON_P2PLL_SLEEP | 1834 RADEON_P2PLL_ATOMIC_UPDATE_EN | 1835 RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN); 1836 1837 /* allow time for clock to lock */ 1838 delay(50000); 1839 1840 PATCHPLL(sc, RADEON_PIXCLKS_CNTL, 1841 RADEON_PIX2CLK_SRC_SEL_P2PLLCLK, 1842 ~RADEON_PIX2CLK_SRC_SEL_MASK); 1843 } 1844 PRINTREG(RADEON_CRTC_MORE_CNTL); 1845 } 1846 1847 void 1848 radeonfb_modeswitch(struct radeonfb_display *dp) 1849 { 1850 struct radeonfb_softc *sc = dp->rd_softc; 1851 int i; 1852 1853 /* blank the display while we switch modes */ 1854 //radeonfb_blank(dp, 1); 1855 1856 #if 0 1857 SET32(sc, RADEON_CRTC_EXT_CNTL, 1858 RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS | 1859 RADEON_CRTC_DISPLAY_DIS /* | RADEON_CRTC_DISP_REQ_EN_B */); 1860 #endif 1861 1862 /* these registers might get in the way... */ 1863 PUT32(sc, RADEON_OVR_CLR, 0); 1864 PUT32(sc, RADEON_OVR_WID_LEFT_RIGHT, 0); 1865 PUT32(sc, RADEON_OVR_WID_TOP_BOTTOM, 0); 1866 PUT32(sc, RADEON_OV0_SCALE_CNTL, 0); 1867 PUT32(sc, RADEON_SUBPIC_CNTL, 0); 1868 PUT32(sc, RADEON_VIPH_CONTROL, 0); 1869 PUT32(sc, RADEON_I2C_CNTL_1, 0); 1870 PUT32(sc, RADEON_GEN_INT_CNTL, 0); 1871 PUT32(sc, RADEON_CAP0_TRIG_CNTL, 0); 1872 PUT32(sc, RADEON_CAP1_TRIG_CNTL, 0); 1873 PUT32(sc, RADEON_SURFACE_CNTL, 0); 1874 1875 for (i = 0; i < dp->rd_ncrtcs; i++) 1876 radeonfb_setcrtc(dp, i); 1877 1878 /* activate the display */ 1879 //radeonfb_blank(dp, 0); 1880 } 1881 1882 void 1883 radeonfb_setcrtc(struct radeonfb_display *dp, int index) 1884 { 1885 int crtc; 1886 struct videomode *mode; 1887 struct radeonfb_softc *sc; 1888 struct radeonfb_crtc *cp; 1889 uint32_t v; 1890 uint32_t gencntl; 1891 uint32_t htotaldisp; 1892 uint32_t hsyncstrt; 1893 uint32_t vtotaldisp; 1894 uint32_t vsyncstrt; 1895 uint32_t fphsyncstrt; 1896 uint32_t fpvsyncstrt; 1897 uint32_t fphtotaldisp; 1898 uint32_t fpvtotaldisp; 1899 uint32_t pitch; 1900 1901 sc = dp->rd_softc; 1902 cp = &dp->rd_crtcs[index]; 1903 crtc = cp->rc_number; 1904 mode = &cp->rc_videomode; 1905 1906 #if 1 1907 pitch = (((dp->rd_virtx * dp->rd_bpp) + ((dp->rd_bpp * 8) - 1)) / 1908 (dp->rd_bpp * 8)); 1909 #else 1910 pitch = (((sc->sc_maxx * sc->sc_maxbpp) + ((sc->sc_maxbpp * 8) - 1)) / 1911 (sc->sc_maxbpp * 8)); 1912 #endif 1913 //pitch = pitch | (pitch << 16); 1914 1915 switch (crtc) { 1916 case 0: 1917 gencntl = RADEON_CRTC_GEN_CNTL; 1918 htotaldisp = RADEON_CRTC_H_TOTAL_DISP; 1919 hsyncstrt = RADEON_CRTC_H_SYNC_STRT_WID; 1920 vtotaldisp = RADEON_CRTC_V_TOTAL_DISP; 1921 vsyncstrt = RADEON_CRTC_V_SYNC_STRT_WID; 1922 fpvsyncstrt = RADEON_FP_V_SYNC_STRT_WID; 1923 fphsyncstrt = RADEON_FP_H_SYNC_STRT_WID; 1924 fpvtotaldisp = RADEON_FP_CRTC_V_TOTAL_DISP; 1925 fphtotaldisp = RADEON_FP_CRTC_H_TOTAL_DISP; 1926 break; 1927 case 1: 1928 gencntl = RADEON_CRTC2_GEN_CNTL; 1929 htotaldisp = RADEON_CRTC2_H_TOTAL_DISP; 1930 hsyncstrt = RADEON_CRTC2_H_SYNC_STRT_WID; 1931 vtotaldisp = RADEON_CRTC2_V_TOTAL_DISP; 1932 vsyncstrt = RADEON_CRTC2_V_SYNC_STRT_WID; 1933 fpvsyncstrt = RADEON_FP_V2_SYNC_STRT_WID; 1934 fphsyncstrt = RADEON_FP_H2_SYNC_STRT_WID; 1935 fpvtotaldisp = RADEON_FP_CRTC2_V_TOTAL_DISP; 1936 fphtotaldisp = RADEON_FP_CRTC2_H_TOTAL_DISP; 1937 break; 1938 default: 1939 panic("Bad CRTC!"); 1940 break; 1941 } 1942 1943 /* 1944 * CRTC_GEN_CNTL - depth, accelerator mode, etc. 1945 */ 1946 /* only bother with 32bpp and 8bpp */ 1947 v = dp->rd_format << RADEON_CRTC_PIX_WIDTH_SHIFT; 1948 1949 if (crtc == 1) { 1950 v |= RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_EN; 1951 } else { 1952 v |= RADEON_CRTC_EXT_DISP_EN | RADEON_CRTC_EN; 1953 } 1954 1955 if (mode->flags & VID_DBLSCAN) 1956 v |= RADEON_CRTC2_DBL_SCAN_EN; 1957 1958 if (mode->flags & VID_INTERLACE) 1959 v |= RADEON_CRTC2_INTERLACE_EN; 1960 1961 if (mode->flags & VID_CSYNC) { 1962 v |= RADEON_CRTC2_CSYNC_EN; 1963 if (crtc == 1) 1964 v |= RADEON_CRTC2_VSYNC_TRISTAT; 1965 } 1966 1967 PUT32(sc, gencntl, v); 1968 DPRINTF(("CRTC%s_GEN_CNTL = %08x\n", crtc ? "2" : "", v)); 1969 1970 /* 1971 * CRTC_EXT_CNTL - preserve disable flags, set ATI linear and EXT_CNT 1972 */ 1973 v = GET32(sc, RADEON_CRTC_EXT_CNTL); 1974 if (crtc == 0) { 1975 v &= (RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS | 1976 RADEON_CRTC_DISPLAY_DIS); 1977 v |= RADEON_XCRT_CNT_EN | RADEON_VGA_ATI_LINEAR; 1978 if (mode->flags & VID_CSYNC) 1979 v |= RADEON_CRTC_VSYNC_TRISTAT; 1980 } 1981 /* unconditional turn on CRT, in case first CRTC is DFP */ 1982 v |= RADEON_CRTC_CRT_ON; 1983 PUT32(sc, RADEON_CRTC_EXT_CNTL, v); 1984 PRINTREG(RADEON_CRTC_EXT_CNTL); 1985 1986 /* 1987 * H_TOTAL_DISP 1988 */ 1989 v = ((mode->hdisplay / 8) - 1) << 16; 1990 v |= (mode->htotal / 8) - 1; 1991 PUT32(sc, htotaldisp, v); 1992 DPRINTF(("CRTC%s_H_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 1993 PUT32(sc, fphtotaldisp, v); 1994 DPRINTF(("FP_H%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 1995 1996 /* 1997 * H_SYNC_STRT_WID 1998 */ 1999 v = (((mode->hsync_end - mode->hsync_start) / 8) << 16); 2000 v |= mode->hsync_start; 2001 if (mode->flags & VID_NHSYNC) 2002 v |= RADEON_CRTC_H_SYNC_POL; 2003 PUT32(sc, hsyncstrt, v); 2004 DPRINTF(("CRTC%s_H_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2005 PUT32(sc, fphsyncstrt, v); 2006 DPRINTF(("FP_H%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2007 2008 /* 2009 * V_TOTAL_DISP 2010 */ 2011 v = ((mode->vdisplay - 1) << 16); 2012 v |= (mode->vtotal - 1); 2013 PUT32(sc, vtotaldisp, v); 2014 DPRINTF(("CRTC%s_V_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 2015 PUT32(sc, fpvtotaldisp, v); 2016 DPRINTF(("FP_V%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 2017 2018 /* 2019 * V_SYNC_STRT_WID 2020 */ 2021 v = ((mode->vsync_end - mode->vsync_start) << 16); 2022 v |= (mode->vsync_start - 1); 2023 if (mode->flags & VID_NVSYNC) 2024 v |= RADEON_CRTC_V_SYNC_POL; 2025 PUT32(sc, vsyncstrt, v); 2026 DPRINTF(("CRTC%s_V_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2027 PUT32(sc, fpvsyncstrt, v); 2028 DPRINTF(("FP_V%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2029 2030 radeonfb_program_vclk(sc, mode->dot_clock, crtc); 2031 2032 switch (crtc) { 2033 case 0: 2034 PUT32(sc, RADEON_CRTC_OFFSET, 0); 2035 PUT32(sc, RADEON_CRTC_OFFSET_CNTL, 0); 2036 PUT32(sc, RADEON_CRTC_PITCH, pitch); 2037 CLR32(sc, RADEON_DISP_MERGE_CNTL, RADEON_DISP_RGB_OFFSET_EN); 2038 2039 CLR32(sc, RADEON_CRTC_EXT_CNTL, 2040 RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS | 2041 RADEON_CRTC_DISPLAY_DIS /* | RADEON_CRTC_DISP_REQ_EN_B */); 2042 CLR32(sc, RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B); 2043 PRINTREG(RADEON_CRTC_EXT_CNTL); 2044 PRINTREG(RADEON_CRTC_GEN_CNTL); 2045 PRINTREG(RADEON_CLOCK_CNTL_INDEX); 2046 break; 2047 2048 case 1: 2049 PUT32(sc, RADEON_CRTC2_OFFSET, 0); 2050 PUT32(sc, RADEON_CRTC2_OFFSET_CNTL, 0); 2051 PUT32(sc, RADEON_CRTC2_PITCH, pitch); 2052 CLR32(sc, RADEON_DISP2_MERGE_CNTL, RADEON_DISP2_RGB_OFFSET_EN); 2053 CLR32(sc, RADEON_CRTC2_GEN_CNTL, 2054 RADEON_CRTC2_VSYNC_DIS | 2055 RADEON_CRTC2_HSYNC_DIS | 2056 RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_DISP_REQ_EN_B); 2057 PRINTREG(RADEON_CRTC2_GEN_CNTL); 2058 break; 2059 } 2060 } 2061 2062 int 2063 radeonfb_isblank(struct radeonfb_display *dp) 2064 { 2065 uint32_t reg, mask; 2066 2067 if (dp->rd_crtcs[0].rc_number) { 2068 reg = RADEON_CRTC2_GEN_CNTL; 2069 mask = RADEON_CRTC2_DISP_DIS; 2070 } else { 2071 reg = RADEON_CRTC_EXT_CNTL; 2072 mask = RADEON_CRTC_DISPLAY_DIS; 2073 } 2074 return ((GET32(dp->rd_softc, reg) & mask) ? 1 : 0); 2075 } 2076 2077 void 2078 radeonfb_blank(struct radeonfb_display *dp, int blank) 2079 { 2080 struct radeonfb_softc *sc = dp->rd_softc; 2081 uint32_t reg, mask; 2082 uint32_t fpreg, fpval; 2083 int i; 2084 2085 for (i = 0; i < dp->rd_ncrtcs; i++) { 2086 2087 if (dp->rd_crtcs[i].rc_number) { 2088 reg = RADEON_CRTC2_GEN_CNTL; 2089 mask = RADEON_CRTC2_DISP_DIS; 2090 fpreg = RADEON_FP2_GEN_CNTL; 2091 fpval = RADEON_FP2_ON; 2092 } else { 2093 reg = RADEON_CRTC_EXT_CNTL; 2094 mask = RADEON_CRTC_DISPLAY_DIS; 2095 fpreg = RADEON_FP_GEN_CNTL; 2096 fpval = RADEON_FP_FPON; 2097 } 2098 2099 if (blank) { 2100 SET32(sc, reg, mask); 2101 CLR32(sc, fpreg, fpval); 2102 } else { 2103 CLR32(sc, reg, mask); 2104 SET32(sc, fpreg, fpval); 2105 } 2106 } 2107 PRINTREG(RADEON_FP_GEN_CNTL); 2108 PRINTREG(RADEON_FP2_GEN_CNTL); 2109 } 2110 2111 void 2112 radeonfb_init_screen(void *cookie, struct vcons_screen *scr, int existing, 2113 long *defattr) 2114 { 2115 struct radeonfb_display *dp = cookie; 2116 struct rasops_info *ri = &scr->scr_ri; 2117 2118 /* initialize font subsystem */ 2119 wsfont_init(); 2120 2121 DPRINTF(("init screen called, existing %d\n", existing)); 2122 2123 ri->ri_depth = dp->rd_bpp; 2124 ri->ri_width = dp->rd_virtx; 2125 ri->ri_height = dp->rd_virty; 2126 ri->ri_stride = dp->rd_stride; 2127 ri->ri_flg = RI_CENTER; 2128 ri->ri_bits = (void *)dp->rd_fbptr; 2129 2130 /* XXX: 32 bpp only */ 2131 /* this is rgb in "big-endian order..." */ 2132 ri->ri_rnum = 8; 2133 ri->ri_gnum = 8; 2134 ri->ri_bnum = 8; 2135 ri->ri_rpos = 16; 2136 ri->ri_gpos = 8; 2137 ri->ri_bpos = 0; 2138 2139 if (existing) { 2140 ri->ri_flg |= RI_CLEAR; 2141 2142 /* start a modeswitch now */ 2143 radeonfb_modeswitch(dp); 2144 } 2145 2146 /* 2147 * XXX: font selection should be based on properties, with some 2148 * normal/reasonable default. 2149 */ 2150 ri->ri_caps = WSSCREEN_WSCOLORS; 2151 2152 /* initialize and look for an initial font */ 2153 rasops_init(ri, dp->rd_virty/8, dp->rd_virtx/8); 2154 2155 rasops_reconfig(ri, dp->rd_virty / ri->ri_font->fontheight, 2156 dp->rd_virtx / ri->ri_font->fontwidth); 2157 2158 /* enable acceleration */ 2159 ri->ri_ops.copyrows = radeonfb_copyrows; 2160 ri->ri_ops.copycols = radeonfb_copycols; 2161 ri->ri_ops.eraserows = radeonfb_eraserows; 2162 ri->ri_ops.erasecols = radeonfb_erasecols; 2163 ri->ri_ops.allocattr = radeonfb_allocattr; 2164 if (!IS_R300(dp->rd_softc)) { 2165 ri->ri_ops.putchar = radeonfb_putchar; 2166 } 2167 ri->ri_ops.cursor = radeonfb_cursor; 2168 } 2169 2170 void 2171 radeonfb_set_fbloc(struct radeonfb_softc *sc) 2172 { 2173 uint32_t gen, ext, gen2 = 0; 2174 uint32_t agploc, aperbase, apersize, mcfbloc; 2175 2176 gen = GET32(sc, RADEON_CRTC_GEN_CNTL); 2177 ext = GET32(sc, RADEON_CRTC_EXT_CNTL); 2178 agploc = GET32(sc, RADEON_MC_AGP_LOCATION); 2179 aperbase = GET32(sc, RADEON_CONFIG_APER_0_BASE); 2180 apersize = GET32(sc, RADEON_CONFIG_APER_SIZE); 2181 2182 PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISP_REQ_EN_B); 2183 PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISPLAY_DIS); 2184 //PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISPLAY_DIS); 2185 //PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISP_REQ_EN_B); 2186 2187 if (HAS_CRTC2(sc)) { 2188 gen2 = GET32(sc, RADEON_CRTC2_GEN_CNTL); 2189 PUT32(sc, RADEON_CRTC2_GEN_CNTL, 2190 gen2 | RADEON_CRTC2_DISP_REQ_EN_B); 2191 } 2192 2193 delay(100000); 2194 2195 mcfbloc = (aperbase >> 16) | 2196 ((aperbase + (apersize - 1)) & 0xffff0000); 2197 2198 sc->sc_aperbase = (mcfbloc & 0xffff) << 16; 2199 sc->sc_memsz = apersize; 2200 2201 if (((agploc & 0xffff) << 16) != 2202 ((mcfbloc & 0xffff0000U) + 0x10000)) { 2203 agploc = mcfbloc & 0xffff0000U; 2204 agploc |= ((agploc + 0x10000) >> 16); 2205 } 2206 2207 PUT32(sc, RADEON_HOST_PATH_CNTL, 0); 2208 2209 PUT32(sc, RADEON_MC_FB_LOCATION, mcfbloc); 2210 PUT32(sc, RADEON_MC_AGP_LOCATION, agploc); 2211 2212 DPRINTF(("aperbase = %u\n", aperbase)); 2213 PRINTREG(RADEON_MC_FB_LOCATION); 2214 PRINTREG(RADEON_MC_AGP_LOCATION); 2215 2216 PUT32(sc, RADEON_DISPLAY_BASE_ADDR, sc->sc_aperbase); 2217 2218 if (HAS_CRTC2(sc)) 2219 PUT32(sc, RADEON_DISPLAY2_BASE_ADDR, sc->sc_aperbase); 2220 2221 PUT32(sc, RADEON_OV0_BASE_ADDR, sc->sc_aperbase); 2222 2223 #if 0 2224 /* XXX: what is this AGP garbage? :-) */ 2225 PUT32(sc, RADEON_AGP_CNTL, 0x00100000); 2226 #endif 2227 2228 delay(100000); 2229 2230 PUT32(sc, RADEON_CRTC_GEN_CNTL, gen); 2231 PUT32(sc, RADEON_CRTC_EXT_CNTL, ext); 2232 2233 if (HAS_CRTC2(sc)) 2234 PUT32(sc, RADEON_CRTC2_GEN_CNTL, gen2); 2235 } 2236 2237 void 2238 radeonfb_init_misc(struct radeonfb_softc *sc) 2239 { 2240 PUT32(sc, RADEON_BUS_CNTL, 2241 RADEON_BUS_MASTER_DIS | 2242 RADEON_BUS_PREFETCH_MODE_ACT | 2243 RADEON_BUS_PCI_READ_RETRY_EN | 2244 RADEON_BUS_PCI_WRT_RETRY_EN | 2245 (3 << RADEON_BUS_RETRY_WS_SHIFT) | 2246 RADEON_BUS_MSTR_RD_MULT | 2247 RADEON_BUS_MSTR_RD_LINE | 2248 RADEON_BUS_RD_DISCARD_EN | 2249 RADEON_BUS_MSTR_DISCONNECT_EN | 2250 RADEON_BUS_READ_BURST); 2251 2252 PUT32(sc, RADEON_BUS_CNTL1, 0xf0); 2253 /* PUT32(sc, RADEON_SEPROM_CNTL1, 0x09ff0000); */ 2254 PUT32(sc, RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); 2255 PUT32(sc, RADEON_RBBM_CNTL, 2256 (3 << RADEON_RB_SETTLE_SHIFT) | 2257 (4 << RADEON_ABORTCLKS_HI_SHIFT) | 2258 (4 << RADEON_ABORTCLKS_CP_SHIFT) | 2259 (4 << RADEON_ABORTCLKS_CFIFO_SHIFT)); 2260 2261 /* XXX: figure out what these mean! */ 2262 PUT32(sc, RADEON_AGP_CNTL, 0x00100000); 2263 PUT32(sc, RADEON_HOST_PATH_CNTL, 0); 2264 //PUT32(sc, RADEON_DISP_MISC_CNTL, 0x5bb00400); 2265 2266 PUT32(sc, RADEON_GEN_INT_CNTL, 0); 2267 PUT32(sc, RADEON_GEN_INT_STATUS, GET32(sc, RADEON_GEN_INT_STATUS)); 2268 } 2269 2270 /* 2271 * This loads a linear color map for true color. 2272 */ 2273 void 2274 radeonfb_init_palette(struct radeonfb_softc *sc, int crtc) 2275 { 2276 int i; 2277 uint32_t vclk; 2278 2279 #define DAC_WIDTH ((1 << 10) - 1) 2280 #define CLUT_WIDTH ((1 << 8) - 1) 2281 #define CLUT_COLOR(i) ((i * DAC_WIDTH * 2 / CLUT_WIDTH + 1) / 2) 2282 2283 vclk = GETPLL(sc, RADEON_VCLK_ECP_CNTL); 2284 PUTPLL(sc, RADEON_VCLK_ECP_CNTL, vclk & ~RADEON_PIXCLK_DAC_ALWAYS_ONb); 2285 2286 if (crtc) 2287 SET32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL); 2288 else 2289 CLR32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL); 2290 2291 PUT32(sc, RADEON_PALETTE_INDEX, 0); 2292 for (i = 0; i <= CLUT_WIDTH; ++i) { 2293 PUT32(sc, RADEON_PALETTE_30_DATA, 2294 (CLUT_COLOR(i) << 10) | 2295 (CLUT_COLOR(i) << 20) | 2296 (CLUT_COLOR(i))); 2297 } 2298 2299 CLR32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL); 2300 PRINTREG(RADEON_DAC_CNTL2); 2301 2302 PUTPLL(sc, RADEON_VCLK_ECP_CNTL, vclk); 2303 } 2304 2305 /* 2306 * Bugs in some R300 hardware requires this when accessing CLOCK_CNTL_INDEX. 2307 */ 2308 void 2309 radeonfb_r300cg_workaround(struct radeonfb_softc *sc) 2310 { 2311 uint32_t tmp, save; 2312 2313 save = GET32(sc, RADEON_CLOCK_CNTL_INDEX); 2314 tmp = save & ~(0x3f | RADEON_PLL_WR_EN); 2315 PUT32(sc, RADEON_CLOCK_CNTL_INDEX, tmp); 2316 tmp = GET32(sc, RADEON_CLOCK_CNTL_DATA); 2317 PUT32(sc, RADEON_CLOCK_CNTL_INDEX, save); 2318 } 2319 2320 /* 2321 * Acceleration entry points. 2322 */ 2323 static void 2324 radeonfb_putchar(void *cookie, int row, int col, u_int c, long attr) 2325 { 2326 struct rasops_info *ri = cookie; 2327 struct vcons_screen *scr = ri->ri_hw; 2328 struct radeonfb_display *dp = scr->scr_cookie; 2329 uint32_t x, y, w, h; 2330 uint32_t bg, fg; 2331 uint8_t *data; 2332 2333 if (dp->rd_wsmode != WSDISPLAYIO_MODE_EMUL) 2334 return; 2335 2336 if (!CHAR_IN_FONT(c, ri->ri_font)) 2337 return; 2338 2339 w = ri->ri_font->fontwidth; 2340 h = ri->ri_font->fontheight; 2341 2342 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 2343 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 2344 2345 x = ri->ri_xorigin + col * w; 2346 y = ri->ri_yorigin + row * h; 2347 2348 if (c == 0x20) { 2349 radeonfb_rectfill(dp, x, y, w, h, bg); 2350 } else { 2351 data = (uint8_t *)ri->ri_font->data + 2352 (c - ri->ri_font->firstchar) * ri->ri_fontscale; 2353 2354 radeonfb_setup_mono(dp, x, y, w, h, fg, bg); 2355 radeonfb_feed_bytes(dp, ri->ri_fontscale, data); 2356 } 2357 } 2358 2359 static void 2360 radeonfb_eraserows(void *cookie, int row, int nrows, long fillattr) 2361 { 2362 struct rasops_info *ri = cookie; 2363 struct vcons_screen *scr = ri->ri_hw; 2364 struct radeonfb_display *dp = scr->scr_cookie; 2365 uint32_t x, y, w, h, fg, bg, ul; 2366 2367 /* XXX: check for full emulation mode? */ 2368 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 2369 x = ri->ri_xorigin; 2370 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 2371 w = ri->ri_emuwidth; 2372 h = ri->ri_font->fontheight * nrows; 2373 2374 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 2375 radeonfb_rectfill(dp, x, y, w, h, ri->ri_devcmap[bg & 0xf]); 2376 } 2377 } 2378 2379 static void 2380 radeonfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 2381 { 2382 struct rasops_info *ri = cookie; 2383 struct vcons_screen *scr = ri->ri_hw; 2384 struct radeonfb_display *dp = scr->scr_cookie; 2385 uint32_t x, ys, yd, w, h; 2386 2387 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 2388 x = ri->ri_xorigin; 2389 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 2390 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 2391 w = ri->ri_emuwidth; 2392 h = ri->ri_font->fontheight * nrows; 2393 radeonfb_bitblt(dp, x, ys, x, yd, w, h, 2394 RADEON_ROP3_S, 0xffffffff); 2395 } 2396 } 2397 2398 static void 2399 radeonfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 2400 { 2401 struct rasops_info *ri = cookie; 2402 struct vcons_screen *scr = ri->ri_hw; 2403 struct radeonfb_display *dp = scr->scr_cookie; 2404 uint32_t xs, xd, y, w, h; 2405 2406 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 2407 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 2408 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 2409 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 2410 w = ri->ri_font->fontwidth * ncols; 2411 h = ri->ri_font->fontheight; 2412 radeonfb_bitblt(dp, xs, y, xd, y, w, h, 2413 RADEON_ROP3_S, 0xffffffff); 2414 } 2415 } 2416 2417 static void 2418 radeonfb_erasecols(void *cookie, int row, int startcol, int ncols, 2419 long fillattr) 2420 { 2421 struct rasops_info *ri = cookie; 2422 struct vcons_screen *scr = ri->ri_hw; 2423 struct radeonfb_display *dp = scr->scr_cookie; 2424 uint32_t x, y, w, h, fg, bg, ul; 2425 2426 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 2427 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 2428 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 2429 w = ri->ri_font->fontwidth * ncols; 2430 h = ri->ri_font->fontheight; 2431 2432 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 2433 radeonfb_rectfill(dp, x, y, w, h, ri->ri_devcmap[bg & 0xf]); 2434 } 2435 } 2436 2437 static void 2438 radeonfb_cursor(void *cookie, int on, int row, int col) 2439 { 2440 struct rasops_info *ri = cookie; 2441 struct vcons_screen *scr = ri->ri_hw; 2442 struct radeonfb_display *dp = scr->scr_cookie; 2443 int x, y, wi, he; 2444 2445 wi = ri->ri_font->fontwidth; 2446 he = ri->ri_font->fontheight; 2447 2448 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 2449 x = ri->ri_ccol * wi + ri->ri_xorigin; 2450 y = ri->ri_crow * he + ri->ri_yorigin; 2451 /* first turn off the old cursor */ 2452 if (ri->ri_flg & RI_CURSOR) { 2453 radeonfb_bitblt(dp, x, y, x, y, wi, he, 2454 RADEON_ROP3_Dn, 0xffffffff); 2455 ri->ri_flg &= ~RI_CURSOR; 2456 } 2457 ri->ri_crow = row; 2458 ri->ri_ccol = col; 2459 /* then (possibly) turn on the new one */ 2460 if (on) { 2461 x = ri->ri_ccol * wi + ri->ri_xorigin; 2462 y = ri->ri_crow * he + ri->ri_yorigin; 2463 radeonfb_bitblt(dp, x, y, x, y, wi, he, 2464 RADEON_ROP3_Dn, 0xffffffff); 2465 ri->ri_flg |= RI_CURSOR; 2466 } 2467 } else { 2468 scr->scr_ri.ri_crow = row; 2469 scr->scr_ri.ri_ccol = col; 2470 scr->scr_ri.ri_flg &= ~RI_CURSOR; 2471 } 2472 } 2473 2474 static int 2475 radeonfb_allocattr(void *cookie, int fg, int bg, int flags, long *attrp) 2476 { 2477 if ((fg == 0) && (bg == 0)) { 2478 fg = WS_DEFAULT_FG; 2479 bg = WS_DEFAULT_BG; 2480 } 2481 *attrp = ((fg & 0xf) << 24) | ((bg & 0xf) << 16) | (flags & 0xff) << 8; 2482 return 0; 2483 } 2484 2485 /* 2486 * Underlying acceleration support. 2487 */ 2488 static void 2489 radeonfb_setup_mono(struct radeonfb_display *dp, int xd, int yd, int width, 2490 int height, uint32_t fg, uint32_t bg) 2491 { 2492 struct radeonfb_softc *sc = dp->rd_softc; 2493 uint32_t gmc; 2494 uint32_t padded_width = (width+7) & 0xfff8; 2495 uint32_t topleft, bottomright; 2496 2497 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 2498 2499 if (width != padded_width) { 2500 2501 radeonfb_wait_fifo(sc, 2); 2502 topleft = ((yd << 16) & 0x1fff0000) | (xd & 0x1fff); 2503 bottomright = (((yd + height) << 16) & 0x1fff0000) | 2504 ((xd + width) & 0x1fff); 2505 PUT32(sc, RADEON_SC_TOP_LEFT, topleft); 2506 PUT32(sc, RADEON_SC_BOTTOM_RIGHT, bottomright); 2507 } 2508 2509 radeonfb_wait_fifo(sc, 5); 2510 2511 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 2512 RADEON_GMC_BRUSH_NONE | 2513 RADEON_GMC_SRC_DATATYPE_MONO_FG_BG | 2514 //RADEON_GMC_BYTE_LSB_TO_MSB | 2515 RADEON_GMC_DST_CLIPPING | 2516 RADEON_ROP3_S | 2517 RADEON_DP_SRC_SOURCE_HOST_DATA | 2518 RADEON_GMC_CLR_CMP_CNTL_DIS | 2519 RADEON_GMC_WR_MSK_DIS | 2520 gmc); 2521 2522 PUT32(sc, RADEON_DP_SRC_FRGD_CLR, fg); 2523 PUT32(sc, RADEON_DP_SRC_BKGD_CLR, bg); 2524 2525 PUT32(sc, RADEON_DST_X_Y, (xd << 16) | yd); 2526 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (padded_width << 16) | height); 2527 2528 } 2529 2530 static void 2531 radeonfb_feed_bytes(struct radeonfb_display *dp, int count, uint8_t *data) 2532 { 2533 struct radeonfb_softc *sc = dp->rd_softc; 2534 int i; 2535 uint32_t latch = 0; 2536 int shift = 0; 2537 2538 for (i = 0; i < count; i++) { 2539 latch |= (data[i] << shift); 2540 if (shift == 24) { 2541 radeonfb_wait_fifo(sc, 1); 2542 PUT32(sc, RADEON_HOST_DATA0, latch); 2543 latch = 0; 2544 shift = 0; 2545 } else 2546 shift += 8; 2547 } 2548 if (shift != 0) { 2549 radeonfb_wait_fifo(sc, 1); 2550 PUT32(sc, RADEON_HOST_DATA0, latch); 2551 } 2552 radeonfb_unclip(sc); 2553 } 2554 2555 static void 2556 radeonfb_rectfill(struct radeonfb_display *dp, int dstx, int dsty, 2557 int width, int height, uint32_t color) 2558 { 2559 struct radeonfb_softc *sc = dp->rd_softc; 2560 uint32_t gmc; 2561 2562 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 2563 2564 radeonfb_wait_fifo(sc, 6); 2565 2566 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 2567 RADEON_GMC_BRUSH_SOLID_COLOR | 2568 RADEON_GMC_SRC_DATATYPE_COLOR | 2569 RADEON_GMC_CLR_CMP_CNTL_DIS | 2570 RADEON_ROP3_P | gmc); 2571 2572 PUT32(sc, RADEON_DP_BRUSH_FRGD_CLR, color); 2573 PUT32(sc, RADEON_DP_WRITE_MASK, 0xffffffff); 2574 PUT32(sc, RADEON_DP_CNTL, 2575 RADEON_DST_X_LEFT_TO_RIGHT | 2576 RADEON_DST_Y_TOP_TO_BOTTOM); 2577 PUT32(sc, RADEON_DST_Y_X, (dsty << 16) | dstx); 2578 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (width << 16) | (height)); 2579 2580 /* 2581 * XXX: we don't wait for the fifo to empty -- that would slow 2582 * things down! The linux radeonfb driver waits, but xfree doesn't 2583 */ 2584 /* XXX: for now we do, to make it safe for direct drawing */ 2585 radeonfb_engine_idle(sc); 2586 } 2587 2588 static void 2589 radeonfb_bitblt(struct radeonfb_display *dp, int srcx, int srcy, 2590 int dstx, int dsty, int width, int height, int rop, uint32_t mask) 2591 { 2592 struct radeonfb_softc *sc = dp->rd_softc; 2593 uint32_t gmc; 2594 uint32_t dir; 2595 2596 if (dsty < srcy) { 2597 dir = RADEON_DST_Y_TOP_TO_BOTTOM; 2598 } else { 2599 srcy += height - 1; 2600 dsty += height - 1; 2601 dir = 0; 2602 } 2603 if (dstx < srcx) { 2604 dir |= RADEON_DST_X_LEFT_TO_RIGHT; 2605 } else { 2606 srcx += width - 1; 2607 dstx += width - 1; 2608 } 2609 2610 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 2611 2612 radeonfb_wait_fifo(sc, 6); 2613 2614 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 2615 //RADEON_GMC_SRC_CLIPPING | 2616 RADEON_GMC_BRUSH_SOLID_COLOR | 2617 RADEON_GMC_SRC_DATATYPE_COLOR | 2618 RADEON_GMC_CLR_CMP_CNTL_DIS | 2619 RADEON_DP_SRC_SOURCE_MEMORY | 2620 rop | gmc); 2621 2622 PUT32(sc, RADEON_DP_WRITE_MASK, mask); 2623 PUT32(sc, RADEON_DP_CNTL, dir); 2624 PUT32(sc, RADEON_SRC_Y_X, (srcy << 16) | srcx); 2625 PUT32(sc, RADEON_DST_Y_X, (dsty << 16) | dstx); 2626 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (width << 16) | (height)); 2627 2628 /* 2629 * XXX: we don't wait for the fifo to empty -- that would slow 2630 * things down! The linux radeonfb driver waits, but xfree doesn't 2631 */ 2632 /* XXX: for now we do, to make it safe for direct drawing */ 2633 radeonfb_engine_idle(sc); 2634 } 2635 2636 static void 2637 radeonfb_engine_idle(struct radeonfb_softc *sc) 2638 { 2639 int i; 2640 2641 radeonfb_wait_fifo(sc, 64); 2642 for (i = RADEON_TIMEOUT; i; i--) { 2643 if ((GET32(sc, RADEON_RBBM_STATUS) & 2644 RADEON_RBBM_ACTIVE) == 0) { 2645 radeonfb_engine_flush(sc); 2646 break; 2647 } 2648 } 2649 } 2650 2651 static void 2652 radeonfb_wait_fifo(struct radeonfb_softc *sc, int n) 2653 { 2654 int i; 2655 2656 for (i = RADEON_TIMEOUT; i; i--) { 2657 if ((GET32(sc, RADEON_RBBM_STATUS) & 2658 RADEON_RBBM_FIFOCNT_MASK) >= n) 2659 return; 2660 } 2661 #ifdef DIAGNOSTIC 2662 if (!i) 2663 printf("%s: timed out waiting for fifo (%x)\n", 2664 XNAME(sc), GET32(sc, RADEON_RBBM_STATUS)); 2665 #endif 2666 } 2667 2668 static void 2669 radeonfb_engine_flush(struct radeonfb_softc *sc) 2670 { 2671 int i; 2672 SET32(sc, RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 2673 for (i = RADEON_TIMEOUT; i; i--) { 2674 if ((GET32(sc, RADEON_RB2D_DSTCACHE_CTLSTAT) & 2675 RADEON_RB2D_DC_BUSY) == 0) 2676 break; 2677 } 2678 #ifdef DIAGNOSTIC 2679 if (!i) 2680 printf("%s: engine flush timed out!\n", XNAME(sc)); 2681 #endif 2682 } 2683 2684 static inline void 2685 radeonfb_unclip(struct radeonfb_softc *sc) 2686 { 2687 2688 radeonfb_wait_fifo(sc, 2); 2689 PUT32(sc, RADEON_SC_TOP_LEFT, 0); 2690 PUT32(sc, RADEON_SC_BOTTOM_RIGHT, 0x1fff1fff); 2691 } 2692 2693 static void 2694 radeonfb_engine_init(struct radeonfb_display *dp) 2695 { 2696 struct radeonfb_softc *sc = dp->rd_softc; 2697 uint32_t pitch; 2698 2699 /* no 3D */ 2700 PUT32(sc, RADEON_RB3D_CNTL, 0); 2701 2702 radeonfb_engine_reset(sc); 2703 pitch = ((dp->rd_virtx * (dp->rd_bpp / 8) + 0x3f)) >> 6; 2704 //pitch = ((sc->sc_maxx * (sc->sc_maxbpp / 8) + 0x3f)) >> 6; 2705 2706 radeonfb_wait_fifo(sc, 1); 2707 if (!IS_R300(sc)) 2708 PUT32(sc, RADEON_RB2D_DSTCACHE_MODE, 0); 2709 2710 radeonfb_wait_fifo(sc, 3); 2711 PUT32(sc, RADEON_DEFAULT_PITCH_OFFSET, 2712 (pitch << 22) | (sc->sc_aperbase >> 10)); 2713 2714 2715 PUT32(sc, RADEON_DST_PITCH_OFFSET, 2716 (pitch << 22) | (sc->sc_aperbase >> 10)); 2717 PUT32(sc, RADEON_SRC_PITCH_OFFSET, 2718 (pitch << 22) | (sc->sc_aperbase >> 10)); 2719 2720 radeonfb_wait_fifo(sc, 1); 2721 #if _BYTE_ORDER == _BIG_ENDIAN 2722 SET32(sc, RADEON_DP_DATATYPE, RADEON_HOST_BIG_ENDIAN_EN); 2723 #else 2724 CLR32(sc, RADEON_DP_DATATYPE, RADEON_HOST_BIG_ENDIAN_EN); 2725 #endif 2726 2727 /* default scissors -- no clipping */ 2728 radeonfb_wait_fifo(sc, 1); 2729 PUT32(sc, RADEON_DEFAULT_SC_BOTTOM_RIGHT, 2730 RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX); 2731 2732 radeonfb_wait_fifo(sc, 1); 2733 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 2734 (dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT) | 2735 RADEON_GMC_CLR_CMP_CNTL_DIS | 2736 RADEON_GMC_BRUSH_SOLID_COLOR | 2737 RADEON_GMC_SRC_DATATYPE_COLOR); 2738 2739 radeonfb_wait_fifo(sc, 7); 2740 PUT32(sc, RADEON_DST_LINE_START, 0); 2741 PUT32(sc, RADEON_DST_LINE_END, 0); 2742 PUT32(sc, RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); 2743 PUT32(sc, RADEON_DP_BRUSH_BKGD_CLR, 0); 2744 PUT32(sc, RADEON_DP_SRC_FRGD_CLR, 0xffffffff); 2745 PUT32(sc, RADEON_DP_SRC_BKGD_CLR, 0); 2746 PUT32(sc, RADEON_DP_WRITE_MASK, 0xffffffff); 2747 2748 radeonfb_engine_idle(sc); 2749 } 2750 2751 static void 2752 radeonfb_engine_reset(struct radeonfb_softc *sc) 2753 { 2754 uint32_t hpc, rbbm, mclkcntl, clkindex; 2755 2756 radeonfb_engine_flush(sc); 2757 2758 clkindex = GET32(sc, RADEON_CLOCK_CNTL_INDEX); 2759 if (HAS_R300CG(sc)) 2760 radeonfb_r300cg_workaround(sc); 2761 mclkcntl = GETPLL(sc, RADEON_MCLK_CNTL); 2762 2763 /* 2764 * According to comments in XFree code, resetting the HDP via 2765 * the RBBM_SOFT_RESET can cause bad behavior on some systems. 2766 * So we use HOST_PATH_CNTL instead. 2767 */ 2768 2769 hpc = GET32(sc, RADEON_HOST_PATH_CNTL); 2770 rbbm = GET32(sc, RADEON_RBBM_SOFT_RESET); 2771 if (IS_R300(sc)) { 2772 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm | 2773 RADEON_SOFT_RESET_CP | 2774 RADEON_SOFT_RESET_HI | 2775 RADEON_SOFT_RESET_E2); 2776 GET32(sc, RADEON_RBBM_SOFT_RESET); 2777 PUT32(sc, RADEON_RBBM_SOFT_RESET, 0); 2778 /* 2779 * XXX: this bit is not defined in any ATI docs I have, 2780 * nor in the XFree code, but XFree does it. Why? 2781 */ 2782 SET32(sc, RADEON_RB2D_DSTCACHE_MODE, (1<<17)); 2783 } else { 2784 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm | 2785 RADEON_SOFT_RESET_CP | 2786 RADEON_SOFT_RESET_SE | 2787 RADEON_SOFT_RESET_RE | 2788 RADEON_SOFT_RESET_PP | 2789 RADEON_SOFT_RESET_E2 | 2790 RADEON_SOFT_RESET_RB); 2791 GET32(sc, RADEON_RBBM_SOFT_RESET); 2792 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm & 2793 ~(RADEON_SOFT_RESET_CP | 2794 RADEON_SOFT_RESET_SE | 2795 RADEON_SOFT_RESET_RE | 2796 RADEON_SOFT_RESET_PP | 2797 RADEON_SOFT_RESET_E2 | 2798 RADEON_SOFT_RESET_RB)); 2799 GET32(sc, RADEON_RBBM_SOFT_RESET); 2800 } 2801 2802 PUT32(sc, RADEON_HOST_PATH_CNTL, hpc | RADEON_HDP_SOFT_RESET); 2803 GET32(sc, RADEON_HOST_PATH_CNTL); 2804 PUT32(sc, RADEON_HOST_PATH_CNTL, hpc); 2805 2806 if (IS_R300(sc)) 2807 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm); 2808 2809 PUT32(sc, RADEON_CLOCK_CNTL_INDEX, clkindex); 2810 PUTPLL(sc, RADEON_MCLK_CNTL, mclkcntl); 2811 2812 if (HAS_R300CG(sc)) 2813 radeonfb_r300cg_workaround(sc); 2814 } 2815 2816 static int 2817 radeonfb_set_curpos(struct radeonfb_display *dp, struct wsdisplay_curpos *pos) 2818 { 2819 int x, y; 2820 2821 x = pos->x; 2822 y = pos->y; 2823 2824 /* 2825 * This doesn't let a cursor move off the screen. I'm not 2826 * sure if this will have negative effects for e.g. Xinerama. 2827 * I'd guess Xinerama handles it by changing the cursor shape, 2828 * but that needs verification. 2829 */ 2830 if (x >= dp->rd_virtx) 2831 x = dp->rd_virtx - 1; 2832 if (x < 0) 2833 x = 0; 2834 if (y >= dp->rd_virty) 2835 y = dp->rd_virty - 1; 2836 if (y < 0) 2837 y = 0; 2838 2839 dp->rd_cursor.rc_pos.x = x; 2840 dp->rd_cursor.rc_pos.y = y; 2841 2842 radeonfb_cursor_position(dp); 2843 return 0; 2844 } 2845 2846 static int 2847 radeonfb_set_cursor(struct radeonfb_display *dp, struct wsdisplay_cursor *wc) 2848 { 2849 unsigned flags; 2850 2851 uint8_t r[2], g[2], b[2]; 2852 unsigned index, count; 2853 int i, err; 2854 int pitch, size; 2855 struct radeonfb_cursor nc; 2856 2857 flags = wc->which; 2858 2859 /* copy old values */ 2860 nc = dp->rd_cursor; 2861 2862 if (flags & WSDISPLAY_CURSOR_DOCMAP) { 2863 index = wc->cmap.index; 2864 count = wc->cmap.count; 2865 2866 if (index >= 2 || (index + count) > 2) 2867 return EINVAL; 2868 2869 err = copyin(wc->cmap.red, &r[index], count); 2870 if (err) 2871 return err; 2872 err = copyin(wc->cmap.green, &g[index], count); 2873 if (err) 2874 return err; 2875 err = copyin(wc->cmap.blue, &b[index], count); 2876 if (err) 2877 return err; 2878 2879 for (i = index; i < index + count; i++) { 2880 nc.rc_cmap[i] = 2881 (r[i] << 16) + (g[i] << 8) + (b[i] << 0); 2882 } 2883 } 2884 2885 if (flags & WSDISPLAY_CURSOR_DOSHAPE) { 2886 if ((wc->size.x > RADEON_CURSORMAXX) || 2887 (wc->size.y > RADEON_CURSORMAXY)) 2888 return EINVAL; 2889 2890 /* figure bytes per line */ 2891 pitch = (wc->size.x + 7) / 8; 2892 size = pitch * wc->size.y; 2893 2894 /* clear the old cursor and mask */ 2895 memset(nc.rc_image, 0, 512); 2896 memset(nc.rc_mask, 0, 512); 2897 2898 nc.rc_size = wc->size; 2899 2900 if ((err = copyin(wc->image, nc.rc_image, size)) != 0) 2901 return err; 2902 2903 if ((err = copyin(wc->mask, nc.rc_mask, size)) != 0) 2904 return err; 2905 } 2906 2907 if (flags & WSDISPLAY_CURSOR_DOHOT) { 2908 nc.rc_hot = wc->hot; 2909 if (nc.rc_hot.x >= nc.rc_size.x) 2910 nc.rc_hot.x = nc.rc_size.x - 1; 2911 if (nc.rc_hot.y >= nc.rc_size.y) 2912 nc.rc_hot.y = nc.rc_size.y - 1; 2913 } 2914 2915 if (flags & WSDISPLAY_CURSOR_DOPOS) { 2916 nc.rc_pos = wc->pos; 2917 if (nc.rc_pos.x >= dp->rd_virtx) 2918 nc.rc_pos.x = dp->rd_virtx - 1; 2919 #if 0 2920 if (nc.rc_pos.x < 0) 2921 nc.rc_pos.x = 0; 2922 #endif 2923 if (nc.rc_pos.y >= dp->rd_virty) 2924 nc.rc_pos.y = dp->rd_virty - 1; 2925 #if 0 2926 if (nc.rc_pos.y < 0) 2927 nc.rc_pos.y = 0; 2928 #endif 2929 } 2930 if (flags & WSDISPLAY_CURSOR_DOCUR) { 2931 nc.rc_visible = wc->enable; 2932 } 2933 2934 dp->rd_cursor = nc; 2935 radeonfb_cursor_update(dp, wc->which); 2936 2937 return 0; 2938 } 2939 2940 /* 2941 * Change the cursor shape. Call this with the cursor locked to avoid 2942 * flickering/tearing. 2943 */ 2944 static void 2945 radeonfb_cursor_shape(struct radeonfb_display *dp) 2946 { 2947 uint8_t and[512], xor[512]; 2948 int i, j, src, dst, pitch; 2949 const uint8_t *msk = dp->rd_cursor.rc_mask; 2950 const uint8_t *img = dp->rd_cursor.rc_image; 2951 2952 /* 2953 * Radeon cursor data interleaves one line of AND data followed 2954 * by a line of XOR data. (Each line corresponds to a whole hardware 2955 * pitch - i.e. 64 pixels or 8 bytes.) 2956 * 2957 * The cursor is displayed using the following table: 2958 * 2959 * AND XOR Result 2960 * ---------------------- 2961 * 0 0 Cursor color 0 2962 * 0 1 Cursor color 1 2963 * 1 0 Transparent 2964 * 1 1 Complement of background 2965 * 2966 * Our masks are therefore different from what we were passed. 2967 * Passed in, I'm assuming the data represents either color 0 or 1, 2968 * and a mask, so the passed in table looks like: 2969 * 2970 * IMG Mask Result 2971 * ----------------------- 2972 * 0 0 Transparent 2973 * 0 1 Cursor color 0 2974 * 1 0 Transparent 2975 * 1 1 Cursor color 1 2976 * 2977 * IF mask bit == 1, AND = 0, XOR = color. 2978 * IF mask bit == 0, AND = 1, XOR = 0. 2979 * 2980 * hence: AND = ~(mask); XOR = color & ~(mask); 2981 */ 2982 2983 pitch = ((dp->rd_cursor.rc_size.x + 7) / 8); 2984 2985 /* start by assuming all bits are transparent */ 2986 memset(and, 0xff, 512); 2987 memset(xor, 0x00, 512); 2988 2989 src = 0; 2990 dst = 0; 2991 for (i = 0; i < 64; i++) { 2992 for (j = 0; j < 64; j += 8) { 2993 if ((i < dp->rd_cursor.rc_size.y) && 2994 (j < dp->rd_cursor.rc_size.x)) { 2995 2996 /* take care to leave odd bits alone */ 2997 and[dst] &= ~(msk[src]); 2998 xor[dst] = img[src] & msk[src]; 2999 src++; 3000 } 3001 dst++; 3002 } 3003 } 3004 3005 /* copy the image into place */ 3006 for (i = 0; i < 64; i++) { 3007 memcpy((uint8_t *)dp->rd_curptr + (i * 16), 3008 &and[i * 8], 8); 3009 memcpy((uint8_t *)dp->rd_curptr + (i * 16) + 8, 3010 &xor[i * 8], 8); 3011 } 3012 } 3013 3014 static void 3015 radeonfb_cursor_position(struct radeonfb_display *dp) 3016 { 3017 struct radeonfb_softc *sc = dp->rd_softc; 3018 uint32_t offset, hvoff, hvpos; /* registers */ 3019 uint32_t coff; /* cursor offset */ 3020 int i, x, y, xoff, yoff, crtcoff; 3021 3022 /* 3023 * XXX: this also needs to handle pan/scan 3024 */ 3025 for (i = 0; i < dp->rd_ncrtcs; i++) { 3026 3027 struct radeonfb_crtc *rcp = &dp->rd_crtcs[i]; 3028 3029 if (rcp->rc_number) { 3030 offset = RADEON_CUR2_OFFSET; 3031 hvoff = RADEON_CUR2_HORZ_VERT_OFF; 3032 hvpos = RADEON_CUR2_HORZ_VERT_POSN; 3033 crtcoff = RADEON_CRTC2_OFFSET; 3034 } else { 3035 offset = RADEON_CUR_OFFSET; 3036 hvoff = RADEON_CUR_HORZ_VERT_OFF; 3037 hvpos = RADEON_CUR_HORZ_VERT_POSN; 3038 crtcoff = RADEON_CRTC_OFFSET; 3039 } 3040 3041 x = dp->rd_cursor.rc_pos.x; 3042 y = dp->rd_cursor.rc_pos.y; 3043 3044 while (y < rcp->rc_yoffset) { 3045 rcp->rc_yoffset -= RADEON_PANINCREMENT; 3046 } 3047 while (y >= (rcp->rc_yoffset + rcp->rc_videomode.vdisplay)) { 3048 rcp->rc_yoffset += RADEON_PANINCREMENT; 3049 } 3050 while (x < rcp->rc_xoffset) { 3051 rcp->rc_xoffset -= RADEON_PANINCREMENT; 3052 } 3053 while (x >= (rcp->rc_xoffset + rcp->rc_videomode.hdisplay)) { 3054 rcp->rc_xoffset += RADEON_PANINCREMENT; 3055 } 3056 3057 /* adjust for the cursor's hotspot */ 3058 x -= dp->rd_cursor.rc_hot.x; 3059 y -= dp->rd_cursor.rc_hot.y; 3060 xoff = yoff = 0; 3061 3062 if (x >= dp->rd_virtx) 3063 x = dp->rd_virtx - 1; 3064 if (y >= dp->rd_virty) 3065 y = dp->rd_virty - 1; 3066 3067 /* now adjust cursor so it is relative to viewport */ 3068 x -= rcp->rc_xoffset; 3069 y -= rcp->rc_yoffset; 3070 3071 /* 3072 * no need to check for fall off, because we should 3073 * never move off the screen entirely! 3074 */ 3075 coff = 0; 3076 if (x < 0) { 3077 xoff = -x; 3078 x = 0; 3079 } 3080 if (y < 0) { 3081 yoff = -y; 3082 y = 0; 3083 coff = (yoff * 2) * 8; 3084 } 3085 3086 /* pan the display */ 3087 PUT32(sc, crtcoff, (rcp->rc_yoffset * dp->rd_stride) + 3088 rcp->rc_xoffset); 3089 3090 PUT32(sc, offset, (dp->rd_curoff + coff) | RADEON_CUR_LOCK); 3091 PUT32(sc, hvoff, (xoff << 16) | (yoff) | RADEON_CUR_LOCK); 3092 /* NB: this unlocks the cursor */ 3093 PUT32(sc, hvpos, (x << 16) | y); 3094 } 3095 } 3096 3097 static void 3098 radeonfb_cursor_visible(struct radeonfb_display *dp) 3099 { 3100 int i; 3101 uint32_t gencntl, bit; 3102 3103 for (i = 0; i < dp->rd_ncrtcs; i++) { 3104 if (dp->rd_crtcs[i].rc_number) { 3105 gencntl = RADEON_CRTC2_GEN_CNTL; 3106 bit = RADEON_CRTC2_CUR_EN; 3107 } else { 3108 gencntl = RADEON_CRTC_GEN_CNTL; 3109 bit = RADEON_CRTC_CUR_EN; 3110 } 3111 3112 if (dp->rd_cursor.rc_visible) 3113 SET32(dp->rd_softc, gencntl, bit); 3114 else 3115 CLR32(dp->rd_softc, gencntl, bit); 3116 } 3117 } 3118 3119 static void 3120 radeonfb_cursor_cmap(struct radeonfb_display *dp) 3121 { 3122 int i; 3123 uint32_t c0reg, c1reg; 3124 struct radeonfb_softc *sc = dp->rd_softc; 3125 3126 for (i = 0; i < dp->rd_ncrtcs; i++) { 3127 if (dp->rd_crtcs[i].rc_number) { 3128 c0reg = RADEON_CUR2_CLR0; 3129 c1reg = RADEON_CUR2_CLR1; 3130 } else { 3131 c0reg = RADEON_CUR_CLR0; 3132 c1reg = RADEON_CUR_CLR1; 3133 } 3134 3135 PUT32(sc, c0reg, dp->rd_cursor.rc_cmap[0]); 3136 PUT32(sc, c1reg, dp->rd_cursor.rc_cmap[1]); 3137 } 3138 } 3139 3140 static void 3141 radeonfb_cursor_update(struct radeonfb_display *dp, unsigned which) 3142 { 3143 struct radeonfb_softc *sc; 3144 int i; 3145 3146 sc = dp->rd_softc; 3147 for (i = 0; i < dp->rd_ncrtcs; i++) { 3148 if (dp->rd_crtcs[i].rc_number) { 3149 SET32(sc, RADEON_CUR2_OFFSET, RADEON_CUR_LOCK); 3150 } else { 3151 SET32(sc, RADEON_CUR_OFFSET,RADEON_CUR_LOCK); 3152 } 3153 } 3154 3155 if (which & WSDISPLAY_CURSOR_DOCMAP) 3156 radeonfb_cursor_cmap(dp); 3157 3158 if (which & WSDISPLAY_CURSOR_DOSHAPE) 3159 radeonfb_cursor_shape(dp); 3160 3161 if (which & WSDISPLAY_CURSOR_DOCUR) 3162 radeonfb_cursor_visible(dp); 3163 3164 /* this one is unconditional, because it updates other stuff */ 3165 radeonfb_cursor_position(dp); 3166 } 3167 3168 static struct videomode * 3169 radeonfb_best_refresh(struct videomode *m1, struct videomode *m2) 3170 { 3171 int r1, r2; 3172 3173 /* otherwise pick the higher refresh rate */ 3174 r1 = DIVIDE(DIVIDE(m1->dot_clock, m1->htotal), m1->vtotal); 3175 r2 = DIVIDE(DIVIDE(m2->dot_clock, m2->htotal), m2->vtotal); 3176 3177 return (r1 < r2 ? m2 : m1); 3178 } 3179 3180 static const struct videomode * 3181 radeonfb_port_mode(struct radeonfb_softc *sc, struct radeonfb_port *rp, 3182 int x, int y) 3183 { 3184 struct edid_info *ep = &rp->rp_edid; 3185 struct videomode *vmp = NULL; 3186 int i; 3187 3188 if (!rp->rp_edid_valid) { 3189 /* fallback to safe mode */ 3190 return radeonfb_modelookup(sc->sc_defaultmode); 3191 } 3192 3193 /* always choose the preferred mode first! */ 3194 if (ep->edid_preferred_mode) { 3195 3196 /* XXX: add auto-stretching support for native mode */ 3197 3198 /* this may want panning to occur, btw */ 3199 if ((ep->edid_preferred_mode->hdisplay <= x) && 3200 (ep->edid_preferred_mode->vdisplay <= y)) 3201 return ep->edid_preferred_mode; 3202 } 3203 3204 for (i = 0; i < ep->edid_nmodes; i++) { 3205 /* 3206 * We elect to pick a resolution that is too large for 3207 * the monitor than one that is too small. This means 3208 * that we will prefer to pan rather than to try to 3209 * center a smaller display on a larger screen. In 3210 * practice, this shouldn't matter because if a 3211 * monitor can support a larger resolution, it can 3212 * probably also support the smaller. A specific 3213 * exception is fixed format panels, but hopefully 3214 * they are properly dealt with by the "autostretch" 3215 * logic above. 3216 */ 3217 if ((ep->edid_modes[i].hdisplay > x) || 3218 (ep->edid_modes[i].vdisplay > y)) { 3219 continue; 3220 } 3221 3222 /* 3223 * at this point, the display mode is no larger than 3224 * what we've requested. 3225 */ 3226 if (vmp == NULL) 3227 vmp = &ep->edid_modes[i]; 3228 3229 /* eliminate smaller modes */ 3230 if ((vmp->hdisplay >= ep->edid_modes[i].hdisplay) || 3231 (vmp->vdisplay >= ep->edid_modes[i].vdisplay)) 3232 continue; 3233 3234 if ((vmp->hdisplay < ep->edid_modes[i].hdisplay) || 3235 (vmp->vdisplay < ep->edid_modes[i].vdisplay)) { 3236 vmp = &ep->edid_modes[i]; 3237 continue; 3238 } 3239 3240 KASSERT(vmp->hdisplay == ep->edid_modes[i].hdisplay); 3241 KASSERT(vmp->vdisplay == ep->edid_modes[i].vdisplay); 3242 3243 vmp = radeonfb_best_refresh(vmp, &ep->edid_modes[i]); 3244 } 3245 3246 return (vmp ? vmp : radeonfb_modelookup(sc->sc_defaultmode)); 3247 } 3248 3249 static int 3250 radeonfb_hasres(struct videomode *list, int nlist, int x, int y) 3251 { 3252 int i; 3253 3254 for (i = 0; i < nlist; i++) { 3255 if ((x == list[i].hdisplay) && 3256 (y == list[i].vdisplay)) { 3257 return 1; 3258 } 3259 } 3260 return 0; 3261 } 3262 3263 static void 3264 radeonfb_pickres(struct radeonfb_display *dp, uint16_t *x, uint16_t *y, 3265 int pan) 3266 { 3267 struct radeonfb_port *rp; 3268 struct edid_info *ep; 3269 int i, j; 3270 3271 *x = 0; 3272 *y = 0; 3273 3274 if (pan) { 3275 for (i = 0; i < dp->rd_ncrtcs; i++) { 3276 rp = dp->rd_crtcs[i].rc_port; 3277 ep = &rp->rp_edid; 3278 if (!rp->rp_edid_valid) { 3279 /* monitor not present */ 3280 continue; 3281 } 3282 3283 /* 3284 * For now we are ignoring "conflict" that 3285 * could occur when mixing some modes like 3286 * 1280x1024 and 1400x800. It isn't clear 3287 * which is better, so the first one wins. 3288 */ 3289 for (j = 0; j < ep->edid_nmodes; j++) { 3290 /* 3291 * ignore resolutions that are too big for 3292 * the radeon 3293 */ 3294 if (ep->edid_modes[j].hdisplay > 3295 dp->rd_softc->sc_maxx) 3296 continue; 3297 if (ep->edid_modes[j].vdisplay > 3298 dp->rd_softc->sc_maxy) 3299 continue; 3300 3301 /* 3302 * pick largest resolution, the 3303 * smaller monitor will pan 3304 */ 3305 if ((ep->edid_modes[j].hdisplay >= *x) && 3306 (ep->edid_modes[j].vdisplay >= *y)) { 3307 *x = ep->edid_modes[j].hdisplay; 3308 *y = ep->edid_modes[j].vdisplay; 3309 } 3310 } 3311 } 3312 3313 } else { 3314 struct videomode modes[64]; 3315 int nmodes = 0; 3316 int valid = 0; 3317 3318 for (i = 0; i < dp->rd_ncrtcs; i++) { 3319 /* 3320 * pick the largest resolution in common. 3321 */ 3322 rp = dp->rd_crtcs[i].rc_port; 3323 ep = &rp->rp_edid; 3324 3325 if (!rp->rp_edid_valid) 3326 continue; 3327 3328 if (!valid) { 3329 /* initialize starting list */ 3330 for (j = 0; j < ep->edid_nmodes; j++) { 3331 /* 3332 * ignore resolutions that are 3333 * too big for the radeon 3334 */ 3335 if (ep->edid_modes[j].hdisplay > 3336 dp->rd_softc->sc_maxx) 3337 continue; 3338 if (ep->edid_modes[j].vdisplay > 3339 dp->rd_softc->sc_maxy) 3340 continue; 3341 3342 modes[nmodes] = ep->edid_modes[j]; 3343 nmodes++; 3344 } 3345 valid = 1; 3346 } else { 3347 /* merge into preexisting list */ 3348 for (j = 0; j < nmodes; j++) { 3349 if (!radeonfb_hasres(ep->edid_modes, 3350 ep->edid_nmodes, 3351 modes[j].hdisplay, 3352 modes[j].vdisplay)) { 3353 modes[j] = modes[nmodes]; 3354 j--; 3355 nmodes--; 3356 } 3357 } 3358 } 3359 } 3360 3361 /* now we have to pick from the merged list */ 3362 for (i = 0; i < nmodes; i++) { 3363 if ((modes[i].hdisplay >= *x) && 3364 (modes[i].vdisplay >= *y)) { 3365 *x = modes[i].hdisplay; 3366 *y = modes[i].vdisplay; 3367 } 3368 } 3369 } 3370 3371 if ((*x == 0) || (*y == 0)) { 3372 /* fallback to safe mode */ 3373 *x = 640; 3374 *y = 480; 3375 } 3376 } 3377 3378 /* 3379 * backlight levels are linear on: 3380 * - RV200, RV250, RV280, RV350 3381 * - but NOT on PowerBook4,3 6,3 6,5 3382 * according to Linux' radeonfb 3383 */ 3384 3385 /* Get the current backlight level for the display. */ 3386 3387 static int 3388 radeonfb_get_backlight(struct radeonfb_display *dp) 3389 { 3390 int s; 3391 uint32_t level; 3392 3393 s = spltty(); 3394 3395 level = radeonfb_get32(dp->rd_softc, RADEON_LVDS_GEN_CNTL); 3396 level &= RADEON_LVDS_BL_MOD_LEV_MASK; 3397 level >>= RADEON_LVDS_BL_MOD_LEV_SHIFT; 3398 3399 /* 3400 * On some chips, we should negate the backlight level. 3401 * XXX Find out on which chips. 3402 */ 3403 if (dp->rd_softc->sc_flags & RFB_INV_BLIGHT) 3404 level = RADEONFB_BACKLIGHT_MAX - level; 3405 3406 splx(s); 3407 3408 return level; 3409 } 3410 3411 /* Set the backlight to the given level for the display. */ 3412 3413 static int 3414 radeonfb_set_backlight(struct radeonfb_display *dp, int level) 3415 { 3416 struct radeonfb_softc *sc; 3417 int rlevel, s; 3418 uint32_t lvds; 3419 3420 s = spltty(); 3421 3422 if (level < 0) 3423 level = 0; 3424 else if (level >= RADEONFB_BACKLIGHT_MAX) 3425 level = RADEONFB_BACKLIGHT_MAX; 3426 3427 sc = dp->rd_softc; 3428 3429 /* On some chips, we should negate the backlight level. */ 3430 if (dp->rd_softc->sc_flags & RFB_INV_BLIGHT) { 3431 rlevel = RADEONFB_BACKLIGHT_MAX - level; 3432 } else 3433 rlevel = level; 3434 3435 callout_stop(&dp->rd_bl_lvds_co); 3436 radeonfb_engine_idle(sc); 3437 3438 /* 3439 * Turn off the display if the backlight is set to 0, since the 3440 * display is useless without backlight anyway. 3441 */ 3442 if (level == 0) 3443 radeonfb_blank(dp, 1); 3444 else if (radeonfb_get_backlight(dp) == 0) 3445 radeonfb_blank(dp, 0); 3446 3447 lvds = radeonfb_get32(sc, RADEON_LVDS_GEN_CNTL); 3448 lvds &= ~RADEON_LVDS_DISPLAY_DIS; 3449 if (!(lvds & RADEON_LVDS_BLON) || !(lvds & RADEON_LVDS_ON)) { 3450 lvds |= dp->rd_bl_lvds_val & RADEON_LVDS_DIGON; 3451 lvds |= RADEON_LVDS_BLON | RADEON_LVDS_EN; 3452 radeonfb_put32(sc, RADEON_LVDS_GEN_CNTL, lvds); 3453 lvds &= ~RADEON_LVDS_BL_MOD_LEV_MASK; 3454 lvds |= rlevel << RADEON_LVDS_BL_MOD_LEV_SHIFT; 3455 lvds |= RADEON_LVDS_ON; 3456 lvds |= dp->rd_bl_lvds_val & RADEON_LVDS_BL_MOD_EN; 3457 } else { 3458 lvds &= ~RADEON_LVDS_BL_MOD_LEV_MASK; 3459 lvds |= rlevel << RADEON_LVDS_BL_MOD_LEV_SHIFT; 3460 radeonfb_put32(sc, RADEON_LVDS_GEN_CNTL, lvds); 3461 } 3462 3463 dp->rd_bl_lvds_val &= ~RADEON_LVDS_STATE_MASK; 3464 dp->rd_bl_lvds_val |= lvds & RADEON_LVDS_STATE_MASK; 3465 /* XXX What is the correct delay? */ 3466 callout_schedule(&dp->rd_bl_lvds_co, 200 * hz); 3467 3468 splx(s); 3469 3470 return 0; 3471 } 3472 3473 /* 3474 * Callout function for delayed operations on the LVDS_GEN_CNTL register. 3475 * Set the delayed bits in the register, and clear the stored delayed 3476 * value. 3477 */ 3478 3479 static void radeonfb_lvds_callout(void *arg) 3480 { 3481 struct radeonfb_display *dp = arg; 3482 int s; 3483 3484 s = splhigh(); 3485 3486 radeonfb_mask32(dp->rd_softc, RADEON_LVDS_GEN_CNTL, ~0, 3487 dp->rd_bl_lvds_val); 3488 dp->rd_bl_lvds_val = 0; 3489 3490 splx(s); 3491 } 3492