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/0272627b9730
branches:  trunk
changeset: 826279:0272627b9730
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 50b12d0e3c73 -r 0272627b9730 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