qxl-wddm-dod: Simplify interrupt handling for rev4 device
Do not clear interrupt mask upon interrupt. Instead clear pending interrupt status and write QXL_IO_UPDATE_IRQ register (this drops interrupt level). There are 3 advantages: 1. We do not need to wake the host to enable interrupt mask in DPC procedure (1 wake per interrupt instead of 2) 2. The driver is not sensitive to failure when queues DPC, as already queued DPC will process this interrupt when executed. 3. When we implement VSync interrupt simulation, we do not need to touch registers neither when notify the OS nor when process DPC related to this notification. Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
parent
58b3a7a75b
commit
a2b58d1557
@ -4799,50 +4799,37 @@ BOOLEAN QxlDevice::InterruptRoutine(_In_ PDXGKRNL_INTERFACE pDxgkInterface, _In_
|
||||
if (!(m_RamHdr->int_pending & m_RamHdr->int_mask)) {
|
||||
return FALSE;
|
||||
}
|
||||
m_RamHdr->int_mask = 0;
|
||||
m_Pending |= InterlockedExchange((LONG *)&m_RamHdr->int_pending, 0);
|
||||
WRITE_PORT_UCHAR((PUCHAR)(m_IoBase + QXL_IO_UPDATE_IRQ), 0);
|
||||
m_Pending |= m_RamHdr->int_pending;
|
||||
m_RamHdr->int_pending = 0;
|
||||
// QXL_IO_UPDATE_IRQ sets interrupt level to m_RamHdr->int_pending & m_RamHdr->int_mask
|
||||
// so it will be dropped if interrupt status is not modified after clear
|
||||
|
||||
if (!pDxgkInterface->DxgkCbQueueDpc(pDxgkInterface->DeviceHandle)) {
|
||||
m_RamHdr->int_mask = WIN_QXL_INT_MASK;
|
||||
WRITE_PORT_UCHAR((PUCHAR)(m_IoBase + QXL_IO_UPDATE_IRQ), 0);
|
||||
DbgPrint(TRACE_LEVEL_FATAL, ("---> %s DxgkCbQueueDpc failed\n", __FUNCTION__));
|
||||
// DPC already queued and will process m_Pending when called
|
||||
DbgPrint(TRACE_LEVEL_WARNING, ("---> %s can't queue Dpc for %X\n", __FUNCTION__, m_Pending));
|
||||
}
|
||||
DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
QXL_NON_PAGED
|
||||
VOID QxlDevice::DpcRoutine(PVOID ptr)
|
||||
VOID QxlDevice::DpcRoutine(PVOID)
|
||||
{
|
||||
PDXGKRNL_INTERFACE pDxgkInterface = (PDXGKRNL_INTERFACE)ptr;
|
||||
|
||||
LONG intStatus = InterlockedExchange(&m_Pending, 0);
|
||||
DbgPrint(TRACE_LEVEL_INFORMATION, ("---> %s\n", __FUNCTION__));
|
||||
DPC_CB_CONTEXT ctx;
|
||||
BOOLEAN dummy;
|
||||
ctx.ptr = this;
|
||||
NTSTATUS Status = pDxgkInterface->DxgkCbSynchronizeExecution(
|
||||
pDxgkInterface->DeviceHandle,
|
||||
DpcCallbackEx,
|
||||
&ctx,
|
||||
0,
|
||||
&dummy);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
|
||||
if (ctx.data & QXL_INTERRUPT_DISPLAY) {
|
||||
if (intStatus & QXL_INTERRUPT_DISPLAY) {
|
||||
DbgPrint(TRACE_LEVEL_INFORMATION, ("---> %s m_DisplayEvent\n", __FUNCTION__));
|
||||
KeSetEvent (&m_DisplayEvent, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
if (ctx.data & QXL_INTERRUPT_CURSOR) {
|
||||
if (intStatus & QXL_INTERRUPT_CURSOR) {
|
||||
DbgPrint(TRACE_LEVEL_INFORMATION, ("---> %s m_CursorEvent\n", __FUNCTION__));
|
||||
KeSetEvent (&m_CursorEvent, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
if (ctx.data & QXL_INTERRUPT_IO_CMD) {
|
||||
if (intStatus & QXL_INTERRUPT_IO_CMD) {
|
||||
DbgPrint(TRACE_LEVEL_INFORMATION, ("---> %s m_IoCmdEvent\n", __FUNCTION__));
|
||||
KeSetEvent (&m_IoCmdEvent, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
m_RamHdr->int_mask = WIN_QXL_INT_MASK;
|
||||
WRITE_PORT_UCHAR((PUCHAR)(m_IoBase + QXL_IO_UPDATE_IRQ), 0);
|
||||
|
||||
DbgPrint(TRACE_LEVEL_INFORMATION, ("<--- %s\n", __FUNCTION__));
|
||||
}
|
||||
@ -4858,24 +4845,6 @@ VOID QxlDevice::UpdateArea(CONST RECT* area, UINT32 surface_id)
|
||||
DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__));
|
||||
}
|
||||
|
||||
QXL_NON_PAGED
|
||||
BOOLEAN QxlDevice:: DpcCallbackEx(PVOID ptr)
|
||||
{
|
||||
DbgPrint(TRACE_LEVEL_VERBOSE, ("<--> %s\n", __FUNCTION__));
|
||||
PDPC_CB_CONTEXT ctx = (PDPC_CB_CONTEXT) ptr;
|
||||
QxlDevice* pqxl = (QxlDevice*)ctx->ptr;
|
||||
pqxl->DpcCallback(ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
QXL_NON_PAGED
|
||||
VOID QxlDevice::DpcCallback(PDPC_CB_CONTEXT ctx)
|
||||
{
|
||||
ctx->data = m_Pending;
|
||||
m_Pending = 0;
|
||||
|
||||
}
|
||||
|
||||
QXL_NON_PAGED
|
||||
UINT BPPFromPixelFormat(D3DDDIFORMAT Format)
|
||||
{
|
||||
|
@ -549,8 +549,6 @@ private:
|
||||
void PutBytesAlign(QXLDataChunk **chunk_ptr, UINT8 **now_ptr,
|
||||
UINT8 **end_ptr, UINT8 *src, int size,
|
||||
size_t alloc_size, uint32_t alignment);
|
||||
QXL_NON_PAGED BOOLEAN static DpcCallbackEx(PVOID);
|
||||
QXL_NON_PAGED void DpcCallback(PDPC_CB_CONTEXT);
|
||||
void AsyncIo(UCHAR Port, UCHAR Value);
|
||||
void SyncIo(UCHAR Port, UCHAR Value);
|
||||
NTSTATUS UpdateChildStatus(BOOLEAN connect);
|
||||
@ -602,7 +600,7 @@ private:
|
||||
MspaceInfo m_MSInfo[NUM_MSPACES];
|
||||
|
||||
UINT64 m_FreeOutputs;
|
||||
UINT32 m_Pending;
|
||||
LONG m_Pending;
|
||||
|
||||
QXLMonitorsConfig* m_monitor_config;
|
||||
QXLPHYSICAL* m_monitor_config_pa;
|
||||
|
Loading…
Reference in New Issue
Block a user