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