[haiku-commits] r42397 - haiku/trunk/src/add-ons/accelerants/radeon_hd

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 9 Jul 2011 07:23:52 +0200 (CEST)

Author: kallisti5
Date: 2011-07-09 07:23:51 +0200 (Sat, 09 Jul 2011)
New Revision: 42397
Changeset: https://dev.haiku-os.org/changeset/42397

Modified:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h
Log:
* Final (hopefully?) calculation for blank start/end
* Lets actually call PLLPower after PLLSet
* Improve screen blanking function
* Detect DAC/PLL to use separately from CRT id
* Add DACSense that senses displays on DACA/DACB
* Grab CRT in PLL code via gRegister crtid
* Set overscan to 0 for now
* Setting extended video modes now kinda works sometimes :-/


Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp       2011-07-09 
05:08:18 UTC (rev 42396)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp       2011-07-09 
05:23:51 UTC (rev 42397)
@@ -22,6 +22,79 @@
 #endif
 
 
+bool
+DACSense(uint8 dacIndex)
+{
+       uint32 dacOffset = (dacIndex == 1) ? REG_DACB_OFFSET : REG_DACA_OFFSET;
+
+       // Backup current DAC values
+       uint32 compEnable = Read32(OUT, dacOffset + DACA_COMPARATOR_ENABLE);
+       uint32 control1 = Read32(OUT, dacOffset + DACA_CONTROL1);
+       uint32 control2 = Read32(OUT, dacOffset + DACA_CONTROL2);
+       uint32 detectControl = Read32(OUT, dacOffset + DACA_AUTODETECT_CONTROL);
+       uint32 enable = Read32(OUT, dacOffset + DACA_ENABLE);
+
+       Write32(OUT, dacOffset + DACA_ENABLE, 1);
+       // Acknowledge autodetect
+       Write32Mask(OUT, dacOffset + DACA_AUTODETECT_INT_CONTROL, 0x01, 0x01);
+       Write32Mask(OUT, dacOffset + DACA_AUTODETECT_CONTROL, 0, 0x00000003);
+       Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0, 0x00000001);
+       Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0, 0x00ff0000);
+
+       Write32(OUT, dacOffset + DACA_FORCE_DATA, 0);
+       Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0x00000001, 0x0000001);
+
+       Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
+               0x00070000, 0x00070101);
+       Write32(OUT, dacOffset + DACA_CONTROL1, 0x00050802);
+       Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x00000001);
+               // Shutdown Bandgap voltage reference
+
+       snooze(5);
+
+       Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x01010100);
+               // Shutdown RGB
+
+       Write32(OUT, dacOffset + DACA_FORCE_DATA, 0x1e6);
+               // 486 out of 1024
+       snooze(200);
+
+       Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0x01010100, 0x01010100);
+               // Enable RGB
+       snooze(88);
+
+       Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x01010100);
+               // Shutdown RGB
+
+       Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
+               0x00000100, 0x00000100);
+
+       snooze(100);
+
+       // Get detected RGB channels
+       // If only G is found, it could be a monochrome monitor, but we
+       // don't bother checking.
+       uint8 out = (Read32(OUT, dacOffset + DACA_COMPARATOR_OUTPUT) & 0x0E) >> 
1;
+
+       // Restore stored DAC values
+       Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
+               compEnable, 0x00FFFFFF);
+       Write32(OUT, dacOffset + DACA_CONTROL1, control1);
+       Write32Mask(OUT, dacOffset + DACA_CONTROL2, control2, 0x000001FF);
+       Write32Mask(OUT, dacOffset + DACA_AUTODETECT_CONTROL,
+               detectControl, 0x000000FF);
+       Write32Mask(OUT, dacOffset + DACA_ENABLE, enable, 0x000000FF);
+
+       if (out == 0x7) {
+               TRACE("%s: DAC%d : Display device attached\n", __func__, 
dacIndex);
+               return true;
+       } else {
+               TRACE("%s: DAC%d : No display device attached\n", __func__, 
dacIndex);
+               return false;
+       }
+}
+
+
 void
 DACGetElectrical(uint8 type, uint8 dac,
        uint8 *bandgap, uint8 *whitefine)

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h 2011-07-09 05:08:18 UTC 
(rev 42396)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h 2011-07-09 05:23:51 UTC 
(rev 42397)
@@ -22,6 +22,7 @@
 #define FORMAT_TvCV 0x3
 
 
+bool DACSense(uint8 dacIndex);
 void DACGetElectrical(uint8 type, uint8 dac, uint8 *bandgap, uint8 *whitefine);
 void DACSet(uint8 dacIndex, uint32 crtid);
 void DACPower(uint8 dacIndex, int mode);

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp      2011-07-09 
05:08:18 UTC (rev 42396)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp      2011-07-09 
05:23:51 UTC (rev 42397)
@@ -128,10 +128,12 @@
 
 // Blacks the screen out, useful for mode setting
 static void
