mirror of
https://github.com/gnif/vendor-reset.git
synced 2025-12-27 06:19:29 +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 amd_vendor_private *priv;
|
||||||
struct pci_dev *pdev = dev->pdev;
|
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 */
|
/* disable bus reset for the card, seems to be an issue with all of em */
|
||||||
pdev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET;
|
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;
|
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_set_power_state(pdev, PCI_D0);
|
||||||
pci_clear_master(pdev);
|
pci_clear_master(pdev);
|
||||||
pci_save_state(pdev);
|
pci_save_state(pdev);
|
||||||
@ -82,6 +94,12 @@ int amd_common_post_reset(struct vendor_reset_dev *dev)
|
|||||||
priv->mmio = NULL;
|
priv->mmio = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->rio_mem)
|
||||||
|
{
|
||||||
|
pci_iounmap(pdev, priv->rio_mem);
|
||||||
|
priv->rio_mem = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->saved_state)
|
if (priv->saved_state)
|
||||||
{
|
{
|
||||||
pci_load_and_free_saved_state(pdev, &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_base;
|
||||||
resource_size_t mmio_size;
|
resource_size_t mmio_size;
|
||||||
uint32_t __iomem *mmio;
|
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)
|
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"
|
#include "firmware.h"
|
||||||
|
|
||||||
#define to_adev(info) ((struct amd_fake_dev *)container_of(info, struct amd_fake_dev, card_info))
|
#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)
|
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;
|
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)
|
int atom_bios_init(struct amd_fake_dev *adev)
|
||||||
{
|
{
|
||||||
struct card_info *info = &adev->card_info;
|
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_read = info->pll_read = null_read;
|
||||||
info->mc_write = info->pll_write = null_write;
|
info->mc_write = info->pll_write = null_write;
|
||||||
|
|
||||||
info->reg_read = info->ioreg_read = reg_read;
|
info->reg_read = reg_read;
|
||||||
info->reg_write = info->ioreg_write = reg_write;
|
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);
|
adev->atom_context = amdgpu_atom_parse(info, adev->bios);
|
||||||
if (!adev->atom_context)
|
if (!adev->atom_context)
|
||||||
|
|||||||
@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#ifndef __VENDOR_RESET_FIRMWARE_H__
|
#ifndef __VENDOR_RESET_FIRMWARE_H__
|
||||||
#define __VENDOR_RESET_FIRMWARE_H__
|
#define __VENDOR_RESET_FIRMWARE_H__
|
||||||
|
|
||||||
|
struct amd_fake_dev;
|
||||||
int atom_bios_init(struct amd_fake_dev *adev);
|
int atom_bios_init(struct amd_fake_dev *adev);
|
||||||
void atom_bios_fini(struct amd_fake_dev *adev);
|
void atom_bios_fini(struct amd_fake_dev *adev);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user