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

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 12 Oct 2011 19:24:16 +0200 (CEST)

Author: kallisti5
Date: 2011-10-12 19:24:15 +0200 (Wed, 12 Oct 2011)
New Revision: 42828
Changeset: https://dev.haiku-os.org/changeset/42828

Modified:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp
Log:
* complete pll_set for all AtomBIOS revisions
* add update of crtc encoder scratch registers
* rename id for more descriptive crtc_id
* encoder dpms, BL on/off on lcd


Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp   2011-10-11 
22:32:45 UTC (rev 42827)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.cpp   2011-10-12 
17:24:15 UTC (rev 42828)
@@ -37,7 +37,7 @@
 
 
 void
-encoder_assign_crtc(uint8 id)
+encoder_assign_crtc(uint8 crtc_id)
 {
        int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
        union crtc_source_param args;
@@ -50,7 +50,7 @@
                != B_OK)
                return;
 
-       uint16 connector_index = gDisplay[id]->connector_index;
+       uint16 connector_index = gDisplay[crtc_id]->connector_index;
        uint16 encoder_id = gConnector[connector_index]->encoder.object_id;
 
        switch (frev) {
@@ -58,7 +58,7 @@
                        switch (crev) {
                                case 1:
                                default:
-                                       args.v1.ucCRTC = id;
+                                       args.v1.ucCRTC = crtc_id;
                                        switch (encoder_id) {
                                                case 
ENCODER_OBJECT_ID_INTERNAL_TMDS1:
                                                case 
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -102,7 +102,7 @@
                                        }
                                        break;
                                case 2:
-                                       args.v2.ucCRTC = id;
+                                       args.v2.ucCRTC = crtc_id;
                                        args.v2.ucEncodeMode
                                                = 
display_get_encoder_mode(connector_index);
                                        switch (encoder_id) {
@@ -168,7 +168,8 @@
 
        atom_execute_table(gAtomContext, index, (uint32*)&args);
 
-       // TODO : encoder_crtc_scratch_regs?
+       // update crtc encoder scratch register @ scratch 3
+       encoder_crtc_scratch(crtc_id);
 }
 
 
@@ -366,6 +367,55 @@
 
 
 void
+encoder_crtc_scratch(uint8 crtc_id)
+{
+       TRACE("%s\n", __func__);
+
+       uint32 connector_index = gDisplay[crtc_id]->connector_index;
+       uint32 encoder_flags = gConnector[connector_index]->encoder.flags;
+
+       // TODO : r500
+       uint32 bios_3_scratch = Read32(OUT, R600_BIOS_3_SCRATCH);
+
+       if (encoder_flags & ATOM_DEVICE_TV1_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 18);
+       }
+       if (encoder_flags & ATOM_DEVICE_CV_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 24);
+       }
+       if (encoder_flags & ATOM_DEVICE_CRT1_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 16);
+       }
+       if (encoder_flags & ATOM_DEVICE_CRT2_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 20);
+       }
+       if (encoder_flags & ATOM_DEVICE_LCD1_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 17);
+       }
+       if (encoder_flags & ATOM_DEVICE_DFP1_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 19);
+       }
+       if (encoder_flags & ATOM_DEVICE_DFP2_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 23);
+       }
+       if (encoder_flags & ATOM_DEVICE_DFP3_SUPPORT) {
+               bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
+               bios_3_scratch |= (crtc_id << 25);
+       }
+
+       // TODO : r500
+       Write32(OUT, R600_BIOS_3_SCRATCH, bios_3_scratch);
+}
+
+
+void
 encoder_dpms_scratch(uint8 crtc_id, bool power)
 {
        TRACE("%s: power: %s\n", __func__, power ? "true" : "false");
@@ -448,6 +498,9 @@
 
        memset(&args, 0, sizeof(args));
 
+       uint32 connector_index = gDisplay[crtc_id]->connector_index;
+       uint32 encoder_flags = gConnector[connector_index]->encoder.flags;
+
        switch (encoder_id) {
                case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
                case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -474,10 +527,10 @@
                        index = GetIndexIntoMasterTable(COMMAND, 
LCD1OutputControl);
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-                       // TODO : Laptop LCD special cases dpms set
-                       // if ATOM_DEVICE_LCD_SUPPORT, LCD1OutputControl
-                       // else...
-                       index = GetIndexIntoMasterTable(COMMAND, 
LVTMAOutputControl);
+                       if (encoder_flags & ATOM_DEVICE_LCD_SUPPORT)
+                               index = GetIndexIntoMasterTable(COMMAND, 
LCD1OutputControl);
+                       else
+                               index = GetIndexIntoMasterTable(COMMAND, 
LVTMAOutputControl);
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_DAC1:
                case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -503,8 +556,10 @@
                case B_DPMS_ON:
                        args.ucAction = ATOM_ENABLE;
                        atom_execute_table(gAtomContext, index, (uint32*)&args);
-                       // TODO : ATOM_DEVICE_LCD_SUPPORT : args.ucAction = 
ATOM_LCD_BLON;
-                       //                execute again
+                       if (encoder_flags & ATOM_DEVICE_LCD_SUPPORT) {
+                               args.ucAction = ATOM_LCD_BLON;
+                               atom_execute_table(gAtomContext, index, 
(uint32*)&args);
+                       }
                        encoder_dpms_scratch(crtc_id, true);
                        break;
                case B_DPMS_STAND_BY:
@@ -512,8 +567,10 @@
                case B_DPMS_OFF:
                        args.ucAction = ATOM_DISABLE;
                        atom_execute_table(gAtomContext, index, (uint32*)&args);
-                       // TODO : ATOM_DEVICE_LCD_SUPPORT : args.ucAction = 
ATOM_LCD_BLOFF;
-                       //                execute again
+                       if (encoder_flags & ATOM_DEVICE_LCD_SUPPORT) {
+                               args.ucAction = ATOM_LCD_BLOFF;
+                               atom_execute_table(gAtomContext, index, 
(uint32*)&args);
+                       }
                        encoder_dpms_scratch(crtc_id, false);
                        break;
        }

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h     2011-10-11 
22:32:45 UTC (rev 42827)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/encoder.h     2011-10-12 
17:24:15 UTC (rev 42828)
@@ -14,6 +14,7 @@
 status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command);
 status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command);
 void encoder_output_lock(bool lock);
