void psb_msvdx_irq_off(struct drm_psb_private *dev_priv) { unsigned long irqflags; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); if (dev_priv->irq_enabled) { dev_priv->vdc_irq_mask &= ~_PSB_IRQ_MSVDX_FLAG; PSB_WSGX32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); (void)PSB_RSGX32(PSB_INT_ENABLE_R); } spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); }
void psb_2D_irq_off(struct drm_psb_private *dev_priv) { unsigned long irqflags; uint32_t old_mask; uint32_t cleared_mask; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); --dev_priv->irqen_count_2d; if (dev_priv->irq_enabled && dev_priv->irqen_count_2d == 0) { old_mask = dev_priv->sgx_irq_mask; dev_priv->sgx_irq_mask &= ~_PSB_CE_TWOD_COMPLETE; PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE); (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); cleared_mask = (old_mask ^ dev_priv->sgx_irq_mask) & old_mask; PSB_WSGX32(cleared_mask, PSB_CR_EVENT_HOST_CLEAR); (void)PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR); } spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); }
void psb_2D_irq_on(struct drm_psb_private *dev_priv) { unsigned long irqflags; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); if (dev_priv->irq_enabled && dev_priv->irqen_count_2d == 0) { dev_priv->sgx_irq_mask |= _PSB_CE_TWOD_COMPLETE; PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE); (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); } ++dev_priv->irqen_count_2d; spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); }
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); (void) 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->pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); }
int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, unsigned size) { int ret = 0; int i; unsigned submit_size; while (size > 0) { submit_size = (size < 0x60) ? size : 0x60; size -= submit_size; ret = psb_2d_wait_available(dev_priv, submit_size); if (ret) return ret; submit_size <<= 2; for (i = 0; i < submit_size; i += 4) { PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i); } (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4); } return 0; }
void psb_irq_preinstall(struct drm_device *dev) { struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; spin_lock(&dev_priv->irqmask_lock); PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); PSB_WVDC32(0x00000000, PSB_INT_MASK_R); PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE); (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); dev_priv->sgx_irq_mask = _PSB_CE_PIXELBE_END_RENDER | _PSB_CE_DPM_3D_MEM_FREE | _PSB_CE_TA_FINISHED | _PSB_CE_DPM_REACHED_MEM_THRESH | _PSB_CE_DPM_OUT_OF_MEMORY_GBL | _PSB_CE_DPM_OUT_OF_MEMORY_MT | _PSB_CE_TA_TERMINATE | _PSB_CE_SW_EVENT; dev_priv->sgx2_irq_mask = _PSB_CE2_BIF_REQUESTER_FAULT; dev_priv->vdc_irq_mask = _PSB_IRQ_SGX_FLAG | _PSB_IRQ_MSVDX_FLAG | _PSB_HOTPLUG_INTERRUPT_ENABLE; if (!drm_psb_disable_vsync || drm_psb_detear) dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG | _PSB_VSYNC_PIPEB_FLAG; /*Clear MTX interrupt */ { unsigned long mtx_int = 0; REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ, 1); PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR); } spin_unlock(&dev_priv->irqmask_lock); }