mirror of
https://github.com/gnif/vendor-reset.git
synced 2025-12-26 22:09:28 +01:00
[amd] common: Map port I/O space (proper way to access certain ATOM registers?)
This commit is contained in:
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…
x
Reference in New Issue
Block a user