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

Hello,

The v2 incorporates the feedback on v1 [1] and rebases the series to master.
We no longer force 32bpp, fix incorrect error handling during plane
initialization, and drom some irrelevant patches.

[1] https://lists.freedesktop.org/archives/dri-devel/2017-August/150703.html

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

Varad Gautam (9):
  drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram
  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   |  13 +-
 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  | 682 ++++++++++++++++++++++++++--------
 drivers/gpu/drm/cirrus/cirrus_prime.c |  63 ++++
 drivers/gpu/drm/cirrus/cirrus_ttm.c   |  55 ++-
 8 files changed, 705 insertions(+), 164 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] 16+ messages in thread

* [PATCH 01/12] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 02/12] drm/cirrus: add drm_read to cirrus_driver_fops Varad Gautam
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 be2d7e488062..e16b86dd6c19 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -254,6 +254,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 a4c4a465b385..6a8d09c9a36b 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -112,26 +112,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 */
@@ -139,7 +130,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] 16+ messages in thread

* [PATCH 02/12] drm/cirrus: add drm_read to cirrus_driver_fops
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
  2017-09-08 13:35 ` [PATCH 01/12] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 03/12] drm/cirrus: do not disable outputs on fbdev init for atomic Varad Gautam
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 69c4e352dd78..452059780ddc 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] 16+ messages in thread

* [PATCH 03/12] drm/cirrus: do not disable outputs on fbdev init for atomic.
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
  2017-09-08 13:35 ` [PATCH 01/12] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
  2017-09-08 13:35 ` [PATCH 02/12] drm/cirrus: add drm_read to cirrus_driver_fops Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 04/12] drm/cirrus: initialize start and size fields Varad Gautam
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 32fbfba2c623..28383b828f47 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -293,9 +293,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] 16+ messages in thread

* [PATCH 04/12] drm/cirrus: initialize start and size fields
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (2 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 03/12] drm/cirrus: do not disable outputs on fbdev init for atomic Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-11  8:23   ` Gerd Hoffmann
  2017-09-08 13:35 ` [PATCH 05/12] drm/cirrus: hardcode vram size Varad Gautam
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 UTC (permalink / raw)
  To: dri-devel; +Cc: Zhuo-hao Lee, Stphane 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: Stphane 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 28383b828f47..30fb10cbb038 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -231,6 +231,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] 16+ messages in thread

* [PATCH 05/12] drm/cirrus: hardcode vram size
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (3 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 04/12] drm/cirrus: initialize start and size fields Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-11  8:31   ` Gerd Hoffmann
  2017-09-08 13:35 ` [PATCH 06/12] drm/cirrus: implement PRIME export for cirrus Varad Gautam
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 b5f528543956..332bb2169508 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] 16+ messages in thread

* [PATCH 06/12] drm/cirrus: implement PRIME export for cirrus
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (4 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 05/12] drm/cirrus: hardcode vram size Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 07/12] drm/cirrus: use universal plane interfaces for primary plane Varad Gautam
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 452059780ddc..09461868ed46 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,
 	.fops = &cirrus_driver_fops,
@@ -143,6 +143,15 @@ static struct drm_driver driver = {
 	.gem_free_object_unlocked = cirrus_gem_free_object,
 	.dumb_create = cirrus_dumb_create,
 	.dumb_map_offset = cirrus_dumb_mmap_offset,
+	.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 e16b86dd6c19..8c43cc963027 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -163,6 +163,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;
@@ -256,6 +257,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] 16+ messages in thread

* [PATCH 07/12] drm/cirrus: use universal plane interfaces for primary plane
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (5 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 06/12] drm/cirrus: implement PRIME export for cirrus Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 08/12] drm/cirrus: use atomic transition helpers for plane and crtc Varad Gautam
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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.

v2: avoid early plane cleanup to fix faulty error handling. (krisman)

Signed-off-by: Varad Gautam <varad.gautam@collabora.com>
Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
---
 drivers/gpu/drm/cirrus/cirrus_mode.c | 45 +++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 6a8d09c9a36b..d12399986c81 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -348,11 +348,29 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
 	.commit = cirrus_crtc_commit,
 };
 
+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;
+	struct drm_plane *primary;
+	int ret;
 
 	cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
 			      (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -361,12 +379,37 @@ 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),
+				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret) {
+		kfree(primary);
+		goto cleanup_crtc;
+	}
+
+	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;
 
 	drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
+	return;
+
+cleanup:
+	drm_plane_cleanup(primary);
+	kfree(primary);
+cleanup_crtc:
+	kfree(cirrus_crtc);
+	return;
 }
 
 static void cirrus_encoder_mode_set(struct drm_encoder *encoder,
-- 
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] 16+ messages in thread

* [PATCH 08/12] drm/cirrus: use atomic transition helpers for plane and crtc
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (6 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 07/12] drm/cirrus: use universal plane interfaces for primary plane Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 09/12] drm/cirrus: send vblank on crtc atomic_flush Varad Gautam
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 8c43cc963027..1db0849b4bcb 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -167,6 +167,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 332bb2169508..f146a4129742 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 d12399986c81..ee023c865165 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>
 
@@ -72,95 +74,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;
@@ -225,54 +152,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;
 }
 
 /*
@@ -338,16 +222,33 @@ 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,
 };
 
+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,
@@ -356,12 +257,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 */
@@ -509,6 +600,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)
@@ -565,6 +659,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] 16+ messages in thread

* [PATCH 09/12] drm/cirrus: send vblank on crtc atomic_flush
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (7 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 08/12] drm/cirrus: use atomic transition helpers for plane and crtc Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 10/12] drm/cirrus: use atomic handlers for plane and crtc Varad Gautam
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 ee023c865165..4c95447ac445 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -217,6 +217,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,
@@ -234,6 +251,7 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
 	.mode_set_nofb = cirrus_mode_set_nofb,
 	.prepare = cirrus_crtc_prepare,
 	.commit = cirrus_crtc_commit,
+	.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] 16+ messages in thread

* [PATCH 10/12] drm/cirrus: use atomic handlers for plane and crtc
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (8 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 09/12] drm/cirrus: send vblank on crtc atomic_flush Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-08 13:35 ` [PATCH 11/12] drm/cirrus: implement atomic hardware cursor support Varad Gautam
  2017-09-08 13:35 ` [PATCH 12/12] drm/cirrus: advertise DRIVER_ATOMIC Varad Gautam
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 | 30 +++---------------------------
 1 file changed, 3 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 4c95447ac445..fb3d808ffb5f 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -160,15 +160,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
  */
@@ -237,8 +228,9 @@ 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,
 	.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,
@@ -246,27 +238,11 @@ 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,
 	.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,
@@ -275,7 +251,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] 16+ messages in thread

* [PATCH 11/12] drm/cirrus: implement atomic hardware cursor support
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (9 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 10/12] drm/cirrus: use atomic handlers for plane and crtc Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  2017-09-11  8:37   ` Gerd Hoffmann
  2017-09-08 13:35 ` [PATCH 12/12] drm/cirrus: advertise DRIVER_ATOMIC Varad Gautam
  11 siblings, 1 reply; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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>

v2: rework faulty error handling (krisman <krisman@collabora.co.uk>)
---
 drivers/gpu/drm/cirrus/cirrus_drv.h  |  13 ++
 drivers/gpu/drm/cirrus/cirrus_main.c |  13 ++
 drivers/gpu/drm/cirrus/cirrus_mode.c | 273 ++++++++++++++++++++++++++++++++++-
 3 files changed, 294 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 1db0849b4bcb..639af38c035d 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
 
@@ -136,6 +147,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 f146a4129742..deb531b6e3db 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 fb3d808ffb5f..66b0750eb33a 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -243,6 +243,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,
@@ -440,6 +665,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,
@@ -454,7 +699,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 ret;
 
 	cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
@@ -479,17 +724,35 @@ static void cirrus_crtc_init(struct drm_device *dev)
 		goto cleanup_crtc;
 	}
 
-	ret = drm_crtc_init_with_planes(dev, &cirrus_crtc->base, primary, NULL,
-					&cirrus_crtc_funcs, NULL);
+	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),
+				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
+	if (ret) {
+		kfree(cursor);
+		goto cleanup_primary;
+	}
+
+	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;
 
 	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] 16+ messages in thread

* [PATCH 12/12] drm/cirrus: advertise DRIVER_ATOMIC
  2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
                   ` (10 preceding siblings ...)
  2017-09-08 13:35 ` [PATCH 11/12] drm/cirrus: implement atomic hardware cursor support Varad Gautam
@ 2017-09-08 13:35 ` Varad Gautam
  11 siblings, 0 replies; 16+ messages in thread
