All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure
@ 2022-06-01 11:25 Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 01/10] drm/mgag200: Remove special case for G200SE with <2 MiB Thomas Zimmermann
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Convert the device-init code to use a device-info structure for each
model. The device info contains constants and flags that were previously
located in different places of the code.

Also refactor the PCI and VRAM initialization handling. A later patchset
could convert the PCI magic numbers into constants.

For modesetting, the per-model init functions currently don't do much.
This will change when more model-specific code gets moved there. The
modesetting and PLL code contains model-specific handling that should
be refactored.

Tested with G200 and G200EV hardware.

Thomas Zimmermann (10):
  drm/mgag200: Remove special case for G200SE with <2 MiB
  drm/mgag200: Initialize each model in separate function
  drm/mgag200: Move PCI-option setup into model-specific code
  drm/mgag200: Call mgag200_device_probe_vram() from per-model init
  drm/mgag200: Implement new init logic
  drm/mgag200: Add struct mgag200_device_info
  drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info
  drm/mgag200: Store maximum resolution and memory bandwith in device
    info
  drm/mgag200: Store vidrst flag in device info
  drm/mgag200: Store positions of I2C data and clock bits in device info

 drivers/gpu/drm/mgag200/Makefile          |  14 +-
 drivers/gpu/drm/mgag200/mgag200_drv.c     | 386 ++++++++--------------
 drivers/gpu/drm/mgag200/mgag200_drv.h     | 135 ++++++--
 drivers/gpu/drm/mgag200/mgag200_g200.c    | 200 +++++++++++
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  50 +++
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  51 +++
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |  46 +++
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  50 +++
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  60 ++++
 drivers/gpu/drm/mgag200/mgag200_g200se.c  | 130 ++++++++
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  50 +++
 drivers/gpu/drm/mgag200/mgag200_i2c.c     |  27 +-
 drivers/gpu/drm/mgag200/mgag200_mm.c      | 116 -------
 drivers/gpu/drm/mgag200/mgag200_mode.c    | 100 ++----
 drivers/gpu/drm/mgag200/mgag200_pll.c     |  12 +-
 drivers/gpu/drm/mgag200/mgag200_reg.h     |   2 +
 16 files changed, 942 insertions(+), 487 deletions(-)
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh3.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200er.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ev.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ew3.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200se.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200wb.c
 delete mode 100644 drivers/gpu/drm/mgag200/mgag200_mm.c


base-commit: 2c8cc5cd20e28afe6b63acb28890e5f57d9bf055
prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
-- 
2.36.1


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

* [PATCH 01/10] drm/mgag200: Remove special case for G200SE with <2 MiB
  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 ` Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 02/10] drm/mgag200: Initialize each model in separate function Thomas Zimmermann
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Remove old test for 32-bit vs 16-bit colors. Prefer 24-bit color depth
on all devices. 32-bit color depth doesn't exist, it should have always
been 24-bit.

G200SE with less than 2 MiB of video memory have defaulted to 16-bit
color depth, as the original revision of the G200SE had only 1.75 MiB
of video memory. Using 16-bit colors enabled XGA resolution. But we
now already limit these devices to VGA resolutions as the memory-bandwith
test assumes 32-bit pixel size. So drop the special case from color-depth
selection.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/mgag200_mode.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 028c6ba7124c..8cb72e11a2ea 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1072,14 +1072,6 @@ static const struct drm_mode_config_funcs mgag200_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
-static unsigned int mgag200_preferred_depth(struct mga_device *mdev)
-{
-	if (IS_G200_SE(mdev) && mdev->vram_fb_available < (2048*1024))
-		return 16;
-	else
-		return 32;
-}
-
 int mgag200_modeset_init(struct mga_device *mdev)
 {
 	struct drm_device *dev = &mdev->base;
@@ -1100,11 +1092,8 @@ int mgag200_modeset_init(struct mga_device *mdev)
 
 	dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
 	dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
-
-	dev->mode_config.preferred_depth = mgag200_preferred_depth(mdev);
-
+	dev->mode_config.preferred_depth = 24;
 	dev->mode_config.fb_base = mdev->mc.vram_base;
-
 	dev->mode_config.funcs = &mgag200_mode_config_funcs;
 
 	ret = mgag200_i2c_init(mdev, i2c);
-- 
2.36.1


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

* [PATCH 02/10] drm/mgag200: Initialize each model in separate function
  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 ` Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 03/10] drm/mgag200: Move PCI-option setup into model-specific code Thomas Zimmermann
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Add a separate initializer function for each model. Add separate
devic structures for G200 and G200SE, which require additional
information.

Also move G200's and G200SE's helpers for reading the BIOS and
version id into model-specific code.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/Makefile          |  15 +-
 drivers/gpu/drm/mgag200/mgag200_drv.c     | 206 ++++------------------
 drivers/gpu/drm/mgag200/mgag200_drv.h     |  59 +++++--
 drivers/gpu/drm/mgag200/mgag200_g200.c    | 170 ++++++++++++++++++
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  43 +++++
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  44 +++++
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |  43 +++++
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  43 +++++
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  44 +++++
 drivers/gpu/drm/mgag200/mgag200_g200se.c  |  58 ++++++
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  43 +++++
 drivers/gpu/drm/mgag200/mgag200_mode.c    |  25 +--
 drivers/gpu/drm/mgag200/mgag200_pll.c     |  12 +-
 13 files changed, 603 insertions(+), 202 deletions(-)
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh3.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200er.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ev.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ew3.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200se.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200wb.c

diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile
index d4f766522483..0c515a3b073d 100644
--- a/drivers/gpu/drm/mgag200/Makefile
+++ b/drivers/gpu/drm/mgag200/Makefile
@@ -1,4 +1,17 @@
 # SPDX-License-Identifier: GPL-2.0-only
-mgag200-y   := mgag200_drv.o mgag200_i2c.o mgag200_mm.o mgag200_mode.o mgag200_pll.o
+mgag200-y := \
+	mgag200_drv.o \
+	mgag200_g200.o \
+	mgag200_g200eh.o \
+	mgag200_g200eh3.o \
+	mgag200_g200er.o \
+	mgag200_g200ev.o \
+	mgag200_g200ew3.o \
+	mgag200_g200se.o \
+	mgag200_g200wb.o \
+	mgag200_i2c.o \
+	mgag200_mm.o \
+	mgag200_mode.o \
+	mgag200_pll.o
 
 obj-$(CONFIG_DRM_MGAG200) += mgag200.o
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 08839460606f..e5f06f44ec90 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -60,7 +60,7 @@ static bool mgag200_has_sgram(struct mga_device *mdev)
 	return !!(option & PCI_MGA_OPTION_HARDPWMSK);
 }
 
-static int mgag200_regs_init(struct mga_device *mdev)
+int mgag200_regs_init(struct mga_device *mdev)
 {
 	struct drm_device *dev = &mdev->base;
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
@@ -133,178 +133,6 @@ static int mgag200_regs_init(struct mga_device *mdev)
 	return 0;
 }
 
-static void mgag200_g200_interpret_bios(struct mga_device *mdev,
-					const unsigned char *bios,
-					size_t size)
-{
-	static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'};
-	static const unsigned int expected_length[6] = {
-		0, 64, 64, 64, 128, 128
-	};
-	struct drm_device *dev = &mdev->base;
-	const unsigned char *pins;
-	unsigned int pins_len, version;
-	int offset;
-	int tmp;
-
-	/* Test for MATROX string. */
-	if (size < 45 + sizeof(matrox))
-		return;
-	if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0)
-		return;
-
-	/* Get the PInS offset. */
-	if (size < MGA_BIOS_OFFSET + 2)
-		return;
-	offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET];
-
-	/* Get PInS data structure. */
-
-	if (size < offset + 6)
-		return;
-	pins = bios + offset;
-	if (pins[0] == 0x2e && pins[1] == 0x41) {
-		version = pins[5];
-		pins_len = pins[2];
-	} else {
-		version = 1;
-		pins_len = pins[0] + (pins[1] << 8);
-	}
-
-	if (version < 1 || version > 5) {
-		drm_warn(dev, "Unknown BIOS PInS version: %d\n", version);
-		return;
-	}
-	if (pins_len != expected_length[version]) {
-		drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n",
-			 pins_len, expected_length[version]);
-		return;
-	}
-	if (size < offset + pins_len)
-		return;
-
-	drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n",
-		    version, pins_len);
-
-	/* Extract the clock values */
-
-	switch (version) {
-	case 1:
-		tmp = pins[24] + (pins[25] << 8);
-		if (tmp)
-			mdev->model.g200.pclk_max = tmp * 10;
-		break;
-	case 2:
-		if (pins[41] != 0xff)
-			mdev->model.g200.pclk_max = (pins[41] + 100) * 1000;
-		break;
-	case 3:
-		if (pins[36] != 0xff)
-			mdev->model.g200.pclk_max = (pins[36] + 100) * 1000;
-		if (pins[52] & 0x20)
-			mdev->model.g200.ref_clk = 14318;
-		break;
-	case 4:
-		if (pins[39] != 0xff)
-			mdev->model.g200.pclk_max = pins[39] * 4 * 1000;
-		if (pins[92] & 0x01)
-			mdev->model.g200.ref_clk = 14318;
-		break;
-	case 5:
-		tmp = pins[4] ? 8000 : 6000;
-		if (pins[123] != 0xff)
-			mdev->model.g200.pclk_min = pins[123] * tmp;
-		if (pins[38] != 0xff)
-			mdev->model.g200.pclk_max = pins[38] * tmp;
-		if (pins[110] & 0x01)
-			mdev->model.g200.ref_clk = 14318;
-		break;
-	default:
-		break;
-	}
-}
-
-static void mgag200_g200_init_refclk(struct mga_device *mdev)
-{
-	struct drm_device *dev = &mdev->base;
-	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	unsigned char __iomem *rom;
-	unsigned char *bios;
-	size_t size;
-
-	mdev->model.g200.pclk_min = 50000;
-	mdev->model.g200.pclk_max = 230000;
-	mdev->model.g200.ref_clk = 27050;
-
-	rom = pci_map_rom(pdev, &size);
-	if (!rom)
-		return;
-
-	bios = vmalloc(size);
-	if (!bios)
-		goto out;
-	memcpy_fromio(bios, rom, size);
-
-	if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa)
-		mgag200_g200_interpret_bios(mdev, bios, size);
-
-	drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n",
-		    mdev->model.g200.pclk_min, mdev->model.g200.pclk_max,
-		    mdev->model.g200.ref_clk);
-
-	vfree(bios);
-out:
-	pci_unmap_rom(pdev, rom);
-}
-
-static void mgag200_g200se_init_unique_id(struct mga_device *mdev)
-{
-	struct drm_device *dev = &mdev->base;
-
-	/* stash G200 SE model number for later use */
-	mdev->model.g200se.unique_rev_id = RREG32(0x1e24);
-
-	drm_dbg(dev, "G200 SE unique revision id is 0x%x\n",
-		mdev->model.g200se.unique_rev_id);
-}
-
-static struct mga_device *
-mgag200_device_create(struct pci_dev *pdev, enum mga_type type, unsigned long flags)
-{
-	struct mga_device *mdev;
-	struct drm_device *dev;
-	int ret;
-
-	mdev = devm_drm_dev_alloc(&pdev->dev, &mgag200_driver, struct mga_device, base);
-	if (IS_ERR(mdev))
-		return mdev;
-	dev = &mdev->base;
-
-	pci_set_drvdata(pdev, dev);
-
-	mdev->flags = flags;
-	mdev->type = type;
-
-	ret = mgag200_regs_init(mdev);
-	if (ret)
-		return ERR_PTR(ret);
-
-	if (mdev->type == G200_PCI || mdev->type == G200_AGP)
-		mgag200_g200_init_refclk(mdev);
-	else if (IS_G200_SE(mdev))
-		mgag200_g200se_init_unique_id(mdev);
-
-	ret = mgag200_mm_init(mdev);
-	if (ret)
-		return ERR_PTR(ret);
-
-	ret = mgag200_modeset_init(mdev);
-	if (ret)
-		return ERR_PTR(ret);
-
-	return mdev;
-}
-
 /*
  * PCI driver
  */
