Beispiel #1
0
/*
 * Sandybridge RC6 power management inhibit state erratum.
 * This can cause power high power consumption.
 * Workaround is to prevent graphics get into RC6
 * state when doing VT-d IOTLB operations, do the VT-d
 * IOTLB operation, and then re-enable RC6 state.
 */
static void snb_vtd_ops_preamble(struct iommu* iommu)
{
    struct intel_iommu *intel = iommu->intel;
    struct acpi_drhd_unit *drhd = intel ? intel->drhd : NULL;
    s_time_t start_time;

    if ( !is_igd_drhd(drhd) || !is_snb_gfx )
        return;

    if ( !map_igd_reg() )
        return;

    *((volatile u32 *)(igd_reg_va + 0x54)) = 0x000FFFFF;
    *((volatile u32 *)(igd_reg_va + 0x700)) = 0;

    start_time = NOW();
    while ( (*((volatile u32 *)(igd_reg_va + 0x2AC)) & 0xF) != 0 )
    {
        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
        {
            dprintk(XENLOG_INFO VTDPREFIX,
                    "snb_vtd_ops_preamble: failed to disable idle handshake\n");
            break;
        }
        cpu_relax();
    }

    *((volatile u32*)(igd_reg_va + 0x50)) = 0x10001;
}
Beispiel #2
0
static void snb_vtd_ops_postamble(struct iommu* iommu)
{
    struct intel_iommu *intel = iommu->intel;
    struct acpi_drhd_unit *drhd = intel ? intel->drhd : NULL;

    if ( !is_igd_drhd(drhd) || !is_snb_gfx )
        return;

    if ( !map_igd_reg() )
        return;

    *((volatile u32 *)(igd_reg_va + 0x54)) = 0xA;
    *((volatile u32 *)(igd_reg_va + 0x50)) = 0x10000;
}
Beispiel #3
0
/*
 * force IGD to exit low power mode by accessing a IGD 3D regsiter.
 */
static int cantiga_vtd_ops_preamble(struct iommu* iommu)
{
    struct intel_iommu *intel = iommu->intel;
    struct acpi_drhd_unit *drhd = intel ? intel->drhd : NULL;

    if ( !is_igd_drhd(drhd) || !is_cantiga_b3 )
        return 0;

    if ( !igd_reg_va )
        return 0;

    /*
     * Read IGD register at IGD MMIO + 0x20A4 to force IGD
     * to exit low power state.
     */
    return *(volatile int *)(igd_reg_va + 0x20A4);
}
Beispiel #4
0
/*
 * force IGD to exit low power mode by accessing a IGD 3D regsiter.
 */
static int cantiga_vtd_ops_preamble(struct iommu* iommu)
{
    struct intel_iommu *intel = iommu->intel;
    struct acpi_drhd_unit *drhd = intel ? intel->drhd : NULL;

    if ( !is_igd_drhd(drhd) || !is_cantiga_b3 )
        return 0;

    if ( !map_igd_reg() )
        return 0;

    /*
     * read IGD register at IGD MMIO + 0x20A4 to force IGD
     * to exit low power state.  Since map_igd_reg()
     * already mapped page starting 0x2000, we just need to
     * add page offset 0x0A4 to virtual address base.
     */
    return ( *((volatile int *)(igd_reg_va + 0x0A4)) );
}