From: Varad Gautam @ 2017-09-08 13:35 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 when running with cirrus.bpp=32:
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 09461868ed46..c2c010379b93 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,
 	.fops = &cirrus_driver_fops,
-- 
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] 16+ messages in thread

* Re: [PATCH 04/12] drm/cirrus: initialize start and size fields
  2017-09-08 13:35 ` [PATCH 04/12] drm/cirrus: initialize start and size fields Varad Gautam
@ 2017-09-11  8:23   ` Gerd Hoffmann
  0 siblings, 0 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2017-09-11  8:23 UTC (permalink / raw)
  To: Varad Gautam, dri-devel; +Cc: Stphane Marchesin, Zhuo-hao Lee

On Fri, 2017-09-08 at 19:05 +0530, Varad Gautam wrote:
> From: Dominik Behr <dbehr@chromium.org>
> 
> initialize start and size fields in fb info
> so user space drivers like fbdev can map the memory

Hmm? That works just fine in vanilla 4.12 ...

cheers,
  Gerd

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

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

* Re: [PATCH 05/12] drm/cirrus: hardcode vram size
  2017-09-08 13:35 ` [PATCH 05/12] drm/cirrus: hardcode vram size Varad Gautam
@ 2017-09-11  8:31   ` Gerd Hoffmann
  0 siblings, 0 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2017-09-11  8:31 UTC (permalink / raw)
  To: Varad Gautam, dri-devel; +Cc: Stéphane Marchesin, Zach Reizner

