drm/radeon/kms: properly handle bpc >8 in atom command tables
authorAlex Deucher <alexdeucher@gmail.com>
Fri, 20 May 2011 08:34:15 +0000 (04:34 -0400)
committerDave Airlie <airlied@redhat.com>
Fri, 20 May 2011 10:02:20 +0000 (20:02 +1000)
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon_encoders.c

index 529a3a7..608b1c2 100644 (file)
@@ -512,6 +512,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
        struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *encoder = NULL;
        struct radeon_encoder *radeon_encoder = NULL;
+       struct drm_connector *connector = NULL;
        u32 adjusted_clock = mode->clock;
        int encoder_mode = 0;
        u32 dp_clock = mode->clock;
@@ -546,9 +547,11 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                if (encoder->crtc == crtc) {
                        radeon_encoder = to_radeon_encoder(encoder);
+                       connector = radeon_get_connector_for_encoder(encoder);
+                       if (connector)
+                               bpc = connector->display_info.bpc;
                        encoder_mode = atombios_get_encoder_mode(encoder);
                        if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) {
-                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
                                if (connector) {
                                        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
                                        struct radeon_connector_atom_dig *dig_connector =
@@ -754,7 +757,8 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
                                      u32 ref_div,
                                      u32 fb_div,
                                      u32 frac_fb_div,
-                                     u32 post_div)
+                                     u32 post_div,
+                                     int bpc)
 {
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
@@ -812,6 +816,15 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
                        args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
                        args.v5.ucPostDiv = post_div;
                        args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
+                       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 = encoder_id;
                        args.v5.ucEncoderMode = encoder_mode;
                        args.v5.ucPpll = pll_id;
@@ -824,6 +837,21 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
                        args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
                        args.v6.ucPostDiv = post_div;
                        args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
+                       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 = encoder_id;
                        args.v6.ucEncoderMode = encoder_mode;
                        args.v6.ucPpll = pll_id;
@@ -855,6 +883,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        int encoder_mode = 0;
        struct radeon_atom_ss ss;
        bool ss_enabled = false;
+       int bpc = 8;
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
                if (encoder->crtc == crtc) {
@@ -891,6 +920,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
                struct radeon_connector_atom_dig *dig_connector =
                        radeon_connector->con_priv;
                int dp_clock;
+               bpc = connector->display_info.bpc;
 
                switch (encoder_mode) {
                case ATOM_ENCODER_MODE_DP:
@@ -974,7 +1004,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
 
        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
                                  encoder_mode, radeon_encoder->encoder_id, mode->clock,
-                                 ref_div, fb_div, frac_fb_div, post_div);
+                                 ref_div, fb_div, frac_fb_div, post_div, bpc);
 
        if (ss_enabled) {
                /* calculate ss amount and step size */
@@ -1522,7 +1552,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
        case ATOM_PPLL2:
                /* disable the ppll */
                atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
-                                         0, 0, ATOM_DISABLE, 0, 0, 0, 0);
+                                         0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0);
                break;
        default:
                break;
index b2e0b58..6c6793e 100644 (file)
@@ -760,6 +760,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
        int dp_clock = 0;
        int dp_lane_count = 0;
        int hpd_id = RADEON_HPD_NONE;
+       int bpc = 8;
 
        if (connector) {
                struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -769,6 +770,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
                dp_clock = dig_connector->dp_clock;
                dp_lane_count = dig_connector->dp_lane_count;
                hpd_id = radeon_connector->hpd.hpd;
+               bpc = connector->display_info.bpc;
        }
 
        /* no dig encoder assigned */
@@ -810,7 +812,27 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
                                args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
                }
                args.v4.acConfig.ucDigSel = dig->dig_encoder;
-               args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+               switch (bpc) {
+               case 0:
+                       args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
+                       break;
+               case 6:
+                       args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+                       break;
+               case 8:
+               default:
+                       args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+                       break;
+               case 10:
+                       args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+                       break;
+               case 12:
+                       args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+                       break;
+               case 16:
+                       args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+                       break;
+               }
                if (hpd_id == RADEON_HPD_NONE)
                        args.v4.ucHPD_ID = 0;
                else
@@ -819,7 +841,27 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
                if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
                        args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
                args.v3.acConfig.ucDigSel = dig->dig_encoder;
-               args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+               switch (bpc) {
+               case 0:
+                       args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE;
+                       break;
+               case 6:
+                       args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+                       break;
+               case 8:
+               default:
+                       args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+                       break;
+               case 10:
+                       args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+                       break;
+               case 12:
+                       args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+                       break;
+               case 16:
+                       args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+                       break;
+               }
        } else {
                if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
                        args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
@@ -1099,6 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
        int dp_lane_count = 0;
        int connector_object_id = 0;
        u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+       int bpc = 8;
 
        if (connector) {
                struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1109,6 +1152,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
                dp_lane_count = dig_connector->dp_lane_count;
                connector_object_id =
                        (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+               bpc = connector->display_info.bpc;
        }
 
        memset(&args, 0, sizeof(args));
@@ -1166,7 +1210,27 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
                                args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
                                break;
                        }
-                       args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+                       switch (bpc) {
+                       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:
                        DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);