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@xxxxxxx> --- 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@xxxxxxxxxx> - */ - -#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