[haiku-commits] haiku: hrev43368 - src/add-ons/accelerants/radeon_hd

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 30 Nov 2011 03:59:39 +0100 (CET)

hrev43368 adds 1 changeset to branch 'master'
old head: fc111138a9ca143e42ba94add2a3a2053b743b0c
new head: b394b1d2bb311256614713abe6a9184b440e3c30

----------------------------------------------------------------------------

2 files changed, 184 insertions(+), 2 deletions(-)
src/add-ons/accelerants/radeon_hd/encoder.cpp |  183 ++++++++++++++++++++-
src/add-ons/accelerants/radeon_hd/encoder.h   |    3 +-

############################################################################

Revision:    hrev43368
Commit:      b394b1d2bb311256614713abe6a9184b440e3c30
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b394b1d
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Wed Nov 30 02:58:30 2011 UTC

Add early support for external encoders

* detect and attempt setup on external encoders
* improve encoder tracing

----------------------------------------------------------------------------

diff --git a/src/add-ons/accelerants/radeon_hd/encoder.cpp 
b/src/add-ons/accelerants/radeon_hd/encoder.cpp
index a09654f..4eb33d5 100644
--- a/src/add-ons/accelerants/radeon_hd/encoder.cpp
+++ b/src/add-ons/accelerants/radeon_hd/encoder.cpp
@@ -39,6 +39,7 @@ union crtc_source_param {
 void
 encoder_assign_crtc(uint8 crtcID)
 {
+       TRACE("%s\n", __func__);
        int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
        union crtc_source_param args;
 
@@ -176,6 +177,7 @@ encoder_assign_crtc(uint8 crtcID)
 void
 encoder_apply_quirks(uint8 crtcID)
 {
+       TRACE("%s\n", __func__);
        radeon_shared_info &info = *gInfo->shared_info;
        register_info* regs = gDisplay[crtcID]->regs;
        uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
@@ -194,6 +196,7 @@ encoder_apply_quirks(uint8 crtcID)
 void
 encoder_mode_set(uint8 id, uint32 pixelClock)
 {
+       TRACE("%s\n", __func__);
        radeon_shared_info &info = *gInfo->shared_info;
        uint32 connectorIndex = gDisplay[id]->connectorIndex;
        uint16 encoderFlags = gConnector[connectorIndex]->encoder.flags;
@@ -256,6 +259,23 @@ encoder_mode_set(uint8 id, uint32 pixelClock)
                case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
                        TRACE("%s: TODO for DVO encoder setup\n", __func__);
                        break;
+               case ENCODER_OBJECT_ID_SI170B:
+               case ENCODER_OBJECT_ID_CH7303:
+               case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
+               case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
+               case ENCODER_OBJECT_ID_TITFP513:
+               case ENCODER_OBJECT_ID_VT1623:
+               case ENCODER_OBJECT_ID_HDMI_SI1930:
+               case ENCODER_OBJECT_ID_TRAVIS:
+               case ENCODER_OBJECT_ID_NUTMEG:
+                       if (info.dceMajor >= 4 && info.dceMinor >= 1) {
+                               encoder_external_setup(id, pixelClock,
+                                       
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
+                       } else {
+                               encoder_external_setup(id, pixelClock,
+                                       ATOM_ENABLE);
+                       }
+                       break;
                default:
                        TRACE("%s: TODO for unknown encoder setup!\n", 
__func__);
        }
@@ -330,8 +350,10 @@ encoder_digital_setup(uint8 id, uint32 pixelClock, int 
command)
        uint8 tableMinor;
 
        if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor)
-               != B_OK)
+               != B_OK) {
+               ERROR("%s: cannot parse command table\n", __func__);
                return B_ERROR;
+       }
 
        switch (tableMajor) {
        case 1:
@@ -437,6 +459,7 @@ encoder_dig_setup(uint8 id, uint32 pixelClock, int command)
        union dig_encoder_control args;
        int index = 0;
 
+       // Table verson
        uint8 tableMajor;
        uint8 tableMinor;
 
@@ -576,6 +599,164 @@ encoder_dig_setup(uint8 id, uint32 pixelClock, int 
command)
 }
 
 
+union external_encoder_control {
+       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
+       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;
+};
+
+
+status_t
+encoder_external_setup(uint8 id, uint32 pixelClock, int command)
+{
+       TRACE("%s\n", __func__);
+
+       int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
+       union external_encoder_control args;
+       memset(&args, 0, sizeof(args));
+
+       uint32 connectorIndex = gDisplay[id]->connectorIndex;
+       int connectorObjectID
+               = (gConnector[connectorIndex]->objectID & OBJECT_ID_MASK)
+                       >> OBJECT_ID_SHIFT;
+
+       uint8 tableMajor;
+       uint8 tableMinor;
+
+       if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor)
+               != B_OK) {
+               ERROR("%s: Error parsing ExternalEncoderControl table\n", 
__func__);
+               return B_ERROR;
+       }
+
+       switch (tableMajor) {
+               case 1:
+                       // no options needed on table 1.x
+                       break;
+               case 2:
+                       switch (tableMinor) {
+                               case 1:
+                               case 2:
+                                       args.v1.sDigEncoder.ucAction = command;
+                                       args.v1.sDigEncoder.usPixelClock
+                                               = 
B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
+                                       args.v1.sDigEncoder.ucEncoderMode
+                                               = 
display_get_encoder_mode(connectorIndex);
+                                       #if 0
+                                       if (0) { // 
ENCODER_MODE_IS_DP(v1.sDigEncoder.ucEncoderMode)
+                                               if (dp_clock == 270000) {
+                                                       
args.v1.sDigEncoder.ucConfig
+                                                               |= 
ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+                                               }
+                                               args.v1.sDigEncoder.ucLaneNum = 
dp_lane_count;
+                                       } else if (pixelClock > 165000) {
+                                       #endif
+                                       if (pixelClock > 165000) {
+                                               args.v1.sDigEncoder.ucLaneNum = 
8;
+                                       } else {
+                                               args.v1.sDigEncoder.ucLaneNum = 
4;
+                                       }
+                                       break;
+                               case 3:
+                               {
+                                       args.v3.sExtEncoder.ucAction = command;
+                                       if (command == 
EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) {
+                                               
args.v3.sExtEncoder.usConnectorId
+                                                       = 
B_HOST_TO_LENDIAN_INT16(connectorObjectID);
+                                       } else {
+                                               args.v3.sExtEncoder.usPixelClock
+                                                       = 
B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
+                                       }
+
+                                       args.v3.sExtEncoder.ucEncoderMode
+                                               = 
display_get_encoder_mode(connectorIndex);
+
+                                       #if 0
+                                       if 
(ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) {
+                                               if (dp_clock == 270000) {
+                                                       
args.v3.sExtEncoder.ucConfig
+                                                               
|=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
+                                               } else if (dp_clock == 540000) {
+                                                       
args.v3.sExtEncoder.ucConfig
+                                                               
|=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
+                                               }
+                                               args.v3.sExtEncoder.ucLaneNum = 
dp_lane_count;
+                                       } else if (pixelClock > 165000) {
+                                       #endif
+                                       if (pixelClock > 165000) {
+                                               args.v3.sExtEncoder.ucLaneNum = 
8;
+                                       } else {
+                                               args.v3.sExtEncoder.ucLaneNum = 
4;
+                                       }
+
+                                       uint16 encoderFlags
+                                               = 
gConnector[connectorIndex]->encoder.flags;
+                                       switch ((encoderFlags & ENUM_ID_MASK) 
>> ENUM_ID_SHIFT) {
+                                               case GRAPH_OBJECT_ENUM_ID1:
+                                                       TRACE("%s: external 
encoder 1\n", __func__);
+                                                       
args.v3.sExtEncoder.ucConfig
+                                                               |= 
EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;
+                                                       break;
+                                               case GRAPH_OBJECT_ENUM_ID2:
+                                                       TRACE("%s: external 
encoder 2\n", __func__);
+                                                       
args.v3.sExtEncoder.ucConfig
+                                                               |= 
EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;
+                                                       break;
+                                               case GRAPH_OBJECT_ENUM_ID3:
+                                                       TRACE("%s: external 
encoder 3\n", __func__);
+                                                       
args.v3.sExtEncoder.ucConfig
+                                                               |= 
EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
+                                                       break;
+                                       }
+
+                                       // TODO: don't set statically
+                                       uint32 bitsPerColor = 8;
+                                       switch (bitsPerColor) {
+                                               case 0:
+                                                       
args.v3.sExtEncoder.ucBitPerColor
+                                                               = 
PANEL_BPC_UNDEFINE;
+                                                       break;
+                                               case 6:
+                                                       
args.v3.sExtEncoder.ucBitPerColor
+                                                               = 
PANEL_6BIT_PER_COLOR;
+                                                       break;
+                                               case 8:
+                                               default:
+                                                       
args.v3.sExtEncoder.ucBitPerColor
+                                                               = 
PANEL_8BIT_PER_COLOR;
+                                                       break;
+                                               case 10:
+                                                       
args.v3.sExtEncoder.ucBitPerColor
+                                                               = 
PANEL_10BIT_PER_COLOR;
+                                                       break;
+                                               case 12:
+                                                       
args.v3.sExtEncoder.ucBitPerColor
+                                                               = 
PANEL_12BIT_PER_COLOR;
+                                                       break;
+                                               case 16:
+                                                       
args.v3.sExtEncoder.ucBitPerColor
+                                                               = 
PANEL_16BIT_PER_COLOR;
+                                                       break;
+                                       }
+                                       break;
+                               }
+                               default:
+                                       ERROR("%s: Unknown table minor version: 
"
+                                               "%" B_PRIu8 ".%" B_PRIu8 "\n", 
__func__,
+                                               tableMajor, tableMinor);
+                                       return B_ERROR;
+                       }
+                       break;
+               default:
+                       ERROR("%s: Unknown table major version: "
+                               "%" B_PRIu8 ".%" B_PRIu8 "\n", __func__,
+                               tableMajor, tableMinor);
+                       return B_ERROR;
+       }
+
+       return atom_execute_table(gAtomContext, index, (uint32*)&args);
+}
+
+
 status_t
 encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
 {
diff --git a/src/add-ons/accelerants/radeon_hd/encoder.h 
b/src/add-ons/accelerants/radeon_hd/encoder.h
index fb39070..abe6b61 100644
--- a/src/add-ons/accelerants/radeon_hd/encoder.h
+++ b/src/add-ons/accelerants/radeon_hd/encoder.h
@@ -12,9 +12,10 @@
 void encoder_assign_crtc(uint8 crt_id);
 void encoder_apply_quirks(uint8 crtcID);
 void encoder_mode_set(uint8 id, uint32 pixelClock);
-status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command);
 status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command);
+status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command);
 status_t encoder_dig_setup(uint8 id, uint32 pixelClock, int command);
+status_t encoder_external_setup(uint8 id, uint32 pixelClock, int command);
 status_t encoder_tv_setup(uint8 id, uint32 pixelClock, int command);
 bool encoder_analog_load_detect(uint8 connectorIndex);
 void encoder_output_lock(bool lock);


Other related posts:

  • » [haiku-commits] haiku: hrev43368 - src/add-ons/accelerants/radeon_hd - kallisti5