-CardBlankSet(bool blank)
+CardBlankSet(uint8 crtid, bool blank)
 {
-       int blackColorReg = D1CRTC_BLACK_COLOR;
-       int blankControlReg = D1CRTC_BLANK_CONTROL;
+       int blackColorReg
+               = (crtid == 1) ? D2CRTC_BLACK_COLOR : D1CRTC_BLACK_COLOR;
+       int blankControlReg
+               = (crtid == 1) ? D2CRTC_BLANK_CONTROL : D1CRTC_BLANK_CONTROL;
 
        Write32(CRT, blackColorReg, 0);
        Write32Mask(CRT, blankControlReg, blank ? 1 << 8 : 0, 1 << 8);
@@ -233,13 +235,11 @@
        Write32(CRT, gRegister->crtHTotal,
                displayTiming.h_total - 1);
 
-       // Calculate blanking
-       uint16 frontPorch = displayTiming.h_sync_start - 
displayTiming.h_display;
-       uint16 backPorch = displayTiming.h_total - displayTiming.h_sync_end;
+       // Blanking
+       uint16 blankStart = displayTiming.h_total
+               + displayTiming.h_display - displayTiming.h_sync_start;
+       uint16 blankEnd = displayTiming.h_total - displayTiming.h_sync_start;
 
-       uint16 blankStart = frontPorch - OVERSCAN;
-       uint16 blankEnd = backPorch;
-
        Write32(CRT, gRegister->crtHBlank,
                blankStart | (blankEnd << 16));
 
@@ -254,12 +254,10 @@
        Write32(CRT, gRegister->crtVTotal,
                displayTiming.v_total - 1);
 
-       frontPorch = displayTiming.v_sync_start - displayTiming.v_display;
-       backPorch = displayTiming.v_total - displayTiming.v_sync_end;
+       blankStart = displayTiming.v_total
+               + displayTiming.v_display - displayTiming.v_sync_start;
+       blankEnd = displayTiming.v_total - displayTiming.v_sync_start;
 
-       blankStart = frontPorch - OVERSCAN;
-       blankEnd = backPorch;
-
        Write32(CRT, gRegister->crtVBlank,
                blankStart | (blankEnd << 16));
 
@@ -290,13 +288,14 @@
 CardModeScale(display_mode *mode)
 {
        // No scaling
-       //Write32(CRT, gRegister->sclUpdate, (1<<16));// Lock
+       Write32(CRT, gRegister->sclUpdate, (1<<16));// Lock
 
-       // For now, default overscan
+       #if 0
        Write32(CRT, D1MODE_EXT_OVERSCAN_LEFT_RIGHT,
                (OVERSCAN << 16) | OVERSCAN); // LEFT | RIGHT
        Write32(CRT, D1MODE_EXT_OVERSCAN_TOP_BOTTOM,
                (OVERSCAN << 16) | OVERSCAN); // TOP | BOTTOM
+       #endif
 
        Write32(CRT, gRegister->viewportStart, 0);
        Write32(CRT, gRegister->viewportSize,
@@ -305,7 +304,7 @@
        Write32(CRT, gRegister->sclTapControl, 0);
        Write32(CRT, gRegister->modeCenter, 2);
        // D1MODE_DATA_FORMAT?
-       //Write32(CRT, gRegister->sclUpdate, 0);                // Unlock
+       Write32(CRT, gRegister->sclUpdate, 0);          // Unlock
 }
 
 
@@ -313,24 +312,40 @@
 radeon_set_display_mode(display_mode *mode)
 {
        uint8 crtNumber = 0;
+       uint8 dacNumber = 0;
 
        init_registers(crtNumber);
 
+       // TODO : this obviously breaks horribly on attached multiple outputs
+       if (DACSense(0))
+               dacNumber = 0;
+       else if (DACSense(1))
+               dacNumber = 1;
+
        CardFBSet(mode);
        CardModeSet(mode);
        CardModeScale(mode);
-       PLLSet(0, mode->timing.pixel_clock);
+
+       PLLSet(dacNumber, mode->timing.pixel_clock);
                // Set pixel clock
 
        Write32(CRT, D1GRPH_LUT_SEL, 0);
 
-       DACSet(crtNumber, 0);
-               // Set DAC A to crt 0
-       DACPower(crtNumber, RHD_POWER_ON);
-       CardBlankSet(false);
+       DACSet(dacNumber, crtNumber);
 
+       // TODO : Shutdown unused PLL/DAC
+
+       // Power up the output
+       PLLPower(dacNumber, RHD_POWER_ON);
+       DACPower(dacNumber, RHD_POWER_ON);
+
+       // Ensure screen isn't blanked
+       CardBlankSet(crtNumber, false);
+
        int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
        TRACE("CRT0 Status: 0x%X\n", crtstatus);
+       crtstatus = Read32(CRT, D2CRTC_STATUS);
+       TRACE("CRT1 Status: 0x%X\n", crtstatus);
 
        return B_OK;
 }

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h        2011-07-09 
05:08:18 UTC (rev 42396)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h        2011-07-09 
05:23:51 UTC (rev 42397)
@@ -21,8 +21,8 @@
 #define FMT1_REG_OFFSET 0x0000
 #define FMT2_REG_OFFSET 0x800
 
-#define OVERSCAN 8
-       // default overscan? Applied to all sides
+#define OVERSCAN 0
+       // TODO : Overscan and scaling support
 
 status_t detect_crt_ranges();
 status_t create_mode_list(void);

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp       2011-07-09 
05:08:18 UTC (rev 42396)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp       2011-07-09 
05:23:51 UTC (rev 42397)
@@ -187,9 +187,15 @@
                        snooze(2);
 
                        if (info.device_chipset >= (RADEON_R600 | 0x20)) {
+                               uint16 pllDiffPostReg
+                                       = (pllIndex == 1) ? 
RV620_EXT2_DIFF_POST_DIV_CNTL
+                                               : RV620_EXT1_DIFF_POST_DIV_CNTL;
+                               uint16 pllDiffDriverEnable
+                                       = (pllIndex == 1) ? 
RV62_EXT2_DIFF_DRIVER_ENABLE
+                                               : RV62_EXT1_DIFF_DRIVER_ENABLE;
                                // Sometimes we have to keep an unused PLL 
running. X Bug #18016
-                               if ((Read32(PLL, RV620_EXT1_DIFF_POST_DIV_CNTL)
-                                       & RV62_EXT1_DIFF_DRIVER_ENABLE) == 0) {
+                               if ((Read32(PLL, pllDiffPostReg)
+                                       & pllDiffDriverEnable) == 0) {
                                        Write32Mask(PLL, pllControlReg, 0x02, 
0x02);
                                                // Power Down
                                } else {
@@ -201,6 +207,11 @@
 
                                Write32Mask(PLL, pllControlReg,  0x2000, 
0x2000);
                                        // Reset anti-glitch?
+
+                       } else {
+                               Write32Mask(PLL, pllControlReg, 0x02, 0x02);
+                                       // Power Down
+                               snooze(200);
                        }
        }
 
@@ -333,7 +344,8 @@
        Write32(PLL, pllExtPostDivSrc, 0x01);
                // Set source as PLL
 
-       PLLCRTCGrab(pllIndex, false);
+       // TODO : better way to grab crt to work on?
+       PLLCRTCGrab(pllIndex, gRegister->crtid);
 }
 
 
@@ -448,7 +460,8 @@
        Write32Mask(PLL, pllCntl, 0, 0x80000000);
                // needed and undocumented
 
-       PLLCRTCGrab(pllIndex, false);
+       // TODO : better way to grab crt to work on?
+       PLLCRTCGrab(pllIndex, gRegister->crtid);
 
        if (hasDccg)
                DCCGCLKSet(pllIndex, RV620_DCCGCLK_GRAB);
@@ -492,11 +505,11 @@
 
 
 void
-PLLCRTCGrab(uint8 pllIndex, bool crt2)
+PLLCRTCGrab(uint8 pllIndex, uint8 crtid)
 {
        bool pll2IsCurrent;
 
-       if (!crt2) {
+       if (crtid == 0) {
                pll2IsCurrent = Read32(PLL, PCLK_CRTC1_CNTL) & 0x00010000;
 
                Write32Mask(PLL, PCLK_CRTC1_CNTL, (pllIndex == 0) ? 0x00010000 
: 0,

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h 2011-07-09 05:08:18 UTC 
(rev 42396)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h 2011-07-09 05:23:51 UTC 
(rev 42397)
@@ -42,7 +42,7 @@
        uint16 feedback, uint16 post);
 status_t PLLPower(uint8 pllIndex, int command);
 status_t PLLCalibrate(uint8 pllIndex);
-void PLLCRTCGrab(uint8 pllIndex, bool crt2);
+void PLLCRTCGrab(uint8 pllIndex, uint8 crtid);
 bool DCCGCLKAvailable(uint8 pllIndex);
 void DCCGCLKSet(uint8 pllIndex, int set);
 


Other related posts:

  • » [haiku-commits] r42397 - haiku/trunk/src/add-ons/accelerants/radeon_hd - kallisti5