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