[Openchrome-devel] drm-openchrome: 3 commits - drivers/gpu/drm

James Simmons jsimmons at kemper.freedesktop.org
Sat Aug 24 11:19:51 PDT 2013


 drivers/gpu/drm/via/via_analog.c  |    1 
 drivers/gpu/drm/via/via_crtc.c    |   51 ++++++++++++++++-------------
 drivers/gpu/drm/via/via_display.c |    7 ++++
 drivers/gpu/drm/via/via_display.h |    1 
 drivers/gpu/drm/via/via_hdmi.c    |    4 ++
 drivers/gpu/drm/via/via_lvds.c    |   65 +++++++++++++++++++++++---------------
 drivers/gpu/drm/via/via_tmds.c    |    2 +
 7 files changed, 83 insertions(+), 48 deletions(-)

New commits:
commit b7ae94866f18df75dc7ae0b66a29d8853714d7fb
Author: James Simmons <jsimmons at infradead.org>
Date:   Sat Aug 24 14:19:34 2013 -0400

    Only set the frame buffer offset if it actually changes. This helps with flickering when the screen scrolls

diff --git a/drivers/gpu/drm/via/via_crtc.c b/drivers/gpu/drm/via/via_crtc.c
index 9de64ea..fbf0cd0 100644
--- a/drivers/gpu/drm/via/via_crtc.c
+++ b/drivers/gpu/drm/via/via_crtc.c
@@ -987,7 +987,7 @@ via_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode,
 static int
 via_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
 			struct drm_display_mode *adjusted_mode,
-			int x, int y, struct drm_framebuffer *old_fb)
+			int x, int y, struct drm_framebuffer *fb)
 {
 	struct via_crtc *iga = container_of(crtc, struct via_crtc, base);
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
@@ -1136,14 +1136,14 @@ via_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		pll_regs = via_get_clk_value(crtc->dev, clock);
 		via_set_vclock(crtc, pll_regs);
 	}
-	return crtc_funcs->mode_set_base(crtc, x, y, old_fb);
+	return crtc_funcs->mode_set_base(crtc, x, y, fb);
 }
 
 static int
 via_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-			struct drm_framebuffer *old_fb)
+			struct drm_framebuffer *fb)
 {
-	enum mode_set_atomic state = old_fb ? LEAVE_ATOMIC_MODE_SET : ENTER_ATOMIC_MODE_SET;
+	enum mode_set_atomic state = fb ? ENTER_ATOMIC_MODE_SET : LEAVE_ATOMIC_MODE_SET;
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 	struct drm_framebuffer *new_fb = crtc->fb;
 	struct ttm_buffer_object *bo;
@@ -1173,8 +1173,8 @@ via_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	}
 
 	/* Free the old framebuffer if it exist */
