All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] atomic modesetting for cirrus
@ 2017-08-18 15:49 Varad Gautam
  2017-08-18 15:49 ` [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
                   ` (13 more replies)
  0 siblings, 14 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel
  Cc: Zach Reizner, Tomeu Vizoso, Daniel Vetter,
	Stéphane Marchesin, Gustavo Padovan, Gerd Hoffmann,
	Dave Airlie, Gabriel Krisman Bertazi

Hello,

This series converts drm/cirrus to support atomic modesetting for the
emulated CL GD-54xx hw in qemu.

Patches 1-7 are general fixes and improvements, in preparation for atomic.
Patch 8 provides dmabuf export for cirrus.
Patch 9-11 add universal primary plane support and rework the driver to use
  atomic transition helpers for legacy modesetting.
Patch 12 moves away from legacy modesetting entirely to use atomic handlers.
Patch 13 adds atomic cursor plane.
Patch 14 flips on DRIVER_ATOMIC.

I have tested this with igt and chromeos/drm-tests (details in patch 14).

Fun trivia from the GD-54xx TRM, 1996! It boasts 'optimized PCI burst write,
which supports PCI writes to the frame buffer at greater than 55 Mbytes
per second.'

Dominik Behr (1):
  drm/cirrus: initialize start and size fields

Stéphane Marchesin (1):
  drm/cirrus: Use 32bpp by default

Varad Gautam (10):
  drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram
  drm/cirrus: unregister connector on destroy
  drm/cirrus: add drm_read to cirrus_driver_fops
  drm/cirrus: do not disable outputs on fbdev init for atomic.
  drm/cirrus: use universal plane interfaces for primary plane
  drm/cirrus: use atomic transition helpers for plane and crtc
  drm/cirrus: send vblank on crtc atomic_flush
  drm/cirrus: use atomic handlers for plane and crtc
  drm/cirrus: implement atomic hardware cursor support
  drm/cirrus: advertise DRIVER_ATOMIC

Zach Reizner (2):
  drm/cirrus: hardcode vram size
  drm/cirrus: implement PRIME export for cirrus

 drivers/gpu/drm/cirrus/Makefile       |   2 +-
 drivers/gpu/drm/cirrus/cirrus_drv.c   |  17 +-
 drivers/gpu/drm/cirrus/cirrus_drv.h   |  25 ++
 drivers/gpu/drm/cirrus/cirrus_fbdev.c |   6 +-
 drivers/gpu/drm/cirrus/cirrus_main.c  |  23 +-
 drivers/gpu/drm/cirrus/cirrus_mode.c  | 681 ++++++++++++++++++++++++++--------
 drivers/gpu/drm/cirrus/cirrus_prime.c |  63 ++++
 drivers/gpu/drm/cirrus/cirrus_ttm.c   |  55 ++-
 8 files changed, 705 insertions(+), 167 deletions(-)
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_prime.c

Thanks,
Varad
-- 
2.13.1

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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-09-04 10:41   ` Gabriel Krisman Bertazi
  2017-08-18 15:49 ` [PATCH 02/14] drm/cirrus: unregister connector on destroy Varad Gautam
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

add a cirrus_bo_unpin call, and move bo_{reserve,unreserve} operations
to bo_{pin,unpin} to ensure correct pinning/unpinning and simplify the call
sequence.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_drv.h  |  1 +
 drivers/gpu/drm/cirrus/cirrus_mode.c | 14 ++-------
 drivers/gpu/drm/cirrus/cirrus_ttm.c  | 55 +++++++++++++++++++++++++++++-------
 3 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 8690352d96f7..8cdf6b0db4a7 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -262,6 +262,7 @@ static inline void cirrus_bo_unreserve(struct cirrus_bo *bo)
 
 int cirrus_bo_push_sysram(struct cirrus_bo *bo);
 int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr);
+int cirrus_bo_unpin(struct cirrus_bo *bo);
 
 extern int cirrus_bpp;
 
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 53f6f0f84206..21d75e7e4abc 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -131,26 +131,17 @@ static int cirrus_crtc_do_set_base(struct drm_crtc *crtc,
 		cirrus_fb = to_cirrus_framebuffer(fb);
 		obj = cirrus_fb->obj;
 		bo = gem_to_cirrus_bo(obj);
-		ret = cirrus_bo_reserve(bo, false);
-		if (ret)
-			return ret;
+		cirrus_bo_unpin(bo);
 		cirrus_bo_push_sysram(bo);
-		cirrus_bo_unreserve(bo);
 	}
 
 	cirrus_fb = to_cirrus_framebuffer(crtc->primary->fb);
 	obj = cirrus_fb->obj;
 	bo = gem_to_cirrus_bo(obj);
 
-	ret = cirrus_bo_reserve(bo, false);
-	if (ret)
-		return ret;
-
 	ret = cirrus_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-	if (ret) {
-		cirrus_bo_unreserve(bo);
+	if (ret)
 		return ret;
-	}
 
 	if (&cdev->mode_info.gfbdev->gfb == cirrus_fb) {
 		/* if pushing console in kmap it */
@@ -158,7 +149,6 @@ static int cirrus_crtc_do_set_base(struct drm_crtc *crtc,
 		if (ret)
 			DRM_ERROR("failed to kmap fbcon\n");
 	}
-	cirrus_bo_unreserve(bo);
 
 	cirrus_set_start_address(crtc, (u32)gpu_addr);
 	return 0;
diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c b/drivers/gpu/drm/cirrus/cirrus_ttm.c
index 1ff1838c0d44..a91d31da90ba 100644
--- a/drivers/gpu/drm/cirrus/cirrus_ttm.c
+++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c
@@ -358,12 +358,17 @@ static inline u64 cirrus_bo_gpu_offset(struct cirrus_bo *bo)
 
 int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr)
 {
-	int i, ret;
+	int i, ret = 0;
+
+	ret = cirrus_bo_reserve(bo, false);
+	if (ret)
+		return ret;
 
 	if (bo->pin_count) {
 		bo->pin_count++;
 		if (gpu_addr)
 			*gpu_addr = cirrus_bo_gpu_offset(bo);
+		goto out;
 	}
 
 	cirrus_ttm_placement(bo, pl_flag);
@@ -371,24 +376,51 @@ int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr)
 		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
 	ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
 	if (ret)
-		return ret;
+		goto out;
 
 	bo->pin_count = 1;
 	if (gpu_addr)
 		*gpu_addr = cirrus_bo_gpu_offset(bo);
