Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Radeon PLLs can't have odd post dividers when us...
details: https://anonhg.NetBSD.org/src/rev/d066b2227f5d
branches: trunk
changeset: 355978:d066b2227f5d
user: macallan <macallan%NetBSD.org@localhost>
date: Fri Aug 25 22:45:33 2017 +0000
description:
Radeon PLLs can't have odd post dividers when used with digital outputs -
add a flag to track this in relevant functions.
Now DVI output works properly on my Mini 2
Needs testing on Mini 1 and other hardware...
diffstat:
sys/dev/pci/radeonfb.c | 85 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 61 insertions(+), 24 deletions(-)
diffs (222 lines):
diff -r ebfe5fbf8e38 -r d066b2227f5d sys/dev/pci/radeonfb.c
--- a/sys/dev/pci/radeonfb.c Fri Aug 25 22:23:59 2017 +0000
+++ b/sys/dev/pci/radeonfb.c Fri Aug 25 22:45:33 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: radeonfb.c,v 1.91 2017/08/23 19:47:39 macallan Exp $ */
+/* $NetBSD: radeonfb.c,v 1.92 2017/08/25 22:45:33 macallan Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.91 2017/08/23 19:47:39 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.92 2017/08/25 22:45:33 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -120,13 +120,16 @@
static int radeonfb_getclocks(struct radeonfb_softc *);
static int radeonfb_gettmds(struct radeonfb_softc *);
static int radeonfb_calc_dividers(struct radeonfb_softc *, uint32_t,
- uint32_t *, uint32_t *);
+ uint32_t *, uint32_t *, int);
+/* flags for radeonfb_calc_dividers */
+#define NO_ODD_FBDIV 1
+
static int radeonfb_getconnectors(struct radeonfb_softc *);
static const struct videomode *radeonfb_modelookup(const char *);
static void radeonfb_init_screen(void *, struct vcons_screen *, int, long *);
static void radeonfb_pllwriteupdate(struct radeonfb_softc *, int);
static void radeonfb_pllwaitatomicread(struct radeonfb_softc *, int);
-static void radeonfb_program_vclk(struct radeonfb_softc *, int, int);
+static void radeonfb_program_vclk(struct radeonfb_softc *, int, int, int);
static void radeonfb_modeswitch(struct radeonfb_display *);
static void radeonfb_setcrtc(struct radeonfb_display *, int);
static void radeonfb_init_misc(struct radeonfb_softc *);
@@ -580,9 +583,12 @@
PRINTREG(RADEON_TMDS_TRANSMITTER_CNTL);
PRINTREG(RADEON_TMDS_PLL_CNTL);
PRINTREG(RADEON_LVDS_GEN_CNTL);
- PRINTREG(RADEON_FP_HORZ_STRETCH);
- PRINTREG(RADEON_FP_VERT_STRETCH);
PRINTREG(RADEON_DISP_HW_DEBUG);
+ PRINTREG(RADEON_PIXCLKS_CNTL);
+ PRINTREG(RADEON_CRTC_H_SYNC_STRT_WID);
+ PRINTREG(RADEON_FP_H_SYNC_STRT_WID);
+ PRINTREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+ PRINTREG(RADEON_FP_H2_SYNC_STRT_WID);
if (IS_RV100(sc))
PUT32(sc, RADEON_TMDS_PLL_CNTL, 0xa27);
@@ -1041,6 +1047,7 @@
PRINTREG(RADEON_TMDS_CNTL);
PRINTREG(RADEON_TMDS_TRANSMITTER_CNTL);
PRINTREG(RADEON_TMDS_PLL_CNTL);
+ PRINTREG(RADEON_PIXCLKS_CNTL);
return;
@@ -1625,7 +1632,7 @@
int
radeonfb_calc_dividers(struct radeonfb_softc *sc, uint32_t dotclock,
- uint32_t *postdivbit, uint32_t *feedbackdiv)
+ uint32_t *postdivbit, uint32_t *feedbackdiv, int flags)
{
int i;
uint32_t outfreq;
@@ -1633,6 +1640,7 @@
DPRINTF(("dot clock: %u\n", dotclock));
for (i = 0; (div = radeonfb_dividers[i].divider) != 0; i++) {
+ if ((flags & NO_ODD_FBDIV) && ((div & 1) != 0)) continue;
outfreq = div * dotclock;
if ((outfreq >= sc->sc_minpll) &&
(outfreq <= sc->sc_maxpll)) {
@@ -2021,13 +2029,13 @@
}
void
-radeonfb_program_vclk(struct radeonfb_softc *sc, int dotclock, int crtc)
+radeonfb_program_vclk(struct radeonfb_softc *sc, int dotclock, int crtc, int flags)
{
uint32_t pbit = 0;
uint32_t feed = 0;
uint32_t data, refdiv, div0;
- radeonfb_calc_dividers(sc, dotclock, &pbit, &feed);
+ radeonfb_calc_dividers(sc, dotclock, &pbit, &feed, flags);
if (crtc == 0) {
@@ -2190,6 +2198,21 @@
for (i = 0; i < dp->rd_ncrtcs; i++)
radeonfb_setcrtc(dp, i);
+#if 0
+ /*
+ * DVO chip voodoo from xf86-video-radeon
+ * apparently this is needed for some powerbooks with DVI outputs
+ */
+
+ uint8_t data[5][2] = {{0x8, 0x030}, {0x9, 0}, {0xa, 0x90}, {0xc, 0x89}, {0x8, 0x3b}};
+ int n = 0;
+ iic_acquire_bus(&sc->sc_i2c[0].ric_controller, 0);
+ for (i = 0; i < 5; i++)
+ n += iic_exec(&sc->sc_i2c[0].ric_controller, I2C_OP_WRITE, 0x38, data[i], 2, NULL, 0, 0);
+ iic_release_bus(&sc->sc_i2c[0].ric_controller, 0);
+ printf("n = %d\n", n);
+#endif
+
/* activate the display */
radeonfb_blank(dp, 0);
}
@@ -2197,7 +2220,7 @@
void
radeonfb_setcrtc(struct radeonfb_display *dp, int index)
{
- int crtc;
+ int crtc, flags = 0;
struct videomode *mode;
struct radeonfb_softc *sc;
struct radeonfb_crtc *cp;
@@ -2214,6 +2237,12 @@
uint32_t pitch;
sc = dp->rd_softc;
+
+ if ((sc->sc_ports[index].rp_tmds_type == RADEON_TMDS_INT) ||
+ (sc->sc_ports[index].rp_tmds_type == RADEON_TMDS_EXT)) {
+ flags |= NO_ODD_FBDIV;
+ }
+
cp = &dp->rd_crtcs[index];
crtc = cp->rc_number;
mode = &cp->rc_videomode;
@@ -2231,6 +2260,7 @@
hsyncstrt = RADEON_CRTC_H_SYNC_STRT_WID;
vtotaldisp = RADEON_CRTC_V_TOTAL_DISP;
vsyncstrt = RADEON_CRTC_V_SYNC_STRT_WID;
+ /* should probably leave those alone on non-LVDS */
fpvsyncstrt = RADEON_FP_V_SYNC_STRT_WID;
fphsyncstrt = RADEON_FP_H_SYNC_STRT_WID;
fpvtotaldisp = RADEON_FP_CRTC_V_TOTAL_DISP;
@@ -2244,8 +2274,9 @@
vsyncstrt = RADEON_CRTC2_V_SYNC_STRT_WID;
fpvsyncstrt = RADEON_FP_V2_SYNC_STRT_WID;
fphsyncstrt = RADEON_FP_H2_SYNC_STRT_WID;
- fpvtotaldisp = RADEON_FP_CRTC2_V_TOTAL_DISP;
- fphtotaldisp = RADEON_FP_CRTC2_H_TOTAL_DISP;
+ /* XXX these registers don't seem to exist */
+ fpvtotaldisp = 0;//RADEON_FP_CRTC2_V_TOTAL_DISP;
+ fphtotaldisp = 0;//RADEON_FP_CRTC2_H_TOTAL_DISP;
break;
default:
panic("Bad CRTC!");
@@ -2302,9 +2333,10 @@
v |= (mode->htotal / 8) - 1;
PUT32(sc, htotaldisp, v);
DPRINTF(("CRTC%s_H_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
- PUT32(sc, fphtotaldisp, v);
- DPRINTF(("FP_H%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
-
+ if (fphtotaldisp) {
+ PUT32(sc, fphtotaldisp, v);
+ DPRINTF(("FP_H%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
+ }
/*
* H_SYNC_STRT_WID
*/
@@ -2314,8 +2346,10 @@
v |= RADEON_CRTC_H_SYNC_POL;
PUT32(sc, hsyncstrt, v);
DPRINTF(("CRTC%s_H_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
- PUT32(sc, fphsyncstrt, v);
- DPRINTF(("FP_H%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
+ if (fphsyncstrt) {
+ PUT32(sc, fphsyncstrt, v);
+ DPRINTF(("FP_H%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
+ }
/*
* V_TOTAL_DISP
@@ -2324,8 +2358,10 @@
v |= (mode->vtotal - 1);
PUT32(sc, vtotaldisp, v);
DPRINTF(("CRTC%s_V_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
- PUT32(sc, fpvtotaldisp, v);
- DPRINTF(("FP_V%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
+ if (fpvtotaldisp) {
+ PUT32(sc, fpvtotaldisp, v);
+ DPRINTF(("FP_V%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
+ }
/*
* V_SYNC_STRT_WID
@@ -2336,10 +2372,12 @@
v |= RADEON_CRTC_V_SYNC_POL;
PUT32(sc, vsyncstrt, v);
DPRINTF(("CRTC%s_V_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
- PUT32(sc, fpvsyncstrt, v);
- DPRINTF(("FP_V%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
-
- radeonfb_program_vclk(sc, mode->dot_clock, crtc);
+ if (fpvsyncstrt) {
+ PUT32(sc, fpvsyncstrt, v);
+ DPRINTF(("FP_V%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
+ }
+
+ radeonfb_program_vclk(sc, mode->dot_clock, crtc, flags);
switch (crtc) {
case 0:
@@ -2644,7 +2682,6 @@
/* initialize the palette for every CRTC used by this display */
for (cc = 0; cc < dp->rd_ncrtcs; cc++) {
crtc = dp->rd_crtcs[cc].rc_number;
- DPRINTF(("%s: doing crtc %d %d\n", __func__, cc, crtc));
if (crtc)
SET32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL);
Home |
Main Index |
Thread Index |
Old Index