[amd] common: Map port I/O space (proper way to access certain ATOM registers?)

pull/1/head
Adam Madsen 4 years ago
parent d537ed67d9
commit c18730a60d

@ -32,7 +32,7 @@ int amd_common_pre_reset(struct vendor_reset_dev *dev)
{
struct amd_vendor_private *priv;
struct pci_dev *pdev = dev->pdev;
int ret;
int ret, i;
/* disable bus reset for the card, seems to be an issue with all of em */
pdev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET;
@ -58,6 +58,18 @@ int amd_common_pre_reset(struct vendor_reset_dev *dev)
goto err_free;
}
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
{
if (pci_resource_flags(pdev, i) & IORESOURCE_IO)
{
priv->rio_mem_size = pci_resource_len(pdev, i);
priv->rio_mem = pci_iomap(pdev, i, priv->rio_mem_size);
break;
}
}
if (!priv->rio_mem)
pci_warn(pdev, "Could not map I/O\n");
pci_set_power_state(pdev, PCI_D0);
pci_clear_master(pdev);
pci_save_state(pdev);
@ -82,6 +94,12 @@ int amd_common_post_reset(struct vendor_reset_dev *dev)
priv->mmio = NULL;
}
if (priv->rio_mem)
{
pci_iounmap(pdev, priv->rio_mem);
priv->rio_mem = NULL;
}
if (priv->saved_state)
{
pci_load_and_free_saved_state(pdev, &priv->saved_state);

@ -108,6 +108,9 @@ struct amd_vendor_private
resource_size_t mmio_base;
resource_size_t mmio_size;
uint32_t __iomem *mmio;
resource_size_t rio_mem_size;
uint32_t __iomem *rio_mem;
};
static inline struct amd_vendor_private *adev_to_amd_private(struct amd_fake_dev *adev)

@ -26,6 +26,47 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "firmware.h"
#define to_adev(info) ((struct amd_fake_dev *)container_of(info, struct amd_fake_dev, card_info))
#define RREG32_IO(reg) amdgpu_io_rreg(adev, (reg))
#define WREG32_IO(reg, v) amdgpu_io_wreg(adev, (reg), (v))
/**
* amdgpu_io_rreg - read an IO register
*
* @adev: amdgpu_device pointer
* @reg: dword aligned register offset
*
* Returns the 32 bit value from the offset specified.
*/
u32 amdgpu_io_rreg(struct amd_fake_dev *adev, u32 reg)
{
if ((reg * 4) < adev_to_amd_private(adev)->rio_mem_size)
return ioread32(adev_to_amd_private(adev)->rio_mem + (reg * 4));
else
{
iowrite32((reg * 4), adev_to_amd_private(adev)->rio_mem + (mmMM_INDEX * 4));
return ioread32(adev_to_amd_private(adev)->rio_mem + (mmMM_DATA * 4));
}
}
/**
* amdgpu_io_wreg - write to an IO register
*
* @adev: amdgpu_device pointer
* @reg: dword aligned register offset
* @v: 32 bit value to write to the register
*
* Writes the value specified to the offset specified.
*/
void amdgpu_io_wreg(struct amd_fake_dev *adev, u32 reg, u32 v)
{
if ((reg * 4) < adev_to_amd_private(adev)->rio_mem_size)
iowrite32(v, adev_to_amd_private(adev)->rio_mem + (reg * 4));
else
{
iowrite32((reg * 4), adev_to_amd_private(adev)->rio_mem + (mmMM_INDEX * 4));
iowrite32(v, adev_to_amd_private(adev)->rio_mem + (mmMM_DATA * 4));
}
}
static uint32_t null_read(struct card_info *info, uint32_t reg)
{
@ -52,6 +93,22 @@ static uint32_t reg_read(struct card_info *info, uint32_t reg)
return r;
}
static uint32_t ioreg_read(struct card_info *info, uint32_t reg)
{
struct amd_fake_dev *adev = to_adev(info);
uint32_t r;
r = RREG32_IO(reg);
return r;
}
static void ioreg_write(struct card_info *info, uint32_t reg, uint32_t val)
{
struct amd_fake_dev *adev = to_adev(info);
WREG32_IO(reg, val);
}
int atom_bios_init(struct amd_fake_dev *adev)
{
struct card_info *info = &adev->card_info;
@ -59,8 +116,19 @@ int atom_bios_init(struct amd_fake_dev *adev)
info->mc_read = info->pll_read = null_read;
info->mc_write = info->pll_write = null_write;
info->reg_read = info->ioreg_read = reg_read;
info->reg_write = info->ioreg_write = reg_write;
info->reg_read = reg_read;
info->reg_write = reg_write;
if (adev_to_amd_private(adev)->rio_mem)
{
info->ioreg_read = ioreg_read;
info->ioreg_write = ioreg_write;
}
else
{
pr_warn("vendor-reset: using MMIO to access I/O\n");
info->ioreg_read = reg_read;
info->ioreg_write = reg_write;
}
adev->atom_context = amdgpu_atom_parse(info, adev->bios);
if (!adev->atom_context)

@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef __VENDOR_RESET_FIRMWARE_H__
#define __VENDOR_RESET_FIRMWARE_H__
struct amd_fake_dev;
int atom_bios_init(struct amd_fake_dev *adev);
void atom_bios_fini(struct amd_fake_dev *adev);

Loading…
Cancel
Save