-	return 0;
+
+out:
+	cirrus_bo_unreserve(bo);
+	return ret;
+}
+
+int cirrus_bo_unpin(struct cirrus_bo *bo)
+{
+	int i, ret = 0;
+
+	ret = cirrus_bo_reserve(bo, false);
+	if (ret)
+		return ret;
+
+	if (!bo->pin_count || --bo->pin_count)
+		goto out;
+
+	for (i = 0; i < bo->placement.num_placement; i++)
+		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
+	ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
+	if (ret)
+		goto out;
+
+out:
+	cirrus_bo_unreserve(bo);
+	return ret;
 }
 
 int cirrus_bo_push_sysram(struct cirrus_bo *bo)
 {
 	int i, ret;
-	if (!bo->pin_count) {
+
+	ret = cirrus_bo_reserve(bo, false);
+	if (ret)
+		return ret;
+
+	if (bo->pin_count) {
 		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
+		goto out;
 	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
 
 	if (bo->kmap.virtual)
 		ttm_bo_kunmap(&bo->kmap);
@@ -400,9 +432,12 @@ int cirrus_bo_push_sysram(struct cirrus_bo *bo)
 	ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
 	if (ret) {
 		DRM_ERROR("pushing to VRAM failed\n");
-		return ret;
+		goto out;
 	}
-	return 0;
+
+out:
+	cirrus_bo_unreserve(bo);
+	return ret;
 }
 
 int cirrus_mmap(struct file *filp, struct vm_area_struct *vma)
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 02/14] drm/cirrus: unregister connector on destroy
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
  2017-08-18 15:49 ` [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-19  6:10   ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 03/14] drm/cirrus: add drm_read to cirrus_driver_fops Varad Gautam
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

add missing unregister call on connector destroy.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_mode.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 21d75e7e4abc..6032978a2797 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -492,6 +492,7 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
 
 static void cirrus_connector_destroy(struct drm_connector *connector)
 {
+	drm_connector_unregister(connector);
 	drm_connector_cleanup(connector);
 	kfree(connector);
 }
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 03/14] drm/cirrus: add drm_read to cirrus_driver_fops
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
  2017-08-18 15:49 ` [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
  2017-08-18 15:49 ` [PATCH 02/14] drm/cirrus: unregister connector on destroy Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 04/14] drm/cirrus: do not disable outputs on fbdev init for atomic Varad Gautam
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

allow reading the drm file from userspace.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index d893ea21a359..bae34f5c2c02 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -122,6 +122,7 @@ static int cirrus_pm_resume(struct device *dev)
 static const struct file_operations cirrus_driver_fops = {
 	.owner = THIS_MODULE,
 	.open = drm_open,
+	.read = drm_read,
 	.release = drm_release,
 	.unlocked_ioctl = drm_ioctl,
 	.mmap = cirrus_mmap,
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 04/14] drm/cirrus: do not disable outputs on fbdev init for atomic.
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (2 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 03/14] drm/cirrus: add drm_read to cirrus_driver_fops Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 05/14] drm/cirrus: initialize start and size fields Varad Gautam
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

drm_helper_disable_unused_functions should not be called by atomic drivers,
so disable it for later patches.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_fbdev.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 7fa58eeadc9d..ed96dae1c205 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -296,9 +296,6 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
 	if (ret)
 		return ret;
 
-	/* disable all the possible outputs/crtcs before entering KMS mode */
-	drm_helper_disable_unused_functions(cdev->dev);
-
 	return drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
 }
 
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 05/14] drm/cirrus: initialize start and size fields
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (3 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 04/14] drm/cirrus: do not disable outputs on fbdev init for atomic Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 06/14] drm/cirrus: Use 32bpp by default Varad Gautam
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Zhuo-hao Lee, Stéphane Marchesin

From: Dominik Behr <dbehr@chromium.org>

initialize start and size fields in fb info
so user space drivers like fbdev can map the memory

cherry-pick from 3.14 to 3.18 kernel to let VMtest pass

dmesg now shows proper size and fb start

initially reviewed for chromiumos at:
https://chromium-review.googlesource.com/167396
https://chromium-review.googlesource.com/282933
https://chromium-review.googlesource.com/339092

Signed-off-by: Dominik Behr <dbehr@chromium.org>
Signed-off-by: Zhuo-hao Lee <zhuo-hao.lee@intel.com>
Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
---
 drivers/gpu/drm/cirrus/cirrus_fbdev.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index ed96dae1c205..4bc7d8f60e97 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -232,6 +232,9 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
 	info->screen_base = sysram;
 	info->screen_size = size;
 
+	info->fix.smem_start = cdev->dev->mode_config.fb_base;
+	info->fix.smem_len = size;
+
 	info->fix.mmio_start = 0;
 	info->fix.mmio_len = 0;
 
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 06/14] drm/cirrus: Use 32bpp by default
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (4 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 05/14] drm/cirrus: initialize start and size fields Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-19  8:32   ` Matthew Garrett
  2017-08-18 15:49 ` [PATCH 07/14] drm/cirrus: hardcode vram size Varad Gautam
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Stéphane Marchesin

From: Stéphane Marchesin <marcheu@chromium.org>

initially reviewed for ChromiumOS at:
https://chromium-review.googlesource.com/339093
Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
---
 drivers/gpu/drm/cirrus/cirrus_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index bae34f5c2c02..dfaeea92d344 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -16,11 +16,11 @@
 #include "cirrus_drv.h"
 
 int cirrus_modeset = -1;
-int cirrus_bpp = 24;
+int cirrus_bpp = 32;
 
 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
 module_param_named(modeset, cirrus_modeset, int, 0400);
-MODULE_PARM_DESC(bpp, "Max bits-per-pixel (default:24)");
+MODULE_PARM_DESC(bpp, "Max bits-per-pixel (default:32)");
 module_param_named(bpp, cirrus_bpp, int, 0400);
 
 /*
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 07/14] drm/cirrus: hardcode vram size
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (5 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 06/14] drm/cirrus: Use 32bpp by default Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 08/14] drm/cirrus: implement PRIME export for cirrus Varad Gautam
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Stéphane Marchesin, Zach Reizner

From: Zach Reizner <zachr@google.com>

There is no reliable way of detecting actual VRAM size, which is
important in the case of cirrus because cursor data is always stored in
the last 16K of VRAM. Because qemu effectivaly hardcodes 4MB but reports
32MB, we hardcode 4MB in the cirrus driver to ensure the cursor works
properly.

initially reviewed at: https://chromium-review.googlesource.com/411344
Signed-off-by: Zach Reizner <zachr@chromium.org>
CC: Stéphane Marchesin <marcheu@chromium.org>
---
 drivers/gpu/drm/cirrus/cirrus_main.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index e7fc95f63dca..c92ccb00db62 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -98,7 +98,12 @@ static int cirrus_vram_init(struct cirrus_device *cdev)
 {
 	/* BAR 0 is VRAM */
 	cdev->mc.vram_base = pci_resource_start(cdev->dev->pdev, 0);
-	cdev->mc.vram_size = pci_resource_len(cdev->dev->pdev, 0);
+
+	/*
+	 * While we can use the entire PCI bar for VRAM, qemu always expects to
+	 * find the cursor data at the 4M - 16K point.
+	 */
+	cdev->mc.vram_size = 4 * 1024 * 1024;
 
 	if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size,
 				"cirrusdrmfb_vram")) {
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 08/14] drm/cirrus: implement PRIME export for cirrus
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (6 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 07/14] drm/cirrus: hardcode vram size Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 09/14] drm/cirrus: use universal plane interfaces for primary plane Varad Gautam
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Stphane Marchesin, Zach Reizner, Varad Gautam

From: Zach Reizner <zachr@chromium.org>

This patch implements PRIME export, but not import for cirrus.

initially reviewed at:
https://chromium-review.googlesource.com/229688
https://chromium-review.googlesource.com/339057

Signed-off-by: Zach Reizner <zachr@chromium.org>
Signed-off-by: Stphane Marchesin <marcheu@chromium.org>
Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/Makefile       |  2 +-
 drivers/gpu/drm/cirrus/cirrus_drv.c   | 11 +++++-
 drivers/gpu/drm/cirrus/cirrus_drv.h   | 10 ++++++
 drivers/gpu/drm/cirrus/cirrus_prime.c | 63 +++++++++++++++++++++++++++++++++++
 4 files changed, 84 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/cirrus/cirrus_prime.c

diff --git a/drivers/gpu/drm/cirrus/Makefile b/drivers/gpu/drm/cirrus/Makefile
index 919c0a336c97..f6bcc21454c6 100644
--- a/drivers/gpu/drm/cirrus/Makefile
+++ b/drivers/gpu/drm/cirrus/Makefile
@@ -1,4 +1,4 @@
 cirrus-y  := cirrus_main.o cirrus_mode.o \
-	cirrus_drv.o cirrus_fbdev.o cirrus_ttm.o
+	cirrus_drv.o cirrus_fbdev.o cirrus_ttm.o cirrus_prime.o
 
 obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index dfaeea92d344..dca7a3f4791d 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -130,7 +130,7 @@ static const struct file_operations cirrus_driver_fops = {
 	.compat_ioctl = drm_compat_ioctl,
 };
 static struct drm_driver driver = {
-	.driver_features = DRIVER_MODESET | DRIVER_GEM,
+	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
 	.load = cirrus_driver_load,
 	.unload = cirrus_driver_unload,
 	.set_busid = drm_pci_set_busid,
@@ -145,6 +145,15 @@ static struct drm_driver driver = {
 	.dumb_create = cirrus_dumb_create,
 	.dumb_map_offset = cirrus_dumb_mmap_offset,
 	.dumb_destroy = drm_gem_dumb_destroy,
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_export = drm_gem_prime_export,
+	.gem_prime_import = drm_gem_prime_import,
+	.gem_prime_pin = cirrus_gem_prime_pin,
+	.gem_prime_get_sg_table = cirrus_gem_prime_get_sg_table,
+	.gem_prime_import_sg_table = cirrus_gem_prime_import_sg_table,
+	.gem_prime_vmap = cirrus_gem_prime_vmap,
+	.gem_prime_vunmap = cirrus_gem_prime_vunmap,
 };
 
 static const struct dev_pm_ops cirrus_pm_ops = {
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 8cdf6b0db4a7..29de4f0dbd01 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -164,6 +164,7 @@ struct cirrus_bo {
 	struct ttm_buffer_object bo;
 	struct ttm_placement placement;
 	struct ttm_bo_kmap_obj kmap;
+	struct ttm_bo_kmap_obj dma_buf_vmap;
 	struct drm_gem_object gem;
 	struct ttm_place placements[3];
 	int pin_count;
@@ -264,6 +265,15 @@ int cirrus_bo_push_sysram(struct cirrus_bo *bo);
 int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr);
 int cirrus_bo_unpin(struct cirrus_bo *bo);
 
+struct sg_table *cirrus_gem_prime_get_sg_table(struct drm_gem_object *obj);
+void *cirrus_gem_prime_vmap(struct drm_gem_object *obj);
+void cirrus_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+struct drm_gem_object *cirrus_gem_prime_import_sg_table(
+				struct drm_device *dev,
+				struct dma_buf_attachment *attach,
+				struct sg_table *sgt);
+int cirrus_gem_prime_pin(struct drm_gem_object *obj);
+
 extern int cirrus_bpp;
 
 #endif				/* __CIRRUS_DRV_H__ */
diff --git a/drivers/gpu/drm/cirrus/cirrus_prime.c b/drivers/gpu/drm/cirrus/cirrus_prime.c
new file mode 100644
index 000000000000..a7fe6c73bfb6
--- /dev/null
+++ b/drivers/gpu/drm/cirrus/cirrus_prime.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2014 The Chromium OS Authors
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License version 2. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ */
+
+#include <drm/ttm/ttm_page_alloc.h>
+#include <drm/drmP.h>
+#include "cirrus_drv.h"
+
+struct sg_table *cirrus_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+	struct cirrus_bo *cirrusbo = gem_to_cirrus_bo(obj);
+	unsigned long npages = cirrusbo->bo.num_pages;
+
+	return drm_prime_pages_to_sg(cirrusbo->bo.ttm->pages, npages);
+}
+
+void *cirrus_gem_prime_vmap(struct drm_gem_object *obj)
+{
+	struct cirrus_bo *cirrusbo = gem_to_cirrus_bo(obj);
+	int ret;
+
+	ret = ttm_bo_kmap(&cirrusbo->bo, 0, cirrusbo->bo.num_pages,
+			  &cirrusbo->dma_buf_vmap);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return cirrusbo->dma_buf_vmap.virtual;
+}
+
+void cirrus_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+	struct cirrus_bo *cirrusbo = gem_to_cirrus_bo(obj);
+
+	ttm_bo_kunmap(&cirrusbo->dma_buf_vmap);
+}
+
+struct drm_gem_object *cirrus_gem_prime_import_sg_table(
+				struct drm_device *dev,
+				struct dma_buf_attachment *attach,
+				struct sg_table *sgt)
+{
+	return NULL;
+}
+
+int cirrus_gem_prime_pin(struct drm_gem_object *obj)
+{
+	struct cirrus_bo *cirrusbo = gem_to_cirrus_bo(obj);
+	int ret = 0;
+
+	ret = cirrus_bo_pin(cirrusbo, TTM_PL_FLAG_SYSTEM, NULL);
+	if (ret)
+		goto out;
+
+	ttm_pool_populate(cirrusbo->bo.ttm);
+
+out:
+	return ret;
+}
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 09/14] drm/cirrus: use universal plane interfaces for primary plane
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (7 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 08/14] drm/cirrus: implement PRIME export for cirrus Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-09-04 11:14   ` Gabriel Krisman Bertazi
  2017-08-18 15:49 ` [PATCH 10/14] drm/cirrus: use atomic transition helpers for plane and crtc Varad Gautam
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

cirrus exposes one legacy primary plane tied to the crtc. convert this to
use the universal planes interface in preparation for atomic.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_mode.c | 44 ++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 6032978a2797..2994dd391850 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -358,12 +358,29 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
 	.load_lut = cirrus_crtc_load_lut,
 };
 
+static const uint32_t cirrus_plane_formats[] = {
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_RGB565,
+};
+
+static const struct drm_plane_funcs cirrus_plane_funcs = {
+	.update_plane	= drm_primary_helper_update,
+	.disable_plane	= drm_primary_helper_disable,
+	.destroy	= drm_primary_helper_destroy,
+};
+
+static const struct drm_plane_helper_funcs cirrus_plane_helper_funcs = {
+};
+
 /* CRTC setup */
 static void cirrus_crtc_init(struct drm_device *dev)
 {
 	struct cirrus_device *cdev = dev->dev_private;
 	struct cirrus_crtc *cirrus_crtc;
-	int i;
+	struct drm_plane *primary;
+	int i, ret;
 
 	cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
 			      (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -372,8 +389,23 @@ static void cirrus_crtc_init(struct drm_device *dev)
 	if (cirrus_crtc == NULL)
 		return;
 
-	drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs);
+	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+	if (primary == NULL)
+		goto cleanup_crtc;
 
+	drm_plane_helper_add(primary, &cirrus_plane_helper_funcs);
+	ret = drm_universal_plane_init(dev, primary, 1,
+				       &cirrus_plane_funcs,
+				       cirrus_plane_formats,
+				       ARRAY_SIZE(cirrus_plane_formats),
+				       DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret)
+		goto cleanup;
+
+	ret = drm_crtc_init_with_planes(dev, &cirrus_crtc->base, primary, NULL,
+					&cirrus_crtc_funcs, NULL);
+	if (ret)
+		goto cleanup;
 	drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
 	cdev->mode_info.crtc = cirrus_crtc;
 
@@ -384,6 +416,14 @@ static void cirrus_crtc_init(struct drm_device *dev)
 	}
 
 	drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
+	return;
+
+cleanup:
+	drm_plane_cleanup(primary);
+	kfree(primary);
+cleanup_crtc:
+	kfree(cirrus_crtc);
+	return;
 }
 
 /** Sets the color ramps on behalf of fbcon */
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 10/14] drm/cirrus: use atomic transition helpers for plane and crtc
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (8 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 09/14] drm/cirrus: use universal plane interfaces for primary plane Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 11/14] drm/cirrus: send vblank on crtc atomic_flush Varad Gautam
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

split the driver to fit into atomic semantics, and switch to using
the atomic transition layer helpers for legacy modesetting.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_drv.h  |   1 +
 drivers/gpu/drm/cirrus/cirrus_main.c |   3 +
 drivers/gpu/drm/cirrus/cirrus_mode.c | 350 ++++++++++++++++++++++-------------
 3 files changed, 227 insertions(+), 127 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 29de4f0dbd01..d680815f23e6 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -168,6 +168,7 @@ struct cirrus_bo {
 	struct drm_gem_object gem;
 	struct ttm_place placements[3];
 	int pin_count;
+	u64 gpu_addr;
 };
 #define gem_to_cirrus_bo(gobj) container_of((gobj), struct cirrus_bo, gem)
 
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index c92ccb00db62..7d0431bbc6e3 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -9,6 +9,7 @@
  *          Dave Airlie
  */
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 
 #include "cirrus_drv.h"
@@ -82,6 +83,8 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
 
 static const struct drm_mode_config_funcs cirrus_mode_funcs = {
 	.fb_create = cirrus_user_framebuffer_create,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 /* Unmap the framebuffer from the core and release the memory */
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 2994dd391850..eda3c4d18b37 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -15,6 +15,8 @@
  * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
  */
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
 
@@ -91,95 +93,20 @@ static void cirrus_crtc_dpms(struct drm_crtc *crtc, int mode)
 	WREG_GFX(0xe, gr0e);
 }
 
-static void cirrus_set_start_address(struct drm_crtc *crtc, unsigned offset)
-{
-	struct cirrus_device *cdev = crtc->dev->dev_private;
-	u32 addr;
-	u8 tmp;
-
-	addr = offset >> 2;
-	WREG_CRT(0x0c, (u8)((addr >> 8) & 0xff));
-	WREG_CRT(0x0d, (u8)(addr & 0xff));
-
-	WREG8(CRT_INDEX, 0x1b);
-	tmp = RREG8(CRT_DATA);
-	tmp &= 0xf2;
-	tmp |= (addr >> 16) & 0x01;
-	tmp |= (addr >> 15) & 0x0c;
-	WREG_CRT(0x1b, tmp);
-	WREG8(CRT_INDEX, 0x1d);
-	tmp = RREG8(CRT_DATA);
-	tmp &= 0x7f;
-	tmp |= (addr >> 12) & 0x80;
-	WREG_CRT(0x1d, tmp);
-}
-
-/* cirrus is different - we will force move buffers out of VRAM */
-static int cirrus_crtc_do_set_base(struct drm_crtc *crtc,
-				struct drm_framebuffer *fb,
-				int x, int y, int atomic)
-{
-	struct cirrus_device *cdev = crtc->dev->dev_private;
-	struct drm_gem_object *obj;
-	struct cirrus_framebuffer *cirrus_fb;
-	struct cirrus_bo *bo;
-	int ret;
-	u64 gpu_addr;
-
-	/* push the previous fb to system ram */
-	if (!atomic && fb) {
-		cirrus_fb = to_cirrus_framebuffer(fb);
-		obj = cirrus_fb->obj;
-		bo = gem_to_cirrus_bo(obj);
-		cirrus_bo_unpin(bo);
-		cirrus_bo_push_sysram(bo);
-	}
-
-	cirrus_fb = to_cirrus_framebuffer(crtc->primary->fb);
-	obj = cirrus_fb->obj;
-	bo = gem_to_cirrus_bo(obj);
-
-	ret = cirrus_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-	if (ret)
-		return ret;
-
-	if (&cdev->mode_info.gfbdev->gfb == cirrus_fb) {
-		/* if pushing console in kmap it */
-		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
-		if (ret)
-			DRM_ERROR("failed to kmap fbcon\n");
-	}
-
-	cirrus_set_start_address(crtc, (u32)gpu_addr);
-	return 0;
-}
-
-static int cirrus_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-			     struct drm_framebuffer *old_fb)
-{
-	return cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);
-}
-
 /*
- * The meat of this driver. The core passes us a mode and we have to program
- * it. The modesetting here is the bare minimum required to satisfy the qemu
- * emulation of this hardware, and running this against a real device is
- * likely to result in an inadequately programmed mode. We've already had
- * the opportunity to modify the mode, so whatever we receive here should
- * be something that can be correctly programmed and displayed
+ * The core passes us a mode and we have to program it. The modesetting here
+ * is the bare minimum required to satisfy the qemu emulation of this
+ * hardware, and running this against a real device is likely to result in
+ * an inadequately programmed mode.
  */
-static int cirrus_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)
+static void cirrus_mode_set_nofb(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct cirrus_device *cdev = dev->dev_private;
-	const struct drm_framebuffer *fb = crtc->primary->fb;
+	struct drm_display_mode *mode = &crtc->mode;
 	int hsyncstart, hsyncend, htotal, hdispend;
 	int vtotal, vdispend;
 	int tmp;
-	int sr07 = 0, hdr = 0;
 
 	htotal = mode->htotal / 8;
 	hsyncend = mode->hsync_end / 8;
@@ -244,54 +171,11 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc,
 	/* Disable Hercules/CGA compatibility */
 	WREG_CRT(VGA_CRTC_MODE, 0x03);
 
-	WREG8(SEQ_INDEX, 0x7);
-	sr07 = RREG8(SEQ_DATA);
-	sr07 &= 0xe0;
-	hdr = 0;
-	switch (fb->format->cpp[0] * 8) {
-	case 8:
-		sr07 |= 0x11;
-		break;
-	case 16:
-		sr07 |= 0x17;
-		hdr = 0xc1;
-		break;
-	case 24:
-		sr07 |= 0x15;
-		hdr = 0xc5;
-		break;
-	case 32:
-		sr07 |= 0x19;
-		hdr = 0xc5;
-		break;
-	default:
-		return -1;
-	}
-
-	WREG_SEQ(0x7, sr07);
-
-	/* Program the pitch */
-	tmp = fb->pitches[0] / 8;
-	WREG_CRT(VGA_CRTC_OFFSET, tmp);
-
-	/* Enable extended blanking and pitch bits, and enable full memory */
-	tmp = 0x22;
-	tmp |= (fb->pitches[0] >> 7) & 0x10;
-	tmp |= (fb->pitches[0] >> 6) & 0x40;
-	WREG_CRT(0x1b, tmp);
-
 	/* Enable high-colour modes */
 	WREG_GFX(VGA_GFX_MODE, 0x40);
 
 	/* And set graphics mode */
 	WREG_GFX(VGA_GFX_MISC, 0x01);
-
-	WREG_HDR(hdr);
-	cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);
-
-	/* Unblank (needed on S3 resume, vgabios doesn't do it then) */
-	outb(0x20, 0x3c0);
-	return 0;
 }
 
 /*
@@ -347,17 +231,34 @@ static const struct drm_crtc_funcs cirrus_crtc_funcs = {
 	.gamma_set = cirrus_crtc_gamma_set,
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = cirrus_crtc_destroy,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
 static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
 	.dpms = cirrus_crtc_dpms,
-	.mode_set = cirrus_crtc_mode_set,
-	.mode_set_base = cirrus_crtc_mode_set_base,
+	.mode_set = drm_helper_crtc_mode_set,
+	.mode_set_base = drm_helper_crtc_mode_set_base,
+	.mode_set_nofb = cirrus_mode_set_nofb,
 	.prepare = cirrus_crtc_prepare,
 	.commit = cirrus_crtc_commit,
 	.load_lut = cirrus_crtc_load_lut,
 };
 
+static int cirrus_plane_update(struct drm_plane *plane,
+			       struct drm_crtc *crtc,
+			       struct drm_framebuffer *fb, int crtc_x,
+			       int crtc_y, unsigned int crtc_w,
+			       unsigned int crtc_h, uint32_t src_x,
+			       uint32_t src_y, uint32_t src_w, uint32_t src_h,
+			       struct drm_modeset_acquire_ctx *ctx)
+{
+	return drm_plane_helper_update(plane, crtc, fb,
+				       crtc_x, crtc_y, crtc_w,
+				       crtc_h, src_x, src_y, src_w, src_h);
+}
+
 static const uint32_t cirrus_plane_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -366,12 +267,202 @@ static const uint32_t cirrus_plane_formats[] = {
 };
 
 static const struct drm_plane_funcs cirrus_plane_funcs = {
-	.update_plane	= drm_primary_helper_update,
+	.update_plane	= cirrus_plane_update,
 	.disable_plane	= drm_primary_helper_disable,
 	.destroy	= drm_primary_helper_destroy,
+	.reset	= drm_atomic_helper_plane_reset,
+	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
 };
 
+static int cirrus_plane_prepare_fb(struct drm_plane *plane,
+				   struct drm_plane_state *new_state)
+{
+	struct cirrus_device *cdev = plane->dev->dev_private;
+	struct drm_gem_object *obj;
+	struct cirrus_framebuffer *cirrus_fb;
+	struct cirrus_bo *bo;
+	int ret;
+
+	if (!new_state->fb)
+		return 0;
+
+	if (plane->old_fb) {
+		cirrus_fb = to_cirrus_framebuffer(plane->old_fb);
+		obj = cirrus_fb->obj;
+		bo = gem_to_cirrus_bo(obj);
+		cirrus_bo_push_sysram(bo);
+	}
+
+	cirrus_fb = to_cirrus_framebuffer(new_state->fb);
+	obj = cirrus_fb->obj;
+	bo = gem_to_cirrus_bo(obj);
+
+	ret = cirrus_bo_pin(bo, TTM_PL_FLAG_VRAM, &bo->gpu_addr);
+	if (ret)
+		return ret;
+
+	if (&cdev->mode_info.gfbdev->gfb == cirrus_fb) {
+		/* if pushing console in kmap it */
+		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void cirrus_plane_cleanup_fb(struct drm_plane *plane,
+				    struct drm_plane_state *old_state)
+{
+	struct drm_gem_object *obj;
+	struct cirrus_bo *bo;
+
+	if (!plane->state->fb) {
+		/* we never executed prepare_fb, so there's nothing to
+		 * unpin.
+		 */
+		return;
+	}
+
+	obj = to_cirrus_framebuffer(plane->state->fb)->obj;
+	bo = gem_to_cirrus_bo(obj);
+
+	cirrus_bo_unpin(bo);
+}
+
+static int cirrus_plane_atomic_check(struct drm_plane *plane,
+				     struct drm_plane_state *state)
+{
+	struct cirrus_device *cdev = plane->dev->dev_private;
+	struct drm_framebuffer *fb = state->fb;
+	struct drm_crtc *crtc = state->crtc ? state->crtc : plane->crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_rect clip = { 0 };
+	int ret;
+
+	if (!crtc || !fb)
+		return 0;
+
+	if (!cirrus_check_framebuffer(cdev, fb->width, fb->height,
+				      fb->format->cpp[0], fb->pitches[0]))
+		return -EINVAL;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
+	if (!crtc_state)
+		return -EINVAL;
+
+	clip.x2 = crtc_state->adjusted_mode.hdisplay;
+	clip.y2 = crtc_state->adjusted_mode.vdisplay;
+
+	ret = drm_plane_helper_check_state(state, &clip,
+					   DRM_PLANE_HELPER_NO_SCALING,
+					   DRM_PLANE_HELPER_NO_SCALING,
+					   false, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void cirrus_plane_atomic_disable(struct drm_plane *plane,
+					struct drm_plane_state *old_state)
+{
+	return;
+}
+
+static void cirrus_set_framebuffer_regs(struct drm_plane *plane)
+{
+	struct cirrus_device *cdev = plane->dev->dev_private;
+	struct drm_framebuffer *fb = plane->state->fb;
+	int sr07 = 0, hdr = 0, tmp;
+
+	WREG8(SEQ_INDEX, 0x7);
+	sr07 = RREG8(SEQ_DATA);
+	sr07 &= 0xe0;
+	switch (fb->format->cpp[0] * 8) {
+	case 8:
+		sr07 |= 0x11;
+		break;
+	case 16:
+		sr07 |= 0x17;
+		hdr = 0xc1;
+		break;
+	case 24:
+		sr07 |= 0x15;
+		hdr = 0xc5;
+		break;
+	case 32:
+		sr07 |= 0x19;
+		hdr = 0xc5;
+		break;
+	default:
+		/* Should never reach here. */
+		break;
+	}
+
+	WREG_SEQ(0x7, sr07);
+
+	/* Program the pitch */
+	tmp = fb->pitches[0] / 8;
+	WREG_CRT(VGA_CRTC_OFFSET, tmp);
+
+	/* Enable extended blanking and pitch bits, and enable full memory */
+	tmp = 0x22;
+	tmp |= (fb->pitches[0] >> 7) & 0x10;
+	tmp |= (fb->pitches[0] >> 6) & 0x40;
+	WREG_CRT(0x1b, tmp);
+
+	WREG_HDR(hdr);
+}
+
+static void cirrus_set_start_address(struct drm_crtc *crtc, unsigned offset)
+{
+	struct cirrus_device *cdev = crtc->dev->dev_private;
+	u32 addr;
+	u8 tmp;
+
+	addr = offset >> 2;
+	WREG_CRT(0x0c, (u8)((addr >> 8) & 0xff));
+	WREG_CRT(0x0d, (u8)(addr & 0xff));
+
+	WREG8(CRT_INDEX, 0x1b);
+	tmp = RREG8(CRT_DATA);
+	tmp &= 0xf2;
+	tmp |= (addr >> 16) & 0x01;
+	tmp |= (addr >> 15) & 0x0c;
+	WREG_CRT(0x1b, tmp);
+	WREG8(CRT_INDEX, 0x1d);
+	tmp = RREG8(CRT_DATA);
+	tmp &= 0x7f;
+	tmp |= (addr >> 12) & 0x80;
+	WREG_CRT(0x1d, tmp);
+}
+
+static void cirrus_plane_atomic_update(struct drm_plane *plane,
+				       struct drm_plane_state *old_state)
+{
+	struct drm_plane_state *state = plane->state;
+	struct drm_gem_object *obj;
+	struct cirrus_bo *bo;
+
+	cirrus_set_framebuffer_regs(plane);
+
+	obj = to_cirrus_framebuffer(state->fb)->obj;
+	bo = gem_to_cirrus_bo(obj);
+	cirrus_set_start_address(state->crtc, (u32)bo->gpu_addr);
+
+	/* Unblank (needed on S3 resume, vgabios doesn't do it then) */
+	outb(0x20, 0x3c0);
+}
+
+
 static const struct drm_plane_helper_funcs cirrus_plane_helper_funcs = {
+	.prepare_fb = cirrus_plane_prepare_fb,
+	.cleanup_fb = cirrus_plane_cleanup_fb,
+	.atomic_check = cirrus_plane_atomic_check,
+	.atomic_disable = cirrus_plane_atomic_disable,
+	.atomic_update = cirrus_plane_atomic_update,
 };
 
 /* CRTC setup */
@@ -546,6 +637,9 @@ static const struct drm_connector_funcs cirrus_vga_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = cirrus_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static struct drm_connector *cirrus_vga_init(struct drm_device *dev)
@@ -602,6 +696,8 @@ int cirrus_modeset_init(struct cirrus_device *cdev)
 
 	drm_mode_connector_attach_encoder(connector, encoder);
 
+	drm_mode_config_reset(cdev->dev);
+
 	ret = cirrus_fbdev_init(cdev);
 	if (ret) {
 		DRM_ERROR("cirrus_fbdev_init failed\n");
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 11/14] drm/cirrus: send vblank on crtc atomic_flush
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (9 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 10/14] drm/cirrus: use atomic transition helpers for plane and crtc Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 12/14] drm/cirrus: use atomic handlers for plane and crtc Varad Gautam
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

the hardware does not provide interrupts on vblank, so we just send a fake
vblank event on atomic_flush.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_mode.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index eda3c4d18b37..e777157fe474 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -226,6 +226,23 @@ static void cirrus_crtc_destroy(struct drm_crtc *crtc)
 	kfree(cirrus_crtc);
 }
 
+static void cirrus_crtc_atomic_flush(struct drm_crtc *crtc,
+				     struct drm_crtc_state *old_crtc_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_pending_vblank_event *event;
+	unsigned long flags;
+
+	if (crtc->state && crtc->state->event) {
+		event = crtc->state->event;
+		crtc->state->event = NULL;
+
+		spin_lock_irqsave(&dev->event_lock, flags);
+		drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+	}
+}
+
 /* These provide the minimum set of functions required to handle a CRTC */
 static const struct drm_crtc_funcs cirrus_crtc_funcs = {
 	.gamma_set = cirrus_crtc_gamma_set,
@@ -244,6 +261,7 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
 	.prepare = cirrus_crtc_prepare,
 	.commit = cirrus_crtc_commit,
 	.load_lut = cirrus_crtc_load_lut,
+	.atomic_flush = cirrus_crtc_atomic_flush,
 };
 
 static int cirrus_plane_update(struct drm_plane *plane,
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 12/14] drm/cirrus: use atomic handlers for plane and crtc
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (10 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 11/14] drm/cirrus: send vblank on crtc atomic_flush Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 13/14] drm/cirrus: implement atomic hardware cursor support Varad Gautam
  2017-08-18 15:49 ` [PATCH 14/14] drm/cirrus: advertise DRIVER_ATOMIC Varad Gautam
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

move from transition helpers to actual atomic handlers.

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_mode.c | 31 ++++---------------------------
 1 file changed, 4 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index e777157fe474..39bea39a565e 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -179,15 +179,6 @@ static void cirrus_mode_set_nofb(struct drm_crtc *crtc)
 }
 
 /*
- * This is called before a mode is programmed. A typical use might be to
- * enable DPMS during the programming to avoid seeing intermediate stages,
- * but that's not relevant to us
- */
-static void cirrus_crtc_prepare(struct drm_crtc *crtc)
-{
-}
-
-/*
  * This is called after a mode is programmed. It should reverse anything done
  * by the prepare function
  */
@@ -246,8 +237,10 @@ static void cirrus_crtc_atomic_flush(struct drm_crtc *crtc,
 /* These provide the minimum set of functions required to handle a CRTC */
 static const struct drm_crtc_funcs cirrus_crtc_funcs = {
 	.gamma_set = cirrus_crtc_gamma_set,
-	.set_config = drm_crtc_helper_set_config,
+	.set_config = drm_atomic_helper_set_config,
+	.set_property = drm_atomic_helper_crtc_set_property,
 	.destroy = cirrus_crtc_destroy,
+	.page_flip = drm_atomic_helper_page_flip,
 	.reset = drm_atomic_helper_crtc_reset,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
@@ -255,28 +248,12 @@ static const struct drm_crtc_funcs cirrus_crtc_funcs = {
 
 static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
 	.dpms = cirrus_crtc_dpms,
-	.mode_set = drm_helper_crtc_mode_set,
-	.mode_set_base = drm_helper_crtc_mode_set_base,
 	.mode_set_nofb = cirrus_mode_set_nofb,
-	.prepare = cirrus_crtc_prepare,
 	.commit = cirrus_crtc_commit,
 	.load_lut = cirrus_crtc_load_lut,
 	.atomic_flush = cirrus_crtc_atomic_flush,
 };
 
-static int cirrus_plane_update(struct drm_plane *plane,
-			       struct drm_crtc *crtc,
-			       struct drm_framebuffer *fb, int crtc_x,
-			       int crtc_y, unsigned int crtc_w,
-			       unsigned int crtc_h, uint32_t src_x,
-			       uint32_t src_y, uint32_t src_w, uint32_t src_h,
-			       struct drm_modeset_acquire_ctx *ctx)
-{
-	return drm_plane_helper_update(plane, crtc, fb,
-				       crtc_x, crtc_y, crtc_w,
-				       crtc_h, src_x, src_y, src_w, src_h);
-}
-
 static const uint32_t cirrus_plane_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -285,7 +262,7 @@ static const uint32_t cirrus_plane_formats[] = {
 };
 
 static const struct drm_plane_funcs cirrus_plane_funcs = {
-	.update_plane	= cirrus_plane_update,
+	.update_plane	= drm_atomic_helper_update_plane,
 	.disable_plane	= drm_primary_helper_disable,
 	.destroy	= drm_primary_helper_destroy,
 	.reset	= drm_atomic_helper_plane_reset,
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 13/14] drm/cirrus: implement atomic hardware cursor support
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (11 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 12/14] drm/cirrus: use atomic handlers for plane and crtc Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  2017-08-18 15:49 ` [PATCH 14/14] drm/cirrus: advertise DRIVER_ATOMIC Varad Gautam
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Stéphane Marchesin, Varad Gautam, Haixia Shi

From: Varad Gautam <varad.gautam@collabora.com>

This enables cursor plane on cirrus. It only supports ARGB 8-bit cursors
from userspace, and downconverts them to 1-bit black and white with
masking, which is all cirrus hardware can support. Only cursors with
size 32x32 or 64x64 will work.

initial non-atomic version:
Reviewed-at:
https://chromium-review.googlesource.com/335579
https://chromium-review.googlesource.com/339091
Signed-off-by: Zach Reizner <zachr@google.com>

Signed-off-by: Varad Gautam <varadgautam@gmail.com>

CC: Haixia Shi <hshi@chromium.org>
CC: Stéphane Marchesin <marcheu@chromium.org>
---
 drivers/gpu/drm/cirrus/cirrus_drv.h  |  13 ++
 drivers/gpu/drm/cirrus/cirrus_main.c |  13 ++
 drivers/gpu/drm/cirrus/cirrus_mode.c | 281 +++++++++++++++++++++++++++++++++--
 3 files changed, 297 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index d680815f23e6..fbd76c4e6d57 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -50,6 +50,17 @@
 		WREG8(SEQ_DATA, v);				\
 	} while (0)						\
 
+#define PAL_ADDR 8
+#define PAL_DATA 9
+
+#define WREG_PAL(addr, r, g, b)				\
+	do {							\
+		WREG8(PAL_ADDR, addr);				\
+		WREG8(PAL_DATA, r);				\
+		WREG8(PAL_DATA, g);				\
+		WREG8(PAL_DATA, b);				\
+	} while (0)						\
+
 #define CRT_INDEX 0x14
 #define CRT_DATA 0x15
 
@@ -137,6 +148,8 @@ struct cirrus_device {
 	void __iomem			*rmmio;
 
 	struct cirrus_mc			mc;
+	resource_size_t			cursor_ram_size;
+	void __iomem			*cursor_iomem;
 	struct cirrus_mode_info		mode_info;
 
 	int				num_crtc;
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 7d0431bbc6e3..20229b13d6d2 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -94,6 +94,8 @@ static void cirrus_vram_fini(struct cirrus_device *cdev)
 	cdev->rmmio = NULL;
 	if (cdev->mc.vram_base)
 		release_mem_region(cdev->mc.vram_base, cdev->mc.vram_size);
+	if (cdev->cursor_iomem)
+		iounmap(cdev->cursor_iomem);
 }
 
 /* Map the framebuffer from the card and configure the core */
@@ -107,12 +109,23 @@ static int cirrus_vram_init(struct cirrus_device *cdev)
 	 * find the cursor data at the 4M - 16K point.
 	 */
 	cdev->mc.vram_size = 4 * 1024 * 1024;
+	/* The last 16K of VRAM is for cursor */
+	cdev->cursor_ram_size = 16 * 1024;
 
 	if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size,
 				"cirrusdrmfb_vram")) {
 		DRM_ERROR("can't reserve VRAM\n");
 		return -ENXIO;
 	}
+	cdev->cursor_iomem = ioremap_nocache(cdev->mc.vram_base +
+					     cdev->mc.vram_size -
+					     cdev->cursor_ram_size,
+					     cdev->cursor_ram_size);
+	if (!cdev->cursor_iomem) {
+		release_mem_region(cdev->mc.vram_base, cdev->mc.vram_size);
+		DRM_ERROR("can't ioremap cursor VRAM\n");
+		return -ENXIO;
+	}
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 39bea39a565e..915028159975 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -254,6 +254,231 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
 	.atomic_flush = cirrus_crtc_atomic_flush,
 };
 
+static void cirrus_argb_to_cursor(void *src , void __iomem *dst,
+				  uint32_t cursor_size)
+{
+	uint8_t *pixel = (uint8_t *)src;
+	const uint32_t row_size = cursor_size / 8;
+	const uint32_t plane_size = row_size * cursor_size;
+	uint32_t row_skip;
+	void __iomem *plane_0 = dst;
+	void __iomem *plane_1;
+	uint32_t x;
+	uint32_t y;
+
+	switch (cursor_size) {
+	case 32:
+		row_skip = 0;
+		plane_1 = plane_0 + plane_size;
+		break;
+	case 64:
+		row_skip = row_size;
+		plane_1 = plane_0 + row_size;
+		break;
+	default:
+		DRM_DEBUG("Cursor plane format is undefined for given size");
+		return;
+	}
+
+	for (y = 0; y < cursor_size; y++) {
+		uint8_t bits_0 = 0;
+		uint8_t bits_1 = 0;
+
+		for (x = 0; x < cursor_size; x++) {
+			uint8_t alpha = pixel[3];
+			int intensity = pixel[0] + pixel[1] + pixel[2];
+
+			intensity /= 3;
+			bits_0 <<= 1;
+			bits_1 <<= 1;
+			if (alpha > 0x7f) {
+				bits_1 |= 1;
+				if (intensity > 0x7f)
+					bits_0 |= 1;
+			}
+			if ((x % 8) == 7) {
+				iowrite8(bits_0, plane_0);
+				iowrite8(bits_1, plane_1);
+				plane_0++;
+				plane_1++;
+				bits_0 = 0;
+				bits_1 = 0;
+			}
+			pixel += 4;
+		}
+		plane_0 += row_skip;
+		plane_1 += row_skip;
+	}
+}
+
+static int cirrus_bo_to_cursor(struct cirrus_device *cdev,
+			       struct drm_framebuffer *fb,
+			       uint32_t cursor_size, uint32_t cursor_index)
+{
+	const uint32_t pixel_count = cursor_size * cursor_size;
+	const uint32_t plane_size = pixel_count / 8;
+	const uint32_t cursor_offset = cursor_index * plane_size * 2;
+	int ret = 0;
+	struct drm_device *dev = cdev->dev;
+	struct drm_gem_object *obj;
+	struct cirrus_bo *bo;
+	struct ttm_bo_kmap_obj bo_kmap;
+	bool is_iomem;
+	struct ttm_tt *ttm;
+	void *bo_ptr;
+
+	if ((cursor_size == 32 && cursor_index >= 64) ||
+	    (cursor_size == 64 && cursor_index >= 16)) {
+		DRM_ERROR("Cursor index is out of bounds\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->struct_mutex);
+	obj = to_cirrus_framebuffer(fb)->obj;
+	if (obj == NULL) {
+		ret = -ENOENT;
+		DRM_ERROR("Buffer handle for cursor is invalid\n");
+		goto out_unlock;
+	}
+
+	bo = gem_to_cirrus_bo(obj);
+	ttm = bo->bo.ttm;
+
+	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo_kmap);
+	if (ret) {
+		DRM_ERROR("Cursor failed kmap of buffer object\n");
+		goto out_unlock;
+	}
+
+	bo_ptr = ttm_kmap_obj_virtual(&bo_kmap, &is_iomem);
+
+	cirrus_argb_to_cursor(bo_ptr, cdev->cursor_iomem + cursor_offset,
+			      cursor_size);
+
+	ttm_bo_kunmap(&bo_kmap);
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+
+int cirrus_cursor_atomic_check(struct drm_plane *plane,
+			   struct drm_plane_state *state)
+{
+	struct drm_framebuffer *fb = state->fb;
+	struct drm_gem_object *obj;
+	struct cirrus_bo *bo;
+	uint32_t pixel_count;
+	uint32_t expected_pages;
+
+	if (!fb)
+		return 0;
+	if (fb->width != fb->height) {
+		DRM_DEBUG("Cursors are expected to have square dimensions\n");
+		return -EINVAL;
+	}
+
+	if (!(fb->width == 32 || fb->width == 64)) {
+		DRM_ERROR("Cursor dimension are expected to be 32 or 64\n");
+		return -EINVAL;
+	}
+
+	obj = to_cirrus_framebuffer(fb)->obj;
+	if (obj == NULL) {
+		DRM_ERROR("Buffer handle for cursor is invalid\n");
+		return -ENOENT;
+	}
+	bo = gem_to_cirrus_bo(obj);
+	pixel_count = fb->width * fb->width;
+	expected_pages = DIV_ROUND_UP(pixel_count * 4, PAGE_SIZE);
+	if (bo->bo.num_pages < expected_pages) {
+		DRM_ERROR("Buffer object for cursor is too small\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void cirrus_cursor_atomic_update(struct drm_plane *plane,
+				    struct drm_plane_state *old_state)
+{
+	int ret;
+	struct drm_device *dev = plane->state->crtc->dev;
+	struct cirrus_device *cdev = dev->dev_private;
+	struct drm_framebuffer *fb = plane->state->fb;
+	uint8_t cursor_index = 0;
+	int width, x, y;
+	int sr10, sr10_index;
+	int sr11, sr11_index;
+	int sr12, sr13;
+
+	width = fb->width;
+	if (fb != old_state->fb) {
+		WREG8(SEQ_INDEX, 0x12);
+		sr12 = RREG8(SEQ_DATA);
+		sr12 &= 0xfe;
+		WREG_SEQ(0x12, sr12);
+
+		/* This may still fail if the bo reservation fails. */
+		ret = cirrus_bo_to_cursor(cdev, fb, width, cursor_index);
+		if (ret)
+			return;
+
+		WREG8(SEQ_INDEX, 0x12);
+		sr12 = RREG8(SEQ_DATA);
+		sr12 &= 0xfa;
+		sr12 |= 0x03; /* enables cursor and write to extra DAC LUT */
+		if (width == 64)
+			sr12 |= 0x04;
+		WREG_SEQ(0x12, sr12);
+
+		/* Background set to black, foreground set to white */
+		WREG_PAL(0x00, 0, 0, 0);
+		WREG_PAL(0x0f, 255, 255, 255);
+
+		sr12 &= ~0x2; /* Disables writes to the extra LUT */
+		WREG_SEQ(0x12, sr12);
+
+		sr13 = 0;
+		if (width == 64)
+			sr13 |= (cursor_index & 0x0f) << 2;
+		else
+			sr13 |= cursor_index & 0x3f;
+		WREG_SEQ(0x13, sr13);
+	}
+
+	x = plane->state->crtc_x + fb->hot_x;
+	y = plane->state->crtc_y + fb->hot_y;
+	if (x < 0)
+		x = 0;
+	if (x > 0x7ff)
+		x = 0x7ff;
+	if (y < 0)
+		y = 0;
+	if (y > 0x7ff)
+		y = 0x7ff;
+
+	sr10 = (x >> 3) & 0xff;
+	sr10_index = 0x10;
+	sr10_index |= (x & 0x07) << 5;
+	WREG_SEQ(sr10_index, sr10);
+	sr11 = (y >> 3) & 0xff;
+	sr11_index = 0x11;
+	sr11_index |= (y & 0x07) << 5;
+	WREG_SEQ(sr11_index, sr11);
+}
+
+void cirrus_cursor_atomic_disable(struct drm_plane *plane,
+			       struct drm_plane_state *old_state)
+{
+	struct cirrus_device *cdev = plane->dev->dev_private;
+	int sr12;
+
+	WREG8(SEQ_INDEX, 0x12);
+	sr12 = (RREG8(SEQ_DATA) | 0x04) & 0xfe;
+	WREG8(SEQ_DATA, sr12);
+}
+
 static const uint32_t cirrus_plane_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -451,6 +676,26 @@ static void cirrus_plane_atomic_update(struct drm_plane *plane,
 	outb(0x20, 0x3c0);
 }
 
+static const uint32_t cirrus_cursor_formats[] = {
+	DRM_FORMAT_ARGB8888,
+};
+
+static const struct drm_plane_funcs cirrus_cursor_plane_funcs = {
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
+	.destroy	= drm_primary_helper_destroy,
+	.reset		= drm_atomic_helper_plane_reset,
+	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static const struct drm_plane_helper_funcs cirrus_cursor_helper_funcs = {
+	.atomic_check = cirrus_cursor_atomic_check,
+	.atomic_update = cirrus_cursor_atomic_update,
+	.atomic_disable = cirrus_cursor_atomic_disable,
+	.prepare_fb = cirrus_plane_prepare_fb,
+	.cleanup_fb = cirrus_plane_cleanup_fb,
+};
 
 static const struct drm_plane_helper_funcs cirrus_plane_helper_funcs = {
 	.prepare_fb = cirrus_plane_prepare_fb,
@@ -465,7 +710,7 @@ static void cirrus_crtc_init(struct drm_device *dev)
 {
 	struct cirrus_device *cdev = dev->dev_private;
 	struct cirrus_crtc *cirrus_crtc;
-	struct drm_plane *primary;
+	struct drm_plane *primary, *cursor;
 	int i, ret;
 
 	cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
@@ -481,17 +726,30 @@ static void cirrus_crtc_init(struct drm_device *dev)
 
 	drm_plane_helper_add(primary, &cirrus_plane_helper_funcs);
 	ret = drm_universal_plane_init(dev, primary, 1,
-				       &cirrus_plane_funcs,
-				       cirrus_plane_formats,
-				       ARRAY_SIZE(cirrus_plane_formats),
-				       DRM_PLANE_TYPE_PRIMARY, NULL);
+				&cirrus_plane_funcs,
+				cirrus_plane_formats,
+				ARRAY_SIZE(cirrus_plane_formats),
+				DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret)
+		goto cleanup_primary;
+
+	cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
+	if (cursor == NULL)
+		goto cleanup_primary;
+
+	drm_plane_helper_add(cursor, &cirrus_cursor_helper_funcs);
+	ret = drm_universal_plane_init(dev, cursor, 1,
+				&cirrus_cursor_plane_funcs,
+				cirrus_cursor_formats,
+				ARRAY_SIZE(cirrus_cursor_formats),
+				DRM_PLANE_TYPE_CURSOR, NULL);
 	if (ret)
-		goto cleanup;
+		goto cleanup_cursor;
 
-	ret = drm_crtc_init_with_planes(dev, &cirrus_crtc->base, primary, NULL,
-					&cirrus_crtc_funcs, NULL);
+	ret = drm_crtc_init_with_planes(dev, &cirrus_crtc->base, primary, cursor,
+				      &cirrus_crtc_funcs, NULL);
 	if (ret)
-		goto cleanup;
+		goto cleanup_cursor;
 	drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
 	cdev->mode_info.crtc = cirrus_crtc;
 
@@ -504,7 +762,10 @@ static void cirrus_crtc_init(struct drm_device *dev)
 	drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
 	return;
 
-cleanup:
+cleanup_cursor:
+	drm_plane_cleanup(cursor);
+	kfree(cursor);
+cleanup_primary:
 	drm_plane_cleanup(primary);
 	kfree(primary);
 cleanup_crtc:
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 14/14] drm/cirrus: advertise DRIVER_ATOMIC
  2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
                   ` (12 preceding siblings ...)
  2017-08-18 15:49 ` [PATCH 13/14] drm/cirrus: implement atomic hardware cursor support Varad Gautam
@ 2017-08-18 15:49 ` Varad Gautam
  13 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-18 15:49 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

From: Varad Gautam <varad.gautam@collabora.com>

allow userspace to use atomic ioctls.

we now pass the following tests:
igt/kms_atomic_transition:
    plane-all-transition
    plane-use-after-nonblocking-unbind
    plane-all-modeset-transition
    plane-toggle-modeset-transition
    1x-modeset-transitions
    1x-modeset-transitions-nonblocking
igt/kms_atomic:
    plane_primary_legacy
    test_only
    plane_cursor_legacy
    plane_invalid_params
    crtc_invalid_params
igt/kms_setmode
igt/kms_rmfb
drm-tests/atomictest:
    disable_primary
    fullscreen_video
    overlay_pageflip
    primary_pageflip
    video_overlay

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
---
 drivers/gpu/drm/cirrus/cirrus_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index dca7a3f4791d..1e9878103a38 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -130,7 +130,8 @@ static const struct file_operations cirrus_driver_fops = {
 	.compat_ioctl = drm_compat_ioctl,
 };
 static struct drm_driver driver = {
-	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
+			DRIVER_ATOMIC,
 	.load = cirrus_driver_load,
 	.unload = cirrus_driver_unload,
 	.set_busid = drm_pci_set_busid,
-- 
2.13.1

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

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 02/14] drm/cirrus: unregister connector on destroy
  2017-08-18 15:49 ` [PATCH 02/14] drm/cirrus: unregister connector on destroy Varad Gautam
@ 2017-08-19  6:10   ` Varad Gautam
  0 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-08-19  6:10 UTC (permalink / raw)
  To: dri-devel; +Cc: Varad Gautam

Discard this one, not needed in light of [1]:

"drm_dev_unregister unregisters all connectors too. Explicitly calling
drm_connector_unregister should only be needed when you
a) screwed up your unload sequence. Get rid of ->unload and make sure you
call drm_dev_unregister first to fix this properly
b) hot-unplug. Doesn't apply to cirrus."

[1] http://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg191644.html

Thanks,
Varad

On Fri, Aug 18, 2017 at 9:19 PM, Varad Gautam <varadgautam@gmail.com> wrote:
> From: Varad Gautam <varad.gautam@collabora.com>
>
> add missing unregister call on connector destroy.
>
> Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
> ---
>  drivers/gpu/drm/cirrus/cirrus_mode.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
> index 21d75e7e4abc..6032978a2797 100644
> --- a/drivers/gpu/drm/cirrus/cirrus_mode.c
> +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
> @@ -492,6 +492,7 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
>
>  static void cirrus_connector_destroy(struct drm_connector *connector)
>  {
> +       drm_connector_unregister(connector);
>         drm_connector_cleanup(connector);
>         kfree(connector);
>  }
> --
> 2.13.1
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 06/14] drm/cirrus: Use 32bpp by default
  2017-08-18 15:49 ` [PATCH 06/14] drm/cirrus: Use 32bpp by default Varad Gautam
@ 2017-08-19  8:32   ` Matthew Garrett
  2017-08-23 15:40     ` Varad Gautam
  0 siblings, 1 reply; 22+ messages in thread
From: Matthew Garrett @ 2017-08-19  8:32 UTC (permalink / raw)
  To: Varad Gautam; +Cc: Stéphane Marchesin, dri-devel

On Fri, Aug 18, 2017 at 09:19:11PM +0530, Varad Gautam wrote:
> From: Stéphane Marchesin <marcheu@chromium.org>
> 
> initially reviewed for ChromiumOS at:
> https://chromium-review.googlesource.com/339093
> Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>

1280x1024x24 fits in 4MB, 1280x1024x32 doesn't. That seems like it's 
going to be a visible change in behaviour.

-- 
Matthew Garrett | mjg59@srcf.ucam.org
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 06/14] drm/cirrus: Use 32bpp by default
  2017-08-19  8:32   ` Matthew Garrett