@@ -354,7 +182,37 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (ret)
 		return ret;
 
-	mdev = mgag200_device_create(pdev, type, flags);
+	switch (type) {
+	case G200_PCI:
+	case G200_AGP:
+		mdev = mgag200_g200_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	case G200_SE_A:
+	case G200_SE_B:
+		mdev = mgag200_g200se_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	case G200_WB:
+		mdev = mgag200_g200wb_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	case G200_EV:
+		mdev = mgag200_g200ev_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	case G200_EH:
+		mdev = mgag200_g200eh_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	case G200_EH3:
+		mdev = mgag200_g200eh3_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	case G200_ER:
+		mdev = mgag200_g200er_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	case G200_EW3:
+		mdev = mgag200_g200ew3_device_create(pdev, &mgag200_driver, type, flags);
+		break;
+	default:
+		dev_err(&pdev->dev, "Device type %d is unsupported\n", type);
+		return -ENODEV;
+	}
 	if (IS_ERR(mdev))
 		return PTR_ERR(mdev);
 	dev = &mdev->base;
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 5634fc003ca4..99a9446b7df5 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -218,18 +218,6 @@ struct mga_device {
 
 	enum mga_type			type;
 
-	union {
-		struct {
-			long ref_clk;
-			long pclk_min;
-			long pclk_max;
-		} g200;
-		struct {
-			/* SE model number stored in reg 0x1e24 */
-			u32 unique_rev_id;
-		} g200se;
-	} model;
-
 	struct mgag200_pll pixpll;
 	struct mga_i2c_chan i2c;
 	struct drm_connector connector;
@@ -241,6 +229,53 @@ static inline struct mga_device *to_mga_device(struct drm_device *dev)
 	return container_of(dev, struct mga_device, base);
 }
 
+struct mgag200_g200_device {
+	struct mga_device base;
+
+	/* PLL constants */
+	long ref_clk;
+	long pclk_min;
+	long pclk_max;
+};
+
+static inline struct mgag200_g200_device *to_mgag200_g200_device(struct drm_device *dev)
+{
+	return container_of(to_mga_device(dev), struct mgag200_g200_device, base);
+}
+
+struct mgag200_g200se_device {
+	struct mga_device base;
+
+	/* SE model number stored in reg 0x1e24 */
+	u32 unique_rev_id;
+};
+
+static inline struct mgag200_g200se_device *to_mgag200_g200se_device(struct drm_device *dev)
+{
+	return container_of(to_mga_device(dev), struct mgag200_g200se_device, base);
+}
+
+				/* mgag200_drv.c */
+int mgag200_regs_init(struct mga_device *mdev);
+
+				/* mgag200_<device type>.c */
+struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+					      enum mga_type type, unsigned long flags);
+struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						enum mga_type type, unsigned long flags);
+struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						enum mga_type type, unsigned long flags);
+struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						enum mga_type type, unsigned long flags);
+struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						enum mga_type type, unsigned long flags);
+struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						 enum mga_type type, unsigned long flags);
+struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						enum mga_type type, unsigned long flags);
+struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						 enum mga_type type, unsigned long flags);
+
 				/* mgag200_mode.c */
 int mgag200_modeset_init(struct mga_device *mdev);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
