Skip to content

Commit

Permalink
drm/mgag200: Move PCI-option setup into model-specific code
Browse files Browse the repository at this point in the history
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>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Tested-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220601112522.5774-4-tzimmermann@suse.de
  • Loading branch information
Thomas Zimmermann committed Jun 7, 2022
1 parent 85397f6 commit ce19021
Showing 9 changed files with 100 additions and 55 deletions.
81 changes: 26 additions & 55 deletions drivers/gpu/drm/mgag200/mgag200_drv.c
Original file line number Diff line number Diff line change
@@ -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,72 +72,17 @@ 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;

ret = drmm_mutex_init(dev, &mdev->rmmio_lock);
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);
1 change: 1 addition & 0 deletions drivers/gpu/drm/mgag200/mgag200_drv.h
Original file line number Diff line number Diff line change
@@ -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 */
27 changes: 27 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_g200.c
Original file line number Diff line number Diff line change
@@ -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;

4 changes: 4 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_g200eh.c
Original file line number Diff line number Diff line change
@@ -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);
4 changes: 4 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_g200eh3.c
Original file line number Diff line number Diff line change
@@ -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);
4 changes: 4 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_g200ev.c
Original file line number Diff line number Diff line change
@@ -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;

4 changes: 4 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_g200ew3.c
Original file line number Diff line number Diff line change
@@ -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;

26 changes: 26 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_g200se.c
Original file line number Diff line number Diff line change
@@ -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;

4 changes: 4 additions & 0 deletions drivers/gpu/drm/mgag200/mgag200_g200wb.c
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit ce19021

Please sign in to comment.