@ 2017-08-23 15:40     ` Varad Gautam
  2017-08-23 17:38       ` Matthew Garrett
  0 siblings, 1 reply; 22+ messages in thread
From: Varad Gautam @ 2017-08-23 15:40 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: Stéphane Marchesin, dri-devel

Hi Matthew,

On Sat, Aug 19, 2017 at 2:02 PM, Matthew Garrett <mjg59@srcf.ucam.org> wrote:
> On Fri, Aug 18, 2017 at 09:19:11PM +0530, Varad Gautam wrote:
>> From: Stéphane Marchesin <marcheu@chromium.org>
>>
>> initially reviewed for ChromiumOS at:
>> https://chromium-review.googlesource.com/339093
>> Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
>
> 1280x1024x24 fits in 4MB, 1280x1024x32 doesn't. That seems like it's
> going to be a visible change in behaviour.
>

Right, 800x600 is the highest we can go for >24bpp, so we now switch
to that instead of 1280x1024. fb creation fails in
cirrus_check_framebuffer if the w*h*bpp doesn't fit, and plane updates
get rejected when atomic is enabled later on.

Regards,
Varad

> --
> Matthew Garrett | mjg59@srcf.ucam.org
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 06/14] drm/cirrus: Use 32bpp by default
  2017-08-23 15:40     ` Varad Gautam
@ 2017-08-23 17:38       ` Matthew Garrett
  0 siblings, 0 replies; 22+ messages in thread
