|
|
/* Copyright © 2011 Intel Corporation
|
|
|
*
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
*
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
* Software.
|
|
|
*
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
*/
|
|
|
|
|
|
#include <unistd.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <stdio.h>
|
|
|
#include <err.h>
|
|
|
#include <string.h>
|
|
|
#include <stdbool.h>
|
|
|
#include "intel_io.h"
|
|
|
#include "intel_chipset.h"
|
|
|
|
|
|
static uint32_t devid;
|
|
|
static int gen;
|
|
|
|
|
|
static uint32_t
|
|
|
read_and_print_reg(const char *name, uint32_t reg)
|
|
|
{
|
|
|
uint32_t val = INREG(reg);
|
|
|
|
|
|
printf("%s (0x%x): 0x%08x\n", name, reg, val);
|
|
|
|
|
|
return val;
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_chicken_unset(const char *name, uint32_t reg)
|
|
|
{
|
|
|
uint32_t val = read_and_print_reg(name, reg);
|
|
|
|
|
|
|
|
|
if (val != 0) {
|
|
|
fprintf(stderr, " WARN: chicken bits set\n");
|
|
|
} else {
|
|
|
printf(" OK: chicken bits unset\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_bit(uint32_t val, int bit, const char *bitname, bool set)
|
|
|
{
|
|
|
if (!!(val & (1 << bit)) != set) {
|
|
|
fprintf(stderr, " (bit %2d) FAIL: %s must be %s\n",
|
|
|
bit, bitname, set ? "set" : "unset");
|
|
|
} else {
|
|
|
printf(" (bit %2d) OK: %s\n", bit, bitname);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_perf_bit(uint32_t val, int bit, const char *bitname, bool set)
|
|
|
{
|
|
|
if (!!(val & (1 << bit)) != set) {
|
|
|
printf(" (bit %2d) PERF: %s should be %s\n",
|
|
|
bit, bitname, set ? "set" : "unset");
|
|
|
} else {
|
|
|
printf(" (bit %2d) OK: %s\n", bit, bitname);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_mi_mode(void)
|
|
|
{
|
|
|
/* Described in page 14-16 of the IHD_OS_Vol1_Part3.pdf
|
|
|
* specification.
|
|
|
*/
|
|
|
|
|
|
uint32_t mi_mode = read_and_print_reg("MI_MODE", 0x209c);
|
|
|
|
|
|
/* From page 14:
|
|
|
*
|
|
|
* Async Flip Performance mode
|
|
|
* Project: All
|
|
|
* Default Value: 0h
|
|
|
* Format: U1
|
|
|
* [DevSNB] This bit must be set to ‘1’
|
|
|
*/
|
|
|
if (gen == 6)
|
|
|
check_bit(mi_mode, 14, "Async Flip Performance mode", true);
|
|
|
else
|
|
|
check_perf_bit(mi_mode, 14, "Async Flip Performance mode",
|
|
|
false);
|
|
|
|
|
|
check_perf_bit(mi_mode, 13, "Flush Performance Mode", false);
|
|
|
|
|
|
/* Our driver relies on MI_FLUSH, unfortunately. */
|
|
|
if (gen >= 6)
|
|
|
check_bit(mi_mode, 12, "MI_FLUSH enable", true);
|
|
|
|
|
|
/* From page 15:
|
|
|
*
|
|
|
* "1h: LRA mode of allocation. Used for validation purposes"
|
|
|
*/
|
|
|
if (gen < 7)
|
|
|
check_bit(mi_mode, 7, "Vertex Shader Cache Mode", false);
|
|
|
|
|
|
/* From page 16:
|
|
|
*
|
|
|
* "To avoid deadlock conditions in hardware this bit
|
|
|
* needs to be set for normal operation.
|
|
|
*/
|
|
|
check_bit(mi_mode, 6, "Vertex Shader Timer Dispatch Enable", true);
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_gfx_mode(void)
|
|
|
{
|
|
|
/* Described in page 17-19 of the IHD_OS_Vol1_Part3.pdf
|
|
|
* specification.
|
|
|
*/
|
|
|
uint32_t gfx_mode;
|
|
|
|
|
|
if (gen < 6)
|
|
|
return;
|
|
|
|
|
|
if (gen == 6)
|
|
|
gfx_mode = read_and_print_reg("GFX_MODE", 0x2520);
|
|
|
else
|
|
|
gfx_mode = read_and_print_reg("GFX_MODE", 0x229c);
|
|
|
|
|
|
/* Our driver only updates page tables at batchbuffer
|
|
|
* boundaries, so we don't need TLB flushes at other times.
|
|
|
*/
|
|
|
check_perf_bit(gfx_mode, 13, "Flush TLB Invalidation Mode", true);
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_gt_mode(void)
|
|
|
{
|
|
|
/* Described in page 20-22 of the IHD_OS_Vol1_Part3.pdf
|
|
|
* specification.
|
|
|
*/
|
|
|
uint32_t gt_mode;
|
|
|
|
|
|
if (gen < 6)
|
|
|
return;
|
|
|
|
|
|
if (gen == 6)
|
|
|
gt_mode = read_and_print_reg("GT_MODE", 0x20d0);
|
|
|
else
|
|
|
gt_mode = read_and_print_reg("GT_MODE", 0x7008);
|
|
|
|
|
|
if (gen == 6)
|
|
|
check_perf_bit(gt_mode, 8, "Full Rate Sampler Disable", false);
|
|
|
|
|
|
if (gen == 6) {
|
|
|
/* For DevSmallGT, this bit must be set, which means disable
|
|
|
* hashing.
|
|
|
*/
|
|
|
if (intel_gt(devid) == 0)
|
|
|
check_bit(gt_mode, 6,
|
|
|
"WIZ Hashing disable", true);
|
|
|
else
|
|
|
check_perf_bit(gt_mode, 6,
|
|
|
"WIZ Hashing disable", false);
|
|
|
|
|
|
check_perf_bit(gt_mode, 5, "TD Four Row Dispatch Disable",
|
|
|
false);
|
|
|
check_perf_bit(gt_mode, 4, "Full Size URB Disable", false);
|
|
|
check_perf_bit(gt_mode, 3, "Full Size SF FIFO Disable", false);
|
|
|
check_perf_bit(gt_mode, 1, "VS Quad Thread Dispatch Disable",
|
|
|
false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_cache_mode_0(void)
|
|
|
{
|
|
|
/* Described in page 23-25 of the IHD_OS_Vol1_Part3.pdf
|
|
|
* specification.
|
|
|
*/
|
|
|
uint32_t cache_mode_0;
|
|
|
|
|
|
if (gen >= 7)
|
|
|
cache_mode_0 = read_and_print_reg("CACHE_MODE_0", 0x7000);
|
|
|
else
|
|
|
cache_mode_0 = read_and_print_reg("CACHE_MODE_0", 0x2120);
|
|
|
|
|
|
check_perf_bit(cache_mode_0, 15, "Sampler L2 Disable", false);
|
|
|
check_perf_bit(cache_mode_0, 9, "Sampler L2 TLB Prefetch Enable", true);
|
|
|
check_perf_bit(cache_mode_0, 8,
|
|
|
"Depth Related Cache Pipelined Flush Disable", false);
|
|
|
|
|
|
/* From page 24:
|
|
|
*
|
|
|
* "If this bit is set, RCCunit will have LRA as
|
|
|
* replacement policy. The default value i.e. ( when this
|
|
|
* bit is reset ) indicates that non-LRA eviction
|
|
|
* policy. This bit must be reset. LRA replacement policy
|
|
|
* is not supported."
|
|
|
*
|
|
|
* And the same for STC Eviction Policy.
|
|
|
*/
|
|
|
check_bit(cache_mode_0, 5, "STC LRA Eviction Policy", false);
|
|
|
if (gen >= 6)
|
|
|
check_bit(cache_mode_0, 4, "RCC LRA Eviction Policy", false);
|
|
|
|
|
|
check_perf_bit(cache_mode_0, 3, "Hierarchical Z Disable", false);
|
|
|
|
|
|
if (gen == 6) {
|
|
|
check_perf_bit(cache_mode_0, 2,
|
|
|
"Hierarchical Z RAW Stall Optimization "
|
|
|
"Disable", false);
|
|
|
}
|
|
|
|
|
|
/* From page 25:
|
|
|
*
|
|
|
* "This bit must be 0. Operational Flushes [DevSNB] are
|
|
|
* not supported in [DevSNB]. SW must flush the render
|
|
|
* target after front buffer rendering."
|
|
|
*/
|
|
|
check_bit(cache_mode_0, 0, "Render Cache Operational Flush", false);
|
|
|
}
|
|
|
|
|
|
|
|
|
static void
|
|
|
check_cache_mode_1(void)
|
|
|
{
|
|
|
/* Described in page 23-25 of the IHD_OS_Vol1_Part3.pdf
|
|
|
* specification.
|
|
|
*/
|
|
|
uint32_t cache_mode_1;
|
|
|
|
|
|
if (gen >= 7)
|
|
|
cache_mode_1 = read_and_print_reg("CACHE_MODE_1", 0x7004);
|
|
|
else
|
|
|
cache_mode_1 = read_and_print_reg("CACHE_MODE_1", 0x2124);
|
|
|
|
|
|
if (gen >= 7) {
|
|
|
check_perf_bit(cache_mode_1, 13,
|
|
|
"STC Address Lookup Optimization Disable",
|
|
|
false);
|
|
|
}
|
|
|
|
|
|
/* From page 24:
|
|
|
*
|
|
|
* "If this bit is set, Hizunit will have LRA as
|
|
|
* replacement policy. The default value i.e. (when this
|
|
|
* bit is reset) indicates the non-LRA eviction
|
|
|
* policy. For performance reasons, this bit must be
|
|
|
* reset."
|
|
|
*/
|
|
|
check_bit(cache_mode_1, 12, "HIZ LRA Eviction Policy", false);
|
|
|
|
|
|
/* Page 26 describes these bits as reserved (debug only). */
|
|
|
check_bit(cache_mode_1, 11,
|
|
|
"DAP Instruction and State Cache Invalidate", false);
|
|
|
check_bit(cache_mode_1, 10,
|
|
|
"Instruction L1 Cache and In-Flight Queue Disable",
|
|
|
false);
|
|
|
check_bit(cache_mode_1, 9, "Instruction L2 Cache Fill Buffers Disable",
|
|
|
false);
|
|
|
|
|
|
|
|
|
if (gen >= 7) {
|
|
|
check_perf_bit(cache_mode_1, 6,
|
|
|
"Pixel Backend sub-span collection "
|
|
|
"Optimization Disable",
|
|
|
false);
|
|
|
check_perf_bit(cache_mode_1, 5, "MCS Cache Disable", false);
|
|
|
}
|
|
|
check_perf_bit(cache_mode_1, 4, "Data Disable", false);
|
|
|
|
|
|
if (gen == 6) {
|
|
|
/* In a later update of the documentation, it says:
|
|
|
*
|
|
|
* "[DevSNB:A0{WKA1}] [DevSNB]: This bit must be
|
|
|
* set for depth buffer format
|
|
|
* D24_UNORM_S8_UINT."
|
|
|
*
|
|
|
* XXX: Does that mean A0 only, or all DevSNB?
|
|
|
*/
|
|
|
check_perf_bit(cache_mode_1, 3,
|
|
|
"Depth Read Hit Write-Only Optimization "
|
|
|
"Disable", false);
|
|
|
|
|
|
check_perf_bit(cache_mode_1, 2,
|
|
|
"Depth Cache LRA Hunt Feature Disable",
|
|
|
false);
|
|
|
}
|
|
|
|
|
|
check_bit(cache_mode_1, 1, "Instruction and State L2 Cache Disable",
|
|
|
false);
|
|
|
check_bit(cache_mode_1, 0, "Instruction and State L1 Cache Disable",
|
|
|
false);
|
|
|
}
|
|
|
|
|
|
|
|
|
static void
|
|
|
check_3d_chicken4(void)
|
|
|
{
|
|
|
/* Described in page 23-25 of the IHD_OS_Vol1_Part3.pdf
|
|
|
* specification.
|
|
|
*/
|
|
|
uint32_t _3d_chicken4 = read_and_print_reg("3D_CHICKEN4", 0x20d4);
|
|
|
|
|
|
check_perf_bit(_3d_chicken4, 6, "3D Scoreboard Hashing Enable", true);
|
|
|
|
|
|
if (_3d_chicken4 & 0x0fbf) {
|
|
|
fprintf(stderr,
|
|
|
" WARN: other non-thread deps bits set\n");
|
|
|
} else {
|
|
|
printf(" OK: other non-thread deps bits unset\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
check_dpfc_control_sa(void)
|
|
|
{
|
|
|
uint32_t dpfc_control_sa;
|
|
|
|
|
|
if (gen != 6)
|
|
|
return;
|
|
|
|
|
|
dpfc_control_sa = read_and_print_reg("DPFC_CONTROL_SA", 0x100100);
|
|
|
|
|
|
/* This is needed for framebuffer compression for us to be
|
|
|
* able to access the framebuffer by the CPU through the GTT.
|
|
|
*/
|
|
|
check_bit(dpfc_control_sa, 29, "CPU Fence Enable", true);
|
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
{
|
|
|
struct pci_device *dev;
|
|
|
|
|
|
dev = intel_get_pci_device();
|
|
|
devid = dev->device_id;
|
|
|
intel_mmio_use_pci_bar(dev);
|
|
|
|
|
|
if (IS_GEN7(devid))
|
|
|
gen = 7;
|
|
|
else if (IS_GEN6(devid))
|
|
|
gen = 6;
|
|
|
else if (IS_GEN5(devid))
|
|
|
gen = 5;
|
|
|
else
|
|
|
gen = 4;
|
|
|
|
|
|
check_mi_mode();
|
|
|
check_gfx_mode();
|
|
|
check_gt_mode();
|
|
|
check_cache_mode_0();
|
|
|
check_cache_mode_1();
|
|
|
|
|
|
if (gen < 7) {
|
|
|
check_chicken_unset("3D_CHICKEN", 0x2084);
|
|
|
check_chicken_unset("3D_CHICKEN2", 0x208c);
|
|
|
} else {
|
|
|
check_chicken_unset("FF_SLICE_CHICKEN", 0x2088);
|
|
|
}
|
|
|
if (gen >= 6)
|
|
|
check_chicken_unset("3D_CHICKEN3", 0x2090);
|
|
|
if (gen == 6)
|
|
|
check_3d_chicken4();
|
|
|
|
|
|
if (gen >= 7) {
|
|
|
check_chicken_unset("FF_SLICE_CS_CHICKEN1", 0x20e0);
|
|
|
check_chicken_unset("FF_SLICE_CS_CHICKEN2", 0x20e4);
|
|
|
check_chicken_unset("FF_SLICE_CS_CHICKEN3", 0x20e8);
|
|
|
check_chicken_unset("COMMON_SLICE_CHICKEN1", 0x7010);
|
|
|
check_chicken_unset("COMMON_SLICE_CHICKEN2", 0x7014);
|
|
|
check_chicken_unset("WM_CHICKEN", 0x5580);
|
|
|
check_chicken_unset("HALF_SLICE_CHICKEN", 0xe100);
|
|
|
check_chicken_unset("HALF_SLICE_CHICKEN2", 0xe180);
|
|
|
check_chicken_unset("ROW_CHICKEN", 0xe4f0);
|
|
|
check_chicken_unset("ROW_CHICKEN2", 0xe4f4);
|
|
|
}
|
|
|
|
|
|
check_chicken_unset("ECOSKPD", 0x21d0);
|
|
|
|
|
|
check_dpfc_control_sa();
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|