-	if (old_fb) {
-		obj = old_fb->helper_private;
+	if (fb) {
+		obj = fb->helper_private;
 		bo = obj->driver_private;
 
 		ret = ttm_bo_unpin(bo, NULL);
@@ -1190,24 +1190,24 @@ via_iga1_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 {
 	struct via_crtc *iga = container_of(crtc, struct via_crtc, base);
 	struct drm_via_private *dev_priv = crtc->dev->dev_private;
+	struct drm_gem_object *crtc_obj = crtc->fb->helper_private;
+	struct ttm_buffer_object *crtc_bo = crtc_obj->driver_private;
 	struct drm_gem_object *obj = fb->helper_private;
 	struct ttm_buffer_object *bo = obj->driver_private;
 	u32 pitch = (x * fb->bits_per_pixel) >> 3, addr;
 
-	/*if ((state == ENTER_ATOMIC_MODE_SET) && (fb != crtc->fb))
-		disable_accel(dev);
-	else
-		restore_accel(dev);*/
-
 	/* Set the framebuffer offset */
 	pitch += y * fb->pitches[0];
 	addr = round_up(bo->offset + pitch, 16) >> 1;
 
-	vga_wcrt(VGABASE, 0x0D, addr & 0xFF);
-	vga_wcrt(VGABASE, 0x0C, (addr >> 8) & 0xFF);
-	/* Yes order of setting these registers matters on some hardware */
-	svga_wcrt_mask(VGABASE, 0x48, ((addr >> 24) & 0x1F), 0x1F);
-	vga_wcrt(VGABASE, 0x34, (addr >> 16) & 0xFF);
+	if ((state == ENTER_ATOMIC_MODE_SET) ||
+	     crtc_bo->offset != bo->offset) {
+		vga_wcrt(VGABASE, 0x0D, addr & 0xFF);
+		vga_wcrt(VGABASE, 0x0C, (addr >> 8) & 0xFF);
+		/* Yes order of setting these registers matters on some hardware */
+		svga_wcrt_mask(VGABASE, 0x48, ((addr >> 24) & 0x1F), 0x1F);
+		vga_wcrt(VGABASE, 0x34, (addr >> 16) & 0xFF);
+	}
 
 	/* Load fetch count registers */
 	pitch = ALIGN(crtc->mode.hdisplay * fb->bits_per_pixel >> 3, 16) >> 4;
@@ -1259,6 +1259,8 @@ via_iga2_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 {
 	struct via_crtc *iga = container_of(crtc, struct via_crtc, base);
 	struct drm_via_private *dev_priv = crtc->dev->dev_private;
+	struct drm_gem_object *crtc_obj = crtc->fb->helper_private;
+	struct ttm_buffer_object *crtc_bo = crtc_obj->driver_private;
 	struct drm_gem_object *obj = fb->helper_private;
 	struct ttm_buffer_object *bo = obj->driver_private;
 	u32 pitch = (x * fb->bits_per_pixel) >> 3, addr;
@@ -1268,13 +1270,16 @@ via_iga2_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 	pitch += y * fb->pitches[0];
 	addr = round_up(bo->offset + pitch, 16);
 
-	/* Bits 9 to 3 of the frame buffer go into bits 7 to 1
-	 * of the register. Bit 0 is for setting tile mode or
-	 * linear mode. A value of zero sets it to linear mode */
-	vga_wcrt(VGABASE, 0x62, ((addr >> 3) & 0x7F) << 1);
-	vga_wcrt(VGABASE, 0x63, (addr >> 10) & 0xFF);
-	vga_wcrt(VGABASE, 0x64, (addr >> 18) & 0xFF);
-	svga_wcrt_mask(VGABASE, 0xA3, ((addr >> 26) & 0x07), 0x07);
+	if ((state == ENTER_ATOMIC_MODE_SET) ||
+	     crtc_bo->offset != bo->offset) {
+		/* Bits 9 to 3 of the frame buffer go into bits 7 to 1
+		 * of the register. Bit 0 is for setting tile mode or
+		 * linear mode. A value of zero sets it to linear mode */
+		vga_wcrt(VGABASE, 0x62, ((addr >> 3) & 0x7F) << 1);
+		vga_wcrt(VGABASE, 0x63, (addr >> 10) & 0xFF);
+		vga_wcrt(VGABASE, 0x64, (addr >> 18) & 0xFF);
+		svga_wcrt_mask(VGABASE, 0xA3, ((addr >> 26) & 0x07), 0x07);
+	}
 
 	/* Load fetch count registers */
 	pitch = ALIGN(crtc->mode.hdisplay * fb->bits_per_pixel >> 3, 16) >> 4;
commit 77d7c613e70826ea3c3221df1ee1f34089643f7b
Author: James Simmons <jsimmons at infradead.org>
Date:   Sat Aug 24 13:16:33 2013 -0400

    Dither will be removed out of the DRM core in the future so we make our LVDS use a private dither property

diff --git a/drivers/gpu/drm/via/via_lvds.c b/drivers/gpu/drm/via/via_lvds.c
index 3cfdcb2..f9a4802 100644
--- a/drivers/gpu/drm/via/via_lvds.c
+++ b/drivers/gpu/drm/via/via_lvds.c
@@ -367,36 +367,27 @@ via_lcd_detect(struct drm_connector *connector,  bool force)
 	return ret;
 }
 
+static const struct drm_prop_enum_list dithering_enum_list[] =
+{
+	{ DRM_MODE_DITHERING_OFF, "Off" },
+	{ DRM_MODE_DITHERING_ON, "On" },
+	{ DRM_MODE_DITHERING_AUTO, "Automatic" },
+};
+
 static int
 via_lcd_set_property(struct drm_connector *connector,
 			struct drm_property *property, uint64_t value)
 {
+	struct via_connector *con = container_of(connector, struct via_connector, base);
 	struct drm_via_private *dev_priv = connector->dev->dev_private;
 	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
 	uint64_t orig;
 	int ret;
 
 	ret = drm_object_property_get_value(&connector->base, property, &orig);
 	if (!ret && (orig != value)) {
-		if (property == dev->mode_config.dithering_mode_property) {
-			u8 reg_value;
-
-			switch (value) {
-			case DRM_MODE_DITHERING_AUTO:
-			case DRM_MODE_DITHERING_ON:
-				reg_value = BIT(0);
-				break;
-
-			case DRM_MODE_DITHERING_OFF:
-				reg_value = 0x00;
-				break;
-
-			default:
-				return -EINVAL;
-			}
-			svga_wcrt_mask(VGABASE, 0x88, reg_value, BIT(0));
-
-		} else if (property == dev->mode_config.scaling_mode_property) {
+		if (property == dev->mode_config.scaling_mode_property) {
 			switch (value) {
 			case DRM_MODE_SCALE_NONE:
 				break;
@@ -414,6 +405,27 @@ via_lcd_set_property(struct drm_connector *connector,
 				return -EINVAL;
 			}
 		}
+
+		list_for_each_entry(prop, &con->props, head) {
+			if (property == prop) {
+				u8 reg_value;
+
+				switch (value) {
+				case DRM_MODE_DITHERING_AUTO:
+				case DRM_MODE_DITHERING_ON:
+					reg_value = BIT(0);
+					break;
+
+				case DRM_MODE_DITHERING_OFF:
+					reg_value = 0x00;
+					break;
+
+				default:
+					return -EINVAL;
+				}
+				svga_wcrt_mask(VGABASE, 0x88, reg_value, BIT(0));
+			}
+		}
 	}
 	return 0;
 }
@@ -646,6 +658,7 @@ via_lvds_init(struct drm_device *dev)
 	struct drm_via_private *dev_priv = dev->dev_private;
 	bool dual_channel = false, is_msb = false;
 	uint64_t dither = DRM_MODE_DITHERING_OFF;
+	struct drm_property *dithering;
 	struct via_connector *con;
 	struct via_encoder *enc;
 	struct edid *edid;
@@ -727,12 +740,13 @@ via_lvds_init(struct drm_device *dev)
 					dev->mode_config.scaling_mode_property,
 					DRM_MODE_SCALE_CENTER);
 
-	drm_mode_create_dithering_property(dev);
-	drm_object_attach_property(&con->base.base,
-					dev->mode_config.dithering_mode_property,
-					dither);
-	via_lcd_set_property(&con->base, dev->mode_config.dithering_mode_property,
-				dither);
+	dithering = drm_property_create_enum(dev, 0, "dithering",
+					     dithering_enum_list,
+					     ARRAY_SIZE(dithering_enum_list));
+	list_add(&dithering->head, &con->props);
+
+	drm_object_attach_property(&con->base.base, dithering, dither);
+	via_lcd_set_property(&con->base, dithering, dither);
 
 	/* Now setup the encoder */
 	drm_encoder_init(dev, &enc->base, &via_lvds_enc_funcs,
commit ac7f86696a7968010b5c90fef9c467f9ddc9ce14
Author: James Simmons <jsimmons at infradead.org>
Date:   Sat Aug 24 12:15:25 2013 -0400

    Enable connectors to have a collection of properties

diff --git a/drivers/gpu/drm/via/via_analog.c b/drivers/gpu/drm/via/via_analog.c
index 84e7b95..5002349 100644
--- a/drivers/gpu/drm/via/via_analog.c
+++ b/drivers/gpu/drm/via/via_analog.c
@@ -123,6 +123,7 @@ via_analog_init(struct drm_device *dev)
 		return;
 	}
 	con = &enc->cons[0];
+	INIT_LIST_HEAD(&con->props);
 
 	/* Piece together our connector */
 	drm_connector_init(dev, &con->base, &via_analog_connector_funcs,
diff --git a/drivers/gpu/drm/via/via_display.c b/drivers/gpu/drm/via/via_display.c
index 1880272..bdc2401 100644
--- a/drivers/gpu/drm/via/via_display.c
+++ b/drivers/gpu/drm/via/via_display.c
@@ -335,6 +335,13 @@ via_connector_set_property(struct drm_connector *connector,
 void
 via_connector_destroy(struct drm_connector *connector)
 {
+	struct via_connector *con = container_of(connector, struct via_connector, base);
+	struct drm_property *property, *tmp;
+
+	list_for_each_entry_safe(property, tmp, &con->props, head)
+		drm_property_destroy(connector->dev, property);
+	list_del(&con->props);
+
 	drm_mode_connector_update_edid_property(connector, NULL);
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
diff --git a/drivers/gpu/drm/via/via_display.h b/drivers/gpu/drm/via/via_display.h
index c914cd7..85d610a 100644
--- a/drivers/gpu/drm/via/via_display.h
+++ b/drivers/gpu/drm/via/via_display.h
@@ -74,6 +74,7 @@ struct via_crtc {
 struct via_connector {
 	struct drm_connector base;
 	struct i2c_adapter *ddc_bus;
+	struct list_head props;
 	uint32_t flags;
 };
 
diff --git a/drivers/gpu/drm/via/via_hdmi.c b/drivers/gpu/drm/via/via_hdmi.c
index 8afe533..45ed77b 100644
--- a/drivers/gpu/drm/via/via_hdmi.c
+++ b/drivers/gpu/drm/via/via_hdmi.c
@@ -675,6 +675,8 @@ via_hdmi_init(struct drm_device *dev, int diport)
 
 	hdmi->base.polled = DRM_CONNECTOR_POLL_HPD;
 	hdmi->base.doublescan_allowed = false;
+	INIT_LIST_HEAD(&hdmi->props);
+
 	switch (dev->pdev->device) {
 	case PCI_DEVICE_ID_VIA_VT3157:
 	case PCI_DEVICE_ID_VIA_VT1122:
@@ -694,6 +696,8 @@ via_hdmi_init(struct drm_device *dev, int diport)
 
 	dvi->base.polled = DRM_CONNECTOR_POLL_HPD;
 	dvi->base.doublescan_allowed = false;
+	INIT_LIST_HEAD(&dvi->props);
+
 	switch (dev->pdev->device) {
 	case PCI_DEVICE_ID_VIA_VT3157:
 	case PCI_DEVICE_ID_VIA_VT3353:
diff --git a/drivers/gpu/drm/via/via_lvds.c b/drivers/gpu/drm/via/via_lvds.c
index 3b9e43f..3cfdcb2 100644
--- a/drivers/gpu/drm/via/via_lvds.c
+++ b/drivers/gpu/drm/via/via_lvds.c
@@ -657,6 +657,7 @@ via_lvds_init(struct drm_device *dev)
 		return;
 	}
 	con = &enc->cons[0];
+	INIT_LIST_HEAD(&con->props);
 
 	drm_connector_init(dev, &con->base, &via_lcd_connector_funcs,
 				DRM_MODE_CONNECTOR_LVDS);
diff --git a/drivers/gpu/drm/via/via_tmds.c b/drivers/gpu/drm/via/via_tmds.c
index b1e6148..86f0ef7 100644
--- a/drivers/gpu/drm/via/via_tmds.c
+++ b/drivers/gpu/drm/via/via_tmds.c
@@ -169,6 +169,7 @@ via_tmds_init(struct drm_device *dev)
 	con->ddc_bus = via_find_ddc_bus(i2c_port);
 	con->base.doublescan_allowed = false;
 	con->base.interlace_allowed = true;
+	INIT_LIST_HEAD(&con->props);
 
 	drm_mode_connector_attach_encoder(&con->base, &enc->base);
 
@@ -181,6 +182,7 @@ via_tmds_init(struct drm_device *dev)
 	con->ddc_bus = via_find_ddc_bus(i2c_port);
 	con->base.doublescan_allowed = false;
 	con->base.interlace_allowed = true;
+	INIT_LIST_HEAD(&con->props);
 
 	drm_mode_connector_attach_encoder(&con->base, &enc->base);
 	return 0;


More information about the Openchrome-devel mailing list