All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: airlied@redhat.com, jfalempe@redhat.com, airlied@linux.ie,
	daniel@ffwll.ch
Cc: Thomas Zimmermann <tzimmermann@suse.de>, dri-devel@lists.freedesktop.org
Subject: [PATCH 08/10] drm/mgag200: Store maximum resolution and memory bandwith in device info
Date: Wed,  1 Jun 2022 13:25:20 +0200	[thread overview]
Message-ID: <20220601112522.5774-9-tzimmermann@suse.de> (raw)
In-Reply-To: <20220601112522.5774-1-tzimmermann@suse.de>

The maximum resolution and memory bandwidth are model-specific limits.
Both are used during display-mode validation. Store the values in struct
mgag200_device_info and simplify the validation code.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/mgag200_drv.h     | 15 ++++-
 drivers/gpu/drm/mgag200/mgag200_g200.c    |  2 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  2 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  2 +-
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |  2 +-
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  2 +-
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  2 +-
 drivers/gpu/drm/mgag200/mgag200_g200se.c  | 44 ++++++++++++---
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  2 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c    | 69 +++++++----------------
 10 files changed, 77 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index b05becb3d4b7..f0fb13238f4f 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -191,6 +191,15 @@ enum mga_type {
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
 struct mgag200_device_info {
+	u16 max_hdisplay;
+	u16 max_vdisplay;
+
+	/*
+	 * Maximum memory bandwidth (MiB/sec). Setting this to zero disables
+	 * the rsp test during mode validation.
+	 */
+	unsigned long max_mem_bandwidth;
+
 	/*
 	 * HW does not handle 'startadd' register correctly. Always set
 	 * it's value to 0.
@@ -198,8 +207,12 @@ struct mgag200_device_info {
 	bool bug_no_startadd:1;
 };
 
-#define MGAG200_DEVICE_INFO_INIT(_bug_no_startadd) \
+#define MGAG200_DEVICE_INFO_INIT(_max_hdisplay, _max_vdisplay, _max_mem_bandwidth, \
+				 _bug_no_startadd) \
 	{ \
+		.max_hdisplay = (_max_hdisplay), \
+		.max_vdisplay = (_max_vdisplay), \
+		.max_mem_bandwidth = (_max_mem_bandwidth), \
 		.bug_no_startadd = (_bug_no_startadd), \
 	}
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index 90b33a7352e5..4ec1b18ab170 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -34,7 +34,7 @@ static int mgag200_g200_init_pci_options(struct pci_dev *pdev)
  */
 
 static const struct mgag200_device_info mgag200_g200_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false);
 
 static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200,
 					const unsigned char *bios, size_t size)
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
index 14bec513e441..a35ba2fdfc0e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -11,7 +11,7 @@
  */
 
 static const struct mgag200_device_info mgag200_g200eh_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 37500, false);
 
 struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type)
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
index c982533de9e7..649559be1482 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -11,7 +11,7 @@
  */
 
 static const struct mgag200_device_info mgag200_g200eh3_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false);
 
 struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 						 const struct drm_driver *drv,
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c
index d84039eef982..e661fad2f8b2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -11,7 +11,7 @@
  */
 
 static const struct mgag200_device_info mgag200_g200er_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false);
 
 struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type)
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
index 14a891d47270..07a3862d69de 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -11,7 +11,7 @@
  */
 
 static const struct mgag200_device_info mgag200_g200ev_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 32700, false);
 
 struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type)
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
index b09f345ba29b..7f3987435085 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -11,7 +11,7 @@
  */
 
 static const struct mgag200_device_info mgag200_g200ew3_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false);
 
 static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev)
 {
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c
index 9c0fc57366f2..78120470b7be 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -32,21 +32,37 @@ static int mgag200_g200se_init_pci_options(struct pci_dev *pdev)
  * DRM device
  */
 
-static const struct mgag200_device_info mgag200_g200se_a_device_info =
-	MGAG200_DEVICE_INFO_INIT(true);
+static const struct mgag200_device_info mgag200_g200se_a_01_device_info =
+	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, true);
 
