1 /* $NetBSD: radeonfb.c,v 1.99 2018/06/28 17:22:09 macallan 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.99 2018/06/28 17:22:09 macallan Exp $"); 74 75 #include <sys/param.h> 76 #include <sys/systm.h> 77 #include <sys/device.h> 78 #include <sys/malloc.h> 79 #include <sys/bus.h> 80 #include <sys/kernel.h> 81 #include <sys/lwp.h> 82 #include <sys/kauth.h> 83 84 #include <dev/wscons/wsdisplayvar.h> 85 #include <dev/wscons/wsconsio.h> 86 #include <dev/wsfont/wsfont.h> 87 #include <dev/rasops/rasops.h> 88 #include <dev/videomode/videomode.h> 89 #include <dev/videomode/edidvar.h> 90 #include <dev/wscons/wsdisplay_vconsvar.h> 91 #include <dev/pci/wsdisplay_pci.h> 92 #include <dev/wscons/wsdisplay_glyphcachevar.h> 93 94 #include <dev/pci/pcidevs.h> 95 #include <dev/pci/pcireg.h> 96 #include <dev/pci/pcivar.h> 97 #include <dev/pci/pciio.h> 98 #include <dev/pci/radeonfbreg.h> 99 #include <dev/pci/radeonfbvar.h> 100 #include "opt_radeonfb.h" 101 #include "opt_vcons.h" 102 103 #ifdef RADEONFB_DEPTH_32 104 #define RADEONFB_DEFAULT_DEPTH 32 105 #else 106 #define RADEONFB_DEFAULT_DEPTH 8 107 #endif 108 109 static int radeonfb_match(device_t, cfdata_t, void *); 110 static void radeonfb_attach(device_t, device_t, void *); 111 static int radeonfb_ioctl(void *, void *, unsigned long, void *, int, 112 struct lwp *); 113 static paddr_t radeonfb_mmap(void *, void *, off_t, int); 114 static int radeonfb_scratch_test(struct radeonfb_softc *, int, uint32_t); 115 static void radeonfb_loadbios(struct radeonfb_softc *, 116 const struct pci_attach_args *); 117 118 static uintmax_t radeonfb_getprop_num(struct radeonfb_softc *, const char *, 119 uintmax_t); 120 static int radeonfb_getclocks(struct radeonfb_softc *); 121 static int radeonfb_gettmds(struct radeonfb_softc *); 122 static int radeonfb_calc_dividers(struct radeonfb_softc *, uint32_t, 123 uint32_t *, uint32_t *, int); 124 /* flags for radeonfb_calc_dividers */ 125 #define NO_ODD_FBDIV 1 126 127 static int radeonfb_getconnectors(struct radeonfb_softc *); 128 static const struct videomode *radeonfb_modelookup(const char *); 129 static void radeonfb_init_screen(void *, struct vcons_screen *, int, long *); 130 static void radeonfb_pllwriteupdate(struct radeonfb_softc *, int); 131 static void radeonfb_pllwaitatomicread(struct radeonfb_softc *, int); 132 static void radeonfb_program_vclk(struct radeonfb_softc *, int, int, int); 133 static void radeonfb_modeswitch(struct radeonfb_display *); 134 static void radeonfb_setcrtc(struct radeonfb_display *, int); 135 static void radeonfb_init_misc(struct radeonfb_softc *); 136 static void radeonfb_set_fbloc(struct radeonfb_softc *); 137 static void radeonfb_init_palette(struct radeonfb_display *); 138 static void radeonfb_r300cg_workaround(struct radeonfb_softc *); 139 140 static int radeonfb_isblank(struct radeonfb_display *); 141 static void radeonfb_blank(struct radeonfb_display *, int); 142 static int radeonfb_set_cursor(struct radeonfb_display *, 143 struct wsdisplay_cursor *); 144 static int radeonfb_set_curpos(struct radeonfb_display *, 145 struct wsdisplay_curpos *); 146 static void radeonfb_putpal(struct radeonfb_display *, int, int, int, int); 147 static int radeonfb_putcmap(struct radeonfb_display *, struct wsdisplay_cmap *); 148 static int radeonfb_getcmap(struct radeonfb_display *, struct wsdisplay_cmap *); 149 150 /* acceleration support */ 151 static void radeonfb_rectfill(struct radeonfb_display *, int dstx, int dsty, 152 int width, int height, uint32_t color); 153 static void radeonfb_rectfill_a(void *, int, int, int, int, long); 154 static void radeonfb_bitblt(void *, int srcx, int srcy, 155 int dstx, int dsty, int width, int height, int rop); 156 157 /* hw cursor support */ 158 static void radeonfb_cursor_cmap(struct radeonfb_display *); 159 static void radeonfb_cursor_shape(struct radeonfb_display *); 160 static void radeonfb_cursor_position(struct radeonfb_display *); 161 static void radeonfb_cursor_visible(struct radeonfb_display *); 162 static void radeonfb_cursor_update(struct radeonfb_display *, unsigned); 163 164 static inline void radeonfb_wait_fifo(struct radeonfb_softc *, int); 165 static void radeonfb_engine_idle(struct radeonfb_softc *); 166 static void radeonfb_engine_flush(struct radeonfb_softc *); 167 static void radeonfb_engine_reset(struct radeonfb_softc *); 168 static void radeonfb_engine_init(struct radeonfb_display *); 169 static inline void radeonfb_unclip(struct radeonfb_softc *) __unused; 170 171 static void radeonfb_eraserows(void *, int, int, long); 172 static void radeonfb_erasecols(void *, int, int, int, long); 173 static void radeonfb_copyrows(void *, int, int, int); 174 static void radeonfb_copycols(void *, int, int, int, int); 175 static void radeonfb_cursor(void *, int, int, int); 176 static void radeonfb_putchar(void *, int, int, unsigned, long); 177 static void radeonfb_putchar_aa32(void *, int, int, unsigned, long); 178 static void radeonfb_putchar_aa8(void *, int, int, unsigned, long); 179 #ifndef RADEONFB_ALWAYS_ACCEL_PUTCHAR 180 static void radeonfb_putchar_wrapper(void *, int, int, unsigned, long); 181 #endif 182 183 static int radeonfb_set_backlight(struct radeonfb_display *, int); 184 static int radeonfb_get_backlight(struct radeonfb_display *); 185 static void radeonfb_switch_backlight(struct radeonfb_display *, int); 186 static void radeonfb_lvds_callout(void *); 187 188 static void radeonfb_brightness_up(device_t); 189 static void radeonfb_brightness_down(device_t); 190 191 static struct videomode *radeonfb_best_refresh(struct videomode *, 192 struct videomode *); 193 static void radeonfb_pickres(struct radeonfb_display *, uint16_t *, 194 uint16_t *, int); 195 static const struct videomode *radeonfb_port_mode(struct radeonfb_softc *, 196 struct radeonfb_port *, int, int); 197 198 static int radeonfb_drm_print(void *, const char *); 199 200 #ifdef RADEONFB_DEBUG 201 int radeon_debug = 1; 202 #define DPRINTF(x) \ 203 if (radeon_debug) printf x 204 #define PRINTREG(r) DPRINTF((#r " = %08x\n", GET32(sc, r))) 205 #define PRINTPLL(r) DPRINTF((#r " = %08x\n", GETPLL(sc, r))) 206 #else 207 #define DPRINTF(x) 208 #define PRINTREG(r) 209 #define PRINTPLL(r) 210 #endif 211 212 #define ROUNDUP(x,y) (((x) + ((y) - 1)) & ~((y) - 1)) 213 214 #ifndef RADEON_DEFAULT_MODE 215 /* any reasonably modern display should handle this */ 216 #define RADEON_DEFAULT_MODE "1024x768x60" 217 #endif 218 219 extern const u_char rasops_cmap[768]; 220 221 const char *radeonfb_default_mode = RADEON_DEFAULT_MODE; 222 223 static struct { 224 int size; /* minimum memory size (MB) */ 225 int maxx; /* maximum x dimension */ 226 int maxy; /* maximum y dimension */ 227 int maxbpp; /* maximum bpp */ 228 int maxdisp; /* maximum logical display count */ 229 } radeonfb_limits[] = { 230 { 32, 2048, 1536, 32, 2 }, 231 { 16, 1600, 1200, 32, 2 }, 232 { 8, 1600, 1200, 32, 1 }, 233 { 0, 0, 0, 0, 0 }, 234 }; 235 236 static struct wsscreen_descr radeonfb_stdscreen = { 237 "fb", /* name */ 238 0, 0, /* ncols, nrows */ 239 NULL, /* textops */ 240 8, 16, /* fontwidth, fontheight */ 241 WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE | WSSCREEN_RESIZE, /* capabilities */ 242 0, /* modecookie */ 243 }; 244 245 struct wsdisplay_accessops radeonfb_accessops = { 246 radeonfb_ioctl, 247 radeonfb_mmap, 248 NULL, /* vcons_alloc_screen */ 249 NULL, /* vcons_free_screen */ 250 NULL, /* vcons_show_screen */ 251 NULL, /* load_font */ 252 NULL, /* pollc */ 253 NULL, /* scroll */ 254 }; 255 256 static struct { 257 uint16_t devid; 258 uint16_t family; 259 uint16_t flags; 260 } radeonfb_devices[] = 261 { 262 /* R100 family */ 263 { PCI_PRODUCT_ATI_RADEON_R100_QD, RADEON_R100, 0 }, 264 { PCI_PRODUCT_ATI_RADEON_R100_QE, RADEON_R100, 0 }, 265 { PCI_PRODUCT_ATI_RADEON_R100_QF, RADEON_R100, 0 }, 266 { PCI_PRODUCT_ATI_RADEON_R100_QG, RADEON_R100, 0 }, 267 268 /* RV100 family */ 269 { PCI_PRODUCT_ATI_RADEON_RV100_LY, RADEON_RV100, RFB_MOB }, 270 { PCI_PRODUCT_ATI_RADEON_RV100_LZ, RADEON_RV100, RFB_MOB }, 271 { PCI_PRODUCT_ATI_RADEON_RV100_QY, RADEON_RV100, 0 }, 272 { PCI_PRODUCT_ATI_RADEON_RV100_QZ, RADEON_RV100, 0 }, 273 274 /* RS100 family */ 275 { PCI_PRODUCT_ATI_RADEON_RS100_4136, RADEON_RS100, 0 }, 276 { PCI_PRODUCT_ATI_RADEON_RS100_4336, RADEON_RS100, RFB_MOB }, 277 278 /* RS200/RS250 family */ 279 { PCI_PRODUCT_ATI_RADEON_RS200_4337, RADEON_RS200, RFB_MOB }, 280 { PCI_PRODUCT_ATI_RADEON_RS200_A7, RADEON_RS200, 0 }, 281 { PCI_PRODUCT_ATI_RADEON_RS250_B7, RADEON_RS200, RFB_MOB }, 282 { PCI_PRODUCT_ATI_RADEON_RS250_D7, RADEON_RS200, 0 }, 283 284 /* R200 family */ 285 /* add more R200 products? , 5148 */ 286 { PCI_PRODUCT_ATI_RADEON_R200_BB, RADEON_R200, 0 }, 287 { PCI_PRODUCT_ATI_RADEON_R200_BC, RADEON_R200, 0 }, 288 { PCI_PRODUCT_ATI_RADEON_R200_QH, RADEON_R200, 0 }, 289 { PCI_PRODUCT_ATI_RADEON_R200_QL, RADEON_R200, 0 }, 290 { PCI_PRODUCT_ATI_RADEON_R200_QM, RADEON_R200, 0 }, 291 292 /* RV200 family */ 293 { PCI_PRODUCT_ATI_RADEON_RV200_LW, RADEON_RV200, RFB_MOB }, 294 { PCI_PRODUCT_ATI_RADEON_RV200_LX, RADEON_RV200, RFB_MOB }, 295 { PCI_PRODUCT_ATI_RADEON_RV200_QW, RADEON_RV200, 0 }, 296 { PCI_PRODUCT_ATI_RADEON_RV200_QX, RADEON_RV200, 0 }, 297 298 /* RV250 family */ 299 { PCI_PRODUCT_ATI_RADEON_RV250_4966, RADEON_RV250, 0 }, 300 { PCI_PRODUCT_ATI_RADEON_RV250_4967, RADEON_RV250, 0 }, 301 { PCI_PRODUCT_ATI_RADEON_RV250_4C64, RADEON_RV250, RFB_MOB }, 302 { PCI_PRODUCT_ATI_RADEON_RV250_4C66, RADEON_RV250, RFB_MOB }, 303 { PCI_PRODUCT_ATI_RADEON_RV250_4C67, RADEON_RV250, RFB_MOB }, 304 305 /* RS300 family */ 306 { PCI_PRODUCT_ATI_RADEON_RS300_X5, RADEON_RS300, 0 }, 307 { PCI_PRODUCT_ATI_RADEON_RS300_X4, RADEON_RS300, 0 }, 308 { PCI_PRODUCT_ATI_RADEON_RS300_7834, RADEON_RS300, 0 }, 309 { PCI_PRODUCT_ATI_RADEON_RS300_7835, RADEON_RS300, RFB_MOB }, 310 311 /* RV280 family */ 312 { PCI_PRODUCT_ATI_RADEON_RV280_5960, RADEON_RV280, 0 }, 313 { PCI_PRODUCT_ATI_RADEON_RV280_5961, RADEON_RV280, 0 }, 314 { PCI_PRODUCT_ATI_RADEON_RV280_5962, RADEON_RV280, 0 }, 315 { PCI_PRODUCT_ATI_RADEON_RV280_5963, RADEON_RV280, 0 }, 316 { PCI_PRODUCT_ATI_RADEON_RV280_5964, RADEON_RV280, 0 }, 317 { PCI_PRODUCT_ATI_RADEON_RV280_5C61, RADEON_RV280, RFB_MOB }, 318 { PCI_PRODUCT_ATI_RADEON_RV280_5C63, RADEON_RV280, RFB_MOB }, 319 320 /* R300 family */ 321 { PCI_PRODUCT_ATI_RADEON_R300_AD, RADEON_R300, 0 }, 322 { PCI_PRODUCT_ATI_RADEON_R300_AE, RADEON_R300, 0 }, 323 { PCI_PRODUCT_ATI_RADEON_R300_AF, RADEON_R300, 0 }, 324 { PCI_PRODUCT_ATI_RADEON_R300_AG, RADEON_R300, 0 }, 325 { PCI_PRODUCT_ATI_RADEON_R300_ND, RADEON_R300, 0 }, 326 { PCI_PRODUCT_ATI_RADEON_R300_NE, RADEON_R300, 0 }, 327 { PCI_PRODUCT_ATI_RADEON_R300_NF, RADEON_R300, 0 }, 328 { PCI_PRODUCT_ATI_RADEON_R300_NG, RADEON_R300, 0 }, 329 330 /* RV350/RV360 family */ 331 { PCI_PRODUCT_ATI_RADEON_RV350_AP, RADEON_RV350, 0 }, 332 { PCI_PRODUCT_ATI_RADEON_RV350_AQ, RADEON_RV350, 0 }, 333 { PCI_PRODUCT_ATI_RADEON_RV360_AR, RADEON_RV350, 0 }, 334 { PCI_PRODUCT_ATI_RADEON_RV350_AS, RADEON_RV350, 0 }, 335 { PCI_PRODUCT_ATI_RADEON_RV350_AT, RADEON_RV350, 0 }, 336 { PCI_PRODUCT_ATI_RADEON_RV350_AV, RADEON_RV350, 0 }, 337 { PCI_PRODUCT_ATI_RADEON_RV350_NP, RADEON_RV350, RFB_MOB }, 338 { PCI_PRODUCT_ATI_RADEON_RV350_NQ, RADEON_RV350, RFB_MOB }, 339 { PCI_PRODUCT_ATI_RADEON_RV350_NR, RADEON_RV350, RFB_MOB }, 340 { PCI_PRODUCT_ATI_RADEON_RV350_NS, RADEON_RV350, RFB_MOB }, 341 { PCI_PRODUCT_ATI_RADEON_RV350_NT, RADEON_RV350, RFB_MOB }, 342 { PCI_PRODUCT_ATI_RADEON_RV350_NV, RADEON_RV350, RFB_MOB }, 343 344 /* R350/R360 family */ 345 { PCI_PRODUCT_ATI_RADEON_R350_AH, RADEON_R350, 0 }, 346 { PCI_PRODUCT_ATI_RADEON_R350_AI, RADEON_R350, 0 }, 347 { PCI_PRODUCT_ATI_RADEON_R350_AJ, RADEON_R350, 0 }, 348 { PCI_PRODUCT_ATI_RADEON_R350_AK, RADEON_R350, 0 }, 349 { PCI_PRODUCT_ATI_RADEON_R350_NH, RADEON_R350, 0 }, 350 { PCI_PRODUCT_ATI_RADEON_R350_NI, RADEON_R350, 0 }, 351 { PCI_PRODUCT_ATI_RADEON_R350_NK, RADEON_R350, 0 }, 352 { PCI_PRODUCT_ATI_RADEON_R360_NJ, RADEON_R350, 0 }, 353 354 /* RV380/RV370 family */ 355 { PCI_PRODUCT_ATI_RADEON_RV380_3150, RADEON_RV380, RFB_MOB }, 356 { PCI_PRODUCT_ATI_RADEON_RV380_3154, RADEON_RV380, RFB_MOB }, 357 { PCI_PRODUCT_ATI_RADEON_RV380_3E50, RADEON_RV380, 0 }, 358 { PCI_PRODUCT_ATI_RADEON_RV380_3E54, RADEON_RV380, 0 }, 359 { PCI_PRODUCT_ATI_RADEON_RV370_5460, RADEON_RV380, RFB_MOB }, 360 { PCI_PRODUCT_ATI_RADEON_RV370_5464, RADEON_RV380, RFB_MOB }, 361 { PCI_PRODUCT_ATI_RADEON_RV370_5B60, RADEON_RV380, 0 }, 362 { PCI_PRODUCT_ATI_RADEON_RV370_5B63, RADEON_RV380, 0 }, 363 { PCI_PRODUCT_ATI_RADEON_RV370_5B64, RADEON_RV380, 0 }, 364 { PCI_PRODUCT_ATI_RADEON_RV370_5B65, RADEON_RV380, 0 }, 365 366 #if notyet 367 /* R420/R423 family */ 368 { PCI_PRODUCT_ATI_RADEON_R420_JH, RADEON_R420, 0 }, 369 { PCI_PRODUCT_ATI_RADEON_R420_JI, RADEON_R420, 0 }, 370 { PCI_PRODUCT_ATI_RADEON_R420_JJ, RADEON_R420, 0 }, 371 { PCI_PRODUCT_ATI_RADEON_R420_JK, RADEON_R420, 0 }, 372 { PCI_PRODUCT_ATI_RADEON_R420_JL, RADEON_R420, 0 }, 373 { PCI_PRODUCT_ATI_RADEON_R420_JM, RADEON_R420, 0 }, 374 { PCI_PRODUCT_ATI_RADEON_R420_JN, RADEON_R420, RFB_MOB }, 375 { PCI_PRODUCT_ATI_RADEON_R420_JP, RADEON_R420, 0 }, 376 { PCI_PRODUCT_ATI_RADEON_R423_UH, RADEON_R420, 0 }, 377 { PCI_PRODUCT_ATI_RADEON_R423_UI, RADEON_R420, 0 }, 378 { PCI_PRODUCT_ATI_RADEON_R423_UJ, RADEON_R420, 0 }, 379 { PCI_PRODUCT_ATI_RADEON_R423_UK, RADEON_R420, 0 }, 380 { PCI_PRODUCT_ATI_RADEON_R423_UQ, RADEON_R420, 0 }, 381 { PCI_PRODUCT_ATI_RADEON_R423_UR, RADEON_R420, 0 }, 382 { PCI_PRODUCT_ATI_RADEON_R423_UT, RADEON_R420, 0 }, 383 { PCI_PRODUCT_ATI_RADEON_R423_5D57, RADEON_R420, 0 }, 384 { PCI_PRODUCT_ATI_RADEON_R430_554F, RADEON_R420, 0 }, 385 386 /* R5xx family */ 387 { 0x7240, RADEON_R420, 0 }, 388 #endif 389 { 0, 0, 0 } 390 }; 391 392 static struct { 393 int divider; 394 int mask; 395 } radeonfb_dividers[] = { 396 { 16, 5 }, 397 { 12, 7 }, 398 { 8, 3 }, 399 { 6, 6 }, 400 { 4, 2 }, 401 { 3, 4 }, 402 { 2, 1 }, 403 { 1, 0 }, 404 { 0, 0 } 405 }; 406 407 /* 408 * This table taken from X11. 409 */ 410 static const struct { 411 int family; 412 struct radeon_tmds_pll plls[4]; 413 } radeonfb_tmds_pll[] = { 414 { RADEON_R100, {{12000, 0xa1b}, {-1, 0xa3f}}}, 415 { RADEON_RV100, {{12000, 0xa1b}, {-1, 0xa3f}}}, 416 { RADEON_RS100, {{0, 0}}}, 417 { RADEON_RV200, {{15000, 0xa1b}, {-1, 0xa3f}}}, 418 { RADEON_RS200, {{15000, 0xa1b}, {-1, 0xa3f}}}, 419 { RADEON_R200, {{15000, 0xa1b}, {-1, 0xa3f}}}, 420 { RADEON_RV250, {{15500, 0x81b}, {-1, 0x83f}}}, 421 { RADEON_RS300, {{0, 0}}}, 422 { RADEON_RV280, {{13000, 0x400f4}, {15000, 0x400f7}, {-1, 0x40111}}}, 423 { RADEON_R300, {{-1, 0xb01cb}}}, 424 { RADEON_R350, {{-1, 0xb01cb}}}, 425 { RADEON_RV350, {{15000, 0xb0155}, {-1, 0xb01cb}}}, 426 { RADEON_RV380, {{15000, 0xb0155}, {-1, 0xb01cb}}}, 427 { RADEON_R420, {{-1, 0xb01cb}}}, 428 }; 429 430 #define RADEONFB_BACKLIGHT_MAX 255 /* Maximum backlight level. */ 431 432 433 CFATTACH_DECL_NEW(radeonfb, sizeof (struct radeonfb_softc), 434 radeonfb_match, radeonfb_attach, NULL, NULL); 435 436 static int 437 radeonfb_match(device_t parent, cfdata_t match, void *aux) 438 { 439 const struct pci_attach_args *pa = aux; 440 int i; 441 442 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_ATI) 443 return 0; 444 445 for (i = 0; radeonfb_devices[i].devid; i++) { 446 if (PCI_PRODUCT(pa->pa_id) == radeonfb_devices[i].devid) 447 return 100; /* high to defeat VGA/VESA */ 448 } 449 450 return 0; 451 } 452 453 static void 454 radeonfb_attach(device_t parent, device_t dev, void *aux) 455 { 456 struct radeonfb_softc *sc = device_private(dev); 457 const struct pci_attach_args *pa = aux; 458 const char *mptr; 459 bus_size_t bsz; 460 pcireg_t screg; 461 int i, j, fg, bg, ul, flags; 462 uint32_t v; 463 464 sc->sc_dev = dev; 465 sc->sc_id = pa->pa_id; 466 for (i = 0; radeonfb_devices[i].devid; i++) { 467 if (PCI_PRODUCT(sc->sc_id) == radeonfb_devices[i].devid) 468 break; 469 } 470 471 pci_aprint_devinfo(pa, NULL); 472 473 DPRINTF(("%s", prop_dictionary_externalize(device_properties(dev)))); 474 475 KASSERT(radeonfb_devices[i].devid != 0); 476 sc->sc_pt = pa->pa_tag; 477 sc->sc_iot = pa->pa_iot; 478 sc->sc_pc = pa->pa_pc; 479 sc->sc_family = radeonfb_devices[i].family; 480 sc->sc_flags = radeonfb_devices[i].flags; 481 482 /* enable memory and IO access */ 483 screg = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 484 screg |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE; 485 pci_conf_write(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG, screg); 486 487 /* 488 * Some flags are general to entire chip families, and rather 489 * than clutter up the table with them, we go ahead and set 490 * them here. 491 */ 492 switch (sc->sc_family) { 493 case RADEON_RS100: 494 case RADEON_RS200: 495 sc->sc_flags |= RFB_IGP | RFB_RV100; 496 break; 497 498 case RADEON_RV100: 499 case RADEON_RV200: 500 case RADEON_RV250: 501 case RADEON_RV280: 502 sc->sc_flags |= RFB_RV100; 503 break; 504 505 case RADEON_RS300: 506 sc->sc_flags |= RFB_SDAC | RFB_IGP | RFB_RV100; 507 break; 508 509 case RADEON_R300: 510 case RADEON_RV350: 511 case RADEON_R350: 512 case RADEON_RV380: 513 case RADEON_R420: 514 /* newer chips */ 515 sc->sc_flags |= RFB_R300; 516 break; 517 518 case RADEON_R100: 519 sc->sc_flags |= RFB_NCRTC2; 520 break; 521 } 522 523 if ((sc->sc_family == RADEON_RV200) || 524 (sc->sc_family == RADEON_RV250) || 525 (sc->sc_family == RADEON_RV280) || 526 (sc->sc_family == RADEON_RV350)) { 527 bool inverted = 0; 528 /* backlight level is linear */ 529 DPRINTF(("found RV* chip, backlight is supposedly linear\n")); 530 prop_dictionary_get_bool(device_properties(sc->sc_dev), 531 "backlight_level_reverted", &inverted); 532 if (inverted) { 533 DPRINTF(("nope, it's inverted\n")); 534 sc->sc_flags |= RFB_INV_BLIGHT; 535 } 536 } else 537 sc->sc_flags |= RFB_INV_BLIGHT; 538 539 /* 540 * XXX: to support true multihead, this must change. 541 */ 542 sc->sc_ndisplays = 1; 543 544 /* XXX: */ 545 if (!HAS_CRTC2(sc)) { 546 sc->sc_ndisplays = 1; 547 } 548 549 if (pci_mapreg_map(pa, RADEON_MAPREG_MMIO, PCI_MAPREG_TYPE_MEM, 0, 550 &sc->sc_regt, &sc->sc_regh, &sc->sc_regaddr, 551 &sc->sc_regsz) != 0) { 552 aprint_error("%s: unable to map registers!\n", XNAME(sc)); 553 goto error; 554 } 555 556 if (pci_mapreg_info(sc->sc_pc, sc->sc_pt, PCI_MAPREG_ROM, 557 PCI_MAPREG_TYPE_ROM, &sc->sc_romaddr, &sc->sc_romsz, &flags) != 0) 558 { 559 aprint_error("%s: unable to find ROM!\n", XNAME(sc)); 560 goto error; 561 } 562 sc->sc_romt = sc->sc_memt; 563 564 sc->sc_mapped = TRUE; 565 566 /* scratch register test... */ 567 if (radeonfb_scratch_test(sc, RADEON_BIOS_0_SCRATCH, 0x55555555) || 568 radeonfb_scratch_test(sc, RADEON_BIOS_0_SCRATCH, 0xaaaaaaaa)) { 569 aprint_error("%s: scratch register test failed!\n", XNAME(sc)); 570 goto error; 571 } 572 573 PRINTREG(RADEON_CRTC_EXT_CNTL); 574 PRINTREG(RADEON_CRTC_GEN_CNTL); 575 PRINTREG(RADEON_CRTC2_GEN_CNTL); 576 PRINTREG(RADEON_DISP_OUTPUT_CNTL); 577 PRINTREG(RADEON_DAC_CNTL2); 578 PRINTREG(RADEON_BIOS_4_SCRATCH); 579 PRINTREG(RADEON_FP_GEN_CNTL); 580 sc->sc_fp_gen_cntl = GET32(sc, RADEON_FP_GEN_CNTL); 581 PRINTREG(RADEON_FP2_GEN_CNTL); 582 PRINTREG(RADEON_TMDS_CNTL); 583 PRINTREG(RADEON_TMDS_TRANSMITTER_CNTL); 584 PRINTREG(RADEON_TMDS_PLL_CNTL); 585 PRINTREG(RADEON_LVDS_GEN_CNTL); 586 PRINTREG(RADEON_DISP_HW_DEBUG); 587 PRINTREG(RADEON_PIXCLKS_CNTL); 588 PRINTREG(RADEON_CRTC_H_SYNC_STRT_WID); 589 PRINTREG(RADEON_FP_H_SYNC_STRT_WID); 590 PRINTREG(RADEON_CRTC2_H_SYNC_STRT_WID); 591 PRINTREG(RADEON_FP_H2_SYNC_STRT_WID); 592 593 /* 594 * XXX 595 * This was if (IS_RV100()), which is set for all pre-R3xx chips. 596 * I suspect this only makes sense on Sun XVR-100 with firmware that doesn't 597 * support DVI, so for now let's restrict it to only actual RV100 598 */ 599 if (sc->sc_family == RADEON_RV100) 600 PUT32(sc, RADEON_TMDS_PLL_CNTL, 0xa27); 601 602 /* XXX 603 * according to xf86-video-radeon R3xx has this bit backwards 604 */ 605 if (IS_R300(sc)) { 606 PATCH32(sc, RADEON_TMDS_TRANSMITTER_CNTL, 607 0, 608 ~(RADEON_TMDS_TRANSMITTER_PLLEN | RADEON_TMDS_TRANSMITTER_PLLRST)); 609 } else { 610 PATCH32(sc, RADEON_TMDS_TRANSMITTER_CNTL, 611 RADEON_TMDS_TRANSMITTER_PLLEN, 612 ~(RADEON_TMDS_TRANSMITTER_PLLEN | RADEON_TMDS_TRANSMITTER_PLLRST)); 613 } 614 615 radeonfb_i2c_init(sc); 616 617 radeonfb_loadbios(sc, pa); 618 619 #ifdef RADEONFB_BIOS_INIT 620 if (radeonfb_bios_init(sc)) { 621 aprint_error("%s: BIOS inititialization failed\n", XNAME(sc)); 622 } 623 #endif 624 625 if (radeonfb_getclocks(sc)) { 626 aprint_error("%s: Unable to get reference clocks from BIOS\n", 627 XNAME(sc)); 628 goto error; 629 } 630 631 if (radeonfb_gettmds(sc)) { 632 aprint_error("%s: Unable to identify TMDS PLL settings\n", 633 XNAME(sc)); 634 goto error; 635 } 636 637 aprint_verbose("%s: refclk = %d.%03d MHz, refdiv = %d " 638 "minpll = %d, maxpll = %d\n", XNAME(sc), 639 (int)sc->sc_refclk / 1000, (int)sc->sc_refclk % 1000, 640 (int)sc->sc_refdiv, (int)sc->sc_minpll, (int)sc->sc_maxpll); 641 642 radeonfb_getconnectors(sc); 643 644 radeonfb_set_fbloc(sc); 645 646 /* 64 MB should be enough -- more just wastes map entries */ 647 if (sc->sc_memsz > (64 << 20)) 648 sc->sc_memsz = (64 << 20); 649 650 for (i = 0; radeonfb_limits[i].size; i++) { 651 if (sc->sc_memsz >= radeonfb_limits[i].size) { 652 sc->sc_maxx = radeonfb_limits[i].maxx; 653 sc->sc_maxy = radeonfb_limits[i].maxy; 654 sc->sc_maxbpp = radeonfb_limits[i].maxbpp; 655 /* framebuffer offset, start at a 4K page */ 656 sc->sc_fboffset = sc->sc_memsz / 657 radeonfb_limits[i].maxdisp; 658 /* 659 * we use the fbsize to figure out where we can store 660 * things like cursor data. 661 */ 662 sc->sc_fbsize = 663 ROUNDUP(ROUNDUP(sc->sc_maxx * sc->sc_maxbpp / 8 , 664 RADEON_STRIDEALIGN) * sc->sc_maxy, 665 4096); 666 break; 667 } 668 } 669 670 671 radeonfb_init_misc(sc); 672 673 /* program the DAC wirings */ 674 for (i = 0; i < (HAS_CRTC2(sc) ? 2 : 1); i++) { 675 switch (sc->sc_ports[i].rp_dac_type) { 676 case RADEON_DAC_PRIMARY: 677 PATCH32(sc, RADEON_DAC_CNTL2, 678 i ? RADEON_DAC2_DAC_CLK_SEL : 0, 679 ~RADEON_DAC2_DAC_CLK_SEL); 680 break; 681 case RADEON_DAC_TVDAC: 682 /* we always use the TVDAC to drive a secondary analog 683 * CRT for now. if we ever support TV-out this will 684 * have to change. 685 */ 686 SET32(sc, RADEON_DAC_CNTL2, 687 RADEON_DAC2_DAC2_CLK_SEL); 688 PATCH32(sc, RADEON_DISP_HW_DEBUG, 689 i ? 0 : RADEON_CRT2_DISP1_SEL, 690 ~RADEON_CRT2_DISP1_SEL); 691 /* we're using CRTC2 for the 2nd port */ 692 if (sc->sc_ports[i].rp_number == 1) { 693 PATCH32(sc, RADEON_DISP_OUTPUT_CNTL, 694 RADEON_DISP_DAC2_SOURCE_CRTC2, 695 ~RADEON_DISP_DAC2_SOURCE_MASK); 696 } 697 698 break; 699 } 700 DPRINTF(("%s: port %d tmds type %d\n", __func__, i, 701 sc->sc_ports[i].rp_tmds_type)); 702 switch (sc->sc_ports[i].rp_tmds_type) { 703 case RADEON_TMDS_INT: 704 /* point FP0 at the CRTC this port uses */ 705 DPRINTF(("%s: plugging internal TMDS into CRTC %d\n", 706 __func__, sc->sc_ports[i].rp_number)); 707 if (IS_R300(sc)) { 708 PATCH32(sc, RADEON_FP_GEN_CNTL, 709 sc->sc_ports[i].rp_number ? 710 R200_FP_SOURCE_SEL_CRTC2 : 711 R200_FP_SOURCE_SEL_CRTC1, 712 ~R200_FP_SOURCE_SEL_MASK); 713 } else { 714 PATCH32(sc, RADEON_FP_GEN_CNTL, 715 sc->sc_ports[i].rp_number ? 716 RADEON_FP_SEL_CRTC2 : 717 RADEON_FP_SEL_CRTC1, 718 ~RADEON_FP_SEL_MASK); 719 } 720 break; 721 case RADEON_TMDS_EXT: 722 /* point FP2 at the CRTC this port uses */ 723 DPRINTF(("%s: plugging external TMDS into CRTC %d\n", 724 __func__, sc->sc_ports[i].rp_number)); 725 if (IS_R300(sc)) { 726 PATCH32(sc, RADEON_FP2_GEN_CNTL, 727 sc->sc_ports[i].rp_number ? 728 R200_FP2_SOURCE_SEL_CRTC2 : 729 R200_FP2_SOURCE_SEL_CRTC1, 730 ~R200_FP2_SOURCE_SEL_CRTC2); 731 } else { 732 PATCH32(sc, RADEON_FP2_GEN_CNTL, 733 sc->sc_ports[i].rp_number ? 734 RADEON_FP2_SRC_SEL_CRTC2 : 735 RADEON_FP2_SRC_SEL_CRTC1, 736 ~RADEON_FP2_SRC_SEL_CRTC2); 737 } 738 break; 739 } 740 } 741 PRINTREG(RADEON_DAC_CNTL2); 742 PRINTREG(RADEON_DISP_HW_DEBUG); 743 744 PRINTREG(RADEON_DAC_CNTL); 745 /* other DAC programming */ 746 v = GET32(sc, RADEON_DAC_CNTL); 747 v &= (RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_BLANKING); 748 v |= RADEON_DAC_MASK_ALL | RADEON_DAC_8BIT_EN; 749 PUT32(sc, RADEON_DAC_CNTL, v); 750 PRINTREG(RADEON_DAC_CNTL); 751 752 /* XXX: this may need more investigation */ 753 PUT32(sc, RADEON_TV_DAC_CNTL, 0x00280203); 754 PRINTREG(RADEON_TV_DAC_CNTL); 755 756 /* enable TMDS */ 757 SET32(sc, RADEON_FP_GEN_CNTL, 758 RADEON_FP_TMDS_EN | 759 RADEON_FP_CRTC_DONT_SHADOW_VPAR | 760 RADEON_FP_CRTC_DONT_SHADOW_HEND); 761 /* 762 * XXX 763 * no idea why this is necessary - if I do not clear this bit on my 764 * iBook G4 the screen remains black, even though it's already clear. 765 * It needs to be set on my Sun XVR-100 for the DVI port to work 766 * TODO: 767 * see if this is still necessary now that CRTCs, DACs and outputs are 768 * getting wired up in a halfway sane way 769 */ 770 if (sc->sc_fp_gen_cntl & RADEON_FP_SEL_CRTC2) { 771 SET32(sc, RADEON_FP_GEN_CNTL, RADEON_FP_SEL_CRTC2); 772 } else { 773 CLR32(sc, RADEON_FP_GEN_CNTL, RADEON_FP_SEL_CRTC2); 774 } 775 776 /* 777 * we use bus_space_map instead of pci_mapreg, because we don't 778 * need the full aperature space. no point in wasting virtual 779 * address space we don't intend to use, right? 780 */ 781 if ((sc->sc_memsz < (4096 * 1024)) || 782 (pci_mapreg_info(sc->sc_pc, sc->sc_pt, RADEON_MAPREG_VRAM, 783 PCI_MAPREG_TYPE_MEM, &sc->sc_memaddr, &bsz, NULL) != 0) || 784 (bsz < sc->sc_memsz)) { 785 sc->sc_memsz = 0; 786 aprint_error("%s: Bad frame buffer configuration\n", 787 XNAME(sc)); 788 goto error; 789 } 790 791 sc->sc_memt = pa->pa_memt; 792 if (bus_space_map(sc->sc_memt, sc->sc_memaddr, sc->sc_memsz, 793 BUS_SPACE_MAP_LINEAR, &sc->sc_memh) != 0) { 794 sc->sc_memsz = 0; 795 aprint_error("%s: Unable to map frame buffer\n", XNAME(sc)); 796 goto error; 797 } 798 799 aprint_normal("%s: %d MB aperture at 0x%08x, " 800 "%d KB registers at 0x%08x\n", XNAME(sc), 801 (int)sc->sc_memsz >> 20, (unsigned)sc->sc_memaddr, 802 (int)sc->sc_regsz >> 10, (unsigned)sc->sc_regaddr); 803 804 /* setup default video mode from devprop (allows PROM override) */ 805 sc->sc_defaultmode = radeonfb_default_mode; 806 if (prop_dictionary_get_cstring_nocopy(device_properties(sc->sc_dev), 807 "videomode", &mptr)) { 808 809 strncpy(sc->sc_modebuf, mptr, sizeof(sc->sc_modebuf)); 810 sc->sc_defaultmode = sc->sc_modebuf; 811 } 812 813 /* initialize some basic display parameters */ 814 for (i = 0; i < sc->sc_ndisplays; i++) { 815 struct radeonfb_display *dp = &sc->sc_displays[i]; 816 struct rasops_info *ri; 817 long defattr; 818 struct wsemuldisplaydev_attach_args aa; 819 820 /* 821 * Figure out how many "displays" (desktops) we are going to 822 * support. If more than one, then each CRTC gets its own 823 * programming. 824 * 825 * XXX: this code needs to change to support mergedfb. 826 * XXX: would be nice to allow this to be overridden 827 */ 828 if (HAS_CRTC2(sc) && (sc->sc_ndisplays == 1)) { 829 DPRINTF(("dual crtcs!\n")); 830 dp->rd_ncrtcs = 2; 831 dp->rd_crtcs[0].rc_port = 832 &sc->sc_ports[0]; 833 dp->rd_crtcs[0].rc_number = sc->sc_ports[0].rp_number; 834 dp->rd_crtcs[1].rc_port = 835 &sc->sc_ports[1]; 836 dp->rd_crtcs[1].rc_number = sc->sc_ports[1].rp_number; 837 } else { 838 dp->rd_ncrtcs = 1; 839 dp->rd_crtcs[0].rc_port = 840 &sc->sc_ports[i]; 841 dp->rd_crtcs[0].rc_number = sc->sc_ports[i].rp_number; 842 } 843 844 dp->rd_softc = sc; 845 dp->rd_wsmode = WSDISPLAYIO_MODE_EMUL; 846 dp->rd_bpp = RADEONFB_DEFAULT_DEPTH; /* XXX */ 847 848 /* for text mode, we pick a resolution that won't 849 * require panning */ 850 radeonfb_pickres(dp, &dp->rd_virtx, &dp->rd_virty, 0); 851 852 aprint_normal("%s: display %d: " 853 "initial virtual resolution %dx%d at %d bpp\n", 854 XNAME(sc), i, dp->rd_virtx, dp->rd_virty, dp->rd_bpp); 855 aprint_normal_dev(sc->sc_dev, "using %d MB per display\n", 856 sc->sc_fboffset >> 20); 857 /* now select the *video mode* that we will use */ 858 for (j = 0; j < dp->rd_ncrtcs; j++) { 859 const struct videomode *vmp; 860 vmp = radeonfb_port_mode(sc, dp->rd_crtcs[j].rc_port, 861 dp->rd_virtx, dp->rd_virty); 862 863 /* 864 * virtual resolution should be at least as high as 865 * physical 866 */ 867 if (dp->rd_virtx < vmp->hdisplay || 868 dp->rd_virty < vmp->vdisplay) { 869 dp->rd_virtx = vmp->hdisplay; 870 dp->rd_virty = vmp->vdisplay; 871 } 872 873 dp->rd_crtcs[j].rc_videomode = *vmp; 874 printf("%s: port %d: physical %dx%d %dHz\n", 875 XNAME(sc), j, vmp->hdisplay, vmp->vdisplay, 876 DIVIDE(DIVIDE(vmp->dot_clock * 1000, 877 vmp->htotal), vmp->vtotal)); 878 } 879 880 /* N.B.: radeon wants 64-byte aligned stride */ 881 dp->rd_stride = dp->rd_virtx * dp->rd_bpp / 8; 882 dp->rd_stride = ROUNDUP(dp->rd_stride, RADEON_STRIDEALIGN); 883 DPRINTF(("stride: %d %d\n", dp->rd_stride, dp->rd_virtx)); 884 885 dp->rd_offset = sc->sc_fboffset * i; 886 dp->rd_fbptr = (vaddr_t)bus_space_vaddr(sc->sc_memt, 887 sc->sc_memh) + dp->rd_offset; 888 dp->rd_curoff = sc->sc_fboffset - 4096; /* 4KB cursor space */ 889 dp->rd_curptr = dp->rd_fbptr + dp->rd_curoff; 890 891 DPRINTF(("fpbtr = %p\n", (void *)dp->rd_fbptr)); 892 893 switch (dp->rd_bpp) { 894 case 8: 895 dp->rd_format = 2; 896 break; 897 case 32: 898 dp->rd_format = 6; 899 break; 900 default: 901 aprint_error("%s: bad depth %d\n", XNAME(sc), 902 dp->rd_bpp); 903 goto error; 904 } 905 906 DPRINTF(("init engine\n")); 907 /* XXX: this seems suspicious - per display engine 908 initialization? */ 909 radeonfb_engine_init(dp); 910 911 /* copy the template into place */ 912 dp->rd_wsscreens_storage[0] = radeonfb_stdscreen; 913 dp->rd_wsscreens = dp->rd_wsscreens_storage; 914 915 /* and make up the list */ 916 dp->rd_wsscreenlist.nscreens = 1; 917 dp->rd_wsscreenlist.screens = (void *)&dp->rd_wsscreens; 918 919 vcons_init(&dp->rd_vd, dp, dp->rd_wsscreens, 920 &radeonfb_accessops); 921 922 dp->rd_vd.init_screen = radeonfb_init_screen; 923 924 #ifdef RADEONFB_DEBUG 925 dp->rd_virty -= 200; 926 #endif 927 928 dp->rd_console = 0; 929 prop_dictionary_get_bool(device_properties(sc->sc_dev), 930 "is_console", &dp->rd_console); 931 932 dp->rd_vscreen.scr_flags |= VCONS_SCREEN_IS_STATIC; 933 934 935 vcons_init_screen(&dp->rd_vd, &dp->rd_vscreen, 936 dp->rd_console, &defattr); 937 938 ri = &dp->rd_vscreen.scr_ri; 939 940 /* clear the screen */ 941 rasops_unpack_attr(defattr, &fg, &bg, &ul); 942 dp->rd_bg = ri->ri_devcmap[bg & 0xf]; 943 radeonfb_rectfill(dp, 0, 0, ri->ri_width, ri->ri_height, 944 dp->rd_bg); 945 946 dp->rd_wsscreens->textops = &ri->ri_ops; 947 dp->rd_wsscreens->capabilities = ri->ri_caps; 948 dp->rd_wsscreens->nrows = ri->ri_rows; 949 dp->rd_wsscreens->ncols = ri->ri_cols; 950 951 #ifdef SPLASHSCREEN 952 dp->rd_splash.si_depth = ri->ri_depth; 953 dp->rd_splash.si_bits = ri->ri_bits; 954 dp->rd_splash.si_hwbits = ri->ri_hwbits; 955 dp->rd_splash.si_width = ri->ri_width; 956 dp->rd_splash.si_height = ri->ri_height; 957 dp->rd_splash.si_stride = ri->ri_stride; 958 dp->rd_splash.si_fillrect = NULL; 959 #endif 960 dp->rd_gc.gc_bitblt = radeonfb_bitblt; 961 dp->rd_gc.gc_rectfill = radeonfb_rectfill_a; 962 dp->rd_gc.gc_rop = RADEON_ROP3_S; 963 dp->rd_gc.gc_blitcookie = dp; 964 /* 965 * use memory between framebuffer and cursor area as glyph 966 * cache, cap at 4096 lines 967 */ 968 glyphcache_init(&dp->rd_gc, dp->rd_virty + 4, 969 min(4096, 970 (dp->rd_curoff / dp->rd_stride) - (dp->rd_virty + 4)), 971 dp->rd_virtx, 972 ri->ri_font->fontwidth, 973 ri->ri_font->fontheight, 974 defattr); 975 dp->rd_vd.show_screen_cookie = &dp->rd_gc; 976 dp->rd_vd.show_screen_cb = glyphcache_adapt; 977 978 if (dp->rd_console) { 979 980 radeonfb_modeswitch(dp); 981 wsdisplay_cnattach(dp->rd_wsscreens, ri, 0, 0, 982 defattr); 983 #ifdef SPLASHSCREEN 984 if (splash_render(&dp->rd_splash, 985 SPLASH_F_CENTER|SPLASH_F_FILL) == 0) 986 SCREEN_DISABLE_DRAWING(&dp->rd_vscreen); 987 else 988 #endif 989 vcons_replay_msgbuf(&dp->rd_vscreen); 990 } else { 991 992 /* 993 * since we're not the console we can postpone 994 * the rest until someone actually allocates a 995 * screen for us. but we do clear the screen 996 * at least. 997 */ 998 memset(ri->ri_bits, 0, 1024); 999 1000 radeonfb_modeswitch(dp); 1001 #ifdef SPLASHSCREEN 1002 if (splash_render(&dp->rd_splash, 1003 SPLASH_F_CENTER|SPLASH_F_FILL) == 0) 1004 SCREEN_DISABLE_DRAWING(&dp->rd_vscreen); 1005 #endif 1006 } 1007 1008 aa.console = dp->rd_console; 1009 aa.scrdata = &dp->rd_wsscreenlist; 1010 aa.accessops = &radeonfb_accessops; 1011 aa.accesscookie = &dp->rd_vd; 1012 1013 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); 1014 1015 radeonfb_blank(dp, 0); 1016 1017 /* Initialise delayed lvds operations for backlight. */ 1018 callout_init(&dp->rd_bl_lvds_co, 0); 1019 callout_setfunc(&dp->rd_bl_lvds_co, 1020 radeonfb_lvds_callout, dp); 1021 dp->rd_bl_on = 1; 1022 dp->rd_bl_level = radeonfb_get_backlight(dp); 1023 radeonfb_set_backlight(dp, dp->rd_bl_level); 1024 } 1025 1026 for (i = 0; i < RADEON_NDISPLAYS; i++) 1027 radeonfb_init_palette(&sc->sc_displays[i]); 1028 1029 if (HAS_CRTC2(sc)) { 1030 CLR32(sc, RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_DISP_DIS); 1031 } 1032 1033 CLR32(sc, RADEON_CRTC_EXT_CNTL, RADEON_CRTC_DISPLAY_DIS); 1034 SET32(sc, RADEON_FP_GEN_CNTL, RADEON_FP_FPON); 1035 pmf_event_register(dev, PMFE_DISPLAY_BRIGHTNESS_UP, 1036 radeonfb_brightness_up, TRUE); 1037 pmf_event_register(dev, PMFE_DISPLAY_BRIGHTNESS_DOWN, 1038 radeonfb_brightness_down, TRUE); 1039 1040 /* 1041 * if we attach a DRM we need to unmap registers in 1042 * WSDISPLAYIO_MODE_MAPPED, since this keeps us from doing things like 1043 * screen blanking we only do it if needed 1044 */ 1045 sc->sc_needs_unmap = 1046 (config_found_ia(dev, "drm", aux, radeonfb_drm_print) != 0); 1047 DPRINTF(("needs_unmap: %d\n", sc->sc_needs_unmap)); 1048 1049 PRINTREG(RADEON_CRTC_EXT_CNTL); 1050 PRINTREG(RADEON_CRTC_GEN_CNTL); 1051 PRINTREG(RADEON_CRTC2_GEN_CNTL); 1052 PRINTREG(RADEON_DISP_OUTPUT_CNTL); 1053 PRINTREG(RADEON_DAC_CNTL2); 1054 PRINTREG(RADEON_FP_GEN_CNTL); 1055 PRINTREG(RADEON_FP2_GEN_CNTL); 1056 PRINTREG(RADEON_TMDS_CNTL); 1057 PRINTREG(RADEON_TMDS_TRANSMITTER_CNTL); 1058 PRINTREG(RADEON_TMDS_PLL_CNTL); 1059 PRINTREG(RADEON_PIXCLKS_CNTL); 1060 1061 return; 1062 1063 error: 1064 if (sc->sc_biossz) 1065 free(sc->sc_bios, M_DEVBUF); 1066 1067 if (sc->sc_regsz) 1068 bus_space_unmap(sc->sc_regt, sc->sc_regh, sc->sc_regsz); 1069 1070 if (sc->sc_memsz) 1071 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsz); 1072 } 1073 1074 static void 1075 radeonfb_map(struct radeonfb_softc *sc) 1076 { 1077 if (!sc->sc_mapped) { 1078 if (bus_space_map(sc->sc_regt, sc->sc_regaddr, sc->sc_regsz, 0, 1079 &sc->sc_regh) != 0) { 1080 aprint_error_dev(sc->sc_dev, 1081 "unable to map registers!\n"); 1082 return; 1083 } 1084 if (bus_space_map(sc->sc_memt, sc->sc_memaddr, sc->sc_memsz, 1085 BUS_SPACE_MAP_LINEAR, &sc->sc_memh) != 0) { 1086 sc->sc_memsz = 0; 1087 aprint_error_dev(sc->sc_dev, 1088 "Unable to map frame buffer\n"); 1089 return; 1090 } 1091 sc->sc_mapped = TRUE; 1092 } 1093 } 1094 1095 static void 1096 radeonfb_unmap(struct radeonfb_softc *sc) 1097 { 1098 if (!sc->sc_needs_unmap) 1099 return; 1100 1101 if (sc->sc_mapped) { 1102 bus_space_unmap(sc->sc_regt, sc->sc_regh, sc->sc_regsz); 1103 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsz); 1104 sc->sc_mapped = FALSE; 1105 } 1106 } 1107 1108 static int 1109 radeonfb_drm_print(void *aux, const char *pnp) 1110 { 1111 if (pnp) 1112 aprint_normal("drm at %s", pnp); 1113 return (UNCONF); 1114 } 1115 1116 int 1117 radeonfb_ioctl(void *v, void *vs, 1118 unsigned long cmd, void *d, int flag, struct lwp *l) 1119 { 1120 struct vcons_data *vd; 1121 struct radeonfb_display *dp; 1122 struct radeonfb_softc *sc; 1123 struct wsdisplay_param *param; 1124 struct vcons_screen *ms; 1125 1126 vd = (struct vcons_data *)v; 1127 ms = vd->active; 1128 dp = (struct radeonfb_display *)vd->cookie; 1129 sc = dp->rd_softc; 1130 1131 /* can't do these without registers being mapped */ 1132 if (!sc->sc_mapped) { 1133 switch (cmd) { 1134 case WSDISPLAYIO_GVIDEO: 1135 case WSDISPLAYIO_SVIDEO: 1136 case WSDISPLAYIO_GETCMAP: 1137 case WSDISPLAYIO_PUTCMAP: 1138 case WSDISPLAYIO_SCURSOR: 1139 case WSDISPLAYIO_GCURPOS: 1140 case WSDISPLAYIO_SCURPOS: 1141 case WSDISPLAYIO_SETPARAM: 1142 return EINVAL; 1143 } 1144 } 1145 1146 switch (cmd) { 1147 case WSDISPLAYIO_GTYPE: 1148 *(unsigned *)d = WSDISPLAY_TYPE_PCIMISC; 1149 return 0; 1150 1151 case WSDISPLAYIO_GINFO: 1152 if (vd->active != NULL) { 1153 struct wsdisplay_fbinfo *fb; 1154 fb = (struct wsdisplay_fbinfo *)d; 1155 fb->width = dp->rd_virtx; 1156 fb->height = dp->rd_virty; 1157 fb->depth = dp->rd_bpp; 1158 fb->cmsize = 256; 1159 return 0; 1160 } else 1161 return ENODEV; 1162 case WSDISPLAYIO_GVIDEO: 1163 if (radeonfb_isblank(dp)) 1164 *(unsigned *)d = WSDISPLAYIO_VIDEO_OFF; 1165 else 1166 *(unsigned *)d = WSDISPLAYIO_VIDEO_ON; 1167 return 0; 1168 1169 case WSDISPLAYIO_SVIDEO: 1170 radeonfb_blank(dp, 1171 (*(unsigned int *)d == WSDISPLAYIO_VIDEO_OFF)); 1172 radeonfb_switch_backlight(dp, 1173 (*(unsigned int *)d == WSDISPLAYIO_VIDEO_ON)); 1174 return 0; 1175 1176 case WSDISPLAYIO_GETCMAP: 1177 if (dp->rd_bpp == 8) 1178 return radeonfb_getcmap(dp, 1179 (struct wsdisplay_cmap *)d); 1180 return EINVAL; 1181 1182 case WSDISPLAYIO_PUTCMAP: 1183 if (dp->rd_bpp == 8) 1184 return radeonfb_putcmap(dp, 1185 (struct wsdisplay_cmap *)d); 1186 return EINVAL; 1187 1188 case WSDISPLAYIO_LINEBYTES: 1189 *(unsigned *)d = dp->rd_stride; 1190 return 0; 1191 1192 case WSDISPLAYIO_SMODE: 1193 if (*(int *)d != dp->rd_wsmode) { 1194 dp->rd_wsmode = *(int *)d; 1195 if ((dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) || 1196 (dp->rd_wsmode == WSDISPLAYIO_MODE_DUMBFB)) 1197 radeonfb_map(sc); 1198 1199 if ((dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) && 1200 (dp->rd_vd.active)) { 1201 radeonfb_engine_init(dp); 1202 glyphcache_wipe(&dp->rd_gc); 1203 radeonfb_init_palette(dp); 1204 radeonfb_modeswitch(dp); 1205 radeonfb_rectfill(dp, 0, 0, dp->rd_virtx, 1206 dp->rd_virty, dp->rd_bg); 1207 vcons_redraw_screen(dp->rd_vd.active); 1208 } 1209 if (dp->rd_wsmode == WSDISPLAYIO_MODE_MAPPED) 1210 radeonfb_unmap(sc); 1211 } 1212 return 0; 1213 1214 case WSDISPLAYIO_GCURMAX: 1215 ((struct wsdisplay_curpos *)d)->x = RADEON_CURSORMAXX; 1216 ((struct wsdisplay_curpos *)d)->y = RADEON_CURSORMAXY; 1217 return 0; 1218 1219 case WSDISPLAYIO_SCURSOR: 1220 return radeonfb_set_cursor(dp, (struct wsdisplay_cursor *)d); 1221 1222 case WSDISPLAYIO_GCURSOR: 1223 return EPASSTHROUGH; 1224 1225 case WSDISPLAYIO_GCURPOS: 1226 ((struct wsdisplay_curpos *)d)->x = dp->rd_cursor.rc_pos.x; 1227 ((struct wsdisplay_curpos *)d)->y = dp->rd_cursor.rc_pos.y; 1228 return 0; 1229 1230 case WSDISPLAYIO_SCURPOS: 1231 return radeonfb_set_curpos(dp, (struct wsdisplay_curpos *)d); 1232 1233 case WSDISPLAYIO_SSPLASH: 1234 #if defined(SPLASHSCREEN) 1235 if (*(int *)d == 1) { 1236 SCREEN_DISABLE_DRAWING(&dp->rd_vscreen); 1237 splash_render(&dp->rd_splash, 1238 SPLASH_F_CENTER|SPLASH_F_FILL); 1239 } else 1240 SCREEN_ENABLE_DRAWING(&dp->rd_vscreen); 1241 return 0; 1242 #else 1243 return ENODEV; 1244 #endif 1245 case WSDISPLAYIO_GETPARAM: 1246 param = (struct wsdisplay_param *)d; 1247 switch (param->param) { 1248 case WSDISPLAYIO_PARAM_BRIGHTNESS: 1249 param->min = 0; 1250 param->max = 255; 1251 param->curval = dp->rd_bl_level; 1252 return 0; 1253 case WSDISPLAYIO_PARAM_BACKLIGHT: 1254 param->min = 0; 1255 param->max = RADEONFB_BACKLIGHT_MAX; 1256 param->curval = dp->rd_bl_on; 1257 return 0; 1258 } 1259 return EPASSTHROUGH; 1260 1261 case WSDISPLAYIO_SETPARAM: 1262 param = (struct wsdisplay_param *)d; 1263 switch (param->param) { 1264 case WSDISPLAYIO_PARAM_BRIGHTNESS: 1265 radeonfb_set_backlight(dp, param->curval); 1266 return 0; 1267 case WSDISPLAYIO_PARAM_BACKLIGHT: 1268 radeonfb_switch_backlight(dp, param->curval); 1269 return 0; 1270 } 1271 return EPASSTHROUGH; 1272 1273 /* PCI config read/write passthrough. */ 1274 case PCI_IOC_CFGREAD: 1275 case PCI_IOC_CFGWRITE: 1276 return pci_devioctl(sc->sc_pc, sc->sc_pt, cmd, d, flag, l); 1277 1278 case WSDISPLAYIO_GET_BUSID: 1279 return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc, 1280 sc->sc_pt, d); 1281 1282 case WSDISPLAYIO_GET_EDID: { 1283 struct wsdisplayio_edid_info *ei = d; 1284 return wsdisplayio_get_edid(sc->sc_dev, ei); 1285 } 1286 1287 case WSDISPLAYIO_GET_FBINFO: { 1288 struct wsdisplayio_fbinfo *fbi = d; 1289 return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); 1290 } 1291 1292 default: 1293 return EPASSTHROUGH; 1294 } 1295 } 1296 1297 paddr_t 1298 radeonfb_mmap(void *v, void *vs, off_t offset, int prot) 1299 { 1300 struct vcons_data *vd; 1301 struct radeonfb_display *dp; 1302 struct radeonfb_softc *sc; 1303 paddr_t pa; 1304 1305 vd = (struct vcons_data *)v; 1306 dp = (struct radeonfb_display *)vd->cookie; 1307 sc = dp->rd_softc; 1308 1309 if ((offset >= 0) && (offset < (dp->rd_virty * dp->rd_stride))) { 1310 pa = bus_space_mmap(sc->sc_memt, 1311 sc->sc_memaddr + dp->rd_offset + offset, 0, 1312 prot, BUS_SPACE_MAP_LINEAR); 1313 return pa; 1314 } 1315 1316 /* 1317 * restrict all other mappings to processes with superuser privileges 1318 * or the kernel itself 1319 */ 1320 if (kauth_authorize_machdep(kauth_cred_get(), KAUTH_MACHDEP_UNMANAGEDMEM, 1321 NULL, NULL, NULL, NULL) != 0) { 1322 aprint_error_dev(sc->sc_dev, "mmap() rejected.\n"); 1323 return -1; 1324 } 1325 1326 if ((offset >= sc->sc_regaddr) && 1327 (offset < sc->sc_regaddr + sc->sc_regsz)) { 1328 return bus_space_mmap(sc->sc_regt, offset, 0, prot, 1329 BUS_SPACE_MAP_LINEAR); 1330 } 1331 1332 if ((offset >= sc->sc_memaddr) && 1333 (offset < sc->sc_memaddr + sc->sc_memsz)) { 1334 return bus_space_mmap(sc->sc_memt, offset, 0, prot, 1335 BUS_SPACE_MAP_LINEAR); 1336 } 1337 1338 if ((offset >= sc->sc_romaddr) && 1339 (offset < sc->sc_romaddr + sc->sc_romsz)) { 1340 return bus_space_mmap(sc->sc_memt, offset, 0, prot, 1341 BUS_SPACE_MAP_LINEAR); 1342 } 1343 1344 #ifdef PCI_MAGIC_IO_RANGE 1345 /* allow mapping of IO space */ 1346 if ((offset >= PCI_MAGIC_IO_RANGE) && 1347 (offset < PCI_MAGIC_IO_RANGE + 0x10000)) { 1348 pa = bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE, 1349 0, prot, 0); 1350 return pa; 1351 } 1352 #endif /* PCI_MAGIC_IO_RANGE */ 1353 1354 return -1; 1355 } 1356 1357 static void 1358 radeonfb_loadbios(struct radeonfb_softc *sc, const struct pci_attach_args *pa) 1359 { 1360 bus_space_tag_t romt; 1361 bus_space_handle_t romh, biosh; 1362 bus_size_t romsz; 1363 bus_addr_t ptr; 1364 1365 if (pci_mapreg_map(pa, PCI_MAPREG_ROM, PCI_MAPREG_TYPE_ROM, 1366 BUS_SPACE_MAP_PREFETCHABLE, &romt, &romh, NULL, &romsz) != 0) { 1367 aprint_verbose("%s: unable to map BIOS!\n", XNAME(sc)); 1368 return; 1369 } 1370 1371 pci_find_rom(pa, romt, romh, romsz, PCI_ROM_CODE_TYPE_X86, &biosh, 1372 &sc->sc_biossz); 1373 if (sc->sc_biossz == 0) { 1374 aprint_verbose("%s: Video BIOS not present\n", XNAME(sc)); 1375 return; 1376 } 1377 1378 sc->sc_bios = malloc(sc->sc_biossz, M_DEVBUF, M_WAITOK); 1379 bus_space_read_region_1(romt, biosh, 0, sc->sc_bios, sc->sc_biossz); 1380 1381 /* unmap the PCI expansion rom */ 1382 bus_space_unmap(romt, romh, romsz); 1383 1384 /* turn off rom decoder now */ 1385 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM, 1386 pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM) & 1387 ~PCI_MAPREG_ROM_ENABLE); 1388 1389 ptr = GETBIOS16(sc, 0x48); 1390 if ((GETBIOS32(sc, ptr + 4) == 0x41544f4d /* "ATOM" */) || 1391 (GETBIOS32(sc, ptr + 4) == 0x4d4f5441 /* "MOTA" */)) { 1392 sc->sc_flags |= RFB_ATOM; 1393 } 1394 1395 aprint_verbose("%s: Found %d KB %s BIOS\n", XNAME(sc), 1396 (unsigned)sc->sc_biossz >> 10, IS_ATOM(sc) ? "ATOM" : "Legacy"); 1397 } 1398 1399 1400 uint32_t 1401 radeonfb_get32(struct radeonfb_softc *sc, uint32_t reg) 1402 { 1403 1404 return bus_space_read_4(sc->sc_regt, sc->sc_regh, reg); 1405 } 1406 1407 void 1408 radeonfb_put32(struct radeonfb_softc *sc, uint32_t reg, uint32_t val) 1409 { 1410 1411 bus_space_write_4(sc->sc_regt, sc->sc_regh, reg, val); 1412 } 1413 1414 void 1415 radeonfb_put32s(struct radeonfb_softc *sc, uint32_t reg, uint32_t val) 1416 { 1417 1418 bus_space_write_stream_4(sc->sc_regt, sc->sc_regh, reg, val); 1419 } 1420 1421 void 1422 radeonfb_mask32(struct radeonfb_softc *sc, uint32_t reg, 1423 uint32_t andmask, uint32_t ormask) 1424 { 1425 int s; 1426 uint32_t val; 1427 1428 s = splhigh(); 1429 val = radeonfb_get32(sc, reg); 1430 val = (val & andmask) | ormask; 1431 radeonfb_put32(sc, reg, val); 1432 splx(s); 1433 } 1434 1435 uint32_t 1436 radeonfb_getindex(struct radeonfb_softc *sc, uint32_t idx) 1437 { 1438 int s; 1439 uint32_t val; 1440 1441 s = splhigh(); 1442 radeonfb_put32(sc, RADEON_MM_INDEX, idx); 1443 val = radeonfb_get32(sc, RADEON_MM_DATA); 1444 splx(s); 1445 1446 return (val); 1447 } 1448 1449 void 1450 radeonfb_putindex(struct radeonfb_softc *sc, uint32_t idx, uint32_t val) 1451 { 1452 int s; 1453 1454 s = splhigh(); 1455 radeonfb_put32(sc, RADEON_MM_INDEX, idx); 1456 radeonfb_put32(sc, RADEON_MM_DATA, val); 1457 splx(s); 1458 } 1459 1460 void 1461 radeonfb_maskindex(struct radeonfb_softc *sc, uint32_t idx, 1462 uint32_t andmask, uint32_t ormask) 1463 { 1464 int s; 1465 uint32_t val; 1466 1467 s = splhigh(); 1468 radeonfb_put32(sc, RADEON_MM_INDEX, idx); 1469 val = radeonfb_get32(sc, RADEON_MM_DATA); 1470 val = (val & andmask) | ormask; 1471 radeonfb_put32(sc, RADEON_MM_DATA, val); 1472 splx(s); 1473 } 1474 1475 uint32_t 1476 radeonfb_getpll(struct radeonfb_softc *sc, uint32_t idx) 1477 { 1478 int s; 1479 uint32_t val; 1480 1481 s = splhigh(); 1482 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, (idx & 0x3f)); 1483 val = radeonfb_get32(sc, RADEON_CLOCK_CNTL_DATA); 1484 if (HAS_R300CG(sc)) 1485 radeonfb_r300cg_workaround(sc); 1486 splx(s); 1487 1488 return (val); 1489 } 1490 1491 void 1492 radeonfb_putpll(struct radeonfb_softc *sc, uint32_t idx, uint32_t val) 1493 { 1494 int s; 1495 1496 s = splhigh(); 1497 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, (idx & 0x3f) | 1498 RADEON_PLL_WR_EN); 1499 radeonfb_put32(sc, RADEON_CLOCK_CNTL_DATA, val); 1500 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, 0); 1501 splx(s); 1502 } 1503 1504 void 1505 radeonfb_maskpll(struct radeonfb_softc *sc, uint32_t idx, 1506 uint32_t andmask, uint32_t ormask) 1507 { 1508 int s; 1509 uint32_t val; 1510 1511 s = splhigh(); 1512 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, (idx & 0x3f) | 1513 RADEON_PLL_WR_EN); 1514 val = radeonfb_get32(sc, RADEON_CLOCK_CNTL_DATA); 1515 val = (val & andmask) | ormask; 1516 radeonfb_put32(sc, RADEON_CLOCK_CNTL_DATA, val); 1517 radeonfb_put32(sc, RADEON_CLOCK_CNTL_INDEX, 0); 1518 splx(s); 1519 } 1520 1521 int 1522 radeonfb_scratch_test(struct radeonfb_softc *sc, int reg, uint32_t v) 1523 { 1524 uint32_t saved; 1525 1526 saved = GET32(sc, reg); 1527 PUT32(sc, reg, v); 1528 if (GET32(sc, reg) != v) { 1529 return -1; 1530 } 1531 PUT32(sc, reg, saved); 1532 return 0; 1533 } 1534 1535 uintmax_t 1536 radeonfb_getprop_num(struct radeonfb_softc *sc, const char *name, 1537 uintmax_t defval) 1538 { 1539 prop_number_t pn; 1540 pn = prop_dictionary_get(device_properties(sc->sc_dev), name); 1541 if (pn == NULL) { 1542 return defval; 1543 } 1544 KASSERT(prop_object_type(pn) == PROP_TYPE_NUMBER); 1545 return (prop_number_integer_value(pn)); 1546 } 1547 1548 int 1549 radeonfb_getclocks(struct radeonfb_softc *sc) 1550 { 1551 bus_addr_t ptr; 1552 int refclk = 0; 1553 int refdiv = 0; 1554 int minpll = 0; 1555 int maxpll = 0; 1556 1557 /* load initial property values if port/board provides them */ 1558 refclk = radeonfb_getprop_num(sc, "refclk", 0) & 0xffff; 1559 refdiv = radeonfb_getprop_num(sc, "refdiv", 0) & 0xffff; 1560 minpll = radeonfb_getprop_num(sc, "minpll", 0) & 0xffffffffU; 1561 maxpll = radeonfb_getprop_num(sc, "maxpll", 0) & 0xffffffffU; 1562 1563 PRINTPLL(RADEON_PPLL_REF_DIV); 1564 PRINTPLL(RADEON_PPLL_DIV_0); 1565 PRINTPLL(RADEON_PPLL_DIV_1); 1566 PRINTPLL(RADEON_PPLL_DIV_2); 1567 PRINTPLL(RADEON_PPLL_DIV_3); 1568 PRINTREG(RADEON_CLOCK_CNTL_INDEX); 1569 PRINTPLL(RADEON_P2PLL_REF_DIV); 1570 PRINTPLL(RADEON_P2PLL_DIV_0); 1571 1572 if (refclk && refdiv && minpll && maxpll) 1573 goto dontprobe; 1574 1575 if (!sc->sc_biossz) { 1576 /* no BIOS */ 1577 aprint_verbose("%s: No video BIOS, using default clocks\n", 1578 XNAME(sc)); 1579 if (IS_IGP(sc)) 1580 refclk = refclk ? refclk : 1432; 1581 else 1582 refclk = refclk ? refclk : 2700; 1583 refdiv = refdiv ? refdiv : 12; 1584 minpll = minpll ? minpll : 12500; 1585 /* XXX 1586 * Need to check if the firmware or something programmed a 1587 * higher value than this, and if so, bump it. 1588 * The RV280 in my iBook is unhappy if the PLL input is less 1589 * than 360MHz 1590 */ 1591 maxpll = maxpll ? maxpll : 40000/*35000*/; 1592 } else if (IS_ATOM(sc)) { 1593 /* ATOM BIOS */ 1594 ptr = GETBIOS16(sc, 0x48); 1595 ptr = GETBIOS16(sc, ptr + 32); /* aka MasterDataStart */ 1596 ptr = GETBIOS16(sc, ptr + 12); /* pll info block */ 1597 refclk = refclk ? refclk : GETBIOS16(sc, ptr + 82); 1598 minpll = minpll ? minpll : GETBIOS16(sc, ptr + 78); 1599 maxpll = maxpll ? maxpll : GETBIOS16(sc, ptr + 32); 1600 /* 1601 * ATOM BIOS doesn't supply a reference divider, so we 1602 * have to probe for it. 1603 */ 1604 if (refdiv < 2) 1605 refdiv = GETPLL(sc, RADEON_PPLL_REF_DIV) & 1606 RADEON_PPLL_REF_DIV_MASK; 1607 /* 1608 * if probe is zero, just assume one that should work 1609 * for most parts 1610 */ 1611 if (refdiv < 2) 1612 refdiv = 12; 1613 1614 } else { 1615 uint32_t tmp = GETPLL(sc, RADEON_PPLL_REF_DIV); 1616 /* Legacy BIOS */ 1617 ptr = GETBIOS16(sc, 0x48); 1618 ptr = GETBIOS16(sc, ptr + 0x30); 1619 if (IS_R300(sc)) { 1620 refdiv = refdiv ? refdiv : 1621 (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> 1622 R300_PPLL_REF_DIV_ACC_SHIFT; 1623 } else { 1624 refdiv = refdiv ? refdiv : 1625 tmp & RADEON_PPLL_REF_DIV_MASK; 1626 } 1627 refclk = refclk ? refclk : GETBIOS16(sc, ptr + 0x0E); 1628 refdiv = refdiv ? refdiv : GETBIOS16(sc, ptr + 0x10); 1629 minpll = minpll ? minpll : GETBIOS32(sc, ptr + 0x12); 1630 maxpll = maxpll ? maxpll : GETBIOS32(sc, ptr + 0x16); 1631 } 1632 1633 1634 dontprobe: 1635 sc->sc_refclk = refclk * 10; 1636 sc->sc_refdiv = refdiv; 1637 sc->sc_minpll = minpll * 10; 1638 sc->sc_maxpll = maxpll * 10; 1639 return 0; 1640 } 1641 1642 int 1643 radeonfb_calc_dividers(struct radeonfb_softc *sc, uint32_t dotclock, 1644 uint32_t *postdivbit, uint32_t *feedbackdiv, int flags) 1645 { 1646 int i; 1647 uint32_t outfreq; 1648 int div; 1649 1650 DPRINTF(("dot clock: %u\n", dotclock)); 1651 for (i = 0; (div = radeonfb_dividers[i].divider) != 0; i++) { 1652 1653 if ((flags & NO_ODD_FBDIV) && ((div & 1) != 0)) 1654 continue; 1655 1656 /* 1657 * XXX 1658 * the rv350 in my last generation 14" iBook G4 produces 1659 * garbage with dividers > 4. No idea if this is a hardware 1660 * limitation or an error in the divider table. 1661 */ 1662 if ((sc->sc_family == RADEON_RV350) && (div > 4)) 1663 continue; 1664 1665 outfreq = div * dotclock; 1666 if ((outfreq >= sc->sc_minpll) && 1667 (outfreq <= sc->sc_maxpll)) { 1668 DPRINTF(("outfreq: %u\n", outfreq)); 1669 *postdivbit = 1670 ((uint32_t)radeonfb_dividers[i].mask << 16); 1671 DPRINTF(("post divider: %d (mask %x)\n", div, 1672 *postdivbit)); 1673 break; 1674 } 1675 } 1676 1677 if (div == 0) 1678 return 1; 1679 1680 *feedbackdiv = DIVIDE(sc->sc_refdiv * outfreq, sc->sc_refclk); 1681 DPRINTF(("feedback divider: %d\n", *feedbackdiv)); 1682 return 0; 1683 } 1684 1685 #if 0 1686 #ifdef RADEONFB_DEBUG 1687 static void 1688 dump_buffer(const char *pfx, void *buffer, unsigned int size) 1689 { 1690 char asc[17]; 1691 unsigned ptr = (unsigned)buffer; 1692 char *start = (char *)(ptr & ~0xf); 1693 char *end = (char *)(ptr + size); 1694 1695 end = (char *)(((unsigned)end + 0xf) & ~0xf); 1696 1697 if (pfx == NULL) { 1698 pfx = ""; 1699 } 1700 1701 while (start < end) { 1702 unsigned offset = (unsigned)start & 0xf; 1703 if (offset == 0) { 1704 printf("%s%x: ", pfx, (unsigned)start); 1705 } 1706 if (((unsigned)start < ptr) || 1707 ((unsigned)start >= (ptr + size))) { 1708 printf(" "); 1709 asc[offset] = ' '; 1710 } else { 1711 printf("%02x", *(unsigned char *)start); 1712 if ((*start >= ' ') && (*start <= '~')) { 1713 asc[offset] = *start; 1714 } else { 1715 asc[offset] = '.'; 1716 } 1717 } 1718 asc[offset + 1] = 0; 1719 if (offset % 2) { 1720 printf(" "); 1721 } 1722 if (offset == 15) { 1723 printf(" %s\n", asc); 1724 } 1725 start++; 1726 } 1727 } 1728 #endif 1729 #endif 1730 1731 int 1732 radeonfb_getconnectors(struct radeonfb_softc *sc) 1733 { 1734 int i; 1735 int found = 0; 1736 1737 for (i = 0; i < 2; i++) { 1738 sc->sc_ports[i].rp_mon_type = RADEON_MT_UNKNOWN; 1739 sc->sc_ports[i].rp_ddc_type = RADEON_DDC_NONE; 1740 sc->sc_ports[i].rp_dac_type = RADEON_DAC_UNKNOWN; 1741 sc->sc_ports[i].rp_conn_type = RADEON_CONN_NONE; 1742 sc->sc_ports[i].rp_tmds_type = RADEON_TMDS_UNKNOWN; 1743 } 1744 1745 /* 1746 * This logic is borrowed from Xorg's radeon driver. 1747 */ 1748 if (!sc->sc_biossz) 1749 goto nobios; 1750 1751 if (IS_ATOM(sc)) { 1752 /* not done yet */ 1753 } else { 1754 uint16_t ptr; 1755 int port = 0; 1756 1757 ptr = GETBIOS16(sc, 0x48); 1758 ptr = GETBIOS16(sc, ptr + 0x50); 1759 for (i = 1; i < 4; i++) { 1760 uint16_t entry; 1761 uint8_t conn, ddc, dac, tmds; 1762 1763 /* 1764 * Parse the connector table. From reading the code, 1765 * it appears to made up of 16-bit entries for each 1766 * connector. The 16-bits are defined as: 1767 * 1768 * bits 12-15 - connector type (0 == end of table) 1769 * bits 8-11 - DDC type 1770 * bits 5-7 - ??? 1771 * bit 4 - TMDS type (1 = EXT, 0 = INT) 1772 * bits 1-3 - ??? 1773 * bit 0 - DAC, 1 = TVDAC, 0 = primary 1774 */ 1775 if (!GETBIOS8(sc, ptr + i * 2) && i > 1) 1776 break; 1777 entry = GETBIOS16(sc, ptr + i * 2); 1778 1779 conn = (entry >> 12) & 0xf; 1780 ddc = (entry >> 8) & 0xf; 1781 dac = (entry & 0x1) ? RADEON_DAC_TVDAC : 1782 RADEON_DAC_PRIMARY; 1783 tmds = ((entry >> 4) & 0x1) ? RADEON_TMDS_EXT : 1784 RADEON_TMDS_INT; 1785 1786 if (conn == RADEON_CONN_NONE) 1787 continue; /* no connector */ 1788 1789 1790 1791 /* 1792 * XXX 1793 * both Mac Mini variants have both outputs wired to 1794 * the same connector and share the DDC lines 1795 */ 1796 if ((found > 0) && 1797 (sc->sc_ports[port].rp_ddc_type == ddc)) { 1798 /* duplicate entry for same connector */ 1799 continue; 1800 } 1801 1802 /* internal DDC_DVI port gets priority */ 1803 if ((ddc == RADEON_DDC_DVI) || (port == 1)) 1804 port = 0; 1805 else 1806 port = 1; 1807 1808 sc->sc_ports[port].rp_ddc_type = 1809 ddc > RADEON_DDC_CRT2 ? RADEON_DDC_NONE : ddc; 1810 sc->sc_ports[port].rp_dac_type = dac; 1811 sc->sc_ports[port].rp_conn_type = 1812 min(conn, RADEON_CONN_UNSUPPORTED) ; 1813 1814 sc->sc_ports[port].rp_tmds_type = tmds; 1815 1816 if ((conn != RADEON_CONN_DVI_I) && 1817 (conn != RADEON_CONN_DVI_D) && 1818 (tmds == RADEON_TMDS_INT)) 1819 sc->sc_ports[port].rp_tmds_type = 1820 RADEON_TMDS_UNKNOWN; 1821 sc->sc_ports[port].rp_number = i - 1; 1822 1823 found += (port + 1); 1824 } 1825 } 1826 1827 nobios: 1828 if (!found) { 1829 bool dvi_ext = FALSE, dvi_int = FALSE; 1830 DPRINTF(("No connector info in BIOS!\n")); 1831 prop_dictionary_get_bool(device_properties(sc->sc_dev), 1832 "dvi-internal", &dvi_int); 1833 prop_dictionary_get_bool(device_properties(sc->sc_dev), 1834 "dvi-external", &dvi_ext); 1835 if (dvi_ext) { 1836 sc->sc_ports[0].rp_mon_type = RADEON_MT_UNKNOWN; 1837 sc->sc_ports[0].rp_ddc_type = RADEON_DDC_CRT2; 1838 sc->sc_ports[0].rp_dac_type = RADEON_DAC_PRIMARY; 1839 sc->sc_ports[0].rp_conn_type = RADEON_CONN_DVI_I; 1840 sc->sc_ports[0].rp_tmds_type = RADEON_TMDS_EXT; /* output to fp2 */ 1841 sc->sc_ports[0].rp_number = 0; 1842 sc->sc_ports[1].rp_mon_type = RADEON_MT_UNKNOWN; 1843 sc->sc_ports[1].rp_ddc_type = RADEON_DDC_NONE; 1844 sc->sc_ports[1].rp_dac_type = RADEON_DAC_UNKNOWN; 1845 sc->sc_ports[1].rp_conn_type = RADEON_CONN_NONE; 1846 sc->sc_ports[1].rp_tmds_type = RADEON_TMDS_UNKNOWN; 1847 sc->sc_ports[1].rp_number = 1; 1848 } else if (dvi_int) { 1849 sc->sc_ports[0].rp_mon_type = RADEON_MT_UNKNOWN; 1850 sc->sc_ports[0].rp_ddc_type = RADEON_DDC_CRT2; 1851 sc->sc_ports[0].rp_dac_type = RADEON_DAC_PRIMARY; 1852 sc->sc_ports[0].rp_conn_type = RADEON_CONN_DVI_I; 1853 sc->sc_ports[0].rp_tmds_type = RADEON_TMDS_INT; 1854 sc->sc_ports[0].rp_number = 0; 1855 sc->sc_ports[1].rp_mon_type = RADEON_MT_UNKNOWN; 1856 sc->sc_ports[1].rp_ddc_type = RADEON_DDC_NONE; 1857 sc->sc_ports[1].rp_dac_type = RADEON_DAC_UNKNOWN; 1858 sc->sc_ports[1].rp_conn_type = RADEON_CONN_NONE; 1859 sc->sc_ports[1].rp_tmds_type = RADEON_TMDS_UNKNOWN; 1860 sc->sc_ports[1].rp_number = 1; 1861 } else if IS_MOBILITY(sc) { 1862 /* default, port 0 = internal TMDS, port 1 = CRT */ 1863 sc->sc_ports[0].rp_mon_type = RADEON_MT_UNKNOWN; 1864 sc->sc_ports[0].rp_ddc_type = RADEON_DDC_DVI; 1865 sc->sc_ports[0].rp_dac_type = RADEON_DAC_TVDAC; 1866 sc->sc_ports[0].rp_conn_type = RADEON_CONN_DVI_D; 1867 sc->sc_ports[0].rp_tmds_type = RADEON_TMDS_INT; 1868 sc->sc_ports[0].rp_number = 0; 1869 1870 sc->sc_ports[1].rp_mon_type = RADEON_MT_UNKNOWN; 1871 sc->sc_ports[1].rp_ddc_type = RADEON_DDC_VGA; 1872 sc->sc_ports[1].rp_dac_type = RADEON_DAC_PRIMARY; 1873 sc->sc_ports[1].rp_conn_type = RADEON_CONN_CRT; 1874 sc->sc_ports[1].rp_tmds_type = RADEON_TMDS_EXT; 1875 sc->sc_ports[1].rp_number = 1; 1876 } else { 1877 /* default, port 0 = DVI, port 1 = CRT */ 1878 sc->sc_ports[0].rp_mon_type = RADEON_MT_UNKNOWN; 1879 sc->sc_ports[0].rp_ddc_type = RADEON_DDC_DVI; 1880 sc->sc_ports[0].rp_dac_type = RADEON_DAC_TVDAC; 1881 sc->sc_ports[0].rp_conn_type = RADEON_CONN_DVI_D; 1882 sc->sc_ports[0].rp_tmds_type = RADEON_TMDS_INT; 1883 sc->sc_ports[0].rp_number = 1; 1884 1885 sc->sc_ports[1].rp_mon_type = RADEON_MT_UNKNOWN; 1886 sc->sc_ports[1].rp_ddc_type = RADEON_DDC_VGA; 1887 sc->sc_ports[1].rp_dac_type = RADEON_DAC_PRIMARY; 1888 sc->sc_ports[1].rp_conn_type = RADEON_CONN_CRT; 1889 sc->sc_ports[1].rp_tmds_type = RADEON_TMDS_UNKNOWN; 1890 sc->sc_ports[1].rp_number = 0; 1891 } 1892 } 1893 1894 /* 1895 * Fixup for RS300/RS350/RS400 chips, that lack a primary DAC. 1896 * these chips should use TVDAC for the VGA port. 1897 */ 1898 if (HAS_SDAC(sc)) { 1899 if (sc->sc_ports[0].rp_conn_type == RADEON_CONN_CRT) { 1900 sc->sc_ports[0].rp_dac_type = RADEON_DAC_TVDAC; 1901 sc->sc_ports[1].rp_dac_type = RADEON_DAC_PRIMARY; 1902 } else { 1903 sc->sc_ports[1].rp_dac_type = RADEON_DAC_TVDAC; 1904 sc->sc_ports[0].rp_dac_type = RADEON_DAC_PRIMARY; 1905 } 1906 } else if (!HAS_CRTC2(sc)) { 1907 sc->sc_ports[0].rp_dac_type = RADEON_DAC_PRIMARY; 1908 } 1909 1910 for (i = 0; i < 2; i++) { 1911 char edid[128]; 1912 uint8_t ddc; 1913 struct edid_info *eip = &sc->sc_ports[i].rp_edid; 1914 prop_data_t edid_data; 1915 1916 DPRINTF(("Port #%d:\n", i)); 1917 DPRINTF((" conn = %d\n", sc->sc_ports[i].rp_conn_type)); 1918 DPRINTF((" ddc = %d\n", sc->sc_ports[i].rp_ddc_type)); 1919 DPRINTF((" dac = %d\n", sc->sc_ports[i].rp_dac_type)); 1920 DPRINTF((" tmds = %d\n", sc->sc_ports[i].rp_tmds_type)); 1921 DPRINTF((" crtc = %d\n", sc->sc_ports[i].rp_number)); 1922 1923 sc->sc_ports[i].rp_edid_valid = 0; 1924 /* first look for static EDID data */ 1925 if ((edid_data = prop_dictionary_get(device_properties( 1926 sc->sc_dev), "EDID")) != NULL) { 1927 1928 aprint_debug_dev(sc->sc_dev, "using static EDID\n"); 1929 memcpy(edid, prop_data_data_nocopy(edid_data), 128); 1930 if (edid_parse(edid, eip) == 0) { 1931 1932 sc->sc_ports[i].rp_edid_valid = 1; 1933 } 1934 } 1935 /* if we didn't find any we'll try to talk to the monitor */ 1936 if (sc->sc_ports[i].rp_edid_valid != 1) { 1937 1938 ddc = sc->sc_ports[i].rp_ddc_type; 1939 if (ddc != RADEON_DDC_NONE) { 1940 if ((radeonfb_i2c_read_edid(sc, ddc, edid) 1941 == 0) && (edid_parse(edid, eip) == 0)) { 1942 1943 sc->sc_ports[i].rp_edid_valid = 1; 1944 #ifdef RADEONFB_DEBUG 1945 edid_print(eip); 1946 #endif 1947 } 1948 } 1949 } 1950 } 1951 1952 return found; 1953 } 1954 1955 int 1956 radeonfb_gettmds(struct radeonfb_softc *sc) 1957 { 1958 int i; 1959 1960 if (!sc->sc_biossz) { 1961 goto nobios; 1962 } 1963 1964 if (IS_ATOM(sc)) { 1965 /* XXX: not done yet */ 1966 } else { 1967 uint16_t ptr; 1968 int n; 1969 1970 ptr = GETBIOS16(sc, 0x48); 1971 ptr = GETBIOS16(sc, ptr + 0x34); 1972 DPRINTF(("DFP table revision %d\n", GETBIOS8(sc, ptr))); 1973 if (GETBIOS8(sc, ptr) == 3) { 1974 /* revision three table */ 1975 n = GETBIOS8(sc, ptr + 5) + 1; 1976 n = min(n, 4); 1977 1978 memset(sc->sc_tmds_pll, 0, sizeof (sc->sc_tmds_pll)); 1979 for (i = 0; i < n; i++) { 1980 sc->sc_tmds_pll[i].rtp_pll = GETBIOS32(sc, 1981 ptr + i * 10 + 8); 1982 sc->sc_tmds_pll[i].rtp_freq = GETBIOS16(sc, 1983 ptr + i * 10 + 0x10); 1984 DPRINTF(("TMDS_PLL dot clock %d pll %x\n", 1985 sc->sc_tmds_pll[i].rtp_freq, 1986 sc->sc_tmds_pll[i].rtp_pll)); 1987 } 1988 return 0; 1989 } 1990 } 1991 1992 nobios: 1993 DPRINTF(("no suitable DFP table present\n")); 1994 for (i = 0; 1995 i < sizeof (radeonfb_tmds_pll) / sizeof (radeonfb_tmds_pll[0]); 1996 i++) { 1997 int j; 1998 1999 if (radeonfb_tmds_pll[i].family != sc->sc_family) 2000 continue; 2001 2002 for (j = 0; j < 4; j++) { 2003 sc->sc_tmds_pll[j] = radeonfb_tmds_pll[i].plls[j]; 2004 DPRINTF(("TMDS_PLL dot clock %d pll %x\n", 2005 sc->sc_tmds_pll[j].rtp_freq, 2006 sc->sc_tmds_pll[j].rtp_pll)); 2007 } 2008 return 0; 2009 } 2010 2011 return -1; 2012 } 2013 2014 const struct videomode * 2015 radeonfb_modelookup(const char *name) 2016 { 2017 int i; 2018 2019 for (i = 0; i < videomode_count; i++) 2020 if (!strcmp(name, videomode_list[i].name)) 2021 return &videomode_list[i]; 2022 2023 return NULL; 2024 } 2025 2026 void 2027 radeonfb_pllwriteupdate(struct radeonfb_softc *sc, int crtc) 2028 { 2029 if (crtc) { 2030 while (GETPLL(sc, RADEON_P2PLL_REF_DIV) & 2031 RADEON_P2PLL_ATOMIC_UPDATE_R); 2032 SETPLL(sc, RADEON_P2PLL_REF_DIV, RADEON_P2PLL_ATOMIC_UPDATE_W); 2033 } else { 2034 while (GETPLL(sc, RADEON_PPLL_REF_DIV) & 2035 RADEON_PPLL_ATOMIC_UPDATE_R); 2036 SETPLL(sc, RADEON_PPLL_REF_DIV, RADEON_PPLL_ATOMIC_UPDATE_W); 2037 } 2038 } 2039 2040 void 2041 radeonfb_pllwaitatomicread(struct radeonfb_softc *sc, int crtc) 2042 { 2043 int i; 2044 2045 for (i = 10000; i; i--) { 2046 if (crtc) { 2047 if (GETPLL(sc, RADEON_P2PLL_REF_DIV) & 2048 RADEON_P2PLL_ATOMIC_UPDATE_R) 2049 break; 2050 } else { 2051 if (GETPLL(sc, RADEON_PPLL_REF_DIV) & 2052 RADEON_PPLL_ATOMIC_UPDATE_R) 2053 break; 2054 } 2055 } 2056 } 2057 2058 void 2059 radeonfb_program_vclk(struct radeonfb_softc *sc, int dotclock, int crtc, int flags) 2060 { 2061 uint32_t pbit = 0; 2062 uint32_t feed = 0; 2063 uint32_t data, refdiv, div0, r2xxref; 2064 2065 radeonfb_calc_dividers(sc, dotclock, &pbit, &feed, flags); 2066 2067 if (crtc == 0) { 2068 2069 refdiv = GETPLL(sc, RADEON_PPLL_REF_DIV); 2070 2071 /* 2072 * XXX 2073 * the RV350 in my last generation iBook G4 behaves like an 2074 * r2xx here - try to detect that and not screw up the reference 2075 * divider. 2076 * xf86-video-radeon just skips PLL programming altogether 2077 * on iBooks, probably for this reason. 2078 */ 2079 r2xxref = (refdiv & ~RADEON_PPLL_REF_DIV_MASK) | sc->sc_refdiv; 2080 if (IS_R300(sc) && (r2xxref != refdiv)) { 2081 refdiv = (refdiv & ~R300_PPLL_REF_DIV_ACC_MASK) | 2082 (sc->sc_refdiv << R300_PPLL_REF_DIV_ACC_SHIFT); 2083 } else { 2084 refdiv = (refdiv & ~RADEON_PPLL_REF_DIV_MASK) | 2085 sc->sc_refdiv; 2086 } 2087 DPRINTF(("refdiv %08x\n", refdiv)); 2088 div0 = GETPLL(sc, RADEON_PPLL_DIV_0); 2089 DPRINTF(("div0 %08x\n", div0)); 2090 div0 &= ~(RADEON_PPLL_FB3_DIV_MASK | 2091 RADEON_PPLL_POST3_DIV_MASK); 2092 div0 |= pbit; 2093 div0 |= (feed & RADEON_PPLL_FB3_DIV_MASK); 2094 DPRINTF(("div0 %08x\n", div0)); 2095 2096 if ((refdiv == GETPLL(sc, RADEON_PPLL_REF_DIV)) && 2097 (div0 == GETPLL(sc, RADEON_PPLL_DIV_0))) { 2098 /* 2099 * nothing to do here, the PLL is already where we 2100 * want it 2101 */ 2102 PATCH32(sc, RADEON_CLOCK_CNTL_INDEX, 0, 2103 ~RADEON_PLL_DIV_SEL); 2104 aprint_debug_dev(sc->sc_dev, "no need to touch the PLL\n"); 2105 return; 2106 } 2107 2108 /* alright, we do need to reprogram stuff */ 2109 PATCHPLL(sc, RADEON_VCLK_ECP_CNTL, 2110 RADEON_VCLK_SRC_SEL_CPUCLK, 2111 ~RADEON_VCLK_SRC_SEL_MASK); 2112 2113 /* put vclk into reset, use atomic updates */ 2114 SETPLL(sc, RADEON_PPLL_CNTL, 2115 RADEON_PPLL_REFCLK_SEL | 2116 RADEON_PPLL_FBCLK_SEL | 2117 RADEON_PPLL_RESET | 2118 RADEON_PPLL_ATOMIC_UPDATE_EN | 2119 RADEON_PPLL_VGA_ATOMIC_UPDATE_EN); 2120 2121 /* select clock 0 */ 2122 PATCH32(sc, RADEON_CLOCK_CNTL_INDEX, 0, 2123 ~RADEON_PLL_DIV_SEL); 2124 2125 PUTPLL(sc, RADEON_PPLL_REF_DIV, refdiv); 2126 2127 /* xf86-video-radeon does this, not sure why */ 2128 PUTPLL(sc, RADEON_PPLL_DIV_0, div0); 2129 PUTPLL(sc, RADEON_PPLL_DIV_0, div0); 2130 2131 /* use the atomic update */ 2132 radeonfb_pllwriteupdate(sc, crtc); 2133 2134 /* and wait for it to complete */ 2135 radeonfb_pllwaitatomicread(sc, crtc); 2136 2137 /* program HTOTAL (why?) */ 2138 PUTPLL(sc, RADEON_HTOTAL_CNTL, 0); 2139 2140 /* drop reset */ 2141 CLRPLL(sc, RADEON_PPLL_CNTL, 2142 RADEON_PPLL_RESET | RADEON_PPLL_SLEEP | 2143 RADEON_PPLL_ATOMIC_UPDATE_EN | 2144 RADEON_PPLL_VGA_ATOMIC_UPDATE_EN); 2145 2146 PRINTPLL(RADEON_PPLL_CNTL); 2147 PRINTPLL(RADEON_PPLL_REF_DIV); 2148 PRINTPLL(RADEON_PPLL_DIV_3); 2149 2150 /* give clock time to lock */ 2151 delay(50000); 2152 2153 PATCHPLL(sc, RADEON_VCLK_ECP_CNTL, 2154 RADEON_VCLK_SRC_SEL_PPLLCLK, 2155 ~RADEON_VCLK_SRC_SEL_MASK); 2156 2157 } else { 2158 2159 PATCHPLL(sc, RADEON_PIXCLKS_CNTL, 2160 RADEON_PIX2CLK_SRC_SEL_CPUCLK, 2161 ~RADEON_PIX2CLK_SRC_SEL_MASK); 2162 2163 /* put vclk into reset, use atomic updates */ 2164 SETPLL(sc, RADEON_P2PLL_CNTL, 2165 RADEON_P2PLL_RESET | 2166 RADEON_P2PLL_ATOMIC_UPDATE_EN | 2167 RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN); 2168 2169 /* program reference divider */ 2170 PATCHPLL(sc, RADEON_P2PLL_REF_DIV, sc->sc_refdiv, 2171 ~RADEON_P2PLL_REF_DIV_MASK); 2172 2173 /* program feedback and post dividers */ 2174 data = GETPLL(sc, RADEON_P2PLL_DIV_0); 2175 data &= ~(RADEON_P2PLL_FB0_DIV_MASK | 2176 RADEON_P2PLL_POST0_DIV_MASK); 2177 data |= pbit; 2178 data |= (feed & RADEON_P2PLL_FB0_DIV_MASK); 2179 PUTPLL(sc, RADEON_P2PLL_DIV_0, data); 2180 PUTPLL(sc, RADEON_P2PLL_DIV_0, data); 2181 2182 PRINTPLL(RADEON_P2PLL_REF_DIV); 2183 PRINTPLL(RADEON_P2PLL_DIV_0); 2184 2185 /* use the atomic update */ 2186 radeonfb_pllwriteupdate(sc, crtc); 2187 2188 /* and wait for it to complete */ 2189 radeonfb_pllwaitatomicread(sc, crtc); 2190 2191 /* program HTOTAL (why?) */ 2192 PUTPLL(sc, RADEON_HTOTAL2_CNTL, 0); 2193 2194 /* drop reset */ 2195 CLRPLL(sc, RADEON_P2PLL_CNTL, 2196 RADEON_P2PLL_RESET | RADEON_P2PLL_SLEEP | 2197 RADEON_P2PLL_ATOMIC_UPDATE_EN | 2198 RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN); 2199 2200 /* allow time for clock to lock */ 2201 delay(50000); 2202 2203 PATCHPLL(sc, RADEON_PIXCLKS_CNTL, 2204 RADEON_PIX2CLK_SRC_SEL_P2PLLCLK, 2205 ~RADEON_PIX2CLK_SRC_SEL_MASK); 2206 } 2207 PRINTREG(RADEON_CRTC_MORE_CNTL); 2208 } 2209 2210 void 2211 radeonfb_modeswitch(struct radeonfb_display *dp) 2212 { 2213 struct radeonfb_softc *sc = dp->rd_softc; 2214 int i; 2215 2216 /* blank the display while we switch modes */ 2217 radeonfb_blank(dp, 1); 2218 2219 #if 0 2220 SET32(sc, RADEON_CRTC_EXT_CNTL, 2221 RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS | 2222 RADEON_CRTC_DISPLAY_DIS /* | RADEON_CRTC_DISP_REQ_EN_B */); 2223 #endif 2224 2225 /* these registers might get in the way... */ 2226 PUT32(sc, RADEON_OVR_CLR, 0); 2227 PUT32(sc, RADEON_OVR_WID_LEFT_RIGHT, 0); 2228 PUT32(sc, RADEON_OVR_WID_TOP_BOTTOM, 0); 2229 PUT32(sc, RADEON_OV0_SCALE_CNTL, 0); 2230 PUT32(sc, RADEON_SUBPIC_CNTL, 0); 2231 PUT32(sc, RADEON_VIPH_CONTROL, 0); 2232 PUT32(sc, RADEON_I2C_CNTL_1, 0); 2233 PUT32(sc, RADEON_GEN_INT_CNTL, 0); 2234 PUT32(sc, RADEON_CAP0_TRIG_CNTL, 0); 2235 PUT32(sc, RADEON_CAP1_TRIG_CNTL, 0); 2236 /* 2237 * Apple OF hands us R3xx radeons with tiling enabled - explicitly 2238 * disable it here 2239 */ 2240 PUT32(sc, RADEON_SURFACE_CNTL, RADEON_SURF_TRANSLATION_DIS); 2241 2242 for (i = 0; i < dp->rd_ncrtcs; i++) 2243 radeonfb_setcrtc(dp, i); 2244 2245 #if 0 2246 /* 2247 * DVO chip voodoo from xf86-video-radeon 2248 * apparently this is needed for some powerbooks with DVI outputs 2249 */ 2250 2251 uint8_t data[5][2] = {{0x8, 0x030}, {0x9, 0}, {0xa, 0x90}, {0xc, 0x89}, {0x8, 0x3b}}; 2252 int n = 0; 2253 iic_acquire_bus(&sc->sc_i2c[0].ric_controller, 0); 2254 for (i = 0; i < 5; i++) 2255 n += iic_exec(&sc->sc_i2c[0].ric_controller, I2C_OP_WRITE, 0x38, data[i], 2, NULL, 0, 0); 2256 iic_release_bus(&sc->sc_i2c[0].ric_controller, 0); 2257 printf("n = %d\n", n); 2258 #endif 2259 2260 /* activate the display */ 2261 radeonfb_blank(dp, 0); 2262 } 2263 2264 void 2265 radeonfb_setcrtc(struct radeonfb_display *dp, int index) 2266 { 2267 int crtc, flags = 0; 2268 struct videomode *mode; 2269 struct radeonfb_softc *sc; 2270 struct radeonfb_crtc *cp; 2271 uint32_t v; 2272 uint32_t gencntl; 2273 uint32_t htotaldisp; 2274 uint32_t hsyncstrt; 2275 uint32_t vtotaldisp; 2276 uint32_t vsyncstrt; 2277 uint32_t fphsyncstrt; 2278 uint32_t fpvsyncstrt; 2279 uint32_t fphtotaldisp; 2280 uint32_t fpvtotaldisp; 2281 uint32_t pitch; 2282 2283 sc = dp->rd_softc; 2284 2285 if ((sc->sc_ports[index].rp_tmds_type == RADEON_TMDS_INT) || 2286 (sc->sc_ports[index].rp_tmds_type == RADEON_TMDS_EXT)) { 2287 flags |= NO_ODD_FBDIV; 2288 } 2289 2290 cp = &dp->rd_crtcs[index]; 2291 crtc = cp->rc_number; 2292 mode = &cp->rc_videomode; 2293 2294 #if 1 2295 pitch = dp->rd_stride / dp->rd_bpp; 2296 #else 2297 pitch = (((sc->sc_maxx * sc->sc_maxbpp) + ((sc->sc_maxbpp * 8) - 1)) / 2298 (sc->sc_maxbpp * 8)); 2299 #endif 2300 switch (crtc) { 2301 case 0: 2302 gencntl = RADEON_CRTC_GEN_CNTL; 2303 htotaldisp = RADEON_CRTC_H_TOTAL_DISP; 2304 hsyncstrt = RADEON_CRTC_H_SYNC_STRT_WID; 2305 vtotaldisp = RADEON_CRTC_V_TOTAL_DISP; 2306 vsyncstrt = RADEON_CRTC_V_SYNC_STRT_WID; 2307 /* should probably leave those alone on non-LVDS */ 2308 fpvsyncstrt = RADEON_FP_V_SYNC_STRT_WID; 2309 fphsyncstrt = RADEON_FP_H_SYNC_STRT_WID; 2310 fpvtotaldisp = RADEON_FP_CRTC_V_TOTAL_DISP; 2311 fphtotaldisp = RADEON_FP_CRTC_H_TOTAL_DISP; 2312 break; 2313 case 1: 2314 gencntl = RADEON_CRTC2_GEN_CNTL; 2315 htotaldisp = RADEON_CRTC2_H_TOTAL_DISP; 2316 hsyncstrt = RADEON_CRTC2_H_SYNC_STRT_WID; 2317 vtotaldisp = RADEON_CRTC2_V_TOTAL_DISP; 2318 vsyncstrt = RADEON_CRTC2_V_SYNC_STRT_WID; 2319 fpvsyncstrt = RADEON_FP_V2_SYNC_STRT_WID; 2320 fphsyncstrt = RADEON_FP_H2_SYNC_STRT_WID; 2321 /* XXX these registers don't seem to exist */ 2322 fpvtotaldisp = 0;//RADEON_FP_CRTC2_V_TOTAL_DISP; 2323 fphtotaldisp = 0;//RADEON_FP_CRTC2_H_TOTAL_DISP; 2324 break; 2325 default: 2326 panic("Bad CRTC!"); 2327 break; 2328 } 2329 2330 /* 2331 * CRTC_GEN_CNTL - depth, accelerator mode, etc. 2332 */ 2333 /* only bother with 32bpp and 8bpp */ 2334 v = dp->rd_format << RADEON_CRTC_PIX_WIDTH_SHIFT; 2335 2336 if (crtc == 1) { 2337 v |= RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_EN; 2338 } else { 2339 v |= RADEON_CRTC_EXT_DISP_EN | RADEON_CRTC_EN; 2340 } 2341 2342 if (mode->flags & VID_DBLSCAN) 2343 v |= RADEON_CRTC2_DBL_SCAN_EN; 2344 2345 if (mode->flags & VID_INTERLACE) 2346 v |= RADEON_CRTC2_INTERLACE_EN; 2347 2348 if (mode->flags & VID_CSYNC) { 2349 v |= RADEON_CRTC2_CSYNC_EN; 2350 if (crtc == 1) 2351 v |= RADEON_CRTC2_VSYNC_TRISTAT; 2352 } 2353 2354 PUT32(sc, gencntl, v); 2355 DPRINTF(("CRTC%s_GEN_CNTL = %08x\n", crtc ? "2" : "", v)); 2356 2357 /* 2358 * CRTC_EXT_CNTL - preserve disable flags, set ATI linear and EXT_CNT 2359 */ 2360 v = GET32(sc, RADEON_CRTC_EXT_CNTL); 2361 if (crtc == 0) { 2362 v &= (RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS | 2363 RADEON_CRTC_DISPLAY_DIS); 2364 v |= RADEON_XCRT_CNT_EN | RADEON_VGA_ATI_LINEAR; 2365 if (mode->flags & VID_CSYNC) 2366 v |= RADEON_CRTC_VSYNC_TRISTAT; 2367 } 2368 /* unconditional turn on CRT, in case first CRTC is DFP */ 2369 v |= RADEON_CRTC_CRT_ON; 2370 PUT32(sc, RADEON_CRTC_EXT_CNTL, v); 2371 PRINTREG(RADEON_CRTC_EXT_CNTL); 2372 2373 /* 2374 * H_TOTAL_DISP 2375 */ 2376 v = ((mode->hdisplay / 8) - 1) << 16; 2377 v |= (mode->htotal / 8) - 1; 2378 PUT32(sc, htotaldisp, v); 2379 DPRINTF(("CRTC%s_H_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 2380 if (fphtotaldisp) { 2381 PUT32(sc, fphtotaldisp, v); 2382 DPRINTF(("FP_H%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 2383 } 2384 /* 2385 * H_SYNC_STRT_WID 2386 */ 2387 v = (((mode->hsync_end - mode->hsync_start) / 8) << 16); 2388 v |= (mode->hsync_start - 8); /* match xf86-video-radeon */ 2389 if (mode->flags & VID_NHSYNC) 2390 v |= RADEON_CRTC_H_SYNC_POL; 2391 PUT32(sc, hsyncstrt, v); 2392 DPRINTF(("CRTC%s_H_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2393 if (fphsyncstrt) { 2394 PUT32(sc, fphsyncstrt, v); 2395 DPRINTF(("FP_H%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2396 } 2397 2398 /* 2399 * V_TOTAL_DISP 2400 */ 2401 v = ((mode->vdisplay - 1) << 16); 2402 v |= (mode->vtotal - 1); 2403 PUT32(sc, vtotaldisp, v); 2404 DPRINTF(("CRTC%s_V_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 2405 if (fpvtotaldisp) { 2406 PUT32(sc, fpvtotaldisp, v); 2407 DPRINTF(("FP_V%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v)); 2408 } 2409 2410 /* 2411 * V_SYNC_STRT_WID 2412 */ 2413 v = ((mode->vsync_end - mode->vsync_start) << 16); 2414 v |= (mode->vsync_start - 1); 2415 if (mode->flags & VID_NVSYNC) 2416 v |= RADEON_CRTC_V_SYNC_POL; 2417 PUT32(sc, vsyncstrt, v); 2418 DPRINTF(("CRTC%s_V_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2419 if (fpvsyncstrt) { 2420 PUT32(sc, fpvsyncstrt, v); 2421 DPRINTF(("FP_V%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v)); 2422 } 2423 2424 radeonfb_program_vclk(sc, mode->dot_clock, crtc, flags); 2425 2426 switch (crtc) { 2427 case 0: 2428 PUT32(sc, RADEON_CRTC_OFFSET, 0); 2429 PUT32(sc, RADEON_CRTC_OFFSET_CNTL, 0); 2430 PUT32(sc, RADEON_CRTC_PITCH, pitch); 2431 CLR32(sc, RADEON_DISP_MERGE_CNTL, RADEON_DISP_RGB_OFFSET_EN); 2432 2433 CLR32(sc, RADEON_CRTC_EXT_CNTL, 2434 RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS | 2435 RADEON_CRTC_DISPLAY_DIS /* | RADEON_CRTC_DISP_REQ_EN_B */); 2436 CLR32(sc, RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B); 2437 PRINTREG(RADEON_CRTC_EXT_CNTL); 2438 PRINTREG(RADEON_CRTC_GEN_CNTL); 2439 PRINTREG(RADEON_CLOCK_CNTL_INDEX); 2440 break; 2441 2442 case 1: 2443 PUT32(sc, RADEON_CRTC2_OFFSET, 0); 2444 PUT32(sc, RADEON_CRTC2_OFFSET_CNTL, 0); 2445 PUT32(sc, RADEON_CRTC2_PITCH, pitch); 2446 CLR32(sc, RADEON_DISP2_MERGE_CNTL, RADEON_DISP2_RGB_OFFSET_EN); 2447 CLR32(sc, RADEON_CRTC2_GEN_CNTL, 2448 RADEON_CRTC2_VSYNC_DIS | 2449 RADEON_CRTC2_HSYNC_DIS | 2450 RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_DISP_REQ_EN_B); 2451 PRINTREG(RADEON_CRTC2_GEN_CNTL); 2452 break; 2453 } 2454 } 2455 2456 int 2457 radeonfb_isblank(struct radeonfb_display *dp) 2458 { 2459 uint32_t reg, mask; 2460 2461 if(!dp->rd_softc->sc_mapped) 2462 return 1; 2463 2464 if (dp->rd_crtcs[0].rc_number) { 2465 reg = RADEON_CRTC2_GEN_CNTL; 2466 mask = RADEON_CRTC2_DISP_DIS; 2467 } else { 2468 reg = RADEON_CRTC_EXT_CNTL; 2469 mask = RADEON_CRTC_DISPLAY_DIS; 2470 } 2471 return ((GET32(dp->rd_softc, reg) & mask) ? 1 : 0); 2472 } 2473 2474 void 2475 radeonfb_blank(struct radeonfb_display *dp, int blank) 2476 { 2477 struct radeonfb_softc *sc = dp->rd_softc; 2478 uint32_t reg, mask; 2479 uint32_t fpreg, fpval; 2480 int i; 2481 2482 if (!sc->sc_mapped) 2483 return; 2484 2485 for (i = 0; i < dp->rd_ncrtcs; i++) { 2486 2487 if (dp->rd_crtcs[i].rc_number) { 2488 reg = RADEON_CRTC2_GEN_CNTL; 2489 mask = RADEON_CRTC2_DISP_DIS; 2490 fpreg = RADEON_FP2_GEN_CNTL; 2491 fpval = RADEON_FP2_ON; 2492 } else { 2493 reg = RADEON_CRTC_EXT_CNTL; 2494 mask = RADEON_CRTC_DISPLAY_DIS; 2495 fpreg = RADEON_FP_GEN_CNTL; 2496 fpval = RADEON_FP_FPON; 2497 } 2498 2499 if (blank) { 2500 SET32(sc, reg, mask); 2501 CLR32(sc, fpreg, fpval); 2502 } else { 2503 CLR32(sc, reg, mask); 2504 SET32(sc, fpreg, fpval); 2505 } 2506 } 2507 PRINTREG(RADEON_FP_GEN_CNTL); 2508 PRINTREG(RADEON_FP2_GEN_CNTL); 2509 } 2510 2511 void 2512 radeonfb_init_screen(void *cookie, struct vcons_screen *scr, int existing, 2513 long *defattr) 2514 { 2515 struct radeonfb_display *dp = cookie; 2516 struct rasops_info *ri = &scr->scr_ri; 2517 2518 /* initialize font subsystem */ 2519 wsfont_init(); 2520 2521 scr->scr_flags |= VCONS_LOADFONT; 2522 2523 DPRINTF(("init screen called, existing %d\n", existing)); 2524 2525 ri->ri_depth = dp->rd_bpp; 2526 ri->ri_width = dp->rd_virtx; 2527 ri->ri_height = dp->rd_virty; 2528 ri->ri_stride = dp->rd_stride; 2529 ri->ri_flg = RI_CENTER; 2530 switch (ri->ri_depth) { 2531 case 8: 2532 ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB | RI_PREFER_ALPHA; 2533 break; 2534 case 32: 2535 ri->ri_flg |= RI_ENABLE_ALPHA | RI_PREFER_ALPHA; 2536 /* we run radeons in RGB even on SPARC hardware */ 2537 ri->ri_rnum = 8; 2538 ri->ri_gnum = 8; 2539 ri->ri_bnum = 8; 2540 ri->ri_rpos = 16; 2541 ri->ri_gpos = 8; 2542 ri->ri_bpos = 0; 2543 break; 2544 } 2545 2546 ri->ri_bits = (void *)dp->rd_fbptr; 2547 2548 #ifdef VCONS_DRAW_INTR 2549 scr->scr_flags |= VCONS_DONT_READ; 2550 #endif 2551 2552 if (existing) { 2553 ri->ri_flg |= RI_CLEAR; 2554 2555 /* start a modeswitch now */ 2556 radeonfb_modeswitch(dp); 2557 } 2558 2559 /* 2560 * XXX: font selection should be based on properties, with some 2561 * normal/reasonable default. 2562 */ 2563 2564 /* initialize and look for an initial font */ 2565 rasops_init(ri, 0, 0); 2566 ri->ri_caps = WSSCREEN_UNDERLINE | WSSCREEN_HILIT | 2567 WSSCREEN_WSCOLORS | WSSCREEN_REVERSE | WSSCREEN_RESIZE; 2568 2569 rasops_reconfig(ri, dp->rd_virty / ri->ri_font->fontheight, 2570 dp->rd_virtx / ri->ri_font->fontwidth); 2571 2572 /* enable acceleration */ 2573 dp->rd_putchar = ri->ri_ops.putchar; 2574 ri->ri_ops.copyrows = radeonfb_copyrows; 2575 ri->ri_ops.copycols = radeonfb_copycols; 2576 ri->ri_ops.eraserows = radeonfb_eraserows; 2577 ri->ri_ops.erasecols = radeonfb_erasecols; 2578 /* pick a putchar method based on font and Radeon model */ 2579 if (ri->ri_font->stride < ri->ri_font->fontwidth) { 2580 /* got a bitmap font */ 2581 #ifndef RADEONFB_ALWAYS_ACCEL_PUTCHAR 2582 if (IS_R300(dp->rd_softc)) { 2583 /* 2584 * radeonfb_putchar() doesn't work right on some R3xx 2585 * so we use software drawing here, the wrapper just 2586 * makes sure the engine is idle before scribbling 2587 * into vram 2588 */ 2589 ri->ri_ops.putchar = radeonfb_putchar_wrapper; 2590 } else 2591 #endif 2592 ri->ri_ops.putchar = radeonfb_putchar; 2593 } else { 2594 /* got an alpha font */ 2595 switch(ri->ri_depth) { 2596 case 32: 2597 ri->ri_ops.putchar = radeonfb_putchar_aa32; 2598 break; 2599 case 8: 2600 ri->ri_ops.putchar = radeonfb_putchar_aa8; 2601 break; 2602 default: 2603 /* XXX this should never happen */ 2604 panic("%s: depth is not 8 or 32 but we got an" \ 2605 " alpha font?!", __func__); 2606 } 2607 } 2608 ri->ri_ops.cursor = radeonfb_cursor; 2609 } 2610 2611 void 2612 radeonfb_set_fbloc(struct radeonfb_softc *sc) 2613 { 2614 uint32_t gen, ext, gen2 = 0; 2615 uint32_t agploc, aperbase, apersize, mcfbloc; 2616 2617 gen = GET32(sc, RADEON_CRTC_GEN_CNTL); 2618 /* XXX */ 2619 ext = GET32(sc, RADEON_CRTC_EXT_CNTL) & ~RADEON_CRTC_DISPLAY_DIS; 2620 agploc = GET32(sc, RADEON_MC_AGP_LOCATION); 2621 aperbase = GET32(sc, RADEON_CONFIG_APER_0_BASE); 2622 apersize = GET32(sc, RADEON_CONFIG_APER_SIZE); 2623 2624 PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISP_REQ_EN_B); 2625 PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISPLAY_DIS); 2626 #if 0 2627 PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISPLAY_DIS); 2628 PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISP_REQ_EN_B); 2629 #endif 2630 2631 if (HAS_CRTC2(sc)) { 2632 gen2 = GET32(sc, RADEON_CRTC2_GEN_CNTL); 2633 PUT32(sc, RADEON_CRTC2_GEN_CNTL, 2634 gen2 | RADEON_CRTC2_DISP_REQ_EN_B); 2635 } 2636 2637 delay(100000); 2638 2639 mcfbloc = (aperbase >> 16) | 2640 ((aperbase + (apersize - 1)) & 0xffff0000); 2641 2642 sc->sc_aperbase = (mcfbloc & 0xffff) << 16; 2643 sc->sc_memsz = apersize; 2644 2645 if (((agploc & 0xffff) << 16) != 2646 ((mcfbloc & 0xffff0000U) + 0x10000)) { 2647 agploc = mcfbloc & 0xffff0000U; 2648 agploc |= ((agploc + 0x10000) >> 16); 2649 } 2650 2651 PUT32(sc, RADEON_HOST_PATH_CNTL, 0); 2652 2653 PUT32(sc, RADEON_MC_FB_LOCATION, mcfbloc); 2654 PUT32(sc, RADEON_MC_AGP_LOCATION, agploc); 2655 2656 DPRINTF(("aperbase = %u\n", aperbase)); 2657 PRINTREG(RADEON_MC_FB_LOCATION); 2658 PRINTREG(RADEON_MC_AGP_LOCATION); 2659 2660 PUT32(sc, RADEON_DISPLAY_BASE_ADDR, sc->sc_aperbase); 2661 2662 if (HAS_CRTC2(sc)) 2663 PUT32(sc, RADEON_DISPLAY2_BASE_ADDR, sc->sc_aperbase); 2664 2665 PUT32(sc, RADEON_OV0_BASE_ADDR, sc->sc_aperbase); 2666 2667 #if 0 2668 /* XXX: what is this AGP garbage? :-) */ 2669 PUT32(sc, RADEON_AGP_CNTL, 0x00100000); 2670 #endif 2671 2672 delay(100000); 2673 2674 PUT32(sc, RADEON_CRTC_GEN_CNTL, gen); 2675 PUT32(sc, RADEON_CRTC_EXT_CNTL, ext); 2676 2677 if (HAS_CRTC2(sc)) 2678 PUT32(sc, RADEON_CRTC2_GEN_CNTL, gen2); 2679 } 2680 2681 void 2682 radeonfb_init_misc(struct radeonfb_softc *sc) 2683 { 2684 PUT32(sc, RADEON_BUS_CNTL, 2685 RADEON_BUS_MASTER_DIS | 2686 RADEON_BUS_PREFETCH_MODE_ACT | 2687 RADEON_BUS_PCI_READ_RETRY_EN | 2688 RADEON_BUS_PCI_WRT_RETRY_EN | 2689 (3 << RADEON_BUS_RETRY_WS_SHIFT) | 2690 RADEON_BUS_MSTR_RD_MULT | 2691 RADEON_BUS_MSTR_RD_LINE | 2692 RADEON_BUS_RD_DISCARD_EN | 2693 RADEON_BUS_MSTR_DISCONNECT_EN | 2694 RADEON_BUS_READ_BURST); 2695 2696 PUT32(sc, RADEON_BUS_CNTL1, 0xf0); 2697 /* PUT32(sc, RADEON_SEPROM_CNTL1, 0x09ff0000); */ 2698 PUT32(sc, RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); 2699 PUT32(sc, RADEON_RBBM_CNTL, 2700 (3 << RADEON_RB_SETTLE_SHIFT) | 2701 (4 << RADEON_ABORTCLKS_HI_SHIFT) | 2702 (4 << RADEON_ABORTCLKS_CP_SHIFT) | 2703 (4 << RADEON_ABORTCLKS_CFIFO_SHIFT)); 2704 2705 /* XXX: figure out what these mean! */ 2706 PUT32(sc, RADEON_AGP_CNTL, 0x00100000); 2707 PUT32(sc, RADEON_HOST_PATH_CNTL, 0); 2708 #if 0 2709 PUT32(sc, RADEON_DISP_MISC_CNTL, 0x5bb00400); 2710 #endif 2711 2712 PUT32(sc, RADEON_GEN_INT_CNTL, 0); 2713 PUT32(sc, RADEON_GEN_INT_STATUS, GET32(sc, RADEON_GEN_INT_STATUS)); 2714 } 2715 2716 static void 2717 radeonfb_putpal(struct radeonfb_display *dp, int idx, int r, int g, int b) 2718 { 2719 struct radeonfb_softc *sc = dp->rd_softc; 2720 int crtc, cc; 2721 uint32_t vclk; 2722 2723 vclk = GETPLL(sc, RADEON_VCLK_ECP_CNTL); 2724 PUTPLL(sc, RADEON_VCLK_ECP_CNTL, vclk & ~RADEON_PIXCLK_DAC_ALWAYS_ONb); 2725 2726 /* initialize the palette for every CRTC used by this display */ 2727 for (cc = 0; cc < dp->rd_ncrtcs; cc++) { 2728 crtc = dp->rd_crtcs[cc].rc_number; 2729 2730 if (crtc) 2731 SET32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL); 2732 else 2733 CLR32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL); 2734 2735 PUT32(sc, RADEON_PALETTE_INDEX, idx); 2736 PUT32(sc, RADEON_PALETTE_30_DATA, 2737 (r << 22) | (g << 12) | (b << 2)); 2738 } 2739 2740 PUTPLL(sc, RADEON_VCLK_ECP_CNTL, vclk); 2741 } 2742 2743 /* 2744 * This loads a linear color map for true color. 2745 */ 2746 void 2747 radeonfb_init_palette(struct radeonfb_display *dp) 2748 { 2749 int i; 2750 2751 #define DAC_WIDTH ((1 << 10) - 1) 2752 #define CLUT_WIDTH ((1 << 8) - 1) 2753 #define CLUT_COLOR(i) ((i * DAC_WIDTH * 2 / CLUT_WIDTH + 1) / 2) 2754 2755 if (dp->rd_bpp == 8) { 2756 2757 /* R3G3B2 palette */ 2758 uint32_t tmp, r, g, b; 2759 2760 for (i = 0; i <= CLUT_WIDTH; ++i) { 2761 tmp = i & 0xe0; 2762 2763 /* 2764 * replicate bits so 0xe0 maps to a red value of 0xff 2765 * in order to make white look actually white 2766 */ 2767 tmp |= (tmp >> 3) | (tmp >> 6); 2768 r = tmp; 2769 2770 tmp = (i & 0x1c) << 3; 2771 tmp |= (tmp >> 3) | (tmp >> 6); 2772 g = tmp; 2773 2774 tmp = (i & 0x03) << 6; 2775 tmp |= tmp >> 2; 2776 tmp |= tmp >> 4; 2777 b = tmp; 2778 2779 radeonfb_putpal(dp, i, r, g, b); 2780 } 2781 } else { 2782 /* linear ramp */ 2783 for (i = 0; i <= CLUT_WIDTH; ++i) { 2784 radeonfb_putpal(dp, i, i, i, i); 2785 } 2786 } 2787 } 2788 2789 static int 2790 radeonfb_putcmap(struct radeonfb_display *dp, struct wsdisplay_cmap *cm) 2791 { 2792 u_char *r, *g, *b; 2793 u_int index = cm->index; 2794 u_int count = cm->count; 2795 int i, error; 2796 u_char rbuf[256], gbuf[256], bbuf[256]; 2797 2798 #ifdef GENFB_DEBUG 2799 aprint_debug("putcmap: %d %d\n",index, count); 2800 #endif 2801 if (index >= 256 || count > 256 - index) 2802 return EINVAL; 2803 error = copyin(cm->red, &rbuf[index], count); 2804 if (error) 2805 return error; 2806 error = copyin(cm->green, &gbuf[index], count); 2807 if (error) 2808 return error; 2809 error = copyin(cm->blue, &bbuf[index], count); 2810 if (error) 2811 return error; 2812 2813 memcpy(&dp->rd_cmap_red[index], &rbuf[index], count); 2814 memcpy(&dp->rd_cmap_green[index], &gbuf[index], count); 2815 memcpy(&dp->rd_cmap_blue[index], &bbuf[index], count); 2816 2817 r = &dp->rd_cmap_red[index]; 2818 g = &dp->rd_cmap_green[index]; 2819 b = &dp->rd_cmap_blue[index]; 2820 2821 for (i = 0; i < count; i++) { 2822 radeonfb_putpal(dp, index, *r, *g, *b); 2823 index++; 2824 r++, g++, b++; 2825 } 2826 return 0; 2827 } 2828 2829 static int 2830 radeonfb_getcmap(struct radeonfb_display *dp, struct wsdisplay_cmap *cm) 2831 { 2832 u_int index = cm->index; 2833 u_int count = cm->count; 2834 int error; 2835 2836 if (index >= 256 || count > 256 - index) 2837 return EINVAL; 2838 2839 error = copyout(&dp->rd_cmap_red[index], cm->red, count); 2840 if (error) 2841 return error; 2842 error = copyout(&dp->rd_cmap_green[index], cm->green, count); 2843 if (error) 2844 return error; 2845 error = copyout(&dp->rd_cmap_blue[index], cm->blue, count); 2846 if (error) 2847 return error; 2848 2849 return 0; 2850 } 2851 2852 /* 2853 * Bugs in some R300 hardware requires this when accessing CLOCK_CNTL_INDEX. 2854 */ 2855 void 2856 radeonfb_r300cg_workaround(struct radeonfb_softc *sc) 2857 { 2858 uint32_t tmp, save; 2859 2860 save = GET32(sc, RADEON_CLOCK_CNTL_INDEX); 2861 tmp = save & ~(0x3f | RADEON_PLL_WR_EN); 2862 PUT32(sc, RADEON_CLOCK_CNTL_INDEX, tmp); 2863 tmp = GET32(sc, RADEON_CLOCK_CNTL_DATA); 2864 PUT32(sc, RADEON_CLOCK_CNTL_INDEX, save); 2865 } 2866 2867 /* 2868 * Acceleration entry points. 2869 */ 2870 2871 /* this one draws characters using bitmap fonts */ 2872 static void 2873 radeonfb_putchar(void *cookie, int row, int col, u_int c, long attr) 2874 { 2875 struct rasops_info *ri = cookie; 2876 struct vcons_screen *scr = ri->ri_hw; 2877 struct radeonfb_display *dp = scr->scr_cookie; 2878 struct radeonfb_softc *sc = dp->rd_softc; 2879 struct wsdisplay_font *font = PICK_FONT(ri, c); 2880 uint32_t w, h; 2881 int xd, yd, offset, i; 2882 uint32_t bg, fg, gmc; 2883 uint32_t reg; 2884 uint8_t *data8; 2885 uint16_t *data16; 2886 void *data; 2887 2888 if (dp->rd_wsmode != WSDISPLAYIO_MODE_EMUL) 2889 return; 2890 2891 if (!CHAR_IN_FONT(c, font)) 2892 return; 2893 2894 w = font->fontwidth; 2895 h = font->fontheight; 2896 2897 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 2898 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 2899 2900 xd = ri->ri_xorigin + col * w; 2901 yd = ri->ri_yorigin + row * h; 2902 2903 if (c == 0x20) { 2904 radeonfb_rectfill(dp, xd, yd, w, h, bg); 2905 return; 2906 } 2907 data = WSFONT_GLYPH(c, font); 2908 2909 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 2910 2911 radeonfb_wait_fifo(sc, 9); 2912 2913 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 2914 RADEON_GMC_BRUSH_NONE | 2915 RADEON_GMC_SRC_DATATYPE_MONO_FG_BG | 2916 RADEON_GMC_DST_CLIPPING | 2917 RADEON_ROP3_S | 2918 RADEON_DP_SRC_SOURCE_HOST_DATA | 2919 RADEON_GMC_CLR_CMP_CNTL_DIS | 2920 RADEON_GMC_WR_MSK_DIS | 2921 gmc); 2922 2923 PUT32(sc, RADEON_SC_LEFT, xd); 2924 PUT32(sc, RADEON_SC_RIGHT, xd + w); 2925 PUT32(sc, RADEON_DP_SRC_FRGD_CLR, fg); 2926 PUT32(sc, RADEON_DP_SRC_BKGD_CLR, bg); 2927 PUT32(sc, RADEON_DP_CNTL, 2928 RADEON_DST_X_LEFT_TO_RIGHT | 2929 RADEON_DST_Y_TOP_TO_BOTTOM); 2930 2931 PUT32(sc, RADEON_SRC_X_Y, 0); 2932 offset = 32 - (font->stride << 3); 2933 PUT32(sc, RADEON_DST_X_Y, ((xd - offset) << 16) | yd); 2934 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (32 << 16) | h); 2935 2936 radeonfb_wait_fifo(sc, h); 2937 switch (font->stride) { 2938 case 1: { 2939 data8 = data; 2940 for (i = 0; i < h; i++) { 2941 reg = *data8; 2942 #if BYTE_ORDER == LITTLE_ENDIAN 2943 reg = reg << 24; 2944 #endif 2945 bus_space_write_stream_4(sc->sc_regt, 2946 sc->sc_regh, RADEON_HOST_DATA0, reg); 2947 data8++; 2948 } 2949 break; 2950 } 2951 case 2: { 2952 data16 = data; 2953 for (i = 0; i < h; i++) { 2954 reg = *data16; 2955 #if BYTE_ORDER == LITTLE_ENDIAN 2956 reg = reg << 16; 2957 #endif 2958 bus_space_write_stream_4(sc->sc_regt, 2959 sc->sc_regh, RADEON_HOST_DATA0, reg); 2960 data16++; 2961 } 2962 break; 2963 } 2964 } 2965 if (attr & 1) 2966 radeonfb_rectfill(dp, xd, yd + h - 2, w, 1, fg); 2967 } 2968 2969 /* ... while this one is for anti-aliased ones */ 2970 static void 2971 radeonfb_putchar_aa32(void *cookie, int row, int col, u_int c, long attr) 2972 { 2973 struct rasops_info *ri = cookie; 2974 struct vcons_screen *scr = ri->ri_hw; 2975 struct radeonfb_display *dp = scr->scr_cookie; 2976 struct radeonfb_softc *sc = dp->rd_softc; 2977 struct wsdisplay_font *font = PICK_FONT(ri, c); 2978 uint32_t bg, fg, gmc; 2979 uint8_t *data; 2980 int w, h, xd, yd; 2981 int i, r, g, b, aval; 2982 int rf, gf, bf, rb, gb, bb; 2983 uint32_t pixel; 2984 int rv; 2985 2986 if (dp->rd_wsmode != WSDISPLAYIO_MODE_EMUL) 2987 return; 2988 2989 if (!CHAR_IN_FONT(c, font)) 2990 return; 2991 2992 w = font->fontwidth; 2993 h = font->fontheight; 2994 2995 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 2996 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 2997 2998 xd = ri->ri_xorigin + col * w; 2999 yd = ri->ri_yorigin + row * h; 3000 3001 if (c == 0x20) { 3002 radeonfb_rectfill(dp, xd, yd, w, h, bg); 3003 if (attr & 1) 3004 radeonfb_rectfill(dp, xd, yd + h - 2, w, 1, fg); 3005 return; 3006 } 3007 rv = glyphcache_try(&dp->rd_gc, c, xd, yd, attr); 3008 if (rv == GC_OK) 3009 return; 3010 3011 data = WSFONT_GLYPH(c, font); 3012 3013 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 3014 3015 radeonfb_wait_fifo(sc, 5); 3016 3017 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 3018 RADEON_GMC_BRUSH_NONE | 3019 RADEON_GMC_SRC_DATATYPE_COLOR | 3020 RADEON_ROP3_S | 3021 RADEON_DP_SRC_SOURCE_HOST_DATA | 3022 RADEON_GMC_CLR_CMP_CNTL_DIS | 3023 RADEON_GMC_WR_MSK_DIS | 3024 gmc); 3025 3026 PUT32(sc, RADEON_DP_CNTL, 3027 RADEON_DST_X_LEFT_TO_RIGHT | 3028 RADEON_DST_Y_TOP_TO_BOTTOM); 3029 3030 PUT32(sc, RADEON_SRC_X_Y, 0); 3031 PUT32(sc, RADEON_DST_X_Y, (xd << 16) | yd); 3032 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (w << 16) | h); 3033 3034 rf = (fg >> 16) & 0xff; 3035 rb = (bg >> 16) & 0xff; 3036 gf = (fg >> 8) & 0xff; 3037 gb = (bg >> 8) & 0xff; 3038 bf = fg & 0xff; 3039 bb = bg & 0xff; 3040 3041 /* 3042 * I doubt we can upload data faster than even the slowest Radeon 3043 * could process them, especially when doing the alpha blending stuff 3044 * along the way, so just make sure there's some room in the FIFO and 3045 * then hammer away 3046 * As it turns out we can, so make periodic stops to let the FIFO 3047 * drain. 3048 */ 3049 radeonfb_wait_fifo(sc, 20); 3050 for (i = 0; i < ri->ri_fontscale; i++) { 3051 aval = *data; 3052 data++; 3053 if (aval == 0) { 3054 pixel = bg; 3055 } else if (aval == 255) { 3056 pixel = fg; 3057 } else { 3058 r = aval * rf + (255 - aval) * rb; 3059 g = aval * gf + (255 - aval) * gb; 3060 b = aval * bf + (255 - aval) * bb; 3061 pixel = (r & 0xff00) << 8 | 3062 (g & 0xff00) | 3063 (b & 0xff00) >> 8; 3064 } 3065 if (i & 16) 3066 radeonfb_wait_fifo(sc, 20); 3067 PUT32(sc, RADEON_HOST_DATA0, pixel); 3068 } 3069 if (rv == GC_ADD) { 3070 glyphcache_add(&dp->rd_gc, c, xd, yd); 3071 } else if (attr & 1) 3072 radeonfb_rectfill(dp, xd, yd + h - 2, w, 1, fg); 3073 } 3074 3075 static void 3076 radeonfb_putchar_aa8(void *cookie, int row, int col, u_int c, long attr) 3077 { 3078 struct rasops_info *ri = cookie; 3079 struct vcons_screen *scr = ri->ri_hw; 3080 struct radeonfb_display *dp = scr->scr_cookie; 3081 struct radeonfb_softc *sc = dp->rd_softc; 3082 struct wsdisplay_font *font = PICK_FONT(ri, c); 3083 uint32_t bg, fg, latch = 0, bg8, fg8, pixel, gmc; 3084 int i, x, y, wi, he, r, g, b, aval; 3085 int r1, g1, b1, r0, g0, b0, fgo, bgo; 3086 uint8_t *data8; 3087 int rv, cnt; 3088 3089 if (dp->rd_wsmode != WSDISPLAYIO_MODE_EMUL) 3090 return; 3091 3092 if (!CHAR_IN_FONT(c, font)) 3093 return; 3094 3095 wi = font->fontwidth; 3096 he = font->fontheight; 3097 3098 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 3099 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 3100 3101 x = ri->ri_xorigin + col * wi; 3102 y = ri->ri_yorigin + row * he; 3103 3104 if (c == 0x20) { 3105 radeonfb_rectfill(dp, x, y, wi, he, bg); 3106 if (attr & 1) 3107 radeonfb_rectfill(dp, x, y + he - 2, wi, 1, fg); 3108 return; 3109 } 3110 rv = glyphcache_try(&dp->rd_gc, c, x, y, attr); 3111 if (rv == GC_OK) 3112 return; 3113 3114 data8 = WSFONT_GLYPH(c, font); 3115 3116 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 3117 3118 radeonfb_wait_fifo(sc, 5); 3119 3120 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 3121 RADEON_GMC_BRUSH_NONE | 3122 RADEON_GMC_SRC_DATATYPE_COLOR | 3123 RADEON_ROP3_S | 3124 RADEON_DP_SRC_SOURCE_HOST_DATA | 3125 RADEON_GMC_CLR_CMP_CNTL_DIS | 3126 RADEON_GMC_WR_MSK_DIS | 3127 gmc); 3128 3129 PUT32(sc, RADEON_DP_CNTL, 3130 RADEON_DST_X_LEFT_TO_RIGHT | 3131 RADEON_DST_Y_TOP_TO_BOTTOM); 3132 3133 PUT32(sc, RADEON_SRC_X_Y, 0); 3134 PUT32(sc, RADEON_DST_X_Y, (x << 16) | y); 3135 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (wi << 16) | he); 3136 3137 /* 3138 * we need the RGB colours here, so get offsets into rasops_cmap 3139 */ 3140 fgo = ((attr >> 24) & 0xf) * 3; 3141 bgo = ((attr >> 16) & 0xf) * 3; 3142 3143 r0 = rasops_cmap[bgo]; 3144 r1 = rasops_cmap[fgo]; 3145 g0 = rasops_cmap[bgo + 1]; 3146 g1 = rasops_cmap[fgo + 1]; 3147 b0 = rasops_cmap[bgo + 2]; 3148 b1 = rasops_cmap[fgo + 2]; 3149 #define R3G3B2(r, g, b) ((r & 0xe0) | ((g >> 3) & 0x1c) | (b >> 6)) 3150 bg8 = R3G3B2(r0, g0, b0); 3151 fg8 = R3G3B2(r1, g1, b1); 3152 3153 radeonfb_wait_fifo(sc, 20); 3154 cnt = 0; 3155 for (i = 0; i < ri->ri_fontscale; i++) { 3156 aval = *data8; 3157 if (aval == 0) { 3158 pixel = bg8; 3159 } else if (aval == 255) { 3160 pixel = fg8; 3161 } else { 3162 r = aval * r1 + (255 - aval) * r0; 3163 g = aval * g1 + (255 - aval) * g0; 3164 b = aval * b1 + (255 - aval) * b0; 3165 pixel = ((r & 0xe000) >> 8) | 3166 ((g & 0xe000) >> 11) | 3167 ((b & 0xc000) >> 14); 3168 } 3169 latch |= pixel << (8 * (i & 3)); 3170 /* write in 32bit chunks */ 3171 if ((i & 3) == 3) { 3172 PUT32(sc, RADEON_HOST_DATA0, latch); 3173 /* 3174 * not strictly necessary, old data should be shifted 3175 * out 3176 */ 3177 latch = 0; 3178 cnt++; 3179 if (cnt > 16) { 3180 cnt = 0; 3181 radeonfb_wait_fifo(sc, 20); 3182 } 3183 } 3184 data8++; 3185 } 3186 /* if we have pixels left in latch write them out */ 3187 if ((i & 3) != 0) { 3188 /* 3189 * radeon is weird - apparently leftover pixels are written 3190 * from the middle, not from the left as everything else 3191 */ 3192 PUT32(sc, RADEON_HOST_DATA0, latch); 3193 } 3194 3195 if (rv == GC_ADD) { 3196 glyphcache_add(&dp->rd_gc, c, x, y); 3197 } else 3198 if (attr & 1) 3199 radeonfb_rectfill(dp, x, y + he - 2, wi, 1, fg); 3200 } 3201 3202 /* 3203 * wrapper for software character drawing 3204 * just sync the engine and call rasops*_putchar() 3205 */ 3206 3207 #ifndef RADEONFB_ALWAYS_ACCEL_PUTCHAR 3208 static void 3209 radeonfb_putchar_wrapper(void *cookie, int row, int col, u_int c, long attr) 3210 { 3211 struct rasops_info *ri = cookie; 3212 struct vcons_screen *scr = ri->ri_hw; 3213 struct radeonfb_display *dp = scr->scr_cookie; 3214 3215 radeonfb_engine_idle(dp->rd_softc); 3216 dp->rd_putchar(ri, row, col, c, attr); 3217 } 3218 #endif 3219 3220 static void 3221 radeonfb_eraserows(void *cookie, int row, int nrows, long fillattr) 3222 { 3223 struct rasops_info *ri = cookie; 3224 struct vcons_screen *scr = ri->ri_hw; 3225 struct radeonfb_display *dp = scr->scr_cookie; 3226 uint32_t x, y, w, h, fg, bg, ul; 3227 3228 /* XXX: check for full emulation mode? */ 3229 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 3230 x = ri->ri_xorigin; 3231 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 3232 w = ri->ri_emuwidth; 3233 h = ri->ri_font->fontheight * nrows; 3234 3235 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 3236 radeonfb_rectfill(dp, x, y, w, h, ri->ri_devcmap[bg & 0xf]); 3237 } 3238 } 3239 3240 static void 3241 radeonfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 3242 { 3243 struct rasops_info *ri = cookie; 3244 struct vcons_screen *scr = ri->ri_hw; 3245 struct radeonfb_display *dp = scr->scr_cookie; 3246 uint32_t x, ys, yd, w, h; 3247 3248 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 3249 x = ri->ri_xorigin; 3250 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 3251 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 3252 w = ri->ri_emuwidth; 3253 h = ri->ri_font->fontheight * nrows; 3254 radeonfb_bitblt(dp, x, ys, x, yd, w, h, 3255 RADEON_ROP3_S); 3256 } 3257 } 3258 3259 static void 3260 radeonfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 3261 { 3262 struct rasops_info *ri = cookie; 3263 struct vcons_screen *scr = ri->ri_hw; 3264 struct radeonfb_display *dp = scr->scr_cookie; 3265 uint32_t xs, xd, y, w, h; 3266 3267 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 3268 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 3269 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 3270 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 3271 w = ri->ri_font->fontwidth * ncols; 3272 h = ri->ri_font->fontheight; 3273 radeonfb_bitblt(dp, xs, y, xd, y, w, h, 3274 RADEON_ROP3_S); 3275 } 3276 } 3277 3278 static void 3279 radeonfb_erasecols(void *cookie, int row, int startcol, int ncols, 3280 long fillattr) 3281 { 3282 struct rasops_info *ri = cookie; 3283 struct vcons_screen *scr = ri->ri_hw; 3284 struct radeonfb_display *dp = scr->scr_cookie; 3285 uint32_t x, y, w, h, fg, bg, ul; 3286 3287 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 3288 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 3289 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 3290 w = ri->ri_font->fontwidth * ncols; 3291 h = ri->ri_font->fontheight; 3292 3293 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 3294 radeonfb_rectfill(dp, x, y, w, h, ri->ri_devcmap[bg & 0xf]); 3295 } 3296 } 3297 3298 static void 3299 radeonfb_cursor(void *cookie, int on, int row, int col) 3300 { 3301 struct rasops_info *ri = cookie; 3302 struct vcons_screen *scr = ri->ri_hw; 3303 struct radeonfb_display *dp = scr->scr_cookie; 3304 int x, y, wi, he; 3305 3306 wi = ri->ri_font->fontwidth; 3307 he = ri->ri_font->fontheight; 3308 3309 if (dp->rd_wsmode == WSDISPLAYIO_MODE_EMUL) { 3310 x = ri->ri_ccol * wi + ri->ri_xorigin; 3311 y = ri->ri_crow * he + ri->ri_yorigin; 3312 /* first turn off the old cursor */ 3313 if (ri->ri_flg & RI_CURSOR) { 3314 radeonfb_bitblt(dp, x, y, x, y, wi, he, 3315 RADEON_ROP3_Dn); 3316 ri->ri_flg &= ~RI_CURSOR; 3317 } 3318 ri->ri_crow = row; 3319 ri->ri_ccol = col; 3320 /* then (possibly) turn on the new one */ 3321 if (on) { 3322 x = ri->ri_ccol * wi + ri->ri_xorigin; 3323 y = ri->ri_crow * he + ri->ri_yorigin; 3324 radeonfb_bitblt(dp, x, y, x, y, wi, he, 3325 RADEON_ROP3_Dn); 3326 ri->ri_flg |= RI_CURSOR; 3327 } 3328 } else { 3329 scr->scr_ri.ri_crow = row; 3330 scr->scr_ri.ri_ccol = col; 3331 scr->scr_ri.ri_flg &= ~RI_CURSOR; 3332 } 3333 } 3334 3335 /* 3336 * Underlying acceleration support. 3337 */ 3338 3339 static void 3340 radeonfb_rectfill(struct radeonfb_display *dp, int dstx, int dsty, 3341 int width, int height, uint32_t color) 3342 { 3343 struct radeonfb_softc *sc = dp->rd_softc; 3344 uint32_t gmc; 3345 3346 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 3347 3348 radeonfb_wait_fifo(sc, 6); 3349 3350 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 3351 RADEON_GMC_BRUSH_SOLID_COLOR | 3352 RADEON_GMC_SRC_DATATYPE_COLOR | 3353 RADEON_GMC_CLR_CMP_CNTL_DIS | 3354 RADEON_ROP3_P | gmc); 3355 3356 PUT32(sc, RADEON_DP_BRUSH_FRGD_CLR, color); 3357 PUT32(sc, RADEON_DP_WRITE_MASK, 0xffffffff); 3358 PUT32(sc, RADEON_DP_CNTL, 3359 RADEON_DST_X_LEFT_TO_RIGHT | 3360 RADEON_DST_Y_TOP_TO_BOTTOM); 3361 PUT32(sc, RADEON_DST_Y_X, (dsty << 16) | dstx); 3362 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (width << 16) | (height)); 3363 } 3364 3365 static void 3366 radeonfb_rectfill_a(void *cookie, int dstx, int dsty, 3367 int width, int height, long attr) 3368 { 3369 struct radeonfb_display *dp = cookie; 3370 3371 radeonfb_rectfill(dp, dstx, dsty, width, height, 3372 dp->rd_vscreen.scr_ri.ri_devcmap[(attr >> 24 & 0xf)]); 3373 } 3374 3375 static void 3376 radeonfb_bitblt(void *cookie, int srcx, int srcy, 3377 int dstx, int dsty, int width, int height, int rop) 3378 { 3379 struct radeonfb_display *dp = cookie; 3380 struct radeonfb_softc *sc = dp->rd_softc; 3381 uint32_t gmc; 3382 uint32_t dir; 3383 3384 if (dsty < srcy) { 3385 dir = RADEON_DST_Y_TOP_TO_BOTTOM; 3386 } else { 3387 srcy += height - 1; 3388 dsty += height - 1; 3389 dir = 0; 3390 } 3391 if (dstx < srcx) { 3392 dir |= RADEON_DST_X_LEFT_TO_RIGHT; 3393 } else { 3394 srcx += width - 1; 3395 dstx += width - 1; 3396 } 3397 3398 gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT; 3399 3400 radeonfb_wait_fifo(sc, 6); 3401 3402 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 3403 RADEON_GMC_BRUSH_SOLID_COLOR | 3404 RADEON_GMC_SRC_DATATYPE_COLOR | 3405 RADEON_GMC_CLR_CMP_CNTL_DIS | 3406 RADEON_DP_SRC_SOURCE_MEMORY | 3407 rop | gmc); 3408 3409 PUT32(sc, RADEON_DP_WRITE_MASK, 0xffffffff); 3410 PUT32(sc, RADEON_DP_CNTL, dir); 3411 PUT32(sc, RADEON_SRC_Y_X, (srcy << 16) | srcx); 3412 PUT32(sc, RADEON_DST_Y_X, (dsty << 16) | dstx); 3413 PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (width << 16) | (height)); 3414 } 3415 3416 static void 3417 radeonfb_engine_idle(struct radeonfb_softc *sc) 3418 { 3419 3420 radeonfb_wait_fifo(sc, 64); 3421 while ((GET32(sc, RADEON_RBBM_STATUS) & 3422 RADEON_RBBM_ACTIVE) != 0); 3423 radeonfb_engine_flush(sc); 3424 } 3425 3426 static inline void 3427 radeonfb_wait_fifo(struct radeonfb_softc *sc, int n) 3428 { 3429 int i; 3430 3431 for (i = RADEON_TIMEOUT; i; i--) { 3432 if ((GET32(sc, RADEON_RBBM_STATUS) & 3433 RADEON_RBBM_FIFOCNT_MASK) >= n) 3434 return; 3435 } 3436 #ifdef DIAGNOSTIC 3437 if (!i) 3438 printf("%s: timed out waiting for fifo (%x)\n", 3439 XNAME(sc), GET32(sc, RADEON_RBBM_STATUS)); 3440 #endif 3441 } 3442 3443 static void 3444 radeonfb_engine_flush(struct radeonfb_softc *sc) 3445 { 3446 int i = 0; 3447 3448 if (IS_R300(sc)) { 3449 SET32(sc, R300_DSTCACHE_CTLSTAT, R300_RB2D_DC_FLUSH_ALL); 3450 while (GET32(sc, R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY) { 3451 i++; 3452 } 3453 } else { 3454 SET32(sc, RADEON_RB2D_DSTCACHE_CTLSTAT, 3455 RADEON_RB2D_DC_FLUSH_ALL); 3456 while (GET32(sc, RADEON_RB2D_DSTCACHE_CTLSTAT) & 3457 RADEON_RB2D_DC_BUSY) { 3458 i++; 3459 } 3460 } 3461 #ifdef DIAGNOSTIC 3462 if (i > RADEON_TIMEOUT) 3463 printf("%s: engine flush timed out!\n", XNAME(sc)); 3464 #endif 3465 } 3466 3467 static inline void 3468 radeonfb_unclip(struct radeonfb_softc *sc) 3469 { 3470 3471 radeonfb_wait_fifo(sc, 2); 3472 PUT32(sc, RADEON_SC_TOP_LEFT, 0); 3473 PUT32(sc, RADEON_SC_BOTTOM_RIGHT, 0x1fff1fff); 3474 } 3475 3476 static void 3477 radeonfb_engine_init(struct radeonfb_display *dp) 3478 { 3479 struct radeonfb_softc *sc = dp->rd_softc; 3480 uint32_t pitch; 3481 3482 /* no 3D */ 3483 PUT32(sc, RADEON_RB3D_CNTL, 0); 3484 3485 radeonfb_engine_reset(sc); 3486 pitch = ((dp->rd_virtx * (dp->rd_bpp / 8) + 0x3f)) >> 6; 3487 3488 radeonfb_wait_fifo(sc, 1); 3489 if (!IS_R300(sc)) 3490 PUT32(sc, RADEON_RB2D_DSTCACHE_MODE, 0); 3491 3492 radeonfb_wait_fifo(sc, 3); 3493 PUT32(sc, RADEON_DEFAULT_PITCH_OFFSET, 3494 (pitch << 22) | (sc->sc_aperbase >> 10)); 3495 3496 3497 PUT32(sc, RADEON_DST_PITCH_OFFSET, 3498 (pitch << 22) | (sc->sc_aperbase >> 10)); 3499 PUT32(sc, RADEON_SRC_PITCH_OFFSET, 3500 (pitch << 22) | (sc->sc_aperbase >> 10)); 3501 3502 (void)GET32(sc, RADEON_DP_DATATYPE); 3503 3504 /* default scissors -- no clipping */ 3505 radeonfb_wait_fifo(sc, 1); 3506 PUT32(sc, RADEON_DEFAULT_SC_BOTTOM_RIGHT, 3507 RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX); 3508 3509 radeonfb_wait_fifo(sc, 1); 3510 PUT32(sc, RADEON_DP_GUI_MASTER_CNTL, 3511 (dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT) | 3512 RADEON_GMC_CLR_CMP_CNTL_DIS | 3513 RADEON_GMC_BRUSH_SOLID_COLOR | 3514 RADEON_GMC_SRC_DATATYPE_COLOR); 3515 3516 radeonfb_wait_fifo(sc, 10); 3517 PUT32(sc, RADEON_DST_LINE_START, 0); 3518 PUT32(sc, RADEON_DST_LINE_END, 0); 3519 PUT32(sc, RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); 3520 PUT32(sc, RADEON_DP_BRUSH_BKGD_CLR, 0); 3521 PUT32(sc, RADEON_DP_SRC_FRGD_CLR, 0xffffffff); 3522 PUT32(sc, RADEON_DP_SRC_BKGD_CLR, 0); 3523 PUT32(sc, RADEON_DP_WRITE_MASK, 0xffffffff); 3524 PUT32(sc, RADEON_SC_TOP_LEFT, 0); 3525 PUT32(sc, RADEON_SC_BOTTOM_RIGHT, 0x1fff1fff); 3526 PUT32(sc, RADEON_AUX_SC_CNTL, 0); 3527 radeonfb_engine_idle(sc); 3528 } 3529 3530 static void 3531 radeonfb_engine_reset(struct radeonfb_softc *sc) 3532 { 3533 uint32_t hpc, rbbm, mclkcntl, clkindex; 3534 3535 radeonfb_engine_flush(sc); 3536 3537 clkindex = GET32(sc, RADEON_CLOCK_CNTL_INDEX); 3538 if (HAS_R300CG(sc)) 3539 radeonfb_r300cg_workaround(sc); 3540 mclkcntl = GETPLL(sc, RADEON_MCLK_CNTL); 3541 3542 /* 3543 * According to comments in XFree code, resetting the HDP via 3544 * the RBBM_SOFT_RESET can cause bad behavior on some systems. 3545 * So we use HOST_PATH_CNTL instead. 3546 */ 3547 3548 hpc = GET32(sc, RADEON_HOST_PATH_CNTL); 3549 rbbm = GET32(sc, RADEON_RBBM_SOFT_RESET); 3550 if (IS_R300(sc)) { 3551 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm | 3552 RADEON_SOFT_RESET_CP | 3553 RADEON_SOFT_RESET_HI | 3554 RADEON_SOFT_RESET_E2); 3555 GET32(sc, RADEON_RBBM_SOFT_RESET); 3556 PUT32(sc, RADEON_RBBM_SOFT_RESET, 0); 3557 /* 3558 * XXX: this bit is not defined in any ATI docs I have, 3559 * nor in the XFree code, but XFree does it. Why? 3560 */ 3561 SET32(sc, RADEON_RB2D_DSTCACHE_MODE, (1<<17)); 3562 } else { 3563 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm | 3564 RADEON_SOFT_RESET_CP | 3565 RADEON_SOFT_RESET_SE | 3566 RADEON_SOFT_RESET_RE | 3567 RADEON_SOFT_RESET_PP | 3568 RADEON_SOFT_RESET_E2 | 3569 RADEON_SOFT_RESET_RB); 3570 GET32(sc, RADEON_RBBM_SOFT_RESET); 3571 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm & 3572 ~(RADEON_SOFT_RESET_CP | 3573 RADEON_SOFT_RESET_SE | 3574 RADEON_SOFT_RESET_RE | 3575 RADEON_SOFT_RESET_PP | 3576 RADEON_SOFT_RESET_E2 | 3577 RADEON_SOFT_RESET_RB)); 3578 GET32(sc, RADEON_RBBM_SOFT_RESET); 3579 } 3580 3581 PUT32(sc, RADEON_HOST_PATH_CNTL, hpc | RADEON_HDP_SOFT_RESET); 3582 GET32(sc, RADEON_HOST_PATH_CNTL); 3583 PUT32(sc, RADEON_HOST_PATH_CNTL, hpc); 3584 3585 if (IS_R300(sc)) 3586 PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm); 3587 3588 PUT32(sc, RADEON_CLOCK_CNTL_INDEX, clkindex); 3589 PRINTREG(RADEON_CLOCK_CNTL_INDEX); 3590 PUTPLL(sc, RADEON_MCLK_CNTL, mclkcntl); 3591 3592 if (HAS_R300CG(sc)) 3593 radeonfb_r300cg_workaround(sc); 3594 } 3595 3596 static int 3597 radeonfb_set_curpos(struct radeonfb_display *dp, struct wsdisplay_curpos *pos) 3598 { 3599 int x, y; 3600 3601 x = pos->x; 3602 y = pos->y; 3603 3604 /* 3605 * This doesn't let a cursor move off the screen. I'm not 3606 * sure if this will have negative effects for e.g. Xinerama. 3607 * I'd guess Xinerama handles it by changing the cursor shape, 3608 * but that needs verification. 3609 */ 3610 if (x >= dp->rd_virtx) 3611 x = dp->rd_virtx - 1; 3612 if (x < 0) 3613 x = 0; 3614 if (y >= dp->rd_virty) 3615 y = dp->rd_virty - 1; 3616 if (y < 0) 3617 y = 0; 3618 3619 dp->rd_cursor.rc_pos.x = x; 3620 dp->rd_cursor.rc_pos.y = y; 3621 3622 radeonfb_cursor_position(dp); 3623 return 0; 3624 } 3625 3626 static int 3627 radeonfb_set_cursor(struct radeonfb_display *dp, struct wsdisplay_cursor *wc) 3628 { 3629 unsigned flags; 3630 3631 uint8_t r[2], g[2], b[2]; 3632 unsigned index, count; 3633 int i, err; 3634 int pitch, size; 3635 struct radeonfb_cursor nc; 3636 3637 flags = wc->which; 3638 3639 /* copy old values */ 3640 nc = dp->rd_cursor; 3641 3642 if (flags & WSDISPLAY_CURSOR_DOCMAP) { 3643 index = wc->cmap.index; 3644 count = wc->cmap.count; 3645 3646 if (index >= 2 || count > 2 - index) 3647 return EINVAL; 3648 3649 err = copyin(wc->cmap.red, &r[index], count); 3650 if (err) 3651 return err; 3652 err = copyin(wc->cmap.green, &g[index], count); 3653 if (err) 3654 return err; 3655 err = copyin(wc->cmap.blue, &b[index], count); 3656 if (err) 3657 return err; 3658 3659 for (i = index; i < index + count; i++) { 3660 nc.rc_cmap[i] = 3661 (r[i] << 16) + (g[i] << 8) + (b[i] << 0); 3662 } 3663 } 3664 3665 if (flags & WSDISPLAY_CURSOR_DOSHAPE) { 3666 if ((wc->size.x > RADEON_CURSORMAXX) || 3667 (wc->size.y > RADEON_CURSORMAXY)) 3668 return EINVAL; 3669 3670 /* figure bytes per line */ 3671 pitch = (wc->size.x + 7) / 8; 3672 size = pitch * wc->size.y; 3673 3674 /* clear the old cursor and mask */ 3675 memset(nc.rc_image, 0, 512); 3676 memset(nc.rc_mask, 0, 512); 3677 3678 nc.rc_size = wc->size; 3679 3680 if ((err = copyin(wc->image, nc.rc_image, size)) != 0) 3681 return err; 3682 3683 if ((err = copyin(wc->mask, nc.rc_mask, size)) != 0) 3684 return err; 3685 } 3686 3687 if (flags & WSDISPLAY_CURSOR_DOHOT) { 3688 nc.rc_hot = wc->hot; 3689 if (nc.rc_hot.x >= nc.rc_size.x) 3690 nc.rc_hot.x = nc.rc_size.x - 1; 3691 if (nc.rc_hot.y >= nc.rc_size.y) 3692 nc.rc_hot.y = nc.rc_size.y - 1; 3693 } 3694 3695 if (flags & WSDISPLAY_CURSOR_DOPOS) { 3696 nc.rc_pos = wc->pos; 3697 if (nc.rc_pos.x >= dp->rd_virtx) 3698 nc.rc_pos.x = dp->rd_virtx - 1; 3699 #if 0 3700 if (nc.rc_pos.x < 0) 3701 nc.rc_pos.x = 0; 3702 #endif 3703 if (nc.rc_pos.y >= dp->rd_virty) 3704 nc.rc_pos.y = dp->rd_virty - 1; 3705 #if 0 3706 if (nc.rc_pos.y < 0) 3707 nc.rc_pos.y = 0; 3708 #endif 3709 } 3710 if (flags & WSDISPLAY_CURSOR_DOCUR) { 3711 nc.rc_visible = wc->enable; 3712 } 3713 3714 dp->rd_cursor = nc; 3715 radeonfb_cursor_update(dp, wc->which); 3716 3717 return 0; 3718 } 3719 3720 static uint8_t 3721 radeonfb_backwards(uint8_t d) 3722 { 3723 uint8_t l; 3724 3725 l = d << 7; 3726 l |= ((d & 0x02) << 5); 3727 l |= ((d & 0x04) << 3); 3728 l |= ((d & 0x08) << 1); 3729 l |= ((d & 0x10) >> 1); 3730 l |= ((d & 0x20) >> 3); 3731 l |= ((d & 0x40) >> 5); 3732 l |= ((d & 0x80) >> 7); 3733 return l; 3734 } 3735 3736 /* 3737 * Change the cursor shape. Call this with the cursor locked to avoid 3738 * flickering/tearing. 3739 */ 3740 static void 3741 radeonfb_cursor_shape(struct radeonfb_display *dp) 3742 { 3743 uint8_t and[512], xor[512]; 3744 int i, j, src, dst /* , pitch */; 3745 const uint8_t *msk = dp->rd_cursor.rc_mask; 3746 const uint8_t *img = dp->rd_cursor.rc_image; 3747 3748 /* 3749 * Radeon cursor data interleaves one line of AND data followed 3750 * by a line of XOR data. (Each line corresponds to a whole hardware 3751 * pitch - i.e. 64 pixels or 8 bytes.) 3752 * 3753 * The cursor is displayed using the following table: 3754 * 3755 * AND XOR Result 3756 * ---------------------- 3757 * 0 0 Cursor color 0 3758 * 0 1 Cursor color 1 3759 * 1 0 Transparent 3760 * 1 1 Complement of background 3761 * 3762 * Our masks are therefore different from what we were passed. 3763 * Passed in, I'm assuming the data represents either color 0 or 1, 3764 * and a mask, so the passed in table looks like: 3765 * 3766 * IMG Mask Result 3767 * ----------------------- 3768 * 0 0 Transparent 3769 * 0 1 Cursor color 0 3770 * 1 0 Transparent 3771 * 1 1 Cursor color 1 3772 * 3773 * IF mask bit == 1, AND = 0, XOR = color. 3774 * IF mask bit == 0, AND = 1, XOR = 0. 3775 * 3776 * hence: AND = ~(mask); XOR = color & ~(mask); 3777 */ 3778 3779 /* pitch = ((dp->rd_cursor.rc_size.x + 7) / 8); */ 3780 3781 /* start by assuming all bits are transparent */ 3782 memset(and, 0xff, 512); 3783 memset(xor, 0x00, 512); 3784 3785 src = 0; 3786 dst = 0; 3787 for (i = 0; i < 64; i++) { 3788 for (j = 0; j < 64; j += 8) { 3789 if ((i < dp->rd_cursor.rc_size.y) && 3790 (j < dp->rd_cursor.rc_size.x)) { 3791 3792 /* take care to leave odd bits alone */ 3793 and[dst] &= ~(msk[src]); 3794 xor[dst] = img[src] & msk[src]; 3795 src++; 3796 } 3797 dst++; 3798 } 3799 } 3800 3801 for (i = 0; i < 512; i++) { 3802 and[i] = radeonfb_backwards(and[i]); 3803 xor[i] = radeonfb_backwards(xor[i]); 3804 } 3805 3806 /* copy the image into place */ 3807 for (i = 0; i < 64; i++) { 3808 memcpy((uint8_t *)dp->rd_curptr + (i * 16), 3809 &and[i * 8], 8); 3810 memcpy((uint8_t *)dp->rd_curptr + (i * 16) + 8, 3811 &xor[i * 8], 8); 3812 } 3813 } 3814 3815 static void 3816 radeonfb_cursor_position(struct radeonfb_display *dp) 3817 { 3818 struct radeonfb_softc *sc = dp->rd_softc; 3819 uint32_t offset, hvoff, hvpos; /* registers */ 3820 uint32_t coff; /* cursor offset */ 3821 int i, x, y, xoff, yoff, crtcoff; 3822 3823 /* 3824 * XXX: this also needs to handle pan/scan 3825 */ 3826 for (i = 0; i < dp->rd_ncrtcs; i++) { 3827 3828 struct radeonfb_crtc *rcp = &dp->rd_crtcs[i]; 3829 3830 if (rcp->rc_number) { 3831 offset = RADEON_CUR2_OFFSET; 3832 hvoff = RADEON_CUR2_HORZ_VERT_OFF; 3833 hvpos = RADEON_CUR2_HORZ_VERT_POSN; 3834 crtcoff = RADEON_CRTC2_OFFSET; 3835 } else { 3836 offset = RADEON_CUR_OFFSET; 3837 hvoff = RADEON_CUR_HORZ_VERT_OFF; 3838 hvpos = RADEON_CUR_HORZ_VERT_POSN; 3839 crtcoff = RADEON_CRTC_OFFSET; 3840 } 3841 3842 x = dp->rd_cursor.rc_pos.x; 3843 y = dp->rd_cursor.rc_pos.y; 3844 3845 while (y < rcp->rc_yoffset) { 3846 rcp->rc_yoffset -= RADEON_PANINCREMENT; 3847 } 3848 while (y >= (rcp->rc_yoffset + rcp->rc_videomode.vdisplay)) { 3849 rcp->rc_yoffset += RADEON_PANINCREMENT; 3850 } 3851 while (x < rcp->rc_xoffset) { 3852 rcp->rc_xoffset -= RADEON_PANINCREMENT; 3853 } 3854 while (x >= (rcp->rc_xoffset + rcp->rc_videomode.hdisplay)) { 3855 rcp->rc_xoffset += RADEON_PANINCREMENT; 3856 } 3857 3858 /* adjust for the cursor's hotspot */ 3859 x -= dp->rd_cursor.rc_hot.x; 3860 y -= dp->rd_cursor.rc_hot.y; 3861 xoff = yoff = 0; 3862 3863 if (x >= dp->rd_virtx) 3864 x = dp->rd_virtx - 1; 3865 if (y >= dp->rd_virty) 3866 y = dp->rd_virty - 1; 3867 3868 /* now adjust cursor so it is relative to viewport */ 3869 x -= rcp->rc_xoffset; 3870 y -= rcp->rc_yoffset; 3871 3872 /* 3873 * no need to check for fall off, because we should 3874 * never move off the screen entirely! 3875 */ 3876 coff = 0; 3877 if (x < 0) { 3878 xoff = -x; 3879 x = 0; 3880 } 3881 if (y < 0) { 3882 yoff = -y; 3883 y = 0; 3884 coff = (yoff * 2) * 8; 3885 } 3886 3887 /* pan the display */ 3888 PUT32(sc, crtcoff, (rcp->rc_yoffset * dp->rd_stride) + 3889 rcp->rc_xoffset); 3890 3891 PUT32(sc, offset, (dp->rd_curoff + coff) | RADEON_CUR_LOCK); 3892 PUT32(sc, hvoff, (xoff << 16) | (yoff) | RADEON_CUR_LOCK); 3893 /* NB: this unlocks the cursor */ 3894 PUT32(sc, hvpos, (x << 16) | y); 3895 } 3896 } 3897 3898 static void 3899 radeonfb_cursor_visible(struct radeonfb_display *dp) 3900 { 3901 int i; 3902 uint32_t gencntl, bit; 3903 3904 for (i = 0; i < dp->rd_ncrtcs; i++) { 3905 if (dp->rd_crtcs[i].rc_number) { 3906 gencntl = RADEON_CRTC2_GEN_CNTL; 3907 bit = RADEON_CRTC2_CUR_EN; 3908 } else { 3909 gencntl = RADEON_CRTC_GEN_CNTL; 3910 bit = RADEON_CRTC_CUR_EN; 3911 } 3912 3913 if (dp->rd_cursor.rc_visible) 3914 SET32(dp->rd_softc, gencntl, bit); 3915 else 3916 CLR32(dp->rd_softc, gencntl, bit); 3917 } 3918 } 3919 3920 static void 3921 radeonfb_cursor_cmap(struct radeonfb_display *dp) 3922 { 3923 int i; 3924 uint32_t c0reg, c1reg; 3925 struct radeonfb_softc *sc = dp->rd_softc; 3926 3927 for (i = 0; i < dp->rd_ncrtcs; i++) { 3928 if (dp->rd_crtcs[i].rc_number) { 3929 c0reg = RADEON_CUR2_CLR0; 3930 c1reg = RADEON_CUR2_CLR1; 3931 } else { 3932 c0reg = RADEON_CUR_CLR0; 3933 c1reg = RADEON_CUR_CLR1; 3934 } 3935 3936 PUT32(sc, c0reg, dp->rd_cursor.rc_cmap[0]); 3937 PUT32(sc, c1reg, dp->rd_cursor.rc_cmap[1]); 3938 } 3939 } 3940 3941 static void 3942 radeonfb_cursor_update(struct radeonfb_display *dp, unsigned which) 3943 { 3944 struct radeonfb_softc *sc; 3945 int i; 3946 3947 sc = dp->rd_softc; 3948 for (i = 0; i < dp->rd_ncrtcs; i++) { 3949 if (dp->rd_crtcs[i].rc_number) { 3950 SET32(sc, RADEON_CUR2_OFFSET, RADEON_CUR_LOCK); 3951 } else { 3952 SET32(sc, RADEON_CUR_OFFSET,RADEON_CUR_LOCK); 3953 } 3954 } 3955 3956 if (which & WSDISPLAY_CURSOR_DOCMAP) 3957 radeonfb_cursor_cmap(dp); 3958 3959 if (which & WSDISPLAY_CURSOR_DOSHAPE) 3960 radeonfb_cursor_shape(dp); 3961 3962 if (which & WSDISPLAY_CURSOR_DOCUR) 3963 radeonfb_cursor_visible(dp); 3964 3965 /* this one is unconditional, because it updates other stuff */ 3966 radeonfb_cursor_position(dp); 3967 } 3968 3969 static struct videomode * 3970 radeonfb_best_refresh(struct videomode *m1, struct videomode *m2) 3971 { 3972 int r1, r2; 3973 3974 /* otherwise pick the higher refresh rate */ 3975 r1 = DIVIDE(DIVIDE(m1->dot_clock, m1->htotal), m1->vtotal); 3976 r2 = DIVIDE(DIVIDE(m2->dot_clock, m2->htotal), m2->vtotal); 3977 3978 return (r1 < r2 ? m2 : m1); 3979 } 3980 3981 static const struct videomode * 3982 radeonfb_port_mode(struct radeonfb_softc *sc, struct radeonfb_port *rp, 3983 int x, int y) 3984 { 3985 struct edid_info *ep = &rp->rp_edid; 3986 struct videomode *vmp = NULL; 3987 int i; 3988 3989 if (!rp->rp_edid_valid) { 3990 /* fallback to safe mode */ 3991 return radeonfb_modelookup(sc->sc_defaultmode); 3992 } 3993 3994 /* always choose the preferred mode first! */ 3995 if (ep->edid_preferred_mode) { 3996 3997 /* XXX: add auto-stretching support for native mode */ 3998 3999 /* this may want panning to occur, btw */ 4000 if ((ep->edid_preferred_mode->hdisplay <= x) && 4001 (ep->edid_preferred_mode->vdisplay <= y)) 4002 return ep->edid_preferred_mode; 4003 } 4004 4005 for (i = 0; i < ep->edid_nmodes; i++) { 4006 /* 4007 * We elect to pick a resolution that is too large for 4008 * the monitor than one that is too small. This means 4009 * that we will prefer to pan rather than to try to 4010 * center a smaller display on a larger screen. In 4011 * practice, this shouldn't matter because if a 4012 * monitor can support a larger resolution, it can 4013 * probably also support the smaller. A specific 4014 * exception is fixed format panels, but hopefully 4015 * they are properly dealt with by the "autostretch" 4016 * logic above. 4017 */ 4018 if ((ep->edid_modes[i].hdisplay > x) || 4019 (ep->edid_modes[i].vdisplay > y)) { 4020 continue; 4021 } 4022 4023 /* 4024 * at this point, the display mode is no larger than 4025 * what we've requested. 4026 */ 4027 if (vmp == NULL) 4028 vmp = &ep->edid_modes[i]; 4029 4030 /* eliminate smaller modes */ 4031 if ((vmp->hdisplay >= ep->edid_modes[i].hdisplay) || 4032 (vmp->vdisplay >= ep->edid_modes[i].vdisplay)) 4033 continue; 4034 4035 if ((vmp->hdisplay < ep->edid_modes[i].hdisplay) || 4036 (vmp->vdisplay < ep->edid_modes[i].vdisplay)) { 4037 vmp = &ep->edid_modes[i]; 4038 continue; 4039 } 4040 4041 KASSERT(vmp->hdisplay == ep->edid_modes[i].hdisplay); 4042 KASSERT(vmp->vdisplay == ep->edid_modes[i].vdisplay); 4043 4044 vmp = radeonfb_best_refresh(vmp, &ep->edid_modes[i]); 4045 } 4046 4047 return (vmp ? vmp : radeonfb_modelookup(sc->sc_defaultmode)); 4048 } 4049 4050 static int 4051 radeonfb_hasres(struct videomode *list, int nlist, int x, int y) 4052 { 4053 int i; 4054 4055 for (i = 0; i < nlist; i++) { 4056 if ((x == list[i].hdisplay) && 4057 (y == list[i].vdisplay)) { 4058 return 1; 4059 } 4060 } 4061 return 0; 4062 } 4063 4064 static void 4065 radeonfb_pickres(struct radeonfb_display *dp, uint16_t *x, uint16_t *y, 4066 int pan) 4067 { 4068 struct radeonfb_port *rp; 4069 struct edid_info *ep; 4070 int i, j; 4071 4072 *x = 0; 4073 *y = 0; 4074 4075 if (pan) { 4076 for (i = 0; i < dp->rd_ncrtcs; i++) { 4077 rp = dp->rd_crtcs[i].rc_port; 4078 ep = &rp->rp_edid; 4079 if (!rp->rp_edid_valid) { 4080 /* monitor not present */ 4081 continue; 4082 } 4083 4084 /* 4085 * For now we are ignoring "conflict" that 4086 * could occur when mixing some modes like 4087 * 1280x1024 and 1400x800. It isn't clear 4088 * which is better, so the first one wins. 4089 */ 4090 for (j = 0; j < ep->edid_nmodes; j++) { 4091 /* 4092 * ignore resolutions that are too big for 4093 * the radeon 4094 */ 4095 if (ep->edid_modes[j].hdisplay > 4096 dp->rd_softc->sc_maxx) 4097 continue; 4098 if (ep->edid_modes[j].vdisplay > 4099 dp->rd_softc->sc_maxy) 4100 continue; 4101 4102 /* 4103 * pick largest resolution, the 4104 * smaller monitor will pan 4105 */ 4106 if ((ep->edid_modes[j].hdisplay >= *x) && 4107 (ep->edid_modes[j].vdisplay >= *y)) { 4108 *x = ep->edid_modes[j].hdisplay; 4109 *y = ep->edid_modes[j].vdisplay; 4110 } 4111 } 4112 } 4113 4114 } else { 4115 struct videomode modes[64]; 4116 int nmodes = 0; 4117 int valid = 0; 4118 4119 for (i = 0; i < dp->rd_ncrtcs; i++) { 4120 /* 4121 * pick the largest resolution in common. 4122 */ 4123 rp = dp->rd_crtcs[i].rc_port; 4124 ep = &rp->rp_edid; 4125 4126 if (!rp->rp_edid_valid) 4127 continue; 4128 4129 if (!valid) { 4130 /* 4131 * Pick the preferred mode for this port 4132 * if available. 4133 */ 4134 if (ep->edid_preferred_mode) { 4135 struct videomode *vmp = 4136 ep->edid_preferred_mode; 4137 4138 if ((vmp->hdisplay <= 4139 dp->rd_softc->sc_maxx) && 4140 (vmp->vdisplay <= 4141 dp->rd_softc->sc_maxy)) 4142 modes[nmodes++] = *vmp; 4143 } else { 4144 4145 /* initialize starting list */ 4146 for (j = 0; j < ep->edid_nmodes; j++) { 4147 /* 4148 * ignore resolutions that are 4149 * too big for the radeon 4150 */ 4151 if (ep->edid_modes[j].hdisplay > 4152 dp->rd_softc->sc_maxx) 4153 continue; 4154 if (ep->edid_modes[j].vdisplay > 4155 dp->rd_softc->sc_maxy) 4156 continue; 4157 4158 modes[nmodes] = 4159 ep->edid_modes[j]; 4160 nmodes++; 4161 } 4162 } 4163 valid = 1; 4164 } else { 4165 /* merge into preexisting list */ 4166 for (j = 0; j < nmodes; j++) { 4167 if (!radeonfb_hasres(ep->edid_modes, 4168 ep->edid_nmodes, 4169 modes[j].hdisplay, 4170 modes[j].vdisplay)) { 4171 modes[j] = modes[nmodes]; 4172 j--; 4173 nmodes--; 4174 } 4175 } 4176 } 4177 } 4178 4179 /* now we have to pick from the merged list */ 4180 for (i = 0; i < nmodes; i++) { 4181 if ((modes[i].hdisplay >= *x) && 4182 (modes[i].vdisplay >= *y)) { 4183 *x = modes[i].hdisplay; 4184 *y = modes[i].vdisplay; 4185 } 4186 } 4187 } 4188 4189 if ((*x == 0) || (*y == 0)) { 4190 /* fallback to safe mode */ 4191 *x = 640; 4192 *y = 480; 4193 } 4194 } 4195 4196 /* 4197 * backlight levels are linear on: 4198 * - RV200, RV250, RV280, RV350 4199 * - but NOT on PowerBook4,3 6,3 6,5 4200 * according to Linux' radeonfb 4201 */ 4202 4203 /* Get the current backlight level for the display. */ 4204 4205 static int 4206 radeonfb_get_backlight(struct radeonfb_display *dp) 4207 { 4208 int s; 4209 uint32_t level; 4210 4211 s = spltty(); 4212 4213 level = radeonfb_get32(dp->rd_softc, RADEON_LVDS_GEN_CNTL); 4214 level &= RADEON_LVDS_BL_MOD_LEV_MASK; 4215 level >>= RADEON_LVDS_BL_MOD_LEV_SHIFT; 4216 4217 /* 4218 * On some chips, we should negate the backlight level. 4219 * XXX Find out on which chips. 4220 */ 4221 if (dp->rd_softc->sc_flags & RFB_INV_BLIGHT) 4222 level = RADEONFB_BACKLIGHT_MAX - level; 4223 4224 splx(s); 4225 4226 return level; 4227 } 4228 4229 /* Set the backlight to the given level for the display. */ 4230 static void 4231 radeonfb_switch_backlight(struct radeonfb_display *dp, int on) 4232 { 4233 if (dp->rd_bl_on == on) 4234 return; 4235 dp->rd_bl_on = on; 4236 radeonfb_set_backlight(dp, dp->rd_bl_level); 4237 } 4238 4239 static int 4240 radeonfb_set_backlight(struct radeonfb_display *dp, int level) 4241 { 4242 struct radeonfb_softc *sc = dp->rd_softc; 4243 int rlevel, s; 4244 uint32_t lvds; 4245 4246 if(!sc->sc_mapped) 4247 return 0; 4248 4249 s = spltty(); 4250 4251 dp->rd_bl_level = level; 4252 if (dp->rd_bl_on == 0) 4253 level = 0; 4254 4255 if (level < 0) 4256 level = 0; 4257 else if (level >= RADEONFB_BACKLIGHT_MAX) 4258 level = RADEONFB_BACKLIGHT_MAX; 4259 4260 /* On some chips, we should negate the backlight level. */ 4261 if (dp->rd_softc->sc_flags & RFB_INV_BLIGHT) { 4262 rlevel = RADEONFB_BACKLIGHT_MAX - level; 4263 } else 4264 rlevel = level; 4265 4266 callout_stop(&dp->rd_bl_lvds_co); 4267 radeonfb_engine_idle(sc); 4268 4269 /* 4270 * Turn off the display if the backlight is set to 0, since the 4271 * display is useless without backlight anyway. 4272 */ 4273 if (level == 0) 4274 radeonfb_blank(dp, 1); 4275 else if (radeonfb_get_backlight(dp) == 0) 4276 radeonfb_blank(dp, 0); 4277 4278 lvds = radeonfb_get32(sc, RADEON_LVDS_GEN_CNTL); 4279 lvds &= ~RADEON_LVDS_DISPLAY_DIS; 4280 if (!(lvds & RADEON_LVDS_BLON) || !(lvds & RADEON_LVDS_ON)) { 4281 lvds |= dp->rd_bl_lvds_val & RADEON_LVDS_DIGON; 4282 lvds |= RADEON_LVDS_BLON | RADEON_LVDS_EN; 4283 radeonfb_put32(sc, RADEON_LVDS_GEN_CNTL, lvds); 4284 lvds &= ~RADEON_LVDS_BL_MOD_LEV_MASK; 4285 lvds |= rlevel << RADEON_LVDS_BL_MOD_LEV_SHIFT; 4286 lvds |= RADEON_LVDS_ON; 4287 lvds |= dp->rd_bl_lvds_val & RADEON_LVDS_BL_MOD_EN; 4288 } else { 4289 lvds &= ~RADEON_LVDS_BL_MOD_LEV_MASK; 4290 lvds |= rlevel << RADEON_LVDS_BL_MOD_LEV_SHIFT; 4291 radeonfb_put32(sc, RADEON_LVDS_GEN_CNTL, lvds); 4292 } 4293 4294 dp->rd_bl_lvds_val &= ~RADEON_LVDS_STATE_MASK; 4295 dp->rd_bl_lvds_val |= lvds & RADEON_LVDS_STATE_MASK; 4296 /* XXX What is the correct delay? */ 4297 callout_schedule(&dp->rd_bl_lvds_co, 200 * hz); 4298 4299 splx(s); 4300 4301 return 0; 4302 } 4303 4304 /* 4305 * Callout function for delayed operations on the LVDS_GEN_CNTL register. 4306 * Set the delayed bits in the register, and clear the stored delayed 4307 * value. 4308 */ 4309 4310 static void radeonfb_lvds_callout(void *arg) 4311 { 4312 struct radeonfb_display *dp = arg; 4313 int s; 4314 4315 s = splhigh(); 4316 4317 radeonfb_mask32(dp->rd_softc, RADEON_LVDS_GEN_CNTL, ~0, 4318 dp->rd_bl_lvds_val); 4319 dp->rd_bl_lvds_val = 0; 4320 4321 splx(s); 4322 } 4323 4324 static void 4325 radeonfb_brightness_up(device_t dev) 4326 { 4327 struct radeonfb_softc *sc = device_private(dev); 4328 struct radeonfb_display *dp = &sc->sc_displays[0]; 4329 int level; 4330 4331 /* we assume the main display is the first one - need a better way */ 4332 if (sc->sc_ndisplays < 1) return; 4333 /* make sure pushing the hotkeys always has an effect */ 4334 dp->rd_bl_on = 1; 4335 level = dp->rd_bl_level; 4336 level = min(RADEONFB_BACKLIGHT_MAX, level + 5); 4337 radeonfb_set_backlight(dp, level); 4338 } 4339 4340 static void 4341 radeonfb_brightness_down(device_t dev) 4342 { 4343 struct radeonfb_softc *sc = device_private(dev); 4344 struct radeonfb_display *dp = &sc->sc_displays[0]; 4345 int level; 4346 4347 /* we assume the main display is the first one - need a better way */ 4348 if (sc->sc_ndisplays < 1) return; 4349 /* make sure pushing the hotkeys always has an effect */ 4350 dp->rd_bl_on = 1; 4351 level = dp->rd_bl_level; 4352 level = max(0, level - 5); 4353 radeonfb_set_backlight(dp, level); 4354 } 4355