From: Matthew Garrett @ 2017-08-23 17:38 UTC (permalink / raw)
  To: Varad Gautam; +Cc: Stéphane Marchesin, dri-devel

On Wed, Aug 23, 2017 at 09:10:09PM +0530, Varad Gautam wrote:
> Hi Matthew,
> 
> On Sat, Aug 19, 2017 at 2:02 PM, Matthew Garrett <mjg59@srcf.ucam.org> wrote:
> > On Fri, Aug 18, 2017 at 09:19:11PM +0530, Varad Gautam wrote:
> >> From: Stéphane Marchesin <marcheu@chromium.org>
> >>
> >> initially reviewed for ChromiumOS at:
> >> https://chromium-review.googlesource.com/339093
> >> Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
> >
> > 1280x1024x24 fits in 4MB, 1280x1024x32 doesn't. That seems like it's
> > going to be a visible change in behaviour.
> >
> 
> Right, 800x600 is the highest we can go for >24bpp, so we now switch
> to that instead of 1280x1024. fb creation fails in
> cirrus_check_framebuffer if the w*h*bpp doesn't fit, and plane updates
> get rejected when atomic is enabled later on.

So users who want 1280x1024 now have to change their configuration. Is 
that the intent? It seems odd to change user-visible behaviour for 
everyone just to fix ChromeOS in a VM.