new file mode 100644
index 000000000000..ca9522daf6e1
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM Device
+ */
+
+static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200,
+					const unsigned char *bios, size_t size)
+{
+	static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'};
+	static const unsigned int expected_length[6] = {
+		0, 64, 64, 64, 128, 128
+	};
+	struct mga_device *mdev = &g200->base;
+	struct drm_device *dev = &mdev->base;
+	const unsigned char *pins;
+	unsigned int pins_len, version;
+	int offset;
+	int tmp;
+
+	/* Test for MATROX string. */
+	if (size < 45 + sizeof(matrox))
+		return;
+	if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0)
+		return;
+
+	/* Get the PInS offset. */
+	if (size < MGA_BIOS_OFFSET + 2)
+		return;
+	offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET];
+
+	/* Get PInS data structure. */
+
+	if (size < offset + 6)
+		return;
+	pins = bios + offset;
+	if (pins[0] == 0x2e && pins[1] == 0x41) {
+		version = pins[5];
+		pins_len = pins[2];
+	} else {
+		version = 1;
+		pins_len = pins[0] + (pins[1] << 8);
+	}
+
+	if (version < 1 || version > 5) {
+		drm_warn(dev, "Unknown BIOS PInS version: %d\n", version);
+		return;
+	}
+	if (pins_len != expected_length[version]) {
+		drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n",
+			 pins_len, expected_length[version]);
+		return;
+	}
+	if (size < offset + pins_len)
+		return;
+
+	drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n", version, pins_len);
+
+	/* Extract the clock values */
+
+	switch (version) {
+	case 1:
+		tmp = pins[24] + (pins[25] << 8);
+		if (tmp)
+			g200->pclk_max = tmp * 10;
+		break;
+	case 2:
+		if (pins[41] != 0xff)
+			g200->pclk_max = (pins[41] + 100) * 1000;
+		break;
+	case 3:
+		if (pins[36] != 0xff)
+			g200->pclk_max = (pins[36] + 100) * 1000;
+		if (pins[52] & 0x20)
+			g200->ref_clk = 14318;
+		break;
+	case 4:
+		if (pins[39] != 0xff)
+			g200->pclk_max = pins[39] * 4 * 1000;
+		if (pins[92] & 0x01)
+			g200->ref_clk = 14318;
+		break;
+	case 5:
+		tmp = pins[4] ? 8000 : 6000;
+		if (pins[123] != 0xff)
+			g200->pclk_min = pins[123] * tmp;
+		if (pins[38] != 0xff)
+			g200->pclk_max = pins[38] * tmp;
+		if (pins[110] & 0x01)
+			g200->ref_clk = 14318;
+		break;
+	default:
+		break;
+	}
+}
+
+static void mgag200_g200_init_refclk(struct mgag200_g200_device *g200)
+{
+	struct mga_device *mdev = &g200->base;
+	struct drm_device *dev = &mdev->base;
+	struct pci_dev *pdev = to_pci_dev(dev->dev);
+	unsigned char __iomem *rom;
+	unsigned char *bios;
+	size_t size;
+
+	g200->pclk_min = 50000;
+	g200->pclk_max = 230000;
+	g200->ref_clk = 27050;
+
+	rom = pci_map_rom(pdev, &size);
+	if (!rom)
+		return;
+
+	bios = vmalloc(size);
+	if (!bios)
+		goto out;
+	memcpy_fromio(bios, rom, size);
+
+	if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa)
+		mgag200_g200_interpret_bios(g200, bios, size);
+
+	drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n",
+		    g200->pclk_min, g200->pclk_max, g200->ref_clk);
+
+	vfree(bios);
+out:
+	pci_unmap_rom(pdev, rom);
+}
+
+struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+					      enum mga_type type, unsigned long flags)
+{
+	struct mgag200_g200_device *g200;
+	struct mga_device *mdev;
+	struct drm_device *dev;
+	int ret;
+
+	g200 = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200_device, base.base);
+	if (IS_ERR(g200))
+		return ERR_CAST(g200);
+	mdev = &g200->base;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	mgag200_g200_init_refclk(g200);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
new file mode 100644
index 000000000000..67c7c75ea791
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM device
+ */
+
+struct mga_device *mgag200_g200eh_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;
+	int ret;
+
+	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
+	if (IS_ERR(mdev))
+		return mdev;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
new file mode 100644
index 000000000000..b7a3f9551bfd
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM device
+ */
+
+struct mga_device *mgag200_g200eh3_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;
+	int ret;
+
+	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
+	if (IS_ERR(mdev))
+		return mdev;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c
new file mode 100644
index 000000000000..1c5e757ec016
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM device
+ */
+
+struct mga_device *mgag200_g200er_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;
+	int ret;
+
+	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
+	if (IS_ERR(mdev))
+		return mdev;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
new file mode 100644
index 000000000000..f8afd05913fd
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM device
+ */
+
+struct mga_device *mgag200_g200ev_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;
+	int ret;
+
+	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
+	if (IS_ERR(mdev))
+		return mdev;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
new file mode 100644
index 000000000000..f65bb94e0b3d
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM device
+ */
+
+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;
+	int ret;
+
+	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
+	if (IS_ERR(mdev))
+		return mdev;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c
new file mode 100644
index 000000000000..d809cc680024
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM device
+ */
+
+static void mgag200_g200se_init_unique_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);
+
+	drm_dbg(dev, "G200 SE unique revision id is 0x%x\n", g200se->unique_rev_id);
+}
+
+struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
+						enum mga_type type, unsigned long flags)
+{
+	struct mgag200_g200se_device *g200se;
+	struct mga_device *mdev;
+	struct drm_device *dev;
+	int ret;
+
+	g200se = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200se_device, base.base);
+	if (IS_ERR(g200se))
+		return ERR_CAST(g200se);
+	mdev = &g200se->base;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	mgag200_g200se_init_unique_id(g200se);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
new file mode 100644
index 000000000000..67b28646386d
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/pci.h>
+
+#include <drm/drm_drv.h>
+
+#include "mgag200_drv.h"
+
+/*
+ * DRM device
+ */
+
+struct mga_device *mgag200_g200wb_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;
+	int ret;
+
+	mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base);
+	if (IS_ERR(mdev))
+		return mdev;
+	dev = &mdev->base;
+
+	pci_set_drvdata(pdev, dev);
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = mgag200_regs_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_mm_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = mgag200_modeset_init(mdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return mdev;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 8cb72e11a2ea..2b034255a4af 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -583,13 +583,13 @@ static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev,
 					const struct drm_display_mode *mode,
 					const struct drm_framebuffer *fb)
 {
-	u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
+	struct mgag200_g200se_device *g200se = to_mgag200_g200se_device(&mdev->base);
 	unsigned int hiprilvl;
 	u8 crtcext6;
 
-	if  (unique_rev_id >= 0x04) {
+	if  (g200se->unique_rev_id >= 0x04) {
 		hiprilvl = 0;
-	} else if (unique_rev_id >= 0x02) {
+	} else if (g200se->unique_rev_id >= 0x02) {
 		unsigned int bpp;
 		unsigned long mb;
 
@@ -614,7 +614,7 @@ static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev,
 		else
 			hiprilvl = 5;
 
-	} else if (unique_rev_id >= 0x01) {
+	} else if (g200se->unique_rev_id >= 0x01) {
 		hiprilvl = 3;
 	} else {
 		hiprilvl = 4;
@@ -725,17 +725,19 @@ static enum drm_mode_status
 mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
 				       const struct drm_display_mode *mode)
 {
-	struct mga_device *mdev = to_mga_device(pipe->crtc.dev);
+	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)) {
-		u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
+		g200se = to_mgag200_g200se_device(dev);
 
-		if (unique_rev_id == 0x01) {
+		if (g200se->unique_rev_id == 0x01) {
 			if (mode->hdisplay > 1600)
 				return MODE_VIRTUAL_X;
 			if (mode->vdisplay > 1200)
 				return MODE_VIRTUAL_Y;
-		} else if (unique_rev_id == 0x02) {
+		} else if (g200se->unique_rev_id == 0x02) {
 			if (mode->hdisplay > 1920)
 				return MODE_VIRTUAL_X;
 			if (mode->vdisplay > 1200)
@@ -1026,6 +1028,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;
 
 	max_fbpages = mdev->vram_fb_available >> PAGE_SHIFT;
 
@@ -1036,12 +1039,12 @@ static enum drm_mode_status mgag200_mode_config_mode_valid(struct drm_device *de
 		return MODE_MEM;
 
 	if (IS_G200_SE(mdev)) {
-		u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
+		g200se = to_mgag200_g200se_device(dev);
 
-		if (unique_rev_id == 0x01) {
+		if (g200se->unique_rev_id == 0x01) {
 			if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (24400 * 1024))
 				return MODE_BAD;
-		} else if (unique_rev_id == 0x02) {
+		} else if (g200se->unique_rev_id == 0x02) {
 			if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (30100 * 1024))
 				return MODE_BAD;
 		} else {
diff --git a/drivers/gpu/drm/mgag200/mgag200_pll.c b/drivers/gpu/drm/mgag200/mgag200_pll.c
index 52be08b744ad..8065ca5d8de9 100644
--- a/drivers/gpu/drm/mgag200/mgag200_pll.c
+++ b/drivers/gpu/drm/mgag200/mgag200_pll.c
@@ -13,6 +13,7 @@ static int mgag200_pixpll_compute_g200(struct mgag200_pll *pixpll, long clock,
 {
 	struct mga_device *mdev = pixpll->mdev;
 	struct drm_device *dev = &mdev->base;
+	struct mgag200_g200_device *g200 = to_mgag200_g200_device(dev);
 	const int post_div_max = 7;
 	const int in_div_min = 1;
 	const int in_div_max = 6;
@@ -23,9 +24,9 @@ static int mgag200_pixpll_compute_g200(struct mgag200_pll *pixpll, long clock,
 	long f_vco;
 	long computed;
 	long delta, tmp_delta;
-	long ref_clk = mdev->model.g200.ref_clk;
-	long p_clk_min = mdev->model.g200.pclk_min;
-	long p_clk_max =  mdev->model.g200.pclk_max;
+	long ref_clk = g200->ref_clk;
+	long p_clk_min = g200->pclk_min;
+	long p_clk_max = g200->pclk_max;
 
 	if (clock > p_clk_max) {
 		drm_err(dev, "Pixel Clock %ld too high\n", clock);
@@ -951,6 +952,7 @@ static const struct mgag200_pll_funcs mgag200_pixpll_funcs_g200ew3 = {
 int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev)
 {
 	struct drm_device *dev = &mdev->base;
+	struct mgag200_g200se_device *g200se;
 
 	pixpll->mdev = mdev;
 
@@ -961,7 +963,9 @@ int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev)
 		break;
 	case G200_SE_A:
 	case G200_SE_B:
-		if (mdev->model.g200se.unique_rev_id >= 0x04)
+		g200se = to_mgag200_g200se_device(dev);
+
+		if (g200se->unique_rev_id >= 0x04)
 			pixpll->funcs = &mgag200_pixpll_funcs_g200se_04;
 		else
 			pixpll->funcs = &mgag200_pixpll_funcs_g200se_00;
-- 
2.36.1


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

* [PATCH 03/10] drm/mgag200: Move PCI-option setup into model-specific code
  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 ` Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 04/10] drm/mgag200: Call mgag200_device_probe_vram() from per-model init Thomas Zimmermann
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Split the PCI code into a single call for each model. G200 and G200SE
each contain a dedicated helper with additional instructions. Noteably,
the G200ER has no code for PCI setup.

In a later patch, the magic numbers should be replaced by descriptive
constants.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/mgag200_drv.c     | 81 ++++++++---------------
 drivers/gpu/drm/mgag200/mgag200_drv.h     |  1 +
 drivers/gpu/drm/mgag200/mgag200_g200.c    | 27 ++++++++
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  4 ++
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  4 ++
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  4 ++
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  4 ++
 drivers/gpu/drm/mgag200/mgag200_g200se.c  | 26 ++++++++
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  4 ++
 9 files changed, 100 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index e5f06f44ec90..ea765c1abcc1 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -24,6 +24,32 @@ int mgag200_modeset = -1;
 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
 module_param_named(modeset, mgag200_modeset, int, 0400);
 
+int mgag200_init_pci_options(struct pci_dev *pdev, u32 option, u32 option2)
+{
+	struct device *dev = &pdev->dev;
+	int err;
+
+	err = pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
+	if (err != PCIBIOS_SUCCESSFUL) {
+		dev_err(dev, "pci_read_config_dword(PCI_MGA_OPTION) failed: %d\n", err);
+		return pcibios_err_to_errno(err);
+	}
+
+	err = pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
+	if (err != PCIBIOS_SUCCESSFUL) {
+		dev_err(dev, "pci_write_config_dword(PCI_MGA_OPTION) failed: %d\n", err);
+		return pcibios_err_to_errno(err);
+	}
+
+	err = pci_write_config_dword(pdev, PCI_MGA_OPTION2, option2);
+	if (err != PCIBIOS_SUCCESSFUL) {
+		dev_err(dev, "pci_write_config_dword(PCI_MGA_OPTION2) failed: %d\n", err);
+		return pcibios_err_to_errno(err);
+	}
+
+	return 0;
+}
+
 /*
  * DRM driver
  */
@@ -46,25 +72,10 @@ static const struct drm_driver mgag200_driver = {
  * DRM device
  */
 
-static bool mgag200_has_sgram(struct mga_device *mdev)
-{
-	struct drm_device *dev = &mdev->base;
-	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	u32 option;
-	int ret;
-
-	ret = pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
-	if (drm_WARN(dev, ret, "failed to read PCI config dword: %d\n", ret))
-		return false;
-
-	return !!(option & PCI_MGA_OPTION_HARDPWMSK);
-}
-
 int mgag200_regs_init(struct mga_device *mdev)
 {
 	struct drm_device *dev = &mdev->base;
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	u32 option, option2;
 	u8 crtcext3;
 	int ret;
 
@@ -72,46 +83,6 @@ int mgag200_regs_init(struct mga_device *mdev)
 	if (ret)
 		return ret;
 
-	switch (mdev->type) {
-	case G200_PCI:
-	case G200_AGP:
-		if (mgag200_has_sgram(mdev))
-			option = 0x4049cd21;
-		else
-			option = 0x40499121;
-		option2 = 0x00008000;
-		break;
-	case G200_SE_A:
-	case G200_SE_B:
-		option = 0x40049120;
-		if (mgag200_has_sgram(mdev))
-			option |= PCI_MGA_OPTION_HARDPWMSK;
-		option2 = 0x00008000;
-		break;
-	case G200_WB:
-	case G200_EW3:
-		option = 0x41049120;
-		option2 = 0x0000b000;
-		break;
-	case G200_EV:
-		option = 0x00000120;
-		option2 = 0x0000b000;
-		break;
-	case G200_EH:
-	case G200_EH3:
-		option = 0x00000120;
-		option2 = 0x0000b000;
-		break;
-	default:
-		option = 0;
-		option2 = 0;
-	}
-
-	if (option)
-		pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
-	if (option2)
-		pci_write_config_dword(pdev, PCI_MGA_OPTION2, option2);
-
 	/* BAR 1 contains registers */
 	mdev->rmmio_base = pci_resource_start(pdev, 1);
 	mdev->rmmio_size = pci_resource_len(pdev, 1);
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 99a9446b7df5..d188382d60ca 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -256,6 +256,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);
 int mgag200_regs_init(struct mga_device *mdev);
 
 				/* mgag200_<device type>.c */
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index ca9522daf6e1..b9ec6367719c 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -6,6 +6,29 @@
 
 #include "mgag200_drv.h"
 
+static int mgag200_g200_init_pci_options(struct pci_dev *pdev)
+{
+	struct device *dev = &pdev->dev;
+	bool has_sgram;
+	u32 option;
+	int err;
+
+	err = pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
+	if (err != PCIBIOS_SUCCESSFUL) {
+		dev_err(dev, "pci_read_config_dword(PCI_MGA_OPTION) failed: %d\n", err);
+		return pcibios_err_to_errno(err);
+	}
+
+	has_sgram = !!(option & PCI_MGA_OPTION_HARDPWMSK);
+
+	if (has_sgram)
+		option = 0x4049cd21;
+	else
+		option = 0x40499121;
+
+	return mgag200_init_pci_options(pdev, option, 0x00008000);
+}
+
 /*
  * DRM Device
  */
@@ -149,6 +172,10 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
 
 	pci_set_drvdata(pdev, dev);
 
+	ret = mgag200_g200_init_pci_options(pdev);
+	if (ret)
+		return ERR_PTR(ret);
+
 	mdev->flags = flags;
 	mdev->type = type;
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
index 67c7c75ea791..3a531148c523 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -27,6 +27,10 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
 	mdev->flags = flags;
 	mdev->type = type;
 
+	ret = mgag200_init_pci_options(pdev, 0x00000120, 0x0000b000);
+	if (ret)
+		return ERR_PTR(ret);
+
 	ret = mgag200_regs_init(mdev);
 	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 b7a3f9551bfd..fbb53e624d90 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -28,6 +28,10 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 	mdev->flags = flags;
 	mdev->type = type;
 
+	ret = mgag200_init_pci_options(pdev, 0x00000120, 0x0000b000);
+	if (ret)
+		return ERR_PTR(ret);
+
 	ret = mgag200_regs_init(mdev);
 	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 f8afd05913fd..e55dd01ed42e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -24,6 +24,10 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
 
 	pci_set_drvdata(pdev, dev);
 
+	ret = mgag200_init_pci_options(pdev, 0x00000120, 0x0000b000);
+	if (ret)
+		return ERR_PTR(ret);
+
 	mdev->flags = flags;
 	mdev->type = type;
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
index f65bb94e0b3d..6dd62135f0b2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -25,6 +25,10 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
 
 	pci_set_drvdata(pdev, dev);
 
+	ret = mgag200_init_pci_options(pdev, 0x41049120, 0x0000b000);
+	if (ret)
+		return ERR_PTR(ret);
+
 	mdev->flags = flags;
 	mdev->type = type;
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c
index d809cc680024..75d284abb2a2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -6,6 +6,28 @@
 
 #include "mgag200_drv.h"
 
+static int mgag200_g200se_init_pci_options(struct pci_dev *pdev)
+{
+	struct device *dev = &pdev->dev;
+	bool has_sgram;
+	u32 option;
+	int err;
+
+	err = pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
+	if (err != PCIBIOS_SUCCESSFUL) {
+		dev_err(dev, "pci_read_config_dword(PCI_MGA_OPTION) failed: %d\n", err);
+		return pcibios_err_to_errno(err);
+	}
+
+	has_sgram = !!(option & PCI_MGA_OPTION_HARDPWMSK);
+
+	option = 0x40049120;
+	if (has_sgram)
+		option |= PCI_MGA_OPTION_HARDPWMSK;
+
+	return mgag200_init_pci_options(pdev, option, 0x00008000);
+}
+
 /*
  * DRM device
  */
@@ -37,6 +59,10 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
 
 	pci_set_drvdata(pdev, dev);
 
+	ret = mgag200_g200se_init_pci_options(pdev);
+	if (ret)
+		return ERR_PTR(ret);
+
 	mdev->flags = flags;
 	mdev->type = type;
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
index 67b28646386d..c622d5418731 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -24,6 +24,10 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
 
 	pci_set_drvdata(pdev, dev);
 
+	ret = mgag200_init_pci_options(pdev, 0x41049120, 0x0000b000);
+	if (ret)
+		return ERR_PTR(ret);
+
 	mdev->flags = flags;
 	mdev->type = type;
 
-- 
2.36.1


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

* [PATCH 04/10] drm/mgag200: Call mgag200_device_probe_vram() from per-model init
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (2 preceding siblings ...)
  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 ` Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 05/10] drm/mgag200: Implement new init logic Thomas Zimmermann
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

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>
---
 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.36.1


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

* [PATCH 05/10] drm/mgag200: Implement new init logic
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (3 preceding siblings ...)
  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 ` Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 06/10] drm/mgag200: Add struct mgag200_device_info Thomas Zimmermann
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Rework mgag200_regs_init() and mgag200_mm_init() into device preinit
and init functions. The preinit function, mgag200_device_preinit(),
requests and maps a device's I/O and video memory. The init function,
mgag200_device_init() initializes the state of struct mga_device.
Splitting the initialization between the two functions is necessary
to perform per-model operations between the two calls, such as reading
the unique revision ID on G200SEs.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/Makefile          |  1 -
 drivers/gpu/drm/mgag200/mgag200_drv.c     | 78 +++++++++++++++++++----
 drivers/gpu/drm/mgag200/mgag200_drv.h     | 21 ++----
 drivers/gpu/drm/mgag200/mgag200_g200.c    |  7 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  7 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  7 +-
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |  7 +-
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  7 +-
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  9 +--
 drivers/gpu/drm/mgag200/mgag200_g200se.c  |  7 +-
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  7 +-
 drivers/gpu/drm/mgag200/mgag200_mm.c      | 71 ---------------------
 drivers/gpu/drm/mgag200/mgag200_mode.c    |  7 +-
 13 files changed, 88 insertions(+), 148 deletions(-)
 delete mode 100644 drivers/gpu/drm/mgag200/mgag200_mm.c

diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile
index 0c515a3b073d..89558549c3af 100644
--- a/drivers/gpu/drm/mgag200/Makefile
+++ b/drivers/gpu/drm/mgag200/Makefile
@@ -10,7 +10,6 @@ mgag200-y := \
 	mgag200_g200se.o \
 	mgag200_g200wb.o \
 	mgag200_i2c.o \
-	mgag200_mm.o \
 	mgag200_mode.o \
 	mgag200_pll.o
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 1d53ddcc00df..8f636db4a723 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -111,35 +111,85 @@ static const struct drm_driver mgag200_driver = {
  * DRM device
  */
 
-int mgag200_regs_init(struct mga_device *mdev)
+resource_size_t mgag200_device_probe_vram(struct mga_device *mdev)
+{
+	return mgag200_probe_vram(mdev->vram, resource_size(mdev->vram_res));
+}
+
+int mgag200_device_preinit(struct mga_device *mdev)
 {
 	struct drm_device *dev = &mdev->base;
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	u8 crtcext3;
-	int ret;
-
-	ret = drmm_mutex_init(dev, &mdev->rmmio_lock);
-	if (ret)
-		return ret;
+	resource_size_t start, len;
+	struct resource *res;
 
 	/* BAR 1 contains registers */
-	mdev->rmmio_base = pci_resource_start(pdev, 1);
-	mdev->rmmio_size = pci_resource_len(pdev, 1);
 
-	if (!devm_request_mem_region(dev->dev, mdev->rmmio_base,
-				     mdev->rmmio_size, "mgadrmfb_mmio")) {
-		drm_err(dev, "can't reserve mmio registers\n");
-		return -ENOMEM;
+	start = pci_resource_start(pdev, 1);
+	len = pci_resource_len(pdev, 1);
+
+	res = devm_request_mem_region(dev->dev, start, len, "mgadrmfb_mmio");
+	if (!res) {
+		drm_err(dev, "devm_request_mem_region(MMIO) failed\n");
+		return -ENXIO;
 	}
+	mdev->rmmio_res = res;
 
 	mdev->rmmio = pcim_iomap(pdev, 1, 0);
-	if (mdev->rmmio == NULL)
+	if (!mdev->rmmio)
+		return -ENOMEM;
+
+	/* BAR 0 is VRAM */
+
+	start = pci_resource_start(pdev, 0);
+	len = pci_resource_len(pdev, 0);
+
+	res = devm_request_mem_region(dev->dev, start, len, "mgadrmfb_vram");
+	if (!res) {
+		drm_err(dev, "devm_request_mem_region(VRAM) failed\n");
+		return -ENXIO;
+	}
+	mdev->vram_res = res;
+
+	/* Don't fail on errors, but performance might be reduced. */
+	devm_arch_io_reserve_memtype_wc(dev->dev, res->start, resource_size(res));
+	devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res));
+
+	mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res));
+	if (!mdev->vram)
 		return -ENOMEM;
 
+	return 0;
+}
+
+int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags)
+{
+	struct drm_device *dev = &mdev->base;
+	u8 crtcext3, misc;
+	int ret;
+
+	mdev->flags = flags;
+	mdev->type = type;
+
+	ret = drmm_mutex_init(dev, &mdev->rmmio_lock);
+	if (ret)
+		return ret;
+
+	mutex_lock(&mdev->rmmio_lock);
+
 	RREG_ECRT(0x03, crtcext3);
 	crtcext3 |= MGAREG_CRTCEXT3_MGAMODE;
 	WREG_ECRT(0x03, crtcext3);
 
+	WREG_ECRT(0x04, 0x00);
+
+	misc = RREG8(MGA_MISC_IN);
+	misc |= MGAREG_MISC_RAMMAPEN |
+		MGAREG_MISC_HIGH_PG_SEL;
+	WREG8(MGA_MISC_OUT, misc);
+
+	mutex_unlock(&mdev->rmmio_lock);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 21c7a689ed33..9abecf366268 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -175,12 +175,6 @@ struct mga_i2c_chan {
 	int data, clock;
 };
 
-struct mga_mc {
-	resource_size_t			vram_size;
-	resource_size_t			vram_base;
-	resource_size_t			vram_window;
-};
-
 enum mga_type {
 	G200_PCI,
 	G200_AGP,
@@ -206,13 +200,11 @@ struct mga_device {
 	struct drm_device		base;
 	unsigned long			flags;
 
-	struct mutex			rmmio_lock; /* Protects access to rmmio */
-	resource_size_t			rmmio_base;
-	resource_size_t			rmmio_size;
+	struct resource			*rmmio_res;
 	void __iomem			*rmmio;
+	struct mutex			rmmio_lock; /* Protects access to rmmio */
 
-	struct mga_mc			mc;
-
+	struct resource			*vram_res;
 	void __iomem			*vram;
 	resource_size_t			vram_available;
 
@@ -258,7 +250,9 @@ 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);
+resource_size_t mgag200_device_probe_vram(struct mga_device *mdev);
+int mgag200_device_preinit(struct mga_device *mdev);
+int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags);
 
 				/* mgag200_<device type>.c */
 struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
@@ -285,9 +279,6 @@ int mgag200_modeset_init(struct mga_device *mdev, resource_size_t vram_fb_availa
 				/* mgag200_i2c.c */
 int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c);
 
-				/* mgag200_mm.c */
-int mgag200_mm_init(struct mga_device *mdev);
-
 				/* mgag200_pll.c */
 int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index 4e30b54a2677..4300a472c0a3 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -177,16 +177,13 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
 	if (ret)
 		return ERR_PTR(ret);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
 	mgag200_g200_init_refclk(g200);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	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 a16493db0512..7af9bdfb03c7 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -25,18 +25,15 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
 
 	pci_set_drvdata(pdev, dev);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
 	ret = mgag200_init_pci_options(pdev, 0x00000120, 0x0000b000);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	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 478ca578b839..c0695d5c4f68 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -26,18 +26,15 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 
 	pci_set_drvdata(pdev, dev);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
 	ret = mgag200_init_pci_options(pdev, 0x00000120, 0x0000b000);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	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 2f38fb470f4e..281317450fad 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -25,14 +25,11 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
 
 	pci_set_drvdata(pdev, dev);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	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 ff3c7b17ac44..41f948962b93 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -29,14 +29,11 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	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 971d40874cf3..89346815e107 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -12,7 +12,7 @@
 
 static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev)
 {
-	resource_size_t vram_size = mdev->mc.vram_size;
+	resource_size_t vram_size = resource_size(mdev->vram_res);
 
 	if (vram_size >= 0x1000000)
 		vram_size = vram_size - 0x400000;
@@ -39,14 +39,11 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	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 cd2987b58fcb..b23459710372 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -64,16 +64,13 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
 	mgag200_g200se_init_unique_id(g200se);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	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 38e374c00419..776bad867b4d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -29,14 +29,11 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	mdev->flags = flags;
-	mdev->type = type;
-
-	ret = mgag200_regs_init(mdev);
+	ret = mgag200_device_preinit(mdev);
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_mm_init(mdev);
+	ret = mgag200_device_init(mdev, type, flags);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_mm.c b/drivers/gpu/drm/mgag200/mgag200_mm.c
deleted file mode 100644
index fc19c2369641..000000000000
--- a/drivers/gpu/drm/mgag200/mgag200_mm.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- */
-/*
- * Authors: Dave Airlie <airlied@redhat.com>
- */
-
-#include <linux/pci.h>
-
-#include <drm/drm_managed.h>
-
-#include "mgag200_drv.h"
-
-int mgag200_mm_init(struct mga_device *mdev)
-{
-	struct drm_device *dev = &mdev->base;
-	struct pci_dev *pdev = to_pci_dev(dev->dev);
-	u8 misc;
-	resource_size_t start, len;
-
-	WREG_ECRT(0x04, 0x00);
-
-	misc = RREG8(MGA_MISC_IN);
-	misc |= MGAREG_MISC_RAMMAPEN |
-		MGAREG_MISC_HIGH_PG_SEL;
-	WREG8(MGA_MISC_OUT, misc);
-
-	/* BAR 0 is VRAM */
-	start = pci_resource_start(pdev, 0);
-	len = pci_resource_len(pdev, 0);
-
-	if (!devm_request_mem_region(dev->dev, start, len, "mgadrmfb_vram")) {
-		drm_err(dev, "can't reserve VRAM\n");
-		return -ENXIO;
-	}
-
-	/* Don't fail on errors, but performance might be reduced. */
-	devm_arch_io_reserve_memtype_wc(dev->dev, start, len);
-	devm_arch_phys_wc_add(dev->dev, start, len);
-
-	mdev->vram = devm_ioremap(dev->dev, start, len);
-	if (!mdev->vram)
-		return -ENOMEM;
-
-	mdev->mc.vram_size = len;
-	mdev->mc.vram_base = start;
-	mdev->mc.vram_window = len;
-
-	return 0;
-}
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index c254988e5bcb..effe5160bb79 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -32,11 +32,6 @@
  * 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)
 {
@@ -1103,7 +1098,7 @@ int mgag200_modeset_init(struct mga_device *mdev, resource_size_t vram_available
 	dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
 	dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
 	dev->mode_config.preferred_depth = 24;
-	dev->mode_config.fb_base = mdev->mc.vram_base;
+	dev->mode_config.fb_base = mdev->vram_res->start;
 	dev->mode_config.funcs = &mgag200_mode_config_funcs;
 
 	ret = mgag200_i2c_init(mdev, i2c);
-- 
2.36.1


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

* [PATCH 06/10] drm/mgag200: Add struct mgag200_device_info
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (4 preceding siblings ...)
  2022-06-01 11:25 ` [PATCH 05/10] drm/mgag200: Implement new init logic Thomas Zimmermann
@ 2022-06-01 11:25 ` Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 07/10] drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info Thomas Zimmermann
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

While currently empty, struct mgag200_device_info, will provide static,
constant information on each device model.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/mgag200_drv.c     |  4 +++-
 drivers/gpu/drm/mgag200/mgag200_drv.h     | 12 +++++++++++-
 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 |  5 ++++-
 drivers/gpu/drm/mgag200/mgag200_g200se.c  |  5 ++++-
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  5 ++++-
 10 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 8f636db4a723..90ed7770ff72 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -162,13 +162,15 @@ int mgag200_device_preinit(struct mga_device *mdev)
 	return 0;
 }
 
-int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags)
+int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags,
+			const struct mgag200_device_info *info)
 {
 	struct drm_device *dev = &mdev->base;
 	u8 crtcext3, misc;
 	int ret;
 
 	mdev->flags = flags;
+	mdev->info = info;
 	mdev->type = type;
 
 	ret = drmm_mutex_init(dev, &mdev->rmmio_lock);
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 9abecf366268..89cb4e476119 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -196,10 +196,19 @@ enum mga_type {
 
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
+struct mgag200_device_info {
+};
+
+#define MGAG200_DEVICE_INFO_INIT() \
+	{ \
+	}
+
 struct mga_device {
 	struct drm_device		base;
 	unsigned long			flags;
 
+	const struct mgag200_device_info *info;
+
 	struct resource			*rmmio_res;
 	void __iomem			*rmmio;
 	struct mutex			rmmio_lock; /* Protects access to rmmio */
@@ -252,7 +261,8 @@ 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);
 resource_size_t mgag200_device_probe_vram(struct mga_device *mdev);
 int mgag200_device_preinit(struct mga_device *mdev);
-int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags);
+int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags,
+			const struct mgag200_device_info *info);
 
 				/* mgag200_<device type>.c */
 struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index 4300a472c0a3..b2969a1f1e0b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -33,6 +33,9 @@ static int mgag200_g200_init_pci_options(struct pci_dev *pdev)
  * DRM Device
  */
 
+static const struct mgag200_device_info mgag200_g200_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200,
 					const unsigned char *bios, size_t size)
 {
@@ -183,7 +186,7 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
 
 	mgag200_g200_init_refclk(g200);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200_device_info);
 	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 7af9bdfb03c7..6284fedc1b8a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -10,6 +10,9 @@
  * DRM device
  */
 
+static const struct mgag200_device_info mgag200_g200eh_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type, unsigned long flags)
 {
@@ -33,7 +36,7 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200eh_device_info);
 	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 c0695d5c4f68..c8e46b89286f 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -10,6 +10,9 @@
  * DRM device
  */
 
+static const struct mgag200_device_info mgag200_g200eh3_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 						 const struct drm_driver *drv,
 						 enum mga_type type, unsigned long flags)
@@ -34,7 +37,7 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200eh3_device_info);
 	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 281317450fad..ef16ce4adecd 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -10,6 +10,9 @@
  * DRM device
  */
 
+static const struct mgag200_device_info mgag200_g200er_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type, unsigned long flags)
 {
@@ -29,7 +32,7 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200er_device_info);
 	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 41f948962b93..75d08fb503bb 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -10,6 +10,9 @@
  * DRM device
  */
 
+static const struct mgag200_device_info mgag200_g200ev_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type, unsigned long flags)
 {
@@ -33,7 +36,7 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200ev_device_info);
 	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 89346815e107..7cb18685b98d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -10,6 +10,9 @@
  * DRM device
  */
 
+static const struct mgag200_device_info mgag200_g200ew3_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev)
 {
 	resource_size_t vram_size = resource_size(mdev->vram_res);
@@ -43,7 +46,7 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200ew3_device_info);
 	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 b23459710372..69a17f057b32 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -32,6 +32,9 @@ static int mgag200_g200se_init_pci_options(struct pci_dev *pdev)
  * DRM device
  */
 
+static const struct mgag200_device_info mgag200_g200se_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 static void mgag200_g200se_init_unique_id(struct mgag200_g200se_device *g200se)
 {
 	struct mga_device *mdev = &g200se->base;
@@ -70,7 +73,7 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
 
 	mgag200_g200se_init_unique_id(g200se);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200se_device_info);
 	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 776bad867b4d..921c55ec309e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -10,6 +10,9 @@
  * DRM device
  */
 
+static const struct mgag200_device_info mgag200_g200wb_device_info =
+	MGAG200_DEVICE_INFO_INIT();
+
 struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
 						enum mga_type type, unsigned long flags)
 {
@@ -33,7 +36,7 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags);
+	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200wb_device_info);
 	if (ret)
 		return ERR_PTR(ret);
 
-- 
2.36.1


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

* [PATCH 07/10] drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (5 preceding siblings ...)
  2022-06-01 11:25 ` [PATCH 06/10] drm/mgag200: Add struct mgag200_device_info Thomas Zimmermann
@ 2022-06-01 11:25 ` Thomas Zimmermann
  2022-06-01 11:25 ` [PATCH 08/10] drm/mgag200: Store maximum resolution and memory bandwith " Thomas Zimmermann
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Flag devices with broken handling of the startadd field in
struct mgag200_device_info, instead of PCI driver data. This
reduces the driver data to a simple type constant.

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

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 90ed7770ff72..361eb7dffda1 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -162,14 +162,13 @@ int mgag200_device_preinit(struct mga_device *mdev)
 	return 0;
 }
 
-int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags,
+int mgag200_device_init(struct mga_device *mdev, enum mga_type type,
 			const struct mgag200_device_info *info)
 {
 	struct drm_device *dev = &mdev->base;
 	u8 crtcext3, misc;
 	int ret;
 
-	mdev->flags = flags;
 	mdev->info = info;
 	mdev->type = type;
 
@@ -202,8 +201,7 @@ int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned lo
 static const struct pci_device_id mgag200_pciidlist[] = {
 	{ PCI_VENDOR_ID_MATROX, 0x520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_PCI },
 	{ PCI_VENDOR_ID_MATROX, 0x521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_AGP },
-	{ PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
+	{ PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A },
 	{ PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
 	{ PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
 	{ PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
@@ -216,22 +214,10 @@ static const struct pci_device_id mgag200_pciidlist[] = {
 
 MODULE_DEVICE_TABLE(pci, mgag200_pciidlist);
 
-static enum mga_type mgag200_type_from_driver_data(kernel_ulong_t driver_data)
-{
-	return (enum mga_type)(driver_data & MGAG200_TYPE_MASK);
-}
-
-static unsigned long mgag200_flags_from_driver_data(kernel_ulong_t driver_data)
-{
-	return driver_data & MGAG200_FLAG_MASK;
-}
-
 static int
 mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	kernel_ulong_t driver_data = ent->driver_data;
-	enum mga_type type = mgag200_type_from_driver_data(driver_data);
-	unsigned long flags = mgag200_flags_from_driver_data(driver_data);
+	enum mga_type type = (enum mga_type)ent->driver_data;
 	struct mga_device *mdev;
 	struct drm_device *dev;
 	int ret;
@@ -247,29 +233,29 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	switch (type) {
 	case G200_PCI:
 	case G200_AGP:
-		mdev = mgag200_g200_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200_device_create(pdev, &mgag200_driver, type);
 		break;
 	case G200_SE_A:
 	case G200_SE_B:
-		mdev = mgag200_g200se_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200se_device_create(pdev, &mgag200_driver, type);
 		break;
 	case G200_WB:
-		mdev = mgag200_g200wb_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200wb_device_create(pdev, &mgag200_driver, type);
 		break;
 	case G200_EV:
-		mdev = mgag200_g200ev_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200ev_device_create(pdev, &mgag200_driver, type);
 		break;
 	case G200_EH:
-		mdev = mgag200_g200eh_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200eh_device_create(pdev, &mgag200_driver, type);
 		break;
 	case G200_EH3:
-		mdev = mgag200_g200eh3_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200eh3_device_create(pdev, &mgag200_driver, type);
 		break;
 	case G200_ER:
-		mdev = mgag200_g200er_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200er_device_create(pdev, &mgag200_driver, type);
 		break;
 	case G200_EW3:
-		mdev = mgag200_g200ew3_device_create(pdev, &mgag200_driver, type, flags);
+		mdev = mgag200_g200ew3_device_create(pdev, &mgag200_driver, type);
 		break;
 	default:
 		dev_err(&pdev->dev, "Device type %d is unsupported\n", type);
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 89cb4e476119..b05becb3d4b7 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -188,24 +188,23 @@ enum mga_type {
 	G200_EW3,
 };
 
-/* HW does not handle 'startadd' field correct. */
-#define MGAG200_FLAG_HW_BUG_NO_STARTADD	(1ul << 8)
-
-#define MGAG200_TYPE_MASK	(0x000000ff)
-#define MGAG200_FLAG_MASK	(0x00ffff00)
-
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
 struct mgag200_device_info {
+	/*
+	 * HW does not handle 'startadd' register correctly. Always set
+	 * it's value to 0.
+	 */
+	bool bug_no_startadd:1;
 };
 
-#define MGAG200_DEVICE_INFO_INIT() \
+#define MGAG200_DEVICE_INFO_INIT(_bug_no_startadd) \
 	{ \
+		.bug_no_startadd = (_bug_no_startadd), \
 	}
 
 struct mga_device {
-	struct drm_device		base;
-	unsigned long			flags;
+	struct drm_device base;
 
 	const struct mgag200_device_info *info;
 
@@ -261,26 +260,26 @@ 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);
 resource_size_t mgag200_device_probe_vram(struct mga_device *mdev);
 int mgag200_device_preinit(struct mga_device *mdev);
-int mgag200_device_init(struct mga_device *mdev, enum mga_type type, unsigned long flags,
+int mgag200_device_init(struct mga_device *mdev, enum mga_type type,
 			const struct mgag200_device_info *info);
 
 				/* mgag200_<device type>.c */
 struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-					      enum mga_type type, unsigned long flags);
+					      enum mga_type type);
 struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags);
+						enum mga_type type);
 struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags);
+						enum mga_type type);
 struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags);
+						enum mga_type type);
 struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags);
+						enum mga_type type);
 struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						 enum mga_type type, unsigned long flags);
+						 enum mga_type type);
 struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags);
+						enum mga_type type);
 struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						 enum mga_type type, unsigned long flags);
+						 enum mga_type type);
 
 				/* mgag200_mode.c */
 resource_size_t mgag200_device_probe_vram(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index b2969a1f1e0b..90b33a7352e5 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();
+	MGAG200_DEVICE_INFO_INIT(false);
 
 static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200,
 					const unsigned char *bios, size_t size)
@@ -160,7 +160,7 @@ static void mgag200_g200_init_refclk(struct mgag200_g200_device *g200)
 }
 
 struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-					      enum mga_type type, unsigned long flags)
