diff options
author | Sean Paul <seanpaul@chromium.org> | 2017-06-27 11:36:28 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2017-06-27 11:36:28 -0400 |
commit | c048c984de38d906bb0df56ec2ae90eafc123d0a (patch) | |
tree | 4e670e712aeedcaf2e2193b64f9120e03320e01c | |
parent | 38cb266ad1a24e037220dc563ab46364595b17b6 (diff) | |
parent | 6d61e70ccc21606ffb8a0a03bd3aba24f659502b (diff) | |
download | op-kernel-dev-c048c984de38d906bb0df56ec2ae90eafc123d0a.zip op-kernel-dev-c048c984de38d906bb0df56ec2ae90eafc123d0a.tar.gz |
Merge remote-tracking branch 'airlied/drm-next' into drm-misc-next-fixes
Backmerge drm-next with rc7
313 files changed, 40877 insertions, 4720 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt index e9c5a1d..f465647 100644 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt @@ -22,7 +22,8 @@ Required properties : - #clock-cells : must contain 1 - #reset-cells : must contain 1 -For the PRCM CCUs on H3/A64, one more clock is needed: +For the PRCM CCUs on H3/A64, two more clocks are needed: +- "pll-periph": the SoC's peripheral PLL from the main CCU - "iosc": the SoC's internal frequency oscillator Example for generic CCU: @@ -39,8 +40,8 @@ Example for PRCM CCU: r_ccu: clock@01f01400 { compatible = "allwinner,sun50i-a64-r-ccu"; reg = <0x01f01400 0x100>; - clocks = <&osc24M>, <&osc32k>, <&iosc>; - clock-names = "hosc", "losc", "iosc"; + clocks = <&osc24M>, <&osc32k>, <&iosc>, <&ccu CLK_PLL_PERIPH0>; + clock-names = "hosc", "losc", "iosc", "pll-periph"; #clock-cells = <1>; #reset-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt index 42c3bb2..01e331a 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt @@ -41,9 +41,9 @@ Required properties: Optional properties: In order to use the GPIO lines in PWM mode, some additional optional -properties are required. Only Armada 370 and XP support these properties. +properties are required. -- compatible: Must contain "marvell,armada-370-xp-gpio" +- compatible: Must contain "marvell,armada-370-gpio" - reg: an additional register set is needed, for the GPIO Blink Counter on/off registers. @@ -71,7 +71,7 @@ Example: }; gpio1: gpio@18140 { - compatible = "marvell,armada-370-xp-gpio"; + compatible = "marvell,armada-370-gpio"; reg = <0x18140 0x40>, <0x181c8 0x08>; reg-names = "gpio", "pwm"; ngpios = <17>; diff --git a/Documentation/devicetree/bindings/mfd/stm32-timers.txt b/Documentation/devicetree/bindings/mfd/stm32-timers.txt index bbd083f..1db6e00 100644 --- a/Documentation/devicetree/bindings/mfd/stm32-timers.txt +++ b/Documentation/devicetree/bindings/mfd/stm32-timers.txt @@ -31,7 +31,7 @@ Example: compatible = "st,stm32-timers"; reg = <0x40010000 0x400>; clocks = <&rcc 0 160>; - clock-names = "clk_int"; + clock-names = "int"; pwm { compatible = "st,stm32-pwm"; diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt index d6c6e41..8ec2ca2 100644 --- a/Documentation/devicetree/bindings/net/dsa/b53.txt +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt @@ -34,7 +34,7 @@ Required properties: "brcm,bcm6328-switch" "brcm,bcm6368-switch" and the mandatory "brcm,bcm63xx-switch" -See Documentation/devicetree/bindings/dsa/dsa.txt for a list of additional +See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional required and optional properties. Examples: diff --git a/Documentation/devicetree/bindings/net/smsc911x.txt b/Documentation/devicetree/bindings/net/smsc911x.txt index 16c3a950..acfafc8 100644 --- a/Documentation/devicetree/bindings/net/smsc911x.txt +++ b/Documentation/devicetree/bindings/net/smsc911x.txt @@ -27,6 +27,7 @@ Optional properties: of the device. On many systems this is wired high so the device goes out of reset at power-on, but if it is under program control, this optional GPIO can wake up in response to it. +- vdd33a-supply, vddvario-supply : 3.3V analog and IO logic power supplies Examples: @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 12 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc7 NAME = Fearless Coyote # *DOCUMENTATION* @@ -1437,7 +1437,7 @@ help: @echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build' @echo ' make V=2 [targets] 2 => give reason for rebuild of target' @echo ' make O=dir [targets] Locate all output files in "dir", including .config' - @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)' + @echo ' make C=1 [targets] Check re-compiled c source with $$CHECK (sparse by default)' @echo ' make C=2 [targets] Force check of all c source with $$CHECK' @echo ' make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections' @echo ' make W=n [targets] Enable extra gcc checks, n=1,2,3 where' diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 41b6e31..d0cb007 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -221,10 +221,11 @@ void update_vsyscall(struct timekeeper *tk) /* tkr_mono.cycle_last == tkr_raw.cycle_last */ vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; vdso_data->raw_time_sec = tk->raw_time.tv_sec; - vdso_data->raw_time_nsec = tk->raw_time.tv_nsec; + vdso_data->raw_time_nsec = (tk->raw_time.tv_nsec << + tk->tkr_raw.shift) + + tk->tkr_raw.xtime_nsec; vdso_data->xtime_clock_sec = tk->xtime_sec; vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; - /* tkr_raw.xtime_nsec == 0 */ vdso_data->cs_mono_mult = tk->tkr_mono.mult; vdso_data->cs_raw_mult = tk->tkr_raw.mult; /* tkr_mono.shift == tkr_raw.shift */ diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index e00b467..76320e9 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S @@ -256,7 +256,6 @@ monotonic_raw: seqcnt_check fail=monotonic_raw /* All computations are done with left-shifted nsecs. */ - lsl x14, x14, x12 get_nsec_per_sec res=x9 lsl x9, x9, x12 diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c index 7c6336d..7cd9216 100644 --- a/arch/mips/kvm/tlb.c +++ b/arch/mips/kvm/tlb.c @@ -166,7 +166,11 @@ static int _kvm_mips_host_tlb_inv(unsigned long entryhi) int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va, bool user, bool kernel) { - int idx_user, idx_kernel; + /* + * Initialize idx_user and idx_kernel to workaround bogus + * maybe-initialized warning when using GCC 6. + */ + int idx_user = 0, idx_kernel = 0; unsigned long flags, old_entryhi; local_irq_save(flags); diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h index a83821f..8814a72 100644 --- a/arch/powerpc/include/asm/kprobes.h +++ b/arch/powerpc/include/asm/kprobes.h @@ -103,6 +103,7 @@ extern int kprobe_exceptions_notify(struct notifier_block *self, extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_handler(struct pt_regs *regs); extern int kprobe_post_handler(struct pt_regs *regs); +extern int is_current_kprobe_addr(unsigned long addr); #ifdef CONFIG_KPROBES_ON_FTRACE extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb); diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index ae418b8..b886795 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1411,10 +1411,8 @@ USE_TEXT_SECTION() .balign IFETCH_ALIGN_BYTES do_hash_page: #ifdef CONFIG_PPC_STD_MMU_64 - andis. r0,r4,0xa410 /* weird error? */ + andis. r0,r4,0xa450 /* weird error? */ bne- handle_page_fault /* if not, try to insert a HPTE */ - andis. r0,r4,DSISR_DABRMATCH@h - bne- handle_dabr_fault CURRENT_THREAD_INFO(r11, r1) lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ @@ -1438,11 +1436,16 @@ do_hash_page: /* Error */ blt- 13f + + /* Reload DSISR into r4 for the DABR check below */ + ld r4,_DSISR(r1) #endif /* CONFIG_PPC_STD_MMU_64 */ /* Here we have a page fault that hash_page can't handle. */ handle_page_fault: -11: ld r4,_DAR(r1) +11: andis. r0,r4,DSISR_DABRMATCH@h + bne- handle_dabr_fault + ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_page_fault diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index fc43435..01addfb 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -43,6 +43,12 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; +int is_current_kprobe_addr(unsigned long addr) +{ + struct kprobe *p = kprobe_running(); + return (p && (unsigned long)p->addr == addr) ? 1 : 0; +} + bool arch_within_kprobe_blacklist(unsigned long addr) { return (addr >= (unsigned long)__kprobes_text_start && @@ -617,6 +623,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); #endif + /* + * jprobes use jprobe_return() which skips the normal return + * path of the function, and this messes up the accounting of the + * function graph tracer. + * + * Pause function graph tracing while performing the jprobe function. + */ + pause_graph_tracing(); + return 1; } NOKPROBE_SYMBOL(setjmp_pre_handler); @@ -642,6 +657,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) * saved regs... */ memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs)); + /* It's OK to start function graph tracing again */ + unpause_graph_tracing(); preempt_enable_no_resched(); return 1; } diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index a8c1f99..4640f6d 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -616,6 +616,24 @@ void __init exc_lvl_early_init(void) #endif /* + * Emergency stacks are used for a range of things, from asynchronous + * NMIs (system reset, machine check) to synchronous, process context. + * We set preempt_count to zero, even though that isn't necessarily correct. To + * get the right value we'd need to copy it from the previous thread_info, but + * doing that might fault causing more problems. + * TODO: what to do with accounting? + */ +static void emerg_stack_init_thread_info(struct thread_info *ti, int cpu) +{ + ti->task = NULL; + ti->cpu = cpu; + ti->preempt_count = 0; + ti->local_flags = 0; + ti->flags = 0; + klp_init_thread_info(ti); +} + +/* * Stack space used when we detect a bad kernel stack pointer, and * early in SMP boots before relocation is enabled. Exclusive emergency * stack for machine checks. @@ -633,24 +651,31 @@ void __init emergency_stack_init(void) * Since we use these as temporary stacks during secondary CPU * bringup, we need to get at them in real mode. This means they * must also be within the RMO region. + * + * The IRQ stacks allocated elsewhere in this file are zeroed and + * initialized in kernel/irq.c. These are initialized here in order + * to have emergency stacks available as early as possible. */ limit = min(safe_stack_limit(), ppc64_rma_size); for_each_possible_cpu(i) { struct thread_info *ti; ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); - klp_init_thread_info(ti); + memset(ti, 0, THREAD_SIZE); + emerg_stack_init_thread_info(ti, i); paca[i].emergency_sp = (void *)ti + THREAD_SIZE; #ifdef CONFIG_PPC_BOOK3S_64 /* emergency stack for NMI exception handling. */ ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); - klp_init_thread_info(ti); + memset(ti, 0, THREAD_SIZE); + emerg_stack_init_thread_info(ti, i); paca[i].nmi_emergency_sp = (void *)ti + THREAD_SIZE; /* emergency stack for machine check exception handling. */ ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); - klp_init_thread_info(ti); + memset(ti, 0, THREAD_SIZE); + emerg_stack_init_thread_info(ti, i); paca[i].mc_emergency_sp = (void *)ti + THREAD_SIZE; #endif } diff --git a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S index 7c933a9..c98e90b 100644 --- a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S +++ b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S @@ -45,10 +45,14 @@ _GLOBAL(ftrace_caller) stdu r1,-SWITCH_FRAME_SIZE(r1) /* Save all gprs to pt_regs */ - SAVE_8GPRS(0,r1) - SAVE_8GPRS(8,r1) - SAVE_8GPRS(16,r1) - SAVE_8GPRS(24,r1) + SAVE_GPR(0, r1) + SAVE_10GPRS(2, r1) + SAVE_10GPRS(12, r1) + SAVE_10GPRS(22, r1) + + /* Save previous stack pointer (r1) */ + addi r8, r1, SWITCH_FRAME_SIZE + std r8, GPR1(r1) /* Load special regs for save below */ mfmsr r8 @@ -95,18 +99,44 @@ ftrace_call: bl ftrace_stub nop - /* Load ctr with the possibly modified NIP */ - ld r3, _NIP(r1) - mtctr r3 + /* Load the possibly modified NIP */ + ld r15, _NIP(r1) + #ifdef CONFIG_LIVEPATCH - cmpd r14,r3 /* has NIP been altered? */ + cmpd r14, r15 /* has NIP been altered? */ +#endif + +#if defined(CONFIG_LIVEPATCH) && defined(CONFIG_KPROBES_ON_FTRACE) + /* NIP has not been altered, skip over further checks */ + beq 1f + + /* Check if there is an active kprobe on us */ + subi r3, r14, 4 + bl is_current_kprobe_addr + nop + + /* + * If r3 == 1, then this is a kprobe/jprobe. + * else, this is livepatched function. + * + * The conditional branch for livepatch_handler below will use the + * result of this comparison. For kprobe/jprobe, we just need to branch to + * the new NIP, not call livepatch_handler. The branch below is bne, so we + * want CR0[EQ] to be true if this is a kprobe/jprobe. Which means we want + * CR0[EQ] = (r3 == 1). + */ + cmpdi r3, 1 +1: #endif + /* Load CTR with the possibly modified NIP */ + mtctr r15 + /* Restore gprs */ - REST_8GPRS(0,r1) - REST_8GPRS(8,r1) - REST_8GPRS(16,r1) - REST_8GPRS(24,r1) + REST_GPR(0,r1) + REST_10GPRS(2,r1) + REST_10GPRS(12,r1) + REST_10GPRS(22,r1) /* Restore possibly modified LR */ ld r0, _LINK(r1) @@ -119,7 +149,10 @@ ftrace_call: addi r1, r1, SWITCH_FRAME_SIZE #ifdef CONFIG_LIVEPATCH - /* Based on the cmpd above, if the NIP was altered handle livepatch */ + /* + * Based on the cmpd or cmpdi above, if the NIP was altered and we're + * not on a kprobe/jprobe, then handle livepatch. + */ bne- livepatch_handler #endif diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 42b7a4f..8d1a365 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1486,6 +1486,14 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, r = set_vpa(vcpu, &vcpu->arch.dtl, addr, len); break; case KVM_REG_PPC_TB_OFFSET: + /* + * POWER9 DD1 has an erratum where writing TBU40 causes + * the timebase to lose ticks. So we don't let the + * timebase offset be changed on P9 DD1. (It is + * initialized to zero.) + */ + if (cpu_has_feature(CPU_FTR_POWER9_DD1)) + break; /* round up to multiple of 2^24 */ vcpu->arch.vcore->tb_offset = ALIGN(set_reg_val(id, *val), 1UL << 24); @@ -2907,12 +2915,36 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) { int r; int srcu_idx; + unsigned long ebb_regs[3] = {}; /* shut up GCC */ + unsigned long user_tar = 0; + unsigned int user_vrsave; if (!vcpu->arch.sane) { run->exit_reason = KVM_EXIT_INTERNAL_ERROR; return -EINVAL; } + /* + * Don't allow entry with a suspended transaction, because + * the guest entry/exit code will lose it. + * If the guest has TM enabled, save away their TM-related SPRs + * (they will get restored by the TM unavailable interrupt). + */ +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + if (cpu_has_feature(CPU_FTR_TM) && current->thread.regs && + (current->thread.regs->msr & MSR_TM)) { + if (MSR_TM_ACTIVE(current->thread.regs->msr)) { + run->exit_reason = KVM_EXIT_FAIL_ENTRY; + run->fail_entry.hardware_entry_failure_reason = 0; + return -EINVAL; + } + current->thread.tm_tfhar = mfspr(SPRN_TFHAR); + current->thread.tm_tfiar = mfspr(SPRN_TFIAR); + current->thread.tm_texasr = mfspr(SPRN_TEXASR); + current->thread.regs->msr &= ~MSR_TM; + } +#endif + kvmppc_core_prepare_to_enter(vcpu); /* No need to go into the guest when all we'll do is come back out */ @@ -2934,6 +2966,15 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) flush_all_to_thread(current); + /* Save userspace EBB and other register values */ + if (cpu_has_feature(CPU_FTR_ARCH_207S)) { + ebb_regs[0] = mfspr(SPRN_EBBHR); + ebb_regs[1] = mfspr(SPRN_EBBRR); + ebb_regs[2] = mfspr(SPRN_BESCR); + user_tar = mfspr(SPRN_TAR); + } + user_vrsave = mfspr(SPRN_VRSAVE); + vcpu->arch.wqp = &vcpu->arch.vcore->wq; vcpu->arch.pgdir = current->mm->pgd; vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST; @@ -2960,6 +3001,16 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) } } while (is_kvmppc_resume_guest(r)); + /* Restore userspace EBB and other register values */ + if (cpu_has_feature(CPU_FTR_ARCH_207S)) { + mtspr(SPRN_EBBHR, ebb_regs[0]); + mtspr(SPRN_EBBRR, ebb_regs[1]); + mtspr(SPRN_BESCR, ebb_regs[2]); + mtspr(SPRN_TAR, user_tar); + mtspr(SPRN_FSCR, current->thread.fscr); + } + mtspr(SPRN_VRSAVE, user_vrsave); + out: vcpu->arch.state = KVMPPC_VCPU_NOTREADY; atomic_dec(&vcpu->kvm->arch.vcpus_running); diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S index 0fdc4a2..404deb5 100644 --- a/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S @@ -121,10 +121,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) * Put whatever is in the decrementer into the * hypervisor decrementer. */ +BEGIN_FTR_SECTION + ld r5, HSTATE_KVM_VCORE(r13) + ld r6, VCORE_KVM(r5) + ld r9, KVM_HOST_LPCR(r6) + andis. r9, r9, LPCR_LD@h +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) mfspr r8,SPRN_DEC mftb r7 - mtspr SPRN_HDEC,r8 +BEGIN_FTR_SECTION + /* On POWER9, don't sign-extend if host LPCR[LD] bit is set */ + bne 32f +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) extsw r8,r8 +32: mtspr SPRN_HDEC,r8 add r8,r8,r7 std r8,HSTATE_DECEXP(r13) diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index bdb3f76..4888dd4 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -32,12 +32,29 @@ #include <asm/opal.h> #include <asm/xive-regs.h> +/* Sign-extend HDEC if not on POWER9 */ +#define EXTEND_HDEC(reg) \ +BEGIN_FTR_SECTION; \ + extsw reg, reg; \ +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) + #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) /* Values in HSTATE_NAPPING(r13) */ #define NAPPING_CEDE 1 #define NAPPING_NOVCPU 2 +/* Stack frame offsets for kvmppc_hv_entry */ +#define SFS 144 +#define STACK_SLOT_TRAP (SFS-4) +#define STACK_SLOT_TID (SFS-16) +#define STACK_SLOT_PSSCR (SFS-24) +#define STACK_SLOT_PID (SFS-32) +#define STACK_SLOT_IAMR (SFS-40) +#define STACK_SLOT_CIABR (SFS-48) +#define STACK_SLOT_DAWR (SFS-56) +#define STACK_SLOT_DAWRX (SFS-64) + /* * Call kvmppc_hv_entry in real mode. * Must be called with interrupts hard-disabled. @@ -214,6 +231,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) kvmppc_primary_no_guest: /* We handle this much like a ceded vcpu */ /* put the HDEC into the DEC, since HDEC interrupts don't wake us */ + /* HDEC may be larger than DEC for arch >= v3.00, but since the */ + /* HDEC value came from DEC in the first place, it will fit */ mfspr r3, SPRN_HDEC mtspr SPRN_DEC, r3 /* @@ -295,8 +314,9 @@ kvm_novcpu_wakeup: /* See if our timeslice has expired (HDEC is negative) */ mfspr r0, SPRN_HDEC + EXTEND_HDEC(r0) li r12, BOOK3S_INTERRUPT_HV_DECREMENTER - cmpwi r0, 0 + cmpdi r0, 0 blt kvm_novcpu_exit /* Got an IPI but other vcpus aren't yet exiting, must be a latecomer */ @@ -319,10 +339,10 @@ kvm_novcpu_exit: bl kvmhv_accumulate_time #endif 13: mr r3, r12 - stw r12, 112-4(r1) + stw r12, STACK_SLOT_TRAP(r1) bl kvmhv_commence_exit nop - lwz r12, 112-4(r1) + lwz r12, STACK_SLOT_TRAP(r1) b kvmhv_switch_to_host /* @@ -390,8 +410,8 @@ kvm_secondary_got_guest: lbz r4, HSTATE_PTID(r13) cmpwi r4, 0 bne 63f - lis r6, 0x7fff - ori r6, r6, 0xffff + LOAD_REG_ADDR(r6, decrementer_max) + ld r6, 0(r6) mtspr SPRN_HDEC, r6 /* and set per-LPAR registers, if doing dynamic micro-threading */ ld r6, HSTATE_SPLIT_MODE(r13) @@ -545,11 +565,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) * * *****************************************************************************/ -/* Stack frame offsets */ -#define STACK_SLOT_TID (112-16) -#define STACK_SLOT_PSSCR (112-24) -#define STACK_SLOT_PID (112-32) - .global kvmppc_hv_entry kvmppc_hv_entry: @@ -565,7 +580,7 @@ kvmppc_hv_entry: */ mflr r0 std r0, PPC_LR_STKOFF(r1) - stdu r1, -112(r1) + stdu r1, -SFS(r1) /* Save R1 in the PACA */ std r1, HSTATE_HOST_R1(r13) @@ -749,10 +764,20 @@ BEGIN_FTR_SECTION mfspr r5, SPRN_TIDR mfspr r6, SPRN_PSSCR mfspr r7, SPRN_PID + mfspr r8, SPRN_IAMR std r5, STACK_SLOT_TID(r1) std r6, STACK_SLOT_PSSCR(r1) std r7, STACK_SLOT_PID(r1) + std r8, STACK_SLOT_IAMR(r1) END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) +BEGIN_FTR_SECTION + mfspr r5, SPRN_CIABR + mfspr r6, SPRN_DAWR + mfspr r7, SPRN_DAWRX + std r5, STACK_SLOT_CIABR(r1) + std r6, STACK_SLOT_DAWR(r1) + std r7, STACK_SLOT_DAWRX(r1) +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) BEGIN_FTR_SECTION /* Set partition DABR */ @@ -968,7 +993,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300) /* Check if HDEC expires soon */ mfspr r3, SPRN_HDEC - cmpwi r3, 512 /* 1 microsecond */ + EXTEND_HDEC(r3) + cmpdi r3, 512 /* 1 microsecond */ blt hdec_soon #ifdef CONFIG_KVM_XICS @@ -1505,11 +1531,10 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300) * set by the guest could disrupt the host. */ li r0, 0 - mtspr SPRN_IAMR, r0 - mtspr SPRN_CIABR, r0 - mtspr SPRN_DAWRX, r0 + mtspr SPRN_PSPB, r0 mtspr SPRN_WORT, r0 BEGIN_FTR_SECTION + mtspr SPRN_IAMR, r0 mtspr SPRN_TCSCR, r0 /* Set MMCRS to 1<<31 to freeze and disable the SPMC counters */ li r0, 1 @@ -1525,6 +1550,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) std r6,VCPU_UAMOR(r9) li r6,0 mtspr SPRN_AMR,r6 + mtspr SPRN_UAMOR, r6 /* Switch DSCR back to host value */ mfspr r8, SPRN_DSCR @@ -1670,12 +1696,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) /* Restore host values of some registers */ BEGIN_FTR_SECTION + ld r5, STACK_SLOT_CIABR(r1) + ld r6, STACK_SLOT_DAWR(r1) + ld r7, STACK_SLOT_DAWRX(r1) + mtspr SPRN_CIABR, r5 + mtspr SPRN_DAWR, r6 + mtspr SPRN_DAWRX, r7 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) +BEGIN_FTR_SECTION ld r5, STACK_SLOT_TID(r1) ld r6, STACK_SLOT_PSSCR(r1) ld r7, STACK_SLOT_PID(r1) + ld r8, STACK_SLOT_IAMR(r1) mtspr SPRN_TIDR, r5 mtspr SPRN_PSSCR, r6 mtspr SPRN_PID, r7 + mtspr SPRN_IAMR, r8 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) BEGIN_FTR_SECTION PPC_INVALIDATE_ERAT @@ -1819,8 +1855,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX) li r0, KVM_GUEST_MODE_NONE stb r0, HSTATE_IN_GUEST(r13) - ld r0, 112+PPC_LR_STKOFF(r1) - addi r1, r1, 112 + ld r0, SFS+PPC_LR_STKOFF(r1) + addi r1, r1, SFS mtlr r0 blr @@ -2366,12 +2402,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) mfspr r3, SPRN_DEC mfspr r4, SPRN_HDEC mftb r5 - cmpw r3, r4 + extsw r3, r3 + EXTEND_HDEC(r4) + cmpd r3, r4 ble 67f mtspr SPRN_DEC, r4 67: /* save expiry time of guest decrementer */ - extsw r3, r3 add r3, r3, r5 ld r4, HSTATE_KVM_VCPU(r13) ld r5, HSTATE_KVM_VCORE(r13) diff --git a/arch/powerpc/perf/perf_regs.c b/arch/powerpc/perf/perf_regs.c index cbd82fd..09ceea6 100644 --- a/arch/powerpc/perf/perf_regs.c +++ b/arch/powerpc/perf/perf_regs.c @@ -101,5 +101,6 @@ void perf_get_regs_user(struct perf_regs *regs_user, struct pt_regs *regs_user_copy) { regs_user->regs = task_pt_regs(current); - regs_user->abi = perf_reg_abi(current); + regs_user->abi = (regs_user->regs) ? perf_reg_abi(current) : + PERF_SAMPLE_REGS_ABI_NONE; } diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index e6f444b..b5d960d 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -449,7 +449,7 @@ static int mmio_launch_invalidate(struct npu *npu, unsigned long launch, return mmio_atsd_reg; } -static int mmio_invalidate_pid(struct npu *npu, unsigned long pid) +static int mmio_invalidate_pid(struct npu *npu, unsigned long pid, bool flush) { unsigned long launch; @@ -465,12 +465,15 @@ static int mmio_invalidate_pid(struct npu *npu, unsigned long pid) /* PID */ launch |= pid << PPC_BITLSHIFT(38); + /* No flush */ + launch |= !flush << PPC_BITLSHIFT(39); + /* Invalidating the entire process doesn't use a va */ return mmio_launch_invalidate(npu, launch, 0); } static int mmio_invalidate_va(struct npu *npu, unsigned long va, - unsigned long pid) + unsigned long pid, bool flush) { unsigned long launch; @@ -486,26 +489,60 @@ static int mmio_invalidate_va(struct npu *npu, unsigned long va, /* PID */ launch |= pid << PPC_BITLSHIFT(38); + /* No flush */ + launch |= !flush << PPC_BITLSHIFT(39); + return mmio_launch_invalidate(npu, launch, va); } #define mn_to_npu_context(x) container_of(x, struct npu_context, mn) +struct mmio_atsd_reg { + struct npu *npu; + int reg; +}; + +static void mmio_invalidate_wait( + struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS], bool flush) +{ + struct npu *npu; + int i, reg; + + /* Wait for all invalidations to complete */ + for (i = 0; i <= max_npu2_index; i++) { + if (mmio_atsd_reg[i].reg < 0) + continue; + + /* Wait for completion */ + npu = mmio_atsd_reg[i].npu; + reg = mmio_atsd_reg[i].reg; + while (__raw_readq(npu->mmio_atsd_regs[reg] + XTS_ATSD_STAT)) + cpu_relax(); + + put_mmio_atsd_reg(npu, reg); + + /* + * The GPU requires two flush ATSDs to ensure all entries have + * been flushed. We use PID 0 as it will never be used for a + * process on the GPU. + */ + if (flush) + mmio_invalidate_pid(npu, 0, true); + } +} + /* * Invalidate either a single address or an entire PID depending on * the value of va. */ static void mmio_invalidate(struct npu_context *npu_context, int va, - unsigned long address) + unsigned long address, bool flush) { - int i, j, reg; + int i, j; struct npu *npu; struct pnv_phb *nphb; struct pci_dev *npdev; - struct { - struct npu *npu; - int reg; - } mmio_atsd_reg[NV_MAX_NPUS]; + struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]; unsigned long pid = npu_context->mm->context.id; /* @@ -525,10 +562,11 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, if (va) mmio_atsd_reg[i].reg = - mmio_invalidate_va(npu, address, pid); + mmio_invalidate_va(npu, address, pid, + flush); else mmio_atsd_reg[i].reg = - mmio_invalidate_pid(npu, pid); + mmio_invalidate_pid(npu, pid, flush); /* * The NPU hardware forwards the shootdown to all GPUs @@ -544,18 +582,10 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, */ flush_tlb_mm(npu_context->mm); - /* Wait for all invalidations to complete */ - for (i = 0; i <= max_npu2_index; i++) { - if (mmio_atsd_reg[i].reg < 0) - continue; - - /* Wait for completion */ - npu = mmio_atsd_reg[i].npu; - reg = mmio_atsd_reg[i].reg; - while (__raw_readq(npu->mmio_atsd_regs[reg] + XTS_ATSD_STAT)) - cpu_relax(); - put_mmio_atsd_reg(npu, reg); - } + mmio_invalidate_wait(mmio_atsd_reg, flush); + if (flush) + /* Wait for the flush to complete */ + mmio_invalidate_wait(mmio_atsd_reg, false); } static void pnv_npu2_mn_release(struct mmu_notifier *mn, @@ -571,7 +601,7 @@ static void pnv_npu2_mn_release(struct mmu_notifier *mn, * There should be no more translation requests for this PID, but we * need to ensure any entries for it are removed from the TLB. */ - mmio_invalidate(npu_context, 0, 0); + mmio_invalidate(npu_context, 0, 0, true); } static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn, @@ -581,7 +611,7 @@ static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn, { struct npu_context *npu_context = mn_to_npu_context(mn); - mmio_invalidate(npu_context, 1, address); + mmio_invalidate(npu_context, 1, address, true); } static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn, @@ -590,7 +620,7 @@ static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn, { struct npu_context *npu_context = mn_to_npu_context(mn); - mmio_invalidate(npu_context, 1, address); + mmio_invalidate(npu_context, 1, address, true); } static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, @@ -600,8 +630,11 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, struct npu_context *npu_context = mn_to_npu_context(mn); unsigned long address; - for (address = start; address <= end; address += PAGE_SIZE) - mmio_invalidate(npu_context, 1, address); + for (address = start; address < end; address += PAGE_SIZE) + mmio_invalidate(npu_context, 1, address, false); + + /* Do the flush only on the final addess == end */ + mmio_invalidate(npu_context, 1, address, true); } static const struct mmu_notifier_ops nv_nmmu_notifier_ops = { @@ -651,8 +684,11 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, /* No nvlink associated with this GPU device */ return ERR_PTR(-ENODEV); - if (!mm) { - /* kernel thread contexts are not supported */ + if (!mm || mm->context.id == 0) { + /* + * Kernel thread contexts are not supported and context id 0 is + * reserved on the GPU. + */ return ERR_PTR(-EINVAL); } diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 9da243d..3b297fa 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -977,11 +977,12 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, ptr = asce.origin * 4096; if (asce.r) { *fake = 1; + ptr = 0; asce.dt = ASCE_TYPE_REGION1; } switch (asce.dt) { case ASCE_TYPE_REGION1: - if (vaddr.rfx01 > asce.tl && !asce.r) + if (vaddr.rfx01 > asce.tl && !*fake) return PGM_REGION_FIRST_TRANS; break; case ASCE_TYPE_REGION2: @@ -1009,8 +1010,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, union region1_table_entry rfte; if (*fake) { - /* offset in 16EB guest memory block */ - ptr = ptr + ((unsigned long) vaddr.rsx << 53UL); + ptr += (unsigned long) vaddr.rfx << 53; rfte.val = ptr; goto shadow_r2t; } @@ -1036,8 +1036,7 @@ shadow_r2t: union region2_table_entry rste; if (*fake) { - /* offset in 8PB guest memory block */ - ptr = ptr + ((unsigned long) vaddr.rtx << 42UL); + ptr += (unsigned long) vaddr.rsx << 42; rste.val = ptr; goto shadow_r3t; } @@ -1064,8 +1063,7 @@ shadow_r3t: union region3_table_entry rtte; if (*fake) { - /* offset in 4TB guest memory block */ - ptr = ptr + ((unsigned long) vaddr.sx << 31UL); + ptr += (unsigned long) vaddr.rtx << 31; rtte.val = ptr; goto shadow_sgt; } @@ -1101,8 +1099,7 @@ shadow_sgt: union segment_table_entry ste; if (*fake) { - /* offset in 2G guest memory block */ - ptr = ptr + ((unsigned long) vaddr.sx << 20UL); + ptr += (unsigned long) vaddr.sx << 20; ste.val = ptr; goto shadow_pgt; } diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index a6d91d4..110ce82 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -431,11 +431,11 @@ static __initconst const u64 skl_hw_cache_event_ids [ C(DTLB) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_INST_RETIRED.ALL_LOADS */ - [ C(RESULT_MISS) ] = 0x608, /* DTLB_LOAD_MISSES.WALK_COMPLETED */ + [ C(RESULT_MISS) ] = 0xe08, /* DTLB_LOAD_MISSES.WALK_COMPLETED */ }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_INST_RETIRED.ALL_STORES */ - [ C(RESULT_MISS) ] = 0x649, /* DTLB_STORE_MISSES.WALK_COMPLETED */ + [ C(RESULT_MISS) ] = 0xe49, /* DTLB_STORE_MISSES.WALK_COMPLETED */ }, [ C(OP_PREFETCH) ] = { [ C(RESULT_ACCESS) ] = 0x0, diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 0559626..722d0e5 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -296,6 +296,7 @@ struct x86_emulate_ctxt { bool perm_ok; /* do not check permissions if true */ bool ud; /* inject an #UD if host doesn't support insn */ + bool tf; /* TF value before instruction (after for syscall/sysret) */ bool have_exception; struct x86_exception exception; diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index fba1007..d5acc27 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -2,8 +2,7 @@ #define _ASM_X86_MSHYPER_H #include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/clocksource.h> +#include <linux/atomic.h> #include <asm/hyperv.h> /* diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0816ab2..80890de 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2742,6 +2742,7 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt) ctxt->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IF); } + ctxt->tf = (ctxt->eflags & X86_EFLAGS_TF) != 0; return X86EMUL_CONTINUE; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 87d3cb9..0e846f0 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5313,6 +5313,8 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu) kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); ctxt->eflags = kvm_get_rflags(vcpu); + ctxt->tf = (ctxt->eflags & X86_EFLAGS_TF) != 0; + ctxt->eip = kvm_rip_read(vcpu); ctxt->mode = (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL : (ctxt->eflags & X86_EFLAGS_VM) ? X86EMUL_MODE_VM86 : @@ -5528,36 +5530,25 @@ static int kvm_vcpu_check_hw_bp(unsigned long addr, u32 type, u32 dr7, return dr6; } -static void kvm_vcpu_check_singlestep(struct kvm_vcpu *vcpu, unsigned long rflags, int *r) +static void kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu, int *r) { struct kvm_run *kvm_run = vcpu->run; - /* - * rflags is the old, "raw" value of the flags. The new value has - * not been saved yet. - * - * This is correct even for TF set by the guest, because "the - * processor will not generate this exception after the instruction - * that sets the TF flag". - */ - if (unlikely(rflags & X86_EFLAGS_TF)) { - if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { - kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 | - DR6_RTM; - kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip; - kvm_run->debug.arch.exception = DB_VECTOR; - kvm_run->exit_reason = KVM_EXIT_DEBUG; - *r = EMULATE_USER_EXIT; - } else { - /* - * "Certain debug exceptions may clear bit 0-3. The - * remaining contents of the DR6 register are never - * cleared by the processor". - */ - vcpu->arch.dr6 &= ~15; - vcpu->arch.dr6 |= DR6_BS | DR6_RTM; - kvm_queue_exception(vcpu, DB_VECTOR); - } + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { + kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 | DR6_RTM; + kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip; + kvm_run->debug.arch.exception = DB_VECTOR; + kvm_run->exit_reason = KVM_EXIT_DEBUG; + *r = EMULATE_USER_EXIT; + } else { + /* + * "Certain debug exceptions may clear bit 0-3. The + * remaining contents of the DR6 register are never + * cleared by the processor". + */ + vcpu->arch.dr6 &= ~15; + vcpu->arch.dr6 |= DR6_BS | DR6_RTM; + kvm_queue_exception(vcpu, DB_VECTOR); } } @@ -5567,7 +5558,17 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu) int r = EMULATE_DONE; kvm_x86_ops->skip_emulated_instruction(vcpu); - kvm_vcpu_check_singlestep(vcpu, rflags, &r); + + /* + * rflags is the old, "raw" value of the flags. The new value has + * not been saved yet. + * + * This is correct even for TF set by the guest, because "the + * processor will not generate this exception after the instruction + * that sets the TF flag". + */ + if (unlikely(rflags & X86_EFLAGS_TF)) + kvm_vcpu_do_singlestep(vcpu, &r); return r == EMULATE_DONE; } EXPORT_SYMBOL_GPL(kvm_skip_emulated_instruction); @@ -5726,8 +5727,9 @@ restart: toggle_interruptibility(vcpu, ctxt->interruptibility); vcpu->arch.emulate_regs_need_sync_to_vcpu = false; kvm_rip_write(vcpu, ctxt->eip); - if (r == EMULATE_DONE) - kvm_vcpu_check_singlestep(vcpu, rflags, &r); + if (r == EMULATE_DONE && + (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP))) + kvm_vcpu_do_singlestep(vcpu, &r); if (!ctxt->have_exception || exception_type(ctxt->exception.vector) == EXCPT_TRAP) __kvm_set_rflags(vcpu, ctxt->eflags); diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index 1f5b692..0ded5e8 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -68,6 +68,45 @@ static void blk_mq_sched_assign_ioc(struct request_queue *q, __blk_mq_sched_assign_ioc(q, rq, bio, ioc); } +/* + * Mark a hardware queue as needing a restart. For shared queues, maintain + * a count of how many hardware queues are marked for restart. + */ +static void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx) +{ + if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) + return; + + if (hctx->flags & BLK_MQ_F_TAG_SHARED) { + struct request_queue *q = hctx->queue; + + if (!test_and_set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) + atomic_inc(&q->shared_hctx_restart); + } else + set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state); +} + +static bool blk_mq_sched_restart_hctx(struct blk_mq_hw_ctx *hctx) +{ + if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) + return false; + + if (hctx->flags & BLK_MQ_F_TAG_SHARED) { + struct request_queue *q = hctx->queue; + + if (test_and_clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) + atomic_dec(&q->shared_hctx_restart); + } else + clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state); + + if (blk_mq_hctx_has_pending(hctx)) { + blk_mq_run_hw_queue(hctx, true); + return true; + } + + return false; +} + struct request *blk_mq_sched_get_request(struct request_queue *q, struct bio *bio, unsigned int op, @@ -266,18 +305,6 @@ static bool blk_mq_sched_bypass_insert(struct blk_mq_hw_ctx *hctx, return true; } -static bool blk_mq_sched_restart_hctx(struct blk_mq_hw_ctx *hctx) -{ - if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) { - clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state); - if (blk_mq_hctx_has_pending(hctx)) { - blk_mq_run_hw_queue(hctx, true); - return true; - } - } - return false; -} - /** * list_for_each_entry_rcu_rr - iterate in a round-robin fashion over rcu list * @pos: loop cursor. @@ -309,6 +336,13 @@ void blk_mq_sched_restart(struct blk_mq_hw_ctx *const hctx) unsigned int i, j; if (set->flags & BLK_MQ_F_TAG_SHARED) { + /* + * If this is 0, then we know that no hardware queues + * have RESTART marked. We're done. + */ + if (!atomic_read(&queue->shared_hctx_restart)) + return; + rcu_read_lock(); list_for_each_entry_rcu_rr(q, queue, &set->tag_list, tag_set_list) { diff --git a/block/blk-mq-sched.h b/block/blk-mq-sched.h index edafb53..5007ede 100644 --- a/block/blk-mq-sched.h +++ b/block/blk-mq-sched.h @@ -115,15 +115,6 @@ static inline bool blk_mq_sched_has_work(struct blk_mq_hw_ctx *hctx) return false; } -/* - * Mark a hardware queue as needing a restart. - */ -static inline void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx) -{ - if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) - set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state); -} - static inline bool blk_mq_sched_needs_restart(struct blk_mq_hw_ctx *hctx) { return test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state); diff --git a/block/blk-mq.c b/block/blk-mq.c index bb66c96..958ceda 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2103,20 +2103,30 @@ static void blk_mq_map_swqueue(struct request_queue *q, } } +/* + * Caller needs to ensure that we're either frozen/quiesced, or that + * the queue isn't live yet. + */ static void queue_set_hctx_shared(struct request_queue *q, bool shared) { struct blk_mq_hw_ctx *hctx; int i; queue_for_each_hw_ctx(q, hctx, i) { - if (shared) + if (shared) { + if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) + atomic_inc(&q->shared_hctx_restart); hctx->flags |= BLK_MQ_F_TAG_SHARED; - else + } else { + if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) + atomic_dec(&q->shared_hctx_restart); hctx->flags &= ~BLK_MQ_F_TAG_SHARED; + } } } -static void blk_mq_update_tag_set_depth(struct blk_mq_tag_set *set, bool shared) +static void blk_mq_update_tag_set_depth(struct blk_mq_tag_set *set, + bool shared) { struct request_queue *q; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3a10d757..d531629 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1428,6 +1428,37 @@ static void acpi_init_coherency(struct acpi_device *adev) adev->flags.coherent_dma = cca; } +static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) +{ + bool *is_spi_i2c_slave_p = data; + + if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) + return 1; + + /* + * devices that are connected to UART still need to be enumerated to + * platform bus + */ + if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) + *is_spi_i2c_slave_p = true; + + /* no need to do more checking */ + return -1; +} + +static bool acpi_is_spi_i2c_slave(struct acpi_device *device) +{ + struct list_head resource_list; + bool is_spi_i2c_slave = false; + + INIT_LIST_HEAD(&resource_list); + acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, + &is_spi_i2c_slave); + acpi_dev_free_resource_list(&resource_list); + + return is_spi_i2c_slave; +} + void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, int type, unsigned long long sta) { @@ -1443,6 +1474,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, acpi_bus_get_flags(device); device->flags.match_driver = false; device->flags.initialized = true; + device->flags.spi_i2c_slave = acpi_is_spi_i2c_slave(device); acpi_device_clear_enumerated(device); device_initialize(&device->dev); dev_set_uevent_suppress(&device->dev, true); @@ -1727,38 +1759,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_OK; } -static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) -{ - bool *is_spi_i2c_slave_p = data; - - if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) - return 1; - - /* - * devices that are connected to UART still need to be enumerated to - * platform bus - */ - if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) - *is_spi_i2c_slave_p = true; - - /* no need to do more checking */ - return -1; -} - static void acpi_default_enumeration(struct acpi_device *device) { - struct list_head resource_list; - bool is_spi_i2c_slave = false; - /* * Do not enumerate SPI/I2C slaves as they will be enumerated by their * respective parents. */ - INIT_LIST_HEAD(&resource_list); - acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, - &is_spi_i2c_slave); - acpi_dev_free_resource_list(&resource_list); - if (!is_spi_i2c_slave) { + if (!device->flags.spi_i2c_slave) { acpi_create_platform_device(device, NULL); acpi_device_set_enumerated(device); } else { @@ -1854,7 +1861,7 @@ static void acpi_bus_attach(struct acpi_device *device) return; device->flags.match_driver = true; - if (ret > 0) { + if (ret > 0 && !device->flags.spi_i2c_slave) { acpi_device_set_enumerated(device); goto ok; } @@ -1863,10 +1870,10 @@ static void acpi_bus_attach(struct acpi_device *device) if (ret < 0) return; - if (device->pnp.type.platform_id) - acpi_default_enumeration(device); - else + if (!device->pnp.type.platform_id && !device->flags.spi_i2c_slave) acpi_device_set_enumerated(device); + else + acpi_default_enumeration(device); ok: list_for_each_entry(child, &device->children, node) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 726c32e..0e82409 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -609,8 +609,6 @@ int xen_blkif_schedule(void *arg) unsigned long timeout; int ret; - xen_blkif_get(blkif); - set_freezable(); while (!kthread_should_stop()) { if (try_to_freeze()) @@ -665,7 +663,6 @@ purge_gnt_list: print_stats(ring); ring->xenblkd = NULL; - xen_blkif_put(blkif); return 0; } @@ -1436,34 +1433,35 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring, static void make_response(struct xen_blkif_ring *ring, u64 id, unsigned short op, int st) { - struct blkif_response resp; + struct blkif_response *resp; unsigned long flags; union blkif_back_rings *blk_rings; int notify; - resp.id = id; - resp.operation = op; - resp.status = st; - spin_lock_irqsave(&ring->blk_ring_lock, flags); blk_rings = &ring->blk_rings; /* Place on the response ring for the relevant domain. */ switch (ring->blkif->blk_protocol) { case BLKIF_PROTOCOL_NATIVE: - memcpy(RING_GET_RESPONSE(&blk_rings->native, blk_rings->native.rsp_prod_pvt), - &resp, sizeof(resp)); + resp = RING_GET_RESPONSE(&blk_rings->native, + blk_rings->native.rsp_prod_pvt); break; case BLKIF_PROTOCOL_X86_32: - memcpy(RING_GET_RESPONSE(&blk_rings->x86_32, blk_rings->x86_32.rsp_prod_pvt), - &resp, sizeof(resp)); + resp = RING_GET_RESPONSE(&blk_rings->x86_32, + blk_rings->x86_32.rsp_prod_pvt); break; case BLKIF_PROTOCOL_X86_64: - memcpy(RING_GET_RESPONSE(&blk_rings->x86_64, blk_rings->x86_64.rsp_prod_pvt), - &resp, sizeof(resp)); + resp = RING_GET_RESPONSE(&blk_rings->x86_64, + blk_rings->x86_64.rsp_prod_pvt); break; default: BUG(); } + + resp->id = id; + resp->operation = op; + resp->status = st; + blk_rings->common.rsp_prod_pvt++; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify); spin_unlock_irqrestore(&ring->blk_ring_lock, flags); diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index dea61f6..ecb35fe 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -75,9 +75,8 @@ extern unsigned int xenblk_max_queues; struct blkif_common_request { char dummy; }; -struct blkif_common_response { - char dummy; -}; + +/* i386 protocol version */ struct blkif_x86_32_request_rw { uint8_t nr_segments; /* number of segments */ @@ -129,14 +128,6 @@ struct blkif_x86_32_request { } u; } __attribute__((__packed__)); -/* i386 protocol version */ -#pragma pack(push, 4) -struct blkif_x86_32_response { - uint64_t id; /* copied from request */ - uint8_t operation; /* copied from request */ - int16_t status; /* BLKIF_RSP_??? */ -}; -#pragma pack(pop) /* x86_64 protocol version */ struct blkif_x86_64_request_rw { @@ -193,18 +184,12 @@ struct blkif_x86_64_request { } u; } __attribute__((__packed__)); -struct blkif_x86_64_response { - uint64_t __attribute__((__aligned__(8))) id; - uint8_t operation; /* copied from request */ - int16_t status; /* BLKIF_RSP_??? */ -}; - DEFINE_RING_TYPES(blkif_common, struct blkif_common_request, - struct blkif_common_response); + struct blkif_response); DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, - struct blkif_x86_32_response); + struct blkif_response __packed); DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, - struct blkif_x86_64_response); + struct blkif_response); union blkif_back_rings { struct blkif_back_ring native; @@ -281,6 +266,7 @@ struct xen_blkif_ring { wait_queue_head_t wq; atomic_t inflight; + bool active; /* One thread per blkif ring. */ struct task_struct *xenblkd; unsigned int waiting_reqs; diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 1f3dfaa..792da68 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -159,7 +159,7 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif) init_waitqueue_head(&ring->shutdown_wq); ring->blkif = blkif; ring->st_print = jiffies; - xen_blkif_get(blkif); + ring->active = true; } return 0; @@ -249,10 +249,12 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) struct xen_blkif_ring *ring = &blkif->rings[r]; unsigned int i = 0; + if (!ring->active) + continue; + if (ring->xenblkd) { kthread_stop(ring->xenblkd); wake_up(&ring->shutdown_wq); - ring->xenblkd = NULL; } /* The above kthread_stop() guarantees that at this point we @@ -296,7 +298,7 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) BUG_ON(ring->free_pages_num != 0); BUG_ON(ring->persistent_gnt_c != 0); WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); - xen_blkif_put(blkif); + ring->active = false; } blkif->nr_ring_pages = 0; /* @@ -312,9 +314,10 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) static void xen_blkif_free(struct xen_blkif *blkif) { - - xen_blkif_disconnect(blkif); + WARN_ON(xen_blkif_disconnect(blkif)); xen_vbd_free(&blkif->vbd); + kfree(blkif->be->mode); + kfree(blkif->be); /* Make sure everything is drained before shutting down */ kmem_cache_free(xen_blkif_cachep, blkif); @@ -511,8 +514,6 @@ static int xen_blkbk_remove(struct xenbus_device *dev) xen_blkif_put(be->blkif); } - kfree(be->mode); - kfree(be); return 0; } diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 0a52da4..b83c535 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -121,7 +121,6 @@ config QCOM_EBI2 config SIMPLE_PM_BUS bool "Simple Power-Managed Bus Driver" depends on OF && PM - depends on ARCH_RENESAS || COMPILE_TEST help Driver for transparent busses that don't need a real driver, but where the bus controller is part of a PM domain, or under the control diff --git a/drivers/char/random.c b/drivers/char/random.c index e870f32..01a260f 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -803,13 +803,13 @@ static int crng_fast_load(const char *cp, size_t len) p[crng_init_cnt % CHACHA20_KEY_SIZE] ^= *cp; cp++; crng_init_cnt++; len--; } + spin_unlock_irqrestore(&primary_crng.lock, flags); if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { invalidate_batched_entropy(); crng_init = 1; wake_up_interruptible(&crng_init_wait); pr_notice("random: fast init done\n"); } - spin_unlock_irqrestore(&primary_crng.lock, flags); return 1; } @@ -841,6 +841,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) } memzero_explicit(&buf, sizeof(buf)); crng->init_time = jiffies; + spin_unlock_irqrestore(&primary_crng.lock, flags); if (crng == &primary_crng && crng_init < 2) { invalidate_batched_entropy(); crng_init = 2; @@ -848,7 +849,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) wake_up_interruptible(&crng_init_wait); pr_notice("random: crng init done\n"); } - spin_unlock_irqrestore(&primary_crng.lock, flags); } static inline void crng_wait_ready(void) @@ -2041,8 +2041,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64); u64 get_random_u64(void) { u64 ret; - bool use_lock = crng_init < 2; - unsigned long flags; + bool use_lock = READ_ONCE(crng_init) < 2; + unsigned long flags = 0; struct batched_entropy *batch; #if BITS_PER_LONG == 64 @@ -2073,8 +2073,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32); u32 get_random_u32(void) { u32 ret; - bool use_lock = crng_init < 2; - unsigned long flags; + bool use_lock = READ_ONCE(crng_init) < 2; + unsigned long flags = 0; struct batched_entropy *batch; if (arch_get_random_int(&ret)) diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 19480bc..2f29ee1 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -14,6 +14,7 @@ config COMMON_CLK_MESON8B config COMMON_CLK_GXBB bool depends on COMMON_CLK_AMLOGIC + select RESET_CONTROLLER help Support for the clock controller on AmLogic S905 devices, aka gxbb. Say Y if you want peripherals and CPU frequency scaling to work. diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index b0d551a..eb89c78 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -156,6 +156,7 @@ config SUN8I_R_CCU bool "Support for Allwinner SoCs' PRCM CCUs" select SUNXI_CCU_DIV select SUNXI_CCU_GATE + select SUNXI_CCU_MP default MACH_SUN8I || (ARCH_SUNXI && ARM64) endif diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index 9b3cd24..061b6fb 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h @@ -31,7 +31,9 @@ #define CLK_PLL_VIDEO0_2X 8 #define CLK_PLL_VE 9 #define CLK_PLL_DDR0 10 -#define CLK_PLL_PERIPH0 11 + +/* PLL_PERIPH0 exported for PRCM */ + #define CLK_PLL_PERIPH0_2X 12 #define CLK_PLL_PERIPH1 13 #define CLK_PLL_PERIPH1_2X 14 diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index 5c476f9..5372bf8 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c @@ -243,7 +243,7 @@ static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb", static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb", 0x060, BIT(6), 0); static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb", - 0x060, BIT(6), 0); + 0x060, BIT(7), 0); static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb", 0x060, BIT(8), 0); static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb", diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 89e68d2..df97e25 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c @@ -556,7 +556,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents, 0x12c, 0, 4, 24, 3, BIT(31), CLK_SET_RATE_PARENT); static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents, - 0x12c, 0, 4, 24, 3, BIT(31), + 0x130, 0, 4, 24, 3, BIT(31), CLK_SET_RATE_PARENT); static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1", diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h index 85973d1..1b4baea 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h @@ -29,7 +29,9 @@ #define CLK_PLL_VIDEO 6 #define CLK_PLL_VE 7 #define CLK_PLL_DDR 8 -#define CLK_PLL_PERIPH0 9 + +/* PLL_PERIPH0 exported for PRCM */ + #define CLK_PLL_PERIPH0_2X 10 #define CLK_PLL_GPU 11 #define CLK_PLL_PERIPH1 12 diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index e58706b..6297add 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -537,7 +537,7 @@ static struct ccu_reset_map sun8i_v3s_ccu_resets[] = { [RST_BUS_EMAC] = { 0x2c0, BIT(17) }, [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, - [RST_BUS_OTG] = { 0x2c0, BIT(23) }, + [RST_BUS_OTG] = { 0x2c0, BIT(24) }, [RST_BUS_EHCI0] = { 0x2c0, BIT(26) }, [RST_BUS_OHCI0] = { 0x2c0, BIT(29) }, diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 4bed671..8b5c300 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -1209,9 +1209,9 @@ arch_timer_mem_frame_get_cntfrq(struct arch_timer_mem_frame *frame) return 0; } - rate = readl_relaxed(frame + CNTFRQ); + rate = readl_relaxed(base + CNTFRQ); - iounmap(frame); + iounmap(base); return rate; } diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index 44e5e95..8e64b84 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c @@ -18,6 +18,7 @@ #include <linux/clk.h> #include <linux/interrupt.h> #include <linux/clockchips.h> +#include <linux/clocksource.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/slab.h> diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c index 2e9c830..c4656c4 100644 --- a/drivers/clocksource/timer-sun5i.c +++ b/drivers/clocksource/timer-sun5i.c @@ -12,6 +12,7 @@ #include <linux/clk.h> #include <linux/clockchips.h> +#include <linux/clocksource.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/irq.h> diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 5104b63..c83ea68 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -721,7 +721,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev, u32 set; if (!of_device_is_compatible(mvchip->chip.of_node, - "marvell,armada-370-xp-gpio")) + "marvell,armada-370-gpio")) return 0; if (IS_ERR(mvchip->clk)) @@ -852,7 +852,7 @@ static const struct of_device_id mvebu_gpio_of_match[] = { .data = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP, }, { - .compatible = "marvell,armada-370-xp-gpio", + .compatible = "marvell,armada-370-gpio", .data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION, }, { @@ -1128,7 +1128,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) mvchip); } - /* Armada 370/XP has simple PWM support for GPIO lines */ + /* Some MVEBU SoCs have simple PWM support for GPIO lines */ if (IS_ENABLED(CONFIG_PWM)) return mvebu_pwm_probe(pdev, mvchip, id); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 1cf78f4..1e8e112 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -693,6 +693,10 @@ int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev) DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n", adev->clock.default_dispclk / 100); adev->clock.default_dispclk = 60000; + } else if (adev->clock.default_dispclk <= 60000) { + DRM_INFO("Changing default dispclk from %dMhz to 625Mhz\n", + adev->clock.default_dispclk / 100); + adev->clock.default_dispclk = 62500; } adev->clock.dp_extclk = le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 4c7c262..3e5d550 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -475,6 +475,7 @@ static const struct pci_device_id pciidlist[] = { {0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, {0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, {0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, + {0x1002, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, /* Vega 10 */ {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_crtc.c b/drivers/gpu/drm/amd/amdgpu/atombios_crtc.c index 8c9bc75..8a0818b 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_crtc.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_crtc.c @@ -165,7 +165,7 @@ void amdgpu_atombios_crtc_powergate(struct drm_crtc *crtc, int state) struct drm_device *dev = crtc->dev; struct amdgpu_device *adev = dev->dev_private; int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating); - ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args; + ENABLE_DISP_POWER_GATING_PS_ALLOCATION args; memset(&args, 0, sizeof(args)); @@ -178,7 +178,7 @@ void amdgpu_atombios_crtc_powergate(struct drm_crtc *crtc, int state) void amdgpu_atombios_crtc_powergate_init(struct amdgpu_device *adev) { int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating); - ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args; + ENABLE_DISP_POWER_GATING_PS_ALLOCATION args; memset(&args, 0, sizeof(args)); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 1a3359c..d67b6f1 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -261,21 +261,14 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane, { struct drm_framebuffer *fb = plane->state->fb; struct hdlcd_drm_private *hdlcd; - struct drm_gem_cma_object *gem; - u32 src_x, src_y, dest_h; + u32 dest_h; dma_addr_t scanout_start; if (!fb) return; - src_x = plane->state->src.x1 >> 16; - src_y = plane->state->src.y1 >> 16; dest_h = drm_rect_height(&plane->state->dst); - gem = drm_fb_cma_get_gem_obj(fb, 0); - - scanout_start = gem->paddr + fb->offsets[0] + - src_y * fb->pitches[0] + - src_x * fb->format->cpp[0]; + scanout_start = drm_fb_cma_get_gem_addr(fb, plane->state, 0); hdlcd = plane->dev->dev_private; hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, fb->pitches[0]); diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 345c835..d3da87f 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -297,6 +297,9 @@ static int hdlcd_drm_bind(struct device *dev) if (ret) goto err_free; + /* Set the CRTC's port so that the encoder component can find it */ + hdlcd->crtc.port = of_graph_get_port_by_id(dev->of_node, 0); + ret = component_bind_all(dev, drm); if (ret) { DRM_ERROR("Failed to bind all components\n"); @@ -340,11 +343,14 @@ err_register: } err_fbdev: drm_kms_helper_poll_fini(drm); + drm_vblank_cleanup(drm); err_vblank: pm_runtime_disable(drm->dev); err_pm_active: component_unbind_all(dev, drm); err_unload: + of_node_put(hdlcd->crtc.port); + hdlcd->crtc.port = NULL; drm_irq_uninstall(drm); of_reserved_mem_device_release(drm->dev); err_free: @@ -367,6 +373,9 @@ static void hdlcd_drm_unbind(struct device *dev) } drm_kms_helper_poll_fini(drm); component_unbind_all(dev, drm); + of_node_put(hdlcd->crtc.port); + hdlcd->crtc.port = NULL; + drm_vblank_cleanup(drm); pm_runtime_get_sync(drm->dev); drm_irq_uninstall(drm); pm_runtime_put_sync(drm->dev); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 5cd61af..8072e6e 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1293,21 +1293,6 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, if (!connector) return -ENOENT; - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - encoder = drm_connector_get_encoder(connector); - if (encoder) - out_resp->encoder_id = encoder->base.id; - else - out_resp->encoder_id = 0; - - ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic, - (uint32_t __user *)(unsigned long)(out_resp->props_ptr), - (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr), - &out_resp->count_props); - drm_modeset_unlock(&dev->mode_config.connection_mutex); - if (ret) - goto out_unref; - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) if (connector->encoder_ids[i] != 0) encoders_count++; @@ -1320,7 +1305,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, if (put_user(connector->encoder_ids[i], encoder_ptr + copied)) { ret = -EFAULT; - goto out_unref; + goto out; } copied++; } @@ -1364,15 +1349,32 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, if (copy_to_user(mode_ptr + copied, &u_mode, sizeof(u_mode))) { ret = -EFAULT; + mutex_unlock(&dev->mode_config.mutex); + goto out; } copied++; } } out_resp->count_modes = mode_count; -out: mutex_unlock(&dev->mode_config.mutex); -out_unref: + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + encoder = drm_connector_get_encoder(connector); + if (encoder) + out_resp->encoder_id = encoder->base.id; + else + out_resp->encoder_id = 0; + + /* Only grab properties after probing, to make sure EDID and other + * properties reflect the latest status. */ + ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic, + (uint32_t __user *)(unsigned long)(out_resp->props_ptr), + (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr), + &out_resp->count_props); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + +out: drm_connector_put(connector); return ret; diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 16dccf5..f822731 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -129,7 +129,16 @@ i915-y += i915_vgpu.o # perf code i915-y += i915_perf.o \ - i915_oa_hsw.o + i915_oa_hsw.o \ + i915_oa_bdw.o \ + i915_oa_chv.o \ + i915_oa_sklgt2.o \ + i915_oa_sklgt3.o \ + i915_oa_sklgt4.o \ + i915_oa_bxt.o \ + i915_oa_kblgt2.o \ + i915_oa_kblgt3.o \ + i915_oa_glk.o ifeq ($(CONFIG_DRM_I915_GVT),y) i915-y += intel_gvt.o diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index 44b3159..7aeeffd 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c @@ -217,9 +217,8 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, name = ch7xxx_get_id(vendor); if (!name) { - DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s " - "slave %d.\n", - vendor, adapter->name, dvo->slave_addr); + DRM_DEBUG_KMS("ch7xxx not detected; got VID 0x%02x from %s slave %d.\n", + vendor, adapter->name, dvo->slave_addr); goto out; } @@ -229,9 +228,8 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, devid = ch7xxx_get_did(device); if (!devid) { - DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s " - "slave %d.\n", - vendor, adapter->name, dvo->slave_addr); + DRM_DEBUG_KMS("ch7xxx not detected; got DID 0x%02x from %s slave %d.\n", + device, adapter->name, dvo->slave_addr); goto out; } diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile index b123c20..f5486cb9 100644 --- a/drivers/gpu/drm/i915/gvt/Makefile +++ b/drivers/gpu/drm/i915/gvt/Makefile @@ -3,6 +3,6 @@ GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \ interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \ execlist.o scheduler.o sched_policy.o render.o cmd_parser.o -ccflags-y += -I$(src) -I$(src)/$(GVT_DIR) -Wall +ccflags-y += -I$(src) -I$(src)/$(GVT_DIR) i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE)) obj-$(CONFIG_DRM_I915_GVT_KVMGT) += $(GVT_DIR)/kvmgt.o diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 41b2c3a..51241de5 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -2414,53 +2414,13 @@ static void add_cmd_entry(struct intel_gvt *gvt, struct cmd_entry *e) hash_add(gvt->cmd_table, &e->hlist, e->info->opcode); } -#define GVT_MAX_CMD_LENGTH 20 /* In Dword */ - -static void trace_cs_command(struct parser_exec_state *s, - cycles_t cost_pre_cmd_handler, cycles_t cost_cmd_handler) -{ - /* This buffer is used by ftrace to store all commands copied from - * guest gma space. Sometimes commands can cross pages, this should - * not be handled in ftrace logic. So this is just used as a - * 'bounce buffer' - */ - u32 cmd_trace_buf[GVT_MAX_CMD_LENGTH]; - int i; - u32 cmd_len = cmd_length(s); - /* The chosen value of GVT_MAX_CMD_LENGTH are just based on - * following two considerations: - * 1) From observation, most common ring commands is not that long. - * But there are execeptions. So it indeed makes sence to observe - * longer commands. - * 2) From the performance and debugging point of view, dumping all - * contents of very commands is not necessary. - * We mgith shrink GVT_MAX_CMD_LENGTH or remove this trace event in - * future for performance considerations. - */ - if (unlikely(cmd_len > GVT_MAX_CMD_LENGTH)) { - gvt_dbg_cmd("cmd length exceed tracing limitation!\n"); - cmd_len = GVT_MAX_CMD_LENGTH; - } - - for (i = 0; i < cmd_len; i++) - cmd_trace_buf[i] = cmd_val(s, i); - - trace_gvt_command(s->vgpu->id, s->ring_id, s->ip_gma, cmd_trace_buf, - cmd_len, s->buf_type == RING_BUFFER_INSTRUCTION, - cost_pre_cmd_handler, cost_cmd_handler); -} - /* call the cmd handler, and advance ip */ static int cmd_parser_exec(struct parser_exec_state *s) { + struct intel_vgpu *vgpu = s->vgpu; struct cmd_info *info; u32 cmd; int ret = 0; - cycles_t t0, t1, t2; - struct parser_exec_state s_before_advance_custom; - struct intel_vgpu *vgpu = s->vgpu; - - t0 = get_cycles(); cmd = cmd_val(s, 0); @@ -2471,13 +2431,10 @@ static int cmd_parser_exec(struct parser_exec_state *s) return -EINVAL; } - gvt_dbg_cmd("%s\n", info->name); - s->info = info; - t1 = get_cycles(); - - s_before_advance_custom = *s; + trace_gvt_command(vgpu->id, s->ring_id, s->ip_gma, s->ip_va, + cmd_length(s), s->buf_type); if (info->handler) { ret = info->handler(s); @@ -2486,9 +2443,6 @@ static int cmd_parser_exec(struct parser_exec_state *s) return ret; } } - t2 = get_cycles(); - - trace_cs_command(&s_before_advance_custom, t1 - t0, t2 - t1); if (!(info->flag & F_IP_ADVANCE_CUSTOM)) { ret = cmd_advance_default(s); @@ -2522,8 +2476,6 @@ static int command_scan(struct parser_exec_state *s, gma_tail = rb_start + rb_tail; gma_bottom = rb_start + rb_len; - gvt_dbg_cmd("scan_start: start=%lx end=%lx\n", gma_head, gma_tail); - while (s->ip_gma != gma_tail) { if (s->buf_type == RING_BUFFER_INSTRUCTION) { if (!(s->ip_gma >= rb_start) || @@ -2552,8 +2504,6 @@ static int command_scan(struct parser_exec_state *s, } } - gvt_dbg_cmd("scan_end\n"); - return ret; } diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index 24fe04d..7000505 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -708,53 +708,43 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id, int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id) { struct intel_vgpu_execlist *execlist = &vgpu->execlist[ring_id]; - struct execlist_ctx_descriptor_format *desc[2], valid_desc[2]; - unsigned long valid_desc_bitmap = 0; - bool emulate_schedule_in = true; - int ret; - int i; + struct execlist_ctx_descriptor_format desc[2]; + int i, ret; - memset(valid_desc, 0, sizeof(valid_desc)); + desc[0] = *get_desc_from_elsp_dwords(&execlist->elsp_dwords, 1); + desc[1] = *get_desc_from_elsp_dwords(&execlist->elsp_dwords, 0); - desc[0] = get_desc_from_elsp_dwords(&execlist->elsp_dwords, 1); - desc[1] = get_desc_from_elsp_dwords(&execlist->elsp_dwords, 0); + if (!desc[0].valid) { + gvt_vgpu_err("invalid elsp submission, desc0 is invalid\n"); + goto inv_desc; + } - for (i = 0; i < 2; i++) { - if (!desc[i]->valid) + for (i = 0; i < ARRAY_SIZE(desc); i++) { + if (!desc[i].valid) continue; - - if (!desc[i]->privilege_access) { + if (!desc[i].privilege_access) { gvt_vgpu_err("unexpected GGTT elsp submission\n"); - return -EINVAL; + goto inv_desc; } - - /* TODO: add another guest context checks here. */ - set_bit(i, &valid_desc_bitmap); - valid_desc[i] = *desc[i]; - } - - if (!valid_desc_bitmap) { - gvt_vgpu_err("no valid desc in a elsp submission\n"); - return -EINVAL; - } - - if (!test_bit(0, (void *)&valid_desc_bitmap) && - test_bit(1, (void *)&valid_desc_bitmap)) { - gvt_vgpu_err("weird elsp submission, desc 0 is not valid\n"); - return -EINVAL; } /* submit workload */ - for_each_set_bit(i, (void *)&valid_desc_bitmap, 2) { - ret = submit_context(vgpu, ring_id, &valid_desc[i], - emulate_schedule_in); + for (i = 0; i < ARRAY_SIZE(desc); i++) { + if (!desc[i].valid) + continue; + ret = submit_context(vgpu, ring_id, &desc[i], i == 0); if (ret) { - gvt_vgpu_err("fail to schedule workload\n"); + gvt_vgpu_err("failed to submit desc %d\n", i); return ret; } - emulate_schedule_in = false; } + return 0; + +inv_desc: + gvt_vgpu_err("descriptors content: desc0 %08x %08x desc1 %08x %08x\n", + desc[0].udw, desc[0].ldw, desc[1].udw, desc[1].ldw); + return -EINVAL; } static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id) diff --git a/drivers/gpu/drm/i915/gvt/firmware.c b/drivers/gpu/drm/i915/gvt/firmware.c index dce8d15..5dad929 100644 --- a/drivers/gpu/drm/i915/gvt/firmware.c +++ b/drivers/gpu/drm/i915/gvt/firmware.c @@ -102,13 +102,8 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt) p = firmware + h->mmio_offset; - hash_for_each(gvt->mmio.mmio_info_table, i, e, node) { - int j; - - for (j = 0; j < e->length; j += 4) - *(u32 *)(p + e->offset + j) = - I915_READ_NOTRACE(_MMIO(e->offset + j)); - } + hash_for_each(gvt->mmio.mmio_info_table, i, e, node) + *(u32 *)(p + e->offset) = I915_READ_NOTRACE(_MMIO(e->offset)); memcpy(gvt->firmware.mmio, p, info->mmio_size); diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index c6f0077..66374db 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -244,15 +244,19 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index) return readq(addr); } +static void gtt_invalidate(struct drm_i915_private *dev_priv) +{ + mmio_hw_access_pre(dev_priv); + I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); + mmio_hw_access_post(dev_priv); +} + static void write_pte64(struct drm_i915_private *dev_priv, unsigned long index, u64 pte) { void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index; writeq(pte, addr); - - I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); - POSTING_READ(GFX_FLSH_CNTL_GEN6); } static inline struct intel_gvt_gtt_entry *gtt_get_entry64(void *pt, @@ -1849,6 +1853,7 @@ static int emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, } ggtt_set_shadow_entry(ggtt_mm, &m, g_gtt_index); + gtt_invalidate(gvt->dev_priv); ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index); return 0; } @@ -2301,8 +2306,6 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) u32 num_entries; struct intel_gvt_gtt_entry e; - intel_runtime_pm_get(dev_priv); - memset(&e, 0, sizeof(struct intel_gvt_gtt_entry)); e.type = GTT_TYPE_GGTT_PTE; ops->set_pfn(&e, gvt->gtt.scratch_ggtt_mfn); @@ -2318,7 +2321,7 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) for (offset = 0; offset < num_entries; offset++) ops->set_entry(NULL, &e, index + offset, false, 0, vgpu); - intel_runtime_pm_put(dev_priv); + gtt_invalidate(dev_priv); } /** diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index 7dea5e5..c27c683 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c @@ -147,7 +147,9 @@ static int gvt_service_thread(void *data) mutex_unlock(&gvt->lock); } - if (test_and_clear_bit(INTEL_GVT_REQUEST_SCHED, + if (test_bit(INTEL_GVT_REQUEST_SCHED, + (void *)&gvt->service_request) || + test_bit(INTEL_GVT_REQUEST_EVENT_SCHED, (void *)&gvt->service_request)) { intel_gvt_schedule(gvt); } @@ -244,7 +246,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) gvt_dbg_core("init gvt device\n"); idr_init(&gvt->vgpu_idr); - + spin_lock_init(&gvt->scheduler.mmio_context_lock); mutex_init(&gvt->lock); gvt->dev_priv = dev_priv; diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 930732e..3a74e79 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -165,7 +165,6 @@ struct intel_vgpu { struct list_head workload_q_head[I915_NUM_ENGINES]; struct kmem_cache *workloads; atomic_t running_workload_num; - ktime_t last_ctx_submit_time; DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES); struct i915_gem_context *shadow_ctx; @@ -196,11 +195,27 @@ struct intel_gvt_fence { unsigned long vgpu_allocated_fence_num; }; -#define INTEL_GVT_MMIO_HASH_BITS 9 +#define INTEL_GVT_MMIO_HASH_BITS 11 struct intel_gvt_mmio { - u32 *mmio_attribute; + u8 *mmio_attribute; +/* Register contains RO bits */ +#define F_RO (1 << 0) +/* Register contains graphics address */ +#define F_GMADR (1 << 1) +/* Mode mask registers with high 16 bits as the mask bits */ +#define F_MODE_MASK (1 << 2) +/* This reg can be accessed by GPU commands */ +#define F_CMD_ACCESS (1 << 3) +/* This reg has been accessed by a VM */ +#define F_ACCESSED (1 << 4) +/* This reg has been accessed through GPU commands */ +#define F_CMD_ACCESSED (1 << 5) +/* This reg could be accessed by unaligned address */ +#define F_UNALIGN (1 << 6) + DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS); + unsigned int num_tracked_mmio; }; struct intel_gvt_firmware { @@ -257,7 +272,12 @@ static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915) enum { INTEL_GVT_REQUEST_EMULATE_VBLANK = 0, + + /* Scheduling trigger by timer */ INTEL_GVT_REQUEST_SCHED = 1, + + /* Scheduling trigger by event */ + INTEL_GVT_REQUEST_EVENT_SCHED = 2, }; static inline void intel_gvt_request_service(struct intel_gvt *gvt, @@ -473,6 +493,80 @@ enum { GVT_FAILSAFE_INSUFFICIENT_RESOURCE, }; +static inline void mmio_hw_access_pre(struct drm_i915_private *dev_priv) +{ + intel_runtime_pm_get(dev_priv); +} + +static inline void mmio_hw_access_post(struct drm_i915_private *dev_priv) +{ + intel_runtime_pm_put(dev_priv); +} + +/** + * intel_gvt_mmio_set_accessed - mark a MMIO has been accessed + * @gvt: a GVT device + * @offset: register offset + * + */ +static inline void intel_gvt_mmio_set_accessed( + struct intel_gvt *gvt, unsigned int offset) +{ + gvt->mmio.mmio_attribute[offset >> 2] |= F_ACCESSED; +} + +/** + * intel_gvt_mmio_is_cmd_accessed - mark a MMIO could be accessed by command + * @gvt: a GVT device + * @offset: register offset + * + */ +static inline bool intel_gvt_mmio_is_cmd_access( + struct intel_gvt *gvt, unsigned int offset) +{ + return gvt->mmio.mmio_attribute[offset >> 2] & F_CMD_ACCESS; +} + +/** + * intel_gvt_mmio_is_unalign - mark a MMIO could be accessed unaligned + * @gvt: a GVT device + * @offset: register offset + * + */ +static inline bool intel_gvt_mmio_is_unalign( + struct intel_gvt *gvt, unsigned int offset) +{ + return gvt->mmio.mmio_attribute[offset >> 2] & F_UNALIGN; +} + +/** + * intel_gvt_mmio_set_cmd_accessed - mark a MMIO has been accessed by command + * @gvt: a GVT device + * @offset: register offset + * + */ +static inline void intel_gvt_mmio_set_cmd_accessed( + struct intel_gvt *gvt, unsigned int offset) +{ + gvt->mmio.mmio_attribute[offset >> 2] |= F_CMD_ACCESSED; +} + +/** + * intel_gvt_mmio_has_mode_mask - if a MMIO has a mode mask + * @gvt: a GVT device + * @offset: register offset + * + * Returns: + * True if a MMIO has a mode mask in its higher 16 bits, false if it isn't. + * + */ +static inline bool intel_gvt_mmio_has_mode_mask( + struct intel_gvt *gvt, unsigned int offset) +{ + return gvt->mmio.mmio_attribute[offset >> 2] & F_MODE_MASK; +} + +#include "trace.h" #include "mpt.h" #endif diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 0ffd696..1414d7e 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -47,21 +47,6 @@ #define PCH_PP_OFF_DELAYS _MMIO(0xc720c) #define PCH_PP_DIVISOR _MMIO(0xc7210) -/* Register contains RO bits */ -#define F_RO (1 << 0) -/* Register contains graphics address */ -#define F_GMADR (1 << 1) -/* Mode mask registers with high 16 bits as the mask bits */ -#define F_MODE_MASK (1 << 2) -/* This reg can be accessed by GPU commands */ -#define F_CMD_ACCESS (1 << 3) -/* This reg has been accessed by a VM */ -#define F_ACCESSED (1 << 4) -/* This reg has been accessed through GPU commands */ -#define F_CMD_ACCESSED (1 << 5) -/* This reg could be accessed by unaligned address */ -#define F_UNALIGN (1 << 6) - unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt) { if (IS_BROADWELL(gvt->dev_priv)) @@ -92,11 +77,22 @@ static void write_vreg(struct intel_vgpu *vgpu, unsigned int offset, memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes); } +static struct intel_gvt_mmio_info *find_mmio_info(struct intel_gvt *gvt, + unsigned int offset) +{ + struct intel_gvt_mmio_info *e; + + hash_for_each_possible(gvt->mmio.mmio_info_table, e, node, offset) { + if (e->offset == offset) + return e; + } + return NULL; +} + static int new_mmio_info(struct intel_gvt *gvt, - u32 offset, u32 flags, u32 size, + u32 offset, u8 flags, u32 size, u32 addr_mask, u32 ro_mask, u32 device, - int (*read)(struct intel_vgpu *, unsigned int, void *, unsigned int), - int (*write)(struct intel_vgpu *, unsigned int, void *, unsigned int)) + gvt_mmio_func read, gvt_mmio_func write) { struct intel_gvt_mmio_info *info, *p; u32 start, end, i; @@ -116,13 +112,11 @@ static int new_mmio_info(struct intel_gvt *gvt, return -ENOMEM; info->offset = i; - p = intel_gvt_find_mmio_info(gvt, info->offset); + p = find_mmio_info(gvt, info->offset); if (p) gvt_err("dup mmio definition offset %x\n", info->offset); - info->size = size; - info->length = (i + 4) < end ? 4 : (end - i); - info->addr_mask = addr_mask; + info->ro_mask = ro_mask; info->device = device; info->read = read ? read : intel_vgpu_default_mmio_read; @@ -130,6 +124,7 @@ static int new_mmio_info(struct intel_gvt *gvt, gvt->mmio.mmio_attribute[info->offset / 4] = flags; INIT_HLIST_NODE(&info->node); hash_add(gvt->mmio.mmio_info_table, &info->node, info->offset); + gvt->mmio.num_tracked_mmio++; } return 0; } @@ -209,6 +204,7 @@ static int fence_mmio_read(struct intel_vgpu *vgpu, unsigned int off, static int fence_mmio_write(struct intel_vgpu *vgpu, unsigned int off, void *p_data, unsigned int bytes) { + struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; unsigned int fence_num = offset_to_fence_num(off); int ret; @@ -217,8 +213,10 @@ static int fence_mmio_write(struct intel_vgpu *vgpu, unsigned int off, return ret; write_vreg(vgpu, off, p_data, bytes); + mmio_hw_access_pre(dev_priv); intel_vgpu_write_fence(vgpu, fence_num, vgpu_vreg64(vgpu, fence_num_to_offset(fence_num))); + mmio_hw_access_post(dev_priv); return 0; } @@ -300,6 +298,9 @@ static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, intel_gvt_reset_vgpu_locked(vgpu, false, engine_mask); + /* sw will wait for the device to ack the reset request */ + vgpu_vreg(vgpu, offset) = 0; + return 0; } @@ -1265,7 +1266,10 @@ static int gen9_trtte_write(struct intel_vgpu *vgpu, unsigned int offset, } write_vreg(vgpu, offset, p_data, bytes); /* TRTTE is not per-context */ + + mmio_hw_access_pre(dev_priv); I915_WRITE(_MMIO(offset), vgpu_vreg(vgpu, offset)); + mmio_hw_access_post(dev_priv); return 0; } @@ -1278,7 +1282,9 @@ static int gen9_trtt_chicken_write(struct intel_vgpu *vgpu, unsigned int offset, if (val & 1) { /* unblock hw logic */ + mmio_hw_access_pre(dev_priv); I915_WRITE(_MMIO(offset), val); + mmio_hw_access_post(dev_priv); } write_vreg(vgpu, offset, p_data, bytes); return 0; @@ -1415,7 +1421,20 @@ static int ring_timestamp_mmio_read(struct intel_vgpu *vgpu, { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + mmio_hw_access_pre(dev_priv); vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset)); + mmio_hw_access_post(dev_priv); + return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); +} + +static int instdone_mmio_read(struct intel_vgpu *vgpu, + unsigned int offset, void *p_data, unsigned int bytes) +{ + struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + + mmio_hw_access_pre(dev_priv); + vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset)); + mmio_hw_access_post(dev_priv); return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); } @@ -1434,7 +1453,6 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data; if (execlist->elsp_dwords.index == 3) { - vgpu->last_ctx_submit_time = ktime_get(); ret = intel_vgpu_submit_execlist(vgpu, ring_id); if(ret) gvt_vgpu_err("fail submit workload on ring %d\n", @@ -1603,6 +1621,12 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_RING_DFH(RING_REG, D_ALL, F_CMD_ACCESS, NULL, NULL); #undef RING_REG +#define RING_REG(base) (base + 0x6c) + MMIO_RING_DFH(RING_REG, D_ALL, 0, instdone_mmio_read, NULL); + MMIO_DH(RING_REG(GEN8_BSD2_RING_BASE), D_ALL, instdone_mmio_read, NULL); +#undef RING_REG + MMIO_DH(GEN7_SC_INSTDONE, D_BDW_PLUS, instdone_mmio_read, NULL); + MMIO_GM_RDR(0x2148, D_ALL, NULL, NULL); MMIO_GM_RDR(CCID, D_ALL, NULL, NULL); MMIO_GM_RDR(0x12198, D_ALL, NULL, NULL); @@ -1779,10 +1803,6 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(SPRSCALE(PIPE_C), D_ALL); MMIO_D(SPRSURFLIVE(PIPE_C), D_ALL); - MMIO_F(LGC_PALETTE(PIPE_A, 0), 4 * 256, 0, 0, 0, D_ALL, NULL, NULL); - MMIO_F(LGC_PALETTE(PIPE_B, 0), 4 * 256, 0, 0, 0, D_ALL, NULL, NULL); - MMIO_F(LGC_PALETTE(PIPE_C, 0), 4 * 256, 0, 0, 0, D_ALL, NULL, NULL); - MMIO_D(HTOTAL(TRANSCODER_A), D_ALL); MMIO_D(HBLANK(TRANSCODER_A), D_ALL); MMIO_D(HSYNC(TRANSCODER_A), D_ALL); @@ -2187,7 +2207,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_DFH(GTFIFODBG, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(GTFIFOCTL, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DH(FORCEWAKE_MT, D_PRE_SKL, NULL, mul_force_wake_write); - MMIO_DH(FORCEWAKE_ACK_HSW, D_HSW | D_BDW, NULL, NULL); + MMIO_DH(FORCEWAKE_ACK_HSW, D_BDW, NULL, NULL); MMIO_D(ECOBUS, D_ALL); MMIO_DH(GEN6_RC_CONTROL, D_ALL, NULL, NULL); MMIO_DH(GEN6_RC_STATE, D_ALL, NULL, NULL); @@ -2219,22 +2239,19 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(GEN6_RC6p_THRESHOLD, D_ALL); MMIO_D(GEN6_RC6pp_THRESHOLD, D_ALL); MMIO_D(GEN6_PMINTRMSK, D_ALL); - MMIO_DH(HSW_PWR_WELL_BIOS, D_HSW | D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_DRIVER, D_HSW | D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_KVMR, D_HSW | D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_DEBUG, D_HSW | D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_CTL5, D_HSW | D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_CTL6, D_HSW | D_BDW, NULL, power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_BIOS, D_BDW, NULL, power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_DRIVER, D_BDW, NULL, power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_DEBUG, D_BDW, NULL, power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_CTL5, D_BDW, NULL, power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_CTL6, D_BDW, NULL, power_well_ctl_mmio_write); MMIO_D(RSTDBYCTL, D_ALL); MMIO_DH(GEN6_GDRST, D_ALL, NULL, gdrst_mmio_write); MMIO_F(FENCE_REG_GEN6_LO(0), 0x80, 0, 0, 0, D_ALL, fence_mmio_read, fence_mmio_write); - MMIO_F(VGT_PVINFO_PAGE, VGT_PVINFO_SIZE, F_UNALIGN, 0, 0, D_ALL, pvinfo_mmio_read, pvinfo_mmio_write); MMIO_DH(CPU_VGACNTRL, D_ALL, NULL, vga_control_mmio_write); - MMIO_F(MCHBAR_MIRROR_BASE_SNB, 0x40000, 0, 0, 0, D_ALL, NULL, NULL); - MMIO_D(TILECTL, D_ALL); MMIO_D(GEN6_UCGCTL1, D_ALL); @@ -2242,7 +2259,6 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_F(0x4f000, 0x90, 0, 0, 0, D_ALL, NULL, NULL); - MMIO_D(GEN6_PCODE_MAILBOX, D_PRE_BDW); MMIO_D(GEN6_PCODE_DATA, D_ALL); MMIO_D(0x13812c, D_ALL); MMIO_DH(GEN7_ERR_INT, D_ALL, NULL, NULL); @@ -2321,14 +2337,13 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(0x1a054, D_ALL); MMIO_D(0x44070, D_ALL); - MMIO_DFH(0x215c, D_HSW_PLUS, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(0x215c, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(0x2178, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(0x217c, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(0x12178, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_DFH(0x1217c, D_ALL, F_CMD_ACCESS, NULL, NULL); - MMIO_F(0x2290, 8, F_CMD_ACCESS, 0, 0, D_HSW_PLUS, NULL, NULL); - MMIO_DFH(GEN7_OACONTROL, D_HSW, F_CMD_ACCESS, NULL, NULL); + MMIO_F(0x2290, 8, F_CMD_ACCESS, 0, 0, D_BDW_PLUS, NULL, NULL); MMIO_D(0x2b00, D_BDW_PLUS); MMIO_D(0x2360, D_BDW_PLUS); MMIO_F(0x5200, 32, F_CMD_ACCESS, 0, 0, D_ALL, NULL, NULL); @@ -2766,7 +2781,6 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_D(0x72380, D_SKL_PLUS); MMIO_D(0x7039c, D_SKL_PLUS); - MMIO_F(0x80000, 0x3000, 0, 0, 0, D_SKL_PLUS, NULL, NULL); MMIO_D(0x8f074, D_SKL | D_KBL); MMIO_D(0x8f004, D_SKL | D_KBL); MMIO_D(0x8f034, D_SKL | D_KBL); @@ -2840,26 +2854,36 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) return 0; } -/** - * intel_gvt_find_mmio_info - find MMIO information entry by aligned offset - * @gvt: GVT device - * @offset: register offset - * - * This function is used to find the MMIO information entry from hash table - * - * Returns: - * pointer to MMIO information entry, NULL if not exists - */ -struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt, - unsigned int offset) -{ - struct intel_gvt_mmio_info *e; +/* Special MMIO blocks. */ +static struct gvt_mmio_block { + unsigned int device; + i915_reg_t offset; + unsigned int size; + gvt_mmio_func read; + gvt_mmio_func write; +} gvt_mmio_blocks[] = { + {D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL}, + {D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL}, + {D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE, + pvinfo_mmio_read, pvinfo_mmio_write}, + {D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL}, + {D_ALL, LGC_PALETTE(PIPE_B, 0), 1024, NULL, NULL}, + {D_ALL, LGC_PALETTE(PIPE_C, 0), 1024, NULL, NULL}, +}; - WARN_ON(!IS_ALIGNED(offset, 4)); +static struct gvt_mmio_block *find_mmio_block(struct intel_gvt *gvt, + unsigned int offset) +{ + unsigned long device = intel_gvt_get_device_type(gvt); + struct gvt_mmio_block *block = gvt_mmio_blocks; + int i; - hash_for_each_possible(gvt->mmio.mmio_info_table, e, node, offset) { - if (e->offset == offset) - return e; + for (i = 0; i < ARRAY_SIZE(gvt_mmio_blocks); i++, block++) { + if (!(device & block->device)) + continue; + if (offset >= INTEL_GVT_MMIO_OFFSET(block->offset) && + offset < INTEL_GVT_MMIO_OFFSET(block->offset) + block->size) + return block; } return NULL; } @@ -2899,9 +2923,10 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt) { struct intel_gvt_device_info *info = &gvt->device_info; struct drm_i915_private *dev_priv = gvt->dev_priv; + int size = info->mmio_size / 4 * sizeof(*gvt->mmio.mmio_attribute); int ret; - gvt->mmio.mmio_attribute = vzalloc(info->mmio_size); + gvt->mmio.mmio_attribute = vzalloc(size); if (!gvt->mmio.mmio_attribute) return -ENOMEM; @@ -2922,77 +2947,15 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt) if (ret) goto err; } + + gvt_dbg_mmio("traced %u virtual mmio registers\n", + gvt->mmio.num_tracked_mmio); return 0; err: intel_gvt_clean_mmio_info(gvt); return ret; } -/** - * intel_gvt_mmio_set_accessed - mark a MMIO has been accessed - * @gvt: a GVT device - * @offset: register offset - * - */ -void intel_gvt_mmio_set_accessed(struct intel_gvt *gvt, unsigned int offset) -{ - gvt->mmio.mmio_attribute[offset >> 2] |= - F_ACCESSED; -} - -/** - * intel_gvt_mmio_is_cmd_accessed - mark a MMIO could be accessed by command - * @gvt: a GVT device - * @offset: register offset - * - */ -bool intel_gvt_mmio_is_cmd_access(struct intel_gvt *gvt, - unsigned int offset) -{ - return gvt->mmio.mmio_attribute[offset >> 2] & - F_CMD_ACCESS; -} - -/** - * intel_gvt_mmio_is_unalign - mark a MMIO could be accessed unaligned - * @gvt: a GVT device - * @offset: register offset - * - */ -bool intel_gvt_mmio_is_unalign(struct intel_gvt *gvt, - unsigned int offset) -{ - return gvt->mmio.mmio_attribute[offset >> 2] & - F_UNALIGN; -} - -/** - * intel_gvt_mmio_set_cmd_accessed - mark a MMIO has been accessed by command - * @gvt: a GVT device - * @offset: register offset - * - */ -void intel_gvt_mmio_set_cmd_accessed(struct intel_gvt *gvt, - unsigned int offset) -{ - gvt->mmio.mmio_attribute[offset >> 2] |= - F_CMD_ACCESSED; -} - -/** - * intel_gvt_mmio_has_mode_mask - if a MMIO has a mode mask - * @gvt: a GVT device - * @offset: register offset - * - * Returns: - * True if a MMIO has a mode mask in its higher 16 bits, false if it isn't. - * - */ -bool intel_gvt_mmio_has_mode_mask(struct intel_gvt *gvt, unsigned int offset) -{ - return gvt->mmio.mmio_attribute[offset >> 2] & - F_MODE_MASK; -} /** * intel_vgpu_default_mmio_read - default MMIO read handler @@ -3044,3 +3007,91 @@ bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt, { return in_whitelist(offset); } + +/** + * intel_vgpu_mmio_reg_rw - emulate tracked mmio registers + * @vgpu: a vGPU + * @offset: register offset + * @pdata: data buffer + * @bytes: data length + * + * Returns: + * Zero on success, negative error code if failed. + */ +int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset, + void *pdata, unsigned int bytes, bool is_read) +{ + struct intel_gvt *gvt = vgpu->gvt; + struct intel_gvt_mmio_info *mmio_info; + struct gvt_mmio_block *mmio_block; + gvt_mmio_func func; + int ret; + + if (WARN_ON(bytes > 4)) + return -EINVAL; + + /* + * Handle special MMIO blocks. + */ + mmio_block = find_mmio_block(gvt, offset); + if (mmio_block) { + func = is_read ? mmio_block->read : mmio_block->write; + if (func) + return func(vgpu, offset, pdata, bytes); + goto default_rw; + } + + /* + * Normal tracked MMIOs. + */ + mmio_info = find_mmio_info(gvt, offset); + if (!mmio_info) { + if (!vgpu->mmio.disable_warn_untrack) + gvt_vgpu_err("untracked MMIO %08x len %d\n", + offset, bytes); + goto default_rw; + } + + if (is_read) + return mmio_info->read(vgpu, offset, pdata, bytes); + else { + u64 ro_mask = mmio_info->ro_mask; + u32 old_vreg = 0, old_sreg = 0; + u64 data = 0; + + if (intel_gvt_mmio_has_mode_mask(gvt, mmio_info->offset)) { + old_vreg = vgpu_vreg(vgpu, offset); + old_sreg = vgpu_sreg(vgpu, offset); + } + + if (likely(!ro_mask)) + ret = mmio_info->write(vgpu, offset, pdata, bytes); + else if (!~ro_mask) { + gvt_vgpu_err("try to write RO reg %x\n", offset); + return 0; + } else { + /* keep the RO bits in the virtual register */ + memcpy(&data, pdata, bytes); + data &= ~ro_mask; + data |= vgpu_vreg(vgpu, offset) & ro_mask; + ret = mmio_info->write(vgpu, offset, &data, bytes); + } + + /* higher 16bits of mode ctl regs are mask bits for change */ + if (intel_gvt_mmio_has_mode_mask(gvt, mmio_info->offset)) { + u32 mask = vgpu_vreg(vgpu, offset) >> 16; + + vgpu_vreg(vgpu, offset) = (old_vreg & ~mask) + | (vgpu_vreg(vgpu, offset) & mask); + vgpu_sreg(vgpu, offset) = (old_sreg & ~mask) + | (vgpu_sreg(vgpu, offset) & mask); + } + } + + return ret; + +default_rw: + return is_read ? + intel_vgpu_default_mmio_read(vgpu, offset, pdata, bytes) : + intel_vgpu_default_mmio_write(vgpu, offset, pdata, bytes); +} diff --git a/drivers/gpu/drm/i915/gvt/interrupt.c b/drivers/gpu/drm/i915/gvt/interrupt.c index 9d6812f..7a041b3 100644 --- a/drivers/gpu/drm/i915/gvt/interrupt.c +++ b/drivers/gpu/drm/i915/gvt/interrupt.c @@ -31,6 +31,7 @@ #include "i915_drv.h" #include "gvt.h" +#include "trace.h" /* common offset among interrupt control registers */ #define regbase_to_isr(base) (base) @@ -178,8 +179,8 @@ int intel_vgpu_reg_imr_handler(struct intel_vgpu *vgpu, struct intel_gvt_irq_ops *ops = gvt->irq.ops; u32 imr = *(u32 *)p_data; - gvt_dbg_irq("write IMR %x, new %08x, old %08x, changed %08x\n", - reg, imr, vgpu_vreg(vgpu, reg), vgpu_vreg(vgpu, reg) ^ imr); + trace_write_ir(vgpu->id, "IMR", reg, imr, vgpu_vreg(vgpu, reg), + (vgpu_vreg(vgpu, reg) ^ imr)); vgpu_vreg(vgpu, reg) = imr; @@ -209,8 +210,8 @@ int intel_vgpu_reg_master_irq_handler(struct intel_vgpu *vgpu, u32 ier = *(u32 *)p_data; u32 virtual_ier = vgpu_vreg(vgpu, reg); - gvt_dbg_irq("write MASTER_IRQ %x, new %08x, old %08x, changed %08x\n", - reg, ier, virtual_ier, virtual_ier ^ ier); + trace_write_ir(vgpu->id, "MASTER_IRQ", reg, ier, virtual_ier, + (virtual_ier ^ ier)); /* * GEN8_MASTER_IRQ is a special irq register, @@ -248,8 +249,8 @@ int intel_vgpu_reg_ier_handler(struct intel_vgpu *vgpu, struct intel_gvt_irq_info *info; u32 ier = *(u32 *)p_data; - gvt_dbg_irq("write IER %x, new %08x, old %08x, changed %08x\n", - reg, ier, vgpu_vreg(vgpu, reg), vgpu_vreg(vgpu, reg) ^ ier); + trace_write_ir(vgpu->id, "IER", reg, ier, vgpu_vreg(vgpu, reg), + (vgpu_vreg(vgpu, reg) ^ ier)); vgpu_vreg(vgpu, reg) = ier; @@ -285,8 +286,8 @@ int intel_vgpu_reg_iir_handler(struct intel_vgpu *vgpu, unsigned int reg, iir_to_regbase(reg)); u32 iir = *(u32 *)p_data; - gvt_dbg_irq("write IIR %x, new %08x, old %08x, changed %08x\n", - reg, iir, vgpu_vreg(vgpu, reg), vgpu_vreg(vgpu, reg) ^ iir); + trace_write_ir(vgpu->id, "IIR", reg, iir, vgpu_vreg(vgpu, reg), + (vgpu_vreg(vgpu, reg) ^ iir)); if (WARN_ON(!info)) return -EINVAL; @@ -411,8 +412,7 @@ static void propagate_event(struct intel_gvt_irq *irq, if (!test_bit(bit, (void *)&vgpu_vreg(vgpu, regbase_to_imr(reg_base)))) { - gvt_dbg_irq("set bit (%d) for (%s) for vgpu (%d)\n", - bit, irq_name[event], vgpu->id); + trace_propagate_event(vgpu->id, irq_name[event], bit); set_bit(bit, (void *)&vgpu_vreg(vgpu, regbase_to_iir(reg_base))); } diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index 1ba3bdb..980ec89 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -123,7 +123,6 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, void *p_data, unsigned int bytes) { struct intel_gvt *gvt = vgpu->gvt; - struct intel_gvt_mmio_info *mmio; unsigned int offset = 0; int ret = -EINVAL; @@ -187,32 +186,8 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, goto err; } - mmio = intel_gvt_find_mmio_info(gvt, rounddown(offset, 4)); - if (mmio) { - if (!intel_gvt_mmio_is_unalign(gvt, mmio->offset)) { - if (WARN_ON(offset + bytes > mmio->offset + mmio->size)) - goto err; - if (WARN_ON(mmio->offset != offset)) - goto err; - } - ret = mmio->read(vgpu, offset, p_data, bytes); - } else { - ret = intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); - - if (!vgpu->mmio.disable_warn_untrack) { - gvt_vgpu_err("read untracked MMIO %x(%dB) val %x\n", - offset, bytes, *(u32 *)p_data); - - if (offset == 0x206c) { - gvt_vgpu_err("------------------------------------------\n"); - gvt_vgpu_err("likely triggers a gfx reset\n"); - gvt_vgpu_err("------------------------------------------\n"); - vgpu->mmio.disable_warn_untrack = true; - } - } - } - - if (ret) + ret = intel_vgpu_mmio_reg_rw(vgpu, offset, p_data, bytes, true); + if (ret < 0) goto err; intel_gvt_mmio_set_accessed(gvt, offset); @@ -239,9 +214,7 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, void *p_data, unsigned int bytes) { struct intel_gvt *gvt = vgpu->gvt; - struct intel_gvt_mmio_info *mmio; unsigned int offset = 0; - u32 old_vreg = 0, old_sreg = 0; int ret = -EINVAL; if (vgpu->failsafe) { @@ -296,66 +269,10 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, return ret; } - mmio = intel_gvt_find_mmio_info(gvt, rounddown(offset, 4)); - if (!mmio && !vgpu->mmio.disable_warn_untrack) - gvt_dbg_mmio("vgpu%d: write untracked MMIO %x len %d val %x\n", - vgpu->id, offset, bytes, *(u32 *)p_data); - - if (!intel_gvt_mmio_is_unalign(gvt, offset)) { - if (WARN_ON(!IS_ALIGNED(offset, bytes))) - goto err; - } - - if (mmio) { - u64 ro_mask = mmio->ro_mask; - - if (!intel_gvt_mmio_is_unalign(gvt, mmio->offset)) { - if (WARN_ON(offset + bytes > mmio->offset + mmio->size)) - goto err; - if (WARN_ON(mmio->offset != offset)) - goto err; - } - - if (intel_gvt_mmio_has_mode_mask(gvt, mmio->offset)) { - old_vreg = vgpu_vreg(vgpu, offset); - old_sreg = vgpu_sreg(vgpu, offset); - } - - if (!ro_mask) { - ret = mmio->write(vgpu, offset, p_data, bytes); - } else { - /* Protect RO bits like HW */ - u64 data = 0; - - /* all register bits are RO. */ - if (ro_mask == ~(u64)0) { - gvt_vgpu_err("try to write RO reg %x\n", - offset); - ret = 0; - goto out; - } - /* keep the RO bits in the virtual register */ - memcpy(&data, p_data, bytes); - data &= ~mmio->ro_mask; - data |= vgpu_vreg(vgpu, offset) & mmio->ro_mask; - ret = mmio->write(vgpu, offset, &data, bytes); - } - - /* higher 16bits of mode ctl regs are mask bits for change */ - if (intel_gvt_mmio_has_mode_mask(gvt, mmio->offset)) { - u32 mask = vgpu_vreg(vgpu, offset) >> 16; - - vgpu_vreg(vgpu, offset) = (old_vreg & ~mask) - | (vgpu_vreg(vgpu, offset) & mask); - vgpu_sreg(vgpu, offset) = (old_sreg & ~mask) - | (vgpu_sreg(vgpu, offset) & mask); - } - } else - ret = intel_vgpu_default_mmio_write(vgpu, offset, p_data, - bytes); - if (ret) + ret = intel_vgpu_mmio_reg_rw(vgpu, offset, p_data, bytes, false); + if (ret < 0) goto err; -out: + intel_gvt_mmio_set_accessed(gvt, offset); mutex_unlock(&gvt->lock); return 0; @@ -372,20 +289,32 @@ err: * @vgpu: a vGPU * */ -void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu) +void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr) { struct intel_gvt *gvt = vgpu->gvt; const struct intel_gvt_device_info *info = &gvt->device_info; + void *mmio = gvt->firmware.mmio; + + if (dmlr) { + memcpy(vgpu->mmio.vreg, mmio, info->mmio_size); + memcpy(vgpu->mmio.sreg, mmio, info->mmio_size); - memcpy(vgpu->mmio.vreg, gvt->firmware.mmio, info->mmio_size); - memcpy(vgpu->mmio.sreg, gvt->firmware.mmio, info->mmio_size); + vgpu_vreg(vgpu, GEN6_GT_THREAD_STATUS_REG) = 0; - vgpu_vreg(vgpu, GEN6_GT_THREAD_STATUS_REG) = 0; + /* set the bit 0:2(Core C-State ) to C0 */ + vgpu_vreg(vgpu, GEN6_GT_CORE_STATUS) = 0; - /* set the bit 0:2(Core C-State ) to C0 */ - vgpu_vreg(vgpu, GEN6_GT_CORE_STATUS) = 0; + vgpu->mmio.disable_warn_untrack = false; + } else { +#define GVT_GEN8_MMIO_RESET_OFFSET (0x44200) + /* only reset the engine related, so starting with 0x44200 + * interrupt include DE,display mmio related will not be + * touched + */ + memcpy(vgpu->mmio.vreg, mmio, GVT_GEN8_MMIO_RESET_OFFSET); + memcpy(vgpu->mmio.sreg, mmio, GVT_GEN8_MMIO_RESET_OFFSET); + } - vgpu->mmio.disable_warn_untrack = false; } /** @@ -405,7 +334,7 @@ int intel_vgpu_init_mmio(struct intel_vgpu *vgpu) vgpu->mmio.sreg = vgpu->mmio.vreg + info->mmio_size; - intel_vgpu_reset_mmio(vgpu); + intel_vgpu_reset_mmio(vgpu, true); return 0; } diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h index 7edd66f..32cd64d 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.h +++ b/drivers/gpu/drm/i915/gvt/mmio.h @@ -39,36 +39,28 @@ struct intel_gvt; struct intel_vgpu; -#define D_SNB (1 << 0) -#define D_IVB (1 << 1) -#define D_HSW (1 << 2) -#define D_BDW (1 << 3) -#define D_SKL (1 << 4) -#define D_KBL (1 << 5) +#define D_BDW (1 << 0) +#define D_SKL (1 << 1) +#define D_KBL (1 << 2) #define D_GEN9PLUS (D_SKL | D_KBL) #define D_GEN8PLUS (D_BDW | D_SKL | D_KBL) -#define D_GEN75PLUS (D_HSW | D_BDW | D_SKL | D_KBL) -#define D_GEN7PLUS (D_IVB | D_HSW | D_BDW | D_SKL | D_KBL) #define D_SKL_PLUS (D_SKL | D_KBL) #define D_BDW_PLUS (D_BDW | D_SKL | D_KBL) -#define D_HSW_PLUS (D_HSW | D_BDW | D_SKL | D_KBL) -#define D_IVB_PLUS (D_IVB | D_HSW | D_BDW | D_SKL | D_KBL) -#define D_PRE_BDW (D_SNB | D_IVB | D_HSW) -#define D_PRE_SKL (D_SNB | D_IVB | D_HSW | D_BDW) -#define D_ALL (D_SNB | D_IVB | D_HSW | D_BDW | D_SKL | D_KBL) +#define D_PRE_SKL (D_BDW) +#define D_ALL (D_BDW | D_SKL | D_KBL) + +typedef int (*gvt_mmio_func)(struct intel_vgpu *, unsigned int, void *, + unsigned int); struct intel_gvt_mmio_info { u32 offset; - u32 size; - u32 length; - u32 addr_mask; u64 ro_mask; u32 device; - int (*read)(struct intel_vgpu *, unsigned int, void *, unsigned int); - int (*write)(struct intel_vgpu *, unsigned int, void *, unsigned int); + gvt_mmio_func read; + gvt_mmio_func write; u32 addr_range; struct hlist_node node; }; @@ -79,8 +71,6 @@ bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device); int intel_gvt_setup_mmio_info(struct intel_gvt *gvt); void intel_gvt_clean_mmio_info(struct intel_gvt *gvt); -struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt, - unsigned int offset); #define INTEL_GVT_MMIO_OFFSET(reg) ({ \ typeof(reg) __reg = reg; \ u32 *offset = (u32 *)&__reg; \ @@ -88,7 +78,7 @@ struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt, }) int intel_vgpu_init_mmio(struct intel_vgpu *vgpu); -void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu); +void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr); void intel_vgpu_clean_mmio(struct intel_vgpu *vgpu); int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa); @@ -97,13 +87,7 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, u64 pa, void *p_data, unsigned int bytes); int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, u64 pa, void *p_data, unsigned int bytes); -bool intel_gvt_mmio_is_cmd_access(struct intel_gvt *gvt, - unsigned int offset); -bool intel_gvt_mmio_is_unalign(struct intel_gvt *gvt, unsigned int offset); -void intel_gvt_mmio_set_accessed(struct intel_gvt *gvt, unsigned int offset); -void intel_gvt_mmio_set_cmd_accessed(struct intel_gvt *gvt, - unsigned int offset); -bool intel_gvt_mmio_has_mode_mask(struct intel_gvt *gvt, unsigned int offset); + int intel_vgpu_default_mmio_read(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes); int intel_vgpu_default_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, @@ -111,4 +95,8 @@ int intel_vgpu_default_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt, unsigned int offset); + +int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset, + void *pdata, unsigned int bytes, bool is_read); + #endif diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h index 4193536..f0e5487 100644 --- a/drivers/gpu/drm/i915/gvt/mpt.h +++ b/drivers/gpu/drm/i915/gvt/mpt.h @@ -133,8 +133,7 @@ static inline int intel_gvt_hypervisor_inject_msi(struct intel_vgpu *vgpu) if (WARN(control & GENMASK(15, 1), "only support one MSI format\n")) return -EINVAL; - gvt_dbg_irq("vgpu%d: inject msi address %x data%x\n", vgpu->id, addr, - data); + trace_inject_msi(vgpu->id, addr, data); ret = intel_gvt_host.mpt->inject_msi(vgpu->handle, addr, data); if (ret) diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c index a5e11d8..504e57c 100644 --- a/drivers/gpu/drm/i915/gvt/render.c +++ b/drivers/gpu/drm/i915/gvt/render.c @@ -35,6 +35,7 @@ #include "i915_drv.h" #include "gvt.h" +#include "trace.h" struct render_mmio { int ring_id; @@ -260,7 +261,8 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id) #define CTX_CONTEXT_CONTROL_VAL 0x03 -void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id) +/* Switch ring mmio values (context) from host to a vgpu. */ +static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct render_mmio *mmio; @@ -305,14 +307,15 @@ void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id) I915_WRITE(mmio->reg, v); POSTING_READ(mmio->reg); - gvt_dbg_render("load reg %x old %x new %x\n", - i915_mmio_reg_offset(mmio->reg), - mmio->value, v); + trace_render_mmio(vgpu->id, "load", + i915_mmio_reg_offset(mmio->reg), + mmio->value, v); } handle_tlb_pending_event(vgpu, ring_id); } -void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id) +/* Switch ring mmio values (context) from vgpu to host. */ +static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct render_mmio *mmio; @@ -346,8 +349,37 @@ void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id) I915_WRITE(mmio->reg, v); POSTING_READ(mmio->reg); - gvt_dbg_render("restore reg %x old %x new %x\n", - i915_mmio_reg_offset(mmio->reg), - mmio->value, v); + trace_render_mmio(vgpu->id, "restore", + i915_mmio_reg_offset(mmio->reg), + mmio->value, v); } } + +/** + * intel_gvt_switch_render_mmio - switch mmio context of specific engine + * @pre: the last vGPU that own the engine + * @next: the vGPU to switch to + * @ring_id: specify the engine + * + * If pre is null indicates that host own the engine. If next is null + * indicates that we are switching to host workload. + */ +void intel_gvt_switch_mmio(struct intel_vgpu *pre, + struct intel_vgpu *next, int ring_id) +{ + if (WARN_ON(!pre && !next)) + return; + + gvt_dbg_render("switch ring %d from %s to %s\n", ring_id, + pre ? "vGPU" : "host", next ? "vGPU" : "HOST"); + + /** + * TODO: Optimize for vGPU to vGPU switch by merging + * switch_mmio_to_host() and switch_mmio_to_vgpu(). + */ + if (pre) + switch_mmio_to_host(pre, ring_id); + + if (next) + switch_mmio_to_vgpu(next, ring_id); +} diff --git a/drivers/gpu/drm/i915/gvt/render.h b/drivers/gpu/drm/i915/gvt/render.h index dac1a3c..91db1d3 100644 --- a/drivers/gpu/drm/i915/gvt/render.h +++ b/drivers/gpu/drm/i915/gvt/render.h @@ -36,8 +36,8 @@ #ifndef __GVT_RENDER_H__ #define __GVT_RENDER_H__ -void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id); +void intel_gvt_switch_mmio(struct intel_vgpu *pre, + struct intel_vgpu *next, int ring_id); -void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id); #endif diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c index f25ff13..436377d 100644 --- a/drivers/gpu/drm/i915/gvt/sched_policy.c +++ b/drivers/gpu/drm/i915/gvt/sched_policy.c @@ -202,11 +202,6 @@ static void tbs_sched_func(struct gvt_sched_data *sched_data) struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; struct vgpu_sched_data *vgpu_data; struct intel_vgpu *vgpu = NULL; - static uint64_t timer_check; - - if (!(timer_check++ % GVT_TS_BALANCE_PERIOD_MS)) - gvt_balance_timeslice(sched_data); - /* no active vgpu or has already had a target */ if (list_empty(&sched_data->lru_runq_head) || scheduler->next_vgpu) goto out; @@ -231,9 +226,19 @@ out: void intel_gvt_schedule(struct intel_gvt *gvt) { struct gvt_sched_data *sched_data = gvt->scheduler.sched_data; + static uint64_t timer_check; mutex_lock(&gvt->lock); + + if (test_and_clear_bit(INTEL_GVT_REQUEST_SCHED, + (void *)&gvt->service_request)) { + if (!(timer_check++ % GVT_TS_BALANCE_PERIOD_MS)) + gvt_balance_timeslice(sched_data); + } + clear_bit(INTEL_GVT_REQUEST_EVENT_SCHED, (void *)&gvt->service_request); + tbs_sched_func(sched_data); + mutex_unlock(&gvt->lock); } @@ -303,8 +308,20 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu) static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu) { + struct intel_gvt_workload_scheduler *scheduler = &vgpu->gvt->scheduler; + int ring_id; + kfree(vgpu->sched_data); vgpu->sched_data = NULL; + + spin_lock_bh(&scheduler->mmio_context_lock); + for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) { + if (scheduler->engine_owner[ring_id] == vgpu) { + intel_gvt_switch_mmio(vgpu, NULL, ring_id); + scheduler->engine_owner[ring_id] = NULL; + } + } + spin_unlock_bh(&scheduler->mmio_context_lock); } static void tbs_sched_start_schedule(struct intel_vgpu *vgpu) diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 6ae286c..488fdea 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -138,21 +138,42 @@ static int shadow_context_status_change(struct notifier_block *nb, struct intel_gvt *gvt = container_of(nb, struct intel_gvt, shadow_ctx_notifier_block[req->engine->id]); struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; - struct intel_vgpu_workload *workload = - scheduler->current_workload[req->engine->id]; + enum intel_engine_id ring_id = req->engine->id; + struct intel_vgpu_workload *workload; + + if (!is_gvt_request(req)) { + spin_lock_bh(&scheduler->mmio_context_lock); + if (action == INTEL_CONTEXT_SCHEDULE_IN && + scheduler->engine_owner[ring_id]) { + /* Switch ring from vGPU to host. */ + intel_gvt_switch_mmio(scheduler->engine_owner[ring_id], + NULL, ring_id); + scheduler->engine_owner[ring_id] = NULL; + } + spin_unlock_bh(&scheduler->mmio_context_lock); - if (!is_gvt_request(req) || unlikely(!workload)) + return NOTIFY_OK; + } + + workload = scheduler->current_workload[ring_id]; + if (unlikely(!workload)) return NOTIFY_OK; switch (action) { case INTEL_CONTEXT_SCHEDULE_IN: - intel_gvt_load_render_mmio(workload->vgpu, - workload->ring_id); + spin_lock_bh(&scheduler->mmio_context_lock); + if (workload->vgpu != scheduler->engine_owner[ring_id]) { + /* Switch ring from host to vGPU or vGPU to vGPU. */ + intel_gvt_switch_mmio(scheduler->engine_owner[ring_id], + workload->vgpu, ring_id); + scheduler->engine_owner[ring_id] = workload->vgpu; + } else + gvt_dbg_sched("skip ring %d mmio switch for vgpu%d\n", + ring_id, workload->vgpu->id); + spin_unlock_bh(&scheduler->mmio_context_lock); atomic_set(&workload->shadow_ctx_active, 1); break; case INTEL_CONTEXT_SCHEDULE_OUT: - intel_gvt_restore_render_mmio(workload->vgpu, - workload->ring_id); /* If the status is -EINPROGRESS means this workload * doesn't meet any issue during dispatching so when * get the SCHEDULE_OUT set the status to be zero for @@ -431,6 +452,10 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id) atomic_dec(&vgpu->running_workload_num); wake_up(&scheduler->workload_complete_wq); + + if (gvt->scheduler.need_reschedule) + intel_gvt_request_service(gvt, INTEL_GVT_REQUEST_EVENT_SCHED); + mutex_unlock(&gvt->lock); } diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h index 2cd725c..9b6bf51 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.h +++ b/drivers/gpu/drm/i915/gvt/scheduler.h @@ -42,6 +42,10 @@ struct intel_gvt_workload_scheduler { struct intel_vgpu_workload *current_workload[I915_NUM_ENGINES]; bool need_reschedule; + spinlock_t mmio_context_lock; + /* can be null when owner is host */ + struct intel_vgpu *engine_owner[I915_NUM_ENGINES]; + wait_queue_head_t workload_complete_wq; struct task_struct *thread[I915_NUM_ENGINES]; wait_queue_head_t waitq[I915_NUM_ENGINES]; diff --git a/drivers/gpu/drm/i915/gvt/trace.h b/drivers/gpu/drm/i915/gvt/trace.h index 53a2d10..8c15038 100644 --- a/drivers/gpu/drm/i915/gvt/trace.h +++ b/drivers/gpu/drm/i915/gvt/trace.h @@ -224,58 +224,138 @@ TRACE_EVENT(oos_sync, TP_printk("%s", __entry->buf) ); -#define MAX_CMD_STR_LEN 256 TRACE_EVENT(gvt_command, - TP_PROTO(u8 vm_id, u8 ring_id, u32 ip_gma, u32 *cmd_va, u32 cmd_len, bool ring_buffer_cmd, cycles_t cost_pre_cmd_handler, cycles_t cost_cmd_handler), - - TP_ARGS(vm_id, ring_id, ip_gma, cmd_va, cmd_len, ring_buffer_cmd, cost_pre_cmd_handler, cost_cmd_handler), - - TP_STRUCT__entry( - __field(u8, vm_id) - __field(u8, ring_id) - __field(int, i) - __array(char, tmp_buf, MAX_CMD_STR_LEN) - __array(char, cmd_str, MAX_CMD_STR_LEN) - ), - - TP_fast_assign( - __entry->vm_id = vm_id; - __entry->ring_id = ring_id; - __entry->cmd_str[0] = '\0'; - snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "VM(%d) Ring(%d): %s ip(%08x) pre handler cost (%llu), handler cost (%llu) ", vm_id, ring_id, ring_buffer_cmd ? "RB":"BB", ip_gma, cost_pre_cmd_handler, cost_cmd_handler); - strcat(__entry->cmd_str, __entry->tmp_buf); - entry->i = 0; - while (cmd_len > 0) { - if (cmd_len >= 8) { - snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x %08x %08x %08x %08x %08x %08x %08x ", - cmd_va[__entry->i], cmd_va[__entry->i+1], cmd_va[__entry->i+2], cmd_va[__entry->i+3], - cmd_va[__entry->i+4], cmd_va[__entry->i+5], cmd_va[__entry->i+6], cmd_va[__entry->i+7]); - __entry->i += 8; - cmd_len -= 8; - strcat(__entry->cmd_str, __entry->tmp_buf); - } else if (cmd_len >= 4) { - snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x %08x %08x %08x ", - cmd_va[__entry->i], cmd_va[__entry->i+1], cmd_va[__entry->i+2], cmd_va[__entry->i+3]); - __entry->i += 4; - cmd_len -= 4; - strcat(__entry->cmd_str, __entry->tmp_buf); - } else if (cmd_len >= 2) { - snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x %08x ", cmd_va[__entry->i], cmd_va[__entry->i+1]); - __entry->i += 2; - cmd_len -= 2; - strcat(__entry->cmd_str, __entry->tmp_buf); - } else if (cmd_len == 1) { - snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x ", cmd_va[__entry->i]); - __entry->i += 1; - cmd_len -= 1; - strcat(__entry->cmd_str, __entry->tmp_buf); - } - } - strcat(__entry->cmd_str, "\n"); - ), + TP_PROTO(u8 vgpu_id, u8 ring_id, u32 ip_gma, u32 *cmd_va, u32 cmd_len, + u32 buf_type), + + TP_ARGS(vgpu_id, ring_id, ip_gma, cmd_va, cmd_len, buf_type), + + TP_STRUCT__entry( + __field(u8, vgpu_id) + __field(u8, ring_id) + __field(u32, ip_gma) + __field(u32, buf_type) + __field(u32, cmd_len) + __dynamic_array(u32, raw_cmd, cmd_len) + ), + + TP_fast_assign( + __entry->vgpu_id = vgpu_id; + __entry->ring_id = ring_id; + __entry->ip_gma = ip_gma; + __entry->buf_type = buf_type; + __entry->cmd_len = cmd_len; + memcpy(__get_dynamic_array(raw_cmd), cmd_va, cmd_len * sizeof(*cmd_va)); + ), + + + TP_printk("vgpu%d ring %d: buf_type %u, ip_gma %08x, raw cmd %s", + __entry->vgpu_id, + __entry->ring_id, + __entry->buf_type, + __entry->ip_gma, + __print_array(__get_dynamic_array(raw_cmd), __entry->cmd_len, 4)) +); + +#define GVT_TEMP_STR_LEN 10 +TRACE_EVENT(write_ir, + TP_PROTO(int id, char *reg_name, unsigned int reg, unsigned int new_val, + unsigned int old_val, bool changed), + + TP_ARGS(id, reg_name, reg, new_val, old_val, changed), + + TP_STRUCT__entry( + __field(int, id) + __array(char, buf, GVT_TEMP_STR_LEN) + __field(unsigned int, reg) + __field(unsigned int, new_val) + __field(unsigned int, old_val) + __field(bool, changed) + ), + + TP_fast_assign( + __entry->id = id; + snprintf(__entry->buf, GVT_TEMP_STR_LEN, "%s", reg_name); + __entry->reg = reg; + __entry->new_val = new_val; + __entry->old_val = old_val; + __entry->changed = changed; + ), + + TP_printk("VM%u write [%s] %x, new %08x, old %08x, changed %08x\n", + __entry->id, __entry->buf, __entry->reg, __entry->new_val, + __entry->old_val, __entry->changed) +); + +TRACE_EVENT(propagate_event, + TP_PROTO(int id, const char *irq_name, int bit), + + TP_ARGS(id, irq_name, bit), + + TP_STRUCT__entry( + __field(int, id) + __array(char, buf, GVT_TEMP_STR_LEN) + __field(int, bit) + ), - TP_printk("%s", __entry->cmd_str) + TP_fast_assign( + __entry->id = id; + snprintf(__entry->buf, GVT_TEMP_STR_LEN, "%s", irq_name); + __entry->bit = bit; + ), + + TP_printk("Set bit (%d) for (%s) for vgpu (%d)\n", + __entry->bit, __entry->buf, __entry->id) ); + +TRACE_EVENT(inject_msi, + TP_PROTO(int id, unsigned int address, unsigned int data), + + TP_ARGS(id, address, data), + + TP_STRUCT__entry( + __field(int, id) + __field(unsigned int, address) + __field(unsigned int, data) + ), + + TP_fast_assign( + __entry->id = id; + __entry->address = address; + __entry->data = data; + ), + + TP_printk("vgpu%d:inject msi address %x data %x\n", + __entry->id, __entry->address, __entry->data) +); + +TRACE_EVENT(render_mmio, + TP_PROTO(int id, char *action, unsigned int reg, + unsigned int old_val, unsigned int new_val), + + TP_ARGS(id, action, reg, new_val, old_val), + + TP_STRUCT__entry( + __field(int, id) + __array(char, buf, GVT_TEMP_STR_LEN) + __field(unsigned int, reg) + __field(unsigned int, old_val) + __field(unsigned int, new_val) + ), + + TP_fast_assign( + __entry->id = id; + snprintf(__entry->buf, GVT_TEMP_STR_LEN, "%s", action); + __entry->reg = reg; + __entry->old_val = old_val; + __entry->new_val = new_val; + ), + + TP_printk("VM%u %s reg %x, old %08x new %08x\n", + __entry->id, __entry->buf, __entry->reg, + __entry->old_val, __entry->new_val) +); + #endif /* _GVT_TRACE_H_ */ /* This part must be out of protection */ diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 6e3cbd8..90c14e6 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -501,9 +501,14 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, /* full GPU reset or device model level reset */ if (engine_mask == ALL_ENGINES || dmlr) { + intel_vgpu_reset_gtt(vgpu, dmlr); - intel_vgpu_reset_resource(vgpu); - intel_vgpu_reset_mmio(vgpu); + + /*fence will not be reset during virtual reset */ + if (dmlr) + intel_vgpu_reset_resource(vgpu); + + intel_vgpu_reset_mmio(vgpu, dmlr); populate_pvinfo_page(vgpu); intel_vgpu_reset_display(vgpu); diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 7e0816c..4577b0a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1670,12 +1670,22 @@ static int i915_fbc_status(struct seq_file *m, void *unused) seq_printf(m, "FBC disabled: %s\n", dev_priv->fbc.no_fbc_reason); - if (intel_fbc_is_active(dev_priv) && INTEL_GEN(dev_priv) >= 7) { - uint32_t mask = INTEL_GEN(dev_priv) >= 8 ? - BDW_FBC_COMPRESSION_MASK : - IVB_FBC_COMPRESSION_MASK; - seq_printf(m, "Compressing: %s\n", - yesno(I915_READ(FBC_STATUS2) & mask)); + if (intel_fbc_is_active(dev_priv)) { + u32 mask; + + if (INTEL_GEN(dev_priv) >= 8) + mask = I915_READ(IVB_FBC_STATUS2) & BDW_FBC_COMP_SEG_MASK; + else if (INTEL_GEN(dev_priv) >= 7) + mask = I915_READ(IVB_FBC_STATUS2) & IVB_FBC_COMP_SEG_MASK; + else if (INTEL_GEN(dev_priv) >= 5) + mask = I915_READ(ILK_DPFC_STATUS) & ILK_DPFC_COMP_SEG_MASK; + else if (IS_G4X(dev_priv)) + mask = I915_READ(DPFC_STATUS) & DPFC_COMP_SEG_MASK; + else + mask = I915_READ(FBC_STATUS) & (FBC_STAT_COMPRESSING | + FBC_STAT_COMPRESSED); + + seq_printf(m, "Compressing: %s\n", yesno(mask)); } mutex_unlock(&dev_priv->fbc.lock); @@ -1684,7 +1694,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused) return 0; } -static int i915_fbc_fc_get(void *data, u64 *val) +static int i915_fbc_false_color_get(void *data, u64 *val) { struct drm_i915_private *dev_priv = data; @@ -1696,7 +1706,7 @@ static int i915_fbc_fc_get(void *data, u64 *val) return 0; } -static int i915_fbc_fc_set(void *data, u64 val) +static int i915_fbc_false_color_set(void *data, u64 val) { struct drm_i915_private *dev_priv = data; u32 reg; @@ -1717,8 +1727,8 @@ static int i915_fbc_fc_set(void *data, u64 val) return 0; } -DEFINE_SIMPLE_ATTRIBUTE(i915_fbc_fc_fops, - i915_fbc_fc_get, i915_fbc_fc_set, +DEFINE_SIMPLE_ATTRIBUTE(i915_fbc_false_color_fops, + i915_fbc_false_color_get, i915_fbc_false_color_set, "%llu\n"); static int i915_ips_status(struct seq_file *m, void *unused) @@ -1988,6 +1998,12 @@ static int i915_context_status(struct seq_file *m, void *unused) seq_putc(m, '\n'); } + seq_printf(m, + "\tvma hashtable size=%u (actual %lu), count=%u\n", + ctx->vma_lut.ht_size, + BIT(ctx->vma_lut.ht_bits), + ctx->vma_lut.ht_count); + seq_putc(m, '\n'); } @@ -4289,26 +4305,27 @@ i915_drop_caches_set(void *data, u64 val) { struct drm_i915_private *dev_priv = data; struct drm_device *dev = &dev_priv->drm; - int ret; + int ret = 0; DRM_DEBUG("Dropping caches: 0x%08llx\n", val); /* No need to check and wait for gpu resets, only libdrm auto-restarts * on ioctls on -EAGAIN. */ - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - if (val & DROP_ACTIVE) { - ret = i915_gem_wait_for_idle(dev_priv, - I915_WAIT_INTERRUPTIBLE | - I915_WAIT_LOCKED); + if (val & (DROP_ACTIVE | DROP_RETIRE)) { + ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) - goto unlock; - } + return ret; - if (val & DROP_RETIRE) - i915_gem_retire_requests(dev_priv); + if (val & DROP_ACTIVE) + ret = i915_gem_wait_for_idle(dev_priv, + I915_WAIT_INTERRUPTIBLE | + I915_WAIT_LOCKED); + + if (val & DROP_RETIRE) + i915_gem_retire_requests(dev_priv); + + mutex_unlock(&dev->struct_mutex); + } lockdep_set_current_reclaim_state(GFP_KERNEL); if (val & DROP_BOUND) @@ -4321,9 +4338,6 @@ i915_drop_caches_set(void *data, u64 val) i915_gem_shrink_all(dev_priv); lockdep_clear_current_reclaim_state(); -unlock: - mutex_unlock(&dev->struct_mutex); - if (val & DROP_FREED) { synchronize_rcu(); i915_gem_drain_freed_objects(dev_priv); @@ -4861,7 +4875,7 @@ static const struct i915_debugfs_files { {"i915_pri_wm_latency", &i915_pri_wm_latency_fops}, {"i915_spr_wm_latency", &i915_spr_wm_latency_fops}, {"i915_cur_wm_latency", &i915_cur_wm_latency_fops}, - {"i915_fbc_false_color", &i915_fbc_fc_fops}, + {"i915_fbc_false_color", &i915_fbc_false_color_fops}, {"i915_dp_test_data", &i915_displayport_test_data_fops}, {"i915_dp_test_type", &i915_displayport_test_type_fops}, {"i915_dp_test_active", &i915_displayport_test_active_fops}, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d703897..ee2325b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -139,6 +139,9 @@ static enum intel_pch intel_virt_detect_pch(struct drm_i915_private *dev_priv) } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { ret = PCH_SPT; DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n"); + } else if (IS_COFFEELAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) { + ret = PCH_CNP; + DRM_DEBUG_KMS("Assuming CannonPoint PCH\n"); } return ret; @@ -170,24 +173,29 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv) while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { if (pch->vendor == PCI_VENDOR_ID_INTEL) { unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK; - dev_priv->pch_id = id; + unsigned short id_ext = pch->device & + INTEL_PCH_DEVICE_ID_MASK_EXT; if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { + dev_priv->pch_id = id; dev_priv->pch_type = PCH_IBX; DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); WARN_ON(!IS_GEN5(dev_priv)); } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { + dev_priv->pch_id = id; dev_priv->pch_type = PCH_CPT; DRM_DEBUG_KMS("Found CougarPoint PCH\n"); WARN_ON(!(IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))); } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { /* PantherPoint is CPT compatible */ + dev_priv->pch_id = id; dev_priv->pch_type = PCH_CPT; DRM_DEBUG_KMS("Found PantherPoint PCH\n"); WARN_ON(!(IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))); } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { + dev_priv->pch_id = id; dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint PCH\n"); WARN_ON(!IS_HASWELL(dev_priv) && @@ -195,6 +203,7 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv) WARN_ON(IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv)); } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { + dev_priv->pch_id = id; dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); WARN_ON(!IS_HASWELL(dev_priv) && @@ -202,20 +211,35 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv) WARN_ON(!IS_HSW_ULT(dev_priv) && !IS_BDW_ULT(dev_priv)); } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { + dev_priv->pch_id = id; dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); WARN_ON(!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv)); - } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) { + } else if (id_ext == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) { + dev_priv->pch_id = id_ext; dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); WARN_ON(!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv)); } else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) { + dev_priv->pch_id = id; dev_priv->pch_type = PCH_KBP; DRM_DEBUG_KMS("Found KabyPoint PCH\n"); WARN_ON(!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv)); + } else if (id == INTEL_PCH_CNP_DEVICE_ID_TYPE) { + dev_priv->pch_id = id; + dev_priv->pch_type = PCH_CNP; + DRM_DEBUG_KMS("Found CannonPoint PCH\n"); + WARN_ON(!IS_CANNONLAKE(dev_priv) && + !IS_COFFEELAKE(dev_priv)); + } else if (id_ext == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) { + dev_priv->pch_id = id_ext; + dev_priv->pch_type = PCH_CNP; + DRM_DEBUG_KMS("Found CannonPoint LP PCH\n"); + WARN_ON(!IS_CANNONLAKE(dev_priv) && + !IS_COFFEELAKE(dev_priv)); } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) || (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) || ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) && @@ -223,6 +247,7 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv) PCI_SUBVENDOR_ID_REDHAT_QUMRANET && pch->subsystem_device == PCI_SUBDEVICE_ID_QEMU)) { + dev_priv->pch_id = id; dev_priv->pch_type = intel_virt_detect_pch(dev_priv); } else @@ -351,6 +376,7 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_EXEC_ASYNC: case I915_PARAM_HAS_EXEC_FENCE: case I915_PARAM_HAS_EXEC_CAPTURE: + case I915_PARAM_HAS_EXEC_BATCH_FIRST: /* For the time being all of these are always true; * if some supported hardware does not have one of these * features this value needs to be provided from @@ -358,6 +384,16 @@ static int i915_getparam(struct drm_device *dev, void *data, */ value = 1; break; + case I915_PARAM_SLICE_MASK: + value = INTEL_INFO(dev_priv)->sseu.slice_mask; + if (!value) + return -ENODEV; + break; + case I915_PARAM_SUBSLICE_MASK: + value = INTEL_INFO(dev_priv)->sseu.subslice_mask; + if (!value) + return -ENODEV; + break; default: DRM_DEBUG("Unknown parameter %d\n", param->param); return -EINVAL; @@ -553,6 +589,7 @@ static void i915_gem_fini(struct drm_i915_private *dev_priv) intel_uc_fini_hw(dev_priv); i915_gem_cleanup_engines(dev_priv); i915_gem_context_fini(dev_priv); + i915_gem_cleanup_userptr(dev_priv); mutex_unlock(&dev_priv->drm.struct_mutex); i915_gem_drain_freed_objects(dev_priv); @@ -997,6 +1034,8 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv) DRM_DEBUG_DRIVER("use GPU semaphores? %s\n", yesno(i915.semaphores)); intel_uc_sanitize_options(dev_priv); + + intel_gvt_sanitize_options(dev_priv); } /** @@ -2459,9 +2498,6 @@ static int intel_runtime_resume(struct device *kdev) intel_guc_resume(dev_priv); - if (IS_GEN6(dev_priv)) - intel_init_pch_refclk(dev_priv); - if (IS_GEN9_LP(dev_priv)) { bxt_disable_dc9(dev_priv); bxt_display_core_init(dev_priv, true); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 35f71b5..e1f7c97 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -37,7 +37,7 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include <linux/backlight.h> -#include <linux/hashtable.h> +#include <linux/hash.h> #include <linux/intel-iommu.h> #include <linux/kref.h> #include <linux/pm_qos.h> @@ -80,8 +80,8 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20170529" -#define DRIVER_TIMESTAMP 1496041258 +#define DRIVER_DATE "20170619" +#define DRIVER_TIMESTAMP 1497857498 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions @@ -752,7 +752,6 @@ struct intel_csr { func(has_aliasing_ppgtt); \ func(has_csr); \ func(has_ddi); \ - func(has_decoupled_mmio); \ func(has_dp_mst); \ func(has_fbc); \ func(has_fpga_dbg); \ @@ -827,6 +826,8 @@ enum intel_platform { INTEL_BROXTON, INTEL_KABYLAKE, INTEL_GEMINILAKE, + INTEL_COFFEELAKE, + INTEL_CANNONLAKE, INTEL_MAX_PLATFORMS }; @@ -1152,6 +1153,7 @@ enum intel_pch { PCH_LPT, /* Lynxpoint PCH */ PCH_SPT, /* Sunrisepoint PCH */ PCH_KBP, /* Kabypoint PCH */ + PCH_CNP, /* Cannonpoint PCH */ PCH_NOP, }; @@ -1160,11 +1162,9 @@ enum intel_sbi_destination { SBI_MPHY, }; -#define QUIRK_PIPEA_FORCE (1<<0) #define QUIRK_LVDS_SSC_DISABLE (1<<1) #define QUIRK_INVERT_BRIGHTNESS (1<<2) #define QUIRK_BACKLIGHT_PRESENT (1<<3) -#define QUIRK_PIPEB_FORCE (1<<4) #define QUIRK_PIN_SWIZZLED_PAGES (1<<5) struct intel_fbdev; @@ -1454,6 +1454,13 @@ struct i915_gem_mm { /** LRU list of objects with fence regs on them. */ struct list_head fence_list; + /** + * Workqueue to fault in userptr pages, flushed by the execbuf + * when required but otherwise left to userspace to try again + * on EAGAIN. + */ + struct workqueue_struct *userptr_wq; + u64 unordered_timeline; /* the indicator for dispatch video commands on two BSD rings */ @@ -2017,9 +2024,17 @@ struct i915_oa_ops { void (*init_oa_buffer)(struct drm_i915_private *dev_priv); /** - * @enable_metric_set: Applies any MUX configuration to set up the - * Boolean and Custom (B/C) counters that are part of the counter - * reports being sampled. May apply system constraints such as + * @select_metric_set: The auto generated code that checks whether a + * requested OA config is applicable to the system and if so sets up + * the mux, oa and flex eu register config pointers according to the + * current dev_priv->perf.oa.metrics_set. + */ + int (*select_metric_set)(struct drm_i915_private *dev_priv); + + /** + * @enable_metric_set: Selects and applies any MUX configuration to set + * up the Boolean and Custom (B/C) counters that are part of the + * counter reports being sampled. May apply system constraints such as * disabling EU clock gating as required. */ int (*enable_metric_set)(struct drm_i915_private *dev_priv); @@ -2050,20 +2065,13 @@ struct i915_oa_ops { size_t *offset); /** - * @oa_buffer_check: Check for OA buffer data + update tail - * - * This is either called via fops or the poll check hrtimer (atomic - * ctx) without any locks taken. + * @oa_hw_tail_read: read the OA tail pointer register * - * It's safe to read OA config state here unlocked, assuming that this - * is only called while the stream is enabled, while the global OA - * configuration can't be modified. - * - * Efficiency is more important than avoiding some false positives - * here, which will be handled gracefully - likely resulting in an - * %EAGAIN error for userspace. + * In particular this enables us to share all the fiddly code for + * handling the OA unit tail pointer race that affects multiple + * generations. */ - bool (*oa_buffer_check)(struct drm_i915_private *dev_priv); + u32 (*oa_hw_tail_read)(struct drm_i915_private *dev_priv); }; struct intel_cdclk_state { @@ -2394,8 +2402,6 @@ struct drm_i915_private { struct mutex lock; struct list_head streams; - spinlock_t hook_lock; - struct { struct i915_perf_stream *exclusive_stream; @@ -2413,17 +2419,23 @@ struct drm_i915_private { bool periodic; int period_exponent; + int timestamp_frequency; int metrics_set; - const struct i915_oa_reg *mux_regs; - int mux_regs_len; + const struct i915_oa_reg *mux_regs[6]; + int mux_regs_lens[6]; + int n_mux_configs; + const struct i915_oa_reg *b_counter_regs; int b_counter_regs_len; + const struct i915_oa_reg *flex_regs; + int flex_regs_len; struct { struct i915_vma *vma; u8 *vaddr; + u32 last_ctx_id; int format; int format_size; @@ -2493,6 +2505,15 @@ struct drm_i915_private { } oa_buffer; u32 gen7_latched_oastatus1; + u32 ctx_oactxctrl_offset; + u32 ctx_flexeu0_offset; + + /** + * The RPT_ID/reason field for Gen8+ includes a bit + * to determine if the CTX ID in the report is valid + * but the specific bit differs between Gen 8 and 9 + */ + u32 gen8_valid_ctx_bit; struct i915_oa_ops ops; const struct i915_oa_format *oa_formats; @@ -2768,6 +2789,8 @@ intel_info(const struct drm_i915_private *dev_priv) #define IS_BROXTON(dev_priv) ((dev_priv)->info.platform == INTEL_BROXTON) #define IS_KABYLAKE(dev_priv) ((dev_priv)->info.platform == INTEL_KABYLAKE) #define IS_GEMINILAKE(dev_priv) ((dev_priv)->info.platform == INTEL_GEMINILAKE) +#define IS_COFFEELAKE(dev_priv) ((dev_priv)->info.platform == INTEL_COFFEELAKE) +#define IS_CANNONLAKE(dev_priv) ((dev_priv)->info.platform == INTEL_CANNONLAKE) #define IS_MOBILE(dev_priv) ((dev_priv)->info.is_mobile) #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) @@ -2803,10 +2826,18 @@ intel_info(const struct drm_i915_private *dev_priv) #define IS_KBL_ULX(dev_priv) (INTEL_DEVID(dev_priv) == 0x590E || \ INTEL_DEVID(dev_priv) == 0x5915 || \ INTEL_DEVID(dev_priv) == 0x591E) +#define IS_SKL_GT2(dev_priv) (IS_SKYLAKE(dev_priv) && \ + (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0010) #define IS_SKL_GT3(dev_priv) (IS_SKYLAKE(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0020) #define IS_SKL_GT4(dev_priv) (IS_SKYLAKE(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0030) +#define IS_KBL_GT2(dev_priv) (IS_KABYLAKE(dev_priv) && \ + (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0010) +#define IS_KBL_GT3(dev_priv) (IS_KABYLAKE(dev_priv) && \ + (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0020) +#define IS_CFL_ULT(dev_priv) (IS_COFFEELAKE(dev_priv) && \ + (INTEL_DEVID(dev_priv) & 0x00F0) == 0x00A0) #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support) @@ -2845,6 +2876,12 @@ intel_info(const struct drm_i915_private *dev_priv) #define IS_GLK_REVID(dev_priv, since, until) \ (IS_GEMINILAKE(dev_priv) && IS_REVID(dev_priv, since, until)) +#define CNL_REVID_A0 0x0 +#define CNL_REVID_B0 0x1 + +#define IS_CNL_REVID(p, since, until) \ + (IS_CANNONLAKE(p) && IS_REVID(p, since, until)) + /* * The genX designation typically refers to the render engine, so render * capability related checks should use IS_GEN, while display and other checks @@ -2859,6 +2896,7 @@ intel_info(const struct drm_i915_private *dev_priv) #define IS_GEN7(dev_priv) (!!((dev_priv)->info.gen_mask & BIT(6))) #define IS_GEN8(dev_priv) (!!((dev_priv)->info.gen_mask & BIT(7))) #define IS_GEN9(dev_priv) (!!((dev_priv)->info.gen_mask & BIT(8))) +#define IS_GEN10(dev_priv) (!!((dev_priv)->info.gen_mask & BIT(9))) #define IS_LP(dev_priv) (INTEL_INFO(dev_priv)->is_lp) #define IS_GEN9_LP(dev_priv) (IS_GEN9(dev_priv) && IS_LP(dev_priv)) @@ -2959,6 +2997,7 @@ intel_info(const struct drm_i915_private *dev_priv) #define HAS_POOLED_EU(dev_priv) ((dev_priv)->info.has_pooled_eu) #define INTEL_PCH_DEVICE_ID_MASK 0xff00 +#define INTEL_PCH_DEVICE_ID_MASK_EXT 0xff80 #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 #define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 @@ -2967,11 +3006,16 @@ intel_info(const struct drm_i915_private *dev_priv) #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 #define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA200 +#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300 +#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 #define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 #define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ #define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type) +#define HAS_PCH_CNP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CNP) +#define HAS_PCH_CNP_LP(dev_priv) \ + ((dev_priv)->pch_id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) #define HAS_PCH_KBP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_KBP) #define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT) #define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT) @@ -2986,7 +3030,7 @@ intel_info(const struct drm_i915_private *dev_priv) #define HAS_GMCH_DISPLAY(dev_priv) ((dev_priv)->info.has_gmch_display) -#define HAS_LSPCON(dev_priv) (IS_GEN9(dev_priv)) +#define HAS_LSPCON(dev_priv) (INTEL_GEN(dev_priv) >= 9) /* DPF == dynamic parity feature */ #define HAS_L3_DPF(dev_priv) ((dev_priv)->info.has_l3_dpf) @@ -2996,8 +3040,6 @@ intel_info(const struct drm_i915_private *dev_priv) #define GT_FREQUENCY_MULTIPLIER 50 #define GEN9_FREQ_SCALER 3 -#define HAS_DECOUPLED_MMIO(dev_priv) (INTEL_INFO(dev_priv)->has_decoupled_mmio) - #include "i915_trace.h" static inline bool intel_vtd_active(void) @@ -3194,7 +3236,8 @@ int i915_gem_set_tiling_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_get_tiling_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -void i915_gem_init_userptr(struct drm_i915_private *dev_priv); +int i915_gem_init_userptr(struct drm_i915_private *dev_priv); +void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv); int i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file); int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, @@ -3534,6 +3577,9 @@ i915_gem_context_lookup_timeline(struct i915_gem_context *ctx, int i915_perf_open_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +void i915_oa_init_reg_state(struct intel_engine_cs *engine, + struct i915_gem_context *ctx, + uint32_t *reg_state); /* i915_gem_evict.c */ int __must_check i915_gem_evict_something(struct i915_address_space *vm, @@ -3544,7 +3590,7 @@ int __must_check i915_gem_evict_something(struct i915_address_space *vm, int __must_check i915_gem_evict_for_node(struct i915_address_space *vm, struct drm_mm_node *node, unsigned int flags); -int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle); +int i915_gem_evict_vm(struct i915_address_space *vm); /* belongs in i915_gem_gtt.h */ static inline void i915_gem_chipset_flush(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7b676fd..7dcac3b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -49,10 +49,10 @@ static void i915_gem_flush_free_objects(struct drm_i915_private *i915); static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj) { - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) + if (obj->cache_dirty) return false; - if (!i915_gem_object_is_coherent(obj)) + if (!obj->cache_coherent) return true; return obj->pin_display; @@ -143,9 +143,9 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_i915_gem_get_aperture *args = data; struct i915_vma *vma; - size_t pinned; + u64 pinned; - pinned = 0; + pinned = ggtt->base.reserved; mutex_lock(&dev->struct_mutex); list_for_each_entry(vma, &ggtt->base.active_list, vm_link) if (i915_vma_is_pinned(vma)) @@ -233,6 +233,14 @@ err_phys: return st; } +static void __start_cpu_write(struct drm_i915_gem_object *obj) +{ + obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->base.write_domain = I915_GEM_DOMAIN_CPU; + if (cpu_write_needs_clflush(obj)) + obj->cache_dirty = true; +} + static void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, struct sg_table *pages, @@ -245,11 +253,10 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, if (needs_clflush && (obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 && - !i915_gem_object_is_coherent(obj)) + !obj->cache_coherent) drm_clflush_sg(pages); - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; + __start_cpu_write(obj); } static void @@ -684,6 +691,12 @@ i915_gem_dumb_create(struct drm_file *file, args->size, &args->handle); } +static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj) +{ + return !(obj->cache_level == I915_CACHE_NONE || + obj->cache_level == I915_CACHE_WT); +} + /** * Creates a new mm object and returns a handle to it. * @dev: drm device pointer @@ -753,6 +766,11 @@ flush_write_domain(struct drm_i915_gem_object *obj, unsigned int flush_domains) case I915_GEM_DOMAIN_CPU: i915_gem_clflush_object(obj, I915_CLFLUSH_SYNC); break; + + case I915_GEM_DOMAIN_RENDER: + if (gpu_write_needs_clflush(obj)) + obj->cache_dirty = true; + break; } obj->base.write_domain = 0; @@ -838,8 +856,7 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj, if (ret) return ret; - if (i915_gem_object_is_coherent(obj) || - !static_cpu_has(X86_FEATURE_CLFLUSH)) { + if (obj->cache_coherent || !static_cpu_has(X86_FEATURE_CLFLUSH)) { ret = i915_gem_object_set_to_cpu_domain(obj, false); if (ret) goto err_unpin; @@ -854,7 +871,8 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj, * optimizes for the case when the gpu will dirty the data * anyway again before the next pread happens. */ - if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) + if (!obj->cache_dirty && + !(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) *needs_clflush = CLFLUSH_BEFORE; out: @@ -890,8 +908,7 @@ int i915_gem_obj_prepare_shmem_write(struct drm_i915_gem_object *obj, if (ret) return ret; - if (i915_gem_object_is_coherent(obj) || - !static_cpu_has(X86_FEATURE_CLFLUSH)) { + if (obj->cache_coherent || !static_cpu_has(X86_FEATURE_CLFLUSH)) { ret = i915_gem_object_set_to_cpu_domain(obj, true); if (ret) goto err_unpin; @@ -906,14 +923,16 @@ int i915_gem_obj_prepare_shmem_write(struct drm_i915_gem_object *obj, * This optimizes for the case when the gpu will use the data * right away and we therefore have to clflush anyway. */ - if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) + if (!obj->cache_dirty) { *needs_clflush |= CLFLUSH_AFTER; - /* Same trick applies to invalidate partially written cachelines read - * before writing. - */ - if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) - *needs_clflush |= CLFLUSH_BEFORE; + /* + * Same trick applies to invalidate partially written + * cachelines read before writing. + */ + if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) + *needs_clflush |= CLFLUSH_BEFORE; + } out: intel_fb_obj_invalidate(obj, ORIGIN_CPU); @@ -2337,8 +2356,8 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) struct page *page; unsigned long last_pfn = 0; /* suppress gcc warning */ unsigned int max_segment; + gfp_t noreclaim; int ret; - gfp_t gfp; /* Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in @@ -2367,22 +2386,30 @@ rebuild_st: * Fail silently without starting the shrinker */ mapping = obj->base.filp->f_mapping; - gfp = mapping_gfp_constraint(mapping, ~(__GFP_IO | __GFP_RECLAIM)); - gfp |= __GFP_NORETRY | __GFP_NOWARN; + noreclaim = mapping_gfp_constraint(mapping, ~__GFP_RECLAIM); + noreclaim |= __GFP_NORETRY | __GFP_NOWARN; + sg = st->sgl; st->nents = 0; for (i = 0; i < page_count; i++) { - page = shmem_read_mapping_page_gfp(mapping, i, gfp); - if (unlikely(IS_ERR(page))) { - i915_gem_shrink(dev_priv, - page_count, - I915_SHRINK_BOUND | - I915_SHRINK_UNBOUND | - I915_SHRINK_PURGEABLE); + const unsigned int shrink[] = { + I915_SHRINK_BOUND | I915_SHRINK_UNBOUND | I915_SHRINK_PURGEABLE, + 0, + }, *s = shrink; + gfp_t gfp = noreclaim; + + do { page = shmem_read_mapping_page_gfp(mapping, i, gfp); - } - if (unlikely(IS_ERR(page))) { - gfp_t reclaim; + if (likely(!IS_ERR(page))) + break; + + if (!*s) { + ret = PTR_ERR(page); + goto err_sg; + } + + i915_gem_shrink(dev_priv, 2 * page_count, *s++); + cond_resched(); /* We've tried hard to allocate the memory by reaping * our own buffer, now let the real VM do its job and @@ -2392,15 +2419,26 @@ rebuild_st: * defer the oom here by reporting the ENOMEM back * to userspace. */ - reclaim = mapping_gfp_mask(mapping); - reclaim |= __GFP_NORETRY; /* reclaim, but no oom */ - - page = shmem_read_mapping_page_gfp(mapping, i, reclaim); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - goto err_sg; + if (!*s) { + /* reclaim and warn, but no oom */ + gfp = mapping_gfp_mask(mapping); + + /* Our bo are always dirty and so we require + * kswapd to reclaim our pages (direct reclaim + * does not effectively begin pageout of our + * buffers on its own). However, direct reclaim + * only waits for kswapd when under allocation + * congestion. So as a result __GFP_RECLAIM is + * unreliable and fails to actually reclaim our + * dirty pages -- unless you try over and over + * again with !__GFP_NORETRY. However, we still + * want to fail this allocation rather than + * trigger the out-of-memory killer and for + * this we want the future __GFP_MAYFAIL. + */ } - } + } while (1); + if (!i || sg->length >= max_segment || page_to_pfn(page) != last_pfn + 1) { @@ -3223,6 +3261,10 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file) if (vma->vm->file == fpriv) i915_vma_close(vma); + vma = obj->vma_hashed; + if (vma && vma->ctx->file_priv == fpriv) + i915_vma_unlink_ctx(vma); + if (i915_gem_object_is_active(obj) && !i915_gem_object_has_active_reference(obj)) { i915_gem_object_set_active_reference(obj); @@ -3376,10 +3418,13 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags) static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj) { - if (obj->base.write_domain != I915_GEM_DOMAIN_CPU && !obj->cache_dirty) - return; - - i915_gem_clflush_object(obj, I915_CLFLUSH_FORCE); + /* + * We manually flush the CPU domain so that we can override and + * force the flush for the display, and perform it asyncrhonously. + */ + flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU); + if (obj->cache_dirty) + i915_gem_clflush_object(obj, I915_CLFLUSH_FORCE); obj->base.write_domain = 0; } @@ -3638,13 +3683,11 @@ restart: } } - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU && - i915_gem_object_is_coherent(obj)) - obj->cache_dirty = true; - list_for_each_entry(vma, &obj->vma_list, obj_link) vma->node.color = cache_level; obj->cache_level = cache_level; + obj->cache_coherent = i915_gem_object_is_coherent(obj); + obj->cache_dirty = true; /* Always invalidate stale cachelines */ return 0; } @@ -3866,9 +3909,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) if (ret) return ret; - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) - return 0; - flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU); /* Flush the CPU cache if it's still invalid. */ @@ -3880,15 +3920,13 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) /* It should now be out of any other write domains, and we can update * the domain values for our changes. */ - GEM_BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); + GEM_BUG_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU); /* If we're writing through the CPU, then the GPU read domains will * need to be invalidated at next use. */ - if (write) { - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - } + if (write) + __start_cpu_write(obj); return 0; } @@ -4220,7 +4258,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, INIT_LIST_HEAD(&obj->global_link); INIT_LIST_HEAD(&obj->userfault_link); - INIT_LIST_HEAD(&obj->obj_exec_link); INIT_LIST_HEAD(&obj->vma_list); INIT_LIST_HEAD(&obj->batch_pool_link); @@ -4285,6 +4322,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size) mapping = obj->base.filp->f_mapping; mapping_set_gfp_mask(mapping, mask); + GEM_BUG_ON(!(mapping_gfp_mask(mapping) & __GFP_RECLAIM)); i915_gem_object_init(obj, &i915_gem_object_ops); @@ -4308,6 +4346,9 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size) } else obj->cache_level = I915_CACHE_NONE; + obj->cache_coherent = i915_gem_object_is_coherent(obj); + obj->cache_dirty = !obj->cache_coherent; + trace_i915_gem_object_create(obj); return obj; @@ -4356,7 +4397,6 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, GEM_BUG_ON(i915_gem_object_is_active(obj)); list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link) { - GEM_BUG_ON(!i915_vma_is_ggtt(vma)); GEM_BUG_ON(i915_vma_is_active(vma)); vma->flags &= ~I915_VMA_PIN_MASK; i915_vma_close(vma); @@ -4763,7 +4803,9 @@ int i915_gem_init(struct drm_i915_private *dev_priv) */ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); - i915_gem_init_userptr(dev_priv); + ret = i915_gem_init_userptr(dev_priv); + if (ret) + goto out_unlock; ret = i915_gem_init_ggtt(dev_priv); if (ret) @@ -4974,10 +5016,8 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv) mutex_lock(&dev_priv->drm.struct_mutex); for (p = phases; *p; p++) { - list_for_each_entry(obj, *p, global_link) { - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - } + list_for_each_entry(obj, *p, global_link) + __start_cpu_write(obj); } mutex_unlock(&dev_priv->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c index 41aa598..c93005c 100644 --- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c +++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c @@ -114,12 +114,27 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, list_for_each_entry(obj, list, batch_pool_link) { /* The batches are strictly LRU ordered */ if (i915_gem_object_is_active(obj)) { - if (!reservation_object_test_signaled_rcu(obj->resv, - true)) + struct reservation_object *resv = obj->resv; + + if (!reservation_object_test_signaled_rcu(resv, true)) break; i915_gem_retire_requests(pool->engine->i915); GEM_BUG_ON(i915_gem_object_is_active(obj)); + + /* + * The object is now idle, clear the array of shared + * fences before we add a new request. Although, we + * remain on the same engine, we may be on a different + * timeline and so may continually grow the array, + * trapping a reference to all the old fences, rather + * than replace the existing fence. + */ + if (rcu_access_pointer(resv->fence)) { + reservation_object_lock(resv, NULL); + reservation_object_add_excl_fence(resv, NULL); + reservation_object_unlock(resv); + } } GEM_BUG_ON(!reservation_object_test_signaled_rcu(obj->resv, diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.c b/drivers/gpu/drm/i915/i915_gem_clflush.c index ffac7a1..152f16c 100644 --- a/drivers/gpu/drm/i915/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/i915_gem_clflush.c @@ -71,8 +71,6 @@ static const struct dma_fence_ops i915_clflush_ops = { static void __i915_do_clflush(struct drm_i915_gem_object *obj) { drm_clflush_sg(obj->mm.pages); - obj->cache_dirty = false; - intel_fb_obj_flush(obj, ORIGIN_CPU); } @@ -81,9 +79,6 @@ static void i915_clflush_work(struct work_struct *work) struct clflush *clflush = container_of(work, typeof(*clflush), work); struct drm_i915_gem_object *obj = clflush->obj; - if (!obj->cache_dirty) - goto out; - if (i915_gem_object_pin_pages(obj)) { DRM_ERROR("Failed to acquire obj->pages for clflushing\n"); goto out; @@ -131,10 +126,10 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj, * anything not backed by physical memory we consider to be always * coherent and not need clflushing. */ - if (!i915_gem_object_has_struct_page(obj)) + if (!i915_gem_object_has_struct_page(obj)) { + obj->cache_dirty = false; return; - - obj->cache_dirty = true; + } /* If the GPU is snooping the contents of the CPU cache, * we do not need to manually clear the CPU cache lines. However, @@ -144,7 +139,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj, * snooping behaviour occurs naturally as the result of our domain * tracking. */ - if (!(flags & I915_CLFLUSH_FORCE) && i915_gem_object_is_coherent(obj)) + if (!(flags & I915_CLFLUSH_FORCE) && obj->cache_coherent) return; trace_i915_gem_object_clflush(obj); @@ -153,6 +148,8 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj, if (!(flags & I915_CLFLUSH_SYNC)) clflush = kmalloc(sizeof(*clflush), GFP_KERNEL); if (clflush) { + GEM_BUG_ON(!obj->cache_dirty); + dma_fence_init(&clflush->dma, &i915_clflush_ops, &clflush_lock, @@ -180,4 +177,6 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj, } else { GEM_BUG_ON(obj->base.write_domain != I915_GEM_DOMAIN_CPU); } + + obj->cache_dirty = false; } diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index c5d1666..39ed58a 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -85,6 +85,7 @@ * */ +#include <linux/log2.h> #include <drm/drmP.h> #include <drm/i915_drm.h> #include "i915_drv.h" @@ -92,6 +93,71 @@ #define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1 +/* Initial size (as log2) to preallocate the handle->object hashtable */ +#define VMA_HT_BITS 2u /* 4 x 2 pointers, 64 bytes minimum */ + +static void resize_vma_ht(struct work_struct *work) +{ + struct i915_gem_context_vma_lut *lut = + container_of(work, typeof(*lut), resize); + unsigned int bits, new_bits, size, i; + struct hlist_head *new_ht; + + GEM_BUG_ON(!(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS)); + + bits = 1 + ilog2(4*lut->ht_count/3 + 1); + new_bits = min_t(unsigned int, + max(bits, VMA_HT_BITS), + sizeof(unsigned int) * BITS_PER_BYTE - 1); + if (new_bits == lut->ht_bits) + goto out; + + new_ht = kzalloc(sizeof(*new_ht)<<new_bits, GFP_KERNEL | __GFP_NOWARN); + if (!new_ht) + new_ht = vzalloc(sizeof(*new_ht)<<new_bits); + if (!new_ht) + /* Pretend resize succeeded and stop calling us for a bit! */ + goto out; + + size = BIT(lut->ht_bits); + for (i = 0; i < size; i++) { + struct i915_vma *vma; + struct hlist_node *tmp; + + hlist_for_each_entry_safe(vma, tmp, &lut->ht[i], ctx_node) + hlist_add_head(&vma->ctx_node, + &new_ht[hash_32(vma->ctx_handle, + new_bits)]); + } + kvfree(lut->ht); + lut->ht = new_ht; + lut->ht_bits = new_bits; +out: + smp_store_release(&lut->ht_size, BIT(bits)); + GEM_BUG_ON(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS); +} + +static void vma_lut_free(struct i915_gem_context *ctx) +{ + struct i915_gem_context_vma_lut *lut = &ctx->vma_lut; + unsigned int i, size; + + if (lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS) + cancel_work_sync(&lut->resize); + + size = BIT(lut->ht_bits); + for (i = 0; i < size; i++) { + struct i915_vma *vma; + + hlist_for_each_entry(vma, &lut->ht[i], ctx_node) { + vma->obj->vma_hashed = NULL; + vma->ctx = NULL; + i915_vma_put(vma); + } + } + kvfree(lut->ht); +} + void i915_gem_context_free(struct kref *ctx_ref) { struct i915_gem_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); @@ -101,6 +167,7 @@ void i915_gem_context_free(struct kref *ctx_ref) trace_i915_context_free(ctx); GEM_BUG_ON(!i915_gem_context_is_closed(ctx)); + vma_lut_free(ctx); i915_ppgtt_put(ctx->ppgtt); for (i = 0; i < I915_NUM_ENGINES; i++) { @@ -118,6 +185,7 @@ void i915_gem_context_free(struct kref *ctx_ref) kfree(ctx->name); put_pid(ctx->pid); + list_del(&ctx->link); ida_simple_remove(&ctx->i915->context_hw_ida, ctx->hw_id); @@ -201,13 +269,24 @@ __create_hw_context(struct drm_i915_private *dev_priv, ctx->i915 = dev_priv; ctx->priority = I915_PRIORITY_NORMAL; + ctx->vma_lut.ht_bits = VMA_HT_BITS; + ctx->vma_lut.ht_size = BIT(VMA_HT_BITS); + BUILD_BUG_ON(BIT(VMA_HT_BITS) == I915_CTX_RESIZE_IN_PROGRESS); + ctx->vma_lut.ht = kcalloc(ctx->vma_lut.ht_size, + sizeof(*ctx->vma_lut.ht), + GFP_KERNEL); + if (!ctx->vma_lut.ht) + goto err_out; + + INIT_WORK(&ctx->vma_lut.resize, resize_vma_ht); + /* Default context will never have a file_priv */ ret = DEFAULT_CONTEXT_HANDLE; if (file_priv) { ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL); if (ret < 0) - goto err_out; + goto err_lut; } ctx->user_handle = ret; @@ -248,6 +327,8 @@ __create_hw_context(struct drm_i915_private *dev_priv, err_pid: put_pid(ctx->pid); idr_remove(&file_priv->context_idr, ctx->user_handle); +err_lut: + kvfree(ctx->vma_lut.ht); err_out: context_close(ctx); return ERR_PTR(ret); @@ -1034,9 +1115,6 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, if (args->flags || args->pad) return -EINVAL; - if (args->ctx_id == DEFAULT_CONTEXT_HANDLE && !capable(CAP_SYS_ADMIN)) - return -EPERM; - ret = i915_mutex_lock_interruptible(dev); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index 4af2ab94..82c99ba 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h @@ -143,6 +143,32 @@ struct i915_gem_context { /** ggtt_offset_bias: placement restriction for context objects */ u32 ggtt_offset_bias; + struct i915_gem_context_vma_lut { + /** ht_size: last request size to allocate the hashtable for. */ + unsigned int ht_size; +#define I915_CTX_RESIZE_IN_PROGRESS BIT(0) + /** ht_bits: real log2(size) of hashtable. */ + unsigned int ht_bits; + /** ht_count: current number of entries inside the hashtable */ + unsigned int ht_count; + + /** ht: the array of buckets comprising the simple hashtable */ + struct hlist_head *ht; + + /** + * resize: After an execbuf completes, we check the load factor + * of the hashtable. If the hashtable is too full, or too empty, + * we schedule a task to resize the hashtable. During the + * resize, the entries are moved between different buckets and + * so we cannot simultaneously read the hashtable as it is + * being resized (unlike rhashtable). Therefore we treat the + * active work as a strong barrier, pausing a subsequent + * execbuf to wait for the resize worker to complete, if + * required. + */ + struct work_struct resize; + } vma_lut; + /** engine: per-engine logical HW state */ struct intel_context { struct i915_vma *state; diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 51e365f..a193f1b 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -50,6 +50,29 @@ static bool ggtt_is_idle(struct drm_i915_private *dev_priv) return true; } +static int ggtt_flush(struct drm_i915_private *i915) +{ + int err; + + /* Not everything in the GGTT is tracked via vma (otherwise we + * could evict as required with minimal stalling) so we are forced + * to idle the GPU and explicitly retire outstanding requests in + * the hopes that we can then remove contexts and the like only + * bound by their active reference. + */ + err = i915_gem_switch_to_kernel_context(i915); + if (err) + return err; + + err = i915_gem_wait_for_idle(i915, + I915_WAIT_INTERRUPTIBLE | + I915_WAIT_LOCKED); + if (err) + return err; + + return 0; +} + static bool mark_free(struct drm_mm_scan *scan, struct i915_vma *vma, @@ -59,13 +82,10 @@ mark_free(struct drm_mm_scan *scan, if (i915_vma_is_pinned(vma)) return false; - if (WARN_ON(!list_empty(&vma->exec_list))) - return false; - if (flags & PIN_NONFAULT && !list_empty(&vma->obj->userfault_link)) return false; - list_add(&vma->exec_list, unwind); + list_add(&vma->evict_link, unwind); return drm_mm_scan_add_block(scan, &vma->node); } @@ -157,11 +177,9 @@ search_again: } while (*++phase); /* Nothing found, clean up and bail out! */ - list_for_each_entry_safe(vma, next, &eviction_list, exec_list) { + list_for_each_entry_safe(vma, next, &eviction_list, evict_link) { ret = drm_mm_scan_remove_block(&scan, &vma->node); BUG_ON(ret); - - INIT_LIST_HEAD(&vma->exec_list); } /* Can we unpin some objects such as idle hw contents, @@ -180,19 +198,7 @@ search_again: return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC; } - /* Not everything in the GGTT is tracked via vma (otherwise we - * could evict as required with minimal stalling) so we are forced - * to idle the GPU and explicitly retire outstanding requests in - * the hopes that we can then remove contexts and the like only - * bound by their active reference. - */ - ret = i915_gem_switch_to_kernel_context(dev_priv); - if (ret) - return ret; - - ret = i915_gem_wait_for_idle(dev_priv, - I915_WAIT_INTERRUPTIBLE | - I915_WAIT_LOCKED); + ret = ggtt_flush(dev_priv); if (ret) return ret; @@ -205,21 +211,16 @@ found: * calling unbind (which may remove the active reference * of any of our objects, thus corrupting the list). */ - list_for_each_entry_safe(vma, next, &eviction_list, exec_list) { + list_for_each_entry_safe(vma, next, &eviction_list, evict_link) { if (drm_mm_scan_remove_block(&scan, &vma->node)) __i915_vma_pin(vma); else - list_del_init(&vma->exec_list); + list_del(&vma->evict_link); } /* Unbinding will emit any required flushes */ ret = 0; - while (!list_empty(&eviction_list)) { - vma = list_first_entry(&eviction_list, - struct i915_vma, - exec_list); - - list_del_init(&vma->exec_list); + list_for_each_entry_safe(vma, next, &eviction_list, evict_link) { __i915_vma_unpin(vma); if (ret == 0) ret = i915_vma_unbind(vma); @@ -315,7 +316,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm, } /* Overlap of objects in the same batch? */ - if (i915_vma_is_pinned(vma) || !list_empty(&vma->exec_list)) { + if (i915_vma_is_pinned(vma)) { ret = -ENOSPC; if (vma->exec_entry && vma->exec_entry->flags & EXEC_OBJECT_PINNED) @@ -332,11 +333,10 @@ int i915_gem_evict_for_node(struct i915_address_space *vm, * reference) another in our eviction list. */ __i915_vma_pin(vma); - list_add(&vma->exec_list, &eviction_list); + list_add(&vma->evict_link, &eviction_list); } - list_for_each_entry_safe(vma, next, &eviction_list, exec_list) { - list_del_init(&vma->exec_list); + list_for_each_entry_safe(vma, next, &eviction_list, evict_link) { __i915_vma_unpin(vma); if (ret == 0) ret = i915_vma_unbind(vma); @@ -348,10 +348,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm, /** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse - * @do_idle: Boolean directing whether to idle first. * - * This function evicts all idles vmas from a vm. If all unpinned vmas should be - * evicted the @do_idle needs to be set to true. + * This function evicts all vmas from a vm. * * This is used by the execbuf code as a last-ditch effort to defragment the * address space. @@ -359,37 +357,50 @@ int i915_gem_evict_for_node(struct i915_address_space *vm, * To clarify: This is for freeing up virtual address space, not for freeing * memory in e.g. the shrinker. */ -int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle) +int i915_gem_evict_vm(struct i915_address_space *vm) { + struct list_head *phases[] = { + &vm->inactive_list, + &vm->active_list, + NULL + }, **phase; + struct list_head eviction_list; struct i915_vma *vma, *next; int ret; lockdep_assert_held(&vm->i915->drm.struct_mutex); trace_i915_gem_evict_vm(vm); - if (do_idle) { - struct drm_i915_private *dev_priv = vm->i915; - - if (i915_is_ggtt(vm)) { - ret = i915_gem_switch_to_kernel_context(dev_priv); - if (ret) - return ret; - } - - ret = i915_gem_wait_for_idle(dev_priv, - I915_WAIT_INTERRUPTIBLE | - I915_WAIT_LOCKED); + /* Switch back to the default context in order to unpin + * the existing context objects. However, such objects only + * pin themselves inside the global GTT and performing the + * switch otherwise is ineffective. + */ + if (i915_is_ggtt(vm)) { + ret = ggtt_flush(vm->i915); if (ret) return ret; - - WARN_ON(!list_empty(&vm->active_list)); } - list_for_each_entry_safe(vma, next, &vm->inactive_list, vm_link) - if (!i915_vma_is_pinned(vma)) - WARN_ON(i915_vma_unbind(vma)); + INIT_LIST_HEAD(&eviction_list); + phase = phases; + do { + list_for_each_entry(vma, *phase, vm_link) { + if (i915_vma_is_pinned(vma)) + continue; - return 0; + __i915_vma_pin(vma); + list_add(&vma->evict_link, &eviction_list); + } + } while (*++phase); + + ret = 0; + list_for_each_entry_safe(vma, next, &eviction_list, evict_link) { + __i915_vma_unpin(vma); + if (ret == 0) + ret = i915_vma_unbind(vma); + } + return ret; } #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 04211c9..eb46dfa 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -40,143 +40,726 @@ #include "intel_drv.h" #include "intel_frontbuffer.h" -#define DBG_USE_CPU_RELOC 0 /* -1 force GTT relocs; 1 force CPU relocs */ +enum { + FORCE_CPU_RELOC = 1, + FORCE_GTT_RELOC, + FORCE_GPU_RELOC, +#define DBG_FORCE_RELOC 0 /* choose one of the above! */ +}; + +#define __EXEC_OBJECT_HAS_REF BIT(31) +#define __EXEC_OBJECT_HAS_PIN BIT(30) +#define __EXEC_OBJECT_HAS_FENCE BIT(29) +#define __EXEC_OBJECT_NEEDS_MAP BIT(28) +#define __EXEC_OBJECT_NEEDS_BIAS BIT(27) +#define __EXEC_OBJECT_INTERNAL_FLAGS (~0u << 27) /* all of the above */ +#define __EXEC_OBJECT_RESERVED (__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_FENCE) -#define __EXEC_OBJECT_HAS_PIN (1<<31) -#define __EXEC_OBJECT_HAS_FENCE (1<<30) -#define __EXEC_OBJECT_NEEDS_MAP (1<<29) -#define __EXEC_OBJECT_NEEDS_BIAS (1<<28) -#define __EXEC_OBJECT_INTERNAL_FLAGS (0xf<<28) /* all of the above */ +#define __EXEC_HAS_RELOC BIT(31) +#define __EXEC_VALIDATED BIT(30) +#define UPDATE PIN_OFFSET_FIXED #define BATCH_OFFSET_BIAS (256*1024) -struct i915_execbuffer_params { - struct drm_device *dev; - struct drm_file *file; - struct i915_vma *batch; - u32 dispatch_flags; - u32 args_batch_start_offset; - struct intel_engine_cs *engine; - struct i915_gem_context *ctx; - struct drm_i915_gem_request *request; -}; +#define __I915_EXEC_ILLEGAL_FLAGS \ + (__I915_EXEC_UNKNOWN_FLAGS | I915_EXEC_CONSTANTS_MASK) + +/** + * DOC: User command execution + * + * Userspace submits commands to be executed on the GPU as an instruction + * stream within a GEM object we call a batchbuffer. This instructions may + * refer to other GEM objects containing auxiliary state such as kernels, + * samplers, render targets and even secondary batchbuffers. Userspace does + * not know where in the GPU memory these objects reside and so before the + * batchbuffer is passed to the GPU for execution, those addresses in the + * batchbuffer and auxiliary objects are updated. This is known as relocation, + * or patching. To try and avoid having to relocate each object on the next + * execution, userspace is told the location of those objects in this pass, + * but this remains just a hint as the kernel may choose a new location for + * any object in the future. + * + * Processing an execbuf ioctl is conceptually split up into a few phases. + * + * 1. Validation - Ensure all the pointers, handles and flags are valid. + * 2. Reservation - Assign GPU address space for every object + * 3. Relocation - Update any addresses to point to the final locations + * 4. Serialisation - Order the request with respect to its dependencies + * 5. Construction - Construct a request to execute the batchbuffer + * 6. Submission (at some point in the future execution) + * + * Reserving resources for the execbuf is the most complicated phase. We + * neither want to have to migrate the object in the address space, nor do + * we want to have to update any relocations pointing to this object. Ideally, + * we want to leave the object where it is and for all the existing relocations + * to match. If the object is given a new address, or if userspace thinks the + * object is elsewhere, we have to parse all the relocation entries and update + * the addresses. Userspace can set the I915_EXEC_NORELOC flag to hint that + * all the target addresses in all of its objects match the value in the + * relocation entries and that they all match the presumed offsets given by the + * list of execbuffer objects. Using this knowledge, we know that if we haven't + * moved any buffers, all the relocation entries are valid and we can skip + * the update. (If userspace is wrong, the likely outcome is an impromptu GPU + * hang.) The requirement for using I915_EXEC_NO_RELOC are: + * + * The addresses written in the objects must match the corresponding + * reloc.presumed_offset which in turn must match the corresponding + * execobject.offset. + * + * Any render targets written to in the batch must be flagged with + * EXEC_OBJECT_WRITE. + * + * To avoid stalling, execobject.offset should match the current + * address of that object within the active context. + * + * The reservation is done is multiple phases. First we try and keep any + * object already bound in its current location - so as long as meets the + * constraints imposed by the new execbuffer. Any object left unbound after the + * first pass is then fitted into any available idle space. If an object does + * not fit, all objects are removed from the reservation and the process rerun + * after sorting the objects into a priority order (more difficult to fit + * objects are tried first). Failing that, the entire VM is cleared and we try + * to fit the execbuf once last time before concluding that it simply will not + * fit. + * + * A small complication to all of this is that we allow userspace not only to + * specify an alignment and a size for the object in the address space, but + * we also allow userspace to specify the exact offset. This objects are + * simpler to place (the location is known a priori) all we have to do is make + * sure the space is available. + * + * Once all the objects are in place, patching up the buried pointers to point + * to the final locations is a fairly simple job of walking over the relocation + * entry arrays, looking up the right address and rewriting the value into + * the object. Simple! ... The relocation entries are stored in user memory + * and so to access them we have to copy them into a local buffer. That copy + * has to avoid taking any pagefaults as they may lead back to a GEM object + * requiring the struct_mutex (i.e. recursive deadlock). So once again we split + * the relocation into multiple passes. First we try to do everything within an + * atomic context (avoid the pagefaults) which requires that we never wait. If + * we detect that we may wait, or if we need to fault, then we have to fallback + * to a slower path. The slowpath has to drop the mutex. (Can you hear alarm + * bells yet?) Dropping the mutex means that we lose all the state we have + * built up so far for the execbuf and we must reset any global data. However, + * we do leave the objects pinned in their final locations - which is a + * potential issue for concurrent execbufs. Once we have left the mutex, we can + * allocate and copy all the relocation entries into a large array at our + * leisure, reacquire the mutex, reclaim all the objects and other state and + * then proceed to update any incorrect addresses with the objects. + * + * As we process the relocation entries, we maintain a record of whether the + * object is being written to. Using NORELOC, we expect userspace to provide + * this information instead. We also check whether we can skip the relocation + * by comparing the expected value inside the relocation entry with the target's + * final address. If they differ, we have to map the current object and rewrite + * the 4 or 8 byte pointer within. + * + * Serialising an execbuf is quite simple according to the rules of the GEM + * ABI. Execution within each context is ordered by the order of submission. + * Writes to any GEM object are in order of submission and are exclusive. Reads + * from a GEM object are unordered with respect to other reads, but ordered by + * writes. A write submitted after a read cannot occur before the read, and + * similarly any read submitted after a write cannot occur before the write. + * Writes are ordered between engines such that only one write occurs at any + * time (completing any reads beforehand) - using semaphores where available + * and CPU serialisation otherwise. Other GEM access obey the same rules, any + * write (either via mmaps using set-domain, or via pwrite) must flush all GPU + * reads before starting, and any read (either using set-domain or pread) must + * flush all GPU writes before starting. (Note we only employ a barrier before, + * we currently rely on userspace not concurrently starting a new execution + * whilst reading or writing to an object. This may be an advantage or not + * depending on how much you trust userspace not to shoot themselves in the + * foot.) Serialisation may just result in the request being inserted into + * a DAG awaiting its turn, but most simple is to wait on the CPU until + * all dependencies are resolved. + * + * After all of that, is just a matter of closing the request and handing it to + * the hardware (well, leaving it in a queue to be executed). However, we also + * offer the ability for batchbuffers to be run with elevated privileges so + * that they access otherwise hidden registers. (Used to adjust L3 cache etc.) + * Before any batch is given extra privileges we first must check that it + * contains no nefarious instructions, we check that each instruction is from + * our whitelist and all registers are also from an allowed list. We first + * copy the user's batchbuffer to a shadow (so that the user doesn't have + * access to it, either by the CPU or GPU as we scan it) and then parse each + * instruction. If everything is ok, we set a flag telling the hardware to run + * the batchbuffer in trusted mode, otherwise the ioctl is rejected. + */ + +struct i915_execbuffer { + struct drm_i915_private *i915; /** i915 backpointer */ + struct drm_file *file; /** per-file lookup tables and limits */ + struct drm_i915_gem_execbuffer2 *args; /** ioctl parameters */ + struct drm_i915_gem_exec_object2 *exec; /** ioctl execobj[] */ + + struct intel_engine_cs *engine; /** engine to queue the request to */ + struct i915_gem_context *ctx; /** context for building the request */ + struct i915_address_space *vm; /** GTT and vma for the request */ + + struct drm_i915_gem_request *request; /** our request to build */ + struct i915_vma *batch; /** identity of the batch obj/vma */ + + /** actual size of execobj[] as we may extend it for the cmdparser */ + unsigned int buffer_count; + + /** list of vma not yet bound during reservation phase */ + struct list_head unbound; + + /** list of vma that have execobj.relocation_count */ + struct list_head relocs; -struct eb_vmas { - struct drm_i915_private *i915; - struct list_head vmas; - int and; - union { - struct i915_vma *lut[0]; - struct hlist_head buckets[0]; - }; + /** + * Track the most recently used object for relocations, as we + * frequently have to perform multiple relocations within the same + * obj/page + */ + struct reloc_cache { + struct drm_mm_node node; /** temporary GTT binding */ + unsigned long vaddr; /** Current kmap address */ + unsigned long page; /** Currently mapped page index */ + unsigned int gen; /** Cached value of INTEL_GEN */ + bool use_64bit_reloc : 1; + bool has_llc : 1; + bool has_fence : 1; + bool needs_unfenced : 1; + + struct drm_i915_gem_request *rq; + u32 *rq_cmd; + unsigned int rq_size; + } reloc_cache; + + u64 invalid_flags; /** Set of execobj.flags that are invalid */ + u32 context_flags; /** Set of execobj.flags to insert from the ctx */ + + u32 batch_start_offset; /** Location within object of batch */ + u32 batch_len; /** Length of batch within object */ + u32 batch_flags; /** Flags composed for emit_bb_start() */ + + /** + * Indicate either the size of the hastable used to resolve + * relocation handles, or if negative that we are using a direct + * index into the execobj[]. + */ + int lut_size; + struct hlist_head *buckets; /** ht for relocation handles */ }; -static struct eb_vmas * -eb_create(struct drm_i915_private *i915, - struct drm_i915_gem_execbuffer2 *args) +/* + * As an alternative to creating a hashtable of handle-to-vma for a batch, + * we used the last available reserved field in the execobject[] and stash + * a link from the execobj to its vma. + */ +#define __exec_to_vma(ee) (ee)->rsvd2 +#define exec_to_vma(ee) u64_to_ptr(struct i915_vma, __exec_to_vma(ee)) + +/* + * Used to convert any address to canonical form. + * Starting from gen8, some commands (e.g. STATE_BASE_ADDRESS, + * MI_LOAD_REGISTER_MEM and others, see Broadwell PRM Vol2a) require the + * addresses to be in a canonical form: + * "GraphicsAddress[63:48] are ignored by the HW and assumed to be in correct + * canonical form [63:48] == [47]." + */ +#define GEN8_HIGH_ADDRESS_BIT 47 +static inline u64 gen8_canonical_addr(u64 address) { - struct eb_vmas *eb = NULL; - - if (args->flags & I915_EXEC_HANDLE_LUT) { - unsigned size = args->buffer_count; - size *= sizeof(struct i915_vma *); - size += sizeof(struct eb_vmas); - eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); - } - - if (eb == NULL) { - unsigned size = args->buffer_count; - unsigned count = PAGE_SIZE / sizeof(struct hlist_head) / 2; - BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head)); - while (count > 2*size) - count >>= 1; - eb = kzalloc(count*sizeof(struct hlist_head) + - sizeof(struct eb_vmas), - GFP_TEMPORARY); - if (eb == NULL) - return eb; - - eb->and = count - 1; - } else - eb->and = -args->buffer_count; + return sign_extend64(address, GEN8_HIGH_ADDRESS_BIT); +} - eb->i915 = i915; - INIT_LIST_HEAD(&eb->vmas); - return eb; +static inline u64 gen8_noncanonical_addr(u64 address) +{ + return address & GENMASK_ULL(GEN8_HIGH_ADDRESS_BIT, 0); } -static void -eb_reset(struct eb_vmas *eb) +static int eb_create(struct i915_execbuffer *eb) { - if (eb->and >= 0) - memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); + if (!(eb->args->flags & I915_EXEC_HANDLE_LUT)) { + unsigned int size = 1 + ilog2(eb->buffer_count); + + /* + * Without a 1:1 association between relocation handles and + * the execobject[] index, we instead create a hashtable. + * We size it dynamically based on available memory, starting + * first with 1:1 assocative hash and scaling back until + * the allocation succeeds. + * + * Later on we use a positive lut_size to indicate we are + * using this hashtable, and a negative value to indicate a + * direct lookup. + */ + do { + eb->buckets = kzalloc(sizeof(struct hlist_head) << size, + GFP_TEMPORARY | + __GFP_NORETRY | + __GFP_NOWARN); + if (eb->buckets) + break; + } while (--size); + + if (unlikely(!eb->buckets)) { + eb->buckets = kzalloc(sizeof(struct hlist_head), + GFP_TEMPORARY); + if (unlikely(!eb->buckets)) + return -ENOMEM; + } + + eb->lut_size = size; + } else { + eb->lut_size = -eb->buffer_count; + } + + return 0; } -static struct i915_vma * -eb_get_batch(struct eb_vmas *eb) +static bool +eb_vma_misplaced(const struct drm_i915_gem_exec_object2 *entry, + const struct i915_vma *vma) +{ + if (!(entry->flags & __EXEC_OBJECT_HAS_PIN)) + return true; + + if (vma->node.size < entry->pad_to_size) + return true; + + if (entry->alignment && !IS_ALIGNED(vma->node.start, entry->alignment)) + return true; + + if (entry->flags & EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) + return true; + + if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && + vma->node.start < BATCH_OFFSET_BIAS) + return true; + + if (!(entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) && + (vma->node.start + vma->node.size - 1) >> 32) + return true; + + return false; +} + +static inline void +eb_pin_vma(struct i915_execbuffer *eb, + struct drm_i915_gem_exec_object2 *entry, + struct i915_vma *vma) +{ + u64 flags; + + if (vma->node.size) + flags = vma->node.start; + else + flags = entry->offset & PIN_OFFSET_MASK; + + flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED; + if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_GTT)) + flags |= PIN_GLOBAL; + + if (unlikely(i915_vma_pin(vma, 0, 0, flags))) + return; + + if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_FENCE)) { + if (unlikely(i915_vma_get_fence(vma))) { + i915_vma_unpin(vma); + return; + } + + if (i915_vma_pin_fence(vma)) + entry->flags |= __EXEC_OBJECT_HAS_FENCE; + } + + entry->flags |= __EXEC_OBJECT_HAS_PIN; +} + +static inline void +__eb_unreserve_vma(struct i915_vma *vma, + const struct drm_i915_gem_exec_object2 *entry) +{ + GEM_BUG_ON(!(entry->flags & __EXEC_OBJECT_HAS_PIN)); + + if (unlikely(entry->flags & __EXEC_OBJECT_HAS_FENCE)) + i915_vma_unpin_fence(vma); + + __i915_vma_unpin(vma); +} + +static inline void +eb_unreserve_vma(struct i915_vma *vma, + struct drm_i915_gem_exec_object2 *entry) { - struct i915_vma *vma = list_entry(eb->vmas.prev, typeof(*vma), exec_list); + if (!(entry->flags & __EXEC_OBJECT_HAS_PIN)) + return; + + __eb_unreserve_vma(vma, entry); + entry->flags &= ~__EXEC_OBJECT_RESERVED; +} + +static int +eb_validate_vma(struct i915_execbuffer *eb, + struct drm_i915_gem_exec_object2 *entry, + struct i915_vma *vma) +{ + if (unlikely(entry->flags & eb->invalid_flags)) + return -EINVAL; + + if (unlikely(entry->alignment && !is_power_of_2(entry->alignment))) + return -EINVAL; /* - * SNA is doing fancy tricks with compressing batch buffers, which leads - * to negative relocation deltas. Usually that works out ok since the - * relocate address is still positive, except when the batch is placed - * very low in the GTT. Ensure this doesn't happen. - * - * Note that actual hangs have only been observed on gen7, but for - * paranoia do it everywhere. + * Offset can be used as input (EXEC_OBJECT_PINNED), reject + * any non-page-aligned or non-canonical addresses. */ - if ((vma->exec_entry->flags & EXEC_OBJECT_PINNED) == 0) - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; + if (unlikely(entry->flags & EXEC_OBJECT_PINNED && + entry->offset != gen8_canonical_addr(entry->offset & PAGE_MASK))) + return -EINVAL; - return vma; + /* pad_to_size was once a reserved field, so sanitize it */ + if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) { + if (unlikely(offset_in_page(entry->pad_to_size))) + return -EINVAL; + } else { + entry->pad_to_size = 0; + } + + if (unlikely(vma->exec_entry)) { + DRM_DEBUG("Object [handle %d, index %d] appears more than once in object list\n", + entry->handle, (int)(entry - eb->exec)); + return -EINVAL; + } + + /* + * From drm_mm perspective address space is continuous, + * so from this point we're always using non-canonical + * form internally. + */ + entry->offset = gen8_noncanonical_addr(entry->offset); + + return 0; } static int -eb_lookup_vmas(struct eb_vmas *eb, - struct drm_i915_gem_exec_object2 *exec, - const struct drm_i915_gem_execbuffer2 *args, - struct i915_address_space *vm, - struct drm_file *file) +eb_add_vma(struct i915_execbuffer *eb, + struct drm_i915_gem_exec_object2 *entry, + struct i915_vma *vma) { - struct drm_i915_gem_object *obj; - struct list_head objects; - int i, ret; + int err; - INIT_LIST_HEAD(&objects); - spin_lock(&file->table_lock); - /* Grab a reference to the object and release the lock so we can lookup - * or create the VMA without using GFP_ATOMIC */ - for (i = 0; i < args->buffer_count; i++) { - obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle)); - if (obj == NULL) { - spin_unlock(&file->table_lock); - DRM_DEBUG("Invalid object handle %d at index %d\n", - exec[i].handle, i); - ret = -ENOENT; - goto err; + GEM_BUG_ON(i915_vma_is_closed(vma)); + + if (!(eb->args->flags & __EXEC_VALIDATED)) { + err = eb_validate_vma(eb, entry, vma); + if (unlikely(err)) + return err; + } + + if (eb->lut_size >= 0) { + vma->exec_handle = entry->handle; + hlist_add_head(&vma->exec_node, + &eb->buckets[hash_32(entry->handle, + eb->lut_size)]); + } + + if (entry->relocation_count) + list_add_tail(&vma->reloc_link, &eb->relocs); + + if (!eb->reloc_cache.has_fence) { + entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE; + } else { + if ((entry->flags & EXEC_OBJECT_NEEDS_FENCE || + eb->reloc_cache.needs_unfenced) && + i915_gem_object_is_tiled(vma->obj)) + entry->flags |= EXEC_OBJECT_NEEDS_GTT | __EXEC_OBJECT_NEEDS_MAP; + } + + if (!(entry->flags & EXEC_OBJECT_PINNED)) + entry->flags |= eb->context_flags; + + /* + * Stash a pointer from the vma to execobj, so we can query its flags, + * size, alignment etc as provided by the user. Also we stash a pointer + * to the vma inside the execobj so that we can use a direct lookup + * to find the right target VMA when doing relocations. + */ + vma->exec_entry = entry; + __exec_to_vma(entry) = (uintptr_t)vma; + + err = 0; + eb_pin_vma(eb, entry, vma); + if (eb_vma_misplaced(entry, vma)) { + eb_unreserve_vma(vma, entry); + + list_add_tail(&vma->exec_link, &eb->unbound); + if (drm_mm_node_allocated(&vma->node)) + err = i915_vma_unbind(vma); + } else { + if (entry->offset != vma->node.start) { + entry->offset = vma->node.start | UPDATE; + eb->args->flags |= __EXEC_HAS_RELOC; + } + } + return err; +} + +static inline int use_cpu_reloc(const struct reloc_cache *cache, + const struct drm_i915_gem_object *obj) +{ + if (!i915_gem_object_has_struct_page(obj)) + return false; + + if (DBG_FORCE_RELOC == FORCE_CPU_RELOC) + return true; + + if (DBG_FORCE_RELOC == FORCE_GTT_RELOC) + return false; + + return (cache->has_llc || + obj->cache_dirty || + obj->cache_level != I915_CACHE_NONE); +} + +static int eb_reserve_vma(const struct i915_execbuffer *eb, + struct i915_vma *vma) +{ + struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + u64 flags; + int err; + + flags = PIN_USER | PIN_NONBLOCK; + if (entry->flags & EXEC_OBJECT_NEEDS_GTT) + flags |= PIN_GLOBAL; + + /* + * Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset, + * limit address to the first 4GBs for unflagged objects. + */ + if (!(entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS)) + flags |= PIN_ZONE_4G; + + if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) + flags |= PIN_MAPPABLE; + + if (entry->flags & EXEC_OBJECT_PINNED) { + flags |= entry->offset | PIN_OFFSET_FIXED; + flags &= ~PIN_NONBLOCK; /* force overlapping PINNED checks */ + } else if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) { + flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS; + } + + err = i915_vma_pin(vma, entry->pad_to_size, entry->alignment, flags); + if (err) + return err; + + if (entry->offset != vma->node.start) { + entry->offset = vma->node.start | UPDATE; + eb->args->flags |= __EXEC_HAS_RELOC; + } + + entry->flags |= __EXEC_OBJECT_HAS_PIN; + GEM_BUG_ON(eb_vma_misplaced(entry, vma)); + + if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_FENCE)) { + err = i915_vma_get_fence(vma); + if (unlikely(err)) { + i915_vma_unpin(vma); + return err; + } + + if (i915_vma_pin_fence(vma)) + entry->flags |= __EXEC_OBJECT_HAS_FENCE; + } + + return 0; +} + +static int eb_reserve(struct i915_execbuffer *eb) +{ + const unsigned int count = eb->buffer_count; + struct list_head last; + struct i915_vma *vma; + unsigned int i, pass; + int err; + + /* + * Attempt to pin all of the buffers into the GTT. + * This is done in 3 phases: + * + * 1a. Unbind all objects that do not match the GTT constraints for + * the execbuffer (fenceable, mappable, alignment etc). + * 1b. Increment pin count for already bound objects. + * 2. Bind new objects. + * 3. Decrement pin count. + * + * This avoid unnecessary unbinding of later objects in order to make + * room for the earlier objects *unless* we need to defragment. + */ + + pass = 0; + err = 0; + do { + list_for_each_entry(vma, &eb->unbound, exec_link) { + err = eb_reserve_vma(eb, vma); + if (err) + break; + } + if (err != -ENOSPC) + return err; + + /* Resort *all* the objects into priority order */ + INIT_LIST_HEAD(&eb->unbound); + INIT_LIST_HEAD(&last); + for (i = 0; i < count; i++) { + struct drm_i915_gem_exec_object2 *entry = &eb->exec[i]; + + if (entry->flags & EXEC_OBJECT_PINNED && + entry->flags & __EXEC_OBJECT_HAS_PIN) + continue; + + vma = exec_to_vma(entry); + eb_unreserve_vma(vma, entry); + + if (entry->flags & EXEC_OBJECT_PINNED) + list_add(&vma->exec_link, &eb->unbound); + else if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) + list_add_tail(&vma->exec_link, &eb->unbound); + else + list_add_tail(&vma->exec_link, &last); + } + list_splice_tail(&last, &eb->unbound); + + switch (pass++) { + case 0: + break; + + case 1: + /* Too fragmented, unbind everything and retry */ + err = i915_gem_evict_vm(eb->vm); + if (err) + return err; + break; + + default: + return -ENOSPC; } + } while (1); +} + +static inline struct hlist_head * +ht_head(const struct i915_gem_context_vma_lut *lut, u32 handle) +{ + return &lut->ht[hash_32(handle, lut->ht_bits)]; +} - if (!list_empty(&obj->obj_exec_link)) { - spin_unlock(&file->table_lock); - DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", - obj, exec[i].handle, i); - ret = -EINVAL; +static inline bool +ht_needs_resize(const struct i915_gem_context_vma_lut *lut) +{ + return (4*lut->ht_count > 3*lut->ht_size || + 4*lut->ht_count + 1 < lut->ht_size); +} + +static unsigned int eb_batch_index(const struct i915_execbuffer *eb) +{ + if (eb->args->flags & I915_EXEC_BATCH_FIRST) + return 0; + else + return eb->buffer_count - 1; +} + +static int eb_select_context(struct i915_execbuffer *eb) +{ + struct i915_gem_context *ctx; + + ctx = i915_gem_context_lookup(eb->file->driver_priv, eb->args->rsvd1); + if (unlikely(IS_ERR(ctx))) + return PTR_ERR(ctx); + + if (unlikely(i915_gem_context_is_banned(ctx))) { + DRM_DEBUG("Context %u tried to submit while banned\n", + ctx->user_handle); + return -EIO; + } + + eb->ctx = i915_gem_context_get(ctx); + eb->vm = ctx->ppgtt ? &ctx->ppgtt->base : &eb->i915->ggtt.base; + + eb->context_flags = 0; + if (ctx->flags & CONTEXT_NO_ZEROMAP) + eb->context_flags |= __EXEC_OBJECT_NEEDS_BIAS; + + return 0; +} + +static int eb_lookup_vmas(struct i915_execbuffer *eb) +{ +#define INTERMEDIATE BIT(0) + const unsigned int count = eb->buffer_count; + struct i915_gem_context_vma_lut *lut = &eb->ctx->vma_lut; + struct i915_vma *vma; + struct idr *idr; + unsigned int i; + int slow_pass = -1; + int err; + + INIT_LIST_HEAD(&eb->relocs); + INIT_LIST_HEAD(&eb->unbound); + + if (unlikely(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS)) + flush_work(&lut->resize); + GEM_BUG_ON(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS); + + for (i = 0; i < count; i++) { + __exec_to_vma(&eb->exec[i]) = 0; + + hlist_for_each_entry(vma, + ht_head(lut, eb->exec[i].handle), + ctx_node) { + if (vma->ctx_handle != eb->exec[i].handle) + continue; + + err = eb_add_vma(eb, &eb->exec[i], vma); + if (unlikely(err)) + return err; + + goto next_vma; + } + + if (slow_pass < 0) + slow_pass = i; +next_vma: ; + } + + if (slow_pass < 0) + goto out; + + spin_lock(&eb->file->table_lock); + /* + * Grab a reference to the object and release the lock so we can lookup + * or create the VMA without using GFP_ATOMIC + */ + idr = &eb->file->object_idr; + for (i = slow_pass; i < count; i++) { + struct drm_i915_gem_object *obj; + + if (__exec_to_vma(&eb->exec[i])) + continue; + + obj = to_intel_bo(idr_find(idr, eb->exec[i].handle)); + if (unlikely(!obj)) { + spin_unlock(&eb->file->table_lock); + DRM_DEBUG("Invalid object handle %d at index %d\n", + eb->exec[i].handle, i); + err = -ENOENT; goto err; } - i915_gem_object_get(obj); - list_add_tail(&obj->obj_exec_link, &objects); + __exec_to_vma(&eb->exec[i]) = INTERMEDIATE | (uintptr_t)obj; } - spin_unlock(&file->table_lock); + spin_unlock(&eb->file->table_lock); - i = 0; - while (!list_empty(&objects)) { - struct i915_vma *vma; + for (i = slow_pass; i < count; i++) { + struct drm_i915_gem_object *obj; - obj = list_first_entry(&objects, - struct drm_i915_gem_object, - obj_exec_link); + if (!(__exec_to_vma(&eb->exec[i]) & INTERMEDIATE)) + continue; /* * NOTE: We can leak any vmas created here when something fails @@ -186,59 +769,93 @@ eb_lookup_vmas(struct eb_vmas *eb, * from the (obj, vm) we don't run the risk of creating * duplicated vmas for the same vm. */ - vma = i915_vma_instance(obj, vm, NULL); + obj = u64_to_ptr(typeof(*obj), + __exec_to_vma(&eb->exec[i]) & ~INTERMEDIATE); + vma = i915_vma_instance(obj, eb->vm, NULL); if (unlikely(IS_ERR(vma))) { DRM_DEBUG("Failed to lookup VMA\n"); - ret = PTR_ERR(vma); + err = PTR_ERR(vma); goto err; } - /* Transfer ownership from the objects list to the vmas list. */ - list_add_tail(&vma->exec_list, &eb->vmas); - list_del_init(&obj->obj_exec_link); + /* First come, first served */ + if (!vma->ctx) { + vma->ctx = eb->ctx; + vma->ctx_handle = eb->exec[i].handle; + hlist_add_head(&vma->ctx_node, + ht_head(lut, eb->exec[i].handle)); + lut->ht_count++; + lut->ht_size |= I915_CTX_RESIZE_IN_PROGRESS; + if (i915_vma_is_ggtt(vma)) { + GEM_BUG_ON(obj->vma_hashed); + obj->vma_hashed = vma; + } - vma->exec_entry = &exec[i]; - if (eb->and < 0) { - eb->lut[i] = vma; - } else { - uint32_t handle = args->flags & I915_EXEC_HANDLE_LUT ? i : exec[i].handle; - vma->exec_handle = handle; - hlist_add_head(&vma->exec_node, - &eb->buckets[handle & eb->and]); + i915_vma_get(vma); } - ++i; - } - return 0; + err = eb_add_vma(eb, &eb->exec[i], vma); + if (unlikely(err)) + goto err; + /* Only after we validated the user didn't use our bits */ + if (vma->ctx != eb->ctx) { + i915_vma_get(vma); + eb->exec[i].flags |= __EXEC_OBJECT_HAS_REF; + } + } -err: - while (!list_empty(&objects)) { - obj = list_first_entry(&objects, - struct drm_i915_gem_object, - obj_exec_link); - list_del_init(&obj->obj_exec_link); - i915_gem_object_put(obj); + if (lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS) { + if (ht_needs_resize(lut)) + queue_work(system_highpri_wq, &lut->resize); + else + lut->ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS; } + +out: + /* take note of the batch buffer before we might reorder the lists */ + i = eb_batch_index(eb); + eb->batch = exec_to_vma(&eb->exec[i]); + /* - * Objects already transfered to the vmas list will be unreferenced by - * eb_destroy. + * SNA is doing fancy tricks with compressing batch buffers, which leads + * to negative relocation deltas. Usually that works out ok since the + * relocate address is still positive, except when the batch is placed + * very low in the GTT. Ensure this doesn't happen. + * + * Note that actual hangs have only been observed on gen7, but for + * paranoia do it everywhere. */ + if (!(eb->exec[i].flags & EXEC_OBJECT_PINNED)) + eb->exec[i].flags |= __EXEC_OBJECT_NEEDS_BIAS; + if (eb->reloc_cache.has_fence) + eb->exec[i].flags |= EXEC_OBJECT_NEEDS_FENCE; + + eb->args->flags |= __EXEC_VALIDATED; + return eb_reserve(eb); - return ret; +err: + for (i = slow_pass; i < count; i++) { + if (__exec_to_vma(&eb->exec[i]) & INTERMEDIATE) + __exec_to_vma(&eb->exec[i]) = 0; + } + lut->ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS; + return err; +#undef INTERMEDIATE } -static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle) +static struct i915_vma * +eb_get_vma(const struct i915_execbuffer *eb, unsigned long handle) { - if (eb->and < 0) { - if (handle >= -eb->and) + if (eb->lut_size < 0) { + if (handle >= -eb->lut_size) return NULL; - return eb->lut[handle]; + return exec_to_vma(&eb->exec[handle]); } else { struct hlist_head *head; struct i915_vma *vma; - head = &eb->buckets[handle & eb->and]; + head = &eb->buckets[hash_32(handle, eb->lut_size)]; hlist_for_each_entry(vma, head, exec_node) { if (vma->exec_handle == handle) return vma; @@ -247,96 +864,69 @@ static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle) } } -static void -i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma) +static void eb_release_vmas(const struct i915_execbuffer *eb) { - struct drm_i915_gem_exec_object2 *entry; + const unsigned int count = eb->buffer_count; + unsigned int i; - if (!drm_mm_node_allocated(&vma->node)) - return; + for (i = 0; i < count; i++) { + struct drm_i915_gem_exec_object2 *entry = &eb->exec[i]; + struct i915_vma *vma = exec_to_vma(entry); - entry = vma->exec_entry; + if (!vma) + continue; - if (entry->flags & __EXEC_OBJECT_HAS_FENCE) - i915_vma_unpin_fence(vma); + GEM_BUG_ON(vma->exec_entry != entry); + vma->exec_entry = NULL; - if (entry->flags & __EXEC_OBJECT_HAS_PIN) - __i915_vma_unpin(vma); + if (entry->flags & __EXEC_OBJECT_HAS_PIN) + __eb_unreserve_vma(vma, entry); - entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN); -} + if (entry->flags & __EXEC_OBJECT_HAS_REF) + i915_vma_put(vma); -static void eb_destroy(struct eb_vmas *eb) -{ - while (!list_empty(&eb->vmas)) { - struct i915_vma *vma; - - vma = list_first_entry(&eb->vmas, - struct i915_vma, - exec_list); - list_del_init(&vma->exec_list); - i915_gem_execbuffer_unreserve_vma(vma); - vma->exec_entry = NULL; - i915_vma_put(vma); + entry->flags &= + ~(__EXEC_OBJECT_RESERVED | __EXEC_OBJECT_HAS_REF); } - kfree(eb); } -static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) +static void eb_reset_vmas(const struct i915_execbuffer *eb) { - if (!i915_gem_object_has_struct_page(obj)) - return false; - - if (DBG_USE_CPU_RELOC) - return DBG_USE_CPU_RELOC > 0; - - return (HAS_LLC(to_i915(obj->base.dev)) || - obj->base.write_domain == I915_GEM_DOMAIN_CPU || - obj->cache_level != I915_CACHE_NONE); + eb_release_vmas(eb); + if (eb->lut_size >= 0) + memset(eb->buckets, 0, + sizeof(struct hlist_head) << eb->lut_size); } -/* Used to convert any address to canonical form. - * Starting from gen8, some commands (e.g. STATE_BASE_ADDRESS, - * MI_LOAD_REGISTER_MEM and others, see Broadwell PRM Vol2a) require the - * addresses to be in a canonical form: - * "GraphicsAddress[63:48] are ignored by the HW and assumed to be in correct - * canonical form [63:48] == [47]." - */ -#define GEN8_HIGH_ADDRESS_BIT 47 -static inline uint64_t gen8_canonical_addr(uint64_t address) +static void eb_destroy(const struct i915_execbuffer *eb) { - return sign_extend64(address, GEN8_HIGH_ADDRESS_BIT); -} + GEM_BUG_ON(eb->reloc_cache.rq); -static inline uint64_t gen8_noncanonical_addr(uint64_t address) -{ - return address & ((1ULL << (GEN8_HIGH_ADDRESS_BIT + 1)) - 1); + if (eb->lut_size >= 0) + kfree(eb->buckets); } -static inline uint64_t +static inline u64 relocation_target(const struct drm_i915_gem_relocation_entry *reloc, - uint64_t target_offset) + const struct i915_vma *target) { - return gen8_canonical_addr((int)reloc->delta + target_offset); + return gen8_canonical_addr((int)reloc->delta + target->node.start); } -struct reloc_cache { - struct drm_i915_private *i915; - struct drm_mm_node node; - unsigned long vaddr; - unsigned int page; - bool use_64bit_reloc; -}; - static void reloc_cache_init(struct reloc_cache *cache, struct drm_i915_private *i915) { cache->page = -1; cache->vaddr = 0; - cache->i915 = i915; /* Must be a variable in the struct to allow GCC to unroll. */ + cache->gen = INTEL_GEN(i915); + cache->has_llc = HAS_LLC(i915); cache->use_64bit_reloc = HAS_64BIT_RELOC(i915); + cache->has_fence = cache->gen < 4; + cache->needs_unfenced = INTEL_INFO(i915)->unfenced_needs_alignment; cache->node.allocated = false; + cache->rq = NULL; + cache->rq_size = 0; } static inline void *unmask_page(unsigned long p) @@ -351,10 +941,31 @@ static inline unsigned int unmask_flags(unsigned long p) #define KMAP 0x4 /* after CLFLUSH_FLAGS */ -static void reloc_cache_fini(struct reloc_cache *cache) +static inline struct i915_ggtt *cache_to_ggtt(struct reloc_cache *cache) +{ + struct drm_i915_private *i915 = + container_of(cache, struct i915_execbuffer, reloc_cache)->i915; + return &i915->ggtt; +} + +static void reloc_gpu_flush(struct reloc_cache *cache) +{ + GEM_BUG_ON(cache->rq_size >= cache->rq->batch->obj->base.size / sizeof(u32)); + cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END; + i915_gem_object_unpin_map(cache->rq->batch->obj); + i915_gem_chipset_flush(cache->rq->i915); + + __i915_add_request(cache->rq, true); + cache->rq = NULL; +} + +static void reloc_cache_reset(struct reloc_cache *cache) { void *vaddr; + if (cache->rq) + reloc_gpu_flush(cache); + if (!cache->vaddr) return; @@ -369,7 +980,7 @@ static void reloc_cache_fini(struct reloc_cache *cache) wmb(); io_mapping_unmap_atomic((void __iomem *)vaddr); if (cache->node.allocated) { - struct i915_ggtt *ggtt = &cache->i915->ggtt; + struct i915_ggtt *ggtt = cache_to_ggtt(cache); ggtt->base.clear_range(&ggtt->base, cache->node.start, @@ -379,11 +990,14 @@ static void reloc_cache_fini(struct reloc_cache *cache) i915_vma_unpin((struct i915_vma *)cache->node.mm); } } + + cache->vaddr = 0; + cache->page = -1; } static void *reloc_kmap(struct drm_i915_gem_object *obj, struct reloc_cache *cache, - int page) + unsigned long page) { void *vaddr; @@ -391,11 +1005,11 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj, kunmap_atomic(unmask_page(cache->vaddr)); } else { unsigned int flushes; - int ret; + int err; - ret = i915_gem_obj_prepare_shmem_write(obj, &flushes); - if (ret) - return ERR_PTR(ret); + err = i915_gem_obj_prepare_shmem_write(obj, &flushes); + if (err) + return ERR_PTR(err); BUILD_BUG_ON(KMAP & CLFLUSH_FLAGS); BUILD_BUG_ON((KMAP | CLFLUSH_FLAGS) & PAGE_MASK); @@ -415,9 +1029,9 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj, static void *reloc_iomap(struct drm_i915_gem_object *obj, struct reloc_cache *cache, - int page) + unsigned long page) { - struct i915_ggtt *ggtt = &cache->i915->ggtt; + struct i915_ggtt *ggtt = cache_to_ggtt(cache); unsigned long offset; void *vaddr; @@ -425,31 +1039,31 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj, io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr)); } else { struct i915_vma *vma; - int ret; + int err; - if (use_cpu_reloc(obj)) + if (use_cpu_reloc(cache, obj)) return NULL; - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) - return ERR_PTR(ret); + err = i915_gem_object_set_to_gtt_domain(obj, true); + if (err) + return ERR_PTR(err); vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE | PIN_NONBLOCK); if (IS_ERR(vma)) { memset(&cache->node, 0, sizeof(cache->node)); - ret = drm_mm_insert_node_in_range + err = drm_mm_insert_node_in_range (&ggtt->base.mm, &cache->node, PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE, 0, ggtt->mappable_end, DRM_MM_INSERT_LOW); - if (ret) /* no inactive aperture space, use cpu reloc */ + if (err) /* no inactive aperture space, use cpu reloc */ return NULL; } else { - ret = i915_vma_put_fence(vma); - if (ret) { + err = i915_vma_put_fence(vma); + if (err) { i915_vma_unpin(vma); - return ERR_PTR(ret); + return ERR_PTR(err); } cache->node.start = vma->node.start; @@ -467,7 +1081,8 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj, offset += page << PAGE_SHIFT; } - vaddr = (void __force *) io_mapping_map_atomic_wc(&cache->i915->ggtt.mappable, offset); + vaddr = (void __force *)io_mapping_map_atomic_wc(&ggtt->mappable, + offset); cache->page = page; cache->vaddr = (unsigned long)vaddr; @@ -476,7 +1091,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj, static void *reloc_vaddr(struct drm_i915_gem_object *obj, struct reloc_cache *cache, - int page) + unsigned long page) { void *vaddr; @@ -503,7 +1118,8 @@ static void clflush_write32(u32 *addr, u32 value, unsigned int flushes) *addr = value; - /* Writes to the same cacheline are serialised by the CPU + /* + * Writes to the same cacheline are serialised by the CPU * (including clflush). On the write path, we only require * that it hits memory in an orderly fashion and place * mb barriers at the start and end of the relocation phase @@ -515,25 +1131,201 @@ static void clflush_write32(u32 *addr, u32 value, unsigned int flushes) *addr = value; } -static int -relocate_entry(struct drm_i915_gem_object *obj, +static int __reloc_gpu_alloc(struct i915_execbuffer *eb, + struct i915_vma *vma, + unsigned int len) +{ + struct reloc_cache *cache = &eb->reloc_cache; + struct drm_i915_gem_object *obj; + struct drm_i915_gem_request *rq; + struct i915_vma *batch; + u32 *cmd; + int err; + + GEM_BUG_ON(vma->obj->base.write_domain & I915_GEM_DOMAIN_CPU); + + obj = i915_gem_batch_pool_get(&eb->engine->batch_pool, PAGE_SIZE); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + cmd = i915_gem_object_pin_map(obj, + cache->has_llc ? I915_MAP_WB : I915_MAP_WC); + i915_gem_object_unpin_pages(obj); + if (IS_ERR(cmd)) + return PTR_ERR(cmd); + + err = i915_gem_object_set_to_wc_domain(obj, false); + if (err) + goto err_unmap; + + batch = i915_vma_instance(obj, vma->vm, NULL); + if (IS_ERR(batch)) { + err = PTR_ERR(batch); + goto err_unmap; + } + + err = i915_vma_pin(batch, 0, 0, PIN_USER | PIN_NONBLOCK); + if (err) + goto err_unmap; + + rq = i915_gem_request_alloc(eb->engine, eb->ctx); + if (IS_ERR(rq)) { + err = PTR_ERR(rq); + goto err_unpin; + } + + err = i915_gem_request_await_object(rq, vma->obj, true); + if (err) + goto err_request; + + err = eb->engine->emit_flush(rq, EMIT_INVALIDATE); + if (err) + goto err_request; + + err = i915_switch_context(rq); + if (err) + goto err_request; + + err = eb->engine->emit_bb_start(rq, + batch->node.start, PAGE_SIZE, + cache->gen > 5 ? 0 : I915_DISPATCH_SECURE); + if (err) + goto err_request; + + GEM_BUG_ON(!reservation_object_test_signaled_rcu(batch->resv, true)); + i915_vma_move_to_active(batch, rq, 0); + reservation_object_lock(batch->resv, NULL); + reservation_object_add_excl_fence(batch->resv, &rq->fence); + reservation_object_unlock(batch->resv); + i915_vma_unpin(batch); + + i915_vma_move_to_active(vma, rq, true); + reservation_object_lock(vma->resv, NULL); + reservation_object_add_excl_fence(vma->resv, &rq->fence); + reservation_object_unlock(vma->resv); + + rq->batch = batch; + + cache->rq = rq; + cache->rq_cmd = cmd; + cache->rq_size = 0; + + /* Return with batch mapping (cmd) still pinned */ + return 0; + +err_request: + i915_add_request(rq); +err_unpin: + i915_vma_unpin(batch); +err_unmap: + i915_gem_object_unpin_map(obj); + return err; +} + +static u32 *reloc_gpu(struct i915_execbuffer *eb, + struct i915_vma *vma, + unsigned int len) +{ + struct reloc_cache *cache = &eb->reloc_cache; + u32 *cmd; + + if (cache->rq_size > PAGE_SIZE/sizeof(u32) - (len + 1)) + reloc_gpu_flush(cache); + + if (unlikely(!cache->rq)) { + int err; + + err = __reloc_gpu_alloc(eb, vma, len); + if (unlikely(err)) + return ERR_PTR(err); + } + + cmd = cache->rq_cmd + cache->rq_size; + cache->rq_size += len; + + return cmd; +} + +static u64 +relocate_entry(struct i915_vma *vma, const struct drm_i915_gem_relocation_entry *reloc, - struct reloc_cache *cache, - u64 target_offset) + struct i915_execbuffer *eb, + const struct i915_vma *target) { u64 offset = reloc->offset; - bool wide = cache->use_64bit_reloc; + u64 target_offset = relocation_target(reloc, target); + bool wide = eb->reloc_cache.use_64bit_reloc; void *vaddr; - target_offset = relocation_target(reloc, target_offset); + if (!eb->reloc_cache.vaddr && + (DBG_FORCE_RELOC == FORCE_GPU_RELOC || + !reservation_object_test_signaled_rcu(vma->resv, true))) { + const unsigned int gen = eb->reloc_cache.gen; + unsigned int len; + u32 *batch; + u64 addr; + + if (wide) + len = offset & 7 ? 8 : 5; + else if (gen >= 4) + len = 4; + else if (gen >= 3) + len = 3; + else /* On gen2 MI_STORE_DWORD_IMM uses a physical address */ + goto repeat; + + batch = reloc_gpu(eb, vma, len); + if (IS_ERR(batch)) + goto repeat; + + addr = gen8_canonical_addr(vma->node.start + offset); + if (wide) { + if (offset & 7) { + *batch++ = MI_STORE_DWORD_IMM_GEN4; + *batch++ = lower_32_bits(addr); + *batch++ = upper_32_bits(addr); + *batch++ = lower_32_bits(target_offset); + + addr = gen8_canonical_addr(addr + 4); + + *batch++ = MI_STORE_DWORD_IMM_GEN4; + *batch++ = lower_32_bits(addr); + *batch++ = upper_32_bits(addr); + *batch++ = upper_32_bits(target_offset); + } else { + *batch++ = (MI_STORE_DWORD_IMM_GEN4 | (1 << 21)) + 1; + *batch++ = lower_32_bits(addr); + *batch++ = upper_32_bits(addr); + *batch++ = lower_32_bits(target_offset); + *batch++ = upper_32_bits(target_offset); + } + } else if (gen >= 6) { + *batch++ = MI_STORE_DWORD_IMM_GEN4; + *batch++ = 0; + *batch++ = addr; + *batch++ = target_offset; + } else if (gen >= 4) { + *batch++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT; + *batch++ = 0; + *batch++ = addr; + *batch++ = target_offset; + } else { + *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL; + *batch++ = addr; + *batch++ = target_offset; + } + + goto out; + } + repeat: - vaddr = reloc_vaddr(obj, cache, offset >> PAGE_SHIFT); + vaddr = reloc_vaddr(vma->obj, &eb->reloc_cache, offset >> PAGE_SHIFT); if (IS_ERR(vaddr)) return PTR_ERR(vaddr); clflush_write32(vaddr + offset_in_page(offset), lower_32_bits(target_offset), - cache->vaddr); + eb->reloc_cache.vaddr); if (wide) { offset += sizeof(u32); @@ -542,48 +1334,29 @@ repeat: goto repeat; } - return 0; +out: + return target->node.start | UPDATE; } -static int -i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, - struct eb_vmas *eb, - struct drm_i915_gem_relocation_entry *reloc, - struct reloc_cache *cache) +static u64 +eb_relocate_entry(struct i915_execbuffer *eb, + struct i915_vma *vma, + const struct drm_i915_gem_relocation_entry *reloc) { - struct drm_i915_private *dev_priv = to_i915(obj->base.dev); - struct drm_gem_object *target_obj; - struct drm_i915_gem_object *target_i915_obj; - struct i915_vma *target_vma; - uint64_t target_offset; - int ret; + struct i915_vma *target; + int err; /* we've already hold a reference to all valid objects */ - target_vma = eb_get_vma(eb, reloc->target_handle); - if (unlikely(target_vma == NULL)) + target = eb_get_vma(eb, reloc->target_handle); + if (unlikely(!target)) return -ENOENT; - target_i915_obj = target_vma->obj; - target_obj = &target_vma->obj->base; - - target_offset = gen8_canonical_addr(target_vma->node.start); - - /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and - * pipe_control writes because the gpu doesn't properly redirect them - * through the ppgtt for non_secure batchbuffers. */ - if (unlikely(IS_GEN6(dev_priv) && - reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION)) { - ret = i915_vma_bind(target_vma, target_i915_obj->cache_level, - PIN_GLOBAL); - if (WARN_ONCE(ret, "Unexpected failure to bind target VMA!")) - return ret; - } /* Validate that the target is in a valid r/w GPU domain */ if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { DRM_DEBUG("reloc with multiple write domains: " - "obj %p target %d offset %d " + "target %d offset %d " "read %08x write %08x", - obj, reloc->target_handle, + reloc->target_handle, (int) reloc->offset, reloc->read_domains, reloc->write_domain); @@ -592,75 +1365,103 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, if (unlikely((reloc->write_domain | reloc->read_domains) & ~I915_GEM_GPU_DOMAINS)) { DRM_DEBUG("reloc with read/write non-GPU domains: " - "obj %p target %d offset %d " + "target %d offset %d " "read %08x write %08x", - obj, reloc->target_handle, + reloc->target_handle, (int) reloc->offset, reloc->read_domains, reloc->write_domain); return -EINVAL; } - target_obj->pending_read_domains |= reloc->read_domains; - target_obj->pending_write_domain |= reloc->write_domain; + if (reloc->write_domain) { + target->exec_entry->flags |= EXEC_OBJECT_WRITE; + + /* + * Sandybridge PPGTT errata: We need a global gtt mapping + * for MI and pipe_control writes because the gpu doesn't + * properly redirect them through the ppgtt for non_secure + * batchbuffers. + */ + if (reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && + IS_GEN6(eb->i915)) { + err = i915_vma_bind(target, target->obj->cache_level, + PIN_GLOBAL); + if (WARN_ONCE(err, + "Unexpected failure to bind target VMA!")) + return err; + } + } - /* If the relocation already has the right value in it, no + /* + * If the relocation already has the right value in it, no * more work needs to be done. */ - if (target_offset == reloc->presumed_offset) + if (!DBG_FORCE_RELOC && + gen8_canonical_addr(target->node.start) == reloc->presumed_offset) return 0; /* Check that the relocation address is valid... */ if (unlikely(reloc->offset > - obj->base.size - (cache->use_64bit_reloc ? 8 : 4))) { + vma->size - (eb->reloc_cache.use_64bit_reloc ? 8 : 4))) { DRM_DEBUG("Relocation beyond object bounds: " - "obj %p target %d offset %d size %d.\n", - obj, reloc->target_handle, - (int) reloc->offset, - (int) obj->base.size); + "target %d offset %d size %d.\n", + reloc->target_handle, + (int)reloc->offset, + (int)vma->size); return -EINVAL; } if (unlikely(reloc->offset & 3)) { DRM_DEBUG("Relocation not 4-byte aligned: " - "obj %p target %d offset %d.\n", - obj, reloc->target_handle, - (int) reloc->offset); + "target %d offset %d.\n", + reloc->target_handle, + (int)reloc->offset); return -EINVAL; } - ret = relocate_entry(obj, reloc, cache, target_offset); - if (ret) - return ret; + /* + * If we write into the object, we need to force the synchronisation + * barrier, either with an asynchronous clflush or if we executed the + * patching using the GPU (though that should be serialised by the + * timeline). To be completely sure, and since we are required to + * do relocations we are already stalling, disable the user's opt + * of our synchronisation. + */ + vma->exec_entry->flags &= ~EXEC_OBJECT_ASYNC; /* and update the user's relocation entry */ - reloc->presumed_offset = target_offset; - return 0; + return relocate_entry(vma, reloc, eb, target); } -static int -i915_gem_execbuffer_relocate_vma(struct i915_vma *vma, - struct eb_vmas *eb) +static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma) { #define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry)) - struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)]; - struct drm_i915_gem_relocation_entry __user *user_relocs; - struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; - struct reloc_cache cache; - int remain, ret = 0; - - user_relocs = u64_to_user_ptr(entry->relocs_ptr); - reloc_cache_init(&cache, eb->i915); + struct drm_i915_gem_relocation_entry stack[N_RELOC(512)]; + struct drm_i915_gem_relocation_entry __user *urelocs; + const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + unsigned int remain; + urelocs = u64_to_user_ptr(entry->relocs_ptr); remain = entry->relocation_count; - while (remain) { - struct drm_i915_gem_relocation_entry *r = stack_reloc; - unsigned long unwritten; - unsigned int count; + if (unlikely(remain > N_RELOC(ULONG_MAX))) + return -EINVAL; - count = min_t(unsigned int, remain, ARRAY_SIZE(stack_reloc)); - remain -= count; + /* + * We must check that the entire relocation array is safe + * to read. However, if the array is not writable the user loses + * the updated relocation values. + */ + if (unlikely(!access_ok(VERIFY_READ, urelocs, remain*sizeof(urelocs)))) + return -EFAULT; + + do { + struct drm_i915_gem_relocation_entry *r = stack; + unsigned int count = + min_t(unsigned int, remain, ARRAY_SIZE(stack)); + unsigned int copied; - /* This is the fast path and we cannot handle a pagefault + /* + * This is the fast path and we cannot handle a pagefault * whilst holding the struct mutex lest the user pass in the * relocations contained within a mmaped bo. For in such a case * we, the page fault handler would call i915_gem_fault() and @@ -668,489 +1469,408 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma, * this is bad and so lockdep complains vehemently. */ pagefault_disable(); - unwritten = __copy_from_user_inatomic(r, user_relocs, count*sizeof(r[0])); + copied = __copy_from_user_inatomic(r, urelocs, count * sizeof(r[0])); pagefault_enable(); - if (unlikely(unwritten)) { - ret = -EFAULT; + if (unlikely(copied)) { + remain = -EFAULT; goto out; } + remain -= count; do { - u64 offset = r->presumed_offset; + u64 offset = eb_relocate_entry(eb, vma, r); - ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r, &cache); - if (ret) + if (likely(offset == 0)) { + } else if ((s64)offset < 0) { + remain = (int)offset; goto out; - - if (r->presumed_offset != offset) { - pagefault_disable(); - unwritten = __put_user(r->presumed_offset, - &user_relocs->presumed_offset); - pagefault_enable(); - if (unlikely(unwritten)) { - /* Note that reporting an error now - * leaves everything in an inconsistent - * state as we have *already* changed - * the relocation value inside the - * object. As we have not changed the - * reloc.presumed_offset or will not - * change the execobject.offset, on the - * call we may not rewrite the value - * inside the object, leaving it - * dangling and causing a GPU hang. - */ - ret = -EFAULT; - goto out; - } + } else { + /* + * Note that reporting an error now + * leaves everything in an inconsistent + * state as we have *already* changed + * the relocation value inside the + * object. As we have not changed the + * reloc.presumed_offset or will not + * change the execobject.offset, on the + * call we may not rewrite the value + * inside the object, leaving it + * dangling and causing a GPU hang. Unless + * userspace dynamically rebuilds the + * relocations on each execbuf rather than + * presume a static tree. + * + * We did previously check if the relocations + * were writable (access_ok), an error now + * would be a strange race with mprotect, + * having already demonstrated that we + * can read from this userspace address. + */ + offset = gen8_canonical_addr(offset & ~UPDATE); + __put_user(offset, + &urelocs[r-stack].presumed_offset); } - - user_relocs++; - r++; - } while (--count); - } - + } while (r++, --count); + urelocs += ARRAY_SIZE(stack); + } while (remain); out: - reloc_cache_fini(&cache); - return ret; -#undef N_RELOC + reloc_cache_reset(&eb->reloc_cache); + return remain; } static int -i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma, - struct eb_vmas *eb, - struct drm_i915_gem_relocation_entry *relocs) +eb_relocate_vma_slow(struct i915_execbuffer *eb, struct i915_vma *vma) { const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; - struct reloc_cache cache; - int i, ret = 0; + struct drm_i915_gem_relocation_entry *relocs = + u64_to_ptr(typeof(*relocs), entry->relocs_ptr); + unsigned int i; + int err; - reloc_cache_init(&cache, eb->i915); for (i = 0; i < entry->relocation_count; i++) { - ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i], &cache); - if (ret) - break; - } - reloc_cache_fini(&cache); + u64 offset = eb_relocate_entry(eb, vma, &relocs[i]); - return ret; + if ((s64)offset < 0) { + err = (int)offset; + goto err; + } + } + err = 0; +err: + reloc_cache_reset(&eb->reloc_cache); + return err; } -static int -i915_gem_execbuffer_relocate(struct eb_vmas *eb) +static int check_relocations(const struct drm_i915_gem_exec_object2 *entry) { - struct i915_vma *vma; - int ret = 0; + const char __user *addr, *end; + unsigned long size; + char __maybe_unused c; - list_for_each_entry(vma, &eb->vmas, exec_list) { - ret = i915_gem_execbuffer_relocate_vma(vma, eb); - if (ret) - break; - } + size = entry->relocation_count; + if (size == 0) + return 0; - return ret; -} + if (size > N_RELOC(ULONG_MAX)) + return -EINVAL; -static bool only_mappable_for_reloc(unsigned int flags) -{ - return (flags & (EXEC_OBJECT_NEEDS_FENCE | __EXEC_OBJECT_NEEDS_MAP)) == - __EXEC_OBJECT_NEEDS_MAP; + addr = u64_to_user_ptr(entry->relocs_ptr); + size *= sizeof(struct drm_i915_gem_relocation_entry); + if (!access_ok(VERIFY_READ, addr, size)) + return -EFAULT; + + end = addr + size; + for (; addr < end; addr += PAGE_SIZE) { + int err = __get_user(c, addr); + if (err) + return err; + } + return __get_user(c, end - 1); } -static int -i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, - struct intel_engine_cs *engine, - bool *need_reloc) +static int eb_copy_relocations(const struct i915_execbuffer *eb) { - struct drm_i915_gem_object *obj = vma->obj; - struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; - uint64_t flags; - int ret; + const unsigned int count = eb->buffer_count; + unsigned int i; + int err; - flags = PIN_USER; - if (entry->flags & EXEC_OBJECT_NEEDS_GTT) - flags |= PIN_GLOBAL; + for (i = 0; i < count; i++) { + const unsigned int nreloc = eb->exec[i].relocation_count; + struct drm_i915_gem_relocation_entry __user *urelocs; + struct drm_i915_gem_relocation_entry *relocs; + unsigned long size; + unsigned long copied; - if (!drm_mm_node_allocated(&vma->node)) { - /* Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset, - * limit address to the first 4GBs for unflagged objects. - */ - if ((entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) == 0) - flags |= PIN_ZONE_4G; - if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) - flags |= PIN_GLOBAL | PIN_MAPPABLE; - if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) - flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS; - if (entry->flags & EXEC_OBJECT_PINNED) - flags |= entry->offset | PIN_OFFSET_FIXED; - if ((flags & PIN_MAPPABLE) == 0) - flags |= PIN_HIGH; - } - - ret = i915_vma_pin(vma, - entry->pad_to_size, - entry->alignment, - flags); - if ((ret == -ENOSPC || ret == -E2BIG) && - only_mappable_for_reloc(entry->flags)) - ret = i915_vma_pin(vma, - entry->pad_to_size, - entry->alignment, - flags & ~PIN_MAPPABLE); - if (ret) - return ret; + if (nreloc == 0) + continue; - entry->flags |= __EXEC_OBJECT_HAS_PIN; + err = check_relocations(&eb->exec[i]); + if (err) + goto err; - if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { - ret = i915_vma_get_fence(vma); - if (ret) - return ret; + urelocs = u64_to_user_ptr(eb->exec[i].relocs_ptr); + size = nreloc * sizeof(*relocs); - if (i915_vma_pin_fence(vma)) - entry->flags |= __EXEC_OBJECT_HAS_FENCE; - } + relocs = kvmalloc_array(size, 1, GFP_TEMPORARY); + if (!relocs) { + kvfree(relocs); + err = -ENOMEM; + goto err; + } - if (entry->offset != vma->node.start) { - entry->offset = vma->node.start; - *need_reloc = true; - } + /* copy_from_user is limited to < 4GiB */ + copied = 0; + do { + unsigned int len = + min_t(u64, BIT_ULL(31), size - copied); + + if (__copy_from_user((char *)relocs + copied, + (char *)urelocs + copied, + len)) { + kvfree(relocs); + err = -EFAULT; + goto err; + } + + copied += len; + } while (copied < size); - if (entry->flags & EXEC_OBJECT_WRITE) { - obj->base.pending_read_domains = I915_GEM_DOMAIN_RENDER; - obj->base.pending_write_domain = I915_GEM_DOMAIN_RENDER; + /* + * As we do not update the known relocation offsets after + * relocating (due to the complexities in lock handling), + * we need to mark them as invalid now so that we force the + * relocation processing next time. Just in case the target + * object is evicted and then rebound into its old + * presumed_offset before the next execbuffer - if that + * happened we would make the mistake of assuming that the + * relocations were valid. + */ + user_access_begin(); + for (copied = 0; copied < nreloc; copied++) + unsafe_put_user(-1, + &urelocs[copied].presumed_offset, + end_user); +end_user: + user_access_end(); + + eb->exec[i].relocs_ptr = (uintptr_t)relocs; } return 0; + +err: + while (i--) { + struct drm_i915_gem_relocation_entry *relocs = + u64_to_ptr(typeof(*relocs), eb->exec[i].relocs_ptr); + if (eb->exec[i].relocation_count) + kvfree(relocs); + } + return err; } -static bool -need_reloc_mappable(struct i915_vma *vma) +static int eb_prefault_relocations(const struct i915_execbuffer *eb) { - struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + const unsigned int count = eb->buffer_count; + unsigned int i; - if (entry->relocation_count == 0) - return false; - - if (!i915_vma_is_ggtt(vma)) - return false; + if (unlikely(i915.prefault_disable)) + return 0; - /* See also use_cpu_reloc() */ - if (HAS_LLC(to_i915(vma->obj->base.dev))) - return false; + for (i = 0; i < count; i++) { + int err; - if (vma->obj->base.write_domain == I915_GEM_DOMAIN_CPU) - return false; + err = check_relocations(&eb->exec[i]); + if (err) + return err; + } - return true; + return 0; } -static bool -eb_vma_misplaced(struct i915_vma *vma) +static noinline int eb_relocate_slow(struct i915_execbuffer *eb) { - struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; - - WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP && - !i915_vma_is_ggtt(vma)); - - if (entry->alignment && !IS_ALIGNED(vma->node.start, entry->alignment)) - return true; - - if (vma->node.size < entry->pad_to_size) - return true; - - if (entry->flags & EXEC_OBJECT_PINNED && - vma->node.start != entry->offset) - return true; - - if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && - vma->node.start < BATCH_OFFSET_BIAS) - return true; - - /* avoid costly ping-pong once a batch bo ended up non-mappable */ - if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && - !i915_vma_is_map_and_fenceable(vma)) - return !only_mappable_for_reloc(entry->flags); + struct drm_device *dev = &eb->i915->drm; + bool have_copy = false; + struct i915_vma *vma; + int err = 0; - if ((entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) == 0 && - (vma->node.start + vma->node.size - 1) >> 32) - return true; +repeat: + if (signal_pending(current)) { + err = -ERESTARTSYS; + goto out; + } - return false; -} + /* We may process another execbuffer during the unlock... */ + eb_reset_vmas(eb); + mutex_unlock(&dev->struct_mutex); -static int -i915_gem_execbuffer_reserve(struct intel_engine_cs *engine, - struct list_head *vmas, - struct i915_gem_context *ctx, - bool *need_relocs) -{ - struct drm_i915_gem_object *obj; - struct i915_vma *vma; - struct i915_address_space *vm; - struct list_head ordered_vmas; - struct list_head pinned_vmas; - bool has_fenced_gpu_access = INTEL_GEN(engine->i915) < 4; - bool needs_unfenced_map = INTEL_INFO(engine->i915)->unfenced_needs_alignment; - int retry; - - vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm; - - INIT_LIST_HEAD(&ordered_vmas); - INIT_LIST_HEAD(&pinned_vmas); - while (!list_empty(vmas)) { - struct drm_i915_gem_exec_object2 *entry; - bool need_fence, need_mappable; - - vma = list_first_entry(vmas, struct i915_vma, exec_list); - obj = vma->obj; - entry = vma->exec_entry; - - if (ctx->flags & CONTEXT_NO_ZEROMAP) - entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; - - if (!has_fenced_gpu_access) - entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE; - need_fence = - (entry->flags & EXEC_OBJECT_NEEDS_FENCE || - needs_unfenced_map) && - i915_gem_object_is_tiled(obj); - need_mappable = need_fence || need_reloc_mappable(vma); - - if (entry->flags & EXEC_OBJECT_PINNED) - list_move_tail(&vma->exec_list, &pinned_vmas); - else if (need_mappable) { - entry->flags |= __EXEC_OBJECT_NEEDS_MAP; - list_move(&vma->exec_list, &ordered_vmas); - } else - list_move_tail(&vma->exec_list, &ordered_vmas); - - obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND; - obj->base.pending_write_domain = 0; - } - list_splice(&ordered_vmas, vmas); - list_splice(&pinned_vmas, vmas); - - /* Attempt to pin all of the buffers into the GTT. - * This is done in 3 phases: + /* + * We take 3 passes through the slowpatch. * - * 1a. Unbind all objects that do not match the GTT constraints for - * the execbuffer (fenceable, mappable, alignment etc). - * 1b. Increment pin count for already bound objects. - * 2. Bind new objects. - * 3. Decrement pin count. + * 1 - we try to just prefault all the user relocation entries and + * then attempt to reuse the atomic pagefault disabled fast path again. * - * This avoid unnecessary unbinding of later objects in order to make - * room for the earlier objects *unless* we need to defragment. + * 2 - we copy the user entries to a local buffer here outside of the + * local and allow ourselves to wait upon any rendering before + * relocations + * + * 3 - we already have a local copy of the relocation entries, but + * were interrupted (EAGAIN) whilst waiting for the objects, try again. */ - retry = 0; - do { - int ret = 0; + if (!err) { + err = eb_prefault_relocations(eb); + } else if (!have_copy) { + err = eb_copy_relocations(eb); + have_copy = err == 0; + } else { + cond_resched(); + err = 0; + } + if (err) { + mutex_lock(&dev->struct_mutex); + goto out; + } - /* Unbind any ill-fitting objects or pin. */ - list_for_each_entry(vma, vmas, exec_list) { - if (!drm_mm_node_allocated(&vma->node)) - continue; + /* A frequent cause for EAGAIN are currently unavailable client pages */ + flush_workqueue(eb->i915->mm.userptr_wq); - if (eb_vma_misplaced(vma)) - ret = i915_vma_unbind(vma); - else - ret = i915_gem_execbuffer_reserve_vma(vma, - engine, - need_relocs); - if (ret) - goto err; - } + err = i915_mutex_lock_interruptible(dev); + if (err) { + mutex_lock(&dev->struct_mutex); + goto out; + } - /* Bind fresh objects */ - list_for_each_entry(vma, vmas, exec_list) { - if (drm_mm_node_allocated(&vma->node)) - continue; + /* reacquire the objects */ + err = eb_lookup_vmas(eb); + if (err) + goto err; - ret = i915_gem_execbuffer_reserve_vma(vma, engine, - need_relocs); - if (ret) + list_for_each_entry(vma, &eb->relocs, reloc_link) { + if (!have_copy) { + pagefault_disable(); + err = eb_relocate_vma(eb, vma); + pagefault_enable(); + if (err) + goto repeat; + } else { + err = eb_relocate_vma_slow(eb, vma); + if (err) goto err; } + } -err: - if (ret != -ENOSPC || retry++) - return ret; - - /* Decrement pin count for bound objects */ - list_for_each_entry(vma, vmas, exec_list) - i915_gem_execbuffer_unreserve_vma(vma); - - ret = i915_gem_evict_vm(vm, true); - if (ret) - return ret; - } while (1); -} - -static int -i915_gem_execbuffer_relocate_slow(struct drm_device *dev, - struct drm_i915_gem_execbuffer2 *args, - struct drm_file *file, - struct intel_engine_cs *engine, - struct eb_vmas *eb, - struct drm_i915_gem_exec_object2 *exec, - struct i915_gem_context *ctx) -{ - struct drm_i915_gem_relocation_entry *reloc; - struct i915_address_space *vm; - struct i915_vma *vma; - bool need_relocs; - int *reloc_offset; - int i, total, ret; - unsigned count = args->buffer_count; + /* + * Leave the user relocations as are, this is the painfully slow path, + * and we want to avoid the complication of dropping the lock whilst + * having buffers reserved in the aperture and so causing spurious + * ENOSPC for random operations. + */ - vm = list_first_entry(&eb->vmas, struct i915_vma, exec_list)->vm; +err: + if (err == -EAGAIN) + goto repeat; - /* We may process another execbuffer during the unlock... */ - while (!list_empty(&eb->vmas)) { - vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list); - list_del_init(&vma->exec_list); - i915_gem_execbuffer_unreserve_vma(vma); - i915_vma_put(vma); - } +out: + if (have_copy) { + const unsigned int count = eb->buffer_count; + unsigned int i; - mutex_unlock(&dev->struct_mutex); + for (i = 0; i < count; i++) { + const struct drm_i915_gem_exec_object2 *entry = + &eb->exec[i]; + struct drm_i915_gem_relocation_entry *relocs; - total = 0; - for (i = 0; i < count; i++) - total += exec[i].relocation_count; + if (!entry->relocation_count) + continue; - reloc_offset = kvmalloc_array(count, sizeof(*reloc_offset), GFP_KERNEL); - reloc = kvmalloc_array(total, sizeof(*reloc), GFP_KERNEL); - if (reloc == NULL || reloc_offset == NULL) { - kvfree(reloc); - kvfree(reloc_offset); - mutex_lock(&dev->struct_mutex); - return -ENOMEM; + relocs = u64_to_ptr(typeof(*relocs), entry->relocs_ptr); + kvfree(relocs); + } } - total = 0; - for (i = 0; i < count; i++) { - struct drm_i915_gem_relocation_entry __user *user_relocs; - u64 invalid_offset = (u64)-1; - int j; + return err ?: have_copy; +} - user_relocs = u64_to_user_ptr(exec[i].relocs_ptr); +static int eb_relocate(struct i915_execbuffer *eb) +{ + if (eb_lookup_vmas(eb)) + goto slow; - if (copy_from_user(reloc+total, user_relocs, - exec[i].relocation_count * sizeof(*reloc))) { - ret = -EFAULT; - mutex_lock(&dev->struct_mutex); - goto err; - } + /* The objects are in their final locations, apply the relocations. */ + if (eb->args->flags & __EXEC_HAS_RELOC) { + struct i915_vma *vma; - /* As we do not update the known relocation offsets after - * relocating (due to the complexities in lock handling), - * we need to mark them as invalid now so that we force the - * relocation processing next time. Just in case the target - * object is evicted and then rebound into its old - * presumed_offset before the next execbuffer - if that - * happened we would make the mistake of assuming that the - * relocations were valid. - */ - for (j = 0; j < exec[i].relocation_count; j++) { - if (__copy_to_user(&user_relocs[j].presumed_offset, - &invalid_offset, - sizeof(invalid_offset))) { - ret = -EFAULT; - mutex_lock(&dev->struct_mutex); - goto err; - } + list_for_each_entry(vma, &eb->relocs, reloc_link) { + if (eb_relocate_vma(eb, vma)) + goto slow; } - - reloc_offset[i] = total; - total += exec[i].relocation_count; - } - - ret = i915_mutex_lock_interruptible(dev); - if (ret) { - mutex_lock(&dev->struct_mutex); - goto err; } - /* reacquire the objects */ - eb_reset(eb); - ret = eb_lookup_vmas(eb, exec, args, vm, file); - if (ret) - goto err; + return 0; - need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; - ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx, - &need_relocs); - if (ret) - goto err; +slow: + return eb_relocate_slow(eb); +} - list_for_each_entry(vma, &eb->vmas, exec_list) { - int offset = vma->exec_entry - exec; - ret = i915_gem_execbuffer_relocate_vma_slow(vma, eb, - reloc + reloc_offset[offset]); - if (ret) - goto err; - } +static void eb_export_fence(struct i915_vma *vma, + struct drm_i915_gem_request *req, + unsigned int flags) +{ + struct reservation_object *resv = vma->resv; - /* Leave the user relocations as are, this is the painfully slow path, - * and we want to avoid the complication of dropping the lock whilst - * having buffers reserved in the aperture and so causing spurious - * ENOSPC for random operations. + /* + * Ignore errors from failing to allocate the new fence, we can't + * handle an error right now. Worst case should be missed + * synchronisation leading to rendering corruption. */ - -err: - kvfree(reloc); - kvfree(reloc_offset); - return ret; + reservation_object_lock(resv, NULL); + if (flags & EXEC_OBJECT_WRITE) + reservation_object_add_excl_fence(resv, &req->fence); + else if (reservation_object_reserve_shared(resv) == 0) + reservation_object_add_shared_fence(resv, &req->fence); + reservation_object_unlock(resv); } -static int -i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, - struct list_head *vmas) +static int eb_move_to_gpu(struct i915_execbuffer *eb) { - struct i915_vma *vma; - int ret; + const unsigned int count = eb->buffer_count; + unsigned int i; + int err; - list_for_each_entry(vma, vmas, exec_list) { + for (i = 0; i < count; i++) { + const struct drm_i915_gem_exec_object2 *entry = &eb->exec[i]; + struct i915_vma *vma = exec_to_vma(entry); struct drm_i915_gem_object *obj = vma->obj; - if (vma->exec_entry->flags & EXEC_OBJECT_CAPTURE) { + if (entry->flags & EXEC_OBJECT_CAPTURE) { struct i915_gem_capture_list *capture; capture = kmalloc(sizeof(*capture), GFP_KERNEL); if (unlikely(!capture)) return -ENOMEM; - capture->next = req->capture_list; + capture->next = eb->request->capture_list; capture->vma = vma; - req->capture_list = capture; + eb->request->capture_list = capture; } - if (vma->exec_entry->flags & EXEC_OBJECT_ASYNC) - continue; + if (entry->flags & EXEC_OBJECT_ASYNC) + goto skip_flushes; - if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) { + if (unlikely(obj->cache_dirty && !obj->cache_coherent)) i915_gem_clflush_object(obj, 0); - obj->base.write_domain = 0; - } - ret = i915_gem_request_await_object - (req, obj, obj->base.pending_write_domain); - if (ret) - return ret; + err = i915_gem_request_await_object + (eb->request, obj, entry->flags & EXEC_OBJECT_WRITE); + if (err) + return err; + +skip_flushes: + i915_vma_move_to_active(vma, eb->request, entry->flags); + __eb_unreserve_vma(vma, entry); + vma->exec_entry = NULL; + } + + for (i = 0; i < count; i++) { + const struct drm_i915_gem_exec_object2 *entry = &eb->exec[i]; + struct i915_vma *vma = exec_to_vma(entry); + + eb_export_fence(vma, eb->request, entry->flags); + if (unlikely(entry->flags & __EXEC_OBJECT_HAS_REF)) + i915_vma_put(vma); } + eb->exec = NULL; /* Unconditionally flush any chipset caches (for streaming writes). */ - i915_gem_chipset_flush(req->engine->i915); + i915_gem_chipset_flush(eb->i915); /* Unconditionally invalidate GPU caches and TLBs. */ - return req->engine->emit_flush(req, EMIT_INVALIDATE); + return eb->engine->emit_flush(eb->request, EMIT_INVALIDATE); } -static bool -i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) +static bool i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) { - if (exec->flags & __I915_EXEC_UNKNOWN_FLAGS) + if (exec->flags & __I915_EXEC_ILLEGAL_FLAGS) return false; /* Kernel clipping was a DRI1 misfeature */ @@ -1170,107 +1890,6 @@ i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) return true; } -static int -validate_exec_list(struct drm_device *dev, - struct drm_i915_gem_exec_object2 *exec, - int count) -{ - unsigned relocs_total = 0; - unsigned relocs_max = UINT_MAX / sizeof(struct drm_i915_gem_relocation_entry); - unsigned invalid_flags; - int i; - - /* INTERNAL flags must not overlap with external ones */ - BUILD_BUG_ON(__EXEC_OBJECT_INTERNAL_FLAGS & ~__EXEC_OBJECT_UNKNOWN_FLAGS); - - invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS; - if (USES_FULL_PPGTT(dev)) - invalid_flags |= EXEC_OBJECT_NEEDS_GTT; - - for (i = 0; i < count; i++) { - char __user *ptr = u64_to_user_ptr(exec[i].relocs_ptr); - int length; /* limited by fault_in_pages_readable() */ - - if (exec[i].flags & invalid_flags) - return -EINVAL; - - /* Offset can be used as input (EXEC_OBJECT_PINNED), reject - * any non-page-aligned or non-canonical addresses. - */ - if (exec[i].flags & EXEC_OBJECT_PINNED) { - if (exec[i].offset != - gen8_canonical_addr(exec[i].offset & PAGE_MASK)) - return -EINVAL; - } - - /* From drm_mm perspective address space is continuous, - * so from this point we're always using non-canonical - * form internally. - */ - exec[i].offset = gen8_noncanonical_addr(exec[i].offset); - - if (exec[i].alignment && !is_power_of_2(exec[i].alignment)) - return -EINVAL; - - /* pad_to_size was once a reserved field, so sanitize it */ - if (exec[i].flags & EXEC_OBJECT_PAD_TO_SIZE) { - if (offset_in_page(exec[i].pad_to_size)) - return -EINVAL; - } else { - exec[i].pad_to_size = 0; - } - - /* First check for malicious input causing overflow in - * the worst case where we need to allocate the entire - * relocation tree as a single array. - */ - if (exec[i].relocation_count > relocs_max - relocs_total) - return -EINVAL; - relocs_total += exec[i].relocation_count; - - length = exec[i].relocation_count * - sizeof(struct drm_i915_gem_relocation_entry); - /* - * We must check that the entire relocation array is safe - * to read, but since we may need to update the presumed - * offsets during execution, check for full write access. - */ - if (!access_ok(VERIFY_WRITE, ptr, length)) - return -EFAULT; - - if (likely(!i915.prefault_disable)) { - if (fault_in_pages_readable(ptr, length)) - return -EFAULT; - } - } - - return 0; -} - -static struct i915_gem_context * -i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, - struct intel_engine_cs *engine, const u32 ctx_id) -{ - struct i915_gem_context *ctx; - - ctx = i915_gem_context_lookup(file->driver_priv, ctx_id); - if (IS_ERR(ctx)) - return ctx; - - if (i915_gem_context_is_banned(ctx)) { - DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id); - return ERR_PTR(-EIO); - } - - return ctx; -} - -static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj) -{ - return !(obj->cache_level == I915_CACHE_NONE || - obj->cache_level == I915_CACHE_WT); -} - void i915_vma_move_to_active(struct i915_vma *vma, struct drm_i915_gem_request *req, unsigned int flags) @@ -1281,7 +1900,8 @@ void i915_vma_move_to_active(struct i915_vma *vma, lockdep_assert_held(&req->i915->drm.struct_mutex); GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); - /* Add a reference if we're newly entering the active list. + /* + * Add a reference if we're newly entering the active list. * The order in which we add operations to the retirement queue is * vital here: mark_active adds to the start of the callback list, * such that subsequent callbacks are called first. Therefore we @@ -1294,61 +1914,22 @@ void i915_vma_move_to_active(struct i915_vma *vma, i915_gem_active_set(&vma->last_read[idx], req); list_move_tail(&vma->vm_link, &vma->vm->active_list); + obj->base.write_domain = 0; if (flags & EXEC_OBJECT_WRITE) { + obj->base.write_domain = I915_GEM_DOMAIN_RENDER; + if (intel_fb_obj_invalidate(obj, ORIGIN_CS)) i915_gem_active_set(&obj->frontbuffer_write, req); - /* update for the implicit flush after a batch */ - obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; - if (!obj->cache_dirty && gpu_write_needs_clflush(obj)) - obj->cache_dirty = true; + obj->base.read_domains = 0; } + obj->base.read_domains |= I915_GEM_GPU_DOMAINS; if (flags & EXEC_OBJECT_NEEDS_FENCE) i915_gem_active_set(&vma->last_fence, req); } -static void eb_export_fence(struct drm_i915_gem_object *obj, - struct drm_i915_gem_request *req, - unsigned int flags) -{ - struct reservation_object *resv = obj->resv; - - /* Ignore errors from failing to allocate the new fence, we can't - * handle an error right now. Worst case should be missed - * synchronisation leading to rendering corruption. - */ - reservation_object_lock(resv, NULL); - if (flags & EXEC_OBJECT_WRITE) - reservation_object_add_excl_fence(resv, &req->fence); - else if (reservation_object_reserve_shared(resv) == 0) - reservation_object_add_shared_fence(resv, &req->fence); - reservation_object_unlock(resv); -} - -static void -i915_gem_execbuffer_move_to_active(struct list_head *vmas, - struct drm_i915_gem_request *req) -{ - struct i915_vma *vma; - - list_for_each_entry(vma, vmas, exec_list) { - struct drm_i915_gem_object *obj = vma->obj; - - obj->base.write_domain = obj->base.pending_write_domain; - if (obj->base.write_domain) - vma->exec_entry->flags |= EXEC_OBJECT_WRITE; - else - obj->base.pending_read_domains |= obj->base.read_domains; - obj->base.read_domains = obj->base.pending_read_domains; - - i915_vma_move_to_active(vma, req, vma->exec_entry->flags); - eb_export_fence(obj, req, vma->exec_entry->flags); - } -} - -static int -i915_reset_gen7_sol_offsets(struct drm_i915_gem_request *req) +static int i915_reset_gen7_sol_offsets(struct drm_i915_gem_request *req) { u32 *cs; int i; @@ -1358,50 +1939,43 @@ i915_reset_gen7_sol_offsets(struct drm_i915_gem_request *req) return -EINVAL; } - cs = intel_ring_begin(req, 4 * 3); + cs = intel_ring_begin(req, 4 * 2 + 2); if (IS_ERR(cs)) return PTR_ERR(cs); + *cs++ = MI_LOAD_REGISTER_IMM(4); for (i = 0; i < 4; i++) { - *cs++ = MI_LOAD_REGISTER_IMM(1); *cs++ = i915_mmio_reg_offset(GEN7_SO_WRITE_OFFSET(i)); *cs++ = 0; } - + *cs++ = MI_NOOP; intel_ring_advance(req, cs); return 0; } -static struct i915_vma * -i915_gem_execbuffer_parse(struct intel_engine_cs *engine, - struct drm_i915_gem_exec_object2 *shadow_exec_entry, - struct drm_i915_gem_object *batch_obj, - struct eb_vmas *eb, - u32 batch_start_offset, - u32 batch_len, - bool is_master) +static struct i915_vma *eb_parse(struct i915_execbuffer *eb, bool is_master) { struct drm_i915_gem_object *shadow_batch_obj; struct i915_vma *vma; - int ret; + int err; - shadow_batch_obj = i915_gem_batch_pool_get(&engine->batch_pool, - PAGE_ALIGN(batch_len)); + shadow_batch_obj = i915_gem_batch_pool_get(&eb->engine->batch_pool, + PAGE_ALIGN(eb->batch_len)); if (IS_ERR(shadow_batch_obj)) return ERR_CAST(shadow_batch_obj); - ret = intel_engine_cmd_parser(engine, - batch_obj, + err = intel_engine_cmd_parser(eb->engine, + eb->batch->obj, shadow_batch_obj, - batch_start_offset, - batch_len, + eb->batch_start_offset, + eb->batch_len, is_master); - if (ret) { - if (ret == -EACCES) /* unhandled chained batch */ + if (err) { + if (err == -EACCES) /* unhandled chained batch */ vma = NULL; else - vma = ERR_PTR(ret); + vma = ERR_PTR(err); goto out; } @@ -1409,12 +1983,11 @@ i915_gem_execbuffer_parse(struct intel_engine_cs *engine, if (IS_ERR(vma)) goto out; - memset(shadow_exec_entry, 0, sizeof(*shadow_exec_entry)); - - vma->exec_entry = shadow_exec_entry; - vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN; - i915_gem_object_get(shadow_batch_obj); - list_add_tail(&vma->exec_list, &eb->vmas); + vma->exec_entry = + memset(&eb->exec[eb->buffer_count++], + 0, sizeof(*vma->exec_entry)); + vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF; + __exec_to_vma(vma->exec_entry) = (uintptr_t)i915_vma_get(vma); out: i915_gem_object_unpin_pages(shadow_batch_obj); @@ -1422,54 +1995,37 @@ out: } static void -add_to_client(struct drm_i915_gem_request *req, - struct drm_file *file) +add_to_client(struct drm_i915_gem_request *req, struct drm_file *file) { req->file_priv = file->driver_priv; list_add_tail(&req->client_link, &req->file_priv->mm.request_list); } -static int -execbuf_submit(struct i915_execbuffer_params *params, - struct drm_i915_gem_execbuffer2 *args, - struct list_head *vmas) +static int eb_submit(struct i915_execbuffer *eb) { - u64 exec_start, exec_len; - int ret; + int err; - ret = i915_gem_execbuffer_move_to_gpu(params->request, vmas); - if (ret) - return ret; + err = eb_move_to_gpu(eb); + if (err) + return err; - ret = i915_switch_context(params->request); - if (ret) - return ret; + err = i915_switch_context(eb->request); + if (err) + return err; - if (args->flags & I915_EXEC_CONSTANTS_MASK) { - DRM_DEBUG("I915_EXEC_CONSTANTS_* unsupported\n"); - return -EINVAL; - } - - if (args->flags & I915_EXEC_GEN7_SOL_RESET) { - ret = i915_reset_gen7_sol_offsets(params->request); - if (ret) - return ret; + if (eb->args->flags & I915_EXEC_GEN7_SOL_RESET) { + err = i915_reset_gen7_sol_offsets(eb->request); + if (err) + return err; } - exec_len = args->batch_len; - exec_start = params->batch->node.start + - params->args_batch_start_offset; - - if (exec_len == 0) - exec_len = params->batch->size - params->args_batch_start_offset; - - ret = params->engine->emit_bb_start(params->request, - exec_start, exec_len, - params->dispatch_flags); - if (ret) - return ret; - - i915_gem_execbuffer_move_to_active(vmas, params->request); + err = eb->engine->emit_bb_start(eb->request, + eb->batch->node.start + + eb->batch_start_offset, + eb->batch_len, + eb->batch_flags); + if (err) + return err; return 0; } @@ -1551,66 +2107,62 @@ eb_select_engine(struct drm_i915_private *dev_priv, } static int -i915_gem_do_execbuffer(struct drm_device *dev, void *data, +i915_gem_do_execbuffer(struct drm_device *dev, struct drm_file *file, struct drm_i915_gem_execbuffer2 *args, struct drm_i915_gem_exec_object2 *exec) { - struct drm_i915_private *dev_priv = to_i915(dev); - struct i915_ggtt *ggtt = &dev_priv->ggtt; - struct eb_vmas *eb; - struct drm_i915_gem_exec_object2 shadow_exec_entry; - struct intel_engine_cs *engine; - struct i915_gem_context *ctx; - struct i915_address_space *vm; - struct i915_execbuffer_params params_master; /* XXX: will be removed later */ - struct i915_execbuffer_params *params = ¶ms_master; - const u32 ctx_id = i915_execbuffer2_get_context_id(*args); - u32 dispatch_flags; + struct i915_execbuffer eb; struct dma_fence *in_fence = NULL; struct sync_file *out_fence = NULL; int out_fence_fd = -1; - int ret; - bool need_relocs; - - if (!i915_gem_check_execbuffer(args)) - return -EINVAL; - - ret = validate_exec_list(dev, exec, args->buffer_count); - if (ret) - return ret; - - dispatch_flags = 0; + int err; + + BUILD_BUG_ON(__EXEC_OBJECT_INTERNAL_FLAGS & + ~__EXEC_OBJECT_UNKNOWN_FLAGS); + + eb.i915 = to_i915(dev); + eb.file = file; + eb.args = args; + if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC)) + args->flags |= __EXEC_HAS_RELOC; + eb.exec = exec; + eb.ctx = NULL; + eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS; + if (USES_FULL_PPGTT(eb.i915)) + eb.invalid_flags |= EXEC_OBJECT_NEEDS_GTT; + reloc_cache_init(&eb.reloc_cache, eb.i915); + + eb.buffer_count = args->buffer_count; + eb.batch_start_offset = args->batch_start_offset; + eb.batch_len = args->batch_len; + + eb.batch_flags = 0; if (args->flags & I915_EXEC_SECURE) { if (!drm_is_current_master(file) || !capable(CAP_SYS_ADMIN)) return -EPERM; - dispatch_flags |= I915_DISPATCH_SECURE; + eb.batch_flags |= I915_DISPATCH_SECURE; } if (args->flags & I915_EXEC_IS_PINNED) - dispatch_flags |= I915_DISPATCH_PINNED; + eb.batch_flags |= I915_DISPATCH_PINNED; - engine = eb_select_engine(dev_priv, file, args); - if (!engine) + eb.engine = eb_select_engine(eb.i915, file, args); + if (!eb.engine) return -EINVAL; - if (args->buffer_count < 1) { - DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); - return -EINVAL; - } - if (args->flags & I915_EXEC_RESOURCE_STREAMER) { - if (!HAS_RESOURCE_STREAMER(dev_priv)) { + if (!HAS_RESOURCE_STREAMER(eb.i915)) { DRM_DEBUG("RS is only allowed for Haswell, Gen8 and above\n"); return -EINVAL; } - if (engine->id != RCS) { + if (eb.engine->id != RCS) { DRM_DEBUG("RS is not available on %s\n", - engine->name); + eb.engine->name); return -EINVAL; } - dispatch_flags |= I915_DISPATCH_RS; + eb.batch_flags |= I915_DISPATCH_RS; } if (args->flags & I915_EXEC_FENCE_IN) { @@ -1622,102 +2174,62 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (args->flags & I915_EXEC_FENCE_OUT) { out_fence_fd = get_unused_fd_flags(O_CLOEXEC); if (out_fence_fd < 0) { - ret = out_fence_fd; + err = out_fence_fd; goto err_in_fence; } } - /* Take a local wakeref for preparing to dispatch the execbuf as + if (eb_create(&eb)) + return -ENOMEM; + + /* + * Take a local wakeref for preparing to dispatch the execbuf as * we expect to access the hardware fairly frequently in the * process. Upon first dispatch, we acquire another prolonged * wakeref that we hold until the GPU has been idle for at least * 100ms. */ - intel_runtime_pm_get(dev_priv); - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - goto pre_mutex_err; - - ctx = i915_gem_validate_context(dev, file, engine, ctx_id); - if (IS_ERR(ctx)) { - mutex_unlock(&dev->struct_mutex); - ret = PTR_ERR(ctx); - goto pre_mutex_err; - } - - i915_gem_context_get(ctx); - - if (ctx->ppgtt) - vm = &ctx->ppgtt->base; - else - vm = &ggtt->base; + intel_runtime_pm_get(eb.i915); + err = i915_mutex_lock_interruptible(dev); + if (err) + goto err_rpm; - memset(¶ms_master, 0x00, sizeof(params_master)); + err = eb_select_context(&eb); + if (unlikely(err)) + goto err_unlock; - eb = eb_create(dev_priv, args); - if (eb == NULL) { - i915_gem_context_put(ctx); - mutex_unlock(&dev->struct_mutex); - ret = -ENOMEM; - goto pre_mutex_err; - } - - /* Look up object handles */ - ret = eb_lookup_vmas(eb, exec, args, vm, file); - if (ret) - goto err; - - /* take note of the batch buffer before we might reorder the lists */ - params->batch = eb_get_batch(eb); - - /* Move the objects en-masse into the GTT, evicting if necessary. */ - need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; - ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx, - &need_relocs); - if (ret) - goto err; - - /* The objects are in their final locations, apply the relocations. */ - if (need_relocs) - ret = i915_gem_execbuffer_relocate(eb); - if (ret) { - if (ret == -EFAULT) { - ret = i915_gem_execbuffer_relocate_slow(dev, args, file, - engine, - eb, exec, ctx); - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - } - if (ret) - goto err; - } + err = eb_relocate(&eb); + if (err) + /* + * If the user expects the execobject.offset and + * reloc.presumed_offset to be an exact match, + * as for using NO_RELOC, then we cannot update + * the execobject.offset until we have completed + * relocation. + */ + args->flags &= ~__EXEC_HAS_RELOC; + if (err < 0) + goto err_vma; - /* Set the pending read domains for the batch buffer to COMMAND */ - if (params->batch->obj->base.pending_write_domain) { + if (unlikely(eb.batch->exec_entry->flags & EXEC_OBJECT_WRITE)) { DRM_DEBUG("Attempting to use self-modifying batch buffer\n"); - ret = -EINVAL; - goto err; + err = -EINVAL; + goto err_vma; } - if (args->batch_start_offset > params->batch->size || - args->batch_len > params->batch->size - args->batch_start_offset) { + if (eb.batch_start_offset > eb.batch->size || + eb.batch_len > eb.batch->size - eb.batch_start_offset) { DRM_DEBUG("Attempting to use out-of-bounds batch\n"); - ret = -EINVAL; - goto err; + err = -EINVAL; + goto err_vma; } - params->args_batch_start_offset = args->batch_start_offset; - if (engine->needs_cmd_parser && args->batch_len) { + if (eb.engine->needs_cmd_parser && eb.batch_len) { struct i915_vma *vma; - vma = i915_gem_execbuffer_parse(engine, &shadow_exec_entry, - params->batch->obj, - eb, - args->batch_start_offset, - args->batch_len, - drm_is_current_master(file)); + vma = eb_parse(&eb, drm_is_current_master(file)); if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - goto err; + err = PTR_ERR(vma); + goto err_vma; } if (vma) { @@ -1730,19 +2242,20 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * specifically don't want that set on batches the * command parser has accepted. */ - dispatch_flags |= I915_DISPATCH_SECURE; - params->args_batch_start_offset = 0; - params->batch = vma; + eb.batch_flags |= I915_DISPATCH_SECURE; + eb.batch_start_offset = 0; + eb.batch = vma; } } - params->batch->obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; + if (eb.batch_len == 0) + eb.batch_len = eb.batch->size - eb.batch_start_offset; - /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure + /* + * snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure * batch" bit. Hence we need to pin secure batches into the global gtt. * hsw should have this fixed, but bdw mucks it up again. */ - if (dispatch_flags & I915_DISPATCH_SECURE) { - struct drm_i915_gem_object *obj = params->batch->obj; + if (eb.batch_flags & I915_DISPATCH_SECURE) { struct i915_vma *vma; /* @@ -1755,66 +2268,56 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * fitting due to fragmentation. * So this is actually safe. */ - vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0); + vma = i915_gem_object_ggtt_pin(eb.batch->obj, NULL, 0, 0, 0); if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - goto err; + err = PTR_ERR(vma); + goto err_vma; } - params->batch = vma; + eb.batch = vma; } + /* All GPU relocation batches must be submitted prior to the user rq */ + GEM_BUG_ON(eb.reloc_cache.rq); + /* Allocate a request for this batch buffer nice and early. */ - params->request = i915_gem_request_alloc(engine, ctx); - if (IS_ERR(params->request)) { - ret = PTR_ERR(params->request); + eb.request = i915_gem_request_alloc(eb.engine, eb.ctx); + if (IS_ERR(eb.request)) { + err = PTR_ERR(eb.request); goto err_batch_unpin; } if (in_fence) { - ret = i915_gem_request_await_dma_fence(params->request, - in_fence); - if (ret < 0) + err = i915_gem_request_await_dma_fence(eb.request, in_fence); + if (err < 0) goto err_request; } if (out_fence_fd != -1) { - out_fence = sync_file_create(¶ms->request->fence); + out_fence = sync_file_create(&eb.request->fence); if (!out_fence) { - ret = -ENOMEM; + err = -ENOMEM; goto err_request; } } - /* Whilst this request exists, batch_obj will be on the + /* + * Whilst this request exists, batch_obj will be on the * active_list, and so will hold the active reference. Only when this * request is retired will the the batch_obj be moved onto the * inactive_list and lose its active reference. Hence we do not need * to explicitly hold another reference here. */ - params->request->batch = params->batch; - - /* - * Save assorted stuff away to pass through to *_submission(). - * NB: This data should be 'persistent' and not local as it will - * kept around beyond the duration of the IOCTL once the GPU - * scheduler arrives. - */ - params->dev = dev; - params->file = file; - params->engine = engine; - params->dispatch_flags = dispatch_flags; - params->ctx = ctx; - - trace_i915_gem_request_queue(params->request, dispatch_flags); + eb.request->batch = eb.batch; - ret = execbuf_submit(params, args, &eb->vmas); + trace_i915_gem_request_queue(eb.request, eb.batch_flags); + err = eb_submit(&eb); err_request: - __i915_add_request(params->request, ret == 0); - add_to_client(params->request, file); + __i915_add_request(eb.request, err == 0); + add_to_client(eb.request, file); if (out_fence) { - if (ret == 0) { + if (err == 0) { fd_install(out_fence_fd, out_fence->file); args->rsvd2 &= GENMASK_ULL(0, 31); /* keep in-fence */ args->rsvd2 |= (u64)out_fence_fd << 32; @@ -1825,30 +2328,22 @@ err_request: } err_batch_unpin: - /* - * FIXME: We crucially rely upon the active tracking for the (ppgtt) - * batch vma for correctness. For less ugly and less fragility this - * needs to be adjusted to also track the ggtt batch vma properly as - * active. - */ - if (dispatch_flags & I915_DISPATCH_SECURE) - i915_vma_unpin(params->batch); -err: - /* the request owns the ref now */ - i915_gem_context_put(ctx); - eb_destroy(eb); - + if (eb.batch_flags & I915_DISPATCH_SECURE) + i915_vma_unpin(eb.batch); +err_vma: + if (eb.exec) + eb_release_vmas(&eb); + i915_gem_context_put(eb.ctx); +err_unlock: mutex_unlock(&dev->struct_mutex); - -pre_mutex_err: - /* intel_gpu_busy should also get a ref, so it will free when the device - * is really idle. */ - intel_runtime_pm_put(dev_priv); +err_rpm: + intel_runtime_pm_put(eb.i915); + eb_destroy(&eb); if (out_fence_fd != -1) put_unused_fd(out_fence_fd); err_in_fence: dma_fence_put(in_fence); - return ret; + return err; } /* @@ -1859,20 +2354,38 @@ int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file) { + const size_t sz = sizeof(struct drm_i915_gem_exec_object2); struct drm_i915_gem_execbuffer *args = data; struct drm_i915_gem_execbuffer2 exec2; struct drm_i915_gem_exec_object *exec_list = NULL; struct drm_i915_gem_exec_object2 *exec2_list = NULL; - int ret, i; + unsigned int i; + int err; - if (args->buffer_count < 1) { - DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); + if (args->buffer_count < 1 || args->buffer_count > SIZE_MAX / sz - 1) { + DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); return -EINVAL; } + exec2.buffers_ptr = args->buffers_ptr; + exec2.buffer_count = args->buffer_count; + exec2.batch_start_offset = args->batch_start_offset; + exec2.batch_len = args->batch_len; + exec2.DR1 = args->DR1; + exec2.DR4 = args->DR4; + exec2.num_cliprects = args->num_cliprects; + exec2.cliprects_ptr = args->cliprects_ptr; + exec2.flags = I915_EXEC_RENDER; + i915_execbuffer2_set_context_id(exec2, 0); + + if (!i915_gem_check_execbuffer(&exec2)) + return -EINVAL; + /* Copy in the exec list from userland */ - exec_list = kvmalloc_array(sizeof(*exec_list), args->buffer_count, GFP_KERNEL); - exec2_list = kvmalloc_array(sizeof(*exec2_list), args->buffer_count, GFP_KERNEL); + exec_list = kvmalloc_array(args->buffer_count, sizeof(*exec_list), + __GFP_NOWARN | GFP_TEMPORARY); + exec2_list = kvmalloc_array(args->buffer_count + 1, sz, + __GFP_NOWARN | GFP_TEMPORARY); if (exec_list == NULL || exec2_list == NULL) { DRM_DEBUG("Failed to allocate exec list for %d buffers\n", args->buffer_count); @@ -1880,12 +2393,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, kvfree(exec2_list); return -ENOMEM; } - ret = copy_from_user(exec_list, + err = copy_from_user(exec_list, u64_to_user_ptr(args->buffers_ptr), sizeof(*exec_list) * args->buffer_count); - if (ret != 0) { + if (err) { DRM_DEBUG("copy %d exec entries failed %d\n", - args->buffer_count, ret); + args->buffer_count, err); kvfree(exec_list); kvfree(exec2_list); return -EFAULT; @@ -1903,99 +2416,94 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, exec2_list[i].flags = 0; } - exec2.buffers_ptr = args->buffers_ptr; - exec2.buffer_count = args->buffer_count; - exec2.batch_start_offset = args->batch_start_offset; - exec2.batch_len = args->batch_len; - exec2.DR1 = args->DR1; - exec2.DR4 = args->DR4; - exec2.num_cliprects = args->num_cliprects; - exec2.cliprects_ptr = args->cliprects_ptr; - exec2.flags = I915_EXEC_RENDER; - i915_execbuffer2_set_context_id(exec2, 0); - - ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); - if (!ret) { + err = i915_gem_do_execbuffer(dev, file, &exec2, exec2_list); + if (exec2.flags & __EXEC_HAS_RELOC) { struct drm_i915_gem_exec_object __user *user_exec_list = u64_to_user_ptr(args->buffers_ptr); /* Copy the new buffer offsets back to the user's exec list. */ for (i = 0; i < args->buffer_count; i++) { + if (!(exec2_list[i].offset & UPDATE)) + continue; + exec2_list[i].offset = - gen8_canonical_addr(exec2_list[i].offset); - ret = __copy_to_user(&user_exec_list[i].offset, - &exec2_list[i].offset, - sizeof(user_exec_list[i].offset)); - if (ret) { - ret = -EFAULT; - DRM_DEBUG("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); + gen8_canonical_addr(exec2_list[i].offset & PIN_OFFSET_MASK); + exec2_list[i].offset &= PIN_OFFSET_MASK; + if (__copy_to_user(&user_exec_list[i].offset, + &exec2_list[i].offset, + sizeof(user_exec_list[i].offset))) break; - } } } kvfree(exec_list); kvfree(exec2_list); - return ret; + return err; } int i915_gem_execbuffer2(struct drm_device *dev, void *data, struct drm_file *file) { + const size_t sz = sizeof(struct drm_i915_gem_exec_object2); struct drm_i915_gem_execbuffer2 *args = data; - struct drm_i915_gem_exec_object2 *exec2_list = NULL; - int ret; + struct drm_i915_gem_exec_object2 *exec2_list; + int err; - if (args->buffer_count < 1 || - args->buffer_count > UINT_MAX / sizeof(*exec2_list)) { + if (args->buffer_count < 1 || args->buffer_count > SIZE_MAX / sz - 1) { DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); return -EINVAL; } - exec2_list = kvmalloc_array(args->buffer_count, - sizeof(*exec2_list), - GFP_TEMPORARY); + if (!i915_gem_check_execbuffer(args)) + return -EINVAL; + + /* Allocate an extra slot for use by the command parser */ + exec2_list = kvmalloc_array(args->buffer_count + 1, sz, + __GFP_NOWARN | GFP_TEMPORARY); if (exec2_list == NULL) { DRM_DEBUG("Failed to allocate exec list for %d buffers\n", args->buffer_count); return -ENOMEM; } - ret = copy_from_user(exec2_list, - u64_to_user_ptr(args->buffers_ptr), - sizeof(*exec2_list) * args->buffer_count); - if (ret != 0) { - DRM_DEBUG("copy %d exec entries failed %d\n", - args->buffer_count, ret); + if (copy_from_user(exec2_list, + u64_to_user_ptr(args->buffers_ptr), + sizeof(*exec2_list) * args->buffer_count)) { + DRM_DEBUG("copy %d exec entries failed\n", args->buffer_count); kvfree(exec2_list); return -EFAULT; } - ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); - if (!ret) { - /* Copy the new buffer offsets back to the user's exec list. */ + err = i915_gem_do_execbuffer(dev, file, args, exec2_list); + + /* + * Now that we have begun execution of the batchbuffer, we ignore + * any new error after this point. Also given that we have already + * updated the associated relocations, we try to write out the current + * object locations irrespective of any error. + */ + if (args->flags & __EXEC_HAS_RELOC) { struct drm_i915_gem_exec_object2 __user *user_exec_list = - u64_to_user_ptr(args->buffers_ptr); - int i; + u64_to_user_ptr(args->buffers_ptr); + unsigned int i; + /* Copy the new buffer offsets back to the user's exec list. */ + user_access_begin(); for (i = 0; i < args->buffer_count; i++) { + if (!(exec2_list[i].offset & UPDATE)) + continue; + exec2_list[i].offset = - gen8_canonical_addr(exec2_list[i].offset); - ret = __copy_to_user(&user_exec_list[i].offset, - &exec2_list[i].offset, - sizeof(user_exec_list[i].offset)); - if (ret) { - ret = -EFAULT; - DRM_DEBUG("failed to copy %d exec entries " - "back to user\n", - args->buffer_count); - break; - } + gen8_canonical_addr(exec2_list[i].offset & PIN_OFFSET_MASK); + unsafe_put_user(exec2_list[i].offset, + &user_exec_list[i].offset, + end_user); } +end_user: + user_access_end(); } + args->flags &= ~__I915_EXEC_UNKNOWN_FLAGS; kvfree(exec2_list); - return ret; + return err; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 1489c3a..61fc7e9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1884,7 +1884,7 @@ static void gtt_write_workarounds(struct drm_i915_private *dev_priv) * called on driver load and after a GPU reset, so you can place * workarounds here even if they get overwritten by GPU reset. */ - /* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt,kbl,glk */ + /* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt,kbl,glk,cfl */ if (IS_BROADWELL(dev_priv)) I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW); else if (IS_CHERRYVIEW(dev_priv)) @@ -3095,13 +3095,17 @@ int i915_ggtt_enable_hw(struct drm_i915_private *dev_priv) void i915_ggtt_enable_guc(struct drm_i915_private *i915) { + GEM_BUG_ON(i915->ggtt.invalidate != gen6_ggtt_invalidate); + i915->ggtt.invalidate = guc_ggtt_invalidate; } void i915_ggtt_disable_guc(struct drm_i915_private *i915) { - if (i915->ggtt.invalidate == guc_ggtt_invalidate) - i915->ggtt.invalidate = gen6_ggtt_invalidate; + /* We should only be called after i915_ggtt_enable_guc() */ + GEM_BUG_ON(i915->ggtt.invalidate != guc_ggtt_invalidate); + + i915->ggtt.invalidate = gen6_ggtt_invalidate; } void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv) @@ -3398,6 +3402,9 @@ int i915_gem_gtt_reserve(struct i915_address_space *vm, if (err != -ENOSPC) return err; + if (flags & PIN_NOEVICT) + return -ENOSPC; + err = i915_gem_evict_for_node(vm, node, flags); if (err == 0) err = drm_mm_reserve_node(&vm->mm, node); @@ -3512,6 +3519,9 @@ int i915_gem_gtt_insert(struct i915_address_space *vm, if (err != -ENOSPC) return err; + if (flags & PIN_NOEVICT) + return -ENOSPC; + /* No free space, pick a slot at random. * * There is a pathological case here using a GTT shared between diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index fb15684..1b2a56c 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -255,6 +255,7 @@ struct i915_address_space { struct drm_i915_file_private *file; struct list_head global_link; u64 total; /* size addr space maps (ex. 2GB for ggtt) */ + u64 reserved; /* size addr space reserved */ bool closed; @@ -588,6 +589,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm, #define PIN_MAPPABLE BIT(1) #define PIN_ZONE_4G BIT(2) #define PIN_NONFAULT BIT(3) +#define PIN_NOEVICT BIT(4) #define PIN_MBZ BIT(5) /* I915_VMA_PIN_OVERFLOW */ #define PIN_GLOBAL BIT(6) /* I915_VMA_GLOBAL_BIND */ diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c index fc950ab..568bf83 100644 --- a/drivers/gpu/drm/i915/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/i915_gem_internal.c @@ -188,9 +188,11 @@ i915_gem_object_create_internal(struct drm_i915_private *i915, drm_gem_private_object_init(&i915->drm, &obj->base, size); i915_gem_object_init(obj, &i915_gem_object_internal_ops); - obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; + obj->cache_coherent = i915_gem_object_is_coherent(obj); + obj->cache_dirty = !obj->cache_coherent; return obj; } diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 35e1a27..5b19a49 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -68,9 +68,25 @@ struct drm_i915_gem_object { const struct drm_i915_gem_object_ops *ops; - /** List of VMAs backed by this object */ + /** + * @vma_list: List of VMAs backed by this object + * + * The VMA on this list are ordered by type, all GGTT vma are placed + * at the head and all ppGTT vma are placed at the tail. The different + * types of GGTT vma are unordered between themselves, use the + * @vma_tree (which has a defined order between all VMA) to find an + * exact match. + */ struct list_head vma_list; + /** + * @vma_tree: Ordered tree of VMAs backed by this object + * + * All VMA created for this object are placed in the @vma_tree for + * fast retrieval via a binary search in i915_vma_instance(). + * They are also added to @vma_list for easy iteration. + */ struct rb_root vma_tree; + struct i915_vma *vma_hashed; /** Stolen memory for this object, instead of being backed by shmem. */ struct drm_mm_node *stolen; @@ -85,9 +101,6 @@ struct drm_i915_gem_object { */ struct list_head userfault_link; - /** Used in execbuf to temporarily hold a ref */ - struct list_head obj_exec_link; - struct list_head batch_pool_link; I915_SELFTEST_DECLARE(struct list_head st_link); @@ -106,6 +119,7 @@ struct drm_i915_gem_object { unsigned long gt_ro:1; unsigned int cache_level:3; unsigned int cache_dirty:1; + unsigned int cache_coherent:1; atomic_t frontbuffer_bits; unsigned int frontbuffer_ggtt_origin; /* write once */ diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 0d1e0d8..8c59c79 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -62,7 +62,7 @@ static bool i915_fence_enable_signaling(struct dma_fence *fence) return false; intel_engine_enable_signaling(to_request(fence), true); - return true; + return !i915_fence_signaled(fence); } static signed long i915_fence_wait(struct dma_fence *fence, @@ -683,7 +683,6 @@ static int i915_gem_request_await_request(struct drm_i915_gem_request *to, struct drm_i915_gem_request *from) { - u32 seqno; int ret; GEM_BUG_ON(to == from); @@ -707,18 +706,14 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, return ret < 0 ? ret : 0; } - seqno = i915_gem_request_global_seqno(from); - if (!seqno) - goto await_dma_fence; + if (to->engine->semaphore.sync_to) { + u32 seqno; - if (!to->engine->semaphore.sync_to) { - if (!__i915_gem_request_started(from, seqno)) - goto await_dma_fence; + GEM_BUG_ON(!from->engine->semaphore.signal); - if (!__i915_spin_request(from, seqno, TASK_INTERRUPTIBLE, 2)) + seqno = i915_gem_request_global_seqno(from); + if (!seqno) goto await_dma_fence; - } else { - GEM_BUG_ON(!from->engine->semaphore.signal); if (seqno <= to->timeline->global_sync[from->engine->id]) return 0; @@ -729,10 +724,9 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, return ret; to->timeline->global_sync[from->engine->id] = seqno; + return 0; } - return 0; - await_dma_fence: ret = i915_sw_fence_await_dma_fence(&to->submit, &from->fence, 0, diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 0fd2b58..1032f98 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -38,16 +38,21 @@ static bool shrinker_lock(struct drm_i915_private *dev_priv, bool *unlock) { switch (mutex_trylock_recursive(&dev_priv->drm.struct_mutex)) { - case MUTEX_TRYLOCK_FAILED: - return false; - - case MUTEX_TRYLOCK_SUCCESS: - *unlock = true; - return true; - case MUTEX_TRYLOCK_RECURSIVE: *unlock = false; return true; + + case MUTEX_TRYLOCK_FAILED: + do { + cpu_relax(); + if (mutex_trylock(&dev_priv->drm.struct_mutex)) { + case MUTEX_TRYLOCK_SUCCESS: + *unlock = true; + return true; + } + } while (!need_resched()); + + return false; } BUG(); @@ -332,6 +337,15 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) sc->nr_to_scan - freed, I915_SHRINK_BOUND | I915_SHRINK_UNBOUND); + if (freed < sc->nr_to_scan && current_is_kswapd()) { + intel_runtime_pm_get(dev_priv); + freed += i915_gem_shrink(dev_priv, + sc->nr_to_scan - freed, + I915_SHRINK_ACTIVE | + I915_SHRINK_BOUND | + I915_SHRINK_UNBOUND); + intel_runtime_pm_put(dev_priv); + } shrinker_unlock(dev_priv, unlock); diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 681db60..a817b3e 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -590,6 +590,7 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv, obj->stolen = stolen; obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT; obj->cache_level = HAS_LLC(dev_priv) ? I915_CACHE_LLC : I915_CACHE_NONE; + obj->cache_coherent = true; /* assumptions! more like cache_oblivious */ if (i915_gem_object_pin_pages(obj)) goto cleanup; diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 1a0ce1d..ccd09e8 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -378,7 +378,7 @@ __i915_mm_struct_free(struct kref *kref) mutex_unlock(&mm->i915->mm_lock); INIT_WORK(&mm->work, __i915_mm_struct_free__worker); - schedule_work(&mm->work); + queue_work(mm->i915->mm.userptr_wq, &mm->work); } static void @@ -598,7 +598,7 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj) get_task_struct(work->task); INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker); - schedule_work(&work->work); + queue_work(to_i915(obj->base.dev)->mm.userptr_wq, &work->work); return ERR_PTR(-EAGAIN); } @@ -802,9 +802,11 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file drm_gem_private_object_init(dev, &obj->base, args->user_size); i915_gem_object_init(obj, &i915_gem_userptr_ops); - obj->cache_level = I915_CACHE_LLC; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->base.write_domain = I915_GEM_DOMAIN_CPU; + obj->cache_level = I915_CACHE_LLC; + obj->cache_coherent = i915_gem_object_is_coherent(obj); + obj->cache_dirty = !obj->cache_coherent; obj->userptr.ptr = args->user_ptr; obj->userptr.read_only = !!(args->flags & I915_USERPTR_READ_ONLY); @@ -828,8 +830,20 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file return 0; } -void i915_gem_init_userptr(struct drm_i915_private *dev_priv) +int i915_gem_init_userptr(struct drm_i915_private *dev_priv) { mutex_init(&dev_priv->mm_lock); hash_init(dev_priv->mm_structs); + + dev_priv->mm.userptr_wq = + alloc_workqueue("i915-userptr-acquire", WQ_HIGHPRI, 0); + if (!dev_priv->mm.userptr_wq) + return -ENOMEM; + + return 0; +} + +void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv) +{ + destroy_workqueue(dev_priv->mm.userptr_wq); } diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index e6e0c6e..48a1e93 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -105,7 +105,7 @@ static int __reserve_doorbell(struct i915_guc_client *client) end += offset; } - id = find_next_zero_bit(client->guc->doorbell_bitmap, offset, end); + id = find_next_zero_bit(client->guc->doorbell_bitmap, end, offset); if (id == end) return -ENOSPC; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7b7f55a..4cd9ee1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2548,7 +2548,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) I915_WRITE(SDEIIR, iir); ret = IRQ_HANDLED; - if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv)) + if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv) || + HAS_PCH_CNP(dev_priv)) spt_irq_handler(dev_priv, iir); else cpt_irq_handler(dev_priv, iir); @@ -4289,7 +4290,8 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev->driver->disable_vblank = gen8_disable_vblank; if (IS_GEN9_LP(dev_priv)) dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; - else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv)) + else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv) || + HAS_PCH_CNP(dev_priv)) dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup; else dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.c b/drivers/gpu/drm/i915/i915_oa_bdw.c new file mode 100644 index 0000000..d4462c2 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_bdw.c @@ -0,0 +1,5376 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_bdw.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_DATA_PORT_READS_COALESCING, + METRIC_SET_ID_DATA_PORT_WRITES_COALESCING, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_L3_2, + METRIC_SET_ID_L3_3, + METRIC_SET_ID_L3_4, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER_1, + METRIC_SET_ID_SAMPLER_2, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_VME_PIPE, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_bdw = 22; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic_0_slices_0x01[] = { + { _MMIO(0x9888), 0x143f000f }, + { _MMIO(0x9888), 0x14110014 }, + { _MMIO(0x9888), 0x14310014 }, + { _MMIO(0x9888), 0x14bf000f }, + { _MMIO(0x9888), 0x118a0317 }, + { _MMIO(0x9888), 0x13837be0 }, + { _MMIO(0x9888), 0x3b800060 }, + { _MMIO(0x9888), 0x3d800005 }, + { _MMIO(0x9888), 0x005c4000 }, + { _MMIO(0x9888), 0x065c8000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x003d8000 }, + { _MMIO(0x9888), 0x183d0800 }, + { _MMIO(0x9888), 0x0a3f0023 }, + { _MMIO(0x9888), 0x103f0000 }, + { _MMIO(0x9888), 0x00584000 }, + { _MMIO(0x9888), 0x08584000 }, + { _MMIO(0x9888), 0x0a5a4000 }, + { _MMIO(0x9888), 0x005b4000 }, + { _MMIO(0x9888), 0x0e5b8000 }, + { _MMIO(0x9888), 0x185b2400 }, + { _MMIO(0x9888), 0x0a1d4000 }, + { _MMIO(0x9888), 0x0c1f0800 }, + { _MMIO(0x9888), 0x0e1faa00 }, + { _MMIO(0x9888), 0x00384000 }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18380001 }, + { _MMIO(0x9888), 0x00392000 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a391000 }, + { _MMIO(0x9888), 0x00104000 }, + { _MMIO(0x9888), 0x08104000 }, + { _MMIO(0x9888), 0x00110030 }, + { _MMIO(0x9888), 0x08110031 }, + { _MMIO(0x9888), 0x10110000 }, + { _MMIO(0x9888), 0x00134000 }, + { _MMIO(0x9888), 0x16130020 }, + { _MMIO(0x9888), 0x06308000 }, + { _MMIO(0x9888), 0x08308000 }, + { _MMIO(0x9888), 0x06311800 }, + { _MMIO(0x9888), 0x08311880 }, + { _MMIO(0x9888), 0x10310000 }, + { _MMIO(0x9888), 0x0e334000 }, + { _MMIO(0x9888), 0x16330080 }, + { _MMIO(0x9888), 0x0abf1180 }, + { _MMIO(0x9888), 0x10bf0000 }, + { _MMIO(0x9888), 0x0ada8000 }, + { _MMIO(0x9888), 0x0a9d8000 }, + { _MMIO(0x9888), 0x109f0002 }, + { _MMIO(0x9888), 0x0ab94000 }, + { _MMIO(0x9888), 0x0d888000 }, + { _MMIO(0x9888), 0x038a0380 }, + { _MMIO(0x9888), 0x058a000e }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8a00a0 }, + { _MMIO(0x9888), 0x078a0000 }, + { _MMIO(0x9888), 0x098a0000 }, + { _MMIO(0x9888), 0x238b2820 }, + { _MMIO(0x9888), 0x258b2550 }, + { _MMIO(0x9888), 0x198c1000 }, + { _MMIO(0x9888), 0x0b8d8000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa0 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x0d831021 }, + { _MMIO(0x9888), 0x0f83572f }, + { _MMIO(0x9888), 0x01835680 }, + { _MMIO(0x9888), 0x0383002c }, + { _MMIO(0x9888), 0x11830000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830001 }, + { _MMIO(0x9888), 0x05830000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x05844000 }, + { _MMIO(0x9888), 0x1b80c137 }, + { _MMIO(0x9888), 0x1d80c147 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x15804000 }, + { _MMIO(0x9888), 0x4d801110 }, + { _MMIO(0x9888), 0x4f800331 }, + { _MMIO(0x9888), 0x43800802 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45801465 }, + { _MMIO(0x9888), 0x53801111 }, + { _MMIO(0x9888), 0x478014a5 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800ca5 }, + { _MMIO(0x9888), 0x41800003 }, +}; + +static const struct i915_oa_reg mux_config_render_basic_1_slices_0x02[] = { + { _MMIO(0x9888), 0x143f000f }, + { _MMIO(0x9888), 0x14bf000f }, + { _MMIO(0x9888), 0x14910014 }, + { _MMIO(0x9888), 0x14b10014 }, + { _MMIO(0x9888), 0x118a0317 }, + { _MMIO(0x9888), 0x13837be0 }, + { _MMIO(0x9888), 0x3b800060 }, + { _MMIO(0x9888), 0x3d800005 }, + { _MMIO(0x9888), 0x0a3f0023 }, + { _MMIO(0x9888), 0x103f0000 }, + { _MMIO(0x9888), 0x0a5a4000 }, + { _MMIO(0x9888), 0x0a1d4000 }, + { _MMIO(0x9888), 0x0e1f8000 }, + { _MMIO(0x9888), 0x0a391000 }, + { _MMIO(0x9888), 0x00dc4000 }, + { _MMIO(0x9888), 0x06dc8000 }, + { _MMIO(0x9888), 0x08dcc000 }, + { _MMIO(0x9888), 0x00bd8000 }, + { _MMIO(0x9888), 0x18bd0800 }, + { _MMIO(0x9888), 0x0abf1180 }, + { _MMIO(0x9888), 0x10bf0000 }, + { _MMIO(0x9888), 0x00d84000 }, + { _MMIO(0x9888), 0x08d84000 }, + { _MMIO(0x9888), 0x0ada8000 }, + { _MMIO(0x9888), 0x00db4000 }, + { _MMIO(0x9888), 0x0edb8000 }, + { _MMIO(0x9888), 0x18db2400 }, + { _MMIO(0x9888), 0x0a9d8000 }, + { _MMIO(0x9888), 0x0c9f0800 }, + { _MMIO(0x9888), 0x0e9f2a00 }, + { _MMIO(0x9888), 0x109f0002 }, + { _MMIO(0x9888), 0x00b84000 }, + { _MMIO(0x9888), 0x0eb84000 }, + { _MMIO(0x9888), 0x16b84000 }, + { _MMIO(0x9888), 0x18b80001 }, + { _MMIO(0x9888), 0x00b92000 }, + { _MMIO(0x9888), 0x06b98000 }, + { _MMIO(0x9888), 0x08b9a000 }, + { _MMIO(0x9888), 0x0ab94000 }, + { _MMIO(0x9888), 0x00904000 }, + { _MMIO(0x9888), 0x08904000 }, + { _MMIO(0x9888), 0x00910030 }, + { _MMIO(0x9888), 0x08910031 }, + { _MMIO(0x9888), 0x10910000 }, + { _MMIO(0x9888), 0x00934000 }, + { _MMIO(0x9888), 0x16930020 }, + { _MMIO(0x9888), 0x06b08000 }, + { _MMIO(0x9888), 0x08b08000 }, + { _MMIO(0x9888), 0x06b11800 }, + { _MMIO(0x9888), 0x08b11880 }, + { _MMIO(0x9888), 0x10b10000 }, + { _MMIO(0x9888), 0x0eb34000 }, + { _MMIO(0x9888), 0x16b30080 }, + { _MMIO(0x9888), 0x01888000 }, + { _MMIO(0x9888), 0x0d88b800 }, + { _MMIO(0x9888), 0x038a0380 }, + { _MMIO(0x9888), 0x058a000e }, + { _MMIO(0x9888), 0x1b8a0080 }, + { _MMIO(0x9888), 0x078a0000 }, + { _MMIO(0x9888), 0x098a0000 }, + { _MMIO(0x9888), 0x238b2840 }, + { _MMIO(0x9888), 0x258b26a0 }, + { _MMIO(0x9888), 0x018c4000 }, + { _MMIO(0x9888), 0x0f8c4000 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c1100 }, + { _MMIO(0x9888), 0x018d2000 }, + { _MMIO(0x9888), 0x078d8000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8d8000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa0 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x0d831021 }, + { _MMIO(0x9888), 0x0f83572f }, + { _MMIO(0x9888), 0x01835680 }, + { _MMIO(0x9888), 0x0383002c }, + { _MMIO(0x9888), 0x11830000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830001 }, + { _MMIO(0x9888), 0x05830000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x05844000 }, + { _MMIO(0x9888), 0x1b80c137 }, + { _MMIO(0x9888), 0x1d80c147 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x15804000 }, + { _MMIO(0x9888), 0x4d801550 }, + { _MMIO(0x9888), 0x4f800331 }, + { _MMIO(0x9888), 0x43800802 }, + { _MMIO(0x9888), 0x51800400 }, + { _MMIO(0x9888), 0x458004a1 }, + { _MMIO(0x9888), 0x53805555 }, + { _MMIO(0x9888), 0x47800421 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f801421 }, + { _MMIO(0x9888), 0x41800845 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2); + + if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) { + regs[n] = mux_config_render_basic_0_slices_0x01; + lens[n] = ARRAY_SIZE(mux_config_render_basic_0_slices_0x01); + n++; + } + if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x02) { + regs[n] = mux_config_render_basic_1_slices_0x02; + lens[n] = ARRAY_SIZE(mux_config_render_basic_1_slices_0x02); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01[] = { + { _MMIO(0x9888), 0x105c00e0 }, + { _MMIO(0x9888), 0x105800e0 }, + { _MMIO(0x9888), 0x103800e0 }, + { _MMIO(0x9888), 0x3580001a }, + { _MMIO(0x9888), 0x3b800060 }, + { _MMIO(0x9888), 0x3d800005 }, + { _MMIO(0x9888), 0x065c2100 }, + { _MMIO(0x9888), 0x0a5c0041 }, + { _MMIO(0x9888), 0x0c5c6600 }, + { _MMIO(0x9888), 0x005c6580 }, + { _MMIO(0x9888), 0x085c8000 }, + { _MMIO(0x9888), 0x0e5c8000 }, + { _MMIO(0x9888), 0x00580042 }, + { _MMIO(0x9888), 0x08582080 }, + { _MMIO(0x9888), 0x0c58004c }, + { _MMIO(0x9888), 0x0e582580 }, + { _MMIO(0x9888), 0x005b4000 }, + { _MMIO(0x9888), 0x185b1000 }, + { _MMIO(0x9888), 0x1a5b0104 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1faa00 }, + { _MMIO(0x9888), 0x101f02aa }, + { _MMIO(0x9888), 0x08380042 }, + { _MMIO(0x9888), 0x0a382080 }, + { _MMIO(0x9888), 0x0e38404c }, + { _MMIO(0x9888), 0x0238404b }, + { _MMIO(0x9888), 0x00384000 }, + { _MMIO(0x9888), 0x16380000 }, + { _MMIO(0x9888), 0x18381145 }, + { _MMIO(0x9888), 0x04380000 }, + { _MMIO(0x9888), 0x0039a000 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x02392000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8aaaa0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x238b02a0 }, + { _MMIO(0x9888), 0x258b5550 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x1f850a80 }, + { _MMIO(0x9888), 0x2185aaa0 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x03844000 }, + { _MMIO(0x9888), 0x17808137 }, + { _MMIO(0x9888), 0x1980c147 }, + { _MMIO(0x9888), 0x1b80c0e5 }, + { _MMIO(0x9888), 0x1d80c0e3 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x13804000 }, + { _MMIO(0x9888), 0x15800000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d801000 }, + { _MMIO(0x9888), 0x4f800111 }, + { _MMIO(0x9888), 0x43800062 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800062 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800062 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f801062 }, + { _MMIO(0x9888), 0x41801084 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic_2_slices_0x02[] = { + { _MMIO(0x9888), 0x10dc00e0 }, + { _MMIO(0x9888), 0x10d800e0 }, + { _MMIO(0x9888), 0x10b800e0 }, + { _MMIO(0x9888), 0x3580001a }, + { _MMIO(0x9888), 0x3b800060 }, + { _MMIO(0x9888), 0x3d800005 }, + { _MMIO(0x9888), 0x06dc2100 }, + { _MMIO(0x9888), 0x0adc0041 }, + { _MMIO(0x9888), 0x0cdc6600 }, + { _MMIO(0x9888), 0x00dc6580 }, + { _MMIO(0x9888), 0x08dc8000 }, + { _MMIO(0x9888), 0x0edc8000 }, + { _MMIO(0x9888), 0x00d80042 }, + { _MMIO(0x9888), 0x08d82080 }, + { _MMIO(0x9888), 0x0cd8004c }, + { _MMIO(0x9888), 0x0ed82580 }, + { _MMIO(0x9888), 0x00db4000 }, + { _MMIO(0x9888), 0x18db1000 }, + { _MMIO(0x9888), 0x1adb0104 }, + { _MMIO(0x9888), 0x0c9fa800 }, + { _MMIO(0x9888), 0x0e9faa00 }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x08b80042 }, + { _MMIO(0x9888), 0x0ab82080 }, + { _MMIO(0x9888), 0x0eb8404c }, + { _MMIO(0x9888), 0x02b8404b }, + { _MMIO(0x9888), 0x00b84000 }, + { _MMIO(0x9888), 0x16b80000 }, + { _MMIO(0x9888), 0x18b81145 }, + { _MMIO(0x9888), 0x04b80000 }, + { _MMIO(0x9888), 0x00b9a000 }, + { _MMIO(0x9888), 0x06b98000 }, + { _MMIO(0x9888), 0x08b9a000 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x02b92000 }, + { _MMIO(0x9888), 0x01888000 }, + { _MMIO(0x9888), 0x0d88f800 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x238b0540 }, + { _MMIO(0x9888), 0x258baaa0 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x018c4000 }, + { _MMIO(0x9888), 0x0f8c4000 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c5500 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x018da000 }, + { _MMIO(0x9888), 0x078d8000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x038d2000 }, + { _MMIO(0x9888), 0x1f850a80 }, + { _MMIO(0x9888), 0x2185aaa0 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x03844000 }, + { _MMIO(0x9888), 0x17808137 }, + { _MMIO(0x9888), 0x1980c147 }, + { _MMIO(0x9888), 0x1b80c0e5 }, + { _MMIO(0x9888), 0x1d80c0e3 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x13804000 }, + { _MMIO(0x9888), 0x15800000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d805000 }, + { _MMIO(0x9888), 0x4f800555 }, + { _MMIO(0x9888), 0x43800062 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800062 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800062 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800062 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2); + + if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) { + regs[n] = mux_config_compute_basic_0_slices_0x01; + lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01); + n++; + } + if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x02) { + regs[n] = mux_config_compute_basic_2_slices_0x02; + lens[n] = ARRAY_SIZE(mux_config_compute_basic_2_slices_0x02); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x0a1e0000 }, + { _MMIO(0x9888), 0x0c1f000f }, + { _MMIO(0x9888), 0x10176800 }, + { _MMIO(0x9888), 0x1191001f }, + { _MMIO(0x9888), 0x0b880320 }, + { _MMIO(0x9888), 0x01890c40 }, + { _MMIO(0x9888), 0x118a1c00 }, + { _MMIO(0x9888), 0x118d7c00 }, + { _MMIO(0x9888), 0x118e0020 }, + { _MMIO(0x9888), 0x118f4c00 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x13900001 }, + { _MMIO(0x9888), 0x065c4000 }, + { _MMIO(0x9888), 0x0c3d8000 }, + { _MMIO(0x9888), 0x06584000 }, + { _MMIO(0x9888), 0x0c5b4000 }, + { _MMIO(0x9888), 0x081e0040 }, + { _MMIO(0x9888), 0x0e1e0000 }, + { _MMIO(0x9888), 0x021f5400 }, + { _MMIO(0x9888), 0x001f0000 }, + { _MMIO(0x9888), 0x101f0010 }, + { _MMIO(0x9888), 0x0e1f0080 }, + { _MMIO(0x9888), 0x0c384000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x0c13c000 }, + { _MMIO(0x9888), 0x06164000 }, + { _MMIO(0x9888), 0x06170012 }, + { _MMIO(0x9888), 0x00170000 }, + { _MMIO(0x9888), 0x01910005 }, + { _MMIO(0x9888), 0x07880002 }, + { _MMIO(0x9888), 0x01880c00 }, + { _MMIO(0x9888), 0x0f880000 }, + { _MMIO(0x9888), 0x0d880000 }, + { _MMIO(0x9888), 0x05880000 }, + { _MMIO(0x9888), 0x09890032 }, + { _MMIO(0x9888), 0x078a0800 }, + { _MMIO(0x9888), 0x0f8a0a00 }, + { _MMIO(0x9888), 0x198a4000 }, + { _MMIO(0x9888), 0x1b8a2000 }, + { _MMIO(0x9888), 0x1d8a0000 }, + { _MMIO(0x9888), 0x038a4000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x238b54c0 }, + { _MMIO(0x9888), 0x258baa55 }, + { _MMIO(0x9888), 0x278b0019 }, + { _MMIO(0x9888), 0x198c0100 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x0f8d0015 }, + { _MMIO(0x9888), 0x018d1000 }, + { _MMIO(0x9888), 0x098d8000 }, + { _MMIO(0x9888), 0x0b8df000 }, + { _MMIO(0x9888), 0x0d8d3000 }, + { _MMIO(0x9888), 0x038de000 }, + { _MMIO(0x9888), 0x058d3000 }, + { _MMIO(0x9888), 0x0d8e0004 }, + { _MMIO(0x9888), 0x058e000c }, + { _MMIO(0x9888), 0x098e0000 }, + { _MMIO(0x9888), 0x078e0000 }, + { _MMIO(0x9888), 0x038e0000 }, + { _MMIO(0x9888), 0x0b8f0020 }, + { _MMIO(0x9888), 0x198f0c00 }, + { _MMIO(0x9888), 0x078f8000 }, + { _MMIO(0x9888), 0x098f4000 }, + { _MMIO(0x9888), 0x0b900980 }, + { _MMIO(0x9888), 0x03900d80 }, + { _MMIO(0x9888), 0x01900000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d801111 }, + { _MMIO(0x9888), 0x3d800800 }, + { _MMIO(0x9888), 0x4f801011 }, + { _MMIO(0x9888), 0x43800443 }, + { _MMIO(0x9888), 0x51801111 }, + { _MMIO(0x9888), 0x45800422 }, + { _MMIO(0x9888), 0x53801111 }, + { _MMIO(0x9888), 0x47800c60 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800422 }, + { _MMIO(0x9888), 0x41800021 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads[] = { + { _MMIO(0x9888), 0x198b0343 }, + { _MMIO(0x9888), 0x13845800 }, + { _MMIO(0x9888), 0x15840018 }, + { _MMIO(0x9888), 0x3580001a }, + { _MMIO(0x9888), 0x038b6300 }, + { _MMIO(0x9888), 0x058b6b62 }, + { _MMIO(0x9888), 0x078b006a }, + { _MMIO(0x9888), 0x118b0000 }, + { _MMIO(0x9888), 0x238b0000 }, + { _MMIO(0x9888), 0x258b0000 }, + { _MMIO(0x9888), 0x1f85a080 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385000a }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x01840018 }, + { _MMIO(0x9888), 0x07844c80 }, + { _MMIO(0x9888), 0x09840d9a }, + { _MMIO(0x9888), 0x0b840e9c }, + { _MMIO(0x9888), 0x0d840f9e }, + { _MMIO(0x9888), 0x0f840010 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x03848000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x2f8000e5 }, + { _MMIO(0x9888), 0x138080e3 }, + { _MMIO(0x9888), 0x1580c0e1 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x11804000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f804000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800800 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800842 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800842 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47801042 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800084 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes[] = { + { _MMIO(0x9888), 0x198b0343 }, + { _MMIO(0x9888), 0x13845400 }, + { _MMIO(0x9888), 0x3580001a }, + { _MMIO(0x9888), 0x3d800805 }, + { _MMIO(0x9888), 0x038b6300 }, + { _MMIO(0x9888), 0x058b6b62 }, + { _MMIO(0x9888), 0x078b006a }, + { _MMIO(0x9888), 0x118b0000 }, + { _MMIO(0x9888), 0x238b0000 }, + { _MMIO(0x9888), 0x258b0000 }, + { _MMIO(0x9888), 0x1f85a080 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x23850002 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x01840010 }, + { _MMIO(0x9888), 0x07844880 }, + { _MMIO(0x9888), 0x09840992 }, + { _MMIO(0x9888), 0x0b840a94 }, + { _MMIO(0x9888), 0x0d840b96 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x03848000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x2d800147 }, + { _MMIO(0x9888), 0x2f8000e5 }, + { _MMIO(0x9888), 0x138080e3 }, + { _MMIO(0x9888), 0x1580c0e1 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x11804000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f800000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800842 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800842 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47801082 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800084 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended_0_subslices_0x01[] = { + { _MMIO(0x9888), 0x143d0160 }, + { _MMIO(0x9888), 0x163d2800 }, + { _MMIO(0x9888), 0x183d0120 }, + { _MMIO(0x9888), 0x105800e0 }, + { _MMIO(0x9888), 0x005cc000 }, + { _MMIO(0x9888), 0x065c8000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x0a5cc000 }, + { _MMIO(0x9888), 0x0c5cc000 }, + { _MMIO(0x9888), 0x0e5cc000 }, + { _MMIO(0x9888), 0x025cc000 }, + { _MMIO(0x9888), 0x045cc000 }, + { _MMIO(0x9888), 0x003d0011 }, + { _MMIO(0x9888), 0x063d0900 }, + { _MMIO(0x9888), 0x083d0a13 }, + { _MMIO(0x9888), 0x0a3d0b15 }, + { _MMIO(0x9888), 0x0c3d2317 }, + { _MMIO(0x9888), 0x043d21b7 }, + { _MMIO(0x9888), 0x103d0000 }, + { _MMIO(0x9888), 0x0e3d0000 }, + { _MMIO(0x9888), 0x1a3d0000 }, + { _MMIO(0x9888), 0x0e5825c1 }, + { _MMIO(0x9888), 0x00586100 }, + { _MMIO(0x9888), 0x0258204c }, + { _MMIO(0x9888), 0x06588000 }, + { _MMIO(0x9888), 0x0858c000 }, + { _MMIO(0x9888), 0x0a58c000 }, + { _MMIO(0x9888), 0x0c58c000 }, + { _MMIO(0x9888), 0x0458c000 }, + { _MMIO(0x9888), 0x005b4000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x185b5400 }, + { _MMIO(0x9888), 0x1a5b0155 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1faa2a }, + { _MMIO(0x9888), 0x101f02aa }, + { _MMIO(0x9888), 0x00384000 }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18381555 }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x04384000 }, + { _MMIO(0x9888), 0x06384000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0039a000 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8aaaa0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x238b2aa0 }, + { _MMIO(0x9888), 0x258b5551 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa2 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended_2_subslices_0x02[] = { + { _MMIO(0x9888), 0x105c00e0 }, + { _MMIO(0x9888), 0x145b0160 }, + { _MMIO(0x9888), 0x165b2800 }, + { _MMIO(0x9888), 0x185b0120 }, + { _MMIO(0x9888), 0x0e5c25c1 }, + { _MMIO(0x9888), 0x005c6100 }, + { _MMIO(0x9888), 0x025c204c }, + { _MMIO(0x9888), 0x065c8000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x0a5cc000 }, + { _MMIO(0x9888), 0x0c5cc000 }, + { _MMIO(0x9888), 0x045cc000 }, + { _MMIO(0x9888), 0x005b0011 }, + { _MMIO(0x9888), 0x065b0900 }, + { _MMIO(0x9888), 0x085b0a13 }, + { _MMIO(0x9888), 0x0a5b0b15 }, + { _MMIO(0x9888), 0x0c5b2317 }, + { _MMIO(0x9888), 0x045b21b7 }, + { _MMIO(0x9888), 0x105b0000 }, + { _MMIO(0x9888), 0x0e5b0000 }, + { _MMIO(0x9888), 0x1a5b0000 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1faa2a }, + { _MMIO(0x9888), 0x101f02aa }, + { _MMIO(0x9888), 0x00384000 }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18381555 }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x04384000 }, + { _MMIO(0x9888), 0x06384000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0039a000 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8aaaa0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x238b2aa0 }, + { _MMIO(0x9888), 0x258b5551 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa2 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended_4_subslices_0x04[] = { + { _MMIO(0x9888), 0x103800e0 }, + { _MMIO(0x9888), 0x143a0160 }, + { _MMIO(0x9888), 0x163a2800 }, + { _MMIO(0x9888), 0x183a0120 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1faa2a }, + { _MMIO(0x9888), 0x101f02aa }, + { _MMIO(0x9888), 0x0e38a5c1 }, + { _MMIO(0x9888), 0x0038a100 }, + { _MMIO(0x9888), 0x0238204c }, + { _MMIO(0x9888), 0x16388000 }, + { _MMIO(0x9888), 0x183802aa }, + { _MMIO(0x9888), 0x04380000 }, + { _MMIO(0x9888), 0x06380000 }, + { _MMIO(0x9888), 0x08388000 }, + { _MMIO(0x9888), 0x0a388000 }, + { _MMIO(0x9888), 0x0039a000 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x003a0011 }, + { _MMIO(0x9888), 0x063a0900 }, + { _MMIO(0x9888), 0x083a0a13 }, + { _MMIO(0x9888), 0x0a3a0b15 }, + { _MMIO(0x9888), 0x0c3a2317 }, + { _MMIO(0x9888), 0x043a21b7 }, + { _MMIO(0x9888), 0x103a0000 }, + { _MMIO(0x9888), 0x0e3a0000 }, + { _MMIO(0x9888), 0x1a3a0000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8aaaa0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x238b2aa0 }, + { _MMIO(0x9888), 0x258b5551 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa2 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended_1_subslices_0x08[] = { + { _MMIO(0x9888), 0x14bd0160 }, + { _MMIO(0x9888), 0x16bd2800 }, + { _MMIO(0x9888), 0x18bd0120 }, + { _MMIO(0x9888), 0x10d800e0 }, + { _MMIO(0x9888), 0x00dcc000 }, + { _MMIO(0x9888), 0x06dc8000 }, + { _MMIO(0x9888), 0x08dcc000 }, + { _MMIO(0x9888), 0x0adcc000 }, + { _MMIO(0x9888), 0x0cdcc000 }, + { _MMIO(0x9888), 0x0edcc000 }, + { _MMIO(0x9888), 0x02dcc000 }, + { _MMIO(0x9888), 0x04dcc000 }, + { _MMIO(0x9888), 0x00bd0011 }, + { _MMIO(0x9888), 0x06bd0900 }, + { _MMIO(0x9888), 0x08bd0a13 }, + { _MMIO(0x9888), 0x0abd0b15 }, + { _MMIO(0x9888), 0x0cbd2317 }, + { _MMIO(0x9888), 0x04bd21b7 }, + { _MMIO(0x9888), 0x10bd0000 }, + { _MMIO(0x9888), 0x0ebd0000 }, + { _MMIO(0x9888), 0x1abd0000 }, + { _MMIO(0x9888), 0x0ed825c1 }, + { _MMIO(0x9888), 0x00d86100 }, + { _MMIO(0x9888), 0x02d8204c }, + { _MMIO(0x9888), 0x06d88000 }, + { _MMIO(0x9888), 0x08d8c000 }, + { _MMIO(0x9888), 0x0ad8c000 }, + { _MMIO(0x9888), 0x0cd8c000 }, + { _MMIO(0x9888), 0x04d8c000 }, + { _MMIO(0x9888), 0x00db4000 }, + { _MMIO(0x9888), 0x0edb4000 }, + { _MMIO(0x9888), 0x18db5400 }, + { _MMIO(0x9888), 0x1adb0155 }, + { _MMIO(0x9888), 0x02db4000 }, + { _MMIO(0x9888), 0x04db4000 }, + { _MMIO(0x9888), 0x06db4000 }, + { _MMIO(0x9888), 0x08db4000 }, + { _MMIO(0x9888), 0x0adb4000 }, + { _MMIO(0x9888), 0x0c9fa800 }, + { _MMIO(0x9888), 0x0e9faa2a }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x00b84000 }, + { _MMIO(0x9888), 0x0eb84000 }, + { _MMIO(0x9888), 0x16b84000 }, + { _MMIO(0x9888), 0x18b81555 }, + { _MMIO(0x9888), 0x02b84000 }, + { _MMIO(0x9888), 0x04b84000 }, + { _MMIO(0x9888), 0x06b84000 }, + { _MMIO(0x9888), 0x08b84000 }, + { _MMIO(0x9888), 0x0ab84000 }, + { _MMIO(0x9888), 0x00b9a000 }, + { _MMIO(0x9888), 0x06b98000 }, + { _MMIO(0x9888), 0x08b9a000 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x04b9a000 }, + { _MMIO(0x9888), 0x01888000 }, + { _MMIO(0x9888), 0x0d88f800 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x238b5540 }, + { _MMIO(0x9888), 0x258baaa2 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x018c4000 }, + { _MMIO(0x9888), 0x0f8c4000 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c5500 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x018da000 }, + { _MMIO(0x9888), 0x078d8000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa2 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended_3_subslices_0x10[] = { + { _MMIO(0x9888), 0x10dc00e0 }, + { _MMIO(0x9888), 0x14db0160 }, + { _MMIO(0x9888), 0x16db2800 }, + { _MMIO(0x9888), 0x18db0120 }, + { _MMIO(0x9888), 0x0edc25c1 }, + { _MMIO(0x9888), 0x00dc6100 }, + { _MMIO(0x9888), 0x02dc204c }, + { _MMIO(0x9888), 0x06dc8000 }, + { _MMIO(0x9888), 0x08dcc000 }, + { _MMIO(0x9888), 0x0adcc000 }, + { _MMIO(0x9888), 0x0cdcc000 }, + { _MMIO(0x9888), 0x04dcc000 }, + { _MMIO(0x9888), 0x00db0011 }, + { _MMIO(0x9888), 0x06db0900 }, + { _MMIO(0x9888), 0x08db0a13 }, + { _MMIO(0x9888), 0x0adb0b15 }, + { _MMIO(0x9888), 0x0cdb2317 }, + { _MMIO(0x9888), 0x04db21b7 }, + { _MMIO(0x9888), 0x10db0000 }, + { _MMIO(0x9888), 0x0edb0000 }, + { _MMIO(0x9888), 0x1adb0000 }, + { _MMIO(0x9888), 0x0c9fa800 }, + { _MMIO(0x9888), 0x0e9faa2a }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x00b84000 }, + { _MMIO(0x9888), 0x0eb84000 }, + { _MMIO(0x9888), 0x16b84000 }, + { _MMIO(0x9888), 0x18b81555 }, + { _MMIO(0x9888), 0x02b84000 }, + { _MMIO(0x9888), 0x04b84000 }, + { _MMIO(0x9888), 0x06b84000 }, + { _MMIO(0x9888), 0x08b84000 }, + { _MMIO(0x9888), 0x0ab84000 }, + { _MMIO(0x9888), 0x00b9a000 }, + { _MMIO(0x9888), 0x06b98000 }, + { _MMIO(0x9888), 0x08b9a000 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x04b9a000 }, + { _MMIO(0x9888), 0x01888000 }, + { _MMIO(0x9888), 0x0d88f800 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x238b5540 }, + { _MMIO(0x9888), 0x258baaa2 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x018c4000 }, + { _MMIO(0x9888), 0x0f8c4000 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c5500 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x018da000 }, + { _MMIO(0x9888), 0x078d8000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa2 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended_5_subslices_0x20[] = { + { _MMIO(0x9888), 0x10b800e0 }, + { _MMIO(0x9888), 0x14ba0160 }, + { _MMIO(0x9888), 0x16ba2800 }, + { _MMIO(0x9888), 0x18ba0120 }, + { _MMIO(0x9888), 0x0c9fa800 }, + { _MMIO(0x9888), 0x0e9faa2a }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x0eb8a5c1 }, + { _MMIO(0x9888), 0x00b8a100 }, + { _MMIO(0x9888), 0x02b8204c }, + { _MMIO(0x9888), 0x16b88000 }, + { _MMIO(0x9888), 0x18b802aa }, + { _MMIO(0x9888), 0x04b80000 }, + { _MMIO(0x9888), 0x06b80000 }, + { _MMIO(0x9888), 0x08b88000 }, + { _MMIO(0x9888), 0x0ab88000 }, + { _MMIO(0x9888), 0x00b9a000 }, + { _MMIO(0x9888), 0x06b98000 }, + { _MMIO(0x9888), 0x08b9a000 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x04b9a000 }, + { _MMIO(0x9888), 0x00ba0011 }, + { _MMIO(0x9888), 0x06ba0900 }, + { _MMIO(0x9888), 0x08ba0a13 }, + { _MMIO(0x9888), 0x0aba0b15 }, + { _MMIO(0x9888), 0x0cba2317 }, + { _MMIO(0x9888), 0x04ba21b7 }, + { _MMIO(0x9888), 0x10ba0000 }, + { _MMIO(0x9888), 0x0eba0000 }, + { _MMIO(0x9888), 0x1aba0000 }, + { _MMIO(0x9888), 0x01888000 }, + { _MMIO(0x9888), 0x0d88f800 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x238b5540 }, + { _MMIO(0x9888), 0x258baaa2 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x018c4000 }, + { _MMIO(0x9888), 0x0f8c4000 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c5500 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x018da000 }, + { _MMIO(0x9888), 0x078d8000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa2 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800000 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 6); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 6); + + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) { + regs[n] = mux_config_compute_extended_0_subslices_0x01; + lens[n] = ARRAY_SIZE(mux_config_compute_extended_0_subslices_0x01); + n++; + } + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x08) { + regs[n] = mux_config_compute_extended_1_subslices_0x08; + lens[n] = ARRAY_SIZE(mux_config_compute_extended_1_subslices_0x08); + n++; + } + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x02) { + regs[n] = mux_config_compute_extended_2_subslices_0x02; + lens[n] = ARRAY_SIZE(mux_config_compute_extended_2_subslices_0x02); + n++; + } + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x10) { + regs[n] = mux_config_compute_extended_3_subslices_0x10; + lens[n] = ARRAY_SIZE(mux_config_compute_extended_3_subslices_0x10); + n++; + } + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x04) { + regs[n] = mux_config_compute_extended_4_subslices_0x04; + lens[n] = ARRAY_SIZE(mux_config_compute_extended_4_subslices_0x04); + n++; + } + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x20) { + regs[n] = mux_config_compute_extended_5_subslices_0x20; + lens[n] = ARRAY_SIZE(mux_config_compute_extended_5_subslices_0x20); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x143f00b3 }, + { _MMIO(0x9888), 0x14bf00b3 }, + { _MMIO(0x9888), 0x138303c0 }, + { _MMIO(0x9888), 0x3b800060 }, + { _MMIO(0x9888), 0x3d800805 }, + { _MMIO(0x9888), 0x003f0029 }, + { _MMIO(0x9888), 0x063f1400 }, + { _MMIO(0x9888), 0x083f1225 }, + { _MMIO(0x9888), 0x0e3f1327 }, + { _MMIO(0x9888), 0x103f0000 }, + { _MMIO(0x9888), 0x005a4000 }, + { _MMIO(0x9888), 0x065a8000 }, + { _MMIO(0x9888), 0x085ac000 }, + { _MMIO(0x9888), 0x0e5ac000 }, + { _MMIO(0x9888), 0x001d4000 }, + { _MMIO(0x9888), 0x061d8000 }, + { _MMIO(0x9888), 0x081dc000 }, + { _MMIO(0x9888), 0x0e1dc000 }, + { _MMIO(0x9888), 0x0c1f0800 }, + { _MMIO(0x9888), 0x0e1f2a00 }, + { _MMIO(0x9888), 0x101f0280 }, + { _MMIO(0x9888), 0x00391000 }, + { _MMIO(0x9888), 0x06394000 }, + { _MMIO(0x9888), 0x08395000 }, + { _MMIO(0x9888), 0x0e395000 }, + { _MMIO(0x9888), 0x0abf1429 }, + { _MMIO(0x9888), 0x0cbf1225 }, + { _MMIO(0x9888), 0x00bf1380 }, + { _MMIO(0x9888), 0x02bf0026 }, + { _MMIO(0x9888), 0x10bf0000 }, + { _MMIO(0x9888), 0x0adac000 }, + { _MMIO(0x9888), 0x0cdac000 }, + { _MMIO(0x9888), 0x00da8000 }, + { _MMIO(0x9888), 0x02da4000 }, + { _MMIO(0x9888), 0x0a9dc000 }, + { _MMIO(0x9888), 0x0c9dc000 }, + { _MMIO(0x9888), 0x009d8000 }, + { _MMIO(0x9888), 0x029d4000 }, + { _MMIO(0x9888), 0x0e9f8000 }, + { _MMIO(0x9888), 0x109f002a }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0ab95000 }, + { _MMIO(0x9888), 0x0cb95000 }, + { _MMIO(0x9888), 0x00b94000 }, + { _MMIO(0x9888), 0x02b91000 }, + { _MMIO(0x9888), 0x0d88c000 }, + { _MMIO(0x9888), 0x0f880003 }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8a8020 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x238b0520 }, + { _MMIO(0x9888), 0x258ba950 }, + { _MMIO(0x9888), 0x278b0016 }, + { _MMIO(0x9888), 0x198c5400 }, + { _MMIO(0x9888), 0x1b8c0001 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038d2000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaa0 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x03835180 }, + { _MMIO(0x9888), 0x05834022 }, + { _MMIO(0x9888), 0x11830000 }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x07830000 }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x05844000 }, + { _MMIO(0x9888), 0x1b80c137 }, + { _MMIO(0x9888), 0x1d80c147 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x15804000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d801000 }, + { _MMIO(0x9888), 0x4f800111 }, + { _MMIO(0x9888), 0x43800842 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800840 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800800 }, + { _MMIO(0x9888), 0x418014a2 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_data_port_reads_coalescing[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0xba98ba98 }, + { _MMIO(0x2748), 0xba98ba98 }, + { _MMIO(0x2744), 0x00003377 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fff2 }, + { _MMIO(0x2774), 0x00007ff0 }, + { _MMIO(0x2778), 0x0007ffe2 }, + { _MMIO(0x277c), 0x00007ff0 }, + { _MMIO(0x2780), 0x0007ffc2 }, + { _MMIO(0x2784), 0x00007ff0 }, + { _MMIO(0x2788), 0x0007ff82 }, + { _MMIO(0x278c), 0x00007ff0 }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000bfef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000bfdf }, + { _MMIO(0x27a0), 0x0007fffa }, + { _MMIO(0x27a4), 0x0000bfbf }, + { _MMIO(0x27a8), 0x0007fffa }, + { _MMIO(0x27ac), 0x0000bf7f }, +}; + +static const struct i915_oa_reg flex_eu_config_data_port_reads_coalescing[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_data_port_reads_coalescing_0_subslices_0x01[] = { + { _MMIO(0x9888), 0x103d0005 }, + { _MMIO(0x9888), 0x163d240b }, + { _MMIO(0x9888), 0x1058022f }, + { _MMIO(0x9888), 0x185b5520 }, + { _MMIO(0x9888), 0x198b0003 }, + { _MMIO(0x9888), 0x005cc000 }, + { _MMIO(0x9888), 0x065cc000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x0a5cc000 }, + { _MMIO(0x9888), 0x0c5cc000 }, + { _MMIO(0x9888), 0x0e5cc000 }, + { _MMIO(0x9888), 0x025c4000 }, + { _MMIO(0x9888), 0x045c8000 }, + { _MMIO(0x9888), 0x003d0000 }, + { _MMIO(0x9888), 0x063d00b0 }, + { _MMIO(0x9888), 0x083d0182 }, + { _MMIO(0x9888), 0x0a3d10a0 }, + { _MMIO(0x9888), 0x0c3d11a2 }, + { _MMIO(0x9888), 0x0e3d0000 }, + { _MMIO(0x9888), 0x183d0000 }, + { _MMIO(0x9888), 0x1a3d0000 }, + { _MMIO(0x9888), 0x0e582242 }, + { _MMIO(0x9888), 0x00586700 }, + { _MMIO(0x9888), 0x0258004f }, + { _MMIO(0x9888), 0x0658c000 }, + { _MMIO(0x9888), 0x0858c000 }, + { _MMIO(0x9888), 0x0a58c000 }, + { _MMIO(0x9888), 0x0c58c000 }, + { _MMIO(0x9888), 0x045b6300 }, + { _MMIO(0x9888), 0x105b0000 }, + { _MMIO(0x9888), 0x005b4000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x1a5b0155 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x0a5b0000 }, + { _MMIO(0x9888), 0x0c5b4000 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1faaa0 }, + { _MMIO(0x9888), 0x101f02aa }, + { _MMIO(0x9888), 0x00384000 }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18381555 }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x04384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0c384000 }, + { _MMIO(0x9888), 0x0039a000 }, + { _MMIO(0x9888), 0x0639a000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x02392000 }, + { _MMIO(0x9888), 0x04398000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8aaaa0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x038b6300 }, + { _MMIO(0x9888), 0x058b0062 }, + { _MMIO(0x9888), 0x118b0000 }, + { _MMIO(0x9888), 0x238b02a0 }, + { _MMIO(0x9888), 0x258b5555 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d801000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800001 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800041 }, +}; + +static int +get_data_port_reads_coalescing_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) { + regs[n] = mux_config_data_port_reads_coalescing_0_subslices_0x01; + lens[n] = ARRAY_SIZE(mux_config_data_port_reads_coalescing_0_subslices_0x01); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_data_port_writes_coalescing[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0xba98ba98 }, + { _MMIO(0x2748), 0xba98ba98 }, + { _MMIO(0x2744), 0x00003377 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ff72 }, + { _MMIO(0x2774), 0x0000bfd0 }, + { _MMIO(0x2778), 0x0007ff62 }, + { _MMIO(0x277c), 0x0000bfd0 }, + { _MMIO(0x2780), 0x0007ff42 }, + { _MMIO(0x2784), 0x0000bfd0 }, + { _MMIO(0x2788), 0x0007ff02 }, + { _MMIO(0x278c), 0x0000bfd0 }, + { _MMIO(0x2790), 0x0005fff2 }, + { _MMIO(0x2794), 0x0000bfd0 }, + { _MMIO(0x2798), 0x0005ffe2 }, + { _MMIO(0x279c), 0x0000bfd0 }, + { _MMIO(0x27a0), 0x0005ffc2 }, + { _MMIO(0x27a4), 0x0000bfd0 }, + { _MMIO(0x27a8), 0x0005ff82 }, + { _MMIO(0x27ac), 0x0000bfd0 }, +}; + +static const struct i915_oa_reg flex_eu_config_data_port_writes_coalescing[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_data_port_writes_coalescing_0_subslices_0x01[] = { + { _MMIO(0x9888), 0x103d0005 }, + { _MMIO(0x9888), 0x143d0120 }, + { _MMIO(0x9888), 0x163d2400 }, + { _MMIO(0x9888), 0x1058022f }, + { _MMIO(0x9888), 0x105b0000 }, + { _MMIO(0x9888), 0x198b0003 }, + { _MMIO(0x9888), 0x005cc000 }, + { _MMIO(0x9888), 0x065cc000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x0a5cc000 }, + { _MMIO(0x9888), 0x0e5cc000 }, + { _MMIO(0x9888), 0x025c4000 }, + { _MMIO(0x9888), 0x045c8000 }, + { _MMIO(0x9888), 0x003d0000 }, + { _MMIO(0x9888), 0x063d0094 }, + { _MMIO(0x9888), 0x083d0182 }, + { _MMIO(0x9888), 0x0a3d1814 }, + { _MMIO(0x9888), 0x0e3d0000 }, + { _MMIO(0x9888), 0x183d0000 }, + { _MMIO(0x9888), 0x1a3d0000 }, + { _MMIO(0x9888), 0x0c3d0000 }, + { _MMIO(0x9888), 0x0e582242 }, + { _MMIO(0x9888), 0x00586700 }, + { _MMIO(0x9888), 0x0258004f }, + { _MMIO(0x9888), 0x0658c000 }, + { _MMIO(0x9888), 0x0858c000 }, + { _MMIO(0x9888), 0x0a58c000 }, + { _MMIO(0x9888), 0x045b6a80 }, + { _MMIO(0x9888), 0x005b4000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x185b5400 }, + { _MMIO(0x9888), 0x1a5b0141 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x0a5b0000 }, + { _MMIO(0x9888), 0x0c5b4000 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1faaa0 }, + { _MMIO(0x9888), 0x101f0282 }, + { _MMIO(0x9888), 0x00384000 }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18381415 }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x04384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0c384000 }, + { _MMIO(0x9888), 0x0039a000 }, + { _MMIO(0x9888), 0x0639a000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x02392000 }, + { _MMIO(0x9888), 0x04398000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8a82a0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x038b6300 }, + { _MMIO(0x9888), 0x058b0062 }, + { _MMIO(0x9888), 0x118b0000 }, + { _MMIO(0x9888), 0x238b02a0 }, + { _MMIO(0x9888), 0x258b1555 }, + { _MMIO(0x9888), 0x278b0014 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x21852aaa }, + { _MMIO(0x9888), 0x23850028 }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830141 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0xd24), 0x00000000 }, + { _MMIO(0x9888), 0x4d801000 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f800001 }, + { _MMIO(0x9888), 0x43800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800420 }, + { _MMIO(0x9888), 0x3f800421 }, + { _MMIO(0x9888), 0x41800041 }, +}; + +static int +get_data_port_writes_coalescing_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) { + regs[n] = mux_config_data_port_writes_coalescing_0_subslices_0x01; + lens[n] = ARRAY_SIZE(mux_config_data_port_writes_coalescing_0_subslices_0x01); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fff7 }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x105c0232 }, + { _MMIO(0x9888), 0x10580232 }, + { _MMIO(0x9888), 0x10380232 }, + { _MMIO(0x9888), 0x10dc0232 }, + { _MMIO(0x9888), 0x10d80232 }, + { _MMIO(0x9888), 0x10b80232 }, + { _MMIO(0x9888), 0x118e4400 }, + { _MMIO(0x9888), 0x025c6080 }, + { _MMIO(0x9888), 0x045c004b }, + { _MMIO(0x9888), 0x005c8000 }, + { _MMIO(0x9888), 0x00582080 }, + { _MMIO(0x9888), 0x0258004b }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00aa }, + { _MMIO(0x9888), 0x04386080 }, + { _MMIO(0x9888), 0x0638404b }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a380000 }, + { _MMIO(0x9888), 0x0c380000 }, + { _MMIO(0x9888), 0x00398000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x0cdc25c1 }, + { _MMIO(0x9888), 0x0adcc000 }, + { _MMIO(0x9888), 0x0ad825c1 }, + { _MMIO(0x9888), 0x18db4000 }, + { _MMIO(0x9888), 0x1adb0001 }, + { _MMIO(0x9888), 0x0e9f8000 }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x0eb825c1 }, + { _MMIO(0x9888), 0x18b80154 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x0d88c000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x258baa05 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x198c5400 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x098dc000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x098e05c0 }, + { _MMIO(0x9888), 0x058e0000 }, + { _MMIO(0x9888), 0x198f0020 }, + { _MMIO(0x9888), 0x2185aa0a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x19835000 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x19808000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x51800040 }, + { _MMIO(0x9888), 0x43800400 }, + { _MMIO(0x9888), 0x45800800 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800c62 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f801042 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x418014a4 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x10bf03da }, + { _MMIO(0x9888), 0x14bf0001 }, + { _MMIO(0x9888), 0x12980340 }, + { _MMIO(0x9888), 0x12990340 }, + { _MMIO(0x9888), 0x0cbf1187 }, + { _MMIO(0x9888), 0x0ebf1205 }, + { _MMIO(0x9888), 0x00bf0500 }, + { _MMIO(0x9888), 0x02bf042b }, + { _MMIO(0x9888), 0x04bf002c }, + { _MMIO(0x9888), 0x0cdac000 }, + { _MMIO(0x9888), 0x0edac000 }, + { _MMIO(0x9888), 0x00da8000 }, + { _MMIO(0x9888), 0x02dac000 }, + { _MMIO(0x9888), 0x04da4000 }, + { _MMIO(0x9888), 0x04983400 }, + { _MMIO(0x9888), 0x10980000 }, + { _MMIO(0x9888), 0x06990034 }, + { _MMIO(0x9888), 0x10990000 }, + { _MMIO(0x9888), 0x0c9dc000 }, + { _MMIO(0x9888), 0x0e9dc000 }, + { _MMIO(0x9888), 0x009d8000 }, + { _MMIO(0x9888), 0x029dc000 }, + { _MMIO(0x9888), 0x049d4000 }, + { _MMIO(0x9888), 0x109f02a8 }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0e9f00ba }, + { _MMIO(0x9888), 0x0cb88000 }, + { _MMIO(0x9888), 0x0cb95000 }, + { _MMIO(0x9888), 0x0eb95000 }, + { _MMIO(0x9888), 0x00b94000 }, + { _MMIO(0x9888), 0x02b95000 }, + { _MMIO(0x9888), 0x04b91000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x0cba4000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x258b800a }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b5500 }, + { _MMIO(0x9888), 0x198c4000 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x47800000 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800060 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_2[] = { + { _MMIO(0x9888), 0x103f03da }, + { _MMIO(0x9888), 0x143f0001 }, + { _MMIO(0x9888), 0x12180340 }, + { _MMIO(0x9888), 0x12190340 }, + { _MMIO(0x9888), 0x0c3f1187 }, + { _MMIO(0x9888), 0x0e3f1205 }, + { _MMIO(0x9888), 0x003f0500 }, + { _MMIO(0x9888), 0x023f042b }, + { _MMIO(0x9888), 0x043f002c }, + { _MMIO(0x9888), 0x0c5ac000 }, + { _MMIO(0x9888), 0x0e5ac000 }, + { _MMIO(0x9888), 0x005a8000 }, + { _MMIO(0x9888), 0x025ac000 }, + { _MMIO(0x9888), 0x045a4000 }, + { _MMIO(0x9888), 0x04183400 }, + { _MMIO(0x9888), 0x10180000 }, + { _MMIO(0x9888), 0x06190034 }, + { _MMIO(0x9888), 0x10190000 }, + { _MMIO(0x9888), 0x0c1dc000 }, + { _MMIO(0x9888), 0x0e1dc000 }, + { _MMIO(0x9888), 0x001d8000 }, + { _MMIO(0x9888), 0x021dc000 }, + { _MMIO(0x9888), 0x041d4000 }, + { _MMIO(0x9888), 0x101f02a8 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00ba }, + { _MMIO(0x9888), 0x0c388000 }, + { _MMIO(0x9888), 0x0c395000 }, + { _MMIO(0x9888), 0x0e395000 }, + { _MMIO(0x9888), 0x00394000 }, + { _MMIO(0x9888), 0x02395000 }, + { _MMIO(0x9888), 0x04391000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x0c3a4000 }, + { _MMIO(0x9888), 0x1b8aa800 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x258b4005 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x47800000 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800060 }, +}; + +static int +get_l3_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_2; + lens[n] = ARRAY_SIZE(mux_config_l3_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_3[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_3[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_3[] = { + { _MMIO(0x9888), 0x121b0340 }, + { _MMIO(0x9888), 0x103f0274 }, + { _MMIO(0x9888), 0x123f0000 }, + { _MMIO(0x9888), 0x129b0340 }, + { _MMIO(0x9888), 0x10bf0274 }, + { _MMIO(0x9888), 0x12bf0000 }, + { _MMIO(0x9888), 0x041b3400 }, + { _MMIO(0x9888), 0x101b0000 }, + { _MMIO(0x9888), 0x045c8000 }, + { _MMIO(0x9888), 0x0a3d4000 }, + { _MMIO(0x9888), 0x003f0080 }, + { _MMIO(0x9888), 0x023f0793 }, + { _MMIO(0x9888), 0x043f0014 }, + { _MMIO(0x9888), 0x04588000 }, + { _MMIO(0x9888), 0x005a8000 }, + { _MMIO(0x9888), 0x025ac000 }, + { _MMIO(0x9888), 0x045a4000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x001d8000 }, + { _MMIO(0x9888), 0x021dc000 }, + { _MMIO(0x9888), 0x041d4000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f002a }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x00394000 }, + { _MMIO(0x9888), 0x02395000 }, + { _MMIO(0x9888), 0x04399000 }, + { _MMIO(0x9888), 0x069b0034 }, + { _MMIO(0x9888), 0x109b0000 }, + { _MMIO(0x9888), 0x06dc4000 }, + { _MMIO(0x9888), 0x0cbd4000 }, + { _MMIO(0x9888), 0x0cbf0981 }, + { _MMIO(0x9888), 0x0ebf0a0f }, + { _MMIO(0x9888), 0x06d84000 }, + { _MMIO(0x9888), 0x0cdac000 }, + { _MMIO(0x9888), 0x0edac000 }, + { _MMIO(0x9888), 0x0cdb4000 }, + { _MMIO(0x9888), 0x0c9dc000 }, + { _MMIO(0x9888), 0x0e9dc000 }, + { _MMIO(0x9888), 0x109f02a8 }, + { _MMIO(0x9888), 0x0e9f0080 }, + { _MMIO(0x9888), 0x0cb84000 }, + { _MMIO(0x9888), 0x0cb95000 }, + { _MMIO(0x9888), 0x0eb95000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x258b8009 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x198c4000 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800c00 }, + { _MMIO(0x9888), 0x47800c63 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f8014a5 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800045 }, +}; + +static int +get_l3_3_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_3; + lens[n] = ARRAY_SIZE(mux_config_l3_3); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_4[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_4[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_4[] = { + { _MMIO(0x9888), 0x121a0340 }, + { _MMIO(0x9888), 0x103f0017 }, + { _MMIO(0x9888), 0x123f0020 }, + { _MMIO(0x9888), 0x129a0340 }, + { _MMIO(0x9888), 0x10bf0017 }, + { _MMIO(0x9888), 0x12bf0020 }, + { _MMIO(0x9888), 0x041a3400 }, + { _MMIO(0x9888), 0x101a0000 }, + { _MMIO(0x9888), 0x043b8000 }, + { _MMIO(0x9888), 0x0a3e0010 }, + { _MMIO(0x9888), 0x003f0200 }, + { _MMIO(0x9888), 0x023f0113 }, + { _MMIO(0x9888), 0x043f0014 }, + { _MMIO(0x9888), 0x02592000 }, + { _MMIO(0x9888), 0x005a8000 }, + { _MMIO(0x9888), 0x025ac000 }, + { _MMIO(0x9888), 0x045a4000 }, + { _MMIO(0x9888), 0x0a1c8000 }, + { _MMIO(0x9888), 0x001d8000 }, + { _MMIO(0x9888), 0x021dc000 }, + { _MMIO(0x9888), 0x041d4000 }, + { _MMIO(0x9888), 0x0a1e8000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f001a }, + { _MMIO(0x9888), 0x00394000 }, + { _MMIO(0x9888), 0x02395000 }, + { _MMIO(0x9888), 0x04391000 }, + { _MMIO(0x9888), 0x069a0034 }, + { _MMIO(0x9888), 0x109a0000 }, + { _MMIO(0x9888), 0x06bb4000 }, + { _MMIO(0x9888), 0x0abe0040 }, + { _MMIO(0x9888), 0x0cbf0984 }, + { _MMIO(0x9888), 0x0ebf0a02 }, + { _MMIO(0x9888), 0x02d94000 }, + { _MMIO(0x9888), 0x0cdac000 }, + { _MMIO(0x9888), 0x0edac000 }, + { _MMIO(0x9888), 0x0c9c0400 }, + { _MMIO(0x9888), 0x0c9dc000 }, + { _MMIO(0x9888), 0x0e9dc000 }, + { _MMIO(0x9888), 0x0c9e0400 }, + { _MMIO(0x9888), 0x109f02a8 }, + { _MMIO(0x9888), 0x0e9f0040 }, + { _MMIO(0x9888), 0x0cb95000 }, + { _MMIO(0x9888), 0x0eb95000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x258b8009 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x198c4000 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800800 }, + { _MMIO(0x9888), 0x47800842 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f801084 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800044 }, +}; + +static int +get_l3_4_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_4; + lens[n] = ARRAY_SIZE(mux_config_l3_4); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00006000 }, + { _MMIO(0x2774), 0x0000f3ff }, + { _MMIO(0x2778), 0x00001800 }, + { _MMIO(0x277c), 0x0000fcff }, + { _MMIO(0x2780), 0x00000600 }, + { _MMIO(0x2784), 0x0000ff3f }, + { _MMIO(0x2788), 0x00000180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000060 }, + { _MMIO(0x2794), 0x0000fff3 }, + { _MMIO(0x2798), 0x00000018 }, + { _MMIO(0x279c), 0x0000fffc }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x143b000e }, + { _MMIO(0x9888), 0x043c55c0 }, + { _MMIO(0x9888), 0x0a1e0280 }, + { _MMIO(0x9888), 0x0c1e0408 }, + { _MMIO(0x9888), 0x10390000 }, + { _MMIO(0x9888), 0x12397a1f }, + { _MMIO(0x9888), 0x14bb000e }, + { _MMIO(0x9888), 0x04bc5000 }, + { _MMIO(0x9888), 0x0a9e0296 }, + { _MMIO(0x9888), 0x0c9e0008 }, + { _MMIO(0x9888), 0x10b90000 }, + { _MMIO(0x9888), 0x12b97a1f }, + { _MMIO(0x9888), 0x063b0042 }, + { _MMIO(0x9888), 0x103b0000 }, + { _MMIO(0x9888), 0x083c0000 }, + { _MMIO(0x9888), 0x0a3e0040 }, + { _MMIO(0x9888), 0x043f8000 }, + { _MMIO(0x9888), 0x02594000 }, + { _MMIO(0x9888), 0x045a8000 }, + { _MMIO(0x9888), 0x0c1c0400 }, + { _MMIO(0x9888), 0x041d8000 }, + { _MMIO(0x9888), 0x081e02c0 }, + { _MMIO(0x9888), 0x0e1e0000 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1f0260 }, + { _MMIO(0x9888), 0x101f0014 }, + { _MMIO(0x9888), 0x003905e0 }, + { _MMIO(0x9888), 0x06390bc0 }, + { _MMIO(0x9888), 0x02390018 }, + { _MMIO(0x9888), 0x04394000 }, + { _MMIO(0x9888), 0x04bb0042 }, + { _MMIO(0x9888), 0x10bb0000 }, + { _MMIO(0x9888), 0x02bc05c0 }, + { _MMIO(0x9888), 0x08bc0000 }, + { _MMIO(0x9888), 0x0abe0004 }, + { _MMIO(0x9888), 0x02bf8000 }, + { _MMIO(0x9888), 0x02d91000 }, + { _MMIO(0x9888), 0x02da8000 }, + { _MMIO(0x9888), 0x089c8000 }, + { _MMIO(0x9888), 0x029d8000 }, + { _MMIO(0x9888), 0x089e8000 }, + { _MMIO(0x9888), 0x0e9e0000 }, + { _MMIO(0x9888), 0x0e9fa806 }, + { _MMIO(0x9888), 0x109f0142 }, + { _MMIO(0x9888), 0x08b90617 }, + { _MMIO(0x9888), 0x0ab90be0 }, + { _MMIO(0x9888), 0x02b94000 }, + { _MMIO(0x9888), 0x0d88f000 }, + { _MMIO(0x9888), 0x0f88000c }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x1b8a2800 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x238b52a0 }, + { _MMIO(0x9888), 0x258b6a95 }, + { _MMIO(0x9888), 0x278b0029 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c1500 }, + { _MMIO(0x9888), 0x1b8c0014 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x038d8000 }, + { _MMIO(0x9888), 0x058d2000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x4d800444 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f804000 }, + { _MMIO(0x9888), 0x43801080 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800084 }, + { _MMIO(0x9888), 0x53800044 }, + { _MMIO(0x9888), 0x47801080 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800000 }, + { _MMIO(0x9888), 0x41800840 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler_1[] = { + { _MMIO(0x9888), 0x18921400 }, + { _MMIO(0x9888), 0x149500ab }, + { _MMIO(0x9888), 0x18b21400 }, + { _MMIO(0x9888), 0x14b500ab }, + { _MMIO(0x9888), 0x18d21400 }, + { _MMIO(0x9888), 0x14d500ab }, + { _MMIO(0x9888), 0x0cdc8000 }, + { _MMIO(0x9888), 0x0edc4000 }, + { _MMIO(0x9888), 0x02dcc000 }, + { _MMIO(0x9888), 0x04dcc000 }, + { _MMIO(0x9888), 0x1abd00a0 }, + { _MMIO(0x9888), 0x0abd8000 }, + { _MMIO(0x9888), 0x0cd88000 }, + { _MMIO(0x9888), 0x0ed84000 }, + { _MMIO(0x9888), 0x04d88000 }, + { _MMIO(0x9888), 0x1adb0050 }, + { _MMIO(0x9888), 0x04db8000 }, + { _MMIO(0x9888), 0x06db8000 }, + { _MMIO(0x9888), 0x08db8000 }, + { _MMIO(0x9888), 0x0adb4000 }, + { _MMIO(0x9888), 0x109f02a0 }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0e9f00aa }, + { _MMIO(0x9888), 0x18b82500 }, + { _MMIO(0x9888), 0x02b88000 }, + { _MMIO(0x9888), 0x04b84000 }, + { _MMIO(0x9888), 0x06b84000 }, + { _MMIO(0x9888), 0x08b84000 }, + { _MMIO(0x9888), 0x0ab84000 }, + { _MMIO(0x9888), 0x0cb88000 }, + { _MMIO(0x9888), 0x0cb98000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x00b98000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x04b9a000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x1aba0200 }, + { _MMIO(0x9888), 0x02ba8000 }, + { _MMIO(0x9888), 0x0cba8000 }, + { _MMIO(0x9888), 0x04908000 }, + { _MMIO(0x9888), 0x04918000 }, + { _MMIO(0x9888), 0x04927300 }, + { _MMIO(0x9888), 0x10920000 }, + { _MMIO(0x9888), 0x1893000a }, + { _MMIO(0x9888), 0x0a934000 }, + { _MMIO(0x9888), 0x0a946000 }, + { _MMIO(0x9888), 0x0c959000 }, + { _MMIO(0x9888), 0x0e950098 }, + { _MMIO(0x9888), 0x10950000 }, + { _MMIO(0x9888), 0x04b04000 }, + { _MMIO(0x9888), 0x04b14000 }, + { _MMIO(0x9888), 0x04b20073 }, + { _MMIO(0x9888), 0x10b20000 }, + { _MMIO(0x9888), 0x04b38000 }, + { _MMIO(0x9888), 0x06b38000 }, + { _MMIO(0x9888), 0x08b34000 }, + { _MMIO(0x9888), 0x04b4c000 }, + { _MMIO(0x9888), 0x02b59890 }, + { _MMIO(0x9888), 0x10b50000 }, + { _MMIO(0x9888), 0x06d04000 }, + { _MMIO(0x9888), 0x06d14000 }, + { _MMIO(0x9888), 0x06d20073 }, + { _MMIO(0x9888), 0x10d20000 }, + { _MMIO(0x9888), 0x18d30020 }, + { _MMIO(0x9888), 0x02d38000 }, + { _MMIO(0x9888), 0x0cd34000 }, + { _MMIO(0x9888), 0x0ad48000 }, + { _MMIO(0x9888), 0x04d42000 }, + { _MMIO(0x9888), 0x0ed59000 }, + { _MMIO(0x9888), 0x00d59800 }, + { _MMIO(0x9888), 0x10d50000 }, + { _MMIO(0x9888), 0x0f88000e }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b5500 }, + { _MMIO(0x9888), 0x258b000a }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8d8000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x2185000a }, + { _MMIO(0x9888), 0x1b830150 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d848000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d808000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47801021 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800c64 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800c02 }, +}; + +static int +get_sampler_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler_1; + lens[n] = ARRAY_SIZE(mux_config_sampler_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler_2[] = { + { _MMIO(0x9888), 0x18121400 }, + { _MMIO(0x9888), 0x141500ab }, + { _MMIO(0x9888), 0x18321400 }, + { _MMIO(0x9888), 0x143500ab }, + { _MMIO(0x9888), 0x18521400 }, + { _MMIO(0x9888), 0x145500ab }, + { _MMIO(0x9888), 0x0c5c8000 }, + { _MMIO(0x9888), 0x0e5c4000 }, + { _MMIO(0x9888), 0x025cc000 }, + { _MMIO(0x9888), 0x045cc000 }, + { _MMIO(0x9888), 0x1a3d00a0 }, + { _MMIO(0x9888), 0x0a3d8000 }, + { _MMIO(0x9888), 0x0c588000 }, + { _MMIO(0x9888), 0x0e584000 }, + { _MMIO(0x9888), 0x04588000 }, + { _MMIO(0x9888), 0x1a5b0050 }, + { _MMIO(0x9888), 0x045b8000 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b8000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x101f02a0 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00aa }, + { _MMIO(0x9888), 0x18382500 }, + { _MMIO(0x9888), 0x02388000 }, + { _MMIO(0x9888), 0x04384000 }, + { _MMIO(0x9888), 0x06384000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0c388000 }, + { _MMIO(0x9888), 0x0c398000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x00398000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x1a3a0200 }, + { _MMIO(0x9888), 0x023a8000 }, + { _MMIO(0x9888), 0x0c3a8000 }, + { _MMIO(0x9888), 0x04108000 }, + { _MMIO(0x9888), 0x04118000 }, + { _MMIO(0x9888), 0x04127300 }, + { _MMIO(0x9888), 0x10120000 }, + { _MMIO(0x9888), 0x1813000a }, + { _MMIO(0x9888), 0x0a134000 }, + { _MMIO(0x9888), 0x0a146000 }, + { _MMIO(0x9888), 0x0c159000 }, + { _MMIO(0x9888), 0x0e150098 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x04304000 }, + { _MMIO(0x9888), 0x04314000 }, + { _MMIO(0x9888), 0x04320073 }, + { _MMIO(0x9888), 0x10320000 }, + { _MMIO(0x9888), 0x04338000 }, + { _MMIO(0x9888), 0x06338000 }, + { _MMIO(0x9888), 0x08334000 }, + { _MMIO(0x9888), 0x0434c000 }, + { _MMIO(0x9888), 0x02359890 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x06504000 }, + { _MMIO(0x9888), 0x06514000 }, + { _MMIO(0x9888), 0x06520073 }, + { _MMIO(0x9888), 0x10520000 }, + { _MMIO(0x9888), 0x18530020 }, + { _MMIO(0x9888), 0x02538000 }, + { _MMIO(0x9888), 0x0c534000 }, + { _MMIO(0x9888), 0x0a548000 }, + { _MMIO(0x9888), 0x04542000 }, + { _MMIO(0x9888), 0x0e559000 }, + { _MMIO(0x9888), 0x00559800 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x1b8aa000 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x258b0005 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x2185000a }, + { _MMIO(0x9888), 0x1b830150 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d848000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d808000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47801021 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800c64 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800c02 }, +}; + +static int +get_sampler_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler_2; + lens[n] = ARRAY_SIZE(mux_config_sampler_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x0000fe7f }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000ffbf }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fff7 }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fff9 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x16154d60 }, + { _MMIO(0x9888), 0x16352e60 }, + { _MMIO(0x9888), 0x16554d60 }, + { _MMIO(0x9888), 0x16950000 }, + { _MMIO(0x9888), 0x16b50000 }, + { _MMIO(0x9888), 0x16d50000 }, + { _MMIO(0x9888), 0x005c8000 }, + { _MMIO(0x9888), 0x045cc000 }, + { _MMIO(0x9888), 0x065c4000 }, + { _MMIO(0x9888), 0x083d8000 }, + { _MMIO(0x9888), 0x0a3d8000 }, + { _MMIO(0x9888), 0x0458c000 }, + { _MMIO(0x9888), 0x025b8000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x0c5b8000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00aa }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x04388000 }, + { _MMIO(0x9888), 0x06388000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0c384000 }, + { _MMIO(0x9888), 0x00398000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x043a8000 }, + { _MMIO(0x9888), 0x063a8000 }, + { _MMIO(0x9888), 0x08138000 }, + { _MMIO(0x9888), 0x0a138000 }, + { _MMIO(0x9888), 0x06143000 }, + { _MMIO(0x9888), 0x0415cfc7 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x02338000 }, + { _MMIO(0x9888), 0x0c338000 }, + { _MMIO(0x9888), 0x04342000 }, + { _MMIO(0x9888), 0x06344000 }, + { _MMIO(0x9888), 0x0035c700 }, + { _MMIO(0x9888), 0x063500cf }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x04538000 }, + { _MMIO(0x9888), 0x06538000 }, + { _MMIO(0x9888), 0x0454c000 }, + { _MMIO(0x9888), 0x0255cfc7 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x06dc8000 }, + { _MMIO(0x9888), 0x08dc4000 }, + { _MMIO(0x9888), 0x0cdcc000 }, + { _MMIO(0x9888), 0x0edcc000 }, + { _MMIO(0x9888), 0x1abd00a8 }, + { _MMIO(0x9888), 0x0cd8c000 }, + { _MMIO(0x9888), 0x0ed84000 }, + { _MMIO(0x9888), 0x0edb8000 }, + { _MMIO(0x9888), 0x18db0800 }, + { _MMIO(0x9888), 0x1adb0254 }, + { _MMIO(0x9888), 0x0e9faa00 }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x0eb84000 }, + { _MMIO(0x9888), 0x16b84000 }, + { _MMIO(0x9888), 0x18b8156a }, + { _MMIO(0x9888), 0x06b98000 }, + { _MMIO(0x9888), 0x08b9a000 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x18baa000 }, + { _MMIO(0x9888), 0x1aba0002 }, + { _MMIO(0x9888), 0x16934000 }, + { _MMIO(0x9888), 0x1893000a }, + { _MMIO(0x9888), 0x0a947000 }, + { _MMIO(0x9888), 0x0c95c5c1 }, + { _MMIO(0x9888), 0x0e9500c3 }, + { _MMIO(0x9888), 0x10950000 }, + { _MMIO(0x9888), 0x0eb38000 }, + { _MMIO(0x9888), 0x16b30040 }, + { _MMIO(0x9888), 0x18b30020 }, + { _MMIO(0x9888), 0x06b48000 }, + { _MMIO(0x9888), 0x08b41000 }, + { _MMIO(0x9888), 0x0ab48000 }, + { _MMIO(0x9888), 0x06b5c500 }, + { _MMIO(0x9888), 0x08b500c3 }, + { _MMIO(0x9888), 0x0eb5c100 }, + { _MMIO(0x9888), 0x10b50000 }, + { _MMIO(0x9888), 0x16d31500 }, + { _MMIO(0x9888), 0x08d4e000 }, + { _MMIO(0x9888), 0x08d5c100 }, + { _MMIO(0x9888), 0x0ad5c3c5 }, + { _MMIO(0x9888), 0x10d50000 }, + { _MMIO(0x9888), 0x0d88f800 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x258baaa5 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x0f8c4000 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c5500 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x078d8000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800c42 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800063 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800800 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f8014a4 }, + { _MMIO(0x9888), 0x41801042 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x0000fe7f }, + { _MMIO(0x2780), 0x00000000 }, + { _MMIO(0x2784), 0x0000ff9f }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000ffe7 }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fffb }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000fffd }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x16150000 }, + { _MMIO(0x9888), 0x16350000 }, + { _MMIO(0x9888), 0x16550000 }, + { _MMIO(0x9888), 0x16952e60 }, + { _MMIO(0x9888), 0x16b54d60 }, + { _MMIO(0x9888), 0x16d52e60 }, + { _MMIO(0x9888), 0x065c8000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x0a5cc000 }, + { _MMIO(0x9888), 0x0c5c4000 }, + { _MMIO(0x9888), 0x0e3d8000 }, + { _MMIO(0x9888), 0x183da000 }, + { _MMIO(0x9888), 0x06588000 }, + { _MMIO(0x9888), 0x08588000 }, + { _MMIO(0x9888), 0x0a584000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x185b5800 }, + { _MMIO(0x9888), 0x1a5b000a }, + { _MMIO(0x9888), 0x0e1faa00 }, + { _MMIO(0x9888), 0x101f02aa }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18382a55 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x1a3a02a0 }, + { _MMIO(0x9888), 0x0e138000 }, + { _MMIO(0x9888), 0x16130500 }, + { _MMIO(0x9888), 0x06148000 }, + { _MMIO(0x9888), 0x08146000 }, + { _MMIO(0x9888), 0x0615c100 }, + { _MMIO(0x9888), 0x0815c500 }, + { _MMIO(0x9888), 0x0a1500c3 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x16335040 }, + { _MMIO(0x9888), 0x08349000 }, + { _MMIO(0x9888), 0x0a341000 }, + { _MMIO(0x9888), 0x083500c1 }, + { _MMIO(0x9888), 0x0a35c500 }, + { _MMIO(0x9888), 0x0c3500c3 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x1853002a }, + { _MMIO(0x9888), 0x0a54e000 }, + { _MMIO(0x9888), 0x0c55c500 }, + { _MMIO(0x9888), 0x0e55c1c3 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x00dc8000 }, + { _MMIO(0x9888), 0x02dcc000 }, + { _MMIO(0x9888), 0x04dc4000 }, + { _MMIO(0x9888), 0x04bd8000 }, + { _MMIO(0x9888), 0x06bd8000 }, + { _MMIO(0x9888), 0x02d8c000 }, + { _MMIO(0x9888), 0x02db8000 }, + { _MMIO(0x9888), 0x04db4000 }, + { _MMIO(0x9888), 0x06db4000 }, + { _MMIO(0x9888), 0x08db8000 }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0e9f00aa }, + { _MMIO(0x9888), 0x02b84000 }, + { _MMIO(0x9888), 0x04b84000 }, + { _MMIO(0x9888), 0x06b84000 }, + { _MMIO(0x9888), 0x08b84000 }, + { _MMIO(0x9888), 0x0ab88000 }, + { _MMIO(0x9888), 0x0cb88000 }, + { _MMIO(0x9888), 0x00b98000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x04b9a000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x0aba8000 }, + { _MMIO(0x9888), 0x0cba8000 }, + { _MMIO(0x9888), 0x04938000 }, + { _MMIO(0x9888), 0x06938000 }, + { _MMIO(0x9888), 0x0494c000 }, + { _MMIO(0x9888), 0x0295cfc7 }, + { _MMIO(0x9888), 0x10950000 }, + { _MMIO(0x9888), 0x02b38000 }, + { _MMIO(0x9888), 0x08b38000 }, + { _MMIO(0x9888), 0x04b42000 }, + { _MMIO(0x9888), 0x06b41000 }, + { _MMIO(0x9888), 0x00b5c700 }, + { _MMIO(0x9888), 0x04b500cf }, + { _MMIO(0x9888), 0x10b50000 }, + { _MMIO(0x9888), 0x0ad38000 }, + { _MMIO(0x9888), 0x0cd38000 }, + { _MMIO(0x9888), 0x06d46000 }, + { _MMIO(0x9888), 0x04d5c700 }, + { _MMIO(0x9888), 0x06d500cf }, + { _MMIO(0x9888), 0x10d50000 }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8aaaa0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x258b555a }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x238b5500 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800882 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45801082 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x478014a5 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800002 }, + { _MMIO(0x9888), 0x41800c62 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { + { _MMIO(0xe458), 0x00001000 }, + { _MMIO(0xe558), 0x00003002 }, + { _MMIO(0xe658), 0x00005004 }, + { _MMIO(0xe758), 0x00011010 }, + { _MMIO(0xe45c), 0x00050012 }, + { _MMIO(0xe55c), 0x00052051 }, + { _MMIO(0xe65c), 0x00000008 }, +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x161503e0 }, + { _MMIO(0x9888), 0x163503e0 }, + { _MMIO(0x9888), 0x165503e0 }, + { _MMIO(0x9888), 0x169503e0 }, + { _MMIO(0x9888), 0x16b503e0 }, + { _MMIO(0x9888), 0x16d503e0 }, + { _MMIO(0x9888), 0x045cc000 }, + { _MMIO(0x9888), 0x083d8000 }, + { _MMIO(0x9888), 0x04584000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5b8000 }, + { _MMIO(0x9888), 0x0e1f00a8 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0c388000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x0c3a8000 }, + { _MMIO(0x9888), 0x08138000 }, + { _MMIO(0x9888), 0x06141000 }, + { _MMIO(0x9888), 0x041500c3 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x0a338000 }, + { _MMIO(0x9888), 0x06342000 }, + { _MMIO(0x9888), 0x0435c300 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x0c538000 }, + { _MMIO(0x9888), 0x06544000 }, + { _MMIO(0x9888), 0x065500c3 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x00dc8000 }, + { _MMIO(0x9888), 0x02dc4000 }, + { _MMIO(0x9888), 0x02bd8000 }, + { _MMIO(0x9888), 0x00d88000 }, + { _MMIO(0x9888), 0x02db4000 }, + { _MMIO(0x9888), 0x04db8000 }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0e9f0002 }, + { _MMIO(0x9888), 0x02b84000 }, + { _MMIO(0x9888), 0x04b84000 }, + { _MMIO(0x9888), 0x06b88000 }, + { _MMIO(0x9888), 0x00b98000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x06ba8000 }, + { _MMIO(0x9888), 0x02938000 }, + { _MMIO(0x9888), 0x04942000 }, + { _MMIO(0x9888), 0x0095c300 }, + { _MMIO(0x9888), 0x10950000 }, + { _MMIO(0x9888), 0x04b38000 }, + { _MMIO(0x9888), 0x04b44000 }, + { _MMIO(0x9888), 0x02b500c3 }, + { _MMIO(0x9888), 0x10b50000 }, + { _MMIO(0x9888), 0x06d38000 }, + { _MMIO(0x9888), 0x04d48000 }, + { _MMIO(0x9888), 0x02d5c300 }, + { _MMIO(0x9888), 0x10d50000 }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x238b3500 }, + { _MMIO(0x9888), 0x258b0005 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x2185000a }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800c40 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41801482 }, + { _MMIO(0x9888), 0x31800000 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_vme_pipe[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00100030 }, + { _MMIO(0x2774), 0x0000fff9 }, + { _MMIO(0x2778), 0x00000002 }, + { _MMIO(0x277c), 0x0000fffc }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000fff3 }, + { _MMIO(0x2788), 0x00100180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000ff3f }, +}; + +static const struct i915_oa_reg flex_eu_config_vme_pipe[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00008003 }, +}; + +static const struct i915_oa_reg mux_config_vme_pipe[] = { + { _MMIO(0x9888), 0x14100812 }, + { _MMIO(0x9888), 0x14125800 }, + { _MMIO(0x9888), 0x161200c0 }, + { _MMIO(0x9888), 0x14300812 }, + { _MMIO(0x9888), 0x14325800 }, + { _MMIO(0x9888), 0x163200c0 }, + { _MMIO(0x9888), 0x005c4000 }, + { _MMIO(0x9888), 0x065c8000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x0a5cc000 }, + { _MMIO(0x9888), 0x0c5cc000 }, + { _MMIO(0x9888), 0x003d8000 }, + { _MMIO(0x9888), 0x0e3d8000 }, + { _MMIO(0x9888), 0x183d2800 }, + { _MMIO(0x9888), 0x00584000 }, + { _MMIO(0x9888), 0x06588000 }, + { _MMIO(0x9888), 0x0858c000 }, + { _MMIO(0x9888), 0x005b4000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x185b9400 }, + { _MMIO(0x9888), 0x1a5b002a }, + { _MMIO(0x9888), 0x0c1f0800 }, + { _MMIO(0x9888), 0x0e1faa00 }, + { _MMIO(0x9888), 0x101f002a }, + { _MMIO(0x9888), 0x00384000 }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18380155 }, + { _MMIO(0x9888), 0x00392000 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x00100047 }, + { _MMIO(0x9888), 0x06101a80 }, + { _MMIO(0x9888), 0x10100000 }, + { _MMIO(0x9888), 0x0810c000 }, + { _MMIO(0x9888), 0x0811c000 }, + { _MMIO(0x9888), 0x08126151 }, + { _MMIO(0x9888), 0x10120000 }, + { _MMIO(0x9888), 0x00134000 }, + { _MMIO(0x9888), 0x0e134000 }, + { _MMIO(0x9888), 0x161300a0 }, + { _MMIO(0x9888), 0x0a301ac7 }, + { _MMIO(0x9888), 0x10300000 }, + { _MMIO(0x9888), 0x0c30c000 }, + { _MMIO(0x9888), 0x0c31c000 }, + { _MMIO(0x9888), 0x0c326151 }, + { _MMIO(0x9888), 0x10320000 }, + { _MMIO(0x9888), 0x16332a00 }, + { _MMIO(0x9888), 0x18330001 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8a2aa0 }, + { _MMIO(0x9888), 0x238b0020 }, + { _MMIO(0x9888), 0x258b5550 }, + { _MMIO(0x9888), 0x278b0001 }, + { _MMIO(0x9888), 0x1f850080 }, + { _MMIO(0x9888), 0x2185aaa0 }, + { _MMIO(0x9888), 0x23850002 }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830015 }, + { _MMIO(0x9888), 0x01844000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x11804000 }, + { _MMIO(0x9888), 0x17808000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3d800800 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800002 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800884 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800002 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, +}; + +static int +get_vme_pipe_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_vme_pipe; + lens[n] = ARRAY_SIZE(mux_config_vme_pipe); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x198b0000 }, + { _MMIO(0x9888), 0x078b0066 }, + { _MMIO(0x9888), 0x118b0000 }, + { _MMIO(0x9888), 0x258b0000 }, + { _MMIO(0x9888), 0x21850008 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800000 }, + { _MMIO(0x9888), 0x31800000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_bdw(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_DATA_PORT_READS_COALESCING: + dev_priv->perf.oa.n_mux_configs = + get_data_port_reads_coalescing_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"DATA_PORT_READS_COALESCING\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_data_port_reads_coalescing; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_data_port_reads_coalescing); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_data_port_reads_coalescing; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_data_port_reads_coalescing); + + return 0; + case METRIC_SET_ID_DATA_PORT_WRITES_COALESCING: + dev_priv->perf.oa.n_mux_configs = + get_data_port_writes_coalescing_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"DATA_PORT_WRITES_COALESCING\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_data_port_writes_coalescing; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_data_port_writes_coalescing); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_data_port_writes_coalescing; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_data_port_writes_coalescing); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_L3_2: + dev_priv->perf.oa.n_mux_configs = + get_l3_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_2); + + return 0; + case METRIC_SET_ID_L3_3: + dev_priv->perf.oa.n_mux_configs = + get_l3_3_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_3; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_3); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_3; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_3); + + return 0; + case METRIC_SET_ID_L3_4: + dev_priv->perf.oa.n_mux_configs = + get_l3_4_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_4\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_4; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_4); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_4; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_4); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER_1: + dev_priv->perf.oa.n_mux_configs = + get_sampler_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler_1); + + return 0; + case METRIC_SET_ID_SAMPLER_2: + dev_priv->perf.oa.n_mux_configs = + get_sampler_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler_2); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_VME_PIPE: + dev_priv->perf.oa.n_mux_configs = + get_vme_pipe_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_vme_pipe; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_vme_pipe); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_vme_pipe; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_vme_pipe); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "b541bd57-0e0f-4154-b4c0-5858010a2bf7", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "35fbc9b2-a891-40a6-a38d-022bb7057552", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "233d0544-fff7-4281-8291-e02f222aff72", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "2b255d48-2117-4fef-a8f7-f151e1d25a2c", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "f7fd3220-b466-4a4d-9f98-b0caf3f2394c", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "e99ccaca-821c-4df9-97a7-96bdb7204e43", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "27a364dc-8225-4ecb-b607-d6f1925598d9", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_data_port_reads_coalescing_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_DATA_PORT_READS_COALESCING); +} + +static struct device_attribute dev_attr_data_port_reads_coalescing_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_data_port_reads_coalescing_id, + .store = NULL, +}; + +static struct attribute *attrs_data_port_reads_coalescing[] = { + &dev_attr_data_port_reads_coalescing_id.attr, + NULL, +}; + +static struct attribute_group group_data_port_reads_coalescing = { + .name = "857fc630-2f09-4804-85f1-084adfadd5ab", + .attrs = attrs_data_port_reads_coalescing, +}; + +static ssize_t +show_data_port_writes_coalescing_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_DATA_PORT_WRITES_COALESCING); +} + +static struct device_attribute dev_attr_data_port_writes_coalescing_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_data_port_writes_coalescing_id, + .store = NULL, +}; + +static struct attribute *attrs_data_port_writes_coalescing[] = { + &dev_attr_data_port_writes_coalescing_id.attr, + NULL, +}; + +static struct attribute_group group_data_port_writes_coalescing = { + .name = "343ebc99-4a55-414c-8c17-d8e259cf5e20", + .attrs = attrs_data_port_writes_coalescing, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "7bdafd88-a4fa-4ed5-bc09-1a977aa5be3e", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "9385ebb2-f34f-4aa5-aec5-7e9cbbea0f0b", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2); +} + +static struct device_attribute dev_attr_l3_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_2_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_2[] = { + &dev_attr_l3_2_id.attr, + NULL, +}; + +static struct attribute_group group_l3_2 = { + .name = "446ae59b-ff2e-41c9-b49e-0184a54bf00a", + .attrs = attrs_l3_2, +}; + +static ssize_t +show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3); +} + +static struct device_attribute dev_attr_l3_3_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_3_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_3[] = { + &dev_attr_l3_3_id.attr, + NULL, +}; + +static struct attribute_group group_l3_3 = { + .name = "84a7956f-1ea4-4d0d-837f-e39a0376e38c", + .attrs = attrs_l3_3, +}; + +static ssize_t +show_l3_4_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_4); +} + +static struct device_attribute dev_attr_l3_4_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_4_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_4[] = { + &dev_attr_l3_4_id.attr, + NULL, +}; + +static struct attribute_group group_l3_4 = { + .name = "92b493d9-df18-4bed-be06-5cac6f2a6f5f", + .attrs = attrs_l3_4, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "14345c35-cc46-40d0-bb04-6ed1fbb43679", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_1); +} + +static struct device_attribute dev_attr_sampler_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_1_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler_1[] = { + &dev_attr_sampler_1_id.attr, + NULL, +}; + +static struct attribute_group group_sampler_1 = { + .name = "f0c6ba37-d3d3-4211-91b5-226730312a54", + .attrs = attrs_sampler_1, +}; + +static ssize_t +show_sampler_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_2); +} + +static struct device_attribute dev_attr_sampler_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_2_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler_2[] = { + &dev_attr_sampler_2_id.attr, + NULL, +}; + +static struct attribute_group group_sampler_2 = { + .name = "30bf3702-48cf-4bca-b412-7cf50bb2f564", + .attrs = attrs_sampler_2, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "238bec85-df05-44f3-b905-d166712f2451", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "24bf02cd-8693-4583-981c-c4165b33da01", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "8fb61ba2-2fbb-454c-a136-2dec5a8a595e", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE); +} + +static struct device_attribute dev_attr_vme_pipe_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_vme_pipe_id, + .store = NULL, +}; + +static struct attribute *attrs_vme_pipe[] = { + &dev_attr_vme_pipe_id.attr, + NULL, +}; + +static struct attribute_group group_vme_pipe = { + .name = "e1743ca0-7fc8-410b-a066-de7bbb9280b7", + .attrs = attrs_vme_pipe, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "d6de6f55-e526-4f79-a6a6-d7315c09044e", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_bdw(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing); + if (ret) + goto error_data_port_reads_coalescing; + } + if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing); + if (ret) + goto error_data_port_writes_coalescing; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (ret) + goto error_l3_2; + } + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (ret) + goto error_l3_3; + } + if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_4); + if (ret) + goto error_l3_4; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_1); + if (ret) + goto error_sampler_1; + } + if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_2); + if (ret) + goto error_sampler_2; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (ret) + goto error_vme_pipe; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); +error_vme_pipe: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2); +error_sampler_2: + if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1); +error_sampler_1: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4); +error_l3_4: + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); +error_l3_3: + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); +error_l3_2: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing); +error_data_port_writes_coalescing: + if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing); +error_data_port_reads_coalescing: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_bdw(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing); + if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1); + if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.h b/drivers/gpu/drm/i915/i915_oa_bdw.h new file mode 100644 index 0000000..6363ff9 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_bdw.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_BDW_H__ +#define __I915_OA_BDW_H__ + +extern int i915_oa_n_builtin_metric_sets_bdw; + +extern int i915_oa_select_metric_set_bdw(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_bdw(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_bdw(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.c b/drivers/gpu/drm/i915/i915_oa_bxt.c new file mode 100644 index 0000000..93864d8 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_bxt.c @@ -0,0 +1,2690 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_bxt.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_bxt = 15; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic_0_sku_gte_0x03[] = { + { _MMIO(0x9888), 0x166c00f0 }, + { _MMIO(0x9888), 0x12120280 }, + { _MMIO(0x9888), 0x12320280 }, + { _MMIO(0x9888), 0x11930317 }, + { _MMIO(0x9888), 0x159303df }, + { _MMIO(0x9888), 0x3f900c00 }, + { _MMIO(0x9888), 0x419000a0 }, + { _MMIO(0x9888), 0x002d1000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d5000 }, + { _MMIO(0x9888), 0x0a2d1000 }, + { _MMIO(0x9888), 0x0c2e0800 }, + { _MMIO(0x9888), 0x0e2e5900 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4c8000 }, + { _MMIO(0x9888), 0x0e4c4000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e2000 }, + { _MMIO(0x9888), 0x1c4f0010 }, + { _MMIO(0x9888), 0x0a6c0053 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1a0fcc00 }, + { _MMIO(0x9888), 0x1c0f0002 }, + { _MMIO(0x9888), 0x1c2c0040 }, + { _MMIO(0x9888), 0x00101000 }, + { _MMIO(0x9888), 0x04101000 }, + { _MMIO(0x9888), 0x00114000 }, + { _MMIO(0x9888), 0x08114000 }, + { _MMIO(0x9888), 0x00120020 }, + { _MMIO(0x9888), 0x08120021 }, + { _MMIO(0x9888), 0x00141000 }, + { _MMIO(0x9888), 0x08141000 }, + { _MMIO(0x9888), 0x02308000 }, + { _MMIO(0x9888), 0x04302000 }, + { _MMIO(0x9888), 0x06318000 }, + { _MMIO(0x9888), 0x08318000 }, + { _MMIO(0x9888), 0x06320800 }, + { _MMIO(0x9888), 0x08320840 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x06344000 }, + { _MMIO(0x9888), 0x08344000 }, + { _MMIO(0x9888), 0x0d931831 }, + { _MMIO(0x9888), 0x0f939f3f }, + { _MMIO(0x9888), 0x01939e80 }, + { _MMIO(0x9888), 0x039303bc }, + { _MMIO(0x9888), 0x0593000e }, + { _MMIO(0x9888), 0x1993002a }, + { _MMIO(0x9888), 0x07930000 }, + { _MMIO(0x9888), 0x09930000 }, + { _MMIO(0x9888), 0x1d900177 }, + { _MMIO(0x9888), 0x1f900187 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x53901110 }, + { _MMIO(0x9888), 0x43900423 }, + { _MMIO(0x9888), 0x55900111 }, + { _MMIO(0x9888), 0x47900c02 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900020 }, + { _MMIO(0x9888), 0x59901111 }, + { _MMIO(0x9888), 0x4b900421 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x45900821 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + if (dev_priv->drm.pdev->revision >= 0x03) { + regs[n] = mux_config_render_basic_0_sku_gte_0x03; + lens[n] = ARRAY_SIZE(mux_config_render_basic_0_sku_gte_0x03); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x39900340 }, + { _MMIO(0x9888), 0x3f900c00 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x002d5000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d4000 }, + { _MMIO(0x9888), 0x0a2d1000 }, + { _MMIO(0x9888), 0x0c2d5000 }, + { _MMIO(0x9888), 0x0e2d4000 }, + { _MMIO(0x9888), 0x0c2e1400 }, + { _MMIO(0x9888), 0x0e2e5100 }, + { _MMIO(0x9888), 0x102e0114 }, + { _MMIO(0x9888), 0x044cc000 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4c8000 }, + { _MMIO(0x9888), 0x0e4c4000 }, + { _MMIO(0x9888), 0x104c8000 }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x004ea000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e2000 }, + { _MMIO(0x9888), 0x0c4ea000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x004f6b42 }, + { _MMIO(0x9888), 0x064f6200 }, + { _MMIO(0x9888), 0x084f4100 }, + { _MMIO(0x9888), 0x0a4f0061 }, + { _MMIO(0x9888), 0x0c4f6c4c }, + { _MMIO(0x9888), 0x0e4f4b00 }, + { _MMIO(0x9888), 0x1a4f0000 }, + { _MMIO(0x9888), 0x1c4f0000 }, + { _MMIO(0x9888), 0x180f5000 }, + { _MMIO(0x9888), 0x1a0f8800 }, + { _MMIO(0x9888), 0x1c0f08a2 }, + { _MMIO(0x9888), 0x182c4000 }, + { _MMIO(0x9888), 0x1c2c1451 }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x1a2c0010 }, + { _MMIO(0x9888), 0x01938000 }, + { _MMIO(0x9888), 0x0f938000 }, + { _MMIO(0x9888), 0x19938a28 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x19900177 }, + { _MMIO(0x9888), 0x1b900178 }, + { _MMIO(0x9888), 0x1d900125 }, + { _MMIO(0x9888), 0x1f900123 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x53901000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x55900111 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x45900000 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x0c2e001f }, + { _MMIO(0x9888), 0x0a2f0000 }, + { _MMIO(0x9888), 0x10186800 }, + { _MMIO(0x9888), 0x11810019 }, + { _MMIO(0x9888), 0x15810013 }, + { _MMIO(0x9888), 0x13820020 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x17840000 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x21860000 }, + { _MMIO(0x9888), 0x178703e0 }, + { _MMIO(0x9888), 0x0c2d8000 }, + { _MMIO(0x9888), 0x042d4000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x022e5400 }, + { _MMIO(0x9888), 0x002e0000 }, + { _MMIO(0x9888), 0x0e2e0080 }, + { _MMIO(0x9888), 0x082f0040 }, + { _MMIO(0x9888), 0x002f0000 }, + { _MMIO(0x9888), 0x06143000 }, + { _MMIO(0x9888), 0x06174000 }, + { _MMIO(0x9888), 0x06180012 }, + { _MMIO(0x9888), 0x00180000 }, + { _MMIO(0x9888), 0x0d804000 }, + { _MMIO(0x9888), 0x0f804000 }, + { _MMIO(0x9888), 0x05804000 }, + { _MMIO(0x9888), 0x09810200 }, + { _MMIO(0x9888), 0x0b810030 }, + { _MMIO(0x9888), 0x03810003 }, + { _MMIO(0x9888), 0x21819140 }, + { _MMIO(0x9888), 0x23819050 }, + { _MMIO(0x9888), 0x25810018 }, + { _MMIO(0x9888), 0x0b820980 }, + { _MMIO(0x9888), 0x03820d80 }, + { _MMIO(0x9888), 0x11820000 }, + { _MMIO(0x9888), 0x0182c000 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x09824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x0d830004 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x0f831000 }, + { _MMIO(0x9888), 0x01848072 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x09844000 }, + { _MMIO(0x9888), 0x0f848000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x09860092 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x01869100 }, + { _MMIO(0x9888), 0x0f870065 }, + { _MMIO(0x9888), 0x01870000 }, + { _MMIO(0x9888), 0x19930800 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x1b952000 }, + { _MMIO(0x9888), 0x1d955055 }, + { _MMIO(0x9888), 0x1f951455 }, + { _MMIO(0x9888), 0x0992a000 }, + { _MMIO(0x9888), 0x0f928000 }, + { _MMIO(0x9888), 0x1192a800 }, + { _MMIO(0x9888), 0x1392028a }, + { _MMIO(0x9888), 0x0b92a000 }, + { _MMIO(0x9888), 0x0d922000 }, + { _MMIO(0x9888), 0x13908000 }, + { _MMIO(0x9888), 0x21908000 }, + { _MMIO(0x9888), 0x23908000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27908000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x15908000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900c01 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900863 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900061 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x45900c22 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads[] = { + { _MMIO(0x9888), 0x19800343 }, + { _MMIO(0x9888), 0x39900340 }, + { _MMIO(0x9888), 0x3f901000 }, + { _MMIO(0x9888), 0x41900003 }, + { _MMIO(0x9888), 0x03803180 }, + { _MMIO(0x9888), 0x058035e2 }, + { _MMIO(0x9888), 0x0780006a }, + { _MMIO(0x9888), 0x11800000 }, + { _MMIO(0x9888), 0x2181a000 }, + { _MMIO(0x9888), 0x2381000a }, + { _MMIO(0x9888), 0x1d950550 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d92a000 }, + { _MMIO(0x9888), 0x0f922000 }, + { _MMIO(0x9888), 0x13900170 }, + { _MMIO(0x9888), 0x21900171 }, + { _MMIO(0x9888), 0x23900172 }, + { _MMIO(0x9888), 0x25900173 }, + { _MMIO(0x9888), 0x27900174 }, + { _MMIO(0x9888), 0x29900175 }, + { _MMIO(0x9888), 0x2b900176 }, + { _MMIO(0x9888), 0x2d900177 }, + { _MMIO(0x9888), 0x2f90017f }, + { _MMIO(0x9888), 0x31900125 }, + { _MMIO(0x9888), 0x15900123 }, + { _MMIO(0x9888), 0x17900121 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43901084 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47901080 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49901084 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b901084 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900004 }, + { _MMIO(0x9888), 0x45900000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes[] = { + { _MMIO(0x9888), 0x19800343 }, + { _MMIO(0x9888), 0x39900340 }, + { _MMIO(0x9888), 0x3f900000 }, + { _MMIO(0x9888), 0x41900080 }, + { _MMIO(0x9888), 0x03803180 }, + { _MMIO(0x9888), 0x058035e2 }, + { _MMIO(0x9888), 0x0780006a }, + { _MMIO(0x9888), 0x11800000 }, + { _MMIO(0x9888), 0x2181a000 }, + { _MMIO(0x9888), 0x2381000a }, + { _MMIO(0x9888), 0x1d950550 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d92a000 }, + { _MMIO(0x9888), 0x0f922000 }, + { _MMIO(0x9888), 0x13900180 }, + { _MMIO(0x9888), 0x21900181 }, + { _MMIO(0x9888), 0x23900182 }, + { _MMIO(0x9888), 0x25900183 }, + { _MMIO(0x9888), 0x27900184 }, + { _MMIO(0x9888), 0x29900185 }, + { _MMIO(0x9888), 0x2b900186 }, + { _MMIO(0x9888), 0x2d900187 }, + { _MMIO(0x9888), 0x2f900170 }, + { _MMIO(0x9888), 0x31900125 }, + { _MMIO(0x9888), 0x15900123 }, + { _MMIO(0x9888), 0x17900121 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43901084 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47901080 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49901084 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b901084 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900004 }, + { _MMIO(0x9888), 0x45900000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x141c0160 }, + { _MMIO(0x9888), 0x161c0015 }, + { _MMIO(0x9888), 0x181c0120 }, + { _MMIO(0x9888), 0x002d5000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d5000 }, + { _MMIO(0x9888), 0x0a2d5000 }, + { _MMIO(0x9888), 0x0c2d5000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x0c2e5400 }, + { _MMIO(0x9888), 0x0e2e5515 }, + { _MMIO(0x9888), 0x102e0155 }, + { _MMIO(0x9888), 0x044cc000 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4cc000 }, + { _MMIO(0x9888), 0x0e4cc000 }, + { _MMIO(0x9888), 0x104c8000 }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x004ea000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084ea000 }, + { _MMIO(0x9888), 0x0a4ea000 }, + { _MMIO(0x9888), 0x0c4ea000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x0e4f4b41 }, + { _MMIO(0x9888), 0x004f4200 }, + { _MMIO(0x9888), 0x024f404c }, + { _MMIO(0x9888), 0x1c4f0000 }, + { _MMIO(0x9888), 0x1a4f0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x061b8000 }, + { _MMIO(0x9888), 0x081bc000 }, + { _MMIO(0x9888), 0x0a1bc000 }, + { _MMIO(0x9888), 0x0c1bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x001c0031 }, + { _MMIO(0x9888), 0x061c1900 }, + { _MMIO(0x9888), 0x081c1a33 }, + { _MMIO(0x9888), 0x0a1c1b35 }, + { _MMIO(0x9888), 0x0c1c3337 }, + { _MMIO(0x9888), 0x041c31c7 }, + { _MMIO(0x9888), 0x180f5000 }, + { _MMIO(0x9888), 0x1a0fa8aa }, + { _MMIO(0x9888), 0x1c0f0aaa }, + { _MMIO(0x9888), 0x182c8000 }, + { _MMIO(0x9888), 0x1c2c6aaa }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x1a2c2950 }, + { _MMIO(0x9888), 0x01938000 }, + { _MMIO(0x9888), 0x0f938000 }, + { _MMIO(0x9888), 0x1993aaaa }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29904000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900420 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900400 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x45900001 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extended; + lens[n] = ARRAY_SIZE(mux_config_compute_extended); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x166c03b0 }, + { _MMIO(0x9888), 0x1593001e }, + { _MMIO(0x9888), 0x3f900c00 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x002d1000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d5000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x0c2e0400 }, + { _MMIO(0x9888), 0x0e2e1500 }, + { _MMIO(0x9888), 0x102e0140 }, + { _MMIO(0x9888), 0x044c4000 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4cc000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x004e2000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084ea000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x1a4f4001 }, + { _MMIO(0x9888), 0x1c4f5005 }, + { _MMIO(0x9888), 0x006c0051 }, + { _MMIO(0x9888), 0x066c5000 }, + { _MMIO(0x9888), 0x086c5c5d }, + { _MMIO(0x9888), 0x0e6c5e5f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x146c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x180f1000 }, + { _MMIO(0x9888), 0x1a0fa800 }, + { _MMIO(0x9888), 0x1c0f0a00 }, + { _MMIO(0x9888), 0x182c4000 }, + { _MMIO(0x9888), 0x1c2c4015 }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x03931980 }, + { _MMIO(0x9888), 0x05930032 }, + { _MMIO(0x9888), 0x11930000 }, + { _MMIO(0x9888), 0x01938000 }, + { _MMIO(0x9888), 0x0f938000 }, + { _MMIO(0x9888), 0x1993a00a }, + { _MMIO(0x9888), 0x07930000 }, + { _MMIO(0x9888), 0x09930000 }, + { _MMIO(0x9888), 0x1d900177 }, + { _MMIO(0x9888), 0x1f900178 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x53901000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x55900111 }, + { _MMIO(0x9888), 0x47900001 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x45900400 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x104f0232 }, + { _MMIO(0x9888), 0x124f4640 }, + { _MMIO(0x9888), 0x11834400 }, + { _MMIO(0x9888), 0x022d4000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0e2e0055 }, + { _MMIO(0x9888), 0x064c8000 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x024f6100 }, + { _MMIO(0x9888), 0x044f416b }, + { _MMIO(0x9888), 0x064f004b }, + { _MMIO(0x9888), 0x1a4f0000 }, + { _MMIO(0x9888), 0x1a0f02a8 }, + { _MMIO(0x9888), 0x1a2c5500 }, + { _MMIO(0x9888), 0x0f808000 }, + { _MMIO(0x9888), 0x25810020 }, + { _MMIO(0x9888), 0x0f8305c0 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x1f951000 }, + { _MMIO(0x9888), 0x13920200 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4d900003 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1_0_sku_gte_0x03[] = { + { _MMIO(0x9888), 0x12643400 }, + { _MMIO(0x9888), 0x12653400 }, + { _MMIO(0x9888), 0x106c6800 }, + { _MMIO(0x9888), 0x126c001e }, + { _MMIO(0x9888), 0x166c0010 }, + { _MMIO(0x9888), 0x0c2d5000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x102e0154 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e0055 }, + { _MMIO(0x9888), 0x104c8000 }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x0c4ea000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x1c4f5500 }, + { _MMIO(0x9888), 0x1a4f1554 }, + { _MMIO(0x9888), 0x0a640024 }, + { _MMIO(0x9888), 0x10640000 }, + { _MMIO(0x9888), 0x04640000 }, + { _MMIO(0x9888), 0x0c650024 }, + { _MMIO(0x9888), 0x10650000 }, + { _MMIO(0x9888), 0x06650000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1a6c0900 }, + { _MMIO(0x9888), 0x1c0f0aa0 }, + { _MMIO(0x9888), 0x180f4000 }, + { _MMIO(0x9888), 0x1a0f02aa }, + { _MMIO(0x9888), 0x1c2c5400 }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x1a2c5550 }, + { _MMIO(0x9888), 0x1993aa00 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900421 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900420 }, + { _MMIO(0x9888), 0x45900021 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, +}; + +static const struct i915_oa_reg mux_config_l3_1_0_sku_lt_0x03[] = { + { _MMIO(0x9888), 0x14640340 }, + { _MMIO(0x9888), 0x14650340 }, + { _MMIO(0x9888), 0x106c6800 }, + { _MMIO(0x9888), 0x126c001e }, + { _MMIO(0x9888), 0x166c0010 }, + { _MMIO(0x9888), 0x0c2d5000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x102e0154 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e0055 }, + { _MMIO(0x9888), 0x104c8000 }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x0c4ea000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x1c4f5500 }, + { _MMIO(0x9888), 0x1a4f1554 }, + { _MMIO(0x9888), 0x04642400 }, + { _MMIO(0x9888), 0x22640000 }, + { _MMIO(0x9888), 0x1a640000 }, + { _MMIO(0x9888), 0x06650024 }, + { _MMIO(0x9888), 0x22650000 }, + { _MMIO(0x9888), 0x1c650000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1a6c0900 }, + { _MMIO(0x9888), 0x1c0f0aa0 }, + { _MMIO(0x9888), 0x180f4000 }, + { _MMIO(0x9888), 0x1a0f02aa }, + { _MMIO(0x9888), 0x1c2c5400 }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x1a2c5550 }, + { _MMIO(0x9888), 0x1993aa00 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900421 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900420 }, + { _MMIO(0x9888), 0x45900021 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2); + + if (dev_priv->drm.pdev->revision >= 0x03) { + regs[n] = mux_config_l3_1_0_sku_gte_0x03; + lens[n] = ARRAY_SIZE(mux_config_l3_1_0_sku_gte_0x03); + n++; + } + if (dev_priv->drm.pdev->revision < 0x03) { + regs[n] = mux_config_l3_1_0_sku_lt_0x03; + lens[n] = ARRAY_SIZE(mux_config_l3_1_0_sku_lt_0x03); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000efff }, + { _MMIO(0x2778), 0x00006000 }, + { _MMIO(0x277c), 0x0000f3ff }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x102d7800 }, + { _MMIO(0x9888), 0x122d79e0 }, + { _MMIO(0x9888), 0x0c2f0004 }, + { _MMIO(0x9888), 0x100e3800 }, + { _MMIO(0x9888), 0x180f0005 }, + { _MMIO(0x9888), 0x002d0940 }, + { _MMIO(0x9888), 0x022d802f }, + { _MMIO(0x9888), 0x042d4013 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0e2e0050 }, + { _MMIO(0x9888), 0x022f0010 }, + { _MMIO(0x9888), 0x002f0000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x040e0480 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x060f0027 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x1a0f0040 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x439014a0 }, + { _MMIO(0x9888), 0x459000a4 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler[] = { + { _MMIO(0x9888), 0x121300a0 }, + { _MMIO(0x9888), 0x141600ab }, + { _MMIO(0x9888), 0x123300a0 }, + { _MMIO(0x9888), 0x143600ab }, + { _MMIO(0x9888), 0x125300a0 }, + { _MMIO(0x9888), 0x145600ab }, + { _MMIO(0x9888), 0x0c2d4000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x102e01a0 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e0065 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x084c4000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x044e2000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x1c0f0800 }, + { _MMIO(0x9888), 0x180f4000 }, + { _MMIO(0x9888), 0x1a0f023f }, + { _MMIO(0x9888), 0x1e2c0003 }, + { _MMIO(0x9888), 0x1a2cc030 }, + { _MMIO(0x9888), 0x04132180 }, + { _MMIO(0x9888), 0x02130000 }, + { _MMIO(0x9888), 0x0c148000 }, + { _MMIO(0x9888), 0x0e142000 }, + { _MMIO(0x9888), 0x04148000 }, + { _MMIO(0x9888), 0x1e150140 }, + { _MMIO(0x9888), 0x1c150040 }, + { _MMIO(0x9888), 0x0c163000 }, + { _MMIO(0x9888), 0x0e160068 }, + { _MMIO(0x9888), 0x10160000 }, + { _MMIO(0x9888), 0x18160000 }, + { _MMIO(0x9888), 0x0a164000 }, + { _MMIO(0x9888), 0x04330043 }, + { _MMIO(0x9888), 0x02330000 }, + { _MMIO(0x9888), 0x0234a000 }, + { _MMIO(0x9888), 0x04342000 }, + { _MMIO(0x9888), 0x1c350015 }, + { _MMIO(0x9888), 0x02363460 }, + { _MMIO(0x9888), 0x10360000 }, + { _MMIO(0x9888), 0x04360000 }, + { _MMIO(0x9888), 0x06360000 }, + { _MMIO(0x9888), 0x08364000 }, + { _MMIO(0x9888), 0x06530043 }, + { _MMIO(0x9888), 0x02530000 }, + { _MMIO(0x9888), 0x0e548000 }, + { _MMIO(0x9888), 0x00548000 }, + { _MMIO(0x9888), 0x06542000 }, + { _MMIO(0x9888), 0x1e550400 }, + { _MMIO(0x9888), 0x1a552000 }, + { _MMIO(0x9888), 0x1c550100 }, + { _MMIO(0x9888), 0x0e563000 }, + { _MMIO(0x9888), 0x00563400 }, + { _MMIO(0x9888), 0x10560000 }, + { _MMIO(0x9888), 0x18560000 }, + { _MMIO(0x9888), 0x02560000 }, + { _MMIO(0x9888), 0x0c564000 }, + { _MMIO(0x9888), 0x1993a800 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b9014a0 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900820 }, + { _MMIO(0x9888), 0x45901022 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, +}; + +static int +get_sampler_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler; + lens[n] = ARRAY_SIZE(mux_config_sampler); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x00007fff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x00009fff }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000efff }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000f3ff }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fdff }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x141a0000 }, + { _MMIO(0x9888), 0x143a0000 }, + { _MMIO(0x9888), 0x145a0000 }, + { _MMIO(0x9888), 0x0c2d4000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x102e0150 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e006a }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064c4000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024e2000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x1c0f0bc0 }, + { _MMIO(0x9888), 0x180f4000 }, + { _MMIO(0x9888), 0x1a0f0302 }, + { _MMIO(0x9888), 0x1e2c0003 }, + { _MMIO(0x9888), 0x1a2c00f0 }, + { _MMIO(0x9888), 0x021a3080 }, + { _MMIO(0x9888), 0x041a31e5 }, + { _MMIO(0x9888), 0x02148000 }, + { _MMIO(0x9888), 0x0414a000 }, + { _MMIO(0x9888), 0x1c150054 }, + { _MMIO(0x9888), 0x06168000 }, + { _MMIO(0x9888), 0x08168000 }, + { _MMIO(0x9888), 0x0a168000 }, + { _MMIO(0x9888), 0x0c3a3280 }, + { _MMIO(0x9888), 0x0e3a0063 }, + { _MMIO(0x9888), 0x063a0061 }, + { _MMIO(0x9888), 0x023a0000 }, + { _MMIO(0x9888), 0x0c348000 }, + { _MMIO(0x9888), 0x0e342000 }, + { _MMIO(0x9888), 0x06342000 }, + { _MMIO(0x9888), 0x1e350140 }, + { _MMIO(0x9888), 0x1c350100 }, + { _MMIO(0x9888), 0x18360028 }, + { _MMIO(0x9888), 0x0c368000 }, + { _MMIO(0x9888), 0x0e5a3080 }, + { _MMIO(0x9888), 0x005a3280 }, + { _MMIO(0x9888), 0x025a0063 }, + { _MMIO(0x9888), 0x0e548000 }, + { _MMIO(0x9888), 0x00548000 }, + { _MMIO(0x9888), 0x02542000 }, + { _MMIO(0x9888), 0x1e550400 }, + { _MMIO(0x9888), 0x1a552000 }, + { _MMIO(0x9888), 0x1c550001 }, + { _MMIO(0x9888), 0x18560080 }, + { _MMIO(0x9888), 0x02568000 }, + { _MMIO(0x9888), 0x04568000 }, + { _MMIO(0x9888), 0x1993a800 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900420 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x45901084 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900001 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x141a026b }, + { _MMIO(0x9888), 0x143a0173 }, + { _MMIO(0x9888), 0x145a026b }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e0069 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x180f6000 }, + { _MMIO(0x9888), 0x1a0f030a }, + { _MMIO(0x9888), 0x1a2c03c0 }, + { _MMIO(0x9888), 0x041a37e7 }, + { _MMIO(0x9888), 0x021a0000 }, + { _MMIO(0x9888), 0x0414a000 }, + { _MMIO(0x9888), 0x1c150050 }, + { _MMIO(0x9888), 0x08168000 }, + { _MMIO(0x9888), 0x0a168000 }, + { _MMIO(0x9888), 0x003a3380 }, + { _MMIO(0x9888), 0x063a006f }, + { _MMIO(0x9888), 0x023a0000 }, + { _MMIO(0x9888), 0x00348000 }, + { _MMIO(0x9888), 0x06342000 }, + { _MMIO(0x9888), 0x1a352000 }, + { _MMIO(0x9888), 0x1c350100 }, + { _MMIO(0x9888), 0x02368000 }, + { _MMIO(0x9888), 0x0c368000 }, + { _MMIO(0x9888), 0x025a37e7 }, + { _MMIO(0x9888), 0x0254a000 }, + { _MMIO(0x9888), 0x1c550005 }, + { _MMIO(0x9888), 0x04568000 }, + { _MMIO(0x9888), 0x06568000 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900020 }, + { _MMIO(0x9888), 0x45901080 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { + { _MMIO(0xe458), 0x00001000 }, + { _MMIO(0xe558), 0x00003002 }, + { _MMIO(0xe658), 0x00005004 }, + { _MMIO(0xe758), 0x00011010 }, + { _MMIO(0xe45c), 0x00050012 }, + { _MMIO(0xe55c), 0x00052051 }, + { _MMIO(0xe65c), 0x00000008 }, +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x141a001f }, + { _MMIO(0x9888), 0x143a001f }, + { _MMIO(0x9888), 0x145a001f }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0e2e0094 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x1a0f00e0 }, + { _MMIO(0x9888), 0x1a2c0c00 }, + { _MMIO(0x9888), 0x061a0063 }, + { _MMIO(0x9888), 0x021a0000 }, + { _MMIO(0x9888), 0x06142000 }, + { _MMIO(0x9888), 0x1c150100 }, + { _MMIO(0x9888), 0x0c168000 }, + { _MMIO(0x9888), 0x043a3180 }, + { _MMIO(0x9888), 0x023a0000 }, + { _MMIO(0x9888), 0x04348000 }, + { _MMIO(0x9888), 0x1c350040 }, + { _MMIO(0x9888), 0x0a368000 }, + { _MMIO(0x9888), 0x045a0063 }, + { _MMIO(0x9888), 0x025a0000 }, + { _MMIO(0x9888), 0x04542000 }, + { _MMIO(0x9888), 0x1c550010 }, + { _MMIO(0x9888), 0x08568000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x47900004 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x19800000 }, + { _MMIO(0x9888), 0x07800063 }, + { _MMIO(0x9888), 0x11800000 }, + { _MMIO(0x9888), 0x23810008 }, + { _MMIO(0x9888), 0x1d950400 }, + { _MMIO(0x9888), 0x0f922000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_bxt(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER: + dev_priv->perf.oa.n_mux_configs = + get_sampler_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "22b9519a-e9ba-4c41-8b54-f4f8ca14fa0a", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "012d72cf-82a9-4d25-8ddf-74076fd30797", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "ce416533-e49e-4211-80af-ec513590a914", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "398e2452-18d7-42d0-b241-e4d0a9148ada", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "d324a0d6-7269-4847-a5c2-6f71ddc7fed5", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "caf3596a-7bb1-4dec-b3b3-2a080d283b49", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "49b956e2-d5b9-47e0-9d8a-cee5e8cec527", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "f64ef50a-bdba-4b35-8f09-203c13d8ee5a", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "00ad5a41-7eab-4f7a-9103-49d411c67219", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "46dc44ca-491c-4cc1-a951-e7b3e62bf02b", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER); +} + +static struct device_attribute dev_attr_sampler_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler[] = { + &dev_attr_sampler_id.attr, + NULL, +}; + +static struct attribute_group group_sampler = { + .name = "8364e2a8-af63-40af-b0d5-42969a255654", + .attrs = attrs_sampler, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "175c8092-cb25-4d1e-8dc7-b4fdd39e2d92", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "d260f03f-b34d-4b49-a44e-436819117332", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "fa6ecf21-2cb8-4d0b-9308-6e4a7b4ca87a", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "5ee72f5c-092f-421e-8b70-225f7c3e9612", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_bxt(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (ret) + goto error_sampler; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); +error_sampler: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_bxt(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.h b/drivers/gpu/drm/i915/i915_oa_bxt.h new file mode 100644 index 0000000..6cf7ba7 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_bxt.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_BXT_H__ +#define __I915_OA_BXT_H__ + +extern int i915_oa_n_builtin_metric_sets_bxt; + +extern int i915_oa_select_metric_set_bxt(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_bxt(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_bxt(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_chv.c b/drivers/gpu/drm/i915/i915_oa_chv.c new file mode 100644 index 0000000..aa6bece --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_chv.c @@ -0,0 +1,2873 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_chv.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_L3_2, + METRIC_SET_ID_L3_3, + METRIC_SET_ID_L3_4, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER_1, + METRIC_SET_ID_SAMPLER_2, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_chv = 14; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic[] = { + { _MMIO(0x9888), 0x59800000 }, + { _MMIO(0x9888), 0x59800001 }, + { _MMIO(0x9888), 0x285a0006 }, + { _MMIO(0x9888), 0x2c110014 }, + { _MMIO(0x9888), 0x2e110000 }, + { _MMIO(0x9888), 0x2c310014 }, + { _MMIO(0x9888), 0x2e310000 }, + { _MMIO(0x9888), 0x2b8303df }, + { _MMIO(0x9888), 0x3580024f }, + { _MMIO(0x9888), 0x00580888 }, + { _MMIO(0x9888), 0x1e5a0015 }, + { _MMIO(0x9888), 0x205a0014 }, + { _MMIO(0x9888), 0x045a0000 }, + { _MMIO(0x9888), 0x025a0000 }, + { _MMIO(0x9888), 0x02180500 }, + { _MMIO(0x9888), 0x00190555 }, + { _MMIO(0x9888), 0x021d0500 }, + { _MMIO(0x9888), 0x021f0a00 }, + { _MMIO(0x9888), 0x00380444 }, + { _MMIO(0x9888), 0x02390500 }, + { _MMIO(0x9888), 0x003a0666 }, + { _MMIO(0x9888), 0x00100111 }, + { _MMIO(0x9888), 0x06110030 }, + { _MMIO(0x9888), 0x0a110031 }, + { _MMIO(0x9888), 0x0e110046 }, + { _MMIO(0x9888), 0x04110000 }, + { _MMIO(0x9888), 0x00110000 }, + { _MMIO(0x9888), 0x00130111 }, + { _MMIO(0x9888), 0x00300444 }, + { _MMIO(0x9888), 0x08310030 }, + { _MMIO(0x9888), 0x0c310031 }, + { _MMIO(0x9888), 0x10310046 }, + { _MMIO(0x9888), 0x04310000 }, + { _MMIO(0x9888), 0x00310000 }, + { _MMIO(0x9888), 0x00330444 }, + { _MMIO(0x9888), 0x038a0a00 }, + { _MMIO(0x9888), 0x018b0fff }, + { _MMIO(0x9888), 0x038b0a00 }, + { _MMIO(0x9888), 0x01855000 }, + { _MMIO(0x9888), 0x03850055 }, + { _MMIO(0x9888), 0x13830021 }, + { _MMIO(0x9888), 0x15830020 }, + { _MMIO(0x9888), 0x1783002f }, + { _MMIO(0x9888), 0x1983002e }, + { _MMIO(0x9888), 0x1b83002d }, + { _MMIO(0x9888), 0x1d83002c }, + { _MMIO(0x9888), 0x05830000 }, + { _MMIO(0x9888), 0x01840555 }, + { _MMIO(0x9888), 0x03840500 }, + { _MMIO(0x9888), 0x23800074 }, + { _MMIO(0x9888), 0x2580007d }, + { _MMIO(0x9888), 0x05800000 }, + { _MMIO(0x9888), 0x01805000 }, + { _MMIO(0x9888), 0x03800055 }, + { _MMIO(0x9888), 0x01865000 }, + { _MMIO(0x9888), 0x03860055 }, + { _MMIO(0x9888), 0x01875000 }, + { _MMIO(0x9888), 0x03870055 }, + { _MMIO(0x9888), 0x418000aa }, + { _MMIO(0x9888), 0x4380000a }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x4780000a }, + { _MMIO(0x9888), 0x49800000 }, + { _MMIO(0x9888), 0x4b800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x55800000 }, + { _MMIO(0x9888), 0x57800000 }, + { _MMIO(0x9888), 0x59800000 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_basic; + lens[n] = ARRAY_SIZE(mux_config_render_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic[] = { + { _MMIO(0x9888), 0x59800000 }, + { _MMIO(0x9888), 0x59800001 }, + { _MMIO(0x9888), 0x2e5800e0 }, + { _MMIO(0x9888), 0x2e3800e0 }, + { _MMIO(0x9888), 0x3580024f }, + { _MMIO(0x9888), 0x3d800140 }, + { _MMIO(0x9888), 0x08580042 }, + { _MMIO(0x9888), 0x0c580040 }, + { _MMIO(0x9888), 0x1058004c }, + { _MMIO(0x9888), 0x1458004b }, + { _MMIO(0x9888), 0x04580000 }, + { _MMIO(0x9888), 0x00580000 }, + { _MMIO(0x9888), 0x00195555 }, + { _MMIO(0x9888), 0x06380042 }, + { _MMIO(0x9888), 0x0a380040 }, + { _MMIO(0x9888), 0x0e38004c }, + { _MMIO(0x9888), 0x1238004b }, + { _MMIO(0x9888), 0x04380000 }, + { _MMIO(0x9888), 0x00384444 }, + { _MMIO(0x9888), 0x003a5555 }, + { _MMIO(0x9888), 0x018bffff }, + { _MMIO(0x9888), 0x01845555 }, + { _MMIO(0x9888), 0x17800074 }, + { _MMIO(0x9888), 0x1980007d }, + { _MMIO(0x9888), 0x1b80007c }, + { _MMIO(0x9888), 0x1d8000b6 }, + { _MMIO(0x9888), 0x1f8000b7 }, + { _MMIO(0x9888), 0x05800000 }, + { _MMIO(0x9888), 0x03800000 }, + { _MMIO(0x9888), 0x418000aa }, + { _MMIO(0x9888), 0x438000aa }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x47800000 }, + { _MMIO(0x9888), 0x4980012a }, + { _MMIO(0x9888), 0x4b80012a }, + { _MMIO(0x9888), 0x4d80012a }, + { _MMIO(0x9888), 0x4f80012a }, + { _MMIO(0x9888), 0x518001ce }, + { _MMIO(0x9888), 0x538001ce }, + { _MMIO(0x9888), 0x5580000e }, + { _MMIO(0x9888), 0x59800000 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x59800000 }, + { _MMIO(0x9888), 0x59800001 }, + { _MMIO(0x9888), 0x261e0000 }, + { _MMIO(0x9888), 0x281f000f }, + { _MMIO(0x9888), 0x2817001a }, + { _MMIO(0x9888), 0x2791001f }, + { _MMIO(0x9888), 0x27880019 }, + { _MMIO(0x9888), 0x2d890000 }, + { _MMIO(0x9888), 0x278a0007 }, + { _MMIO(0x9888), 0x298d001f }, + { _MMIO(0x9888), 0x278e0020 }, + { _MMIO(0x9888), 0x2b8f0012 }, + { _MMIO(0x9888), 0x29900000 }, + { _MMIO(0x9888), 0x00184000 }, + { _MMIO(0x9888), 0x02181000 }, + { _MMIO(0x9888), 0x02194000 }, + { _MMIO(0x9888), 0x141e0002 }, + { _MMIO(0x9888), 0x041e0000 }, + { _MMIO(0x9888), 0x001e0000 }, + { _MMIO(0x9888), 0x221f0015 }, + { _MMIO(0x9888), 0x041f0000 }, + { _MMIO(0x9888), 0x001f4000 }, + { _MMIO(0x9888), 0x021f0000 }, + { _MMIO(0x9888), 0x023a8000 }, + { _MMIO(0x9888), 0x0213c000 }, + { _MMIO(0x9888), 0x02164000 }, + { _MMIO(0x9888), 0x24170012 }, + { _MMIO(0x9888), 0x04170000 }, + { _MMIO(0x9888), 0x07910005 }, + { _MMIO(0x9888), 0x05910000 }, + { _MMIO(0x9888), 0x01911500 }, + { _MMIO(0x9888), 0x03910501 }, + { _MMIO(0x9888), 0x0d880002 }, + { _MMIO(0x9888), 0x1d880003 }, + { _MMIO(0x9888), 0x05880000 }, + { _MMIO(0x9888), 0x0b890032 }, + { _MMIO(0x9888), 0x1b890031 }, + { _MMIO(0x9888), 0x05890000 }, + { _MMIO(0x9888), 0x01890040 }, + { _MMIO(0x9888), 0x03890040 }, + { _MMIO(0x9888), 0x098a0000 }, + { _MMIO(0x9888), 0x198a0004 }, + { _MMIO(0x9888), 0x058a0000 }, + { _MMIO(0x9888), 0x018a8050 }, + { _MMIO(0x9888), 0x038a2050 }, + { _MMIO(0x9888), 0x018b95a9 }, + { _MMIO(0x9888), 0x038be5a9 }, + { _MMIO(0x9888), 0x018c1500 }, + { _MMIO(0x9888), 0x038c0501 }, + { _MMIO(0x9888), 0x178d0015 }, + { _MMIO(0x9888), 0x058d0000 }, + { _MMIO(0x9888), 0x138e0004 }, + { _MMIO(0x9888), 0x218e000c }, + { _MMIO(0x9888), 0x058e0000 }, + { _MMIO(0x9888), 0x018e0500 }, + { _MMIO(0x9888), 0x038e0101 }, + { _MMIO(0x9888), 0x0f8f0027 }, + { _MMIO(0x9888), 0x058f0000 }, + { _MMIO(0x9888), 0x018f0000 }, + { _MMIO(0x9888), 0x038f0001 }, + { _MMIO(0x9888), 0x11900013 }, + { _MMIO(0x9888), 0x1f900017 }, + { _MMIO(0x9888), 0x05900000 }, + { _MMIO(0x9888), 0x01900100 }, + { _MMIO(0x9888), 0x03900001 }, + { _MMIO(0x9888), 0x01845555 }, + { _MMIO(0x9888), 0x03845555 }, + { _MMIO(0x9888), 0x418000aa }, + { _MMIO(0x9888), 0x438000aa }, + { _MMIO(0x9888), 0x458000aa }, + { _MMIO(0x9888), 0x478000aa }, + { _MMIO(0x9888), 0x4980018c }, + { _MMIO(0x9888), 0x4b80014b }, + { _MMIO(0x9888), 0x4d800128 }, + { _MMIO(0x9888), 0x4f80012a }, + { _MMIO(0x9888), 0x51800187 }, + { _MMIO(0x9888), 0x5380014b }, + { _MMIO(0x9888), 0x55800149 }, + { _MMIO(0x9888), 0x5780010a }, + { _MMIO(0x9888), 0x59800000 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fff7 }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x105c0232 }, + { _MMIO(0x9888), 0x10580232 }, + { _MMIO(0x9888), 0x10380232 }, + { _MMIO(0x9888), 0x10dc0232 }, + { _MMIO(0x9888), 0x10d80232 }, + { _MMIO(0x9888), 0x10b80232 }, + { _MMIO(0x9888), 0x118e4400 }, + { _MMIO(0x9888), 0x025c6080 }, + { _MMIO(0x9888), 0x045c004b }, + { _MMIO(0x9888), 0x005c8000 }, + { _MMIO(0x9888), 0x00582080 }, + { _MMIO(0x9888), 0x0258004b }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00aa }, + { _MMIO(0x9888), 0x04386080 }, + { _MMIO(0x9888), 0x0638404b }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a380000 }, + { _MMIO(0x9888), 0x0c380000 }, + { _MMIO(0x9888), 0x00398000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x0cdc25c1 }, + { _MMIO(0x9888), 0x0adcc000 }, + { _MMIO(0x9888), 0x0ad825c1 }, + { _MMIO(0x9888), 0x18db4000 }, + { _MMIO(0x9888), 0x1adb0001 }, + { _MMIO(0x9888), 0x0e9f8000 }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x0eb825c1 }, + { _MMIO(0x9888), 0x18b80154 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x0d88c000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x258baa05 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x198c5400 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x098dc000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x098e05c0 }, + { _MMIO(0x9888), 0x058e0000 }, + { _MMIO(0x9888), 0x198f0020 }, + { _MMIO(0x9888), 0x2185aa0a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x19835000 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x19808000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x51800040 }, + { _MMIO(0x9888), 0x43800400 }, + { _MMIO(0x9888), 0x45800800 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800c62 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f801042 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x418014a4 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x10bf03da }, + { _MMIO(0x9888), 0x14bf0001 }, + { _MMIO(0x9888), 0x12980340 }, + { _MMIO(0x9888), 0x12990340 }, + { _MMIO(0x9888), 0x0cbf1187 }, + { _MMIO(0x9888), 0x0ebf1205 }, + { _MMIO(0x9888), 0x00bf0500 }, + { _MMIO(0x9888), 0x02bf042b }, + { _MMIO(0x9888), 0x04bf002c }, + { _MMIO(0x9888), 0x0cdac000 }, + { _MMIO(0x9888), 0x0edac000 }, + { _MMIO(0x9888), 0x00da8000 }, + { _MMIO(0x9888), 0x02dac000 }, + { _MMIO(0x9888), 0x04da4000 }, + { _MMIO(0x9888), 0x04983400 }, + { _MMIO(0x9888), 0x10980000 }, + { _MMIO(0x9888), 0x06990034 }, + { _MMIO(0x9888), 0x10990000 }, + { _MMIO(0x9888), 0x0c9dc000 }, + { _MMIO(0x9888), 0x0e9dc000 }, + { _MMIO(0x9888), 0x009d8000 }, + { _MMIO(0x9888), 0x029dc000 }, + { _MMIO(0x9888), 0x049d4000 }, + { _MMIO(0x9888), 0x109f02a8 }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0e9f00ba }, + { _MMIO(0x9888), 0x0cb88000 }, + { _MMIO(0x9888), 0x0cb95000 }, + { _MMIO(0x9888), 0x0eb95000 }, + { _MMIO(0x9888), 0x00b94000 }, + { _MMIO(0x9888), 0x02b95000 }, + { _MMIO(0x9888), 0x04b91000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x0cba4000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x258b800a }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b5500 }, + { _MMIO(0x9888), 0x198c4000 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x47800000 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800060 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_2[] = { + { _MMIO(0x9888), 0x103f03da }, + { _MMIO(0x9888), 0x143f0001 }, + { _MMIO(0x9888), 0x12180340 }, + { _MMIO(0x9888), 0x12190340 }, + { _MMIO(0x9888), 0x0c3f1187 }, + { _MMIO(0x9888), 0x0e3f1205 }, + { _MMIO(0x9888), 0x003f0500 }, + { _MMIO(0x9888), 0x023f042b }, + { _MMIO(0x9888), 0x043f002c }, + { _MMIO(0x9888), 0x0c5ac000 }, + { _MMIO(0x9888), 0x0e5ac000 }, + { _MMIO(0x9888), 0x005a8000 }, + { _MMIO(0x9888), 0x025ac000 }, + { _MMIO(0x9888), 0x045a4000 }, + { _MMIO(0x9888), 0x04183400 }, + { _MMIO(0x9888), 0x10180000 }, + { _MMIO(0x9888), 0x06190034 }, + { _MMIO(0x9888), 0x10190000 }, + { _MMIO(0x9888), 0x0c1dc000 }, + { _MMIO(0x9888), 0x0e1dc000 }, + { _MMIO(0x9888), 0x001d8000 }, + { _MMIO(0x9888), 0x021dc000 }, + { _MMIO(0x9888), 0x041d4000 }, + { _MMIO(0x9888), 0x101f02a8 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00ba }, + { _MMIO(0x9888), 0x0c388000 }, + { _MMIO(0x9888), 0x0c395000 }, + { _MMIO(0x9888), 0x0e395000 }, + { _MMIO(0x9888), 0x00394000 }, + { _MMIO(0x9888), 0x02395000 }, + { _MMIO(0x9888), 0x04391000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x0c3a4000 }, + { _MMIO(0x9888), 0x1b8aa800 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x258b4005 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800000 }, + { _MMIO(0x9888), 0x47800000 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800060 }, +}; + +static int +get_l3_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_2; + lens[n] = ARRAY_SIZE(mux_config_l3_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_3[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_3[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_3[] = { + { _MMIO(0x9888), 0x121b0340 }, + { _MMIO(0x9888), 0x103f0274 }, + { _MMIO(0x9888), 0x123f0000 }, + { _MMIO(0x9888), 0x129b0340 }, + { _MMIO(0x9888), 0x10bf0274 }, + { _MMIO(0x9888), 0x12bf0000 }, + { _MMIO(0x9888), 0x041b3400 }, + { _MMIO(0x9888), 0x101b0000 }, + { _MMIO(0x9888), 0x045c8000 }, + { _MMIO(0x9888), 0x0a3d4000 }, + { _MMIO(0x9888), 0x003f0080 }, + { _MMIO(0x9888), 0x023f0793 }, + { _MMIO(0x9888), 0x043f0014 }, + { _MMIO(0x9888), 0x04588000 }, + { _MMIO(0x9888), 0x005a8000 }, + { _MMIO(0x9888), 0x025ac000 }, + { _MMIO(0x9888), 0x045a4000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x001d8000 }, + { _MMIO(0x9888), 0x021dc000 }, + { _MMIO(0x9888), 0x041d4000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f002a }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x00394000 }, + { _MMIO(0x9888), 0x02395000 }, + { _MMIO(0x9888), 0x04399000 }, + { _MMIO(0x9888), 0x069b0034 }, + { _MMIO(0x9888), 0x109b0000 }, + { _MMIO(0x9888), 0x06dc4000 }, + { _MMIO(0x9888), 0x0cbd4000 }, + { _MMIO(0x9888), 0x0cbf0981 }, + { _MMIO(0x9888), 0x0ebf0a0f }, + { _MMIO(0x9888), 0x06d84000 }, + { _MMIO(0x9888), 0x0cdac000 }, + { _MMIO(0x9888), 0x0edac000 }, + { _MMIO(0x9888), 0x0cdb4000 }, + { _MMIO(0x9888), 0x0c9dc000 }, + { _MMIO(0x9888), 0x0e9dc000 }, + { _MMIO(0x9888), 0x109f02a8 }, + { _MMIO(0x9888), 0x0e9f0080 }, + { _MMIO(0x9888), 0x0cb84000 }, + { _MMIO(0x9888), 0x0cb95000 }, + { _MMIO(0x9888), 0x0eb95000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x258b8009 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x198c4000 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800c00 }, + { _MMIO(0x9888), 0x47800c63 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f8014a5 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800045 }, +}; + +static int +get_l3_3_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_3; + lens[n] = ARRAY_SIZE(mux_config_l3_3); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_4[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_4[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_4[] = { + { _MMIO(0x9888), 0x121a0340 }, + { _MMIO(0x9888), 0x103f0017 }, + { _MMIO(0x9888), 0x123f0020 }, + { _MMIO(0x9888), 0x129a0340 }, + { _MMIO(0x9888), 0x10bf0017 }, + { _MMIO(0x9888), 0x12bf0020 }, + { _MMIO(0x9888), 0x041a3400 }, + { _MMIO(0x9888), 0x101a0000 }, + { _MMIO(0x9888), 0x043b8000 }, + { _MMIO(0x9888), 0x0a3e0010 }, + { _MMIO(0x9888), 0x003f0200 }, + { _MMIO(0x9888), 0x023f0113 }, + { _MMIO(0x9888), 0x043f0014 }, + { _MMIO(0x9888), 0x02592000 }, + { _MMIO(0x9888), 0x005a8000 }, + { _MMIO(0x9888), 0x025ac000 }, + { _MMIO(0x9888), 0x045a4000 }, + { _MMIO(0x9888), 0x0a1c8000 }, + { _MMIO(0x9888), 0x001d8000 }, + { _MMIO(0x9888), 0x021dc000 }, + { _MMIO(0x9888), 0x041d4000 }, + { _MMIO(0x9888), 0x0a1e8000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f001a }, + { _MMIO(0x9888), 0x00394000 }, + { _MMIO(0x9888), 0x02395000 }, + { _MMIO(0x9888), 0x04391000 }, + { _MMIO(0x9888), 0x069a0034 }, + { _MMIO(0x9888), 0x109a0000 }, + { _MMIO(0x9888), 0x06bb4000 }, + { _MMIO(0x9888), 0x0abe0040 }, + { _MMIO(0x9888), 0x0cbf0984 }, + { _MMIO(0x9888), 0x0ebf0a02 }, + { _MMIO(0x9888), 0x02d94000 }, + { _MMIO(0x9888), 0x0cdac000 }, + { _MMIO(0x9888), 0x0edac000 }, + { _MMIO(0x9888), 0x0c9c0400 }, + { _MMIO(0x9888), 0x0c9dc000 }, + { _MMIO(0x9888), 0x0e9dc000 }, + { _MMIO(0x9888), 0x0c9e0400 }, + { _MMIO(0x9888), 0x109f02a8 }, + { _MMIO(0x9888), 0x0e9f0040 }, + { _MMIO(0x9888), 0x0cb95000 }, + { _MMIO(0x9888), 0x0eb95000 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x258b8009 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x198c4000 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185800a }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x1b830154 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x45800800 }, + { _MMIO(0x9888), 0x47800842 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f801084 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800044 }, +}; + +static int +get_l3_4_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_4; + lens[n] = ARRAY_SIZE(mux_config_l3_4); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00006000 }, + { _MMIO(0x2774), 0x0000f3ff }, + { _MMIO(0x2778), 0x00001800 }, + { _MMIO(0x277c), 0x0000fcff }, + { _MMIO(0x2780), 0x00000600 }, + { _MMIO(0x2784), 0x0000ff3f }, + { _MMIO(0x2788), 0x00000180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000060 }, + { _MMIO(0x2794), 0x0000fff3 }, + { _MMIO(0x2798), 0x00000018 }, + { _MMIO(0x279c), 0x0000fffc }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x143b000e }, + { _MMIO(0x9888), 0x043c55c0 }, + { _MMIO(0x9888), 0x0a1e0280 }, + { _MMIO(0x9888), 0x0c1e0408 }, + { _MMIO(0x9888), 0x10390000 }, + { _MMIO(0x9888), 0x12397a1f }, + { _MMIO(0x9888), 0x14bb000e }, + { _MMIO(0x9888), 0x04bc5000 }, + { _MMIO(0x9888), 0x0a9e0296 }, + { _MMIO(0x9888), 0x0c9e0008 }, + { _MMIO(0x9888), 0x10b90000 }, + { _MMIO(0x9888), 0x12b97a1f }, + { _MMIO(0x9888), 0x063b0042 }, + { _MMIO(0x9888), 0x103b0000 }, + { _MMIO(0x9888), 0x083c0000 }, + { _MMIO(0x9888), 0x0a3e0040 }, + { _MMIO(0x9888), 0x043f8000 }, + { _MMIO(0x9888), 0x02594000 }, + { _MMIO(0x9888), 0x045a8000 }, + { _MMIO(0x9888), 0x0c1c0400 }, + { _MMIO(0x9888), 0x041d8000 }, + { _MMIO(0x9888), 0x081e02c0 }, + { _MMIO(0x9888), 0x0e1e0000 }, + { _MMIO(0x9888), 0x0c1fa800 }, + { _MMIO(0x9888), 0x0e1f0260 }, + { _MMIO(0x9888), 0x101f0014 }, + { _MMIO(0x9888), 0x003905e0 }, + { _MMIO(0x9888), 0x06390bc0 }, + { _MMIO(0x9888), 0x02390018 }, + { _MMIO(0x9888), 0x04394000 }, + { _MMIO(0x9888), 0x04bb0042 }, + { _MMIO(0x9888), 0x10bb0000 }, + { _MMIO(0x9888), 0x02bc05c0 }, + { _MMIO(0x9888), 0x08bc0000 }, + { _MMIO(0x9888), 0x0abe0004 }, + { _MMIO(0x9888), 0x02bf8000 }, + { _MMIO(0x9888), 0x02d91000 }, + { _MMIO(0x9888), 0x02da8000 }, + { _MMIO(0x9888), 0x089c8000 }, + { _MMIO(0x9888), 0x029d8000 }, + { _MMIO(0x9888), 0x089e8000 }, + { _MMIO(0x9888), 0x0e9e0000 }, + { _MMIO(0x9888), 0x0e9fa806 }, + { _MMIO(0x9888), 0x109f0142 }, + { _MMIO(0x9888), 0x08b90617 }, + { _MMIO(0x9888), 0x0ab90be0 }, + { _MMIO(0x9888), 0x02b94000 }, + { _MMIO(0x9888), 0x0d88f000 }, + { _MMIO(0x9888), 0x0f88000c }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x018a8000 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x1b8a2800 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x238b52a0 }, + { _MMIO(0x9888), 0x258b6a95 }, + { _MMIO(0x9888), 0x278b0029 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c1500 }, + { _MMIO(0x9888), 0x1b8c0014 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x038d8000 }, + { _MMIO(0x9888), 0x058d2000 }, + { _MMIO(0x9888), 0x1f85aa80 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x01834000 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0184c000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1180c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x4d800444 }, + { _MMIO(0x9888), 0x3d800000 }, + { _MMIO(0x9888), 0x4f804000 }, + { _MMIO(0x9888), 0x43801080 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800084 }, + { _MMIO(0x9888), 0x53800044 }, + { _MMIO(0x9888), 0x47801080 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x3f800000 }, + { _MMIO(0x9888), 0x41800840 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler_1[] = { + { _MMIO(0x9888), 0x18921400 }, + { _MMIO(0x9888), 0x149500ab }, + { _MMIO(0x9888), 0x18b21400 }, + { _MMIO(0x9888), 0x14b500ab }, + { _MMIO(0x9888), 0x18d21400 }, + { _MMIO(0x9888), 0x14d500ab }, + { _MMIO(0x9888), 0x0cdc8000 }, + { _MMIO(0x9888), 0x0edc4000 }, + { _MMIO(0x9888), 0x02dcc000 }, + { _MMIO(0x9888), 0x04dcc000 }, + { _MMIO(0x9888), 0x1abd00a0 }, + { _MMIO(0x9888), 0x0abd8000 }, + { _MMIO(0x9888), 0x0cd88000 }, + { _MMIO(0x9888), 0x0ed84000 }, + { _MMIO(0x9888), 0x04d88000 }, + { _MMIO(0x9888), 0x1adb0050 }, + { _MMIO(0x9888), 0x04db8000 }, + { _MMIO(0x9888), 0x06db8000 }, + { _MMIO(0x9888), 0x08db8000 }, + { _MMIO(0x9888), 0x0adb4000 }, + { _MMIO(0x9888), 0x109f02a0 }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0e9f00aa }, + { _MMIO(0x9888), 0x18b82500 }, + { _MMIO(0x9888), 0x02b88000 }, + { _MMIO(0x9888), 0x04b84000 }, + { _MMIO(0x9888), 0x06b84000 }, + { _MMIO(0x9888), 0x08b84000 }, + { _MMIO(0x9888), 0x0ab84000 }, + { _MMIO(0x9888), 0x0cb88000 }, + { _MMIO(0x9888), 0x0cb98000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x00b98000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x04b9a000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x1aba0200 }, + { _MMIO(0x9888), 0x02ba8000 }, + { _MMIO(0x9888), 0x0cba8000 }, + { _MMIO(0x9888), 0x04908000 }, + { _MMIO(0x9888), 0x04918000 }, + { _MMIO(0x9888), 0x04927300 }, + { _MMIO(0x9888), 0x10920000 }, + { _MMIO(0x9888), 0x1893000a }, + { _MMIO(0x9888), 0x0a934000 }, + { _MMIO(0x9888), 0x0a946000 }, + { _MMIO(0x9888), 0x0c959000 }, + { _MMIO(0x9888), 0x0e950098 }, + { _MMIO(0x9888), 0x10950000 }, + { _MMIO(0x9888), 0x04b04000 }, + { _MMIO(0x9888), 0x04b14000 }, + { _MMIO(0x9888), 0x04b20073 }, + { _MMIO(0x9888), 0x10b20000 }, + { _MMIO(0x9888), 0x04b38000 }, + { _MMIO(0x9888), 0x06b38000 }, + { _MMIO(0x9888), 0x08b34000 }, + { _MMIO(0x9888), 0x04b4c000 }, + { _MMIO(0x9888), 0x02b59890 }, + { _MMIO(0x9888), 0x10b50000 }, + { _MMIO(0x9888), 0x06d04000 }, + { _MMIO(0x9888), 0x06d14000 }, + { _MMIO(0x9888), 0x06d20073 }, + { _MMIO(0x9888), 0x10d20000 }, + { _MMIO(0x9888), 0x18d30020 }, + { _MMIO(0x9888), 0x02d38000 }, + { _MMIO(0x9888), 0x0cd34000 }, + { _MMIO(0x9888), 0x0ad48000 }, + { _MMIO(0x9888), 0x04d42000 }, + { _MMIO(0x9888), 0x0ed59000 }, + { _MMIO(0x9888), 0x00d59800 }, + { _MMIO(0x9888), 0x10d50000 }, + { _MMIO(0x9888), 0x0f88000e }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b5500 }, + { _MMIO(0x9888), 0x258b000a }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x0d8d8000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x2185000a }, + { _MMIO(0x9888), 0x1b830150 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d848000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d808000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47801021 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800c64 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800c02 }, +}; + +static int +get_sampler_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler_1; + lens[n] = ARRAY_SIZE(mux_config_sampler_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler_2[] = { + { _MMIO(0x9888), 0x18121400 }, + { _MMIO(0x9888), 0x141500ab }, + { _MMIO(0x9888), 0x18321400 }, + { _MMIO(0x9888), 0x143500ab }, + { _MMIO(0x9888), 0x18521400 }, + { _MMIO(0x9888), 0x145500ab }, + { _MMIO(0x9888), 0x0c5c8000 }, + { _MMIO(0x9888), 0x0e5c4000 }, + { _MMIO(0x9888), 0x025cc000 }, + { _MMIO(0x9888), 0x045cc000 }, + { _MMIO(0x9888), 0x1a3d00a0 }, + { _MMIO(0x9888), 0x0a3d8000 }, + { _MMIO(0x9888), 0x0c588000 }, + { _MMIO(0x9888), 0x0e584000 }, + { _MMIO(0x9888), 0x04588000 }, + { _MMIO(0x9888), 0x1a5b0050 }, + { _MMIO(0x9888), 0x045b8000 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b8000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x101f02a0 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00aa }, + { _MMIO(0x9888), 0x18382500 }, + { _MMIO(0x9888), 0x02388000 }, + { _MMIO(0x9888), 0x04384000 }, + { _MMIO(0x9888), 0x06384000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0c388000 }, + { _MMIO(0x9888), 0x0c398000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x00398000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x1a3a0200 }, + { _MMIO(0x9888), 0x023a8000 }, + { _MMIO(0x9888), 0x0c3a8000 }, + { _MMIO(0x9888), 0x04108000 }, + { _MMIO(0x9888), 0x04118000 }, + { _MMIO(0x9888), 0x04127300 }, + { _MMIO(0x9888), 0x10120000 }, + { _MMIO(0x9888), 0x1813000a }, + { _MMIO(0x9888), 0x0a134000 }, + { _MMIO(0x9888), 0x0a146000 }, + { _MMIO(0x9888), 0x0c159000 }, + { _MMIO(0x9888), 0x0e150098 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x04304000 }, + { _MMIO(0x9888), 0x04314000 }, + { _MMIO(0x9888), 0x04320073 }, + { _MMIO(0x9888), 0x10320000 }, + { _MMIO(0x9888), 0x04338000 }, + { _MMIO(0x9888), 0x06338000 }, + { _MMIO(0x9888), 0x08334000 }, + { _MMIO(0x9888), 0x0434c000 }, + { _MMIO(0x9888), 0x02359890 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x06504000 }, + { _MMIO(0x9888), 0x06514000 }, + { _MMIO(0x9888), 0x06520073 }, + { _MMIO(0x9888), 0x10520000 }, + { _MMIO(0x9888), 0x18530020 }, + { _MMIO(0x9888), 0x02538000 }, + { _MMIO(0x9888), 0x0c534000 }, + { _MMIO(0x9888), 0x0a548000 }, + { _MMIO(0x9888), 0x04542000 }, + { _MMIO(0x9888), 0x0e559000 }, + { _MMIO(0x9888), 0x00559800 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x1b8aa000 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x258b0005 }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x2185000a }, + { _MMIO(0x9888), 0x1b830150 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0d848000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x07844000 }, + { _MMIO(0x9888), 0x1d808000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x17804000 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47801021 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800c64 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x41800c02 }, +}; + +static int +get_sampler_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler_2; + lens[n] = ARRAY_SIZE(mux_config_sampler_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x0000fe7f }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000ffbf }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fff7 }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fff9 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x16154d60 }, + { _MMIO(0x9888), 0x16352e60 }, + { _MMIO(0x9888), 0x16554d60 }, + { _MMIO(0x9888), 0x16950000 }, + { _MMIO(0x9888), 0x16b50000 }, + { _MMIO(0x9888), 0x16d50000 }, + { _MMIO(0x9888), 0x005c8000 }, + { _MMIO(0x9888), 0x045cc000 }, + { _MMIO(0x9888), 0x065c4000 }, + { _MMIO(0x9888), 0x083d8000 }, + { _MMIO(0x9888), 0x0a3d8000 }, + { _MMIO(0x9888), 0x0458c000 }, + { _MMIO(0x9888), 0x025b8000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x0c5b8000 }, + { _MMIO(0x9888), 0x0c1fa000 }, + { _MMIO(0x9888), 0x0e1f00aa }, + { _MMIO(0x9888), 0x02384000 }, + { _MMIO(0x9888), 0x04388000 }, + { _MMIO(0x9888), 0x06388000 }, + { _MMIO(0x9888), 0x08384000 }, + { _MMIO(0x9888), 0x0a384000 }, + { _MMIO(0x9888), 0x0c384000 }, + { _MMIO(0x9888), 0x00398000 }, + { _MMIO(0x9888), 0x0239a000 }, + { _MMIO(0x9888), 0x0439a000 }, + { _MMIO(0x9888), 0x06392000 }, + { _MMIO(0x9888), 0x043a8000 }, + { _MMIO(0x9888), 0x063a8000 }, + { _MMIO(0x9888), 0x08138000 }, + { _MMIO(0x9888), 0x0a138000 }, + { _MMIO(0x9888), 0x06143000 }, + { _MMIO(0x9888), 0x0415cfc7 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x02338000 }, + { _MMIO(0x9888), 0x0c338000 }, + { _MMIO(0x9888), 0x04342000 }, + { _MMIO(0x9888), 0x06344000 }, + { _MMIO(0x9888), 0x0035c700 }, + { _MMIO(0x9888), 0x063500cf }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x04538000 }, + { _MMIO(0x9888), 0x06538000 }, + { _MMIO(0x9888), 0x0454c000 }, + { _MMIO(0x9888), 0x0255cfc7 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x06dc8000 }, + { _MMIO(0x9888), 0x08dc4000 }, + { _MMIO(0x9888), 0x0cdcc000 }, + { _MMIO(0x9888), 0x0edcc000 }, + { _MMIO(0x9888), 0x1abd00a8 }, + { _MMIO(0x9888), 0x0cd8c000 }, + { _MMIO(0x9888), 0x0ed84000 }, + { _MMIO(0x9888), 0x0edb8000 }, + { _MMIO(0x9888), 0x18db0800 }, + { _MMIO(0x9888), 0x1adb0254 }, + { _MMIO(0x9888), 0x0e9faa00 }, + { _MMIO(0x9888), 0x109f02aa }, + { _MMIO(0x9888), 0x0eb84000 }, + { _MMIO(0x9888), 0x16b84000 }, + { _MMIO(0x9888), 0x18b8156a }, + { _MMIO(0x9888), 0x06b98000 }, + { _MMIO(0x9888), 0x08b9a000 }, + { _MMIO(0x9888), 0x0ab9a000 }, + { _MMIO(0x9888), 0x0cb9a000 }, + { _MMIO(0x9888), 0x0eb9a000 }, + { _MMIO(0x9888), 0x18baa000 }, + { _MMIO(0x9888), 0x1aba0002 }, + { _MMIO(0x9888), 0x16934000 }, + { _MMIO(0x9888), 0x1893000a }, + { _MMIO(0x9888), 0x0a947000 }, + { _MMIO(0x9888), 0x0c95c5c1 }, + { _MMIO(0x9888), 0x0e9500c3 }, + { _MMIO(0x9888), 0x10950000 }, + { _MMIO(0x9888), 0x0eb38000 }, + { _MMIO(0x9888), 0x16b30040 }, + { _MMIO(0x9888), 0x18b30020 }, + { _MMIO(0x9888), 0x06b48000 }, + { _MMIO(0x9888), 0x08b41000 }, + { _MMIO(0x9888), 0x0ab48000 }, + { _MMIO(0x9888), 0x06b5c500 }, + { _MMIO(0x9888), 0x08b500c3 }, + { _MMIO(0x9888), 0x0eb5c100 }, + { _MMIO(0x9888), 0x10b50000 }, + { _MMIO(0x9888), 0x16d31500 }, + { _MMIO(0x9888), 0x08d4e000 }, + { _MMIO(0x9888), 0x08d5c100 }, + { _MMIO(0x9888), 0x0ad5c3c5 }, + { _MMIO(0x9888), 0x10d50000 }, + { _MMIO(0x9888), 0x0d88f800 }, + { _MMIO(0x9888), 0x0f88000f }, + { _MMIO(0x9888), 0x038a8000 }, + { _MMIO(0x9888), 0x058a8000 }, + { _MMIO(0x9888), 0x078a8000 }, + { _MMIO(0x9888), 0x098a8000 }, + { _MMIO(0x9888), 0x0b8a8000 }, + { _MMIO(0x9888), 0x0d8a8000 }, + { _MMIO(0x9888), 0x258baaa5 }, + { _MMIO(0x9888), 0x278b002a }, + { _MMIO(0x9888), 0x238b2a80 }, + { _MMIO(0x9888), 0x0f8c4000 }, + { _MMIO(0x9888), 0x178c2000 }, + { _MMIO(0x9888), 0x198c5500 }, + { _MMIO(0x9888), 0x1b8c0015 }, + { _MMIO(0x9888), 0x078d8000 }, + { _MMIO(0x9888), 0x098da000 }, + { _MMIO(0x9888), 0x0b8da000 }, + { _MMIO(0x9888), 0x0d8da000 }, + { _MMIO(0x9888), 0x0f8da000 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800c42 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45800063 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x47800800 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f8014a4 }, + { _MMIO(0x9888), 0x41801042 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x0000fe7f }, + { _MMIO(0x2780), 0x00000000 }, + { _MMIO(0x2784), 0x0000ff9f }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000ffe7 }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fffb }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000fffd }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x16150000 }, + { _MMIO(0x9888), 0x16350000 }, + { _MMIO(0x9888), 0x16550000 }, + { _MMIO(0x9888), 0x16952e60 }, + { _MMIO(0x9888), 0x16b54d60 }, + { _MMIO(0x9888), 0x16d52e60 }, + { _MMIO(0x9888), 0x065c8000 }, + { _MMIO(0x9888), 0x085cc000 }, + { _MMIO(0x9888), 0x0a5cc000 }, + { _MMIO(0x9888), 0x0c5c4000 }, + { _MMIO(0x9888), 0x0e3d8000 }, + { _MMIO(0x9888), 0x183da000 }, + { _MMIO(0x9888), 0x06588000 }, + { _MMIO(0x9888), 0x08588000 }, + { _MMIO(0x9888), 0x0a584000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x185b5800 }, + { _MMIO(0x9888), 0x1a5b000a }, + { _MMIO(0x9888), 0x0e1faa00 }, + { _MMIO(0x9888), 0x101f02aa }, + { _MMIO(0x9888), 0x0e384000 }, + { _MMIO(0x9888), 0x16384000 }, + { _MMIO(0x9888), 0x18382a55 }, + { _MMIO(0x9888), 0x06398000 }, + { _MMIO(0x9888), 0x0839a000 }, + { _MMIO(0x9888), 0x0a39a000 }, + { _MMIO(0x9888), 0x0c39a000 }, + { _MMIO(0x9888), 0x0e39a000 }, + { _MMIO(0x9888), 0x1a3a02a0 }, + { _MMIO(0x9888), 0x0e138000 }, + { _MMIO(0x9888), 0x16130500 }, + { _MMIO(0x9888), 0x06148000 }, + { _MMIO(0x9888), 0x08146000 }, + { _MMIO(0x9888), 0x0615c100 }, + { _MMIO(0x9888), 0x0815c500 }, + { _MMIO(0x9888), 0x0a1500c3 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x16335040 }, + { _MMIO(0x9888), 0x08349000 }, + { _MMIO(0x9888), 0x0a341000 }, + { _MMIO(0x9888), 0x083500c1 }, + { _MMIO(0x9888), 0x0a35c500 }, + { _MMIO(0x9888), 0x0c3500c3 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x1853002a }, + { _MMIO(0x9888), 0x0a54e000 }, + { _MMIO(0x9888), 0x0c55c500 }, + { _MMIO(0x9888), 0x0e55c1c3 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x00dc8000 }, + { _MMIO(0x9888), 0x02dcc000 }, + { _MMIO(0x9888), 0x04dc4000 }, + { _MMIO(0x9888), 0x04bd8000 }, + { _MMIO(0x9888), 0x06bd8000 }, + { _MMIO(0x9888), 0x02d8c000 }, + { _MMIO(0x9888), 0x02db8000 }, + { _MMIO(0x9888), 0x04db4000 }, + { _MMIO(0x9888), 0x06db4000 }, + { _MMIO(0x9888), 0x08db8000 }, + { _MMIO(0x9888), 0x0c9fa000 }, + { _MMIO(0x9888), 0x0e9f00aa }, + { _MMIO(0x9888), 0x02b84000 }, + { _MMIO(0x9888), 0x04b84000 }, + { _MMIO(0x9888), 0x06b84000 }, + { _MMIO(0x9888), 0x08b84000 }, + { _MMIO(0x9888), 0x0ab88000 }, + { _MMIO(0x9888), 0x0cb88000 }, + { _MMIO(0x9888), 0x00b98000 }, + { _MMIO(0x9888), 0x02b9a000 }, + { _MMIO(0x9888), 0x04b9a000 }, + { _MMIO(0x9888), 0x06b92000 }, + { _MMIO(0x9888), 0x0aba8000 }, + { _MMIO(0x9888), 0x0cba8000 }, + { _MMIO(0x9888), 0x04938000 }, + { _MMIO(0x9888), 0x06938000 }, + { _MMIO(0x9888), 0x0494c000 }, + { _MMIO(0x9888), 0x0295cfc7 }, + { _MMIO(0x9888), 0x10950000 }, + { _MMIO(0x9888), 0x02b38000 }, + { _MMIO(0x9888), 0x08b38000 }, + { _MMIO(0x9888), 0x04b42000 }, + { _MMIO(0x9888), 0x06b41000 }, + { _MMIO(0x9888), 0x00b5c700 }, + { _MMIO(0x9888), 0x04b500cf }, + { _MMIO(0x9888), 0x10b50000 }, + { _MMIO(0x9888), 0x0ad38000 }, + { _MMIO(0x9888), 0x0cd38000 }, + { _MMIO(0x9888), 0x06d46000 }, + { _MMIO(0x9888), 0x04d5c700 }, + { _MMIO(0x9888), 0x06d500cf }, + { _MMIO(0x9888), 0x10d50000 }, + { _MMIO(0x9888), 0x03888000 }, + { _MMIO(0x9888), 0x05888000 }, + { _MMIO(0x9888), 0x07888000 }, + { _MMIO(0x9888), 0x09888000 }, + { _MMIO(0x9888), 0x0b888000 }, + { _MMIO(0x9888), 0x0d880400 }, + { _MMIO(0x9888), 0x0f8a8000 }, + { _MMIO(0x9888), 0x198a8000 }, + { _MMIO(0x9888), 0x1b8aaaa0 }, + { _MMIO(0x9888), 0x1d8a0002 }, + { _MMIO(0x9888), 0x258b555a }, + { _MMIO(0x9888), 0x278b0015 }, + { _MMIO(0x9888), 0x238b5500 }, + { _MMIO(0x9888), 0x038c4000 }, + { _MMIO(0x9888), 0x058c4000 }, + { _MMIO(0x9888), 0x078c4000 }, + { _MMIO(0x9888), 0x098c4000 }, + { _MMIO(0x9888), 0x0b8c4000 }, + { _MMIO(0x9888), 0x0d8c4000 }, + { _MMIO(0x9888), 0x018d8000 }, + { _MMIO(0x9888), 0x038da000 }, + { _MMIO(0x9888), 0x058da000 }, + { _MMIO(0x9888), 0x078d2000 }, + { _MMIO(0x9888), 0x2185aaaa }, + { _MMIO(0x9888), 0x2385002a }, + { _MMIO(0x9888), 0x1f85aa00 }, + { _MMIO(0x9888), 0x0f834000 }, + { _MMIO(0x9888), 0x19835400 }, + { _MMIO(0x9888), 0x1b830155 }, + { _MMIO(0x9888), 0x03834000 }, + { _MMIO(0x9888), 0x05834000 }, + { _MMIO(0x9888), 0x07834000 }, + { _MMIO(0x9888), 0x09834000 }, + { _MMIO(0x9888), 0x0b834000 }, + { _MMIO(0x9888), 0x0d834000 }, + { _MMIO(0x9888), 0x0784c000 }, + { _MMIO(0x9888), 0x0984c000 }, + { _MMIO(0x9888), 0x0b84c000 }, + { _MMIO(0x9888), 0x0d84c000 }, + { _MMIO(0x9888), 0x0f84c000 }, + { _MMIO(0x9888), 0x01848000 }, + { _MMIO(0x9888), 0x0384c000 }, + { _MMIO(0x9888), 0x0584c000 }, + { _MMIO(0x9888), 0x1780c000 }, + { _MMIO(0x9888), 0x1980c000 }, + { _MMIO(0x9888), 0x1b80c000 }, + { _MMIO(0x9888), 0x1d80c000 }, + { _MMIO(0x9888), 0x1f80c000 }, + { _MMIO(0x9888), 0x11808000 }, + { _MMIO(0x9888), 0x1380c000 }, + { _MMIO(0x9888), 0x1580c000 }, + { _MMIO(0x9888), 0x4f800000 }, + { _MMIO(0x9888), 0x43800882 }, + { _MMIO(0x9888), 0x51800000 }, + { _MMIO(0x9888), 0x45801082 }, + { _MMIO(0x9888), 0x53800000 }, + { _MMIO(0x9888), 0x478014a5 }, + { _MMIO(0x9888), 0x21800000 }, + { _MMIO(0x9888), 0x31800000 }, + { _MMIO(0x9888), 0x4d800000 }, + { _MMIO(0x9888), 0x3f800002 }, + { _MMIO(0x9888), 0x41800c62 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x59800000 }, + { _MMIO(0x9888), 0x59800001 }, + { _MMIO(0x9888), 0x338b0000 }, + { _MMIO(0x9888), 0x258b0066 }, + { _MMIO(0x9888), 0x058b0000 }, + { _MMIO(0x9888), 0x038b0000 }, + { _MMIO(0x9888), 0x03844000 }, + { _MMIO(0x9888), 0x47800080 }, + { _MMIO(0x9888), 0x57800000 }, + { _MMIO(0x1823a4), 0x00000000 }, + { _MMIO(0x9888), 0x59800000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_chv(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_L3_2: + dev_priv->perf.oa.n_mux_configs = + get_l3_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_2); + + return 0; + case METRIC_SET_ID_L3_3: + dev_priv->perf.oa.n_mux_configs = + get_l3_3_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_3; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_3); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_3; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_3); + + return 0; + case METRIC_SET_ID_L3_4: + dev_priv->perf.oa.n_mux_configs = + get_l3_4_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_4\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_4; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_4); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_4; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_4); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER_1: + dev_priv->perf.oa.n_mux_configs = + get_sampler_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler_1); + + return 0; + case METRIC_SET_ID_SAMPLER_2: + dev_priv->perf.oa.n_mux_configs = + get_sampler_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler_2); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "9d8a3af5-c02c-4a4a-b947-f1672469e0fb", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "f522a89c-ecd1-4522-8331-3383c54af5f5", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "a9ccc03d-a943-4e6b-9cd6-13e063075927", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "2cf0c064-68df-4fac-9b3f-57f51ca8a069", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "78a87ff9-543a-49ce-95ea-26d86071ea93", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2); +} + +static struct device_attribute dev_attr_l3_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_2_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_2[] = { + &dev_attr_l3_2_id.attr, + NULL, +}; + +static struct attribute_group group_l3_2 = { + .name = "9f2cece5-7bfe-4320-ad66-8c7cc526bec5", + .attrs = attrs_l3_2, +}; + +static ssize_t +show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3); +} + +static struct device_attribute dev_attr_l3_3_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_3_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_3[] = { + &dev_attr_l3_3_id.attr, + NULL, +}; + +static struct attribute_group group_l3_3 = { + .name = "d890ef38-d309-47e4-b8b5-aa779bb19ab0", + .attrs = attrs_l3_3, +}; + +static ssize_t +show_l3_4_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_4); +} + +static struct device_attribute dev_attr_l3_4_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_4_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_4[] = { + &dev_attr_l3_4_id.attr, + NULL, +}; + +static struct attribute_group group_l3_4 = { + .name = "5fdff4a6-9dc8-45e1-bfda-ef54869fbdd4", + .attrs = attrs_l3_4, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "2c0e45e1-7e2c-4a14-ae00-0b7ec868b8aa", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_1); +} + +static struct device_attribute dev_attr_sampler_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_1_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler_1[] = { + &dev_attr_sampler_1_id.attr, + NULL, +}; + +static struct attribute_group group_sampler_1 = { + .name = "71148d78-baf5-474f-878a-e23158d0265d", + .attrs = attrs_sampler_1, +}; + +static ssize_t +show_sampler_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_2); +} + +static struct device_attribute dev_attr_sampler_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_2_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler_2[] = { + &dev_attr_sampler_2_id.attr, + NULL, +}; + +static struct attribute_group group_sampler_2 = { + .name = "b996a2b7-c59c-492d-877a-8cd54fd6df84", + .attrs = attrs_sampler_2, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "eb2fecba-b431-42e7-8261-fe9429a6e67a", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "60749470-a648-4a4b-9f10-dbfe1e36e44d", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "4a534b07-cba3-414d-8d60-874830e883aa", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_chv(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (ret) + goto error_l3_2; + } + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (ret) + goto error_l3_3; + } + if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_4); + if (ret) + goto error_l3_4; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_1); + if (ret) + goto error_sampler_1; + } + if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_2); + if (ret) + goto error_sampler_2; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2); +error_sampler_2: + if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1); +error_sampler_1: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4); +error_l3_4: + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); +error_l3_3: + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); +error_l3_2: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_chv(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1); + if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_chv.h b/drivers/gpu/drm/i915/i915_oa_chv.h new file mode 100644 index 0000000..8b8bdc2 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_chv.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_CHV_H__ +#define __I915_OA_CHV_H__ + +extern int i915_oa_n_builtin_metric_sets_chv; + +extern int i915_oa_select_metric_set_chv(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_chv(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_chv(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_glk.c b/drivers/gpu/drm/i915/i915_oa_glk.c new file mode 100644 index 0000000..2f356d5 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_glk.c @@ -0,0 +1,2602 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_glk.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_glk = 15; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic[] = { + { _MMIO(0x9888), 0x166c00f0 }, + { _MMIO(0x9888), 0x12120280 }, + { _MMIO(0x9888), 0x12320280 }, + { _MMIO(0x9888), 0x11930317 }, + { _MMIO(0x9888), 0x159303df }, + { _MMIO(0x9888), 0x3f900c00 }, + { _MMIO(0x9888), 0x419000a0 }, + { _MMIO(0x9888), 0x002d1000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d5000 }, + { _MMIO(0x9888), 0x0a2d1000 }, + { _MMIO(0x9888), 0x0c2e0800 }, + { _MMIO(0x9888), 0x0e2e5900 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4c8000 }, + { _MMIO(0x9888), 0x0e4c4000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e2000 }, + { _MMIO(0x9888), 0x1c4f0010 }, + { _MMIO(0x9888), 0x0a6c0053 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1a0fcc00 }, + { _MMIO(0x9888), 0x1c0f0002 }, + { _MMIO(0x9888), 0x1c2c0040 }, + { _MMIO(0x9888), 0x00101000 }, + { _MMIO(0x9888), 0x04101000 }, + { _MMIO(0x9888), 0x00114000 }, + { _MMIO(0x9888), 0x08114000 }, + { _MMIO(0x9888), 0x00120020 }, + { _MMIO(0x9888), 0x08120021 }, + { _MMIO(0x9888), 0x00141000 }, + { _MMIO(0x9888), 0x08141000 }, + { _MMIO(0x9888), 0x02308000 }, + { _MMIO(0x9888), 0x04302000 }, + { _MMIO(0x9888), 0x06318000 }, + { _MMIO(0x9888), 0x08318000 }, + { _MMIO(0x9888), 0x06320800 }, + { _MMIO(0x9888), 0x08320840 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x06344000 }, + { _MMIO(0x9888), 0x08344000 }, + { _MMIO(0x9888), 0x0d931831 }, + { _MMIO(0x9888), 0x0f939f3f }, + { _MMIO(0x9888), 0x01939e80 }, + { _MMIO(0x9888), 0x039303bc }, + { _MMIO(0x9888), 0x0593000e }, + { _MMIO(0x9888), 0x1993002a }, + { _MMIO(0x9888), 0x07930000 }, + { _MMIO(0x9888), 0x09930000 }, + { _MMIO(0x9888), 0x1d900177 }, + { _MMIO(0x9888), 0x1f900187 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x53901110 }, + { _MMIO(0x9888), 0x43900423 }, + { _MMIO(0x9888), 0x55900111 }, + { _MMIO(0x9888), 0x47900c02 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900020 }, + { _MMIO(0x9888), 0x59901111 }, + { _MMIO(0x9888), 0x4b900421 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x45900821 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_basic; + lens[n] = ARRAY_SIZE(mux_config_render_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x39900340 }, + { _MMIO(0x9888), 0x3f900c00 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x002d5000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d4000 }, + { _MMIO(0x9888), 0x0a2d1000 }, + { _MMIO(0x9888), 0x0c2d5000 }, + { _MMIO(0x9888), 0x0e2d4000 }, + { _MMIO(0x9888), 0x0c2e1400 }, + { _MMIO(0x9888), 0x0e2e5100 }, + { _MMIO(0x9888), 0x102e0114 }, + { _MMIO(0x9888), 0x044cc000 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4c8000 }, + { _MMIO(0x9888), 0x0e4c4000 }, + { _MMIO(0x9888), 0x104c8000 }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x004ea000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e2000 }, + { _MMIO(0x9888), 0x0c4ea000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x004f6b42 }, + { _MMIO(0x9888), 0x064f6200 }, + { _MMIO(0x9888), 0x084f4100 }, + { _MMIO(0x9888), 0x0a4f0061 }, + { _MMIO(0x9888), 0x0c4f6c4c }, + { _MMIO(0x9888), 0x0e4f4b00 }, + { _MMIO(0x9888), 0x1a4f0000 }, + { _MMIO(0x9888), 0x1c4f0000 }, + { _MMIO(0x9888), 0x180f5000 }, + { _MMIO(0x9888), 0x1a0f8800 }, + { _MMIO(0x9888), 0x1c0f08a2 }, + { _MMIO(0x9888), 0x182c4000 }, + { _MMIO(0x9888), 0x1c2c1451 }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x1a2c0010 }, + { _MMIO(0x9888), 0x01938000 }, + { _MMIO(0x9888), 0x0f938000 }, + { _MMIO(0x9888), 0x19938a28 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x19900177 }, + { _MMIO(0x9888), 0x1b900178 }, + { _MMIO(0x9888), 0x1d900125 }, + { _MMIO(0x9888), 0x1f900123 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x53901000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x55900111 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x45900000 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x0c2e001f }, + { _MMIO(0x9888), 0x0a2f0000 }, + { _MMIO(0x9888), 0x10186800 }, + { _MMIO(0x9888), 0x11810019 }, + { _MMIO(0x9888), 0x15810013 }, + { _MMIO(0x9888), 0x13820020 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x17840000 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x21860000 }, + { _MMIO(0x9888), 0x178703e0 }, + { _MMIO(0x9888), 0x0c2d8000 }, + { _MMIO(0x9888), 0x042d4000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x022e5400 }, + { _MMIO(0x9888), 0x002e0000 }, + { _MMIO(0x9888), 0x0e2e0080 }, + { _MMIO(0x9888), 0x082f0040 }, + { _MMIO(0x9888), 0x002f0000 }, + { _MMIO(0x9888), 0x06143000 }, + { _MMIO(0x9888), 0x06174000 }, + { _MMIO(0x9888), 0x06180012 }, + { _MMIO(0x9888), 0x00180000 }, + { _MMIO(0x9888), 0x0d804000 }, + { _MMIO(0x9888), 0x0f804000 }, + { _MMIO(0x9888), 0x05804000 }, + { _MMIO(0x9888), 0x09810200 }, + { _MMIO(0x9888), 0x0b810030 }, + { _MMIO(0x9888), 0x03810003 }, + { _MMIO(0x9888), 0x21819140 }, + { _MMIO(0x9888), 0x23819050 }, + { _MMIO(0x9888), 0x25810018 }, + { _MMIO(0x9888), 0x0b820980 }, + { _MMIO(0x9888), 0x03820d80 }, + { _MMIO(0x9888), 0x11820000 }, + { _MMIO(0x9888), 0x0182c000 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x09824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x0d830004 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x0f831000 }, + { _MMIO(0x9888), 0x01848072 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x07848000 }, + { _MMIO(0x9888), 0x09844000 }, + { _MMIO(0x9888), 0x0f848000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x09860092 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x01869100 }, + { _MMIO(0x9888), 0x0f870065 }, + { _MMIO(0x9888), 0x01870000 }, + { _MMIO(0x9888), 0x19930800 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x1b952000 }, + { _MMIO(0x9888), 0x1d955055 }, + { _MMIO(0x9888), 0x1f951455 }, + { _MMIO(0x9888), 0x0992a000 }, + { _MMIO(0x9888), 0x0f928000 }, + { _MMIO(0x9888), 0x1192a800 }, + { _MMIO(0x9888), 0x1392028a }, + { _MMIO(0x9888), 0x0b92a000 }, + { _MMIO(0x9888), 0x0d922000 }, + { _MMIO(0x9888), 0x13908000 }, + { _MMIO(0x9888), 0x21908000 }, + { _MMIO(0x9888), 0x23908000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27908000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x15908000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900c01 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900863 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900061 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x45900c22 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads[] = { + { _MMIO(0x9888), 0x19800343 }, + { _MMIO(0x9888), 0x39900340 }, + { _MMIO(0x9888), 0x3f901000 }, + { _MMIO(0x9888), 0x41900003 }, + { _MMIO(0x9888), 0x03803180 }, + { _MMIO(0x9888), 0x058035e2 }, + { _MMIO(0x9888), 0x0780006a }, + { _MMIO(0x9888), 0x11800000 }, + { _MMIO(0x9888), 0x2181a000 }, + { _MMIO(0x9888), 0x2381000a }, + { _MMIO(0x9888), 0x1d950550 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d92a000 }, + { _MMIO(0x9888), 0x0f922000 }, + { _MMIO(0x9888), 0x13900170 }, + { _MMIO(0x9888), 0x21900171 }, + { _MMIO(0x9888), 0x23900172 }, + { _MMIO(0x9888), 0x25900173 }, + { _MMIO(0x9888), 0x27900174 }, + { _MMIO(0x9888), 0x29900175 }, + { _MMIO(0x9888), 0x2b900176 }, + { _MMIO(0x9888), 0x2d900177 }, + { _MMIO(0x9888), 0x2f90017f }, + { _MMIO(0x9888), 0x31900125 }, + { _MMIO(0x9888), 0x15900123 }, + { _MMIO(0x9888), 0x17900121 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43901084 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47901080 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49901084 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b901084 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900004 }, + { _MMIO(0x9888), 0x45900000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes[] = { + { _MMIO(0x9888), 0x19800343 }, + { _MMIO(0x9888), 0x39900340 }, + { _MMIO(0x9888), 0x3f900000 }, + { _MMIO(0x9888), 0x41900080 }, + { _MMIO(0x9888), 0x03803180 }, + { _MMIO(0x9888), 0x058035e2 }, + { _MMIO(0x9888), 0x0780006a }, + { _MMIO(0x9888), 0x11800000 }, + { _MMIO(0x9888), 0x2181a000 }, + { _MMIO(0x9888), 0x2381000a }, + { _MMIO(0x9888), 0x1d950550 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d92a000 }, + { _MMIO(0x9888), 0x0f922000 }, + { _MMIO(0x9888), 0x13900180 }, + { _MMIO(0x9888), 0x21900181 }, + { _MMIO(0x9888), 0x23900182 }, + { _MMIO(0x9888), 0x25900183 }, + { _MMIO(0x9888), 0x27900184 }, + { _MMIO(0x9888), 0x29900185 }, + { _MMIO(0x9888), 0x2b900186 }, + { _MMIO(0x9888), 0x2d900187 }, + { _MMIO(0x9888), 0x2f900170 }, + { _MMIO(0x9888), 0x31900125 }, + { _MMIO(0x9888), 0x15900123 }, + { _MMIO(0x9888), 0x17900121 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43901084 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47901080 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49901084 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b901084 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900004 }, + { _MMIO(0x9888), 0x45900000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x141c0160 }, + { _MMIO(0x9888), 0x161c0015 }, + { _MMIO(0x9888), 0x181c0120 }, + { _MMIO(0x9888), 0x002d5000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d5000 }, + { _MMIO(0x9888), 0x0a2d5000 }, + { _MMIO(0x9888), 0x0c2d5000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x0c2e5400 }, + { _MMIO(0x9888), 0x0e2e5515 }, + { _MMIO(0x9888), 0x102e0155 }, + { _MMIO(0x9888), 0x044cc000 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4cc000 }, + { _MMIO(0x9888), 0x0e4cc000 }, + { _MMIO(0x9888), 0x104c8000 }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x004ea000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084ea000 }, + { _MMIO(0x9888), 0x0a4ea000 }, + { _MMIO(0x9888), 0x0c4ea000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x0e4f4b41 }, + { _MMIO(0x9888), 0x004f4200 }, + { _MMIO(0x9888), 0x024f404c }, + { _MMIO(0x9888), 0x1c4f0000 }, + { _MMIO(0x9888), 0x1a4f0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x061b8000 }, + { _MMIO(0x9888), 0x081bc000 }, + { _MMIO(0x9888), 0x0a1bc000 }, + { _MMIO(0x9888), 0x0c1bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x001c0031 }, + { _MMIO(0x9888), 0x061c1900 }, + { _MMIO(0x9888), 0x081c1a33 }, + { _MMIO(0x9888), 0x0a1c1b35 }, + { _MMIO(0x9888), 0x0c1c3337 }, + { _MMIO(0x9888), 0x041c31c7 }, + { _MMIO(0x9888), 0x180f5000 }, + { _MMIO(0x9888), 0x1a0fa8aa }, + { _MMIO(0x9888), 0x1c0f0aaa }, + { _MMIO(0x9888), 0x182c8000 }, + { _MMIO(0x9888), 0x1c2c6aaa }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x1a2c2950 }, + { _MMIO(0x9888), 0x01938000 }, + { _MMIO(0x9888), 0x0f938000 }, + { _MMIO(0x9888), 0x1993aaaa }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29904000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900420 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900400 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x45900001 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extended; + lens[n] = ARRAY_SIZE(mux_config_compute_extended); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x166c03b0 }, + { _MMIO(0x9888), 0x1593001e }, + { _MMIO(0x9888), 0x3f900c00 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x002d1000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x082d5000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x0c2e0400 }, + { _MMIO(0x9888), 0x0e2e1500 }, + { _MMIO(0x9888), 0x102e0140 }, + { _MMIO(0x9888), 0x044c4000 }, + { _MMIO(0x9888), 0x0a4c8000 }, + { _MMIO(0x9888), 0x0c4cc000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x004e2000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084ea000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x1a4f4001 }, + { _MMIO(0x9888), 0x1c4f5005 }, + { _MMIO(0x9888), 0x006c0051 }, + { _MMIO(0x9888), 0x066c5000 }, + { _MMIO(0x9888), 0x086c5c5d }, + { _MMIO(0x9888), 0x0e6c5e5f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x146c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x180f1000 }, + { _MMIO(0x9888), 0x1a0fa800 }, + { _MMIO(0x9888), 0x1c0f0a00 }, + { _MMIO(0x9888), 0x182c4000 }, + { _MMIO(0x9888), 0x1c2c4015 }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x03931980 }, + { _MMIO(0x9888), 0x05930032 }, + { _MMIO(0x9888), 0x11930000 }, + { _MMIO(0x9888), 0x01938000 }, + { _MMIO(0x9888), 0x0f938000 }, + { _MMIO(0x9888), 0x1993a00a }, + { _MMIO(0x9888), 0x07930000 }, + { _MMIO(0x9888), 0x09930000 }, + { _MMIO(0x9888), 0x1d900177 }, + { _MMIO(0x9888), 0x1f900178 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x53901000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x55900111 }, + { _MMIO(0x9888), 0x47900001 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x45900400 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x104f0232 }, + { _MMIO(0x9888), 0x124f4640 }, + { _MMIO(0x9888), 0x11834400 }, + { _MMIO(0x9888), 0x022d4000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0e2e0055 }, + { _MMIO(0x9888), 0x064c8000 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x024f6100 }, + { _MMIO(0x9888), 0x044f416b }, + { _MMIO(0x9888), 0x064f004b }, + { _MMIO(0x9888), 0x1a4f0000 }, + { _MMIO(0x9888), 0x1a0f02a8 }, + { _MMIO(0x9888), 0x1a2c5500 }, + { _MMIO(0x9888), 0x0f808000 }, + { _MMIO(0x9888), 0x25810020 }, + { _MMIO(0x9888), 0x0f8305c0 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x1f951000 }, + { _MMIO(0x9888), 0x13920200 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4d900003 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x12643400 }, + { _MMIO(0x9888), 0x12653400 }, + { _MMIO(0x9888), 0x106c6800 }, + { _MMIO(0x9888), 0x126c001e }, + { _MMIO(0x9888), 0x166c0010 }, + { _MMIO(0x9888), 0x0c2d5000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x102e0154 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e0055 }, + { _MMIO(0x9888), 0x104c8000 }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x0c4ea000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x1c4f5500 }, + { _MMIO(0x9888), 0x1a4f1554 }, + { _MMIO(0x9888), 0x0a640024 }, + { _MMIO(0x9888), 0x10640000 }, + { _MMIO(0x9888), 0x04640000 }, + { _MMIO(0x9888), 0x0c650024 }, + { _MMIO(0x9888), 0x10650000 }, + { _MMIO(0x9888), 0x06650000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1a6c0900 }, + { _MMIO(0x9888), 0x1c0f0aa0 }, + { _MMIO(0x9888), 0x180f4000 }, + { _MMIO(0x9888), 0x1a0f02aa }, + { _MMIO(0x9888), 0x1c2c5400 }, + { _MMIO(0x9888), 0x1e2c0001 }, + { _MMIO(0x9888), 0x1a2c5550 }, + { _MMIO(0x9888), 0x1993aa00 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900421 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900420 }, + { _MMIO(0x9888), 0x45900021 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000efff }, + { _MMIO(0x2778), 0x00006000 }, + { _MMIO(0x277c), 0x0000f3ff }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x102d7800 }, + { _MMIO(0x9888), 0x122d79e0 }, + { _MMIO(0x9888), 0x0c2f0004 }, + { _MMIO(0x9888), 0x100e3800 }, + { _MMIO(0x9888), 0x180f0005 }, + { _MMIO(0x9888), 0x002d0940 }, + { _MMIO(0x9888), 0x022d802f }, + { _MMIO(0x9888), 0x042d4013 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0e2e0050 }, + { _MMIO(0x9888), 0x022f0010 }, + { _MMIO(0x9888), 0x002f0000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x040e0480 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x060f0027 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x1a0f0040 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x439014a0 }, + { _MMIO(0x9888), 0x459000a4 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler[] = { + { _MMIO(0x9888), 0x121300a0 }, + { _MMIO(0x9888), 0x141600ab }, + { _MMIO(0x9888), 0x123300a0 }, + { _MMIO(0x9888), 0x143600ab }, + { _MMIO(0x9888), 0x125300a0 }, + { _MMIO(0x9888), 0x145600ab }, + { _MMIO(0x9888), 0x0c2d4000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x102e01a0 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e0065 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x084c4000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x044e2000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x1c0f0800 }, + { _MMIO(0x9888), 0x180f4000 }, + { _MMIO(0x9888), 0x1a0f023f }, + { _MMIO(0x9888), 0x1e2c0003 }, + { _MMIO(0x9888), 0x1a2cc030 }, + { _MMIO(0x9888), 0x04132180 }, + { _MMIO(0x9888), 0x02130000 }, + { _MMIO(0x9888), 0x0c148000 }, + { _MMIO(0x9888), 0x0e142000 }, + { _MMIO(0x9888), 0x04148000 }, + { _MMIO(0x9888), 0x1e150140 }, + { _MMIO(0x9888), 0x1c150040 }, + { _MMIO(0x9888), 0x0c163000 }, + { _MMIO(0x9888), 0x0e160068 }, + { _MMIO(0x9888), 0x10160000 }, + { _MMIO(0x9888), 0x18160000 }, + { _MMIO(0x9888), 0x0a164000 }, + { _MMIO(0x9888), 0x04330043 }, + { _MMIO(0x9888), 0x02330000 }, + { _MMIO(0x9888), 0x0234a000 }, + { _MMIO(0x9888), 0x04342000 }, + { _MMIO(0x9888), 0x1c350015 }, + { _MMIO(0x9888), 0x02363460 }, + { _MMIO(0x9888), 0x10360000 }, + { _MMIO(0x9888), 0x04360000 }, + { _MMIO(0x9888), 0x06360000 }, + { _MMIO(0x9888), 0x08364000 }, + { _MMIO(0x9888), 0x06530043 }, + { _MMIO(0x9888), 0x02530000 }, + { _MMIO(0x9888), 0x0e548000 }, + { _MMIO(0x9888), 0x00548000 }, + { _MMIO(0x9888), 0x06542000 }, + { _MMIO(0x9888), 0x1e550400 }, + { _MMIO(0x9888), 0x1a552000 }, + { _MMIO(0x9888), 0x1c550100 }, + { _MMIO(0x9888), 0x0e563000 }, + { _MMIO(0x9888), 0x00563400 }, + { _MMIO(0x9888), 0x10560000 }, + { _MMIO(0x9888), 0x18560000 }, + { _MMIO(0x9888), 0x02560000 }, + { _MMIO(0x9888), 0x0c564000 }, + { _MMIO(0x9888), 0x1993a800 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b9014a0 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900001 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900820 }, + { _MMIO(0x9888), 0x45901022 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, +}; + +static int +get_sampler_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler; + lens[n] = ARRAY_SIZE(mux_config_sampler); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x00007fff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x00009fff }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000efff }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000f3ff }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fdff }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x141a0000 }, + { _MMIO(0x9888), 0x143a0000 }, + { _MMIO(0x9888), 0x145a0000 }, + { _MMIO(0x9888), 0x0c2d4000 }, + { _MMIO(0x9888), 0x0e2d5000 }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x102e0150 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e006a }, + { _MMIO(0x9888), 0x124c8000 }, + { _MMIO(0x9888), 0x144c8000 }, + { _MMIO(0x9888), 0x164c2000 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064c4000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x0e4ea000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024e2000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x1c0f0bc0 }, + { _MMIO(0x9888), 0x180f4000 }, + { _MMIO(0x9888), 0x1a0f0302 }, + { _MMIO(0x9888), 0x1e2c0003 }, + { _MMIO(0x9888), 0x1a2c00f0 }, + { _MMIO(0x9888), 0x021a3080 }, + { _MMIO(0x9888), 0x041a31e5 }, + { _MMIO(0x9888), 0x02148000 }, + { _MMIO(0x9888), 0x0414a000 }, + { _MMIO(0x9888), 0x1c150054 }, + { _MMIO(0x9888), 0x06168000 }, + { _MMIO(0x9888), 0x08168000 }, + { _MMIO(0x9888), 0x0a168000 }, + { _MMIO(0x9888), 0x0c3a3280 }, + { _MMIO(0x9888), 0x0e3a0063 }, + { _MMIO(0x9888), 0x063a0061 }, + { _MMIO(0x9888), 0x023a0000 }, + { _MMIO(0x9888), 0x0c348000 }, + { _MMIO(0x9888), 0x0e342000 }, + { _MMIO(0x9888), 0x06342000 }, + { _MMIO(0x9888), 0x1e350140 }, + { _MMIO(0x9888), 0x1c350100 }, + { _MMIO(0x9888), 0x18360028 }, + { _MMIO(0x9888), 0x0c368000 }, + { _MMIO(0x9888), 0x0e5a3080 }, + { _MMIO(0x9888), 0x005a3280 }, + { _MMIO(0x9888), 0x025a0063 }, + { _MMIO(0x9888), 0x0e548000 }, + { _MMIO(0x9888), 0x00548000 }, + { _MMIO(0x9888), 0x02542000 }, + { _MMIO(0x9888), 0x1e550400 }, + { _MMIO(0x9888), 0x1a552000 }, + { _MMIO(0x9888), 0x1c550001 }, + { _MMIO(0x9888), 0x18560080 }, + { _MMIO(0x9888), 0x02568000 }, + { _MMIO(0x9888), 0x04568000 }, + { _MMIO(0x9888), 0x1993a800 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x2d904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900420 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4d900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x45901084 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900001 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x141a026b }, + { _MMIO(0x9888), 0x143a0173 }, + { _MMIO(0x9888), 0x145a026b }, + { _MMIO(0x9888), 0x002d4000 }, + { _MMIO(0x9888), 0x022d5000 }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0c2e5000 }, + { _MMIO(0x9888), 0x0e2e0069 }, + { _MMIO(0x9888), 0x044c8000 }, + { _MMIO(0x9888), 0x064cc000 }, + { _MMIO(0x9888), 0x0a4c4000 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x024ea000 }, + { _MMIO(0x9888), 0x064e2000 }, + { _MMIO(0x9888), 0x180f6000 }, + { _MMIO(0x9888), 0x1a0f030a }, + { _MMIO(0x9888), 0x1a2c03c0 }, + { _MMIO(0x9888), 0x041a37e7 }, + { _MMIO(0x9888), 0x021a0000 }, + { _MMIO(0x9888), 0x0414a000 }, + { _MMIO(0x9888), 0x1c150050 }, + { _MMIO(0x9888), 0x08168000 }, + { _MMIO(0x9888), 0x0a168000 }, + { _MMIO(0x9888), 0x003a3380 }, + { _MMIO(0x9888), 0x063a006f }, + { _MMIO(0x9888), 0x023a0000 }, + { _MMIO(0x9888), 0x00348000 }, + { _MMIO(0x9888), 0x06342000 }, + { _MMIO(0x9888), 0x1a352000 }, + { _MMIO(0x9888), 0x1c350100 }, + { _MMIO(0x9888), 0x02368000 }, + { _MMIO(0x9888), 0x0c368000 }, + { _MMIO(0x9888), 0x025a37e7 }, + { _MMIO(0x9888), 0x0254a000 }, + { _MMIO(0x9888), 0x1c550005 }, + { _MMIO(0x9888), 0x04568000 }, + { _MMIO(0x9888), 0x06568000 }, + { _MMIO(0x9888), 0x03938000 }, + { _MMIO(0x9888), 0x05938000 }, + { _MMIO(0x9888), 0x07938000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17904000 }, + { _MMIO(0x9888), 0x19904000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900020 }, + { _MMIO(0x9888), 0x45901080 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { + { _MMIO(0xe458), 0x00001000 }, + { _MMIO(0xe558), 0x00003002 }, + { _MMIO(0xe658), 0x00005004 }, + { _MMIO(0xe758), 0x00011010 }, + { _MMIO(0xe45c), 0x00050012 }, + { _MMIO(0xe55c), 0x00052051 }, + { _MMIO(0xe65c), 0x00000008 }, +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x141a001f }, + { _MMIO(0x9888), 0x143a001f }, + { _MMIO(0x9888), 0x145a001f }, + { _MMIO(0x9888), 0x042d5000 }, + { _MMIO(0x9888), 0x062d1000 }, + { _MMIO(0x9888), 0x0e2e0094 }, + { _MMIO(0x9888), 0x084cc000 }, + { _MMIO(0x9888), 0x044ea000 }, + { _MMIO(0x9888), 0x1a0f00e0 }, + { _MMIO(0x9888), 0x1a2c0c00 }, + { _MMIO(0x9888), 0x061a0063 }, + { _MMIO(0x9888), 0x021a0000 }, + { _MMIO(0x9888), 0x06142000 }, + { _MMIO(0x9888), 0x1c150100 }, + { _MMIO(0x9888), 0x0c168000 }, + { _MMIO(0x9888), 0x043a3180 }, + { _MMIO(0x9888), 0x023a0000 }, + { _MMIO(0x9888), 0x04348000 }, + { _MMIO(0x9888), 0x1c350040 }, + { _MMIO(0x9888), 0x0a368000 }, + { _MMIO(0x9888), 0x045a0063 }, + { _MMIO(0x9888), 0x025a0000 }, + { _MMIO(0x9888), 0x04542000 }, + { _MMIO(0x9888), 0x1c550010 }, + { _MMIO(0x9888), 0x08568000 }, + { _MMIO(0x9888), 0x09938000 }, + { _MMIO(0x9888), 0x0b938000 }, + { _MMIO(0x9888), 0x0d938000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1d904000 }, + { _MMIO(0x9888), 0x1f904000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x47900004 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x19800000 }, + { _MMIO(0x9888), 0x07800063 }, + { _MMIO(0x9888), 0x11800000 }, + { _MMIO(0x9888), 0x23810008 }, + { _MMIO(0x9888), 0x1d950400 }, + { _MMIO(0x9888), 0x0f922000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_glk(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER: + dev_priv->perf.oa.n_mux_configs = + get_sampler_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "d72df5c7-5b4a-4274-a43f-00b0fd51fc68", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "814285f6-354d-41d2-ba49-e24e622714a0", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "07d397a6-b3e6-49f6-9433-a4f293d55978", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "1a356946-5428-450b-a2f0-89f8783a302d", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "5299be9d-7a61-4c99-9f81-f87e6c5aaca9", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "bc9bcff2-459a-4cbc-986d-a84b077153f3", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "88ec931f-5b4a-453a-9db6-a61232b6143d", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "530d176d-2a18-4014-adf8-1500c6c60835", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "fdee5a5a-f23c-43d1-aa73-f6257c71671d", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "6617623e-ca73-4791-b2b7-ddedd0846a0c", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER); +} + +static struct device_attribute dev_attr_sampler_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler[] = { + &dev_attr_sampler_id.attr, + NULL, +}; + +static struct attribute_group group_sampler = { + .name = "f3b2ea63-e82e-4234-b418-44dd20dd34d0", + .attrs = attrs_sampler, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "14411d35-cbf6-4f5e-b68b-190faf9a1a83", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "ffa3f263-0478-4724-8c9f-c911c5ec0f1d", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "15274c82-27d2-4819-876a-7cb1a2c59ba4", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_glk(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (ret) + goto error_sampler; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); +error_sampler: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_glk(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_glk.h b/drivers/gpu/drm/i915/i915_oa_glk.h new file mode 100644 index 0000000..5511bb1 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_glk.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_GLK_H__ +#define __I915_OA_GLK_H__ + +extern int i915_oa_n_builtin_metric_sets_glk; + +extern int i915_oa_select_metric_set_glk(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_glk(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_glk(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c index 4ddf756..10f169f 100644 --- a/drivers/gpu/drm/i915/i915_oa_hsw.c +++ b/drivers/gpu/drm/i915/i915_oa_hsw.c @@ -1,5 +1,7 @@ /* - * Autogenerated file, DO NOT EDIT manually! + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * * * Copyright (c) 2015 Intel Corporation * @@ -47,6 +49,9 @@ static const struct i915_oa_reg b_counter_config_render_basic[] = { { _MMIO(0x2710), 0x00000000 }, }; +static const struct i915_oa_reg flex_eu_config_render_basic[] = { +}; + static const struct i915_oa_reg mux_config_render_basic[] = { { _MMIO(0x253a4), 0x01600000 }, { _MMIO(0x25440), 0x00100000 }, @@ -109,12 +114,21 @@ static const struct i915_oa_reg mux_config_render_basic[] = { { _MMIO(0x25428), 0x00042049 }, }; -static const struct i915_oa_reg * +static int get_render_basic_mux_config(struct drm_i915_private *dev_priv, - int *len) + const struct i915_oa_reg **regs, + int *lens) { - *len = ARRAY_SIZE(mux_config_render_basic); - return mux_config_render_basic; + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_basic; + lens[n] = ARRAY_SIZE(mux_config_render_basic); + n++; + + return n; } static const struct i915_oa_reg b_counter_config_compute_basic[] = { @@ -137,6 +151,9 @@ static const struct i915_oa_reg b_counter_config_compute_basic[] = { { _MMIO(0x236c), 0x00000000 }, }; +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { +}; + static const struct i915_oa_reg mux_config_compute_basic[] = { { _MMIO(0x253a4), 0x00000000 }, { _MMIO(0x2681c), 0x01f00800 }, @@ -172,12 +189,21 @@ static const struct i915_oa_reg mux_config_compute_basic[] = { { _MMIO(0x25428), 0x00000c03 }, }; -static const struct i915_oa_reg * +static int get_compute_basic_mux_config(struct drm_i915_private *dev_priv, - int *len) + const struct i915_oa_reg **regs, + int *lens) { - *len = ARRAY_SIZE(mux_config_compute_basic); - return mux_config_compute_basic; + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; } static const struct i915_oa_reg b_counter_config_compute_extended[] = { @@ -203,6 +229,9 @@ static const struct i915_oa_reg b_counter_config_compute_extended[] = { { _MMIO(0x27ac), 0x0000fffe }, }; +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { +}; + static const struct i915_oa_reg mux_config_compute_extended[] = { { _MMIO(0x2681c), 0x3eb00800 }, { _MMIO(0x26820), 0x00900000 }, @@ -221,12 +250,21 @@ static const struct i915_oa_reg mux_config_compute_extended[] = { { _MMIO(0x25428), 0x00000000 }, }; -static const struct i915_oa_reg * +static int get_compute_extended_mux_config(struct drm_i915_private *dev_priv, - int *len) + const struct i915_oa_reg **regs, + int *lens) { - *len = ARRAY_SIZE(mux_config_compute_extended); - return mux_config_compute_extended; + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extended; + lens[n] = ARRAY_SIZE(mux_config_compute_extended); + n++; + + return n; } static const struct i915_oa_reg b_counter_config_memory_reads[] = { @@ -260,6 +298,9 @@ static const struct i915_oa_reg b_counter_config_memory_reads[] = { { _MMIO(0x27ac), 0x0000fc00 }, }; +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { +}; + static const struct i915_oa_reg mux_config_memory_reads[] = { { _MMIO(0x253a4), 0x34300000 }, { _MMIO(0x25440), 0x2d800000 }, @@ -281,12 +322,21 @@ static const struct i915_oa_reg mux_config_memory_reads[] = { { _MMIO(0x25428), 0x00000000 }, }; -static const struct i915_oa_reg * +static int get_memory_reads_mux_config(struct drm_i915_private *dev_priv, - int *len) + const struct i915_oa_reg **regs, + int *lens) { - *len = ARRAY_SIZE(mux_config_memory_reads); - return mux_config_memory_reads; + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; } static const struct i915_oa_reg b_counter_config_memory_writes[] = { @@ -320,6 +370,9 @@ static const struct i915_oa_reg b_counter_config_memory_writes[] = { { _MMIO(0x27ac), 0x0000fc00 }, }; +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { +}; + static const struct i915_oa_reg mux_config_memory_writes[] = { { _MMIO(0x253a4), 0x34300000 }, { _MMIO(0x25440), 0x01500000 }, @@ -341,12 +394,21 @@ static const struct i915_oa_reg mux_config_memory_writes[] = { { _MMIO(0x25428), 0x00000000 }, }; -static const struct i915_oa_reg * +static int get_memory_writes_mux_config(struct drm_i915_private *dev_priv, - int *len) + const struct i915_oa_reg **regs, + int *lens) { - *len = ARRAY_SIZE(mux_config_memory_writes); - return mux_config_memory_writes; + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; } static const struct i915_oa_reg b_counter_config_sampler_balance[] = { @@ -358,6 +420,9 @@ static const struct i915_oa_reg b_counter_config_sampler_balance[] = { { _MMIO(0x2724), 0x00800000 }, }; +static const struct i915_oa_reg flex_eu_config_sampler_balance[] = { +}; + static const struct i915_oa_reg mux_config_sampler_balance[] = { { _MMIO(0x2eb9c), 0x01906400 }, { _MMIO(0x2fb9c), 0x01906400 }, @@ -401,31 +466,40 @@ static const struct i915_oa_reg mux_config_sampler_balance[] = { { _MMIO(0x25428), 0x0004a54a }, }; -static const struct i915_oa_reg * +static int get_sampler_balance_mux_config(struct drm_i915_private *dev_priv, - int *len) + const struct i915_oa_reg **regs, + int *lens) { - *len = ARRAY_SIZE(mux_config_sampler_balance); - return mux_config_sampler_balance; + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler_balance; + lens[n] = ARRAY_SIZE(mux_config_sampler_balance); + n++; + + return n; } int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv) { - dev_priv->perf.oa.mux_regs = NULL; - dev_priv->perf.oa.mux_regs_len = 0; + dev_priv->perf.oa.n_mux_configs = 0; dev_priv->perf.oa.b_counter_regs = NULL; dev_priv->perf.oa.b_counter_regs_len = 0; switch (dev_priv->perf.oa.metrics_set) { case METRIC_SET_ID_RENDER_BASIC: - dev_priv->perf.oa.mux_regs = + dev_priv->perf.oa.n_mux_configs = get_render_basic_mux_config(dev_priv, - &dev_priv->perf.oa.mux_regs_len); - if (!dev_priv->perf.oa.mux_regs) { - DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set"); + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); /* EINVAL because *_register_sysfs already checked this - * and so it wouldn't have been advertised so userspace and + * and so it wouldn't have been advertised to userspace and * so shouldn't have been requested */ return -EINVAL; @@ -436,16 +510,22 @@ int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv) dev_priv->perf.oa.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic); + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + return 0; case METRIC_SET_ID_COMPUTE_BASIC: - dev_priv->perf.oa.mux_regs = + dev_priv->perf.oa.n_mux_configs = get_compute_basic_mux_config(dev_priv, - &dev_priv->perf.oa.mux_regs_len); - if (!dev_priv->perf.oa.mux_regs) { - DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set"); + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); /* EINVAL because *_register_sysfs already checked this - * and so it wouldn't have been advertised so userspace and + * and so it wouldn't have been advertised to userspace and * so shouldn't have been requested */ return -EINVAL; @@ -456,16 +536,22 @@ int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv) dev_priv->perf.oa.b_counter_regs_len = ARRAY_SIZE(b_counter_config_compute_basic); + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + return 0; case METRIC_SET_ID_COMPUTE_EXTENDED: - dev_priv->perf.oa.mux_regs = + dev_priv->perf.oa.n_mux_configs = get_compute_extended_mux_config(dev_priv, - &dev_priv->perf.oa.mux_regs_len); - if (!dev_priv->perf.oa.mux_regs) { - DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set"); + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); /* EINVAL because *_register_sysfs already checked this - * and so it wouldn't have been advertised so userspace and + * and so it wouldn't have been advertised to userspace and * so shouldn't have been requested */ return -EINVAL; @@ -476,16 +562,22 @@ int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv) dev_priv->perf.oa.b_counter_regs_len = ARRAY_SIZE(b_counter_config_compute_extended); + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + return 0; case METRIC_SET_ID_MEMORY_READS: - dev_priv->perf.oa.mux_regs = + dev_priv->perf.oa.n_mux_configs = get_memory_reads_mux_config(dev_priv, - &dev_priv->perf.oa.mux_regs_len); - if (!dev_priv->perf.oa.mux_regs) { - DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set"); + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); /* EINVAL because *_register_sysfs already checked this - * and so it wouldn't have been advertised so userspace and + * and so it wouldn't have been advertised to userspace and * so shouldn't have been requested */ return -EINVAL; @@ -496,16 +588,22 @@ int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv) dev_priv->perf.oa.b_counter_regs_len = ARRAY_SIZE(b_counter_config_memory_reads); + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + return 0; case METRIC_SET_ID_MEMORY_WRITES: - dev_priv->perf.oa.mux_regs = + dev_priv->perf.oa.n_mux_configs = get_memory_writes_mux_config(dev_priv, - &dev_priv->perf.oa.mux_regs_len); - if (!dev_priv->perf.oa.mux_regs) { - DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set"); + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); /* EINVAL because *_register_sysfs already checked this - * and so it wouldn't have been advertised so userspace and + * and so it wouldn't have been advertised to userspace and * so shouldn't have been requested */ return -EINVAL; @@ -516,16 +614,22 @@ int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv) dev_priv->perf.oa.b_counter_regs_len = ARRAY_SIZE(b_counter_config_memory_writes); + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + return 0; case METRIC_SET_ID_SAMPLER_BALANCE: - dev_priv->perf.oa.mux_regs = + dev_priv->perf.oa.n_mux_configs = get_sampler_balance_mux_config(dev_priv, - &dev_priv->perf.oa.mux_regs_len); - if (!dev_priv->perf.oa.mux_regs) { - DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_BALANCE\" metric set"); + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_BALANCE\" metric set\n"); /* EINVAL because *_register_sysfs already checked this - * and so it wouldn't have been advertised so userspace and + * and so it wouldn't have been advertised to userspace and * so shouldn't have been requested */ return -EINVAL; @@ -536,6 +640,11 @@ int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv) dev_priv->perf.oa.b_counter_regs_len = ARRAY_SIZE(b_counter_config_sampler_balance); + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler_balance; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler_balance); + return 0; default: return -ENODEV; @@ -677,35 +786,36 @@ static struct attribute_group group_sampler_balance = { int i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv) { - int mux_len; + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; int ret = 0; - if (get_render_basic_mux_config(dev_priv, &mux_len)) { + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); if (ret) goto error_render_basic; } - if (get_compute_basic_mux_config(dev_priv, &mux_len)) { + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); if (ret) goto error_compute_basic; } - if (get_compute_extended_mux_config(dev_priv, &mux_len)) { + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); if (ret) goto error_compute_extended; } - if (get_memory_reads_mux_config(dev_priv, &mux_len)) { + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); if (ret) goto error_memory_reads; } - if (get_memory_writes_mux_config(dev_priv, &mux_len)) { + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); if (ret) goto error_memory_writes; } - if (get_sampler_balance_mux_config(dev_priv, &mux_len)) { + if (get_sampler_balance_mux_config(dev_priv, mux_regs, mux_lens)) { ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_balance); if (ret) goto error_sampler_balance; @@ -714,19 +824,19 @@ i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv) return 0; error_sampler_balance: - if (get_sampler_balance_mux_config(dev_priv, &mux_len)) + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); error_memory_writes: - if (get_sampler_balance_mux_config(dev_priv, &mux_len)) + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); error_memory_reads: - if (get_sampler_balance_mux_config(dev_priv, &mux_len)) + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); error_compute_extended: - if (get_sampler_balance_mux_config(dev_priv, &mux_len)) + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); error_compute_basic: - if (get_sampler_balance_mux_config(dev_priv, &mux_len)) + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); error_render_basic: return ret; @@ -735,18 +845,19 @@ error_render_basic: void i915_perf_unregister_sysfs_hsw(struct drm_i915_private *dev_priv) { - int mux_len; + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; - if (get_render_basic_mux_config(dev_priv, &mux_len)) + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); - if (get_compute_basic_mux_config(dev_priv, &mux_len)) + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); - if (get_compute_extended_mux_config(dev_priv, &mux_len)) + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); - if (get_memory_reads_mux_config(dev_priv, &mux_len)) + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); - if (get_memory_writes_mux_config(dev_priv, &mux_len)) + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); - if (get_sampler_balance_mux_config(dev_priv, &mux_len)) + if (get_sampler_balance_mux_config(dev_priv, mux_regs, mux_lens)) sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_balance); } diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.h b/drivers/gpu/drm/i915/i915_oa_hsw.h index 429a229..6fe7e06 100644 --- a/drivers/gpu/drm/i915/i915_oa_hsw.h +++ b/drivers/gpu/drm/i915/i915_oa_hsw.h @@ -1,5 +1,7 @@ /* - * Autogenerated file, DO NOT EDIT manually! + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * * * Copyright (c) 2015 Intel Corporation * diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.c b/drivers/gpu/drm/i915/i915_oa_kblgt2.c new file mode 100644 index 0000000..87dbd0a --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.c @@ -0,0 +1,2991 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_kblgt2.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_L3_2, + METRIC_SET_ID_L3_3, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_VME_PIPE, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_kblgt2 = 18; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic[] = { + { _MMIO(0x9888), 0x166c01e0 }, + { _MMIO(0x9888), 0x12170280 }, + { _MMIO(0x9888), 0x12370280 }, + { _MMIO(0x9888), 0x11930317 }, + { _MMIO(0x9888), 0x159303df }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x1a4e0080 }, + { _MMIO(0x9888), 0x0a6c0053 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x0a1b4000 }, + { _MMIO(0x9888), 0x1c1c0001 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x042f1000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c8400 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0d2000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f6600 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x162c2200 }, + { _MMIO(0x9888), 0x062d8000 }, + { _MMIO(0x9888), 0x082d8000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x08133000 }, + { _MMIO(0x9888), 0x00170020 }, + { _MMIO(0x9888), 0x08170021 }, + { _MMIO(0x9888), 0x10170000 }, + { _MMIO(0x9888), 0x0633c000 }, + { _MMIO(0x9888), 0x0833c000 }, + { _MMIO(0x9888), 0x06370800 }, + { _MMIO(0x9888), 0x08370840 }, + { _MMIO(0x9888), 0x10370000 }, + { _MMIO(0x9888), 0x0d933031 }, + { _MMIO(0x9888), 0x0f933e3f }, + { _MMIO(0x9888), 0x01933d00 }, + { _MMIO(0x9888), 0x0393073c }, + { _MMIO(0x9888), 0x0593000e }, + { _MMIO(0x9888), 0x1d930000 }, + { _MMIO(0x9888), 0x19930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x15908000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190001f }, + { _MMIO(0x9888), 0x51904400 }, + { _MMIO(0x9888), 0x41900020 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c21 }, + { _MMIO(0x9888), 0x47900061 }, + { _MMIO(0x9888), 0x57904440 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900004 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x53904444 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_basic; + lens[n] = ARRAY_SIZE(mux_config_render_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x1a4e0820 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x064f0900 }, + { _MMIO(0x9888), 0x084f0032 }, + { _MMIO(0x9888), 0x0a4f1891 }, + { _MMIO(0x9888), 0x0c4f0e00 }, + { _MMIO(0x9888), 0x0e4f003c }, + { _MMIO(0x9888), 0x004f0d80 }, + { _MMIO(0x9888), 0x024f003b }, + { _MMIO(0x9888), 0x006c0002 }, + { _MMIO(0x9888), 0x086c0100 }, + { _MMIO(0x9888), 0x0c6c000c }, + { _MMIO(0x9888), 0x0e6c0b00 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x081b8000 }, + { _MMIO(0x9888), 0x0c1b4000 }, + { _MMIO(0x9888), 0x0e1b8000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1c8000 }, + { _MMIO(0x9888), 0x1c1c0024 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5bc000 }, + { _MMIO(0x9888), 0x0c5b8000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x1a5c6000 }, + { _MMIO(0x9888), 0x1c5c001b }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2000 }, + { _MMIO(0x9888), 0x0c4c0208 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020d2000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2cc000 }, + { _MMIO(0x9888), 0x162cfb00 }, + { _MMIO(0x9888), 0x182c00be }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x19900157 }, + { _MMIO(0x9888), 0x1b900158 }, + { _MMIO(0x9888), 0x1d900105 }, + { _MMIO(0x9888), 0x1f900103 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x11900fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900821 }, + { _MMIO(0x9888), 0x47900802 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900802 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900002 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900422 }, + { _MMIO(0x9888), 0x53904444 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x0c0e001f }, + { _MMIO(0x9888), 0x0a0f0000 }, + { _MMIO(0x9888), 0x10116800 }, + { _MMIO(0x9888), 0x178a03e0 }, + { _MMIO(0x9888), 0x11824c00 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x13840020 }, + { _MMIO(0x9888), 0x11850019 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x01870c40 }, + { _MMIO(0x9888), 0x17880000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x040d4000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020e5400 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x080f0040 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x0e0f0040 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06110012 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x01898000 }, + { _MMIO(0x9888), 0x0d890100 }, + { _MMIO(0x9888), 0x03898000 }, + { _MMIO(0x9888), 0x09808000 }, + { _MMIO(0x9888), 0x0b808000 }, + { _MMIO(0x9888), 0x0380c000 }, + { _MMIO(0x9888), 0x0f8a0075 }, + { _MMIO(0x9888), 0x1d8a0000 }, + { _MMIO(0x9888), 0x118a8000 }, + { _MMIO(0x9888), 0x1b8a4000 }, + { _MMIO(0x9888), 0x138a8000 }, + { _MMIO(0x9888), 0x1d81a000 }, + { _MMIO(0x9888), 0x15818000 }, + { _MMIO(0x9888), 0x17818000 }, + { _MMIO(0x9888), 0x0b820030 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x0d824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x05824000 }, + { _MMIO(0x9888), 0x0d830003 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x03838000 }, + { _MMIO(0x9888), 0x07838000 }, + { _MMIO(0x9888), 0x0b840980 }, + { _MMIO(0x9888), 0x03844d80 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x09850080 }, + { _MMIO(0x9888), 0x03850003 }, + { _MMIO(0x9888), 0x01850000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x09870032 }, + { _MMIO(0x9888), 0x01888052 }, + { _MMIO(0x9888), 0x11880000 }, + { _MMIO(0x9888), 0x09884000 }, + { _MMIO(0x9888), 0x1b931001 }, + { _MMIO(0x9888), 0x1d930001 }, + { _MMIO(0x9888), 0x19934000 }, + { _MMIO(0x9888), 0x1b958000 }, + { _MMIO(0x9888), 0x1d950094 }, + { _MMIO(0x9888), 0x19958000 }, + { _MMIO(0x9888), 0x09e58000 }, + { _MMIO(0x9888), 0x0be58000 }, + { _MMIO(0x9888), 0x03e5c000 }, + { _MMIO(0x9888), 0x0592c000 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d924000 }, + { _MMIO(0x9888), 0x0f924000 }, + { _MMIO(0x9888), 0x11928000 }, + { _MMIO(0x9888), 0x1392c000 }, + { _MMIO(0x9888), 0x09924000 }, + { _MMIO(0x9888), 0x01985000 }, + { _MMIO(0x9888), 0x07988000 }, + { _MMIO(0x9888), 0x09981000 }, + { _MMIO(0x9888), 0x0b982000 }, + { _MMIO(0x9888), 0x0d982000 }, + { _MMIO(0x9888), 0x0f989000 }, + { _MMIO(0x9888), 0x05982000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1190c080 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900440 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x47900c21 }, + { _MMIO(0x9888), 0x57900400 }, + { _MMIO(0x9888), 0x49900042 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900024 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900841 }, + { _MMIO(0x9888), 0x53900400 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900064 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900150 }, + { _MMIO(0x9888), 0x21900151 }, + { _MMIO(0x9888), 0x23900152 }, + { _MMIO(0x9888), 0x25900153 }, + { _MMIO(0x9888), 0x27900154 }, + { _MMIO(0x9888), 0x29900155 }, + { _MMIO(0x9888), 0x2b900156 }, + { _MMIO(0x9888), 0x2d900157 }, + { _MMIO(0x9888), 0x2f90015f }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901000 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900160 }, + { _MMIO(0x9888), 0x21900161 }, + { _MMIO(0x9888), 0x23900162 }, + { _MMIO(0x9888), 0x25900163 }, + { _MMIO(0x9888), 0x27900164 }, + { _MMIO(0x9888), 0x29900165 }, + { _MMIO(0x9888), 0x2b900166 }, + { _MMIO(0x9888), 0x2d900167 }, + { _MMIO(0x9888), 0x2f900150 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended[] = { + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x141c8160 }, + { _MMIO(0x9888), 0x161c8015 }, + { _MMIO(0x9888), 0x181c0120 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4eaaa0 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0e6c0b01 }, + { _MMIO(0x9888), 0x006c0200 }, + { _MMIO(0x9888), 0x026c000c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x001c0041 }, + { _MMIO(0x9888), 0x061c4200 }, + { _MMIO(0x9888), 0x081c4443 }, + { _MMIO(0x9888), 0x0a1c4645 }, + { _MMIO(0x9888), 0x0c1c7647 }, + { _MMIO(0x9888), 0x041c7357 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x101c0000 }, + { _MMIO(0x9888), 0x1a1c0000 }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4caa2a }, + { _MMIO(0x9888), 0x0c4c02aa }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5515 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x11907fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900040 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900802 }, + { _MMIO(0x9888), 0x47900842 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900842 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900800 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extended; + lens[n] = ARRAY_SIZE(mux_config_compute_extended); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x166c0760 }, + { _MMIO(0x9888), 0x1593001e }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4e8020 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x006c0051 }, + { _MMIO(0x9888), 0x066c5000 }, + { _MMIO(0x9888), 0x086c5c5d }, + { _MMIO(0x9888), 0x0e6c5e5f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x061b8000 }, + { _MMIO(0x9888), 0x081bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1ce000 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2a00 }, + { _MMIO(0x9888), 0x0c4c0280 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f1500 }, + { _MMIO(0x9888), 0x100f0140 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162c0a00 }, + { _MMIO(0x9888), 0x182c00a0 }, + { _MMIO(0x9888), 0x03933300 }, + { _MMIO(0x9888), 0x05930032 }, + { _MMIO(0x9888), 0x11930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190030f }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900021 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x53904444 }, + { _MMIO(0x9888), 0x43900000 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x104f0232 }, + { _MMIO(0x9888), 0x124f4640 }, + { _MMIO(0x9888), 0x106c0232 }, + { _MMIO(0x9888), 0x11834400 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x004f1880 }, + { _MMIO(0x9888), 0x024f08bb }, + { _MMIO(0x9888), 0x044f001b }, + { _MMIO(0x9888), 0x046c0100 }, + { _MMIO(0x9888), 0x066c000b }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x041b8000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025bc000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x165c8000 }, + { _MMIO(0x9888), 0x185c8000 }, + { _MMIO(0x9888), 0x0a4c00a0 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x062cc000 }, + { _MMIO(0x9888), 0x082cc000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x0f8305c0 }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x07830000 }, + { _MMIO(0x9888), 0x1d950080 }, + { _MMIO(0x9888), 0x13928000 }, + { _MMIO(0x9888), 0x0f988000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900040 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x126c7b40 }, + { _MMIO(0x9888), 0x166c0020 }, + { _MMIO(0x9888), 0x0a603444 }, + { _MMIO(0x9888), 0x0a613400 }, + { _MMIO(0x9888), 0x1a4ea800 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0800 }, + { _MMIO(0x9888), 0x0c1bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x1c1c003c }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x10600000 }, + { _MMIO(0x9888), 0x04600000 }, + { _MMIO(0x9888), 0x0c610044 }, + { _MMIO(0x9888), 0x10610000 }, + { _MMIO(0x9888), 0x06610000 }, + { _MMIO(0x9888), 0x0c4c02a8 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0154 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190ffc0 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900420 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900021 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900400 }, + { _MMIO(0x9888), 0x43900421 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_2[] = { + { _MMIO(0x9888), 0x126c02e0 }, + { _MMIO(0x9888), 0x146c0001 }, + { _MMIO(0x9888), 0x0a623400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x026c3324 }, + { _MMIO(0x9888), 0x046c3422 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x06614000 }, + { _MMIO(0x9888), 0x0c620044 }, + { _MMIO(0x9888), 0x10620000 }, + { _MMIO(0x9888), 0x06620000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_2; + lens[n] = ARRAY_SIZE(mux_config_l3_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_3[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_3[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_3[] = { + { _MMIO(0x9888), 0x126c4e80 }, + { _MMIO(0x9888), 0x146c0000 }, + { _MMIO(0x9888), 0x0a633400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x026c3321 }, + { _MMIO(0x9888), 0x046c342f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c2000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x06604000 }, + { _MMIO(0x9888), 0x0c630044 }, + { _MMIO(0x9888), 0x10630000 }, + { _MMIO(0x9888), 0x06630000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c00aa }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900002 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_3_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_3; + lens[n] = ARRAY_SIZE(mux_config_l3_3); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000efff }, + { _MMIO(0x2778), 0x00006000 }, + { _MMIO(0x277c), 0x0000f3ff }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x102f3800 }, + { _MMIO(0x9888), 0x144d0500 }, + { _MMIO(0x9888), 0x120d03c0 }, + { _MMIO(0x9888), 0x140d03cf }, + { _MMIO(0x9888), 0x0c0f0004 }, + { _MMIO(0x9888), 0x0c4e4000 }, + { _MMIO(0x9888), 0x042f0480 }, + { _MMIO(0x9888), 0x082f0000 }, + { _MMIO(0x9888), 0x022f0000 }, + { _MMIO(0x9888), 0x0a4c0090 }, + { _MMIO(0x9888), 0x064d0027 }, + { _MMIO(0x9888), 0x004d0000 }, + { _MMIO(0x9888), 0x000d0d40 }, + { _MMIO(0x9888), 0x020d803f }, + { _MMIO(0x9888), 0x040d8023 }, + { _MMIO(0x9888), 0x100d0000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020f0010 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x0e0f0050 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41901400 }, + { _MMIO(0x9888), 0x43901485 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler[] = { + { _MMIO(0x9888), 0x14152c00 }, + { _MMIO(0x9888), 0x16150005 }, + { _MMIO(0x9888), 0x121600a0 }, + { _MMIO(0x9888), 0x14352c00 }, + { _MMIO(0x9888), 0x16350005 }, + { _MMIO(0x9888), 0x123600a0 }, + { _MMIO(0x9888), 0x14552c00 }, + { _MMIO(0x9888), 0x16550005 }, + { _MMIO(0x9888), 0x125600a0 }, + { _MMIO(0x9888), 0x062f6000 }, + { _MMIO(0x9888), 0x022f2000 }, + { _MMIO(0x9888), 0x0c4c0050 }, + { _MMIO(0x9888), 0x0a4c0010 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0350 }, + { _MMIO(0x9888), 0x0c0fb000 }, + { _MMIO(0x9888), 0x0e0f00da }, + { _MMIO(0x9888), 0x182c0028 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x022dc000 }, + { _MMIO(0x9888), 0x042d4000 }, + { _MMIO(0x9888), 0x0c138000 }, + { _MMIO(0x9888), 0x0e132000 }, + { _MMIO(0x9888), 0x0413c000 }, + { _MMIO(0x9888), 0x1c140018 }, + { _MMIO(0x9888), 0x0c157000 }, + { _MMIO(0x9888), 0x0e150078 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x04162180 }, + { _MMIO(0x9888), 0x02160000 }, + { _MMIO(0x9888), 0x04174000 }, + { _MMIO(0x9888), 0x0233a000 }, + { _MMIO(0x9888), 0x04333000 }, + { _MMIO(0x9888), 0x14348000 }, + { _MMIO(0x9888), 0x16348000 }, + { _MMIO(0x9888), 0x02357870 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x04360043 }, + { _MMIO(0x9888), 0x02360000 }, + { _MMIO(0x9888), 0x04371000 }, + { _MMIO(0x9888), 0x0e538000 }, + { _MMIO(0x9888), 0x00538000 }, + { _MMIO(0x9888), 0x06533000 }, + { _MMIO(0x9888), 0x1c540020 }, + { _MMIO(0x9888), 0x12548000 }, + { _MMIO(0x9888), 0x0e557000 }, + { _MMIO(0x9888), 0x00557800 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x06560043 }, + { _MMIO(0x9888), 0x02560000 }, + { _MMIO(0x9888), 0x06571000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900060 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900060 }, +}; + +static int +get_sampler_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler; + lens[n] = ARRAY_SIZE(mux_config_sampler); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x00007fff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x00009fff }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000efff }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000f3ff }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fdff }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x12120000 }, + { _MMIO(0x9888), 0x12320000 }, + { _MMIO(0x9888), 0x12520000 }, + { _MMIO(0x9888), 0x002f8000 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0015 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f03a0 }, + { _MMIO(0x9888), 0x0c0ff000 }, + { _MMIO(0x9888), 0x0e0f0095 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2d8000 }, + { _MMIO(0x9888), 0x0e2d4000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x02108000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x02118000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x02121880 }, + { _MMIO(0x9888), 0x041219b5 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x02134000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x0c308000 }, + { _MMIO(0x9888), 0x0e304000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x0c318000 }, + { _MMIO(0x9888), 0x0e314000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x0c321a80 }, + { _MMIO(0x9888), 0x0e320033 }, + { _MMIO(0x9888), 0x06320031 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x0c334000 }, + { _MMIO(0x9888), 0x0e331000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0e508000 }, + { _MMIO(0x9888), 0x00508000 }, + { _MMIO(0x9888), 0x02504000 }, + { _MMIO(0x9888), 0x0e518000 }, + { _MMIO(0x9888), 0x00518000 }, + { _MMIO(0x9888), 0x02514000 }, + { _MMIO(0x9888), 0x0e521880 }, + { _MMIO(0x9888), 0x00521a80 }, + { _MMIO(0x9888), 0x02520033 }, + { _MMIO(0x9888), 0x0e534000 }, + { _MMIO(0x9888), 0x00534000 }, + { _MMIO(0x9888), 0x02531000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900062 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x12124d60 }, + { _MMIO(0x9888), 0x12322e60 }, + { _MMIO(0x9888), 0x12524d60 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0014 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0fe000 }, + { _MMIO(0x9888), 0x0e0f0097 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x002d8000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x04121fb7 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x00308000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x00318000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x00321b80 }, + { _MMIO(0x9888), 0x0632003f }, + { _MMIO(0x9888), 0x00334000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0250c000 }, + { _MMIO(0x9888), 0x0251c000 }, + { _MMIO(0x9888), 0x02521fb7 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x02535000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900063 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { + { _MMIO(0xe458), 0x00001000 }, + { _MMIO(0xe558), 0x00003002 }, + { _MMIO(0xe658), 0x00005004 }, + { _MMIO(0xe758), 0x00011010 }, + { _MMIO(0xe45c), 0x00050012 }, + { _MMIO(0xe55c), 0x00052051 }, + { _MMIO(0xe65c), 0x00000008 }, +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x121203e0 }, + { _MMIO(0x9888), 0x123203e0 }, + { _MMIO(0x9888), 0x125203e0 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0e0f006c }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x042d8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06114000 }, + { _MMIO(0x9888), 0x06120033 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x04308000 }, + { _MMIO(0x9888), 0x04318000 }, + { _MMIO(0x9888), 0x04321980 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x04334000 }, + { _MMIO(0x9888), 0x04504000 }, + { _MMIO(0x9888), 0x04514000 }, + { _MMIO(0x9888), 0x04520033 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x04531000 }, + { _MMIO(0x9888), 0x1190e000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900c00 }, + { _MMIO(0x9888), 0x45900002 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_vme_pipe[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00100030 }, + { _MMIO(0x2774), 0x0000fff9 }, + { _MMIO(0x2778), 0x00000002 }, + { _MMIO(0x277c), 0x0000fffc }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000fff3 }, + { _MMIO(0x2788), 0x00100180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000ff3f }, +}; + +static const struct i915_oa_reg flex_eu_config_vme_pipe[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00008003 }, +}; + +static const struct i915_oa_reg mux_config_vme_pipe[] = { + { _MMIO(0x9888), 0x141a5800 }, + { _MMIO(0x9888), 0x161a00c0 }, + { _MMIO(0x9888), 0x12180240 }, + { _MMIO(0x9888), 0x14180002 }, + { _MMIO(0x9888), 0x143a5800 }, + { _MMIO(0x9888), 0x163a00c0 }, + { _MMIO(0x9888), 0x12380240 }, + { _MMIO(0x9888), 0x14380002 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x022f8000 }, + { _MMIO(0x9888), 0x042f3000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c1500 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f9500 }, + { _MMIO(0x9888), 0x100f002a }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162c0a00 }, + { _MMIO(0x9888), 0x0a2dc000 }, + { _MMIO(0x9888), 0x0c2dc000 }, + { _MMIO(0x9888), 0x04193000 }, + { _MMIO(0x9888), 0x081a28c1 }, + { _MMIO(0x9888), 0x001a0000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x0613c000 }, + { _MMIO(0x9888), 0x0813f000 }, + { _MMIO(0x9888), 0x00172000 }, + { _MMIO(0x9888), 0x06178000 }, + { _MMIO(0x9888), 0x0817a000 }, + { _MMIO(0x9888), 0x00180037 }, + { _MMIO(0x9888), 0x06180940 }, + { _MMIO(0x9888), 0x08180000 }, + { _MMIO(0x9888), 0x02180000 }, + { _MMIO(0x9888), 0x04183000 }, + { _MMIO(0x9888), 0x06393000 }, + { _MMIO(0x9888), 0x0c3a28c1 }, + { _MMIO(0x9888), 0x003a0000 }, + { _MMIO(0x9888), 0x0a33f000 }, + { _MMIO(0x9888), 0x0c33f000 }, + { _MMIO(0x9888), 0x0a37a000 }, + { _MMIO(0x9888), 0x0c37a000 }, + { _MMIO(0x9888), 0x0a380977 }, + { _MMIO(0x9888), 0x08380000 }, + { _MMIO(0x9888), 0x04380000 }, + { _MMIO(0x9888), 0x06383000 }, + { _MMIO(0x9888), 0x119000ff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900040 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900800 }, + { _MMIO(0x9888), 0x47901000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900844 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_vme_pipe_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_vme_pipe; + lens[n] = ARRAY_SIZE(mux_config_vme_pipe); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x11810000 }, + { _MMIO(0x9888), 0x07810013 }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930040 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_kblgt2(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_L3_2: + dev_priv->perf.oa.n_mux_configs = + get_l3_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_2); + + return 0; + case METRIC_SET_ID_L3_3: + dev_priv->perf.oa.n_mux_configs = + get_l3_3_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_3; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_3); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_3; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_3); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER: + dev_priv->perf.oa.n_mux_configs = + get_sampler_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_VME_PIPE: + dev_priv->perf.oa.n_mux_configs = + get_vme_pipe_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_vme_pipe; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_vme_pipe); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_vme_pipe; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_vme_pipe); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "f8d677e9-ff6f-4df1-9310-0334c6efacce", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "e17fc42a-e614-41b6-90c4-1074841a6c77", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "d7a17a3a-ca71-40d2-a919-ace80d50633f", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "57b59202-172b-477a-87de-33f85572c589", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "3addf8ef-8e9b-40f5-a448-3dbb5d5128b0", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "4af0400a-81c3-47db-a6b6-deddbd75680e", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "0e22f995-79ca-4f67-83ab-e9d9772488d8", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "bc2a00f7-cb8a-4ff2-8ad0-e241dad16937", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "d2bbe790-f058-42d9-81c6-cdedcf655bc2", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2); +} + +static struct device_attribute dev_attr_l3_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_2_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_2[] = { + &dev_attr_l3_2_id.attr, + NULL, +}; + +static struct attribute_group group_l3_2 = { + .name = "2f8e32e4-5956-46e2-af31-c8ea95887332", + .attrs = attrs_l3_2, +}; + +static ssize_t +show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3); +} + +static struct device_attribute dev_attr_l3_3_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_3_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_3[] = { + &dev_attr_l3_3_id.attr, + NULL, +}; + +static struct attribute_group group_l3_3 = { + .name = "ca046aad-b5fb-4101-adce-6473ee6e5b14", + .attrs = attrs_l3_3, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "605f388f-24bb-455c-88e3-8d57ae0d7e9f", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER); +} + +static struct device_attribute dev_attr_sampler_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler[] = { + &dev_attr_sampler_id.attr, + NULL, +}; + +static struct attribute_group group_sampler = { + .name = "31dd157c-bf4e-4bab-bf2b-f5c8174af1af", + .attrs = attrs_sampler, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "105db928-5542-466b-9128-e1f3c91426cb", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "03db94d2-b37f-4c58-a791-0d2067b013bb", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "aa7a3fb9-22fb-43ff-a32d-0ab6c13bbd16", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE); +} + +static struct device_attribute dev_attr_vme_pipe_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_vme_pipe_id, + .store = NULL, +}; + +static struct attribute *attrs_vme_pipe[] = { + &dev_attr_vme_pipe_id.attr, + NULL, +}; + +static struct attribute_group group_vme_pipe = { + .name = "398a4268-ef6f-4ffc-b55f-3c7b5363ce61", + .attrs = attrs_vme_pipe, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "baa3c7e4-52b6-4b85-801e-465a94b746dd", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_kblgt2(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (ret) + goto error_l3_2; + } + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (ret) + goto error_l3_3; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (ret) + goto error_sampler; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (ret) + goto error_vme_pipe; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); +error_vme_pipe: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); +error_sampler: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); +error_l3_3: + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); +error_l3_2: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_kblgt2(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.h b/drivers/gpu/drm/i915/i915_oa_kblgt2.h new file mode 100644 index 0000000..7e61bfc --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_KBLGT2_H__ +#define __I915_OA_KBLGT2_H__ + +extern int i915_oa_n_builtin_metric_sets_kblgt2; + +extern int i915_oa_select_metric_set_kblgt2(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_kblgt2(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_kblgt2(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.c b/drivers/gpu/drm/i915/i915_oa_kblgt3.c new file mode 100644 index 0000000..6ed0925 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.c @@ -0,0 +1,3040 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_kblgt3.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_L3_2, + METRIC_SET_ID_L3_3, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_VME_PIPE, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_kblgt3 = 18; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic[] = { + { _MMIO(0x9888), 0x166c01e0 }, + { _MMIO(0x9888), 0x12170280 }, + { _MMIO(0x9888), 0x12370280 }, + { _MMIO(0x9888), 0x16ec01e0 }, + { _MMIO(0x9888), 0x11930317 }, + { _MMIO(0x9888), 0x159303df }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x1a4e0380 }, + { _MMIO(0x9888), 0x0a6c0053 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x0a1b4000 }, + { _MMIO(0x9888), 0x1c1c0001 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x042f1000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c8400 }, + { _MMIO(0x9888), 0x0c4c0002 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f6600 }, + { _MMIO(0x9888), 0x100f0001 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x162ca200 }, + { _MMIO(0x9888), 0x062d8000 }, + { _MMIO(0x9888), 0x082d8000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x08133000 }, + { _MMIO(0x9888), 0x00170020 }, + { _MMIO(0x9888), 0x08170021 }, + { _MMIO(0x9888), 0x10170000 }, + { _MMIO(0x9888), 0x0633c000 }, + { _MMIO(0x9888), 0x0833c000 }, + { _MMIO(0x9888), 0x06370800 }, + { _MMIO(0x9888), 0x08370840 }, + { _MMIO(0x9888), 0x10370000 }, + { _MMIO(0x9888), 0x1ace0200 }, + { _MMIO(0x9888), 0x0aec5300 }, + { _MMIO(0x9888), 0x10ec0000 }, + { _MMIO(0x9888), 0x1cec0000 }, + { _MMIO(0x9888), 0x0a9b8000 }, + { _MMIO(0x9888), 0x1c9c0002 }, + { _MMIO(0x9888), 0x0ccc0002 }, + { _MMIO(0x9888), 0x0a8d8000 }, + { _MMIO(0x9888), 0x108f0001 }, + { _MMIO(0x9888), 0x16ac8000 }, + { _MMIO(0x9888), 0x0d933031 }, + { _MMIO(0x9888), 0x0f933e3f }, + { _MMIO(0x9888), 0x01933d00 }, + { _MMIO(0x9888), 0x0393073c }, + { _MMIO(0x9888), 0x0593000e }, + { _MMIO(0x9888), 0x1d930000 }, + { _MMIO(0x9888), 0x19930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x15908000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190003f }, + { _MMIO(0x9888), 0x51902240 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x55900242 }, + { _MMIO(0x9888), 0x45900084 }, + { _MMIO(0x9888), 0x47901400 }, + { _MMIO(0x9888), 0x57902220 }, + { _MMIO(0x9888), 0x49900c60 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900002 }, + { _MMIO(0x9888), 0x43900c63 }, + { _MMIO(0x9888), 0x53902222 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_basic; + lens[n] = ARRAY_SIZE(mux_config_render_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x1a4e0820 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x064f0900 }, + { _MMIO(0x9888), 0x084f0032 }, + { _MMIO(0x9888), 0x0a4f1891 }, + { _MMIO(0x9888), 0x0c4f0e00 }, + { _MMIO(0x9888), 0x0e4f003c }, + { _MMIO(0x9888), 0x004f0d80 }, + { _MMIO(0x9888), 0x024f003b }, + { _MMIO(0x9888), 0x006c0002 }, + { _MMIO(0x9888), 0x086c0100 }, + { _MMIO(0x9888), 0x0c6c000c }, + { _MMIO(0x9888), 0x0e6c0b00 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x081b8000 }, + { _MMIO(0x9888), 0x0c1b4000 }, + { _MMIO(0x9888), 0x0e1b8000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1c8000 }, + { _MMIO(0x9888), 0x1c1c0024 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5bc000 }, + { _MMIO(0x9888), 0x0c5b8000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x1a5c6000 }, + { _MMIO(0x9888), 0x1c5c001b }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2000 }, + { _MMIO(0x9888), 0x0c4c0208 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020d2000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2cc000 }, + { _MMIO(0x9888), 0x162cfb00 }, + { _MMIO(0x9888), 0x182c00be }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x19900157 }, + { _MMIO(0x9888), 0x1b900158 }, + { _MMIO(0x9888), 0x1d900105 }, + { _MMIO(0x9888), 0x1f900103 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x11900fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900821 }, + { _MMIO(0x9888), 0x47900802 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900802 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900002 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900422 }, + { _MMIO(0x9888), 0x53904444 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x0c0e001f }, + { _MMIO(0x9888), 0x0a0f0000 }, + { _MMIO(0x9888), 0x10116800 }, + { _MMIO(0x9888), 0x178a03e0 }, + { _MMIO(0x9888), 0x11824c00 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x13840020 }, + { _MMIO(0x9888), 0x11850019 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x01870c40 }, + { _MMIO(0x9888), 0x17880000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x040d4000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020e5400 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x080f0040 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x0e0f0040 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06110012 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x01898000 }, + { _MMIO(0x9888), 0x0d890100 }, + { _MMIO(0x9888), 0x03898000 }, + { _MMIO(0x9888), 0x09808000 }, + { _MMIO(0x9888), 0x0b808000 }, + { _MMIO(0x9888), 0x0380c000 }, + { _MMIO(0x9888), 0x0f8a0075 }, + { _MMIO(0x9888), 0x1d8a0000 }, + { _MMIO(0x9888), 0x118a8000 }, + { _MMIO(0x9888), 0x1b8a4000 }, + { _MMIO(0x9888), 0x138a8000 }, + { _MMIO(0x9888), 0x1d81a000 }, + { _MMIO(0x9888), 0x15818000 }, + { _MMIO(0x9888), 0x17818000 }, + { _MMIO(0x9888), 0x0b820030 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x0d824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x05824000 }, + { _MMIO(0x9888), 0x0d830003 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x03838000 }, + { _MMIO(0x9888), 0x07838000 }, + { _MMIO(0x9888), 0x0b840980 }, + { _MMIO(0x9888), 0x03844d80 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x09850080 }, + { _MMIO(0x9888), 0x03850003 }, + { _MMIO(0x9888), 0x01850000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x09870032 }, + { _MMIO(0x9888), 0x01888052 }, + { _MMIO(0x9888), 0x11880000 }, + { _MMIO(0x9888), 0x09884000 }, + { _MMIO(0x9888), 0x1b931001 }, + { _MMIO(0x9888), 0x1d930001 }, + { _MMIO(0x9888), 0x19934000 }, + { _MMIO(0x9888), 0x1b958000 }, + { _MMIO(0x9888), 0x1d950094 }, + { _MMIO(0x9888), 0x19958000 }, + { _MMIO(0x9888), 0x09e58000 }, + { _MMIO(0x9888), 0x0be58000 }, + { _MMIO(0x9888), 0x03e5c000 }, + { _MMIO(0x9888), 0x0592c000 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d924000 }, + { _MMIO(0x9888), 0x0f924000 }, + { _MMIO(0x9888), 0x11928000 }, + { _MMIO(0x9888), 0x1392c000 }, + { _MMIO(0x9888), 0x09924000 }, + { _MMIO(0x9888), 0x01985000 }, + { _MMIO(0x9888), 0x07988000 }, + { _MMIO(0x9888), 0x09981000 }, + { _MMIO(0x9888), 0x0b982000 }, + { _MMIO(0x9888), 0x0d982000 }, + { _MMIO(0x9888), 0x0f989000 }, + { _MMIO(0x9888), 0x05982000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1190c080 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900440 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x47900c21 }, + { _MMIO(0x9888), 0x57900400 }, + { _MMIO(0x9888), 0x49900042 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900024 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900841 }, + { _MMIO(0x9888), 0x53900400 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900064 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900150 }, + { _MMIO(0x9888), 0x21900151 }, + { _MMIO(0x9888), 0x23900152 }, + { _MMIO(0x9888), 0x25900153 }, + { _MMIO(0x9888), 0x27900154 }, + { _MMIO(0x9888), 0x29900155 }, + { _MMIO(0x9888), 0x2b900156 }, + { _MMIO(0x9888), 0x2d900157 }, + { _MMIO(0x9888), 0x2f90015f }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901000 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900160 }, + { _MMIO(0x9888), 0x21900161 }, + { _MMIO(0x9888), 0x23900162 }, + { _MMIO(0x9888), 0x25900163 }, + { _MMIO(0x9888), 0x27900164 }, + { _MMIO(0x9888), 0x29900165 }, + { _MMIO(0x9888), 0x2b900166 }, + { _MMIO(0x9888), 0x2d900167 }, + { _MMIO(0x9888), 0x2f900150 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended[] = { + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x141c8160 }, + { _MMIO(0x9888), 0x161c8015 }, + { _MMIO(0x9888), 0x181c0120 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4eaaa0 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0e6c0b01 }, + { _MMIO(0x9888), 0x006c0200 }, + { _MMIO(0x9888), 0x026c000c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x001c0041 }, + { _MMIO(0x9888), 0x061c4200 }, + { _MMIO(0x9888), 0x081c4443 }, + { _MMIO(0x9888), 0x0a1c4645 }, + { _MMIO(0x9888), 0x0c1c7647 }, + { _MMIO(0x9888), 0x041c7357 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x101c0000 }, + { _MMIO(0x9888), 0x1a1c0000 }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4caa2a }, + { _MMIO(0x9888), 0x0c4c02aa }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5515 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x11907fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900040 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900802 }, + { _MMIO(0x9888), 0x47900842 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900842 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900800 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extended; + lens[n] = ARRAY_SIZE(mux_config_compute_extended); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x166c0760 }, + { _MMIO(0x9888), 0x1593001e }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4e8020 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x006c0051 }, + { _MMIO(0x9888), 0x066c5000 }, + { _MMIO(0x9888), 0x086c5c5d }, + { _MMIO(0x9888), 0x0e6c5e5f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x061b8000 }, + { _MMIO(0x9888), 0x081bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1ce000 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2a00 }, + { _MMIO(0x9888), 0x0c4c0280 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f1500 }, + { _MMIO(0x9888), 0x100f0140 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162c0a00 }, + { _MMIO(0x9888), 0x182c00a0 }, + { _MMIO(0x9888), 0x03933300 }, + { _MMIO(0x9888), 0x05930032 }, + { _MMIO(0x9888), 0x11930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190030f }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900021 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x53904444 }, + { _MMIO(0x9888), 0x43900000 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x104f0232 }, + { _MMIO(0x9888), 0x124f4640 }, + { _MMIO(0x9888), 0x106c0232 }, + { _MMIO(0x9888), 0x11834400 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x004f1880 }, + { _MMIO(0x9888), 0x024f08bb }, + { _MMIO(0x9888), 0x044f001b }, + { _MMIO(0x9888), 0x046c0100 }, + { _MMIO(0x9888), 0x066c000b }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x041b8000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025bc000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x165c8000 }, + { _MMIO(0x9888), 0x185c8000 }, + { _MMIO(0x9888), 0x0a4c00a0 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x062cc000 }, + { _MMIO(0x9888), 0x082cc000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x0f8305c0 }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x07830000 }, + { _MMIO(0x9888), 0x1d950080 }, + { _MMIO(0x9888), 0x13928000 }, + { _MMIO(0x9888), 0x0f988000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b900040 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x126c7b40 }, + { _MMIO(0x9888), 0x166c0020 }, + { _MMIO(0x9888), 0x0a603444 }, + { _MMIO(0x9888), 0x0a613400 }, + { _MMIO(0x9888), 0x1a4ea800 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0800 }, + { _MMIO(0x9888), 0x0c1bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x1c1c003c }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x10600000 }, + { _MMIO(0x9888), 0x04600000 }, + { _MMIO(0x9888), 0x0c610044 }, + { _MMIO(0x9888), 0x10610000 }, + { _MMIO(0x9888), 0x06610000 }, + { _MMIO(0x9888), 0x0c4c02a8 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0154 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190ffc0 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900420 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900021 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900400 }, + { _MMIO(0x9888), 0x43900421 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_2[] = { + { _MMIO(0x9888), 0x126c02e0 }, + { _MMIO(0x9888), 0x146c0001 }, + { _MMIO(0x9888), 0x0a623400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x026c3324 }, + { _MMIO(0x9888), 0x046c3422 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x06614000 }, + { _MMIO(0x9888), 0x0c620044 }, + { _MMIO(0x9888), 0x10620000 }, + { _MMIO(0x9888), 0x06620000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_2; + lens[n] = ARRAY_SIZE(mux_config_l3_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_3[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_3[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_3[] = { + { _MMIO(0x9888), 0x126c4e80 }, + { _MMIO(0x9888), 0x146c0000 }, + { _MMIO(0x9888), 0x0a633400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x026c3321 }, + { _MMIO(0x9888), 0x046c342f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c2000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x06604000 }, + { _MMIO(0x9888), 0x0c630044 }, + { _MMIO(0x9888), 0x10630000 }, + { _MMIO(0x9888), 0x06630000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c00aa }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900002 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_3_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_3; + lens[n] = ARRAY_SIZE(mux_config_l3_3); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000efff }, + { _MMIO(0x2778), 0x00006000 }, + { _MMIO(0x277c), 0x0000f3ff }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x102f3800 }, + { _MMIO(0x9888), 0x144d0500 }, + { _MMIO(0x9888), 0x120d03c0 }, + { _MMIO(0x9888), 0x140d03cf }, + { _MMIO(0x9888), 0x0c0f0004 }, + { _MMIO(0x9888), 0x0c4e4000 }, + { _MMIO(0x9888), 0x042f0480 }, + { _MMIO(0x9888), 0x082f0000 }, + { _MMIO(0x9888), 0x022f0000 }, + { _MMIO(0x9888), 0x0a4c0090 }, + { _MMIO(0x9888), 0x064d0027 }, + { _MMIO(0x9888), 0x004d0000 }, + { _MMIO(0x9888), 0x000d0d40 }, + { _MMIO(0x9888), 0x020d803f }, + { _MMIO(0x9888), 0x040d8023 }, + { _MMIO(0x9888), 0x100d0000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020f0010 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x0e0f0050 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41901400 }, + { _MMIO(0x9888), 0x43901485 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler[] = { + { _MMIO(0x9888), 0x14152c00 }, + { _MMIO(0x9888), 0x16150005 }, + { _MMIO(0x9888), 0x121600a0 }, + { _MMIO(0x9888), 0x14352c00 }, + { _MMIO(0x9888), 0x16350005 }, + { _MMIO(0x9888), 0x123600a0 }, + { _MMIO(0x9888), 0x14552c00 }, + { _MMIO(0x9888), 0x16550005 }, + { _MMIO(0x9888), 0x125600a0 }, + { _MMIO(0x9888), 0x062f6000 }, + { _MMIO(0x9888), 0x022f2000 }, + { _MMIO(0x9888), 0x0c4c0050 }, + { _MMIO(0x9888), 0x0a4c0010 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0350 }, + { _MMIO(0x9888), 0x0c0fb000 }, + { _MMIO(0x9888), 0x0e0f00da }, + { _MMIO(0x9888), 0x182c0028 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x022dc000 }, + { _MMIO(0x9888), 0x042d4000 }, + { _MMIO(0x9888), 0x0c138000 }, + { _MMIO(0x9888), 0x0e132000 }, + { _MMIO(0x9888), 0x0413c000 }, + { _MMIO(0x9888), 0x1c140018 }, + { _MMIO(0x9888), 0x0c157000 }, + { _MMIO(0x9888), 0x0e150078 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x04162180 }, + { _MMIO(0x9888), 0x02160000 }, + { _MMIO(0x9888), 0x04174000 }, + { _MMIO(0x9888), 0x0233a000 }, + { _MMIO(0x9888), 0x04333000 }, + { _MMIO(0x9888), 0x14348000 }, + { _MMIO(0x9888), 0x16348000 }, + { _MMIO(0x9888), 0x02357870 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x04360043 }, + { _MMIO(0x9888), 0x02360000 }, + { _MMIO(0x9888), 0x04371000 }, + { _MMIO(0x9888), 0x0e538000 }, + { _MMIO(0x9888), 0x00538000 }, + { _MMIO(0x9888), 0x06533000 }, + { _MMIO(0x9888), 0x1c540020 }, + { _MMIO(0x9888), 0x12548000 }, + { _MMIO(0x9888), 0x0e557000 }, + { _MMIO(0x9888), 0x00557800 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x06560043 }, + { _MMIO(0x9888), 0x02560000 }, + { _MMIO(0x9888), 0x06571000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900060 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900060 }, +}; + +static int +get_sampler_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler; + lens[n] = ARRAY_SIZE(mux_config_sampler); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x00007fff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x00009fff }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000efff }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000f3ff }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fdff }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x12120000 }, + { _MMIO(0x9888), 0x12320000 }, + { _MMIO(0x9888), 0x12520000 }, + { _MMIO(0x9888), 0x002f8000 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0015 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f03a0 }, + { _MMIO(0x9888), 0x0c0ff000 }, + { _MMIO(0x9888), 0x0e0f0095 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2d8000 }, + { _MMIO(0x9888), 0x0e2d4000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x02108000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x02118000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x02121880 }, + { _MMIO(0x9888), 0x041219b5 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x02134000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x0c308000 }, + { _MMIO(0x9888), 0x0e304000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x0c318000 }, + { _MMIO(0x9888), 0x0e314000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x0c321a80 }, + { _MMIO(0x9888), 0x0e320033 }, + { _MMIO(0x9888), 0x06320031 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x0c334000 }, + { _MMIO(0x9888), 0x0e331000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0e508000 }, + { _MMIO(0x9888), 0x00508000 }, + { _MMIO(0x9888), 0x02504000 }, + { _MMIO(0x9888), 0x0e518000 }, + { _MMIO(0x9888), 0x00518000 }, + { _MMIO(0x9888), 0x02514000 }, + { _MMIO(0x9888), 0x0e521880 }, + { _MMIO(0x9888), 0x00521a80 }, + { _MMIO(0x9888), 0x02520033 }, + { _MMIO(0x9888), 0x0e534000 }, + { _MMIO(0x9888), 0x00534000 }, + { _MMIO(0x9888), 0x02531000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900062 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x12124d60 }, + { _MMIO(0x9888), 0x12322e60 }, + { _MMIO(0x9888), 0x12524d60 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0014 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0fe000 }, + { _MMIO(0x9888), 0x0e0f0097 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x002d8000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x04121fb7 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x00308000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x00318000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x00321b80 }, + { _MMIO(0x9888), 0x0632003f }, + { _MMIO(0x9888), 0x00334000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0250c000 }, + { _MMIO(0x9888), 0x0251c000 }, + { _MMIO(0x9888), 0x02521fb7 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x02535000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900063 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x121203e0 }, + { _MMIO(0x9888), 0x123203e0 }, + { _MMIO(0x9888), 0x125203e0 }, + { _MMIO(0x9888), 0x129203e0 }, + { _MMIO(0x9888), 0x12b203e0 }, + { _MMIO(0x9888), 0x12d203e0 }, + { _MMIO(0x9888), 0x024ec000 }, + { _MMIO(0x9888), 0x044ec000 }, + { _MMIO(0x9888), 0x064ec000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c0042 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f006d }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x042d8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06114000 }, + { _MMIO(0x9888), 0x06120033 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x04308000 }, + { _MMIO(0x9888), 0x04318000 }, + { _MMIO(0x9888), 0x04321980 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x04334000 }, + { _MMIO(0x9888), 0x04504000 }, + { _MMIO(0x9888), 0x04514000 }, + { _MMIO(0x9888), 0x04520033 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x04531000 }, + { _MMIO(0x9888), 0x00af8000 }, + { _MMIO(0x9888), 0x0acc0001 }, + { _MMIO(0x9888), 0x008d8000 }, + { _MMIO(0x9888), 0x028da000 }, + { _MMIO(0x9888), 0x0c8fb000 }, + { _MMIO(0x9888), 0x0e8f0001 }, + { _MMIO(0x9888), 0x06ac8000 }, + { _MMIO(0x9888), 0x02ad4000 }, + { _MMIO(0x9888), 0x02908000 }, + { _MMIO(0x9888), 0x02918000 }, + { _MMIO(0x9888), 0x02921980 }, + { _MMIO(0x9888), 0x00920000 }, + { _MMIO(0x9888), 0x02934000 }, + { _MMIO(0x9888), 0x02b04000 }, + { _MMIO(0x9888), 0x02b14000 }, + { _MMIO(0x9888), 0x02b20033 }, + { _MMIO(0x9888), 0x00b20000 }, + { _MMIO(0x9888), 0x02b31000 }, + { _MMIO(0x9888), 0x00d08000 }, + { _MMIO(0x9888), 0x00d18000 }, + { _MMIO(0x9888), 0x00d21980 }, + { _MMIO(0x9888), 0x00d34000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900002 }, + { _MMIO(0x9888), 0x53900420 }, + { _MMIO(0x9888), 0x459000a1 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_vme_pipe[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00100030 }, + { _MMIO(0x2774), 0x0000fff9 }, + { _MMIO(0x2778), 0x00000002 }, + { _MMIO(0x277c), 0x0000fffc }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000fff3 }, + { _MMIO(0x2788), 0x00100180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000ff3f }, +}; + +static const struct i915_oa_reg flex_eu_config_vme_pipe[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00008003 }, +}; + +static const struct i915_oa_reg mux_config_vme_pipe[] = { + { _MMIO(0x9888), 0x141a5800 }, + { _MMIO(0x9888), 0x161a00c0 }, + { _MMIO(0x9888), 0x12180240 }, + { _MMIO(0x9888), 0x14180002 }, + { _MMIO(0x9888), 0x149a5800 }, + { _MMIO(0x9888), 0x169a00c0 }, + { _MMIO(0x9888), 0x12980240 }, + { _MMIO(0x9888), 0x14980002 }, + { _MMIO(0x9888), 0x1a4e3fc0 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x022f8000 }, + { _MMIO(0x9888), 0x042f3000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c9500 }, + { _MMIO(0x9888), 0x0c4c002a }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0015 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c000a }, + { _MMIO(0x9888), 0x04193000 }, + { _MMIO(0x9888), 0x081a28c1 }, + { _MMIO(0x9888), 0x001a0000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x0613c000 }, + { _MMIO(0x9888), 0x0813f000 }, + { _MMIO(0x9888), 0x00172000 }, + { _MMIO(0x9888), 0x06178000 }, + { _MMIO(0x9888), 0x0817a000 }, + { _MMIO(0x9888), 0x00180037 }, + { _MMIO(0x9888), 0x06180940 }, + { _MMIO(0x9888), 0x08180000 }, + { _MMIO(0x9888), 0x02180000 }, + { _MMIO(0x9888), 0x04183000 }, + { _MMIO(0x9888), 0x04afc000 }, + { _MMIO(0x9888), 0x06af3000 }, + { _MMIO(0x9888), 0x0acc4000 }, + { _MMIO(0x9888), 0x0ccc0015 }, + { _MMIO(0x9888), 0x0a8da000 }, + { _MMIO(0x9888), 0x0c8da000 }, + { _MMIO(0x9888), 0x0e8f4000 }, + { _MMIO(0x9888), 0x108f0015 }, + { _MMIO(0x9888), 0x16aca000 }, + { _MMIO(0x9888), 0x18ac000a }, + { _MMIO(0x9888), 0x06993000 }, + { _MMIO(0x9888), 0x0c9a28c1 }, + { _MMIO(0x9888), 0x009a0000 }, + { _MMIO(0x9888), 0x0a93f000 }, + { _MMIO(0x9888), 0x0c93f000 }, + { _MMIO(0x9888), 0x0a97a000 }, + { _MMIO(0x9888), 0x0c97a000 }, + { _MMIO(0x9888), 0x0a980977 }, + { _MMIO(0x9888), 0x08980000 }, + { _MMIO(0x9888), 0x04980000 }, + { _MMIO(0x9888), 0x06983000 }, + { _MMIO(0x9888), 0x119000ff }, + { _MMIO(0x9888), 0x51900040 }, + { _MMIO(0x9888), 0x41900020 }, + { _MMIO(0x9888), 0x55900004 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x479008a5 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900002 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_vme_pipe_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_vme_pipe; + lens[n] = ARRAY_SIZE(mux_config_vme_pipe); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x11810000 }, + { _MMIO(0x9888), 0x07810013 }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930040 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_kblgt3(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_L3_2: + dev_priv->perf.oa.n_mux_configs = + get_l3_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_2); + + return 0; + case METRIC_SET_ID_L3_3: + dev_priv->perf.oa.n_mux_configs = + get_l3_3_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_3; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_3); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_3; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_3); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER: + dev_priv->perf.oa.n_mux_configs = + get_sampler_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_VME_PIPE: + dev_priv->perf.oa.n_mux_configs = + get_vme_pipe_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_vme_pipe; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_vme_pipe); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_vme_pipe; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_vme_pipe); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "0286c920-2f6d-493b-b22d-7a5280df43de", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "9823aaa1-b06f-40ce-884b-cd798c79f0c2", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "c7c735f3-ce58-45cf-aa04-30b183f1faff", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "96ec2219-040b-428a-856a-6bc03363a057", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "03372b64-4996-4d3b-aa18-790e75eeb9c2", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "31b4ce5a-bd61-4c1f-bb5d-f2e731412150", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "2ce0911a-27fc-4887-96f0-11084fa807c3", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "546c4c1d-99b8-42fb-a107-5aaabb5314a8", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "4e93d156-9b39-4268-8544-a8e0480806d7", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2); +} + +static struct device_attribute dev_attr_l3_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_2_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_2[] = { + &dev_attr_l3_2_id.attr, + NULL, +}; + +static struct attribute_group group_l3_2 = { + .name = "de1bec86-ca92-4b43-89fa-147653221cc0", + .attrs = attrs_l3_2, +}; + +static ssize_t +show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3); +} + +static struct device_attribute dev_attr_l3_3_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_3_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_3[] = { + &dev_attr_l3_3_id.attr, + NULL, +}; + +static struct attribute_group group_l3_3 = { + .name = "e63537bb-10be-4d4a-92c4-c6b0c65e02ef", + .attrs = attrs_l3_3, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "7a03a9f8-ec5e-46bb-8b67-1f0ff1476281", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER); +} + +static struct device_attribute dev_attr_sampler_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler[] = { + &dev_attr_sampler_id.attr, + NULL, +}; + +static struct attribute_group group_sampler = { + .name = "b25d2ebf-a6e0-4b29-96be-a9b010edeeda", + .attrs = attrs_sampler, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "469a05e5-e299-46f7-9598-7b05f3c34991", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "52f925c6-786a-4ec6-86ce-cba85c83453a", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "efc497ac-884e-4ee4-a4a8-15fba22aaf21", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE); +} + +static struct device_attribute dev_attr_vme_pipe_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_vme_pipe_id, + .store = NULL, +}; + +static struct attribute *attrs_vme_pipe[] = { + &dev_attr_vme_pipe_id.attr, + NULL, +}; + +static struct attribute_group group_vme_pipe = { + .name = "bfd9764d-2c5b-4c16-bfc1-89de3ca10917", + .attrs = attrs_vme_pipe, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "f1792f32-6db2-4b50-b4b2-557128f1688d", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_kblgt3(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (ret) + goto error_l3_2; + } + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (ret) + goto error_l3_3; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (ret) + goto error_sampler; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (ret) + goto error_vme_pipe; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); +error_vme_pipe: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); +error_sampler: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); +error_l3_3: + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); +error_l3_2: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_kblgt3(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.h b/drivers/gpu/drm/i915/i915_oa_kblgt3.h new file mode 100644 index 0000000..b0ca7f3 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_KBLGT3_H__ +#define __I915_OA_KBLGT3_H__ + +extern int i915_oa_n_builtin_metric_sets_kblgt3; + +extern int i915_oa_select_metric_set_kblgt3(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_kblgt3(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_kblgt3(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.c b/drivers/gpu/drm/i915/i915_oa_sklgt2.c new file mode 100644 index 0000000..1268bed --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.c @@ -0,0 +1,3479 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_sklgt2.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_L3_2, + METRIC_SET_ID_L3_3, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_VME_PIPE, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_sklgt2 = 18; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic_1_sku_gte_0x02[] = { + { _MMIO(0x9888), 0x166c01e0 }, + { _MMIO(0x9888), 0x12170280 }, + { _MMIO(0x9888), 0x12370280 }, + { _MMIO(0x9888), 0x11930317 }, + { _MMIO(0x9888), 0x159303df }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x1a4e0080 }, + { _MMIO(0x9888), 0x0a6c0053 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x0a1b4000 }, + { _MMIO(0x9888), 0x1c1c0001 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x042f1000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c8400 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0d2000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f6600 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x162c2200 }, + { _MMIO(0x9888), 0x062d8000 }, + { _MMIO(0x9888), 0x082d8000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x08133000 }, + { _MMIO(0x9888), 0x00170020 }, + { _MMIO(0x9888), 0x08170021 }, + { _MMIO(0x9888), 0x10170000 }, + { _MMIO(0x9888), 0x0633c000 }, + { _MMIO(0x9888), 0x0833c000 }, + { _MMIO(0x9888), 0x06370800 }, + { _MMIO(0x9888), 0x08370840 }, + { _MMIO(0x9888), 0x10370000 }, + { _MMIO(0x9888), 0x0d933031 }, + { _MMIO(0x9888), 0x0f933e3f }, + { _MMIO(0x9888), 0x01933d00 }, + { _MMIO(0x9888), 0x0393073c }, + { _MMIO(0x9888), 0x0593000e }, + { _MMIO(0x9888), 0x1d930000 }, + { _MMIO(0x9888), 0x19930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x15908000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190001f }, + { _MMIO(0x9888), 0x51904400 }, + { _MMIO(0x9888), 0x41900020 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c21 }, + { _MMIO(0x9888), 0x47900061 }, + { _MMIO(0x9888), 0x57904440 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900004 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x53904444 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + if (dev_priv->drm.pdev->revision >= 0x02) { + regs[n] = mux_config_render_basic_1_sku_gte_0x02; + lens[n] = ARRAY_SIZE(mux_config_render_basic_1_sku_gte_0x02); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901403 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4e8200 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x004f0db2 }, + { _MMIO(0x9888), 0x064f0900 }, + { _MMIO(0x9888), 0x084f1880 }, + { _MMIO(0x9888), 0x0a4f0011 }, + { _MMIO(0x9888), 0x0c4f0e3c }, + { _MMIO(0x9888), 0x0e4f1d80 }, + { _MMIO(0x9888), 0x086c0002 }, + { _MMIO(0x9888), 0x0a6c0100 }, + { _MMIO(0x9888), 0x0e6c000c }, + { _MMIO(0x9888), 0x026c000b }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x081b4000 }, + { _MMIO(0x9888), 0x0a1b8000 }, + { _MMIO(0x9888), 0x0e1b4000 }, + { _MMIO(0x9888), 0x021b4000 }, + { _MMIO(0x9888), 0x1a1c4000 }, + { _MMIO(0x9888), 0x1c1c0012 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x005bc000 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b8000 }, + { _MMIO(0x9888), 0x0a5b4000 }, + { _MMIO(0x9888), 0x0c5bc000 }, + { _MMIO(0x9888), 0x0e5b8000 }, + { _MMIO(0x9888), 0x105c8000 }, + { _MMIO(0x9888), 0x1a5ca000 }, + { _MMIO(0x9888), 0x1c5c002d }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x0a4c0800 }, + { _MMIO(0x9888), 0x0c4c0082 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020d2000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002cc000 }, + { _MMIO(0x9888), 0x0e2cc000 }, + { _MMIO(0x9888), 0x162cbe00 }, + { _MMIO(0x9888), 0x182c00ef }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x19900157 }, + { _MMIO(0x9888), 0x1b900167 }, + { _MMIO(0x9888), 0x1d900105 }, + { _MMIO(0x9888), 0x1f900103 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0xd28), 0x00000000 }, + { _MMIO(0x9888), 0x11900fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900840 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900842 }, + { _MMIO(0x9888), 0x47900840 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900840 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900040 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900840 }, + { _MMIO(0x9888), 0x53901111 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901403 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x1a4e0820 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x064f0900 }, + { _MMIO(0x9888), 0x084f0032 }, + { _MMIO(0x9888), 0x0a4f1810 }, + { _MMIO(0x9888), 0x0c4f0e00 }, + { _MMIO(0x9888), 0x0e4f003c }, + { _MMIO(0x9888), 0x004f0d80 }, + { _MMIO(0x9888), 0x024f003b }, + { _MMIO(0x9888), 0x006c0002 }, + { _MMIO(0x9888), 0x086c0000 }, + { _MMIO(0x9888), 0x0c6c000c }, + { _MMIO(0x9888), 0x0e6c0b00 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x081b8000 }, + { _MMIO(0x9888), 0x0c1b4000 }, + { _MMIO(0x9888), 0x0e1b8000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1c8000 }, + { _MMIO(0x9888), 0x1c1c0024 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5bc000 }, + { _MMIO(0x9888), 0x0c5b8000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x1a5c6000 }, + { _MMIO(0x9888), 0x1c5c001b }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2000 }, + { _MMIO(0x9888), 0x0c4c0208 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020d2000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2cc000 }, + { _MMIO(0x9888), 0x162cfb00 }, + { _MMIO(0x9888), 0x182c00be }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x19900157 }, + { _MMIO(0x9888), 0x1b900167 }, + { _MMIO(0x9888), 0x1d900105 }, + { _MMIO(0x9888), 0x1f900103 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x11900fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900842 }, + { _MMIO(0x9888), 0x47900802 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900802 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900002 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53901111 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2); + + if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) && + (dev_priv->drm.pdev->revision < 0x02)) { + regs[n] = mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02; + lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02); + n++; + } + if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) && + (dev_priv->drm.pdev->revision >= 0x02)) { + regs[n] = mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02; + lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile_0_sku_lt_0x02[] = { + { _MMIO(0x9888), 0x0c0e001f }, + { _MMIO(0x9888), 0x0a0f0000 }, + { _MMIO(0x9888), 0x10116800 }, + { _MMIO(0x9888), 0x178a03e0 }, + { _MMIO(0x9888), 0x11824c00 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x13840020 }, + { _MMIO(0x9888), 0x11850019 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x01870c40 }, + { _MMIO(0x9888), 0x17880000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x040d4000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020e5400 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x080f0040 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x0e0f0040 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06110012 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x01898000 }, + { _MMIO(0x9888), 0x0d890100 }, + { _MMIO(0x9888), 0x03898000 }, + { _MMIO(0x9888), 0x09808000 }, + { _MMIO(0x9888), 0x0b808000 }, + { _MMIO(0x9888), 0x0380c000 }, + { _MMIO(0x9888), 0x0f8a0075 }, + { _MMIO(0x9888), 0x1d8a0000 }, + { _MMIO(0x9888), 0x118a8000 }, + { _MMIO(0x9888), 0x1b8a4000 }, + { _MMIO(0x9888), 0x138a8000 }, + { _MMIO(0x9888), 0x1d81a000 }, + { _MMIO(0x9888), 0x15818000 }, + { _MMIO(0x9888), 0x17818000 }, + { _MMIO(0x9888), 0x0b820030 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x0d824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x05824000 }, + { _MMIO(0x9888), 0x0d830003 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x03838000 }, + { _MMIO(0x9888), 0x07838000 }, + { _MMIO(0x9888), 0x0b840980 }, + { _MMIO(0x9888), 0x03844d80 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x09850080 }, + { _MMIO(0x9888), 0x03850003 }, + { _MMIO(0x9888), 0x01850000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x09870032 }, + { _MMIO(0x9888), 0x01888052 }, + { _MMIO(0x9888), 0x11880000 }, + { _MMIO(0x9888), 0x09884000 }, + { _MMIO(0x9888), 0x15968000 }, + { _MMIO(0x9888), 0x17968000 }, + { _MMIO(0x9888), 0x0f96c000 }, + { _MMIO(0x9888), 0x1f950011 }, + { _MMIO(0x9888), 0x1d950014 }, + { _MMIO(0x9888), 0x0592c000 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d924000 }, + { _MMIO(0x9888), 0x0f924000 }, + { _MMIO(0x9888), 0x11928000 }, + { _MMIO(0x9888), 0x1392c000 }, + { _MMIO(0x9888), 0x09924000 }, + { _MMIO(0x9888), 0x01985000 }, + { _MMIO(0x9888), 0x07988000 }, + { _MMIO(0x9888), 0x09981000 }, + { _MMIO(0x9888), 0x0b982000 }, + { _MMIO(0x9888), 0x0d982000 }, + { _MMIO(0x9888), 0x0f989000 }, + { _MMIO(0x9888), 0x05982000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x0b978000 }, + { _MMIO(0x9888), 0x0f974000 }, + { _MMIO(0x9888), 0x11974000 }, + { _MMIO(0x9888), 0x13978000 }, + { _MMIO(0x9888), 0x09974000 }, + { _MMIO(0xd28), 0x00000000 }, + { _MMIO(0x9888), 0x1190c080 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x419010a0 }, + { _MMIO(0x9888), 0x55904000 }, + { _MMIO(0x9888), 0x45901000 }, + { _MMIO(0x9888), 0x47900084 }, + { _MMIO(0x9888), 0x57904400 }, + { _MMIO(0x9888), 0x499000a5 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900081 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x439014a4 }, + { _MMIO(0x9888), 0x53900400 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile_0_sku_gte_0x02[] = { + { _MMIO(0x9888), 0x0c0e001f }, + { _MMIO(0x9888), 0x0a0f0000 }, + { _MMIO(0x9888), 0x10116800 }, + { _MMIO(0x9888), 0x178a03e0 }, + { _MMIO(0x9888), 0x11824c00 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x13840020 }, + { _MMIO(0x9888), 0x11850019 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x01870c40 }, + { _MMIO(0x9888), 0x17880000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x040d4000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020e5400 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x080f0040 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x0e0f0040 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06110012 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x01898000 }, + { _MMIO(0x9888), 0x0d890100 }, + { _MMIO(0x9888), 0x03898000 }, + { _MMIO(0x9888), 0x09808000 }, + { _MMIO(0x9888), 0x0b808000 }, + { _MMIO(0x9888), 0x0380c000 }, + { _MMIO(0x9888), 0x0f8a0075 }, + { _MMIO(0x9888), 0x1d8a0000 }, + { _MMIO(0x9888), 0x118a8000 }, + { _MMIO(0x9888), 0x1b8a4000 }, + { _MMIO(0x9888), 0x138a8000 }, + { _MMIO(0x9888), 0x1d81a000 }, + { _MMIO(0x9888), 0x15818000 }, + { _MMIO(0x9888), 0x17818000 }, + { _MMIO(0x9888), 0x0b820030 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x0d824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x05824000 }, + { _MMIO(0x9888), 0x0d830003 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x03838000 }, + { _MMIO(0x9888), 0x07838000 }, + { _MMIO(0x9888), 0x0b840980 }, + { _MMIO(0x9888), 0x03844d80 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x09850080 }, + { _MMIO(0x9888), 0x03850003 }, + { _MMIO(0x9888), 0x01850000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x09870032 }, + { _MMIO(0x9888), 0x01888052 }, + { _MMIO(0x9888), 0x11880000 }, + { _MMIO(0x9888), 0x09884000 }, + { _MMIO(0x9888), 0x1b931001 }, + { _MMIO(0x9888), 0x1d930001 }, + { _MMIO(0x9888), 0x19934000 }, + { _MMIO(0x9888), 0x1b958000 }, + { _MMIO(0x9888), 0x1d950094 }, + { _MMIO(0x9888), 0x19958000 }, + { _MMIO(0x9888), 0x05e5a000 }, + { _MMIO(0x9888), 0x01e5c000 }, + { _MMIO(0x9888), 0x0592c000 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d924000 }, + { _MMIO(0x9888), 0x0f924000 }, + { _MMIO(0x9888), 0x11928000 }, + { _MMIO(0x9888), 0x1392c000 }, + { _MMIO(0x9888), 0x09924000 }, + { _MMIO(0x9888), 0x01985000 }, + { _MMIO(0x9888), 0x07988000 }, + { _MMIO(0x9888), 0x09981000 }, + { _MMIO(0x9888), 0x0b982000 }, + { _MMIO(0x9888), 0x0d982000 }, + { _MMIO(0x9888), 0x0f989000 }, + { _MMIO(0x9888), 0x05982000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1190c080 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x419010a0 }, + { _MMIO(0x9888), 0x55904000 }, + { _MMIO(0x9888), 0x45901000 }, + { _MMIO(0x9888), 0x47900084 }, + { _MMIO(0x9888), 0x57904400 }, + { _MMIO(0x9888), 0x499000a5 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900081 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x439014a4 }, + { _MMIO(0x9888), 0x53900400 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2); + + if (dev_priv->drm.pdev->revision < 0x02) { + regs[n] = mux_config_render_pipe_profile_0_sku_lt_0x02; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile_0_sku_lt_0x02); + n++; + } + if (dev_priv->drm.pdev->revision >= 0x02) { + regs[n] = mux_config_render_pipe_profile_0_sku_gte_0x02; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile_0_sku_gte_0x02); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x13946000 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x0f968000 }, + { _MMIO(0x9888), 0x1196c000 }, + { _MMIO(0x9888), 0x13964000 }, + { _MMIO(0x9888), 0x11938000 }, + { _MMIO(0x9888), 0x1b93fe00 }, + { _MMIO(0x9888), 0x01940010 }, + { _MMIO(0x9888), 0x07941100 }, + { _MMIO(0x9888), 0x09941312 }, + { _MMIO(0x9888), 0x0b941514 }, + { _MMIO(0x9888), 0x0d941716 }, + { _MMIO(0x9888), 0x11940000 }, + { _MMIO(0x9888), 0x19940000 }, + { _MMIO(0x9888), 0x1b940000 }, + { _MMIO(0x9888), 0x1d940000 }, + { _MMIO(0x9888), 0x1b954000 }, + { _MMIO(0x9888), 0x1d95a550 }, + { _MMIO(0x9888), 0x1f9502aa }, + { _MMIO(0x9888), 0x2f900157 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13908000 }, + { _MMIO(0x9888), 0x21908000 }, + { _MMIO(0x9888), 0x23908000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27908000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0xd28), 0x00000000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x13946000 }, + { _MMIO(0x9888), 0x15940016 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x19930800 }, + { _MMIO(0x9888), 0x1b93aa55 }, + { _MMIO(0x9888), 0x1d9300aa }, + { _MMIO(0x9888), 0x01940010 }, + { _MMIO(0x9888), 0x07941100 }, + { _MMIO(0x9888), 0x09941312 }, + { _MMIO(0x9888), 0x0b941514 }, + { _MMIO(0x9888), 0x0d941716 }, + { _MMIO(0x9888), 0x0f940018 }, + { _MMIO(0x9888), 0x1b940000 }, + { _MMIO(0x9888), 0x11940000 }, + { _MMIO(0x9888), 0x01e58000 }, + { _MMIO(0x9888), 0x03e57000 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13908000 }, + { _MMIO(0x9888), 0x21908000 }, + { _MMIO(0x9888), 0x23908000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27908000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c20 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x47900421 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900421 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900061 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads_0_sku_gte_0x05[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900064 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900150 }, + { _MMIO(0x9888), 0x21900151 }, + { _MMIO(0x9888), 0x23900152 }, + { _MMIO(0x9888), 0x25900153 }, + { _MMIO(0x9888), 0x27900154 }, + { _MMIO(0x9888), 0x29900155 }, + { _MMIO(0x9888), 0x2b900156 }, + { _MMIO(0x9888), 0x2d900157 }, + { _MMIO(0x9888), 0x2f90015f }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 3); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 3); + + if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) && + (dev_priv->drm.pdev->revision < 0x02)) { + regs[n] = mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02; + lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02); + n++; + } + if ((dev_priv->drm.pdev->revision < 0x05) && + (dev_priv->drm.pdev->revision >= 0x02)) { + regs[n] = mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02; + lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02); + n++; + } + if (dev_priv->drm.pdev->revision >= 0x05) { + regs[n] = mux_config_memory_reads_0_sku_gte_0x05; + lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_sku_gte_0x05); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x13945400 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901400 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x0f968000 }, + { _MMIO(0x9888), 0x1196c000 }, + { _MMIO(0x9888), 0x13964000 }, + { _MMIO(0x9888), 0x11938000 }, + { _MMIO(0x9888), 0x1b93fe00 }, + { _MMIO(0x9888), 0x01940010 }, + { _MMIO(0x9888), 0x07941100 }, + { _MMIO(0x9888), 0x09941312 }, + { _MMIO(0x9888), 0x0b941514 }, + { _MMIO(0x9888), 0x0d941716 }, + { _MMIO(0x9888), 0x11940000 }, + { _MMIO(0x9888), 0x19940000 }, + { _MMIO(0x9888), 0x1b940000 }, + { _MMIO(0x9888), 0x1d940000 }, + { _MMIO(0x9888), 0x1b954000 }, + { _MMIO(0x9888), 0x1d95a550 }, + { _MMIO(0x9888), 0x1f9502aa }, + { _MMIO(0x9888), 0x2f900167 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13908000 }, + { _MMIO(0x9888), 0x21908000 }, + { _MMIO(0x9888), 0x23908000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27908000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0xd28), 0x00000000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x13945400 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901400 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x19930800 }, + { _MMIO(0x9888), 0x1b93aa55 }, + { _MMIO(0x9888), 0x1d93002a }, + { _MMIO(0x9888), 0x01940010 }, + { _MMIO(0x9888), 0x07941100 }, + { _MMIO(0x9888), 0x09941312 }, + { _MMIO(0x9888), 0x0b941514 }, + { _MMIO(0x9888), 0x0d941716 }, + { _MMIO(0x9888), 0x1b940000 }, + { _MMIO(0x9888), 0x11940000 }, + { _MMIO(0x9888), 0x01e58000 }, + { _MMIO(0x9888), 0x03e57000 }, + { _MMIO(0x9888), 0x2f900167 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x13908000 }, + { _MMIO(0x9888), 0x21908000 }, + { _MMIO(0x9888), 0x23908000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27908000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c20 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x47900421 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900421 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes_0_sku_gte_0x05[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901000 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900160 }, + { _MMIO(0x9888), 0x21900161 }, + { _MMIO(0x9888), 0x23900162 }, + { _MMIO(0x9888), 0x25900163 }, + { _MMIO(0x9888), 0x27900164 }, + { _MMIO(0x9888), 0x29900165 }, + { _MMIO(0x9888), 0x2b900166 }, + { _MMIO(0x9888), 0x2d900167 }, + { _MMIO(0x9888), 0x2f900150 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 3); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 3); + + if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) && + (dev_priv->drm.pdev->revision < 0x02)) { + regs[n] = mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02; + lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02); + n++; + } + if ((dev_priv->drm.pdev->revision < 0x05) && + (dev_priv->drm.pdev->revision >= 0x02)) { + regs[n] = mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02; + lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02); + n++; + } + if (dev_priv->drm.pdev->revision >= 0x05) { + regs[n] = mux_config_memory_writes_0_sku_gte_0x05; + lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_sku_gte_0x05); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended_0_subslices_0x01[] = { + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x141c8160 }, + { _MMIO(0x9888), 0x161c8015 }, + { _MMIO(0x9888), 0x181c0120 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4eaaa0 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0e6c0b01 }, + { _MMIO(0x9888), 0x006c0200 }, + { _MMIO(0x9888), 0x026c000c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x001c0041 }, + { _MMIO(0x9888), 0x061c4200 }, + { _MMIO(0x9888), 0x081c4443 }, + { _MMIO(0x9888), 0x0a1c4645 }, + { _MMIO(0x9888), 0x0c1c7647 }, + { _MMIO(0x9888), 0x041c7357 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x101c0000 }, + { _MMIO(0x9888), 0x1a1c0000 }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4caa2a }, + { _MMIO(0x9888), 0x0c4c02aa }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5515 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0xd28), 0x00000000 }, + { _MMIO(0x9888), 0x11907fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900040 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900802 }, + { _MMIO(0x9888), 0x47900842 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900842 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900800 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) { + regs[n] = mux_config_compute_extended_0_subslices_0x01; + lens[n] = ARRAY_SIZE(mux_config_compute_extended_0_subslices_0x01); + n++; + } + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x166c0760 }, + { _MMIO(0x9888), 0x1593001e }, + { _MMIO(0x9888), 0x3f901403 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4e8020 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x006c0051 }, + { _MMIO(0x9888), 0x066c5000 }, + { _MMIO(0x9888), 0x086c5c5d }, + { _MMIO(0x9888), 0x0e6c5e5f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x061b8000 }, + { _MMIO(0x9888), 0x081bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1ce000 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2a00 }, + { _MMIO(0x9888), 0x0c4c0280 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f1500 }, + { _MMIO(0x9888), 0x100f0140 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162c0a00 }, + { _MMIO(0x9888), 0x182c00a0 }, + { _MMIO(0x9888), 0x03933300 }, + { _MMIO(0x9888), 0x05930032 }, + { _MMIO(0x9888), 0x11930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900167 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190030f }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900042 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x53901111 }, + { _MMIO(0x9888), 0x43900420 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x104f0232 }, + { _MMIO(0x9888), 0x124f4640 }, + { _MMIO(0x9888), 0x106c0232 }, + { _MMIO(0x9888), 0x11834400 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x004f1880 }, + { _MMIO(0x9888), 0x024f08bb }, + { _MMIO(0x9888), 0x044f001b }, + { _MMIO(0x9888), 0x046c0100 }, + { _MMIO(0x9888), 0x066c000b }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x041b8000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025bc000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x165c8000 }, + { _MMIO(0x9888), 0x185c8000 }, + { _MMIO(0x9888), 0x0a4c00a0 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x062cc000 }, + { _MMIO(0x9888), 0x082cc000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x0f8305c0 }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x07830000 }, + { _MMIO(0x9888), 0x1d950080 }, + { _MMIO(0x9888), 0x13928000 }, + { _MMIO(0x9888), 0x0f988000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x4b9000a0 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x126c7b40 }, + { _MMIO(0x9888), 0x166c0020 }, + { _MMIO(0x9888), 0x0a603444 }, + { _MMIO(0x9888), 0x0a613400 }, + { _MMIO(0x9888), 0x1a4ea800 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0800 }, + { _MMIO(0x9888), 0x0c1bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x1c1c003c }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x10600000 }, + { _MMIO(0x9888), 0x04600000 }, + { _MMIO(0x9888), 0x0c610044 }, + { _MMIO(0x9888), 0x10610000 }, + { _MMIO(0x9888), 0x06610000 }, + { _MMIO(0x9888), 0x0c4c02a8 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0154 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190ffc0 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900420 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900021 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900400 }, + { _MMIO(0x9888), 0x43900421 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_2[] = { + { _MMIO(0x9888), 0x126c02e0 }, + { _MMIO(0x9888), 0x146c0001 }, + { _MMIO(0x9888), 0x0a623400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x026c3324 }, + { _MMIO(0x9888), 0x046c3422 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x06614000 }, + { _MMIO(0x9888), 0x0c620044 }, + { _MMIO(0x9888), 0x10620000 }, + { _MMIO(0x9888), 0x06620000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_2; + lens[n] = ARRAY_SIZE(mux_config_l3_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_3[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_3[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_3[] = { + { _MMIO(0x9888), 0x126c4e80 }, + { _MMIO(0x9888), 0x146c0000 }, + { _MMIO(0x9888), 0x0a633400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x026c3321 }, + { _MMIO(0x9888), 0x046c342f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c2000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x06604000 }, + { _MMIO(0x9888), 0x0c630044 }, + { _MMIO(0x9888), 0x10630000 }, + { _MMIO(0x9888), 0x06630000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c00aa }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900002 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_3_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_3; + lens[n] = ARRAY_SIZE(mux_config_l3_3); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000efff }, + { _MMIO(0x2778), 0x00006000 }, + { _MMIO(0x277c), 0x0000f3ff }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x102f3800 }, + { _MMIO(0x9888), 0x144d0500 }, + { _MMIO(0x9888), 0x120d03c0 }, + { _MMIO(0x9888), 0x140d03cf }, + { _MMIO(0x9888), 0x0c0f0004 }, + { _MMIO(0x9888), 0x0c4e4000 }, + { _MMIO(0x9888), 0x042f0480 }, + { _MMIO(0x9888), 0x082f0000 }, + { _MMIO(0x9888), 0x022f0000 }, + { _MMIO(0x9888), 0x0a4c0090 }, + { _MMIO(0x9888), 0x064d0027 }, + { _MMIO(0x9888), 0x004d0000 }, + { _MMIO(0x9888), 0x000d0d40 }, + { _MMIO(0x9888), 0x020d803f }, + { _MMIO(0x9888), 0x040d8023 }, + { _MMIO(0x9888), 0x100d0000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020f0010 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x0e0f0050 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41901400 }, + { _MMIO(0x9888), 0x43901485 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler[] = { + { _MMIO(0x9888), 0x14152c00 }, + { _MMIO(0x9888), 0x16150005 }, + { _MMIO(0x9888), 0x121600a0 }, + { _MMIO(0x9888), 0x14352c00 }, + { _MMIO(0x9888), 0x16350005 }, + { _MMIO(0x9888), 0x123600a0 }, + { _MMIO(0x9888), 0x14552c00 }, + { _MMIO(0x9888), 0x16550005 }, + { _MMIO(0x9888), 0x125600a0 }, + { _MMIO(0x9888), 0x062f6000 }, + { _MMIO(0x9888), 0x022f2000 }, + { _MMIO(0x9888), 0x0c4c0050 }, + { _MMIO(0x9888), 0x0a4c0010 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0350 }, + { _MMIO(0x9888), 0x0c0fb000 }, + { _MMIO(0x9888), 0x0e0f00da }, + { _MMIO(0x9888), 0x182c0028 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x022dc000 }, + { _MMIO(0x9888), 0x042d4000 }, + { _MMIO(0x9888), 0x0c138000 }, + { _MMIO(0x9888), 0x0e132000 }, + { _MMIO(0x9888), 0x0413c000 }, + { _MMIO(0x9888), 0x1c140018 }, + { _MMIO(0x9888), 0x0c157000 }, + { _MMIO(0x9888), 0x0e150078 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x04162180 }, + { _MMIO(0x9888), 0x02160000 }, + { _MMIO(0x9888), 0x04174000 }, + { _MMIO(0x9888), 0x0233a000 }, + { _MMIO(0x9888), 0x04333000 }, + { _MMIO(0x9888), 0x14348000 }, + { _MMIO(0x9888), 0x16348000 }, + { _MMIO(0x9888), 0x02357870 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x04360043 }, + { _MMIO(0x9888), 0x02360000 }, + { _MMIO(0x9888), 0x04371000 }, + { _MMIO(0x9888), 0x0e538000 }, + { _MMIO(0x9888), 0x00538000 }, + { _MMIO(0x9888), 0x06533000 }, + { _MMIO(0x9888), 0x1c540020 }, + { _MMIO(0x9888), 0x12548000 }, + { _MMIO(0x9888), 0x0e557000 }, + { _MMIO(0x9888), 0x00557800 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x06560043 }, + { _MMIO(0x9888), 0x02560000 }, + { _MMIO(0x9888), 0x06571000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900060 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900060 }, +}; + +static int +get_sampler_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler; + lens[n] = ARRAY_SIZE(mux_config_sampler); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x00007fff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x00009fff }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000efff }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000f3ff }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fdff }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x12120000 }, + { _MMIO(0x9888), 0x12320000 }, + { _MMIO(0x9888), 0x12520000 }, + { _MMIO(0x9888), 0x002f8000 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0015 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f03a0 }, + { _MMIO(0x9888), 0x0c0ff000 }, + { _MMIO(0x9888), 0x0e0f0095 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2d8000 }, + { _MMIO(0x9888), 0x0e2d4000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x02108000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x02118000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x02121880 }, + { _MMIO(0x9888), 0x041219b5 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x02134000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x0c308000 }, + { _MMIO(0x9888), 0x0e304000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x0c318000 }, + { _MMIO(0x9888), 0x0e314000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x0c321a80 }, + { _MMIO(0x9888), 0x0e320033 }, + { _MMIO(0x9888), 0x06320031 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x0c334000 }, + { _MMIO(0x9888), 0x0e331000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0e508000 }, + { _MMIO(0x9888), 0x00508000 }, + { _MMIO(0x9888), 0x02504000 }, + { _MMIO(0x9888), 0x0e518000 }, + { _MMIO(0x9888), 0x00518000 }, + { _MMIO(0x9888), 0x02514000 }, + { _MMIO(0x9888), 0x0e521880 }, + { _MMIO(0x9888), 0x00521a80 }, + { _MMIO(0x9888), 0x02520033 }, + { _MMIO(0x9888), 0x0e534000 }, + { _MMIO(0x9888), 0x00534000 }, + { _MMIO(0x9888), 0x02531000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900062 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x12124d60 }, + { _MMIO(0x9888), 0x12322e60 }, + { _MMIO(0x9888), 0x12524d60 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0014 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0fe000 }, + { _MMIO(0x9888), 0x0e0f0097 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x002d8000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x04121fb7 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x00308000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x00318000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x00321b80 }, + { _MMIO(0x9888), 0x0632003f }, + { _MMIO(0x9888), 0x00334000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0250c000 }, + { _MMIO(0x9888), 0x0251c000 }, + { _MMIO(0x9888), 0x02521fb7 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x02535000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900063 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { + { _MMIO(0xe458), 0x00001000 }, + { _MMIO(0xe558), 0x00003002 }, + { _MMIO(0xe658), 0x00005004 }, + { _MMIO(0xe758), 0x00011010 }, + { _MMIO(0xe45c), 0x00050012 }, + { _MMIO(0xe55c), 0x00052051 }, + { _MMIO(0xe65c), 0x00000008 }, +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x121203e0 }, + { _MMIO(0x9888), 0x123203e0 }, + { _MMIO(0x9888), 0x125203e0 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0e0f006c }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x042d8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06114000 }, + { _MMIO(0x9888), 0x06120033 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x04308000 }, + { _MMIO(0x9888), 0x04318000 }, + { _MMIO(0x9888), 0x04321980 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x04334000 }, + { _MMIO(0x9888), 0x04504000 }, + { _MMIO(0x9888), 0x04514000 }, + { _MMIO(0x9888), 0x04520033 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x04531000 }, + { _MMIO(0x9888), 0x1190e000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x43900c00 }, + { _MMIO(0x9888), 0x45900002 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_vme_pipe[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00100030 }, + { _MMIO(0x2774), 0x0000fff9 }, + { _MMIO(0x2778), 0x00000002 }, + { _MMIO(0x277c), 0x0000fffc }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000fff3 }, + { _MMIO(0x2788), 0x00100180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000ff3f }, +}; + +static const struct i915_oa_reg flex_eu_config_vme_pipe[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00008003 }, +}; + +static const struct i915_oa_reg mux_config_vme_pipe[] = { + { _MMIO(0x9888), 0x141a5800 }, + { _MMIO(0x9888), 0x161a00c0 }, + { _MMIO(0x9888), 0x12180240 }, + { _MMIO(0x9888), 0x14180002 }, + { _MMIO(0x9888), 0x143a5800 }, + { _MMIO(0x9888), 0x163a00c0 }, + { _MMIO(0x9888), 0x12380240 }, + { _MMIO(0x9888), 0x14380002 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x022f8000 }, + { _MMIO(0x9888), 0x042f3000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c1500 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f9500 }, + { _MMIO(0x9888), 0x100f002a }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162c0a00 }, + { _MMIO(0x9888), 0x0a2dc000 }, + { _MMIO(0x9888), 0x0c2dc000 }, + { _MMIO(0x9888), 0x04193000 }, + { _MMIO(0x9888), 0x081a28c1 }, + { _MMIO(0x9888), 0x001a0000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x0613c000 }, + { _MMIO(0x9888), 0x0813f000 }, + { _MMIO(0x9888), 0x00172000 }, + { _MMIO(0x9888), 0x06178000 }, + { _MMIO(0x9888), 0x0817a000 }, + { _MMIO(0x9888), 0x00180037 }, + { _MMIO(0x9888), 0x06180940 }, + { _MMIO(0x9888), 0x08180000 }, + { _MMIO(0x9888), 0x02180000 }, + { _MMIO(0x9888), 0x04183000 }, + { _MMIO(0x9888), 0x06393000 }, + { _MMIO(0x9888), 0x0c3a28c1 }, + { _MMIO(0x9888), 0x003a0000 }, + { _MMIO(0x9888), 0x0a33f000 }, + { _MMIO(0x9888), 0x0c33f000 }, + { _MMIO(0x9888), 0x0a37a000 }, + { _MMIO(0x9888), 0x0c37a000 }, + { _MMIO(0x9888), 0x0a380977 }, + { _MMIO(0x9888), 0x08380000 }, + { _MMIO(0x9888), 0x04380000 }, + { _MMIO(0x9888), 0x06383000 }, + { _MMIO(0x9888), 0x119000ff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900040 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900800 }, + { _MMIO(0x9888), 0x47901000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900844 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_vme_pipe_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_vme_pipe; + lens[n] = ARRAY_SIZE(mux_config_vme_pipe); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x11810000 }, + { _MMIO(0x9888), 0x07810016 }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930040 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_sklgt2(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_L3_2: + dev_priv->perf.oa.n_mux_configs = + get_l3_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_2); + + return 0; + case METRIC_SET_ID_L3_3: + dev_priv->perf.oa.n_mux_configs = + get_l3_3_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_3; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_3); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_3; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_3); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER: + dev_priv->perf.oa.n_mux_configs = + get_sampler_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_VME_PIPE: + dev_priv->perf.oa.n_mux_configs = + get_vme_pipe_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_vme_pipe; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_vme_pipe); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_vme_pipe; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_vme_pipe); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "f519e481-24d2-4d42-87c9-3fdd12c00202", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "fe47b29d-ae51-423e-bff4-27d965a95b60", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "e0ad5ae0-84ba-4f29-a723-1906c12cb774", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "9bc436dd-6130-4add-affc-283eb6eaa864", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "2ea0da8f-3527-4669-9d9d-13099a7435bf", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "d97d16af-028b-4cd1-a672-6210cb5513dd", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "9fb22842-e708-43f7-9752-e0e41670c39e", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "5378e2a1-4248-4188-a4ae-da25a794c603", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "f42cdd6a-b000-42cb-870f-5eb423a7f514", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2); +} + +static struct device_attribute dev_attr_l3_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_2_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_2[] = { + &dev_attr_l3_2_id.attr, + NULL, +}; + +static struct attribute_group group_l3_2 = { + .name = "b9bf2423-d88c-4a7b-a051-627611d00dcc", + .attrs = attrs_l3_2, +}; + +static ssize_t +show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3); +} + +static struct device_attribute dev_attr_l3_3_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_3_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_3[] = { + &dev_attr_l3_3_id.attr, + NULL, +}; + +static struct attribute_group group_l3_3 = { + .name = "2414a93d-d84f-406e-99c0-472161194b40", + .attrs = attrs_l3_3, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "53a45d2d-170b-4cf5-b7bb-585120c8e2f5", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER); +} + +static struct device_attribute dev_attr_sampler_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler[] = { + &dev_attr_sampler_id.attr, + NULL, +}; + +static struct attribute_group group_sampler = { + .name = "b4cff514-a91e-4798-a0b3-426ca13fc9c1", + .attrs = attrs_sampler, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "7821d13b-9b8b-4405-9618-78cd56b62cce", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "893f1a4d-919d-4388-8cb7-746d73ea7259", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "41a24047-7484-4ead-ae37-de907e5ff2b2", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE); +} + +static struct device_attribute dev_attr_vme_pipe_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_vme_pipe_id, + .store = NULL, +}; + +static struct attribute *attrs_vme_pipe[] = { + &dev_attr_vme_pipe_id.attr, + NULL, +}; + +static struct attribute_group group_vme_pipe = { + .name = "95910492-943f-44bd-9461-390240f243fd", + .attrs = attrs_vme_pipe, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_sklgt2(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (ret) + goto error_l3_2; + } + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (ret) + goto error_l3_3; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (ret) + goto error_sampler; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (ret) + goto error_vme_pipe; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); +error_vme_pipe: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); +error_sampler: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); +error_l3_3: + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); +error_l3_2: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_sklgt2(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.h b/drivers/gpu/drm/i915/i915_oa_sklgt2.h new file mode 100644 index 0000000..f4397ba --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_SKLGT2_H__ +#define __I915_OA_SKLGT2_H__ + +extern int i915_oa_n_builtin_metric_sets_sklgt2; + +extern int i915_oa_select_metric_set_sklgt2(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_sklgt2(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_sklgt2(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.c b/drivers/gpu/drm/i915/i915_oa_sklgt3.c new file mode 100644 index 0000000..7765e22 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.c @@ -0,0 +1,3039 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_sklgt3.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_L3_2, + METRIC_SET_ID_L3_3, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_VME_PIPE, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_sklgt3 = 18; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic[] = { + { _MMIO(0x9888), 0x166c01e0 }, + { _MMIO(0x9888), 0x12170280 }, + { _MMIO(0x9888), 0x12370280 }, + { _MMIO(0x9888), 0x16ec01e0 }, + { _MMIO(0x9888), 0x11930317 }, + { _MMIO(0x9888), 0x159303df }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x1a4e0380 }, + { _MMIO(0x9888), 0x0a6c0053 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x0a1b4000 }, + { _MMIO(0x9888), 0x1c1c0001 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x042f1000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c8400 }, + { _MMIO(0x9888), 0x0c4c0002 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f6600 }, + { _MMIO(0x9888), 0x100f0001 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x162ca200 }, + { _MMIO(0x9888), 0x062d8000 }, + { _MMIO(0x9888), 0x082d8000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x08133000 }, + { _MMIO(0x9888), 0x00170020 }, + { _MMIO(0x9888), 0x08170021 }, + { _MMIO(0x9888), 0x10170000 }, + { _MMIO(0x9888), 0x0633c000 }, + { _MMIO(0x9888), 0x0833c000 }, + { _MMIO(0x9888), 0x06370800 }, + { _MMIO(0x9888), 0x08370840 }, + { _MMIO(0x9888), 0x10370000 }, + { _MMIO(0x9888), 0x1ace0200 }, + { _MMIO(0x9888), 0x0aec5300 }, + { _MMIO(0x9888), 0x10ec0000 }, + { _MMIO(0x9888), 0x1cec0000 }, + { _MMIO(0x9888), 0x0a9b8000 }, + { _MMIO(0x9888), 0x1c9c0002 }, + { _MMIO(0x9888), 0x0ccc0002 }, + { _MMIO(0x9888), 0x0a8d8000 }, + { _MMIO(0x9888), 0x108f0001 }, + { _MMIO(0x9888), 0x16ac8000 }, + { _MMIO(0x9888), 0x0d933031 }, + { _MMIO(0x9888), 0x0f933e3f }, + { _MMIO(0x9888), 0x01933d00 }, + { _MMIO(0x9888), 0x0393073c }, + { _MMIO(0x9888), 0x0593000e }, + { _MMIO(0x9888), 0x1d930000 }, + { _MMIO(0x9888), 0x19930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x15908000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190003f }, + { _MMIO(0x9888), 0x51907710 }, + { _MMIO(0x9888), 0x419020a0 }, + { _MMIO(0x9888), 0x55901515 }, + { _MMIO(0x9888), 0x45900529 }, + { _MMIO(0x9888), 0x47901025 }, + { _MMIO(0x9888), 0x57907770 }, + { _MMIO(0x9888), 0x49902100 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900108 }, + { _MMIO(0x9888), 0x59900007 }, + { _MMIO(0x9888), 0x43902108 }, + { _MMIO(0x9888), 0x53907777 }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_basic; + lens[n] = ARRAY_SIZE(mux_config_render_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x1a4e0820 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x064f0900 }, + { _MMIO(0x9888), 0x084f0032 }, + { _MMIO(0x9888), 0x0a4f1891 }, + { _MMIO(0x9888), 0x0c4f0e00 }, + { _MMIO(0x9888), 0x0e4f003c }, + { _MMIO(0x9888), 0x004f0d80 }, + { _MMIO(0x9888), 0x024f003b }, + { _MMIO(0x9888), 0x006c0002 }, + { _MMIO(0x9888), 0x086c0100 }, + { _MMIO(0x9888), 0x0c6c000c }, + { _MMIO(0x9888), 0x0e6c0b00 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x081b8000 }, + { _MMIO(0x9888), 0x0c1b4000 }, + { _MMIO(0x9888), 0x0e1b8000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1c8000 }, + { _MMIO(0x9888), 0x1c1c0024 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5bc000 }, + { _MMIO(0x9888), 0x0c5b8000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x1a5c6000 }, + { _MMIO(0x9888), 0x1c5c001b }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2000 }, + { _MMIO(0x9888), 0x0c4c0208 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020d2000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2cc000 }, + { _MMIO(0x9888), 0x162cfb00 }, + { _MMIO(0x9888), 0x182c00be }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x19900157 }, + { _MMIO(0x9888), 0x1b900158 }, + { _MMIO(0x9888), 0x1d900105 }, + { _MMIO(0x9888), 0x1f900103 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x11900fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900863 }, + { _MMIO(0x9888), 0x47900802 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900802 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900002 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900c62 }, + { _MMIO(0x9888), 0x53903333 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x0c0e001f }, + { _MMIO(0x9888), 0x0a0f0000 }, + { _MMIO(0x9888), 0x10116800 }, + { _MMIO(0x9888), 0x178a03e0 }, + { _MMIO(0x9888), 0x11824c00 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x13840020 }, + { _MMIO(0x9888), 0x11850019 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x01870c40 }, + { _MMIO(0x9888), 0x17880000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x040d4000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020e5400 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x080f0040 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x0e0f0040 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06110012 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x01898000 }, + { _MMIO(0x9888), 0x0d890100 }, + { _MMIO(0x9888), 0x03898000 }, + { _MMIO(0x9888), 0x09808000 }, + { _MMIO(0x9888), 0x0b808000 }, + { _MMIO(0x9888), 0x0380c000 }, + { _MMIO(0x9888), 0x0f8a0075 }, + { _MMIO(0x9888), 0x1d8a0000 }, + { _MMIO(0x9888), 0x118a8000 }, + { _MMIO(0x9888), 0x1b8a4000 }, + { _MMIO(0x9888), 0x138a8000 }, + { _MMIO(0x9888), 0x1d81a000 }, + { _MMIO(0x9888), 0x15818000 }, + { _MMIO(0x9888), 0x17818000 }, + { _MMIO(0x9888), 0x0b820030 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x0d824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x05824000 }, + { _MMIO(0x9888), 0x0d830003 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x03838000 }, + { _MMIO(0x9888), 0x07838000 }, + { _MMIO(0x9888), 0x0b840980 }, + { _MMIO(0x9888), 0x03844d80 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x09850080 }, + { _MMIO(0x9888), 0x03850003 }, + { _MMIO(0x9888), 0x01850000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x09870032 }, + { _MMIO(0x9888), 0x01888052 }, + { _MMIO(0x9888), 0x11880000 }, + { _MMIO(0x9888), 0x09884000 }, + { _MMIO(0x9888), 0x1b931001 }, + { _MMIO(0x9888), 0x1d930001 }, + { _MMIO(0x9888), 0x19934000 }, + { _MMIO(0x9888), 0x1b958000 }, + { _MMIO(0x9888), 0x1d950094 }, + { _MMIO(0x9888), 0x19958000 }, + { _MMIO(0x9888), 0x09e58000 }, + { _MMIO(0x9888), 0x0be58000 }, + { _MMIO(0x9888), 0x03e5c000 }, + { _MMIO(0x9888), 0x0592c000 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d924000 }, + { _MMIO(0x9888), 0x0f924000 }, + { _MMIO(0x9888), 0x11928000 }, + { _MMIO(0x9888), 0x1392c000 }, + { _MMIO(0x9888), 0x09924000 }, + { _MMIO(0x9888), 0x01985000 }, + { _MMIO(0x9888), 0x07988000 }, + { _MMIO(0x9888), 0x09981000 }, + { _MMIO(0x9888), 0x0b982000 }, + { _MMIO(0x9888), 0x0d982000 }, + { _MMIO(0x9888), 0x0f989000 }, + { _MMIO(0x9888), 0x05982000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1190c080 }, + { _MMIO(0x9888), 0x51901150 }, + { _MMIO(0x9888), 0x41901400 }, + { _MMIO(0x9888), 0x55905111 }, + { _MMIO(0x9888), 0x45901400 }, + { _MMIO(0x9888), 0x479004a5 }, + { _MMIO(0x9888), 0x57903455 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b9000a0 }, + { _MMIO(0x9888), 0x59900001 }, + { _MMIO(0x9888), 0x43900005 }, + { _MMIO(0x9888), 0x53900455 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900064 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900150 }, + { _MMIO(0x9888), 0x21900151 }, + { _MMIO(0x9888), 0x23900152 }, + { _MMIO(0x9888), 0x25900153 }, + { _MMIO(0x9888), 0x27900154 }, + { _MMIO(0x9888), 0x29900155 }, + { _MMIO(0x9888), 0x2b900156 }, + { _MMIO(0x9888), 0x2d900157 }, + { _MMIO(0x9888), 0x2f90015f }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901000 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900160 }, + { _MMIO(0x9888), 0x21900161 }, + { _MMIO(0x9888), 0x23900162 }, + { _MMIO(0x9888), 0x25900163 }, + { _MMIO(0x9888), 0x27900164 }, + { _MMIO(0x9888), 0x29900165 }, + { _MMIO(0x9888), 0x2b900166 }, + { _MMIO(0x9888), 0x2d900167 }, + { _MMIO(0x9888), 0x2f900150 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended[] = { + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x141c8160 }, + { _MMIO(0x9888), 0x161c8015 }, + { _MMIO(0x9888), 0x181c0120 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4eaaa0 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0e6c0b01 }, + { _MMIO(0x9888), 0x006c0200 }, + { _MMIO(0x9888), 0x026c000c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x001c0041 }, + { _MMIO(0x9888), 0x061c4200 }, + { _MMIO(0x9888), 0x081c4443 }, + { _MMIO(0x9888), 0x0a1c4645 }, + { _MMIO(0x9888), 0x0c1c7647 }, + { _MMIO(0x9888), 0x041c7357 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x101c0000 }, + { _MMIO(0x9888), 0x1a1c0000 }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4caa2a }, + { _MMIO(0x9888), 0x0c4c02aa }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5515 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x11907fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900040 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900802 }, + { _MMIO(0x9888), 0x47900842 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900842 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900800 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extended; + lens[n] = ARRAY_SIZE(mux_config_compute_extended); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x166c0760 }, + { _MMIO(0x9888), 0x1593001e }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4e8020 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x006c0051 }, + { _MMIO(0x9888), 0x066c5000 }, + { _MMIO(0x9888), 0x086c5c5d }, + { _MMIO(0x9888), 0x0e6c5e5f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x061b8000 }, + { _MMIO(0x9888), 0x081bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1ce000 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2a00 }, + { _MMIO(0x9888), 0x0c4c0280 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f1500 }, + { _MMIO(0x9888), 0x100f0140 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162c0a00 }, + { _MMIO(0x9888), 0x182c00a0 }, + { _MMIO(0x9888), 0x03933300 }, + { _MMIO(0x9888), 0x05930032 }, + { _MMIO(0x9888), 0x11930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190030f }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900063 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x53903333 }, + { _MMIO(0x9888), 0x43900840 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x104f0232 }, + { _MMIO(0x9888), 0x124f4640 }, + { _MMIO(0x9888), 0x106c0232 }, + { _MMIO(0x9888), 0x11834400 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x004f1880 }, + { _MMIO(0x9888), 0x024f08bb }, + { _MMIO(0x9888), 0x044f001b }, + { _MMIO(0x9888), 0x046c0100 }, + { _MMIO(0x9888), 0x066c000b }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x041b8000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025bc000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x165c8000 }, + { _MMIO(0x9888), 0x185c8000 }, + { _MMIO(0x9888), 0x0a4c00a0 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x062cc000 }, + { _MMIO(0x9888), 0x082cc000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x0f8305c0 }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x07830000 }, + { _MMIO(0x9888), 0x1d950080 }, + { _MMIO(0x9888), 0x13928000 }, + { _MMIO(0x9888), 0x0f988000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x59900005 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x126c7b40 }, + { _MMIO(0x9888), 0x166c0020 }, + { _MMIO(0x9888), 0x0a603444 }, + { _MMIO(0x9888), 0x0a613400 }, + { _MMIO(0x9888), 0x1a4ea800 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0800 }, + { _MMIO(0x9888), 0x0c1bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x1c1c003c }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x10600000 }, + { _MMIO(0x9888), 0x04600000 }, + { _MMIO(0x9888), 0x0c610044 }, + { _MMIO(0x9888), 0x10610000 }, + { _MMIO(0x9888), 0x06610000 }, + { _MMIO(0x9888), 0x0c4c02a8 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0154 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190ffc0 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900420 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900021 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900400 }, + { _MMIO(0x9888), 0x43900421 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_2[] = { + { _MMIO(0x9888), 0x126c02e0 }, + { _MMIO(0x9888), 0x146c0001 }, + { _MMIO(0x9888), 0x0a623400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x026c3324 }, + { _MMIO(0x9888), 0x046c3422 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x06614000 }, + { _MMIO(0x9888), 0x0c620044 }, + { _MMIO(0x9888), 0x10620000 }, + { _MMIO(0x9888), 0x06620000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_2; + lens[n] = ARRAY_SIZE(mux_config_l3_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_3[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_3[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_3[] = { + { _MMIO(0x9888), 0x126c4e80 }, + { _MMIO(0x9888), 0x146c0000 }, + { _MMIO(0x9888), 0x0a633400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x026c3321 }, + { _MMIO(0x9888), 0x046c342f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c2000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x06604000 }, + { _MMIO(0x9888), 0x0c630044 }, + { _MMIO(0x9888), 0x10630000 }, + { _MMIO(0x9888), 0x06630000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c00aa }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900002 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_3_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_3; + lens[n] = ARRAY_SIZE(mux_config_l3_3); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000efff }, + { _MMIO(0x2778), 0x00006000 }, + { _MMIO(0x277c), 0x0000f3ff }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x102f3800 }, + { _MMIO(0x9888), 0x144d0500 }, + { _MMIO(0x9888), 0x120d03c0 }, + { _MMIO(0x9888), 0x140d03cf }, + { _MMIO(0x9888), 0x0c0f0004 }, + { _MMIO(0x9888), 0x0c4e4000 }, + { _MMIO(0x9888), 0x042f0480 }, + { _MMIO(0x9888), 0x082f0000 }, + { _MMIO(0x9888), 0x022f0000 }, + { _MMIO(0x9888), 0x0a4c0090 }, + { _MMIO(0x9888), 0x064d0027 }, + { _MMIO(0x9888), 0x004d0000 }, + { _MMIO(0x9888), 0x000d0d40 }, + { _MMIO(0x9888), 0x020d803f }, + { _MMIO(0x9888), 0x040d8023 }, + { _MMIO(0x9888), 0x100d0000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020f0010 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x0e0f0050 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41901400 }, + { _MMIO(0x9888), 0x43901485 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler[] = { + { _MMIO(0x9888), 0x14152c00 }, + { _MMIO(0x9888), 0x16150005 }, + { _MMIO(0x9888), 0x121600a0 }, + { _MMIO(0x9888), 0x14352c00 }, + { _MMIO(0x9888), 0x16350005 }, + { _MMIO(0x9888), 0x123600a0 }, + { _MMIO(0x9888), 0x14552c00 }, + { _MMIO(0x9888), 0x16550005 }, + { _MMIO(0x9888), 0x125600a0 }, + { _MMIO(0x9888), 0x062f6000 }, + { _MMIO(0x9888), 0x022f2000 }, + { _MMIO(0x9888), 0x0c4c0050 }, + { _MMIO(0x9888), 0x0a4c0010 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0350 }, + { _MMIO(0x9888), 0x0c0fb000 }, + { _MMIO(0x9888), 0x0e0f00da }, + { _MMIO(0x9888), 0x182c0028 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x022dc000 }, + { _MMIO(0x9888), 0x042d4000 }, + { _MMIO(0x9888), 0x0c138000 }, + { _MMIO(0x9888), 0x0e132000 }, + { _MMIO(0x9888), 0x0413c000 }, + { _MMIO(0x9888), 0x1c140018 }, + { _MMIO(0x9888), 0x0c157000 }, + { _MMIO(0x9888), 0x0e150078 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x04162180 }, + { _MMIO(0x9888), 0x02160000 }, + { _MMIO(0x9888), 0x04174000 }, + { _MMIO(0x9888), 0x0233a000 }, + { _MMIO(0x9888), 0x04333000 }, + { _MMIO(0x9888), 0x14348000 }, + { _MMIO(0x9888), 0x16348000 }, + { _MMIO(0x9888), 0x02357870 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x04360043 }, + { _MMIO(0x9888), 0x02360000 }, + { _MMIO(0x9888), 0x04371000 }, + { _MMIO(0x9888), 0x0e538000 }, + { _MMIO(0x9888), 0x00538000 }, + { _MMIO(0x9888), 0x06533000 }, + { _MMIO(0x9888), 0x1c540020 }, + { _MMIO(0x9888), 0x12548000 }, + { _MMIO(0x9888), 0x0e557000 }, + { _MMIO(0x9888), 0x00557800 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x06560043 }, + { _MMIO(0x9888), 0x02560000 }, + { _MMIO(0x9888), 0x06571000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900060 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900060 }, +}; + +static int +get_sampler_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler; + lens[n] = ARRAY_SIZE(mux_config_sampler); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x00007fff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x00009fff }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000efff }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000f3ff }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fdff }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x12120000 }, + { _MMIO(0x9888), 0x12320000 }, + { _MMIO(0x9888), 0x12520000 }, + { _MMIO(0x9888), 0x002f8000 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0015 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f03a0 }, + { _MMIO(0x9888), 0x0c0ff000 }, + { _MMIO(0x9888), 0x0e0f0095 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2d8000 }, + { _MMIO(0x9888), 0x0e2d4000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x02108000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x02118000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x02121880 }, + { _MMIO(0x9888), 0x041219b5 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x02134000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x0c308000 }, + { _MMIO(0x9888), 0x0e304000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x0c318000 }, + { _MMIO(0x9888), 0x0e314000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x0c321a80 }, + { _MMIO(0x9888), 0x0e320033 }, + { _MMIO(0x9888), 0x06320031 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x0c334000 }, + { _MMIO(0x9888), 0x0e331000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0e508000 }, + { _MMIO(0x9888), 0x00508000 }, + { _MMIO(0x9888), 0x02504000 }, + { _MMIO(0x9888), 0x0e518000 }, + { _MMIO(0x9888), 0x00518000 }, + { _MMIO(0x9888), 0x02514000 }, + { _MMIO(0x9888), 0x0e521880 }, + { _MMIO(0x9888), 0x00521a80 }, + { _MMIO(0x9888), 0x02520033 }, + { _MMIO(0x9888), 0x0e534000 }, + { _MMIO(0x9888), 0x00534000 }, + { _MMIO(0x9888), 0x02531000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900062 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x12124d60 }, + { _MMIO(0x9888), 0x12322e60 }, + { _MMIO(0x9888), 0x12524d60 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0014 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0fe000 }, + { _MMIO(0x9888), 0x0e0f0097 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x002d8000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x04121fb7 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x00308000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x00318000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x00321b80 }, + { _MMIO(0x9888), 0x0632003f }, + { _MMIO(0x9888), 0x00334000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0250c000 }, + { _MMIO(0x9888), 0x0251c000 }, + { _MMIO(0x9888), 0x02521fb7 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x02535000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900063 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x121203e0 }, + { _MMIO(0x9888), 0x123203e0 }, + { _MMIO(0x9888), 0x125203e0 }, + { _MMIO(0x9888), 0x129203e0 }, + { _MMIO(0x9888), 0x12b203e0 }, + { _MMIO(0x9888), 0x12d203e0 }, + { _MMIO(0x9888), 0x024ec000 }, + { _MMIO(0x9888), 0x044ec000 }, + { _MMIO(0x9888), 0x064ec000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c0042 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f006d }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x042d8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06114000 }, + { _MMIO(0x9888), 0x06120033 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x04308000 }, + { _MMIO(0x9888), 0x04318000 }, + { _MMIO(0x9888), 0x04321980 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x04334000 }, + { _MMIO(0x9888), 0x04504000 }, + { _MMIO(0x9888), 0x04514000 }, + { _MMIO(0x9888), 0x04520033 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x04531000 }, + { _MMIO(0x9888), 0x00af8000 }, + { _MMIO(0x9888), 0x0acc0001 }, + { _MMIO(0x9888), 0x008d8000 }, + { _MMIO(0x9888), 0x028da000 }, + { _MMIO(0x9888), 0x0c8fb000 }, + { _MMIO(0x9888), 0x0e8f0001 }, + { _MMIO(0x9888), 0x06ac8000 }, + { _MMIO(0x9888), 0x02ad4000 }, + { _MMIO(0x9888), 0x02908000 }, + { _MMIO(0x9888), 0x02918000 }, + { _MMIO(0x9888), 0x02921980 }, + { _MMIO(0x9888), 0x00920000 }, + { _MMIO(0x9888), 0x02934000 }, + { _MMIO(0x9888), 0x02b04000 }, + { _MMIO(0x9888), 0x02b14000 }, + { _MMIO(0x9888), 0x02b20033 }, + { _MMIO(0x9888), 0x00b20000 }, + { _MMIO(0x9888), 0x02b31000 }, + { _MMIO(0x9888), 0x00d08000 }, + { _MMIO(0x9888), 0x00d18000 }, + { _MMIO(0x9888), 0x00d21980 }, + { _MMIO(0x9888), 0x00d34000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900402 }, + { _MMIO(0x9888), 0x53901550 }, + { _MMIO(0x9888), 0x45900080 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_vme_pipe[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00100030 }, + { _MMIO(0x2774), 0x0000fff9 }, + { _MMIO(0x2778), 0x00000002 }, + { _MMIO(0x277c), 0x0000fffc }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000fff3 }, + { _MMIO(0x2788), 0x00100180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000ff3f }, +}; + +static const struct i915_oa_reg flex_eu_config_vme_pipe[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00008003 }, +}; + +static const struct i915_oa_reg mux_config_vme_pipe[] = { + { _MMIO(0x9888), 0x141a5800 }, + { _MMIO(0x9888), 0x161a00c0 }, + { _MMIO(0x9888), 0x12180240 }, + { _MMIO(0x9888), 0x14180002 }, + { _MMIO(0x9888), 0x149a5800 }, + { _MMIO(0x9888), 0x169a00c0 }, + { _MMIO(0x9888), 0x12980240 }, + { _MMIO(0x9888), 0x14980002 }, + { _MMIO(0x9888), 0x1a4e3fc0 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x022f8000 }, + { _MMIO(0x9888), 0x042f3000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c9500 }, + { _MMIO(0x9888), 0x0c4c002a }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0015 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c000a }, + { _MMIO(0x9888), 0x04193000 }, + { _MMIO(0x9888), 0x081a28c1 }, + { _MMIO(0x9888), 0x001a0000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x0613c000 }, + { _MMIO(0x9888), 0x0813f000 }, + { _MMIO(0x9888), 0x00172000 }, + { _MMIO(0x9888), 0x06178000 }, + { _MMIO(0x9888), 0x0817a000 }, + { _MMIO(0x9888), 0x00180037 }, + { _MMIO(0x9888), 0x06180940 }, + { _MMIO(0x9888), 0x08180000 }, + { _MMIO(0x9888), 0x02180000 }, + { _MMIO(0x9888), 0x04183000 }, + { _MMIO(0x9888), 0x04afc000 }, + { _MMIO(0x9888), 0x06af3000 }, + { _MMIO(0x9888), 0x0acc4000 }, + { _MMIO(0x9888), 0x0ccc0015 }, + { _MMIO(0x9888), 0x0a8da000 }, + { _MMIO(0x9888), 0x0c8da000 }, + { _MMIO(0x9888), 0x0e8f4000 }, + { _MMIO(0x9888), 0x108f0015 }, + { _MMIO(0x9888), 0x16aca000 }, + { _MMIO(0x9888), 0x18ac000a }, + { _MMIO(0x9888), 0x06993000 }, + { _MMIO(0x9888), 0x0c9a28c1 }, + { _MMIO(0x9888), 0x009a0000 }, + { _MMIO(0x9888), 0x0a93f000 }, + { _MMIO(0x9888), 0x0c93f000 }, + { _MMIO(0x9888), 0x0a97a000 }, + { _MMIO(0x9888), 0x0c97a000 }, + { _MMIO(0x9888), 0x0a980977 }, + { _MMIO(0x9888), 0x08980000 }, + { _MMIO(0x9888), 0x04980000 }, + { _MMIO(0x9888), 0x06983000 }, + { _MMIO(0x9888), 0x119000ff }, + { _MMIO(0x9888), 0x51900050 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x55900115 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x47900884 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900002 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_vme_pipe_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_vme_pipe; + lens[n] = ARRAY_SIZE(mux_config_vme_pipe); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x11810000 }, + { _MMIO(0x9888), 0x07810013 }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930040 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_sklgt3(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_L3_2: + dev_priv->perf.oa.n_mux_configs = + get_l3_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_2); + + return 0; + case METRIC_SET_ID_L3_3: + dev_priv->perf.oa.n_mux_configs = + get_l3_3_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_3; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_3); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_3; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_3); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER: + dev_priv->perf.oa.n_mux_configs = + get_sampler_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_VME_PIPE: + dev_priv->perf.oa.n_mux_configs = + get_vme_pipe_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_vme_pipe; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_vme_pipe); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_vme_pipe; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_vme_pipe); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "4616d450-2393-4836-8146-53c5ed84d359", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "4320492b-fd03-42ac-922f-dbe1ef3b7b58", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "bd2d9cae-b9ec-4f5b-9d2f-934bed398a2d", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "4ca0f3fe-7fd3-4924-98cb-1807d9879767", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "a0c0172c-ee13-403d-99ff-2bdf6936cf14", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "52435e0b-f188-42ea-8680-21a56ee20dee", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "27076eeb-49f3-4fed-8423-c66506005c63", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "8071b409-c39a-4674-94d7-32962ecfb512", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "5e0b391e-9ea8-4901-b2ff-b64ff616c7ed", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2); +} + +static struct device_attribute dev_attr_l3_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_2_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_2[] = { + &dev_attr_l3_2_id.attr, + NULL, +}; + +static struct attribute_group group_l3_2 = { + .name = "25dc828e-1d2d-426e-9546-a1d4233cdf16", + .attrs = attrs_l3_2, +}; + +static ssize_t +show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3); +} + +static struct device_attribute dev_attr_l3_3_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_3_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_3[] = { + &dev_attr_l3_3_id.attr, + NULL, +}; + +static struct attribute_group group_l3_3 = { + .name = "3dba9405-2d7e-4d70-8199-e734e82fd6bf", + .attrs = attrs_l3_3, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "76935d7b-09c9-46bf-87f1-c18b4a86ebe5", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER); +} + +static struct device_attribute dev_attr_sampler_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler[] = { + &dev_attr_sampler_id.attr, + NULL, +}; + +static struct attribute_group group_sampler = { + .name = "1b34c0d6-4f4c-4d7b-833f-4aaf236d87a6", + .attrs = attrs_sampler, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "b375c985-9953-455b-bda2-b03f7594e9db", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "3e2be2bb-884a-49bb-82c5-2358e6bd5f2d", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "2d80a648-7b5a-4e92-bbe7-3b5c76f2e221", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE); +} + +static struct device_attribute dev_attr_vme_pipe_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_vme_pipe_id, + .store = NULL, +}; + +static struct attribute *attrs_vme_pipe[] = { + &dev_attr_vme_pipe_id.attr, + NULL, +}; + +static struct attribute_group group_vme_pipe = { + .name = "cfae9232-6ffc-42cc-a703-9790016925f0", + .attrs = attrs_vme_pipe, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "2b985803-d3c9-4629-8a4f-634bfecba0e8", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_sklgt3(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (ret) + goto error_l3_2; + } + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (ret) + goto error_l3_3; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (ret) + goto error_sampler; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (ret) + goto error_vme_pipe; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); +error_vme_pipe: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); +error_sampler: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); +error_l3_3: + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); +error_l3_2: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_sklgt3(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.h b/drivers/gpu/drm/i915/i915_oa_sklgt3.h new file mode 100644 index 0000000..c0accb1 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_SKLGT3_H__ +#define __I915_OA_SKLGT3_H__ + +extern int i915_oa_n_builtin_metric_sets_sklgt3; + +extern int i915_oa_select_metric_set_sklgt3(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_sklgt3(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_sklgt3(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.c b/drivers/gpu/drm/i915/i915_oa_sklgt4.c new file mode 100644 index 0000000..9ddab43 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.c @@ -0,0 +1,3093 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 <linux/sysfs.h> + +#include "i915_drv.h" +#include "i915_oa_sklgt4.h" + +enum metric_set_id { + METRIC_SET_ID_RENDER_BASIC = 1, + METRIC_SET_ID_COMPUTE_BASIC, + METRIC_SET_ID_RENDER_PIPE_PROFILE, + METRIC_SET_ID_MEMORY_READS, + METRIC_SET_ID_MEMORY_WRITES, + METRIC_SET_ID_COMPUTE_EXTENDED, + METRIC_SET_ID_COMPUTE_L3_CACHE, + METRIC_SET_ID_HDC_AND_SF, + METRIC_SET_ID_L3_1, + METRIC_SET_ID_L3_2, + METRIC_SET_ID_L3_3, + METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND, + METRIC_SET_ID_SAMPLER, + METRIC_SET_ID_TDL_1, + METRIC_SET_ID_TDL_2, + METRIC_SET_ID_COMPUTE_EXTRA, + METRIC_SET_ID_VME_PIPE, + METRIC_SET_ID_TEST_OA, +}; + +int i915_oa_n_builtin_metric_sets_sklgt4 = 18; + +static const struct i915_oa_reg b_counter_config_render_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_render_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_render_basic[] = { + { _MMIO(0x9888), 0x166c01e0 }, + { _MMIO(0x9888), 0x12170280 }, + { _MMIO(0x9888), 0x12370280 }, + { _MMIO(0x9888), 0x16ec01e0 }, + { _MMIO(0x9888), 0x176c01e0 }, + { _MMIO(0x9888), 0x11930317 }, + { _MMIO(0x9888), 0x159303df }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x1a4e03b0 }, + { _MMIO(0x9888), 0x0a6c0053 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x0a1b4000 }, + { _MMIO(0x9888), 0x1c1c0001 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x042f1000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4ca400 }, + { _MMIO(0x9888), 0x0c4c0002 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f5600 }, + { _MMIO(0x9888), 0x100f0001 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x062d8000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x08133000 }, + { _MMIO(0x9888), 0x00170020 }, + { _MMIO(0x9888), 0x08170021 }, + { _MMIO(0x9888), 0x10170000 }, + { _MMIO(0x9888), 0x0633c000 }, + { _MMIO(0x9888), 0x06370800 }, + { _MMIO(0x9888), 0x10370000 }, + { _MMIO(0x9888), 0x1ace0230 }, + { _MMIO(0x9888), 0x0aec5300 }, + { _MMIO(0x9888), 0x10ec0000 }, + { _MMIO(0x9888), 0x1cec0000 }, + { _MMIO(0x9888), 0x0a9b8000 }, + { _MMIO(0x9888), 0x1c9c0002 }, + { _MMIO(0x9888), 0x0acc2000 }, + { _MMIO(0x9888), 0x0ccc0002 }, + { _MMIO(0x9888), 0x088d8000 }, + { _MMIO(0x9888), 0x0a8d8000 }, + { _MMIO(0x9888), 0x0e8f1000 }, + { _MMIO(0x9888), 0x108f0001 }, + { _MMIO(0x9888), 0x16ac8800 }, + { _MMIO(0x9888), 0x1b4e0020 }, + { _MMIO(0x9888), 0x096c5300 }, + { _MMIO(0x9888), 0x116c0000 }, + { _MMIO(0x9888), 0x1d6c0000 }, + { _MMIO(0x9888), 0x091b8000 }, + { _MMIO(0x9888), 0x1b1c8000 }, + { _MMIO(0x9888), 0x0b4c2000 }, + { _MMIO(0x9888), 0x090d8000 }, + { _MMIO(0x9888), 0x0f0f1000 }, + { _MMIO(0x9888), 0x172c0800 }, + { _MMIO(0x9888), 0x0d933031 }, + { _MMIO(0x9888), 0x0f933e3f }, + { _MMIO(0x9888), 0x01933d00 }, + { _MMIO(0x9888), 0x0393073c }, + { _MMIO(0x9888), 0x0593000e }, + { _MMIO(0x9888), 0x1d930000 }, + { _MMIO(0x9888), 0x19930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x2b908000 }, + { _MMIO(0x9888), 0x2d908000 }, + { _MMIO(0x9888), 0x2f908000 }, + { _MMIO(0x9888), 0x31908000 }, + { _MMIO(0x9888), 0x15908000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190003f }, + { _MMIO(0x9888), 0x5190ff30 }, + { _MMIO(0x9888), 0x41900060 }, + { _MMIO(0x9888), 0x55903033 }, + { _MMIO(0x9888), 0x45901421 }, + { _MMIO(0x9888), 0x47900803 }, + { _MMIO(0x9888), 0x5790fff1 }, + { _MMIO(0x9888), 0x49900001 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x5990000f }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x5390ffff }, +}; + +static int +get_render_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_basic; + lens[n] = ARRAY_SIZE(mux_config_render_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_basic[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2740), 0x00000000 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_basic[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_basic[] = { + { _MMIO(0x9888), 0x104f00e0 }, + { _MMIO(0x9888), 0x124f1c00 }, + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x1a4e0820 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x064f0900 }, + { _MMIO(0x9888), 0x084f0032 }, + { _MMIO(0x9888), 0x0a4f1891 }, + { _MMIO(0x9888), 0x0c4f0e00 }, + { _MMIO(0x9888), 0x0e4f003c }, + { _MMIO(0x9888), 0x004f0d80 }, + { _MMIO(0x9888), 0x024f003b }, + { _MMIO(0x9888), 0x006c0002 }, + { _MMIO(0x9888), 0x086c0100 }, + { _MMIO(0x9888), 0x0c6c000c }, + { _MMIO(0x9888), 0x0e6c0b00 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x081b8000 }, + { _MMIO(0x9888), 0x0c1b4000 }, + { _MMIO(0x9888), 0x0e1b8000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1c8000 }, + { _MMIO(0x9888), 0x1c1c0024 }, + { _MMIO(0x9888), 0x065b8000 }, + { _MMIO(0x9888), 0x085b4000 }, + { _MMIO(0x9888), 0x0a5bc000 }, + { _MMIO(0x9888), 0x0c5b8000 }, + { _MMIO(0x9888), 0x0e5b4000 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025b4000 }, + { _MMIO(0x9888), 0x1a5c6000 }, + { _MMIO(0x9888), 0x1c5c001b }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2000 }, + { _MMIO(0x9888), 0x0c4c0208 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020d2000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2cc000 }, + { _MMIO(0x9888), 0x162cfb00 }, + { _MMIO(0x9888), 0x182c00be }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x19900157 }, + { _MMIO(0x9888), 0x1b900158 }, + { _MMIO(0x9888), 0x1d900105 }, + { _MMIO(0x9888), 0x1f900103 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x11900fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900821 }, + { _MMIO(0x9888), 0x47900802 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900802 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900002 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900422 }, + { _MMIO(0x9888), 0x53905555 }, +}; + +static int +get_compute_basic_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_basic; + lens[n] = ARRAY_SIZE(mux_config_compute_basic); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007ffea }, + { _MMIO(0x2774), 0x00007ffc }, + { _MMIO(0x2778), 0x0007affa }, + { _MMIO(0x277c), 0x0000f5fd }, + { _MMIO(0x2780), 0x00079ffa }, + { _MMIO(0x2784), 0x0000f3fb }, + { _MMIO(0x2788), 0x0007bf7a }, + { _MMIO(0x278c), 0x0000f7e7 }, + { _MMIO(0x2790), 0x0007fefa }, + { _MMIO(0x2794), 0x0000f7cf }, + { _MMIO(0x2798), 0x00077ffa }, + { _MMIO(0x279c), 0x0000efdf }, + { _MMIO(0x27a0), 0x0006fffa }, + { _MMIO(0x27a4), 0x0000cfbf }, + { _MMIO(0x27a8), 0x0003fffa }, + { _MMIO(0x27ac), 0x00005f7f }, +}; + +static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_render_pipe_profile[] = { + { _MMIO(0x9888), 0x0c0e001f }, + { _MMIO(0x9888), 0x0a0f0000 }, + { _MMIO(0x9888), 0x10116800 }, + { _MMIO(0x9888), 0x178a03e0 }, + { _MMIO(0x9888), 0x11824c00 }, + { _MMIO(0x9888), 0x11830020 }, + { _MMIO(0x9888), 0x13840020 }, + { _MMIO(0x9888), 0x11850019 }, + { _MMIO(0x9888), 0x11860007 }, + { _MMIO(0x9888), 0x01870c40 }, + { _MMIO(0x9888), 0x17880000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0a4c0040 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x040d4000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020e5400 }, + { _MMIO(0x9888), 0x000e0000 }, + { _MMIO(0x9888), 0x080f0040 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x100f0000 }, + { _MMIO(0x9888), 0x0e0f0040 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06110012 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x01898000 }, + { _MMIO(0x9888), 0x0d890100 }, + { _MMIO(0x9888), 0x03898000 }, + { _MMIO(0x9888), 0x09808000 }, + { _MMIO(0x9888), 0x0b808000 }, + { _MMIO(0x9888), 0x0380c000 }, + { _MMIO(0x9888), 0x0f8a0075 }, + { _MMIO(0x9888), 0x1d8a0000 }, + { _MMIO(0x9888), 0x118a8000 }, + { _MMIO(0x9888), 0x1b8a4000 }, + { _MMIO(0x9888), 0x138a8000 }, + { _MMIO(0x9888), 0x1d81a000 }, + { _MMIO(0x9888), 0x15818000 }, + { _MMIO(0x9888), 0x17818000 }, + { _MMIO(0x9888), 0x0b820030 }, + { _MMIO(0x9888), 0x07828000 }, + { _MMIO(0x9888), 0x0d824000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x05824000 }, + { _MMIO(0x9888), 0x0d830003 }, + { _MMIO(0x9888), 0x0583000c }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x03838000 }, + { _MMIO(0x9888), 0x07838000 }, + { _MMIO(0x9888), 0x0b840980 }, + { _MMIO(0x9888), 0x03844d80 }, + { _MMIO(0x9888), 0x11840000 }, + { _MMIO(0x9888), 0x09848000 }, + { _MMIO(0x9888), 0x09850080 }, + { _MMIO(0x9888), 0x03850003 }, + { _MMIO(0x9888), 0x01850000 }, + { _MMIO(0x9888), 0x07860000 }, + { _MMIO(0x9888), 0x0f860400 }, + { _MMIO(0x9888), 0x09870032 }, + { _MMIO(0x9888), 0x01888052 }, + { _MMIO(0x9888), 0x11880000 }, + { _MMIO(0x9888), 0x09884000 }, + { _MMIO(0x9888), 0x1b931001 }, + { _MMIO(0x9888), 0x1d930001 }, + { _MMIO(0x9888), 0x19934000 }, + { _MMIO(0x9888), 0x1b958000 }, + { _MMIO(0x9888), 0x1d950094 }, + { _MMIO(0x9888), 0x19958000 }, + { _MMIO(0x9888), 0x09e58000 }, + { _MMIO(0x9888), 0x0be58000 }, + { _MMIO(0x9888), 0x03e5c000 }, + { _MMIO(0x9888), 0x0592c000 }, + { _MMIO(0x9888), 0x0b928000 }, + { _MMIO(0x9888), 0x0d924000 }, + { _MMIO(0x9888), 0x0f924000 }, + { _MMIO(0x9888), 0x11928000 }, + { _MMIO(0x9888), 0x1392c000 }, + { _MMIO(0x9888), 0x09924000 }, + { _MMIO(0x9888), 0x01985000 }, + { _MMIO(0x9888), 0x07988000 }, + { _MMIO(0x9888), 0x09981000 }, + { _MMIO(0x9888), 0x0b982000 }, + { _MMIO(0x9888), 0x0d982000 }, + { _MMIO(0x9888), 0x0f989000 }, + { _MMIO(0x9888), 0x05982000 }, + { _MMIO(0x9888), 0x13904000 }, + { _MMIO(0x9888), 0x21904000 }, + { _MMIO(0x9888), 0x23904000 }, + { _MMIO(0x9888), 0x25908000 }, + { _MMIO(0x9888), 0x27904000 }, + { _MMIO(0x9888), 0x29908000 }, + { _MMIO(0x9888), 0x2b904000 }, + { _MMIO(0x9888), 0x2f904000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x15904000 }, + { _MMIO(0x9888), 0x17908000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b904000 }, + { _MMIO(0x9888), 0x1190c080 }, + { _MMIO(0x9888), 0x51901110 }, + { _MMIO(0x9888), 0x41900440 }, + { _MMIO(0x9888), 0x55901111 }, + { _MMIO(0x9888), 0x45900400 }, + { _MMIO(0x9888), 0x47900c21 }, + { _MMIO(0x9888), 0x57901411 }, + { _MMIO(0x9888), 0x49900042 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900024 }, + { _MMIO(0x9888), 0x59900001 }, + { _MMIO(0x9888), 0x43900841 }, + { _MMIO(0x9888), 0x53900411 }, +}; + +static int +get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_render_pipe_profile; + lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_reads[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f872 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_reads[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_reads[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f900064 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900150 }, + { _MMIO(0x9888), 0x21900151 }, + { _MMIO(0x9888), 0x23900152 }, + { _MMIO(0x9888), 0x25900153 }, + { _MMIO(0x9888), 0x27900154 }, + { _MMIO(0x9888), 0x29900155 }, + { _MMIO(0x9888), 0x2b900156 }, + { _MMIO(0x9888), 0x2d900157 }, + { _MMIO(0x9888), 0x2f90015f }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_reads_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_reads; + lens[n] = ARRAY_SIZE(mux_config_memory_reads); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_memory_writes[] = { + { _MMIO(0x272c), 0xffffffff }, + { _MMIO(0x2728), 0xffffffff }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x271c), 0xffffffff }, + { _MMIO(0x2718), 0xffffffff }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x274c), 0x86543210 }, + { _MMIO(0x2748), 0x86543210 }, + { _MMIO(0x2744), 0x00006667 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x275c), 0x86543210 }, + { _MMIO(0x2758), 0x86543210 }, + { _MMIO(0x2754), 0x00006465 }, + { _MMIO(0x2750), 0x00000000 }, + { _MMIO(0x2770), 0x0007f81a }, + { _MMIO(0x2774), 0x0000fe00 }, + { _MMIO(0x2778), 0x0007f82a }, + { _MMIO(0x277c), 0x0000fe00 }, + { _MMIO(0x2780), 0x0007f822 }, + { _MMIO(0x2784), 0x0000fe00 }, + { _MMIO(0x2788), 0x0007f8ba }, + { _MMIO(0x278c), 0x0000fe00 }, + { _MMIO(0x2790), 0x0007f87a }, + { _MMIO(0x2794), 0x0000fe00 }, + { _MMIO(0x2798), 0x0007f8ea }, + { _MMIO(0x279c), 0x0000fe00 }, + { _MMIO(0x27a0), 0x0007f8e2 }, + { _MMIO(0x27a4), 0x0000fe00 }, + { _MMIO(0x27a8), 0x0007f8f2 }, + { _MMIO(0x27ac), 0x0000fe00 }, +}; + +static const struct i915_oa_reg flex_eu_config_memory_writes[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00015014 }, + { _MMIO(0xe658), 0x00025024 }, + { _MMIO(0xe758), 0x00035034 }, + { _MMIO(0xe45c), 0x00045044 }, + { _MMIO(0xe55c), 0x00055054 }, + { _MMIO(0xe65c), 0x00065064 }, +}; + +static const struct i915_oa_reg mux_config_memory_writes[] = { + { _MMIO(0x9888), 0x11810c00 }, + { _MMIO(0x9888), 0x1381001a }, + { _MMIO(0x9888), 0x37906800 }, + { _MMIO(0x9888), 0x3f901000 }, + { _MMIO(0x9888), 0x03811300 }, + { _MMIO(0x9888), 0x05811b12 }, + { _MMIO(0x9888), 0x0781001a }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x17810000 }, + { _MMIO(0x9888), 0x19810000 }, + { _MMIO(0x9888), 0x1b810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930055 }, + { _MMIO(0x9888), 0x03e58000 }, + { _MMIO(0x9888), 0x05e5c000 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x13900160 }, + { _MMIO(0x9888), 0x21900161 }, + { _MMIO(0x9888), 0x23900162 }, + { _MMIO(0x9888), 0x25900163 }, + { _MMIO(0x9888), 0x27900164 }, + { _MMIO(0x9888), 0x29900165 }, + { _MMIO(0x9888), 0x2b900166 }, + { _MMIO(0x9888), 0x2d900167 }, + { _MMIO(0x9888), 0x2f900150 }, + { _MMIO(0x9888), 0x31900105 }, + { _MMIO(0x9888), 0x15900103 }, + { _MMIO(0x9888), 0x17900101 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1d908000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c60 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900c63 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c63 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900063 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_memory_writes_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_memory_writes; + lens[n] = ARRAY_SIZE(mux_config_memory_writes); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extended[] = { + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fc2a }, + { _MMIO(0x2774), 0x0000bf00 }, + { _MMIO(0x2778), 0x0007fc6a }, + { _MMIO(0x277c), 0x0000bf00 }, + { _MMIO(0x2780), 0x0007fc92 }, + { _MMIO(0x2784), 0x0000bf00 }, + { _MMIO(0x2788), 0x0007fca2 }, + { _MMIO(0x278c), 0x0000bf00 }, + { _MMIO(0x2790), 0x0007fc32 }, + { _MMIO(0x2794), 0x0000bf00 }, + { _MMIO(0x2798), 0x0007fc9a }, + { _MMIO(0x279c), 0x0000bf00 }, + { _MMIO(0x27a0), 0x0007fe6a }, + { _MMIO(0x27a4), 0x0000bf00 }, + { _MMIO(0x27a8), 0x0007fe7a }, + { _MMIO(0x27ac), 0x0000bf00 }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_extended[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00778008 }, + { _MMIO(0xe45c), 0x00088078 }, + { _MMIO(0xe55c), 0x00808708 }, + { _MMIO(0xe65c), 0x00a08908 }, +}; + +static const struct i915_oa_reg mux_config_compute_extended[] = { + { _MMIO(0x9888), 0x106c00e0 }, + { _MMIO(0x9888), 0x141c8160 }, + { _MMIO(0x9888), 0x161c8015 }, + { _MMIO(0x9888), 0x181c0120 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4eaaa0 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0e6c0b01 }, + { _MMIO(0x9888), 0x006c0200 }, + { _MMIO(0x9888), 0x026c000c }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x001c0041 }, + { _MMIO(0x9888), 0x061c4200 }, + { _MMIO(0x9888), 0x081c4443 }, + { _MMIO(0x9888), 0x0a1c4645 }, + { _MMIO(0x9888), 0x0c1c7647 }, + { _MMIO(0x9888), 0x041c7357 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x101c0000 }, + { _MMIO(0x9888), 0x1a1c0000 }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4caa2a }, + { _MMIO(0x9888), 0x0c4c02aa }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x000da000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x0c0f5400 }, + { _MMIO(0x9888), 0x0e0f5515 }, + { _MMIO(0x9888), 0x100f0155 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x11907fff }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900040 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900802 }, + { _MMIO(0x9888), 0x47900842 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900842 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x43900800 }, + { _MMIO(0x9888), 0x53900000 }, +}; + +static int +get_compute_extended_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extended; + lens[n] = ARRAY_SIZE(mux_config_compute_extended); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = { + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2770), 0x0007fffa }, + { _MMIO(0x2774), 0x0000fefe }, + { _MMIO(0x2778), 0x0007fffa }, + { _MMIO(0x277c), 0x0000fefd }, + { _MMIO(0x2790), 0x0007fffa }, + { _MMIO(0x2794), 0x0000fbef }, + { _MMIO(0x2798), 0x0007fffa }, + { _MMIO(0x279c), 0x0000fbdf }, +}; + +static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00000003 }, + { _MMIO(0xe658), 0x00002001 }, + { _MMIO(0xe758), 0x00101100 }, + { _MMIO(0xe45c), 0x00201200 }, + { _MMIO(0xe55c), 0x00301300 }, + { _MMIO(0xe65c), 0x00401400 }, +}; + +static const struct i915_oa_reg mux_config_compute_l3_cache[] = { + { _MMIO(0x9888), 0x166c0760 }, + { _MMIO(0x9888), 0x1593001e }, + { _MMIO(0x9888), 0x3f900003 }, + { _MMIO(0x9888), 0x004e8000 }, + { _MMIO(0x9888), 0x0e4e8000 }, + { _MMIO(0x9888), 0x184e8000 }, + { _MMIO(0x9888), 0x1a4e8020 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x006c0051 }, + { _MMIO(0x9888), 0x066c5000 }, + { _MMIO(0x9888), 0x086c5c5d }, + { _MMIO(0x9888), 0x0e6c5e5f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x186c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x001b4000 }, + { _MMIO(0x9888), 0x061b8000 }, + { _MMIO(0x9888), 0x081bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x101c8000 }, + { _MMIO(0x9888), 0x1a1ce000 }, + { _MMIO(0x9888), 0x1c1c0030 }, + { _MMIO(0x9888), 0x004c8000 }, + { _MMIO(0x9888), 0x0a4c2a00 }, + { _MMIO(0x9888), 0x0c4c0280 }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f1500 }, + { _MMIO(0x9888), 0x100f0140 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162c0a00 }, + { _MMIO(0x9888), 0x182c00a0 }, + { _MMIO(0x9888), 0x03933300 }, + { _MMIO(0x9888), 0x05930032 }, + { _MMIO(0x9888), 0x11930000 }, + { _MMIO(0x9888), 0x1b930000 }, + { _MMIO(0x9888), 0x1d900157 }, + { _MMIO(0x9888), 0x1f900158 }, + { _MMIO(0x9888), 0x35900000 }, + { _MMIO(0x9888), 0x19908000 }, + { _MMIO(0x9888), 0x1b908000 }, + { _MMIO(0x9888), 0x1190030f }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900000 }, + { _MMIO(0x9888), 0x55900000 }, + { _MMIO(0x9888), 0x45900021 }, + { _MMIO(0x9888), 0x47900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x4b900000 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x53905555 }, + { _MMIO(0x9888), 0x43900000 }, +}; + +static int +get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_l3_cache; + lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x10800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000fdff }, +}; + +static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_hdc_and_sf[] = { + { _MMIO(0x9888), 0x104f0232 }, + { _MMIO(0x9888), 0x124f4640 }, + { _MMIO(0x9888), 0x106c0232 }, + { _MMIO(0x9888), 0x11834400 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x004f1880 }, + { _MMIO(0x9888), 0x024f08bb }, + { _MMIO(0x9888), 0x044f001b }, + { _MMIO(0x9888), 0x046c0100 }, + { _MMIO(0x9888), 0x066c000b }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x041b8000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x005b8000 }, + { _MMIO(0x9888), 0x025bc000 }, + { _MMIO(0x9888), 0x045b4000 }, + { _MMIO(0x9888), 0x125c8000 }, + { _MMIO(0x9888), 0x145c8000 }, + { _MMIO(0x9888), 0x165c8000 }, + { _MMIO(0x9888), 0x185c8000 }, + { _MMIO(0x9888), 0x0a4c00a0 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x022cc000 }, + { _MMIO(0x9888), 0x042cc000 }, + { _MMIO(0x9888), 0x062cc000 }, + { _MMIO(0x9888), 0x082cc000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x0f828000 }, + { _MMIO(0x9888), 0x0f8305c0 }, + { _MMIO(0x9888), 0x09830000 }, + { _MMIO(0x9888), 0x07830000 }, + { _MMIO(0x9888), 0x1d950080 }, + { _MMIO(0x9888), 0x13928000 }, + { _MMIO(0x9888), 0x0f988000 }, + { _MMIO(0x9888), 0x31904000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x59900001 }, + { _MMIO(0x9888), 0x4b900040 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_hdc_and_sf; + lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00014002 }, + { _MMIO(0x277c), 0x0000c3ff }, + { _MMIO(0x2780), 0x00010002 }, + { _MMIO(0x2784), 0x0000c7ff }, + { _MMIO(0x2788), 0x00004002 }, + { _MMIO(0x278c), 0x0000d3ff }, + { _MMIO(0x2790), 0x00100700 }, + { _MMIO(0x2794), 0x0000ff1f }, + { _MMIO(0x2798), 0x00001402 }, + { _MMIO(0x279c), 0x0000fc3f }, + { _MMIO(0x27a0), 0x00001002 }, + { _MMIO(0x27a4), 0x0000fc7f }, + { _MMIO(0x27a8), 0x00000402 }, + { _MMIO(0x27ac), 0x0000fd3f }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_1[] = { + { _MMIO(0x9888), 0x126c7b40 }, + { _MMIO(0x9888), 0x166c0020 }, + { _MMIO(0x9888), 0x0a603444 }, + { _MMIO(0x9888), 0x0a613400 }, + { _MMIO(0x9888), 0x1a4ea800 }, + { _MMIO(0x9888), 0x1c4e0002 }, + { _MMIO(0x9888), 0x024e8000 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x0c6c5327 }, + { _MMIO(0x9888), 0x0e6c5425 }, + { _MMIO(0x9888), 0x006c2a00 }, + { _MMIO(0x9888), 0x026c285b }, + { _MMIO(0x9888), 0x046c005c }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1c6c0000 }, + { _MMIO(0x9888), 0x1e6c0000 }, + { _MMIO(0x9888), 0x1a6c0800 }, + { _MMIO(0x9888), 0x0c1bc000 }, + { _MMIO(0x9888), 0x0e1bc000 }, + { _MMIO(0x9888), 0x001b8000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x1c1c003c }, + { _MMIO(0x9888), 0x121c8000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x10600000 }, + { _MMIO(0x9888), 0x04600000 }, + { _MMIO(0x9888), 0x0c610044 }, + { _MMIO(0x9888), 0x10610000 }, + { _MMIO(0x9888), 0x06610000 }, + { _MMIO(0x9888), 0x0c4c02a8 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0154 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x182c00aa }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190ffc0 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900420 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900021 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900400 }, + { _MMIO(0x9888), 0x43900421 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_l3_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_1; + lens[n] = ARRAY_SIZE(mux_config_l3_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_2[] = { + { _MMIO(0x9888), 0x126c02e0 }, + { _MMIO(0x9888), 0x146c0001 }, + { _MMIO(0x9888), 0x0a623400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x064f4000 }, + { _MMIO(0x9888), 0x026c3324 }, + { _MMIO(0x9888), 0x046c3422 }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c0000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c0800 }, + { _MMIO(0x9888), 0x065b4000 }, + { _MMIO(0x9888), 0x1a5c1000 }, + { _MMIO(0x9888), 0x06614000 }, + { _MMIO(0x9888), 0x0c620044 }, + { _MMIO(0x9888), 0x10620000 }, + { _MMIO(0x9888), 0x06620000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c002a }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2cc000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_2; + lens[n] = ARRAY_SIZE(mux_config_l3_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_l3_3[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00100070 }, + { _MMIO(0x2774), 0x0000fff1 }, + { _MMIO(0x2778), 0x00028002 }, + { _MMIO(0x277c), 0x000087ff }, + { _MMIO(0x2780), 0x00020002 }, + { _MMIO(0x2784), 0x00008fff }, + { _MMIO(0x2788), 0x00008002 }, + { _MMIO(0x278c), 0x0000a7ff }, +}; + +static const struct i915_oa_reg flex_eu_config_l3_3[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_l3_3[] = { + { _MMIO(0x9888), 0x126c4e80 }, + { _MMIO(0x9888), 0x146c0000 }, + { _MMIO(0x9888), 0x0a633400 }, + { _MMIO(0x9888), 0x044e8000 }, + { _MMIO(0x9888), 0x064e8000 }, + { _MMIO(0x9888), 0x084e8000 }, + { _MMIO(0x9888), 0x0a4e8000 }, + { _MMIO(0x9888), 0x0c4e8000 }, + { _MMIO(0x9888), 0x026c3321 }, + { _MMIO(0x9888), 0x046c342f }, + { _MMIO(0x9888), 0x106c0000 }, + { _MMIO(0x9888), 0x1a6c2000 }, + { _MMIO(0x9888), 0x021bc000 }, + { _MMIO(0x9888), 0x041bc000 }, + { _MMIO(0x9888), 0x061b4000 }, + { _MMIO(0x9888), 0x141c8000 }, + { _MMIO(0x9888), 0x161c8000 }, + { _MMIO(0x9888), 0x181c8000 }, + { _MMIO(0x9888), 0x1a1c1800 }, + { _MMIO(0x9888), 0x06604000 }, + { _MMIO(0x9888), 0x0c630044 }, + { _MMIO(0x9888), 0x10630000 }, + { _MMIO(0x9888), 0x06630000 }, + { _MMIO(0x9888), 0x084c8000 }, + { _MMIO(0x9888), 0x0a4c00aa }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0f4000 }, + { _MMIO(0x9888), 0x0e0f0055 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190f800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900002 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_l3_3_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_l3_3; + lens[n] = ARRAY_SIZE(mux_config_l3_3); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x30800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x0000efff }, + { _MMIO(0x2778), 0x00006000 }, + { _MMIO(0x277c), 0x0000f3ff }, +}; + +static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = { + { _MMIO(0x9888), 0x102f3800 }, + { _MMIO(0x9888), 0x144d0500 }, + { _MMIO(0x9888), 0x120d03c0 }, + { _MMIO(0x9888), 0x140d03cf }, + { _MMIO(0x9888), 0x0c0f0004 }, + { _MMIO(0x9888), 0x0c4e4000 }, + { _MMIO(0x9888), 0x042f0480 }, + { _MMIO(0x9888), 0x082f0000 }, + { _MMIO(0x9888), 0x022f0000 }, + { _MMIO(0x9888), 0x0a4c0090 }, + { _MMIO(0x9888), 0x064d0027 }, + { _MMIO(0x9888), 0x004d0000 }, + { _MMIO(0x9888), 0x000d0d40 }, + { _MMIO(0x9888), 0x020d803f }, + { _MMIO(0x9888), 0x040d8023 }, + { _MMIO(0x9888), 0x100d0000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x020f0010 }, + { _MMIO(0x9888), 0x000f0000 }, + { _MMIO(0x9888), 0x0e0f0050 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41901400 }, + { _MMIO(0x9888), 0x43901485 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900001 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_rasterizer_and_pixel_backend; + lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_sampler[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x70800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, + { _MMIO(0x2770), 0x0000c000 }, + { _MMIO(0x2774), 0x0000e7ff }, + { _MMIO(0x2778), 0x00003000 }, + { _MMIO(0x277c), 0x0000f9ff }, + { _MMIO(0x2780), 0x00000c00 }, + { _MMIO(0x2784), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_sampler[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_sampler[] = { + { _MMIO(0x9888), 0x14152c00 }, + { _MMIO(0x9888), 0x16150005 }, + { _MMIO(0x9888), 0x121600a0 }, + { _MMIO(0x9888), 0x14352c00 }, + { _MMIO(0x9888), 0x16350005 }, + { _MMIO(0x9888), 0x123600a0 }, + { _MMIO(0x9888), 0x14552c00 }, + { _MMIO(0x9888), 0x16550005 }, + { _MMIO(0x9888), 0x125600a0 }, + { _MMIO(0x9888), 0x062f6000 }, + { _MMIO(0x9888), 0x022f2000 }, + { _MMIO(0x9888), 0x0c4c0050 }, + { _MMIO(0x9888), 0x0a4c0010 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0350 }, + { _MMIO(0x9888), 0x0c0fb000 }, + { _MMIO(0x9888), 0x0e0f00da }, + { _MMIO(0x9888), 0x182c0028 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x022dc000 }, + { _MMIO(0x9888), 0x042d4000 }, + { _MMIO(0x9888), 0x0c138000 }, + { _MMIO(0x9888), 0x0e132000 }, + { _MMIO(0x9888), 0x0413c000 }, + { _MMIO(0x9888), 0x1c140018 }, + { _MMIO(0x9888), 0x0c157000 }, + { _MMIO(0x9888), 0x0e150078 }, + { _MMIO(0x9888), 0x10150000 }, + { _MMIO(0x9888), 0x04162180 }, + { _MMIO(0x9888), 0x02160000 }, + { _MMIO(0x9888), 0x04174000 }, + { _MMIO(0x9888), 0x0233a000 }, + { _MMIO(0x9888), 0x04333000 }, + { _MMIO(0x9888), 0x14348000 }, + { _MMIO(0x9888), 0x16348000 }, + { _MMIO(0x9888), 0x02357870 }, + { _MMIO(0x9888), 0x10350000 }, + { _MMIO(0x9888), 0x04360043 }, + { _MMIO(0x9888), 0x02360000 }, + { _MMIO(0x9888), 0x04371000 }, + { _MMIO(0x9888), 0x0e538000 }, + { _MMIO(0x9888), 0x00538000 }, + { _MMIO(0x9888), 0x06533000 }, + { _MMIO(0x9888), 0x1c540020 }, + { _MMIO(0x9888), 0x12548000 }, + { _MMIO(0x9888), 0x0e557000 }, + { _MMIO(0x9888), 0x00557800 }, + { _MMIO(0x9888), 0x10550000 }, + { _MMIO(0x9888), 0x06560043 }, + { _MMIO(0x9888), 0x02560000 }, + { _MMIO(0x9888), 0x06571000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900060 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900842 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900060 }, +}; + +static int +get_sampler_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_sampler; + lens[n] = ARRAY_SIZE(mux_config_sampler); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_1[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00000002 }, + { _MMIO(0x2774), 0x00007fff }, + { _MMIO(0x2778), 0x00000000 }, + { _MMIO(0x277c), 0x00009fff }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000efff }, + { _MMIO(0x2788), 0x00000000 }, + { _MMIO(0x278c), 0x0000f3ff }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000fdff }, + { _MMIO(0x2798), 0x00000000 }, + { _MMIO(0x279c), 0x0000fe7f }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_1[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_1[] = { + { _MMIO(0x9888), 0x12120000 }, + { _MMIO(0x9888), 0x12320000 }, + { _MMIO(0x9888), 0x12520000 }, + { _MMIO(0x9888), 0x002f8000 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0015 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f03a0 }, + { _MMIO(0x9888), 0x0c0ff000 }, + { _MMIO(0x9888), 0x0e0f0095 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x0c2d8000 }, + { _MMIO(0x9888), 0x0e2d4000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x02108000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x02118000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x02121880 }, + { _MMIO(0x9888), 0x041219b5 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x02134000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x0c308000 }, + { _MMIO(0x9888), 0x0e304000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x0c318000 }, + { _MMIO(0x9888), 0x0e314000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x0c321a80 }, + { _MMIO(0x9888), 0x0e320033 }, + { _MMIO(0x9888), 0x06320031 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x0c334000 }, + { _MMIO(0x9888), 0x0e331000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0e508000 }, + { _MMIO(0x9888), 0x00508000 }, + { _MMIO(0x9888), 0x02504000 }, + { _MMIO(0x9888), 0x0e518000 }, + { _MMIO(0x9888), 0x00518000 }, + { _MMIO(0x9888), 0x02514000 }, + { _MMIO(0x9888), 0x0e521880 }, + { _MMIO(0x9888), 0x00521a80 }, + { _MMIO(0x9888), 0x02520033 }, + { _MMIO(0x9888), 0x0e534000 }, + { _MMIO(0x9888), 0x00534000 }, + { _MMIO(0x9888), 0x02531000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900800 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900062 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900c00 }, + { _MMIO(0x9888), 0x43900003 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, +}; + +static int +get_tdl_1_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_1; + lens[n] = ARRAY_SIZE(mux_config_tdl_1); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_tdl_2[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0x00800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x00800000 }, +}; + +static const struct i915_oa_reg flex_eu_config_tdl_2[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00010003 }, + { _MMIO(0xe658), 0x00012011 }, + { _MMIO(0xe758), 0x00015014 }, + { _MMIO(0xe45c), 0x00051050 }, + { _MMIO(0xe55c), 0x00053052 }, + { _MMIO(0xe65c), 0x00055054 }, +}; + +static const struct i915_oa_reg mux_config_tdl_2[] = { + { _MMIO(0x9888), 0x12124d60 }, + { _MMIO(0x9888), 0x12322e60 }, + { _MMIO(0x9888), 0x12524d60 }, + { _MMIO(0x9888), 0x022f3000 }, + { _MMIO(0x9888), 0x0a4c0014 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x0c0fe000 }, + { _MMIO(0x9888), 0x0e0f0097 }, + { _MMIO(0x9888), 0x082c8000 }, + { _MMIO(0x9888), 0x0a2c8000 }, + { _MMIO(0x9888), 0x002d8000 }, + { _MMIO(0x9888), 0x062d4000 }, + { _MMIO(0x9888), 0x0410c000 }, + { _MMIO(0x9888), 0x0411c000 }, + { _MMIO(0x9888), 0x04121fb7 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x04135000 }, + { _MMIO(0x9888), 0x00308000 }, + { _MMIO(0x9888), 0x06304000 }, + { _MMIO(0x9888), 0x00318000 }, + { _MMIO(0x9888), 0x06314000 }, + { _MMIO(0x9888), 0x00321b80 }, + { _MMIO(0x9888), 0x0632003f }, + { _MMIO(0x9888), 0x00334000 }, + { _MMIO(0x9888), 0x06331000 }, + { _MMIO(0x9888), 0x0250c000 }, + { _MMIO(0x9888), 0x0251c000 }, + { _MMIO(0x9888), 0x02521fb7 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x02535000 }, + { _MMIO(0x9888), 0x1190fc00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x51900000 }, + { _MMIO(0x9888), 0x41900800 }, + { _MMIO(0x9888), 0x43900063 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900040 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_tdl_2_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_tdl_2; + lens[n] = ARRAY_SIZE(mux_config_tdl_2); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_compute_extra[] = { +}; + +static const struct i915_oa_reg flex_eu_config_compute_extra[] = { +}; + +static const struct i915_oa_reg mux_config_compute_extra[] = { + { _MMIO(0x9888), 0x121203e0 }, + { _MMIO(0x9888), 0x123203e0 }, + { _MMIO(0x9888), 0x125203e0 }, + { _MMIO(0x9888), 0x129203e0 }, + { _MMIO(0x9888), 0x12b203e0 }, + { _MMIO(0x9888), 0x12d203e0 }, + { _MMIO(0x9888), 0x131203e0 }, + { _MMIO(0x9888), 0x133203e0 }, + { _MMIO(0x9888), 0x135203e0 }, + { _MMIO(0x9888), 0x1a4ef000 }, + { _MMIO(0x9888), 0x1c4e0003 }, + { _MMIO(0x9888), 0x024ec000 }, + { _MMIO(0x9888), 0x044ec000 }, + { _MMIO(0x9888), 0x064ec000 }, + { _MMIO(0x9888), 0x022f4000 }, + { _MMIO(0x9888), 0x0c4c02a0 }, + { _MMIO(0x9888), 0x084ca000 }, + { _MMIO(0x9888), 0x0a4c0042 }, + { _MMIO(0x9888), 0x0c0d8000 }, + { _MMIO(0x9888), 0x0e0da000 }, + { _MMIO(0x9888), 0x000d8000 }, + { _MMIO(0x9888), 0x020da000 }, + { _MMIO(0x9888), 0x040da000 }, + { _MMIO(0x9888), 0x060d2000 }, + { _MMIO(0x9888), 0x100f0150 }, + { _MMIO(0x9888), 0x0c0f5000 }, + { _MMIO(0x9888), 0x0e0f006d }, + { _MMIO(0x9888), 0x182c00a8 }, + { _MMIO(0x9888), 0x022c8000 }, + { _MMIO(0x9888), 0x042c8000 }, + { _MMIO(0x9888), 0x062c8000 }, + { _MMIO(0x9888), 0x0c2c8000 }, + { _MMIO(0x9888), 0x042d8000 }, + { _MMIO(0x9888), 0x06104000 }, + { _MMIO(0x9888), 0x06114000 }, + { _MMIO(0x9888), 0x06120033 }, + { _MMIO(0x9888), 0x00120000 }, + { _MMIO(0x9888), 0x06131000 }, + { _MMIO(0x9888), 0x04308000 }, + { _MMIO(0x9888), 0x04318000 }, + { _MMIO(0x9888), 0x04321980 }, + { _MMIO(0x9888), 0x00320000 }, + { _MMIO(0x9888), 0x04334000 }, + { _MMIO(0x9888), 0x04504000 }, + { _MMIO(0x9888), 0x04514000 }, + { _MMIO(0x9888), 0x04520033 }, + { _MMIO(0x9888), 0x00520000 }, + { _MMIO(0x9888), 0x04531000 }, + { _MMIO(0x9888), 0x1acef000 }, + { _MMIO(0x9888), 0x1cce0003 }, + { _MMIO(0x9888), 0x00af8000 }, + { _MMIO(0x9888), 0x0ccc02a0 }, + { _MMIO(0x9888), 0x0acc0001 }, + { _MMIO(0x9888), 0x0c8d8000 }, + { _MMIO(0x9888), 0x0e8da000 }, + { _MMIO(0x9888), 0x008d8000 }, + { _MMIO(0x9888), 0x028da000 }, + { _MMIO(0x9888), 0x108f0150 }, + { _MMIO(0x9888), 0x0c8fb000 }, + { _MMIO(0x9888), 0x0e8f0001 }, + { _MMIO(0x9888), 0x18ac00a8 }, + { _MMIO(0x9888), 0x06ac8000 }, + { _MMIO(0x9888), 0x02ad4000 }, + { _MMIO(0x9888), 0x02908000 }, + { _MMIO(0x9888), 0x02918000 }, + { _MMIO(0x9888), 0x02921980 }, + { _MMIO(0x9888), 0x00920000 }, + { _MMIO(0x9888), 0x02934000 }, + { _MMIO(0x9888), 0x02b04000 }, + { _MMIO(0x9888), 0x02b14000 }, + { _MMIO(0x9888), 0x02b20033 }, + { _MMIO(0x9888), 0x00b20000 }, + { _MMIO(0x9888), 0x02b31000 }, + { _MMIO(0x9888), 0x00d08000 }, + { _MMIO(0x9888), 0x00d18000 }, + { _MMIO(0x9888), 0x00d21980 }, + { _MMIO(0x9888), 0x00d34000 }, + { _MMIO(0x9888), 0x072f8000 }, + { _MMIO(0x9888), 0x0d4c0100 }, + { _MMIO(0x9888), 0x0d0d8000 }, + { _MMIO(0x9888), 0x0f0da000 }, + { _MMIO(0x9888), 0x110f01b0 }, + { _MMIO(0x9888), 0x192c0080 }, + { _MMIO(0x9888), 0x0f2d4000 }, + { _MMIO(0x9888), 0x0f108000 }, + { _MMIO(0x9888), 0x0f118000 }, + { _MMIO(0x9888), 0x0f121980 }, + { _MMIO(0x9888), 0x01120000 }, + { _MMIO(0x9888), 0x0f134000 }, + { _MMIO(0x9888), 0x0f304000 }, + { _MMIO(0x9888), 0x0f314000 }, + { _MMIO(0x9888), 0x0f320033 }, + { _MMIO(0x9888), 0x01320000 }, + { _MMIO(0x9888), 0x0f331000 }, + { _MMIO(0x9888), 0x0d508000 }, + { _MMIO(0x9888), 0x0d518000 }, + { _MMIO(0x9888), 0x0d521980 }, + { _MMIO(0x9888), 0x01520000 }, + { _MMIO(0x9888), 0x0d534000 }, + { _MMIO(0x9888), 0x1190ff80 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900c00 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, + { _MMIO(0x9888), 0x4b900002 }, + { _MMIO(0x9888), 0x59900000 }, + { _MMIO(0x9888), 0x51901100 }, + { _MMIO(0x9888), 0x41901000 }, + { _MMIO(0x9888), 0x43901423 }, + { _MMIO(0x9888), 0x53903331 }, + { _MMIO(0x9888), 0x45900044 }, +}; + +static int +get_compute_extra_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_compute_extra; + lens[n] = ARRAY_SIZE(mux_config_compute_extra); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_vme_pipe[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2724), 0x30800000 }, + { _MMIO(0x2770), 0x00100030 }, + { _MMIO(0x2774), 0x0000fff9 }, + { _MMIO(0x2778), 0x00000002 }, + { _MMIO(0x277c), 0x0000fffc }, + { _MMIO(0x2780), 0x00000002 }, + { _MMIO(0x2784), 0x0000fff3 }, + { _MMIO(0x2788), 0x00100180 }, + { _MMIO(0x278c), 0x0000ffcf }, + { _MMIO(0x2790), 0x00000002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00000002 }, + { _MMIO(0x279c), 0x0000ff3f }, +}; + +static const struct i915_oa_reg flex_eu_config_vme_pipe[] = { + { _MMIO(0xe458), 0x00005004 }, + { _MMIO(0xe558), 0x00008003 }, +}; + +static const struct i915_oa_reg mux_config_vme_pipe[] = { + { _MMIO(0x9888), 0x141a5800 }, + { _MMIO(0x9888), 0x161a00c0 }, + { _MMIO(0x9888), 0x12180240 }, + { _MMIO(0x9888), 0x14180002 }, + { _MMIO(0x9888), 0x149a5800 }, + { _MMIO(0x9888), 0x169a00c0 }, + { _MMIO(0x9888), 0x12980240 }, + { _MMIO(0x9888), 0x14980002 }, + { _MMIO(0x9888), 0x1a4e3fc0 }, + { _MMIO(0x9888), 0x002f1000 }, + { _MMIO(0x9888), 0x022f8000 }, + { _MMIO(0x9888), 0x042f3000 }, + { _MMIO(0x9888), 0x004c4000 }, + { _MMIO(0x9888), 0x0a4c9500 }, + { _MMIO(0x9888), 0x0c4c002a }, + { _MMIO(0x9888), 0x000d2000 }, + { _MMIO(0x9888), 0x060d8000 }, + { _MMIO(0x9888), 0x080da000 }, + { _MMIO(0x9888), 0x0a0da000 }, + { _MMIO(0x9888), 0x0c0da000 }, + { _MMIO(0x9888), 0x0c0f0400 }, + { _MMIO(0x9888), 0x0e0f5500 }, + { _MMIO(0x9888), 0x100f0015 }, + { _MMIO(0x9888), 0x002c8000 }, + { _MMIO(0x9888), 0x0e2c8000 }, + { _MMIO(0x9888), 0x162caa00 }, + { _MMIO(0x9888), 0x182c000a }, + { _MMIO(0x9888), 0x04193000 }, + { _MMIO(0x9888), 0x081a28c1 }, + { _MMIO(0x9888), 0x001a0000 }, + { _MMIO(0x9888), 0x00133000 }, + { _MMIO(0x9888), 0x0613c000 }, + { _MMIO(0x9888), 0x0813f000 }, + { _MMIO(0x9888), 0x00172000 }, + { _MMIO(0x9888), 0x06178000 }, + { _MMIO(0x9888), 0x0817a000 }, + { _MMIO(0x9888), 0x00180037 }, + { _MMIO(0x9888), 0x06180940 }, + { _MMIO(0x9888), 0x08180000 }, + { _MMIO(0x9888), 0x02180000 }, + { _MMIO(0x9888), 0x04183000 }, + { _MMIO(0x9888), 0x04afc000 }, + { _MMIO(0x9888), 0x06af3000 }, + { _MMIO(0x9888), 0x0acc4000 }, + { _MMIO(0x9888), 0x0ccc0015 }, + { _MMIO(0x9888), 0x0a8da000 }, + { _MMIO(0x9888), 0x0c8da000 }, + { _MMIO(0x9888), 0x0e8f4000 }, + { _MMIO(0x9888), 0x108f0015 }, + { _MMIO(0x9888), 0x16aca000 }, + { _MMIO(0x9888), 0x18ac000a }, + { _MMIO(0x9888), 0x06993000 }, + { _MMIO(0x9888), 0x0c9a28c1 }, + { _MMIO(0x9888), 0x009a0000 }, + { _MMIO(0x9888), 0x0a93f000 }, + { _MMIO(0x9888), 0x0c93f000 }, + { _MMIO(0x9888), 0x0a97a000 }, + { _MMIO(0x9888), 0x0c97a000 }, + { _MMIO(0x9888), 0x0a980977 }, + { _MMIO(0x9888), 0x08980000 }, + { _MMIO(0x9888), 0x04980000 }, + { _MMIO(0x9888), 0x06983000 }, + { _MMIO(0x9888), 0x119000ff }, + { _MMIO(0x9888), 0x51900010 }, + { _MMIO(0x9888), 0x41900060 }, + { _MMIO(0x9888), 0x55900111 }, + { _MMIO(0x9888), 0x45900c00 }, + { _MMIO(0x9888), 0x47900821 }, + { _MMIO(0x9888), 0x57900000 }, + { _MMIO(0x9888), 0x49900002 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_vme_pipe_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_vme_pipe; + lens[n] = ARRAY_SIZE(mux_config_vme_pipe); + n++; + + return n; +} + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9888), 0x11810000 }, + { _MMIO(0x9888), 0x07810013 }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930040 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static int +get_test_oa_mux_config(struct drm_i915_private *dev_priv, + const struct i915_oa_reg **regs, + int *lens) +{ + int n = 0; + + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1); + BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1); + + regs[n] = mux_config_test_oa; + lens[n] = ARRAY_SIZE(mux_config_test_oa); + n++; + + return n; +} + +int i915_oa_select_metric_set_sklgt4(struct drm_i915_private *dev_priv) +{ + dev_priv->perf.oa.n_mux_configs = 0; + dev_priv->perf.oa.b_counter_regs = NULL; + dev_priv->perf.oa.b_counter_regs_len = 0; + dev_priv->perf.oa.flex_regs = NULL; + dev_priv->perf.oa.flex_regs_len = 0; + + switch (dev_priv->perf.oa.metrics_set) { + case METRIC_SET_ID_RENDER_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_render_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_basic); + + return 0; + case METRIC_SET_ID_COMPUTE_BASIC: + dev_priv->perf.oa.n_mux_configs = + get_compute_basic_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_basic; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_basic); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_basic; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_basic); + + return 0; + case METRIC_SET_ID_RENDER_PIPE_PROFILE: + dev_priv->perf.oa.n_mux_configs = + get_render_pipe_profile_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_render_pipe_profile; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_render_pipe_profile); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_render_pipe_profile; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_render_pipe_profile); + + return 0; + case METRIC_SET_ID_MEMORY_READS: + dev_priv->perf.oa.n_mux_configs = + get_memory_reads_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_reads; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_reads); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_reads; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_reads); + + return 0; + case METRIC_SET_ID_MEMORY_WRITES: + dev_priv->perf.oa.n_mux_configs = + get_memory_writes_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_memory_writes; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_memory_writes); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_memory_writes; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_memory_writes); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTENDED: + dev_priv->perf.oa.n_mux_configs = + get_compute_extended_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extended; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extended); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extended; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extended); + + return 0; + case METRIC_SET_ID_COMPUTE_L3_CACHE: + dev_priv->perf.oa.n_mux_configs = + get_compute_l3_cache_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_l3_cache; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_l3_cache); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_l3_cache; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_l3_cache); + + return 0; + case METRIC_SET_ID_HDC_AND_SF: + dev_priv->perf.oa.n_mux_configs = + get_hdc_and_sf_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_hdc_and_sf; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_hdc_and_sf); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_hdc_and_sf; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_hdc_and_sf); + + return 0; + case METRIC_SET_ID_L3_1: + dev_priv->perf.oa.n_mux_configs = + get_l3_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_1); + + return 0; + case METRIC_SET_ID_L3_2: + dev_priv->perf.oa.n_mux_configs = + get_l3_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_2); + + return 0; + case METRIC_SET_ID_L3_3: + dev_priv->perf.oa.n_mux_configs = + get_l3_3_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_l3_3; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_l3_3); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_l3_3; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_l3_3); + + return 0; + case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND: + dev_priv->perf.oa.n_mux_configs = + get_rasterizer_and_pixel_backend_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_rasterizer_and_pixel_backend; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend); + + return 0; + case METRIC_SET_ID_SAMPLER: + dev_priv->perf.oa.n_mux_configs = + get_sampler_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_sampler; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_sampler); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_sampler; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_sampler); + + return 0; + case METRIC_SET_ID_TDL_1: + dev_priv->perf.oa.n_mux_configs = + get_tdl_1_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_1; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_1); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_1; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_1); + + return 0; + case METRIC_SET_ID_TDL_2: + dev_priv->perf.oa.n_mux_configs = + get_tdl_2_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_tdl_2; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_tdl_2); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_tdl_2; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_tdl_2); + + return 0; + case METRIC_SET_ID_COMPUTE_EXTRA: + dev_priv->perf.oa.n_mux_configs = + get_compute_extra_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_compute_extra; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_compute_extra); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_compute_extra; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_compute_extra); + + return 0; + case METRIC_SET_ID_VME_PIPE: + dev_priv->perf.oa.n_mux_configs = + get_vme_pipe_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_vme_pipe; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_vme_pipe); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_vme_pipe; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_vme_pipe); + + return 0; + case METRIC_SET_ID_TEST_OA: + dev_priv->perf.oa.n_mux_configs = + get_test_oa_mux_config(dev_priv, + dev_priv->perf.oa.mux_regs, + dev_priv->perf.oa.mux_regs_lens); + if (dev_priv->perf.oa.n_mux_configs == 0) { + DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n"); + + /* EINVAL because *_register_sysfs already checked this + * and so it wouldn't have been advertised to userspace and + * so shouldn't have been requested + */ + return -EINVAL; + } + + dev_priv->perf.oa.b_counter_regs = + b_counter_config_test_oa; + dev_priv->perf.oa.b_counter_regs_len = + ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.flex_regs = + flex_eu_config_test_oa; + dev_priv->perf.oa.flex_regs_len = + ARRAY_SIZE(flex_eu_config_test_oa); + + return 0; + default: + return -ENODEV; + } +} + +static ssize_t +show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC); +} + +static struct device_attribute dev_attr_render_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_render_basic[] = { + &dev_attr_render_basic_id.attr, + NULL, +}; + +static struct attribute_group group_render_basic = { + .name = "bad77c24-cc64-480d-99bf-e7b740713800", + .attrs = attrs_render_basic, +}; + +static ssize_t +show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC); +} + +static struct device_attribute dev_attr_compute_basic_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_basic_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_basic[] = { + &dev_attr_compute_basic_id.attr, + NULL, +}; + +static struct attribute_group group_compute_basic = { + .name = "7277228f-e7f3-4743-945a-6a2049d11377", + .attrs = attrs_compute_basic, +}; + +static ssize_t +show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE); +} + +static struct device_attribute dev_attr_render_pipe_profile_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_render_pipe_profile_id, + .store = NULL, +}; + +static struct attribute *attrs_render_pipe_profile[] = { + &dev_attr_render_pipe_profile_id.attr, + NULL, +}; + +static struct attribute_group group_render_pipe_profile = { + .name = "463c668c-3f60-49b6-8f85-d995b635b3b2", + .attrs = attrs_render_pipe_profile, +}; + +static ssize_t +show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS); +} + +static struct device_attribute dev_attr_memory_reads_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_reads_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_reads[] = { + &dev_attr_memory_reads_id.attr, + NULL, +}; + +static struct attribute_group group_memory_reads = { + .name = "3ae6e74c-72c3-4040-9bd0-7961430b8cc8", + .attrs = attrs_memory_reads, +}; + +static ssize_t +show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES); +} + +static struct device_attribute dev_attr_memory_writes_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_memory_writes_id, + .store = NULL, +}; + +static struct attribute *attrs_memory_writes[] = { + &dev_attr_memory_writes_id.attr, + NULL, +}; + +static struct attribute_group group_memory_writes = { + .name = "055f256d-4052-467c-8dec-6064a4806433", + .attrs = attrs_memory_writes, +}; + +static ssize_t +show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED); +} + +static struct device_attribute dev_attr_compute_extended_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extended_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extended[] = { + &dev_attr_compute_extended_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extended = { + .name = "753972d4-87cd-4460-824d-754463ac5054", + .attrs = attrs_compute_extended, +}; + +static ssize_t +show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE); +} + +static struct device_attribute dev_attr_compute_l3_cache_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_l3_cache_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_l3_cache[] = { + &dev_attr_compute_l3_cache_id.attr, + NULL, +}; + +static struct attribute_group group_compute_l3_cache = { + .name = "4e4392e9-8f73-457b-ab44-b49f7a0c733b", + .attrs = attrs_compute_l3_cache, +}; + +static ssize_t +show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF); +} + +static struct device_attribute dev_attr_hdc_and_sf_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_hdc_and_sf_id, + .store = NULL, +}; + +static struct attribute *attrs_hdc_and_sf[] = { + &dev_attr_hdc_and_sf_id.attr, + NULL, +}; + +static struct attribute_group group_hdc_and_sf = { + .name = "730d95dd-7da8-4e1c-ab8d-c0eb1e4c1805", + .attrs = attrs_hdc_and_sf, +}; + +static ssize_t +show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1); +} + +static struct device_attribute dev_attr_l3_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_1_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_1[] = { + &dev_attr_l3_1_id.attr, + NULL, +}; + +static struct attribute_group group_l3_1 = { + .name = "d9e86d70-462b-462a-851e-fd63e8c13d63", + .attrs = attrs_l3_1, +}; + +static ssize_t +show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2); +} + +static struct device_attribute dev_attr_l3_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_2_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_2[] = { + &dev_attr_l3_2_id.attr, + NULL, +}; + +static struct attribute_group group_l3_2 = { + .name = "52200424-6ee9-48b3-b7fa-0afcf1975e4d", + .attrs = attrs_l3_2, +}; + +static ssize_t +show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3); +} + +static struct device_attribute dev_attr_l3_3_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_l3_3_id, + .store = NULL, +}; + +static struct attribute *attrs_l3_3[] = { + &dev_attr_l3_3_id.attr, + NULL, +}; + +static struct attribute_group group_l3_3 = { + .name = "1988315f-0a26-44df-acb0-df7ec86b1456", + .attrs = attrs_l3_3, +}; + +static ssize_t +show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND); +} + +static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_rasterizer_and_pixel_backend_id, + .store = NULL, +}; + +static struct attribute *attrs_rasterizer_and_pixel_backend[] = { + &dev_attr_rasterizer_and_pixel_backend_id.attr, + NULL, +}; + +static struct attribute_group group_rasterizer_and_pixel_backend = { + .name = "f1f17ca7-286e-4ae5-9d15-9fccad6c665d", + .attrs = attrs_rasterizer_and_pixel_backend, +}; + +static ssize_t +show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER); +} + +static struct device_attribute dev_attr_sampler_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_sampler_id, + .store = NULL, +}; + +static struct attribute *attrs_sampler[] = { + &dev_attr_sampler_id.attr, + NULL, +}; + +static struct attribute_group group_sampler = { + .name = "00a9e0fb-3d2e-4405-852c-dce6334ffb3b", + .attrs = attrs_sampler, +}; + +static ssize_t +show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1); +} + +static struct device_attribute dev_attr_tdl_1_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_1_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_1[] = { + &dev_attr_tdl_1_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_1 = { + .name = "13dcc50a-7ec0-409b-99d6-a3f932cedcb3", + .attrs = attrs_tdl_1, +}; + +static ssize_t +show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2); +} + +static struct device_attribute dev_attr_tdl_2_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_tdl_2_id, + .store = NULL, +}; + +static struct attribute *attrs_tdl_2[] = { + &dev_attr_tdl_2_id.attr, + NULL, +}; + +static struct attribute_group group_tdl_2 = { + .name = "97875e21-6624-4aee-9191-682feb3eae21", + .attrs = attrs_tdl_2, +}; + +static ssize_t +show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA); +} + +static struct device_attribute dev_attr_compute_extra_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_compute_extra_id, + .store = NULL, +}; + +static struct attribute *attrs_compute_extra[] = { + &dev_attr_compute_extra_id.attr, + NULL, +}; + +static struct attribute_group group_compute_extra = { + .name = "a5aa857d-e8f0-4dfa-8981-ce340fa748fd", + .attrs = attrs_compute_extra, +}; + +static ssize_t +show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE); +} + +static struct device_attribute dev_attr_vme_pipe_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_vme_pipe_id, + .store = NULL, +}; + +static struct attribute *attrs_vme_pipe[] = { + &dev_attr_vme_pipe_id.attr, + NULL, +}; + +static struct attribute_group group_vme_pipe = { + .name = "0e8d8b86-4ee7-4cdd-aaaa-58adc92cb29e", + .attrs = attrs_vme_pipe, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA); +} + +static struct device_attribute dev_attr_test_oa_id = { + .attr = { .name = "id", .mode = 0444 }, + .show = show_test_oa_id, + .store = NULL, +}; + +static struct attribute *attrs_test_oa[] = { + &dev_attr_test_oa_id.attr, + NULL, +}; + +static struct attribute_group group_test_oa = { + .name = "882fa433-1f4a-4a67-a962-c741888fe5f5", + .attrs = attrs_test_oa, +}; + +int +i915_perf_register_sysfs_sklgt4(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + int ret = 0; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (ret) + goto error_render_basic; + } + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (ret) + goto error_compute_basic; + } + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (ret) + goto error_render_pipe_profile; + } + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (ret) + goto error_memory_reads; + } + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (ret) + goto error_memory_writes; + } + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (ret) + goto error_compute_extended; + } + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (ret) + goto error_compute_l3_cache; + } + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (ret) + goto error_hdc_and_sf; + } + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (ret) + goto error_l3_1; + } + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (ret) + goto error_l3_2; + } + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (ret) + goto error_l3_3; + } + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (ret) + goto error_rasterizer_and_pixel_backend; + } + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (ret) + goto error_sampler; + } + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (ret) + goto error_tdl_1; + } + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (ret) + goto error_tdl_2; + } + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (ret) + goto error_compute_extra; + } + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (ret) + goto error_vme_pipe; + } + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) { + ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa); + if (ret) + goto error_test_oa; + } + + return 0; + +error_test_oa: + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); +error_vme_pipe: + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); +error_compute_extra: + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); +error_tdl_2: + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); +error_tdl_1: + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); +error_sampler: + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); +error_rasterizer_and_pixel_backend: + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); +error_l3_3: + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); +error_l3_2: + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); +error_l3_1: + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); +error_hdc_and_sf: + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); +error_compute_l3_cache: + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); +error_compute_extended: + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); +error_memory_writes: + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); +error_memory_reads: + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); +error_render_pipe_profile: + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); +error_compute_basic: + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); +error_render_basic: + return ret; +} + +void +i915_perf_unregister_sysfs_sklgt4(struct drm_i915_private *dev_priv) +{ + const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)]; + int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)]; + + if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic); + if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic); + if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile); + if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads); + if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes); + if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended); + if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache); + if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf); + if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1); + if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2); + if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3); + if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend); + if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler); + if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1); + if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2); + if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra); + if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe); + if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) + sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa); +} diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.h b/drivers/gpu/drm/i915/i915_oa_sklgt4.h new file mode 100644 index 0000000..1b718f1 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.h @@ -0,0 +1,40 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 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 __I915_OA_SKLGT4_H__ +#define __I915_OA_SKLGT4_H__ + +extern int i915_oa_n_builtin_metric_sets_sklgt4; + +extern int i915_oa_select_metric_set_sklgt4(struct drm_i915_private *dev_priv); + +extern int i915_perf_register_sysfs_sklgt4(struct drm_i915_private *dev_priv); + +extern void i915_perf_unregister_sysfs_sklgt4(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index f940e48..506ec32 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -312,16 +312,17 @@ static const struct intel_device_info intel_haswell_info = { .has_full_48bit_ppgtt = 1, \ .has_64bit_reloc = 1 +#define BDW_PLATFORM \ + BDW_FEATURES, \ + .gen = 8, \ + .platform = INTEL_BROADWELL + static const struct intel_device_info intel_broadwell_info = { - BDW_FEATURES, - .gen = 8, - .platform = INTEL_BROADWELL, + BDW_PLATFORM, }; static const struct intel_device_info intel_broadwell_gt3_info = { - BDW_FEATURES, - .gen = 8, - .platform = INTEL_BROADWELL, + BDW_PLATFORM, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; @@ -347,22 +348,20 @@ static const struct intel_device_info intel_cherryview_info = { CHV_COLORS, }; +#define SKL_PLATFORM \ + BDW_FEATURES, \ + .gen = 9, \ + .platform = INTEL_SKYLAKE, \ + .has_csr = 1, \ + .has_guc = 1, \ + .ddb_size = 896 + static const struct intel_device_info intel_skylake_info = { - BDW_FEATURES, - .platform = INTEL_SKYLAKE, - .gen = 9, - .has_csr = 1, - .has_guc = 1, - .ddb_size = 896, + SKL_PLATFORM, }; static const struct intel_device_info intel_skylake_gt3_info = { - BDW_FEATURES, - .platform = INTEL_SKYLAKE, - .gen = 9, - .has_csr = 1, - .has_guc = 1, - .ddb_size = 896, + SKL_PLATFORM, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; @@ -401,28 +400,52 @@ static const struct intel_device_info intel_broxton_info = { static const struct intel_device_info intel_geminilake_info = { GEN9_LP_FEATURES, .platform = INTEL_GEMINILAKE, - .is_alpha_support = 1, .ddb_size = 1024, .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } }; +#define KBL_PLATFORM \ + BDW_FEATURES, \ + .gen = 9, \ + .platform = INTEL_KABYLAKE, \ + .has_csr = 1, \ + .has_guc = 1, \ + .ddb_size = 896 + static const struct intel_device_info intel_kabylake_info = { - BDW_FEATURES, - .platform = INTEL_KABYLAKE, - .gen = 9, - .has_csr = 1, - .has_guc = 1, - .ddb_size = 896, + KBL_PLATFORM, }; static const struct intel_device_info intel_kabylake_gt3_info = { + KBL_PLATFORM, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +#define CFL_PLATFORM \ + .is_alpha_support = 1, \ + BDW_FEATURES, \ + .gen = 9, \ + .platform = INTEL_COFFEELAKE, \ + .has_csr = 1, \ + .has_guc = 1, \ + .ddb_size = 896 + +static const struct intel_device_info intel_coffeelake_info = { + CFL_PLATFORM, +}; + +static const struct intel_device_info intel_coffeelake_gt3_info = { + CFL_PLATFORM, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +static const struct intel_device_info intel_cannonlake_info = { BDW_FEATURES, - .platform = INTEL_KABYLAKE, - .gen = 9, + .is_alpha_support = 1, + .platform = INTEL_CANNONLAKE, + .gen = 10, + .ddb_size = 1024, .has_csr = 1, - .has_guc = 1, - .ddb_size = 896, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; /* @@ -469,6 +492,10 @@ static const struct pci_device_id pciidlist[] = { INTEL_KBL_GT2_IDS(&intel_kabylake_info), INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info), INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info), + INTEL_CFL_S_IDS(&intel_coffeelake_info), + INTEL_CFL_H_IDS(&intel_coffeelake_info), + INTEL_CFL_U_IDS(&intel_coffeelake_gt3_info), + INTEL_CNL_IDS(&intel_cannonlake_info), {0, 0, 0} }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 85269bc..38c4440 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -196,6 +196,15 @@ #include "i915_drv.h" #include "i915_oa_hsw.h" +#include "i915_oa_bdw.h" +#include "i915_oa_chv.h" +#include "i915_oa_sklgt2.h" +#include "i915_oa_sklgt3.h" +#include "i915_oa_sklgt4.h" +#include "i915_oa_bxt.h" +#include "i915_oa_kblgt2.h" +#include "i915_oa_kblgt3.h" +#include "i915_oa_glk.h" /* HW requires this to be a power of two, between 128k and 16M, though driver * is currently generally designed assuming the largest 16M size is used such @@ -215,7 +224,7 @@ * * Although this can be observed explicitly while copying reports to userspace * by checking for a zeroed report-id field in tail reports, we want to account - * for this earlier, as part of the _oa_buffer_check to avoid lots of redundant + * for this earlier, as part of the oa_buffer_check to avoid lots of redundant * read() attempts. * * In effect we define a tail pointer for reading that lags the real tail @@ -237,7 +246,7 @@ * indicates that an updated tail pointer is needed. * * Most of the implementation details for this workaround are in - * gen7_oa_buffer_check_unlocked() and gen7_appand_oa_reports() + * oa_buffer_check_unlocked() and _append_oa_reports() * * Note for posterity: previously the driver used to define an effective tail * pointer that lagged the real pointer by a 'tail margin' measured in bytes @@ -272,13 +281,22 @@ static u32 i915_perf_stream_paranoid = true; #define INVALID_CTX_ID 0xffffffff +/* On Gen8+ automatically triggered OA reports include a 'reason' field... */ +#define OAREPORT_REASON_MASK 0x3f +#define OAREPORT_REASON_SHIFT 19 +#define OAREPORT_REASON_TIMER (1<<0) +#define OAREPORT_REASON_CTX_SWITCH (1<<3) +#define OAREPORT_REASON_CLK_RATIO (1<<5) + /* For sysctl proc_dointvec_minmax of i915_oa_max_sample_rate * - * 160ns is the smallest sampling period we can theoretically program the OA - * unit with on Haswell, corresponding to 6.25MHz. + * The highest sampling frequency we can theoretically program the OA unit + * with is always half the timestamp frequency: E.g. 6.25Mhz for Haswell. + * + * Initialized just before we register the sysctl parameter. */ -static int oa_sample_rate_hard_limit = 6250000; +static int oa_sample_rate_hard_limit; /* Theoretically we can program the OA unit to sample every 160ns but don't * allow that by default unless root... @@ -303,6 +321,13 @@ static struct i915_oa_format hsw_oa_formats[I915_OA_FORMAT_MAX] = { [I915_OA_FORMAT_C4_B8] = { 7, 64 }, }; +static struct i915_oa_format gen8_plus_oa_formats[I915_OA_FORMAT_MAX] = { + [I915_OA_FORMAT_A12] = { 0, 64 }, + [I915_OA_FORMAT_A12_B8_C8] = { 2, 128 }, + [I915_OA_FORMAT_A32u40_A4u32_B8_C8] = { 5, 256 }, + [I915_OA_FORMAT_C4_B8] = { 7, 64 }, +}; + #define SAMPLE_OA_REPORT (1<<0) /** @@ -332,8 +357,20 @@ struct perf_open_properties { int oa_period_exponent; }; +static u32 gen8_oa_hw_tail_read(struct drm_i915_private *dev_priv) +{ + return I915_READ(GEN8_OATAILPTR) & GEN8_OATAILPTR_MASK; +} + +static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv) +{ + u32 oastatus1 = I915_READ(GEN7_OASTATUS1); + + return oastatus1 & GEN7_OASTATUS1_TAIL_MASK; +} + /** - * gen7_oa_buffer_check_unlocked - check for data and update tail ptr state + * oa_buffer_check_unlocked - check for data and update tail ptr state * @dev_priv: i915 device instance * * This is either called via fops (for blocking reads in user ctx) or the poll @@ -356,12 +393,11 @@ struct perf_open_properties { * * Returns: %true if the OA buffer contains data, else %false */ -static bool gen7_oa_buffer_check_unlocked(struct drm_i915_private *dev_priv) +static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv) { int report_size = dev_priv->perf.oa.oa_buffer.format_size; unsigned long flags; unsigned int aged_idx; - u32 oastatus1; u32 head, hw_tail, aged_tail, aging_tail; u64 now; @@ -381,8 +417,7 @@ static bool gen7_oa_buffer_check_unlocked(struct drm_i915_private *dev_priv) aged_tail = dev_priv->perf.oa.oa_buffer.tails[aged_idx].offset; aging_tail = dev_priv->perf.oa.oa_buffer.tails[!aged_idx].offset; - oastatus1 = I915_READ(GEN7_OASTATUS1); - hw_tail = oastatus1 & GEN7_OASTATUS1_TAIL_MASK; + hw_tail = dev_priv->perf.oa.ops.oa_hw_tail_read(dev_priv); /* The tail pointer increases in 64 byte increments, * not in report_size steps... @@ -404,6 +439,7 @@ static bool gen7_oa_buffer_check_unlocked(struct drm_i915_private *dev_priv) if (aging_tail != INVALID_TAIL_PTR && ((now - dev_priv->perf.oa.oa_buffer.aging_timestamp) > OA_TAIL_MARGIN_NSEC)) { + aged_idx ^= 1; dev_priv->perf.oa.oa_buffer.aged_tail_idx = aged_idx; @@ -553,6 +589,300 @@ static int append_oa_sample(struct i915_perf_stream *stream, * * Returns: 0 on success, negative error code on failure. */ +static int gen8_append_oa_reports(struct i915_perf_stream *stream, + char __user *buf, + size_t count, + size_t *offset) +{ + struct drm_i915_private *dev_priv = stream->dev_priv; + int report_size = dev_priv->perf.oa.oa_buffer.format_size; + u8 *oa_buf_base = dev_priv->perf.oa.oa_buffer.vaddr; + u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma); + u32 mask = (OA_BUFFER_SIZE - 1); + size_t start_offset = *offset; + unsigned long flags; + unsigned int aged_tail_idx; + u32 head, tail; + u32 taken; + int ret = 0; + + if (WARN_ON(!stream->enabled)) + return -EIO; + + spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags); + + head = dev_priv->perf.oa.oa_buffer.head; + aged_tail_idx = dev_priv->perf.oa.oa_buffer.aged_tail_idx; + tail = dev_priv->perf.oa.oa_buffer.tails[aged_tail_idx].offset; + + spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags); + + /* + * An invalid tail pointer here means we're still waiting for the poll + * hrtimer callback to give us a pointer + */ + if (tail == INVALID_TAIL_PTR) + return -EAGAIN; + + /* + * NB: oa_buffer.head/tail include the gtt_offset which we don't want + * while indexing relative to oa_buf_base. + */ + head -= gtt_offset; + tail -= gtt_offset; + + /* + * An out of bounds or misaligned head or tail pointer implies a driver + * bug since we validate + align the tail pointers we read from the + * hardware and we are in full control of the head pointer which should + * only be incremented by multiples of the report size (notably also + * all a power of two). + */ + if (WARN_ONCE(head > OA_BUFFER_SIZE || head % report_size || + tail > OA_BUFFER_SIZE || tail % report_size, + "Inconsistent OA buffer pointers: head = %u, tail = %u\n", + head, tail)) + return -EIO; + + + for (/* none */; + (taken = OA_TAKEN(tail, head)); + head = (head + report_size) & mask) { + u8 *report = oa_buf_base + head; + u32 *report32 = (void *)report; + u32 ctx_id; + u32 reason; + + /* + * All the report sizes factor neatly into the buffer + * size so we never expect to see a report split + * between the beginning and end of the buffer. + * + * Given the initial alignment check a misalignment + * here would imply a driver bug that would result + * in an overrun. + */ + if (WARN_ON((OA_BUFFER_SIZE - head) < report_size)) { + DRM_ERROR("Spurious OA head ptr: non-integral report offset\n"); + break; + } + + /* + * The reason field includes flags identifying what + * triggered this specific report (mostly timer + * triggered or e.g. due to a context switch). + * + * This field is never expected to be zero so we can + * check that the report isn't invalid before copying + * it to userspace... + */ + reason = ((report32[0] >> OAREPORT_REASON_SHIFT) & + OAREPORT_REASON_MASK); + if (reason == 0) { + if (__ratelimit(&dev_priv->perf.oa.spurious_report_rs)) + DRM_NOTE("Skipping spurious, invalid OA report\n"); + continue; + } + + /* + * XXX: Just keep the lower 21 bits for now since I'm not + * entirely sure if the HW touches any of the higher bits in + * this field + */ + ctx_id = report32[2] & 0x1fffff; + + /* + * Squash whatever is in the CTX_ID field if it's marked as + * invalid to be sure we avoid false-positive, single-context + * filtering below... + * + * Note: that we don't clear the valid_ctx_bit so userspace can + * understand that the ID has been squashed by the kernel. + */ + if (!(report32[0] & dev_priv->perf.oa.gen8_valid_ctx_bit)) + ctx_id = report32[2] = INVALID_CTX_ID; + + /* + * NB: For Gen 8 the OA unit no longer supports clock gating + * off for a specific context and the kernel can't securely + * stop the counters from updating as system-wide / global + * values. + * + * Automatic reports now include a context ID so reports can be + * filtered on the cpu but it's not worth trying to + * automatically subtract/hide counter progress for other + * contexts while filtering since we can't stop userspace + * issuing MI_REPORT_PERF_COUNT commands which would still + * provide a side-band view of the real values. + * + * To allow userspace (such as Mesa/GL_INTEL_performance_query) + * to normalize counters for a single filtered context then it + * needs be forwarded bookend context-switch reports so that it + * can track switches in between MI_REPORT_PERF_COUNT commands + * and can itself subtract/ignore the progress of counters + * associated with other contexts. Note that the hardware + * automatically triggers reports when switching to a new + * context which are tagged with the ID of the newly active + * context. To avoid the complexity (and likely fragility) of + * reading ahead while parsing reports to try and minimize + * forwarding redundant context switch reports (i.e. between + * other, unrelated contexts) we simply elect to forward them + * all. + * + * We don't rely solely on the reason field to identify context + * switches since it's not-uncommon for periodic samples to + * identify a switch before any 'context switch' report. + */ + if (!dev_priv->perf.oa.exclusive_stream->ctx || + dev_priv->perf.oa.specific_ctx_id == ctx_id || + (dev_priv->perf.oa.oa_buffer.last_ctx_id == + dev_priv->perf.oa.specific_ctx_id) || + reason & OAREPORT_REASON_CTX_SWITCH) { + + /* + * While filtering for a single context we avoid + * leaking the IDs of other contexts. + */ + if (dev_priv->perf.oa.exclusive_stream->ctx && + dev_priv->perf.oa.specific_ctx_id != ctx_id) { + report32[2] = INVALID_CTX_ID; + } + + ret = append_oa_sample(stream, buf, count, offset, + report); + if (ret) + break; + + dev_priv->perf.oa.oa_buffer.last_ctx_id = ctx_id; + } + + /* + * The above reason field sanity check is based on + * the assumption that the OA buffer is initially + * zeroed and we reset the field after copying so the + * check is still meaningful once old reports start + * being overwritten. + */ + report32[0] = 0; + } + + if (start_offset != *offset) { + spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags); + + /* + * We removed the gtt_offset for the copy loop above, indexing + * relative to oa_buf_base so put back here... + */ + head += gtt_offset; + + I915_WRITE(GEN8_OAHEADPTR, head & GEN8_OAHEADPTR_MASK); + dev_priv->perf.oa.oa_buffer.head = head; + + spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags); + } + + return ret; +} + +/** + * gen8_oa_read - copy status records then buffered OA reports + * @stream: An i915-perf stream opened for OA metrics + * @buf: destination buffer given by userspace + * @count: the number of bytes userspace wants to read + * @offset: (inout): the current position for writing into @buf + * + * Checks OA unit status registers and if necessary appends corresponding + * status records for userspace (such as for a buffer full condition) and then + * initiate appending any buffered OA reports. + * + * Updates @offset according to the number of bytes successfully copied into + * the userspace buffer. + * + * NB: some data may be successfully copied to the userspace buffer + * even if an error is returned, and this is reflected in the + * updated @offset. + * + * Returns: zero on success or a negative error code + */ +static int gen8_oa_read(struct i915_perf_stream *stream, + char __user *buf, + size_t count, + size_t *offset) +{ + struct drm_i915_private *dev_priv = stream->dev_priv; + u32 oastatus; + int ret; + + if (WARN_ON(!dev_priv->perf.oa.oa_buffer.vaddr)) + return -EIO; + + oastatus = I915_READ(GEN8_OASTATUS); + + /* + * We treat OABUFFER_OVERFLOW as a significant error: + * + * Although theoretically we could handle this more gracefully + * sometimes, some Gens don't correctly suppress certain + * automatically triggered reports in this condition and so we + * have to assume that old reports are now being trampled + * over. + * + * Considering how we don't currently give userspace control + * over the OA buffer size and always configure a large 16MB + * buffer, then a buffer overflow does anyway likely indicate + * that something has gone quite badly wrong. + */ + if (oastatus & GEN8_OASTATUS_OABUFFER_OVERFLOW) { + ret = append_oa_status(stream, buf, count, offset, + DRM_I915_PERF_RECORD_OA_BUFFER_LOST); + if (ret) + return ret; + + DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n", + dev_priv->perf.oa.period_exponent); + + dev_priv->perf.oa.ops.oa_disable(dev_priv); + dev_priv->perf.oa.ops.oa_enable(dev_priv); + + /* + * Note: .oa_enable() is expected to re-init the oabuffer and + * reset GEN8_OASTATUS for us + */ + oastatus = I915_READ(GEN8_OASTATUS); + } + + if (oastatus & GEN8_OASTATUS_REPORT_LOST) { + ret = append_oa_status(stream, buf, count, offset, + DRM_I915_PERF_RECORD_OA_REPORT_LOST); + if (ret) + return ret; + I915_WRITE(GEN8_OASTATUS, + oastatus & ~GEN8_OASTATUS_REPORT_LOST); + } + + return gen8_append_oa_reports(stream, buf, count, offset); +} + +/** + * Copies all buffered OA reports into userspace read() buffer. + * @stream: An i915-perf stream opened for OA metrics + * @buf: destination buffer given by userspace + * @count: the number of bytes userspace wants to read + * @offset: (inout): the current position for writing into @buf + * + * Notably any error condition resulting in a short read (-%ENOSPC or + * -%EFAULT) will be returned even though one or more records may + * have been successfully copied. In this case it's up to the caller + * to decide if the error should be squashed before returning to + * userspace. + * + * Note: reports are consumed from the head, and appended to the + * tail, so the tail chases the head?... If you think that's mad + * and back-to-front you're not alone, but this follows the + * Gen PRM naming convention. + * + * Returns: 0 on success, negative error code on failure. + */ static int gen7_append_oa_reports(struct i915_perf_stream *stream, char __user *buf, size_t count, @@ -732,7 +1062,8 @@ static int gen7_oa_read(struct i915_perf_stream *stream, if (ret) return ret; - DRM_DEBUG("OA buffer overflow: force restart\n"); + DRM_DEBUG("OA buffer overflow (exponent = %d): force restart\n", + dev_priv->perf.oa.period_exponent); dev_priv->perf.oa.ops.oa_disable(dev_priv); dev_priv->perf.oa.ops.oa_enable(dev_priv); @@ -775,7 +1106,7 @@ static int i915_oa_wait_unlocked(struct i915_perf_stream *stream) return -EIO; return wait_event_interruptible(dev_priv->perf.oa.poll_wq, - dev_priv->perf.oa.ops.oa_buffer_check(dev_priv)); + oa_buffer_check_unlocked(dev_priv)); } /** @@ -832,30 +1163,38 @@ static int i915_oa_read(struct i915_perf_stream *stream, static int oa_get_render_ctx_id(struct i915_perf_stream *stream) { struct drm_i915_private *dev_priv = stream->dev_priv; - struct intel_engine_cs *engine = dev_priv->engine[RCS]; - struct intel_ring *ring; - int ret; - ret = i915_mutex_lock_interruptible(&dev_priv->drm); - if (ret) - return ret; + if (i915.enable_execlists) + dev_priv->perf.oa.specific_ctx_id = stream->ctx->hw_id; + else { + struct intel_engine_cs *engine = dev_priv->engine[RCS]; + struct intel_ring *ring; + int ret; - /* As the ID is the gtt offset of the context's vma we pin - * the vma to ensure the ID remains fixed. - * - * NB: implied RCS engine... - */ - ring = engine->context_pin(engine, stream->ctx); - mutex_unlock(&dev_priv->drm.struct_mutex); - if (IS_ERR(ring)) - return PTR_ERR(ring); + ret = i915_mutex_lock_interruptible(&dev_priv->drm); + if (ret) + return ret; - /* Explicitly track the ID (instead of calling i915_ggtt_offset() - * on the fly) considering the difference with gen8+ and - * execlists - */ - dev_priv->perf.oa.specific_ctx_id = - i915_ggtt_offset(stream->ctx->engine[engine->id].state); + /* + * As the ID is the gtt offset of the context's vma we + * pin the vma to ensure the ID remains fixed. + * + * NB: implied RCS engine... + */ + ring = engine->context_pin(engine, stream->ctx); + mutex_unlock(&dev_priv->drm.struct_mutex); + if (IS_ERR(ring)) + return PTR_ERR(ring); + + + /* + * Explicitly track the ID (instead of calling + * i915_ggtt_offset() on the fly) considering the difference + * with gen8+ and execlists + */ + dev_priv->perf.oa.specific_ctx_id = + i915_ggtt_offset(stream->ctx->engine[engine->id].state); + } return 0; } @@ -870,14 +1209,19 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream) static void oa_put_render_ctx_id(struct i915_perf_stream *stream) { struct drm_i915_private *dev_priv = stream->dev_priv; - struct intel_engine_cs *engine = dev_priv->engine[RCS]; - mutex_lock(&dev_priv->drm.struct_mutex); + if (i915.enable_execlists) { + dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID; + } else { + struct intel_engine_cs *engine = dev_priv->engine[RCS]; + + mutex_lock(&dev_priv->drm.struct_mutex); - dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID; - engine->context_unpin(engine, stream->ctx); + dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID; + engine->context_unpin(engine, stream->ctx); - mutex_unlock(&dev_priv->drm.struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); + } } static void @@ -901,6 +1245,12 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream) BUG_ON(stream != dev_priv->perf.oa.exclusive_stream); + /* + * Unset exclusive_stream first, it might be checked while + * disabling the metric set on gen8+. + */ + dev_priv->perf.oa.exclusive_stream = NULL; + dev_priv->perf.oa.ops.disable_metric_set(dev_priv); free_oa_buffer(dev_priv); @@ -911,8 +1261,6 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream) if (stream->ctx) oa_put_render_ctx_id(stream); - dev_priv->perf.oa.exclusive_stream = NULL; - if (dev_priv->perf.oa.spurious_report_rs.missed) { DRM_NOTE("%d spurious OA report notices suppressed due to ratelimiting\n", dev_priv->perf.oa.spurious_report_rs.missed); @@ -967,6 +1315,65 @@ static void gen7_init_oa_buffer(struct drm_i915_private *dev_priv) dev_priv->perf.oa.pollin = false; } +static void gen8_init_oa_buffer(struct drm_i915_private *dev_priv) +{ + u32 gtt_offset = i915_ggtt_offset(dev_priv->perf.oa.oa_buffer.vma); + unsigned long flags; + + spin_lock_irqsave(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags); + + I915_WRITE(GEN8_OASTATUS, 0); + I915_WRITE(GEN8_OAHEADPTR, gtt_offset); + dev_priv->perf.oa.oa_buffer.head = gtt_offset; + + I915_WRITE(GEN8_OABUFFER_UDW, 0); + + /* + * PRM says: + * + * "This MMIO must be set before the OATAILPTR + * register and after the OAHEADPTR register. This is + * to enable proper functionality of the overflow + * bit." + */ + I915_WRITE(GEN8_OABUFFER, gtt_offset | + OABUFFER_SIZE_16M | OA_MEM_SELECT_GGTT); + I915_WRITE(GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK); + + /* Mark that we need updated tail pointers to read from... */ + dev_priv->perf.oa.oa_buffer.tails[0].offset = INVALID_TAIL_PTR; + dev_priv->perf.oa.oa_buffer.tails[1].offset = INVALID_TAIL_PTR; + + /* + * Reset state used to recognise context switches, affecting which + * reports we will forward to userspace while filtering for a single + * context. + */ + dev_priv->perf.oa.oa_buffer.last_ctx_id = INVALID_CTX_ID; + + spin_unlock_irqrestore(&dev_priv->perf.oa.oa_buffer.ptr_lock, flags); + + /* + * NB: although the OA buffer will initially be allocated + * zeroed via shmfs (and so this memset is redundant when + * first allocating), we may re-init the OA buffer, either + * when re-enabling a stream or in error/reset paths. + * + * The reason we clear the buffer for each re-init is for the + * sanity check in gen8_append_oa_reports() that looks at the + * reason field to make sure it's non-zero which relies on + * the assumption that new reports are being written to zeroed + * memory... + */ + memset(dev_priv->perf.oa.oa_buffer.vaddr, 0, OA_BUFFER_SIZE); + + /* + * Maybe make ->pollin per-stream state if we support multiple + * concurrent streams in the future. + */ + dev_priv->perf.oa.pollin = false; +} + static int alloc_oa_buffer(struct drm_i915_private *dev_priv) { struct drm_i915_gem_object *bo; @@ -1047,6 +1454,7 @@ static void config_oa_regs(struct drm_i915_private *dev_priv, static int hsw_enable_metric_set(struct drm_i915_private *dev_priv) { int ret = i915_oa_select_metric_set_hsw(dev_priv); + int i; if (ret) return ret; @@ -1068,8 +1476,10 @@ static int hsw_enable_metric_set(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) | GEN6_CSUNIT_CLOCK_GATE_DISABLE)); - config_oa_regs(dev_priv, dev_priv->perf.oa.mux_regs, - dev_priv->perf.oa.mux_regs_len); + for (i = 0; i < dev_priv->perf.oa.n_mux_configs; i++) { + config_oa_regs(dev_priv, dev_priv->perf.oa.mux_regs[i], + dev_priv->perf.oa.mux_regs_lens[i]); + } /* It apparently takes a fairly long time for a new MUX * configuration to be be applied after these register writes. @@ -1111,9 +1521,337 @@ static void hsw_disable_metric_set(struct drm_i915_private *dev_priv) ~GT_NOA_ENABLE)); } -static void gen7_update_oacontrol_locked(struct drm_i915_private *dev_priv) +/* + * NB: It must always remain pointer safe to run this even if the OA unit + * has been disabled. + * + * It's fine to put out-of-date values into these per-context registers + * in the case that the OA unit has been disabled. + */ +static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx, + u32 *reg_state) +{ + struct drm_i915_private *dev_priv = ctx->i915; + const struct i915_oa_reg *flex_regs = dev_priv->perf.oa.flex_regs; + int n_flex_regs = dev_priv->perf.oa.flex_regs_len; + u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset; + u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset; + /* The MMIO offsets for Flex EU registers aren't contiguous */ + u32 flex_mmio[] = { + i915_mmio_reg_offset(EU_PERF_CNTL0), + i915_mmio_reg_offset(EU_PERF_CNTL1), + i915_mmio_reg_offset(EU_PERF_CNTL2), + i915_mmio_reg_offset(EU_PERF_CNTL3), + i915_mmio_reg_offset(EU_PERF_CNTL4), + i915_mmio_reg_offset(EU_PERF_CNTL5), + i915_mmio_reg_offset(EU_PERF_CNTL6), + }; + int i; + + reg_state[ctx_oactxctrl] = i915_mmio_reg_offset(GEN8_OACTXCONTROL); + reg_state[ctx_oactxctrl+1] = (dev_priv->perf.oa.period_exponent << + GEN8_OA_TIMER_PERIOD_SHIFT) | + (dev_priv->perf.oa.periodic ? + GEN8_OA_TIMER_ENABLE : 0) | + GEN8_OA_COUNTER_RESUME; + + for (i = 0; i < ARRAY_SIZE(flex_mmio); i++) { + u32 state_offset = ctx_flexeu0 + i * 2; + u32 mmio = flex_mmio[i]; + + /* + * This arbitrary default will select the 'EU FPU0 Pipeline + * Active' event. In the future it's anticipated that there + * will be an explicit 'No Event' we can select, but not yet... + */ + u32 value = 0; + int j; + + for (j = 0; j < n_flex_regs; j++) { + if (i915_mmio_reg_offset(flex_regs[j].addr) == mmio) { + value = flex_regs[j].value; + break; + } + } + + reg_state[state_offset] = mmio; + reg_state[state_offset+1] = value; + } +} + +/* + * Same as gen8_update_reg_state_unlocked only through the batchbuffer. This + * is only used by the kernel context. + */ +static int gen8_emit_oa_config(struct drm_i915_gem_request *req) +{ + struct drm_i915_private *dev_priv = req->i915; + const struct i915_oa_reg *flex_regs = dev_priv->perf.oa.flex_regs; + int n_flex_regs = dev_priv->perf.oa.flex_regs_len; + /* The MMIO offsets for Flex EU registers aren't contiguous */ + u32 flex_mmio[] = { + i915_mmio_reg_offset(EU_PERF_CNTL0), + i915_mmio_reg_offset(EU_PERF_CNTL1), + i915_mmio_reg_offset(EU_PERF_CNTL2), + i915_mmio_reg_offset(EU_PERF_CNTL3), + i915_mmio_reg_offset(EU_PERF_CNTL4), + i915_mmio_reg_offset(EU_PERF_CNTL5), + i915_mmio_reg_offset(EU_PERF_CNTL6), + }; + u32 *cs; + int i; + + cs = intel_ring_begin(req, n_flex_regs * 2 + 4); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + *cs++ = MI_LOAD_REGISTER_IMM(n_flex_regs + 1); + + *cs++ = i915_mmio_reg_offset(GEN8_OACTXCONTROL); + *cs++ = (dev_priv->perf.oa.period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) | + (dev_priv->perf.oa.periodic ? GEN8_OA_TIMER_ENABLE : 0) | + GEN8_OA_COUNTER_RESUME; + + for (i = 0; i < ARRAY_SIZE(flex_mmio); i++) { + u32 mmio = flex_mmio[i]; + + /* + * This arbitrary default will select the 'EU FPU0 Pipeline + * Active' event. In the future it's anticipated that there + * will be an explicit 'No Event' we can select, but not + * yet... + */ + u32 value = 0; + int j; + + for (j = 0; j < n_flex_regs; j++) { + if (i915_mmio_reg_offset(flex_regs[j].addr) == mmio) { + value = flex_regs[j].value; + break; + } + } + + *cs++ = mmio; + *cs++ = value; + } + + *cs++ = MI_NOOP; + intel_ring_advance(req, cs); + + return 0; +} + +static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *engine = dev_priv->engine[RCS]; + struct i915_gem_timeline *timeline; + struct drm_i915_gem_request *req; + int ret; + + lockdep_assert_held(&dev_priv->drm.struct_mutex); + + i915_gem_retire_requests(dev_priv); + + req = i915_gem_request_alloc(engine, dev_priv->kernel_context); + if (IS_ERR(req)) + return PTR_ERR(req); + + ret = gen8_emit_oa_config(req); + if (ret) { + i915_add_request(req); + return ret; + } + + /* Queue this switch after all other activity */ + list_for_each_entry(timeline, &dev_priv->gt.timelines, link) { + struct drm_i915_gem_request *prev; + struct intel_timeline *tl; + + tl = &timeline->engine[engine->id]; + prev = i915_gem_active_raw(&tl->last_request, + &dev_priv->drm.struct_mutex); + if (prev) + i915_sw_fence_await_sw_fence_gfp(&req->submit, + &prev->submit, + GFP_KERNEL); + } + + ret = i915_switch_context(req); + i915_add_request(req); + + return ret; +} + +/* + * Manages updating the per-context aspects of the OA stream + * configuration across all contexts. + * + * The awkward consideration here is that OACTXCONTROL controls the + * exponent for periodic sampling which is primarily used for system + * wide profiling where we'd like a consistent sampling period even in + * the face of context switches. + * + * Our approach of updating the register state context (as opposed to + * say using a workaround batch buffer) ensures that the hardware + * won't automatically reload an out-of-date timer exponent even + * transiently before a WA BB could be parsed. + * + * This function needs to: + * - Ensure the currently running context's per-context OA state is + * updated + * - Ensure that all existing contexts will have the correct per-context + * OA state if they are scheduled for use. + * - Ensure any new contexts will be initialized with the correct + * per-context OA state. + * + * Note: it's only the RCS/Render context that has any OA state. + */ +static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, + bool interruptible) +{ + struct i915_gem_context *ctx; + int ret; + unsigned int wait_flags = I915_WAIT_LOCKED; + + if (interruptible) { + ret = i915_mutex_lock_interruptible(&dev_priv->drm); + if (ret) + return ret; + + wait_flags |= I915_WAIT_INTERRUPTIBLE; + } else { + mutex_lock(&dev_priv->drm.struct_mutex); + } + + /* Switch away from any user context. */ + ret = gen8_switch_to_updated_kernel_context(dev_priv); + if (ret) + goto out; + + /* + * The OA register config is setup through the context image. This image + * might be written to by the GPU on context switch (in particular on + * lite-restore). This means we can't safely update a context's image, + * if this context is scheduled/submitted to run on the GPU. + * + * We could emit the OA register config through the batch buffer but + * this might leave small interval of time where the OA unit is + * configured at an invalid sampling period. + * + * So far the best way to work around this issue seems to be draining + * the GPU from any submitted work. + */ + ret = i915_gem_wait_for_idle(dev_priv, wait_flags); + if (ret) + goto out; + + /* Update all contexts now that we've stalled the submission. */ + list_for_each_entry(ctx, &dev_priv->context_list, link) { + struct intel_context *ce = &ctx->engine[RCS]; + u32 *regs; + + /* OA settings will be set upon first use */ + if (!ce->state) + continue; + + regs = i915_gem_object_pin_map(ce->state->obj, I915_MAP_WB); + if (IS_ERR(regs)) { + ret = PTR_ERR(regs); + goto out; + } + + ce->state->obj->mm.dirty = true; + regs += LRC_STATE_PN * PAGE_SIZE / sizeof(*regs); + + gen8_update_reg_state_unlocked(ctx, regs); + + i915_gem_object_unpin_map(ce->state->obj); + } + + out: + mutex_unlock(&dev_priv->drm.struct_mutex); + + return ret; +} + +static int gen8_enable_metric_set(struct drm_i915_private *dev_priv) { - lockdep_assert_held(&dev_priv->perf.hook_lock); + int ret = dev_priv->perf.oa.ops.select_metric_set(dev_priv); + int i; + + if (ret) + return ret; + + /* + * We disable slice/unslice clock ratio change reports on SKL since + * they are too noisy. The HW generates a lot of redundant reports + * where the ratio hasn't really changed causing a lot of redundant + * work to processes and increasing the chances we'll hit buffer + * overruns. + * + * Although we don't currently use the 'disable overrun' OABUFFER + * feature it's worth noting that clock ratio reports have to be + * disabled before considering to use that feature since the HW doesn't + * correctly block these reports. + * + * Currently none of the high-level metrics we have depend on knowing + * this ratio to normalize. + * + * Note: This register is not power context saved and restored, but + * that's OK considering that we disable RC6 while the OA unit is + * enabled. + * + * The _INCLUDE_CLK_RATIO bit allows the slice/unslice frequency to + * be read back from automatically triggered reports, as part of the + * RPT_ID field. + */ + if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) || + IS_KABYLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) { + I915_WRITE(GEN8_OA_DEBUG, + _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS | + GEN9_OA_DEBUG_INCLUDE_CLK_RATIO)); + } + + /* + * Update all contexts prior writing the mux configurations as we need + * to make sure all slices/subslices are ON before writing to NOA + * registers. + */ + ret = gen8_configure_all_contexts(dev_priv, true); + if (ret) + return ret; + + I915_WRITE(GDT_CHICKEN_BITS, 0xA0); + for (i = 0; i < dev_priv->perf.oa.n_mux_configs; i++) { + config_oa_regs(dev_priv, dev_priv->perf.oa.mux_regs[i], + dev_priv->perf.oa.mux_regs_lens[i]); + } + I915_WRITE(GDT_CHICKEN_BITS, 0x80); + + config_oa_regs(dev_priv, dev_priv->perf.oa.b_counter_regs, + dev_priv->perf.oa.b_counter_regs_len); + + return 0; +} + +static void gen8_disable_metric_set(struct drm_i915_private *dev_priv) +{ + /* Reset all contexts' slices/subslices configurations. */ + gen8_configure_all_contexts(dev_priv, false); +} + +static void gen7_oa_enable(struct drm_i915_private *dev_priv) +{ + /* + * Reset buf pointers so we don't forward reports from before now. + * + * Think carefully if considering trying to avoid this, since it + * also ensures status flags and the buffer itself are cleared + * in error paths, and we have checks for invalid reports based + * on the assumption that certain fields are written to zeroed + * memory which this helps maintains. + */ + gen7_init_oa_buffer(dev_priv); if (dev_priv->perf.oa.exclusive_stream->enabled) { struct i915_gem_context *ctx = @@ -1136,11 +1874,12 @@ static void gen7_update_oacontrol_locked(struct drm_i915_private *dev_priv) I915_WRITE(GEN7_OACONTROL, 0); } -static void gen7_oa_enable(struct drm_i915_private *dev_priv) +static void gen8_oa_enable(struct drm_i915_private *dev_priv) { - unsigned long flags; + u32 report_format = dev_priv->perf.oa.oa_buffer.format; - /* Reset buf pointers so we don't forward reports from before now. + /* + * Reset buf pointers so we don't forward reports from before now. * * Think carefully if considering trying to avoid this, since it * also ensures status flags and the buffer itself are cleared @@ -1148,11 +1887,16 @@ static void gen7_oa_enable(struct drm_i915_private *dev_priv) * on the assumption that certain fields are written to zeroed * memory which this helps maintains. */ - gen7_init_oa_buffer(dev_priv); + gen8_init_oa_buffer(dev_priv); - spin_lock_irqsave(&dev_priv->perf.hook_lock, flags); - gen7_update_oacontrol_locked(dev_priv); - spin_unlock_irqrestore(&dev_priv->perf.hook_lock, flags); + /* + * Note: we don't rely on the hardware to perform single context + * filtering and instead filter on the cpu based on the context-id + * field of reports + */ + I915_WRITE(GEN8_OACONTROL, (report_format << + GEN8_OA_REPORT_FORMAT_SHIFT) | + GEN8_OA_COUNTER_ENABLE); } /** @@ -1181,6 +1925,11 @@ static void gen7_oa_disable(struct drm_i915_private *dev_priv) I915_WRITE(GEN7_OACONTROL, 0); } +static void gen8_oa_disable(struct drm_i915_private *dev_priv) +{ + I915_WRITE(GEN8_OACONTROL, 0); +} + /** * i915_oa_stream_disable - handle `I915_PERF_IOCTL_DISABLE` for OA stream * @stream: An i915 perf stream opened for OA metrics @@ -1359,6 +2108,21 @@ err_oa_buf_alloc: return ret; } +void i915_oa_init_reg_state(struct intel_engine_cs *engine, + struct i915_gem_context *ctx, + u32 *reg_state) +{ + struct drm_i915_private *dev_priv = engine->i915; + + if (engine->id != RCS) + return; + + if (!dev_priv->perf.initialized) + return; + + gen8_update_reg_state_unlocked(ctx, reg_state); +} + /** * i915_perf_read_locked - &i915_perf_stream_ops->read with error normalisation * @stream: An i915 perf stream @@ -1484,7 +2248,7 @@ static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer) container_of(hrtimer, typeof(*dev_priv), perf.oa.poll_check_timer); - if (dev_priv->perf.oa.ops.oa_buffer_check(dev_priv)) { + if (oa_buffer_check_unlocked(dev_priv)) { dev_priv->perf.oa.pollin = true; wake_up(&dev_priv->perf.oa.poll_wq); } @@ -1773,6 +2537,7 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv, struct i915_gem_context *specific_ctx = NULL; struct i915_perf_stream *stream = NULL; unsigned long f_flags = 0; + bool privileged_op = true; int stream_fd; int ret; @@ -1790,12 +2555,29 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv, } } + /* + * On Haswell the OA unit supports clock gating off for a specific + * context and in this mode there's no visibility of metrics for the + * rest of the system, which we consider acceptable for a + * non-privileged client. + * + * For Gen8+ the OA unit no longer supports clock gating off for a + * specific context and the kernel can't securely stop the counters + * from updating as system-wide / global values. Even though we can + * filter reports based on the included context ID we can't block + * clients from seeing the raw / global counter values via + * MI_REPORT_PERF_COUNT commands and so consider it a privileged op to + * enable the OA unit by default. + */ + if (IS_HASWELL(dev_priv) && specific_ctx) + privileged_op = false; + /* Similar to perf's kernel.perf_paranoid_cpu sysctl option * we check a dev.i915.perf_stream_paranoid sysctl option * to determine if it's ok to access system wide OA counters * without CAP_SYS_ADMIN privileges. */ - if (!specific_ctx && + if (privileged_op && i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) { DRM_DEBUG("Insufficient privileges to open system-wide i915 perf stream\n"); ret = -EACCES; @@ -1856,6 +2638,12 @@ err: return ret; } +static u64 oa_exponent_to_ns(struct drm_i915_private *dev_priv, int exponent) +{ + return div_u64(1000000000ULL * (2ULL << exponent), + dev_priv->perf.oa.timestamp_frequency); +} + /** * read_properties_unlocked - validate + copy userspace stream open properties * @dev_priv: i915 device instance @@ -1952,16 +2740,13 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv, } /* Theoretically we can program the OA unit to sample - * every 160ns but don't allow that by default unless - * root. - * - * On Haswell the period is derived from the exponent - * as: - * - * period = 80ns * 2^(exponent + 1) + * e.g. every 160ns for HSW, 167ns for BDW/SKL or 104ns + * for BXT. We don't allow such high sampling + * frequencies by default unless root. */ + BUILD_BUG_ON(sizeof(oa_period) != 8); - oa_period = 80ull * (2ull << value); + oa_period = oa_exponent_to_ns(dev_priv, value); /* This check is primarily to ensure that oa_period <= * UINT32_MAX (before passing to do_div which only @@ -2067,9 +2852,6 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data, */ void i915_perf_register(struct drm_i915_private *dev_priv) { - if (!IS_HASWELL(dev_priv)) - return; - if (!dev_priv->perf.initialized) return; @@ -2085,11 +2867,50 @@ void i915_perf_register(struct drm_i915_private *dev_priv) if (!dev_priv->perf.metrics_kobj) goto exit; - if (i915_perf_register_sysfs_hsw(dev_priv)) { - kobject_put(dev_priv->perf.metrics_kobj); - dev_priv->perf.metrics_kobj = NULL; + if (IS_HASWELL(dev_priv)) { + if (i915_perf_register_sysfs_hsw(dev_priv)) + goto sysfs_error; + } else if (IS_BROADWELL(dev_priv)) { + if (i915_perf_register_sysfs_bdw(dev_priv)) + goto sysfs_error; + } else if (IS_CHERRYVIEW(dev_priv)) { + if (i915_perf_register_sysfs_chv(dev_priv)) + goto sysfs_error; + } else if (IS_SKYLAKE(dev_priv)) { + if (IS_SKL_GT2(dev_priv)) { + if (i915_perf_register_sysfs_sklgt2(dev_priv)) + goto sysfs_error; + } else if (IS_SKL_GT3(dev_priv)) { + if (i915_perf_register_sysfs_sklgt3(dev_priv)) + goto sysfs_error; + } else if (IS_SKL_GT4(dev_priv)) { + if (i915_perf_register_sysfs_sklgt4(dev_priv)) + goto sysfs_error; + } else + goto sysfs_error; + } else if (IS_BROXTON(dev_priv)) { + if (i915_perf_register_sysfs_bxt(dev_priv)) + goto sysfs_error; + } else if (IS_KABYLAKE(dev_priv)) { + if (IS_KBL_GT2(dev_priv)) { + if (i915_perf_register_sysfs_kblgt2(dev_priv)) + goto sysfs_error; + } else if (IS_KBL_GT3(dev_priv)) { + if (i915_perf_register_sysfs_kblgt3(dev_priv)) + goto sysfs_error; + } else + goto sysfs_error; + } else if (IS_GEMINILAKE(dev_priv)) { + if (i915_perf_register_sysfs_glk(dev_priv)) + goto sysfs_error; } + goto exit; + +sysfs_error: + kobject_put(dev_priv->perf.metrics_kobj); + dev_priv->perf.metrics_kobj = NULL; + exit: mutex_unlock(&dev_priv->perf.lock); } @@ -2105,13 +2926,32 @@ exit: */ void i915_perf_unregister(struct drm_i915_private *dev_priv) { - if (!IS_HASWELL(dev_priv)) - return; - if (!dev_priv->perf.metrics_kobj) return; - i915_perf_unregister_sysfs_hsw(dev_priv); + if (IS_HASWELL(dev_priv)) + i915_perf_unregister_sysfs_hsw(dev_priv); + else if (IS_BROADWELL(dev_priv)) + i915_perf_unregister_sysfs_bdw(dev_priv); + else if (IS_CHERRYVIEW(dev_priv)) + i915_perf_unregister_sysfs_chv(dev_priv); + else if (IS_SKYLAKE(dev_priv)) { + if (IS_SKL_GT2(dev_priv)) + i915_perf_unregister_sysfs_sklgt2(dev_priv); + else if (IS_SKL_GT3(dev_priv)) + i915_perf_unregister_sysfs_sklgt3(dev_priv); + else if (IS_SKL_GT4(dev_priv)) + i915_perf_unregister_sysfs_sklgt4(dev_priv); + } else if (IS_BROXTON(dev_priv)) + i915_perf_unregister_sysfs_bxt(dev_priv); + else if (IS_KABYLAKE(dev_priv)) { + if (IS_KBL_GT2(dev_priv)) + i915_perf_unregister_sysfs_kblgt2(dev_priv); + else if (IS_KBL_GT3(dev_priv)) + i915_perf_unregister_sysfs_kblgt3(dev_priv); + } else if (IS_GEMINILAKE(dev_priv)) + i915_perf_unregister_sysfs_glk(dev_priv); + kobject_put(dev_priv->perf.metrics_kobj); dev_priv->perf.metrics_kobj = NULL; @@ -2170,36 +3010,133 @@ static struct ctl_table dev_root[] = { */ void i915_perf_init(struct drm_i915_private *dev_priv) { - if (!IS_HASWELL(dev_priv)) - return; + dev_priv->perf.oa.n_builtin_sets = 0; + + if (IS_HASWELL(dev_priv)) { + dev_priv->perf.oa.ops.init_oa_buffer = gen7_init_oa_buffer; + dev_priv->perf.oa.ops.enable_metric_set = hsw_enable_metric_set; + dev_priv->perf.oa.ops.disable_metric_set = hsw_disable_metric_set; + dev_priv->perf.oa.ops.oa_enable = gen7_oa_enable; + dev_priv->perf.oa.ops.oa_disable = gen7_oa_disable; + dev_priv->perf.oa.ops.read = gen7_oa_read; + dev_priv->perf.oa.ops.oa_hw_tail_read = + gen7_oa_hw_tail_read; + + dev_priv->perf.oa.timestamp_frequency = 12500000; + + dev_priv->perf.oa.oa_formats = hsw_oa_formats; + + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_hsw; + } else if (i915.enable_execlists) { + /* Note: that although we could theoretically also support the + * legacy ringbuffer mode on BDW (and earlier iterations of + * this driver, before upstreaming did this) it didn't seem + * worth the complexity to maintain now that BDW+ enable + * execlist mode by default. + */ - hrtimer_init(&dev_priv->perf.oa.poll_check_timer, - CLOCK_MONOTONIC, HRTIMER_MODE_REL); - dev_priv->perf.oa.poll_check_timer.function = oa_poll_check_timer_cb; - init_waitqueue_head(&dev_priv->perf.oa.poll_wq); + if (IS_GEN8(dev_priv)) { + dev_priv->perf.oa.ctx_oactxctrl_offset = 0x120; + dev_priv->perf.oa.ctx_flexeu0_offset = 0x2ce; - INIT_LIST_HEAD(&dev_priv->perf.streams); - mutex_init(&dev_priv->perf.lock); - spin_lock_init(&dev_priv->perf.hook_lock); - spin_lock_init(&dev_priv->perf.oa.oa_buffer.ptr_lock); + dev_priv->perf.oa.timestamp_frequency = 12500000; - dev_priv->perf.oa.ops.init_oa_buffer = gen7_init_oa_buffer; - dev_priv->perf.oa.ops.enable_metric_set = hsw_enable_metric_set; - dev_priv->perf.oa.ops.disable_metric_set = hsw_disable_metric_set; - dev_priv->perf.oa.ops.oa_enable = gen7_oa_enable; - dev_priv->perf.oa.ops.oa_disable = gen7_oa_disable; - dev_priv->perf.oa.ops.read = gen7_oa_read; - dev_priv->perf.oa.ops.oa_buffer_check = - gen7_oa_buffer_check_unlocked; + dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<25); - dev_priv->perf.oa.oa_formats = hsw_oa_formats; + if (IS_BROADWELL(dev_priv)) { + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_bdw; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_bdw; + } else if (IS_CHERRYVIEW(dev_priv)) { + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_chv; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_chv; + } + } else if (IS_GEN9(dev_priv)) { + dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128; + dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de; + + dev_priv->perf.oa.timestamp_frequency = 12000000; + + dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16); + + if (IS_SKL_GT2(dev_priv)) { + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_sklgt2; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_sklgt2; + } else if (IS_SKL_GT3(dev_priv)) { + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_sklgt3; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_sklgt3; + } else if (IS_SKL_GT4(dev_priv)) { + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_sklgt4; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_sklgt4; + } else if (IS_BROXTON(dev_priv)) { + dev_priv->perf.oa.timestamp_frequency = 19200000; + + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_bxt; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_bxt; + } else if (IS_KBL_GT2(dev_priv)) { + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_kblgt2; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_kblgt2; + } else if (IS_KBL_GT3(dev_priv)) { + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_kblgt3; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_kblgt3; + } else if (IS_GEMINILAKE(dev_priv)) { + dev_priv->perf.oa.timestamp_frequency = 19200000; + + dev_priv->perf.oa.n_builtin_sets = + i915_oa_n_builtin_metric_sets_glk; + dev_priv->perf.oa.ops.select_metric_set = + i915_oa_select_metric_set_glk; + } + } - dev_priv->perf.oa.n_builtin_sets = - i915_oa_n_builtin_metric_sets_hsw; + if (dev_priv->perf.oa.n_builtin_sets) { + dev_priv->perf.oa.ops.init_oa_buffer = gen8_init_oa_buffer; + dev_priv->perf.oa.ops.enable_metric_set = + gen8_enable_metric_set; + dev_priv->perf.oa.ops.disable_metric_set = + gen8_disable_metric_set; + dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable; + dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable; + dev_priv->perf.oa.ops.read = gen8_oa_read; + dev_priv->perf.oa.ops.oa_hw_tail_read = + gen8_oa_hw_tail_read; + + dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats; + } + } + + if (dev_priv->perf.oa.n_builtin_sets) { + hrtimer_init(&dev_priv->perf.oa.poll_check_timer, + CLOCK_MONOTONIC, HRTIMER_MODE_REL); + dev_priv->perf.oa.poll_check_timer.function = oa_poll_check_timer_cb; + init_waitqueue_head(&dev_priv->perf.oa.poll_wq); - dev_priv->perf.sysctl_header = register_sysctl_table(dev_root); + INIT_LIST_HEAD(&dev_priv->perf.streams); + mutex_init(&dev_priv->perf.lock); + spin_lock_init(&dev_priv->perf.oa.oa_buffer.ptr_lock); - dev_priv->perf.initialized = true; + oa_sample_rate_hard_limit = + dev_priv->perf.oa.timestamp_frequency / 2; + dev_priv->perf.sysctl_header = register_sysctl_table(dev_root); + + dev_priv->perf.initialized = true; + } } /** @@ -2214,5 +3151,6 @@ void i915_perf_fini(struct drm_i915_private *dev_priv) unregister_sysctl_table(dev_priv->perf.sysctl_header); memset(&dev_priv->perf.oa.ops, 0, sizeof(dev_priv->perf.oa.ops)); + dev_priv->perf.initialized = false; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 89888ad..bd535f1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -58,10 +58,13 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define _MMIO_TRANS(tran, a, b) _MMIO(_TRANS(tran, a, b)) #define _PORT(port, a, b) ((a) + (port)*((b)-(a))) #define _MMIO_PORT(port, a, b) _MMIO(_PORT(port, a, b)) -#define _PIPE3(pipe, ...) _PICK(pipe, __VA_ARGS__) -#define _MMIO_PIPE3(pipe, a, b, c) _MMIO(_PIPE3(pipe, a, b, c)) -#define _PORT3(port, ...) _PICK(port, __VA_ARGS__) -#define _MMIO_PORT3(pipe, a, b, c) _MMIO(_PORT3(pipe, a, b, c)) +#define _MMIO_PIPE3(pipe, a, b, c) _MMIO(_PICK(pipe, a, b, c)) +#define _MMIO_PORT3(pipe, a, b, c) _MMIO(_PICK(pipe, a, b, c)) +#define _PLL(pll, a, b) ((a) + (pll)*((b)-(a))) +#define _MMIO_PLL(pll, a, b) _MMIO(_PLL(pll, a, b)) +#define _MMIO_PORT6(port, a, b, c, d, e, f) _MMIO(_PICK(port, a, b, c, d, e, f)) +#define _MMIO_PORT6_LN(port, ln, a0, a1, b, c, d, e, f) \ + _MMIO(_PICK(port, a0, b, c, d, e, f) + (ln * (a1 - a0))) #define _PHY3(phy, ...) _PICK(phy, __VA_ARGS__) #define _MMIO_PHY3(phy, a, b, c) _MMIO(_PHY3(phy, a, b, c)) @@ -653,6 +656,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define GEN8_OACTXID _MMIO(0x2364) +#define GEN8_OA_DEBUG _MMIO(0x2B04) +#define GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS (1<<5) +#define GEN9_OA_DEBUG_INCLUDE_CLK_RATIO (1<<6) +#define GEN9_OA_DEBUG_DISABLE_GO_1_0_REPORTS (1<<2) +#define GEN9_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS (1<<1) + #define GEN8_OACONTROL _MMIO(0x2B00) #define GEN8_OA_REPORT_FORMAT_A12 (0<<2) #define GEN8_OA_REPORT_FORMAT_A12_B8_C8 (2<<2) @@ -674,6 +683,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define GEN7_OABUFFER_STOP_RESUME_ENABLE (1<<1) #define GEN7_OABUFFER_RESUME (1<<0) +#define GEN8_OABUFFER_UDW _MMIO(0x23b4) #define GEN8_OABUFFER _MMIO(0x2b14) #define GEN7_OASTATUS1 _MMIO(0x2364) @@ -692,7 +702,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define GEN8_OASTATUS_REPORT_LOST (1<<0) #define GEN8_OAHEADPTR _MMIO(0x2B0C) +#define GEN8_OAHEADPTR_MASK 0xffffffc0 #define GEN8_OATAILPTR _MMIO(0x2B10) +#define GEN8_OATAILPTR_MASK 0xffffffc0 #define OABUFFER_SIZE_128K (0<<3) #define OABUFFER_SIZE_256K (1<<3) @@ -705,7 +717,17 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define OA_MEM_SELECT_GGTT (1<<0) +/* + * Flexible, Aggregate EU Counter Registers. + * Note: these aren't contiguous + */ #define EU_PERF_CNTL0 _MMIO(0xe458) +#define EU_PERF_CNTL1 _MMIO(0xe558) +#define EU_PERF_CNTL2 _MMIO(0xe658) +#define EU_PERF_CNTL3 _MMIO(0xe758) +#define EU_PERF_CNTL4 _MMIO(0xe45c) +#define EU_PERF_CNTL5 _MMIO(0xe55c) +#define EU_PERF_CNTL6 _MMIO(0xe65c) #define GDT_CHICKEN_BITS _MMIO(0x9840) #define GT_NOA_ENABLE 0x00000080 @@ -1065,6 +1087,7 @@ enum skl_disp_power_wells { SKL_DISP_PW_MISC_IO, SKL_DISP_PW_DDI_A_E, GLK_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E, + CNL_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E, SKL_DISP_PW_DDI_B, SKL_DISP_PW_DDI_C, SKL_DISP_PW_DDI_D, @@ -1072,6 +1095,10 @@ enum skl_disp_power_wells { GLK_DISP_PW_AUX_A = 8, GLK_DISP_PW_AUX_B, GLK_DISP_PW_AUX_C, + CNL_DISP_PW_AUX_A = GLK_DISP_PW_AUX_A, + CNL_DISP_PW_AUX_B = GLK_DISP_PW_AUX_B, + CNL_DISP_PW_AUX_C = GLK_DISP_PW_AUX_C, + CNL_DISP_PW_AUX_D, SKL_DISP_PW_1 = 14, SKL_DISP_PW_2, @@ -1658,6 +1685,10 @@ enum skl_disp_power_wells { #define PHY_RESERVED (1 << 7) #define BXT_PORT_CL1CM_DW0(phy) _BXT_PHY((phy), _PORT_CL1CM_DW0_BC) +#define CNL_PORT_CL1CM_DW5 _MMIO(0x162014) +#define CL_POWER_DOWN_ENABLE (1 << 4) +#define SUS_CLOCK_CONFIG (3 << 0) + #define _PORT_CL1CM_DW9_A 0x162024 #define _PORT_CL1CM_DW9_BC 0x6C024 #define IREF0RC_OFFSET_SHIFT 8 @@ -1682,6 +1713,146 @@ enum skl_disp_power_wells { #define OCL2_LDOFUSE_PWR_DIS (1 << 6) #define BXT_PORT_CL1CM_DW30(phy) _BXT_PHY((phy), _PORT_CL1CM_DW30_BC) +#define _CNL_PORT_PCS_DW1_GRP_AE 0x162304 +#define _CNL_PORT_PCS_DW1_GRP_B 0x162384 +#define _CNL_PORT_PCS_DW1_GRP_C 0x162B04 +#define _CNL_PORT_PCS_DW1_GRP_D 0x162B84 +#define _CNL_PORT_PCS_DW1_GRP_F 0x162A04 +#define _CNL_PORT_PCS_DW1_LN0_AE 0x162404 +#define _CNL_PORT_PCS_DW1_LN0_B 0x162604 +#define _CNL_PORT_PCS_DW1_LN0_C 0x162C04 +#define _CNL_PORT_PCS_DW1_LN0_D 0x162E04 +#define _CNL_PORT_PCS_DW1_LN0_F 0x162804 +#define CNL_PORT_PCS_DW1_GRP(port) _MMIO_PORT6(port, \ + _CNL_PORT_PCS_DW1_GRP_AE, \ + _CNL_PORT_PCS_DW1_GRP_B, \ + _CNL_PORT_PCS_DW1_GRP_C, \ + _CNL_PORT_PCS_DW1_GRP_D, \ + _CNL_PORT_PCS_DW1_GRP_AE, \ + _CNL_PORT_PCS_DW1_GRP_F) +#define CNL_PORT_PCS_DW1_LN0(port) _MMIO_PORT6(port, \ + _CNL_PORT_PCS_DW1_LN0_AE, \ + _CNL_PORT_PCS_DW1_LN0_B, \ + _CNL_PORT_PCS_DW1_LN0_C, \ + _CNL_PORT_PCS_DW1_LN0_D, \ + _CNL_PORT_PCS_DW1_LN0_AE, \ + _CNL_PORT_PCS_DW1_LN0_F) +#define COMMON_KEEPER_EN (1 << 26) + +#define _CNL_PORT_TX_DW2_GRP_AE 0x162348 +#define _CNL_PORT_TX_DW2_GRP_B 0x1623C8 +#define _CNL_PORT_TX_DW2_GRP_C 0x162B48 +#define _CNL_PORT_TX_DW2_GRP_D 0x162BC8 +#define _CNL_PORT_TX_DW2_GRP_F 0x162A48 +#define _CNL_PORT_TX_DW2_LN0_AE 0x162448 +#define _CNL_PORT_TX_DW2_LN0_B 0x162648 +#define _CNL_PORT_TX_DW2_LN0_C 0x162C48 +#define _CNL_PORT_TX_DW2_LN0_D 0x162E48 +#define _CNL_PORT_TX_DW2_LN0_F 0x162A48 +#define CNL_PORT_TX_DW2_GRP(port) _MMIO_PORT6(port, \ + _CNL_PORT_TX_DW2_GRP_AE, \ + _CNL_PORT_TX_DW2_GRP_B, \ + _CNL_PORT_TX_DW2_GRP_C, \ + _CNL_PORT_TX_DW2_GRP_D, \ + _CNL_PORT_TX_DW2_GRP_AE, \ + _CNL_PORT_TX_DW2_GRP_F) +#define CNL_PORT_TX_DW2_LN0(port) _MMIO_PORT6(port, \ + _CNL_PORT_TX_DW2_LN0_AE, \ + _CNL_PORT_TX_DW2_LN0_B, \ + _CNL_PORT_TX_DW2_LN0_C, \ + _CNL_PORT_TX_DW2_LN0_D, \ + _CNL_PORT_TX_DW2_LN0_AE, \ + _CNL_PORT_TX_DW2_LN0_F) +#define SWING_SEL_UPPER(x) ((x >> 3) << 15) +#define SWING_SEL_LOWER(x) ((x & 0x7) << 11) +#define RCOMP_SCALAR(x) ((x) << 0) + +#define _CNL_PORT_TX_DW4_GRP_AE 0x162350 +#define _CNL_PORT_TX_DW4_GRP_B 0x1623D0 +#define _CNL_PORT_TX_DW4_GRP_C 0x162B50 +#define _CNL_PORT_TX_DW4_GRP_D 0x162BD0 +#define _CNL_PORT_TX_DW4_GRP_F 0x162A50 +#define _CNL_PORT_TX_DW4_LN0_AE 0x162450 +#define _CNL_PORT_TX_DW4_LN1_AE 0x1624D0 +#define _CNL_PORT_TX_DW4_LN0_B 0x162650 +#define _CNL_PORT_TX_DW4_LN0_C 0x162C50 +#define _CNL_PORT_TX_DW4_LN0_D 0x162E50 +#define _CNL_PORT_TX_DW4_LN0_F 0x162850 +#define CNL_PORT_TX_DW4_GRP(port) _MMIO_PORT6(port, \ + _CNL_PORT_TX_DW4_GRP_AE, \ + _CNL_PORT_TX_DW4_GRP_B, \ + _CNL_PORT_TX_DW4_GRP_C, \ + _CNL_PORT_TX_DW4_GRP_D, \ + _CNL_PORT_TX_DW4_GRP_AE, \ + _CNL_PORT_TX_DW4_GRP_F) +#define CNL_PORT_TX_DW4_LN(port, ln) _MMIO_PORT6_LN(port, ln, \ + _CNL_PORT_TX_DW4_LN0_AE, \ + _CNL_PORT_TX_DW4_LN1_AE, \ + _CNL_PORT_TX_DW4_LN0_B, \ + _CNL_PORT_TX_DW4_LN0_C, \ + _CNL_PORT_TX_DW4_LN0_D, \ + _CNL_PORT_TX_DW4_LN0_AE, \ + _CNL_PORT_TX_DW4_LN0_F) +#define LOADGEN_SELECT (1 << 31) +#define POST_CURSOR_1(x) ((x) << 12) +#define POST_CURSOR_2(x) ((x) << 6) +#define CURSOR_COEFF(x) ((x) << 0) + +#define _CNL_PORT_TX_DW5_GRP_AE 0x162354 +#define _CNL_PORT_TX_DW5_GRP_B 0x1623D4 +#define _CNL_PORT_TX_DW5_GRP_C 0x162B54 +#define _CNL_PORT_TX_DW5_GRP_D 0x162BD4 +#define _CNL_PORT_TX_DW5_GRP_F 0x162A54 +#define _CNL_PORT_TX_DW5_LN0_AE 0x162454 +#define _CNL_PORT_TX_DW5_LN0_B 0x162654 +#define _CNL_PORT_TX_DW5_LN0_C 0x162C54 +#define _CNL_PORT_TX_DW5_LN0_D 0x162ED4 +#define _CNL_PORT_TX_DW5_LN0_F 0x162854 +#define CNL_PORT_TX_DW5_GRP(port) _MMIO_PORT6(port, \ + _CNL_PORT_TX_DW5_GRP_AE, \ + _CNL_PORT_TX_DW5_GRP_B, \ + _CNL_PORT_TX_DW5_GRP_C, \ + _CNL_PORT_TX_DW5_GRP_D, \ + _CNL_PORT_TX_DW5_GRP_AE, \ + _CNL_PORT_TX_DW5_GRP_F) +#define CNL_PORT_TX_DW5_LN0(port) _MMIO_PORT6(port, \ + _CNL_PORT_TX_DW5_LN0_AE, \ + _CNL_PORT_TX_DW5_LN0_B, \ + _CNL_PORT_TX_DW5_LN0_C, \ + _CNL_PORT_TX_DW5_LN0_D, \ + _CNL_PORT_TX_DW5_LN0_AE, \ + _CNL_PORT_TX_DW5_LN0_F) +#define TX_TRAINING_EN (1 << 31) +#define TAP3_DISABLE (1 << 29) +#define SCALING_MODE_SEL(x) ((x) << 18) +#define RTERM_SELECT(x) ((x) << 3) + +#define _CNL_PORT_TX_DW7_GRP_AE 0x16235C +#define _CNL_PORT_TX_DW7_GRP_B 0x1623DC +#define _CNL_PORT_TX_DW7_GRP_C 0x162B5C +#define _CNL_PORT_TX_DW7_GRP_D 0x162BDC +#define _CNL_PORT_TX_DW7_GRP_F 0x162A5C +#define _CNL_PORT_TX_DW7_LN0_AE 0x16245C +#define _CNL_PORT_TX_DW7_LN0_B 0x16265C +#define _CNL_PORT_TX_DW7_LN0_C 0x162C5C +#define _CNL_PORT_TX_DW7_LN0_D 0x162EDC +#define _CNL_PORT_TX_DW7_LN0_F 0x16285C +#define CNL_PORT_TX_DW7_GRP(port) _MMIO_PORT6(port, \ + _CNL_PORT_TX_DW7_GRP_AE, \ + _CNL_PORT_TX_DW7_GRP_B, \ + _CNL_PORT_TX_DW7_GRP_C, \ + _CNL_PORT_TX_DW7_GRP_D, \ + _CNL_PORT_TX_DW7_GRP_AE, \ + _CNL_PORT_TX_DW7_GRP_F) +#define CNL_PORT_TX_DW7_LN0(port) _MMIO_PORT6(port, \ + _CNL_PORT_TX_DW7_LN0_AE, \ + _CNL_PORT_TX_DW7_LN0_B, \ + _CNL_PORT_TX_DW7_LN0_C, \ + _CNL_PORT_TX_DW7_LN0_D, \ + _CNL_PORT_TX_DW7_LN0_AE, \ + _CNL_PORT_TX_DW7_LN0_F) +#define N_SCALAR(x) ((x) << 24) + /* The spec defines this only for BXT PHY0, but lets assume that this * would exist for PHY1 too if it had a second channel. */ @@ -1690,6 +1861,23 @@ enum skl_disp_power_wells { #define BXT_PORT_CL2CM_DW6(phy) _BXT_PHY((phy), _PORT_CL2CM_DW6_BC) #define DW6_OLDO_DYN_PWR_DOWN_EN (1 << 28) +#define CNL_PORT_COMP_DW0 _MMIO(0x162100) +#define COMP_INIT (1 << 31) +#define CNL_PORT_COMP_DW1 _MMIO(0x162104) +#define CNL_PORT_COMP_DW3 _MMIO(0x16210c) +#define PROCESS_INFO_DOT_0 (0 << 26) +#define PROCESS_INFO_DOT_1 (1 << 26) +#define PROCESS_INFO_DOT_4 (2 << 26) +#define PROCESS_INFO_MASK (7 << 26) +#define PROCESS_INFO_SHIFT 26 +#define VOLTAGE_INFO_0_85V (0 << 24) +#define VOLTAGE_INFO_0_95V (1 << 24) +#define VOLTAGE_INFO_1_05V (2 << 24) +#define VOLTAGE_INFO_MASK (3 << 24) +#define VOLTAGE_INFO_SHIFT 24 +#define CNL_PORT_COMP_DW9 _MMIO(0x162124) +#define CNL_PORT_COMP_DW10 _MMIO(0x162128) + /* BXT PHY Ref registers */ #define _PORT_REF_DW3_A 0x16218C #define _PORT_REF_DW3_BC 0x6C18C @@ -2325,6 +2513,9 @@ enum skl_disp_power_wells { #define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) #define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10) +#define GEN6_RCS_PWR_FSM _MMIO(0x22ac) +#define GEN9_RCS_FE_FSM2 _MMIO(0x22a4) + /* Fuse readout registers for GT */ #define CHV_FUSE_GT _MMIO(VLV_DISPLAY_BASE + 0x2168) #define CHV_FGT_DISABLE_SS0 (1 << 10) @@ -2507,10 +2698,6 @@ enum skl_disp_power_wells { #define FBC_FENCE_OFF _MMIO(0x3218) /* BSpec typo has 321Bh */ #define FBC_TAG(i) _MMIO(0x3300 + (i) * 4) -#define FBC_STATUS2 _MMIO(0x43214) -#define IVB_FBC_COMPRESSION_MASK 0x7ff -#define BDW_FBC_COMPRESSION_MASK 0xfff - #define FBC_LL_SIZE (1536) #define FBC_LLC_READ_CTRL _MMIO(0x9044) @@ -2539,7 +2726,7 @@ enum skl_disp_power_wells { #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_COMP_SEG_MASK (0x000007ff) #define DPFC_STATUS2 _MMIO(0x3214) #define DPFC_FENCE_YOFF _MMIO(0x3218) #define DPFC_CHICKEN _MMIO(0x3224) @@ -2553,6 +2740,10 @@ enum skl_disp_power_wells { #define DPFC_RESERVED (0x1FFFFF00) #define ILK_DPFC_RECOMP_CTL _MMIO(0x4320c) #define ILK_DPFC_STATUS _MMIO(0x43210) +#define ILK_DPFC_COMP_SEG_MASK 0x7ff +#define IVB_FBC_STATUS2 _MMIO(0x43214) +#define IVB_FBC_COMP_SEG_MASK 0x7ff +#define BDW_FBC_COMP_SEG_MASK 0xfff #define ILK_DPFC_FENCE_YOFF _MMIO(0x43218) #define ILK_DPFC_CHICKEN _MMIO(0x43224) #define ILK_DPFC_DISABLE_DUMMY0 (1<<8) @@ -2626,9 +2817,10 @@ enum skl_disp_power_wells { #define GMBUS_PIN_DPB 5 /* SDVO, HDMIB */ #define GMBUS_PIN_DPD 6 /* HDMID */ #define GMBUS_PIN_RESERVED 7 /* 7 reserved */ -#define GMBUS_PIN_1_BXT 1 +#define GMBUS_PIN_1_BXT 1 /* BXT+ (atom) and CNP+ (big core) */ #define GMBUS_PIN_2_BXT 2 #define GMBUS_PIN_3_BXT 3 +#define GMBUS_PIN_4_CNP 4 #define GMBUS_NUM_PINS 7 /* including 0 */ #define GMBUS1 _MMIO(dev_priv->gpio_mmio_base + 0x5104) /* command/status */ #define GMBUS_SW_CLR_INT (1<<31) @@ -6506,6 +6698,9 @@ enum { #define GLK_CL1_PWR_DOWN (1 << 11) #define GLK_CL2_PWR_DOWN (1 << 12) +#define CHICKEN_MISC_2 _MMIO(0x42084) +#define COMP_PWR_DOWN (1 << 23) + #define _CHICKEN_PIPESL_1_A 0x420b0 #define _CHICKEN_PIPESL_1_B 0x420b4 #define HSW_FBCQ_DIS (1 << 22) @@ -6546,6 +6741,9 @@ enum { #define SKL_DFSM_PIPE_B_DISABLE (1 << 21) #define SKL_DFSM_PIPE_C_DISABLE (1 << 28) +#define SKL_DSSM _MMIO(0x51004) +#define CNL_DSSM_CDCLK_PLL_REFCLK_24MHz (1 << 31) + #define GEN7_FF_SLICE_CS_CHICKEN1 _MMIO(0x20e0) #define GEN9_FFSC_PERCTX_PREEMPT_CTRL (1<<14) @@ -6838,6 +7036,10 @@ enum { #define FDL_TP2_TIMER_SHIFT 10 #define FDL_TP2_TIMER_MASK (3<<10) #define RAWCLK_FREQ_MASK 0x3ff +#define CNP_RAWCLK_DIV_MASK (0x3ff << 16) +#define CNP_RAWCLK_DIV(div) ((div) << 16) +#define CNP_RAWCLK_FRAC_MASK (0xf << 26) +#define CNP_RAWCLK_FRAC(frac) ((frac) << 26) #define PCH_DPLL_TMR_CFG _MMIO(0xc6208) @@ -7792,13 +7994,6 @@ enum { #define SKL_FUSE_PG1_DIST_STATUS (1<<26) #define SKL_FUSE_PG2_DIST_STATUS (1<<25) -/* Decoupled MMIO register pair for kernel driver */ -#define GEN9_DECOUPLED_REG0_DW0 _MMIO(0xF00) -#define GEN9_DECOUPLED_REG0_DW1 _MMIO(0xF04) -#define GEN9_DECOUPLED_DW1_GO (1<<31) -#define GEN9_DECOUPLED_PD_SHIFT 28 -#define GEN9_DECOUPLED_OP_SHIFT 24 - /* Per-pipe DDI Function Control */ #define _TRANS_DDI_FUNC_CTL_A 0x60400 #define _TRANS_DDI_FUNC_CTL_B 0x61400 @@ -8107,6 +8302,61 @@ enum { #define DPLL_CFGCR1(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1) #define DPLL_CFGCR2(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2) +/* + * CNL Clocks + */ +#define DPCLKA_CFGCR0 _MMIO(0x6C200) +#define DPCLKA_CFGCR0_DDI_CLK_OFF(port) (1 << ((port)+10)) +#define DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port) (3 << ((port)*2)) +#define DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port) ((port)*2) +#define DPCLKA_CFGCR0_DDI_CLK_SEL(pll, port) ((pll) << ((port)*2)) + +/* CNL PLL */ +#define DPLL0_ENABLE 0x46010 +#define DPLL1_ENABLE 0x46014 +#define PLL_ENABLE (1 << 31) +#define PLL_LOCK (1 << 30) +#define PLL_POWER_ENABLE (1 << 27) +#define PLL_POWER_STATE (1 << 26) +#define CNL_DPLL_ENABLE(pll) _MMIO_PLL(pll, DPLL0_ENABLE, DPLL1_ENABLE) + +#define _CNL_DPLL0_CFGCR0 0x6C000 +#define _CNL_DPLL1_CFGCR0 0x6C080 +#define DPLL_CFGCR0_HDMI_MODE (1 << 30) +#define DPLL_CFGCR0_SSC_ENABLE (1 << 29) +#define DPLL_CFGCR0_LINK_RATE_MASK (0xf << 25) +#define DPLL_CFGCR0_LINK_RATE_2700 (0 << 25) +#define DPLL_CFGCR0_LINK_RATE_1350 (1 << 25) +#define DPLL_CFGCR0_LINK_RATE_810 (2 << 25) +#define DPLL_CFGCR0_LINK_RATE_1620 (3 << 25) +#define DPLL_CFGCR0_LINK_RATE_1080 (4 << 25) +#define DPLL_CFGCR0_LINK_RATE_2160 (5 << 25) +#define DPLL_CFGCR0_LINK_RATE_3240 (6 << 25) +#define DPLL_CFGCR0_LINK_RATE_4050 (7 << 25) +#define DPLL_CFGCR0_DCO_FRACTION_MASK (0x7fff << 10) +#define DPLL_CFGCR0_DCO_FRACTION(x) ((x) << 10) +#define DPLL_CFGCR0_DCO_INTEGER_MASK (0x3ff) +#define CNL_DPLL_CFGCR0(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR0, _CNL_DPLL1_CFGCR0) + +#define _CNL_DPLL0_CFGCR1 0x6C004 +#define _CNL_DPLL1_CFGCR1 0x6C084 +#define DPLL_CFGCR1_QDIV_RATIO_MASK (0xff << 10) +#define DPLL_CFGCR1_QDIV_RATIO(x) ((x) << 10) +#define DPLL_CFGCR1_QDIV_MODE(x) ((x) << 9) +#define DPLL_CFGCR1_KDIV_MASK (7 << 6) +#define DPLL_CFGCR1_KDIV(x) ((x) << 6) +#define DPLL_CFGCR1_KDIV_1 (1 << 6) +#define DPLL_CFGCR1_KDIV_2 (2 << 6) +#define DPLL_CFGCR1_KDIV_4 (4 << 6) +#define DPLL_CFGCR1_PDIV_MASK (0xf << 2) +#define DPLL_CFGCR1_PDIV(x) ((x) << 2) +#define DPLL_CFGCR1_PDIV_2 (1 << 2) +#define DPLL_CFGCR1_PDIV_3 (2 << 2) +#define DPLL_CFGCR1_PDIV_5 (4 << 2) +#define DPLL_CFGCR1_PDIV_7 (8 << 2) +#define DPLL_CFGCR1_CENTRAL_FREQ (3 << 0) +#define CNL_DPLL_CFGCR1(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR1, _CNL_DPLL1_CFGCR1) + /* BXT display engine PLL */ #define BXT_DE_PLL_CTL _MMIO(0x6d000) #define BXT_DE_PLL_RATIO(x) (x) /* {60,65,100} * 19.2MHz */ @@ -8115,6 +8365,8 @@ enum { #define BXT_DE_PLL_ENABLE _MMIO(0x46070) #define BXT_DE_PLL_PLL_ENABLE (1 << 31) #define BXT_DE_PLL_LOCK (1 << 30) +#define CNL_CDCLK_PLL_RATIO(x) (x) +#define CNL_CDCLK_PLL_RATIO_MASK 0xff /* GEN9 DC */ #define DC_STATE_EN _MMIO(0x45504) @@ -8148,6 +8400,7 @@ enum { /* SFUSE_STRAP */ #define SFUSE_STRAP _MMIO(0xc2014) #define SFUSE_STRAP_FUSE_LOCK (1<<13) +#define SFUSE_STRAP_RAW_FREQUENCY (1<<8) #define SFUSE_STRAP_DISPLAY_DISABLED (1<<7) #define SFUSE_STRAP_CRT_DISABLED (1<<6) #define SFUSE_STRAP_DDIB_DETECTED (1<<2) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 16ecd1a..12fc250 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -99,6 +99,11 @@ __T; \ }) +#define u64_to_ptr(T, x) ({ \ + typecheck(u64, x); \ + (T *)(uintptr_t)(x); \ +}) + #define __mask_next_bit(mask) ({ \ int __idx = ffs(mask) - 1; \ mask &= ~BIT(__idx); \ diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index 2e73901..cf7a958 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -90,6 +90,18 @@ struct _balloon_info_ { static struct _balloon_info_ bl_info; +static void vgt_deballoon_space(struct i915_ggtt *ggtt, + struct drm_mm_node *node) +{ + DRM_DEBUG_DRIVER("deballoon space: range [0x%llx - 0x%llx] %llu KiB.\n", + node->start, + node->start + node->size, + node->size / 1024); + + ggtt->base.reserved -= node->size; + drm_mm_remove_node(node); +} + /** * intel_vgt_deballoon - deballoon reserved graphics address trunks * @dev_priv: i915 device private data @@ -106,12 +118,8 @@ void intel_vgt_deballoon(struct drm_i915_private *dev_priv) DRM_DEBUG("VGT deballoon.\n"); - for (i = 0; i < 4; i++) { - if (bl_info.space[i].allocated) - drm_mm_remove_node(&bl_info.space[i]); - } - - memset(&bl_info, 0, sizeof(bl_info)); + for (i = 0; i < 4; i++) + vgt_deballoon_space(&dev_priv->ggtt, &bl_info.space[i]); } static int vgt_balloon_space(struct i915_ggtt *ggtt, @@ -119,15 +127,20 @@ static int vgt_balloon_space(struct i915_ggtt *ggtt, unsigned long start, unsigned long end) { unsigned long size = end - start; + int ret; if (start >= end) return -EINVAL; DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n", start, end, size / 1024); - return i915_gem_gtt_reserve(&ggtt->base, node, - size, start, I915_COLOR_UNEVICTABLE, - 0); + ret = i915_gem_gtt_reserve(&ggtt->base, node, + size, start, I915_COLOR_UNEVICTABLE, + 0); + if (!ret) + ggtt->base.reserved += size; + + return ret; } /** @@ -220,7 +233,7 @@ int intel_vgt_balloon(struct drm_i915_private *dev_priv) ret = vgt_balloon_space(ggtt, &bl_info.space[3], unmappable_end, ggtt_end); if (ret) - goto err; + goto err_upon_mappable; } /* Mappable graphic memory ballooning */ @@ -229,7 +242,7 @@ int intel_vgt_balloon(struct drm_i915_private *dev_priv) 0, mappable_base); if (ret) - goto err; + goto err_upon_unmappable; } if (mappable_end < ggtt->mappable_end) { @@ -237,14 +250,19 @@ int intel_vgt_balloon(struct drm_i915_private *dev_priv) mappable_end, ggtt->mappable_end); if (ret) - goto err; + goto err_below_mappable; } DRM_INFO("VGT balloon successfully\n"); return 0; +err_below_mappable: + vgt_deballoon_space(ggtt, &bl_info.space[0]); +err_upon_unmappable: + vgt_deballoon_space(ggtt, &bl_info.space[3]); +err_upon_mappable: + vgt_deballoon_space(ggtt, &bl_info.space[2]); err: DRM_ERROR("VGT balloon fail\n"); - intel_vgt_deballoon(dev_priv); return ret; } diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 1aba470..532c709 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -85,12 +85,12 @@ vma_create(struct drm_i915_gem_object *obj, if (vma == NULL) return ERR_PTR(-ENOMEM); - INIT_LIST_HEAD(&vma->exec_list); for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) init_request_active(&vma->last_read[i], i915_vma_retire); init_request_active(&vma->last_fence, NULL); vma->vm = vm; vma->obj = obj; + vma->resv = obj->resv; vma->size = obj->base.size; vma->display_alignment = I915_GTT_MIN_ALIGNMENT; @@ -464,7 +464,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) size, obj->base.size, flags & PIN_MAPPABLE ? "mappable" : "total", end); - return -E2BIG; + return -ENOSPC; } ret = i915_gem_object_pin_pages(obj); @@ -577,7 +577,7 @@ err_unpin: return ret; } -void i915_vma_destroy(struct i915_vma *vma) +static void i915_vma_destroy(struct i915_vma *vma) { GEM_BUG_ON(vma->node.allocated); GEM_BUG_ON(i915_vma_is_active(vma)); @@ -591,11 +591,33 @@ void i915_vma_destroy(struct i915_vma *vma) kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma); } +void i915_vma_unlink_ctx(struct i915_vma *vma) +{ + struct i915_gem_context *ctx = vma->ctx; + + if (ctx->vma_lut.ht_size & I915_CTX_RESIZE_IN_PROGRESS) { + cancel_work_sync(&ctx->vma_lut.resize); + ctx->vma_lut.ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS; + } + + __hlist_del(&vma->ctx_node); + ctx->vma_lut.ht_count--; + + if (i915_vma_is_ggtt(vma)) + vma->obj->vma_hashed = NULL; + vma->ctx = NULL; + + i915_vma_put(vma); +} + void i915_vma_close(struct i915_vma *vma) { GEM_BUG_ON(i915_vma_is_closed(vma)); vma->flags |= I915_VMA_CLOSED; + if (vma->ctx) + i915_vma_unlink_ctx(vma); + list_del(&vma->obj_link); rb_erase(&vma->obj_node, &vma->obj->vma_tree); diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 2e03f81..4a673fc 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -50,6 +50,7 @@ struct i915_vma { struct drm_i915_gem_object *obj; struct i915_address_space *vm; struct drm_i915_fence_reg *fence; + struct reservation_object *resv; /** Alias of obj->resv */ struct sg_table *pages; void __iomem *iomap; u64 size; @@ -99,16 +100,25 @@ struct i915_vma { struct list_head obj_link; /* Link in the object's VMA list */ struct rb_node obj_node; + struct hlist_node obj_hash; - /** This vma's place in the batchbuffer or on the eviction list */ - struct list_head exec_list; + /** This vma's place in the execbuf reservation list */ + struct list_head exec_link; + struct list_head reloc_link; + + /** This vma's place in the eviction list */ + struct list_head evict_link; /** * Used for performing relocations during execbuffer insertion. */ - struct hlist_node exec_node; - unsigned long exec_handle; struct drm_i915_gem_exec_object2 *exec_entry; + struct hlist_node exec_node; + u32 exec_handle; + + struct i915_gem_context *ctx; + struct hlist_node ctx_node; + u32 ctx_handle; }; struct i915_vma * @@ -232,8 +242,8 @@ bool i915_vma_misplaced(const struct i915_vma *vma, u64 size, u64 alignment, u64 flags); void __i915_vma_set_map_and_fenceable(struct i915_vma *vma); int __must_check i915_vma_unbind(struct i915_vma *vma); +void i915_vma_unlink_ctx(struct i915_vma *vma); void i915_vma_close(struct i915_vma *vma); -void i915_vma_destroy(struct i915_vma *vma); int __i915_vma_do_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags); diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 50fb1f7..36d4e63 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -36,44 +36,121 @@ #include "intel_drv.h" /** - * intel_connector_atomic_get_property - fetch connector property value - * @connector: connector to fetch property for - * @state: state containing the property value - * @property: property to look up - * @val: pointer to write property value into + * intel_digital_connector_atomic_get_property - hook for connector->atomic_get_property. + * @connector: Connector to get the property for. + * @state: Connector state to retrieve the property from. + * @property: Property to retrieve. + * @val: Return value for the property. * - * The DRM core does not store shadow copies of properties for - * atomic-capable drivers. This entrypoint is used to fetch - * the current value of a driver-specific connector property. + * Returns the atomic property value for a digital connector. */ -int -intel_connector_atomic_get_property(struct drm_connector *connector, - const struct drm_connector_state *state, - struct drm_property *property, - uint64_t *val) +int intel_digital_connector_atomic_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) { - int i; + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_digital_connector_state *intel_conn_state = + to_intel_digital_connector_state(state); + + if (property == dev_priv->force_audio_property) + *val = intel_conn_state->force_audio; + else if (property == dev_priv->broadcast_rgb_property) + *val = intel_conn_state->broadcast_rgb; + else { + DRM_DEBUG_ATOMIC("Unknown property %s\n", property->name); + return -EINVAL; + } - /* - * TODO: We only have atomic modeset for planes at the moment, so the - * crtc/connector code isn't quite ready yet. Until it's ready, - * continue to look up all property values in the DRM's shadow copy - * in obj->properties->values[]. - * - * When the crtc/connector state work matures, this function should - * be updated to read the values out of the state structure instead. - */ - for (i = 0; i < connector->base.properties->count; i++) { - if (connector->base.properties->properties[i] == property) { - *val = connector->base.properties->values[i]; - return 0; - } + return 0; +} + +/** + * intel_digital_connector_atomic_set_property - hook for connector->atomic_set_property. + * @connector: Connector to set the property for. + * @state: Connector state to set the property on. + * @property: Property to set. + * @val: New value for the property. + * + * Sets the atomic property value for a digital connector. + */ +int intel_digital_connector_atomic_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_digital_connector_state *intel_conn_state = + to_intel_digital_connector_state(state); + + if (property == dev_priv->force_audio_property) { + intel_conn_state->force_audio = val; + return 0; } + if (property == dev_priv->broadcast_rgb_property) { + intel_conn_state->broadcast_rgb = val; + return 0; + } + + DRM_DEBUG_ATOMIC("Unknown property %s\n", property->name); return -EINVAL; } -/* +int intel_digital_connector_atomic_check(struct drm_connector *conn, + struct drm_connector_state *new_state) +{ + struct intel_digital_connector_state *new_conn_state = + to_intel_digital_connector_state(new_state); + struct drm_connector_state *old_state = + drm_atomic_get_old_connector_state(new_state->state, conn); + struct intel_digital_connector_state *old_conn_state = + to_intel_digital_connector_state(old_state); + struct drm_crtc_state *crtc_state; + + if (!new_state->crtc) + return 0; + + crtc_state = drm_atomic_get_new_crtc_state(new_state->state, new_state->crtc); + + /* + * These properties are handled by fastset, and might not end + * up in a modeset. + */ + if (new_conn_state->force_audio != old_conn_state->force_audio || + new_conn_state->broadcast_rgb != old_conn_state->broadcast_rgb || + new_conn_state->base.picture_aspect_ratio != old_conn_state->base.picture_aspect_ratio || + new_conn_state->base.scaling_mode != old_conn_state->base.scaling_mode) + crtc_state->mode_changed = true; + + return 0; +} + +/** + * intel_digital_connector_duplicate_state - duplicate connector state + * @connector: digital connector + * + * Allocates and returns a copy of the connector state (both common and + * digital connector specific) for the specified connector. + * + * Returns: The newly allocated connector state, or NULL on failure. + */ +struct drm_connector_state * +intel_digital_connector_duplicate_state(struct drm_connector *connector) +{ + struct intel_digital_connector_state *state; + + state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL); + if (!state) + return NULL; + + __drm_atomic_helper_connector_duplicate_state(connector, &state->base); + return &state->base; +} + +/** * intel_crtc_duplicate_state - duplicate crtc state * @crtc: drm crtc * @@ -248,7 +325,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, } /* set scaler mode */ - if (IS_GEMINILAKE(dev_priv)) { + if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) { scaler_state->scalers[*scaler_id].mode = 0; } else if (num_scalers_need == 1 && intel_crtc->pipe != PIPE_C) { /* diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 183afcb..4e00e5c 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -234,7 +234,7 @@ static void enable_fake_irq(struct intel_breadcrumbs *b) mod_timer(&b->hangcheck, wait_timeout()); } -static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) +static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) { struct intel_engine_cs *engine = container_of(b, struct intel_engine_cs, breadcrumbs); @@ -242,7 +242,7 @@ static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) lockdep_assert_held(&b->irq_lock); if (b->irq_armed) - return; + return false; /* The breadcrumb irq will be disarmed on the interrupt after the * waiters are signaled. This gives us a single interrupt window in @@ -260,7 +260,7 @@ static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) * implementation to call intel_engine_wakeup() * itself when it wants to simulate a user interrupt, */ - return; + return true; } /* Since we are waiting on a request, the GPU should be busy @@ -278,6 +278,7 @@ static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) } enable_fake_irq(b); + return true; } static inline struct intel_wait *to_wait(struct rb_node *node) @@ -329,7 +330,7 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, { struct intel_breadcrumbs *b = &engine->breadcrumbs; struct rb_node **p, *parent, *completed; - bool first; + bool first, armed; u32 seqno; /* Insert the request into the retirement ordered list @@ -344,6 +345,7 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, * removing stale elements in the tree, we may be able to reduce the * ping-pong between the old bottom-half and ourselves as first-waiter. */ + armed = false; first = true; parent = NULL; completed = NULL; @@ -399,7 +401,7 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, * in the unlocked read of b->irq_seqno_bh in the irq handler) * and so we miss the wake up. */ - __intel_breadcrumbs_enable_irq(b); + armed = __intel_breadcrumbs_enable_irq(b); spin_unlock(&b->irq_lock); } @@ -426,20 +428,24 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, GEM_BUG_ON(!b->irq_armed); GEM_BUG_ON(rb_first(&b->waiters) != &b->irq_wait->node); - return first; + return armed; } bool intel_engine_add_wait(struct intel_engine_cs *engine, struct intel_wait *wait) { struct intel_breadcrumbs *b = &engine->breadcrumbs; - bool first; + bool armed; spin_lock_irq(&b->rb_lock); - first = __intel_engine_add_wait(engine, wait); + armed = __intel_engine_add_wait(engine, wait); spin_unlock_irq(&b->rb_lock); + if (armed) + return armed; - return first; + /* Make the caller recheck if its request has already started. */ + return i915_seqno_passed(intel_engine_get_seqno(engine), + wait->seqno - 1); } static inline bool chain_wakeup(struct rb_node *rb, int priority) @@ -672,8 +678,6 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request, { struct intel_engine_cs *engine = request->engine; struct intel_breadcrumbs *b = &engine->breadcrumbs; - struct rb_node *parent, **p; - bool first; u32 seqno; /* Note that we may be called from an interrupt handler on another @@ -708,27 +712,36 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request, */ wakeup &= __intel_engine_add_wait(engine, &request->signaling.wait); - /* Now insert ourselves into the retirement ordered list of signals - * on this engine. We track the oldest seqno as that will be the - * first signal to complete. - */ - parent = NULL; - first = true; - p = &b->signals.rb_node; - while (*p) { - parent = *p; - if (i915_seqno_passed(seqno, - to_signaler(parent)->signaling.wait.seqno)) { - p = &parent->rb_right; - first = false; - } else { - p = &parent->rb_left; + if (!__i915_gem_request_completed(request, seqno)) { + struct rb_node *parent, **p; + bool first; + + /* Now insert ourselves into the retirement ordered list of + * signals on this engine. We track the oldest seqno as that + * will be the first signal to complete. + */ + parent = NULL; + first = true; + p = &b->signals.rb_node; + while (*p) { + parent = *p; + if (i915_seqno_passed(seqno, + to_signaler(parent)->signaling.wait.seqno)) { + p = &parent->rb_right; + first = false; + } else { + p = &parent->rb_left; + } } + rb_link_node(&request->signaling.node, parent, p); + rb_insert_color(&request->signaling.node, &b->signals); + if (first) + rcu_assign_pointer(b->first_signal, request); + } else { + __intel_engine_remove_wait(engine, &request->signaling.wait); + i915_gem_request_put(request); + wakeup = false; } - rb_link_node(&request->signaling.node, parent, p); - rb_insert_color(&request->signaling.node, &b->signals); - if (first) - rcu_assign_pointer(b->first_signal, request); spin_unlock(&b->rb_lock); diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 2979297..b8914db 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -1400,6 +1400,280 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) bxt_set_cdclk(dev_priv, &cdclk_state); } +static int cnl_calc_cdclk(int max_pixclk) +{ + if (max_pixclk > 336000) + return 528000; + else if (max_pixclk > 168000) + return 336000; + else + return 168000; +} + +static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv, + struct intel_cdclk_state *cdclk_state) +{ + u32 val; + + if (I915_READ(SKL_DSSM) & CNL_DSSM_CDCLK_PLL_REFCLK_24MHz) + cdclk_state->ref = 24000; + else + cdclk_state->ref = 19200; + + cdclk_state->vco = 0; + + val = I915_READ(BXT_DE_PLL_ENABLE); + if ((val & BXT_DE_PLL_PLL_ENABLE) == 0) + return; + + if (WARN_ON((val & BXT_DE_PLL_LOCK) == 0)) + return; + + cdclk_state->vco = (val & CNL_CDCLK_PLL_RATIO_MASK) * cdclk_state->ref; +} + +static void cnl_get_cdclk(struct drm_i915_private *dev_priv, + struct intel_cdclk_state *cdclk_state) +{ + u32 divider; + int div; + + cnl_cdclk_pll_update(dev_priv, cdclk_state); + + cdclk_state->cdclk = cdclk_state->ref; + + if (cdclk_state->vco == 0) + return; + + divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; + + switch (divider) { + case BXT_CDCLK_CD2X_DIV_SEL_1: + div = 2; + break; + case BXT_CDCLK_CD2X_DIV_SEL_2: + div = 4; + break; + default: + MISSING_CASE(divider); + return; + } + + cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div); +} + +static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv) +{ + u32 val; + + val = I915_READ(BXT_DE_PLL_ENABLE); + val &= ~BXT_DE_PLL_PLL_ENABLE; + I915_WRITE(BXT_DE_PLL_ENABLE, val); + + /* Timeout 200us */ + if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) == 0, 1)) + DRM_ERROR("timout waiting for CDCLK PLL unlock\n"); + + dev_priv->cdclk.hw.vco = 0; +} + +static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco) +{ + int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref); + u32 val; + + val = CNL_CDCLK_PLL_RATIO(ratio); + I915_WRITE(BXT_DE_PLL_ENABLE, val); + + val |= BXT_DE_PLL_PLL_ENABLE; + I915_WRITE(BXT_DE_PLL_ENABLE, val); + + /* Timeout 200us */ + if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1)) + DRM_ERROR("timout waiting for CDCLK PLL lock\n"); + + dev_priv->cdclk.hw.vco = vco; +} + +static void cnl_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *cdclk_state) +{ + int cdclk = cdclk_state->cdclk; + int vco = cdclk_state->vco; + u32 val, divider, pcu_ack; + int ret; + + mutex_lock(&dev_priv->rps.hw_lock); + ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL, + SKL_CDCLK_PREPARE_FOR_CHANGE, + SKL_CDCLK_READY_FOR_CHANGE, + SKL_CDCLK_READY_FOR_CHANGE, 3); + mutex_unlock(&dev_priv->rps.hw_lock); + if (ret) { + DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n", + ret); + return; + } + + /* cdclk = vco / 2 / div{1,2} */ + switch (DIV_ROUND_CLOSEST(vco, cdclk)) { + case 4: + divider = BXT_CDCLK_CD2X_DIV_SEL_2; + break; + case 2: + divider = BXT_CDCLK_CD2X_DIV_SEL_1; + break; + default: + WARN_ON(cdclk != dev_priv->cdclk.hw.ref); + WARN_ON(vco != 0); + + divider = BXT_CDCLK_CD2X_DIV_SEL_1; + break; + } + + switch (cdclk) { + case 528000: + pcu_ack = 2; + break; + case 336000: + pcu_ack = 1; + break; + case 168000: + default: + pcu_ack = 0; + break; + } + + if (dev_priv->cdclk.hw.vco != 0 && + dev_priv->cdclk.hw.vco != vco) + cnl_cdclk_pll_disable(dev_priv); + + if (dev_priv->cdclk.hw.vco != vco) + cnl_cdclk_pll_enable(dev_priv, vco); + + val = divider | skl_cdclk_decimal(cdclk); + /* + * FIXME if only the cd2x divider needs changing, it could be done + * without shutting off the pipe (if only one pipe is active). + */ + val |= BXT_CDCLK_CD2X_PIPE_NONE; + I915_WRITE(CDCLK_CTL, val); + + /* inform PCU of the change */ + mutex_lock(&dev_priv->rps.hw_lock); + sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack); + mutex_unlock(&dev_priv->rps.hw_lock); + + intel_update_cdclk(dev_priv); +} + +static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk) +{ + int ratio; + + if (cdclk == dev_priv->cdclk.hw.ref) + return 0; + + switch (cdclk) { + default: + MISSING_CASE(cdclk); + case 168000: + case 336000: + ratio = dev_priv->cdclk.hw.ref == 19200 ? 35 : 28; + break; + case 528000: + ratio = dev_priv->cdclk.hw.ref == 19200 ? 55 : 44; + break; + } + + return dev_priv->cdclk.hw.ref * ratio; +} + +static void cnl_sanitize_cdclk(struct drm_i915_private *dev_priv) +{ + u32 cdctl, expected; + + intel_update_cdclk(dev_priv); + + if (dev_priv->cdclk.hw.vco == 0 || + dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) + goto sanitize; + + /* DPLL okay; verify the cdclock + * + * Some BIOS versions leave an incorrect decimal frequency value and + * set reserved MBZ bits in CDCLK_CTL at least during exiting from S4, + * so sanitize this register. + */ + cdctl = I915_READ(CDCLK_CTL); + /* + * Let's ignore the pipe field, since BIOS could have configured the + * dividers both synching to an active pipe, or asynchronously + * (PIPE_NONE). + */ + cdctl &= ~BXT_CDCLK_CD2X_PIPE_NONE; + + expected = (cdctl & BXT_CDCLK_CD2X_DIV_SEL_MASK) | + skl_cdclk_decimal(dev_priv->cdclk.hw.cdclk); + + if (cdctl == expected) + /* All well; nothing to sanitize */ + return; + +sanitize: + DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n"); + + /* force cdclk programming */ + dev_priv->cdclk.hw.cdclk = 0; + + /* force full PLL disable + enable */ + dev_priv->cdclk.hw.vco = -1; +} + +/** + * cnl_init_cdclk - Initialize CDCLK on CNL + * @dev_priv: i915 device + * + * Initialize CDCLK for CNL. This is generally + * done only during the display core initialization sequence, + * after which the DMC will take care of turning CDCLK off/on + * as needed. + */ +void cnl_init_cdclk(struct drm_i915_private *dev_priv) +{ + struct intel_cdclk_state cdclk_state; + + cnl_sanitize_cdclk(dev_priv); + + if (dev_priv->cdclk.hw.cdclk != 0 && + dev_priv->cdclk.hw.vco != 0) + return; + + cdclk_state = dev_priv->cdclk.hw; + + cdclk_state.cdclk = cnl_calc_cdclk(0); + cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk); + + cnl_set_cdclk(dev_priv, &cdclk_state); +} + +/** + * cnl_uninit_cdclk - Uninitialize CDCLK on CNL + * @dev_priv: i915 device + * + * Uninitialize CDCLK for CNL. This is done only + * during the display core uninitialization sequence. + */ +void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) +{ + struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; + + cdclk_state.cdclk = cdclk_state.ref; + cdclk_state.vco = 0; + + cnl_set_cdclk(dev_priv, &cdclk_state); +} + /** * intel_cdclk_state_compare - Determine if two CDCLK states differ * @a: first CDCLK state @@ -1458,7 +1732,9 @@ static int bdw_adjust_min_pipe_pixel_rate(struct intel_crtc_state *crtc_state, crtc_state->has_audio && crtc_state->port_clock >= 540000 && crtc_state->lane_count == 4) { - if (IS_GEMINILAKE(dev_priv)) + if (IS_CANNONLAKE(dev_priv)) + pixel_rate = max(316800, pixel_rate); + else if (IS_GEMINILAKE(dev_priv)) pixel_rate = max(2 * 316800, pixel_rate); else pixel_rate = max(432000, pixel_rate); @@ -1504,7 +1780,7 @@ static int intel_max_pixel_rate(struct drm_atomic_state *state) pixel_rate = crtc_state->pixel_rate; - if (IS_BROADWELL(dev_priv) || IS_GEN9(dev_priv)) + if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) pixel_rate = bdw_adjust_min_pipe_pixel_rate(crtc_state, pixel_rate); @@ -1665,6 +1941,40 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) return 0; } +static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->dev); + struct intel_atomic_state *intel_state = + to_intel_atomic_state(state); + int max_pixclk = intel_max_pixel_rate(state); + int cdclk, vco; + + cdclk = cnl_calc_cdclk(max_pixclk); + vco = cnl_cdclk_pll_vco(dev_priv, cdclk); + + if (cdclk > dev_priv->max_cdclk_freq) { + DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n", + cdclk, dev_priv->max_cdclk_freq); + return -EINVAL; + } + + intel_state->cdclk.logical.vco = vco; + intel_state->cdclk.logical.cdclk = cdclk; + + if (!intel_state->active_crtcs) { + cdclk = cnl_calc_cdclk(0); + vco = cnl_cdclk_pll_vco(dev_priv, cdclk); + + intel_state->cdclk.actual.vco = vco; + intel_state->cdclk.actual.cdclk = cdclk; + } else { + intel_state->cdclk.actual = + intel_state->cdclk.logical; + } + + return 0; +} + static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv) { int max_cdclk_freq = dev_priv->max_cdclk_freq; @@ -1696,7 +2006,9 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv) */ void intel_update_max_cdclk(struct drm_i915_private *dev_priv) { - if (IS_GEN9_BC(dev_priv)) { + if (IS_CANNONLAKE(dev_priv)) { + dev_priv->max_cdclk_freq = 528000; + } else if (IS_GEN9_BC(dev_priv)) { u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; int max_cdclk, vco; @@ -1780,6 +2092,30 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv) DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000)); } +static int cnp_rawclk(struct drm_i915_private *dev_priv) +{ + u32 rawclk; + int divider, fraction; + + if (I915_READ(SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) { + /* 24 MHz */ + divider = 24000; + fraction = 0; + } else { + /* 19.2 MHz */ + divider = 19000; + fraction = 200; + } + + rawclk = CNP_RAWCLK_DIV((divider / 1000) - 1); + if (fraction) + rawclk |= CNP_RAWCLK_FRAC(DIV_ROUND_CLOSEST(1000, + fraction) - 1); + + I915_WRITE(PCH_RAWCLK_FREQ, rawclk); + return divider + fraction; +} + static int pch_rawclk(struct drm_i915_private *dev_priv) { return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000; @@ -1827,7 +2163,10 @@ static int g4x_hrawclk(struct drm_i915_private *dev_priv) */ void intel_update_rawclk(struct drm_i915_private *dev_priv) { - if (HAS_PCH_SPLIT(dev_priv)) + + if (HAS_PCH_CNP(dev_priv)) + dev_priv->rawclk_freq = cnp_rawclk(dev_priv); + else if (HAS_PCH_SPLIT(dev_priv)) dev_priv->rawclk_freq = pch_rawclk(dev_priv); else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) dev_priv->rawclk_freq = vlv_hrawclk(dev_priv); @@ -1866,9 +2205,15 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) dev_priv->display.set_cdclk = skl_set_cdclk; dev_priv->display.modeset_calc_cdclk = skl_modeset_calc_cdclk; + } else if (IS_CANNONLAKE(dev_priv)) { + dev_priv->display.set_cdclk = cnl_set_cdclk; + dev_priv->display.modeset_calc_cdclk = + cnl_modeset_calc_cdclk; } - if (IS_GEN9_BC(dev_priv)) + if (IS_CANNONLAKE(dev_priv)) + dev_priv->display.get_cdclk = cnl_get_cdclk; + else if (IS_GEN9_BC(dev_priv)) dev_priv->display.get_cdclk = skl_get_cdclk; else if (IS_GEN9_LP(dev_priv)) dev_priv->display.get_cdclk = bxt_get_cdclk; diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 1575bde..965988f 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -37,6 +37,9 @@ #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) +#define I915_CSR_CNL "i915/cnl_dmc_ver1_04.bin" +#define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) + #define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin" MODULE_FIRMWARE(I915_CSR_KBL); #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 1) @@ -238,7 +241,7 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv) u32 *payload = dev_priv->csr.dmc_payload; uint32_t i, fw_size; - if (!IS_GEN9(dev_priv)) { + if (!HAS_CSR(dev_priv)) { DRM_ERROR("No CSR support available for this platform\n"); return; } @@ -289,9 +292,11 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, csr->version = css_header->version; - if (IS_GEMINILAKE(dev_priv)) { + if (IS_CANNONLAKE(dev_priv)) { + required_version = CNL_CSR_VERSION_REQUIRED; + } else if (IS_GEMINILAKE(dev_priv)) { required_version = GLK_CSR_VERSION_REQUIRED; - } else if (IS_KABYLAKE(dev_priv)) { + } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { required_version = KBL_CSR_VERSION_REQUIRED; } else if (IS_SKYLAKE(dev_priv)) { required_version = SKL_CSR_VERSION_REQUIRED; @@ -438,9 +443,11 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) if (!HAS_CSR(dev_priv)) return; - if (IS_GEMINILAKE(dev_priv)) + if (IS_CANNONLAKE(dev_priv)) + csr->fw_path = I915_CSR_CNL; + else if (IS_GEMINILAKE(dev_priv)) csr->fw_path = I915_CSR_GLK; - else if (IS_KABYLAKE(dev_priv)) + else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) csr->fw_path = I915_CSR_KBL; else if (IS_SKYLAKE(dev_priv)) csr->fw_path = I915_CSR_SKL; diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 0914ad9..db80938 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -353,6 +353,146 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = { { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */ }; +struct cnl_ddi_buf_trans { + u32 dw2_swing_sel; + u32 dw7_n_scalar; + u32 dw4_cursor_coeff; + u32 dw4_post_cursor_2; + u32 dw4_post_cursor_1; +}; + +/* Voltage Swing Programming for VccIO 0.85V for DP */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_0_85V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x5D, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */ + { 0xA, 0x6A, 0x38, 0x00, 0x07 }, /* 350 500 3.1 */ + { 0xB, 0x7A, 0x32, 0x00, 0x0D }, /* 350 700 6.0 */ + { 0x6, 0x7C, 0x2D, 0x00, 0x12 }, /* 350 900 8.2 */ + { 0xA, 0x69, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */ + { 0xB, 0x7A, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */ + { 0x6, 0x7C, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */ + { 0xB, 0x7D, 0x3C, 0x00, 0x03 }, /* 650 725 0.9 */ + { 0x6, 0x7C, 0x34, 0x00, 0x0B }, /* 600 900 3.5 */ + { 0x6, 0x7B, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */ +}; + +/* Voltage Swing Programming for VccIO 0.85V for HDMI */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_0_85V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x60, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */ + { 0xB, 0x73, 0x36, 0x00, 0x09 }, /* 450 650 3.2 */ + { 0x6, 0x7F, 0x31, 0x00, 0x0E }, /* 450 850 5.5 */ + { 0xB, 0x73, 0x3F, 0x00, 0x00 }, /* 650 650 0.0 */ + { 0x6, 0x7F, 0x37, 0x00, 0x08 }, /* 650 850 2.3 */ + { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 850 850 0.0 */ + { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */ +}; + +/* Voltage Swing Programming for VccIO 0.85V for eDP */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_0_85V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x66, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */ + { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */ + { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */ + { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */ + { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */ + { 0xA, 0x66, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */ + { 0xB, 0x70, 0x3C, 0x00, 0x03 }, /* 460 600 2.3 */ + { 0xC, 0x75, 0x3C, 0x00, 0x03 }, /* 537 700 2.3 */ + { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ +}; + +/* Voltage Swing Programming for VccIO 0.95V for DP */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_0_95V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x5D, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */ + { 0xA, 0x6A, 0x38, 0x00, 0x07 }, /* 350 500 3.1 */ + { 0xB, 0x7A, 0x32, 0x00, 0x0D }, /* 350 700 6.0 */ + { 0x6, 0x7C, 0x2D, 0x00, 0x12 }, /* 350 900 8.2 */ + { 0xA, 0x69, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */ + { 0xB, 0x7A, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */ + { 0x6, 0x7C, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */ + { 0xB, 0x7D, 0x3C, 0x00, 0x03 }, /* 650 725 0.9 */ + { 0x6, 0x7C, 0x34, 0x00, 0x0B }, /* 600 900 3.5 */ + { 0x6, 0x7B, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */ +}; + +/* Voltage Swing Programming for VccIO 0.95V for HDMI */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_0_95V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x5C, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ + { 0xB, 0x69, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */ + { 0x5, 0x76, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */ + { 0xA, 0x5E, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */ + { 0xB, 0x69, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */ + { 0xB, 0x79, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */ + { 0x6, 0x7D, 0x32, 0x00, 0x0D }, /* 600 1000 4.4 */ + { 0x5, 0x76, 0x3F, 0x00, 0x00 }, /* 800 800 0.0 */ + { 0x6, 0x7D, 0x39, 0x00, 0x06 }, /* 800 1000 1.9 */ + { 0x6, 0x7F, 0x39, 0x00, 0x06 }, /* 850 1050 1.8 */ + { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */ +}; + +/* Voltage Swing Programming for VccIO 0.95V for eDP */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_0_95V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x61, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */ + { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */ + { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */ + { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */ + { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */ + { 0xA, 0x61, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */ + { 0xB, 0x68, 0x39, 0x00, 0x06 }, /* 460 600 2.3 */ + { 0xC, 0x6E, 0x39, 0x00, 0x06 }, /* 537 700 2.3 */ + { 0x4, 0x7F, 0x3A, 0x00, 0x05 }, /* 460 600 2.3 */ + { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ +}; + +/* Voltage Swing Programming for VccIO 1.05V for DP */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_1_05V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x58, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ + { 0xB, 0x64, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */ + { 0x5, 0x70, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */ + { 0x6, 0x7F, 0x2C, 0x00, 0x13 }, /* 400 1050 8.4 */ + { 0xB, 0x64, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */ + { 0x5, 0x73, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */ + { 0x6, 0x7F, 0x30, 0x00, 0x0F }, /* 550 1050 5.6 */ + { 0x5, 0x76, 0x3E, 0x00, 0x01 }, /* 850 900 0.5 */ + { 0x6, 0x7F, 0x36, 0x00, 0x09 }, /* 750 1050 2.9 */ + { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */ +}; + +/* Voltage Swing Programming for VccIO 1.05V for HDMI */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_1_05V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x58, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ + { 0xB, 0x64, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */ + { 0x5, 0x70, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */ + { 0xA, 0x5B, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */ + { 0xB, 0x64, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */ + { 0x5, 0x73, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */ + { 0x6, 0x7C, 0x32, 0x00, 0x0D }, /* 600 1000 4.4 */ + { 0x5, 0x70, 0x3F, 0x00, 0x00 }, /* 800 800 0.0 */ + { 0x6, 0x7C, 0x39, 0x00, 0x06 }, /* 800 1000 1.9 */ + { 0x6, 0x7F, 0x39, 0x00, 0x06 }, /* 850 1050 1.8 */ + { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */ +}; + +/* Voltage Swing Programming for VccIO 1.05V for eDP */ +static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_1_05V[] = { + /* NT mV Trans mV db */ + { 0xA, 0x5E, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */ + { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */ + { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */ + { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */ + { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */ + { 0xA, 0x5E, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */ + { 0xB, 0x64, 0x39, 0x00, 0x06 }, /* 460 600 2.3 */ + { 0xE, 0x6A, 0x39, 0x00, 0x06 }, /* 537 700 2.3 */ + { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ +}; + enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) { switch (encoder->type) { @@ -404,7 +544,7 @@ kbl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries) if (IS_KBL_ULX(dev_priv)) { *n_entries = ARRAY_SIZE(kbl_y_ddi_translations_dp); return kbl_y_ddi_translations_dp; - } else if (IS_KBL_ULT(dev_priv)) { + } else if (IS_KBL_ULT(dev_priv) || IS_CFL_ULT(dev_priv)) { *n_entries = ARRAY_SIZE(kbl_u_ddi_translations_dp); return kbl_u_ddi_translations_dp; } else { @@ -420,7 +560,8 @@ skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) { *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp); return skl_y_ddi_translations_edp; - } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) { + } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv) || + IS_CFL_ULT(dev_priv)) { *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp); return skl_u_ddi_translations_edp; } else { @@ -429,7 +570,7 @@ skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) } } - if (IS_KABYLAKE(dev_priv)) + if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) return kbl_get_buf_trans_dp(dev_priv, n_entries); else return skl_get_buf_trans_dp(dev_priv, n_entries); @@ -485,7 +626,7 @@ static const struct ddi_buf_trans * intel_ddi_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries) { - if (IS_KABYLAKE(dev_priv)) { + if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { return kbl_get_buf_trans_dp(dev_priv, n_entries); } else if (IS_SKYLAKE(dev_priv)) { return skl_get_buf_trans_dp(dev_priv, n_entries); @@ -505,7 +646,7 @@ static const struct ddi_buf_trans * intel_ddi_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) { - if (IS_KABYLAKE(dev_priv) || IS_SKYLAKE(dev_priv)) { + if (IS_GEN9_BC(dev_priv)) { return skl_get_buf_trans_edp(dev_priv, n_entries); } else if (IS_BROADWELL(dev_priv)) { return bdw_get_buf_trans_edp(dev_priv, n_entries); @@ -1478,7 +1619,7 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, u32 level) if (dp_iboost) { iboost = dp_iboost; } else { - if (IS_KABYLAKE(dev_priv)) + if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) ddi_translations = kbl_get_buf_trans_dp(dev_priv, &n_entries); else @@ -1580,6 +1721,200 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder) DP_TRAIN_VOLTAGE_SWING_MASK; } +static const struct cnl_ddi_buf_trans * +cnl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, + u32 voltage, int *n_entries) +{ + if (voltage == VOLTAGE_INFO_0_85V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_0_85V); + return cnl_ddi_translations_hdmi_0_85V; + } else if (voltage == VOLTAGE_INFO_0_95V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_0_95V); + return cnl_ddi_translations_hdmi_0_95V; + } else if (voltage == VOLTAGE_INFO_1_05V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_1_05V); + return cnl_ddi_translations_hdmi_1_05V; + } + return NULL; +} + +static const struct cnl_ddi_buf_trans * +cnl_get_buf_trans_dp(struct drm_i915_private *dev_priv, + u32 voltage, int *n_entries) +{ + if (voltage == VOLTAGE_INFO_0_85V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_0_85V); + return cnl_ddi_translations_dp_0_85V; + } else if (voltage == VOLTAGE_INFO_0_95V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_0_95V); + return cnl_ddi_translations_dp_0_95V; + } else if (voltage == VOLTAGE_INFO_1_05V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_1_05V); + return cnl_ddi_translations_dp_1_05V; + } + return NULL; +} + +static const struct cnl_ddi_buf_trans * +cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, + u32 voltage, int *n_entries) +{ + if (dev_priv->vbt.edp.low_vswing) { + if (voltage == VOLTAGE_INFO_0_85V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_85V); + return cnl_ddi_translations_dp_0_85V; + } else if (voltage == VOLTAGE_INFO_0_95V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_95V); + return cnl_ddi_translations_edp_0_95V; + } else if (voltage == VOLTAGE_INFO_1_05V) { + *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_1_05V); + return cnl_ddi_translations_edp_1_05V; + } + return NULL; + } else { + return cnl_get_buf_trans_dp(dev_priv, voltage, n_entries); + } +} + +static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv, + u32 level, enum port port, int type) +{ + const struct cnl_ddi_buf_trans *ddi_translations = NULL; + u32 n_entries, val, voltage; + int ln; + + /* + * Values for each port type are listed in + * voltage swing programming tables. + * Vccio voltage found in PORT_COMP_DW3. + */ + voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK; + + if (type == INTEL_OUTPUT_HDMI) { + ddi_translations = cnl_get_buf_trans_hdmi(dev_priv, + voltage, &n_entries); + } else if (type == INTEL_OUTPUT_DP) { + ddi_translations = cnl_get_buf_trans_dp(dev_priv, + voltage, &n_entries); + } else if (type == INTEL_OUTPUT_EDP) { + ddi_translations = cnl_get_buf_trans_edp(dev_priv, + voltage, &n_entries); + } + + if (ddi_translations == NULL) { + MISSING_CASE(voltage); + return; + } + + if (level >= n_entries) { + DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1); + level = n_entries - 1; + } + + /* Set PORT_TX_DW5 Scaling Mode Sel to 010b. */ + val = I915_READ(CNL_PORT_TX_DW5_LN0(port)); + val |= SCALING_MODE_SEL(2); + I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val); + + /* Program PORT_TX_DW2 */ + val = I915_READ(CNL_PORT_TX_DW2_LN0(port)); + val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_sel); + val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_sel); + /* Rcomp scalar is fixed as 0x98 for every table entry */ + val |= RCOMP_SCALAR(0x98); + I915_WRITE(CNL_PORT_TX_DW2_GRP(port), val); + + /* Program PORT_TX_DW4 */ + /* We cannot write to GRP. It would overrite individual loadgen */ + for (ln = 0; ln < 4; ln++) { + val = I915_READ(CNL_PORT_TX_DW4_LN(port, ln)); + val |= POST_CURSOR_1(ddi_translations[level].dw4_post_cursor_1); + val |= POST_CURSOR_2(ddi_translations[level].dw4_post_cursor_2); + val |= CURSOR_COEFF(ddi_translations[level].dw4_cursor_coeff); + I915_WRITE(CNL_PORT_TX_DW4_LN(port, ln), val); + } + + /* Program PORT_TX_DW5 */ + /* All DW5 values are fixed for every table entry */ + val = I915_READ(CNL_PORT_TX_DW5_LN0(port)); + val |= RTERM_SELECT(6); + val |= TAP3_DISABLE; + I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val); + + /* Program PORT_TX_DW7 */ + val = I915_READ(CNL_PORT_TX_DW7_LN0(port)); + val |= N_SCALAR(ddi_translations[level].dw7_n_scalar); + I915_WRITE(CNL_PORT_TX_DW7_GRP(port), val); +} + +static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + enum port port = intel_ddi_get_encoder_port(encoder); + int type = encoder->type; + int width = 0; + int rate = 0; + u32 val; + int ln = 0; + + if ((intel_dp) && (type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP)) { + width = intel_dp->lane_count; + rate = intel_dp->link_rate; + } else { + width = 4; + /* Rate is always < than 6GHz for HDMI */ + } + + /* + * 1. If port type is eDP or DP, + * set PORT_PCS_DW1 cmnkeeper_enable to 1b, + * else clear to 0b. + */ + val = I915_READ(CNL_PORT_PCS_DW1_LN0(port)); + if (type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP) + val |= COMMON_KEEPER_EN; + else + val &= ~COMMON_KEEPER_EN; + I915_WRITE(CNL_PORT_PCS_DW1_GRP(port), val); + + /* 2. Program loadgen select */ + /* + * Program PORT_TX_DW4_LN depending on Bit rate and used lanes + * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1) + * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0) + * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0) + */ + for (ln = 0; ln <= 3; ln++) { + val = I915_READ(CNL_PORT_TX_DW4_LN(port, ln)); + val &= ~LOADGEN_SELECT; + + if (((rate < 600000) && (width == 4) && (ln >= 1)) || + ((rate < 600000) && (width < 4) && ((ln == 1) || (ln == 2)))) { + val |= LOADGEN_SELECT; + } + I915_WRITE(CNL_PORT_TX_DW4_LN(port, ln), val); + } + + /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */ + val = I915_READ(CNL_PORT_CL1CM_DW5); + val |= SUS_CLOCK_CONFIG; + I915_WRITE(CNL_PORT_CL1CM_DW5, val); + + /* 4. Clear training enable to change swing values */ + val = I915_READ(CNL_PORT_TX_DW5_LN0(port)); + val &= ~TX_TRAINING_EN; + I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val); + + /* 5. Program swing and de-emphasis */ + cnl_ddi_vswing_program(dev_priv, level, port, type); + + /* 6. Set training enable to trigger update */ + val = I915_READ(CNL_PORT_TX_DW5_LN0(port)); + val |= TX_TRAINING_EN; + I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val); +} + static uint32_t translate_signal_level(int signal_levels) { int i; @@ -1612,7 +1947,11 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) skl_ddi_set_iboost(encoder, level); else if (IS_GEN9_LP(dev_priv)) bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type); - + else if (IS_CANNONLAKE(dev_priv)) { + cnl_ddi_vswing_sequence(encoder, level); + /* DDI_BUF_CTL bits 27:24 are reserved on CNL */ + return 0; + } return DDI_BUF_TRANS_SELECT(level); } @@ -1621,13 +1960,27 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = intel_ddi_get_encoder_port(encoder); + uint32_t val; if (WARN_ON(!pll)) return; - if (IS_GEN9_BC(dev_priv)) { - uint32_t val; + if (IS_CANNONLAKE(dev_priv)) { + /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */ + val = I915_READ(DPCLKA_CFGCR0); + val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->id, port); + I915_WRITE(DPCLKA_CFGCR0, val); + /* + * Configure DPCLKA_CFGCR0 to turn on the clock for the DDI. + * This step and the step before must be done with separate + * register writes. + */ + val = I915_READ(DPCLKA_CFGCR0); + val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) | + DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port)); + I915_WRITE(DPCLKA_CFGCR0, val); + } else if (IS_GEN9_BC(dev_priv)) { /* DDI -> PLL mapping */ val = I915_READ(DPLL_CTRL2); @@ -1696,6 +2049,8 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, else if (IS_GEN9_LP(dev_priv)) bxt_ddi_vswing_sequence(dev_priv, level, port, INTEL_OUTPUT_HDMI); + else if (IS_CANNONLAKE(dev_priv)) + cnl_ddi_vswing_sequence(encoder, level); intel_hdmi->set_infoframes(drm_encoder, has_hdmi_sink, @@ -1732,12 +2087,18 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, struct drm_i915_private *dev_priv = to_i915(encoder->dev); enum port port = intel_ddi_get_encoder_port(intel_encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + struct intel_dp *intel_dp = NULL; int type = intel_encoder->type; uint32_t val; bool wait = false; /* old_crtc_state and old_conn_state are NULL when called from DP_MST */ + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { + intel_dp = enc_to_intel_dp(encoder); + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); + } + val = I915_READ(DDI_BUF_CTL(port)); if (val & DDI_BUF_CTL_ENABLE) { val &= ~DDI_BUF_CTL_ENABLE; @@ -1753,9 +2114,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, if (wait) intel_wait_ddi_buf_idle(dev_priv, port); - if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); + if (intel_dp) { intel_edp_panel_vdd_on(intel_dp); intel_edp_panel_off(intel_dp); } @@ -1763,7 +2122,10 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, if (dig_port) intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); - if (IS_GEN9_BC(dev_priv)) + if (IS_CANNONLAKE(dev_priv)) + I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) | + DPCLKA_CFGCR0_DDI_CLK_OFF(port)); + else if (IS_GEN9_BC(dev_priv)) I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) | DPLL_CTRL2_DDI_CLK_OFF(port))); else if (INTEL_GEN(dev_priv) < 9) @@ -1841,7 +2203,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder, if (port == PORT_A && INTEL_GEN(dev_priv) < 9) intel_dp_stop_link_train(intel_dp); - intel_edp_backlight_on(intel_dp); + intel_edp_backlight_on(pipe_config, conn_state); intel_psr_enable(intel_dp); intel_edp_drrs_enable(intel_dp, pipe_config); } @@ -1871,7 +2233,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder, intel_edp_drrs_disable(intel_dp, old_crtc_state); intel_psr_disable(intel_dp); - intel_edp_backlight_off(intel_dp); + intel_edp_backlight_off(old_conn_state); } } diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 3718341..77d3214 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -51,6 +51,8 @@ static const char * const platform_names[] = { PLATFORM_NAME(BROXTON), PLATFORM_NAME(KABYLAKE), PLATFORM_NAME(GEMINILAKE), + PLATFORM_NAME(COFFEELAKE), + PLATFORM_NAME(CANNONLAKE), }; #undef PLATFORM_NAME @@ -183,16 +185,15 @@ static void gen9_sseu_info_init(struct drm_i915_private *dev_priv) DIV_ROUND_UP(sseu->eu_total, sseu_subslice_total(sseu)) : 0; /* - * SKL supports slice power gating on devices with more than + * SKL+ supports slice power gating on devices with more than * one slice, and supports EU power gating on devices with - * more than one EU pair per subslice. BXT supports subslice + * more than one EU pair per subslice. BXT+ supports subslice * power gating on devices with more than one subslice, and * supports EU power gating on devices with more than one EU * pair per subslice. */ sseu->has_slice_pg = - (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && - hweight8(sseu->slice_mask) > 1; + !IS_GEN9_LP(dev_priv) && hweight8(sseu->slice_mask) > 1; sseu->has_subslice_pg = IS_GEN9_LP(dev_priv) && sseu_subslice_total(sseu) > 1; sseu->has_eu_pg = sseu->eu_per_subslice > 2; @@ -327,7 +328,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) * we don't expose the topmost plane at all to prevent ABI breakage * down the line. */ - if (IS_GEMINILAKE(dev_priv)) + if (IS_GEN10(dev_priv) || IS_GEMINILAKE(dev_priv)) for_each_pipe(dev_priv, pipe) info->num_sprites[pipe] = 3; else if (IS_BROXTON(dev_priv)) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ce34fb7..dec9e58 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -120,7 +120,8 @@ static void intel_crtc_init_scalers(struct intel_crtc *crtc, static void skylake_pfit_enable(struct intel_crtc *crtc); static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force); static void ironlake_pfit_enable(struct intel_crtc *crtc); -static void intel_modeset_setup_hw_state(struct drm_device *dev); +static void intel_modeset_setup_hw_state(struct drm_device *dev, + struct drm_modeset_acquire_ctx *ctx); static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc); struct intel_limit { @@ -1192,9 +1193,8 @@ void assert_pipe(struct drm_i915_private *dev_priv, pipe); enum intel_display_power_domain power_domain; - /* if we need the pipe quirk it must be always on */ - if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || - (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) + /* we keep both pipes enabled on 830 */ + if (IS_I830(dev_priv)) state = true; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); @@ -1549,6 +1549,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); i915_reg_t reg = DPLL(crtc->pipe); u32 dpll = crtc->config->dpll_hw_state.dpll; + int i; assert_pipe_disabled(dev_priv, crtc->pipe); @@ -1595,15 +1596,11 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) } /* We do this three times for luck */ - I915_WRITE(reg, dpll); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ - I915_WRITE(reg, dpll); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ - I915_WRITE(reg, dpll); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ + for (i = 0; i < 3; i++) { + I915_WRITE(reg, dpll); + POSTING_READ(reg); + udelay(150); /* wait for warmup */ + } } /** @@ -1631,8 +1628,7 @@ static void i9xx_disable_pll(struct intel_crtc *crtc) } /* Don't disable pipe or pipe PLLs if needed */ - if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || - (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) + if (IS_I830(dev_priv)) return; /* Make sure the pipe isn't still relying on us */ @@ -1915,8 +1911,8 @@ static void intel_enable_pipe(struct intel_crtc *crtc) reg = PIPECONF(cpu_transcoder); val = I915_READ(reg); if (val & PIPECONF_ENABLE) { - WARN_ON(!((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || - (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))); + /* we keep both pipes enabled on 830 */ + WARN_ON(!IS_I830(dev_priv)); return; } @@ -1976,8 +1972,7 @@ static void intel_disable_pipe(struct intel_crtc *crtc) val &= ~PIPECONF_DOUBLE_WIDE; /* Don't disable pipe or pipe PLLs if needed */ - if (!(pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) && - !(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) + if (!IS_I830(dev_priv)) val &= ~PIPECONF_ENABLE; I915_WRITE(reg, val); @@ -3461,7 +3456,7 @@ __intel_display_resume(struct drm_device *dev, struct drm_crtc *crtc; int i, ret; - intel_modeset_setup_hw_state(dev); + intel_modeset_setup_hw_state(dev, ctx); i915_redisable_vga(to_i915(dev)); if (!state) @@ -5838,9 +5833,14 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state, if (!dev_priv->display.initial_watermarks) intel_update_watermarks(intel_crtc); + + /* clock the pipe down to 640x480@60 to potentially save power */ + if (IS_I830(dev_priv)) + i830_enable_pipe(dev_priv, pipe); } -static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) +static void intel_crtc_disable_noatomic(struct drm_crtc *crtc, + struct drm_modeset_acquire_ctx *ctx) { struct intel_encoder *encoder; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -5870,7 +5870,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) return; } - state->acquire_ctx = crtc->dev->mode_config.acquire_ctx; + state->acquire_ctx = ctx; /* Everything's already locked, -EDEADLK can't happen. */ crtc_state = intel_atomic_get_crtc_state(state, intel_crtc); @@ -5976,11 +5976,21 @@ static void intel_connector_verify_state(struct drm_crtc_state *crtc_state, int intel_connector_init(struct intel_connector *connector) { - drm_atomic_helper_connector_reset(&connector->base); + struct intel_digital_connector_state *conn_state; - if (!connector->base.state) + /* + * Allocate enough memory to hold intel_digital_connector_state, + * This might be a few bytes too many, but for connectors that don't + * need it we'll free the state and allocate a smaller one on the first + * succesful commit anyway. + */ + conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL); + if (!conn_state) return -ENOMEM; + __drm_atomic_helper_connector_reset(&connector->base, + &conn_state->base); + return 0; } @@ -7038,8 +7048,8 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) pipeconf = 0; - if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || - (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) + /* we keep both pipes enabled on 830 */ + if (IS_I830(dev_priv)) pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE; if (intel_crtc->config->double_wide) @@ -8864,6 +8874,22 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc, return 0; } +static void cannonlake_get_ddi_pll(struct drm_i915_private *dev_priv, + enum port port, + struct intel_crtc_state *pipe_config) +{ + enum intel_dpll_id id; + u32 temp; + + temp = I915_READ(DPCLKA_CFGCR0) & DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); + id = temp >> (port * 2); + + if (WARN_ON(id < SKL_DPLL0 || id > SKL_DPLL2)) + return; + + pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); +} + static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_state *pipe_config) @@ -9051,7 +9077,9 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT; - if (IS_GEN9_BC(dev_priv)) + if (IS_CANNONLAKE(dev_priv)) + cannonlake_get_ddi_pll(dev_priv, port, pipe_config); + else if (IS_GEN9_BC(dev_priv)) skylake_get_ddi_pll(dev_priv, port, pipe_config); else if (IS_GEN9_LP(dev_priv)) bxt_get_ddi_pll(dev_priv, port, pipe_config); @@ -11185,6 +11213,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, ret = skl_update_scaler_crtc(pipe_config); if (!ret) + ret = skl_check_pipe_max_pixel_rate(intel_crtc, + pipe_config); + if (!ret) ret = intel_atomic_setup_scalers(dev_priv, intel_crtc, pipe_config); } @@ -12206,9 +12237,8 @@ verify_crtc_state(struct drm_crtc *crtc, active = dev_priv->display.get_pipe_config(intel_crtc, pipe_config); - /* hw state is inconsistent with the pipe quirk */ - if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || - (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) + /* we keep both pipes enabled on 830 */ + if (IS_I830(dev_priv)) active = new_crtc_state->active; I915_STATE_WARN(new_crtc_state->active != active, @@ -13117,8 +13147,16 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_helper_commit_hw_done(state); - if (intel_state->modeset) + if (intel_state->modeset) { + /* As one of the primary mmio accessors, KMS has a high + * likelihood of triggering bugs in unclaimed access. After we + * finish modesetting, see if an error has been flagged, and if + * so enable debugging for the next modeset - and hope we catch + * the culprit. + */ + intel_uncore_arm_unclaimed_mmio_detection(dev_priv); intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); + } mutex_lock(&dev->struct_mutex); drm_atomic_helper_cleanup_planes(dev, state); @@ -13128,19 +13166,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_state_put(state); - /* As one of the primary mmio accessors, KMS has a high likelihood - * of triggering bugs in unclaimed access. After we finish - * modesetting, see if an error has been flagged, and if so - * enable debugging for the next modeset - and hope we catch - * the culprit. - * - * XXX note that we assume display power is on at this point. - * This might hold true now but we need to add pm helper to check - * unclaimed only when the hardware is on, as atomic commits - * can happen also when the device is completely off. - */ - intel_uncore_arm_unclaimed_mmio_detection(dev_priv); - intel_atomic_helper_free_state(dev_priv); } @@ -13272,43 +13297,6 @@ static int intel_atomic_commit(struct drm_device *dev, return 0; } -void intel_crtc_restore_mode(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_atomic_state *state; - struct drm_crtc_state *crtc_state; - int ret; - - state = drm_atomic_state_alloc(dev); - if (!state) { - DRM_DEBUG_KMS("[CRTC:%d:%s] crtc restore failed, out of memory", - crtc->base.id, crtc->name); - return; - } - - state->acquire_ctx = crtc->dev->mode_config.acquire_ctx; - -retry: - crtc_state = drm_atomic_get_crtc_state(state, crtc); - ret = PTR_ERR_OR_ZERO(crtc_state); - if (!ret) { - if (!crtc_state->active) - goto out; - - crtc_state->mode_changed = true; - ret = drm_atomic_commit(state); - } - - if (ret == -EDEADLK) { - drm_atomic_state_clear(state); - drm_modeset_backoff(state->acquire_ctx); - goto retry; - } - -out: - drm_atomic_state_put(state); -} - static const struct drm_crtc_funcs intel_crtc_funcs = { .gamma_set = drm_atomic_helper_legacy_gamma_set, .set_config = drm_atomic_helper_set_config, @@ -14749,27 +14737,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) } /* - * Some BIOSes insist on assuming the GPU's pipe A is enabled at suspend, - * resume, or other times. This quirk makes sure that's the case for - * affected systems. - */ -static void quirk_pipea_force(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - dev_priv->quirks |= QUIRK_PIPEA_FORCE; - DRM_INFO("applying pipe a force quirk\n"); -} - -static void quirk_pipeb_force(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - dev_priv->quirks |= QUIRK_PIPEB_FORCE; - DRM_INFO("applying pipe b force quirk\n"); -} - -/* * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason */ static void quirk_ssc_force_disable(struct drm_device *dev) @@ -14834,18 +14801,6 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = { }; static struct intel_quirk intel_quirks[] = { - /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ - { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, - - /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ - { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, - - /* 830 needs to leave pipe A & dpll A up */ - { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, - - /* 830 needs to leave pipe B & dpll B up */ - { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipeb_force }, - /* Lenovo U160 cannot use SSC on LVDS */ { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, @@ -15129,7 +15084,7 @@ int intel_modeset_init(struct drm_device *dev) intel_setup_outputs(dev_priv); drm_modeset_lock_all(dev); - intel_modeset_setup_hw_state(dev); + intel_modeset_setup_hw_state(dev, dev->mode_config.acquire_ctx); drm_modeset_unlock_all(dev); for_each_intel_crtc(dev, crtc) { @@ -15166,35 +15121,89 @@ int intel_modeset_init(struct drm_device *dev) return 0; } -static void intel_enable_pipe_a(struct drm_device *dev) +void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct intel_connector *connector; - struct drm_connector_list_iter conn_iter; - struct drm_connector *crt = NULL; - struct intel_load_detect_pipe load_detect_temp; - struct drm_modeset_acquire_ctx *ctx = dev->mode_config.acquire_ctx; - int ret; + /* 640x480@60Hz, ~25175 kHz */ + struct dpll clock = { + .m1 = 18, + .m2 = 7, + .p1 = 13, + .p2 = 4, + .n = 2, + }; + u32 dpll, fp; + int i; - /* We can't just switch on the pipe A, we need to set things up with a - * proper mode and output configuration. As a gross hack, enable pipe A - * by enabling the load detect pipe once. */ - drm_connector_list_iter_begin(dev, &conn_iter); - for_each_intel_connector_iter(connector, &conn_iter) { - if (connector->encoder->type == INTEL_OUTPUT_ANALOG) { - crt = &connector->base; - break; - } + WARN_ON(i9xx_calc_dpll_params(48000, &clock) != 25154); + + DRM_DEBUG_KMS("enabling pipe %c due to force quirk (vco=%d dot=%d)\n", + pipe_name(pipe), clock.vco, clock.dot); + + fp = i9xx_dpll_compute_fp(&clock); + dpll = (I915_READ(DPLL(pipe)) & DPLL_DVO_2X_MODE) | + DPLL_VGA_MODE_DIS | + ((clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT) | + PLL_P2_DIVIDE_BY_4 | + PLL_REF_INPUT_DREFCLK | + DPLL_VCO_ENABLE; + + I915_WRITE(FP0(pipe), fp); + I915_WRITE(FP1(pipe), fp); + + I915_WRITE(HTOTAL(pipe), (640 - 1) | ((800 - 1) << 16)); + I915_WRITE(HBLANK(pipe), (640 - 1) | ((800 - 1) << 16)); + I915_WRITE(HSYNC(pipe), (656 - 1) | ((752 - 1) << 16)); + I915_WRITE(VTOTAL(pipe), (480 - 1) | ((525 - 1) << 16)); + I915_WRITE(VBLANK(pipe), (480 - 1) | ((525 - 1) << 16)); + I915_WRITE(VSYNC(pipe), (490 - 1) | ((492 - 1) << 16)); + I915_WRITE(PIPESRC(pipe), ((640 - 1) << 16) | (480 - 1)); + + /* + * Apparently we need to have VGA mode enabled prior to changing + * the P1/P2 dividers. Otherwise the DPLL will keep using the old + * dividers, even though the register value does change. + */ + I915_WRITE(DPLL(pipe), dpll & ~DPLL_VGA_MODE_DIS); + I915_WRITE(DPLL(pipe), dpll); + + /* Wait for the clocks to stabilize. */ + POSTING_READ(DPLL(pipe)); + udelay(150); + + /* The pixel multiplier can only be updated once the + * DPLL is enabled and the clocks are stable. + * + * So write it again. + */ + I915_WRITE(DPLL(pipe), dpll); + + /* We do this three times for luck */ + for (i = 0; i < 3 ; i++) { + I915_WRITE(DPLL(pipe), dpll); + POSTING_READ(DPLL(pipe)); + udelay(150); /* wait for warmup */ } - drm_connector_list_iter_end(&conn_iter); - if (!crt) - return; + I915_WRITE(PIPECONF(pipe), PIPECONF_ENABLE | PIPECONF_PROGRESSIVE); + POSTING_READ(PIPECONF(pipe)); +} + +void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) +{ + DRM_DEBUG_KMS("disabling pipe %c due to force quirk\n", + pipe_name(pipe)); - ret = intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, ctx); - WARN(ret < 0, "All modeset mutexes are locked, but intel_get_load_detect_pipe failed\n"); + assert_plane_disabled(dev_priv, PLANE_A); + assert_plane_disabled(dev_priv, PLANE_B); - if (ret > 0) - intel_release_load_detect_pipe(crt, &load_detect_temp, ctx); + I915_WRITE(PIPECONF(pipe), 0); + POSTING_READ(PIPECONF(pipe)); + + if (wait_for(pipe_dsl_stopped(dev_priv, pipe), 100)) + DRM_ERROR("pipe %c off wait timed out\n", pipe_name(pipe)); + + I915_WRITE(DPLL(pipe), DPLL_VGA_MODE_DIS); + POSTING_READ(DPLL(pipe)); } static bool @@ -15244,7 +15253,8 @@ static bool has_pch_trancoder(struct drm_i915_private *dev_priv, (HAS_PCH_LPT_H(dev_priv) && pch_transcoder == TRANSCODER_A); } -static void intel_sanitize_crtc(struct intel_crtc *crtc) +static void intel_sanitize_crtc(struct intel_crtc *crtc, + struct drm_modeset_acquire_ctx *ctx) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); @@ -15290,23 +15300,14 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) plane = crtc->plane; crtc->base.primary->state->visible = true; crtc->plane = !plane; - intel_crtc_disable_noatomic(&crtc->base); + intel_crtc_disable_noatomic(&crtc->base, ctx); crtc->plane = plane; } - if (dev_priv->quirks & QUIRK_PIPEA_FORCE && - crtc->pipe == PIPE_A && !crtc->active) { - /* BIOS forgot to enable pipe A, this mostly happens after - * resume. Force-enable the pipe to fix this, the update_dpms - * call below we restore the pipe to the right state, but leave - * the required bits on. */ - intel_enable_pipe_a(dev); - } - /* Adjust the state of the output pipe according to whether we * have active connectors/encoders. */ if (crtc->active && !intel_crtc_has_encoders(crtc)) - intel_crtc_disable_noatomic(&crtc->base); + intel_crtc_disable_noatomic(&crtc->base, ctx); if (crtc->active || HAS_GMCH_DISPLAY(dev_priv)) { /* @@ -15603,7 +15604,8 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) * and sanitizes it to the current state */ static void -intel_modeset_setup_hw_state(struct drm_device *dev) +intel_modeset_setup_hw_state(struct drm_device *dev, + struct drm_modeset_acquire_ctx *ctx) { struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; @@ -15623,7 +15625,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev) for_each_pipe(dev_priv, pipe) { crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - intel_sanitize_crtc(crtc); + intel_sanitize_crtc(crtc, ctx); intel_dump_pipe_config(crtc, crtc->config, "[setup_hw_state]"); } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index de4b1f2..64fa774 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -798,7 +798,7 @@ static void intel_pps_get_registers(struct drm_i915_private *dev_priv, regs->pp_stat = PP_STATUS(pps_idx); regs->pp_on = PP_ON_DELAYS(pps_idx); regs->pp_off = PP_OFF_DELAYS(pps_idx); - if (!IS_GEN9_LP(dev_priv)) + if (!IS_GEN9_LP(dev_priv) && !HAS_PCH_CNP(dev_priv)) regs->pp_div = PP_DIVISOR(pps_idx); } @@ -1548,17 +1548,6 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp) DRM_DEBUG_KMS("common rates: %s\n", str); } -static int rate_to_index(int find, const int *rates) -{ - int i = 0; - - for (i = 0; i < DP_MAX_SUPPORTED_RATES; ++i) - if (find == rates[i]) - break; - - return i; -} - int intel_dp_max_link_rate(struct intel_dp *intel_dp) { @@ -1628,6 +1617,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, enum port port = dp_to_dig_port(intel_dp)->port; struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); struct intel_connector *intel_connector = intel_dp->attached_connector; + struct intel_digital_connector_state *intel_conn_state = + to_intel_digital_connector_state(conn_state); int lane_count, clock; int min_lane_count = 1; int max_lane_count = intel_dp_max_lane_count(intel_dp); @@ -1653,7 +1644,12 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_pch_encoder = true; pipe_config->has_drrs = false; - pipe_config->has_audio = intel_dp->has_audio && port != PORT_A; + if (port == PORT_A) + pipe_config->has_audio = false; + else if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) + pipe_config->has_audio = intel_dp->has_audio; + else + pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON; if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { intel_fixed_panel_mode(intel_connector->panel.fixed_mode, @@ -1668,10 +1664,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (HAS_GMCH_DISPLAY(dev_priv)) intel_gmch_panel_fitting(intel_crtc, pipe_config, - intel_connector->panel.fitting_mode); + conn_state->scaling_mode); else intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector->panel.fitting_mode); + conn_state->scaling_mode); } if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) @@ -1740,7 +1736,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, return false; found: - if (intel_dp->color_range_auto) { + if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { /* * See: * CEA-861-E - 5.1 Default Encoding Parameters @@ -1752,7 +1748,7 @@ found: HDMI_QUANTIZATION_RANGE_LIMITED; } else { pipe_config->limited_color_range = - intel_dp->limited_color_range; + intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED; } pipe_config->lane_count = lane_count; @@ -2315,14 +2311,17 @@ static void _intel_edp_backlight_on(struct intel_dp *intel_dp) } /* Enable backlight PWM and backlight PP control. */ -void intel_edp_backlight_on(struct intel_dp *intel_dp) +void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_dp *intel_dp = enc_to_intel_dp(conn_state->best_encoder); + if (!is_edp(intel_dp)) return; DRM_DEBUG_KMS("\n"); - intel_panel_enable_backlight(intel_dp->attached_connector); + intel_panel_enable_backlight(crtc_state, conn_state); _intel_edp_backlight_on(intel_dp); } @@ -2354,15 +2353,17 @@ static void _intel_edp_backlight_off(struct intel_dp *intel_dp) } /* Disable backlight PP control and backlight PWM. */ -void intel_edp_backlight_off(struct intel_dp *intel_dp) +void intel_edp_backlight_off(const struct drm_connector_state *old_conn_state) { + struct intel_dp *intel_dp = enc_to_intel_dp(old_conn_state->best_encoder); + if (!is_edp(intel_dp)) return; DRM_DEBUG_KMS("\n"); _intel_edp_backlight_off(intel_dp); - intel_panel_disable_backlight(intel_dp->attached_connector); + intel_panel_disable_backlight(old_conn_state); } /* @@ -2658,7 +2659,7 @@ static void intel_disable_dp(struct intel_encoder *encoder, /* Make sure the panel is off before trying to change the mode. But also * ensure that we have vdd while we switch off the panel. */ intel_edp_panel_vdd_on(intel_dp); - intel_edp_backlight_off(intel_dp); + intel_edp_backlight_off(old_conn_state); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_edp_panel_off(intel_dp); @@ -2872,10 +2873,8 @@ static void g4x_enable_dp(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { - struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); - intel_enable_dp(encoder, pipe_config, conn_state); - intel_edp_backlight_on(intel_dp); + intel_edp_backlight_on(pipe_config, conn_state); } static void vlv_enable_dp(struct intel_encoder *encoder, @@ -2884,7 +2883,7 @@ static void vlv_enable_dp(struct intel_encoder *encoder, { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); - intel_edp_backlight_on(intel_dp); + intel_edp_backlight_on(pipe_config, conn_state); intel_psr_enable(intel_dp); } @@ -3466,7 +3465,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp) if (HAS_DDI(dev_priv)) { signal_levels = ddi_signal_levels(intel_dp); - if (IS_GEN9_LP(dev_priv)) + if (IS_GEN9_LP(dev_priv) || IS_CANNONLAKE(dev_priv)) signal_levels = 0; else mask = DDI_BUF_EMP_MASK; @@ -4587,10 +4586,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp) edid = intel_dp_get_edid(intel_dp); intel_connector->detect_edid = edid; - if (intel_dp->force_audio != HDMI_AUDIO_AUTO) - intel_dp->has_audio = intel_dp->force_audio == HDMI_AUDIO_ON; - else - intel_dp->has_audio = drm_detect_monitor_audio(edid); + intel_dp->has_audio = drm_detect_monitor_audio(edid); } static void @@ -4799,112 +4795,6 @@ static int intel_dp_get_modes(struct drm_connector *connector) return 0; } -static bool -intel_dp_detect_audio(struct drm_connector *connector) -{ - bool has_audio = false; - struct edid *edid; - - edid = to_intel_connector(connector)->detect_edid; - if (edid) - has_audio = drm_detect_monitor_audio(edid); - - return has_audio; -} - -static int -intel_dp_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_encoder *intel_encoder = intel_attached_encoder(connector); - struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); - int ret; - - ret = drm_object_property_set_value(&connector->base, property, val); - if (ret) - return ret; - - if (property == dev_priv->force_audio_property) { - int i = val; - bool has_audio; - - if (i == intel_dp->force_audio) - return 0; - - intel_dp->force_audio = i; - - if (i == HDMI_AUDIO_AUTO) - has_audio = intel_dp_detect_audio(connector); - else - has_audio = (i == HDMI_AUDIO_ON); - - if (has_audio == intel_dp->has_audio) - return 0; - - intel_dp->has_audio = has_audio; - goto done; - } - - if (property == dev_priv->broadcast_rgb_property) { - bool old_auto = intel_dp->color_range_auto; - bool old_range = intel_dp->limited_color_range; - - switch (val) { - case INTEL_BROADCAST_RGB_AUTO: - intel_dp->color_range_auto = true; - break; - case INTEL_BROADCAST_RGB_FULL: - intel_dp->color_range_auto = false; - intel_dp->limited_color_range = false; - break; - case INTEL_BROADCAST_RGB_LIMITED: - intel_dp->color_range_auto = false; - intel_dp->limited_color_range = true; - break; - default: - return -EINVAL; - } - - if (old_auto == intel_dp->color_range_auto && - old_range == intel_dp->limited_color_range) - return 0; - - goto done; - } - - if (is_edp(intel_dp) && - property == connector->dev->mode_config.scaling_mode_property) { - if (val == DRM_MODE_SCALE_NONE) { - DRM_DEBUG_KMS("no scaling not supported\n"); - return -EINVAL; - } - if (HAS_GMCH_DISPLAY(dev_priv) && - val == DRM_MODE_SCALE_CENTER) { - DRM_DEBUG_KMS("centering not supported\n"); - return -EINVAL; - } - - if (intel_connector->panel.fitting_mode == val) { - /* the eDP scaling property is not changed */ - return 0; - } - intel_connector->panel.fitting_mode = val; - - goto done; - } - - return -EINVAL; - -done: - if (intel_encoder->base.crtc) - intel_crtc_restore_mode(intel_encoder->base.crtc); - - return 0; -} - static int intel_dp_connector_register(struct drm_connector *connector) { @@ -5063,19 +4953,21 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .force = intel_dp_force, .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_dp_set_property, - .atomic_get_property = intel_connector_atomic_get_property, + .set_property = drm_atomic_helper_connector_set_property, + .atomic_get_property = intel_digital_connector_atomic_get_property, + .atomic_set_property = intel_digital_connector_atomic_set_property, .late_register = intel_dp_connector_register, .early_unregister = intel_dp_connector_unregister, .destroy = intel_dp_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { .detect_ctx = intel_dp_detect, .get_modes = intel_dp_get_modes, .mode_valid = intel_dp_mode_valid, + .atomic_check = intel_digital_connector_atomic_check, }; static const struct drm_encoder_funcs intel_dp_enc_funcs = { @@ -5169,19 +5061,22 @@ bool intel_dp_is_edp(struct drm_i915_private *dev_priv, enum port port) static void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) { - struct intel_connector *intel_connector = to_intel_connector(connector); + struct drm_i915_private *dev_priv = to_i915(connector->dev); intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); - intel_dp->color_range_auto = true; if (is_edp(intel_dp)) { - drm_mode_create_scaling_mode_property(connector->dev); - drm_object_attach_property( - &connector->base, - connector->dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_ASPECT); - intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT; + u32 allowed_scalers; + + allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN); + if (!HAS_GMCH_DISPLAY(dev_priv)) + allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER); + + drm_connector_attach_scaling_mode_property(connector, allowed_scalers); + + connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT; + } } @@ -5207,7 +5102,7 @@ intel_pps_readout_hw_state(struct drm_i915_private *dev_priv, pp_on = I915_READ(regs.pp_on); pp_off = I915_READ(regs.pp_off); - if (!IS_GEN9_LP(dev_priv)) { + if (!IS_GEN9_LP(dev_priv) && !HAS_PCH_CNP(dev_priv)) { I915_WRITE(regs.pp_ctrl, pp_ctl); pp_div = I915_READ(regs.pp_div); } @@ -5225,7 +5120,7 @@ intel_pps_readout_hw_state(struct drm_i915_private *dev_priv, seq->t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >> PANEL_POWER_DOWN_DELAY_SHIFT; - if (IS_GEN9_LP(dev_priv)) { + if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) { u16 tmp = (pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >> BXT_POWER_CYCLE_DELAY_SHIFT; if (tmp > 0) @@ -5382,7 +5277,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT); /* Compute the divisor for the pp clock, simply match the Bspec * formula. */ - if (IS_GEN9_LP(dev_priv)) { + if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) { pp_div = I915_READ(regs.pp_ctrl); pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK; pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000) @@ -5408,7 +5303,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, I915_WRITE(regs.pp_on, pp_on); I915_WRITE(regs.pp_off, pp_off); - if (IS_GEN9_LP(dev_priv)) + if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) I915_WRITE(regs.pp_ctrl, pp_div); else I915_WRITE(regs.pp_div, pp_div); @@ -5416,7 +5311,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n", I915_READ(regs.pp_on), I915_READ(regs.pp_off), - IS_GEN9_LP(dev_priv) ? + (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) ? (I915_READ(regs.pp_ctrl) & BXT_POWER_CYCLE_DELAY_MASK) : I915_READ(regs.pp_div)); } diff --git a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c index a0995c00..228ca06 100644 --- a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c @@ -78,8 +78,9 @@ static uint32_t intel_dp_aux_get_backlight(struct intel_connector *connector) * 8-bit or 16 bit value (MSB and LSB) */ static void -intel_dp_aux_set_backlight(struct intel_connector *connector, u32 level) +intel_dp_aux_set_backlight(const struct drm_connector_state *conn_state, u32 level) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); uint8_t vals[2] = { 0x0 }; @@ -97,8 +98,10 @@ intel_dp_aux_set_backlight(struct intel_connector *connector, u32 level) } } -static void intel_dp_aux_enable_backlight(struct intel_connector *connector) +static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); uint8_t dpcd_buf = 0; uint8_t edp_backlight_mode = 0; @@ -131,12 +134,12 @@ static void intel_dp_aux_enable_backlight(struct intel_connector *connector) } set_aux_backlight_enable(intel_dp, true); - intel_dp_aux_set_backlight(connector, connector->panel.backlight.level); + intel_dp_aux_set_backlight(conn_state, connector->panel.backlight.level); } -static void intel_dp_aux_disable_backlight(struct intel_connector *connector) +static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old_conn_state) { - set_aux_backlight_enable(enc_to_intel_dp(&connector->encoder->base), false); + set_aux_backlight_enable(enc_to_intel_dp(old_conn_state->best_encoder), false); } static int intel_dp_aux_setup_backlight(struct intel_connector *connector, @@ -145,8 +148,6 @@ static int intel_dp_aux_setup_backlight(struct intel_connector *connector, struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); struct intel_panel *panel = &connector->panel; - intel_dp_aux_enable_backlight(connector); - if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) panel->backlight.max = 0xFFFF; else @@ -165,7 +166,7 @@ intel_dp_aux_display_control_capable(struct intel_connector *connector) { struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); - /* Check the eDP Display control capabilities registers to determine if + /* Check the eDP Display control capabilities registers to determine if * the panel can support backlight control over the aux channel */ if (intel_dp->edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP && diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index b4de632..2f7b0e6 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -1321,7 +1321,6 @@ static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc, return true; } - static bool skl_ddi_dp_set_dpll_hw_state(int clock, struct intel_dpll_hw_state *dpll_hw_state) @@ -1967,6 +1966,438 @@ static const struct intel_dpll_mgr bxt_pll_mgr = { .dump_hw_state = bxt_dump_hw_state, }; +static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t val; + + /* 1. Enable DPLL power in DPLL_ENABLE. */ + val = I915_READ(CNL_DPLL_ENABLE(pll->id)); + val |= PLL_POWER_ENABLE; + I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); + + /* 2. Wait for DPLL power state enabled in DPLL_ENABLE. */ + if (intel_wait_for_register(dev_priv, + CNL_DPLL_ENABLE(pll->id), + PLL_POWER_STATE, + PLL_POWER_STATE, + 5)) + DRM_ERROR("PLL %d Power not enabled\n", pll->id); + + /* + * 3. Configure DPLL_CFGCR0 to set SSC enable/disable, + * select DP mode, and set DP link rate. + */ + val = pll->state.hw_state.cfgcr0; + I915_WRITE(CNL_DPLL_CFGCR0(pll->id), val); + + /* 4. Reab back to ensure writes completed */ + POSTING_READ(CNL_DPLL_CFGCR0(pll->id)); + + /* 3. Configure DPLL_CFGCR0 */ + /* Avoid touch CFGCR1 if HDMI mode is not enabled */ + if (pll->state.hw_state.cfgcr0 & DPLL_CTRL1_HDMI_MODE(pll->id)) { + val = pll->state.hw_state.cfgcr1; + I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val); + /* 4. Reab back to ensure writes completed */ + POSTING_READ(CNL_DPLL_CFGCR1(pll->id)); + } + + /* + * 5. If the frequency will result in a change to the voltage + * requirement, follow the Display Voltage Frequency Switching + * Sequence Before Frequency Change + * + * FIXME: (DVFS) is used to adjust the display voltage to match the + * display clock frequencies + */ + + /* 6. Enable DPLL in DPLL_ENABLE. */ + val = I915_READ(CNL_DPLL_ENABLE(pll->id)); + val |= PLL_ENABLE; + I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); + + /* 7. Wait for PLL lock status in DPLL_ENABLE. */ + if (intel_wait_for_register(dev_priv, + CNL_DPLL_ENABLE(pll->id), + PLL_LOCK, + PLL_LOCK, + 5)) + DRM_ERROR("PLL %d not locked\n", pll->id); + + /* + * 8. If the frequency will result in a change to the voltage + * requirement, follow the Display Voltage Frequency Switching + * Sequence After Frequency Change + * + * FIXME: (DVFS) is used to adjust the display voltage to match the + * display clock frequencies + */ + + /* + * 9. turn on the clock for the DDI and map the DPLL to the DDI + * Done at intel_ddi_clk_select + */ +} + +static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t val; + + /* + * 1. Configure DPCLKA_CFGCR0 to turn off the clock for the DDI. + * Done at intel_ddi_post_disable + */ + + /* + * 2. If the frequency will result in a change to the voltage + * requirement, follow the Display Voltage Frequency Switching + * Sequence Before Frequency Change + * + * FIXME: (DVFS) is used to adjust the display voltage to match the + * display clock frequencies + */ + + /* 3. Disable DPLL through DPLL_ENABLE. */ + val = I915_READ(CNL_DPLL_ENABLE(pll->id)); + val &= ~PLL_ENABLE; + I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); + + /* 4. Wait for PLL not locked status in DPLL_ENABLE. */ + if (intel_wait_for_register(dev_priv, + CNL_DPLL_ENABLE(pll->id), + PLL_LOCK, + 0, + 5)) + DRM_ERROR("PLL %d locked\n", pll->id); + + /* + * 5. If the frequency will result in a change to the voltage + * requirement, follow the Display Voltage Frequency Switching + * Sequence After Frequency Change + * + * FIXME: (DVFS) is used to adjust the display voltage to match the + * display clock frequencies + */ + + /* 6. Disable DPLL power in DPLL_ENABLE. */ + val = I915_READ(CNL_DPLL_ENABLE(pll->id)); + val &= ~PLL_POWER_ENABLE; + I915_WRITE(CNL_DPLL_ENABLE(pll->id), val); + + /* 7. Wait for DPLL power state disabled in DPLL_ENABLE. */ + if (intel_wait_for_register(dev_priv, + CNL_DPLL_ENABLE(pll->id), + PLL_POWER_STATE, + 0, + 5)) + DRM_ERROR("PLL %d Power not disabled\n", pll->id); +} + +static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + uint32_t val; + bool ret; + + if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + ret = false; + + val = I915_READ(CNL_DPLL_ENABLE(pll->id)); + if (!(val & PLL_ENABLE)) + goto out; + + val = I915_READ(CNL_DPLL_CFGCR0(pll->id)); + hw_state->cfgcr0 = val; + + /* avoid reading back stale values if HDMI mode is not enabled */ + if (val & DPLL_CFGCR0_HDMI_MODE) { + hw_state->cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll->id)); + } + ret = true; + +out: + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); + + return ret; +} + +static void cnl_wrpll_get_multipliers(unsigned int bestdiv, + unsigned int *pdiv, + unsigned int *qdiv, + unsigned int *kdiv) +{ + /* even dividers */ + if (bestdiv % 2 == 0) { + if (bestdiv == 2) { + *pdiv = 2; + *qdiv = 1; + *kdiv = 1; + } else if (bestdiv % 4 == 0) { + *pdiv = 2; + *qdiv = bestdiv / 4; + *kdiv = 2; + } else if (bestdiv % 6 == 0) { + *pdiv = 3; + *qdiv = bestdiv / 6; + *kdiv = 2; + } else if (bestdiv % 5 == 0) { + *pdiv = 5; + *qdiv = bestdiv / 10; + *kdiv = 2; + } else if (bestdiv % 14 == 0) { + *pdiv = 7; + *qdiv = bestdiv / 14; + *kdiv = 2; + } + } else { + if (bestdiv == 3 || bestdiv == 5 || bestdiv == 7) { + *pdiv = bestdiv; + *qdiv = 1; + *kdiv = 1; + } else { /* 9, 15, 21 */ + *pdiv = bestdiv / 3; + *qdiv = 1; + *kdiv = 3; + } + } +} + +static void cnl_wrpll_params_populate(struct skl_wrpll_params *params, uint32_t dco_freq, + uint32_t ref_freq, uint32_t pdiv, uint32_t qdiv, + uint32_t kdiv) +{ + switch (kdiv) { + case 1: + params->kdiv = 1; + break; + case 2: + params->kdiv = 2; + break; + case 3: + params->kdiv = 4; + break; + default: + WARN(1, "Incorrect KDiv\n"); + } + + switch (pdiv) { + case 2: + params->pdiv = 1; + break; + case 3: + params->pdiv = 2; + break; + case 5: + params->pdiv = 4; + break; + case 7: + params->pdiv = 8; + break; + default: + WARN(1, "Incorrect PDiv\n"); + } + + if (kdiv != 2) + qdiv = 1; + + params->qdiv_ratio = qdiv; + params->qdiv_mode = (qdiv == 1) ? 0 : 1; + + params->dco_integer = div_u64(dco_freq, ref_freq); + params->dco_fraction = div_u64((div_u64((uint64_t)dco_freq<<15, (uint64_t)ref_freq) - + ((uint64_t)params->dco_integer<<15)) * 0x8000, 0x8000); +} + +static bool +cnl_ddi_calculate_wrpll(int clock /* in Hz */, + struct drm_i915_private *dev_priv, + struct skl_wrpll_params *wrpll_params) +{ + uint64_t afe_clock = clock * 5 / KHz(1); /* clocks in kHz */ + unsigned int dco_min = 7998 * KHz(1); + unsigned int dco_max = 10000 * KHz(1); + unsigned int dco_mid = (dco_min + dco_max) / 2; + + static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16, + 18, 20, 24, 28, 30, 32, 36, 40, + 42, 44, 48, 50, 52, 54, 56, 60, + 64, 66, 68, 70, 72, 76, 78, 80, + 84, 88, 90, 92, 96, 98, 100, 102, + 3, 5, 7, 9, 15, 21 }; + unsigned int d, dco; + unsigned int dco_centrality = 0; + unsigned int best_dco_centrality = 999999; + unsigned int best_div = 0; + unsigned int best_dco = 0; + unsigned int pdiv = 0, qdiv = 0, kdiv = 0; + + for (d = 0; d < ARRAY_SIZE(dividers); d++) { + dco = afe_clock * dividers[d]; + + if ((dco <= dco_max) && (dco >= dco_min)) { + dco_centrality = abs(dco - dco_mid); + + if (dco_centrality < best_dco_centrality) { + best_dco_centrality = dco_centrality; + best_div = dividers[d]; + best_dco = dco; + } + } + } + + if (best_div == 0) + return false; + + cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv); + + cnl_wrpll_params_populate(wrpll_params, best_dco, + dev_priv->cdclk.hw.ref, pdiv, qdiv, kdiv); + + return true; +} + +static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state, + int clock) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + uint32_t cfgcr0, cfgcr1; + struct skl_wrpll_params wrpll_params = { 0, }; + + cfgcr0 = DPLL_CFGCR0_HDMI_MODE; + + if (!cnl_ddi_calculate_wrpll(clock * 1000, dev_priv, &wrpll_params)) + return false; + + cfgcr0 |= DPLL_CFGCR0_DCO_FRACTION(wrpll_params.dco_fraction) | + wrpll_params.dco_integer; + + cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(wrpll_params.qdiv_ratio) | + DPLL_CFGCR1_QDIV_MODE(wrpll_params.qdiv_mode) | + DPLL_CFGCR1_KDIV(wrpll_params.kdiv) | + DPLL_CFGCR1_PDIV(wrpll_params.pdiv) | + wrpll_params.central_freq | + DPLL_CFGCR1_CENTRAL_FREQ; + + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + crtc_state->dpll_hw_state.cfgcr0 = cfgcr0; + crtc_state->dpll_hw_state.cfgcr1 = cfgcr1; + return true; +} + +static bool +cnl_ddi_dp_set_dpll_hw_state(int clock, + struct intel_dpll_hw_state *dpll_hw_state) +{ + uint32_t cfgcr0; + + cfgcr0 = DPLL_CFGCR0_SSC_ENABLE; + + switch (clock / 2) { + case 81000: + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_810; + break; + case 135000: + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1350; + break; + case 270000: + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_2700; + break; + /* eDP 1.4 rates */ + case 162000: + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1620; + break; + case 108000: + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1080; + break; + case 216000: + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_2160; + break; + case 324000: + /* Some SKUs may require elevated I/O voltage to support this */ + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_3240; + break; + case 405000: + /* Some SKUs may require elevated I/O voltage to support this */ + cfgcr0 |= DPLL_CFGCR0_LINK_RATE_4050; + break; + } + + dpll_hw_state->cfgcr0 = cfgcr0; + return true; +} + +static struct intel_shared_dpll * +cnl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, + struct intel_encoder *encoder) +{ + struct intel_shared_dpll *pll; + int clock = crtc_state->port_clock; + bool bret; + struct intel_dpll_hw_state dpll_hw_state; + + memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); + + if (encoder->type == INTEL_OUTPUT_HDMI) { + bret = cnl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock); + if (!bret) { + DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n"); + return NULL; + } + } else if (encoder->type == INTEL_OUTPUT_DP || + encoder->type == INTEL_OUTPUT_DP_MST || + encoder->type == INTEL_OUTPUT_EDP) { + bret = cnl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state); + if (!bret) { + DRM_DEBUG_KMS("Could not set DP dpll HW state.\n"); + return NULL; + } + crtc_state->dpll_hw_state = dpll_hw_state; + } else { + DRM_DEBUG_KMS("Skip DPLL setup for encoder %d\n", + encoder->type); + return NULL; + } + + pll = intel_find_shared_dpll(crtc, crtc_state, + DPLL_ID_SKL_DPLL0, + DPLL_ID_SKL_DPLL2); + if (!pll) { + DRM_DEBUG_KMS("No PLL selected\n"); + return NULL; + } + + intel_reference_shared_dpll(pll, crtc_state); + + return pll; +} + +static const struct intel_shared_dpll_funcs cnl_ddi_pll_funcs = { + .enable = cnl_ddi_pll_enable, + .disable = cnl_ddi_pll_disable, + .get_hw_state = cnl_ddi_pll_get_hw_state, +}; + +static const struct dpll_info cnl_plls[] = { + { "DPLL 0", DPLL_ID_SKL_DPLL0, &cnl_ddi_pll_funcs, 0 }, + { "DPLL 1", DPLL_ID_SKL_DPLL1, &cnl_ddi_pll_funcs, 0 }, + { "DPLL 2", DPLL_ID_SKL_DPLL2, &cnl_ddi_pll_funcs, 0 }, + { NULL, -1, NULL, }, +}; + +static const struct intel_dpll_mgr cnl_pll_mgr = { + .dpll_info = cnl_plls, + .get_dpll = cnl_get_dpll, + .dump_hw_state = skl_dump_hw_state, +}; + /** * intel_shared_dpll_init - Initialize shared DPLLs * @dev: drm device @@ -1980,7 +2411,9 @@ void intel_shared_dpll_init(struct drm_device *dev) const struct dpll_info *dpll_info; int i; - if (IS_GEN9_BC(dev_priv)) + if (IS_CANNONLAKE(dev_priv)) + dpll_mgr = &cnl_pll_mgr; + else if (IS_GEN9_BC(dev_priv)) dpll_mgr = &skl_pll_mgr; else if (IS_GEN9_LP(dev_priv)) dpll_mgr = &bxt_pll_mgr; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index f8d13a9..f24ccf4 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -128,6 +128,10 @@ struct intel_dpll_hw_state { /* HDMI only, 0 when used for DP */ uint32_t cfgcr1, cfgcr2; + /* cnl */ + uint32_t cfgcr0; + /* CNL also uses cfgcr1 */ + /* bxt */ uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, pcsdw12; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 71f94a0..d93efb4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -266,7 +266,6 @@ struct intel_encoder { struct intel_panel { struct drm_display_mode *fixed_mode; struct drm_display_mode *downclock_mode; - int fitting_mode; /* backlight */ struct { @@ -289,9 +288,10 @@ struct intel_panel { /* Connector and platform specific backlight functions */ int (*setup)(struct intel_connector *connector, enum pipe pipe); uint32_t (*get)(struct intel_connector *connector); - void (*set)(struct intel_connector *connector, uint32_t level); - void (*disable)(struct intel_connector *connector); - void (*enable)(struct intel_connector *connector); + void (*set)(const struct drm_connector_state *conn_state, uint32_t level); + void (*disable)(const struct drm_connector_state *conn_state); + void (*enable)(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); uint32_t (*hz_to_pwm)(struct intel_connector *connector, uint32_t hz); void (*power)(struct intel_connector *, bool enable); @@ -331,6 +331,15 @@ struct intel_connector { struct work_struct modeset_retry_work; }; +struct intel_digital_connector_state { + struct drm_connector_state base; + + enum hdmi_force_audio force_audio; + int broadcast_rgb; +}; + +#define to_intel_digital_connector_state(x) container_of(x, struct intel_digital_connector_state, base) + struct dpll { /* given values */ int n; @@ -896,11 +905,8 @@ struct intel_hdmi { enum drm_dp_dual_mode_type type; int max_tmds_clock; } dp_dual_mode; - bool limited_color_range; - bool color_range_auto; bool has_hdmi_sink; bool has_audio; - enum hdmi_force_audio force_audio; bool rgb_quant_range_selectable; struct intel_connector *attached_connector; void (*write_infoframe)(struct drm_encoder *encoder, @@ -966,9 +972,6 @@ struct intel_dp { bool detect_done; bool channel_eq_status; bool reset_link_params; - enum hdmi_force_audio force_audio; - bool limited_color_range; - bool color_range_auto; uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE]; uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; @@ -1307,6 +1310,8 @@ void intel_audio_deinit(struct drm_i915_private *dev_priv); /* intel_cdclk.c */ void skl_init_cdclk(struct drm_i915_private *dev_priv); void skl_uninit_cdclk(struct drm_i915_private *dev_priv); +void cnl_init_cdclk(struct drm_i915_private *dev_priv); +void cnl_uninit_cdclk(struct drm_i915_private *dev_priv); void bxt_init_cdclk(struct drm_i915_private *dev_priv); void bxt_uninit_cdclk(struct drm_i915_private *dev_priv); void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); @@ -1319,6 +1324,8 @@ void intel_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_state *cdclk_state); /* intel_display.c */ +void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); +void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc); void intel_update_rawclk(struct drm_i915_private *dev_priv); int vlv_get_hpll_vco(struct drm_i915_private *dev_priv); @@ -1339,7 +1346,6 @@ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv); void intel_mark_busy(struct drm_i915_private *dev_priv); void intel_mark_idle(struct drm_i915_private *dev_priv); -void intel_crtc_restore_mode(struct drm_crtc *crtc); int intel_display_suspend(struct drm_device *dev); void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv); void intel_encoder_destroy(struct drm_encoder *encoder); @@ -1518,8 +1524,9 @@ bool intel_dp_compute_config(struct intel_encoder *encoder, bool intel_dp_is_edp(struct drm_i915_private *dev_priv, enum port port); enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd); -void intel_edp_backlight_on(struct intel_dp *intel_dp); -void intel_edp_backlight_off(struct intel_dp *intel_dp); +void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_edp_backlight_off(const struct drm_connector_state *conn_state); void intel_edp_panel_vdd_on(struct intel_dp *intel_dp); void intel_edp_panel_on(struct intel_dp *intel_dp); void intel_edp_panel_off(struct intel_dp *intel_dp); @@ -1699,12 +1706,13 @@ void intel_pch_panel_fitting(struct intel_crtc *crtc, void intel_gmch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, int fitting_mode); -void intel_panel_set_backlight_acpi(struct intel_connector *connector, +void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, u32 level, u32 max); int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe); -void intel_panel_enable_backlight(struct intel_connector *connector); -void intel_panel_disable_backlight(struct intel_connector *connector); +void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); void intel_panel_destroy_backlight(struct drm_connector *connector); enum drm_connector_status intel_panel_detect(struct drm_i915_private *dev_priv); extern struct drm_display_mode *intel_find_panel_downclock( @@ -1874,6 +1882,8 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry **entries, int ignore); bool ilk_disable_lp_wm(struct drm_device *dev); int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); +int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, + struct intel_crtc_state *cstate); static inline int intel_enable_rc6(void) { return i915.enable_rc6; @@ -1898,10 +1908,19 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work void intel_tv_init(struct drm_i915_private *dev_priv); /* intel_atomic.c */ -int intel_connector_atomic_get_property(struct drm_connector *connector, - const struct drm_connector_state *state, - struct drm_property *property, - uint64_t *val); +int intel_digital_connector_atomic_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val); +int intel_digital_connector_atomic_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val); +int intel_digital_connector_atomic_check(struct drm_connector *conn, + struct drm_connector_state *new_state); +struct drm_connector_state * +intel_digital_connector_duplicate_state(struct drm_connector *connector); + struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc); void intel_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state); diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index fc0ef49..50ec836 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -320,10 +320,10 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, if (HAS_GMCH_DISPLAY(dev_priv)) intel_gmch_panel_fitting(crtc, pipe_config, - intel_connector->panel.fitting_mode); + conn_state->scaling_mode); else intel_pch_panel_fitting(crtc, pipe_config, - intel_connector->panel.fitting_mode); + conn_state->scaling_mode); } /* DSI uses short packets for sync events, so clear mode flags for DSI */ @@ -346,12 +346,13 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, return true; } -static void glk_dsi_device_ready(struct intel_encoder *encoder) +static bool glk_dsi_enable_io(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; - u32 tmp, val; + u32 tmp; + bool cold_boot = false; /* Set the MIPI mode * If MIPI_Mode is off, then writing to LP_Wake bit is not reflecting. @@ -370,7 +371,10 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) /* Program LP Wake */ for_each_dsi_port(port, intel_dsi->ports) { tmp = I915_READ(MIPI_CTRL(port)); - tmp |= GLK_LP_WAKE; + if (!(I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY)) + tmp &= ~GLK_LP_WAKE; + else + tmp |= GLK_LP_WAKE; I915_WRITE(MIPI_CTRL(port), tmp); } @@ -382,6 +386,22 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) DRM_ERROR("MIPIO port is powergated\n"); } + /* Check for cold boot scenario */ + for_each_dsi_port(port, intel_dsi->ports) { + cold_boot |= !(I915_READ(MIPI_DEVICE_READY(port)) & + DEVICE_READY); + } + + return cold_boot; +} + +static void glk_dsi_device_ready(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; + u32 val; + /* Wait for MIPI PHY status bit to set */ for_each_dsi_port(port, intel_dsi->ports) { if (intel_wait_for_register(dev_priv, @@ -391,8 +411,8 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) } /* Get IO out of reset */ - tmp = I915_READ(MIPI_CTRL(PORT_A)); - I915_WRITE(MIPI_CTRL(PORT_A), tmp | GLK_MIPIIO_RESET_RELEASED); + val = I915_READ(MIPI_CTRL(PORT_A)); + I915_WRITE(MIPI_CTRL(PORT_A), val | GLK_MIPIIO_RESET_RELEASED); /* Get IO out of Low power state*/ for_each_dsi_port(port, intel_dsi->ports) { @@ -402,34 +422,34 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) val |= DEVICE_READY; I915_WRITE(MIPI_DEVICE_READY(port), val); usleep_range(10, 15); - } - - /* Enter ULPS */ - val = I915_READ(MIPI_DEVICE_READY(port)); - val &= ~ULPS_STATE_MASK; - val |= (ULPS_STATE_ENTER | DEVICE_READY); - I915_WRITE(MIPI_DEVICE_READY(port), val); + } else { + /* Enter ULPS */ + val = I915_READ(MIPI_DEVICE_READY(port)); + val &= ~ULPS_STATE_MASK; + val |= (ULPS_STATE_ENTER | DEVICE_READY); + I915_WRITE(MIPI_DEVICE_READY(port), val); - /* Wait for ULPS active */ - if (intel_wait_for_register(dev_priv, + /* Wait for ULPS active */ + if (intel_wait_for_register(dev_priv, MIPI_CTRL(port), GLK_ULPS_NOT_ACTIVE, 0, 20)) - DRM_ERROR("ULPS not active\n"); + DRM_ERROR("ULPS not active\n"); - /* Exit ULPS */ - val = I915_READ(MIPI_DEVICE_READY(port)); - val &= ~ULPS_STATE_MASK; - val |= (ULPS_STATE_EXIT | DEVICE_READY); - I915_WRITE(MIPI_DEVICE_READY(port), val); + /* Exit ULPS */ + val = I915_READ(MIPI_DEVICE_READY(port)); + val &= ~ULPS_STATE_MASK; + val |= (ULPS_STATE_EXIT | DEVICE_READY); + I915_WRITE(MIPI_DEVICE_READY(port), val); - /* Enter Normal Mode */ - val = I915_READ(MIPI_DEVICE_READY(port)); - val &= ~ULPS_STATE_MASK; - val |= (ULPS_STATE_NORMAL_OPERATION | DEVICE_READY); - I915_WRITE(MIPI_DEVICE_READY(port), val); + /* Enter Normal Mode */ + val = I915_READ(MIPI_DEVICE_READY(port)); + val &= ~ULPS_STATE_MASK; + val |= (ULPS_STATE_NORMAL_OPERATION | DEVICE_READY); + I915_WRITE(MIPI_DEVICE_READY(port), val); - tmp = I915_READ(MIPI_CTRL(port)); - tmp &= ~GLK_LP_WAKE; - I915_WRITE(MIPI_CTRL(port), tmp); + val = I915_READ(MIPI_CTRL(port)); + val &= ~GLK_LP_WAKE; + I915_WRITE(MIPI_CTRL(port), val); + } } /* Wait for Stop state */ @@ -770,6 +790,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; u32 val; + bool glk_cold_boot = false; DRM_DEBUG_KMS("\n"); @@ -800,7 +821,8 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, I915_WRITE(DSPCLK_GATE_D, val); } - intel_dsi_prepare(encoder, pipe_config); + if (!IS_GEMINILAKE(dev_priv)) + intel_dsi_prepare(encoder, pipe_config); /* Power on, try both CRC pmic gpio and VBT */ if (intel_dsi->gpio_panel) @@ -811,9 +833,21 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, /* Deassert reset */ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); + if (IS_GEMINILAKE(dev_priv)) { + glk_cold_boot = glk_dsi_enable_io(encoder); + + /* Prepare port in cold boot(s3/s4) scenario */ + if (glk_cold_boot) + intel_dsi_prepare(encoder, pipe_config); + } + /* Put device in ready state (LP-11) */ intel_dsi_device_ready(encoder); + /* Prepare port in normal boot scenario */ + if (IS_GEMINILAKE(dev_priv) && !glk_cold_boot) + intel_dsi_prepare(encoder, pipe_config); + /* Send initialization commands in LP mode */ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); @@ -835,7 +869,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, intel_dsi_port_enable(encoder); } - intel_panel_enable_backlight(intel_dsi->attached_connector); + intel_panel_enable_backlight(pipe_config, conn_state); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); } @@ -866,7 +900,7 @@ static void intel_dsi_disable(struct intel_encoder *encoder, DRM_DEBUG_KMS("\n"); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); - intel_panel_disable_backlight(intel_dsi->attached_connector); + intel_panel_disable_backlight(old_conn_state); /* * Disable Device ready before the port shutdown in order @@ -1587,48 +1621,6 @@ static int intel_dsi_get_modes(struct drm_connector *connector) return 1; } -static int intel_dsi_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = connector->dev; - struct intel_connector *intel_connector = to_intel_connector(connector); - struct drm_crtc *crtc; - int ret; - - ret = drm_object_property_set_value(&connector->base, property, val); - if (ret) - return ret; - - if (property == dev->mode_config.scaling_mode_property) { - if (val == DRM_MODE_SCALE_NONE) { - DRM_DEBUG_KMS("no scaling not supported\n"); - return -EINVAL; - } - if (HAS_GMCH_DISPLAY(to_i915(dev)) && - val == DRM_MODE_SCALE_CENTER) { - DRM_DEBUG_KMS("centering not supported\n"); - return -EINVAL; - } - - if (intel_connector->panel.fitting_mode == val) - return 0; - - intel_connector->panel.fitting_mode = val; - } - - crtc = connector->state->crtc; - if (crtc && crtc->state->enable) { - /* - * If the CRTC is enabled, the display will be changed - * according to the new panel fitting mode. - */ - intel_crtc_restore_mode(crtc); - } - - return 0; -} - static void intel_dsi_connector_destroy(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); @@ -1657,6 +1649,7 @@ static const struct drm_encoder_funcs intel_dsi_funcs = { static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = { .get_modes = intel_dsi_get_modes, .mode_valid = intel_dsi_mode_valid, + .atomic_check = intel_digital_connector_atomic_check, }; static const struct drm_connector_funcs intel_dsi_connector_funcs = { @@ -1665,22 +1658,28 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = { .early_unregister = intel_connector_unregister, .destroy = intel_dsi_connector_destroy, .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_dsi_set_property, - .atomic_get_property = intel_connector_atomic_get_property, + .set_property = drm_atomic_helper_connector_set_property, + .atomic_get_property = intel_digital_connector_atomic_get_property, + .atomic_set_property = intel_digital_connector_atomic_set_property, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; static void intel_dsi_add_properties(struct intel_connector *connector) { - struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); if (connector->panel.fixed_mode) { - drm_mode_create_scaling_mode_property(dev); - drm_object_attach_property(&connector->base.base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_ASPECT); - connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT; + u32 allowed_scalers; + + allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN); + if (!HAS_GMCH_DISPLAY(dev_priv)) + allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER); + + drm_connector_attach_scaling_mode_property(&connector->base, + allowed_scalers); + + connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT; } } diff --git a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c index ac7c602..6e09ceb 100644 --- a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c @@ -60,10 +60,9 @@ static u32 dcs_get_backlight(struct intel_connector *connector) return data; } -static void dcs_set_backlight(struct intel_connector *connector, u32 level) +static void dcs_set_backlight(const struct drm_connector_state *conn_state, u32 level) { - struct intel_encoder *encoder = connector->encoder; - struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(conn_state->best_encoder); struct mipi_dsi_device *dsi_device; u8 data = level; enum port port; @@ -76,14 +75,13 @@ static void dcs_set_backlight(struct intel_connector *connector, u32 level) } } -static void dcs_disable_backlight(struct intel_connector *connector) +static void dcs_disable_backlight(const struct drm_connector_state *conn_state) { - struct intel_encoder *encoder = connector->encoder; - struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(conn_state->best_encoder); struct mipi_dsi_device *dsi_device; enum port port; - dcs_set_backlight(connector, 0); + dcs_set_backlight(conn_state, 0); for_each_dsi_port(port, intel_dsi->dcs_cabc_ports) { u8 cabc = POWER_SAVE_OFF; @@ -110,11 +108,11 @@ static void dcs_disable_backlight(struct intel_connector *connector) } } -static void dcs_enable_backlight(struct intel_connector *connector) +static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { - struct intel_encoder *encoder = connector->encoder; - struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - struct intel_panel *panel = &connector->panel; + struct intel_dsi *intel_dsi = enc_to_intel_dsi(conn_state->best_encoder); + struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel; struct mipi_dsi_device *dsi_device; enum port port; @@ -142,7 +140,7 @@ static void dcs_enable_backlight(struct intel_connector *connector) &cabc, sizeof(cabc)); } - dcs_set_backlight(connector, panel->backlight.level); + dcs_set_backlight(conn_state, panel->backlight.level); } static int dcs_setup_backlight(struct intel_connector *connector, diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 699f2d3..a4487c5 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -814,26 +814,27 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) struct drm_i915_private *dev_priv = engine->i915; int ret; - /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk */ + /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE)); - /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk */ + /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); - /* WaDisableKillLogic:bxt,skl,kbl */ + /* WaDisableKillLogic:bxt,skl,kbl,cfl */ I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | ECOCHK_DIS_TLB); - /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk */ - /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk */ + /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */ + /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */ WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, FLOW_CONTROL_ENABLE | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); /* Syncing dependencies between camera and graphics:skl,bxt,kbl */ - WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, - GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); + if (!IS_COFFEELAKE(dev_priv)) + WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, + GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */ if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) @@ -851,18 +852,18 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) */ } - /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk */ - /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl */ + /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */ + /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */ WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, GEN9_ENABLE_YV12_BUGFIX | GEN9_ENABLE_GPGPU_PREEMPTION); - /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk */ - /* WaDisablePartialResolveInVc:skl,bxt,kbl */ + /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */ + /* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */ WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE | GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE)); - /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk */ + /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */ WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, GEN9_CCS_TLB_PREFETCH_ENABLE); @@ -871,7 +872,7 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0, PIXEL_MASK_CAMMING_DISABLE); - /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl */ + /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */ WA_SET_BIT_MASKED(HDC_CHICKEN0, HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE); @@ -889,39 +890,41 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) * a TLB invalidation occurs during a PSD flush. */ - /* WaForceEnableNonCoherent:skl,bxt,kbl */ + /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */ WA_SET_BIT_MASKED(HDC_CHICKEN0, HDC_FORCE_NON_COHERENT); /* WaDisableHDCInvalidation:skl,bxt,kbl */ - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | - BDW_DISABLE_HDC_INVALIDATION); + if (!IS_COFFEELAKE(dev_priv)) + I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | + BDW_DISABLE_HDC_INVALIDATION); - /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl */ + /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */ if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || + IS_COFFEELAKE(dev_priv) || IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, GEN8_SAMPLER_POWER_BYPASS_DIS); - /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk */ + /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */ WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); - /* WaOCLCoherentLineFlush:skl,bxt,kbl */ + /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */ I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES)); - /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk */ + /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */ ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG); if (ret) return ret; - /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl */ + /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl */ ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1); if (ret) return ret; - /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk */ + /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */ ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1); if (ret) return ret; @@ -1140,6 +1143,38 @@ static int glk_init_workarounds(struct intel_engine_cs *engine) return 0; } +static int cfl_init_workarounds(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + int ret; + + ret = gen9_init_workarounds(engine); + if (ret) + return ret; + + /* WaEnableGapsTsvCreditFix:cfl */ + I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) | + GEN9_GAPS_TSV_CREDIT_DISABLE)); + + /* WaToEnableHwFixForPushConstHWBug:cfl */ + WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, + GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); + + /* WaDisableGafsUnitClkGating:cfl */ + WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); + + /* WaDisableSbeCacheDispatchPortSharing:cfl */ + WA_SET_BIT_MASKED( + GEN7_HALF_SLICE_CHICKEN1, + GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); + + /* WaInPlaceDecompressionHang:cfl */ + WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA, + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); + + return 0; +} + int init_workarounds_ring(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; @@ -1162,6 +1197,8 @@ int init_workarounds_ring(struct intel_engine_cs *engine) err = kbl_init_workarounds(engine); else if (IS_GEMINILAKE(dev_priv)) err = glk_init_workarounds(engine); + else if (IS_COFFEELAKE(dev_priv)) + err = cfl_init_workarounds(engine); else err = 0; if (err) @@ -1212,6 +1249,11 @@ static bool ring_is_idle(struct intel_engine_cs *engine) intel_runtime_pm_get(dev_priv); + /* First check that no commands are left in the ring */ + if ((I915_READ_HEAD(engine) & HEAD_ADDR) != + (I915_READ_TAIL(engine) & TAIL_ADDR)) + idle = false; + /* No bit for gen2, so assume the CS parser is idle */ if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE)) idle = false; diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 966e255..d484862 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -262,7 +262,7 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, ironlake_set_fifo_underrun_reporting(dev, pipe, enable); else if (IS_GEN7(dev_priv)) ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old); - else if (IS_GEN8(dev_priv) || IS_GEN9(dev_priv)) + else if (INTEL_GEN(dev_priv) >= 8) broadwell_set_fifo_underrun_reporting(dev, pipe, enable); return old; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index d9045b6..8b0ae7f 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -402,7 +402,7 @@ int intel_guc_select_fw(struct intel_guc *guc) guc->fw.path = I915_BXT_GUC_UCODE; guc->fw.major_ver_wanted = BXT_FW_MAJOR; guc->fw.minor_ver_wanted = BXT_FW_MINOR; - } else if (IS_KABYLAKE(dev_priv)) { + } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { guc->fw.path = I915_KBL_GUC_UCODE; guc->fw.major_ver_wanted = KBL_FW_MAJOR; guc->fw.minor_ver_wanted = KBL_FW_MINOR; diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c index e1ab643..52d5b82 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c +++ b/drivers/gpu/drm/i915/intel_gvt.c @@ -51,6 +51,32 @@ static bool is_supported_device(struct drm_i915_private *dev_priv) } /** + * intel_gvt_sanitize_options - sanitize GVT related options + * @dev_priv: drm i915 private data + * + * This function is called at the i915 options sanitize stage. + */ +void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv) +{ + if (!i915.enable_gvt) + return; + + if (intel_vgpu_active(dev_priv)) { + DRM_INFO("GVT-g is disabled for guest\n"); + goto bail; + } + + if (!is_supported_device(dev_priv)) { + DRM_INFO("Unsupported device. GVT-g is disabled\n"); + goto bail; + } + + return; +bail: + i915.enable_gvt = 0; +} + +/** * intel_gvt_init - initialize GVT components * @dev_priv: drm i915 private data * @@ -69,19 +95,14 @@ int intel_gvt_init(struct drm_i915_private *dev_priv) return 0; } - if (intel_vgpu_active(dev_priv)) { - DRM_DEBUG_DRIVER("GVT-g is disabled for guest\n"); - goto bail; - } - - if (!is_supported_device(dev_priv)) { - DRM_DEBUG_DRIVER("Unsupported device. GVT-g is disabled\n"); - goto bail; + if (!i915.enable_execlists) { + DRM_ERROR("i915 GVT-g loading failed due to disabled execlists mode\n"); + return -EIO; } - if (!i915.enable_execlists) { - DRM_INFO("GPU guest virtualisation [GVT-g] disabled due to disabled execlist submission [i915.enable_execlists module parameter]\n"); - goto bail; + if (i915.enable_guc_submission) { + DRM_ERROR("i915 GVT-g loading failed due to Graphics virtualization is not yet supported with GuC submission\n"); + return -EIO; } /* diff --git a/drivers/gpu/drm/i915/intel_gvt.h b/drivers/gpu/drm/i915/intel_gvt.h index 25df2d6..61b2464 100644 --- a/drivers/gpu/drm/i915/intel_gvt.h +++ b/drivers/gpu/drm/i915/intel_gvt.h @@ -32,6 +32,7 @@ void intel_gvt_cleanup(struct drm_i915_private *dev_priv); int intel_gvt_init_device(struct drm_i915_private *dev_priv); void intel_gvt_clean_device(struct drm_i915_private *dev_priv); int intel_gvt_init_host(void); +void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv); #else static inline int intel_gvt_init(struct drm_i915_private *dev_priv) { @@ -40,6 +41,10 @@ static inline int intel_gvt_init(struct drm_i915_private *dev_priv) static inline void intel_gvt_cleanup(struct drm_i915_private *dev_priv) { } + +static inline void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv) +{ +} #endif #endif /* _INTEL_GVT_H_ */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 58d6903..ec0779a 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1218,7 +1218,8 @@ static int intel_hdmi_source_max_tmds_clock(struct drm_i915_private *dev_priv) } static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, - bool respect_downstream_limits) + bool respect_downstream_limits, + bool force_dvi) { struct drm_device *dev = intel_hdmi_to_dev(hdmi); int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev)); @@ -1234,7 +1235,7 @@ static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, if (info->max_tmds_clock) max_tmds_clock = min(max_tmds_clock, info->max_tmds_clock); - else if (!hdmi->has_hdmi_sink) + else if (!hdmi->has_hdmi_sink || force_dvi) max_tmds_clock = min(max_tmds_clock, 165000); } @@ -1243,13 +1244,14 @@ static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, static enum drm_mode_status hdmi_port_clock_valid(struct intel_hdmi *hdmi, - int clock, bool respect_downstream_limits) + int clock, bool respect_downstream_limits, + bool force_dvi) { struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); if (clock < 25000) return MODE_CLOCK_LOW; - if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits)) + if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits, force_dvi)) return MODE_CLOCK_HIGH; /* BXT DPLL can't generate 223-240 MHz */ @@ -1273,6 +1275,8 @@ intel_hdmi_mode_valid(struct drm_connector *connector, enum drm_mode_status status; int clock; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; + bool force_dvi = + READ_ONCE(to_intel_digital_connector_state(connector->state)->force_audio) == HDMI_AUDIO_OFF_DVI; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; @@ -1289,11 +1293,11 @@ intel_hdmi_mode_valid(struct drm_connector *connector, clock *= 2; /* check if we can do 8bpc */ - status = hdmi_port_clock_valid(hdmi, clock, true); + status = hdmi_port_clock_valid(hdmi, clock, true, force_dvi); /* if we can't do 8bpc we may still be able to do 12bpc */ - if (!HAS_GMCH_DISPLAY(dev_priv) && status != MODE_OK) - status = hdmi_port_clock_valid(hdmi, clock * 3 / 2, true); + if (!HAS_GMCH_DISPLAY(dev_priv) && status != MODE_OK && hdmi->has_hdmi_sink && !force_dvi) + status = hdmi_port_clock_valid(hdmi, clock * 3 / 2, true, force_dvi); return status; } @@ -1343,16 +1347,19 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; struct drm_scdc *scdc = &conn_state->connector->display_info.hdmi.scdc; + struct intel_digital_connector_state *intel_conn_state = + to_intel_digital_connector_state(conn_state); int clock_8bpc = pipe_config->base.adjusted_mode.crtc_clock; int clock_12bpc = clock_8bpc * 3 / 2; int desired_bpp; + bool force_dvi = intel_conn_state->force_audio == HDMI_AUDIO_OFF_DVI; - pipe_config->has_hdmi_sink = intel_hdmi->has_hdmi_sink; + pipe_config->has_hdmi_sink = !force_dvi && intel_hdmi->has_hdmi_sink; if (pipe_config->has_hdmi_sink) pipe_config->has_infoframe = true; - if (intel_hdmi->color_range_auto) { + if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { /* See CEA-861-E - 5.1 Default Encoding Parameters */ pipe_config->limited_color_range = pipe_config->has_hdmi_sink && @@ -1360,7 +1367,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, HDMI_QUANTIZATION_RANGE_LIMITED; } else { pipe_config->limited_color_range = - intel_hdmi->limited_color_range; + intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED; } if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) { @@ -1372,8 +1379,13 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv)) pipe_config->has_pch_encoder = true; - if (pipe_config->has_hdmi_sink && intel_hdmi->has_audio) - pipe_config->has_audio = true; + if (pipe_config->has_hdmi_sink) { + if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) + pipe_config->has_audio = intel_hdmi->has_audio; + else + pipe_config->has_audio = + intel_conn_state->force_audio == HDMI_AUDIO_ON; + } /* * HDMI is either 12 or 8, so if the display lets 10bpc sneak @@ -1381,8 +1393,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, * outputs. We also need to check that the higher clock still fits * within limits. */ - if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink && - hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true) == MODE_OK && + if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink && !force_dvi && + hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true, force_dvi) == MODE_OK && hdmi_12bpc_possible(pipe_config)) { DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); desired_bpp = 12*3; @@ -1402,7 +1414,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, } if (hdmi_port_clock_valid(intel_hdmi, pipe_config->port_clock, - false) != MODE_OK) { + false, force_dvi) != MODE_OK) { DRM_DEBUG_KMS("unsupported HDMI clock, rejecting mode\n"); return false; } @@ -1509,13 +1521,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) drm_rgb_quant_range_selectable(edid); intel_hdmi->has_audio = drm_detect_monitor_audio(edid); - if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO) - intel_hdmi->has_audio = - intel_hdmi->force_audio == HDMI_AUDIO_ON; - - if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) - intel_hdmi->has_hdmi_sink = - drm_detect_hdmi_monitor(edid); + intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); connected = true; } @@ -1577,96 +1583,6 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) return intel_connector_update_modes(connector, edid); } -static bool -intel_hdmi_detect_audio(struct drm_connector *connector) -{ - bool has_audio = false; - struct edid *edid; - - edid = to_intel_connector(connector)->detect_edid; - if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - - return has_audio; -} - -static int -intel_hdmi_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct intel_digital_port *intel_dig_port = - hdmi_to_dig_port(intel_hdmi); - struct drm_i915_private *dev_priv = to_i915(connector->dev); - int ret; - - ret = drm_object_property_set_value(&connector->base, property, val); - if (ret) - return ret; - - if (property == dev_priv->force_audio_property) { - enum hdmi_force_audio i = val; - bool has_audio; - - if (i == intel_hdmi->force_audio) - return 0; - - intel_hdmi->force_audio = i; - - if (i == HDMI_AUDIO_AUTO) - has_audio = intel_hdmi_detect_audio(connector); - else - has_audio = (i == HDMI_AUDIO_ON); - - if (i == HDMI_AUDIO_OFF_DVI) - intel_hdmi->has_hdmi_sink = 0; - - intel_hdmi->has_audio = has_audio; - goto done; - } - - if (property == dev_priv->broadcast_rgb_property) { - bool old_auto = intel_hdmi->color_range_auto; - bool old_range = intel_hdmi->limited_color_range; - - switch (val) { - case INTEL_BROADCAST_RGB_AUTO: - intel_hdmi->color_range_auto = true; - break; - case INTEL_BROADCAST_RGB_FULL: - intel_hdmi->color_range_auto = false; - intel_hdmi->limited_color_range = false; - break; - case INTEL_BROADCAST_RGB_LIMITED: - intel_hdmi->color_range_auto = false; - intel_hdmi->limited_color_range = true; - break; - default: - return -EINVAL; - } - - if (old_auto == intel_hdmi->color_range_auto && - old_range == intel_hdmi->limited_color_range) - return 0; - - goto done; - } - - if (property == connector->dev->mode_config.aspect_ratio_property) { - connector->state->picture_aspect_ratio = val; - goto done; - } - - return -EINVAL; - -done: - if (intel_dig_port->base.base.crtc) - intel_crtc_restore_mode(intel_dig_port->base.base.crtc); - - return 0; -} - static void intel_hdmi_pre_enable(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -1791,18 +1707,20 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = { .detect = intel_hdmi_detect, .force = intel_hdmi_force, .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_hdmi_set_property, - .atomic_get_property = intel_connector_atomic_get_property, + .set_property = drm_atomic_helper_connector_set_property, + .atomic_get_property = intel_digital_connector_atomic_get_property, + .atomic_set_property = intel_digital_connector_atomic_set_property, .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_hdmi_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { .get_modes = intel_hdmi_get_modes, .mode_valid = intel_hdmi_mode_valid, + .atomic_check = intel_digital_connector_atomic_check, }; static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { @@ -1814,7 +1732,6 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c { intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); - intel_hdmi->color_range_auto = true; intel_attach_aspect_ratio_property(connector); connector->state->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE; } @@ -1885,19 +1802,21 @@ static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv, switch (port) { case PORT_B: - if (IS_GEN9_LP(dev_priv)) + if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) ddc_pin = GMBUS_PIN_1_BXT; else ddc_pin = GMBUS_PIN_DPB; break; case PORT_C: - if (IS_GEN9_LP(dev_priv)) + if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) ddc_pin = GMBUS_PIN_2_BXT; else ddc_pin = GMBUS_PIN_DPC; break; case PORT_D: - if (IS_CHERRYVIEW(dev_priv)) + if (HAS_PCH_CNP(dev_priv)) + ddc_pin = GMBUS_PIN_4_CNP; + else if (IS_CHERRYVIEW(dev_priv)) ddc_pin = GMBUS_PIN_DPD_CHV; else ddc_pin = GMBUS_PIN_DPD; diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index f5eb18d0e..6145fa0 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c @@ -167,7 +167,7 @@ void intel_huc_select_fw(struct intel_huc *huc) huc->fw.path = I915_BXT_HUC_UCODE; huc->fw.major_ver_wanted = BXT_HUC_FW_MAJOR; huc->fw.minor_ver_wanted = BXT_HUC_FW_MINOR; - } else if (IS_KABYLAKE(dev_priv)) { + } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { huc->fw.path = I915_KBL_HUC_UCODE; huc->fw.major_ver_wanted = KBL_HUC_FW_MAJOR; huc->fw.minor_ver_wanted = KBL_HUC_FW_MINOR; diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index b6401e8..3c9e00d 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -68,11 +68,20 @@ static const struct gmbus_pin gmbus_pins_bxt[] = { [GMBUS_PIN_3_BXT] = { "misc", GPIOD }, }; +static const struct gmbus_pin gmbus_pins_cnp[] = { + [GMBUS_PIN_1_BXT] = { "dpb", GPIOB }, + [GMBUS_PIN_2_BXT] = { "dpc", GPIOC }, + [GMBUS_PIN_3_BXT] = { "misc", GPIOD }, + [GMBUS_PIN_4_CNP] = { "dpd", GPIOE }, +}; + /* pin is expected to be valid */ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv, unsigned int pin) { - if (IS_GEN9_LP(dev_priv)) + if (HAS_PCH_CNP(dev_priv)) + return &gmbus_pins_cnp[pin]; + else if (IS_GEN9_LP(dev_priv)) return &gmbus_pins_bxt[pin]; else if (IS_GEN9_BC(dev_priv)) return &gmbus_pins_skl[pin]; @@ -87,7 +96,9 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv, { unsigned int size; - if (IS_GEN9_LP(dev_priv)) + if (HAS_PCH_CNP(dev_priv)) + size = ARRAY_SIZE(gmbus_pins_cnp); + else if (IS_GEN9_LP(dev_priv)) size = ARRAY_SIZE(gmbus_pins_bxt); else if (IS_GEN9_BC(dev_priv)) size = ARRAY_SIZE(gmbus_pins_skl); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 014b30a..7404cf2 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -204,6 +204,7 @@ #define GEN8_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT 0x17 #define GEN9_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT 0x26 +#define GEN10_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT 0x19 /* Typical size of the average request (2 pipecontrols and a MI_BB) */ #define EXECLISTS_REQUEST_SIZE 64 /* bytes */ @@ -1861,6 +1862,10 @@ static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *engine) default: MISSING_CASE(INTEL_GEN(engine->i915)); /* fall through */ + case 10: + indirect_ctx_offset = + GEN10_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT; + break; case 9: indirect_ctx_offset = GEN9_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT; @@ -1957,6 +1962,8 @@ static void execlists_init_reg_state(u32 *regs, regs[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1); CTX_REG(regs, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE, make_rpcs(dev_priv)); + + i915_oa_init_reg_state(engine, ctx, regs); } } diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 8b942ef..6fe5d7c 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -311,8 +311,6 @@ static void intel_enable_lvds(struct intel_encoder *encoder, { struct drm_device *dev = encoder->base.dev; struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); - struct intel_connector *intel_connector = - &lvds_encoder->attached_connector->base; struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN); @@ -322,7 +320,7 @@ static void intel_enable_lvds(struct intel_encoder *encoder, if (intel_wait_for_register(dev_priv, PP_STATUS(0), PP_ON, PP_ON, 1000)) DRM_ERROR("timed out waiting for panel to power on\n"); - intel_panel_enable_backlight(intel_connector); + intel_panel_enable_backlight(pipe_config, conn_state); } static void intel_disable_lvds(struct intel_encoder *encoder, @@ -345,11 +343,7 @@ static void gmch_disable_lvds(struct intel_encoder *encoder, struct drm_connector_state *old_conn_state) { - struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); - struct intel_connector *intel_connector = - &lvds_encoder->attached_connector->base; - - intel_panel_disable_backlight(intel_connector); + intel_panel_disable_backlight(old_conn_state); intel_disable_lvds(encoder, old_crtc_state, old_conn_state); } @@ -358,11 +352,7 @@ static void pch_disable_lvds(struct intel_encoder *encoder, struct intel_crtc_state *old_crtc_state, struct drm_connector_state *old_conn_state) { - struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); - struct intel_connector *intel_connector = - &lvds_encoder->attached_connector->base; - - intel_panel_disable_backlight(intel_connector); + intel_panel_disable_backlight(old_conn_state); } static void pch_post_disable_lvds(struct intel_encoder *encoder, @@ -433,10 +423,10 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, pipe_config->has_pch_encoder = true; intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector->panel.fitting_mode); + conn_state->scaling_mode); } else { intel_gmch_panel_fitting(intel_crtc, pipe_config, - intel_connector->panel.fitting_mode); + conn_state->scaling_mode); } @@ -598,56 +588,24 @@ static void intel_lvds_destroy(struct drm_connector *connector) kfree(connector); } -static int intel_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct intel_connector *intel_connector = to_intel_connector(connector); - struct drm_device *dev = connector->dev; - - if (property == dev->mode_config.scaling_mode_property) { - struct drm_crtc *crtc; - - if (value == DRM_MODE_SCALE_NONE) { - DRM_DEBUG_KMS("no scaling not supported\n"); - return -EINVAL; - } - - if (intel_connector->panel.fitting_mode == value) { - /* the LVDS scaling property is not changed */ - return 0; - } - intel_connector->panel.fitting_mode = value; - - crtc = intel_attached_encoder(connector)->base.crtc; - if (crtc && crtc->state->enable) { - /* - * If the CRTC is enabled, the display will be changed - * according to the new panel fitting mode. - */ - intel_crtc_restore_mode(crtc); - } - } - - return 0; -} - static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { .get_modes = intel_lvds_get_modes, .mode_valid = intel_lvds_mode_valid, + .atomic_check = intel_digital_connector_atomic_check, }; static const struct drm_connector_funcs intel_lvds_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .detect = intel_lvds_detect, .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_lvds_set_property, - .atomic_get_property = intel_connector_atomic_get_property, + .set_property = drm_atomic_helper_connector_set_property, + .atomic_get_property = intel_digital_connector_atomic_get_property, + .atomic_set_property = intel_digital_connector_atomic_set_property, .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_lvds_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; static const struct drm_encoder_funcs intel_lvds_enc_funcs = { @@ -988,6 +946,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) u32 lvds; int pipe; u8 pin; + u32 allowed_scalers; if (!intel_lvds_supported(dev_priv)) return; @@ -1083,11 +1042,11 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) lvds_encoder->reg = lvds_reg; /* create the scaling mode property */ - drm_mode_create_scaling_mode_property(dev); - drm_object_attach_property(&connector->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_ASPECT); - intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT; + allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT); + allowed_scalers |= BIT(DRM_MODE_SCALE_FULLSCREEN); + allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER); + drm_connector_attach_scaling_mode_property(connector, allowed_scalers); + connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT; intel_lvds_pps_get_hw_state(dev_priv, &lvds_encoder->init_pps); lvds_encoder->init_lvds_val = lvds; diff --git a/drivers/gpu/drm/i915/intel_mocs.c b/drivers/gpu/drm/i915/intel_mocs.c index 92e461c..f4c46b0 100644 --- a/drivers/gpu/drm/i915/intel_mocs.c +++ b/drivers/gpu/drm/i915/intel_mocs.c @@ -178,7 +178,7 @@ static bool get_mocs_settings(struct drm_i915_private *dev_priv, { bool result = false; - if (IS_GEN9_BC(dev_priv)) { + if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { table->size = ARRAY_SIZE(skylake_mocs_table); table->table = skylake_mocs_table; result = true; diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index d444651..2bd0300 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -461,7 +461,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp) DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); drm_connector_list_iter_begin(dev, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) - intel_panel_set_backlight_acpi(connector, bclp, 255); + intel_panel_set_backlight_acpi(connector->base.state, bclp, 255); drm_connector_list_iter_end(&conn_iter); asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 2e0c56e..b96aed9 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -270,7 +270,6 @@ static int intel_overlay_on(struct intel_overlay *overlay) u32 *cs; WARN_ON(overlay->active); - WARN_ON(IS_I830(dev_priv) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); req = alloc_request(overlay); if (IS_ERR(req)) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index c8103f8..96c2cbd 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -561,15 +561,18 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector) return val; } -static void lpt_set_backlight(struct intel_connector *connector, u32 level) +static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; I915_WRITE(BLC_PWM_PCH_CTL2, val | level); } -static void pch_set_backlight(struct intel_connector *connector, u32 level) +static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); u32 tmp; @@ -577,8 +580,9 @@ static void pch_set_backlight(struct intel_connector *connector, u32 level) I915_WRITE(BLC_PWM_CPU_CTL, tmp | level); } -static void i9xx_set_backlight(struct intel_connector *connector, u32 level) +static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 tmp, mask; @@ -604,50 +608,51 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level) I915_WRITE(BLC_PWM_CTL, tmp | level); } -static void vlv_set_backlight(struct intel_connector *connector, u32 level) +static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - enum pipe pipe = intel_get_pipe_from_connector(connector); + enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; u32 tmp; - if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) - return; - tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); } -static void bxt_set_backlight(struct intel_connector *connector, u32 level) +static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level); } -static void pwm_set_backlight(struct intel_connector *connector, u32 level) +static void pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) { - struct intel_panel *panel = &connector->panel; + struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel; int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100); pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS); } static void -intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) +intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_panel *panel = &connector->panel; DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); level = intel_panel_compute_brightness(connector, level); - panel->backlight.set(connector, level); + panel->backlight.set(conn_state, level); } /* set backlight brightness to level in range [0..max], scaling wrt hw min */ -static void intel_panel_set_backlight(struct intel_connector *connector, +static void intel_panel_set_backlight(const struct drm_connector_state *conn_state, u32 user_level, u32 user_max) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 hw_level; @@ -663,7 +668,7 @@ static void intel_panel_set_backlight(struct intel_connector *connector, panel->backlight.level = hw_level; if (panel->backlight.enabled) - intel_panel_actually_set_backlight(connector, hw_level); + intel_panel_actually_set_backlight(conn_state, hw_level); mutex_unlock(&dev_priv->backlight_lock); } @@ -671,21 +676,21 @@ static void intel_panel_set_backlight(struct intel_connector *connector, /* set backlight brightness to level in range [0..max], assuming hw min is * respected. */ -void intel_panel_set_backlight_acpi(struct intel_connector *connector, +void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, u32 user_level, u32 user_max) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); u32 hw_level; /* - * INVALID_PIPE may occur during driver init because + * Lack of crtc may occur during driver init because * connection_mutex isn't held across the entire backlight * setup + modeset readout, and the BIOS can issue the * requests at any time. */ - if (!panel->backlight.present || pipe == INVALID_PIPE) + if (!panel->backlight.present || !conn_state->crtc) return; mutex_lock(&dev_priv->backlight_lock); @@ -702,17 +707,18 @@ void intel_panel_set_backlight_acpi(struct intel_connector *connector, panel->backlight.device->props.max_brightness); if (panel->backlight.enabled) - intel_panel_actually_set_backlight(connector, hw_level); + intel_panel_actually_set_backlight(conn_state, hw_level); mutex_unlock(&dev_priv->backlight_lock); } -static void lpt_disable_backlight(struct intel_connector *connector) +static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state) { + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); u32 tmp; - intel_panel_actually_set_backlight(connector, 0); + intel_panel_actually_set_backlight(old_conn_state, 0); /* * Although we don't support or enable CPU PWM with LPT/SPT based @@ -732,12 +738,13 @@ static void lpt_disable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); } -static void pch_disable_backlight(struct intel_connector *connector) +static void pch_disable_backlight(const struct drm_connector_state *old_conn_state) { + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); u32 tmp; - intel_panel_actually_set_backlight(connector, 0); + intel_panel_actually_set_backlight(old_conn_state, 0); tmp = I915_READ(BLC_PWM_CPU_CTL2); I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); @@ -746,44 +753,43 @@ static void pch_disable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); } -static void i9xx_disable_backlight(struct intel_connector *connector) +static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state) { - intel_panel_actually_set_backlight(connector, 0); + intel_panel_actually_set_backlight(old_conn_state, 0); } -static void i965_disable_backlight(struct intel_connector *connector) +static void i965_disable_backlight(const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev); u32 tmp; - intel_panel_actually_set_backlight(connector, 0); + intel_panel_actually_set_backlight(old_conn_state, 0); tmp = I915_READ(BLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); } -static void vlv_disable_backlight(struct intel_connector *connector) +static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state) { + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - enum pipe pipe = intel_get_pipe_from_connector(connector); + enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe; u32 tmp; - if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) - return; - - intel_panel_actually_set_backlight(connector, 0); + intel_panel_actually_set_backlight(old_conn_state, 0); tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE); } -static void bxt_disable_backlight(struct intel_connector *connector) +static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state) { + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 tmp, val; - intel_panel_actually_set_backlight(connector, 0); + intel_panel_actually_set_backlight(old_conn_state, 0); tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), @@ -796,8 +802,23 @@ static void bxt_disable_backlight(struct intel_connector *connector) } } -static void pwm_disable_backlight(struct intel_connector *connector) +static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state) { + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 tmp; + + intel_panel_actually_set_backlight(old_conn_state, 0); + + tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); + I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), + tmp & ~BXT_BLC_PWM_ENABLE); +} + +static void pwm_disable_backlight(const struct drm_connector_state *old_conn_state) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct intel_panel *panel = &connector->panel; /* Disable the backlight */ @@ -806,8 +827,9 @@ static void pwm_disable_backlight(struct intel_connector *connector) pwm_disable(panel->backlight.pwm); } -void intel_panel_disable_backlight(struct intel_connector *connector) +void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state) { + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; @@ -830,13 +852,15 @@ void intel_panel_disable_backlight(struct intel_connector *connector) if (panel->backlight.device) panel->backlight.device->props.power = FB_BLANK_POWERDOWN; panel->backlight.enabled = false; - panel->backlight.disable(connector); + panel->backlight.disable(old_conn_state); mutex_unlock(&dev_priv->backlight_lock); } -static void lpt_enable_backlight(struct intel_connector *connector) +static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 pch_ctl1, pch_ctl2, schicken; @@ -880,22 +904,18 @@ static void lpt_enable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); /* This won't stick until the above enable. */ - intel_panel_actually_set_backlight(connector, panel->backlight.level); + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); } -static void pch_enable_backlight(struct intel_connector *connector) +static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); - enum transcoder cpu_transcoder; + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 cpu_ctl2, pch_ctl1, pch_ctl2; - if (!WARN_ON_ONCE(pipe == INVALID_PIPE)) - cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); - else - cpu_transcoder = TRANSCODER_EDP; - cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); if (cpu_ctl2 & BLM_PWM_ENABLE) { DRM_DEBUG_KMS("cpu backlight already enabled\n"); @@ -919,7 +939,7 @@ static void pch_enable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); /* This won't stick until the above enable. */ - intel_panel_actually_set_backlight(connector, panel->backlight.level); + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); pch_ctl2 = panel->backlight.max << 16; I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); @@ -933,8 +953,10 @@ static void pch_enable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); } -static void i9xx_enable_backlight(struct intel_connector *connector) +static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 ctl, freq; @@ -959,7 +981,7 @@ static void i9xx_enable_backlight(struct intel_connector *connector) POSTING_READ(BLC_PWM_CTL); /* XXX: combine this into above write? */ - intel_panel_actually_set_backlight(connector, panel->backlight.level); + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); /* * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is @@ -970,16 +992,15 @@ static void i9xx_enable_backlight(struct intel_connector *connector) I915_WRITE(BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); } -static void i965_enable_backlight(struct intel_connector *connector) +static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); + enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; u32 ctl, ctl2, freq; - if (WARN_ON_ONCE(pipe == INVALID_PIPE)) - pipe = PIPE_A; - ctl2 = I915_READ(BLC_PWM_CTL2); if (ctl2 & BLM_PWM_ENABLE) { DRM_DEBUG_KMS("backlight already enabled\n"); @@ -1003,19 +1024,18 @@ static void i965_enable_backlight(struct intel_connector *connector) POSTING_READ(BLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); - intel_panel_actually_set_backlight(connector, panel->backlight.level); + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); } -static void vlv_enable_backlight(struct intel_connector *connector) +static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); + enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe; u32 ctl, ctl2; - if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) - return; - ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); if (ctl2 & BLM_PWM_ENABLE) { DRM_DEBUG_KMS("backlight already enabled\n"); @@ -1027,7 +1047,7 @@ static void vlv_enable_backlight(struct intel_connector *connector) I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl); /* XXX: combine this into above write? */ - intel_panel_actually_set_backlight(connector, panel->backlight.level); + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); ctl2 = 0; if (panel->backlight.active_low_pwm) @@ -1037,16 +1057,15 @@ static void vlv_enable_backlight(struct intel_connector *connector) I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); } -static void bxt_enable_backlight(struct intel_connector *connector) +static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); + enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe; u32 pwm_ctl, val; - if (WARN_ON_ONCE(pipe == INVALID_PIPE)) - pipe = PIPE_A; - /* Controller 1 uses the utility pin. */ if (panel->backlight.controller == 1) { val = I915_READ(UTIL_PIN_CTL); @@ -1074,7 +1093,7 @@ static void bxt_enable_backlight(struct intel_connector *connector) I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller), panel->backlight.max); - intel_panel_actually_set_backlight(connector, panel->backlight.level); + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); pwm_ctl = 0; if (panel->backlight.active_low_pwm) @@ -1086,25 +1105,59 @@ static void bxt_enable_backlight(struct intel_connector *connector) pwm_ctl | BXT_BLC_PWM_ENABLE); } -static void pwm_enable_backlight(struct intel_connector *connector) +static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pwm_ctl; + + pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); + if (pwm_ctl & BXT_BLC_PWM_ENABLE) { + DRM_DEBUG_KMS("backlight already enabled\n"); + pwm_ctl &= ~BXT_BLC_PWM_ENABLE; + I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl); + } + + I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller), + panel->backlight.max); + + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); + + pwm_ctl = 0; + if (panel->backlight.active_low_pwm) + pwm_ctl |= BXT_BLC_PWM_POLARITY; + + I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); + POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); + I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl | BXT_BLC_PWM_ENABLE); +} + +static void pwm_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_panel *panel = &connector->panel; pwm_enable(panel->backlight.pwm); - intel_panel_actually_set_backlight(connector, panel->backlight.level); + intel_panel_actually_set_backlight(conn_state, panel->backlight.level); } -void intel_panel_enable_backlight(struct intel_connector *connector) +void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { + struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); + enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe; if (!panel->backlight.present) return; - if (!WARN_ON_ONCE(pipe == INVALID_PIPE)) - DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); + DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); mutex_lock(&dev_priv->backlight_lock); @@ -1119,7 +1172,7 @@ void intel_panel_enable_backlight(struct intel_connector *connector) panel->backlight.device->props.max_brightness); } - panel->backlight.enable(connector); + panel->backlight.enable(crtc_state, conn_state); panel->backlight.enabled = true; if (panel->backlight.device) panel->backlight.device->props.power = FB_BLANK_UNBLANK; @@ -1137,7 +1190,7 @@ static int intel_backlight_device_update_status(struct backlight_device *bd) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", bd->props.brightness, bd->props.max_brightness); - intel_panel_set_backlight(connector, bd->props.brightness, + intel_panel_set_backlight(connector->base.state, bd->props.brightness, bd->props.max_brightness); /* @@ -1250,6 +1303,17 @@ void intel_backlight_device_unregister(struct intel_connector *connector) #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ /* + * CNP: PWM clock frequency is 19.2 MHz or 24 MHz. + * PWM increment = 1 + */ +static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz); +} + +/* * BXT: PWM clock frequency = 19.2 MHz. */ static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) @@ -1644,6 +1708,42 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) return 0; } +static int +cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pwm_ctl, val; + + /* + * CNP has the BXT implementation of backlight, but with only + * one controller. Future platforms could have multiple controllers + * so let's make this extensible and prepared for the future. + */ + panel->backlight.controller = 0; + + pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); + + panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; + panel->backlight.max = + I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller)); + + if (!panel->backlight.max) + panel->backlight.max = get_backlight_max_vbt(connector); + + if (!panel->backlight.max) + return -ENODEV; + + val = bxt_get_backlight(connector); + val = intel_panel_compute_brightness(connector, val); + panel->backlight.level = clamp(val, panel->backlight.min, + panel->backlight.max); + + panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; + + return 0; +} + static int pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) { @@ -1760,6 +1860,13 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel) panel->backlight.set = bxt_set_backlight; panel->backlight.get = bxt_get_backlight; panel->backlight.hz_to_pwm = bxt_hz_to_pwm; + } else if (HAS_PCH_CNP(dev_priv)) { + panel->backlight.setup = cnp_setup_backlight; + panel->backlight.enable = cnp_enable_backlight; + panel->backlight.disable = cnp_disable_backlight; + panel->backlight.set = bxt_set_backlight; + panel->backlight.get = bxt_get_backlight; + panel->backlight.hz_to_pwm = cnp_hz_to_pwm; } else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv)) { panel->backlight.setup = lpt_setup_backlight; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f2c1d03..48ea0fc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -58,24 +58,24 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) { - /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl */ + /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ I915_WRITE(CHICKEN_PAR1_1, I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); I915_WRITE(GEN8_CONFIG0, I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES); - /* WaEnableChickenDCPR:skl,bxt,kbl,glk */ + /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); - /* WaFbcTurnOffFbcWatermark:skl,bxt,kbl */ - /* WaFbcWakeMemOn:skl,bxt,kbl,glk */ + /* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */ + /* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */ I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS | DISP_FBC_MEMORY_WAKE); - /* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl */ + /* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */ I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | ILK_DPFC_DISABLE_DUMMY0); } @@ -3549,7 +3549,7 @@ static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state) static bool intel_has_sagv(struct drm_i915_private *dev_priv) { - if (IS_KABYLAKE(dev_priv)) + if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) return true; if (IS_SKYLAKE(dev_priv) && @@ -3869,6 +3869,97 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate, return mul_fixed16(downscale_w, downscale_h); } +static uint_fixed_16_16_t +skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state) +{ + uint_fixed_16_16_t pipe_downscale = u32_to_fixed_16_16(1); + + if (!crtc_state->base.enable) + return pipe_downscale; + + if (crtc_state->pch_pfit.enabled) { + uint32_t src_w, src_h, dst_w, dst_h; + uint32_t pfit_size = crtc_state->pch_pfit.size; + uint_fixed_16_16_t fp_w_ratio, fp_h_ratio; + uint_fixed_16_16_t downscale_h, downscale_w; + + src_w = crtc_state->pipe_src_w; + src_h = crtc_state->pipe_src_h; + dst_w = pfit_size >> 16; + dst_h = pfit_size & 0xffff; + + if (!dst_w || !dst_h) + return pipe_downscale; + + fp_w_ratio = fixed_16_16_div(src_w, dst_w); + fp_h_ratio = fixed_16_16_div(src_h, dst_h); + downscale_w = max_fixed_16_16(fp_w_ratio, u32_to_fixed_16_16(1)); + downscale_h = max_fixed_16_16(fp_h_ratio, u32_to_fixed_16_16(1)); + + pipe_downscale = mul_fixed16(downscale_w, downscale_h); + } + + return pipe_downscale; +} + +int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, + struct intel_crtc_state *cstate) +{ + struct drm_crtc_state *crtc_state = &cstate->base; + struct drm_atomic_state *state = crtc_state->state; + struct drm_plane *plane; + const struct drm_plane_state *pstate; + struct intel_plane_state *intel_pstate; + int crtc_clock, dotclk; + uint32_t pipe_max_pixel_rate; + uint_fixed_16_16_t pipe_downscale; + uint_fixed_16_16_t max_downscale = u32_to_fixed_16_16(1); + + if (!cstate->base.enable) + return 0; + + drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { + uint_fixed_16_16_t plane_downscale; + uint_fixed_16_16_t fp_9_div_8 = fixed_16_16_div(9, 8); + int bpp; + + if (!intel_wm_plane_visible(cstate, + to_intel_plane_state(pstate))) + continue; + + if (WARN_ON(!pstate->fb)) + return -EINVAL; + + intel_pstate = to_intel_plane_state(pstate); + plane_downscale = skl_plane_downscale_amount(cstate, + intel_pstate); + bpp = pstate->fb->format->cpp[0] * 8; + if (bpp == 64) + plane_downscale = mul_fixed16(plane_downscale, + fp_9_div_8); + + max_downscale = max_fixed_16_16(plane_downscale, max_downscale); + } + pipe_downscale = skl_pipe_downscale_amount(cstate); + + pipe_downscale = mul_fixed16(pipe_downscale, max_downscale); + + crtc_clock = crtc_state->adjusted_mode.crtc_clock; + dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk; + + if (IS_GEMINILAKE(to_i915(intel_crtc->base.dev))) + dotclk *= 2; + + pipe_max_pixel_rate = div_round_up_u32_fixed16(dotclk, pipe_downscale); + + if (pipe_max_pixel_rate < crtc_clock) { + DRM_DEBUG_KMS("Max supported pixel clock with scaling exceeded\n"); + return -EINVAL; + } + + return 0; +} + static unsigned int skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, const struct drm_plane_state *pstate, @@ -4289,8 +4380,9 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, fb->modifier == I915_FORMAT_MOD_Yf_TILED; x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED; - /* Display WA #1141: kbl. */ - if (IS_KABYLAKE(dev_priv) && dev_priv->ipc_enabled) + /* Display WA #1141: kbl,cfl */ + if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && + dev_priv->ipc_enabled) latency += 4; if (apply_memory_bw_wa && x_tiled) @@ -8160,7 +8252,7 @@ static void kabylake_init_clock_gating(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | GEN6_GAMUNIT_CLOCK_GATE_DISABLE); - /* WaFbcNukeOnHostModify:kbl */ + /* WaFbcNukeOnHostModify:kbl,cfl */ I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); } @@ -8628,7 +8720,7 @@ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) { if (IS_SKYLAKE(dev_priv)) dev_priv->display.init_clock_gating = skylake_init_clock_gating; - else if (IS_KABYLAKE(dev_priv)) + else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) dev_priv->display.init_clock_gating = kabylake_init_clock_gating; else if (IS_BROXTON(dev_priv)) dev_priv->display.init_clock_gating = bxt_init_clock_gating; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index f8a375f..efe80ed 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -494,6 +494,55 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, BIT_ULL(POWER_DOMAIN_AUX_A) | \ BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \ + BIT_ULL(POWER_DOMAIN_PIPE_B) | \ + BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \ + BIT_ULL(POWER_DOMAIN_PIPE_C) | \ + BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \ + BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \ + BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \ + BIT_ULL(POWER_DOMAIN_AUX_B) | \ + BIT_ULL(POWER_DOMAIN_AUX_C) | \ + BIT_ULL(POWER_DOMAIN_AUX_D) | \ + BIT_ULL(POWER_DOMAIN_AUDIO) | \ + BIT_ULL(POWER_DOMAIN_VGA) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_AUX_A_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_A) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_AUX_B_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_B) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_AUX_C_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_C) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_AUX_D_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_D) | \ + BIT_ULL(POWER_DOMAIN_INIT)) +#define CNL_DISPLAY_DC_OFF_POWER_DOMAINS ( \ + CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ + BIT_ULL(POWER_DOMAIN_MODESET) | \ + BIT_ULL(POWER_DOMAIN_AUX_A) | \ + BIT_ULL(POWER_DOMAIN_INIT)) + static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) { WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9), @@ -762,13 +811,14 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, } break; case SKL_DISP_PW_MISC_IO: - case SKL_DISP_PW_DDI_A_E: /* GLK_DISP_PW_DDI_A */ + case SKL_DISP_PW_DDI_A_E: /* GLK_DISP_PW_DDI_A, CNL_DISP_PW_DDI_A */ case SKL_DISP_PW_DDI_B: case SKL_DISP_PW_DDI_C: case SKL_DISP_PW_DDI_D: - case GLK_DISP_PW_AUX_A: - case GLK_DISP_PW_AUX_B: - case GLK_DISP_PW_AUX_C: + case GLK_DISP_PW_AUX_A: /* CNL_DISP_PW_AUX_A */ + case GLK_DISP_PW_AUX_B: /* CNL_DISP_PW_AUX_B */ + case GLK_DISP_PW_AUX_C: /* CNL_DISP_PW_AUX_C */ + case CNL_DISP_PW_AUX_D: break; default: WARN(1, "Unknown power well %lu\n", power_well->id); @@ -803,8 +853,7 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("Disabling %s\n", power_well->name); } - if (IS_GEN9(dev_priv)) - gen9_sanitize_power_well_requests(dev_priv, power_well); + gen9_sanitize_power_well_requests(dev_priv, power_well); } if (wait_for(!!(I915_READ(HSW_PWR_WELL_DRIVER) & state_mask) == enable, @@ -992,6 +1041,38 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, return true; } +static void i830_pipes_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + if ((I915_READ(PIPECONF(PIPE_A)) & PIPECONF_ENABLE) == 0) + i830_enable_pipe(dev_priv, PIPE_A); + if ((I915_READ(PIPECONF(PIPE_B)) & PIPECONF_ENABLE) == 0) + i830_enable_pipe(dev_priv, PIPE_B); +} + +static void i830_pipes_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + i830_disable_pipe(dev_priv, PIPE_B); + i830_disable_pipe(dev_priv, PIPE_A); +} + +static bool i830_pipes_power_well_enabled(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + return I915_READ(PIPECONF(PIPE_A)) & PIPECONF_ENABLE && + I915_READ(PIPECONF(PIPE_B)) & PIPECONF_ENABLE; +} + +static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + if (power_well->count > 0) + i830_pipes_power_well_enable(dev_priv, power_well); + else + i830_pipes_power_well_disable(dev_priv, power_well); +} + static void vlv_set_power_well(struct drm_i915_private *dev_priv, struct i915_power_well *power_well, bool enable) { @@ -1880,6 +1961,15 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, BIT_ULL(POWER_DOMAIN_AUX_D) | \ BIT_ULL(POWER_DOMAIN_INIT)) +#define I830_PIPES_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PIPE_A) | \ + BIT_ULL(POWER_DOMAIN_PIPE_B) | \ + BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \ + BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \ + BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \ + BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \ + BIT_ULL(POWER_DOMAIN_INIT)) + static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { .sync_hw = i9xx_power_well_sync_hw_noop, .enable = i9xx_always_on_power_well_noop, @@ -1910,6 +2000,27 @@ static struct i915_power_well i9xx_always_on_power_well[] = { }, }; +static const struct i915_power_well_ops i830_pipes_power_well_ops = { + .sync_hw = i830_pipes_power_well_sync_hw, + .enable = i830_pipes_power_well_enable, + .disable = i830_pipes_power_well_disable, + .is_enabled = i830_pipes_power_well_enabled, +}; + +static struct i915_power_well i830_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = POWER_DOMAIN_MASK, + .ops = &i9xx_always_on_power_well_ops, + }, + { + .name = "pipes", + .domains = I830_PIPES_POWER_DOMAINS, + .ops = &i830_pipes_power_well_ops, + }, +}; + static const struct i915_power_well_ops hsw_power_well_ops = { .sync_hw = hsw_power_well_sync_hw, .enable = hsw_power_well_enable, @@ -2275,6 +2386,82 @@ static struct i915_power_well glk_power_wells[] = { }, }; +static struct i915_power_well cnl_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = POWER_DOMAIN_MASK, + .ops = &i9xx_always_on_power_well_ops, + }, + { + .name = "power well 1", + /* Handled by the DMC firmware */ + .domains = 0, + .ops = &skl_power_well_ops, + .id = SKL_DISP_PW_1, + }, + { + .name = "AUX A", + .domains = CNL_DISPLAY_AUX_A_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = CNL_DISP_PW_AUX_A, + }, + { + .name = "AUX B", + .domains = CNL_DISPLAY_AUX_B_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = CNL_DISP_PW_AUX_B, + }, + { + .name = "AUX C", + .domains = CNL_DISPLAY_AUX_C_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = CNL_DISP_PW_AUX_C, + }, + { + .name = "AUX D", + .domains = CNL_DISPLAY_AUX_D_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = CNL_DISP_PW_AUX_D, + }, + { + .name = "DC off", + .domains = CNL_DISPLAY_DC_OFF_POWER_DOMAINS, + .ops = &gen9_dc_off_power_well_ops, + .id = SKL_DISP_PW_DC_OFF, + }, + { + .name = "power well 2", + .domains = CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = SKL_DISP_PW_2, + }, + { + .name = "DDI A IO power well", + .domains = CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = CNL_DISP_PW_DDI_A, + }, + { + .name = "DDI B IO power well", + .domains = CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = SKL_DISP_PW_DDI_B, + }, + { + .name = "DDI C IO power well", + .domains = CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = SKL_DISP_PW_DDI_C, + }, + { + .name = "DDI D IO power well", + .domains = CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .id = SKL_DISP_PW_DDI_D, + }, +}; + static int sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv, int disable_power_well) @@ -2369,6 +2556,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) set_power_wells(power_domains, bdw_power_wells); } else if (IS_GEN9_BC(dev_priv)) { set_power_wells(power_domains, skl_power_wells); + } else if (IS_CANNONLAKE(dev_priv)) { + set_power_wells(power_domains, cnl_power_wells); } else if (IS_BROXTON(dev_priv)) { set_power_wells(power_domains, bxt_power_wells); } else if (IS_GEMINILAKE(dev_priv)) { @@ -2377,6 +2566,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) set_power_wells(power_domains, chv_power_wells); } else if (IS_VALLEYVIEW(dev_priv)) { set_power_wells(power_domains, vlv_power_wells); + } else if (IS_I830(dev_priv)) { + set_power_wells(power_domains, i830_power_wells); } else { set_power_wells(power_domains, i9xx_always_on_power_well); } @@ -2569,6 +2760,111 @@ void bxt_display_core_uninit(struct drm_i915_private *dev_priv) mutex_unlock(&power_domains->lock); } +#define CNL_PROCMON_IDX(val) \ + (((val) & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) >> VOLTAGE_INFO_SHIFT) +#define NUM_CNL_PROCMON \ + (CNL_PROCMON_IDX(VOLTAGE_INFO_MASK | PROCESS_INFO_MASK) + 1) + +static const struct cnl_procmon { + u32 dw1, dw9, dw10; +} cnl_procmon_values[NUM_CNL_PROCMON] = { + [CNL_PROCMON_IDX(VOLTAGE_INFO_0_85V | PROCESS_INFO_DOT_0)] = + { .dw1 = 0x00 << 16, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96, }, + [CNL_PROCMON_IDX(VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_0)] = + { .dw1 = 0x00 << 16, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB, }, + [CNL_PROCMON_IDX(VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_1)] = + { .dw1 = 0x00 << 16, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5, }, + [CNL_PROCMON_IDX(VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_0)] = + { .dw1 = 0x00 << 16, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1, }, + [CNL_PROCMON_IDX(VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_1)] = + { .dw1 = 0x44 << 16, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1, }, +}; + +static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume) +{ + struct i915_power_domains *power_domains = &dev_priv->power_domains; + const struct cnl_procmon *procmon; + struct i915_power_well *well; + u32 val; + + gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + + /* 1. Enable PCH Reset Handshake */ + val = I915_READ(HSW_NDE_RSTWRN_OPT); + val |= RESET_PCH_HANDSHAKE_ENABLE; + I915_WRITE(HSW_NDE_RSTWRN_OPT, val); + + /* 2. Enable Comp */ + val = I915_READ(CHICKEN_MISC_2); + val &= ~COMP_PWR_DOWN; + I915_WRITE(CHICKEN_MISC_2, val); + + val = I915_READ(CNL_PORT_COMP_DW3); + procmon = &cnl_procmon_values[CNL_PROCMON_IDX(val)]; + + WARN_ON(procmon->dw10 == 0); + + val = I915_READ(CNL_PORT_COMP_DW1); + val &= ~((0xff << 16) | 0xff); + val |= procmon->dw1; + I915_WRITE(CNL_PORT_COMP_DW1, val); + + I915_WRITE(CNL_PORT_COMP_DW9, procmon->dw9); + I915_WRITE(CNL_PORT_COMP_DW10, procmon->dw10); + + val = I915_READ(CNL_PORT_COMP_DW0); + val |= COMP_INIT; + I915_WRITE(CNL_PORT_COMP_DW0, val); + + /* 3. */ + val = I915_READ(CNL_PORT_CL1CM_DW5); + val |= CL_POWER_DOWN_ENABLE; + I915_WRITE(CNL_PORT_CL1CM_DW5, val); + + /* 4. Enable Power Well 1 (PG1) and Aux IO Power */ + mutex_lock(&power_domains->lock); + well = lookup_power_well(dev_priv, SKL_DISP_PW_1); + intel_power_well_enable(dev_priv, well); + mutex_unlock(&power_domains->lock); + + /* 5. Enable CD clock */ + cnl_init_cdclk(dev_priv); + + /* 6. Enable DBUF */ + gen9_dbuf_enable(dev_priv); +} + +#undef CNL_PROCMON_IDX +#undef NUM_CNL_PROCMON + +static void cnl_display_core_uninit(struct drm_i915_private *dev_priv) +{ + struct i915_power_domains *power_domains = &dev_priv->power_domains; + struct i915_power_well *well; + u32 val; + + gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + + /* 1. Disable all display engine functions -> aready done */ + + /* 2. Disable DBUF */ + gen9_dbuf_disable(dev_priv); + + /* 3. Disable CD clock */ + cnl_uninit_cdclk(dev_priv); + + /* 4. Disable Power Well 1 (PG1) and Aux IO Power */ + mutex_lock(&power_domains->lock); + well = lookup_power_well(dev_priv, SKL_DISP_PW_1); + intel_power_well_disable(dev_priv, well); + mutex_unlock(&power_domains->lock); + + /* 5. Disable Comp */ + val = I915_READ(CHICKEN_MISC_2); + val |= COMP_PWR_DOWN; + I915_WRITE(CHICKEN_MISC_2, val); +} + static void chv_phy_control_init(struct drm_i915_private *dev_priv) { struct i915_power_well *cmn_bc = @@ -2701,7 +2997,9 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) power_domains->initializing = true; - if (IS_GEN9_BC(dev_priv)) { + if (IS_CANNONLAKE(dev_priv)) { + cnl_display_core_init(dev_priv, resume); + } else if (IS_GEN9_BC(dev_priv)) { skl_display_core_init(dev_priv, resume); } else if (IS_GEN9_LP(dev_priv)) { bxt_display_core_init(dev_priv, resume); @@ -2740,7 +3038,9 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv) if (!i915.disable_power_well) intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); - if (IS_GEN9_BC(dev_priv)) + if (IS_CANNONLAKE(dev_priv)) + cnl_display_core_uninit(dev_priv); + else if (IS_GEN9_BC(dev_priv)) skl_display_core_uninit(dev_priv); else if (IS_GEN9_LP(dev_priv)) bxt_display_core_uninit(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 6cc1812..3f8f30b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -100,13 +100,6 @@ struct intel_sdvo { uint16_t hotplug_active; /** - * This is used to select the color range of RBG outputs in HDMI mode. - * It is only valid when using TMDS encoding and 8 bit per color mode. - */ - uint32_t color_range; - bool color_range_auto; - - /** * This is set if we're going to treat the device as TV-out. * * While we have these nice friendly flags for output types that ought @@ -117,9 +110,6 @@ struct intel_sdvo { enum port port; - /* This is for current tv format name */ - int tv_format_index; - /** * This is set if we treat the device as HDMI, instead of DVI. */ @@ -154,8 +144,6 @@ struct intel_sdvo_connector { /* Mark the type of connector */ uint16_t output_flag; - enum hdmi_force_audio force_audio; - /* This contains all current supported TV format */ u8 tv_format_supported[TV_FORMAT_NUM]; int format_supported_num; @@ -182,24 +170,19 @@ struct intel_sdvo_connector { /* add the property for the SDVO-TV/LVDS */ struct drm_property *brightness; - /* Add variable to record current setting for the above property */ - u32 left_margin, right_margin, top_margin, bottom_margin; - /* this is to get the range of margin.*/ - u32 max_hscan, max_vscan; - u32 max_hpos, cur_hpos; - u32 max_vpos, cur_vpos; - u32 cur_brightness, max_brightness; - u32 cur_contrast, max_contrast; - u32 cur_saturation, max_saturation; - u32 cur_hue, max_hue; - u32 cur_sharpness, max_sharpness; - u32 cur_flicker_filter, max_flicker_filter; - u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; - u32 cur_flicker_filter_2d, max_flicker_filter_2d; - u32 cur_tv_chroma_filter, max_tv_chroma_filter; - u32 cur_tv_luma_filter, max_tv_luma_filter; - u32 cur_dot_crawl, max_dot_crawl; + u32 max_hscan, max_vscan; +}; + +struct intel_sdvo_connector_state { + /* base.base: tv.saturation/contrast/hue/brightness */ + struct intel_digital_connector_state base; + + struct { + unsigned overscan_h, overscan_v, hpos, vpos, sharpness; + unsigned flicker_filter, flicker_filter_2d, flicker_filter_adaptive; + unsigned chroma_filter, luma_filter, dot_crawl; + } tv; }; static struct intel_sdvo *to_sdvo(struct intel_encoder *encoder) @@ -212,9 +195,16 @@ static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) return to_sdvo(intel_attached_encoder(connector)); } -static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) +static struct intel_sdvo_connector * +to_intel_sdvo_connector(struct drm_connector *connector) { - return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base); + return container_of(connector, struct intel_sdvo_connector, base.base); +} + +static struct intel_sdvo_connector_state * +to_intel_sdvo_connector_state(struct drm_connector_state *conn_state) +{ + return container_of(conn_state, struct intel_sdvo_connector_state, base.base); } static bool @@ -1030,12 +1020,13 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, sdvo_data, sizeof(sdvo_data)); } -static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) +static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo, + struct drm_connector_state *conn_state) { struct intel_sdvo_tv_format format; uint32_t format_map; - format_map = 1 << intel_sdvo->tv_format_index; + format_map = 1 << conn_state->tv.mode; memset(&format, 0, sizeof(format)); memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); @@ -1122,6 +1113,8 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct intel_sdvo *intel_sdvo = to_sdvo(encoder); + struct intel_sdvo_connector_state *intel_sdvo_state = + to_intel_sdvo_connector_state(conn_state); struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; struct drm_display_mode *mode = &pipe_config->base.mode; @@ -1160,9 +1153,14 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, pipe_config->pixel_multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode); - pipe_config->has_hdmi_sink = intel_sdvo->has_hdmi_monitor; + if (intel_sdvo_state->base.force_audio != HDMI_AUDIO_OFF_DVI) + pipe_config->has_hdmi_sink = intel_sdvo->has_hdmi_monitor; + + if (intel_sdvo_state->base.force_audio == HDMI_AUDIO_ON || + (intel_sdvo_state->base.force_audio == HDMI_AUDIO_AUTO && intel_sdvo->has_hdmi_audio)) + pipe_config->has_audio = true; - if (intel_sdvo->color_range_auto) { + if (intel_sdvo_state->base.broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { /* See CEA-861-E - 5.1 Default Encoding Parameters */ /* FIXME: This bit is only valid when using TMDS encoding and 8 * bit per color mode. */ @@ -1171,7 +1169,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, pipe_config->limited_color_range = true; } else { if (pipe_config->has_hdmi_sink && - intel_sdvo->color_range == HDMI_COLOR_RANGE_16_235) + intel_sdvo_state->base.broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED) pipe_config->limited_color_range = true; } @@ -1186,6 +1184,68 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, return true; } +#define UPDATE_PROPERTY(input, NAME) \ + do { \ + val = input; \ + intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_##NAME, &val, sizeof(val)); \ + } while (0) + +static void intel_sdvo_update_props(struct intel_sdvo *intel_sdvo, + struct intel_sdvo_connector_state *sdvo_state) +{ + struct drm_connector_state *conn_state = &sdvo_state->base.base; + struct intel_sdvo_connector *intel_sdvo_conn = + to_intel_sdvo_connector(conn_state->connector); + uint16_t val; + + if (intel_sdvo_conn->left) + UPDATE_PROPERTY(sdvo_state->tv.overscan_h, OVERSCAN_H); + + if (intel_sdvo_conn->top) + UPDATE_PROPERTY(sdvo_state->tv.overscan_v, OVERSCAN_V); + + if (intel_sdvo_conn->hpos) + UPDATE_PROPERTY(sdvo_state->tv.hpos, HPOS); + + if (intel_sdvo_conn->vpos) + UPDATE_PROPERTY(sdvo_state->tv.vpos, VPOS); + + if (intel_sdvo_conn->saturation) + UPDATE_PROPERTY(conn_state->tv.saturation, SATURATION); + + if (intel_sdvo_conn->contrast) + UPDATE_PROPERTY(conn_state->tv.contrast, CONTRAST); + + if (intel_sdvo_conn->hue) + UPDATE_PROPERTY(conn_state->tv.hue, HUE); + + if (intel_sdvo_conn->brightness) + UPDATE_PROPERTY(conn_state->tv.brightness, BRIGHTNESS); + + if (intel_sdvo_conn->sharpness) + UPDATE_PROPERTY(sdvo_state->tv.sharpness, SHARPNESS); + + if (intel_sdvo_conn->flicker_filter) + UPDATE_PROPERTY(sdvo_state->tv.flicker_filter, FLICKER_FILTER); + + if (intel_sdvo_conn->flicker_filter_2d) + UPDATE_PROPERTY(sdvo_state->tv.flicker_filter_2d, FLICKER_FILTER_2D); + + if (intel_sdvo_conn->flicker_filter_adaptive) + UPDATE_PROPERTY(sdvo_state->tv.flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); + + if (intel_sdvo_conn->tv_chroma_filter) + UPDATE_PROPERTY(sdvo_state->tv.chroma_filter, TV_CHROMA_FILTER); + + if (intel_sdvo_conn->tv_luma_filter) + UPDATE_PROPERTY(sdvo_state->tv.luma_filter, TV_LUMA_FILTER); + + if (intel_sdvo_conn->dot_crawl) + UPDATE_PROPERTY(sdvo_state->tv.dot_crawl, DOT_CRAWL); + +#undef UPDATE_PROPERTY +} + static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -1193,6 +1253,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder, struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode; + struct intel_sdvo_connector_state *sdvo_state = to_intel_sdvo_connector_state(conn_state); struct drm_display_mode *mode = &crtc_state->base.mode; struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); u32 sdvox; @@ -1200,6 +1261,8 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd input_dtd, output_dtd; int rate; + intel_sdvo_update_props(intel_sdvo, sdvo_state); + /* First, set the input mapping for the first input to our controlled * output. This is only correct if we're a single-input device, in * which case the first input is the output from the appropriate SDVO @@ -1241,7 +1304,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder, intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI); if (intel_sdvo->is_tv && - !intel_sdvo_set_tv_format(intel_sdvo)) + !intel_sdvo_set_tv_format(intel_sdvo, conn_state)) return; intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); @@ -1285,7 +1348,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder, else sdvox |= SDVO_PIPE_SEL(crtc->pipe); - if (intel_sdvo->has_hdmi_audio) + if (crtc_state->has_audio) sdvox |= SDVO_AUDIO_ENABLE; if (INTEL_GEN(dev_priv) >= 4) { @@ -1694,12 +1757,6 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector) kfree(edid); } - if (status == connector_status_connected) { - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - if (intel_sdvo_connector->force_audio != HDMI_AUDIO_AUTO) - intel_sdvo->has_hdmi_audio = (intel_sdvo_connector->force_audio == HDMI_AUDIO_ON); - } - return status; } @@ -1879,6 +1936,7 @@ static const struct drm_display_mode sdvo_tv_modes[] = { static void intel_sdvo_get_tv_modes(struct drm_connector *connector) { struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); + const struct drm_connector_state *conn_state = connector->state; struct intel_sdvo_sdtv_resolution_request tv_res; uint32_t reply = 0, format_map = 0; int i; @@ -1889,7 +1947,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) /* Read the list of supported input resolutions for the selected TV * format. */ - format_map = 1 << intel_sdvo->tv_format_index; + format_map = 1 << conn_state->tv.mode; memcpy(&tv_res, &format_map, min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); @@ -1978,192 +2036,121 @@ static void intel_sdvo_destroy(struct drm_connector *connector) kfree(intel_sdvo_connector); } -static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct edid *edid; - bool has_audio = false; - - if (!intel_sdvo->is_hdmi) - return false; - - edid = intel_sdvo_get_edid(connector); - if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - kfree(edid); - - return has_audio; -} - static int -intel_sdvo_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) +intel_sdvo_connector_atomic_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) { - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - struct drm_i915_private *dev_priv = to_i915(connector->dev); - uint16_t temp_value; - uint8_t cmd; - int ret; - - ret = drm_object_property_set_value(&connector->base, property, val); - if (ret) - return ret; - - if (property == dev_priv->force_audio_property) { - int i = val; - bool has_audio; - - if (i == intel_sdvo_connector->force_audio) - return 0; - - intel_sdvo_connector->force_audio = i; - - if (i == HDMI_AUDIO_AUTO) - has_audio = intel_sdvo_detect_hdmi_audio(connector); - else - has_audio = (i == HDMI_AUDIO_ON); - - if (has_audio == intel_sdvo->has_hdmi_audio) - return 0; - - intel_sdvo->has_hdmi_audio = has_audio; - goto done; - } - - if (property == dev_priv->broadcast_rgb_property) { - bool old_auto = intel_sdvo->color_range_auto; - uint32_t old_range = intel_sdvo->color_range; - - switch (val) { - case INTEL_BROADCAST_RGB_AUTO: - intel_sdvo->color_range_auto = true; - break; - case INTEL_BROADCAST_RGB_FULL: - intel_sdvo->color_range_auto = false; - intel_sdvo->color_range = 0; - break; - case INTEL_BROADCAST_RGB_LIMITED: - intel_sdvo->color_range_auto = false; - /* FIXME: this bit is only valid when using TMDS - * encoding and 8 bit per color mode. */ - intel_sdvo->color_range = HDMI_COLOR_RANGE_16_235; - break; - default: - return -EINVAL; - } - - if (old_auto == intel_sdvo->color_range_auto && - old_range == intel_sdvo->color_range) - return 0; - - goto done; - } - - if (property == connector->dev->mode_config.aspect_ratio_property) { - connector->state->picture_aspect_ratio = val; - goto done; - } - -#define CHECK_PROPERTY(name, NAME) \ - if (intel_sdvo_connector->name == property) { \ - if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ - if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ - cmd = SDVO_CMD_SET_##NAME; \ - intel_sdvo_connector->cur_##name = temp_value; \ - goto set_value; \ - } + const struct intel_sdvo_connector_state *sdvo_state = to_intel_sdvo_connector_state((void *)state); if (property == intel_sdvo_connector->tv_format) { - if (val >= TV_FORMAT_NUM) - return -EINVAL; - - if (intel_sdvo->tv_format_index == - intel_sdvo_connector->tv_format_supported[val]) - return 0; - - intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val]; - goto done; - } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { - temp_value = val; - if (intel_sdvo_connector->left == property) { - drm_object_property_set_value(&connector->base, - intel_sdvo_connector->right, val); - if (intel_sdvo_connector->left_margin == temp_value) - return 0; + int i; - intel_sdvo_connector->left_margin = temp_value; - intel_sdvo_connector->right_margin = temp_value; - temp_value = intel_sdvo_connector->max_hscan - - intel_sdvo_connector->left_margin; - cmd = SDVO_CMD_SET_OVERSCAN_H; - goto set_value; - } else if (intel_sdvo_connector->right == property) { - drm_object_property_set_value(&connector->base, - intel_sdvo_connector->left, val); - if (intel_sdvo_connector->right_margin == temp_value) - return 0; + for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) + if (state->tv.mode == intel_sdvo_connector->tv_format_supported[i]) { + *val = i; - intel_sdvo_connector->left_margin = temp_value; - intel_sdvo_connector->right_margin = temp_value; - temp_value = intel_sdvo_connector->max_hscan - - intel_sdvo_connector->left_margin; - cmd = SDVO_CMD_SET_OVERSCAN_H; - goto set_value; - } else if (intel_sdvo_connector->top == property) { - drm_object_property_set_value(&connector->base, - intel_sdvo_connector->bottom, val); - if (intel_sdvo_connector->top_margin == temp_value) return 0; + } - intel_sdvo_connector->top_margin = temp_value; - intel_sdvo_connector->bottom_margin = temp_value; - temp_value = intel_sdvo_connector->max_vscan - - intel_sdvo_connector->top_margin; - cmd = SDVO_CMD_SET_OVERSCAN_V; - goto set_value; - } else if (intel_sdvo_connector->bottom == property) { - drm_object_property_set_value(&connector->base, - intel_sdvo_connector->top, val); - if (intel_sdvo_connector->bottom_margin == temp_value) - return 0; + WARN_ON(1); + *val = 0; + } else if (property == intel_sdvo_connector->top || + property == intel_sdvo_connector->bottom) + *val = intel_sdvo_connector->max_vscan - sdvo_state->tv.overscan_v; + else if (property == intel_sdvo_connector->left || + property == intel_sdvo_connector->right) + *val = intel_sdvo_connector->max_hscan - sdvo_state->tv.overscan_h; + else if (property == intel_sdvo_connector->hpos) + *val = sdvo_state->tv.hpos; + else if (property == intel_sdvo_connector->vpos) + *val = sdvo_state->tv.vpos; + else if (property == intel_sdvo_connector->saturation) + *val = state->tv.saturation; + else if (property == intel_sdvo_connector->contrast) + *val = state->tv.contrast; + else if (property == intel_sdvo_connector->hue) + *val = state->tv.hue; + else if (property == intel_sdvo_connector->brightness) + *val = state->tv.brightness; + else if (property == intel_sdvo_connector->sharpness) + *val = sdvo_state->tv.sharpness; + else if (property == intel_sdvo_connector->flicker_filter) + *val = sdvo_state->tv.flicker_filter; + else if (property == intel_sdvo_connector->flicker_filter_2d) + *val = sdvo_state->tv.flicker_filter_2d; + else if (property == intel_sdvo_connector->flicker_filter_adaptive) + *val = sdvo_state->tv.flicker_filter_adaptive; + else if (property == intel_sdvo_connector->tv_chroma_filter) + *val = sdvo_state->tv.chroma_filter; + else if (property == intel_sdvo_connector->tv_luma_filter) + *val = sdvo_state->tv.luma_filter; + else if (property == intel_sdvo_connector->dot_crawl) + *val = sdvo_state->tv.dot_crawl; + else + return intel_digital_connector_atomic_get_property(connector, state, property, val); - intel_sdvo_connector->top_margin = temp_value; - intel_sdvo_connector->bottom_margin = temp_value; - temp_value = intel_sdvo_connector->max_vscan - - intel_sdvo_connector->top_margin; - cmd = SDVO_CMD_SET_OVERSCAN_V; - goto set_value; - } - CHECK_PROPERTY(hpos, HPOS) - CHECK_PROPERTY(vpos, VPOS) - CHECK_PROPERTY(saturation, SATURATION) - CHECK_PROPERTY(contrast, CONTRAST) - CHECK_PROPERTY(hue, HUE) - CHECK_PROPERTY(brightness, BRIGHTNESS) - CHECK_PROPERTY(sharpness, SHARPNESS) - CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) - CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) - CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) - CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) - CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) - CHECK_PROPERTY(dot_crawl, DOT_CRAWL) - } + return 0; +} - return -EINVAL; /* unknown property */ +static int +intel_sdvo_connector_atomic_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); + struct intel_sdvo_connector_state *sdvo_state = to_intel_sdvo_connector_state(state); -set_value: - if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2)) - return -EIO; + if (property == intel_sdvo_connector->tv_format) { + state->tv.mode = intel_sdvo_connector->tv_format_supported[val]; + if (state->crtc) { + struct drm_crtc_state *crtc_state = + drm_atomic_get_new_crtc_state(state->state, state->crtc); -done: - if (intel_sdvo->base.base.crtc) - intel_crtc_restore_mode(intel_sdvo->base.base.crtc); + crtc_state->connectors_changed = true; + } + } else if (property == intel_sdvo_connector->top || + property == intel_sdvo_connector->bottom) + /* Cannot set these independent from each other */ + sdvo_state->tv.overscan_v = intel_sdvo_connector->max_vscan - val; + else if (property == intel_sdvo_connector->left || + property == intel_sdvo_connector->right) + /* Cannot set these independent from each other */ + sdvo_state->tv.overscan_h = intel_sdvo_connector->max_hscan - val; + else if (property == intel_sdvo_connector->hpos) + sdvo_state->tv.hpos = val; + else if (property == intel_sdvo_connector->vpos) + sdvo_state->tv.vpos = val; + else if (property == intel_sdvo_connector->saturation) + state->tv.saturation = val; + else if (property == intel_sdvo_connector->contrast) + state->tv.contrast = val; + else if (property == intel_sdvo_connector->hue) + state->tv.hue = val; + else if (property == intel_sdvo_connector->brightness) + state->tv.brightness = val; + else if (property == intel_sdvo_connector->sharpness) + sdvo_state->tv.sharpness = val; + else if (property == intel_sdvo_connector->flicker_filter) + sdvo_state->tv.flicker_filter = val; + else if (property == intel_sdvo_connector->flicker_filter_2d) + sdvo_state->tv.flicker_filter_2d = val; + else if (property == intel_sdvo_connector->flicker_filter_adaptive) + sdvo_state->tv.flicker_filter_adaptive = val; + else if (property == intel_sdvo_connector->tv_chroma_filter) + sdvo_state->tv.chroma_filter = val; + else if (property == intel_sdvo_connector->tv_luma_filter) + sdvo_state->tv.luma_filter = val; + else if (property == intel_sdvo_connector->dot_crawl) + sdvo_state->tv.dot_crawl = val; + else + return intel_digital_connector_atomic_set_property(connector, state, property, val); return 0; -#undef CHECK_PROPERTY } static int @@ -2191,22 +2178,61 @@ intel_sdvo_connector_unregister(struct drm_connector *connector) intel_connector_unregister(connector); } +static struct drm_connector_state * +intel_sdvo_connector_duplicate_state(struct drm_connector *connector) +{ + struct intel_sdvo_connector_state *state; + + state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL); + if (!state) + return NULL; + + __drm_atomic_helper_connector_duplicate_state(connector, &state->base.base); + return &state->base.base; +} + static const struct drm_connector_funcs intel_sdvo_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .detect = intel_sdvo_detect, .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_sdvo_set_property, - .atomic_get_property = intel_connector_atomic_get_property, + .set_property = drm_atomic_helper_connector_set_property, + .atomic_get_property = intel_sdvo_connector_atomic_get_property, + .atomic_set_property = intel_sdvo_connector_atomic_set_property, .late_register = intel_sdvo_connector_register, .early_unregister = intel_sdvo_connector_unregister, .destroy = intel_sdvo_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_duplicate_state = intel_sdvo_connector_duplicate_state, }; +static int intel_sdvo_atomic_check(struct drm_connector *conn, + struct drm_connector_state *new_conn_state) +{ + struct drm_atomic_state *state = new_conn_state->state; + struct drm_connector_state *old_conn_state = + drm_atomic_get_old_connector_state(state, conn); + struct intel_sdvo_connector_state *old_state = + to_intel_sdvo_connector_state(old_conn_state); + struct intel_sdvo_connector_state *new_state = + to_intel_sdvo_connector_state(new_conn_state); + + if (new_conn_state->crtc && + (memcmp(&old_state->tv, &new_state->tv, sizeof(old_state->tv)) || + memcmp(&old_conn_state->tv, &new_conn_state->tv, sizeof(old_conn_state->tv)))) { + struct drm_crtc_state *crtc_state = + drm_atomic_get_new_crtc_state(new_conn_state->state, + new_conn_state->crtc); + + crtc_state->connectors_changed = true; + } + + return intel_digital_connector_atomic_check(conn, new_conn_state); +} + static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { .get_modes = intel_sdvo_get_modes, .mode_valid = intel_sdvo_mode_valid, + .atomic_check = intel_sdvo_atomic_check, }; static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) @@ -2398,7 +2424,6 @@ intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo, intel_attach_force_audio_property(&connector->base.base); if (INTEL_GEN(dev_priv) >= 4 && IS_MOBILE(dev_priv)) { intel_attach_broadcast_rgb_property(&connector->base.base); - intel_sdvo->color_range_auto = true; } intel_attach_aspect_ratio_property(&connector->base.base); connector->base.base.state->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE; @@ -2407,16 +2432,21 @@ intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo, static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) { struct intel_sdvo_connector *sdvo_connector; + struct intel_sdvo_connector_state *conn_state; sdvo_connector = kzalloc(sizeof(*sdvo_connector), GFP_KERNEL); if (!sdvo_connector) return NULL; - if (intel_connector_init(&sdvo_connector->base) < 0) { + conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL); + if (!conn_state) { kfree(sdvo_connector); return NULL; } + __drm_atomic_helper_connector_reset(&sdvo_connector->base.base, + &conn_state->base.base); + return sdvo_connector; } @@ -2708,31 +2738,31 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->tv_format, i, i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]); - intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0]; + intel_sdvo_connector->base.base.state->tv.mode = intel_sdvo_connector->tv_format_supported[0]; drm_object_attach_property(&intel_sdvo_connector->base.base.base, - intel_sdvo_connector->tv_format, 0); + intel_sdvo_connector->tv_format, 0); return true; } -#define ENHANCEMENT(name, NAME) do { \ +#define _ENHANCEMENT(state_assignment, name, NAME) do { \ if (enhancements.name) { \ if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ return false; \ - intel_sdvo_connector->max_##name = data_value[0]; \ - intel_sdvo_connector->cur_##name = response; \ intel_sdvo_connector->name = \ drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ if (!intel_sdvo_connector->name) return false; \ + state_assignment = response; \ drm_object_attach_property(&connector->base, \ - intel_sdvo_connector->name, \ - intel_sdvo_connector->cur_##name); \ + intel_sdvo_connector->name, 0); \ DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ data_value[0], data_value[1], response); \ } \ } while (0) +#define ENHANCEMENT(state, name, NAME) _ENHANCEMENT((state)->name, name, NAME) + static bool intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector, @@ -2740,6 +2770,9 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, { struct drm_device *dev = intel_sdvo->base.base.dev; struct drm_connector *connector = &intel_sdvo_connector->base.base; + struct drm_connector_state *conn_state = connector->state; + struct intel_sdvo_connector_state *sdvo_state = + to_intel_sdvo_connector_state(conn_state); uint16_t response, data_value[2]; /* when horizontal overscan is supported, Add the left/right property */ @@ -2754,17 +2787,16 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, &response, 2)) return false; + sdvo_state->tv.overscan_h = response; + intel_sdvo_connector->max_hscan = data_value[0]; - intel_sdvo_connector->left_margin = data_value[0] - response; - intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; intel_sdvo_connector->left = drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); if (!intel_sdvo_connector->left) return false; drm_object_attach_property(&connector->base, - intel_sdvo_connector->left, - intel_sdvo_connector->left_margin); + intel_sdvo_connector->left, 0); intel_sdvo_connector->right = drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); @@ -2772,8 +2804,7 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, return false; drm_object_attach_property(&connector->base, - intel_sdvo_connector->right, - intel_sdvo_connector->right_margin); + intel_sdvo_connector->right, 0); DRM_DEBUG_KMS("h_overscan: max %d, " "default %d, current %d\n", data_value[0], data_value[1], response); @@ -2790,9 +2821,9 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, &response, 2)) return false; + sdvo_state->tv.overscan_v = response; + intel_sdvo_connector->max_vscan = data_value[0]; - intel_sdvo_connector->top_margin = data_value[0] - response; - intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; intel_sdvo_connector->top = drm_property_create_range(dev, 0, "top_margin", 0, data_value[0]); @@ -2800,8 +2831,7 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, return false; drm_object_attach_property(&connector->base, - intel_sdvo_connector->top, - intel_sdvo_connector->top_margin); + intel_sdvo_connector->top, 0); intel_sdvo_connector->bottom = drm_property_create_range(dev, 0, @@ -2810,40 +2840,37 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, return false; drm_object_attach_property(&connector->base, - intel_sdvo_connector->bottom, - intel_sdvo_connector->bottom_margin); + intel_sdvo_connector->bottom, 0); DRM_DEBUG_KMS("v_overscan: max %d, " "default %d, current %d\n", data_value[0], data_value[1], response); } - ENHANCEMENT(hpos, HPOS); - ENHANCEMENT(vpos, VPOS); - ENHANCEMENT(saturation, SATURATION); - ENHANCEMENT(contrast, CONTRAST); - ENHANCEMENT(hue, HUE); - ENHANCEMENT(sharpness, SHARPNESS); - ENHANCEMENT(brightness, BRIGHTNESS); - ENHANCEMENT(flicker_filter, FLICKER_FILTER); - ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); - ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); - ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); - ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); + ENHANCEMENT(&sdvo_state->tv, hpos, HPOS); + ENHANCEMENT(&sdvo_state->tv, vpos, VPOS); + ENHANCEMENT(&conn_state->tv, saturation, SATURATION); + ENHANCEMENT(&conn_state->tv, contrast, CONTRAST); + ENHANCEMENT(&conn_state->tv, hue, HUE); + ENHANCEMENT(&conn_state->tv, brightness, BRIGHTNESS); + ENHANCEMENT(&sdvo_state->tv, sharpness, SHARPNESS); + ENHANCEMENT(&sdvo_state->tv, flicker_filter, FLICKER_FILTER); + ENHANCEMENT(&sdvo_state->tv, flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); + ENHANCEMENT(&sdvo_state->tv, flicker_filter_2d, FLICKER_FILTER_2D); + _ENHANCEMENT(sdvo_state->tv.chroma_filter, tv_chroma_filter, TV_CHROMA_FILTER); + _ENHANCEMENT(sdvo_state->tv.luma_filter, tv_luma_filter, TV_LUMA_FILTER); if (enhancements.dot_crawl) { if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) return false; - intel_sdvo_connector->max_dot_crawl = 1; - intel_sdvo_connector->cur_dot_crawl = response & 0x1; + sdvo_state->tv.dot_crawl = response & 0x1; intel_sdvo_connector->dot_crawl = drm_property_create_range(dev, 0, "dot_crawl", 0, 1); if (!intel_sdvo_connector->dot_crawl) return false; drm_object_attach_property(&connector->base, - intel_sdvo_connector->dot_crawl, - intel_sdvo_connector->cur_dot_crawl); + intel_sdvo_connector->dot_crawl, 0); DRM_DEBUG_KMS("dot crawl: current %d\n", response); } @@ -2859,11 +2886,12 @@ intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, struct drm_connector *connector = &intel_sdvo_connector->base.base; uint16_t response, data_value[2]; - ENHANCEMENT(brightness, BRIGHTNESS); + ENHANCEMENT(&connector->state->tv, brightness, BRIGHTNESS); return true; } #undef ENHANCEMENT +#undef _ENHANCEMENT static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector) diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 7a7b07d..27e072c 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -433,16 +433,19 @@ err_guc: DRM_NOTE("Falling back from GuC submission to execlist mode\n"); } + i915.enable_guc_loading = 0; + DRM_NOTE("GuC firmware loading disabled\n"); + return ret; } void intel_uc_fini_hw(struct drm_i915_private *dev_priv) { + guc_free_load_err_log(&dev_priv->guc); + if (!i915.enable_guc_loading) return; - guc_free_load_err_log(&dev_priv->guc); - if (i915.enable_guc_submission) i915_guc_submission_disable(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 47d7ee1..9882724 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -404,8 +404,6 @@ check_for_unclaimed_mmio(struct drm_i915_private *dev_priv) static void __intel_uncore_early_sanitize(struct drm_i915_private *dev_priv, bool restore_forcewake) { - struct intel_device_info *info = mkwrite_device_info(dev_priv); - /* clear out unclaimed reg detection bit */ if (check_for_unclaimed_mmio(dev_priv)) DRM_DEBUG("unclaimed mmio detected on uncore init, clearing\n"); @@ -418,9 +416,6 @@ static void __intel_uncore_early_sanitize(struct drm_i915_private *dev_priv, GT_FIFO_CTL_RC6_POLICY_STALL); } - if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST)) - info->has_decoupled_mmio = false; - intel_uncore_forcewake_reset(dev_priv, restore_forcewake); } @@ -810,78 +805,6 @@ unclaimed_reg_debug(struct drm_i915_private *dev_priv, __unclaimed_reg_debug(dev_priv, reg, read, before); } -enum decoupled_power_domain { - GEN9_DECOUPLED_PD_BLITTER = 0, - GEN9_DECOUPLED_PD_RENDER, - GEN9_DECOUPLED_PD_MEDIA, - GEN9_DECOUPLED_PD_ALL -}; - -enum decoupled_ops { - GEN9_DECOUPLED_OP_WRITE = 0, - GEN9_DECOUPLED_OP_READ -}; - -static const enum decoupled_power_domain fw2dpd_domain[] = { - GEN9_DECOUPLED_PD_RENDER, - GEN9_DECOUPLED_PD_BLITTER, - GEN9_DECOUPLED_PD_ALL, - GEN9_DECOUPLED_PD_MEDIA, - GEN9_DECOUPLED_PD_ALL, - GEN9_DECOUPLED_PD_ALL, - GEN9_DECOUPLED_PD_ALL -}; - -/* - * Decoupled MMIO access for only 1 DWORD - */ -static void __gen9_decoupled_mmio_access(struct drm_i915_private *dev_priv, - u32 reg, - enum forcewake_domains fw_domain, - enum decoupled_ops operation) -{ - enum decoupled_power_domain dp_domain; - u32 ctrl_reg_data = 0; - - dp_domain = fw2dpd_domain[fw_domain - 1]; - - ctrl_reg_data |= reg; - ctrl_reg_data |= (operation << GEN9_DECOUPLED_OP_SHIFT); - ctrl_reg_data |= (dp_domain << GEN9_DECOUPLED_PD_SHIFT); - ctrl_reg_data |= GEN9_DECOUPLED_DW1_GO; - __raw_i915_write32(dev_priv, GEN9_DECOUPLED_REG0_DW1, ctrl_reg_data); - - if (wait_for_atomic((__raw_i915_read32(dev_priv, - GEN9_DECOUPLED_REG0_DW1) & - GEN9_DECOUPLED_DW1_GO) == 0, - FORCEWAKE_ACK_TIMEOUT_MS)) - DRM_ERROR("Decoupled MMIO wait timed out\n"); -} - -static inline u32 -__gen9_decoupled_mmio_read32(struct drm_i915_private *dev_priv, - u32 reg, - enum forcewake_domains fw_domain) -{ - __gen9_decoupled_mmio_access(dev_priv, reg, fw_domain, - GEN9_DECOUPLED_OP_READ); - - return __raw_i915_read32(dev_priv, GEN9_DECOUPLED_REG0_DW0); -} - -static inline void -__gen9_decoupled_mmio_write(struct drm_i915_private *dev_priv, - u32 reg, u32 data, - enum forcewake_domains fw_domain) -{ - - __raw_i915_write32(dev_priv, GEN9_DECOUPLED_REG0_DW0, data); - - __gen9_decoupled_mmio_access(dev_priv, reg, fw_domain, - GEN9_DECOUPLED_OP_WRITE); -} - - #define GEN2_READ_HEADER(x) \ u##x val = 0; \ assert_rpm_wakelock_held(dev_priv); @@ -978,28 +901,6 @@ func##_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { #define __gen6_read(x) __gen_read(gen6, x) #define __fwtable_read(x) __gen_read(fwtable, x) -#define __gen9_decoupled_read(x) \ -static u##x \ -gen9_decoupled_read##x(struct drm_i915_private *dev_priv, \ - i915_reg_t reg, bool trace) { \ - enum forcewake_domains fw_engine; \ - GEN6_READ_HEADER(x); \ - fw_engine = __fwtable_reg_read_fw_domains(offset); \ - if (fw_engine & ~dev_priv->uncore.fw_domains_active) { \ - unsigned i; \ - u32 *ptr_data = (u32 *) &val; \ - for (i = 0; i < x/32; i++, offset += sizeof(u32), ptr_data++) \ - *ptr_data = __gen9_decoupled_mmio_read32(dev_priv, \ - offset, \ - fw_engine); \ - } else { \ - val = __raw_i915_read##x(dev_priv, reg); \ - } \ - GEN6_READ_FOOTER; \ -} - -__gen9_decoupled_read(32) -__gen9_decoupled_read(64) __fwtable_read(8) __fwtable_read(16) __fwtable_read(32) @@ -1086,25 +987,6 @@ func##_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, boo #define __gen8_write(x) __gen_write(gen8, x) #define __fwtable_write(x) __gen_write(fwtable, x) -#define __gen9_decoupled_write(x) \ -static void \ -gen9_decoupled_write##x(struct drm_i915_private *dev_priv, \ - i915_reg_t reg, u##x val, \ - bool trace) { \ - enum forcewake_domains fw_engine; \ - GEN6_WRITE_HEADER; \ - fw_engine = __fwtable_reg_write_fw_domains(offset); \ - if (fw_engine & ~dev_priv->uncore.fw_domains_active) \ - __gen9_decoupled_mmio_write(dev_priv, \ - offset, \ - val, \ - fw_engine); \ - else \ - __raw_i915_write##x(dev_priv, reg, val); \ - GEN6_WRITE_FOOTER; \ -} - -__gen9_decoupled_write(32) __fwtable_write(8) __fwtable_write(16) __fwtable_write(32) @@ -1341,14 +1223,6 @@ void intel_uncore_init(struct drm_i915_private *dev_priv) ASSIGN_FW_DOMAINS_TABLE(__gen9_fw_ranges); ASSIGN_WRITE_MMIO_VFUNCS(dev_priv, fwtable); ASSIGN_READ_MMIO_VFUNCS(dev_priv, fwtable); - if (HAS_DECOUPLED_MMIO(dev_priv)) { - dev_priv->uncore.funcs.mmio_readl = - gen9_decoupled_read32; - dev_priv->uncore.funcs.mmio_readq = - gen9_decoupled_read64; - dev_priv->uncore.funcs.mmio_writel = - gen9_decoupled_write32; - } } iosf_mbi_register_pmic_bus_access_notifier( diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c index 4e681fc..caf76af 100644 --- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c +++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c @@ -126,9 +126,11 @@ huge_gem_object(struct drm_i915_private *i915, drm_gem_private_object_init(&i915->drm, &obj->base, dma_size); i915_gem_object_init(obj, &huge_ops); - obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; + obj->cache_coherent = i915_gem_object_is_coherent(obj); + obj->cache_dirty = !obj->cache_coherent; obj->scratch = phys_size; return obj; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index 14e9c2f..5ea3732 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -304,7 +304,7 @@ static int igt_evict_vm(void *arg) goto cleanup; /* Everything is pinned, nothing should happen */ - err = i915_gem_evict_vm(&ggtt->base, false); + err = i915_gem_evict_vm(&ggtt->base); if (err) { pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n", err); @@ -313,7 +313,7 @@ static int igt_evict_vm(void *arg) unpin_ggtt(i915); - err = i915_gem_evict_vm(&ggtt->base, false); + err = i915_gem_evict_vm(&ggtt->base); if (err) { pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n", err); diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index ad56566..fb9072d 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c @@ -225,14 +225,6 @@ static bool assert_pin_valid(const struct i915_vma *vma, } __maybe_unused -static bool assert_pin_e2big(const struct i915_vma *vma, - const struct pin_mode *mode, - int result) -{ - return result == -E2BIG; -} - -__maybe_unused static bool assert_pin_enospc(const struct i915_vma *vma, const struct pin_mode *mode, int result) @@ -255,7 +247,6 @@ static int igt_vma_pin1(void *arg) #define VALID(sz, fl) { .size = (sz), .flags = (fl), .assert = assert_pin_valid, .string = #sz ", " #fl ", (valid) " } #define __INVALID(sz, fl, check, eval) { .size = (sz), .flags = (fl), .assert = (check), .string = #sz ", " #fl ", (invalid " #eval ")" } #define INVALID(sz, fl) __INVALID(sz, fl, assert_pin_einval, EINVAL) -#define TOOBIG(sz, fl) __INVALID(sz, fl, assert_pin_e2big, E2BIG) #define NOSPACE(sz, fl) __INVALID(sz, fl, assert_pin_enospc, ENOSPC) VALID(0, PIN_GLOBAL), VALID(0, PIN_GLOBAL | PIN_MAPPABLE), @@ -276,11 +267,11 @@ static int igt_vma_pin1(void *arg) VALID(8192, PIN_GLOBAL), VALID(i915->ggtt.mappable_end - 4096, PIN_GLOBAL | PIN_MAPPABLE), VALID(i915->ggtt.mappable_end, PIN_GLOBAL | PIN_MAPPABLE), - TOOBIG(i915->ggtt.mappable_end + 4096, PIN_GLOBAL | PIN_MAPPABLE), + NOSPACE(i915->ggtt.mappable_end + 4096, PIN_GLOBAL | PIN_MAPPABLE), VALID(i915->ggtt.base.total - 4096, PIN_GLOBAL), VALID(i915->ggtt.base.total, PIN_GLOBAL), - TOOBIG(i915->ggtt.base.total + 4096, PIN_GLOBAL), - TOOBIG(round_down(U64_MAX, PAGE_SIZE), PIN_GLOBAL), + NOSPACE(i915->ggtt.base.total + 4096, PIN_GLOBAL), + NOSPACE(round_down(U64_MAX, PAGE_SIZE), PIN_GLOBAL), INVALID(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (i915->ggtt.mappable_end - 4096)), INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (i915->ggtt.base.total - 4096)), INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (round_down(U64_MAX, PAGE_SIZE) - 4096)), @@ -300,7 +291,6 @@ static int igt_vma_pin1(void *arg) #endif { }, #undef NOSPACE -#undef TOOBIG #undef INVALID #undef __INVALID #undef VALID diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c b/drivers/gpu/drm/i915/selftests/mock_context.c index 8d3a90c..f8b9cc2 100644 --- a/drivers/gpu/drm/i915/selftests/mock_context.c +++ b/drivers/gpu/drm/i915/selftests/mock_context.c @@ -40,10 +40,18 @@ mock_context(struct drm_i915_private *i915, INIT_LIST_HEAD(&ctx->link); ctx->i915 = i915; + ctx->vma_lut.ht_bits = VMA_HT_BITS; + ctx->vma_lut.ht_size = BIT(VMA_HT_BITS); + ctx->vma_lut.ht = kcalloc(ctx->vma_lut.ht_size, + sizeof(*ctx->vma_lut.ht), + GFP_KERNEL); + if (!ctx->vma_lut.ht) + goto err_free; + ret = ida_simple_get(&i915->context_hw_ida, 0, MAX_CONTEXT_HW_ID, GFP_KERNEL); if (ret < 0) - goto err_free; + goto err_vma_ht; ctx->hw_id = ret; if (name) { @@ -58,6 +66,8 @@ mock_context(struct drm_i915_private *i915, return ctx; +err_vma_ht: + kvfree(ctx->vma_lut.ht); err_free: kfree(ctx); return NULL; diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 0a31cd6..b638d19 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -5,6 +5,7 @@ config DRM_MSM depends on ARCH_QCOM || (ARM && COMPILE_TEST) depends on OF && COMMON_CLK depends on MMU + select QCOM_MDT_LOADER select REGULATOR select DRM_KMS_HELPER select DRM_PANEL diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h index 4be092f..644374c 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h @@ -8,17 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2016-04-26 17:56:44) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32907 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 12025 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 22544 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 110765 bytes, from 2016-11-26 23:01:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 90321 bytes, from 2016-11-28 16:50:05) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) - -Copyright (C) 2013-2016 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 37162 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 13324 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 31866 bytes, from 2017-06-06 18:26:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 111898 bytes, from 2017-06-06 18:23:59) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 139480 bytes, from 2017-06-16 12:44:39) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) @@ -352,6 +352,38 @@ static inline uint32_t A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(enum adreno_mmu_cln #define REG_A2XX_RBBM_DEBUG 0x0000039b #define REG_A2XX_RBBM_PM_OVERRIDE1 0x0000039c +#define A2XX_RBBM_PM_OVERRIDE1_RBBM_AHBCLK_PM_OVERRIDE 0x00000001 +#define A2XX_RBBM_PM_OVERRIDE1_SC_REG_SCLK_PM_OVERRIDE 0x00000002 +#define A2XX_RBBM_PM_OVERRIDE1_SC_SCLK_PM_OVERRIDE 0x00000004 +#define A2XX_RBBM_PM_OVERRIDE1_SP_TOP_SCLK_PM_OVERRIDE 0x00000008 +#define A2XX_RBBM_PM_OVERRIDE1_SP_V0_SCLK_PM_OVERRIDE 0x00000010 +#define A2XX_RBBM_PM_OVERRIDE1_SQ_REG_SCLK_PM_OVERRIDE 0x00000020 +#define A2XX_RBBM_PM_OVERRIDE1_SQ_REG_FIFOS_SCLK_PM_OVERRIDE 0x00000040 +#define A2XX_RBBM_PM_OVERRIDE1_SQ_CONST_MEM_SCLK_PM_OVERRIDE 0x00000080 +#define A2XX_RBBM_PM_OVERRIDE1_SQ_SQ_SCLK_PM_OVERRIDE 0x00000100 +#define A2XX_RBBM_PM_OVERRIDE1_SX_SCLK_PM_OVERRIDE 0x00000200 +#define A2XX_RBBM_PM_OVERRIDE1_SX_REG_SCLK_PM_OVERRIDE 0x00000400 +#define A2XX_RBBM_PM_OVERRIDE1_TCM_TCO_SCLK_PM_OVERRIDE 0x00000800 +#define A2XX_RBBM_PM_OVERRIDE1_TCM_TCM_SCLK_PM_OVERRIDE 0x00001000 +#define A2XX_RBBM_PM_OVERRIDE1_TCM_TCD_SCLK_PM_OVERRIDE 0x00002000 +#define A2XX_RBBM_PM_OVERRIDE1_TCM_REG_SCLK_PM_OVERRIDE 0x00004000 +#define A2XX_RBBM_PM_OVERRIDE1_TPC_TPC_SCLK_PM_OVERRIDE 0x00008000 +#define A2XX_RBBM_PM_OVERRIDE1_TPC_REG_SCLK_PM_OVERRIDE 0x00010000 +#define A2XX_RBBM_PM_OVERRIDE1_TCF_TCA_SCLK_PM_OVERRIDE 0x00020000 +#define A2XX_RBBM_PM_OVERRIDE1_TCF_TCB_SCLK_PM_OVERRIDE 0x00040000 +#define A2XX_RBBM_PM_OVERRIDE1_TCF_TCB_READ_SCLK_PM_OVERRIDE 0x00080000 +#define A2XX_RBBM_PM_OVERRIDE1_TP_TP_SCLK_PM_OVERRIDE 0x00100000 +#define A2XX_RBBM_PM_OVERRIDE1_TP_REG_SCLK_PM_OVERRIDE 0x00200000 +#define A2XX_RBBM_PM_OVERRIDE1_CP_G_SCLK_PM_OVERRIDE 0x00400000 +#define A2XX_RBBM_PM_OVERRIDE1_CP_REG_SCLK_PM_OVERRIDE 0x00800000 +#define A2XX_RBBM_PM_OVERRIDE1_CP_G_REG_SCLK_PM_OVERRIDE 0x01000000 +#define A2XX_RBBM_PM_OVERRIDE1_SPI_SCLK_PM_OVERRIDE 0x02000000 +#define A2XX_RBBM_PM_OVERRIDE1_RB_REG_SCLK_PM_OVERRIDE 0x04000000 +#define A2XX_RBBM_PM_OVERRIDE1_RB_SCLK_PM_OVERRIDE 0x08000000 +#define A2XX_RBBM_PM_OVERRIDE1_MH_MH_SCLK_PM_OVERRIDE 0x10000000 +#define A2XX_RBBM_PM_OVERRIDE1_MH_REG_SCLK_PM_OVERRIDE 0x20000000 +#define A2XX_RBBM_PM_OVERRIDE1_MH_MMU_SCLK_PM_OVERRIDE 0x40000000 +#define A2XX_RBBM_PM_OVERRIDE1_MH_TCROQ_SCLK_PM_OVERRIDE 0x80000000 #define REG_A2XX_RBBM_PM_OVERRIDE2 0x0000039d @@ -477,12 +509,43 @@ static inline uint32_t REG_A2XX_VSC_PIPE_DATA_LENGTH(uint32_t i0) { return 0x000 #define REG_A2XX_PA_SU_DEBUG_DATA 0x00000c81 #define REG_A2XX_PA_SU_FACE_DATA 0x00000c86 +#define A2XX_PA_SU_FACE_DATA_BASE_ADDR__MASK 0xffffffe0 +#define A2XX_PA_SU_FACE_DATA_BASE_ADDR__SHIFT 5 +static inline uint32_t A2XX_PA_SU_FACE_DATA_BASE_ADDR(uint32_t val) +{ + return ((val) << A2XX_PA_SU_FACE_DATA_BASE_ADDR__SHIFT) & A2XX_PA_SU_FACE_DATA_BASE_ADDR__MASK; +} #define REG_A2XX_SQ_GPR_MANAGEMENT 0x00000d00 +#define A2XX_SQ_GPR_MANAGEMENT_REG_DYNAMIC 0x00000001 +#define A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_PIX__MASK 0x00000ff0 +#define A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_PIX__SHIFT 4 +static inline uint32_t A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_PIX(uint32_t val) +{ + return ((val) << A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_PIX__SHIFT) & A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_PIX__MASK; +} +#define A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_VTX__MASK 0x000ff000 +#define A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_VTX__SHIFT 12 +static inline uint32_t A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_VTX(uint32_t val) +{ + return ((val) << A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_VTX__SHIFT) & A2XX_SQ_GPR_MANAGEMENT_REG_SIZE_VTX__MASK; +} #define REG_A2XX_SQ_FLOW_CONTROL 0x00000d01 #define REG_A2XX_SQ_INST_STORE_MANAGMENT 0x00000d02 +#define A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_PIX__MASK 0x00000fff +#define A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_PIX__SHIFT 0 +static inline uint32_t A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_PIX(uint32_t val) +{ + return ((val) << A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_PIX__SHIFT) & A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_PIX__MASK; +} +#define A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_VTX__MASK 0x0fff0000 +#define A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_VTX__SHIFT 16 +static inline uint32_t A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_VTX(uint32_t val) +{ + return ((val) << A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_VTX__SHIFT) & A2XX_SQ_INST_STORE_MANAGMENT_INST_BASE_VTX__MASK; +} #define REG_A2XX_SQ_DEBUG_MISC 0x00000d05 @@ -742,6 +805,24 @@ static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_BR_Y(uint32_t val) #define REG_A2XX_RB_BLEND_ALPHA 0x00002108 #define REG_A2XX_RB_FOG_COLOR 0x00002109 +#define A2XX_RB_FOG_COLOR_FOG_RED__MASK 0x000000ff +#define A2XX_RB_FOG_COLOR_FOG_RED__SHIFT 0 +static inline uint32_t A2XX_RB_FOG_COLOR_FOG_RED(uint32_t val) +{ + return ((val) << A2XX_RB_FOG_COLOR_FOG_RED__SHIFT) & A2XX_RB_FOG_COLOR_FOG_RED__MASK; +} +#define A2XX_RB_FOG_COLOR_FOG_GREEN__MASK 0x0000ff00 +#define A2XX_RB_FOG_COLOR_FOG_GREEN__SHIFT 8 +static inline uint32_t A2XX_RB_FOG_COLOR_FOG_GREEN(uint32_t val) +{ + return ((val) << A2XX_RB_FOG_COLOR_FOG_GREEN__SHIFT) & A2XX_RB_FOG_COLOR_FOG_GREEN__MASK; +} +#define A2XX_RB_FOG_COLOR_FOG_BLUE__MASK 0x00ff0000 +#define A2XX_RB_FOG_COLOR_FOG_BLUE__SHIFT 16 +static inline uint32_t A2XX_RB_FOG_COLOR_FOG_BLUE(uint32_t val) +{ + return ((val) << A2XX_RB_FOG_COLOR_FOG_BLUE__SHIFT) & A2XX_RB_FOG_COLOR_FOG_BLUE__MASK; +} #define REG_A2XX_RB_STENCILREFMASK_BF 0x0000210c #define A2XX_RB_STENCILREFMASK_BF_STENCILREF__MASK 0x000000ff @@ -890,14 +971,146 @@ static inline uint32_t A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS(uint32_t val) #define A2XX_SQ_CONTEXT_MISC_TX_CACHE_SEL 0x00040000 #define REG_A2XX_SQ_INTERPOLATOR_CNTL 0x00002182 +#define A2XX_SQ_INTERPOLATOR_CNTL_PARAM_SHADE__MASK 0x0000ffff +#define A2XX_SQ_INTERPOLATOR_CNTL_PARAM_SHADE__SHIFT 0 +static inline uint32_t A2XX_SQ_INTERPOLATOR_CNTL_PARAM_SHADE(uint32_t val) +{ + return ((val) << A2XX_SQ_INTERPOLATOR_CNTL_PARAM_SHADE__SHIFT) & A2XX_SQ_INTERPOLATOR_CNTL_PARAM_SHADE__MASK; +} +#define A2XX_SQ_INTERPOLATOR_CNTL_SAMPLING_PATTERN__MASK 0xffff0000 +#define A2XX_SQ_INTERPOLATOR_CNTL_SAMPLING_PATTERN__SHIFT 16 +static inline uint32_t A2XX_SQ_INTERPOLATOR_CNTL_SAMPLING_PATTERN(uint32_t val) +{ + return ((val) << A2XX_SQ_INTERPOLATOR_CNTL_SAMPLING_PATTERN__SHIFT) & A2XX_SQ_INTERPOLATOR_CNTL_SAMPLING_PATTERN__MASK; +} #define REG_A2XX_SQ_WRAPPING_0 0x00002183 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_0__MASK 0x0000000f +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_0__SHIFT 0 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_0(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_0__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_0__MASK; +} +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_1__MASK 0x000000f0 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_1__SHIFT 4 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_1(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_1__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_1__MASK; +} +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_2__MASK 0x00000f00 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_2__SHIFT 8 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_2(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_2__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_2__MASK; +} +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_3__MASK 0x0000f000 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_3__SHIFT 12 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_3(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_3__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_3__MASK; +} +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_4__MASK 0x000f0000 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_4__SHIFT 16 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_4(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_4__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_4__MASK; +} +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_5__MASK 0x00f00000 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_5__SHIFT 20 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_5(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_5__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_5__MASK; +} +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_6__MASK 0x0f000000 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_6__SHIFT 24 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_6(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_6__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_6__MASK; +} +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_7__MASK 0xf0000000 +#define A2XX_SQ_WRAPPING_0_PARAM_WRAP_7__SHIFT 28 +static inline uint32_t A2XX_SQ_WRAPPING_0_PARAM_WRAP_7(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_0_PARAM_WRAP_7__SHIFT) & A2XX_SQ_WRAPPING_0_PARAM_WRAP_7__MASK; +} #define REG_A2XX_SQ_WRAPPING_1 0x00002184 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_8__MASK 0x0000000f +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_8__SHIFT 0 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_8(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_8__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_8__MASK; +} +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_9__MASK 0x000000f0 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_9__SHIFT 4 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_9(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_9__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_9__MASK; +} +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_10__MASK 0x00000f00 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_10__SHIFT 8 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_10(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_10__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_10__MASK; +} +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_11__MASK 0x0000f000 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_11__SHIFT 12 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_11(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_11__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_11__MASK; +} +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_12__MASK 0x000f0000 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_12__SHIFT 16 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_12(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_12__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_12__MASK; +} +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_13__MASK 0x00f00000 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_13__SHIFT 20 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_13(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_13__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_13__MASK; +} +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_14__MASK 0x0f000000 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_14__SHIFT 24 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_14(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_14__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_14__MASK; +} +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_15__MASK 0xf0000000 +#define A2XX_SQ_WRAPPING_1_PARAM_WRAP_15__SHIFT 28 +static inline uint32_t A2XX_SQ_WRAPPING_1_PARAM_WRAP_15(uint32_t val) +{ + return ((val) << A2XX_SQ_WRAPPING_1_PARAM_WRAP_15__SHIFT) & A2XX_SQ_WRAPPING_1_PARAM_WRAP_15__MASK; +} #define REG_A2XX_SQ_PS_PROGRAM 0x000021f6 +#define A2XX_SQ_PS_PROGRAM_BASE__MASK 0x00000fff +#define A2XX_SQ_PS_PROGRAM_BASE__SHIFT 0 +static inline uint32_t A2XX_SQ_PS_PROGRAM_BASE(uint32_t val) +{ + return ((val) << A2XX_SQ_PS_PROGRAM_BASE__SHIFT) & A2XX_SQ_PS_PROGRAM_BASE__MASK; +} +#define A2XX_SQ_PS_PROGRAM_SIZE__MASK 0x00fff000 +#define A2XX_SQ_PS_PROGRAM_SIZE__SHIFT 12 +static inline uint32_t A2XX_SQ_PS_PROGRAM_SIZE(uint32_t val) +{ + return ((val) << A2XX_SQ_PS_PROGRAM_SIZE__SHIFT) & A2XX_SQ_PS_PROGRAM_SIZE__MASK; +} #define REG_A2XX_SQ_VS_PROGRAM 0x000021f7 +#define A2XX_SQ_VS_PROGRAM_BASE__MASK 0x00000fff +#define A2XX_SQ_VS_PROGRAM_BASE__SHIFT 0 +static inline uint32_t A2XX_SQ_VS_PROGRAM_BASE(uint32_t val) +{ + return ((val) << A2XX_SQ_VS_PROGRAM_BASE__SHIFT) & A2XX_SQ_VS_PROGRAM_BASE__MASK; +} +#define A2XX_SQ_VS_PROGRAM_SIZE__MASK 0x00fff000 +#define A2XX_SQ_VS_PROGRAM_SIZE__SHIFT 12 +static inline uint32_t A2XX_SQ_VS_PROGRAM_SIZE(uint32_t val) +{ + return ((val) << A2XX_SQ_VS_PROGRAM_SIZE__SHIFT) & A2XX_SQ_VS_PROGRAM_SIZE__MASK; +} #define REG_A2XX_VGT_EVENT_INITIATOR 0x000021f9 @@ -1304,6 +1517,14 @@ static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL(enum a2xx_pa_sc_a } #define REG_A2XX_PA_SC_VIZ_QUERY 0x00002293 +#define A2XX_PA_SC_VIZ_QUERY_VIZ_QUERY_ENA 0x00000001 +#define A2XX_PA_SC_VIZ_QUERY_VIZ_QUERY_ID__MASK 0x0000007e +#define A2XX_PA_SC_VIZ_QUERY_VIZ_QUERY_ID__SHIFT 1 +static inline uint32_t A2XX_PA_SC_VIZ_QUERY_VIZ_QUERY_ID(uint32_t val) +{ + return ((val) << A2XX_PA_SC_VIZ_QUERY_VIZ_QUERY_ID__SHIFT) & A2XX_PA_SC_VIZ_QUERY_VIZ_QUERY_ID__MASK; +} +#define A2XX_PA_SC_VIZ_QUERY_KILL_PIX_POST_EARLY_Z 0x00000100 #define REG_A2XX_VGT_ENHANCE 0x00002294 @@ -1319,6 +1540,18 @@ static inline uint32_t A2XX_PA_SC_LINE_CNTL_BRES_CNTL(uint32_t val) #define A2XX_PA_SC_LINE_CNTL_LAST_PIXEL 0x00000400 #define REG_A2XX_PA_SC_AA_CONFIG 0x00002301 +#define A2XX_PA_SC_AA_CONFIG_MSAA_NUM_SAMPLES__MASK 0x00000007 +#define A2XX_PA_SC_AA_CONFIG_MSAA_NUM_SAMPLES__SHIFT 0 +static inline uint32_t A2XX_PA_SC_AA_CONFIG_MSAA_NUM_SAMPLES(uint32_t val) +{ + return ((val) << A2XX_PA_SC_AA_CONFIG_MSAA_NUM_SAMPLES__SHIFT) & A2XX_PA_SC_AA_CONFIG_MSAA_NUM_SAMPLES__MASK; +} +#define A2XX_PA_SC_AA_CONFIG_MAX_SAMPLE_DIST__MASK 0x0001e000 +#define A2XX_PA_SC_AA_CONFIG_MAX_SAMPLE_DIST__SHIFT 13 +static inline uint32_t A2XX_PA_SC_AA_CONFIG_MAX_SAMPLE_DIST(uint32_t val) +{ + return ((val) << A2XX_PA_SC_AA_CONFIG_MAX_SAMPLE_DIST__SHIFT) & A2XX_PA_SC_AA_CONFIG_MAX_SAMPLE_DIST__MASK; +} #define REG_A2XX_PA_SU_VTX_CNTL 0x00002302 #define A2XX_PA_SU_VTX_CNTL_PIX_CENTER__MASK 0x00000001 @@ -1407,8 +1640,20 @@ static inline uint32_t A2XX_SQ_PS_CONST_SIZE(uint32_t val) #define REG_A2XX_PA_SC_AA_MASK 0x00002312 #define REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL 0x00002316 +#define A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL_VTX_REUSE_DEPTH__MASK 0x00000007 +#define A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL_VTX_REUSE_DEPTH__SHIFT 0 +static inline uint32_t A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL_VTX_REUSE_DEPTH(uint32_t val) +{ + return ((val) << A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL_VTX_REUSE_DEPTH__SHIFT) & A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL_VTX_REUSE_DEPTH__MASK; +} #define REG_A2XX_VGT_OUT_DEALLOC_CNTL 0x00002317 +#define A2XX_VGT_OUT_DEALLOC_CNTL_DEALLOC_DIST__MASK 0x00000003 +#define A2XX_VGT_OUT_DEALLOC_CNTL_DEALLOC_DIST__SHIFT 0 +static inline uint32_t A2XX_VGT_OUT_DEALLOC_CNTL_DEALLOC_DIST(uint32_t val) +{ + return ((val) << A2XX_VGT_OUT_DEALLOC_CNTL_DEALLOC_DIST__SHIFT) & A2XX_VGT_OUT_DEALLOC_CNTL_DEALLOC_DIST__MASK; +} #define REG_A2XX_RB_COPY_CONTROL 0x00002318 #define A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__MASK 0x00000007 diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h index a066c8b..663a732 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h @@ -8,17 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2016-04-26 17:56:44) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32907 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 12025 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 22544 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 110765 bytes, from 2016-11-26 23:01:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 90321 bytes, from 2016-11-28 16:50:05) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) - -Copyright (C) 2013-2016 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 37162 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 13324 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 31866 bytes, from 2017-06-06 18:26:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 111898 bytes, from 2017-06-06 18:23:59) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 139480 bytes, from 2017-06-16 12:44:39) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 7fd7795..0e3828ed 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -40,6 +40,7 @@ extern bool hang_debug; static void a3xx_dump(struct msm_gpu *gpu); +static bool a3xx_idle(struct msm_gpu *gpu); static bool a3xx_me_init(struct msm_gpu *gpu) { @@ -65,7 +66,7 @@ static bool a3xx_me_init(struct msm_gpu *gpu) OUT_RING(ring, 0x00000000); gpu->funcs->flush(gpu); - return gpu->funcs->idle(gpu); + return a3xx_idle(gpu); } static int a3xx_hw_init(struct msm_gpu *gpu) @@ -446,7 +447,6 @@ static const struct adreno_gpu_funcs funcs = { .last_fence = adreno_last_fence, .submit = adreno_submit, .flush = adreno_flush, - .idle = a3xx_idle, .irq = a3xx_irq, .destroy = a3xx_destroy, #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/msm/adreno/a4xx.xml.h b/drivers/gpu/drm/msm/adreno/a4xx.xml.h index 4ce21b9..1a14f4a 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a4xx.xml.h @@ -8,17 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2016-04-26 17:56:44) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32907 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 12025 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 22544 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 110765 bytes, from 2016-11-26 23:01:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 90321 bytes, from 2016-11-28 16:50:05) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) - -Copyright (C) 2013-2016 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 37162 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 13324 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 31866 bytes, from 2017-06-06 18:26:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 111898 bytes, from 2017-06-06 18:23:59) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 139480 bytes, from 2017-06-16 12:44:39) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) @@ -3010,11 +3010,11 @@ static inline uint32_t A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val) static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_1(uint32_t i0) { return 0x0000220b + 0x4*i0; } static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_2(uint32_t i0) { return 0x0000220c + 0x4*i0; } -#define A4XX_VFD_FETCH_INSTR_2_SIZE__MASK 0xfffffff0 -#define A4XX_VFD_FETCH_INSTR_2_SIZE__SHIFT 4 +#define A4XX_VFD_FETCH_INSTR_2_SIZE__MASK 0xffffffff +#define A4XX_VFD_FETCH_INSTR_2_SIZE__SHIFT 0 static inline uint32_t A4XX_VFD_FETCH_INSTR_2_SIZE(uint32_t val) { - return ((val >> 4) << A4XX_VFD_FETCH_INSTR_2_SIZE__SHIFT) & A4XX_VFD_FETCH_INSTR_2_SIZE__MASK; + return ((val) << A4XX_VFD_FETCH_INSTR_2_SIZE__SHIFT) & A4XX_VFD_FETCH_INSTR_2_SIZE__MASK; } static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_3(uint32_t i0) { return 0x0000220d + 0x4*i0; } @@ -3829,6 +3829,44 @@ static inline uint32_t A4XX_PC_HS_PARAM_SPACING(enum a4xx_tess_spacing val) #define REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB 0x00003049 +#define REG_A4XX_VBIF_PERF_CNT_EN0 0x000030c0 + +#define REG_A4XX_VBIF_PERF_CNT_EN1 0x000030c1 + +#define REG_A4XX_VBIF_PERF_CNT_EN2 0x000030c2 + +#define REG_A4XX_VBIF_PERF_CNT_EN3 0x000030c3 + +#define REG_A4XX_VBIF_PERF_CNT_SEL0 0x000030d0 + +#define REG_A4XX_VBIF_PERF_CNT_SEL1 0x000030d1 + +#define REG_A4XX_VBIF_PERF_CNT_SEL2 0x000030d2 + +#define REG_A4XX_VBIF_PERF_CNT_SEL3 0x000030d3 + +#define REG_A4XX_VBIF_PERF_CNT_LOW0 0x000030d8 + +#define REG_A4XX_VBIF_PERF_CNT_LOW1 0x000030d9 + +#define REG_A4XX_VBIF_PERF_CNT_LOW2 0x000030da + +#define REG_A4XX_VBIF_PERF_CNT_LOW3 0x000030db + +#define REG_A4XX_VBIF_PERF_CNT_HIGH0 0x000030e0 + +#define REG_A4XX_VBIF_PERF_CNT_HIGH1 0x000030e1 + +#define REG_A4XX_VBIF_PERF_CNT_HIGH2 0x000030e2 + +#define REG_A4XX_VBIF_PERF_CNT_HIGH3 0x000030e3 + +#define REG_A4XX_VBIF_PERF_PWR_CNT_EN0 0x00003100 + +#define REG_A4XX_VBIF_PERF_PWR_CNT_EN1 0x00003101 + +#define REG_A4XX_VBIF_PERF_PWR_CNT_EN2 0x00003102 + #define REG_A4XX_UNKNOWN_0CC5 0x00000cc5 #define REG_A4XX_UNKNOWN_0CC6 0x00000cc6 diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index dfe0ece..19abf22 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -31,6 +31,7 @@ extern bool hang_debug; static void a4xx_dump(struct msm_gpu *gpu); +static bool a4xx_idle(struct msm_gpu *gpu); /* * a4xx_enable_hwcg() - Program the clock control registers @@ -137,7 +138,7 @@ static bool a4xx_me_init(struct msm_gpu *gpu) OUT_RING(ring, 0x00000000); gpu->funcs->flush(gpu); - return gpu->funcs->idle(gpu); + return a4xx_idle(gpu); } static int a4xx_hw_init(struct msm_gpu *gpu) @@ -534,7 +535,6 @@ static const struct adreno_gpu_funcs funcs = { .last_fence = adreno_last_fence, .submit = adreno_submit, .flush = adreno_flush, - .idle = a4xx_idle, .irq = a4xx_irq, .destroy = a4xx_destroy, #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/msm/adreno/a5xx.xml.h b/drivers/gpu/drm/msm/adreno/a5xx.xml.h index b6fe763..e0e6711f 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a5xx.xml.h @@ -8,17 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2016-04-26 17:56:44) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32907 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 12025 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 22544 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 110765 bytes, from 2016-11-26 23:01:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 90321 bytes, from 2016-11-28 16:50:05) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) - -Copyright (C) 2013-2016 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 37162 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 13324 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 31866 bytes, from 2017-06-06 18:26:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 111898 bytes, from 2017-06-06 18:23:59) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 139480 bytes, from 2017-06-16 12:44:39) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) @@ -45,20 +45,50 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. enum a5xx_color_fmt { + RB5_A8_UNORM = 2, RB5_R8_UNORM = 3, + RB5_R8_SNORM = 4, + RB5_R8_UINT = 5, + RB5_R8_SINT = 6, RB5_R4G4B4A4_UNORM = 8, RB5_R5G5B5A1_UNORM = 10, RB5_R5G6B5_UNORM = 14, + RB5_R8G8_UNORM = 15, + RB5_R8G8_SNORM = 16, + RB5_R8G8_UINT = 17, + RB5_R8G8_SINT = 18, + RB5_R16_UNORM = 21, + RB5_R16_SNORM = 22, RB5_R16_FLOAT = 23, + RB5_R16_UINT = 24, + RB5_R16_SINT = 25, RB5_R8G8B8A8_UNORM = 48, RB5_R8G8B8_UNORM = 49, + RB5_R8G8B8A8_SNORM = 50, RB5_R8G8B8A8_UINT = 51, + RB5_R8G8B8A8_SINT = 52, + RB5_R10G10B10A2_UNORM = 55, RB5_R10G10B10A2_UINT = 58, + RB5_R11G11B10_FLOAT = 66, + RB5_R16G16_UNORM = 67, + RB5_R16G16_SNORM = 68, RB5_R16G16_FLOAT = 69, + RB5_R16G16_UINT = 70, + RB5_R16G16_SINT = 71, RB5_R32_FLOAT = 74, + RB5_R32_UINT = 75, + RB5_R32_SINT = 76, + RB5_R16G16B16A16_UNORM = 96, + RB5_R16G16B16A16_SNORM = 97, RB5_R16G16B16A16_FLOAT = 98, + RB5_R16G16B16A16_UINT = 99, + RB5_R16G16B16A16_SINT = 100, RB5_R32G32_FLOAT = 103, + RB5_R32G32_UINT = 104, + RB5_R32G32_SINT = 105, RB5_R32G32B32A32_FLOAT = 130, + RB5_R32G32B32A32_UINT = 131, + RB5_R32G32B32A32_SINT = 132, }; enum a5xx_tile_mode { @@ -133,25 +163,55 @@ enum a5xx_vtx_fmt { enum a5xx_tex_fmt { TFMT5_A8_UNORM = 2, TFMT5_8_UNORM = 3, + TFMT5_8_SNORM = 4, + TFMT5_8_UINT = 5, + TFMT5_8_SINT = 6, TFMT5_4_4_4_4_UNORM = 8, TFMT5_5_5_5_1_UNORM = 10, TFMT5_5_6_5_UNORM = 14, TFMT5_8_8_UNORM = 15, TFMT5_8_8_SNORM = 16, + TFMT5_8_8_UINT = 17, + TFMT5_8_8_SINT = 18, TFMT5_L8_A8_UNORM = 19, + TFMT5_16_UNORM = 21, + TFMT5_16_SNORM = 22, TFMT5_16_FLOAT = 23, + TFMT5_16_UINT = 24, + TFMT5_16_SINT = 25, TFMT5_8_8_8_8_UNORM = 48, TFMT5_8_8_8_UNORM = 49, - TFMT5_8_8_8_SNORM = 50, + TFMT5_8_8_8_8_SNORM = 50, + TFMT5_8_8_8_8_UINT = 51, + TFMT5_8_8_8_8_SINT = 52, TFMT5_9_9_9_E5_FLOAT = 53, TFMT5_10_10_10_2_UNORM = 54, + TFMT5_10_10_10_2_UINT = 58, TFMT5_11_11_10_FLOAT = 66, + TFMT5_16_16_UNORM = 67, + TFMT5_16_16_SNORM = 68, TFMT5_16_16_FLOAT = 69, + TFMT5_16_16_UINT = 70, + TFMT5_16_16_SINT = 71, TFMT5_32_FLOAT = 74, + TFMT5_32_UINT = 75, + TFMT5_32_SINT = 76, + TFMT5_16_16_16_16_UNORM = 96, + TFMT5_16_16_16_16_SNORM = 97, TFMT5_16_16_16_16_FLOAT = 98, + TFMT5_16_16_16_16_UINT = 99, + TFMT5_16_16_16_16_SINT = 100, TFMT5_32_32_FLOAT = 103, + TFMT5_32_32_UINT = 104, + TFMT5_32_32_SINT = 105, TFMT5_32_32_32_32_FLOAT = 130, + TFMT5_32_32_32_32_UINT = 131, + TFMT5_32_32_32_32_SINT = 132, TFMT5_X8Z24_UNORM = 160, + TFMT5_RGTC1_UNORM = 183, + TFMT5_RGTC1_SNORM = 184, + TFMT5_RGTC2_UNORM = 187, + TFMT5_RGTC2_SNORM = 188, }; enum a5xx_tex_fetchsize { @@ -182,6 +242,565 @@ enum a5xx_blit_buf { BLIT_Z32 = 9, }; +enum a5xx_cp_perfcounter_select { + PERF_CP_ALWAYS_COUNT = 0, + PERF_CP_BUSY_GFX_CORE_IDLE = 1, + PERF_CP_BUSY_CYCLES = 2, + PERF_CP_PFP_IDLE = 3, + PERF_CP_PFP_BUSY_WORKING = 4, + PERF_CP_PFP_STALL_CYCLES_ANY = 5, + PERF_CP_PFP_STARVE_CYCLES_ANY = 6, + PERF_CP_PFP_ICACHE_MISS = 7, + PERF_CP_PFP_ICACHE_HIT = 8, + PERF_CP_PFP_MATCH_PM4_PKT_PROFILE = 9, + PERF_CP_ME_BUSY_WORKING = 10, + PERF_CP_ME_IDLE = 11, + PERF_CP_ME_STARVE_CYCLES_ANY = 12, + PERF_CP_ME_FIFO_EMPTY_PFP_IDLE = 13, + PERF_CP_ME_FIFO_EMPTY_PFP_BUSY = 14, + PERF_CP_ME_FIFO_FULL_ME_BUSY = 15, + PERF_CP_ME_FIFO_FULL_ME_NON_WORKING = 16, + PERF_CP_ME_STALL_CYCLES_ANY = 17, + PERF_CP_ME_ICACHE_MISS = 18, + PERF_CP_ME_ICACHE_HIT = 19, + PERF_CP_NUM_PREEMPTIONS = 20, + PERF_CP_PREEMPTION_REACTION_DELAY = 21, + PERF_CP_PREEMPTION_SWITCH_OUT_TIME = 22, + PERF_CP_PREEMPTION_SWITCH_IN_TIME = 23, + PERF_CP_DEAD_DRAWS_IN_BIN_RENDER = 24, + PERF_CP_PREDICATED_DRAWS_KILLED = 25, + PERF_CP_MODE_SWITCH = 26, + PERF_CP_ZPASS_DONE = 27, + PERF_CP_CONTEXT_DONE = 28, + PERF_CP_CACHE_FLUSH = 29, + PERF_CP_LONG_PREEMPTIONS = 30, +}; + +enum a5xx_rbbm_perfcounter_select { + PERF_RBBM_ALWAYS_COUNT = 0, + PERF_RBBM_ALWAYS_ON = 1, + PERF_RBBM_TSE_BUSY = 2, + PERF_RBBM_RAS_BUSY = 3, + PERF_RBBM_PC_DCALL_BUSY = 4, + PERF_RBBM_PC_VSD_BUSY = 5, + PERF_RBBM_STATUS_MASKED = 6, + PERF_RBBM_COM_BUSY = 7, + PERF_RBBM_DCOM_BUSY = 8, + PERF_RBBM_VBIF_BUSY = 9, + PERF_RBBM_VSC_BUSY = 10, + PERF_RBBM_TESS_BUSY = 11, + PERF_RBBM_UCHE_BUSY = 12, + PERF_RBBM_HLSQ_BUSY = 13, +}; + +enum a5xx_pc_perfcounter_select { + PERF_PC_BUSY_CYCLES = 0, + PERF_PC_WORKING_CYCLES = 1, + PERF_PC_STALL_CYCLES_VFD = 2, + PERF_PC_STALL_CYCLES_TSE = 3, + PERF_PC_STALL_CYCLES_VPC = 4, + PERF_PC_STALL_CYCLES_UCHE = 5, + PERF_PC_STALL_CYCLES_TESS = 6, + PERF_PC_STALL_CYCLES_TSE_ONLY = 7, + PERF_PC_STALL_CYCLES_VPC_ONLY = 8, + PERF_PC_PASS1_TF_STALL_CYCLES = 9, + PERF_PC_STARVE_CYCLES_FOR_INDEX = 10, + PERF_PC_STARVE_CYCLES_FOR_TESS_FACTOR = 11, + PERF_PC_STARVE_CYCLES_FOR_VIZ_STREAM = 12, + PERF_PC_STARVE_CYCLES_FOR_POSITION = 13, + PERF_PC_STARVE_CYCLES_DI = 14, + PERF_PC_VIS_STREAMS_LOADED = 15, + PERF_PC_INSTANCES = 16, + PERF_PC_VPC_PRIMITIVES = 17, + PERF_PC_DEAD_PRIM = 18, + PERF_PC_LIVE_PRIM = 19, + PERF_PC_VERTEX_HITS = 20, + PERF_PC_IA_VERTICES = 21, + PERF_PC_IA_PRIMITIVES = 22, + PERF_PC_GS_PRIMITIVES = 23, + PERF_PC_HS_INVOCATIONS = 24, + PERF_PC_DS_INVOCATIONS = 25, + PERF_PC_VS_INVOCATIONS = 26, + PERF_PC_GS_INVOCATIONS = 27, + PERF_PC_DS_PRIMITIVES = 28, + PERF_PC_VPC_POS_DATA_TRANSACTION = 29, + PERF_PC_3D_DRAWCALLS = 30, + PERF_PC_2D_DRAWCALLS = 31, + PERF_PC_NON_DRAWCALL_GLOBAL_EVENTS = 32, + PERF_TESS_BUSY_CYCLES = 33, + PERF_TESS_WORKING_CYCLES = 34, + PERF_TESS_STALL_CYCLES_PC = 35, + PERF_TESS_STARVE_CYCLES_PC = 36, +}; + +enum a5xx_vfd_perfcounter_select { + PERF_VFD_BUSY_CYCLES = 0, + PERF_VFD_STALL_CYCLES_UCHE = 1, + PERF_VFD_STALL_CYCLES_VPC_ALLOC = 2, + PERF_VFD_STALL_CYCLES_MISS_VB = 3, + PERF_VFD_STALL_CYCLES_MISS_Q = 4, + PERF_VFD_STALL_CYCLES_SP_INFO = 5, + PERF_VFD_STALL_CYCLES_SP_ATTR = 6, + PERF_VFD_STALL_CYCLES_VFDP_VB = 7, + PERF_VFD_STALL_CYCLES_VFDP_Q = 8, + PERF_VFD_DECODER_PACKER_STALL = 9, + PERF_VFD_STARVE_CYCLES_UCHE = 10, + PERF_VFD_RBUFFER_FULL = 11, + PERF_VFD_ATTR_INFO_FIFO_FULL = 12, + PERF_VFD_DECODED_ATTRIBUTE_BYTES = 13, + PERF_VFD_NUM_ATTRIBUTES = 14, + PERF_VFD_INSTRUCTIONS = 15, + PERF_VFD_UPPER_SHADER_FIBERS = 16, + PERF_VFD_LOWER_SHADER_FIBERS = 17, + PERF_VFD_MODE_0_FIBERS = 18, + PERF_VFD_MODE_1_FIBERS = 19, + PERF_VFD_MODE_2_FIBERS = 20, + PERF_VFD_MODE_3_FIBERS = 21, + PERF_VFD_MODE_4_FIBERS = 22, + PERF_VFD_TOTAL_VERTICES = 23, + PERF_VFD_NUM_ATTR_MISS = 24, + PERF_VFD_1_BURST_REQ = 25, + PERF_VFDP_STALL_CYCLES_VFD = 26, + PERF_VFDP_STALL_CYCLES_VFD_INDEX = 27, + PERF_VFDP_STALL_CYCLES_VFD_PROG = 28, + PERF_VFDP_STARVE_CYCLES_PC = 29, + PERF_VFDP_VS_STAGE_32_WAVES = 30, +}; + +enum a5xx_hlsq_perfcounter_select { + PERF_HLSQ_BUSY_CYCLES = 0, + PERF_HLSQ_STALL_CYCLES_UCHE = 1, + PERF_HLSQ_STALL_CYCLES_SP_STATE = 2, + PERF_HLSQ_STALL_CYCLES_SP_FS_STAGE = 3, + PERF_HLSQ_UCHE_LATENCY_CYCLES = 4, + PERF_HLSQ_UCHE_LATENCY_COUNT = 5, + PERF_HLSQ_FS_STAGE_32_WAVES = 6, + PERF_HLSQ_FS_STAGE_64_WAVES = 7, + PERF_HLSQ_QUADS = 8, + PERF_HLSQ_SP_STATE_COPY_TRANS_FS_STAGE = 9, + PERF_HLSQ_SP_STATE_COPY_TRANS_VS_STAGE = 10, + PERF_HLSQ_TP_STATE_COPY_TRANS_FS_STAGE = 11, + PERF_HLSQ_TP_STATE_COPY_TRANS_VS_STAGE = 12, + PERF_HLSQ_CS_INVOCATIONS = 13, + PERF_HLSQ_COMPUTE_DRAWCALLS = 14, +}; + +enum a5xx_vpc_perfcounter_select { + PERF_VPC_BUSY_CYCLES = 0, + PERF_VPC_WORKING_CYCLES = 1, + PERF_VPC_STALL_CYCLES_UCHE = 2, + PERF_VPC_STALL_CYCLES_VFD_WACK = 3, + PERF_VPC_STALL_CYCLES_HLSQ_PRIM_ALLOC = 4, + PERF_VPC_STALL_CYCLES_PC = 5, + PERF_VPC_STALL_CYCLES_SP_LM = 6, + PERF_VPC_POS_EXPORT_STALL_CYCLES = 7, + PERF_VPC_STARVE_CYCLES_SP = 8, + PERF_VPC_STARVE_CYCLES_LRZ = 9, + PERF_VPC_PC_PRIMITIVES = 10, + PERF_VPC_SP_COMPONENTS = 11, + PERF_VPC_SP_LM_PRIMITIVES = 12, + PERF_VPC_SP_LM_COMPONENTS = 13, + PERF_VPC_SP_LM_DWORDS = 14, + PERF_VPC_STREAMOUT_COMPONENTS = 15, + PERF_VPC_GRANT_PHASES = 16, +}; + +enum a5xx_tse_perfcounter_select { + PERF_TSE_BUSY_CYCLES = 0, + PERF_TSE_CLIPPING_CYCLES = 1, + PERF_TSE_STALL_CYCLES_RAS = 2, + PERF_TSE_STALL_CYCLES_LRZ_BARYPLANE = 3, + PERF_TSE_STALL_CYCLES_LRZ_ZPLANE = 4, + PERF_TSE_STARVE_CYCLES_PC = 5, + PERF_TSE_INPUT_PRIM = 6, + PERF_TSE_INPUT_NULL_PRIM = 7, + PERF_TSE_TRIVAL_REJ_PRIM = 8, + PERF_TSE_CLIPPED_PRIM = 9, + PERF_TSE_ZERO_AREA_PRIM = 10, + PERF_TSE_FACENESS_CULLED_PRIM = 11, + PERF_TSE_ZERO_PIXEL_PRIM = 12, + PERF_TSE_OUTPUT_NULL_PRIM = 13, + PERF_TSE_OUTPUT_VISIBLE_PRIM = 14, + PERF_TSE_CINVOCATION = 15, + PERF_TSE_CPRIMITIVES = 16, + PERF_TSE_2D_INPUT_PRIM = 17, + PERF_TSE_2D_ALIVE_CLCLES = 18, +}; + +enum a5xx_ras_perfcounter_select { + PERF_RAS_BUSY_CYCLES = 0, + PERF_RAS_SUPERTILE_ACTIVE_CYCLES = 1, + PERF_RAS_STALL_CYCLES_LRZ = 2, + PERF_RAS_STARVE_CYCLES_TSE = 3, + PERF_RAS_SUPER_TILES = 4, + PERF_RAS_8X4_TILES = 5, + PERF_RAS_MASKGEN_ACTIVE = 6, + PERF_RAS_FULLY_COVERED_SUPER_TILES = 7, + PERF_RAS_FULLY_COVERED_8X4_TILES = 8, + PERF_RAS_PRIM_KILLED_INVISILBE = 9, +}; + +enum a5xx_lrz_perfcounter_select { + PERF_LRZ_BUSY_CYCLES = 0, + PERF_LRZ_STARVE_CYCLES_RAS = 1, + PERF_LRZ_STALL_CYCLES_RB = 2, + PERF_LRZ_STALL_CYCLES_VSC = 3, + PERF_LRZ_STALL_CYCLES_VPC = 4, + PERF_LRZ_STALL_CYCLES_FLAG_PREFETCH = 5, + PERF_LRZ_STALL_CYCLES_UCHE = 6, + PERF_LRZ_LRZ_READ = 7, + PERF_LRZ_LRZ_WRITE = 8, + PERF_LRZ_READ_LATENCY = 9, + PERF_LRZ_MERGE_CACHE_UPDATING = 10, + PERF_LRZ_PRIM_KILLED_BY_MASKGEN = 11, + PERF_LRZ_PRIM_KILLED_BY_LRZ = 12, + PERF_LRZ_VISIBLE_PRIM_AFTER_LRZ = 13, + PERF_LRZ_FULL_8X8_TILES = 14, + PERF_LRZ_PARTIAL_8X8_TILES = 15, + PERF_LRZ_TILE_KILLED = 16, + PERF_LRZ_TOTAL_PIXEL = 17, + PERF_LRZ_VISIBLE_PIXEL_AFTER_LRZ = 18, +}; + +enum a5xx_uche_perfcounter_select { + PERF_UCHE_BUSY_CYCLES = 0, + PERF_UCHE_STALL_CYCLES_VBIF = 1, + PERF_UCHE_VBIF_LATENCY_CYCLES = 2, + PERF_UCHE_VBIF_LATENCY_SAMPLES = 3, + PERF_UCHE_VBIF_READ_BEATS_TP = 4, + PERF_UCHE_VBIF_READ_BEATS_VFD = 5, + PERF_UCHE_VBIF_READ_BEATS_HLSQ = 6, + PERF_UCHE_VBIF_READ_BEATS_LRZ = 7, + PERF_UCHE_VBIF_READ_BEATS_SP = 8, + PERF_UCHE_READ_REQUESTS_TP = 9, + PERF_UCHE_READ_REQUESTS_VFD = 10, + PERF_UCHE_READ_REQUESTS_HLSQ = 11, + PERF_UCHE_READ_REQUESTS_LRZ = 12, + PERF_UCHE_READ_REQUESTS_SP = 13, + PERF_UCHE_WRITE_REQUESTS_LRZ = 14, + PERF_UCHE_WRITE_REQUESTS_SP = 15, + PERF_UCHE_WRITE_REQUESTS_VPC = 16, + PERF_UCHE_WRITE_REQUESTS_VSC = 17, + PERF_UCHE_EVICTS = 18, + PERF_UCHE_BANK_REQ0 = 19, + PERF_UCHE_BANK_REQ1 = 20, + PERF_UCHE_BANK_REQ2 = 21, + PERF_UCHE_BANK_REQ3 = 22, + PERF_UCHE_BANK_REQ4 = 23, + PERF_UCHE_BANK_REQ5 = 24, + PERF_UCHE_BANK_REQ6 = 25, + PERF_UCHE_BANK_REQ7 = 26, + PERF_UCHE_VBIF_READ_BEATS_CH0 = 27, + PERF_UCHE_VBIF_READ_BEATS_CH1 = 28, + PERF_UCHE_GMEM_READ_BEATS = 29, + PERF_UCHE_FLAG_COUNT = 30, +}; + +enum a5xx_tp_perfcounter_select { + PERF_TP_BUSY_CYCLES = 0, + PERF_TP_STALL_CYCLES_UCHE = 1, + PERF_TP_LATENCY_CYCLES = 2, + PERF_TP_LATENCY_TRANS = 3, + PERF_TP_FLAG_CACHE_REQUEST_SAMPLES = 4, + PERF_TP_FLAG_CACHE_REQUEST_LATENCY = 5, + PERF_TP_L1_CACHELINE_REQUESTS = 6, + PERF_TP_L1_CACHELINE_MISSES = 7, + PERF_TP_SP_TP_TRANS = 8, + PERF_TP_TP_SP_TRANS = 9, + PERF_TP_OUTPUT_PIXELS = 10, + PERF_TP_FILTER_WORKLOAD_16BIT = 11, + PERF_TP_FILTER_WORKLOAD_32BIT = 12, + PERF_TP_QUADS_RECEIVED = 13, + PERF_TP_QUADS_OFFSET = 14, + PERF_TP_QUADS_SHADOW = 15, + PERF_TP_QUADS_ARRAY = 16, + PERF_TP_QUADS_GRADIENT = 17, + PERF_TP_QUADS_1D = 18, + PERF_TP_QUADS_2D = 19, + PERF_TP_QUADS_BUFFER = 20, + PERF_TP_QUADS_3D = 21, + PERF_TP_QUADS_CUBE = 22, + PERF_TP_STATE_CACHE_REQUESTS = 23, + PERF_TP_STATE_CACHE_MISSES = 24, + PERF_TP_DIVERGENT_QUADS_RECEIVED = 25, + PERF_TP_BINDLESS_STATE_CACHE_REQUESTS = 26, + PERF_TP_BINDLESS_STATE_CACHE_MISSES = 27, + PERF_TP_PRT_NON_RESIDENT_EVENTS = 28, + PERF_TP_OUTPUT_PIXELS_POINT = 29, + PERF_TP_OUTPUT_PIXELS_BILINEAR = 30, + PERF_TP_OUTPUT_PIXELS_MIP = 31, + PERF_TP_OUTPUT_PIXELS_ANISO = 32, + PERF_TP_OUTPUT_PIXELS_ZERO_LOD = 33, + PERF_TP_FLAG_CACHE_REQUESTS = 34, + PERF_TP_FLAG_CACHE_MISSES = 35, + PERF_TP_L1_5_L2_REQUESTS = 36, + PERF_TP_2D_OUTPUT_PIXELS = 37, + PERF_TP_2D_OUTPUT_PIXELS_POINT = 38, + PERF_TP_2D_OUTPUT_PIXELS_BILINEAR = 39, + PERF_TP_2D_FILTER_WORKLOAD_16BIT = 40, + PERF_TP_2D_FILTER_WORKLOAD_32BIT = 41, +}; + +enum a5xx_sp_perfcounter_select { + PERF_SP_BUSY_CYCLES = 0, + PERF_SP_ALU_WORKING_CYCLES = 1, + PERF_SP_EFU_WORKING_CYCLES = 2, + PERF_SP_STALL_CYCLES_VPC = 3, + PERF_SP_STALL_CYCLES_TP = 4, + PERF_SP_STALL_CYCLES_UCHE = 5, + PERF_SP_STALL_CYCLES_RB = 6, + PERF_SP_SCHEDULER_NON_WORKING = 7, + PERF_SP_WAVE_CONTEXTS = 8, + PERF_SP_WAVE_CONTEXT_CYCLES = 9, + PERF_SP_FS_STAGE_WAVE_CYCLES = 10, + PERF_SP_FS_STAGE_WAVE_SAMPLES = 11, + PERF_SP_VS_STAGE_WAVE_CYCLES = 12, + PERF_SP_VS_STAGE_WAVE_SAMPLES = 13, + PERF_SP_FS_STAGE_DURATION_CYCLES = 14, + PERF_SP_VS_STAGE_DURATION_CYCLES = 15, + PERF_SP_WAVE_CTRL_CYCLES = 16, + PERF_SP_WAVE_LOAD_CYCLES = 17, + PERF_SP_WAVE_EMIT_CYCLES = 18, + PERF_SP_WAVE_NOP_CYCLES = 19, + PERF_SP_WAVE_WAIT_CYCLES = 20, + PERF_SP_WAVE_FETCH_CYCLES = 21, + PERF_SP_WAVE_IDLE_CYCLES = 22, + PERF_SP_WAVE_END_CYCLES = 23, + PERF_SP_WAVE_LONG_SYNC_CYCLES = 24, + PERF_SP_WAVE_SHORT_SYNC_CYCLES = 25, + PERF_SP_WAVE_JOIN_CYCLES = 26, + PERF_SP_LM_LOAD_INSTRUCTIONS = 27, + PERF_SP_LM_STORE_INSTRUCTIONS = 28, + PERF_SP_LM_ATOMICS = 29, + PERF_SP_GM_LOAD_INSTRUCTIONS = 30, + PERF_SP_GM_STORE_INSTRUCTIONS = 31, + PERF_SP_GM_ATOMICS = 32, + PERF_SP_VS_STAGE_TEX_INSTRUCTIONS = 33, + PERF_SP_VS_STAGE_CFLOW_INSTRUCTIONS = 34, + PERF_SP_VS_STAGE_EFU_INSTRUCTIONS = 35, + PERF_SP_VS_STAGE_FULL_ALU_INSTRUCTIONS = 36, + PERF_SP_VS_STAGE_HALF_ALU_INSTRUCTIONS = 37, + PERF_SP_FS_STAGE_TEX_INSTRUCTIONS = 38, + PERF_SP_FS_STAGE_CFLOW_INSTRUCTIONS = 39, + PERF_SP_FS_STAGE_EFU_INSTRUCTIONS = 40, + PERF_SP_FS_STAGE_FULL_ALU_INSTRUCTIONS = 41, + PERF_SP_FS_STAGE_HALF_ALU_INSTRUCTIONS = 42, + PERF_SP_FS_STAGE_BARY_INSTRUCTIONS = 43, + PERF_SP_VS_INSTRUCTIONS = 44, + PERF_SP_FS_INSTRUCTIONS = 45, + PERF_SP_ADDR_LOCK_COUNT = 46, + PERF_SP_UCHE_READ_TRANS = 47, + PERF_SP_UCHE_WRITE_TRANS = 48, + PERF_SP_EXPORT_VPC_TRANS = 49, + PERF_SP_EXPORT_RB_TRANS = 50, + PERF_SP_PIXELS_KILLED = 51, + PERF_SP_ICL1_REQUESTS = 52, + PERF_SP_ICL1_MISSES = 53, + PERF_SP_ICL0_REQUESTS = 54, + PERF_SP_ICL0_MISSES = 55, + PERF_SP_HS_INSTRUCTIONS = 56, + PERF_SP_DS_INSTRUCTIONS = 57, + PERF_SP_GS_INSTRUCTIONS = 58, + PERF_SP_CS_INSTRUCTIONS = 59, + PERF_SP_GPR_READ = 60, + PERF_SP_GPR_WRITE = 61, + PERF_SP_LM_CH0_REQUESTS = 62, + PERF_SP_LM_CH1_REQUESTS = 63, + PERF_SP_LM_BANK_CONFLICTS = 64, +}; + +enum a5xx_rb_perfcounter_select { + PERF_RB_BUSY_CYCLES = 0, + PERF_RB_STALL_CYCLES_CCU = 1, + PERF_RB_STALL_CYCLES_HLSQ = 2, + PERF_RB_STALL_CYCLES_FIFO0_FULL = 3, + PERF_RB_STALL_CYCLES_FIFO1_FULL = 4, + PERF_RB_STALL_CYCLES_FIFO2_FULL = 5, + PERF_RB_STARVE_CYCLES_SP = 6, + PERF_RB_STARVE_CYCLES_LRZ_TILE = 7, + PERF_RB_STARVE_CYCLES_CCU = 8, + PERF_RB_STARVE_CYCLES_Z_PLANE = 9, + PERF_RB_STARVE_CYCLES_BARY_PLANE = 10, + PERF_RB_Z_WORKLOAD = 11, + PERF_RB_HLSQ_ACTIVE = 12, + PERF_RB_Z_READ = 13, + PERF_RB_Z_WRITE = 14, + PERF_RB_C_READ = 15, + PERF_RB_C_WRITE = 16, + PERF_RB_TOTAL_PASS = 17, + PERF_RB_Z_PASS = 18, + PERF_RB_Z_FAIL = 19, + PERF_RB_S_FAIL = 20, + PERF_RB_BLENDED_FXP_COMPONENTS = 21, + PERF_RB_BLENDED_FP16_COMPONENTS = 22, + RB_RESERVED = 23, + PERF_RB_2D_ALIVE_CYCLES = 24, + PERF_RB_2D_STALL_CYCLES_A2D = 25, + PERF_RB_2D_STARVE_CYCLES_SRC = 26, + PERF_RB_2D_STARVE_CYCLES_SP = 27, + PERF_RB_2D_STARVE_CYCLES_DST = 28, + PERF_RB_2D_VALID_PIXELS = 29, +}; + +enum a5xx_rb_samples_perfcounter_select { + TOTAL_SAMPLES = 0, + ZPASS_SAMPLES = 1, + ZFAIL_SAMPLES = 2, + SFAIL_SAMPLES = 3, +}; + +enum a5xx_vsc_perfcounter_select { + PERF_VSC_BUSY_CYCLES = 0, + PERF_VSC_WORKING_CYCLES = 1, + PERF_VSC_STALL_CYCLES_UCHE = 2, + PERF_VSC_EOT_NUM = 3, +}; + +enum a5xx_ccu_perfcounter_select { + PERF_CCU_BUSY_CYCLES = 0, + PERF_CCU_STALL_CYCLES_RB_DEPTH_RETURN = 1, + PERF_CCU_STALL_CYCLES_RB_COLOR_RETURN = 2, + PERF_CCU_STARVE_CYCLES_FLAG_RETURN = 3, + PERF_CCU_DEPTH_BLOCKS = 4, + PERF_CCU_COLOR_BLOCKS = 5, + PERF_CCU_DEPTH_BLOCK_HIT = 6, + PERF_CCU_COLOR_BLOCK_HIT = 7, + PERF_CCU_PARTIAL_BLOCK_READ = 8, + PERF_CCU_GMEM_READ = 9, + PERF_CCU_GMEM_WRITE = 10, + PERF_CCU_DEPTH_READ_FLAG0_COUNT = 11, + PERF_CCU_DEPTH_READ_FLAG1_COUNT = 12, + PERF_CCU_DEPTH_READ_FLAG2_COUNT = 13, + PERF_CCU_DEPTH_READ_FLAG3_COUNT = 14, + PERF_CCU_DEPTH_READ_FLAG4_COUNT = 15, + PERF_CCU_COLOR_READ_FLAG0_COUNT = 16, + PERF_CCU_COLOR_READ_FLAG1_COUNT = 17, + PERF_CCU_COLOR_READ_FLAG2_COUNT = 18, + PERF_CCU_COLOR_READ_FLAG3_COUNT = 19, + PERF_CCU_COLOR_READ_FLAG4_COUNT = 20, + PERF_CCU_2D_BUSY_CYCLES = 21, + PERF_CCU_2D_RD_REQ = 22, + PERF_CCU_2D_WR_REQ = 23, + PERF_CCU_2D_REORDER_STARVE_CYCLES = 24, + PERF_CCU_2D_PIXELS = 25, +}; + +enum a5xx_cmp_perfcounter_select { + PERF_CMPDECMP_STALL_CYCLES_VBIF = 0, + PERF_CMPDECMP_VBIF_LATENCY_CYCLES = 1, + PERF_CMPDECMP_VBIF_LATENCY_SAMPLES = 2, + PERF_CMPDECMP_VBIF_READ_DATA_CCU = 3, + PERF_CMPDECMP_VBIF_WRITE_DATA_CCU = 4, + PERF_CMPDECMP_VBIF_READ_REQUEST = 5, + PERF_CMPDECMP_VBIF_WRITE_REQUEST = 6, + PERF_CMPDECMP_VBIF_READ_DATA = 7, + PERF_CMPDECMP_VBIF_WRITE_DATA = 8, + PERF_CMPDECMP_FLAG_FETCH_CYCLES = 9, + PERF_CMPDECMP_FLAG_FETCH_SAMPLES = 10, + PERF_CMPDECMP_DEPTH_WRITE_FLAG1_COUNT = 11, + PERF_CMPDECMP_DEPTH_WRITE_FLAG2_COUNT = 12, + PERF_CMPDECMP_DEPTH_WRITE_FLAG3_COUNT = 13, + PERF_CMPDECMP_DEPTH_WRITE_FLAG4_COUNT = 14, + PERF_CMPDECMP_COLOR_WRITE_FLAG1_COUNT = 15, + PERF_CMPDECMP_COLOR_WRITE_FLAG2_COUNT = 16, + PERF_CMPDECMP_COLOR_WRITE_FLAG3_COUNT = 17, + PERF_CMPDECMP_COLOR_WRITE_FLAG4_COUNT = 18, + PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_REQ = 19, + PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_WR = 20, + PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_RETURN = 21, + PERF_CMPDECMP_2D_RD_DATA = 22, + PERF_CMPDECMP_2D_WR_DATA = 23, +}; + +enum a5xx_vbif_perfcounter_select { + AXI_READ_REQUESTS_ID_0 = 0, + AXI_READ_REQUESTS_ID_1 = 1, + AXI_READ_REQUESTS_ID_2 = 2, + AXI_READ_REQUESTS_ID_3 = 3, + AXI_READ_REQUESTS_ID_4 = 4, + AXI_READ_REQUESTS_ID_5 = 5, + AXI_READ_REQUESTS_ID_6 = 6, + AXI_READ_REQUESTS_ID_7 = 7, + AXI_READ_REQUESTS_ID_8 = 8, + AXI_READ_REQUESTS_ID_9 = 9, + AXI_READ_REQUESTS_ID_10 = 10, + AXI_READ_REQUESTS_ID_11 = 11, + AXI_READ_REQUESTS_ID_12 = 12, + AXI_READ_REQUESTS_ID_13 = 13, + AXI_READ_REQUESTS_ID_14 = 14, + AXI_READ_REQUESTS_ID_15 = 15, + AXI0_READ_REQUESTS_TOTAL = 16, + AXI1_READ_REQUESTS_TOTAL = 17, + AXI2_READ_REQUESTS_TOTAL = 18, + AXI3_READ_REQUESTS_TOTAL = 19, + AXI_READ_REQUESTS_TOTAL = 20, + AXI_WRITE_REQUESTS_ID_0 = 21, + AXI_WRITE_REQUESTS_ID_1 = 22, + AXI_WRITE_REQUESTS_ID_2 = 23, + AXI_WRITE_REQUESTS_ID_3 = 24, + AXI_WRITE_REQUESTS_ID_4 = 25, + AXI_WRITE_REQUESTS_ID_5 = 26, + AXI_WRITE_REQUESTS_ID_6 = 27, + AXI_WRITE_REQUESTS_ID_7 = 28, + AXI_WRITE_REQUESTS_ID_8 = 29, + AXI_WRITE_REQUESTS_ID_9 = 30, + AXI_WRITE_REQUESTS_ID_10 = 31, + AXI_WRITE_REQUESTS_ID_11 = 32, + AXI_WRITE_REQUESTS_ID_12 = 33, + AXI_WRITE_REQUESTS_ID_13 = 34, + AXI_WRITE_REQUESTS_ID_14 = 35, + AXI_WRITE_REQUESTS_ID_15 = 36, + AXI0_WRITE_REQUESTS_TOTAL = 37, + AXI1_WRITE_REQUESTS_TOTAL = 38, + AXI2_WRITE_REQUESTS_TOTAL = 39, + AXI3_WRITE_REQUESTS_TOTAL = 40, + AXI_WRITE_REQUESTS_TOTAL = 41, + AXI_TOTAL_REQUESTS = 42, + AXI_READ_DATA_BEATS_ID_0 = 43, + AXI_READ_DATA_BEATS_ID_1 = 44, + AXI_READ_DATA_BEATS_ID_2 = 45, + AXI_READ_DATA_BEATS_ID_3 = 46, + AXI_READ_DATA_BEATS_ID_4 = 47, + AXI_READ_DATA_BEATS_ID_5 = 48, + AXI_READ_DATA_BEATS_ID_6 = 49, + AXI_READ_DATA_BEATS_ID_7 = 50, + AXI_READ_DATA_BEATS_ID_8 = 51, + AXI_READ_DATA_BEATS_ID_9 = 52, + AXI_READ_DATA_BEATS_ID_10 = 53, + AXI_READ_DATA_BEATS_ID_11 = 54, + AXI_READ_DATA_BEATS_ID_12 = 55, + AXI_READ_DATA_BEATS_ID_13 = 56, + AXI_READ_DATA_BEATS_ID_14 = 57, + AXI_READ_DATA_BEATS_ID_15 = 58, + AXI0_READ_DATA_BEATS_TOTAL = 59, + AXI1_READ_DATA_BEATS_TOTAL = 60, + AXI2_READ_DATA_BEATS_TOTAL = 61, + AXI3_READ_DATA_BEATS_TOTAL = 62, + AXI_READ_DATA_BEATS_TOTAL = 63, + AXI_WRITE_DATA_BEATS_ID_0 = 64, + AXI_WRITE_DATA_BEATS_ID_1 = 65, + AXI_WRITE_DATA_BEATS_ID_2 = 66, + AXI_WRITE_DATA_BEATS_ID_3 = 67, + AXI_WRITE_DATA_BEATS_ID_4 = 68, + AXI_WRITE_DATA_BEATS_ID_5 = 69, + AXI_WRITE_DATA_BEATS_ID_6 = 70, + AXI_WRITE_DATA_BEATS_ID_7 = 71, + AXI_WRITE_DATA_BEATS_ID_8 = 72, + AXI_WRITE_DATA_BEATS_ID_9 = 73, + AXI_WRITE_DATA_BEATS_ID_10 = 74, + AXI_WRITE_DATA_BEATS_ID_11 = 75, + AXI_WRITE_DATA_BEATS_ID_12 = 76, + AXI_WRITE_DATA_BEATS_ID_13 = 77, + AXI_WRITE_DATA_BEATS_ID_14 = 78, + AXI_WRITE_DATA_BEATS_ID_15 = 79, + AXI0_WRITE_DATA_BEATS_TOTAL = 80, + AXI1_WRITE_DATA_BEATS_TOTAL = 81, + AXI2_WRITE_DATA_BEATS_TOTAL = 82, + AXI3_WRITE_DATA_BEATS_TOTAL = 83, + AXI_WRITE_DATA_BEATS_TOTAL = 84, + AXI_DATA_BEATS_TOTAL = 85, +}; + enum a5xx_tex_filter { A5XX_TEX_NEAREST = 0, A5XX_TEX_LINEAR = 1, @@ -1289,25 +1908,83 @@ static inline uint32_t A5XX_CP_PROTECT_REG_MASK_LEN(uint32_t val) #define REG_A5XX_RBBM_SECVID_TSB_ADDR_MODE_CNTL 0x0000f810 -#define REG_A5XX_VSC_PIPE_DATA_LENGTH_0 0x00000c00 +#define REG_A5XX_VSC_BIN_SIZE 0x00000bc2 +#define A5XX_VSC_BIN_SIZE_WIDTH__MASK 0x000000ff +#define A5XX_VSC_BIN_SIZE_WIDTH__SHIFT 0 +static inline uint32_t A5XX_VSC_BIN_SIZE_WIDTH(uint32_t val) +{ + return ((val >> 5) << A5XX_VSC_BIN_SIZE_WIDTH__SHIFT) & A5XX_VSC_BIN_SIZE_WIDTH__MASK; +} +#define A5XX_VSC_BIN_SIZE_HEIGHT__MASK 0x0001fe00 +#define A5XX_VSC_BIN_SIZE_HEIGHT__SHIFT 9 +static inline uint32_t A5XX_VSC_BIN_SIZE_HEIGHT(uint32_t val) +{ + return ((val >> 5) << A5XX_VSC_BIN_SIZE_HEIGHT__SHIFT) & A5XX_VSC_BIN_SIZE_HEIGHT__MASK; +} + +#define REG_A5XX_VSC_SIZE_ADDRESS_LO 0x00000bc3 + +#define REG_A5XX_VSC_SIZE_ADDRESS_HI 0x00000bc4 + +#define REG_A5XX_UNKNOWN_0BC5 0x00000bc5 + +#define REG_A5XX_UNKNOWN_0BC6 0x00000bc6 + +static inline uint32_t REG_A5XX_VSC_PIPE_CONFIG(uint32_t i0) { return 0x00000bd0 + 0x1*i0; } + +static inline uint32_t REG_A5XX_VSC_PIPE_CONFIG_REG(uint32_t i0) { return 0x00000bd0 + 0x1*i0; } +#define A5XX_VSC_PIPE_CONFIG_REG_X__MASK 0x000003ff +#define A5XX_VSC_PIPE_CONFIG_REG_X__SHIFT 0 +static inline uint32_t A5XX_VSC_PIPE_CONFIG_REG_X(uint32_t val) +{ + return ((val) << A5XX_VSC_PIPE_CONFIG_REG_X__SHIFT) & A5XX_VSC_PIPE_CONFIG_REG_X__MASK; +} +#define A5XX_VSC_PIPE_CONFIG_REG_Y__MASK 0x000ffc00 +#define A5XX_VSC_PIPE_CONFIG_REG_Y__SHIFT 10 +static inline uint32_t A5XX_VSC_PIPE_CONFIG_REG_Y(uint32_t val) +{ + return ((val) << A5XX_VSC_PIPE_CONFIG_REG_Y__SHIFT) & A5XX_VSC_PIPE_CONFIG_REG_Y__MASK; +} +#define A5XX_VSC_PIPE_CONFIG_REG_W__MASK 0x00f00000 +#define A5XX_VSC_PIPE_CONFIG_REG_W__SHIFT 20 +static inline uint32_t A5XX_VSC_PIPE_CONFIG_REG_W(uint32_t val) +{ + return ((val) << A5XX_VSC_PIPE_CONFIG_REG_W__SHIFT) & A5XX_VSC_PIPE_CONFIG_REG_W__MASK; +} +#define A5XX_VSC_PIPE_CONFIG_REG_H__MASK 0x0f000000 +#define A5XX_VSC_PIPE_CONFIG_REG_H__SHIFT 24 +static inline uint32_t A5XX_VSC_PIPE_CONFIG_REG_H(uint32_t val) +{ + return ((val) << A5XX_VSC_PIPE_CONFIG_REG_H__SHIFT) & A5XX_VSC_PIPE_CONFIG_REG_H__MASK; +} + +static inline uint32_t REG_A5XX_VSC_PIPE_DATA_ADDRESS(uint32_t i0) { return 0x00000be0 + 0x2*i0; } + +static inline uint32_t REG_A5XX_VSC_PIPE_DATA_ADDRESS_LO(uint32_t i0) { return 0x00000be0 + 0x2*i0; } + +static inline uint32_t REG_A5XX_VSC_PIPE_DATA_ADDRESS_HI(uint32_t i0) { return 0x00000be1 + 0x2*i0; } + +static inline uint32_t REG_A5XX_VSC_PIPE_DATA_LENGTH(uint32_t i0) { return 0x00000c00 + 0x1*i0; } + +static inline uint32_t REG_A5XX_VSC_PIPE_DATA_LENGTH_REG(uint32_t i0) { return 0x00000c00 + 0x1*i0; } #define REG_A5XX_VSC_PERFCTR_VSC_SEL_0 0x00000c60 #define REG_A5XX_VSC_PERFCTR_VSC_SEL_1 0x00000c61 -#define REG_A5XX_VSC_BIN_SIZE 0x00000cdd -#define A5XX_VSC_BIN_SIZE_WINDOW_OFFSET_DISABLE 0x80000000 -#define A5XX_VSC_BIN_SIZE_X__MASK 0x00007fff -#define A5XX_VSC_BIN_SIZE_X__SHIFT 0 -static inline uint32_t A5XX_VSC_BIN_SIZE_X(uint32_t val) +#define REG_A5XX_VSC_RESOLVE_CNTL 0x00000cdd +#define A5XX_VSC_RESOLVE_CNTL_WINDOW_OFFSET_DISABLE 0x80000000 +#define A5XX_VSC_RESOLVE_CNTL_X__MASK 0x00007fff +#define A5XX_VSC_RESOLVE_CNTL_X__SHIFT 0 +static inline uint32_t A5XX_VSC_RESOLVE_CNTL_X(uint32_t val) { - return ((val) << A5XX_VSC_BIN_SIZE_X__SHIFT) & A5XX_VSC_BIN_SIZE_X__MASK; + return ((val) << A5XX_VSC_RESOLVE_CNTL_X__SHIFT) & A5XX_VSC_RESOLVE_CNTL_X__MASK; } -#define A5XX_VSC_BIN_SIZE_Y__MASK 0x7fff0000 -#define A5XX_VSC_BIN_SIZE_Y__SHIFT 16 -static inline uint32_t A5XX_VSC_BIN_SIZE_Y(uint32_t val) +#define A5XX_VSC_RESOLVE_CNTL_Y__MASK 0x7fff0000 +#define A5XX_VSC_RESOLVE_CNTL_Y__SHIFT 16 +static inline uint32_t A5XX_VSC_RESOLVE_CNTL_Y(uint32_t val) { - return ((val) << A5XX_VSC_BIN_SIZE_Y__SHIFT) & A5XX_VSC_BIN_SIZE_Y__MASK; + return ((val) << A5XX_VSC_RESOLVE_CNTL_Y__SHIFT) & A5XX_VSC_RESOLVE_CNTL_Y__MASK; } #define REG_A5XX_GRAS_ADDR_MODE_CNTL 0x00000c81 @@ -1470,6 +2147,7 @@ static inline uint32_t A5XX_VSC_BIN_SIZE_Y(uint32_t val) #define REG_A5XX_VPC_ADDR_MODE_CNTL 0x00000e61 #define REG_A5XX_VPC_MODE_CNTL 0x00000e62 +#define A5XX_VPC_MODE_CNTL_BINNING_PASS 0x00000001 #define REG_A5XX_VPC_PERFCTR_VPC_SEL_0 0x00000e64 @@ -1641,6 +2319,14 @@ static inline uint32_t A5XX_VSC_BIN_SIZE_Y(uint32_t val) #define REG_A5XX_VBIF_TEST_BUS_OUT 0x0000308c +#define REG_A5XX_VBIF_PERF_CNT_EN0 0x000030c0 + +#define REG_A5XX_VBIF_PERF_CNT_EN1 0x000030c1 + +#define REG_A5XX_VBIF_PERF_CNT_EN2 0x000030c2 + +#define REG_A5XX_VBIF_PERF_CNT_EN3 0x000030c3 + #define REG_A5XX_VBIF_PERF_CNT_SEL0 0x000030d0 #define REG_A5XX_VBIF_PERF_CNT_SEL1 0x000030d1 @@ -1911,6 +2597,11 @@ static inline uint32_t A5XX_VSC_BIN_SIZE_Y(uint32_t val) #define REG_A5XX_GRAS_CNTL 0x0000e005 #define A5XX_GRAS_CNTL_VARYING 0x00000001 +#define A5XX_GRAS_CNTL_UNK3 0x00000008 +#define A5XX_GRAS_CNTL_XCOORD 0x00000040 +#define A5XX_GRAS_CNTL_YCOORD 0x00000080 +#define A5XX_GRAS_CNTL_ZCOORD 0x00000100 +#define A5XX_GRAS_CNTL_WCOORD 0x00000200 #define REG_A5XX_GRAS_CL_GUARDBAND_CLIP_ADJ 0x0000e006 #define A5XX_GRAS_CL_GUARDBAND_CLIP_ADJ_HORZ__MASK 0x000003ff @@ -1975,6 +2666,8 @@ static inline uint32_t A5XX_GRAS_CL_VPORT_ZSCALE_0(float val) } #define REG_A5XX_GRAS_SU_CNTL 0x0000e090 +#define A5XX_GRAS_SU_CNTL_CULL_FRONT 0x00000001 +#define A5XX_GRAS_SU_CNTL_CULL_BACK 0x00000002 #define A5XX_GRAS_SU_CNTL_FRONT_CW 0x00000004 #define A5XX_GRAS_SU_CNTL_LINEHALFWIDTH__MASK 0x000007f8 #define A5XX_GRAS_SU_CNTL_LINEHALFWIDTH__SHIFT 3 @@ -2010,7 +2703,8 @@ static inline uint32_t A5XX_GRAS_SU_POINT_SIZE(float val) #define REG_A5XX_UNKNOWN_E093 0x0000e093 #define REG_A5XX_GRAS_SU_DEPTH_PLANE_CNTL 0x0000e094 -#define A5XX_GRAS_SU_DEPTH_PLANE_CNTL_ALPHA_TEST_ENABLE 0x00000001 +#define A5XX_GRAS_SU_DEPTH_PLANE_CNTL_FRAG_WRITES_Z 0x00000001 +#define A5XX_GRAS_SU_DEPTH_PLANE_CNTL_UNK1 0x00000002 #define REG_A5XX_GRAS_SU_POLY_OFFSET_SCALE 0x0000e095 #define A5XX_GRAS_SU_POLY_OFFSET_SCALE__MASK 0xffffffff @@ -2047,6 +2741,7 @@ static inline uint32_t A5XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(enum a5xx_dep #define REG_A5XX_GRAS_SU_CONSERVATIVE_RAS_CNTL 0x0000e099 #define REG_A5XX_GRAS_SC_CNTL 0x0000e0a0 +#define A5XX_GRAS_SC_CNTL_BINNING_PASS 0x00000001 #define A5XX_GRAS_SC_CNTL_SAMPLES_PASSED 0x00008000 #define REG_A5XX_GRAS_SC_BIN_CNTL 0x0000e0a1 @@ -2161,12 +2856,21 @@ static inline uint32_t A5XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(uint32_t val) } #define REG_A5XX_GRAS_LRZ_CNTL 0x0000e100 +#define A5XX_GRAS_LRZ_CNTL_ENABLE 0x00000001 +#define A5XX_GRAS_LRZ_CNTL_LRZ_WRITE 0x00000002 +#define A5XX_GRAS_LRZ_CNTL_GREATER 0x00000004 #define REG_A5XX_GRAS_LRZ_BUFFER_BASE_LO 0x0000e101 #define REG_A5XX_GRAS_LRZ_BUFFER_BASE_HI 0x0000e102 #define REG_A5XX_GRAS_LRZ_BUFFER_PITCH 0x0000e103 +#define A5XX_GRAS_LRZ_BUFFER_PITCH__MASK 0xffffffff +#define A5XX_GRAS_LRZ_BUFFER_PITCH__SHIFT 0 +static inline uint32_t A5XX_GRAS_LRZ_BUFFER_PITCH(uint32_t val) +{ + return ((val >> 5) << A5XX_GRAS_LRZ_BUFFER_PITCH__SHIFT) & A5XX_GRAS_LRZ_BUFFER_PITCH__MASK; +} #define REG_A5XX_GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO 0x0000e104 @@ -2188,7 +2892,9 @@ static inline uint32_t A5XX_RB_CNTL_HEIGHT(uint32_t val) #define A5XX_RB_CNTL_BYPASS 0x00020000 #define REG_A5XX_RB_RENDER_CNTL 0x0000e141 +#define A5XX_RB_RENDER_CNTL_BINNING_PASS 0x00000001 #define A5XX_RB_RENDER_CNTL_SAMPLES_PASSED 0x00000040 +#define A5XX_RB_RENDER_CNTL_DISABLE_COLOR_PIPE 0x00000080 #define A5XX_RB_RENDER_CNTL_FLAG_DEPTH 0x00004000 #define A5XX_RB_RENDER_CNTL_FLAG_DEPTH2 0x00008000 #define A5XX_RB_RENDER_CNTL_FLAG_MRTS__MASK 0x00ff0000 @@ -2223,6 +2929,7 @@ static inline uint32_t A5XX_RB_DEST_MSAA_CNTL_SAMPLES(enum a3xx_msaa_samples val #define REG_A5XX_RB_RENDER_CONTROL0 0x0000e144 #define A5XX_RB_RENDER_CONTROL0_VARYING 0x00000001 +#define A5XX_RB_RENDER_CONTROL0_UNK3 0x00000008 #define A5XX_RB_RENDER_CONTROL0_XCOORD 0x00000040 #define A5XX_RB_RENDER_CONTROL0_YCOORD 0x00000080 #define A5XX_RB_RENDER_CONTROL0_ZCOORD 0x00000100 @@ -2525,6 +3232,7 @@ static inline uint32_t A5XX_RB_BLEND_CNTL_SAMPLE_MASK(uint32_t val) #define REG_A5XX_RB_DEPTH_PLANE_CNTL 0x0000e1b0 #define A5XX_RB_DEPTH_PLANE_CNTL_FRAG_WRITES_Z 0x00000001 +#define A5XX_RB_DEPTH_PLANE_CNTL_UNK1 0x00000002 #define REG_A5XX_RB_DEPTH_CNTL 0x0000e1b1 #define A5XX_RB_DEPTH_CNTL_Z_ENABLE 0x00000001 @@ -2554,7 +3262,7 @@ static inline uint32_t A5XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(enum a5xx_depth_fo #define A5XX_RB_DEPTH_BUFFER_PITCH__SHIFT 0 static inline uint32_t A5XX_RB_DEPTH_BUFFER_PITCH(uint32_t val) { - return ((val >> 5) << A5XX_RB_DEPTH_BUFFER_PITCH__SHIFT) & A5XX_RB_DEPTH_BUFFER_PITCH__MASK; + return ((val >> 6) << A5XX_RB_DEPTH_BUFFER_PITCH__SHIFT) & A5XX_RB_DEPTH_BUFFER_PITCH__MASK; } #define REG_A5XX_RB_DEPTH_BUFFER_ARRAY_PITCH 0x0000e1b6 @@ -2562,7 +3270,7 @@ static inline uint32_t A5XX_RB_DEPTH_BUFFER_PITCH(uint32_t val) #define A5XX_RB_DEPTH_BUFFER_ARRAY_PITCH__SHIFT 0 static inline uint32_t A5XX_RB_DEPTH_BUFFER_ARRAY_PITCH(uint32_t val) { - return ((val >> 5) << A5XX_RB_DEPTH_BUFFER_ARRAY_PITCH__SHIFT) & A5XX_RB_DEPTH_BUFFER_ARRAY_PITCH__MASK; + return ((val >> 6) << A5XX_RB_DEPTH_BUFFER_ARRAY_PITCH__SHIFT) & A5XX_RB_DEPTH_BUFFER_ARRAY_PITCH__MASK; } #define REG_A5XX_RB_STENCIL_CONTROL 0x0000e1c0 @@ -2678,8 +3386,11 @@ static inline uint32_t A5XX_RB_WINDOW_OFFSET_Y(uint32_t val) return ((val) << A5XX_RB_WINDOW_OFFSET_Y__SHIFT) & A5XX_RB_WINDOW_OFFSET_Y__MASK; } +#define REG_A5XX_RB_SAMPLE_COUNT_CONTROL 0x0000e1d1 +#define A5XX_RB_SAMPLE_COUNT_CONTROL_COPY 0x00000002 + #define REG_A5XX_RB_BLIT_CNTL 0x0000e210 -#define A5XX_RB_BLIT_CNTL_BUF__MASK 0x0000003f +#define A5XX_RB_BLIT_CNTL_BUF__MASK 0x0000000f #define A5XX_RB_BLIT_CNTL_BUF__SHIFT 0 static inline uint32_t A5XX_RB_BLIT_CNTL_BUF(enum a5xx_blit_buf val) { @@ -2803,6 +3514,10 @@ static inline uint32_t A5XX_RB_BLIT_FLAG_DST_ARRAY_PITCH(uint32_t val) return ((val >> 6) << A5XX_RB_BLIT_FLAG_DST_ARRAY_PITCH__SHIFT) & A5XX_RB_BLIT_FLAG_DST_ARRAY_PITCH__MASK; } +#define REG_A5XX_RB_SAMPLE_COUNT_ADDR_LO 0x0000e267 + +#define REG_A5XX_RB_SAMPLE_COUNT_ADDR_HI 0x0000e268 + #define REG_A5XX_VPC_CNTL_0 0x0000e280 #define A5XX_VPC_CNTL_0_STRIDE_IN_VPC__MASK 0x0000007f #define A5XX_VPC_CNTL_0_STRIDE_IN_VPC__SHIFT 0 @@ -2839,32 +3554,71 @@ static inline uint32_t A5XX_VPC_PACK_NUMNONPOSVAR(uint32_t val) { return ((val) << A5XX_VPC_PACK_NUMNONPOSVAR__SHIFT) & A5XX_VPC_PACK_NUMNONPOSVAR__MASK; } +#define A5XX_VPC_PACK_PSIZELOC__MASK 0x0000ff00 +#define A5XX_VPC_PACK_PSIZELOC__SHIFT 8 +static inline uint32_t A5XX_VPC_PACK_PSIZELOC(uint32_t val) +{ + return ((val) << A5XX_VPC_PACK_PSIZELOC__SHIFT) & A5XX_VPC_PACK_PSIZELOC__MASK; +} #define REG_A5XX_VPC_FS_PRIMITIVEID_CNTL 0x0000e2a0 -#define REG_A5XX_UNKNOWN_E2A1 0x0000e2a1 +#define REG_A5XX_VPC_SO_BUF_CNTL 0x0000e2a1 +#define A5XX_VPC_SO_BUF_CNTL_BUF0 0x00000001 +#define A5XX_VPC_SO_BUF_CNTL_BUF1 0x00000008 +#define A5XX_VPC_SO_BUF_CNTL_BUF2 0x00000040 +#define A5XX_VPC_SO_BUF_CNTL_BUF3 0x00000200 +#define A5XX_VPC_SO_BUF_CNTL_ENABLE 0x00008000 #define REG_A5XX_VPC_SO_OVERRIDE 0x0000e2a2 +#define A5XX_VPC_SO_OVERRIDE_SO_DISABLE 0x00000001 -#define REG_A5XX_VPC_SO_BUFFER_BASE_LO_0 0x0000e2a7 +#define REG_A5XX_VPC_SO_CNTL 0x0000e2a3 +#define A5XX_VPC_SO_CNTL_ENABLE 0x00010000 -#define REG_A5XX_VPC_SO_BUFFER_BASE_HI_0 0x0000e2a8 +#define REG_A5XX_VPC_SO_PROG 0x0000e2a4 +#define A5XX_VPC_SO_PROG_A_BUF__MASK 0x00000003 +#define A5XX_VPC_SO_PROG_A_BUF__SHIFT 0 +static inline uint32_t A5XX_VPC_SO_PROG_A_BUF(uint32_t val) +{ + return ((val) << A5XX_VPC_SO_PROG_A_BUF__SHIFT) & A5XX_VPC_SO_PROG_A_BUF__MASK; +} +#define A5XX_VPC_SO_PROG_A_OFF__MASK 0x000007fc +#define A5XX_VPC_SO_PROG_A_OFF__SHIFT 2 +static inline uint32_t A5XX_VPC_SO_PROG_A_OFF(uint32_t val) +{ + return ((val >> 2) << A5XX_VPC_SO_PROG_A_OFF__SHIFT) & A5XX_VPC_SO_PROG_A_OFF__MASK; +} +#define A5XX_VPC_SO_PROG_A_EN 0x00000800 +#define A5XX_VPC_SO_PROG_B_BUF__MASK 0x00003000 +#define A5XX_VPC_SO_PROG_B_BUF__SHIFT 12 +static inline uint32_t A5XX_VPC_SO_PROG_B_BUF(uint32_t val) +{ + return ((val) << A5XX_VPC_SO_PROG_B_BUF__SHIFT) & A5XX_VPC_SO_PROG_B_BUF__MASK; +} +#define A5XX_VPC_SO_PROG_B_OFF__MASK 0x007fc000 +#define A5XX_VPC_SO_PROG_B_OFF__SHIFT 14 +static inline uint32_t A5XX_VPC_SO_PROG_B_OFF(uint32_t val) +{ + return ((val >> 2) << A5XX_VPC_SO_PROG_B_OFF__SHIFT) & A5XX_VPC_SO_PROG_B_OFF__MASK; +} +#define A5XX_VPC_SO_PROG_B_EN 0x00800000 -#define REG_A5XX_VPC_SO_BUFFER_SIZE_0 0x0000e2a9 +static inline uint32_t REG_A5XX_VPC_SO(uint32_t i0) { return 0x0000e2a7 + 0x7*i0; } -#define REG_A5XX_UNKNOWN_E2AB 0x0000e2ab +static inline uint32_t REG_A5XX_VPC_SO_BUFFER_BASE_LO(uint32_t i0) { return 0x0000e2a7 + 0x7*i0; } -#define REG_A5XX_VPC_SO_FLUSH_BASE_LO_0 0x0000e2ac +static inline uint32_t REG_A5XX_VPC_SO_BUFFER_BASE_HI(uint32_t i0) { return 0x0000e2a8 + 0x7*i0; } -#define REG_A5XX_VPC_SO_FLUSH_BASE_HI_0 0x0000e2ad +static inline uint32_t REG_A5XX_VPC_SO_BUFFER_SIZE(uint32_t i0) { return 0x0000e2a9 + 0x7*i0; } -#define REG_A5XX_UNKNOWN_E2AE 0x0000e2ae +static inline uint32_t REG_A5XX_VPC_SO_NCOMP(uint32_t i0) { return 0x0000e2aa + 0x7*i0; } -#define REG_A5XX_UNKNOWN_E2B2 0x0000e2b2 +static inline uint32_t REG_A5XX_VPC_SO_BUFFER_OFFSET(uint32_t i0) { return 0x0000e2ab + 0x7*i0; } -#define REG_A5XX_UNKNOWN_E2B9 0x0000e2b9 +static inline uint32_t REG_A5XX_VPC_SO_FLUSH_BASE_LO(uint32_t i0) { return 0x0000e2ac + 0x7*i0; } -#define REG_A5XX_UNKNOWN_E2C0 0x0000e2c0 +static inline uint32_t REG_A5XX_VPC_SO_FLUSH_BASE_HI(uint32_t i0) { return 0x0000e2ad + 0x7*i0; } #define REG_A5XX_PC_PRIMITIVE_CNTL 0x0000e384 #define A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC__MASK 0x0000007f @@ -2873,6 +3627,7 @@ static inline uint32_t A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC(uint32_t val) { return ((val) << A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC__SHIFT) & A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC__MASK; } +#define A5XX_PC_PRIMITIVE_CNTL_PROVOKING_VTX_LAST 0x00000400 #define REG_A5XX_PC_PRIM_VTX_CNTL 0x0000e385 #define A5XX_PC_PRIM_VTX_CNTL_PSIZE 0x00000800 @@ -2900,18 +3655,18 @@ static inline uint32_t A5XX_VFD_CONTROL_0_VTXCNT(uint32_t val) } #define REG_A5XX_VFD_CONTROL_1 0x0000e401 +#define A5XX_VFD_CONTROL_1_REGID4VTX__MASK 0x000000ff +#define A5XX_VFD_CONTROL_1_REGID4VTX__SHIFT 0 +static inline uint32_t A5XX_VFD_CONTROL_1_REGID4VTX(uint32_t val) +{ + return ((val) << A5XX_VFD_CONTROL_1_REGID4VTX__SHIFT) & A5XX_VFD_CONTROL_1_REGID4VTX__MASK; +} #define A5XX_VFD_CONTROL_1_REGID4INST__MASK 0x0000ff00 #define A5XX_VFD_CONTROL_1_REGID4INST__SHIFT 8 static inline uint32_t A5XX_VFD_CONTROL_1_REGID4INST(uint32_t val) { return ((val) << A5XX_VFD_CONTROL_1_REGID4INST__SHIFT) & A5XX_VFD_CONTROL_1_REGID4INST__MASK; } -#define A5XX_VFD_CONTROL_1_REGID4VTX__MASK 0x00ff0000 -#define A5XX_VFD_CONTROL_1_REGID4VTX__SHIFT 16 -static inline uint32_t A5XX_VFD_CONTROL_1_REGID4VTX(uint32_t val) -{ - return ((val) << A5XX_VFD_CONTROL_1_REGID4VTX__SHIFT) & A5XX_VFD_CONTROL_1_REGID4VTX__MASK; -} #define REG_A5XX_VFD_CONTROL_2 0x0000e402 @@ -2944,18 +3699,15 @@ static inline uint32_t A5XX_VFD_DECODE_INSTR_IDX(uint32_t val) { return ((val) << A5XX_VFD_DECODE_INSTR_IDX__SHIFT) & A5XX_VFD_DECODE_INSTR_IDX__MASK; } +#define A5XX_VFD_DECODE_INSTR_INSTANCED 0x00020000 #define A5XX_VFD_DECODE_INSTR_FORMAT__MASK 0x3ff00000 #define A5XX_VFD_DECODE_INSTR_FORMAT__SHIFT 20 static inline uint32_t A5XX_VFD_DECODE_INSTR_FORMAT(enum a5xx_vtx_fmt val) { return ((val) << A5XX_VFD_DECODE_INSTR_FORMAT__SHIFT) & A5XX_VFD_DECODE_INSTR_FORMAT__MASK; } -#define A5XX_VFD_DECODE_INSTR_SWAP__MASK 0xc0000000 -#define A5XX_VFD_DECODE_INSTR_SWAP__SHIFT 30 -static inline uint32_t A5XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val) -{ - return ((val) << A5XX_VFD_DECODE_INSTR_SWAP__SHIFT) & A5XX_VFD_DECODE_INSTR_SWAP__MASK; -} +#define A5XX_VFD_DECODE_INSTR_UNK30 0x40000000 +#define A5XX_VFD_DECODE_INSTR_FLOAT 0x80000000 static inline uint32_t REG_A5XX_VFD_DECODE_STEP_RATE(uint32_t i0) { return 0x0000e48b + 0x2*i0; } @@ -2979,88 +3731,107 @@ static inline uint32_t A5XX_VFD_DEST_CNTL_INSTR_REGID(uint32_t val) #define REG_A5XX_SP_SP_CNTL 0x0000e580 -#define REG_A5XX_SP_VS_CONTROL_REG 0x0000e584 -#define A5XX_SP_VS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_SP_VS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_SP_VS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_SP_VS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_SP_VS_CONFIG 0x0000e584 +#define A5XX_SP_VS_CONFIG_ENABLED 0x00000001 +#define A5XX_SP_VS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_SP_VS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_SP_VS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_SP_VS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_VS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_SP_VS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_VS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_SP_VS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_SP_VS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_SP_VS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_SP_VS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_SP_VS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_SP_VS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_SP_VS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_VS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_SP_VS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_VS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_SP_FS_CONTROL_REG 0x0000e585 -#define A5XX_SP_FS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_SP_FS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_SP_FS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_SP_FS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_SP_FS_CONFIG 0x0000e585 +#define A5XX_SP_FS_CONFIG_ENABLED 0x00000001 +#define A5XX_SP_FS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_SP_FS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_SP_FS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_SP_FS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_FS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_SP_FS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_FS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_SP_FS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_SP_FS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_SP_FS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_SP_FS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_SP_FS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_SP_FS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_SP_FS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_FS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_SP_FS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_FS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_SP_HS_CONTROL_REG 0x0000e586 -#define A5XX_SP_HS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_SP_HS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_SP_HS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_SP_HS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_SP_HS_CONFIG 0x0000e586 +#define A5XX_SP_HS_CONFIG_ENABLED 0x00000001 +#define A5XX_SP_HS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_SP_HS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_SP_HS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_SP_HS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_HS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_SP_HS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_HS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_SP_HS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_SP_HS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_SP_HS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_SP_HS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_SP_HS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_SP_HS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_SP_HS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_HS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_SP_HS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_HS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_SP_DS_CONTROL_REG 0x0000e587 -#define A5XX_SP_DS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_SP_DS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_SP_DS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_SP_DS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_SP_DS_CONFIG 0x0000e587 +#define A5XX_SP_DS_CONFIG_ENABLED 0x00000001 +#define A5XX_SP_DS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_SP_DS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_SP_DS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_SP_DS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_DS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_SP_DS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_DS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_SP_DS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_SP_DS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_SP_DS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_SP_DS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_SP_DS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_SP_DS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_SP_DS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_DS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_SP_DS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_DS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_SP_GS_CONTROL_REG 0x0000e588 -#define A5XX_SP_GS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_SP_GS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_SP_GS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_SP_GS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_SP_GS_CONFIG 0x0000e588 +#define A5XX_SP_GS_CONFIG_ENABLED 0x00000001 +#define A5XX_SP_GS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_SP_GS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_SP_GS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_SP_GS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_GS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_SP_GS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_GS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_SP_GS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_SP_GS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_SP_GS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_SP_GS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_SP_GS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_SP_GS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_SP_GS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_GS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_SP_GS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_GS_CONFIG_SHADEROBJOFFSET__MASK; } #define REG_A5XX_SP_CS_CONFIG 0x0000e589 +#define A5XX_SP_CS_CONFIG_ENABLED 0x00000001 +#define A5XX_SP_CS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_SP_CS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_SP_CS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A5XX_SP_CS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_SP_CS_CONFIG_CONSTOBJECTOFFSET__MASK; +} +#define A5XX_SP_CS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_SP_CS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_SP_CS_CONFIG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A5XX_SP_CS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_SP_CS_CONFIG_SHADEROBJOFFSET__MASK; +} #define REG_A5XX_SP_VS_CONFIG_MAX_CONST 0x0000e58a #define REG_A5XX_SP_FS_CONFIG_MAX_CONST 0x0000e58b #define REG_A5XX_SP_VS_CTRL_REG0 0x0000e590 +#define A5XX_SP_VS_CTRL_REG0_THREADSIZE__MASK 0x00000008 +#define A5XX_SP_VS_CTRL_REG0_THREADSIZE__SHIFT 3 +static inline uint32_t A5XX_SP_VS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A5XX_SP_VS_CTRL_REG0_THREADSIZE__SHIFT) & A5XX_SP_VS_CTRL_REG0_THREADSIZE__MASK; +} #define A5XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__MASK 0x000003f0 #define A5XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT 4 static inline uint32_t A5XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val) @@ -3075,13 +3846,19 @@ static inline uint32_t A5XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val) } #define A5XX_SP_VS_CTRL_REG0_VARYING 0x00010000 #define A5XX_SP_VS_CTRL_REG0_PIXLODENABLE 0x00100000 +#define A5XX_SP_VS_CTRL_REG0_BRANCHSTACK__MASK 0xfe000000 +#define A5XX_SP_VS_CTRL_REG0_BRANCHSTACK__SHIFT 25 +static inline uint32_t A5XX_SP_VS_CTRL_REG0_BRANCHSTACK(uint32_t val) +{ + return ((val) << A5XX_SP_VS_CTRL_REG0_BRANCHSTACK__SHIFT) & A5XX_SP_VS_CTRL_REG0_BRANCHSTACK__MASK; +} #define REG_A5XX_SP_PRIMITIVE_CNTL 0x0000e592 -#define A5XX_SP_PRIMITIVE_CNTL_STRIDE_IN_VPC__MASK 0x0000001f -#define A5XX_SP_PRIMITIVE_CNTL_STRIDE_IN_VPC__SHIFT 0 -static inline uint32_t A5XX_SP_PRIMITIVE_CNTL_STRIDE_IN_VPC(uint32_t val) +#define A5XX_SP_PRIMITIVE_CNTL_VSOUT__MASK 0x0000001f +#define A5XX_SP_PRIMITIVE_CNTL_VSOUT__SHIFT 0 +static inline uint32_t A5XX_SP_PRIMITIVE_CNTL_VSOUT(uint32_t val) { - return ((val >> 2) << A5XX_SP_PRIMITIVE_CNTL_STRIDE_IN_VPC__SHIFT) & A5XX_SP_PRIMITIVE_CNTL_STRIDE_IN_VPC__MASK; + return ((val) << A5XX_SP_PRIMITIVE_CNTL_VSOUT__SHIFT) & A5XX_SP_PRIMITIVE_CNTL_VSOUT__MASK; } static inline uint32_t REG_A5XX_SP_VS_OUT(uint32_t i0) { return 0x0000e593 + 0x1*i0; } @@ -3147,6 +3924,12 @@ static inline uint32_t A5XX_SP_VS_VPC_DST_REG_OUTLOC3(uint32_t val) #define REG_A5XX_SP_VS_OBJ_START_HI 0x0000e5ad #define REG_A5XX_SP_FS_CTRL_REG0 0x0000e5c0 +#define A5XX_SP_FS_CTRL_REG0_THREADSIZE__MASK 0x00000008 +#define A5XX_SP_FS_CTRL_REG0_THREADSIZE__SHIFT 3 +static inline uint32_t A5XX_SP_FS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A5XX_SP_FS_CTRL_REG0_THREADSIZE__SHIFT) & A5XX_SP_FS_CTRL_REG0_THREADSIZE__MASK; +} #define A5XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__MASK 0x000003f0 #define A5XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT 4 static inline uint32_t A5XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val) @@ -3161,6 +3944,12 @@ static inline uint32_t A5XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val) } #define A5XX_SP_FS_CTRL_REG0_VARYING 0x00010000 #define A5XX_SP_FS_CTRL_REG0_PIXLODENABLE 0x00100000 +#define A5XX_SP_FS_CTRL_REG0_BRANCHSTACK__MASK 0xfe000000 +#define A5XX_SP_FS_CTRL_REG0_BRANCHSTACK__SHIFT 25 +static inline uint32_t A5XX_SP_FS_CTRL_REG0_BRANCHSTACK(uint32_t val) +{ + return ((val) << A5XX_SP_FS_CTRL_REG0_BRANCHSTACK__SHIFT) & A5XX_SP_FS_CTRL_REG0_BRANCHSTACK__MASK; +} #define REG_A5XX_UNKNOWN_E5C2 0x0000e5c2 @@ -3169,6 +3958,8 @@ static inline uint32_t A5XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val) #define REG_A5XX_SP_FS_OBJ_START_HI 0x0000e5c4 #define REG_A5XX_SP_BLEND_CNTL 0x0000e5c9 +#define A5XX_SP_BLEND_CNTL_ENABLED 0x00000001 +#define A5XX_SP_BLEND_CNTL_UNK8 0x00000100 #define REG_A5XX_SP_FS_OUTPUT_CNTL 0x0000e5ca #define A5XX_SP_FS_OUTPUT_CNTL_MRT__MASK 0x0000000f @@ -3210,15 +4001,66 @@ static inline uint32_t A5XX_SP_FS_MRT_REG_COLOR_FORMAT(enum a5xx_color_fmt val) { return ((val) << A5XX_SP_FS_MRT_REG_COLOR_FORMAT__SHIFT) & A5XX_SP_FS_MRT_REG_COLOR_FORMAT__MASK; } +#define A5XX_SP_FS_MRT_REG_COLOR_SRGB 0x00000400 #define REG_A5XX_UNKNOWN_E5DB 0x0000e5db -#define REG_A5XX_SP_CS_CNTL_0 0x0000e5f0 +#define REG_A5XX_UNKNOWN_E5F2 0x0000e5f2 + +#define REG_A5XX_SP_CS_OBJ_START_LO 0x0000e5f3 + +#define REG_A5XX_SP_CS_OBJ_START_HI 0x0000e5f4 + +#define REG_A5XX_SP_CS_CTRL_REG0 0x0000e5f0 +#define A5XX_SP_CS_CTRL_REG0_THREADSIZE__MASK 0x00000008 +#define A5XX_SP_CS_CTRL_REG0_THREADSIZE__SHIFT 3 +static inline uint32_t A5XX_SP_CS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A5XX_SP_CS_CTRL_REG0_THREADSIZE__SHIFT) & A5XX_SP_CS_CTRL_REG0_THREADSIZE__MASK; +} +#define A5XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__MASK 0x000003f0 +#define A5XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT 4 +static inline uint32_t A5XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val) +{ + return ((val) << A5XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT) & A5XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__MASK; +} +#define A5XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__MASK 0x0000fc00 +#define A5XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT 10 +static inline uint32_t A5XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val) +{ + return ((val) << A5XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT) & A5XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__MASK; +} +#define A5XX_SP_CS_CTRL_REG0_VARYING 0x00010000 +#define A5XX_SP_CS_CTRL_REG0_PIXLODENABLE 0x00100000 +#define A5XX_SP_CS_CTRL_REG0_BRANCHSTACK__MASK 0xfe000000 +#define A5XX_SP_CS_CTRL_REG0_BRANCHSTACK__SHIFT 25 +static inline uint32_t A5XX_SP_CS_CTRL_REG0_BRANCHSTACK(uint32_t val) +{ + return ((val) << A5XX_SP_CS_CTRL_REG0_BRANCHSTACK__SHIFT) & A5XX_SP_CS_CTRL_REG0_BRANCHSTACK__MASK; +} #define REG_A5XX_UNKNOWN_E600 0x0000e600 +#define REG_A5XX_UNKNOWN_E602 0x0000e602 + +#define REG_A5XX_SP_HS_OBJ_START_LO 0x0000e603 + +#define REG_A5XX_SP_HS_OBJ_START_HI 0x0000e604 + +#define REG_A5XX_UNKNOWN_E62B 0x0000e62b + +#define REG_A5XX_SP_DS_OBJ_START_LO 0x0000e62c + +#define REG_A5XX_SP_DS_OBJ_START_HI 0x0000e62d + #define REG_A5XX_UNKNOWN_E640 0x0000e640 +#define REG_A5XX_UNKNOWN_E65B 0x0000e65b + +#define REG_A5XX_SP_GS_OBJ_START_LO 0x0000e65c + +#define REG_A5XX_SP_GS_OBJ_START_HI 0x0000e65d + #define REG_A5XX_TPL1_TP_RAS_MSAA_CNTL 0x0000e704 #define A5XX_TPL1_TP_RAS_MSAA_CNTL_SAMPLES__MASK 0x00000003 #define A5XX_TPL1_TP_RAS_MSAA_CNTL_SAMPLES__SHIFT 0 @@ -3236,29 +4078,85 @@ static inline uint32_t A5XX_TPL1_TP_DEST_MSAA_CNTL_SAMPLES(enum a3xx_msaa_sample } #define A5XX_TPL1_TP_DEST_MSAA_CNTL_MSAA_DISABLE 0x00000004 +#define REG_A5XX_TPL1_TP_BORDER_COLOR_BASE_ADDR_LO 0x0000e706 + +#define REG_A5XX_TPL1_TP_BORDER_COLOR_BASE_ADDR_HI 0x0000e707 + #define REG_A5XX_TPL1_VS_TEX_COUNT 0x0000e700 +#define REG_A5XX_TPL1_HS_TEX_COUNT 0x0000e701 + +#define REG_A5XX_TPL1_DS_TEX_COUNT 0x0000e702 + +#define REG_A5XX_TPL1_GS_TEX_COUNT 0x0000e703 + #define REG_A5XX_TPL1_VS_TEX_SAMP_LO 0x0000e722 #define REG_A5XX_TPL1_VS_TEX_SAMP_HI 0x0000e723 +#define REG_A5XX_TPL1_HS_TEX_SAMP_LO 0x0000e724 + +#define REG_A5XX_TPL1_HS_TEX_SAMP_HI 0x0000e725 + +#define REG_A5XX_TPL1_DS_TEX_SAMP_LO 0x0000e726 + +#define REG_A5XX_TPL1_DS_TEX_SAMP_HI 0x0000e727 + +#define REG_A5XX_TPL1_GS_TEX_SAMP_LO 0x0000e728 + +#define REG_A5XX_TPL1_GS_TEX_SAMP_HI 0x0000e729 + #define REG_A5XX_TPL1_VS_TEX_CONST_LO 0x0000e72a #define REG_A5XX_TPL1_VS_TEX_CONST_HI 0x0000e72b +#define REG_A5XX_TPL1_HS_TEX_CONST_LO 0x0000e72c + +#define REG_A5XX_TPL1_HS_TEX_CONST_HI 0x0000e72d + +#define REG_A5XX_TPL1_DS_TEX_CONST_LO 0x0000e72e + +#define REG_A5XX_TPL1_DS_TEX_CONST_HI 0x0000e72f + +#define REG_A5XX_TPL1_GS_TEX_CONST_LO 0x0000e730 + +#define REG_A5XX_TPL1_GS_TEX_CONST_HI 0x0000e731 + #define REG_A5XX_TPL1_FS_TEX_COUNT 0x0000e750 +#define REG_A5XX_TPL1_CS_TEX_COUNT 0x0000e751 + #define REG_A5XX_TPL1_FS_TEX_SAMP_LO 0x0000e75a #define REG_A5XX_TPL1_FS_TEX_SAMP_HI 0x0000e75b +#define REG_A5XX_TPL1_CS_TEX_SAMP_LO 0x0000e75c + +#define REG_A5XX_TPL1_CS_TEX_SAMP_HI 0x0000e75d + #define REG_A5XX_TPL1_FS_TEX_CONST_LO 0x0000e75e #define REG_A5XX_TPL1_FS_TEX_CONST_HI 0x0000e75f +#define REG_A5XX_TPL1_CS_TEX_CONST_LO 0x0000e760 + +#define REG_A5XX_TPL1_CS_TEX_CONST_HI 0x0000e761 + #define REG_A5XX_TPL1_TP_FS_ROTATION_CNTL 0x0000e764 #define REG_A5XX_HLSQ_CONTROL_0_REG 0x0000e784 +#define A5XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__MASK 0x00000001 +#define A5XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__SHIFT 0 +static inline uint32_t A5XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A5XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__SHIFT) & A5XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__MASK; +} +#define A5XX_HLSQ_CONTROL_0_REG_CSTHREADSIZE__MASK 0x00000004 +#define A5XX_HLSQ_CONTROL_0_REG_CSTHREADSIZE__SHIFT 2 +static inline uint32_t A5XX_HLSQ_CONTROL_0_REG_CSTHREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A5XX_HLSQ_CONTROL_0_REG_CSTHREADSIZE__SHIFT) & A5XX_HLSQ_CONTROL_0_REG_CSTHREADSIZE__MASK; +} #define REG_A5XX_HLSQ_CONTROL_1_REG 0x0000e785 #define A5XX_HLSQ_CONTROL_1_REG_PRIMALLOCTHRESHOLD__MASK 0x0000003f @@ -3300,84 +4198,98 @@ static inline uint32_t A5XX_HLSQ_CONTROL_4_REG_ZWCOORDREGID(uint32_t val) #define REG_A5XX_HLSQ_UPDATE_CNTL 0x0000e78a -#define REG_A5XX_HLSQ_VS_CONTROL_REG 0x0000e78b -#define A5XX_HLSQ_VS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_HLSQ_VS_CONFIG 0x0000e78b +#define A5XX_HLSQ_VS_CONFIG_ENABLED 0x00000001 +#define A5XX_HLSQ_VS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_HLSQ_VS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_HLSQ_VS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_HLSQ_VS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_VS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_HLSQ_VS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_HLSQ_VS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_HLSQ_VS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_HLSQ_VS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_VS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_HLSQ_FS_CONTROL_REG 0x0000e78c -#define A5XX_HLSQ_FS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_HLSQ_FS_CONFIG 0x0000e78c +#define A5XX_HLSQ_FS_CONFIG_ENABLED 0x00000001 +#define A5XX_HLSQ_FS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_HLSQ_FS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_HLSQ_FS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_HLSQ_FS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_FS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_HLSQ_FS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_HLSQ_FS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_HLSQ_FS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_HLSQ_FS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_FS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_HLSQ_HS_CONTROL_REG 0x0000e78d -#define A5XX_HLSQ_HS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_HLSQ_HS_CONFIG 0x0000e78d +#define A5XX_HLSQ_HS_CONFIG_ENABLED 0x00000001 +#define A5XX_HLSQ_HS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_HLSQ_HS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_HLSQ_HS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_HLSQ_HS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_HS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_HLSQ_HS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_HLSQ_HS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_HLSQ_HS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_HLSQ_HS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_HS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_HLSQ_DS_CONTROL_REG 0x0000e78e -#define A5XX_HLSQ_DS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_HLSQ_DS_CONFIG 0x0000e78e +#define A5XX_HLSQ_DS_CONFIG_ENABLED 0x00000001 +#define A5XX_HLSQ_DS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_HLSQ_DS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_HLSQ_DS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_HLSQ_DS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_DS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_HLSQ_DS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_HLSQ_DS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_HLSQ_DS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_HLSQ_DS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_DS_CONFIG_SHADEROBJOFFSET__MASK; } -#define REG_A5XX_HLSQ_GS_CONTROL_REG 0x0000e78f -#define A5XX_HLSQ_GS_CONTROL_REG_ENABLED 0x00000001 -#define A5XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x000000fe -#define A5XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 1 -static inline uint32_t A5XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +#define REG_A5XX_HLSQ_GS_CONFIG 0x0000e78f +#define A5XX_HLSQ_GS_CONFIG_ENABLED 0x00000001 +#define A5XX_HLSQ_GS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_HLSQ_GS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_HLSQ_GS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; + return ((val) << A5XX_HLSQ_GS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_GS_CONFIG_CONSTOBJECTOFFSET__MASK; } -#define A5XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00007f00 -#define A5XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 8 -static inline uint32_t A5XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +#define A5XX_HLSQ_GS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_HLSQ_GS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_HLSQ_GS_CONFIG_SHADEROBJOFFSET(uint32_t val) { - return ((val) << A5XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__MASK; + return ((val) << A5XX_HLSQ_GS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_GS_CONFIG_SHADEROBJOFFSET__MASK; } #define REG_A5XX_HLSQ_CS_CONFIG 0x0000e790 +#define A5XX_HLSQ_CS_CONFIG_ENABLED 0x00000001 +#define A5XX_HLSQ_CS_CONFIG_CONSTOBJECTOFFSET__MASK 0x000000fe +#define A5XX_HLSQ_CS_CONFIG_CONSTOBJECTOFFSET__SHIFT 1 +static inline uint32_t A5XX_HLSQ_CS_CONFIG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_CONFIG_CONSTOBJECTOFFSET__SHIFT) & A5XX_HLSQ_CS_CONFIG_CONSTOBJECTOFFSET__MASK; +} +#define A5XX_HLSQ_CS_CONFIG_SHADEROBJOFFSET__MASK 0x00007f00 +#define A5XX_HLSQ_CS_CONFIG_SHADEROBJOFFSET__SHIFT 8 +static inline uint32_t A5XX_HLSQ_CS_CONFIG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_CONFIG_SHADEROBJOFFSET__SHIFT) & A5XX_HLSQ_CS_CONFIG_SHADEROBJOFFSET__MASK; +} #define REG_A5XX_HLSQ_VS_CNTL 0x0000e791 +#define A5XX_HLSQ_VS_CNTL_SSBO_ENABLE 0x00000001 #define A5XX_HLSQ_VS_CNTL_INSTRLEN__MASK 0xfffffffe #define A5XX_HLSQ_VS_CNTL_INSTRLEN__SHIFT 1 static inline uint32_t A5XX_HLSQ_VS_CNTL_INSTRLEN(uint32_t val) @@ -3386,6 +4298,7 @@ static inline uint32_t A5XX_HLSQ_VS_CNTL_INSTRLEN(uint32_t val) } #define REG_A5XX_HLSQ_FS_CNTL 0x0000e792 +#define A5XX_HLSQ_FS_CNTL_SSBO_ENABLE 0x00000001 #define A5XX_HLSQ_FS_CNTL_INSTRLEN__MASK 0xfffffffe #define A5XX_HLSQ_FS_CNTL_INSTRLEN__SHIFT 1 static inline uint32_t A5XX_HLSQ_FS_CNTL_INSTRLEN(uint32_t val) @@ -3394,6 +4307,7 @@ static inline uint32_t A5XX_HLSQ_FS_CNTL_INSTRLEN(uint32_t val) } #define REG_A5XX_HLSQ_HS_CNTL 0x0000e793 +#define A5XX_HLSQ_HS_CNTL_SSBO_ENABLE 0x00000001 #define A5XX_HLSQ_HS_CNTL_INSTRLEN__MASK 0xfffffffe #define A5XX_HLSQ_HS_CNTL_INSTRLEN__SHIFT 1 static inline uint32_t A5XX_HLSQ_HS_CNTL_INSTRLEN(uint32_t val) @@ -3402,6 +4316,7 @@ static inline uint32_t A5XX_HLSQ_HS_CNTL_INSTRLEN(uint32_t val) } #define REG_A5XX_HLSQ_DS_CNTL 0x0000e794 +#define A5XX_HLSQ_DS_CNTL_SSBO_ENABLE 0x00000001 #define A5XX_HLSQ_DS_CNTL_INSTRLEN__MASK 0xfffffffe #define A5XX_HLSQ_DS_CNTL_INSTRLEN__SHIFT 1 static inline uint32_t A5XX_HLSQ_DS_CNTL_INSTRLEN(uint32_t val) @@ -3410,6 +4325,7 @@ static inline uint32_t A5XX_HLSQ_DS_CNTL_INSTRLEN(uint32_t val) } #define REG_A5XX_HLSQ_GS_CNTL 0x0000e795 +#define A5XX_HLSQ_GS_CNTL_SSBO_ENABLE 0x00000001 #define A5XX_HLSQ_GS_CNTL_INSTRLEN__MASK 0xfffffffe #define A5XX_HLSQ_GS_CNTL_INSTRLEN__SHIFT 1 static inline uint32_t A5XX_HLSQ_GS_CNTL_INSTRLEN(uint32_t val) @@ -3418,6 +4334,7 @@ static inline uint32_t A5XX_HLSQ_GS_CNTL_INSTRLEN(uint32_t val) } #define REG_A5XX_HLSQ_CS_CNTL 0x0000e796 +#define A5XX_HLSQ_CS_CNTL_SSBO_ENABLE 0x00000001 #define A5XX_HLSQ_CS_CNTL_INSTRLEN__MASK 0xfffffffe #define A5XX_HLSQ_CS_CNTL_INSTRLEN__SHIFT 1 static inline uint32_t A5XX_HLSQ_CS_CNTL_INSTRLEN(uint32_t val) @@ -3432,20 +4349,86 @@ static inline uint32_t A5XX_HLSQ_CS_CNTL_INSTRLEN(uint32_t val) #define REG_A5XX_HLSQ_CS_KERNEL_GROUP_Z 0x0000e7bb #define REG_A5XX_HLSQ_CS_NDRANGE_0 0x0000e7b0 +#define A5XX_HLSQ_CS_NDRANGE_0_KERNELDIM__MASK 0x00000003 +#define A5XX_HLSQ_CS_NDRANGE_0_KERNELDIM__SHIFT 0 +static inline uint32_t A5XX_HLSQ_CS_NDRANGE_0_KERNELDIM(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_NDRANGE_0_KERNELDIM__SHIFT) & A5XX_HLSQ_CS_NDRANGE_0_KERNELDIM__MASK; +} +#define A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEX__MASK 0x00000ffc +#define A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEX__SHIFT 2 +static inline uint32_t A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEX(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEX__SHIFT) & A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEX__MASK; +} +#define A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEY__MASK 0x003ff000 +#define A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEY__SHIFT 12 +static inline uint32_t A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEY(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEY__SHIFT) & A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEY__MASK; +} +#define A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEZ__MASK 0xffc00000 +#define A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEZ__SHIFT 22 +static inline uint32_t A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEZ(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEZ__SHIFT) & A5XX_HLSQ_CS_NDRANGE_0_LOCALSIZEZ__MASK; +} #define REG_A5XX_HLSQ_CS_NDRANGE_1 0x0000e7b1 +#define A5XX_HLSQ_CS_NDRANGE_1_SIZE_X__MASK 0xffffffff +#define A5XX_HLSQ_CS_NDRANGE_1_SIZE_X__SHIFT 0 +static inline uint32_t A5XX_HLSQ_CS_NDRANGE_1_SIZE_X(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_NDRANGE_1_SIZE_X__SHIFT) & A5XX_HLSQ_CS_NDRANGE_1_SIZE_X__MASK; +} #define REG_A5XX_HLSQ_CS_NDRANGE_2 0x0000e7b2 #define REG_A5XX_HLSQ_CS_NDRANGE_3 0x0000e7b3 +#define A5XX_HLSQ_CS_NDRANGE_3_SIZE_Y__MASK 0xffffffff +#define A5XX_HLSQ_CS_NDRANGE_3_SIZE_Y__SHIFT 0 +static inline uint32_t A5XX_HLSQ_CS_NDRANGE_3_SIZE_Y(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_NDRANGE_3_SIZE_Y__SHIFT) & A5XX_HLSQ_CS_NDRANGE_3_SIZE_Y__MASK; +} #define REG_A5XX_HLSQ_CS_NDRANGE_4 0x0000e7b4 #define REG_A5XX_HLSQ_CS_NDRANGE_5 0x0000e7b5 +#define A5XX_HLSQ_CS_NDRANGE_5_SIZE_Z__MASK 0xffffffff +#define A5XX_HLSQ_CS_NDRANGE_5_SIZE_Z__SHIFT 0 +static inline uint32_t A5XX_HLSQ_CS_NDRANGE_5_SIZE_Z(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_NDRANGE_5_SIZE_Z__SHIFT) & A5XX_HLSQ_CS_NDRANGE_5_SIZE_Z__MASK; +} #define REG_A5XX_HLSQ_CS_NDRANGE_6 0x0000e7b6 #define REG_A5XX_HLSQ_CS_CNTL_0 0x0000e7b7 +#define A5XX_HLSQ_CS_CNTL_0_WGIDCONSTID__MASK 0x000000ff +#define A5XX_HLSQ_CS_CNTL_0_WGIDCONSTID__SHIFT 0 +static inline uint32_t A5XX_HLSQ_CS_CNTL_0_WGIDCONSTID(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_CNTL_0_WGIDCONSTID__SHIFT) & A5XX_HLSQ_CS_CNTL_0_WGIDCONSTID__MASK; +} +#define A5XX_HLSQ_CS_CNTL_0_UNK0__MASK 0x0000ff00 +#define A5XX_HLSQ_CS_CNTL_0_UNK0__SHIFT 8 +static inline uint32_t A5XX_HLSQ_CS_CNTL_0_UNK0(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_CNTL_0_UNK0__SHIFT) & A5XX_HLSQ_CS_CNTL_0_UNK0__MASK; +} +#define A5XX_HLSQ_CS_CNTL_0_UNK1__MASK 0x00ff0000 +#define A5XX_HLSQ_CS_CNTL_0_UNK1__SHIFT 16 +static inline uint32_t A5XX_HLSQ_CS_CNTL_0_UNK1(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_CNTL_0_UNK1__SHIFT) & A5XX_HLSQ_CS_CNTL_0_UNK1__MASK; +} +#define A5XX_HLSQ_CS_CNTL_0_LOCALIDREGID__MASK 0xff000000 +#define A5XX_HLSQ_CS_CNTL_0_LOCALIDREGID__SHIFT 24 +static inline uint32_t A5XX_HLSQ_CS_CNTL_0_LOCALIDREGID(uint32_t val) +{ + return ((val) << A5XX_HLSQ_CS_CNTL_0_LOCALIDREGID__SHIFT) & A5XX_HLSQ_CS_CNTL_0_LOCALIDREGID__MASK; +} #define REG_A5XX_HLSQ_CS_CNTL_1 0x0000e7b8 @@ -3457,16 +4440,12 @@ static inline uint32_t A5XX_HLSQ_CS_CNTL_INSTRLEN(uint32_t val) #define REG_A5XX_UNKNOWN_E7C5 0x0000e7c5 -#define REG_A5XX_UNKNOWN_E7CA 0x0000e7ca - -#define REG_A5XX_HLSQ_FS_CONSTLEN 0x0000e7d7 - -#define REG_A5XX_HLSQ_FS_INSTRLEN 0x0000e7d8 - #define REG_A5XX_HLSQ_HS_CONSTLEN 0x0000e7c8 #define REG_A5XX_HLSQ_HS_INSTRLEN 0x0000e7c9 +#define REG_A5XX_UNKNOWN_E7CA 0x0000e7ca + #define REG_A5XX_HLSQ_DS_CONSTLEN 0x0000e7cd #define REG_A5XX_HLSQ_DS_INSTRLEN 0x0000e7ce @@ -3479,13 +4458,23 @@ static inline uint32_t A5XX_HLSQ_CS_CNTL_INSTRLEN(uint32_t val) #define REG_A5XX_UNKNOWN_E7D4 0x0000e7d4 +#define REG_A5XX_HLSQ_FS_CONSTLEN 0x0000e7d7 + +#define REG_A5XX_HLSQ_FS_INSTRLEN 0x0000e7d8 + #define REG_A5XX_UNKNOWN_E7D9 0x0000e7d9 -#define REG_A5XX_HLSQ_CONTEXT_SWITCH_CS_SW_3 0x0000e7dc +#define REG_A5XX_HLSQ_CS_CONSTLEN 0x0000e7dc + +#define REG_A5XX_HLSQ_CS_INSTRLEN 0x0000e7dd + +#define REG_A5XX_RB_2D_SRC_SOLID_DW0 0x00002101 -#define REG_A5XX_HLSQ_CONTEXT_SWITCH_CS_SW_4 0x0000e7dd +#define REG_A5XX_RB_2D_SRC_SOLID_DW1 0x00002102 -#define REG_A5XX_RB_2D_DST_FILL 0x00002101 +#define REG_A5XX_RB_2D_SRC_SOLID_DW2 0x00002103 + +#define REG_A5XX_RB_2D_SRC_SOLID_DW3 0x00002104 #define REG_A5XX_RB_2D_SRC_INFO 0x00002107 #define A5XX_RB_2D_SRC_INFO_COLOR_FORMAT__MASK 0x000000ff @@ -3505,6 +4494,20 @@ static inline uint32_t A5XX_RB_2D_SRC_INFO_COLOR_SWAP(enum a3xx_color_swap val) #define REG_A5XX_RB_2D_SRC_HI 0x00002109 +#define REG_A5XX_RB_2D_SRC_SIZE 0x0000210a +#define A5XX_RB_2D_SRC_SIZE_PITCH__MASK 0x0000ffff +#define A5XX_RB_2D_SRC_SIZE_PITCH__SHIFT 0 +static inline uint32_t A5XX_RB_2D_SRC_SIZE_PITCH(uint32_t val) +{ + return ((val >> 6) << A5XX_RB_2D_SRC_SIZE_PITCH__SHIFT) & A5XX_RB_2D_SRC_SIZE_PITCH__MASK; +} +#define A5XX_RB_2D_SRC_SIZE_ARRAY_PITCH__MASK 0xffff0000 +#define A5XX_RB_2D_SRC_SIZE_ARRAY_PITCH__SHIFT 16 +static inline uint32_t A5XX_RB_2D_SRC_SIZE_ARRAY_PITCH(uint32_t val) +{ + return ((val >> 6) << A5XX_RB_2D_SRC_SIZE_ARRAY_PITCH__SHIFT) & A5XX_RB_2D_SRC_SIZE_ARRAY_PITCH__MASK; +} + #define REG_A5XX_RB_2D_DST_INFO 0x00002110 #define A5XX_RB_2D_DST_INFO_COLOR_FORMAT__MASK 0x000000ff #define A5XX_RB_2D_DST_INFO_COLOR_FORMAT__SHIFT 0 @@ -3519,14 +4522,28 @@ static inline uint32_t A5XX_RB_2D_DST_INFO_COLOR_SWAP(enum a3xx_color_swap val) return ((val) << A5XX_RB_2D_DST_INFO_COLOR_SWAP__SHIFT) & A5XX_RB_2D_DST_INFO_COLOR_SWAP__MASK; } -#define REG_A5XX_RB_2D_SRC_FLAGS_LO 0x00002140 - -#define REG_A5XX_RB_2D_SRC_FLAGS_HI 0x00002141 - #define REG_A5XX_RB_2D_DST_LO 0x00002111 #define REG_A5XX_RB_2D_DST_HI 0x00002112 +#define REG_A5XX_RB_2D_DST_SIZE 0x00002113 +#define A5XX_RB_2D_DST_SIZE_PITCH__MASK 0x0000ffff +#define A5XX_RB_2D_DST_SIZE_PITCH__SHIFT 0 +static inline uint32_t A5XX_RB_2D_DST_SIZE_PITCH(uint32_t val) +{ + return ((val >> 6) << A5XX_RB_2D_DST_SIZE_PITCH__SHIFT) & A5XX_RB_2D_DST_SIZE_PITCH__MASK; +} +#define A5XX_RB_2D_DST_SIZE_ARRAY_PITCH__MASK 0xffff0000 +#define A5XX_RB_2D_DST_SIZE_ARRAY_PITCH__SHIFT 16 +static inline uint32_t A5XX_RB_2D_DST_SIZE_ARRAY_PITCH(uint32_t val) +{ + return ((val >> 6) << A5XX_RB_2D_DST_SIZE_ARRAY_PITCH__SHIFT) & A5XX_RB_2D_DST_SIZE_ARRAY_PITCH__MASK; +} + +#define REG_A5XX_RB_2D_SRC_FLAGS_LO 0x00002140 + +#define REG_A5XX_RB_2D_SRC_FLAGS_HI 0x00002141 + #define REG_A5XX_RB_2D_DST_FLAGS_LO 0x00002143 #define REG_A5XX_RB_2D_DST_FLAGS_HI 0x00002144 @@ -3559,6 +4576,12 @@ static inline uint32_t A5XX_GRAS_2D_DST_INFO_COLOR_SWAP(enum a3xx_color_swap val return ((val) << A5XX_GRAS_2D_DST_INFO_COLOR_SWAP__SHIFT) & A5XX_GRAS_2D_DST_INFO_COLOR_SWAP__MASK; } +#define REG_A5XX_UNKNOWN_2100 0x00002100 + +#define REG_A5XX_UNKNOWN_2180 0x00002180 + +#define REG_A5XX_UNKNOWN_2184 0x00002184 + #define REG_A5XX_TEX_SAMP_0 0x00000000 #define A5XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR 0x00000001 #define A5XX_TEX_SAMP_0_XY_MAG__MASK 0x00000006 @@ -3628,6 +4651,12 @@ static inline uint32_t A5XX_TEX_SAMP_1_MIN_LOD(float val) } #define REG_A5XX_TEX_SAMP_2 0x00000002 +#define A5XX_TEX_SAMP_2_BCOLOR_OFFSET__MASK 0xfffffff0 +#define A5XX_TEX_SAMP_2_BCOLOR_OFFSET__SHIFT 4 +static inline uint32_t A5XX_TEX_SAMP_2_BCOLOR_OFFSET(uint32_t val) +{ + return ((val) << A5XX_TEX_SAMP_2_BCOLOR_OFFSET__SHIFT) & A5XX_TEX_SAMP_2_BCOLOR_OFFSET__MASK; +} #define REG_A5XX_TEX_SAMP_3 0x00000003 @@ -3663,6 +4692,12 @@ static inline uint32_t A5XX_TEX_CONST_0_SWIZ_W(enum a5xx_tex_swiz val) { return ((val) << A5XX_TEX_CONST_0_SWIZ_W__SHIFT) & A5XX_TEX_CONST_0_SWIZ_W__MASK; } +#define A5XX_TEX_CONST_0_MIPLVLS__MASK 0x000f0000 +#define A5XX_TEX_CONST_0_MIPLVLS__SHIFT 16 +static inline uint32_t A5XX_TEX_CONST_0_MIPLVLS(uint32_t val) +{ + return ((val) << A5XX_TEX_CONST_0_MIPLVLS__SHIFT) & A5XX_TEX_CONST_0_MIPLVLS__MASK; +} #define A5XX_TEX_CONST_0_FMT__MASK 0x3fc00000 #define A5XX_TEX_CONST_0_FMT__SHIFT 22 static inline uint32_t A5XX_TEX_CONST_0_FMT(enum a5xx_tex_fmt val) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 31a9bce..b4b54f1 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -11,6 +11,12 @@ * */ +#include <linux/types.h> +#include <linux/cpumask.h> +#include <linux/qcom_scm.h> +#include <linux/dma-mapping.h> +#include <linux/of_reserved_mem.h> +#include <linux/soc/qcom/mdt_loader.h> #include "msm_gem.h" #include "msm_mmu.h" #include "a5xx_gpu.h" @@ -18,6 +24,62 @@ extern bool hang_debug; static void a5xx_dump(struct msm_gpu *gpu); +#define GPU_PAS_ID 13 + +#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER) + +static int zap_shader_load_mdt(struct device *dev, const char *fwname) +{ + const struct firmware *fw; + phys_addr_t mem_phys; + ssize_t mem_size; + void *mem_region = NULL; + int ret; + + /* Request the MDT file for the firmware */ + ret = request_firmware(&fw, fwname, dev); + if (ret) { + DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname); + return ret; + } + + /* Figure out how much memory we need */ + mem_size = qcom_mdt_get_size(fw); + if (mem_size < 0) { + ret = mem_size; + goto out; + } + + /* Allocate memory for the firmware image */ + mem_region = dmam_alloc_coherent(dev, mem_size, &mem_phys, GFP_KERNEL); + if (!mem_region) { + ret = -ENOMEM; + goto out; + } + + /* Load the rest of the MDT */ + ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID, mem_region, mem_phys, + mem_size); + if (ret) + goto out; + + /* Send the image to the secure world */ + ret = qcom_scm_pas_auth_and_reset(GPU_PAS_ID); + if (ret) + DRM_DEV_ERROR(dev, "Unable to authorize the image\n"); + +out: + release_firmware(fw); + + return ret; +} +#else +static int zap_shader_load_mdt(struct device *dev, const char *fwname) +{ + return -ENODEV; +} +#endif + static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { @@ -225,7 +287,7 @@ static int a5xx_me_init(struct msm_gpu *gpu) gpu->funcs->flush(gpu); - return gpu->funcs->idle(gpu) ? 0 : -EINVAL; + return a5xx_idle(gpu) ? 0 : -EINVAL; } static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu, @@ -235,24 +297,21 @@ static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu, struct drm_gem_object *bo; void *ptr; - mutex_lock(&drm->struct_mutex); - bo = msm_gem_new(drm, fw->size - 4, MSM_BO_UNCACHED); - mutex_unlock(&drm->struct_mutex); - + bo = msm_gem_new_locked(drm, fw->size - 4, MSM_BO_UNCACHED); if (IS_ERR(bo)) return bo; ptr = msm_gem_get_vaddr(bo); if (!ptr) { - drm_gem_object_unreference_unlocked(bo); + drm_gem_object_unreference(bo); return ERR_PTR(-ENOMEM); } if (iova) { - int ret = msm_gem_get_iova(bo, gpu->id, iova); + int ret = msm_gem_get_iova(bo, gpu->aspace, iova); if (ret) { - drm_gem_object_unreference_unlocked(bo); + drm_gem_object_unreference(bo); return ERR_PTR(ret); } } @@ -304,6 +363,98 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) return 0; } +#define SCM_GPU_ZAP_SHADER_RESUME 0 + +static int a5xx_zap_shader_resume(struct msm_gpu *gpu) +{ + int ret; + + ret = qcom_scm_set_remote_state(SCM_GPU_ZAP_SHADER_RESUME, GPU_PAS_ID); + if (ret) + DRM_ERROR("%s: zap-shader resume failed: %d\n", + gpu->name, ret); + + return ret; +} + +/* Set up a child device to "own" the zap shader */ +static int a5xx_zap_shader_dev_init(struct device *parent, struct device *dev) +{ + struct device_node *node; + int ret; + + if (dev->parent) + return 0; + + /* Find the sub-node for the zap shader */ + node = of_get_child_by_name(parent->of_node, "zap-shader"); + if (!node) { + DRM_DEV_ERROR(parent, "zap-shader not found in device tree\n"); + return -ENODEV; + } + + dev->parent = parent; + dev->of_node = node; + dev_set_name(dev, "adreno_zap_shader"); + + ret = device_register(dev); + if (ret) { + DRM_DEV_ERROR(parent, "Couldn't register zap shader device\n"); + goto out; + } + + ret = of_reserved_mem_device_init(dev); + if (ret) { + DRM_DEV_ERROR(parent, "Unable to set up the reserved memory\n"); + device_unregister(dev); + } + +out: + if (ret) + dev->parent = NULL; + + return ret; +} + +static int a5xx_zap_shader_init(struct msm_gpu *gpu) +{ + static bool loaded; + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + struct platform_device *pdev = a5xx_gpu->pdev; + int ret; + + /* + * If the zap shader is already loaded into memory we just need to kick + * the remote processor to reinitialize it + */ + if (loaded) + return a5xx_zap_shader_resume(gpu); + + /* We need SCM to be able to load the firmware */ + if (!qcom_scm_is_available()) { + DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n"); + return -EPROBE_DEFER; + } + + /* Each GPU has a target specific zap shader firmware name to use */ + if (!adreno_gpu->info->zapfw) { + DRM_DEV_ERROR(&pdev->dev, + "Zap shader firmware file not specified for this target\n"); + return -ENODEV; + } + + ret = a5xx_zap_shader_dev_init(&pdev->dev, &a5xx_gpu->zap_dev); + + if (!ret) + ret = zap_shader_load_mdt(&a5xx_gpu->zap_dev, + adreno_gpu->info->zapfw); + + loaded = !ret; + + return ret; +} + #define A5XX_INT_MASK (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \ A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \ A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \ @@ -484,12 +635,31 @@ static int a5xx_hw_init(struct msm_gpu *gpu) OUT_RING(gpu->rb, 0x0F); gpu->funcs->flush(gpu); - if (!gpu->funcs->idle(gpu)) + if (!a5xx_idle(gpu)) return -EINVAL; } - /* Put the GPU into unsecure mode */ - gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0); + /* + * Try to load a zap shader into the secure world. If successful + * we can use the CP to switch out of secure mode. If not then we + * have no resource but to try to switch ourselves out manually. If we + * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will + * be blocked and a permissions violation will soon follow. + */ + ret = a5xx_zap_shader_init(gpu); + if (!ret) { + OUT_PKT7(gpu->rb, CP_SET_SECURE_MODE, 1); + OUT_RING(gpu->rb, 0x00000000); + + gpu->funcs->flush(gpu); + if (!a5xx_idle(gpu)) + return -EINVAL; + } else { + /* Print a warning so if we die, we know why */ + dev_warn_once(gpu->dev->dev, + "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n"); + gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0); + } return 0; } @@ -521,21 +691,24 @@ static void a5xx_destroy(struct msm_gpu *gpu) DBG("%s", gpu->name); + if (a5xx_gpu->zap_dev.parent) + device_unregister(&a5xx_gpu->zap_dev); + if (a5xx_gpu->pm4_bo) { if (a5xx_gpu->pm4_iova) - msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->id); + msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace); drm_gem_object_unreference_unlocked(a5xx_gpu->pm4_bo); } if (a5xx_gpu->pfp_bo) { if (a5xx_gpu->pfp_iova) - msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->id); + msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace); drm_gem_object_unreference_unlocked(a5xx_gpu->pfp_bo); } if (a5xx_gpu->gpmu_bo) { if (a5xx_gpu->gpmu_iova) - msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->id); + msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace); drm_gem_object_unreference_unlocked(a5xx_gpu->gpmu_bo); } @@ -556,7 +729,7 @@ static inline bool _a5xx_check_idle(struct msm_gpu *gpu) A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT); } -static bool a5xx_idle(struct msm_gpu *gpu) +bool a5xx_idle(struct msm_gpu *gpu) { /* wait for CP to drain ringbuffer: */ if (!adreno_idle(gpu)) @@ -861,7 +1034,6 @@ static const struct adreno_gpu_funcs funcs = { .last_fence = adreno_last_fence, .submit = a5xx_submit, .flush = adreno_flush, - .idle = a5xx_idle, .irq = a5xx_irq, .destroy = a5xx_destroy, #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h index 1590f84..6638bc8 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h @@ -36,6 +36,8 @@ struct a5xx_gpu { uint32_t gpmu_dwords; uint32_t lm_leakage; + + struct device zap_dev; }; #define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base) @@ -56,5 +58,6 @@ static inline int spin_usecs(struct msm_gpu *gpu, uint32_t usecs, return -ETIMEDOUT; } +bool a5xx_idle(struct msm_gpu *gpu); #endif /* __A5XX_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index 72d52c7..87af6ee 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -194,7 +194,7 @@ static int a5xx_gpmu_init(struct msm_gpu *gpu) gpu->funcs->flush(gpu); - if (!gpu->funcs->idle(gpu)) { + if (!a5xx_idle(gpu)) { DRM_ERROR("%s: Unable to load GPMU firmware. GPMU will not be active\n", gpu->name); return -EINVAL; @@ -294,14 +294,12 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) */ bosize = (cmds_size + (cmds_size / TYPE4_MAX_PAYLOAD) + 1) << 2; - mutex_lock(&drm->struct_mutex); - a5xx_gpu->gpmu_bo = msm_gem_new(drm, bosize, MSM_BO_UNCACHED); - mutex_unlock(&drm->struct_mutex); - + a5xx_gpu->gpmu_bo = msm_gem_new_locked(drm, bosize, MSM_BO_UNCACHED); if (IS_ERR(a5xx_gpu->gpmu_bo)) goto err; - if (msm_gem_get_iova(a5xx_gpu->gpmu_bo, gpu->id, &a5xx_gpu->gpmu_iova)) + if (msm_gem_get_iova(a5xx_gpu->gpmu_bo, gpu->aspace, + &a5xx_gpu->gpmu_iova)) goto err; ptr = msm_gem_get_vaddr(a5xx_gpu->gpmu_bo); @@ -330,9 +328,9 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) err: if (a5xx_gpu->gpmu_iova) - msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->id); + msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace); if (a5xx_gpu->gpmu_bo) - drm_gem_object_unreference_unlocked(a5xx_gpu->gpmu_bo); + drm_gem_object_unreference(a5xx_gpu->gpmu_bo); a5xx_gpu->gpmu_bo = NULL; a5xx_gpu->gpmu_iova = 0; diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h index 4a33ba6..b634cf7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h @@ -8,17 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2016-04-26 17:56:44) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32907 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 12025 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 22544 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 110765 bytes, from 2016-11-26 23:01:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 90321 bytes, from 2016-11-28 16:50:05) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) - -Copyright (C) 2013-2016 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 37162 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 13324 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 31866 bytes, from 2017-06-06 18:26:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 111898 bytes, from 2017-06-06 18:23:59) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 139480 bytes, from 2017-06-16 12:44:39) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) @@ -421,6 +421,35 @@ static inline uint32_t AXXX_CP_CSQ_IB2_STAT_WPTR(uint32_t val) #define REG_AXXX_CP_IB2_BUFSZ 0x0000045b #define REG_AXXX_CP_STAT 0x0000047f +#define AXXX_CP_STAT_CP_BUSY 0x80000000 +#define AXXX_CP_STAT_VS_EVENT_FIFO_BUSY 0x40000000 +#define AXXX_CP_STAT_PS_EVENT_FIFO_BUSY 0x20000000 +#define AXXX_CP_STAT_CF_EVENT_FIFO_BUSY 0x10000000 +#define AXXX_CP_STAT_RB_EVENT_FIFO_BUSY 0x08000000 +#define AXXX_CP_STAT_ME_BUSY 0x04000000 +#define AXXX_CP_STAT_MIU_WR_C_BUSY 0x02000000 +#define AXXX_CP_STAT_CP_3D_BUSY 0x00800000 +#define AXXX_CP_STAT_CP_NRT_BUSY 0x00400000 +#define AXXX_CP_STAT_RBIU_SCRATCH_BUSY 0x00200000 +#define AXXX_CP_STAT_RCIU_ME_BUSY 0x00100000 +#define AXXX_CP_STAT_RCIU_PFP_BUSY 0x00080000 +#define AXXX_CP_STAT_MEQ_RING_BUSY 0x00040000 +#define AXXX_CP_STAT_PFP_BUSY 0x00020000 +#define AXXX_CP_STAT_ST_QUEUE_BUSY 0x00010000 +#define AXXX_CP_STAT_INDIRECT2_QUEUE_BUSY 0x00002000 +#define AXXX_CP_STAT_INDIRECTS_QUEUE_BUSY 0x00001000 +#define AXXX_CP_STAT_RING_QUEUE_BUSY 0x00000800 +#define AXXX_CP_STAT_CSF_BUSY 0x00000400 +#define AXXX_CP_STAT_CSF_ST_BUSY 0x00000200 +#define AXXX_CP_STAT_EVENT_BUSY 0x00000100 +#define AXXX_CP_STAT_CSF_INDIRECT2_BUSY 0x00000080 +#define AXXX_CP_STAT_CSF_INDIRECTS_BUSY 0x00000040 +#define AXXX_CP_STAT_CSF_RING_BUSY 0x00000020 +#define AXXX_CP_STAT_RCIU_BUSY 0x00000010 +#define AXXX_CP_STAT_RBIU_BUSY 0x00000008 +#define AXXX_CP_STAT_MIU_RD_RETURN_BUSY 0x00000004 +#define AXXX_CP_STAT_MIU_RD_REQ_BUSY 0x00000002 +#define AXXX_CP_STAT_MIU_WR_BUSY 0x00000001 #define REG_AXXX_CP_SCRATCH_REG0 0x00000578 diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index c0fa5d1..c75c4df 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -86,6 +86,7 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .gpmufw = "a530v3_gpmu.fw2", + .zapfw = "a530_zap.mdt", }, }; @@ -158,7 +159,9 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) int ret; pm_runtime_get_sync(&pdev->dev); + mutex_lock(&dev->struct_mutex); ret = msm_gpu_hw_init(gpu); + mutex_unlock(&dev->struct_mutex); pm_runtime_put_sync(&pdev->dev); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 5b63fc6..f1ab270 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -64,7 +64,7 @@ int adreno_hw_init(struct msm_gpu *gpu) DBG("%s", gpu->name); - ret = msm_gem_get_iova(gpu->rb->bo, gpu->id, &gpu->rb_iova); + ret = msm_gem_get_iova(gpu->rb->bo, gpu->aspace, &gpu->rb_iova); if (ret) { gpu->rb_iova = 0; dev_err(gpu->dev->dev, "could not map ringbuffer: %d\n", ret); @@ -77,7 +77,6 @@ int adreno_hw_init(struct msm_gpu *gpu) /* reset completed fence seqno: */ adreno_gpu->memptrs->fence = gpu->fctx->completed_fence; adreno_gpu->memptrs->rptr = 0; - adreno_gpu->memptrs->wptr = 0; /* Setup REG_CP_RB_CNTL: */ adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL, @@ -258,7 +257,6 @@ void adreno_show(struct msm_gpu *gpu, struct seq_file *m) seq_printf(m, "fence: %d/%d\n", adreno_gpu->memptrs->fence, gpu->fctx->last_fence); seq_printf(m, "rptr: %d\n", get_rptr(adreno_gpu)); - seq_printf(m, "wptr: %d\n", adreno_gpu->memptrs->wptr); seq_printf(m, "rb wptr: %d\n", get_wptr(gpu->rb)); /* dump these out in a form that can be parsed by demsm: */ @@ -294,7 +292,6 @@ void adreno_dump_info(struct msm_gpu *gpu) printk("fence: %d/%d\n", adreno_gpu->memptrs->fence, gpu->fctx->last_fence); printk("rptr: %d\n", get_rptr(adreno_gpu)); - printk("wptr: %d\n", adreno_gpu->memptrs->wptr); printk("rb wptr: %d\n", get_wptr(gpu->rb)); } @@ -342,6 +339,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs) { struct adreno_platform_config *config = pdev->dev.platform_data; + struct msm_gpu_config adreno_gpu_config = { 0 }; struct msm_gpu *gpu = &adreno_gpu->base; int ret; @@ -360,9 +358,16 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, DBG("fast_rate=%u, slow_rate=27000000, bus_freq=%u", gpu->fast_rate, gpu->bus_freq); + adreno_gpu_config.ioname = "kgsl_3d0_reg_memory"; + adreno_gpu_config.irqname = "kgsl_3d0_irq"; + + adreno_gpu_config.va_start = SZ_16M; + adreno_gpu_config.va_end = 0xffffffff; + + adreno_gpu_config.ringsz = RB_SIZE; + ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, - adreno_gpu->info->name, "kgsl_3d0_reg_memory", "kgsl_3d0_irq", - RB_SIZE); + adreno_gpu->info->name, &adreno_gpu_config); if (ret) return ret; @@ -392,10 +397,8 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, return ret; } - mutex_lock(&drm->struct_mutex); adreno_gpu->memptrs_bo = msm_gem_new(drm, sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED); - mutex_unlock(&drm->struct_mutex); if (IS_ERR(adreno_gpu->memptrs_bo)) { ret = PTR_ERR(adreno_gpu->memptrs_bo); adreno_gpu->memptrs_bo = NULL; @@ -409,7 +412,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, return -ENOMEM; } - ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->id, + ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->aspace, &adreno_gpu->memptrs_iova); if (ret) { dev_err(drm->dev, "could not map memptrs: %d\n", ret); @@ -428,7 +431,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) msm_gem_put_vaddr(adreno_gpu->memptrs_bo); if (adreno_gpu->memptrs_iova) - msm_gem_put_iova(adreno_gpu->memptrs_bo, gpu->id); + msm_gem_put_iova(adreno_gpu->memptrs_bo, gpu->aspace); drm_gem_object_unreference_unlocked(adreno_gpu->memptrs_bo); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index fb4831f..4d9165f 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -77,6 +77,7 @@ struct adreno_info { uint32_t gmem; enum adreno_quirks quirks; struct msm_gpu *(*init)(struct drm_device *dev); + const char *zapfw; }; const struct adreno_info *adreno_info(struct adreno_rev rev); @@ -86,7 +87,6 @@ const struct adreno_info *adreno_info(struct adreno_rev rev); struct adreno_rbmemptrs { volatile uint32_t rptr; - volatile uint32_t wptr; volatile uint32_t fence; }; diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h index 6a2930e..fb605a3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h @@ -8,17 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2016-04-26 17:56:44) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32907 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 12025 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 22544 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 110765 bytes, from 2016-11-26 23:01:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 90321 bytes, from 2016-11-28 16:50:05) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) - -Copyright (C) 2013-2016 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 37162 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 13324 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 31866 bytes, from 2017-06-06 18:26:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 111898 bytes, from 2017-06-06 18:23:59) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 139480 bytes, from 2017-06-16 12:44:39) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) @@ -67,10 +67,18 @@ enum vgt_event_type { PERFCOUNTER_STOP = 24, VS_FETCH_DONE = 27, FACENESS_FLUSH = 28, + FLUSH_SO_0 = 17, + FLUSH_SO_1 = 18, + FLUSH_SO_2 = 19, + FLUSH_SO_3 = 20, + UNK_19 = 25, UNK_1C = 28, UNK_1D = 29, BLIT = 30, - UNK_26 = 38, + UNK_25 = 37, + LRZ_FLUSH = 38, + UNK_2C = 44, + UNK_2D = 45, }; enum pc_di_primtype { @@ -134,11 +142,13 @@ enum adreno_pm4_type3_packets { CP_WAIT_IB_PFD_COMPLETE = 93, CP_REG_RMW = 33, CP_SET_BIN_DATA = 47, + CP_SET_BIN_DATA5 = 47, CP_REG_TO_MEM = 62, CP_MEM_WRITE = 61, CP_MEM_WRITE_CNTR = 79, CP_COND_EXEC = 68, CP_COND_WRITE = 69, + CP_COND_WRITE5 = 69, CP_EVENT_WRITE = 70, CP_EVENT_WRITE_SHD = 88, CP_EVENT_WRITE_CFL = 89, @@ -165,6 +175,7 @@ enum adreno_pm4_type3_packets { CP_SET_PROTECTED_MODE = 95, CP_BOOTSTRAP_UCODE = 111, CP_LOAD_STATE = 48, + CP_LOAD_STATE4 = 48, CP_COND_INDIRECT_BUFFER_PFE = 58, CP_COND_INDIRECT_BUFFER_PFD = 50, CP_INDIRECT_BUFFER_PFE = 63, @@ -204,6 +215,7 @@ enum adreno_pm4_type3_packets { CP_COMPUTE_CHECKPOINT = 110, CP_MEM_TO_MEM = 115, CP_BLIT = 44, + CP_UNK_39 = 57, IN_IB_PREFETCH_END = 23, IN_SUBBLK_PREFETCH = 31, IN_INSTR_PREFETCH = 32, @@ -239,21 +251,61 @@ enum adreno_state_src { SS_INDIRECT_STM = 6, }; +enum a4xx_state_block { + SB4_VS_TEX = 0, + SB4_HS_TEX = 1, + SB4_DS_TEX = 2, + SB4_GS_TEX = 3, + SB4_FS_TEX = 4, + SB4_CS_TEX = 5, + SB4_VS_SHADER = 8, + SB4_HS_SHADER = 9, + SB4_DS_SHADER = 10, + SB4_GS_SHADER = 11, + SB4_FS_SHADER = 12, + SB4_CS_SHADER = 13, + SB4_SSBO = 14, + SB4_CS_SSBO = 15, +}; + +enum a4xx_state_type { + ST4_SHADER = 0, + ST4_CONSTANTS = 1, +}; + +enum a4xx_state_src { + SS4_DIRECT = 0, + SS4_INDIRECT = 2, +}; + enum a4xx_index_size { INDEX4_SIZE_8_BIT = 0, INDEX4_SIZE_16_BIT = 1, INDEX4_SIZE_32_BIT = 2, }; +enum cp_cond_function { + WRITE_ALWAYS = 0, + WRITE_LT = 1, + WRITE_LE = 2, + WRITE_EQ = 3, + WRITE_NE = 4, + WRITE_GE = 5, + WRITE_GT = 6, +}; + enum render_mode_cmd { BYPASS = 1, + BINNING = 2, GMEM = 3, BLIT2D = 5, + BLIT2DSCALE = 7, }; enum cp_blit_cmd { BLIT_OP_FILL = 0, - BLIT_OP_BLIT = 1, + BLIT_OP_COPY = 1, + BLIT_OP_SCALE = 3, }; #define REG_CP_LOAD_STATE_0 0x00000000 @@ -296,12 +348,52 @@ static inline uint32_t CP_LOAD_STATE_1_EXT_SRC_ADDR(uint32_t val) return ((val >> 2) << CP_LOAD_STATE_1_EXT_SRC_ADDR__SHIFT) & CP_LOAD_STATE_1_EXT_SRC_ADDR__MASK; } -#define REG_CP_LOAD_STATE_2 0x00000002 -#define CP_LOAD_STATE_2_EXT_SRC_ADDR_HI__MASK 0xffffffff -#define CP_LOAD_STATE_2_EXT_SRC_ADDR_HI__SHIFT 0 -static inline uint32_t CP_LOAD_STATE_2_EXT_SRC_ADDR_HI(uint32_t val) +#define REG_CP_LOAD_STATE4_0 0x00000000 +#define CP_LOAD_STATE4_0_DST_OFF__MASK 0x0000ffff +#define CP_LOAD_STATE4_0_DST_OFF__SHIFT 0 +static inline uint32_t CP_LOAD_STATE4_0_DST_OFF(uint32_t val) +{ + return ((val) << CP_LOAD_STATE4_0_DST_OFF__SHIFT) & CP_LOAD_STATE4_0_DST_OFF__MASK; +} +#define CP_LOAD_STATE4_0_STATE_SRC__MASK 0x00030000 +#define CP_LOAD_STATE4_0_STATE_SRC__SHIFT 16 +static inline uint32_t CP_LOAD_STATE4_0_STATE_SRC(enum a4xx_state_src val) +{ + return ((val) << CP_LOAD_STATE4_0_STATE_SRC__SHIFT) & CP_LOAD_STATE4_0_STATE_SRC__MASK; +} +#define CP_LOAD_STATE4_0_STATE_BLOCK__MASK 0x003c0000 +#define CP_LOAD_STATE4_0_STATE_BLOCK__SHIFT 18 +static inline uint32_t CP_LOAD_STATE4_0_STATE_BLOCK(enum a4xx_state_block val) +{ + return ((val) << CP_LOAD_STATE4_0_STATE_BLOCK__SHIFT) & CP_LOAD_STATE4_0_STATE_BLOCK__MASK; +} +#define CP_LOAD_STATE4_0_NUM_UNIT__MASK 0xffc00000 +#define CP_LOAD_STATE4_0_NUM_UNIT__SHIFT 22 +static inline uint32_t CP_LOAD_STATE4_0_NUM_UNIT(uint32_t val) +{ + return ((val) << CP_LOAD_STATE4_0_NUM_UNIT__SHIFT) & CP_LOAD_STATE4_0_NUM_UNIT__MASK; +} + +#define REG_CP_LOAD_STATE4_1 0x00000001 +#define CP_LOAD_STATE4_1_STATE_TYPE__MASK 0x00000003 +#define CP_LOAD_STATE4_1_STATE_TYPE__SHIFT 0 +static inline uint32_t CP_LOAD_STATE4_1_STATE_TYPE(enum a4xx_state_type val) +{ + return ((val) << CP_LOAD_STATE4_1_STATE_TYPE__SHIFT) & CP_LOAD_STATE4_1_STATE_TYPE__MASK; +} +#define CP_LOAD_STATE4_1_EXT_SRC_ADDR__MASK 0xfffffffc +#define CP_LOAD_STATE4_1_EXT_SRC_ADDR__SHIFT 2 +static inline uint32_t CP_LOAD_STATE4_1_EXT_SRC_ADDR(uint32_t val) +{ + return ((val >> 2) << CP_LOAD_STATE4_1_EXT_SRC_ADDR__SHIFT) & CP_LOAD_STATE4_1_EXT_SRC_ADDR__MASK; +} + +#define REG_CP_LOAD_STATE4_2 0x00000002 +#define CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI__MASK 0xffffffff +#define CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI__SHIFT 0 +static inline uint32_t CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(uint32_t val) { - return ((val) << CP_LOAD_STATE_2_EXT_SRC_ADDR_HI__SHIFT) & CP_LOAD_STATE_2_EXT_SRC_ADDR_HI__MASK; + return ((val) << CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI__SHIFT) & CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI__MASK; } #define REG_CP_DRAW_INDX_0 0x00000000 @@ -570,6 +662,52 @@ static inline uint32_t CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS(uint32_t val) return ((val) << CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS__SHIFT) & CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS__MASK; } +#define REG_CP_SET_BIN_DATA5_0 0x00000000 +#define CP_SET_BIN_DATA5_0_VSC_SIZE__MASK 0x003f0000 +#define CP_SET_BIN_DATA5_0_VSC_SIZE__SHIFT 16 +static inline uint32_t CP_SET_BIN_DATA5_0_VSC_SIZE(uint32_t val) +{ + return ((val) << CP_SET_BIN_DATA5_0_VSC_SIZE__SHIFT) & CP_SET_BIN_DATA5_0_VSC_SIZE__MASK; +} +#define CP_SET_BIN_DATA5_0_VSC_N__MASK 0x07c00000 +#define CP_SET_BIN_DATA5_0_VSC_N__SHIFT 22 +static inline uint32_t CP_SET_BIN_DATA5_0_VSC_N(uint32_t val) +{ + return ((val) << CP_SET_BIN_DATA5_0_VSC_N__SHIFT) & CP_SET_BIN_DATA5_0_VSC_N__MASK; +} + +#define REG_CP_SET_BIN_DATA5_1 0x00000001 +#define CP_SET_BIN_DATA5_1_BIN_DATA_ADDR_LO__MASK 0xffffffff +#define CP_SET_BIN_DATA5_1_BIN_DATA_ADDR_LO__SHIFT 0 +static inline uint32_t CP_SET_BIN_DATA5_1_BIN_DATA_ADDR_LO(uint32_t val) +{ + return ((val) << CP_SET_BIN_DATA5_1_BIN_DATA_ADDR_LO__SHIFT) & CP_SET_BIN_DATA5_1_BIN_DATA_ADDR_LO__MASK; +} + +#define REG_CP_SET_BIN_DATA5_2 0x00000002 +#define CP_SET_BIN_DATA5_2_BIN_DATA_ADDR_HI__MASK 0xffffffff +#define CP_SET_BIN_DATA5_2_BIN_DATA_ADDR_HI__SHIFT 0 +static inline uint32_t CP_SET_BIN_DATA5_2_BIN_DATA_ADDR_HI(uint32_t val) +{ + return ((val) << CP_SET_BIN_DATA5_2_BIN_DATA_ADDR_HI__SHIFT) & CP_SET_BIN_DATA5_2_BIN_DATA_ADDR_HI__MASK; +} + +#define REG_CP_SET_BIN_DATA5_3 0x00000003 +#define CP_SET_BIN_DATA5_3_BIN_SIZE_ADDRESS_LO__MASK 0xffffffff +#define CP_SET_BIN_DATA5_3_BIN_SIZE_ADDRESS_LO__SHIFT 0 +static inline uint32_t CP_SET_BIN_DATA5_3_BIN_SIZE_ADDRESS_LO(uint32_t val) +{ + return ((val) << CP_SET_BIN_DATA5_3_BIN_SIZE_ADDRESS_LO__SHIFT) & CP_SET_BIN_DATA5_3_BIN_SIZE_ADDRESS_LO__MASK; +} + +#define REG_CP_SET_BIN_DATA5_4 0x00000004 +#define CP_SET_BIN_DATA5_4_BIN_SIZE_ADDRESS_HI__MASK 0xffffffff +#define CP_SET_BIN_DATA5_4_BIN_SIZE_ADDRESS_HI__SHIFT 0 +static inline uint32_t CP_SET_BIN_DATA5_4_BIN_SIZE_ADDRESS_HI(uint32_t val) +{ + return ((val) << CP_SET_BIN_DATA5_4_BIN_SIZE_ADDRESS_HI__SHIFT) & CP_SET_BIN_DATA5_4_BIN_SIZE_ADDRESS_HI__MASK; +} + #define REG_CP_REG_TO_MEM_0 0x00000000 #define CP_REG_TO_MEM_0_REG__MASK 0x0000ffff #define CP_REG_TO_MEM_0_REG__SHIFT 0 @@ -594,6 +732,128 @@ static inline uint32_t CP_REG_TO_MEM_1_DEST(uint32_t val) return ((val) << CP_REG_TO_MEM_1_DEST__SHIFT) & CP_REG_TO_MEM_1_DEST__MASK; } +#define REG_CP_MEM_TO_MEM_0 0x00000000 +#define CP_MEM_TO_MEM_0_NEG_A 0x00000001 +#define CP_MEM_TO_MEM_0_NEG_B 0x00000002 +#define CP_MEM_TO_MEM_0_NEG_C 0x00000004 +#define CP_MEM_TO_MEM_0_DOUBLE 0x20000000 + +#define REG_CP_COND_WRITE_0 0x00000000 +#define CP_COND_WRITE_0_FUNCTION__MASK 0x00000007 +#define CP_COND_WRITE_0_FUNCTION__SHIFT 0 +static inline uint32_t CP_COND_WRITE_0_FUNCTION(enum cp_cond_function val) +{ + return ((val) << CP_COND_WRITE_0_FUNCTION__SHIFT) & CP_COND_WRITE_0_FUNCTION__MASK; +} +#define CP_COND_WRITE_0_POLL_MEMORY 0x00000010 +#define CP_COND_WRITE_0_WRITE_MEMORY 0x00000100 + +#define REG_CP_COND_WRITE_1 0x00000001 +#define CP_COND_WRITE_1_POLL_ADDR__MASK 0xffffffff +#define CP_COND_WRITE_1_POLL_ADDR__SHIFT 0 +static inline uint32_t CP_COND_WRITE_1_POLL_ADDR(uint32_t val) +{ + return ((val) << CP_COND_WRITE_1_POLL_ADDR__SHIFT) & CP_COND_WRITE_1_POLL_ADDR__MASK; +} + +#define REG_CP_COND_WRITE_2 0x00000002 +#define CP_COND_WRITE_2_REF__MASK 0xffffffff +#define CP_COND_WRITE_2_REF__SHIFT 0 +static inline uint32_t CP_COND_WRITE_2_REF(uint32_t val) +{ + return ((val) << CP_COND_WRITE_2_REF__SHIFT) & CP_COND_WRITE_2_REF__MASK; +} + +#define REG_CP_COND_WRITE_3 0x00000003 +#define CP_COND_WRITE_3_MASK__MASK 0xffffffff +#define CP_COND_WRITE_3_MASK__SHIFT 0 +static inline uint32_t CP_COND_WRITE_3_MASK(uint32_t val) +{ + return ((val) << CP_COND_WRITE_3_MASK__SHIFT) & CP_COND_WRITE_3_MASK__MASK; +} + +#define REG_CP_COND_WRITE_4 0x00000004 +#define CP_COND_WRITE_4_WRITE_ADDR__MASK 0xffffffff +#define CP_COND_WRITE_4_WRITE_ADDR__SHIFT 0 +static inline uint32_t CP_COND_WRITE_4_WRITE_ADDR(uint32_t val) +{ + return ((val) << CP_COND_WRITE_4_WRITE_ADDR__SHIFT) & CP_COND_WRITE_4_WRITE_ADDR__MASK; +} + +#define REG_CP_COND_WRITE_5 0x00000005 +#define CP_COND_WRITE_5_WRITE_DATA__MASK 0xffffffff +#define CP_COND_WRITE_5_WRITE_DATA__SHIFT 0 +static inline uint32_t CP_COND_WRITE_5_WRITE_DATA(uint32_t val) +{ + return ((val) << CP_COND_WRITE_5_WRITE_DATA__SHIFT) & CP_COND_WRITE_5_WRITE_DATA__MASK; +} + +#define REG_CP_COND_WRITE5_0 0x00000000 +#define CP_COND_WRITE5_0_FUNCTION__MASK 0x00000007 +#define CP_COND_WRITE5_0_FUNCTION__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_0_FUNCTION(enum cp_cond_function val) +{ + return ((val) << CP_COND_WRITE5_0_FUNCTION__SHIFT) & CP_COND_WRITE5_0_FUNCTION__MASK; +} +#define CP_COND_WRITE5_0_POLL_MEMORY 0x00000010 +#define CP_COND_WRITE5_0_WRITE_MEMORY 0x00000100 + +#define REG_CP_COND_WRITE5_1 0x00000001 +#define CP_COND_WRITE5_1_POLL_ADDR_LO__MASK 0xffffffff +#define CP_COND_WRITE5_1_POLL_ADDR_LO__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_1_POLL_ADDR_LO(uint32_t val) +{ + return ((val) << CP_COND_WRITE5_1_POLL_ADDR_LO__SHIFT) & CP_COND_WRITE5_1_POLL_ADDR_LO__MASK; +} + +#define REG_CP_COND_WRITE5_2 0x00000002 +#define CP_COND_WRITE5_2_POLL_ADDR_HI__MASK 0xffffffff +#define CP_COND_WRITE5_2_POLL_ADDR_HI__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_2_POLL_ADDR_HI(uint32_t val) +{ + return ((val) << CP_COND_WRITE5_2_POLL_ADDR_HI__SHIFT) & CP_COND_WRITE5_2_POLL_ADDR_HI__MASK; +} + +#define REG_CP_COND_WRITE5_3 0x00000003 +#define CP_COND_WRITE5_3_REF__MASK 0xffffffff +#define CP_COND_WRITE5_3_REF__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_3_REF(uint32_t val) +{ + return ((val) << CP_COND_WRITE5_3_REF__SHIFT) & CP_COND_WRITE5_3_REF__MASK; +} + +#define REG_CP_COND_WRITE5_4 0x00000004 +#define CP_COND_WRITE5_4_MASK__MASK 0xffffffff +#define CP_COND_WRITE5_4_MASK__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_4_MASK(uint32_t val) +{ + return ((val) << CP_COND_WRITE5_4_MASK__SHIFT) & CP_COND_WRITE5_4_MASK__MASK; +} + +#define REG_CP_COND_WRITE5_5 0x00000005 +#define CP_COND_WRITE5_5_WRITE_ADDR_LO__MASK 0xffffffff +#define CP_COND_WRITE5_5_WRITE_ADDR_LO__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_5_WRITE_ADDR_LO(uint32_t val) +{ + return ((val) << CP_COND_WRITE5_5_WRITE_ADDR_LO__SHIFT) & CP_COND_WRITE5_5_WRITE_ADDR_LO__MASK; +} + +#define REG_CP_COND_WRITE5_6 0x00000006 +#define CP_COND_WRITE5_6_WRITE_ADDR_HI__MASK 0xffffffff +#define CP_COND_WRITE5_6_WRITE_ADDR_HI__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_6_WRITE_ADDR_HI(uint32_t val) +{ + return ((val) << CP_COND_WRITE5_6_WRITE_ADDR_HI__SHIFT) & CP_COND_WRITE5_6_WRITE_ADDR_HI__MASK; +} + +#define REG_CP_COND_WRITE5_7 0x00000007 +#define CP_COND_WRITE5_7_WRITE_DATA__MASK 0xffffffff +#define CP_COND_WRITE5_7_WRITE_DATA__SHIFT 0 +static inline uint32_t CP_COND_WRITE5_7_WRITE_DATA(uint32_t val) +{ + return ((val) << CP_COND_WRITE5_7_WRITE_DATA__SHIFT) & CP_COND_WRITE5_7_WRITE_DATA__MASK; +} + #define REG_CP_DISPATCH_COMPUTE_0 0x00000000 #define REG_CP_DISPATCH_COMPUTE_1 0x00000001 @@ -645,6 +905,7 @@ static inline uint32_t CP_SET_RENDER_MODE_2_ADDR_0_HI(uint32_t val) } #define REG_CP_SET_RENDER_MODE_3 0x00000003 +#define CP_SET_RENDER_MODE_3_VSC_ENABLE 0x00000008 #define CP_SET_RENDER_MODE_3_GMEM_ENABLE 0x00000010 #define REG_CP_SET_RENDER_MODE_4 0x00000004 @@ -673,6 +934,50 @@ static inline uint32_t CP_SET_RENDER_MODE_7_ADDR_1_HI(uint32_t val) return ((val) << CP_SET_RENDER_MODE_7_ADDR_1_HI__SHIFT) & CP_SET_RENDER_MODE_7_ADDR_1_HI__MASK; } +#define REG_CP_COMPUTE_CHECKPOINT_0 0x00000000 +#define CP_COMPUTE_CHECKPOINT_0_ADDR_0_LO__MASK 0xffffffff +#define CP_COMPUTE_CHECKPOINT_0_ADDR_0_LO__SHIFT 0 +static inline uint32_t CP_COMPUTE_CHECKPOINT_0_ADDR_0_LO(uint32_t val) +{ + return ((val) << CP_COMPUTE_CHECKPOINT_0_ADDR_0_LO__SHIFT) & CP_COMPUTE_CHECKPOINT_0_ADDR_0_LO__MASK; +} + +#define REG_CP_COMPUTE_CHECKPOINT_1 0x00000001 +#define CP_COMPUTE_CHECKPOINT_1_ADDR_0_HI__MASK 0xffffffff +#define CP_COMPUTE_CHECKPOINT_1_ADDR_0_HI__SHIFT 0 +static inline uint32_t CP_COMPUTE_CHECKPOINT_1_ADDR_0_HI(uint32_t val) +{ + return ((val) << CP_COMPUTE_CHECKPOINT_1_ADDR_0_HI__SHIFT) & CP_COMPUTE_CHECKPOINT_1_ADDR_0_HI__MASK; +} + +#define REG_CP_COMPUTE_CHECKPOINT_2 0x00000002 + +#define REG_CP_COMPUTE_CHECKPOINT_3 0x00000003 + +#define REG_CP_COMPUTE_CHECKPOINT_4 0x00000004 +#define CP_COMPUTE_CHECKPOINT_4_ADDR_1_LEN__MASK 0xffffffff +#define CP_COMPUTE_CHECKPOINT_4_ADDR_1_LEN__SHIFT 0 +static inline uint32_t CP_COMPUTE_CHECKPOINT_4_ADDR_1_LEN(uint32_t val) +{ + return ((val) << CP_COMPUTE_CHECKPOINT_4_ADDR_1_LEN__SHIFT) & CP_COMPUTE_CHECKPOINT_4_ADDR_1_LEN__MASK; +} + +#define REG_CP_COMPUTE_CHECKPOINT_5 0x00000005 +#define CP_COMPUTE_CHECKPOINT_5_ADDR_1_LO__MASK 0xffffffff +#define CP_COMPUTE_CHECKPOINT_5_ADDR_1_LO__SHIFT 0 +static inline uint32_t CP_COMPUTE_CHECKPOINT_5_ADDR_1_LO(uint32_t val) +{ + return ((val) << CP_COMPUTE_CHECKPOINT_5_ADDR_1_LO__SHIFT) & CP_COMPUTE_CHECKPOINT_5_ADDR_1_LO__MASK; +} + +#define REG_CP_COMPUTE_CHECKPOINT_6 0x00000006 +#define CP_COMPUTE_CHECKPOINT_6_ADDR_1_HI__MASK 0xffffffff +#define CP_COMPUTE_CHECKPOINT_6_ADDR_1_HI__SHIFT 0 +static inline uint32_t CP_COMPUTE_CHECKPOINT_6_ADDR_1_HI(uint32_t val) +{ + return ((val) << CP_COMPUTE_CHECKPOINT_6_ADDR_1_HI__SHIFT) & CP_COMPUTE_CHECKPOINT_6_ADDR_1_HI__MASK; +} + #define REG_CP_PERFCOUNTER_ACTION_0 0x00000000 #define REG_CP_PERFCOUNTER_ACTION_1 0x00000001 @@ -698,6 +1003,7 @@ static inline uint32_t CP_EVENT_WRITE_0_EVENT(enum vgt_event_type val) { return ((val) << CP_EVENT_WRITE_0_EVENT__SHIFT) & CP_EVENT_WRITE_0_EVENT__MASK; } +#define CP_EVENT_WRITE_0_TIMESTAMP 0x40000000 #define REG_CP_EVENT_WRITE_1 0x00000001 #define CP_EVENT_WRITE_1_ADDR_0_LO__MASK 0xffffffff @@ -781,5 +1087,31 @@ static inline uint32_t CP_BLIT_4_DST_Y2(uint32_t val) return ((val) << CP_BLIT_4_DST_Y2__SHIFT) & CP_BLIT_4_DST_Y2__MASK; } +#define REG_CP_EXEC_CS_0 0x00000000 + +#define REG_CP_EXEC_CS_1 0x00000001 +#define CP_EXEC_CS_1_NGROUPS_X__MASK 0xffffffff +#define CP_EXEC_CS_1_NGROUPS_X__SHIFT 0 +static inline uint32_t CP_EXEC_CS_1_NGROUPS_X(uint32_t val) +{ + return ((val) << CP_EXEC_CS_1_NGROUPS_X__SHIFT) & CP_EXEC_CS_1_NGROUPS_X__MASK; +} + +#define REG_CP_EXEC_CS_2 0x00000002 +#define CP_EXEC_CS_2_NGROUPS_Y__MASK 0xffffffff +#define CP_EXEC_CS_2_NGROUPS_Y__SHIFT 0 +static inline uint32_t CP_EXEC_CS_2_NGROUPS_Y(uint32_t val) +{ + return ((val) << CP_EXEC_CS_2_NGROUPS_Y__SHIFT) & CP_EXEC_CS_2_NGROUPS_Y__MASK; +} + +#define REG_CP_EXEC_CS_3 0x00000003 +#define CP_EXEC_CS_3_NGROUPS_Z__MASK 0xffffffff +#define CP_EXEC_CS_3_NGROUPS_Z__SHIFT 0 +static inline uint32_t CP_EXEC_CS_3_NGROUPS_Z(uint32_t val) +{ + return ((val) << CP_EXEC_CS_3_NGROUPS_Z__SHIFT) & CP_EXEC_CS_3_NGROUPS_Z__MASK; +} + #endif /* ADRENO_PM4_XML */ diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index b3d70ea..479086c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -8,8 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /local/mnt/workspace/source_trees/envytools/rnndb/../rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-01-11 05:19:19) -- /local/mnt/workspace/source_trees/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-05-09 06:32:54) +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index f97a780..9e9c569 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -32,6 +32,7 @@ #include "dsi.xml.h" #include "sfpb.xml.h" #include "dsi_cfg.h" +#include "msm_kms.h" static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) { @@ -975,23 +976,23 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size) { struct drm_device *dev = msm_host->dev; + struct msm_drm_private *priv = dev->dev_private; const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; int ret; uint64_t iova; if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) { - mutex_lock(&dev->struct_mutex); msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED); if (IS_ERR(msm_host->tx_gem_obj)) { ret = PTR_ERR(msm_host->tx_gem_obj); pr_err("%s: failed to allocate gem, %d\n", __func__, ret); msm_host->tx_gem_obj = NULL; - mutex_unlock(&dev->struct_mutex); return ret; } - ret = msm_gem_get_iova_locked(msm_host->tx_gem_obj, 0, &iova); + ret = msm_gem_get_iova(msm_host->tx_gem_obj, + priv->kms->aspace, &iova); mutex_unlock(&dev->struct_mutex); if (ret) { pr_err("%s: failed to get iova, %d\n", __func__, ret); @@ -1141,12 +1142,15 @@ static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len) { const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; + struct drm_device *dev = msm_host->dev; + struct msm_drm_private *priv = dev->dev_private; int ret; uint64_t dma_base; bool triggered; if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) { - ret = msm_gem_get_iova(msm_host->tx_gem_obj, 0, &dma_base); + ret = msm_gem_get_iova(msm_host->tx_gem_obj, + priv->kms->aspace, &dma_base); if (ret) { pr_err("%s: failed to get iova: %d\n", __func__, ret); return ret; diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h index 8b9f3eb..57cf7fa 100644 --- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h +++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) - -Copyright (C) 2013-2015 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h index 3fcbb30..9d4d1fe 100644 --- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h +++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) - -Copyright (C) 2013-2015 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) diff --git a/drivers/gpu/drm/msm/edp/edp.xml.h b/drivers/gpu/drm/msm/edp/edp.xml.h index d7bf323..f150d4a 100644 --- a/drivers/gpu/drm/msm/edp/edp.xml.h +++ b/drivers/gpu/drm/msm/edp/edp.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) - -Copyright (C) 2013-2015 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h index 0a97ff7..ecebf8b 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) - -Copyright (C) 2013-2016 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) @@ -111,6 +111,32 @@ static inline uint32_t HDMI_ACR_PKT_CTRL_N_MULTIPLIER(uint32_t val) #define HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE 0x00000040 #define HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE 0x00000080 +#define REG_HDMI_INFOFRAME_CTRL1 0x00000030 +#define HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK 0x0000003f +#define HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__SHIFT 0 +static inline uint32_t HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(uint32_t val) +{ + return ((val) << HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__SHIFT) & HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; +} +#define HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK 0x00003f00 +#define HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__SHIFT 8 +static inline uint32_t HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE(uint32_t val) +{ + return ((val) << HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__SHIFT) & HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK; +} +#define HDMI_INFOFRAME_CTRL1_MPEG_INFO_LINE__MASK 0x003f0000 +#define HDMI_INFOFRAME_CTRL1_MPEG_INFO_LINE__SHIFT 16 +static inline uint32_t HDMI_INFOFRAME_CTRL1_MPEG_INFO_LINE(uint32_t val) +{ + return ((val) << HDMI_INFOFRAME_CTRL1_MPEG_INFO_LINE__SHIFT) & HDMI_INFOFRAME_CTRL1_MPEG_INFO_LINE__MASK; +} +#define HDMI_INFOFRAME_CTRL1_VENSPEC_INFO_LINE__MASK 0x3f000000 +#define HDMI_INFOFRAME_CTRL1_VENSPEC_INFO_LINE__SHIFT 24 +static inline uint32_t HDMI_INFOFRAME_CTRL1_VENSPEC_INFO_LINE(uint32_t val) +{ + return ((val) << HDMI_INFOFRAME_CTRL1_VENSPEC_INFO_LINE__SHIFT) & HDMI_INFOFRAME_CTRL1_VENSPEC_INFO_LINE__MASK; +} + #define REG_HDMI_GEN_PKT_CTRL 0x00000034 #define HDMI_GEN_PKT_CTRL_GENERIC0_SEND 0x00000001 #define HDMI_GEN_PKT_CTRL_GENERIC0_CONT 0x00000002 @@ -463,7 +489,7 @@ static inline uint32_t HDMI_DDC_REF_REFTIMER(uint32_t val) #define REG_HDMI_CEC_RD_FILTER 0x000002b0 #define REG_HDMI_ACTIVE_HSYNC 0x000002b4 -#define HDMI_ACTIVE_HSYNC_START__MASK 0x00000fff +#define HDMI_ACTIVE_HSYNC_START__MASK 0x00001fff #define HDMI_ACTIVE_HSYNC_START__SHIFT 0 static inline uint32_t HDMI_ACTIVE_HSYNC_START(uint32_t val) { @@ -477,13 +503,13 @@ static inline uint32_t HDMI_ACTIVE_HSYNC_END(uint32_t val) } #define REG_HDMI_ACTIVE_VSYNC 0x000002b8 -#define HDMI_ACTIVE_VSYNC_START__MASK 0x00000fff +#define HDMI_ACTIVE_VSYNC_START__MASK 0x00001fff #define HDMI_ACTIVE_VSYNC_START__SHIFT 0 static inline uint32_t HDMI_ACTIVE_VSYNC_START(uint32_t val) { return ((val) << HDMI_ACTIVE_VSYNC_START__SHIFT) & HDMI_ACTIVE_VSYNC_START__MASK; } -#define HDMI_ACTIVE_VSYNC_END__MASK 0x0fff0000 +#define HDMI_ACTIVE_VSYNC_END__MASK 0x1fff0000 #define HDMI_ACTIVE_VSYNC_END__SHIFT 16 static inline uint32_t HDMI_ACTIVE_VSYNC_END(uint32_t val) { @@ -491,13 +517,13 @@ static inline uint32_t HDMI_ACTIVE_VSYNC_END(uint32_t val) } #define REG_HDMI_VSYNC_ACTIVE_F2 0x000002bc -#define HDMI_VSYNC_ACTIVE_F2_START__MASK 0x00000fff +#define HDMI_VSYNC_ACTIVE_F2_START__MASK 0x00001fff #define HDMI_VSYNC_ACTIVE_F2_START__SHIFT 0 static inline uint32_t HDMI_VSYNC_ACTIVE_F2_START(uint32_t val) { return ((val) << HDMI_VSYNC_ACTIVE_F2_START__SHIFT) & HDMI_VSYNC_ACTIVE_F2_START__MASK; } -#define HDMI_VSYNC_ACTIVE_F2_END__MASK 0x0fff0000 +#define HDMI_VSYNC_ACTIVE_F2_END__MASK 0x1fff0000 #define HDMI_VSYNC_ACTIVE_F2_END__SHIFT 16 static inline uint32_t HDMI_VSYNC_ACTIVE_F2_END(uint32_t val) { @@ -505,13 +531,13 @@ static inline uint32_t HDMI_VSYNC_ACTIVE_F2_END(uint32_t val) } #define REG_HDMI_TOTAL 0x000002c0 -#define HDMI_TOTAL_H_TOTAL__MASK 0x00000fff +#define HDMI_TOTAL_H_TOTAL__MASK 0x00001fff #define HDMI_TOTAL_H_TOTAL__SHIFT 0 static inline uint32_t HDMI_TOTAL_H_TOTAL(uint32_t val) { return ((val) << HDMI_TOTAL_H_TOTAL__SHIFT) & HDMI_TOTAL_H_TOTAL__MASK; } -#define HDMI_TOTAL_V_TOTAL__MASK 0x0fff0000 +#define HDMI_TOTAL_V_TOTAL__MASK 0x1fff0000 #define HDMI_TOTAL_V_TOTAL__SHIFT 16 static inline uint32_t HDMI_TOTAL_V_TOTAL(uint32_t val) { @@ -519,7 +545,7 @@ static inline uint32_t HDMI_TOTAL_V_TOTAL(uint32_t val) } #define REG_HDMI_VSYNC_TOTAL_F2 0x000002c4 -#define HDMI_VSYNC_TOTAL_F2_V_TOTAL__MASK 0x00000fff +#define HDMI_VSYNC_TOTAL_F2_V_TOTAL__MASK 0x00001fff #define HDMI_VSYNC_TOTAL_F2_V_TOTAL__SHIFT 0 static inline uint32_t HDMI_VSYNC_TOTAL_F2_V_TOTAL(uint32_t val) { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c index 8177e85..9c34b91 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c @@ -175,10 +175,10 @@ int msm_hdmi_audio_update(struct hdmi *hdmi) /* configure infoframe: */ hdmi_audio_infoframe_pack(info, buf, sizeof(buf)); hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0, - (buf[3] << 0) || (buf[4] << 8) || - (buf[5] << 16) || (buf[6] << 24)); + (buf[3] << 0) | (buf[4] << 8) | + (buf[5] << 16) | (buf[6] << 24)); hdmi_write(hdmi, REG_HDMI_AUDIO_INFO1, - (buf[7] << 0) || (buf[8] << 8)); + (buf[7] << 0) | (buf[8] << 8)); hdmi_write(hdmi, REG_HDMI_GC, 0); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 4e6d1bf..ae40e71 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -86,6 +86,65 @@ static void power_off(struct drm_bridge *bridge) } } +#define AVI_IFRAME_LINE_NUMBER 1 + +static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi) +{ + struct drm_crtc *crtc = hdmi->encoder->crtc; + const struct drm_display_mode *mode = &crtc->state->adjusted_mode; + union hdmi_infoframe frame; + u8 buffer[HDMI_INFOFRAME_SIZE(AVI)]; + u32 val; + int len; + + drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode); + + len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); + if (len < 0) { + dev_err(&hdmi->pdev->dev, + "failed to configure avi infoframe\n"); + return; + } + + /* + * the AVI_INFOx registers don't map exactly to how the AVI infoframes + * are packed according to the spec. The checksum from the header is + * written to the LSB byte of AVI_INFO0 and the version is written to + * the third byte from the LSB of AVI_INFO3 + */ + hdmi_write(hdmi, REG_HDMI_AVI_INFO(0), + buffer[3] | + buffer[4] << 8 | + buffer[5] << 16 | + buffer[6] << 24); + + hdmi_write(hdmi, REG_HDMI_AVI_INFO(1), + buffer[7] | + buffer[8] << 8 | + buffer[9] << 16 | + buffer[10] << 24); + + hdmi_write(hdmi, REG_HDMI_AVI_INFO(2), + buffer[11] | + buffer[12] << 8 | + buffer[13] << 16 | + buffer[14] << 24); + + hdmi_write(hdmi, REG_HDMI_AVI_INFO(3), + buffer[15] | + buffer[16] << 8 | + buffer[1] << 24); + + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, + HDMI_INFOFRAME_CTRL0_AVI_SEND | + HDMI_INFOFRAME_CTRL0_AVI_CONT); + + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); + val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; + val |= HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER); + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); +} + static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge) { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); @@ -98,7 +157,10 @@ static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge) msm_hdmi_phy_resource_enable(phy); msm_hdmi_power_on(bridge); hdmi->power_on = true; - msm_hdmi_audio_update(hdmi); + if (hdmi->hdmi_mode) { + msm_hdmi_config_avi_infoframe(hdmi); + msm_hdmi_audio_update(hdmi); + } } msm_hdmi_phy_powerup(phy, hdmi->pixclock); @@ -134,7 +196,8 @@ static void msm_hdmi_bridge_post_disable(struct drm_bridge *bridge) if (hdmi->power_on) { power_off(bridge); hdmi->power_on = false; - msm_hdmi_audio_update(hdmi); + if (hdmi->hdmi_mode) + msm_hdmi_audio_update(hdmi); msm_hdmi_phy_resource_disable(phy); } } @@ -196,7 +259,8 @@ static void msm_hdmi_bridge_mode_set(struct drm_bridge *bridge, DBG("frame_ctrl=%08x", frame_ctrl); hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl); - msm_hdmi_audio_update(hdmi); + if (hdmi->hdmi_mode) + msm_hdmi_audio_update(hdmi); } static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c index 143eab4..1fb7645 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c @@ -670,6 +670,11 @@ static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw *hw, static void hdmi_8996_pll_unprepare(struct clk_hw *hw) { + struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); + struct hdmi_phy *phy = pll_get_phy(pll); + + hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x6); + usleep_range(100, 150); } static int hdmi_8996_pll_is_enabled(struct clk_hw *hw) diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h index 1b996ed..da646de 100644 --- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h +++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) - -Copyright (C) 2013-2015 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h index 8803788..576cea3 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) - -Copyright (C) 2013-2015 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 698e514..615e1de 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -126,8 +126,9 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) struct mdp4_crtc *mdp4_crtc = container_of(work, struct mdp4_crtc, unref_cursor_work); struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base); + struct msm_kms *kms = &mdp4_kms->base.base; - msm_gem_put_iova(val, mdp4_kms->id); + msm_gem_put_iova(val, kms->aspace); drm_gem_object_unreference_unlocked(val); } @@ -360,6 +361,7 @@ static void update_cursor(struct drm_crtc *crtc) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); + struct msm_kms *kms = &mdp4_kms->base.base; enum mdp4_dma dma = mdp4_crtc->dma; unsigned long flags; @@ -372,7 +374,7 @@ static void update_cursor(struct drm_crtc *crtc) if (next_bo) { /* take a obj ref + iova ref when we start scanning out: */ drm_gem_object_reference(next_bo); - msm_gem_get_iova_locked(next_bo, mdp4_kms->id, &iova); + msm_gem_get_iova(next_bo, kms->aspace, &iova); /* enable cursor: */ mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma), @@ -409,6 +411,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); + struct msm_kms *kms = &mdp4_kms->base.base; struct drm_device *dev = crtc->dev; struct drm_gem_object *cursor_bo, *old_bo; unsigned long flags; @@ -429,7 +432,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, } if (cursor_bo) { - ret = msm_gem_get_iova(cursor_bo, mdp4_kms->id, &iova); + ret = msm_gem_get_iova(cursor_bo, kms->aspace, &iova); if (ret) goto fail; } else { diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 3d26d77..bcd1f5c 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -160,10 +160,10 @@ static void mdp4_destroy(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); struct device *dev = mdp4_kms->dev->dev; - struct msm_gem_address_space *aspace = mdp4_kms->aspace; + struct msm_gem_address_space *aspace = kms->aspace; if (mdp4_kms->blank_cursor_iova) - msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id); + msm_gem_put_iova(mdp4_kms->blank_cursor_bo, kms->aspace); drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo); if (aspace) { @@ -510,7 +510,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) goto fail; } - mdp4_kms->aspace = aspace; + kms->aspace = aspace; ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); @@ -522,22 +522,13 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) aspace = NULL; } - mdp4_kms->id = msm_register_address_space(dev, aspace); - if (mdp4_kms->id < 0) { - ret = mdp4_kms->id; - dev_err(dev->dev, "failed to register mdp4 iommu: %d\n", ret); - goto fail; - } - ret = modeset_init(mdp4_kms); if (ret) { dev_err(dev->dev, "modeset_init failed: %d\n", ret); goto fail; } - mutex_lock(&dev->struct_mutex); mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC); - mutex_unlock(&dev->struct_mutex); if (IS_ERR(mdp4_kms->blank_cursor_bo)) { ret = PTR_ERR(mdp4_kms->blank_cursor_bo); dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); @@ -545,7 +536,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) goto fail; } - ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id, + ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, kms->aspace, &mdp4_kms->blank_cursor_iova); if (ret) { dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index c413779..940de51 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -34,9 +34,6 @@ struct mdp4_kms { int rev; - /* mapper-id used to request GEM buffer mapped for scanout: */ - int id; - void __iomem *mmio; struct regulator *vdd; @@ -45,7 +42,6 @@ struct mdp4_kms { struct clk *pclk; struct clk *lut_clk; struct clk *axi_clk; - struct msm_gem_address_space *aspace; struct mdp_irq error_handler; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 53619d0..a20e3d6 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -103,13 +103,14 @@ static int mdp4_plane_prepare_fb(struct drm_plane *plane, { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); + struct msm_kms *kms = &mdp4_kms->base.base; struct drm_framebuffer *fb = new_state->fb; if (!fb) return 0; DBG("%s: prepare: FB[%u]", mdp4_plane->name, fb->base.id); - return msm_framebuffer_prepare(fb, mdp4_kms->id); + return msm_framebuffer_prepare(fb, kms->aspace); } static void mdp4_plane_cleanup_fb(struct drm_plane *plane, @@ -117,13 +118,14 @@ static void mdp4_plane_cleanup_fb(struct drm_plane *plane, { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); + struct msm_kms *kms = &mdp4_kms->base.base; struct drm_framebuffer *fb = old_state->fb; if (!fb) return; DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id); - msm_framebuffer_cleanup(fb, mdp4_kms->id); + msm_framebuffer_cleanup(fb, kms->aspace); } @@ -161,6 +163,7 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane, { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); + struct msm_kms *kms = &mdp4_kms->base.base; enum mdp4_pipe pipe = mdp4_plane->pipe; mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe), @@ -172,13 +175,13 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane, MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 0)); + msm_framebuffer_iova(fb, kms->aspace, 0)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP1_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 1)); + msm_framebuffer_iova(fb, kms->aspace, 1)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP2_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 2)); + msm_framebuffer_iova(fb, kms->aspace, 2)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 3)); + msm_framebuffer_iova(fb, kms->aspace, 3)); plane->fb = fb; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h index e6dfc51..d9c10e0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h @@ -8,9 +8,17 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /local/mnt/workspace/source_trees/envytools/rnndb/../rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-01-11 05:19:19) -- /local/mnt/workspace/source_trees/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-05-09 06:32:54) -- /local/mnt/workspace/source_trees/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2016-01-07 08:45:55) +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 0764a64..cb5415d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -160,8 +160,9 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) struct mdp5_crtc *mdp5_crtc = container_of(work, struct mdp5_crtc, unref_cursor_work); struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base); + struct msm_kms *kms = &mdp5_kms->base.base; - msm_gem_put_iova(val, mdp5_kms->id); + msm_gem_put_iova(val, kms->aspace); drm_gem_object_unreference_unlocked(val); } @@ -724,6 +725,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; struct drm_device *dev = crtc->dev; struct mdp5_kms *mdp5_kms = get_kms(crtc); + struct msm_kms *kms = &mdp5_kms->base.base; struct drm_gem_object *cursor_bo, *old_bo = NULL; uint32_t blendcfg, stride; uint64_t cursor_addr; @@ -758,7 +760,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, if (!cursor_bo) return -ENOENT; - ret = msm_gem_get_iova(cursor_bo, mdp5_kms->id, &cursor_addr); + ret = msm_gem_get_iova(cursor_bo, kms->aspace, &cursor_addr); if (ret) return -EINVAL; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index e2b3346..5d13fa5 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -163,7 +163,7 @@ static void mdp5_set_encoder_mode(struct msm_kms *kms, static void mdp5_kms_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - struct msm_gem_address_space *aspace = mdp5_kms->aspace; + struct msm_gem_address_space *aspace = kms->aspace; int i; for (i = 0; i < mdp5_kms->num_hwmixers; i++) @@ -663,7 +663,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) goto fail; } - mdp5_kms->aspace = aspace; + kms->aspace = aspace; ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); @@ -678,13 +678,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) aspace = NULL;; } - mdp5_kms->id = msm_register_address_space(dev, aspace); - if (mdp5_kms->id < 0) { - ret = mdp5_kms->id; - dev_err(&pdev->dev, "failed to register mdp5 iommu: %d\n", ret); - goto fail; - } - ret = modeset_init(mdp5_kms); if (ret) { dev_err(&pdev->dev, "modeset_init failed: %d\n", ret); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 8bdb7ee..17caa0e 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -55,10 +55,6 @@ struct mdp5_kms { struct mdp5_state *state; struct drm_modeset_lock state_lock; - /* mapper-id used to request GEM buffer mapped for scanout: */ - int id; - struct msm_gem_address_space *aspace; - struct mdp5_smp *smp; struct mdp5_ctl_manager *ctlm; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index abaaac7..fe3a4de 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -22,8 +22,6 @@ struct mdp5_plane { struct drm_plane base; - spinlock_t pipe_lock; /* protect REG_MDP5_PIPE_* registers */ - uint32_t nformats; uint32_t formats[32]; }; @@ -274,26 +272,28 @@ static int mdp5_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { struct mdp5_kms *mdp5_kms = get_kms(plane); + struct msm_kms *kms = &mdp5_kms->base.base; struct drm_framebuffer *fb = new_state->fb; if (!new_state->fb) return 0; DBG("%s: prepare: FB[%u]", plane->name, fb->base.id); - return msm_framebuffer_prepare(fb, mdp5_kms->id); + return msm_framebuffer_prepare(fb, kms->aspace); } static void mdp5_plane_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) { struct mdp5_kms *mdp5_kms = get_kms(plane); + struct msm_kms *kms = &mdp5_kms->base.base; struct drm_framebuffer *fb = old_state->fb; if (!fb) return; DBG("%s: cleanup: FB[%u]", plane->name, fb->base.id); - msm_framebuffer_cleanup(fb, mdp5_kms->id); + msm_framebuffer_cleanup(fb, kms->aspace); } #define FRAC_16_16(mult, div) (((mult) << 16) / (div)) @@ -500,6 +500,8 @@ static void set_scanout_locked(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe, struct drm_framebuffer *fb) { + struct msm_kms *kms = &mdp5_kms->base.base; + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_A(pipe), MDP5_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | MDP5_PIPE_SRC_STRIDE_A_P1(fb->pitches[1])); @@ -509,13 +511,13 @@ static void set_scanout_locked(struct mdp5_kms *mdp5_kms, MDP5_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 0)); + msm_framebuffer_iova(fb, kms->aspace, 0)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 1)); + msm_framebuffer_iova(fb, kms->aspace, 1)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 2)); + msm_framebuffer_iova(fb, kms->aspace, 2)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 3)); + msm_framebuffer_iova(fb, kms->aspace, 3)); } /* Note: mdp5_plane->pipe_lock must be locked */ @@ -881,7 +883,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_rect *src, struct drm_rect *dest) { - struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct drm_plane_state *pstate = plane->state; struct mdp5_hw_pipe *hwpipe = to_mdp5_plane_state(pstate)->hwpipe; struct mdp5_kms *mdp5_kms = get_kms(plane); @@ -902,7 +903,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, uint32_t src_img_w, src_img_h; uint32_t src_x_r; int crtc_x_r; - unsigned long flags; int ret; nplanes = fb->format->num_planes; @@ -981,8 +981,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, hflip = !!(rotation & DRM_MODE_REFLECT_X); vflip = !!(rotation & DRM_MODE_REFLECT_Y); - spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); - mdp5_hwpipe_mode_set(mdp5_kms, hwpipe, fb, &step, &pe, config, hdecm, vdecm, hflip, vflip, crtc_x, crtc_y, crtc_w, crtc_h, @@ -995,8 +993,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, src_img_w, src_img_h, src_x_r, src_y, src_w, src_h); - spin_unlock_irqrestore(&mdp5_plane->pipe_lock, flags); - plane->fb = fb; return ret; @@ -1139,8 +1135,6 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, mdp5_plane->nformats = mdp_get_formats(mdp5_plane->formats, ARRAY_SIZE(mdp5_plane->formats), false); - spin_lock_init(&mdp5_plane->pipe_lock); - if (type == DRM_PLANE_TYPE_CURSOR) ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_cursor_plane_funcs, diff --git a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h index 8994c36..1494c40 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) - -Copyright (C) 2013-2015 by the following authors: +- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2017-05-17 13:21:27) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41799 bytes, from 2017-06-16 12:32:42) +- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2017-05-17 13:21:27) + +Copyright (C) 2013-2017 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9d498eb..f49f6ac 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -51,19 +51,6 @@ static const struct drm_mode_config_funcs mode_config_funcs = { .atomic_state_free = msm_atomic_state_free, }; -int msm_register_address_space(struct drm_device *dev, - struct msm_gem_address_space *aspace) -{ - struct msm_drm_private *priv = dev->dev_private; - - if (WARN_ON(priv->num_aspaces >= ARRAY_SIZE(priv->aspace))) - return -EINVAL; - - priv->aspace[priv->num_aspaces] = aspace; - - return priv->num_aspaces++; -} - #ifdef CONFIG_DRM_MSM_REGISTER_LOGGING static bool reglog = false; MODULE_PARM_DESC(reglog, "Enable register read/write logging"); @@ -349,6 +336,7 @@ static int msm_init_vram(struct drm_device *dev) priv->vram.size = size; drm_mm_init(&priv->vram.mm, 0, (size >> PAGE_SHIFT) - 1); + spin_lock_init(&priv->vram.lock); attrs |= DMA_ATTR_NO_KERNEL_MAPPING; attrs |= DMA_ATTR_WRITE_COMBINE; @@ -699,6 +687,17 @@ static int msm_ioctl_gem_cpu_fini(struct drm_device *dev, void *data, return ret; } +static int msm_ioctl_gem_info_iova(struct drm_device *dev, + struct drm_gem_object *obj, uint64_t *iova) +{ + struct msm_drm_private *priv = dev->dev_private; + + if (!priv->gpu) + return -EINVAL; + + return msm_gem_get_iova(obj, priv->gpu->aspace, iova); +} + static int msm_ioctl_gem_info(struct drm_device *dev, void *data, struct drm_file *file) { @@ -706,14 +705,22 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, struct drm_gem_object *obj; int ret = 0; - if (args->pad) + if (args->flags & ~MSM_INFO_FLAGS) return -EINVAL; obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; - args->offset = msm_gem_mmap_offset(obj); + if (args->flags & MSM_INFO_IOVA) { + uint64_t iova; + + ret = msm_ioctl_gem_info_iova(dev, obj, &iova); + if (!ret) + args->offset = iova; + } else { + args->offset = msm_gem_mmap_offset(obj); + } drm_gem_object_unreference_unlocked(obj); @@ -842,7 +849,7 @@ static struct drm_driver msm_driver = { .debugfs_init = msm_debugfs_init, #endif .ioctls = msm_ioctls, - .num_ioctls = DRM_MSM_NUM_IOCTLS, + .num_ioctls = ARRAY_SIZE(msm_ioctls), .fops = &fops, .name = "msm", .desc = "MSM Snapdragon DRM", diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 1b26ca6..fc8d24f 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -123,14 +123,6 @@ struct msm_drm_private { uint32_t pending_crtcs; wait_queue_head_t pending_crtcs_event; - /* Registered address spaces.. currently this is fixed per # of - * iommu's. Ie. one for display block and one for gpu block. - * Eventually, to do per-process gpu pagetables, we'll want one - * of these per-process. - */ - unsigned int num_aspaces; - struct msm_gem_address_space *aspace[NUM_DOMAINS]; - unsigned int num_planes; struct drm_plane *planes[16]; @@ -157,6 +149,7 @@ struct msm_drm_private { * and position mm_node->start is in # of pages: */ struct drm_mm mm; + spinlock_t lock; /* Protects drm_mm node allocation/removal */ } vram; struct notifier_block vmap_notifier; @@ -183,9 +176,6 @@ struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev); void msm_atomic_state_clear(struct drm_atomic_state *state); void msm_atomic_state_free(struct drm_atomic_state *state); -int msm_register_address_space(struct drm_device *dev, - struct msm_gem_address_space *aspace); - void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, struct sg_table *sgt); int msm_gem_map_vma(struct msm_gem_address_space *aspace, @@ -209,13 +199,14 @@ int msm_gem_mmap_obj(struct drm_gem_object *obj, int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma); int msm_gem_fault(struct vm_fault *vmf); uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); -int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, - uint64_t *iova); -int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint64_t *iova); -uint64_t msm_gem_iova(struct drm_gem_object *obj, int id); +int msm_gem_get_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint64_t *iova); +uint64_t msm_gem_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace); struct page **msm_gem_get_pages(struct drm_gem_object *obj); void msm_gem_put_pages(struct drm_gem_object *obj); -void msm_gem_put_iova(struct drm_gem_object *obj, int id); +void msm_gem_put_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace); int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, @@ -229,13 +220,9 @@ struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg); int msm_gem_prime_pin(struct drm_gem_object *obj); void msm_gem_prime_unpin(struct drm_gem_object *obj); -void *msm_gem_get_vaddr_locked(struct drm_gem_object *obj); void *msm_gem_get_vaddr(struct drm_gem_object *obj); -void msm_gem_put_vaddr_locked(struct drm_gem_object *obj); void msm_gem_put_vaddr(struct drm_gem_object *obj); int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv); -void msm_gem_purge(struct drm_gem_object *obj); -void msm_gem_vunmap(struct drm_gem_object *obj); int msm_gem_sync_object(struct drm_gem_object *obj, struct msm_fence_context *fctx, bool exclusive); void msm_gem_move_to_active(struct drm_gem_object *obj, @@ -248,12 +235,17 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, uint32_t size, uint32_t flags, uint32_t *handle); struct drm_gem_object *msm_gem_new(struct drm_device *dev, uint32_t size, uint32_t flags); +struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev, + uint32_t size, uint32_t flags); struct drm_gem_object *msm_gem_import(struct drm_device *dev, struct dma_buf *dmabuf, struct sg_table *sgt); -int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id); -void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id); -uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane); +int msm_framebuffer_prepare(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace); +void msm_framebuffer_cleanup(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace); +uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace, int plane); struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane); const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb); struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index ba2733a..6ecb7b1 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -84,14 +84,15 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m) * should be fine, since only the scanout (mdpN) side of things needs * this, the gpu doesn't care about fb's. */ -int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id) +int msm_framebuffer_prepare(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); int ret, i, n = fb->format->num_planes; uint64_t iova; for (i = 0; i < n; i++) { - ret = msm_gem_get_iova(msm_fb->planes[i], id, &iova); + ret = msm_gem_get_iova(msm_fb->planes[i], aspace, &iova); DBG("FB[%u]: iova[%d]: %08llx (%d)", fb->base.id, i, iova, ret); if (ret) return ret; @@ -100,21 +101,23 @@ int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id) return 0; } -void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id) +void msm_framebuffer_cleanup(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); int i, n = fb->format->num_planes; for (i = 0; i < n; i++) - msm_gem_put_iova(msm_fb->planes[i], id); + msm_gem_put_iova(msm_fb->planes[i], aspace); } -uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane) +uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace, int plane) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); if (!msm_fb->planes[plane]) return 0; - return msm_gem_iova(msm_fb->planes[plane], id) + fb->offsets[plane]; + return msm_gem_iova(msm_fb->planes[plane], aspace) + fb->offsets[plane]; } struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane) diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index feea8ba..5ecf4ff 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -20,6 +20,7 @@ #include "msm_drv.h" #include "msm_gem.h" +#include "msm_kms.h" extern int msm_gem_mmap_obj(struct drm_gem_object *obj, struct vm_area_struct *vma); @@ -73,6 +74,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, { struct msm_fbdev *fbdev = to_msm_fbdev(helper); struct drm_device *dev = helper->dev; + struct msm_drm_private *priv = dev->dev_private; struct drm_framebuffer *fb = NULL; struct fb_info *fbi = NULL; struct drm_mode_fb_cmd2 mode_cmd = {0}; @@ -95,10 +97,8 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, /* allocate backing bo */ size = mode_cmd.pitches[0] * mode_cmd.height; DBG("allocating %d bytes for fb %d", size, dev->primary->index); - mutex_lock(&dev->struct_mutex); fbdev->bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN); - mutex_unlock(&dev->struct_mutex); if (IS_ERR(fbdev->bo)) { ret = PTR_ERR(fbdev->bo); fbdev->bo = NULL; @@ -124,7 +124,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, * in panic (ie. lock-safe, etc) we could avoid pinning the * buffer now: */ - ret = msm_gem_get_iova_locked(fbdev->bo, 0, &paddr); + ret = msm_gem_get_iova(fbdev->bo, priv->kms->aspace, &paddr); if (ret) { dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret); goto fail_unlock; @@ -153,7 +153,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, dev->mode_config.fb_base = paddr; - fbi->screen_base = msm_gem_get_vaddr_locked(fbdev->bo); + fbi->screen_base = msm_gem_get_vaddr(fbdev->bo); if (IS_ERR(fbi->screen_base)) { ret = PTR_ERR(fbi->screen_base); goto fail_unlock; diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index be77a35..65f3554 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -26,6 +26,9 @@ #include "msm_gpu.h" #include "msm_mmu.h" +static void msm_gem_vunmap_locked(struct drm_gem_object *obj); + + static dma_addr_t physaddr(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); @@ -41,8 +44,7 @@ static bool use_pages(struct drm_gem_object *obj) } /* allocate pages from VRAM carveout, used when no IOMMU: */ -static struct page **get_pages_vram(struct drm_gem_object *obj, - int npages) +static struct page **get_pages_vram(struct drm_gem_object *obj, int npages) { struct msm_gem_object *msm_obj = to_msm_bo(obj); struct msm_drm_private *priv = obj->dev->dev_private; @@ -54,7 +56,9 @@ static struct page **get_pages_vram(struct drm_gem_object *obj, if (!p) return ERR_PTR(-ENOMEM); + spin_lock(&priv->vram.lock); ret = drm_mm_insert_node(&priv->vram.mm, msm_obj->vram_node, npages); + spin_unlock(&priv->vram.lock); if (ret) { kvfree(p); return ERR_PTR(ret); @@ -69,7 +73,6 @@ static struct page **get_pages_vram(struct drm_gem_object *obj, return p; } -/* called with dev->struct_mutex held */ static struct page **get_pages(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); @@ -109,6 +112,18 @@ static struct page **get_pages(struct drm_gem_object *obj) return msm_obj->pages; } +static void put_pages_vram(struct drm_gem_object *obj) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_drm_private *priv = obj->dev->dev_private; + + spin_lock(&priv->vram.lock); + drm_mm_remove_node(msm_obj->vram_node); + spin_unlock(&priv->vram.lock); + + kvfree(msm_obj->pages); +} + static void put_pages(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); @@ -125,10 +140,8 @@ static void put_pages(struct drm_gem_object *obj) if (use_pages(obj)) drm_gem_put_pages(obj, msm_obj->pages, true, false); - else { - drm_mm_remove_node(msm_obj->vram_node); - kvfree(msm_obj->pages); - } + else + put_pages_vram(obj); msm_obj->pages = NULL; } @@ -136,11 +149,18 @@ static void put_pages(struct drm_gem_object *obj) struct page **msm_gem_get_pages(struct drm_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct msm_gem_object *msm_obj = to_msm_bo(obj); struct page **p; - mutex_lock(&dev->struct_mutex); + + mutex_lock(&msm_obj->lock); + + if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) { + mutex_unlock(&msm_obj->lock); + return ERR_PTR(-EBUSY); + } + p = get_pages(obj); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&msm_obj->lock); return p; } @@ -195,28 +215,25 @@ int msm_gem_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct drm_gem_object *obj = vma->vm_private_data; - struct drm_device *dev = obj->dev; - struct msm_drm_private *priv = dev->dev_private; + struct msm_gem_object *msm_obj = to_msm_bo(obj); struct page **pages; unsigned long pfn; pgoff_t pgoff; int ret; - /* This should only happen if userspace tries to pass a mmap'd - * but unfaulted gem bo vaddr into submit ioctl, triggering - * a page fault while struct_mutex is already held. This is - * not a valid use-case so just bail. - */ - if (priv->struct_mutex_task == current) - return VM_FAULT_SIGBUS; - - /* Make sure we don't parallel update on a fault, nor move or remove - * something from beneath our feet + /* + * vm_ops.open/drm_gem_mmap_obj and close get and put + * a reference on obj. So, we dont need to hold one here. */ - ret = mutex_lock_interruptible(&dev->struct_mutex); + ret = mutex_lock_interruptible(&msm_obj->lock); if (ret) goto out; + if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) { + mutex_unlock(&msm_obj->lock); + return VM_FAULT_SIGBUS; + } + /* make sure we have pages attached now */ pages = get_pages(obj); if (IS_ERR(pages)) { @@ -235,7 +252,7 @@ int msm_gem_fault(struct vm_fault *vmf) ret = vm_insert_mixed(vma, vmf->address, __pfn_to_pfn_t(pfn, PFN_DEV)); out_unlock: - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&msm_obj->lock); out: switch (ret) { case -EAGAIN: @@ -259,9 +276,10 @@ out: static uint64_t mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; + struct msm_gem_object *msm_obj = to_msm_bo(obj); int ret; - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&msm_obj->lock)); /* Make it mmapable */ ret = drm_gem_create_mmap_offset(obj); @@ -277,95 +295,140 @@ static uint64_t mmap_offset(struct drm_gem_object *obj) uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj) { uint64_t offset; - mutex_lock(&obj->dev->struct_mutex); + struct msm_gem_object *msm_obj = to_msm_bo(obj); + + mutex_lock(&msm_obj->lock); offset = mmap_offset(obj); - mutex_unlock(&obj->dev->struct_mutex); + mutex_unlock(&msm_obj->lock); return offset; } -static void -put_iova(struct drm_gem_object *obj) +static struct msm_gem_vma *add_vma(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) { - struct drm_device *dev = obj->dev; - struct msm_drm_private *priv = obj->dev->dev_private; struct msm_gem_object *msm_obj = to_msm_bo(obj); - int id; + struct msm_gem_vma *vma; - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&msm_obj->lock)); - for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) { - if (!priv->aspace[id]) - continue; - msm_gem_unmap_vma(priv->aspace[id], - &msm_obj->domain[id], msm_obj->sgt); - } + vma = kzalloc(sizeof(*vma), GFP_KERNEL); + if (!vma) + return ERR_PTR(-ENOMEM); + + vma->aspace = aspace; + + list_add_tail(&vma->list, &msm_obj->vmas); + + return vma; } -/* should be called under struct_mutex.. although it can be called - * from atomic context without struct_mutex to acquire an extra - * iova ref if you know one is already held. - * - * That means when I do eventually need to add support for unpinning - * the refcnt counter needs to be atomic_t. - */ -int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, - uint64_t *iova) +static struct msm_gem_vma *lookup_vma(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) { struct msm_gem_object *msm_obj = to_msm_bo(obj); - int ret = 0; + struct msm_gem_vma *vma; - if (!msm_obj->domain[id].iova) { - struct msm_drm_private *priv = obj->dev->dev_private; - struct page **pages = get_pages(obj); + WARN_ON(!mutex_is_locked(&msm_obj->lock)); - if (IS_ERR(pages)) - return PTR_ERR(pages); - - if (iommu_present(&platform_bus_type)) { - ret = msm_gem_map_vma(priv->aspace[id], &msm_obj->domain[id], - msm_obj->sgt, obj->size >> PAGE_SHIFT); - } else { - msm_obj->domain[id].iova = physaddr(obj); - } + list_for_each_entry(vma, &msm_obj->vmas, list) { + if (vma->aspace == aspace) + return vma; } - if (!ret) - *iova = msm_obj->domain[id].iova; + return NULL; +} - return ret; +static void del_vma(struct msm_gem_vma *vma) +{ + if (!vma) + return; + + list_del(&vma->list); + kfree(vma); +} + +/* Called with msm_obj->lock locked */ +static void +put_iova(struct drm_gem_object *obj) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *vma, *tmp; + + WARN_ON(!mutex_is_locked(&msm_obj->lock)); + + list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) { + msm_gem_unmap_vma(vma->aspace, vma, msm_obj->sgt); + del_vma(vma); + } } /* get iova, taking a reference. Should have a matching put */ -int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint64_t *iova) +int msm_gem_get_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint64_t *iova) { struct msm_gem_object *msm_obj = to_msm_bo(obj); - int ret; + struct msm_gem_vma *vma; + int ret = 0; - /* this is safe right now because we don't unmap until the - * bo is deleted: - */ - if (msm_obj->domain[id].iova) { - *iova = msm_obj->domain[id].iova; - return 0; + mutex_lock(&msm_obj->lock); + + if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) { + mutex_unlock(&msm_obj->lock); + return -EBUSY; } - mutex_lock(&obj->dev->struct_mutex); - ret = msm_gem_get_iova_locked(obj, id, iova); - mutex_unlock(&obj->dev->struct_mutex); + vma = lookup_vma(obj, aspace); + + if (!vma) { + struct page **pages; + + vma = add_vma(obj, aspace); + if (IS_ERR(vma)) + return PTR_ERR(vma); + + pages = get_pages(obj); + if (IS_ERR(pages)) { + ret = PTR_ERR(pages); + goto fail; + } + + ret = msm_gem_map_vma(aspace, vma, msm_obj->sgt, + obj->size >> PAGE_SHIFT); + if (ret) + goto fail; + } + + *iova = vma->iova; + + mutex_unlock(&msm_obj->lock); + return 0; + +fail: + del_vma(vma); + + mutex_unlock(&msm_obj->lock); return ret; } /* get iova without taking a reference, used in places where you have * already done a 'msm_gem_get_iova()'. */ -uint64_t msm_gem_iova(struct drm_gem_object *obj, int id) +uint64_t msm_gem_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) { struct msm_gem_object *msm_obj = to_msm_bo(obj); - WARN_ON(!msm_obj->domain[id].iova); - return msm_obj->domain[id].iova; + struct msm_gem_vma *vma; + + mutex_lock(&msm_obj->lock); + vma = lookup_vma(obj, aspace); + mutex_unlock(&msm_obj->lock); + WARN_ON(!vma); + + return vma ? vma->iova : 0; } -void msm_gem_put_iova(struct drm_gem_object *obj, int id) +void msm_gem_put_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) { // XXX TODO .. // NOTE: probably don't need a _locked() version.. we wouldn't @@ -405,45 +468,57 @@ fail: return ret; } -void *msm_gem_get_vaddr_locked(struct drm_gem_object *obj) +void *msm_gem_get_vaddr(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); - WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); + int ret = 0; + + mutex_lock(&msm_obj->lock); + + if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) { + mutex_unlock(&msm_obj->lock); + return ERR_PTR(-EBUSY); + } + + /* increment vmap_count *before* vmap() call, so shrinker can + * check vmap_count (is_vunmapable()) outside of msm_obj->lock. + * This guarantees that we won't try to msm_gem_vunmap() this + * same object from within the vmap() call (while we already + * hold msm_obj->lock) + */ + msm_obj->vmap_count++; + if (!msm_obj->vaddr) { struct page **pages = get_pages(obj); - if (IS_ERR(pages)) - return ERR_CAST(pages); + if (IS_ERR(pages)) { + ret = PTR_ERR(pages); + goto fail; + } msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); - if (msm_obj->vaddr == NULL) - return ERR_PTR(-ENOMEM); + if (msm_obj->vaddr == NULL) { + ret = -ENOMEM; + goto fail; + } } - msm_obj->vmap_count++; + + mutex_unlock(&msm_obj->lock); return msm_obj->vaddr; -} -void *msm_gem_get_vaddr(struct drm_gem_object *obj) -{ - void *ret; - mutex_lock(&obj->dev->struct_mutex); - ret = msm_gem_get_vaddr_locked(obj); - mutex_unlock(&obj->dev->struct_mutex); - return ret; +fail: + msm_obj->vmap_count--; + mutex_unlock(&msm_obj->lock); + return ERR_PTR(ret); } -void msm_gem_put_vaddr_locked(struct drm_gem_object *obj) +void msm_gem_put_vaddr(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); - WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); + + mutex_lock(&msm_obj->lock); WARN_ON(msm_obj->vmap_count < 1); msm_obj->vmap_count--; -} - -void msm_gem_put_vaddr(struct drm_gem_object *obj) -{ - mutex_lock(&obj->dev->struct_mutex); - msm_gem_put_vaddr_locked(obj); - mutex_unlock(&obj->dev->struct_mutex); + mutex_unlock(&msm_obj->lock); } /* Update madvise status, returns true if not purged, else @@ -453,15 +528,21 @@ int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv) { struct msm_gem_object *msm_obj = to_msm_bo(obj); + mutex_lock(&msm_obj->lock); + WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); if (msm_obj->madv != __MSM_MADV_PURGED) msm_obj->madv = madv; - return (msm_obj->madv != __MSM_MADV_PURGED); + madv = msm_obj->madv; + + mutex_unlock(&msm_obj->lock); + + return (madv != __MSM_MADV_PURGED); } -void msm_gem_purge(struct drm_gem_object *obj) +void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass) { struct drm_device *dev = obj->dev; struct msm_gem_object *msm_obj = to_msm_bo(obj); @@ -470,9 +551,11 @@ void msm_gem_purge(struct drm_gem_object *obj) WARN_ON(!is_purgeable(msm_obj)); WARN_ON(obj->import_attach); + mutex_lock_nested(&msm_obj->lock, subclass); + put_iova(obj); - msm_gem_vunmap(obj); + msm_gem_vunmap_locked(obj); put_pages(obj); @@ -490,12 +573,16 @@ void msm_gem_purge(struct drm_gem_object *obj) invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); + + mutex_unlock(&msm_obj->lock); } -void msm_gem_vunmap(struct drm_gem_object *obj) +static void msm_gem_vunmap_locked(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); + WARN_ON(!mutex_is_locked(&msm_obj->lock)); + if (!msm_obj->vaddr || WARN_ON(!is_vunmapable(msm_obj))) return; @@ -503,6 +590,15 @@ void msm_gem_vunmap(struct drm_gem_object *obj) msm_obj->vaddr = NULL; } +void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + + mutex_lock_nested(&msm_obj->lock, subclass); + msm_gem_vunmap_locked(obj); + mutex_unlock(&msm_obj->lock); +} + /* must be called before _move_to_active().. */ int msm_gem_sync_object(struct drm_gem_object *obj, struct msm_fence_context *fctx, bool exclusive) @@ -619,13 +715,12 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) struct msm_gem_object *msm_obj = to_msm_bo(obj); struct reservation_object *robj = msm_obj->resv; struct reservation_object_list *fobj; - struct msm_drm_private *priv = obj->dev->dev_private; struct dma_fence *fence; + struct msm_gem_vma *vma; uint64_t off = drm_vma_node_start(&obj->vma_node); const char *madv; - unsigned id; - WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); + mutex_lock(&msm_obj->lock); switch (msm_obj->madv) { case __MSM_MADV_PURGED: @@ -645,8 +740,9 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) obj->name, kref_read(&obj->refcount), off, msm_obj->vaddr); - for (id = 0; id < priv->num_aspaces; id++) - seq_printf(m, " %08llx", msm_obj->domain[id].iova); + /* FIXME: we need to print the address space here too */ + list_for_each_entry(vma, &msm_obj->vmas, list) + seq_printf(m, " %08llx", vma->iova); seq_printf(m, " %zu%s\n", obj->size, madv); @@ -665,6 +761,8 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) if (fence) describe_fence(fence, "Exclusive", m); rcu_read_unlock(); + + mutex_unlock(&msm_obj->lock); } void msm_gem_describe_objects(struct list_head *list, struct seq_file *m) @@ -697,6 +795,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) list_del(&msm_obj->mm_list); + mutex_lock(&msm_obj->lock); + put_iova(obj); if (obj->import_attach) { @@ -711,7 +811,7 @@ void msm_gem_free_object(struct drm_gem_object *obj) drm_prime_gem_destroy(obj, msm_obj->sgt); } else { - msm_gem_vunmap(obj); + msm_gem_vunmap_locked(obj); put_pages(obj); } @@ -720,6 +820,7 @@ void msm_gem_free_object(struct drm_gem_object *obj) drm_gem_object_release(obj); + mutex_unlock(&msm_obj->lock); kfree(msm_obj); } @@ -730,14 +831,8 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, struct drm_gem_object *obj; int ret; - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - obj = msm_gem_new(dev, size, flags); - mutex_unlock(&dev->struct_mutex); - if (IS_ERR(obj)) return PTR_ERR(obj); @@ -752,13 +847,11 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, static int msm_gem_new_impl(struct drm_device *dev, uint32_t size, uint32_t flags, struct reservation_object *resv, - struct drm_gem_object **obj) + struct drm_gem_object **obj, + bool struct_mutex_locked) { struct msm_drm_private *priv = dev->dev_private; struct msm_gem_object *msm_obj; - bool use_vram = false; - - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); switch (flags & MSM_BO_CACHE_MASK) { case MSM_BO_UNCACHED: @@ -771,20 +864,11 @@ static int msm_gem_new_impl(struct drm_device *dev, return -EINVAL; } - if (!iommu_present(&platform_bus_type)) - use_vram = true; - else if ((flags & MSM_BO_STOLEN) && priv->vram.size) - use_vram = true; - - if (WARN_ON(use_vram && !priv->vram.size)) - return -EINVAL; - msm_obj = kzalloc(sizeof(*msm_obj), GFP_KERNEL); if (!msm_obj) return -ENOMEM; - if (use_vram) - msm_obj->vram_node = &msm_obj->domain[0].node; + mutex_init(&msm_obj->lock); msm_obj->flags = flags; msm_obj->madv = MSM_MADV_WILLNEED; @@ -797,48 +881,96 @@ static int msm_gem_new_impl(struct drm_device *dev, } INIT_LIST_HEAD(&msm_obj->submit_entry); - list_add_tail(&msm_obj->mm_list, &priv->inactive_list); + INIT_LIST_HEAD(&msm_obj->vmas); + + if (struct_mutex_locked) { + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + list_add_tail(&msm_obj->mm_list, &priv->inactive_list); + } else { + mutex_lock(&dev->struct_mutex); + list_add_tail(&msm_obj->mm_list, &priv->inactive_list); + mutex_unlock(&dev->struct_mutex); + } *obj = &msm_obj->base; return 0; } -struct drm_gem_object *msm_gem_new(struct drm_device *dev, - uint32_t size, uint32_t flags) +static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, + uint32_t size, uint32_t flags, bool struct_mutex_locked) { + struct msm_drm_private *priv = dev->dev_private; struct drm_gem_object *obj = NULL; + bool use_vram = false; int ret; - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - size = PAGE_ALIGN(size); + if (!iommu_present(&platform_bus_type)) + use_vram = true; + else if ((flags & MSM_BO_STOLEN) && priv->vram.size) + use_vram = true; + + if (WARN_ON(use_vram && !priv->vram.size)) + return ERR_PTR(-EINVAL); + /* Disallow zero sized objects as they make the underlying * infrastructure grumpy */ if (size == 0) return ERR_PTR(-EINVAL); - ret = msm_gem_new_impl(dev, size, flags, NULL, &obj); + ret = msm_gem_new_impl(dev, size, flags, NULL, &obj, struct_mutex_locked); if (ret) goto fail; - if (use_pages(obj)) { + if (use_vram) { + struct msm_gem_vma *vma; + struct page **pages; + + vma = add_vma(obj, NULL); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto fail; + } + + to_msm_bo(obj)->vram_node = &vma->node; + + drm_gem_private_object_init(dev, obj, size); + + pages = get_pages(obj); + if (IS_ERR(pages)) { + ret = PTR_ERR(pages); + goto fail; + } + + vma->iova = physaddr(obj); + } else { ret = drm_gem_object_init(dev, obj, size); if (ret) goto fail; - } else { - drm_gem_private_object_init(dev, obj, size); } return obj; fail: - drm_gem_object_unreference(obj); + drm_gem_object_unreference_unlocked(obj); return ERR_PTR(ret); } +struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev, + uint32_t size, uint32_t flags) +{ + return _msm_gem_new(dev, size, flags, true); +} + +struct drm_gem_object *msm_gem_new(struct drm_device *dev, + uint32_t size, uint32_t flags) +{ + return _msm_gem_new(dev, size, flags, false); +} + struct drm_gem_object *msm_gem_import(struct drm_device *dev, struct dma_buf *dmabuf, struct sg_table *sgt) { @@ -855,11 +987,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, size = PAGE_ALIGN(dmabuf->size); - /* Take mutex so we can modify the inactive list in msm_gem_new_impl */ - mutex_lock(&dev->struct_mutex); - ret = msm_gem_new_impl(dev, size, MSM_BO_WC, dmabuf->resv, &obj); - mutex_unlock(&dev->struct_mutex); - + ret = msm_gem_new_impl(dev, size, MSM_BO_WC, dmabuf->resv, &obj, false); if (ret) goto fail; @@ -868,17 +996,22 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, npages = size / PAGE_SIZE; msm_obj = to_msm_bo(obj); + mutex_lock(&msm_obj->lock); msm_obj->sgt = sgt; msm_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!msm_obj->pages) { + mutex_unlock(&msm_obj->lock); ret = -ENOMEM; goto fail; } ret = drm_prime_sg_to_page_addr_arrays(sgt, msm_obj->pages, NULL, npages); - if (ret) + if (ret) { + mutex_unlock(&msm_obj->lock); goto fail; + } + mutex_unlock(&msm_obj->lock); return obj; fail: diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 1b4cf20..91c210d 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -31,6 +31,7 @@ struct msm_gem_address_space { * and position mm_node->start is in # of pages: */ struct drm_mm mm; + spinlock_t lock; /* Protects drm_mm node allocation/removal */ struct msm_mmu *mmu; struct kref kref; }; @@ -38,6 +39,8 @@ struct msm_gem_address_space { struct msm_gem_vma { struct drm_mm_node node; uint64_t iova; + struct msm_gem_address_space *aspace; + struct list_head list; /* node in msm_gem_object::vmas */ }; struct msm_gem_object { @@ -77,7 +80,7 @@ struct msm_gem_object { struct sg_table *sgt; void *vaddr; - struct msm_gem_vma domain[NUM_DOMAINS]; + struct list_head vmas; /* list of msm_gem_vma */ /* normally (resv == &_resv) except for imported bo's */ struct reservation_object *resv; @@ -87,6 +90,7 @@ struct msm_gem_object { * an IOMMU. Also used for stolen/splashscreen buffer. */ struct drm_mm_node *vram_node; + struct mutex lock; /* Protects resources associated with bo */ }; #define to_msm_bo(x) container_of(x, struct msm_gem_object, base) @@ -97,6 +101,7 @@ static inline bool is_active(struct msm_gem_object *msm_obj) static inline bool is_purgeable(struct msm_gem_object *msm_obj) { + WARN_ON(!mutex_is_locked(&msm_obj->base.dev->struct_mutex)); return (msm_obj->madv == MSM_MADV_DONTNEED) && msm_obj->sgt && !msm_obj->base.dma_buf && !msm_obj->base.import_attach; } @@ -106,6 +111,25 @@ static inline bool is_vunmapable(struct msm_gem_object *msm_obj) return (msm_obj->vmap_count == 0) && msm_obj->vaddr; } +/* The shrinker can be triggered while we hold objA->lock, and need + * to grab objB->lock to purge it. Lockdep just sees these as a single + * class of lock, so we use subclasses to teach it the difference. + * + * OBJ_LOCK_NORMAL is implicit (ie. normal mutex_lock() call), and + * OBJ_LOCK_SHRINKER is used by shrinker. + * + * It is *essential* that we never go down paths that could trigger the + * shrinker for a purgable object. This is ensured by checking that + * msm_obj->madv == MSM_MADV_WILLNEED. + */ +enum msm_gem_lock { + OBJ_LOCK_NORMAL, + OBJ_LOCK_SHRINKER, +}; + +void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass); +void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass); + /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, * associated with the cmdstream submission for synchronization (and * make it easier to unwind when things go wrong, etc). This only diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c b/drivers/gpu/drm/msm/msm_gem_shrinker.c index ab1dd02..b72d8e6 100644 --- a/drivers/gpu/drm/msm/msm_gem_shrinker.c +++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c @@ -20,6 +20,18 @@ static bool msm_gem_shrinker_lock(struct drm_device *dev, bool *unlock) { + /* NOTE: we are *closer* to being able to get rid of + * mutex_trylock_recursive().. the msm_gem code itself does + * not need struct_mutex, although codepaths that can trigger + * shrinker are still called in code-paths that hold the + * struct_mutex. + * + * Also, msm_obj->madv is protected by struct_mutex. + * + * The next step is probably split out a seperate lock for + * protecting inactive_list, so that shrinker does not need + * struct_mutex. + */ switch (mutex_trylock_recursive(&dev->struct_mutex)) { case MUTEX_TRYLOCK_FAILED: return false; @@ -77,7 +89,7 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) if (freed >= sc->nr_to_scan) break; if (is_purgeable(msm_obj)) { - msm_gem_purge(&msm_obj->base); + msm_gem_purge(&msm_obj->base, OBJ_LOCK_SHRINKER); freed += msm_obj->base.size >> PAGE_SHIFT; } } @@ -106,7 +118,7 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr) list_for_each_entry(msm_obj, &priv->inactive_list, mm_list) { if (is_vunmapable(msm_obj)) { - msm_gem_vunmap(&msm_obj->base); + msm_gem_vunmap(&msm_obj->base, OBJ_LOCK_SHRINKER); /* since we don't know any better, lets bail after a few * and if necessary the shrinker will be invoked again. * Seems better than unmapping *everything* diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 7832e64..6bfca74 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -31,11 +31,14 @@ #define BO_PINNED 0x2000 static struct msm_gem_submit *submit_create(struct drm_device *dev, - struct msm_gpu *gpu, int nr_bos, int nr_cmds) + struct msm_gpu *gpu, uint32_t nr_bos, uint32_t nr_cmds) { struct msm_gem_submit *submit; - int sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) + - (nr_cmds * sizeof(*submit->cmd)); + uint64_t sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) + + (nr_cmds * sizeof(submit->cmd[0])); + + if (sz > SIZE_MAX) + return NULL; submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); if (!submit) @@ -158,7 +161,7 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i) struct msm_gem_object *msm_obj = submit->bos[i].obj; if (submit->bos[i].flags & BO_PINNED) - msm_gem_put_iova(&msm_obj->base, submit->gpu->id); + msm_gem_put_iova(&msm_obj->base, submit->gpu->aspace); if (submit->bos[i].flags & BO_LOCKED) ww_mutex_unlock(&msm_obj->resv->lock); @@ -245,8 +248,8 @@ static int submit_pin_objects(struct msm_gem_submit *submit) uint64_t iova; /* if locking succeeded, pin bo: */ - ret = msm_gem_get_iova_locked(&msm_obj->base, - submit->gpu->id, &iova); + ret = msm_gem_get_iova(&msm_obj->base, + submit->gpu->aspace, &iova); if (ret) break; @@ -301,7 +304,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob /* For now, just map the entire thing. Eventually we probably * to do it page-by-page, w/ kmap() if not vmap()d.. */ - ptr = msm_gem_get_vaddr_locked(&obj->base); + ptr = msm_gem_get_vaddr(&obj->base); if (IS_ERR(ptr)) { ret = PTR_ERR(ptr); @@ -359,7 +362,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob } out: - msm_gem_put_vaddr_locked(&obj->base); + msm_gem_put_vaddr(&obj->base); return ret; } diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index f285d7e..c36321bc 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -50,7 +50,9 @@ msm_gem_unmap_vma(struct msm_gem_address_space *aspace, aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt, size); } + spin_lock(&aspace->lock); drm_mm_remove_node(&vma->node); + spin_unlock(&aspace->lock); vma->iova = 0; @@ -63,10 +65,15 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, { int ret; - if (WARN_ON(drm_mm_node_allocated(&vma->node))) + spin_lock(&aspace->lock); + if (WARN_ON(drm_mm_node_allocated(&vma->node))) { + spin_unlock(&aspace->lock); return 0; + } ret = drm_mm_insert_node(&aspace->mm, &vma->node, npages); + spin_unlock(&aspace->lock); + if (ret) return ret; @@ -94,6 +101,7 @@ msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, if (!aspace) return ERR_PTR(-ENOMEM); + spin_lock_init(&aspace->lock); aspace->name = name; aspace->mmu = msm_iommu_new(dev, domain); diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 0fdc88d..9f3dbc2 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -203,6 +203,8 @@ int msm_gpu_hw_init(struct msm_gpu *gpu) { int ret; + WARN_ON(!mutex_is_locked(&gpu->dev->struct_mutex)); + if (!gpu->needs_hw_init) return 0; @@ -414,7 +416,7 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) struct msm_gem_object *msm_obj = submit->bos[i].obj; /* move to inactive: */ msm_gem_move_to_inactive(&msm_obj->base); - msm_gem_put_iova(&msm_obj->base, gpu->id); + msm_gem_put_iova(&msm_obj->base, gpu->aspace); drm_gem_object_unreference(&msm_obj->base); } @@ -495,8 +497,8 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, /* submit takes a reference to the bo and iova until retired: */ drm_gem_object_reference(&msm_obj->base); - msm_gem_get_iova_locked(&msm_obj->base, - submit->gpu->id, &iova); + msm_gem_get_iova(&msm_obj->base, + submit->gpu->aspace, &iova); if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE) msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence); @@ -562,7 +564,7 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu) int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, - const char *name, const char *ioname, const char *irqname, int ringsz) + const char *name, struct msm_gpu_config *config) { struct iommu_domain *iommu; int ret; @@ -593,14 +595,14 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, /* Map registers: */ - gpu->mmio = msm_ioremap(pdev, ioname, name); + gpu->mmio = msm_ioremap(pdev, config->ioname, name); if (IS_ERR(gpu->mmio)) { ret = PTR_ERR(gpu->mmio); goto fail; } /* Get Interrupt: */ - gpu->irq = platform_get_irq_byname(pdev, irqname); + gpu->irq = platform_get_irq_byname(pdev, config->irqname); if (gpu->irq < 0) { ret = gpu->irq; dev_err(drm->dev, "failed to get irq: %d\n", ret); @@ -640,9 +642,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, */ iommu = iommu_domain_alloc(&platform_bus_type); if (iommu) { - /* TODO 32b vs 64b address space.. */ - iommu->geometry.aperture_start = SZ_16M; - iommu->geometry.aperture_end = 0xffffffff; + iommu->geometry.aperture_start = config->va_start; + iommu->geometry.aperture_end = config->va_end; dev_info(drm->dev, "%s: using IOMMU\n", name); gpu->aspace = msm_gem_address_space_create(&pdev->dev, @@ -658,13 +659,9 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, } else { dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name); } - gpu->id = msm_register_address_space(drm, gpu->aspace); - /* Create ringbuffer: */ - mutex_lock(&drm->struct_mutex); - gpu->rb = msm_ringbuffer_new(gpu, ringsz); - mutex_unlock(&drm->struct_mutex); + gpu->rb = msm_ringbuffer_new(gpu, config->ringsz); if (IS_ERR(gpu->rb)) { ret = PTR_ERR(gpu->rb); gpu->rb = NULL; @@ -693,7 +690,7 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) if (gpu->rb) { if (gpu->rb_iova) - msm_gem_put_iova(gpu->rb->bo, gpu->id); + msm_gem_put_iova(gpu->rb->bo, gpu->aspace); msm_ringbuffer_destroy(gpu->rb); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index aa32410..df4e277 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -28,6 +28,14 @@ struct msm_gem_submit; struct msm_gpu_perfcntr; +struct msm_gpu_config { + const char *ioname; + const char *irqname; + uint64_t va_start; + uint64_t va_end; + unsigned int ringsz; +}; + /* So far, with hardware that I've seen to date, we can have: * + zero, one, or two z180 2d cores * + a3xx or a2xx 3d core, which share a common CP (the firmware @@ -50,7 +58,6 @@ struct msm_gpu_funcs { void (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx); void (*flush)(struct msm_gpu *gpu); - bool (*idle)(struct msm_gpu *gpu); irqreturn_t (*irq)(struct msm_gpu *irq); uint32_t (*last_fence)(struct msm_gpu *gpu); void (*recover)(struct msm_gpu *gpu); @@ -99,7 +106,6 @@ struct msm_gpu { int irq; struct msm_gem_address_space *aspace; - int id; /* Power Control: */ struct regulator *gpu_reg, *gpu_cx; @@ -209,7 +215,8 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, - const char *name, const char *ioname, const char *irqname, int ringsz); + const char *name, struct msm_gpu_config *config); + void msm_gpu_cleanup(struct msm_gpu *gpu); struct msm_gpu *adreno_load_gpu(struct drm_device *dev); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index faa22c7..a8f2ba5 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -72,6 +72,9 @@ struct msm_kms { /* irq number to be passed on to drm_irq_install */ int irq; + + /* mapper-id used to request GEM buffer mapped for scanout: */ + struct msm_gem_address_space *aspace; }; /** diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 0e81faa..0366b80 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -268,7 +268,7 @@ static void snapshot_buf(struct msm_rd_state *rd, struct msm_gem_object *obj = submit->bos[idx].obj; const char *buf; - buf = msm_gem_get_vaddr_locked(&obj->base); + buf = msm_gem_get_vaddr(&obj->base); if (IS_ERR(buf)) return; @@ -283,7 +283,7 @@ static void snapshot_buf(struct msm_rd_state *rd, (uint32_t[3]){ iova, size, iova >> 32 }, 12); rd_write_section(rd, RD_BUFFER_CONTENTS, buf, size); - msm_gem_put_vaddr_locked(&obj->base); + msm_gem_put_vaddr(&obj->base); } /* called under struct_mutex */ diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 67b34e0..791bca3 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -40,7 +40,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) goto fail; } - ring->start = msm_gem_get_vaddr_locked(ring->bo); + ring->start = msm_gem_get_vaddr(ring->bo); if (IS_ERR(ring->start)) { ret = PTR_ERR(ring->start); goto fail; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 432480f..3178ba0 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -3393,6 +3393,13 @@ void radeon_combios_asic_init(struct drm_device *dev) rdev->pdev->subsystem_vendor == 0x103c && rdev->pdev->subsystem_device == 0x280a) return; + /* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume + * - it hangs on resume inside the dynclk 1 table. + */ + if (rdev->family == CHIP_RS400 && + rdev->pdev->subsystem_vendor == 0x1179 && + rdev->pdev->subsystem_device == 0xff31) + return; /* DYN CLK 1 */ table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 6ecf427..0a6444d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -136,6 +136,10 @@ static struct radeon_px_quirk radeon_px_quirk_list[] = { * https://bugzilla.kernel.org/show_bug.cgi?id=51381 */ { PCI_VENDOR_ID_ATI, 0x6840, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX }, + /* Asus K53TK laptop with AMD A6-3420M APU and Radeon 7670m GPU + * https://bugs.freedesktop.org/show_bug.cgi?id=101491 + */ + { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX }, /* macbook pro 8.2 */ { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP }, { 0, 0, 0, 0, 0 }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 8ca1e8c..4f9a393 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -319,6 +319,9 @@ #define USB_VENDOR_ID_DELCOM 0x0fc5 #define USB_DEVICE_ID_DELCOM_VISUAL_IND 0xb080 +#define USB_VENDOR_ID_DELL 0x413c +#define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a + #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 1d6c997..20b40ad 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -349,7 +349,6 @@ static int magicmouse_raw_event(struct hid_device *hdev, if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { magicmouse_emit_buttons(msc, clicks & 3); - input_mt_report_pointer_emulation(input, true); input_report_rel(input, REL_X, x); input_report_rel(input, REL_Y, y); } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ @@ -389,16 +388,16 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd __clear_bit(BTN_RIGHT, input->keybit); __clear_bit(BTN_MIDDLE, input->keybit); __set_bit(BTN_MOUSE, input->keybit); + __set_bit(BTN_TOOL_FINGER, input->keybit); + __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); + __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); + __set_bit(BTN_TOOL_QUADTAP, input->keybit); + __set_bit(BTN_TOOL_QUINTTAP, input->keybit); + __set_bit(BTN_TOUCH, input->keybit); + __set_bit(INPUT_PROP_POINTER, input->propbit); __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); } - __set_bit(BTN_TOOL_FINGER, input->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); - __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); - __set_bit(BTN_TOOL_QUADTAP, input->keybit); - __set_bit(BTN_TOOL_QUINTTAP, input->keybit); - __set_bit(BTN_TOUCH, input->keybit); - __set_bit(INPUT_PROP_POINTER, input->propbit); __set_bit(EV_ABS, input->evbit); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 6316498..a88e7c7 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -85,6 +85,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT }, diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 95ed171..54a47b4 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -734,9 +734,9 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx, * the first read operation, otherwise the first read cost * one extra clock cycle. */ - temp = readb(i2c_imx->base + IMX_I2C_I2CR); + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); temp |= I2CR_MTX; - writeb(temp, i2c_imx->base + IMX_I2C_I2CR); + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); } msgs->buf[msgs->len-1] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); @@ -857,9 +857,9 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo * the first read operation, otherwise the first read cost * one extra clock cycle. */ - temp = readb(i2c_imx->base + IMX_I2C_I2CR); + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); temp |= I2CR_MTX; - writeb(temp, i2c_imx->base + IMX_I2C_I2CR); + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); } } else if (i == (msgs->len - 2)) { dev_dbg(&i2c_imx->adapter.dev, diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index e37d372..f600f3a 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -248,7 +248,8 @@ static struct soc_button_info *soc_button_get_button_info(struct device *dev) if (!btns_desc) { dev_err(dev, "ACPI Button Descriptors not found\n"); - return ERR_PTR(-ENODEV); + button_info = ERR_PTR(-ENODEV); + goto out; } /* The first package describes the collection */ @@ -264,24 +265,31 @@ static struct soc_button_info *soc_button_get_button_info(struct device *dev) } if (collection_uid == -1) { dev_err(dev, "Invalid Button Collection Descriptor\n"); - return ERR_PTR(-ENODEV); + button_info = ERR_PTR(-ENODEV); + goto out; } /* There are package.count - 1 buttons + 1 terminating empty entry */ button_info = devm_kcalloc(dev, btns_desc->package.count, sizeof(*button_info), GFP_KERNEL); - if (!button_info) - return ERR_PTR(-ENOMEM); + if (!button_info) { + button_info = ERR_PTR(-ENOMEM); + goto out; + } /* Parse the button descriptors */ for (i = 1, btn = 0; i < btns_desc->package.count; i++, btn++) { if (soc_button_parse_btn_desc(dev, &btns_desc->package.elements[i], collection_uid, - &button_info[btn])) - return ERR_PTR(-ENODEV); + &button_info[btn])) { + button_info = ERR_PTR(-ENODEV); + goto out; + } } +out: + kfree(buf.pointer); return button_info; } diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c index dea63e2..f5206e2 100644 --- a/drivers/input/rmi4/rmi_f54.c +++ b/drivers/input/rmi4/rmi_f54.c @@ -31,9 +31,6 @@ #define F54_GET_REPORT 1 #define F54_FORCE_CAL 2 -/* Fixed sizes of reports */ -#define F54_QUERY_LEN 27 - /* F54 capabilities */ #define F54_CAP_BASELINE (1 << 2) #define F54_CAP_IMAGE8 (1 << 3) @@ -95,7 +92,6 @@ struct rmi_f54_reports { struct f54_data { struct rmi_function *fn; - u8 qry[F54_QUERY_LEN]; u8 num_rx_electrodes; u8 num_tx_electrodes; u8 capabilities; @@ -632,22 +628,23 @@ static int rmi_f54_detect(struct rmi_function *fn) { int error; struct f54_data *f54; + u8 buf[6]; f54 = dev_get_drvdata(&fn->dev); error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, - &f54->qry, sizeof(f54->qry)); + buf, sizeof(buf)); if (error) { dev_err(&fn->dev, "%s: Failed to query F54 properties\n", __func__); return error; } - f54->num_rx_electrodes = f54->qry[0]; - f54->num_tx_electrodes = f54->qry[1]; - f54->capabilities = f54->qry[2]; - f54->clock_rate = f54->qry[3] | (f54->qry[4] << 8); - f54->family = f54->qry[5]; + f54->num_rx_electrodes = buf[0]; + f54->num_tx_electrodes = buf[1]; + f54->capabilities = buf[2]; + f54->clock_rate = buf[3] | (buf[4] << 8); + f54->family = buf[5]; rmi_dbg(RMI_DEBUG_FN, &fn->dev, "F54 num_rx_electrodes: %d\n", f54->num_rx_electrodes); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 09720d9..f932a83 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -723,6 +723,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"), }, }, + { + /* Fujitsu UH554 laptop */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"), + }, + }, { } }; diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index eb7fbe1..929f855 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -140,7 +140,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe) } #ifdef CONFIG_CLKSRC_MIPS_GIC -u64 gic_read_count(void) +u64 notrace gic_read_count(void) { unsigned int hi, hi2, lo; @@ -167,7 +167,7 @@ unsigned int gic_get_count_width(void) return bits; } -void gic_write_compare(u64 cnt) +void notrace gic_write_compare(u64 cnt) { if (mips_cm_is64) { gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt); @@ -179,7 +179,7 @@ void gic_write_compare(u64 cnt) } } -void gic_write_cpu_compare(u64 cnt, int cpu) +void notrace gic_write_cpu_compare(u64 cnt, int cpu) { unsigned long flags; diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 7910bfe..93b1810 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -1105,10 +1105,13 @@ static void schedule_autocommit(struct dm_integrity_c *ic) static void submit_flush_bio(struct dm_integrity_c *ic, struct dm_integrity_io *dio) { struct bio *bio; - spin_lock_irq(&ic->endio_wait.lock); + unsigned long flags; + + spin_lock_irqsave(&ic->endio_wait.lock, flags); bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); bio_list_add(&ic->flush_bio_list, bio); - spin_unlock_irq(&ic->endio_wait.lock); + spin_unlock_irqrestore(&ic->endio_wait.lock, flags); + queue_work(ic->commit_wq, &ic->commit_work); } @@ -3040,6 +3043,11 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) ti->error = "The device is too small"; goto bad; } + if (ti->len > ic->provided_data_sectors) { + r = -EINVAL; + ti->error = "Not enough provided sectors for requested mapping size"; + goto bad; + } if (!buffer_sectors) buffer_sectors = 1; diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 3702e50..8d5ca30 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -317,8 +317,8 @@ static void do_region(int op, int op_flags, unsigned region, else if (op == REQ_OP_WRITE_SAME) special_cmd_max_sectors = q->limits.max_write_same_sectors; if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES || - op == REQ_OP_WRITE_SAME) && - special_cmd_max_sectors == 0) { + op == REQ_OP_WRITE_SAME) && special_cmd_max_sectors == 0) { + atomic_inc(&io->count); dec_count(io, region, -EOPNOTSUPP); return; } diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index e61c450..4da8858 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -145,6 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list) struct dm_raid1_bio_record { struct mirror *m; + /* if details->bi_bdev == NULL, details were not saved */ struct dm_bio_details details; region_t write_region; }; @@ -1198,6 +1199,8 @@ static int mirror_map(struct dm_target *ti, struct bio *bio) struct dm_raid1_bio_record *bio_record = dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); + bio_record->details.bi_bdev = NULL; + if (rw == WRITE) { /* Save region for mirror_end_io() handler */ bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio); @@ -1256,12 +1259,22 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) } if (error == -EOPNOTSUPP) - return error; + goto out; if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD)) - return error; + goto out; if (unlikely(error)) { + if (!bio_record->details.bi_bdev) { + /* + * There wasn't enough memory to record necessary + * information for a retry or there was no other + * mirror in-sync. + */ + DMERR_LIMIT("Mirror read failed."); + return -EIO; + } + m = bio_record->m; DMERR("Mirror read failed from %s. Trying alternative device.", @@ -1277,6 +1290,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) bd = &bio_record->details; dm_bio_restore(bd, bio); + bio_record->details.bi_bdev = NULL; bio->bi_error = 0; queue_bio(ms, bio, rw); @@ -1285,6 +1299,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) DMERR("All replicated volumes dead, failing I/O"); } +out: + bio_record->details.bi_bdev = NULL; + return error; } diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 75488e6..8d46e3a 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -245,8 +245,7 @@ static int arizona_poll_reg(struct arizona *arizona, int ret; ret = regmap_read_poll_timeout(arizona->regmap, - ARIZONA_INTERRUPT_RAW_STATUS_5, val, - ((val & mask) == target), + reg, val, ((val & mask) == target), ARIZONA_REG_POLL_DELAY_US, timeout_ms * 1000); if (ret) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index ea1bfcf..53309f6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2171,9 +2171,10 @@ static int cxgb_up(struct adapter *adap) { int err; + mutex_lock(&uld_mutex); err = setup_sge_queues(adap); if (err) - goto out; + goto rel_lock; err = setup_rss(adap); if (err) goto freeq; @@ -2197,7 +2198,6 @@ static int cxgb_up(struct adapter *adap) goto irq_err; } - mutex_lock(&uld_mutex); enable_rx(adap); t4_sge_start(adap); t4_intr_enable(adap); @@ -2210,13 +2210,15 @@ static int cxgb_up(struct adapter *adap) #endif /* Initialize hash mac addr list*/ INIT_LIST_HEAD(&adap->mac_hlist); - out: return err; + irq_err: dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err); freeq: t4_free_sge_resources(adap); - goto out; + rel_lock: + mutex_unlock(&uld_mutex); + return err; } static void cxgb_down(struct adapter *adapter) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 9a520e4..290ad05 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -2647,7 +2647,7 @@ static int dpaa_eth_probe(struct platform_device *pdev) priv->buf_layout[TX].priv_data_size = DPAA_TX_PRIV_DATA_SIZE; /* Tx */ /* device used for DMA mapping */ - arch_setup_dma_ops(dev, 0, 0, NULL, false); + set_dma_ops(dev, get_dma_ops(&pdev->dev)); err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40)); if (err) { dev_err(dev, "dma_coerce_mask_and_coherent() failed\n"); diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c index 0b31f85..6e67d22 100644 --- a/drivers/net/ethernet/freescale/fman/mac.c +++ b/drivers/net/ethernet/freescale/fman/mac.c @@ -623,6 +623,8 @@ static struct platform_device *dpaa_eth_add_device(int fman_id, goto no_mem; } + set_dma_ops(&pdev->dev, get_dma_ops(priv->dev)); + ret = platform_device_add_data(pdev, &data, sizeof(data)); if (ret) goto err; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index b8fab14..e95795b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -288,9 +288,15 @@ static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en) /* Force 1000M Link, Default is 0x0200 */ phy_write(phy_dev, 7, 0x20C); - phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); - /* Enable PHY loop-back */ + /* Powerup Fiber */ + phy_write(phy_dev, HNS_PHY_PAGE_REG, 1); + val = phy_read(phy_dev, COPPER_CONTROL_REG); + val &= ~PHY_POWER_DOWN; + phy_write(phy_dev, COPPER_CONTROL_REG, val); + + /* Enable Phy Loopback */ + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); val = phy_read(phy_dev, COPPER_CONTROL_REG); val |= PHY_LOOP_BACK; val &= ~PHY_POWER_DOWN; @@ -299,6 +305,12 @@ static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en) phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA); phy_write(phy_dev, 1, 0x400); phy_write(phy_dev, 7, 0x200); + + phy_write(phy_dev, HNS_PHY_PAGE_REG, 1); + val = phy_read(phy_dev, COPPER_CONTROL_REG); + val |= PHY_POWER_DOWN; + phy_write(phy_dev, COPPER_CONTROL_REG, val); + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); phy_write(phy_dev, 9, 0xF00); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 8209aff..16486df 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -1242,11 +1242,11 @@ static int mlx5e_get_ts_info(struct net_device *dev, SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; - info->tx_types = (BIT(1) << HWTSTAMP_TX_OFF) | - (BIT(1) << HWTSTAMP_TX_ON); + info->tx_types = BIT(HWTSTAMP_TX_OFF) | + BIT(HWTSTAMP_TX_ON); - info->rx_filters = (BIT(1) << HWTSTAMP_FILTER_NONE) | - (BIT(1) << HWTSTAMP_FILTER_ALL); + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | + BIT(HWTSTAMP_FILTER_ALL); return 0; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 41cd22a..277f4de 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -4241,7 +4241,8 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev, return netdev; err_cleanup_nic: - profile->cleanup(priv); + if (profile->cleanup) + profile->cleanup(priv); free_netdev(netdev); return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 79462c0..46984a5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -791,6 +791,8 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev, params->tx_max_inline = mlx5e_get_max_inline_cap(mdev); params->num_tc = 1; params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; + + mlx5_query_min_inline(mdev, ¶ms->tx_min_inline_mode); } static void mlx5e_build_rep_netdev(struct net_device *netdev) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index ec63158..9df9fc0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -895,7 +895,6 @@ static struct mlx5_fields fields[] = { {MLX5_ACTION_IN_FIELD_OUT_SMAC_15_0, 2, offsetof(struct pedit_headers, eth.h_source[4])}, {MLX5_ACTION_IN_FIELD_OUT_ETHERTYPE, 2, offsetof(struct pedit_headers, eth.h_proto)}, - {MLX5_ACTION_IN_FIELD_OUT_IP_DSCP, 1, offsetof(struct pedit_headers, ip4.tos)}, {MLX5_ACTION_IN_FIELD_OUT_IP_TTL, 1, offsetof(struct pedit_headers, ip4.ttl)}, {MLX5_ACTION_IN_FIELD_OUT_SIPV4, 4, offsetof(struct pedit_headers, ip4.saddr)}, {MLX5_ACTION_IN_FIELD_OUT_DIPV4, 4, offsetof(struct pedit_headers, ip4.daddr)}, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index f991f66..a53e982 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -906,21 +906,34 @@ static int esw_inline_mode_to_devlink(u8 mlx5_mode, u8 *mode) return 0; } -int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode) +static int mlx5_devlink_eswitch_check(struct devlink *devlink) { - struct mlx5_core_dev *dev; - u16 cur_mlx5_mode, mlx5_mode = 0; + struct mlx5_core_dev *dev = devlink_priv(devlink); - dev = devlink_priv(devlink); + if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH) + return -EOPNOTSUPP; if (!MLX5_CAP_GEN(dev, vport_group_manager)) return -EOPNOTSUPP; - cur_mlx5_mode = dev->priv.eswitch->mode; - - if (cur_mlx5_mode == SRIOV_NONE) + if (dev->priv.eswitch->mode == SRIOV_NONE) return -EOPNOTSUPP; + return 0; +} + +int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + u16 cur_mlx5_mode, mlx5_mode = 0; + int err; + + err = mlx5_devlink_eswitch_check(devlink); + if (err) + return err; + + cur_mlx5_mode = dev->priv.eswitch->mode; + if (esw_mode_from_devlink(mode, &mlx5_mode)) return -EINVAL; @@ -937,15 +950,12 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode) int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) { - struct mlx5_core_dev *dev; - - dev = devlink_priv(devlink); - - if (!MLX5_CAP_GEN(dev, vport_group_manager)) - return -EOPNOTSUPP; + struct mlx5_core_dev *dev = devlink_priv(devlink); + int err; - if (dev->priv.eswitch->mode == SRIOV_NONE) - return -EOPNOTSUPP; + err = mlx5_devlink_eswitch_check(devlink); + if (err) + return err; return esw_mode_to_devlink(dev->priv.eswitch->mode, mode); } @@ -954,15 +964,12 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode) { struct mlx5_core_dev *dev = devlink_priv(devlink); struct mlx5_eswitch *esw = dev->priv.eswitch; - int num_vports = esw->enabled_vports; int err, vport; u8 mlx5_mode; - if (!MLX5_CAP_GEN(dev, vport_group_manager)) - return -EOPNOTSUPP; - - if (esw->mode == SRIOV_NONE) - return -EOPNOTSUPP; + err = mlx5_devlink_eswitch_check(devlink); + if (err) + return err; switch (MLX5_CAP_ETH(dev, wqe_inline_mode)) { case MLX5_CAP_INLINE_MODE_NOT_REQUIRED: @@ -985,7 +992,7 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode) if (err) goto out; - for (vport = 1; vport < num_vports; vport++) { + for (vport = 1; vport < esw->enabled_vports; vport++) { err = mlx5_modify_nic_vport_min_inline(dev, vport, mlx5_mode); if (err) { esw_warn(dev, "Failed to set min inline on vport %d\n", @@ -1010,12 +1017,11 @@ int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode) { struct mlx5_core_dev *dev = devlink_priv(devlink); struct mlx5_eswitch *esw = dev->priv.eswitch; + int err; - if (!MLX5_CAP_GEN(dev, vport_group_manager)) - return -EOPNOTSUPP; - - if (esw->mode == SRIOV_NONE) - return -EOPNOTSUPP; + err = mlx5_devlink_eswitch_check(devlink); + if (err) + return err; return esw_inline_mode_to_devlink(esw->offloads.inline_mode, mode); } @@ -1062,11 +1068,9 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap) struct mlx5_eswitch *esw = dev->priv.eswitch; int err; - if (!MLX5_CAP_GEN(dev, vport_group_manager)) - return -EOPNOTSUPP; - - if (esw->mode == SRIOV_NONE) - return -EOPNOTSUPP; + err = mlx5_devlink_eswitch_check(devlink); + if (err) + return err; if (encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE && (!MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) || @@ -1105,12 +1109,11 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap) { struct mlx5_core_dev *dev = devlink_priv(devlink); struct mlx5_eswitch *esw = dev->priv.eswitch; + int err; - if (!MLX5_CAP_GEN(dev, vport_group_manager)) - return -EOPNOTSUPP; - - if (esw->mode == SRIOV_NONE) - return -EOPNOTSUPP; + err = mlx5_devlink_eswitch_check(devlink); + if (err) + return err; *encap = esw->offloads.encap; return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 4f577a5..13be264 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -175,8 +175,9 @@ static struct mlx5_profile profile[] = { }, }; -#define FW_INIT_TIMEOUT_MILI 2000 -#define FW_INIT_WAIT_MS 2 +#define FW_INIT_TIMEOUT_MILI 2000 +#define FW_INIT_WAIT_MS 2 +#define FW_PRE_INIT_TIMEOUT_MILI 10000 static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili) { @@ -1013,6 +1014,15 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, */ dev->state = MLX5_DEVICE_STATE_UP; + /* wait for firmware to accept initialization segments configurations + */ + err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI); + if (err) { + dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n", + FW_PRE_INIT_TIMEOUT_MILI); + goto out; + } + err = mlx5_cmd_init(dev); if (err) { dev_err(&pdev->dev, "Failed initializing command interface, aborting\n"); diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c index b7e4345..019cef1 100644 --- a/drivers/net/ethernet/sfc/ef10_sriov.c +++ b/drivers/net/ethernet/sfc/ef10_sriov.c @@ -661,8 +661,6 @@ restore_filters: up_write(&vf->efx->filter_sem); mutex_unlock(&vf->efx->mac_lock); - up_write(&vf->efx->filter_sem); - rc2 = efx_net_open(vf->efx->net_dev); if (rc2) goto reset_nic; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d16d11b..6e4cbc6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2831,7 +2831,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) tx_q->tx_skbuff_dma[first_entry].buf = des; tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb); - tx_q->tx_skbuff[first_entry] = skb; first->des0 = cpu_to_le32(des); @@ -2865,6 +2864,14 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) tx_q->tx_skbuff_dma[tx_q->cur_tx].last_segment = true; + /* Only the last descriptor gets to point to the skb. */ + tx_q->tx_skbuff[tx_q->cur_tx] = skb; + + /* We've used all descriptors we need for this skb, however, + * advance cur_tx so that it references a fresh descriptor. + * ndo_start_xmit will fill this descriptor the next time it's + * called and stmmac_tx_clean may clean up to this descriptor. + */ tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE); if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) { @@ -2998,8 +3005,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) first = desc; - tx_q->tx_skbuff[first_entry] = skb; - enh_desc = priv->plat->enh_desc; /* To program the descriptors according to the size of the frame */ if (enh_desc) @@ -3047,8 +3052,15 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) skb->len); } - entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE); + /* Only the last descriptor gets to point to the skb. */ + tx_q->tx_skbuff[entry] = skb; + /* We've used all descriptors we need for this skb, however, + * advance cur_tx so that it references a fresh descriptor. + * ndo_start_xmit will fill this descriptor the next time it's + * called and stmmac_tx_clean may clean up to this descriptor. + */ + entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE); tx_q->cur_tx = entry; if (netif_msg_pktdata(priv)) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c index c7c1e99..d231042 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -442,7 +442,7 @@ struct brcmf_fw { const char *nvram_name; u16 domain_nr; u16 bus_nr; - void (*done)(struct device *dev, const struct firmware *fw, + void (*done)(struct device *dev, int err, const struct firmware *fw, void *nvram_image, u32 nvram_len); }; @@ -477,52 +477,51 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) goto fail; - fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length); + fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length); kfree(fwctx); return; fail: brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); release_firmware(fwctx->code); - device_release_driver(fwctx->dev); + fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0); kfree(fwctx); } static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) { struct brcmf_fw *fwctx = ctx; - int ret; + int ret = 0; brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); - if (!fw) + if (!fw) { + ret = -ENOENT; goto fail; - - /* only requested code so done here */ - if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) { - fwctx->done(fwctx->dev, fw, NULL, 0); - kfree(fwctx); - return; } + /* only requested code so done here */ + if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) + goto done; + fwctx->code = fw; ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name, fwctx->dev, GFP_KERNEL, fwctx, brcmf_fw_request_nvram_done); - if (!ret) - return; - - brcmf_fw_request_nvram_done(NULL, fwctx); + /* pass NULL to nvram callback for bcm47xx fallback */ + if (ret) + brcmf_fw_request_nvram_done(NULL, fwctx); return; fail: brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); - device_release_driver(fwctx->dev); +done: + fwctx->done(fwctx->dev, ret, fw, NULL, 0); kfree(fwctx); } int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, const char *code, const char *nvram, - void (*fw_cb)(struct device *dev, + void (*fw_cb)(struct device *dev, int err, const struct firmware *fw, void *nvram_image, u32 nvram_len), u16 domain_nr, u16 bus_nr) @@ -555,7 +554,7 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, int brcmf_fw_get_firmwares(struct device *dev, u16 flags, const char *code, const char *nvram, - void (*fw_cb)(struct device *dev, + void (*fw_cb)(struct device *dev, int err, const struct firmware *fw, void *nvram_image, u32 nvram_len)) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h index d3c9f0d..8fa4b7e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h @@ -73,13 +73,13 @@ void brcmf_fw_nvram_free(void *nvram); */ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, const char *code, const char *nvram, - void (*fw_cb)(struct device *dev, + void (*fw_cb)(struct device *dev, int err, const struct firmware *fw, void *nvram_image, u32 nvram_len), u16 domain_nr, u16 bus_nr); int brcmf_fw_get_firmwares(struct device *dev, u16 flags, const char *code, const char *nvram, - void (*fw_cb)(struct device *dev, + void (*fw_cb)(struct device *dev, int err, const struct firmware *fw, void *nvram_image, u32 nvram_len)); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index 72373e5..f59642b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -2145,7 +2145,7 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp) struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr); struct brcmf_fws_mac_descriptor *entry; - if (!ifp->ndev || fws->fcmode == BRCMF_FWS_FCMODE_NONE) + if (!ifp->ndev || !brcmf_fws_queue_skbs(fws)) return; entry = &fws->desc.iface[ifp->ifidx]; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index f36b96d..f878706 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -1650,16 +1650,23 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { .write32 = brcmf_pcie_buscore_write32, }; -static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw, +static void brcmf_pcie_setup(struct device *dev, int ret, + const struct firmware *fw, void *nvram, u32 nvram_len) { - struct brcmf_bus *bus = dev_get_drvdata(dev); - struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie; - struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo; + struct brcmf_bus *bus; + struct brcmf_pciedev *pcie_bus_dev; + struct brcmf_pciedev_info *devinfo; struct brcmf_commonring **flowrings; - int ret; u32 i; + /* check firmware loading result */ + if (ret) + goto fail; + + bus = dev_get_drvdata(dev); + pcie_bus_dev = bus->bus_priv.pcie; + devinfo = pcie_bus_dev->devinfo; brcmf_pcie_attach(devinfo); /* Some of the firmwares have the size of the memory of the device diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index e034500..5653d6d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -3982,21 +3982,26 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .get_memdump = brcmf_sdio_bus_get_memdump, }; -static void brcmf_sdio_firmware_callback(struct device *dev, +static void brcmf_sdio_firmware_callback(struct device *dev, int err, const struct firmware *code, void *nvram, u32 nvram_len) { - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - struct brcmf_sdio *bus = sdiodev->bus; - int err = 0; + struct brcmf_bus *bus_if; + struct brcmf_sdio_dev *sdiodev; + struct brcmf_sdio *bus; u8 saveclk; - brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev)); + brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); + bus_if = dev_get_drvdata(dev); + sdiodev = bus_if->bus_priv.sdio; + if (err) + goto fail; if (!bus_if->drvr) return; + bus = sdiodev->bus; + /* try to download image and nvram to the dongle */ bus->alp_only = true; err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); @@ -4083,6 +4088,7 @@ release: fail: brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); device_release_driver(dev); + device_release_driver(&sdiodev->func[2]->dev); } struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index e4d545f..0eea48e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -1159,17 +1159,18 @@ fail: return ret; } -static void brcmf_usb_probe_phase2(struct device *dev, +static void brcmf_usb_probe_phase2(struct device *dev, int ret, const struct firmware *fw, void *nvram, u32 nvlen) { struct brcmf_bus *bus = dev_get_drvdata(dev); - struct brcmf_usbdev_info *devinfo; - int ret; + struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; + + if (ret) + goto error; brcmf_dbg(USB, "Start fw downloading\n"); - devinfo = bus->bus_priv.usb->devinfo; ret = check_file(fw->data); if (ret < 0) { brcmf_err("invalid firmware\n"); diff --git a/drivers/ntb/hw/intel/ntb_hw_intel.c b/drivers/ntb/hw/intel/ntb_hw_intel.c index c002384..7b3b6fd 100644 --- a/drivers/ntb/hw/intel/ntb_hw_intel.c +++ b/drivers/ntb/hw/intel/ntb_hw_intel.c @@ -2878,7 +2878,7 @@ static const struct intel_ntb_reg skx_reg = { .link_is_up = xeon_link_is_up, .db_ioread = skx_db_ioread, .db_iowrite = skx_db_iowrite, - .db_size = sizeof(u64), + .db_size = sizeof(u32), .ntb_ctl = SKX_NTBCNTL_OFFSET, .mw_bar = {2, 4}, }; diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 02ca45f..10e5bf4 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -177,14 +177,12 @@ struct ntb_transport_qp { u64 rx_err_ver; u64 rx_memcpy; u64 rx_async; - u64 dma_rx_prep_err; u64 tx_bytes; u64 tx_pkts; u64 tx_ring_full; u64 tx_err_no_buf; u64 tx_memcpy; u64 tx_async; - u64 dma_tx_prep_err; }; struct ntb_transport_mw { @@ -254,8 +252,6 @@ enum { #define QP_TO_MW(nt, qp) ((qp) % nt->mw_count) #define NTB_QP_DEF_NUM_ENTRIES 100 #define NTB_LINK_DOWN_TIMEOUT 10 -#define DMA_RETRIES 20 -#define DMA_OUT_RESOURCE_TO msecs_to_jiffies(50) static void ntb_transport_rxc_db(unsigned long data); static const struct ntb_ctx_ops ntb_transport_ops; @@ -516,12 +512,6 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count, out_offset += snprintf(buf + out_offset, out_count - out_offset, "free tx - \t%u\n", ntb_transport_tx_free_entry(qp)); - out_offset += snprintf(buf + out_offset, out_count - out_offset, - "DMA tx prep err - \t%llu\n", - qp->dma_tx_prep_err); - out_offset += snprintf(buf + out_offset, out_count - out_offset, - "DMA rx prep err - \t%llu\n", - qp->dma_rx_prep_err); out_offset += snprintf(buf + out_offset, out_count - out_offset, "\n"); @@ -623,7 +613,7 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt, if (!mw->virt_addr) return -ENOMEM; - if (qp_count % mw_count && mw_num + 1 < qp_count / mw_count) + if (mw_num < qp_count % mw_count) num_qps_mw = qp_count / mw_count + 1; else num_qps_mw = qp_count / mw_count; @@ -768,8 +758,6 @@ static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) qp->tx_err_no_buf = 0; qp->tx_memcpy = 0; qp->tx_async = 0; - qp->dma_tx_prep_err = 0; - qp->dma_rx_prep_err = 0; } static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp) @@ -1000,7 +988,7 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt, qp->event_handler = NULL; ntb_qp_link_down_reset(qp); - if (qp_count % mw_count && mw_num + 1 < qp_count / mw_count) + if (mw_num < qp_count % mw_count) num_qps_mw = qp_count / mw_count + 1; else num_qps_mw = qp_count / mw_count; @@ -1128,8 +1116,8 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev) qp_count = ilog2(qp_bitmap); if (max_num_clients && max_num_clients < qp_count) qp_count = max_num_clients; - else if (mw_count < qp_count) - qp_count = mw_count; + else if (nt->mw_count < qp_count) + qp_count = nt->mw_count; qp_bitmap &= BIT_ULL(qp_count) - 1; @@ -1317,7 +1305,6 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset) struct dmaengine_unmap_data *unmap; dma_cookie_t cookie; void *buf = entry->buf; - int retries = 0; len = entry->len; device = chan->device; @@ -1346,22 +1333,11 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset) unmap->from_cnt = 1; - for (retries = 0; retries < DMA_RETRIES; retries++) { - txd = device->device_prep_dma_memcpy(chan, - unmap->addr[1], - unmap->addr[0], len, - DMA_PREP_INTERRUPT); - if (txd) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(DMA_OUT_RESOURCE_TO); - } - - if (!txd) { - qp->dma_rx_prep_err++; + txd = device->device_prep_dma_memcpy(chan, unmap->addr[1], + unmap->addr[0], len, + DMA_PREP_INTERRUPT); + if (!txd) goto err_get_unmap; - } txd->callback_result = ntb_rx_copy_callback; txd->callback_param = entry; @@ -1606,7 +1582,6 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp, struct dmaengine_unmap_data *unmap; dma_addr_t dest; dma_cookie_t cookie; - int retries = 0; device = chan->device; dest = qp->tx_mw_phys + qp->tx_max_frame * entry->tx_index; @@ -1628,21 +1603,10 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp, unmap->to_cnt = 1; - for (retries = 0; retries < DMA_RETRIES; retries++) { - txd = device->device_prep_dma_memcpy(chan, dest, - unmap->addr[0], len, - DMA_PREP_INTERRUPT); - if (txd) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(DMA_OUT_RESOURCE_TO); - } - - if (!txd) { - qp->dma_tx_prep_err++; + txd = device->device_prep_dma_memcpy(chan, dest, unmap->addr[0], len, + DMA_PREP_INTERRUPT); + if (!txd) goto err_get_unmap; - } txd->callback_result = ntb_tx_copy_callback; txd->callback_param = entry; diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c index 434e1d4..5cab283 100644 --- a/drivers/ntb/test/ntb_perf.c +++ b/drivers/ntb/test/ntb_perf.c @@ -90,11 +90,11 @@ MODULE_PARM_DESC(max_mw_size, "Limit size of large memory windows"); static unsigned int seg_order = 19; /* 512K */ module_param(seg_order, uint, 0644); -MODULE_PARM_DESC(seg_order, "size order [n^2] of buffer segment for testing"); +MODULE_PARM_DESC(seg_order, "size order [2^n] of buffer segment for testing"); static unsigned int run_order = 32; /* 4G */ module_param(run_order, uint, 0644); -MODULE_PARM_DESC(run_order, "size order [n^2] of total data to transfer"); +MODULE_PARM_DESC(run_order, "size order [2^n] of total data to transfer"); static bool use_dma; /* default to 0 */ module_param(use_dma, bool, 0644); diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 1482d13..e432ec8 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -495,64 +495,54 @@ static struct irq_chip amd_gpio_irqchip = { .flags = IRQCHIP_SKIP_SET_WAKE, }; -static void amd_gpio_irq_handler(struct irq_desc *desc) +#define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF)) + +static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) { - u32 i; - u32 off; - u32 reg; - u32 pin_reg; - u64 reg64; - int handled = 0; - unsigned int irq; + struct amd_gpio *gpio_dev = dev_id; + struct gpio_chip *gc = &gpio_dev->gc; + irqreturn_t ret = IRQ_NONE; + unsigned int i, irqnr; unsigned long flags; - struct irq_chip *chip = irq_desc_get_chip(desc); - struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct amd_gpio *gpio_dev = gpiochip_get_data(gc); + u32 *regs, regval; + u64 status, mask; - chained_irq_enter(chip, desc); - /*enable GPIO interrupt again*/ + /* Read the wake status */ raw_spin_lock_irqsave(&gpio_dev->lock, flags); - reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1); - reg64 = reg; - reg64 = reg64 << 32; - - reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0); - reg64 |= reg; + status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1); + status <<= 32; + status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); - /* - * first 46 bits indicates interrupt status. - * one bit represents four interrupt sources. - */ - for (off = 0; off < 46 ; off++) { - if (reg64 & BIT(off)) { - for (i = 0; i < 4; i++) { - pin_reg = readl(gpio_dev->base + - (off * 4 + i) * 4); - if ((pin_reg & BIT(INTERRUPT_STS_OFF)) || - (pin_reg & BIT(WAKE_STS_OFF))) { - irq = irq_find_mapping(gc->irqdomain, - off * 4 + i); - generic_handle_irq(irq); - writel(pin_reg, - gpio_dev->base - + (off * 4 + i) * 4); - handled++; - } - } + /* Bit 0-45 contain the relevant status bits */ + status &= (1ULL << 46) - 1; + regs = gpio_dev->base; + for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) { + if (!(status & mask)) + continue; + status &= ~mask; + + /* Each status bit covers four pins */ + for (i = 0; i < 4; i++) { + regval = readl(regs + i); + if (!(regval & PIN_IRQ_PENDING)) + continue; + irq = irq_find_mapping(gc->irqdomain, irqnr + i); + generic_handle_irq(irq); + /* Clear interrupt */ + writel(regval, regs + i); + ret = IRQ_HANDLED; } } - if (handled == 0) - handle_bad_irq(desc); - + /* Signal EOI to the GPIO unit */ raw_spin_lock_irqsave(&gpio_dev->lock, flags); - reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); - reg |= EOI_MASK; - writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG); + regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG); + regval |= EOI_MASK; + writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); - chained_irq_exit(chip, desc); + return ret; } static int amd_get_groups_count(struct pinctrl_dev *pctldev) @@ -821,10 +811,11 @@ static int amd_gpio_probe(struct platform_device *pdev) goto out2; } - gpiochip_set_chained_irqchip(&gpio_dev->gc, - &amd_gpio_irqchip, - irq_base, - amd_gpio_irq_handler); + ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0, + KBUILD_MODNAME, gpio_dev); + if (ret) + goto out2; + platform_set_drvdata(pdev, gpio_dev); dev_dbg(&pdev->dev, "amd gpio driver loaded\n"); diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index d3c5f5d..222b668 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -798,7 +798,7 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, break; case PIN_CONFIG_OUTPUT: __stm32_gpio_set(bank, offset, arg); - ret = stm32_pmx_gpio_set_direction(pctldev, NULL, pin, false); + ret = stm32_pmx_gpio_set_direction(pctldev, range, pin, false); break; default: ret = -EINVAL; diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 8bc7ee1..507512c 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -870,7 +870,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, QEDI_ERR(&qedi->dbg_ctx, "Delayed or untracked cleanup response, itt=0x%x, tid=0x%x, cid=0x%x, task=%p\n", protoitt, cqe->itid, qedi_conn->iscsi_conn_id, task); - WARN_ON(1); } } diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 09a2946..879d3b7 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -1499,11 +1499,9 @@ err_idx: void qedi_clear_task_idx(struct qedi_ctx *qedi, int idx) { - if (!test_and_clear_bit(idx, qedi->task_idx_map)) { + if (!test_and_clear_bit(idx, qedi->task_idx_map)) QEDI_ERR(&qedi->dbg_ctx, "FW task context, already cleared, tid=0x%x\n", idx); - WARN_ON(1); - } } void qedi_update_itt_map(struct qedi_ctx *qedi, u32 tid, u32 proto_itt, diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 0d8f815..3fdca2c 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1279,6 +1279,18 @@ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, */ if (dump_payload) goto after_immediate_data; + /* + * Check for underflow case where both EDTL and immediate data payload + * exceeds what is presented by CDB's TRANSFER LENGTH, and what has + * already been set in target_cmd_size_check() as se_cmd->data_length. + * + * For this special case, fail the command and dump the immediate data + * payload. + */ + if (cmd->first_burst_len > cmd->se_cmd.data_length) { + cmd->sense_reason = TCM_INVALID_CDB_FIELD; + goto after_immediate_data; + } immed_ret = iscsit_handle_immediate_data(cmd, hdr, cmd->first_burst_len); @@ -4423,8 +4435,11 @@ static void iscsit_logout_post_handler_closesession( * always sleep waiting for RX/TX thread shutdown to complete * within iscsit_close_connection(). */ - if (!conn->conn_transport->rdma_shutdown) + if (!conn->conn_transport->rdma_shutdown) { sleep = cmpxchg(&conn->tx_thread_active, true, false); + if (!sleep) + return; + } atomic_set(&conn->conn_logout_remove, 0); complete(&conn->conn_logout_comp); @@ -4440,8 +4455,11 @@ static void iscsit_logout_post_handler_samecid( { int sleep = 1; - if (!conn->conn_transport->rdma_shutdown) + if (!conn->conn_transport->rdma_shutdown) { sleep = cmpxchg(&conn->tx_thread_active, true, false); + if (!sleep) + return; + } atomic_set(&conn->conn_logout_remove, 0); complete(&conn->conn_logout_comp); diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 9ab7090..0912de7 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -136,7 +136,7 @@ int init_se_kmem_caches(void); void release_se_kmem_caches(void); u32 scsi_get_new_index(scsi_index_t); void transport_subsystem_check_init(void); -void transport_cmd_finish_abort(struct se_cmd *, int); +int transport_cmd_finish_abort(struct se_cmd *, int); unsigned char *transport_dump_cmd_direction(struct se_cmd *); void transport_dump_dev_state(struct se_device *, char *, int *); void transport_dump_dev_info(struct se_device *, struct se_lun *, diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index dce1e1b..13f47bf 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -75,7 +75,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr) kfree(tmr); } -static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas) +static int core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas) { unsigned long flags; bool remove = true, send_tas; @@ -91,7 +91,7 @@ static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas) transport_send_task_abort(cmd); } - transport_cmd_finish_abort(cmd, remove); + return transport_cmd_finish_abort(cmd, remove); } static int target_check_cdb_and_preempt(struct list_head *list, @@ -184,8 +184,8 @@ void core_tmr_abort_task( cancel_work_sync(&se_cmd->work); transport_wait_for_tasks(se_cmd); - transport_cmd_finish_abort(se_cmd, true); - target_put_sess_cmd(se_cmd); + if (!transport_cmd_finish_abort(se_cmd, true)) + target_put_sess_cmd(se_cmd); printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for" " ref_tag: %llu\n", ref_tag); @@ -281,8 +281,8 @@ static void core_tmr_drain_tmr_list( cancel_work_sync(&cmd->work); transport_wait_for_tasks(cmd); - transport_cmd_finish_abort(cmd, 1); - target_put_sess_cmd(cmd); + if (!transport_cmd_finish_abort(cmd, 1)) + target_put_sess_cmd(cmd); } } @@ -380,8 +380,8 @@ static void core_tmr_drain_state_list( cancel_work_sync(&cmd->work); transport_wait_for_tasks(cmd); - core_tmr_handle_tas_abort(cmd, tas); - target_put_sess_cmd(cmd); + if (!core_tmr_handle_tas_abort(cmd, tas)) + target_put_sess_cmd(cmd); } } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 6025935..f1b3a46 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -651,9 +651,10 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) percpu_ref_put(&lun->lun_ref); } -void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) +int transport_cmd_finish_abort(struct se_cmd *cmd, int remove) { bool ack_kref = (cmd->se_cmd_flags & SCF_ACK_KREF); + int ret = 0; if (cmd->se_cmd_flags & SCF_SE_LUN_CMD) transport_lun_remove_cmd(cmd); @@ -665,9 +666,11 @@ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove) cmd->se_tfo->aborted_task(cmd); if (transport_cmd_check_stop_to_fabric(cmd)) - return; + return 1; if (remove && ack_kref) - transport_put_cmd(cmd); + ret = transport_put_cmd(cmd); + + return ret; } static void target_complete_failure_work(struct work_struct *work) diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 734cbf8..dd9f1be 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c @@ -344,7 +344,7 @@ static int autofs_dev_ioctl_fail(struct file *fp, int status; token = (autofs_wqt_t) param->fail.token; - status = param->fail.status ? param->fail.status : -ENOENT; + status = param->fail.status < 0 ? param->fail.status : -ENOENT; return autofs4_wait_release(sbi, token, status); } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0fd081b..fcef706 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3271,7 +3271,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) if (!is_sync_kiocb(iocb)) ctx->iocb = iocb; - if (to->type & ITER_IOVEC) + if (to->type == ITER_IOVEC) ctx->should_dirty = true; rc = setup_aio_ctx_iter(ctx, to, READ); diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index b085319..3b147dc 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -810,7 +810,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) if (!pages) { pages = vmalloc(max_pages * sizeof(struct page *)); - if (!bv) { + if (!pages) { kvfree(bv); return -ENOMEM; } diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 27bc360..a723df3 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -849,8 +849,13 @@ cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *fid, __u16 search_flags, struct cifs_search_info *srch_inf) { - return CIFSFindFirst(xid, tcon, path, cifs_sb, - &fid->netfid, search_flags, srch_inf, true); + int rc; + + rc = CIFSFindFirst(xid, tcon, path, cifs_sb, + &fid->netfid, search_flags, srch_inf, true); + if (rc) + cifs_dbg(FYI, "find first failed=%d\n", rc); + return rc; } static int diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index c586918..7e48561 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -982,7 +982,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); kfree(utf16_path); if (rc) { - cifs_dbg(VFS, "open dir failed\n"); + cifs_dbg(FYI, "open dir failed rc=%d\n", rc); return rc; } @@ -992,7 +992,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, rc = SMB2_query_directory(xid, tcon, fid->persistent_fid, fid->volatile_fid, 0, srch_inf); if (rc) { - cifs_dbg(VFS, "query directory failed\n"); + cifs_dbg(FYI, "query directory failed rc=%d\n", rc); SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid); } return rc; @@ -1809,7 +1809,8 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc) sg = init_sg(rqst, sign); if (!sg) { - cifs_dbg(VFS, "%s: Failed to init sg %d", __func__, rc); + cifs_dbg(VFS, "%s: Failed to init sg", __func__); + rc = -ENOMEM; goto free_req; } @@ -1817,6 +1818,7 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc) iv = kzalloc(iv_len, GFP_KERNEL); if (!iv) { cifs_dbg(VFS, "%s: Failed to alloc IV", __func__); + rc = -ENOMEM; goto free_sg; } iv[0] = 3; diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 3cb5c9e..de50e74 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -188,8 +188,6 @@ static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode, pcreatetime = (__u64 *)value; *pcreatetime = CIFS_I(inode)->createtime; return sizeof(__u64); - - return rc; } @@ -859,6 +859,7 @@ int dax_writeback_mapping_range(struct address_space *mapping, if (ret < 0) goto out; } + start_index = indices[pvec.nr - 1] + 1; } out: put_dax(dax_dev); @@ -220,8 +220,26 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, if (write) { unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; + unsigned long ptr_size; struct rlimit *rlim; + /* + * Since the stack will hold pointers to the strings, we + * must account for them as well. + * + * The size calculation is the entire vma while each arg page is + * built, so each time we get here it's calculating how far it + * is currently (rather than each call being just the newly + * added size from the arg page). As a result, we need to + * always add the entire size of the pointers, so that on the + * last call to get_arg_page() we'll actually have the entire + * correct size. + */ + ptr_size = (bprm->argc + bprm->envc) * sizeof(void *); + if (ptr_size > ULONG_MAX - size) + goto fail; + size += ptr_size; + acct_arg_size(bprm, size / PAGE_SIZE); /* @@ -239,13 +257,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, * to work from. */ rlim = current->signal->rlim; - if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) { - put_page(page); - return NULL; - } + if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) + goto fail; } return page; + +fail: + put_page(page); + return NULL; } static void put_arg_page(struct page *page) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 3b7c937..4689940 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -2591,6 +2591,10 @@ void ocfs2_inode_unlock_tracker(struct inode *inode, struct ocfs2_lock_res *lockres; lockres = &OCFS2_I(inode)->ip_inode_lockres; + /* had_lock means that the currect process already takes the cluster + * lock previously. If had_lock is 1, we have nothing to do here, and + * it will get unlocked where we got the lock. + */ if (!had_lock) { ocfs2_remove_holder(lockres, oh); ocfs2_inode_unlock(inode, ex); diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 3c5384d..f70c377 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -1328,20 +1328,21 @@ static int ocfs2_xattr_get(struct inode *inode, void *buffer, size_t buffer_size) { - int ret; + int ret, had_lock; struct buffer_head *di_bh = NULL; + struct ocfs2_lock_holder oh; - ret = ocfs2_inode_lock(inode, &di_bh, 0); - if (ret < 0) { - mlog_errno(ret); - return ret; + had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 0, &oh); + if (had_lock < 0) { + mlog_errno(had_lock); + return had_lock; } down_read(&OCFS2_I(inode)->ip_xattr_sem); ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, name, buffer, buffer_size); up_read(&OCFS2_I(inode)->ip_xattr_sem); - ocfs2_inode_unlock(inode, 0); + ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock); brelse(di_bh); @@ -3537,11 +3538,12 @@ int ocfs2_xattr_set(struct inode *inode, { struct buffer_head *di_bh = NULL; struct ocfs2_dinode *di; - int ret, credits, ref_meta = 0, ref_credits = 0; + int ret, credits, had_lock, ref_meta = 0, ref_credits = 0; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct inode *tl_inode = osb->osb_tl_inode; struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, NULL, }; struct ocfs2_refcount_tree *ref_tree = NULL; + struct ocfs2_lock_holder oh; struct ocfs2_xattr_info xi = { .xi_name_index = name_index, @@ -3572,8 +3574,9 @@ int ocfs2_xattr_set(struct inode *inode, return -ENOMEM; } - ret = ocfs2_inode_lock(inode, &di_bh, 1); - if (ret < 0) { + had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 1, &oh); + if (had_lock < 0) { + ret = had_lock; mlog_errno(ret); goto cleanup_nolock; } @@ -3670,7 +3673,7 @@ cleanup: if (ret) mlog_errno(ret); } - ocfs2_inode_unlock(inode, 1); + ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock); cleanup_nolock: brelse(di_bh); brelse(xbs.xattr_bh); diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 0315fea..f80be4c 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c @@ -455,24 +455,14 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, /* * allocate new block and move data */ - switch (fs32_to_cpu(sb, usb1->fs_optim)) { - case UFS_OPTSPACE: + if (fs32_to_cpu(sb, usb1->fs_optim) == UFS_OPTSPACE) { request = newcount; - if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree - > uspi->s_dsize * uspi->s_minfree / (2 * 100)) - break; - usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); - break; - default: - usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); - - case UFS_OPTTIME: + if (uspi->cs_total.cs_nffree < uspi->s_space_to_time) + usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); + } else { request = uspi->s_fpb; - if (uspi->cs_total.cs_nffree < uspi->s_dsize * - (uspi->s_minfree - 2) / 100) - break; - usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); - break; + if (uspi->cs_total.cs_nffree > uspi->s_time_to_space) + usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE); } result = ufs_alloc_fragments (inode, cgno, goal, request, err); if (result) { diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 9f459026..f36d6a5 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -566,10 +566,8 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) */ inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode); set_nlink(inode, fs16_to_cpu(sb, ufs_inode->ui_nlink)); - if (inode->i_nlink == 0) { - ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino); - return -1; - } + if (inode->i_nlink == 0) + return -ESTALE; /* * Linux now has 32-bit uid and gid, so we can support EFT. @@ -578,9 +576,9 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode)); inode->i_size = fs64_to_cpu(sb, ufs_inode->ui_size); - inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec); - inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec); - inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec); + inode->i_atime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec); + inode->i_ctime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec); + inode->i_mtime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec); inode->i_mtime.tv_nsec = 0; inode->i_atime.tv_nsec = 0; inode->i_ctime.tv_nsec = 0; @@ -614,10 +612,8 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) */ inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode); set_nlink(inode, fs16_to_cpu(sb, ufs2_inode->ui_nlink)); - if (inode->i_nlink == 0) { - ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino); - return -1; - } + if (inode->i_nlink == 0) + return -ESTALE; /* * Linux now has 32-bit uid and gid, so we can support EFT. @@ -657,7 +653,7 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino) struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; struct buffer_head * bh; struct inode *inode; - int err; + int err = -EIO; UFSD("ENTER, ino %lu\n", ino); @@ -692,9 +688,10 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino) err = ufs1_read_inode(inode, ufs_inode + ufs_inotofsbo(inode->i_ino)); } - + brelse(bh); if (err) goto bad_inode; + inode->i_version++; ufsi->i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; @@ -703,15 +700,13 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino) ufs_set_inode_ops(inode); - brelse(bh); - UFSD("EXIT\n"); unlock_new_inode(inode); return inode; bad_inode: iget_failed(inode); - return ERR_PTR(-EIO); + return ERR_PTR(err); } static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode) diff --git a/fs/ufs/super.c b/fs/ufs/super.c index d5300ad..0a4f58a 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1210,6 +1210,15 @@ magic_found: uspi->s_root_blocks = mul_u64_u32_div(uspi->s_dsize, uspi->s_minfree, 100); + if (uspi->s_minfree <= 5) { + uspi->s_time_to_space = ~0ULL; + uspi->s_space_to_time = 0; + usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE); + } else { + uspi->s_time_to_space = (uspi->s_root_blocks / 2) + 1; + uspi->s_space_to_time = mul_u64_u32_div(uspi->s_dsize, + uspi->s_minfree - 2, 100) - 1; + } /* * Compute another frequently used values diff --git a/fs/ufs/ufs_fs.h b/fs/ufs/ufs_fs.h index 823d55a..150eef6 100644 --- a/fs/ufs/ufs_fs.h +++ b/fs/ufs/ufs_fs.h @@ -792,6 +792,8 @@ struct ufs_sb_private_info { __s32 fs_magic; /* filesystem magic */ unsigned int s_dirblksize; __u64 s_root_blocks; + __u64 s_time_to_space; + __u64 s_space_to_time; }; /* diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 09af0f7..3b91faa 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1316,9 +1316,12 @@ xfs_vm_bmap( * The swap code (ab-)uses ->bmap to get a block mapping and then * bypasseÑ• the file system for actual I/O. We really can't allow * that on reflinks inodes, so we have to skip out here. And yes, - * 0 is the magic code for a bmap error.. + * 0 is the magic code for a bmap error. + * + * Since we don't pass back blockdev info, we can't return bmap + * information for rt files either. */ - if (xfs_is_reflink_inode(ip)) + if (xfs_is_reflink_inode(ip) || XFS_IS_REALTIME_INODE(ip)) return 0; filemap_write_and_wait(mapping); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 197f3ff..408c782 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -210,7 +210,8 @@ struct acpi_device_flags { u32 of_compatible_ok:1; u32 coherent_dma:1; u32 cca_seen:1; - u32 reserved:20; + u32 spi_i2c_slave:1; + u32 reserved:19; }; /* File System */ diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 27e0dba..34c8f56 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -334,4 +334,44 @@ INTEL_KBL_GT3_IDS(info), \ INTEL_KBL_GT4_IDS(info) +/* CFL S */ +#define INTEL_CFL_S_IDS(info) \ + INTEL_VGA_DEVICE(0x3E90, info), /* SRV GT1 */ \ + INTEL_VGA_DEVICE(0x3E93, info), /* SRV GT1 */ \ + INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */ \ + INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */ \ + INTEL_VGA_DEVICE(0x3E96, info) /* SRV GT2 */ + +/* CFL H */ +#define INTEL_CFL_H_IDS(info) \ + INTEL_VGA_DEVICE(0x3E9B, info), /* Halo GT2 */ \ + INTEL_VGA_DEVICE(0x3E94, info) /* Halo GT2 */ + +/* CFL U */ +#define INTEL_CFL_U_IDS(info) \ + INTEL_VGA_DEVICE(0x3EA6, info), /* ULT GT3 */ \ + INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */ \ + INTEL_VGA_DEVICE(0x3EA8, info), /* ULT GT3 */ \ + INTEL_VGA_DEVICE(0x3EA5, info) /* ULT GT3 */ + +/* CNL U 2+2 */ +#define INTEL_CNL_U_GT2_IDS(info) \ + INTEL_VGA_DEVICE(0x5A52, info), \ + INTEL_VGA_DEVICE(0x5A5A, info), \ + INTEL_VGA_DEVICE(0x5A42, info), \ + INTEL_VGA_DEVICE(0x5A4A, info) + +/* CNL Y 2+2 */ +#define INTEL_CNL_Y_GT2_IDS(info) \ + INTEL_VGA_DEVICE(0x5A51, info), \ + INTEL_VGA_DEVICE(0x5A59, info), \ + INTEL_VGA_DEVICE(0x5A41, info), \ + INTEL_VGA_DEVICE(0x5A49, info), \ + INTEL_VGA_DEVICE(0x5A71, info), \ + INTEL_VGA_DEVICE(0x5A79, info) + +#define INTEL_CNL_IDS(info) \ + INTEL_CNL_U_GT2_IDS(info), \ + INTEL_CNL_Y_GT2_IDS(info) + #endif /* _I915_PCIIDS_H */ diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h index 370c0a0..d66432c 100644 --- a/include/dt-bindings/clock/sun50i-a64-ccu.h +++ b/include/dt-bindings/clock/sun50i-a64-ccu.h @@ -43,6 +43,8 @@ #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_ #define _DT_BINDINGS_CLK_SUN50I_A64_H_ +#define CLK_PLL_PERIPH0 11 + #define CLK_BUS_MIPI_DSI 28 #define CLK_BUS_CE 29 #define CLK_BUS_DMA 30 diff --git a/include/dt-bindings/clock/sun8i-h3-ccu.h b/include/dt-bindings/clock/sun8i-h3-ccu.h index c2afc41..e139fe5 100644 --- a/include/dt-bindings/clock/sun8i-h3-ccu.h +++ b/include/dt-bindings/clock/sun8i-h3-ccu.h @@ -43,6 +43,8 @@ #ifndef _DT_BINDINGS_CLK_SUN8I_H3_H_ #define _DT_BINDINGS_CLK_SUN8I_H3_H_ +#define CLK_PLL_PERIPH0 9 + #define CLK_CPUX 14 #define CLK_BUS_CE 20 diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index b74a3ed..1ddd36b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -391,6 +391,8 @@ struct request_queue { int nr_rqs[2]; /* # allocated [a]sync rqs */ int nr_rqs_elvpriv; /* # allocated rqs w/ elvpriv */ + atomic_t shared_hctx_restart; + struct blk_queue_stats *stats; struct rq_wb *rq_wb; diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 07ef550..93315d6 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -84,6 +84,7 @@ struct kmem_cache { int red_left_pad; /* Left redzone padding size */ #ifdef CONFIG_SYSFS struct kobject kobj; /* For sysfs */ + struct work_struct kobj_remove_work; #endif #ifdef CONFIG_MEMCG struct memcg_cache_params memcg_params; diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index 110f453..f7043cc 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -29,7 +29,6 @@ */ struct tk_read_base { struct clocksource *clock; - u64 (*read)(struct clocksource *cs); u64 mask; u64 cycle_last; u32 mult; @@ -58,7 +57,7 @@ struct tk_read_base { * interval. * @xtime_remainder: Shifted nano seconds left over when rounding * @cycle_interval - * @raw_interval: Raw nano seconds accumulated per NTP interval. + * @raw_interval: Shifted raw nano seconds accumulated per NTP interval. * @ntp_error: Difference between accumulated time and NTP time in ntp * shifted nano seconds. * @ntp_error_shift: Shift conversion between clock shifted nano seconds and @@ -100,7 +99,7 @@ struct timekeeper { u64 cycle_interval; u64 xtime_interval; s64 xtime_remainder; - u32 raw_interval; + u64 raw_interval; /* The ntp_tick_length() value currently being used. * This cached copy ensures we consistently apply the tick * length for an entire tick, as ntp_tick_length may change diff --git a/include/net/wext.h b/include/net/wext.h index 3459119..454ff76 100644 --- a/include/net/wext.h +++ b/include/net/wext.h @@ -6,7 +6,7 @@ struct net; #ifdef CONFIG_WEXT_CORE -int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, +int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd, void __user *arg); int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, unsigned long arg); @@ -14,7 +14,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, struct iw_statistics *get_wireless_stats(struct net_device *dev); int call_commit_handler(struct net_device *dev); #else -static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, +static inline int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd, void __user *arg) { return -EINVAL; diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index f24a80d..7ccbd6a 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -418,6 +418,19 @@ typedef struct drm_i915_irq_wait { */ #define I915_PARAM_HAS_EXEC_CAPTURE 45 +#define I915_PARAM_SLICE_MASK 46 + +/* Assuming it's uniform for each slice, this queries the mask of subslices + * per-slice for this system. + */ +#define I915_PARAM_SUBSLICE_MASK 47 + +/* + * Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying the batch buffer + * as the first execobject as opposed to the last. See I915_EXEC_BATCH_FIRST. + */ +#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48 + typedef struct drm_i915_getparam { __s32 param; /* @@ -904,7 +917,17 @@ struct drm_i915_gem_execbuffer2 { */ #define I915_EXEC_FENCE_OUT (1<<17) -#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_OUT<<1)) +/* + * Traditionally the execbuf ioctl has only considered the final element in + * the execobject[] to be the executable batch. Often though, the client + * will known the batch object prior to construction and being able to place + * it into the execobject[] array first can simplify the relocation tracking. + * Setting I915_EXEC_BATCH_FIRST tells execbuf to use element 0 of the + * execobject[] as the * batch instead (the default is to use the last + * element). + */ +#define I915_EXEC_BATCH_FIRST (1<<18) +#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_BATCH_FIRST<<1)) #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) #define i915_execbuffer2_set_context_id(eb2, context) \ @@ -1308,13 +1331,18 @@ struct drm_i915_gem_context_param { }; enum drm_i915_oa_format { - I915_OA_FORMAT_A13 = 1, - I915_OA_FORMAT_A29, - I915_OA_FORMAT_A13_B8_C8, - I915_OA_FORMAT_B4_C8, - I915_OA_FORMAT_A45_B8_C8, - I915_OA_FORMAT_B4_C8_A16, - I915_OA_FORMAT_C4_B8, + I915_OA_FORMAT_A13 = 1, /* HSW only */ + I915_OA_FORMAT_A29, /* HSW only */ + I915_OA_FORMAT_A13_B8_C8, /* HSW only */ + I915_OA_FORMAT_B4_C8, /* HSW only */ + I915_OA_FORMAT_A45_B8_C8, /* HSW only */ + I915_OA_FORMAT_B4_C8_A16, /* HSW only */ + I915_OA_FORMAT_C4_B8, /* HSW+ */ + + /* Gen8+ */ + I915_OA_FORMAT_A12, + I915_OA_FORMAT_A12_B8_C8, + I915_OA_FORMAT_A32u40_A4u32_B8_C8, I915_OA_FORMAT_MAX /* non-ABI */ }; diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index a4a189a..26c54f6 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -104,10 +104,14 @@ struct drm_msm_gem_new { __u32 handle; /* out */ }; +#define MSM_INFO_IOVA 0x01 + +#define MSM_INFO_FLAGS (MSM_INFO_IOVA) + struct drm_msm_gem_info { __u32 handle; /* in */ - __u32 pad; - __u64 offset; /* out, offset to pass to mmap() */ + __u32 flags; /* in - combination of MSM_INFO_* flags */ + __u64 offset; /* out, mmap() offset or iova */ }; #define MSM_PREP_READ 0x01 @@ -261,7 +265,6 @@ struct drm_msm_gem_madvise { #define DRM_MSM_GEM_SUBMIT 0x06 #define DRM_MSM_WAIT_FENCE 0x07 #define DRM_MSM_GEM_MADVISE 0x08 -#define DRM_MSM_NUM_IOCTLS 0x09 #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 2831480..ee97196 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -580,7 +580,7 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event, int ret = -ENOMEM, max_order = 0; if (!has_aux(event)) - return -ENOTSUPP; + return -EOPNOTSUPP; if (event->pmu->capabilities & PERF_PMU_CAP_AUX_NO_SG) { /* diff --git a/kernel/livepatch/patch.c b/kernel/livepatch/patch.c index f826903..52c4e90 100644 --- a/kernel/livepatch/patch.c +++ b/kernel/livepatch/patch.c @@ -59,7 +59,11 @@ static void notrace klp_ftrace_handler(unsigned long ip, ops = container_of(fops, struct klp_ops, fops); - rcu_read_lock(); + /* + * A variant of synchronize_sched() is used to allow patching functions + * where RCU is not watching, see klp_synchronize_transition(). + */ + preempt_disable_notrace(); func = list_first_or_null_rcu(&ops->func_stack, struct klp_func, stack_node); @@ -115,7 +119,7 @@ static void notrace klp_ftrace_handler(unsigned long ip, klp_arch_set_pc(regs, (unsigned long)func->new_func); unlock: - rcu_read_unlock(); + preempt_enable_notrace(); } /* diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index adc0cc6..b004a1f 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -49,6 +49,28 @@ static void klp_transition_work_fn(struct work_struct *work) static DECLARE_DELAYED_WORK(klp_transition_work, klp_transition_work_fn); /* + * This function is just a stub to implement a hard force + * of synchronize_sched(). This requires synchronizing + * tasks even in userspace and idle. + */ +static void klp_sync(struct work_struct *work) +{ +} + +/* + * We allow to patch also functions where RCU is not watching, + * e.g. before user_exit(). We can not rely on the RCU infrastructure + * to do the synchronization. Instead hard force the sched synchronization. + * + * This approach allows to use RCU functions for manipulating func_stack + * safely. + */ +static void klp_synchronize_transition(void) +{ + schedule_on_each_cpu(klp_sync); +} + +/* * The transition to the target patch state is complete. Clean up the data * structures. */ @@ -73,7 +95,7 @@ static void klp_complete_transition(void) * func->transition gets cleared, the handler may choose a * removed function. */ - synchronize_rcu(); + klp_synchronize_transition(); } if (klp_transition_patch->immediate) @@ -92,7 +114,7 @@ static void klp_complete_transition(void) /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */ if (klp_target_state == KLP_PATCHED) - synchronize_rcu(); + klp_synchronize_transition(); read_lock(&tasklist_lock); for_each_process_thread(g, task) { @@ -136,7 +158,11 @@ void klp_cancel_transition(void) */ void klp_update_patch_state(struct task_struct *task) { - rcu_read_lock(); + /* + * A variant of synchronize_sched() is used to allow patching functions + * where RCU is not watching, see klp_synchronize_transition(). + */ + preempt_disable_notrace(); /* * This test_and_clear_tsk_thread_flag() call also serves as a read @@ -153,7 +179,7 @@ void klp_update_patch_state(struct task_struct *task) if (test_and_clear_tsk_thread_flag(task, TIF_PATCH_PENDING)) task->patch_state = READ_ONCE(klp_target_state); - rcu_read_unlock(); + preempt_enable_notrace(); } /* @@ -539,7 +565,7 @@ void klp_reverse_transition(void) clear_tsk_thread_flag(idle_task(cpu), TIF_PATCH_PENDING); /* Let any remaining calls to klp_update_patch_state() complete */ - synchronize_rcu(); + klp_synchronize_transition(); klp_start_transition(); } diff --git a/kernel/signal.c b/kernel/signal.c index ca92bcf..45b4c1f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -510,7 +510,8 @@ int unhandled_signal(struct task_struct *tsk, int sig) return !tsk->ptrace; } -static void collect_signal(int sig, struct sigpending *list, siginfo_t *info) +static void collect_signal(int sig, struct sigpending *list, siginfo_t *info, + bool *resched_timer) { struct sigqueue *q, *first = NULL; @@ -532,6 +533,12 @@ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info) still_pending: list_del_init(&first->list); copy_siginfo(info, &first->info); + + *resched_timer = + (first->flags & SIGQUEUE_PREALLOC) && + (info->si_code == SI_TIMER) && + (info->si_sys_private); + __sigqueue_free(first); } else { /* @@ -548,12 +555,12 @@ still_pending: } static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, - siginfo_t *info) + siginfo_t *info, bool *resched_timer) { int sig = next_signal(pending, mask); if (sig) - collect_signal(sig, pending, info); + collect_signal(sig, pending, info, resched_timer); return sig; } @@ -565,15 +572,16 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, */ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) { + bool resched_timer = false; int signr; /* We only dequeue private signals from ourselves, we don't let * signalfd steal them */ - signr = __dequeue_signal(&tsk->pending, mask, info); + signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer); if (!signr) { signr = __dequeue_signal(&tsk->signal->shared_pending, - mask, info); + mask, info, &resched_timer); #ifdef CONFIG_POSIX_TIMERS /* * itimer signal ? @@ -621,7 +629,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) current->jobctl |= JOBCTL_STOP_DEQUEUED; } #ifdef CONFIG_POSIX_TIMERS - if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { + if (resched_timer) { /* * Release the siglock to ensure proper locking order * of timer locks outside of siglocks. Note, we leave diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 9652bc5..b602c48 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -118,6 +118,26 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta) tk->offs_boot = ktime_add(tk->offs_boot, delta); } +/* + * tk_clock_read - atomic clocksource read() helper + * + * This helper is necessary to use in the read paths because, while the + * seqlock ensures we don't return a bad value while structures are updated, + * it doesn't protect from potential crashes. There is the possibility that + * the tkr's clocksource may change between the read reference, and the + * clock reference passed to the read function. This can cause crashes if + * the wrong clocksource is passed to the wrong read function. + * This isn't necessary to use when holding the timekeeper_lock or doing + * a read of the fast-timekeeper tkrs (which is protected by its own locking + * and update logic). + */ +static inline u64 tk_clock_read(struct tk_read_base *tkr) +{ + struct clocksource *clock = READ_ONCE(tkr->clock); + + return clock->read(clock); +} + #ifdef CONFIG_DEBUG_TIMEKEEPING #define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */ @@ -175,7 +195,7 @@ static inline u64 timekeeping_get_delta(struct tk_read_base *tkr) */ do { seq = read_seqcount_begin(&tk_core.seq); - now = tkr->read(tkr->clock); + now = tk_clock_read(tkr); last = tkr->cycle_last; mask = tkr->mask; max = tkr->clock->max_cycles; @@ -209,7 +229,7 @@ static inline u64 timekeeping_get_delta(struct tk_read_base *tkr) u64 cycle_now, delta; /* read clocksource */ - cycle_now = tkr->read(tkr->clock); + cycle_now = tk_clock_read(tkr); /* calculate the delta since the last update_wall_time */ delta = clocksource_delta(cycle_now, tkr->cycle_last, tkr->mask); @@ -238,12 +258,10 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) ++tk->cs_was_changed_seq; old_clock = tk->tkr_mono.clock; tk->tkr_mono.clock = clock; - tk->tkr_mono.read = clock->read; tk->tkr_mono.mask = clock->mask; - tk->tkr_mono.cycle_last = tk->tkr_mono.read(clock); + tk->tkr_mono.cycle_last = tk_clock_read(&tk->tkr_mono); tk->tkr_raw.clock = clock; - tk->tkr_raw.read = clock->read; tk->tkr_raw.mask = clock->mask; tk->tkr_raw.cycle_last = tk->tkr_mono.cycle_last; @@ -262,7 +280,7 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) /* Go back from cycles -> shifted ns */ tk->xtime_interval = interval * clock->mult; tk->xtime_remainder = ntpinterval - tk->xtime_interval; - tk->raw_interval = (interval * clock->mult) >> clock->shift; + tk->raw_interval = interval * clock->mult; /* if changing clocks, convert xtime_nsec shift units */ if (old_clock) { @@ -404,7 +422,7 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) now += timekeeping_delta_to_ns(tkr, clocksource_delta( - tkr->read(tkr->clock), + tk_clock_read(tkr), tkr->cycle_last, tkr->mask)); } while (read_seqcount_retry(&tkf->seq, seq)); @@ -461,6 +479,10 @@ static u64 dummy_clock_read(struct clocksource *cs) return cycles_at_suspend; } +static struct clocksource dummy_clock = { + .read = dummy_clock_read, +}; + /** * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource. * @tk: Timekeeper to snapshot. @@ -477,13 +499,13 @@ static void halt_fast_timekeeper(struct timekeeper *tk) struct tk_read_base *tkr = &tk->tkr_mono; memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy)); - cycles_at_suspend = tkr->read(tkr->clock); - tkr_dummy.read = dummy_clock_read; + cycles_at_suspend = tk_clock_read(tkr); + tkr_dummy.clock = &dummy_clock; update_fast_timekeeper(&tkr_dummy, &tk_fast_mono); tkr = &tk->tkr_raw; memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy)); - tkr_dummy.read = dummy_clock_read; + tkr_dummy.clock = &dummy_clock; update_fast_timekeeper(&tkr_dummy, &tk_fast_raw); } @@ -649,11 +671,10 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) */ static void timekeeping_forward_now(struct timekeeper *tk) { - struct clocksource *clock = tk->tkr_mono.clock; u64 cycle_now, delta; u64 nsec; - cycle_now = tk->tkr_mono.read(clock); + cycle_now = tk_clock_read(&tk->tkr_mono); delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask); tk->tkr_mono.cycle_last = cycle_now; tk->tkr_raw.cycle_last = cycle_now; @@ -929,8 +950,7 @@ void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot) do { seq = read_seqcount_begin(&tk_core.seq); - - now = tk->tkr_mono.read(tk->tkr_mono.clock); + now = tk_clock_read(&tk->tkr_mono); systime_snapshot->cs_was_changed_seq = tk->cs_was_changed_seq; systime_snapshot->clock_was_set_seq = tk->clock_was_set_seq; base_real = ktime_add(tk->tkr_mono.base, @@ -1108,7 +1128,7 @@ int get_device_system_crosststamp(int (*get_time_fn) * Check whether the system counter value provided by the * device driver is on the current timekeeping interval. */ - now = tk->tkr_mono.read(tk->tkr_mono.clock); + now = tk_clock_read(&tk->tkr_mono); interval_start = tk->tkr_mono.cycle_last; if (!cycle_between(interval_start, cycles, now)) { clock_was_set_seq = tk->clock_was_set_seq; @@ -1629,7 +1649,7 @@ void timekeeping_resume(void) * The less preferred source will only be tried if there is no better * usable source. The rtc part is handled separately in rtc core code. */ - cycle_now = tk->tkr_mono.read(clock); + cycle_now = tk_clock_read(&tk->tkr_mono); if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) && cycle_now > tk->tkr_mono.cycle_last) { u64 nsec, cyc_delta; @@ -1976,7 +1996,7 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset, u32 shift, unsigned int *clock_set) { u64 interval = tk->cycle_interval << shift; - u64 raw_nsecs; + u64 snsec_per_sec; /* If the offset is smaller than a shifted interval, do nothing */ if (offset < interval) @@ -1991,14 +2011,15 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset, *clock_set |= accumulate_nsecs_to_secs(tk); /* Accumulate raw time */ - raw_nsecs = (u64)tk->raw_interval << shift; - raw_nsecs += tk->raw_time.tv_nsec; - if (raw_nsecs >= NSEC_PER_SEC) { - u64 raw_secs = raw_nsecs; - raw_nsecs = do_div(raw_secs, NSEC_PER_SEC); - tk->raw_time.tv_sec += raw_secs; + tk->tkr_raw.xtime_nsec += (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift; + tk->tkr_raw.xtime_nsec += tk->raw_interval << shift; + snsec_per_sec = (u64)NSEC_PER_SEC << tk->tkr_raw.shift; + while (tk->tkr_raw.xtime_nsec >= snsec_per_sec) { + tk->tkr_raw.xtime_nsec -= snsec_per_sec; + tk->raw_time.tv_sec++; } - tk->raw_time.tv_nsec = raw_nsecs; + tk->raw_time.tv_nsec = tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift; + tk->tkr_raw.xtime_nsec -= (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift; /* Accumulate error between NTP and clock interval */ tk->ntp_error += tk->ntp_tick << shift; @@ -2030,7 +2051,7 @@ void update_wall_time(void) #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET offset = real_tk->cycle_interval; #else - offset = clocksource_delta(tk->tkr_mono.read(tk->tkr_mono.clock), + offset = clocksource_delta(tk_clock_read(&tk->tkr_mono), tk->tkr_mono.cycle_last, tk->tkr_mono.mask); #endif diff --git a/lib/cmdline.c b/lib/cmdline.c index 3c6432df..4c0888c 100644 --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -23,14 +23,14 @@ * the values[M, M+1, ..., N] into the ints array in get_options. */ -static int get_range(char **str, int *pint) +static int get_range(char **str, int *pint, int n) { int x, inc_counter, upper_range; (*str)++; upper_range = simple_strtol((*str), NULL, 0); inc_counter = upper_range - *pint; - for (x = *pint; x < upper_range; x++) + for (x = *pint; n && x < upper_range; x++, n--) *pint++ = x; return inc_counter; } @@ -97,7 +97,7 @@ char *get_options(const char *str, int nints, int *ints) break; if (res == 3) { int range_nums; - range_nums = get_range((char **)&str, ints + i); + range_nums = get_range((char **)&str, ints + i, nints - i); if (range_nums < 0) break; /* diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 945fd1c..df4ebdb 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -652,7 +652,6 @@ static void __collapse_huge_page_copy(pte_t *pte, struct page *page, spin_unlock(ptl); free_page_and_swap_cache(src_page); } - cond_resched(); } } @@ -1817,7 +1817,8 @@ check_current: /* Check if current node has a suitable gap */ if (gap_start > high_limit) return -ENOMEM; - if (gap_end >= low_limit && gap_end - gap_start >= length) + if (gap_end >= low_limit && + gap_end > gap_start && gap_end - gap_start >= length) goto found; /* Visit right subtree if it looks promising */ @@ -1920,7 +1921,8 @@ check_current: gap_end = vm_start_gap(vma); if (gap_end < low_limit) return -ENOMEM; - if (gap_start <= high_limit && gap_end - gap_start >= length) + if (gap_start <= high_limit && + gap_end > gap_start && gap_end - gap_start >= length) goto found; /* Visit left subtree if it looks promising */ @@ -2228,16 +2230,19 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) if (!(vma->vm_flags & VM_GROWSUP)) return -EFAULT; - /* Guard against wrapping around to address 0. */ + /* Guard against exceeding limits of the address space. */ address &= PAGE_MASK; - address += PAGE_SIZE; - if (!address) + if (address >= TASK_SIZE) return -ENOMEM; + address += PAGE_SIZE; /* Enforce stack_guard_gap */ gap_addr = address + stack_guard_gap; - if (gap_addr < address) - return -ENOMEM; + + /* Guard against overflow */ + if (gap_addr < address || gap_addr > TASK_SIZE) + gap_addr = TASK_SIZE; + next = vma->vm_next; if (next && next->vm_start < gap_addr) { if (!(next->vm_flags & VM_GROWSUP)) @@ -5625,6 +5625,28 @@ static char *create_unique_id(struct kmem_cache *s) return name; } +static void sysfs_slab_remove_workfn(struct work_struct *work) +{ + struct kmem_cache *s = + container_of(work, struct kmem_cache, kobj_remove_work); + + if (!s->kobj.state_in_sysfs) + /* + * For a memcg cache, this may be called during + * deactivation and again on shutdown. Remove only once. + * A cache is never shut down before deactivation is + * complete, so no need to worry about synchronization. + */ + return; + +#ifdef CONFIG_MEMCG + kset_unregister(s->memcg_kset); +#endif + kobject_uevent(&s->kobj, KOBJ_REMOVE); + kobject_del(&s->kobj); + kobject_put(&s->kobj); +} + static int sysfs_slab_add(struct kmem_cache *s) { int err; @@ -5632,6 +5654,8 @@ static int sysfs_slab_add(struct kmem_cache *s) struct kset *kset = cache_kset(s); int unmergeable = slab_unmergeable(s); + INIT_WORK(&s->kobj_remove_work, sysfs_slab_remove_workfn); + if (!kset) { kobject_init(&s->kobj, &slab_ktype); return 0; @@ -5695,20 +5719,8 @@ static void sysfs_slab_remove(struct kmem_cache *s) */ return; - if (!s->kobj.state_in_sysfs) - /* - * For a memcg cache, this may be called during - * deactivation and again on shutdown. Remove only once. - * A cache is never shut down before deactivation is - * complete, so no need to worry about synchronization. - */ - return; - -#ifdef CONFIG_MEMCG - kset_unregister(s->memcg_kset); -#endif - kobject_uevent(&s->kobj, KOBJ_REMOVE); - kobject_del(&s->kobj); + kobject_get(&s->kobj); + schedule_work(&s->kobj_remove_work); } void sysfs_slab_release(struct kmem_cache *s) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 34a1c3e..ecc97f7 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -287,10 +287,21 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) if (p4d_none(*p4d)) return NULL; pud = pud_offset(p4d, addr); - if (pud_none(*pud)) + + /* + * Don't dereference bad PUD or PMD (below) entries. This will also + * identify huge mappings, which we may encounter on architectures + * that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be + * identified as vmalloc addresses by is_vmalloc_addr(), but are + * not [unambiguously] associated with a struct page, so there is + * no correct value to return for them. + */ + WARN_ON_ONCE(pud_bad(*pud)); + if (pud_none(*pud) || pud_bad(*pud)) return NULL; pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) + WARN_ON_ONCE(pmd_bad(*pmd)); + if (pmd_none(*pmd) || pmd_bad(*pmd)) return NULL; ptep = pte_offset_map(pmd, addr); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 467069b..9649579 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -277,7 +277,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) return 0; out_free_newdev: - free_netdev(new_dev); + if (new_dev->reg_state == NETREG_UNINITIALIZED) + free_netdev(new_dev); return err; } diff --git a/net/core/dev.c b/net/core/dev.c index 6d60149..7243421 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5206,8 +5206,6 @@ static void busy_poll_stop(struct napi_struct *napi, void *have_poll_lock) if (rc == BUSY_POLL_BUDGET) __napi_schedule(napi); local_bh_enable(); - if (local_softirq_pending()) - do_softirq(); } void napi_busy_loop(unsigned int napi_id, diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index b94b1d2..27fad31 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -410,6 +410,22 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) if (cmd == SIOCGIFNAME) return dev_ifname(net, (struct ifreq __user *)arg); + /* + * Take care of Wireless Extensions. Unfortunately struct iwreq + * isn't a proper subset of struct ifreq (it's 8 byte shorter) + * so we need to treat it specially, otherwise applications may + * fault if the struct they're passing happens to land at the + * end of a mapped page. + */ + if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { + struct iwreq iwr; + + if (copy_from_user(&iwr, arg, sizeof(iwr))) + return -EFAULT; + + return wext_handle_ioctl(net, &iwr, cmd, arg); + } + if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) return -EFAULT; @@ -559,9 +575,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) ret = -EFAULT; return ret; } - /* Take care of Wireless Extensions */ - if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) - return wext_handle_ioctl(net, &ifr, cmd, arg); return -ENOTTY; } } diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index f21c4d3..3bba291 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -568,7 +568,7 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, struct net *net = sock_net(skb->sk); struct fib_rule_hdr *frh = nlmsg_data(nlh); struct fib_rules_ops *ops = NULL; - struct fib_rule *rule, *tmp; + struct fib_rule *rule, *r; struct nlattr *tb[FRA_MAX+1]; struct fib_kuid_range range; int err = -EINVAL; @@ -668,16 +668,23 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, /* * Check if this rule is a target to any of them. If so, + * adjust to the next one with the same preference or * disable them. As this operation is eventually very - * expensive, it is only performed if goto rules have - * actually been added. + * expensive, it is only performed if goto rules, except + * current if it is goto rule, have actually been added. */ if (ops->nr_goto_rules > 0) { - list_for_each_entry(tmp, &ops->rules_list, list) { - if (rtnl_dereference(tmp->ctarget) == rule) { - RCU_INIT_POINTER(tmp->ctarget, NULL); + struct fib_rule *n; + + n = list_next_entry(rule, list); + if (&n->list == &ops->rules_list || n->pref != rule->pref) + n = NULL; + list_for_each_entry(r, &ops->rules_list, list) { + if (rtnl_dereference(r->ctarget) != rule) + continue; + rcu_assign_pointer(r->ctarget, n); + if (!n) ops->unresolved_rules++; - } } } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 5e61456..467a2f4 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -931,6 +931,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, + nla_total_size(1) /* IFLA_LINKMODE */ + nla_total_size(4) /* IFLA_CARRIER_CHANGES */ + nla_total_size(4) /* IFLA_LINK_NETNSID */ + + nla_total_size(4) /* IFLA_GROUP */ + nla_total_size(ext_filter_mask & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ @@ -1468,6 +1469,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_LINK_NETNSID] = { .type = NLA_S32 }, [IFLA_PROTO_DOWN] = { .type = NLA_U8 }, [IFLA_XDP] = { .type = NLA_NESTED }, + [IFLA_GROUP] = { .type = NLA_U32 }, }; static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 4b9518a..6f95612 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -188,12 +188,6 @@ static inline void dnrt_free(struct dn_route *rt) call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free); } -static inline void dnrt_drop(struct dn_route *rt) -{ - dst_release(&rt->dst); - call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free); -} - static void dn_dst_check_expire(unsigned long dummy) { int i; @@ -248,7 +242,7 @@ static int dn_dst_gc(struct dst_ops *ops) } *rtp = rt->dst.dn_next; rt->dst.dn_next = NULL; - dnrt_drop(rt); + dnrt_free(rt); break; } spin_unlock_bh(&dn_rt_hash_table[i].lock); @@ -350,7 +344,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned int hash, struct dn_rou dst_use(&rth->dst, now); spin_unlock_bh(&dn_rt_hash_table[hash].lock); - dnrt_drop(rt); + dst_free(&rt->dst); *rp = rth; return 0; } @@ -380,7 +374,7 @@ static void dn_run_flush(unsigned long dummy) for(; rt; rt = next) { next = rcu_dereference_raw(rt->dst.dn_next); RCU_INIT_POINTER(rt->dst.dn_next, NULL); - dst_free((struct dst_entry *)rt); + dnrt_free(rt); } nothing_to_declare: @@ -1187,7 +1181,7 @@ make_route: if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; - rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST); + rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, DST_HOST); if (rt == NULL) goto e_nobufs; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 8f6b5bb..ec9a396 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1112,6 +1112,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im) pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); if (!pmc) return; + spin_lock_init(&pmc->lock); spin_lock_bh(&im->lock); pmc->interface = im->interface; in_dev_hold(in_dev); diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index b436d07..129d1a3 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -446,6 +446,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, return 0; drop: + if (tun_dst) + dst_release((struct dst_entry *)tun_dst); kfree_skb(skb); return 0; } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6a4fb1e..686c923 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -332,9 +332,9 @@ static void addrconf_mod_rs_timer(struct inet6_dev *idev, static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp, unsigned long delay) { - if (!delayed_work_pending(&ifp->dad_work)) - in6_ifa_hold(ifp); - mod_delayed_work(addrconf_wq, &ifp->dad_work, delay); + in6_ifa_hold(ifp); + if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay)) + in6_ifa_put(ifp); } static int snmp6_alloc_dev(struct inet6_dev *idev) diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index eea23b5..ec849d8 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -32,7 +32,6 @@ struct fib6_rule { struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, int flags, pol_lookup_t lookup) { - struct rt6_info *rt; struct fib_lookup_arg arg = { .lookup_ptr = lookup, .flags = FIB_LOOKUP_NOREF, @@ -44,21 +43,11 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, fib_rules_lookup(net->ipv6.fib6_rules_ops, flowi6_to_flowi(fl6), flags, &arg); - rt = arg.result; + if (arg.result) + return arg.result; - if (!rt) { - dst_hold(&net->ipv6.ip6_null_entry->dst); - return &net->ipv6.ip6_null_entry->dst; - } - - if (rt->rt6i_flags & RTF_REJECT && - rt->dst.error == -EAGAIN) { - ip6_rt_put(rt); - rt = net->ipv6.ip6_null_entry; - dst_hold(&rt->dst); - } - - return &rt->dst; + dst_hold(&net->ipv6.ip6_null_entry->dst); + return &net->ipv6.ip6_null_entry->dst; } static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, @@ -121,7 +110,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, flp6->saddr = saddr; } err = rt->dst.error; - goto out; + if (err != -EAGAIN) + goto out; } again: ip6_rt_put(rt); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index d4bf2c6..e6b78ba 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -289,8 +289,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, struct rt6_info *rt; rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); - if (rt->rt6i_flags & RTF_REJECT && - rt->dst.error == -EAGAIN) { + if (rt->dst.error == -EAGAIN) { ip6_rt_put(rt); rt = net->ipv6.ip6_null_entry; dst_hold(&rt->dst); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index c358197..8c6c3c8 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -858,6 +858,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, return 0; drop: + if (tun_dst) + dst_release((struct dst_entry *)tun_dst); kfree_skb(skb); return 0; } @@ -1246,7 +1248,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPIP; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; - dsfield = ip6_tclass(key->label); + dsfield = key->tos; } else { if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) encap_limit = t->parms.encap_limit; @@ -1317,7 +1319,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto = IPPROTO_IPV6; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; - dsfield = ip6_tclass(key->label); + dsfield = key->tos; } else { offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c index 0a4e284..5436922 100644 --- a/net/rxrpc/key.c +++ b/net/rxrpc/key.c @@ -217,7 +217,7 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ, unsigned int *_toklen) { const __be32 *xdr = *_xdr; - unsigned int toklen = *_toklen, n_parts, loop, tmp; + unsigned int toklen = *_toklen, n_parts, loop, tmp, paddedlen; /* there must be at least one name, and at least #names+1 length * words */ @@ -247,16 +247,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ, toklen -= 4; if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX) return -EINVAL; - if (tmp > toklen) + paddedlen = (tmp + 3) & ~3; + if (paddedlen > toklen) return -EINVAL; princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL); if (!princ->name_parts[loop]) return -ENOMEM; memcpy(princ->name_parts[loop], xdr, tmp); princ->name_parts[loop][tmp] = 0; - tmp = (tmp + 3) & ~3; - toklen -= tmp; - xdr += tmp >> 2; + toklen -= paddedlen; + xdr += paddedlen >> 2; } if (toklen < 4) @@ -265,16 +265,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ, toklen -= 4; if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX) return -EINVAL; - if (tmp > toklen) + paddedlen = (tmp + 3) & ~3; + if (paddedlen > toklen) return -EINVAL; princ->realm = kmalloc(tmp + 1, GFP_KERNEL); if (!princ->realm) return -ENOMEM; memcpy(princ->realm, xdr, tmp); princ->realm[tmp] = 0; - tmp = (tmp + 3) & ~3; - toklen -= tmp; - xdr += tmp >> 2; + toklen -= paddedlen; + xdr += paddedlen >> 2; _debug("%s/...@%s", princ->name_parts[0], princ->realm); @@ -293,7 +293,7 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td, unsigned int *_toklen) { const __be32 *xdr = *_xdr; - unsigned int toklen = *_toklen, len; + unsigned int toklen = *_toklen, len, paddedlen; /* there must be at least one tag and one length word */ if (toklen <= 8) @@ -307,15 +307,17 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td, toklen -= 8; if (len > max_data_size) return -EINVAL; + paddedlen = (len + 3) & ~3; + if (paddedlen > toklen) + return -EINVAL; td->data_len = len; if (len > 0) { td->data = kmemdup(xdr, len, GFP_KERNEL); if (!td->data) return -ENOMEM; - len = (len + 3) & ~3; - toklen -= len; - xdr += len >> 2; + toklen -= paddedlen; + xdr += paddedlen >> 2; } _debug("tag %x len %x", td->tag, td->data_len); @@ -387,7 +389,7 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen, const __be32 **_xdr, unsigned int *_toklen) { const __be32 *xdr = *_xdr; - unsigned int toklen = *_toklen, len; + unsigned int toklen = *_toklen, len, paddedlen; /* there must be at least one length word */ if (toklen <= 4) @@ -399,6 +401,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen, toklen -= 4; if (len > AFSTOKEN_K5_TIX_MAX) return -EINVAL; + paddedlen = (len + 3) & ~3; + if (paddedlen > toklen) + return -EINVAL; *_tktlen = len; _debug("ticket len %u", len); @@ -407,9 +412,8 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen, *_ticket = kmemdup(xdr, len, GFP_KERNEL); if (!*_ticket) return -ENOMEM; - len = (len + 3) & ~3; - toklen -= len; - xdr += len >> 2; + toklen -= paddedlen; + xdr += paddedlen >> 2; } *_xdr = xdr; @@ -552,7 +556,7 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep) { const __be32 *xdr = prep->data, *token; const char *cp; - unsigned int len, tmp, loop, ntoken, toklen, sec_ix; + unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix; size_t datalen = prep->datalen; int ret; @@ -578,22 +582,21 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep) if (len < 1 || len > AFSTOKEN_CELL_MAX) goto not_xdr; datalen -= 4; - tmp = (len + 3) & ~3; - if (tmp > datalen) + paddedlen = (len + 3) & ~3; + if (paddedlen > datalen) goto not_xdr; cp = (const char *) xdr; for (loop = 0; loop < len; loop++) if (!isprint(cp[loop])) goto not_xdr; - if (len < tmp) - for (; loop < tmp; loop++) - if (cp[loop]) - goto not_xdr; + for (; loop < paddedlen; loop++) + if (cp[loop]) + goto not_xdr; _debug("cellname: [%u/%u] '%*.*s'", - len, tmp, len, len, (const char *) xdr); - datalen -= tmp; - xdr += tmp >> 2; + len, paddedlen, len, len, (const char *) xdr); + datalen -= paddedlen; + xdr += paddedlen >> 2; /* get the token count */ if (datalen < 12) @@ -614,10 +617,11 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep) sec_ix = ntohl(*xdr); datalen -= 4; _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix); - if (toklen < 20 || toklen > datalen) + paddedlen = (toklen + 3) & ~3; + if (toklen < 20 || toklen > datalen || paddedlen > datalen) goto not_xdr; - datalen -= (toklen + 3) & ~3; - xdr += (toklen + 3) >> 2; + datalen -= paddedlen; + xdr += paddedlen >> 2; } while (--loop > 0); diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 8c58923..3dcd0ec 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -275,6 +275,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) if (sctp_sk(sk)->bind_hash) sctp_put_port(sk); + sctp_sk(sk)->ep = NULL; sock_put(sk); } diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c index 048954e..9a64721 100644 --- a/net/sctp/sctp_diag.c +++ b/net/sctp/sctp_diag.c @@ -278,7 +278,6 @@ out: static int sctp_sock_dump(struct sock *sk, void *p) { - struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_comm_param *commp = p; struct sk_buff *skb = commp->skb; struct netlink_callback *cb = commp->cb; @@ -287,7 +286,9 @@ static int sctp_sock_dump(struct sock *sk, void *p) int err = 0; lock_sock(sk); - list_for_each_entry(assoc, &ep->asocs, asocs) { + if (!sctp_sk(sk)->ep) + goto release; + list_for_each_entry(assoc, &sctp_sk(sk)->ep->asocs, asocs) { if (cb->args[4] < cb->args[1]) goto next; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 30aa0a5..3a8318e 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4666,9 +4666,8 @@ int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *), if (err) return err; - sctp_transport_get_idx(net, &hti, pos); - obj = sctp_transport_get_next(net, &hti); - for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) { + obj = sctp_transport_get_idx(net, &hti, pos + 1); + for (; !IS_ERR_OR_NULL(obj); obj = sctp_transport_get_next(net, &hti)) { struct sctp_transport *transport = obj; if (!sctp_transport_hold(transport)) diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 1a4db67..6cdb054 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -914,13 +914,12 @@ int call_commit_handler(struct net_device *dev) * Main IOCTl dispatcher. * Check the type of IOCTL and call the appropriate wrapper... */ -static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, +static int wireless_process_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd, struct iw_request_info *info, wext_ioctl_func standard, wext_ioctl_func private) { - struct iwreq *iwr = (struct iwreq *) ifr; struct net_device *dev; iw_handler handler; @@ -928,7 +927,7 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, * The copy_to/from_user() of ifr is also dealt with in there */ /* Make sure the device exist */ - if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL) + if ((dev = __dev_get_by_name(net, iwr->ifr_name)) == NULL) return -ENODEV; /* A bunch of special cases, then the generic case... @@ -957,9 +956,6 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, else if (private) return private(dev, iwr, cmd, info, handler); } - /* Old driver API : call driver ioctl handler */ - if (dev->netdev_ops->ndo_do_ioctl) - return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); return -EOPNOTSUPP; } @@ -977,7 +973,7 @@ static int wext_permission_check(unsigned int cmd) } /* entry point from dev ioctl */ -static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr, +static int wext_ioctl_dispatch(struct net *net, struct iwreq *iwr, unsigned int cmd, struct iw_request_info *info, wext_ioctl_func standard, wext_ioctl_func private) @@ -987,9 +983,9 @@ static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr, if (ret) return ret; - dev_load(net, ifr->ifr_name); + dev_load(net, iwr->ifr_name); rtnl_lock(); - ret = wireless_process_ioctl(net, ifr, cmd, info, standard, private); + ret = wireless_process_ioctl(net, iwr, cmd, info, standard, private); rtnl_unlock(); return ret; @@ -1039,18 +1035,18 @@ static int ioctl_standard_call(struct net_device * dev, } -int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, +int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd, void __user *arg) { struct iw_request_info info = { .cmd = cmd, .flags = 0 }; int ret; - ret = wext_ioctl_dispatch(net, ifr, cmd, &info, + ret = wext_ioctl_dispatch(net, iwr, cmd, &info, ioctl_standard_call, ioctl_private_call); if (ret >= 0 && IW_IS_GET(cmd) && - copy_to_user(arg, ifr, sizeof(struct iwreq))) + copy_to_user(arg, iwr, sizeof(struct iwreq))) return -EFAULT; return ret; @@ -1107,7 +1103,7 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd, info.cmd = cmd; info.flags = IW_REQUEST_FLAG_COMPAT; - ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd, &info, + ret = wext_ioctl_dispatch(net, &iwr, cmd, &info, compat_standard_call, compat_private_call); diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index ce753a4..c583a1e 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -14,7 +14,15 @@ __headers: include scripts/Kbuild.include srcdir := $(srctree)/$(obj) -subdirs := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.)) + +# When make is run under a fakechroot environment, the function +# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular +# files. So, we are using a combination of sort/dir/wildcard which works +# with fakechroot. +subdirs := $(patsubst $(srcdir)/%/,%,\ + $(filter-out $(srcdir)/,\ + $(sort $(dir $(wildcard $(srcdir)/*/))))) + # caller may set destination dir (when installing to asm/) _dst := $(if $(dst),$(dst),$(obj)) diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index 3bffdca..b724a02 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h @@ -75,7 +75,7 @@ struct string_list *copy_list_range(struct string_list *start, int yylex(void); int yyparse(void); -void error_with_pos(const char *, ...); +void error_with_pos(const char *, ...) __attribute__ ((format(printf, 1, 2))); /*----------------------------------------------------------------------*/ #define xmalloc(size) ({ void *__ptr = malloc(size); \ diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 90a091b..eb81446 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -196,7 +196,7 @@ clean-files += config.pot linux.pot # Check that we have the required ncurses stuff installed for lxdialog (menuconfig) PHONY += $(obj)/dochecklxdialog -$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog +$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog $(obj)/dochecklxdialog: $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf) diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index a9bc533..0031147 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -271,7 +271,7 @@ static struct mitem k_menu_items[MAX_MENU_ITEMS]; static int items_num; static int global_exit; /* the currently selected button */ -const char *current_instructions = menu_instructions; +static const char *current_instructions = menu_instructions; static char *dialog_input_result; static int dialog_input_result_len; @@ -305,7 +305,7 @@ struct function_keys { }; static const int function_keys_num = 9; -struct function_keys function_keys[] = { +static struct function_keys function_keys[] = { { .key_str = "F1", .func = "Help", @@ -508,7 +508,7 @@ static int get_mext_match(const char *match_str, match_f flag) index = (index + items_num) % items_num; while (true) { char *str = k_menu_items[index].str; - if (strcasestr(str, match_str) != 0) + if (strcasestr(str, match_str) != NULL) return index; if (flag == FIND_NEXT_MATCH_UP || flag == MATCH_TINKER_PATTERN_UP) @@ -1067,7 +1067,7 @@ static int do_match(int key, struct match_state *state, int *ans) static void conf(struct menu *menu) { - struct menu *submenu = 0; + struct menu *submenu = NULL; const char *prompt = menu_get_prompt(menu); struct symbol *sym; int res; @@ -1234,7 +1234,7 @@ static void show_help(struct menu *menu) static void conf_choice(struct menu *menu) { const char *prompt = _(menu_get_prompt(menu)); - struct menu *child = 0; + struct menu *child = NULL; struct symbol *active; int selected_index = 0; int last_top_row = 0; @@ -1456,7 +1456,7 @@ static void conf_save(void) } } -void setup_windows(void) +static void setup_windows(void) { int lines, columns; diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 4b2f44c..a64b1c3 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -129,7 +129,7 @@ static void no_colors_theme(void) mkattrn(FUNCTION_TEXT, A_REVERSE); } -void set_colors() +void set_colors(void) { start_color(); use_default_colors(); @@ -192,7 +192,7 @@ const char *get_line(const char *text, int line_no) int lines = 0; if (!text) - return 0; + return NULL; for (i = 0; text[i] != '\0' && lines < line_no; i++) if (text[i] == '\n') diff --git a/scripts/tags.sh b/scripts/tags.sh index d661f2f..d23dcbf 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -106,6 +106,7 @@ all_compiled_sources() case "$i" in *.[cS]) j=${i/\.[cS]/\.o} + j="${j#$tree}" if [ -e $j ]; then echo $i fi diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 5088d4b..009e6c9 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -2492,7 +2492,7 @@ static int pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, struct snd_pcm_substream *substream; const struct snd_pcm_chmap_elem *map; - if (snd_BUG_ON(!info->chmap)) + if (!info->chmap) return -EINVAL; substream = snd_pcm_chmap_substream(info, idx); if (!substream) @@ -2524,7 +2524,7 @@ static int pcm_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int __user *dst; int c, count = 0; - if (snd_BUG_ON(!info->chmap)) + if (!info->chmap) return -EINVAL; if (size < 8) return -ENOMEM; diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 9e6f54f..1e26854 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -682,7 +682,9 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp, cycle = increment_cycle_count(cycle, 1); if (s->handle_packet(s, 0, cycle, i) < 0) { s->packet_index = -1; - amdtp_stream_pcm_abort(s); + if (in_interrupt()) + amdtp_stream_pcm_abort(s); + WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN); return; } } @@ -734,7 +736,9 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp, /* Queueing error or detecting invalid payload. */ if (i < packets) { s->packet_index = -1; - amdtp_stream_pcm_abort(s); + if (in_interrupt()) + amdtp_stream_pcm_abort(s); + WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN); return; } diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index 7e88317..ea1a91e 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h @@ -135,7 +135,7 @@ struct amdtp_stream { /* For a PCM substream processing. */ struct snd_pcm_substream *pcm; struct tasklet_struct period_tasklet; - unsigned int pcm_buffer_pointer; + snd_pcm_uframes_t pcm_buffer_pointer; unsigned int pcm_period_pointer; /* To wait for first packet. */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1770f08..01eb1dc 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -370,10 +370,12 @@ enum { #define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71) #define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0) #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) +#define IS_BXT_T(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x1a98) #define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198) -#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \ - IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \ - IS_GLK(pci) +#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348) +#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci) || \ + IS_BXT_T(pci) || IS_KBL(pci) || IS_KBL_LP(pci) || \ + IS_KBL_H(pci) || IS_GLK(pci) || IS_CFL(pci)) static char *driver_short_names[] = { [AZX_DRIVER_ICH] = "HDA Intel", @@ -2378,6 +2380,9 @@ static const struct pci_device_id azx_ids[] = { /* Kabylake-H */ { PCI_DEVICE(0x8086, 0xa2f0), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, + /* Coffelake */ + { PCI_DEVICE(0x8086, 0xa348), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE}, /* Broxton-P(Apollolake) */ { PCI_DEVICE(0x8086, 0x5a98), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON }, diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 84e7e69..a2670e9 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -619,7 +619,7 @@ static int post_process_probe_trace_point(struct probe_trace_point *tp, struct map *map, unsigned long offs) { struct symbol *sym; - u64 addr = tp->address + tp->offset - offs; + u64 addr = tp->address - offs; sym = map__find_symbol(map, addr); if (!sym) diff --git a/tools/testing/selftests/ntb/ntb_test.sh b/tools/testing/selftests/ntb/ntb_test.sh index a676d3e..13f5198 100755 --- a/tools/testing/selftests/ntb/ntb_test.sh +++ b/tools/testing/selftests/ntb/ntb_test.sh @@ -305,7 +305,7 @@ function perf_test() echo "Running remote perf test $WITH DMA" write_file "" $REMOTE_PERF/run echo -n " " - read_file $LOCAL_PERF/run + read_file $REMOTE_PERF/run echo " Passed" _modprobe -r ntb_perf |