Blob Blame History Raw
From 01ce260b60a2077faa168a8a207a70d130f9d365 Mon Sep 17 00:00:00 2001
From: Thomas Zimmermann <tzimmermann@suse.de>
Date: Wed, 1 Jun 2022 13:25:16 +0200
Subject: drm/mgag200: Call mgag200_device_probe_vram() from per-model init
Git-commit: d45e32c9d98ce7c22a4bafe69cee58165b59533b
Patch-mainline: v6.0-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225 jsc#PED-2849

Call mgag200_device_probe_vram() from each model's initializer. The
G200EW3 uses a special helper with additional instructions.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Tested-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220601112522.5774-5-tzimmermann@suse.de
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/mgag200/mgag200_drv.c     | 39 +++++++++++++++++++
 drivers/gpu/drm/mgag200/mgag200_drv.h     |  6 ++-
 drivers/gpu/drm/mgag200/mgag200_g200.c    |  5 ++-
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  5 ++-
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  5 ++-
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |  5 ++-
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  5 ++-
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 14 ++++++-
 drivers/gpu/drm/mgag200/mgag200_g200se.c  |  5 ++-
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  5 ++-
 drivers/gpu/drm/mgag200/mgag200_mm.c      | 47 +----------------------
 drivers/gpu/drm/mgag200/mgag200_mode.c    | 11 +++++-
 12 files changed, 94 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index ea765c1abcc1..1d53ddcc00df 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -50,6 +50,45 @@ int mgag200_init_pci_options(struct pci_dev *pdev, u32 option, u32 option2)
 	return 0;
 }
 
+resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size)
+{
+	int offset;
+	int orig;
+	int test1, test2;
+	int orig1, orig2;
+	size_t vram_size;
+
+	/* Probe */
+	orig = ioread16(mem);
+	iowrite16(0, mem);
+
+	vram_size = size;
+
+	for (offset = 0x100000; offset < vram_size; offset += 0x4000) {
+		orig1 = ioread8(mem + offset);
+		orig2 = ioread8(mem + offset + 0x100);
+
+		iowrite16(0xaa55, mem + offset);
+		iowrite16(0xaa55, mem + offset + 0x100);
+
+		test1 = ioread16(mem + offset);
+		test2 = ioread16(mem);
+
+		iowrite16(orig1, mem + offset);
+		iowrite16(orig2, mem + offset + 0x100);
+
+		if (test1 != 0xaa55)
+			break;
+
+		if (test2)
+			break;
+	}
+
+	iowrite16(orig, mem);
+
+	return offset - 65536;
+}
+
 /*
  * DRM driver
  */
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index d188382d60ca..21c7a689ed33 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -214,7 +214,7 @@ struct mga_device {
 	struct mga_mc			mc;
 
 	void __iomem			*vram;
-	size_t				vram_fb_available;
+	resource_size_t			vram_available;
 
 	enum mga_type			type;
 
@@ -257,6 +257,7 @@ static inline struct mgag200_g200se_device *to_mgag200_g200se_device(struct drm_
 
 				/* mgag200_drv.c */
 int mgag200_init_pci_options(struct pci_dev *pdev, u32 option, u32 option2);
+resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size);
 int mgag200_regs_init(struct mga_device *mdev);
 
 				/* mgag200_<device type>.c */
@@ -278,7 +279,8 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, const str
 						 enum mga_type type, unsigned long flags);
 
 				/* mgag200_mode.c */
-int mgag200_modeset_init(struct mga_device *mdev);
+resource_size_t mgag200_device_probe_vram(struct mga_device *mdev);
+int mgag200_modeset_init(struct mga_device *mdev, resource_size_t vram_fb_available);
 
 				/* mgag200_i2c.c */
 int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c);
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index b9ec6367719c..4e30b54a2677 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -162,6 +162,7 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
 	struct mgag200_g200_device *g200;
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	g200 = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200_device, base.base);
@@ -189,7 +190,9 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
index 3a531148c523..a16493db0512 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -15,6 +15,7 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
@@ -39,7 +40,9 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
index fbb53e624d90..478ca578b839 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -16,6 +16,7 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
@@ -40,7 +41,9 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c
index 1c5e757ec016..2f38fb470f4e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -15,6 +15,7 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
@@ -35,7 +36,9 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
index e55dd01ed42e..ff3c7b17ac44 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -15,6 +15,7 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
@@ -39,7 +40,9 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
index 6dd62135f0b2..971d40874cf3 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -10,12 +10,22 @@
  * DRM device
  */
 
