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

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 10 Oct 2011 20:07:53 +0200 (CEST)

Author: kallisti5
Date: 2011-10-10 20:07:53 +0200 (Mon, 10 Oct 2011)
New Revision: 42819
Changeset: https://dev.haiku-os.org/changeset/42819

Modified:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h
Log:
* move pll info onto encoder
* add atombios PLL adjustment code
* add initial PLL clock flags


Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h  2011-10-10 
16:46:22 UTC (rev 42818)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h  2011-10-10 
18:07:53 UTC (rev 42819)
@@ -171,6 +171,7 @@
        uint32          flags;
        bool            is_hdmi;
        bool            is_tv;
+       struct pll_info pll;
 };
 
 
@@ -195,7 +196,6 @@
        uint32                  vfreq_min;
        uint32                  hfreq_max;
        uint32                  hfreq_min;
-       pll_info                pll;
        edid1_info              edid_info;
 } display_info;
 

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp       2011-10-10 
16:46:22 UTC (rev 42818)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp       2011-10-10 
18:07:53 UTC (rev 42819)
@@ -168,6 +168,104 @@
 }
 
 
+union adjust_pixel_clock {
+       ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
+       ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
+};
+
+
+uint32
+pll_adjust(uint32 pixelClock, uint8 crtc_id)
+{
+       uint32 flags = 0;
+       flags |= PLL_PREFER_LOW_REF_DIV;
+       // TODO : PLL flags
+       radeon_shared_info &info = *gInfo->shared_info;
+
+       uint32 adjustedClock = pixelClock;
+
+       uint32 connector_index = gDisplay[crtc_id]->connector_index;
+       uint32 encoder_id = gConnector[connector_index]->encoder.object_id;
+       uint32 encoder_mode = display_get_encoder_mode(connector_index);
+       pll_info *pll = &gConnector[connector_index]->encoder.pll;
+
+       if (info.device_chipset >= (RADEON_R600 | 0x20)) {
+               union adjust_pixel_clock args;
+               uint8 frev;
+               uint8 crev;
+
+               int index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
+
+               if (atom_parse_cmd_header(gAtomContext, index, &frev, &crev) != 
B_OK)
+                       return adjustedClock;
+
+               memset(&args, 0, sizeof(args));
+               switch (frev) {
+                       case 1:
+                               switch (crev) {
+                                       case 1:
+                                       case 2:
+                                               args.v1.usPixelClock
+                                                       = 
B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
+                                               args.v1.ucTransmitterID = 
encoder_id;
+                                               args.v1.ucEncodeMode = 
encoder_mode;
+                                               // TODO : SS and SS % > 0
+                                               if (0) {
+                                                       args.v1.ucConfig
+                                                               |= 
ADJUST_DISPLAY_CONFIG_SS_ENABLE;
+                                               }
+
+                                               
atom_execute_table(gAtomContext, index, (uint32*)&args);
+                                               // get returned adjusted clock
+                                               adjustedClock
+                                                       = 
B_LENDIAN_TO_HOST_INT16(args.v1.usPixelClock);
+                                               adjustedClock *= 10;
+                                               break;
+                                       case 3:
+                                               args.v3.sInput.usPixelClock
+                                                       = 
B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
+                                               args.v3.sInput.ucTransmitterID 
= encoder_id;
+                                               args.v3.sInput.ucEncodeMode = 
encoder_mode;
+                                               args.v3.sInput.ucDispPllConfig 
= 0;
+                                               // TODO : SS and SS % > 0
+                                               if (0) {
+                                                       
args.v3.sInput.ucDispPllConfig
+                                                               |= 
DISPPLL_CONFIG_SS_ENABLE;
+                                               }
+                                               // TODO : if 
ATOM_DEVICE_DFP_SUPPORT
+                                               // TODO : display port DP
+
+                                               // TODO : is DP?
+                                               
args.v3.sInput.ucExtTransmitterID = 0;
+
+                                               
atom_execute_table(gAtomContext, index, (uint32*)&args);
+                                               adjustedClock
+                                                       = 
B_LENDIAN_TO_HOST_INT32(
+                                                               
args.v3.sOutput.ulDispPllFreq) * 10;
+
+                                               if (args.v3.sOutput.ucRefDiv) {
+                                                       pll->flags |= 
PLL_USE_FRAC_FB_DIV;
+                                                       pll->flags |= 
PLL_USE_REF_DIV;
+                                                       pll->reference_div = 
args.v3.sOutput.ucRefDiv;
+                                               }
+                                               if (args.v3.sOutput.ucPostDiv) {
+                                                       pll->flags |= 
PLL_USE_FRAC_FB_DIV;
+                                                       pll->flags |= 
PLL_USE_POST_DIV;
+                                                       pll->post_div = 
args.v3.sOutput.ucPostDiv;
+                                               }
+                                               break;
+                                       default:
+                                               return adjustedClock;
+                               }
+                               break;
+                       default:
+                               return adjustedClock;
+               }
+       }
+       return adjustedClock;
+}
+
+
 status_t
 pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
 {
@@ -177,7 +275,9 @@
        uint32 feedbackFrac = 0;
        uint32 post = 0;
 
-       pll_compute(pixelClock, &dotclock, &reference, &feedback,
+       uint32 adjustedClock = pll_adjust(pixelClock, crtc_id);
+
+       pll_compute(adjustedClock, &dotclock, &reference, &feedback,
                &feedbackFrac, &post);
 
        int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
@@ -192,7 +292,7 @@
 
        switch (crev) {
                case 1:
-                       args.v1.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
+                       args.v1.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(adjustedClock / 10);
                        args.v1.usRefDiv = B_HOST_TO_LENDIAN_INT16(reference);
                        args.v1.usFbDiv = B_HOST_TO_LENDIAN_INT16(feedback);
                        args.v1.ucFracFbDiv = feedbackFrac;
@@ -202,7 +302,7 @@
                        args.v1.ucRefDivSrc = 1;
                        break;
                case 2:
-                       args.v2.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
+                       args.v2.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(adjustedClock / 10);
                        args.v2.usRefDiv = B_HOST_TO_LENDIAN_INT16(reference);
                        args.v2.usFbDiv = B_HOST_TO_LENDIAN_INT16(feedback);
                        args.v2.ucFracFbDiv = feedbackFrac;
@@ -212,7 +312,7 @@
                        args.v2.ucRefDivSrc = 1;
                        break;
                case 3:
-                       args.v3.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
+                       args.v3.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(adjustedClock / 10);
                        args.v3.usRefDiv = B_HOST_TO_LENDIAN_INT16(reference);
                        args.v3.usFbDiv = B_HOST_TO_LENDIAN_INT16(feedback);
                        args.v3.ucFracFbDiv = feedbackFrac;
@@ -231,7 +331,8 @@
                        return B_ERROR;
        }
 
-       TRACE("%s: setting pixel clock %" B_PRIu32 "\n", __func__, pixelClock);
+       TRACE("%s: set adjusted pixel clock %" B_PRIu32 " (was %" B_PRIu32 
")\n",
+               __func__, adjustedClock, pixelClock);
 
        return atom_execute_table(gAtomContext, index, (uint32 *)&args);
 }

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h 2011-10-10 16:46:22 UTC 
(rev 42818)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.h 2011-10-10 18:07:53 UTC 
(rev 42819)
@@ -23,7 +23,25 @@
 #define POST_DIV_MIN 2
 #define POST_DIV_LIMIT 127
 
+/* pll flags */
+#define PLL_USE_BIOS_DIVS        (1 << 0)
+#define PLL_NO_ODD_POST_DIV      (1 << 1)
+#define PLL_USE_REF_DIV          (1 << 2)
+#define PLL_LEGACY               (1 << 3)
+#define PLL_PREFER_LOW_REF_DIV   (1 << 4)
+#define PLL_PREFER_HIGH_REF_DIV  (1 << 5)
+#define PLL_PREFER_LOW_FB_DIV    (1 << 6)
+#define PLL_PREFER_HIGH_FB_DIV   (1 << 7)
+#define PLL_PREFER_LOW_POST_DIV  (1 << 8)
+#define PLL_PREFER_HIGH_POST_DIV (1 << 9)
+#define PLL_USE_FRAC_FB_DIV      (1 << 10)
+#define PLL_PREFER_CLOSEST_LOWER (1 << 11)
+#define PLL_USE_POST_DIV         (1 << 12)
+#define PLL_IS_LCD               (1 << 13)
+#define PLL_PREFER_MINM_OVER_MAXP (1 << 14)
 
+
+uint32 pll_adjust(uint32 pixelClock, uint8 crtc_id);
 status_t pll_compute(uint32 pixelClock, uint32 *dotclockOut,
        uint32 *referenceOut, uint32 *feedbackOut, uint32 *feedbackFracOut,
        uint32 *postOut);


Other related posts:

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