-static const struct mgag200_device_info mgag200_g200se_b_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+static const struct mgag200_device_info mgag200_g200se_a_02_device_info =
+	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, true);
 
-static void mgag200_g200se_init_unique_id(struct mgag200_g200se_device *g200se)
+static const struct mgag200_device_info mgag200_g200se_a_03_device_info =
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false);
+
+static const struct mgag200_device_info mgag200_g200se_b_01_device_info =
+	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false);
+
+static const struct mgag200_device_info mgag200_g200se_b_02_device_info =
+	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false);
+
+static const struct mgag200_device_info mgag200_g200se_b_03_device_info =
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false);
+
+static int mgag200_g200se_init_unique_rev_id(struct mgag200_g200se_device *g200se)
 {
 	struct mga_device *mdev = &g200se->base;
 	struct drm_device *dev = &mdev->base;
 
 	/* stash G200 SE model number for later use */
 	g200se->unique_rev_id = RREG32(0x1e24);
+	if (!g200se->unique_rev_id)
+		return -ENODEV;
 
 	drm_dbg(dev, "G200 SE unique revision id is 0x%x\n", g200se->unique_rev_id);
+
+	return 0;
 }
 
 struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
@@ -75,14 +91,26 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	mgag200_g200se_init_unique_id(g200se);
+	ret = mgag200_g200se_init_unique_rev_id(g200se);
+	if (ret)
+		return ERR_PTR(ret);
 
 	switch (type) {
 	case G200_SE_A:
-		info = &mgag200_g200se_a_device_info;
+		if (g200se->unique_rev_id >= 0x03)
+			info = &mgag200_g200se_a_03_device_info;
+		else if (g200se->unique_rev_id >= 0x02)
+			info = &mgag200_g200se_a_02_device_info;
+		else
+			info = &mgag200_g200se_a_01_device_info;
 		break;
 	case G200_SE_B:
-		info = &mgag200_g200se_b_device_info;
+		if (g200se->unique_rev_id >= 0x03)
+			info = &mgag200_g200se_b_03_device_info;
+		else if (g200se->unique_rev_id >= 0x02)
+			info = &mgag200_g200se_b_02_device_info;
+		else
+			info = &mgag200_g200se_b_01_device_info;
 		break;
 	default:
 		return ERR_PTR(-EINVAL);
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
index c9bf2176726e..0943ad2a9999 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -11,7 +11,7 @@
  */
 
 static const struct mgag200_device_info mgag200_g200wb_device_info =
-	MGAG200_DEVICE_INFO_INIT(false);
+	MGAG200_DEVICE_INFO_INIT(1280, 1024, 31877, false);
 
 struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index f5e1a89e0bfe..aa85558faa1b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -725,30 +725,17 @@ static enum drm_mode_status
 mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
 				       const struct drm_display_mode *mode)
 {
-	struct drm_device *dev = pipe->crtc.dev;
-	struct mga_device *mdev = to_mga_device(dev);
-	struct mgag200_g200se_device *g200se;
-
-	if (IS_G200_SE(mdev)) {
-		g200se = to_mgag200_g200se_device(dev);
-
-		if (g200se->unique_rev_id == 0x01) {
-			if (mode->hdisplay > 1600)
-				return MODE_VIRTUAL_X;
-			if (mode->vdisplay > 1200)
-				return MODE_VIRTUAL_Y;
-		} else if (g200se->unique_rev_id == 0x02) {
-			if (mode->hdisplay > 1920)
-				return MODE_VIRTUAL_X;
-			if (mode->vdisplay > 1200)
-				return MODE_VIRTUAL_Y;
-		}
-	} else if (mdev->type == G200_WB) {
-		if (mode->hdisplay > 1280)
-			return MODE_VIRTUAL_X;
-		if (mode->vdisplay > 1024)
-			return MODE_VIRTUAL_Y;
-	}
+	struct mga_device *mdev = to_mga_device(pipe->crtc.dev);
+	const struct mgag200_device_info *info = mdev->info;
+
+	/*
+	 * Some devices have additional limits on the size of the
+	 * display mode.
+	 */
+	if (mode->hdisplay > info->max_hdisplay)
+		return MODE_VIRTUAL_X;
+	if (mode->vdisplay > info->max_vdisplay)
+		return MODE_VIRTUAL_Y;
 
 	if ((mode->hdisplay % 8) != 0 || (mode->hsync_start % 8) != 0 ||
 	    (mode->hsync_end % 8) != 0 || (mode->htotal % 8) != 0) {
@@ -1028,7 +1015,7 @@ static enum drm_mode_status mgag200_mode_config_mode_valid(struct drm_device *de
 	static const unsigned int max_bpp = 4; // DRM_FORMAT_XRGB8888
 	struct mga_device *mdev = to_mga_device(dev);
 	unsigned long fbsize, fbpages, max_fbpages;
-	struct mgag200_g200se_device *g200se;
+	const struct mgag200_device_info *info = mdev->info;
 
 	max_fbpages = mdev->vram_available >> PAGE_SHIFT;
 
@@ -1038,30 +1025,14 @@ static enum drm_mode_status mgag200_mode_config_mode_valid(struct drm_device *de
 	if (fbpages > max_fbpages)
 		return MODE_MEM;
 
-	if (IS_G200_SE(mdev)) {
-		g200se = to_mgag200_g200se_device(dev);
-
-		if (g200se->unique_rev_id == 0x01) {
-			if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (24400 * 1024))
-				return MODE_BAD;
-		} else if (g200se->unique_rev_id == 0x02) {
-			if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (30100 * 1024))
-				return MODE_BAD;
-		} else {
-			if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (55000 * 1024))
-				return MODE_BAD;
-		}
-	} else if (mdev->type == G200_WB) {
-		if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (31877 * 1024))
-			return MODE_BAD;
-	} else if (mdev->type == G200_EV) {
-		if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (32700 * 1024))
-			return MODE_BAD;
-	} else if (mdev->type == G200_EH) {
-		if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (37500 * 1024))
-			return MODE_BAD;
-	} else if (mdev->type == G200_ER) {
-		if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (55000 * 1024))
+	/*
+	 * Test the mode's required memory bandwidth if the device
+	 * specifies a maximum. Not all devices do though.
+	 */
+	if (info->max_mem_bandwidth) {
+		uint32_t mode_bandwidth = mgag200_calculate_mode_bandwidth(mode, max_bpp * 8);
+
+		if (mode_bandwidth > (info->max_mem_bandwidth * 1024))
 			return MODE_BAD;
 	}
 
-- 
2.36.1


  parent reply	other threads:[~2022-06-01 11:25 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 01/10] drm/mgag200: Remove special case for G200SE with <2 MiB Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 02/10] drm/mgag200: Initialize each model in separate function Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 03/10] drm/mgag200: Move PCI-option setup into model-specific code Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 04/10] drm/mgag200: Call mgag200_device_probe_vram() from per-model init Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 05/10] drm/mgag200: Implement new init logic Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 06/10] drm/mgag200: Add struct mgag200_device_info Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 07/10] drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info Thomas Zimmermann
2022-06-01 11:25 ` Thomas Zimmermann [this message]
2022-06-01 11:25 ` [PATCH 09/10] drm/mgag200: Store vidrst " Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 10/10] drm/mgag200: Store positions of I2C data and clock bits " Thomas Zimmermann
2022-06-02  9:52 ` [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Jocelyn Falempe
2022-06-02 11:07   ` Thomas Zimmermann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220601112522.5774-9-tzimmermann@suse.de \
    --to=tzimmermann@suse.de \
    --cc=airlied@linux.ie \
    --cc=airlied@redhat.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jfalempe@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.