Commit 21e74bf9 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info



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: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJocelyn Falempe <jfalempe@redhat.com>
Tested-by: default avatarJocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220601112522.5774-8-tzimmermann@suse.de
parent b9a577a4
Loading
Loading
Loading
Loading
+11 −25
Original line number Diff line number Diff line
@@ -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);
+17 −18
Original line number Diff line number Diff line
@@ -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;

	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);
+3 −3
Original line number Diff line number Diff line
@@ -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);

+3 −3
Original line number Diff line number Diff line
@@ -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);

+3 −3
Original line number Diff line number Diff line
@@ -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);

Loading