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: 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-6-tzimmermann@suse.de
This commit is contained in:
parent
d45e32c9d9
commit
b62d943e96
@ -10,7 +10,6 @@ mgag200-y := \
|
||||
mgag200_g200se.o \
|
||||
mgag200_g200wb.o \
|
||||
mgag200_i2c.o \
|
||||
mgag200_mm.o \
|
||||
mgag200_mode.o \
|
||||
mgag200_pll.o
|
||||
|
||||
|
@ -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;
|
||||
resource_size_t start, len;
|
||||
struct resource *res;
|
||||
|
||||
/* BAR 1 contains registers */
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
mdev->rmmio = pcim_iomap(pdev, 1, 0);
|
||||
if (mdev->rmmio == NULL)
|
||||
return -ENOMEM;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user