On Fri, 2017-09-08 at 19:05 +0530, Varad Gautam wrote:
> 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.

This comment is misleading.  pci bar size != vram size.  There is more
stuff in the pci bar than just the vram, thats why it is larger than
vram.  It's not qemu mis-reporting something.

The actual vram size is 4MB.  This is what the original hardware had,
so the qemu emulation uses that too.  So the fix is correct, but please
adjust commit message and comment.

cheers,
  Gerd


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

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

* Re: [PATCH 11/12] drm/cirrus: implement atomic hardware cursor support
  2017-09-08 13:35 ` [PATCH 11/12] drm/cirrus: implement atomic hardware cursor support Varad Gautam
@ 2017-09-11  8:37   ` Gerd Hoffmann
  0 siblings, 0 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2017-09-11  8:37 UTC (permalink / raw)
  To: Varad Gautam, dri-devel; +Cc: Stéphane Marchesin, Varad Gautam, Haixia Shi

On Fri, 2017-09-08 at 19:05 +0530, Varad Gautam wrote:
> 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.

Isn't it better to just not implement hardware cursor then, so
userspace can fallback to software cursor instead?  Advertising ARGB
cursor support to userspace, but then crippling those cursors to
black'n'white doesn't look sensible to me ...

cheers,
  Gerd

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

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

end of thread, other threads:[~2017-09-11  8:37 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-08 13:35 [PATCH 00/12] atomic modesetting for cirrus v2 Varad Gautam
2017-09-08 13:35 ` [PATCH 01/12] drm/cirrus: split out bo unpinning from cirrus_bo_push_sysram Varad Gautam
2017-09-08 13:35 ` [PATCH 02/12] drm/cirrus: add drm_read to cirrus_driver_fops Varad Gautam
2017-09-08 13:35 ` [PATCH 03/12] drm/cirrus: do not disable outputs on fbdev init for atomic Varad Gautam
2017-09-08 13:35 ` [PATCH 04/12] drm/cirrus: initialize start and size fields Varad Gautam
2017-09-11  8:23   ` Gerd Hoffmann
2017-09-08 13:35 ` [PATCH 05/12] drm/cirrus: hardcode vram size Varad Gautam
2017-09-11  8:31   ` Gerd Hoffmann
2017-09-08 13:35 ` [PATCH 06/12] drm/cirrus: implement PRIME export for cirrus Varad Gautam
2017-09-08 13:35 ` [PATCH 07/12] drm/cirrus: use universal plane interfaces for primary plane Varad Gautam
2017-09-08 13:35 ` [PATCH 08/12] drm/cirrus: use atomic transition helpers for plane and crtc Varad Gautam
2017-09-08 13:35 ` [PATCH 09/12] drm/cirrus: send vblank on crtc atomic_flush Varad Gautam
2017-09-08 13:35 ` [PATCH 10/12] drm/cirrus: use atomic handlers for plane and crtc Varad Gautam
2017-09-08 13:35 ` [PATCH 11/12] drm/cirrus: implement atomic hardware cursor support Varad Gautam
2017-09-11  8:37   ` Gerd Hoffmann
2017-09-08 13:35 ` [PATCH 12/12] 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.