drm/nouveau: add overscan compensation connector properties

Exposes the same connector properties as the Radeon implementation, however
their behaviour isn't exactly the same.  The primary difference being that
unless both hborder/vborder have been defined by the user, the driver will
keep the aspect ratio of the overscanned area the same as the mode the
display is programmed for.

Enabled for digital outputs on GeForce 8 and up, excluding GF119.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 017d4ea..9bc9d64 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -152,17 +152,50 @@
 	.output_poll_changed = nouveau_fbcon_output_poll_changed,
 };
 
+
+struct drm_prop_enum_list {
+	int type;
+	char *name;
+};
+
+static struct drm_prop_enum_list nouveau_underscan_enum_list[] = {
+	{ UNDERSCAN_OFF, "off" },
+	{ UNDERSCAN_ON, "on" },
+	{ UNDERSCAN_AUTO, "auto" },
+};
+
 int
 nouveau_display_create(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_display_engine *disp = &dev_priv->engine.display;
-	int ret;
+	int ret, cnt, i;
 
 	drm_mode_config_init(dev);
 	drm_mode_create_scaling_mode_property(dev);
 	drm_mode_create_dithering_property(dev);
 
+	cnt = ARRAY_SIZE(nouveau_underscan_enum_list);
+	disp->underscan_property = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+						       "underscan", cnt);
+	for (i = 0; i < cnt; i++) {
+		drm_property_add_enum(disp->underscan_property, i,
+				      nouveau_underscan_enum_list[i].type,
+				      nouveau_underscan_enum_list[i].name);
+	}
+
+	disp->underscan_hborder_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "underscan hborder", 2);
+	disp->underscan_hborder_property->values[0] = 0;
+	disp->underscan_hborder_property->values[1] = 128;
+
+	disp->underscan_vborder_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "underscan vborder", 2);
+	disp->underscan_vborder_property->values[0] = 0;
+	disp->underscan_vborder_property->values[1] = 128;
+
 	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
 	dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1);