+					      enum mga_type type)
 {
 	struct mgag200_g200_device *g200;
 	struct mga_device *mdev;
@@ -186,7 +186,7 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
 
 	mgag200_g200_init_refclk(g200);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200_device_info);
+	ret = mgag200_device_init(mdev, type, &mgag200_g200_device_info);
 	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 6284fedc1b8a..14bec513e441 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -11,10 +11,10 @@
  */
 
 static const struct mgag200_device_info mgag200_g200eh_device_info =
-	MGAG200_DEVICE_INFO_INIT();
+	MGAG200_DEVICE_INFO_INIT(false);
 
 struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags)
+						enum mga_type type)
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
@@ -36,7 +36,7 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200eh_device_info);
+	ret = mgag200_device_init(mdev, type, &mgag200_g200eh_device_info);
 	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 c8e46b89286f..c982533de9e7 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -11,11 +11,11 @@
  */
 
 static const struct mgag200_device_info mgag200_g200eh3_device_info =
-	MGAG200_DEVICE_INFO_INIT();
+	MGAG200_DEVICE_INFO_INIT(false);
 
 struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 						 const struct drm_driver *drv,
-						 enum mga_type type, unsigned long flags)
+						 enum mga_type type)
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
@@ -37,7 +37,7 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200eh3_device_info);
+	ret = mgag200_device_init(mdev, type, &mgag200_g200eh3_device_info);
 	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 ef16ce4adecd..d84039eef982 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -11,10 +11,10 @@
  */
 
 static const struct mgag200_device_info mgag200_g200er_device_info =