+void encoder_crtc_scratch(uint8 crtc_id);
 void encoder_dpms_scratch(uint8 crtc_id, bool power);
 void encoder_dpms_set(uint8 crtc_id, uint8 encoder_id, int mode);
 

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp       2011-10-11 
22:32:45 UTC (rev 42827)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/pll.cpp       2011-10-12 
17:24:15 UTC (rev 42828)
@@ -267,12 +267,14 @@
 {
        uint32 connector_index = gDisplay[crtc_id]->connector_index;
        pll_info *pll = &gConnector[connector_index]->encoder.pll;
+
        pll->pixel_clock = pixelClock;
        pll->id = pll_id;
 
        // get any needed clock adjustments, set reference/post dividers, set 
flags
        uint32 adjustedClock = pll_adjust(pll, crtc_id);
 
+       // compute dividers, set flags
        pll_compute(pll);
 
        int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
@@ -283,6 +285,10 @@
        uint8 crev;
        atom_parse_cmd_header(gAtomContext, index, &frev, &crev);
 
+       uint32 bpc = 8;
+               // TODO : BPC == Digital Depth, EDID 1.4+ on digital displays
+               // isn't in Haiku edid common code?
+
        switch (crev) {
                case 1:
                        args.v1.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(adjustedClock / 10);
@@ -318,6 +324,63 @@
                                = 
gConnector[connector_index]->encoder.object_id;
                        args.v3.ucEncoderMode = 
display_get_encoder_mode(connector_index);
                        break;
+               case 5:
+                       args.v5.ucCRTC = crtc_id;
+                       args.v5.usPixelClock = 
B_HOST_TO_LENDIAN_INT16(adjustedClock / 10);
+                       args.v5.ucRefDiv = pll->reference_div;
+                       args.v5.usFbDiv = 
B_HOST_TO_LENDIAN_INT16(pll->feedback_div);
+                       args.v5.ulFbDivDecFrac
+                               = 
B_HOST_TO_LENDIAN_INT32(pll->feedback_div_frac * 100000);
+                       args.v5.ucPostDiv = pll->post_div;
+                       args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
+                       // if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
+                       //      args.v5.ucMiscInfo |= 
PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
+                       switch (bpc) {
+                               case 8:
+                               default:
+                                       args.v5.ucMiscInfo |= 
PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
+                                       break;
+                               case 10:
+                                       args.v5.ucMiscInfo |= 
PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
+                                       break;
+                       }
+                       args.v5.ucTransmitterID
+                               = 
gConnector[connector_index]->encoder.object_id;
+                       args.v5.ucEncoderMode
+                               = display_get_encoder_mode(connector_index);
+                       args.v5.ucPpll = pll_id;
+                       break;
+               case 6:
+                       args.v6.ulDispEngClkFreq
+                               = B_HOST_TO_LENDIAN_INT32(crtc_id << 24 | 
adjustedClock / 10);
+                       args.v6.ucRefDiv = pll->reference_div;
+                       args.v6.usFbDiv = 
B_HOST_TO_LENDIAN_INT16(pll->feedback_div);
+                       args.v6.ulFbDivDecFrac
+                               = 
B_HOST_TO_LENDIAN_INT32(pll->feedback_div_frac * 100000);
+                       args.v6.ucPostDiv = pll->post_div;
+                       args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
+                       // if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
+                       //      args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
+                       switch (bpc) {
+                               case 8:
+                               default:
+                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
+                                       break;
+                               case 10:
+                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
+                                       break;
+                               case 12:
+                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
+                                       break;
+                               case 16:
+                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
+                                       break;
+                       }
+                       args.v6.ucTransmitterID
+                               = 
gConnector[connector_index]->encoder.object_id;
+                       args.v6.ucEncoderMode = 
display_get_encoder_mode(connector_index);
+                       args.v6.ucPpll = pll_id;
+                       break;
                default:
                        TRACE("%s: ERROR: table version %d.%d TODO\n", __func__,
                                frev, crev);


Other related posts: