diff options
Diffstat (limited to 'drivers/gpu/drm/gma500/psb_drv.c')
-rw-r--r-- | drivers/gpu/drm/gma500/psb_drv.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 0bcab065242c..650af221c916 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -12,6 +12,7 @@ #include <linux/notifier.h> #include <linux/pm_runtime.h> #include <linux/spinlock.h> +#include <linux/delay.h> #include <asm/set_memory.h> @@ -54,7 +55,7 @@ static const struct pci_device_id pciidlist[] = { /* Poulsbo */ { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, -#if defined(CONFIG_DRM_GMA600) + /* Oak Trail */ { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, @@ -64,8 +65,7 @@ static const struct pci_device_id pciidlist[] = { { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, { 0x8086, 0x4108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops }, -#endif - /* Cedartrail */ + /* Cedar Trail */ { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops }, { 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops }, { 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops }, @@ -92,6 +92,36 @@ MODULE_DEVICE_TABLE(pci, pciidlist); static const struct drm_ioctl_desc psb_ioctls[] = { }; +/** + * psb_spank - reset the 2D engine + * @dev_priv: our PSB DRM device + * + * Soft reset the graphics engine and then reload the necessary registers. + */ +void psb_spank(struct drm_psb_private *dev_priv) +{ + PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET | + _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET | + _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET | + _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET); + PSB_RSGX32(PSB_CR_SOFT_RESET); + + msleep(1); + + PSB_WSGX32(0, PSB_CR_SOFT_RESET); + wmb(); + PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT, + PSB_CR_BIF_CTRL); + wmb(); + (void) PSB_RSGX32(PSB_CR_BIF_CTRL); + + msleep(1); + PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT, + PSB_CR_BIF_CTRL); + (void) PSB_RSGX32(PSB_CR_BIF_CTRL); + PSB_WSGX32(dev_priv->gtt.gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); +} + static int psb_do_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; |