-	MGAG200_DEVICE_INFO_INIT();
+	MGAG200_DEVICE_INFO_INIT(false);
 
 struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags)
+						enum mga_type type)
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
@@ -32,7 +32,7 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200er_device_info);
+	ret = mgag200_device_init(mdev, type, &mgag200_g200er_device_info);
 	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 75d08fb503bb..14a891d47270 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -11,10 +11,10 @@
  */
 
 static const struct mgag200_device_info mgag200_g200ev_device_info =
-	MGAG200_DEVICE_INFO_INIT();
+	MGAG200_DEVICE_INFO_INIT(false);
 
 struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags)
+						enum mga_type type)
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
@@ -36,7 +36,7 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200ev_device_info);
+	ret = mgag200_device_init(mdev, type, &mgag200_g200ev_device_info);
 	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 7cb18685b98d..b09f345ba29b 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();
+	MGAG200_DEVICE_INFO_INIT(false);
 
 static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev)
 {
@@ -24,7 +24,7 @@ static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev
 
 struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
 						 const struct drm_driver *drv,
-						 enum mga_type type, unsigned long flags)
+						 enum mga_type type)
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
@@ -46,7 +46,7 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200ew3_device_info);
+	ret = mgag200_device_init(mdev, type, &mgag200_g200ew3_device_info);
 	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 69a17f057b32..9c0fc57366f2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -32,8 +32,11 @@ static int mgag200_g200se_init_pci_options(struct pci_dev *pdev)
  * DRM device
  */
 