+static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev)
+{
+	resource_size_t vram_size = mdev->mc.vram_size;
+
+	if (vram_size >= 0x1000000)
+		vram_size = vram_size - 0x400000;
+	return mgag200_probe_vram(mdev->vram, vram_size);
+}
+
 struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
 						 const struct drm_driver *drv,
 						 enum mga_type type, unsigned long flags)
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
@@ -40,7 +50,9 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_g200ew3_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c
index 75d284abb2a2..cd2987b58fcb 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -49,6 +49,7 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
 	struct mgag200_g200se_device *g200se;
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	g200se = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200se_device, base.base);
@@ -76,7 +77,9 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
index c622d5418731..38e374c00419 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -15,6 +15,7 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
+	resource_size_t vram_available;
 	int ret;
 
 	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
@@ -39,7 +40,9 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_modeset_init(mdev);
+	vram_available = mgag200_device_probe_vram(mdev);
+
+	ret = mgag200_modeset_init(mdev, vram_available);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_mm.c b/drivers/gpu/drm/mgag200/mgag200_mm.c
index fa996d46feed..fc19c2369641 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mm.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mm.c
@@ -32,49 +32,6 @@
 
 #include "mgag200_drv.h"
 
-static size_t mgag200_probe_vram(struct mga_device *mdev, void __iomem *mem,
-				 size_t size)
-{
-	int offset;
-	int orig;
-	int test1, test2;
-	int orig1, orig2;
-	size_t vram_size;
-
-	/* Probe */
-	orig = ioread16(mem);
-	iowrite16(0, mem);
-
-	vram_size = size;
-
-	if ((mdev->type == G200_EW3) && (vram_size >= 0x1000000))
-		vram_size = vram_size - 0x400000;
-
-	for (offset = 0x100000; offset < vram_size; offset += 0x4000) {
-		orig1 = ioread8(mem + offset);
-		orig2 = ioread8(mem + offset + 0x100);
-
-		iowrite16(0xaa55, mem + offset);
-		iowrite16(0xaa55, mem + offset + 0x100);
-
-		test1 = ioread16(mem + offset);
-		test2 = ioread16(mem);
-
-		iowrite16(orig1, mem + offset);
-		iowrite16(orig2, mem + offset + 0x100);
-
-		if (test1 != 0xaa55)
-			break;
-
-		if (test2)
-			break;
-	}
-
-	iowrite16(orig, mem);
-
-	return offset - 65536;
-}
-
 int mgag200_mm_init(struct mga_device *mdev)
 {
 	struct drm_device *dev = &mdev->base;
@@ -106,11 +63,9 @@ int mgag200_mm_init(struct mga_device *mdev)
 	if (!mdev->vram)
 		return -ENOMEM;
 
-	mdev->mc.vram_size = mgag200_probe_vram(mdev, mdev->vram, len);
+	mdev->mc.vram_size = len;
 	mdev->mc.vram_base = start;
 	mdev->mc.vram_window = len;
 
-	mdev->vram_fb_available = mdev->mc.vram_size;
-
 	return 0;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 2b034255a4af..c254988e5bcb 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -32,6 +32,11 @@
  * This file contains setup code for the CRTC.
  */
 
+resource_size_t mgag200_device_probe_vram(struct mga_device *mdev)
+{
+	return mgag200_probe_vram(mdev->vram, mdev->mc.vram_size);
+}
+
 static void mgag200_crtc_set_gamma_linear(struct mga_device *mdev,
 					  const struct drm_format_info *format)
 {
@@ -1030,7 +1035,7 @@ static enum drm_mode_status mgag200_mode_config_mode_valid(struct drm_device *de
 	unsigned long fbsize, fbpages, max_fbpages;
 	struct mgag200_g200se_device *g200se;
 
-	max_fbpages = mdev->vram_fb_available >> PAGE_SHIFT;
+	max_fbpages = mdev->vram_available >> PAGE_SHIFT;
 
 	fbsize = mode->hdisplay * mode->vdisplay * max_bpp;
 	fbpages = DIV_ROUND_UP(fbsize, PAGE_SIZE);
@@ -1075,7 +1080,7 @@ static const struct drm_mode_config_funcs mgag200_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
-int mgag200_modeset_init(struct mga_device *mdev)
+int mgag200_modeset_init(struct mga_device *mdev, resource_size_t vram_available)
 {
 	struct drm_device *dev = &mdev->base;
 	struct mga_i2c_chan *i2c = &mdev->i2c;
@@ -1086,6 +1091,8 @@ int mgag200_modeset_init(struct mga_device *mdev)
 
 	mgag200_init_regs(mdev);
 
+	mdev->vram_available = vram_available;
+
 	ret = drmm_mode_config_init(dev);
 	if (ret) {
 		drm_err(dev, "drmm_mode_config_init() failed, error %d\n",
-- 
2.38.1