This allows for a more exact fitting on the physical
display. The new properties default to zero which corresponds to the
previous underscan border width[height] formula:
(display_width[display_width] >> 5) + 16.

Example to set a horizontal border width of 30 and a vertikal border
height of 22:

   xrandr --output HDMI-0 --set underscan on --set "underscan hborder" 30 --set 
"underscan vborder" 22

Signed-off-by: Marius Gröger <marius.groe...@googlemail.com>
---
 drivers/gpu/drm/radeon/radeon_connectors.c |   55 ++++++++++++++++++++++++++--
 drivers/gpu/drm/radeon/radeon_display.c    |   28 +++++++++++++-
 drivers/gpu/drm/radeon/radeon_mode.h       |    4 ++
 3 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c 
b/drivers/gpu/drm/radeon/radeon_connectors.c
index 1a5ee39..12ec609 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -326,6 +326,34 @@ int radeon_connector_set_property(struct drm_connector 
*connector, struct drm_pr
                }
        }
 
+       if (property == rdev->mode_info.underscan_hborder_property) {
+               /* need to find digital encoder on connector */
+               encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
+               if (!encoder)
+                       return 0;
+
+               radeon_encoder = to_radeon_encoder(encoder);
+
+               if (radeon_encoder->underscan_hborder != val) {
+                       radeon_encoder->underscan_hborder = val;
+                       radeon_property_change_mode(&radeon_encoder->base);
+               }
+       }
+
+       if (property == rdev->mode_info.underscan_vborder_property) {
+               /* need to find digital encoder on connector */
+               encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
+               if (!encoder)
+                       return 0;
+
+               radeon_encoder = to_radeon_encoder(encoder);
+
+               if (radeon_encoder->underscan_vborder != val) {
+                       radeon_encoder->underscan_vborder = val;
+                       radeon_property_change_mode(&radeon_encoder->base);
+               }
+       }
+
        if (property == rdev->mode_info.tv_std_property) {
                encoder = radeon_find_encoder(connector, 
DRM_MODE_ENCODER_TVDAC);
                if (!encoder) {
@@ -1142,10 +1170,17 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              
rdev->mode_info.coherent_mode_property,
                                              1);
-               if (ASIC_IS_AVIVO(rdev))
+               if (ASIC_IS_AVIVO(rdev)) {
                        drm_connector_attach_property(&radeon_connector->base,
                                                      
rdev->mode_info.underscan_property,
                                                      UNDERSCAN_AUTO);
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     
rdev->mode_info.underscan_hborder_property,
+                                                     0);
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     
rdev->mode_info.underscan_vborder_property,
+                                                     0);
+               }
                if (connector_type == DRM_MODE_CONNECTOR_DVII) {
                        radeon_connector->dac_load_detect = true;
                        drm_connector_attach_property(&radeon_connector->base,
@@ -1170,10 +1205,17 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              
rdev->mode_info.coherent_mode_property,
                                              1);
-               if (ASIC_IS_AVIVO(rdev))
+               if (ASIC_IS_AVIVO(rdev)) {
                        drm_connector_attach_property(&radeon_connector->base,
                                                      
rdev->mode_info.underscan_property,
                                                      UNDERSCAN_AUTO);
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     
rdev->mode_info.underscan_hborder_property,
+                                                     0);
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     
rdev->mode_info.underscan_vborder_property,
+                                                     0);
+               }
                subpixel_order = SubPixelHorizontalRGB;
                break;
        case DRM_MODE_CONNECTOR_DisplayPort:
@@ -1201,10 +1243,17 @@ radeon_add_atom_connector(struct drm_device *dev,
                drm_connector_attach_property(&radeon_connector->base,
                                              
rdev->mode_info.coherent_mode_property,
                                              1);
-               if (ASIC_IS_AVIVO(rdev))
+               if (ASIC_IS_AVIVO(rdev)) {
                        drm_connector_attach_property(&radeon_connector->base,
                                                      
rdev->mode_info.underscan_property,
                                                      UNDERSCAN_AUTO);
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     
rdev->mode_info.underscan_hborder_property,
+                                                     0);
+                       drm_connector_attach_property(&radeon_connector->base,
+                                                     
rdev->mode_info.underscan_vborder_property,
+                                                     0);
+               }
                break;
        case DRM_MODE_CONNECTOR_SVIDEO:
        case DRM_MODE_CONNECTOR_Composite:
diff --git a/drivers/gpu/drm/radeon/radeon_display.c 
b/drivers/gpu/drm/radeon/radeon_display.c
index 6dd434a..c465955 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -999,6 +999,24 @@ static int radeon_modeset_create_props(struct 
radeon_device *rdev)
                                      radeon_underscan_enum_list[i].name);
        }
 
+       rdev->mode_info.underscan_hborder_property =
+               drm_property_create(rdev->ddev,
+                                       DRM_MODE_PROP_RANGE,
+                                       "underscan hborder", 2);
+       if (!rdev->mode_info.underscan_hborder_property)
+               return -ENOMEM;
+       rdev->mode_info.underscan_hborder_property->values[0] = 0;
+       rdev->mode_info.underscan_hborder_property->values[1] = 128;
+
+       rdev->mode_info.underscan_vborder_property =
+               drm_property_create(rdev->ddev,
+                                       DRM_MODE_PROP_RANGE,
+                                       "underscan vborder", 2);
+       if (!rdev->mode_info.underscan_vborder_property)
+               return -ENOMEM;
+       rdev->mode_info.underscan_vborder_property->values[0] = 0;
+       rdev->mode_info.underscan_vborder_property->values[1] = 128;
+
        return 0;
 }
 
@@ -1155,8 +1173,14 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc 
*crtc,
                             ((radeon_encoder->underscan_type == 
UNDERSCAN_AUTO) &&
                              drm_detect_hdmi_monitor(radeon_connector->edid) &&
                              is_hdtv_mode(mode)))) {
-                               radeon_crtc->h_border = (mode->hdisplay >> 5) + 
16;
-                               radeon_crtc->v_border = (mode->vdisplay >> 5) + 
16;
+                               if (radeon_encoder->underscan_hborder != 0)
+                                       radeon_crtc->h_border = 
radeon_encoder->underscan_hborder;
+                               else
+                                       radeon_crtc->h_border = (mode->hdisplay 
>> 5) + 16;
+                               if (radeon_encoder->underscan_vborder != 0)
+                                       radeon_crtc->v_border = 
radeon_encoder->underscan_vborder;
+                               else
+                                       radeon_crtc->v_border = (mode->vdisplay 
>> 5) + 16;
                                radeon_crtc->rmx_type = RMX_FULL;
                                src_v = crtc->mode.vdisplay;
                                dst_v = crtc->mode.vdisplay - 
(radeon_crtc->v_border * 2);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h 
b/drivers/gpu/drm/radeon/radeon_mode.h
index 8f93e2b..6f2d22c 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -240,6 +240,8 @@ struct radeon_mode_info {
        struct drm_property *tmds_pll_property;
        /* underscan */
        struct drm_property *underscan_property;
+       struct drm_property *underscan_hborder_property;
+       struct drm_property *underscan_vborder_property;
        /* hardcoded DFP edid from BIOS */
        struct edid *bios_hardcoded_edid;
 
@@ -369,6 +371,8 @@ struct radeon_encoder {
        uint32_t pixel_clock;
        enum radeon_rmx_type rmx_type;
        enum radeon_underscan_type underscan_type;
+       uint32_t underscan_hborder;
+       uint32_t underscan_vborder;
        struct drm_display_mode native_mode;
        void *enc_priv;
        int audio_polling_active;
-- 
1.7.0.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to