Commit b62d943e authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/mgag200: Implement new init logic



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: 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-6-tzimmermann@suse.de
parent d45e32c9
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@ mgag200-y := \
	mgag200_g200se.o \
	mgag200_g200wb.o \
	mgag200_i2c.o \
	mgag200_mm.o \
	mgag200_mode.o \
	mgag200_pll.o

+64 −14
Original line number Diff line number Diff line
@@ -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;
}

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

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

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

Loading