-static const struct mgag200_device_info mgag200_g200se_device_info =
-	MGAG200_DEVICE_INFO_INIT();
+static const struct mgag200_device_info mgag200_g200se_a_device_info =
+	MGAG200_DEVICE_INFO_INIT(true);
+
+static const struct mgag200_device_info mgag200_g200se_b_device_info =
+	MGAG200_DEVICE_INFO_INIT(false);
 
 static void mgag200_g200se_init_unique_id(struct mgag200_g200se_device *g200se)
 {
@@ -47,9 +50,10 @@ static void mgag200_g200se_init_unique_id(struct mgag200_g200se_device *g200se)
 }
 
 struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags)
+						enum mga_type type)
 {
 	struct mgag200_g200se_device *g200se;
+	const struct mgag200_device_info *info;
 	struct mga_device *mdev;
 	struct drm_device *dev;
 	resource_size_t vram_available;
@@ -73,7 +77,18 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
 
 	mgag200_g200se_init_unique_id(g200se);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200se_device_info);
+	switch (type) {
+	case G200_SE_A:
+		info = &mgag200_g200se_a_device_info;
+		break;
+	case G200_SE_B:
+		info = &mgag200_g200se_b_device_info;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	ret = mgag200_device_init(mdev, type, info);
 	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 921c55ec309e..c9bf2176726e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -11,10 +11,10 @@
  */
 
 static const struct mgag200_device_info mgag200_g200wb_device_info =
-	MGAG200_DEVICE_INFO_INIT();
+	MGAG200_DEVICE_INFO_INIT(false);
 
 struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
-						enum mga_type type, unsigned long flags)
+						enum mga_type type)
 {
 	struct mga_device *mdev;
 	struct drm_device *dev;
@@ -36,7 +36,7 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = mgag200_device_init(mdev, type, flags, &mgag200_g200wb_device_info);
+	ret = mgag200_device_init(mdev, type, &mgag200_g200wb_device_info);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index effe5160bb79..f5e1a89e0bfe 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -245,7 +245,7 @@ static void mgag200_set_startadd(struct mga_device *mdev,
 	startadd = offset / 8;
 
 	if (startadd > 0)
-		drm_WARN_ON_ONCE(dev, mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD);
+		drm_WARN_ON_ONCE(dev, mdev->info->bug_no_startadd);
 
 	/*
 	 * Can't store addresses any higher than that, but we also
-- 
2.36.1


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

* [PATCH 08/10] drm/mgag200: Store maximum resolution and memory bandwith in device info
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (6 preceding siblings ...)
  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
  2022-06-01 11:25 ` [PATCH 09/10] drm/mgag200: Store vidrst flag " Thomas Zimmermann
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

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


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

* [PATCH 09/10] drm/mgag200: Store vidrst flag in device info
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (7 preceding siblings ...)
  2022-06-01 11:25 ` [PATCH 08/10] drm/mgag200: Store maximum resolution and memory bandwith " Thomas Zimmermann
@ 2022-06-01 11:25 ` 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
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Set new vidrst flag in device info for models that synchronize with
external sources (i.e., BMCs). In modesetting, set the corresponding
bits from the device-info flag.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/mgag200_drv.h     |  6 +++++-
 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  | 12 ++++++------
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  2 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c    |  7 ++++---
 drivers/gpu/drm/mgag200/mgag200_reg.h     |  2 ++
 11 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index f0fb13238f4f..1ceb19a987e2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -200,6 +200,9 @@ struct mgag200_device_info {
 	 */
 	unsigned long max_mem_bandwidth;
 
+	/* HW has external source (e.g., BMC) to synchronize with */
+	bool has_vidrst:1;
+
 	/*
 	 * HW does not handle 'startadd' register correctly. Always set
 	 * it's value to 0.
@@ -208,11 +211,12 @@ struct mgag200_device_info {
 };
 
 #define MGAG200_DEVICE_INFO_INIT(_max_hdisplay, _max_vdisplay, _max_mem_bandwidth, \
-				 _bug_no_startadd) \
+				 _has_vidrst, _bug_no_startadd) \
 	{ \
 		.max_hdisplay = (_max_hdisplay), \
 		.max_vdisplay = (_max_vdisplay), \
 		.max_mem_bandwidth = (_max_mem_bandwidth), \
+		.has_vidrst = (_has_vidrst), \
 		.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 4ec1b18ab170..58ae5d067263 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(2048, 2048, 0, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false, 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 a35ba2fdfc0e..ee38d918c727 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(2048, 2048, 37500, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 37500, false, 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 649559be1482..4b69206296ee 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(2048, 2048, 0, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false, 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 e661fad2f8b2..7e44fcc7bb59 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(2048, 2048, 55000, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, 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 07a3862d69de..87a9497ab805 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(2048, 2048, 32700, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 32700, false, 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 7f3987435085..61f944319bc9 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(2048, 2048, 0, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, true, 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 78120470b7be..0ccec9358529 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -33,22 +33,22 @@ static int mgag200_g200se_init_pci_options(struct pci_dev *pdev)
  */
 
 static const struct mgag200_device_info mgag200_g200se_a_01_device_info =
-	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, true);
+	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, true);
 
 static const struct mgag200_device_info mgag200_g200se_a_02_device_info =
