diff options
author | Thomas Zimmermann <tzimmermann@suse.de> | 2023-11-16 10:59:21 +0100 |
---|---|---|
committer | Thomas Zimmermann <tzimmermann@suse.de> | 2023-11-28 16:12:29 +0100 |
commit | 0ccaa3dde97bd30ae615c66fc20080e920ec9b4e (patch) | |
tree | cbd7ffc19a6149b07b7b8a796f6d85387e855c2a | |
parent | c350a08ac7ec933f1dc8a143ebab60164ed4d90b (diff) |
drm/ast: Rework I/O register setup
There are three different ways of retrieving the I/O-memory ranges
for AST devices: either from PCI BAR 1, from PCI BAR 2 or from PCI
BAR 1 by 'guessing'.
Make the respective code more readable by making each case self-
contained. Also add error checking against the length of the PCI
BARs.
v2:
* fix I/O range length to 128 bytes
* fix length test for PCI BAR 2
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231116100240.22975-3-tzimmermann@suse.de
-rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_reg.h | 1 |
2 files changed, 31 insertions, 10 deletions
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 445cf47871a4..70e1871dbaf9 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -444,22 +444,42 @@ struct ast_device *ast_device_create(const struct drm_driver *drv, if (!ast->regs) return ERR_PTR(-EIO); - /* - * After AST2500, MMIO is enabled by default, and it should be adopted - * to be compatible with Arm. - */ if (pdev->revision >= 0x40) { + /* + * On AST2500 and later models, MMIO is enabled by + * default. Adopt it to be compatible with ARM. + */ + resource_size_t len = pci_resource_len(pdev, 1); + + if (len < AST_IO_MM_OFFSET) + return ERR_PTR(-EIO); + if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH) + return ERR_PTR(-EIO); ast->ioregs = ast->regs + AST_IO_MM_OFFSET; - } else if (!(pci_resource_flags(pdev, 2) & IORESOURCE_IO)) { - drm_info(dev, "platform has no IO space, trying MMIO\n"); - ast->ioregs = ast->regs + AST_IO_MM_OFFSET; - } + } else if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { + /* + * Map I/O registers if we have a PCI BAR for I/O. + */ + resource_size_t len = pci_resource_len(pdev, 2); - /* "map" IO regs if the above hasn't done so already */ - if (!ast->ioregs) { + if (len < AST_IO_MM_LENGTH) + return -EIO; ast->ioregs = pcim_iomap(pdev, 2, 0); if (!ast->ioregs) return ERR_PTR(-EIO); + } else { + /* + * Anything else is best effort. + */ + resource_size_t len = pci_resource_len(pdev, 1); + + if (len < AST_IO_MM_OFFSET) + return ERR_PTR(-EIO); + if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH) + return ERR_PTR(-EIO); + ast->ioregs = ast->regs + AST_IO_MM_OFFSET; + + drm_info(dev, "Platform has no I/O space, using MMIO\n"); } if (!ast_is_vga_enabled(dev)) { diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h index 555286ecf520..05bab94a9a90 100644 --- a/drivers/gpu/drm/ast/ast_reg.h +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -10,6 +10,7 @@ */ #define AST_IO_MM_OFFSET (0x380) +#define AST_IO_MM_LENGTH (128) #define AST_IO_VGAARI_W (0x40) #define AST_IO_VGAMR_W (0x42) |