| From d1fb3e7a23996a053ebd6075cc622b27111108f1 Mon Sep 17 00:00:00 2001 |
| From: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> |
| Date: Mon, 16 Sep 2013 18:02:40 +0200 |
| Subject: drm/gma500: Add support for aux pci vdc device |
| |
| Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> |
| (cherry picked from commit 2657929d4e7c0a4db5456cc2c9a230a68b07813d) |
| Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> |
| --- |
| drivers/gpu/drm/gma500/psb_drv.c | 32 +++++++++++++++++++++++++++++++- |
| drivers/gpu/drm/gma500/psb_drv.h | 21 ++++++++++++++++++++- |
| 2 files changed, 51 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/gpu/drm/gma500/psb_drv.c |
| +++ b/drivers/gpu/drm/gma500/psb_drv.c |
| @@ -251,6 +251,12 @@ static int psb_driver_unload(struct drm_ |
| iounmap(dev_priv->sgx_reg); |
| dev_priv->sgx_reg = NULL; |
| } |
| + if (dev_priv->aux_reg) { |
| + iounmap(dev_priv->aux_reg); |
| + dev_priv->aux_reg = NULL; |
| + } |
| + if (dev_priv->aux_pdev) |
| + pci_dev_put(dev_priv->aux_pdev); |
| |
| /* Destroy VBT data */ |
| psb_intel_destroy_bios(dev); |
| @@ -266,7 +272,7 @@ static int psb_driver_unload(struct drm_ |
| static int psb_driver_load(struct drm_device *dev, unsigned long chipset) |
| { |
| struct drm_psb_private *dev_priv; |
| - unsigned long resource_start; |
| + unsigned long resource_start, resource_len; |
| unsigned long irqflags; |
| int ret = -ENOMEM; |
| struct drm_connector *connector; |
| @@ -296,6 +302,30 @@ static int psb_driver_load(struct drm_de |
| if (!dev_priv->sgx_reg) |
| goto out_err; |
| |
| + if (IS_MRST(dev)) { |
| + dev_priv->aux_pdev = pci_get_bus_and_slot(0, PCI_DEVFN(3, 0)); |
| + |
| + if (dev_priv->aux_pdev) { |
| + resource_start = pci_resource_start(dev_priv->aux_pdev, |
| + PSB_AUX_RESOURCE); |
| + resource_len = pci_resource_len(dev_priv->aux_pdev, |
| + PSB_AUX_RESOURCE); |
| + dev_priv->aux_reg = ioremap_nocache(resource_start, |
| + resource_len); |
| + if (!dev_priv->aux_reg) |
| + goto out_err; |
| + |
| + DRM_DEBUG_KMS("Found aux vdc"); |
| + } else { |
| + /* Couldn't find the aux vdc so map to primary vdc */ |
| + dev_priv->aux_reg = dev_priv->vdc_reg; |
| + DRM_DEBUG_KMS("Couldn't find aux pci device"); |
| + } |
| + dev_priv->gmbus_reg = dev_priv->aux_reg; |
| + } else { |
| + dev_priv->gmbus_reg = dev_priv->vdc_reg; |
| + } |
| + |
| psb_intel_opregion_setup(dev); |
| |
| ret = dev_priv->ops->chip_setup(dev); |
| --- a/drivers/gpu/drm/gma500/psb_drv.h |
| +++ b/drivers/gpu/drm/gma500/psb_drv.h |
| @@ -75,6 +75,7 @@ enum { |
| * PCI resource identifiers |
| */ |
| #define PSB_MMIO_RESOURCE 0 |
| +#define PSB_AUX_RESOURCE 0 |
| #define PSB_GATT_RESOURCE 2 |
| #define PSB_GTT_RESOURCE 3 |
| /* |
| @@ -455,6 +456,7 @@ struct psb_ops; |
| |
| struct drm_psb_private { |
| struct drm_device *dev; |
| + struct pci_dev *aux_pdev; /* Currently only used by mrst */ |
| const struct psb_ops *ops; |
| const struct psb_offset *regmap; |
| |
| @@ -486,6 +488,7 @@ struct drm_psb_private { |
| |
| uint8_t __iomem *sgx_reg; |
| uint8_t __iomem *vdc_reg; |
| + uint8_t __iomem *aux_reg; /* Auxillary vdc pipe regs */ |
| uint32_t gatt_free_offset; |
| |
| /* |
| @@ -532,6 +535,7 @@ struct drm_psb_private { |
| |
| /* gmbus */ |
| struct intel_gmbus *gmbus; |
| + uint8_t __iomem *gmbus_reg; |
| |
| /* Used by SDVO */ |
| int crt_ddc_pin; |
| @@ -927,16 +931,31 @@ static inline uint32_t REGISTER_READ(str |
| return ioread32(dev_priv->vdc_reg + reg); |
| } |
| |
| +static inline uint32_t REGISTER_READ_AUX(struct drm_device *dev, uint32_t reg) |
| +{ |
| + struct drm_psb_private *dev_priv = dev->dev_private; |
| + return ioread32(dev_priv->aux_reg + reg); |
| +} |
| + |
| #define REG_READ(reg) REGISTER_READ(dev, (reg)) |
| +#define REG_READ_AUX(reg) REGISTER_READ_AUX(dev, (reg)) |
| |
| static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, |
| - uint32_t val) |
| + uint32_t val) |
| { |
| struct drm_psb_private *dev_priv = dev->dev_private; |
| iowrite32((val), dev_priv->vdc_reg + (reg)); |
| } |
| |
| +static inline void REGISTER_WRITE_AUX(struct drm_device *dev, uint32_t reg, |
| + uint32_t val) |
| +{ |
| + struct drm_psb_private *dev_priv = dev->dev_private; |
| + iowrite32((val), dev_priv->aux_reg + (reg)); |
| +} |
| + |
| #define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val)) |
| +#define REG_WRITE_AUX(reg, val) REGISTER_WRITE_AUX(dev, (reg), (val)) |
| |
| static inline void REGISTER_WRITE16(struct drm_device *dev, |
| uint32_t reg, uint32_t val) |