-	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, true);
+	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, true);
 
 static const struct mgag200_device_info mgag200_g200se_a_03_device_info =
-	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, false);
 
 static const struct mgag200_device_info mgag200_g200se_b_01_device_info =
-	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false);
+	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, false);
 
 static const struct mgag200_device_info mgag200_g200se_b_02_device_info =
-	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false);
+	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, false);
 
 static const struct mgag200_device_info mgag200_g200se_b_03_device_info =
-	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, false);
 
 static int mgag200_g200se_init_unique_rev_id(struct mgag200_g200se_device *g200se)
 {
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
index 0943ad2a9999..97002c08da41 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(1280, 1024, 31877, false);
+	MGAG200_DEVICE_INFO_INIT(1280, 1024, 31877, true, 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 aa85558faa1b..e339f50d6bc8 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -377,6 +377,7 @@ static void mgag200_init_regs(struct mga_device *mdev)
 static void mgag200_set_mode_regs(struct mga_device *mdev,
 				  const struct drm_display_mode *mode)
 {
+	const struct mgag200_device_info *info = mdev->info;
 	unsigned int hdisplay, hsyncstart, hsyncend, htotal;
 	unsigned int vdisplay, vsyncstart, vsyncend, vtotal;
 	u8 misc, crtcext1, crtcext2, crtcext5;
@@ -411,9 +412,9 @@ static void mgag200_set_mode_regs(struct mga_device *mdev,
 		   ((hdisplay & 0x100) >> 7) |
 		   ((hsyncstart & 0x100) >> 6) |
 		    (htotal & 0x40);
-	if (mdev->type == G200_WB || mdev->type == G200_EW3)
-		crtcext1 |= BIT(7) | /* vrsten */
-			    BIT(3); /* hrsten */
+	if (info->has_vidrst)
+		crtcext1 |= MGAREG_CRTCEXT1_VRSTEN |
+			    MGAREG_CRTCEXT1_HRSTEN;
 
 	crtcext2 = ((vtotal & 0xc00) >> 10) |
 		   ((vdisplay & 0x400) >> 8) |
diff --git a/drivers/gpu/drm/mgag200/mgag200_reg.h b/drivers/gpu/drm/mgag200/mgag200_reg.h
index 60e705283fe8..99a9ab7d9119 100644
--- a/drivers/gpu/drm/mgag200/mgag200_reg.h
+++ b/drivers/gpu/drm/mgag200/mgag200_reg.h
@@ -252,8 +252,10 @@
 
 #define MGAREG_CRTCEXT0_OFFSET_MASK	GENMASK(5, 4)
 
+#define MGAREG_CRTCEXT1_VRSTEN		BIT(7)
 #define MGAREG_CRTCEXT1_VSYNCOFF	BIT(5)
 #define MGAREG_CRTCEXT1_HSYNCOFF	BIT(4)
+#define MGAREG_CRTCEXT1_HRSTEN		BIT(3)
 
 #define MGAREG_CRTCEXT3_MGAMODE		BIT(7)
 
-- 
2.36.1


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

* [PATCH 10/10] drm/mgag200: Store positions of I2C data and clock bits in device info
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (8 preceding siblings ...)
  2022-06-01 11:25 ` [PATCH 09/10] drm/mgag200: Store vidrst flag " Thomas Zimmermann
@ 2022-06-01 11:25 ` Thomas Zimmermann
  2022-06-02  9:52 ` [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Jocelyn Falempe
  10 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-01 11:25 UTC (permalink / raw)
  To: airlied, jfalempe, airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

The bits for accessing I2C data and clock channels varies among
models. Store them in the device-info structure for consumption
by the DDC code.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/mgag200_drv.h     | 12 +++++++++-
 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  | 12 +++++-----
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  2 +-
 drivers/gpu/drm/mgag200/mgag200_i2c.c     | 27 +++--------------------
 10 files changed, 27 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 1ceb19a987e2..301c4ab46539 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -203,6 +203,11 @@ struct mgag200_device_info {
 	/* HW has external source (e.g., BMC) to synchronize with */
 	bool has_vidrst:1;
 
+	struct {
+		unsigned data_bit:3;
+		unsigned clock_bit:3;
+	} i2c;
+
 	/*
 	 * HW does not handle 'startadd' register correctly. Always set
 	 * it's value to 0.
@@ -211,12 +216,17 @@ struct mgag200_device_info {
 };
 
 #define MGAG200_DEVICE_INFO_INIT(_max_hdisplay, _max_vdisplay, _max_mem_bandwidth, \
-				 _has_vidrst, _bug_no_startadd) \
+				 _has_vidrst, _i2c_data_bit, _i2c_clock_bit, \
+				 _bug_no_startadd) \
 	{ \
 		.max_hdisplay = (_max_hdisplay), \
 		.max_vdisplay = (_max_vdisplay), \
 		.max_mem_bandwidth = (_max_mem_bandwidth), \
 		.has_vidrst = (_has_vidrst), \
+		.i2c = { \
+			.data_bit = (_i2c_data_bit), \
+			.clock_bit = (_i2c_clock_bit), \
+		}, \
 		.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 58ae5d067263..616e11391e02 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(2048, 2048, 0, false, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false, 1, 3, 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 ee38d918c727..1b9a22728744 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(2048, 2048, 37500, false, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 37500, false, 1, 0, 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 4b69206296ee..438cda1b14c9 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(2048, 2048, 0, false, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false, 1, 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 7e44fcc7bb59..0790d4e6463d 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(2048, 2048, 55000, false, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, 1, 0, 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 87a9497ab805..5353422d0eef 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(2048, 2048, 32700, false, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 32700, false, 0, 1, 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 61f944319bc9..3bfc1324cf78 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(2048, 2048, 0, true, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, true, 0, 1, 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 0ccec9358529..0a3e66695e22 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -33,22 +33,22 @@ static int mgag200_g200se_init_pci_options(struct pci_dev *pdev)
  */
 
 static const struct mgag200_device_info mgag200_g200se_a_01_device_info =
-	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, true);
+	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, 0, 1, true);
 
 static const struct mgag200_device_info mgag200_g200se_a_02_device_info =
-	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, true);
+	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, 0, 1, true);
 
 static const struct mgag200_device_info mgag200_g200se_a_03_device_info =
-	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, 0, 1, false);
 
 static const struct mgag200_device_info mgag200_g200se_b_01_device_info =
-	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, false);
+	MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, 0, 1, false);
 
 static const struct mgag200_device_info mgag200_g200se_b_02_device_info =
-	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, false);
+	MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, 0, 1, false);
 
 static const struct mgag200_device_info mgag200_g200se_b_03_device_info =
-	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, false);
+	MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, 0, 1, false);
 
 static int mgag200_g200se_init_unique_rev_id(struct mgag200_g200se_device *g200se)
 {
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
index 97002c08da41..c8450ac8eaec 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(1280, 1024, 31877, true, false);
+	MGAG200_DEVICE_INFO_INIT(1280, 1024, 31877, true, 0, 1, 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_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index f57b33917152..0c48bdf3e7f8 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -96,36 +96,15 @@ static void mgag200_i2c_release(void *res)
 int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
 {
 	struct drm_device *dev = &mdev->base;
+	const struct mgag200_device_info *info = mdev->info;
 	int ret;
-	int data, clock;
 
 	WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
 	WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
 	WREG_DAC(MGA1064_GEN_IO_CTL, 0);
 
-	switch (mdev->type) {
-	case G200_SE_A:
-	case G200_SE_B:
-	case G200_EV:
-	case G200_WB:
-	case G200_EW3:
-		data = 1;
-		clock = 2;
-		break;
-	case G200_EH:
-	case G200_EH3:
-	case G200_ER:
-		data = 2;
-		clock = 1;
-		break;
-	default:
-		data = 2;
-		clock = 8;
-		break;
-	}
-
-	i2c->data = data;
-	i2c->clock = clock;
+	i2c->data = BIT(info->i2c.data_bit);
+	i2c->clock = BIT(info->i2c.clock_bit);
 	i2c->adapter.owner = THIS_MODULE;
 	i2c->adapter.class = I2C_CLASS_DDC;
 	i2c->adapter.dev.parent = dev->dev;
-- 
2.36.1


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

* Re: [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure
  2022-06-01 11:25 [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure Thomas Zimmermann
                   ` (9 preceding siblings ...)
  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 ` Jocelyn Falempe
  2022-06-02 11:07   ` Thomas Zimmermann
  10 siblings, 1 reply; 13+ messages in thread
From: Jocelyn Falempe @ 2022-06-02  9:52 UTC (permalink / raw)
  To: Thomas Zimmermann, airlied, airlied, daniel; +Cc: dri-devel

On 01/06/2022 13:25, Thomas Zimmermann wrote:
> Convert the device-init code to use a device-info structure for each
> model. The device info contains constants and flags that were previously
> located in different places of the code.
> 
> Also refactor the PCI and VRAM initialization handling. A later patchset
> could convert the PCI magic numbers into constants.
> 
> For modesetting, the per-model init functions currently don't do much.
> This will change when more model-specific code gets moved there. The
> modesetting and PLL code contains model-specific handling that should
> be refactored.
> 
> Tested with G200 and G200EV hardware.

Thanks for this refactoring.
I've also tested this patchset on a G200eW, and have seen no regression.

For the whole series:

Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Tested-by: Jocelyn Falempe <jfalempe@redhat.com>

> 
> Thomas Zimmermann (10):
>    drm/mgag200: Remove special case for G200SE with <2 MiB
>    drm/mgag200: Initialize each model in separate function
>    drm/mgag200: Move PCI-option setup into model-specific code
>    drm/mgag200: Call mgag200_device_probe_vram() from per-model init
>    drm/mgag200: Implement new init logic
>    drm/mgag200: Add struct mgag200_device_info
>    drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info
>    drm/mgag200: Store maximum resolution and memory bandwith in device
>      info
>    drm/mgag200: Store vidrst flag in device info
>    drm/mgag200: Store positions of I2C data and clock bits in device info
> 
>   drivers/gpu/drm/mgag200/Makefile          |  14 +-
>   drivers/gpu/drm/mgag200/mgag200_drv.c     | 386 ++++++++--------------
>   drivers/gpu/drm/mgag200/mgag200_drv.h     | 135 ++++++--
>   drivers/gpu/drm/mgag200/mgag200_g200.c    | 200 +++++++++++
>   drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  50 +++
>   drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  51 +++
>   drivers/gpu/drm/mgag200/mgag200_g200er.c  |  46 +++
>   drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  50 +++
>   drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  60 ++++
>   drivers/gpu/drm/mgag200/mgag200_g200se.c  | 130 ++++++++
>   drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  50 +++
>   drivers/gpu/drm/mgag200/mgag200_i2c.c     |  27 +-
>   drivers/gpu/drm/mgag200/mgag200_mm.c      | 116 -------
>   drivers/gpu/drm/mgag200/mgag200_mode.c    | 100 ++----
>   drivers/gpu/drm/mgag200/mgag200_pll.c     |  12 +-
>   drivers/gpu/drm/mgag200/mgag200_reg.h     |   2 +
>   16 files changed, 942 insertions(+), 487 deletions(-)
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200.c
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh.c
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh3.c
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200er.c
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ev.c
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ew3.c
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200se.c
>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200wb.c
>   delete mode 100644 drivers/gpu/drm/mgag200/mgag200_mm.c
> 
> 
> base-commit: 2c8cc5cd20e28afe6b63acb28890e5f57d9bf055
> prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
> prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24




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

* Re: [PATCH 00/10] drm/mgag200: Convert device init to use device-info structure
  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
  0 siblings, 0 replies; 13+ messages in thread
From: Thomas Zimmermann @ 2022-06-02 11:07 UTC (permalink / raw)
  To: Jocelyn Falempe, airlied, airlied, daniel; +Cc: dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 4179 bytes --]

Hi

Am 02.06.22 um 11:52 schrieb Jocelyn Falempe:
> On 01/06/2022 13:25, Thomas Zimmermann wrote:
>> Convert the device-init code to use a device-info structure for each
>> model. The device info contains constants and flags that were previously
>> located in different places of the code.
>>
>> Also refactor the PCI and VRAM initialization handling. A later patchset
>> could convert the PCI magic numbers into constants.
>>
>> For modesetting, the per-model init functions currently don't do much.
>> This will change when more model-specific code gets moved there. The
>> modesetting and PLL code contains model-specific handling that should
>> be refactored.
>>
>> Tested with G200 and G200EV hardware.
> 
> Thanks for this refactoring.
> I've also tested this patchset on a G200eW, and have seen no regression.
> 
> For the whole series:
> 
> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
> Tested-by: Jocelyn Falempe <jfalempe@redhat.com>

Thanks a lot.

FYI I have another patchset in the queue that removes the type-related 
branching throughout the driver. It covers modesetting and PLL setup and 
will split the driver into per-model and fully-generic code. It's fairly 
large but mostly refactoring of existing code. I'll post it when these 
patches have landed without major regressions.

Best regards
Thomas

> 
>>
>> Thomas Zimmermann (10):
>>    drm/mgag200: Remove special case for G200SE with <2 MiB
>>    drm/mgag200: Initialize each model in separate function
>>    drm/mgag200: Move PCI-option setup into model-specific code
>>    drm/mgag200: Call mgag200_device_probe_vram() from per-model init
>>    drm/mgag200: Implement new init logic
>>    drm/mgag200: Add struct mgag200_device_info
>>    drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info
>>    drm/mgag200: Store maximum resolution and memory bandwith in device
>>      info
>>    drm/mgag200: Store vidrst flag in device info
>>    drm/mgag200: Store positions of I2C data and clock bits in device info
>>
>>   drivers/gpu/drm/mgag200/Makefile          |  14 +-
>>   drivers/gpu/drm/mgag200/mgag200_drv.c     | 386 ++++++++--------------
>>   drivers/gpu/drm/mgag200/mgag200_drv.h     | 135 ++++++--
>>   drivers/gpu/drm/mgag200/mgag200_g200.c    | 200 +++++++++++
>>   drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  50 +++
>>   drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  51 +++
>>   drivers/gpu/drm/mgag200/mgag200_g200er.c  |  46 +++
>>   drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  50 +++
>>   drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  60 ++++
>>   drivers/gpu/drm/mgag200/mgag200_g200se.c  | 130 ++++++++
>>   drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  50 +++
>>   drivers/gpu/drm/mgag200/mgag200_i2c.c     |  27 +-
>>   drivers/gpu/drm/mgag200/mgag200_mm.c      | 116 -------
>>   drivers/gpu/drm/mgag200/mgag200_mode.c    | 100 ++----
>>   drivers/gpu/drm/mgag200/mgag200_pll.c     |  12 +-
>>   drivers/gpu/drm/mgag200/mgag200_reg.h     |   2 +
>>   16 files changed, 942 insertions(+), 487 deletions(-)
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200.c
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh.c
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh3.c
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200er.c
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ev.c
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ew3.c
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200se.c
>>   create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200wb.c
>>   delete mode 100644 drivers/gpu/drm/mgag200/mgag200_mm.c
>>
>>
>> base-commit: 2c8cc5cd20e28afe6b63acb28890e5f57d9bf055
>> prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
>> prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
> 
> 
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

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

end of thread, other threads:[~2022-06-02 11:07 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 08/10] drm/mgag200: Store maximum resolution and memory bandwith " Thomas Zimmermann
2022-06-01 11:25 ` [PATCH 09/10] drm/mgag200: Store vidrst flag " 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

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.