-- 
Matthew Garrett | mjg59@srcf.ucam.org
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram
  2017-08-18 15:49 ` [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
@ 2017-09-04 10:41   ` Gabriel Krisman Bertazi
  2017-09-05 13:04     ` Varad Gautam
  0 siblings, 1 reply; 22+ messages in thread
From: Gabriel Krisman Bertazi @ 2017-09-04 10:41 UTC (permalink / raw)
  To: Varad Gautam; +Cc: Varad Gautam, dri-devel

Varad Gautam <varadgautam@gmail.com> writes:


>  int cirrus_bo_push_sysram(struct cirrus_bo *bo)
>  {
>  	int i, ret;
> -	if (!bo->pin_count) {
> +
> +	ret = cirrus_bo_reserve(bo, false);
> +	if (ret)
> +		return ret;
> +
> +	if (bo->pin_count) {
>  		DRM_ERROR("unpin bad %p\n", bo);
> -		return 0;
> +		goto out;
>  	}
> -	bo->pin_count--;
> -	if (bo->pin_count)
> -		return 0;

Can you adjust this to also use your version of cirrus_bo_unpin()?

Also, If I'm not mistaken, this hunk unbalances pin_count, since you
no longer decrement it after unpinning.

>  
>  	if (bo->kmap.virtual)
>  		ttm_bo_kunmap(&bo->kmap);
> @@ -400,9 +432,12 @@ int cirrus_bo_push_sysram(struct cirrus_bo *bo)
>  	ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
>  	if (ret) {
>  		DRM_ERROR("pushing to VRAM failed\n");
> -		return ret;
> +		goto out;
>  	}
> -	return 0;
> +
> +out:
> +	cirrus_bo_unreserve(bo);
> +	return ret;
>  }
>  
>  int cirrus_mmap(struct file *filp, struct vm_area_struct *vma)

-- 
Gabriel Krisman Bertazi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 09/14] drm/cirrus: use universal plane interfaces for primary plane
  2017-08-18 15:49 ` [PATCH 09/14] drm/cirrus: use universal plane interfaces for primary plane Varad Gautam
