diff options
-rw-r--r-- | Android.mk | 21 | ||||
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | androidio.h | 134 | ||||
-rw-r--r-- | debugfs.c | 56 | ||||
-rw-r--r-- | display.c | 500 | ||||
-rw-r--r-- | gtt.c | 230 | ||||
-rw-r--r-- | i915_reg.h | 7033 | ||||
-rw-r--r-- | igdbg.lex.l | 92 | ||||
-rw-r--r-- | igdbg.yacc.y | 67 | ||||
-rw-r--r-- | ioperm.S | 40 | ||||
-rw-r--r-- | iopl.S | 35 | ||||
-rw-r--r-- | linux/Makefile | 19 | ||||
-rw-r--r-- | linux/imem.c | 910 | ||||
-rwxr-xr-x | linux/load.sh | 17 | ||||
-rw-r--r-- | main.c | 576 | ||||
-rw-r--r-- | main.h | 220 | ||||
-rw-r--r-- | ppgtt.c | 167 | ||||
-rw-r--r-- | readme.txt | 581 | ||||
-rw-r--r-- | reg.c | 446 | ||||
-rw-r--r-- | ring.c | 770 |
20 files changed, 11934 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..ffca1c6 --- /dev/null +++ b/Android.mk @@ -0,0 +1,21 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := igdbg.lex.l igdbg.yacc.y \ + ioperm.S iopl.S \ + main.c gtt.c ppgtt.c display.c ring.c reg.c \ + debugfs.c + +LOCAL_32_BIT_ONLY := true +LOCAL_CFLAGS += -DANDROID -O2 -Wall -ffloat-store + +LOCAL_C_INCLUDES := + +LOCAL_MODULE := igdbg +LOCAL_MODULE_TAGS := optional + +LOCAL_SHARED_LIBRARIES := +include $(BUILD_EXECUTABLE) + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..affb3e3 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +all:igdbg +srcs= igdbg.yacc.c igdbg.lex.c main.c gtt.c ppgtt.c display.c ring.c reg.c debugfs.c +objs= igdbg.yacc.o igdbg.lex.o main.o gtt.o ppgtt.o display.o ring.o reg.o debugfs.o + +igdbg.yacc.c igdbg.yacc.h: igdbg.yacc.y + bison -v -d igdbg.yacc.y -o igdbg.yacc.c + +igdbg.lex.c: igdbg.lex.l + lex -o igdbg.lex.c igdbg.lex.l + +%.o: %.c + gcc -Wall -g -c -o $@ $< -I. -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE + +main.o: main.c main.h + +igdbg: $(srcs) $(objs) + gcc -g -Wall -o igdbg $(objs) -ll -lreadline -lncurses + +clean: + rm -rf igdbg *.o *.output igdbg.lex.c igdbg.yacc.c igdbg.yacc.h diff --git a/androidio.h b/androidio.h new file mode 100644 index 0000000..cd2d89b --- /dev/null +++ b/androidio.h @@ -0,0 +1,134 @@ +static __inline unsigned char +inb (unsigned short int __port) +{ + unsigned char _v; + + __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (__port)); + return _v; +} + +static __inline unsigned char +inb_p (unsigned short int __port) +{ + unsigned char _v; + + __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (__port)); + return _v; +} + +static __inline unsigned short int +inw (unsigned short int __port) +{ + unsigned short _v; + + __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (__port)); + return _v; +} + +static __inline unsigned short int +inw_p (unsigned short int __port) +{ + unsigned short int _v; + + __asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (__port)); + return _v; +} + +static __inline unsigned int +inl (unsigned short int __port) +{ + unsigned int _v; + + __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (__port)); + return _v; +} + +static __inline unsigned int +inl_p (unsigned short int __port) +{ + unsigned int _v; + __asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (__port)); + return _v; +} + +static __inline void +outb (unsigned char __value, unsigned short int __port) +{ + __asm__ __volatile__ ("outb %b0,%w1": :"a" (__value), "Nd" (__port)); +} + +static __inline void +outb_p (unsigned char __value, unsigned short int __port) +{ + __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (__value), + "Nd" (__port)); +} + +static __inline void +outw (unsigned short int __value, unsigned short int __port) +{ + __asm__ __volatile__ ("outw %w0,%w1": :"a" (__value), "Nd" (__port)); + +} + +static __inline void +outw_p (unsigned short int __value, unsigned short int __port) +{ + __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (__value), + "Nd" (__port)); +} + +static __inline void +outl (unsigned int __value, unsigned short int __port) +{ + __asm__ __volatile__ ("outl %0,%w1": :"a" (__value), "Nd" (__port)); +} + +static __inline void +outl_p (unsigned int __value, unsigned short int __port) +{ + __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (__value), + "Nd" (__port)); +} + +static __inline void +insb (unsigned short int __port, void *addr, unsigned long int __count) +{ + __asm__ __volatile__ ("cld ; rep ; insb":"=D" (addr), "=c" (__count) + :"d" (__port), "0" (addr), "1" (__count)); +} + +static __inline void +insw (unsigned short int __port, void *addr, unsigned long int __count) +{ + __asm__ __volatile__ ("cld ; rep ; insw":"=D" (addr), "=c" (__count) + :"d" (__port), "0" (addr), "1" (__count)); +} + +static __inline void +insl (unsigned short int __port, void *addr, unsigned long int __count) +{ + __asm__ __volatile__ ("cld ; rep ; insl":"=D" (addr), "=c" (__count) + :"d" (__port), "0" (addr), "1" (__count)); +} + +static __inline void +outsb (unsigned short int __port, const void *addr, unsigned long int __count) +{ + __asm__ __volatile__ ("cld ; rep ; outsb":"=S" (addr), "=c" (__count) + :"d" (__port), "0" (addr), "1" (__count)); +} + +static __inline void +outsw (unsigned short int __port, const void *addr, unsigned long int __count) +{ + __asm__ __volatile__ ("cld ; rep ; outsw":"=S" (addr), "=c" (__count) + :"d" (__port), "0" (addr), "1" (__count)); +} + +static __inline void +outsl (unsigned short int __port, const void *addr, unsigned long int __count) +{ + __asm__ __volatile__ ("cld ; rep ; outsl":"=S" (addr), "=c" (__count) + :"d" (__port), "0" (addr), "1" (__count)); +} diff --git a/debugfs.c b/debugfs.c new file mode 100644 index 0000000..931992b --- /dev/null +++ b/debugfs.c @@ -0,0 +1,56 @@ +/* + * Copyright © 2014 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> +#include <errno.h> +#include "i915_reg.h" +#include "main.h" + +static FILE *forcewake_fp = NULL; + +int forcewake_on() +{ + forcewake_fp = fopen("/sys/kernel/debug/dri/0/i915_forcewake_user", "w"); + if (forcewake_fp == NULL) { + printf("Open /sys/kernel/debug/dri/0/i915_forcewake_user with %s\n", strerror(errno)); + return 1; + } + + return 0; +} + +int forcewake_off() +{ + fclose(forcewake_fp); + forcewake_fp = NULL; + + return 0; +} diff --git a/display.c b/display.c new file mode 100644 index 0000000..066079a --- /dev/null +++ b/display.c @@ -0,0 +1,500 @@ +/* + * Copyright © 2014 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> + +#include "main.h" +#include "i915_reg.h" + +int process_onscreen(char *cmdhdr) +{ + unsigned int adpa, dspcntr, dsp_off, gtt_off; + int info_dumped = 0; /* onscreen information is dumped */ + + adpa=INREG_DISP(linear_mmio,0x61100); + +#define PRINT_DSPINFO \ + info_dumped = 1; \ + gtt_off=dsp_off/4096 * 8; \ + printf("DSPCNTR:value=0x%08x(%s, format 0x%01x(e:RGBX,f:RGBA))\n", \ + dspcntr, (dspcntr&(1<<10))?"X-tiled(512x8)":"linear", (dspcntr>>26)&0xf); \ + print_bin_fmt(dspcntr,9); \ + printf("Offset of current display:0x%x(%dM+%dK), GTT offset at %d\n", \ + dsp_off,dsp_off>>20,(dsp_off>>10)&0x3ff, gtt_off); + + if (adpa & (1<<31)) { + if (adpa & (1<<30)) { /* pipe B selected */ + printf("Pipe B is selected\n"); + dsp_off=INREG_DISP(linear_mmio,0x7019C); /* plane B is the default */ + dspcntr = INREG_DISP(linear_mmio,0x71180); + } else { /* pipe A selected */ + printf("Pipe A is selected\n"); + dsp_off=INREG_DISP(linear_mmio,0x7019C); /* plane A is the default */ + dspcntr = INREG_DISP(linear_mmio,0x70180); + } + PRINT_DSPINFO; + + return 0; + } + + dspcntr = INREG_DISP(linear_mmio,0x70180); + if (dspcntr & (1<<31)) { + printf("Plane A is enabled\n"); + dsp_off=INREG_DISP(linear_mmio,0x7019C); /* plane A is the default */ + + PRINT_DSPINFO; + } + + dspcntr = INREG_DISP(linear_mmio,0x71180); + if (dspcntr & (1<<31)) { + printf("Plane B is enabled\n"); + dsp_off=INREG_DISP(linear_mmio,0x7119C); /* plane A is the default */ + PRINT_DSPINFO; + } + + if (info_dumped == 0) { + printf("It looks no plane is enabled. Check bellow file?\n"); + printf(" /sys/kernel/debug/dri/0/i915_gem_framebuffer\n"); + } + + return 0; +} + +int process_pipe(char *cmdhdr) +{ + unsigned int value; + + printf("DSPARB:reg=0x%x,value=0x%08x\n",0x70030,(value=INREG_DISP(linear_mmio,0x70030))); + print_bin_fmt(value,9); + + printf("PIPE A Information...\n"); + + value=INREG_DISP(linear_mmio,0x70008); + printf("PIPEACONF:reg=0x%x,value=0x%08x (%s,%s)\n",0x70008, + value,value&(1<<31)?"enabled":"disabled",value&(1<<30)?"single wide mode":"double wide mode"); + print_bin_fmt(value,9); + + printf("PIPEASTAT:reg=0x70024,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x70024))); + print_bin_fmt(value,9); + + value=INREG_DISP(linear_mmio,0x70008); + printf("PIPEACONF:reg=0x%x,value=0x%08x (%s,%s)\n",0x70008, + value,value&(1<<31)?"enabled":"disabled",value&(1<<30)?"single wide mode":"double wide mode"); + print_bin_fmt(value,9); + +#if 0 + printf("DPLL_A:reg=0x6014,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x6014))); + print_bin_fmt(value,9); + printf("FPA0:reg=0x6040,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x6040))); + print_bin_fmt(value,9); +#endif + + value=INREG_DISP(linear_mmio,0x60000); + printf("HTOTAL_A:reg=0x60000,value=0x%08x(horizontal active display pixel %d)\n", + value,value&0xfff); + print_bin_fmt(value,9); + printf("HBLANK_A:reg=0x60004,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60004))); + print_bin_fmt(value,9); + printf("HSYNC_A:reg=0x60008,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60008))); + print_bin_fmt(value,9); + + value=INREG_DISP(linear_mmio,0x6000c); + printf("VTOTAL_A:reg=0x6000c,value=0x%08x(vertical active display lines %d)\n", + value,value&0xfff); + print_bin_fmt(value,9); + printf("VBLANK_A:reg=0x60010,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60010))); + print_bin_fmt(value,9); + printf("VSYNC_A:reg=0x60014,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60014))); + print_bin_fmt(value,9); + printf("PIPEASRC:reg=0x6001c,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x6001c))); + print_bin_fmt(value,9); + printf("BCLPPAT_A:reg=0x60020,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60020))); + print_bin_fmt(value,9); + printf("VYNCSHIFT_A:reg=0x60028,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60028))); + print_bin_fmt(value,9); + printf("CRCCtrlColorA_G:reg=0x60054,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60054))); + print_bin_fmt(value,9); + printf("CRCCtrlColorA_B:reg=0x60058,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x60058))); + print_bin_fmt(value,9); + printf("CRCCtrlColorA_Residual:reg=0x6005C,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x6005c))); + print_bin_fmt(value,9); + + printf("PIPEA_DSL:reg=0x%x,value=0x%08x\n",0x70000,(value=INREG_DISP(linear_mmio,0x70000))); + print_bin_fmt(value,9); + printf("PIPEA_SLC:reg=0x%x,value=0x%08x\n",0x70004,(value=INREG_DISP(linear_mmio,0x70004))); + print_bin_fmt(value,9); + printf("PIPEASTAT:reg=0x%x,value=0x%08x\n",0x70024,(value=INREG_DISP(linear_mmio,0x70024))); + print_bin_fmt(value,9); + +#if 0 /* readonly, requires that this pipe's PLL is running */ + printf("PIPEAFRAMEH:reg=0x%x,value=0x%08x\n",0x70040,(value=INREG_DISP(linear_mmio,0x70040))); + print_bin_fmt(value,9); + printf("PIPEAFRAMEPIX:reg=0x%x,value=0x%08x\n",0x70044,(value=INREG_DISP(linear_mmio,0x70044))); + print_bin_fmt(value,9); +#endif + +#if 0 + printf("\nPIPE B Information...\n"); + + printf("DPLL_B:reg=0x6018,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x6018))); + print_bin_fmt(value,9); + printf("FPB0:reg=0x6048,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x6048))); + print_bin_fmt(value,9); + value=INREG_DISP(linear_mmio,0x61000); + printf("HTOTAL_B:reg=0x61000,value=0x%08x(horizontal active display pixel %d)\n", + value,value&0xfff); + print_bin_fmt(value,9); + printf("HBLANK_B:reg=0x61004,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61004))); + print_bin_fmt(value,9); + printf("HSYNC_B:reg=0x61008,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61008))); + print_bin_fmt(value,9); + value=INREG_DISP(linear_mmio,0x6100c); + printf("VTOTAL_B:reg=0x6100c,value=0x%08x(vertical active display lines %d)\n", + value,value&0xfff); + print_bin_fmt(value,9); + printf("VBLANK_B:reg=0x61010,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61010))); + print_bin_fmt(value,9); + printf("VSYNC_B:reg=0x61014,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61014))); + print_bin_fmt(value,9); + printf("PIPEBSRC:reg=0x6101c,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x6101c))); + print_bin_fmt(value,9); + value=INREG_DISP(linear_mmio,0x71008); + printf("PIPEBCONF:reg=0x%x,value=0x%08x (%s,%s)\n",0x71008, + value,value&(1<<31)?"enabled":"disabled",value&(1<<30)?"single wide mode":"double wide mode"); + print_bin_fmt(value,9); +#if 0 + printf("BCLRPAT_B:reg=0x61020,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61020))); + print_bin_fmt(value,9); + printf("CRCCtrlColorB:reg=0x61050,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61050))); + print_bin_fmt(value,9); + printf("CRCCtrlColorB:reg=0x61054,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61054))); + print_bin_fmt(value,9); + printf("CRCResColorB:reg=0x61060,value=0x%08x\n",(value=INREG_DISP(linear_mmio,0x61060))); + print_bin_fmt(value,9); +#endif + printf("PIPEB_DSL:reg=0x%x,value=0x%08x\n",0x71000,(value=INREG_DISP(linear_mmio,0x71000))); + print_bin_fmt(value,9); + printf("PIPEB_SLC:reg=0x%x,value=0x%08x\n",0x71004,(value=INREG_DISP(linear_mmio,0x71004))); + print_bin_fmt(value,9); + printf("PIPEBSTAT:reg=0x%x,value=0x%08x\n",0x71024,(value=INREG_DISP(linear_mmio,0x71024))); + print_bin_fmt(value,9); +#if 0 /* readonly, requires that this pipe's PLL is running */ + printf("PIPEBFRAMEH:reg=0x%x,value=0x%08x\n",0x71040,(value=INREG_DISP(linear_mmio,0x71040))); + print_bin_fmt(value,9); + printf("PIPEBFRAMEPIX:reg=0x%x,value=0x%08x\n",0x71044,(value=INREG_DISP(linear_mmio,0x71044))); + print_bin_fmt(value,9); +#endif + +#endif + + printf("\n"); + + return 0; +} + +int process_plane(char *cmdhdr) +{ + unsigned int value; + unsigned int reg; + int i; + + printf("DSPARB:reg=0x%x,value=0x%08x\n",0x70030,(value=INREG_DISP(linear_mmio,0x70030))); + print_bin_fmt(value,9); + + printf("PLANE A Information...\n"); + printf("DSPASTRIDE:reg=0x%x,value=0x%08x\n",0x70188,(value=INREG_DISP(linear_mmio,0x70188))); + print_bin_fmt(value,9); + printf("DSPASIZE:reg=0x%x,value=0x%08x\n",0x70190,(value=INREG_DISP(linear_mmio,0x70190))); + print_bin_fmt(value,9); + printf("DSPAKEYVAL:reg=0x%x,value=0x%08x\n",0x70194,(value=INREG_DISP(linear_mmio,0x70194))); + print_bin_fmt(value,9); + printf("DSPAKEYMASK:reg=0x%x,value=0x%08x\n",0x70198,(value=INREG_DISP(linear_mmio,0x70198))); + print_bin_fmt(value,9); + printf("DSPASURF:reg=0x%x,value=0x%08x\n",0x7019C,(value=INREG_DISP(linear_mmio,0x7019c))); + print_bin_fmt(value,9); + printf("DSPATILEOFF:reg=0x%x,value=0x%08x\n",0x701a4,(value=INREG_DISP(linear_mmio,0x701a4))); + print_bin_fmt(value,9); + printf("DSPAPOS:reg=0x%x,value=0x%08x\n",0x7018C,(value=INREG_DISP(linear_mmio,0x7018C))); + print_bin_fmt(value,9); + printf("DSPAADDR:reg=0x%x,value=0x%08x\n",0x70184,(value=INREG_DISP(linear_mmio,0x70184))); + print_bin_fmt(value,9); + value = INREG_DISP(linear_mmio,0x70180); + printf("DSPACNTR:reg=0x%x,value=0x%08x(%s,pipe %c selected)\n", + 0x70180,value,(value&(1<<31))?"Enabled":"Disabled",(value&(3<<24))?'B':'A'); + print_bin_fmt(value,9); + + printf("\nPLANE B Information...\n"); + printf("DSPBSTRIDE:reg=0x%x,value=0x%08x\n",0x71188,(value=INREG_DISP(linear_mmio,0x71188))); + print_bin_fmt(value,9); + printf("DSPBSIZE:reg=0x%x,value=0x%08x\n",0x71190,(value=INREG_DISP(linear_mmio,0x71190))); + print_bin_fmt(value,9); + printf("DSPBKEYVAL:reg=0x%x,value=0x%08x\n",0x71194,(value=INREG_DISP(linear_mmio,0x71194))); + print_bin_fmt(value,9); + printf("DSPBKEYMASK:reg=0x%x,value=0x%08x\n",0x71198,(value=INREG_DISP(linear_mmio,0x71198))); + print_bin_fmt(value,9); + printf("DSPBSURF:reg=0x%x,value=0x%08x\n",0x7119C,(value=INREG_DISP(linear_mmio,0x7119c))); + print_bin_fmt(value,9); + printf("DSPBTILEOFF:reg=0x%x,value=0x%08x\n",0x711a4,(value=INREG_DISP(linear_mmio,0x711a4))); + print_bin_fmt(value,9); + printf("DSPBPOS:reg=0x%x,value=0x%08x\n",0x7118C,(value=INREG_DISP(linear_mmio,0x7118C))); + print_bin_fmt(value,9); + printf("DSPBADDR:reg=0x%x,value=0x%08x\n",0x71184,(value=INREG_DISP(linear_mmio,0x71184))); + print_bin_fmt(value,9); + value=INREG_DISP(linear_mmio,0x71180); + printf("DSPBCNTR:reg=0x%x,value=0x%08x(%s,pipe %c selected)\n", + 0x71180,value, + (value&(1<<31))?"Enabled":"Disabled",(value&(3<<24))?'B':'A'); + print_bin_fmt(value,9); + + printf("\nPLANE C Information...\n"); + printf("DSPCSTRIDE:reg=0x%x,value=0x%08x\n",0x72188,(value=INREG_DISP(linear_mmio,0x72188))); + print_bin_fmt(value,9); + printf("DSPCSIZE:reg=0x%x,value=0x%08x\n",0x72190,(value=INREG_DISP(linear_mmio,0x72190))); + print_bin_fmt(value,9); + printf("DSPCKEYMINVAL:reg=0x%x,value=0x%08x\n",0x72194,(value=INREG_DISP(linear_mmio,0x72194))); + print_bin_fmt(value,9); + printf("DSPCKEYMAXVAL:reg=0x%x,value=0x%08x\n",0x721A0,(value=INREG_DISP(linear_mmio,0x721A0))); + print_bin_fmt(value,9); + printf("DSPCKEYMASK:reg=0x%x,value=0x%08x\n",0x72198,(value=INREG_DISP(linear_mmio,0x72198))); + print_bin_fmt(value,9); + printf("DSPCSURF:reg=0x%x,value=0x%08x\n",0x7219C,(value=INREG_DISP(linear_mmio,0x7219c))); + print_bin_fmt(value,9); + printf("DSPCTILEOFF:reg=0x%x,value=0x%08x\n",0x721a4,(value=INREG_DISP(linear_mmio,0x721a4))); + print_bin_fmt(value,9); + printf("DSPCContAlpha:reg=0x%x,value=0x%08x\n",0x721a8,(value=INREG_DISP(linear_mmio,0x721a8))); + print_bin_fmt(value,9); + printf("DSPCPOS:reg=0x%x,value=0x%08x\n",0x7218C,(value=INREG_DISP(linear_mmio,0x7218C))); + print_bin_fmt(value,9); + printf("DSPCLINOFF:reg=0x%x,value=0x%08x\n",0x72184,(value=INREG_DISP(linear_mmio,0x72184))); + print_bin_fmt(value,9); + printf("DCLRC0:reg=0x%x,value=0x%08x\n",0x721d0,(value=INREG_DISP(linear_mmio,0x721d0))); + print_bin_fmt(value,9); + printf("DCLRC1:reg=0x%x,value=0x%08x\n",0x721d4,(value=INREG_DISP(linear_mmio,0x721d4))); + print_bin_fmt(value,9); + + reg = 0x721e0; + for (i=5; i>=0; i--) { + printf("GAMC%d:reg=0x%x,value=0x%08x\n",i, reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = reg + 4; + } + + value=INREG_DISP(linear_mmio,0x72180); + printf("DSPCCNTR:reg=0x%x,value=0x%08x(%s,pipe %c selected)\n", + 0x72180,value, + (value&(1<<31))?"Enabled":"Disabled",(value&(3<<24))?'B':'A'); + print_bin_fmt(value,9); + + printf("\n"); + + return 0; +} + +int process_port(char *cmdhdr) +{ + unsigned int value; + + printf("PORT Information...\n"); + + value=INREG_DISP(linear_mmio,0x61100); + printf("ADPA:reg=0x%x,value=0x%08x (pipe %c selected)\n", + 0x61100,(value),(value&(1<<30))?'B':'A'); + print_bin_fmt(value,9); + + printf("\n"); + + return 0; +} + + +int process_fifo(char *cmdhdr) +{ + unsigned int value; + unsigned int reg; + + printf("DSPARB:reg=0x%x,value=0x%08x\n",0x70030,(value=INREG_DISP(linear_mmio,0x70030))); + print_bin_fmt(value,9); + + printf("FW1:reg=0x%x,value=0x%08x\n",0x70034,(value=INREG_DISP(linear_mmio,0x70034))); + print_bin_fmt(value,9); + + reg = 0x70038; + printf("FW2:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x7003c; + printf("FW3:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x7003c; + printf("FW3:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + printf("\n"); + + return 0; +} + +int process_overlay(char *cmdhdr) +{ + unsigned int value; + unsigned int reg; + int i; + + reg = 0x30000; + printf("OVADD:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30004; + printf("OTEST:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30008; + printf("DVOSTA:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x3000C; + printf("DVOSTAX:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + for (i=0; i<=5;i++) { + reg = 0x30010 + 4*i; + printf("GAMMA-%d:reg=0x%x,value=0x%08x\n",i, reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + } + + for (i=0; i<=3;i++) { + reg = 0x30058 + 4*i; + printf("SYNCHPH-%d:reg=0x%x,value=0x%08x\n",i, reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + } + + reg = 0x30100; + printf("OBUF_0Y:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30104; + printf("OBUF_1Y:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30108; + printf("OBUF_0U:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x3010C; + printf("OBUF_0V:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + + reg = 0x30110; + printf("OBUF_1U:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30114; + printf("OBUF_1V:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30118; + printf("OSTRIDE:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x3011C; + printf("YRGB_VPH:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30120; + printf("UV_VPH:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30124; + printf("HORZ_PH:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30128; + printf("INIT_PHS:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x3012C; + printf("DWINPOS:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30130; + printf("DWINSZ:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30134; + printf("DWINSZ:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30138; + printf("SWIDTHSW:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x3013C; + printf("SHEIGHT:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + + reg = 0x30168; + printf("OCMD:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + + reg = 0x30170; + printf("OSTART_0Y:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30174; + printf("OSTART_1Y:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + + reg = 0x30178; + printf("OSTART_0U:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x3017C; + printf("OSTART_0V:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30180; + printf("OSTART_1U:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + reg = 0x30184; + printf("OSTART_1V:reg=0x%x,value=0x%08x\n",reg,(value=INREG_DISP(linear_mmio,reg))); + print_bin_fmt(value,9); + + printf("\n"); + + return 0; +} @@ -0,0 +1,230 @@ +/* + * Copyright © 2014 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/mman.h> +#include <stdint.h> +#include "main.h" +#include "i915_reg.h" + + +int process_dumpgtt(char *cmdhdr,unsigned int fbaddr,unsigned int size) +{ + uint32_t i,start_entry,end_entry,total_entries; + uint32_t aligned_size, entries = 0; + uint64_t *p, previous_entry=0; + //const char *type = "1:valid,2:WR,4:RO,8:cached"; + + if (fbaddr >= gtt_mapable_size) { + printf("Address 0x%x is out of GTT mappable range 0x%x\n", + fbaddr, gtt_mapable_size/4096); + return 0; + } + + total_entries = gtt_mapable_size/4096; + start_entry = fbaddr/4096; + aligned_size = (size + 4095) & (~4095); + entries = aligned_size / 4096; + end_entry = min(start_entry + entries, total_entries); + + fprintf(stdout,"\nGTT entry from entry %d to %d(total %d, size %d/%dK)\n", + start_entry,end_entry,end_entry - start_entry + 1, + size, size/1024); + fprintf(stdout,"\nSkip if the entry map to same address\n"); + + p =(uint64_t *)((char *)linear_gtt + 8*start_entry); + for (i=start_entry;i<end_entry;i++) { + uint64_t tmp = *p++; + uint32_t tmp1 = (uint32_t) tmp; + if (previous_entry == tmp) + continue; + + previous_entry = tmp; + if (i%256==0) + printf("\n-----------------------------%03dM FB------------------------------\n",i/256); + fprintf(stdout,"FB:0x%07x|%03dM+%04dK|GTT offset:0x%05lx(entry 0x%05x):", + i*4096,i>>8,(i<<2)&0x3ff,(unsigned char *)p-linear_gtt-8, i); + fprintf(stdout," %010x", (uint32_t)tmp); + if (verbose) + fprintf(stdout," page no.=%06d(%04dM+%04dK),map type=0x%x", + (tmp1>>12),(tmp1>>20),(tmp1>>10)&0x3ff,tmp1&0xf); + fprintf(stdout,"\n"); + } + + return 0; +} + +int process_stolen(char *cmdhdr) +{ + uint32_t stolen_phy_start = stolen_base; + uint32_t stolen_phy_end = stolen_base + stolen_size; + uint32_t i, start_i=~0, total_entry = gtt_size / 8; + uint64_t *p, previous_entry=0; + + printf("Dump all stolen memory mappings in GTT\n"); + + p =(uint64_t *)linear_gtt; + + for (i=0;i<total_entry;i++) { + uint64_t tmp = *p++; + uint32_t tmp1 = (uint32_t) tmp; + + if (previous_entry == tmp) + continue; + + previous_entry = tmp; + if (tmp1<stolen_phy_start || tmp1>stolen_phy_end) + continue; + + if (i != start_i) { + printf("\n-----------------------------%03dM+%04dK FB------------------------------\n", + i>>8,(i<<2)&0x3ff); + start_i = i; + } + start_i++; + + fprintf(stdout,"FB:0x%07x|%03dM+%04dK|GTT offset:0x%05lx(entry 0x%05x):", + i*4096,i>>8,(i<<2)&0x3ff,(unsigned char *)p-linear_gtt-8,i); + fprintf(stdout," %010x", (uint32_t)tmp); + if (verbose) + fprintf(stdout," page no.=%06d(%04dM+%04dK),map type=0x%x", + (tmp1>>12),(tmp1>>20),(tmp1>>10)&0x3ff,tmp1&0xf); + fprintf(stdout,"\n"); + } + + return 0; +} + +static uint32_t old_lsb; +static uint32_t old_msb; +static int set_fence(unsigned int offset, unsigned int size) +{ + unsigned int force_stride = 5120; + unsigned int fence_idx = 0; + uint32_t fencereg_offset = 0x100000; + + uint32_t lsb = (offset & 0xfffff000) | 1; + uint32_t msb = ((offset + size + 0xfff) & 0xfffff000) | (force_stride/128 -1); + + old_lsb = INREG(linear_mmio, fence_idx*8 + fencereg_offset); + old_msb = INREG(linear_mmio, (fence_idx*8 + 4) + fencereg_offset); + + printf("Force FENCE0 for linear access with stride %d\n", force_stride); + OUTREG(linear_mmio, fence_idx*8 + fencereg_offset, lsb); + OUTREG(linear_mmio, (fence_idx*8 + 4) + fencereg_offset, msb); + + return 0; +} + +static int unset_fence() +{ + uint32_t fencereg_offset = 0x100000; + int fence_idx = 0; + + printf("Restore FENCE0\n"); + OUTREG(linear_mmio, fence_idx*8 + fencereg_offset, old_lsb); + OUTREG(linear_mmio, (fence_idx*8 + 4) + fencereg_offset, old_msb); + + return 0; +} + +int process_fillfb(char *cmdhdr,unsigned int offset, + unsigned int size,unsigned int value) +{ + printf("Fill frame buffer from offset 0x%x (%dM+%dK),with value 0x%x,size %d\n", + offset,offset>>20, (offset>>10)&0x3ff,value,size); + if ((offset>>20) > FB_MMAP_MB) { + printf("!!!!!Sorry, Out of aperture mmap range %dM!!!!!\n", FB_MMAP_MB); + return 0; + } + + memset((char *)(linear_fb+offset),value,size); + + return 0; +} + +int process_fillfbl(char *cmdhdr,unsigned int offset, + unsigned int size,unsigned int value) +{ + set_fence(offset, size); + process_fillfb(NULL, offset, size, value); + unset_fence(); + + return 0; +} + +int process_dumpfb(char *cmdhdr,unsigned int offset, + unsigned int size) +{ + unsigned int i; + + printf("Dump frame buffer from offset 0x%x,size %d\n",offset,size); + for (i=0;i<size;i++) { + if ((i%8) == 0) { + printf("\n0x%08x: ",offset+i); + } + printf("0x%02x ",*((unsigned char *)(linear_fb+offset+i))); + } + printf("\n"); + + return 0; +} + +int process_dumpfbl(char *cmdhdr,unsigned int offset, + unsigned int size) +{ + set_fence(offset, size); + process_dumpfb(NULL, offset, size); + unset_fence(); + + return 0; +} + +int process_fence(char *cmdhdr) +{ + printf("Dump all fence register information\n"); + uint32_t i, fence_offset = 0x100000; + + for (i=0;i<16;i++) { + uint32_t lsb = INREG(linear_mmio, i*8 + fence_offset); + uint32_t msb = INREG(linear_mmio, (i*8 + 4) + fence_offset); + uint32_t addr = lsb&(~0xfff); + + fprintf(stdout,"FENCDE%d_LSB:0x%08x (valid:%d, tile:%c, start addr:0x%08x(%dM+%dK))\n", + i, lsb, lsb&1, (lsb>>1)&1?'Y':'X', + addr, addr>>20, (addr>>10)&0x3ff); + + addr = msb&(~0xfff); + fprintf(stdout,"FENCDE%d_MSB:0x%08x (pitch=%d,size=%dK,end addr:0x%08x(%dM+%dK))\n", + i, msb, ((msb&0x7ff) + 1) * 128, ((msb&(~0xfff)) - (lsb&(~0xfff))) >> 10 , + addr, addr>>20, (addr>>10)&0x3ff); + printf("\n"); + } + + return 0; +} + + diff --git a/i915_reg.h b/i915_reg.h new file mode 100644 index 0000000..396648d --- /dev/null +++ b/i915_reg.h @@ -0,0 +1,7033 @@ +/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + */ + +#ifndef _I915_REG_H_ +#define _I915_REG_H_ + +#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) +#define _TRANSCODER(tran, a, b) ((a) + (tran)*((b)-(a))) + +#define _PORT(port, a, b) ((a) + (port)*((b)-(a))) +#define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \ + (pipe) == PIPE_B ? (b) : (c)) + +#define _MASKED_BIT_ENABLE(a) (((a) << 16) | (a)) +#define _MASKED_BIT_DISABLE(a) ((a) << 16) +#define _MASKED_BIT_ENABLE_ALL(b) (0xFFFF0000 | (b)) + +/* PCI config space */ + +#define HPLLCC 0xc0 /* 855 only */ +#define GC_CLOCK_CONTROL_MASK (0xf << 0) +#define GC_CLOCK_133_200 (0 << 0) +#define GC_CLOCK_100_200 (1 << 0) +#define GC_CLOCK_100_133 (2 << 0) +#define GC_CLOCK_166_250 (3 << 0) +#define GCFGC2 0xda +#define GCFGC 0xf0 /* 915+ only */ +#define GC_LOW_FREQUENCY_ENABLE (1 << 7) +#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define GC_DISPLAY_CLOCK_267_MHZ_PNV (0 << 4) +#define GC_DISPLAY_CLOCK_333_MHZ_PNV (1 << 4) +#define GC_DISPLAY_CLOCK_444_MHZ_PNV (2 << 4) +#define GC_DISPLAY_CLOCK_200_MHZ_PNV (5 << 4) +#define GC_DISPLAY_CLOCK_133_MHZ_PNV (6 << 4) +#define GC_DISPLAY_CLOCK_167_MHZ_PNV (7 << 4) +#define GC_DISPLAY_CLOCK_MASK (7 << 4) +#define GM45_GC_RENDER_CLOCK_MASK (0xf << 0) +#define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0) +#define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0) +#define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0) +#define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0) +#define I965_GC_RENDER_CLOCK_MASK (0xf << 0) +#define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0) +#define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0) +#define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0) +#define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0) +#define I945_GC_RENDER_CLOCK_MASK (7 << 0) +#define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0) +#define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0) +#define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0) +#define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0) +#define I915_GC_RENDER_CLOCK_MASK (7 << 0) +#define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0) +#define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0) +#define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0) +#define PCI_LBPC 0xf4 /* legacy/combination backlight modes, also called LBB */ + + +/* Graphics reset regs */ +#define I965_GDRST 0xc0 /* PCI config register */ +#define GRDOM_FULL (0<<2) +#define GRDOM_RENDER (1<<2) +#define GRDOM_MEDIA (3<<2) +#define GRDOM_MASK (3<<2) +#define GRDOM_RESET_ENABLE (1<<0) + +#define ILK_GDSR 0x2ca4 /* MCHBAR offset */ +#define ILK_GRDOM_FULL (0<<1) +#define ILK_GRDOM_RENDER (1<<1) +#define ILK_GRDOM_MEDIA (3<<1) +#define ILK_GRDOM_MASK (3<<1) +#define ILK_GRDOM_RESET_ENABLE (1<<0) + +#define GEN6_MBCUNIT_SNPCR 0x900c /* for LLC config */ +#define GEN6_MBC_SNPCR_SHIFT 21 +#define GEN6_MBC_SNPCR_MASK (3<<21) +#define GEN6_MBC_SNPCR_MAX (0<<21) +#define GEN6_MBC_SNPCR_MED (1<<21) +#define GEN6_MBC_SNPCR_LOW (2<<21) +#define GEN6_MBC_SNPCR_MIN (3<<21) /* only 1/16th of the cache is shared */ + +#define VLV_G3DCTL 0x9024 +#define VLV_GSCKGCTL 0x9028 + +#define GEN6_MBCTL 0x0907c +#define GEN6_MBCTL_ENABLE_BOOT_FETCH (1 << 4) +#define GEN6_MBCTL_CTX_FETCH_NEEDED (1 << 3) +#define GEN6_MBCTL_BME_UPDATE_ENABLE (1 << 2) +#define GEN6_MBCTL_MAE_UPDATE_ENABLE (1 << 1) +#define GEN6_MBCTL_BOOT_FETCH_MECH (1 << 0) + +#define GEN6_GDRST 0x941c +#define GEN6_GRDOM_FULL (1 << 0) +#define GEN6_GRDOM_RENDER (1 << 1) +#define GEN6_GRDOM_MEDIA (1 << 2) +#define GEN6_GRDOM_BLT (1 << 3) +#define GEN6_GRDOM_VECS (1 << 4) +#define GEN8_GRDOM_MEDIA2 (1 << 7) + +#define GEN8_SRID_0_2_0_PCI 0xf8 + +#define RING_PP_DIR_BASE(ring) ((ring)->mmio_base+0x228) +#define RING_PP_DIR_BASE_READ(ring) ((ring)->mmio_base+0x518) +#define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220) +#define PP_DIR_DCLV_2G 0xffffffff + +#define GEN8_RING_PDP_UDW(ring, n) ((ring)->mmio_base+0x270 + ((n) * 8 + 4)) +#define GEN8_RING_PDP_LDW(ring, n) ((ring)->mmio_base+0x270 + (n) * 8) + +#define GAM_ECOCHK 0x4090 +#define ECOCHK_SNB_BIT (1<<10) +#define HSW_ECOCHK_ARB_PRIO_SOL (1<<6) +#define ECOCHK_PPGTT_CACHE64B (0x3<<3) +#define ECOCHK_PPGTT_CACHE4B (0x0<<3) +#define ECOCHK_PPGTT_GFDT_IVB (0x1<<4) +#define ECOCHK_PPGTT_LLC_IVB (0x1<<3) +#define ECOCHK_PPGTT_UC_HSW (0x1<<3) +#define ECOCHK_PPGTT_WT_HSW (0x2<<3) +#define ECOCHK_PPGTT_WB_HSW (0x3<<3) + +#define GAC_ECO_BITS 0x14090 +#define ECOBITS_SNB_BIT (1<<13) +#define ECOBITS_PPGTT_CACHE64B (3<<8) +#define ECOBITS_PPGTT_CACHE4B (0<<8) + +#define GAB_CTL 0x24000 +#define GAB_CTL_CONT_AFTER_PAGEFAULT (1<<8) + +/* VGA stuff */ + +#define VGA_ST01_MDA 0x3ba +#define VGA_ST01_CGA 0x3da + +#define VGA_MSR_WRITE 0x3c2 +#define VGA_MSR_READ 0x3cc +#define VGA_MSR_MEM_EN (1<<1) +#define VGA_MSR_CGA_MODE (1<<0) + +#define VGA_SR_INDEX 0x3c4 +#define SR01 1 +#define VGA_SR_DATA 0x3c5 + +#define VGA_AR_INDEX 0x3c0 +#define VGA_AR_VID_EN (1<<5) +#define VGA_AR_DATA_WRITE 0x3c0 +#define VGA_AR_DATA_READ 0x3c1 + +#define VGA_GR_INDEX 0x3ce +#define VGA_GR_DATA 0x3cf +/* GR05 */ +#define VGA_GR_MEM_READ_MODE_SHIFT 3 +#define VGA_GR_MEM_READ_MODE_PLANE 1 +/* GR06 */ +#define VGA_GR_MEM_MODE_MASK 0xc +#define VGA_GR_MEM_MODE_SHIFT 2 +#define VGA_GR_MEM_A0000_AFFFF 0 +#define VGA_GR_MEM_A0000_BFFFF 1 +#define VGA_GR_MEM_B0000_B7FFF 2 +#define VGA_GR_MEM_B0000_BFFFF 3 + +#define VGA_DACMASK 0x3c6 +#define VGA_DACRX 0x3c7 +#define VGA_DACWX 0x3c8 +#define VGA_DACDATA 0x3c9 + +#define VGA_CR_INDEX_MDA 0x3b4 +#define VGA_CR_DATA_MDA 0x3b5 +#define VGA_CR_INDEX_CGA 0x3d4 +#define VGA_CR_DATA_CGA 0x3d5 + +/* + * Instruction field definitions used by the command parser + */ +#define INSTR_CLIENT_SHIFT 29 +#define INSTR_CLIENT_MASK 0xE0000000 +#define INSTR_MI_CLIENT 0x0 +#define INSTR_BC_CLIENT 0x2 +#define INSTR_RC_CLIENT 0x3 +#define INSTR_SUBCLIENT_SHIFT 27 +#define INSTR_SUBCLIENT_MASK 0x18000000 +#define INSTR_MEDIA_SUBCLIENT 0x2 + +/* + * Memory interface instructions used by the kernel + */ +#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) +/* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */ +#define MI_GLOBAL_GTT (1<<22) + +#define MI_NOOP MI_INSTR(0, 0) +#define MI_NOOP_WRITE_ID (1<<22) +#define MI_NOOP_ID_MASK ((1<<22) - 1) +#define MI_NOOP_MID(id) ((id) & MI_NOOP_ID_MASK) +#define MI_NOOP_WITH_ID(id) MI_INSTR(0, MI_NOOP_WRITE_ID|MI_NOOP_MID(id)) +#define MI_USER_INTERRUPT MI_INSTR(0x02, 0) +#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0) +#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) +#define MI_FLUSH MI_INSTR(0x04, 0) +#define MI_READ_FLUSH (1 << 0) +#define MI_EXE_FLUSH (1 << 1) +#define MI_NO_WRITE_FLUSH (1 << 2) +#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ +#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ +#define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ +#define MI_REPORT_HEAD MI_INSTR(0x07, 0) +#define MI_ARB_ON_OFF MI_INSTR(0x08, 0) +#define MI_ARB_ENABLE (1<<0) +#define MI_ARB_DISABLE (0<<0) +#define MI_ARB_CHECK MI_INSTR(0x05, 0) +#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) +#define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0) +#define MI_SUSPEND_FLUSH_EN (1<<0) +#define MI_OVERLAY_FLIP MI_INSTR(0x11, 0) +#define MI_OVERLAY_CONTINUE (0x0<<21) +#define MI_OVERLAY_ON (0x1<<21) +#define MI_OVERLAY_OFF (0x2<<21) +#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) +#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) +#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) +#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) +/* IVB has funny definitions for which plane to flip. */ +#define MI_DISPLAY_FLIP_IVB_PLANE_A (0 << 19) +#define MI_DISPLAY_FLIP_IVB_PLANE_B (1 << 19) +#define MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19) +#define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) +#define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) +#define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) +#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ +#define MI_SEMAPHORE_GLOBAL_GTT (1<<22) +#define MI_SEMAPHORE_UPDATE (1<<21) +#define MI_SEMAPHORE_COMPARE (1<<20) +#define MI_SEMAPHORE_REGISTER (1<<18) +#define MI_SEMAPHORE_SYNC_VR (0<<16) /* RCS wait for VCS (RVSYNC) */ +#define MI_SEMAPHORE_SYNC_VER (1<<16) /* RCS wait for VECS (RVESYNC) */ +#define MI_SEMAPHORE_SYNC_BR (2<<16) /* RCS wait for BCS (RBSYNC) */ +#define MI_SEMAPHORE_SYNC_BV (0<<16) /* VCS wait for BCS (VBSYNC) */ +#define MI_SEMAPHORE_SYNC_VEV (1<<16) /* VCS wait for VECS (VVESYNC) */ +#define MI_SEMAPHORE_SYNC_RV (2<<16) /* VCS wait for RCS (VRSYNC) */ +#define MI_SEMAPHORE_SYNC_RB (0<<16) /* BCS wait for RCS (BRSYNC) */ +#define MI_SEMAPHORE_SYNC_VEB (1<<16) /* BCS wait for VECS (BVESYNC) */ +#define MI_SEMAPHORE_SYNC_VB (2<<16) /* BCS wait for VCS (BVSYNC) */ +#define MI_SEMAPHORE_SYNC_BVE (0<<16) /* VECS wait for BCS (VEBSYNC) */ +#define MI_SEMAPHORE_SYNC_VVE (1<<16) /* VECS wait for VCS (VEVSYNC) */ +#define MI_SEMAPHORE_SYNC_RVE (2<<16) /* VECS wait for RCS (VERSYNC) */ +#define MI_SEMAPHORE_SYNC_INVALID (3<<16) +#define MI_SEMAPHORE_SYNC_MASK (3<<16) +#define MI_SET_CONTEXT MI_INSTR(0x18, 0) +#define MI_CONTEXT_ADDR_MASK ((~0)<<12) +#define MI_SET_CONTEXT_FLAG_MASK ((1<<12)-1) +#define MI_MM_SPACE_GTT (1<<8) +#define MI_MM_SPACE_PHYSICAL (0<<8) +#define MI_SAVE_EXT_STATE_EN (1<<3) +#define MI_RESTORE_EXT_STATE_EN (1<<2) +#define MI_FORCE_RESTORE (1<<1) +#define MI_RESTORE_INHIBIT (1<<0) +#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) +#define MI_STORE_DWORD_IMM_GEN4 MI_INSTR(0x20, 2) +#define MI_MEM_VIRTUAL (1 << 22) /* 945,g33,965 */ +#define MI_USE_GGTT (1 << 22) /* g4x+ */ +#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) +#define MI_STORE_DWORD_INDEX_SHIFT 2 +#define MI_STORE_REG_MEM MI_INSTR(0x24, 1) +#define MI_STORE_REG_MEM_GTT (1 << 22) +#define MI_STORE_REG_MEM_PREDICATE (1 << 21) + +/* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM: + * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw + * simply ignores the register load under certain conditions. + * - One can actually load arbitrary many arbitrary registers: Simply issue x + * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! + */ +#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*(x)-1) +#define MI_LRI_FORCE_POSTED (1<<12) +#define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*(x)-1) +#define MI_STORE_REGISTER_MEM_GEN8(x) MI_INSTR(0x24, 3*(x)-1) +#define MI_SRM_LRM_GLOBAL_GTT (1<<22) +#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ +#define MI_FLUSH_DW_STORE_INDEX (1<<21) +#define MI_INVALIDATE_TLB (1<<18) +#define MI_FLUSH_DW_OP_NONE (0<<14) +#define MI_FLUSH_DW_OP_STOREDW (1<<14) +#define MI_FLUSH_DW_OP_RSVD (2<<14) +#define MI_FLUSH_DW_OP_STAMP (3<<14) +#define MI_FLUSH_DW_OP_MASK (3<<14) +#define MI_FLUSH_DW_NOTIFY (1<<8) +#define MI_INVALIDATE_BSD (1<<7) +#define MI_FLUSH_DW_USE_GTT (1<<2) +#define MI_FLUSH_DW_USE_PPGTT (0<<2) +#define MI_BATCH_BUFFER MI_INSTR(0x30, 1) +#define MI_BATCH_NON_SECURE (1) +/* for snb/ivb/vlv this also means "batch in ppgtt" when ppgtt is enabled. */ +#define MI_BATCH_NON_SECURE_I965 (1<<8) +#define MI_BATCH_PPGTT_HSW (1<<8) +#define MI_BATCH_NON_SECURE_HSW (1<<13) +#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) +#define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */ +#define MI_BATCH_2ND_LEVEL_HSW (1<<22) +#define MI_BATCH_ADD_OFFSET_HSW (1<<16) +#define MI_BATCH_RESOURCE_STREAMER (1<<10) +#define MI_BATCH_BUFFER_START_GEN8 MI_INSTR(0x31, 1) + + +#define MI_PREDICATE_RESULT_2 (0x2214) +#define LOWER_SLICE_ENABLED (1<<0) +#define LOWER_SLICE_DISABLED (0<<0) + +/* + * 3D instructions used by the kernel + */ +#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags)) + +#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) +#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) +#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) +#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) +#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) +#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) +#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) +#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) +#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5) +#define COLOR_BLT_CMD ((2 << 29) | (0x40 << 22) | 3) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) +#define BLT_DEPTH_8 (0<<24) +#define BLT_DEPTH_16_565 (1<<24) +#define BLT_DEPTH_16_1555 (2<<24) +#define BLT_DEPTH_32 (3<<24) +#define PAT_ROP_GXCOPY 0xf0 +#define ROP_SHIFT 16 +#define HEIGHT_SHIFT 16 +#define PITCH_SIZE 4096 +#define BLT_ROP_GXCOPY (0xcc<<16) +#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */ +#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */ +#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) +#define ASYNC_FLIP (1<<22) +#define DISPLAY_PLANE_A (0<<20) +#define DISPLAY_PLANE_B (1<<20) +#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) +#define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */ +#define PIPE_CONTROL_MMIO_WRITE (1<<23) +#define PIPE_CONTROL_STORE_DATA_INDEX (1<<21) +#define PIPE_CONTROL_CS_STALL (1<<20) +#define PIPE_CONTROL_TLB_INVALIDATE (1<<18) +#define PIPE_CONTROL_QW_WRITE (1<<14) +#define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14) +#define PIPE_CONTROL_DEPTH_STALL (1<<13) +#define PIPE_CONTROL_WRITE_FLUSH (1<<12) +#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */ +#define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on Ironlake */ +#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */ +#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9) +#define PIPE_CONTROL_NOTIFY (1<<8) +#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4) +#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3) +#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2) +#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1) +#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0) +#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ + +#define GFX_OP_3DPRIMITIVE() \ + ((0x3<<29)|(0x3<<27)|(0x3<<24)| \ + (0x0<<16)|(0x0<<10)|(0x0<<8)|(7-2)) + + +/* + * Commands used only by the command parser + */ +#define MI_SET_PREDICATE MI_INSTR(0x01, 0) +#define MI_ARB_CHECK MI_INSTR(0x05, 0) +#define MI_RS_CONTROL MI_INSTR(0x06, 0) +#define MI_URB_ATOMIC_ALLOC MI_INSTR(0x09, 0) +#define MI_PREDICATE MI_INSTR(0x0C, 0) +#define MI_RS_CONTEXT MI_INSTR(0x0F, 0) +#define MI_TOPOLOGY_FILTER MI_INSTR(0x0D, 0) +#define MI_LOAD_SCAN_LINES_EXCL MI_INSTR(0x13, 0) +#define MI_URB_CLEAR MI_INSTR(0x19, 0) +#define MI_UPDATE_GTT MI_INSTR(0x23, 0) +#define MI_CLFLUSH MI_INSTR(0x27, 0) +#define MI_REPORT_PERF_COUNT MI_INSTR(0x28, 0) +#define MI_REPORT_PERF_COUNT_GGTT (1<<0) +#define MI_LOAD_REGISTER_MEM MI_INSTR(0x29, 0) +#define MI_LOAD_REGISTER_REG MI_INSTR(0x2A, 0) +#define MI_RS_STORE_DATA_IMM MI_INSTR(0x2B, 0) +#define MI_LOAD_URB_MEM MI_INSTR(0x2C, 0) +#define MI_STORE_URB_MEM MI_INSTR(0x2D, 0) +#define MI_CONDITIONAL_BATCH_BUFFER_END MI_INSTR(0x36, 0) + +#define PIPELINE_SELECT ((0x3<<29)|(0x1<<27)|(0x1<<24)|(0x4<<16)) +#define GFX_OP_3DSTATE_VF_STATISTICS ((0x3<<29)|(0x1<<27)|(0x0<<24)|(0xB<<16)) +#define MEDIA_VFE_STATE ((0x3<<29)|(0x2<<27)|(0x0<<24)|(0x0<<16)) +#define MEDIA_VFE_STATE_MMIO_ACCESS_MASK (0x18) +#define GPGPU_OBJECT ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x4<<16)) +#define GPGPU_WALKER ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x5<<16)) +#define GFX_OP_3DSTATE_DX9_CONSTANTF_VS \ + ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x39<<16)) +#define GFX_OP_3DSTATE_DX9_CONSTANTF_PS \ + ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x3A<<16)) +#define GFX_OP_3DSTATE_SO_DECL_LIST \ + ((0x3<<29)|(0x3<<27)|(0x1<<24)|(0x17<<16)) + +#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_VS \ + ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x43<<16)) +#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_GS \ + ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x44<<16)) +#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_HS \ + ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x45<<16)) +#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_DS \ + ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x46<<16)) +#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \ + ((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16)) + +#define MFX_WAIT ((0x3<<29)|(0x1<<27)|(0x0<<16)) + +#define COLOR_BLT ((0x2<<29)|(0x40<<22)) +#define SRC_COPY_BLT ((0x2<<29)|(0x43<<22)) + +#define GCI_CONTROL (dev_priv->info.display_mmio_offset + 0x650C) +#define VGA_FAST_MODE_DISABLE (1<<14) +#define PFI_CREDITS_15 (7<<28) +#define PFI_CREDITS_31 (8<<28) +#define PFI_CREDITS_63 (9<<28) +#define FORCE_CREDIT_RESEND (1<<27) + +/* + * Registers used only by the command parser + */ +#define BCS_SWCTRL 0x22200 + +#define HS_INVOCATION_COUNT 0x2300 +#define DS_INVOCATION_COUNT 0x2308 +#define IA_VERTICES_COUNT 0x2310 +#define IA_PRIMITIVES_COUNT 0x2318 +#define VS_INVOCATION_COUNT 0x2320 +#define GS_INVOCATION_COUNT 0x2328 +#define GS_PRIMITIVES_COUNT 0x2330 +#define CL_INVOCATION_COUNT 0x2338 +#define CL_PRIMITIVES_COUNT 0x2340 +#define PS_INVOCATION_COUNT 0x2348 +#define PS_DEPTH_COUNT 0x2350 + +/* There are the 4 64-bit counter registers, one for each stream output */ +#define GEN7_SO_NUM_PRIMS_WRITTEN(n) (0x5200 + (n) * 8) + +#define GEN7_SO_PRIM_STORAGE_NEEDED(n) (0x5240 + (n) * 8) + +#define GEN7_3DPRIM_END_OFFSET 0x2420 +#define GEN7_3DPRIM_START_VERTEX 0x2430 +#define GEN7_3DPRIM_VERTEX_COUNT 0x2434 +#define GEN7_3DPRIM_INSTANCE_COUNT 0x2438 +#define GEN7_3DPRIM_START_INSTANCE 0x243C +#define GEN7_3DPRIM_BASE_VERTEX 0x2440 + +#define OACONTROL 0x2360 + +#define _GEN7_PIPEA_DE_LOAD_SL 0x70068 +#define _GEN7_PIPEB_DE_LOAD_SL 0x71068 +#define GEN7_PIPE_DE_LOAD_SL(pipe) _PIPE(pipe, \ + _GEN7_PIPEA_DE_LOAD_SL, \ + _GEN7_PIPEB_DE_LOAD_SL) + +/* + * Reset registers + */ +#define DEBUG_RESET_I830 0x6070 +#define DEBUG_RESET_FULL (1<<7) +#define DEBUG_RESET_RENDER (1<<8) +#define DEBUG_RESET_DISPLAY (1<<9) + +/* + * IOSF sideband + */ +#define VLV_IOSF_DOORBELL_REQ (VLV_DISPLAY_BASE + 0x2100) +#define IOSF_DEVFN_SHIFT 24 +#define IOSF_OPCODE_SHIFT 16 +#define IOSF_PORT_SHIFT 8 +#define IOSF_BYTE_ENABLES_SHIFT 4 +#define IOSF_BAR_SHIFT 1 +#define IOSF_SB_BUSY (1<<0) +#define IOSF_PORT_BUNIT 0x3 +#define IOSF_PORT_PUNIT 0x4 +#define IOSF_PORT_NC 0x11 +#define IOSF_PORT_DPIO 0x12 +#define IOSF_PORT_DPIO_2 0x1a +#define IOSF_PORT_GPIO_NC 0x13 +#define CHV_IOSF_PORT_GPIO_N 0x13 +#define IOSF_PORT_GPIO_SC 0x48 +#define CHV_IOSF_PORT_GPIO_SE 0x48 +#define CHV_IOSF_PORT_GPIO_SW 0xB2 +#define IOSF_PORT_GPIO_SUS 0xA8 +#define CHV_IOSF_PORT_GPIO_E 0xA8 +#define MAX_GPIO_NUM_NC 26 +#define MAX_GPIO_NUM_SC 128 +#define MAX_GPIO_NUM 172 +#define CHV_MAX_GPIO_NUM_N 72 +#define CHV_MAX_GPIO_NUM_SE 99 +#define CHV_MAX_GPIO_NUM_SW 197 +#define CHV_MIN_GPIO_NUM_SE 73 +#define CHV_MIN_GPIO_NUM_SW 100 +#define CHV_MIN_GPIO_NUM_E 198 +#define IOSF_PORT_CCK 0x14 +#define IOSF_PORT_CCU 0xA9 +#define IOSF_PORT_GPS_CORE 0x48 +#define IOSF_PORT_FLISDSI 0x1B +#define VLV_IOSF_DATA (VLV_DISPLAY_BASE + 0x2104) +#define VLV_IOSF_ADDR (VLV_DISPLAY_BASE + 0x2108) + +#define VLV_GPIO_CFG 0x2000CC00 +#define VLV_GPIO_INPUT_DIS 0x04 + +#define CHV_PAD_FMLY_BASE 0x4400 +#define CHV_PAD_FMLY_SIZE 0x400 +#define CHV_PAD_CFG_0_1_REG_SIZE 0x8 +#define CHV_PAD_CFG_REG_SIZE 0x4 +#define CHV_VBT_MAX_PINS_PER_FMLY 15 + +#define CHV_GPIO_CFG_UNLOCK 0x00000000 +#define CHV_GPIO_CFG_HiZ 0x00008100 +#define CHV_GPIO_CFG1_INT_RISING 0x00000002 +#define CHV_GPIO_CFG0_EDGE_DETECT 0x04000000 +#define CHV_GPIO_CFG0_5K 0x00100000 +#define CHV_GPIO_CFG0_TE_PAD 0x00030000 +#define CHV_GPIO_CFG_TX_STATE_SHIFT 1 + +#define CHV_GPIO_NC_PNL1_BKLTCTL_CFG0 0x5418 +#define CHV_GPIO_NC_PNL1_BKLTCTL_CFG1 0x541c + +/* See configdb bunit SB addr map */ +#define BUNIT_REG_BISOC 0x11 + +#define PUNIT_REG_DSPFREQ 0x36 +#define DSPFREQSTAT_SHIFT_VLV 30 +#define DSPFREQSTAT_MASK_VLV (0x3 << DSPFREQSTAT_SHIFT_VLV) +#define DSPFREQGUAR_SHIFT_VLV 14 +#define DSPFREQGUAR_MASK_VLV (0x3 << DSPFREQGUAR_SHIFT_VLV) + +#define DSPFREQSTAT_SHIFT_CHV 24 +#define DSPFREQSTAT_MASK_CHV (0x1f << DSPFREQSTAT_SHIFT_CHV) +#define DSPFREQGUAR_SHIFT_CHV 8 +#define DSPFREQGUAR_MASK_CHV (0x1f << DSPFREQGUAR_SHIFT_CHV) + +#define DSPFREQSTAT_SHIFT(dev) \ + (IS_CHERRYVIEW(dev) ? DSPFREQSTAT_SHIFT_CHV : DSPFREQSTAT_SHIFT_VLV) +#define DSPFREQSTAT_MASK(dev) \ + (IS_CHERRYVIEW(dev) ? DSPFREQSTAT_MASK_CHV : DSPFREQSTAT_MASK_VLV) +#define DSPFREQGUAR_SHIFT(dev) \ + (IS_CHERRYVIEW(dev) ? DSPFREQGUAR_SHIFT_CHV : DSPFREQGUAR_SHIFT_VLV) +#define DSPFREQGUAR_MASK(dev) \ + (IS_CHERRYVIEW(dev) ? DSPFREQGUAR_MASK_CHV : DSPFREQGUAR_MASK_VLV) + +#define _DP_SSC(val, pipe) ((val) << (2 * (pipe))) +#define DP_SSC_MASK(pipe) _DP_SSC(0x3, (pipe)) +#define DP_SSC_PWR_ON(pipe) _DP_SSC(0x0, (pipe)) +#define DP_SSC_CLK_GATE(pipe) _DP_SSC(0x1, (pipe)) +#define DP_SSC_RESET(pipe) _DP_SSC(0x2, (pipe)) +#define DP_SSC_PWR_GATE(pipe) _DP_SSC(0x3, (pipe)) +#define _DP_SSS(val, pipe) ((val) << (2 * (pipe) + 16)) +#define DP_SSS_MASK(pipe) _DP_SSS(0x3, (pipe)) +#define DP_SSS_PWR_ON(pipe) _DP_SSS(0x0, (pipe)) +#define DP_SSS_CLK_GATE(pipe) _DP_SSS(0x1, (pipe)) +#define DP_SSS_RESET(pipe) _DP_SSS(0x2, (pipe)) +#define DP_SSS_PWR_GATE(pipe) _DP_SSS(0x3, (pipe)) + +/* See the PUNIT HAS v0.8 for the below bits */ +enum punit_power_well { + PUNIT_POWER_WELL_RENDER = 0, + PUNIT_POWER_WELL_MEDIA = 1, + PUNIT_POWER_WELL_DISP2D = 3, + PUNIT_POWER_WELL_DPIO_CMN_BC = 5, + PUNIT_POWER_WELL_DPIO_TX_B_LANES_01 = 6, + PUNIT_POWER_WELL_DPIO_TX_B_LANES_23 = 7, + PUNIT_POWER_WELL_DPIO_TX_C_LANES_01 = 8, + PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9, + PUNIT_POWER_WELL_DPIO_RX0 = 10, + PUNIT_POWER_WELL_DPIO_RX1 = 11, + PUNIT_POWER_WELL_DPIO_CMN_D = 12, + /* FIXME: guesswork below */ + PUNIT_POWER_WELL_DPIO_TX_D_LANES_01 = 13, + PUNIT_POWER_WELL_DPIO_TX_D_LANES_23 = 14, + PUNIT_POWER_WELL_DPIO_RX2 = 15, + + PUNIT_POWER_WELL_NUM, +}; + +#define PUNIT_REG_PWRGT_CTRL 0x60 +#define PUNIT_REG_PWRGT_STATUS 0x61 +#define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2)) +#define PUNIT_PWRGT_PWR_ON(power_well) (0 << ((power_well) * 2)) +#define PUNIT_PWRGT_CLK_GATE(power_well) (1 << ((power_well) * 2)) +#define PUNIT_PWRGT_RESET(power_well) (2 << ((power_well) * 2)) +#define PUNIT_PWRGT_PWR_GATE(power_well) (3 << ((power_well) * 2)) + +#define PUNIT_REG_GPU_LFM 0xd3 +#define PUNIT_REG_GPU_FREQ_REQ 0xd4 +#define PUNIT_REG_GPU_FREQ_STS 0xd8 +#define GENFREQSTATUS (1<<0) +#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc +#define PUNIT_REG_CZ_TIMESTAMP 0xce + +#define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */ +#define PUNIT_FUSE_BUS1 0xf5 /* bits 55:48 */ + +#define FB_GFX_FMAX_AT_VMAX_FUSE 0x136 +#define FB_GFX_FMAX_AT_VMAX_FUSE_MASK 0xff +#define FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT 24 +#define FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT 16 +#define FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT 8 + +#define FB_GFX_GUAR_FREQ_FUSE_MASK 0xff + +#define FB_GFX_FMIN_AT_VMIN_FUSE 0x137 +#define FB_GFX_FMIN_AT_VMIN_FUSE_MASK 0xff +#define FB_GFX_FMIN_AT_VMIN_FUSE_SHIFT 8 + +#define PUNIT_GPU_STATUS_REG 0xdb +#define PUNIT_GPU_STATUS_MAX_FREQ_SHIFT 16 +#define PUNIT_GPU_STATUS_MAX_FREQ_MASK 0xff +#define PUNIT_GPU_STATIS_GFX_MIN_FREQ_SHIFT 8 +#define PUNIT_GPU_STATUS_GFX_MIN_FREQ_MASK 0xff + +#define PUNIT_GPU_DUTYCYCLE_REG 0xdf +#define PUNIT_GPU_DUTYCYCLE_RPE_FREQ_SHIFT 8 +#define PUNIT_GPU_DUTYCYCLE_RPE_FREQ_MASK 0xff + +#define IOSF_NC_FB_GFX_FREQ_FUSE 0x1c +#define FB_GFX_MAX_FREQ_FUSE_SHIFT 3 +#define FB_GFX_MAX_FREQ_FUSE_MASK 0x000007f8 +#define FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT 11 +#define FB_GFX_FGUARANTEED_FREQ_FUSE_MASK 0x0007f800 +#define IOSF_NC_FB_GFX_FMAX_FUSE_HI 0x34 +#define FB_FMAX_VMIN_FREQ_HI_MASK 0x00000007 +#define IOSF_NC_FB_GFX_FMAX_FUSE_LO 0x30 +#define FB_FMAX_VMIN_FREQ_LO_SHIFT 27 +#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000 + +#define VLV_IOSFB_RPS_OVERRIDE 0x04 +#define VLV_OVERRIDE_RPS_REG 1 +#define VLV_ENABLE_TDP_SHARE (1 << 1) +#define VLV_BIAS_VAL (6 << 2) + +#define VLV_CZ_CLOCK_TO_MILLI_SEC 100000 +#define VLV_RP_UP_EI_THRESHOLD 90 +#define VLV_RP_DOWN_EI_THRESHOLD 70 +#define VLV_INT_COUNT_FOR_DOWN_EI 5 + +/* vlv2 north clock has */ +#define CCK_FUSE_REG 0x8 +#define CCK_FUSE_HPLL_FREQ_MASK 0x3 +#define CCK_REG_DSI_PLL_FUSE 0x44 +#define CCK_REG_DSI_PLL_CONTROL 0x48 +#define DSI_PLL_VCO_EN (1 << 31) +#define DSI_PLL_LDO_GATE (1 << 30) +#define DSI_PLL_P1_POST_DIV_SHIFT 17 +#define DSI_PLL_P1_POST_DIV_MASK (0x1ff << 17) +#define DSI_PLL_P2_MUX_DSI0_DIV2 (1 << 13) +#define DSI_PLL_P3_MUX_DSI1_DIV2 (1 << 12) +#define DSI_PLL_MUX_MASK (3 << 9) +#define DSI_PLL_MUX_DSI0_DSIPLL (0 << 10) +#define DSI_PLL_MUX_DSI0_CCK (1 << 10) +#define DSI_PLL_MUX_DSI1_DSIPLL (0 << 9) +#define DSI_PLL_MUX_DSI1_CCK (1 << 9) +#define DSI_PLL_CLK_GATE_MASK (0xf << 5) +#define DSI_PLL_CLK_GATE_DSI0_DSIPLL (1 << 8) +#define DSI_PLL_CLK_GATE_DSI1_DSIPLL (1 << 7) +#define DSI_PLL_CLK_GATE_DSI0_CCK (1 << 6) +#define DSI_PLL_CLK_GATE_DSI1_CCK (1 << 5) +#define DSI_PLL_LOCK (1 << 0) +#define CCK_REG_DSI_PLL_DIVIDER 0x4c +#define DSI_PLL_LFSR (1 << 31) +#define DSI_PLL_FRACTION_EN (1 << 30) +#define DSI_PLL_FRAC_COUNTER_SHIFT 27 +#define DSI_PLL_FRAC_COUNTER_MASK (7 << 27) +#define DSI_PLL_USYNC_CNT_SHIFT 18 +#define DSI_PLL_USYNC_CNT_MASK (0x1ff << 18) +#define DSI_PLL_N1_DIV_SHIFT 16 +#define DSI_PLL_N1_DIV_MASK (3 << 16) +#define DSI_PLL_M1_DIV_SHIFT 0 +#define DSI_PLL_M1_DIV_MASK (0x1ff << 0) +#define CCK_DISPLAY_CLOCK_CONTROL 0x6b + +/** + * DOC: DPIO + * + * VLV and CHV have slightly peculiar display PHYs for driving DP/HDMI + * ports. DPIO is the name given to such a display PHY. These PHYs + * don't follow the standard programming model using direct MMIO + * registers, and instead their registers must be accessed trough IOSF + * sideband. VLV has one such PHY for driving ports B and C, and CHV + * adds another PHY for driving port D. Each PHY responds to specific + * IOSF-SB port. + * + * Each display PHY is made up of one or two channels. Each channel + * houses a common lane part which contains the PLL and other common + * logic. CH0 common lane also contains the IOSF-SB logic for the + * Common Register Interface (CRI) ie. the DPIO registers. CRI clock + * must be running when any DPIO registers are accessed. + * + * In addition to having their own registers, the PHYs are also + * controlled through some dedicated signals from the display + * controller. These include PLL reference clock enable, PLL enable, + * and CRI clock selection, for example. + * + * Eeach channel also has two splines (also called data lanes), and + * each spline is made up of one Physical Access Coding Sub-Layer + * (PCS) block and two TX lanes. So each channel has two PCS blocks + * and four TX lanes. The TX lanes are used as DP lanes or TMDS + * data/clock pairs depending on the output type. + * + * Additionally the PHY also contains an AUX lane with AUX blocks + * for each channel. This is used for DP AUX communication, but + * this fact isn't really relevant for the driver since AUX is + * controlled from the display controller side. No DPIO registers + * need to be accessed during AUX communication, + * + * Generally the common lane corresponds to the pipe and + * the spline (PCS/TX) correponds to the port. + * + * For dual channel PHY (VLV/CHV): + * + * pipe A == CMN/PLL/REF CH0 + * + * pipe B == CMN/PLL/REF CH1 + * + * port B == PCS/TX CH0 + * + * port C == PCS/TX CH1 + * + * This is especially important when we cross the streams + * ie. drive port B with pipe B, or port C with pipe A. + * + * For single channel PHY (CHV): + * + * pipe C == CMN/PLL/REF CH0 + * + * port D == PCS/TX CH0 + * + * Note: digital port B is DDI0, digital port C is DDI1, + * digital port D is DDI2 + */ +/* + * Dual channel PHY (VLV/CHV) + * --------------------------------- + * | CH0 | CH1 | + * | CMN/PLL/REF | CMN/PLL/REF | + * |---------------|---------------| Display PHY + * | PCS01 | PCS23 | PCS01 | PCS23 | + * |-------|-------|-------|-------| + * |TX0|TX1|TX2|TX3|TX0|TX1|TX2|TX3| + * --------------------------------- + * | DDI0 | DDI1 | DP/HDMI ports + * --------------------------------- + * + * Single channel PHY (CHV) + * ----------------- + * | CH0 | + * | CMN/PLL/REF | + * |---------------| Display PHY + * | PCS01 | PCS23 | + * |-------|-------| + * |TX0|TX1|TX2|TX3| + * ----------------- + * | DDI2 | DP/HDMI port + * ----------------- + */ +#define DPIO_DEVFN 0 + +#define DPIO_CTL (VLV_DISPLAY_BASE + 0x2110) +#define DPIO_MODSEL1 (1<<3) /* if ref clk b == 27 */ +#define DPIO_MODSEL0 (1<<2) /* if ref clk a == 27 */ +#define DPIO_SFR_BYPASS (1<<1) +#define DPIO_CMNRST (1<<0) + +#define DPIO_PHY(pipe) ((pipe) >> 1) +#define DPIO_PHY_IOSF_PORT(phy) (dev_priv->dpio_phy_iosf_port[phy]) + +/* + * Per pipe/PLL DPIO regs + */ +#define _VLV_PLL_DW3_CH0 0x800c +#define DPIO_POST_DIV_SHIFT (28) /* 3 bits */ +#define DPIO_POST_DIV_DAC 0 +#define DPIO_POST_DIV_HDMIDP 1 /* DAC 225-400M rate */ +#define DPIO_POST_DIV_LVDS1 2 +#define DPIO_POST_DIV_LVDS2 3 +#define DPIO_K_SHIFT (24) /* 4 bits */ +#define DPIO_P1_SHIFT (21) /* 3 bits */ +#define DPIO_P2_SHIFT (16) /* 5 bits */ +#define DPIO_N_SHIFT (12) /* 4 bits */ +#define DPIO_ENABLE_CALIBRATION (1<<11) +#define DPIO_M1DIV_SHIFT (8) /* 3 bits */ +#define DPIO_M2DIV_MASK 0xff +#define _VLV_PLL_DW3_CH1 0x802c +#define VLV_PLL_DW3(ch) _PIPE(ch, _VLV_PLL_DW3_CH0, _VLV_PLL_DW3_CH1) + +#define _VLV_PLL_DW5_CH0 0x8014 +#define DPIO_REFSEL_OVERRIDE 27 +#define DPIO_PLL_MODESEL_SHIFT 24 /* 3 bits */ +#define DPIO_BIAS_CURRENT_CTL_SHIFT 21 /* 3 bits, always 0x7 */ +#define DPIO_PLL_REFCLK_SEL_SHIFT 16 /* 2 bits */ +#define DPIO_PLL_REFCLK_SEL_MASK 3 +#define DPIO_DRIVER_CTL_SHIFT 12 /* always set to 0x8 */ +#define DPIO_CLK_BIAS_CTL_SHIFT 8 /* always set to 0x5 */ +#define _VLV_PLL_DW5_CH1 0x8034 +#define VLV_PLL_DW5(ch) _PIPE(ch, _VLV_PLL_DW5_CH0, _VLV_PLL_DW5_CH1) + +#define _VLV_PLL_DW7_CH0 0x801c +#define _VLV_PLL_DW7_CH1 0x803c +#define VLV_PLL_DW7(ch) _PIPE(ch, _VLV_PLL_DW7_CH0, _VLV_PLL_DW7_CH1) + +#define _VLV_PLL_DW8_CH0 0x8040 +#define _VLV_PLL_DW8_CH1 0x8060 +#define VLV_PLL_DW8(ch) _PIPE(ch, _VLV_PLL_DW8_CH0, _VLV_PLL_DW8_CH1) + +#define VLV_PLL_DW9_BCAST 0xc044 +#define _VLV_PLL_DW9_CH0 0x8044 +#define _VLV_PLL_DW9_CH1 0x8064 +#define VLV_PLL_DW9(ch) _PIPE(ch, _VLV_PLL_DW9_CH0, _VLV_PLL_DW9_CH1) + +#define _VLV_PLL_DW10_CH0 0x8048 +#define _VLV_PLL_DW10_CH1 0x8068 +#define VLV_PLL_DW10(ch) _PIPE(ch, _VLV_PLL_DW10_CH0, _VLV_PLL_DW10_CH1) + +#define _VLV_PLL_DW11_CH0 0x804c +#define _VLV_PLL_DW11_CH1 0x806c +#define VLV_PLL_DW11(ch) _PIPE(ch, _VLV_PLL_DW11_CH0, _VLV_PLL_DW11_CH1) + +/* Spec for ref block start counts at DW10 */ +#define VLV_REF_DW13 0x80ac + +#define VLV_CMN_DW0 0x8100 + +/* + * Per DDI channel DPIO regs + */ + +#define _VLV_PCS_DW0_CH0 0x8200 +#define _VLV_PCS_DW0_CH1 0x8400 +#define DPIO_PCS_TX_LANE2_RESET (1<<16) +#define DPIO_PCS_TX_LANE1_RESET (1<<7) +#define DPIO_LEFT_TXFIFO_RST_MASTER2 (1<<4) +#define DPIO_RIGHT_TXFIFO_RST_MASTER2 (1<<3) +#define VLV_PCS_DW0(ch) _PORT(ch, _VLV_PCS_DW0_CH0, _VLV_PCS_DW0_CH1) + +#define _VLV_PCS01_DW0_CH0 0x200 +#define _VLV_PCS23_DW0_CH0 0x400 +#define _VLV_PCS01_DW0_CH1 0x2600 +#define _VLV_PCS23_DW0_CH1 0x2800 +#define VLV_PCS01_DW0(ch) _PORT(ch, _VLV_PCS01_DW0_CH0, _VLV_PCS01_DW0_CH1) +#define VLV_PCS23_DW0(ch) _PORT(ch, _VLV_PCS23_DW0_CH0, _VLV_PCS23_DW0_CH1) + +#define _VLV_PCS_DW1_CH0 0x8204 +#define _VLV_PCS_DW1_CH1 0x8404 +#define CHV_PCS_REQ_SOFTRESET_EN (1<<23) +#define DPIO_PCS_CLK_CRI_RXEB_EIOS_EN (1<<22) +#define DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN (1<<21) +#define DPIO_PCS_CLK_DATAWIDTH_SHIFT (6) +#define DPIO_PCS_CLK_SOFT_RESET (1<<5) +#define VLV_PCS_DW1(ch) _PORT(ch, _VLV_PCS_DW1_CH0, _VLV_PCS_DW1_CH1) + +#define _VLV_PCS01_DW1_CH0 0x204 +#define _VLV_PCS23_DW1_CH0 0x404 +#define _VLV_PCS01_DW1_CH1 0x2604 +#define _VLV_PCS23_DW1_CH1 0x2804 +#define VLV_PCS01_DW1(ch) _PORT(ch, _VLV_PCS01_DW1_CH0, _VLV_PCS01_DW1_CH1) +#define VLV_PCS23_DW1(ch) _PORT(ch, _VLV_PCS23_DW1_CH0, _VLV_PCS23_DW1_CH1) + +#define _VLV_PCS_DW8_CH0 0x8220 +#define _VLV_PCS_DW8_CH1 0x8420 +#define CHV_PCS_USEDCLKCHANNEL_OVRRIDE (1 << 20) +#define CHV_PCS_USEDCLKCHANNEL (1 << 21) +#define VLV_PCS_DW8(ch) _PORT(ch, _VLV_PCS_DW8_CH0, _VLV_PCS_DW8_CH1) + +#define _VLV_PCS01_DW8_CH0 0x0220 +#define _VLV_PCS23_DW8_CH0 0x0420 +#define _VLV_PCS01_DW8_CH1 0x2620 +#define _VLV_PCS23_DW8_CH1 0x2820 +#define VLV_PCS01_DW8(port) _PORT(port, _VLV_PCS01_DW8_CH0, _VLV_PCS01_DW8_CH1) +#define VLV_PCS23_DW8(port) _PORT(port, _VLV_PCS23_DW8_CH0, _VLV_PCS23_DW8_CH1) + +#define _VLV_PCS_DW9_CH0 0x8224 +#define _VLV_PCS_DW9_CH1 0x8424 +#define DPIO_PCS_TX2MARGIN_MASK (0x7<<13) +#define DPIO_PCS_TX2MARGIN_000 (0<<13) +#define DPIO_PCS_TX2MARGIN_101 (1<<13) +#define DPIO_PCS_TX1MARGIN_MASK (0x7<<10) +#define DPIO_PCS_TX1MARGIN_000 (0<<10) +#define DPIO_PCS_TX1MARGIN_101 (1<<10) +#define VLV_PCS_DW9(ch) _PORT(ch, _VLV_PCS_DW9_CH0, _VLV_PCS_DW9_CH1) + +#define _VLV_PCS01_DW9_CH0 0x224 +#define _VLV_PCS23_DW9_CH0 0x424 +#define _VLV_PCS01_DW9_CH1 0x2624 +#define _VLV_PCS23_DW9_CH1 0x2824 +#define VLV_PCS01_DW9(ch) _PORT(ch, _VLV_PCS01_DW9_CH0, _VLV_PCS01_DW9_CH1) +#define VLV_PCS23_DW9(ch) _PORT(ch, _VLV_PCS23_DW9_CH0, _VLV_PCS23_DW9_CH1) + +#define _CHV_PCS_DW10_CH0 0x8228 +#define _CHV_PCS_DW10_CH1 0x8428 +#define DPIO_PCS_SWING_CALC_TX0_TX2 (1<<30) +#define DPIO_PCS_SWING_CALC_TX1_TX3 (1<<31) +#define DPIO_PCS_TX2DEEMP_MASK (0xf<<24) +#define DPIO_PCS_TX2DEEMP_9P5 (0<<24) +#define DPIO_PCS_TX2DEEMP_6P0 (2<<24) +#define DPIO_PCS_TX1DEEMP_MASK (0xf<<16) +#define DPIO_PCS_TX1DEEMP_9P5 (0<<16) +#define DPIO_PCS_TX1DEEMP_6P0 (2<<16) +#define CHV_PCS_DW10(ch) _PORT(ch, _CHV_PCS_DW10_CH0, _CHV_PCS_DW10_CH1) + +#define _VLV_PCS01_DW10_CH0 0x0228 +#define _VLV_PCS23_DW10_CH0 0x0428 +#define _VLV_PCS01_DW10_CH1 0x2628 +#define _VLV_PCS23_DW10_CH1 0x2828 +#define VLV_PCS01_DW10(port) _PORT(port, _VLV_PCS01_DW10_CH0, _VLV_PCS01_DW10_CH1) +#define VLV_PCS23_DW10(port) _PORT(port, _VLV_PCS23_DW10_CH0, _VLV_PCS23_DW10_CH1) + +#define _VLV_PCS_DW11_CH0 0x822c +#define _VLV_PCS_DW11_CH1 0x842c +#define DPIO_LANEDESKEW_STRAP_OVRD (1<<3) +#define DPIO_LEFT_TXFIFO_RST_MASTER (1<<1) +#define DPIO_RIGHT_TXFIFO_RST_MASTER (1<<0) +#define VLV_PCS_DW11(ch) _PORT(ch, _VLV_PCS_DW11_CH0, _VLV_PCS_DW11_CH1) + +#define _VLV_PCS01_DW11_CH0 0x022c +#define _VLV_PCS23_DW11_CH0 0x042c +#define _VLV_PCS01_DW11_CH1 0x262c +#define _VLV_PCS23_DW11_CH1 0x282c +#define VLV_PCS01_DW11(ch) _PORT(ch, _VLV_PCS01_DW0_CH0, _VLV_PCS01_DW0_CH1) +#define VLV_PCS23_DW11(ch) _PORT(ch, _VLV_PCS23_DW0_CH0, _VLV_PCS23_DW0_CH1) + +#define _VLV_PCS_DW12_CH0 0x8230 +#define _VLV_PCS_DW12_CH1 0x8430 +#define VLV_PCS_DW12(ch) _PORT(ch, _VLV_PCS_DW12_CH0, _VLV_PCS_DW12_CH1) + +#define _VLV_PCS_DW14_CH0 0x8238 +#define _VLV_PCS_DW14_CH1 0x8438 +#define VLV_PCS_DW14(ch) _PORT(ch, _VLV_PCS_DW14_CH0, _VLV_PCS_DW14_CH1) + +#define _VLV_PCS_DW23_CH0 0x825c +#define _VLV_PCS_DW23_CH1 0x845c +#define VLV_PCS_DW23(ch) _PORT(ch, _VLV_PCS_DW23_CH0, _VLV_PCS_DW23_CH1) + +#define _VLV_TX_DW2_CH0 0x8288 +#define _VLV_TX_DW2_CH1 0x8488 +#define DPIO_SWING_MARGIN000_SHIFT 16 +#define DPIO_SWING_MARGIN000_MASK (0xff << DPIO_SWING_MARGIN000_SHIFT) +#define DPIO_UNIQ_TRANS_SCALE_SHIFT 8 +#define VLV_TX_DW2(ch) _PORT(ch, _VLV_TX_DW2_CH0, _VLV_TX_DW2_CH1) + +#define _VLV_TX_DW3_CH0 0x828c +#define _VLV_TX_DW3_CH1 0x848c +/* The following bit for CHV phy */ +#define DPIO_TX_UNIQ_TRANS_SCALE_EN (1<<27) +#define DPIO_TX_UNIQ_TRANS_SCALE_CH1 (1 << 3) +#define DPIO_TX_UNIQ_TRANS_SCALE_CH0 (1 << 2) +#define DPIO_SWING_MARGIN101_SHIFT 16 +#define DPIO_SWING_MARGIN101_MASK (0xff << DPIO_SWING_MARGIN101_SHIFT) +#define VLV_TX_DW3(ch) _PORT(ch, _VLV_TX_DW3_CH0, _VLV_TX_DW3_CH1) + +#define _VLV_TX_DW4_CH0 0x8290 +#define _VLV_TX_DW4_CH1 0x8490 +#define DPIO_SWING_DEEMPH9P5_SHIFT 24 +#define DPIO_SWING_DEEMPH9P5_MASK (0xff << DPIO_SWING_DEEMPH9P5_SHIFT) +#define DPIO_SWING_DEEMPH6P0_SHIFT 16 +#define DPIO_SWING_DEEMPH6P0_MASK (0xff << DPIO_SWING_DEEMPH6P0_SHIFT) +#define VLV_TX_DW4(ch) _PORT(ch, _VLV_TX_DW4_CH0, _VLV_TX_DW4_CH1) + +#define _VLV_TX3_DW4_CH0 0x690 +#define _VLV_TX3_DW4_CH1 0x2a90 +#define VLV_TX3_DW4(ch) _PORT(ch, _VLV_TX3_DW4_CH0, _VLV_TX3_DW4_CH1) + +#define _VLV_TX_DW5_CH0 0x8294 +#define _VLV_TX_DW5_CH1 0x8494 +#define DPIO_TX_OCALINIT_EN (1<<31) +#define VLV_TX_DW5(ch) _PORT(ch, _VLV_TX_DW5_CH0, _VLV_TX_DW5_CH1) + +#define _VLV_TX_DW11_CH0 0x82ac +#define _VLV_TX_DW11_CH1 0x84ac +#define VLV_TX_DW11(ch) _PORT(ch, _VLV_TX_DW11_CH0, _VLV_TX_DW11_CH1) + +#define _VLV_TX_DW14_CH0 0x82b8 +#define _VLV_TX_DW14_CH1 0x84b8 +#define VLV_TX_DW14(ch) _PORT(ch, _VLV_TX_DW14_CH0, _VLV_TX_DW14_CH1) + +/* CHV dpPhy registers */ +#define _CHV_PLL_DW0_CH0 0x8000 +#define _CHV_PLL_DW0_CH1 0x8180 +#define CHV_PLL_DW0(ch) _PIPE(ch, _CHV_PLL_DW0_CH0, _CHV_PLL_DW0_CH1) + +#define _CHV_PLL_DW1_CH0 0x8004 +#define _CHV_PLL_DW1_CH1 0x8184 +#define DPIO_CHV_N_DIV_SHIFT 8 +#define DPIO_CHV_M1_DIV_BY_2 (0 << 0) +#define CHV_PLL_DW1(ch) _PIPE(ch, _CHV_PLL_DW1_CH0, _CHV_PLL_DW1_CH1) + +#define _CHV_PLL_DW2_CH0 0x8008 +#define _CHV_PLL_DW2_CH1 0x8188 +#define CHV_PLL_DW2(ch) _PIPE(ch, _CHV_PLL_DW2_CH0, _CHV_PLL_DW2_CH1) + +#define _CHV_PLL_DW3_CH0 0x800c +#define _CHV_PLL_DW3_CH1 0x818c +#define DPIO_CHV_FRAC_DIV_EN (1 << 16) +#define DPIO_CHV_FIRST_MOD (0 << 8) +#define DPIO_CHV_SECOND_MOD (1 << 8) +#define DPIO_CHV_FEEDFWD_GAIN_SHIFT 0 +#define CHV_PLL_DW3(ch) _PIPE(ch, _CHV_PLL_DW3_CH0, _CHV_PLL_DW3_CH1) + +#define _CHV_PLL_DW6_CH0 0x8018 +#define _CHV_PLL_DW6_CH1 0x8198 +#define DPIO_CHV_GAIN_CTRL_SHIFT 16 +#define DPIO_CHV_INT_COEFF_SHIFT 8 +#define DPIO_CHV_PROP_COEFF_SHIFT 0 +#define CHV_PLL_DW6(ch) _PIPE(ch, _CHV_PLL_DW6_CH0, _CHV_PLL_DW6_CH1) + +#define _CHV_PLL_DW7_CH0 0x801c +#define _CHV_PLL_DW7_CH1 0x803c +#define CHV_PLL_DW7(ch) _PIPE(ch, _CHV_PLL_DW7_CH0, _CHV_PLL_DW7_CH1) + +#define _CHV_PLL_DW8_CH0 0x8020 +#define _CHV_PLL_DW8_CH1 0x81A0 +#define CHV_PLL_DW8(ch) _PIPE(ch, _CHV_PLL_DW8_CH0, _CHV_PLL_DW8_CH1) + +#define _CHV_PLL_DW9_CH0 0x8024 +#define _CHV_PLL_DW9_CH1 0x81A4 +#define DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT 1 /* 3 bits */ +#define DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE 1 /* 1: coarse & 0 : fine */ +#define CHV_PLL_DW9(ch) _PIPE(ch, _CHV_PLL_DW9_CH0, _CHV_PLL_DW9_CH1) + +#define _CHV_PLL_DW10_CH0 0x8040 +#define _CHV_PLL_DW10_CH1 0x8060 +#define CHV_PLL_DW10(ch) _PIPE(ch, _CHV_PLL_DW10_CH0, _CHV_PLL_DW10_CH1) + +#define _CHV_PLL_DW11_BCAST 0xC044 +#define _CHV_PLL_DW11_CH0 0x8044 +#define _CHV_PLL_DW11_CH1 0x8064 +#define CHV_PLL_DW11(ch) _PIPE(ch, _CHV_PLL_DW11_CH0, _CHV_PLL_DW11_CH1) + +#define _CHV_PLL_DW12_CH0 0x8048 +#define _CHV_PLL_DW12_CH1 0x8068 +#define CHV_PLL_DW12(ch) _PIPE(ch, _CHV_PLL_DW12_CH0, _CHV_PLL_DW12_CH1) + +#define _CHV_PLL_DW13_CH0 0x804C +#define _CHV_PLL_DW13_CH1 0x806C +#define CHV_PLL_DW13(ch) _PIPE(ch, _CHV_PLL_DW13_CH0, _CHV_PLL_DW13_CH1) + +#define _CHV_CMN_DW5_CH0 0x8114 +#define CHV_BUFRIGHTENA1_DISABLE (0 << 20) +#define CHV_BUFRIGHTENA1_NORMAL (1 << 20) +#define CHV_BUFRIGHTENA1_FORCE (3 << 20) +#define CHV_BUFRIGHTENA1_MASK (3 << 20) +#define CHV_BUFLEFTENA1_DISABLE (0 << 22) +#define CHV_BUFLEFTENA1_NORMAL (1 << 22) +#define CHV_BUFLEFTENA1_FORCE (3 << 22) +#define CHV_BUFLEFTENA1_MASK (3 << 22) + +#define _CHV_CMN_DW13_CH0 0x8134 +#define _CHV_CMN_DW0_CH1 0x8080 +#define DPIO_CHV_S1_DIV_SHIFT 21 +#define DPIO_CHV_P1_DIV_SHIFT 13 /* 3 bits */ +#define DPIO_CHV_P2_DIV_SHIFT 8 /* 5 bits */ +#define DPIO_CHV_K_DIV_SHIFT 4 +#define DPIO_PLL_FREQLOCK (1 << 1) +#define DPIO_PLL_LOCK (1 << 0) +#define CHV_CMN_DW13(ch) _PIPE(ch, _CHV_CMN_DW13_CH0, _CHV_CMN_DW0_CH1) + +#define _CHV_CMN_DW14_CH0 0x8138 +#define _CHV_CMN_DW1_CH1 0x8084 +#define DPIO_AFC_RECAL (1 << 14) +#define DPIO_DCLKP_EN (1 << 13) +#define CHV_BUFLEFTENA2_DISABLE (0 << 17) /* CL2 DW1 only */ +#define CHV_BUFLEFTENA2_NORMAL (1 << 17) /* CL2 DW1 only */ +#define CHV_BUFLEFTENA2_FORCE (3 << 17) /* CL2 DW1 only */ +#define CHV_BUFLEFTENA2_MASK (3 << 17) /* CL2 DW1 only */ +#define CHV_BUFRIGHTENA2_DISABLE (0 << 19) /* CL2 DW1 only */ +#define CHV_BUFRIGHTENA2_NORMAL (1 << 19) /* CL2 DW1 only */ +#define CHV_BUFRIGHTENA2_FORCE (3 << 19) /* CL2 DW1 only */ +#define CHV_BUFRIGHTENA2_MASK (3 << 19) /* CL2 DW1 only */ +#define CHV_CMN_DW14(ch) _PIPE(ch, _CHV_CMN_DW14_CH0, _CHV_CMN_DW1_CH1) + +#define _CHV_CMN_DW19_CH0 0x814c +#define _CHV_CMN_DW6_CH1 0x8098 +#define CHV_CMN_USEDCLKCHANNEL (1 << 13) +#define CHV_CMN_DW19(ch) _PIPE(ch, _CHV_CMN_DW19_CH0, _CHV_CMN_DW6_CH1) + +#define CHV_CMN_DW30 0x8178 +#define DPIO_LRC_BYPASS (1 << 3) + +#define _TXLANE(ch, lane, offset) ((ch ? 0x2400 : 0) + \ + (lane) * 0x200 + (offset)) + +#define CHV_TX_DW0(ch, lane) _TXLANE(ch, lane, 0x80) +#define CHV_TX_DW1(ch, lane) _TXLANE(ch, lane, 0x84) +#define CHV_TX_DW2(ch, lane) _TXLANE(ch, lane, 0x88) +#define CHV_TX_DW3(ch, lane) _TXLANE(ch, lane, 0x8c) +#define CHV_TX_DW4(ch, lane) _TXLANE(ch, lane, 0x90) +#define CHV_TX_DW5(ch, lane) _TXLANE(ch, lane, 0x94) +#define CHV_TX_DW6(ch, lane) _TXLANE(ch, lane, 0x98) +#define CHV_TX_DW7(ch, lane) _TXLANE(ch, lane, 0x9c) +#define CHV_TX_DW8(ch, lane) _TXLANE(ch, lane, 0xa0) +#define CHV_TX_DW9(ch, lane) _TXLANE(ch, lane, 0xa4) +#define CHV_TX_DW10(ch, lane) _TXLANE(ch, lane, 0xa8) +#define CHV_TX_DW11(ch, lane) _TXLANE(ch, lane, 0xac) +#define DPIO_FRC_LATENCY_SHFIT 8 +#define CHV_TX_DW14(ch, lane) _TXLANE(ch, lane, 0xb8) +#define DPIO_UPAR_SHIFT 30 +/* + * Fence registers + */ +#define FENCE_REG_830_0 0x2000 +#define FENCE_REG_945_8 0x3000 +#define I830_FENCE_START_MASK 0x07f80000 +#define I830_FENCE_TILING_Y_SHIFT 12 +#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) +#define I830_FENCE_PITCH_SHIFT 4 +#define I830_FENCE_REG_VALID (1<<0) +#define I915_FENCE_MAX_PITCH_VAL 4 +#define I830_FENCE_MAX_PITCH_VAL 6 +#define I830_FENCE_MAX_SIZE_VAL (1<<8) + +#define I915_FENCE_START_MASK 0x0ff00000 +#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) + +#define FENCE_REG_965_0 0x03000 +#define I965_FENCE_PITCH_SHIFT 2 +#define I965_FENCE_TILING_Y_SHIFT 1 +#define I965_FENCE_REG_VALID (1<<0) +#define I965_FENCE_MAX_PITCH_VAL 0x0400 + +#define FENCE_REG_SANDYBRIDGE_0 0x100000 +#define SANDYBRIDGE_FENCE_PITCH_SHIFT 32 +#define GEN7_FENCE_MAX_PITCH_VAL 0x0800 + + +/* control register for cpu gtt access */ +#define TILECTL 0x101000 +#define TILECTL_SWZCTL (1 << 0) +#define TILECTL_TLB_PREFETCH_DIS (1 << 2) +#define TILECTL_BACKSNOOP_DIS (1 << 3) + +/* + * Instruction and interrupt control regs + */ +#define PGTBL_ER 0x02024 +#define RENDER_RING_BASE 0x02000 +#define BSD_RING_BASE 0x04000 +#define GEN6_BSD_RING_BASE 0x12000 +#define GEN8_BSD2_RING_BASE 0x1c000 +#define VEBOX_RING_BASE 0x1a000 +#define BLT_RING_BASE 0x22000 +#define RING_TAIL(base) ((base)+0x30) +#define RING_HEAD(base) ((base)+0x34) +#define RING_START(base) ((base)+0x38) +#define RING_CTL(base) ((base)+0x3c) +#define RING_MI_MODE(base) ((base)+0x9c) +#define RING_MODE_STOP (1 << 8) +#define RING_MODE_IDLE (1 << 9) +#define RING_UHPTR(base) ((base)+0x134) +#define RING_CNTR(base) ((base)+0x178) +#define RING_THRESH(base) ((base)+0x17C) +#define RING_SYNC_0(base) ((base)+0x40) +#define RING_SYNC_1(base) ((base)+0x44) +#define RING_SYNC_2(base) ((base)+0x48) +#define GEN6_RVSYNC (RING_SYNC_0(RENDER_RING_BASE)) +#define GEN6_RBSYNC (RING_SYNC_1(RENDER_RING_BASE)) +#define GEN6_RVESYNC (RING_SYNC_2(RENDER_RING_BASE)) +#define GEN6_VBSYNC (RING_SYNC_0(GEN6_BSD_RING_BASE)) +#define GEN6_VRSYNC (RING_SYNC_1(GEN6_BSD_RING_BASE)) +#define GEN6_VVESYNC (RING_SYNC_2(GEN6_BSD_RING_BASE)) +#define GEN6_BRSYNC (RING_SYNC_0(BLT_RING_BASE)) +#define GEN6_BVSYNC (RING_SYNC_1(BLT_RING_BASE)) +#define GEN6_BVESYNC (RING_SYNC_2(BLT_RING_BASE)) +#define GEN6_VEBSYNC (RING_SYNC_0(VEBOX_RING_BASE)) +#define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE)) +#define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE)) +#define GEN6_NOSYNC 0 + +/* + * Premption-related registers + */ +#define RING_UHPTR(base) ((base)+0x134) +#define UHPTR_GFX_ADDR_ALIGN (0x7) +#define UHPTR_VALID (0x1) +#define RING_PREEMPT_ADDR 0x0214c +#define PREEMPT_BATCH_LEVEL_MASK (0x3) +#define BB_PREEMPT_ADDR 0x02148 +#define SBB_PREEMPT_ADDR 0x0213c +#define RS_PREEMPT_STATUS 0x0215c + +#define RING_MAX_IDLE(base) ((base)+0x54) +#define RING_HWS_PGA(base) ((base)+0x80) +#define RING_HWS_PGA_GEN6(base) ((base)+0x2080) + +#define GEN7_WR_WATERMARK 0x4028 +#define GEN7_GFX_PRIO_CTRL 0x402C +#define ARB_MODE 0x4030 +#define ARB_MODE_SWIZZLE_SNB (1<<4) +#define ARB_MODE_SWIZZLE_IVB (1<<5) +#define GEN7_GFX_PEND_TLB0 0x4034 +#define GEN7_GFX_PEND_TLB1 0x4038 +/* L3, CVS, ZTLB, RCC, CASC LRA min, max values */ +#define GEN7_LRA_LIMITS_BASE 0x403C +#define GEN7_LRA_LIMITS_REG_NUM 13 +#define GEN7_MEDIA_MAX_REQ_COUNT 0x4070 +#define GEN7_GFX_MAX_REQ_COUNT 0x4074 + +#define GAMTARBMODE 0x04a08 +#define ARB_MODE_BWGTLB_DISABLE (1<<9) +#define ARB_MODE_SWIZZLE_BDW (1<<1) +#define RENDER_HWS_PGA_GEN7 (0x04080) +#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) +#define RING_FAULT_GTTSEL_MASK (1<<11) +#define RING_FAULT_SRCID(x) ((x >> 3) & 0xff) +#define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3) +#define RING_FAULT_VALID (1<<0) +#define DONE_REG 0x40b0 +#define GEN8_PRIVATE_PAT 0x40e0 +#define BSD_HWS_PGA_GEN7 (0x04180) +#define BLT_HWS_PGA_GEN7 (0x04280) +#define VEBOX_HWS_PGA_GEN7 (0x04380) +#define RING_ACTHD(base) ((base)+0x74) +#define RING_ACTHD_UDW(base) ((base)+0x5c) +#define RING_NOPID(base) ((base)+0x94) +#define RING_IMR(base) ((base)+0xa8) +#define RING_HWSTAM(base) ((base)+0x98) +#define RING_TIMESTAMP_LO(base) ((base)+0x358) +#define RING_TIMESTAMP_HI(base) ((base)+0x35c) +#define TAIL_ADDR 0x001FFFF8 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 +#define RING_WAIT_I8XX (1<<0) /* gen2, PRBx_HEAD */ +#define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ +#define RING_WAIT_SEMAPHORE (1<<10) /* gen6+ */ +#define RS_CHICKEN(base) ((base)+0xdc) +#define WAIT_FOR_RC6_EXIT(base) ((base)+0xe4) +#define FF_SLICE_CS_CHICKEN2(base) ((base)+0xcc) + +#define GEN7_TLB_RD_ADDR 0x4700 + +#if 0 +#define PRB0_TAIL 0x02030 +#define PRB0_HEAD 0x02034 +#define PRB0_START 0x02038 +#define PRB0_CTL 0x0203c +#define PRB1_TAIL 0x02040 /* 915+ only */ +#define PRB1_HEAD 0x02044 /* 915+ only */ +#define PRB1_START 0x02048 /* 915+ only */ +#define PRB1_CTL 0x0204c /* 915+ only */ +#endif +#define IPEIR_I965 0x02064 +#define IPEHR_I965 0x02068 +#define INSTDONE_I965 0x0206c +#define GEN7_INSTDONE_1 0x0206c +#define GEN7_SC_INSTDONE 0x07100 +#define GEN7_SAMPLER_INSTDONE 0x0e160 +#define GEN7_ROW_INSTDONE 0x0e164 +#define I915_NUM_INSTDONE_REG 4 +#define RING_IPEIR(base) ((base)+0x64) +#define RING_IPEHR(base) ((base)+0x68) +#define RING_INSTDONE(base) ((base)+0x6c) +#define RING_INSTPS(base) ((base)+0x70) +#define RING_DMA_FADD(base) ((base)+0x78) +#define RING_DMA_FADD_UDW(base) ((base)+0x60) /* gen8+ */ +#define RING_INSTPM(base) ((base)+0xc0) +#define RING_MI_MODE(base) ((base)+0x9c) +#define INSTPS 0x02070 /* 965+ only */ +#define INSTDONE1 0x0207c /* 965+ only */ +#define ACTHD_I965 0x02074 +#define HWS_PGA 0x02080 +#define HWS_ADDRESS_MASK 0xfffff000 +#define HWS_START_ADDRESS_SHIFT 4 +#define PWRCTXA 0x2088 /* 965GM+ only */ +#define PWRCTX_EN (1<<0) +#define IPEIR 0x02088 +#define IPEHR 0x0208c +#define INSTDONE 0x02090 +#define NOPID 0x02094 +#define HWSTAM 0x02098 +#define DMA_FADD_I8XX 0x020d0 +#define RING_BBSTATE(base) ((base)+0x110) +#define RING_BBADDR(base) ((base)+0x140) +#define RING_BBADDR_UDW(base) ((base)+0x168) /* gen8+ */ + +#define ERROR_GEN6 0x040a0 +#define GEN7_ERR_INT 0x44040 +#define ERR_INT_POISON (1<<31) +#define ERR_INT_MMIO_UNCLAIMED (1<<13) +#define ERR_INT_PIPE_CRC_DONE_C (1<<8) +#define ERR_INT_FIFO_UNDERRUN_C (1<<6) +#define ERR_INT_PIPE_CRC_DONE_B (1<<5) +#define ERR_INT_FIFO_UNDERRUN_B (1<<3) +#define ERR_INT_PIPE_CRC_DONE_A (1<<2) +#define ERR_INT_PIPE_CRC_DONE(pipe) (1<<(2 + pipe*3)) +#define ERR_INT_FIFO_UNDERRUN_A (1<<0) +#define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3)) + +#define FPGA_DBG 0x42300 +#define FPGA_DBG_RM_NOCLAIM (1<<31) + +#define DERRMR 0x44050 +/* Note that HBLANK events are reserved on bdw+ */ +#define DERRMR_PIPEA_SCANLINE (1<<0) +#define DERRMR_PIPEA_PRI_FLIP_DONE (1<<1) +#define DERRMR_PIPEA_SPR_FLIP_DONE (1<<2) +#define DERRMR_PIPEA_VBLANK (1<<3) +#define DERRMR_PIPEA_HBLANK (1<<5) +#define DERRMR_PIPEB_SCANLINE (1<<8) +#define DERRMR_PIPEB_PRI_FLIP_DONE (1<<9) +#define DERRMR_PIPEB_SPR_FLIP_DONE (1<<10) +#define DERRMR_PIPEB_VBLANK (1<<11) +#define DERRMR_PIPEB_HBLANK (1<<13) +/* Note that PIPEC is not a simple translation of PIPEA/PIPEB */ +#define DERRMR_PIPEC_SCANLINE (1<<14) +#define DERRMR_PIPEC_PRI_FLIP_DONE (1<<15) +#define DERRMR_PIPEC_SPR_FLIP_DONE (1<<20) +#define DERRMR_PIPEC_VBLANK (1<<21) +#define DERRMR_PIPEC_HBLANK (1<<22) + + +/* GM45+ chicken bits -- debug workaround bits that may be required + * for various sorts of correct behavior. The top 16 bits of each are + * the enables for writing to the corresponding low bit. + */ +#define _3D_CHICKEN 0x02084 +#define _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB (1 << 10) +#define _3D_CHICKEN2 0x0208c +/* Disables pipelining of read flushes past the SF-WIZ interface. + * Required on all Ironlake steppings according to the B-Spec, but the + * particular danger of not doing so is not specified. + */ +# define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) +#define _3D_CHICKEN3 0x02090 +#define _3D_CHICKEN_SF_DISABLE_OBJEND_CULL (1 << 10) +#define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5) +#define _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(x) ((x)<<1) /* gen8+ */ +#define _3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH (1 << 1) /* gen6 */ + +#define MI_MODE 0x0209c +# define VS_TIMER_DISPATCH (1 << 6) +# define MI_FLUSH_ENABLE (1 << 12) +# define ASYNC_FLIP_PERF_DISABLE (1 << 14) + +#define GEN6_GT_MODE 0x20d0 +#define GEN7_GT_MODE 0x7008 +#define GEN6_WIZ_HASHING(hi, lo) (((hi) << 9) | ((lo) << 7)) +#define GEN6_WIZ_HASHING_8x8 GEN6_WIZ_HASHING(0, 0) +#define GEN6_WIZ_HASHING_8x4 GEN6_WIZ_HASHING(0, 1) +#define GEN6_WIZ_HASHING_16x4 GEN6_WIZ_HASHING(1, 0) +#define GEN6_WIZ_HASHING_MASK (GEN6_WIZ_HASHING(1, 1) << 16) +#define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5) + +#define GFX_MODE 0x02520 +#define GFX_MODE_GEN7 0x0229c +#define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c) +#define RING_EXCC_GEN7(ring) ((ring)->mmio_base+0x028) +#define GFX_RUN_LIST_ENABLE (1<<15) +#define GFX_TLB_INVALIDATE_EXPLICIT (1<<13) +#define GFX_SURFACE_FAULT_ENABLE (1<<12) +#define GFX_REPLAY_MODE (1<<11) +#define GFX_PSMI_GRANULARITY (1<<10) +#define GFX_PPGTT_ENABLE (1<<9) + +#define VLV_DISPLAY_BASE 0x180000 +#define VLV_MIPI_BASE VLV_DISPLAY_BASE + +#define VLV_GU_CTL0 (VLV_DISPLAY_BASE + 0x2030) +#define VLV_GU_CTL1 (VLV_DISPLAY_BASE + 0x2034) +#define SCPD0 0x0209c /* 915+ only */ +#define IER 0x020a0 +#define IIR 0x020a4 +#define IMR 0x020a8 +#define ISR 0x020ac +#define VLV_GUNIT_CLOCK_GATE (VLV_DISPLAY_BASE + 0x2060) +#define GINT_DIS (1<<22) +#define GCFG_DIS (1<<8) +#define VLV_GUNIT_CLOCK_GATE2 (VLV_DISPLAY_BASE + 0x2064) +#define VLV_IIR_RW (VLV_DISPLAY_BASE + 0x2084) +#define VLV_IER (VLV_DISPLAY_BASE + 0x20a0) +#define VLV_IIR (VLV_DISPLAY_BASE + 0x20a4) +#define VLV_IMR (VLV_DISPLAY_BASE + 0x20a8) +#define VLV_ISR (VLV_DISPLAY_BASE + 0x20ac) +#define VLV_PCBR (VLV_DISPLAY_BASE + 0x2120) +#define VLV_PCBR_ADDR_SHIFT 12 + +#define DISPLAY_PLANE_FLIP_PENDING(plane) (1<<(11-(plane))) /* A and B only */ +#define EIR 0x020b0 +#define EMR 0x020b4 +#define ESR 0x020b8 +#define GM45_ERROR_PAGE_TABLE (1<<5) +#define GM45_ERROR_MEM_PRIV (1<<4) +#define I915_ERROR_PAGE_TABLE (1<<4) +#define GM45_ERROR_CP_PRIV (1<<3) +#define I915_ERROR_MEMORY_REFRESH (1<<1) +#define I915_ERROR_INSTRUCTION (1<<0) +#define INSTPM 0x020c0 +#define INSTPM_SELF_EN (1<<12) /* 915GM only */ +#define INSTPM_AGPBUSY_INT_EN (1<<11) /* gen3: when disabled, pending interrupts + will not assert AGPBUSY# and will only + be delivered when out of C3. */ +#define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */ +#define INSTPM_TLB_INVALIDATE (1<<9) +#define INSTPM_SYNC_FLUSH (1<<5) +#define ACTHD 0x020c8 +#define FW_BLC 0x020d8 +#define FW_BLC2 0x020dc +#define FW_BLC_SELF 0x020e0 /* 915+ only */ +#define FW_BLC_SELF_EN_MASK (1<<31) +#define FW_BLC_SELF_FIFO_MASK (1<<16) /* 945 only */ +#define FW_BLC_SELF_EN (1<<15) /* 945 only */ +#define MM_BURST_LENGTH 0x00700000 +#define MM_FIFO_WATERMARK 0x0001F000 +#define LM_BURST_LENGTH 0x00000700 +#define LM_FIFO_WATERMARK 0x0000001F +#define MI_ARB_STATE 0x020e4 /* 915+ only */ + +/* Make render/texture TLB fetches lower priorty than associated data + * fetches. This is not turned on by default + */ +#define MI_ARB_RENDER_TLB_LOW_PRIORITY (1 << 15) + +/* Isoch request wait on GTT enable (Display A/B/C streams). + * Make isoch requests stall on the TLB update. May cause + * display underruns (test mode only) + */ +#define MI_ARB_ISOCH_WAIT_GTT (1 << 14) + +/* Block grant count for isoch requests when block count is + * set to a finite value. + */ +#define MI_ARB_BLOCK_GRANT_MASK (3 << 12) +#define MI_ARB_BLOCK_GRANT_8 (0 << 12) /* for 3 display planes */ +#define MI_ARB_BLOCK_GRANT_4 (1 << 12) /* for 2 display planes */ +#define MI_ARB_BLOCK_GRANT_2 (2 << 12) /* for 1 display plane */ +#define MI_ARB_BLOCK_GRANT_0 (3 << 12) /* don't use */ + +/* Enable render writes to complete in C2/C3/C4 power states. + * If this isn't enabled, render writes are prevented in low + * power states. That seems bad to me. + */ +#define MI_ARB_C3_LP_WRITE_ENABLE (1 << 11) + +/* This acknowledges an async flip immediately instead + * of waiting for 2TLB fetches. + */ +#define MI_ARB_ASYNC_FLIP_ACK_IMMEDIATE (1 << 10) + +/* Enables non-sequential data reads through arbiter + */ +#define MI_ARB_DUAL_DATA_PHASE_DISABLE (1 << 9) + +/* Disable FSB snooping of cacheable write cycles from binner/render + * command stream + */ +#define MI_ARB_CACHE_SNOOP_DISABLE (1 << 8) + +/* Arbiter time slice for non-isoch streams */ +#define MI_ARB_TIME_SLICE_MASK (7 << 5) +#define MI_ARB_TIME_SLICE_1 (0 << 5) +#define MI_ARB_TIME_SLICE_2 (1 << 5) +#define MI_ARB_TIME_SLICE_4 (2 << 5) +#define MI_ARB_TIME_SLICE_6 (3 << 5) +#define MI_ARB_TIME_SLICE_8 (4 << 5) +#define MI_ARB_TIME_SLICE_10 (5 << 5) +#define MI_ARB_TIME_SLICE_14 (6 << 5) +#define MI_ARB_TIME_SLICE_16 (7 << 5) + +/* Low priority grace period page size */ +#define MI_ARB_LOW_PRIORITY_GRACE_4KB (0 << 4) /* default */ +#define MI_ARB_LOW_PRIORITY_GRACE_8KB (1 << 4) + +/* Disable display A/B trickle feed */ +#define MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE (1 << 2) + +/* Set display plane priority */ +#define MI_ARB_DISPLAY_PRIORITY_A_B (0 << 0) /* display A > display B */ +#define MI_ARB_DISPLAY_PRIORITY_B_A (1 << 0) /* display B > display A */ + +#define MI_STATE 0x020e4 /* gen2 only */ +#define MI_AGPBUSY_INT_EN (1 << 1) /* 85x only */ +#define MI_AGPBUSY_830_MODE (1 << 0) /* 85x only */ + +#define CACHE_MODE_0 0x02120 /* 915+ only */ +#define CM0_PIPELINED_RENDER_FLUSH_DISABLE (1<<8) +#define CM0_IZ_OPT_DISABLE (1<<6) +#define CM0_ZR_OPT_DISABLE (1<<5) +#define CM0_STC_EVICT_DISABLE_LRA_SNB (1<<5) +#define CM0_DEPTH_EVICT_DISABLE (1<<4) +#define CM0_COLOR_EVICT_DISABLE (1<<3) +#define CM0_DEPTH_WRITE_DISABLE (1<<1) +#define CM0_RC_OP_FLUSH_DISABLE (1<<0) +#define GFX_FLSH_CNTL 0x02170 /* 915+ only */ +#define GFX_FLSH_CNTL_GEN6 0x101008 +#define GFX_FLSH_CNTL_EN (1<<0) +#define ECOSKPD 0x021d0 +#define ECO_GATING_CX_ONLY (1<<3) +#define ECO_FLIP_DONE (1<<0) + +#define CACHE_MODE_0_GEN7 0x7000 /* IVB+ */ +#define RC_OP_FLUSH_ENABLE (1<<0) +#define HIZ_RAW_STALL_OPT_DISABLE (1<<2) +#define CACHE_MODE_1 0x7004 /* IVB+ */ +#define PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1<<6) +#define GEN8_4x4_STC_OPTIMIZATION_DISABLE (1<<6) + +#define GEN6_BLITTER_ECOSKPD 0x221d0 +#define GEN6_BLITTER_LOCK_SHIFT 16 +#define GEN6_BLITTER_FBC_NOTIFY (1<<3) + +#define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050 +#define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) +#define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10) + +/* Fuse readout registers for GT */ +#define CHV_FUSE_GT 0x182168 +#define CHV_FGT_EU_DIS_SS0_R0_SHIFT 16 +#define CHV_FGT_EU_DIS_SS0_R0_MASK (0xf<<CHV_FGT_EU_DIS_SS0_R0_SHIFT) +#define CHV_FGT_EU_DIS_SS0_R1_SHIFT 20 +#define CHV_FGT_EU_DIS_SS0_R1_MASK (0xf<<CHV_FGT_EU_DIS_SS0_R1_SHIFT) +#define CHV_FGT_EU_DIS_SS1_R0_SHIFT 24 +#define CHV_FGT_EU_DIS_SS1_R0_MASK (0xf<<CHV_FGT_EU_DIS_SS1_R0_SHIFT) +#define CHV_FGT_EU_DIS_SS1_R1_SHIFT 28 +#define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf<<CHV_FGT_EU_DIS_SS1_R1_SHIFT) + +#define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 +#define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) +#define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) +#define GEN6_BSD_SLEEP_INDICATOR (1 << 3) +#define GEN6_BSD_GO_INDICATOR (1 << 4) + +/* On modern GEN architectures interrupt control consists of two sets + * of registers. The first set pertains to the ring generating the + * interrupt. The second control is for the functional block generating the + * interrupt. These are PM, GT, DE, etc. + * + * Luckily *knocks on wood* all the ring interrupt bits match up with the + * GT interrupt bits, so we don't need to duplicate the defines. + * + * These defines should cover us well from SNB->HSW with minor exceptions + * it can also work on ILK. + */ +#define GT_BLT_FLUSHDW_NOTIFY_INTERRUPT (1 << 26) +#define GT_BLT_CS_ERROR_INTERRUPT (1 << 25) +#define GT_BLT_USER_INTERRUPT (1 << 22) +#define GT_GEN6_BSD_WATCHDOG_INTERRUPT (1 << 18) +#define RCS_WATCHDOG_DISABLE 1 +#define GT_BSD_CS_ERROR_INTERRUPT (1 << 15) +#define GT_BSD_USER_INTERRUPT (1 << 12) +#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 (1 << 11) /* hsw+; rsvd on snb, ivb, vlv */ +#define GT_RENDER_PERFMON_BUFFER_INTERRUPT (1 << 9) /* !snb */ +#define GT_CONTEXT_SWITCH_INTERRUPT (1 << 8) +#define GT_GEN6_RENDER_WATCHDOG_INTERRUPT (1 << 6) +#define GT_GEN8_RCS_WATCHDOG_INTERRUPT (1 << 6) +#define GT_GEN8_VCS_WATCHDOG_INTERRUPT (1 << 6) +#define VCS_WATCHDOG_DISABLE 0xFFFFFFFF +#define VCS2_WATCHDOG_DISABLE 0xFFFFFFFF +#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT (1 << 5) /* !snb */ +#define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT (1 << 4) +#define GT_RENDER_CS_MASTER_ERROR_INTERRUPT (1 << 3) +#define GT_RENDER_SYNC_STATUS_INTERRUPT (1 << 2) +#define GT_RENDER_DEBUG_INTERRUPT (1 << 1) +#define GT_RENDER_USER_INTERRUPT (1 << 0) + +#define PM_VEBOX_CS_ERROR_INTERRUPT (1 << 12) /* hsw+ */ +#define PM_VEBOX_USER_INTERRUPT (1 << 10) /* hsw+ */ + +#define GT_PARITY_ERROR(dev) \ + (GT_RENDER_L3_PARITY_ERROR_INTERRUPT | \ + (IS_HASWELL(dev) ? GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 : 0)) + +/* These are all the "old" interrupts */ +#define ILK_BSD_USER_INTERRUPT (1<<5) + +#define I915_PM_INTERRUPT (1<<31) +#define I915_ISP_INTERRUPT (1<<22) +#define I915_MIPIB_INTERRUPT (1<<19) +#define I915_MIPIA_INTERRUPT (1<<18) +#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) +#define I915_DISPLAY_PORT_INTERRUPT (1<<17) +#define I915_DISPLAY_PIPE_C_HBLANK_INTERRUPT (1<<16) +#define I915_MASTER_ERROR_INTERRUPT (1<<15) +#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) +#define I915_DISPLAY_PIPE_B_HBLANK_INTERRUPT (1<<14) +#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) /* p-state */ +#define I915_DISPLAY_PIPE_A_HBLANK_INTERRUPT (1<<13) +#define I915_HWB_OOM_INTERRUPT (1<<13) +#define I915_SYNC_STATUS_INTERRUPT (1<<12) +#define I915_MISC_INTERRUPT (1<<11) +#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) +#define I915_DISPLAY_PIPE_C_VBLANK_INTERRUPT (1<<10) +#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) +#define I915_DISPLAY_PIPE_C_EVENT_INTERRUPT (1<<9) +#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) +#define I915_DISPLAY_PIPE_C_DPBM_INTERRUPT (1<<8) +#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) +#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) +#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) +#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) +#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) +#define I915_DISPLAY_PIPE_A_DPBM_INTERRUPT (1<<3) +#define I915_DISPLAY_PIPE_B_DPBM_INTERRUPT (1<<2) +#define I915_DEBUG_INTERRUPT (1<<2) +#define I915_WINVALID_INTERRUPT (1<<1) +#define I915_USER_INTERRUPT (1<<1) +#define I915_ASLE_INTERRUPT (1<<0) +#define I915_BSD_USER_INTERRUPT (1<<25) + +/* Added for HDMI Audio */ +#define I915_LPE_AUDIO_HDMI_STATUS_A \ + (dev_priv->info.display_mmio_offset + 0x65064) +#define I915_LPE_AUDIO_HDMI_STATUS_B \ + (dev_priv->info.display_mmio_offset + 0x65864) +#define I915_LPE_AUDIO_HDMI_STATUS_C \ + (dev_priv->info.display_mmio_offset + 0x65964) +#define I915_LPE_PIPE_B_INTERRUPT (1<<20) +#define I915_LPE_PIPE_A_INTERRUPT (1<<21) +#define I915_LPE_PIPE_C_INTERRUPT (1<<12) +#define I915_HDMI_AUDIO_UNDERRUN (1UL<<31) +#define I915_HDMI_AUDIO_BUFFER_DONE (1UL<<29) +#define I915_HDMI_AUDIO_UNDERRUN_ENABLE (1UL<<15) +#define I915_HDMI_AUDIO_LPE_C_CONFIG 0x65900 +#define I915_HDMI_AUDIO_LPE_B_CONFIG 0x65800 +#define GEN6_BSD_RNCID 0x12198 + +#define GEN7_FF_THREAD_MODE 0x20a0 +#define GEN7_FF_SCHED_MASK 0x0077070 +#define GEN8_FF_DS_REF_CNT_FFME (1 << 19) +#define GEN7_FF_TS_SCHED_HS1 (0x5<<16) +#define GEN7_FF_TS_SCHED_HS0 (0x3<<16) +#define GEN7_FF_TS_SCHED_LOAD_BALANCE (0x1<<16) +#define GEN7_FF_TS_SCHED_HW (0x0<<16) /* Default */ +#define GEN7_FF_VS_REF_CNT_FFME (1 << 15) +#define GEN7_FF_VS_SCHED_HS1 (0x5<<12) +#define GEN7_FF_VS_SCHED_HS0 (0x3<<12) +#define GEN7_FF_VS_SCHED_LOAD_BALANCE (0x1<<12) /* Default */ +#define GEN7_FF_VS_SCHED_HW (0x0<<12) +#define GEN7_FF_DS_SCHED_HS1 (0x5<<4) +#define GEN7_FF_DS_SCHED_HS0 (0x3<<4) +#define GEN7_FF_DS_SCHED_LOAD_BALANCE (0x1<<4) /* Default */ +#define GEN7_FF_DS_SCHED_HW (0x0<<4) + +/* + * Framebuffer compression (915+ only) + */ + +#define FBC_CFB_BASE 0x03200 /* 4k page aligned */ +#define FBC_LL_BASE 0x03204 /* 4k page aligned */ +#define FBC_CONTROL 0x03208 +#define FBC_CTL_EN (1<<31) +#define FBC_CTL_PERIODIC (1<<30) +#define FBC_CTL_INTERVAL_SHIFT (16) +#define FBC_CTL_UNCOMPRESSIBLE (1<<14) +#define FBC_CTL_C3_IDLE (1<<13) +#define FBC_CTL_STRIDE_SHIFT (5) +#define FBC_CTL_FENCENO_SHIFT (0) +#define FBC_COMMAND 0x0320c +#define FBC_CMD_COMPRESS (1<<0) +#define FBC_STATUS 0x03210 +#define FBC_STAT_COMPRESSING (1<<31) +#define FBC_STAT_COMPRESSED (1<<30) +#define FBC_STAT_MODIFIED (1<<29) +#define FBC_STAT_CURRENT_LINE_SHIFT (0) +#define FBC_CONTROL2 0x03214 +#define FBC_CTL_FENCE_DBL (0<<4) +#define FBC_CTL_IDLE_IMM (0<<2) +#define FBC_CTL_IDLE_FULL (1<<2) +#define FBC_CTL_IDLE_LINE (2<<2) +#define FBC_CTL_IDLE_DEBUG (3<<2) +#define FBC_CTL_CPU_FENCE (1<<1) +#define FBC_CTL_PLANE(plane) ((plane)<<0) +#define FBC_FENCE_OFF 0x03218 /* BSpec typo has 321Bh */ +#define FBC_TAG 0x03300 + +#define FBC_LL_SIZE (1536) + +/* Framebuffer compression for GM45+ */ +#define DPFC_CB_BASE 0x3200 +#define DPFC_CONTROL 0x3208 +#define DPFC_CTL_EN (1<<31) +#define DPFC_CTL_PLANE(plane) ((plane)<<30) +#define IVB_DPFC_CTL_PLANE(plane) ((plane)<<29) +#define DPFC_CTL_FENCE_EN (1<<29) +#define IVB_DPFC_CTL_FENCE_EN (1<<28) +#define DPFC_CTL_PERSISTENT_MODE (1<<25) +#define DPFC_SR_EN (1<<10) +#define DPFC_CTL_LIMIT_1X (0<<6) +#define DPFC_CTL_LIMIT_2X (1<<6) +#define DPFC_CTL_LIMIT_4X (2<<6) +#define DPFC_RECOMP_CTL 0x320c +#define DPFC_RECOMP_STALL_EN (1<<27) +#define DPFC_RECOMP_STALL_WM_SHIFT (16) +#define DPFC_RECOMP_STALL_WM_MASK (0x07ff0000) +#define DPFC_RECOMP_TIMER_COUNT_SHIFT (0) +#define DPFC_RECOMP_TIMER_COUNT_MASK (0x0000003f) +#define DPFC_STATUS 0x3210 +#define DPFC_INVAL_SEG_SHIFT (16) +#define DPFC_INVAL_SEG_MASK (0x07ff0000) +#define DPFC_COMP_SEG_SHIFT (0) +#define DPFC_COMP_SEG_MASK (0x000003ff) +#define DPFC_STATUS2 0x3214 +#define DPFC_FENCE_YOFF 0x3218 +#define DPFC_CHICKEN 0x3224 +#define DPFC_HT_MODIFY (1<<31) + +/* Framebuffer compression for Ironlake */ +#define ILK_DPFC_CB_BASE 0x43200 +#define ILK_DPFC_CONTROL 0x43208 +/* The bit 28-8 is reserved */ +#define DPFC_RESERVED (0x1FFFFF00) +#define ILK_DPFC_RECOMP_CTL 0x4320c +#define ILK_DPFC_STATUS 0x43210 +#define ILK_DPFC_FENCE_YOFF 0x43218 +#define ILK_DPFC_CHICKEN 0x43224 +#define ILK_FBC_RT_BASE 0x2128 +#define ILK_FBC_RT_VALID (1<<0) +#define SNB_FBC_FRONT_BUFFER (1<<1) + +#define ILK_DISPLAY_CHICKEN1 0x42000 +#define ILK_FBCQ_DIS (1<<22) +#define ILK_PABSTRETCH_DIS (1<<21) + + +/* + * Framebuffer compression for Sandybridge + * + * The following two registers are of type GTTMMADR + */ +#define SNB_DPFC_CTL_SA 0x100100 +#define SNB_CPU_FENCE_ENABLE (1<<29) +#define DPFC_CPU_FENCE_OFFSET 0x100104 + +/* Framebuffer compression for Ivybridge */ +#define IVB_FBC_RT_BASE 0x7020 + +#define IPS_CTL 0x43408 +#define IPS_ENABLE (1 << 31) + +#define MSG_FBC_REND_STATE 0x50380 +#define FBC_REND_NUKE (1<<2) +#define FBC_REND_CACHE_CLEAN (1<<1) + +/* + * GPIO regs + */ +#define GPIOA 0x5010 +#define GPIOB 0x5014 +#define GPIOC 0x5018 +#define GPIOD 0x501c +#define GPIOE 0x5020 +#define GPIOF 0x5024 +#define GPIOG 0x5028 +#define GPIOH 0x502c +# define GPIO_CLOCK_DIR_MASK (1 << 0) +# define GPIO_CLOCK_DIR_IN (0 << 1) +# define GPIO_CLOCK_DIR_OUT (1 << 1) +# define GPIO_CLOCK_VAL_MASK (1 << 2) +# define GPIO_CLOCK_VAL_OUT (1 << 3) +# define GPIO_CLOCK_VAL_IN (1 << 4) +# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) +# define GPIO_DATA_DIR_MASK (1 << 8) +# define GPIO_DATA_DIR_IN (0 << 9) +# define GPIO_DATA_DIR_OUT (1 << 9) +# define GPIO_DATA_VAL_MASK (1 << 10) +# define GPIO_DATA_VAL_OUT (1 << 11) +# define GPIO_DATA_VAL_IN (1 << 12) +# define GPIO_DATA_PULLUP_DISABLE (1 << 13) + +#define GMBUS0 0x5100 /* clock/port select */ +#define GMBUS_RATE_100KHZ (0<<8) +#define GMBUS_RATE_50KHZ (1<<8) +#define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */ +#define GMBUS_RATE_1MHZ (3<<8) /* reserved on Pineview */ +#define GMBUS_HOLD_EXT (1<<7) /* 300ns hold time, rsvd on Pineview */ +#define GMBUS_PORT_DISABLED 0 +#define GMBUS_PORT_SSC 1 +#define GMBUS_PORT_VGADDC 2 +#define GMBUS_PORT_PANEL 3 +#define GMBUS_PORT_DPD_CHV 3 /* HDMID_CHV */ +#define GMBUS_PORT_DPC 4 /* HDMIC */ +#define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */ +#define GMBUS_PORT_DPD 6 /* HDMID */ +#define GMBUS_PORT_RESERVED 7 /* 7 reserved */ +#define GMBUS_NUM_PORTS (GMBUS_PORT_DPD - GMBUS_PORT_SSC + 1) +#define GMBUS1 0x5104 /* command/status */ +#define GMBUS_SW_CLR_INT (1<<31) +#define GMBUS_SW_RDY (1<<30) +#define GMBUS_ENT (1<<29) /* enable timeout */ +#define GMBUS_CYCLE_NONE (0<<25) +#define GMBUS_CYCLE_WAIT (1<<25) +#define GMBUS_CYCLE_INDEX (2<<25) +#define GMBUS_CYCLE_STOP (4<<25) +#define GMBUS_BYTE_COUNT_SHIFT 16 +#define GMBUS_SLAVE_INDEX_SHIFT 8 +#define GMBUS_SLAVE_ADDR_SHIFT 1 +#define GMBUS_SLAVE_READ (1<<0) +#define GMBUS_SLAVE_WRITE (0<<0) +#define GMBUS2 0x5108 /* status */ +#define GMBUS_INUSE (1<<15) +#define GMBUS_HW_WAIT_PHASE (1<<14) +#define GMBUS_STALL_TIMEOUT (1<<13) +#define GMBUS_INT (1<<12) +#define GMBUS_HW_RDY (1<<11) +#define GMBUS_SATOER (1<<10) +#define GMBUS_ACTIVE (1<<9) +#define GMBUS3 0x510c /* data buffer bytes 3-0 */ +#define GMBUS4 0x5110 /* interrupt mask (Pineview+) */ +#define GMBUS_SLAVE_TIMEOUT_EN (1<<4) +#define GMBUS_NAK_EN (1<<3) +#define GMBUS_IDLE_EN (1<<2) +#define GMBUS_HW_WAIT_EN (1<<1) +#define GMBUS_HW_RDY_EN (1<<0) +#define GMBUS5 0x5120 /* byte index */ +#define GMBUS_2BYTE_INDEX_EN (1<<31) + +/* + * Clock control & power management + */ +#define _DPLL_A (dev_priv->info.display_mmio_offset + 0x6014) +#define _DPLL_B (dev_priv->info.display_mmio_offset + 0x6018) +#define _CHV_DPLL_C (dev_priv->info.display_mmio_offset + 0x6030) +#define DPLL(pipe) _PIPE3((pipe), _DPLL_A, _DPLL_B, _CHV_DPLL_C) + +#define VGA0 0x6000 +#define VGA1 0x6004 +#define VGA_PD 0x6010 +#define VGA0_PD_P2_DIV_4 (1 << 7) +#define VGA0_PD_P1_DIV_2 (1 << 5) +#define VGA0_PD_P1_SHIFT 0 +#define VGA0_PD_P1_MASK (0x1f << 0) +#define VGA1_PD_P2_DIV_4 (1 << 15) +#define VGA1_PD_P1_DIV_2 (1 << 13) +#define VGA1_PD_P1_SHIFT 8 +#define VGA1_PD_P1_MASK (0x1f << 8) +#define DPLL_VCO_ENABLE (1 << 31) +#define DPLL_SDVO_HIGH_SPEED (1 << 30) +#define DPLL_DVO_2X_MODE (1 << 30) +#define DPLL_EXT_BUFFER_ENABLE_VLV (1 << 30) +#define DPLL_SYNCLOCK_ENABLE (1 << 29) +#define DPLL_REFA_CLK_ENABLE_VLV (1 << 29) +#define DPLL_VGA_MODE_DIS (1 << 28) +#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +#define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +#define DPLL_MODE_MASK (3 << 26) +#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +#define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ +#define DPLL_LOCK_VLV (1<<15) +#define DPLL_INTEGRATED_CRI_CLK_VLV (1<<14) +#define DPLL_INTEGRATED_CLOCK_VLV (1<<13) +#define DPLL_RESERVED_BIT (1<<11) +#define DPLL_SSC_REF_CLOCK_CHV (1<<13) +#define DPLL_PORTC_READY_MASK (0xf << 4) +#define DPLL_PORTB_READY_MASK (0xf) + +#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 + +/* Additional CHV pll/phy registers */ +#define DPIO_PHY_STATUS (VLV_DISPLAY_BASE + 0x6240) +#define DPLL_PORTD_READY_MASK (0xf) +#define DISPLAY_PHY_CONTROL (VLV_DISPLAY_BASE + 0x60100) +#define PHY_COM_LANE_RESET_DEASSERT(phy) (1 << (phy)) +#define DISPLAY_PHY_STATUS (VLV_DISPLAY_BASE + 0x60104) +#define PHY_POWERGOOD(phy) (((phy) == DPIO_PHY0) ? (1<<31) : (1<<30)) + +/* + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +#define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +#define DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW 15 +/* i830, required in DVO non-gang */ +#define PLL_P2_DIVIDE_BY_4 (1 << 23) +#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +#define PLL_REF_INPUT_DREFCLK (0 << 13) +#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ +#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +#define PLL_REF_INPUT_MASK (3 << 13) +#define PLL_LOAD_PULSE_PHASE_SHIFT 9 +/* Ironlake */ +# define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT 9 +# define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK (7 << 9) +# define PLL_REF_SDVO_HDMI_MULTIPLIER(x) (((x)-1) << 9) +# define DPLL_FPA1_P1_POST_DIV_SHIFT 0 +# define DPLL_FPA1_P1_POST_DIV_MASK 0xff + +/* + * Parallel to Serial Load Pulse phase selection. + * Selects the phase for the 10X DPLL clock for the PCIe + * digital display port. The range is 4 to 13; 10 or more + * is just a flip delay. The default is 6 + */ +#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +#define DISPLAY_RATE_SELECT_FPA1 (1 << 8) +/* + * SDVO multiplier for 945G/GM. Not used on 965. + */ +#define SDVO_MULTIPLIER_MASK 0x000000ff +#define SDVO_MULTIPLIER_SHIFT_HIRES 4 +#define SDVO_MULTIPLIER_SHIFT_VGA 0 + +#define _DPLL_A_MD (dev_priv->info.display_mmio_offset + 0x601c) +#define _DPLL_B_MD (dev_priv->info.display_mmio_offset + 0x6020) +#define _CHV_DPLL_C_MD (dev_priv->info.display_mmio_offset + 0x603c) +#define DPLL_MD(pipe) _PIPE3((pipe), _DPLL_A_MD, _DPLL_B_MD, _CHV_DPLL_C_MD) + +/* + * UDI pixel divider, controlling how many pixels are stuffed into a packet. + * + * Value is pixels minus 1. Must be set to 1 pixel for SDVO. + */ +#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +#define DPLL_MD_UDI_DIVIDER_SHIFT 24 +/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +/* + * SDVO/UDI pixel multiplier. + * + * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus + * clock rate is 10 times the DPLL clock. At low resolution/refresh rate + * modes, the bus rate would be below the limits, so SDVO allows for stuffing + * dummy bytes in the datastream at an increased clock rate, with both sides of + * the link knowing how many bytes are fill. + * + * So, for a mode with a dotclock of 65Mhz, we would want to double the clock + * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be + * set to 130Mhz, and the SDVO multiplier set to 2x in this register and + * through an SDVO command. + * + * This register field has values of multiplication factor minus 1, with + * a maximum multiplier of 5 for SDVO. + */ +#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +/* + * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. + * This best be set to the default value (3) or the CRT won't work. No, + * I don't entirely understand what this does... + */ +#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 + +#define _FPA0 0x06040 +#define _FPA1 0x06044 +#define _FPB0 0x06048 +#define _FPB1 0x0604c +#define FP0(pipe) _PIPE(pipe, _FPA0, _FPB0) +#define FP1(pipe) _PIPE(pipe, _FPA1, _FPB1) +#define FP_N_DIV_MASK 0x003f0000 +#define FP_N_PINEVIEW_DIV_MASK 0x00ff0000 +#define FP_N_DIV_SHIFT 16 +#define FP_M1_DIV_MASK 0x00003f00 +#define FP_M1_DIV_SHIFT 8 +#define FP_M2_DIV_MASK 0x0000003f +#define FP_M2_PINEVIEW_DIV_MASK 0x000000ff +#define FP_M2_DIV_SHIFT 0 +#define DPLL_TEST 0x606c +#define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +#define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +#define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +#define DPLLB_TEST_N_BYPASS (1 << 19) +#define DPLLB_TEST_M_BYPASS (1 << 18) +#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +#define DPLLA_TEST_N_BYPASS (1 << 3) +#define DPLLA_TEST_M_BYPASS (1 << 2) +#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) +#define D_STATE 0x6104 +#define DSTATE_GFX_RESET_I830 (1<<6) +#define DSTATE_PLL_D3_OFF (1<<3) +#define DSTATE_GFX_CLOCK_GATING (1<<1) +#define DSTATE_DOT_CLOCK_GATING (1<<0) +#define DSPCLK_GATE_D (dev_priv->info.display_mmio_offset + 0x6200) +# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ +# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ +# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ +# define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */ +# define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */ +# define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */ +# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */ +# define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */ +# define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */ +# define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */ +# define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */ +# define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */ +# define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */ +# define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */ +# define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */ +# define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */ +# define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */ +# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */ +# define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */ +# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) +# define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10) +# define DCUNIT_CLOCK_GATE_DISABLE (1 << 9) +# define DPUNIT_CLOCK_GATE_DISABLE (1 << 8) +# define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */ +# define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */ +# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ +# define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) +# define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) +/* + * This bit must be set on the 830 to prevent hangs when turning off the + * overlay scaler. + */ +# define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3) +# define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2) +# define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1) +# define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */ +# define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */ + +#define RENCLK_GATE_D1 0x6204 +# define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */ +# define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */ +# define PC_FE_CLOCK_GATE_DISABLE (1 << 11) +# define PC_BE_CLOCK_GATE_DISABLE (1 << 10) +# define WINDOWER_CLOCK_GATE_DISABLE (1 << 9) +# define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8) +# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7) +# define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6) +# define MAG_CLOCK_GATE_DISABLE (1 << 5) +/* This bit must be unset on 855,865 */ +# define MECI_CLOCK_GATE_DISABLE (1 << 4) +# define DCMP_CLOCK_GATE_DISABLE (1 << 3) +# define MEC_CLOCK_GATE_DISABLE (1 << 2) +# define MECO_CLOCK_GATE_DISABLE (1 << 1) +/* This bit must be set on 855,865. */ +# define SV_CLOCK_GATE_DISABLE (1 << 0) +# define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16) +# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15) +# define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14) +# define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13) +# define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12) +# define I915_WM_CLOCK_GATE_DISABLE (1 << 11) +# define I915_IZ_CLOCK_GATE_DISABLE (1 << 10) +# define I915_PI_CLOCK_GATE_DISABLE (1 << 9) +# define I915_DI_CLOCK_GATE_DISABLE (1 << 8) +# define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7) +# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6) +# define I915_SC_CLOCK_GATE_DISABLE (1 << 5) +# define I915_FL_CLOCK_GATE_DISABLE (1 << 4) +# define I915_DM_CLOCK_GATE_DISABLE (1 << 3) +# define I915_PS_CLOCK_GATE_DISABLE (1 << 2) +# define I915_CC_CLOCK_GATE_DISABLE (1 << 1) +# define I915_BY_CLOCK_GATE_DISABLE (1 << 0) + +# define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30) +/* This bit must always be set on 965G/965GM */ +# define I965_RCC_CLOCK_GATE_DISABLE (1 << 29) +# define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28) +# define I965_DAP_CLOCK_GATE_DISABLE (1 << 27) +# define I965_ROC_CLOCK_GATE_DISABLE (1 << 26) +# define I965_GW_CLOCK_GATE_DISABLE (1 << 25) +# define I965_TD_CLOCK_GATE_DISABLE (1 << 24) +/* This bit must always be set on 965G */ +# define I965_ISC_CLOCK_GATE_DISABLE (1 << 23) +# define I965_IC_CLOCK_GATE_DISABLE (1 << 22) +# define I965_EU_CLOCK_GATE_DISABLE (1 << 21) +# define I965_IF_CLOCK_GATE_DISABLE (1 << 20) +# define I965_TC_CLOCK_GATE_DISABLE (1 << 19) +# define I965_SO_CLOCK_GATE_DISABLE (1 << 17) +# define I965_FBC_CLOCK_GATE_DISABLE (1 << 16) +# define I965_MARI_CLOCK_GATE_DISABLE (1 << 15) +# define I965_MASF_CLOCK_GATE_DISABLE (1 << 14) +# define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13) +# define I965_EM_CLOCK_GATE_DISABLE (1 << 12) +# define I965_UC_CLOCK_GATE_DISABLE (1 << 11) +# define I965_SI_CLOCK_GATE_DISABLE (1 << 6) +# define I965_MT_CLOCK_GATE_DISABLE (1 << 5) +# define I965_PL_CLOCK_GATE_DISABLE (1 << 4) +# define I965_DG_CLOCK_GATE_DISABLE (1 << 3) +# define I965_QC_CLOCK_GATE_DISABLE (1 << 2) +# define I965_FT_CLOCK_GATE_DISABLE (1 << 1) +# define I965_DM_CLOCK_GATE_DISABLE (1 << 0) + +#define RENCLK_GATE_D2 0x6208 +#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) +#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) +#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) + +#define VDECCLK_GATE_D 0x620C /* g4x only */ +#define VCP_UNIT_CLOCK_GATE_DISABLE (1 << 4) + +#define RAMCLK_GATE_D 0x6210 /* CRL only */ +#define DEUC 0x6214 /* CRL only */ + +#define FW_BLC_SELF_VLV (VLV_DISPLAY_BASE + 0x6500) +#define FW_CSPWRDWNEN (1<<15) + +#define MI_ARB_VLV (VLV_DISPLAY_BASE + 0x6504) + +#define CZCLK_CDCLK_FREQ_RATIO (VLV_DISPLAY_BASE + 0x6508) +#define CDCLK_FREQ_SHIFT 4 +#define CDCLK_FREQ_MASK (0x1f << CDCLK_FREQ_SHIFT) +#define CZCLK_FREQ_MASK 0xf +#define GMBUSFREQ_VLV (VLV_DISPLAY_BASE + 0x6510) + +/* + * Palette regs + */ +#define PALETTE_A_OFFSET 0xa000 +#define PALETTE_B_OFFSET 0xa800 +#define CHV_PALETTE_C_OFFSET 0xc000 +#define PALETTE(pipe) (dev_priv->info.palette_offsets[pipe] + \ + dev_priv->info.display_mmio_offset) + +/* MCH MMIO space */ + +/* + * MCHBAR mirror. + * + * This mirrors the MCHBAR MMIO space whose location is determined by + * device 0 function 0's pci config register 0x44 or 0x48 and matches it in + * every way. It is not accessible from the CP register read instructions. + * + * Starting from Haswell, you can't write registers using the MCHBAR mirror, + * just read. + */ +#define MCHBAR_MIRROR_BASE 0x10000 + +#define MCHBAR_MIRROR_BASE_SNB 0x140000 + +/* Memory controller frequency in MCHBAR for Haswell (possible SNB+) */ +#define DCLK (MCHBAR_MIRROR_BASE_SNB + 0x5e04) + +/* 915-945 and GM965 MCH register controlling DRAM channel access */ +#define DCC 0x10200 +#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) +#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0) +#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0) +#define DCC_ADDRESSING_MODE_MASK (3 << 0) +#define DCC_CHANNEL_XOR_DISABLE (1 << 10) +#define DCC_CHANNEL_XOR_BIT_17 (1 << 9) + +/* Pineview MCH register contains DDR3 setting */ +#define CSHRDDR3CTL 0x101a8 +#define CSHRDDR3CTL_DDR3 (1 << 2) + +/* 965 MCH register controlling DRAM channel configuration */ +#define C0DRB3 0x10206 +#define C1DRB3 0x10606 + +/* snb MCH registers for reading the DRAM channel configuration */ +#define MAD_DIMM_C0 (MCHBAR_MIRROR_BASE_SNB + 0x5004) +#define MAD_DIMM_C1 (MCHBAR_MIRROR_BASE_SNB + 0x5008) +#define MAD_DIMM_C2 (MCHBAR_MIRROR_BASE_SNB + 0x500C) +#define MAD_DIMM_ECC_MASK (0x3 << 24) +#define MAD_DIMM_ECC_OFF (0x0 << 24) +#define MAD_DIMM_ECC_IO_ON_LOGIC_OFF (0x1 << 24) +#define MAD_DIMM_ECC_IO_OFF_LOGIC_ON (0x2 << 24) +#define MAD_DIMM_ECC_ON (0x3 << 24) +#define MAD_DIMM_ENH_INTERLEAVE (0x1 << 22) +#define MAD_DIMM_RANK_INTERLEAVE (0x1 << 21) +#define MAD_DIMM_B_WIDTH_X16 (0x1 << 20) /* X8 chips if unset */ +#define MAD_DIMM_A_WIDTH_X16 (0x1 << 19) /* X8 chips if unset */ +#define MAD_DIMM_B_DUAL_RANK (0x1 << 18) +#define MAD_DIMM_A_DUAL_RANK (0x1 << 17) +#define MAD_DIMM_A_SELECT (0x1 << 16) +/* DIMM sizes are in multiples of 256mb. */ +#define MAD_DIMM_B_SIZE_SHIFT 8 +#define MAD_DIMM_B_SIZE_MASK (0xff << MAD_DIMM_B_SIZE_SHIFT) +#define MAD_DIMM_A_SIZE_SHIFT 0 +#define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT) + +/* snb MCH registers for priority tuning */ +#define MCH_SSKPD (MCHBAR_MIRROR_BASE_SNB + 0x5d10) +#define MCH_SSKPD_WM0_MASK 0x3f +#define MCH_SSKPD_WM0_VAL 0xc + +#define MCH_SECP_NRG_STTS (MCHBAR_MIRROR_BASE_SNB + 0x592c) + +/* Clocking configuration register */ +#define CLKCFG 0x10c00 +#define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ +#define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ +#define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ +#define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ +#define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ +#define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ +/* Note, below two are guess */ +#define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ +#define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */ +#define CLKCFG_FSB_MASK (7 << 0) +#define CLKCFG_MEM_533 (1 << 4) +#define CLKCFG_MEM_667 (2 << 4) +#define CLKCFG_MEM_800 (3 << 4) +#define CLKCFG_MEM_MASK (7 << 4) + +#define TSC1 0x11001 +#define TSE (1<<0) +#define TR1 0x11006 +#define TSFS 0x11020 +#define TSFS_SLOPE_MASK 0x0000ff00 +#define TSFS_SLOPE_SHIFT 8 +#define TSFS_INTR_MASK 0x000000ff + +#define CRSTANDVID 0x11100 +#define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */ +#define PXVFREQ_PX_MASK 0x7f000000 +#define PXVFREQ_PX_SHIFT 24 +#define VIDFREQ_BASE 0x11110 +#define VIDFREQ1 0x11110 /* VIDFREQ1-4 (0x1111c) (Cantiga) */ +#define VIDFREQ2 0x11114 +#define VIDFREQ3 0x11118 +#define VIDFREQ4 0x1111c +#define VIDFREQ_P0_MASK 0x1f000000 +#define VIDFREQ_P0_SHIFT 24 +#define VIDFREQ_P0_CSCLK_MASK 0x00f00000 +#define VIDFREQ_P0_CSCLK_SHIFT 20 +#define VIDFREQ_P0_CRCLK_MASK 0x000f0000 +#define VIDFREQ_P0_CRCLK_SHIFT 16 +#define VIDFREQ_P1_MASK 0x00001f00 +#define VIDFREQ_P1_SHIFT 8 +#define VIDFREQ_P1_CSCLK_MASK 0x000000f0 +#define VIDFREQ_P1_CSCLK_SHIFT 4 +#define VIDFREQ_P1_CRCLK_MASK 0x0000000f +#define INTTOEXT_BASE_ILK 0x11300 +#define INTTOEXT_BASE 0x11120 /* INTTOEXT1-8 (0x1113c) */ +#define INTTOEXT_MAP3_SHIFT 24 +#define INTTOEXT_MAP3_MASK (0x1f << INTTOEXT_MAP3_SHIFT) +#define INTTOEXT_MAP2_SHIFT 16 +#define INTTOEXT_MAP2_MASK (0x1f << INTTOEXT_MAP2_SHIFT) +#define INTTOEXT_MAP1_SHIFT 8 +#define INTTOEXT_MAP1_MASK (0x1f << INTTOEXT_MAP1_SHIFT) +#define INTTOEXT_MAP0_SHIFT 0 +#define INTTOEXT_MAP0_MASK (0x1f << INTTOEXT_MAP0_SHIFT) +#define MEMSWCTL 0x11170 /* Ironlake only */ +#define MEMCTL_CMD_MASK 0xe000 +#define MEMCTL_CMD_SHIFT 13 +#define MEMCTL_CMD_RCLK_OFF 0 +#define MEMCTL_CMD_RCLK_ON 1 +#define MEMCTL_CMD_CHFREQ 2 +#define MEMCTL_CMD_CHVID 3 +#define MEMCTL_CMD_VMMOFF 4 +#define MEMCTL_CMD_VMMON 5 +#define MEMCTL_CMD_STS (1<<12) /* write 1 triggers command, clears + when command complete */ +#define MEMCTL_FREQ_MASK 0x0f00 /* jitter, from 0-15 */ +#define MEMCTL_FREQ_SHIFT 8 +#define MEMCTL_SFCAVM (1<<7) +#define MEMCTL_TGT_VID_MASK 0x007f +#define MEMIHYST 0x1117c +#define MEMINTREN 0x11180 /* 16 bits */ +#define MEMINT_RSEXIT_EN (1<<8) +#define MEMINT_CX_SUPR_EN (1<<7) +#define MEMINT_CONT_BUSY_EN (1<<6) +#define MEMINT_AVG_BUSY_EN (1<<5) +#define MEMINT_EVAL_CHG_EN (1<<4) +#define MEMINT_MON_IDLE_EN (1<<3) +#define MEMINT_UP_EVAL_EN (1<<2) +#define MEMINT_DOWN_EVAL_EN (1<<1) +#define MEMINT_SW_CMD_EN (1<<0) +#define MEMINTRSTR 0x11182 /* 16 bits */ +#define MEM_RSEXIT_MASK 0xc000 +#define MEM_RSEXIT_SHIFT 14 +#define MEM_CONT_BUSY_MASK 0x3000 +#define MEM_CONT_BUSY_SHIFT 12 +#define MEM_AVG_BUSY_MASK 0x0c00 +#define MEM_AVG_BUSY_SHIFT 10 +#define MEM_EVAL_CHG_MASK 0x0300 +#define MEM_EVAL_BUSY_SHIFT 8 +#define MEM_MON_IDLE_MASK 0x00c0 +#define MEM_MON_IDLE_SHIFT 6 +#define MEM_UP_EVAL_MASK 0x0030 +#define MEM_UP_EVAL_SHIFT 4 +#define MEM_DOWN_EVAL_MASK 0x000c +#define MEM_DOWN_EVAL_SHIFT 2 +#define MEM_SW_CMD_MASK 0x0003 +#define MEM_INT_STEER_GFX 0 +#define MEM_INT_STEER_CMR 1 +#define MEM_INT_STEER_SMI 2 +#define MEM_INT_STEER_SCI 3 +#define MEMINTRSTS 0x11184 +#define MEMINT_RSEXIT (1<<7) +#define MEMINT_CONT_BUSY (1<<6) +#define MEMINT_AVG_BUSY (1<<5) +#define MEMINT_EVAL_CHG (1<<4) +#define MEMINT_MON_IDLE (1<<3) +#define MEMINT_UP_EVAL (1<<2) +#define MEMINT_DOWN_EVAL (1<<1) +#define MEMINT_SW_CMD (1<<0) +#define MEMMODECTL 0x11190 +#define MEMMODE_BOOST_EN (1<<31) +#define MEMMODE_BOOST_FREQ_MASK 0x0f000000 /* jitter for boost, 0-15 */ +#define MEMMODE_BOOST_FREQ_SHIFT 24 +#define MEMMODE_IDLE_MODE_MASK 0x00030000 +#define MEMMODE_IDLE_MODE_SHIFT 16 +#define MEMMODE_IDLE_MODE_EVAL 0 +#define MEMMODE_IDLE_MODE_CONT 1 +#define MEMMODE_HWIDLE_EN (1<<15) +#define MEMMODE_SWMODE_EN (1<<14) +#define MEMMODE_RCLK_GATE (1<<13) +#define MEMMODE_HW_UPDATE (1<<12) +#define MEMMODE_FSTART_MASK 0x00000f00 /* starting jitter, 0-15 */ +#define MEMMODE_FSTART_SHIFT 8 +#define MEMMODE_FMAX_MASK 0x000000f0 /* max jitter, 0-15 */ +#define MEMMODE_FMAX_SHIFT 4 +#define MEMMODE_FMIN_MASK 0x0000000f /* min jitter, 0-15 */ +#define RCBMAXAVG 0x1119c +#define MEMSWCTL2 0x1119e /* Cantiga only */ +#define SWMEMCMD_RENDER_OFF (0 << 13) +#define SWMEMCMD_RENDER_ON (1 << 13) +#define SWMEMCMD_SWFREQ (2 << 13) +#define SWMEMCMD_TARVID (3 << 13) +#define SWMEMCMD_VRM_OFF (4 << 13) +#define SWMEMCMD_VRM_ON (5 << 13) +#define CMDSTS (1<<12) +#define SFCAVM (1<<11) +#define SWFREQ_MASK 0x0380 /* P0-7 */ +#define SWFREQ_SHIFT 7 +#define TARVID_MASK 0x001f +#define MEMSTAT_CTG 0x111a0 +#define RCBMINAVG 0x111a0 +#define RCUPEI 0x111b0 +#define RCDNEI 0x111b4 +#define RSTDBYCTL 0x111b8 +#define RS1EN (1<<31) +#define RS2EN (1<<30) +#define RS3EN (1<<29) +#define D3RS3EN (1<<28) /* Display D3 imlies RS3 */ +#define SWPROMORSX (1<<27) /* RSx promotion timers ignored */ +#define RCWAKERW (1<<26) /* Resetwarn from PCH causes wakeup */ +#define DPRSLPVREN (1<<25) /* Fast voltage ramp enable */ +#define GFXTGHYST (1<<24) /* Hysteresis to allow trunk gating */ +#define RCX_SW_EXIT (1<<23) /* Leave RSx and prevent re-entry */ +#define RSX_STATUS_MASK (7<<20) +#define RSX_STATUS_ON (0<<20) +#define RSX_STATUS_RC1 (1<<20) +#define RSX_STATUS_RC1E (2<<20) +#define RSX_STATUS_RS1 (3<<20) +#define RSX_STATUS_RS2 (4<<20) /* aka rc6 */ +#define RSX_STATUS_RSVD (5<<20) /* deep rc6 unsupported on ilk */ +#define RSX_STATUS_RS3 (6<<20) /* rs3 unsupported on ilk */ +#define RSX_STATUS_RSVD2 (7<<20) +#define UWRCRSXE (1<<19) /* wake counter limit prevents rsx */ +#define RSCRP (1<<18) /* rs requests control on rs1/2 reqs */ +#define JRSC (1<<17) /* rsx coupled to cpu c-state */ +#define RS2INC0 (1<<16) /* allow rs2 in cpu c0 */ +#define RS1CONTSAV_MASK (3<<14) +#define RS1CONTSAV_NO_RS1 (0<<14) /* rs1 doesn't save/restore context */ +#define RS1CONTSAV_RSVD (1<<14) +#define RS1CONTSAV_SAVE_RS1 (2<<14) /* rs1 saves context */ +#define RS1CONTSAV_FULL_RS1 (3<<14) /* rs1 saves and restores context */ +#define NORMSLEXLAT_MASK (3<<12) +#define SLOW_RS123 (0<<12) +#define SLOW_RS23 (1<<12) +#define SLOW_RS3 (2<<12) +#define NORMAL_RS123 (3<<12) +#define RCMODE_TIMEOUT (1<<11) /* 0 is eval interval method */ +#define IMPROMOEN (1<<10) /* promo is immediate or delayed until next idle interval (only for timeout method above) */ +#define RCENTSYNC (1<<9) /* rs coupled to cpu c-state (3/6/7) */ +#define STATELOCK (1<<7) /* locked to rs_cstate if 0 */ +#define RS_CSTATE_MASK (3<<4) +#define RS_CSTATE_C367_RS1 (0<<4) +#define RS_CSTATE_C36_RS1_C7_RS2 (1<<4) +#define RS_CSTATE_RSVD (2<<4) +#define RS_CSTATE_C367_RS2 (3<<4) +#define REDSAVES (1<<3) /* no context save if was idle during rs0 */ +#define REDRESTORES (1<<2) /* no restore if was idle during rs0 */ +#define VIDCTL 0x111c0 +#define VIDSTS 0x111c8 +#define VIDSTART 0x111cc /* 8 bits */ +#define MEMSTAT_ILK 0x111f8 +#define MEMSTAT_VID_MASK 0x7f00 +#define MEMSTAT_VID_SHIFT 8 +#define MEMSTAT_PSTATE_MASK 0x00f8 +#define MEMSTAT_PSTATE_SHIFT 3 +#define MEMSTAT_MON_ACTV (1<<2) +#define MEMSTAT_SRC_CTL_MASK 0x0003 +#define MEMSTAT_SRC_CTL_CORE 0 +#define MEMSTAT_SRC_CTL_TRB 1 +#define MEMSTAT_SRC_CTL_THM 2 +#define MEMSTAT_SRC_CTL_STDBY 3 +#define RCPREVBSYTUPAVG 0x113b8 +#define RCPREVBSYTDNAVG 0x113bc +#define PMMISC 0x11214 +#define MCPPCE_EN (1<<0) /* enable PM_MSG from PCH->MPC */ +#define SDEW 0x1124c +#define CSIEW0 0x11250 +#define CSIEW1 0x11254 +#define CSIEW2 0x11258 +#define PEW 0x1125c +#define DEW 0x11270 +#define MCHAFE 0x112c0 +#define CSIEC 0x112e0 +#define DMIEC 0x112e4 +#define DDREC 0x112e8 +#define PEG0EC 0x112ec +#define PEG1EC 0x112f0 +#define GFXEC 0x112f4 +#define RPPREVBSYTUPAVG 0x113b8 +#define RPPREVBSYTDNAVG 0x113bc +#define ECR 0x11600 +#define ECR_GPFE (1<<31) +#define ECR_IMONE (1<<30) +#define ECR_CAP_MASK 0x0000001f /* Event range, 0-31 */ +#define OGW0 0x11608 +#define OGW1 0x1160c +#define EG0 0x11610 +#define EG1 0x11614 +#define EG2 0x11618 +#define EG3 0x1161c +#define EG4 0x11620 +#define EG5 0x11624 +#define EG6 0x11628 +#define EG7 0x1162c +#define PXW 0x11664 +#define PXWL 0x11680 +#define LCFUSE02 0x116c0 +#define LCFUSE_HIV_MASK 0x000000ff +#define CSIPLL0 0x12c10 +#define DDRMPLL1 0X12c20 +#define PEG_BAND_GAP_DATA 0x14d68 + +#define GEN6_GT_THREAD_STATUS_REG 0x13805c +#define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7 +#define GEN6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16)) + +#define GEN6_GT_PERF_STATUS (MCHBAR_MIRROR_BASE_SNB + 0x5948) +#define GEN6_RP_STATE_LIMITS (MCHBAR_MIRROR_BASE_SNB + 0x5994) +#define GEN6_RP_STATE_CAP (MCHBAR_MIRROR_BASE_SNB + 0x5998) + +/* + * Logical Context regs + */ +#define CCID 0x2180 +#define CCID_EN (1<<0) +/* + * Notes on SNB/IVB/VLV context size: + * - Power context is saved elsewhere (LLC or stolen) + * - Ring/execlist context is saved on SNB, not on IVB + * - Extended context size already includes render context size + * - We always need to follow the extended context size. + * SNB BSpec has comments indicating that we should use the + * render context size instead if execlists are disabled, but + * based on empirical testing that's just nonsense. + * - Pipelined/VF state is saved on SNB/IVB respectively + * - GT1 size just indicates how much of render context + * doesn't need saving on GT1 + */ +#define CXT_SIZE 0x21a0 +#define GEN6_CXT_POWER_SIZE(cxt_reg) ((cxt_reg >> 24) & 0x3f) +#define GEN6_CXT_RING_SIZE(cxt_reg) ((cxt_reg >> 18) & 0x3f) +#define GEN6_CXT_RENDER_SIZE(cxt_reg) ((cxt_reg >> 12) & 0x3f) +#define GEN6_CXT_EXTENDED_SIZE(cxt_reg) ((cxt_reg >> 6) & 0x3f) +#define GEN6_CXT_PIPELINE_SIZE(cxt_reg) ((cxt_reg >> 0) & 0x3f) +#define GEN6_CXT_TOTAL_SIZE(cxt_reg) (GEN6_CXT_RING_SIZE(cxt_reg) + \ + GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \ + GEN6_CXT_PIPELINE_SIZE(cxt_reg)) +#define GEN7_CXT_SIZE 0x21a8 +#define GEN7_CXT_POWER_SIZE(ctx_reg) ((ctx_reg >> 25) & 0x7f) +#define GEN7_CXT_RING_SIZE(ctx_reg) ((ctx_reg >> 22) & 0x7) +#define GEN7_CXT_RENDER_SIZE(ctx_reg) ((ctx_reg >> 16) & 0x3f) +#define GEN7_CXT_EXTENDED_SIZE(ctx_reg) ((ctx_reg >> 9) & 0x7f) +#define GEN7_CXT_GT1_SIZE(ctx_reg) ((ctx_reg >> 6) & 0x7) +#define GEN7_CXT_VFSTATE_SIZE(ctx_reg) ((ctx_reg >> 0) & 0x3f) +#define GEN7_CXT_TOTAL_SIZE(ctx_reg) (GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \ + GEN7_CXT_VFSTATE_SIZE(ctx_reg)) +/* Haswell does have the CXT_SIZE register however it does not appear to be + * valid. Now, docs explain in dwords what is in the context object. The full + * size is 70720 bytes, however, the power context and execlist context will + * never be saved (power context is stored elsewhere, and execlists don't work + * on HSW) - so the final size is 66944 bytes, which rounds to 17 pages. + */ +#define HSW_CXT_TOTAL_SIZE (17 * PAGE_SIZE) +/* Same as Haswell, but 72064 bytes now. */ +#define GEN8_CXT_TOTAL_SIZE (18 * PAGE_SIZE) + +/* CSC Control Register */ +#define _PIPEACSC (dev_priv->info.display_mmio_offset + 0x600b0) +#define _PIPEBCSC (dev_priv->info.display_mmio_offset + 0x610b0) +#define _CHV_PIPECCSC (dev_priv->info.display_mmio_offset + 0x630b0) +#define PIPECONF_CSC_ENABLE (1<<15) + +#define CHV_CLK_CTL1 0x101100 +#define VLV_CLK_CTL2 0x101104 +#define CLK_CTL2_CZCOUNT_30NS_SHIFT 28 + +/* + * Overlay regs + */ + +#define OVADD 0x30000 +#define DOVSTA 0x30008 +#define OC_BUF (0x3<<20) +#define OGAMC5 0x30010 +#define OGAMC4 0x30014 +#define OGAMC3 0x30018 +#define OGAMC2 0x3001c +#define OGAMC1 0x30020 +#define OGAMC0 0x30024 + +/* + * Display engine regs + */ + +/* Pipe A CRC regs */ +#define _PIPE_CRC_CTL_A 0x60050 +#define PIPE_CRC_ENABLE (1 << 31) +/* ivb+ source selection */ +#define PIPE_CRC_SOURCE_PRIMARY_IVB (0 << 29) +#define PIPE_CRC_SOURCE_SPRITE_IVB (1 << 29) +#define PIPE_CRC_SOURCE_PF_IVB (2 << 29) +/* ilk+ source selection */ +#define PIPE_CRC_SOURCE_PRIMARY_ILK (0 << 28) +#define PIPE_CRC_SOURCE_SPRITE_ILK (1 << 28) +#define PIPE_CRC_SOURCE_PIPE_ILK (2 << 28) +/* embedded DP port on the north display block, reserved on ivb */ +#define PIPE_CRC_SOURCE_PORT_A_ILK (4 << 28) +#define PIPE_CRC_SOURCE_FDI_ILK (5 << 28) /* reserved on ivb */ +/* vlv source selection */ +#define PIPE_CRC_SOURCE_PIPE_VLV (0 << 27) +#define PIPE_CRC_SOURCE_HDMIB_VLV (1 << 27) +#define PIPE_CRC_SOURCE_HDMIC_VLV (2 << 27) +/* with DP port the pipe source is invalid */ +#define PIPE_CRC_SOURCE_DP_D_VLV (3 << 27) +#define PIPE_CRC_SOURCE_DP_B_VLV (6 << 27) +#define PIPE_CRC_SOURCE_DP_C_VLV (7 << 27) +/* gen3+ source selection */ +#define PIPE_CRC_SOURCE_PIPE_I9XX (0 << 28) +#define PIPE_CRC_SOURCE_SDVOB_I9XX (1 << 28) +#define PIPE_CRC_SOURCE_SDVOC_I9XX (2 << 28) +/* with DP/TV port the pipe source is invalid */ +#define PIPE_CRC_SOURCE_DP_D_G4X (3 << 28) +#define PIPE_CRC_SOURCE_TV_PRE (4 << 28) +#define PIPE_CRC_SOURCE_TV_POST (5 << 28) +#define PIPE_CRC_SOURCE_DP_B_G4X (6 << 28) +#define PIPE_CRC_SOURCE_DP_C_G4X (7 << 28) +/* gen2 doesn't have source selection bits */ +#define PIPE_CRC_INCLUDE_BORDER_I8XX (1 << 30) + +#define _PIPE_CRC_RES_1_A_IVB 0x60064 +#define _PIPE_CRC_RES_2_A_IVB 0x60068 +#define _PIPE_CRC_RES_3_A_IVB 0x6006c +#define _PIPE_CRC_RES_4_A_IVB 0x60070 +#define _PIPE_CRC_RES_5_A_IVB 0x60074 + +#define _PIPE_CRC_RES_RED_A 0x60060 +#define _PIPE_CRC_RES_GREEN_A 0x60064 +#define _PIPE_CRC_RES_BLUE_A 0x60068 +#define _PIPE_CRC_RES_RES1_A_I915 0x6006c +#define _PIPE_CRC_RES_RES2_A_G4X 0x60080 + +/* Pipe B CRC regs */ +#define _PIPE_CRC_RES_1_B_IVB 0x61064 +#define _PIPE_CRC_RES_2_B_IVB 0x61068 +#define _PIPE_CRC_RES_3_B_IVB 0x6106c +#define _PIPE_CRC_RES_4_B_IVB 0x61070 +#define _PIPE_CRC_RES_5_B_IVB 0x61074 + +#define PIPE_CRC_CTL(pipe) _TRANSCODER2(pipe, _PIPE_CRC_CTL_A) +#define PIPE_CRC_RES_1_IVB(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_1_A_IVB) +#define PIPE_CRC_RES_2_IVB(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_2_A_IVB) +#define PIPE_CRC_RES_3_IVB(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_3_A_IVB) +#define PIPE_CRC_RES_4_IVB(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_4_A_IVB) +#define PIPE_CRC_RES_5_IVB(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_5_A_IVB) + +#define PIPE_CRC_RES_RED(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_RED_A) +#define PIPE_CRC_RES_GREEN(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_GREEN_A) +#define PIPE_CRC_RES_BLUE(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_BLUE_A) +#define PIPE_CRC_RES_RES1_I915(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_RES1_A_I915) +#define PIPE_CRC_RES_RES2_G4X(pipe) \ + _TRANSCODER2(pipe, _PIPE_CRC_RES_RES2_A_G4X) + +/* Pipe A timing regs */ +#define _HTOTAL_A 0x60000 +#define _HBLANK_A 0x60004 +#define _HSYNC_A 0x60008 +#define _VTOTAL_A 0x6000c +#define _VBLANK_A 0x60010 +#define _VSYNC_A 0x60014 +#define _PIPEASRC 0x6001c +#define _BCLRPAT_A 0x60020 +#define _VSYNCSHIFT_A 0x60028 + +/* Pipe B timing regs */ +#define _HTOTAL_B 0x61000 +#define _HBLANK_B 0x61004 +#define _HSYNC_B 0x61008 +#define _VTOTAL_B 0x6100c +#define _VBLANK_B 0x61010 +#define _VSYNC_B 0x61014 +#define _PIPEBSRC 0x6101c +#define _BCLRPAT_B 0x61020 +#define _VSYNCSHIFT_B 0x61028 + +#define TRANSCODER_A_OFFSET 0x60000 +#define TRANSCODER_B_OFFSET 0x61000 +#define TRANSCODER_C_OFFSET 0x62000 +#define CHV_TRANSCODER_C_OFFSET 0x63000 +#define TRANSCODER_EDP_OFFSET 0x6f000 + +#define _TRANSCODER2(pipe, reg) (dev_priv->info.trans_offsets[(pipe)] - \ + dev_priv->info.trans_offsets[TRANSCODER_A] + (reg) + \ + dev_priv->info.display_mmio_offset) + +#define HTOTAL(trans) _TRANSCODER2(trans, _HTOTAL_A) +#define HBLANK(trans) _TRANSCODER2(trans, _HBLANK_A) +#define HSYNC(trans) _TRANSCODER2(trans, _HSYNC_A) +#define VTOTAL(trans) _TRANSCODER2(trans, _VTOTAL_A) +#define VBLANK(trans) _TRANSCODER2(trans, _VBLANK_A) +#define VSYNC(trans) _TRANSCODER2(trans, _VSYNC_A) +#define BCLRPAT(trans) _TRANSCODER2(trans, _BCLRPAT_A) +#define VSYNCSHIFT(trans) _TRANSCODER2(trans, _VSYNCSHIFT_A) +#define PIPESRC(trans) _TRANSCODER2(trans, _PIPEASRC) + +/* HSW+ eDP PSR registers */ +#define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800) +#define EDP_PSR_CTL(dev) (EDP_PSR_BASE(dev) + 0) +#define EDP_PSR_ENABLE (1<<31) +#define EDP_PSR_LINK_DISABLE (0<<27) +#define EDP_PSR_LINK_STANDBY (1<<27) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3<<25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES (0<<25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_4_LINES (1<<25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_2_LINES (2<<25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_0_LINES (3<<25) +#define EDP_PSR_MAX_SLEEP_TIME_SHIFT 20 +#define EDP_PSR_SKIP_AUX_EXIT (1<<12) +#define EDP_PSR_TP1_TP2_SEL (0<<11) +#define EDP_PSR_TP1_TP3_SEL (1<<11) +#define EDP_PSR_TP2_TP3_TIME_500us (0<<8) +#define EDP_PSR_TP2_TP3_TIME_100us (1<<8) +#define EDP_PSR_TP2_TP3_TIME_2500us (2<<8) +#define EDP_PSR_TP2_TP3_TIME_0us (3<<8) +#define EDP_PSR_TP1_TIME_500us (0<<4) +#define EDP_PSR_TP1_TIME_100us (1<<4) +#define EDP_PSR_TP1_TIME_2500us (2<<4) +#define EDP_PSR_TP1_TIME_0us (3<<4) +#define EDP_PSR_IDLE_FRAME_SHIFT 0 + +#define EDP_PSR_AUX_CTL(dev) (EDP_PSR_BASE(dev) + 0x10) +#define EDP_PSR_AUX_DATA1(dev) (EDP_PSR_BASE(dev) + 0x14) +#define EDP_PSR_DPCD_COMMAND 0x80060000 +#define EDP_PSR_AUX_DATA2(dev) (EDP_PSR_BASE(dev) + 0x18) +#define EDP_PSR_DPCD_NORMAL_OPERATION (1<<24) +#define EDP_PSR_AUX_DATA3(dev) (EDP_PSR_BASE(dev) + 0x1c) +#define EDP_PSR_AUX_DATA4(dev) (EDP_PSR_BASE(dev) + 0x20) +#define EDP_PSR_AUX_DATA5(dev) (EDP_PSR_BASE(dev) + 0x24) + +#define EDP_PSR_STATUS_CTL(dev) (EDP_PSR_BASE(dev) + 0x40) +#define EDP_PSR_STATUS_STATE_MASK (7<<29) +#define EDP_PSR_STATUS_STATE_IDLE (0<<29) +#define EDP_PSR_STATUS_STATE_SRDONACK (1<<29) +#define EDP_PSR_STATUS_STATE_SRDENT (2<<29) +#define EDP_PSR_STATUS_STATE_BUFOFF (3<<29) +#define EDP_PSR_STATUS_STATE_BUFON (4<<29) +#define EDP_PSR_STATUS_STATE_AUXACK (5<<29) +#define EDP_PSR_STATUS_STATE_SRDOFFACK (6<<29) +#define EDP_PSR_STATUS_LINK_MASK (3<<26) +#define EDP_PSR_STATUS_LINK_FULL_OFF (0<<26) +#define EDP_PSR_STATUS_LINK_FULL_ON (1<<26) +#define EDP_PSR_STATUS_LINK_STANDBY (2<<26) +#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT 20 +#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK 0x1f +#define EDP_PSR_STATUS_COUNT_SHIFT 16 +#define EDP_PSR_STATUS_COUNT_MASK 0xf +#define EDP_PSR_STATUS_AUX_ERROR (1<<15) +#define EDP_PSR_STATUS_AUX_SENDING (1<<12) +#define EDP_PSR_STATUS_SENDING_IDLE (1<<9) +#define EDP_PSR_STATUS_SENDING_TP2_TP3 (1<<8) +#define EDP_PSR_STATUS_SENDING_TP1 (1<<4) +#define EDP_PSR_STATUS_IDLE_MASK 0xf + +#define EDP_PSR_PERF_CNT(dev) (EDP_PSR_BASE(dev) + 0x44) +#define EDP_PSR_PERF_CNT_MASK 0xffffff + +#define EDP_PSR_DEBUG_CTL(dev) (EDP_PSR_BASE(dev) + 0x60) +#define EDP_PSR_DEBUG_MASK_LPSP (1<<27) +#define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) +#define EDP_PSR_DEBUG_MASK_HPD (1<<25) + +/* VLV/CHV PSR control registers */ +#define _VLV_PIPEA_EDP_PSR_CTL 0x60090 +#define _CHV_PIPEB_EDP_PSR_CTL 0x61090 +#define VLV_PSR_IDENTICAL_FRAMES 15 +#define VLV_PSR_IDENTICAL_FRAMES_SHIFT 16 +#define VLV_PSR_IDENTICAL_FRAMES_MASK (0xff << 16) +#define VLV_PSR_DOUBLE_FRAME_ENABLE (1 << 10) +#define VLV_PSR_SRC_TRANSMITTER_STATE (1 << 9) +#define VLV_PSR_ACTIVE_ENTRY (1 << 8) +#define VLV_PSR_SINGLE_FRAME_UPDATE (1 << 7) +#define VLV_PSR_MODE_SHIFT 2 +#define VLV_PSR_MODE_MASK (0x07 << VLV_PSR_MODE_SHIFT) +#define VLV_PSR_HW_MODE 2 +#define VLV_PSR_SW_MODE 1 +#define VLV_PSR_RESET (1 << 1) +#define VLV_PSR_ENABLE (1 << 0) +#define VLV_EDP_PSR_CONTROL(pipe) (VLV_DISPLAY_BASE + \ + (_PIPE((pipe), _VLV_PIPEA_EDP_PSR_CTL, _CHV_PIPEB_EDP_PSR_CTL))) + +#define VLV_EDP_PSR_STATUS(pipe) (VLV_EDP_PSR_CONTROL(pipe) + 0x04) +#define VLV_PSR_SRC_STANDBY_STATE_SHIFT 30 +#define VLV_PSR_SRC_STANDBY_STATE_MASK 0x03 +#define VLV_PSR_IN_TRANSITION (1 << 7) +#define VLV_PSR_PREV_STATE_SHIFT 3 +#define VLV_PSR_CUR_STATE_SHIFT 0 +#define VLV_PSR_STATE_MASK 0x07 +#define VLV_PSR_INACTIVE 0x01 +#define VLV_PSR_TRANSIT_TO_ACTIVE 0x02 +#define VLV_PSR_ACTIVE_NO_RFB 0x03 +#define VLV_PSR_ACTIVE_SFU 0x04 +#define VLV_PSR_EXIT 0x05 + +#define VLV_EDP_PSR_CRC1(pipe) (VLV_EDP_PSR_CONTROL(pipe) + 0x08) +#define VLV_EDP_PSR_CRC2(pipe) (VLV_EDP_PSR_CONTROL(pipe) + 0x0C) +#define VLV_EDP_PSR_VSC_SDP(pipe) (VLV_EDP_PSR_CONTROL(pipe) + 0x10) +#define VLV_PSR_SDP_SEND_FREQ_MASK (0x03 << 30) +#define VLV_PSR_SDP_SEND_EVFRAME (1 << 30) +#define VLV_PSR_SDP_SEND_ONCE (2 << 30) + +#define VLV_PSR_ENABLE_DELAY 1000 +#define VLV_CHICKEN2_BIT_REG (VLV_DISPLAY_BASE + 0x70404) +#define DPLL_OK_IGNORE_BIT (1 << 12) + +#define VLV_PSR_CLK_GATE (VLV_DISPLAY_BASE + 0x6204) +#define CLK_GATE_DISABLE_ALL 0xffffffff + +/* VGA port control */ +#define ADPA 0x61100 +#define PCH_ADPA 0xe1100 +#define VLV_ADPA (VLV_DISPLAY_BASE + ADPA) + +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_PIPE_SELECT(pipe) ((pipe) << 30) +/* CPT uses bits 29:30 for pch transcoder select */ +#define ADPA_CRT_HOTPLUG_MASK 0x03ff0000 /* bit 25-16 */ +#define ADPA_CRT_HOTPLUG_MONITOR_NONE (0<<24) +#define ADPA_CRT_HOTPLUG_MONITOR_MASK (3<<24) +#define ADPA_CRT_HOTPLUG_MONITOR_COLOR (3<<24) +#define ADPA_CRT_HOTPLUG_MONITOR_MONO (2<<24) +#define ADPA_CRT_HOTPLUG_ENABLE (1<<23) +#define ADPA_CRT_HOTPLUG_PERIOD_64 (0<<22) +#define ADPA_CRT_HOTPLUG_PERIOD_128 (1<<22) +#define ADPA_CRT_HOTPLUG_WARMUP_5MS (0<<21) +#define ADPA_CRT_HOTPLUG_WARMUP_10MS (1<<21) +#define ADPA_CRT_HOTPLUG_SAMPLE_2S (0<<20) +#define ADPA_CRT_HOTPLUG_SAMPLE_4S (1<<20) +#define ADPA_CRT_HOTPLUG_VOLTAGE_40 (0<<18) +#define ADPA_CRT_HOTPLUG_VOLTAGE_50 (1<<18) +#define ADPA_CRT_HOTPLUG_VOLTAGE_60 (2<<18) +#define ADPA_CRT_HOTPLUG_VOLTAGE_70 (3<<18) +#define ADPA_CRT_HOTPLUG_VOLREF_325MV (0<<17) +#define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17) +#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<10) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<11) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 +#define ADPA_DPMS_MASK (~(3<<10)) +#define ADPA_DPMS_ON (0<<10) +#define ADPA_DPMS_SUSPEND (1<<10) +#define ADPA_DPMS_STANDBY (2<<10) +#define ADPA_DPMS_OFF (3<<10) + + +/* Hotplug control (945+ only) */ +#define PORT_HOTPLUG_EN (dev_priv->info.display_mmio_offset + 0x61110) +#define PORTB_HOTPLUG_INT_EN (1 << 29) +#define PORTC_HOTPLUG_INT_EN (1 << 28) +#define PORTD_HOTPLUG_INT_EN (1 << 27) +#define SDVOB_HOTPLUG_INT_EN (1 << 26) +#define SDVOC_HOTPLUG_INT_EN (1 << 25) +#define TV_HOTPLUG_INT_EN (1 << 18) +#define CRT_HOTPLUG_INT_EN (1 << 9) +#define HOTPLUG_INT_EN_MASK (PORTB_HOTPLUG_INT_EN | \ + PORTC_HOTPLUG_INT_EN | \ + PORTD_HOTPLUG_INT_EN | \ + SDVOC_HOTPLUG_INT_EN | \ + SDVOB_HOTPLUG_INT_EN | \ + CRT_HOTPLUG_INT_EN) +#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) +#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) +/* must use period 64 on GM45 according to docs */ +#define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8) +#define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7) +#define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5) +#define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4) +#define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) +#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) +#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) + +#define PORT_HOTPLUG_STAT (dev_priv->info.display_mmio_offset + 0x61114) +/* + * HDMI/DP bits are gen4+ + * + * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused. + * Please check the detailed lore in the commit message for for experimental + * evidence. + */ +#define PORTD_HOTPLUG_LIVE_STATUS_G4X (1 << 29) +#define PORTC_HOTPLUG_LIVE_STATUS_G4X (1 << 28) +#define PORTB_HOTPLUG_LIVE_STATUS_G4X (1 << 27) +/* VLV DP/HDMI bits again match Bspec */ +#define PORTD_HOTPLUG_LIVE_STATUS_VLV (1 << 27) +#define PORTC_HOTPLUG_LIVE_STATUS_VLV (1 << 28) +#define PORTB_HOTPLUG_LIVE_STATUS_VLV (1 << 29) +#define PORTD_HOTPLUG_INT_STATUS (3 << 21) +#define PORTC_HOTPLUG_INT_STATUS (3 << 19) +#define PORTB_HOTPLUG_INT_STATUS (3 << 17) +/* CRT/TV common between gen3+ */ +#define CRT_HOTPLUG_INT_STATUS (1 << 11) +#define TV_HOTPLUG_INT_STATUS (1 << 10) +#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +#define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +#define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +#define DP_AUX_CHANNEL_D_INT_STATUS_G4X (1 << 6) +#define DP_AUX_CHANNEL_C_INT_STATUS_G4X (1 << 5) +#define DP_AUX_CHANNEL_B_INT_STATUS_G4X (1 << 4) +#define DP_AUX_CHANNEL_MASK_INT_STATUS_G4X (7 << 4) + +/* SDVO is different across gen3/4 */ +#define SDVOC_HOTPLUG_INT_STATUS_G4X (1 << 3) +#define SDVOB_HOTPLUG_INT_STATUS_G4X (1 << 2) +/* + * Bspec seems to be seriously misleaded about the SDVO hpd bits on i965g/gm, + * since reality corrobates that they're the same as on gen3. But keep these + * bits here (and the comment!) to help any other lost wanderers back onto the + * right tracks. + */ +#define SDVOC_HOTPLUG_INT_STATUS_I965 (3 << 4) +#define SDVOB_HOTPLUG_INT_STATUS_I965 (3 << 2) +#define SDVOC_HOTPLUG_INT_STATUS_I915 (1 << 7) +#define SDVOB_HOTPLUG_INT_STATUS_I915 (1 << 6) +#define HOTPLUG_INT_STATUS_G4X (CRT_HOTPLUG_INT_STATUS | \ + SDVOB_HOTPLUG_INT_STATUS_G4X | \ + SDVOC_HOTPLUG_INT_STATUS_G4X | \ + PORTB_HOTPLUG_INT_STATUS | \ + PORTC_HOTPLUG_INT_STATUS | \ + PORTD_HOTPLUG_INT_STATUS) + +#define HOTPLUG_INT_STATUS_I915 (CRT_HOTPLUG_INT_STATUS | \ + SDVOB_HOTPLUG_INT_STATUS_I915 | \ + SDVOC_HOTPLUG_INT_STATUS_I915 | \ + PORTB_HOTPLUG_INT_STATUS | \ + PORTC_HOTPLUG_INT_STATUS | \ + PORTD_HOTPLUG_INT_STATUS) + +#define HPD_SHORT_PULSE (1<<17) + +/* SDVO and HDMI port control. + * The same register may be used for SDVO or HDMI */ +#define GEN3_SDVOB 0x61140 +#define GEN3_SDVOC 0x61160 +#define HDMIB (dev_priv->info.display_mmio_offset + 0x61140) +#define HDMIC (dev_priv->info.display_mmio_offset + 0x61160) +#define GEN4_HDMIB GEN3_SDVOB +#define GEN4_HDMIC GEN3_SDVOC +#define CHV_HDMID 0x6116C +#define PCH_SDVOB 0xe1140 +#define PCH_HDMIB PCH_SDVOB +#define PCH_HDMIC 0xe1150 +#define PCH_HDMID 0xe1160 +#define PORT_ENABLE (1 << 31) +#define _PORTADDR(dvo_port, b, c, d) ((dvo_port == b) ? GEN4_HDMIB : \ + ((dvo_port == c) ? GEN4_HDMIC : \ + CHV_HDMID)) +#define PORT_DFT_I9XX 0x61150 +#define DC_BALANCE_RESET (1 << 25) +#define PORT_DFT2_G4X 0x61154 +#define DC_BALANCE_RESET_VLV (1 << 31) +#define PIPE_SCRAMBLE_RESET_MASK (0x3 << 0) +#define PIPE_B_SCRAMBLE_RESET (1 << 1) +#define PIPE_A_SCRAMBLE_RESET (1 << 0) +#define PORT_ADDR(dvo_port) _PORTADDR(dvo_port, DVO_PORT_HDMIB,\ + DVO_PORT_HDMIC, DVO_PORT_HDMID) +/* Gen 3 SDVO bits: */ +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_SEL(pipe) ((pipe) << 30) +#define SDVO_PIPE_SEL_MASK (1 << 30) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) +/* + * 915G/GM SDVO pixel multiplier. + * Programmed value is multiplier - 1, up to 5x. + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) /* Port C only */ +#define SDVO_BORDER_ENABLE (1 << 7) /* SDVO only */ +#define SDVOB_PCIE_CONCURRENCY (1 << 3) /* Port B only */ +#define SDVO_DETECTED (1 << 2) +/* Bits to be preserved when writing */ +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | \ + SDVO_INTERRUPT_ENABLE) +#define SDVOC_PRESERVE_MASK ((1 << 17) | SDVO_INTERRUPT_ENABLE) + +/* Gen 4 SDVO/HDMI bits: */ +#define SDVO_COLOR_FORMAT_8bpc (0 << 26) +#define SDVO_COLOR_FORMAT_MASK (7 << 26) +#define SDVO_ENCODING_SDVO (0 << 10) +#define SDVO_ENCODING_HDMI (2 << 10) +#define HDMI_MODE_SELECT_HDMI (1 << 9) /* HDMI only */ +#define HDMI_MODE_SELECT_DVI (0 << 9) /* HDMI only */ +#define HDMI_COLOR_RANGE_16_235 (1 << 8) /* HDMI only */ +#define SDVO_AUDIO_ENABLE (1 << 6) +/* VSYNC/HSYNC bits new with 965, default is to be set */ +#define SDVO_VSYNC_ACTIVE_HIGH (1 << 4) +#define SDVO_HSYNC_ACTIVE_HIGH (1 << 3) + +/* Gen 5 (IBX) SDVO/HDMI bits: */ +#define HDMI_COLOR_FORMAT_12bpc (3 << 26) /* HDMI only */ +#define SDVOB_HOTPLUG_ENABLE (1 << 23) /* SDVO only */ + +/* Gen 6 (CPT) SDVO/HDMI bits: */ +#define SDVO_PIPE_SEL_CPT(pipe) ((pipe) << 29) +#define SDVO_PIPE_SEL_MASK_CPT (3 << 29) + +/* CHV SDVO/HDMI bits: */ +#define SDVO_PIPE_SEL_CHV(pipe) ((pipe) << 24) +#define SDVO_PIPE_SEL_MASK_CHV (3 << 24) + + +/* DVO port control */ +#define DVOA 0x61120 +#define DVOB 0x61140 +#define DVOC 0x61160 +#define DVO_ENABLE (1 << 31) +#define DVO_PIPE_B_SELECT (1 << 30) +#define DVO_PIPE_STALL_UNUSED (0 << 28) +#define DVO_PIPE_STALL (1 << 28) +#define DVO_PIPE_STALL_TV (2 << 28) +#define DVO_PIPE_STALL_MASK (3 << 28) +#define DVO_USE_VGA_SYNC (1 << 15) +#define DVO_DATA_ORDER_I740 (0 << 14) +#define DVO_DATA_ORDER_FP (1 << 14) +#define DVO_VSYNC_DISABLE (1 << 11) +#define DVO_HSYNC_DISABLE (1 << 10) +#define DVO_VSYNC_TRISTATE (1 << 9) +#define DVO_HSYNC_TRISTATE (1 << 8) +#define DVO_BORDER_ENABLE (1 << 7) +#define DVO_DATA_ORDER_GBRG (1 << 6) +#define DVO_DATA_ORDER_RGGB (0 << 6) +#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) +#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) +#define DVO_VSYNC_ACTIVE_HIGH (1 << 4) +#define DVO_HSYNC_ACTIVE_HIGH (1 << 3) +#define DVO_BLANK_ACTIVE_HIGH (1 << 2) +#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ +#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ +#define DVO_PRESERVE_MASK (0x7<<24) +#define DVOA_SRCDIM 0x61124 +#define DVOB_SRCDIM 0x61144 +#define DVOC_SRCDIM 0x61164 +#define DVO_SRCDIM_HORIZONTAL_SHIFT 12 +#define DVO_SRCDIM_VERTICAL_SHIFT 0 + +/* LVDS port control */ +#define LVDS 0x61180 +/* + * Enables the LVDS port. This bit must be set before DPLLs are enabled, as + * the DPLL semantics change when the LVDS is assigned to that pipe. + */ +#define LVDS_PORT_EN (1 << 31) +/* Selects pipe B for LVDS data. Must be set on pre-965. */ +#define LVDS_PIPEB_SELECT (1 << 30) +#define LVDS_PIPE_MASK (1 << 30) +#define LVDS_PIPE(pipe) ((pipe) << 30) +/* LVDS dithering flag on 965/g4x platform */ +#define LVDS_ENABLE_DITHER (1 << 25) +/* LVDS sync polarity flags. Set to invert (i.e. negative) */ +#define LVDS_VSYNC_POLARITY (1 << 21) +#define LVDS_HSYNC_POLARITY (1 << 20) + +/* Enable border for unscaled (or aspect-scaled) display */ +#define LVDS_BORDER_ENABLE (1 << 15) +/* + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per + * pixel. + */ +#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +/* + * Controls the A3 data pair, which contains the additional LSBs for 24 bit + * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be + * on. + */ +#define LVDS_A3_POWER_MASK (3 << 6) +#define LVDS_A3_POWER_DOWN (0 << 6) +#define LVDS_A3_POWER_UP (3 << 6) +/* + * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP + * is set. + */ +#define LVDS_CLKB_POWER_MASK (3 << 4) +#define LVDS_CLKB_POWER_DOWN (0 << 4) +#define LVDS_CLKB_POWER_UP (3 << 4) +/* + * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 + * setting for whether we are in dual-channel mode. The B3 pair will + * additionally only be powered up when LVDS_A3_POWER_UP is set. + */ +#define LVDS_B0B3_POWER_MASK (3 << 2) +#define LVDS_B0B3_POWER_DOWN (0 << 2) +#define LVDS_B0B3_POWER_UP (3 << 2) + +/* Video Data Island Packet control */ +#define VIDEO_DIP_DATA 0x61178 +/* Read the description of VIDEO_DIP_DATA (before Haswel) or VIDEO_DIP_ECC + * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte + * of the infoframe structure specified by CEA-861. */ +#define VIDEO_DIP_DATA_SIZE 32 +#define VIDEO_DIP_VSC_DATA_SIZE 36 +#define VIDEO_DIP_CTL 0x61170 +/* Pre HSW: */ +#define VIDEO_DIP_ENABLE (1 << 31) +#define VIDEO_DIP_PORT(port) ((port) << 29) +#define VIDEO_DIP_PORT_MASK (3 << 29) +#define VIDEO_DIP_ENABLE_GCP (1 << 25) +#define VIDEO_DIP_ENABLE_AVI (1 << 21) +#define VIDEO_DIP_ENABLE_VENDOR (2 << 21) +#define VIDEO_DIP_ENABLE_GAMUT (4 << 21) +#define VIDEO_DIP_ENABLE_SPD (8 << 21) +#define VIDEO_DIP_SELECT_AVI (0 << 19) +#define VIDEO_DIP_SELECT_VENDOR (1 << 19) +#define VIDEO_DIP_SELECT_SPD (3 << 19) +#define VIDEO_DIP_SELECT_MASK (3 << 19) +#define VIDEO_DIP_FREQ_ONCE (0 << 16) +#define VIDEO_DIP_FREQ_VSYNC (1 << 16) +#define VIDEO_DIP_FREQ_2VSYNC (2 << 16) +#define VIDEO_DIP_FREQ_MASK (3 << 16) +/* HSW and later: */ +#define VIDEO_DIP_ENABLE_VSC_HSW (1 << 20) +#define VIDEO_DIP_ENABLE_GCP_HSW (1 << 16) +#define VIDEO_DIP_ENABLE_AVI_HSW (1 << 12) +#define VIDEO_DIP_ENABLE_VS_HSW (1 << 8) +#define VIDEO_DIP_ENABLE_GMP_HSW (1 << 4) +#define VIDEO_DIP_ENABLE_SPD_HSW (1 << 0) + +/* Panel power sequencing */ +#define PP_STATUS 0x61200 +#define PP_ON (1 << 31) +/* + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +#define PP_READY (1 << 30) +#define PP_SEQUENCE_NONE (0 << 28) +#define PP_SEQUENCE_POWER_UP (1 << 28) +#define PP_SEQUENCE_POWER_DOWN (2 << 28) +#define PP_SEQUENCE_MASK (3 << 28) +#define PP_SEQUENCE_SHIFT 28 +#define PP_CYCLE_DELAY_ACTIVE (1 << 27) +#define PP_SEQUENCE_STATE_MASK 0x0000000f +#define PP_SEQUENCE_STATE_OFF_IDLE (0x0 << 0) +#define PP_SEQUENCE_STATE_OFF_S0_1 (0x1 << 0) +#define PP_SEQUENCE_STATE_OFF_S0_2 (0x2 << 0) +#define PP_SEQUENCE_STATE_OFF_S0_3 (0x3 << 0) +#define PP_SEQUENCE_STATE_ON_IDLE (0x8 << 0) +#define PP_SEQUENCE_STATE_ON_S1_0 (0x9 << 0) +#define PP_SEQUENCE_STATE_ON_S1_2 (0xa << 0) +#define PP_SEQUENCE_STATE_ON_S1_3 (0xb << 0) +#define PP_SEQUENCE_STATE_RESET (0xf << 0) +#define PP_CONTROL 0x61204 +#define POWER_TARGET_ON (1 << 0) +#define PP_ON_DELAYS 0x61208 +#define PP_OFF_DELAYS 0x6120c +#define PP_DIVISOR 0x61210 + +/* Panel fitting */ +#define PFIT_CONTROL (dev_priv->info.display_mmio_offset + 0x61230) +#define PFIT_ENABLE (1 << 31) +#define PFIT_DISABLE (0 << 31) +#define PFIT_PIPE_MASK (3 << 29) +#define PFIT_PIPE_SHIFT 29 +#define VERT_INTERP_DISABLE (0 << 10) +#define VERT_INTERP_BILINEAR (1 << 10) +#define VERT_INTERP_MASK (3 << 10) +#define VERT_AUTO_SCALE (1 << 9) +#define HORIZ_INTERP_DISABLE (0 << 6) +#define HORIZ_INTERP_BILINEAR (1 << 6) +#define HORIZ_INTERP_MASK (3 << 6) +#define HORIZ_AUTO_SCALE (1 << 5) +#define PANEL_8TO6_DITHER_ENABLE (1 << 3) +#define PFIT_FILTER_FUZZY (0 << 24) +#define PFIT_SCALING_AUTO (0 << 26) +#define PFIT_SCALING_PROGRAMMED (1 << 26) +#define PFIT_SCALING_PILLAR (2 << 26) +#define PFIT_SCALING_LETTER (3 << 26) +#define MASK_PFIT_SCALING_MODE (0xe3ffffff) +#define PFIT_PGM_RATIOS (dev_priv->info.display_mmio_offset + 0x61234) +#define PFIT_SIZE_LIMIT 2000 +#define SCALING_SRCSIZE_SHIFT 16 +#define SCALING_SRCSIZE_MASK 0xffff +/* Pre-965 */ +#define PFIT_VERT_SCALE_SHIFT 20 +#define PFIT_VERT_SCALE_MASK 0xfff00000 +#define PFIT_HORIZ_SCALE_SHIFT 4 +#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 +/* 965+ */ +#define PFIT_VERT_SCALE_SHIFT_965 16 +#define PFIT_VERT_SCALE_MASK_965 0x1fff0000 +#define PFIT_HORIZ_SCALE_SHIFT_965 0 +#define PFIT_HORIZ_SCALE_MASK_965 0x00001fff + +#define PFIT_AUTO_RATIOS (dev_priv->info.display_mmio_offset + 0x61238) + +#define _VLV_BLC_PWM_CTL2_A (dev_priv->info.display_mmio_offset + 0x61250) +#define _VLV_BLC_PWM_CTL2_B (dev_priv->info.display_mmio_offset + 0x61350) +#define VLV_BLC_PWM_CTL2(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL2_A, \ + _VLV_BLC_PWM_CTL2_B) + +#define _VLV_BLC_PWM_CTL_A (dev_priv->info.display_mmio_offset + 0x61254) +#define _VLV_BLC_PWM_CTL_B (dev_priv->info.display_mmio_offset + 0x61354) +#define VLV_BLC_PWM_CTL(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL_A, \ + _VLV_BLC_PWM_CTL_B) + +#define _VLV_BLC_HIST_CTL_A (dev_priv->info.display_mmio_offset + 0x61260) +#define _VLV_BLC_HIST_CTL_B (dev_priv->info.display_mmio_offset + 0x61360) +#define VLV_BLC_HIST_CTL(pipe) _PIPE(pipe, _VLV_BLC_HIST_CTL_A, \ + _VLV_BLC_HIST_CTL_B) + +#define _VLV_BLC_HIST_BIN_A (dev_priv->info.display_mmio_offset + 0x61264) +#define _VLV_BLC_HIST_BIN_B (dev_priv->info.display_mmio_offset + 0x61364) +#define VLV_BLC_HIST_BIN(pipe) _PIPE(pipe, _VLV_BLC_HIST_BIN_A, \ + _VLV_BLC_HIST_BIN_B) + +#define _VLV_BLC_HIST_GUARD_A (dev_priv->info.display_mmio_offset + 0x61268) +#define _VLV_BLC_HIST_GUARD_B (dev_priv->info.display_mmio_offset + 0x61368) +#define VLV_BLC_HIST_GUARD(pipe) _PIPE(pipe, _VLV_BLC_HIST_GUARD_A, \ + _VLV_BLC_HIST_GUARD_B) + +/* Backlight control */ +#define BLC_PWM_CTL2 (dev_priv->info.display_mmio_offset + 0x61250) /* 965+ only */ +#define BLM_PWM_ENABLE (1 << 31) +#define BLM_COMBINATION_MODE (1 << 30) /* gen4 only */ +#define BLM_PIPE_SELECT (1 << 29) +#define BLM_PIPE_SELECT_IVB (3 << 29) +#define BLM_PIPE_A (0 << 29) +#define BLM_PIPE_B (1 << 29) +#define BLM_PIPE_C (2 << 29) /* ivb + */ +#define BLM_TRANSCODER_A BLM_PIPE_A /* hsw */ +#define BLM_TRANSCODER_B BLM_PIPE_B +#define BLM_TRANSCODER_C BLM_PIPE_C +#define BLM_TRANSCODER_EDP (3 << 29) +#define BLM_PIPE(pipe) ((pipe) << 29) +#define BLM_POLARITY_I965 (1 << 28) /* gen4 only */ +#define BLM_PHASE_IN_INTERUPT_STATUS (1 << 26) +#define BLM_PHASE_IN_ENABLE (1 << 25) +#define BLM_PHASE_IN_INTERUPT_ENABL (1 << 24) +#define BLM_PHASE_IN_TIME_BASE_SHIFT (16) +#define BLM_PHASE_IN_TIME_BASE_MASK (0xff << 16) +#define BLM_PHASE_IN_COUNT_SHIFT (8) +#define BLM_PHASE_IN_COUNT_MASK (0xff << 8) +#define BLM_PHASE_IN_INCR_SHIFT (0) +#define BLM_PHASE_IN_INCR_MASK (0xff << 0) +#define BLC_PWM_CTL (dev_priv->info.display_mmio_offset + 0x61254) +/* + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) /* gen2 only */ +/* + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. + * + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. + */ +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) +#define BACKLIGHT_DUTY_CYCLE_MASK_PNV (0xfffe) +#define BLM_POLARITY_PNV (1 << 0) /* pnv only */ + +#define BLC_HIST_CTL (dev_priv->info.display_mmio_offset + 0x61260) + +/* New registers for PCH-split platforms. Safe where new bits show up, the + * register layout machtes with gen4 BLC_PWM_CTL[12]. */ +#define BLC_PWM_CPU_CTL2 0x48250 +#define BLC_PWM_CPU_CTL 0x48254 + +#define HSW_BLC_PWM2_CTL 0x48350 + +/* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is + * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */ +#define BLC_PWM_PCH_CTL1 0xc8250 +#define BLM_PCH_PWM_ENABLE (1 << 31) +#define BLM_PCH_OVERRIDE_ENABLE (1 << 30) +#define BLM_PCH_POLARITY (1 << 29) +#define BLC_PWM_PCH_CTL2 0xc8254 + +#define UTIL_PIN_CTL 0x48400 +#define UTIL_PIN_ENABLE (1 << 31) + +#define PCH_GTC_CTL 0xe7000 +#define PCH_GTC_ENABLE (1 << 31) + +/* TV port control */ +#define TV_CTL 0x68000 +/* Enables the TV encoder */ +# define TV_ENC_ENABLE (1 << 31) +/* Sources the TV encoder input from pipe B instead of A. */ +# define TV_ENC_PIPEB_SELECT (1 << 30) +/* Outputs composite video (DAC A only) */ +# define TV_ENC_OUTPUT_COMPOSITE (0 << 28) +/* Outputs SVideo video (DAC B/C) */ +# define TV_ENC_OUTPUT_SVIDEO (1 << 28) +/* Outputs Component video (DAC A/B/C) */ +# define TV_ENC_OUTPUT_COMPONENT (2 << 28) +/* Outputs Composite and SVideo (DAC A/B/C) */ +# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28) +# define TV_TRILEVEL_SYNC (1 << 21) +/* Enables slow sync generation (945GM only) */ +# define TV_SLOW_SYNC (1 << 20) +/* Selects 4x oversampling for 480i and 576p */ +# define TV_OVERSAMPLE_4X (0 << 18) +/* Selects 2x oversampling for 720p and 1080i */ +# define TV_OVERSAMPLE_2X (1 << 18) +/* Selects no oversampling for 1080p */ +# define TV_OVERSAMPLE_NONE (2 << 18) +/* Selects 8x oversampling */ +# define TV_OVERSAMPLE_8X (3 << 18) +/* Selects progressive mode rather than interlaced */ +# define TV_PROGRESSIVE (1 << 17) +/* Sets the colorburst to PAL mode. Required for non-M PAL modes. */ +# define TV_PAL_BURST (1 << 16) +/* Field for setting delay of Y compared to C */ +# define TV_YC_SKEW_MASK (7 << 12) +/* Enables a fix for 480p/576p standard definition modes on the 915GM only */ +# define TV_ENC_SDP_FIX (1 << 11) +/* + * Enables a fix for the 915GM only. + * + * Not sure what it does. + */ +# define TV_ENC_C0_FIX (1 << 10) +/* Bits that must be preserved by software */ +# define TV_CTL_SAVE ((1 << 11) | (3 << 9) | (7 << 6) | 0xf) +# define TV_FUSE_STATE_MASK (3 << 4) +/* Read-only state that reports all features enabled */ +# define TV_FUSE_STATE_ENABLED (0 << 4) +/* Read-only state that reports that Macrovision is disabled in hardware*/ +# define TV_FUSE_STATE_NO_MACROVISION (1 << 4) +/* Read-only state that reports that TV-out is disabled in hardware. */ +# define TV_FUSE_STATE_DISABLED (2 << 4) +/* Normal operation */ +# define TV_TEST_MODE_NORMAL (0 << 0) +/* Encoder test pattern 1 - combo pattern */ +# define TV_TEST_MODE_PATTERN_1 (1 << 0) +/* Encoder test pattern 2 - full screen vertical 75% color bars */ +# define TV_TEST_MODE_PATTERN_2 (2 << 0) +/* Encoder test pattern 3 - full screen horizontal 75% color bars */ +# define TV_TEST_MODE_PATTERN_3 (3 << 0) +/* Encoder test pattern 4 - random noise */ +# define TV_TEST_MODE_PATTERN_4 (4 << 0) +/* Encoder test pattern 5 - linear color ramps */ +# define TV_TEST_MODE_PATTERN_5 (5 << 0) +/* + * This test mode forces the DACs to 50% of full output. + * + * This is used for load detection in combination with TVDAC_SENSE_MASK + */ +# define TV_TEST_MODE_MONITOR_DETECT (7 << 0) +# define TV_TEST_MODE_MASK (7 << 0) + +#define TV_DAC 0x68004 +# define TV_DAC_SAVE 0x00ffff00 +/* + * Reports that DAC state change logic has reported change (RO). + * + * This gets cleared when TV_DAC_STATE_EN is cleared +*/ +# define TVDAC_STATE_CHG (1 << 31) +# define TVDAC_SENSE_MASK (7 << 28) +/* Reports that DAC A voltage is above the detect threshold */ +# define TVDAC_A_SENSE (1 << 30) +/* Reports that DAC B voltage is above the detect threshold */ +# define TVDAC_B_SENSE (1 << 29) +/* Reports that DAC C voltage is above the detect threshold */ +# define TVDAC_C_SENSE (1 << 28) +/* + * Enables DAC state detection logic, for load-based TV detection. + * + * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set + * to off, for load detection to work. + */ +# define TVDAC_STATE_CHG_EN (1 << 27) +/* Sets the DAC A sense value to high */ +# define TVDAC_A_SENSE_CTL (1 << 26) +/* Sets the DAC B sense value to high */ +# define TVDAC_B_SENSE_CTL (1 << 25) +/* Sets the DAC C sense value to high */ +# define TVDAC_C_SENSE_CTL (1 << 24) +/* Overrides the ENC_ENABLE and DAC voltage levels */ +# define DAC_CTL_OVERRIDE (1 << 7) +/* Sets the slew rate. Must be preserved in software */ +# define ENC_TVDAC_SLEW_FAST (1 << 6) +# define DAC_A_1_3_V (0 << 4) +# define DAC_A_1_1_V (1 << 4) +# define DAC_A_0_7_V (2 << 4) +# define DAC_A_MASK (3 << 4) +# define DAC_B_1_3_V (0 << 2) +# define DAC_B_1_1_V (1 << 2) +# define DAC_B_0_7_V (2 << 2) +# define DAC_B_MASK (3 << 2) +# define DAC_C_1_3_V (0 << 0) +# define DAC_C_1_1_V (1 << 0) +# define DAC_C_0_7_V (2 << 0) +# define DAC_C_MASK (3 << 0) + +/* + * CSC coefficients are stored in a floating point format with 9 bits of + * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n, + * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with + * -1 (0x3) being the only legal negative value. + */ +#define TV_CSC_Y 0x68010 +# define TV_RY_MASK 0x07ff0000 +# define TV_RY_SHIFT 16 +# define TV_GY_MASK 0x00000fff +# define TV_GY_SHIFT 0 + +#define TV_CSC_Y2 0x68014 +# define TV_BY_MASK 0x07ff0000 +# define TV_BY_SHIFT 16 +/* + * Y attenuation for component video. + * + * Stored in 1.9 fixed point. + */ +# define TV_AY_MASK 0x000003ff +# define TV_AY_SHIFT 0 + +#define TV_CSC_U 0x68018 +# define TV_RU_MASK 0x07ff0000 +# define TV_RU_SHIFT 16 +# define TV_GU_MASK 0x000007ff +# define TV_GU_SHIFT 0 + +#define TV_CSC_U2 0x6801c +# define TV_BU_MASK 0x07ff0000 +# define TV_BU_SHIFT 16 +/* + * U attenuation for component video. + * + * Stored in 1.9 fixed point. + */ +# define TV_AU_MASK 0x000003ff +# define TV_AU_SHIFT 0 + +#define TV_CSC_V 0x68020 +# define TV_RV_MASK 0x0fff0000 +# define TV_RV_SHIFT 16 +# define TV_GV_MASK 0x000007ff +# define TV_GV_SHIFT 0 + +#define TV_CSC_V2 0x68024 +# define TV_BV_MASK 0x07ff0000 +# define TV_BV_SHIFT 16 +/* + * V attenuation for component video. + * + * Stored in 1.9 fixed point. + */ +# define TV_AV_MASK 0x000007ff +# define TV_AV_SHIFT 0 + +#define TV_CLR_KNOBS 0x68028 +/* 2s-complement brightness adjustment */ +# define TV_BRIGHTNESS_MASK 0xff000000 +# define TV_BRIGHTNESS_SHIFT 24 +/* Contrast adjustment, as a 2.6 unsigned floating point number */ +# define TV_CONTRAST_MASK 0x00ff0000 +# define TV_CONTRAST_SHIFT 16 +/* Saturation adjustment, as a 2.6 unsigned floating point number */ +# define TV_SATURATION_MASK 0x0000ff00 +# define TV_SATURATION_SHIFT 8 +/* Hue adjustment, as an integer phase angle in degrees */ +# define TV_HUE_MASK 0x000000ff +# define TV_HUE_SHIFT 0 + +#define TV_CLR_LEVEL 0x6802c +/* Controls the DAC level for black */ +# define TV_BLACK_LEVEL_MASK 0x01ff0000 +# define TV_BLACK_LEVEL_SHIFT 16 +/* Controls the DAC level for blanking */ +# define TV_BLANK_LEVEL_MASK 0x000001ff +# define TV_BLANK_LEVEL_SHIFT 0 + +#define TV_H_CTL_1 0x68030 +/* Number of pixels in the hsync. */ +# define TV_HSYNC_END_MASK 0x1fff0000 +# define TV_HSYNC_END_SHIFT 16 +/* Total number of pixels minus one in the line (display and blanking). */ +# define TV_HTOTAL_MASK 0x00001fff +# define TV_HTOTAL_SHIFT 0 + +#define TV_H_CTL_2 0x68034 +/* Enables the colorburst (needed for non-component color) */ +# define TV_BURST_ENA (1 << 31) +/* Offset of the colorburst from the start of hsync, in pixels minus one. */ +# define TV_HBURST_START_SHIFT 16 +# define TV_HBURST_START_MASK 0x1fff0000 +/* Length of the colorburst */ +# define TV_HBURST_LEN_SHIFT 0 +# define TV_HBURST_LEN_MASK 0x0001fff + +#define TV_H_CTL_3 0x68038 +/* End of hblank, measured in pixels minus one from start of hsync */ +# define TV_HBLANK_END_SHIFT 16 +# define TV_HBLANK_END_MASK 0x1fff0000 +/* Start of hblank, measured in pixels minus one from start of hsync */ +# define TV_HBLANK_START_SHIFT 0 +# define TV_HBLANK_START_MASK 0x0001fff + +#define TV_V_CTL_1 0x6803c +/* XXX */ +# define TV_NBR_END_SHIFT 16 +# define TV_NBR_END_MASK 0x07ff0000 +/* XXX */ +# define TV_VI_END_F1_SHIFT 8 +# define TV_VI_END_F1_MASK 0x00003f00 +/* XXX */ +# define TV_VI_END_F2_SHIFT 0 +# define TV_VI_END_F2_MASK 0x0000003f + +#define TV_V_CTL_2 0x68040 +/* Length of vsync, in half lines */ +# define TV_VSYNC_LEN_MASK 0x07ff0000 +# define TV_VSYNC_LEN_SHIFT 16 +/* Offset of the start of vsync in field 1, measured in one less than the + * number of half lines. + */ +# define TV_VSYNC_START_F1_MASK 0x00007f00 +# define TV_VSYNC_START_F1_SHIFT 8 +/* + * Offset of the start of vsync in field 2, measured in one less than the + * number of half lines. + */ +# define TV_VSYNC_START_F2_MASK 0x0000007f +# define TV_VSYNC_START_F2_SHIFT 0 + +#define TV_V_CTL_3 0x68044 +/* Enables generation of the equalization signal */ +# define TV_EQUAL_ENA (1 << 31) +/* Length of vsync, in half lines */ +# define TV_VEQ_LEN_MASK 0x007f0000 +# define TV_VEQ_LEN_SHIFT 16 +/* Offset of the start of equalization in field 1, measured in one less than + * the number of half lines. + */ +# define TV_VEQ_START_F1_MASK 0x0007f00 +# define TV_VEQ_START_F1_SHIFT 8 +/* + * Offset of the start of equalization in field 2, measured in one less than + * the number of half lines. + */ +# define TV_VEQ_START_F2_MASK 0x000007f +# define TV_VEQ_START_F2_SHIFT 0 + +#define TV_V_CTL_4 0x68048 +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F1_MASK 0x003f0000 +# define TV_VBURST_START_F1_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F1_MASK 0x000000ff +# define TV_VBURST_END_F1_SHIFT 0 + +#define TV_V_CTL_5 0x6804c +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F2_MASK 0x003f0000 +# define TV_VBURST_START_F2_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F2_MASK 0x000000ff +# define TV_VBURST_END_F2_SHIFT 0 + +#define TV_V_CTL_6 0x68050 +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F3_MASK 0x003f0000 +# define TV_VBURST_START_F3_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F3_MASK 0x000000ff +# define TV_VBURST_END_F3_SHIFT 0 + +#define TV_V_CTL_7 0x68054 +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F4_MASK 0x003f0000 +# define TV_VBURST_START_F4_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F4_MASK 0x000000ff +# define TV_VBURST_END_F4_SHIFT 0 + +#define TV_SC_CTL_1 0x68060 +/* Turns on the first subcarrier phase generation DDA */ +# define TV_SC_DDA1_EN (1 << 31) +/* Turns on the first subcarrier phase generation DDA */ +# define TV_SC_DDA2_EN (1 << 30) +/* Turns on the first subcarrier phase generation DDA */ +# define TV_SC_DDA3_EN (1 << 29) +/* Sets the subcarrier DDA to reset frequency every other field */ +# define TV_SC_RESET_EVERY_2 (0 << 24) +/* Sets the subcarrier DDA to reset frequency every fourth field */ +# define TV_SC_RESET_EVERY_4 (1 << 24) +/* Sets the subcarrier DDA to reset frequency every eighth field */ +# define TV_SC_RESET_EVERY_8 (2 << 24) +/* Sets the subcarrier DDA to never reset the frequency */ +# define TV_SC_RESET_NEVER (3 << 24) +/* Sets the peak amplitude of the colorburst.*/ +# define TV_BURST_LEVEL_MASK 0x00ff0000 +# define TV_BURST_LEVEL_SHIFT 16 +/* Sets the increment of the first subcarrier phase generation DDA */ +# define TV_SCDDA1_INC_MASK 0x00000fff +# define TV_SCDDA1_INC_SHIFT 0 + +#define TV_SC_CTL_2 0x68064 +/* Sets the rollover for the second subcarrier phase generation DDA */ +# define TV_SCDDA2_SIZE_MASK 0x7fff0000 +# define TV_SCDDA2_SIZE_SHIFT 16 +/* Sets the increent of the second subcarrier phase generation DDA */ +# define TV_SCDDA2_INC_MASK 0x00007fff +# define TV_SCDDA2_INC_SHIFT 0 + +#define TV_SC_CTL_3 0x68068 +/* Sets the rollover for the third subcarrier phase generation DDA */ +# define TV_SCDDA3_SIZE_MASK 0x7fff0000 +# define TV_SCDDA3_SIZE_SHIFT 16 +/* Sets the increent of the third subcarrier phase generation DDA */ +# define TV_SCDDA3_INC_MASK 0x00007fff +# define TV_SCDDA3_INC_SHIFT 0 + +#define TV_WIN_POS 0x68070 +/* X coordinate of the display from the start of horizontal active */ +# define TV_XPOS_MASK 0x1fff0000 +# define TV_XPOS_SHIFT 16 +/* Y coordinate of the display from the start of vertical active (NBR) */ +# define TV_YPOS_MASK 0x00000fff +# define TV_YPOS_SHIFT 0 + +#define TV_WIN_SIZE 0x68074 +/* Horizontal size of the display window, measured in pixels*/ +# define TV_XSIZE_MASK 0x1fff0000 +# define TV_XSIZE_SHIFT 16 +/* + * Vertical size of the display window, measured in pixels. + * + * Must be even for interlaced modes. + */ +# define TV_YSIZE_MASK 0x00000fff +# define TV_YSIZE_SHIFT 0 + +#define TV_FILTER_CTL_1 0x68080 +/* + * Enables automatic scaling calculation. + * + * If set, the rest of the registers are ignored, and the calculated values can + * be read back from the register. + */ +# define TV_AUTO_SCALE (1 << 31) +/* + * Disables the vertical filter. + * + * This is required on modes more than 1024 pixels wide */ +# define TV_V_FILTER_BYPASS (1 << 29) +/* Enables adaptive vertical filtering */ +# define TV_VADAPT (1 << 28) +# define TV_VADAPT_MODE_MASK (3 << 26) +/* Selects the least adaptive vertical filtering mode */ +# define TV_VADAPT_MODE_LEAST (0 << 26) +/* Selects the moderately adaptive vertical filtering mode */ +# define TV_VADAPT_MODE_MODERATE (1 << 26) +/* Selects the most adaptive vertical filtering mode */ +# define TV_VADAPT_MODE_MOST (3 << 26) +/* + * Sets the horizontal scaling factor. + * + * This should be the fractional part of the horizontal scaling factor divided + * by the oversampling rate. TV_HSCALE should be less than 1, and set to: + * + * (src width - 1) / ((oversample * dest width) - 1) + */ +# define TV_HSCALE_FRAC_MASK 0x00003fff +# define TV_HSCALE_FRAC_SHIFT 0 + +#define TV_FILTER_CTL_2 0x68084 +/* + * Sets the integer part of the 3.15 fixed-point vertical scaling factor. + * + * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1) + */ +# define TV_VSCALE_INT_MASK 0x00038000 +# define TV_VSCALE_INT_SHIFT 15 +/* + * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. + * + * \sa TV_VSCALE_INT_MASK + */ +# define TV_VSCALE_FRAC_MASK 0x00007fff +# define TV_VSCALE_FRAC_SHIFT 0 + +#define TV_FILTER_CTL_3 0x68088 +/* + * Sets the integer part of the 3.15 fixed-point vertical scaling factor. + * + * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1)) + * + * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. + */ +# define TV_VSCALE_IP_INT_MASK 0x00038000 +# define TV_VSCALE_IP_INT_SHIFT 15 +/* + * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. + * + * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. + * + * \sa TV_VSCALE_IP_INT_MASK + */ +# define TV_VSCALE_IP_FRAC_MASK 0x00007fff +# define TV_VSCALE_IP_FRAC_SHIFT 0 + +#define TV_CC_CONTROL 0x68090 +# define TV_CC_ENABLE (1 << 31) +/* + * Specifies which field to send the CC data in. + * + * CC data is usually sent in field 0. + */ +# define TV_CC_FID_MASK (1 << 27) +# define TV_CC_FID_SHIFT 27 +/* Sets the horizontal position of the CC data. Usually 135. */ +# define TV_CC_HOFF_MASK 0x03ff0000 +# define TV_CC_HOFF_SHIFT 16 +/* Sets the vertical position of the CC data. Usually 21 */ +# define TV_CC_LINE_MASK 0x0000003f +# define TV_CC_LINE_SHIFT 0 + +#define TV_CC_DATA 0x68094 +# define TV_CC_RDY (1 << 31) +/* Second word of CC data to be transmitted. */ +# define TV_CC_DATA_2_MASK 0x007f0000 +# define TV_CC_DATA_2_SHIFT 16 +/* First word of CC data to be transmitted. */ +# define TV_CC_DATA_1_MASK 0x0000007f +# define TV_CC_DATA_1_SHIFT 0 + +#define TV_H_LUMA_0 0x68100 +#define TV_H_LUMA_59 0x681ec +#define TV_H_CHROMA_0 0x68200 +#define TV_H_CHROMA_59 0x682ec +#define TV_V_LUMA_0 0x68300 +#define TV_V_LUMA_42 0x683a8 +#define TV_V_CHROMA_0 0x68400 +#define TV_V_CHROMA_42 0x684a8 + +/* Display Port */ +#define DP_A 0x64000 /* eDP */ +#define DP_B 0x64100 +#define DP_C 0x64200 +#define DP_D 0x64300 + +#define DP_PORT_EN (1 << 31) +#define DP_PIPEB_SELECT (1 << 30) +#define DP_PIPE_MASK (1 << 30) +#define DP_PIPE_SELECT_CHV(pipe) ((pipe) << 16) +#define DP_PIPE_MASK_CHV (3 << 16) + +/* Link training mode - select a suitable mode for each stage */ +#define DP_LINK_TRAIN_PAT_1 (0 << 28) +#define DP_LINK_TRAIN_PAT_2 (1 << 28) +#define DP_LINK_TRAIN_PAT_IDLE (2 << 28) +#define DP_LINK_TRAIN_OFF (3 << 28) +#define DP_LINK_TRAIN_MASK (3 << 28) +#define DP_LINK_TRAIN_SHIFT 28 +#define DP_LINK_TRAIN_PAT_3_CHV (1 << 14) +#define DP_LINK_TRAIN_MASK_CHV ((3 << 28)|(1<<14)) + +/* CPT Link training mode */ +#define DP_LINK_TRAIN_PAT_1_CPT (0 << 8) +#define DP_LINK_TRAIN_PAT_2_CPT (1 << 8) +#define DP_LINK_TRAIN_PAT_IDLE_CPT (2 << 8) +#define DP_LINK_TRAIN_OFF_CPT (3 << 8) +#define DP_LINK_TRAIN_MASK_CPT (7 << 8) +#define DP_LINK_TRAIN_SHIFT_CPT 8 + +/* Signal voltages. These are mostly controlled by the other end */ +#define DP_VOLTAGE_0_4 (0 << 25) +#define DP_VOLTAGE_0_6 (1 << 25) +#define DP_VOLTAGE_0_8 (2 << 25) +#define DP_VOLTAGE_1_2 (3 << 25) +#define DP_VOLTAGE_MASK (7 << 25) +#define DP_VOLTAGE_SHIFT 25 + +/* Signal pre-emphasis levels, like voltages, the other end tells us what + * they want + */ +#define DP_PRE_EMPHASIS_0 (0 << 22) +#define DP_PRE_EMPHASIS_3_5 (1 << 22) +#define DP_PRE_EMPHASIS_6 (2 << 22) +#define DP_PRE_EMPHASIS_9_5 (3 << 22) +#define DP_PRE_EMPHASIS_MASK (7 << 22) +#define DP_PRE_EMPHASIS_SHIFT 22 + +/* How many wires to use. I guess 3 was too hard */ +#define DP_PORT_WIDTH(width) (((width) - 1) << 19) +#define DP_PORT_WIDTH_MASK (7 << 19) + +/* Mystic DPCD version 1.1 special mode */ +#define DP_ENHANCED_FRAMING (1 << 18) + +/* eDP */ +#define DP_PLL_FREQ_270MHZ (0 << 16) +#define DP_PLL_FREQ_160MHZ (1 << 16) +#define DP_PLL_FREQ_MASK (3 << 16) + +/* locked once port is enabled */ +#define DP_PORT_REVERSAL (1 << 15) + +/* eDP */ +#define DP_PLL_ENABLE (1 << 14) + +/* sends the clock on lane 15 of the PEG for debug */ +#define DP_CLOCK_OUTPUT_ENABLE (1 << 13) + +#define DP_SCRAMBLING_DISABLE (1 << 12) +#define DP_SCRAMBLING_DISABLE_IRONLAKE (1 << 7) + +/* limit RGB values to avoid confusing TVs */ +#define DP_COLOR_RANGE_16_235 (1 << 8) + +/* Turn on the audio link */ +#define DP_AUDIO_OUTPUT_ENABLE (1 << 6) + +/* vs and hs sync polarity */ +#define DP_SYNC_VS_HIGH (1 << 4) +#define DP_SYNC_HS_HIGH (1 << 3) + +/* A fantasy */ +#define DP_DETECTED (1 << 2) + +/* The aux channel provides a way to talk to the + * signal sink for DDC etc. Max packet size supported + * is 20 bytes in each direction, hence the 5 fixed + * data registers + */ +#define DPA_AUX_CH_CTL 0x64010 +#define DPA_AUX_CH_DATA1 0x64014 +#define DPA_AUX_CH_DATA2 0x64018 +#define DPA_AUX_CH_DATA3 0x6401c +#define DPA_AUX_CH_DATA4 0x64020 +#define DPA_AUX_CH_DATA5 0x64024 + +#define DPB_AUX_CH_CTL 0x64110 +#define DPB_AUX_CH_DATA1 0x64114 +#define DPB_AUX_CH_DATA2 0x64118 +#define DPB_AUX_CH_DATA3 0x6411c +#define DPB_AUX_CH_DATA4 0x64120 +#define DPB_AUX_CH_DATA5 0x64124 + +#define DPC_AUX_CH_CTL 0x64210 +#define DPC_AUX_CH_DATA1 0x64214 +#define DPC_AUX_CH_DATA2 0x64218 +#define DPC_AUX_CH_DATA3 0x6421c +#define DPC_AUX_CH_DATA4 0x64220 +#define DPC_AUX_CH_DATA5 0x64224 + +#define DPD_AUX_CH_CTL 0x64310 +#define DPD_AUX_CH_DATA1 0x64314 +#define DPD_AUX_CH_DATA2 0x64318 +#define DPD_AUX_CH_DATA3 0x6431c +#define DPD_AUX_CH_DATA4 0x64320 +#define DPD_AUX_CH_DATA5 0x64324 + +#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31) +#define DP_AUX_CH_CTL_DONE (1 << 30) +#define DP_AUX_CH_CTL_INTERRUPT (1 << 29) +#define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28) +#define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_1600us (3 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26) +#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25) +#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20) +#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20 +#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16) +#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16 +#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15) +#define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14) +#define DP_AUX_CH_CTL_SYNC_TEST (1 << 13) +#define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12) +#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11) +#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff) +#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0 + +/* + * Computing GMCH M and N values for the Display Port link + * + * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes + * + * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz) + * + * The GMCH value is used internally + * + * bytes_per_pixel is the number of bytes coming out of the plane, + * which is after the LUTs, so we want the bytes for our color format. + * For our current usage, this is always 3, one byte for R, G and B. + */ +#define _PIPEA_DATA_M_G4X 0x70050 +#define _PIPEB_DATA_M_G4X 0x71050 + +/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ +#define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */ +#define TU_SIZE_SHIFT 25 +#define TU_SIZE_MASK (0x3f << 25) + +#define DATA_LINK_M_N_MASK (0xffffff) +#define DATA_LINK_N_MAX (0x800000) + +#define _PIPEA_DATA_N_G4X 0x70054 +#define _PIPEB_DATA_N_G4X 0x71054 +#define PIPE_GMCH_DATA_N_MASK (0xffffff) + +/* + * Computing Link M and N values for the Display Port link + * + * Link M / N = pixel_clock / ls_clk + * + * (the DP spec calls pixel_clock the 'strm_clk') + * + * The Link value is transmitted in the Main Stream + * Attributes and VB-ID. + */ + +#define _PIPEA_LINK_M_G4X 0x70060 +#define _PIPEB_LINK_M_G4X 0x71060 +#define PIPEA_DP_LINK_M_MASK (0xffffff) + +#define _PIPEA_LINK_N_G4X 0x70064 +#define _PIPEB_LINK_N_G4X 0x71064 +#define PIPEA_DP_LINK_N_MASK (0xffffff) + +#define PIPE_DATA_M_G4X(pipe) _PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X) +#define PIPE_DATA_N_G4X(pipe) _PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X) +#define PIPE_LINK_M_G4X(pipe) _PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X) +#define PIPE_LINK_N_G4X(pipe) _PIPE(pipe, _PIPEA_LINK_N_G4X, _PIPEB_LINK_N_G4X) + +/* Display & cursor control */ + +/* Pipe A */ +#define _PIPEADSL 0x70000 +#define DSL_LINEMASK_GEN2 0x00000fff +#define DSL_LINEMASK_GEN3 0x00001fff +#define _PIPEACONF 0x70008 +#define PIPECONF_ENABLE (1<<31) +#define PIPECONF_DISABLE 0 +#define PIPECONF_DOUBLE_WIDE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) +#define PIPECONF_DSI_PLL_LOCKED (1<<29) /* vlv & pipe A only */ +#define PIPECONF_FRAME_START_DELAY_MASK (3<<27) +#define PIPECONF_SINGLE_WIDE 0 +#define PIPECONF_PIPE_UNLOCKED 0 +#define PIPECONF_PIPE_LOCKED (1<<25) +#define PIPECONF_PALETTE 0 +#define PIPECONF_GAMMA (1<<24) +#define PIPECONF_FORCE_BORDER (1<<25) +#define PIPECONF_INTERLACE_MASK (7 << 21) +#define PIPECONF_INTERLACE_MASK_HSW (3 << 21) + +#define SURF_RESERVED_REG_BIT_2_ENABLE (1<<2) +#define PLANE_RESERVED_REG_BIT_2_ENABLE (1 << 2) + +/* Note that pre-gen3 does not support interlaced display directly. Panel + * fitting must be disabled on pre-ilk for interlaced. */ +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_SYNC_SHIFT_PANEL (4 << 21) /* gen4 only */ +#define PIPECONF_INTERLACE_W_SYNC_SHIFT (5 << 21) /* gen4 only */ +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) /* gen3 only */ +/* Ironlake and later have a complete new set of values for interlaced. PFIT + * means panel fitter required, PF means progressive fetch, DBL means power + * saving pixel doubling. */ +#define PIPECONF_PFIT_PF_INTERLACED_ILK (1 << 21) +#define PIPECONF_INTERLACED_ILK (3 << 21) +#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ +#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ +#define PIPECONF_INTERLACE_MODE_MASK (7 << 21) +#define PIPECONF_MIPI_DSR_ENABLE (1 << 20) +#define PIPECONF_EDP_RR_MODE_SWITCH (1 << 20) +#define PIPECONF_EDP_RR_MODE_SWITCH_VLV (1 << 14) +#define PIPECONF_CXSR_DOWNCLOCK (1<<16) +#define PIPECONF_COLOR_RANGE_SELECT (1 << 13) +#define PIPECONF_BPC_MASK (0x7 << 5) +#define PIPECONF_8BPC (0<<5) +#define PIPECONF_10BPC (1<<5) +#define PIPECONF_6BPC (2<<5) +#define PIPECONF_12BPC (3<<5) +#define PIPECONF_DITHER_EN (1<<4) +#define PIPECONF_DITHER_TYPE_MASK (0x0000000c) +#define PIPECONF_DITHER_TYPE_SP (0<<2) +#define PIPECONF_DITHER_TYPE_ST1 (1<<2) +#define PIPECONF_DITHER_TYPE_ST2 (2<<2) +#define PIPECONF_DITHER_TYPE_TEMP (3<<2) +#define _PIPEASTAT 0x70024 +#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) +#define SPRITE1_FLIP_DONE_INT_EN_VLV (1UL<<30) +#define PIPE_CRC_ERROR_ENABLE (1UL<<29) +#define PIPE_CRC_DONE_ENABLE (1UL<<28) +#define PERF_COUNTER2_INTERRUPT_EN (1UL<<27) +#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27) +#define PLANE_FLIP_DONE_INT_EN_VLV (1UL<<26) +#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) +#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25) +#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) +#define PIPE_DPST_EVENT_ENABLE (1UL<<23) +#define SPRITE0_FLIP_DONE_INT_EN_VLV (1UL<<22) +#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22) +#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) +#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) +#define PIPE_B_PSR_INTERRUPT_ENABLE_VLV (1UL<<19) +#define PERF_COUNTER_INTERRUPT_EN (1UL<<19) +#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */ +#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ +#define PIPE_FRAMESTART_INTERRUPT_ENABLE (1UL<<17) +#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define PIPEA_HBLANK_INT_EN_VLV (1UL<<16) +#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16) +#define SPRITE1_FLIP_DONE_INT_STATUS_VLV (1UL<<15) +#define SPRITE0_FLIP_DONE_INT_STATUS_VLV (1UL<<14) +#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) +#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12) +#define PERF_COUNTER2_INTERRUPT_STATUS (1UL<<11) +#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11) +#define PLANE_FLIP_DONE_INT_STATUS_VLV (1UL<<10) +#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) +#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9) +#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) +#define PIPE_DPST_EVENT_STATUS (1UL<<7) +#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) +#define PIPE_A_PSR_STATUS_VLV (1UL<<6) +#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) +#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) +#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) +#define PIPE_B_PSR_STATUS_VLV (1UL<<3) +#define PERF_COUNTER_INTERRUPT_STATUS (1UL<<3) +#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */ +#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ +#define PIPE_FRAMESTART_INTERRUPT_STATUS (1UL<<1) +#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) +#define PIPE_HBLANK_INT_STATUS (1UL<<0) +#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) + +#define PIPESTAT_INT_ENABLE_MASK 0x7fff0000 +#define PIPESTAT_INT_STATUS_MASK 0x0000ffff + +#define PIPE_A_OFFSET 0x70000 +#define PIPE_B_OFFSET 0x71000 +#define PIPE_C_OFFSET 0x72000 +#define CHV_PIPE_C_OFFSET 0x74000 +/* + * There's actually no pipe EDP. Some pipe registers have + * simply shifted from the pipe to the transcoder, while + * keeping their original offset. Thus we need PIPE_EDP_OFFSET + * to access such registers in transcoder EDP. + */ +#define PIPE_EDP_OFFSET 0x7f000 + +#define _PIPE2(pipe, reg) (dev_priv->info.pipe_offsets[pipe] - \ + dev_priv->info.pipe_offsets[PIPE_A] + (reg) + \ + dev_priv->info.display_mmio_offset) + +#define PIPECONF(pipe) _PIPE2(pipe, _PIPEACONF) +#define PIPEDSL(pipe) _PIPE2(pipe, _PIPEADSL) +#define PIPEFRAME(pipe) _PIPE2(pipe, _PIPEAFRAMEHIGH) +#define PIPEFRAMEPIXEL(pipe) _PIPE2(pipe, _PIPEAFRAMEPIXEL) +#define PIPESTAT(pipe) _PIPE2(pipe, _PIPEASTAT) +#define PIPESTAT_IIR(pipe) ((pipe == PIPE_A) ? \ + I915_DISPLAY_PIPE_A_EVENT_INTERRUPT \ + : (pipe == PIPE_B) \ + ? I915_DISPLAY_PIPE_B_EVENT_INTERRUPT \ + : I915_DISPLAY_PIPE_C_EVENT_INTERRUPT); + +#define _PIPE_MISC_A 0x70030 +#define _PIPE_MISC_B 0x71030 +#define PIPEMISC_DITHER_BPC_MASK (7<<5) +#define PIPEMISC_DITHER_8_BPC (0<<5) +#define PIPEMISC_DITHER_10_BPC (1<<5) +#define PIPEMISC_DITHER_6_BPC (2<<5) +#define PIPEMISC_DITHER_12_BPC (3<<5) +#define PIPEMISC_DITHER_ENABLE (1<<4) +#define PIPEMISC_DITHER_TYPE_MASK (3<<2) +#define PIPEMISC_DITHER_TYPE_SP (0<<2) +#define PIPEMISC(pipe) _PIPE2(pipe, _PIPE_MISC_A) + +#define VLV_DPFLIPSTAT (VLV_DISPLAY_BASE + 0x70028) +#define PIPEB_LINE_COMPARE_INT_EN (1<<29) +#define PIPEB_HLINE_INT_EN (1<<28) +#define PIPEB_VBLANK_INT_EN (1<<27) +#define SPRITED_FLIP_DONE_INT_EN (1<<26) +#define SPRITEC_FLIP_DONE_INT_EN (1<<25) +#define PLANEB_FLIP_DONE_INT_EN (1<<24) +#define PIPE_PSR_INT_EN (1<<22) +#define PIPEA_LINE_COMPARE_INT_EN (1<<21) +#define PIPEA_HLINE_INT_EN (1<<20) +#define PIPEA_VBLANK_INT_EN (1<<19) +#define SPRITEB_FLIP_DONE_INT_EN (1<<18) +#define SPRITEA_FLIP_DONE_INT_EN (1<<17) +#define PLANEA_FLIPDONE_INT_EN (1<<16) +#define PIPEC_LINE_COMPARE_INT_EN (1<<13) +#define PIPEC_HLINE_INT_EN (1<<12) +#define PIPEC_VBLANK_INT_EN (1<<11) +#define SPRITEF_FLIPDONE_INT_EN (1<<10) +#define SPRITEE_FLIPDONE_INT_EN (1<<9) +#define PLANEC_FLIPDONE_INT_EN (1<<8) + +#define DPINVGTT (VLV_DISPLAY_BASE + 0x7002c) /* VLV/CHV only */ +#define SPRITEF_INVALID_GTT_INT_EN (1<<27) +#define SPRITEE_INVALID_GTT_INT_EN (1<<26) +#define PLANEC_INVALID_GTT_INT_EN (1<<25) +#define CURSORC_INVALID_GTT_INT_EN (1<<24) +#define CURSORB_INVALID_GTT_INT_EN (1<<23) +#define CURSORA_INVALID_GTT_INT_EN (1<<22) +#define SPRITED_INVALID_GTT_INT_EN (1<<21) +#define SPRITEC_INVALID_GTT_INT_EN (1<<20) +#define PLANEB_INVALID_GTT_INT_EN (1<<19) +#define SPRITEB_INVALID_GTT_INT_EN (1<<18) +#define SPRITEA_INVALID_GTT_INT_EN (1<<17) +#define PLANEA_INVALID_GTT_INT_EN (1<<16) +#define DPINVGTT_EN_MASK 0xff0000 +#define DPINVGTT_EN_MASK_CHV 0xfff0000 +#define SPRITEF_INVALID_GTT_STATUS (1<<11) +#define SPRITEE_INVALID_GTT_STATUS (1<<10) +#define PLANEC_INVALID_GTT_STATUS (1<<9) +#define CURSORC_INVALID_GTT_STATUS (1<<8) +#define CURSORB_INVALID_GTT_STATUS (1<<7) +#define CURSORA_INVALID_GTT_STATUS (1<<6) +#define SPRITED_INVALID_GTT_STATUS (1<<5) +#define SPRITEC_INVALID_GTT_STATUS (1<<4) +#define PLANEB_INVALID_GTT_STATUS (1<<3) +#define SPRITEB_INVALID_GTT_STATUS (1<<2) +#define SPRITEA_INVALID_GTT_STATUS (1<<1) +#define PLANEA_INVALID_GTT_STATUS (1<<0) +#define DPINVGTT_STATUS_MASK 0xff +#define DPINVGTT_STATUS_MASK_CHV 0xfff + +#define DSPARB (dev_priv->info.display_mmio_offset + 0x70030) +#define DSPARB_VLV_DEFAULT 0x80008000 +#define DSPARB_CSTART_MASK (0x7f << 7) +#define DSPARB_CSTART_SHIFT 7 +#define DSPARB_BSTART_MASK (0x7f) +#define DSPARB_BSTART_SHIFT 0 +#define DSPARB_BEND_SHIFT 9 /* on 855 */ +#define DSPARB_AEND_SHIFT 0 + +#define DSPFW1 (dev_priv->info.display_mmio_offset + 0x70034) +#define DSPFW_SR_SHIFT 23 +#define DSPFW_SR_MASK (0x1ff<<23) +#define DSPFW_CURSORB_SHIFT 16 +#define DSPFW_CURSORB_MASK (0x3f<<16) +#define DSPFW_PLANEB_SHIFT 8 +#define DSPFW_PLANEB_MASK (0x7f<<8) +#define DSPFW_PLANEA_MASK (0x7f) +#define DSPFW1_VLV 0x3F8F0F0F +#define DSPFW_PLANEA_VAL 0x0F +#define DSPFW_PLANEB_VAL 0x0F +#define DSPFW_CURSORB_VAL 0x0F +#define DSPFW_SR_VAL 0x7F +#define DSPFW2 (dev_priv->info.display_mmio_offset + 0x70038) +#define DSPFW_CURSORA_MASK 0x00003f00 +#define DSPFW_CURSORA_SHIFT 8 +#define DSPFW_PLANEC_MASK (0x7f) +#define DSPFW2_VLV 0x0B0F0F0F +#define DSPFW_PLANEC_VAL 0x0F +#define DSPFW_CURSORA_VAL 0x0F +#define DSPFW2_RESERVED (0xB0F<<16) +#define DSPFW3 (dev_priv->info.display_mmio_offset + 0x7003c) +#define DSPFW_HPLL_SR_EN (1<<31) +#define DSPFW_CURSOR_SR_SHIFT 24 +#define DSPFW3_VLV 0x0 +#define PINEVIEW_SELF_REFRESH_EN (1<<30) +#define DSPFW_CURSOR_SR_MASK (0x3f<<24) +#define DSPFW_HPLL_CURSOR_SHIFT 16 +#define DSPFW_HPLL_CURSOR_MASK (0x3f<<16) +#define DSPFW_HPLL_SR_MASK (0x1ff) +#define DSPFW4 (dev_priv->info.display_mmio_offset + 0x70070) +#define DSPFW4_SPRITEA_VAL 0x04 +#define DSPFW4_CURSORA_SHIFT 8 +#define DSPFW4_CURSORA_VAL 0x04 +#define DSPFW4_SPRITEB_SHIFT 16 +#define DSPFW4_SPRITEB_VAL 0x04 +#define DSPFW4_VLV 0x00040404 +#define DSPFW5 (dev_priv->info.display_mmio_offset + 0x70074) +#define DSPFW5_CURSORSR_VAL 0x4 +#define DSPFW5_CURSORB_SHIFT 8 +#define DSPFW5_CURSORB_VAL 0x4 +#define DSPFW5_DISPLAYA_SHIFT 16 +#define DSPFW5_DISPLAYA_VAL 0x4 +#define DSPFW5_DISPLAYB_SHIFT 24 +#define DSPFW5_DISPLAYB_VAL 0x4 +#define DSPFW5_VLV 0x04040404 +#define DSPFW6 (dev_priv->info.display_mmio_offset + 0x70078) +#define DSPFW6_DISPLAYSR_VAL 0xF +#define DSPFW6_VLV 0x0000000F +#define DSPFW7 (dev_priv->info.display_mmio_offset + 0x7007c) +#define DSPFW7_SPRITEC_VAL 0x0F +#define DSPFW7_SPRITEC1_VAL 0x04 +#define DSPFW7_SPRITEC1_SHIFT 8 +#define DSPFW7_SPRITED_VAL 0x0F +#define DSPFW7_SPRITED_SHIFT 16 +#define DSPFW7_SPRITED1_VAL 0x04 +#define DSPFW7_SPRITED1_SHIFT 24 +#define DSPFW7_VLV 0x040F040F + +/* drain latency register values*/ +#define VLV_DDL(pipe) _PIPE(pipe, VLV_DDL1, VLV_DDL2) +#define DRAIN_LATENCY_PRECISION_64 64 +#define DRAIN_LATENCY_PRECISION_32 32 +#define VLV_DDL1 (VLV_DISPLAY_BASE + 0x70050) +#define DDL_CURSORA_PRECISION_H (1<<31) +#define DDL_CURSORA_PRECISION_L (0<<31) +#define DDL_CURSORA_SHIFT 24 +#define DDL_SPRITEA_PRECISION_H (1<<15) +#define DDL_SPRITEA_PRECISION_L (0<<15) +#define DDL_SPRITEB_PRECISION_H (1<<23) +#define DDL_SPRITEB_PRECISION_L (0<<23) +#define DDL_SPRITEA_SHIFT 8 + +#define DDL_PLANEA_PRECISION_H (1<<7) +#define DDL_PLANEA_PRECISION_L (0<<7) + +#define VLV_DDL2 (VLV_DISPLAY_BASE + 0x70054) +#define DDL_CURSORB_PRECISION_H (1<<31) +#define DDL_CURSORB_PRECISION_L (0<<31) +#define DDL_CURSORB_SHIFT 24 +#define DDL_SPRITEB_PRECISION_H (1<<23) +#define DDL_SPRITEB_PRECISION_L (0<<23) +#define DDL_SPRITEB_SHIFT 16 +#define DDL_PLANEB_PRECISION_H (1<<7) +#define DDL_PLANEB_PRECISION_L (0<<7) + +/* FIFO watermark sizes etc */ +#define G4X_FIFO_LINE_SIZE 64 +#define I915_FIFO_LINE_SIZE 64 +#define I830_FIFO_LINE_SIZE 32 + +#define VALLEYVIEW_FIFO_SIZE 255 +#define G4X_FIFO_SIZE 127 +#define I965_FIFO_SIZE 512 +#define I945_FIFO_SIZE 127 +#define I915_FIFO_SIZE 95 +#define I855GM_FIFO_SIZE 127 /* In cachelines */ +#define I830_FIFO_SIZE 95 + +#define VALLEYVIEW_MAX_WM 0xff +#define G4X_MAX_WM 0x3f +#define I915_MAX_WM 0x3f + +#define PINEVIEW_DISPLAY_FIFO 512 /* in 64byte unit */ +#define PINEVIEW_FIFO_LINE_SIZE 64 +#define PINEVIEW_MAX_WM 0x1ff +#define PINEVIEW_DFT_WM 0x3f +#define PINEVIEW_DFT_HPLLOFF_WM 0 +#define PINEVIEW_GUARD_WM 10 +#define PINEVIEW_CURSOR_FIFO 64 +#define PINEVIEW_CURSOR_MAX_WM 0x3f +#define PINEVIEW_CURSOR_DFT_WM 0 +#define PINEVIEW_CURSOR_GUARD_WM 5 + +#define VALLEYVIEW_CURSOR_MAX_WM 64 +#define I965_CURSOR_FIFO 64 +#define I965_CURSOR_MAX_WM 32 +#define I965_CURSOR_DFT_WM 8 + +/* define the Watermark register on Ironlake */ +#define WM0_PIPEA_ILK 0x45100 +#define WM0_PIPE_PLANE_MASK (0xffff<<16) +#define WM0_PIPE_PLANE_SHIFT 16 +#define WM0_PIPE_SPRITE_MASK (0xff<<8) +#define WM0_PIPE_SPRITE_SHIFT 8 +#define WM0_PIPE_CURSOR_MASK (0xff) + +#define WM0_PIPEB_ILK 0x45104 +#define WM0_PIPEC_IVB 0x45200 +#define WM1_LP_ILK 0x45108 +#define WM1_LP_SR_EN (1<<31) +#define WM1_LP_LATENCY_SHIFT 24 +#define WM1_LP_LATENCY_MASK (0x7f<<24) +#define WM1_LP_FBC_MASK (0xf<<20) +#define WM1_LP_FBC_SHIFT 20 +#define WM1_LP_FBC_SHIFT_BDW 19 +#define WM1_LP_SR_MASK (0x7ff<<8) +#define WM1_LP_SR_SHIFT 8 +#define WM1_LP_CURSOR_MASK (0xff) +#define WM2_LP_ILK 0x4510c +#define WM2_LP_EN (1<<31) +#define WM3_LP_ILK 0x45110 +#define WM3_LP_EN (1<<31) +#define WM1S_LP_ILK 0x45120 +#define WM2S_LP_IVB 0x45124 +#define WM3S_LP_IVB 0x45128 +#define WM1S_LP_EN (1<<31) + +#define HSW_WM_LP_VAL(lat, fbc, pri, cur) \ + (WM3_LP_EN | ((lat) << WM1_LP_LATENCY_SHIFT) | \ + ((fbc) << WM1_LP_FBC_SHIFT) | ((pri) << WM1_LP_SR_SHIFT) | (cur)) + +/* Memory latency timer register */ +#define MLTR_ILK 0x11222 +#define MLTR_WM1_SHIFT 0 +#define MLTR_WM2_SHIFT 8 +/* the unit of memory self-refresh latency time is 0.5us */ +#define ILK_SRLT_MASK 0x3f + + +/* the address where we get all kinds of latency value */ +#define SSKPD 0x5d10 +#define SSKPD_WM_MASK 0x3f +#define SSKPD_WM0_SHIFT 0 +#define SSKPD_WM1_SHIFT 8 +#define SSKPD_WM2_SHIFT 16 +#define SSKPD_WM3_SHIFT 24 + +/* + * The two pipe frame counter registers are not synchronized, so + * reading a stable value is somewhat tricky. The following code + * should work: + * + * do { + * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> + * PIPE_FRAME_HIGH_SHIFT; + * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> + * PIPE_FRAME_LOW_SHIFT); + * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> + * PIPE_FRAME_HIGH_SHIFT); + * } while (high1 != high2); + * frame = (high1 << 8) | low1; + */ +#define _PIPEAFRAMEHIGH 0x70040 +#define PIPE_FRAME_HIGH_MASK 0x0000ffff +#define PIPE_FRAME_HIGH_SHIFT 0 +#define _PIPEAFRAMEPIXEL 0x70044 +#define PIPE_FRAME_LOW_MASK 0xff000000 +#define PIPE_FRAME_LOW_SHIFT 24 +#define PIPE_PIXEL_MASK 0x00ffffff +#define PIPE_PIXEL_SHIFT 0 +/* GM45+ just has to be different */ +#define _PIPEA_FRMCOUNT_GM45 0x70040 +#define _PIPEA_FLIPCOUNT_GM45 0x70044 +#define PIPE_FRMCOUNT_GM45(pipe) _PIPE2(pipe, _PIPEA_FRMCOUNT_GM45) +#define PIPE_FLIPCOUNT_GM45(pipe) _PIPE2(pipe, _PIPEA_FLIPCOUNT_GM45) + +/* Cursor A & B regs */ +#define _CURACNTR 0x70080 +/* Old style CUR*CNTR flags (desktop 8xx) */ +#define CURSOR_ENABLE 0x80000000 +#define CURSOR_GAMMA_ENABLE 0x40000000 +#define CURSOR_STRIDE_MASK 0x30000000 +#define CURSOR_PIPE_CSC_ENABLE (1<<24) +#define CURSOR_FORMAT_SHIFT 24 +#define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_3C (0x01 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_4C (0x02 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_ARGB (0x04 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_XRGB (0x05 << CURSOR_FORMAT_SHIFT) +/* New style CUR*CNTR flags */ +#define CURSOR_MODE 0x27 +#define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_128_32B_AX 0x02 +#define CURSOR_MODE_256_32B_AX 0x03 +#define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_128_ARGB_AX ((1 << 5) | CURSOR_MODE_128_32B_AX) +#define CURSOR_MODE_256_ARGB_AX ((1 << 5) | CURSOR_MODE_256_32B_AX) +#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) +#define MCURSOR_PIPE_SELECT (1 << 28) +#define MCURSOR_PIPE_A 0x00 +#define MCURSOR_PIPE_B (1 << 28) +#define MCURSOR_GAMMA_ENABLE (1 << 26) +#define CURSOR_TRICKLE_FEED_DISABLE (1 << 14) +#define CUR_MODE_SEL_BIT (1 << 5) +#define CUR_ENABLE 7 +#define _CURABASE 0x70084 +#define _CURAPOS 0x70088 +#define CURSOR_POS_MASK 0x007FF +#define CURSOR_POS_SIGN 0x8000 +#define CURSOR_X_SHIFT 0 +#define CURSOR_Y_SHIFT 16 +#define CURSIZE 0x700a0 +#define _CURBCNTR 0x700c0 +#define _CURBBASE 0x700c4 +#define _CURBPOS 0x700c8 + +#define _CURBCNTR_IVB 0x71080 +#define _CURBBASE_IVB 0x71084 +#define _CURBPOS_IVB 0x71088 + +#define _CURSOR2(pipe, reg) (dev_priv->info.cursor_offsets[(pipe)] - \ + dev_priv->info.cursor_offsets[PIPE_A] + (reg) + \ + dev_priv->info.display_mmio_offset) + +#define CURCNTR(pipe) _CURSOR2(pipe, _CURACNTR) +#define CURBASE(pipe) _CURSOR2(pipe, _CURABASE) +#define CURPOS(pipe) _CURSOR2(pipe, _CURAPOS) + +#define CURSOR_A_OFFSET 0x70080 +#define CURSOR_B_OFFSET 0x700c0 +#define CHV_CURSOR_C_OFFSET 0x700e0 +#define IVB_CURSOR_B_OFFSET 0x71080 +#define IVB_CURSOR_C_OFFSET 0x72080 + +/* Display A control */ +#define _DSPACNTR 0x70180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_YUV422 (0x0<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_BGRA555 (0x3<<26) +#define DISPPLANE_BGRX555 (0x4<<26) +#define DISPPLANE_BGRX565 (0x5<<26) +#define DISPPLANE_BGRX888 (0x6<<26) +#define DISPPLANE_BGRA888 (0x7<<26) +#define DISPPLANE_RGBX101010 (0x8<<26) +#define DISPPLANE_RGBA101010 (0x9<<26) +#define DISPPLANE_BGRX101010 (0xa<<26) +#define DISPPLANE_BGRA101010 (0xb<<26) +#define DISPPLANE_RGBX161616 (0xc<<26) +#define DISPPLANE_RGBA161616 (0xd<<26) +#define DISPPLANE_RGBX888 (0xe<<26) +#define DISPPLANE_RGBA888 (0xf<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_PIPE_CSC_ENABLE (1<<24) +#define DISPPLANE_SEL_PIPE_SHIFT 24 +#define DISPPLANE_SEL_PIPE_MASK (3<<DISPPLANE_SEL_PIPE_SHIFT) +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<DISPPLANE_SEL_PIPE_SHIFT) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */ +#define DISPPLANE_TILED (1<<10) +#define DISPPLANE_180_ROTATION_ENABLE (1<<15) +#define _DSPAADDR 0x70184 +#define _DSPASTRIDE 0x70188 +#define _DSPAPOS 0x7018C /* reserved */ +#define _DSPASIZE 0x70190 +#define _DSPASURF 0x7019C /* 965+ only */ +#define _DSPATILEOFF 0x701A4 /* 965+ only */ +#define _DSPAOFFSET 0x701A4 /* HSW */ +#define _DSPASURFLIVE 0x701AC + +#define DSPCNTR(plane) _PIPE2(plane, _DSPACNTR) +#define DSPADDR(plane) _PIPE2(plane, _DSPAADDR) +#define DSPSTRIDE(plane) _PIPE2(plane, _DSPASTRIDE) +#define DSPPOS(plane) _PIPE2(plane, _DSPAPOS) +#define DSPSIZE(plane) _PIPE2(plane, _DSPASIZE) +#define DSPSURF(plane) _PIPE2(plane, _DSPASURF) +#define DSPTILEOFF(plane) _PIPE2(plane, _DSPATILEOFF) +#define DSPLINOFF(plane) DSPADDR(plane) +#define DSPOFFSET(plane) _PIPE2(plane, _DSPAOFFSET) +#define DSPSURFLIVE(plane) _PIPE2(plane, _DSPASURFLIVE) + +/* Display/Sprite base address macros */ +#define DISP_BASEADDR_MASK (0xfffff000) +#define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK) +#define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK) +#define I915_MODIFY_DISPBASE(reg, gfx_addr) \ + (I915_WRITE((reg), (gfx_addr) | I915_LO_DISPBASE(I915_READ(reg)))) + +/* VBIOS flags */ +#define SWF00 (dev_priv->info.display_mmio_offset + 0x71410) +#define SWF01 (dev_priv->info.display_mmio_offset + 0x71414) +#define SWF02 (dev_priv->info.display_mmio_offset + 0x71418) +#define SWF03 (dev_priv->info.display_mmio_offset + 0x7141c) +#define SWF04 (dev_priv->info.display_mmio_offset + 0x71420) +#define SWF05 (dev_priv->info.display_mmio_offset + 0x71424) +#define SWF06 (dev_priv->info.display_mmio_offset + 0x71428) +#define SWF10 (dev_priv->info.display_mmio_offset + 0x70410) +#define SWF11 (dev_priv->info.display_mmio_offset + 0x70414) +#define SWF14 (dev_priv->info.display_mmio_offset + 0x71420) +#define SWF30 (dev_priv->info.display_mmio_offset + 0x72414) +#define SWF31 (dev_priv->info.display_mmio_offset + 0x72418) +#define SWF32 (dev_priv->info.display_mmio_offset + 0x7241c) + +/* Pipe B */ +#define _PIPEBDSL (dev_priv->info.display_mmio_offset + 0x71000) +#define _PIPEBCONF (dev_priv->info.display_mmio_offset + 0x71008) +#define _PIPEBSTAT (dev_priv->info.display_mmio_offset + 0x71024) +#define _PIPEBFRAMEHIGH 0x71040 +#define _PIPEBFRAMEPIXEL 0x71044 +#define _PIPEB_FRMCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x71040) +#define _PIPEB_FLIPCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x71044) + + +/* Display B control */ +#define _DSPBCNTR (dev_priv->info.display_mmio_offset + 0x71180) +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) +#define _DSPBADDR (dev_priv->info.display_mmio_offset + 0x71184) +#define _DSPBSTRIDE (dev_priv->info.display_mmio_offset + 0x71188) +#define _DSPBPOS (dev_priv->info.display_mmio_offset + 0x7118C) +#define _DSPBSIZE (dev_priv->info.display_mmio_offset + 0x71190) +#define _DSPBSURF (dev_priv->info.display_mmio_offset + 0x7119C) +#define _DSPBTILEOFF (dev_priv->info.display_mmio_offset + 0x711A4) +#define _DSPBOFFSET (dev_priv->info.display_mmio_offset + 0x711A4) +#define _DSPBSURFLIVE (dev_priv->info.display_mmio_offset + 0x711AC) + +/* Sprite Contrast and Brightness Registers */ +#define SPRITEA_CB_REG (dev_priv->info.display_mmio_offset + 0x721d0) +#define SPRITEB_CB_REG (dev_priv->info.display_mmio_offset + 0x722d0) +#define SPRITEC_CB_REG (dev_priv->info.display_mmio_offset + 0x723d0) +#define SPRITED_CB_REG (dev_priv->info.display_mmio_offset + 0x724d0) +#define SPRITEE_CB_REG (dev_priv->info.display_mmio_offset + 0x725d0) +#define SPRITEF_CB_REG (dev_priv->info.display_mmio_offset + 0x726d0) + +/* Sprite Hue and Saturation Registers */ +#define SPRITEA_HS_REG (dev_priv->info.display_mmio_offset + 0x721d4) +#define SPRITEB_HS_REG (dev_priv->info.display_mmio_offset + 0x722d4) +#define SPRITEC_HS_REG (dev_priv->info.display_mmio_offset + 0x723d4) +#define SPRITED_HS_REG (dev_priv->info.display_mmio_offset + 0x724d4) +#define SPRITEE_HS_REG (dev_priv->info.display_mmio_offset + 0x725d4) +#define SPRITEF_HS_REG (dev_priv->info.display_mmio_offset + 0x726d4) + + +/* Sprite A control */ +#define _DVSACNTR 0x72180 +#define DVS_ENABLE (1<<31) +#define DVS_GAMMA_ENABLE (1<<30) +#define DVS_PIXFORMAT_MASK (3<<25) +#define DVS_FORMAT_YUV422 (0<<25) +#define DVS_FORMAT_RGBX101010 (1<<25) +#define DVS_FORMAT_RGBX888 (2<<25) +#define DVS_FORMAT_RGBX161616 (3<<25) +#define DVS_PIPE_CSC_ENABLE (1<<24) +#define DVS_SOURCE_KEY (1<<22) +#define DVS_RGB_ORDER_XBGR (1<<20) +#define DVS_YUV_BYTE_ORDER_MASK (3<<16) +#define DVS_YUV_ORDER_YUYV (0<<16) +#define DVS_YUV_ORDER_UYVY (1<<16) +#define DVS_YUV_ORDER_YVYU (2<<16) +#define DVS_YUV_ORDER_VYUY (3<<16) +#define DVS_DEST_KEY (1<<2) +#define DVS_TRICKLE_FEED_DISABLE (1<<14) +#define DVS_TILED (1<<10) +#define _DVSALINOFF 0x72184 +#define _DVSASTRIDE 0x72188 +#define _DVSAPOS 0x7218c +#define _DVSASIZE 0x72190 +#define _DVSAKEYVAL 0x72194 +#define _DVSAKEYMSK 0x72198 +#define _DVSASURF 0x7219c +#define _DVSAKEYMAXVAL 0x721a0 +#define _DVSATILEOFF 0x721a4 +#define _DVSASURFLIVE 0x721ac +#define _DVSASCALE 0x72204 +#define DVS_SCALE_ENABLE (1<<31) +#define DVS_FILTER_MASK (3<<29) +#define DVS_FILTER_MEDIUM (0<<29) +#define DVS_FILTER_ENHANCING (1<<29) +#define DVS_FILTER_SOFTENING (2<<29) +#define DVS_VERTICAL_OFFSET_HALF (1<<28) /* must be enabled below */ +#define DVS_VERTICAL_OFFSET_ENABLE (1<<27) +#define _DVSAGAMC 0x72300 + +#define _DVSBCNTR 0x73180 +#define _DVSBLINOFF 0x73184 +#define _DVSBSTRIDE 0x73188 +#define _DVSBPOS 0x7318c +#define _DVSBSIZE 0x73190 +#define _DVSBKEYVAL 0x73194 +#define _DVSBKEYMSK 0x73198 +#define _DVSBSURF 0x7319c +#define _DVSBKEYMAXVAL 0x731a0 +#define _DVSBTILEOFF 0x731a4 +#define _DVSBSURFLIVE 0x731ac +#define _DVSBSCALE 0x73204 +#define _DVSBGAMC 0x73300 + +#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR) +#define DVSLINOFF(pipe) _PIPE(pipe, _DVSALINOFF, _DVSBLINOFF) +#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE) +#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS) +#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF) +#define DVSSURFLIVE(pipe) _PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE) +#define DVSKEYMAX(pipe) _PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL) +#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE) +#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE) +#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF) +#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL) +#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK) +#define DVSSURFLIVE(pipe) _PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE) + +#define _SPRA_CTL 0x70280 +#define SPRITE_ENABLE (1<<31) +#define SPRITE_GAMMA_ENABLE (1<<30) +#define SPRITE_PIXFORMAT_MASK (7<<25) +#define SPRITE_FORMAT_YUV422 (0<<25) +#define SPRITE_FORMAT_RGBX101010 (1<<25) +#define SPRITE_FORMAT_RGBX888 (2<<25) +#define SPRITE_FORMAT_RGBX161616 (3<<25) +#define SPRITE_FORMAT_YUV444 (4<<25) +#define SPRITE_FORMAT_XR_BGR101010 (5<<25) /* Extended range */ +#define SPRITE_PIPE_CSC_ENABLE (1<<24) +#define SPRITE_SOURCE_KEY (1<<22) +#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */ +#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19) +#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */ +#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16) +#define SPRITE_YUV_ORDER_YUYV (0<<16) +#define SPRITE_YUV_ORDER_UYVY (1<<16) +#define SPRITE_YUV_ORDER_YVYU (2<<16) +#define SPRITE_YUV_ORDER_VYUY (3<<16) +#define SPRITE_TRICKLE_FEED_DISABLE (1<<14) +#define SPRITE_INT_GAMMA_ENABLE (1<<13) +#define SPRITE_TILED (1<<10) +#define SPRITE_DEST_KEY (1<<2) +#define SPRITE_FORCE_BOTTOM (1<<2) +#define SPRITE_ZORDER_ENABLE (1<<0) + +#define P1S1S2C1 0 +#define P1S2S1C1 8 +#define S2P1S1C1 1 +#define S2S1P1C1 9 +#define S1P1S2C1 4 +#define S1S2P1C1 6 + +#define _SPRA_LINOFF 0x70284 +#define _SPRA_STRIDE 0x70288 +#define _SPRA_POS 0x7028c +#define _SPRA_SIZE 0x70290 +#define _SPRA_KEYVAL 0x70294 +#define _SPRA_KEYMSK 0x70298 +#define _SPRA_SURF 0x7029c +#define _SPRA_KEYMAX 0x702a0 +#define _SPRA_TILEOFF 0x702a4 +#define _SPRA_OFFSET 0x702a4 +#define _SPRA_SURFLIVE 0x702ac +#define _SPRA_SCALE 0x70304 +#define SPRITE_SCALE_ENABLE (1<<31) +#define SPRITE_FILTER_MASK (3<<29) +#define SPRITE_FILTER_MEDIUM (0<<29) +#define SPRITE_FILTER_ENHANCING (1<<29) +#define SPRITE_FILTER_SOFTENING (2<<29) +#define SPRITE_VERTICAL_OFFSET_HALF (1<<28) /* must be enabled below */ +#define SPRITE_VERTICAL_OFFSET_ENABLE (1<<27) +#define _SPRA_GAMC 0x70400 + +#define _SPRB_CTL 0x71280 +#define _SPRB_LINOFF 0x71284 +#define _SPRB_STRIDE 0x71288 +#define _SPRB_POS 0x7128c +#define _SPRB_SIZE 0x71290 +#define _SPRB_KEYVAL 0x71294 +#define _SPRB_KEYMSK 0x71298 +#define _SPRB_SURF 0x7129c +#define _SPRB_KEYMAX 0x712a0 +#define _SPRB_TILEOFF 0x712a4 +#define _SPRB_OFFSET 0x712a4 +#define _SPRB_SURFLIVE 0x712ac +#define _SPRB_SCALE 0x71304 +#define _SPRB_GAMC 0x71400 + +#define CHV_PRIMPOS_B (dev_priv->info.display_mmio_offset + 0x61A08) +#define CHV_PRIMSIZE_B (dev_priv->info.display_mmio_offset + 0x61A0C) + +#define CHV_SPC_CSC_YGOFF (dev_priv->info.display_mmio_offset + 0x6D900) +#define CHV_SPC_CSC_YGICLAMP (dev_priv->info.display_mmio_offset + 0x6D920) +#define CHV_SPC_CSC_YGOCLAMP (dev_priv->info.display_mmio_offset + 0x6D92C) +#define CHV_SPC_CSC_CBOFF (dev_priv->info.display_mmio_offset + 0x6D904) +#define CHV_SPC_CSC_CBICLAMP (dev_priv->info.display_mmio_offset + 0x6D924) +#define CHV_SPC_CSC_CBOCLAMP (dev_priv->info.display_mmio_offset + 0x6D930) +#define CHV_SPC_CSC_CROFF (dev_priv->info.display_mmio_offset + 0x6D908) +#define CHV_SPC_CSC_CRICLAMP (dev_priv->info.display_mmio_offset + 0x6D928) +#define CHV_SPC_CSC_CROCLAMP (dev_priv->info.display_mmio_offset + 0x6D934) +#define CHV_SPC_CSC_C01 (dev_priv->info.display_mmio_offset + 0x6D90C) +#define CHV_SPC_CSC_C23 (dev_priv->info.display_mmio_offset + 0x6D910) +#define CHV_SPC_CSC_C45 (dev_priv->info.display_mmio_offset + 0x6D914) +#define CHV_SPC_CSC_C67 (dev_priv->info.display_mmio_offset + 0x6D918) +#define CHV_SPC_CSC_C8 (dev_priv->info.display_mmio_offset + 0x6D91C) + +#define CHV_SPD_CSC_YGOFF (dev_priv->info.display_mmio_offset + 0x6E900) +#define CHV_SPD_CSC_YGICLAMP (dev_priv->info.display_mmio_offset + 0x6E920) +#define CHV_SPD_CSC_YGOCLAMP (dev_priv->info.display_mmio_offset + 0x6E92C) +#define CHV_SPD_CSC_CBOFF (dev_priv->info.display_mmio_offset + 0x6E904) +#define CHV_SPD_CSC_CBICLAMP (dev_priv->info.display_mmio_offset + 0x6E924) +#define CHV_SPD_CSC_CBOCLAMP (dev_priv->info.display_mmio_offset + 0x6E930) +#define CHV_SPD_CSC_CROFF (dev_priv->info.display_mmio_offset + 0x6E908) +#define CHV_SPD_CSC_CRICLAMP (dev_priv->info.display_mmio_offset + 0x6E928) +#define CHV_SPD_CSC_CROCLAMP (dev_priv->info.display_mmio_offset + 0x6E934) +#define CHV_SPD_CSC_C01 (dev_priv->info.display_mmio_offset + 0x6E90C) +#define CHV_SPD_CSC_C23 (dev_priv->info.display_mmio_offset + 0x6E910) +#define CHV_SPD_CSC_C45 (dev_priv->info.display_mmio_offset + 0x6E914) +#define CHV_SPD_CSC_C67 (dev_priv->info.display_mmio_offset + 0x6E918) +#define CHV_SPD_CSC_C8 (dev_priv->info.display_mmio_offset + 0x6E91C) + +#define CHV_SPCSC_YGOFF(plane) (!plane ? CHV_SPC_CSC_YGOFF : CHV_SPD_CSC_YGOFF) +#define CHV_SPCSC_CBOFF(plane) (!plane ? CHV_SPC_CSC_CBOFF : CHV_SPD_CSC_CBOFF) +#define CHV_SPCSC_CROFF(plane) (!plane ? CHV_SPC_CSC_CROFF : CHV_SPD_CSC_CROFF) +#define CHV_SPCSC_YGICLAMP(plane) (!plane ? CHV_SPC_CSC_YGICLAMP : \ + CHV_SPD_CSC_YGICLAMP) +#define CHV_SPCSC_CBICLAMP(plane) (!plane ? CHV_SPC_CSC_CBICLAMP : \ + CHV_SPD_CSC_CBICLAMP) +#define CHV_SPCSC_CRICLAMP(plane) (!plane ? CHV_SPC_CSC_CRICLAMP : \ + CHV_SPD_CSC_CRICLAMP) +#define CHV_SPCSC_YGOCLAMP(plane) (!plane ? CHV_SPC_CSC_YGOCLAMP : \ + CHV_SPD_CSC_YGOCLAMP) +#define CHV_SPCSC_CBOCLAMP(plane) (!plane ? CHV_SPC_CSC_CBOCLAMP : \ + CHV_SPD_CSC_CBOCLAMP) +#define CHV_SPCSC_CROCLAMP(plane) (!plane ? CHV_SPC_CSC_CROCLAMP : \ + CHV_SPD_CSC_CROCLAMP) + +#define CHV_SPCSC_C01(plane) (!plane ? CHV_SPC_CSC_C01 : CHV_SPD_CSC_C01) +#define CHV_SPCSC_C23(plane) (!plane ? CHV_SPC_CSC_C23 : CHV_SPD_CSC_C23) +#define CHV_SPCSC_C45(plane) (!plane ? CHV_SPC_CSC_C45 : CHV_SPD_CSC_C45) +#define CHV_SPCSC_C67(plane) (!plane ? CHV_SPC_CSC_C67 : CHV_SPD_CSC_C67) +#define CHV_SPCSC_C8(plane) (!plane ? CHV_SPC_CSC_C8 : CHV_SPD_CSC_C8) + +#define CHV_SPCSC_CLAMP(plane, channel, inout) \ + (!channel ? (!inout ? CHV_SPCSC_YGICLAMP(plane) : \ + CHV_SPCSC_YGOCLAMP(plane)) : \ + (channel == 1 ? (!inout ? CHV_SPCSC_CBICLAMP(plane) : \ + CHV_SPCSC_CBOCLAMP(plane)) : \ + (!inout ? CHV_SPCSC_CRICLAMP(plane) : \ + CHV_SPCSC_CROCLAMP(plane)))) + +#define CHV_SPCSC_OFFSET(plane, channel) \ + (!channel ? CHV_SPCSC_YGOFF(plane) : \ + (channel == 1 ? CHV_SPCSC_CBOFF(plane) : \ + CHV_SPCSC_CROFF(plane))) + +#define CHV_SPCSC_COEFFS(plane, coeff_index) \ + (!coeff_index ? CHV_SPCSC_C01(plane) : \ + (coeff_index == 2 ? CHV_SPCSC_C23(plane) : \ + (coeff_index == 4 ? CHV_SPCSC_C45(plane) : \ + (coeff_index == 6 ? CHV_SPCSC_C67(plane) : \ + CHV_SPCSC_C8(plane))))) + +#define SPRCTL(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL) +#define SPRLINOFF(pipe) _PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF) +#define SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE) +#define SPRPOS(pipe) _PIPE(pipe, _SPRA_POS, _SPRB_POS) +#define SPRSIZE(pipe) _PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE) +#define SPRKEYVAL(pipe) _PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL) +#define SPRKEYMSK(pipe) _PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK) +#define SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF) +#define SPRSURFLIVE(pipe) _PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE) +#define SPRKEYMAX(pipe) _PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX) +#define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF) +#define SPROFFSET(pipe) _PIPE(pipe, _SPRA_OFFSET, _SPRB_OFFSET) +#define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE) +#define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC) +#define SPRSURFLIVE(pipe) _PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE) + +#define _SPACNTR (VLV_DISPLAY_BASE + 0x72180) +#define SP_ENABLE (1<<31) +#define SP_GAMMA_ENABLE (1<<30) +#define SP_PIXFORMAT_MASK (0xf<<26) +#define SP_FORMAT_YUV422 (0<<26) +#define SP_FORMAT_BGR565 (5<<26) +#define SP_FORMAT_BGRX8888 (6<<26) +#define SP_FORMAT_BGRA8888 (7<<26) +#define SP_FORMAT_RGBX1010102 (8<<26) +#define SP_FORMAT_RGBA1010102 (9<<26) +#define SP_FORMAT_RGBX8888 (0xe<<26) +#define SP_FORMAT_RGBA8888 (0xf<<26) +#define SP_SOURCE_KEY (1<<22) +#define SP_YUV_BYTE_ORDER_MASK (3<<16) +#define SP_YUV_ORDER_YUYV (0<<16) +#define SP_YUV_ORDER_UYVY (1<<16) +#define SP_YUV_ORDER_YVYU (2<<16) +#define SP_YUV_ORDER_VYUY (3<<16) +#define SP_TILED (1<<10) +#define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184) +#define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188) +#define _SPAPOS (VLV_DISPLAY_BASE + 0x7218c) +#define _SPASIZE (VLV_DISPLAY_BASE + 0x72190) +#define _SPAKEYMINVAL (VLV_DISPLAY_BASE + 0x72194) +#define _SPAKEYMSK (VLV_DISPLAY_BASE + 0x72198) +#define _SPASURF (VLV_DISPLAY_BASE + 0x7219c) +#define _SPAKEYMAXVAL (VLV_DISPLAY_BASE + 0x721a0) +#define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4) +#define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8) +#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721f4) + +#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280) +#define _SPBLINOFF (VLV_DISPLAY_BASE + 0x72284) +#define _SPBSTRIDE (VLV_DISPLAY_BASE + 0x72288) +#define _SPBPOS (VLV_DISPLAY_BASE + 0x7228c) +#define _SPBSIZE (VLV_DISPLAY_BASE + 0x72290) +#define _SPBKEYMINVAL (VLV_DISPLAY_BASE + 0x72294) +#define _SPBKEYMSK (VLV_DISPLAY_BASE + 0x72298) +#define _SPBSURF (VLV_DISPLAY_BASE + 0x7229c) +#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0) +#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4) +#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8) +#define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4) +#define VLV_NUM_SPRITES 2 + +#define _SPCCNTR (VLV_DISPLAY_BASE + 0x72380) +#define _SPDCNTR (VLV_DISPLAY_BASE + 0x72480) + +#define SPCNTR(pipe, plane) _PIPE(pipe * 2 + plane, _SPACNTR, _SPBCNTR) +#define SPLINOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPALINOFF, _SPBLINOFF) +#define SPSTRIDE(pipe, plane) _PIPE(pipe * 2 + plane, _SPASTRIDE, _SPBSTRIDE) +#define SPPOS(pipe, plane) _PIPE(pipe * 2 + plane, _SPAPOS, _SPBPOS) +#define SPSIZE(pipe, plane) _PIPE(pipe * 2 + plane, _SPASIZE, _SPBSIZE) +#define SPKEYMINVAL(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMINVAL, _SPBKEYMINVAL) +#define SPKEYMSK(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMSK, _SPBKEYMSK) +#define SPSURF(pipe, plane) _PIPE(pipe * 2 + plane, _SPASURF, _SPBSURF) +#define SPKEYMAXVAL(pipe, plane) _PIPE(pipe * 2 + plane, _SPAKEYMAXVAL, _SPBKEYMAXVAL) +#define SPTILEOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPATILEOFF, _SPBTILEOFF) +#define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA, _SPBCONSTALPHA) +#define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC) + +/* VBIOS regs */ +#define VGACNTRL 0x71400 +# define VGA_DISP_DISABLE (1 << 31) +# define VGA_2X_MODE (1 << 30) +# define VGA_PIPE_B_SELECT (1 << 29) + +#define VLV_VGACNTRL (VLV_DISPLAY_BASE + 0x71400) + +/* Ironlake */ + +#define CPU_VGACNTRL 0x41000 + +#define DIGITAL_PORT_HOTPLUG_CNTRL 0x44030 +#define DIGITAL_PORTA_HOTPLUG_ENABLE (1 << 4) +#define DIGITAL_PORTA_SHORT_PULSE_2MS (0 << 2) +#define DIGITAL_PORTA_SHORT_PULSE_4_5MS (1 << 2) +#define DIGITAL_PORTA_SHORT_PULSE_6MS (2 << 2) +#define DIGITAL_PORTA_SHORT_PULSE_100MS (3 << 2) +#define DIGITAL_PORTA_NO_DETECT (0 << 0) +#define DIGITAL_PORTA_LONG_PULSE_DETECT_MASK (1 << 1) +#define DIGITAL_PORTA_SHORT_PULSE_DETECT_MASK (1 << 0) + +/* refresh rate hardware control */ +#define RR_HW_CTL 0x45300 +#define RR_HW_LOW_POWER_FRAMES_MASK 0xff +#define RR_HW_HIGH_POWER_FRAMES_MASK 0xff00 + +#define FDI_PLL_BIOS_0 0x46000 +#define FDI_PLL_FB_CLOCK_MASK 0xff +#define FDI_PLL_BIOS_1 0x46004 +#define FDI_PLL_BIOS_2 0x46008 +#define DISPLAY_PORT_PLL_BIOS_0 0x4600c +#define DISPLAY_PORT_PLL_BIOS_1 0x46010 +#define DISPLAY_PORT_PLL_BIOS_2 0x46014 + +#define PCH_3DCGDIS0 0x46020 +# define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) +# define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) + +#define PCH_3DCGDIS1 0x46024 +# define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11) + +#define FDI_PLL_FREQ_CTL 0x46030 +#define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) +#define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 +#define FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK 0xff + + +#define _PIPEA_DATA_M1 0x60030 +#define PIPE_DATA_M1_OFFSET 0 +#define _PIPEA_DATA_N1 0x60034 +#define PIPE_DATA_N1_OFFSET 0 + +#define _PIPEA_DATA_M2 0x60038 +#define PIPE_DATA_M2_OFFSET 0 +#define _PIPEA_DATA_N2 0x6003c +#define PIPE_DATA_N2_OFFSET 0 + +#define _PIPEA_LINK_M1 0x60040 +#define PIPE_LINK_M1_OFFSET 0 +#define _PIPEA_LINK_N1 0x60044 +#define PIPE_LINK_N1_OFFSET 0 + +#define _PIPEA_LINK_M2 0x60048 +#define PIPE_LINK_M2_OFFSET 0 +#define _PIPEA_LINK_N2 0x6004c +#define PIPE_LINK_N2_OFFSET 0 + +/* PIPEB timing regs are same start from 0x61000 */ + +#define _PIPEB_DATA_M1 0x61030 +#define _PIPEB_DATA_N1 0x61034 +#define _PIPEB_DATA_M2 0x61038 +#define _PIPEB_DATA_N2 0x6103c +#define _PIPEB_LINK_M1 0x61040 +#define _PIPEB_LINK_N1 0x61044 +#define _PIPEB_LINK_M2 0x61048 +#define _PIPEB_LINK_N2 0x6104c + +#define PIPE_DATA_M1(tran) _TRANSCODER2(tran, _PIPEA_DATA_M1) +#define PIPE_DATA_N1(tran) _TRANSCODER2(tran, _PIPEA_DATA_N1) +#define PIPE_DATA_M2(tran) _TRANSCODER2(tran, _PIPEA_DATA_M2) +#define PIPE_DATA_N2(tran) _TRANSCODER2(tran, _PIPEA_DATA_N2) +#define PIPE_LINK_M1(tran) _TRANSCODER2(tran, _PIPEA_LINK_M1) +#define PIPE_LINK_N1(tran) _TRANSCODER2(tran, _PIPEA_LINK_N1) +#define PIPE_LINK_M2(tran) _TRANSCODER2(tran, _PIPEA_LINK_M2) +#define PIPE_LINK_N2(tran) _TRANSCODER2(tran, _PIPEA_LINK_N2) + +/* CPU panel fitter */ +/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */ +#define _PFA_CTL_1 0x68080 +#define _PFB_CTL_1 0x68880 +#define PF_ENABLE (1<<31) +#define PF_PIPE_SEL_MASK_IVB (3<<29) +#define PF_PIPE_SEL_IVB(pipe) ((pipe)<<29) +#define PF_FILTER_MASK (3<<23) +#define PF_FILTER_PROGRAMMED (0<<23) +#define PF_FILTER_MED_3x3 (1<<23) +#define PF_FILTER_EDGE_ENHANCE (2<<23) +#define PF_FILTER_EDGE_SOFTEN (3<<23) +#define _PFA_WIN_SZ 0x68074 +#define _PFB_WIN_SZ 0x68874 +#define _PFA_WIN_POS 0x68070 +#define _PFB_WIN_POS 0x68870 +#define _PFA_VSCALE 0x68084 +#define _PFB_VSCALE 0x68884 +#define _PFA_HSCALE 0x68090 +#define _PFB_HSCALE 0x68890 + +#define PF_CTL(pipe) _PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1) +#define PF_WIN_SZ(pipe) _PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ) +#define PF_WIN_POS(pipe) _PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS) +#define PF_VSCALE(pipe) _PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE) +#define PF_HSCALE(pipe) _PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE) + +/* legacy palette */ +#define _LGC_PALETTE_A 0x4a000 +#define _LGC_PALETTE_B 0x4a800 +#define LGC_PALETTE(pipe) _PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + +#define _GAMMA_MODE_A 0x4a480 +#define _GAMMA_MODE_B 0x4ac80 +#define GAMMA_MODE(pipe) _PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B) +#define GAMMA_MODE_MODE_MASK (3 << 0) +#define GAMMA_MODE_MODE_8BIT (0 << 0) +#define GAMMA_MODE_MODE_10BIT (1 << 0) +#define GAMMA_MODE_MODE_12BIT (2 << 0) +#define GAMMA_MODE_MODE_SPLIT (3 << 0) + +/* interrupts */ +#define DE_MASTER_IRQ_CONTROL (1 << 31) +#define DE_SPRITEB_FLIP_DONE (1 << 29) +#define DE_SPRITEA_FLIP_DONE (1 << 28) +#define DE_PLANEB_FLIP_DONE (1 << 27) +#define DE_PLANEA_FLIP_DONE (1 << 26) +#define DE_PLANE_FLIP_DONE(plane) (1 << (26 + (plane))) +#define DE_PCU_EVENT (1 << 25) +#define DE_GTT_FAULT (1 << 24) +#define DE_POISON (1 << 23) +#define DE_PERFORM_COUNTER (1 << 22) +#define DE_PCH_EVENT (1 << 21) +#define DE_AUX_CHANNEL_A (1 << 20) +#define DE_DP_A_HOTPLUG (1 << 19) +#define DE_GSE (1 << 18) +#define DE_PIPEB_VBLANK (1 << 15) +#define DE_PIPEB_EVEN_FIELD (1 << 14) +#define DE_PIPEB_ODD_FIELD (1 << 13) +#define DE_PIPEB_LINE_COMPARE (1 << 12) +#define DE_PIPEB_VSYNC (1 << 11) +#define DE_PIPEB_CRC_DONE (1 << 10) +#define DE_PIPEB_FIFO_UNDERRUN (1 << 8) +#define DE_PIPEA_VBLANK (1 << 7) +#define DE_PIPE_VBLANK(pipe) (1 << (7 + 8*(pipe))) +#define DE_PIPEA_EVEN_FIELD (1 << 6) +#define DE_PIPEA_ODD_FIELD (1 << 5) +#define DE_PIPEA_LINE_COMPARE (1 << 4) +#define DE_PIPEA_VSYNC (1 << 3) +#define DE_PIPEA_CRC_DONE (1 << 2) +#define DE_PIPE_CRC_DONE(pipe) (1 << (2 + 8*(pipe))) +#define DE_PIPEA_FIFO_UNDERRUN (1 << 0) +#define DE_PIPE_FIFO_UNDERRUN(pipe) (1 << (8*(pipe))) + +/* More Ivybridge lolz */ +#define DE_ERR_INT_IVB (1<<30) +#define DE_GSE_IVB (1<<29) +#define DE_PCH_EVENT_IVB (1<<28) +#define DE_DP_A_HOTPLUG_IVB (1<<27) +#define DE_AUX_CHANNEL_A_IVB (1<<26) +#define DE_DPST_HISTOGRAM_IVB (1<<25) +#define DE_SPRITEC_FLIP_DONE_IVB (1<<14) +#define DE_PLANEC_FLIP_DONE_IVB (1<<13) +#define DE_PIPEC_VBLANK_IVB (1<<10) +#define DE_SPRITEB_FLIP_DONE_IVB (1<<9) +#define DE_PLANEB_FLIP_DONE_IVB (1<<8) +#define DE_PIPEB_VBLANK_IVB (1<<5) +#define DE_SPRITEA_FLIP_DONE_IVB (1<<4) +#define DE_PLANEA_FLIP_DONE_IVB (1<<3) +#define DE_PLANE_FLIP_DONE_IVB(plane) (1<< (3 + 5*(plane))) +#define DE_PIPEA_VBLANK_IVB (1<<0) +#define DE_PIPE_VBLANK_IVB(pipe) (1 << (pipe * 5)) + +#define VLV_MASTER_IER 0x4400c /* Gunit master IER */ +#define MASTER_INTERRUPT_ENABLE (1<<31) + +#define DEISR 0x44000 +#define DEIMR 0x44004 +#define DEIIR 0x44008 +#define DEIER 0x4400c + +#define GTISR 0x44010 +#define GTIMR 0x44014 +#define GTIIR 0x44018 +#define GTIER 0x4401c + +#define GEN8_MASTER_IRQ 0x44200 +#define GEN8_MASTER_IRQ_CONTROL (1<<31) +#define GEN8_PCU_IRQ (1<<30) +#define GEN8_DE_PCH_IRQ (1<<23) +#define GEN8_DE_MISC_IRQ (1<<22) +#define GEN8_DE_PORT_IRQ (1<<20) +#define GEN8_DE_PIPE_C_IRQ (1<<18) +#define GEN8_DE_PIPE_B_IRQ (1<<17) +#define GEN8_DE_PIPE_A_IRQ (1<<16) +#define GEN8_DE_PIPE_IRQ(pipe) (1<<(16+pipe)) +#define GEN8_GT_OACS_IRQ (1<<7) +#define GEN8_GT_VECS_IRQ (1<<6) +#define GEN8_GT_PM_IRQ (1<<4) +#define GEN8_GT_VCS2_IRQ (1<<3) +#define GEN8_GT_VCS1_IRQ (1<<2) +#define GEN8_GT_BCS_IRQ (1<<1) +#define GEN8_GT_RCS_IRQ (1<<0) + +#define GEN8_GT_ISR(which) (0x44300 + (0x10 * (which))) +#define GEN8_GT_IMR(which) (0x44304 + (0x10 * (which))) +#define GEN8_GT_IIR(which) (0x44308 + (0x10 * (which))) +#define GEN8_GT_IER(which) (0x4430c + (0x10 * (which))) + +#define GEN8_BCS_IRQ_SHIFT 16 +#define GEN8_RCS_IRQ_SHIFT 0 +#define GEN8_VCS2_IRQ_SHIFT 16 +#define GEN8_VCS1_IRQ_SHIFT 0 +#define GEN8_VECS_IRQ_SHIFT 0 +#define GEN8_OACS_IRQ_SHIFT 19 + +#define GEN8_DE_PIPE_ISR(pipe) (0x44400 + (0x10 * (pipe))) +#define GEN8_DE_PIPE_IMR(pipe) (0x44404 + (0x10 * (pipe))) +#define GEN8_DE_PIPE_IIR(pipe) (0x44408 + (0x10 * (pipe))) +#define GEN8_DE_PIPE_IER(pipe) (0x4440c + (0x10 * (pipe))) +#define GEN8_PIPE_FIFO_UNDERRUN (1 << 31) +#define GEN8_PIPE_CDCLK_CRC_ERROR (1 << 29) +#define GEN8_PIPE_CDCLK_CRC_DONE (1 << 28) +#define GEN8_PIPE_DPST_INTERRUPT (1 << 12) +#define GEN8_PIPE_CURSOR_FAULT (1 << 10) +#define GEN8_PIPE_SPRITE_FAULT (1 << 9) +#define GEN8_PIPE_PRIMARY_FAULT (1 << 8) +#define GEN8_PIPE_SPRITE_FLIP_DONE (1 << 5) +#define GEN8_PIPE_PRIMARY_FLIP_DONE (1 << 4) +#define GEN8_PIPE_SCAN_LINE_EVENT (1 << 2) +#define GEN8_PIPE_VSYNC (1 << 1) +#define GEN8_PIPE_VBLANK (1 << 0) +#define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \ + (GEN8_PIPE_CURSOR_FAULT | \ + GEN8_PIPE_SPRITE_FAULT | \ + GEN8_PIPE_PRIMARY_FAULT) + +#define GEN8_DE_PORT_ISR 0x44440 +#define GEN8_DE_PORT_IMR 0x44444 +#define GEN8_DE_PORT_IIR 0x44448 +#define GEN8_DE_PORT_IER 0x4444c +#define GEN8_PORT_DP_A_HOTPLUG (1 << 3) +#define GEN8_AUX_CHANNEL_A (1 << 0) + +#define GEN8_DE_MISC_ISR 0x44460 +#define GEN8_DE_MISC_IMR 0x44464 +#define GEN8_DE_MISC_IIR 0x44468 +#define GEN8_DE_MISC_IER 0x4446c +#define GEN8_DE_MISC_GSE (1 << 27) + +#define GEN8_PCU_ISR 0x444e0 +#define GEN8_PCU_IMR 0x444e4 +#define GEN8_PCU_IIR 0x444e8 +#define GEN8_PCU_IER 0x444ec + +#define GEN8_OA_IMR 0x2b20 + +#define ILK_DISPLAY_CHICKEN2 0x42004 +/* Required on all Ironlake and Sandybridge according to the B-Spec. */ +#define ILK_ELPIN_409_SELECT (1 << 25) +#define ILK_DPARB_GATE (1<<22) +#define ILK_VSDPFD_FULL (1<<21) +#define FUSE_STRAP 0x42014 +#define ILK_INTERNAL_GRAPHICS_DISABLE (1 << 31) +#define ILK_INTERNAL_DISPLAY_DISABLE (1 << 30) +#define ILK_DISPLAY_DEBUG_DISABLE (1 << 29) +#define ILK_HDCP_DISABLE (1 << 25) +#define ILK_eDP_A_DISABLE (1 << 24) +#define HSW_CDCLK_LIMIT (1 << 24) +#define ILK_DESKTOP (1 << 23) + +#define ILK_DSPCLK_GATE_D 0x42020 +#define ILK_VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) +#define ILK_DPFCUNIT_CLOCK_GATE_DISABLE (1 << 9) +#define ILK_DPFCRUNIT_CLOCK_GATE_DISABLE (1 << 8) +#define ILK_DPFDUNIT_CLOCK_GATE_ENABLE (1 << 7) +#define ILK_DPARBUNIT_CLOCK_GATE_ENABLE (1 << 5) + +#define IVB_CHICKEN3 0x4200c +# define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE (1 << 5) +# define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2) + +#define CHICKEN_PAR1_1 0x42080 +#define DPA_MASK_VBLANK_SRD (1 << 15) +#define FORCE_ARB_IDLE_PLANES (1 << 14) + +#define _CHICKEN_PIPESL_1_A 0x420b0 +#define _CHICKEN_PIPESL_1_B 0x420b4 +#define HSW_FBCQ_DIS (1 << 22) +#define BDW_DPRS_MASK_VBLANK_SRD (1 << 0) +#define CHICKEN_PIPESL_1(pipe) _PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) + +#define DISP_ARB_CTL 0x45000 +#define DISP_TILE_SURFACE_SWIZZLING (1<<13) +#define DISP_FBC_WM_DIS (1<<15) +#define DISP_ARB_CTL2 0x45004 +#define DISP_DATA_PARTITION_5_6 (1<<6) +#define GEN7_MSG_CTL 0x45010 +#define WAIT_FOR_PCH_RESET_ACK (1<<1) +#define WAIT_FOR_PCH_FLR_ACK (1<<0) +#define HSW_NDE_RSTWRN_OPT 0x46408 +#define RESET_PCH_HANDSHAKE_ENABLE (1<<4) + +/* GEN7 chicken */ +#define GEN7_COMMON_SLICE_CHICKEN1 0x7010 +# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) +#define COMMON_SLICE_CHICKEN2 0x7014 +# define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1<<0) + +#define GEN7_L3SQCREG1 0xB010 +#define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000 + +#define GEN7_L3CNTLREG1 0xB01C +#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C +#define GEN7_L3AGDIS (1<<19) + +#define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030 +#define GEN7_WA_L3_CHICKEN_MODE 0x20000000 + +#define GEN7_L3SQCREG4 0xb034 +#define L3SQ_URB_READ_CAM_MATCH_DISABLE (1<<27) + +#define GEN8_L3CNTLREG 0x7034 +#define GEN8_L3CNTLREG_ALL_L3_CLIENT_POOL (48<<25) +#define GEN8_L3CNTLREG_URB_ALLOCATION (16<<1) +#define GEN8_L3CNTLREG_SLM_MODE_ENABLE (1<<0) + +/* GEN8 chicken */ +#define HDC_CHICKEN0 0x7300 +#define HDC_FENCE_DESTINATION_TO_SLM_DISABLE (1<<14) +#define HDC_DONOT_FETCH_MEM_WHEN_MASKED (1<<11) +#define HDC_FORCE_NON_COHERENT (1<<4) +#define HDC_FENCE_DEST_SLM_DISABLE (1<<14) + +/* WaProgramL3SqcReg1Default */ +#define GEN8_L3SQCREG1 0xb100 +#define GEN8_L3SQCREG1_DEFAULT_VALUE 0x784000 + +#define GEN8_L3CNTLREG1 0xb10c +#define GEN8_TAG_CLK_OFFTIME (1<<23) +#define GEN8_TAG_CLK_OFFTIME_MASK (~((1<<23) | (1<<22) | (1<<21) | (1<<20))) + +#define GEN8_L3SQCREG4 0xb118 +#define GEN8_L3SQCREG4_LQSC_RO_PERF_DISABLE (1<<27) +#define GEN8_PIPELINE_FLUSH_COHERENT_LINES (1<<21) + +/* WaCatErrorRejectionIssue */ +#define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030 +#define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) + +#define HSW_SCRATCH1 0xb038 +#define HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE (1<<27) + +/* PCH */ + +/* south display engine interrupt: IBX */ +#define SDE_AUDIO_POWER_D (1 << 27) +#define SDE_AUDIO_POWER_C (1 << 26) +#define SDE_AUDIO_POWER_B (1 << 25) +#define SDE_AUDIO_POWER_SHIFT (25) +#define SDE_AUDIO_POWER_MASK (7 << SDE_AUDIO_POWER_SHIFT) +#define SDE_GMBUS (1 << 24) +#define SDE_AUDIO_HDCP_TRANSB (1 << 23) +#define SDE_AUDIO_HDCP_TRANSA (1 << 22) +#define SDE_AUDIO_HDCP_MASK (3 << 22) +#define SDE_AUDIO_TRANSB (1 << 21) +#define SDE_AUDIO_TRANSA (1 << 20) +#define SDE_AUDIO_TRANS_MASK (3 << 20) +#define SDE_POISON (1 << 19) +/* 18 reserved */ +#define SDE_FDI_RXB (1 << 17) +#define SDE_FDI_RXA (1 << 16) +#define SDE_FDI_MASK (3 << 16) +#define SDE_AUXD (1 << 15) +#define SDE_AUXC (1 << 14) +#define SDE_AUXB (1 << 13) +#define SDE_AUX_MASK (7 << 13) +/* 12 reserved */ +#define SDE_CRT_HOTPLUG (1 << 11) +#define SDE_PORTD_HOTPLUG (1 << 10) +#define SDE_PORTC_HOTPLUG (1 << 9) +#define SDE_PORTB_HOTPLUG (1 << 8) +#define SDE_SDVOB_HOTPLUG (1 << 6) +#define SDE_HOTPLUG_MASK (SDE_CRT_HOTPLUG | \ + SDE_SDVOB_HOTPLUG | \ + SDE_PORTB_HOTPLUG | \ + SDE_PORTC_HOTPLUG | \ + SDE_PORTD_HOTPLUG) +#define SDE_TRANSB_CRC_DONE (1 << 5) +#define SDE_TRANSB_CRC_ERR (1 << 4) +#define SDE_TRANSB_FIFO_UNDER (1 << 3) +#define SDE_TRANSA_CRC_DONE (1 << 2) +#define SDE_TRANSA_CRC_ERR (1 << 1) +#define SDE_TRANSA_FIFO_UNDER (1 << 0) +#define SDE_TRANS_MASK (0x3f) + +/* south display engine interrupt: CPT/PPT */ +#define SDE_AUDIO_POWER_D_CPT (1 << 31) +#define SDE_AUDIO_POWER_C_CPT (1 << 30) +#define SDE_AUDIO_POWER_B_CPT (1 << 29) +#define SDE_AUDIO_POWER_SHIFT_CPT 29 +#define SDE_AUDIO_POWER_MASK_CPT (7 << 29) +#define SDE_AUXD_CPT (1 << 27) +#define SDE_AUXC_CPT (1 << 26) +#define SDE_AUXB_CPT (1 << 25) +#define SDE_AUX_MASK_CPT (7 << 25) +#define SDE_PORTD_HOTPLUG_CPT (1 << 23) +#define SDE_PORTC_HOTPLUG_CPT (1 << 22) +#define SDE_PORTB_HOTPLUG_CPT (1 << 21) +#define SDE_CRT_HOTPLUG_CPT (1 << 19) +#define SDE_SDVOB_HOTPLUG_CPT (1 << 18) +#define SDE_HOTPLUG_MASK_CPT (SDE_CRT_HOTPLUG_CPT | \ + SDE_SDVOB_HOTPLUG_CPT | \ + SDE_PORTD_HOTPLUG_CPT | \ + SDE_PORTC_HOTPLUG_CPT | \ + SDE_PORTB_HOTPLUG_CPT) +#define SDE_GMBUS_CPT (1 << 17) +#define SDE_ERROR_CPT (1 << 16) +#define SDE_AUDIO_CP_REQ_C_CPT (1 << 10) +#define SDE_AUDIO_CP_CHG_C_CPT (1 << 9) +#define SDE_FDI_RXC_CPT (1 << 8) +#define SDE_AUDIO_CP_REQ_B_CPT (1 << 6) +#define SDE_AUDIO_CP_CHG_B_CPT (1 << 5) +#define SDE_FDI_RXB_CPT (1 << 4) +#define SDE_AUDIO_CP_REQ_A_CPT (1 << 2) +#define SDE_AUDIO_CP_CHG_A_CPT (1 << 1) +#define SDE_FDI_RXA_CPT (1 << 0) +#define SDE_AUDIO_CP_REQ_CPT (SDE_AUDIO_CP_REQ_C_CPT | \ + SDE_AUDIO_CP_REQ_B_CPT | \ + SDE_AUDIO_CP_REQ_A_CPT) +#define SDE_AUDIO_CP_CHG_CPT (SDE_AUDIO_CP_CHG_C_CPT | \ + SDE_AUDIO_CP_CHG_B_CPT | \ + SDE_AUDIO_CP_CHG_A_CPT) +#define SDE_FDI_MASK_CPT (SDE_FDI_RXC_CPT | \ + SDE_FDI_RXB_CPT | \ + SDE_FDI_RXA_CPT) + +#define SDEISR 0xc4000 +#define SDEIMR 0xc4004 +#define SDEIIR 0xc4008 +#define SDEIER 0xc400c + +#define SERR_INT 0xc4040 +#define SERR_INT_POISON (1<<31) +#define SERR_INT_TRANS_C_FIFO_UNDERRUN (1<<6) +#define SERR_INT_TRANS_B_FIFO_UNDERRUN (1<<3) +#define SERR_INT_TRANS_A_FIFO_UNDERRUN (1<<0) +#define SERR_INT_TRANS_FIFO_UNDERRUN(pipe) (1<<(pipe*3)) + +/* digital port hotplug */ +#define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */ +#define PORTD_HOTPLUG_ENABLE (1 << 20) +#define PORTD_PULSE_DURATION_2ms (0) +#define PORTD_PULSE_DURATION_4_5ms (1 << 18) +#define PORTD_PULSE_DURATION_6ms (2 << 18) +#define PORTD_PULSE_DURATION_100ms (3 << 18) +#define PORTD_PULSE_DURATION_MASK (3 << 18) +#define PORTD_HOTPLUG_STATUS_MASK (0x3 << 16) +#define PORTD_HOTPLUG_NO_DETECT (0 << 16) +#define PORTD_HOTPLUG_SHORT_DETECT (1 << 16) +#define PORTD_HOTPLUG_LONG_DETECT (2 << 16) +#define PORTC_HOTPLUG_ENABLE (1 << 12) +#define PORTC_PULSE_DURATION_2ms (0) +#define PORTC_PULSE_DURATION_4_5ms (1 << 10) +#define PORTC_PULSE_DURATION_6ms (2 << 10) +#define PORTC_PULSE_DURATION_100ms (3 << 10) +#define PORTC_PULSE_DURATION_MASK (3 << 10) +#define PORTC_HOTPLUG_STATUS_MASK (0x3 << 8) +#define PORTC_HOTPLUG_NO_DETECT (0 << 8) +#define PORTC_HOTPLUG_SHORT_DETECT (1 << 8) +#define PORTC_HOTPLUG_LONG_DETECT (2 << 8) +#define PORTB_HOTPLUG_ENABLE (1 << 4) +#define PORTB_PULSE_DURATION_2ms (0) +#define PORTB_PULSE_DURATION_4_5ms (1 << 2) +#define PORTB_PULSE_DURATION_6ms (2 << 2) +#define PORTB_PULSE_DURATION_100ms (3 << 2) +#define PORTB_PULSE_DURATION_MASK (3 << 2) +#define PORTB_HOTPLUG_STATUS_MASK (0x3 << 0) +#define PORTB_HOTPLUG_NO_DETECT (0 << 0) +#define PORTB_HOTPLUG_SHORT_DETECT (1 << 0) +#define PORTB_HOTPLUG_LONG_DETECT (2 << 0) + +#define PCH_GPIOA 0xc5010 +#define PCH_GPIOB 0xc5014 +#define PCH_GPIOC 0xc5018 +#define PCH_GPIOD 0xc501c +#define PCH_GPIOE 0xc5020 +#define PCH_GPIOF 0xc5024 + +#define PCH_GMBUS0 0xc5100 +#define PCH_GMBUS1 0xc5104 +#define PCH_GMBUS2 0xc5108 +#define PCH_GMBUS3 0xc510c +#define PCH_GMBUS4 0xc5110 +#define PCH_GMBUS5 0xc5120 + +#define _PCH_DPLL_A 0xc6014 +#define _PCH_DPLL_B 0xc6018 +#define PCH_DPLL(pll) (pll == 0 ? _PCH_DPLL_A : _PCH_DPLL_B) + +#define _PCH_FPA0 0xc6040 +#define FP_CB_TUNE (0x3<<22) +#define _PCH_FPA1 0xc6044 +#define _PCH_FPB0 0xc6048 +#define _PCH_FPB1 0xc604c +#define PCH_FP0(pll) (pll == 0 ? _PCH_FPA0 : _PCH_FPB0) +#define PCH_FP1(pll) (pll == 0 ? _PCH_FPA1 : _PCH_FPB1) + +#define PCH_DPLL_TEST 0xc606c + +#define PCH_DREF_CONTROL 0xC6200 +#define DREF_CONTROL_MASK 0x7fc3 +#define DREF_CPU_SOURCE_OUTPUT_DISABLE (0<<13) +#define DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD (2<<13) +#define DREF_CPU_SOURCE_OUTPUT_NONSPREAD (3<<13) +#define DREF_CPU_SOURCE_OUTPUT_MASK (3<<13) +#define DREF_SSC_SOURCE_DISABLE (0<<11) +#define DREF_SSC_SOURCE_ENABLE (2<<11) +#define DREF_SSC_SOURCE_MASK (3<<11) +#define DREF_NONSPREAD_SOURCE_DISABLE (0<<9) +#define DREF_NONSPREAD_CK505_ENABLE (1<<9) +#define DREF_NONSPREAD_SOURCE_ENABLE (2<<9) +#define DREF_NONSPREAD_SOURCE_MASK (3<<9) +#define DREF_SUPERSPREAD_SOURCE_DISABLE (0<<7) +#define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7) +#define DREF_SUPERSPREAD_SOURCE_MASK (3<<7) +#define DREF_SSC4_DOWNSPREAD (0<<6) +#define DREF_SSC4_CENTERSPREAD (1<<6) +#define DREF_SSC1_DISABLE (0<<1) +#define DREF_SSC1_ENABLE (1<<1) +#define DREF_SSC4_DISABLE (0) +#define DREF_SSC4_ENABLE (1) + +#define PCH_RAWCLK_FREQ 0xc6204 +#define FDL_TP1_TIMER_SHIFT 12 +#define FDL_TP1_TIMER_MASK (3<<12) +#define FDL_TP2_TIMER_SHIFT 10 +#define FDL_TP2_TIMER_MASK (3<<10) +#define RAWCLK_FREQ_MASK 0x3ff + +#define PCH_DPLL_TMR_CFG 0xc6208 + +#define PCH_SSC4_PARMS 0xc6210 +#define PCH_SSC4_AUX_PARMS 0xc6214 + +#define PCH_DPLL_SEL 0xc7000 +#define TRANS_DPLLB_SEL(pipe) (1 << (pipe * 4)) +#define TRANS_DPLLA_SEL(pipe) 0 +#define TRANS_DPLL_ENABLE(pipe) (1 << (pipe * 4 + 3)) + +/* transcoder */ + +#define _PCH_TRANS_HTOTAL_A 0xe0000 +#define TRANS_HTOTAL_SHIFT 16 +#define TRANS_HACTIVE_SHIFT 0 +#define _PCH_TRANS_HBLANK_A 0xe0004 +#define TRANS_HBLANK_END_SHIFT 16 +#define TRANS_HBLANK_START_SHIFT 0 +#define _PCH_TRANS_HSYNC_A 0xe0008 +#define TRANS_HSYNC_END_SHIFT 16 +#define TRANS_HSYNC_START_SHIFT 0 +#define _PCH_TRANS_VTOTAL_A 0xe000c +#define TRANS_VTOTAL_SHIFT 16 +#define TRANS_VACTIVE_SHIFT 0 +#define _PCH_TRANS_VBLANK_A 0xe0010 +#define TRANS_VBLANK_END_SHIFT 16 +#define TRANS_VBLANK_START_SHIFT 0 +#define _PCH_TRANS_VSYNC_A 0xe0014 +#define TRANS_VSYNC_END_SHIFT 16 +#define TRANS_VSYNC_START_SHIFT 0 +#define _PCH_TRANS_VSYNCSHIFT_A 0xe0028 + +#define _PCH_TRANSA_DATA_M1 0xe0030 +#define _PCH_TRANSA_DATA_N1 0xe0034 +#define _PCH_TRANSA_DATA_M2 0xe0038 +#define _PCH_TRANSA_DATA_N2 0xe003c +#define _PCH_TRANSA_LINK_M1 0xe0040 +#define _PCH_TRANSA_LINK_N1 0xe0044 +#define _PCH_TRANSA_LINK_M2 0xe0048 +#define _PCH_TRANSA_LINK_N2 0xe004c + +/* Per-transcoder DIP controls (PCH) */ +#define _VIDEO_DIP_CTL_A 0xe0200 +#define _VIDEO_DIP_DATA_A 0xe0208 +#define _VIDEO_DIP_GCP_A 0xe0210 + +#define _VIDEO_DIP_CTL_B 0xe1200 +#define _VIDEO_DIP_DATA_B 0xe1208 +#define _VIDEO_DIP_GCP_B 0xe1210 + +#define TVIDEO_DIP_CTL(pipe) _PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B) +#define TVIDEO_DIP_DATA(pipe) _PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B) +#define TVIDEO_DIP_GCP(pipe) _PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B) + +/* Per-transcoder DIP controls (VLV) */ +#define VLV_VIDEO_DIP_CTL_A (VLV_DISPLAY_BASE + 0x60200) +#define VLV_VIDEO_DIP_DATA_A (VLV_DISPLAY_BASE + 0x60208) +#define VLV_VIDEO_DIP_GDCP_PAYLOAD_A (VLV_DISPLAY_BASE + 0x60210) + +#define VLV_VIDEO_DIP_CTL_B (VLV_DISPLAY_BASE + 0x61170) +#define VLV_VIDEO_DIP_DATA_B (VLV_DISPLAY_BASE + 0x61174) +#define VLV_VIDEO_DIP_GDCP_PAYLOAD_B (VLV_DISPLAY_BASE + 0x61178) + +#define CHV_VIDEO_DIP_CTL_C (VLV_DISPLAY_BASE + 0x611f0) +#define CHV_VIDEO_DIP_DATA_C (VLV_DISPLAY_BASE + 0x611f4) +#define CHV_VIDEO_DIP_GDCP_PAYLOAD_C (VLV_DISPLAY_BASE + 0x611f8) + +#define VLV_TVIDEO_DIP_CTL(pipe) \ + _PIPE3((pipe), VLV_VIDEO_DIP_CTL_A, \ + VLV_VIDEO_DIP_CTL_B, CHV_VIDEO_DIP_CTL_C) +#define VLV_TVIDEO_DIP_DATA(pipe) \ + _PIPE3((pipe), VLV_VIDEO_DIP_DATA_A, \ + VLV_VIDEO_DIP_DATA_B, CHV_VIDEO_DIP_DATA_C) +#define VLV_TVIDEO_DIP_GCP(pipe) \ + _PIPE3((pipe), VLV_VIDEO_DIP_GDCP_PAYLOAD_A, \ + VLV_VIDEO_DIP_GDCP_PAYLOAD_B, CHV_VIDEO_DIP_GDCP_PAYLOAD_C) + +/* Haswell DIP controls */ +#define HSW_VIDEO_DIP_CTL_A 0x60200 +#define HSW_VIDEO_DIP_AVI_DATA_A 0x60220 +#define HSW_VIDEO_DIP_VS_DATA_A 0x60260 +#define HSW_VIDEO_DIP_SPD_DATA_A 0x602A0 +#define HSW_VIDEO_DIP_GMP_DATA_A 0x602E0 +#define HSW_VIDEO_DIP_VSC_DATA_A 0x60320 +#define HSW_VIDEO_DIP_AVI_ECC_A 0x60240 +#define HSW_VIDEO_DIP_VS_ECC_A 0x60280 +#define HSW_VIDEO_DIP_SPD_ECC_A 0x602C0 +#define HSW_VIDEO_DIP_GMP_ECC_A 0x60300 +#define HSW_VIDEO_DIP_VSC_ECC_A 0x60344 +#define HSW_VIDEO_DIP_GCP_A 0x60210 + +#define HSW_VIDEO_DIP_CTL_B 0x61200 +#define HSW_VIDEO_DIP_AVI_DATA_B 0x61220 +#define HSW_VIDEO_DIP_VS_DATA_B 0x61260 +#define HSW_VIDEO_DIP_SPD_DATA_B 0x612A0 +#define HSW_VIDEO_DIP_GMP_DATA_B 0x612E0 +#define HSW_VIDEO_DIP_VSC_DATA_B 0x61320 +#define HSW_VIDEO_DIP_BVI_ECC_B 0x61240 +#define HSW_VIDEO_DIP_VS_ECC_B 0x61280 +#define HSW_VIDEO_DIP_SPD_ECC_B 0x612C0 +#define HSW_VIDEO_DIP_GMP_ECC_B 0x61300 +#define HSW_VIDEO_DIP_VSC_ECC_B 0x61344 +#define HSW_VIDEO_DIP_GCP_B 0x61210 + +#define HSW_TVIDEO_DIP_CTL(trans) \ + _TRANSCODER2(trans, HSW_VIDEO_DIP_CTL_A) +#define HSW_TVIDEO_DIP_AVI_DATA(trans) \ + _TRANSCODER2(trans, HSW_VIDEO_DIP_AVI_DATA_A) +#define HSW_TVIDEO_DIP_VS_DATA(trans) \ + _TRANSCODER2(trans, HSW_VIDEO_DIP_VS_DATA_A) +#define HSW_TVIDEO_DIP_SPD_DATA(trans) \ + _TRANSCODER2(trans, HSW_VIDEO_DIP_SPD_DATA_A) +#define HSW_TVIDEO_DIP_GCP(trans) \ + _TRANSCODER2(trans, HSW_VIDEO_DIP_GCP_A) +#define HSW_TVIDEO_DIP_VSC_DATA(trans) \ + _TRANSCODER2(trans, HSW_VIDEO_DIP_VSC_DATA_A) + +#define HSW_STEREO_3D_CTL_A 0x70020 +#define S3D_ENABLE (1<<31) +#define HSW_STEREO_3D_CTL_B 0x71020 + +#define HSW_STEREO_3D_CTL(trans) \ + _PIPE2(trans, HSW_STEREO_3D_CTL_A) + +#define _PCH_TRANS_HTOTAL_B 0xe1000 +#define _PCH_TRANS_HBLANK_B 0xe1004 +#define _PCH_TRANS_HSYNC_B 0xe1008 +#define _PCH_TRANS_VTOTAL_B 0xe100c +#define _PCH_TRANS_VBLANK_B 0xe1010 +#define _PCH_TRANS_VSYNC_B 0xe1014 +#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028 + +#define PCH_TRANS_HTOTAL(pipe) _PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B) +#define PCH_TRANS_HBLANK(pipe) _PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B) +#define PCH_TRANS_HSYNC(pipe) _PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B) +#define PCH_TRANS_VTOTAL(pipe) _PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B) +#define PCH_TRANS_VBLANK(pipe) _PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B) +#define PCH_TRANS_VSYNC(pipe) _PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B) +#define PCH_TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, \ + _PCH_TRANS_VSYNCSHIFT_B) + +#define _PCH_TRANSB_DATA_M1 0xe1030 +#define _PCH_TRANSB_DATA_N1 0xe1034 +#define _PCH_TRANSB_DATA_M2 0xe1038 +#define _PCH_TRANSB_DATA_N2 0xe103c +#define _PCH_TRANSB_LINK_M1 0xe1040 +#define _PCH_TRANSB_LINK_N1 0xe1044 +#define _PCH_TRANSB_LINK_M2 0xe1048 +#define _PCH_TRANSB_LINK_N2 0xe104c + +#define PCH_TRANS_DATA_M1(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1) +#define PCH_TRANS_DATA_N1(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1) +#define PCH_TRANS_DATA_M2(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2) +#define PCH_TRANS_DATA_N2(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2) +#define PCH_TRANS_LINK_M1(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1) +#define PCH_TRANS_LINK_N1(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1) +#define PCH_TRANS_LINK_M2(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2) +#define PCH_TRANS_LINK_N2(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2) + +#define _PCH_TRANSACONF 0xf0008 +#define _PCH_TRANSBCONF 0xf1008 +#define PCH_TRANSCONF(pipe) _PIPE(pipe, _PCH_TRANSACONF, _PCH_TRANSBCONF) +#define LPT_TRANSCONF _PCH_TRANSACONF /* lpt has only one transcoder */ +#define TRANS_DISABLE (0<<31) +#define TRANS_ENABLE (1<<31) +#define TRANS_STATE_MASK (1<<30) +#define TRANS_STATE_DISABLE (0<<30) +#define TRANS_STATE_ENABLE (1<<30) +#define TRANS_FSYNC_DELAY_HB1 (0<<27) +#define TRANS_FSYNC_DELAY_HB2 (1<<27) +#define TRANS_FSYNC_DELAY_HB3 (2<<27) +#define TRANS_FSYNC_DELAY_HB4 (3<<27) +#define TRANS_INTERLACE_MASK (7<<21) +#define TRANS_PROGRESSIVE (0<<21) +#define TRANS_INTERLACED (3<<21) +#define TRANS_LEGACY_INTERLACED_ILK (2<<21) +#define TRANS_8BPC (0<<5) +#define TRANS_10BPC (1<<5) +#define TRANS_6BPC (2<<5) +#define TRANS_12BPC (3<<5) + +#define _TRANSA_CHICKEN1 0xf0060 +#define _TRANSB_CHICKEN1 0xf1060 +#define TRANS_CHICKEN1(pipe) _PIPE(pipe, _TRANSA_CHICKEN1, _TRANSB_CHICKEN1) +#define TRANS_CHICKEN1_DP0UNIT_GC_DISABLE (1<<4) +#define _TRANSA_CHICKEN2 0xf0064 +#define _TRANSB_CHICKEN2 0xf1064 +#define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) +#define TRANS_CHICKEN2_TIMING_OVERRIDE (1<<31) +#define TRANS_CHICKEN2_FDI_POLARITY_REVERSED (1<<29) +#define TRANS_CHICKEN2_FRAME_START_DELAY_MASK (3<<27) +#define TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER (1<<26) +#define TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH (1<<25) + +#define SOUTH_CHICKEN1 0xc2000 +#define FDIA_PHASE_SYNC_SHIFT_OVR 19 +#define FDIA_PHASE_SYNC_SHIFT_EN 18 +#define FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 2))) +#define FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2))) +#define FDI_BC_BIFURCATION_SELECT (1 << 12) +#define SOUTH_CHICKEN2 0xc2004 +#define FDI_MPHY_IOSFSB_RESET_STATUS (1<<13) +#define FDI_MPHY_IOSFSB_RESET_CTL (1<<12) +#define DPLS_EDP_PPS_FIX_DIS (1<<0) + +#define _FDI_RXA_CHICKEN 0xc200c +#define _FDI_RXB_CHICKEN 0xc2010 +#define FDI_RX_PHASE_SYNC_POINTER_OVR (1<<1) +#define FDI_RX_PHASE_SYNC_POINTER_EN (1<<0) +#define FDI_RX_CHICKEN(pipe) _PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN) + +#define SOUTH_DSPCLK_GATE_D 0xc2020 +#define PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30) +#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29) +#define PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14) +#define PCH_LP_PARTITION_LEVEL_DISABLE (1<<12) + +/* CPU: FDI_TX */ +#define _FDI_TXA_CTL 0x60100 +#define _FDI_TXB_CTL 0x61100 +#define FDI_TX_CTL(pipe) _PIPE(pipe, _FDI_TXA_CTL, _FDI_TXB_CTL) +#define FDI_TX_DISABLE (0<<31) +#define FDI_TX_ENABLE (1<<31) +#define FDI_LINK_TRAIN_PATTERN_1 (0<<28) +#define FDI_LINK_TRAIN_PATTERN_2 (1<<28) +#define FDI_LINK_TRAIN_PATTERN_IDLE (2<<28) +#define FDI_LINK_TRAIN_NONE (3<<28) +#define FDI_LINK_TRAIN_VOLTAGE_0_4V (0<<25) +#define FDI_LINK_TRAIN_VOLTAGE_0_6V (1<<25) +#define FDI_LINK_TRAIN_VOLTAGE_0_8V (2<<25) +#define FDI_LINK_TRAIN_VOLTAGE_1_2V (3<<25) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0<<22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1<<22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2<<22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3<<22) +/* ILK always use 400mV 0dB for voltage swing and pre-emphasis level. + SNB has different settings. */ +/* SNB A-stepping */ +#define FDI_LINK_TRAIN_400MV_0DB_SNB_A (0x38<<22) +#define FDI_LINK_TRAIN_400MV_6DB_SNB_A (0x02<<22) +#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01<<22) +#define FDI_LINK_TRAIN_800MV_0DB_SNB_A (0x0<<22) +/* SNB B-stepping */ +#define FDI_LINK_TRAIN_400MV_0DB_SNB_B (0x0<<22) +#define FDI_LINK_TRAIN_400MV_6DB_SNB_B (0x3a<<22) +#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39<<22) +#define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) +#define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f<<22) +#define FDI_DP_PORT_WIDTH_SHIFT 19 +#define FDI_DP_PORT_WIDTH_MASK (7 << FDI_DP_PORT_WIDTH_SHIFT) +#define FDI_DP_PORT_WIDTH(width) (((width) - 1) << FDI_DP_PORT_WIDTH_SHIFT) +#define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18) +/* Ironlake: hardwired to 1 */ +#define FDI_TX_PLL_ENABLE (1<<14) + +/* Ivybridge has different bits for lolz */ +#define FDI_LINK_TRAIN_PATTERN_1_IVB (0<<8) +#define FDI_LINK_TRAIN_PATTERN_2_IVB (1<<8) +#define FDI_LINK_TRAIN_PATTERN_IDLE_IVB (2<<8) +#define FDI_LINK_TRAIN_NONE_IVB (3<<8) + +/* both Tx and Rx */ +#define FDI_COMPOSITE_SYNC (1<<11) +#define FDI_LINK_TRAIN_AUTO (1<<10) +#define FDI_SCRAMBLING_ENABLE (0<<7) +#define FDI_SCRAMBLING_DISABLE (1<<7) + +/* FDI_RX, FDI_X is hard-wired to Transcoder_X */ +#define _FDI_RXA_CTL 0xf000c +#define _FDI_RXB_CTL 0xf100c +#define FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL) +#define FDI_RX_ENABLE (1<<31) +/* train, dp width same as FDI_TX */ +#define FDI_FS_ERRC_ENABLE (1<<27) +#define FDI_FE_ERRC_ENABLE (1<<26) +#define FDI_RX_POLARITY_REVERSED_LPT (1<<16) +#define FDI_8BPC (0<<16) +#define FDI_10BPC (1<<16) +#define FDI_6BPC (2<<16) +#define FDI_12BPC (3<<16) +#define FDI_RX_LINK_REVERSAL_OVERRIDE (1<<15) +#define FDI_DMI_LINK_REVERSE_MASK (1<<14) +#define FDI_RX_PLL_ENABLE (1<<13) +#define FDI_FS_ERR_CORRECT_ENABLE (1<<11) +#define FDI_FE_ERR_CORRECT_ENABLE (1<<10) +#define FDI_FS_ERR_REPORT_ENABLE (1<<9) +#define FDI_FE_ERR_REPORT_ENABLE (1<<8) +#define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) +#define FDI_PCDCLK (1<<4) +/* CPT */ +#define FDI_AUTO_TRAINING (1<<10) +#define FDI_LINK_TRAIN_PATTERN_1_CPT (0<<8) +#define FDI_LINK_TRAIN_PATTERN_2_CPT (1<<8) +#define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2<<8) +#define FDI_LINK_TRAIN_NORMAL_CPT (3<<8) +#define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3<<8) + +#define _FDI_RXA_MISC 0xf0010 +#define _FDI_RXB_MISC 0xf1010 +#define FDI_RX_PWRDN_LANE1_MASK (3<<26) +#define FDI_RX_PWRDN_LANE1_VAL(x) ((x)<<26) +#define FDI_RX_PWRDN_LANE0_MASK (3<<24) +#define FDI_RX_PWRDN_LANE0_VAL(x) ((x)<<24) +#define FDI_RX_TP1_TO_TP2_48 (2<<20) +#define FDI_RX_TP1_TO_TP2_64 (3<<20) +#define FDI_RX_FDI_DELAY_90 (0x90<<0) +#define FDI_RX_MISC(pipe) _PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC) + +#define _FDI_RXA_TUSIZE1 0xf0030 +#define _FDI_RXA_TUSIZE2 0xf0038 +#define _FDI_RXB_TUSIZE1 0xf1030 +#define _FDI_RXB_TUSIZE2 0xf1038 +#define FDI_RX_TUSIZE1(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1) +#define FDI_RX_TUSIZE2(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2) + +/* FDI_RX interrupt register format */ +#define FDI_RX_INTER_LANE_ALIGN (1<<10) +#define FDI_RX_SYMBOL_LOCK (1<<9) /* train 2 */ +#define FDI_RX_BIT_LOCK (1<<8) /* train 1 */ +#define FDI_RX_TRAIN_PATTERN_2_FAIL (1<<7) +#define FDI_RX_FS_CODE_ERR (1<<6) +#define FDI_RX_FE_CODE_ERR (1<<5) +#define FDI_RX_SYMBOL_ERR_RATE_ABOVE (1<<4) +#define FDI_RX_HDCP_LINK_FAIL (1<<3) +#define FDI_RX_PIXEL_FIFO_OVERFLOW (1<<2) +#define FDI_RX_CROSS_CLOCK_OVERFLOW (1<<1) +#define FDI_RX_SYMBOL_QUEUE_OVERFLOW (1<<0) + +#define _FDI_RXA_IIR 0xf0014 +#define _FDI_RXA_IMR 0xf0018 +#define _FDI_RXB_IIR 0xf1014 +#define _FDI_RXB_IMR 0xf1018 +#define FDI_RX_IIR(pipe) _PIPE(pipe, _FDI_RXA_IIR, _FDI_RXB_IIR) +#define FDI_RX_IMR(pipe) _PIPE(pipe, _FDI_RXA_IMR, _FDI_RXB_IMR) + +#define FDI_PLL_CTL_1 0xfe000 +#define FDI_PLL_CTL_2 0xfe004 + +#define PCH_LVDS 0xe1180 +#define LVDS_DETECTED (1 << 1) + +/* vlv has 2 sets of panel control regs. */ +#define PIPEA_PP_STATUS (VLV_DISPLAY_BASE + 0x61200) +#define PIPEA_PP_CONTROL (VLV_DISPLAY_BASE + 0x61204) +#define PIPEA_PP_ON_DELAYS (VLV_DISPLAY_BASE + 0x61208) +#define PANEL_PORT_SELECT_DPB_VLV (1 << 30) +#define PANEL_PORT_SELECT_DPC_VLV (2 << 30) +#define PIPEA_PP_OFF_DELAYS (VLV_DISPLAY_BASE + 0x6120c) +#define PIPEA_PP_DIVISOR (VLV_DISPLAY_BASE + 0x61210) + +#define PIPEB_PP_STATUS (VLV_DISPLAY_BASE + 0x61300) +#define PIPEB_PP_CONTROL (VLV_DISPLAY_BASE + 0x61304) +#define PIPEB_PP_ON_DELAYS (VLV_DISPLAY_BASE + 0x61308) +#define PIPEB_PP_OFF_DELAYS (VLV_DISPLAY_BASE + 0x6130c) +#define PIPEB_PP_DIVISOR (VLV_DISPLAY_BASE + 0x61310) + +#define VLV_PIPE_PP_STATUS(pipe) _PIPE(pipe, PIPEA_PP_STATUS, PIPEB_PP_STATUS) +#define VLV_PIPE_PP_CONTROL(pipe) _PIPE(pipe, PIPEA_PP_CONTROL, PIPEB_PP_CONTROL) +#define VLV_PIPE_PP_ON_DELAYS(pipe) \ + _PIPE(pipe, PIPEA_PP_ON_DELAYS, PIPEB_PP_ON_DELAYS) +#define VLV_PIPE_PP_OFF_DELAYS(pipe) \ + _PIPE(pipe, PIPEA_PP_OFF_DELAYS, PIPEB_PP_OFF_DELAYS) +#define VLV_PIPE_PP_DIVISOR(pipe) \ + _PIPE(pipe, PIPEA_PP_DIVISOR, PIPEB_PP_DIVISOR) + +#define PCH_PP_STATUS 0xc7200 +#define PCH_PP_CONTROL 0xc7204 +#define PANEL_UNLOCK_REGS (0xabcd << 16) +#define PANEL_UNLOCK_MASK (0xffff << 16) +#define EDP_FORCE_VDD (1 << 3) +#define EDP_BLC_ENABLE (1 << 2) +#define PANEL_POWER_RESET (1 << 1) +#define PANEL_POWER_OFF (0 << 0) +#define PANEL_POWER_ON (1 << 0) +#define PCH_PP_ON_DELAYS 0xc7208 +#define PANEL_PORT_SELECT_MASK (3 << 30) +#define PANEL_PORT_SELECT_LVDS (0 << 30) +#define PANEL_PORT_SELECT_DPA (1 << 30) +#define PANEL_PORT_SELECT_DPC (2 << 30) +#define PANEL_PORT_SELECT_DPD (3 << 30) +#define PANEL_POWER_UP_DELAY_MASK (0x1fff0000) +#define PANEL_POWER_UP_DELAY_SHIFT 16 +#define PANEL_LIGHT_ON_DELAY_MASK (0x1fff) +#define PANEL_LIGHT_ON_DELAY_SHIFT 0 + +#define PCH_PP_OFF_DELAYS 0xc720c +#define PANEL_POWER_DOWN_DELAY_MASK (0x1fff0000) +#define PANEL_POWER_DOWN_DELAY_SHIFT 16 +#define PANEL_LIGHT_OFF_DELAY_MASK (0x1fff) +#define PANEL_LIGHT_OFF_DELAY_SHIFT 0 + +#define PCH_PP_DIVISOR 0xc7210 +#define PP_REFERENCE_DIVIDER_MASK (0xffffff00) +#define PP_REFERENCE_DIVIDER_SHIFT 8 +#define PANEL_POWER_CYCLE_DELAY_MASK (0x1f) +#define PANEL_POWER_CYCLE_DELAY_SHIFT 0 + +#define PCH_DP_B 0xe4100 +#define PCH_DPB_AUX_CH_CTL 0xe4110 +#define PCH_DPB_AUX_CH_DATA1 0xe4114 +#define PCH_DPB_AUX_CH_DATA2 0xe4118 +#define PCH_DPB_AUX_CH_DATA3 0xe411c +#define PCH_DPB_AUX_CH_DATA4 0xe4120 +#define PCH_DPB_AUX_CH_DATA5 0xe4124 + +#define PCH_DP_C 0xe4200 +#define PCH_DPC_AUX_CH_CTL 0xe4210 +#define PCH_DPC_AUX_CH_DATA1 0xe4214 +#define PCH_DPC_AUX_CH_DATA2 0xe4218 +#define PCH_DPC_AUX_CH_DATA3 0xe421c +#define PCH_DPC_AUX_CH_DATA4 0xe4220 +#define PCH_DPC_AUX_CH_DATA5 0xe4224 + +#define PCH_DP_D 0xe4300 +#define PCH_DPD_AUX_CH_CTL 0xe4310 +#define PCH_DPD_AUX_CH_DATA1 0xe4314 +#define PCH_DPD_AUX_CH_DATA2 0xe4318 +#define PCH_DPD_AUX_CH_DATA3 0xe431c +#define PCH_DPD_AUX_CH_DATA4 0xe4320 +#define PCH_DPD_AUX_CH_DATA5 0xe4324 + +/* CPT */ +#define PORT_TRANS_A_SEL_CPT 0 +#define PORT_TRANS_B_SEL_CPT (1<<29) +#define PORT_TRANS_C_SEL_CPT (2<<29) +#define PORT_TRANS_SEL_MASK (3<<29) +#define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29) +#define PORT_TO_PIPE(val) (((val) & (1<<30)) >> 30) +#define PORT_TO_PIPE_CPT(val) (((val) & PORT_TRANS_SEL_MASK) >> 29) +#define SDVO_PORT_TO_PIPE_CHV(val) (((val) & (3<<24)) >> 24) +#define DP_PORT_TO_PIPE_CHV(val) (((val) & (3<<16)) >> 16) + +#define TRANS_DP_CTL_A 0xe0300 +#define TRANS_DP_CTL_B 0xe1300 +#define TRANS_DP_CTL_C 0xe2300 +#define TRANS_DP_CTL(pipe) _PIPE(pipe, TRANS_DP_CTL_A, TRANS_DP_CTL_B) +#define TRANS_DP_OUTPUT_ENABLE (1<<31) +#define TRANS_DP_PORT_SEL_B (0<<29) +#define TRANS_DP_PORT_SEL_C (1<<29) +#define TRANS_DP_PORT_SEL_D (2<<29) +#define TRANS_DP_PORT_SEL_NONE (3<<29) +#define TRANS_DP_PORT_SEL_MASK (3<<29) +#define TRANS_DP_AUDIO_ONLY (1<<26) +#define TRANS_DP_ENH_FRAMING (1<<18) +#define TRANS_DP_8BPC (0<<9) +#define TRANS_DP_10BPC (1<<9) +#define TRANS_DP_6BPC (2<<9) +#define TRANS_DP_12BPC (3<<9) +#define TRANS_DP_BPC_MASK (3<<9) +#define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) +#define TRANS_DP_VSYNC_ACTIVE_LOW 0 +#define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) +#define TRANS_DP_HSYNC_ACTIVE_LOW 0 +#define TRANS_DP_SYNC_MASK (3<<3) + +/* SNB eDP training params */ +/* SNB A-stepping */ +#define EDP_LINK_TRAIN_400MV_0DB_SNB_A (0x38<<22) +#define EDP_LINK_TRAIN_400MV_6DB_SNB_A (0x02<<22) +#define EDP_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01<<22) +#define EDP_LINK_TRAIN_800MV_0DB_SNB_A (0x0<<22) +/* SNB B-stepping */ +#define EDP_LINK_TRAIN_400_600MV_0DB_SNB_B (0x0<<22) +#define EDP_LINK_TRAIN_400MV_3_5DB_SNB_B (0x1<<22) +#define EDP_LINK_TRAIN_400_600MV_6DB_SNB_B (0x3a<<22) +#define EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B (0x39<<22) +#define EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B (0x38<<22) +#define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) + +/* IVB */ +#define EDP_LINK_TRAIN_400MV_0DB_IVB (0x24 <<22) +#define EDP_LINK_TRAIN_400MV_3_5DB_IVB (0x2a <<22) +#define EDP_LINK_TRAIN_400MV_6DB_IVB (0x2f <<22) +#define EDP_LINK_TRAIN_600MV_0DB_IVB (0x30 <<22) +#define EDP_LINK_TRAIN_600MV_3_5DB_IVB (0x36 <<22) +#define EDP_LINK_TRAIN_800MV_0DB_IVB (0x38 <<22) +#define EDP_LINK_TRAIN_800MV_3_5DB_IVB (0x3e <<22) + +/* legacy values */ +#define EDP_LINK_TRAIN_500MV_0DB_IVB (0x00 <<22) +#define EDP_LINK_TRAIN_1000MV_0DB_IVB (0x20 <<22) +#define EDP_LINK_TRAIN_500MV_3_5DB_IVB (0x02 <<22) +#define EDP_LINK_TRAIN_1000MV_3_5DB_IVB (0x22 <<22) +#define EDP_LINK_TRAIN_1000MV_6DB_IVB (0x23 <<22) + +#define EDP_LINK_TRAIN_VOL_EMP_MASK_IVB (0x3f<<22) + +#define VLV_PMWGICZ 0x1300a4 + +#define FORCEWAKE 0xA18C +#define FORCEWAKE_VLV 0x1300b0 +#define FORCEWAKE_ACK_VLV 0x1300b4 +#define FORCEWAKE_MEDIA_VLV 0x1300b8 +#define FORCEWAKE_ACK_MEDIA_VLV 0x1300bc +#define FORCEWAKE_ACK_HSW 0x130044 +#define FORCEWAKE_ACK 0x130090 +#define VLV_GTLC_WAKE_CTRL 0x130090 +#define VLV_GTLC_RENDER_CTX_EXISTS (1 << 25) +#define VLV_GTLC_MEDIA_CTX_EXISTS (1 << 24) +#define VLV_GTLC_ALLOWWAKEREQ (1 << 0) + +#define VLV_GTLC_PW_STATUS 0x130094 +#define VLV_GTLC_ALLOWWAKEACK (1 << 0) +#define VLV_GTLC_ALLOWWAKEERR (1 << 1) +#define VLV_GTLC_PW_MEDIA_STATUS_MASK (1 << 5) +#define VLV_GTLC_PW_RENDER_STATUS_MASK (1 << 7) +#define VLV_GTLC_SURVIVABILITY_REG 0x130098 +#define FORCEWAKE_MT 0xa188 /* multi-threaded */ +#define FORCEWAKE_KERNEL 0x1 +#define FORCEWAKE_USER 0x2 +#define FORCEWAKE_MT_ACK 0x130040 +#define ECOBUS 0xa180 +#define FORCEWAKE_MT_ENABLE (1<<5) +#define VLV_SPAREG2H 0xA194 + +#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2) +#define VLV_GFX_CLK_STATUS_BIT (1<<3) + +#define VLV_RC_COUNTER_CONTROL 0xFFFF00FF + +#define GTFIFODBG 0x120000 +#define GT_FIFO_CPU_ERROR_MASK 0xf +#define GT_FIFO_SDDROPERR (1<<6) +#define GT_FIFO_BLOBDROPERR (1<<5) +#define GT_FIFO_SB_READ_ABORTERR (1<<4) +#define GT_FIFO_DROPERR (1<<3) +#define GT_FIFO_OVFERR (1<<2) +#define GT_FIFO_IAWRERR (1<<1) +#define GT_FIFO_IARDERR (1<<0) + +#define GTFIFOCTL 0x120008 +#define GT_FIFO_FREE_ENTRIES_MASK 0x7f +#define GT_FIFO_NUM_RESERVED_ENTRIES 20 + +#define HSW_IDICR 0x9008 +#define IDIHASHMSK(x) (((x) & 0x3f) << 16) +#define HSW_EDRAM_PRESENT 0x120010 + +#define GEN6_UCGCTL1 0x9400 +# define GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE (1 << 16) +# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5) +# define GEN6_CSUNIT_CLOCK_GATE_DISABLE (1 << 7) + +#define GEN6_UCGCTL2 0x9404 +# define GEN7_VDSUNIT_CLOCK_GATE_DISABLE (1 << 30) +# define GEN7_TDLUNIT_CLOCK_GATE_DISABLE (1 << 22) +# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) +# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) +# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) + +#define GEN6_UCGCTL3 0x9408 + +#define GEN7_UCGCTL4 0x940c +#define GEN7_L3BANK2X_CLOCK_GATE_DISABLE (1<<25) + +#define GEN6_RCGCTL1 0x9410 +#define GEN6_RCGCTL2 0x9414 +#define GEN6_RSTCTL 0x9420 + +#define GEN8_UCGCTL6 0x9430 +#define GEN8_SDEUNIT_CLOCK_GATE_DISABLE (1<<14) + +#define TIMESTAMP_CTR 0x44070 +#define FREQ_1_28_US(us) (((us) * 100) >> 7) +#define MCHBAR_PCU_C0 (MCHBAR_MIRROR_BASE_SNB + 0x5960) + +#define GEN6_GFXPAUSE 0xA000 +#define GEN6_RPNSWREQ 0xA008 +#define GEN6_TURBO_DISABLE (1<<31) +#define GEN6_FREQUENCY(x) ((x)<<25) +#define HSW_FREQUENCY(x) ((x)<<24) +#define GEN6_OFFSET(x) ((x)<<19) +#define GEN6_AGGRESSIVE_TURBO (0<<15) +#define GEN6_RC_VIDEO_FREQ 0xA00C +#define GEN6_RC_CONTROL 0xA090 +#define GEN6_RC_CTL_RC6pp_ENABLE (1<<16) +#define GEN6_RC_CTL_RC6p_ENABLE (1<<17) +#define GEN6_RC_CTL_RC6_ENABLE (1<<18) +#define GEN6_RC_CTL_RC1e_ENABLE (1<<20) +#define GEN6_RC_CTL_RC7_ENABLE (1<<22) +#define VLV_RC_CTL_CTX_RST_PARALLEL (1<<24) +#define GEN7_RC_CTL_TO_MODE (1<<28) +#define GEN6_RC_CTL_EI_MODE(x) ((x)<<27) +#define GEN6_RC_CTL_HW_ENABLE (1<<31) +#define GEN6_RP_DOWN_TIMEOUT 0xA010 +#define GEN6_RP_INTERRUPT_LIMITS 0xA014 +#define GEN6_RPSTAT1 0xA01C +#define GEN6_CAGF_SHIFT 8 +#define HSW_CAGF_SHIFT 7 +#define GEN6_CAGF_MASK (0x7f << GEN6_CAGF_SHIFT) +#define HSW_CAGF_MASK (0x7f << HSW_CAGF_SHIFT) +#define GEN6_RP_CONTROL 0xA024 +#define GEN6_RP_MEDIA_TURBO (1<<11) +#define GEN6_RP_MEDIA_MODE_MASK (3<<9) +#define GEN6_RP_MEDIA_HW_TURBO_MODE (3<<9) +#define GEN6_RP_MEDIA_HW_NORMAL_MODE (2<<9) +#define GEN6_RP_MEDIA_HW_MODE (1<<9) +#define GEN6_RP_MEDIA_SW_MODE (0<<9) +#define GEN6_RP_MEDIA_IS_GFX (1<<8) +#define GEN6_RP_ENABLE (1<<7) +#define GEN6_RP_UP_IDLE_MIN (0x1<<3) +#define GEN6_RP_UP_BUSY_AVG (0x2<<3) +#define GEN6_RP_UP_BUSY_CONT (0x4<<3) +#define GEN6_RP_DOWN_IDLE_AVG (0x2<<0) +#define GEN6_RP_DOWN_IDLE_CONT (0x1<<0) +#define GEN6_RP_UP_THRESHOLD 0xA02C +#define GEN6_RP_DOWN_THRESHOLD 0xA030 +#define GEN6_RP_CUR_UP_EI 0xA050 +#define GEN6_CURICONT_MASK 0xffffff +#define GEN6_RP_CUR_UP 0xA054 +#define GEN6_CURBSYTAVG_MASK 0xffffff +#define GEN6_RP_PREV_UP 0xA058 +#define GEN6_RP_CUR_DOWN_EI 0xA05C +#define GEN6_CURIAVG_MASK 0xffffff +#define GEN6_RP_CUR_DOWN 0xA060 +#define GEN6_RP_PREV_DOWN 0xA064 +#define GEN6_RP_UP_EI 0xA068 +#define GEN6_RP_DOWN_EI 0xA06C +#define GEN6_RP_IDLE_HYSTERSIS 0xA070 +#define GEN6_RPDEUHWTC 0xA080 +#define GEN6_RPDEUC 0xA084 +#define GEN6_RPDEUCSW 0xA088 +#define GEN6_RC_STATE 0xA094 +#define GEN6_RC1_WAKE_RATE_LIMIT 0xA098 +#define GEN6_RC6_WAKE_RATE_LIMIT 0xA09C +#define GEN6_RC6pp_WAKE_RATE_LIMIT 0xA0A0 +#define GEN6_RC_EVALUATION_INTERVAL 0xA0A8 +#define GEN6_RC_IDLE_HYSTERSIS 0xA0AC +#define GEN6_RC_SLEEP 0xA0B0 +#define GEN6_RCUBMABDTMR 0xA0B0 +#define GEN6_RC1e_THRESHOLD 0xA0B4 +#define GEN6_RC6_THRESHOLD 0xA0B8 +#define GEN6_RC6_RENDER_PROMOTION_TIMER_TO 0x0557 +#define GEN6_RC6_MEDIA_PROMOTION_TIMER_TO 0x00C3 +#define GEN6_RC6p_THRESHOLD 0xA0BC +#define VLV_RCEDATA 0xA0BC +#define GEN6_RC6pp_THRESHOLD 0xA0C0 +#define GEN6_PMINTRMSK 0xA168 +#define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31) +#define VLV_PWRDWNUPCTL 0xA294 + +#define VLV_CHICKEN_3 (dev_priv->info.display_mmio_offset + 0x7040C) +#define PIXEL_OVERLAP_CNT_MASK (3 << 30) +#define PIXEL_OVERLAP_CNT_SHIFT 30 + +#define GEN6_PMISR 0x44020 +#define GEN6_PMIMR 0x44024 /* rps_lock */ +#define GEN6_PMIIR 0x44028 +#define GEN6_PMIER 0x4402C +#define GEN6_PM_MBOX_EVENT (1<<25) +#define GEN6_PM_THERMAL_EVENT (1<<24) +#define GEN6_PM_RP_DOWN_TIMEOUT (1<<6) +#define GEN6_PM_RP_UP_THRESHOLD (1<<5) +#define GEN6_PM_RP_DOWN_THRESHOLD (1<<4) +#define GEN6_PM_RP_UP_EI_EXPIRED (1<<2) +#define GEN6_PM_RP_DOWN_EI_EXPIRED (1<<1) +#define GEN6_PM_RPS_EVENTS (GEN6_PM_RP_UP_THRESHOLD | \ + GEN6_PM_RP_DOWN_THRESHOLD | \ + GEN6_PM_RP_DOWN_TIMEOUT) + +#define CHV_CZ_CLOCK_FREQ_MODE_200 200 +#define CHV_CZ_CLOCK_FREQ_MODE_267 267 +#define CHV_CZ_CLOCK_FREQ_MODE_320 320 +#define CHV_CZ_CLOCK_FREQ_MODE_333 333 +#define CHV_CZ_CLOCK_FREQ_MODE_400 400 + +#define GEN7_GT_SCRATCH_BASE 0x4F100 +#define GEN7_GT_SCRATCH_REG_NUM 8 + +#define VLV_GTLC_SURVIVABILITY_REG 0x130098 +#define VLV_GFX_CLK_STATUS_BIT (1<<3) +#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2) + +#define VLV_RENDER_C0_COUNT_REG 0x138118 +#define VLV_MEDIA_C0_COUNT_REG 0x13811C + +#define GEN6_GT_GFX_RC6_LOCKED 0x138104 +#define VLV_COUNTER_CONTROL 0x138104 +#define VLV_COUNT_RANGE_HIGH (1<<15) +#define VLV_MEDIA_RC6_COUNT_EN (1<<1) +#define VLV_RENDER_RC6_COUNT_EN (1<<0) +#define GEN6_GT_GFX_RC6 0x138108 +#define VLV_GT_RENDER_RC6 0x138108 +#define VLV_GT_MEDIA_RC6 0x13810C + +#define GEN6_GT_GFX_RC6p 0x13810C +#define GEN6_GT_GFX_RC6pp 0x138110 +#define VLV_PCBR_ADDR_SHIFT 12 + +#define GEN6_PCODE_MAILBOX 0x138124 +#define GEN6_PCODE_READY (1<<31) +#define GEN6_READ_OC_PARAMS 0xc +#define GEN6_PCODE_WRITE_MIN_FREQ_TABLE 0x8 +#define GEN6_PCODE_READ_MIN_FREQ_TABLE 0x9 +#define GEN6_PCODE_WRITE_RC6VIDS 0x4 +#define GEN6_PCODE_READ_RC6VIDS 0x5 +#define GEN6_PCODE_READ_D_COMP 0x10 +#define GEN6_PCODE_WRITE_D_COMP 0x11 +#define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) +#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245) +#define DISPLAY_IPS_CONTROL 0x19 +#define GEN6_PCODE_DATA 0x138128 +#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 +#define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 + +#define GEN6_GT_CORE_STATUS 0x138060 +#define GEN6_CORE_CPD_STATE_MASK (7<<4) +#define GEN6_RCn_MASK 7 +#define GEN6_RC0 0 +#define GEN6_RC3 2 +#define GEN6_RC6 3 +#define GEN6_RC7 4 + +#define GEN7_MISCCPCTL (0x9424) +#define GEN8_DOP_CLOCK_GATE_CFCLK_ENABLE (1<<2) +#define GEN7_DOP_CLOCK_GATE_ENABLE (1<<0) + +/* IVYBRIDGE DPF */ +#define GEN7_L3CDERRST1 0xB008 /* L3CD Error Status 1 */ +#define HSW_L3CDERRST11 0xB208 /* L3CD Error Status register 1 slice 1 */ +#define GEN7_L3CDERRST1_ROW_MASK (0x7ff<<14) +#define GEN7_PARITY_ERROR_VALID (1<<13) +#define GEN7_L3CDERRST1_BANK_MASK (3<<11) +#define GEN7_L3CDERRST1_SUBBANK_MASK (7<<8) +#define GEN7_PARITY_ERROR_ROW(reg) \ + ((reg & GEN7_L3CDERRST1_ROW_MASK) >> 14) +#define GEN7_PARITY_ERROR_BANK(reg) \ + ((reg & GEN7_L3CDERRST1_BANK_MASK) >> 11) +#define GEN7_PARITY_ERROR_SUBBANK(reg) \ + ((reg & GEN7_L3CDERRST1_SUBBANK_MASK) >> 8) +#define GEN7_L3CDERRST1_ENABLE (1<<7) + +#define GEN7_L3LOG_BASE 0xB070 +#define HSW_L3LOG_BASE_SLICE1 0xB270 +#define GEN7_L3LOG_SIZE 0x80 + +#define GEN7_HALF_SLICE_CHICKEN1 0xe100 /* IVB GT1 + VLV */ +#define GEN7_HALF_SLICE_CHICKEN1_GT2 0xf100 +#define GEN7_MAX_PS_THREAD_DEP (8<<12) +#define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10) +#define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3) + +#define GEN8_ROW_CHICKEN 0xe4f0 +#define FLOW_CONTROL_ENABLE (1<<15) +#define INSTRUCTION_SHOOTDOWN_DISABLE (1<<9) +#define PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE (1<<8) +#define STALL_DOP_GATING_DISABLE (1<<5) + +#define GEN7_ROW_CHICKEN2 0xe4f4 +#define GEN7_ROW_CHICKEN2_GT2 0xf4f4 +#define DOP_CLOCK_GATING_DISABLE (1<<0) + +#define HSW_ROW_CHICKEN3 0xe49c +#define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6) + +#define HALF_SLICE_CHICKEN3 0xe184 +#define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8) +#define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) + +#define G4X_AUD_VID_DID (dev_priv->info.display_mmio_offset + 0x62020) +#define INTEL_AUDIO_DEVCL 0x808629FB +#define INTEL_AUDIO_DEVBLC 0x80862801 +#define INTEL_AUDIO_DEVCTG 0x80862802 + +#define G4X_AUD_CNTL_ST 0x620B4 +#define G4X_ELDV_DEVCL_DEVBLC (1 << 13) +#define G4X_ELDV_DEVCTG (1 << 14) +#define G4X_ELD_ADDR (0xf << 5) +#define G4X_ELD_ACK (1 << 4) +#define G4X_HDMIW_HDMIEDID 0x6210C + +#define IBX_HDMIW_HDMIEDID_A 0xE2050 +#define IBX_HDMIW_HDMIEDID_B 0xE2150 +#define IBX_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \ + IBX_HDMIW_HDMIEDID_A, \ + IBX_HDMIW_HDMIEDID_B) +#define IBX_AUD_CNTL_ST_A 0xE20B4 +#define IBX_AUD_CNTL_ST_B 0xE21B4 +#define IBX_AUD_CNTL_ST(pipe) _PIPE(pipe, \ + IBX_AUD_CNTL_ST_A, \ + IBX_AUD_CNTL_ST_B) +#define IBX_ELD_BUFFER_SIZE (0x1f << 10) +#define IBX_ELD_ADDRESS (0x1f << 5) +#define IBX_ELD_ACK (1 << 4) +#define IBX_AUD_CNTL_ST2 0xE20C0 +#define IBX_ELD_VALIDB (1 << 0) +#define IBX_CP_READYB (1 << 1) + +#define CPT_HDMIW_HDMIEDID_A 0xE5050 +#define CPT_HDMIW_HDMIEDID_B 0xE5150 +#define CPT_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \ + CPT_HDMIW_HDMIEDID_A, \ + CPT_HDMIW_HDMIEDID_B) +#define CPT_AUD_CNTL_ST_A 0xE50B4 +#define CPT_AUD_CNTL_ST_B 0xE51B4 +#define CPT_AUD_CNTL_ST(pipe) _PIPE(pipe, \ + CPT_AUD_CNTL_ST_A, \ + CPT_AUD_CNTL_ST_B) +#define CPT_AUD_CNTRL_ST2 0xE50C0 + +#define VLV_HDMIW_HDMIEDID_A (VLV_DISPLAY_BASE + 0x62050) +#define VLV_HDMIW_HDMIEDID_B (VLV_DISPLAY_BASE + 0x62150) +#define VLV_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \ + VLV_HDMIW_HDMIEDID_A, \ + VLV_HDMIW_HDMIEDID_B) +#define VLV_AUD_CNTL_ST_A (VLV_DISPLAY_BASE + 0x620B4) +#define VLV_AUD_CNTL_ST_B (VLV_DISPLAY_BASE + 0x621B4) +#define VLV_AUD_CNTL_ST(pipe) _PIPE(pipe, \ + VLV_AUD_CNTL_ST_A, \ + VLV_AUD_CNTL_ST_B) +#define VLV_AUD_CNTL_ST2 (VLV_DISPLAY_BASE + 0x620C0) + +/* These are the 4 32-bit write offset registers for each stream + * output buffer. It determines the offset from the + * 3DSTATE_SO_BUFFERs that the next streamed vertex output goes to. + */ +#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) + +#define IBX_AUD_CONFIG_A 0xe2000 +#define IBX_AUD_CONFIG_B 0xe2100 +#define IBX_AUD_CFG(pipe) _PIPE(pipe, \ + IBX_AUD_CONFIG_A, \ + IBX_AUD_CONFIG_B) +#define CPT_AUD_CONFIG_A 0xe5000 +#define CPT_AUD_CONFIG_B 0xe5100 +#define CPT_AUD_CFG(pipe) _PIPE(pipe, \ + CPT_AUD_CONFIG_A, \ + CPT_AUD_CONFIG_B) +#define VLV_AUD_CONFIG_A (VLV_DISPLAY_BASE + 0x62000) +#define VLV_AUD_CONFIG_B (VLV_DISPLAY_BASE + 0x62100) +#define VLV_AUD_CFG(pipe) _PIPE(pipe, \ + VLV_AUD_CONFIG_A, \ + VLV_AUD_CONFIG_B) + +#define AUD_CONFIG_N_VALUE_INDEX (1 << 29) +#define AUD_CONFIG_N_PROG_ENABLE (1 << 28) +#define AUD_CONFIG_UPPER_N_SHIFT 20 +#define AUD_CONFIG_UPPER_N_VALUE (0xff << 20) +#define AUD_CONFIG_LOWER_N_SHIFT 4 +#define AUD_CONFIG_LOWER_N_VALUE (0xfff << 4) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16 +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK (0xf << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 (0 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 (1 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 (2 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 (3 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 (4 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 (5 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 (6 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 (7 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 (8 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 (9 << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_296703 (0xA << 16) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_297000 (0xB << 16) +#define AUD_CONFIG_DISABLE_NCTS (1 << 3) + +/* HSW Audio */ +#define HSW_AUD_CONFIG_A 0x65000 /* Audio Configuration Transcoder A */ +#define HSW_AUD_CONFIG_B 0x65100 /* Audio Configuration Transcoder B */ +#define HSW_AUD_CFG(pipe) _PIPE(pipe, \ + HSW_AUD_CONFIG_A, \ + HSW_AUD_CONFIG_B) + +#define HSW_AUD_MISC_CTRL_A 0x65010 /* Audio Misc Control Convert 1 */ +#define HSW_AUD_MISC_CTRL_B 0x65110 /* Audio Misc Control Convert 2 */ +#define HSW_AUD_MISC_CTRL(pipe) _PIPE(pipe, \ + HSW_AUD_MISC_CTRL_A, \ + HSW_AUD_MISC_CTRL_B) + +#define HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 /* Audio DIP and ELD Control State Transcoder A */ +#define HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 /* Audio DIP and ELD Control State Transcoder B */ +#define HSW_AUD_DIP_ELD_CTRL(pipe) _PIPE(pipe, \ + HSW_AUD_DIP_ELD_CTRL_ST_A, \ + HSW_AUD_DIP_ELD_CTRL_ST_B) + +/* Audio Digital Converter */ +#define HSW_AUD_DIG_CNVT_1 0x65080 /* Audio Converter 1 */ +#define HSW_AUD_DIG_CNVT_2 0x65180 /* Audio Converter 1 */ +#define AUD_DIG_CNVT(pipe) _PIPE(pipe, \ + HSW_AUD_DIG_CNVT_1, \ + HSW_AUD_DIG_CNVT_2) +#define DIP_PORT_SEL_MASK 0x3 + +#define HSW_AUD_EDID_DATA_A 0x65050 +#define HSW_AUD_EDID_DATA_B 0x65150 +#define HSW_AUD_EDID_DATA(pipe) _PIPE(pipe, \ + HSW_AUD_EDID_DATA_A, \ + HSW_AUD_EDID_DATA_B) + +#define HSW_AUD_PIPE_CONV_CFG 0x6507c /* Audio pipe and converter configs */ +#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 /* Audio ELD and CP Ready Status */ +#define AUDIO_INACTIVE_C (1<<11) +#define AUDIO_INACTIVE_B (1<<7) +#define AUDIO_INACTIVE_A (1<<3) +#define AUDIO_OUTPUT_ENABLE_A (1<<2) +#define AUDIO_OUTPUT_ENABLE_B (1<<6) +#define AUDIO_OUTPUT_ENABLE_C (1<<10) +#define AUDIO_ELD_VALID_A (1<<0) +#define AUDIO_ELD_VALID_B (1<<4) +#define AUDIO_ELD_VALID_C (1<<8) +#define AUDIO_CP_READY_A (1<<1) +#define AUDIO_CP_READY_B (1<<5) +#define AUDIO_CP_READY_C (1<<9) + +/* HSW Power Wells */ +#define HSW_PWR_WELL_BIOS 0x45400 /* CTL1 */ +#define HSW_PWR_WELL_DRIVER 0x45404 /* CTL2 */ +#define HSW_PWR_WELL_KVMR 0x45408 /* CTL3 */ +#define HSW_PWR_WELL_DEBUG 0x4540C /* CTL4 */ +#define HSW_PWR_WELL_ENABLE_REQUEST (1<<31) +#define HSW_PWR_WELL_STATE_ENABLED (1<<30) +#define HSW_PWR_WELL_CTL5 0x45410 +#define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31) +#define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20) +#define HSW_PWR_WELL_FORCE_ON (1<<19) +#define HSW_PWR_WELL_CTL6 0x45414 + +/* Per-pipe DDI Function Control */ +#define TRANS_DDI_FUNC_CTL_A 0x60400 +#define TRANS_DDI_FUNC_CTL_B 0x61400 +#define TRANS_DDI_FUNC_CTL_C 0x62400 +#define TRANS_DDI_FUNC_CTL_EDP 0x6F400 +#define TRANS_DDI_FUNC_CTL(tran) _TRANSCODER2(tran, TRANS_DDI_FUNC_CTL_A) + +#define TRANS_DDI_FUNC_ENABLE (1<<31) +/* Those bits are ignored by pipe EDP since it can only connect to DDI A */ +#define TRANS_DDI_PORT_MASK (7<<28) +#define TRANS_DDI_SELECT_PORT(x) ((x)<<28) +#define TRANS_DDI_PORT_NONE (0<<28) +#define TRANS_DDI_MODE_SELECT_MASK (7<<24) +#define TRANS_DDI_MODE_SELECT_HDMI (0<<24) +#define TRANS_DDI_MODE_SELECT_DVI (1<<24) +#define TRANS_DDI_MODE_SELECT_DP_SST (2<<24) +#define TRANS_DDI_MODE_SELECT_DP_MST (3<<24) +#define TRANS_DDI_MODE_SELECT_FDI (4<<24) +#define TRANS_DDI_BPC_MASK (7<<20) +#define TRANS_DDI_BPC_8 (0<<20) +#define TRANS_DDI_BPC_10 (1<<20) +#define TRANS_DDI_BPC_6 (2<<20) +#define TRANS_DDI_BPC_12 (3<<20) +#define TRANS_DDI_PVSYNC (1<<17) +#define TRANS_DDI_PHSYNC (1<<16) +#define TRANS_DDI_EDP_INPUT_MASK (7<<12) +#define TRANS_DDI_EDP_INPUT_A_ON (0<<12) +#define TRANS_DDI_EDP_INPUT_A_ONOFF (4<<12) +#define TRANS_DDI_EDP_INPUT_B_ONOFF (5<<12) +#define TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12) +#define TRANS_DDI_BFI_ENABLE (1<<4) + +/* DPST related registers */ +#define BLM_HIST_CTL 0x48260 +#define IE_HISTOGRAM_ENABLE (1<<31) +#define IE_MOD_TABLE_ENABLE (1<<27) +#define VLV_IE_MOD_TABLE_ENABLE (1<<30) +#define HSV_INTENSITY_MODE (1<<24) +#define ENHANCEMENT_MODE_MULT (2<<13) +#define BIN_REG_FUNCTION_SELECT_IE (1<<11) +#define BIN_REGISTER_INDEX_MASK 0x7F +#define BLM_HIST_BIN 0x48264 +#define BUSY_BIT (1<<31) +#define BIN_COUNT_MASK_4M 0x3FFFFF +#define BIN_COUNT_MASK_16M 0xFFFFFF +#define BLM_HIST_GUARD 0x48268 +#define HISTOGRAM_INTERRUPT_ENABLE (1<<31) +#define HISTOGRAM_EVENT_STATUS (1<<30) +#define HIST_BIN_COUNT 32 + +#define BDW_DPST_BIN_PIPE_A 0x490C4 +#define BDW_DPST_CTL_PIPE_A 0x490C0 +#define BDW_DPST_GUARD_PIPE_A 0x490C8 + +#define BDW_DPST_BIN_PIPE(pipe) \ + (BDW_DPST_BIN_PIPE_A + (0x100 * (pipe))) +#define BDW_DPST_CTL_PIPE(pipe) \ + (BDW_DPST_CTL_PIPE_A + (0x100 * (pipe))) +#define BDW_DPST_GUARD_PIPE(pipe) \ + (BDW_DPST_GUARD_PIPE_A + (0x100 * (pipe))) + +/* DisplayPort Transport Control */ +#define DP_TP_CTL_A 0x64040 +#define DP_TP_CTL_B 0x64140 +#define DP_TP_CTL(port) _PORT(port, DP_TP_CTL_A, DP_TP_CTL_B) +#define DP_TP_CTL_ENABLE (1<<31) +#define DP_TP_CTL_MODE_SST (0<<27) +#define DP_TP_CTL_MODE_MST (1<<27) +#define DP_TP_CTL_ENHANCED_FRAME_ENABLE (1<<18) +#define DP_TP_CTL_FDI_AUTOTRAIN (1<<15) +#define DP_TP_CTL_LINK_TRAIN_MASK (7<<8) +#define DP_TP_CTL_LINK_TRAIN_PAT1 (0<<8) +#define DP_TP_CTL_LINK_TRAIN_PAT2 (1<<8) +#define DP_TP_CTL_LINK_TRAIN_PAT3 (4<<8) +#define DP_TP_CTL_LINK_TRAIN_IDLE (2<<8) +#define DP_TP_CTL_LINK_TRAIN_NORMAL (3<<8) +#define DP_TP_CTL_SCRAMBLE_DISABLE (1<<7) + +/* DisplayPort Transport Status */ +#define DP_TP_STATUS_A 0x64044 +#define DP_TP_STATUS_B 0x64144 +#define DP_TP_STATUS(port) _PORT(port, DP_TP_STATUS_A, DP_TP_STATUS_B) +#define DP_TP_STATUS_IDLE_DONE (1<<25) +#define DP_TP_STATUS_AUTOTRAIN_DONE (1<<12) + +/* DDI Buffer Control */ +#define DDI_BUF_CTL_A 0x64000 +#define DDI_BUF_CTL_B 0x64100 +#define DDI_BUF_CTL(port) _PORT(port, DDI_BUF_CTL_A, DDI_BUF_CTL_B) +#define DDI_BUF_CTL_ENABLE (1<<31) +/* Haswell */ +#define DDI_BUF_EMP_400MV_0DB_HSW (0<<24) /* Sel0 */ +#define DDI_BUF_EMP_400MV_3_5DB_HSW (1<<24) /* Sel1 */ +#define DDI_BUF_EMP_400MV_6DB_HSW (2<<24) /* Sel2 */ +#define DDI_BUF_EMP_400MV_9_5DB_HSW (3<<24) /* Sel3 */ +#define DDI_BUF_EMP_600MV_0DB_HSW (4<<24) /* Sel4 */ +#define DDI_BUF_EMP_600MV_3_5DB_HSW (5<<24) /* Sel5 */ +#define DDI_BUF_EMP_600MV_6DB_HSW (6<<24) /* Sel6 */ +#define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */ +#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */ +/* Broadwell */ +#define DDI_BUF_EMP_400MV_0DB_BDW (0<<24) /* Sel0 */ +#define DDI_BUF_EMP_400MV_3_5DB_BDW (1<<24) /* Sel1 */ +#define DDI_BUF_EMP_400MV_6DB_BDW (2<<24) /* Sel2 */ +#define DDI_BUF_EMP_600MV_0DB_BDW (3<<24) /* Sel3 */ +#define DDI_BUF_EMP_600MV_3_5DB_BDW (4<<24) /* Sel4 */ +#define DDI_BUF_EMP_600MV_6DB_BDW (5<<24) /* Sel5 */ +#define DDI_BUF_EMP_800MV_0DB_BDW (6<<24) /* Sel6 */ +#define DDI_BUF_EMP_800MV_3_5DB_BDW (7<<24) /* Sel7 */ +#define DDI_BUF_EMP_1200MV_0DB_BDW (8<<24) /* Sel8 */ +#define DDI_BUF_EMP_MASK (0xf<<24) +#define DDI_BUF_PORT_REVERSAL (1<<16) +#define DDI_BUF_IS_IDLE (1<<7) +#define DDI_A_4_LANES (1<<4) +#define DDI_PORT_WIDTH(width) (((width) - 1) << 1) +#define DDI_INIT_DISPLAY_DETECTED (1<<0) + +/* DDI Buffer Translations */ +#define DDI_BUF_TRANS_A 0x64E00 +#define DDI_BUF_TRANS_B 0x64E60 +#define DDI_BUF_TRANS(port) _PORT(port, DDI_BUF_TRANS_A, DDI_BUF_TRANS_B) + +/* Sideband Interface (SBI) is programmed indirectly, via + * SBI_ADDR, which contains the register offset; and SBI_DATA, + * which contains the payload */ +#define SBI_ADDR 0xC6000 +#define SBI_DATA 0xC6004 +#define SBI_CTL_STAT 0xC6008 +#define SBI_CTL_DEST_ICLK (0x0<<16) +#define SBI_CTL_DEST_MPHY (0x1<<16) +#define SBI_CTL_OP_IORD (0x2<<8) +#define SBI_CTL_OP_IOWR (0x3<<8) +#define SBI_CTL_OP_CRRD (0x6<<8) +#define SBI_CTL_OP_CRWR (0x7<<8) +#define SBI_RESPONSE_FAIL (0x1<<1) +#define SBI_RESPONSE_SUCCESS (0x0<<1) +#define SBI_BUSY (0x1<<0) +#define SBI_READY (0x0<<0) + +/* SBI offsets */ +#define SBI_SSCDIVINTPHASE6 0x0600 +#define SBI_SSCDIVINTPHASE_DIVSEL_MASK ((0x7f)<<1) +#define SBI_SSCDIVINTPHASE_DIVSEL(x) ((x)<<1) +#define SBI_SSCDIVINTPHASE_INCVAL_MASK ((0x7f)<<8) +#define SBI_SSCDIVINTPHASE_INCVAL(x) ((x)<<8) +#define SBI_SSCDIVINTPHASE_DIR(x) ((x)<<15) +#define SBI_SSCDIVINTPHASE_PROPAGATE (1<<0) +#define SBI_SSCCTL 0x020c +#define SBI_SSCCTL6 0x060C +#define SBI_SSCCTL_PATHALT (1<<3) +#define SBI_SSCCTL_DISABLE (1<<0) +#define SBI_SSCAUXDIV6 0x0610 +#define SBI_SSCAUXDIV_FINALDIV2SEL(x) ((x)<<4) +#define SBI_DBUFF0 0x2a00 +#define SBI_GEN0 0x1f00 +#define SBI_GEN0_CFG_BUFFENABLE_DISABLE (1<<0) + +/* LPT PIXCLK_GATE */ +#define PIXCLK_GATE 0xC6020 +#define PIXCLK_GATE_UNGATE (1<<0) +#define PIXCLK_GATE_GATE (0<<0) + +/* SPLL */ +#define SPLL_CTL 0x46020 +#define SPLL_PLL_ENABLE (1<<31) +#define SPLL_PLL_SSC (1<<28) +#define SPLL_PLL_NON_SSC (2<<28) +#define SPLL_PLL_LCPLL (3<<28) +#define SPLL_PLL_REF_MASK (3<<28) +#define SPLL_PLL_FREQ_810MHz (0<<26) +#define SPLL_PLL_FREQ_1350MHz (1<<26) +#define SPLL_PLL_FREQ_2700MHz (2<<26) +#define SPLL_PLL_FREQ_MASK (3<<26) + +/* WRPLL */ +#define WRPLL_CTL1 0x46040 +#define WRPLL_CTL2 0x46060 +#define WRPLL_PLL_ENABLE (1<<31) +#define WRPLL_PLL_SELECT_SSC (0x01<<28) +#define WRPLL_PLL_SELECT_NON_SSC (0x02<<28) +#define WRPLL_PLL_SELECT_LCPLL_2700 (0x03<<28) +/* WRPLL divider programming */ +#define WRPLL_DIVIDER_REFERENCE(x) ((x)<<0) +#define WRPLL_DIVIDER_REF_MASK (0xff) +#define WRPLL_DIVIDER_POST(x) ((x)<<8) +#define WRPLL_DIVIDER_POST_MASK (0x3f<<8) +#define WRPLL_DIVIDER_POST_SHIFT 8 +#define WRPLL_DIVIDER_FEEDBACK(x) ((x)<<16) +#define WRPLL_DIVIDER_FB_SHIFT 16 +#define WRPLL_DIVIDER_FB_MASK (0xff<<16) + +/* Port clock selection */ +#define PORT_CLK_SEL_A 0x46100 +#define PORT_CLK_SEL_B 0x46104 +#define PORT_CLK_SEL(port) _PORT(port, PORT_CLK_SEL_A, PORT_CLK_SEL_B) +#define PORT_CLK_SEL_LCPLL_2700 (0<<29) +#define PORT_CLK_SEL_LCPLL_1350 (1<<29) +#define PORT_CLK_SEL_LCPLL_810 (2<<29) +#define PORT_CLK_SEL_SPLL (3<<29) +#define PORT_CLK_SEL_WRPLL1 (4<<29) +#define PORT_CLK_SEL_WRPLL2 (5<<29) +#define PORT_CLK_SEL_NONE (7<<29) +#define PORT_CLK_SEL_MASK (7<<29) + +/* Transcoder clock selection */ +#define TRANS_CLK_SEL_A 0x46140 +#define TRANS_CLK_SEL_B 0x46144 +#define TRANS_CLK_SEL(tran) _TRANSCODER(tran, TRANS_CLK_SEL_A, TRANS_CLK_SEL_B) +/* For each transcoder, we need to select the corresponding port clock */ +#define TRANS_CLK_SEL_DISABLED (0x0<<29) +#define TRANS_CLK_SEL_PORT(x) ((x+1)<<29) + +#define TRANSA_MSA_MISC 0x60410 +#define TRANSB_MSA_MISC 0x61410 +#define TRANSC_MSA_MISC 0x62410 +#define TRANS_EDP_MSA_MISC 0x6f410 +#define TRANS_MSA_MISC(tran) _TRANSCODER2(tran, TRANSA_MSA_MISC) + +#define TRANS_MSA_SYNC_CLK (1<<0) +#define TRANS_MSA_6_BPC (0<<5) +#define TRANS_MSA_8_BPC (1<<5) +#define TRANS_MSA_10_BPC (2<<5) +#define TRANS_MSA_12_BPC (3<<5) +#define TRANS_MSA_16_BPC (4<<5) + +/* LCPLL Control */ +#define LCPLL_CTL 0x130040 +#define LCPLL_PLL_DISABLE (1<<31) +#define LCPLL_PLL_LOCK (1<<30) +#define LCPLL_CLK_FREQ_MASK (3<<26) +#define LCPLL_CLK_FREQ_450 (0<<26) +#define LCPLL_CLK_FREQ_54O_BDW (1<<26) +#define LCPLL_CLK_FREQ_337_5_BDW (2<<26) +#define LCPLL_CLK_FREQ_675_BDW (3<<26) +#define LCPLL_CD_CLOCK_DISABLE (1<<25) +#define LCPLL_CD2X_CLOCK_DISABLE (1<<23) +#define LCPLL_POWER_DOWN_ALLOW (1<<22) +#define LCPLL_CD_SOURCE_FCLK (1<<21) +#define LCPLL_CD_SOURCE_FCLK_DONE (1<<19) + +#define D_COMP (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) +#define D_COMP_RCOMP_IN_PROGRESS (1<<9) +#define D_COMP_COMP_FORCE (1<<8) +#define D_COMP_COMP_DISABLE (1<<0) + +/* Pipe WM_LINETIME - watermark line time */ +#define PIPE_WM_LINETIME_A 0x45270 +#define PIPE_WM_LINETIME_B 0x45274 +#define PIPE_WM_LINETIME(pipe) _PIPE(pipe, PIPE_WM_LINETIME_A, \ + PIPE_WM_LINETIME_B) +#define PIPE_WM_LINETIME_MASK (0x1ff) +#define PIPE_WM_LINETIME_TIME(x) ((x)) +#define PIPE_WM_LINETIME_IPS_LINETIME_MASK (0x1ff<<16) +#define PIPE_WM_LINETIME_IPS_LINETIME(x) ((x)<<16) + +/* SFUSE_STRAP */ +#define SFUSE_STRAP 0xc2014 +#define SFUSE_STRAP_FUSE_LOCK (1<<13) +#define SFUSE_STRAP_DISPLAY_DISABLED (1<<7) +#define SFUSE_STRAP_DDIB_DETECTED (1<<2) +#define SFUSE_STRAP_DDIC_DETECTED (1<<1) +#define SFUSE_STRAP_DDID_DETECTED (1<<0) + +#define WM_MISC 0x45260 +#define WM_MISC_DATA_PARTITION_5_6 (1 << 0) + +#define WM_DBG 0x45280 +#define WM_DBG_DISALLOW_MULTIPLE_LP (1<<0) +#define WM_DBG_DISALLOW_MAXFIFO (1<<1) +#define WM_DBG_DISALLOW_SPRITE (1<<2) + +#define CHV_DPASSC 0x36 + +/* Bit 6 of DPASSC indicates maxfifo enabling bit */ +#define CHV_PW_MAXFIFO_MASK 0x40 + +/* pipe CSC */ +#define _PIPE_A_CSC_COEFF_RY_GY 0x49010 +#define _PIPE_A_CSC_COEFF_BY 0x49014 +#define _PIPE_A_CSC_COEFF_RU_GU 0x49018 +#define _PIPE_A_CSC_COEFF_BU 0x4901c +#define _PIPE_A_CSC_COEFF_RV_GV 0x49020 +#define _PIPE_A_CSC_COEFF_BV 0x49024 +#define _PIPE_A_CSC_MODE 0x49028 +#define CSC_BLACK_SCREEN_OFFSET (1 << 2) +#define CSC_POSITION_BEFORE_GAMMA (1 << 1) +#define CSC_MODE_YUV_TO_RGB (1 << 0) +#define _PIPE_A_CSC_PREOFF_HI 0x49030 +#define _PIPE_A_CSC_PREOFF_ME 0x49034 +#define _PIPE_A_CSC_PREOFF_LO 0x49038 +#define _PIPE_A_CSC_POSTOFF_HI 0x49040 +#define _PIPE_A_CSC_POSTOFF_ME 0x49044 +#define _PIPE_A_CSC_POSTOFF_LO 0x49048 + +#define _PIPE_B_CSC_COEFF_RY_GY 0x49110 +#define _PIPE_B_CSC_COEFF_BY 0x49114 +#define _PIPE_B_CSC_COEFF_RU_GU 0x49118 +#define _PIPE_B_CSC_COEFF_BU 0x4911c +#define _PIPE_B_CSC_COEFF_RV_GV 0x49120 +#define _PIPE_B_CSC_COEFF_BV 0x49124 +#define _PIPE_B_CSC_MODE 0x49128 +#define _PIPE_B_CSC_PREOFF_HI 0x49130 +#define _PIPE_B_CSC_PREOFF_ME 0x49134 +#define _PIPE_B_CSC_PREOFF_LO 0x49138 +#define _PIPE_B_CSC_POSTOFF_HI 0x49140 +#define _PIPE_B_CSC_POSTOFF_ME 0x49144 +#define _PIPE_B_CSC_POSTOFF_LO 0x49148 + +#define PIPE_CSC_COEFF_RY_GY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY) +#define PIPE_CSC_COEFF_BY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY) +#define PIPE_CSC_COEFF_RU_GU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU) +#define PIPE_CSC_COEFF_BU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BU, _PIPE_B_CSC_COEFF_BU) +#define PIPE_CSC_COEFF_RV_GV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RV_GV, _PIPE_B_CSC_COEFF_RV_GV) +#define PIPE_CSC_COEFF_BV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BV, _PIPE_B_CSC_COEFF_BV) +#define PIPE_CSC_MODE(pipe) _PIPE(pipe, _PIPE_A_CSC_MODE, _PIPE_B_CSC_MODE) +#define PIPE_CSC_PREOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_HI, _PIPE_B_CSC_PREOFF_HI) +#define PIPE_CSC_PREOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_ME, _PIPE_B_CSC_PREOFF_ME) +#define PIPE_CSC_PREOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_LO, _PIPE_B_CSC_PREOFF_LO) +#define PIPE_CSC_POSTOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_HI, _PIPE_B_CSC_POSTOFF_HI) +#define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME) +#define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO) + +/* VLV MIPI registers */ + +#define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190) +#define _MIPIB_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700) +#define MIPI_PORT_CTRL(pipe) _PIPE(pipe, _MIPIA_PORT_CTRL, _MIPIB_PORT_CTRL) +#define DPI_ENABLE (1 << 31) /* A + B */ +#define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27 +#define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27) +#define DUAL_LINK_MODE_SHIFT 26 +#define DUAL_LINK_MODE_MASK (1 << 26) +#define DUAL_LINK_MODE_FRONT_BACK (0 << 26) +#define DUAL_LINK_MODE_PIXEL_ALTERNATIVE (1 << 26) +#define DITHERING_ENABLE (1 << 25) /* A + B */ +#define FLOPPED_HSTX (1 << 23) +#define DE_INVERT (1 << 19) /* XXX */ +#define MIPIA_FLISDSI_DELAY_COUNT_SHIFT 18 +#define MIPIA_FLISDSI_DELAY_COUNT_MASK (0xf << 18) +#define AFE_LATCHOUT (1 << 17) +#define LP_OUTPUT_HOLD (1 << 16) +#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_SHIFT 15 +#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_MASK (1 << 15) +#define MIPIB_MIPI4DPHY_DELAY_COUNT_SHIFT 11 +#define MIPIB_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 11) +#define CSB_SHIFT 9 +#define CSB_MASK (3 << 9) +#define CSB_20MHZ (0 << 9) +#define CSB_10MHZ (1 << 9) +#define CSB_40MHZ (2 << 9) +#define BANDGAP_MASK (1 << 8) +#define BANDGAP_PNW_CIRCUIT (0 << 8) +#define BANDGAP_LNC_CIRCUIT (1 << 8) +#define MIPIB_FLISDSI_DELAY_COUNT_LOW_SHIFT 5 +#define MIPIB_FLISDSI_DELAY_COUNT_LOW_MASK (7 << 5) +#define TEARING_EFFECT_DELAY (1 << 4) /* A + B */ +#define TEARING_EFFECT_SHIFT 2 /* A + B */ +#define TEARING_EFFECT_MASK (3 << 2) +#define TEARING_EFFECT_OFF (0 << 2) +#define TEARING_EFFECT_DSI (1 << 2) +#define TEARING_EFFECT_GPIO (2 << 2) +#define LANE_CONFIGURATION_SHIFT 0 +#define LANE_CONFIGURATION_MASK (3 << 0) +#define LANE_CONFIGURATION_4LANE (0 << 0) +#define LANE_CONFIGURATION_DUAL_LINK_A (1 << 0) +#define LANE_CONFIGURATION_DUAL_LINK_B (2 << 0) + +#define _MIPIA_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61194) +#define _MIPIB_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61704) +#define MIPI_TEARING_CTRL(pipe) _PIPE(pipe, _MIPIA_TEARING_CTRL, _MIPIB_TEARING_CTRL) +#define TEARING_EFFECT_DELAY_SHIFT 0 +#define TEARING_EFFECT_DELAY_MASK (0xffff << 0) + +#define DELAY_180_PHASE_SHIFT_MIPIA 0x682C0000 +#define DELAY_180_PHASE_SHIFT_MIPIC 0xF0E0 + +/* XXX: all bits reserved */ +#define _MIPIA_AUTOPWG (VLV_DISPLAY_BASE + 0x611a0) + +/* MIPI DSI Controller and D-PHY registers */ + +#define _MIPIA_DEVICE_READY (VLV_DISPLAY_BASE + 0xb000) +#define _MIPIB_DEVICE_READY (VLV_DISPLAY_BASE + 0xb800) +#define MIPI_DEVICE_READY(pipe) _PIPE(pipe, _MIPIA_DEVICE_READY, _MIPIB_DEVICE_READY) +#define BUS_POSSESSION (1 << 3) /* set to give bus to receiver */ +#define ULPS_STATE_MASK (3 << 1) +#define ULPS_STATE_ENTER (2 << 1) +#define ULPS_STATE_EXIT (1 << 1) +#define ULPS_STATE_NORMAL_OPERATION (0 << 1) +#define DEVICE_READY (1 << 0) + +#define _MIPIA_INTR_STAT (VLV_DISPLAY_BASE + 0xb004) +#define _MIPIB_INTR_STAT (VLV_DISPLAY_BASE + 0xb804) +#define MIPI_INTR_STAT(pipe) _PIPE(pipe, _MIPIA_INTR_STAT, _MIPIB_INTR_STAT) +#define _MIPIA_INTR_EN (VLV_DISPLAY_BASE + 0xb008) +#define _MIPIB_INTR_EN (VLV_DISPLAY_BASE + 0xb808) +#define MIPI_INTR_EN(pipe) _PIPE(pipe, _MIPIA_INTR_EN, _MIPIB_INTR_EN) +#define TEARING_EFFECT (1 << 31) +#define SPL_PKT_SENT_INTERRUPT (1 << 30) +#define GEN_READ_DATA_AVAIL (1 << 29) +#define LP_GENERIC_WR_FIFO_FULL (1 << 28) +#define HS_GENERIC_WR_FIFO_FULL (1 << 27) +#define RX_PROT_VIOLATION (1 << 26) +#define RX_INVALID_TX_LENGTH (1 << 25) +#define ACK_WITH_NO_ERROR (1 << 24) +#define TURN_AROUND_ACK_TIMEOUT (1 << 23) +#define LP_RX_TIMEOUT (1 << 22) +#define HS_TX_TIMEOUT (1 << 21) +#define DPI_FIFO_UNDERRUN (1 << 20) +#define LOW_CONTENTION (1 << 19) +#define HIGH_CONTENTION (1 << 18) +#define TXDSI_VC_ID_INVALID (1 << 17) +#define TXDSI_DATA_TYPE_NOT_RECOGNISED (1 << 16) +#define TXCHECKSUM_ERROR (1 << 15) +#define TXECC_MULTIBIT_ERROR (1 << 14) +#define TXECC_SINGLE_BIT_ERROR (1 << 13) +#define TXFALSE_CONTROL_ERROR (1 << 12) +#define RXDSI_VC_ID_INVALID (1 << 11) +#define RXDSI_DATA_TYPE_NOT_REGOGNISED (1 << 10) +#define RXCHECKSUM_ERROR (1 << 9) +#define RXECC_MULTIBIT_ERROR (1 << 8) +#define RXECC_SINGLE_BIT_ERROR (1 << 7) +#define RXFALSE_CONTROL_ERROR (1 << 6) +#define RXHS_RECEIVE_TIMEOUT_ERROR (1 << 5) +#define RX_LP_TX_SYNC_ERROR (1 << 4) +#define RXEXCAPE_MODE_ENTRY_ERROR (1 << 3) +#define RXEOT_SYNC_ERROR (1 << 2) +#define RXSOT_SYNC_ERROR (1 << 1) +#define RXSOT_ERROR (1 << 0) + +#define _MIPIA_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb00c) +#define _MIPIB_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb80c) +#define MIPI_DSI_FUNC_PRG(pipe) _PIPE(pipe, _MIPIA_DSI_FUNC_PRG, _MIPIB_DSI_FUNC_PRG) +#define CMD_MODE_DATA_WIDTH_MASK (7 << 13) +#define CMD_MODE_NOT_SUPPORTED (0 << 13) +#define CMD_MODE_DATA_WIDTH_16_BIT (1 << 13) +#define CMD_MODE_DATA_WIDTH_9_BIT (2 << 13) +#define CMD_MODE_DATA_WIDTH_8_BIT (3 << 13) +#define CMD_MODE_DATA_WIDTH_OPTION1 (4 << 13) +#define CMD_MODE_DATA_WIDTH_OPTION2 (5 << 13) +#define VID_MODE_FORMAT_MASK (0xf << 7) +#define VID_MODE_NOT_SUPPORTED (0 << 7) +#define VID_MODE_FORMAT_RGB565 (1 << 7) +#define VID_MODE_FORMAT_RGB666 (2 << 7) +#define VID_MODE_FORMAT_RGB666_LOOSE (3 << 7) +#define VID_MODE_FORMAT_RGB888 (4 << 7) +#define CMD_MODE_CHANNEL_NUMBER_SHIFT 5 +#define CMD_MODE_CHANNEL_NUMBER_MASK (3 << 5) +#define VID_MODE_CHANNEL_NUMBER_SHIFT 3 +#define VID_MODE_CHANNEL_NUMBER_MASK (3 << 3) +#define DATA_LANES_PRG_REG_SHIFT 0 +#define DATA_LANES_PRG_REG_MASK (7 << 0) + +#define _MIPIA_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb010) +#define _MIPIB_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb810) +#define MIPI_HS_TX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_HS_TX_TIMEOUT, _MIPIB_HS_TX_TIMEOUT) +#define HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK 0xffffff + +#define _MIPIA_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb014) +#define _MIPIB_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb814) +#define MIPI_LP_RX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_LP_RX_TIMEOUT, _MIPIB_LP_RX_TIMEOUT) +#define LOW_POWER_RX_TIMEOUT_COUNTER_MASK 0xffffff + +#define _MIPIA_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb018) +#define _MIPIB_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb818) +#define MIPI_TURN_AROUND_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIB_TURN_AROUND_TIMEOUT) +#define TURN_AROUND_TIMEOUT_MASK 0x3f + +#define _MIPIA_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb01c) +#define _MIPIB_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb81c) +#define MIPI_DEVICE_RESET_TIMER(pipe) _PIPE(pipe, _MIPIA_DEVICE_RESET_TIMER, _MIPIB_DEVICE_RESET_TIMER) +#define DEVICE_RESET_TIMER_MASK 0xffff + +#define _MIPIA_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb020) +#define _MIPIB_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb820) +#define MIPI_DPI_RESOLUTION(pipe) _PIPE(pipe, _MIPIA_DPI_RESOLUTION, _MIPIB_DPI_RESOLUTION) +#define VERTICAL_ADDRESS_SHIFT 16 +#define VERTICAL_ADDRESS_MASK (0xffff << 16) +#define HORIZONTAL_ADDRESS_SHIFT 0 +#define HORIZONTAL_ADDRESS_MASK 0xffff + +#define _MIPIA_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb024) +#define _MIPIB_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb824) +#define MIPI_DBI_FIFO_THROTTLE(pipe) _PIPE(pipe, _MIPIA_DBI_FIFO_THROTTLE, _MIPIB_DBI_FIFO_THROTTLE) +#define DBI_FIFO_EMPTY_HALF (0 << 0) +#define DBI_FIFO_EMPTY_QUARTER (1 << 0) +#define DBI_FIFO_EMPTY_7_LOCATIONS (2 << 0) + +/* regs below are bits 15:0 */ +#define _MIPIA_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb028) +#define _MIPIB_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb828) +#define MIPI_HSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_HSYNC_PADDING_COUNT, _MIPIB_HSYNC_PADDING_COUNT) + +#define _MIPIA_HBP_COUNT (VLV_DISPLAY_BASE + 0xb02c) +#define _MIPIB_HBP_COUNT (VLV_DISPLAY_BASE + 0xb82c) +#define MIPI_HBP_COUNT(pipe) _PIPE(pipe, _MIPIA_HBP_COUNT, _MIPIB_HBP_COUNT) + +#define _MIPIA_HFP_COUNT (VLV_DISPLAY_BASE + 0xb030) +#define _MIPIB_HFP_COUNT (VLV_DISPLAY_BASE + 0xb830) +#define MIPI_HFP_COUNT(pipe) _PIPE(pipe, _MIPIA_HFP_COUNT, _MIPIB_HFP_COUNT) + +#define _MIPIA_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb034) +#define _MIPIB_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb834) +#define MIPI_HACTIVE_AREA_COUNT(pipe) _PIPE(pipe, _MIPIA_HACTIVE_AREA_COUNT, _MIPIB_HACTIVE_AREA_COUNT) + +#define _MIPIA_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb038) +#define _MIPIB_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb838) +#define MIPI_VSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_VSYNC_PADDING_COUNT, _MIPIB_VSYNC_PADDING_COUNT) + +#define _MIPIA_VBP_COUNT (VLV_DISPLAY_BASE + 0xb03c) +#define _MIPIB_VBP_COUNT (VLV_DISPLAY_BASE + 0xb83c) +#define MIPI_VBP_COUNT(pipe) _PIPE(pipe, _MIPIA_VBP_COUNT, _MIPIB_VBP_COUNT) + +#define _MIPIA_VFP_COUNT (VLV_DISPLAY_BASE + 0xb040) +#define _MIPIB_VFP_COUNT (VLV_DISPLAY_BASE + 0xb840) +#define MIPI_VFP_COUNT(pipe) _PIPE(pipe, _MIPIA_VFP_COUNT, _MIPIB_VFP_COUNT) + +#define _MIPIA_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb044) +#define _MIPIB_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb844) +#define MIPI_HIGH_LOW_SWITCH_COUNT(pipe) _PIPE(pipe, _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIB_HIGH_LOW_SWITCH_COUNT) +/* regs above are bits 15:0 */ + +#define _MIPIA_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb048) +#define _MIPIB_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb848) +#define MIPI_DPI_CONTROL(pipe) _PIPE(pipe, _MIPIA_DPI_CONTROL, _MIPIB_DPI_CONTROL) +#define DPI_LP_MODE (1 << 6) +#define BACKLIGHT_OFF (1 << 5) +#define BACKLIGHT_ON (1 << 4) +#define COLOR_MODE_OFF (1 << 3) +#define COLOR_MODE_ON (1 << 2) +#define TURN_ON (1 << 1) +#define SHUTDOWN (1 << 0) + +#define _MIPIA_DPI_DATA (VLV_DISPLAY_BASE + 0xb04c) +#define _MIPIB_DPI_DATA (VLV_DISPLAY_BASE + 0xb84c) +#define MIPI_DPI_DATA(pipe) _PIPE(pipe, _MIPIA_DPI_DATA, _MIPIB_DPI_DATA) +#define COMMAND_BYTE_SHIFT 0 +#define COMMAND_BYTE_MASK (0x3f << 0) + +#define _MIPIA_INIT_COUNT (VLV_DISPLAY_BASE + 0xb050) +#define _MIPIB_INIT_COUNT (VLV_DISPLAY_BASE + 0xb850) +#define MIPI_INIT_COUNT(pipe) _PIPE(pipe, _MIPIA_INIT_COUNT, _MIPIB_INIT_COUNT) +#define MASTER_INIT_TIMER_SHIFT 0 +#define MASTER_INIT_TIMER_MASK (0xffff << 0) + +#define _MIPIA_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb054) +#define _MIPIB_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb854) +#define MIPI_MAX_RETURN_PKT_SIZE(pipe) _PIPE(pipe, _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIB_MAX_RETURN_PKT_SIZE) +#define MAX_RETURN_PKT_SIZE_SHIFT 0 +#define MAX_RETURN_PKT_SIZE_MASK (0x3ff << 0) + +#define _MIPIA_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb058) +#define _MIPIB_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb858) +#define MIPI_VIDEO_MODE_FORMAT(pipe) _PIPE(pipe, _MIPIA_VIDEO_MODE_FORMAT, _MIPIB_VIDEO_MODE_FORMAT) +#define RANDOM_DPI_DISPLAY_RESOLUTION (1 << 4) +#define DISABLE_VIDEO_BTA (1 << 3) +#define IP_TG_CONFIG (1 << 2) +#define VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE (1 << 0) +#define VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS (2 << 0) +#define VIDEO_MODE_BURST (3 << 0) + +#define _MIPIA_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb05c) +#define _MIPIB_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb85c) +#define MIPI_EOT_DISABLE(pipe) _PIPE(pipe, _MIPIA_EOT_DISABLE, _MIPIB_EOT_DISABLE) +#define LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 7) +#define HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 6) +#define LOW_CONTENTION_RECOVERY_DISABLE (1 << 5) +#define HIGH_CONTENTION_RECOVERY_DISABLE (1 << 4) +#define TXDSI_TYPE_NOT_RECOGNISED_ERROR_RECOVERY_DISABLE (1 << 3) +#define TXECC_MULTIBIT_ERROR_RECOVERY_DISABLE (1 << 2) +#define CLOCKSTOP (1 << 1) +#define EOT_DISABLE (1 << 0) + +#define _MIPIA_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb060) +#define _MIPIB_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb860) +#define MIPI_LP_BYTECLK(pipe) _PIPE(pipe, _MIPIA_LP_BYTECLK, _MIPIB_LP_BYTECLK) +#define LP_BYTECLK_SHIFT 0 +#define LP_BYTECLK_MASK (0xffff << 0) + +/* bits 31:0 */ +#define _MIPIA_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb064) +#define _MIPIB_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb864) +#define MIPI_LP_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_LP_GEN_DATA, _MIPIB_LP_GEN_DATA) + +/* bits 31:0 */ +#define _MIPIA_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb068) +#define _MIPIB_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb868) +#define MIPI_HS_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_HS_GEN_DATA, _MIPIB_HS_GEN_DATA) + +#define _MIPIA_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb06c) +#define _MIPIB_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb86c) +#define MIPI_LP_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_LP_GEN_CTRL, _MIPIB_LP_GEN_CTRL) +#define _MIPIA_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb070) +#define _MIPIB_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb870) +#define MIPI_HS_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_HS_GEN_CTRL, _MIPIB_HS_GEN_CTRL) +#define LONG_PACKET_WORD_COUNT_SHIFT 8 +#define LONG_PACKET_WORD_COUNT_MASK (0xffff << 8) +#define SHORT_PACKET_PARAM_SHIFT 8 +#define SHORT_PACKET_PARAM_MASK (0xffff << 8) +#define VIRTUAL_CHANNEL_SHIFT 6 +#define VIRTUAL_CHANNEL_MASK (3 << 6) +#define DATA_TYPE_SHIFT 0 +#define DATA_TYPE_MASK (3f << 0) +/* data type values, see include/video/mipi_display.h */ + +#define _MIPIA_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb074) +#define _MIPIB_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb874) +#define MIPI_GEN_FIFO_STAT(pipe) _PIPE(pipe, _MIPIA_GEN_FIFO_STAT, _MIPIB_GEN_FIFO_STAT) +#define DPI_FIFO_EMPTY (1 << 28) +#define DBI_FIFO_EMPTY (1 << 27) +#define LP_CTRL_FIFO_EMPTY (1 << 26) +#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25) +#define LP_CTRL_FIFO_FULL (1 << 24) +#define HS_CTRL_FIFO_EMPTY (1 << 18) +#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17) +#define HS_CTRL_FIFO_FULL (1 << 16) +#define LP_DATA_FIFO_EMPTY (1 << 10) +#define LP_DATA_FIFO_HALF_EMPTY (1 << 9) +#define LP_DATA_FIFO_FULL (1 << 8) +#define HS_DATA_FIFO_EMPTY (1 << 2) +#define HS_DATA_FIFO_HALF_EMPTY (1 << 1) +#define HS_DATA_FIFO_FULL (1 << 0) + +#define _MIPIA_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb078) +#define _MIPIB_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb878) +#define MIPI_HS_LP_DBI_ENABLE(pipe) _PIPE(pipe, _MIPIA_HS_LS_DBI_ENABLE, _MIPIB_HS_LS_DBI_ENABLE) +#define DBI_HS_LP_MODE_MASK (1 << 0) +#define DBI_LP_MODE (1 << 0) +#define DBI_HS_MODE (0 << 0) + +#define _MIPIA_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb080) +#define _MIPIB_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb880) +#define MIPI_DPHY_PARAM(pipe) _PIPE(pipe, _MIPIA_DPHY_PARAM, _MIPIB_DPHY_PARAM) +#define EXIT_ZERO_COUNT_SHIFT 24 +#define EXIT_ZERO_COUNT_MASK (0x3f << 24) +#define TRAIL_COUNT_SHIFT 16 +#define TRAIL_COUNT_MASK (0x1f << 16) +#define CLK_ZERO_COUNT_SHIFT 8 +#define CLK_ZERO_COUNT_MASK (0xff << 8) +#define PREPARE_COUNT_SHIFT 0 +#define PREPARE_COUNT_MASK (0x3f << 0) + +/* bits 31:0 */ +#define _MIPIA_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb084) +#define _MIPIB_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb884) +#define MIPI_DBI_BW_CTRL(pipe) _PIPE(pipe, _MIPIA_DBI_BW_CTRL, _MIPIB_DBI_BW_CTRL) + +#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb088) +#define _MIPIB_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb888) +#define MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe) _PIPE(pipe, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIB_CLK_LANE_SWITCH_TIME_CNT) +#define LP_HS_SSW_CNT_SHIFT 16 +#define LP_HS_SSW_CNT_MASK (0xffff << 16) +#define HS_LP_PWR_SW_CNT_SHIFT 0 +#define HS_LP_PWR_SW_CNT_MASK (0xffff << 0) + +#define _MIPIA_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb08c) +#define _MIPIB_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb88c) +#define MIPI_STOP_STATE_STALL(pipe) _PIPE(pipe, _MIPIA_STOP_STATE_STALL, _MIPIB_STOP_STATE_STALL) +#define STOP_STATE_STALL_COUNTER_SHIFT 0 +#define STOP_STATE_STALL_COUNTER_MASK (0xff << 0) + +#define _MIPIA_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb090) +#define _MIPIB_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb890) +#define MIPI_INTR_STAT_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_STAT_REG_1, _MIPIB_INTR_STAT_REG_1) +#define _MIPIA_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb094) +#define _MIPIB_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb894) +#define MIPI_INTR_EN_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_EN_REG_1, _MIPIB_INTR_EN_REG_1) +#define RX_CONTENTION_DETECTED (1 << 0) + +/* XXX: only pipe A ?!? */ +#define MIPIA_DBI_TYPEC_CTRL (VLV_DISPLAY_BASE + 0xb100) +#define DBI_TYPEC_ENABLE (1 << 31) +#define DBI_TYPEC_WIP (1 << 30) +#define DBI_TYPEC_OPTION_SHIFT 28 +#define DBI_TYPEC_OPTION_MASK (3 << 28) +#define DBI_TYPEC_FREQ_SHIFT 24 +#define DBI_TYPEC_FREQ_MASK (0xf << 24) +#define DBI_TYPEC_OVERRIDE (1 << 8) +#define DBI_TYPEC_OVERRIDE_COUNTER_SHIFT 0 +#define DBI_TYPEC_OVERRIDE_COUNTER_MASK (0xff << 0) + + +/* MIPI adapter registers */ + +#define _MIPIA_CTRL (VLV_DISPLAY_BASE + 0xb104) +#define _MIPIB_CTRL (VLV_DISPLAY_BASE + 0xb904) +#define MIPI_CTRL(pipe) _PIPE(pipe, _MIPIA_CTRL, _MIPIB_CTRL) +#define ESCAPE_CLOCK_DIVIDER_SHIFT 5 /* A only */ +#define ESCAPE_CLOCK_DIVIDER_MASK (3 << 5) +#define ESCAPE_CLOCK_DIVIDER_1 (0 << 5) +#define ESCAPE_CLOCK_DIVIDER_2 (1 << 5) +#define ESCAPE_CLOCK_DIVIDER_4 (2 << 5) +#define READ_REQUEST_PRIORITY_SHIFT 3 +#define READ_REQUEST_PRIORITY_MASK (3 << 3) +#define READ_REQUEST_PRIORITY_LOW (0 << 3) +#define READ_REQUEST_PRIORITY_HIGH (3 << 3) +#define RGB_FLIP_TO_BGR (1 << 2) + +#define _MIPIA_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb108) +#define _MIPIB_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb908) +#define MIPI_DATA_ADDRESS(pipe) _PIPE(pipe, _MIPIA_DATA_ADDRESS, _MIPIB_DATA_ADDRESS) +#define DATA_MEM_ADDRESS_SHIFT 5 +#define DATA_MEM_ADDRESS_MASK (0x7ffffff << 5) +#define DATA_VALID (1 << 0) + +#define _MIPIA_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb10c) +#define _MIPIB_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb90c) +#define MIPI_DATA_LENGTH(pipe) _PIPE(pipe, _MIPIA_DATA_LENGTH, _MIPIB_DATA_LENGTH) +#define DATA_LENGTH_SHIFT 0 +#define DATA_LENGTH_MASK (0xfffff << 0) + +#define _MIPIA_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb110) +#define _MIPIB_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb910) +#define MIPI_COMMAND_ADDRESS(pipe) _PIPE(pipe, _MIPIA_COMMAND_ADDRESS, _MIPIB_COMMAND_ADDRESS) +#define COMMAND_MEM_ADDRESS_SHIFT 5 +#define COMMAND_MEM_ADDRESS_MASK (0x7ffffff << 5) +#define AUTO_PWG_ENABLE (1 << 2) +#define MEMORY_WRITE_DATA_FROM_PIPE_RENDERING (1 << 1) +#define COMMAND_VALID (1 << 0) + +#define _MIPIA_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb114) +#define _MIPIB_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb914) +#define MIPI_COMMAND_LENGTH(pipe) _PIPE(pipe, _MIPIA_COMMAND_LENGTH, _MIPIB_COMMAND_LENGTH) +#define COMMAND_LENGTH_SHIFT(n) (8 * (n)) /* n: 0...3 */ +#define COMMAND_LENGTH_MASK(n) (0xff << (8 * (n))) + +#define _MIPIA_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb118) +#define _MIPIB_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb918) +#define MIPI_READ_DATA_RETURN(pipe, n) \ + (_PIPE(pipe, _MIPIA_READ_DATA_RETURN0, _MIPIB_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */ + +#define _MIPIA_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb138) +#define _MIPIB_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb938) +#define MIPI_READ_DATA_VALID(pipe) _PIPE(pipe, _MIPIA_READ_DATA_VALID, _MIPIB_READ_DATA_VALID) +#define READ_DATA_VALID(n) (1 << (n)) + +/* For UMS only (deprecated): */ +#define _PALETTE_A (dev_priv->info.display_mmio_offset + 0xa000) +#define _PALETTE_B (dev_priv->info.display_mmio_offset + 0xa800) + +#define GEN8_OA_CTX_CONTROL 0x2360 + +#define GEN8_RC6_WA_BB 0x2058 + +#endif /* _I915_REG_H_ */ diff --git a/igdbg.lex.l b/igdbg.lex.l new file mode 100644 index 0000000..d96e60c --- /dev/null +++ b/igdbg.lex.l @@ -0,0 +1,92 @@ +%{ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef __cplusplus +extern "C" { +int yylex(void); +} +#endif + +#include "igdbg.yacc.h" + +#undef YY_INPUT +#define YY_INPUT(b,r,ms) (r = my_yyinput(b,ms)) + +#define min(a,b) ((a)>(b)?b:a) + +extern YYSTYPE yylval; + +extern char *cmd_buf,*cmd_ptr,*cmd_end; + +static int my_yyinput(char *buf, int max_size); + +%} + +%% + +[\t ] ; /* ignore whitespace */ +\n ; /* ignore enter */ + +exit | +quit | +help | +verbose | +dumppci | +pipe | +plane | +port | +fifo | +overlay | +onscreen | +fence | +stolen { yylval.string=strdup(yytext); return CMDHDR0; } + +regread | +irq | +estatus | +cstatus | +dumppgtt | +dumpstat | +inl { yylval.string=strdup(yytext); return CMDHDR1; } + +kkflip | +regwrite | +dumpcmd | +dumpgtt | +dumpfb | +dumpfbl | +msgread { yylval.string=strdup(yytext); return CMDHDR2; } + +fillfb | +fillfbl | +dumpring | +msgwrite { yylval.string=strdup(yytext); return CMDHDR3; } + +pciread { yylval.string=strdup(yytext); return CMDHDR4; } +pciwrite { yylval.string=strdup(yytext); return CMDHDR5; } + +[A-Za-z_][A-Za-z0-9_\.]* | +\.[A-Za-z_0-9][A-Za-z0-9_\.]* { yylval.string=strdup(yytext); return FILENAME; } + +([0-9]+)|(0x[a-fA-F0-9]+) { yylval.expr = strtoul(yytext,NULL,0);return NUMBER;} + +\<\< return LSHIFT; +\>\> return RSHIFT; + +. return *yytext; + +%% + + +static int my_yyinput(char *buf, int max_size) +{ + int n = min(max_size, cmd_end - cmd_ptr); + if (n>0) { + memcpy(buf,cmd_ptr,n); + cmd_ptr += n; + } + return n; +} + diff --git a/igdbg.yacc.y b/igdbg.yacc.y new file mode 100644 index 0000000..956c7e3 --- /dev/null +++ b/igdbg.yacc.y @@ -0,0 +1,67 @@ +%{ +#include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + +int process_cmd(char *cmdhdr, int argc, ...); +void yyerror(char *s); +int yylex(void); +int yyparse(void); +int yywrap(void); + +%} + +%union { + unsigned long expr; + char *string; +} + +%token <string> CMDHDR0 CMDHDR1 CMDHDR2 CMDHDR3 CMDHDR4 CMDHDR5 CMDBEAGLE SUBCMD0 SUBCMD1 SUBCMD2 SUBCMD3 FILENAME CMDTOPAZ +%token <expr> NUMBER +%token LSHIFT RSHIFT +%left '-' '+' +%left '*' '/' +%nonassoc UMINUS + +%type <expr> expression + +%% + +command: CMDHDR0 { process_cmd($1,0); } +| CMDHDR1 expression { process_cmd($1,1,$2); } +| CMDHDR2 expression expression { process_cmd($1,2,$2,$3); } +| CMDHDR3 expression expression expression { process_cmd($1,3,$2,$3,$4);} +| CMDHDR4 expression expression expression expression { process_cmd($1,4,$2,$3,$4,$5);} +| CMDHDR5 expression expression expression expression expression { process_cmd($1,4,$2,$3,$4,$5,$6);} + +expression: expression '+' expression { $$ = $1 + $3; } +| expression '-' expression { $$ = $1 - $3; } +| expression '*' expression { $$ = $1 * $3; } +| expression '/' expression { + if ($3 == 0.0) yyerror("divide by zero"); + else $$ = $1 / $3; +} +| expression LSHIFT expression { $$ = $1 << $3; } +| expression RSHIFT expression { $$ = $1 >> $3; } +| '-' expression %prec UMINUS { $$ = -$2; } +| '(' expression ')' { $$ = $2; } +| NUMBER +; + +%% + +void yyerror(char *s) +{ + fprintf(stderr,"%s\n",s); +} + +int yywrap() +{ + return(1); +} + +#ifdef __cplusplus +} +#endif diff --git a/ioperm.S b/ioperm.S new file mode 100644 index 0000000..c15e749 --- /dev/null +++ b/ioperm.S @@ -0,0 +1,40 @@ + /* autogenerated by gensyscalls.py */ + /*#include <sys/linux-syscalls.h>*/ +#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H +#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__ + # define __NR_SYSCALL_BASE 0x900000 + #else + # define __NR_SYSCALL_BASE 0 + #endif +#endif + + +#define __NR_ioperm (__NR_SYSCALL_BASE+101) /* refert to linux-2.6/arch/x86/include/asm/unistd_32.h */ + + .text + .type ioperm, @function + .globl ioperm + .align 4 + + ioperm: + pushl %ebx + pushl %ecx + pushl %edx + mov 16(%esp), %ebx + mov 20(%esp), %ecx + mov 24(%esp), %edx + movl $__NR_ioperm, %eax + int $0x80 + cmpl $-129, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + addl $4, %esp + orl $-1, %eax + 1: + popl %edx + popl %ecx + popl %ebx + ret +
\ No newline at end of file @@ -0,0 +1,35 @@ + /* autogenerated by gensyscalls.py */ + /* #include <sys/linux-syscalls.h> */ + +#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H +#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__ + # define __NR_SYSCALL_BASE 0x900000 + #else + # define __NR_SYSCALL_BASE 0 + #endif +#endif + + +#define __NR_iopl (__NR_SYSCALL_BASE+110) /* refert to linux-2.6/arch/x86/include/asm/unistd_32.h */ + + .text + .type iopl, @function + .globl iopl + .align 4 + + iopl: + pushl %ebx + mov 8(%esp), %ebx + movl $__NR_iopl, %eax + int $0x80 + cmpl $-129, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + addl $4, %esp + orl $-1, %eax + 1: + popl %ebx + ret + diff --git a/linux/Makefile b/linux/Makefile new file mode 100644 index 0000000..1b91d64 --- /dev/null +++ b/linux/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for the kernel character device drivers. +# + +#CFLAGS += -DMODVERSIONS -include $(AOSP_KERNEL)/linux/modversions.h + +obj-m += imem.o + +KERNEL = $(shell uname -r) + +default: + @echo "For Android, run bellow before make" + @echo " source ./build/envsetup.sh" + @echo " lunch xxxxx" + make -C /lib/modules/$(KERNEL)/build M=$(PWD) modules + #make -C $(ANDROID_PRODUCT_OUT)/linux/kernel/ M=$(PWD) modules +clean: + make -C $(ANDROID_PRODUCT_OUT)/linux/kernel/gmin/ M=$(PWD) clean + diff --git a/linux/imem.c b/linux/imem.c new file mode 100644 index 0000000..e3de520 --- /dev/null +++ b/linux/imem.c @@ -0,0 +1,910 @@ +/* + * linux/drivers/char/mem.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Added devfs support. + * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu> + * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com> + */ + +#define CONFIG_DEVMEM TRUE + +#include <linux/mm.h> +#include <linux/miscdevice.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/mman.h> +#include <linux/random.h> +#include <linux/init.h> +#include <linux/raw.h> +#include <linux/tty.h> +#include <linux/capability.h> +#include <linux/ptrace.h> +#include <linux/device.h> +#include <linux/highmem.h> +#include <linux/backing-dev.h> +#include <linux/splice.h> +#include <linux/pfn.h> +#include <linux/export.h> +#include <linux/io.h> +#include <linux/aio.h> + +#include <asm/uaccess.h> + +#ifdef CONFIG_IA64 +# include <linux/efi.h> +#endif + +static inline unsigned long size_inside_page(unsigned long start, + unsigned long size) +{ + unsigned long sz; + + sz = PAGE_SIZE - (start & (PAGE_SIZE - 1)); + + return min(sz, size); +} + +#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE +static inline int valid_phys_addr_range(phys_addr_t addr, size_t count) +{ + return addr + count <= __pa(high_memory); +} + +static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) +{ + return 1; +} +#endif + +#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) +#if defined(CONFIG_STRICT_DEVMEM) && defined(NOT_DEFINE_TO_DISABLE_STRICT_DEVMEM) +static inline int range_is_allowed(unsigned long pfn, unsigned long size) +{ + u64 from = ((u64)pfn) << PAGE_SHIFT; + u64 to = from + size; + u64 cursor = from; + + while (cursor < to) { + if (!devmem_is_allowed(pfn)) { + printk(KERN_INFO + "Program %s tried to access /dev/mem between %Lx->%Lx.\n", + current->comm, from, to); + return 0; + } + cursor += PAGE_SIZE; + pfn++; + } + return 1; +} +#else +static inline int range_is_allowed(unsigned long pfn, unsigned long size) +{ + return 1; +} +#endif +#endif + +#ifdef CONFIG_DEVMEM +void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr) +{ +} + +/* + * This funcion reads the *physical* memory. The f_pos points directly to the + * memory location. + */ +static ssize_t read_mem(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + phys_addr_t p = *ppos; + ssize_t read, sz; + char *ptr; + + if (!valid_phys_addr_range(p, count)) + return -EFAULT; + read = 0; +#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED + /* we don't have page 0 mapped on sparc and m68k.. */ + if (p < PAGE_SIZE) { + sz = size_inside_page(p, count); + if (sz > 0) { + if (clear_user(buf, sz)) + return -EFAULT; + buf += sz; + p += sz; + count -= sz; + read += sz; + } + } +#endif + while (count > 0) { + unsigned long remaining; + + sz = size_inside_page(p, count); + if (!range_is_allowed(p >> PAGE_SHIFT, count)) + return -EPERM; + + /* + * On ia64 if a page has been mapped somewhere as uncached, then + * it must also be accessed uncached by the kernel or data + * corruption may occur. + */ + /* + ptr = xlate_dev_mem_ptr(p); + if (!ptr) + return -EFAULT; + */ + + /* assume page is ram */ + ptr = __va(p); + remaining = copy_to_user(buf, ptr, sz); + unxlate_dev_mem_ptr(p, ptr); + if (remaining) + return -EFAULT; + + buf += sz; + p += sz; + count -= sz; + read += sz; + } + + *ppos += read; + + return read; +} + +static ssize_t write_mem(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + phys_addr_t p = *ppos; + ssize_t written, sz; + unsigned long copied; + void *ptr; + + if (!valid_phys_addr_range(p, count)) + return -EFAULT; + + written = 0; + +#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED + /* we don't have page 0 mapped on sparc and m68k.. */ + if (p < PAGE_SIZE) { + sz = size_inside_page(p, count); + /* Hmm. Do something? */ + buf += sz; + p += sz; + count -= sz; + written += sz; + } +#endif + + while (count > 0) { + sz = size_inside_page(p, count); + + if (!range_is_allowed(p >> PAGE_SHIFT, sz)) + return -EPERM; + + /* + * On ia64 if a page has been mapped somewhere as uncached, then + * it must also be accessed uncached by the kernel or data + * corruption may occur. + */ + /* + ptr = xlate_dev_mem_ptr(p); + if (!ptr) { + if (written) + break; + return -EFAULT; + } + */ + + /* assume page is ram */ + ptr = __va(p); + copied = copy_from_user(ptr, buf, sz); + unxlate_dev_mem_ptr(p, ptr); + if (copied) { + written += sz - copied; + if (written) + break; + return -EFAULT; + } + + buf += sz; + p += sz; + count -= sz; + written += sz; + } + + *ppos += written; + return written; +} +#endif /* CONFIG_DEVMEM */ + +#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) + +int __weak phys_mem_access_prot_allowed(struct file *file, + unsigned long pfn, unsigned long size, pgprot_t *vma_prot) +{ + return 1; +} + +#ifndef __HAVE_PHYS_MEM_ACCESS_PROT + +/* + * Architectures vary in how they handle caching for addresses + * outside of main memory. + * + */ +#ifdef pgprot_noncached +static int uncached_access(struct file *file, phys_addr_t addr) +{ +#if defined(CONFIG_IA64) + /* + * On ia64, we ignore O_DSYNC because we cannot tolerate memory + * attribute aliases. + */ + return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); +#elif defined(CONFIG_MIPS) + { + extern int __uncached_access(struct file *file, + unsigned long addr); + + return __uncached_access(file, addr); + } +#else + /* + * Accessing memory above the top the kernel knows about or through a + * file pointer + * that was marked O_DSYNC will be done non-cached. + */ + if (file->f_flags & O_DSYNC) + return 1; + return addr >= __pa(high_memory); +#endif +} +#endif + +static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot) +{ +#ifdef pgprot_noncached + phys_addr_t offset = pfn << PAGE_SHIFT; + + if (uncached_access(file, offset)) + return pgprot_noncached(vma_prot); +#endif + return vma_prot; +} +#endif + +#ifndef CONFIG_MMU +static unsigned long get_unmapped_area_mem(struct file *file, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags) +{ + if (!valid_mmap_phys_addr_range(pgoff, len)) + return (unsigned long) -EINVAL; + return pgoff << PAGE_SHIFT; +} + +/* can't do an in-place private mapping if there's no MMU */ +static inline int private_mapping_ok(struct vm_area_struct *vma) +{ + return vma->vm_flags & VM_MAYSHARE; +} +#else +#define get_unmapped_area_mem NULL + +static inline int private_mapping_ok(struct vm_area_struct *vma) +{ + return 1; +} +#endif + +static const struct vm_operations_struct mmap_mem_ops = { +#ifdef CONFIG_HAVE_IOREMAP_PROT + //.access = generic_access_phys +#endif +}; + +static int mmap_mem(struct file *file, struct vm_area_struct *vma) +{ + size_t size = vma->vm_end - vma->vm_start; + + if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) + return -EINVAL; + + if (!private_mapping_ok(vma)) + return -ENOSYS; + + if (!range_is_allowed(vma->vm_pgoff, size)) + return -EPERM; + + /* + if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size, + &vma->vm_page_prot)) + return -EINVAL; + */ + + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, + size, + vma->vm_page_prot); + + vma->vm_ops = &mmap_mem_ops; + + /* Remap-pfn-range will mark the range VM_IO */ + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} +#endif /* CONFIG_DEVMEM */ + +#ifdef CONFIG_DEVKMEM +static int mmap_kmem(struct file *file, struct vm_area_struct *vma) +{ + unsigned long pfn; + + /* Turn a kernel-virtual address into a physical page frame */ + pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; + + /* + * RED-PEN: on some architectures there is more mapped memory than + * available in mem_map which pfn_valid checks for. Perhaps should add a + * new macro here. + * + * RED-PEN: vmalloc is not supported right now. + */ + if (!pfn_valid(pfn)) + return -EIO; + + vma->vm_pgoff = pfn; + return mmap_mem(file, vma); +} +#endif + + +#ifdef CONFIG_DEVKMEM +/* + * This function reads the *virtual* memory as seen by the kernel. + */ +static ssize_t read_kmem(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + ssize_t low_count, read, sz; + char *kbuf; /* k-addr because vread() takes vmlist_lock rwlock */ + int err = 0; + + read = 0; + if (p < (unsigned long) high_memory) { + low_count = count; + if (count > (unsigned long)high_memory - p) + low_count = (unsigned long)high_memory - p; + +#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED + /* we don't have page 0 mapped on sparc and m68k.. */ + if (p < PAGE_SIZE && low_count > 0) { + sz = size_inside_page(p, low_count); + if (clear_user(buf, sz)) + return -EFAULT; + buf += sz; + p += sz; + read += sz; + low_count -= sz; + count -= sz; + } +#endif + while (low_count > 0) { + sz = size_inside_page(p, low_count); + + /* + * On ia64 if a page has been mapped somewhere as + * uncached, then it must also be accessed uncached + * by the kernel or data corruption may occur + */ + kbuf = xlate_dev_kmem_ptr((char *)p); + + if (copy_to_user(buf, kbuf, sz)) + return -EFAULT; + buf += sz; + p += sz; + read += sz; + low_count -= sz; + count -= sz; + } + } + + if (count > 0) { + kbuf = (char *)__get_free_page(GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + while (count > 0) { + sz = size_inside_page(p, count); + if (!is_vmalloc_or_module_addr((void *)p)) { + err = -ENXIO; + break; + } + sz = vread(kbuf, (char *)p, sz); + if (!sz) + break; + if (copy_to_user(buf, kbuf, sz)) { + err = -EFAULT; + break; + } + count -= sz; + buf += sz; + read += sz; + p += sz; + } + free_page((unsigned long)kbuf); + } + *ppos = p; + return read ? read : err; +} + + +static ssize_t do_write_kmem(unsigned long p, const char __user *buf, + size_t count, loff_t *ppos) +{ + ssize_t written, sz; + unsigned long copied; + + written = 0; +#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED + /* we don't have page 0 mapped on sparc and m68k.. */ + if (p < PAGE_SIZE) { + sz = size_inside_page(p, count); + /* Hmm. Do something? */ + buf += sz; + p += sz; + count -= sz; + written += sz; + } +#endif + + while (count > 0) { + char *ptr; + + sz = size_inside_page(p, count); + + /* + * On ia64 if a page has been mapped somewhere as uncached, then + * it must also be accessed uncached by the kernel or data + * corruption may occur. + */ + ptr = xlate_dev_kmem_ptr((char *)p); + + copied = copy_from_user(ptr, buf, sz); + if (copied) { + written += sz - copied; + if (written) + break; + return -EFAULT; + } + buf += sz; + p += sz; + count -= sz; + written += sz; + } + + *ppos += written; + return written; +} + +/* + * This function writes to the *virtual* memory as seen by the kernel. + */ +static ssize_t write_kmem(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + ssize_t wrote = 0; + ssize_t virtr = 0; + char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ + int err = 0; + + if (p < (unsigned long) high_memory) { + unsigned long to_write = min_t(unsigned long, count, + (unsigned long)high_memory - p); + wrote = do_write_kmem(p, buf, to_write, ppos); + if (wrote != to_write) + return wrote; + p += wrote; + buf += wrote; + count -= wrote; + } + + if (count > 0) { + kbuf = (char *)__get_free_page(GFP_KERNEL); + if (!kbuf) + return wrote ? wrote : -ENOMEM; + while (count > 0) { + unsigned long sz = size_inside_page(p, count); + unsigned long n; + + if (!is_vmalloc_or_module_addr((void *)p)) { + err = -ENXIO; + break; + } + n = copy_from_user(kbuf, buf, sz); + if (n) { + err = -EFAULT; + break; + } + vwrite(kbuf, (char *)p, sz); + count -= sz; + buf += sz; + virtr += sz; + p += sz; + } + free_page((unsigned long)kbuf); + } + + *ppos = p; + return virtr + wrote ? : err; +} +#endif + +#ifdef CONFIG_DEVPORT +static ssize_t read_port(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long i = *ppos; + char __user *tmp = buf; + + if (!access_ok(VERIFY_WRITE, buf, count)) + return -EFAULT; + while (count-- > 0 && i < 65536) { + if (__put_user(inb(i), tmp) < 0) + return -EFAULT; + i++; + tmp++; + } + *ppos = i; + return tmp-buf; +} + +static ssize_t write_port(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long i = *ppos; + const char __user *tmp = buf; + + if (!access_ok(VERIFY_READ, buf, count)) + return -EFAULT; + while (count-- > 0 && i < 65536) { + char c; + if (__get_user(c, tmp)) { + if (tmp > buf) + break; + return -EFAULT; + } + outb(c, i); + i++; + tmp++; + } + *ppos = i; + return tmp-buf; +} +#endif + +static ssize_t read_null(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + return 0; +} + +static ssize_t write_null(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + return count; +} + +static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf, + struct splice_desc *sd) +{ + return sd->len; +} + +static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) +{ + return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); +} + +static ssize_t read_zero(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + size_t written; + + if (!count) + return 0; + + if (!access_ok(VERIFY_WRITE, buf, count)) + return -EFAULT; + + written = 0; + while (count) { + unsigned long unwritten; + size_t chunk = count; + + if (chunk > PAGE_SIZE) + chunk = PAGE_SIZE; /* Just for latency reasons */ + unwritten = __clear_user(buf, chunk); + written += chunk - unwritten; + if (unwritten) + break; + if (signal_pending(current)) + return written ? written : -ERESTARTSYS; + buf += chunk; + count -= chunk; + cond_resched(); + } + return written ? written : -EFAULT; +} + +static int mmap_zero(struct file *file, struct vm_area_struct *vma) +{ +#ifndef CONFIG_MMU + return -ENOSYS; +#endif + if (vma->vm_flags & VM_SHARED) + return shmem_zero_setup(vma); + return 0; +} + +static ssize_t write_full(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + return -ENOSPC; +} + +/* + * Special lseek() function for /dev/null and /dev/zero. Most notably, you + * can fopen() both devices with "a" now. This was previously impossible. + * -- SRB. + */ +static loff_t null_lseek(struct file *file, loff_t offset, int orig) +{ + return file->f_pos = 0; +} + +#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT) + +/* + * The memory devices use the full 32/64 bits of the offset, and so we cannot + * check against negative addresses: they are ok. The return value is weird, + * though, in that case (0). + * + * also note that seeking relative to the "end of file" isn't supported: + * it has no meaning, so it returns -EINVAL. + */ +static loff_t memory_lseek(struct file *file, loff_t offset, int orig) +{ + loff_t ret; + + mutex_lock(&file->f_path.dentry->d_inode->i_mutex); + switch (orig) { + case SEEK_CUR: + offset += file->f_pos; + case SEEK_SET: + /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */ + if (IS_ERR_VALUE((unsigned long long)offset)) { + ret = -EOVERFLOW; + break; + } + file->f_pos = offset; + ret = file->f_pos; + force_successful_syscall_return(); + break; + default: + ret = -EINVAL; + } + mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); + return ret; +} + +#endif + +#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT) +static int open_port(struct inode * inode, struct file * filp) +{ + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; +} +#endif + +#define zero_lseek null_lseek +#define full_lseek null_lseek +#define write_zero write_null +#define read_full read_zero +#define open_mem open_port +#define open_kmem open_mem + +#ifdef CONFIG_DEVMEM +static const struct file_operations mem_fops = { + .llseek = memory_lseek, + .read = read_mem, + .write = write_mem, + .mmap = mmap_mem, + .open = open_mem, + .get_unmapped_area = get_unmapped_area_mem, +}; +#endif + +#ifdef CONFIG_DEVKMEM +static const struct file_operations kmem_fops = { + .llseek = memory_lseek, + .read = read_kmem, + .write = write_kmem, + .mmap = mmap_kmem, + .open = open_kmem, + .get_unmapped_area = get_unmapped_area_mem, +}; +#endif + +static const struct file_operations null_fops = { + .llseek = null_lseek, + .read = read_null, + .write = write_null, + .splice_write = splice_write_null, +}; + +#ifdef CONFIG_DEVPORT +static const struct file_operations port_fops = { + .llseek = memory_lseek, + .read = read_port, + .write = write_port, + .open = open_port, +}; +#endif + +static const struct file_operations zero_fops = { + .llseek = zero_lseek, + .read = read_zero, + .write = write_zero, + .mmap = mmap_zero, +}; + +/* + * capabilities for /dev/zero + * - permits private mappings, "copies" are taken of the source of zeros + * - no writeback happens + */ +static struct backing_dev_info zero_bdi = { + .name = "char/mem", + .capabilities = BDI_CAP_MAP_COPY | BDI_CAP_NO_ACCT_AND_WRITEBACK, +}; + +static const struct file_operations full_fops = { + .llseek = full_lseek, + .read = read_full, + .write = write_full, +}; + +static const struct memdev { + const char *name; + mode_t mode; + const struct file_operations *fops; + struct backing_dev_info *dev_info; +} devlist[] = { +#ifdef CONFIG_DEVMEM + [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi }, +#endif +/* +#ifdef CONFIG_DEVKMEM + [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi }, +#endif + [3] = { "null", 0666, &null_fops, NULL }, +#ifdef CONFIG_DEVPORT + [4] = { "port", 0, &port_fops, NULL }, +#endif + [5] = { "zero", 0666, &zero_fops, &zero_bdi }, + [7] = { "full", 0666, &full_fops, NULL }, + [8] = { "random", 0666, &random_fops, NULL }, + [9] = { "urandom", 0666, &urandom_fops, NULL }, + [11] = { "kmsg", 0, &kmsg_fops, NULL }, +#ifdef CONFIG_CRASH_DUMP + [12] = { "oldmem", 0, &oldmem_fops, NULL }, +#endif +*/ +}; + +static int memory_open(struct inode *inode, struct file *filp) +{ + int minor; + const struct memdev *dev; + + minor = iminor(inode); + if (minor >= ARRAY_SIZE(devlist)) + return -ENXIO; + + printk("Try to open /dev/imem minor %d\n", minor); + + dev = &devlist[minor]; + if (!dev->fops) + return -ENXIO; + + filp->f_op = dev->fops; + if (dev->dev_info) + filp->f_mapping->backing_dev_info = dev->dev_info; + + /* Is /dev/mem or /dev/kmem ? */ + /* + if (dev->dev_info == &directly_mappable_cdev_bdi) + filp->f_mode |= FMODE_UNSIGNED_OFFSET; + */ + + if (dev->fops->open) + return dev->fops->open(inode, filp); + + return 0; +} + +static const struct file_operations memory_fops = { + .open = memory_open, + .llseek = noop_llseek, +}; + +static char *mem_devnode(struct device *dev, mode_t *mode) +{ + if (mode && devlist[MINOR(dev->devt)].mode) + *mode = devlist[MINOR(dev->devt)].mode; + return NULL; +} + +static struct class *mem_class; + +#define IMEM_MAJOR 999 + +static int __init chr_dev_init(void) +{ + /* + int minor; + int err; + + err = bdi_init(&zero_bdi); + if (err) + return err; + */ + if (register_chrdev(IMEM_MAJOR, "imem", &memory_fops)) + printk("unable to get major %d for memory devs\n", IMEM_MAJOR); + else + printk("Registered /dev/imem (major %d)!\n", IMEM_MAJOR); + + return 0; + /* + mem_class = class_create(THIS_MODULE, "mem"); + if (IS_ERR(mem_class)) + return PTR_ERR(mem_class); + + mem_class->devnode = mem_devnode; + for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) { + if (!devlist[minor].name) + continue; + device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor), + NULL, devlist[minor].name); + } + + return tty_init(); + */ +} + +/* fs_initcall(chr_dev_init); */ +static void __exit chr_dev_uninit(void) +{ + printk("Unregister /dev/imem\n"); + unregister_chrdev(IMEM_MAJOR, "imem"); +} + +module_init(chr_dev_init); +module_exit(chr_dev_uninit); + diff --git a/linux/load.sh b/linux/load.sh new file mode 100755 index 0000000..f3b197f --- /dev/null +++ b/linux/load.sh @@ -0,0 +1,17 @@ +if lsmod | grep -q "^imem"; then + echo "imem.ko is loaded" +else + echo "load imem.ko" + insmod imem.ko + if [ $? -ne "0" ]; then + echo "load imem.ko failed" + exit + fi +fi + +if [ -c /dev/imem ]; then + echo "/dev/imem is created" +else + echo "create /dev/imem, major=999, minor 1" + mknod /dev/imem c 999 1 +fi @@ -0,0 +1,576 @@ +/* + * Copyright © 2014 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. + * + * Author: + * Yuan Shengquan <shengquan.yuan@intel.com> + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> +#include <errno.h> + +#ifndef ANDROID +#include <readline/readline.h> +#include <readline/history.h> +#endif + +#include "igdbg.yacc.h" + +#include "i915_reg.h" +#include "main.h" + +int iopl(int level); +int ioperm(unsigned long from, unsigned long num, int turn_on); +int yyparse(); + +int devmem_fd = -1; +int devmem_strict = 0; + +unsigned short devid, is_gen7=0, is_gen8=0; + +uint32_t phy_mmio,phy_fb, stolen_base; +unsigned char *linear_mmio,*linear_gtt,*linear_fb;/* linear mmio,fb,gtt */ +unsigned int stolen_size, gtt_size, gtt_mapable_size; +int verbose=0; + +char *cmd_buf=NULL,*cmd_ptr=NULL,*cmd_end=NULL; + +void print_bin_fmt(unsigned int value,int space) +{ + char buf[33]; + int i=0; + unsigned int n = value; + + memset(buf,(int)'0',32); + buf[32]='\0'; + do { + buf[i++] = (n&1)+'0'; + n/=2; + } while(n); +#define print_four_bits(from) printf("|%c%c%c%c| ",buf[from],buf[from-1],buf[from-2],buf[from-3]) + for (i=0;i<space;i++) printf(" "); + printf("31 28 27 24 23 20 19 16 15 12 11 08 07 04 03 00\n"); + for (i=0;i<space;i++) printf(" "); + for (i=31;i>=3;i=i-4) + print_four_bits(i); + + printf("\n"); + + for (i=0;i<space;i++) printf(" "); + for (i=7; i>=0;i--) { + printf(" 0x%1x ", 0xf & (value >> (i*4))); + } + + printf("\n"); +} + +int intel_gmch_probe(unsigned int gpu_devid) +{ + uint16_t gmch_ctrl, snb_gmch_ctrl; + uint32_t gtt_base; + + pci_read_config_word(2, SNB_GMCH_CTRL, snb_gmch_ctrl); + + //chv_get_stolen_size + gmch_ctrl = snb_gmch_ctrl; + gmch_ctrl >>= SNB_GMCH_GMS_SHIFT; + gmch_ctrl &= SNB_GMCH_GMS_MASK; + /* + * 0x0 to 0x10: 32MB increments starting at 0MB + * 0x11 to 0x16: 4MB increments starting at 8MB + * 0x17 to 0x1d: 4MB increments start at 36MB + */ + if (gmch_ctrl < 0x11) + stolen_size = gmch_ctrl << 25; + else if (gmch_ctrl < 0x17) + stolen_size = (gmch_ctrl - 0x11 + 2) << 22; + else + stolen_size = (gmch_ctrl - 0x17 + 9) << 22; + /* Read Graphics Base of Stolen Memory directly */ + pci_read_config_dword(2, 0x5c, stolen_base); + stolen_base &= ~((1<<20) - 1); + + /* get GTT size */ + //chv_get_total_gtt_size + gmch_ctrl = snb_gmch_ctrl; + gmch_ctrl >>= SNB_GMCH_GGMS_SHIFT; + gmch_ctrl &= SNB_GMCH_GGMS_MASK; + if (is_gen7) + gtt_size = 1<<20; + if (is_gen8) { + if (gmch_ctrl) + gtt_size = 1 << (20 + gmch_ctrl); + } + gtt_mapable_size = (gtt_size/8)*4096; + + /* Read Graphics Translate Talbe Base */ + pci_read_config_dword(2, 0x70, gtt_base); + gtt_base &= ~((1<<20) - 1); + + printf("Stolen size =%dK (physical base=[0x%x~0x%x](%dM~%dM))\n", + stolen_size/1024, stolen_base, stolen_base+stolen_size, + stolen_base>>20, (stolen_base+stolen_size)>>20); + printf("GTT size = %dK (Can map %dM memory), location at 0x%x (%dM)\n", + gtt_size/1024, gtt_mapable_size>>20, gtt_base, gtt_base>>20); + + return 0; +} + +unsigned int check_deviceid(void) +{ + switch (devid) { + case 0x0152: + case 0x0162: + case 0x0156: + case 0x0166: + case 0x015a: + case 0x016a: + is_gen7 = 1; + printf("Found Ivybridge(GEN7)\n"); + return devid; + case 0x0a06: + case 0x0a16: + case 0x0a26: + case 0x0d06: + case 0x0d16: + case 0x0d26: + is_gen7 = 1; + printf("Found Haswell(GEN7)\n"); + return devid; + case 0x22b0: + case 0x22b1: + case 0x22b2: + case 0x22b3: + is_gen8 = 1; + printf("Found CherryView(GEN8)\n"); + return devid; + } + + return 0; +} + +/* +00:02.0 Class 0300: Device 8086:22b0 (rev 14) +Subsystem: Device 8086:7270 +Flags: bus master, fast devsel, latency 0, IRQ 133 + Memory at 90000000 (64-bit, non-prefetchable) [size=16M] + Memory at 80000000 (64-bit, prefetchable) [size=256M] + I/O ports at 1000 [size=64] + Expansion ROM at <unassigned> [disabled] + Capabilities: [d0] Power Management version 2 + Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit- + Capabilities: [b0] Vendor Specific Information: Len=07 <?> + Kernel driver in use: i915 +*/ +static int setup_devmem(void) +{ + uint32_t value_dw0; /* the first DWORD of PCI config */ + int fd=devmem_fd, mmio_size; + + /* Allow read/write to ALL io ports */ + ioperm(0, 1024, 1); + iopl(3); + + /* get the physical mmio address */ + value_dw0 = pci_get_long(0,(2<<3),0/*PCI_DEVICE_ID*/); + devid = (value_dw0 >> 16) & 0xffff; /* byte 2/3 is device ID */ + if (check_deviceid() == 0) { + fprintf(stderr,"Chip id=0x%x,not supported,exit\n",devid); + return 1; + } + + /* pci base0: mmio/gtt + * pci base2: aperture + */ + phy_mmio = pci_get_long(0,2<<3, PCI_BASE_ADDRESS_0); + printf("MMADR: PCI base0 for MMIO/GTT is 0x%08x\n", phy_mmio); + phy_fb = pci_get_long(0,2<<3, PCI_BASE_ADDRESS_2); + printf("GMADR: PCI base2 for Aperture is 0x%08x\n", phy_fb); + + phy_mmio &= ~4095; + phy_fb &= ~4095; + + /* map mmio/gtt to user space */ + if (is_gen7) + mmio_size = 2 << 20; + if (is_gen8) + mmio_size = 8 << 20; + linear_mmio = (unsigned char *)mmap64(NULL, mmio_size, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, phy_mmio); + linear_gtt = (unsigned char *)mmap64(NULL, mmio_size, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, phy_mmio + mmio_size); + if ((linear_mmio == MAP_FAILED) || (linear_gtt == MAP_FAILED)) { + fprintf(stderr, "Mapping mmio or gtt address 0x%x failed, reason %s\n", + phy_mmio, strerror(errno)); + fprintf(stderr, "Please try \"nopat\" in kernel boot command line?\n"); + return 1; + } + + /* map frame buffer to user space */ + linear_fb = (unsigned char *)mmap64(NULL,FB_MMAP_MB<<20, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, phy_fb); + if (linear_fb == MAP_FAILED) { + fprintf(stderr, "Mapping framebuffer address 0x%x failed, reason %s\n", + phy_fb, strerror(errno)); + return 1; + } + intel_gmch_probe(devid); + + unsigned char dummy[16]; + lseek(fd, 0x1000000, SEEK_SET); /* kernel code address */ + if (read(fd, dummy, 16) == -1) { + fprintf(stderr, "CONFIG_STRICT_DEVMEM is enabled and system RAM dump is disabled\n"); + devmem_strict = 1; + } + return 0; +} + +static int process_exit(char *cmdhdr) +{ + exit(0); + + return 0; +} + +static int process_help(char *cmdhdr) +{ + printf("igdbg -v -d <device> -c <comand>\n"); + printf(" Device by defalt is /dev/mem which may forbit RAM dump due to kernel CONFIG_STRICT_DEVMEM\n"); + printf(" Kernel module in linux/ provide a similar /dev/mem which is not restricted by STRICT_DEVMEM kernel config \n"); + printf(" Command is a single command which is executed immediately. Without it, it will display a prompt to enter the command\n"); + printf(" Command list\n"); + printf(" exit: exit igdbg\n"); + printf(" help: dump this help infomation\n"); + printf(" verbose: verbose display\n"); + printf(" irq <time>: sample IRQ for seconds\n"); + printf(" regread <reg>: get the value of a register\n"); + printf(" regwrite <reg> <value>: write value into a register\n"); + printf(" onscreen: dump gtt information of current onscreen display\n"); + printf(" onscreen buffer is from ADPA(Analog Display Port Register) or DSPASurf/DSPABSurf register\n"); + printf(" dumpfb <offset> <size>: dump content of frambuffer\n"); + printf(" dumpfbl <offset> <size>: dump content of frambuffer with linear mode\n"); + printf(" fillfb <offset> <size> <value>:fill framebuffer\n"); + printf(" fillfbl <offset> <size> <value>:fill framebuffer with linear mode\n"); + printf(" dumpgtt <start addr> <size>: dump gtt information of current display\n"); + printf(" dumpstat <context state bo>: dump context state buffer of a ring\n"); + printf(" <state bo> can get by (bellow example the bo is 0x0af2f000):\n"); + printf(" adb shell cat /sys/kernel/debug/dri/0/i915_context_status\n"); + printf(" render ring: ffff8800196bcc40:.... (pinned x 1) (ggtt offset: 0af2f000, size....)\n"); + printf(" dumppgtt <context state bo>: dump the ppgtt mapping of a context\n"); + printf(" dumpring <context state bo> <head> <tail>: dump the ring including the chained batch buffer\n"); + printf(" fence: dump fence registers\n"); + printf(" pipe: dump pipe information\n"); + printf(" plane: dump plane information\n"); + printf(" port: dump port information\n"); + printf(" overlay: dump overlay register\n"); + printf(" pciread <bus> <dev> <func> <offset>: read dword value from the offset of pci configuration space\n"); + printf(" pciwrite <bus> <dev> <func> <offset> <value>: read dword value into the offset of pci configuration space\n"); + printf(" dumppci: dump pci configuration space\n"); + printf(" inl <port>: get a value from a port\n"); + printf(" msgread <port> <reg> : read MSG from port and reg\n"); + printf(" msgwrite <port> <reg> <value>: write value to MSG port reg\n"); + return 0; +} + +static int process_verbose(char *cmdhdr) +{ + printf("Enable verbose display\n"); + verbose=1; + + return 0; +} + + +static int process_dumppci(char *cmdhdr) +{ + int i; + for (i=0;i<256;i=i+4) { + uint32_t value=pci_get_long(0,2<<3,i); + if ((i % 16)==0) + printf("\n0x%02x: ",i); + printf("%02x %02x %02x %02x ", + (unsigned char)((value)&0xff),(unsigned char)((value>>8)&0xff), + (unsigned char)((value>>16)&0xff),(unsigned char)((value>>24)&0xff)); + } + printf("\n"); + + return 0; +} + +int process_inl(char *cmdhdr,unsigned int reg) +{ + unsigned int value=inl(reg); + + printf("read port 0x%x,value is 0x%08x\n",reg,value); + + print_bin_fmt(value,15); + + return 0; +} + +static int process_pciwrite(char *cmdhdr,unsigned int bus, unsigned int dev, unsigned func, + unsigned int offset,unsigned int value) +{ + if (offset & 3) { + fprintf(stderr,"offset isn't dword aligned, change it from %d to %d\n", + offset, offset & 0xfffffffc); + offset = offset & 0xfffffffc; + } + printf("write pci configuration space offset 0x%x with value 0x%x,original value 0x%x\n", + offset,value,pci_get_long(bus, PCI_DEVFN(dev, func),offset)); + pci_set_long(bus, PCI_DEVFN(dev, func),offset,value); + printf(" read back the value:0x%x\n",pci_get_long(bus, PCI_DEVFN(dev, func),offset)); + + return 0; +} + + +static int process_pciread(char *cmdhdr,unsigned int bus, unsigned int dev, unsigned func, + unsigned int offset) +{ + uint32_t value; + + if (offset & 3) { + fprintf(stderr,"offset isn't dword aligned, change it from %d to %d\n", + offset, offset & 0xfffffffc); + offset = offset & 0xfffffffc; + } + value = pci_get_long(bus, PCI_DEVFN(dev, func),offset); + + printf("read pci configuration space offset 0x%x, value 0x%x\n", + offset,value); + print_bin_fmt(value,15); + + return 0; +} + +/* add one command... + * 1. add one entry into this cmd_list + * 2. define its handler in this file + * 3. add the command synax into igdbg.lex + */ +typedef unsigned int (*cmd_handler)(char *cmdhdr,...); +struct cmd_struct { + char *cmd; + cmd_handler func; +} cmd_list[] = { + {"exit",(cmd_handler)process_exit }, + {"quit",(cmd_handler)process_exit }, + {"help",(cmd_handler)process_help }, + {"verbose",(cmd_handler)process_verbose }, + {"regread",(cmd_handler)process_regread }, + {"regwrite",(cmd_handler)process_regwrite }, + {"onscreen",(cmd_handler)process_onscreen }, + {"dumpfb",(cmd_handler)process_dumpfb }, + {"fillfb",(cmd_handler)process_fillfb }, + {"dumpfbl",(cmd_handler)process_dumpfbl }, + {"fillfbl",(cmd_handler)process_fillfbl }, + {"irq",(cmd_handler)process_irq }, + {"pipe",(cmd_handler)process_pipe }, + {"port",(cmd_handler)process_port }, + {"plane",(cmd_handler)process_plane }, + {"overlay",(cmd_handler)process_overlay }, + {"fence",(cmd_handler)process_fence }, + {"stolen",(cmd_handler)process_stolen }, + {"dumpgtt",(cmd_handler)process_dumpgtt }, + {"dumppgtt",(cmd_handler)process_dumpppgtt }, + {"dumpstat",(cmd_handler)process_dumpstat }, + {"dumpring",(cmd_handler)process_dumpring }, + {"estatus",(cmd_handler)process_estatus }, + {"cstatus",(cmd_handler)process_cstatus }, + {"dumppci",(cmd_handler)process_dumppci }, + {"pciread",(cmd_handler)process_pciread }, + {"pciwrite",(cmd_handler)process_pciwrite }, + {"inl",(cmd_handler)process_inl }, + {"msgread",(cmd_handler)process_msgread }, + {"msgwrite",(cmd_handler)process_msgwrite }, +}; + +int process_cmd(char *cmdhdr,int argc, ...) +{ + va_list arg_ptr; + cmd_handler handler=NULL; + unsigned int i; + + for (i=0; i<sizeof(cmd_list)/sizeof(struct cmd_struct); i++) { + if (strcmp(cmd_list[i].cmd,cmdhdr) == 0) { + handler = cmd_list[i].func; + break; + } + } + + if (handler==NULL) { + fprintf(stderr,"invalide command: %s\n",cmdhdr); + return 1; + } + + va_start(arg_ptr,argc); + + forcewake_on(); + + if (argc==0) + handler(cmdhdr); + else if (argc==1) { + unsigned int para1; + + para1 = va_arg(arg_ptr,unsigned int); + handler(cmdhdr,para1); + } if (argc==2) { + unsigned int para1,para2; + + para1 = va_arg(arg_ptr,unsigned int); + para2 = va_arg(arg_ptr,unsigned int); + handler(cmdhdr,para1,para2); + } if (argc==3) { + unsigned int para1,para2,para3; + + para1 = va_arg(arg_ptr,unsigned int); + para2 = va_arg(arg_ptr,unsigned int); + para3 = va_arg(arg_ptr,unsigned int); + handler(cmdhdr,para1,para2,para3); + } if (argc==4) { + unsigned int para1,para2,para3,para4; + + para1 = va_arg(arg_ptr,unsigned int); + para2 = va_arg(arg_ptr,unsigned int); + para3 = va_arg(arg_ptr,unsigned int); + para4 = va_arg(arg_ptr,unsigned int); + handler(cmdhdr,para1,para2,para3,para4); + } if (argc==5) { + unsigned int para1,para2,para3,para4,para5; + + para1 = va_arg(arg_ptr,unsigned int); + para2 = va_arg(arg_ptr,unsigned int); + para3 = va_arg(arg_ptr,unsigned int); + para4 = va_arg(arg_ptr,unsigned int); + para5 = va_arg(arg_ptr,unsigned int); + handler(cmdhdr,para1,para2,para3,para4,para5); + } if (argc==0xff) { /* command is <cmd subcmd str1 str2> */ + unsigned char *subcmd,*filename; + + subcmd = va_arg(arg_ptr,unsigned char *); + filename = va_arg(arg_ptr,unsigned char *); + handler(cmdhdr,subcmd,filename); + } + if (argc==0xfe) { /* command is <cmd subcmd exp1 exp2 exp3> */ + unsigned char *subcmd; + unsigned int para1, para2, para3; + subcmd = va_arg(arg_ptr,unsigned char *); + para1 = va_arg(arg_ptr,unsigned int); + para2 = va_arg(arg_ptr,unsigned int); + para3 = va_arg(arg_ptr,unsigned int); + handler(cmdhdr,subcmd,para1, para2, para3); + } + forcewake_off(); + + va_end(arg_ptr); + free(cmdhdr); + + return 0; +} + +int main(int argc, char *argv[]) +{ + char opt; + char *devmem = NULL; + + while ((opt=getopt(argc,argv,"hvc:d:")) != -1) { + switch (opt) { + case 'v': + verbose = 1; + break; + case 'c': + cmd_buf = optarg; + break; + case 'd': + devmem = strdup(optarg); + break; + case 'h': + case '?': + default: + process_help("help"); + exit(0); + } + } + /* + if (open_ioport()) { + printf("can't opne /dev/port\n"); + } + */ + if (devmem == NULL) + devmem = strdup("/dev/mem"); + + devmem_fd = open(devmem, O_RDWR); + if (devmem_fd == -1) { + fprintf(stderr, "Open %s failed:%s\n", devmem, strerror(errno)); + return 1; + } + + printf("**********************************************\n"); + if (setup_devmem()) { + close(devmem_fd); + exit(-1); + } + printf("**********************************************\n"); + + if (cmd_buf) { + cmd_ptr = cmd_buf; + cmd_end = cmd_ptr + strlen(cmd_buf); + yyparse(); + + close(devmem_fd); + + return 0; + } + +#ifdef ANDROID + cmd_buf = (char *)malloc(1024); +#endif + for (;;) { +#ifdef ANDROID + printf("(igdbg)"); + gets(cmd_buf); +#else + cmd_buf = readline("(igdbg)"); +#endif + if (!cmd_buf) + break; + if (strlen(cmd_buf)==0) + continue; + + cmd_ptr = cmd_buf; + cmd_end = cmd_ptr + strlen(cmd_buf); + + yyparse(); + } + free(cmd_buf); + + close(devmem_fd); + + return 0; +} @@ -0,0 +1,220 @@ +/* + * Copyright © 2014 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. + */ +#ifndef _MAIN_H +#define _MAIN_H + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#ifdef ANDROID +#include <androidio.h> +#else +#include <unistd.h> /* for libc5 */ +#include <sys/io.h> /* for glibc */ +#endif + +#define PCI_DEVICE_ID 0x02 /* 16 bits */ +#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ +#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */ +#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */ +#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ +#define CONFIG_CMD(bus,device_fn,where) \ + (0x80000000|((bus&0xff) << 16)|((device_fn&0xff) << 8)|((where&0xff) & ~3)) +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) + +/* form i915_drm.h */ +#define SNB_GMCH_CTRL 0x50 +#define SNB_GMCH_GGMS_SHIFT 8 /* GTT Graphics Memory Size */ +#define SNB_GMCH_GGMS_MASK 0x3 +#define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ +#define SNB_GMCH_GMS_MASK 0x1f +#define BDW_GMCH_GGMS_SHIFT 6 +#define BDW_GMCH_GGMS_MASK 0x3 +#define BDW_GMCH_GMS_SHIFT 8 +#define BDW_GMCH_GMS_MASK 0xff + + +#define PAGE_SIZE 4096 +//#define PAGE_MASK ~(PAGE_SIZE - 1) + +#define max(a,b) ((a)>(b)?(a):(b)) +#define min(a,b) ((a)>(b)?(b):(a)) + +enum intel_ring_id { + RCS = 0x0, + VCS, + BCS, + VECS, + VCS2 +}; + +#define FB_MMAP_MB 256 +#define PCI_DEVFN(dev, fn) ((dev<<3)|fn) + +/* Memory mapped register access macros */ +#define INREG8(base,addr) *(volatile unsigned char *)(base + (addr)) +#define INREG16(base,addr) *(volatile unsigned short *)(base + (addr)) +#define INREG(base,addr) *(volatile unsigned int *)(base + (addr)) +#define INREG_DISP(base,addr) *(volatile unsigned int *)(base + 0x180000 + (addr)) + +#define OUTREG8(base,addr, val) do { \ + *(volatile unsigned char *)(base + (addr)) = (val); \ + } while (0) +#define OUTREG16(base,addr, val) do { \ + *(volatile unsigned short *)(base + (addr)) = (val); \ + } while (0) +#define OUTREG(base,addr, val) do { \ + *(volatile unsigned int *)(base + (addr)) = (val); \ + } while (0) + +#define PSB_WVDC32(_val, _offs) \ + OUTREG(linear_mmio+PSB_VDC_OFFSET, _offs, _val) +#define PSB_RVDC32(_offs) \ + INREG(linear_mmio+PSB_VDC_OFFSET, (_offs)) + +#define CHECK_STRICT_DEVMEM \ +do { \ + if (devmem_strict) { \ + fprintf(stderr, "CONFIG_STRICT_DEVMEM forbids RAM dump, return\n"); \ + return 1; \ + } \ +} while (0) + +extern int devmem_fd; +extern int devmem_strict; + +extern unsigned short devid, is_gen7, is_gen8; +extern uint32_t phy_mmio,phy_gtt,phy_fb, stolen_base; +extern unsigned char *linear_mmio,*linear_gtt,*linear_fb;/* linear mmio,fb,gtt */ +extern unsigned int stolen_size, gtt_size, gtt_mapable_size;; +extern int verbose; + +extern char *cmd_buf, *cmd_ptr,*cmd_end; + +static inline uint32_t pci_get_long(int bus,int device_fn, int where) +{ + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); + return inl(0xCFC); +} + +static inline int pci_set_long(int bus,int device_fn, int where,uint32_t value) +{ + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); + outl(value,0xCFC); + return 0; +} + +static inline int pci_get_short(int bus,int device_fn, int where) +{ + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); + return inw(0xCFC + (where&2)); +} + + +static inline int pci_set_short(int bus,int device_fn, int where,unsigned short value) +{ + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8); + outw(value,0xCFC + (where&2)); + return 0; +} + + +#define pci_write_config_dword(dev_fn, offset, value) pci_set_long(0,dev_fn<<3,offset, value) + +#define pci_read_config_dword(dev_fn, offset, value) \ + do { \ + value = pci_get_long(0,dev_fn<<3,offset); \ + } while (0) + +#define pci_read_config_word(dev_fn, offset, value) \ + do { \ + value = pci_get_short(0,dev_fn<<3,offset); \ + } while (0) + + +/**/ +static inline unsigned int MSG_READ32(unsigned int port, unsigned int offset) +{ + int mcr = (0x10 << 24) | (port << 16) | (offset << 8); + unsigned int ret_val = 0; + /* struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); */ + unsigned int pci_root = 0; + pci_write_config_dword(pci_root, 0xD0, mcr); + pci_read_config_dword(pci_root, 0xD4, ret_val); + /* pci_dev_put(pci_root); */ + return ret_val; +} +static inline void MSG_WRITE32(unsigned int port, unsigned int offset, unsigned int value) +{ + int mcr = (0x11 << 24) | (port << 16) | (offset << 8) | 0xF0; + /* struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); */ + unsigned int pci_root = 0; + pci_write_config_dword(pci_root, 0xD4, value); + pci_write_config_dword(pci_root, 0xD0, mcr); + /* pci_dev_put(pci_root); */ +} + +void print_bin_fmt(unsigned int value,int space); + +int process_inl(char *cmdhdr,unsigned int reg); + +int process_msgread(char *cmdhdr,unsigned int port,unsigned int reg); +int process_msgwrite(char *cmdhdr,unsigned int port, unsigned int reg, unsigned int new_value); +int process_regread(char *cmdhdr,unsigned int reg); +int process_regwrite(char *cmdhdr,unsigned int reg,unsigned int value); +int process_irq(char *cmdhdr,unsigned int seconds); +int process_estatus(char *cmdhdr,unsigned int value); +int process_cstatus(char *cmdhdr,unsigned int value); + +int process_onscreen(char *cmdhdr); +int process_pipe(char *cmdhdr); +int process_plane(char *cmdhdr); +int process_port(char *cmdhdr); +int process_overlay(char *cmdhdr); +int process_fence(char *cmdhdr); + +int process_dumpgtt(char *cmdhdr,unsigned int fb_mstart,unsigned int fb_msize); +int process_stolen(char *cmdhdr); +int process_dumpppgtt(char *cmdhdr,unsigned int ppgtt_pyaddr); +int process_fonscreen(char *cmdhdr,unsigned int value, + unsigned int size, unsigned int flag); +int process_fillfb(char *cmdhdr,unsigned int offset, + unsigned int size,unsigned int value); +int process_dumpfb(char *cmdhdr,unsigned int offset, + unsigned int size); +int process_fillfbl(char *cmdhdr,unsigned int offset, + unsigned int size,unsigned int value); +int process_dumpfbl(char *cmdhdr,unsigned int offset, + unsigned int size); +int process_dumpstat(char *cmdhdr,unsigned int stat_addr); +int process_dumpring(char *cmdhdr,unsigned int stat_addr, unsigned int head, unsigned int tail); + +int get_ppgtt_page(uint32_t pd_phyaddr, uint32_t ppgtt_addr, unsigned char one_page[]); +uint32_t get_ring(unsigned int stat_addr); +uint32_t get_ppgtt(unsigned int stat_addr); +int forcewake_on(); +int forcewake_off(); + +#endif @@ -0,0 +1,167 @@ +/* + * Copyright © 2014 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> + +#include "main.h" + +/* i915_gem_gtt.h */ + +/* GEN8 legacy style address is defined as a 3 level page table: + * 31:30 | 29:21 | 20:12 | 11:0 + * PDPE | PDE | PTE | offset + * The difference as compared to normal x86 3 level page table is the PDPEs are + * programmed via register. + */ +#define FOUR_PAGE_SIZE (4096 * 4) +#define PDE_COUNT_PER_PAGE 512 +#define PTE_COUNT_PER_PDE 512 +#define PDE_COUNT (4*PDE_COUNT_PER_PAGE) +#define PDE_MAPPABLE_SIZE (512*4096) + +static uint64_t pd_page[PDE_COUNT]; +static uint64_t pt_page[PTE_COUNT_PER_PDE]; + +int print_ppgtt_mapping(uint32_t pd_phyaddr) +{ + uint32_t pde, pte; + uint64_t *pd; + + /* first map page directory */ + pd_phyaddr &= 0xfffff000; + + lseek(devmem_fd, pd_phyaddr, SEEK_SET); + if (read(devmem_fd, pd_page, FOUR_PAGE_SIZE) != FOUR_PAGE_SIZE) { + perror("Read page directory content from /dev/mem failed\n"); + exit(-1); + } + + pd = &pd_page[0]; + for (pde = 0; pde<PDE_COUNT; pde++) { + uint32_t pde_value, pde_addr; + uint32_t addr_start = pde * PDE_MAPPABLE_SIZE; + uint32_t addr_end=(pde+1)* PDE_MAPPABLE_SIZE; + uint64_t *pt; + + if ((pd[pde] & 1) == 0) /* not valid */ + continue; + + pde_value = (uint32_t) pd[pde]; + pde_addr = pde_value & 0xfffff000; + printf("pde[%04d]=0x%08x (ppgtt offset range:0x%08x~0x%08x(%04dM~%04dM)\n", + pde, pde_value, addr_start, addr_end, addr_start>>20, addr_end>>20); + + lseek(devmem_fd, pde_addr, SEEK_SET); + if (read(devmem_fd, &pt_page[0], 4096) != 4096) { + perror("Read page table content from /dev/mem failed\n"); + exit(-1); + } + pt = &pt_page[0]; + for (pte=0; pte<PTE_COUNT_PER_PDE; pte++) { + uint32_t pte_value, pte_addr; + uint32_t addr; + + if ((pt[pte] & 1) == 0) + continue; + + if (pte > 0) { + if (pt[pte] == pt[pte-1]) + continue; + } + pte_value = (uint32_t) pt[pte]; + pte_addr = pte_value & 0xfffff000; + addr = addr_start + pte * 4096; + printf("\t pte[%03d] = 0x%08x(page no.=%06d, ppgtt addr 0x%x(%04dM+%04dK))\n", + pte, pte_value, pte_addr>>12, addr, addr>>20, (addr>>10)&0x3ff); + } + } + + return 0; +} + +int get_ppgtt_page(uint32_t pd_phyaddr, uint32_t addr, unsigned char one_page[]) +{ + uint32_t pdp_idx = (addr >> 30) & 0x3; + uint32_t pd_idx = (addr >> 21) & 0x1ff; + uint32_t pt_idx = (addr >> 12) & 0x1ff; + uint32_t pd_index, pde_value, pde_addr, pte_value, pte_addr; + + /* first map page directory */ + pd_phyaddr &= 0xfffff000; + + /* get PDE entry */ + lseek(devmem_fd, pd_phyaddr, SEEK_SET); + if (read(devmem_fd, &pd_page[0], FOUR_PAGE_SIZE) != FOUR_PAGE_SIZE) { + perror("Read page directory content from /dev/mem failed\n"); + exit(-1); + } + + /* get PTE entry */ + pd_index = pdp_idx * PDE_COUNT_PER_PAGE + pd_idx; + pde_value = (uint32_t)(pd_page[pd_index] & 0xfffff000); + pde_addr = pde_value & 0xfffff000; + lseek(devmem_fd, pde_addr, SEEK_SET); + if (read(devmem_fd, &pt_page[0], 4096) != 4096) { + perror("Read page table content from /dev/mem failed\n"); + exit(-1); + } + pte_value = (uint32_t)pt_page[pt_idx]; + /* + printf("Batch buffer in PPGTT:(PD index %d(page %d, offset %d), entry 0x%08x)/(PT index %d, entry 0x%08x)\n", + pd_index, pdp_idx, pd_idx, pde_value, pt_idx, pte_value); + */ + pte_addr = pte_value & 0xfffff000; + lseek(devmem_fd, pte_addr, SEEK_SET); + if (read(devmem_fd, &one_page[0], 4096) != 4096) { /* read the content */ + perror("Read page table content from /dev/mem failed\n"); + exit(-1); + } + + return 0; +} + + +int process_dumpppgtt(char *cmdhdr,unsigned int stat_addr) +{ + uint32_t ppgtt_addr; + + if (is_gen7) { + printf("PPGTT is not supported on GEN7\n"); + return 0; + } + CHECK_STRICT_DEVMEM; + + ppgtt_addr = get_ppgtt(stat_addr); + + printf("Page directory address 0x%08x\n", ppgtt_addr); + print_ppgtt_mapping(ppgtt_addr); + + return 0; +} diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..b701e63 --- /dev/null +++ b/readme.txt @@ -0,0 +1,581 @@ + igdbg: i915 kernel driver tool + +Content: + 1. Introduction + 2. Implementation overview + 3. Command summary + 4. Command details + 5. Reference + + +1. Introduction + +igdbg is a standalone user mode tool that can run on a Linux system with +proper configuration. The primary purpose of this tool is to learn and +understand i915 GPU driver which is in linux kernel "drivers/gpu/drm/i915" +folder. It might be also helpful for developers to check or dump GPU states. + +The tool must be invoked by root. Usage: + igdbg [ -v -d <device name> -c <command> ] + + <device name> is the device that the tool uses to access GPU resources, + by default it is /dev/mem + <command> is the command to be executed. Without it, the tool enters + into interactive mode so that user can type a command later + +The tool till now is only tested on a GEN8 based Android device. It only +adds a few device IDs in the support list, thus it might not work or might +get different result on other devices. + +2. Implementation overview + +The tool opens /dev/mem to "mmap" device memory. The memory includes GPU +mmio space, gtt space and frame buffer. It is the way that the tool dumps +registers/gtt and frame buffer content. There are some GPU resources that +are in system memory including PPGTT tables, ring buffers, etc. For them, +the tool uses "read/write" to access them. + +There are two Linux kernel configurations that may forbid "mmap" and +"read/write" on /dev/mem: CONFIG_X86_PAT and CONFIG_STRICT_DEVMEM. PAT can +be flagged on or off by "nopat" kernel boot parameter. Check bellow table +if there are some problems to run the tool: + +CONFIG_STRICT_DEVMEM | Y | N +---------------------+---------------------+------------------------- + Allow "mmap" | Usually it is Yes, but may get issue on some + on device memory? | systems. Try to add "nopat" if it is the case +---------------------+---------------------+------------------------- + Allow "read/write" | No | Yes + on system RAM? | | +---------------------+---------------------+------------------------- + +Sub-folder linux/imem.c is a kernel module of char device. It derives from linux +kernel "driver/char/mem.c". The difference is that it removes the restrictions +of CONFIG_STRICT_DEVMEM. When load it into kernel, it registers a char device +with major number 999. The tool can use this char device instead of /dev/mem to +"mmap" and "read/write" by command line parameter "-d <device name>". It is for the +people that don't want to rebuild the kernel to disable STRICT_DEVMEM configuration. + +3. Command summary + +As mentioned above, "mmap" is used to access mmio/gtt space and frame buffer +content, and "read/write" is used to access the resources in system memory. From +this perspective, there are two types of commands: + +A. Commands that are supported by "mmap" /dev/mem + + Command | Introduction +-----------+--------------------------------------------------- + regread | Read a register +-----------+--------------------------------------------------- + regwrite | Write a register +-----------+--------------------------------------------------- + dumpgtt | Dump GGTT mappings +-----------+--------------------------------------------------- + stolen | Dump stolen memory mappings +-----------+--------------------------------------------------- + dumpfb | Dump frame buffer +-----------+--------------------------------------------------- + dumpfbl | Dump frame buffer with a fence register, + | thus it is linear mode +-----------+--------------------------------------------------- + fillfb | Fill frame buffer +-----------+--------------------------------------------------- + fillfbl | Fill frame buffer with a fence register, + | thus it is linear mode +-----------+--------------------------------------------------- + irq | Sample IRQ status +-----------+--------------------------------------------------- + cstatus | Sample execlist context status +-----------+--------------------------------------------------- + +B. Commands that are supported by "read/write" /dev/mem + + Command | Introduction +-----------+--------------------------------------------------- + dumpstat | Dump context stat +-----------+--------------------------------------------------- + dumppgtt | Dump PPGTT mappins +-----------+--------------------------------------------------- + dumpring | Dump ring buffer and the chained batch buffer +-----------+--------------------------------------------------- + +4. Command details + +4.1 regread/regwrite + +regread <register address> +regwrite <register address> <register value> + +4.2 dumpgtt + +GTT table usually shares the PCI BAR0 with mmio space. It locates at the +half bottom of the space. The real memory behind it actually resides in +system RAM whose address can be read out from a register + + dumpgtt <offset> <size> + +Example: + igdbg -c "dumpgtt 2<<20 40<<10" + +>>>>>> +GTT size = 4096K (Can map 2048M memory), location at 0x7c900000 (1993M) +-----------------------------002M FB------------------------------ +FB:0x0200000|002M+0000K|GTT offset:0x01000(entry 0x00200): 007cf00001 +FB:0x0201000|002M+0004K|GTT offset:0x01008(entry 0x00201): 007cf01001 +FB:0x0202000|002M+0008K|GTT offset:0x01010(entry 0x00202): 007cf02001 +FB:0x0203000|002M+0012K|GTT offset:0x01018(entry 0x00203): 007cf03001 +FB:0x0204000|002M+0016K|GTT offset:0x01020(entry 0x00204): 007cf04001 +FB:0x0205000|002M+0020K|GTT offset:0x01028(entry 0x00205): 007cf05001 +FB:0x0206000|002M+0024K|GTT offset:0x01030(entry 0x00206): 007cf06001 +FB:0x0207000|002M+0028K|GTT offset:0x01038(entry 0x00207): 007cf07001 +FB:0x0208000|002M+0032K|GTT offset:0x01040(entry 0x00208): 007cf08001 +FB:0x0209000|002M+0036K|GTT offset:0x01048(entry 0x00209): 007cf09001 +<<<<<< + +It dumps the mapping of 40 pages (40K) starting from 2M of frame buffer. + +4.3 stolen + +Dump the mysterious stolen memory mappings in GTT + stolen + +Example: + igdbg -c "stolen" + +>>>>>> +Stolen size =32768K (physical base=[0x7cd00000~0x7ed00000](1997M~2029M)) +-----------------------------000M+0000K FB------------------------------ +FB:0x0000000|000M+0000K|GTT offset:0x00000(entry 0x00000): 007cd00001 +FB:0x0001000|000M+0004K|GTT offset:0x00008(entry 0x00001): 007cd01001 +FB:0x0002000|000M+0008K|GTT offset:0x00010(entry 0x00002): 007cd02001 +...... +-----------------------------022M+0088K FB------------------------------ +FB:0x1616000|022M+0088K|GTT offset:0x0b0b0(entry 0x01616): 007d64c01b +FB:0x1617000|022M+0092K|GTT offset:0x0b0b8(entry 0x01617): 007d64d01b +...... +-----------------------------092M+0512K FB------------------------------ +FB:0x5c80000|092M+0512K|GTT offset:0x2e400(entry 0x05c80): 007d68e01b +FB:0x5c81000|092M+0516K|GTT offset:0x2e408(entry 0x05c81): 007d68f01b +-----------------------------160M+0492K FB------------------------------ +FB:0xa07b000|160M+0492K|GTT offset:0x503d8(entry 0x0a07b): 007d71601b +FB:0xa07c000|160M+0496K|GTT offset:0x503e0(entry 0x0a07c): 007d71701b +...... +<<<<<< + +4.4 onscreen + +Display onscreen frame buffer information. It might be from DSPASURF or DSPBSURF +registers (Display Surface Base Address Register) + + onscreen + +Example: + igdbg -c "onscreen" + +>>>>>> +Plane A is enabled +DSPCNTR:value=0xb8000400(X-tiled(512x8), format 0xe(e:RGBX, f:RGBA)) + 31 28 27 24 23 20 19 16 15 12 11 08 07 04 03 00 + |1011| |1000| |0000| |0000| |0000| |0100| |0000| |0000| + 0xb 0x8 0x0 0x0 0x0 0x4 0x0 0x0 +Offset of current display:0xac8f000(172M+572K), GTT offset at 353400 +<<<<<< + +From above, on-screen frame buffer is X-tiled, and the address is at 0xac8f000 + +4.5 dumpfb/fillfb + +Access frame buffer through PCI BAR2 which is the "window" of the backing real +system RAM mapped by GTT. Another term of this "window" is aperture. + + dumpfb <offset> <size> + fillfb <offset> <size> <value> + +Example: + +Firstly get the onscreen frame buffer address: + + igdbg -c "onscree" + +>>>>>> +Offset of current display:0xac8f000(172M+572K), GTT offset 353400 with 5 entries: +<<<<<< + +Then dump it with an offset 480 (start from 0x0ac8f1e0): + igdbg -c "dumpfb 0xac8f000+480 64" + +>>>>>> +Dump frame buffer from offset 0xac8f1e0,size 128 +0x0ac8f1e0: 0x65 0x71 0x16 0xff 0x64 0x70 0x14 0xff +0x0ac8f1e8: 0x63 0x6f 0x13 0xff 0x62 0x6e 0x11 0xff +0x0ac8f1f0: 0x62 0x6d 0x10 0xff 0x61 0x6e 0x10 0xff +0x0ac8f1f8: 0x62 0x6f 0x11 0xff 0x62 0x70 0x12 0xff +0x0ac8f200: 0x6d 0x74 0x28 0xff 0x6d 0x74 0x34 0xff +0x0ac8f208: 0x6e 0x74 0x41 0xff 0x6e 0x75 0x46 0xff +0x0ac8f210: 0x6e 0x75 0x44 0xff 0x6d 0x75 0x41 0xff +0x0ac8f218: 0x6c 0x75 0x42 0xff 0x6d 0x75 0x44 0xff +<<<<<< + +4.6 dumpfbl/fillfbl + +Same with above commands, but it will force a "fence" register for the accessed +range, thus it will get linear data if frame buffer is tiled format. It is a hack +way for the understanding of aperture/fence and tile/linear. + + dumpfbl <offset> <size> + fillfbl <offset> <size> <value> + +Example: + +Dump the same onscreen buffer as above, but use dumpfbl + igdbg -c "dumpfbl 0xac8f000+480 64" +>>>>>> +Force FENCE0 for linear access with stride 5120 +Dump frame buffer from offset 0xac8f1e0,size 128 +0x0ac8f1e0: 0x65 0x71 0x16 0xff 0x64 0x70 0x14 0xff +0x0ac8f1e8: 0x63 0x6f 0x13 0xff 0x62 0x6e 0x11 0xff +0x0ac8f1f0: 0x62 0x6d 0x10 0xff 0x61 0x6e 0x10 0xff +0x0ac8f1f8: 0x62 0x6f 0x11 0xff 0x62 0x70 0x12 0xff +0x0ac8f200: 0x61 0x71 0x12 0xff 0x60 0x70 0x13 0xff +0x0ac8f208: 0x5f 0x70 0x12 0xff 0x5e 0x70 0x11 0xff +0x0ac8f210: 0x5f 0x70 0x10 0xff 0x5f 0x70 0x10 0xff +0x0ac8f218: 0x5f 0x70 0x11 0xff 0x5e 0x71 0x11 0xff +Restore FENCE0 +<<<<<< + +Since the onscreen frame buffer is X-tile that the sub-tile block is 512x8, +the first 512 bytes from "dumpfb" and "dumpfbl" is same, but then the following +bytes will be different (start from 0x0ac8f200). + +Similarly, use command: + igdbg -c "fillfb 0xac8f000 4096 0xff" + igdbg -c "fillfbl 0xac8f000 4096 0xff" + +They will visually display the difference on screen. The first one will display +a 512x8 grey block on screen, and the second will display a grey line + + +4.7 irq + +Sample IIR registers (interrupt identify register) to print a rough overview of +IRQs. Also the sequence number associated with the command is printed out. It is +read out from an offset of Hardware Status Page. The command is for the purpose +to understand the engines that are used for a task (e.g. video encode) + irq <seconds> + +Example: +Run video encoding and igdbg at the same time + va_encode -r 30 + igdbg -c "irq 500" + +>>>>>> +Sample IRQ for 500 seconds....It is not accurate, just rough view +Render HWS_PGA=0x008cd000, Video HWS_PGA=0x00904000 + +T1253.841:iir=0x00000100 + VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010b3) +T1262.051:iir=0x00000001 + VCS:GT_USER_INTERRUPT (seqno=0x000010b7) +T1295.786:iir=0x00000100 + VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010bb) +T1360.381:iir=0x00000100 + RCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c0) +T1361.176:iir=0x00000001 + VCS:GT_USER_INTERRUPT (seqno=0x000010c2) +T1361.260:iir=0x00000100 + VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c3) +T1392.961:iir=0x00000100 + RCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c1) +T1394.567:iir=0x00000100 + VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c3) +T1394.812:iir=0x00000100 + VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c7) +T1426.393:iir=0x00000001 + RCS:GT_USER_INTERRUPT (seqno=0x000010c8) +T1427.856:iir=0x00000100 + VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010cb) +...... +<<<<<< + +4.8 dumpstat + +On GEN8 and above, each context associates a state buffer for context save and restore. + + dumpstat <state bo> + +State bo can get from /sys/kernel/debug/dri/0/i915_context_status + +Example: + +Firstly run a video encoding, and get the state buffer address + va_encode -i #press one key to encode one frame + cat /sys/kernel/debug/dri/0/i915_context_status +>>>>>> +HW context ir +render ring: ffff880024c4f5c0: g 80KiB 01 01 0 0 0 uncached dirty (pinned x 0) (ggtt offset: 0c347000, size: 00014000) (ringbuffer, space: 128448, head: 0, tail: 384, last head: 352) +bsd ring: ffff88003f03d040: g 8KiB 01 01 0 0 0 uncached dirty (pinned x 0) (ggtt offset: 0c37c000, size: 00002000) (ringbuffer, space: 128640, head: 0, tail: 224, last head: 192) +blitter ring: +video enhancement ring: +<<<<<< + +Then: + igdbg -c "dumpstat 0x0c347000" + +>>>>>> +reg_state[CTX_LRI_HEADER_0]=0x1100101b +reg_state[CTX_CONTEXT_CONTROL]=0x2244 +reg_state[CTX_CONTEXT_CONTROL+1]=0xffff0008 +reg_state[CTX_RING_HEAD]=0x2034(mmio base+0x34) +reg_state[CTX_RING_HEAD+1]=0x178 +reg_state[CTX_RING_TAIL]=0x2030(mmio base+0x30) +reg_state[CTX_RING_TAIL+1]=0x178 +...... + +reg_state[CTX_RING_BUFFER_START+1] = 0xc35b000 (ring buffer gtt address) +reg_state[CTX_PDP0_LDW+1] = 0x30d4000 (page directory physical address) +<<<<<< + +From the dump, the ring buffer address of the context is 0xc35b000, and the ppgtt +physical address is 0x30d4000 + +4.9 dumppgtt + +On GEN8 and above, each context has a per-process gtt, thus don't need to put all +graphics memory mappings into global GTT + + dumppgtt <state bo> + +Example: +Firstly, same above, get the state buffer address of a context, and then + + igdbg -c "dumpppgtt 0x0c347000" + +>>>>>> +pde[0000]=0x05567003 (ppgtt offset range:0x00000000~0x00200000(0000M~0002M) + pte[000] = 0x418bb01b(page no.=268475, ppgtt addr 0x0(0000M+0000K)) + pte[001] = 0x418bc01b(page no.=268476, ppgtt addr 0x1000(0000M+0004K)) + pte[002] = 0x418bd01b(page no.=268477, ppgtt addr 0x2000(0000M+0008K)) + pte[003] = 0x418be01b(page no.=268478, ppgtt addr 0x3000(0000M+0012K)) +...... +pde[0001]=0x720b7003 (ppgtt offset range:0x00200000~0x00400000(0002M~0004M) + pte[000] = 0x274fa01b(page no.=161018, ppgtt addr 0x200000(0002M+0000K)) + pte[001] = 0x274fb01b(page no.=161019, ppgtt addr 0x201000(0002M+0004K)) + pte[002] = 0x275ec01b(page no.=161260, ppgtt addr 0x202000(0002M+0008K)) + pte[003] = 0x275ed01b(page no.=161261, ppgtt addr 0x203000(0002M+0012K)) +...... +<<<<<< + + +4.10 dumpring + +On GEN8 and above, each context has a logical ring. "dumpring" can print the instructions +in the ring and the chained batch buffers: + + dumppgtt <state bo> <head> <tail> + +Example: + +Firstly, same above, get the state buffer address of a context and the head/tail of the +ring, and then: + + igdbg -c "dumpring 0x0c347000 0 384" + +>>>>>> +0x0000:0x7a000004 (PIPE_CONTROL) + 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + |011| |11| |010| |000| |00000| |0000| |0000| |0000| |0100| +0x0004:0x00101001 (data) +0x0008:0x008cb080 (data) +0x000c:0x00000000 (data) +0x0010:0x00000000 (data) +0x0014:0x00000000 (data) + +0x0018:0x11000005 (MI_LOAD_REGISTER_IMM) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |100010| |000| |0000| |0000| |0000| |0000| |0101| +0x001c:0x0000e4f0 (data) +0x0020:0x81208120 (data) +0x0024:0x00007300 (data) +0x0028:0x08100810 (data) +0x002c:0x00007004 (data) +0x0030:0x00400040 (data) + +0x0034:0x00000000 (MI_NOOP) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |000000| |000| |0000| |0000| |0000| |0000| |0000| + +0x0038:0x7a000004 (PIPE_CONTROL) + 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + |011| |11| |010| |000| |00000| |0000| |0000| |0000| |0100| +0x003c:0x00101001 (data) +0x0040:0x008cb080 (data) +0x0044:0x00000000 (data) +0x0048:0x00000000 (data) +0x004c:0x00000000 (data) + +0x0050:0x18800001 (MI_BATCH_BUFFER_START)(BB in GGTT) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |110001| |000| |0000| |0000| |0000| |0000| |0001| +0x0054:0x08ece000 (data) +0x0058:0x00000000 (data) + +0x005c:0x00000000 (MI_NOOP) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |000000| |000| |0000| |0000| |0000| |0000| |0000| + +0x0060:0x10400002 (MI_STORE_DATA_IMM) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |100000| |100| |0000| |0000| |0000| |0000| |0010| +0x0064:0x008cd080 (data) +0x0068:0x00000000 (data) +0x006c:0xfffff5ba (data) + +0x0070:0x01000000 (MI_USER_INTERRUPT) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |000010| |000| |0000| |0000| |0000| |0000| |0000| + +0x0074:0x00000000 (MI_NOOP) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |000000| |000| |0000| |0000| |0000| |0000| |0000| + +0x0078:0x00000000 (MI_NOOP) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |000000| |000| |0000| |0000| |0000| |0000| |0000| + +0x007c:0x00000000 (MI_NOOP) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |000000| |000| |0000| |0000| |0000| |0000| |0000| + +0x0080:0x7a000004 (PIPE_CONTROL) + 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + |011| |11| |010| |000| |00000| |0000| |0000| |0000| |0100| +0x0084:0x01144c1c (data) +0x0088:0x008cb080 (data) +0x008c:0x00000000 (data) +0x0090:0x00000000 (data) +0x0094:0x00000000 (data) + +0x0098:0x10800001 (MI_STORE_DATA_INDEX) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |100001| |000| |0000| |0000| |0000| |0000| |0001| +0x009c:0x00000084 (data) +0x00a0:0xfffff5bb (data) + +0x00a4:0x00000000 (MI_NOOP) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |000000| |000| |0000| |0000| |0000| |0000| |0000| + +0x00a8:0x18800101 (MI_BATCH_BUFFER_START)(BB in PPGTT) + 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + |000| |110001| |000| |0000| |0000| |0001| |0000| |0001| +0x00ac:0x0032f000 (data) +0x00b0:0x00000000 (data) + + BB-L1: >>>>>>>>>>>>BB @ 0x0032f000 Begin>>>>>>>>>>>>> + BB-L1: 0x0000:0x7a000004 (PIPE_CONTROL) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |11| |010| |000| |00000| |0000| |0000| |0000| |0100| + BB-L1: 0x0004:0x011018bc (data) + BB-L1: 0x0008:0x00000000 (data) + BB-L1: 0x000c:0x00000000 (data) + BB-L1: 0x0010:0x00000000 (data) + BB-L1: 0x0014:0x00000000 (data) + + BB-L1: 0x0018:0x7a000004 (PIPE_CONTROL) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |11| |010| |000| |00000| |0000| |0000| |0000| |0100| + BB-L1: 0x001c:0x0110189c (data) + BB-L1: 0x0020:0x00000000 (data) + BB-L1: 0x0024:0x00000000 (data) + BB-L1: 0x0028:0x00000000 (data) + BB-L1: 0x002c:0x00000000 (data) + + BB-L1: 0x0030:0x7a000004 (PIPE_CONTROL) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |11| |010| |000| |00000| |0000| |0000| |0000| |0100| + BB-L1: 0x0034:0x00104080 (data) + BB-L1: 0x0038:0x00000068 (data) + BB-L1: 0x003c:0x00000000 (data) + BB-L1: 0x0040:0x00000001 (data) + BB-L1: 0x0044:0x00000000 (data) + + BB-L1: 0x0048:0x11000001 (MI_LOAD_REGISTER_IMM) + BB-L1: 31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00 + BB-L1: |000| |100010| |000| |0000| |0000| |0000| |0000| |0001| + BB-L1: 0x004c:0x00007034 (data) + BB-L1: 0x0050:0x80000040 (data) + + BB-L1: 0x0054:0x69040001 (PIPELINE_SELECT) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |01| |001| |000| |00100| |0000| |0000| |0000| |0001| + + BB-L1: 0x0058:0x6101000e (STATE_BASE_ADDRESS) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |00| |001| |000| |00001| |0000| |0000| |0000| |1110| + BB-L1: 0x005c:0x00000000 (data) + BB-L1: 0x0060:0x00000000 (data) + BB-L1: 0x0064:0x00000000 (data) + BB-L1: 0x0068:0x00334001 (data) + BB-L1: 0x006c:0x00000000 (data) + BB-L1: 0x0070:0x0004b001 (data) + BB-L1: 0x0074:0x00000000 (data) + BB-L1: 0x0078:0x00000000 (data) + BB-L1: 0x007c:0x00000000 (data) + BB-L1: 0x0080:0x0004d001 (data) + BB-L1: 0x0084:0x00000000 (data) + BB-L1: 0x0088:0x00000000 (data) + BB-L1: 0x008c:0x00002001 (data) + BB-L1: 0x0090:0x00000000 (data) + BB-L1: 0x0094:0x002c7001 (data) + + BB-L1: 0x0098:0x70000007 (MEDIA_VFE_STATE) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |10| |000| |000| |00000| |0000| |0000| |0000| |0111| + BB-L1: 0x009c:0x00000000 (data) + BB-L1: 0x00a0:0x00000000 (data) + BB-L1: 0x00a4:0x006f4000 (data) + BB-L1: 0x00a8:0x00000000 (data) + BB-L1: 0x00ac:0x00010004 (data) + BB-L1: 0x00b0:0xc00000ff (data) + BB-L1: 0x00b4:0xfff1f00f (data) + BB-L1: 0x00b8:0xefe1e01f (data) + + BB-L1: 0x00bc:0x70010002 (MEDIA_CURBE_LOAD) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |10| |000| |000| |00001| |0000| |0000| |0000| |0010| + BB-L1: 0x00c0:0x00000000 (data) + BB-L1: 0x00c4:0x00000080 (data) + BB-L1: 0x00c8:0x00001f80 (data) + + BB-L1: 0x00cc:0x70020002 (MEDIA_INTERFACE_DESCRIPTOR_LOAD) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |10| |000| |000| |00010| |0000| |0000| |0000| |0010| + BB-L1: 0x00d0:0x00000000 (data) + BB-L1: 0x00d4:0x00000040 (data) + BB-L1: 0x00d8:0x00001f40 (data) + + BB-L1: 0x00dc:0x71000005 (MEDIA_OBJECT) + BB-L1: 31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00 + BB-L1: |011| |10| |001| |000| |00000| |0000| |0000| |0000| |0101| + BB-L1: 0x00e0:0x00000000 (data) + BB-L1: 0x00e4:0x00000000 (data) + BB-L1: 0x00e8:0x00000000 (data) + BB-L1: 0x00ec:0x00000000 (data) + BB-L1: 0x00f0:0x00000000 (data) + BB-L1: 0x00f4:0x00000000 (data) +...... +<<<<<< + +The driver may use two engines (thus two rings) for one task, e.g. in above example, the +encoding uses "render ring" and "bsd ring", and driver may use the same batch buffer for +the two rings. If the dump is at frame boundary, the instructions in the batch buffer of +render ring may be overwritten by the instructions of bsd, thus they may be lost and can +not dump correctly. + + +5. Reference + +A. Linux graphics document: https://01.org/linuxgraphics/documentation +B. Intel video driver: http://cgit.freedesktop.org/vaapi/intel-driver/ +C. i915 kernel driver: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ @@ -0,0 +1,446 @@ +/* + * Copyright © 2014 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> +#include <errno.h> +#include <sys/time.h> + +#include "i915_reg.h" +#include "main.h" + +int process_regread(char *cmdhdr,unsigned int reg) +{ + uint32_t value=INREG(linear_mmio,reg); + + printf("read register 0x%x,value is 0x%08x\n",reg,value); + + print_bin_fmt(value,15); + + return 0; +} + +int process_regwrite(char *cmdhdr,unsigned int reg, unsigned int value) +{ + printf("Write register 0x%x with value 0x%x\n",reg,value); + OUTREG(linear_mmio,reg,value); + + return 0; +} + + +static uint64_t now_us() +{ + struct timeval tv; + if (gettimeofday(&tv, NULL)) + return 0; + return tv.tv_usec + tv.tv_sec*1000*1000; +} + +static int current_render(uint32_t delta_ms, uint32_t delta_us); +static int current_video(uint32_t delta_ms, uint32_t delta_us); + +#define I915_GEM_HWS_INDEX 0x20 + + +/* Linux kernle file i915_irq.c */ +#define GEN8_GT_IIR(which) (0x44308 + (0x10 * (which))) +#define GEN8_BCS_IRQ_SHIFT 16 +#define GEN8_RCS_IRQ_SHIFT 0 +#define GEN8_VCS2_IRQ_SHIFT 16 +#define GEN8_VCS1_IRQ_SHIFT 0 +#define GEN8_VECS_IRQ_SHIFT 0 +#define GEN8_OACS_IRQ_SHIFT 19 +int process_irq(char *cmdhdr,unsigned int seconds) +{ + uint64_t start = now_us(); + uint64_t expected_end = start + 1000 * 1000 * seconds; + unsigned int render_iir=0, video_iir=0; + uint32_t *render_seqno, *video_seqno, last_render_seqno=0, last_video_seqno=0; + uint32_t *blit_seqno, *video2_seqno, last_blit_seqno=0, last_video2_seqno=0; + uint32_t render_hws, video_hws, blit_hws, video2_hws; + + if (is_gen7) { + printf("IRQ sample tbd on GEN7\n"); + return 0; + } + render_hws = INREG(linear_mmio, 0x2080); + video_hws = INREG(linear_mmio, 0x12080); + blit_hws = INREG(linear_mmio, 0x1a080); + video2_hws = INREG(linear_mmio, 0x1c080); + + printf("Sample IRQ for %d seconds....It is not accurate, just rough view\n", seconds); + printf("Render HWS_PGA=0x%08x, Video HWS_PGA=0x%08x\n", render_hws, video_hws); + + render_seqno = (uint32_t *)((unsigned char *)linear_fb + render_hws) + I915_GEM_HWS_INDEX; + video_seqno = (uint32_t *)((unsigned char *)linear_fb + video_hws) + I915_GEM_HWS_INDEX; + blit_seqno = (uint32_t *)((unsigned char *)linear_fb + blit_hws) + I915_GEM_HWS_INDEX; + video2_seqno = (uint32_t *)((unsigned char *)linear_fb + video2_hws) + I915_GEM_HWS_INDEX; + + while (1) { + uint64_t now = now_us(); + int64_t test = now - expected_end; + + //printf("now=%u, expected end=%u, test = %d\n", now, expected_end, test); + if (test > 0) + break; + + uint64_t delta = now - start; + uint32_t delta_ms = (uint32_t)(delta/1000); + uint32_t delta_us = (uint32_t)(delta%1000); + + uint32_t tmp = INREG(linear_mmio, GEN8_GT_IIR(0)); + uint32_t tmp1 = INREG(linear_mmio, GEN8_GT_IIR(1)); + + while (render_iir != tmp) { + uint32_t rcs = tmp >> GEN8_RCS_IRQ_SHIFT; + uint32_t bcs = tmp >> GEN8_BCS_IRQ_SHIFT; + int has_irq; + + render_iir = tmp; + + has_irq = (rcs|bcs) & (GT_RENDER_USER_INTERRUPT|GT_CONTEXT_SWITCH_INTERRUPT); + if (has_irq) { + printf("T%d.%03d:iir=0x%08x\n", delta_ms, delta_us, tmp); + //print_bin_fmt(tmp, 8); + } else + break; + + if ((rcs & GT_RENDER_USER_INTERRUPT) + && (last_render_seqno != *render_seqno)) { + printf("\tRCS:GT_USER_INTERRUPT (seqno=0x%08x)\n", *render_seqno); + last_render_seqno = *render_seqno; + } + + if (rcs & GT_CONTEXT_SWITCH_INTERRUPT) { + printf("\tRCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x%08x)\n", *render_seqno); + if (verbose) + current_render(delta_ms, delta_us); + } + + if ((bcs & GT_RENDER_USER_INTERRUPT) + && (last_blit_seqno != *blit_seqno)) { + last_blit_seqno = *blit_seqno; + printf("\tBCS:GT_USER_INTERRUPT (seqno=0x%08x)\n", *blit_seqno); + } + + if (bcs & GT_CONTEXT_SWITCH_INTERRUPT) + printf("\tBCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x%08x)\n", *render_seqno); + + + break; + } + + while (video_iir != tmp1) { + /* video engine */ + uint32_t vcs = tmp1 >> GEN8_VCS1_IRQ_SHIFT; + uint32_t vcs2 = tmp1 >> GEN8_VCS2_IRQ_SHIFT; + int has_irq; + + video_iir = tmp1; + + has_irq = (vcs|vcs2) & (GT_RENDER_USER_INTERRUPT|GT_CONTEXT_SWITCH_INTERRUPT); + if (has_irq) { + printf("T%d.%03d:iir=0x%08x\n", delta_ms, delta_us, tmp1); + //print_bin_fmt(tmp, 8); + } else + break; + + if ((vcs & GT_RENDER_USER_INTERRUPT) + && (last_video_seqno != *video_seqno)) { + last_video_seqno = *video_seqno; + printf("\tVCS:GT_USER_INTERRUPT (seqno=0x%08x)\n", *video_seqno); + } + + if (vcs & GT_CONTEXT_SWITCH_INTERRUPT) { + printf("\tVCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x%08x)\n", *video_seqno); + if (verbose) + current_video(delta_ms, delta_us); + } + + if ((vcs2 & GT_RENDER_USER_INTERRUPT) + && (last_video2_seqno != *video2_seqno)) { + last_video2_seqno = *video2_seqno; + printf("\tVCS2:GT_USER_INTERRUPT (seqno=0x%08x)\n", *video2_seqno); + } + + if (vcs2 & GT_CONTEXT_SWITCH_INTERRUPT) + printf("\tVCS2:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x%08x)\n", *video_seqno); + + break; + } + } + + return 0; +} + + +static void print_estatus(uint32_t estatus) +{ + uint32_t tmp; + + printf("\tExeclist 0 Active = %d\n", (estatus>>18) & 0x1); + printf("\tExeclist 1 Active = %d\n", (estatus>>18) & 0x1); + + tmp = (estatus>>14) & 0x2; + printf("\tCurrent Active Element Status = %d", tmp); + if (tmp == 0) + printf("(No Active Element being executed)\n"); + else if (tmp == 1) + printf("(Element0 of current execlist being executed)\n"); + else if (tmp == 2) + printf("(Element1 of current execlist being executed)\n"); + + tmp = (estatus>>5) & 0x1ff; + printf("\tLast Context Switch Reason = 0x%x\n", tmp); + if (tmp & 1) + printf("\t\tIDLE to ACTIVE\n"); + if (tmp & 2) + printf("\t\tPreempted\n"); + if (tmp & 4) + printf("\t\tElement Switch: from element0 to element1 in the current execlist\n"); + if (tmp & 8) + printf("\t\tACTIVE to IDLE\n"); + if (tmp & 0x10) + printf("\t\tContext Complete:Element is completely processed\n"); + if (tmp & 0x1e0) + printf("\t\tWait on display\n"); + + printf("\tExeclist 0 Valid = %d\n", (estatus>>4) & 0x1); + printf("\tExeclist 1 Valid = %d\n", (estatus>>3) & 0x1); +} + +int process_estatus(char *cmdhdr,unsigned int seconds) +{ + uint64_t start = now_us(); + uint64_t expected_end = start + 1000 * 1000 * seconds; + uint32_t previous_r_eid = 0, previous_r_estatus = 0; + uint32_t previous_v_eid = 0, previous_v_estatus = 0; + + if (is_gen7) { + printf("Execlist is not supported on GEN7\n"); + return 0; + } + + printf("Sample ExecList Status for %d seconds....\n", seconds); + printf("It is not accurate, just for a rough view\n"); + + while (1) { + uint64_t now = now_us(); + int64_t test = now - expected_end; + + if (test > 0) + break; + + uint64_t delta = now - start; + uint32_t delta_ms = (uint32_t)(delta/1000); + uint32_t delta_us = (uint32_t)(delta%1000); + + uint32_t r_estatus = INREG(linear_mmio, 0x2234); + uint32_t r_eid = INREG(linear_mmio, 0x2238); + + uint32_t v_estatus = INREG(linear_mmio, 0x12234); + uint32_t v_eid = INREG(linear_mmio, 0x12238); + + if ((r_eid !=0) && (r_estatus != 0) + && ((previous_r_eid != r_eid) || (previous_r_estatus!= r_estatus))) { + printf("----------------------------------Render---------------------------------\n"); + printf("T%d.%03d:context id=0x%08x, status=0x%08x\n", + delta_ms, delta_us, r_eid, r_estatus); + + print_estatus(r_estatus); + + previous_r_eid = r_eid; + previous_r_estatus = r_estatus; + } + + if ((v_eid !=0) && (v_estatus != 0) + && ((previous_v_eid != v_eid) || (previous_v_estatus!= v_estatus))) { + + printf("----------------------------------Video---------------------------------\n"); + printf("T%d.%03d:context id=0x%08x, status=0x%08x\n", + delta_ms, delta_us, v_eid, v_estatus); + + print_estatus(v_estatus); + + previous_v_eid = v_eid; + previous_v_estatus = v_estatus; + } + } + + return 0; +} + +static void print_cstatus(uint32_t ldw, uint32_t udw) +{ + uint32_t tmp; + + printf("\tContext id=0x%08x\n", udw); + printf("\tContext status = 0x%08x\n", ldw); + + printf("\t\tWait display plane = 0x%04x\n", (ldw>>16) & 0xf); + printf("\t\tLite restore = %d\n", (ldw>>15)&1); + printf("\t\tWait display plane = 0x%03x\n", (ldw>>12) & 0x3); + printf("\t\tSemaphore wait mode = %d\n", (ldw>>11)&1); + + tmp = ldw & 0x1ff; + printf("\t\tLast Context Switch Reason = 0x%x\n", tmp); + if (tmp & 1) + printf("\t\t\tIDLE to ACTIVE\n"); + if (tmp & 2) + printf("\t\t\tPreempted\n"); + if (tmp & 4) + printf("\t\t\tElement Switch: from element0 to element1 in the current execlist\n"); + if (tmp & 8) + printf("\t\t\tACTIVE to IDLE\n"); + if (tmp & 0x10) + printf("\t\t\tContext Complete:Element is completely processed\n"); + if (tmp & 0x1e0) + printf("\t\t\tWait on display\n"); +} + +static struct context_status_t { + uint32_t udw; + uint32_t ldw; +} render[6], video[6]; +static int render_wp, video_wp, last_render_wp, last_video_wp; + +static int current_render(uint32_t delta_ms, uint32_t delta_us) +{ + uint32_t mmio_addr; + + render_wp = INREG(linear_mmio, 0x23a0) % 6; + if (render_wp == last_render_wp) + return 0; + + last_render_wp = render_wp; + + if (render_wp == 0) + render_wp = 5; + else + render_wp--; + + mmio_addr = 0x2370; + render[render_wp].ldw = INREG(linear_mmio, mmio_addr + render_wp*8); + render[render_wp].udw = INREG(linear_mmio, mmio_addr + render_wp*8 + 4); + + if (render[render_wp].udw != 0) { + printf("-----------------------------------------------\n"); + printf("T%d.%03d:Render Context Info(write ponter = %d)\n", delta_ms, delta_us, render_wp); + print_cstatus(render[render_wp].ldw, render[render_wp].udw); + printf("-----------------------------------------------\n"); + } + + return 0; +} + +static int current_video(uint32_t delta_ms, uint32_t delta_us) +{ + uint32_t mmio_addr; + + video_wp = INREG(linear_mmio, 0x123a0) % 6; + if (video_wp == last_video_wp) + return 0; + last_video_wp = video_wp; + + if (video_wp == 0) + video_wp = 5; + else + video_wp--; + + mmio_addr = 0x12370; + video[video_wp].ldw = INREG(linear_mmio, mmio_addr + video_wp*8); + video[video_wp].udw = INREG(linear_mmio, mmio_addr + video_wp*8 + 4); + if (video[video_wp].udw != 0) { + printf("-----------------------------------------------\n"); + printf("T%d.%03d:Video Context Info (write ponter = %d)\n", delta_ms, delta_us, video_wp); + print_cstatus(video[video_wp].ldw, video[video_wp].udw); + printf("-----------------------------------------------\n"); + } + + return 0; +} + +int process_cstatus(char *cmdhdr,unsigned int seconds) +{ + uint64_t start = now_us(); + uint64_t expected_end = start + 1000 * 1000 * seconds; + + if (is_gen7) { + printf("Execlist is not supported on GEN7\n"); + return 0; + } + + printf("Sample Context Status for %d seconds....\n", seconds); + printf("It is not accurate, just for rough view\n"); + + while (1) { + uint64_t now = now_us(); + int64_t test = now - expected_end; + + if (test > 0) + break; + + uint64_t delta = now - start; + uint32_t delta_ms = (uint32_t)(delta/1000); + uint32_t delta_us = (uint32_t)(delta%1000); + + current_render(delta_ms, delta_us); + current_video(delta_ms, delta_us); + } + + return 0; +} + +int process_msgread(char *cmdhdr,unsigned int port,unsigned int reg) +{ + unsigned int value = 0; + + //value = MSG_READ32(port, reg) + printf("read MSG port 0x%x, reg 0x%x, value=0x%08x\n",port, reg, value); + print_bin_fmt(value,15); + + return 0; +} + +int process_msgwrite(char *cmdhdr,unsigned int port, unsigned int reg, unsigned int new_value) +{ + unsigned int value = 0; + + //value = MSG_READ32(port, reg); + printf("Read MSG port 0x%x, reg 0x%x, value 0x%08x,try to write 0x%08x\n",port, reg, value, new_value); + + //MSG_WRITE32(port,reg,new_value); + + //value = MSG_READ32(port, reg); + printf("After write, MSG port 0x%x, reg 0x%x, new value=0x%08x\n",port, reg, value); + + return 0; +} @@ -0,0 +1,770 @@ +/* + * Copyright © 2014 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> +#include "main.h" + +/* from Linux kernel file: intel_lrc.c */ +#define CTX_LRI_HEADER_0 0x01 +#define CTX_CONTEXT_CONTROL 0x02 +#define CTX_RING_HEAD 0x04 +#define CTX_RING_TAIL 0x06 +#define CTX_RING_BUFFER_START 0x08 +#define CTX_RING_BUFFER_CONTROL 0x0a +#define CTX_BB_HEAD_U 0x0c +#define CTX_BB_HEAD_L 0x0e +#define CTX_BB_STATE 0x10 +#define CTX_SECOND_BB_HEAD_U 0x12 +#define CTX_SECOND_BB_HEAD_L 0x14 +#define CTX_SECOND_BB_STATE 0x16 +#define CTX_BB_PER_CTX_PTR 0x18 +#define CTX_RCS_INDIRECT_CTX 0x1a +#define CTX_RCS_INDIRECT_CTX_OFFSET 0x1c +#define CTX_LRI_HEADER_1 0x21 +#define CTX_CTX_TIMESTAMP 0x22 +#define CTX_PDP3_UDW 0x24 +#define CTX_PDP3_LDW 0x26 +#define CTX_PDP2_UDW 0x28 +#define CTX_PDP2_LDW 0x2a +#define CTX_PDP1_UDW 0x2c +#define CTX_PDP1_LDW 0x2e +#define CTX_PDP0_UDW 0x30 +#define CTX_PDP0_LDW 0x32 +#define CTX_LRI_HEADER_2 0x41 +#define CTX_R_PWR_CLK_STATE 0x42 +#define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 + + +static int process_dumpbb(int indent, unsigned int stat_addr, unsigned int bb_addr, int id); +static int process_dumpbb2(int indent, unsigned int stat_addr, unsigned int bb_addr, int id); + +static char *uint_to_char(uint32_t tmp) +{ + static char uint_char_buf[33]; + uint32_t i=0, n=tmp; + + memset(uint_char_buf,(int)'0',32); + uint_char_buf[32]='\0'; + do { + uint_char_buf[i++] = (n&1)+'0'; + n/=2; + } while(n); + + return uint_char_buf; +} + +#define printf_indent(indent, format, args...) \ + do { \ + int abc; \ + for (abc=0; abc<indent; abc++) \ + printf("\t"); \ + if (indent != 0) \ + printf("BB-L%d: ", indent); \ + printf(format, ##args); \ + } while (0) + +static int print_inst_mi(int indent, unsigned int stat_addr, uint32_t cmd_header, + int offset, uint32_t *cmd_ptr, int render_cs) +{ + int i, size; + unsigned int opcode = (cmd_header>>23) & 0x3f; + char *buf = uint_to_char(cmd_header); + int dump_bb = 0; + struct mi_inst { + uint32_t opcode; + uint32_t size; + const char *name; + } mi_insts[] = { + {0x00, 1, "MI_NOOP"}, + {0x01, 1, "MI_SET_PREDICATE"}, + {0x02, 1, "MI_USER_INTERRUPT"}, + {0x03, 1, "MI_WAIT_FOR_EVENT"}, + {0x05, 1, "MI_ARB_CHECK"}, + {0x06, 1, "MI_RS_CONTROL"}, + {0x07, 1, "MI_REPORT_HEAD"}, + {0x08, 1, "MI_ARB_ON_OFF"}, + {0x09, 1, "MI_URB_ATOMIC_ALLOC"}, + {0x0A, 1, "MI_BATCH_BUFFER_END"}, + {0x0B, 1, "MI_SUSPEND_FLUSH"}, + {0x0C, 1, "MI_PREDICATE"}, + {0x0D, 1, "MI_TOPOLOGY_FILTER"}, + {0x0E, 1, "MI_SET_APPID"}, + {0x0F, 1, "MI_RS_CONTEXT"}, + //2+ DWord + {0x10, 0, "Reserved"}, + {0x14, 0, "MI_DISPLAY_FLIP"}, + {0x15, 0, "Reserved"}, + {0x16, 0, "MI_SEMAPHORE_MBOX"}, + {0x17, 0, "Reserved"}, + {0x18, 0, "MI_SET_CONTEXT"}, + {0x19, 0, "MI_URB_CLEAR"}, + {0x1A, 0, "MI_MATH"}, + {0x1B, 0, "MI_SEMAPHORE_SIGNAL"}, + {0x1C, 0, "MI_SEMAPHORE_WAIT"}, + //Store "Data" + {0x20, 0, "MI_STORE_DATA_IMM"}, + {0x21, 0, "MI_STORE_DATA_INDEX"}, + {0x22, 0, "MI_LOAD_REGISTER_IMM"}, + {0x23, 0, "MI_UPDATE_GTT"}, + {0x24, 0, "MI_STORE_REGISTER_MEM"}, + {0x26, 0, "MI_FLUSH_DW"}, + {0x27, 0, "MI_CLFLUSH"}, + {0x28, 0, "MI_REPORT_PERF_COUNT"}, + {0x29, 0, "MI_LOAD_REGISTER_MEM"}, + {0x2A, 0, "MI_LOAD_REGISTER_REG"}, + {0x2B, 0, "MI_RS_STORE_DATA_IMM"}, + {0x2C, 0, "MI_LOAD_URB_MEM"}, + {0x2D, 0, "MI_STORE_URB_MEM"}, + {0x2E, 0, "MI_MEM_TO_MEM"}, + {0x2F, 0, "MI_ATOMIC"}, + {0x30, 0, "Reserved"}, + //Ring/batch buffer + {0x31, 3, "MI_BATCH_BUFFER_START"}, + {0x36, 1, "MI_CONDITIONAL_BATCH_BUFFER_END"}, + {0xff, 0, "TBD"}, + }, *mi_current = NULL; + + int mi_size = sizeof(mi_insts) / sizeof(mi_insts[0]); + + for (i=0; i<mi_size; i++) { + if (opcode == mi_insts[i].opcode) + break; + } + if (i==mi_size) + mi_current = &mi_insts[mi_size -1]; + else + mi_current = &mi_insts[i]; + + printf_indent(indent,"0x%04x:0x%08x (%s)", offset, cmd_header, mi_current->name); + if (strcmp(mi_current->name, "MI_BATCH_BUFFER_START") == 0) { + if ((cmd_header & 0x100) != 0) { + dump_bb = 1; + printf("(BB in PPGTT)\n"); + } else { + /* the instructions in GGTT is the initialization code filled in Kernel */ + dump_bb = 0; + printf("(BB in GGTT)\n"); + } + } else + printf("\n"); + + printf_indent(indent,"\t"); + printf("31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00\n"); + printf_indent(indent,"\t"); + printf("|%c%c%c| ",buf[31],buf[30],buf[29]); + printf("|%c%c%c%c%c%c| ",buf[28],buf[27],buf[26],buf[25],buf[24],buf[23]); + printf("|%c%c%c| ",buf[22],buf[21],buf[20]); +#define print_four_bits(from) printf("|%c%c%c%c| ",buf[from],buf[from-1],buf[from-2],buf[from-3]) + for (i=19;i>=3;i=i-4) + print_four_bits(i); + + printf("\n"); + + //if ((opcode == 0x20) ||(opcode == 0x21)||(opcode == 0x22)) + if (mi_current->size == 0) + size = (cmd_header & 0x3f) + 2; + else if (opcode == 0x0a) /* MI_BATCH_BUFFER_END */ + size = 0; + else + size = mi_current->size; + + for (i=1; i<size; i++) + printf_indent(indent,"0x%04x:0x%08x (data)\n", offset+i*4, *(cmd_ptr+i)); + + printf("\n"); + + if (dump_bb == 0) + return size; + + uint32_t bb_addr = *(cmd_ptr+1); + + indent++; + printf_indent(indent,">>>>>>>>>>>>BB @ 0x%08x Begin>>>>>>>>>>>>>\n", bb_addr); + if (dump_bb == 1) { + if (render_cs) + process_dumpbb(indent, stat_addr, bb_addr, RCS); + else + process_dumpbb(indent, stat_addr, bb_addr, VCS); + } else if (dump_bb == 2) { + if (render_cs) + process_dumpbb2(indent, stat_addr, bb_addr, RCS); + else + process_dumpbb2(indent, stat_addr, bb_addr, VCS); + } + printf_indent(indent,"<<<<<<<<<<<BB @ 0x%08x End<<<<<<<<<<<<<<<<<\n\n", bb_addr); + + return size; +} + + +static int print_inst_rendercs(int indent, uint32_t cmd_header, int offset, uint32_t *cmd_ptr) +{ + int i, size; + unsigned int opcode_bit28_27 = (cmd_header>>27) & 0x3; + unsigned int opcode_bit26_24 = (cmd_header>>24) & 0x7; + unsigned int opcode_bit23_16 = (cmd_header>>16) & 0xff; + char *buf = uint_to_char(cmd_header); + struct render_inst { + uint32_t opcode_bit28_27; + uint32_t opcode_bit26_24; + uint32_t opcode_bit23_16; + uint32_t size; + const char *name; + } render_insts[] = { + { 0, 1, 0x1, 0, "STATE_BASE_ADDRESS" }, + { 1, 1, 0x4, 1, "PIPELINE_SELECT"}, + + { 2, 0, 0x0, 0, "MEDIA_VFE_STATE" }, + { 2, 0, 0x1, 0, "MEDIA_CURBE_LOAD" }, + { 2, 0, 0x2, 0, "MEDIA_INTERFACE_DESCRIPTOR_LOAD" }, + { 2, 0, 0x3, 0, "CMD_MEDIA_GATEWAY_STATE" }, + { 2, 0, 0x4, 0, "MEDIA_STATE_FLUSH" }, + { 2, 1, 0x0, 0, "MEDIA_OBJECT" }, + { 2, 1, 0x2, 0, "MEDIA_OBJECT_PTR" }, + { 2, 1, 0x3, 0, "MEDIA_OBJECT_WALKER" }, + + { 3, 0, 0x04, 0, "3DSTATE_CLEAR_PARAMS" }, + { 3, 0, 0x05, 0, "3DSTATE_DEPTH_BUFFER" }, + { 3, 0, 0x06, 0, "3DSTATE_STENCIL_BUFFER" }, + { 3, 0, 0x07, 0, "3DSTATE_HIER_DEPTH_BUFFER" }, + { 3, 0, 0x08, 0, "3DSTATE_VERTEX_BUFFERS" }, + { 3, 0, 0x09, 0, "3DSTATE_VERTEX_ELEMENTS" }, + { 3, 0, 0x0A, 0, "3DSTATE_INDEX_BUFFER" }, + { 3, 0, 0x0B, 0, "3DSTATE_VF_STATISTICS" }, + { 3, 0, 0x0D, 0, "3DSTATE_VIEWPORT_STATE_POINTERS" }, + { 3, 0, 0x0E, 0, "3DSTATE_CC_STATE_POINTERS" }, + { 3, 0, 0x10, 0, "3DSTATE_VS" }, + { 3, 0, 0x11, 0, "3DSTATE_GS" }, + { 3, 0, 0x12, 0, "3DSTATE_CLIP" }, + { 3, 0, 0x13, 0, "3DSTATE_SF" }, + { 3, 0, 0x14, 0, "3DSTATE_WM" }, + { 3, 0, 0x15, 0, "3DSTATE_CONSTANT_VS" }, + { 3, 0, 0x16, 0, "3DSTATE_CONSTANT_GS" }, + { 3, 0, 0x17, 0, "3DSTATE_CONSTANT_PS" }, + { 3, 0, 0x18, 0, "3DSTATE_SAMPLE_MASK" }, + { 3, 0, 0x19, 0, "3DSTATE_CONSTANT_HS" }, + { 3, 0, 0x1A, 0, "3DSTATE_CONSTANT_DS" }, + { 3, 0, 0x1B, 0, "3DSTATE_HS" }, + { 3, 0, 0x1C, 0, "3DSTATE_TE" }, + { 3, 0, 0x1D, 0, "3DSTATE_DS" }, + { 3, 0, 0x1E, 0, "3DSTATE_STREAMOUT" }, + { 3, 0, 0x1F, 0, "3DSTATE_SBE" }, + { 3, 0, 0x20, 0, "3DSTATE_PS" }, + { 3, 0, 0x21, 0, "3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP" }, + { 3, 0, 0x23, 0, "3DSTATE_VIEWPORT_STATE_POINTERS_CC" }, + { 3, 0, 0x24, 0, "3DSTATE_BLEND_STATE_POINTERS" }, + { 3, 0, 0x25, 0, "3DSTATE_DEPTH_STENCIL_STATE_POINTERS" }, + { 3, 0, 0x26, 0, "3DSTATE_BINDING_TABLE_POINTERS_VS" }, + { 3, 0, 0x27, 0, "3DSTATE_BINDING_TABLE_POINTERS_HS" }, + { 3, 0, 0x28, 0, "3DSTATE_BINDING_TABLE_POINTERS_DS" }, + { 3, 0, 0x29, 0, "3DSTATE_BINDING_TABLE_POINTERS_GS" }, + { 3, 0, 0x2A, 0, "3DSTATE_BINDING_TABLE_POINTERS_PS" }, + { 3, 0, 0x2B, 0, "3DSTATE_SAMPLER_STATE_POINTERS_VS" }, + { 3, 0, 0x2C, 0, "3DSTATE_SAMPLER_STATE_POINTERS_HS" }, + { 3, 0, 0x2D, 0, "3DSTATE_SAMPLER_STATE_POINTERS_DS" }, + { 3, 0, 0x2E, 0, "3DSTATE_SAMPLER_STATE_POINTERS_GS" }, + { 3, 0, 0x30, 0, "3DSTATE_URB_VS" }, + { 3, 0, 0x31, 0, "3DSTATE_URB_HS" }, + { 3, 0, 0x32, 0, "3DSTATE_URB_DS" }, + { 3, 0, 0x33, 0, "3DSTATE_URB_GS" }, + { 3, 0, 0x34, 0, "3DSTATE_GATHER_CONSTANT_VS" }, + { 3, 0, 0x35, 0, "3DSTATE_GATHER_CONSTANT_GS" }, + { 3, 0, 0x36, 0, "3DSTATE_GATHER_CONSTANT_HS" }, + { 3, 0, 0x37, 0, "3DSTATE_GATHER_CONSTANT_DS" }, + { 3, 0, 0x38, 0, "3DSTATE_GATHER_CONSTANT_PS" }, + { 3, 0, 0x39, 0, "3DSTATE_DX9_CONSTANTF_VS" }, + { 3, 0, 0x3A, 0, "3DSTATE_DX9_CONSTANTF_PS" }, + { 3, 0, 0x3B, 0, "3DSTATE_DX9_CONSTANTI_VS" }, + { 3, 0, 0x3C, 0, "3DSTATE_DX9_CONSTANTI_PS" }, + { 3, 0, 0x3D, 0, "3DSTATE_DX9_CONSTANTB_VS" }, + { 3, 0, 0x3E, 0, "3DSTATE_DX9_CONSTANTB_PS" }, + { 3, 0, 0x3F, 0, "3DSTATE_DX9_LOCAL_VALID_VS" }, + { 3, 0, 0x40, 0, "3DSTATE_DX9_LOCAL_VALID_PS" }, + { 3, 0, 0x41, 0, "3DSTATE_DX9_GENERATE_ACTIVE_VS" }, + { 3, 0, 0x42, 0, "3DSTATE_DX9_GENERATE_ACTIVE_PS" }, + { 3, 0, 0x43, 0, "3DSTATE_BINDING_TABLE_EDIT_VS" }, + { 3, 0, 0x44, 0, "3DSTATE_BINDING_TABLE_EDIT_GS" }, + { 3, 0, 0x45, 0, "3DSTATE_BINDING_TABLE_EDIT_HS" }, + { 3, 0, 0x46, 0, "3DSTATE_BINDING_TABLE_EDIT_DS" }, + { 3, 0, 0x47, 0, "3DSTATE_BINDING_TABLE_EDIT_PS" }, + { 3, 0, 0x48, 0, "3DSTATE_VF_HASHING" }, + { 3, 0, 0x49, 0, "3DSTATE_VF_INSTANCING" }, + { 3, 0, 0x4A, 0, "3DSTATE_VF_SGVS" }, + { 3, 0, 0x4B, 0, "3DSTATE_VF_TOPOLOGY" }, + { 3, 0, 0x4C, 0, "3DSTATE_WM_CHROMA_KEY" }, + { 3, 0, 0x4D, 0, "3DSTATE_PS_BLEND" }, + { 3, 0, 0x4E, 0, "3DSTATE_WM_DEPTH_STENCIL" }, + { 3, 0, 0x4F, 0, "3DSTATE_PS_EXTRA" }, + { 3, 0, 0x50, 0, "3DSTATE_RASTER" }, + { 3, 0, 0x51, 0, "3DSTATE_SBE_SWIZ" }, + { 3, 0, 0x52, 0, "3DSTATE_WM_HZ_OP" }, + { 3, 0, 0x53, 0, "3DSTATE_INT" }, + { 3, 1, 0x00, 0, "3DSTATE_DRAWING_RECTANGLE" }, + { 3, 1, 0x02, 0, "3DSTATE_SAMPLER_PALETTE_LOAD0" }, + { 3, 1, 0x04, 0, "3DSTATE_CHROMA_KEY" }, + { 3, 1, 0x06, 0, "3DSTATE_POLY_STIPPLE_OFFSET" }, + { 3, 1, 0x07, 0, "3DSTATE_POLY_STIPPLE_PATTERN" }, + { 3, 1, 0x08, 0, "3DSTATE_LINE_STIPPLE" }, + { 3, 1, 0x0A, 0, "3DSTATE_AA_LINE_PARAMS" }, + { 3, 1, 0x0B, 0, "3DSTATE_GS_SVB_INDEX" }, + { 3, 1, 0x0C, 0, "3DSTATE_SAMPLER_PALETTE_LOAD1" }, + { 3, 1, 0x0D, 0, "3DSTATE_MULTISAMPLE" }, + { 3, 1, 0x0E, 0, "3DSTATE_STENCIL_BUFFER" }, + { 3, 1, 0x0F, 0, "3DSTATE_HIER_DEPTH_BUFFER" }, + { 3, 1, 0x10, 0, "3DSTATE_CLEAR_PARAMS" }, + { 3, 1, 0x11, 0, "3DSTATE_MONOFILTER_SIZE" }, + { 3, 1, 0x12, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_VS" }, + { 3, 1, 0x13, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_HS" }, + { 3, 1, 0x14, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_DS" }, + { 3, 1, 0x15, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_GS" }, + { 3, 1, 0x16, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_PS" }, + { 3, 1, 0x17, 0, "3DSTATE_SO_DECL_LIST" }, + { 3, 1, 0x18, 0, "3DSTATE_SO_BUFFER" }, + { 3, 1, 0x19, 0, "3DSTATE_BINDING_TABLE_POOL_ALLOC" }, + { 3, 1, 0x1A, 0, "3DSTATE_GATHER_POOL_ALLOC" }, + { 3, 1, 0x1B, 0, "3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC" }, + { 3, 1, 0x1C, 0, "3DSTATE_SAMPLE_PATTERN" }, + { 3, 1, 0x1D, 0, "3DSTATE_URB_CLEAR" }, + { 3, 2, 0x00, 0, "PIPE_CONTROL" }, + { 3, 3, 0x00, 0, "3DPRIMITIVE" }, + { 3, 7, 0xff, 0, "TBD"}, + }, *render_current = NULL; + + int render_size = sizeof(render_insts) / sizeof(render_insts[0]); + + for (i=0; i<render_size; i++) { + if ((opcode_bit28_27 == render_insts[i].opcode_bit28_27) + && (opcode_bit26_24 == render_insts[i].opcode_bit26_24) + && (opcode_bit23_16 == render_insts[i].opcode_bit23_16)) + break; + } + if (i==render_size) + render_current = &render_insts[render_size -1]; + else + render_current = &render_insts[i]; + + printf_indent(indent,"0x%04x:0x%08x (%s)\n", offset, cmd_header, render_current->name); + + printf_indent(indent,"\t"); + printf("31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00\n"); + printf_indent(indent,"\t"); + printf("|%c%c%c| ",buf[31],buf[30],buf[29]); + printf("|%c%c| ",buf[28],buf[27]); + printf("|%c%c%c| ", buf[26],buf[25],buf[24]); + printf("|%c%c%c| ", buf[23],buf[22],buf[21]); + printf("|%c%c%c%c%c| ", buf[20],buf[19],buf[18],buf[17],buf[16]); +#define print_four_bits(from) printf("|%c%c%c%c| ",buf[from],buf[from-1],buf[from-2],buf[from-3]) + for (i=15;i>=3;i=i-4) + print_four_bits(i); + + printf("\n"); + /* + if ((strcmp(render_current->name, "MFX_PIPE_MODE_SELECT") == 0) + || (strcmp(render_current->name, "MFX_SURFACE_STATE") == 0) + || (strcmp(render_current->name, "MFX_PIPE_BUF_ADDR_STATE") == 0)) + */ + if (render_current->size == 0) + size = (cmd_header & 0xfff) + 2; + else + size = render_current->size; + for (i=1; i<size; i++) + printf_indent(indent,"0x%04x:0x%08x (data)\n", offset+i*4, *(cmd_ptr+i)); + + printf("\n"); + + return size; +} + + +static int print_inst_mfxcs(int indent, uint32_t cmd_header, int offset, uint32_t *cmd_ptr) +{ + int i, size; + unsigned int opcode_bit28_27 = (cmd_header>>27) & 0x3; + unsigned int opcode_bit26_24 = (cmd_header>>24) & 0x7; + unsigned int opcode_bit23_21 = (cmd_header>>21) & 0x7; + unsigned int opcode_bit20_16 = (cmd_header>>16) & 0x1f; + char *buf = uint_to_char(cmd_header); + struct mfx_inst { + uint32_t opcode_bit28_27; + uint32_t opcode_bit26_24; + uint32_t opcode_bit23_21; + uint32_t opcode_bit20_16; + uint32_t size; + const char *name; + } mfx_insts[] = { + {1, 0, 0, 0, 1, "MFX_WAIT"}, + {2, 0, 0, 0, 0, "MFX_PIPE_MODE_SELECT"}, + {2, 0, 0, 1, 0, "MFX_SURFACE_STATE"}, + {2, 0, 0, 2, 0, "MFX_PIPE_BUF_ADDR_STATE"}, + {2, 0, 0, 3, 0, "MFX_IND_OBJ_BASE_ADDR_STATE"}, + {2, 0, 0, 4, 0, "MFX_BSP_BUF_BASE_ADDR_STATE"}, + {2, 0, 0, 5, 0, "MFX_AES_STATE"}, + {2, 0, 0, 6, 0, "MFX_STATE_POINTER"}, + {2, 0, 0, 7, 0, "MFX_QM_STATE"}, + {2, 0, 0, 8, 0, "MFX_FQM_STATE"}, + {2, 0, 1, 9, 0, "MFD_IT_OBJECT"}, + {2, 0, 2, 8, 0, "MFX_INSERT_OBJECT"}, + {2, 1, 0, 0, 0, "MFX_AVC_IMG_STATE"}, + {2, 1, 0, 1, 0, "MFX_AVC_QM_STATE"}, + {2, 1, 0, 2, 0, "MFX_AVC_DIRECTMODE_STATE"}, + {2, 1, 0, 3, 0, "MFX_AVC_SLICE_STATE"}, + {2, 1, 0, 4, 0, "MFX_AVC_REF_IDX_STATE"}, + {2, 1, 0, 5, 0, "MFX_AVC_WEIGHTOFFSET_STATE"}, + {2, 1, 1, 5, 0, "MFD_AVC_PICID_STATE"}, + {2, 1, 1, 8, 0, "MFD_AVC_BSD_OBJECT"}, + {2, 1, 2, 2, 0, "MFC_AVC_FQM_STATE"}, + {2, 1, 2, 8, 0, "MFC_AVC_PAK_INSERT_OBJECT"}, + {2, 1, 2, 9, 0, "MFC_AVC_PAK_OBJECT"}, + {2, 2, 0, 0, 0, "MFX_VC1_PIC_STATE"}, + {2, 2, 0, 1, 0, "MFX_VC1_PRED_PIPE_STATE"}, + {2, 2, 0, 2, 0, "MFX_VC1_DIRECTMODE_STATE"}, + {2, 2, 1, 0, 0, "MFD_VC1_SHORT_PIC_STATE"}, + {2, 2, 1, 1, 0, "MFD_VC1_LONG_PIC_STATE"}, + {2, 2, 1, 8, 0, "MFD_VC1_BSD_OBJECT"}, + {2, 3, 0, 0, 0, "MFX_MPEG2_PIC_STATE"}, + {2, 3, 0, 1, 0, "MFX_MPEG2_QM_STATE"}, + {2, 3, 1, 8, 0, "MFD_MPEG2_BSD_OBJECT"}, + {2, 3, 2, 3, 0, "MFC_MPEG2_PAK_OBJECT"}, + {2, 3, 2, 9, 0, "MFC_MPEG2_SLICEGROUP_STATE"}, + {2, 4, 0, 0, 0, "MFX_VP8_PIC_STATE"}, + {2, 4, 1, 8, 0, "MFD_VP8_BSD_OBJECT"}, + {2, 4, 2, 1, 0, "MFX_VP8_ENCODER_CFG"}, + {2, 4, 2, 3, 0, "MFX_VP8_BSP_BUF_BASE_ADDR_STATE"}, + {2, 4, 2, 9, 0, "MFX_VP8_PAK_OBJECT"}, + {2, 7, 0, 0, 0, "MFX_JPEG_PIC_STATE"}, + {2, 7, 0, 2, 0, "MFX_JPEG_HUFF_TABLE_STATE"}, + {2, 7, 0, 0, 0, "MFX_JPEG_PIC_STATE"}, + {2, 7, 0, 2, 0, "MFX_JPEG_HUFF_TABLE_STATE"}, + {2, 7, 1, 8, 0, "MFD_JPEG_BSD_OBJECT"}, + {2, 7, 2, 9, 0, "MFC_JPEG_SCAN_OBJECT"}, + {2, 7, 2, 3, 0, "MFC_JPEG_HUFF_TABLE_STATE"}, + {3, 4, 0, 0, 0, "VEB_SURFACE_STATE"}, + {3, 4, 0, 2, 0, "VEB_STATE"}, + {3, 4, 0, 3, 0, "VEB_DNDI_IECP_STATE"}, + {3, 2, 7, 0, 0, "HCP_PIPE_MODE_SELECT"}, + {3, 2, 7, 1, 0, "HCP_SURFACE_STATE"}, + + {2, 7, 7, 0x1f, 0, "TBD"}, + }, *mfx_current = NULL; + + int mfx_size = sizeof(mfx_insts) / sizeof(mfx_insts[0]); + + for (i=0; i<mfx_size; i++) { + if ((opcode_bit28_27 == mfx_insts[i].opcode_bit28_27) + && (opcode_bit26_24 == mfx_insts[i].opcode_bit26_24) + && (opcode_bit23_21 == mfx_insts[i].opcode_bit23_21) + && (opcode_bit20_16 == mfx_insts[i].opcode_bit20_16)) + break; + } + if (i==mfx_size) + mfx_current = &mfx_insts[mfx_size -1]; + else + mfx_current = &mfx_insts[i]; + + printf_indent(indent,"0x%04x:0x%08x (%s)\n", offset, cmd_header, mfx_current->name); + + printf_indent(indent,"\t"); + printf("31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00\n"); + printf_indent(indent,"\t"); + printf("|%c%c%c| ",buf[31],buf[30],buf[29]); + printf("|%c%c| ",buf[28],buf[27]); + printf("|%c%c%c| ", buf[26],buf[25],buf[24]); + printf("|%c%c%c| ", buf[23],buf[22],buf[21]); + printf("|%c%c%c%c%c| ", buf[20],buf[19],buf[18],buf[17],buf[16]); +#define print_four_bits(from) printf("|%c%c%c%c| ",buf[from],buf[from-1],buf[from-2],buf[from-3]) + for (i=15;i>=3;i=i-4) + print_four_bits(i); + + printf("\n"); + if (mfx_current->size == 0) + size = (cmd_header & 0xfff) + 2; + else + size = mfx_current->size; + for (i=1; i<size; i++) + printf_indent(indent,"0x%04x:0x%08x (data)\n", offset+i*4, *(cmd_ptr+i)); + + printf("\n"); + + return size; +} + +int process_dumpring(char *cmdhdr,unsigned int stat_addr, unsigned int head, unsigned int tail) +{ + uint32_t *ring_ptr, i, dw_count; + uint32_t ring_addr; + /* render CS has PIPE_CONTROL, use it to differentiate render and video... */ + int render_cs = 0; + + if (is_gen7) { + printf("Execlist/Logica ring is not supported on GEN7\n"); + return 0; + } + CHECK_STRICT_DEVMEM; + + if (tail <= head) { + printf("Invalid tail=%d/head=%d\n", tail, head); + return 0; + } + ring_addr = get_ring(stat_addr); + + dw_count = (tail - head)/4; + printf("Ring buffer address 0x%08x(%dM+%dK), head =%d(0x%x), tail=%d(0x%x), %d instructions \n", + ring_addr, ring_addr>>20, (ring_addr>>10) & 0x3ff, + head, head, tail, tail, dw_count); + + printf("************************************************************************\n"); + + ring_ptr = (uint32_t *)((unsigned char *)linear_fb + ring_addr + head); + for (i=0; i<dw_count;) { + uint32_t cmd_header = *ring_ptr; + uint32_t type = (cmd_header>>29)&0x7; + uint32_t dw_cmdpkg = 1; + + if (type == 0) + dw_cmdpkg = print_inst_mi(0, stat_addr, cmd_header, head+i*4, ring_ptr, render_cs); + else if (type == 3) { + render_cs = 1; + dw_cmdpkg = print_inst_rendercs(0, cmd_header, head+i*4, ring_ptr); + } else + printf("Unknow instructions 0x%08x\n", cmd_header); + + ring_ptr += dw_cmdpkg; + + i = i + dw_cmdpkg; + } + + return 0; +} + +#define BB_MAX_PAGE 10 +#define BB_MAX_CMDS (BB_MAX_PAGE*4096/4) +static int dumpbb_help(int indent, unsigned int stat_addr, uint32_t *bb_ptr, int id) +{ + uint32_t cmd_header, type; + uint32_t dw_count, dw_cmdpkg=0; + + /* Parse all BB commands */ + dw_count = 0; + while (1) { + cmd_header = *bb_ptr; + type = (cmd_header>>29)&0x7; + + if (type == 0) + dw_cmdpkg = print_inst_mi(indent, stat_addr, cmd_header, dw_count*4, bb_ptr, id == RCS); + else if (type == 3) { + if (id == RCS) + dw_cmdpkg = print_inst_rendercs(indent, cmd_header, dw_count*4, bb_ptr); + else if (id == VCS) + dw_cmdpkg = print_inst_mfxcs(indent, cmd_header, dw_count*4, bb_ptr); + } else { + printf_indent(indent,"Unknow instructions 0x%08x\n", cmd_header); + print_bin_fmt(cmd_header, 8); + + dw_cmdpkg = 1; + } + + if (dw_cmdpkg == 0) /*MI_BATCH_BUFFER_END*/ + break; + + dw_count = dw_count + dw_cmdpkg; + bb_ptr += dw_cmdpkg; + + if (dw_count >= BB_MAX_CMDS) { + printf_indent(indent,"The batch buffer is still not ended, bugs? Break the loop\n"); + break; + } + } + + return 0; +} + +static int process_dumpbb2(int indent, unsigned int stat_addr, unsigned int bb_addr, int id) +{ + uint32_t *bb_ptr; + + /* + printf("Render ring batch buffer address in GGTT 0x%08x(%dM+%dK, offset in page %d)\n", + bb_addr, bb_addr>>20, (bb_addr>>10) & 0x3ff, bb_addr & 0xfff); + */ + + /* Parse all BB commands */ + bb_ptr = (uint32_t *)((unsigned char *)linear_fb + bb_addr); + dumpbb_help(indent, stat_addr, bb_ptr, id); + + return 0; +} + +static int process_dumpbb(int indent, unsigned int stat_addr, unsigned int bb_addr, int id) +{ + uint32_t bb_addr_aligned, bb_addr_offset; + uint32_t i, *bb_ptr; + unsigned char *ten_pages; + + uint32_t ppgtt_addr = get_ppgtt(stat_addr); + + bb_addr_aligned = bb_addr & 0xfffff000;; + bb_addr_offset = bb_addr & 0xfff; + + /* + printf("Render ring batch buffer address in PPGTT 0x%08x(%dM+%dK, offset in page %d)\n", + bb_addr, bb_addr>>20, (bb_addr>>10) & 0x3ff, bb_addr_offset); + printf("Read ten pages from PPGTT mapping (physical address 0x%08x)\n", ppgtt_addr); + */ + /* Read maximum pages to avoid one command package + * wrapping on two pages. It is for simplicity + */ + ten_pages = malloc(BB_MAX_PAGE * 4096); + for (i=0; i<BB_MAX_PAGE; i++) + get_ppgtt_page(ppgtt_addr, bb_addr_aligned + i * 4096, ten_pages + i * 4096); + + /* Parse all BB commands */ + bb_ptr = (uint32_t *)(ten_pages + bb_addr_offset); + dumpbb_help(indent, stat_addr, bb_ptr, id); + + return 0; +} + +uint32_t get_ppgtt(unsigned int stat_addr) +{ + uint32_t *reg_state = (uint32_t *)(linear_fb+stat_addr + 4096); + + /* + printf("Stat buffer: reg_state[CTX_PDP0_LDW+1] = 0x%x (page directory physical address)\n", + reg_state[CTX_PDP0_LDW+1]); + */ + return reg_state[CTX_PDP0_LDW+1]; +} + +uint32_t get_ring(unsigned int stat_addr) +{ + uint32_t *reg_state = (uint32_t *)(linear_fb+stat_addr + 4096); + + /* + printf("Stat buffer: reg_state[CTX_RING_BUFFER_START+1] = 0x%x (ring address)\n", + reg_state[CTX_RING_BUFFER_START+1]); + */ + return reg_state[CTX_RING_BUFFER_START+1]; +} + + +int process_dumpstat(char *cmdhdr,unsigned int stat_addr) +{ + /* The second page of the context object contains some fields which must + * be set up prior to the first execution. + */ + uint32_t *reg_state = (uint32_t *)(linear_fb+stat_addr + 4096); + int id = RCS; /* ignore it currently */ + + if (is_gen7) { + printf("Execlist/logical ring is not supported on GEN7\n"); + return 0; + } + CHECK_STRICT_DEVMEM; + + /* A context is actually a big batch buffer with several MI_LOAD_REGISTER_IMM + * commands followed by (reg, value) pairs. The values we are setting here are + * only for the first context restore: on a subsequent save, the GPU will + * recreate this batchbuffer with new values (including all the missing + * MI_LOAD_REGISTER_IMM commands that we are not initializing here). */ + printf("reg_state[CTX_LRI_HEADER_0]=0x%x\n", reg_state[CTX_LRI_HEADER_0]); + printf("reg_state[CTX_CONTEXT_CONTROL]=0x%x\n", reg_state[CTX_CONTEXT_CONTROL]); + printf("reg_state[CTX_CONTEXT_CONTROL+1]=0x%x\n", reg_state[CTX_CONTEXT_CONTROL+1]); + printf("reg_state[CTX_RING_HEAD]=0x%x(mmio base+0x34)\n", reg_state[CTX_RING_HEAD]); + printf("reg_state[CTX_RING_HEAD+1]=0x%x\n", reg_state[CTX_RING_HEAD+1]); + printf("reg_state[CTX_RING_TAIL]=0x%x(mmio base+0x30)\n", reg_state[CTX_RING_TAIL]); + printf("reg_state[CTX_RING_TAIL+1]=0x%x\n", reg_state[CTX_RING_TAIL+1]); + /* Ring buffer start address is not known until the buffer is pinned. + * It is written to the context image in execlists_update_context() + */ + printf("reg_state[CTX_RING_BUFFER_START]=0x%x(mmio base+0x38)\n", reg_state[CTX_RING_BUFFER_START]); + printf("reg_state[CTX_RING_BUFFER_START+1]=0x%x(mmio base+0x38+4)\n", reg_state[CTX_RING_BUFFER_START+1]); + printf("reg_state[CTX_RING_BUFFER_CONTROL]=0x%x(mmio base+0x3c)\n", reg_state[CTX_RING_BUFFER_CONTROL]); + printf("reg_state[CTX_RING_BUFFER_CONTROL+1]=0x%x\n", reg_state[CTX_RING_BUFFER_CONTROL+1]); + printf("reg_state[CTX_BB_HEAD_U]=0x%x(mmio base+0x168)\n", reg_state[CTX_BB_HEAD_U]); + printf("reg_state[CTX_BB_HEAD_U+1]=0x%x\n", reg_state[CTX_BB_HEAD_U+1]); + printf("reg_state[CTX_BB_HEAD_L]=0x%x(mmio base+0x140)\n", reg_state[CTX_BB_HEAD_L]); + printf("reg_state[CTX_BB_HEAD_L+1]=0x%x\n", reg_state[CTX_BB_HEAD_L+1]); + printf("reg_state[CTX_BB_STATE]=0x%x(mmio base+0x110)\n", reg_state[CTX_BB_STATE]); + printf("reg_state[CTX_BB_STATE+1]=0x%x\n", reg_state[CTX_BB_STATE+1]); + printf("reg_state[CTX_SECOND_BB_HEAD_U]=0x%x(mmio base+0x11c)\n", reg_state[CTX_SECOND_BB_HEAD_U]); + printf("reg_state[CTX_SECOND_BB_HEAD_U+1]=0x%x\n", reg_state[CTX_SECOND_BB_HEAD_U+1]); + printf("reg_state[CTX_SECOND_BB_HEAD_L]=0x%x(mmio base+0x114)\n", reg_state[CTX_SECOND_BB_HEAD_L]); + printf("reg_state[CTX_SECOND_BB_HEAD_L+1]=0x%x\n", reg_state[CTX_SECOND_BB_HEAD_L+1]); + printf("reg_state[CTX_SECOND_BB_STATE]=0x%x(mmio base+0x118)\n", reg_state[CTX_SECOND_BB_STATE]); + printf("reg_state[CTX_SECOND_BB_STATE+1]=0x%x\n", reg_state[CTX_SECOND_BB_STATE+1]); + + if (id == RCS) { + printf("reg_state[CTX_BB_PER_CTX_PTR]=0x%x\n", reg_state[CTX_BB_PER_CTX_PTR]); + printf("reg_state[CTX_BB_PER_CTX_PTR+1]=0x%x\n", reg_state[CTX_BB_PER_CTX_PTR+1]); + printf("reg_state[CTX_RCS_INDIRECT_CTX]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX]); + printf("reg_state[CTX_RCS_INDIRECT_CTX+1]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX+1]); + printf("reg_state[CTX_RCS_INDIRECT_CTX_OFFSET]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX_OFFSET]); + printf("reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1]); + } + + printf("reg_state[CTX_LRI_HEADER_1]=0x%x\n", reg_state[CTX_LRI_HEADER_1]); + printf("reg_state[CTX_LRI_HEADER_1]=0x%x\n", reg_state[CTX_LRI_HEADER_1]); + printf("reg_state[CTX_CTX_TIMESTAMP]=0x%x\n", reg_state[CTX_CTX_TIMESTAMP]); + printf("reg_state[CTX_CTX_TIMESTAMP+1]=0x%x\n", reg_state[CTX_CTX_TIMESTAMP+1]); + printf("reg_state[CTX_PDP3_UDW]=0x%x(mmio base+0x270+(3*8)+4)\n", reg_state[CTX_PDP3_UDW]); + printf("reg_state[CTX_PDP3_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP3_LDW]); + printf("reg_state[CTX_PDP2_UDW]=0x%x(mmio base+0x270+(2*8)+4)\n", reg_state[CTX_PDP2_UDW]); + printf("reg_state[CTX_PDP2_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP2_LDW]); + printf("reg_state[CTX_PDP1_UDW]=0x%x(mmio base+0x270+(1*8)+4)\n", reg_state[CTX_PDP1_UDW]); + printf("reg_state[CTX_PDP1_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP1_LDW]); + printf("reg_state[CTX_PDP0_UDW]=0x%x(mmio base+0x270+(0*8)+4)\n", reg_state[CTX_PDP0_UDW]); + printf("reg_state[CTX_PDP0_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP0_LDW]); + printf("reg_state[CTX_PDP3_UDW+1]=0x%x\n", reg_state[CTX_PDP3_UDW+1]); + printf("reg_state[CTX_PDP3_LDW+1]=0x%x(pd 3 phyaddr)\n", reg_state[CTX_PDP3_LDW+1]); + printf("reg_state[CTX_PDP2_UDW+1]=0x%x\n", reg_state[CTX_PDP2_UDW+1]); + printf("reg_state[CTX_PDP2_LDW+1]=0x%x(pd 2 phyaddr)\n", reg_state[CTX_PDP2_LDW+1]); + printf("reg_state[CTX_PDP1_UDW+1]=0x%x\n", reg_state[CTX_PDP1_UDW+1]); + printf("reg_state[CTX_PDP1_LDW+1]=0x%x(pd 1 phyaddr)\n", reg_state[CTX_PDP1_LDW+1]); + printf("reg_state[CTX_PDP0_UDW+1]=0x%x\n", reg_state[CTX_PDP0_UDW+1]); + printf("reg_state[CTX_PDP0_LDW+1]=0x%x(pd 0 phyaddr)\n", reg_state[CTX_PDP0_LDW+1]); + + if (id == RCS) { + printf("reg_state[CTX_LRI_HEADER_2]=0x%x\n", reg_state[CTX_LRI_HEADER_2]); + printf("reg_state[CTX_R_PWR_CLK_STATE]=0x%x\n", reg_state[CTX_R_PWR_CLK_STATE]); + printf("reg_state[CTX_R_PWR_CLK_STATE+1]=0x%x\n", reg_state[CTX_R_PWR_CLK_STATE+1]); + } + + printf("*****************************************************************\n"); + printf("reg_state[CTX_RING_BUFFER_START+1] = 0x%x (ring buffer gtt address)\n", + reg_state[CTX_RING_BUFFER_START+1]); + printf("reg_state[CTX_PDP0_LDW+1] = 0x%x (page directory physical address)\n", + reg_state[CTX_PDP0_LDW+1]); + //printf("Render Ring [%d..%d); Video Ring [%d..%d)\n", + // INREG(linear_mmio, 0x2034), INREG(linear_mmio, 0x2030), + // INREG(linear_mmio, 0x12034), INREG(linear_mmio, 0x12030)); + printf("*****************************************************************\n"); + + return 0; +} |