@ 2017-09-04 11:14   ` Gabriel Krisman Bertazi
  0 siblings, 0 replies; 22+ messages in thread
From: Gabriel Krisman Bertazi @ 2017-09-04 11:14 UTC (permalink / raw)
  To: Varad Gautam; +Cc: Varad Gautam, dri-devel

Varad Gautam <varadgautam@gmail.com> writes:

> From: Varad Gautam <varad.gautam@collabora.com>
>
> cirrus exposes one legacy primary plane tied to the crtc. convert this to
> use the universal planes interface in preparation for atomic.
>
> Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
> ---
>  drivers/gpu/drm/cirrus/cirrus_mode.c | 44 ++++++++++++++++++++++++++++++++++--
>  1 file changed, 42 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
> index 6032978a2797..2994dd391850 100644
> --- a/drivers/gpu/drm/cirrus/cirrus_mode.c
> +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
> @@ -358,12 +358,29 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
>  	.load_lut = cirrus_crtc_load_lut,
>  };
>  
> +static const uint32_t cirrus_plane_formats[] = {
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_RGB888,
> +	DRM_FORMAT_RGB565,
> +};
> +
> +static const struct drm_plane_funcs cirrus_plane_funcs = {
> +	.update_plane	= drm_primary_helper_update,
> +	.disable_plane	= drm_primary_helper_disable,
> +	.destroy	= drm_primary_helper_destroy,
> +};
> +
> +static const struct drm_plane_helper_funcs cirrus_plane_helper_funcs = {
> +};
> +
>  /* CRTC setup */
>  static void cirrus_crtc_init(struct drm_device *dev)
>  {
>  	struct cirrus_device *cdev = dev->dev_private;
>  	struct cirrus_crtc *cirrus_crtc;
> -	int i;
> +	struct drm_plane *primary;
> +	int i, ret;
>  
>  	cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
>  			      (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
> @@ -372,8 +389,23 @@ static void cirrus_crtc_init(struct drm_device *dev)
>  	if (cirrus_crtc == NULL)
>  		return;
>  
> -	drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs);
> +	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
> +	if (primary == NULL)
> +		goto cleanup_crtc;
>  
> +	drm_plane_helper_add(primary, &cirrus_plane_helper_funcs);
> +	ret = drm_universal_plane_init(dev, primary, 1,
> +				       &cirrus_plane_funcs,
> +				       cirrus_plane_formats,
> +				       ARRAY_SIZE(cirrus_plane_formats),
> +				       DRM_PLANE_TYPE_PRIMARY, NULL);
> +	if (ret)
> +		goto cleanup;

If this fails early enough, you can't call drm_plane_cleanup, otherwise
you'll hit an oops.

Otherwise, looks good.  with the above change, please add:

Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>


> +
> +	ret = drm_crtc_init_with_planes(dev, &cirrus_crtc->base, primary, NULL,
> +					&cirrus_crtc_funcs, NULL);
> +	if (ret)
> +		goto cleanup;
>  	drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
>  	cdev->mode_info.crtc = cirrus_crtc;
>  
> @@ -384,6 +416,14 @@ static void cirrus_crtc_init(struct drm_device *dev)
>  	}
>  
>  	drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
> +	return;
> +
> +cleanup:
> +	drm_plane_cleanup(primary);
> +	kfree(primary);
> +cleanup_crtc:
> +	kfree(cirrus_crtc);
> +	return;
>  }
>  
>  /** Sets the color ramps on behalf of fbcon */

-- 
Gabriel Krisman Bertazi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram
  2017-09-04 10:41   ` Gabriel Krisman Bertazi
@ 2017-09-05 13:04     ` Varad Gautam
  0 siblings, 0 replies; 22+ messages in thread
From: Varad Gautam @ 2017-09-05 13:04 UTC (permalink / raw)
  To: Gabriel Krisman Bertazi; +Cc: Varad Gautam, dri-devel

Hi Gabriel,

On Mon, Sep 4, 2017 at 4:11 PM, Gabriel Krisman Bertazi
<krisman@collabora.co.uk> wrote:
> Varad Gautam <varadgautam@gmail.com> writes:
>
>
>>  int cirrus_bo_push_sysram(struct cirrus_bo *bo)
>>  {
>>       int i, ret;
>> -     if (!bo->pin_count) {
>> +
>> +     ret = cirrus_bo_reserve(bo, false);
>> +     if (ret)
>> +             return ret;
>> +
>> +     if (bo->pin_count) {
>>               DRM_ERROR("unpin bad %p\n", bo);
>> -             return 0;
>> +             goto out;
>>       }
>> -     bo->pin_count--;
>> -     if (bo->pin_count)
>> -             return 0;
>
> Can you adjust this to also use your version of cirrus_bo_unpin()?
>
> Also, If I'm not mistaken, this hunk unbalances pin_count, since you
> no longer decrement it after unpinning.
>

Do you mean we also need to call bo_unpin() from push_sysram?

With this patch, we unpin immediately before calling push_sysram(),
and only allow non-pinned bo-s to be moved to sysram (pin_count
decrements in cirrus_bo_unpin preserving pinning state). With atomic
handlers later (patch 10+), pin-unpin happens from prepare/cleanup_fb,
and a later prepare_fb calls push_sysram() on the bo - so the
pin_count maintains.

Thanks,
Varad

>>
>>       if (bo->kmap.virtual)
>>               ttm_bo_kunmap(&bo->kmap);
>> @@ -400,9 +432,12 @@ int cirrus_bo_push_sysram(struct cirrus_bo *bo)
>>       ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
>>       if (ret) {
>>               DRM_ERROR("pushing to VRAM failed\n");
>> -             return ret;
>> +             goto out;
>>       }
>> -     return 0;
>> +
>> +out:
>> +     cirrus_bo_unreserve(bo);
>> +     return ret;
>>  }
>>
>>  int cirrus_mmap(struct file *filp, struct vm_area_struct *vma)
>
> --
> Gabriel Krisman Bertazi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2017-09-05 13:04 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-18 15:49 [PATCH 00/14] atomic modesetting for cirrus Varad Gautam
2017-08-18 15:49 ` [PATCH 01/14] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
2017-09-04 10:41   ` Gabriel Krisman Bertazi
2017-09-05 13:04     ` Varad Gautam
2017-08-18 15:49 ` [PATCH 02/14] drm/cirrus: unregister connector on destroy Varad Gautam
2017-08-19  6:10   ` Varad Gautam
2017-08-18 15:49 ` [PATCH 03/14] drm/cirrus: add drm_read to cirrus_driver_fops Varad Gautam
2017-08-18 15:49 ` [PATCH 04/14] drm/cirrus: do not disable outputs on fbdev init for atomic Varad Gautam
2017-08-18 15:49 ` [PATCH 05/14] drm/cirrus: initialize start and size fields Varad Gautam
2017-08-18 15:49 ` [PATCH 06/14] drm/cirrus: Use 32bpp by default Varad Gautam
2017-08-19  8:32   ` Matthew Garrett
2017-08-23 15:40     ` Varad Gautam
2017-08-23 17:38       ` Matthew Garrett
2017-08-18 15:49 ` [PATCH 07/14] drm/cirrus: hardcode vram size Varad Gautam
2017-08-18 15:49 ` [PATCH 08/14] drm/cirrus: implement PRIME export for cirrus Varad Gautam
2017-08-18 15:49 ` [PATCH 09/14] drm/cirrus: use universal plane interfaces for primary plane Varad Gautam
2017-09-04 11:14   ` Gabriel Krisman Bertazi
2017-08-18 15:49 ` [PATCH 10/14] drm/cirrus: use atomic transition helpers for plane and crtc Varad Gautam
2017-08-18 15:49 ` [PATCH 11/14] drm/cirrus: send vblank on crtc atomic_flush Varad Gautam
2017-08-18 15:49 ` [PATCH 12/14] drm/cirrus: use atomic handlers for plane and crtc Varad Gautam
2017-08-18 15:49 ` [PATCH 13/14] drm/cirrus: implement atomic hardware cursor support Varad Gautam
2017-08-18 15:49 ` [PATCH 14/14] drm/cirrus: advertise DRIVER_ATOMIC Varad Gautam

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.